예제 #1
0
void CSTransform::RotateOrigin(const double vector[3], double angle, bool concatenate)
{
	double XYZ_A[4]={vector[0],vector[1],vector[2],angle};

	double matrix[16];
	if (RotateOriginMatrix(matrix, XYZ_A)==false)
		return;

	ApplyMatrix(matrix,concatenate);
	AppendList(ROTATE_ORIGIN,XYZ_A,4);
}
예제 #2
0
void Planet::Draw(Renderer & renderer)
{    
    if (!m_attr->active) return;

    Matrix tmp = m_matrix;
    m_matrix = m2;
    ApplyMatrix(renderer);
    
    renderer.SetBlending(false);
    renderer.SetColor(Color(0.0f, 0.0f, 0.0f));
    renderer.DrawShape(m_planetBkgnd);
    renderer.SetBlending(true);

    m_matrix = tmp;
    ApplyMatrix(renderer);
    
    renderer.SetTexturing(false);  
    renderer.SetColor(m_color);  
    renderer.DrawWireSphere(42.5f, 14, 14); 
}
예제 #3
0
void Quaternion::rotate_vector(Vector in,Vector &out)
{
    float inv[4]={float(in.x),float(in.y),float(in.z),0},outv[4]={float(out.x),float(out.y),float(out.z),0};
    float matrix[16];

    normalize();
    to_matrix(matrix);
    ApplyMatrix(inv,matrix,outv);
    out.x=outv[0];
    out.y=outv[1];
    out.z=outv[2];
} /* Quaternion::rotate_vector */
예제 #4
0
void BaseMesh::CreateClosedCylinder(float radius, const Vec3f &pt1, const Vec3f &pt2, UINT slices, UINT stacks)
{
    float height = (pt2 - pt1).Length();
    CreateClosedCylinder(radius, height, slices, stacks);    //create a basic cylinder of the appropriate height

    Matrix4 T1 = Matrix4::Translation(Vec3f(0.0f,0.0f,height / 2.0f));    //translate so it goes from Origin to eZ*height
    Matrix4 Face = Matrix4::Face(Vec3f::eZ, pt2 - pt1);                        //make it face the direction pt2 - pt1 instead of eZ
    Matrix4 T2 = Matrix4::Translation(pt1);                            //translate it so it goes from pt1 -> pt2 as requested

    ApplyMatrix(T1 * Face * T2);    //apply the constructed Matrix4
    GenerateNormals();
}
예제 #5
0
파일: Quat.c 프로젝트: ForsakenW/forsaken
/*-------------------------------------------------------------------
    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 );
}
예제 #6
0
int FB_Jolt( void )
{
    static float checktime = 0.0F;
    //static float jolt_time = 0.0F;
    GLOBALSHIP *s;
    OBJECT *obj;
    VECTOR jolt;
    float magnitude, duration;
    float attack_level, attack_time;
    float fade_level, fade_time;
    MATRIX InvMat;
    
    if ( !FF_Supported( FB_Joystick ) )
        return 0;
    s = &Ships[ WhoIAm ];
    obj = &s->Object;
    if ( framelag )
        magnitude = VectorLength( &JoltForce ) / framelag;
    else
        magnitude = 0.0F;
    magnitude /= MAXTURBOSPEED;
    if ( magnitude > 0.01F )
    {
        MatrixTranspose( &obj->Mat, &InvMat );
        ApplyMatrix( &InvMat, &JoltForce, &jolt );
        duration = 0.25F;
        attack_level = (float) sqrt( magnitude );
        attack_time = 0.1F;
        fade_level = 0.0F;
        fade_time = 0.15F;
        if ( magnitude > MAX_MAGNITUDE )
            magnitude = MAX_MAGNITUDE;
        if ( attack_level > MAX_MAGNITUDE )
            attack_level = MAX_MAGNITUDE;
        FF_UpdateConstantEffect( FB_Joystick, FF_EFFECT_Jolt,
            magnitude, duration,
            attack_level, attack_time,
            fade_level, fade_time,
            &jolt, DIEP_START );
        checktime -= framelag;
        if ( checktime < 0.0F )
        {
            checktime = JOLT_CHECK_INTERVAL;
            FF_CheckEffectPlaying( FB_Joystick, FF_EFFECT_Jolt );
        }
    }
    JoltForce.x = 0.0F;
    JoltForce.y = 0.0F;
    JoltForce.z = 0.0F;
    return 1;
}
예제 #7
0
FX_BOOL CFDE_GdiDevice::FillPolygon(IFDE_Brush* pBrush,
                                    const CFX_PointsF& points,
                                    const CFX_Matrix* pMatrix) {
  Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
  if (pGdiBrush == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->FillPolygon(
      pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
  RestoreMatrix(pMatrix);
  ReleaseGdiBrush(pGdiBrush);
  return ret == Gdiplus::Ok;
}
예제 #8
0
FX_BOOL CFDE_GdiDevice::FillRectangle(IFDE_Brush* pBrush,
                                      const CFX_RectF& rect,
                                      const CFX_Matrix* pMatrix) {
  Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
  if (pGdiBrush == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->FillRectangle(
      pGdiBrush, rect.left, rect.top, rect.width, rect.height);
  RestoreMatrix(pMatrix);
  ReleaseGdiBrush(pGdiBrush);
  return ret == Gdiplus::Ok;
}
void matrixstack::Rotate(const double phi)
{
    Matrix m(3,3);
    m.UnitMatrix();
    const double s = sin(phi);
    const double c = cos(phi);
    m(0,0) =  c;
    m(0,1) = -s;
    m(1,0) =  s;
    m(1,1) =  c;

    ApplyMatrix( m );

}
예제 #10
0
/*-------------------------------------------------------------------
    Procedure   :   Exogenon Move Down
    Input       :   ENEMY * Enemy
    Output      :   Nothing
-------------------------------------------------------------------*/
void AI_EXOGENON_MOVEDOWN( register ENEMY * Enemy )
{
    VECTOR  TempUpVector;
    VECTOR  FireDir;

    BOOL    ClearLos = TRUE;
    VECTOR  TempOffset = { 0.0F, 0.0F, 180.0F };
    ExogenonAim( Enemy );

    Enemy->Object.AnimSpeed = 1.5F;
    if( Enemy->Object.Animating )
    {
        return;
    }

    if( !(ClearLos = AI_ClearLOSNonZeroNonObject( &Enemy->Object.Pos,Enemy->Object.Group, &Ships[WhoIAm].Object.Pos , SHIP_RADIUS))
        || (Random_Range(10) > 5 ) )
    {
        Enemy->Object.AI_Mode = AIMODE_EXOGENON_MOVEUP;
        SetCurAnimSeq( EXOGENONSEQ_Move_Up, &Enemy->Object );

        if( ClearLos )
        {
            ApplyMatrix( &Enemy->Object.Mat, &SlideUp, &TempUpVector );
            ApplyMatrix( &Enemy->Object.Mat, &Forward, &FireDir );
            // Fire a homing missile Forward...
            InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
                &Enemy->Object.Pos, &TempOffset, &FireDir, &TempUpVector,
                &TempOffset, ENEMYBLUEHOMINGMISSILE, FALSE );
        }
        ExogenonFireLeftRight( Enemy );
    }else{
        Enemy->Object.AI_Mode = AIMODE_EXOGENON_SCAN;
        SetCurAnimSeq( EXOGENONSEQ_Idle, &Enemy->Object );
    }
}
예제 #11
0
FX_BOOL CFDE_GdiDevice::DrawRectangle(IFDE_Pen* pPen,
                                      FX_FLOAT fPenWidth,
                                      const CFX_RectF& rect,
                                      const CFX_Matrix* pMatrix) {
  Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
  if (pGdiPen == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->DrawRectangle(pGdiPen, rect.left, rect.top,
                                                   rect.width, rect.height);
  RestoreMatrix(pMatrix);
  ReleaseGdiPen(pGdiPen);
  return ret == Gdiplus::Ok;
}
예제 #12
0
FX_BOOL CFDE_GdiDevice::DrawPolygon(IFDE_Pen* pPen,
                                    FX_FLOAT fPenWidth,
                                    const CFX_PointsF& points,
                                    const CFX_Matrix* pMatrix) {
  Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
  if (pGdiPen == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->DrawPolygon(
      pGdiPen, (const Gdiplus::PointF*)points.GetData(), points.GetSize());
  RestoreMatrix(pMatrix);
  ReleaseGdiPen(pGdiPen);
  return ret == Gdiplus::Ok;
}
예제 #13
0
void CSTransform::RotateXYZ(int dir, double angle, bool concatenate)
{
	if ((dir<0) || (dir>3))
		return;

	double vec[4]={0,0,0,angle};
	vec[dir] = 1;

	double matrix[16];
	if (RotateOriginMatrix(matrix, vec)==false)
		return;

	ApplyMatrix(matrix,concatenate);
	TransformType type = (TransformType)((int)ROTATE_X + dir);
	AppendList(type,&angle,1);
}
예제 #14
0
FX_BOOL CFDE_GdiDevice::FillClosedCurve(IFDE_Brush* pBrush,
                                        const CFX_PointsF& points,
                                        FX_FLOAT fTension,
                                        const CFX_Matrix* pMatrix) {
  Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
  if (pGdiBrush == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->FillClosedCurve(
      pGdiBrush, (const Gdiplus::PointF*)points.GetData(), points.GetSize(),
      Gdiplus::FillModeAlternate, fTension);
  RestoreMatrix(pMatrix);
  ReleaseGdiBrush(pGdiBrush);
  return ret == Gdiplus::Ok;
}
예제 #15
0
FX_BOOL CFDE_GdiDevice::DrawLine(IFDE_Pen* pPen,
                                 FX_FLOAT fPenWidth,
                                 const CFX_PointF& pt1,
                                 const CFX_PointF& pt2,
                                 const CFX_Matrix* pMatrix) {
  Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
  if (pGdiPen == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret =
      m_pGraphics->DrawLine(pGdiPen, pt1.x, pt1.y, pt2.x, pt2.y);
  RestoreMatrix(pMatrix);
  ReleaseGdiPen(pGdiPen);
  return ret == Gdiplus::Ok;
}
예제 #16
0
FX_BOOL CFDE_GdiDevice::FillPath(IFDE_Brush* pBrush,
                                 const IFDE_Path* pPath,
                                 const CFX_Matrix* pMatrix) {
  CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
  if (pGdiPath == NULL) {
    return FALSE;
  }
  Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
  if (pGdiBrush == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->FillPath(pGdiBrush, &pGdiPath->m_Path);
  RestoreMatrix(pMatrix);
  ReleaseGdiBrush(pGdiBrush);
  return ret == Gdiplus::Ok;
}
예제 #17
0
void BaseMesh::ReCreateLozenge(float Radius, const Vec3f &Start, const Vec3f &End, UINT slices, UINT stacks)
{
    //this is just like CreateCylinder(radius, pt1, pt2, slices, stacks) except the radius function isn't fixed;
    //towards the ends it rounds off into a sphere.
    MeshVertex *V = Vertices();
    
    float Theta,CurZ,SqrtValue;
    float PI2_Slices = 2.0f * Math::PIf / float(slices), Height, LocalRadius;
    Vec3f Diff = End - Start;
    Height = Diff.Length();

    for(UINT i=0; i <= stacks; i++)
    {
        for(UINT i2 = 0; i2 < slices; i2++)
        {
            Theta = float(i2) * PI2_Slices;
            CurZ = float(Math::LinearMap(0.0f, float(stacks), -Radius, Height+Radius, float(i)));

            if(CurZ < 0.0f)        //if we need to round the cylinder,
            {
                LocalRadius = float(Math::LinearMap(-Radius, 0.0f, 1.0f, 0.0f, CurZ));
                SqrtValue = 1.0f - LocalRadius*LocalRadius;
                if(SqrtValue < 0.0f) SqrtValue = 0.0f;
                LocalRadius = sqrtf(SqrtValue) * Radius;    //compute the appropriate radius
            }
            else if(CurZ > Height)    //if we're on the other end of the cylinder and need to round,
            {
                LocalRadius = float(Math::LinearMap(Height, Height+Radius, 0.0f, 1.0f, CurZ));
                SqrtValue = 1.0f - LocalRadius*LocalRadius;
                if(SqrtValue < 0.0f) SqrtValue = 0.0f;
                LocalRadius = sqrtf(SqrtValue) * Radius;    //do the same thing
                if(LocalRadius < 0.0f || LocalRadius > Radius + 1e-5f) LocalRadius = 0.0f;
            }
            else
            {
                LocalRadius = Radius;    //otherwise we're in the middle and our radius is fixed like a cylinder
            }

            V[i*slices+i2].Pos = Vec3f(LocalRadius * cosf(Theta), LocalRadius * sinf(Theta), CurZ);    //load the appropriate position
        }
    }

    Vec3f UpVec(0.0f, 0.0f, 1.0f);

    ApplyMatrix(Matrix4::Face(UpVec, Diff) * Matrix4::Translation(Start));            //make it face the right direction and translate it to the right position
}
예제 #18
0
FX_BOOL CFDE_GdiDevice::DrawPath(IFDE_Pen* pPen,
                                 FX_FLOAT fPenWidth,
                                 const IFDE_Path* pPath,
                                 const CFX_Matrix* pMatrix) {
  CFDE_GdiPath* pGdiPath = (CFDE_GdiPath*)pPath;
  if (pGdiPath == NULL) {
    return FALSE;
  }
  Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
  if (pGdiPen == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret = m_pGraphics->DrawPath(pGdiPen, &pGdiPath->m_Path);
  RestoreMatrix(pMatrix);
  ReleaseGdiPen(pGdiPen);
  return ret == Gdiplus::Ok;
}
예제 #19
0
FX_BOOL CFDE_GdiDevice::FillPie(IFDE_Brush* pBrush,
                                const CFX_RectF& rect,
                                FX_FLOAT startAngle,
                                FX_FLOAT sweepAngle,
                                const CFX_Matrix* pMatrix) {
  startAngle = FX_RAD2DEG(startAngle);
  sweepAngle = FX_RAD2DEG(sweepAngle);
  Gdiplus::Brush* pGdiBrush = CreateGdiBrush(pBrush);
  if (pGdiBrush == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret =
      m_pGraphics->FillPie(pGdiBrush, rect.left, rect.top, rect.width,
                           rect.height, startAngle, sweepAngle);
  RestoreMatrix(pMatrix);
  ReleaseGdiBrush(pGdiBrush);
  return ret == Gdiplus::Ok;
}
예제 #20
0
파일: MFView.cpp 프로젝트: FujiGameJam/fuji
MF_API void MFView_TransformPoint2DTo3D(const MFVector& point, MFVector *pResult, MFVector *pResultRayDir)
{
	MFMatrix proj, viewProj, view;

	// get the perspective projection matrix
	proj.SetPerspective(pCurrentView->fov, pCurrentView->nearPlane, pCurrentView->farPlane, pCurrentView->aspectRatio);

	// in this special case, we'll make the projection matrix produce a 0-1 value in z across all platforms (some platforms project into different 'z' spaces)
	float zn = pCurrentView->nearPlane;
	float zf = pCurrentView->farPlane;
	float zd = zf-zn;
	float zs = zf/zd;
	proj.m[10] = zs;
	proj.m[14] = -zn*zs;

	// get the view matrix (which we will need to calculate if we are in ortho mode)
	if(!MFView_IsOrtho())
		view = MFView_GetWorldToViewMatrix();
	else
		view.Inverse(MFView_GetCameraMatrix());

	viewProj.Multiply4x4(view, proj);

	// inverse projection
	viewProj.Inverse();

	// which the point from ortho space back into homogeneous space
	*pResult = point;
	*pResult -= MakeVector(pCurrentView->orthoRect.x, pCurrentView->orthoRect.y);
	*pResult *= MakeVector(MFRcp(pCurrentView->orthoRect.width*0.5f), MFRcp(pCurrentView->orthoRect.height*0.5f));
	pResult->x -= 1.0f;
	pResult->y = -pResult->y + 1.0f;

	// and un-project
	// TODO: undo the perspective divide (f**k)
	*pResult = ApplyMatrix(*pResult, viewProj);

	if(pResultRayDir)
	{
		// calculate the pixels rays direction..

	}
}
예제 #21
0
float BOTAI_DistanceToWall( bool u, bool d, bool l, bool r, bool f, bool b )
{
	float dist;
	VECTOR temp;
	NORMAL FaceNormal;
	VECTOR Pos_New;
	VECTOR ImpactPoint;
	u_int16_t ImpactGroup;
	VECTOR Slide;

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

	if(r) Slide.x = 1.0F;	
	else if(l) Slide.x = -1.0F;		
	if(u) Slide.y = 1.0F;	
	else if(d) Slide.y = -1.0F;	
	if(f) Slide.z = 1.0F;	
	else if(b) Slide.z = -1.0F;

	ApplyMatrix( &Ships[WhoIAm].Object.FinalMat, &Slide, &temp );

	temp.x *= MaxColDistance;
	temp.y *= MaxColDistance;
	temp.z *= MaxColDistance;

	// get collision details	
	BackgroundCollide( &MCloadheadert0, &Mloadheader, &Ships[WhoIAm].Object.Pos, Ships[WhoIAm].Object.Group, &temp, &ImpactPoint, &ImpactGroup, &FaceNormal, &Pos_New, false, NULL );

	// return the distance
	dist = DistanceVector2Vector(&Ships[WhoIAm].Object.Pos, &ImpactPoint);

	// if movement will put me in a gravgon we want to avoid this
	Pos_New = Ships[WhoIAm].Object.Pos;
	BOTAI_LookAheadPos( 10.0F, &Pos_New, Slide );
	if( BOTAI_CheckForGravgons( &Pos_New ) ) 
		dist = 1.0F;

	return dist;
}
예제 #22
0
FX_BOOL CFDE_GdiDevice::DrawPie(IFDE_Pen* pPen,
                                FX_FLOAT fPenWidth,
                                const CFX_RectF& rect,
                                FX_FLOAT startAngle,
                                FX_FLOAT sweepAngle,
                                const CFX_Matrix* pMatrix) {
  startAngle = FX_RAD2DEG(startAngle);
  sweepAngle = FX_RAD2DEG(sweepAngle);
  Gdiplus::Pen* pGdiPen = CreateGdiPen(pPen, fPenWidth);
  if (pGdiPen == NULL) {
    return FALSE;
  }
  ApplyMatrix(pMatrix);
  Gdiplus::Status ret =
      m_pGraphics->DrawPie(pGdiPen, rect.left, rect.top, rect.width,
                           rect.height, startAngle, sweepAngle);
  RestoreMatrix(pMatrix);
  ReleaseGdiPen(pGdiPen);
  return ret == Gdiplus::Ok;
}
예제 #23
0
void BaseMesh::CreatePlane(const Vec3f &_start, const Vec3f &_end, UINT slicesX, UINT slicesY)
{
    Vec3f start = _start, end = _end;
    CreatePlane(1.0f, slicesX, slicesY);

    if(start.x > end.x)
    {
        Utility::Swap(start.x, end.x);
    }
    if(start.y > end.y)
    {
        Utility::Swap(start.y, end.y);
    }
    
    Matrix4 T1 = Matrix4::Translation(Vec3f(0.5f,0.5f,0.0f));
    Matrix4 Scale = Matrix4::Scaling(Vec3f((end.x-start.x),(end.y-start.y),1.0f));
    Matrix4 T2 = Matrix4::Translation(start);

    ApplyMatrix(T1 * Scale * T2);
}
예제 #24
0
/*===================================================================
	Procedure	:	AIR Formation Flying
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_LITTLEGEEK_FORMATION( register ENEMY * Enemy )
{
	OBJECT * SObject;
	VECTOR		Offset;
	VECTOR		TargetPos;
	ENEMY * LinkEnemy;
	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false ,false);

	LinkEnemy = Enemy->FormationLink;

	if( !LinkEnemy || ( LinkEnemy->Object.Shield <= (EnemyTypes[LinkEnemy->Type].Shield * 0.5F ) )  )
	{
		Enemy->Object.ControlType = ENEMY_CONTROLTYPE_FLY_AI;
		EnemyTypes[ENEMY_Boss_LittleGeek].Radius = 800 * GLOBAL_SCALE;
		EnemyTypes[ENEMY_Boss_BigGeek].Radius = 900.0F * GLOBAL_SCALE;
		AI_SetDOGFIGHT( Enemy );
		SetCurAnimSeq( LITTLEGEEKSEQ_Open, &Enemy->Object );
		Enemy->FormationLink = NULL;
		return;
	}

	SetCurAnimSeq( LITTLEGEEKSEQ_Stop, &Enemy->Object );

	Offset = Enemy->FormationOffset;
	ApplyMatrix( &LinkEnemy->Object.Mat, &Offset, &TargetPos );
	TargetPos.x += LinkEnemy->Object.Pos.x;
	TargetPos.y += LinkEnemy->Object.Pos.y;
	TargetPos.z += LinkEnemy->Object.Pos.z;

	Enemy->Object.Pos = TargetPos;

	Enemy->Object.Quat = LinkEnemy->Object.Quat;
	Enemy->Object.Mat = LinkEnemy->Object.Mat;
	Enemy->Object.InvMat = LinkEnemy->Object.InvMat;
	Enemy->Object.FinalMat = LinkEnemy->Object.FinalMat;
	Enemy->Object.FinalInvMat = LinkEnemy->Object.FinalInvMat;
	EnemyTypes[ENEMY_Boss_LittleGeek].Radius = 0.0F;

}
예제 #25
0
bool CSTransform::RotateXYZ(int dir, std::string angle, bool concatenate)
{
	if ((dir<0) || (dir>3))
		return false;

	ParameterScalar ps_angle(m_ParaSet, angle);
	int EC = ps_angle.Evaluate();
	if (EC!=0)
		return false;
	double vec[4]={0,0,0,ps_angle.GetValue()};
	vec[dir] = 1;

	double matrix[16];
	if (RotateOriginMatrix(matrix, vec)==false)
		return false;

	ApplyMatrix(matrix,concatenate);
	TransformType type = (TransformType)((int)ROTATE_X + dir);
	AppendList(type,&ps_angle,1);
	return true;
}
예제 #26
0
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;
}
예제 #27
0
파일: aifire.c 프로젝트: DUANISTON/forsaken
/*===================================================================
	Procedure	:	Update an Enemies Guns...
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_UPDATEGUNS( register ENEMY * Enemy )
{
	OBJECT * TObject;
	GUNOBJECT * GObject;
	VECTOR		TempVector;
	VECTOR		TempUpVector;
	VECTOR		TempOffset = { 0.0F, 0.0F, 0.0F };
	VECTOR		NewPos;
	VECTOR		FireOffset;
	FIREPOS *	FirePosPnt;
	VECTOR		AimOffset;
	u_int16_t		i;
	BYTE		Weapon;

	TObject = (OBJECT*) Enemy->TShip;

	if( !TObject || TObject->Mode != NORMAL_MODE )
		return;
	
	GObject = Enemy->Object.FirstGun;

	
	while( GObject )
	{
		
//		if( TObject && ( (Enemy->AIFlags & AI_ICANSEEPLAYER) || (Enemy->Object.ControlType == ENEMY_CONTROLTYPE_TURRET_AI) || (Enemy->Object.ControlType == ENEMY_CONTROLTYPE_SPLINE) ) )
		if( TObject && ( (Enemy->AIFlags & AI_ICANSEEPLAYER) || (Enemy->Object.ControlType == ENEMY_CONTROLTYPE_SPLINE) ) )
		{
			FirePosPnt = EnemyTypes[Enemy->Type].GunFirePoints[GObject->GunNum>>1];
			ApplyMatrix( &GObject->Mat , &FirePosPnt->Points[GObject->FirePosCount] , &FireOffset );
			FireOffset.x += GObject->FirePos.x;
			FireOffset.y += GObject->FirePos.y;
			FireOffset.z += GObject->FirePos.z;
			FireOffset.x -= Enemy->Object.Pos.x;
			FireOffset.y -= Enemy->Object.Pos.y;
			FireOffset.z -= Enemy->Object.Pos.z;
			
			ApplyMatrix( &GObject->Mat, EnemyTypes[ Enemy->Type ].GunAimPos[GObject->GunNum>>1], &AimOffset );
			AimOffset.x += Enemy->Object.Pos.x;
			AimOffset.y += Enemy->Object.Pos.y;
			AimOffset.z += Enemy->Object.Pos.z;
			
			if( !GunTypes[GObject->Type].BurstMasterCount )
			{
				// Normal gun that just fires when it can..
				
				if( GunTypes[GObject->Type].PrimarySecondary )
				{
					AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , SecondaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed);
				}else{
					AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , PrimaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed[GunTypes[GObject->Type].PowerLevel]);
				}
				
				
				AI_AimAtTarget( &GObject->InvMat , &AimOffset, &NewPos );
				GObject->AIMoveFlags |= AimData.Flags;
				GObject->AI_Angle = AimData.Angle;

				if( GObject->Type == GUN_MetaTankMain )
				{
					if( (GObject->ReloadTime <= (0.5F*60.0F) ) && !Enemy->Object.Animating )
					{
						SetCurAnimSeq( 0, &Enemy->Object );
					}
				}
				if( GObject->ReloadTime <= 0.0F && ( (( ( GObject->AI_Angle.x < GunTypes[GObject->Type].BurstAngle && GObject->AI_Angle.x > -GunTypes[GObject->Type].BurstAngle )
					&& ( GObject->AI_Angle.y < GunTypes[GObject->Type].BurstAngle && GObject->AI_Angle.y > -GunTypes[GObject->Type].BurstAngle ) )  ) || GObject->Type == GUN_MetaTankMain ) )
				{
					ApplyMatrix( &GObject->Mat, &Forward, &TempVector );
					ApplyMatrix( &GObject->Mat, &SlideUp, &TempUpVector );
					
					if( !(Enemy->Object.Flags & SHIP_Scattered ) && (!GunTypes[GObject->Type].Range || ( DistanceVector2Vector( &TObject->Pos , &Enemy->Object.Pos) < GunTypes[GObject->Type].Range ) ))
					{

						if(Enemy->Object.ControlType == ENEMY_CONTROLTYPE_TURRET_AI)
						{
							if( !Enemy->Object.Animating && (Enemy->Type != ENEMY_MissileTurret) )
							{
								SetCurAnimSeq( TURRETSEQ_Fire, &Enemy->Object );
							}
						}
						
						if( GunTypes[GObject->Type].PrimarySecondary )
						{
							InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
								&Enemy->Object.Pos, &FireOffset, &TempVector, &TempUpVector,
								&TempOffset, GunTypes[GObject->Type].WeaponType, false );
							
						}else{
							Weapon = BodgePrimaryWeapon( GunTypes[GObject->Type].WeaponType, Enemy->PickupHeld );

							i = EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Weapon,
										Enemy->Object.Group, &Enemy->Object.Pos, &FireOffset, &TempVector, &TempUpVector,
										GunTypes[GObject->Type].PowerLevel, (GunTypes[GObject->Type].PowerLevel +1) * 33.0F, false, GObject );
							if( i != (u_int16_t) -1 )
							{
								PrimBulls[i].FirePoint = GObject->FirePosCount;
							}
						}
						GObject->FirePosCount++;
						if( GObject->FirePosCount >= FirePosPnt->NumPoints )
							GObject->FirePosCount = 0;
						
						
						GObject->ReloadTime =GunTypes[GObject->Type].ReloadTime;
					}
				}
			}else{
				// A Gun That Does a Burst...
				if( GObject->BurstCount )
				{
					
					if( GunTypes[GObject->Type].PrimarySecondary )
					{
						AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , SecondaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed);
					}else{
						AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , PrimaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed[GunTypes[GObject->Type].PowerLevel]);
					}
					AI_AimAtTarget( &GObject->InvMat , &AimOffset, &NewPos );
					GObject->AIMoveFlags |= AimData.Flags;
					GObject->AIMoveFlags &= ~(AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT );
					GObject->AI_Angle = AimData.Angle;
					if( GObject->BurstStartSign	< 0.0F )
					{
						GObject->AIMoveFlags |= AI_CONTROL_TURNLEFT;
					}else{
						GObject->AIMoveFlags |= AI_CONTROL_TURNRIGHT;
					}
					if( !(Enemy->Object.Flags & SHIP_Scattered ) &&GObject->ReloadTime <= 0.0F )
					{
						ApplyMatrix( &GObject->Mat, &Forward, &TempVector );
						ApplyMatrix( &GObject->Mat, &SlideUp, &TempUpVector );
						
						if(Enemy->Object.ControlType == ENEMY_CONTROLTYPE_TURRET_AI)
						{
							if( !Enemy->Object.Animating && (Enemy->Type != ENEMY_MissileTurret) )
							{
								SetCurAnimSeq( TURRETSEQ_Fire, &Enemy->Object );
							}
						}

						if( GunTypes[GObject->Type].PrimarySecondary )
						{
							InitOneSecBull( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Enemy->Object.Group,
								&Enemy->Object.Pos, &FireOffset, &TempVector, &TempUpVector,
								&TempOffset, GunTypes[GObject->Type].WeaponType, false );
							
						}else{
							Weapon = BodgePrimaryWeapon( GunTypes[GObject->Type].WeaponType, Enemy->PickupHeld );

							i = EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, Weapon,
										Enemy->Object.Group, &Enemy->Object.Pos, &FireOffset, &TempVector, &TempUpVector,
										GunTypes[GObject->Type].PowerLevel, (GunTypes[GObject->Type].PowerLevel +1) * 33.0F, false, GObject );
							if( i != (u_int16_t) -1 )
							{
								PrimBulls[i].FirePoint = GObject->FirePosCount;
							}
						}
						
						GObject->FirePosCount++;
						if( GObject->FirePosCount >= FirePosPnt->NumPoints )
							GObject->FirePosCount = 0;
						
						GObject->ReloadTime = GunTypes[GObject->Type].ReloadTime;
						GObject->BurstCount--;
					}
				}
				
				if( !GObject->BurstCount && GunTypes[GObject->Type].BurstMasterCount )
				{
					
					if( GunTypes[GObject->Type].PrimarySecondary )
					{
						AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , SecondaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed);
					}else{
						AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move ,&AimOffset, TObject , &NewPos , PrimaryWeaponAttribs[GunTypes[GObject->Type].WeaponType].Speed[GunTypes[GObject->Type].PowerLevel]);
					}
					
					AI_AimAtTarget( &GObject->InvMat , &AimOffset, &NewPos );
					GObject->AIMoveFlags |= AimData.Flags;
					GObject->AI_Angle = AimData.Angle;
					if( GObject->BurstTime == 0.0F )
					{
						if( (GObject->AI_Angle.y <= GunTypes[GObject->Type].BurstAngle) && (GObject->AI_Angle.y >= -GunTypes[GObject->Type].BurstAngle) )
						{
							GObject->BurstCount = GunTypes[GObject->Type].BurstMasterCount;
							GObject->BurstTime = GunTypes[GObject->Type].BurstMasterTime;
							GObject->BurstStartSign = GObject->AI_Angle.y;
						}
					}
				}
				
			}
		}
		GObject = GObject->Next;
	}
예제 #28
0
o3d::Primitive* Primitives::CreateSphere(
      o3d::Pack* pack,
      float radius,
      int subdivisionsAxis,
      int subdivisionsHeight,
      o3d::Matrix4* matrix) {
  DCHECK(subdivisionsAxis >= 1);
  DCHECK(subdivisionsHeight >= 1);

  std::vector<o3d::Point3> positions;
  std::vector<o3d::Vector3> normals;
  std::vector<Vector2> tex_coords;
  std::vector<Triangle> indices;

  const float kPI = 3.14159265f;

  for (int y = 0; y <= subdivisionsHeight; ++y) {
    for (int x = 0; x <= subdivisionsAxis; ++x) {
      // Generate a vertex based on its spherical coordinates
      float u = static_cast<float>(x) / static_cast<float>(subdivisionsAxis);
      float v = static_cast<float>(y) / static_cast<float>(subdivisionsHeight);
      float theta = 2.0f * kPI * u;
      float phi = kPI * v;
      float sinTheta = sinf(theta);
      float cosTheta = cosf(theta);
      float sinPhi = sinf(phi);
      float cosPhi = cosf(phi);
      float ux = cosTheta * sinPhi;
      float uy = cosPhi;
      float uz = sinTheta * sinPhi;
      positions.push_back(o3d::Point3(radius * ux, radius * uy, radius * uz));
      normals.push_back(o3d::Vector3(ux, uy, uz));
      tex_coords.push_back(Vector2(1 - u, 1 - v));
    }
  }

  int numVertsAround = subdivisionsAxis + 1;

  for (int x = 0; x < subdivisionsAxis; ++x) {
    for (int y = 0; y < subdivisionsHeight; ++y) {
      // Make triangle 1 of quad.
      indices.push_back(Triangle(
          (y + 0) * numVertsAround + x,
          (y + 0) * numVertsAround + x + 1,
          (y + 1) * numVertsAround + x));

      // Make triangle 2 of quad.
      indices.push_back(Triangle(
          (y + 1) * numVertsAround + x,
          (y + 0) * numVertsAround + x + 1,
          (y + 1) * numVertsAround + x + 1));
    }
  }

  if (matrix) {
    ApplyMatrix(*matrix, &positions);
    ApplyMatrix(*matrix, &normals);
  }

  return CreatePrimitive(
    pack, &positions, &normals, &tex_coords, &indices,
    o3d::Primitive::TRIANGLELIST);
}
예제 #29
0
파일: ReadMD2.cpp 프로젝트: TurkeyMan/fuji
void ParseMD2File(char *pFile, size_t length)
{
	int a, b;

	MD2Header *pHeader = (MD2Header*)pFile;

	MFDebug_Assert(pHeader->ident == (('2'<<24) | ('P'<<16) | ('D'<<8) | 'I'), "Invalid MD2 header.");
	MFDebug_Assert(pHeader->version == 8, "Invalid MD2 version.");

//	md2_skin_t		*skins = (md2_skin_t*)(pFile + pHeader->offset_skins);
	md2_texCoord_t	*st = (md2_texCoord_t*)(pFile + pHeader->offset_st);
	md2_triangle_t	*tris = (md2_triangle_t*)(pFile + pHeader->offset_tris);
	md2_frame_t		*frames = (md2_frame_t*)(pFile + pHeader->offset_frames);

	MFMatrix md2Mat;
	md2Mat.SetIdentity();
	md2Mat.SetXAxis3(MakeVector(1,0,0));
	md2Mat.SetYAxis3(MakeVector(0,0,1));
	md2Mat.SetZAxis3(MakeVector(0,1,0));

	// material
	F3DMaterialChunk *pMatChunk = pModel->GetMaterialChunk();

	F3DMaterial &mat = pMatChunk->materials.push();
	mat.name = pModel->name;
	mat.maps[0] = pModel->name;

	// mesh data
	F3DMeshChunk *pMC = pModel->GetMeshChunk();
	F3DSubObject &sub = pMC->subObjects.push();

	// copy name (TODO: remove file extension)
	sub.name = pModel->name;

	// colours
	sub.colours.resize(1);
	sub.colours[0] = MFVector::one;

	// tex coords
	sub.uvs.resize(pHeader->num_st);

	for(a=0; a<pHeader->num_st; a++)
	{
		sub.uvs[a].x = (float)st[a].s / (float)pHeader->skinwidth;
		sub.uvs[a].y = (float)st[a].t / (float)pHeader->skinheight;
		sub.uvs[a].z = 0.0f;
	}

	// normals
	sub.normals.resize(numNormals);

	for(a=0; a<numNormals; a++)
	{
		sub.normals[a].x = normalTable[a][0];
		sub.normals[a].y = normalTable[a][1];
		sub.normals[a].z = normalTable[a][2];

		sub.normals[a] = ApplyMatrix(sub.normals[a], md2Mat);
	}

//	for(a=0; a<pHeader->num_frames; a++)
//	{
		// read frame data

//		(char*&)pHeader->frames += pHeader->framesize;
//	}

	// vertices
	sub.positions.resize(pHeader->num_vertices);

	MFVector scale = MakeVector(frames->scale[0], frames->scale[1], frames->scale[2], 0.0f);
	MFVector translate = MakeVector(frames->translate[0], frames->translate[1], frames->translate[2]);

	for(b=0; b<pHeader->num_vertices; b++)
	{
		// verts
		sub.positions[b] = MakeVector((float)frames->verts[b].v[0], (float)frames->verts[b].v[1], (float)frames->verts[b].v[2]);
		sub.positions[b] = sub.positions[b]*scale + translate;

		sub.positions[b] = ApplyMatrix(sub.positions[b], md2Mat);
	}

	// trnangles
	F3DMaterialSubobject &matSub = sub.matSubobjects.push();
	matSub.materialIndex = 0;

	matSub.vertices.resize(pHeader->num_tris * 3);

	for(a=0; a<pHeader->num_tris; a++)
	{
		matSub.vertices[a*3 + 0].colour = 0;
		matSub.vertices[a*3 + 1].colour = 0;
		matSub.vertices[a*3 + 2].colour = 0;

		matSub.vertices[a*3 + 0].position = tris[a].vertex[0];
		matSub.vertices[a*3 + 0].uv[0] = tris[a].st[0];
		matSub.vertices[a*3 + 0].normal = frames->verts[tris[a].vertex[0]].normalIndex;

		matSub.vertices[a*3 + 1].position = tris[a].vertex[1];
		matSub.vertices[a*3 + 1].uv[0] = tris[a].st[1];
		matSub.vertices[a*3 + 1].normal = frames->verts[tris[a].vertex[1]].normalIndex;

		matSub.vertices[a*3 + 2].position = tris[a].vertex[2];
		matSub.vertices[a*3 + 2].uv[0] = tris[a].st[2];
		matSub.vertices[a*3 + 2].normal = frames->verts[tris[a].vertex[2]].normalIndex;
	}

	matSub.triangles.resize(pHeader->num_tris);

	for(a=0; a<pHeader->num_tris; a++)
	{
		matSub.triangles[a].v[0] = a*3 + 0;
		matSub.triangles[a].v[1] = a*3 + 1;
		matSub.triangles[a].v[2] = a*3 + 2;

		// TODO: generate face normal
	}
}
예제 #30
0
/*===================================================================
	Procedure	:	AIR Formation Flying
	Input		:	ENEMY * Enemy
	Output		:	Nothing
===================================================================*/
void AI_AIR_FORMATION( register ENEMY * Enemy )
{
	float	Dist;
	OBJECT * TObject;
	OBJECT * SObject;
	VECTOR		NewPos;
	VECTOR		TempVector;
	VECTOR		TempUpVector;
	VECTOR		TempOffset = { 0.0F, 0.0F, 0.0F };
	VECTOR		Offset;
	VECTOR		TargetPos;
	VECTOR		TempDir;
	ENEMY * LinkEnemy;

	SObject = &Enemy->Object;
	// Is it time to think???
	AI_THINK( Enemy , false ,false);

	LinkEnemy = Enemy->FormationLink;

	if( !LinkEnemy || ( LinkEnemy->Object.AI_Mode == AIMODE_RETREAT ) )
	{
		if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
		{
			AI_SetDOGFIGHT( Enemy );
			return;
		}else{
			AI_SetFOLLOWPATH( Enemy );
			return;
		}
	}

	TObject = (OBJECT*) Enemy->TShip;

	
	Enemy->Timer -= framelag;
	if( Enemy->Timer < 0.0F )
		Enemy->Timer = 0.0F;

	Enemy->PrimaryFireTimer -= framelag;
	if( Enemy->PrimaryFireTimer < 0.0F )
		Enemy->PrimaryFireTimer = 0.0F;
	Enemy->SecondaryFireTimer -= framelag;
	if( Enemy->SecondaryFireTimer < 0.0F )
		Enemy->SecondaryFireTimer = 0.0F;

	if( Enemy->AIFlags & ( AI_ICANSEEPLAYER + AI_ICANHEARPLAYER ) )
	{
		Enemy->TNode = NULL;
		if( !(Enemy->Object.Flags & SHIP_Scattered ) && (Enemy->AIFlags & AI_ICANSEEPLAYER) && !(Enemy->AIFlags & AI_FRIENDLYFIRE) )
		{
			ApplyMatrix( &SObject->Mat, &Forward, &TempVector );
			ApplyMatrix( &SObject->Mat, &SlideUp, &TempUpVector );

			if( (Enemy->PrimaryFireTimer == 0.0F) && ( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )  )
			{
				Enemy->PrimaryFireTimer = EnemyTypes[Enemy->Type].PrimaryFireRate + (float) Random_Range( (u_int16_t) EnemyTypes[Enemy->Type].PrimaryFireRate );
				EnemyFirePrimary( OWNER_ENEMY, Enemy->Index, ++Enemy->BulletID, EnemyTypes[Enemy->Type].PrimaryWeaponType,
					Enemy->Object.Group, &Enemy->Object.Pos, &TempOffset, &TempVector, &TempUpVector,
					EnemyTypes[Enemy->Type].PowerLevel, 0.0F, false, NULL );
			}
		}
	}

	if( (Enemy->Object.Flags & SHIP_Scattered ) || ( (EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_RETREAT) && ( Enemy->Object.Shield <= (EnemyTypes[Enemy->Type].Shield * 0.15 ) ) ) )
	{
		// we should get out of hear..
		Enemy->FormationLink = NULL;
		AI_SetRETREAT( Enemy );
		return;
	}
	
	AI_UPDATEGUNS( Enemy );
	// Aim at target

	if( TObject && ( Enemy->AIFlags & AI_ICANSEEPLAYER ) )
	{
		if( EnemyTypes[Enemy->Type].PrimaryWeaponType != NO_PRIMARY )
		{
			AI_LookAhead( EnemyTypes[Enemy->Type].Behave.Anticipate_Move , &Enemy->Object.Pos , TObject , &NewPos ,   PrimaryWeaponAttribs[EnemyTypes[Enemy->Type].PrimaryWeaponType].Speed[0] );
		}else{
			NewPos = TObject->Pos;
		}
		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}else{
		ApplyMatrix( &LinkEnemy->Object.Mat, &Forward, &TempDir );
		TempDir.x *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.y *= 1024.0F * GLOBAL_SCALE * 5.0F;
		TempDir.z *= 1024.0F * GLOBAL_SCALE * 5.0F;
		NewPos.x = LinkEnemy->Object.Pos.x + TempDir.x;
		NewPos.y = LinkEnemy->Object.Pos.y + TempDir.y;
		NewPos.z = LinkEnemy->Object.Pos.z + TempDir.z;

		AI_AimAtTarget( &Enemy->Object.InvMat , &Enemy->Object.Pos, &NewPos );
		if( !( EnemyTypes[Enemy->Type].Behave.Flags & AI_BEHAVIOUR_ICANTPITCH ) )
		{
			Enemy->AIMoveFlags |= AimData.Flags;
		}else{
			//This enemy cant look up or down so it has to move up and down to compensate....
			Enemy->AIMoveFlags |= ( AimData.Flags & ( AI_CONTROL_TURNLEFT + AI_CONTROL_TURNRIGHT ) );
			if( AimData.Flags & AI_CONTROL_TURNUP )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_UP;
			}else if( AimData.Flags & AI_CONTROL_TURNDOWN )
			{
				Enemy->AIMoveFlags |=  AI_CONTROL_DOWN;
			}
			
		}
		
		Enemy->AI_Angle = AimData.Angle;
	}

	if( Enemy->AvoidTimer )
	{
		Enemy->AIMoveFlags = Enemy->AvoidType;
	}else{

		Offset = Enemy->FormationOffset;
		ApplyMatrix( &LinkEnemy->Object.Mat, &Offset, &TargetPos );
		TargetPos.x += LinkEnemy->Object.Pos.x;
		TargetPos.y += LinkEnemy->Object.Pos.y;
		TargetPos.z += LinkEnemy->Object.Pos.z;

		Dist = DistanceVector2Vector( &TargetPos , &Enemy->Object.Pos);

		if( Dist > (EnemyTypes[Enemy->Type].Radius * 0.75F) )
		{
			Offset.x = TargetPos.x - Enemy->Object.Pos.x;
			Offset.y = TargetPos.y - Enemy->Object.Pos.y;
			Offset.z = TargetPos.z - Enemy->Object.Pos.z;

			ApplyMatrix( &Enemy->Object.InvMat, &Offset, &TargetPos );

			if( TargetPos.x < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_LEFT;
			}
			if( TargetPos.x > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_RIGHT;
			}
			if( TargetPos.y < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_DOWN;
			}
			if( TargetPos.y > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_UP;
			}
			if( TargetPos.z < -(EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_BACK;
			}
			if( TargetPos.z > (EnemyTypes[Enemy->Type].Radius * 0.25F) )
			{
				Enemy->AIMoveFlags |= AI_CONTROL_FORWARD;
			}

		}
	}
}