#include "stdafx.h" #include "DynamicSceneNode.h" #include "SceneTree.h" #include "SceneManager.h" #include "OptionManager.h" #include "ResourceManager.h" #include "RenderSystem.h" #include "CameraManager.h" #include "LightAgent.h" #include "FogAgent.h" #include "SoundSystem.h" #include "EffectSceneNode.h" #include "SoundSceneNode.h" #include "ObjectNameCard.h" #include "ShadowGeometry.h" #include "ChatBubble.h" #include "ObjectManager.h" #include "Hero.h" #include "Application.h" cDynamicSceneNode::cDynamicSceneNode( eType type ) : cSceneNode( type ) , mTargetAnimation( UINT_MAX ) , mTargetAnimationEndTime(0) , mTargetAnimationScaleEndTime(0.0f) , mpRandomIdle( 0 ) , mpModel(0) , mpNameCard(0) , mpChatBubble(0) , mShadowGeom( 0 ) , mpLinkInfo(0) , mpActorManager(0) , mNeedUpdateShadow( false ) , mShowNameGauge( false ) { mpHead = 0; mpFoot = 0; mHeadDist = 5.0f; mHeadScreenPosX = 0; mHeadScreenPosY = 0; mFootScreenPosX = 0; mFootScreenPosY = 0; // mpMorpherController = 0; // mStopMorpherProcess = false; mScaleAccumTime = 0; mLastUpdateTime = 0; mScaleFactor = 1.0f; mVisibleCamLength = 0.0f; mUpdateGeomInfo = false; // mpGameObject = 0; mGameObject.type = eOBJECTTYPE_NONE; mGameObject.index = 0; mSetVisibleArray = false; mDisplayObj = 0; mTargetScale = 1.0f; mScaleCheckTime = 0; } cDynamicSceneNode::~cDynamicSceneNode() { /// µî·ÏµÈ ÀÌÆåÆ®°¡ ÀÖ´Ù¸é ¸ðµÎ Á¦°Å ÇÑ´Ù. ClearEffect(); ClearSound(); NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { sTrailInfo* p = mRibbonList.GetNext(pos); SAFE_NIDELETE( p ); } mRibbonList.RemoveAll(); /// ¸»Ç³¼± Á¦°Å SAFE_DELETE(mpChatBubble); /// À̸§ °´Ã¼ Á¦°Å SAFE_DELETE(mpNameCard); if( mpLinkInfo ) { sLinkInfo* info = 0; for( unsigned int i=0; iGetSize(); ++i ) { info = mpLinkInfo->GetAt( i ); if( info ) { NiDelete info; } } mpLinkInfo->RemoveAll(); } SAFE_NIDELETE( mpLinkInfo ); SAFE_NIDELETE( mpRandomIdle ); SAFE_DELETE( mShadowGeom ); SAFE_NIDELETE(mpActorManager); mGameObject.type = eOBJECTTYPE_NONE; mGameObject.index = 0; } void cDynamicSceneNode::OnProcess( unsigned long deltaTime, unsigned long accumTime ) { mSetVisibleArray = false; if( mUpdateGeomInfo ) { /// Clear collect info ClearCollectInfo(); RecursiveNodeInfo( GetNiObj() ); NiMesh::CompleteSceneModifiers( GetNiObj() ); mUpdateGeomInfo = false; } /// ÀÓÀÇ·Î »À´ëÁ¤º¸¸¦ º¯°æÇÏ´Â °æ¿ì¿¡ »ç¿ëÇÑ´Ù. UpdateBipedRootTransforms( accumTime ); if( mGameObject.type != eOBJECTTYPE_HERO )//mpGameObject != HERO ) { cBaseObject* gameObj = GetGameObject(); if( gameObj && gameObj->IsDie() == false ) { if( SCENEMAN->CalcDynamicVisibleLevel( this ) == true ) { if( mTargetAlpha == 0.0f ) SetAlphaBlended( 1.0f ); } else { if( mTargetAlpha > 0.01f ) SetAlphaBlended( 0.0f ); } } } /// Alpha Fade In/Out ó¸® ProcessScale( deltaTime ); ProcessAlpha( deltaTime ); if( mAlpha < 0.01f ) mCheckFrustum = false; else mCheckFrustum = true; /// °æ°ú ½Ã°£ * ¼Óµµ Á¶ÀýÀÚ unsigned long delta = accumTime - mLastUpdateTime; delta = (unsigned long)(delta * mScaleFactor); mScaleAccumTime += delta; float fScaleTime = mScaleAccumTime*0.001f; /// °´Ã¼ÀÇ Update mpActorManager->Update( fScaleTime ); if( mUpdateSelectLIght ) { if( mAttachSelectLight ) GetNiNode()->AttachEffect( LIGHTAGENT->GetSelectAmbientLight() ); else GetNiNode()->DetachEffect( LIGHTAGENT->GetSelectAmbientLight() ); mUpdateSelectLIght = false; GetNiNode()->UpdateEffects(); } GetNiNode()->Update( fScaleTime ); /// °æ°è±¸¸¦ ¼³Á¤ mBoundSphere.Set( GetCenter(), GetRadius() ); /// Àå¸é Æ®¸®¸¦ °»½Å if( mContainer ) mContainer->Update( this ); /// if( mpChatBubble ) mpChatBubble->Update( accumTime ); /// if( mNeedUpdateTransform ) { mNeedUpdateTransform = false; mNeedUpdateShadow = true; } /// ´©Àû ½Ã°£À» ¼³Á¤ mLastUpdateTime = accumTime; ProcessTrail( deltaTime, accumTime ); } bool cDynamicSceneNode::OnVisible() { if( SCENEMAN->IsScreenShotMode() == true ) return false; if( mAlpha <= 0.01f ) return false; /// ±×¸²ÀÚ cBaseObject* gameObj = GetGameObject(); if( gameObj ) { if( gameObj->IsDie() == false && mShadowGeom ) { if( mAlpha > 0.01f ) mShadowGeom->Process( mNeedUpdateShadow, GetWorldTranslate(), mAlpha ); mNeedUpdateShadow = false; } } return cSceneNode::OnVisible(); } bool cDynamicSceneNode::Init( const cDynamicSceneNodeParam& param ) { if( param.mpObject == 0 ) { assert(0); return false; } mGameObject.type = param.mpObject->GetObjectType(); mGameObject.index = param.mpObject->GetObjectID(); /// ¸®¼Ò½º °ü¸®ÀÚ·Î ºÎÅÍ ¸ðµ¨Á¤º¸ ȹµæ.. mpModel = RESOURCEMAN->LoadKFM( param.mPathName.Cstr() ); if( mpModel == 0 ) { assert(0 && "Model file not found"); return false; } /// ¸µÅ©¸¦ À§ÇÑ ¸Þ¸ð¸®¸¦ Àâ´Â´Ù. if( InitLinkInfo() == false ) return false; /// ActorManager »ý¼º.. mpActorManager = cActorManagerForPartition::Create( mpModel ); if( mpActorManager == 0 ) { assert( 0 && "null actor manager" ); return false; } /// °»½Å mpActorManager->Update( 0.0f ); /// IDLE »óÅ ¾Ö´Ï¸ÞÀÌ¼Ç ¼ÂÆÃ.. (¿©·¯°¡Áö ÇüÅÂÀÇ IDLEÀÌ Á¸Àç ÇÏ´Â °æ¿ì) InitializeRandomIdle(); /// ¿£Áø ³ëµå¸¦ ¼³Á¤ mSceneNiNode = mpActorManager->GetNifRoot(); if( GetNiNode() == 0 ) { assert( 0 && "null node" ); return false; } { /// º¯È¯ Çà·ÄÀ» ¼³Á¤ GetNiNode()->SetTranslate( param.mTranslate ); GetNiNode()->SetRotate( param.mRotate ); GetNiNode()->SetScale( param.mScale ); /// °»½Å ¿©ºÎ¸¦ ¼³Á¤ mNeedUpdateTransform = true; /// ÇÈÅ· ¹æ½ÄÀ» ¼³Á¤ mPick.SetQueryType( NiPick::QUERY_FIRST ); mPick.SetSortType( NiPick::SORT_OFF ); mPick.SetIntersectType( NiPick::INTERSECT_TRIANGLE ); mPick.SetCoordinateType( param.mPickCoordinate ); mPick.SetFrontOnly( false ); mPick.SetReturnTexture( param.mPickReturnTexture ); mPick.SetReturnNormal( param.mPickReturnNormal ); mPick.SetReturnSmoothNormal( false ); mPick.SetReturnColor( param.mPickReturnColor ); mPick.SetTarget( GetNiObj() ); mPick.SetPickObjectPolicy(NiNew SimpleBoxPickObjectPolicy(true)); } /// ¾ËÆÄ ¼Ó¼ºÀÌ ¾øÀ¸¸é »ý¼º NiAlphaProperty* alphaProp = (NiAlphaProperty*)GetNiNode()->GetProperty( NiProperty::ALPHA ); if( alphaProp == 0 ) { alphaProp = NiNew NiAlphaProperty; alphaProp->SetAlphaBlending( false ); alphaProp->SetAlphaTesting( false ); alphaProp->SetTestMode(NiAlphaProperty::TEST_GREATEREQUAL); GetNiNode()->AttachProperty( alphaProp ); } NiAmbientLight* amb = FindAmbientLight( GetNiObj() ); if( amb ) GetNiNode()->DetachChild( amb ); /// Á¤º¸ ÃßÃâ ClearCollectInfo(); RecursiveNodeInfo( GetNiObj() ); /// Á¶¸íÀ» ºÎÂø GetNiNode()->AttachEffect( LIGHTAGENT->GetSceneAmbientLight( 1 ) ); GetNiNode()->AttachEffect( LIGHTAGENT->GetSceneDirLight( 1 ) ); /// ¾È°³ ¼Ó¼ºÀ» ºÎÂø GetNiNode()->AttachProperty( FOGAGENT->GetFogProperty() ); /// °»½Å bool selectiveUpdate = true; bool rigid = false; GetNiNode()->SetSelectiveUpdateFlags( selectiveUpdate, true, rigid ); GetNiNode()->UpdateProperties(); GetNiNode()->UpdateEffects(); NiMeshUpdateProcess kUpdateProcess; // kUpdateProcess.SetTime( THEAPP->GetWorldAccumTime()* 0.001f ); GetNiNode()->Update( kUpdateProcess ); NiMesh::CompleteSceneModifiers( GetNiObj() ); GetNiNode()->UpdateNodeBound(); mTargetScale = GetNiNode()->GetWorldScale(); mScaleDt[0] = mScaleDt[1] = mTargetScale; mBoundSphere.Set( GetCenter(), GetRadius() ); /// Á¤º¸Ç¥½Ã¸¦ À§ÇÑ °´Ã¼ »ý¼º if( param.mCreateNameCard ) { mpNameCard = CreateNameCard( GetGameObject() ); //mpGameObject ); assert(mpNameCard); } if( param.mUseShadow ) { /// ±×¸²ÀÚ ±âÇϸ¦ »ý¼º assert( mShadowGeom == 0 ); mShadowGeom = new cShadowGeometry(); if( mShadowGeom->Init( RESOURCEMAN->GetShadowTexture(), GetRadius() * 0.6f ) == false ) { assert( 0 ); return false; } mNeedUpdateShadow = true; } NiPoint3 camPos = CAMERAMAN->GetCurrentCameraPos(); if( (camPos - GetWorldTranslate()).Length() > 4000.0f ) { mAlpha = 0.0f; SetAlphaBlended( 0.0f ); } else { mAlpha = 1.0f; SetAlphaBlended( 1.0f ); } mpHead = GetDummyObject( eLINK_HEAD ); if( !mpHead ) { assert(0); return false; } mpFoot = GetDummyObject( eLINK_FOOT ); if( mpFoot == 0 ) { assert(0); return false; } mLastUpdateTime = THEAPP->GetWorldAccumTime(); return true; } void cDynamicSceneNode::SetTargetAnimation( unsigned int code ) { if( mTargetAnimation != code ) { NiSequenceData* seq = mpActorManager->SetTargetAnimation( code ); if( seq ) { mTargetAnimation = code; mTargetAnimationEndTime = THEAPP->GetWorldAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = (float)GetScaleAccumTime()*0.001f + seq->GetDuration(); } } } bool cDynamicSceneNode::UpdateTargetAnimation( unsigned int code ) { if( mTargetAnimation != code ) { NiSequenceData* seq = mpActorManager->SetTargetAnimation( code ); if( seq ) { mTargetAnimation = code; mTargetAnimationEndTime = THEAPP->GetWorldAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = (float)GetScaleAccumTime()*0.001f + seq->GetDuration(); return true; } } else { NiSequenceData* seq = mpActorManager->UpdateTargetAnimation( code ); if( seq ) { mTargetAnimationEndTime = THEAPP->GetWorldAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = (float)GetScaleAccumTime()*0.001f + seq->GetDuration(); return true; } } return false; } /* ------------------------------------------------------------------ * ÇÔ¼öÀ̸§ : ChangeParts( unsigned int index, NiNode* pObj ) * ¸ñ Àû : ÆÄÆ®¸¦ ±³Ã¼Çϴµ¥ »ç¿ë * ÁÖÀÇ»çÇ× : º»LOD°¡ ¿ÏÀüÈ÷ Å×½ºÆ®µÈ »óÅ´ ¾Æ´Ï´Ù. (Á»´õ ¼öÁ¤¿ä!!) * ½ºÅ²°ú º» Á¤º¸ °»½Å¿¡ ƯÈ÷ À¯ÀÇ ÇØ¾ßÇÑ´Ù. * ------------------------------------------------------------------ */ bool cDynamicSceneNode::ChangeParts( unsigned int partsIdx, NiNode* pNode ) { if( partsIdx == ePART_FACE ) { assert(0); return false; } /// ±âÇÏ Á¤º¸¸¦ °»½Å mUpdateGeomInfo = true; /// 1. ±âÁ¸ ÆÄÆ®¿¡ ´ëÇÑ Á¤º¸¸¦ ¼öÁýÇÑ´Ù. NiAVObject* pSrcNode = mpActorManager->GetParts( partsIdx ); if( !pSrcNode ) { assert(0); return false; } NiMesh* pSrcMesh = NULL; if( NiIsKindOf(NiMesh, pSrcNode) ) { pSrcMesh = (NiMesh*)pSrcNode; } else { pSrcMesh = GetGeom_Parts(pSrcNode); } if( !pSrcMesh ) { assert(0); return false; } NiSkinningMeshModifier* pSrcSkinningModifier = NiGetModifier(NiSkinningMeshModifier, pSrcMesh); if( pSrcSkinningModifier == 0 ) { assert(0); return false; } /// 2. ±³Ã¼ µÇ¾îÁú ÆÄÆ®¿¡ ´ëÇÑ Á¤º¸ ¼öÁý const char* partsName =RESOURCEMAN->GetManagedPartName( partsIdx ); if( partsName == 0 || strlen(partsName) == 0 ) { assert(0); return false; } NiMesh* pDestMesh = GetGeom_Parts( pNode ); if( !pDestMesh ) { 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 = GetNiNode()->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]; } /// »õ·Î¿î °´Ã¼·Î ¹Ù²Û´Ù. mpActorManager->ChangePartsObject( partsIdx, pNode ); /// CloneÇÑ Object¿¡ ÀÖ´ø Bone RootÁ¤º¸¸¦ »èÁ¦ÇÑ´Ù. if( pNode->DetachChild( pNode->GetObjectByName("foot_dummy") ) == 0 ) { if( pNode->DetachChild( pNode->GetObjectByName("Bip01") ) == 0 ) { assert(0); } } pDestMesh->RemoveModifier( pDestSkinningModifier ); pDestMesh->AddModifier( pkModifier ); pDestMesh->ResetModifiers(); /* /// 1. ±âÁ¸ ÆÄÆ®¿¡ ´ëÇÑ Á¤º¸¸¦ ¼öÁýÇÑ´Ù. NiAVObject* pOldNode = mpActorManager->GetParts( partsIdx ); if( !pOldNode ) { assert(0); return false; } /// Geom°´Ã¼¸¦ ȹµæÇÑ´Ù. NiTriBasedGeom* pOldGeom = NULL; if( NiIsKindOf(NiTriBasedGeom, pOldNode) ) { pOldGeom = (NiTriBasedGeom*)pOldNode; } else { pOldGeom = NiDynamicCast( NiTriBasedGeom, GetGeom(pOldNode) ); } if( !pOldGeom ) { assert(0); return false; } /// ½ºÅ²Á¤º¸ ȹµæ NiSkinInstance* pOldSkinInst = pOldGeom->GetSkinInstance(); assert(pOldSkinInst); if( !pOldSkinInst ) { return false; } NiSkinData* pOldSkinData = pOldSkinInst->GetSkinData(); assert(pOldSkinData); if( !pOldSkinData ) { return false; } /// 2. ±³Ã¼ µÇ¾îÁú ÆÄÆ®¿¡ ´ëÇÑ Á¤º¸ ¼öÁý const char* partsName =RESOURCEMAN->GetManagedPartName( partsIdx ); if( partsName == 0 || strlen(partsName) == 0 ) { assert(0); return false; } // /// ±³Ã¼ °´Ã¼ÀÇ Geom°´Ã¼ Á¤º¸ NiTriBasedGeom* pGeom = NiDynamicCast(NiTriBasedGeom, GetGeom( pNode ) ); assert(pGeom); if( !pGeom ) { return false; } /// ±³Ã¼ °´Ã¼ÀÇ ½ºÅ²Á¤º¸ NiSkinInstance* pSkinInst = pGeom->GetSkinInstance(); assert(pSkinInst); if( !pSkinInst ) { return false; } NiSkinData* pSkinData = pSkinInst->GetSkinData(); assert(pSkinData); if( !pSkinData ) { return false; } /// ±³Ã¼µÇ¾îÁú BoneÁ¤º¸ NiAVObject*const* ppBones = pSkinInst->GetBones(); assert(ppBones); if( !ppBones ) { return false; } NiSkinData::BoneData* pBoneData = pSkinData->GetBoneData(); assert(pBoneData); if( !pBoneData ) { return false; } /// »õ·Î¿î ¸ðµ¨ÀÇ BoneÁ¤º¸¸¦ ÇöÀç Bone HierachyÀÇ Bone Nodeµé·Î ±³Ã¼ÇÑ´Ù. /// ÇϳªÀÇ º»¼Â¿¡¼­ ºÐÇÒÇÑ °ÍÀ̹ǷΠº»Àº ±âÁ¸°ÍÀ» °øÀ¯ÇÑ´Ù. /// ºÐÇÒ °´Ã¼ ÀÚüµµ µ¶¸³°´Ã¼·Î Ãâ·ÂÀÌ °¡´ÉÇϵµ·Ï º» Á¤º¸¸¦ °®´Â´Ù. /// ÁÖÀÇ!! ÀÌ º»Á¤º¸´Â ¸ðµÎ °°Áö¸¸, ÂüÁ¶ À§Ä¡¸¦ ±âÁ¸ Æ÷ÀÎÅÍ·Î º¯°æÇØ¾ß ÇÑ´Ù. /// (½ºÅ²Á¤º¸°¡ ÂüÁ¶ÇÏ´Â ¸Þ¸ð¸® ÁÖ¼Ò·ÎÀÇ º¯°æÀÌ´Ù.) unsigned int i; NiAVObject *pBone = NULL; NiAVObject *pNewBone = NULL; NiTPrimitiveSet newBones; NiTPrimitiveSet newBoneDataObjs; sBoneDataObj* pBoneDataObj = NULL; // NiAVObject* pRoot= GetNiObj(); for( i=0; iGetBoneCount(); ++i ) { pBone = ppBones[i]; if( !pBone ) { assert(0); continue; } pNewBone = GetNiObj()->GetObjectByName( pBone->GetName() ); if( !pNewBone ) { assert(0); continue; } newBones.Add( pNewBone ); pBoneDataObj = NiNew sBoneDataObj; pBoneDataObj->pBoneData = &pBoneData[i]; for( unsigned int k = 0; k < pBoneData[i].m_usVerts; ++k ) { pBoneDataObj->BoneVertData.Add( &pBoneData[i].m_pkBoneVertData[k] ); } newBoneDataObjs.Add( pBoneDataObj ); } /// Create the new arrays. unsigned int numNewBones = newBones.GetSize(); NiAVObject** ppNewBones = NiAlloc(NiAVObject*, numNewBones); NiSkinData::BoneData* pNewBoneData = NiNew NiSkinData::BoneData[numNewBones]; /// Fill the new arrays. for( i = 0; ipBoneData->m_kBound; pNewBoneData[i].m_kSkinToBone = pBoneDataObj->pBoneData->m_kSkinToBone; /// ±¸µ¿»óÀÇ ¹®Á¦´Â ¾Æ´ÏÁö¸¸, º°µµÀÇ Ã¼Å©¸¦ ¿äÇÑ´Ù!! assert( pBoneDataObj->BoneVertData.GetSize() < (unsigned int) (unsigned short) ~0 ); pNewBoneData[i].m_usVerts = (unsigned short)pBoneDataObj->BoneVertData.GetSize(); pNewBoneData[i].m_pkBoneVertData = NiNew NiSkinData::BoneVertData[pNewBoneData[i].m_usVerts]; for ( unsigned short k = 0; kBoneVertData.GetAt( k )->m_fWeight; pNewBoneData[i].m_pkBoneVertData[k].m_usVert = pBoneDataObj->BoneVertData.GetAt( k )->m_usVert; } } /// Create the new NiSkinData and NiSkinInstance objects. NiSkinData* pNewSkinData = NiNew NiSkinData( numNewBones, pNewBoneData, pSkinData->GetRootParentToSkin(), pGeom->GetVertices() ); pNewSkinData->SortAndMergeBoneData(); NiSkinInstance* pNewSkinInst = NiNew NiSkinInstance( pNewSkinData, pOldSkinInst->GetRootParent(), ppNewBones ); /// Delete allocated memory. for( i = 0; i< newBoneDataObjs.GetSize(); ++i ) { NiDelete newBoneDataObjs.GetAt( i ); } /// CloneÇÑ Object¿¡ ÀÖ´ø Bone RootÁ¤º¸¸¦ »èÁ¦ÇÑ´Ù. if( pNode->DetachChild( pNode->GetObjectByName("foot_dummy") ) == 0) { assert(0); } /// Skin Instance °»½Å pGeom->SetSkinInstance( pNewSkinInst ); /// »õ·Î¿î °´Ã¼·Î ¹Ù²Û´Ù. mpActorManager->ChangePartsObject( partsIdx, pNode ); /// Bone LOD Á¤º¸ÀÇ °»½Å. NiSkinningLODController* pOldCtrl = NULL; pOldCtrl = mpActorManager->GetSkinningLODController(); if( pOldCtrl ) { int curLOD = pOldCtrl->GetBoneLOD(); mpActorManager->RefreshControllerManager(); NiSkinningLODController* pNewCtrl = mpActorManager->GetSkinningLODController(); pNewCtrl->SetBoneLOD( curLOD ); } NiBoneLODController* pOldCtrl = NULL; pOldCtrl = mpActorManager->GetBoneLODController(); if( pOldCtrl ) { int curLOD = pOldCtrl->GetBoneLOD(); pOldCtrl->ProcessScene( GetNiNode() ); pOldCtrl->ReplaceSkin( pOldGeom, pGeom ); mpActorManager->RefreshControllerManager(); NiBoneLODController* pNewCtrl = mpActorManager->GetBoneLODController(); pNewCtrl->SetBoneLOD( curLOD ); } */ return true; } bool cDynamicSceneNode::ChangePartsTexture( unsigned int partsIdx, NiTexture* pTex ) { /// 1. ±âÁ¸ ÆÄÆ®¿¡ ´ëÇÑ Á¤º¸¸¦ ¼öÁýÇÑ´Ù. NiAVObject* pNode = mpActorManager->GetParts( partsIdx ); if( pNode && pTex ) { NiMesh* pMesh = GetGeom( pNode ); if( pMesh ) { NiTexturingProperty* pProperty = (NiTexturingProperty*)pMesh->GetProperty( NiProperty::TEXTURING ); if( pProperty ) { pProperty->SetBaseTexture( pTex ); pMesh->UpdateProperties(); // mUpdateGeomInfo = true; return true; } } } return false; } /* ------------------------------------------------------------------ * ÇÔ¼öÀ̸§ : LinkObject( unsigned int index, NiNode* pObj ) * ¸ñ Àû : ¹«±â¸¦ ƯÁ¤´õ¹Ì¿¡ ¸µÅ© ½ÃŲ´Ù. * ÁÖÀÇ»çÇ× : ¸®ÅϵǴ À妽º¸¦ Ȱ¿ëÇØ¼­ Á¦°ÅµÇ¹Ç·Î ²À ¹Þ¾Æ¼­ º¸°üÇÒ°Í.. * ------------------------------------------------------------------ */ unsigned int cDynamicSceneNode::LinkObject( unsigned int dummyIdx, NiNode* pNode ) { if( pNode == 0 ) { assert(0); return UINT_MAX; } /// Parts NameÁ¡°Ë.. À߸øµÈ À妽º üũ const char* dummyName = RESOURCEMAN->GetManagedDummyName( dummyIdx ); if( dummyName == 0 || strlen(dummyName) == 0 ) { assert(0); return UINT_MAX; } /// ¸µÅ©½Ãų À§Ä¡ °´Ã¼ ȹµæ.. NiNode* pDummy = NiDynamicCast( NiNode, GetNiNode()->GetObjectByName( dummyName ) ); assert(pDummy); if( pDummy == NULL ) { assert(0); return UINT_MAX; } /// ¿øº»°´Ã¼ º¹»çº» »ý¼º.. NiCloningProcess cloning; cloning.m_eCopyType = NiObjectNET::COPY_EXACT; NiNode* pNewObj = NiDynamicCast( NiNode, pNode->Clone( cloning ) ); assert(pNewObj); if( pNewObj == NULL ) { assert(0); return UINT_MAX; } /// ½ÇÁ¦ ¸µÅ©.. pDummy->AttachChild( pNewObj ); /// °»½Å pNewObj->Update(0.0f); pNewObj->UpdateProperties(); pNewObj->UpdateEffects(); GetNiNode()->UpdateNodeBound(); /// °æ°è±¸¸¦ ¼³Á¤ mBoundSphere.Set( GetCenter(), GetRadius() ); /// ¸µÅ© Á¤º¸ ÀÔ·Â.. sLinkInfo* pkInfo = NiNew sLinkInfo; pkInfo->DummyIndex = dummyIdx; pkInfo->pObject = pNewObj; unsigned int linkIdx = mpLinkInfo->Add( pkInfo ); /// ±âÇÏ Á¤º¸¸¦ °»½Å mUpdateGeomInfo = true; return linkIdx; } void cDynamicSceneNode::UnLinkObject( unsigned int linkIdx ) { if( linkIdx == UINT_MAX ) return; sLinkInfo* pInfo = mpLinkInfo->GetAt( linkIdx ); if( pInfo == NULL ) { assert(0); return; } const char* dummyName = RESOURCEMAN->GetManagedDummyName( pInfo->DummyIndex ); if( dummyName == 0 || strlen(dummyName) == 0 ) { assert(0); return; } /// ¸µÅ©µÈ ´õ¹Ì¸¦ ã´Â´Ù. NiNode* pDummy = NiDynamicCast( NiNode, GetNiNode()->GetObjectByName(dummyName) ); if( pDummy == NULL ) { assert(0); return; } /// ´õ¹Ì assert( pInfo->pObject ); if( pInfo->pObject ) { NiNode* parent = pInfo->pObject->GetParent(); assert( parent ); if( parent ) { assert( pDummy == parent ); if( parent->DetachChild( pInfo->pObject ) == 0 ) { assert(0); } } } // if( pDummy->DetachChild( pInfo->pObject ) == 0 ) // assert(0); mpLinkInfo->RemoveAt( linkIdx ); SAFE_NIDELETE(pInfo); pDummy->Update(0.0f, false); GetNiNode()->UpdateNodeBound(); mBoundSphere.Set(GetCenter(), GetRadius()); /// ±âÇÏ Á¤º¸¸¦ °»½Å mUpdateGeomInfo = true; } NiAVObject* cDynamicSceneNode::GetLinkObject( unsigned int linkId ) { if( linkId == UINT_MAX ) return 0; sLinkInfo* pInfo = mpLinkInfo->GetAt( linkId ); if( pInfo ) { return pInfo->pObject; } return 0; } cEffectSceneNode* cDynamicSceneNode::LinkEffect( unsigned int dummyIdx, const char* fileName, NiTransform* trans, bool bLoop, bool bFollow ) { cEffectSceneNodeParam param; param.mpFollowSceneNode = this; param.mDummyIdx = dummyIdx; param.mPathName = fileName; if( trans != 0 ) { param.mTranslate = trans->m_Translate; param.mRotate = trans->m_Rotate; param.mScale = trans->m_fScale; } param.mFollowing = bFollow; param.mLooping = bLoop; cEffectSceneNode* pnode = SCENEMAN->CreateEffect( param ); if( pnode && bFollow ) { mEffectList.PushBack( pnode->GetIndexByManger() ); } return pnode; } cEffectSceneNode* cDynamicSceneNode::LinkDamage( unsigned int dummyIdx, const char* fileName, NiTransform* trans, bool IsMiss, bool zFalse ) { cEffectSceneNodeParam param; param.mpFollowSceneNode = this; param.mDummyIdx = dummyIdx; param.mPathName = fileName; if( trans != 0 ) { param.mTranslate = trans->m_Translate; param.mRotate = trans->m_Rotate; param.mScale = trans->m_fScale; } param.mFollowing = false; param.mLooping = false; cEffectSceneNode* pnode = SCENEMAN->CreateDamageEffect( param, IsMiss, zFalse ); return pnode; } /// ÁÖÀÇ»çÇ× : void cDynamicSceneNode::UnLinkEffect( cEffectSceneNode* pnode ) { assert(pnode); if( pnode == 0 ) return; mEffectList.Remove( pnode->GetIndexByManger() ); NiNode* parent = pnode->GetNiObj()->GetParent(); if( parent ) { if( parent->DetachChild( pnode->GetNiObj() ) == 0 ) { GameErrorLog( "cDynamicSceneNode::UnLinkEffect(DetachChild)[%d,%d] : %s", mGameObject.index, pnode->GetIndexByManger(), parent->GetName() ); } // char tempmsg[255] = {0,}; // sprintf( tempmsg, "\ncDynamicSceneNode::UnLinkEffect[%d, %d] : %s", GetIndexByManger(), pnode->GetIndexByManger(), parent->GetName() ); // OutputDebugStringA( tempmsg ); } else { assert(0); } } cSoundSceneNode* cDynamicSceneNode::LinkSound( unsigned char type, unsigned long soundIdx, bool bLoop ) { /// ÂüÁ¶ÇÒ À§Ä¡ °´Ã¼ ȹµæ.. NiNode* pDummy = NiDynamicCast( NiNode, GetNiNode()->GetObjectByName("body_dummy") ); if( pDummy == NULL ) { return NULL; } sSoundInfo* pInfo = SOUNDSYS->GetSoundInfo( soundIdx ); if( pInfo == 0 ) return 0; if( type != eSOUNDTYPE_EFFECT && type != eSOUNDTYPE_NOFADE_EFFECT ) { assert(0); return 0; } cSoundSceneNodeParam param; if( pInfo->mRadius <= 0.0f ) { param.mRadius = 1000.0f; } else { param.mRadius = pInfo->mRadius; } param.mSoundType = (eSOUNDTYPE)type; param.mLoopCount = bLoop? 0:1; param.mVolumeRatio = OPTIONMAN->GetEffVolume() * pInfo->mVolume; /// ±âº» ¼Ó¼º ÀÎÀÚµéÀ» ¼³Á¤ param.mPathName = pInfo->mFileName; param.mTranslate = pDummy->GetWorldTranslate(); param.mpOwnerSceneNode = this; cSoundSceneNode* pnode = SCENEMAN->CreateEffectSound( param ); if( pnode ) { mSoundList.PushBack( pnode->GetIndexByManger() ); } return pnode; } void cDynamicSceneNode::UnLinkSound( cSoundSceneNode* pnode ) { assert(pnode); if( pnode == 0 ) return; mSoundList.Remove( pnode->GetIndexByManger() ); } /* /// void cDynamicSceneNode::StartMorpher() { mStopMorpherProcess = false; } /// void cDynamicSceneNode::StopMorpher() { mStopMorpherProcess = true; } */ void cDynamicSceneNode::AddToVisibleArray() { if( IsViewNode() == false ) return; if( mUpdateGeomInfo == true ) return; cSceneNode::AddToVisibleArray(); { /// Ä«¸Þ¶ó¿ÍÀÇ °Å¸® µî·Ï NiPoint3 vec = GetWorldTranslate() - CAMERAMAN->GetCurrentCameraPos(); mVisibleCamLength = vec.Length(); /// visible dynamic array¿¡ µî·Ï SCENEMAN->AddVisibleDynamicNode( this ); } /// CalcScreenPos(); NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { sTrailInfo* p = mRibbonList.GetNext(pos); cRibbonGeometry* geom = p->mRibbonGeom; if( geom && geom->GetActiveVerts() >= 4 ) SCENEMAN->AddVisibleTrailGeom( geom ); } } /// void cDynamicSceneNode::AddDepthPlaneObject() { if( mpHead == 0 ) { assert( 0 ); return; } NiPoint3 pos = this->GetWorldTranslate(); pos.z = mpHead->GetWorldTranslate().z; pos.z += mHeadDist; NiPoint3 camPos = CAMERAMAN->GetCurrentNi()->GetWorldTranslate(); float distCam = (pos - camPos).Length(); float distHero = distCam; if( HERO ) distHero = (GetWorldTranslate() - HERO->GetPos()).Length(); unsigned int optionHeight = 0; if( OPTIONMAN->IsShowBubble() ) { if( mpChatBubble && mpChatBubble->IsActive() ) { /// ¸»Ç³¼± µî·Ï if( distCam <= 3000.0f) { SCENEMAN->AddPlane( mpChatBubble ); mpChatBubble->SetPos( mHeadScreenPosX, mHeadScreenPosY - (optionHeight+5) ); optionHeight = mpChatBubble->GetBubbleHeight()+5; } } } if( mpNameCard ) { cBaseObject* gameObj = GetGameObject(); if( distHero <= 1500 ) { if( mShowNameGauge ) { mpNameCard->SetEnableGauge( true ); if( distHero > 500.0f ) { if( HERO->GetTargetObject() != gameObj ) mpNameCard->SetEnableGauge( false ); } } else { mpNameCard->SetEnableGauge( false ); } if( gameObj == 0 || gameObj->IsDie() ) { mpNameCard->SetEnableGauge( false ); } else { mpNameCard->Set2DPos( mHeadScreenPosX, mHeadScreenPosY - (optionHeight+5), mFootScreenPosX, mFootScreenPosY+20 ); SCENEMAN->AddPlane( mpNameCard ); } } else { /// overÀÎ °æ¿ì cBaseObject* o = OBJECTMAN->GetOverObject(); if( o == gameObj && distHero <= 5000 ) { mpNameCard->SetEnableGauge( false ); mpNameCard->Set2DPos( mHeadScreenPosX, mHeadScreenPosY - (optionHeight+5), mFootScreenPosX, mFootScreenPosY+20 ); SCENEMAN->AddPlane( mpNameCard ); } } } } bool cDynamicSceneNode::PickManagedPlane( float /*mouseX*/, float /*mouseY*/ ) { return false; } /// void cDynamicSceneNode::ActiveChatBubble( LPTSTR msg, unsigned long color ) { if( OPTIONMAN->IsShowBubble() == false ) return; if( mpChatBubble ) mpChatBubble->Active( msg, color ); } void cDynamicSceneNode::ActiveChatBubble( sTextItem* text ) { if( OPTIONMAN->IsShowBubble() == false ) return; if( mpChatBubble ) mpChatBubble->Active( text ); } void cDynamicSceneNode::UpdateNameCardTextValue() { if( mpNameCard ) mpNameCard->ChangeTextValue(); } void cDynamicSceneNode::UpdateNameCardGaugeValue() { if( mpNameCard ) mpNameCard->ChangeGaugeValue(); } void cDynamicSceneNode::UpdateGuildName() { if( mpNameCard ) mpNameCard->ChangeGuildName(); } void cDynamicSceneNode::UpdateGuildMark() { if( mpNameCard ) mpNameCard->ChangeGuildMark(); } void cDynamicSceneNode::PreviewGuildMark( NiTexture* tex ) { if( mpNameCard ) mpNameCard->PreviewGuildMark( tex ); } void cDynamicSceneNode::PreviewTodayWord( LPCTSTR word, unsigned long color ) { if( mpNameCard ) mpNameCard->SetTodayWord( (LPTSTR)word, color ); } NiAmbientLight* cDynamicSceneNode::FindAmbientLight( NiAVObject* obj ) { if( NiIsKindOf( NiAmbientLight, obj ) ) { return (NiAmbientLight*)obj; } else if( NiIsKindOf( NiNode, obj ) ) { NiAVObject* child = 0; NiNode* node = (NiNode*)obj; for( unsigned int i = 0, iend = node->GetArrayCount(); i < iend; ++i ) { child = node->GetAt( i ); if( child ) { NiAmbientLight* amb = FindAmbientLight( child ); if( amb ) return amb; } } } return 0; } bool cDynamicSceneNode::Pick( const cRay& ray ) { //if( mPickDataList.IsEmpty() ) //{ // return cSceneNode::Pick( ray ); //} if( mBoundSphere.IntersectRay( ray ) ) { if( mPick.PickObjects( ray.GetOrigin(), ray.GetDirection() ) ) { NiPick::Record* record = mPick.GetResults().GetAt(0); if( record ) { mPickPos = record->GetIntersection(); mPickDistance = record->GetDistance(); } return true; } } return false; } /// ÁÖÀÇ : scalefactor °ªÀ¸·Î void cDynamicSceneNode::UpdateAniScaleFactor( float factor ) { if( mScaleFactor == factor ) return; if( factor <= 0.0f ) factor = 0.1f; if( factor >= 2.0f ) factor = 1.9f; mScaleFactor = factor; } NiAVObject* cDynamicSceneNode::GetPartObject( unsigned int partsIdx ) { const char* partsName = RESOURCEMAN->GetManagedPartName( partsIdx ); if( strlen(partsName) == 0 ) return 0; /// ¸µÅ©½Ãų À§Ä¡ °´Ã¼ ȹµæ.. return mSceneNiNode->GetObjectByName( partsName ); } NiNode* cDynamicSceneNode::GetDummyObject( unsigned int dummyIdx ) { const char* dummyName = RESOURCEMAN->GetManagedDummyName( dummyIdx ); if( strlen(dummyName) == 0 ) return 0; /// ¸µÅ©½Ãų À§Ä¡ °´Ã¼ ȹµæ.. return NiDynamicCast( NiNode, mSceneNiNode->GetObjectByName( dummyName ) ); } void cDynamicSceneNode::GotoLastFrame() { NiSequenceData* p = mpActorManager->GetSequenceData( mpActorManager->GetTargetAnimation() ); if( p ) { float time = 0.0f; time = p->GetKeyTimeAt( NiAnimationConstants::GetEndTextKey() ); if( time != NiControllerSequence::INVALID_TIME ) mpActorManager->Update( -time ); } } void cDynamicSceneNode::AnimationReset() { mpActorManager->Reset(); mpActorManager->Update(0.0f); } sTrailInfo* cDynamicSceneNode::ActiveTrailEffect( cString str, unsigned long lifeTime, unsigned int link1, unsigned int link2, float lenPer, float factor ) { NiTexture* tex = RESOURCEMAN->LoadTexture( str ); if( tex == 0 ) { assert(0); return 0; } cRibbonGeometry* geom = NiNew cRibbonGeometry; if( geom->Init( THEAPP->GetWorldAccumTime(), tex, 500, 10 ) == false) { NiDelete geom; return 0; } sTrailInfo* info = new sTrailInfo; info->mRibbonGeom = geom; info->mLifeTime = THEAPP->GetWorldAccumTime() + lifeTime; info->mStartLink = link1; info->mEndLink = link2; info->mLoop = (lifeTime == 0); mRibbonList.AddTail( info ); return info; } void cDynamicSceneNode::DeActiveTrailEffect( sTrailInfo* pInfo ) { if( pInfo == 0 ) return; NiTListIterator pos = mRibbonList.FindPos( pInfo ); if( pos ) { cRibbonGeometry* p = pInfo->mRibbonGeom; if( p ) p->SetPushEnabled( false ); pInfo->mLifeTime = 0; } } void cDynamicSceneNode::ClearEffect() { 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 ); assert(n); if( n ) { if( n->IsRemoved() == false ) { NiNode* parent = n->GetNiObj()->GetParent(); if( parent ) { if( parent->DetachChild( n->GetNiObj() ) == 0 ) { GameErrorLog( "cDynamicSceneNode::ClearEffect(DetachChild)[%d,%d]\n", GetIndexByManger(), idx ); } } else { assert(0); GameErrorLog( "cDynamicSceneNode::ClearEffect(No Parent)[%d,%d]\n", GetIndexByManger(), idx ); } n->ParentNodeRemove(); } } } mEffectList.Clear(); } void cDynamicSceneNode::ClearSound() { if( mSoundList.IsEmpty() ) return; cLinkIndexList::cIterator i = mSoundList.Begin(); cLinkIndexList::cIterator end = mSoundList.End(); for( ; i != end; ++i ) { unsigned long idx = (unsigned long)*i; cSoundSceneNode* n = SCENEMAN->GetSoundSceneNode( idx ); assert(n); if( n ) { if( n->IsRemoved() == false ) { n->ParentNodeRemove(); } } } mSoundList.Clear(); } void cDynamicSceneNode::CalcScreenPos() { /// if( mpHead == 0 || mpFoot == 0 ) { assert(0); return; } float x,y; NiPoint3 posF = mpFoot->GetWorldTranslate(); cPlane::WorldPtToScreenPt( CAMERAMAN->GetCurrentNi(), posF, x, y, false ); mFootScreenPosX = (int)( x * RENDERSYS->GetScreenWidth() ); mFootScreenPosY = (int)( (1.0f - y) * RENDERSYS->GetScreenHeight() ); /// NiPoint3 posH = mpHead->GetWorldTranslate(); cBaseObject* gameObj = GetGameObject(); if( gameObj == 0 || gameObj->IsDie() ) { posF = posH; posF.z = posH.z + mHeadDist; } else { posF.z = posH.z + mHeadDist; } cPlane::WorldPtToScreenPt( CAMERAMAN->GetCurrentNi(), posF, x, y, false ); mHeadScreenPosX = (int)( x * RENDERSYS->GetScreenWidth() ); mHeadScreenPosY = (int)( (1.0f - y) * RENDERSYS->GetScreenHeight() ); } cBaseObject* cDynamicSceneNode::GetGameObject() { if( mDisplayObj != 0 ) return mDisplayObj; cBaseObject* obj = OBJECTMAN->GetObject( mGameObject.type, mGameObject.index ); assert(obj); return obj; } void cDynamicSceneNode::SetTargetScale( float scale, bool init ) { if( init ) { mTargetScale = scale; mScaleDt[0] = mScaleDt[1] = scale; SetScale( scale ); } else { mTargetScale = scale; mScaleDt[0] = mScaleDt[1] = GetWorldScale(); } mCurDtIdx = 0; mScaleCheckTime = 0; } void cDynamicSceneNode::ProcessScale( unsigned long deltatime ) { NiNode* node = GetNiNode(); if( node == 0 ) return; if( mScaleDt[0] == mTargetScale ) return; // Æø1 float dt = 0.6f * 0.001f * deltatime; if( mScaleDt[0] > mTargetScale ) { mScaleDt[0] -= dt; if( mScaleDt[0] < mTargetScale ) mScaleDt[0] = mTargetScale; } else if( mScaleDt[0] < mTargetScale ) { mScaleDt[0] += dt; if( mScaleDt[0] > mTargetScale ) mScaleDt[0] = mTargetScale; } // Æø2 dt = 0.8f * 0.001f * deltatime; if( mScaleDt[1] > mTargetScale ) { mScaleDt[1] -= dt; if( mScaleDt[1] < mTargetScale ) mScaleDt[1] = mTargetScale; } else if( mScaleDt[1] < mTargetScale ) { mScaleDt[1] += dt; if( mScaleDt[1] > mTargetScale ) mScaleDt[1] = mTargetScale; } SetScale( mScaleDt[mCurDtIdx] ); if( mScaleCheckTime <= deltatime ) { mScaleCheckTime = 55; mCurDtIdx++; mCurDtIdx = mCurDtIdx%2; } else { mScaleCheckTime -= deltatime; } } void cDynamicSceneNode::ResetHead2() { /// update head2 dummy position NiNode* pHead1 = GetDummyObject( eLINK_HEAD ); if( pHead1 == 0 ) return; NiNode* pHead2 = GetDummyObject( eLINK_HEAD2 ); if( pHead2 == 0 ) return; NiNode* pFoot = GetDummyObject( eLINK_FOOT ); if( pFoot == 0 ) return; NiPoint3 trans = pFoot->GetTranslate(); trans.z = pHead1->GetTranslate().z; pHead2->SetTranslate( trans ); } NiMesh* cDynamicSceneNode::GetGeom_Parts( NiAVObject* obj ) { if( obj == 0 ) { assert( 0 && "null node" ); return 0; } if( obj->GetName() == "eff_dummy") return 0; if( NiIsKindOf(NiMesh, obj) ) { if( NiGetModifier(NiSkinningMeshModifier, (NiMesh*)obj) != 0 ) return (NiMesh*)obj; } if( NiIsKindOf(NiNode, obj) ) { NiAVObject* child = 0; NiNode* node = (NiNode*)obj; for( unsigned int i = 0, iend = node->GetArrayCount(); i < iend; ++i ) { child = node->GetAt( i ); if( child ) { NiMesh* next = GetGeom_Parts( child ); if( next && NiGetModifier(NiSkinningMeshModifier, next) ) return next; } } } return 0; }