#include "StdAfx.h" #include "PlayerSceneNode.h" #include "ResourceManager.h" #include "SceneManager.h" #include "cameraManager.h" #include "RenderSystem.h" #include "ObjectManager.h" #include "EffectSceneNode.h" cPlayerSceneNode::cPlayerSceneNode( eType type ) : cDynamicSceneNode( type ) { mpTarotBoard = 0; mpUserSellBoard = 0; } cPlayerSceneNode::~cPlayerSceneNode() { ClearCollectInfo(); } bool cPlayerSceneNode::Init( const cPlayerSceneNodeParam& param ) { if( param.mDisplayObj == true ) mDisplayObj = param.mpObject; if( cDynamicSceneNode::Init( param ) == false ) { return false; } /// parts Á¤º¸ µî·Ï const char* partName = 0; for( unsigned int i=0; iGetManagedPartName( i ); if( strlen(partName) == 0 ) { assert(0); continue; } mpActorManager->AddPartsObject( i, partName ); } return true; } bool cPlayerSceneNode::InitLinkInfo() { // À̺κÐÀº Àû´çÇÑ ¸Þ¸ð¸® ÇÒ´çÀ» ÇÑ´Ù. (³ªÁß¿¡ Á»´õ Á¤È®ÇÏ°Ô °è»êÇÏ¿© Ãß°¡Çϰųª ÁÙÀϰÍ..) // ´ë·« °è»ê : ¾ç¼Õ ¹«±â 2°³ + ¹æÆÐ 1°³ mpLinkInfo = NiNew NiTPrimitiveArray(15, 5); assert(mpLinkInfo); if( mpLinkInfo == 0 ) { return false; } for( unsigned int i=0; iGetAllocatedSize(); ++i ) { mpLinkInfo->SetAt( i,0 ); } return true; } /* ------------------------------------------------------------------ * ÇÔ¼öÀ̸§ : InitializeRandomIdle() * ¸ñ Àû : µ¿ÀÛÀÇ ´Ù¾ç¼ºÀ» Á¦°øÇϱâ À§Çؼ­ * ÁÖÀÇ»çÇ× : * ------------------------------------------------------------------ */ void cPlayerSceneNode::InitializeRandomIdle() { mpRandomIdle = NiNew NiTPrimitiveArray(1); mpRandomIdle->SetAt( 0, 0 ); } void cPlayerSceneNode::ProcessTrail( unsigned long deltatime, unsigned long accumtime ) { /// NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { NiTListIterator kOldPos = pos; sTrailInfo* p = mRibbonList.GetNext(pos); cRibbonGeometry* geom = p->mRibbonGeom; if( p->mLoop == false ) { if( p->mLifeTime < accumtime ) { geom->SetPushEnabled( false ); if( geom->IsDelete() == true ) { /// delete SAFE_DELETE(p); mRibbonList.RemovePos( kOldPos ); continue; } } } if( geom != NULL ) { /// push point NiAVObject* obj1 = GetDummyObject( p->mStartLink ); NiAVObject* obj2 = GetDummyObject( p->mEndLink ); if( obj1 && obj2 ) { const NiPoint3& pos1 = obj1->GetWorldTranslate(); const NiPoint3& pos2 = obj2->GetWorldTranslate(); geom->PushTrailPoint( accumtime, pos1, pos2 ); } else { assert(0); } geom->Process( deltatime ); } } } const NiPoint3& cPlayerSceneNode::GetObjectHead() { NiNode* spine = GetDummyObject( eLINK_HEAD ); if( spine ) return spine->GetWorldTranslate(); else return NiPoint3::ZERO; } const NiPoint3& cPlayerSceneNode::GetObjectFoot() { NiNode* spine = GetDummyObject( eLINK_FOOT ); if( spine ) return spine->GetWorldTranslate(); else return NiPoint3::ZERO; } const NiPoint3& cPlayerSceneNode::GetObjectCenter() { NiNode* spine = GetDummyObject( eLINK_BODY ); if( spine ) return spine->GetWorldTranslate(); else return NiPoint3::ZERO; } /* ------------------------------------------------------------------ * ÇÔ¼öÀ̸§ : ChangeParts( unsigned int index, const cString& pathName ) * ¸ñ Àû : ÆÄÆ® ±³Ã¼¿ë ÀÎÅÍÆäÀ̽º Á¦°ø * ÁÖÀÇ»çÇ× : * ------------------------------------------------------------------ */ bool cPlayerSceneNode::ChangeParts( unsigned int partIdx, const char* fileName ) { if( fileName == 0 ) return false; /// cString pathName; pathName.Format( "./Data/Character/%s", fileName ); RESOURCEMAN->LoadNIF( pathName ); /// NiNode* pNode = RESOURCEMAN->CloneObjectByName( fileName ); assert(pNode); if( !pNode ) { return false; } if( partIdx == ePART_FACE ) return cPlayerSceneNode::ChangeParts( partIdx, pNode ); else return cDynamicSceneNode::ChangeParts( partIdx, pNode ); } bool cPlayerSceneNode::ChangeParts( unsigned int partsIdx, NiNode* pNode ) { if( partsIdx != ePART_FACE ) return cDynamicSceneNode::ChangeParts( partsIdx, pNode ); ////////////////////////////////////////////////////////////////////////// /// CloneÇÑ Object¿¡ ÀÖ´ø Bone RootÁ¤º¸¸¦ »èÁ¦ÇÑ´Ù. if( pNode->DetachChild( pNode->GetObjectByName("foot_dummy") ) == 0) { assert(0); } /// face ¿Í ear¿¡ ´ëÇÑ Á¤º¸ ȹµæ NiAVObject* pSrcFace = GetPartObject( partsIdx ); if( pSrcFace == 0 ) { assert(0); return false; } NiAVObject* pSrcEar = GetPartObject( ePART_EAR ); ////////////////////////////////////////////////////////////////////////// /// Face ó¸® { /// 1. ±âÁ¸ Face¿¡ ´ëÇÑ Mesh¿Í ModifierÁ¤º¸¸¦ ȹµæÇÑ´Ù. NiMesh* pSrcMesh = NULL; if( NiIsKindOf(NiMesh, pSrcFace) ) { pSrcMesh = (NiMesh*)pSrcFace; } else { pSrcMesh = GetGeom(pSrcFace); } if( pSrcMesh == 0 ) { assert(0); return false; } NiSkinningMeshModifier* pSrcSkinningModifier = NiGetModifier(NiSkinningMeshModifier, pSrcMesh); if( pSrcSkinningModifier == 0 ) { assert(0); return false; } /// 2. ½Å±Ô Face¿¡ ´ëÇÑ Mesh¿Í ModifierÁ¤º¸¸¦ ȹµæÇÑ´Ù. const char* partsName =RESOURCEMAN->GetManagedPartName( partsIdx ); if( partsName == 0 || strlen(partsName) == 0 ) { assert(0); return false; } NiAVObject* pDestFace = pNode->GetObjectByName( partsName ); if( pDestFace == 0 ) { assert(0); return false; } NiMesh* pDestMesh = GetGeom( pDestFace ); if( pDestMesh == 0 ) { assert(0); return false; } NiSkinningMeshModifier* pDestSkinningModifier = NiGetModifier(NiSkinningMeshModifier, pDestMesh); if( pDestSkinningModifier == 0 ) { assert(0); return false; } NiAVObject** ppBones = pDestSkinningModifier->GetBones(); if( ppBones == 0 ) { assert(0); return false; } NiTransform* pSkinToBoneTransforms = pDestSkinningModifier->GetSkinToBoneTransforms(); if( pSkinToBoneTransforms == 0 ) { assert(0); return false; } NiBound* pBoneBounds = pDestSkinningModifier->GetBoneBounds(); if( pBoneBounds == 0 ) { assert(0); return false; } /// 3. ½Å±Ô Á¤º¸·Î °»½ÅÇÑ´Ù. NiSkinningMeshModifier* pkModifier = NiNew NiSkinningMeshModifier( pDestSkinningModifier->GetBoneCount() ); pkModifier->SetSoftwareSkinned( pDestSkinningModifier->GetSoftwareSkinned() ); // Get the destinations for the converted skinning data NiAVObject** apkDestBones = pkModifier->GetBones(); NIASSERT(apkDestBones); NiTransform* akDestSkinToBoneTransforms = pkModifier->GetSkinToBoneTransforms(); NIASSERT(akDestSkinToBoneTransforms); pkModifier->EnableDynamicBounds(); NiBound* akDestBoneBounds = pkModifier->GetBoneBounds(); NIASSERT(akDestBoneBounds); // Set the root bone and its BoneToBindSpace transform pkModifier->SetRootBoneParent( pSrcSkinningModifier->GetRootBoneParent() ); pkModifier->SetRootBoneParentToSkinTransform( pSrcSkinningModifier->GetRootBoneParentToSkinTransform() ); // Set each bone and is bind to bone space transforms for (unsigned int i = 0; i < pDestSkinningModifier->GetBoneCount(); i++ ) { NiAVObject* pBone = ppBones[i]; if( pBone == 0 ) { assert(0); continue; } NiAVObject* pNewBone = GetNiObj()->GetObjectByName( pBone->GetName() ); if( pNewBone == 0 ) { assert(0); continue; } // Add bones, transforms, and bone bounds apkDestBones[i] = pNewBone; akDestSkinToBoneTransforms[i] = pSkinToBoneTransforms[i]; akDestBoneBounds[i] = pBoneBounds[i]; } pDestMesh->RemoveModifier( pDestSkinningModifier ); pDestMesh->AddModifier( pkModifier ); } ////////////////////////////////////////////////////////////////////////// /// Ear ó¸® { const char* partsName =RESOURCEMAN->GetManagedPartName( ePART_EAR ); if( partsName == 0 || strlen(partsName) == 0 ) { assert(0); return false; } NiAVObject* pDestEar = pNode->GetObjectByName( partsName ); if( pDestEar ) { /// 1. ±âÁ¸ Ear¿¡ ´ëÇÑ Mesh¿Í ModifierÁ¤º¸¸¦ ȹµæÇÑ´Ù. NiMesh* pSrcMesh = NULL; if( pSrcEar ) { if( NiIsKindOf(NiMesh, pSrcEar) ) pSrcMesh = (NiMesh*)pSrcEar; else pSrcMesh = GetGeom(pSrcEar); } else { if( NiIsKindOf(NiMesh, pSrcFace) ) pSrcMesh = (NiMesh*)pSrcFace; else pSrcMesh = GetGeom(pSrcFace); } if( pSrcMesh == 0 ) { assert(0); return false; } NiSkinningMeshModifier* pSrcSkinningModifier = NiGetModifier(NiSkinningMeshModifier, pSrcMesh); if( pSrcSkinningModifier == 0 ) { assert(0); return false; } /// 2. ½Å±Ô Ear¿¡ ´ëÇÑ Mesh¿Í ModifierÁ¤º¸¸¦ ȹµæÇÑ´Ù. NiMesh* pDestMesh = GetGeom( pDestEar ); if( pDestMesh == 0 ) { assert(0); return false; } NiSkinningMeshModifier* pDestSkinningModifier = NiGetModifier(NiSkinningMeshModifier, pDestMesh); if( pDestSkinningModifier == 0 ) { assert(0); return false; } NiAVObject** ppBones = pDestSkinningModifier->GetBones(); if( ppBones == 0 ) { assert(0); return false; } NiTransform* pSkinToBoneTransforms = pDestSkinningModifier->GetSkinToBoneTransforms(); if( pSkinToBoneTransforms == 0 ) { assert(0); return false; } NiBound* pBoneBounds = pDestSkinningModifier->GetBoneBounds(); if( pBoneBounds == 0 ) { assert(0); return false; } /// 3. ½Å±Ô Á¤º¸·Î °»½ÅÇÑ´Ù. NiSkinningMeshModifier* pkModifier = NiNew NiSkinningMeshModifier( pDestSkinningModifier->GetBoneCount() ); pkModifier->SetSoftwareSkinned( pDestSkinningModifier->GetSoftwareSkinned() ); // Get the destinations for the converted skinning data NiAVObject** apkDestBones = pkModifier->GetBones(); NIASSERT(apkDestBones); NiTransform* akDestSkinToBoneTransforms = pkModifier->GetSkinToBoneTransforms(); NIASSERT(akDestSkinToBoneTransforms); pkModifier->EnableDynamicBounds(); NiBound* akDestBoneBounds = pkModifier->GetBoneBounds(); NIASSERT(akDestBoneBounds); // Set the root bone and its BoneToBindSpace transform pkModifier->SetRootBoneParent( pSrcSkinningModifier->GetRootBoneParent() ); pkModifier->SetRootBoneParentToSkinTransform( pSrcSkinningModifier->GetRootBoneParentToSkinTransform() ); // Set each bone and is bind to bone space transforms for (unsigned int i = 0; i < pDestSkinningModifier->GetBoneCount(); i++ ) { NiAVObject* pBone = ppBones[i]; if( pBone == 0 ) { assert(0); continue; } NiAVObject* pNewBone = GetNiObj()->GetObjectByName( pBone->GetName() ); if( pNewBone == 0 ) { assert(0); continue; } // Add bones, transforms, and bone bounds apkDestBones[i] = pNewBone; akDestSkinToBoneTransforms[i] = pSkinToBoneTransforms[i]; akDestBoneBounds[i] = pBoneBounds[i]; } pDestMesh->RemoveModifier( pDestSkinningModifier ); pDestMesh->AddModifier( pkModifier ); } } /// »õ·Î¿î °´Ã¼·Î ¹Ù²Û´Ù. mpActorManager->ChangePartsObject( partsIdx, pNode ); /// ±âÇÏ Á¤º¸¸¦ °»½Å mUpdateGeomInfo = true; return true; } bool cPlayerSceneNode::ChangePartsTexture( unsigned int partsIdx, const char* fileName ) { cString pathName; pathName.Format( "./Data/Character/%s", fileName ); NiTexture* pTexture = RESOURCEMAN->LoadTexture( pathName, false ); if( pTexture == 0 ) { return false; } return cDynamicSceneNode::ChangePartsTexture( partsIdx, pTexture ); } /* ------------------------------------------------------------------ * ÇÔ¼öÀ̸§ : LinkToDummy( unsigned int index, const cString& pathName ) * ¸ñ Àû : °´Ã¼ ¸µÅ©¿ë ÀÎÅÍÆäÀ̽º * ÁÖÀÇ»çÇ× : * ------------------------------------------------------------------ */ unsigned int cPlayerSceneNode::LinkObject( unsigned int dummyIdx, const char* fileName ) { if( fileName == 0 ) return UINT_MAX; /// cString pathName; pathName.Format( "./Data/Character/%s", fileName ); if( RESOURCEMAN->LoadNIF( pathName ) == false ) return UINT_MAX; /// NiNode* n = RESOURCEMAN->GetObjectByName( fileName ); if( n == 0 ) { assert(0); return UINT_MAX; } return cDynamicSceneNode::LinkObject( dummyIdx, n ); } NiAVObject* cPlayerSceneNode::GetWeaponDummy( unsigned int objectIdx, bool left ) { NiAVObject* pObj = GetLinkObject( objectIdx ); if( pObj == 0 ) return 0; unsigned int dummyIdx = (left == true)? eLINK_LWEAPON:eLINK_RWEAPON; const char* dummyName = RESOURCEMAN->GetManagedDummyName( dummyIdx ); if( strlen( dummyName ) == 0 ) return 0; return pObj->GetObjectByName( dummyName ); } void cPlayerSceneNode::UpdateLinkEffect() { if( mEffectList.IsEmpty() ) return; cLinkIndexList::cIterator i = mEffectList.Begin(); cLinkIndexList::cIterator end = mEffectList.End(); for( ; i != end; ++i ) { unsigned long idx = (unsigned long)*i; cEffectSceneNode* n = SCENEMAN->GetEffectSceneNode( idx ); if( n ) { unsigned int dummyIdx = n->GetDummyIdx(); if( dummyIdx != eLINK_RWEAPON && dummyIdx != eLINK_LWEAPON ) continue; NiNode* parent = n->GetNiObj()->GetParent(); NiNode* check = GetDummyObject( dummyIdx ); if( check ) { if( check != parent ) { /// new dummy if( parent ) parent->DetachChild( n->GetNiObj() ); else n->GetNiObj()->DetachParent(); check->AttachChild( n->GetNiObj() ); } } else { /// hand dummy check if( dummyIdx == eLINK_RWEAPON ) check = GetDummyObject( eLINK_RHAND ); else check = GetDummyObject( eLINK_LHAND ); assert(check); if( check ) { if( check != parent ) { if( parent ) parent->DetachChild( n->GetNiObj() ); else n->GetNiObj()->DetachParent(); check->AttachChild( n->GetNiObj() ); } } } } } } void cPlayerSceneNode::HideEar( bool hide ) { NiAVObject* obj = GetPartObject( ePART_EAR ); if( obj ) obj->SetAppCulled( hide ); }