Introduction

Editor's Note

This is part three in Roderic Vicaire's series, titled The Technology of a 3D Engine. In this part, Roderic talks about geometry and resource management in his engine, FlExtEngine. In the first section he layers Models and Objects on top of the SceneTree, SpatialGraph and RenderQueue primitives he talked about in part two, and in the second section he talks about effectively mananging the resources you send to the GPU. It's a great sequel to parts one and two, so enjoy.

Models and Objects

While the SceneTree, SpatialGraph, and RenderQueue are key elements of the 3D engine, they are hidden from the user, who manipulates higher level entities: the Model and the Object.

The Model is a blueprint, as well as being a means to share data between objects, and handle instancing, while an Object is an instance of a Model. Think of it like the blueprint for a house. The blueprint contains information about the wall, stairs, roof location and size, but doesn't have any knowledge about the colour of the walls, the kind of parquet, the furniture and so on. The Model does store geometry, but doesn't have any information about textures, materials, animations and other custom metadata for the resulting Object instance.

Whereas the Effect declares its data requirements, the Object defines them. It tells the engine what file to load for a given texture name. For example, "tAlbedo" texture name is linked to "objects/textures.pak/handgun/gun.tga" filename, which the IOModule will load for us. I'll talk about that in a later installment.

That name and data couple is stored in a Tag. A Tag may contain any type of metadata, including string, vector and matrix types. That provides uniform access to anything the user might want to store about the Object.

Model

A Model is divided into bones, making a skeleton, and Meshes, which are drawable geometry. In the context of a Model, those are called BoneModel and MeshModel respectively. As there can be different ways to instance data, the MeshModel class is abstract, leaving the real implementation in child class such as IMRMeshModel or StaticMeshModel.

IMRMeshModel on this case means Indexed Multi Resolution MeshModel. It's a mesh which has different LoD (Level of Detail) solely based on different Index Buffer selection. The vertices are the same, but they make a different shape as they are connected differently through the Index Buffers. The second has been advertised in Unreal 2 under a similar name (Static Mesh), as an effective way to draw lots of geometry. It's simply a mean to share the Vertex and Index Buffers between all instances, which don't do anything on their content, and so keep them 'static'. For example, a given land patch or rock is stored only once, and redrawn several times with different transformations.

New MeshModels can be added painlessly, to provide other kind of meshes, like procedural-based geometry.

Object

An Object has the same structure as its Model: it has Bones and Meshes as instances of BoneModels and MeshModels, and can be animated. Meshes also store Tags to define their appearances, as said earlier, and Objects store their own set of animations. Objects make the user-interface, and it's through them that the user will command animations to be run, moving them on screen.

Objects are SceneTree nodes, but do not exist in either the SpatialGraph or RenderQueue. Bones, like Objects, are SceneTree nodes, but neither appear in the SpatialGraph and RenderQueue. Meshes are SceneTree nodes, as well as SpatialGraph leafs and RenderQueue items (ie. Renderables).