Custom Gravity Direction (per Body) #166
-
I was looking into how to customize gravity for individual bodies to do things either like gravity-wells, Mario Galaxy walkable tiny planets, or having a go-cart racers drive up a vertical section of special wall. My current logic is to set the mGravityFactor to zero and then to apply a per-frame force equal to (customGravity * mass) to the body. Is this the best approach with Jolt's logic? I do not know if there are any side-effects, where gravity may be used in other calculations and this 'force' being applied every step does not replicate the same behavior, although if it works fine enough for driving a car, that is enough for me. CharacterVirtual pretty much already uses faked gravity for lots of things, so I am not too concerned about that besides interacting with physics bodies on those planets. I do see that likely I will need to allow infinite 'PitchRoll' on a vehicle and fix it myself per-frame, due to VehicleConstraint's I was able to run the 'vehicle_wheeled' demo under that logic (with 180 pitch allowed or the car auto-flips itself) and physicsSystem gravity set to positive Z (upside down) and with positive X (gravity horizontal) and still drive around as long as I didn't flip the car via my own steering. I'd put random spheres and cubes on the track to ensure the real world gravity was still set to awkward directions. Ex: the following maintains a sync'd import initJolt from './js/jolt-physics.wasm-compat.js';
initJolt().then(function (Jolt) {
let cb = []; // callback list
initExample(Jolt, () => cb.forEach(f => f()));
// Create a basic floor
let floor = createFloor();
floor.SetFriction(1.0);
// control body, uses internal physics system gravity
const position = new Jolt.RVec3(-1, 15, 0)
const body = createSphere(position, .5, Jolt.EMotionType_Dynamic, LAYER_MOVING, 0xFF0000)
// test body, uses force-based simulation of custom gravity
position.SetX(1);
const shape = new Jolt.SphereShape(.5, null);
const creationSettings = new Jolt.BodyCreationSettings(shape, position, Jolt.Quat.prototype.sIdentity(), Jolt.EMotionType_Dynamic, LAYER_MOVING);
creationSettings.mGravityFactor = 0;
creationSettings.mOverrideMassProperties = Jolt.EOverrideMassProperties_CalculateInertia;
creationSettings.mMassPropertiesOverride.mMass = 100;
const body2 = bodyInterface.CreateBody(creationSettings);
addToScene(body2, 0xff0000);
let gravity = physicsSystem.GetGravity().Mul(100); // acceleration times mass
let logCount = 0;
let i = 0;
cb.push(() => {
if(i++ % 2 == 0 && logCount < 20) {
logCount++;
const pointA = body.GetPosition().ToString();
const pointA_y = body.GetPosition().GetY();
const pointB = body2.GetPosition().ToString();
const pointB_y = body2.GetPosition().GetY();
console.log(pointA, pointB, Math.abs(pointA_y-pointB_y));
if(logCount == 10) {
let customGravity = new Jolt.RVec3(-0.5, -2, 0).Normalized().Mul(9.81);
physicsSystem.SetGravity(customGravity);
gravity = physicsSystem.GetGravity().Mul(100);
}
}
body2.AddForce(gravity);
});
}); |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 6 replies
-
Yes it is (it's also what we're doing), the accumulated force is applied at the same time as gravity so they're mathematically equivalent:
Correct, the update function takes the gravity vector as input, which was done on purpose to allow custom gravity for the character (see CharacterSpaceShipTest C++ demo).
The vehicle world up is indeed only used for 2 things:
It would be very simple to add an API to allow setting a custom world up/gravity vector for the vehicle (that you'd need to call every frame if the gravity varies). With that you'd be able to set a pitch/roll limit again. Let me know if you want this. |
Beta Was this translation helpful? Give feedback.
-
Note to anyone who may attempt this artificial gravity logic: Add If you think you may be encountering the same issue, as a debug-logic prior to touching an object, you can check:
I'd wondered why things were seeming to explode after a while on my little planet, though I do need to fix some character "jump" issues when the character's south of the equator: |
Beta Was this translation helpful? Give feedback.
Yes it is (it's also what we're doing), the accumulated force is applied at the same time as gravity so they're mathematically equivalent:
https://github.com/jrouwe/JoltPhysics/blob/7edba88d5336047ebae8c6e26a5aa89dd5ae069e/Jolt/Physics/Body/MotionProperties.inl#L127
Correct, the update function takes the gravity vector as input, which was done on purpose to allow custom gravity for the character (see CharacterSpaceShipTest C++ demo).