Exemple #1
0
/*-------------------------------------------------------------------
    Procedure   :       Create Quat from dir vector and up vector
    Input       :       VECTOR  *   Direction Vector
                :       VECTOR  *   Up Vector
                :       QUAT    *   Destin Quaternion
    Output      :       Nothing
-------------------------------------------------------------------*/
void QuatFromDirAndUp( VECTOR * Dir, VECTOR * Up, QUAT * Quat )
{
    MATRIX      TempMat;
    VECTOR      TempUp;
    QUAT        RotQuat;

    QuatFrom2Vectors( Quat, &Forward, Dir );
    QuatToMatrix( Quat, &TempMat );
    ApplyMatrix( &TempMat, &SlideUp, &TempUp );
    QuatFrom2Vectors( &RotQuat, &TempUp, Up );
    QuatMultiply( &RotQuat, Quat, Quat );
}
Vec3 TurretComponent::AbsoluteAnglesToRelativeAngles(const Vec3 absoluteAngles) const {
	quat_t torsoRotation;
	quat_t absoluteRotation;
	quat_t relativeRotation;
	vec3_t relativeAngles;

	AnglesToQuat(TorsoAngles().Data(), torsoRotation);
	AnglesToQuat(absoluteAngles.Data(), absoluteRotation);

	// This is the inverse of RelativeAnglesToAbsoluteAngles. See the comment there for details.
	quat_t inverseTorsoOrientation;
	QuatCopy(torsoRotation, inverseTorsoOrientation);
	QuatInverse(inverseTorsoOrientation);
	QuatMultiply(inverseTorsoOrientation, absoluteRotation, relativeRotation);

	QuatToAngles(relativeRotation, relativeAngles);

	/*turretLogger.Debug("AbsoluteAnglesToRelativeAngles: %s → %s. Torso angles: %s.",
		Utility::Print(absoluteAngles), Utility::Print(Vec3::Load(relativeAngles)), TorsoAngles()
	);*/

	return Vec3::Load(relativeAngles);
}
Vec3 TurretComponent::RelativeAnglesToAbsoluteAngles(const Vec3 relativeAngles) const {
	quat_t torsoRotation;
	quat_t relativeRotation;
	quat_t absoluteRotation;
	vec3_t absoluteAngles;

	AnglesToQuat(TorsoAngles().Data(), torsoRotation);
	AnglesToQuat(relativeAngles.Data(), relativeRotation);

	// Rotate by torso rotation in world space, then by relative orientation in torso space.
	// This is equivalent to rotating by relative orientation in world space, then by torso rotation
	// in world space. This then is equivalent to multiplying the torso rotation in world space on
	// the left hand side and the relative rotation in world space on the right hand side.
	QuatMultiply(torsoRotation, relativeRotation, absoluteRotation);

	QuatToAngles(absoluteRotation, absoluteAngles);

	/*turretLogger.Debug("RelativeAnglesToAbsoluteAngles: %s → %s. Torso angles: %s.",
		Utility::Print(relativeAngles), Utility::Print(Vec3::Load(absoluteAngles)), TorsoAngles()
	);*/

	return Vec3::Load(absoluteAngles);
}
bool AnimDelta::LoadData(clientInfo_t* ci)
{
	char newModelName[ MAX_QPATH ];
	// special handling for human_(naked|light|medium)
	if ( !Q_stricmp( ci->modelName, "human_naked"   ) ||
		!Q_stricmp( ci->modelName, "human_light"   ) ||
		!Q_stricmp( ci->modelName, "human_medium" ) )
	{
		Q_strncpyz( newModelName, "human_nobsuit_common", sizeof( newModelName ) );
	}
	else
	{
		Q_strncpyz( newModelName, ci->modelName, sizeof( newModelName ) );
	}

	refSkeleton_t base;
	refSkeleton_t delta;
	for ( int i = WP_NONE + 1; i < WP_NUM_WEAPONS; ++i )
	{
		int handle = LoadDeltaAnimation( static_cast<weapon_t>( i ), newModelName, ci->iqm );
		if ( !handle ) continue;
		Log::Debug("Loaded delta for %s %s", newModelName, BG_Weapon( i )->humanName);
		trap_R_BuildSkeleton( &delta, handle, 1, 1, 0, false );
		// Derive the delta from the base stand animation.
		trap_R_BuildSkeleton( &base, ci->animations[ TORSO_STAND ].handle, 1, 1, 0, false );
		auto ret = deltas_.insert( std::make_pair( i, std::vector<delta_t>( boneIndicies_.size() ) ) );
		auto& weaponDeltas = ret.first->second;
		for ( size_t j = 0; j < boneIndicies_.size(); ++j )
		{
			VectorSubtract( delta.bones[ boneIndicies_[ j ] ].t.trans, base.bones[ boneIndicies_[ j ] ].t.trans, weaponDeltas[ j ].delta );
			QuatInverse( base.bones[ boneIndicies_[ j ] ].t.rot );
			QuatMultiply( base.bones[ boneIndicies_[ j ] ].t.rot, delta.bones[ boneIndicies_[ j ] ].t.rot, weaponDeltas[ j ].rot );
		}
	}
	return true;
}
Exemple #5
0
float *AttitudeUpdate(float dt,float _beta, float _zeta, float a_x,float a_y, float a_z,float w_x, float w_y, float w_z,float m_x, float m_y, float m_z)
{

	float qConj[4];
	float unbiasedGyro[4];
	float qDot[4];
	float beta,zeta;
	float F[6];
	float J[6*4];
	float step[4];
	float North,East,Down;
	float b2,b4;

    
    float q1 = q[0]; float q2 = q[1]; float q3 = q[2]; float q4 = q[3];
    float _error[4];
    
    float accel[] = {0,-a_x,-a_y,-a_z};
    float mag[] = {0,m_x,m_y,m_z};
    

    
    // Direction cosine matrix from quaternion
    float qdcm13 = 2.0f*(q2*q4 - q1*q3);
    float qdcm23 = 2.0f*(q3*q4 + q1*q2);
    float qdcm33 = 2.0f*(0.5f - q2*q2 - q3*q3);
    
    float qdcm12 = 2.0f*(q2*q3 + q1*q4);
    float qdcm22 = 2.0f*(0.5f - q2*q2 - q4*q4);
    float qdcm32 = 2.0f*(q3*q4 - q1*q2);
    
    float qdcm11 = 2.0f*(0.5f - q3*q3 - q4*q4);
    float qdcm21 = 2.0f*(q2*q3 - q1*q4);
    float qdcm31 = 2.0f*(q2*q4 + q1*q3);
    
    counter += dt;
       QuatNormalize(accel);
       QuatNormalize(mag);
    // Earth's field
    North = qdcm11*mag[1] + qdcm21*mag[2] + qdcm31*mag[3];
    East =  qdcm12*mag[1] + qdcm22*mag[2] + qdcm32*mag[3];
    Down =  qdcm13*mag[1] + qdcm23*mag[2] + qdcm33*mag[3];

    b2 = sqrtf(North*North + East*East);
    b4 = Down;
    
    
    
    // 6 x 1
    F[0] =        qdcm13 - accel[1];
    F[1] =        qdcm23 - accel[2];
    F[2] =        qdcm33 - accel[3];
    F[3] =        b2*qdcm11 + b4*qdcm13 - mag[1];
    F[4] =        b2*qdcm21 + b4*qdcm23 - mag[2];
    F[5] =        b2*qdcm31 + b4*qdcm33 - mag[3];

    // 6 x 4

    J[0] = -2*q3; 			J[1] =  2*q4; 			J[2] = -2*q1; 			J[3] =  2*q2;
    J[4] =  2*q2;        	J[5] =	2*q1;        	J[6] =	2*q4;        	J[7] =	2*q3;
    J[8] =     0;       	J[9] =	-4*q2;       	J[10]=	-4*q3;          J[11] = 0;
    J[12]=-2*b4*q3;         J[13]=  2*b4*q4;        J[14]=-4*b2*q3-2*b4*q1; J[15]= -4*b2*q4+2*b4*q2;
    J[16]=-2*b2*q4+2*b4*q2; J[17]=  2*b2*q3+2*b4*q1;J[18]= 2*b2*q2+2*b4*q4; J[19]=-2*b2*q1+2*b4*q3;
    J[20]=2*b2*q3;          J[21]=  2*b2*q4-4*b4*q2;J[22]= 2*b2*q1-4*b4*q3; J[23] =2*b2*q2;

    
    //float Jt[4*6];
    //vDSP_mtrans(J,1,Jt,1,4,6);
    
    // step = J'*F
    //       4 x 6 * 6 x 1
    //vDSP_mmul( Jt,1,F,1,step,1,4,1,6);
    step[0] = J[0]*F[0] + J[4]*F[1] + J[8]*F[2] + J[12]*F[3] + J[16]*F[4] + J[20]*F[5];
    step[1] = J[1]*F[0] + J[5]*F[1] + J[9]*F[2] + J[13]*F[3] + J[17]*F[4] + J[21]*F[5];
    step[2] = J[2]*F[0] + J[6]*F[1] + J[10]*F[2] + J[14]*F[3] + J[18]*F[4] + J[22]*F[5];
    step[3] = J[3]*F[0] + J[7]*F[1] + J[11]*F[2] + J[15]*F[3] + J[19]*F[4] + J[23]*F[5];
    
    // normalize step 
    QuatNormalize(step);
    
    qConj[0] = q[0]; qConj[1] = -q[1]; qConj[2]=-q[2]; qConj[3]=-q[3];
    // Error
    QuatMultiply(qConj,step,_error);
    QuatScale(_error,(2.0f*dt));

    // update gyro biases
    w_bx += zeta*_error[1]; w_by += zeta*_error[2]; w_bz += zeta*_error[3];

    // quaternion dynamics
    unbiasedGyro[0] = 0; unbiasedGyro[1] = (w_x-w_bx); unbiasedGyro[2]= (w_y-w_by); unbiasedGyro[3] = (w_z-w_bz);
    QuatMultiply(q,unbiasedGyro,qDot);
    
    
    // higher gain during startup
    if(counter < 5.0f)
    {
        beta = 1.0f;
        zeta = 1.0f;
    }
    else
    {
        beta = _beta;
        zeta = _zeta;
    }
    
    qDot[0] = 0.5f*qDot[0] - beta*step[0];
    qDot[1] = 0.5f*qDot[1] - beta*step[1];
    qDot[2] = 0.5f*qDot[2] - beta*step[2];
    qDot[3] = 0.5f*qDot[3] - beta*step[3];
    
    q[0] += qDot[0]*dt;
    q[1] += qDot[1]*dt;
    q[2] += qDot[2]*dt;
    q[3] += qDot[3]*dt;

    QuatNormalize(q);
return q;



}