Ejemplo n.º 1
0
// 追加
void cPMDModel::updateSkinning2( void )
{
    // スキニング用行列の更新
    for( unsigned short i = 0 ; i < m_unNumBones ; i++ )
    {
        m_pBoneArray[i].updateSkinningMat2();
    }

    // 頂点スキニング
    Matrix	matTemp;
    for( unsigned long i = 0 ; i < m_ulNumVertices ; i++ )
    {
        if( m_pOrgSkinInfoArray[i].fWeight == 0.0f )
        {
            Vector3Transform( &m_pvec3PositionArray[i], &m_pvec3OrgPositionArray[i], m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[1]].m_matSkinning );
            Vector3Rotate( &m_pvec3NormalArray[i], &m_pvec3OrgNormalArray[i], m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[1]].m_matSkinning );
        }
        else if( m_pOrgSkinInfoArray[i].fWeight >= 0.9999f )
        {
            Vector3Transform( &m_pvec3PositionArray[i], &m_pvec3OrgPositionArray[i], m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[0]].m_matSkinning );
            Vector3Rotate( &m_pvec3NormalArray[i], &m_pvec3OrgNormalArray[i], m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[0]].m_matSkinning );
        }
        else
        {
            MatrixLerp( matTemp,	m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[0]].m_matSkinning,
                        m_pBoneArray[m_pOrgSkinInfoArray[i].unBoneNo[1]].m_matSkinning,		m_pOrgSkinInfoArray[i].fWeight );

            Vector3Transform( &m_pvec3PositionArray[i], &m_pvec3OrgPositionArray[i], matTemp );
            Vector3Rotate( &m_pvec3NormalArray[i], &m_pvec3OrgNormalArray[i], matTemp );
        }
    }
}
Ejemplo n.º 2
0
//==========================
// ボーンを指定座標へ向ける
//==========================
void cPMDBone::lookAt( const Vector3 *pvecTargetPos, float fLimitXD, float fLimitXU, float fLimitY  )
{
	// どうもおかしいので要調整

	Matrix	matTemp;

	MatrixIdentity(	matTemp );
	matTemp[3][0] = m_vec3Position.x + m_vec3Offset.x; 
	matTemp[3][1] = m_vec3Position.y + m_vec3Offset.y; 
	matTemp[3][2] = m_vec3Position.z + m_vec3Offset.z;

	if( m_pParentBone )
	{
		Matrix	matInvTemp;
		MatrixInverse( matInvTemp, m_pParentBone->m_matLocal );
		matInvTemp[3][0] =  m_pParentBone->m_matLocal[3][0]; 
		matInvTemp[3][1] =  m_pParentBone->m_matLocal[3][1]; 
		matInvTemp[3][2] = -m_pParentBone->m_matLocal[3][2];
		MatrixMultiply( matTemp, matTemp, matInvTemp );
	}
	MatrixInverse( matTemp, matTemp );

	Vector3		vec3LocalTgtPosZY;
	Vector3		vec3LocalTgtPosXZ;

	Vector3Transform( &vec3LocalTgtPosZY, pvecTargetPos, matTemp );

	vec3LocalTgtPosXZ = vec3LocalTgtPosZY;
	vec3LocalTgtPosXZ.y = 0.0f;
	Vector3Normalize( &vec3LocalTgtPosXZ, &vec3LocalTgtPosXZ );

	vec3LocalTgtPosZY.x = 0.0f;
	Vector3Normalize( &vec3LocalTgtPosZY, &vec3LocalTgtPosZY );

	Vector3		vec3Angle = { 0.0f, 0.0f, 0.0f };

	vec3Angle.x =  asinf( vec3LocalTgtPosZY.y );
	if( vec3LocalTgtPosXZ.x < 0.0f )	vec3Angle.y =  acosf( vec3LocalTgtPosXZ.z );
	else								vec3Angle.y = -acosf( vec3LocalTgtPosXZ.z );

	if( vec3Angle.x < RAD(fLimitXD) )	vec3Angle.x = RAD(fLimitXD);
	if( RAD(fLimitXU) < vec3Angle.x )	vec3Angle.x = RAD(fLimitXU);

	if( vec3Angle.y < RAD(-fLimitY) )	vec3Angle.y = RAD(-fLimitY);
	if( RAD(fLimitY) < vec3Angle.y  )	vec3Angle.y = RAD( fLimitY);

	Vector4		vec4RotTemp;

	QuaternionCreateEuler( &vec4RotTemp, &vec3Angle );
	QuaternionSlerp( &m_vec4LookRotation, &m_vec4LookRotation, &vec4RotTemp, 0.5f );	// 0.3f );	// 視線の動きを高速化

	m_vec4Rotation = m_vec4LookRotation;
}
Ejemplo n.º 3
0
//====================
// カメラの位置の取得
//====================
void cARTK::getCameraPos( Vector3 *pvec3CamPos )
{
	double		dInvPattTransMat[3][4];

	arUtilMatInv( m_dPattTransMat, dInvPattTransMat );

	pvec3CamPos->x = (float)dInvPattTransMat[0][3];
	pvec3CamPos->y = (float)dInvPattTransMat[1][3];
	pvec3CamPos->z = (float)dInvPattTransMat[2][3];
	Vector3Transform( pvec3CamPos, pvec3CamPos, m_matRotX );

	pvec3CamPos->x *= (float)m_dViewScaleFactor;
	pvec3CamPos->y *= (float)m_dViewScaleFactor;
	pvec3CamPos->z *= (float)m_dViewScaleFactor;
}
Ejemplo n.º 4
0
//==============================================
// Baseを原点とした場合のTargetの相対位置を取得
//==============================================
void cARTK::getMarkerPos( Vector3 *pvec3MarkerPos, int iPattIndexBase, int iPattIndexTarget )
{
	double		dInvBaseTransMat[3][4];
	double		dTargetTransMat[3][4];

	arUtilMatInv( m_sMarkerInfo[iPattIndexBase].dTransMat, dInvBaseTransMat );
	arUtilMatMul( dInvBaseTransMat, m_sMarkerInfo[iPattIndexTarget].dTransMat, dTargetTransMat );

	pvec3MarkerPos->x = (float)dTargetTransMat[0][3];
	pvec3MarkerPos->y = (float)dTargetTransMat[1][3];
	pvec3MarkerPos->z = (float)dTargetTransMat[2][3];
	Vector3Transform( pvec3MarkerPos, pvec3MarkerPos, m_matRotX );

	pvec3MarkerPos->x *= (float)m_dViewScaleFactor;
	pvec3MarkerPos->y *= (float)m_dViewScaleFactor;
	pvec3MarkerPos->z *= (float)m_dViewScaleFactor;
}
Ejemplo n.º 5
0
//======
// 更新
//======
void cPMDIK::update( void )
{
	Vector3	vec3OrgTargetPos;
	vec3OrgTargetPos.x = m_pTargetBone->m_matLocal[3][0];
	vec3OrgTargetPos.y = m_pTargetBone->m_matLocal[3][1];
	vec3OrgTargetPos.z = m_pTargetBone->m_matLocal[3][2];

	Vector3	vec3EffPos;
	Vector3	vec3TargetPos;

	for( short i = m_cbNumLink - 1 ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); }
	m_pEffBone->updateMatrix();

	for( unsigned short it = 0 ; it < m_unCount ; it++ )
	{
		for( unsigned char cbLinkIdx = 0 ; cbLinkIdx < m_cbNumLink ; cbLinkIdx++ )
		{
			// エフェクタの位置の取得
			vec3EffPos.x = m_pEffBone->m_matLocal[3][0];
			vec3EffPos.y = m_pEffBone->m_matLocal[3][1];
			vec3EffPos.z = m_pEffBone->m_matLocal[3][2];

			// ワールド座標系から注目ノードの局所(ローカル)座標系への変換
			Matrix	matInvBone;
			MatrixInverse( matInvBone, m_ppBoneList[cbLinkIdx]->m_matLocal );

			// エフェクタ,到達目標のローカル位置
			Vector3Transform( &vec3EffPos, &vec3EffPos, matInvBone );
			Vector3Transform( &vec3TargetPos, &vec3OrgTargetPos, matInvBone );

			// 十分近ければ終了
			Vector3	vec3Diff;
			Vector3Sub( &vec3Diff, &vec3EffPos, &vec3TargetPos );
			if( Vector3DotProduct( &vec3Diff, &vec3Diff ) < 0.0000001f )	return;

			// (1) 基準関節→エフェクタ位置への方向ベクトル
			Vector3Normalize( &vec3EffPos, &vec3EffPos );

			// (2) 基準関節→目標位置への方向ベクトル
			Vector3Normalize( &vec3TargetPos, &vec3TargetPos );

			// ベクトル (1) を (2) に一致させるための最短回転量(Axis-Angle)
			//
			// 回転角
			float	fRotAngle = acosf( Vector3DotProduct( &vec3EffPos, &vec3TargetPos ) );

			if( 0.00000001f < fabsf( fRotAngle ) )
			{
				if( fRotAngle < -m_fFact )	fRotAngle = -m_fFact;
				else if( m_fFact < fRotAngle )	fRotAngle = m_fFact;

				// 回転軸
				Vector3 vec3RotAxis;

				Vector3CrossProduct( &vec3RotAxis, &vec3EffPos, &vec3TargetPos );
				if( Vector3DotProduct( &vec3RotAxis, &vec3RotAxis ) < 0.0000001f )	continue;

				Vector3Normalize( &vec3RotAxis, &vec3RotAxis );

				// 関節回転量の補正
				Vector4		vec4RotQuat;
				QuaternionCreateAxis( &vec4RotQuat, &vec3RotAxis, fRotAngle );

				if( m_ppBoneList[cbLinkIdx]->m_bIKLimitAngle )	limitAngle( &vec4RotQuat, &vec4RotQuat );

				QuaternionNormalize( &vec4RotQuat, &vec4RotQuat );

				QuaternionMultiply( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &vec4RotQuat );
				QuaternionNormalize( &m_ppBoneList[cbLinkIdx]->m_vec4Rotation, &m_ppBoneList[cbLinkIdx]->m_vec4Rotation );

				for( short i = cbLinkIdx ; i >= 0 ; i-- ){ m_ppBoneList[i]->updateMatrix(); }
				m_pEffBone->updateMatrix();
			}
		}
	}
}