1313// limitations under the License.
1414
1515#include " experimental/filament/filament/math_util.h"
16+ #include < limits>
1617
18+ #include < math/mat3.h>
1719#include < math/mat4.h>
20+ #include < math/quat.h>
1821#include < math/vec3.h>
1922#include < math/vec4.h>
2023#include < math/TVecHelpers.h>
@@ -23,7 +26,9 @@ namespace mujoco {
2326
2427using filament::math::float3;
2528using filament::math::float4;
29+ using filament::math::mat3f;
2630using filament::math::mat4;
31+ using filament::math::quatf;
2732
2833mat4 ToReflectionMatrix (const mat4& xform) {
2934 const float3 normal = xform[2 ].xyz ;
@@ -81,4 +86,38 @@ mat4 CalculateObliqueProjection(const mat4& projection, const float4& plane) {
8186 return res;
8287}
8388
89+
90+ float4 CalculateOrientation (const float3& normal) {
91+ float3 tangent;
92+ float3 bitangent;
93+ if (normal.y < -1 .0f + std::numeric_limits<float >::epsilon ()) {
94+ // Handle the singularity.
95+ tangent = float3{-1 .0f , 0 .0f , 0 .0f };
96+ bitangent = float3{0 .0f , 0 .0f , -1 .0f };
97+ } else {
98+ const float a = 1 .0f / (1 .0f + normal.y );
99+ const float b = -normal.z * normal.x * a;
100+ tangent = float3 (b, -normal.z , 1 .0f - normal.z * normal.z * a);
101+ bitangent = float3 (1 .0f - normal.x * normal.x * a, -normal.x , b);
102+ }
103+ quatf orientation = mat3f::packTangentFrame ({tangent, bitangent, normal});
104+ return float4 (orientation.xyz , orientation.w );
105+ }
106+
107+ float3 CalculateNormal (
108+ const filament::math::float3& p1,
109+ const filament::math::float3& p2,
110+ const filament::math::float3& p3) {
111+ const float3 v12 = p2 - p1;
112+ const float3 v13 = p3 - p1;
113+ return normalize (cross (v12, v13));
114+ }
115+
116+ float4 CalculateOrientation (
117+ const filament::math::float3& p1,
118+ const filament::math::float3& p2,
119+ const filament::math::float3& p3) {
120+ return CalculateOrientation (CalculateNormal (p1, p2, p3));
121+ }
122+
84123} // namespace mujoco
0 commit comments