Files
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

1708 lines
48 KiB
C++

#include "ElementProxyHeaders.hpp"
typedef int (*LPERROR_CALLBACKFN)(char *,bool);
//
//############################################################################
//######################### ElementPolygonMeshProxy #########################
//############################################################################
//
MemoryBlock*
ElementPolygonMeshProxy::AllocatedMemory = NULL;
ElementPolygonMeshProxy::ClassData*
ElementPolygonMeshProxy::DefaultData = NULL;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::InitializeClass()
{
Verify(!AllocatedMemory);
AllocatedMemory =
new MemoryBlock(
sizeof(ElementPolygonMeshProxy),
10,
10,
"ElementPolygonMeshProxy"
);
Register_Object(AllocatedMemory);
Verify(!DefaultData);
DefaultData =
new ClassData(
ElementPolygonMeshProxyClassID,
"ElementPolygonMeshProxy",
PolygonMeshProxy::DefaultData
);
Register_Object(DefaultData);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::TerminateClass()
{
Unregister_Object(DefaultData);
delete DefaultData;
DefaultData = NULL;
Unregister_Object(AllocatedMemory);
delete AllocatedMemory;
AllocatedMemory = NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::Destroy()
{
Check_Object(this);
Verify(referenceCount == 1);
Verify(activePolygonProxies.IsEmpty());
ShapeElement* shape = proxiedShape;
DetachReference();
Verify(shape->GetMLRShape()->GetReferenceCount() == 1);
Unregister_Object(shape);
delete shape;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementPolygonMeshProxy::ElementPolygonMeshProxy(
ElementSceneProxy *scene,
GroupProxy *parent,
ShapeElement *shape,
ChainIterator *iterator
):
PolygonMeshProxy(DefaultData, scene, parent),
proxiedShape(shape),
siblingIterator(iterator)
{
Check_Pointer(this);
Check_Object(scene);
Check_Object(shape);
//
//----------------------------------------------
// If the shape holds no primitives, we are done
//----------------------------------------------
//
Check_Object(proxiedShape);
mlrShape = proxiedShape->GetMLRShape();
if (mlrShape)
{
Check_Object(mlrShape);
mlrShape->AttachReference();
Verify(mlrShape->GetReferenceCount() == 2);
LoadArrays();
}
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ElementPolygonMeshProxy::~ElementPolygonMeshProxy()
{
Check_Object(this);
Unregister_Object(siblingIterator);
delete siblingIterator;
if (mlrShape)
{
Verify(mlrShape->GetReferenceCount() >= 2);
Check_Object(mlrShape);
mlrShape->DetachReference();
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::TestInstance() const
{
Verify(IsDerivedFrom(DefaultData));
Check_Object(siblingIterator);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::TransferAndAppendToParentGroup(GroupProxy *parent)
{
Check_Object(this);
//
//--------------------------------------------
// Delete our attachment to our current parent
//--------------------------------------------
//
Check_Pointer(proxiedShape);
proxiedShape->DetachFromParent();
ElementGroupProxy *old_parent =
static_cast<ElementGroupProxy*>(GetParentGroupProxy());
if (old_parent)
{
Check_Object(old_parent);
old_parent->DetachChildProxy(this);
GetSceneProxy()->DetachReference();
}
else
{
Check_Object(GetSceneProxy());
GetSceneProxy()->DetachChildProxy(this);
}
//
//---------------------------------------------------------------------
// If a parent is specified, then attach to it, otherwise attach to the
// scene
//---------------------------------------------------------------------
//
GroupElement *parent_rec;
parentProxy = parent;
if (parent)
{
ElementGroupProxy *element_parent =
Cast_Object(ElementGroupProxy*, parent);
parent_rec = element_parent->GetProxiedGroup();
parent->AttachChildProxy(this);
GetSceneProxy()->AttachReference();
}
else
{
ElementSceneProxy *scene = GetSceneProxy();
Check_Object(scene);
parent_rec = scene->GetProxiedScene();
scene->AttachChildProxy(this);
}
Check_Pointer(parent_rec);
parent_rec->AttachChild(proxiedShape);
proxiedShape->Sync();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ChildProxy*
ElementPolygonMeshProxy::UseNextSiblingProxy()
{
Check_Object(this);
//
//------------------------------------------------------------------------
// Clone our iterator, then move it and have the scene figure out the type
// of proxy to create
//------------------------------------------------------------------------
//
Check_Object(siblingIterator);
ChainIterator *iterator = siblingIterator->MakeClone();
Register_Object(iterator);
iterator->Next();
return GetSceneProxy()->InterpretElement(GetParentGroupProxy(), iterator);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
ChildProxy*
ElementPolygonMeshProxy::UsePreviousSiblingProxy()
{
Check_Object(this);
//
//------------------------------------------------------------------------
// Clone our iterator, then move it and have the scene figure out the type
// of proxy to create
//------------------------------------------------------------------------
//
Check_Object(siblingIterator);
ChainIterator *iterator = siblingIterator->MakeClone();
Register_Object(iterator);
iterator->Previous();
return GetSceneProxy()->InterpretElement(GetParentGroupProxy(), iterator);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementPolygonMeshProxy::GetName(MString *name)
{
Check_Object(this);
Check_Object(name);
Check_Object(proxiedShape);
*name = m_name;
return !(!m_name);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetName(const char* name)
{
Check_Object(this);
Check_Pointer(proxiedShape);
m_name=name;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementPolygonMeshProxy::GetLocalToParent(LinearMatrix4D *matrix)
{
Check_Object(this);
Check_Pointer(matrix);
Check_Object(proxiedShape);
*matrix = proxiedShape->GetLocalToParent();
return *matrix != LinearMatrix4D::Identity;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetLocalToParent(const LinearMatrix4D &matrix)
{
Check_Object(this);
Check_Object(&matrix);
Check_Object(proxiedShape);
if (matrix == LinearMatrix4D::Identity)
proxiedShape->SetLocalToParentToIdentity();
else
proxiedShape->SetLocalToParent(matrix);
proxiedShape->Sync();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::GetCentroid(Point3D *center)
{
Check_Object(this);
Check_Pointer(center);
Check_Object(proxiedShape);
if (proxiedShape->m_localOBB.sphereRadius > 0.0f)
*center = proxiedShape->m_localOBB.localToParent;
else
PolygonMeshProxy::GetCentroid(center);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementPolygonMeshProxy::GetOBB(OBB *obb)
{
Check_Object(this);
Check_Pointer(obb);
Check_Object(proxiedShape);
//
//-----------------------------------------------
// Make sure that this proxy thinks it has an OBB
//-----------------------------------------------
//
if (!proxiedShape->IsBoundedByOBB())
return false;
//
//------------------------------
// Copy the data into the sphere
//------------------------------
//
*obb = proxiedShape->m_localOBB;
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetOBB(const OBB &obb)
{
Check_Object(this);
Check_Object(&obb);
Check_Object(proxiedShape);
//
//-------------------------------------------------------------------------
// Set the element into sphere mode, and copy the sphere data into the OBB.
// Then sync it up so everyone is happy
//-------------------------------------------------------------------------
//
proxiedShape->m_localOBB = obb;
proxiedShape->SetOBBMode();
proxiedShape->SetVolumeCullMode();
proxiedShape->Sync();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
ElementPolygonMeshProxy::GetBoundingSphere(Sphere *sphere)
{
Check_Object(this);
Check_Pointer(sphere);
Check_Object(proxiedShape);
//
//------------------------------
// Copy the data into the sphere
//------------------------------
//
sphere->center = proxiedShape->m_localOBB.localToParent;
sphere->radius = proxiedShape->m_localOBB.sphereRadius;
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetBoundingSphere(const Sphere &sphere)
{
Check_Object(this);
Check_Object(&sphere);
Check_Object(proxiedShape);
//
//-------------------------------------------------------------------------
// Set the element into sphere mode, and copy the sphere data into the OBB.
// Then sync it up so everyone is happy
//-------------------------------------------------------------------------
//
proxiedShape->m_localOBB.localToParent.BuildTranslation(sphere.center);
proxiedShape->m_localOBB.sphereRadius = sphere.radius;
proxiedShape->SetSphereMode();
proxiedShape->SetVolumeCullMode();
proxiedShape->Sync();
//
//----------------------------------------------------------------------
// If we are running slow enough, go ahead and check our vertices to see
// that they are in the bounds
//----------------------------------------------------------------------
//
#if defined(_ARMOR)
Point3D center(proxiedShape->m_localOBB.localToParent);
Scalar radius_squared =
proxiedShape->m_localOBB.sphereRadius*proxiedShape->m_localOBB.sphereRadius;
MidLevelRenderer::MLRShape *shape = proxiedShape->GetMLRShape();
Check_Object(shape);
int meshes = shape->GetNum();
for(int m=0; m<meshes; m++)
{
MidLevelRenderer::MLRPrimitiveBase *mesh = shape->Find(m);
Check_Object(mesh);
const Point3D *verts;
int count;
mesh->GetCoordData(&verts, &count);
for (int v=0; v<count; ++v)
{
Vector3D diff;
diff.Subtract(verts[v], center);
Scalar room = radius_squared - diff.GetLengthSquared();
Verify(room >= 0.0f);
}
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
unsigned
ElementPolygonMeshProxy::UsePolygonArray(DynamicArrayOf<PolygonProxy*> *polygons)
{
Check_Object(this);
Check_Object(polygons);
//
//---------------------------------------
// Figure out how many polygons there are
//---------------------------------------
//
unsigned poly_count = 0;
unsigned primitive;
unsigned primitive_count = primitiveArray.GetLength();
for (primitive=0; primitive<primitive_count; ++primitive)
{
poly_count += polygonCountArray[primitive];
}
polygons->SetLength(poly_count);
//
//------------------
// Fill in the array
//------------------
//
poly_count = 0;
for (primitive=0; primitive<primitive_count; ++primitive)
{
for (unsigned polygon=0; polygon<polygonCountArray[primitive]; ++polygon)
{
(*polygons)[poly_count] =
MLRPolygonProxy::MakeProxy(
this,
primitive,
polygon
);
Register_Object((*polygons)[poly_count]);
++poly_count;
}
}
return poly_count;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::AddPolygons(
Process *process,
Stuff::DynamicArrayOf<PolygonProxy*> &source_polygons
)
{
Check_Object(this);
Check_Object(process);
Check_Object(&source_polygons);
//
//------------------------------------------------------------------
// Make an array out of both the source polys and the existing polys
//------------------------------------------------------------------
//
DynamicArrayOf<PolygonProxy*> existing_polygons;
unsigned existing_polys = UsePolygonArray(&existing_polygons);
unsigned source_polys = source_polygons.GetLength();
unsigned total_polys = existing_polys + source_polys;
DynamicArrayOf<PolygonProxy*> new_polys(total_polys);
unsigned i;
for (i=0; i<existing_polys; ++i)
new_polys[i] = existing_polygons[i];
for (i=0; i<source_polys; ++i)
new_polys[i+existing_polys] = source_polygons[i];
//
//------------------------------------------------------------------
// Get index arrays for all the polygons
//------------------------------------------------------------------
//
DynamicArrayOf<DynamicArrayOf<IndexProxy*> > indices(total_polys);
for (i=0; i<total_polys; ++i)
{
PolygonProxy *polygon = new_polys[i];
Check_Object(polygon);
polygon->UseIndexArray(&indices[i]);
}
//
//-------------------------------------------------
// Now do the state analysis of the new polygon set
//-------------------------------------------------
//
DynamicArrayOf<unsigned> match;
DynamicArrayOf<unsigned> count;
DynamicArrayOf<MultiState*> multi_states;
unsigned unique_combinations =
UseMultiStateArray(&multi_states, &match, &count, new_polys);
Verify(unique_combinations>0);
//
//----------------------------------------------------------------
// We need to create one MLRPolyMesh object per unique combination
//----------------------------------------------------------------
//
gos_PushCurrentHeap(MidLevelRenderer::ShapeHeap);
MLRShape *new_shape = new MLRShape(unique_combinations);
Register_Object(new_shape);
int primitive;
for (primitive=0; primitive<unique_combinations; ++primitive)
{
Verify( multi_states[primitive]->GetLength() >= 0 &&
multi_states[primitive]->GetLength() <= 2);
MLRPrimitiveBase* mesh = CreateNewMesh(multi_states[primitive]);
Register_Object(mesh);
new_shape->Add(mesh);
//
//--------------------------------------------------------------------
// For each unique combination, we need to create the mesh data
// structures, so we need to first identify the polygons to be grouped
// together
//--------------------------------------------------------------------
//
Verify(count[primitive]>0);
DynamicArrayOf<PolygonProxy*> polygons(count[primitive]);
DynamicArrayOf<VertexProxy*> vertices(Limits::Max_Number_Vertices_Per_Mesh+Limits::Max_Number_Vertices_Per_Polygon);
unsigned i;
unsigned poly_count = 0;
unsigned vertex_count = 0;
for (i=0; i<total_polys && poly_count<count[primitive]; ++i)
{
PolygonProxy *polygon = new_polys[i];
Check_Object(polygon);
if (match[i] == primitive)
{
for (unsigned j=0; j<indices[i].GetLength(); ++j)
{
IndexProxy *index = indices[i][j];
Check_Object(index);
VertexProxy *vertex = index->GetVertexProxy();
Check_Object(vertex);
//
//--------------------------------------------------------------------
// Compare this vertex proxy to what is already in our pool, and if it
// matches, just use it, otherwise stuff it in the pool
//--------------------------------------------------------------------
//
VertexProxy::AddUniqueVertex(
vertices,
&vertex_count,
vertex,
process->duplicateVertexTolerance
);
}
if (vertex_count<=Limits::Max_Number_Vertices_Per_Mesh) {
polygons[poly_count++] = polygon;
}
else {
if(multi_states[primitive]->GetLength() < 2)
{
SetPolyMeshArrays(
Cast_Pointer(MLR_I_L_PMesh*, mesh),
polygons,
poly_count,
process
);
}
else
{
SetPolyMeshArrays(
Cast_Pointer(MLR_I_L_DT_PMesh*, mesh),
polygons,
poly_count,
process,
multi_states[primitive]->isInverted
);
}
mesh->DetachReference();
mesh = CreateNewMesh(multi_states[primitive]);
Register_Object(mesh);
new_shape->Add(mesh);
vertex_count=0;
for (unsigned j=0; j<indices[i].GetLength(); ++j)
{
IndexProxy *index = indices[i][j];
Check_Object(index);
VertexProxy *vertex = index->GetVertexProxy();
Check_Object(vertex);
//
//--------------------------------------------------------------------
// Compare this vertex proxy to what is already in our pool, and if it
// matches, just use it, otherwise stuff it in the pool
//--------------------------------------------------------------------
//
VertexProxy::AddUniqueVertex(
vertices,
&vertex_count,
vertex,
process->duplicateVertexTolerance
);
}
poly_count=0;
polygons[poly_count++] = polygon;
}
}
}
Verify(poly_count <= count[primitive]);
if(multi_states[primitive]->GetLength() < 2 && polygons.GetLength()>0)
{
SetPolyMeshArrays(
Cast_Pointer(MLR_I_L_PMesh*, mesh),
polygons,
poly_count,
process
);
}
else if (polygons.GetLength()>0)
{
SetPolyMeshArrays(
Cast_Pointer(MLR_I_L_DT_PMesh*, mesh),
polygons,
poly_count,
process,
multi_states[primitive]->isInverted
);
}
multi_states[primitive]->DetachReferences();
mesh->DetachReference();
}
//
//-----------------------------
// Now clean up the index array
//-----------------------------
//
for (i=0; i<total_polys; ++i)
{
Check_Object(new_polys[i]);
Check_Object(&indices[i]);
new_polys[i]->DetachArrayReferences(&indices[i]);
}
//
//-----------------------------------------------------------------------
// Now we need to clean out the shape and stick the new primitives inside
// it
//-----------------------------------------------------------------------
//
DetachArrayReferences(&existing_polygons);
mlrShape->DetachReference();
Check_Object(proxiedShape);
proxiedShape->SetMLRShape(new_shape);
mlrShape = new_shape;
// mlrShape->AttachReference();
gos_PopCurrentHeap();
//
//----------------------------------------------------------
// Clean up the proxy arrays, then load up the useful arrays
//----------------------------------------------------------
//
LoadArrays();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetToMatchMultiState(Proxies::MultiState* multi_state)
{
Check_Object(this);
Check_Object(multi_state);
Verify(multi_state->GetLength() > 0 && multi_state->GetLength() <= 2);
if(multi_state->GetLength() == 1)
{
//
//-------------------------------------------------------------------------
// We need to get a state proxy from the state library that matches what we
// were given
//-------------------------------------------------------------------------
//
MLRStateProxy *our_proxy = Cast_Object(MLRStateProxy*, (*multi_state)[0]);
//
//-----------------------------------------------------------------------
// Now, spin through all the primitives, and set their MLRStates to match
// that of our state proxy
//-----------------------------------------------------------------------
//
unsigned primitive_count = primitiveArray.GetLength();
for (unsigned i=0; i<primitive_count; ++i)
primitiveArray[i]->SetReferenceState(our_proxy->GetMLRState());
}
else
{
//
//-------------------------------------------------------------------------
// We need to get a state proxy from the state library that matches what we
// were given
//-------------------------------------------------------------------------
//
MLRStateProxy *our_proxy = NULL, *our_proxy1 = NULL;
if(multi_state->isInverted == false)
{
our_proxy = Cast_Object(MLRStateProxy*, (*multi_state)[0]);
our_proxy1 = Cast_Object(MLRStateProxy*, (*multi_state)[1]);
}
else
{
our_proxy1 = Cast_Object(MLRStateProxy*, (*multi_state)[0]);
our_proxy = Cast_Object(MLRStateProxy*, (*multi_state)[1]);
}
//
//-----------------------------------------------------------------------
// Now, spin through all the primitives, and set their MLRStates to match
// that of our state proxy
//-----------------------------------------------------------------------
//
unsigned primitive_count = primitiveArray.GetLength();
for (unsigned i=0; i<primitive_count; ++i)
{
primitiveArray[i]->SetReferenceState(our_proxy->GetMLRState());
primitiveArray[i]->SetReferenceState(our_proxy1->GetMLRState(), 1);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
unsigned
ElementPolygonMeshProxy::UseVertexArray(DynamicArrayOf<VertexProxy*> *vertices)
{
Check_Object(this);
Check_Object(vertices);
//
//---------------------------------------
// Figure out how many vertices there are
//---------------------------------------
//
unsigned vertex_count = 0;
unsigned primitive;
unsigned primitive_count = primitiveArray.GetLength();
for (primitive=0; primitive<primitive_count; ++primitive)
{
vertex_count += vertexCountArray[primitive];
}
vertices->SetLength(vertex_count);
//
//------------------
// Fill in the array
//------------------
//
vertex_count = 0;
for (primitive=0; primitive<primitive_count; ++primitive)
{
for (unsigned vertex=0; vertex<vertexCountArray[primitive]; ++vertex)
{
(*vertices)[vertex_count] =
MLRVertexProxy::MakeProxy(
this,
primitive,
vertex
);
Register_Object((*vertices)[vertex_count]);
++vertex_count;
}
}
return vertex_count;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
PolygonProxy*
ElementPolygonMeshProxy::GetPolygonProxy(
int primitive_index,
int polygon_index
)
{
Check_Object(this);
Verify(static_cast<unsigned>(primitive_index) < primitiveArray.GetLength());
//
//-----------------------------------------------------------------------
// See if we have walked off the end of the primitive, and if so, we need
// to find the next primitive
//-----------------------------------------------------------------------
//
int poly_count = polygonCountArray[primitive_index];
Verify(poly_count > 0);
if (polygon_index == poly_count)
{
if (++primitive_index == primitiveArray.GetLength())
return NULL;
polygon_index = 0;
}
//
//-------------------------------
// See if we walked off backwards
//-------------------------------
//
else if (polygon_index == -1)
{
--primitive_index;
if (primitive_index < 0)
{
return NULL;
}
polygon_index = polygonCountArray[primitive_index] - 1;
}
//
//---------------------------------
// We found one, so make a new mesh
//---------------------------------
//
Verify(polygon_index >= 0 && polygon_index < poly_count);
Verify(primitive_index >= 0 && primitive_index < primitiveArray.GetLength());
PolygonProxy *proxy =
MLRPolygonProxy::MakeProxy(
this,
primitive_index,
polygon_index
);
Register_Object(proxy);
return proxy;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
VertexProxy*
ElementPolygonMeshProxy::GetVertexProxy(
int primitive_index,
int vertex_index
)
{
Check_Object(this);
Verify(static_cast<unsigned>(primitive_index) < primitiveArray.GetLength());
//
//-----------------------------------------------------------------------
// See if we have walked off the end of the primitive, and if so, we need
// to find the next primitive
//-----------------------------------------------------------------------
//
int vertex_count = vertexCountArray[primitive_index];
Verify(vertex_count > 0);
if (vertex_index == vertex_count)
{
if (++primitive_index == primitiveArray.GetLength())
return NULL;
vertex_index = 0;
}
//
//-------------------------------
// See if we walked off backwards
//-------------------------------
//
else if (vertex_index == -1)
{
--primitive_index;
if (primitive_index < 0)
return NULL;
vertex_index = vertexCountArray[primitive_index] - 1;
}
//
//---------------------------------
// We found one, so make a new mesh
//---------------------------------
//
Verify(vertex_index >= 0 && vertex_index < vertex_count);
Verify(primitive_index >= 0 && primitive_index < primitiveArray.GetLength());
VertexProxy *proxy =
MLRVertexProxy::MakeProxy(
this,
primitive_index,
vertex_index
);
Register_Object(proxy);
return proxy;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::LoadArrays()
{
Check_Object(this);
//
//----------------------
// Initialize the arrays
//----------------------
//
primitiveArray.SetLength(0);
polygonCountArray.SetLength(0);
vertexCountArray.SetLength(0);
indexArray.SetLength(0);
indexCountArray.SetLength(0);
positionArray.SetLength(0);
normalArray.SetLength(0);
colorArray.SetLength(0);
uvArray.SetLength(0);
//
//----------------------------------------------
// If the shape holds no primitives, we are done
//----------------------------------------------
//
if (!mlrShape)
return;
//
//----------------------------------------------------------------------
// Figure out how many primitive there are, then fill up the arrays with
// stuff from each of them
//----------------------------------------------------------------------
//
Check_Object(mlrShape);
int primitive_count = mlrShape->GetNum();
primitiveArray.SetLength(primitive_count);
polygonCountArray.SetLength(primitive_count);
vertexCountArray.SetLength(primitive_count);
indexCountArray.SetLength(primitive_count);
indexArray.SetLength(primitive_count);
positionArray.SetLength(primitive_count);
normalArray.SetLength(primitive_count);
colorArray.SetLength(primitive_count);
uvArray.SetLength(primitive_count);
int primitive;
for (primitive=0; primitive<primitive_count; ++primitive)
{
//
//-------------------
// Grab the primitive
//-------------------
//
MLRPrimitiveBase *mesh = mlrShape->Find(primitive);
if(mesh->IsDerivedFrom(MLR_I_PMesh::DefaultData))
{
primitiveArray[primitive] =
Cast_Object(MLR_I_PMesh*, mesh);
}
else
{
if(mesh->IsDerivedFrom(MLR_I_TMesh::DefaultData))
{
switch(mesh->GetClassID())
{
case MidLevelRenderer::MLR_I_TMeshClassID:
{
primitiveArray[primitive] = new MLR_I_PMesh;
primitiveArray[primitive]->Copy(Cast_Object(MLR_I_TMesh*, mesh));
}
break;
case MidLevelRenderer::MLR_I_L_TMeshClassID:
{
primitiveArray[primitive] = new MLR_I_PMesh;
primitiveArray[primitive]->Copy(Cast_Object(MLR_I_TMesh*, mesh));
}
break;
}
}
else
{
continue;
}
}
//
//------------------------------------------------
// Create the datastorage object if it isn't there
//------------------------------------------------
//
MidLevelRenderer::DataStorage *data_store = primitiveArray[primitive]->dataStore;
if (!data_store)
{
data_store = new MidLevelRenderer::DataStorage;
primitiveArray[primitive]->dataStore = data_store;
}
Check_Pointer(data_store);
//
//---------------------
// Load up the vertices
//---------------------
//
gos_PushCurrentHeap(MidLevelRenderer::Heap);
int test_count;
const Stuff::Point3D *points;
primitiveArray[primitive]->GetCoordData(&points, &test_count);
if (points != data_store->coords.GetData())
{
data_store->coords.AssignData(points, test_count);
primitiveArray[primitive]->SetCoordData(data_store->coords.GetData(), test_count);
}
positionArray[primitive] = data_store->coords.GetData();
Check_Pointer(positionArray[primitive]);
vertexCountArray[primitive] = test_count;
//
//----------------------------------------------------------------------
// The specific primitive will tell us how to deal with normal and color
// data
//----------------------------------------------------------------------
//
if (
primitiveArray[primitive]->IsDerivedFrom(
MidLevelRenderer::MLR_I_C_PMesh::DefaultData
)
)
{
MLR_I_C_PMesh* color_primitive =
Cast_Object(MLR_I_C_PMesh*, primitiveArray[primitive]);
const MidLevelRenderer::ColorType *colors;
color_primitive->GetColorData(&colors, &test_count);
if (colors != data_store->colors.GetData())
{
data_store->colors.AssignData(colors, test_count);
color_primitive->SetColorData(data_store->colors.GetData(), test_count);
Verify(test_count == vertexCountArray[primitive]);
}
colorArray[primitive] = data_store->colors.GetData();
//
//------------------
// Are there normals
//------------------
//
if (
color_primitive->IsDerivedFrom(
MidLevelRenderer::MLR_I_L_PMesh::DefaultData
)
)
{
MLR_I_L_PMesh* lit_primitive =
Cast_Object(MLR_I_L_PMesh*, color_primitive);
const Stuff::Vector3D *normals;
lit_primitive->GetNormalData(&normals, &test_count);
if (normals != data_store->normals.GetData())
{
data_store->normals.AssignData(normals, test_count);
lit_primitive->SetNormalData(data_store->normals.GetData(), test_count);
}
normalArray[primitive] = data_store->normals.GetData();
Verify(test_count == 0 || test_count == vertexCountArray[primitive]);
}
else
normalArray[primitive] = NULL;
}
else if (
primitiveArray[primitive]->IsDerivedFrom(
MidLevelRenderer::MLR_I_C_DT_PMesh::DefaultData
)
)
{
MLR_I_C_DT_PMesh* color_primitive =
Cast_Object(MLR_I_C_DT_PMesh*, primitiveArray[primitive]);
const MidLevelRenderer::ColorType *colors;
color_primitive->GetColorData(&colors, &test_count);
if (colors != data_store->colors.GetData())
{
data_store->colors.AssignData(colors, test_count);
color_primitive->SetColorData(data_store->colors.GetData(), test_count);
Verify(test_count == vertexCountArray[primitive]);
}
colorArray[primitive] = data_store->colors.GetData();
//
//------------------
// Are there normals
//------------------
//
if (
color_primitive->IsDerivedFrom(
MidLevelRenderer::MLR_I_L_DT_PMesh::DefaultData
)
)
{
MLR_I_L_DT_PMesh* lit_primitive =
Cast_Object(MLR_I_L_DT_PMesh*, color_primitive);
const Stuff::Vector3D *normals;
lit_primitive->GetNormalData(&normals, &test_count);
if (normals != data_store->normals.GetData())
{
data_store->normals.AssignData(normals, test_count);
lit_primitive->SetNormalData(data_store->normals.GetData(), test_count);
}
normalArray[primitive] = data_store->normals.GetData();
Verify(test_count == 0 || test_count == vertexCountArray[primitive]);
}
else
normalArray[primitive] = NULL;
}
//
//---------------------
// No normals or colors
//---------------------
//
else
{
normalArray[primitive] = NULL;
colorArray[primitive] = NULL;
}
const Stuff::Vector2DOf<Scalar> *uvs;
primitiveArray[primitive]->GetTexCoordData(&uvs, &test_count);
if (uvs != data_store->texCoords.GetData())
{
data_store->texCoords.AssignData(uvs, test_count);
primitiveArray[primitive]->SetTexCoordData(data_store->texCoords.GetData(), test_count);
}
uvArray[primitive] = data_store->texCoords.GetData();
Verify(test_count == primitiveArray[primitive]->GetNumPasses() * vertexCountArray[primitive]);
//
//----------------------------
// Load up the polygon indices
//----------------------------
//
const BYTE *lengths;
primitiveArray[primitive]->GetSubprimitiveLengths(&lengths, &polygonCountArray[primitive]);
if (lengths != data_store->lengths.GetData())
{
data_store->lengths.AssignData(lengths, test_count);
primitiveArray[primitive]->SetSubprimitiveLengths(
data_store->lengths.GetData(),
polygonCountArray[primitive]
);
}
indexCountArray[primitive] = data_store->lengths.GetData();
//
//--------------------
// Load up the indices
//--------------------
//
const BYTE *indices;
primitiveArray[primitive]->GetIndexData(&indices, &test_count);
if (indices != data_store->index.GetData())
{
data_store->index.AssignData(indices, test_count);
primitiveArray[primitive]->SetIndexData(data_store->index.GetData(), test_count);
}
indexArray[primitive] = data_store->index.GetData();
gos_PopCurrentHeap();
}
Check_Object(this);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetPolyMeshArrays(
MLR_I_L_PMesh *mesh,
DynamicArrayOf<PolygonProxy*> &polygons,
int poly_count,
Process *process
)
{
Check_Object(mesh);
Check_Object(&polygons);
Check_Object(process);
//
//---------------------------------------------------------------------
// Now that we know the polygons we will be adding, we need to create
// the data structures to fill MLR up with, so first find out the total
// number of vertex indices
//---------------------------------------------------------------------
//
//unsigned poly_count = polygons.GetLength();
DynamicArrayOf<DynamicArrayOf<IndexProxy*> > source_indices(poly_count);
DynamicArrayOf<BYTE> index_counts(poly_count);
unsigned
index_count = 0,
polygon;
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(polygons[polygon]);
unsigned count =
polygons[polygon]->UseIndexArray(&source_indices[polygon]);
Verify(count < 256);
index_counts[polygon] = static_cast<BYTE>(count);
Verify(index_counts[polygon] == source_indices[polygon].GetLength());
index_count += index_counts[polygon];
}
//
//--------------------------------------------------------------------------
// Create a vertex array set to the maximum size possible, then loop through
// the polygons and build the vertex array
//--------------------------------------------------------------------------
//
DynamicArrayOf<VertexProxy*> vertices(Limits::Max_Number_Vertices_Per_Mesh);
DynamicArrayOf<BYTE> indices(index_count);
unsigned vertex_count = 0;
unsigned current_index = 0;
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(&source_indices[polygon]);
for (unsigned i=0; i<source_indices[polygon].GetLength(); ++i)
{
IndexProxy *index = source_indices[polygon][i];
Check_Object(index);
VertexProxy *vertex = index->GetVertexProxy();
Check_Object(vertex);
//
//--------------------------------------------------------------------
// Compare this vertex proxy to what is already in our pool, and if it
// matches, just use it, otherwise stuff it in the pool
//--------------------------------------------------------------------
//
unsigned temp =
VertexProxy::AddUniqueVertex(
vertices,
&vertex_count,
vertex,
process->duplicateVertexTolerance
);
BYTE vertex_index = static_cast<BYTE>(temp);
if (temp >= Limits::Max_Number_Vertices_Per_Mesh)
STOP(("You have a mesh with more than %d vertices, exporter error, please contact fwang",Limits::Max_Number_Vertices_Per_Mesh));
//
//---------------------------------
// Set the value in the index array
//---------------------------------
//
indices[current_index++] = vertex_index;
}
}
//
//------------------------------------------------
// Create the datastorage object if it isn't there
//------------------------------------------------
//
MidLevelRenderer::DataStorage *data_store = mesh->dataStore;
if (!data_store)
{
data_store = new MidLevelRenderer::DataStorage;
mesh->dataStore = data_store;
}
Check_Pointer(data_store);
//
//---------------------------------------------------------
// Create the polygon lengths in MLR and set up the indices
//---------------------------------------------------------
//
data_store->lengths.AssignData(index_counts.GetData(), poly_count);
mesh->SetSubprimitiveLengths(
data_store->lengths.GetData(),
poly_count
);
Verify(index_count > 0);
Verify(vertex_count > 0);
Verify(index_count == current_index);
//
//------------------------------------------------
// Extract the vertex information from our proxies
//------------------------------------------------
//
DynamicArrayOf<Point3D> positions(vertex_count);
DynamicArrayOf<Vector3D> normals(vertex_count);
DynamicArrayOf<Vector2DScalar> uvs(vertex_count);
DynamicArrayOf<Vector2DScalar> temp_uvs;
DynamicArrayOf<ColorType> colors(vertex_count);
current_index=0;
bool
has_normal = false;
for (current_index=0; current_index<vertex_count; ++current_index)
{
Check_Object(vertices[current_index]);
vertices[current_index]->GetPosition(&positions[current_index]);
//
//-------------------------------------------
// If colors are missing, assume bright white
//-------------------------------------------
//
RGBAColor temp_color;
if (!vertices[current_index]->GetColor(&temp_color))
{
#if COLOR_AS_DWORD>0
colors[current_index] = 0xffffffff;
#else
colors[current_index].red = 1.0f;
colors[current_index].green = 1.0f;
colors[current_index].blue = 1.0f;
colors[current_index].alpha = 1.0f;
#endif
}
else
{
#if COLOR_AS_DWORD>0
colors[current_index] = GOSCopyColor(&temp_color);
#else
colors[current_index] = temp_color;
#endif
}
//
//-----------------------
// Missing UVs map to 0,0
//-----------------------
//
if (!vertices[current_index]->GetUVs(&temp_uvs))
{
uvs[current_index].x = 0.0f;
uvs[current_index].y = 0.0f;
}
else
{
Verify(temp_uvs.GetLength() == 1);
if (temp_uvs[0].x<-0.015625f || temp_uvs[0].x>1.015625f ||
temp_uvs[0].y<-0.015625f || temp_uvs[0].y>1.015625f)
{
char buffer[200];
MString name;
GetName(&name);
if (process->errorfn && !(!name)) {
sprintf(buffer, "%s has bad UV (%f %f) at vertex %d!", (char*)name, temp_uvs[0].x,temp_uvs[0].y,current_index);
LPERROR_CALLBACKFN fcn = (LPERROR_CALLBACKFN)process->errorfn;
fcn(buffer,process->suppress);
}
}
uvs[current_index] = temp_uvs[0];
}
//
//------------------------------------------------
// We should have either no normals or all normals
//------------------------------------------------
//
bool temp =
vertices[current_index]->GetNormal(
Cast_Pointer(Normal3D*, &normals[current_index])
);
if (!current_index)
has_normal = temp;
else
Verify(temp == has_normal);
}
//
//------------------------
// Set the data within MLR
//------------------------
//
data_store->coords.AssignData(positions.GetData(), vertex_count);
mesh->SetCoordData(data_store->coords.GetData(), vertex_count);
data_store->index.AssignData(indices.GetData(), index_count);
mesh->SetIndexData(data_store->index.GetData(), index_count);
data_store->colors.AssignData(colors.GetData(), vertex_count);
mesh->SetColorData(data_store->colors.GetData(), vertex_count);
data_store->texCoords.AssignData(uvs.GetData(), vertex_count);
mesh->SetTexCoordData(data_store->texCoords.GetData(), vertex_count);
if (has_normal)
{
data_store->normals.AssignData(normals.GetData(), vertex_count);
mesh->SetNormalData(data_store->normals.GetData(), vertex_count);
}
//
//-----------------------------
// Now clean up the index array
//-----------------------------
//
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(polygons[polygon]);
Check_Object(&source_indices[polygon]);
polygons[polygon]->DetachArrayReferences(&source_indices[polygon]);
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ElementPolygonMeshProxy::SetPolyMeshArrays(
MLR_I_L_DT_PMesh *mesh,
DynamicArrayOf<PolygonProxy*> &polygons,
int poly_count,
Process *process,
bool isInverted
)
{
Check_Object(mesh);
Check_Object(&polygons);
Check_Object(process);
//
//---------------------------------------------------------------------
// Now that we know the polygons we will be adding, we need to create
// the data structures to fill MLR up with, so first find out the total
// number of vertex indices
//---------------------------------------------------------------------
//
//unsigned poly_count = polygons.GetLength();
DynamicArrayOf<DynamicArrayOf<IndexProxy*> > source_indices(poly_count);
DynamicArrayOf<BYTE> index_counts(poly_count);
unsigned
index_count = 0,
polygon;
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(polygons[polygon]);
unsigned count =
polygons[polygon]->UseIndexArray(&source_indices[polygon]);
Verify(count < 256);
index_counts[polygon] = static_cast<BYTE>(count);
Verify(index_counts[polygon] == source_indices[polygon].GetLength());
index_count += index_counts[polygon];
}
//
//--------------------------------------------------------------------------
// Create a vertex array set to the maximum size possible, then loop through
// the polygons and build the vertex array
//--------------------------------------------------------------------------
//
DynamicArrayOf<VertexProxy*> vertices(Limits::Max_Number_Vertices_Per_Mesh);
DynamicArrayOf<BYTE> indices(index_count);
unsigned vertex_count = 0;
unsigned current_index = 0;
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(&source_indices[polygon]);
for (unsigned i=0; i<source_indices[polygon].GetLength(); ++i)
{
IndexProxy *index = source_indices[polygon][i];
Check_Object(index);
VertexProxy *vertex = index->GetVertexProxy();
Check_Object(vertex);
//
//--------------------------------------------------------------------
// Compare this vertex proxy to what is already in our pool, and if it
// matches, just use it, otherwise stuff it in the pool
//--------------------------------------------------------------------
//
unsigned temp =
VertexProxy::AddUniqueVertex(
vertices,
&vertex_count,
vertex,
process->duplicateVertexTolerance
);
BYTE vertex_index = static_cast<BYTE>(temp);
if (temp >= Limits::Max_Number_Vertices_Per_Mesh)
STOP(("You have a mesh with more than %d vertices, exporter error, please contact fwang",Limits::Max_Number_Vertices_Per_Mesh));
//
//---------------------------------
// Set the value in the index array
//---------------------------------
//
indices[current_index++] = vertex_index;
}
}
//
//------------------------------------------------
// Create the datastorage object if it isn't there
//------------------------------------------------
//
MidLevelRenderer::DataStorage *data_store = mesh->dataStore;
if (!data_store)
{
data_store = new MidLevelRenderer::DataStorage;
mesh->dataStore = data_store;
}
Check_Pointer(data_store);
//
//---------------------------------------------------------
// Create the polygon lengths in MLR and set up the indices
//---------------------------------------------------------
//
data_store->lengths.AssignData(index_counts.GetData(), poly_count);
mesh->SetSubprimitiveLengths(
data_store->lengths.GetData(),
poly_count
);
Verify(index_count > 0);
Verify(vertex_count > 0);
Verify(index_count == current_index);
//
//------------------------------------------------
// Extract the vertex information from our proxies
//------------------------------------------------
//
DynamicArrayOf<Point3D> positions(vertex_count);
DynamicArrayOf<Vector3D> normals(vertex_count);
DynamicArrayOf<Vector2DScalar> uvs(2*vertex_count);
DynamicArrayOf<Vector2DScalar> temp_uvs;
DynamicArrayOf<ColorType> colors(vertex_count);
current_index=0;
bool
has_normal = false;
for (current_index=0; current_index<vertex_count; ++current_index)
{
Check_Object(vertices[current_index]);
vertices[current_index]->GetPosition(&positions[current_index]);
//
//-------------------------------------------
// If colors are missing, assume bright white
//-------------------------------------------
//
RGBAColor temp_color;
if (!vertices[current_index]->GetColor(&temp_color))
{
#if COLOR_AS_DWORD>0
colors[current_index] = 0xffffffff;
#else
colors[current_index].red = 1.0f;
colors[current_index].green = 1.0f;
colors[current_index].blue = 1.0f;
colors[current_index].alpha = 1.0f;
#endif
}
else
{
#if COLOR_AS_DWORD>0
colors[current_index] = GOSCopyColor(&temp_color);
#else
colors[current_index] = temp_color;
#endif
}
//
//-----------------------
// Missing UVs map to 0,0
//-----------------------
//
if (!vertices[current_index]->GetUVs(&temp_uvs))
{
uvs[current_index].x = 0.0f;
uvs[current_index].y = 0.0f;
}
else
{
Verify(temp_uvs.GetLength() <= 2);
if(isInverted==false)
{
uvs[current_index] = temp_uvs[0];
uvs[current_index+vertex_count] = temp_uvs[1];
}
else
{
uvs[current_index] = temp_uvs[1];
uvs[current_index+vertex_count] = temp_uvs[0];
}
}
//
//------------------------------------------------
// We should have either no normals or all normals
//------------------------------------------------
//
bool temp =
vertices[current_index]->GetNormal(
Cast_Pointer(Normal3D*, &normals[current_index])
);
if (!current_index)
has_normal = temp;
else
Verify(temp == has_normal);
}
//
//------------------------
// Set the data within MLR
//------------------------
//
data_store->coords.AssignData(positions.GetData(), vertex_count);
mesh->SetCoordData(data_store->coords.GetData(), vertex_count);
data_store->index.AssignData(indices.GetData(), index_count);
mesh->SetIndexData(data_store->index.GetData(), index_count);
data_store->colors.AssignData(colors.GetData(), vertex_count);
mesh->SetColorData(data_store->colors.GetData(), vertex_count);
data_store->texCoords.AssignData(uvs.GetData(), 2*vertex_count);
mesh->SetTexCoordData(data_store->texCoords.GetData(), 2*vertex_count);
if (has_normal)
{
data_store->normals.AssignData(normals.GetData(), vertex_count);
mesh->SetNormalData(data_store->normals.GetData(), vertex_count);
}
//
//-----------------------------
// Now clean up the index array
//-----------------------------
//
for (polygon=0; polygon<poly_count; ++polygon)
{
Check_Object(polygons[polygon]);
Check_Object(&source_indices[polygon]);
polygons[polygon]->DetachArrayReferences(&source_indices[polygon]);
}
}
MLRPrimitiveBase*
ElementPolygonMeshProxy::CreateNewMesh(MultiState* multiState)
{
MLRPrimitiveBase* mesh;
if(multiState->GetLength() < 2)
{
mesh = new MLR_I_L_PMesh;
}
else
{
mesh = new MLR_I_L_DT_PMesh;
}
Register_Object(mesh);
Check_Object(multiState);
ElementSceneProxy *scene = GetSceneProxy();
Check_Object(scene);
StateLibrary *state_library = scene->GetStateLibrary();
Check_Object(state_library);
if(multiState->GetLength() > 0)
{
MLRStateProxy *state =
Cast_Object(
MLRStateProxy*,
state_library->UseMatchingStateProxy((*multiState)[0])
);
Check_Object(state);
MLRState mlr_state;
mesh->SetReferenceState(state->GetMLRState());
state->DetachReference();
}
if(multiState->GetLength() > 1)
{
MLRStateProxy *state =
Cast_Object(
MLRStateProxy*,
state_library->UseMatchingStateProxy((*multiState)[1])
);
Check_Object(state);
MLRState mlr_state;
if(multiState->isInverted == false)
{
mesh->SetReferenceState(state->GetMLRState(), 1);
}
else
{
mesh->SetReferenceState(mesh->GetReferenceState(), 1);
mesh->SetReferenceState(state->GetMLRState(), 0);
}
state->DetachReference();
}
return mesh;
}