コード例 #1
0
ファイル: Euler.hpp プロジェクト: netzz/minemonics
	/// Clamp the roll angle to a range of +/-limit.
	inline Euler &limitRoll(const Radian &limit) {
		limitAngle(mRoll, limit);
		return *this;
	}
コード例 #2
0
ファイル: Euler.hpp プロジェクト: netzz/minemonics
	/// Clamp the yaw angle to a range of +/-limit.
	inline Euler &limitYaw(const Radian &limit) {
		limitAngle(mYaw, limit);
		return *this;
	}
コード例 #3
0
ファイル: Euler.hpp プロジェクト: netzz/minemonics
	/// Clamp the pitch angle to a range of +/-limit.
	inline Euler &limitPitch(const Radian &limit) {
		limitAngle(mPitch, limit);
		return *this;
	}
コード例 #4
0
ファイル: PMDIK.cpp プロジェクト: r1cebank/MMDRender
//======
// 更新
//======
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();
			}
		}
	}
}