It’ll only update the result object if there’s more than one hit, so if you re-use your result objects as recommended in the doc and they’ve had a hit already, hasHit will always be true even if there’s no hit.
havokPlugin.js
raycast(from, to, result) {
const queryMembership = ~0;
const queryCollideWith = ~0;
const query = [this._bVecToV3(from), this._bVecToV3(to), [queryMembership, queryCollideWith]];
this._hknp.HP_World_CastRayWithCollector(this.world, this._queryCollector, query);
if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {
const hitData = this._hknp.HP_QueryCollector_GetCastRayResult(this._queryCollector, 0)[1];
const hitPos = hitData[1][3];
const hitNormal = hitData[1][4];
result.setHitData({ x: hitNormal[0], y: hitNormal[1], z: hitNormal[2] }, { x: hitPos[0], y: hitPos[1], z: hitPos[2] });
result.calculateHitDistance();
const hitBody = this._bodies.get(hitData[1][0][0]);
result.body = hitBody === null || hitBody === void 0 ? void 0 : hitBody.body;
result.bodyIndex = hitBody === null || hitBody === void 0 ? void 0 : hitBody.index;
}
}
Indeed! Good catch!. I’m doing a fix.
2 Likes
@Cedric
Additionally, you need to set result._rayFromWorld to the ‘from’ vector, otherwise the distance calculation will be done between (0,0,0) and hitPointWorld.
By setting _rayFromWorld and _rayToWorld before doing the raycast, you’ll still be able to calculate the distance in case of not hitting anything, which might be useful.
4 Likes
I will provide a fix later today.
What I meant was, that as far as I can tell, the _rayFromWorld vector3 of the PhysicsRaycastResult is not set to that of the from vector3 in case of a hit. This results in the distance calculation being incorrect in any case other than a ray being fired from either (0,0,0) - or the last position used when a miss occurred.
A quick fix would be to reset the result in any case, no matter of a hit or not
public raycast(from: Vector3, to: Vector3, result: PhysicsRaycastResult): void {
const queryMembership = ~0;
const queryCollideWith = ~0;
*******result.reset(from, to);********
const query = [this._bVecToV3(from), this._bVecToV3(to), [queryMembership, queryCollideWith]];
this._hknp.HP_World_CastRayWithCollector(this.world, this._queryCollector, query);
if (this._hknp.HP_QueryCollector_GetNumHits(this._queryCollector)[1] > 0) {
const hitData = this._hknp.HP_QueryCollector_GetCastRayResult(this._queryCollector, 0)[1];
const hitPos = hitData[1][3];
const hitNormal = hitData[1][4];
result.setHitData({ x: hitNormal[0], y: hitNormal[1], z: hitNormal[2] }, { x: hitPos[0], y: hitPos[1], z: hitPos[2] });
result.calculateHitDistance();
const hitBody = this._bodies.get(hitData[1][0][0]);
result.body = hitBody?.body;
result.bodyIndex = hitBody?.index;
}
}