#include "ProxyHeaders.hpp" // //############################################################################ //########################### Multistate ############################# //############################################################################ // //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool MultiState::IsEqualTo(const MultiState& multi_state) { if(GetLength() != multi_state.GetLength()) { return false; } for(unsigned i=0;iIsEqualTo(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; iAttachReference(); } 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; iAttachReference(); } 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; iAttachReference(); } return state_count; } */ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void MultiState::DetachReferences() { for(unsigned i=0;iDetachReference(); } 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; iDetachReference(); } // //-------------------------------------- // 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 *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 *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 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 indices; unsigned index_count = UseIndexArray(&indices); Verify(index_count == indices.GetLength()); Verify(index_count >= 3); for (unsigned i=0; iGetVertexProxy(); 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 indices; unsigned index_count = UseIndexArray(&indices); Verify(index_count >= 3); Verify(index_count == indices.GetLength()); for (unsigned i=0; iGetVertexProxy(); Check_Object(vertex); Point3D position; vertex->GetPosition(&position); *center += position; } DetachArrayReferences(&indices); // //---------------------- // Now, average them all //---------------------- // *center /= static_cast(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 indices; unsigned index_count = UseIndexArray(&indices); Verify(index_count == indices.GetLength()); Verify(index_count >= 3); *center = Point3D::Identity; for (unsigned i=0; iGetVertexProxy(); 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 *indices) { Verify(GetClassID() == PolygonProxyClassID); unsigned vertex_count = vertexArray.GetLength(); indices->SetLength(vertex_count); for (unsigned i=0; i *indices) { Check_Object(this); Check_Object(indices); unsigned index_count = indices->GetLength(); for (unsigned i=0; iDetachReference(); } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void PolygonProxy::SetPolygonIndices( const Stuff::DynamicArrayOf &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; iDetachReference(); } // //------------------------------------------------------------------- // 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; iAttachReference(); } }