// Z3DObject.cpp: implementation of the CZ3DObject class. // ////////////////////////////////////////////////////////////////////// #include "Z3DObject.h" #include ////////////////////////////////////////////////////////////////////// // Static member definition ////////////////////////////////////////////////////////////////////// //ObjectList CZ3DObject::ms_ObjectList; long CZ3DObject::ms_lObjectCount = 0; //long CZ3DObject::ms_lObjectCountCopy1 = 0; //long CZ3DObject::ms_lObjectCountCopy2 = 0; //long CZ3DObject::ms_lObjectCountCopy3 = 0; //long CZ3DObject::ms_lObjectCountCopy4 = 0; CZ3DObject* CZ3DObject::ms_rpRootObject = NULL; ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CZ3DObject::CZ3DObject() { m_bDisabled = false; // initialize member data m_Pos.Identity(); m_Dir.Identity(); m_PosLocal.Identity(); m_DirLocal.Identity(); //m_MovLocal.Identity(); //m_RotLocal.Identity(); //m_Mov.Identity(); //m_Rot.Identity(); m_vPivotPos.Identity(); m_rpParent = Z3DOBJECT_NOTLINKED; // to represent 'not linked' m_rpChild = NULL; m_rpSibling = NULL; } CZ3DObject::~CZ3DObject() { ms_lObjectCount--; // ms_lObjectCountCopy1--; // ms_lObjectCountCopy2--; // ms_lObjectCountCopy3--; // ms_lObjectCountCopy4--; } void CZ3DObject::Link( CZ3DObject* pParentObj ) { //_ASSERT( m_rpParent == Z3DOBJECT_NOTLINKED ); bool bChangeLink = false; // ÇöÀç ºÎ¸ð¿Í °°Àº °æ¿ì - ¾Ï°Íµµ ¾ÈÇÔ if( m_rpParent == pParentObj ) { return; } // linkµÈÀûÀÌ ÀÖ´Ù¸é ¸µÅ©¸¦ ¹Ù²Ù´Â °æ¿ì·Î üũ if( m_rpParent != Z3DOBJECT_NOTLINKED ) { UnLink(); bChangeLink = true; } // hierarchy setting m_rpParent = pParentObj; if( pParentObj == NULL ) // link as scene-root ? { if( GetObjectCount() == 0 ) { // no object in list - this object is the first root obj. ms_rpRootObject = this; } else { // set as sibling of other scene-root objects ms_rpRootObject->AddSibling( this ); } } else // link as a child of an object { pParentObj->AddChild( this ); } // ¸µÅ©¸¦¹Ù²Ù´Â °æ¿ì - pos¹× dir Àç¼³Á¤ if( bChangeLink ) { if( m_rpParent ) { matrix m, m1, m2; // m1 : inverse of all of the parents m = m_rpParent->m_TM; m1.Inverse( m ); // m2 : TM_world; m2 = m_TM; // m = TM_world x inv_all_parent m_TM = m2 * m1; } // decompose z3d::QuaternionRotationMatrix( m_Dir, m_TM ); m_Pos.x = m_TM._41; m_Pos.y = m_TM._42; m_Pos.z = m_TM._43; } // ¹Ù²Ù´Â °æ¿ì°¡ ¾Æ´Ï¶ó¸é ½Å±Ôµî·Ï else { ms_lObjectCount++; // ms_lObjectCountCopy1++; // ms_lObjectCountCopy2++; // ms_lObjectCountCopy3++; // ms_lObjectCountCopy4++; } } void CZ3DObject::UnLink() { CZ3DObject* pObj; if( Z3DOBJECT_NOTLINKED == m_rpParent ) { return; // nothing to do } // setting child ptr. of parent object and get first sibling // pObj = first sibling in the same level as this object if( m_rpParent == NULL ) // scene root { pObj = ms_rpRootObject; } else // not a scene root { pObj = m_rpParent->m_rpChild; if( this == pObj ) // this == first in the siblings? { m_rpParent->m_rpChild = m_rpSibling; } } // adjust sibling relation if( this != pObj ) // non-first sibling { // find previous silbing while( pObj->m_rpSibling != this ) { pObj = pObj->m_rpSibling; } pObj->m_rpSibling = m_rpSibling; } else // first sibling { if( m_rpParent == NULL ) // scene root { ms_rpRootObject = m_rpSibling; } } m_rpParent = Z3DOBJECT_NOTLINKED; m_rpSibling = NULL; } void CZ3DObject::Process() { static std::stack stackpObj; if( NULL == ms_rpRootObject ) // nothing to do when nothing's in the hierarchy tree return; // implementing recursion with STL stack CZ3DObject* pObj = ms_rpRootObject; stackpObj.push( pObj ); while( !stackpObj.empty() ) { pObj = stackpObj.top(); stackpObj.pop(); if( pObj->m_rpSibling ) stackpObj.push( pObj->m_rpSibling ); if( !(pObj->IsDisabled()) ) { pObj->UpdateFrame(); if( pObj->m_rpChild ) stackpObj.push( pObj->m_rpChild ); } } }