implement luanti and irrlicht transformations
This commit is contained in:
parent
5eba698c90
commit
2c7a244aa2
@ -130,7 +130,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -662,7 +662,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -662,7 +662,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -730,7 +730,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -118,7 +118,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -89,6 +89,10 @@
|
||||
<td class="summary">Create a matrix from a quaternion.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#set_rot_from_quaternion">set_rot_from_quaternion (q)</a></td>
|
||||
<td class="summary">set the rotation of a matrix from a quaternion.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#from_direction">from_direction (direction, up)</a></td>
|
||||
<td class="summary">Create a matrix from a direction/up pair.</td>
|
||||
</tr>
|
||||
@ -97,6 +101,38 @@
|
||||
<td class="summary">Create a matrix from a transform.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#set_rot_zxy">set_rot_zxy (pitch, yaw, roll)</a></td>
|
||||
<td class="summary">set the rotation of a given matrix in euler in the ZXY application order.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#set_rot_luanti_entity">set_rot_luanti_entity (pitch, yaw, roll)</a></td>
|
||||
<td class="summary">alias of <code>set_rot_zxy</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_zxy">get_rot_zxy (the)</a></td>
|
||||
<td class="summary">get the ZXY euler rotation of the given matrix.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_luanti_entity">get_rot_luanti_entity (the)</a></td>
|
||||
<td class="summary">Alias of <code>get_rot_zxy</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#set_rot_xyz">set_rot_xyz (pitch, yaw, roll)</a></td>
|
||||
<td class="summary">set the rotation of a given matrix in euler in the XYZ application order.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#set_rot_irrlicht_bone">set_rot_irrlicht_bone (pitch, yaw, roll)</a></td>
|
||||
<td class="summary">alias of <code>set_rot_xyz</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_xyz">get_rot_xyz (the)</a></td>
|
||||
<td class="summary">Get the XYZ euler rotation of the given matrix.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_irrlicht_bone">get_rot_irrlicht_bone (the)</a></td>
|
||||
<td class="summary">Alias of <code>get_rot_zxy</code>.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#from_ortho">from_ortho (left, right, top, bottom, near, far)</a></td>
|
||||
<td class="summary">Create matrix from orthogonal.</td>
|
||||
</tr>
|
||||
@ -307,6 +343,29 @@
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "set_rot_from_quaternion"></a>
|
||||
<strong>set_rot_from_quaternion (q)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
set the rotation of a matrix from a quaternion. Not sure at all where i got this code from, but it works...
|
||||
i refactored so it works with https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.html
|
||||
I think I got it from https://github.com/minetest/irrlicht/blob/7173c2c62997b6416f17b90f9a50bff11fef1c4c/include/quaternion.h#L367
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">q</span>
|
||||
<span class="types"><span class="type">quat</span></span>
|
||||
rotation quaternion. only supports normal quaternion rotation (will normalize)
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "from_direction"></a>
|
||||
@ -373,6 +432,286 @@
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "set_rot_zxy"></a>
|
||||
<strong>set_rot_zxy (pitch, yaw, roll)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
set the rotation of a given matrix in euler in the ZXY application order. This is the order that minetest entities are rotated in.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">pitch</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise pitch in radians
|
||||
</li>
|
||||
<li><span class="parameter">yaw</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in radians
|
||||
</li>
|
||||
<li><span class="parameter">roll</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in roll
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "set_rot_luanti_entity"></a>
|
||||
<strong>set_rot_luanti_entity (pitch, yaw, roll)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>set_rot_zxy</code>. Sets the rotation of a given matrix in euler in the ZXY application order. This is the order that minetest entities are rotated in.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">pitch</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise pitch in radians
|
||||
</li>
|
||||
<li><span class="parameter">yaw</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in radians
|
||||
</li>
|
||||
<li><span class="parameter">roll</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in roll
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_zxy"></a>
|
||||
<strong>get_rot_zxy (the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
get the ZXY euler rotation of the given matrix. This is the order that minetest entities are rotated in.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
matrix to get the rotation of
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
pitch</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
yaw</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
roll</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_luanti_entity"></a>
|
||||
<strong>get_rot_luanti_entity (the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Alias of <code>get_rot_zxy</code>. Gets the ZXY euler rotation of the given matrix. This is the order that minetest entities are rotated in.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
matrix to get the rotation of
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
pitch</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
yaw</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
roll</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "set_rot_xyz"></a>
|
||||
<strong>set_rot_xyz (pitch, yaw, roll)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
set the rotation of a given matrix in euler in the XYZ application order. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">pitch</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise pitch in radians
|
||||
</li>
|
||||
<li><span class="parameter">yaw</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in radians
|
||||
</li>
|
||||
<li><span class="parameter">roll</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in roll
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "set_rot_irrlicht_bone"></a>
|
||||
<strong>set_rot_irrlicht_bone (pitch, yaw, roll)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>set_rot_xyz</code>. Sets the rotation of a given matrix in euler in the XYZ application order. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">pitch</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise pitch in radians
|
||||
</li>
|
||||
<li><span class="parameter">yaw</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in radians
|
||||
</li>
|
||||
<li><span class="parameter">roll</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
the clockwise yaw in roll
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_xyz"></a>
|
||||
<strong>get_rot_xyz (the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Get the XYZ euler rotation of the given matrix. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
matrix to get the rotation of
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
pitch</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
yaw</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
roll</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_irrlicht_bone"></a>
|
||||
<strong>get_rot_irrlicht_bone (the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Alias of <code>get_rot_zxy</code>. Gets the XYZ euler rotation of the given matrix. This is the rotation order irrlicht uses (i.e. for bones in Luanti).
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">matrix</span></span>
|
||||
matrix to get the rotation of
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
pitch</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
yaw</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
roll</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "from_ortho"></a>
|
||||
@ -1166,7 +1505,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -703,7 +703,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -98,11 +98,7 @@
|
||||
<td class="summary">Subtract a quaternion from another.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#mul">mul (a, b)</a></td>
|
||||
<td class="summary">Multiply two quaternions.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#mul_vec3">mul_vec3 (a, b)</a></td>
|
||||
<td class="name" nowrap><a href="#mul_vec3">mul_vec3 (a, v)</a></td>
|
||||
<td class="summary">Multiply a quaternion and a vec3.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@ -131,7 +127,7 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#rotate">rotate (angle, axis, y, z)</a></td>
|
||||
<td class="summary">Alias of from<em>angle</em>axis.</td>
|
||||
<td class="summary">Alias of <code>from_angle_axis.</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#conjugate">conjugate (a)</a></td>
|
||||
@ -186,12 +182,40 @@
|
||||
<td class="summary">Convert a quaternion into an angle/axis pair.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#to_euler_angles_unpack">to_euler_angles_unpack (a)</a></td>
|
||||
<td class="summary">Convert a quaternion into euler angle components</td>
|
||||
<td class="name" nowrap><a href="#set_matrix_rot">set_matrix_rot (quaternion, the)</a></td>
|
||||
<td class="summary">set a matrix's rotation fields from a quaternion.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#to_euler_angles">to_euler_angles (a)</a></td>
|
||||
<td class="summary">Convert a quaternion into euler angles</td>
|
||||
<td class="name" nowrap><a href="#from_matrix">from_matrix (the)</a></td>
|
||||
<td class="summary">create a new quaternion from a matrix.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_luanti_entity">get_rot_luanti_entity ()</a></td>
|
||||
<td class="summary">alias of <code>get_euler_zxy</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#from_euler_zxy">from_euler_zxy (X, Y, Z)</a></td>
|
||||
<td class="summary">create a quaternion from euler angles in the ZXY rotation order.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_luanti_entity">get_rot_luanti_entity ()</a></td>
|
||||
<td class="summary">alias of <code>from_euler_zxy</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_euler_xyz">get_euler_xyz (quaternion)</a></td>
|
||||
<td class="summary">convert a quaternion to an xyz euler angles.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_irrlicht_bone">get_rot_irrlicht_bone ()</a></td>
|
||||
<td class="summary">alias of <code>get_euler_xyz</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#from_euler_xyz">from_euler_xyz (X, Y, Z)</a></td>
|
||||
<td class="summary">create a quaternion from euler angles in the xyz rotation order.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#get_rot_irrlicht_bone">get_rot_irrlicht_bone ()</a></td>
|
||||
<td class="summary">alias of <code>quat.from_euler_zxy</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="name" nowrap><a href="#to_vec3">to_vec3 (a)</a></td>
|
||||
@ -298,7 +322,7 @@
|
||||
<strong>from_direction (normal, up)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Create a quaternion from a normal/up vector pair.
|
||||
Create a quaternion from a normal/up vector pair. (accepts minetest vectors)
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
@ -414,44 +438,13 @@
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "mul"></a>
|
||||
<strong>mul (a, b)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Multiply two quaternions.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">a</span>
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
Left hand operand
|
||||
</li>
|
||||
<li><span class="parameter">b</span>
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
Right hand operand
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
quaternion equivalent to "apply b, then a"
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "mul_vec3"></a>
|
||||
<strong>mul_vec3 (a, b)</strong>
|
||||
<strong>mul_vec3 (a, v)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Multiply a quaternion and a vec3.
|
||||
Multiply a quaternion and a vec3. Equivalent to rotating the vector (a) by the quaternion (v)
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
@ -460,7 +453,7 @@
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
Left hand operand
|
||||
</li>
|
||||
<li><span class="parameter">b</span>
|
||||
<li><span class="parameter">v</span>
|
||||
<span class="types"><span class="type">vec3</span></span>
|
||||
Right hand operand
|
||||
</li>
|
||||
@ -656,7 +649,7 @@
|
||||
<strong>rotate (angle, axis, y, z)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Alias of from<em>angle</em>axis.
|
||||
Alias of <code>from_angle_axis.</code>
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
@ -1084,36 +1077,32 @@
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "to_euler_angles_unpack"></a>
|
||||
<strong>to_euler_angles_unpack (a)</strong>
|
||||
<a name = "set_matrix_rot"></a>
|
||||
<strong>set_matrix_rot (quaternion, the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Convert a quaternion into euler angle components
|
||||
set a matrix's rotation fields from a quaternion. Uses mat4.set<em>rot</em>from_quaternion
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">a</span>
|
||||
<li><span class="parameter">quaternion</span>
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
Quaternion to convert
|
||||
to convert
|
||||
</li>
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">mat4</span></span>
|
||||
mat4 to apply to.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">roll</span></span>
|
||||
|
||||
<span class="types"><span class="type">mat4</span></span>
|
||||
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">pitch</span></span>
|
||||
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">yaw</span></span>
|
||||
no idea if this shit really works, very well could not...</li>
|
||||
</ol>
|
||||
|
||||
|
||||
@ -1121,31 +1110,210 @@
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "to_euler_angles"></a>
|
||||
<strong>to_euler_angles (a)</strong>
|
||||
<a name = "from_matrix"></a>
|
||||
<strong>from_matrix (the)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
Convert a quaternion into euler angles
|
||||
create a new quaternion from a matrix. Uses mat4.to_quaternion
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">a</span>
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
Quaternion to convert
|
||||
<li><span class="parameter">the</span>
|
||||
<span class="types"><span class="type">mat4</span></span>
|
||||
matrix to use
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><span class="type">result</span></span>
|
||||
a {roll, pitch, yaw} table
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
|
||||
|
||||
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_luanti_entity"></a>
|
||||
<strong>get_rot_luanti_entity ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>get_euler_zxy</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "from_euler_zxy"></a>
|
||||
<strong>from_euler_zxy (X, Y, Z)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
create a quaternion from euler angles in the ZXY rotation order. This is the rotation order Luanti Entities use
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">X</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
<li><span class="parameter">Y</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
<li><span class="parameter">Z</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
q
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_luanti_entity"></a>
|
||||
<strong>get_rot_luanti_entity ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>from_euler_zxy</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_euler_xyz"></a>
|
||||
<strong>get_euler_xyz (quaternion)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
convert a quaternion to an xyz euler angles. This is the rotation order used by irrlicht bones.
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">quaternion</span>
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
to convert
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
<li>
|
||||
<span class="types"><span class="type">X</span></span>
|
||||
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">Y</span></span>
|
||||
|
||||
|
||||
</li>
|
||||
<li>
|
||||
<span class="types"><span class="type">Z</span></span>
|
||||
|
||||
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_irrlicht_bone"></a>
|
||||
<strong>get_rot_irrlicht_bone ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>get_euler_xyz</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "from_euler_xyz"></a>
|
||||
<strong>from_euler_xyz (X, Y, Z)</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
create a quaternion from euler angles in the xyz rotation order. This is the rotation order irrlicht bones use
|
||||
|
||||
|
||||
<h3>Parameters:</h3>
|
||||
<ul>
|
||||
<li><span class="parameter">X</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
<li><span class="parameter">Y</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
<li><span class="parameter">Z</span>
|
||||
<span class="types"><span class="type">float</span></span>
|
||||
|
||||
|
||||
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3>Returns:</h3>
|
||||
<ol>
|
||||
|
||||
<span class="types"><a class="type" href="../modules/quat.html#quat">quat</a></span>
|
||||
q
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "get_rot_irrlicht_bone"></a>
|
||||
<strong>get_rot_irrlicht_bone ()</strong>
|
||||
</dt>
|
||||
<dd>
|
||||
alias of <code>quat.from_euler_zxy</code>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
<dt>
|
||||
<a name = "to_vec3"></a>
|
||||
@ -1235,7 +1403,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -77,7 +77,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -550,7 +550,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -1117,7 +1117,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -1025,7 +1025,7 @@
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
@ -61,7 +61,7 @@
|
||||
|
||||
|
||||
<h1>Cirno's Perfect Math Library</h1>
|
||||
<h3>Adapated for Minetest</h3>
|
||||
<h3>Adapted for Minetest</h3>
|
||||
<p>For best memory performance: have luaJIT & it's FFI library (this should be built into luaJIT), and add MTUL-CPML to your trusted list (so it can <code>require()</code> call the FFI library).</p>
|
||||
|
||||
<p>Various useful bits of game math. 3D line intersections, ray casting, 2d/3d vectors, 4x4 matrices, quaternions, etc.</p>
|
||||
@ -80,7 +80,7 @@ Documentation can be found here: <a href="https://minetest-unification-library.g
|
||||
</div> <!-- id="main" -->
|
||||
<div id="about">
|
||||
<i>generated by <a href="http://github.com/lunarmodules/ldoc">LDoc 1.5.0</a></i>
|
||||
<i style="float:right;">Last updated 2024-01-06 19:06:14 </i>
|
||||
<i style="float:right;">Last updated 2024-11-30 20:09:10 </i>
|
||||
</div> <!-- id="about" -->
|
||||
</div> <!-- id="container" -->
|
||||
</body>
|
||||
|
111
init.lua
111
init.lua
@ -56,75 +56,82 @@ local files = {
|
||||
"bound3",
|
||||
}
|
||||
|
||||
--you will now witness the lua equivelant of a schizo rant. Have fun with this bullshit.
|
||||
|
||||
--initialize some variables
|
||||
mtul = mtul or {
|
||||
loaded_modules = {}
|
||||
}
|
||||
mtul.math = mtul.math or {} --other modules (probably) have not initialized this.
|
||||
mtul.math = mtul.math or {}
|
||||
mtul.loaded_modules.cpml = true
|
||||
|
||||
local modpath = minetest.get_modpath("mtul_cpml")
|
||||
local loaded_modules = {}
|
||||
local old_require = require --just in case require is present (aka it's an insecure environment)
|
||||
local ie = minetest.request_insecure_environment()
|
||||
|
||||
--if require isn't present, allow us to load the modules through hackish means
|
||||
--there's like 100s of require calls, it'd be insane to replace them. If you're farmiliar with require, the goal should be obvious.
|
||||
modules = "" --this is just for Busted support, as it'll bitch about "attempt to concat a nil value" otherwise.
|
||||
--modules is the path to modules
|
||||
local old_package_path
|
||||
if not ie then
|
||||
--if an insecure environment cannot be loaded, then we basically change how require works temporarily, so modules (which is referenced in all CPML files on require() has to be changed)
|
||||
modules = modpath.."/modules/"
|
||||
else
|
||||
old_package_path = package.path
|
||||
--get the real modpath and add it to the package.path string so we can find our modules in require()
|
||||
ie.package.path = ie.package.path .. ";"..string.gsub(modpath, "\\bin\\%.%.", "").."?.lua" --add our path
|
||||
modules = ".modules."
|
||||
end
|
||||
local modpath
|
||||
--check that it's minetest and not a lua script running it. If it's not minetest we dont have to do all of this, but otherwise we dont know if
|
||||
if minetest or (core and core.register_globalstep) then
|
||||
modpath = minetest.get_modpath("mtul_cpml")
|
||||
local ie = minetest.request_insecure_environment()
|
||||
|
||||
|
||||
if not ie then
|
||||
function require(path)
|
||||
if loaded_modules[path] then return loaded_modules[path] end
|
||||
local ending = string.gsub(path:sub(#modules+1), "%.", "/")..".lua"
|
||||
--[[if ending[1] ~= "/" then
|
||||
ending = "/"..ending
|
||||
end]]
|
||||
path = modules..ending
|
||||
loaded_modules[path] = dofile(path)
|
||||
return loaded_modules[path]
|
||||
end
|
||||
else
|
||||
require = ie.require
|
||||
end
|
||||
--print(require, ie.require)
|
||||
|
||||
if type(jit) == "table" and jit.status() then
|
||||
if ie then
|
||||
if pcall(require, "ffi") then
|
||||
minetest.log("verbose", "MTUL-CPML: loaded JIT FFI library. Memory efficiency with FFI enabled.")
|
||||
print("mtul-cpml: JIT FFI loaded successfully.")
|
||||
--since we can't use require, what we do instead is override require by some utterly offensive means.
|
||||
modules = "" --path to modules.
|
||||
if not ie then
|
||||
--if an insecure environment cannot be loaded, then we basically change how require works temporarily, so modules (which is referenced in all CPML files on require() has to be changed)
|
||||
modules = modpath.."/modules/"
|
||||
function require(path)
|
||||
local ending = string.gsub(path:sub(#modules+1), "%.", "/")..".lua"
|
||||
path = modules..ending
|
||||
return dofile(path)
|
||||
end
|
||||
else
|
||||
minetest.log("error", "MTUL-CPML: Failure to load JIT FFI library.")
|
||||
old_package_path = package.path
|
||||
--get the real modpath and add it to the package.path string so we can find our modules in require()
|
||||
ie.package.path = ie.package.path .. ";"..string.gsub(modpath, "\\bin\\%.%.", "").."?.lua" --add our path
|
||||
modules = ".modules."
|
||||
require = ie.require
|
||||
end
|
||||
else
|
||||
minetest.log("error", "MTUL-CPML: insecure environment denied for MTUL-CPML. Add mtul-cpml to your trusted mods for JIT FFI support (memory efficiency & speed boost)")
|
||||
end
|
||||
else
|
||||
minetest.log("verbose", "MTUL-CPML: JIT not present, skipped attempt to load JIT FFI library for acceleration and memory efficiency")
|
||||
end
|
||||
|
||||
--load the files
|
||||
if type(jit) == "table" and jit.status() then
|
||||
if ie then
|
||||
if pcall(require, "ffi") then
|
||||
minetest.log("verbose", "MTUL-CPML: loaded JIT FFI library. Memory efficiency with FFI enabled.")
|
||||
print("mtul-cpml: JIT FFI loaded successfully.")
|
||||
else
|
||||
minetest.log("error", "MTUL-CPML: Failure to load JIT FFI library.")
|
||||
end
|
||||
else
|
||||
minetest.log("error", "MTUL-CPML: insecure environment denied for MTUL-CPML. Add mtul-cpml to your trusted mods for better performance")
|
||||
end
|
||||
else
|
||||
minetest.log("verbose", "MTUL-CPML: JIT not present, skipped attempt to load JIT FFI library for acceleration and memory efficiency")
|
||||
end
|
||||
end
|
||||
--load the files
|
||||
|
||||
for _, file in ipairs(files) do
|
||||
mtul.math[file] = require(modules .. file)
|
||||
end
|
||||
|
||||
--unset all the global shit we had to change for CPML to work properly.
|
||||
if old_package_path then
|
||||
ie.package.path = old_package_path
|
||||
if modpath then
|
||||
if ie then
|
||||
ie.package.path = old_package_path
|
||||
end
|
||||
modules = nil
|
||||
require = old_require
|
||||
end
|
||||
modules = nil
|
||||
require = old_require
|
||||
|
||||
--dofile(modpath.."/unit_tests/quat_unit_test.lua")
|
||||
if modpath then
|
||||
print("MTUL CPML: BEGINNING UNIT TESTING FOR COMPLEX TYPES")
|
||||
dofile(modpath.."/unit_tests/irrlicht_luanti_tests.lua")
|
||||
dofile(modpath.."/unit_tests/matrix_unit_test.lua")
|
||||
dofile(modpath.."/unit_tests/quat_unit_test.lua")
|
||||
else
|
||||
print("MTUL CPML: BEGINNING UNIT TESTING FOR COMPLEX TYPES")
|
||||
require("/unit_tests/irrlicht_luanti_tests.lua")
|
||||
require("/unit_tests/matrix_unit_test.lua")
|
||||
require("/unit_tests/quat_unit_test.lua")
|
||||
end
|
||||
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
# literally just so I dont have to open powershell every time.
|
||||
@echo off
|
||||
ldoc .
|
200
modules/mat4.lua
200
modules/mat4.lua
@ -3,10 +3,11 @@
|
||||
local constants = require(modules .. "constants")
|
||||
local vec2 = require(modules .. "vec2")
|
||||
local vec3 = require(modules .. "vec3")
|
||||
local quat = require(modules .. "quat")
|
||||
--local quat = require(modules .. "quat")
|
||||
local utils = require(modules .. "utils")
|
||||
local precond = require(modules .. "_private_precond")
|
||||
local private = require(modules .. "_private_utils")
|
||||
local DBL_EPSILON = constants.DBL_EPSILON
|
||||
local sqrt = math.sqrt
|
||||
local cos = math.cos
|
||||
local sin = math.sin
|
||||
@ -58,7 +59,8 @@ local tv4 = { 0, 0, 0, 0 }
|
||||
-- table Length 4 (4 vec4s)
|
||||
-- nil
|
||||
-- @treturn mat4 out
|
||||
function mat4.new(a)
|
||||
|
||||
function mat4.new(a, ...)
|
||||
local out = new()
|
||||
|
||||
-- 4x4 matrix
|
||||
@ -128,7 +130,33 @@ end
|
||||
-- @tparam quat q Rotation quaternion
|
||||
-- @treturn mat4 out
|
||||
function mat4.from_quaternion(q)
|
||||
return mat4.from_angle_axis(q:to_angle_axis())
|
||||
--q=q:normalize()
|
||||
return mat4.set_rot_from_quaternion(identity(new()), q)
|
||||
end
|
||||
|
||||
--- set the rotation of a matrix from a quaternion. Not sure at all where i got this code from, but it works...
|
||||
-- i refactored so it works with https://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToMatrix/index.html
|
||||
-- I think I got it from https://github.com/minetest/irrlicht/blob/7173c2c62997b6416f17b90f9a50bff11fef1c4c/include/quaternion.h#L367
|
||||
-- @tparam quat q rotation quaternion. only supports normal quaternion rotation (will normalize)
|
||||
function mat4.set_rot_from_quaternion(m, q)
|
||||
local qx,qy,qz,qw = q.x,q.y,q.z,q.w
|
||||
--normalize the quaternion
|
||||
--local s = 1/sqrt(qx * qx + qy * qy + qz * qz + qw * qw)
|
||||
local s = 1/sqrt(qx * qx + qz * qz + qy * qy + qw * qw)
|
||||
qx,qy,qz,qw = qx*s,qy*s,qz*s,qw*s
|
||||
|
||||
m[1] = 1-2*(qy^2 + qz^2)
|
||||
m[2] = 2*(qx*qy + qz*qw)
|
||||
m[3] = 2*(qx*qz - qy*qw)
|
||||
|
||||
m[5] = 2*(qx*qy - qz*qw)
|
||||
m[6] = 1-2*(qx^2 + qz^2)
|
||||
m[7] = 2*(qy*qz + qx*qw)
|
||||
|
||||
m[9] = 2*(qx*qz + qy*qw)
|
||||
m[10]= 2*(qy*qz - qx*qw)
|
||||
m[11]= 1-2*(qx^2 + qy^2)
|
||||
return m
|
||||
end
|
||||
|
||||
--- Create a matrix from a direction/up pair.
|
||||
@ -186,6 +214,151 @@ function mat4.from_transform(trans, rot, scale)
|
||||
return rsm
|
||||
end
|
||||
|
||||
local tau = 2*math.pi
|
||||
local atan2 = math.atan2
|
||||
--- set the rotation of a given matrix in euler in the ZXY application order. This is the order that minetest entities are rotated in.
|
||||
-- @tparam float pitch the clockwise pitch in radians
|
||||
-- @tparam float yaw the clockwise yaw in radians
|
||||
-- @tparam float roll the clockwise yaw in roll
|
||||
-- @treturn matrix
|
||||
function mat4.set_rot_zxy(M, pitch,yaw,roll)
|
||||
--minetest numeric.h
|
||||
local cr = cos(roll)
|
||||
local sr = sin(roll)
|
||||
local cp = cos(pitch)
|
||||
local sp = sin(pitch);
|
||||
local cy = cos(yaw)
|
||||
local sy = sin(yaw);
|
||||
|
||||
M[1] = sr * sp * sy + cr * cy
|
||||
M[2] = sr * cp
|
||||
M[3] = sr * sp * cy - cr * sy
|
||||
|
||||
M[5] = cr * sp * sy - sr * cy
|
||||
M[6] = cr * cp
|
||||
M[7] = cr * sp * cy + sr * sy
|
||||
|
||||
M[9] = cp * sy
|
||||
M[10] = -sp
|
||||
M[11] = cp * cy
|
||||
return M
|
||||
end
|
||||
local asin = math.asin
|
||||
local abs = math.abs
|
||||
|
||||
--- alias of `set_rot_zxy`. Sets the rotation of a given matrix in euler in the ZXY application order. This is the order that minetest entities are rotated in.
|
||||
-- @tparam float pitch the clockwise pitch in radians
|
||||
-- @tparam float yaw the clockwise yaw in radians
|
||||
-- @tparam float roll the clockwise yaw in roll
|
||||
-- @treturn matrix
|
||||
-- @function set_rot_luanti_entity
|
||||
mat4.set_rot_luanti_entity = mat4.set_rot_zxy
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- get the ZXY euler rotation of the given matrix. This is the order that minetest entities are rotated in.
|
||||
-- @tparam matrix the matrix to get the rotation of
|
||||
-- @treturn float pitch
|
||||
-- @treturn float yaw
|
||||
-- @treturn float roll
|
||||
function mat4.get_rot_zxy(M)
|
||||
local X,Y,Z
|
||||
if abs(M[10])-1 < DBL_EPSILON then --check if x is 90 or -90. If it is yaw will experience gimbal lock and there will therefore be infinite solutions.
|
||||
Z = atan2(M[2], M[6]) --(cz*cx / sz*cx) = cz/cx = tz.
|
||||
Y = atan2(M[9], M[11])
|
||||
X = atan2(-M[10], M[6]/cos(Z))
|
||||
else
|
||||
Z = atan2(M[7], M[5])
|
||||
Y = 0 --pitch and roll are the same given x=90 or -90.
|
||||
X = asin(-M[10])
|
||||
end
|
||||
return X,Y,Z
|
||||
end
|
||||
|
||||
--- Alias of `get_rot_zxy`. Gets the ZXY euler rotation of the given matrix. This is the order that minetest entities are rotated in.
|
||||
-- @tparam matrix the matrix to get the rotation of
|
||||
-- @treturn float pitch
|
||||
-- @treturn float yaw
|
||||
-- @treturn float roll
|
||||
-- @function get_rot_luanti_entity
|
||||
mat4.get_rot_luanti_entity = mat4.get_rot_zxy
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
--- set the rotation of a given matrix in euler in the XYZ application order. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
-- @tparam float pitch the clockwise pitch in radians
|
||||
-- @tparam float yaw the clockwise yaw in radians
|
||||
-- @tparam float roll the clockwise yaw in roll
|
||||
-- @treturn matrix
|
||||
function mat4.set_rot_xyz(M, pitch,yaw,roll)
|
||||
--standard euler rotation matrices applied in XYZ order (matrix transformations are applied in inverse)
|
||||
local cp = cos(pitch)
|
||||
local sp = sin(pitch)
|
||||
local cy = cos(yaw)
|
||||
local sy = sin(yaw)
|
||||
local cr = cos(roll)
|
||||
local sr = sin(roll)
|
||||
|
||||
M[1] = (cy * cr)
|
||||
M[2] = (cy * sr)
|
||||
M[3] = (-sy)
|
||||
|
||||
M[5] = (sp * sy * cr - cp * sr)
|
||||
M[6] = (sp * sy * sr + cp * cr)
|
||||
M[7] = (sp * cy)
|
||||
|
||||
M[9] = (cp * sy * cr + sp * sr)
|
||||
M[10] = (cp * sy * sr - sp * cr)
|
||||
M[11] = (cp * cy)
|
||||
return M
|
||||
end
|
||||
|
||||
--- alias of `set_rot_xyz`. Sets the rotation of a given matrix in euler in the XYZ application order. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
-- @tparam float pitch the clockwise pitch in radians
|
||||
-- @tparam float yaw the clockwise yaw in radians
|
||||
-- @tparam float roll the clockwise yaw in roll
|
||||
-- @treturn matrix
|
||||
-- @function set_rot_irrlicht_bone
|
||||
mat4.set_rot_irrlicht_bone = mat4.set_rot_xyz
|
||||
|
||||
|
||||
|
||||
--- Get the XYZ euler rotation of the given matrix. This is the rotation order irrlicht uses (i.e. for bones in Luanti)
|
||||
-- @tparam matrix the matrix to get the rotation of
|
||||
-- @treturn float pitch
|
||||
-- @treturn float yaw
|
||||
-- @treturn float roll
|
||||
function mat4.get_rot_xyz(M)
|
||||
local X,Y,Z
|
||||
if abs(M[3])-1 < DBL_EPSILON then --check if x is 90 or -90. If they are yaw will experience gimbal lock and there will therefore be infinite solutions.
|
||||
Z = atan2(M[2], M[1])
|
||||
Y = atan2(-M[3], M[1]/cos(Z))
|
||||
X = atan2(M[7], M[11])
|
||||
else
|
||||
--Z = atan2(M[], M[])
|
||||
Y = asin(M[3])
|
||||
X = atan2(M[5], M[7])
|
||||
Z = 0
|
||||
end
|
||||
return X,Y,Z
|
||||
end
|
||||
|
||||
--- Alias of `get_rot_zxy`. Gets the XYZ euler rotation of the given matrix. This is the rotation order irrlicht uses (i.e. for bones in Luanti).
|
||||
-- @tparam matrix the matrix to get the rotation of
|
||||
-- @treturn float pitch
|
||||
-- @treturn float yaw
|
||||
-- @treturn float roll
|
||||
-- @function get_rot_irrlicht_bone
|
||||
mat4.get_rot_irrlicht_bone = mat4.get_rot_xyz
|
||||
|
||||
|
||||
|
||||
|
||||
--- Create matrix from orthogonal.
|
||||
-- @tparam number left
|
||||
-- @tparam number right
|
||||
@ -773,19 +946,18 @@ end
|
||||
--- Convert a matrix to a quaternion.
|
||||
-- @tparam mat4 a Matrix to be converted
|
||||
-- @treturn quat out
|
||||
function mat4.to_quat(a)
|
||||
identity(tmp):transpose(a)
|
||||
|
||||
local w = sqrt(1 + tmp[1] + tmp[6] + tmp[11]) / 2
|
||||
local scale = w * 4
|
||||
local q = quat.new(
|
||||
tmp[10] - tmp[7] / scale,
|
||||
tmp[3] - tmp[9] / scale,
|
||||
tmp[5] - tmp[2] / scale,
|
||||
local quat_new
|
||||
function mat4.to_quaternion(m)
|
||||
--I want to note that for no apparent reason at all the original matrix was transposed here
|
||||
if not quat_new then quat_new = mtul.math.quat.new end
|
||||
local w = math.sqrt(1 + m[1] + m[6] + m[11]) / 2
|
||||
local q=quat_new(
|
||||
(m[7] - m[10]) /(4 * w),
|
||||
(m[9] - m[3]) /(4 * w),
|
||||
(m[2] - m[5]) /(4 * w),
|
||||
w
|
||||
)
|
||||
|
||||
return q:normalize(q)
|
||||
return q
|
||||
end
|
||||
|
||||
-- http://www.crownandcutlass.com/features/technicaldetails/frustum.html
|
||||
|
279
modules/quat.lua
279
modules/quat.lua
@ -5,6 +5,8 @@ local constants = require(modules .. "constants")
|
||||
local vec3 = require(modules .. "vec3")
|
||||
local precond = require(modules .. "_private_precond")
|
||||
local private = require(modules .. "_private_utils")
|
||||
local utils = require(modules .. "utils")
|
||||
local mat4 = require(modules .. "mat4")
|
||||
local DOT_THRESHOLD = constants.DOT_THRESHOLD
|
||||
local DBL_EPSILON = constants.DBL_EPSILON
|
||||
local acos = math.acos
|
||||
@ -36,10 +38,6 @@ if type(jit) == "table" and jit.status() then
|
||||
end
|
||||
end
|
||||
|
||||
-- Statically allocate a temporary variable used in some of our functions.
|
||||
local tmp = new()
|
||||
local qv, uv, uuv = vec3(), vec3(), vec3()
|
||||
|
||||
--- Constants
|
||||
-- @table quat
|
||||
-- @field unit Unit quaternion
|
||||
@ -79,6 +77,10 @@ function quat.new(x, y, z, w)
|
||||
return new(0, 0, 0, 1)
|
||||
end
|
||||
|
||||
--[[returns the required delta rotation to make a quaternion aim at a point
|
||||
function quat.aim_at_point(quat)
|
||||
end]]
|
||||
|
||||
--- Create a quaternion from an angle/axis pair.
|
||||
-- @tparam number angle Angle (in radians)
|
||||
-- @param axis/x -- Can be of two types, a vec3 axis, or the x component of that axis
|
||||
@ -96,28 +98,6 @@ function quat.from_angle_axis(angle, axis, a3, a4)
|
||||
end
|
||||
end
|
||||
|
||||
--works in theory... probably.
|
||||
--- Create a quaternion from an euler angle
|
||||
-- @tparam Vec3 (or xyz table)
|
||||
-- @treturn quat out
|
||||
function quat.from_euler_rotation(rot)
|
||||
local cr = cos(rot.z*.5)
|
||||
local sr = sin(rot.z*.5)
|
||||
|
||||
local cp = cos(rot.x*.5)
|
||||
local sp = sin(rot.x*.5)
|
||||
|
||||
local cy = cos(rot.y*.5)
|
||||
local sy = sin(rot.y*.5)
|
||||
return quat.new({
|
||||
w = cr * cp * cy + sr * sp * sy,
|
||||
x = sr * cp * cy - cr * sp * sy,
|
||||
y = cr * sp * cy + sr * cp * sy,
|
||||
z = cr * cp * sy - sr * sp * cy
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
--- Create a quaternion from a normal/up vector pair. (accepts minetest vectors)
|
||||
-- @tparam vec3 normal
|
||||
-- @tparam vec3 up (optional)
|
||||
@ -167,28 +147,48 @@ end
|
||||
-- @tparam quat a Left hand operand
|
||||
-- @tparam quat b Right hand operand
|
||||
-- @treturn quat quaternion equivalent to "apply b, then a"
|
||||
local out = {}
|
||||
function quat.mul(a, b)
|
||||
return new(
|
||||
a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
|
||||
a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
|
||||
a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
|
||||
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z
|
||||
(a.x * b.w) + (a.w * b.x) + (a.y * b.z) - (a.z * b.y),
|
||||
(a.y * b.w) + (a.w * b.y) + (a.z * b.x) - (a.x * b.z),
|
||||
(b.w * a.z) + (b.z * a.w) + (b.y * a.x) - (b.x * a.y),
|
||||
(a.w * b.w) - (a.x * b.x) - (a.y * b.y) - (a.z * b.z)
|
||||
)
|
||||
end
|
||||
|
||||
--- Multiply a quaternion and a vec3.
|
||||
-- Statically allocate a temporary variable used in some of our functions.
|
||||
local tmp = new()
|
||||
local u, uv, uuv = vec3(), vec3(), vec3()
|
||||
|
||||
--- Multiply a quaternion and a vec3. Equivalent to rotating the vector (a) by the quaternion (v)
|
||||
-- @tparam quat a Left hand operand
|
||||
-- @tparam vec3 b Right hand operand
|
||||
-- @tparam vec3 v Right hand operand
|
||||
-- @treturn vec3 out
|
||||
function quat.mul_vec3(a, b)
|
||||
qv.x = a.x
|
||||
qv.y = a.y
|
||||
qv.z = a.z
|
||||
uv = qv:cross(b)
|
||||
uuv = qv:cross(uv)
|
||||
return b + ((uv * a.w) + uuv) * 2
|
||||
function quat.mul_vec3(a, v)
|
||||
u.x = a.x
|
||||
u.y = a.y
|
||||
u.z = a.z
|
||||
uv = u:cross(v)
|
||||
uuv = u:cross(uv)
|
||||
return v + ((uv * a.w) + uuv) * 2
|
||||
end
|
||||
|
||||
--[[ does the same thing as above, which I did not know when i reimplemented it to check.
|
||||
function quat.rotate_vec3(a, v)
|
||||
u.x = a.x
|
||||
u.y = a.y
|
||||
u.z = a.z
|
||||
local s = a.w
|
||||
return
|
||||
|
||||
(u*u:dot(v)*2) +
|
||||
|
||||
(v*(s*s - u:dot(u))) +
|
||||
|
||||
(u:cross(v)*s*2)
|
||||
end]]
|
||||
|
||||
--- Raise a normalized quaternion to a scalar power.
|
||||
-- @tparam quat a Left hand operand (should be a unit quaternion)
|
||||
-- @tparam number s Right hand operand
|
||||
@ -253,7 +253,7 @@ function quat.scale(a, s)
|
||||
)
|
||||
end
|
||||
|
||||
--- Alias of from_angle_axis.
|
||||
--- Alias of `from_angle_axis.`
|
||||
-- @tparam number angle Angle (in radians)
|
||||
-- @param axis/x -- Can be of two types, a vec3 axis, or the x component of that axis
|
||||
-- @param y axis -- y component of axis (optional, only if x component param used)
|
||||
@ -445,42 +445,177 @@ function quat.to_angle_axis(a, identityAxis)
|
||||
return angle, vec3(x, y, z)
|
||||
end
|
||||
|
||||
--- Convert a quaternion into euler angle components
|
||||
-- @tparam quat a Quaternion to convert
|
||||
-- @treturn roll
|
||||
-- @treturn pitch
|
||||
-- @treturn yaw
|
||||
--no idea if this shit really works, very well could not...
|
||||
function quat.to_euler_angles_unpack(q)
|
||||
-- roll (x-axis rotation)
|
||||
local sinr_cosp = 2 * (q.w * q.x + q.y * q.z)
|
||||
local cosr_cosp = 1 - 2 * (q.x * q.x + q.y * q.y)
|
||||
local pitch = math.atan2(sinr_cosp, cosr_cosp)
|
||||
|
||||
-- pitch (y-axis rotation)
|
||||
local sinp = 2 * (q.w * q.y - q.z * q.x)
|
||||
local yaw
|
||||
if math.abs(sinp) >= 1 then
|
||||
yaw = math.pi / 2 * ((sinp > 0) and 1 or -1) -- Use 90 degrees if out of range
|
||||
else
|
||||
yaw = math.asin(sinp)
|
||||
end
|
||||
|
||||
-- yaw (z-axis rotation)
|
||||
local siny_cosp = 2 * (q.w * q.z + q.x * q.y)
|
||||
local cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z)
|
||||
local roll = math.atan2(siny_cosp, cosy_cosp)
|
||||
|
||||
return pitch, yaw, roll
|
||||
--- set a matrix's rotation fields from a quaternion. Uses mat4.set_rot_from_quaternion
|
||||
-- @tparam quat quaternion to convert
|
||||
-- @tparam mat4 the mat4 to apply to.
|
||||
-- @treturn mat4
|
||||
function quat.set_matrix_rot(q, m)
|
||||
m:set_rot_from_quaternion(q)
|
||||
return m
|
||||
end
|
||||
|
||||
--- Convert a quaternion into euler angles
|
||||
-- @tparam quat a Quaternion to convert
|
||||
-- @treturn result a {roll, pitch, yaw} table
|
||||
function quat.to_euler_angles(a)
|
||||
return {quat.to_euler_angles_unpack(a)}
|
||||
--- create a new quaternion from a matrix. Uses mat4.to_quaternion
|
||||
-- @tparam mat4 the matrix to use
|
||||
-- @treturn quat
|
||||
function quat.from_matrix(m)
|
||||
return m:to_quaternion()
|
||||
end
|
||||
|
||||
|
||||
|
||||
--- convert a quaternion to an ZXY euler angles. This is the rotation order used by Minetest/Luanti Entities.
|
||||
-- @tparam quat quaternion to convert
|
||||
-- @treturn float X
|
||||
-- @treturn float Y
|
||||
-- @treturn float Z
|
||||
local atan2 = math.atan2
|
||||
local abs = math.abs
|
||||
local asin = math.asin
|
||||
function quat.get_euler_zxy(q)
|
||||
local qx, qy, qz, qw = q.x, q.y, q.z, q.w
|
||||
local s = 1/sqrt(qx * qx + qz * qz + qy * qy + qw * qw)
|
||||
qx,qz,qy,qw = qx*s, qz*s, qy*s, qw*s
|
||||
--convert to matrix but only grab the matrix indices we need. Basically this violently smashes together the matrix to zxy and quat to matrix code.
|
||||
local m2 = 2*(qx*qy + qz*qw)
|
||||
local m5 = 2*(qx*qy - qz*qw)
|
||||
local m6 = 1-2*(qx^2 + qz^2)
|
||||
local m7 = 2*(qy*qz + qx*qw)
|
||||
local m9 = 2*(qx*qz + qy*qw)
|
||||
local m10 = 2*(qy*qz - qx*qw)
|
||||
local m11 = 1-2*(qx^2 + qy^2)
|
||||
|
||||
local X,Y,Z
|
||||
if abs(m10)-1 < DBL_EPSILON then --check if x is 90 or -90. If it is yaw will experience gimbal lock and there will therefore be infinite solutions.
|
||||
Z = atan2(m2, m6) --(cz*cx / sz*cx) = cz/cx = tz.
|
||||
Y = atan2(m9, m11)
|
||||
X = atan2(-m10, m6/cos(Z))
|
||||
else
|
||||
Z = atan2(m7, m5)
|
||||
Y = 0 --pitch and roll are the same given x=90 or -90.
|
||||
X = asin(-m10)
|
||||
end
|
||||
return X,Y,Z
|
||||
end
|
||||
|
||||
--- alias of `get_euler_zxy`
|
||||
-- @function quat.get_rot_luanti_entity
|
||||
quat.get_euler_luanti_entity = quat.get_euler_zxy
|
||||
|
||||
|
||||
|
||||
--- create a quaternion from euler angles in the ZXY rotation order. This is the rotation order Luanti Entities use
|
||||
-- @tparam float X
|
||||
-- @tparam float Y
|
||||
-- @tparam float Z
|
||||
-- @treturn quat q
|
||||
function quat.from_euler_zxy(X,Y,Z)
|
||||
--I want to note that for no apparent reason at all the original matrix was transposed here
|
||||
local cr = cos(Z)
|
||||
local sr = sin(Z)
|
||||
local cp = cos(X)
|
||||
local sp = sin(X);
|
||||
local cy = cos(Y)
|
||||
local sy = sin(Y);
|
||||
|
||||
local m1 = sr * sp * sy + cr * cy
|
||||
local m2 = sr * cp
|
||||
local m3 = sr * sp * cy - cr * sy
|
||||
|
||||
local m5 = cr * sp * sy - sr * cy
|
||||
local m6 = cr * cp
|
||||
local m7 = cr * sp * cy + sr * sy
|
||||
|
||||
local m9 = cp * sy
|
||||
local m10 = -sp
|
||||
local m11 = cp * cy
|
||||
local w = math.sqrt(1 + m1 + m6 + m11) / 2
|
||||
return new(
|
||||
(m7 - m10) /(4 * w),
|
||||
(m9 - m3) /(4 * w),
|
||||
(m2 - m5) /(4 * w),
|
||||
w
|
||||
)
|
||||
end
|
||||
|
||||
--- alias of `from_euler_zxy`
|
||||
-- @function quat.get_rot_luanti_entity
|
||||
quat.from_euler_luanti_entity = quat.from_euler_zxy
|
||||
|
||||
|
||||
|
||||
--- convert a quaternion to an xyz euler angles. This is the rotation order used by irrlicht bones.
|
||||
-- @tparam quat quaternion to convert
|
||||
-- @treturn X
|
||||
-- @treturn Y
|
||||
-- @treturn Z
|
||||
function quat.get_euler_xyz(q)
|
||||
local qx, qy, qz, qw = q.x, q.y, q.z, q.w
|
||||
local s = 1/sqrt(qx * qx + qz * qz + qy * qy + qw * qw)
|
||||
qx,qz,qy,qw = qx*s, qz*s, qy*s, qw*s
|
||||
--convert to matrix but only grab the matrix indices we need. Basically this violently smashes together the matrix to zxy and quat to matrix code.
|
||||
local m1 = 1-2*(qy^2 + qz^2)
|
||||
local m2 = 2*(qx*qy + qz*qw)
|
||||
local m3 = 2*(qx*qz - qy*qw)
|
||||
local m5 = 2*(qx*qy - qz*qw)
|
||||
local m7 = 2*(qy*qz + qx*qw)
|
||||
local m11 = 1-2*(qx^2 + qy^2)
|
||||
|
||||
local X,Y,Z
|
||||
if abs(m3)-1 < DBL_EPSILON then --check if x is 90 or -90. If they are yaw will experience gimbal lock and there will therefore be infinite solutions.
|
||||
Z = atan2(m2, m1)
|
||||
Y = atan2(-m3, m1/cos(Z))
|
||||
X = atan2(m7, m11)
|
||||
else
|
||||
--Z = atan2(M[], M[])
|
||||
Y = asin[m3]
|
||||
X = atan2(m5, m7)
|
||||
Z = 0
|
||||
end
|
||||
return X,Y,Z
|
||||
end
|
||||
|
||||
--- alias of `get_euler_xyz`
|
||||
-- @function quat.get_rot_irrlicht_bone
|
||||
quat.get_euler_irrlicht_bone = quat.get_euler_xyz
|
||||
|
||||
|
||||
|
||||
--- create a quaternion from euler angles in the xyz rotation order. This is the rotation order irrlicht bones use
|
||||
-- @tparam float X
|
||||
-- @tparam float Y
|
||||
-- @tparam float Z
|
||||
-- @treturn quat q
|
||||
function quat.from_euler_xyz(X,Y,Z)
|
||||
local cp = cos(X)
|
||||
local sp = sin(X)
|
||||
local cy = cos(Y)
|
||||
local sy = sin(Y)
|
||||
local cr = cos(Z)
|
||||
local sr = sin(Z)
|
||||
|
||||
local m1 = (cy * cr)
|
||||
local m2 = (cy * sr)
|
||||
local m3 = (-sy)
|
||||
|
||||
local m5 = (sp * sy * cr - cp * sr)
|
||||
local m6 = (sp * sy * sr + cp * cr)
|
||||
local m7 = (sp * cy)
|
||||
|
||||
local m9 = (cp * sy * cr + sp * sr)
|
||||
local m10 = (cp * sy * sr - sp * cr)
|
||||
local m11 = (cp * cy)
|
||||
local w = math.sqrt(1 + m1 + m6 + m11) / 2
|
||||
return new(
|
||||
(m7 - m10) /(4 * w),
|
||||
(m9 - m3) /(4 * w),
|
||||
(m2 - m5) /(4 * w),
|
||||
w
|
||||
)
|
||||
end
|
||||
--- alias of `quat.from_euler_zxy`
|
||||
--@function quat.get_rot_irrlicht_bone
|
||||
quat.from_euler_irrlicht_bone = quat.from_euler_xyz
|
||||
|
||||
--- Convert a quaternion into a vec3.
|
||||
-- @tparam quat a Quaternion to convert
|
||||
-- @treturn vec3 out
|
||||
|
Loading…
x
Reference in New Issue
Block a user