Comments and answers for "Calculate Bounds Intersection Face Normal"
http://answers.unity.com/questions/1749459/calculate-bounds-intersection-face-normal.html
The latest comments and answers for the question "Calculate Bounds Intersection Face Normal"Comment by darksider2000 on darksider2000's comment
http://answers.unity.com/comments/1749509/view.html
Can you cast more than one ray? You could use 3 rays to create a triangle on the surface of the face you're aiming for.
The triangle's normal will have the same direction as the face's. The triangle would ideally need to be as little as possible.
This will circumvent all the sorting and ruling out data.Wed, 08 Jul 2020 22:47:03 GMTdarksider2000Comment by Aeleck on Aeleck's comment
http://answers.unity.com/comments/1749492/view.html
Thank you, that was my first implementation. While I was waiting for replies I stumbled upon another solution that seems to be faster. It checks the t values as it passes the axis planes, ruling out each plane as a normal as it goes. It looks like this:
Vector4 IntersectBounds(Ray ray, Bounds bounds) {
// points on infinite axis that ray intersects, defined by bounds
// we need to keep considering the max to make sure the min is correct
float txmin, txmax, tymin, tymax, tzmin, tzmax;
Vector3 minNormal = Vector3.right * -Mathf.Sign(ray.direction.x),
maxNormal = Vector3.right * -Mathf.Sign(ray.direction.x);
// solve divie by 0 issues
Vector3 invDir = new Vector3(1f / ray.direction.x, 1f / ray.direction.y, 1f / ray.direction.z);
if (invDir.x >= 0) {
txmin = (bounds.min.x - ray.origin.x) * invDir.x;
txmax = (bounds.max.x - ray.origin.x) * invDir.x;
} else {
txmin = (bounds.max.x - ray.origin.x) * invDir.x;
txmax = (bounds.min.x - ray.origin.x) * invDir.x;
}
if (invDir.y >= 0) {
tymin = (bounds.min.y - ray.origin.y) * invDir.y;
tymax = (bounds.max.y - ray.origin.y) * invDir.y;
} else {
tymin = (bounds.max.y - ray.origin.y) * invDir.y;
tymax = (bounds.min.y - ray.origin.y) * invDir.y;
}
if ((txmin > tymax) || (tymin > txmax)) return Vector4.zero;
// moves bounds in to leave only a 2d plane to check (x-z plane)
// if we went past the x start for y, then normal can't be on x-axis
if (tymin > txmin) {
txmin = tymin;
minNormal = Vector3.up * -Mathf.Sign(ray.direction.y);
}
if (tymax < txmax) {
txmax = tymax;
maxNormal = Vector3.up * -Mathf.Sign(ray.direction.y);
}
if (invDir.z >= 0) {
tzmin = (bounds.min.z - ray.origin.z) * invDir.z;
tzmax = (bounds.max.z - ray.origin.z) * invDir.z;
} else {
tzmin = (bounds.max.z - ray.origin.z) * invDir.z;
tzmax = (bounds.min.z - ray.origin.z) * invDir.z;
}
if ((txmin > tzmax) || (tzmin > txmax)) return Vector4.zero;
// same as y, if went passed y/x axis to get to z axis, can't be on y either, must be z
if (tzmin > txmin) {
txmin = tzmin;
minNormal = Vector3.forward * -Mathf.Sign(ray.direction.z);
}
if (tzmax < txmax) {
txmax = tzmax;
maxNormal = Vector3.forward * -Mathf.Sign(ray.direction.z);
}
if (txmin <= 0f) {
if (txmax <= 0f) return Vector4.zero;
return new Vector4(maxNormal.x, maxNormal.y, maxNormal.z, txmax);
}
return new Vector4(minNormal.x, minNormal.y, minNormal.z, txmin);
}
If you have any ideas on improving this or a different technique, I'd be interested in what you have, thank you!Wed, 08 Jul 2020 21:44:31 GMTAeleckComment by darksider2000 on darksider2000's comment
http://answers.unity.com/comments/1749486/view.html
Okay I see what you mean.
I've not tried something like this myself, but I might be able to help with the math.
----------
You could use the mesh's normal array to sort out which normal it is you need.
If your contact point is **on** a face then a vector between the **contact point** and the face's **normal vector's origin** will always be perpendicular to the normal vector **of that face**, and not to any other. (This gets a little tricky around the edges and when the contact point is close to the normal's origin, but should be okay with floats)
So you could just go through the normals array in the mesh, draw vectors and check angles. You can also compare angles and get the one closest to perpendicular to eliminate unlikely results. (If your contact point isn't precisely on the face, or if the geometry is complex enough you could get more than one likely result).Wed, 08 Jul 2020 21:18:37 GMTdarksider2000Comment by Aeleck on Aeleck's comment
http://answers.unity.com/comments/1749473/view.html
Unfortunately, I am not using Unity raycasting. I have the bounds and a ray on the GPU ins$$anonymous$$d of on the Unity processing threads. I am trying to figure this out using only the bounds min and max points and the ray origin and direction since I don't have access to the physic space of the scene, and these are just bounds of meshes ins$$anonymous$$d of their actual physics shapes.
I should note that the example is so that it can be visualized but will actually be running in a compute shader on the GPU.Wed, 08 Jul 2020 20:41:13 GMTAeleckComment by darksider2000
http://answers.unity.com/comments/1749472/view.html
Silly question, but have you tried [RaycastHit.normal][1]? Does it give you the wrong normal?
[1]: https://docs.unity3d.com/ScriptReference/RaycastHit-normal.htmlWed, 08 Jul 2020 20:36:14 GMTdarksider2000