mirror of
https://github.com/luanti-org/luanti.git
synced 2025-06-27 16:36:03 +00:00
Polish
This commit is contained in:
parent
513532a93c
commit
f7067644a3
8 changed files with 107 additions and 92 deletions
|
@ -4154,19 +4154,22 @@ For example:
|
|||
Rotations
|
||||
=========
|
||||
|
||||
As abusing vectors of euler angles is discouraged as error-prone,
|
||||
Luanti provides a proper helper class for working with 3d rotations.
|
||||
Using vectors of euler angles instead is discouraged as it is error-prone.
|
||||
|
||||
You must not rely on the specific type or imprecision of the current implementation.
|
||||
The precision of the implementation may change (improve) in the future.
|
||||
|
||||
Adhering to Luanti and Irrlicht conventions, rotations use **left-handed** conventions
|
||||
with a rotation order of **XYZ** (X first, then Y, then Z).
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
* `Rotation.identity()`: Constructs a no-op rotation.
|
||||
* `Rotation.quaternion(x, y, z, w)`:
|
||||
Constructs a rotation from a quaternion (which need not be normalized)
|
||||
Constructs a rotation from a quaternion (which need not be normalized).
|
||||
* `Rotation.axis_angle(axis, angle)`:
|
||||
Constructs a rotation around the given axis by the given angle
|
||||
Constructs a rotation around the given axis by the given angle.
|
||||
* `axis` is a vector, which need not be normalized
|
||||
* `angle` is in radians
|
||||
* Shorthands for rotations around the respective axes:
|
||||
|
@ -4175,16 +4178,15 @@ Constructors
|
|||
* `Rotation.z(roll)`
|
||||
* `Rotation.euler_angles(pitch, yaw, roll)`
|
||||
* All angles in radians.
|
||||
* Rotation order is ZYX: First pitch is applied, then yaw, then roll. Equivalent to
|
||||
`Rotation.compose(Rotation.z(roll), Rotation.y(yaw), Rotation.x(pitch))`.
|
||||
* Consistent with the euler angles that can be used for bones.
|
||||
* Mathematically equivalent to `Rotation.compose(Rotation.z(roll), Rotation.y(yaw), Rotation.x(pitch))`.
|
||||
* Consistent with the euler angles that can be used for bones or attachments.
|
||||
|
||||
Conversions
|
||||
-----------
|
||||
|
||||
Corresponding to the constructors, quaternions can be converted
|
||||
Corresponding to the constructors, rotations can be converted
|
||||
to different representations; note that you need not get the same values out -
|
||||
you merely get values that produce the same rotation when passed to the corresponding constructor:
|
||||
you merely get values that produce a (roughly) equivalent rotation when passed to the corresponding constructor:
|
||||
|
||||
* `x, y, z, w = Rotation:to_quaternion()`
|
||||
* Returns the normalized quaternion representation.
|
||||
|
@ -4194,8 +4196,8 @@ you merely get values that produce the same rotation when passed to the correspo
|
|||
* `pitch, yaw, roll = Rotation:to_euler_angles()`
|
||||
* Angles are all in radians.
|
||||
* `pitch`, `yaw`, `roll`: Rotation around the X-, Y-, and Z-axis respectively.
|
||||
* Rotation order is ZYX: First pitch is applied, then yaw, then roll.
|
||||
* Coordinate system is right-handed <!-- TODO -->
|
||||
|
||||
Rotations can also be converted to matrices using `Matrix4.rotation(rot)`.
|
||||
|
||||
Methods
|
||||
-------
|
||||
|
@ -4212,11 +4214,14 @@ Methods
|
|||
* `Rotation:angle_to(other)`: Returns the absolute angle between two quaternions.
|
||||
* Useful to measure similarity.
|
||||
|
||||
Rotations implement `__tostring`. The format is only intended for human-readability,
|
||||
not serialization, and may thus change.
|
||||
|
||||
|
||||
Matrices
|
||||
========
|
||||
|
||||
Luanti uses 4x4 matrices to represent transformations of 3d vectors.
|
||||
Luanti uses 4x4 matrices to represent transformations of 3d vectors (embedded into 4d space).
|
||||
The matrices use row-major conventions:
|
||||
The first row is the image of the vector (1, 0, 0, 0),
|
||||
the second row is the image of (0, 1, 0, 0), and so on.
|
||||
|
@ -4231,6 +4236,8 @@ Matrices are very suitable for constructing, composing and applying
|
|||
linear transformations; they are not so useful for exact storage of transformations,
|
||||
decomposition into rotation and scale will not be exact.
|
||||
|
||||
Row and column indices range from `1` to `4`.
|
||||
|
||||
Constructors
|
||||
------------
|
||||
|
||||
|
@ -4250,31 +4257,34 @@ Methods
|
|||
|
||||
Storage:
|
||||
|
||||
* `Matrix4:get(row, col)`: Get an entry.
|
||||
* `row` and `col` range from 1 to 4
|
||||
* `Matrix4:set(row, col, element)`: Set an entry.
|
||||
* `row` and `col` range from 1 to 4
|
||||
* `Matrix4:get(row, col)`
|
||||
* `Matrix4:set(row, col, number)`
|
||||
* `x, y, z, w = Matrix4:get_row(row)`
|
||||
* `Matrix4:set_row(row, x, y, z, w)`
|
||||
* `x, y, z, w = Matrix4:get_column(col)`
|
||||
* `Matrix4:set_column(col, x, y, z, w)`
|
||||
* `Matrix4:copy()`: Copy the matrix.
|
||||
* `... = Matrix4:unpack()`: Get the entries of the matrix in row-major order.
|
||||
* `Matrix4:copy()`
|
||||
* `... = Matrix4:unpack()`: Get the 16 numbers in the matrix in row-major order
|
||||
(inverse of `Matrix4.new`).
|
||||
|
||||
Linear algebra:
|
||||
|
||||
* Vector transformations:
|
||||
* `x, y, z, w = Matrix4:transform_4d(x, y, z, w)`: Apply the matrix to a 4d vector.
|
||||
* `Matrix4:transform_position(pos)`:
|
||||
* Apply the matrix to a vector representing a position.
|
||||
* Applies the transformation as if w = 1 and discards the resulting w component.
|
||||
* `Matrix4:transform_direction(dir)`:
|
||||
* Apply the matrix to a vector representing a direction.
|
||||
* Ignores the fourth row and column; does not apply the translation (w = 0).
|
||||
* `Matrix4.compose(...)`: Returns the composition of the given matrices.
|
||||
* `Matrix4:transpose()`: Returns the transpose of the matrix.
|
||||
* `Matrix4:invert()`: Returns the inverse, or `nil` if the matrix is (close to being) singular.
|
||||
* `x, y, z, w = Matrix4:transform_4d(x, y, z, w)`: Apply the matrix to a 4d vector.
|
||||
* `Matrix4:transform_position(pos)`:
|
||||
* Apply the matrix to a vector representing a position.
|
||||
* Applies the transformation as if w = 1 and discards the resulting w component.
|
||||
* `Matrix4:transform_direction(dir)`:
|
||||
* Apply the matrix to a vector representing a direction.
|
||||
* Ignores the fourth row and column; does not apply the translation (w = 0).
|
||||
If `...` is empty, this is just the identity.
|
||||
* `Matrix4:determinant()`: Returns the determinant.
|
||||
* `Matrix4:invert()`: Returns a newly created inverse, or `nil` if the matrix is (close to being) singular.
|
||||
* `Matrix4:transpose()`: Returns a transposed copy of the matrix.
|
||||
* `Matrix4:equals(other, [tolerance = 0])`:
|
||||
Returns whether all components differ in absolute value at most by the given tolerance.
|
||||
* `m1 == m2`: Returns whether `m1` and `m2` are identical (`tolerance = 0`).
|
||||
* `Matrix4:is_affine_transform([tolerance = 0])`:
|
||||
Whether the matrix is an affine transformation in 3d space,
|
||||
meaning it is a 3d linear transformation plus a translation.
|
||||
|
@ -4282,36 +4292,33 @@ Linear algebra:
|
|||
|
||||
For working with affine transforms, the following methods are available:
|
||||
|
||||
* `Matrix4:get_translation()`:
|
||||
Returns the translation as a vector.
|
||||
* `Matrix4:set_translation(vec)`
|
||||
* `Matrix4:get_translation()`: Returns the translation as a vector.
|
||||
* `Matrix4:set_translation(vec)`: Sets (overwrites) the translation in the last row.
|
||||
|
||||
For TRS transforms specifically,
|
||||
let `self = Matrix4.compose(Matrix4.translation(t), Matrix4.rotation(r), Matrix4.scale(s))`.
|
||||
Then we can decompose `self` further. Note that `self` must not shear or reflect.
|
||||
|
||||
* `rotation, scale = Matrix4:get_rs()`:
|
||||
Extracts a `Rotation` equivalent to `r`.
|
||||
Extracts a `Rotation` equivalent to `r`,
|
||||
along with the corresponding component-wise scaling factors as a vector.
|
||||
|
||||
|
||||
Operators
|
||||
---------
|
||||
|
||||
Similar to vectors, matrices define some arithmetic operators:
|
||||
Similar to vectors, matrices define some element-wise arithmetic operators:
|
||||
|
||||
* `m1 == m2`: Returns whether `m1` and `m2` are identical.
|
||||
* `-m`: Returns the additive inverse.
|
||||
* `m1 + m2`: Returns the sum of both matrices.
|
||||
* `m1 - m2`: Shorthand for `m1 + (-m2)`.
|
||||
* `-m`: Returns the additive inverse.
|
||||
* `m * s` or `s * m`: Returns the matrix `m` scaled by the scalar `s`.
|
||||
* Note: *All* entries are scaled, including the last row.
|
||||
* Note: *All* entries are scaled, including the last column:
|
||||
The matrix may not be an affine transform afterwards.
|
||||
|
||||
Matrices also define a `__tostring` metamethod.
|
||||
This is only intended for human readability and not for serialization.
|
||||
|
||||
|
||||
|
||||
Helper functions
|
||||
================
|
||||
|
||||
|
|
|
@ -1663,14 +1663,16 @@ inline void CMatrix4<T>::getTransposed(CMatrix4<T> &o) const
|
|||
template <class T>
|
||||
std::ostream& operator<<(std::ostream& os, const CMatrix4<T>& matrix)
|
||||
{
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
os << "(\n";
|
||||
for (int row = 0; row < 4; ++row) {
|
||||
for (int col = 0; col < 4; ++col) {
|
||||
os << "\t";
|
||||
os << matrix(row, col);
|
||||
}
|
||||
os << "\n";
|
||||
}
|
||||
return os;
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
// used to scale <-1,-1><1,1> to viewport
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
#include "matrix4.h"
|
||||
#include "vector3d.h"
|
||||
|
||||
#include <ostream>
|
||||
|
||||
// NOTE: You *only* need this when updating an application from Irrlicht before 1.8 to Irrlicht 1.8 or later.
|
||||
// Between Irrlicht 1.7 and Irrlicht 1.8 the quaternion-matrix conversions changed.
|
||||
// Before the fix they had mixed left- and right-handed rotations.
|
||||
|
@ -215,6 +217,12 @@ public:
|
|||
f32 W; // real part
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const quaternion& q)
|
||||
{
|
||||
os << q.X << "\t" << q.Y << "\t" << q.Z << "\t" << q.W;
|
||||
return os;
|
||||
}
|
||||
|
||||
// Constructor which converts Euler angles to a quaternion
|
||||
inline quaternion::quaternion(f32 x, f32 y, f32 z)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,6 @@ extern "C" {
|
|||
#include <irr_v3d.h>
|
||||
#include <string_view>
|
||||
#include "c_converter.h"
|
||||
#include "c_types.h"
|
||||
|
||||
/*
|
||||
* Read template functions
|
||||
|
@ -50,12 +49,12 @@ f64 LuaHelper::readParam(lua_State *L, int index)
|
|||
}
|
||||
|
||||
template <>
|
||||
LuaHelper::Finite<f32> LuaHelper::readParam(lua_State *L, int index)
|
||||
f32 LuaHelper::readFiniteParam(lua_State *L, int index)
|
||||
{
|
||||
f64 original_value = luaL_checknumber(L, index);
|
||||
f32 v = static_cast<f32>(original_value);
|
||||
if (std::isfinite(v))
|
||||
return {v};
|
||||
return v;
|
||||
if (std::isnan(original_value))
|
||||
luaL_argerror(L, index, "number is NaN");
|
||||
if (!std::isfinite(original_value))
|
||||
|
@ -66,11 +65,11 @@ LuaHelper::Finite<f32> LuaHelper::readParam(lua_State *L, int index)
|
|||
}
|
||||
|
||||
template <>
|
||||
LuaHelper::Finite<f64> LuaHelper::readParam(lua_State *L, int index)
|
||||
f64 LuaHelper::readFiniteParam(lua_State *L, int index)
|
||||
{
|
||||
f64 v = luaL_checknumber(L, index);
|
||||
if (std::isfinite(v))
|
||||
return {v};
|
||||
return v;
|
||||
if (std::isnan(v))
|
||||
luaL_argerror(L, index, "number is NaN");
|
||||
luaL_argerror(L, index, "number is not finite");
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
#include <string_view>
|
||||
|
||||
extern "C" {
|
||||
|
@ -25,11 +24,12 @@ protected:
|
|||
template <typename T>
|
||||
static T readParam(lua_State *L, int index);
|
||||
|
||||
/// Type to represent a restriction to finite floats
|
||||
template<typename T>
|
||||
struct Finite {
|
||||
T value;
|
||||
};
|
||||
/**
|
||||
* @brief Read a value, but restrict to finite floats.
|
||||
* @see readParam
|
||||
*/
|
||||
template <typename T>
|
||||
static T readFiniteParam(lua_State *L, int index);
|
||||
|
||||
/**
|
||||
* Read a value using a template type T from Lua state L at index
|
||||
|
|
|
@ -14,19 +14,18 @@
|
|||
#include "quaternion.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
#include <luajit-2.1/lauxlib.h>
|
||||
#include <sstream>
|
||||
|
||||
template<int max = 4>
|
||||
static int read_index(lua_State *L, int index)
|
||||
template<int MAX>
|
||||
int LuaMatrix4::readIndex(lua_State *L, int index)
|
||||
{
|
||||
f64 value = luaL_checknumber(L, index);
|
||||
f64 value = readParam<f64>(L, index);
|
||||
if (std::floor(value) != value)
|
||||
luaL_argerror(L, index, "index must be integer");
|
||||
if (value < 1 || value > max)
|
||||
if (value < 1 || value > MAX)
|
||||
luaL_argerror(L, index, "index out of range");
|
||||
return static_cast<int>(value) - 1;
|
||||
}
|
||||
|
@ -52,7 +51,7 @@ int LuaMatrix4::l_identity(lua_State *L)
|
|||
|
||||
int LuaMatrix4::l_all(lua_State *L)
|
||||
{
|
||||
f32 v = luaL_checknumber(L, 1);
|
||||
f32 v = readParam<f32>(L, 1);
|
||||
create(L) = v;
|
||||
return 1;
|
||||
}
|
||||
|
@ -63,7 +62,7 @@ int LuaMatrix4::l_new(lua_State *L)
|
|||
luaL_error(L, "expected 16 arguments");
|
||||
core::matrix4 &matrix = create(L);
|
||||
for (int i = 0; i < 16; ++i)
|
||||
matrix[i] = luaL_checknumber(L, 1 + i);
|
||||
matrix[i] = readParam<f32>(L, 1 + i);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -118,8 +117,8 @@ int LuaMatrix4::l_reflection(lua_State *L)
|
|||
int LuaMatrix4::l_get(lua_State *L)
|
||||
{
|
||||
const auto &matrix = check(L, 1);
|
||||
int row = read_index(L, 2);
|
||||
int col = read_index(L, 3);
|
||||
int row = readIndex(L, 2);
|
||||
int col = readIndex(L, 3);
|
||||
lua_pushnumber(L, matrix(row, col));
|
||||
return 1;
|
||||
}
|
||||
|
@ -127,9 +126,9 @@ int LuaMatrix4::l_get(lua_State *L)
|
|||
int LuaMatrix4::l_set(lua_State *L)
|
||||
{
|
||||
auto &matrix = check(L, 1);
|
||||
int row = read_index(L, 2);
|
||||
int col = read_index(L, 3);
|
||||
f64 value = luaL_checknumber(L, 4);
|
||||
int row = readIndex(L, 2);
|
||||
int col = readIndex(L, 3);
|
||||
f64 value = readParam<f64>(L, 4);
|
||||
matrix(row, col) = value;
|
||||
return 0;
|
||||
}
|
||||
|
@ -137,7 +136,7 @@ int LuaMatrix4::l_set(lua_State *L)
|
|||
int LuaMatrix4::l_get_row(lua_State *L)
|
||||
{
|
||||
const auto &matrix = check(L, 1);
|
||||
int row = read_index(L, 2);
|
||||
int row = readIndex(L, 2);
|
||||
for (int col = 0; col < 4; ++col)
|
||||
lua_pushnumber(L, matrix(row, col));
|
||||
return 4;
|
||||
|
@ -146,11 +145,11 @@ int LuaMatrix4::l_get_row(lua_State *L)
|
|||
int LuaMatrix4::l_set_row(lua_State *L)
|
||||
{
|
||||
auto &matrix = check(L, 1);
|
||||
int row = read_index(L, 2);
|
||||
f32 x = luaL_checknumber(L, 3);
|
||||
f32 y = luaL_checknumber(L, 4);
|
||||
f32 z = luaL_checknumber(L, 5);
|
||||
f32 w = luaL_checknumber(L, 6);
|
||||
int row = readIndex(L, 2);
|
||||
f32 x = readParam<f32>(L, 3);
|
||||
f32 y = readParam<f32>(L, 4);
|
||||
f32 z = readParam<f32>(L, 5);
|
||||
f32 w = readParam<f32>(L, 6);
|
||||
matrix(row, 0) = x;
|
||||
matrix(row, 1) = y;
|
||||
matrix(row, 2) = z;
|
||||
|
@ -161,7 +160,7 @@ int LuaMatrix4::l_set_row(lua_State *L)
|
|||
int LuaMatrix4::l_get_column(lua_State *L)
|
||||
{
|
||||
const auto &matrix = check(L, 1);
|
||||
int col = read_index(L, 2);
|
||||
int col = readIndex(L, 2);
|
||||
for (int row = 0; row < 4; ++row)
|
||||
lua_pushnumber(L, matrix(row, col));
|
||||
return 4;
|
||||
|
@ -170,11 +169,11 @@ int LuaMatrix4::l_get_column(lua_State *L)
|
|||
int LuaMatrix4::l_set_column(lua_State *L)
|
||||
{
|
||||
auto &matrix = check(L, 1);
|
||||
int col = read_index(L, 2);
|
||||
f32 x = luaL_checknumber(L, 3);
|
||||
f32 y = luaL_checknumber(L, 4);
|
||||
f32 z = luaL_checknumber(L, 5);
|
||||
f32 w = luaL_checknumber(L, 6);
|
||||
int col = readIndex(L, 2);
|
||||
f32 x = readParam<f32>(L, 3);
|
||||
f32 y = readParam<f32>(L, 4);
|
||||
f32 z = readParam<f32>(L, 5);
|
||||
f32 w = readParam<f32>(L, 6);
|
||||
matrix(0, col) = x;
|
||||
matrix(1, col) = y;
|
||||
matrix(2, col) = z;
|
||||
|
@ -205,7 +204,7 @@ int LuaMatrix4::l_transform_4d(lua_State *L)
|
|||
const auto &matrix = check(L, 1);
|
||||
f32 vec4[4];
|
||||
for (int i = 0; i < 4; ++i)
|
||||
vec4[i] = luaL_checknumber(L, i + 2);
|
||||
vec4[i] = readParam<f32>(L, i + 2);
|
||||
f32 res[4];
|
||||
matrix.transformVec4(res, vec4);
|
||||
for (int i = 0; i < 4; ++i)
|
||||
|
@ -354,12 +353,12 @@ int LuaMatrix4::mt_unm(lua_State *L)
|
|||
int LuaMatrix4::mt_mul(lua_State *L)
|
||||
{
|
||||
if (lua_isnumber(L, 1)) {
|
||||
f32 scalar = luaL_checknumber(L, 1);
|
||||
f32 scalar = readParam<f32>(L, 1);
|
||||
const auto &matrix = check(L, 2);
|
||||
create(L) = scalar * matrix;
|
||||
} else {
|
||||
const auto &matrix = check(L, 1);
|
||||
f32 scalar = luaL_checknumber(L, 2);
|
||||
f32 scalar = readParam<f32>(L, 2);
|
||||
create(L) = matrix * scalar;
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -100,6 +100,9 @@ private:
|
|||
static void *packIn(lua_State *L, int idx);
|
||||
static void packOut(lua_State *L, void *ptr);
|
||||
|
||||
template<int max = 4>
|
||||
static int readIndex(lua_State *L, int index);
|
||||
|
||||
public:
|
||||
|
||||
// Constructor. Leaves the value on top of the stack.
|
||||
|
|
|
@ -10,10 +10,9 @@
|
|||
#include "irr_v3d.h"
|
||||
#include "quaternion.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
#include <sstream>
|
||||
|
||||
core::quaternion &LuaRotation::check(lua_State *L, int index)
|
||||
{
|
||||
|
@ -38,12 +37,10 @@ int LuaRotation::l_identity(lua_State *L)
|
|||
|
||||
int LuaRotation::l_quaternion(lua_State *L)
|
||||
{
|
||||
// TODO be more strict.
|
||||
f64 x = luaL_checknumber(L, 1);
|
||||
f64 y = luaL_checknumber(L, 2);
|
||||
f64 z = luaL_checknumber(L, 3);
|
||||
f64 w = luaL_checknumber(L, 4);
|
||||
// Note: Converted to f32
|
||||
f32 x = readFiniteParam<f32>(L, 1);
|
||||
f32 y = readFiniteParam<f32>(L, 2);
|
||||
f32 z = readFiniteParam<f32>(L, 3);
|
||||
f32 w = readFiniteParam<f32>(L, 4);
|
||||
core::quaternion q(x, y, z, w);
|
||||
q.normalize();
|
||||
create(L, q);
|
||||
|
@ -53,9 +50,8 @@ int LuaRotation::l_quaternion(lua_State *L)
|
|||
int LuaRotation::l_axis_angle(lua_State *L)
|
||||
{
|
||||
v3f axis = readParam<v3f>(L, 1);
|
||||
f64 angle = luaL_checknumber(L, 2);
|
||||
f32 angle = readFiniteParam<f32>(L, 2);
|
||||
core::quaternion quaternion;
|
||||
// Note: Axis converted to f32
|
||||
axis.normalize();
|
||||
quaternion.fromAngleAxis(angle, axis);
|
||||
create(L, quaternion);
|
||||
|
@ -65,8 +61,7 @@ int LuaRotation::l_axis_angle(lua_State *L)
|
|||
template<float v3f::* C>
|
||||
int LuaRotation::l_fixed_axis_angle(lua_State *L)
|
||||
{
|
||||
f64 angle = luaL_checknumber(L, 1);
|
||||
// Note: Angle converted to f32
|
||||
f32 angle = readFiniteParam<f32>(L, 1);
|
||||
v3f axis;
|
||||
axis.*C = 1.0f;
|
||||
create(L, core::quaternion().fromAngleAxis(angle, axis));
|
||||
|
@ -77,7 +72,6 @@ int LuaRotation::l_euler_angles(lua_State *L)
|
|||
{
|
||||
v3f euler = readParam<v3f>(L, 1);
|
||||
core::quaternion quaternion;
|
||||
// Note: Euler angles converted to f32
|
||||
quaternion.set(euler.X, euler.Y, euler.Z);
|
||||
create(L, quaternion);
|
||||
return 1;
|
||||
|
@ -148,7 +142,7 @@ int LuaRotation::l_slerp(lua_State *L)
|
|||
{
|
||||
const auto &from = check(L, 1);
|
||||
const auto &to = check(L, 2);
|
||||
f32 time = readParam<Finite<f32>>(L, 3).value;
|
||||
f32 time = readFiniteParam<f32>(L, 3);
|
||||
core::quaternion result;
|
||||
result.slerp(from, to, time);
|
||||
create(L, result);
|
||||
|
@ -169,7 +163,10 @@ int LuaRotation::l_angle_to(lua_State *L)
|
|||
int LuaRotation::mt_tostring(lua_State *L)
|
||||
{
|
||||
const auto &q = check(L, 1);
|
||||
lua_pushfstring(L, "(%f\t%f\t%f\t%f)", q.X, q.Y, q.Z, q.W);
|
||||
std::stringstream ss;
|
||||
ss << q;
|
||||
std::string str = ss.str();
|
||||
lua_pushlstring(L, str.c_str(), str.size());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue