2310 lines
65 KiB
C++
2310 lines
65 KiB
C++
//=============================================================================
|
|
// Copyright (C) 2001 Radical Entertainment Ltd. All rights reserved.
|
|
//
|
|
// File: vehicleinit.cpp
|
|
//
|
|
// Description: init stuff for the vehicle, that is only called once!
|
|
//
|
|
// History: Aug 2, 2002 + Created -- gmayer
|
|
//
|
|
//=============================================================================
|
|
|
|
|
|
//========================================
|
|
// System Includes
|
|
//========================================
|
|
|
|
#include <simcommon/skeletoninfo.hpp>
|
|
#include <simcommon/simstate.hpp>
|
|
#include <simcommon/simstatearticulated.hpp>
|
|
#include <simcommon/simulatedobject.hpp>
|
|
#include <simphysics/articulatedphysicsobject.hpp>
|
|
#include <simphysics/physicsjoint.hpp>
|
|
#include <simphysics/physicsobject.hpp>
|
|
#include <simcommon/simenvironment.hpp>
|
|
#include <simcollision/collisionobject.hpp>
|
|
#include <simcollision/collisionvolume.hpp>
|
|
#include <mission/charactersheet/charactersheetmanager.h>
|
|
#include <simcollision/collisiondisplay.hpp>
|
|
|
|
#include <raddebug.hpp>
|
|
#include <raddebugwatch.hpp>
|
|
|
|
#include <p3d/anim/drawablepose.hpp>
|
|
#include <p3d/shadow.hpp>
|
|
|
|
#include <string.h>
|
|
|
|
//========================================
|
|
// Project Includes
|
|
//========================================
|
|
|
|
#include <worldsim/redbrick/vehicle.h>
|
|
#include <worldsim/worldobject.h>
|
|
|
|
#include <worldsim/worldphysicsmanager.h>
|
|
#include <worldsim/redbrick/geometryvehicle.h>
|
|
#include <worldsim/redbrick/rootmatrixdriver.h>
|
|
#include <worldsim/redbrick/suspensionjointdriver.h>
|
|
#include <worldsim/redbrick/vehicleeventlistener.h>
|
|
#include <worldsim/redbrick/wheel.h>
|
|
#include <worldsim/redbrick/redbrickcollisionsolveragent.h>
|
|
|
|
#include <worldsim/redbrick/physicslocomotion.h>
|
|
#include <worldsim/redbrick/trafficlocomotion.h>
|
|
|
|
#include <worldsim/character/charactermanager.h>
|
|
|
|
|
|
#include <memory/srrmemory.h>
|
|
#include <mission/gameplaymanager.h>
|
|
|
|
#include <meta/carstartlocator.h>
|
|
|
|
#include <debug/debuginfo.h>
|
|
|
|
|
|
#include <ai/actionbuttonhandler.h>
|
|
#include <ai/actionbuttonmanager.h>
|
|
|
|
#include <meta/eventlocator.h>
|
|
#include <meta/spheretriggervolume.h>
|
|
#include <meta/recttriggervolume.h>
|
|
|
|
#include <worldsim/character/character.h>
|
|
|
|
#include <gameflow/gameflow.h>
|
|
|
|
using namespace sim;
|
|
|
|
// The force required to knock a collectible off
|
|
const float MIN_FORCE_DETACH_COLLECTIBLES = 30000.0f;
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::Vehicle
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: Vehicle
|
|
//
|
|
//=============================================================================
|
|
Vehicle::Vehicle() :
|
|
mGeometryVehicle( NULL ),
|
|
mName( NULL ),
|
|
mVehicleID( VehicleEnum::INVALID ),
|
|
mTerrainType( TT_Road),
|
|
mInterior( false ),
|
|
mpEventLocator( NULL ),
|
|
mCharacterSheetCarIndex( -1 ),
|
|
m_IsSimpleShadow( true )
|
|
{
|
|
mTranslucent = true;
|
|
mDrawVehicle = true;
|
|
|
|
mTransform.Identity();
|
|
|
|
mVehicleCentralIndex = -1;
|
|
|
|
// wtf?
|
|
mInitialPosition.Set(0.0f, 8.0f, 20.0f);
|
|
mResetFacingRadians = 0.0f;
|
|
|
|
mVehicleFacing.Set(0.0f, 0.0f, 1.0f);
|
|
mVehicleUp.Set(0.0f, 1.0f, 0.0f);
|
|
|
|
#ifdef RAD_GAMECUBE
|
|
HeapMgr()->PushHeap( GMA_GC_VMM );
|
|
#else
|
|
GameMemoryAllocator allocator = GetGameplayManager()->GetCurrentMissionHeap();
|
|
HeapMgr()->PushHeap( allocator );
|
|
#endif
|
|
mGeometryVehicle = new GeometryVehicle;
|
|
#ifdef RAD_GAMECUBE
|
|
HeapMgr()->PopHeap( GMA_GC_VMM );
|
|
#else
|
|
HeapMgr()->PopHeap( allocator );
|
|
#endif
|
|
|
|
|
|
//mPhysicsVehicle = new PhysicsVehicle;
|
|
//mPhysicsVehicle = 0; test this motherfucker
|
|
|
|
// should this be here or in Init?
|
|
// shouldn't really be in this class at all
|
|
// TODO - take this shit out
|
|
//mVehicleRender = new VehicleRender(this);
|
|
|
|
|
|
mSimStateArticulated = 0;
|
|
mPoseEngine = 0;
|
|
mRootMatrixDriver = 0;
|
|
|
|
//mPoseEngineOutOfCar = 0;
|
|
//mRootMatrixDriverOutOfCar = 0;
|
|
|
|
|
|
mSimStateArticulatedOutOfCar = 0;
|
|
mSimStateArticulatedInCar = 0;
|
|
|
|
mGas = 0.0f;
|
|
mLastGas = 0.0f;
|
|
mDeltaGas = 0.0f;
|
|
mBrake = 0.0f;
|
|
mWheelTurnAngle = 0.0f;
|
|
mReverse = 0.0f;
|
|
mEBrake = 0.0f;
|
|
|
|
mBrakeTimer = 0.0f;
|
|
mBrakeActingAsReverse = false;
|
|
|
|
mGasBrakeDisabled = false;
|
|
|
|
mUnmodifiedInputWheelTurnAngle = 0.0f;
|
|
|
|
mVelocityCM.Set(0.0f, 0.0f, 0.0f);
|
|
mSpeed = 0.0f;
|
|
mSpeedKmh = 0.0f;
|
|
mLastSpeedKmh = 0.0f;
|
|
mAccelMss = 0.0f;
|
|
mPercentOfTopSpeed = 0.0f;
|
|
|
|
mRollingFrictionForce = 2.0f; // need to tune? I don't think so
|
|
//mRollingFrictionForce = 1.5f; // need to tune? I don't think so
|
|
|
|
mRPM = 0.0f;
|
|
mBaseRPM = 500.0f;
|
|
mMaxRpm = 6500.0f;
|
|
|
|
mRPMUpRate = 10.0f;
|
|
mRPMDownRate = 50.0f;
|
|
//mShiftPointHigh = 3500.0f;
|
|
//mShiftPointLow = 1000.0f;
|
|
|
|
//mShiftPointHigh = 4000.0f;
|
|
mShiftPointHigh = 4500.0f;
|
|
//mShiftPointLow = 1500.0f;
|
|
mShiftPointLow = 2000.0f;
|
|
|
|
|
|
mGear = 0; // neutral?
|
|
|
|
mNumGears = -1; // unset
|
|
mGearRatios = 0;
|
|
mFinalDriveRatio = -1.0f; // unset
|
|
|
|
mSkidLevel = 0.0f;
|
|
mBurnoutLevel = 0.0f;
|
|
mSlipGasModifier = 1.0f;
|
|
|
|
int i;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
mInertialJointDrivers[i] = 0;
|
|
mPhysicsJointMatrixModifiers[i] = 0;
|
|
}
|
|
mJointIndexToInertialJointDriverMapping = 0;
|
|
|
|
mCollisionAreaIndex = -1;
|
|
|
|
mDoorDJoint = -1;
|
|
mDoorPJoint = -1;
|
|
mHoodJoint = -1;
|
|
mTrunkJoint = -1;
|
|
|
|
mDoorDDamageLevel = 0;
|
|
mDoorPDamageLevel = 0;
|
|
mHoodDamageLevel = 0;
|
|
mTrunkDamageLevel = 0;
|
|
|
|
mOkToDrawSelf = true;
|
|
mSteeringWheelsOutOfContact = false;
|
|
mAirBorn = false;
|
|
mWasAirborn = false;
|
|
mWasAirbornTimer = 0.0f;
|
|
mWeebleOn = false;
|
|
mInstabilityOffsetOn = false;
|
|
|
|
mSpeedBurstTimer = 0.0f;
|
|
mBuildingUpSpeedBurst = false;
|
|
mDoSpeedBurst = false;
|
|
mFOVToRestore = 1.57f;
|
|
mSpeedBurstTimerHalf = 0.0f;
|
|
|
|
//mDamageType = 0; // 0 is unset - normally 1, 2, or 3
|
|
mDamageType = VDT_UNSET;
|
|
|
|
mVehicleDestroyed = false;
|
|
mVehicleCanSustainDamage = true;
|
|
//mVehicleCanSustainDamage = false;
|
|
|
|
mIsADestroyObjective = false;
|
|
|
|
mHitPoints = 2.0f;
|
|
|
|
mDamageOutResetTimer = 0.0f;
|
|
|
|
mSmokeOffset.Set(0.0f, -0.5f, 1.5f);
|
|
|
|
// mHitJoint = 0;
|
|
|
|
mTrafficVehicle = NULL;
|
|
|
|
mCollisionLateralResistanceDropFactor = 1.0f;
|
|
|
|
mUserDrivingCar = false;
|
|
|
|
mDesiredDoorPosition[0] = mDesiredDoorPosition[1] = 0.0f;
|
|
mDesiredDoorAction[0] = mDesiredDoorAction[1] = DOORACTION_NONE;
|
|
|
|
mpTriggerVolume = NULL;
|
|
|
|
mpDriver = NULL;
|
|
|
|
mDoingRockford = false;
|
|
mDoingWheelie = false;
|
|
|
|
|
|
strcpy(mDriverName,"phantom");
|
|
// mDriverName[0] = 0;
|
|
mPhantomDriver = false;
|
|
|
|
|
|
// vehicle event stuff
|
|
mVehicleEventListener = 0;
|
|
|
|
mDoingJumpBoost = false;
|
|
|
|
mNoSkid = false; // only true for frink's hovering vehicles (also the ghost ship)
|
|
mNoFrontSkid = false; // only true for the rocket car
|
|
|
|
mBrakeLightsOn = false;
|
|
mReverseLightsOn = false;
|
|
mDontShowBrakeLights = false;
|
|
|
|
mCMOffsetSetToOriginal = false;
|
|
|
|
mOutOfControl = false;
|
|
mCollidedWithVehicle = false;
|
|
|
|
mNormalizedMagnitudeOfVehicleHit = 0.0f;
|
|
mWasHitByVehicle = false;
|
|
mWasHitByVehicleType = VT_LAST;
|
|
|
|
mDamperShouldNotPullDown[0] = false;
|
|
mDamperShouldNotPullDown[1] = false;
|
|
mDamperShouldNotPullDown[2] = false;
|
|
mDamperShouldNotPullDown[3] = false;
|
|
|
|
|
|
mNumTurbos = 3; // default to 3 for now
|
|
mSecondsTillNextTurbo = 0.0f;
|
|
|
|
mUsingInCarPhysics = true;
|
|
|
|
//mWaitingToSwitchToOutOfCar = false;
|
|
//mOutOfCarSwitchTimer = 0.0f; // brutal fucking hack
|
|
|
|
mNoDamageTimer = 0.0f;
|
|
|
|
mAlreadyPlayedExplosion = false;
|
|
|
|
mEBrakeTimer = 0.0f;
|
|
|
|
mWheelTurnAngleInputValue = 0.0f;
|
|
|
|
mDrawWireFrame = false;
|
|
mLosingTractionDueToAccel = false; // for plum - just debug output
|
|
|
|
mHijackedByUser = false;
|
|
|
|
|
|
|
|
mDesignerParams.mDpGamblingOdds= 1.0f; //Chuck: set the Gambling Odds to 1.0 or 1:1 by default.
|
|
mbPlayerCar = false;
|
|
|
|
mOurRestSeatingPosition.Set(0.0f, 0.0f, 0.0f);
|
|
mNPCRestSeatingPosition.Set(0.0f, 0.0f, 0.0f);
|
|
mYAccelForSeatingOffset = 0.0f;
|
|
|
|
mVelocityCMLag.Set(0.0f, 0.0f, 0.0f);
|
|
mPositionCMLag.Set(0.0f, 0.0f, 0.0f);
|
|
|
|
// value... fresh from my ass:
|
|
//mBounceLimit = 0.5f;
|
|
//mBounceLimit = 0.25f;
|
|
mBounceLimit = 0.11f;
|
|
|
|
|
|
//mMaxBounceDisplacementPerSecond = 1.0f;
|
|
mMaxBounceDisplacementPerSecond = 2.0f;
|
|
|
|
mBounceAccelThreshold = 1.0f; // below this value just try and move back to rest
|
|
//mBounceAccelThreshold = 2.0f; // below this value just try and move back to rest
|
|
|
|
|
|
mForceToDetachCollectible = MIN_FORCE_DETACH_COLLECTIBLES;
|
|
|
|
mHasDoors = true;
|
|
mVisibleCharacters = true;
|
|
mIrisTransition = false;
|
|
mAllowSlide = true;
|
|
mHighRoof = false;
|
|
mCharacterScale = 1.0f;
|
|
|
|
|
|
// Lets set the default to inflict half damage on this vehicle when they explode
|
|
s_DamageFromExplosion = 0.5f;
|
|
// And no damage on player vehicles
|
|
s_DamageFromExplosionPlayer = 0;
|
|
|
|
mStuckOnSideTimer = 0.0f;
|
|
mAlreadyCalledAutoResetOnSpot = false;
|
|
|
|
|
|
mOriginalCMOffset.x = 0.0f;
|
|
mOriginalCMOffset.y = 0.0f;
|
|
mOriginalCMOffset.z = 0.0f;
|
|
|
|
mBottomOutSpeedMaintenance = 0.0f;
|
|
|
|
mTriggerActive = false;
|
|
|
|
mAtRestAsFarAsTriggersAreConcerned = true;
|
|
|
|
mLocoSwitchedToPhysicsThisFrame = false;
|
|
|
|
mCreatedByParkedCarManager = false;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::Init
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: (char* name, int num, SimEnvironment* se, VehicleLocomotionType loco)
|
|
//
|
|
// Return: bool
|
|
//
|
|
//=============================================================================
|
|
bool Vehicle::Init( const char* name, SimEnvironment* se, VehicleLocomotionType loco, VehicleType vt, bool startoutofcar)
|
|
{
|
|
if(mbPlayerCar ==true)
|
|
{
|
|
mCharacterSheetCarIndex = GetCharacterSheetManager()->GetCarIndex( name );
|
|
}
|
|
else
|
|
{
|
|
mCharacterSheetCarIndex = -1;
|
|
}
|
|
|
|
mDrawVehicle = true;
|
|
|
|
mVehicleType = vt;
|
|
|
|
rAssert( mName == NULL );
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mName = new(gma)char[strlen(name)+1];
|
|
strcpy( mName, name );
|
|
|
|
CollisionEntityDSG::SetName(mName);
|
|
|
|
mLoco = loco;
|
|
|
|
AssignEnumBasedOnName();
|
|
|
|
//++++++++++++++++++++
|
|
// the designer params
|
|
//++++++++++++++++++++
|
|
|
|
|
|
//mDesignerParams.mDpGasScale = 8.0f; // proportional to mass
|
|
//mDesignerParams.mDpGasScale = 6.0f; // proportional to mass
|
|
//mDesignerParams.mDpGasScale = 3.0f; // proportional to mass
|
|
mDesignerParams.mDpGasScale = 4.0f; // proportional to mass
|
|
|
|
mDesignerParams.mDpSlipGasScale = 4.0f;
|
|
|
|
mDesignerParams.mDpHighSpeedGasScale = 2.0f;
|
|
//mDesignerParams.mDpGasScaleSpeedThreshold = 0.5f;
|
|
mDesignerParams.mDpGasScaleSpeedThreshold = 1.0f; // make this the default so it is not used for the time being
|
|
|
|
|
|
mDesignerParams.mDpBrakeScale = 3.0f; // proportional to mass
|
|
|
|
//mDesignerParams.mDpTopSpeedKmh = 300.0f;
|
|
//mDesignerParams.mDpTopSpeedKmh = 250.0f;
|
|
mDesignerParams.mDpTopSpeedKmh = 220.0f;
|
|
|
|
mDesignerParams.mDpMass = 1000.0f; // think of it as kg
|
|
|
|
mDesignerParams.mDpMaxWheelTurnAngle = 35.0f; // in degrees
|
|
//mDesignerParams.mDpMaxWheelTurnAngle = 30.0f; // in degrees
|
|
//mDesignerParams.mDpMaxWheelTurnAngle = 24.0f; // in degrees
|
|
//mDesignerParams.mDpHighSpeedSteeringDrop = 0.25f; // 0.0 to 1.0
|
|
mDesignerParams.mDpHighSpeedSteeringDrop = 0.0f; // 0.0 to 1.0
|
|
|
|
// for wheel
|
|
//mDesignerParams.mDpTireLateralStaticGrip = 2.5f;
|
|
//mDesignerParams.mDpTireLateralStaticGrip = 5.0f;
|
|
mDesignerParams.mDpTireLateralStaticGrip = 4.0f;
|
|
|
|
|
|
mDesignerParams.mDpTireLateralResistanceNormal = 110.0f;
|
|
mDesignerParams.mDpTireLateralResistanceSlip = 35.0f;
|
|
|
|
mDesignerParams.mDpEBrakeEffect = 0.5f;
|
|
|
|
//mDesignerParams.mDpTireLateralResistanceSlipNoEBrake = 20.0f; // this one's for more out of control driving
|
|
mDesignerParams.mDpTireLateralResistanceSlipNoEBrake = 50.0f; // this one's for more out of control driving
|
|
mDesignerParams.mDpSlipEffectNoEBrake = 0.1f;
|
|
|
|
mDesignerParams.mDpCMOffset.x = 0.0f;
|
|
mDesignerParams.mDpCMOffset.y = 0.0f;
|
|
mDesignerParams.mDpCMOffset.z = 0.0f;
|
|
|
|
// don't think they need to touch these for now
|
|
mDesignerParams.mDpSuspensionLimit = 0.4f;
|
|
mDesignerParams.mDpSpringk = 0.5f;
|
|
mDesignerParams.mDpDamperc = 0.2f;
|
|
|
|
mDesignerParams.mDpSuspensionYOffset = 0.0f;
|
|
|
|
mDesignerParams.mHitPoints = 2.0f;
|
|
//mDesignerParams.mHitPoints = 0.5f;
|
|
|
|
//mDesignerParams.mDpBurnoutRange = 0.2f;
|
|
mDesignerParams.mDpBurnoutRange = 0.3f;
|
|
|
|
mDesignerParams.mDpWheelieRange = 0.0f;
|
|
mDesignerParams.mDpWheelieYOffset = 0.0f;
|
|
mDesignerParams.mDpWheelieZOffset = 0.0f;
|
|
|
|
mDesignerParams.mDpMaxSpeedBurstTime = 1.0f;
|
|
mDesignerParams.mDpDonutTorque = 10.0f;
|
|
|
|
mDesignerParams.mDpWeebleOffset = -1.0f;
|
|
|
|
|
|
mVehicleState = VS_NORMAL;
|
|
mTireLateralResistance = mDesignerParams.mDpTireLateralResistanceNormal;
|
|
|
|
mSteeringInputThreshold = 0.7f;
|
|
mSteeringPreSlope = 0.5f;
|
|
|
|
|
|
bool localizedDamage;
|
|
//localizedDamage = mGeometryVehicle->Init(name, this, num);
|
|
localizedDamage = mGeometryVehicle->Init(name, this, 0);
|
|
|
|
// change the logic so that localizedDamage is true if there as at
|
|
// least one localized damage texture
|
|
|
|
|
|
if(!localizedDamage)
|
|
{
|
|
//mDamageType = 3; // traffic
|
|
mDamageType = VDT_TRAFFIC;
|
|
}
|
|
|
|
InitSimState(se);
|
|
|
|
InitGroundPlane();
|
|
|
|
FetchWheelMapping();
|
|
InitWheelsAndLinkSuspensionJointDrivers();
|
|
|
|
|
|
mGeometryVehicle->InitParticles();
|
|
//if(mVehicleType == VT_USER)
|
|
if(1)// mVehicleType == VT_USER || mVehicleType == VT_AI) change this to init for all, only draw for USER - that way it is totally safe to switch vehicle type on the fly
|
|
{
|
|
mGeometryVehicle->InitSkidMarks();
|
|
}
|
|
|
|
|
|
|
|
bool flappingJointPresent = InitFlappingJoints();
|
|
if(flappingJointPresent)
|
|
{
|
|
//if(mDamageType == 3)
|
|
if(mDamageType == VDT_TRAFFIC)
|
|
{
|
|
//rAssertMsg(0, "Fink, what are you doing?");
|
|
|
|
}
|
|
|
|
// else
|
|
|
|
//mDamageType = 1;
|
|
mDamageType = VDT_USER;
|
|
|
|
}
|
|
else if(mDamageType == VDT_UNSET) // still unset
|
|
{
|
|
mDamageType = VDT_AI;
|
|
}
|
|
|
|
// should be set for sure at this point
|
|
rAssertMsg(mDamageType != VDT_UNSET, "damage type not set?");
|
|
|
|
InitGears();
|
|
|
|
//CalculateDragCoeffBasedOnTopSpeed();
|
|
|
|
CalculateValuesBasedOnDesignerParams();
|
|
// does this:
|
|
// SetupPhysicsProperties();
|
|
// CalculatedDragCoeffBasedOnTopSpeed
|
|
// SetDesignerParams on Wheels
|
|
|
|
|
|
CreateLocomotions();
|
|
mLocoSwitchedToPhysicsThisFrame = false;
|
|
|
|
|
|
|
|
// need this call here?
|
|
Reset( false );
|
|
|
|
SetupRadDebugWatchStuff();
|
|
|
|
// moved here from VehicleCentral
|
|
InitEventLocator();
|
|
|
|
|
|
// vehicle event stuff
|
|
mVehicleEventListener = new VehicleEventListener(this);
|
|
|
|
|
|
|
|
|
|
//mUsingInCarPhysics
|
|
|
|
// default at this point in creation is to be using the incar physics.
|
|
//
|
|
// perhaps there should be a paramter to say which, passed into
|
|
|
|
|
|
if(startoutofcar)
|
|
{
|
|
SetOutOfCarSimState();
|
|
}
|
|
|
|
/*
|
|
if( GetGameFlow()->GetCurrentContext() == CONTEXT_DEMO )
|
|
{
|
|
mWaitingToSwitchToOutOfCar = true;
|
|
}
|
|
else
|
|
{
|
|
mWaitingToSwitchToOutOfCar = false;
|
|
}
|
|
*/
|
|
|
|
// actually any use in this result?
|
|
// might as well just assert.
|
|
//return result;
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitEventLocator
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::InitEventLocator()
|
|
{
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
|
|
mpEventLocator = new(gma)EventLocator();
|
|
mpEventLocator->SetName( mName );
|
|
mpEventLocator->AddRef();
|
|
mpEventLocator->SetEventType( LocatorEvent::CAR_DOOR );
|
|
int id = -1;
|
|
|
|
ActionButton::GetInCar* pABHandler = static_cast<ActionButton::GetInCar*>( ActionButton::GetInCar::NewAction( mpEventLocator ) );
|
|
rAssert( dynamic_cast<ActionButton::GetInCar*>( pABHandler ) != NULL );
|
|
rAssert( pABHandler );
|
|
bool bResult = GetActionButtonManager()->AddAction( pABHandler, id );
|
|
rAssert( bResult );
|
|
|
|
// this part is done in VehicleCentral::AddVehicleToActiveList
|
|
//pABHandler->SetVehicleId( mNumActiveVehicles );
|
|
|
|
mpEventLocator->SetData( id );
|
|
|
|
// grab the car bounding box
|
|
mExtents = GetSimState()->GetCollisionObject()->GetCollisionVolume()->mBoxSize;
|
|
|
|
// slap down a trigger volume for getting intop car
|
|
const float edge = 1.0f; // how big? TODO : tunable?
|
|
mpTriggerVolume = new(gma) RectTriggerVolume( mTransform.Row(3),
|
|
mTransform.Row(0),
|
|
mTransform.Row(1),
|
|
mTransform.Row(2),
|
|
mExtents.x + edge,
|
|
mExtents.y + edge,
|
|
mExtents.z + edge);
|
|
|
|
// add volume to event trigger
|
|
mpEventLocator->SetNumTriggers( 1, gma );
|
|
mpEventLocator->AddTriggerVolume( mpTriggerVolume );
|
|
mpTriggerVolume->SetLocator( mpEventLocator );
|
|
mpTriggerVolume->SetName( "get_in" );
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
// Vehicle::AssignEnumBasedOnName
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::AssignEnumBasedOnName()
|
|
{
|
|
/*
|
|
enum VehicleID
|
|
{
|
|
BART_V = 0, // bart_v 0
|
|
APU_V, // apu_v 1
|
|
SNAKE_V, // snake_v 2
|
|
HOMER_V, // homer_v 3
|
|
FAMIL_V, // famil_v 4
|
|
GRAMP_V, // gramp_v 5
|
|
CLETU_V, // cletu_v 6
|
|
WIGGU_V, // wiggu_v 7
|
|
KRUSTYKAR_NOTYETIN, //
|
|
MARGE_V, // marge_v 9
|
|
OTTOBUS_NOTYETIN,
|
|
MOESDUFFTRUCK_NOTYETIN,
|
|
SMITH_V, // smith_v 12
|
|
FLANDERSMOTORHOME_NOTYETIN,
|
|
MCBAINHUMMER_NOTYETIN,
|
|
ALIEN_NOTYETIN,
|
|
ZOMBI_V, // zombi_v 16
|
|
MUNSTERS_NOTYETIN,
|
|
HUMMER2_NOTYETIN,
|
|
|
|
CVAN, // cVan 19
|
|
COMPACTA, // compactA 20
|
|
|
|
COMIC_V, // comic_v 21
|
|
SKINN_V, // skinn_v 22
|
|
|
|
|
|
|
|
// some more new ai cars
|
|
CCOLA, // 23
|
|
CSEDAN,
|
|
CPOLICE,
|
|
CCELLA,
|
|
CCELLB,
|
|
CCELLC,
|
|
CCELLD,
|
|
|
|
// some more new traffic cars
|
|
MINIVANA, // 30
|
|
PICKUPA,
|
|
TAXIA,
|
|
SPORTSA,
|
|
SPORTSB,
|
|
SUVA,
|
|
WAGONA, // 36
|
|
|
|
// some more new cars: nov 12, 2002
|
|
HBIKE_V, // 37
|
|
BURNS_V, // 38
|
|
HONOR_V, // 39
|
|
|
|
CARMOR, // 40
|
|
CCURATOR, // 41
|
|
CHEARS, // 42
|
|
CKLIMO, // 43
|
|
CLIMO, // 44
|
|
CNERD, // 45
|
|
|
|
FRINK_V, // 46
|
|
|
|
// some more new cars: dec 18, 2002
|
|
CMILK, // 47
|
|
CDONUT, // 48
|
|
BBMAN_V, // 49
|
|
BOOKB_V, // 50
|
|
CARHOM_V, // 51
|
|
ELECT_V, // 52
|
|
FONE_V, // 53
|
|
GRAMR_V, // 54
|
|
MOE_V, // 55
|
|
MRPLO_V, // 56
|
|
OTTO_V, // 57
|
|
PLOWK_V, // 58
|
|
SCORP_V, // 59
|
|
WILLI_V, // 60
|
|
|
|
// new traffic cars: Jan 11, 2003
|
|
SEDANA, // 61
|
|
SEDANB, // 62
|
|
|
|
// new Chase cars: Jan 11, 2003
|
|
CBLBART, // 63
|
|
CCUBE, // 64
|
|
CDUFF, // 65
|
|
CNONUP, // 66
|
|
|
|
// new Driver cars: Jan 11, 2003
|
|
LISA_V, // 67
|
|
KRUST_V, // 68
|
|
|
|
// new Traffic cars: Jan 13, 2003
|
|
COFFIN, // 69
|
|
HALLO, // 70
|
|
SHIP, // 71
|
|
WITCHCAR, // 72
|
|
|
|
// new Traffic husk: Feb 10, 2003
|
|
HUSKA, // 73
|
|
|
|
// new Driver cars: Feb 11, 2003
|
|
ATV_V, // 74
|
|
DUNE_V, // 75
|
|
HYPE_V, // 76
|
|
KNIGH_V, // 77
|
|
MONO_V, // 78
|
|
OBLIT_V, // 79
|
|
ROCKE_V, // 80
|
|
|
|
// new Traffic cars: Feb 24, 2003
|
|
AMBUL, // 81
|
|
BURNSARM, // 82
|
|
FISHTRUC, // 83
|
|
GARBAGE, // 84
|
|
ICECREAM, // 85
|
|
ISTRUCK, // 86
|
|
NUCTRUCK, // 87
|
|
PIZZA, // 88
|
|
SCHOOLBU, // 89
|
|
VOTETRUC, // 90
|
|
|
|
// new traffic cars: April 2, 2003
|
|
GLASTRUC, // 91
|
|
CFIRE_V, // 92
|
|
|
|
CBONE,
|
|
REDBRICK, // 94
|
|
|
|
NUM_VEHICLES,
|
|
INVALID
|
|
|
|
};
|
|
|
|
*/
|
|
|
|
if(strcmp(mName, "bart_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::BART_V;
|
|
}
|
|
|
|
if(strcmp(mName, "apu_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::APU_V;
|
|
}
|
|
|
|
if(strcmp(mName, "snake_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SNAKE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "homer_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HOMER_V;
|
|
}
|
|
|
|
if(strcmp(mName, "famil_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::FAMIL_V;
|
|
}
|
|
|
|
if(strcmp(mName, "gramp_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::GRAMP_V;
|
|
}
|
|
|
|
if(strcmp(mName, "cletu_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CLETU_V;
|
|
}
|
|
|
|
if(strcmp(mName, "wiggu_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::WIGGU_V;
|
|
}
|
|
|
|
if(strcmp(mName, "marge_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::MARGE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "smith_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SMITH_V;
|
|
}
|
|
|
|
if(strcmp(mName, "zombi_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ZOMBI_V;
|
|
}
|
|
|
|
if(strcmp(mName, "cVan") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CVAN;
|
|
}
|
|
|
|
if(strcmp(mName, "compactA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::COMPACTA;
|
|
}
|
|
|
|
if(strcmp(mName, "comic_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::COMIC_V;
|
|
}
|
|
|
|
if(strcmp(mName, "skinn_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SKINN_V;
|
|
}
|
|
|
|
if(strcmp(mName, "cCola") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCOLA;
|
|
}
|
|
|
|
if(strcmp(mName, "cSedan") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CSEDAN;
|
|
}
|
|
|
|
if(strcmp(mName, "cPolice") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CPOLICE;
|
|
}
|
|
|
|
if(strcmp(mName, "cCellA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCELLA;
|
|
}
|
|
|
|
if(strcmp(mName, "cCellB") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCELLB;
|
|
}
|
|
|
|
if(strcmp(mName, "cCellC") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCELLC;
|
|
}
|
|
|
|
if(strcmp(mName, "cCellD") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCELLD;
|
|
}
|
|
|
|
if(strcmp(mName, "minivanA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::MINIVANA;
|
|
}
|
|
|
|
if(strcmp(mName, "pickupA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::PICKUPA;
|
|
}
|
|
|
|
if(strcmp(mName, "taxiA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::TAXIA;
|
|
}
|
|
|
|
if(strcmp(mName, "sportsA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SPORTSA;
|
|
}
|
|
|
|
if(strcmp(mName, "sportsB") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SPORTSB;
|
|
}
|
|
|
|
if(strcmp(mName, "SUVA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SUVA;
|
|
}
|
|
|
|
if(strcmp(mName, "wagonA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::WAGONA;
|
|
}
|
|
|
|
if(strcmp(mName, "hbike_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HBIKE_V;
|
|
mNoSkid = true;
|
|
}
|
|
|
|
|
|
if(strcmp(mName, "burns_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::BURNS_V;
|
|
}
|
|
|
|
if(strcmp(mName, "honor_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HONOR_V;
|
|
mNoFrontSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "cArmor") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CARMOR;
|
|
}
|
|
|
|
if(strcmp(mName, "cCurator") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCURATOR;
|
|
}
|
|
|
|
if(strcmp(mName, "cHears") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CHEARS;
|
|
}
|
|
|
|
if(strcmp(mName, "cKlimo") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CKLIMO;
|
|
}
|
|
|
|
if(strcmp(mName, "cLimo") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CLIMO;
|
|
}
|
|
|
|
if(strcmp(mName, "cNerd") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CNERD;
|
|
}
|
|
|
|
if(strcmp(mName, "frink_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::FRINK_V;
|
|
mNoSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "cMilk") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CMILK;
|
|
}
|
|
|
|
if(strcmp(mName, "cDonut") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CDONUT;
|
|
}
|
|
|
|
if(strcmp(mName, "bbman_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::BBMAN_V;
|
|
}
|
|
|
|
if(strcmp(mName, "bookb_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::BOOKB_V;
|
|
}
|
|
|
|
if(strcmp(mName, "carhom_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CARHOM_V;
|
|
}
|
|
|
|
if(strcmp(mName, "elect_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ELECT_V;
|
|
}
|
|
|
|
if(strcmp(mName, "fone_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::FONE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "gramR_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::GRAMR_V;
|
|
}
|
|
|
|
if(strcmp(mName, "moe_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::MOE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "mrplo_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::MRPLO_V;
|
|
}
|
|
|
|
if(strcmp(mName, "otto_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::OTTO_V;
|
|
}
|
|
|
|
if(strcmp(mName, "plowk_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::PLOWK_V;
|
|
}
|
|
|
|
if(strcmp(mName, "scorp_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SCORP_V;
|
|
}
|
|
|
|
if(strcmp(mName, "willi_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::WILLI_V;
|
|
}
|
|
|
|
if(strcmp(mName, "sedanA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SEDANA;
|
|
}
|
|
|
|
if(strcmp(mName, "sedanB") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SEDANB;
|
|
}
|
|
|
|
if(strcmp(mName, "cBlbart") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CBLBART;
|
|
}
|
|
|
|
if(strcmp(mName, "cCube") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CCUBE;
|
|
}
|
|
|
|
if(strcmp(mName, "cDuff") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CDUFF;
|
|
}
|
|
|
|
if(strcmp(mName, "cNonup") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CNONUP;
|
|
}
|
|
|
|
if(strcmp(mName, "lisa_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::LISA_V;
|
|
}
|
|
|
|
if(strcmp(mName, "krust_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::KRUST_V;
|
|
}
|
|
|
|
if(strcmp(mName, "coffin") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::COFFIN;
|
|
}
|
|
|
|
if(strcmp(mName, "hallo") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HALLO;
|
|
}
|
|
|
|
if(strcmp(mName, "ship") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SHIP;
|
|
m_IsSimpleShadow = false;
|
|
mNoSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "witchcar") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::WITCHCAR;
|
|
mNoSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "huskA") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HUSKA;
|
|
}
|
|
|
|
if(strcmp(mName, "atv_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ATV_V;
|
|
}
|
|
|
|
if(strcmp(mName, "dune_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::DUNE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "hype_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::HYPE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "knigh_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::KNIGH_V;
|
|
}
|
|
|
|
if(strcmp(mName, "mono_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::MONO_V;
|
|
mNoSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "oblit_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::OBLIT_V;
|
|
}
|
|
|
|
if(strcmp(mName, "rocke_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ROCKE_V;
|
|
mNoFrontSkid = true;
|
|
}
|
|
|
|
if(strcmp(mName, "ambul") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::AMBUL;
|
|
}
|
|
|
|
if(strcmp(mName, "burnsarm") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::BURNSARM;
|
|
}
|
|
|
|
if(strcmp(mName, "fishtruc") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::FISHTRUC;
|
|
}
|
|
|
|
if(strcmp(mName, "garbage") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::GARBAGE;
|
|
}
|
|
|
|
if(strcmp(mName, "icecream") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ICECREAM;
|
|
}
|
|
|
|
if(strcmp(mName, "IStruck") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::ISTRUCK;
|
|
}
|
|
|
|
if(strcmp(mName, "nuctruck") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::NUCTRUCK;
|
|
}
|
|
|
|
if(strcmp(mName, "pizza") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::PIZZA;
|
|
}
|
|
|
|
if(strcmp(mName, "schoolbu") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::SCHOOLBU;
|
|
}
|
|
|
|
if(strcmp(mName, "votetruc") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::VOTETRUC;
|
|
}
|
|
|
|
if(strcmp(mName, "glastruc") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::GLASTRUC;
|
|
}
|
|
|
|
if(strcmp(mName, "cFire_v") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CFIRE_V;
|
|
}
|
|
|
|
if(strcmp(mName, "cBone") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::CBONE;
|
|
}
|
|
|
|
|
|
// the best for last!
|
|
if(strcmp(mName, "redbrick") == 0)
|
|
{
|
|
mVehicleID = VehicleEnum::REDBRICK;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// call back for debug watcher:
|
|
//typedef void (*RADDEBUGWATCH_CALLBACK)( void* userData );
|
|
void DebugWatchVehicleTuningCallback(void* userData)
|
|
{
|
|
((Vehicle*)userData)->CalculateValuesBasedOnDesignerParams();
|
|
}
|
|
|
|
|
|
void InflictDamageHoodCallback(void* userData)
|
|
{
|
|
((Vehicle*)userData)->DebugInflictDamageHood();
|
|
}
|
|
|
|
void InflictDamageBackCallback(void* userData)
|
|
{
|
|
((Vehicle*)userData)->DebugInflictDamageBack();
|
|
}
|
|
|
|
void InflictDamageDriverSideCallback(void* userData)
|
|
{
|
|
((Vehicle*)userData)->DebugInflictDamageDriverSide();
|
|
}
|
|
|
|
void InflictDamagePassengerSideCallback(void* userData)
|
|
{
|
|
((Vehicle*)userData)->DebugInflictDamagePassengerSide();
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::SetupRadDebugWatchStuff
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::SetupRadDebugWatchStuff()
|
|
{
|
|
radDbgWatchAddFloat(&mSpeedKmh, "speed kmh", mName, NULL, (void*)this, 0.0f, 1000.0f); // just want to observe this
|
|
radDbgWatchAddFloat(&mForceToDetachCollectible, "Detach Collectible Force", mName, DebugWatchVehicleTuningCallback, (void*)this, 5000.0f, 50000.0f );
|
|
|
|
// Add the static explosion damage variables to the watcher. Make sure to only add them once
|
|
// under group "Vehicle"
|
|
static bool staticVariablesInitialized = false;
|
|
if ( !staticVariablesInitialized)
|
|
{
|
|
radDbgWatchAddFloat(&Vehicle::s_DamageFromExplosion, "Damage from Explosion (other)", "Vehicle", NULL, NULL, 0, 10.0f );
|
|
radDbgWatchAddFloat(&Vehicle::s_DamageFromExplosionPlayer, "Damage from Explosion (player)", "Vehicle", NULL, NULL, 0, 10.0f );
|
|
staticVariablesInitialized = true;
|
|
}
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpMass), "mass", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 10000.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpGasScale), "gas scale", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 30.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpSlipGasScale), "slip gas scale", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 30.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpHighSpeedGasScale), "high speed gas scale", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 30.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpGasScaleSpeedThreshold), "gas scale threshold", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpBrakeScale), "brake scale", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 30.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpTopSpeedKmh), "top speed kmh", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 300.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpMaxWheelTurnAngle), "max wheel turn angle", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 55.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpHighSpeedSteeringDrop), "high speed steering drop", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpTireLateralStaticGrip), "tire grip", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 15.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpTireLateralResistanceNormal), "normal steering", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 500.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpTireLateralResistanceSlip), "slip steering", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 500.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpEBrakeEffect), "ebrake effect", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpTireLateralResistanceSlipNoEBrake), "slip steering without ebrake", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 500.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpSlipEffectNoEBrake), "slip effect without ebrake", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpCMOffset.x), "cmoffset x", mName, DebugWatchVehicleTuningCallback, (void*)this, -1.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpCMOffset.y), "cmoffset y", mName, DebugWatchVehicleTuningCallback, (void*)this, -1.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpCMOffset.z), "cmoffset z", mName, DebugWatchVehicleTuningCallback, (void*)this, -1.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpSuspensionLimit), "suspension limit", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpSpringk), "spring k", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpDamperc), "damper c", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpSuspensionYOffset), "suspension Y Offset", mName, DebugWatchVehicleTuningCallback, (void*)this, -1.0f, 1.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpBurnoutRange), "burnout range", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpMaxSpeedBurstTime), "max speed burst time", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 10.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpDonutTorque), "donut torque", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 20.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpWeebleOffset), "weeble offset", mName, DebugWatchVehicleTuningCallback, (void*)this, -3.0f, 3.0f );
|
|
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpWheelieRange), "wheelie range", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 1.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpWheelieYOffset), "wheelie Y offset", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, 2.0f );
|
|
radDbgWatchAddFloat(&(mDesignerParams.mDpWheelieZOffset), "wheelie Z offset", mName, DebugWatchVehicleTuningCallback, (void*)this, 0.0f, -2.0f );
|
|
|
|
radDbgWatchAddFunction( "Inflict Damage Hood", &InflictDamageHoodCallback, (void*)this, mName );
|
|
radDbgWatchAddFunction( "Inflict Damage Back", &InflictDamageBackCallback, (void*)this, mName );
|
|
radDbgWatchAddFunction( "Inflict Damage Driver Side", &InflictDamageDriverSideCallback, (void*)this, mName );
|
|
radDbgWatchAddFunction( "Inflict Damage Passenger Side", &InflictDamagePassengerSideCallback, (void*)this, mName );
|
|
|
|
}
|
|
|
|
//=============================================================================
|
|
// Vehicle::~Vehicle
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: Vehicle
|
|
//
|
|
//=============================================================================
|
|
Vehicle::~Vehicle()
|
|
{
|
|
if(GetGameplayManager()->GetCurrentVehicle() == this)
|
|
{
|
|
GetGameplayManager()->UnregisterVehicleHUDIcon();
|
|
}
|
|
|
|
delete mGeometryVehicle;
|
|
|
|
delete mPhysicsLocomotion;
|
|
delete mTrafficLocomotion;
|
|
|
|
int i;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
delete mWheels[i];
|
|
mSuspensionJointDrivers[i]->Release();
|
|
|
|
// TODO - need to wrap these somehow in case they don't exist?
|
|
if(mInertialJointDrivers[i])
|
|
{
|
|
mInertialJointDrivers[i]->Release();
|
|
}
|
|
if(mPhysicsJointMatrixModifiers[i])
|
|
{
|
|
mPhysicsJointMatrixModifiers[i]->Release();
|
|
}
|
|
|
|
}
|
|
|
|
delete[] mGearRatios;
|
|
delete[] mJointIndexToWheelMapping;
|
|
if(mJointIndexToInertialJointDriverMapping)
|
|
{
|
|
delete[] mJointIndexToInertialJointDriverMapping;
|
|
}
|
|
|
|
// these moved to a method that can be called from VehicleCentral::RemoveVehicleFromActiveList
|
|
//RemoveSelfFromCollisionManager();
|
|
//GetWorldPhysicsManager()->FreeCollisionAreaIndex(mCollisionAreaIndex);
|
|
//mCollisionAreaIndex = -1;
|
|
|
|
mGroundPlaneWallVolume->Release();
|
|
mGroundPlanePhysicsProperties->Release();
|
|
mPhysicsProperties->Release();
|
|
|
|
if(mRootMatrixDriver)
|
|
{
|
|
mRootMatrixDriver->Release();
|
|
}
|
|
|
|
mPoseEngine->Release();
|
|
|
|
mGroundPlaneSimState->Release();
|
|
|
|
//p3d::inventory->SelectSection("Level");
|
|
//p3d::inventory->Remove(mSimStateArticulated->GetCollisionObject());
|
|
//p3d::inventory->Remove(mSimStateArticulated->GetSimulatedObject());
|
|
|
|
|
|
tRefCounted::Release(mSimStateArticulatedInCar);
|
|
tRefCounted::Release(mSimStateArticulatedOutOfCar);
|
|
|
|
|
|
int id = mpEventLocator->GetData();
|
|
GetActionButtonManager()->RemoveActionByIndex( id );
|
|
|
|
|
|
mpEventLocator->Release();
|
|
|
|
if(mpDriver)
|
|
{
|
|
// DO NOT remove a pedestrian manually!
|
|
// We need them for recycling within the level.
|
|
if( mpDriver->GetRole() != Character::ROLE_PEDESTRIAN )
|
|
{
|
|
GetCharacterManager()->RemoveCharacter(mpDriver);
|
|
}
|
|
tRefCounted::Release(mpDriver);
|
|
}
|
|
|
|
GetCharacterManager()->ClearTargetVehicle(this);
|
|
|
|
rAssert( mName != NULL );
|
|
delete[] mName;
|
|
|
|
if(mVehicleEventListener)
|
|
{
|
|
delete mVehicleEventListener;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::CreateLocomotions
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::CreateLocomotions()
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
// is this vehicle being setup for A or B?
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mPhysicsLocomotion = new(gma)PhysicsLocomotion(this);
|
|
mTrafficLocomotion = new(gma)TrafficLocomotion(this);
|
|
|
|
//?
|
|
SetLocomotion( mLoco );
|
|
MEMTRACK_POP_GROUP( "Vehicle" );
|
|
}
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitWheelsAndLinkSuspensionJointDrivers
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::InitWheelsAndLinkSuspensionJointDrivers()
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
CollisionObject* collObj = mSimStateArticulated->GetCollisionObject();
|
|
CollisionVolume* collVol = collObj->GetCollisionVolume();
|
|
rAssert(collVol);
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
|
|
int i;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
CollisionVolume* sub = collVol->GetSubCollisionVolume(mWheelToJointIndexMapping[i], true); // true because we only care about the local sub volume
|
|
|
|
// sub should be of type SphereVolumeType
|
|
rAssert(sub->Type() == SphereVolumeType);
|
|
|
|
float radius = ((SphereVolume*)sub)->GetRadius();
|
|
|
|
mWheels[i] = new(gma)Wheel;
|
|
|
|
// now we can init the goddamn wheel
|
|
if(i < 2) // todo - way to NOT hardcode this for 4 wheels????
|
|
{
|
|
mWheels[i]->Init(this, i, radius, false, true);
|
|
}
|
|
else
|
|
{
|
|
mWheels[i]->Init(this, i, radius, true, false);
|
|
// try all wheel drive
|
|
//mWheels[i]->Init(this, i, radius, true, true);
|
|
}
|
|
|
|
mSuspensionJointDrivers[i] = new(gma)SuspensionJointDriver(mWheels[i], mWheelToJointIndexMapping[i]);
|
|
|
|
mSuspensionJointDrivers[i]->AddRef();
|
|
mPoseEngine->AddPoseDriver(1, mSuspensionJointDrivers[i]);
|
|
}
|
|
MEMTRACK_POP_GROUP("Vehicle");
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitFlappingJoints
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
bool Vehicle::InitFlappingJoints()
|
|
{
|
|
|
|
tPose* p3dPose = mGeometryVehicle->GetP3DPose();
|
|
rAssert(p3dPose);
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mJointIndexToInertialJointDriverMapping = new(gma) int[p3dPose->GetNumJoint()];
|
|
|
|
// TODO ?
|
|
// ok to use memset?
|
|
memset(mJointIndexToInertialJointDriverMapping, -1, (sizeof(int) * p3dPose->GetNumJoint()) );
|
|
|
|
|
|
int count = 0;
|
|
|
|
rmt::Vector axis;
|
|
rmt::Vector rotAxis;
|
|
|
|
bool atLeastOneFlappingJointPresent = false;
|
|
|
|
|
|
//-----------------
|
|
// driver-side door
|
|
//-----------------
|
|
axis.Set(0.0f, 0.0f, -1.0f);
|
|
rotAxis.Set(0.0f, 1.0f, 0.0f);
|
|
if(AddFlappingJoint("DoorDTrans", "DoorDRot", axis, rotAxis, count, &mDoorDJoint))
|
|
{
|
|
// override default settings
|
|
|
|
mInertialJointDrivers[count]->SetSpeedRate(15.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(180.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(0.5f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(2.0f);
|
|
|
|
atLeastOneFlappingJointPresent = true;
|
|
}
|
|
|
|
//--------------------
|
|
// passenger-side door
|
|
//--------------------
|
|
count++;
|
|
rotAxis.Set(0.0f, -1.0f, 0.0f);
|
|
if(AddFlappingJoint("DoorPTrans", "DoorPRot", axis, rotAxis, count, &mDoorPJoint))
|
|
{
|
|
mInertialJointDrivers[count]->SetSpeedRate(15.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(180.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(0.5f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(2.0f);
|
|
|
|
atLeastOneFlappingJointPresent = true;
|
|
}
|
|
|
|
//-----
|
|
// hood
|
|
//-----
|
|
count++;
|
|
axis.Set(0.0f, 0.0f, 1.0f);
|
|
rotAxis.Set(-1.0f, 0.0f, 0.0f);
|
|
if(AddFlappingJoint("HoodTrans", "HoodRot", axis, rotAxis, count, &mHoodJoint))
|
|
{
|
|
mInertialJointDrivers[count]->SetSpeedRate(3.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(300.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(1.0f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(1.0f);
|
|
|
|
atLeastOneFlappingJointPresent = true;
|
|
}
|
|
|
|
//------
|
|
// trunk
|
|
//------
|
|
count++;
|
|
axis.Set(0.0f, 0.0f, -1.0f);
|
|
rotAxis.Set(1.0f, 0.0f, 0.0f);
|
|
if(AddFlappingJoint("TrunkTrans", "TrunkRot", axis, rotAxis, count, &mTrunkJoint))
|
|
{
|
|
mInertialJointDrivers[count]->SetSpeedRate(12.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(180.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(1.0f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(1.0f);
|
|
|
|
atLeastOneFlappingJointPresent = true;
|
|
}
|
|
|
|
return atLeastOneFlappingJointPresent;
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::AddFlappingJoint
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: (const char* transJointName, const char* rotJointName, rmt::Vector& axis, rmt::Vector& rotAxis, int count)
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
bool Vehicle::AddFlappingJoint(const char* transJointName, const char* rotJointName, rmt::Vector& axis, rmt::Vector& rotAxis, int count, int* collisionJointIndex)
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
|
|
//SkeletonInfo* skelInfo = p3d::find<SkeletonInfo>(mName);
|
|
SkeletonInfo* skelInfo = mPhObj->GetSkeletonInfo ();
|
|
rAssert(skelInfo);
|
|
|
|
// release debugging:
|
|
if(skelInfo == 0)
|
|
{
|
|
char buffy[64];
|
|
sprintf(buffy, "can't find skelInfo for %s\n", mName);
|
|
rReleaseString(buffy);
|
|
}
|
|
|
|
|
|
tPose* p3dPose = mGeometryVehicle->GetP3DPose();
|
|
rAssert(p3dPose);
|
|
|
|
|
|
int indexTrans;
|
|
int indexRot;
|
|
|
|
indexTrans = p3dPose->FindJointIndex(transJointName);
|
|
indexRot = p3dPose->FindJointIndex(rotJointName);
|
|
|
|
*collisionJointIndex = indexRot;
|
|
|
|
if(indexTrans == -1 || indexRot == -1)
|
|
{
|
|
MEMTRACK_POP_GROUP( "Vehicle" );
|
|
return false;
|
|
}
|
|
|
|
#ifdef RAD_DEBUG // wrap in define?
|
|
tPose::Joint* transJoint = p3dPose->GetJoint(indexTrans);
|
|
tPose::Joint* rotJoint = p3dPose->GetJoint(indexRot);
|
|
rAssert(rotJoint->parent == transJoint);
|
|
#endif
|
|
|
|
skelInfo->SetJointAxis(indexTrans, axis, 1.0f);
|
|
skelInfo->SetJointAxis(indexRot, axis, 1.0f);
|
|
|
|
skelInfo->SetJointRotAxis(indexRot, rotAxis);
|
|
|
|
// add new driver...
|
|
mJointIndexToInertialJointDriverMapping[indexRot] = count;
|
|
|
|
PhysicsJoint* phizJoint = mPhObj->GetJoint(indexRot);
|
|
rAssert(phizJoint);
|
|
|
|
// test
|
|
//phizJoint->SetInvStiffness(0.5f);
|
|
|
|
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mInertialJointDrivers[count] = new(gma) PhysicsJointInertialEffector(phizJoint);
|
|
|
|
mInertialJointDrivers[count]->AddRef();
|
|
|
|
// defaults
|
|
// override shortly after this...
|
|
|
|
mInertialJointDrivers[count]->SetSpeedRate(15.0f);
|
|
//mInertialJointDrivers[count]->SetAccelRate(20.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(180.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(1.0f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(2.0f);
|
|
|
|
// new
|
|
// start out disabled
|
|
|
|
mPhObj->GetJoint(indexRot)->SetInvStiffness(0.0f);
|
|
mPhObj->GetJoint(indexRot)->ResetDeformation();
|
|
|
|
mInertialJointDrivers[count]->SetIsEnabled(false);
|
|
|
|
// debug
|
|
//mInertialJointDrivers[count]->SetIsEnabled(true);
|
|
|
|
|
|
/*
|
|
mInertialJointDrivers[count]->SetSpeedRate(0.0f);
|
|
//mInertialJointDrivers[count]->SetAccelRate(20.0f);
|
|
mInertialJointDrivers[count]->SetAccelRate(0.0f);
|
|
mInertialJointDrivers[count]->SetGravityRate(0.0f);
|
|
mInertialJointDrivers[count]->SetCentrifugalRate(2.0f);
|
|
*/
|
|
|
|
|
|
// TODO - which pose engine pass?
|
|
mPoseEngine->AddPoseDriver(2, mInertialJointDrivers[count]);
|
|
|
|
// also need this other jointmatrixmodifier thing...
|
|
mPhysicsJointMatrixModifiers[count] = new(gma) PhysicsJointMatrixModifier(phizJoint);
|
|
|
|
mPhysicsJointMatrixModifiers[count]->AddRef();
|
|
|
|
mPoseEngine->AddPoseDriver(2, mPhysicsJointMatrixModifiers[count]);
|
|
|
|
MEMTRACK_POP_GROUP("Vehicle");
|
|
return true;
|
|
}
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitGears
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::InitGears()
|
|
{
|
|
mNumGears = 6; // TODO - not sure we actually want designers to worry about this?
|
|
// maybe, they can just choose number of gears and there will be pre-defined ratios??
|
|
//
|
|
// recall: all this gear shit is just for sound and does not affect performance
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mGearRatios = new(gma) float[mNumGears];
|
|
|
|
mFinalDriveRatio = 3.42f;
|
|
|
|
mGearRatios[0] = 2.97f; // 1st
|
|
//mGearRatios[1] = 2.07f; // 2nd
|
|
mGearRatios[1] = 1.8f; // 2nd
|
|
mGearRatios[2] = 1.43f; // 3rd
|
|
mGearRatios[3] = 1.00f; // 4th
|
|
mGearRatios[4] = 0.84f; // 5th
|
|
mGearRatios[5] = 0.56f; // 6th
|
|
|
|
|
|
|
|
/* some stuff fromt trav for a corvette
|
|
|
|
Transmission..........6-speed manual
|
|
Final-drive ratio..........3.42:1, limited slip
|
|
Gear..........Ratio..........Mph/1000 rpm..........Max. test speed
|
|
I..........2.97..........7.4..........48 mph (6500 rpm)
|
|
II..........2.07..........10.6..........69 mph (6500 rpm)
|
|
III..........1.43..........15.3..........100 mph (6500 rpm)
|
|
IV..........1.00..........21.9..........143 mph (6500 rpm)
|
|
V..........0.84..........26.1..........168 mph (6450 rpm)
|
|
VI..........0.56..........39.2..........155 mph (4000 rpm)
|
|
|
|
*/
|
|
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::SetupPhysicsProperties
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::SetupPhysicsProperties()
|
|
{
|
|
// called when we first create the sim state, as well as when
|
|
// we set new designer paramters.
|
|
|
|
//float volume = mPhObj->GetVolume();
|
|
|
|
float volume = ((ArticulatedPhysicsObject*)(mSimStateArticulatedInCar->GetSimulatedObject(-1)))->GetVolume();
|
|
|
|
// TODO - verify this is coming back in the correct units
|
|
|
|
// can't set mass directly
|
|
float density = mDesignerParams.mDpMass / volume;
|
|
|
|
// TODO - which of these do we actually want to allow designers to modify?
|
|
//mPhysicsProperties->SetFrictCoeffCGS(0.8f);
|
|
//mPhysicsProperties->SetRestCoeffCGS(1.05f);
|
|
//mPhysicsProperties->SetTangRestCoeffCGS(0.0f);
|
|
|
|
// these values slide you along walls a little nicer
|
|
mPhysicsProperties->SetFrictCoeffCGS(0.3f);
|
|
mPhysicsProperties->SetRestCoeffCGS(1.15f);
|
|
mPhysicsProperties->SetTangRestCoeffCGS(-0.6f);
|
|
|
|
|
|
//mPhysicsProperties->SetDensityCGS(density / 1000000.0f); // our density is in g / m^3
|
|
mPhysicsProperties->SetDensityCGS(density); // our density is in g / m^3
|
|
|
|
//mSimStateArticulated->SetPhysicsProperties(mPhysicsProperties);
|
|
|
|
mSimStateArticulatedInCar->SetPhysicsProperties(mPhysicsProperties);
|
|
if(mSimStateArticulatedOutOfCar)
|
|
{
|
|
mSimStateArticulatedOutOfCar->SetPhysicsProperties(mPhysicsProperties);
|
|
}
|
|
|
|
mPhObj->SetInvTWDissip(0);
|
|
mPhObj->SetDissipationInternalRate(0);
|
|
mPhObj->SetDissipationDeformationRate(0); //no good Martin
|
|
|
|
|
|
// TODO - where to put this!
|
|
// should i even use it?
|
|
|
|
// TODO
|
|
// temp hack to fix lack of phizsim
|
|
|
|
const rmt::Vector& gravity = GetWorldPhysicsManager()->mSimEnvironment->Gravity();// this or CGS ?
|
|
|
|
//float gravity_y = 9.81f;
|
|
float gravity_y = -1.0f * gravity.y;
|
|
|
|
//rmt::Vector gravity = SG::phizSim.mSimEnvironment->Gravity();
|
|
//mSuspensionRestValue = mDesignerParams.mDpMass * rmt::Fabs(gravity.y) * 0.25f;
|
|
mSuspensionRestValue = mDesignerParams.mDpMass * gravity_y * 0.25f;
|
|
|
|
// new thing aimed at minimizing strage whipping effects on the car when the wheels bottom out
|
|
// and you get insane values calculated for suspension force
|
|
mSuspensionMaxValue = mDesignerParams.mDpMass * gravity_y * 2.5f; // TODO - find the right value
|
|
|
|
|
|
mCMOffset = mOriginalCMOffset;
|
|
|
|
mCMOffset.Add(mDesignerParams.mDpCMOffset);
|
|
|
|
((ArticulatedPhysicsObject*)(mSimStateArticulatedInCar->GetSimulatedObject(-1)))->SetExternalCMOffset(mCMOffset);
|
|
|
|
//mPhObj->SetExternalCMOffset(mCMOffset);
|
|
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitGroundPlane
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::InitGroundPlane()
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
|
|
rmt::Vector p(0.0f, 0.0f, 0.0f);
|
|
rmt::Vector n(0.0f, 1.0f, 0.0f);
|
|
|
|
HeapMgr()->PushHeap (gma);
|
|
|
|
mGroundPlaneWallVolume = new WallVolume(p, n);
|
|
mGroundPlaneWallVolume->AddRef();
|
|
|
|
mGroundPlaneSimState = (sim::ManualSimState*)(SimState::CreateManualSimState(mGroundPlaneWallVolume));
|
|
mGroundPlaneSimState->AddRef();
|
|
|
|
mGroundPlaneSimState->GetCollisionObject()->SetManualUpdate(true);
|
|
mGroundPlaneSimState->GetCollisionObject()->SetAutoPair(false);
|
|
mGroundPlaneSimState->GetCollisionObject()->SetIsStatic(true);
|
|
|
|
char buffy[128];
|
|
sprintf(buffy, "%s_groundplane", mName);
|
|
|
|
mGroundPlaneSimState->GetCollisionObject()->SetName(buffy);
|
|
|
|
mGroundPlaneSimState->mAIRefIndex = this->GetGroundPlaneAIRef();
|
|
mGroundPlaneSimState->mAIRefPointer = (void*)this;
|
|
|
|
mGroundPlanePhysicsProperties = new PhysicsProperties;
|
|
mGroundPlanePhysicsProperties->AddRef();
|
|
|
|
mGroundPlanePhysicsProperties->SetFrictCoeffCGS(0.8f);
|
|
mGroundPlanePhysicsProperties->SetRestCoeffCGS(1.15f);
|
|
mGroundPlanePhysicsProperties->SetTangRestCoeffCGS(0.0f);
|
|
|
|
mGroundPlaneSimState->SetPhysicsProperties(mGroundPlanePhysicsProperties);
|
|
|
|
HeapMgr()->PopHeap (gma);
|
|
|
|
/*
|
|
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
|
|
rmt::Vector p, n;
|
|
p.Set(0.0f, 0.0f, 0.0f);
|
|
//n.Set(0.0f, 1.0f, 0.0f);
|
|
n.Set(0.0f, 0.0f, 1.0f);
|
|
|
|
mGroundPlaneWallVolume = new(gma) WallVolume(p, n);
|
|
|
|
mGroundPlaneWallVolume->AddRef();
|
|
|
|
mGroundPlaneSimState = SimState::CreateSimState(mGroundPlaneWallVolume);
|
|
mGroundPlaneSimState->AddRef();
|
|
//mGroundPlaneSimState->GetCollisionObject()->SetIsStatic(true);
|
|
mGroundPlaneSimState->GetCollisionObject()->SetAutoPair(false); // TODO - does not work yet
|
|
// TODO - name?
|
|
|
|
char buffy[128];
|
|
sprintf(buffy, "%s_groundplane", mName);
|
|
|
|
mGroundPlaneSimState->GetCollisionObject()->SetName(buffy);
|
|
|
|
mGroundPlaneSimState->mAIRefIndex = this->GetGroundPlaneAIRef();
|
|
mGroundPlaneSimState->mAIRefPointer = (void*)this;
|
|
|
|
mGroundPlanePhysicsProperties = new(gma) PhysicsProperties;
|
|
mGroundPlanePhysicsProperties->AddRef();
|
|
|
|
mGroundPlanePhysicsProperties->SetFrictCoeffCGS(0.8f);
|
|
mGroundPlanePhysicsProperties->SetRestCoeffCGS(1.05f);
|
|
mGroundPlanePhysicsProperties->SetTangRestCoeffCGS(0.0f);
|
|
|
|
mGroundPlaneSimState->SetPhysicsProperties(mGroundPlanePhysicsProperties);
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
MEMTRACK_POP_GROUP("Vehicle");
|
|
}
|
|
|
|
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::FetchWheelMapping
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::FetchWheelMapping()
|
|
{
|
|
// should have already done these asserts, but just in case things
|
|
// get moved around a bit...
|
|
|
|
rAssert(mGeometryVehicle);
|
|
|
|
tPose* p3dPose = mGeometryVehicle->GetP3DPose();
|
|
rAssert(p3dPose);
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mJointIndexToWheelMapping = new(gma) int[p3dPose->GetNumJoint()];
|
|
|
|
memset(mJointIndexToWheelMapping, -1, (sizeof(int) * p3dPose->GetNumJoint()) );
|
|
|
|
//
|
|
// naming convention so far:
|
|
//
|
|
// should have joints named:
|
|
//
|
|
// w0, w1, w2, w3
|
|
|
|
char buffy[8];
|
|
memset(buffy, 0, sizeof(buffy));
|
|
|
|
|
|
int i;
|
|
for(i = 0; i < 4; i++)
|
|
{
|
|
// TODO!
|
|
// safe to use sprintf ??
|
|
sprintf(buffy, "w%d", i);
|
|
mWheelToJointIndexMapping[i] = p3dPose->FindJointIndex(buffy);
|
|
|
|
// for convenience we can look up either way....
|
|
mJointIndexToWheelMapping[mWheelToJointIndexMapping[i]] = i;
|
|
|
|
tPose::Joint* joint = p3dPose->GetJoint(mWheelToJointIndexMapping[i]);
|
|
|
|
// fill mSuspensionRestPoints[4] with the transform row of the joint object space
|
|
// matrix
|
|
|
|
mSuspensionRestPointsFromFile[i] = joint->objectMatrix.Row(3);
|
|
|
|
mSuspensionRestPoints[i] = mSuspensionRestPointsFromFile[i];
|
|
|
|
mSuspensionRestPoints[i].y += mDesignerParams.mDpSuspensionYOffset;
|
|
|
|
// used to be other stuff in here for radius, and Wheels, and suspensionjointdrivers
|
|
|
|
}
|
|
|
|
// passenger/driver locations
|
|
|
|
int passengerIndex = p3dPose->FindJointIndex( "pl" );
|
|
int driverIndex = p3dPose->FindJointIndex( "dl" );
|
|
|
|
if(passengerIndex != -1)
|
|
{
|
|
tPose::Joint* joint = p3dPose->GetJoint( passengerIndex );
|
|
mPassengerLocation = joint->objectMatrix.Row(3);
|
|
}
|
|
else
|
|
{
|
|
mPassengerLocation.Set( 0.5f, -0.6f, 0.01f );
|
|
}
|
|
|
|
if(driverIndex != -1)
|
|
{
|
|
tPose::Joint* joint = p3dPose->GetJoint( driverIndex );
|
|
mDriverLocation = joint->objectMatrix.Row(3);
|
|
}
|
|
else
|
|
{
|
|
mDriverLocation.Set( -0.5f, -0.6f, 0.01f );
|
|
}
|
|
|
|
|
|
mWheelBase = mSuspensionRestPoints[3].z - mSuspensionRestPoints[1].z;
|
|
|
|
// smoke location
|
|
|
|
//int smokeIndex = p3dPose->FindJointIndex("smoke");
|
|
int smokeIndex = p3dPose->FindJointIndex("sl");
|
|
tPose::Joint* joint = p3dPose->GetJoint(smokeIndex);
|
|
if (joint)
|
|
{
|
|
mSmokeOffset = joint->objectMatrix.Row(3);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::GetWheel0Offset
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: rmt
|
|
//
|
|
//=============================================================================
|
|
rmt::Vector Vehicle::GetWheel0Offset()
|
|
{
|
|
// this is not accurate as wheel is lurching around but should be close enough for smoke effects?
|
|
rmt::Vector temp = mSuspensionRestPoints[0];
|
|
temp.y -= mWheels[0]->mRadius;
|
|
return temp;
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::GetWheel1Offset
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: rmt
|
|
//
|
|
//=============================================================================
|
|
rmt::Vector Vehicle::GetWheel1Offset()
|
|
{
|
|
rmt::Vector temp = mSuspensionRestPoints[1];
|
|
temp.y -= mWheels[1]->mRadius;
|
|
return temp;
|
|
}
|
|
|
|
//=============================================================================
|
|
// Vehicle::InitSimState
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::InitSimState(SimEnvironment* se)
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
CreatePoseEngine();
|
|
rAssert(mPoseEngine);
|
|
|
|
// The section stuff here is a hack.
|
|
// Tracked to ATG as bug 1259.
|
|
//
|
|
p3d::inventory->PushSection ();
|
|
p3d::inventory->AddSection (SKELCACHE);
|
|
p3d::inventory->SelectSection (SKELCACHE);
|
|
//mSimStateArticulated = SimStateArticulated::CreateSimStateArticulated(mName, mPoseEngine->GetPose(), SimStateAttribute_Default, NULL);
|
|
|
|
SimStateArticulated* newSimState = SimStateArticulated::CreateSimStateArticulated(mName, mPoseEngine->GetPose(), SimStateAttribute_Default, NULL);
|
|
rAssert( mSimStateArticulatedInCar == NULL );
|
|
tRefCounted::Assign( mSimStateArticulatedInCar, newSimState );
|
|
rAssert( mSimStateArticulatedInCar != NULL );
|
|
|
|
|
|
mSimStateArticulatedInCar->mAIRefIndex = PhysicsAIRef::redBrickVehicle;
|
|
|
|
mSimStateArticulatedInCar->mAIRefPointer = (void*)this;
|
|
|
|
|
|
((ArticulatedPhysicsObject*)(mSimStateArticulatedInCar->GetSimulatedObject(-1)))->SetSimEnvironment(se);
|
|
|
|
|
|
|
|
|
|
// new test:
|
|
char buffy[128];
|
|
sprintf(buffy, "%sBV", mName);
|
|
rAssert( mSimStateArticulatedOutOfCar == NULL );
|
|
mSimStateArticulatedOutOfCar = SimStateArticulated::CreateSimStateArticulated(buffy, mPoseEngine->GetPose(), SimStateAttribute_Default, NULL);
|
|
|
|
if(mSimStateArticulatedOutOfCar)
|
|
{
|
|
|
|
mSimStateArticulatedOutOfCar->AddRef();
|
|
mSimStateArticulatedOutOfCar->mAIRefIndex = PhysicsAIRef::redBrickVehicle;
|
|
|
|
mSimStateArticulatedOutOfCar->mAIRefPointer = (void*)this;
|
|
((ArticulatedPhysicsObject*)(mSimStateArticulatedOutOfCar->GetSimulatedObject(-1)))->SetSimEnvironment(se);
|
|
|
|
}
|
|
|
|
|
|
p3d::inventory->PopSection ();
|
|
|
|
// finish initialization with this... then switch back
|
|
mSimStateArticulated = mSimStateArticulatedInCar;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mPhObj = (ArticulatedPhysicsObject*)(mSimStateArticulated->GetSimulatedObject(-1));
|
|
|
|
// fetch once only ever
|
|
// seven fucking days
|
|
//mOriginalCMOffset = mPhObj->GetExternalCMOffset();
|
|
|
|
mOriginalCMOffset.x = 0.0f;
|
|
mOriginalCMOffset.y = 0.0f;
|
|
mOriginalCMOffset.z = 0.0f;
|
|
|
|
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mPhysicsProperties = new(gma) PhysicsProperties; // TODO - who owns - ie. who is responsible to delete
|
|
|
|
mPhysicsProperties->AddRef();
|
|
|
|
/*
|
|
for (int i=0; i<mPhObj->NumSimJoints(); i++)
|
|
{
|
|
PhysicsJoint* joint = mPhObj->GetSimJoint(i);
|
|
P3DASSERT(joint);
|
|
mPoseEngine->AddPoseDriver(2, new PhysicsJointMatrixModifier(joint));
|
|
}
|
|
|
|
sim::PhysicsJointMatrixModifier mPhysicsJointMatrixModifiers[4];
|
|
*/
|
|
MEMTRACK_POP_GROUP( "Vehicle" );
|
|
}
|
|
|
|
|
|
//=============================================================================
|
|
// Vehicle::CreatePoseEngineOutOfCar
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
/*
|
|
void Vehicle::CreatePoseEngineOutOfCar()
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
// TODO - wtf?
|
|
//const int PoseEngineSimPass = 1;
|
|
const int PoseEngineSimPass = 2;
|
|
|
|
rAssert(mGeometryVehicle);
|
|
|
|
|
|
|
|
tPose* p3dPose = mGeometryVehicle->GetP3DPose();
|
|
rAssert(p3dPose);
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mPoseEngine = new(gma) poser::PoseEngine(p3dPose, PoseEngineSimPass+1, p3dPose->GetNumJoint());
|
|
mRootMatrixDriver = new(gma) RootMatrixDriver(&mTransform);
|
|
|
|
mPoseEngine->AddRef();
|
|
mRootMatrixDriver->AddRef();
|
|
mPoseEngine->AddPoseDriver(1, mRootMatrixDriver); // 0 is the pass
|
|
|
|
MEMTRACK_POP_GROUP();
|
|
|
|
}
|
|
*/
|
|
//=============================================================================
|
|
// Vehicle::CreatePoseEngine
|
|
//=============================================================================
|
|
// Description: Comment
|
|
//
|
|
// Parameters: ()
|
|
//
|
|
// Return: void
|
|
//
|
|
//=============================================================================
|
|
void Vehicle::CreatePoseEngine()
|
|
{
|
|
MEMTRACK_PUSH_GROUP( "Vehicle" );
|
|
// TODO - wtf?
|
|
//const int PoseEngineSimPass = 1;
|
|
const int PoseEngineSimPass = 2;
|
|
|
|
rAssert(mGeometryVehicle);
|
|
|
|
|
|
|
|
tPose* p3dPose = mGeometryVehicle->GetP3DPose();
|
|
rAssert(p3dPose);
|
|
|
|
GameMemoryAllocator gma = GetGameplayManager()->GetCurrentMissionHeap();
|
|
mPoseEngine = new(gma) poser::PoseEngine(p3dPose, PoseEngineSimPass+1, p3dPose->GetNumJoint());
|
|
mRootMatrixDriver = new(gma) RootMatrixDriver(&mTransform);
|
|
|
|
mPoseEngine->AddRef();
|
|
mRootMatrixDriver->AddRef();
|
|
//mPoseEngine->AddPoseDriver(1, mRootMatrixDriver); // 0 is the pass
|
|
mPoseEngine->AddPoseDriver(0, mRootMatrixDriver); // 0 is the pass
|
|
|
|
MEMTRACK_POP_GROUP("Vehicle");
|
|
}
|