コード例 #1
0
ファイル: Quat.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :   Create Quaternion from Vector ( Uuuummmmm )
    Input       :   VECTOR  *   Vector
                :   QUAT    *   New Quaternion
    Output      :   Nothing
-------------------------------------------------------------------*/
void QuatFromVector2( VECTOR * Tv, QUAT * q )
{
    float   angle;
    VECTOR  Av;

/*-------------------------------------------------------------------
    Normalise TARGET Vector
-------------------------------------------------------------------*/
    NormaliseVector( Tv );

/*-------------------------------------------------------------------
    Create AXIS vector
-------------------------------------------------------------------*/
    Av.x = Tv->y;
    Av.y = -Tv->x;
    Av.z = 0.0F;
    NormaliseVector( &Av );

/*-------------------------------------------------------------------
    Calculate ANGLE between TARGET and LOOK vectors
-------------------------------------------------------------------*/
    angle = (float) ( acos( -Tv->z ) / 2 );

/*-------------------------------------------------------------------
    Finally build TARGET QUATERNION
-------------------------------------------------------------------*/
    q->x = (float) ( sin( angle ) * Av.x );
    q->y = (float) ( sin( angle ) * Av.y );
    q->z = 0.0F;
    q->w = (float) cos( angle );

    QuatNormalise( q );
}
コード例 #2
0
ファイル: botai_sensors.c プロジェクト: DUANISTON/forsaken
bool BOTAI_FriendlyFireCheck()
{
	int i;
	VECTOR Move_Dir;
	VECTOR TempVector;

	// no need to check if not a team game
	if(!TeamGame)
		return false;

	// calculate my direction vector
	ApplyMatrix( &Ships[WhoIAm].Object.Mat, &Forward, &Move_Dir );
	NormaliseVector( &Move_Dir );

	// for each player
	for(i = 0; i < MAX_PLAYERS; i++)	
	{
		// that is enabled
		if( i != WhoIAm && Ships[i].enable && Ships[i].Object.Mode == NORMAL_MODE )
		{
			// and on my team
			if(TeamNumber[WhoIAm] != TeamNumber[i])
				continue;

			// are we within visible params?
			if( RaytoSphere2(&Ships[i].Object.Pos, SHIP_RADIUS, &Ships[WhoIAm].Object.Pos, &Move_Dir , &TempVector , &TempVector ) )
				return true;
		}
	}

	return false;
}
コード例 #3
0
ファイル: botai_actions.c プロジェクト: DUANISTON/forsaken
bool BOTAI_AimAtTarget( MATRIX * InvMat , VECTOR * SPos, VECTOR * TPos )
{
	VECTOR WantedDir;
	VECTOR TempDir;
	float Angle;
	float OnTarget = true;

	WantedDir.x = ( TPos->x - SPos->x );
	WantedDir.y = ( TPos->y - SPos->y );
	WantedDir.z = ( TPos->z - SPos->z );
	ApplyMatrix( InvMat, &WantedDir, &TempDir );

	NormaliseVector( &TempDir );
	Angle = (float) acos( TempDir.x );
	Angle = 90.0F - R2D( Angle );

	if( TempDir.z < 0.0F )
		Angle = 180.0F - Angle;

	if( Angle > 180.0F )
		Angle -= 360.0F;

	if( Angle > 0.0F )
	{
		BOTAI_SetAction( &bot.yaw, 1.0F, "AimAtTarget() yaw right" );
		if( Angle > 3.0F )
			OnTarget = false;
	}
	else if( Angle < 0.0F )
	{
		BOTAI_SetAction( &bot.yaw, -1.0F, "AimAtTarget() yaw left" );
		if( Angle < -3.0F )
			OnTarget = false;
	}

	Angle = (float) acos( TempDir.y );
	Angle = 90.0F - R2D( Angle );
	Angle *= -1.0F;

	if( Angle > 180.0F )
		Angle -= 360.0F;

	if( Angle < 0.0F && ( TempDir.z > 0.0F ))
	{
		BOTAI_SetAction( &bot.pitch, -1.0F, "AimAtTarget() pitch up" );
		if(Angle < -3.0F)
			OnTarget = false;
	}
	else if( Angle > 0.0F && ( TempDir.z > 0.0F ))
	{
		BOTAI_SetAction( &bot.pitch, 1.0F, "AimAtTarget() pitch down" );
		if(Angle > 3.0F)
			OnTarget = false;
	}

	return OnTarget;
}
コード例 #4
0
ファイル: botai_sensors.c プロジェクト: DUANISTON/forsaken
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;
	}
}
コード例 #5
0
ファイル: AIExogenon.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :   Exogenon Fire
    Input       :   ENEMY * Enemy
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_EXOGENON_FIRE( register ENEMY * Enemy )
{
    VECTOR      TempVector;
    VECTOR      TempUpVector;
    VECTOR      TempOffset = { 0.0F, 0.0F, 180.0F };
    float       Distance;
    

    Enemy->Object.AnimSpeed = 1.0F;
    
    if( Enemy->Timer )
    {
        Enemy->Timer -= framelag;

        if( Enemy->Timer <= 0.0F )
        {
            // This is where the main Weapon would fire....
            Enemy->Timer = 0.0F;

            if( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )
            {
                ApplyMatrix( &Enemy->Object.Mat, &Forward, &TempVector );
                Distance = DistanceVector2Vector( &Ships[WhoIAm].Object.Pos ,&Enemy->Object.Pos );

                TempVector.x *= Distance;
                TempVector.y *= Distance;
                TempVector.z *= Distance;
                TempVector.y -= Enemy->Object.Pos.y - Ships[WhoIAm].Object.Pos.y;
                NormaliseVector(&TempVector);

                ApplyMatrix( &Enemy->Object.Mat, &SlideUp, &TempUpVector );
                
                EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, EnemyTypes[Enemy->Type].PrimaryWeaponType,
                    Enemy->Object.Group, &Enemy->Object.Pos, &TempOffset, &TempVector, &TempUpVector,
                    EnemyTypes[Enemy->Type].PowerLevel, (EnemyTypes[Enemy->Type].PowerLevel +1) * 33.0F, FALSE, NULL );
            }

            Enemy->Object.AI_Mode = AIMODE_EXOGENON_SWEEP;
            ExogenonAim( Enemy );
            ExogenonSweepDir = Enemy->AIMoveFlags;
            ExogenonSweepAngle = Enemy->AI_Angle;
            Enemy->Timer = 60.0F * 1.0F;
        }
    }
}
コード例 #6
0
ファイル: botai_sensors.c プロジェクト: DUANISTON/forsaken
bool BOTAI_InViewCone( VECTOR * Pos, MATRIX * Mat, VECTOR * TPos, float ViewConeCos )
{
	float Cos;
	VECTOR NormVector;
	VECTOR Dir;

	if( ViewConeCos == 1.0F )
		return true;

	Dir.x = TPos->x - Pos->x;
	Dir.y = TPos->y - Pos->y;
	Dir.z = TPos->z - Pos->z;
	NormVector = Dir;
	NormaliseVector( &NormVector );
	ApplyMatrix( Mat, &Forward, &Dir );

	Cos = DotProduct( &NormVector, &Dir );
	if( Cos > ViewConeCos )
		return true;

	return false;
}
コード例 #7
0
ファイル: botai_sensors.c プロジェクト: DUANISTON/forsaken
float BOTAI_WhenWillBulletHitMe(VECTOR * MyPos)
{
	int i;
	float time;
	float shortestTime = BIGDISTANCE;
	float dist;
	VECTOR TempVect;
	VECTOR temp;
	VECTOR TempVector;
	float ShipRadius;
	float Cos;

	// primary weapon bullets
	for(i = 0; i < MAXPRIMARYWEAPONBULLETS; i++)
	{
		// that are active and aren't my own
		if(PrimBulls[i].Used && PrimBulls[i].Owner != WhoIAm)
		{
			// set the collision radius
			switch( PrimaryWeaponAttribs[ PrimBulls[i].Weapon ].ColType )
			{
				case COLTYPE_Transpulse:
					TempVector.x = Ships[ WhoIAm ].Object.Pos.x - PrimBulls[i].Pos.x;
					TempVector.y = Ships[ WhoIAm ].Object.Pos.y - PrimBulls[i].Pos.y;
					TempVector.z = Ships[ WhoIAm ].Object.Pos.z - PrimBulls[i].Pos.z;
					NormaliseVector( &TempVector );
					Cos = (float) ( 1.0F - fabs( DotProduct( &TempVector, &PrimBulls[i].Dir ) ) );
					Cos = (float) ( Cos * ( 1.0F - fabs( DotProduct( &TempVector, &PrimBulls[i].UpVector ) ) ) );
					ShipRadius = SHIP_RADIUS + ( PrimBulls[i].ColRadius * Cos );
					break;

				case COLTYPE_Sphere:
				case COLTYPE_Trojax:
					ShipRadius = SHIP_RADIUS + PrimBulls[i].ColRadius;
					break;

				case COLTYPE_Point:
				default:
					ShipRadius = SHIP_RADIUS;
					break;
			}

			// bullet will (currently) eventually collide with this position
			if(RaytoSphere2( MyPos, ShipRadius, &PrimBulls[i].Pos, &PrimBulls[i].Dir, &TempVect, &TempVect ))
			{
				dist = DistanceVector2Vector(MyPos, &PrimBulls[i].Pos);
				time = dist/PrimBulls[i].Speed;
				if(time < shortestTime)
					shortestTime = time;
			}
		}
	}

	// reset homing missile flag when it's gone
	if(HomingMissile > -1)
	{
		if(!SecBulls[HomingMissile].Used)
			MissileAvoidanceSet = false;
	}

	// missiles
	HomingMissile = -1;
	for(i = 0; i< MAXSECONDARYWEAPONBULLETS; i++)
	{
		// ignore inactive missiles or my own
		if(!SecBulls[i].Used || SecBulls[i].Owner == WhoIAm)
			continue;

		// get the distance from me and time to impact
		dist = DistanceVector2Vector(MyPos, &SecBulls[i].Pos);
		time = dist/SecBulls[i].Speed;

		// straight missiles (treat like normal bullets)
		if(SecBulls[i].MoveType == MISMOVE_STRAIGHT )
		{
			// if it will hit me 
			if(RaytoSphere2(MyPos, SHIP_RADIUS, &SecBulls[i].Pos, &SecBulls[i].DirVector, &TempVect, &TempVect))
			{
				if(time < shortestTime)
					shortestTime = time; // find the closest
			}
		}
		// if a homing missile has locked on to me
		else if(SecBulls[i].MoveType == MISMOVE_HOMING && SecBulls[i].Target == WhoIAm)
		{
			// and it's close enough i have to deal with it
			if(dist < 2048.0F * GLOBAL_SCALE)
			{
				HomingMissile = i;
				shortestTime = time; // new
			}
		}
	}

	if(shortestTime < 10000.0F)
		return shortestTime;
	else
		return -1.0F; // nothing will hit
}
コード例 #8
0
ファイル: botai_actions.c プロジェクト: DUANISTON/forsaken
void BOTAI_AvoidHomingMissiles()
{
	VECTOR NormVector;
	VECTOR DirVector;
	float xAngle;
	float yAngle;

	if(HomingMissile > -1)
	{
		// -- decide what movement to perform
		// new missile
		//if(!MissileAvoidanceSet)
		{
			//DebugPrintf("set details for missile %d\n", HomingMissile);
			MissileAvoidanceSet = true;
			NormVector.x = SecBulls[HomingMissile].Pos.x - Ships[WhoIAm].Object.Pos.x;
			NormVector.y = SecBulls[HomingMissile].Pos.y - Ships[WhoIAm].Object.Pos.y;
			NormVector.z = SecBulls[HomingMissile].Pos.z - Ships[WhoIAm].Object.Pos.z;
			ApplyMatrix( &Ships[WhoIAm].Object.FinalInvMat, &NormVector, &DirVector );
			NormaliseVector( &DirVector );
			MissileOrigDirVector = DirVector;
		}


		// left/right angle
		xAngle = (float) acos( MissileOrigDirVector.x );
		xAngle = 90.0F - R2D( xAngle );
		if( MissileOrigDirVector.z < 0.0F )
			xAngle = 180.0F - xAngle;
		if( xAngle > 180.0F )
			xAngle -= 360.0F;
		//DebugPrintf("x = %f\n", xAngle);

		// up/down angle
		yAngle = (float) acos( MissileOrigDirVector.y );
		yAngle = 90.0F - R2D( yAngle );
		yAngle *= -1.0F;
		if( yAngle > 180.0F )
			yAngle -= 360.0F;
		//DebugPrintf("y = %f\n", yAngle);

		// -- execute slide movements

		// target is directly in front or behind me
		if((xAngle > -22.5F && xAngle < 22.5F) || (xAngle < -157.5F || xAngle > 157.5F))
		{
			// slide either left or right, doesn't matter
			BOTAI_SetAction( &bot.right, 1.0F, "AvoidHomingMissiles() right" );
		}
		// target is directly to the side of me
		else if((xAngle > 67.5F && xAngle < 112.5F) || (xAngle < -67.5F && xAngle > -112.5F))
		{
			// forward or backward, doesn't matter
			BOTAI_SetAction( &bot.forward, 1.0F, "AvoidHomingMissiles() forward" );
		}

		// target is to my front left 
		else if(xAngle > -67.5F && xAngle < -22.5F)
		{
			// move forward right 
			BOTAI_SetAction( &bot.forward, 1.0F, "AvoidHomingMissiles() forward" );
			BOTAI_SetAction( &bot.right, 1.0F, "AvoidHomingMissiles() right" );
		}

		// target is to my rear left 
		else if(xAngle > -157.5F && xAngle < -112.5F)
		{
			// move back left
			BOTAI_SetAction( &bot.forward, -1.0F, "AvoidHomingMissiles() reverse" );
			BOTAI_SetAction( &bot.forward, -1.0F, "AvoidHomingMissiles() left" );
		}

		// target is to my front right
		else if(xAngle > 22.5F && xAngle < 67.5F)
		{
			// move front left 
			BOTAI_SetAction( &bot.forward, 1.0F, "AvoidHomingMissiles() forward" );
			BOTAI_SetAction( &bot.right, -1.0F, "AvoidHomingMissiles() left" );
		}

		// target is to my rear right 
		else if(xAngle > 112.5F && xAngle < 157.5F)
		{
			// move back right 
			BOTAI_SetAction( &bot.forward, -1.0F, "AvoidHomingMissiles() reverse" );
			BOTAI_SetAction( &bot.right, 1.0F, "AvoidHomingMissiles() right" );
		}

		if(yAngle > 0.0F)
			BOTAI_SetAction( &bot.up, -1.0F, "AvoidHomingMissiles() down" );
		else
			BOTAI_SetAction( &bot.up, 1.0F, "AvoidHomingMissiles() up" );
	}
}
コード例 #9
0
ファイル: botai_actions.c プロジェクト: DUANISTON/forsaken
/* Slides to target pos without aiming at it; returns true if reached target */
bool BOTAI_SlideToTarget(VECTOR * TPos)
{
	VECTOR NormVector;
	VECTOR DirVector;
	float xAngle;
	float yAngle;

	//DebugPrintf("sliding to target\n");

	// -- Calculate angles
	NormVector.x = TPos->x - Ships[WhoIAm].Object.Pos.x;
	NormVector.y = TPos->y - Ships[WhoIAm].Object.Pos.y;
	NormVector.z = TPos->z - Ships[WhoIAm].Object.Pos.z;
	ApplyMatrix( &Ships[WhoIAm].Object.FinalInvMat, &NormVector, &DirVector );
	NormaliseVector( &DirVector );
	////DebugPrintf("x = %f y = %f z = %f\n", DirVector.x, DirVector.y, DirVector.z);

	// left/right angle
	xAngle = (float) acos( DirVector.x );
	xAngle = 90.0F - R2D( xAngle );
	if( DirVector.z < 0.0F )
		xAngle = 180.0F - xAngle;
	if( xAngle > 180.0F )
		xAngle -= 360.0F;
	////DebugPrintf("X Angle %f\n", xAngle);

	// up/down angle
	yAngle = (float) acos( DirVector.y );
	yAngle = 90.0F - R2D( yAngle );
	yAngle *= -1.0F;
	if( yAngle > 180.0F )
		yAngle -= 360.0F;
	////DebugPrintf("Y Angle %f\n", yAngle);
	////DebugPrintf("z %f\n", DirVector.z);


	// -- execute slide movements
	// sliding right
	if(xAngle > 0.0F && DistWall[0] > 100.0F)
		BOTAI_SetAction( &bot.right, 1.0F, "SlideToTarget() right" );
	// sliding left
	else if(xAngle < 0.0F && DistWall[1] > 100.0F)
		BOTAI_SetAction( &bot.right, -1.0F, "SlideToTarget() left" );

	// sliding up
	if(DistWall[2] > 100.0F) 
	{
		if(yAngle < 0.0F )
			BOTAI_SetAction( &bot.up, 1.0F, "SlideToTarget() up" );
	}
	// sliding down
	if(DistWall[3] > 100.0F) 
	{
		if(yAngle > 0.0F)
			BOTAI_SetAction( &bot.up, -1.0F, "SlideToTarget() down" );
	}

	// forward
	if(DirVector.z > 0.0F && DistWall[8] > 100.0F) 
		BOTAI_SetAction( &bot.forward, 1.0F, "SlideToTarget() forward" );
	// backward
	else if(DirVector.z < 0.0F && DistWall[9] > 100.0F )
		BOTAI_SetAction( &bot.forward, -1.0F, "SlideToTarget() reverse" );


	// Reached Target
	if(Ships[WhoIAm].Object.Pos.x < TPos->x + TOL && Ships[WhoIAm].Object.Pos.x > TPos->x - TOL
			&& Ships[WhoIAm].Object.Pos.y < TPos->y + TOL && Ships[WhoIAm].Object.Pos.y > TPos->y - TOL
			&& Ships[WhoIAm].Object.Pos.z < TPos->z + TOL && Ships[WhoIAm].Object.Pos.z > TPos->z - TOL)
		return true;
	else
		return false;
}
コード例 #10
0
ファイル: botai_actions.c プロジェクト: DUANISTON/forsaken
/* (buggy) always triple chords up/right/forward to target */
bool BOTAI_MoveToTarget(VECTOR * TPos)
{
	VECTOR NormVector;
	VECTOR DirVector;
	float xAngle;
	float yAngle;

	//DebugPrintf("moving to %f %f %f\n", TPos->x, TPos->y, TPos->z);


	// set slide movements and check if at target pos
	if(BOTAI_SlideToTarget(TPos))
		return true;

	// adjust the aim

	// -- Calculate angles
	NormVector.x = TPos->x - Ships[WhoIAm].Object.Pos.x;
	NormVector.y = TPos->y - Ships[WhoIAm].Object.Pos.y;
	NormVector.z = TPos->z - Ships[WhoIAm].Object.Pos.z;
	ApplyMatrix( &Ships[WhoIAm].Object.FinalInvMat, &NormVector, &DirVector );
	NormaliseVector( &DirVector );
	////DebugPrintf("x = %f y = %f z = %f\n", DirVector.x, DirVector.y, DirVector.z);

	// left/right angle
	xAngle = (float) acos( DirVector.x );
	xAngle = 90.0F - R2D( xAngle );
	if( DirVector.z < 0.0F )
		xAngle = 180.0F - xAngle;
	if( xAngle > 180.0F )
		xAngle -= 360.0F;
	////DebugPrintf("X Angle %f\n", xAngle);

	// up/down angle
	yAngle = (float) acos( DirVector.y );
	yAngle = 90.0F - R2D( yAngle );
	yAngle *= -1.0F;
	if( yAngle > 180.0F )
		yAngle -= 360.0F;
	////DebugPrintf("Y Angle %f\n", yAngle);

	// -- angle aim
	// sliding right
	if( bot.right == 1.0F)
	{
		// aim left
		if(xAngle < 30.0F)
			BOTAI_SetAction( &bot.yaw, -1.0F, "MoveToTarget() yaw left" );
		// aim right
		else if(xAngle > 40.0F)
			BOTAI_SetAction( &bot.yaw, 1.0F, "MoveToTarget() yaw right" );
	}

	// sliding left
	else if( bot.right == -1.0F)
	{
		// aim left
		if(xAngle < -40.0F)
			BOTAI_SetAction( &bot.yaw, -1.0F, "MoveToTarget() yaw left" );
		// aim right
		else if(xAngle > -30.0F)
			BOTAI_SetAction( &bot.yaw, 1.0F, "MoveToTarget() yaw right" );
	}

	// sliding up
	if(bot.up == 1.0F)
	{
		// aim up
		if(yAngle < -40.0F)
			BOTAI_SetAction( &bot.pitch, -1.0F, "MoveToTarget() pitch up" );
		// aim down
		else if(yAngle > -30.0F)
			BOTAI_SetAction( &bot.pitch, 1.0F, "MoveToTarget() pitch down" );
	}

	// sliding down
	else if(bot.up == -1.0F)
	{
		// aim up
		if(yAngle > 30.0F)
			BOTAI_SetAction( &bot.pitch, -1.0F, "MoveToTarget() pitch up" );
		// aim down
		else if(yAngle < 40.0F)
			BOTAI_SetAction( &bot.pitch, 1.0F, "MoveToTarget() pitch down" );
	}

	return false;
}
コード例 #11
0
ファイル: botai_actions.c プロジェクト: DUANISTON/forsaken
/* triple-chords to target pos in a straight line; returns true if reached target */
bool BOTAI_MoveToTargetNew(VECTOR * TPos)
{
	VECTOR Slide;
	VECTOR TriChordVector;
	VECTOR WantedVector;
	VECTOR NormVector;
	VECTOR DirVector;
	VECTOR FwdDirVector;
	float xAngle;
	float yAngle;
	float Cos;

	////DebugPrintf("moving to %f %f %f\n", TPos->x, TPos->y, TPos->z);

	// -- calculate direction vector from my position to target 
	NormVector.x = TPos->x - Ships[WhoIAm].Object.Pos.x;
	NormVector.y = TPos->y - Ships[WhoIAm].Object.Pos.y;
	NormVector.z = TPos->z - Ships[WhoIAm].Object.Pos.z;

	DirVector = NormVector;

	// apply that vector to my matrix to make direction relative to my direction and rotation 
	//ApplyMatrix( &Ships[WhoIAm].Object.FinalInvMat, &NormVector, &DirVector );
	NormaliseVector( &DirVector );
	//DebugPrintf("straight x = %f y = %f z = %f\n", DirVector.x, DirVector.y, DirVector.z);

	// calculate the desired vector
	// forward right
	Slide.x = 1.0F;
	Slide.y = 0.0F;
	Slide.z = 1.0F;


	// calculate the triple chord direction vector 
	ApplyMatrix( &Ships[WhoIAm].Object.FinalMat, &Slide, &TriChordVector );
	NormaliseVector( &TriChordVector );
	//DebugPrintf("trivec x = %f y = %f z = %f\n", TriChordVector.x, TriChordVector.y, TriChordVector.z);


	// difference between wanted vector and slide vector
	WantedVector.x = DirVector.x - TriChordVector.x;
	WantedVector.y = DirVector.y - TriChordVector.y;
	WantedVector.z = DirVector.z - TriChordVector.z;
	////DebugPrintf("W x = %f y = %f z = %f\n", WantedVector.x, WantedVector.y, WantedVector.z);

	// angle between trichord vector and wanted vector, == 1.0F when aligned perfectly
	Cos = DotProduct( &DirVector, &TriChordVector );
	////DebugPrintf("Cos = %f\n", Cos);

	return false;

	// left/right angle
	xAngle = (float) acos( WantedVector.x );
	xAngle = 90.0F - R2D( xAngle );
	if( WantedVector.z < 0.0F )
		xAngle = 180.0F - xAngle;
	if( xAngle > 180.0F )
		xAngle -= 360.0F;
	////DebugPrintf("X Angle %f\n", xAngle);

	// up/down angle
	yAngle = (float) acos( WantedVector.y );
	yAngle = 90.0F - R2D( yAngle );
	yAngle *= -1.0F;
	if( yAngle > 180.0F )
		yAngle -= 360.0F;
	////DebugPrintf("Y Angle %f\n", yAngle);

	if( xAngle > 0.0F )
		BOTAI_SetAction( &bot.yaw, 1.0F, "MoveToTargetNew() yaw right" );
	else if( xAngle < 0.0F )
		BOTAI_SetAction( &bot.yaw, -1.0F, "MoveToTargetNew() yaw left" );

	if( yAngle < 0.0F && ( WantedVector.z > 0.0F ))
		BOTAI_SetAction( &bot.pitch, -1.0F, "MoveToTargetNew() pitch up" );
	else if( yAngle > 0.0F && ( WantedVector.z > 0.0F ))
		BOTAI_SetAction( &bot.pitch, 1.0F, "MoveToTargetNew() pitch down" );


	// Reached Target
	if(Ships[WhoIAm].Object.Pos.x < TPos->x + TOL && Ships[WhoIAm].Object.Pos.x > TPos->x - TOL
			&& Ships[WhoIAm].Object.Pos.y < TPos->y + TOL && Ships[WhoIAm].Object.Pos.y > TPos->y - TOL
			&& Ships[WhoIAm].Object.Pos.z < TPos->z + TOL && Ships[WhoIAm].Object.Pos.z > TPos->z - TOL)
		return true;
	else
		return false;
}
コード例 #12
0
ファイル: rtlight.c プロジェクト: stevethrowback/forsaken
/******************************************************************************************
	Process real-time game lights
*******************************************************************************************/
void ProcessRTLights( void )
{
    int j;
    RT_LIGHT *light;
    XLIGHT *xlight;
    RT_FIXED_LIGHT *fixed;
    RT_PULSING_LIGHT *pulse;
    RT_FLICKERING_LIGHT *flicker;
    RT_SPOT_LIGHT *spot;
    float chance;
    MATRIX rotmat;

    for ( j = 0; j < rt_lights; j++ )
    {
        light = &rt_light[ j ];
        if ( light->xlight == (u_int16_t) -1 )
            continue; // only happens if run out of XLIGHTs
        xlight = &XLights[ light->xlight ];
        if ( light->delay > 0.0F )
        {
            light->delay -= framelag;
            if ( light->delay <= 0.0F )
            {
                light->enabled = true;
            }
        }
        if ( light->enabled )
        {
            switch ( light->type )
            {
            case LIGHT_FIXED:
                fixed = &light->fixed;
                switch ( light->state )
                {
                case STATE_OFF:
                    light->now_time = 0.0F;
                    xlight->Visible = false;
                    light->intensity = 0.0F;
                    break;
                case STATE_TURNING_ON:
                    if ( light->delay < 0.0F )
                    {
                        light->now_time += -light->delay;
                        light->delay = 0.0F;
                    }
                    else
                        light->now_time += framelag;
                    xlight->Visible = true;
                    if ( light->now_time < fixed->on_time )
                    {
                        InterpLightOn( light, light->now_time / fixed->on_time, fixed->on_type );
                    }
                    else
                    {
                        xlight->r = light->r;
                        xlight->g = light->g;
                        xlight->b = light->b;
                        xlight->Visible = true;
                        light->state = STATE_ON;
                    }
                    break;
                case STATE_ON:
                    xlight->r = light->r;
                    xlight->g = light->g;
                    xlight->b = light->b;
                    xlight->Visible = true;
                    break;
                case STATE_TURNING_OFF:
                    light->now_time += framelag;
                    xlight->Visible = true;
                    if ( light->now_time < fixed->off_time )
                    {
                        InterpLightOff( light, light->now_time / fixed->off_time, fixed->off_type );
                    }
                    else
                    {
                        light->state = STATE_OFF;
                        light->now_time = 0.0F;
                        xlight->Visible = false;
                    }
                    break;
                }
                break;
            case LIGHT_PULSING:
                pulse = &light->pulse;
                if ( light->delay < 0.0F )
                {
                    light->now_time += -light->delay;
                    light->delay = 0.0F;
                }
                else
                    light->now_time += framelag;
                if ( light->now_time > pulse->total_time )
                {
                    light->now_time = FMOD( light->now_time, pulse->total_time );
                }
                if ( light->now_time < pulse->on_time )
                {
                    // light is turning on
                    light->state = STATE_TURNING_ON;
                    InterpLightOn( light, light->now_time / pulse->on_time, pulse->type );
                    xlight->Visible = true;
                }
                else if ( light->now_time < pulse->stay_on_point )
                {
                    // light is staying on
                    light->state = STATE_ON;
                    xlight->r = light->r;
                    xlight->g = light->g;
                    xlight->b = light->b;
                    xlight->Visible = true;
                }
                else if ( light->now_time < pulse->off_point )
                {
                    // light is turning off
                    light->state = STATE_TURNING_OFF;
                    InterpLightOff( light, ( light->now_time - pulse->stay_on_point ) / pulse->off_time, pulse->type );
                    xlight->Visible = true;
                }
                else // light->now_time < pulse->total_time
                {
                    // light is staying off
                    light->state = STATE_OFF;
                    xlight->Visible = false;
                }
                break;
            case LIGHT_FLICKERING:
                flicker = &light->flicker;
                chance = RANDOM();
                if ( light->delay < 0.0F )
                {
                    light->now_time += -light->delay;
                    light->delay = 0.0F;
                }
                else
                    light->now_time += framelag;
                if ( light->state == STATE_ON )
                {
                    // check chance of switching off
                    if ( light->now_time > flicker->stay_on_time &&
                            chance > flicker->stay_on_chance )
                    {
                        light->state = STATE_OFF;
                        light->now_time = 0.0F;
                        xlight->Visible = false;
                    }
                }
                else // light is off
                {
                    // check chance of switching on
                    if ( light->now_time > flicker->stay_off_time &&
                            chance > flicker->stay_off_chance )
                    {
                        light->state = STATE_ON;
                        light->now_time = 0.0F;
                        xlight->Visible = true;
                    }
                }
                break;
            case LIGHT_SPOT:
                spot = &light->spot;
                if ( spot->rotation_speed )
                {
                    // rotate spotlight beam
                    if ( light->delay < 0.0F )
                    {
                        light->now_time += -light->delay;
                        light->delay = 0.0F;
                    }
                    else
                        light->now_time += framelag;
                    spot->angle = light->now_time * spot->rotation_speed;
                    if ( spot->angle > TWO_PI )
                        spot->angle = FMOD( spot->angle, TWO_PI );
                    MatrixFromAxisAndAngle( spot->angle, &spot->up, &rotmat );
                    ApplyMatrix( &rotmat, &spot->dir, &xlight->Dir );
                    NormaliseVector( &xlight->Dir );
                }
                light->state = STATE_ON;
                xlight->Visible = true;
                break;
            }
        }
        else
        {
            // light is disabled, check if turning off
            if ( light->state == STATE_TURNING_OFF )
            {
                switch ( light->type )
                {
                case LIGHT_FIXED:
                    fixed = &light->fixed;
                    light->now_time += framelag;
                    if ( light->now_time < fixed->off_time )
                    {
                        InterpLightOff( light, light->now_time / fixed->off_time, fixed->off_type );
                        xlight->Visible = true;
                    }
                    else
                    {
                        light->state = STATE_OFF;
                        light->now_time = 0.0F;
                        xlight->Visible = false;
                    }
                    break;
                case LIGHT_PULSING:
                    pulse = &light->pulse;
                    light->now_time += framelag;
                    if ( light->now_time < pulse->off_time )
                    {
                        InterpLightOff( light, light->now_time / pulse->off_time, pulse->type );
                        xlight->Visible = true;
                    }
                    else
                    {
                        light->state = STATE_OFF;
                        light->now_time = 0.0F;
                        xlight->Visible = false;
                    }
                    break;
                case LIGHT_FLICKERING:
                    light->state = STATE_OFF;
                    xlight->Visible = false;
                    break;
                case LIGHT_SPOT:
                    light->state = STATE_OFF;
                    xlight->Visible = false;
                    break;
                }
            }
            else if ( light->delay <= 0.0F )
            {
                light->state = STATE_OFF;
                xlight->Visible = false;
            }
        }
    }
}
コード例 #13
0
ファイル: Quat.c プロジェクト: ForsakenW/forsaken
/*-------------------------------------------------------------------
    Procedure   :       create a quaternion from two vectors that rotates
                        v1 to v2 about an axis perpendicular to both
    Input       :       QUAT    *   Destin Quaternion
                :       VECTOR * v1
                :       VECTOR * v2
    Output      :       Nothing
-------------------------------------------------------------------*/
void QuatFrom2Vectors( QUAT * destQuat, VECTOR * v1, VECTOR * v2 )
{
    VECTOR  u1, u2;
    VECTOR  axis;                    /* axis of rotation */
    float   theta;                   /* angle of rotation about axis */
    float   theta_complement;
    float   crossProductMagnitude;
/*
** Normalize both vectors and take cross product to get rotation axis. 
*/
    u1 = *v1;
    u2 = *v2;

    NormaliseVector( &u1 );
    NormaliseVector( &u2 );

    CrossProduct( &u1 , &u2, &axis );
/*
** | u1 X u2 | = |u1||u2|sin(theta)
**
** Since u1 and u2 are normalized, 
**
**  theta = arcsin(|axis|)
*/
    crossProductMagnitude = (float) sqrt( DotProduct( &axis , &axis ) );

/*
** Occasionally, even though the vectors are normalized, the magnitude will
** be calculated to be slightly greater than one.  If this happens, just
** set it to 1 or asin() will barf.
*/
    if( crossProductMagnitude > 1.0F )
       crossProductMagnitude = 1.0F;
/*
** Take arcsin of magnitude of rotation axis to compute rotation angle.
** Since crossProductMagnitude=[0,1], we will have theta=[0,pi/2].
*/
    theta = (float) asin( crossProductMagnitude );
    theta_complement = PI - theta;
/*
** If cos(theta) < 0, use complement of theta as rotation angle.
*/
    if( DotProduct( &u1 , &u2 ) < 0.0F )
    {
        theta = theta_complement;
        theta_complement = PI - theta;
    }

/* if angle is 0, just return identity quaternion   */
    if( theta < EPS )
    {
        destQuat->x = 0.0F;
        destQuat->y = 0.0F;
        destQuat->z = 0.0F;
        destQuat->w = 1.0F;
    }else{
        if( theta_complement < EPS )
        {
            /*
            ** The two vectors are opposed.  Find some arbitrary axis vector.
            ** First try cross product with x-axis if u1 not parallel to x-axis.
            */
            if( (u1.y*u1.y + u1.z*u1.z) >= EPS )
            {
                axis.x = 0.0F ;
                axis.y = u1.z ;
                axis.z = u1.y ;
            }else{
                /*
                ** u1 is parallel to to x-axis.  Use z-axis as axis of rotation.
                */
                axis.x = axis.y = 0.0F ;
                axis.z = 1.0F ;
            }
        }
        NormaliseVector( &axis );
        QuatMake( destQuat, axis.x, axis.y, axis.z, theta ) ;
        QuatNormalise( destQuat );
   }
}