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.
758 lines
18 KiB
C++
758 lines
18 KiB
C++
#include "ProxyHeaders.hpp"
|
|
|
|
//
|
|
//############################################################################
|
|
//########################### Multistate #############################
|
|
//############################################################################
|
|
//
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
MultiState::IsEqualTo(const MultiState& multi_state)
|
|
{
|
|
if(GetLength() != multi_state.GetLength())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for(unsigned i=0;i<GetLength();++i)
|
|
{
|
|
if(!((*this)[i]->IsEqualTo(multi_state[i])))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MultiState::MultiState(const MultiState& multi_state)
|
|
{
|
|
Check_Object(this);
|
|
|
|
unsigned state_count = multi_state.GetLength();
|
|
|
|
SetLength(state_count);
|
|
|
|
for (unsigned i=0; i<state_count; ++i)
|
|
{
|
|
(*this)[i] = multi_state[i];
|
|
|
|
(*this)[i]->AttachReference();
|
|
}
|
|
|
|
isInverted = multi_state.isInverted;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
MultiState&
|
|
MultiState::operator=(const MultiState& multi_state)
|
|
{
|
|
Check_Object(this);
|
|
|
|
unsigned state_count = multi_state.GetLength();
|
|
|
|
SetLength(state_count);
|
|
|
|
for (unsigned i=0; i<state_count; ++i)
|
|
{
|
|
(*this)[i] = multi_state[i];
|
|
|
|
(*this)[i]->AttachReference();
|
|
}
|
|
|
|
isInverted = multi_state.isInverted;
|
|
|
|
return *this;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
/*
|
|
unsigned
|
|
MultiState::UseStateArray(MultiState *states)
|
|
{
|
|
Check_Object(this);
|
|
|
|
unsigned state_count = GetLength();
|
|
states->SetLength(state_count);
|
|
for (unsigned i=0; i<state_count; ++i)
|
|
{
|
|
(*states)[i] = (*this)[i];
|
|
|
|
(*states)[i]->AttachReference();
|
|
}
|
|
return state_count;
|
|
}
|
|
*/
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
MultiState::DetachReferences()
|
|
{
|
|
for(unsigned i=0;i<GetLength();++i)
|
|
{
|
|
(*this)[i]->DetachReference();
|
|
}
|
|
|
|
SetLength(0);
|
|
}
|
|
|
|
|
|
//
|
|
//############################################################################
|
|
//########################### PolygonProxy #############################
|
|
//############################################################################
|
|
//
|
|
|
|
PolygonProxy::ClassData*
|
|
PolygonProxy::DefaultData = NULL;
|
|
MemoryBlock*
|
|
PolygonProxy::AllocatedMemory = NULL;
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::InitializeClass()
|
|
{
|
|
Verify(!AllocatedMemory);
|
|
AllocatedMemory =
|
|
new MemoryBlock(
|
|
sizeof(PolygonProxy),
|
|
100,
|
|
100,
|
|
"PolygonProxy"
|
|
);
|
|
Register_Object(AllocatedMemory);
|
|
|
|
Verify(!DefaultData);
|
|
DefaultData =
|
|
new ClassData(
|
|
PolygonProxyClassID,
|
|
"PolygonProxy",
|
|
GenericProxy::DefaultData
|
|
);
|
|
Register_Object(DefaultData);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::TerminateClass()
|
|
{
|
|
Unregister_Object(DefaultData);
|
|
delete DefaultData;
|
|
DefaultData = NULL;
|
|
|
|
Unregister_Object(AllocatedMemory);
|
|
delete AllocatedMemory;
|
|
AllocatedMemory = NULL;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
PolygonProxy::PolygonProxy(
|
|
ClassData *class_data,
|
|
PolygonMeshProxy *mesh
|
|
):
|
|
GenericProxy(class_data),
|
|
meshProxy(mesh),
|
|
activeIndexProxies(NULL)
|
|
{
|
|
Check_Pointer(this);
|
|
Check_Object(meshProxy);
|
|
meshProxy->AttachPolygonProxy(this);
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
PolygonProxy::PolygonProxy():
|
|
GenericProxy(DefaultData),
|
|
meshProxy(NULL),
|
|
activeIndexProxies(NULL)
|
|
{
|
|
Check_Object(this);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
PolygonProxy::~PolygonProxy()
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//---------------------------------------
|
|
// Detach the state array if there is one
|
|
//---------------------------------------
|
|
//
|
|
unsigned i;
|
|
stateArray.DetachReferences();
|
|
|
|
//
|
|
//----------------------------------------
|
|
// Detach the vertex array if there is one
|
|
//----------------------------------------
|
|
//
|
|
unsigned vertex_count = vertexArray.GetLength();
|
|
for (i=0; i<vertex_count; ++i)
|
|
{
|
|
Verify(GetClassID() == PolygonProxyClassID);
|
|
Check_Object(vertexArray[i]);
|
|
vertexArray[i]->DetachReference();
|
|
}
|
|
|
|
//
|
|
//--------------------------------------
|
|
// Detach the mesh proxy if there is one
|
|
//--------------------------------------
|
|
//
|
|
if (meshProxy)
|
|
{
|
|
Check_Object(meshProxy);
|
|
Verify(activeIndexProxies.IsEmpty());
|
|
meshProxy->DetachPolygonProxy(this);
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::Destroy()
|
|
{
|
|
Check_Object(this);
|
|
Verify(referenceCount == 1);
|
|
Verify(activeIndexProxies.IsEmpty());
|
|
DetachReference();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::TestInstance() const
|
|
{
|
|
Verify(IsDerivedFrom(DefaultData));
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
unsigned
|
|
PolygonProxy::UseMultiState(MultiState *states)
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetClassID() == PolygonProxyClassID);
|
|
|
|
*states = stateArray;
|
|
|
|
return stateArray.GetLength();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::SetStatesToMatch(const MultiState &states)
|
|
{
|
|
Check_Object(this);
|
|
Verify(GetClassID() == PolygonProxyClassID);
|
|
|
|
Verify(states.GetLength() > 0);
|
|
stateArray = states;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::AddToCollection(const char *group)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(group);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::AddToCollections(MStringChain &group_list)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&group_list);
|
|
MStringChainIterator groups(&group_list);
|
|
PlugOf<MString> *group;
|
|
while ((group = groups.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(group);
|
|
AddToCollection(group->GetItem());
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::RemoveFromCollection(const char *group)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(group);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::RemoveFromCollections(MStringChain &group_list)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&group_list);
|
|
MStringChainIterator groups(&group_list);
|
|
PlugOf<MString> *group;
|
|
while ((group = groups.ReadAndNext()) != NULL)
|
|
{
|
|
Check_Object(group);
|
|
RemoveFromCollection(group->GetItem());
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::GetCollections(MStringChain *group_list)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(group_list);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
bool
|
|
PolygonProxy::IsMemberOf(const char* group)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(group);
|
|
return false;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::DetachIndexProxy(IndexProxy* proxy)
|
|
{
|
|
Check_Object(this);
|
|
activeIndexProxies.RemovePlug(proxy);
|
|
Verify(referenceCount > 1);
|
|
DetachReference();
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::GetNormal(Normal3D *normal)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(normal);
|
|
|
|
//
|
|
//-----------------
|
|
// Get the vertices
|
|
//-----------------
|
|
//
|
|
DynamicArrayOf<IndexProxy*> indices;
|
|
#if defined(_ARMOR)
|
|
unsigned index_count = UseIndexArray(&indices);
|
|
Verify(index_count == indices.GetLength());
|
|
Verify(index_count >= 3);
|
|
#endif
|
|
IndexProxy *index_a = indices[0];
|
|
Check_Object(index_a);
|
|
IndexProxy *index_b = indices[1];
|
|
Check_Object(index_b);
|
|
IndexProxy *index_c = indices[2];
|
|
Check_Object(index_c);
|
|
|
|
//
|
|
//------------------------------------------
|
|
// Get the positions and release the proxies
|
|
//------------------------------------------
|
|
//
|
|
VertexProxy *vertex = index_a->GetVertexProxy();
|
|
Check_Object(vertex);
|
|
Point3D position_a;
|
|
vertex->GetPosition(&position_a);
|
|
|
|
vertex = index_b->GetVertexProxy();
|
|
Check_Object(vertex);
|
|
Point3D position_b;
|
|
vertex->GetPosition(&position_b);
|
|
|
|
vertex = index_c->GetVertexProxy();
|
|
Check_Object(vertex);
|
|
Point3D position_c;
|
|
vertex->GetPosition(&position_c);
|
|
DetachArrayReferences(&indices);
|
|
|
|
//
|
|
//--------------------
|
|
// Get the leg vectors
|
|
//--------------------
|
|
//
|
|
Vector3D
|
|
leg_1,
|
|
leg_2;
|
|
leg_1.Subtract(position_b, position_a);
|
|
leg_2.Subtract(position_c, position_a);
|
|
|
|
//
|
|
//----------------------------------------------------------------------
|
|
// Compute the cross-product of the two legs to get the direction of the
|
|
// normal
|
|
//----------------------------------------------------------------------
|
|
//
|
|
Vector3D v;
|
|
v.Cross(leg_1, leg_2);
|
|
*normal = v;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Scalar
|
|
PolygonProxy::GetArea()
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//---------------------
|
|
// Set up the variables
|
|
//---------------------
|
|
//
|
|
Point3D
|
|
position_a = Point3D::Identity,
|
|
position_b,
|
|
position_c = Point3D::Identity;
|
|
VertexProxy
|
|
*vertex_a = NULL,
|
|
*vertex_b = NULL,
|
|
*vertex_c = NULL;
|
|
Vector3D
|
|
leg_1,
|
|
leg_2 = Vector3D::Identity;
|
|
|
|
//
|
|
//-----------------------------------
|
|
// Spin through, testing the vertices
|
|
//-----------------------------------
|
|
//
|
|
Scalar area = 0.0f;
|
|
DynamicArrayOf<IndexProxy*> indices;
|
|
unsigned index_count = UseIndexArray(&indices);
|
|
Verify(index_count == indices.GetLength());
|
|
Verify(index_count >= 3);
|
|
for (unsigned i=0; i<index_count-2; ++i)
|
|
{
|
|
//
|
|
//-----------------------------------------------
|
|
// Generate all the information on the first pass
|
|
//-----------------------------------------------
|
|
//
|
|
if (!i)
|
|
{
|
|
Check_Object(indices[0]);
|
|
vertex_a = indices[0]->GetVertexProxy();
|
|
Check_Object(vertex_a);
|
|
|
|
Check_Object(indices[1]);
|
|
vertex_b = indices[1]->GetVertexProxy();
|
|
Check_Object(vertex_b);
|
|
|
|
Check_Object(indices[2]);
|
|
vertex_c = indices[2]->GetVertexProxy();
|
|
Check_Object(vertex_c);
|
|
|
|
vertex_a->GetPosition(&position_a);
|
|
vertex_b->GetPosition(&position_b);
|
|
vertex_c->GetPosition(&position_c);
|
|
|
|
leg_1.Subtract(position_b, position_a);
|
|
leg_2.Subtract(position_c, position_a);
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// Get the index info. If this is not the first pass, copy the
|
|
// information from last pass
|
|
//--------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
Check_Object(vertex_c);
|
|
vertex_b = vertex_c;
|
|
Check_Object(indices[i+2]);
|
|
vertex_c = indices[i+2]->GetVertexProxy();
|
|
Check_Object(vertex_c);
|
|
|
|
position_b = position_c;
|
|
vertex_c->GetPosition(&position_c);
|
|
leg_1 = leg_2;
|
|
leg_2.Subtract(position_c, position_a);
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------------------
|
|
// Compute the cross-product of the two legs to get the area of the
|
|
// triangle
|
|
//-----------------------------------------------------------------
|
|
//
|
|
Vector3D v;
|
|
v.Cross(leg_1, leg_2);
|
|
area += v.GetLength();
|
|
}
|
|
|
|
//
|
|
//-----------------------------
|
|
// Delete the remaining proxies
|
|
//-----------------------------
|
|
//
|
|
DetachArrayReferences(&indices);
|
|
return 0.5f * area;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::GetVertexCentroid(Point3D *center)
|
|
{
|
|
Check_Object(this);
|
|
Check_Pointer(center);
|
|
|
|
//
|
|
//------------------------------
|
|
// Add all the vertices together
|
|
//------------------------------
|
|
//
|
|
*center = Point3D::Identity;
|
|
DynamicArrayOf<IndexProxy*> indices;
|
|
unsigned index_count = UseIndexArray(&indices);
|
|
Verify(index_count >= 3);
|
|
Verify(index_count == indices.GetLength());
|
|
for (unsigned i=0; i<index_count; ++i)
|
|
{
|
|
IndexProxy *index = indices[i];
|
|
Check_Object(index);
|
|
VertexProxy *vertex = index->GetVertexProxy();
|
|
Check_Object(vertex);
|
|
Point3D position;
|
|
vertex->GetPosition(&position);
|
|
*center += position;
|
|
}
|
|
DetachArrayReferences(&indices);
|
|
|
|
//
|
|
//----------------------
|
|
// Now, average them all
|
|
//----------------------
|
|
//
|
|
*center /= static_cast<Scalar>(index_count);
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
Scalar
|
|
PolygonProxy::GetSurfaceAreaAndCentroid(Point3D *center)
|
|
{
|
|
Check_Object(this);
|
|
|
|
//
|
|
//---------------------
|
|
// Set up the variables
|
|
//---------------------
|
|
//
|
|
Point3D
|
|
position_a = Point3D::Identity,
|
|
position_b,
|
|
position_c = Point3D::Identity;
|
|
VertexProxy
|
|
*vertex_a = NULL,
|
|
*vertex_b = NULL,
|
|
*vertex_c = NULL;
|
|
Vector3D
|
|
leg_1,
|
|
leg_2 = Vector3D::Identity;
|
|
|
|
//
|
|
//-----------------------------------
|
|
// Spin through, testing the vertices
|
|
//-----------------------------------
|
|
//
|
|
Scalar area = 0.0f;
|
|
DynamicArrayOf<IndexProxy*> indices;
|
|
unsigned index_count = UseIndexArray(&indices);
|
|
Verify(index_count == indices.GetLength());
|
|
Verify(index_count >= 3);
|
|
*center = Point3D::Identity;
|
|
for (unsigned i=0; i<index_count-2; ++i)
|
|
{
|
|
//
|
|
//-----------------------------------------------
|
|
// Generate all the information on the first pass
|
|
//-----------------------------------------------
|
|
//
|
|
if (!i)
|
|
{
|
|
Check_Object(indices[0]);
|
|
vertex_a = indices[0]->GetVertexProxy();
|
|
Check_Object(vertex_a);
|
|
|
|
Check_Object(indices[1]);
|
|
vertex_b = indices[1]->GetVertexProxy();
|
|
Check_Object(vertex_b);
|
|
|
|
Check_Object(indices[2]);
|
|
vertex_c = indices[2]->GetVertexProxy();
|
|
Check_Object(vertex_c);
|
|
|
|
vertex_a->GetPosition(&position_a);
|
|
vertex_b->GetPosition(&position_b);
|
|
vertex_c->GetPosition(&position_c);
|
|
leg_1.Subtract(position_b, position_a);
|
|
leg_2.Subtract(position_c, position_a);
|
|
}
|
|
|
|
//
|
|
//--------------------------------------------------------------
|
|
// Get the index info. If this is not the first pass, copy the
|
|
// information from last pass
|
|
//--------------------------------------------------------------
|
|
//
|
|
else
|
|
{
|
|
Check_Object(vertex_c);
|
|
vertex_b = vertex_c;
|
|
Check_Object(indices[i+2]);
|
|
vertex_c = indices[i+2]->GetVertexProxy();
|
|
Check_Object(vertex_c);
|
|
|
|
position_b = position_c;
|
|
vertex_c->GetPosition(&position_c);
|
|
leg_1 = leg_2;
|
|
leg_2.Subtract(position_c, position_a);
|
|
}
|
|
|
|
//
|
|
//-----------------------------------------------------------------
|
|
// Compute the cross-product of the two legs to get the area of the
|
|
// triangle
|
|
//-----------------------------------------------------------------
|
|
//
|
|
Vector3D v;
|
|
v.Cross(leg_1, leg_2);
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Add the three triangle points together and multiply by the area of
|
|
// the triangle to give a weighted sum for the polygon centroid
|
|
//-------------------------------------------------------------------
|
|
//
|
|
Point3D centroid;
|
|
centroid.Add(position_a, position_b);
|
|
centroid += position_c;
|
|
Scalar wedge_area = v.GetLength() * 0.5f;
|
|
if (area <= SMALL)
|
|
{
|
|
if (wedge_area > SMALL)
|
|
{
|
|
area += wedge_area;
|
|
centroid *= wedge_area;
|
|
}
|
|
*center = centroid;
|
|
}
|
|
else
|
|
{
|
|
if (wedge_area > SMALL)
|
|
{
|
|
area += wedge_area;
|
|
centroid *= wedge_area;
|
|
*center += centroid;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
//-----------------------------
|
|
// Delete the remaining proxies
|
|
//-----------------------------
|
|
//
|
|
DetachArrayReferences(&indices);
|
|
*center *= 1.0f/3.0f;
|
|
return area;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
unsigned
|
|
PolygonProxy::UseIndexArray(Stuff::DynamicArrayOf<IndexProxy*> *indices)
|
|
{
|
|
Verify(GetClassID() == PolygonProxyClassID);
|
|
unsigned vertex_count = vertexArray.GetLength();
|
|
indices->SetLength(vertex_count);
|
|
for (unsigned i=0; i<vertex_count; ++i)
|
|
{
|
|
(*indices)[i] = IndexProxy::MakeProxy(this, vertexArray[i]);
|
|
Register_Object((*indices)[i]);
|
|
}
|
|
return vertex_count;
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::DetachArrayReferences(DynamicArrayOf<IndexProxy*> *indices)
|
|
{
|
|
Check_Object(this);
|
|
|
|
Check_Object(indices);
|
|
unsigned index_count = indices->GetLength();
|
|
for (unsigned i=0; i<index_count; ++i)
|
|
{
|
|
Check_Object((*indices)[i]);
|
|
(*indices)[i]->DetachReference();
|
|
}
|
|
}
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
//
|
|
void
|
|
PolygonProxy::SetPolygonIndices(
|
|
const Stuff::DynamicArrayOf<VertexProxy*> &vertices
|
|
)
|
|
{
|
|
Check_Object(this);
|
|
Check_Object(&vertices);
|
|
Verify(GetClassID() == PolygonProxyClassID);
|
|
|
|
//
|
|
//---------------------------------------
|
|
// Detach the index array if there is one
|
|
//---------------------------------------
|
|
//
|
|
unsigned vertex_count = vertexArray.GetLength();
|
|
unsigned i;
|
|
for (i=0; i<vertex_count; ++i)
|
|
{
|
|
Check_Object(vertexArray[i]);
|
|
vertexArray[i]->DetachReference();
|
|
}
|
|
|
|
//
|
|
//-------------------------------------------------------------------
|
|
// Set the length of the index array, then spin through and create an
|
|
// index proxy for each vertex
|
|
//-------------------------------------------------------------------
|
|
//
|
|
vertex_count = vertices.GetLength();
|
|
vertexArray.SetLength(vertex_count);
|
|
for (i=0; i<vertex_count; ++i)
|
|
{
|
|
Check_Object(vertices[i]);
|
|
vertexArray[i] = vertices[i];
|
|
vertexArray[i]->AttachReference();
|
|
}
|
|
}
|