#include "ProxyHeaders.hpp" // //############################################################################ //############################ SceneProxy ############################## //############################################################################ // SceneProxy::ClassData* SceneProxy::DefaultData = NULL; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::InitializeClass() { Verify(!DefaultData); DefaultData = new ClassData( SceneProxyClassID, "SceneProxy", GenericProxy::DefaultData ); Register_Object(DefaultData); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::TerminateClass() { Unregister_Object(DefaultData); delete DefaultData; DefaultData = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SceneProxy::SceneProxy(ClassData *class_data): GenericProxy(class_data), activeChildProxies(NULL) { Check_Object(this); stateLibrary = NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // SceneProxy::~SceneProxy() { Check_Object(this); Verify(activeChildProxies.IsEmpty()); Verify(!stateLibrary); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::TestInstance() const { Verify(IsDerivedFrom(DefaultData)); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::GetCentroid(Point3D *centroid) { Check_Object(this); Check_Pointer(centroid); // //----------------------------------------------- // If we have no children, just return our origin //----------------------------------------------- // unsigned child_count = GetChildCount(); *centroid = Point3D::Identity; if (!child_count) return; // //-------------------------------------------- // Otherwise, just average our child centroids //-------------------------------------------- // ChildProxy *child = UseFirstChildProxy(); while (child) { Check_Object(child); ChildProxy *next = child->UseNextSiblingProxy(); Point3D local_centroid; child->GetCentroid(&local_centroid); LinearMatrix4D m; child->GetLocalToParent(&m); Point3D world_centroid; world_centroid.Multiply(local_centroid, m); *centroid += world_centroid; child->DetachReference(); child = next; } Verify(!child); *centroid /= static_cast(child_count); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // bool SceneProxy::GetBoundingSphere(Sphere *sphere) { Check_Object(this); Check_Pointer(sphere); // //--------------------------------------------------------------------- // Put the center of the sphere at the centroid, then set the radius to // just contain the mesh //--------------------------------------------------------------------- // GetCentroid(&sphere->center); sphere->radius = -1.0f; ChildProxy *child = UseFirstChildProxy(); while (child) { Check_Object(child); ChildProxy *next = child->UseNextSiblingProxy(); // //---------------------------------------------------------- // Transform's the child's bounding sphere into parent space //---------------------------------------------------------- // LinearMatrix4D child_to_parent; child->GetLocalToParent(&child_to_parent); Sphere child_sphere; child->GetBoundingSphere(&child_sphere); Point3D position; position.Multiply(child_sphere.center, child_to_parent); // //----------------------------------------------------------------- // Now stretch the radius of the bounding sphere so that it totally // includes the child sphere //----------------------------------------------------------------- // position -= sphere->center; Scalar range = position.GetLength() + child_sphere.radius; if (range > sphere->radius) { sphere->radius = range; } child->DetachReference(); child = next; } // //------------------------------------- // Make sure the radius is properly set //------------------------------------- // if (sphere->radius == -1.0f) { sphere->radius = 0.0f; return false; } return true; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ChildProxy* SceneProxy::AppendMatchingChildProxy( CopyProcess *process, ChildProxy *child ) { Check_Object(this); Check_Object(process); Check_Object(child); if (child->IsDerivedFrom(PolygonMeshProxy::DefaultData)) { PolygonMeshProxy *proxy = AppendNewPolygonMeshProxy(); Check_Object(proxy); proxy->Copy(process, Cast_Object(PolygonMeshProxy*, child)); return proxy; } else if (child->IsDerivedFrom(GroupProxy::DefaultData)) { GroupProxy *proxy = AppendNewGroupProxy(); Check_Object(proxy); proxy->Copy(process, Cast_Object(GroupProxy*, child)); return proxy; } return NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // ChildProxy* SceneProxy::InsertMatchingChildProxy( CopyProcess *process, ChildProxy *child, ChildProxy *before ) { Check_Object(this); Check_Object(process); Check_Object(child); Check_Object(before); Verify(!before->GetParentGroupProxy()); STOP(("Not implemented")); return NULL; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::FindNamedChildren( DynamicArrayOf *children, const char* prefix, bool matching ) { Check_Object(this); Check_Object(children); Check_Pointer(prefix); // //---------------------- // Get the prefix length //---------------------- // int size = strlen(prefix); // //--------------------------------- // Find out how many children match //--------------------------------- // unsigned count = 0; ChildProxy *child = UseFirstChildProxy(); while (child) { ChildProxy *next = child->UseNextSiblingProxy(); MString name; if (child->GetName(&name)) { if ((!_strnicmp(name, prefix, size)) == matching) ++count; } child->DetachReference(); child = next; } // //------------------------------------------------------------------------ // Set the array length, and if we have any matching children, fill in the // array with those proxies //------------------------------------------------------------------------ // children->SetLength(count); if (count > 0) { child = UseFirstChildProxy(); count = 0; while (child) { ChildProxy *next = child->UseNextSiblingProxy(); // //----------------------------------------------------------------- // If the child has a name and it matches what we are looking for, // store it in the array and bump the reference count so it doesn't // go away //----------------------------------------------------------------- MString name; if (child->GetName(&name)) { if ((!_strnicmp(name, prefix, size)) == matching) { (*children)[count++] = child; child->AttachReference(); } } child->DetachReference(); child = next; } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // void SceneProxy::DetachChildProxy(ChildProxy* proxy) { Check_Object(this); activeChildProxies.RemovePlug(proxy); Verify(referenceCount > 1); DetachReference(); }