Scenegraph Models

Most of the exporter code involves converting authoring tool models into Shockwave 3D§ models. This process is somewhat involved because of the Shockwave 3D real-time rendering and resource sharing requirements. This section outlines the process involved in the conversion of model data.

Putting Authoring Data into IFXAuthorMeshGroup

Geometry/mesh data cannot be translated directly into Shockwave 3D. Instead, it must be put into an intermediate class Shockwave 3D provides to hold author-time mesh data. The data is then converted to a format that is optimized for real-time rendering, including generating update records for multiresolution mesh handling.

The first step for getting model data into Shockwave 3D is to transfer the geometry data into an IFXAuthorMeshGroup object. This is done as follows:

  1. Create an IFXAuthorMeshGroup object and allocate space for a single mesh.

    Important Note: If you are collapsing multiple meshes into a single IFXAuthorMeshGroup object, you may want to allocate space for as many IFXAuthorMesh objects as you have meshes that need merging. Although this will work, keep in mind that the IFXAuthorGeomCompiler::Compile() method will run faster and use less memory if you pre-merge the meshes into a single IFXAuthorMesh. The following instructions assume that you have pre-merged all the meshes. If you did not, you will need to repeat steps 2-6 for each IFXAuthorMesh you create.

  2. Fill in an IFXAuthorAllocationDescriptor class with all the information about the mesh, including the number of vertices, faces, normals, and texture coordinates.

    Note: Before calculating the number of faces in the model, remove any zero area faces and adjust the face lists as necessary.

  3. Create an IFXAuthorMesh, allocate its attributes using the IFXAuthorAllocationDescriptor, and set it as the first mesh in the IFXAuthorMeshGroup.

  4. Transfer the mesh's vertices, normals, vertex colors, and other data into the IFXAuthorMesh.

  5. For each face in the IFXAuthorMesh, set the vertex, normal, vertex color, and texture coordinate indices. Set the face's shader ID to the index of a shader found in a style (shader group). This style must itself be an element of the Style Palette in this model's IFXModelResource object. Do not populate the face's shader ID with an actual Shockwave 3D Shader Resource Palette ID. This indirection requires you to know how many shaders a given model uses up-front and to keep track of the correspondence between the style index and the Shockwave 3D shader it references.

  6. If the mesh represented by the IFXAuthorMesh will be deformed by bones, loop through each vertex in the IFXAuthorMesh, using the IFXAuthorMesh::SetVertexWeightCount() method to indicate how many bones influence the vertex and the IFXAuthorMesh::SetVertexWeight()method to set the weight with which each of these bones will influence the vertex. The weights must be normalized (add to 1.0).

See also IFXAuthorMesh and Shaders

Removing Zero Area Faces

The IFXAuthorGeomCompiler::Compile() method requires that all zero area faces of a model be removed. If these faces are not removed, the number of shaders used by the model will not be correct.

To remove zero area faces from a model, reduce the model's face list by doing the following:

  1. Remove all faces that have two or more equal vertex indices.

  2. Remove all faces that have illegal vertex indices (vertex indices are assumed to be contiguous from 0 to the number of vertices in your mesh, minus one).

  3. Go through all surviving faces and apply the following test, which removes any faces with almost zero area :

for (i = 0; i < mesh->numFaces; i++)
{

int vertexindex0 = mesh->face[i].vertexindices[0];
int vertexindex1 = mesh->face[i].vertexindices[1];
int vertexindex2 = mesh->face[i].vertexindices[2];
vector3 v1, v2, vtest;

v1 = mesh->vertex[vertexindex1] - mesh->vertex[vertexindex0];
v2 = mesh->vertex[vertexindex2] - mesh->vertex[vertexindex0];
vtest = v1 cross v2;

if (0.5f * Length(vtest) < (100.0f * FLT_EPSILON))

// throw out this zero area face.

}

More Than One Mesh?

What do you do if the model contains more than one mesh? If these meshes will animate in Shockwave 3D as a single unit, and you don't need separate control over the individual meshes, use the authoring tool to merge the meshes into a single mesh before exporting. Alternatively you can do this in the exporter code and merge the meshes in the conversion. To retain control over some parts of the model, however, these parts must be authored in such a way that they become separate models in Shockwave 3D. For example, if you want the wheels of a model car to rotate while the body remains static, you must author the body of the car with the wheels as children, each separated from the car body by a group node. Alternately, each part of the car could be modeled as separate root-level nodes, or as separate nodes, individually connected to a common group node by intervening group nodes.

Generating the Render-Time Optimized Mesh Data

Once the IFXAuthorMeshGroup is populated, the next step before putting the model into Shockwave 3D is to convert it into a render-time optimized mesh representation. This is done by allocating and initializing the IFXAuthorGeomCompiler interface, and then passing the IFXAuthorMeshGroup, along with any bones associated with this mesh and its multiresolution settings, to the IFXAuthorGeomCompiler::Compile() method. This method will return an IFXModelResource object, which you must associate with the entry for this model in the Model Resource palette.

Shared Meshes

For multiple instances of the same model within the authoring tool scene, created using "instance clones," only a single IFXModelResource should be created for the common geometry shared by the clones, with the multiple nodes in the Node Hierarchy Palette pointing to this IFXModelResource. If the clones do not all share the same shaders, different style (shader group) IDs must be assigned to their hierarchy nodes, and the Style Palette within the IFXModelResource must contain one style (shader group) for each combination of shaders.

Note: Two meshes are considered the same and "sharable" if they:

Compression and the MultiResolution Mesh Representation

Compression removes no vertices from a model (including keyframes and texture colors), but rather causes the vertex positions (including normals and texture coordinates) to be represented with less precision, causing them to drift from their true positions. This drift increases as the compression rises, eventually resulting in a noticeable wrinkling or crumpling of the object. A quality setting of 1000 (see IFXWriteManager::SetQualityFactor()) means least compression of the mesh data with the highest possible accuracy. The mesh positions are not being represented at their original floating point accuracy, but very close to it.

When models are converted to IFXMeshGroups, their meshes are processed and simplified, one vertex at a time, resulting in the mesh's multiresolution representation. This process is reversed when the model is streaming into a Shockwave 3D scene, building the model, one vertex at a time.

Simplification does not create gaps in a model, although it will cause any existing gaps in a model to get larger as the model is simplified. The degree to which a model is automatically simplified depends on the target framerate, the hardware used, the complexity of the model, the distance between the model and the camera, and the complexity of the entire scene. Very large models need to be greatly simplified just to obtain approximately 30 frames per second, even using fast machines, or when the model is far from the camera.

Level-of-detail (LOD) calculations, on the other hand, remove vertices from a model. This is done by looking at the local smoothness or non-smoothness of the surface around each vertex. Smooth surfaces are retained and jagged surfaces are removed.

Sharp but important features, like an antenna on a vehicle, which would be removed, can be preserved by being marked as base vertices. This effectively indicates that these vertices are the last to be removed.

Further tuning of level of detail can be done with the sw3d_lod_adjust_normals, sw3d_lod_minimum_crease_angle, and sw3d_lod_max_normal_error user properties.

Default settings of user properties can result in the removal of vertices that drastically change the surface normal, resulting in a hole in the model. Model faces with inconsistent normal directions or winding order, or that have zero area, for example, can cause tearing of the model when it simplifies. Decreasing the sw3d_lod_max_normal_error or increasing the sw3d_lod_minimum_crease_angle user property values can often remove these holes as the model simplifies, but often at the expense of creating a larger Shockwave 3D file that will take longer to stream.

§See asterisked (*) statement at Legal Information © 2001 Intel Corporation.