I'm doing a mariokart-like racing game.
First problem is that when I use a RaycastVehicle for the karts and drive them around (or even just let them sit there, not moving), they "vibrate" a lot.
here's the values I'm using for the wheels:
Code: Select all
Radius = 0.5
Width = 0.2
SuspensionRestLength = 0.2
SpringStiffness = 500
SpringCompression = 4.2
SpringDamping = 100
FrictionSlip = 100
RollInfluence = 1
Code: Select all
Raycaster = new DefaultVehicleRaycaster(LKernel.Get<PhysicsMain>().World);
Tuning = new RaycastVehicle.VehicleTuning();
Tuning.MaxSuspensionTravelCm = 40f;
Vehicle = new RaycastVehicle(Tuning, Body, Raycaster);
Vehicle.SetCoordinateSystem(0, 1, 2); // I have no idea what this does... I'm assuming something to do with a matrix?
LKernel.Get<PhysicsMain>().World.AddAction(Vehicle);
// then add wheels...
Code: Select all
public void CreateWheel(Vector3 connectionPoint, bool isFrontWheel) {
Kart.Vehicle.AddWheel(connectionPoint, WheelDirection, WheelAxle, SuspensionRestLength, Radius, Kart.Tuning, isFrontWheel);
WheelInfo info = Kart.Vehicle.GetWheelInfo((int) WheelID);
info.SuspensionStiffness = SpringStiffness;
info.WheelDampingRelaxation = SpringDamping;
info.WheelDampingCompression = SpringCompression;
info.FrictionSlip = FrictionSlip;
info.RollInfluence = RollInfluence;
}
Code: Select all
public override Matrix4 WorldTransform {
get {
return transform;
}
set {
if (node == null)
base.Dispose();
node.Orientation = value.ExtractQuaternion();
node.Position = value.GetTrans();
}
}
Wheels are at 1.7f, 0.4f, 1.33f (making X and Z negative as needed)
Sooooo... I don't know what I'm doing wrong there. But it's probably something dumb!
-------------------------------------------------------------------------------------------------------
Second question: I want to have some sort of "trigger region" things (like what physx has if you've ever used that). They're basically objects that send off events when something collides with them, but you can drive through them as if they weren't there. So you could use them to find when a car passes through a checkpoint, for example.
From what I understand I have to use ghostobjects for this, but I'm not sure I'm using them right either.
here's my code that sets up the ghostobject:
Code: Select all
// physics
Matrix4 transform = new Matrix4(rotation.DegreeVectorToGlobalQuaternion());
transform.SetTrans(position);
// make our ghost object
Ghost = new GhostObject();
Ghost.CollisionFlags = CollisionFlags.NoContactResponse | CollisionFlags.StaticObject;
Ghost.CollisionShape = shape; // usually something like "new BoxShape(1, 1, 1)" or similar
Ghost.WorldTransform = transform;
LKernel.Get<PhysicsMain>().World.AddCollisionObject(Ghost);
Code: Select all
void PostSimulate(DiscreteDynamicsWorld world, FrameEvent evt) {
foreach (TriggerRegion region in Regions.Values) {
// get our set of bodies that were inside the region from the previous frame
Collection<RigidBody> previousBodies = region.CurrentlyCollidingWith;
Collection<RigidBody> newBodies = new Collection<RigidBody>();
// get all of the objects that are inside the region and add them to the new collection
for (int a = 0; a < region.Ghost.NumOverlappingObjects; a++) {
RigidBody body = region.Ghost.GetOverlappingObject(a) as RigidBody;
// check to make sure this is actually a RigidBody - if it isn't, ignore it
if (body != null) {
newBodies.Add(body);
}
}
// get the bodies that have been removed and added (yay linq)
IEnumerable<RigidBody> added = newBodies.Except(previousBodies);
IEnumerable<RigidBody> removed = previousBodies.Except(newBodies);
// update the region's list of bodies that are inside it
region.CurrentlyCollidingWith = newBodies;
// then run our triggers
foreach (RigidBody addedBody in added)
region.InvokeTrigger(addedBody, TriggerReportFlags.Enter);
foreach (RigidBody removedBody in removed)
region.InvokeTrigger(removedBody, TriggerReportFlags.Leave);
}
}
I can upload a little demo if it's needed.