#include "stdafx.h" #include "DynamicSceneNode.h" #include "SceneTree.h" #include "SceneManager.h" #include "ResourceManager.h" #include "RenderSystem.h" #include "CameraManager.h" #include "SoundSystem.h" #include "EffectSceneNode.h" #include "SoundSceneNode.h" #include "TrailGeometry.h" #include "ObjectManager.h" #include "Application.h" cDynamicSceneNode::cDynamicSceneNode( eType type ) : cSceneNode( type ) , mTargetAnimation( UINT_MAX ) , mTargetAnimationEndTime(0) , mTargetAnimationScaleEndTime(0) , mpRandomIdle( 0 ) , mpModel(0) , mpLinkInfo(0) , mpActorManager(0) , mNeedUpdateShadow( false ) { mpHead = 0; mpFoot = 0; mHeadDist = 5.0f; // mpMorpherController = 0; // mStopMorpherProcess = false; mScaleAccumTime = 0; mLastTime = ULONG_MAX; mScaleFactor = 1.0f; mVisibleCamLength = 0.0f; mUpdateGeomInfo = false; mHideEar = false; mSetVisibleArray = false; mDisplayObj = 0; } cDynamicSceneNode::~cDynamicSceneNode() { ClearCollectInfo(); /// µî·ÏµÈ ÀÌÆåÆ®°¡ ÀÖ´Ù¸é ¸ðµÎ Á¦°Å ÇÑ´Ù. ClearEffect(); ClearSound(); NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { sTrailInfo* p = mRibbonList.GetNext(pos); SAFE_NIDELETE( p ); } mRibbonList.RemoveAll(); 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_NIDELETE(mpActorManager); } 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 ); /// Alpha Fade In/Out ó¸® ProcessAlpha( deltaTime ); if( mAlpha < 0.000001f ) mCheckFrustum = false; else mCheckFrustum = true; /// °æ°ú ½Ã°£ * ¼Óµµ Á¶ÀýÀÚ unsigned long delta = accumTime - mLastTime; delta = (unsigned long)(delta * mScaleFactor); /// actormanager Àü¿ë ½Ã°£ °è»ê if( mLastTime == ULONG_MAX ) mScaleAccumTime = accumTime; else mScaleAccumTime += delta; float fScaleTime = mScaleAccumTime*0.001f; /// °´Ã¼ÀÇ Update mpActorManager->Update( fScaleTime ); GetNiNode()->Update( fScaleTime ); /// °æ°è±¸¸¦ ¼³Á¤ mBoundSphere.Set( GetCenter(), GetRadius() ); /// Àå¸é Æ®¸®¸¦ °»½Å if( mContainer ) mContainer->Update( this ); /// if( mNeedUpdateTransform ) { mNeedUpdateTransform = false; mNeedUpdateShadow = true; } /// ´©Àû ½Ã°£À» ¼³Á¤ mLastTime = accumTime; ProcessTrail( deltaTime, accumTime ); } bool cDynamicSceneNode::OnVisible() { if( SCENEMAN->IsScreenShotMode() == true ) return false; if( mAlpha < 0.00001f ) return false; return cSceneNode::OnVisible(); } bool cDynamicSceneNode::Init( const cDynamicSceneNodeParam& param ) { /// ¸®¼Ò½º °ü¸®ÀÚ·Î ºÎÅÍ ¸ðµ¨Á¤º¸ ȹµæ.. 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; } /// ¸ðÇÎ Á¤º¸°¡ ÀÖ´Ù¸é ¼ÂÆÃÇÑ´Ù. // mpMorpherController = mpActorManager->GetMorpherController(); // if( mpMorpherController ) // { // mpMorpherController->SetActive( false ); // mpMorpherController->SetAlwaysUpdate( false ); // mpMorpherController->Stop(); // // StartMorpher(); // } /// °»½Å mpActorManager->Update(0.0f); /// IDLE »óÅ ¾Ö´Ï¸ÞÀÌ¼Ç ¼ÂÆÃ.. (¿©·¯°¡Áö ÇüÅÂÀÇ IDLEÀÌ Á¸Àç ÇÏ´Â °æ¿ì) InitializeRandomIdle(); /// ¿£Áø ³ëµå¸¦ ¼³Á¤ // NiNode* n = GetNiObj(); mSceneNiNode = mpActorManager->GetNifRoot(); if( GetNiObj() == 0 ) { assert( 0 && "null node" ); return false; } { /// º¯È¯ Çà·ÄÀ» ¼³Á¤ GetNiNode()->SetTranslate( param.mTranslate ); GetNiNode()->SetRotate( param.mRotate ); GetNiNode()->SetScale( param.mScale ); /// ÇÈÅ· ¹æ½ÄÀ» ¼³Á¤ mPick.SetQueryType( param.mQueryType ); mPick.SetSortType( param.mPickSort ); mPick.SetIntersectType( param.mPickIntersect ); mPick.SetCoordinateType( param.mPickCoordinate ); mPick.SetFrontOnly( param.mPickFrontOnly ); mPick.SetReturnTexture( param.mPickReturnTexture ); mPick.SetReturnNormal( param.mPickReturnNormal ); mPick.SetReturnSmoothNormal( false ); mPick.SetReturnColor( param.mPickReturnColor ); mPick.SetTarget( GetNiObj() ); } /// ¾ËÆÄ ¼Ó¼ºÀÌ ¾øÀ¸¸é »ý¼º NiAlphaProperty* alphaProp = (NiAlphaProperty*)GetNiObj()->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() ); mPick.SetQueryType( NiPick::QUERY_FIRST ); mPick.SetIntersectType( NiPick::INTERSECT_TRIANGLE ); mPick.SetSortType( NiPick::SORT_OFF ); mPick.SetFrontOnly( false ); /// Á¶¸íÀ» ºÎÂø // 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(); GetNiNode()->Update( 0.0f ); NiMesh::CompleteSceneModifiers( GetNiObj() ); GetNiNode()->UpdateNodeBound(); mBoundSphere.Set( GetCenter(), GetRadius() ); 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; } mLastTime = param.mWoldAccumTime; return true; } void cDynamicSceneNode::SetTargetAnimation( unsigned int code ) { // if( mTargetAnimation != code ) { NiSequenceData* seq = mpActorManager->SetTargetAnimation( code ); if( seq ) { mTargetAnimation = code; mTargetAnimationEndTime = THEAPP->GetAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = GetScaleAccumTime() + (unsigned long)(seq->GetDuration()*1000); } } } bool cDynamicSceneNode::UpdateTargetAnimation( unsigned int code ) { /* if( mTargetAnimation != code ) { NiSequenceData* seq = mpActorManager->SetTargetAnimation( code ); if( seq ) { mTargetAnimation = code; mTargetAnimationEndTime = THEAPP->GetAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = GetScaleAccumTime() + (unsigned long)(seq->GetDuration()*1000); return true; } } else */ { NiSequenceData* seq = mpActorManager->UpdateTargetAnimation( code ); if( seq ) { mTargetAnimation = code; mTargetAnimationEndTime = THEAPP->GetAccumTime() + (unsigned long)(seq->GetDuration()*1000); mTargetAnimationScaleEndTime = GetScaleAccumTime() + (unsigned long)(seq->GetDuration()*1000); 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 = 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]; } /// »õ·Î¿î °´Ã¼·Î ¹Ù²Û´Ù. mpActorManager->ChangePartsObject( partsIdx, pNode ); /// CloneÇÑ Object¿¡ ÀÖ´ø Bone RootÁ¤º¸¸¦ »èÁ¦ÇÑ´Ù. if( pNode->DetachChild( pNode->GetObjectByName("foot_dummy") ) == 0 ) { if( pNode->DetachChild( pNode->GetObjectByName("Bip01") ) == 0 ) { NiMessageBox( "Warning : this object [foot_dummy] check!!", "Error Dlg" ); assert(0); } } pDestMesh->RemoveModifier( pDestSkinningModifier ); pDestMesh->AddModifier( pkModifier ); pDestMesh->ResetModifiers(); 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(); 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, GetNiObj()->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; } // LinkDataInit( pNewObj ); /// ½ÇÁ¦ ¸µÅ©.. pDummy->AttachChild( pNewObj ); /// °»½Å pNewObj->Update(0.0f); pNewObj->UpdateProperties(); pNewObj->UpdateEffects(); GetNiObj()->UpdateNodeBound(); /// ¸µÅ© Á¤º¸ ÀÔ·Â.. 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, GetNiObj()->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); GetNiObj()->UpdateNodeBound(); /// ±âÇÏ Á¤º¸¸¦ °»½Å 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 ) { parent->DetachChild( pnode->GetNiObj() ); } else { assert(0); } } cSoundSceneNode* cDynamicSceneNode::LinkSound( unsigned long soundIdx, bool bLoop ) { /// ÂüÁ¶ÇÒ À§Ä¡ °´Ã¼ ȹµæ.. NiNode* pDummy = NiDynamicCast( NiNode, GetNiObj()->GetObjectByName("body_dummy") ); if( pDummy == NULL ) { return NULL; } sSoundInfo* pInfo = SOUNDSYS->GetSoundInfo( soundIdx ); if( pInfo == 0 ) return 0; cSoundSceneNodeParam param; if( pInfo->mRadius <= 0.0f ) { param.mRadius = 100.0f; } else { param.mRadius = pInfo->mRadius; } param.mLoopCount = bLoop? 0:1; param.mVolumeRatio = pInfo->mVolume; /// ±âº» ¼Ó¼º ÀÎÀÚµéÀ» ¼³Á¤ param.mPathName = pInfo->mFileName; param.mTranslate = pDummy->GetWorldTranslate(); param.mManaged = true; param.mpOwnerSceneNode = this; param.mEffectSound = true; cSoundSceneNode* pnode = SCENEMAN->CreateEffectSound( param ); if( pnode ) { mSoundList.PushBack( pnode->GetIndexByManger() ); // mSoundList.AddFirstEmpty( pnode ); } 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; cSceneNode::AddToVisibleArray(); NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { sTrailInfo* p = mRibbonList.GetNext(pos); cRibbonGeometry* geom = p->mRibbonGeom; if( geom && geom->GetActiveVerts() >= 4 ) SCENEMAN->AddVisibleTrailGeom( geom ); } } 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; } /* void cDynamicSceneNode::CollectPickData( NiAVObject* pobj ) { if( pobj->GetName() == "PickObj" ) { mPickDataList.PushBack( pobj ); return; } else if( NiIsKindOf(NiNode, pobj) ) { NiAVObject* child = 0; NiNode* node = (NiNode*)pobj; for( unsigned int i = 0, end = node->GetArrayCount(); i < end; ++i ) { child = node->GetAt(i); if( child ) CollectPickData( child ); } } } */ 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 = 2.0f; 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::LinkDataInit( NiAVObject* pobj ) { if( pobj == 0 ) return; if( pobj->GetName() == "EffectSceneNode" ) return; if( pobj->GetName() == "PickObj" ) return; if( pobj->GetName() == "weapon_dummy" ) return; NiTransform trans; trans.MakeIdentity(); if( NiIsKindOf( NiMesh, pobj ) == true ) { pobj->SetWorldTranslate( NiPoint3::ZERO ); pobj->SetWorldRotate( NiMatrix3::IDENTITY ); pobj->SetWorldScale( trans.m_fScale ); pobj->SetLocalTransform( trans ); } else if( NiIsKindOf(NiNode, pobj) == true ) { NiNode* node = (NiNode*)pobj; node->SetWorldTranslate( NiPoint3::ZERO ); node->SetWorldRotate( NiMatrix3::IDENTITY ); node->SetWorldScale( trans.m_fScale ); node->SetLocalTransform( trans ); NiAVObject* child = 0; for( unsigned int i = 0, iend = node->GetArrayCount(); i < iend; ++i ) { child = node->GetAt(i); if( child ) LinkDataInit( child ); } } } void cDynamicSceneNode::GotoLastFrame() { NiControllerSequence* p = mpActorManager->GetActiveSequence(mpActorManager->GetTargetAnimation(), true, true ); if( p ) { float time = 0.0f; time = p->GetKeyTimeAt( NiAnimationConstants::GetEndTextKey() ); if( time != NiControllerSequence::INVALID_TIME ) mpActorManager->Update( -time ); } /* NiControllerSequence* p = mpActorManager->GetSequence( mpActorManager->GetTargetAnimation() ); if( p ) { float time = 0.0f; time = p->GetEndKeyTime(); 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 ) { NiTexture* tex = RESOURCEMAN->LoadTexture( str ); if( tex == 0 ) { assert(0); return 0; } cRibbonGeometry* geom = NiNew cRibbonGeometry; if( geom->Init( THEAPP->GetAccumTime(), tex, 500, 10 ) == false) { NiDelete geom; return 0; } sTrailInfo* info = new sTrailInfo; info->mRibbonGeom = geom; info->mLifeTime = THEAPP->GetAccumTime() + 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::ClearAllEffect() { 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 ) { parent->DetachChild( n->GetNiObj() ); } else { assert(0); } n->ParentNodeRemove(); } } } mEffectList.Clear(); NiTListIterator pos = mRibbonList.GetHeadPos(); while( pos ) { sTrailInfo* p = mRibbonList.GetNext(pos); SAFE_NIDELETE( p ); } mRibbonList.RemoveAll(); } 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 ) { parent->DetachChild( n->GetNiObj() ); } else { assert(0); } 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::CollectNodeInfo( NiAVObject* obj, bool& collectGeom, bool& collectProperty ) { cSceneNode::CollectNodeInfo( obj, collectGeom, collectProperty ); ///// ÇÈÅ·¹Ú½º ÃßÃâ //if( obj->GetName() == "PickObj" ) //{ // if( NiIsKindOf( NiMesh, obj ) == true) // { // mPickDataList.PushBack( (NiMesh*)obj ); // } // else // { // assert(0); // } //} } 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; }