-
Notifications
You must be signed in to change notification settings - Fork 3
Open
Description
For my test case, I made a 3x1x3 floor with mass 0 centered on (0, 0, 0), and a 1x1x1 cube with mass 1 at (0, 2, 0).
I created a PhysicsWorld and added both with addRigidBody, but if I keep calling world.stepSimulation(), I can see the cube phase through the floor.
// MotionState implementation:
class GameMotionState(private val go: GameObject) : MotionState {
override fun getWorldTransform(worldTransform: Transform) {
worldTransform.basis put Mat3(go.transform.rotation.bullet()) // transforms between my vec/quat/mat and bullet types
worldTransform.origin put go.transform.translation.bullet()
}
override fun setWorldTransform(worldTransform: Transform) {
go.transform.translation = Vector3(worldTransform.origin)
go.transform.rotation = Quaternion(worldTransform.basis)
}
}
// RigidBody creation:
internal fun makeRigidBody(): RigidBody {
val btShape = shape.getShape(gameObject.transform.scale) // creates a CollisionShape stretched with the scale from transform
var inertia = Vec3(0f)
if (mass == 0f) {
// apply inertia if needed
inertia = Vec3().also { btShape.calculateLocalInertia(mass, it) }
}
val body = RigidBody(RigidBody.RigidBodyConstructionInfo(
mass,
GameMotionState(gameObject),
btShape,
inertia
))
return body
}
// World creation and object handling:
class PhysicsSystem {
val world: DiscreteDynamicsWorld
init {
val config = DefaultCollisionConfiguration()
val dispatcher = CollisionDispatcher(config)
val pairCache = DbvtBroadphase()
val solver = SequentialImpulseConstraintSolver()
world = DiscreteDynamicsWorld(dispatcher, pairCache, solver, config)
world.gravity = Vec3(0f, -1f, 0f) // Slow enough to get clear video; see link at the bottom
}
fun update(delta: Float) {
world.stepSimulation(delta, 10)
}
private val map = mutableMapOf<PhysicsObject, RigidBody>()
fun addObject(physicsObject: PhysicsObject) {
val body = map.getOrPut(physicsObject) { physicsObject.makeRigidBody() }
world.addRigidBody(body)
}
}
val floor = addObject("floor") {
transform.scale = Vector3(3f, 1f, 3f) // make floor big
addComponent<PhysicsObject> {
mass = 0f // no mass, it's static
physics.addObject(this)
}
}
val cube = addObject("cube") {
transform.rotation = Quaternion.IDENTITY.rotate(Vector3(PI / 4)) // apply some rotation; seems to be lost after physics tick?
transform.translation = Vector3(0f, 2f, 0f) // place 2 units above floor
addComponent<PhysicsObject> {
mass = 1f
physics.addObject(this)
}
}
Clip: https://github.com/user-attachments/assets/62a68cbd-c69e-446e-97ba-3bc95b067638
Metadata
Metadata
Assignees
Labels
No labels