Esempio n. 1
0
bool BOTAI_WillHomingMissileHit(VECTOR * MyPos)
{
	float Cos;
	float Angle;
	VECTOR DirVector;
	VECTOR TmpVec;
	QUATLERP qlerp;
	SECONDARYWEAPONBULLET MissCopy = SecBulls[ HomingMissile ];

	// direction vector from missile to me
	DirVector.x = MyPos->x - MissCopy.Pos.x;
	DirVector.y = MyPos->y - MissCopy.Pos.y;
	DirVector.z = MyPos->z - MissCopy.Pos.z;
	NormaliseVector( &DirVector );

	// angle difference between the missile's current vector and wanted vector
	Cos = DotProduct( &DirVector, &MissCopy.DirVector );

	// set the parameters to perform a linear interpolation on two quaternions
	QuatFrom2Vectors( &qlerp.end, &Forward, &DirVector );
	qlerp.start	= MissCopy.DirQuat;				
	qlerp.crnt	= &MissCopy.DirQuat;	
	qlerp.dir	= QuatDotProduct( &qlerp.start, &qlerp.end );

	// bound angle difference
	if( Cos < -1.0F ) Cos = -1.0F;
	else if ( Cos > 1.0F ) Cos = 1.0F;

	// get angle difference in radians
	Angle = (float) acos( Cos );

	// calculate the amount of angle to turn 
	if( Angle ) qlerp.time = ( ( D2R( MissCopy.TurnSpeed ) * framelag ) / Angle );
	else qlerp.time = 1.0F;
	if( qlerp.time > 1.0F ) qlerp.time = 1.0F;

	// perform quat interpolation
	QuatInterpolate( &qlerp );
	QuatToMatrix( &MissCopy.DirQuat, &MissCopy.Mat );
	ApplyMatrix( &MissCopy.Mat, &Forward, &MissCopy.DirVector );
	ApplyMatrix( &MissCopy.Mat, &SlideUp, &MissCopy.UpVector );

	// will missile hit?
	if(RaytoSphere2(MyPos, SHIP_RADIUS, &MissCopy.Pos, &MissCopy.DirVector, &TmpVec, &TmpVec ))
	{
		DebugPrintf("homing missile will hit\n");
		return true;
	}
	else
	{
		DebugPrintf("safe from homing missile\n");
		return false;
	}
}
Esempio n. 2
0
/*-------------------------------------------------------------------
    Procedure   :       Quaternion Spherical Interpolation (Slerp)
    Input       :       double      alpha ( interpolation parameter (0 to 1) )
                :       QUAT    *   a ( start unit quaternions )
                :       QUAT    *   b ( end unit quaternions )
                :       QUAT    *   q ( output interpolated quaternion )
                :       int16       spin ( number of extra spin rotations )
    Output      :       Nothing
-------------------------------------------------------------------*/
void Quaternion_Slerp( float alpha, QUAT * a, QUAT * b, QUAT * q, int spin )
{
    float   beta;           /* complementary interp parameter */
    float   theta;          /* angle between A and B */
    float   sin_t, cos_t;   /* sine, cosine of theta */
    float   phi;            /* theta plus spins */
    int     bflip;          /* use negation of B? */

    cos_t = QuatDotProduct( a, b );

    /* if B is on opposite hemisphere from A, use -B instead */
    if( cos_t < 0.0F )
    {
        cos_t = -cos_t;
        bflip = TRUE;
    }
    else
    {
        bflip = FALSE;
    }

    /* if B is (within precision limits) the same as A,
     * just linear interpolate between A and B.
     * Can't do spins, since we don't know what direction to spin.
     */
    if( ( 1.0F - cos_t ) < EPS )
    {
        beta = ( 1.0F - alpha );
    }
    else
    {               /* normal case */
        theta   = ( (float) acos( cos_t ) );
        phi     = ( theta + ( spin * M_PI ) );
        sin_t   = ( (float) sin( theta ) );
        beta    = ( (float) sin( theta - ( alpha * phi ) ) / sin_t );
        alpha   = ( (float) sin( alpha * phi ) / sin_t );
    }

    if( bflip ) alpha = -alpha;

    /* interpolate */
    q->x = ( ( beta * a->x ) + ( alpha * b->x ) );
    q->y = ( ( beta * a->y ) + ( alpha * b->y ) );
    q->z = ( ( beta * a->z ) + ( alpha * b->z ) );
    q->w = ( ( beta * a->w ) + ( alpha * b->w ) );
}