Check if PhysicsBody is asleep

I was looking for a quick way to skip stationary bodies, and my first thought was the (nonexistent) isAsleep property. Is there a property in havok itself that we could read/expose via the plugin? I’m currently checking if the linear velocity and rotation vector lengths are near zero; it works, but it would be nice if there were a quicker way.

1 Like

HP_Body_GetActivationState but last I checked, angular and linear velocity is more reliable. For fast code, you can check that each xyz component is within some epsilon of 0.

Sometimes, a PhysicsBody seems to “jiggle” and takes a while to settle (or never does). Also, activationControl can be set to ALWAYS_ACTIVE, which will confuse a check for “all inactive.”

this.#havokPlugin._bodies.entries().forEach(e => {
    const bid = e[0]; // Havok Engine BodyId
    const b = e[1].body; // PhysicsBody
    const bidTuple = [e[0]]; // useful as argument in Engine methods

    if (b._motionType == 2) {
        const astate =
            this.#havokPlugin._hknp.HP_Body_GetActivationState(bidTuple)[1].value;
        // 0 is ACTIVE, 1 is INACTIVE
        // ...do something here
    }
}

Or modify .forEach to .map and return astate if _motionType is 2 ( PhysicsMotionType.DYNAMIC) otherwise return 1 (INACTIVE), but might want to exclude each body with ActivationControl set to ALWAYS_ACTIVE.

Good point about ALWAYS_ACTIVE. I don’t use that flag, but I’ve added a note about it.

I ended up with something like this:

const [_, activationState] = this.#hkPlugin.HP_Body_GetActivationState(body._pluginData.hpBodyId)
const isAsleep = (activationState !== this.#hkPlugin.ActivationState.ACTIVE)

const isAtRest = isAsleep
    || (body.getLinearVelocity().lengthSquared() < MIN_SPEED_SQ
        && body.getAngularVelocity().lengthSquared() < MIN_ROT_SPEED_SQ))
if (isAtRest) {
    ...
}
else {
    ...
}

When the body settles, isAsleep becomes true and we skip the expensive vector length computations.