示例#1
0
void FPSCamera::KeyPressed(int key, bool repeat) {
	if (repeat) {
		const float keySens = inputHandler->GetKeySensitivity();
		const bool mouseLook = AUX->GetMouseLook();

		switch (key) {
			case SDLK_LALT:  { VStrafe( 1, keySens); } break;
			case SDLK_LCTRL: { VStrafe(-1, keySens); } break;

			case SDLK_w: { Move(    1, keySens); } break;
			case SDLK_s: { Move(   -1, keySens); } break;
			case SDLK_a: { HStrafe(-1, keySens); } break;
			case SDLK_d: { HStrafe( 1, keySens); } break;
			case SDLK_q: { Roll(   -1, keySens * DEG2RAD(0.5f)); } break;
			case SDLK_e: { Roll(    1, keySens * DEG2RAD(0.5f)); } break;

			case SDLK_UP:    { if (!mouseLook) { Pitch(-1, keySens * DEG2RAD(0.5f)); } } break;
			case SDLK_DOWN:  { if (!mouseLook) { Pitch( 1, keySens * DEG2RAD(0.5f)); } } break;
			case SDLK_LEFT:  { if (!mouseLook) { Yaw(  -1, keySens * DEG2RAD(0.5f)); } } break;
			case SDLK_RIGHT: { if (!mouseLook) { Yaw(   1, keySens * DEG2RAD(0.5f)); } } break;

			default: {} break;
		}
	}
}
示例#2
0
void Camera::Update(float deltaTime, SDL_Event e)
{
	if (e.type == SDL_KEYDOWN)
	{
		switch (e.key.keysym.sym)
		{
		case SDLK_a:
			Yaw(-kAngleToTurn);
			break;

		case SDLK_d:
			Yaw(kAngleToTurn);
			break;

		case SDLK_s:
			Pitch(-kAngleToTurn);
			break;

		case SDLK_w:
			Pitch(kAngleToTurn);
			break;

		case SDLK_q:
			Roll(kAngleToTurn);
			break;

		case SDLK_e:
			Roll(-kAngleToTurn);
			break;

		case SDLK_DOWN:
			MoveForward(-kMoveDistance);
			break;

		case SDLK_UP:
			MoveForward(kMoveDistance);
			break;

		case SDLK_LEFT:
			Strafe(kMoveDistance);
			break;

		case SDLK_RIGHT:
			Strafe(-kMoveDistance);
			break;
		}
	}
}
示例#3
0
clsObject::clsObject(
		float pX, 
		float pY, 
		float pZ, 
		float p,
		float y,
		float r, 
		CLASS_ID clsID)
	: ClassID(clsID), ID(Counter++), Name(NULL)
{
	Name	= new TCHAR[MAX_OBJECT_NAME_LEN];
	Name[0]	= '\0';

	//UCS		= NULL;
	pos		= VECTOR3D(pX, pY, pZ);

	fWd		= VECTOR3D(1.0f, .0f, .0f);
	rWd		= VECTOR3D(.0f, 1.0f, .0f);
	uWd		= VECTOR3D(.0f, .0f, 1.0f);
	world	= VECTOR3D();

	worldScale	= VECTOR3D(1.0f, 1.0f, 1.0f);
	localScale	= worldScale;

	Pitch(p);
	Yaw(y);
	Roll(r);
}
示例#4
0
Dvoid Camera::UpdateCamera(Dint x, Dint y, Dint clickState, MoveKey moveKey, Matrix44& viewMatrix, Matrix44& perspectiveMatrix)
{
    UpdateTimeDelta();
    m_bMove = false;

    //───────────────────────────────────────────────────────────────────────────────────
    //키 입력 처리
    InputHandle(x, y, clickState, moveKey);
    //───────────────────────────────────────────────────────────────────────────────────

    m_vPos += m_vMoveDir;
    m_vLook += m_vMoveDir;

    Pitch();
    Yaw();

    if (m_bMove)
    {
        ViewMatrixCalculate();
    }

    viewMatrix = m_matCam[CM_VIEW];
    perspectiveMatrix = m_matCam[CM_PROJ];

    m_MouseMoveInterval = { 0, 0 };
}
示例#5
0
void Camera3::Update(double dt, bool* myKeys)
{/*
	Vector3 view = (target - position).Normalized();
	Vector3 right = view.Cross(up);
	right.y = 0;
	Inertia: instant dir change

	* strafe */
	if(myKeys[KEY_A] && !myKeys[KEY_D])
		Strafe(-dt);
	else if(straftMovingLeft)
		DecelerateLeft(-dt);

	if(myKeys[KEY_D] && !myKeys[KEY_A])
		Strafe(dt);
	else if(straftMovingRight)
		DecelerateRight(dt);

	/* walk */
	if(myKeys[KEY_W] && !myKeys[KEY_S])
		Walk(dt);
	else if(walkMovingForward)
		DecelerateForward(dt);

	if(myKeys[KEY_S] && !myKeys[KEY_W])
		Walk(-dt);
	else if(walkMovingBackward)
		DecelerateBackward(-dt);

	if(myKeys[KEY_C] && !croutching)
		croutching = true;

	croutch(dt);


	/* fly */
	if(myKeys[KEY_K])
		Fly(dt);
	if(myKeys[KEY_L])
		Fly(-dt);

	if(myKeys[KEY_SPACE] && !jump)	//com runs too fast, spacebar 2 times
		setJump(dt);

	if(myKeys[KEY_T])	//reset
	{
		Reset();
	}
	

	/** update jump **/
	if(jump)
		Jump(dt);
	

	/** mouse **/
	Yaw(dt);
	Pitch(dt);
}
示例#6
0
void CAMERA::Update(MOUSE &mouse, float timeDelta)
{
	//Restrict focus movment to the xz-plane
	m_right.y = m_look.y = 0.0f;
	D3DXVec3Normalize(&m_look, &m_look);
	D3DXVec3Normalize(&m_right, &m_right);

	//Move Focus (i.e. Scroll)
	if(mouse.x < mouse.m_viewport.left + 10)	Scroll(-m_right * timeDelta * 30.0f);
	if(mouse.x > mouse.m_viewport.right - 10)	Scroll(m_right * timeDelta * 30.0f);
	if(mouse.y < mouse.m_viewport.top + 10)		Scroll(m_look * timeDelta * 30.0f);
	if(mouse.y > mouse.m_viewport.bottom - 10)	Scroll(-m_look * timeDelta * 30.0f);

	//Move Camera (i.e. Change Angle)
	if(KEYDOWN(VK_LEFT))Yaw(-timeDelta);
	if(KEYDOWN(VK_RIGHT))Yaw(timeDelta);
	if(KEYDOWN(VK_UP))Pitch(timeDelta);
	if(KEYDOWN(VK_DOWN))Pitch(-timeDelta);
	
	//Zoom (i.e. change fov)
	if(KEYDOWN(VK_ADD))Zoom(-timeDelta);
	if(KEYDOWN(VK_SUBTRACT))Zoom(timeDelta);

	//Change m_radius
	if(mouse.WheelUp())  ChangeRadius(-1.0f);
	if(mouse.WheelDown())ChangeRadius(1.0f);

	//Calculate Eye Position
	float sideRadius = m_radius * cos(m_beta);
	float height = m_radius * sin(m_beta);

	m_eye = D3DXVECTOR3(m_focus.x + sideRadius * cos(m_alpha),
					  m_focus.y + height, 
					  m_focus.z + sideRadius * sin(m_alpha));

	if(m_pDevice != NULL)
	{
		D3DXMATRIX view = GetViewMatrix();
		D3DXMATRIX projection = GetProjectionMatrix();

		m_pDevice->SetTransform(D3DTS_VIEW, &view);
		m_pDevice->SetTransform(D3DTS_PROJECTION, &projection);

		CalculateFrustum(view, projection);
	}	
}
示例#7
0
 /*
 Generates a view matrix for the camera's viewpoint. This matrix can be sent
 straight to the shader...it's already an 'inverse camera' matrix.
 */
 glm::mat4 Camera::BuildViewMatrix()
 {
     //Why do a complicated matrix inversion, when we can just generate the matrix
     //using the negative values ;). The matrix multiplication order is important!
     return glm::rotate(-Pitch(), glm::vec3(1.f, 0.f, 0.f))
          * glm::rotate(-Yaw(), glm::vec3(0.f, 1.f, 0.f))
          * glm::translate(-transform.GetPosition());
 }
示例#8
0
void Camera::MouseMoved(int xdelta, int ydelta)
{
	if (xdelta != 0)
		Yaw(Units::Radians, -xdelta * 0.2 * DEG_TO_RAD);

	if (ydelta != 0)
		Pitch(Units::Radians, -ydelta * 0.2 * DEG_TO_RAD);
}
示例#9
0
void FPSCamera::MouseMoved(int, int, int dx, int dy) {
	if (AUX->GetMouseLook()) {
		const int xsign =  (dx > 0)?  1: -1;
		const int ysign =  (dy > 0)? -1:  1;
		const float rdx = ((dx > 0)? dx: -dx) / hFOVdeg;
		const float rdy = ((dy > 0)? dy: -dy) / vFOVdeg;

		if (dx != 0) { Yaw(  xsign, rdx); }
		if (dy != 0) { Pitch(ysign, rdy); }
	}
}
示例#10
0
void
Camera::LookAt(const Point& target)
{
    // No navel gazing:
    if (target == Pos())
    return;

    Point tgt, tmp = target - Pos();

    // Rotate into the view orientation:
    tgt.x = (tmp * vrt());
    tgt.y = (tmp * vup());
    tgt.z = (tmp * vpn());

    if (tgt.z == 0) {
        Pitch(0.5);
        Yaw(0.5);
        LookAt(target);
        return;
    }

    double az = atan(tgt.x/tgt.z);
    double el = atan(tgt.y/tgt.z);

    // if target is behind, offset by 180 degrees:
    if (tgt.z < 0)
    az -= PI;

    Pitch(-el);
    Yaw(az);

    // roll to upright position:
    double deflection = vrt().y;
    while  (fabs(deflection) > 0.001) {
        double theta = asin(deflection/vrt().length());
        Roll(-theta);

        deflection = vrt().y;
    }
}
示例#11
0
void EjectedPilotClass::SetModel(int model){
	Trotation rot;
	Tpoint pos;
	// Destroy the current bsp.
	if(drawPointer)
	{
		drawPointer->GetPosition (&pos);
		OTWDriver.RemoveObject(drawPointer, TRUE);
		drawPointer = NULL;
	}
	else
	{
		pos.x = XPos();
		pos.y = YPos();
		pos.z = ZPos();
	}

	// Set our new model.
	_model = model;
	
	// Create the new bsp.
	_rot.GetTrotation(rot);
	if ( _md[_model].bsp == VIS_GUYDIE || _md[_model].bsp == VIS_DOWN_PILOT )
	{
      if (pos.z > 0.0F)
         pos.z = 0.0F;
		drawPointer = new DrawableGuys(_md[_model].bsp, &pos, Yaw(), 1, 1.0 );
		((DrawableBSP *)drawPointer)->SetSwitchMask( 0, 1 );
		((DrawableBSP *)drawPointer)->SetSwitchMask( 1, 1 );
	}
	/*
	** edg: better to show nothing than the crappy oval shadow
	else if ( _md[_model].bsp == VIS_EJECT1  )
	{
		drawPointer = new DrawableShadowed(_md[_model].bsp, &pos, &rot, 1.0, VIS_PCHUTESH);
	}
	*/
	else 
	{
		drawPointer = new DrawableBSP(_md[_model].bsp, &pos, &rot, 1.0 );
	}
	F4Assert(drawPointer != NULL);

	// Set the label.
	if(drawPointer && strlen(_label) > 0)
	{
		drawPointer->SetLabel(_label, _labelColor);
		OTWDriver.InsertObject(drawPointer);
	}
}
void CFreeCameraController::MouseView()
{
	// if there's no velocity changed, skip the process
	glm::vec3 vel = Global::InputManager().CursorVelocity();
	if (glm::length2(vel) < glm::epsilon<float>() * glm::epsilon<float>())
		return;

	// find angular increment
	float angleYaw = vel.x * ANG_SPEED_SCALER;
	float anglePitch = vel.y * ANG_SPEED_SCALER;

	Yaw(-angleYaw);
	Pitch(-anglePitch);
}
示例#13
0
	void Camera::Update()
	{
		//更新输入
		POINT curCursorPos;
		GetCursorPos(&curCursorPos);
		static POINT lastCursorPos = curCursorPos;

		long dx = curCursorPos.x - lastCursorPos.x;
		long dy = curCursorPos.y - lastCursorPos.y;

		float yawDelta = 0, pitchDelta = 0;
		if(dx) yawDelta = -dx/5.0f;
		if(dy) pitchDelta = -dy/5.0f;

		lastCursorPos = curCursorPos;

		if(!m_bActive)
			return;

		//相机旋转
		if(dx)
		{
			Yaw(yawDelta);
		}
		if(dy)
		{
			MAT44 rotX;
			rotX.FromAxisAngle(VEC3::UNIT_X, pitchDelta);
			//pitch
			m_matRot = Common::Multiply_Mat44_By_Mat44(m_matRot, rotX);
		}

		//相机移动
		VEC4 forward = GetDirection();
		VEC4 right = GetRight();

		forward = Common::Multiply_Vec4_By_K(forward, m_moveSpeed);
		right = Common::Multiply_Vec4_By_K(right, m_moveSpeed);
		
		if(GetAsyncKeyState('W') < 0)		m_viewPt = Add_Vec4_By_Vec4(m_viewPt, forward);
		else if(GetAsyncKeyState('S') < 0)	m_viewPt = Sub_Vec4_By_Vec4(m_viewPt, forward);
		if(GetAsyncKeyState('A') < 0)		m_viewPt = Sub_Vec4_By_Vec4(m_viewPt, right);
		else if(GetAsyncKeyState('D') < 0)	m_viewPt = Add_Vec4_By_Vec4(m_viewPt, right);

		m_viewPt.w = 1;

		_BuildViewMatrix();
		_BuildProjMatrix();
	}
示例#14
0
void Camera::Rotation(const D3DXVECTOR2& mouseDir, float speed, bool isMouseDown)
{
    if(isMouseDown)
    {
        if(mouseDir.x != 0.0f)
        {
            Yaw(mouseDir.x < 0.0f ? speed : -speed);
            m_cameraNeedsUpdate = true;
        }

        if(mouseDir.y != 0.0f)
        {
            Pitch(mouseDir.y < 0.0f ? speed : -speed);
            m_cameraNeedsUpdate = true;
        }
    }
}
示例#15
0
hMatrix Tool_Position(double roll, double pitch, double yaw){
	hMatrix Yaw(3,3), Pitch(3,3), Roll(3,3), temp(3,3);
	double roll_data[9] =  {1,	0,	0,
							0,cos(roll),-sin(roll),
							0,sin(roll),cos(roll)};

	double pitch_data[9] =  {cos(pitch),0,sin(pitch),
							0,	1,	0,
							-sin(pitch),0,cos(pitch)};
	double yaw_data[9] =  {cos(yaw),-sin(yaw),	0,
							sin(yaw),cos(yaw),0,
							0,0,1};
	Roll.SET(3,3,&roll_data[0]);
	Pitch.SET(3,3,&pitch_data[0]);
	Yaw.SET(3,3,&yaw_data[0]);

	temp = Yaw*Pitch;

	return temp*Roll;
}
示例#16
0
bool
Camera::Padlock(const Point& target, double alimit, double e_lo, double e_hi)
{
    // No navel gazing:
    if (target == Pos())
    return false;

    Point tgt, tmp = target - Pos();

    // Rotate into the view orientation:
    tgt.x = (tmp * vrt());
    tgt.y = (tmp * vup());
    tgt.z = (tmp * vpn());

    if (tgt.z == 0) {
        Yaw(0.1);

        tgt.x = (tmp * vrt());
        tgt.y = (tmp * vup());
        tgt.z = (tmp * vpn());

        if (tgt.z == 0)
        return false;
    }

    bool   locked  = true;
    double az      = atan(tgt.x/tgt.z);
    double orig    = az;

    // if target is behind, offset by 180 degrees:
    if (tgt.z < 0)
    az -= PI;

    while (az >  PI) az -= 2*PI;
    while (az < -PI) az += 2*PI;

    if (alimit > 0) {
        if (az < -alimit) {
            az = -alimit;
            locked = false;
        }
        else if (az > alimit) {
            az = alimit;
            locked = false;
        }
    }

    Yaw(az);

    // Rotate into the new view orientation:
    tgt.x = (tmp * vrt());
    tgt.y = (tmp * vup());
    tgt.z = (tmp * vpn());

    double el      = atan(tgt.y/tgt.z);

    if (e_lo > 0 && el < -e_lo) {
        el = -e_lo;
        locked = false;
    }

    else if (e_hi > 0 && el > e_hi) {
        el = e_hi;
        locked = false;
    }

    Pitch(-el);

    return locked;
}
示例#17
0
void FPcamera::Update(double dt, float heightOffset)
{
	if(myKeys['w'])
	{
		if(myKeys['z'])
		{
			if (!m_bJumping)
			{
				Run(dt, heightOffset);
			}
			else
			{
				Walk(dt, heightOffset);
			}
			myKeys['z'] = false;
		}
		else
		{
			Walk(dt, heightOffset);
		}
		myKeys['w'] = false;
	}

	if(myKeys['s'])
	{
		if(myKeys['z'])
		{
			Run(-dt, heightOffset);
			myKeys['z'] = false;
		}
		else
		{
			Walk(-dt, heightOffset);
		}
		myKeys['s'] = false;
	}

	if(myKeys['a'])
	{
		Strafe(-dt, heightOffset);
		myKeys['a'] = false;
	}

	if(myKeys['d'])
	{
		Strafe(dt, heightOffset);
		myKeys['d'] = false;
	}

	if(myKeys['q'])
	{
		moveUp(dt, 5.f);
		myKeys['q'] = false;
	}

	if(myKeys['e'])
	{
		moveDown(dt, 5.f);
		myKeys['e'] = false;
	}

	if(myKeys[32])
	{
		Jump(dt);
		myKeys[32] = false;
	}

	if(myKeys['c'])
	{
		m_bCrouching = true;
		Crouch(dt, heightOffset);
		myKeys['c'] = false;
	}

	else
	{
		m_bCrouching = false;
		Crouch(-dt, heightOffset);
	}

	if(m_bRecoil)
	{
		static float timer = 0.f;

		lookUp(dt, 20.f);
		timer += (float)dt;

		if (timer >= 0.1f)
		{
			m_bRecoil = false;
			timer = 0.f;
		}
	}

	else if (!m_bRecoil && recoil > 0.f)
	{
		lookDown(dt, 20.f);
	}

	UpdateJump(dt, heightOffset);

	if(Application::camera_pitch != 0)
	{
		Pitch(dt);
	}
	if(Application::camera_yaw != 0)
	{
		Yaw(dt);
	}

	if(myKeys['r'])
	{
		Reset();
		myKeys['r'] = false;
	}
}
示例#18
0
int GroundClass::Wake(void)
{
	if (IsAwake()){ return 0; }
	SimVehicleClass::Wake();

	Tpoint pos;
	int retval = 0;

	if (Sms) {
		Sms->AddWeaponGraphics();
	}

	// Pick a groupId. KCK: Is this even being used?
	groupId = GetCampaignObject()->Id().num_;

	if ( !gai->rank ){
		drawPointer->SetLabel ("", 0xff00ff00);
	}

	// edg: I'm not sure if drawpointer has valid position yet?
	drawPointer->GetPosition( &pos );
    SetPosition (XPos(), YPos(), pos.z - 0.7f );
	ShiAssert(XPos() > 0.0F && YPos() > 0.0F )

	// determine if its a foot squad or not -- Real thinking done in addobj.cpp
	isFootSquad = (drawPointer->GetClass() == DrawableObject::Guys);

	// Determine if this vehicle has a truck and create it, if needed
	if (drawPointer && isTowed){
		// Place truck 20 feet behind us
		Tpoint		simView;
		int			vistype;
		mlTrig		trig;
		int tracktorType;

		// RV - Biker - Make the tracktor random
		tracktorType = (rand() % 3);
		bool teamUs = (
			TeamInfo[GetCountry()] && (
				TeamInfo[GetCountry()]->equipment == toe_us || TeamInfo[GetCountry()]->equipment == toe_rok
			)
		);
		int vtIdx;
		switch (tracktorType){
			case 0: 
				vtIdx =  teamUs ? F4_GENERIC_US_TRUCK_TYPE_SMALL   : F4_GENERIC_OPFOR_TRUCK_TYPE_SMALL;   
			break;
			case 1: 
				vtIdx =  teamUs ? F4_GENERIC_US_TRUCK_TYPE_LARGE   : F4_GENERIC_OPFOR_TRUCK_TYPE_LARGE;   
			break;
			default: 
				vtIdx = teamUs ? F4_GENERIC_US_TRUCK_TYPE_TRAILER : F4_GENERIC_OPFOR_TRUCK_TYPE_TRAILER; 
			break;
		}
		vistype = Falcon4ClassTable[vtIdx].visType[Status() & VIS_TYPE_MASK];

		mlSinCos (&trig, Yaw());
		simView.x = XPos()-20.0F*trig.cos;
		simView.y = YPos()-20.0F*trig.sin;
		simView.z = ZPos();
		if (vistype > 0){
			truckDrawable = new DrawableGroundVehicle(vistype, &simView, Yaw()+PI, drawPointer->GetScale());
		}
	}

	// when we wake the object, default it to not labeled unless
	// it's the main guy
	if (drawPointer && gai->rank != GNDAI_BATTALION_COMMANDER){
		drawPointer->SetLabel ("", 0xff00ff00);		// Don't label
		SetLocalFlag(NOT_LABELED);
	}

	return retval;
}
示例#19
0
void GroundClass::Init(SimInitDataClass* initData)
{
	SimVehicleClass::Init(initData);

	float nextX, nextY;
	float range, velocity;
	float wp1X, wp1Y, wp1Z;
	float wp2X, wp2Y, wp2Z;
	int i;
	WayPointClass* atWaypoint;
	mlTrig trig;
	VehicleClassDataType* vc;

	vc = GetVehicleClassData(Type() - VU_LAST_ENTITY_TYPE);

    // dustTrail = new DrawableTrail(TRAIL_DUST);
	isFootSquad		= FALSE;
	isEmitter		= FALSE;
	needKeepAlive	= FALSE;

	hasCrew			= (vc->Flags & VEH_HAS_CREW)		? TRUE : FALSE;
	isTowed			= (vc->Flags & VEH_IS_TOWED)		? TRUE : FALSE;
	isShip			= (GetDomain() == DOMAIN_SEA)		? TRUE : FALSE;

	// RV - Biker
	radarDown = false;

	// check for radar emitter
	if ( vc->RadarType != RDR_NO_RADAR ){
		isEmitter = TRUE;
	}

	// 2002-01-20 ADDED BY S.G. At time of creation, 
	// the radar will take the mode of the battalion instead of being 
	// off until it finds a target by itself (and can it find it if its radar is off!).
    // SimVehicleClass::Init created the radar so it's safe to do it here...
	if (isEmitter) {
		if (GetCampaignObject()->GetRadarMode() != FEC_RADAR_OFF) {
			RadarClass *radar = NULL;
			radar = (RadarClass*)FindSensor( this, SensorClass::Radar );
			ShiAssert( radar );
			radar->SetEmitting(TRUE);

			
			// 2002-04-22 MN last fix for FalconSP3 - 
			//this was a good intention to keep a 2D target targetted by a deaggregating unit,
			// however - it doesn't work this way. 
			//The campaign air target derived falconentity does not correlate with the deaggregated aircraft.
			// The SAM's radars would stay stuck at TRACK S1 or 
			//TRACK S3 and won't engage. Symptom was the not changing range to the target (.label 4)
			// Now with this code removed, SAMs should work correctly again. 
			//As we have large SAM bubble sizes - it doesn't really matter if we
			// need to go through all search states in the SIM again - 
			//because SAM's are faster in GUIDE mode than in maximum missile range.
			if (g_bSAM2D3DHandover)
			{
				// 2002-03-21 ADDED BY S.G. In addition, we need to set our radar's target RFN 
				//(right f*cking now) and run a sensor sweep on it so it's valid by the 
				//time TargetProcessing is called.
				FalconEntity	*campTargetEntity = ((UnitClass *)GetCampaignObject())->GetAirTarget();
				if (campTargetEntity)
				{
					SetTarget( new SimObjectType(campTargetEntity) );
					CalcRelAzElRangeAta(this, targetPtr);
					radar->SetDesiredTarget(targetPtr);
					radar->SetFlag(RadarClass::FirstSweep);
					radar->Exec(targetList);
				}				
			}
		}
	}

	SetFlag(ON_GROUND);
	SetPowerOutput(1.0F);	// Assume our motor is running all the time

	SetPosition (initData->x, initData->y, OTWDriver.GetGroundLevel(initData->x, initData->y));
	SetYPR(initData->heading, 0.0F, 0.0F);

	SetupGNDAI (initData);
    
	if (initData->ptIndex){
		// Don't move if we've got an assigned point
		gai->moveState = GNDAI_MOVE_HALTED;
		gai->moveFlags |= GNDAI_MOVE_FIXED_POSITIONS;
	}

	CalcTransformMatrix (this);

	strength        = 100.0F;

	// Check for Campaign mode
	// we don't follow waypoints here
	switch (gai->moveState)
	{
		case GNDAI_MOVE_GENERAL:
		{
			waypoint = curWaypoint = NULL;
			numWaypoints = 0;
			DeleteWPList(initData->waypointList);
			InitFromCampaignUnit();
		}
		break;
		case GNDAI_MOVE_WAYPOINT:
		{
			waypoint        = initData->waypointList;
			numWaypoints    = initData->numWaypoints;
			curWaypoint     = waypoint;
			if (curWaypoint)
			{
				// Corrent initial heading/velocity
				// Find the waypoint to go to.
				atWaypoint = curWaypoint;
				for (i=0; i<initData->currentWaypoint; i++)
				{
					atWaypoint = curWaypoint;
					curWaypoint = curWaypoint->GetNextWP();
				}

				// If current is the on we're at, set for the next one.
				if (curWaypoint == atWaypoint)
					curWaypoint = curWaypoint->GetNextWP();

				atWaypoint->GetLocation (&wp1X, &wp1Y, &wp1Z);

				if (curWaypoint == NULL)
				{
					wp1X = initData->x;
					wp1Y = initData->y;
					curWaypoint = atWaypoint;
					SetDelta (0.0F, 0.0F, 0.0F);
					SetYPRDelta (0.0F, 0.0F, 0.0F);
				}
				else {
					curWaypoint->GetLocation (&wp2X, &wp2Y, &wp2Z);

					SetYPR ((float)atan2 (wp2Y - wp1Y, wp2X - wp1X), 0.0F, 0.0F);

					nextX = wp2X;
					nextY = wp2Y;

					range = (float)sqrt((wp1X - nextX) * (wp1X - nextX) + (wp1Y - nextY) * (wp1Y - nextY));
					velocity = range / ((curWaypoint->GetWPArrivalTime() - SimLibElapsedTime) / SEC_TO_MSEC);

					if ((curWaypoint->GetWPArrivalTime() - SimLibElapsedTime) < 1 * SEC_TO_MSEC)
						velocity = 0.0F;

					// sfr: no need for this anymore
					//SetVt(velocity);
					//SetKias(velocity * FTPSEC_TO_KNOTS);
					mlSinCos (&trig, Yaw());
					SetDelta (velocity * trig.cos, velocity * trig.sin, 0.0F);
					SetYPRDelta (0.0F, 0.0F, 0.0F);
				}
			}
		}
		break;
		default:
		{
			SetDelta (0.0F, 0.0F, 0.0F);
			// sfr: no need for this anymore
			//SetVt(0.0F);
			//SetKias(0.0F);
			SetYPRDelta (0.0F, 0.0F, 0.0F);
			gai->moveState = GNDAI_MOVE_HALTED;
			waypoint = curWaypoint = NULL;
			numWaypoints = 0;
			DeleteWPList(initData->waypointList);
			InitFromCampaignUnit();
		}
		break;
	}

	theInputs   = new PilotInputs;

	// Create our SMS
	Sms = new SMSBaseClass (this, initData->weapon,initData->weapons);

	uchar dam[10] = {100};
	for (i = 0; i < 10; i++){
		dam[i] = 100;
	}
	Sms->SelectBestWeapon (dam, LowAir, -1);
	if (Sms->CurHardpoint() != -1){
		isAirCapable = TRUE;
	}
	else{
		isAirCapable = FALSE;
	}

	Sms->SelectBestWeapon (dam, NoMove, -1);
	if (Sms->CurHardpoint() != -1){
		isGroundCapable = TRUE;
	}
	else {
		isGroundCapable = FALSE;
	}
	Sms->SetCurHardpoint(-1);

	if ((GetType() == TYPE_WHEELED && GetSType() == STYPE_WHEELED_AIR_DEFENSE) ||
		(GetType() == TYPE_WHEELED && GetSType() == STYPE_WHEELED_AAA) ||
		(GetType() == TYPE_TRACKED && GetSType() == STYPE_TRACKED_AIR_DEFENSE) ||
		(GetType() == TYPE_TRACKED && GetSType() == STYPE_TRACKED_AAA) ||
		(GetType() == TYPE_TOWED && GetSType() == STYPE_TOWED_AAA))
	{
		isAirDefense = TRUE;
		// If we're an airdefense thingy, elevate our gun, and point in a random direction
		SetDOF(AIRDEF_ELEV, 60.0f * DTR);
		SetDOF(AIRDEF_ELEV2, 60.0f * DTR);
		SetDOF(AIRDEF_AZIMUTH, 180.0F*DTR - rand()/(float)RAND_MAX * 360.0F*DTR);
	}
	else{
		isAirDefense = FALSE;
	}
}
示例#20
0
/*** Procesamiento de los dispositivos de entrada ***/
void Input( float elapsed )
{
    SDL_Event event;
    /* Proceso los eventos de input hasta que no haya más */
    while( SDL_PollEvent( &event ) )
    {
        switch( event.type )
        {
            case SDL_KEYUP:
                switch( event.key.keysym.sym )
            {
                case SDLK_ESCAPE:
                    g_ExitProgram = GL_TRUE;
                    break;
                case SDLK_F6:
                    CreateScreenshot( "Ejercicio" );
                    break;
                case SDLK_w:
                    cam.walk = GL_FALSE;
                    break;
                case SDLK_s:
                    cam.walkinv= GL_FALSE;
                    break;
                    
                case SDLK_d:
                    cam.strafe= GL_FALSE;
                    break;
                    
                case SDLK_a:
                    cam.strafeinv= GL_FALSE;
                    break;

                    
                    
                case SDLK_LSHIFT:
                    Brun = GL_FALSE;
                    break;
                case SDLK_SPACE:
                    jump = GL_FALSE;
                    break;
                    
                    
                    
                    
                    
                default:
                    PrintError( "Unhandled KEYUP event", GL_TRUE );
            }
                break;
                
            case SDL_KEYDOWN:
                switch( event.key.keysym.sym )
            {
                case SDLK_ESCAPE:
                    break;
                case SDLK_F6:
                    break;
                case SDLK_w:
                    cam.walk = GL_TRUE;
                    break;
                case SDLK_s:
                    cam.walkinv = GL_TRUE;
                    break;
                    
                case SDLK_d:
                    cam.strafe= GL_TRUE;
                    break;
                    
                case SDLK_a:
                    cam.strafeinv= GL_TRUE;
                    break;
                    

                    
                case SDLK_LSHIFT:
                    Brun = GL_TRUE;
                    
                    break;
                    
                case SDLK_SPACE:
                    jump = GL_TRUE;
                    break;
                    
                    
                default:
                    PrintError( "Unhandled KEYDOWN event", GL_TRUE );
            }
                break;
                
                /* Botones del mouse */
            case SDL_MOUSEBUTTONUP:
                switch( event.button.button )
            {
                case SDL_BUTTON_LEFT:
                    break;
                case SDL_BUTTON_RIGHT:
                    renderUnderwater = !renderUnderwater;
                    break;
                default:
                    PrintError( "Unhandled MOUSEBUTTONUP event", GL_TRUE );
            }
                break;
                
            case SDL_MOUSEBUTTONDOWN:
                switch( event.button.button )
            {
                case SDL_BUTTON_LEFT:
                    atk1 = GL_TRUE;
                    
                    break;
                default:
                    PrintError( "Unhandled MOUSEBUTTONDOWN event", GL_TRUE );
            }
                break;
                
                
                /* Movimiento del mouse */
            case SDL_MOUSEMOTION:
            {
                /* Capturo los movimientos */
                GLfloat xrel, yrel;
                xrel = (GLfloat)event.motion.xrel;
                yrel = (GLfloat)event.motion.yrel;
                
                if(xrel !=0 && xrel> -100 && xrel < 100)
                    Yaw(&cam,xrel*elapsed*sensibility,GL_TRUE);
                if(yrel !=0 && yrel> -100 && yrel < 100)
                    Pitch(&cam,yrel*elapsed*sensibility,GL_TRUE);
            }
                break;
                
            default:
                PrintError( "Unhandled type of event", GL_TRUE );
        }
        
        /* Borro el mensaje para evitar procesarlo de nuevo */
        memset( &event, 0, sizeof(SDL_Event) );
    }
}
示例#21
0
/*
** GroundClass Exec() function.
** NOTE: returns TRUE if we've processed this frame.  FALSE if we're to do
** dead reckoning (in VU)
*/
int GroundClass::Exec (void)
{
	//RV - I-Hawk - Added a 0 vector for RV new PS calls
	Tpoint PSvec;
	PSvec.x = 0;
	PSvec.y = 0;
	PSvec.z = 0;

	Tpoint pos;
    Tpoint vec;
	float speedScale;
	float groundZ;
	float	labelLOD;
	float	drawLOD;
	RadarClass *radar = NULL;
	
	SoundPos.UpdatePos((SimBaseClass *)this);

	//Cobra
	pos.x = 0.0f;
	pos.y = 0.0f;
	pos.z = 0.0f;
	
	// MLR 5/23/2004 -
	pos.x = XPos();
	pos.y = YPos();
	pos.z = OTWDriver.GetApproxGroundLevel( pos.x, pos.y );
//	pos.z = -10.0f;//Cobra trying to fix the stupid uninit CTD
	SetPosition(pos.x, pos.y, pos.z);

	// dead? -- we do nothing
	if ( IsDead() ){
		return FALSE;
	}

    // if damaged 
	if ( pctStrength < 0.5f ){
		if (sfxTimer > 1.5f - gai->distLOD * 1.3){
			// reset the timer
			sfxTimer = 0.0f;
			pos.z -= 10.0f;

			// VP_changes this shoud be checked why have GetGroundLevel been subtracted by 10.0F
			// Sometimes the trails seem strange
			vec.x = PRANDFloat() * 20.0f;
			vec.y = PRANDFloat() * 20.0f;
			vec.z = PRANDFloat() * 20.0f;
			
			/*
			OTWDriver.AddSfxRequest(
				new SfxClass(
					SFX_TRAILSMOKE,			// type
					SFX_MOVES | SFX_NO_GROUND_CHECK,						// flags
					&pos,							// world pos
					&vec,							// vector
					3.5f,							// time to live
					4.5f					// scale
				)
			);
					*/
			DrawableParticleSys::PS_AddParticleEx((SFX_TRAILSMOKE + 1),
									&pos,
									&vec);
			
		}
	}
	
	if (IsExploding()){
		// KCK: I've never seen this section of code executed. Maybe it gets hit, but I doubt
		// it.
		if (!IsSetFlag( SHOW_EXPLOSION )){
			// Show the explosion
			Tpoint pos, vec;
			Falcon4EntityClassType *classPtr = (Falcon4EntityClassType *)EntityType();
			//DrawableGroundVehicle *destroyedPtr; // FRB

			//Cobra TJL 11/07/04 CTD point initialize here
			pos.x = 0.0f;
			pos.y = 0.0f;
			pos.z = 0.0f;
			
			// MLR 5/23/2004 - uncommented out the x, y
			pos.x = XPos();
			pos.y = YPos();
			pos.z = OTWDriver.GetApproxGroundLevel( pos.x, pos.y ) - 10.0f;
			
			vec.x = 0.0f;
			vec.y = 0.0f;
			vec.z = 0.0f;
			
			// create a new drawable for destroyed vehicle
			// sometimes.....

           //RV - I-Hawk - Commenting all this if statement... not necessary

			/*
			if ( rand() & 1 ){
				destroyedPtr = new DrawableGroundVehicle(
					classPtr->visType[3],
					&pos,
					Yaw(),
					1.0f 
				);
				
				groundZ = PRANDFloatPos() * 60.0f + 15.0f;
				
				/*
				OTWDriver.AddSfxRequest(
					new SfxClass (
						SFX_BURNING_PART,				// type
						&pos,							// world pos
						&vec,							// 
						(DrawableBSP *)destroyedPtr,
						groundZ,							// time to live
						1.0f 	// scale
					)
				);	
						*/
			/*
				DrawableParticleSys::PS_AddParticleEx((SFX_BURNING_PART + 1),
									&pos,
									&vec);
				
				
				pos.z += 10.0f;
				/*
				OTWDriver.AddSfxRequest(
					new SfxClass(
						SFX_FEATURE_EXPLOSION,				// type
						&pos,							// world pos
						groundZ,							// time to live
						100.0f 		// scale
					) 
				);
						*/
			/*
				DrawableParticleSys::PS_AddParticleEx((SFX_FEATURE_EXPLOSION + 1),
									&pos,
									&PSvec);

			}
			*/
			//RV - I-Hawk - seperating explosion type for ground/sea domains. also
			//adding a check so soldiers will not explode like ground vehicles...

            if (GetDomain() == DOMAIN_LAND && GetType() != TYPE_FOOT)
			{		
				//pos.z -= 20.0f;
				/*
				OTWDriver.AddSfxRequest(
					new SfxClass(
						SFX_VEHICLE_EXPLOSION,				// type
						&pos,							// world pos
						1.5f,							// time to live
						100.0f 		// scale
					)
				);
					*/
				DrawableParticleSys::PS_AddParticleEx((SFX_VEHICLE_EXPLOSION + 1),
										&pos,
										&PSvec);
			}
			else if ( GetDomain() == DOMAIN_SEA )
			{
				DrawableParticleSys::PS_AddParticleEx((SFX_WATER_FIREBALL + 1),
										&pos,
										&PSvec);
			}

			// make sure we don't do it again...
			SetFlag( SHOW_EXPLOSION );
			
			// we can now kill it immediately
			SetDead(TRUE);  
		}
		return FALSE;
	}
	
	// exec any base functionality
	SimVehicleClass::Exec();
	
	// Sept 30, 2002
	// VP_changes: Frequently Z value is not in the correct place. It should follow the terrain.
	if ( drawPointer ){
		drawPointer->GetPosition( &pos );
	}
	else {
		return FALSE;
	}

	//JAM 27Sep03 - Let's try this
	groundZ = pos.z;		// - 0.7f; KCK: WTF is this?

	//VP_changes Sept 25
	groundZ = OTWDriver.GetGroundLevel( pos.x, pos.y );


	// Movement/Targeting for local entities
	if (IsLocal() && SimDriver.MotionOn())
	{
		//I commented this out, because it is done in gai->ProcessTargeting down below DSP 4/30/99
		// Refresh our target pointer (if any)
		//SetTarget( SimCampHandoff( targetPtr, targetList, HANDOFF_RANDOM ) );
		// Look for someone to do radar fire control for us
		FindBattalionFireControl();

		// RV - Biker - Switch on lights for ground/naval vehicles
		int isNight = TimeOfDayGeneral(TheCampaign.CurrentTime) < TOD_DAWNDUSK ? true : false;

		if (drawPointer && ((DrawableBSP *)drawPointer)->GetNumSwitches() >= AIRDEF_LIGHT_SWITCH) 
		{
			if (isShip) 
			{
				isNight = (TimeOfDayGeneral(TheCampaign.CurrentTime) <= TOD_DAWNDUSK || realWeather->weatherCondition == INCLEMENT) ? true : false;

				if (pctStrength > 0.50f) 
				{
					((DrawableBSP *)drawPointer)->SetSwitchMask(0, isNight);
					((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight);
				}
			}
			else if (GetVt() > 1.0f) 
			{
				VuListIterator	vehicleWalker(SimDriver.combinedList);
				FalconEntity* object = (FalconEntity*)vehicleWalker.GetFirst();
				bool hasThreat = false;
				float range = 999.9f * NM_TO_FT;

				// Consider each potential target in our environment
				while (object && !hasThreat) 
				{
					// Skip sleeping sim objects
					if (object->IsSim()) 
					{
						if (!((SimBaseClass*)object)->IsAwake()) 
						{
							object = (FalconEntity*)vehicleWalker.GetNext();
							continue;
						}
					}

					// Fow now we skip missles -- might want to display them eventually...
					if (object->IsMissile() || object->IsBomb()) 
					{
						object = (FalconEntity*)vehicleWalker.GetNext();
						continue;
					}

					if (object->GetTeam() == GetTeam()) 
					{
						object = (FalconEntity*)vehicleWalker.GetNext();
						continue;
					}

					float dx = object->XPos() - XPos();
					float dy = object->YPos() - YPos();
					float dz = object->ZPos() - ZPos();

					range = (float)sqrt(dx*dx + dy*dy + dz*dz);

					if (range < 5.0f * NM_TO_FT)
						hasThreat = true;

					object = (FalconEntity*)vehicleWalker.GetNext();
				}

				// If no enemy nearby and not heavy damaged switch on lights
				if (!hasThreat && pctStrength > 0.75f) {
					((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight);
				}
				else 
				{
					((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0);
				}	
			}
			else 
			{
				((DrawableBSP *)drawPointer)->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0);
			}
		}

		// RV - Biker - Do also switch on lights for tractor vehicles
		if (truckDrawable && truckDrawable->GetNumSwitches() >= AIRDEF_LIGHT_SWITCH) 
		{
			if (GetVt() > 1.0f) 
			{
				VuListIterator	vehicleWalker(SimDriver.combinedList);
				FalconEntity* object = (FalconEntity*)vehicleWalker.GetFirst();
				bool hasThreat = false;
				float range = 999.9f * NM_TO_FT;

				// Consider each potential target in our environment
				while (object && !hasThreat) 
				{
					// Skip sleeping sim objects
					if (object->IsSim()) 
					{
						if (!((SimBaseClass*)object)->IsAwake()) 
						{
							object = (FalconEntity*)vehicleWalker.GetNext();
							continue;
						}
					}

					// Fow now we skip missles -- might want to display them eventually...
					if (object->IsMissile() || object->IsBomb()) 
					{
						object = (FalconEntity*)vehicleWalker.GetNext();
						continue;
					}

					if (object->GetTeam() == GetTeam()) 
					{
						object = (FalconEntity*)vehicleWalker.GetNext();
						continue;
					}

					float dx = object->XPos() - XPos();
					float dy = object->YPos() - YPos();
					float dz = object->ZPos() - ZPos();

					range = (float)sqrt(dx*dx + dy*dy + dz*dz);

					if (range < 5.0f * NM_TO_FT)
						hasThreat = true;

					object = (FalconEntity*)vehicleWalker.GetNext();
				}

				// If no enemy nearby and not heavy damaged switch on lights
				if (!hasThreat && pctStrength > 0.75f) {
					truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, isNight);
				}
				else 
				{
					truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0);
				}
			}
			else 
			{
				truckDrawable->SetSwitchMask(AIRDEF_LIGHT_SWITCH, 0);
			}
		}
		
		// RV - Biker - Shut down ship radar if damaged
		if (isShip && radarDown == false && pctStrength < 0.9f && rand()%50 > (pctStrength - 0.50f)*100) 
		{
			isEmitter = false;
			RadarClass *radar = (RadarClass*)FindSensor(this, SensorClass::Radar);
			if (radar) 
			{
				radarDown = true;
				radar->SetDesiredTarget(NULL);
				radar->SetEmitting(FALSE);
			}

			if (targetPtr) 
			{
				SelectWeapon(true);
			}
		}
		
		// 2001-03-26 ADDED BY S.G. NEED TO KNOW IF THE RADAR CALLED SetSpotted
		// RV - Biker - Rotate radars
		float deltaDOF;
		float curDOF = GetDOFValue(5);
		
		deltaDOF = 180.0f * DTR * SimLibMajorFrameTime;
		curDOF += deltaDOF;
		
		if ( curDOF > 360.0f * DTR )
	  		curDOF -= 360.0f * DTR;

		SetDOF(5, curDOF);
		int spottedSet = FALSE;
		// END OF ADDED SECTION

		// 2002-03-21 ADDED BY S.G. 
		// If localData only has zeros, 
		// there is a good chance they are not valid (should not happen here though)... 
		if (targetPtr) {
			SimObjectLocalData* localData= targetPtr->localData;
			if (
				localData->ataFrom == 0.0f && 
				localData->az == 0.0f  && 
				localData->el == 0.0f && 
				localData->range == 0.0f
			) {
				CalcRelAzElRangeAta(this, targetPtr);
			}
		}
		// END OF ADDED SECTION 2002-03-21

		// check for sending radar emmisions
		// 2002-02-26 MODIFIED BY S.G.
		// Added the nextTargetUpdate check to prevent the radar code to run on every frame!
		if ( isEmitter && nextTargetUpdate < SimLibElapsedTime){
			// 2002-02-26 ADDED BY S.G. Next radar scan is 1 sec for aces, 2 for vets, etc ...
			nextTargetUpdate = SimLibElapsedTime + (5 - gai->skillLevel) * SEC_TO_MSEC; 

			radar = (RadarClass*)FindSensor( this, SensorClass::Radar );
			ShiAssert( radar );
			if (radar){
				radar->Exec( targetList );
			}

			// 2001-03-26 ADDED BY S.G. 
			// IF WE CAN SEE THE RADAR'S TARGET AND WE ARE A AIR DEFENSE THINGY 
			// NOT IN A BKOGEN MORAL STATE, MARK IT AS SPOTTED IF WE'RE BRIGHT ENOUGH
			if (
				radar && 
				radar->CurrentTarget() && 
				gai->skillLevel >= 3 && 
				((UnitClass *)GetCampaignObject())->GetSType() == STYPE_UNIT_AIR_DEFENSE && 
				!((UnitClass *)GetCampaignObject())->Broken()
			){
				CampBaseClass *campBaseObj;
				if (radar->CurrentTarget()->BaseData()->IsSim()){
					campBaseObj = ((SimBaseClass *)radar->CurrentTarget()->BaseData())->GetCampaignObject();
				}
				else{
					campBaseObj = (CampBaseClass *)radar->CurrentTarget()->BaseData();
				}

				// JB 011002 If campBaseObj is NULL the target may be chaff
				if (campBaseObj && !(campBaseObj->GetSpotted(GetTeam())) && campBaseObj->IsFlight()){
					RequestIntercept((FlightClass *)campBaseObj, GetTeam());
				}

				spottedSet = TRUE;
				if (campBaseObj && radar->GetRadarDatFile()){
					campBaseObj->SetSpotted(
						GetTeam(), TheCampaign.CurrentTime, 
						(radar->radarData->flag & RAD_NCTR) != 0 && 
						radar->CurrentTarget()->localData && 
						radar->CurrentTarget()->localData->ataFrom < 45.0f * DTR && 
						radar->CurrentTarget()->localData->range < 
						radar->GetRadarDatFile()->MaxNctrRange / (2.0f * (16.0f - (float)gai->skillLevel) / 16.0f)
					);
				}
				// 2002-03-05 MODIFIED BY S.G. target's aspect and skill used in the equation
			}
		// END OF ADDED SECTION
		}

		// 2001-03-26 ADDED BY S.G. 
		// IF THE BATTALION LEAD HAS LOS 
		// ON IT AND WE ARE A AIR DEFENSE THINGY NOT IN A BKOGEN MORAL STATE, 
		// MARK IT AS SPOTTED IF WE'RE BRIGHT ENOUGH
		// 2002-02-11 MODIFED BY S.G. 
		// Since I only identify visually, need to perform this even if spotted by radar in case I can ID it.
		if (
			/*!spottedSet &&  gai->skillLevel >= 3 && */
			((UnitClass *)GetCampaignObject())->GetSType() == STYPE_UNIT_AIR_DEFENSE && 
			gai == gai->battalionCommand && 
			!((UnitClass *)GetCampaignObject())->Broken() && 
			gai->GetAirTargetPtr() && 
			CheckLOS(gai->GetAirTargetPtr())
		){
			CampBaseClass *campBaseObj;
			if (gai->GetAirTargetPtr()->BaseData()->IsSim())
				campBaseObj = ((SimBaseClass *)gai->GetAirTargetPtr()->BaseData())->GetCampaignObject();
			else
				campBaseObj = (CampBaseClass *)gai->GetAirTargetPtr()->BaseData();

			// JB 011002 If campBaseObj is NULL the target may be chaff

			if (!spottedSet && campBaseObj && !(campBaseObj->GetSpotted(GetTeam())) && campBaseObj->IsFlight())
				RequestIntercept((FlightClass *)campBaseObj, GetTeam());

			if (campBaseObj)
				campBaseObj->SetSpotted(GetTeam(),TheCampaign.CurrentTime, 1);
				// 2002-02-11 MODIFIED BY S.G. Visual detection means identified as well
		}
		// END OF ADDED SECTION

		// KCK: When should we run a target update cycle?
		if (SimLibElapsedTime > lastProcess){
			gai->ProcessTargeting();
			lastProcess = SimLibElapsedTime + processRate;
		}

		// KCK: Check if it's ok to think
		if (SimLibElapsedTime > lastThought ){
			// do movement and (possibly) firing....
			gai->Process ();
			lastThought = SimLibElapsedTime + thoughtRate;
		}

		// RV - Biker - Only allow SAM fire if radar still does work
		SimWeaponClass *theWeapon = Sms->GetCurrentWeapon();

		// FRB - This version seems to give SAMs a little more activity
		if(SimLibElapsedTime > nextSamFireTime  && !allowSamFire){
			allowSamFire = TRUE;
		}

		// Biker's version
		//if(SimLibElapsedTime > nextSamFireTime  && !allowSamFire)
		//{
		//	if (radarDown == false || (theWeapon && theWeapon->IsMissile() && theWeapon->sensorArray[0]->Type() == SensorClass::IRST))
		//		allowSamFire = TRUE;
		//}

		// Move and update delta;
		gai->Move_Towards_Dest();
		
		// edg: always insure that our Z position is valid for the entity.
		// the draw pointer should have this value
		// KCK NOTE: The Z we have is actually LAST FRAME's Z. Probably not a big deal.
		SetPosition(
			XPos() + XDelta() * SimLibMajorFrameTime,
			YPos() + YDelta() * SimLibMajorFrameTime,
			groundZ 
		);
		// do firing
		// this also does weapon keep alive
		if ( Sms ){
			gai->Fire();
		}
	}

	// KCK: I simplified this some. This is now speed squared.
	speedScale = XDelta()*XDelta() + YDelta()*YDelta();
	
	// set our level of detail
	if ( gai == gai->battalionCommand ){
		gai->SetDistLOD();
	}
	else{
		gai->distLOD = gai->battalionCommand->distLOD;
	}
	
	// do some extra LOD stuff: if the unit is not a lead veh amd the
	// distLOD is less than a certain value, remove it from the draw
	// list.
	if (drawPointer && gai->rank != GNDAI_BATTALION_COMMANDER){
		// distLOD cutoff by ranking (KCK: This is explicit for testing, could be a formula/table)
		if (gai->rank & GNDAI_COMPANY_LEADER){
			labelLOD = .5F;
			drawLOD = .25F;
		}
		else if (gai->rank & GNDAI_PLATOON_LEADER){
			labelLOD = .925F;
			drawLOD = .5F;
		}
		else {
			labelLOD = 1.1F;
			drawLOD = .75F;
		}

		// RV - Biker - Why do this maybe helpful knowing which vehicle has problems
		// Determine wether to draw label or not
		if (gai->distLOD < labelLOD){
			if (!IsSetLocalFlag(NOT_LABELED)){
				drawPointer->SetLabel ("", 0xff00ff00);		// Don't label
				SetLocalFlag(NOT_LABELED);
			}
		}
		else if (IsSetLocalFlag(NOT_LABELED)){
			SetLabel(this);
			UnSetLocalFlag(NOT_LABELED);
		}

		//if (IsSetLocalFlag(NOT_LABELED)) {
		//	SetLabel(this);
		//	UnSetLocalFlag(NOT_LABELED);
		//}
	}
	
	if (!targetPtr){
		//rotate turret to be pointing forward again
		float maxAz = TURRET_ROTATE_RATE * SimLibMajorFrameTime;
		float maxEl = TURRET_ELEVATE_RATE * SimLibMajorFrameTime;
		float newEl;
		if (isAirDefense){
			newEl = 60.0F*DTR;
		}
		else {
			newEl = 0.0F;
		}

		float delta = newEl - GetDOFValue(AIRDEF_ELEV);
		if(delta > 180.0F*DTR){
			delta -= 180.0F*DTR;
		}
		else if(delta < -180.0F*DTR){
			delta += 180.0F*DTR;
		}

		// Do elevation adjustments
		if (delta > maxEl){
		    SetDOFInc(AIRDEF_ELEV, maxEl);
		}
		else if (delta < -maxEl){
		    SetDOFInc(AIRDEF_ELEV, -maxEl);
		}
		else {
		    SetDOF(AIRDEF_ELEV, newEl);
		}

		SetDOF(AIRDEF_ELEV, min(85.0F*DTR, max(GetDOFValue(AIRDEF_ELEV), 0.0F)));
		SetDOF(AIRDEF_ELEV2, GetDOFValue(AIRDEF_ELEV));
		
		delta = 0.0F - GetDOFValue(AIRDEF_AZIMUTH);
		
		if(delta > 180.0F*DTR){
		    delta -= 180.0F*DTR;
		}
		else if(delta < -180.0F*DTR){
		    delta += 180.0F*DTR;
		}
		
		// Now do the azmuth adjustments
		if (delta > maxAz){
		    SetDOFInc(AIRDEF_AZIMUTH, maxAz);
		}
		else if (delta < -maxAz){
		    SetDOFInc(AIRDEF_AZIMUTH, -maxAz);
		}
		// RV - Biker - Don't do this
		//else
		//	SetDOF(AIRDEF_AZIMUTH, 0.0F);
	}
	
	// Special shit by ground type
	if ( isFootSquad ){
		if ( speedScale > 0.0f ){
			// Couldn't this be done in the drawable class's update function???
			((DrawableGuys*)drawPointer)->SetSquadMoving( TRUE );
		}
		else {
			// Couldn't this be done in the drawable class's update function???
			((DrawableGuys*)drawPointer)->SetSquadMoving( FALSE );
		}
		
		// If we're less than 80% of the way from "FAR" toward the viewer, just draw one guy
		// otherwise, put 5 guys in a squad.
		if (gai->distLOD < 0.8f) {
			((DrawableGuys*)drawPointer)->SetNumInSquad( 1 );
		} 
		else {
			((DrawableGuys*)drawPointer)->SetNumInSquad( 5 );
		}
	} 
	// We're not a foot squad, so do the vehicle stuff
	else if ( !IsSetLocalFlag( IS_HIDDEN ) && speedScale > 300.0f )
	{
		// speedScale /= ( 900.0f * KPH_TO_FPS * KPH_TO_FPS);		// essentially 1.0F at 30 mph

	    // JPO - for engine noise
	    VehicleClassDataType *vc = GetVehicleClassData(Type() - VU_LAST_ENTITY_TYPE);
	    ShiAssert(FALSE == F4IsBadReadPtr(vc, sizeof *vc));
		// (a) Make sound:
		// everything sounds like a tank right now
		if ( GetCampaignObject()->IsBattalion() ){
		    //if (vc)
			if (vc && vc->EngineSound!=34){ // kludge prevent 34 from playing
				SoundPos.Sfx( vc->EngineSound, 0, 1.0, 0); // MLR 5/16/2004 - 
			}
			else{
				SoundPos.Sfx( SFX_TANK, 0, 1.0, 0); // MLR 5/16/2004 - 
			}
			
			// (b) Make dust
			// dustTimer += SimLibMajorFrameTime;
			// if ( dustTimer > max( 0.2f,  4.5f - speedScale - gai->distLOD * 3.3f ) )
			if ( ((rand() & 7) == 7) &&
				gSfxCount[ SFX_GROUND_DUSTCLOUD ] < gSfxLODCutoff &&
				gTotSfx < gSfxLODTotCutoff 
			){
				// reset the timer
				// dustTimer = 0.0f;
				
				pos.x += PRANDFloat() * 5.0f;
				pos.y += PRANDFloat() * 5.0f;
				pos.z = groundZ;

				// RV - Biker - Move that smoke more behind the vehicle 
				mlTrig		trig;
				mlSinCos (&trig, Yaw());

				pos.x -= 15.0f*trig.cos;
				pos.y -= 15.0f*trig.sin;

				vec.x = PRANDFloat() * 5.0f;
				vec.y = PRANDFloat() * 5.0f;
				vec.z = -20.0f;
				
				//JAM 24Oct03 - No dust trails when it's raining.
				if(realWeather->weatherCondition < INCLEMENT){
					/*
					OTWDriver.AddSfxRequest(
						new SfxClass (SFX_VEHICLE_DUST,				// type //JAM 03Oct03
	//					new SfxClass (SFX_GROUND_DUSTCLOUD,			// type
						SFX_USES_GRAVITY | SFX_NO_DOWN_VECTOR | SFX_MOVES | SFX_NO_GROUND_CHECK,
						&pos,							// world pos
						&vec,
						1.0f,							// time to live
						1.f)); //JAM 03Oct03 8.5f ));		// scale
						*/
					DrawableParticleSys::PS_AddParticleEx((SFX_VEHICLE_DUST + 1),
									&pos,
									&vec);
				}
			}
			
			// (c) Make sure we're using our 'Moving' model (i.e. Trucked artillery, APC, etc)
			if (truckDrawable){
				// Keep truck 20 feet behind us (HACK HACK)
				Tpoint		truckPos;
				mlTrig		trig;
				mlSinCos (&trig, Yaw());
				truckPos.x = XPos()-20.0F*trig.cos;
				truckPos.y = YPos()-20.0F*trig.sin;
				truckPos.z = ZPos();
				truckDrawable->Update(&truckPos, Yaw()+PI);
			}

			if (isTowed || hasCrew){
				SetSwitch(0,0x2);
			}
		}
		else // itsa task force
		{
			if (vc){
				SoundPos.Sfx( vc->EngineSound, 0, 1.0, 0);
			}
			else {
				SoundPos.Sfx( SFX_SHIP, 0, 1.0, 0);
			}
			
			//RV - I-Hawk - Do wakes only at some cases
			if ( (rand() & 7) == 7 )
			{
				//I-Hawk - not using all this anymore
				//
				// reset the timer
				// dustTimer = 0.0f;
				//float ttl;
				//static float trailspd = 5.0f;
				//static float bowfx = 0.92f;
				//static float sternfx = 0.75f;
				//float spdratio = GetVt() / ((UnitClass*)GetCampaignObject())->GetMaxSpeed();

				float radius;
				if ( drawPointer ){
					radius = drawPointer->Radius(); // JPO from 0.15 - now done inline
				}
				else{
					radius = 90.0f;
				}
				
				//I-Hawk - Fixed position for ships wakes, effect "delay" in position is 
				//handled by PS now. No more the "V shape" of water wakes.

				pos.x = XPos() + XDelta() * SimLibMajorFrameTime;
				pos.y = YPos() + YDelta() * SimLibMajorFrameTime;
				pos.z = groundZ;

				//// JPO - think this is sideways on.
				///*
				//vec.x = dmx[1][0] * spdratio * PRANDFloat() * trailspd;
				//vec.y = dmx[1][1] * spdratio * PRANDFloat() * trailspd;
				//vec.z = 0.5f; // from -20 JPO
				//*/

				//I-Hawk - More correct vector for wakes
				vec.x = XDelta();
				vec.y = YDelta();
				vec.z = 0.0f;


				//I-Hawk - Separate wake effect for different ships size
				int theSFX;
			
				if ( radius < 200.0f )
				{
					theSFX = SFX_WATER_WAKE_SMALL;
				}

				else if ( radius >= 200.0f && radius < 400.0f )
				{
					theSFX = SFX_WATER_WAKE_MEDIUM;
				}

				else if ( radius >= 400.0f )
				{
					theSFX = SFX_WATER_WAKE_LARGE;
				}
	
				//I-Hawk - The PS
				DrawableParticleSys::PS_AddParticleEx((theSFX + 1),
									&pos,
									&vec);
			}
		}
	}
	// Otherwise, we're not moving or are hidden. Do some stuff
	else {
		// (b) Make sure we're using our 'Holding' model (i.e. Unlimbered artillery, troops prone, etc)
		if (truckDrawable){
			// Once we stop, our truck doesn't move at all - but sits further away than when moving
			Tpoint truckPos;
			truckPos.x = XPos() + 40.0F;
			truckPos.y = YPos();
			truckPos.z = 0.0F;
			truckDrawable->Update(&truckPos, Yaw());
		}
		if (isTowed || hasCrew){
			SetSwitch(0,0x1);
		}
	}
	
	// ACMI Output
    if (gACMIRec.IsRecording() && (SimLibFrameCount & 0x0f ) == 0){
		ACMIGenPositionRecord genPos;
		genPos.hdr.time = SimLibElapsedTime * MSEC_TO_SEC + OTWDriver.todOffset;
		genPos.data.type = Type();
		genPos.data.uniqueID = ACMIIDTable->Add(Id(),NULL,TeamInfo[GetTeam()]->GetColor());//.num_;
		genPos.data.x = XPos();
		genPos.data.y = YPos();
		genPos.data.z = ZPos();
		genPos.data.roll = Roll();
		genPos.data.pitch = Pitch();
		genPos.data.yaw = Yaw();
		// Remove		genPos.data.teamColor = TeamInfo[GetTeam()]->GetColor();
		gACMIRec.GenPositionRecord( &genPos );
	}

	return IsLocal();
}
示例#22
0
bool CXbowDriver::GetData()
{

    //here we actually access serial ports etc
    if(m_pPort->IsStreaming())
    {
        MOOSTrace("Crossbow must not be streaming\n");
        return false;
    }
    
    //ask the crossbow for a reading
    m_pPort->Write("G",1);
    
    string sWhat;
    unsigned char Reply[CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH];
    
    //note local call back invoked here to specify termination
    int nRead = m_pPort->ReadNWithTimeOut((char*)Reply,sizeof(Reply));

    
    if(nRead == CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH)
    {
        if(Reply[0]!=255)
        {
            MOOSTrace("Unexpected Header in CrossBow reply\n");
        }
		
	//angles
        short nRoll  = (Reply[1]<<8) + Reply[2];
        short nPitch = (Reply[3]<<8) + Reply[4];
        short nYaw   = (Reply[5]<<8) + Reply[6];

	//This is roll, pitch and yaw for the DMU-AHRS, which is rotated
	//relative to the vehicle body. It has Z down and X out the tail.
        double df_deg_CBRoll   = nRoll*180.0/pow(2.0,15.0);
        double df_deg_CBPitch  = nPitch*180.0/pow(2.0,15.0);
        double df_deg_CBYaw    = nYaw*180.0/pow(2.0,15.0);
		
        //account for alignment of crossbow in vehicle frame
        //this is the angle measured from the vehicle center line(y)
        double dfHeading = df_deg_CBYaw+m_dfVehicleYToINSX;
        
        //now correct for magnetic offset
        dfHeading+=m_dfMagneticOffset;
        
        //convert to Yaw..
	//Notice that Heading is in DEGREES, positive CLOCKWISE
	//while Yaw is in RADIANS, positive COUNTERCLOCKWISE
        double dfYaw = -dfHeading*PI/180.0;
        dfYaw = MOOS_ANGLE_WRAP(dfYaw);
        
		
	//initialise transformed angles (in degrees)
	double df_deg_TRoll  = df_deg_CBRoll;
	double df_deg_TPitch = df_deg_CBPitch;
		
	if( m_dfVehicleYToINSX == 0 )
	{
	    //Crossbow roll and vehicle body roll match.
	    df_deg_TRoll = df_deg_TRoll;
	    //same for Pitch.
	    df_deg_TPitch = df_deg_TPitch;
	}
	else if (m_dfVehicleYToINSX == 180)
	{
	    df_deg_TRoll = -df_deg_TRoll;
	    df_deg_TPitch = -df_deg_TPitch;
	}
	else
	{
	    MOOSTrace("Bad 'TWIST' value (use 0 or 180)!\r\n");
	    return false;
	}
		
        //look after pitch
        double dfPitch = MOOSDeg2Rad(df_deg_TPitch);
        
        //look after roll
        double dfRoll = MOOSDeg2Rad(df_deg_TRoll);
        
        
        //find the temperature every so often
        m_nTempCnt++;

        if((m_nTempCnt % 100) == 0)
        {
            short nTemp   = ( Reply[25] << 8 ) + Reply[26];
            m_dfTemp = 44.4 * ( ((double)nTemp * 5.0/4096.0) - 1.375); 
            CMOOSMsg Temperature(MOOS_NOTIFY, "INS_TEMPERATURE", m_dfTemp);
	    m_Notifications.push_back(Temperature);
        }
        
        //notify the MOOS
        CMOOSMsg Heading(MOOS_NOTIFY, "INS_HEADING", dfHeading);
	m_Notifications.push_back(Heading);
	CMOOSMsg Yaw(MOOS_NOTIFY, "INS_YAW", dfYaw);
	m_Notifications.push_back(Yaw);
	CMOOSMsg Pitch(MOOS_NOTIFY, "INS_PITCH", dfPitch);
	m_Notifications.push_back(Pitch);
	CMOOSMsg Roll(MOOS_NOTIFY, "INS_ROLL", dfRoll);
	m_Notifications.push_back(Roll);
		
	//rates
	short nRollRate  = (Reply[7]<<8) + Reply[8];//p-dot
        short nPitchRate = (Reply[9]<<8) + Reply[10];//q-dot
        short nYawRate   = (Reply[11]<<8) + Reply[12];//r-dot

	//xbow calib constant
	double RR = 100.0;//deg/sec

	double dfRollRate  = nRollRate * RR * 1.5/pow(2.0,15);
	double dfPitchRate = nPitchRate * RR * 1.5/pow(2.0,15);
	double dfYawRate   = nYawRate * RR * 1.5/pow(2.0,15);

	//note X and Y axes are switched
	CMOOSMsg RollRate(MOOS_NOTIFY, "INS_ROLLRATE_Y", dfRollRate);
	m_Notifications.push_back(RollRate);
	CMOOSMsg PitchRate(MOOS_NOTIFY, "INS_ROLLRATE_X", dfPitchRate);
	m_Notifications.push_back(PitchRate);
	CMOOSMsg YawRate(MOOS_NOTIFY, "INS_ROLLRATE_Z", dfYawRate);
	m_Notifications.push_back(YawRate);

	//accelerations
        short nXAccel = (Reply[13]<<8) + Reply[14];//v-dot
        short nYAccel = (Reply[15]<<8) + Reply[16];//u-dot
        short nZAccel = (Reply[17]<<8) + Reply[18];//w-dot
		
	//xbow calib constant
	double GR = 2.0;//G's
	double dfXAccel = nXAccel * GR * 1.5/pow(2.0,15);
	double dfYAccel = nYAccel * GR * 1.5/pow(2.0,15);
	double dfZAccel = nZAccel * GR * 1.5/pow(2.0,15);

	//note X and Y axes are switched
	CMOOSMsg XAccel(MOOS_NOTIFY, "INS_ACCEL_Y", dfXAccel);
	m_Notifications.push_back(XAccel);
	CMOOSMsg YAccel(MOOS_NOTIFY, "INS_ACCEL_X", dfYAccel);
	m_Notifications.push_back(YAccel);
	CMOOSMsg ZAccel(MOOS_NOTIFY, "INS_ACCEL_Z", dfZAccel);
	m_Notifications.push_back(ZAccel);
		

	//magnetic field data
	short nXMag = (Reply[19]<<8) + Reply[20];
        short nYMag = (Reply[21]<<8) + Reply[22];
        short nZMag = (Reply[23]<<8) + Reply[24];

	double dfGaussX = nXMag * 1.25 * 1.5/pow(2.0,15.0);
	double dfGaussY = nYMag * 1.25 * 1.5/pow(2.0,15.0);
	double dfGaussZ = nZMag * 1.25 * 1.5/pow(2.0,15.0);

	CMOOSMsg GaussX(MOOS_NOTIFY, "INS_MAG_Y", dfGaussX);
	m_Notifications.push_back(GaussX);
	CMOOSMsg GaussY(MOOS_NOTIFY, "INS_MAG_X", dfGaussY);
	m_Notifications.push_back(GaussY);
	CMOOSMsg GaussZ(MOOS_NOTIFY, "INS_MAG_Z", dfGaussZ);
	m_Notifications.push_back(GaussZ);

        
        if(m_pPort->IsVerbose())
        {
            //this allows us to print data in verbose mode
            //when teh port couldn't as it is verbose
            MOOSTrace("Roll = %7.3f Pitch = %7.3f Yaw = %7.3f Heading = %7.3f Temp = %3.2f\n",
		      df_deg_TRoll,
		      df_deg_TPitch,
		      dfYaw*180/PI,
		      dfHeading,
		      m_dfTemp);
        }
        
    }
    else
    {
	MOOSTrace("read %d byte while expecting %d\n",
		  nRead,
		  CROSSBOW_POLLED_ANGLE_MODE_REPLY_LENGTH);
    }
    
    return true;
    
}
示例#23
0
/********************************************************************************
 Update the camera
 ********************************************************************************/
void Camera3::Update(double dt)
{
	// WASD movement
	if ( myKeys['w'] == true)
	{
		Walk( dt );
	}
	else
	{
		MoveVel_W = 0.0f;
	}
	if (myKeys['s'] == true)
	{
		Walk( -dt );
	}
	else
	{
		MoveVel_S = 0.0f;
	}
	if (myKeys['a'] == true)
	{
		Strafe( -dt );
	}
	else
	{
		MoveVel_A = 0.0f;
	}
	if (myKeys['d'] == true)
	{
		Strafe( dt );
	}
	else
	{
		MoveVel_D = 0.0f;
	}

	// Rotation
	if ( myKeys[VK_UP] == true)
	{
		LookUp( dt );
	}
	if (myKeys[VK_DOWN] == true)
	{
		LookUp( -dt );
	}
	if (myKeys[VK_LEFT] == true)
	{
		TurnLeft( -dt );
	}
	if (myKeys[VK_RIGHT] == true)
	{
		TurnRight( dt );
	}

	// Jump
	if (myKeys[32] == true)
	{
		Jump( dt );
		myKeys[32]	= false;
	}
	UpdateJump(dt);

	//Update the camera direction based on mouse move
	// left-right rotate
	if ( Application::camera_yaw != 0 )
		Yaw( dt );
	if ( Application::camera_pitch != 0 )
		Pitch( dt );

	if(Application::IsKeyPressed('R'))
	{
		Reset();
	}
}
示例#24
0
//------------------------------------------------------------------------------
// Purpose :  If connected to a node returns node direction, otherwise
//			  returns local hint direction
//
//			  NOTE: Assumes not using multiple AI networks  
// Input   :
// Output  :
//------------------------------------------------------------------------------
Vector CAI_Hint::GetDirection( )
{
	return UTIL_YawToVector( Yaw() );
}
示例#25
0
int EjectedPilotClass::Exec()
{
   	ACMIGenPositionRecord genPos;
	ACMISwitchRecord acmiSwitch;

	SoundPos.UpdatePos(this);

	if (IsDead())
		return TRUE;
	
		// Call superclass Exec.
		SimMoverClass::Exec();

      if (!SimDriver.MotionOn())
         return IsLocal();

      if (_delayTime > SimLibElapsedTime) { // not time yet
		RunJettisonCanopy(); // stay with it
		return IsLocal();
      }

		// Advance time
		AdvanceTime();

		// Simulate the ejected pilot here.
		switch(_stage)
		{
			case PD_JETTISON_CANOPY :
			{
				RunJettisonCanopy();
				
				break;
			}
			case PD_EJECT_SEAT :
			{
				RunEjectSeat();

				break;
			}
			case PD_FREE_FALL_WITH_SEAT :
			{
				RunFreeFall();

				break;
			}
			case PD_CHUTE_OPENING :
			{
				RunFreeFall();

				// Here we run our little switch based animation...
				static const int NUM_FRAMES = 31;

				float percent = (_runTime             - StageEndTime(_stage-1)) /
					            (StageEndTime(_stage) - StageEndTime(_stage-1));
				int	frame = FloatToInt32(percent * (NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				percent = ((_runTime  - _deltaTime )           - StageEndTime(_stage-1)) /
					       (StageEndTime(_stage) - StageEndTime(_stage-1));

				int	prevframe = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));
				if ( prevframe < 0 )
					prevframe = 0;
				else if ( prevframe > NUM_FRAMES )
					prevframe = NUM_FRAMES;

				if ( gACMIRec.IsRecording() && prevframe != frame)
				{
						acmiSwitch.hdr.time = SimLibElapsedTime * MSEC_TO_SEC + OTWDriver.todOffset;
						acmiSwitch.data.type = Type();
						acmiSwitch.data.uniqueID = ACMIIDTable->Add(Id(),NULL,0);//.num_;
						acmiSwitch.data.switchNum = 0;
						acmiSwitch.data.prevSwitchVal = 1<<prevframe;
						acmiSwitch.data.switchVal = 1<<frame;
						gACMIRec.SwitchRecord( &acmiSwitch );
				}
					
				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );

				break;
			}
			case PD_FREE_FALL_WITH_OPEN_CHUTE :
			{
				RunFreeFallWithOpenChute();
	
				break;
			}
			case PD_FREE_FALL_WITH_COLLAPSED_CHUTE :
			{
				RunFreeFall();
	
				break;
			}
			case PD_SAFE_LANDING :
			{
				RunSafeLanding();

				_stageTimer += _deltaTime;

				static const int NUM_FRAMES = 13;
				float percent = _stageTimer/2.0f;
				int	frame = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );
	
				break;
			}
			case PD_CRASH_LANDING :
			{
				RunCrashLanding();

				_stageTimer += _deltaTime;

				static const int NUM_FRAMES = 12;
				float percent = _stageTimer/2.0f;
				int	frame = FloatToInt32(percent * ((float)NUM_FRAMES-0.5f));

				if ( frame < 0 )
					frame = 0;
				else if ( frame > NUM_FRAMES )
					frame = NUM_FRAMES;

				if ( drawPointer )
					((DrawableBSP*)drawPointer)->SetSwitchMask( 0, 1<<frame );
	
				break;
			}
			default :
			{
				ShiWarning ("Bad Eject Mode");
			}
		}

		// Make sure all components of orientation are in range ( 0 <= n <= TWO_PI).
		FixOrientationRange();

		// Update shared data.
		SetPosition(_pos[I_X], _pos[I_Y], _pos[I_Z]);
		SetDelta(_vel[I_X], _vel[I_Y], _vel[I_Z]);
		SetYPR(_rot[I_YAW], _rot[I_PITCH], _rot[I_ROLL]);
		SetYPRDelta(_aVel[I_YAW], _aVel[I_PITCH], _aVel[I_ROLL]);
		if (gACMIRec.IsRecording() && (SimLibFrameCount & 3 ) == 0)
		{
			genPos.hdr.time = SimLibElapsedTime * MSEC_TO_SEC + OTWDriver.todOffset;
			genPos.data.type = Type();
			genPos.data.uniqueID = ACMIIDTable->Add(Id(),NULL,TeamInfo[GetTeam()]->GetColor());//.num_;
			genPos.data.x = XPos();
			genPos.data.y = YPos();
			genPos.data.z = ZPos();
			genPos.data.roll = Roll();
			genPos.data.pitch = Pitch();
			genPos.data.yaw = Yaw();
// remove			genPos.data.teamColor = TeamInfo[GetTeam()]->GetColor();
			gACMIRec.GenPositionRecord( &genPos );
		}

		// Update matrices for geometry.
		CalcTransformMatrix((SimMoverClass *)this);

		// See if it hit the ground.
		if ( _hitGround == FALSE )
			_hitGround = HasHitGround();

		/*
		** We now do completion in the safe or crash landing stages
		** (by calling HitGround() )
		if (HasHitGround())
		{
			HitGround();
		}
		*/

		// Display some debug data.
#if DEBUG_EJECTION_SEQUENCE
		SpewDebugData();
#endif // DEBUG_EJECTION_SEQUENCE

	return IsLocal();
}
示例#26
0
void EjectedPilotClass::InitLocalData(AircraftClass *ac, int mode, int no){
	DrawableBSP		*acBSP;
	int				labelLen;

	_delayTime = SimLibElapsedTime + no * 2 * CampaignSeconds;
	// Initialize position, rotation, velocity, angular velocity.
	if (ac)
	{
		_pos = EP_VECTOR(ac->XPos(),ac->YPos(),ac->ZPos());

		_rot[I_ROLL] =	ac->Roll();
		_rot[I_PITCH] = ac->Pitch();
		_rot[I_YAW] = ac->Yaw();
		
		_vel = EP_VECTOR(ac->XDelta(),ac->YDelta(),ac->ZDelta());

		_aVel[I_ROLL] = ac->RollDelta();
		_aVel[I_PITCH] = ac->PitchDelta();
		_aVel[I_YAW] = ac->YawDelta();
	}
	else
	{

		_pos = EP_VECTOR(XPos(),YPos(),ZPos());

		_rot[I_ROLL] =	Roll();
		_rot[I_PITCH] = Pitch();
		_rot[I_YAW] = Yaw();
		
		_vel = EP_VECTOR(XDelta(),YDelta(),ZDelta());

		_aVel[I_ROLL] = RollDelta();
		_aVel[I_PITCH] = PitchDelta();
		_aVel[I_YAW] = YawDelta();
	}

	// Play with this value to change the signature of an
	// ejected pilot on the IR.
	SetPowerOutput(0);
	// sfr: not setters on this anymore
	//SetVt(0);
	//SetKias(0);

	// Initialize physical data.
	_pd = NULL;
	_stage = PD_START;

	// Initialize model data to NULL.
	_md = NULL;
	_model = MD_START;

	// Set the ejection mode.
	SetMode(mode);

	// Initialize run time and delta time.
	_runTime = 0.0;
	_deltaTime = 0.0;

	// We just set the type flag to "FalconSimEntity".
	SetTypeFlag(FalconEntity::FalconSimEntity);

	// Is it ourselves - Find out from the aircraft.
	if (ac && no == 0){
		_isPlayer = (SimDriver.GetPlayerEntity() == ac) ? TRUE : FALSE;
	}
	else {
		_isPlayer = FALSE;
	}

	// Is it a player - Find out from the aircraft.
	if (ac){
		_isDigital = ac->IsDigital() ? TRUE : FALSE;
	}
	else{
		_isDigital = TRUE;
	}

	// Set team/country
	if (ac){
      SetCountry (ac->GetCountry());
	}

	_endStageTimeAdjust = 
	(
		IsDigiPilot() ?
		0.0F :
		_pd->humanPilotEndStageTimeAdjust
	);
	
	// It hasn't hit the ground yet.
	_hitGround = FALSE;

	// The chute isn't collapsed yet.
	_collapseChute = FALSE;
	_chuteCollapsedTime = 1000000.0;

	// No death message yet.
	_deathMsg = NULL;

	// Update shared data.
	SetPosition(_pos[I_X], _pos[I_Y], _pos[I_Z]);
	SetDelta(_vel[I_X], _vel[I_Y], _vel[I_Z]);
	SetYPR(_rot[I_YAW], _rot[I_PITCH], _rot[I_ROLL]);
	SetYPRDelta(_aVel[I_YAW], _aVel[I_PITCH], _aVel[I_ROLL]);

	// Update matrices for geometry.
	CalcTransformMatrix((SimMoverClass *)this);

	// Set up our label.
	if (ac)
	{
		acBSP = (DrawableBSP *)ac->drawPointer;
		if(acBSP != NULL)
		{
			strncpy(_label, acBSP->Label(), 32);
			labelLen = strlen(acBSP->Label());
			if (no == 0){
			    strncat(_label, " Pilot", 32 - labelLen);
			}
			else {
			    char crewstr[20];
			    sprintf (crewstr, " Crew%d", no);
			    strncat(_label, crewstr, 32 - labelLen);
			}
			_label[31] = 0;
			_labelColor = acBSP->LabelColor();
		}
		else
		{
			_label[0] = 0;
			_labelColor = 0;
		}
	}
	else
	{
		strcpy(_label, "Pilot");
		labelLen = strlen(_label);
		_labelColor = 0;//acBSP->LabelColor();
	}
	
	_execCalledFromAircraft = FALSE;
	
	// Point to the aircraft that I ejected from.
	if (ac)
	{
		_aircraftId = ac->Id();
		_flightId = ac->GetCampaignObject()->Id();
	}

	// Update exec transfer synching data.
	_lastFrameCount = 0;
	//	_execCount = 0;

   // Act like a bomb, so nobody sees you
   // edg: yuck, we now have an eject pilot motion
   SetFlag(MOTION_BMB_AI);

   SetFlag(MOTION_EJECT_PILOT);

   if (IsLocal()) {
      SimVuDriver *drive = new SimVuDriver(this);
      drive->ExecDR(SimLibElapsedTime);
      SetDriver (drive);
   }
}
示例#27
0
void Entity::Update(const Camera& camera, float dt)
{
	if (mSpinning)		{Yaw(dt*movementMult);}
	if (mUpDown)		{GoUpDown(dt);}
	if (mFlipping)		{Pitch(dt*movementMult);}
	if (mRolling)		{Roll(dt*movementMult);}
	if (mSideToSide)	{GoSideToSide(dt);}
	if (mBackAndForth)	{GoBackAndForth(dt);}
	if (mOrbit)			{ Yaw(dt*movementMult); Walk(dt*movementMult*100); }

	XMVECTOR R = XMLoadFloat3(&mRight);
	XMVECTOR U = XMLoadFloat3(&mUp);
	XMVECTOR L = XMLoadFloat3(&mLook);
	XMVECTOR P = XMLoadFloat3(&mPosition);

	
	// Keep axes orthogonal to each other and of unit length.
	L = XMVector3Normalize(L);
	U = XMVector3Normalize(XMVector3Cross(L, R));

	// U, L already ortho-normal, so no need to normalize cross product.
	R = XMVector3Cross(U, L);

	
	// Fill in the world matrix entries.
// 	float x = XMVectorGetX(XMVector3Dot(P, R));
// 	float y = XMVectorGetX(XMVector3Dot(P, U));
// 	float z = XMVectorGetX(XMVector3Dot(P, L));

	float x = XMVectorGetX(P);
	float y = XMVectorGetY(P);
	float z = XMVectorGetZ(P);

	XMStoreFloat3(&mRight, R);
	XMStoreFloat3(&mUp, U);
	XMStoreFloat3(&mLook, L);

	mWorld(0, 0) = mRight.x;
	mWorld(1, 0) = mRight.y;
	mWorld(2, 0) = mRight.z;
	mWorld(3, 0) = x;

	mWorld(0, 1) = mUp.x;
	mWorld(1, 1) = mUp.y;
	mWorld(2, 1) = mUp.z;
	mWorld(3, 1) = y;

	if (reverseLook){
	mWorld(0, 2) = -mLook.x;
	mWorld(1, 2) = -mLook.y;
	mWorld(2, 2) = -mLook.z;
	mWorld(3, 2) = z;}
	else
	{	mWorld(0, 2) = mLook.x;
		mWorld(1, 2) = mLook.y;
		mWorld(2, 2) = mLook.z;
		mWorld(3, 2) = z;}


	mWorld(0, 3) = 0.0f;
	mWorld(1, 3) = 0.0f;
	mWorld(2, 3) = 0.0f;
	mWorld(3, 3) = 1.0f;

	if (hovering)
	{
		XMMATRIX M = XMLoadFloat4x4(&mWorld);
		XMMATRIX scaling = XMMatrixScaling(1.3f, 1.3f, 1.3f);
		XMStoreFloat4x4(&mWorld, scaling * M);
	}


	//GROWING MOVEMENTS
	if (mPulse)	{ Pulse(dt); }
	if (mGrowIn){ GrowIn(dt); }
	if (mGrowOut){ GrowOut(dt); }
	if (mSquishX || mSquishY || mSquishZ){ Squish(dt); 
	if (mSquishX){  ScaleX(currProgress); }
	if (mSquishY){  ScaleY(currProgress); }
	if (mSquishZ){  ScaleZ(currProgress); }}


	if (progressBar)
	{
		ScaleX(currProgress);
	}

	if (billboard)
	{
		XMMATRIX M		= XMLoadFloat4x4(&mWorld);
		XMVECTOR L		= XMVector3Normalize(XMVectorSubtract(camera.GetPositionXM(), GetPositionXM()));
		XMVECTOR Look	= XMLoadFloat3(&mLook);
		XMVECTOR angle	= XMVector3AngleBetweenNormals(L, Look);
		float theAngle	= XMVectorGetY(angle);

		XMMATRIX rotY;
		camera.GetPosition().x < mPosition.x ? rotY = XMMatrixRotationY(-theAngle) : rotY = XMMatrixRotationY(theAngle);

		XMStoreFloat4x4(&mWorld, rotY * M); 
	}

	if (goToPos)
	{
		if (mDistanceLeft <= 0){ goToPos = false; }
	}

	if (mUseAnimation){ mAnim->Update(dt);}

	//update sphere collider
	mSphereCollider.Center	= mPosition;
	if (mUseAAB){ UpdateAAB(); }
	if (mUseAABOnce){ UpdateAAB(); mUseAABOnce = false; }
}
示例#28
0
void HelicopterClass::RunExplosion (void)
{
	int i;
	Tpoint    pos;
	Falcon4EntityClassType *classPtr;
	SimBaseClass	*tmpSimBase;
	Tpoint tp = Origin;
	Trotation tr = IMatrix;

    // F4PlaySound (SFX_DEF[SFX_OWNSHIP_BOOM].handle);
	//F4SoundFXSetPos( SFX_BOOMA1 + PRANDInt5(), TRUE, XPos(), YPos(), ZPos(), 1.0f );
	SoundPos.Sfx( SFX_BOOMA1 + PRANDInt5() ); // MLR 5/16/2004 - 

	// 1st do primary explosion
    pos.x = XPos();
    pos.y = YPos();
    pos.z = ZPos();

	if ( OnGround( ) )
	{
		pos.z = OTWDriver.GetGroundLevel( pos.x, pos.y ) - 4.0f;
		SetDelta( XDelta() * 0.1f, YDelta() * 0.1f, -50.0f );
    	OTWDriver.AddSfxRequest(
  			new SfxClass (SFX_GROUND_EXPLOSION,				// type
			&pos,							// world pos
			1.2f,							// time to live
			100.0f ) );		// scale
	}
	else
	{
    	OTWDriver.AddSfxRequest(
  			new SfxClass (SFX_AIR_HANGING_EXPLOSION,				// type
			&pos,							// world pos
			2.0f,							// time to live
			200.0f + 200 * PRANDFloatPos() ) );		// scale
	}
	classPtr = (Falcon4EntityClassType*)EntityType();

	// Add the parts (appairently hardcoded at 4)
	// Recoded by KCK on 6/23 to remove damage station BS
	for (i=0; i<4; i++)
		{
		tmpSimBase = new SimBaseClass(Type());
		CalcTransformMatrix (tmpSimBase);
		OTWDriver.CreateVisualObject(tmpSimBase, classPtr->visType[i+2], &tp, &tr, OTWDriver.Scale());
		tmpSimBase->SetPosition (pos.x, pos.y, pos.z);

		if (!i)
			{
			tmpSimBase->SetDelta (XDelta(), YDelta(), ZDelta());
			}
		if (!OnGround())
			{
			tmpSimBase->SetDelta (	XDelta() + 50.0f * PRANDFloat(),
									YDelta() + 50.0f * PRANDFloat(),
									ZDelta() + 50.0f * PRANDFloat() );
			}
		else
			{
			tmpSimBase->SetDelta (	XDelta() + 50.0f * PRANDFloat(),
									YDelta() + 50.0f * PRANDFloat(),
									ZDelta() - 50.0f * PRANDFloatPos() );
			}
		tmpSimBase->SetYPR (Yaw(), Pitch(), Roll());

		if (!i)
			{
			// First peice is more steady and is flaming
			tmpSimBase->SetYPRDelta ( 0.0F, 0.0F, 10.0F + PRANDFloat() * 30.0F * DTR);
			OTWDriver.AddSfxRequest(
  			new SfxClass (SFX_FLAMING_PART,				// type
				SFX_MOVES | SFX_USES_GRAVITY | SFX_EXPLODE_WHEN_DONE,
				tmpSimBase,								// sim base *
				3.0f + PRANDFloatPos() * 4.0F,			// time to live
				1.0F ) );								// scale
			}
		else
			{
			// spin piece a random amount
			tmpSimBase->SetYPRDelta (	PRANDFloat() * 30.0F * DTR,
										PRANDFloat() * 30.0F * DTR,
										PRANDFloat() * 30.0F * DTR);
			OTWDriver.AddSfxRequest(
				new SfxClass (SFX_SMOKING_PART,			// type
				SFX_MOVES | SFX_USES_GRAVITY | SFX_BOUNCES | SFX_EXPLODE_WHEN_DONE,
				tmpSimBase,								// sim base *
				4.0f * PRANDFloatPos() + (float)((i+1)*(i+1)),	// time to live
				1.0 ) );								// scale
			}
		}
}
示例#29
0
	void Orientation::Rotate(float p_rotationX, float p_rotationY, float p_rotationZ)
	{
		Pitch(p_rotationX);
		Yaw(p_rotationY);
		Roll(p_rotationZ);
	}