Ejemplo n.º 1
0
void Jumper::Flip::updatePhysics(void)
{
    // velocity of base jumper's body
    NxVec3 velocity = _phActor->getLinearVelocity();

    // vectical velocity of base jumper's body
    NxVec3 velocityV( 0, velocity.y, 0 );

    // air resistance coefficient
    float AR = _jumper->getVirtues()->getTrackingAirResistance();

    // terminal velocity
    float Vt = sqrt( 9.8f * _phActor->getMass() / AR );
    float It = velocityV.magnitude() / Vt;

    // air resistance force
    NxVec3 Far = NxVec3(0,1,0) * getAirResistancePower( velocityV.magnitude() / Vt ) * _phActor->getMass() * 9.8f;

    // control torque
    NxVec3 Tctrl( 0,0,0 );
    Tctrl += NxVec3(1,0,0) * -_jumper->getVirtues()->getSteerPitch() * _jumper->getSpinalCord()->down;
    Tctrl += NxVec3(1,0,0) * _jumper->getVirtues()->getSteerPitch() * _jumper->getSpinalCord()->up;
    Tctrl *= It;

    // finalize motion equation    
    _phActor->addForce( Far );
    _phActor->addLocalTorque( Tctrl );
}
void Jumper::CanopyOpening::updatePhysics(void)
{
    // velocity of base jumper's body
    NxVec3 velocity = _phActor->getLinearVelocity();

    // local coordinate system of base jumper
    NxMat34 pose = _phActor->getGlobalPose();
    NxVec3 x = pose.M.getColumn(0);
    NxVec3 y = pose.M.getColumn(1);
    NxVec3 z = pose.M.getColumn(2);

    // air resistance force
    float AR = _jumper->getVirtues()->getTrackingAirResistance();

    // terminal velocity
    float Vt = sqrt( 9.8f * _phActor->getMass() / AR );
    float It = velocity.magnitude() / Vt;

    // air resistance force
    NxVec3 Far = NxVec3(0,1,0) * getAirResistancePower( velocity.magnitude() / Vt ) * _phActor->getMass() * 9.8f;

    // finalize motion equation    
    _phActor->addForce( Far );

    // linear damping is function of jumper velocity    
    // this is prevents calculation errors due to high speed rates
    float minVel     = 50.0f;
    float minDamping = _initialLD;
    float maxVel     = 70.0f;
    float maxDamping = 2.5f;
    float factor = ( velocity.magnitude() - minVel ) / ( maxVel - minVel );
    factor = factor < 0 ? 0 : ( factor > 1 ? 1 : factor );
    float damping = minDamping * ( factor - 1 ) + maxDamping * ( factor );
    _phActor->setLinearDamping( damping );

    // shallow brake setting
    _canopy->setLeftDeep( 0.0f );
    _canopy->setRightDeep( 0.0f );

}
void Jumper::Flight::updatePhysics(void)
{
    SpinalCord* spinalCord = _jumper->getSpinalCord();
    Virtues* virtues = _jumper->getVirtues();
	CanopySimulator* canopy = _jumper->getDominantCanopy();

    // velocity of base jumper's body
    NxVec3 velocity = _phActor->getLinearVelocity();
    
    // horizontal velocity (including wind)
    NxVec3 velocityH = velocity; 
    velocityH += _jumper->getScene()->getWindAtPoint( _phActor->getGlobalPosition() );    
    velocityH.y = 0;

    // shock penalty
    float penalty = _jumper->getVirtues()->getControlPenalty( _jumper->getShock() );
    penalty = ( 1 - penalty );

    // update canopy controls
	// modifier to 50% input
	if (spinalCord->modifier) {
		float dt = _jumper->getDeltaTime();
		if (spinalCord->left > 0.5f && Gameplay::iGameplay->getActionChannel(iaLeft)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaLeft)->downAmplitude(dt, 0.5f);
		if (spinalCord->right > 0.5f && Gameplay::iGameplay->getActionChannel(iaRight)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaRight)->downAmplitude(dt, 0.5f);
		if (spinalCord->leftWarp > 0.5f && Gameplay::iGameplay->getActionChannel(iaLeftWarp)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaLeftWarp)->downAmplitude(dt, 0.5f);
		if (spinalCord->rightWarp > 0.5f && Gameplay::iGameplay->getActionChannel(iaRightWarp)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaRightWarp)->downAmplitude(dt, 0.5f);
		if (spinalCord->leftRearRiser > 0.5f && Gameplay::iGameplay->getActionChannel(iaLeftRearRiser)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaLeftRearRiser)->downAmplitude(dt, 0.5f);
		if (spinalCord->rightRearRiser > 0.5f && Gameplay::iGameplay->getActionChannel(iaRightRearRiser)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaRightRearRiser)->downAmplitude(dt, 0.5f);

		if (spinalCord->leftReserve > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveLeft)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveLeft)->downAmplitude(dt, 0.5f);
		if (spinalCord->rightReserve > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveRight)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveRight)->downAmplitude(dt, 0.5f);
		if (spinalCord->leftReserveWarp > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveLeftWarp)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveLeftWarp)->downAmplitude(dt, 0.5f);
		if (spinalCord->rightReserveWarp > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveRightWarp)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveRightWarp)->downAmplitude(dt, 0.5f);
		if (spinalCord->leftReserveRearRiser > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveLeftRearRiser)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveLeftRearRiser)->downAmplitude(dt, 0.5f);
		if (spinalCord->rightReserveRearRiser > 0.5f && Gameplay::iGameplay->getActionChannel(iaReserveRightRearRiser)->getTrigger()) Gameplay::iGameplay->getActionChannel(iaReserveRightRearRiser)->downAmplitude(dt, 0.5f);
	}


	// set risers
    canopy->setLeftWarpDeep( spinalCord->leftWarp * penalty );
    canopy->setRightWarpDeep( spinalCord->rightWarp * penalty );
    canopy->setLeftRearRiser( spinalCord->leftRearRiser * penalty );
    canopy->setRightRearRiser( spinalCord->rightRearRiser * penalty );

	canopy->setWLOToggles( spinalCord->trigger_wlo );
    canopy->setHookKnife( spinalCord->trigger_hook );


    // update reserve canopy controls
	if (_jumper->isPlayer() &&
		_jumper->getCanopyReserveSimulator() &&
		_jumper->getDominantCanopy() != _jumper->getCanopyReserveSimulator() && 
		_jumper->getCanopyReserveSimulator()->isOpened()) {

		// set toggles
		CanopySimulator *reserve_canopy = _jumper->getCanopyReserveSimulator();
		reserve_canopy->setLeftDeep( spinalCord->leftReserve * penalty );
		reserve_canopy->setRightDeep( spinalCord->rightReserve * penalty );
		// set risers
		reserve_canopy->setLeftWarpDeep( spinalCord->leftReserveWarp * penalty );
		reserve_canopy->setRightWarpDeep( spinalCord->rightReserveWarp * penalty );
		reserve_canopy->setLeftRearRiser( spinalCord->leftReserveRearRiser * penalty );
		reserve_canopy->setRightRearRiser( spinalCord->rightReserveRearRiser * penalty );

		reserve_canopy->setWLOToggles( spinalCord->trigger_wlo );
		reserve_canopy->setHookKnife( spinalCord->trigger_hook );
	}
    // determine animation sequence to be played
    _targetSequence = &passiveFlightSequence;

	// get total left and right input
	float totalInputLeft = 0.0f;
	float totalInputRight = 0.0f;
	float toggleLeft = spinalCord->left;
	float toggleRight = spinalCord->right;
	if (canopy->getLeftForcedDeep() != -1.0f) toggleLeft = 0.0f;
	if (canopy->getRightForcedDeep() != -1.0f) toggleRight = 0.0f;

	// hard toggle input if unstowing
	if (canopy->getLeftStowed() && spinalCord->trigger_left) {
		toggleLeft = 0.75f;
	}
	if (canopy->getRightStowed() && spinalCord->trigger_right) {
		toggleRight = 0.75f;
	}

	// set toggles
	canopy->setLeftDeep( spinalCord->left * penalty );
	canopy->setRightDeep( spinalCord->right * penalty );

	if (toggleLeft > spinalCord->leftRearRiser && toggleLeft > spinalCord->leftWarp) {
		totalInputLeft = toggleLeft;
	} else if (spinalCord->leftRearRiser > toggleLeft && spinalCord->leftRearRiser > spinalCord->leftWarp) {
		totalInputLeft = spinalCord->leftRearRiser;
	} else {
		totalInputLeft = spinalCord->leftWarp;
	}
	if (toggleRight > spinalCord->rightRearRiser && toggleRight > spinalCord->rightWarp) {
		totalInputRight = toggleRight;
	} else if (spinalCord->rightRearRiser > toggleRight && spinalCord->rightRearRiser > spinalCord->rightWarp) {
		totalInputRight = spinalCord->rightRearRiser;
	} else {
		totalInputRight = spinalCord->rightWarp;
	}


	if( totalInputLeft != 0 && totalInputRight == 0 ) {
		if (canopy->getLeftStowed() && spinalCord->trigger_left) {
			_targetSequence = &unstowLeftSequence;
		} else if (spinalCord->modifier) {
			_targetSequence = &steerLeftSequenceHalf;
		} else {
			_targetSequence = &steerLeftSequence;
		}
	}
	if( totalInputRight != 0 && totalInputLeft == 0 ) {
		if (canopy->getRightStowed() && spinalCord->trigger_right) {
			_targetSequence = &unstowRightSequence;
		} else if (spinalCord->modifier) {
			_targetSequence = &steerRightSequenceHalf;
		} else {
			_targetSequence = &steerRightSequence;
		}
	}
	if( totalInputLeft != 0 && totalInputRight != 0 ) {
		if (canopy->getLeftStowed() || canopy->getRightStowed()) {
			_targetSequence = &groupingUnstowSequence;
		} else if (spinalCord->modifier) {
			_targetSequence = &groupingSequenceHalf;
		} else {
			_targetSequence = &groupingSequence;
		}
	}

	// unstow toggles
	if (spinalCord->left > 0.1f) {
		canopy->setLeftStowed(false);
	}
	if (spinalCord->right > 0.1f) {
		canopy->setRightStowed(false);
	}

    // local coordinate system of base jumper
    NxMat34 pose = _phActor->getGlobalPose();
    NxVec3 x = pose.M.getColumn(0);
    NxVec3 y = pose.M.getColumn(1);
    NxVec3 z = pose.M.getColumn(2);



	// altitude [m]
	//NxVec3 pos = _phActor->getGlobalPosition();
	//const float altitude = pos.y;
	//const float arch_pose_area = 1.9f;

	//// air density: converted to linear from barometric equation [0:10] km altitude
	//// http://www.denysschen.com/catalogue/density.aspx
	//const float AirDensityOld = altitude <= 10000.0f ? (1.196f - 0.0000826f * altitude) : (0.27f);

	//// add drag force
	//float Cd = 0.4f;	// altitude suit = 0.4f
	//const float mTracking = database::Suit::getRecord( _jumper->getVirtues()->equipment.suit.id )->mTracking;
	//Cd *= mTracking;
	//// Drag force vector
	//NxVec3 VecFd = -_phActor->getLinearVelocity();
	//VecFd.normalize();

	//float Fd = 0.5f * AirDensityOld * velocity.magnitudeSquared() * Cd * arch_pose_area * getCore()->getRandToolkit()->getUniform(0.94f, 1.06f);
	//_phActor->addForceAtLocalPos(Fd*VecFd, NxVec3(0, -3.0f, 0));

    // air resistance coefficient
    const float ARmult = 2.5f;
    float AR = ARmult * virtues->getTrackingAirResistance();
    if( database::Suit::getRecord( virtues->equipment.suit.id )->wingsuit )
    {
        AR = ARmult * virtues->getFrogAirResistance();
    }

    // terminal velocity
    const float Vt = sqrt( 9.8f * _phActor->getMass() / AR );
    const float It = velocity.magnitude() / Vt;

    NxVec3 dir = velocity * -1;
    dir.normalize();

    // air resistance force
    const NxVec3 Far = dir * getAirResistancePower( velocity.magnitude() / Vt ) * _phActor->getMass() * 9.8f;

    // finalize motion equation    
    _phActor->addForce( Far );
}