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.
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.