is true there is no logic to divide by num, but in the code division present.
There is check if num =~ 1.0 and then there are division by num.
Logic must be opposite, we need division only if num is NOT 1. And I assume that it is about division by W to make it real 3d point (so now there are actually no division by W in all cases except when W == 1).
This is the first part.
The second part is about - with this wrong logic still 3d point reconstruction works as expected, I provided example. That is why I am not sure what to do here. It can mean that all the code is expecting incorrect behavior and fix can reproduce the problems, so complex fix is probably needed but I am not sure I can knew all details to make it.
The third part is about what that functions work with. Vector3.unproject takes as input linear screen X,Y in range [0, screenSize] in pixels but Z in non-linear format in range [0-1]. Then I do not see how z is transformed in lenear real z coordinate, so I am confused how it works.
I vote to remove the if (WithinEpsilon(num, 1.0)), as it’s probably slower to do the check than to do the division in all cases (function call + Math.abs(a - b) <= epsilon).
I thought this code was homogeneous division, but that is already done in the Vector3.TransformCoordinatesToRef(source, matrix, result); call:
public static _UnprojectFromInvertedMatrixToRef<T extends Vector3>(source: DeepImmutable<Vector3>, matrix: DeepImmutable<Matrix>, result: T): T {
Vector3.TransformCoordinatesToRef(source, matrix, result);
const m = matrix.m;
const num = source._x * m[3] + source._y * m[7] + source._z * m[11] + m[15];
if (WithinEpsilon(num, 1.0)) {
result.scaleInPlace(1.0 / num);
}
return result;
}
So, I don’t understand the purpose of this code?
In any case, it doesn’t do anything, because with the default epsilon value (1.401298e-45), we execute the scaleInPlace call only if num >= 1 - 1.401298e-45 and num <= 1 + 1.401298e-45:
I have to admit without a define epsilon, this is useless…And as @Evgeni_Popov said, the divide by w is already done by the TransformCoordinatesToRef