int Instance::Update(TimeValue t, View& vw, CJRenderer* pRenderer)
{
FreeAll();
// Check visibility
vis = pNode->GetVisibility(t);
if (vis < 0.0f) {
vis = 0.0f;
SetFlag(INST_HIDE, 1);
return 1;
}
if (vis > 1.0f) vis = 1.0f;
SetFlag(INST_HIDE, 0);
// TM's
Interval tmValid(FOREVER);
objToWorld = pNode->GetObjTMAfterWSM(t,&tmValid);
// Is this node negatively scaled
SetFlag(INST_TM_NEGPARITY, TMNegParity(objToWorld));
// Get Object
ObjectState os = pNode->EvalWorldState(t);
pObject = os.obj;
//******************************************************************
// Mesh access.
// In this sample renderer we retrieve the mesh for all nodes,
// then we transform all the vertices to camera space and finally
// we render the frame.
// Problem: When we retrieve the mesh from instanced objects
// we will get the same mesh for all instances.
// As we, in this case, transform the vertices we would do multiple
// (and invalid) transformations of the mesh for instanced objects.
// To solve this in an easy (but expensive way) we make copies of
// all meshes. We can get away with that, because we are
// a sample renderer - however, you are not.
//******************************************************************
// To Implement Geometry Instancing As Follow:
class MeshObjectRef {
public:
MeshObjectRef( Object *o, Mesh *m )
{
objRef = o;
Mesh = m;
}
public:
Object *objRef;
Mesh *mesh;
};
Object *objRef = pNode->GetObjectRef();
bool foundObjRef = false;
// Do a linear scanIt's an inefficient way, but I don't see any other choice
for( int i = 0; i < objRefList.size(); ++i )
{
if( objRefList[i].objRef == objRef )
{
mesh = objRefList[i].mesh;
foundObjRef = true;
break;
}
}
if( !foundObjRef )
{
// Make a complete copy of the mesh
BOOL deleteMesh;
mesh = new Mesh;
Mesh* nodeMesh = ((GeomObject*)pObject)->GetRenderMesh(t, pNode, vw, deleteMesh);
/*
mesh->DeepCopy(nodeMesh, GEOM_CHANNEL | TOPO_CHANNEL | TEXMAP_CHANNEL |
MTL_CHANNEL | DISP_ATTRIB_CHANNEL | TM_CHANNEL);
*/
*mesh = *nodeMesh;
// If the mesh is not a part of the cache, delete it.
if (deleteMesh) {
delete nodeMesh;
}
objRefList.push_back( MeshObjectRef( objRef, mesh ) );
}
for (int i=0; i<mesh->numFaces; i++) {
BoundingSphere* bs = new BoundingSphere;
faceBoundSpheres.Append(1, &bs, 25);
}
pRenderer->nNumFaces+=mesh->numFaces;
return 1;
}
{
FreeAll();
// Check visibility
vis = pNode->GetVisibility(t);
if (vis < 0.0f) {
vis = 0.0f;
SetFlag(INST_HIDE, 1);
return 1;
}
if (vis > 1.0f) vis = 1.0f;
SetFlag(INST_HIDE, 0);
// TM's
Interval tmValid(FOREVER);
objToWorld = pNode->GetObjTMAfterWSM(t,&tmValid);
// Is this node negatively scaled
SetFlag(INST_TM_NEGPARITY, TMNegParity(objToWorld));
// Get Object
ObjectState os = pNode->EvalWorldState(t);
pObject = os.obj;
//******************************************************************
// Mesh access.
// In this sample renderer we retrieve the mesh for all nodes,
// then we transform all the vertices to camera space and finally
// we render the frame.
// Problem: When we retrieve the mesh from instanced objects
// we will get the same mesh for all instances.
// As we, in this case, transform the vertices we would do multiple
// (and invalid) transformations of the mesh for instanced objects.
// To solve this in an easy (but expensive way) we make copies of
// all meshes. We can get away with that, because we are
// a sample renderer - however, you are not.
//******************************************************************
// To Implement Geometry Instancing As Follow:
class MeshObjectRef {
public:
MeshObjectRef( Object *o, Mesh *m )
{
objRef = o;
Mesh = m;
}
public:
Object *objRef;
Mesh *mesh;
};
Object *objRef = pNode->GetObjectRef();
bool foundObjRef = false;
// Do a linear scanIt's an inefficient way, but I don't see any other choice
for( int i = 0; i < objRefList.size(); ++i )
{
if( objRefList[i].objRef == objRef )
{
mesh = objRefList[i].mesh;
foundObjRef = true;
break;
}
}
if( !foundObjRef )
{
// Make a complete copy of the mesh
BOOL deleteMesh;
mesh = new Mesh;
Mesh* nodeMesh = ((GeomObject*)pObject)->GetRenderMesh(t, pNode, vw, deleteMesh);
/*
mesh->DeepCopy(nodeMesh, GEOM_CHANNEL | TOPO_CHANNEL | TEXMAP_CHANNEL |
MTL_CHANNEL | DISP_ATTRIB_CHANNEL | TM_CHANNEL);
*/
*mesh = *nodeMesh;
// If the mesh is not a part of the cache, delete it.
if (deleteMesh) {
delete nodeMesh;
}
objRefList.push_back( MeshObjectRef( objRef, mesh ) );
}
for (int i=0; i<mesh->numFaces; i++) {
BoundingSphere* bs = new BoundingSphere;
faceBoundSpheres.Append(1, &bs, 25);
}
pRenderer->nNumFaces+=mesh->numFaces;
return 1;
}