void KG3DTransformation::Interpolation(KG3DTransformation &NextTrans, float fFactor) { m_ScalingCenter += (NextTrans.m_ScalingCenter - m_ScalingCenter) * fFactor; m_Scaling += (NextTrans.m_Scaling - m_Scaling) * fFactor; m_RotationCenter += (NextTrans.m_RotationCenter - m_RotationCenter) * fFactor; m_Translation += (NextTrans.m_Translation - m_Translation) * fFactor; D3DXQuaternionSlerp(&m_ScalingRotation, &m_ScalingRotation, &NextTrans.m_ScalingRotation, fFactor); D3DXQuaternionSlerp(&m_Rotation, &m_Rotation, &NextTrans.m_Rotation, fFactor); ASSERT_FLOAT_IS_VALIED(m_Rotation.x); UpdateTransformation(); }
void IObj::DirectionRotation( bool IsSmooth ) { // D3DXVec3Normalize( &m_vDirection, &m_vDirection ); D3DXVECTOR3 vCoord; D3DXVECTOR3 vCross; D3DXMATRIXA16 matRotY; D3DXMatrixRotationY( &matRotY, -D3DX_PI * 0.5f ); D3DXVec3TransformCoord( &vCoord, &m_vDirection, &matRotY ); D3DXVec3Normalize( &vCoord, &vCoord ); D3DXMatrixRotationX( &matRotY, D3DX_PI ); D3DXVec3Cross( &vCross, &vCoord, &m_vDirection ); D3DXVec3TransformCoord( &vCross, &vCross, &matRotY ); D3DXVec3Normalize( &vCross, &vCross ); memcpy( &m_matLookAt._11, &vCoord, sizeof( D3DXVECTOR3 ) ); memcpy( &m_matLookAt._21, &vCross, sizeof( D3DXVECTOR3 ) ); memcpy( &m_matLookAt._31, &m_vDirection, sizeof( D3DXVECTOR3 ) ); memcpy( &m_matLookAt._41, &D3DXVECTOR3( 0.0f, 0.0f, 0.0f ), sizeof( D3DXVECTOR3 ) ); D3DXQUATERNION q; D3DXQuaternionRotationMatrix( &q, &m_matLookAt ); D3DXQuaternionSlerp( &m_quatLookAt, &m_quatLookAt, &q, 0.1f ); }
void CObject3D::_animate(float currentFrame_, int nextFrame) { TMAnimation* frame = null; TMAnimation* next = null; D3DXQUATERNION slerp; D3DXVECTOR3 lerp; D3DXMATRIX m1, m2; D3DXMATRIX* updates = m_group->updates; D3DXMATRIX* parent; GMObject* obj; const int currentFrame = (int)currentFrame_; const float slp = currentFrame_ - (float)currentFrame; for (int i = 0; i < m_group->objectCount; i++) { obj = &m_group->objects[i]; if (obj->parentType == GMT_BONE) { if (m_externBones) parent = m_externBones; else parent = m_baseBones; } else parent = updates; if (m_frameCount > 0) { if (obj->frames) { frame = &obj->frames[currentFrame]; next = &obj->frames[nextFrame]; D3DXQuaternionSlerp(&slerp, &frame->rot, &next->rot, slp); D3DXVec3Lerp(&lerp, &frame->pos, &next->pos, slp); D3DXMatrixTranslation(&m1, lerp.x, lerp.y, lerp.z); D3DXMatrixRotationQuaternion(&m2, &slerp); updates[i] = m2 * m1; if (obj->parentID != -1) updates[i] *= parent[obj->parentID]; } else { if (obj->parentID != -1) updates[i] = obj->transform * parent[obj->parentID]; else updates[i] = obj->transform; } } else { if (obj->parentID != -1) updates[i] = obj->transform * parent[obj->parentID]; else updates[i] = obj->transform; } } }
Mat CD3D11Skeleton::Lerp( D3DXMATRIX a, D3DXMATRIX b, float s ) { //Decompose a D3DXVECTOR3 t1, s1; D3DXQUATERNION q1; D3DXMatrixDecompose(&s1, &q1, &t1, &a); //Decompose b D3DXVECTOR3 t2, s2; D3DXQUATERNION q2; D3DXMatrixDecompose(&s2, &q2, &t2, &b); //Lerp each component D3DXVECTOR3 ti; D3DXVec3Lerp(&ti, &t1, &t2, s); D3DXVECTOR3 si; D3DXVec3Lerp(&si, &s1, &s2, s); D3DXQUATERNION qi; D3DXQuaternionSlerp(&qi, &q1, &q2, s); //Recompose each component D3DXMATRIX Tr, Sc, Rt; D3DXMatrixTranslation(&Tr, ti.x, ti.y, ti.z); D3DXMatrixScaling(&Sc, si.x, si.y, si.z); D3DXMatrixRotationQuaternion(&Rt, &qi); //Product D3DXMATRIX p = Sc * Rt * Tr; //Return return Mat((float*)p.m); }
void CRotationInterpolator::Interpolate(float fPos, SQuaternion* psRotation1, SQuaternion* psRotation2) { float fInv; fInv = 1.0f - fPos; D3DXQuaternionSlerp((D3DXQUATERNION*)&msOutput, (D3DXQUATERNION*)psRotation1, (D3DXQUATERNION*)psRotation2, fInv); }
//----[ setTrackAnimation ]-------------------------------------------------- void AnimatedMeshRenderer::setTrackAnimation( AnimatedMeshAnimationTrack* track, AnimatedMeshAnimationIndex animation, float position) const { assert(position >= 0.0f && position < 1.0f); AnimatedMeshAnimationTrackElement* internal_track = reinterpret_cast<AnimatedMeshAnimationTrackElement*>(track); assert(animation < animated_mesh_animations_.size()); if (animation >= animated_mesh_animations_.size()) return; const AnimatedMeshAnimation& animated_mesh_animation = animated_mesh_animations_.at(animation); size_t number_of_animated_frames = animated_mesh_animation.number_of_animated_frames; // Get the data about the keys that bound this animation position size_t number_of_keys = animated_mesh_animation.number_of_keys; assert(number_of_keys); double key_position = position * double(number_of_keys-1); double lower_key_flt = floor(key_position); size_t lower_key = size_t(lower_key_flt); float upper_weight; upper_weight = key_position - lower_key_flt; size_t upper_key = (number_of_keys == 1) ? 0 : (lower_key + 1); assert(upper_key < number_of_keys); // ensure the upper key is valid // The upper and lower transform pointers are advanced as the naimation // is applied. const AnimatedMeshAnimation::AnimatedFrameTransform* lower_transform = animated_mesh_animation.animated_frame_transforms + (lower_key * number_of_animated_frames); const AnimatedMeshAnimation::AnimatedFrameTransform* upper_transform = animated_mesh_animation.animated_frame_transforms + (upper_key * number_of_animated_frames); // Animate all frames for (size_t i = 0; i < number_of_animated_frames; ++i) { unsigned int frame_index = animated_mesh_animation.animated_frame_to_frame_table[i]; AnimatedMeshAnimationTrackElement* frame = internal_track + frame_index; D3DXVec3Lerp(frame->frame_transform.scaling(), &lower_transform->scaling, &upper_transform->scaling, upper_weight); D3DXVec3Lerp(frame->frame_transform.translation(), &lower_transform->translation, &upper_transform->translation, upper_weight); D3DXQuaternionSlerp(frame->frame_transform.rotation(), &lower_transform->rotation, &upper_transform->rotation, upper_weight); ++upper_transform; ++lower_transform; } }
void quater::slerp( quater const& a, quater const& b, double t ) { #ifdef USE_D3DFUNC D3DXQuaternionSlerp(*this, a, b, t); #else /* ogre implementation doesn't work double fCos = a%b; double fAngle ( acos(fCos) ); if ( ABS(fAngle) < EPS ) *this=a; double fSin = sin(fAngle); double fInvSin = 1.0/fSin; double fCoeff0 = sin((1.0-t)*fAngle)*fInvSin; double fCoeff1 = sin(t*fAngle)*fInvSin; if (fCos < 0.0f )// && shortestPath) { fCoeff0 = -fCoeff0; add(fCoeff0*a , fCoeff1*b); normalize(); } else { add(fCoeff0*a , fCoeff1*b); } */ // jehee lee implementation // buggy double c = a % b; if ( 1.0+c > EPS ) { if ( 1.0-c > EPS ) { double theta = (double)acos( c ); double sinom = (double)sin( theta ); this->mult(( a*(double)sin((1-t)*theta) + b*(double)sin(t*theta) ), 1.f/ sinom); } else this->normalize((a*(1-t) + b*t)); } else this->add(a*(double)sin((0.5-t)*M_PI) , b*(double)sin(t*M_PI)); #endif }
HRESULT CXFrameNode::UpdateMatrices(D3DXMATRIX* ParentMat) { if(m_TransUsed[0]) { D3DXVECTOR3 TransPos = m_TransPos[0]; D3DXVECTOR3 TransScale = m_TransScale[0]; D3DXQUATERNION TransRot = m_TransRot[0]; float LerpValue = m_LerpValue[0]; if(m_TransUsed[1]) { D3DXVec3Lerp(&TransScale, &TransScale, &m_TransScale[1], LerpValue); D3DXQuaternionSlerp(&TransRot, &TransRot, &m_TransRot[1], LerpValue); D3DXVec3Lerp(&TransPos, &TransPos, &m_TransPos[1], LerpValue); } // prepare local transformation matrix D3DXMatrixIdentity(&m_TransformationMatrix); D3DXMATRIX ScaleMat; D3DXMatrixScaling(&ScaleMat, TransScale.x, TransScale.y, TransScale.z); D3DXMatrixMultiply(&m_TransformationMatrix, &m_TransformationMatrix, &ScaleMat); D3DXMATRIX RotMat; D3DXMatrixRotationQuaternion(&RotMat, &TransRot); D3DXMatrixMultiply(&m_TransformationMatrix, &m_TransformationMatrix, &RotMat); D3DXMATRIX PosMat; D3DXMatrixTranslation(&PosMat, TransPos.x, TransPos.y, TransPos.z); D3DXMatrixMultiply(&m_TransformationMatrix, &m_TransformationMatrix, &PosMat); } m_TransUsed[0] = m_TransUsed[1] = false; // multiply by parent transformation D3DXMatrixMultiply(&m_CombinedMatrix, &m_TransformationMatrix, ParentMat); // update child frames for(int i=0; i<m_Frames.GetSize(); i++) { m_Frames[i]->UpdateMatrices(&m_CombinedMatrix); } return S_OK; }
//----[ blendTracks ]-------------------------------------------------------- void AnimatedMeshRenderer::blendTracks( const AnimatedMeshAnimationTrack* input_track_0, const AnimatedMeshAnimationTrack* input_track_1, float track_1_weight, AnimatedMeshAnimationTrack* output_track) const { //if (input_track_1 == output_track) { // input_track_1 = input_track_0; // input_track_0 = output_track; //} assert(track_1_weight >= 0.0f && track_1_weight <= 1.0f); const AnimatedMeshAnimationTrackElement* internal_track_0 = reinterpret_cast<const AnimatedMeshAnimationTrackElement*>(input_track_0); const AnimatedMeshAnimationTrackElement* internal_track_1 = reinterpret_cast<const AnimatedMeshAnimationTrackElement*>(input_track_1); AnimatedMeshAnimationTrackElement* internal_output_track = reinterpret_cast<AnimatedMeshAnimationTrackElement*>(output_track); size_t number_of_mesh_frames = highest_number_of_mesh_frames_; for (size_t frame_index = 0; frame_index < number_of_mesh_frames; ++frame_index) { const AnimatedMeshAnimationTrackElement* frames[2] = { internal_track_0 + frame_index, internal_track_1 + frame_index, }; AnimatedMeshAnimationTrackElement* output_frame = internal_output_track + frame_index; D3DXVec3Lerp(output_frame->frame_transform.translation(), frames[0]->frame_transform.translation(), frames[1]->frame_transform.translation(), track_1_weight); D3DXVec3Lerp(output_frame->frame_transform.scaling(), frames[0]->frame_transform.scaling(), frames[1]->frame_transform.scaling(), track_1_weight); D3DXQuaternionSlerp(output_frame->frame_transform.rotation(), frames[0]->frame_transform.rotation(), frames[1]->frame_transform.rotation(), track_1_weight); } }
void CRigidBody::Update(TimeMS now) { m_position += m_velocity * ((float)(now - m_lastUpdate) / 1000.0f); D3DXQUATERNION orientationTemp; while (now - m_lastUpdate > 1000) { orientationTemp = m_orientation; D3DXQuaternionMultiply(&m_orientation, &m_angularVelocity, &orientationTemp); m_lastUpdate += 1000; } orientationTemp = m_orientation; D3DXQUATERNION orientationFull; D3DXQuaternionMultiply(&orientationFull, &m_angularVelocity, &orientationTemp); D3DXQuaternionSlerp(&m_orientation, &orientationTemp, &orientationFull, (float)(now - m_lastUpdate) / 1000.0f); m_lastUpdate = now; }
/***************************************************************** * D3DXMATRIX Interpolate(D3DXMATRIX _d3dPrevFrame, D3DXMATRIX _d3dNextFrame, float _fLambda): * Interpolates between two Matrices based on Lambda time * * Ins: D3DXMATRIX _d3dPrevFrame * D3DXMATRIX _d3dNextFrame * float _fLambda * * Outs: void * * Returns: D3DXMATRIX * * Mod. Date: 02/20/2013 * Mod. Initials: SD *****************************************************************/ D3DXMATRIX Interpolate(D3DXMATRIX& d3dMatrixA, D3DXMATRIX& d3dMatrixB, float fLambda) { D3DXQUATERNION quatA, quatB, tempQuat; D3DXQuaternionRotationMatrix(&quatA, &d3dMatrixA); D3DXQuaternionRotationMatrix(&quatB, &d3dMatrixB); tempQuat = quatA; D3DXQuaternionNormalize(&quatA, &tempQuat); tempQuat = quatB; D3DXQuaternionNormalize(&quatB, &tempQuat); D3DXQuaternionSlerp(&tempQuat, &quatA, &quatB, fLambda); D3DXMATRIX result; D3DXMatrixRotationQuaternion(&result, &tempQuat); D3DXVec3Lerp((D3DXVECTOR3*)&result[12], (D3DXVECTOR3*)&d3dMatrixA[12], (D3DXVECTOR3*)&d3dMatrixB[12], fLambda); D3DXVECTOR3 scaleA = D3DXVECTOR3(d3dMatrixA[0],d3dMatrixA[5],d3dMatrixA[10]); D3DXVECTOR3 scaleB = D3DXVECTOR3(d3dMatrixB[0],d3dMatrixB[5],d3dMatrixB[10]); D3DXVECTOR3 finalScale; D3DXVec3Lerp(&finalScale, &scaleA, &scaleB, fLambda); result[0] = finalScale[0]; result[5] = finalScale[1]; result[10] = finalScale[2]; return result; }
void CMotion::Animate(D3DXMATRIX* bones, float currentFrame_, int nextFrame) { TMAnimation* frame = null; TMAnimation* next = null; D3DXQUATERNION slerp; D3DXVECTOR3 lerp; D3DXMATRIX m1, m2; const int currentFrame = (int)currentFrame_; const float slp = currentFrame_ - (float)currentFrame; for (int i = 0; i < m_boneCount; i++) { if (m_frames[i].frames) { frame = &m_frames[i].frames[currentFrame]; next = &m_frames[i].frames[nextFrame]; D3DXQuaternionSlerp(&slerp, &frame->rot, &next->rot, slp); D3DXVec3Lerp(&lerp, &frame->pos, &next->pos, slp); D3DXMatrixTranslation(&m1, lerp.x, lerp.y, lerp.z); D3DXMatrixRotationQuaternion(&m2, &slerp); m2 *= m1; if (m_bones[i].parentID != -1) m2 *= bones[m_bones[i].parentID]; } else { m2 = m_frames[i].TM; if (m_bones[i].parentID != -1) m2 *= bones[m_bones[i].parentID]; } bones[i] = m2; } }
/** Samples the current values for a number of curves in the given animation group. The sampled values will be written to a client provided vector4 array. @param time a point in time @param groupIndex index of animation group to sample from @param firstCurveIndex group-relative curve index of first curve to sample @param numCurves number of curves to sample @param dstKeyArray pointer to vector4 array with numCurves element which will be filled with the results - 18-Oct-2004 floh Fixed collapsed curve check (now checks if start key is -1, instead of the curveIpolType). The curve ipol type MUST be set to something sane even for collapsed curves, because it's used at various places for deviding whether quaternion-interpolation must be used instead of simple linear interpolation!! */ void U2MemAnimation::SampeInterpKeys(float fTime, int iInterpGroupIdx, int firstInterpKeyIdx, int numInterpKeys, D3DXVECTOR4* pDstKeyArray) { const InterpKeyGroup& group = GetInterpKeyGroup(iInterpGroupIdx); int startKey = group.GetStartKey(); float frameTime = startKey * group.GetKeyTime(); int keyIdx[2]; int startKeyIdx[2]; float fStartInBetween; float fInBetween; group.TimeToIdx(0.0f, startKeyIdx[0], startKeyIdx[1], fStartInBetween); group.TimeToIdx(fTime, keyIdx[0], keyIdx[1], fInBetween); int i; static D3DXQUATERNION q0; static D3DXQUATERNION q1; static D3DXQUATERNION q; int animCnt = 0; for(i=0; i < numInterpKeys; ++i) { InterpKey& curve = group.GetInterpKey(i + firstInterpKeyIdx); if(curve.GetFirstKeyIdx() == -1) { // a collapsed curve pDstKeyArray[i] = curve.GetConstValue(); curve.SetStartValue(curve.GetConstValue()); } else { switch(curve.GetInterpType()) { case InterpKey::INTERP_STEP: { int idx0 = curve.GetFirstKeyIdx()+ keyIdx[0]; pDstKeyArray[i] = m_keyArray[idx0]->m_key; idx0 = curve.GetFirstKeyIdx(); curve.SetStartValue(m_keyArray[idx0]->m_key); } break; case InterpKey::INTERP_QUAT: { int curveFirstKeyIdx = curve.GetFirstKeyIdx(); int idx0 = curveFirstKeyIdx + keyIdx[0]; int idx1 = curveFirstKeyIdx + keyIdx[1]; D3DXQUATERNION key0 = m_keyArray[idx0]->m_key; D3DXQUATERNION key1 = m_keyArray[idx1]->m_key; q0 = D3DXQUATERNION(key0.x, key0.y, key0.z, key0.w); q1 = D3DXQUATERNION(key1.x, key1.y, key1.z, key1.w); D3DXQuaternionSlerp(&q, &q0, &q1, fInBetween); pDstKeyArray[i] = D3DXVECTOR4(q.x, q.y, q.z, q.w); idx0 = curveFirstKeyIdx + startKeyIdx[0]; idx1 = curveFirstKeyIdx + startKeyIdx[1]; key0 = (float*)&m_keyArray[idx0]->m_key; key1 = (float*)&m_keyArray[idx1]->m_key; q0 = D3DXQUATERNION(key0.x, key0.y, key0.z, key0.w); q1 = D3DXQUATERNION(key1.x, key1.y, key1.z, key1.w); D3DXQuaternionSlerp(&q, &q0, &q1, fInBetween); D3DXVECTOR4 val(q.x, q.y, q.z, q.w); curve.SetConstValue(val); } break; case InterpKey::INTERP_LINEAR: { int curveFirstKeyIdx = curve.GetFirstKeyIdx(); int idx0 = curveFirstKeyIdx + keyIdx[0]; int idx1 = curveFirstKeyIdx + keyIdx[1]; const D3DXVECTOR4& v0 = m_keyArray[idx0]->m_key; const D3DXVECTOR4& v1 = m_keyArray[idx1]->m_key; pDstKeyArray[i] = v0 + ((v1 - v0) * fInBetween); idx0 = curveFirstKeyIdx + startKeyIdx[0]; idx1 = curveFirstKeyIdx + startKeyIdx[1]; D3DXVECTOR4 v2 = m_keyArray[idx0]->m_key; D3DXVECTOR4 v3 = m_keyArray[idx1]->m_key; curve.SetStartValue(v2 + ((v3 - v2) * fStartInBetween)); } break; default: U2ASSERT(FALSE); FDebug("U2MemoryAnimation::SampleCurves(): invalid curveIpolType %d!", curve.GetInterpType()); break; } } } }
void MotionController::UpdatePosAndRot(char* boneName, float time, int boneID, D3DXVECTOR3* pos, D3DXQUATERNION* rot) { //if the bone ID is invalid or name doesn't match //attempt to find the bone by searching for the name if (boneID >= numBones || strcmp(boneName, boneTracks[boneID].name)) { bool found = false; //search for bone name in list for (int b=0;b<numBones;b++) { if (!strcmp(boneName, boneTracks[b].name)) { boneID = b; found = true; break; } } //if can't find bone, don't do anything if (!found) return; } //get the animation track & info for this bone BONE_TRACK boneTrack = boneTracks[boneID]; int boneCurKeyframe = boneTrack.curKeyframe; int boneNumKeyframe = boneTrack.numKeyframes; KEY_BONE *keys = boneTrack.keys; //get the last keyframe in this animation track KEY_BONE lastKey; //curKeyframe should be 1-based, but if for some reason it's not... if (boneCurKeyframe == 0) lastKey = keys[boneCurKeyframe]; else lastKey = keys[boneCurKeyframe-1]; //if past end of animation, return data from last keyframe if (boneCurKeyframe >= boneNumKeyframe) { *pos = lastKey.pos; *rot = lastKey.rot; return; } //get the next keyframe in the animation KEY_BONE nextKey = keys[boneCurKeyframe]; //calculate current frame # from provided time and FPS int curFrame = (int)(time*_fps); //increment curKeyframe if time passed next defined keyframe if (curFrame >= nextKey.frame) { //increment keyframe counter boneTracks[boneID].curKeyframe++; boneCurKeyframe++; //get previous keyframe of new keyframe lastKey = keys[boneCurKeyframe - 1]; //if just passed final keyframe, return data from last keyframe if (boneCurKeyframe >= boneNumKeyframe) { *pos = lastKey.pos; *rot = lastKey.rot; return; } else { //otherwise just get next keyframe nextKey = keys[boneCurKeyframe]; } } //get frame numbers of last and next keyframe int lastKeyframeFrame = lastKey.frame; int nextKeyframeFrame = nextKey.frame; //check if need to update latest frame number if (lastKeyframeFrame > latestKeyframe) { latestKeyframe = lastKeyframeFrame; } //calculate distance (in frames) between next and last keyframes int totDist = nextKeyframeFrame - lastKeyframeFrame; //if this happens something done f****d up if (totDist == 0) return; //get the distance from current frame (based on time) to last keyframe frame # int distLastToCur = curFrame - lastKeyframeFrame; //get percentage of distance current frame is from last keyframe to next keyframe float s = ((float)distLastToCur/(float)totDist); //check limits if (s > 1) s = 1; //solve all bezier curves for interpolated percentage float intX, intY, intZ, intRot; intX = AMBezier::solveForY(s, nextKey.interpol[0][0], nextKey.interpol[0][1], nextKey.interpol[0][2], nextKey.interpol[0][3]); intY = AMBezier::solveForY(s, nextKey.interpol[1][0], nextKey.interpol[1][1], nextKey.interpol[1][2], nextKey.interpol[1][3]); intZ = AMBezier::solveForY(s, nextKey.interpol[2][0], nextKey.interpol[2][1], nextKey.interpol[2][2], nextKey.interpol[2][3]); intRot = AMBezier::solveForY(s, nextKey.interpol[3][0], nextKey.interpol[3][1], nextKey.interpol[3][2], nextKey.interpol[3][3]); //do basic linear interpolation with the interpolated //percentage to get final position and rotation pos->x = (1-intX)*lastKey.pos.x + (intX*nextKey.pos.x); pos->y = (1-intY)*lastKey.pos.y + (intY*nextKey.pos.y); pos->z = (1-intZ)*lastKey.pos.z + (intZ*nextKey.pos.z); D3DXQuaternionSlerp(rot, &lastKey.rot, &nextKey.rot, intRot); //not off the first frame, so the animation can be reset needsReset = true; }
INT CLcAcmIns::FrameMove() { INT hr = 0; INT iNgeo = m_pLcHead->iNgeo; INT i = 0; INT dFrmB = 0; // Begin Frame INT dFrmE = 0; // End Frame if(!m_bAnima) return 0; if(NULL == m_pFrame || m_pFrame->empty()) { dFrmB = m_pLcHead->nFrmF ; dFrmE = m_pLcHead->nFrmL ; } else { vector<_Tframe >::iterator p = m_pFrame->begin() + m_nActM; dFrmB = p->nB; dFrmE = p->nE; } // 현재 프레임 계산 : Frame = FrameSpeed(n/s) * Time(s) + Begin Frame // 시간 단위: 초 m_dFrmCur = m_pLcHead->nFrmS * m_dTimeCur + dFrmB; // End Frame보다 크면 재조정 if(m_dFrmCur>= dFrmE) { // 나머지 시간을 현재시간으로 설정 FLOAT t = FLOAT(dFrmE-dFrmB) /m_pLcHead->nFrmS; m_dTimeCur = m_dTimeCur - t; m_dFrmCur = m_pLcHead->nFrmS * m_dTimeCur + dFrmB; hr = 1; // Return 값을 애니메이션 한 번 수행 것으로한다. } // 1. 현재 프레임, 다음 프레임, 비중을 구한다. // 시간에서 프레임을 구한다. INT nFrmC = INT(m_dFrmCur); // End Frame FLOAT fFrmW = m_dFrmCur - nFrmC; // 소수점은 비중이 된다. INT nFrmN = nFrmC+1; // Next Frame // // End Frame보다 크면 재조정 // if(1 == hr) // nFrmN = nFrmC; // 2. 애니메이션에 관련된 행렬들을 갱신한다. // 월드 행렬 = 지역행렬 * 부모의 월드 행렬 * 전체 월드 행렬 // 전체 월드 행렬의 곱셈 적용은 쉐이더에서 한다. for(i=0; i<m_pLcHead->iNgeo; ++i) { CLcAcm::LcGeo* pDst = &m_pLcGeo[i]; MATA mtL(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); MATA mtP(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1); if(pDst->nPrn>=0) { CLcAcm::LcGeo* pPrn = &m_pLcGeo[pDst->nPrn]; mtP = pPrn->mtWld; } // 프레임에 대한 행렬이 있는 경우 월드 행렬 = 지역행렬 * 부모의 월드 행렬 // 을 적용하지 않고 바로 월드 행렬을 구한다. // 여기서 구한 월드 행렬은 맥스에서 구성한 장면의 기준 좌표계가 된다. // 각각의 Geometry의 행렬 = 해당 방향 행렬 * 지역행렬 if(!pDst->vAniRot->empty()) { VEC3 p(0,0,0); QUAT q(0,0,0,1); VEC3 p1 = *(pDst->vAniTrn->begin() + nFrmC); VEC3 p2 = *(pDst->vAniTrn->begin() + nFrmN); QUAT q1 = *(pDst->vAniRot->begin() + nFrmC); QUAT q2 = *(pDst->vAniRot->begin() + nFrmN); p = p1 * (1.f - fFrmW) + p2 * fFrmW; // 위치를 선형 보간 D3DXQuaternionSlerp(&q, &q1, &q2, fFrmW); // 회전을 선형 보간. slerp을 이용 D3DXMatrixRotationQuaternion(&mtL, &q); mtL._41 = p.x; mtL._42 = p.y; mtL._43 = p.z; pDst->mtWld = pDst->mtOrn * mtL; // 맥스에서 지정된 방향 행렬을 곱해야 한다. if(NULL == m_mtPrn) pDst->mtPvt = mtL * m_mtWld; else pDst->mtPvt = mtL * (*m_mtPrn); } else // 계층구조와 동일 { pDst->mtWld = mtL * mtP; if(NULL == m_mtPrn) pDst->mtPvt = pDst->mtOrI * pDst->mtWld * m_mtWld; else pDst->mtPvt = pDst->mtOrI * pDst->mtWld * (*m_mtPrn); } m_pmtWld[i] = pDst->mtWld; // 행렬 팔레트에 복사. } // // Texture Animation // int iSize = (INT)m_vIfl.size(); // // dTimeC = ::timeGetTime(); // if(dTimeC >m_dIflTime+m_dIflIntv) // { // m_dIflTime = dTimeC; // // for(i=0; i<iSize; ++i) // { // CLcAcm::TaniTx* pTani = &m_vIfl[i]; // CLcAcm::LcMtl* pMtl = pTani->pM; // // ++pTani->nF; // // INT nTot = pMtl->pvIfl->size(); // // pTani->nF %= nTot; // // vector<TaniIfl>::iterator it = pMtl->pvIfl->begin() + pTani->nF; // // pTani->pT = it->pT; // } // } // For Sort...(optional) MATA mtViwI; LPDIRECT3DDEVICE9 pDev = (LPDIRECT3DDEVICE9)LcDev_GetD3Device(); pDev->GetTransform( D3DTS_VIEW, &mtViwI ); D3DXMatrixInverse(&mtViwI, NULL, &mtViwI); VEC3 vcCam = VEC3(mtViwI._41, mtViwI._42, mtViwI._43); VEC3 vcZ = VEC3(mtViwI._31, mtViwI._32, mtViwI._33); VEC3 vcTmp = m_vcTrn - vcCam; m_fStlSrtR = D3DXVec3Dot(&vcZ, &vcTmp); return hr; }
void CKrakenLeg::SwingAttack(float fElapsed) { float Distance = 0; D3DXVECTOR3 CharPos = m_pInplay->GetCharacter()->GetPosition(); Distance = D3DXVec3Length( &D3DXVECTOR3(CharPos - m_vPos) ); if(Distance < 2.0) { D3DXMATRIX Rot; D3DXQUATERNION QuaRot; D3DXQUATERNION QuaStart; D3DXQUATERNION QuaSlerp; D3DXVECTOR3 ZVector(0,0,1); m_vDirection = m_pInplay->GetCharacter()->GetPosition()- m_vPos; D3DXMatrixIdentity(&Rot); Rot._11 = m_pInplay->GetCamera()->GetViewMatrix()->_11; Rot._13 = m_pInplay->GetCamera()->GetViewMatrix()->_13; Rot._31 = m_pInplay->GetCamera()->GetViewMatrix()->_31; Rot._33 = m_pInplay->GetCamera()->GetViewMatrix()->_33; Rot._41 = m_vPos.x; Rot._42 = m_vPos.y; Rot._43 = m_vPos.z; D3DXMatrixInverse( &Rot, NULL, &Rot ); D3DXQuaternionRotationMatrix( &QuaStart, &m_matRotate); D3DXQuaternionRotationMatrix( &QuaRot, &Rot); if( D3DXVec3Dot(&ZVector,&m_vDirection) < 0) { D3DXQuaternionSlerp(&QuaSlerp, &QuaRot, &QuaStart, fElapsed); } else { D3DXQuaternionSlerp(&QuaSlerp, &QuaStart, &QuaRot, fElapsed); } D3DXMatrixRotationQuaternion(&Rot,&QuaSlerp); m_matRotate = Rot; m_fAttackTimer += fElapsed; if( m_fAttackTimer >4.0f ) { ChangeAnimation(1); } if( m_fAttackTimer > 5.63f) { m_fAnimationTime = 0; m_pInplay->GetCharacter()->AddHp( -200 ) ; ChangeAnimation(2); m_fAttackTimer = 0; } } else { ChangeAnimation(2); } }
bool GBoneObj::AniFrame(FLOAT fCurFrame, FLOAT fElapsedTime, int iFirstFrame, int iLastFrame, D3DXMATRIX* pMatrix) { if (pMatrix == NULL) { pMatrix = m_pMatrix; } bool bResult = false; D3DXQUATERNION TmpQuat; int iCurFrame = (int)fCurFrame; int iNextFrame = iCurFrame + 1; D3DXVECTOR3 vScale, vTrans; D3DXMATRIX matRotate, matScale, matTrans; D3DXMatrixIdentity(&matScale); for (int i = 0; i < m_Scene.iNumMesh; i++) { if (iNextFrame >= iLastFrame) { iCurFrame = iFirstFrame; D3DXQUATERNION CurQuat = m_ppAniQuater[i][iCurFrame]; D3DXQUATERNION NextQuat = m_ppAniQuater[i][iCurFrame + 1]; D3DXQuaternionSlerp(&TmpQuat, &CurQuat, &NextQuat, fElapsedTime); D3DXMatrixRotationQuaternion(&matRotate, &TmpQuat); //D3DXVec3Lerp(&vScale, &m_ppScaleVector[i][iCurFrame], &m_ppScaleVector[i][iCurFrame + 1], fElapsedTime); //D3DXMatrixScaling(&matScale, vScale.x, vScale.y, vScale.z); //D3DXVec3Lerp(&vTrans, &m_ppTransVector[i][iCurFrame], &m_ppTransVector[i][iCurFrame + 1], fElapsedTime); D3DXMatrixScaling(&matScale, m_ppScaleVector[i][iCurFrame].x, m_ppScaleVector[i][iCurFrame].y, m_ppScaleVector[i][iCurFrame].z); vTrans = m_ppTransVector[i][iCurFrame]; pMatrix[i] = matScale * matRotate; pMatrix[i]._41 = vTrans.x; pMatrix[i]._42 = vTrans.y; pMatrix[i]._43 = vTrans.z; bResult = true; } else { D3DXQUATERNION CurQuat = m_ppAniQuater[i][iCurFrame]; D3DXQUATERNION NextQuat = m_ppAniQuater[i][iNextFrame]; D3DXQuaternionSlerp(&TmpQuat, &CurQuat, &NextQuat, fElapsedTime); D3DXMatrixRotationQuaternion(&matRotate, &CurQuat); //D3DXVec3Lerp(&vScale, &m_ppScaleVector[i][iCurFrame], &m_ppScaleVector[i][iNextFrame], fElapsedTime); //D3DXMatrixScaling(&matScale, vScale.x, vScale.y, vScale.z); //D3DXVec3Lerp(&vTrans, &m_ppTransVector[i][iCurFrame], &m_ppTransVector[i][iNextFrame], fElapsedTime); D3DXMatrixScaling(&matScale, m_ppScaleVector[i][iCurFrame].x, m_ppScaleVector[i][iCurFrame].y, m_ppScaleVector[i][iCurFrame].z); vTrans = m_ppTransVector[i][iCurFrame]; pMatrix[i] = matScale * matRotate; pMatrix[i]._41 = vTrans.x; pMatrix[i]._42 = vTrans.y; pMatrix[i]._43 = vTrans.z; } } return bResult;//( iCurFrame > m_iLastFrame ) ? TRUE : FALSE; }
//----[ addTrackAnimation ]-------------------------------------------------- void AnimatedMeshRenderer::addTrackAnimation( AnimatedMeshAnimationTrack* track, float track_weight, AnimatedMeshAnimationIndex animation, float animation_weight, float position) const { assert(position >= 0.0f && position < 1.0f); AnimatedMeshAnimationTrackElement* internal_track = reinterpret_cast<AnimatedMeshAnimationTrackElement*>(track); assert(animation < animated_mesh_animations_.size()); if (animation >= animated_mesh_animations_.size()) return; const AnimatedMeshAnimation& animated_mesh_animation = animated_mesh_animations_.at(animation); size_t number_of_animated_frames = animated_mesh_animation.number_of_animated_frames; // Get the data about the keys that bound this animation position size_t number_of_keys = animated_mesh_animation.number_of_keys; assert(number_of_keys); double key_position = position * double(number_of_keys-1); double lower_key_flt = floor(key_position); size_t lower_key = size_t(lower_key_flt); float upper_weight; upper_weight = key_position - lower_key_flt; size_t upper_key = (number_of_keys == 1) ? 0 : (lower_key + 1); assert(upper_key < number_of_keys); // ensure the upper key is valid // The upper and lower transform pointers are advanced as the animation // is applied. const AnimatedMeshAnimation::AnimatedFrameTransform* lower_transform = animated_mesh_animation.animated_frame_transforms + (lower_key * number_of_animated_frames); const AnimatedMeshAnimation::AnimatedFrameTransform* upper_transform = animated_mesh_animation.animated_frame_transforms + (upper_key * number_of_animated_frames); // Animate all frames for (size_t i = 0; i < number_of_animated_frames; ++i) { unsigned int frame_index = animated_mesh_animation.animated_frame_to_frame_table[i]; AnimatedMeshAnimationTrackElement* frame = internal_track + frame_index; D3DXVECTOR3 scaling; D3DXVec3Lerp(&scaling, &lower_transform->scaling, &upper_transform->scaling, upper_weight); frame->frame_transform.s[0] *= track_weight; frame->frame_transform.s[1] *= track_weight; frame->frame_transform.s[2] *= track_weight; frame->frame_transform.s[0] += animation_weight * scaling.x; frame->frame_transform.s[1] += animation_weight * scaling.y; frame->frame_transform.s[2] += animation_weight * scaling.z; D3DXVECTOR3 translation; D3DXVec3Lerp(&translation, &lower_transform->translation, &upper_transform->translation, upper_weight); frame->frame_transform.t[0] *= track_weight; frame->frame_transform.t[1] *= track_weight; frame->frame_transform.t[2] *= track_weight; frame->frame_transform.t[0] += animation_weight * translation.x; frame->frame_transform.t[1] += animation_weight * translation.y; frame->frame_transform.t[2] += animation_weight * translation.z; D3DXQUATERNION rotation; D3DXQuaternionSlerp(&rotation, &lower_transform->rotation, &upper_transform->rotation, upper_weight); if (animation_weight >= 1.0f || track_weight <= 0.0f) { frame->frame_transform.r[0] = rotation.x; frame->frame_transform.r[1] = rotation.y; frame->frame_transform.r[2] = rotation.z; frame->frame_transform.r[3] = rotation.w; } else { D3DXQuaternionSlerp(frame->frame_transform.rotation(), frame->frame_transform.rotation(), &rotation, animation_weight); } /* frame->frame_transform.r[0] *= track_weight; frame->frame_transform.r[1] *= track_weight; frame->frame_transform.r[2] *= track_weight; frame->frame_transform.r[3] *= track_weight; frame->frame_transform.r[0] += animation_weight * rotation.x; frame->frame_transform.r[1] += animation_weight * rotation.y; frame->frame_transform.r[2] += animation_weight * rotation.z; frame->frame_transform.r[3] += animation_weight * rotation.w;*/ ++upper_transform; ++lower_transform; } }
void GGbsModel::MultiAniFrame(){ D3DXMATRIX matWldTrans; D3DXMATRIX matWldRotate; D3DXMATRIX matWldScale; D3DXMatrixIdentity(&matWldTrans); D3DXMatrixIdentity(&matWldRotate); D3DXMatrixIdentity(&matWldScale); D3DXQUATERNION qR, qS; D3DXMATRIX matCalc; D3DXMatrixIdentity(&matCalc); //m_fTickFrame = 6400.0f; m_fTickFrame += g_fSecPerFrame * m_fFrameSpeed *m_fTickPerFrame; if (m_fTickFrame >= m_fLastFrame * m_fTickPerFrame /*마지막 프레임 틱수*/) { m_fTickFrame = 0.0f; } //m_fTickFrame += 1000.0f; //if (m_fTickFrame >= 8000.0f /*마지막 프레임 틱수*/) //{ // m_fTickFrame = 0.0f; //} for (int i = 0; i < m_vGeomObj.size() ; i++) { if (m_vGeomObj[i]->m_bUsed == false) continue; D3DXMatrixIdentity(&m_vGeomObj[i]->m_matCalculation); matWldRotate = m_vGeomObj[i]->m_matWldRotate; matWldTrans = m_vGeomObj[i]->m_matWldTrans; matWldScale = m_vGeomObj[i]->m_matWldScale; D3DXQuaternionRotationMatrix(&qR, &matWldRotate); D3DXQuaternionRotationMatrix(&qS, &matWldScale); //for (int j = 0; j < m_vGeomObj[i]->m_vObj.size(); j++) { //if (m_vGeomObj[i].get()->m_bHasAniTrack) { //Translation if (m_vGeomObj[i].get()->m_vPosTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_POS, i); //애니메이션 보간. D3DXVECTOR3 vResultVector; D3DXVECTOR3 vP1 = pStartTrack->vecVector; D3DXVECTOR3 vP2 = pEndTrack->vecVector; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); if(pStartTrack != pEndTrack){ D3DXVec3Lerp(&vResultVector, &vP1, &vP2, fTValue); //T행렬 값 대입 matWldTrans._41 = vResultVector.x; matWldTrans._42 = vResultVector.y; matWldTrans._43 = vResultVector.z; } else { //T행렬 값 대입 matWldTrans._41 = pStartTrack->vecVector.x; matWldTrans._42 = pStartTrack->vecVector.y; matWldTrans._43 = pStartTrack->vecVector.z; } } //Rotation if (m_vGeomObj[i].get()->m_vRotTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; //D3DXQUATERNION qR; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_ROT, i); //사원수간의 보간.. if (pStartTrack == NULL && pEndTrack == NULL) { qR = m_vGeomObj[i].get()->m_vRotTrack[0]->qRotate;// = m_vGeomObj[i].get()->m_qRotation; } else if (pStartTrack == NULL) { qR;// = m_vGeomObj[i].get()->m_qRotation; float fTValue = (m_fTickFrame - 0) / (pEndTrack->iTick - 0); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } else if (pEndTrack == NULL) { qR = m_vGeomObj[i].get()->m_vRotTrack[m_vGeomObj[i].get()->m_vRotTrack.size() - 1].get()->qRotate; float fTValue = ((m_fTickFrame - pStartTrack->iTick) / (m_fFrameSpeed*m_fTickPerFrame)); D3DXQuaternionSlerp(&qR, &qR, &qR, fTValue); } else { qR = pStartTrack->qRotate; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } //사원수에서 행렬로 변환. D3DXMatrixRotationQuaternion(&matWldRotate, &qR);// 사원수에서 행렬로 변환 } //Scale if (m_vGeomObj[i].get()->m_vSclTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; D3DXMATRIX matScaleRot, matInvScaleRot; D3DXMatrixIdentity(&matScaleRot); D3DXMatrixIdentity(&matInvScaleRot); //D3DXQUATERNION qS; float fStartTick = 0.0f, fEndTick = 0.0f; D3DXVECTOR3 vScale(m_vGeomObj[i].get()->m_matWldScale._11, m_vGeomObj[i].get()->m_matWldScale._22, m_vGeomObj[i].get()->m_matWldScale._33); //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_SCL, i); //신축트랙 보간 if (pStartTrack == NULL) { //vScale = m_vGeomObj[i].get()->m_vecTM_SCALE; //D3DXQuaternionRotationAxis(&qS, &m_vGeomObj[i].get()->m_vecTM_SCALE_AXIS, m_vGeomObj[i].get()->m_fTM_SCALEAXISANG); fStartTick = 0.0f; fEndTick = pEndTrack->iTick; } else if (pEndTrack == NULL) { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pStartTrack->iTick + (m_fFrameSpeed*m_fTickPerFrame); } else { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pEndTrack->iTick; } float fTValue = (m_fTickFrame - fStartTick) / (fEndTick - fStartTick); D3DXVec3Lerp(&vScale, &vScale, &pEndTrack->vecVector, fTValue); D3DXQuaternionSlerp(&qS, &qS, &pEndTrack->qRotate, fTValue); //사원수 -> 행렬로 변환등... D3DXMatrixScaling(&matWldScale, vScale.x, vScale.y, vScale.z); D3DXMatrixRotationQuaternion(&matScaleRot, &qS); D3DXMatrixInverse(&matInvScaleRot, NULL, &matScaleRot); matWldScale = matInvScaleRot * matWldScale * matScaleRot; } if (m_vGeomObj[i].get()->m_pParentObj != NULL) { m_vGeomObj[i].get()->m_matCalculation = matCalc = matWldScale * matWldRotate * matWldTrans * m_vGeomObj[i].get()->m_pParentObj->m_matCalculation; int iTest = 0; // 인버스 매트릭스 확인 코드. D3DXVECTOR3 v0, v1, v2, v3; v0 = m_vGeomObj[i].get()->m_matCalculation.m[0]; v1 = m_vGeomObj[i].get()->m_matCalculation.m[1]; v2 = m_vGeomObj[i].get()->m_matCalculation.m[2]; D3DXVec3Cross(&v3, &v1, &v2); if (D3DXVec3Dot(&v3, &v0) < 0.0f) { D3DXMATRIX matW; D3DXMatrixScaling(&matW, -1.0f, -1.0f, -1.0f); D3DXMatrixMultiply(&m_vGeomObj[i].get()->m_matCalculation, &m_vGeomObj[i].get()->m_matCalculation, &matW); } } else { m_vGeomObj[i].get()->m_matCalculation = matCalc = matWldScale * matWldRotate * matWldTrans; int iTest = 0; // 인버스 매트릭스 확인 코드. D3DXVECTOR3 v0, v1, v2, v3; v0 = m_vGeomObj[i].get()->m_matCalculation.m[0]; v1 = m_vGeomObj[i].get()->m_matCalculation.m[1]; v2 = m_vGeomObj[i].get()->m_matCalculation.m[2]; D3DXVec3Cross(&v3, &v1, &v2); if (D3DXVec3Dot(&v3, &v0) < 0.0f) { D3DXMATRIX matW; D3DXMatrixScaling(&matW, -1.0f, -1.0f, -1.0f); D3DXMatrixMultiply(&m_vGeomObj[i].get()->m_matCalculation, &m_vGeomObj[i].get()->m_matCalculation, &matW); } } } //} //} //최종행렬. }
void GGbsModel::SingleAniFrame() { D3DXMATRIX matWldTrans; D3DXMATRIX matWldRotate; D3DXMATRIX matWldScale; D3DXMatrixIdentity(&matWldTrans); D3DXMatrixIdentity(&matWldRotate); D3DXMatrixIdentity(&matWldScale); m_fTickFrame += g_fSecPerFrame * m_fFrameSpeed *m_fTickPerFrame; if (m_fTickFrame >= m_fLastFrame * m_fTickPerFrame /*마지막 프레임 틱수*/) { m_fTickFrame = 0.0f; } if (m_vGeomObj[0].get()->m_bHasAniTrack) { //Translation if (m_vGeomObj[0].get()->m_vPosTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_POS); //애니메이션 보간. D3DXVECTOR3 vResultVector; D3DXVECTOR3 vP1 = pStartTrack->vecVector; D3DXVECTOR3 vP2 = pEndTrack->vecVector; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); D3DXVec3Lerp(&vResultVector, &vP1, &vP2, fTValue); //T행렬 값 대입 matWldTrans._41 = vResultVector.x; matWldTrans._42 = vResultVector.y; matWldTrans._43 = vResultVector.z; } //Rotation if (m_vGeomObj[0].get()->m_vRotTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; D3DXQUATERNION qR; //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_ROT); //사원수간의 보간.. if (pStartTrack == NULL) { qR = m_vGeomObj[0].get()->m_qRotation; float fTValue = (m_fTickFrame - 0) / (pEndTrack->iTick - 0); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } else if (pEndTrack == NULL) { qR = m_vGeomObj[0].get()->m_vRotTrack[m_vGeomObj[0].get()->m_vRotTrack.size() - 1].get()->qRotate; float fTValue = ((m_fTickFrame - pStartTrack->iTick) / (m_fFrameSpeed*m_fTickPerFrame)); D3DXQuaternionSlerp(&qR, &qR, &qR, fTValue); } else { qR = pStartTrack->qRotate; float fTValue = (m_fTickFrame - pStartTrack->iTick) / (pEndTrack->iTick - pStartTrack->iTick); D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, fTValue); } //사원수에서 행렬로 변환. D3DXMatrixRotationQuaternion(&matWldRotate, &qR);// 사원수에서 행렬로 변환 } //Scale if (m_vGeomObj[0].get()->m_vSclTrack.size() != 0) { GAnimTrack* pStartTrack = NULL; GAnimTrack* pEndTrack = NULL; D3DXMATRIX matScaleRot, matInvScaleRot; D3DXMatrixIdentity(&matScaleRot); D3DXMatrixIdentity(&matInvScaleRot); D3DXQUATERNION qS; float fStartTick = 0.0f, fEndTick = 0.0f; D3DXVECTOR3 vScale(m_vGeomObj[0].get()->m_matWldScale._11, m_vGeomObj[0].get()->m_matWldScale._22, m_vGeomObj[0].get()->m_matWldScale._33); //현재 Tick이 어디인지 찾자. GetAnimationTrack(m_fTickFrame, &pStartTrack, &pEndTrack, ANITRACK_TYPE_SCL); //신축트랙 보간 if (pStartTrack == NULL) { //vScale = m_vGeomObj[0].get()->m_vecTM_SCALE; D3DXQuaternionRotationAxis(&qS, &m_vGeomObj[0].get()->m_vecTM_SCALE_AXIS, m_vGeomObj[0].get()->m_fTM_SCALEAXISANG); fStartTick = 0.0f; fEndTick = pEndTrack->iTick; } else if (pEndTrack == NULL) { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pStartTrack->iTick + (m_fFrameSpeed*m_fTickPerFrame); } else { vScale = pStartTrack->vecVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; fEndTick = pEndTrack->iTick; } float fTValue = (m_fTickFrame - fStartTick) / (fEndTick - fStartTick); D3DXVec3Lerp(&vScale, &vScale, &pEndTrack->vecVector, fTValue); D3DXQuaternionSlerp(&qS, &qS, &pEndTrack->qRotate, fTValue); //사원수 -> 행렬로 변환등... D3DXMatrixScaling(&matWldScale, vScale.x, vScale.y, vScale.z); D3DXMatrixRotationQuaternion(&matScaleRot, &qS); D3DXMatrixInverse(&matInvScaleRot, NULL, &matScaleRot); matWldScale = matInvScaleRot * matWldScale * matScaleRot; } m_vGeomObj[0].get()->m_matCalculation = matWldScale * matWldRotate * matWldTrans; } }
void _X3PCamera::Advance( void ) { BOOL changedcamerastatus = FALSE; FLOAT abscamvel_x = fabs(m_CameraVelocity.x); FLOAT abscamvel_y = fabs(m_CameraVelocity.y); FLOAT abscamvel_z = fabs(m_CameraVelocity.z); FLOAT abscamvel_dist = fabs(m_ZoominoutVelocity); if( abscamvel_x > EPSILON3 || abscamvel_y > EPSILON3 || abscamvel_z > EPSILON3 || abscamvel_dist > EPSILON3 ) { if( abscamvel_x > EPSILON3 ) { m_CameraVelocity.x *= _XDEF_CAMERADECREASERATE; // add yaw mp_fYaw += m_CameraVelocity.x; if( mp_fYaw > 360.0f ) mp_fYaw = (FLOAT)fmod(mp_fYaw, 360.0); } if( abscamvel_y > EPSILON3 ) { m_CameraVelocity.y *= _XDEF_CAMERADECREASERATE; //add pitch mp_fPitch += m_CameraVelocity.y; if(mp_fPitch < mp_fMinPitchLimit) mp_fPitch = mp_fMinPitchLimit; else if(mp_fPitch > mp_fMaxPitchLimit) mp_fPitch = mp_fMaxPitchLimit; } if( abscamvel_z > EPSILON3 ) { m_CameraVelocity.z *= _XDEF_CAMERADECREASERATE; //add roll mp_fRoll += m_CameraVelocity.z; if(mp_fRoll < mp_fMinRollLimit) mp_fRoll = mp_fMinRollLimit; else if(mp_fRoll > mp_fMaxRollLimit) mp_fRoll = mp_fMaxRollLimit; } if( abscamvel_dist > EPSILON3 ) { #ifdef _XDWDEBUG extern BOOL g_MouseLockFlag; if( !g_MouseLockFlag ) { #endif if( m_MinDistance + m_AdditionalHeightMinDistance < m_TargetDistance ) { m_ZoominoutVelocity *= _XDEF_CAMERAZOOMDECREASERATE; } else { m_ZoominoutVelocity *= 0.3f; } m_TargetDistance += m_ZoominoutVelocity; if( m_MinDistance > m_TargetDistance ) { m_TargetDistance = m_MinDistance; } else if( m_MaxDistance < m_TargetDistance ) { m_TargetDistance = m_MaxDistance; } #ifdef _XDWDEBUG } #endif } changedcamerastatus = TRUE; } if( m_QuaterViewChanging ) { D3DXQUATERNION nextrotquat; D3DXQUATERNION orgrotquat; D3DXQUATERNION targetrotquat; D3DXQuaternionRotationYawPitchRoll( &orgrotquat, _X_RAD(mp_fYaw), _X_RAD(mp_fPitch), _X_RAD(mp_fRoll) ); if( m_DefaultViewChanging ) { D3DXQuaternionRotationYawPitchRoll( &targetrotquat, _X_RAD(-45.0f), _X_RAD(30.0f), 0.0f ); } else { D3DXQuaternionRotationYawPitchRoll( &targetrotquat, _X_RAD(180.0f), _X_RAD(30.0f), 0.0f ); } FLOAT fElapsedTime = g_fElapsedFrameMilisecondTime*3.0f; if( fElapsedTime > 1.0f ) fElapsedTime = 1.0f; D3DXQuaternionSlerp( &nextrotquat, &orgrotquat, &targetrotquat, fElapsedTime ); FLOAT fyaw, fpitch, froll; _XMeshMath_QuaternionToEulerAngle( nextrotquat, fyaw, fpitch, froll ); fyaw = _X_DEG(fyaw); if( fyaw > 360.0f ) fyaw = (FLOAT)fmod(fyaw, 360.0); fpitch = _X_DEG(fpitch); if(fpitch < mp_fMinPitchLimit) fpitch = mp_fMinPitchLimit; else if(fpitch > mp_fMaxPitchLimit) fpitch = mp_fMaxPitchLimit; froll = _X_DEG(froll); if(froll < mp_fMinRollLimit) froll = mp_fMinRollLimit; else if(froll > mp_fMaxRollLimit) froll = mp_fMaxRollLimit; if( fabs( mp_fYaw - fyaw ) > EPSILON1 || fabs( mp_fPitch - fpitch ) > EPSILON1 || fabs( mp_fRoll - froll ) > EPSILON1 ) { mp_fYaw = fyaw; mp_fPitch = fpitch; mp_fRoll = froll; changedcamerastatus = TRUE; } else { m_QuaterViewChanging = FALSE; m_QuaterViewMode = TRUE; m_DefaultViewChanging = FALSE; } _XWindow_WorldMinimap* pminimapwindow = (_XWindow_WorldMinimap*)g_MainWindowManager.FindWindow( _XDEF_WTITLE_MINIMAPWINDOW ); if( pminimapwindow ) { // Set direction to minimap arrow pminimapwindow->SetRotateFrustum( _X_RAD( 180 - mp_fYaw ) ); } } else if( m_DefaultViewChanging ) { D3DXQUATERNION nextrotquat; D3DXQUATERNION orgrotquat; D3DXQUATERNION targetrotquat; D3DXQuaternionRotationYawPitchRoll( &orgrotquat, _X_RAD(mp_fYaw), _X_RAD(mp_fPitch), _X_RAD(mp_fRoll) ); D3DXQuaternionRotationYawPitchRoll( &targetrotquat, _X_RAD(180.0f), _X_RAD(mp_fPitch), 0.0f ); FLOAT fElapsedTime = g_fElapsedFrameMilisecondTime*3.0f; if( fElapsedTime > 1.0f ) fElapsedTime = 1.0f; D3DXQuaternionSlerp( &nextrotquat, &orgrotquat, &targetrotquat, fElapsedTime ); FLOAT fyaw, fpitch, froll; _XMeshMath_QuaternionToEulerAngle( nextrotquat, fyaw, fpitch, froll ); fyaw = _X_DEG(fyaw); if( fyaw > 360.0f ) fyaw = (FLOAT)fmod(fyaw, 360.0); fpitch = _X_DEG(fpitch); if(fpitch < mp_fMinPitchLimit) fpitch = mp_fMinPitchLimit; else if(fpitch > mp_fMaxPitchLimit) fpitch = mp_fMaxPitchLimit; froll = _X_DEG(froll); if(froll < mp_fMinRollLimit) froll = mp_fMinRollLimit; else if(froll > mp_fMaxRollLimit) froll = mp_fMaxRollLimit; if( fabs( mp_fYaw - fyaw ) > EPSILON1 || fabs( mp_fPitch - fpitch ) > EPSILON1 || fabs( mp_fRoll - froll ) > EPSILON1 ) { mp_fYaw = fyaw; mp_fPitch = fpitch; mp_fRoll = froll; changedcamerastatus = TRUE; } else { m_DefaultViewChanging = FALSE; } _XWindow_WorldMinimap* pminimapwindow = (_XWindow_WorldMinimap*)g_MainWindowManager.FindWindow( _XDEF_WTITLE_MINIMAPWINDOW ); if( pminimapwindow ) { // Set direction to minimap arrow pminimapwindow->SetRotateFrustum( _X_RAD( 180 - mp_fYaw ) ); } } else { if( !gpInput->GetMouseState()->bButton[1] && ( g_pLocalUser->GetMotionClass() == _XACTION_MOVE && ( g_pLocalUser->m_PathNodeCount >= 1 || g_pLocalUser->m_LeftFinalTargetLength > 64.0f ) ) && (fabs( g_pLocalUser->m_RotateAngle - g_pLocalUser->m_LastRotateAngle ) < EPSILON3) && m_AutoBackTrace ) { D3DXQUATERNION nextrotquat; D3DXQUATERNION orgrotquat; D3DXQUATERNION targetrotquat; D3DXMATRIX mtxRotate = g_pLocalUser->m_ModelDescriptor.m_Position; mtxRotate._41 = mtxRotate._42 = mtxRotate._43 = 0.0f; D3DXQuaternionRotationYawPitchRoll( &orgrotquat, 0.0f, _X_RAD(mp_fPitch), 0.0f ); D3DXQuaternionRotationMatrix( &targetrotquat, &mtxRotate ); D3DXQuaternionMultiply( &targetrotquat, &orgrotquat, &targetrotquat ); D3DXQuaternionRotationYawPitchRoll( &orgrotquat, _X_RAD(mp_fYaw), _X_RAD(mp_fPitch), _X_RAD(mp_fRoll) ); FLOAT fElapsedTime = g_fElapsedFrameMilisecondTime; if( fElapsedTime > 1.0f ) fElapsedTime = 1.0f; D3DXQuaternionSlerp( &nextrotquat, &orgrotquat, &targetrotquat, fElapsedTime ); FLOAT fyaw, fpitch, froll; _XMeshMath_QuaternionToEulerAngle( nextrotquat, fyaw, fpitch, froll ); fyaw = _X_DEG(fyaw); if( fyaw > 360.0f ) fyaw = (FLOAT)fmod(fyaw, 360.0); fpitch = _X_DEG(fpitch); if(fpitch < mp_fMinPitchLimit) fpitch = mp_fMinPitchLimit; else if(fpitch > mp_fMaxPitchLimit) fpitch = mp_fMaxPitchLimit; froll = _X_DEG(froll); if(froll < mp_fMinRollLimit) froll = mp_fMinRollLimit; else if(froll > mp_fMaxRollLimit) froll = mp_fMaxRollLimit; if( fabs( mp_fYaw - fyaw ) > EPSILON3 || fabs( mp_fPitch - fpitch ) > EPSILON3 || fabs( mp_fRoll - froll ) > EPSILON3 ) { mp_fYaw = fyaw; mp_fPitch = fpitch; mp_fRoll = froll; changedcamerastatus = TRUE; } } } if( m_CameraShakeMode ) { if( !m_CameraShakeDelayMode ) { const FLOAT shakeadditionalfactor = 10.0f; FLOAT fshakefactor = _XLinearGraph( 0.1f,0.05f, 0.5f,0.0f ).GetValueAt( g_fElapsedFrameMilisecondTime ); m_CameraShakeFactor.x = fshakefactor * sinf(rand()); m_CameraShakeFactor.y = fshakefactor * sinf(rand()); m_CameraShakeFactor.z = fshakefactor * sinf(rand()); D3DXMATRIX matOrientation; D3DXMatrixInverse( &matOrientation, NULL, &mp_view_matrix ); D3DXVec3TransformNormal( &m_CameraShakeFactor, &m_CameraShakeFactor, &matOrientation ); changedcamerastatus = TRUE; m_fCameraShakeTimer -= g_fElapsedFrameMilisecondTime; if( m_fCameraShakeTimer < 0.0f ) { m_CameraShakeMode = FALSE; m_CameraShakeFactor = D3DXVECTOR3( 0.0f,0.0f,0.0f ); } } else { if( g_LocalSystemTime - m_fCameraShakeStartTimer < m_fCameraShakeTimer*1000 ) { int temp = (int)(((g_LocalSystemTime - m_fCameraShakeStartTimer)/1000.0f)/5.0f)%2; if( temp == 0 ) { if( !m_ChangeCameraShakeAtDelayMode ) { _XPlaySoundEffect(ID_SR_INTERFACE_EARTHQUAKE_WAV, g_pLocalUser->m_Position ); } const FLOAT shakeadditionalfactor = 10.0f; FLOAT fshakefactor = _XLinearGraph( 0.05f,0.025f, 0.25f,0.0f ).GetValueAt( g_fElapsedFrameMilisecondTime ); m_CameraShakeFactor.x = fshakefactor * sinf(rand()); m_CameraShakeFactor.y = fshakefactor * sinf(rand()); m_CameraShakeFactor.z = fshakefactor * sinf(rand()); D3DXMATRIX matOrientation; D3DXMatrixInverse( &matOrientation, NULL, &mp_view_matrix ); D3DXVec3TransformNormal( &m_CameraShakeFactor, &m_CameraShakeFactor, &matOrientation ); changedcamerastatus = TRUE; m_ChangeCameraShakeAtDelayMode = TRUE; } else { if( m_ChangeCameraShakeAtDelayMode ) { _XPlaySoundEffect(ID_SR_INTERFACE_EARTHQUAKE01_WAV, g_pLocalUser->m_Position ); } m_ChangeCameraShakeAtDelayMode = FALSE; } } else { m_CameraShakeMode = FALSE; m_CameraShakeFactor = D3DXVECTOR3( 0.0f,0.0f,0.0f ); } } } if( changedcamerastatus ) { UpdateViewMatrix( &g_LodTerrain, TRUE ); g_LodTerrain.m_ObjectQuadTree.UpdateCamera(g_LodTerrain.m_3PCamera); g_LodTerrain.RebuildLevel(); } }
inline void __Quaternion::Slerp(const D3DXQUATERNION& qt1, const D3DXQUATERNION& qt2, float fDelta) { D3DXQuaternionSlerp(this, &qt1, &qt2, fDelta); }
void Quaternion::Slerp(const Quaternion& begin, const Quaternion& end, float coeff) { D3DXQuaternionSlerp(this, &begin, &end, coeff); }
D3DXMATRIX GAnimation::Interpolate(GMesh* pMesh, D3DXMATRIX* matParents, float fFrameTick, TScene tScene) { // TM = AnimMat * ParentTM; // AaniMat = TM * Inverse(ParentTM) D3DXQUATERNION qR, qS; D3DXMATRIX matAnim, matPos, matRotate, matScale, matCalculation; D3DXMatrixIdentity(&matCalculation); matRotate = pMesh->m_matWorldRotate; matPos = pMesh->m_matWorldTrans; matScale = pMesh->m_matWorldScale; D3DXQuaternionRotationMatrix(&qR, &matRotate); D3DXQuaternionRotationMatrix(&qS, &matScale); // fFrameTick = m_Scene.iFirstFrame * m_Scene.iTickPerFrame + CurFame; float fStartTick = tScene.iFirstFrame * tScene.iTickPerFrame; float fEndTick = 0.0f; TAnimTrack* pStartTrack = NULL; TAnimTrack* pEndTrack = NULL; if (pMesh->m_pRotTrack.size()) { // pStartTrack를 찾을수 있으면 if (GetAnimationTrack(fFrameTick, pMesh->m_pRotTrack, &pStartTrack, &pEndTrack)) { qR = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; } if (pEndTrack) { fEndTick = pEndTrack->iTick; D3DXQuaternionSlerp(&qR, &qR, &pEndTrack->qRotate, (fFrameTick - fStartTick) / (fEndTick - fStartTick)); } D3DXMatrixRotationQuaternion(&matRotate, &qR); } pStartTrack = NULL; pEndTrack = NULL; D3DXVECTOR3 Trans(matPos._41, matPos._42, matPos._43); if (pMesh->m_pPosTrack.size()) { // pStartTrack를 찾을수 있으면 if (GetAnimationTrack(fFrameTick, pMesh->m_pPosTrack, &pStartTrack, &pEndTrack)) { Trans = pStartTrack->vVector; fStartTick = pStartTrack->iTick; } if (pEndTrack) { fEndTick = pEndTrack->iTick; D3DXVec3Lerp(&Trans, &Trans, &pEndTrack->vVector, (fFrameTick - fStartTick) / (fEndTick - fStartTick)); } D3DXMatrixTranslation(&matPos, Trans.x, Trans.y, Trans.z); } pStartTrack = NULL; pEndTrack = NULL; D3DXMATRIX matScaleRot, matInvScaleRot; D3DXVECTOR3 vScale(matScale._11, matScale._22, matScale._33); if (pMesh->m_pSclTrack.size()) { // pStartTrack를 찾을수 있으면 if (GetAnimationTrack(fFrameTick, pMesh->m_pSclTrack, &pStartTrack, &pEndTrack)) { vScale = pStartTrack->vVector; qS = pStartTrack->qRotate; fStartTick = pStartTrack->iTick; } if (pEndTrack) { fEndTick = pEndTrack->iTick; D3DXVec3Lerp(&vScale, &vScale, &pEndTrack->vVector, (fFrameTick - fStartTick) / (fEndTick - fStartTick)); D3DXQuaternionSlerp(&qS, &qS, &pEndTrack->qRotate, (fFrameTick - fStartTick) / (fEndTick - fStartTick)); } D3DXMatrixScaling(&matScale, vScale.x, vScale.y, vScale.z); D3DXMatrixRotationQuaternion(&matScaleRot, &qS); D3DXMatrixInverse(&matInvScaleRot, NULL, &matScaleRot); matScale = matInvScaleRot * matScale * matScaleRot; } pStartTrack = NULL; pEndTrack = NULL; float fCurAlpha, fNextAlpha, fOffSet; fCurAlpha = 0.0f; fNextAlpha = 0.0f; if (pMesh->m_pVisTrack.size()) { // pStartTrack를 찾을수 있으면 if (GetAnimationTrack(fFrameTick, pMesh->m_pVisTrack, &pStartTrack, &pEndTrack)) { fCurAlpha = pStartTrack->vVector.x; fStartTick = pStartTrack->iTick; } if (pEndTrack) { fNextAlpha = pEndTrack->vVector.x; fEndTick = pEndTrack->iTick; fOffSet = (fFrameTick - fStartTick) / (fEndTick - fStartTick); fNextAlpha = (fNextAlpha - fCurAlpha)*fOffSet; } pMesh->m_fVisibility = (fCurAlpha + fNextAlpha); } else { pMesh->m_fVisibility = 1.0f; } D3DXMatrixMultiply(&matAnim, &matScale, &matRotate); matAnim._41 = matPos._41; matAnim._42 = matPos._42; matAnim._43 = matPos._43; // 최종 에미메이션 행렬을 완성한다. D3DXMatrixMultiply(&matCalculation, &matAnim, matParents); // 인버스 매트릭스 확인 코드. D3DXVECTOR3 v0, v1, v2, v3; v0 = pMesh->m_matCalculation.m[0]; v1 = pMesh->m_matCalculation.m[1]; v2 = pMesh->m_matCalculation.m[2]; D3DXVec3Cross(&v3, &v1, &v2); if (D3DXVec3Dot(&v3, &v0) < 0.0f) { D3DXMATRIX matW; D3DXMatrixScaling(&matW, -1.0f, -1.0f, -1.0f); D3DXMatrixMultiply(&matCalculation, &pMesh->m_matCalculation, &matW); } return matCalculation; }