예제 #1
0
파일: ms3d.cpp 프로젝트: jinshizi/rushcodes
//-------------------------------------------------------------
//- Animate
//- Animates the model from start time to end time (in seconds)
//- at specified speed and can loop
//-------------------------------------------------------------
void CMs3d::Animate(float fSpeed, float fStartTime, float fEndTime, bool bLoop)
{
	static bool bFirstTime = true;
	//First time animate has been called
	if(bFirstTime)
	{
		Reset();
		bFirstTime = false;
	}

	static float fLastTime = fStartTime;

	float fTime = m_Timer.GetSeconds() * fSpeed;
	fTime += fLastTime;
	fLastTime = fTime;
	
	//looping
	if(fTime > fEndTime)
	{
		if(bLoop)
		{
			Reset();
			fLastTime = fStartTime;
			fTime = fStartTime;
		}
		else
			fTime = fEndTime;
	}	

	for(int x = 0; x < m_usNumJoints; x++)
	{
		//Transformation matrix
		CMatrix4X4 matTmp;
		//Current joint
		SMs3dJoint * pJoint = &m_pJoints[x];
		//Current frame
		unsigned int uiFrame = 0;

		//if there are no keyframes, don't do any transformations
		if(pJoint->m_usNumRotFrames == 0 && pJoint->m_TransKeyFrames == 0)
		{
			pJoint->m_matFinal = pJoint->m_matAbs;
			continue;
		}
		//Calculate the current frame
		//Translation
		while(uiFrame < pJoint->m_usNumTransFrames && pJoint->m_TransKeyFrames[uiFrame].m_fTime < fTime)
			uiFrame++;
		pJoint->m_usCurTransFrame = uiFrame;

		float fTranslation[3];
		float fDeltaT = 1;
		float fInterp = 0;

		//If its at the extremes
		if(uiFrame == 0)
			memcpy(fTranslation, pJoint->m_TransKeyFrames[0].m_fParam, sizeof(float[3]));
		else if(uiFrame == pJoint->m_usNumTransFrames)
			memcpy(fTranslation, pJoint->m_TransKeyFrames[uiFrame-1].m_fParam, sizeof(float[3]));
		//If its in the middle of two frames
		else
		{
			SMs3dKeyFrame * pkCur = &pJoint->m_TransKeyFrames[uiFrame];
			SMs3dKeyFrame * pkPrev = &pJoint->m_TransKeyFrames[uiFrame-1];
			
			fDeltaT = pkCur->m_fTime - pkPrev->m_fTime;
			fInterp = (fTime - pkPrev->m_fTime) / fDeltaT;
			
			//Interpolate between the translations
			fTranslation[0] = pkPrev->m_fParam[0] + (pkCur->m_fParam[0] - pkPrev->m_fParam[0]) * fInterp;
			fTranslation[1] = pkPrev->m_fParam[1] + (pkCur->m_fParam[1] - pkPrev->m_fParam[1]) * fInterp;
			fTranslation[2] = pkPrev->m_fParam[2] + (pkCur->m_fParam[2] - pkPrev->m_fParam[2]) * fInterp;
		}
		//Calculate the current rotation
		uiFrame = 0;
		while(uiFrame < pJoint->m_usNumRotFrames && pJoint->m_RotKeyFrames[uiFrame].m_fTime < fTime)
			uiFrame++;


		//If its at the extremes
		if(uiFrame == 0)
			matTmp.SetRotation(pJoint->m_RotKeyFrames[0].m_fParam);
		else if(uiFrame == pJoint->m_usNumTransFrames)
			matTmp.SetRotation(pJoint->m_RotKeyFrames[uiFrame-1].m_fParam);
		//If its in the middle of two frames, use a quaternion SLERP operation to calculate a new position
		else
		{
			SMs3dKeyFrame * pkCur = &pJoint->m_RotKeyFrames[uiFrame];
			SMs3dKeyFrame * pkPrev = &pJoint->m_RotKeyFrames[uiFrame-1];

			fDeltaT = pkCur->m_fTime - pkPrev->m_fTime;
			fInterp = (fTime - pkPrev->m_fTime) / fDeltaT;
			
			//Create a rotation quaternion for each frame
			CQuaternion qCur;
			CQuaternion qPrev;
			qCur.FromEulers(pkCur->m_fParam);
			qPrev.FromEulers(pkPrev->m_fParam);
			//SLERP between the two frames
			CQuaternion qFinal = SLERP(qPrev, qCur, fInterp);

			//Convert the quaternion to a rotation matrix
			matTmp = qFinal.ToMatrix4();
		}

		//Set the translation part of the matrix
		matTmp.SetTranslation(fTranslation);

		//Calculate the joints final transformation
		CMatrix4X4 matFinal = pJoint->m_matLocal * matTmp;

		//if there is no parent, just use the matrix you just made
		if(pJoint->m_sParent == -1)
			pJoint->m_matFinal = matFinal;
		//otherwise the final matrix is the parents final matrix * the new matrix
		else
			pJoint->m_matFinal = m_pJoints[pJoint->m_sParent].m_matFinal * matFinal;
	}


	//Transform and render the meshes
	if(m_bDrawMesh)
		RenderT();

	if(m_bDrawBones)
	{
		glDisable(GL_DEPTH_TEST);
		glDisable(GL_LIGHTING);
		glLineWidth(5);
		//Draw the bones
		glColor3f(0.0f, 1.0f, 0.0f);
		glBegin(GL_LINES);	
		for(int x = 1; x < m_usNumJoints; x++)
		{
			float * fMat = m_pJoints[x].m_matFinal.Get();
			float * fMatParent = m_pJoints[m_pJoints[x].m_sParent].m_matFinal.Get();
			glVertex3f(fMat[12], fMat[13], fMat[14]);
			glVertex3f(fMatParent[12], fMatParent[13], fMatParent[14]);
		}
		glEnd();

		glEnable(GL_DEPTH_TEST);
	}
}
예제 #2
0
void Model::updateJoints(float fTime)
{


    //std::cout << "Current Time: " << fTime << std::endl;
    // update matrix
    for(int i = 0; i < COUNT_MODEL_SIMULATE; i++)
    {
        // update matrix
        for(int x = 0; x < m_usNumJoints; x++)
        {
            //Transformation matrix
            vgMs3d::CMatrix4X4 matTmp;
            //Current joint
            MS3DJoint * pJoint = &m_pJoints[x];
            //Current frame]
            unsigned int uiFrame = 0;

            //if there are no keyframes, don't do any transformations
            if(pJoint->m_usNumRotFrames == 0 && pJoint->m_TransKeyFrames == 0)
            {
                pJoint->m_matFinal = pJoint->m_matAbs;
                continue;
            }
            //Calculate the current frame
            //Translation
            while(uiFrame < pJoint->m_usNumTransFrames && pJoint->m_TransKeyFrames[uiFrame].m_fTime < fTime)
                uiFrame++;

            float fTranslation[3];
            float fDeltaT = 1;
            float fInterp = 0;

            //If its at the extremes
            if(uiFrame == 0)
                memcpy(fTranslation, pJoint->m_TransKeyFrames[0].m_fParam, sizeof(float[3]));
            else if(uiFrame == pJoint->m_usNumTransFrames)
                memcpy(fTranslation, pJoint->m_TransKeyFrames[uiFrame-1].m_fParam, sizeof(float[3]));
            //If its in the middle of two frames
            else
            {
                MS3DKeyframe * pkCur = &pJoint->m_TransKeyFrames[uiFrame];
                MS3DKeyframe * pkPrev = &pJoint->m_TransKeyFrames[uiFrame-1];

                fDeltaT = pkCur->m_fTime - pkPrev->m_fTime;
                fInterp = (fTime - pkPrev->m_fTime) / fDeltaT;

                //Interpolate between the translations
                fTranslation[0] = pkPrev->m_fParam[0] + (pkCur->m_fParam[0] - pkPrev->m_fParam[0]) * fInterp;
                fTranslation[1] = pkPrev->m_fParam[1] + (pkCur->m_fParam[1] - pkPrev->m_fParam[1]) * fInterp;
                fTranslation[2] = pkPrev->m_fParam[2] + (pkCur->m_fParam[2] - pkPrev->m_fParam[2]) * fInterp;
            }
            //Calculate the current rotation
            uiFrame = 0;
            while(uiFrame < pJoint->m_usNumRotFrames && pJoint->m_RotKeyFrames[uiFrame].m_fTime < fTime)
                uiFrame++;


            //If its at the extremes
            if(uiFrame == 0)
                matTmp.SetRotation(pJoint->m_RotKeyFrames[0].m_fParam);
            else if(uiFrame == pJoint->m_usNumTransFrames)
                matTmp.SetRotation(pJoint->m_RotKeyFrames[uiFrame-1].m_fParam);
            //If its in the middle of two frames, use a quaternion SLERP operation to calculate a new position
            else
            {
                MS3DKeyframe * pkCur = &pJoint->m_RotKeyFrames[uiFrame];
                MS3DKeyframe * pkPrev = &pJoint->m_RotKeyFrames[uiFrame-1];

                fDeltaT = pkCur->m_fTime - pkPrev->m_fTime;
                fInterp = (fTime - pkPrev->m_fTime) / fDeltaT;

                //Create a rotation quaternion for each frame
                vgMs3d::CQuaternion qCur;
                vgMs3d::CQuaternion qPrev;
                qCur.FromEulers(pkCur->m_fParam);
                qPrev.FromEulers(pkPrev->m_fParam);
                //SLERP between the two frames
                vgMs3d::CQuaternion qFinal = SLERP(qPrev, qCur, fInterp);

                //Convert the quaternion to a rota tion matrix
                matTmp = qFinal.ToMatrix4();
            }

            //Set the translation part of the matrix
            matTmp.SetTranslation(fTranslation);

            //Calculate the joints final transformation
            vgMs3d::CMatrix4X4 matFinal = pJoint->m_matLocal * matTmp;

            //if there is no parent, just use the matrix you just made
            if(pJoint->m_sParent == -1)
                pJoint->m_matFinal = matFinal;
            //otherwise the final matrix is the parents final matrix * the new matrix
            else
                pJoint->m_matFinal = m_pJoints[pJoint->m_sParent].m_matFinal * matFinal;
        }//x

        for (int i=0; i<m_usNumJoints; i++)
        {
            memcpy(m_pJointsMatrix+16*i, m_pJoints[i].m_matFinal.Get(), sizeof(float)*16 );
        }
    }//i

}
예제 #3
0
/***********************
* DlgProc: Process the Dialog Box commands
* @author: Callan Moore
* @Parameter: _hWnd: Handle to the Dialog Box
* @Parameter: _uiMsg: The message ID being sent
* @Parameter: _wParam: Additional detail about the message being sent
* @Parameter: _lParam: Additional detail about the message being sent
* @return: BOOL: Boolean Result
********************/
BOOL CALLBACK DlgProc(HWND _hDlg, UINT _msg, WPARAM _wparam, LPARAM _lparam)
{
	static HWND hEditBox = 0;
	switch(_msg)
	{
	case(WM_INITDIALOG):
		{
			InitialSetup( _hDlg);
			return (0);
		}
	break;
	case(WM_COMMAND):
		{
			switch(LOWORD( _wparam))
			{
			case (IDC_QUAT_SLERP):			// SLERP Button for calculating the SLERP
			{
				SLERP(_hDlg);
			}
			break;
			case (IDC_CONVERT_A):			// Convert Quaternion A to a Matrix
			{
				ConvertToMatrix(_hDlg, 'a');
			}
			break;
			case (IDC_CONVERT_B):			// Convert Quaternion B to a Matrix
			{
				ConvertToMatrix(_hDlg, 'b');
			}
			break;
			case (IDC_CONVERT_SLERP):		// Convert the Quaternion calculatedvia SLERP to a Matrix
			{
				ConvertToMatrix(_hDlg, 's');
			}
			break;
			case (IDC_RESET):				// Reset Button to reset the calculator back to default starting values
				{
					InitialSetup(_hDlg);
				}
				break;
			default: break;
			}	// End Switch
		}
		break;
	case(WM_CLOSE):
		{
			switch( MessageBox( _hDlg, L"Are you sure you would like to close the calculator?", L"Exit", MB_ICONQUESTION | MB_YESNO))
			{
			case (IDYES):
				{
					// Quit out of the whole application if dialog box is closed
					PostQuitMessage(0);
					return true; 
				}
			break;
			case (IDNO): // Do Nothing -> Fall Through
			default: break;
			} // End Switch	
		}
	default:
		{
			break;
		}
	}	// End Switch
	return false;
}