The-Simpsons-Hit-and-Run/game/code/worldsim/redbrick/redbrickcollisionsolveragen...

928 lines
29 KiB
C++

/*===========================================================================
redbrickcollisionsolveragent.cpp
created Jan 28, 2002
by Greg Mayer
Copyright (c) 2002 Radical Entertainment, Inc.
All rights reserved.
===========================================================================*/
#include <simcommon/simstatearticulated.hpp>
#include <simcommon/simulatedobject.hpp>
#include <worldsim/redbrick/redbrickcollisionsolveragent.h>
#include <worldsim/redbrick/vehicle.h>
#include <worldsim/redbrick/wheel.h>
#include <worldsim/worldphysicsmanager.h>
#include <mission/gameplaymanager.h>
#include <worldsim/avatarmanager.h>
#include <worldsim/avatar.h>
#include <events/eventmanager.h>
#include <sound/soundcollisiondata.h>
#ifdef RAD_XBOX
#include <float.h>
#endif
//------------------------------------------------------------------------
RedBrickCollisionSolverAgent::RedBrickCollisionSolverAgent()
{
//
mBottomedOut = false;
//mBottomedOutScale = 1.0e-5f;
//mBottomedOutScale = 1.0f;
//mBottomedOutScale = 0.0002f;
mBottomedOutScale = 0.0003f;
mWheelSidewaysHit = false;
mWheelSidewaysHitScale = 0.002f;
}
//------------------------------------------------------------------------
RedBrickCollisionSolverAgent::~RedBrickCollisionSolverAgent()
{
//
}
//------------------------------------------------------------------------------------------------
void RedBrickCollisionSolverAgent::ResetCollisionFlags()
{
// TODO - how to properly tie this to rest of vehicle module????
// TODO - need these flags on a car by car basis
mBottomedOut = false;
mWheelSidewaysHit = false;
}
//------------------------------------------------------------------------------------------------
Solving_Answer RedBrickCollisionSolverAgent::TestImpulse(rmt::Vector& impulse, Collision& inCollision)
{
// currently this method does nothing...
//
// test some collision results...
// TODO -
// something more efficient here so we don't have to test this shit every time
CollisionObject* collObjA = inCollision.mCollisionObjectA;
CollisionObject* collObjB = inCollision.mCollisionObjectB;
SimState* simStateA = collObjA->GetSimState();
SimState* simStateB = collObjB->GetSimState();
//
// SOUND EVENT HERE?
//
// need to convert the impulse to a nice friendly float between 0.0 and 1.0
//
// just looking at some empirical data, the range of impulse magnitude seems to be from around
// 0.0 to 100000.0 - at the high end would be a heavy vehicle (3000 kg) hitting a static wall at 122kmh
// a 2000kg car hitting a wall at 150kmh gave 78706.7
#ifdef RAD_DEBUG
if(rmt::IsNan(impulse.x) || rmt::IsNan(impulse.y) || rmt::IsNan(impulse.z))
{
rAssert(0);
}
#endif
float impulseMagnitude = impulse.Magnitude();
if(impulseMagnitude > 100000.0f)
{
int stophere = 1;
}
const float maxIntensity = 100000.0f;
float soundScale = impulseMagnitude / maxIntensity;
if(soundScale > 1.0f)
{
soundScale = 1.0f;
}
if(soundScale < 0.0f)
{
rAssert(0);
}
// SoundCollisionData soundData( soundScale, simStateA->mAIRefPointer, simStateB->mAIRefPointer );
// GetEventManager()->TriggerEvent( EVENT_COLLISION, &soundData );
// up to this point is pretty generic for sound stuff - ie. the guts of PostReactToCollision might look a lot like this?
// here is more vehicle intensive
//if(simStateA->mAIRefIndex == Vehicle::GetAIRef() && simStateB->mAIRefIndex == Vehicle::GetAIRef())
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle && simStateB->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
// car on car
//static float magic = 1.0f;
// fun test
//impulse.Scale(magic);
//int stophere = 1;
if( ((Vehicle*)(simStateA->mAIRefPointer))->mVehicleType == VT_TRAFFIC )
{
}
}
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle || simStateB->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
//PhysicsVehicle* physicsVehicle;
Vehicle* vehicle;
float test = impulse.Magnitude();
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle )
{
vehicle = (Vehicle*)(simStateA->mAIRefPointer);
}
else
{
vehicle = (Vehicle*)(simStateB->mAIRefPointer);
}
// TODO - more detailed test...
// TODO - I'm not sure I like this system...
if(mBottomedOut) // todo - more detailed test for if we are dealing with a wheel
{
//mImpulse.Scale(mBottomedOutScale);
}
if(mWheelSidewaysHit)
{
//mImpulse.Scale(mWheelSidewaysHitScale);
//mImpulse.y = 0.0f; // TODO - expand to below later...
}
}
return Solving_Continue;
}
//=============================================================================
// RedBrickCollisionSolverAgent::CarOnCarAction
//=============================================================================
// Description: Comment
//
// Parameters: (Collision& inCollision)
//
// Return: Solving_Answer
//
//=============================================================================
Solving_Answer RedBrickCollisionSolverAgent::CarOnCarPreTest(Collision& inCollision, int inPass)
{
CollisionObject* collObjA = inCollision.mCollisionObjectA;
CollisionObject* collObjB = inCollision.mCollisionObjectB;
SimState* simStateA = collObjA->GetSimState();
SimState* simStateB = collObjB->GetSimState();
Vehicle* vehicleA = (Vehicle*)(simStateA->mAIRefPointer);
Vehicle* vehicleB = (Vehicle*)(simStateB->mAIRefPointer);
int jointIndexA = inCollision.mIndexA;
int jointIndexB = inCollision.mIndexB;
//vehicleA->TriggerDamage();
//vehicleB->TriggerDamage(); - move the damage triggering to Vehicle::PostReactToCollision
// vehicleA->SetHitJoint(jointIndexA);
// vehicleB->SetHitJoint(jointIndexB);
// for now...
if(1)//vehicleA->mUsingInCarPhysics)
{
if(vehicleA->IsJointAWheel(jointIndexA) || vehicleB->IsJointAWheel(jointIndexB))
{
return Solving_Aborted;
}
if(vehicleA->IsAFlappingJoint(jointIndexA) || vehicleB->IsAFlappingJoint(jointIndexB))
{
// TODO - try taking this out?
return Solving_Aborted;
}
}
//hmmm
// is this the place to switch loco?
if(vehicleA->GetLocomotionType() == VL_TRAFFIC)
{
vehicleA->SetLocomotion(VL_PHYSICS);
}
if(vehicleB->GetLocomotionType() == VL_TRAFFIC)
{
vehicleB->SetLocomotion(VL_PHYSICS);
}
// just in case it has come to rest....
if(simStateA->GetControl() == sim::simAICtrl)
{
simStateA->SetControl(sim::simSimulationCtrl);
}
if(simStateB->GetControl() == sim::simAICtrl)
{
simStateB->SetControl(sim::simSimulationCtrl);
}
return CollisionSolverAgent::PreCollisionEvent(inCollision, inPass);
}
//=============================================================================
// RedBrickCollisionSolverAgent::PreCollisionEvent
//=============================================================================
// Description: Comment
//
// Parameters: (Collision& inCollision, int inPass)
//
// Return: Solving_Answer
//
//=============================================================================
Solving_Answer RedBrickCollisionSolverAgent::PreCollisionEvent(Collision& inCollision, int inPass)
{
// have a look at objects A and B and see if we care about them:
// TODO
// also, depending how steeply we've hit something, we also want to let the solver do it's thing...
// ? mabye cancel out the y component?
// also may skip this depending how tipped we are
CollisionObject* collObjA = inCollision.mCollisionObjectA;
CollisionObject* collObjB = inCollision.mCollisionObjectB;
SimState* simStateA = collObjA->GetSimState();
SimState* simStateB = collObjB->GetSimState();
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle || simStateB->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
//--------------------------------------
// deal specially with car on car action
//--------------------------------------
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle && simStateB->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
// test for hitting a wheel or a flapping joint in here
//
return CarOnCarPreTest(inCollision, inPass);
}
Vehicle* vehicle;
int jointIndex;
rmt::Vector groundContactPoint;
rmt::Vector normalPointingAtCar;
bool carisA = true;
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
vehicle = (Vehicle*)(simStateA->mAIRefPointer);
jointIndex = inCollision.mIndexA;
groundContactPoint = inCollision.GetPositionB();
normalPointingAtCar = inCollision.mNormal;
}
else
{
vehicle = (Vehicle*)(simStateB->mAIRefPointer);
jointIndex = inCollision.mIndexB;
groundContactPoint = inCollision.GetPositionA();
normalPointingAtCar = inCollision.mNormal;
normalPointingAtCar.Scale(-1.0f);
carisA = false;
}
// temp hack cause I think we're hitting our driver every frame:
/*
if(carisA)
{
if(simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable)
{
return Solving_Aborted;
}
}
else
{
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable)
{
return Solving_Aborted;
}
}
*/
/*
this now encompassed below...
if(carisA)
{
if(simStateB->mAIRefIndex == PhysicsAIRef::StateProp)
{
Avatar* playerAvatar = GetAvatarManager()->GetAvatarForPlayer(0);
if(playerAvatar->GetVehicle() == vehicle)
{
GetEventManager()->TriggerEvent( EVENT_HIT_MOVEABLE, (void*)simStateB );
}
}
}
else
{
if(simStateA->mAIRefIndex == PhysicsAIRef::StateProp)
{
Avatar* playerAvatar = GetAvatarManager()->GetAvatarForPlayer(0);
if(playerAvatar->GetVehicle() == vehicle)
{
GetEventManager()->TriggerEvent( EVENT_HIT_MOVEABLE, (void*)simStateA );
}
}
}
*/
if(carisA)
{
if(simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable || simStateB->mAIRefIndex == PhysicsAIRef::StateProp)
{
sim::SimControlEnum control = simStateB->GetControl();
bool ishit = ((DynaPhysDSG*)(simStateB->mAIRefPointer))->mIsHit;
enClasstypeID classid = (enClasstypeID)((DynaPhysDSG*)(simStateB->mAIRefPointer))->GetCollisionAttributes()->GetClasstypeid();
if(simStateB->GetControl() == sim::simAICtrl && ((DynaPhysDSG*)(simStateB->mAIRefPointer))->mIsHit &&
((DynaPhysDSG*)(simStateB->mAIRefPointer))->GetCollisionAttributes()->GetClasstypeid() == PROP_ONETIME_MOVEABLE)
{
return Solving_Aborted;
}
else
{
Avatar* playerAvatar = GetAvatarManager()->GetAvatarForPlayer(0);
if(playerAvatar->GetVehicle() == vehicle)
{
GetEventManager()->TriggerEvent( EVENT_HIT_MOVEABLE, (void*)simStateB );
}
}
}
}
else
{
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable || simStateA->mAIRefIndex == PhysicsAIRef::StateProp)
{
sim::SimControlEnum control = simStateA->GetControl();
bool ishit = ((DynaPhysDSG*)(simStateA->mAIRefPointer))->mIsHit;
enClasstypeID classid = (enClasstypeID)((DynaPhysDSG*)(simStateA->mAIRefPointer))->GetCollisionAttributes()->GetClasstypeid();
if(simStateA->GetControl() == sim::simAICtrl && ((DynaPhysDSG*)(simStateA->mAIRefPointer))->mIsHit &&
((DynaPhysDSG*)(simStateA->mAIRefPointer))->GetCollisionAttributes()->GetClasstypeid() == PROP_ONETIME_MOVEABLE) // safe cast?
{
return Solving_Aborted;
}
else
{
Avatar* playerAvatar = GetAvatarManager()->GetAvatarForPlayer(0);
if(playerAvatar->GetVehicle() == vehicle)
{
GetEventManager()->TriggerEvent( EVENT_HIT_MOVEABLE, (void*)simStateA );
}
}
}
}
if(vehicle->mUsingInCarPhysics)
{
if(vehicle->IsAFlappingJoint(jointIndex))
{
// vehicle->SetHitJoint(jointIndex);
return Solving_Aborted;
}
}
if(vehicle->IsJointAWheel(jointIndex))
{
if(carisA)
{
if(simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizFence)
{
int stophere = 1;
// the old tip test
rmt::Vector worldUp = GetWorldPhysicsManager()->mWorldUp;
float cos10 = 0.9848f;
//if(worldUp.DotProduct(vehicle->mVehicleUp) < cos10)
{
// will this work??
inCollision.mIndexA = 0;
return Solving_Continue;
}
}
if(simStateB->mAIRefIndex != PhysicsAIRef::redBrickPhizStatic) // redBrickPhizMoveableAnim? -> don't think we need to
{
if(vehicle->mUsingInCarPhysics)
{
return Solving_Aborted;
}
else
{
return Solving_Continue;
}
}
}
else
{
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizFence)
{
// the old tip test
rmt::Vector worldUp = GetWorldPhysicsManager()->mWorldUp;
float cos10 = 0.9848f;
//if(worldUp.DotProduct(vehicle->mVehicleUp) < cos10)
{
// will this work??
inCollision.mIndexB = 0;
return Solving_Continue;
}
int stophere = 1;
}
if(simStateA->mAIRefIndex != PhysicsAIRef::redBrickPhizStatic)
{
if(vehicle->mUsingInCarPhysics)
{
return Solving_Aborted;
}
else
{
return Solving_Continue;
}
}
}
/*
// if this is a wheel, but the thing we hit is a vehicle ground plane, then we want to ignore it.
if(carisA)
{
if(simStateB->mAIRefIndex == vehicle->GetGroundPlaneAIRef() ||
simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable) // new - do we want to keep this?
{
return Solving_Aborted;
}
}
else
{
if(simStateA->mAIRefIndex == vehicle->GetGroundPlaneAIRef() ||
simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizMoveable) // new - do we want to keep this?
{
return Solving_Aborted;
}
}
*/
// recall:
// mPositionA = mPositionB + mNormal * mDistance
// SG::phizSim.mCollisionDistanceCGS;
// amount we want to keep in collision
// TODO - even want to do this?
//float slightlyColliding = (SG::phizSim.mCollisionDistanceCGS * 0.1f) * 0.01f; // last factor to make sure we're in meters...
//float slightlyColliding = (SG::phizSim.mCollisionDistanceCGS * 1.0f) * 0.01f; // last factor to make sure we're in meters...
// TODO
// hack to fix for no phizsim
float collisionDistanceCGS = 2.0f;
//float slightlyColliding = (SG::phizSim.mCollisionDistanceCGS * 1.0f) * 0.01f; // last factor to make sure we're in meters...
float slightlyColliding = (collisionDistanceCGS * 1.0f) * 0.01f; // last factor to make sure we're in meters...
// TODO - choose right value here based on coefficient of restituion blah blah
// initial random guessof 0.1 was so low it was never used since the impulses
// kept shit apart.
//
// hmmmm... maybe want to use that? but then how does suspension compress?
//
// if we hit something sideways with the wheel, just apply impulse
float cos80 = 0.1736f;
float cos70 = 0.342f;
// TODO - this isn't nearly adequate!
// TODO
// temp fix
rmt::Vector worldUp = GetWorldPhysicsManager()->mWorldUp;
// new test
//if(vehicle->mPercentOfTopSpeed > 0.3f)
if(vehicle->mPercentOfTopSpeed > 0.1f)
{
int wheelIndex = vehicle->mJointIndexToWheelMapping[jointIndex];
rAssert(wheelIndex >= 0);
rAssert(wheelIndex < 5);
rmt::Vector normVel = vehicle->mSuspensionPointVelocities[wheelIndex];
normVel.NormalizeSafe();
float cos45 = 0.7071f;
if(normalPointingAtCar.DotProduct(normVel) > cos45)
//if(normalPointingAtCar.DotProduct(normVel) > cos70)
{
// the collision is pointing the way we're going so fuck it
//char buffy[128];
//sprintf(buffy, "aborting wheel-static collision fix - pointing too much along velocity\n");
//rDebugPrintf(buffy);
vehicle->SetNoDamperDownFlagOnWheel(wheelIndex);
return Solving_Aborted;
}
}
float cos55 = 0.5736f;
//if( rmt::Fabs((inCollision.mNormal).DotProduct(vehicle->mVehicleUp)) < cos70 || // recall - this is the new line
if( rmt::Fabs((inCollision.mNormal).DotProduct(vehicle->mVehicleUp)) < cos55 || // recall - this is the new line
worldUp.DotProduct(vehicle->mVehicleUp) < cos80) // leave this on at 80
{
//char buffy[128];
//sprintf(buffy, "aborting wheel-static collision fix - too horizontal\n");
//rDebugPrintf(buffy);
int wheelIndex = vehicle->mJointIndexToWheelMapping[jointIndex];
rAssert(wheelIndex >= 0);
rAssert(wheelIndex < 5);
vehicle->SetNoDamperDownFlagOnWheel(wheelIndex);
// temp
// TODO - something?
return Solving_Aborted;
// let collision solver just apply some impulse
//
// TODO - scale down impulse??
mWheelSidewaysHit = true;
if(carisA)
{
inCollision.mIndexA = 0;
}
else
{
inCollision.mIndexB = 0;
}
return CollisionSolverAgent::PreCollisionEvent(inCollision, inPass);
}
if(inCollision.mDistance < slightlyColliding)
{
// need to move along normal by:
float fixAlongCollisionNormal = slightlyColliding - inCollision.mDistance;
float fixAlongSuspensionAxis = fixAlongCollisionNormal / rmt::Fabs( (vehicle->mVehicleUp).DotProduct(inCollision.mNormal) );
// now fixAlongSuspensionAxis is the object space y offset that we should correct to
// this will return true for bottom out
if(vehicle->SetWheelCorrectionOffset(jointIndex, fixAlongSuspensionAxis, normalPointingAtCar, groundContactPoint))
//if(fixAlongSuspensionAxis > 2.0f * physicsVehicle->GetWheelByJoint(jointIndex)->GetSuspensionLimit() )
{
// we've bottomed out
//
// so also let solver apply impulse
mBottomedOut = true; // TODO - should also store the joint! - ...later...why?
// if we've bottomed out, we only want to transfer impulse to the chassis if
// it's more or less up
const float cos20 = 0.9397f;
//if( rmt::Fabs((inCollision.mNormal).DotProduct(vehicle->mVehicleUp)) > cos20 )
if(normalPointingAtCar.DotProduct(vehicle->mVehicleUp) > cos20)
{
/*
if(carisA)
{
inCollision.mIndexA = 0;
}
else
{
inCollision.mIndexB = 0;
}
return CollisionSolverAgent::PreCollisionEvent(inCollision, inPass);
april 11, 2003
this makes an absolute world of difference in jumps!!!!
*/
return Solving_Aborted;
}
else
{
return Solving_Aborted;
}
}
return Solving_Aborted;
}
} // end of the IsJointAWheel block...
// if we got here we are the chassis hitting a static or our own groudn plane
if(carisA)
{
if(simStateB->mAIRefIndex == PhysicsAIRef::redBrickPhizVehicleGroundPlane)
{
rmt::Vector up = GetWorldPhysicsManager()->mWorldUp;
float tip = vehicle->mVehicleUp.DotProduct(up);
//float cos10 = 0.9848f;
float cos16 = 0.9613f;
if(vehicle->mAirBorn && tip > cos16)
{
//int stophere = 1;
return Solving_Aborted;
}
//vehicle->mChassisHitGroundPlaneThisFrame = true;
}
}
else
{
if(simStateA->mAIRefIndex == PhysicsAIRef::redBrickPhizVehicleGroundPlane)
{
rmt::Vector up = GetWorldPhysicsManager()->mWorldUp;
float tip = vehicle->mVehicleUp.DotProduct(up);
//float cos10 = 0.9848f;
float cos16 = 0.9613f;
if(vehicle->mAirBorn && tip > cos16)
{
//int stophere = 1;
return Solving_Aborted;
}
//vehicle->mChassisHitGroundPlaneThisFrame = true;
}
}
if(inCollision.mDistance < -0.5f)
//if(inCollision.mDistance < -0.25f)
//if(inCollision.mDistance < -0.1f)
{
//if(vehicle->mVehicleID == VehicleEnum::FAMIL_V)
//{
// int stophere = 1; // motherfucking goddamn data conditions on breakpoints not working!!
//}
// greg
// jan 15, 2003
// did you know, that to penetrate something 0.5m in 32ms, you only have to be going 56 kmh ?
// live and learn
//return Solving_Aborted;
//inCollision.mDistance = -0.1f; // fuck
}
// this is just chassis hitting something here...
// test - if all wheels are out of collision, transffer impulse to root...?
}
return Solving_Continue;
}
Solving_Answer RedBrickCollisionSolverAgent::EndObjectCollision(SimState* inSimState, int inIndex)
{
if(inSimState->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
Vehicle* vehicle = (Vehicle*)(inSimState->mAIRefPointer);
if(vehicle->IsAFlappingJoint(inIndex))
{
//vehicle->mSimStateArticulated->GetSimulatedObject()->ResetCache();
}
}
return CollisionSolverAgent::EndObjectCollision(inSimState, inIndex);
}
Solving_Answer RedBrickCollisionSolverAgent::TestCache(SimState* inSimState, int inIndex)
{
// this is called everytime an impulse is added on an object. Getting the cache give information
/*
if(inSimState->mAIRefIndex == PhysicsAIRef::redBrickVehicle)
{
// car on car
//static float magic = 1.0f;
// fun test
//impulse.Scale(magic);
//int stophere = 1;
if( ((Vehicle*)(inSimState->mAIRefPointer))->mVehicleType == VT_TRAFFIC )
{
static float magic = 5.0f;
// fun test
impulse.Scale(magic);
SimulatedObject* simobj = inSimState->GetSimulatedObject(-1);
rmt::Vector cachev, cachew;
simobj->GetCollisionCache(cachev, cachew, -1); //retrieve the collision cache of the physical object.
if (cachev.MagnitudeSqr() > maxDv2)
{
bool fuck = true;
}
}
}
*/
#if 0
SimulatedObject* simobj = inSimState->GetSimulatedObject(-1);
if ( simobj && (simobj->Type() == RigidObjectType || simobj->Type() == ArticulatedObjectType) )
{
/*
static float thresholdfactor1 = 100.0f;
Vector currentv, vcmv, cachev, cachew;
currentv = inSimState->GetLinearVelocity(); //current speed of the object
if (inSimState->GetVirtualCM()==NULL)
vcmv.Clear();
else
vcmv = inSimState->GetVirtualCM()->GetVelocity(); //The current speed of the vcm of the object
simobj->GetCollisionCache(cachev, cachew, -1); //retrieve the collision cache of the physical object.
cachev.Add(vcmv); //The combined vcm's speed and the cached speed.
float testSpeed = Max(currentv.DotProduct(currentv),Sqr(simobj->GetMinimumLinSpeed()));
if ( cachev.DotProduct(cachev) > thresholdfactor1*testSpeed )
{
//inSimState->SetControl(simSimulationCtrl);
return Solving_Aborted;
}
*/
Vector cachev, cachew;
simobj->GetCollisionCache(cachev, cachew, -1); //retrieve the collision cache of the physical object.
static float maxDv2 = 27.0f*27.0f;
if (cachev.MagnitudeSqr() > maxDv2)
{
bool fuck = true;
}
}
#endif
/*
if (simobj && simobj->Type() == ArticulatedObjectType)
{
//Looks if there is a vcm installed on this joint:
SimStateArticulated *simStateArt = (SimStateArticulated*)inSimState;
JointVCMpArray *vcma = &simStateArt->mVirtualCMList;
for (int i=0 ; i<vcma->GetSize() ; i++)
{
JointVirtualCM *vcm = vcma->GetAt(i);
if (vcm->GetIndex() == inIndex)
{
static float thresholdfactor2=100.0f;
Vector currentv, vcmv, cachev, cachew;
simStateArt->GetVelocity(vcm->GetPosition(), currentv, inIndex);
vcmv = vcm->GetVelocity();
simobj->GetCollisionCache(cachev, cachew, inIndex);
if ( cachev.DotProduct(cachev) > thresholdfactor2*currentv.DotProduct(currentv) )
{
simStateArt->SetControl(simSimulationCtrl);
return Solving_Aborted;
}
}
}
}
*/
return Solving_Continue;
}