示例#1
0
// performs simple maneuvers
void CBE_Floater::AttackManeuver(CCopyEntity* pCopyEnt, SBE_EnemyExtraData *pExtraData)
{
	float& rfSensoringInterval	= pCopyEnt->f1;
	Vector3& rvDesiredDirection  = pCopyEnt->v1;
	float& rfCurrentManeuverTime = pExtraData->fCurrentManeuverTime;
	float& rfTotalManeuverTime = pExtraData->fTotalManeuverTime;
	Vector3& rvManeuverDir = pExtraData->vManeuverDirection;
	float fSqDistToPlayer = pExtraData->fLastCheckedSqDistToPlayer;

	ApplyFriction( pCopyEnt, 1.8f );

	// evasive maneuver
	if( 0.20f < rfCurrentManeuverTime - rfTotalManeuverTime ||
		rvManeuverDir == Vector3(0,0,0) )
	{
		rfCurrentManeuverTime = 0;
		rfTotalManeuverTime = 0.7f + 0.5f * (float)rand() / (float)RAND_MAX;

		// set up  a new direction
		rvManeuverDir
			+= pCopyEnt->GetRightDirection()	* ( 3.0f * (float)rand()/(float)RAND_MAX - 1.5f )
			+  pCopyEnt->GetUpDirection()		* ( 3.0f * (float)rand()/(float)RAND_MAX - 1.5f )
			+  pCopyEnt->GetDirection()			* ( 1.6f * (float)rand()/(float)RAND_MAX - 0.8f );

		if( 36.0f < fSqDistToPlayer )	// if over 6m away from player
			rvManeuverDir += rvDesiredDirection * fSqDistToPlayer / 50.0f;	// move toward the player
			
		Vec3Normalize( rvManeuverDir, rvManeuverDir );
	}
	else
		rfCurrentManeuverTime += m_pStage->GetFrameTime();

	if( 0.5f < rfTotalManeuverTime - rfCurrentManeuverTime )
	{
//		float fWishSpeed = 12.0f;
		float fWishSpeed = 10.0f * m_fMobility;
		Accelerate( pCopyEnt, rvManeuverDir, fWishSpeed, 4.0f );
	}


	if( rfSensoringInterval == 0 )
	{	// check if there is an obstacle in the direction to which the entity is heading
		STrace tr;
		tr.bvType = BVTYPE_AABB;
		tr.aabb   = this->m_aabb;
		tr.pSourceEntity = pCopyEnt;
		tr.vStart       = pCopyEnt->GetWorldPosition();
		tr.vGoal        = pCopyEnt->GetWorldPosition() + pCopyEnt->vVelocity * 1.2f;
		tr.SetAABB();
		m_pStage->ClipTrace(tr);
		// since the entity is heading for some obstacle, correct the velocity to avoid it
		if( tr.fFraction < 1.0f )
		{
			pCopyEnt->vVelocity += tr.plane.normal * (1.0f - tr.fFraction ) * 3.0f; // m_pStage->GetFrameTime();
		}
	}

	SlideMove( pCopyEnt );
}
示例#2
0
void CBE_Floater::SearchManeuver(CCopyEntity* pCopyEnt, SBE_EnemyExtraData *pExtraData)
{
	Vector3& rvDesiredDirection  = pCopyEnt->v1;
	Vector3& rvTargetPosition    = pExtraData->vTargetPosition;
	float& rfSensoringInterval2      = pExtraData->fSensoringInterval2;
	float& rfCurrentManeuverTime     = pExtraData->fCurrentManeuverTime;
	float& rfTotalManeuverTime       = pExtraData->fTotalManeuverTime;
	Vector3& rvManeuverDir       = pExtraData->vManeuverDirection;
	float fWishSpeed = 6.0f;

	const float frametime = m_pStage->GetFrameTime();

//	if( pCopyEnt->vVelocity == Vector3(0,0,0) )
//		return;

	ApplyFriction( pCopyEnt, 1.5f );

	if( m_iRandomSearchManeuver != 0 )
	{
		Vector3 vFromCurrentPosToDest = rvTargetPosition - pCopyEnt->GetWorldPosition();
		float fDist = Vec3LengthSq( vFromCurrentPosToDest );

		if( 0.20f < rfCurrentManeuverTime - rfTotalManeuverTime ||
			rvManeuverDir == Vector3(0,0,0) || fDist < 0.2f )
		{
			rfCurrentManeuverTime = 0;
			rfTotalManeuverTime = 1.0f + 0.6f * (float)rand() / (float)RAND_MAX;

			// set up a target locaion
			rvTargetPosition
				= pExtraData->vOriginalPosition
				+ Vector3(1,0,0) * ( 12.0f * (float)rand()/(float)RAND_MAX - 6.0f )
				+ Vector3(0,1,0) * (  6.0f * (float)rand()/(float)RAND_MAX - 3.0f )
				+ Vector3(0,0,1) * ( 12.0f * (float)rand()/(float)RAND_MAX - 6.0f )
				+ pCopyEnt->GetDirection() * 2.5f;

			Vec3Normalize( rvManeuverDir, rvManeuverDir );
		}
		else
			rfCurrentManeuverTime += frametime;

		if( 0.16f < rfSensoringInterval2 )
		{
			rfSensoringInterval2 = 0.0f;
			Vec3Normalize( rvManeuverDir, vFromCurrentPosToDest );
		}
		else
			rfSensoringInterval2 += frametime;

		if( 0.1f < rfTotalManeuverTime - rfCurrentManeuverTime )
		{
			float fWishSpeed = 4.5f;
			Accelerate( pCopyEnt, rvManeuverDir, fWishSpeed, 2.0f );
		}

		UpdateDesiredYawAndPitch(pCopyEnt, rvManeuverDir);
		AimAlong(pCopyEnt, rvManeuverDir);
	}

	SlideMove( pCopyEnt );
}
/*
=====================
idPhysics_Monster::StepMove

  move start into the delta direction
  the velocity is clipped conform any collisions
=====================
*/
monsterMoveResult_t idPhysics_Monster::StepMove(idVec3 &start, idVec3 &velocity, const idVec3 &delta)
{
	trace_t tr;
	idVec3 up, down, noStepPos, noStepVel, stepPos, stepVel;
	monsterMoveResult_t result1, result2;
	float	stepdist;
	float	nostepdist;

	if (delta == vec3_origin) {
		return MM_OK;
	}

	// try to move without stepping up
	noStepPos = start;
	noStepVel = velocity;
	result1 = SlideMove(noStepPos, noStepVel, delta);

	if (result1 == MM_OK) {
		velocity = noStepVel;

		if (gravityNormal == vec3_zero) {
			start = noStepPos;
			return MM_OK;
		}

		// try to step down so that we walk down slopes and stairs at a normal rate
		down = noStepPos + gravityNormal * maxStepHeight;
		gameLocal.clip.Translation(tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self);

		if (tr.fraction < 1.0f) {
			start = tr.endpos;
			return MM_STEPPED;
		} else {
			start = noStepPos;
			return MM_OK;
		}
	}

	if (blockingEntity && blockingEntity->IsType(idActor::Type)) {
		// try to step down in case walking into an actor while going down steps
		down = noStepPos + gravityNormal * maxStepHeight;
		gameLocal.clip.Translation(tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self);
		start = tr.endpos;
		velocity = noStepVel;
		return MM_BLOCKED;
	}

	if (gravityNormal == vec3_zero) {
		return result1;
	}

	// try to step up
	up = start - gravityNormal * maxStepHeight;
	gameLocal.clip.Translation(tr, start, up, clipModel, clipModel->GetAxis(), clipMask, self);

	if (tr.fraction == 0.0f) {
		start = noStepPos;
		velocity = noStepVel;
		return result1;
	}

	// try to move at the stepped up position
	stepPos = tr.endpos;
	stepVel = velocity;
	result2 = SlideMove(stepPos, stepVel, delta);

	if (result2 == MM_BLOCKED) {
		start = noStepPos;
		velocity = noStepVel;
		return result1;
	}

	// step down again
	down = stepPos + gravityNormal * maxStepHeight;
	gameLocal.clip.Translation(tr, stepPos, down, clipModel, clipModel->GetAxis(), clipMask, self);
	stepPos = tr.endpos;

	// if the move is further without stepping up, or the slope is too steap, don't step up
	nostepdist = (noStepPos - start).LengthSqr();
	stepdist = (stepPos - start).LengthSqr();

	if ((nostepdist >= stepdist) || ((tr.c.normal * -gravityNormal) < minFloorCosine)) {
		start = noStepPos;
		velocity = noStepVel;
		return MM_SLIDING;
	}

	start = stepPos;
	velocity = stepVel;

	return MM_STEPPED;
}
示例#4
0
/*
=====================
idPhysics_Monster::StepMove

move start into the delta direction
the velocity is clipped conform any collisions
=====================
*/
monsterMoveResult_t idPhysics_Monster::StepMove( idVec3 &start, idVec3 &velocity, const idVec3 &delta ) {
	trace_t tr;
	idVec3 up, down, noStepPos, noStepVel, stepPos, stepVel;
	monsterMoveResult_t result1, result2;
	float	stepdist;
	float	nostepdist;
	if( delta == vec3_origin ) {
		return MM_OK;
	}
	// try to move without stepping up
	noStepPos = start;
	noStepVel = velocity;
	result1 = SlideMove( noStepPos, noStepVel, delta );
	if( result1 == MM_OK ) {
		velocity = noStepVel;
		if( gravityNormal == vec3_zero ) {
			start = noStepPos;
			return MM_OK;
		}
		// try to step down so that we walk down slopes and stairs at a normal rate
		down = noStepPos + gravityNormal * maxStepHeight;
		gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
		if( tr.fraction < 1.0f ) {
			start = tr.endpos;
			return MM_STEPPED;
		} else {
			start = noStepPos;
			return MM_OK;
		}
	}
	if( blockingEntity && blockingEntity->IsType( idActor::Type ) ) {
		// try to step down in case walking into an actor while going down steps
		down = noStepPos + gravityNormal * maxStepHeight;
		gameLocal.clip.Translation( tr, noStepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
		start = tr.endpos;
		velocity = noStepVel;
		return MM_BLOCKED;
	}
	if( gravityNormal == vec3_zero ) {
		return result1;
	}
	// try to step up
	up = start - gravityNormal * maxStepHeight;
	gameLocal.clip.Translation( tr, start, up, clipModel, clipModel->GetAxis(), clipMask, self );
	//gameRenderWorld->DebugArrow(colorRed, start, up, 2, 5000);
	if( tr.fraction == 0.0f ) {
		start = noStepPos;
		velocity = noStepVel;
		return result1;
	}
	// try to move at the stepped up position
	stepPos = tr.endpos;
	stepVel = velocity;
	result2 = SlideMove( stepPos, stepVel, delta );
	if( result2 == MM_BLOCKED ) {
		start = noStepPos;
		velocity = noStepVel;
		return result1;
	}
	// step down again
	down = stepPos + gravityNormal * maxStepHeight;
	gameLocal.clip.Translation( tr, stepPos, down, clipModel, clipModel->GetAxis(), clipMask, self );
	//gameRenderWorld->DebugArrow(colorGreen, stepPos, down, 2, 5000);
	//gameRenderWorld->DebugArrow(colorBlue, tr.c.point, tr.c.point + 5 * tr.c.normal, 2, 5000);
	float projection = tr.c.normal * -gravityNormal;
	// greebo: We have collided with a steep slope in front of us
	if( projection < minFloorCosine && projection > 0.06f ) {
		// greebo: Set the endposition a bit more upwards than necessary to prevent gravity from pulling us down immediately again
		stepPos = tr.endpos - gravityNormal * stepUpIncrease;
	} else {
		// No slope, just use the step position
		stepPos = tr.endpos;
	}
	// if the move is further without stepping up, or the slope is too steep, don't step up
	nostepdist = ( noStepPos - start ).LengthSqr();
	stepdist = ( stepPos - start ).LengthSqr();
	// Use the position that brought us the largest forward movement
	if( nostepdist >= stepdist ) {
		start = noStepPos;
		velocity = noStepVel;
		return MM_SLIDING;
	}
	start = stepPos;
	velocity = stepVel;
	return MM_STEPPED;
}
示例#5
0
void OvrSceneView::UpdateViewMatrix(const VrFrame vrFrame )
{
	// Experiments with position tracking
	const bool	useHeadModel = !AllowPositionTracking ||
			( ( vrFrame.Input.buttonState & ( BUTTON_A | BUTTON_X ) ) == 0 );

	// Delta time in seconds since last frame.
	const float dt = vrFrame.DeltaSeconds;
	const float yawSpeed = 1.5f;

    Vector3f GamepadMove;

	// Allow up / down movement if there is no floor collision model
	if ( vrFrame.Input.buttonState & BUTTON_RIGHT_TRIGGER )
	{
		FootPos.y -= vrFrame.Input.sticks[0][1] * dt * MoveSpeed;
	}
	else
	{
		GamepadMove.z = vrFrame.Input.sticks[0][1];
	}
	GamepadMove.x = vrFrame.Input.sticks[0][0];

	// Turn based on the look stick
	// Because this can be predicted ahead by async TimeWarp, we apply
	// the yaw from the previous frame's controls, trading a frame of
	// latency on stick controls to avoid a bounce-back.
	YawOffset -= YawVelocity * dt;

	if ( !( vrFrame.OvrStatus & ovrStatus_OrientationTracked ) )
	{
		PitchOffset -= yawSpeed * vrFrame.Input.sticks[1][1] * dt;
		YawVelocity = yawSpeed * vrFrame.Input.sticks[1][0];
	}
	else
	{
		YawVelocity = 0.0f;
	}

	// We extract Yaw, Pitch, Roll instead of directly using the orientation
	// to allow "additional" yaw manipulation with mouse/controller.
	const Quatf quat = vrFrame.PoseState.Pose.Orientation;

	quat.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>( &EyeYaw, &EyePitch, &EyeRoll );

	EyeYaw += YawOffset;

	// If the sensor isn't plugged in, allow right stick up/down
	// to adjust pitch, which can be useful for debugging.  Never
	// do this when head tracking
	if ( !( vrFrame.OvrStatus & ovrStatus_OrientationTracked ) )
	{
		EyePitch += PitchOffset;
	}

	// Perform player movement.
	if ( GamepadMove.LengthSq() > 0.0f )
	{
		const Matrix4f yawRotate = Matrix4f::RotationY( EyeYaw );
		const Vector3f orientationVector = yawRotate.Transform( GamepadMove );

		// Don't let move get too crazy fast
		const float moveDistance = OVR::Alg::Min<float>( MoveSpeed * (float)dt, 1.0f );
		if ( WorldModel.Definition )
		{
			FootPos = SlideMove( FootPos, ViewParms.EyeHeight, orientationVector, moveDistance,
						WorldModel.Definition->Collisions, WorldModel.Definition->GroundCollisions );
		}
		else
		{	// no scene loaded, walk without any collisions
			CollisionModel collisionModel;
			CollisionModel groundCollisionModel;
			FootPos = SlideMove( FootPos, ViewParms.EyeHeight, orientationVector, moveDistance,
						collisionModel, groundCollisionModel );
		}
	}

	// Rotate and position View Camera, using YawPitchRoll in BodyFrame coordinates.
	Matrix4f rollPitchYaw = Matrix4f::RotationY( EyeYaw )
			* Matrix4f::RotationX( EyePitch )
			* Matrix4f::RotationZ( EyeRoll );
	const Vector3f up = rollPitchYaw.Transform( UpVector );
	const Vector3f forward = rollPitchYaw.Transform( ForwardVector );
	const Vector3f right = rollPitchYaw.Transform( RightVector );

	// Have sensorFusion zero the integration when not using it, so the
	// first frame is correct.
	if ( vrFrame.Input.buttonPressed & (BUTTON_A | BUTTON_X) )
	{
		LatchedHeadModelOffset = LastHeadModelOffset;
	}

	// Calculate the shiftedEyePos
	ShiftedEyePos = CenterEyePos();

	Vector3f headModelOffset = HeadModelOffset( EyeRoll, EyePitch, EyeYaw,
			ViewParms.HeadModelDepth, ViewParms.HeadModelHeight );
	if ( useHeadModel )
	{
		ShiftedEyePos += headModelOffset;
	}

	headModelOffset += forward * ImuToEyeCenter.z;
	headModelOffset += right * ImuToEyeCenter.x;

	LastHeadModelOffset = headModelOffset;

	if ( !useHeadModel )
	{
		// Use position tracking from the sensor system, which is in absolute
		// coordinates without the YawOffset
		ShiftedEyePos += Matrix4f::RotationY( YawOffset ).Transform( vrFrame.PoseState.Pose.Position );

		ShiftedEyePos -= forward * ImuToEyeCenter.z;
		ShiftedEyePos -= right * ImuToEyeCenter.x;

		ShiftedEyePos += LatchedHeadModelOffset;
	}

	ViewMatrix = Matrix4f::LookAtRH( ShiftedEyePos, ShiftedEyePos + forward, up );
}
示例#6
0
/*
================
rvPhysics_Particle::Evaluate

  Evaluate the impulse based rigid body physics.
  When a collision occurs an impulse is applied at the moment of impact but
  the remaining time after the collision is ignored.
================
*/
bool rvPhysics_Particle::Evaluate( int timeStepMSec, int endTimeMSec ) {
	particlePState_t next;
	float			 timeStep;
	float			 upspeed;

	timeStep = MS2SEC( timeStepMSec );

	// if bound to a master
	if ( hasMaster ) {
		idVec3	masterOrigin;
		idMat3	masterAxis;
		idVec3	oldOrigin;		
		
		oldOrigin = current.origin;
		
		self->GetMasterPosition( masterOrigin, masterAxis );
		current.origin = masterOrigin + current.localOrigin * masterAxis;
// RAVEN BEGIN
// ddynerman: multiple clip worlds
		clipModel->Link( self, clipModel->GetId(), current.origin, current.localAxis * masterAxis );
// RAVEN END

		trace_t tr;
		gameLocal.Translation( self, tr, oldOrigin, current.origin, clipModel, clipModel->GetAxis(), clipMask, self );
		
		if ( tr.fraction < 1.0f ) {
			self->Collide ( tr, current.origin - oldOrigin );
		}
		
		DebugDraw();
		
		return true;
	}

	// if the body is at rest
	if ( current.atRest >= 0 || timeStep <= 0.0f ) {
		DebugDraw();
		return false;
	}

	// if putting the body to rest
	if ( dropToFloor ) {
		DropToFloorAndRest();
		return true;
	}

	clipModel->Unlink();

	// Determine if currently on the ground
	CheckGround ( );
	
	// Determine the current upward velocity
	if ( gravityNormal != vec3_zero ) {
		upspeed = -( current.velocity * gravityNormal );
	} else {
		upspeed = current.velocity.z;
	}

	// If not on the ground, or moving upwards, or bouncing and moving toward gravity then do a straight 
	// forward slide move and gravity.		
	if ( !current.onGround || upspeed > 1.0f || (bouncyness > 0.0f && upspeed < -PRT_BOUNCESTOP && !current.inWater) ) {
		// Force ground off when moving upward
		if ( upspeed > 0.0f ) {
			current.onGround = false;
		}
		SlideMove( current.origin, current.velocity, current.velocity * timeStep );		
		if ( current.onGround && upspeed < PRT_BOUNCESTOP ) {
			current.velocity -= ( current.velocity * gravityNormal ) * gravityNormal;
		} else {
			current.velocity += (gravityVector * timeStep);	
		}
	} else {
		idVec3 delta;

		// Slow down due to friction
		ApplyFriction ( timeStep );
	
		delta = current.velocity * timeStep;
		current.velocity -= ( current.velocity * gravityNormal ) * gravityNormal;
		if ( delta == vec3_origin ) {
			PutToRest( );
		} else {
			SlideMove( current.origin, current.velocity, delta );
		}
	}

	// update the position of the clip model
// RAVEN BEGIN
// ddynerman: multiple clip worlds
	clipModel->Link( self, clipModel->GetId(), current.origin, clipModel->GetAxis() );
// RAVEN END

	DebugDraw();

	// get all the ground contacts
	EvaluateContacts();

	current.pushVelocity.Zero();

	if ( IsOutsideWorld() ) {
		gameLocal.Warning( "clip model outside world bounds for entity '%s' at (%s)", self->name.c_str(), current.origin.ToString(0) );
		PutToRest();
	}

	return true;
}
示例#7
0
void OvrSceneView::Frame( const VrFrame & vrFrame,
							const ovrHeadModelParms & headModelParms_,
							const long long supressModelsWithClientId_ )
{
	HeadModelParms = headModelParms_;
	SupressModelsWithClientId = supressModelsWithClientId_;

	CurrentTracking = vrFrame.Tracking;

	// Delta time in seconds since last frame.
	const float dt = vrFrame.DeltaSeconds;
	const float angleSpeed = 1.5f;

	//
	// Player view angles
	//

	// Turn based on the look stick
	// Because this can be predicted ahead by async TimeWarp, we apply
	// the yaw from the previous frame's controls, trading a frame of
	// latency on stick controls to avoid a bounce-back.
	StickYaw -= YawVelocity * dt;
	YawVelocity = angleSpeed * vrFrame.Input.sticks[1][0];

	// Only if there is no head tracking, allow right stick up/down to adjust pitch,
	// which can be useful for debugging without having to dock the device.
	if ( ( vrFrame.Tracking.Status & VRAPI_TRACKING_STATUS_ORIENTATION_TRACKED ) == 0 )
	{
		StickPitch -= angleSpeed * vrFrame.Input.sticks[1][1] * dt;
	}
	else
	{
		StickPitch = 0.0f;
	}

	// We extract Yaw, Pitch, Roll instead of directly using the orientation
	// to allow "additional" yaw manipulation with mouse/controller and scene offsets.
	const Quatf quat = vrFrame.Tracking.HeadPose.Pose.Orientation;

	quat.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>( &EyeYaw, &EyePitch, &EyeRoll );

	// Yaw is modified by both joystick and application-set scene yaw.
	// Pitch is only modified by joystick when no head tracking sensor is active.
	EyeYaw += StickYaw + SceneYaw;
	EyePitch += StickPitch;

	//
	// Player movement
	//

	// Allow up / down movement if there is no floor collision model or in 'free move' mode.
	const bool upDown = ( WorldModel.Definition == NULL || FreeMove ) && ( ( vrFrame.Input.buttonState & BUTTON_RIGHT_TRIGGER ) != 0 );
	const Vector3f gamepadMove(
			vrFrame.Input.sticks[0][0],
			upDown ? -vrFrame.Input.sticks[0][1] : 0.0f,
			upDown ? 0.0f : vrFrame.Input.sticks[0][1] );

	// Perform player movement if there is input.
	if ( gamepadMove.LengthSq() > 0.0f )
	{
		const Matrix4f yawRotate = Matrix4f::RotationY( EyeYaw );
		const Vector3f orientationVector = yawRotate.Transform( gamepadMove );

		// Don't let move get too crazy fast
		const float moveDistance = OVR::Alg::Min<float>( MoveSpeed * (float)dt, 1.0f );
		if ( WorldModel.Definition != NULL && !FreeMove )
		{
			FootPos = SlideMove( FootPos, HeadModelParms.EyeHeight, orientationVector, moveDistance,
						WorldModel.Definition->Collisions, WorldModel.Definition->GroundCollisions );
		}
		else
		{	// no scene loaded, walk without any collisions
			ModelCollision collisionModel;
			ModelCollision groundCollisionModel;
			FootPos = SlideMove( FootPos, HeadModelParms.EyeHeight, orientationVector, moveDistance,
						collisionModel, groundCollisionModel );
		}
	}

	//
	// Center eye transform
	//
	UpdateCenterEye();

	//
	// Model animations
	//

	if ( !Paused )
	{
		for ( int i = 0; i < Models.GetSizeI(); i++ )
		{
			if ( Models[i] != NULL )
			{
				Models[i]->AnimateJoints( static_cast<float>( vrFrame.PredictedDisplayTimeInSeconds ) );
			}
		}
	}

	// External systems can add surfaces to this list before drawing.
	EmitSurfaces.Resize( 0 );
}