Exemple #1
0
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();
}
Exemple #2
0
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 );
	
}
Exemple #3
0
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;
		}
	}
}
Exemple #4
0
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);
  }
}
Exemple #10
0
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;
}
Exemple #12
0
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;
			}
		}		
	}
}
Exemple #14
0
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;
}
Exemple #15
0
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;
}
Exemple #16
0
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);
	}
}
Exemple #17
0
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;
  }
}
Exemple #19
0
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);
			}
		}
	}
			//}
			
		//}

		//최종행렬.


	
}
Exemple #20
0
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;
	}
}
Exemple #21
0
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);
}
Exemple #24
0
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;
}