Skip to content

Collisions do not work #2

@Martmists-GH

Description

@Martmists-GH

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions