Compare commits
2 Commits
de14b6211b
...
140ca506d6
Author | SHA1 | Date |
---|---|---|
SeanOMik | 140ca506d6 | |
SeanOMik | 06a4301c23 |
|
@ -1,5 +1,3 @@
|
|||
--local win = require "scripts.window"
|
||||
|
||||
local is_window_setup = false
|
||||
|
||||
---Return the userdata's name from its metatable.
|
||||
|
@ -19,7 +17,7 @@ end
|
|||
|
||||
|
||||
function on_init()
|
||||
local cube = world:request_res("../assets/cube-texture-embedded.gltf")
|
||||
local cube = world:request_asset("../assets/cube-texture-embedded.gltf") --[[@as GltfHandle]]
|
||||
print("Loaded textured cube (" .. udname(cube) .. ")")
|
||||
|
||||
cube:wait_until_loaded()
|
||||
|
@ -35,17 +33,18 @@ end
|
|||
function on_first()
|
||||
if not is_window_setup then
|
||||
world:view(
|
||||
---@param w Window
|
||||
function (w)
|
||||
if w.cursor_grab == CursorGrabMode.NONE then
|
||||
w.cursor_grab = CursorGrabMode.LOCKED
|
||||
w.cursor_visible = false
|
||||
return w
|
||||
else
|
||||
is_window_setup = true
|
||||
print("Window setup")
|
||||
end
|
||||
end, Window)
|
||||
---@param w Window
|
||||
function (w)
|
||||
if w.cursor_grab == CursorGrabMode.NONE then
|
||||
w.cursor_grab = CursorGrabMode.LOCKED
|
||||
w.cursor_visible = false
|
||||
return w
|
||||
else
|
||||
is_window_setup = true
|
||||
print("Window setup")
|
||||
end
|
||||
end, Window
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -70,10 +69,13 @@ function on_update()
|
|||
---@type number
|
||||
local dt = world:resource(DeltaTime)
|
||||
|
||||
world:view(function (t)
|
||||
t:translate(0, 0.15 * dt, 0)
|
||||
return t
|
||||
end, Transform)
|
||||
world:view(
|
||||
---@param t Transform
|
||||
function (t)
|
||||
t:translate(0, 0.15 * dt, 0)
|
||||
return t
|
||||
end, Transform
|
||||
)
|
||||
end
|
||||
|
||||
--[[ function on_post_update()
|
||||
|
|
|
@ -358,66 +358,61 @@ impl ActionHandler {
|
|||
|
||||
/// Returns true if the action is pressed (or was just pressed).
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
pub fn is_action_pressed<L>(&self, action: L) -> bool
|
||||
/// Returns `None` if the action was not found.
|
||||
pub fn is_action_pressed<L>(&self, action: L) -> Option<bool>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
matches!(action.state, ActionState::Pressed(_) | ActionState::JustPressed(_))
|
||||
Some(matches!(action.state, ActionState::Pressed(_) | ActionState::JustPressed(_)))
|
||||
}
|
||||
|
||||
/// Returns true if the action was just pressed.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
pub fn was_action_just_pressed<L>(&self, action: L) -> bool
|
||||
/// Returns `None` if the action was not found.
|
||||
pub fn was_action_just_pressed<L>(&self, action: L) -> Option<bool>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
matches!(action.state, ActionState::JustPressed(_))
|
||||
Some(matches!(action.state, ActionState::JustPressed(_)))
|
||||
}
|
||||
|
||||
/// Returns true if the action was just released.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
pub fn was_action_just_released<L>(&self, action: L) -> bool
|
||||
/// Returns `None` if the action was not found.
|
||||
pub fn was_action_just_released<L>(&self, action: L) -> Option<bool>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
matches!(action.state, ActionState::JustReleased)
|
||||
Some(matches!(action.state, ActionState::JustReleased))
|
||||
}
|
||||
|
||||
/// Returns an action's state.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
pub fn get_action_state<L>(&self, action: L) -> ActionState
|
||||
/// Returns `None` if the action was not found.
|
||||
pub fn get_action_state<L>(&self, action: L) -> Option<ActionState>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
action.state
|
||||
Some(action.state)
|
||||
}
|
||||
|
||||
/// Returns the action's modifier if it is pressed (or was just pressed).
|
||||
/// Returns `None` if the action's state is not `ActionState::Pressed` or `ActionState::JustPressed`.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
/// Returns `None` if the action's state is not `ActionState::Pressed`, `ActionState::JustPressed`,
|
||||
/// or if the action was not found.
|
||||
pub fn get_pressed_modifier<L>(&self, action: L) -> Option<f32>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
match action.state {
|
||||
ActionState::Pressed(v) | ActionState::JustPressed(v) => Some(v),
|
||||
|
@ -426,15 +421,14 @@ impl ActionHandler {
|
|||
}
|
||||
|
||||
/// Returns the action's modifier if it was just pressed.
|
||||
/// Returns `None` if the action's state is not `ActionState::JustPressed`.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
/// Returns `None` if the action's state is not `ActionState::JustPressed`,
|
||||
/// or if the action was not found.
|
||||
pub fn get_just_pressed_modifier<L>(&self, action: L) -> Option<f32>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
match action.state {
|
||||
ActionState::JustPressed(v) => Some(v),
|
||||
|
@ -443,15 +437,14 @@ impl ActionHandler {
|
|||
}
|
||||
|
||||
/// Returns the action's modifier if its an updated axis.
|
||||
/// Returns `None` if the action's state is not `ActionState::Axis`.
|
||||
///
|
||||
/// This will panic if the action name does not correspond to an action.
|
||||
/// Returns `None` if the action's state is not `ActionState::Axis`,
|
||||
/// or if the action was not found.
|
||||
pub fn get_axis_modifier<L>(&self, action: L) -> Option<f32>
|
||||
where
|
||||
L: ActionLabel
|
||||
{
|
||||
let action = self.actions.get(&action.label_hash())
|
||||
.unwrap_or_else(|| panic!("Action {action:?} was not found"));
|
||||
let action = self.actions.get(&action.label_hash())?;
|
||||
|
||||
match action.state {
|
||||
ActionState::Axis(v) => Some(v),
|
||||
|
|
|
@ -28,10 +28,6 @@ impl Default for Transform {
|
|||
|
||||
// TODO: https://www.brainvoyager.com/bv/doc/UsersGuide/CoordsAndTransforms/SpatialTransformationMatrices.html
|
||||
|
||||
#[allow(dead_code)]
|
||||
const ZERO_V3: Vec3 = Vec3::new(0.0, 0.0, 0.0);
|
||||
const ONE_V3: Vec3 = Vec3::new(1.0, 1.0, 1.0);
|
||||
|
||||
#[allow(dead_code)]
|
||||
impl Transform {
|
||||
pub fn new(translation: Vec3, rotation: Quat, scale: Vec3) -> Self {
|
||||
|
@ -43,33 +39,42 @@ impl Transform {
|
|||
}
|
||||
|
||||
pub fn from_translation(translation: Vec3) -> Self {
|
||||
Self::new(translation, Quat::IDENTITY, ONE_V3)
|
||||
Self::new(translation, Quat::IDENTITY, Vec3::ONE)
|
||||
}
|
||||
|
||||
pub fn from_xyz(x: f32, y: f32, z: f32) -> Self {
|
||||
Self::new(Vec3::new(x, y, z), Quat::IDENTITY, ONE_V3)
|
||||
Self::new(Vec3::new(x, y, z), Quat::IDENTITY, Vec3::ONE)
|
||||
}
|
||||
|
||||
pub fn calculate_mat4(&self) -> Mat4 {
|
||||
Mat4::from_scale_rotation_translation(self.scale, self.rotation, self.translation)
|
||||
}
|
||||
|
||||
/// Get the forward vector of the Transform.
|
||||
/// Returns a normalized vector pointing in the direction the Transform is facing.
|
||||
///
|
||||
/// This represents the front of the object can be used for movement, camera orientation, and
|
||||
/// other directional calculations.
|
||||
pub fn forward(&self) -> Vec3 {
|
||||
(self.rotation * -Vec3::Z).normalize()
|
||||
}
|
||||
|
||||
/// Get the left vector of the Transform.
|
||||
/// Returns a normalized vector pointing to the left side of the Transform.
|
||||
///
|
||||
/// The vector is in local space. This represents the direction that is
|
||||
/// perpendicular to the object's forward direction.
|
||||
pub fn left(&self) -> Vec3 {
|
||||
(self.rotation * Vec3::X).normalize()
|
||||
}
|
||||
|
||||
/// Get the up vector of the Transform.
|
||||
/// Returns a normalized vector that indicates the upward direction of the Transform.
|
||||
///
|
||||
/// This vector is commonly used to define an object's orientation and is essential for maintaining
|
||||
/// consistent vertical alignment in 3D environments, such as for camera positioning and object alignment.
|
||||
pub fn up(&self) -> Vec3 {
|
||||
(self.rotation * Vec3::Y).normalize()
|
||||
}
|
||||
|
||||
/// Rotate this transform using a Quaternion
|
||||
/// Rotate this transform using a Quaternion.
|
||||
pub fn rotate(&mut self, rotation: Quat) {
|
||||
self.rotation = (rotation * self.rotation).normalize();
|
||||
}
|
||||
|
@ -110,7 +115,7 @@ impl Transform {
|
|||
let mut res = *self;
|
||||
res.translation = self.translation.lerp(rhs.translation, alpha);
|
||||
// normalize rotation here to avoid panics
|
||||
res.rotation = self.rotation.lerp(rhs.rotation.normalize(), alpha);
|
||||
res.rotation = self.rotation.normalize().lerp(rhs.rotation.normalize(), alpha);
|
||||
res.scale = self.scale.lerp(rhs.scale, alpha);
|
||||
res
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
---@enum ActionState
|
||||
ActionState = {
|
||||
IDLE = "idle",
|
||||
PRESSED = "pressed",
|
||||
JUST_PRESSED = "just_pressed",
|
||||
JUST_RELEASED = "just_released",
|
||||
AXIS = "axis",
|
||||
OTHER = "other",
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
---@enum HandleState
|
||||
HandleState = {
|
||||
LOADING = "loading",
|
||||
READY = "ready",
|
||||
ERROR = "error",
|
||||
}
|
||||
|
||||
---@enum ActionKind
|
||||
ActionKind = {
|
||||
BUTTON = "button",
|
||||
AXIS = "axis",
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
---@class Quat
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
---@field w number
|
||||
Quat = { x = 0.0, y = 0.0, z = 0.0, w = 0.0 }
|
||||
Quat.__index = Quat
|
||||
Quat.__name = "Quat"
|
||||
|
||||
--- Constructs a new Quaternion from x, y, z, and w.
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@param w number
|
||||
---@return Quat
|
||||
function Quat:new(x, y, z, w)
|
||||
local q = {}
|
||||
setmetatable(q, Quat)
|
||||
|
||||
q.x = x
|
||||
q.y = y
|
||||
q.z = z
|
||||
q.w = w
|
||||
|
||||
return q
|
||||
end
|
||||
|
||||
Quat.IDENTITY = Quat:new(0, 0, 0, 1)
|
||||
|
||||
function Quat:clone()
|
||||
return Quat:new(self.x, self.y, self.z, self.w)
|
||||
end
|
||||
|
||||
--- Creates a quaternion from the angle, in radians, around the x axis.
|
||||
--- @param rad number
|
||||
--- @return Quat
|
||||
function Quat:from_rotation_x(rad)
|
||||
local sin = math.sin(rad * 0.5)
|
||||
local cos = math.cos(rad * 0.5)
|
||||
return Quat:new(sin, 0, 0, cos)
|
||||
end
|
||||
|
||||
--- Creates a quaternion from the angle, in radians, around the y axis.
|
||||
--- @param rad number
|
||||
--- @return Quat
|
||||
function Quat:from_rotation_y(rad)
|
||||
local sin = math.sin(rad * 0.5)
|
||||
local cos = math.cos(rad * 0.5)
|
||||
return Quat:new(0, sin, 0, cos)
|
||||
end
|
||||
|
||||
--- Creates a quaternion from the angle, in radians, around the z axis.
|
||||
--- @param rad number
|
||||
--- @return Quat
|
||||
function Quat:from_rotation_z(rad)
|
||||
local sin = math.sin(rad * 0.5)
|
||||
local cos = math.cos(rad * 0.5)
|
||||
return Quat:new(0, 0, sin, cos)
|
||||
end
|
||||
|
||||
--- Computes the dot product of `self`.
|
||||
---@param rhs Quat
|
||||
---@return number
|
||||
function Quat:dot(rhs)
|
||||
return (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z) + (self.w * rhs.w)
|
||||
end
|
||||
|
||||
--- Computes the length of `self`.
|
||||
---@return number
|
||||
function Quat:length()
|
||||
return math.sqrt(self:dot(self))
|
||||
end
|
||||
|
||||
--- Compute the length of `self` squared.
|
||||
---@return number
|
||||
function Quat:length_squared()
|
||||
return self:length() ^ 2
|
||||
end
|
||||
|
||||
--- Normalizes `self` and returns the new Quat
|
||||
---@return unknown
|
||||
function Quat:normalize()
|
||||
local length = self:length()
|
||||
return self / length
|
||||
end
|
||||
|
||||
--- Multiplies two Quaternions together. Keep in mind that Quaternion multiplication is NOT
|
||||
--- commutative so the order in which you multiply the quaternions matters.
|
||||
---@param rhs Quat
|
||||
---@return Quat
|
||||
function Quat:mult_quat(rhs)
|
||||
local x1, y1, z1, w1 = self.x, self.y, self.z, self.w
|
||||
local x2, y2, z2, w2 = rhs.x, rhs.y, rhs.z, rhs.w
|
||||
|
||||
local x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2
|
||||
local y = w1 * y2 - x1 * z2 + y1 * w2 + z1 * x2
|
||||
local z = w1 * z2 + x1 * y2 - y1 * x2 + z1 * w2
|
||||
local w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * x2
|
||||
|
||||
return Quat:new(x, y, z, w)
|
||||
end
|
||||
|
||||
--- Multiplies `self` by a Vec3, returning the rotated Vec3
|
||||
---@param vec Vec3
|
||||
---@return Vec3
|
||||
function Quat:mult_vec3(vec)
|
||||
local vec_quat = Quat:new(vec.x, vec.y, vec.z, 0)
|
||||
local quat = self:mult_quat(vec_quat)
|
||||
return Vec3:new(quat.x, quat.y, quat.z)
|
||||
end
|
||||
|
||||
--- Calculates the linear iterpolation between `self` and `rhs` based on the `alpha`.
|
||||
--- When `alpha` is `0`, the result will be equal to `self`. When `s` is `1`, the result
|
||||
--- will be equal to `rhs`
|
||||
--- @param rhs Quat
|
||||
--- @param alpha number
|
||||
--- @return Quat
|
||||
function Quat:lerp(rhs, alpha)
|
||||
-- ensure alpha is [0, 1]
|
||||
local alpha = math.max(0, math.min(1, alpha))
|
||||
|
||||
local x1, y1, z1, w1 = self.x, self.y, self.z, self.w
|
||||
local x2, y2, z2, w2 = rhs.x, rhs.y, rhs.z, rhs.w
|
||||
|
||||
local x = (1 - alpha) * x1 + alpha * x2
|
||||
local y = (1 - alpha) * y1 + alpha * y2
|
||||
local z = (1 - alpha) * z1 + alpha * z2
|
||||
local w = (1 - alpha) * w1 + alpha * w2
|
||||
|
||||
return Quat:new(x, y, z, w):normalize()
|
||||
end
|
||||
|
||||
function Quat:__add(rhs)
|
||||
return Quat:new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z, self.w + rhs.w)
|
||||
end
|
||||
|
||||
function Quat:__sub(rhs)
|
||||
return Quat:new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z, self.w - rhs.w)
|
||||
end
|
||||
|
||||
function Quat:__mul(rhs)
|
||||
if type(rhs) == "number" then
|
||||
return Quat:new(self.x * rhs, self.y * rhs, self.z * rhs, self.w * rhs)
|
||||
elseif type(rhs) == "table" then
|
||||
local name = rhs.__name
|
||||
|
||||
if name == "Vec3" then
|
||||
return self:mult_vec3(rhs)
|
||||
elseif name == "Quat" then
|
||||
return self:mult_quat(rhs)
|
||||
else
|
||||
assert(false, "Unknown usertype of rhs" .. name)
|
||||
end
|
||||
else
|
||||
assert(false, "Unknown type of rhs" .. type(rhs))
|
||||
end
|
||||
end
|
||||
|
||||
function Quat:__div(rhs)
|
||||
if type(rhs) == "number" then
|
||||
return Quat:new(self.x / rhs, self.y / rhs, self.z / rhs, self.w / rhs)
|
||||
else
|
||||
assert(rhs.__name == "Quat", "Attempted to divide Quat by unknown type " .. rhs.__name)
|
||||
return Quat:new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z, self.w / rhs.w)
|
||||
end
|
||||
end
|
||||
|
||||
function Quat:__eq(rhs)
|
||||
return self.x == rhs.x and self.y == rhs.y and self.z == rhs.z and self.w == rhs.w
|
||||
end
|
||||
|
||||
function Quat:__lt(rhs)
|
||||
return self.x < rhs.x and self.y < rhs.y and self.z < rhs.z and self.w < rhs.w
|
||||
end
|
||||
|
||||
function Quat:__le(rhs)
|
||||
return self.x <= rhs.x and self.y <= rhs.y and self.z <= rhs.z and self.w <= rhs.w
|
||||
end
|
||||
|
||||
function Quat:__tostring()
|
||||
return "Quat(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ", " .. self.w .. ")"
|
||||
end
|
|
@ -1,95 +0,0 @@
|
|||
---@class Transform
|
||||
---@field translation Vec3
|
||||
---@field rotation Quat
|
||||
---@field Scale Vec3
|
||||
Transform = { translation = Vec3.ZERO, rotation = Quat.IDENTITY, scale = Vec3.ONE }
|
||||
Transform.__index = Transform
|
||||
Transform.__name = "Transform"
|
||||
|
||||
function Transform:new(translation, rotation, scale)
|
||||
local t = {}
|
||||
setmetatable(t, Transform)
|
||||
|
||||
t.translation = translation
|
||||
t.rotation = rotation
|
||||
t.scale = scale
|
||||
|
||||
return t
|
||||
end
|
||||
|
||||
function Transform:clone()
|
||||
return Transform:new(self.translation:clone(), self.rotation:clone(), self.scale:clone())
|
||||
end
|
||||
|
||||
--- Creates a new Transform with the translation at the vec3
|
||||
--- @param pos Vec3
|
||||
function Transform:from_vec3(pos)
|
||||
local t = Transform:clone() -- copy of default transform
|
||||
t.translation = pos
|
||||
return t
|
||||
end
|
||||
|
||||
function Transform:from_xyz(x, y, z)
|
||||
Transform:from_vec3(Vec3:new(x, y, z))
|
||||
end
|
||||
|
||||
--- Calculates the forward vector of the Transform.
|
||||
--- @return Vec3
|
||||
function Transform:forward()
|
||||
return (self.rotation * Vec3.NEG_Z):normalize()
|
||||
end
|
||||
|
||||
--- Calculates the left vector of the Transform.
|
||||
--- @return Vec3
|
||||
function Transform:left()
|
||||
return (self.rotation * Vec3.X):normalize()
|
||||
end
|
||||
|
||||
--- Calculates the up vector of the Transform.
|
||||
--- @return Vec3
|
||||
function Transform:up()
|
||||
return (self.rotation * Vec3.Y):normalize()
|
||||
end
|
||||
|
||||
--- Rotates `self` using a Quaternion
|
||||
--- @param quat Quat
|
||||
function Transform:rotate(quat)
|
||||
self.rotation = (quat * self.rotation):normalize()
|
||||
end
|
||||
|
||||
--- Rotates `self` around the x-axis
|
||||
--- @param rad number
|
||||
function Transform:rotate_x(rad)
|
||||
self:rotate(Quat:from_rotation_x(rad))
|
||||
end
|
||||
|
||||
--- Rotates `self` around the y-axis
|
||||
--- @param rad number
|
||||
function Transform:rotate_y(rad)
|
||||
self:rotate(Quat:from_rotation_y(rad))
|
||||
end
|
||||
|
||||
--- Rotates `self` around the z-axis
|
||||
--- @param rad number
|
||||
function Transform:rotate_z(rad)
|
||||
self:rotate(Quat:from_rotation_z(rad))
|
||||
end
|
||||
|
||||
--- Calculates the linear iterpolation between `self` and `rhs` based on the `alpha`.
|
||||
--- When `alpha` is `0`, the result will be equal to `self`. When `s` is `1`, the result
|
||||
--- will be equal to `rhs`
|
||||
--- @param rhs Transform
|
||||
--- @param alpha number
|
||||
--- @return Transform
|
||||
function Transform:lerp(rhs, alpha)
|
||||
local res = self:clone()
|
||||
res.translation = self.translation:lerp(rhs.translation, alpha)
|
||||
res.rotation = self.rotation:lerp(rhs.rotation, alpha)
|
||||
res.scale = self.scale:lerp(rhs.scale, alpha)
|
||||
return res
|
||||
end
|
||||
|
||||
function Transform:__tostring()
|
||||
return "Transform(pos=" .. tostring(self.translation) .. ", rot="
|
||||
.. tostring(self.rotation) .. ", scale=" .. tostring(self.scale) .. ")"
|
||||
end
|
|
@ -1,187 +0,0 @@
|
|||
---@class Vec3
|
||||
---@field x number
|
||||
---@field y number
|
||||
---@field z number
|
||||
Vec3 = { x = 0.0, y = 0.0, z = 0.0 }
|
||||
Vec3.__index = Vec3
|
||||
Vec3.__name = "Vec3"
|
||||
|
||||
--- Constructs a new vector
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@return Vec3
|
||||
function Vec3:new(x, y, z)
|
||||
local v = {}
|
||||
setmetatable(v, Vec3)
|
||||
|
||||
v.x = x
|
||||
v.y = y
|
||||
v.z = z
|
||||
|
||||
return v
|
||||
end
|
||||
|
||||
---Creates a copy of self
|
||||
---@return Vec3
|
||||
function Vec3:clone()
|
||||
return Vec3:new(self.x, self.y, self.z)
|
||||
end
|
||||
|
||||
--- Constructs a vector with all elements as parameter `x`.
|
||||
---@param x number
|
||||
---@return Vec3
|
||||
function Vec3:all(x)
|
||||
return Vec3:new(x, x, x)
|
||||
end
|
||||
|
||||
--- A unit-length vector pointing alongside the positive X axis.
|
||||
Vec3.X = Vec3:new(1, 0, 0)
|
||||
--- A unit-length vector pointing alongside the positive Y axis.
|
||||
Vec3.Y = Vec3:new(0, 1, 0)
|
||||
--- A unit-length vector pointing alongside the positive Z axis.
|
||||
Vec3.Z = Vec3:new(0, 0, 1)
|
||||
|
||||
--- A unit-length vector pointing alongside the negative X axis.
|
||||
Vec3.NEG_X = Vec3:new(-1, 0, 0)
|
||||
--- A unit-length vector pointing alongside the negative Y axis.
|
||||
Vec3.NEG_Y = Vec3:new(0, -1, 0)
|
||||
--- A unit-length vector pointing alongside the negative Z axis.
|
||||
Vec3.NEG_Z = Vec3:new(0, 0, -1)
|
||||
|
||||
--- A vector of all zeros
|
||||
Vec3.ZERO = Vec3:new(0, 0, 0)
|
||||
--- A vector of all ones
|
||||
Vec3.ONE = Vec3:new(1, 1, 1)
|
||||
|
||||
--- Computes the absolute value of `self`.
|
||||
function Vec3:abs()
|
||||
self.x = math.abs(self.x)
|
||||
self.y = math.abs(self.y)
|
||||
self.z = math.abs(self.z)
|
||||
end
|
||||
|
||||
--- Computes the length of `self`.
|
||||
---@return number
|
||||
function Vec3:length()
|
||||
return math.sqrt(self:dot(self))
|
||||
end
|
||||
|
||||
---Moves `self` by the provided coordinates
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
function Vec3:move_by(x, y, z)
|
||||
self.x = self.x + x
|
||||
self.y = self.y + y
|
||||
self.z = self.z + z
|
||||
end
|
||||
|
||||
--- Computes the dot product of `self` and `rhs`.
|
||||
---@param rhs Vec3
|
||||
---@return number
|
||||
function Vec3:dot(rhs)
|
||||
assert(rhs.__name == "Vec3")
|
||||
|
||||
return (self.x * rhs.x) + (self.y * rhs.y) + (self.z * rhs.z)
|
||||
end
|
||||
|
||||
--- Returns a vector that has the minimum value of each element of `self` and `rhs`
|
||||
---@param rhs Vec3
|
||||
---@return Vec3
|
||||
function Vec3:min(rhs)
|
||||
local x = math.min(self.x, rhs.x)
|
||||
local y = math.min(self.y, rhs.y)
|
||||
local z = math.min(self.z, rhs.z)
|
||||
|
||||
return Vec3:new(x, y, z)
|
||||
end
|
||||
|
||||
--- Modifies `self` to be normalized to a length 1.
|
||||
function Vec3:normalize()
|
||||
local len_recip = 1.0 / self:length()
|
||||
self.x = self.x * len_recip
|
||||
self.y = self.y * len_recip
|
||||
self.z = self.z * len_recip
|
||||
end
|
||||
|
||||
--- Calculates the linear iterpolation between `self` and `rhs` based on the `alpha`.
|
||||
--- When `alpha` is `0`, the result will be equal to `self`. When `s` is `1`, the result
|
||||
--- will be equal to `rhs`
|
||||
--- @param rhs Vec3
|
||||
--- @param alpha number
|
||||
--- @return Vec3
|
||||
function Vec3:lerp(rhs, alpha)
|
||||
-- ensure alpha is [0, 1]
|
||||
local alpha = math.max(0, math.min(1, alpha))
|
||||
|
||||
local res = self:clone()
|
||||
res = res + ((rhs - res) * alpha)
|
||||
return res
|
||||
end
|
||||
|
||||
function Vec3:__add(rhs)
|
||||
if type(rhs) == "Vec3" then
|
||||
return Vec3:new(self.x + rhs.x, self.y + rhs.y, self.z + rhs.z)
|
||||
else
|
||||
return Vec3:new(self.x + rhs, self.y + rhs, self.z + rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__sub(rhs)
|
||||
if type(rhs) == "Vec3" then
|
||||
return Vec3:new(self.x - rhs.x, self.y - rhs.y, self.z - rhs.z)
|
||||
else
|
||||
return Vec3:new(self.x - rhs, self.y - rhs, self.z - rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__mul(rhs)
|
||||
if type(rhs) == "Vec3" then
|
||||
return Vec3:new(self.x * rhs.x, self.y * rhs.y, self.z * rhs.z)
|
||||
else
|
||||
return Vec3:new(self.x * rhs, self.y * rhs, self.z * rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__div(rhs)
|
||||
if type(rhs) == "Vec3" then
|
||||
return Vec3:new(self.x / rhs.x, self.y / rhs.y, self.z / rhs.z)
|
||||
else
|
||||
return Vec3:new(self.x / rhs, self.y / rhs, self.z / rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__idiv(rhs)
|
||||
if type(rhs) == "Vec3" then
|
||||
return Vec3:new(self.x // rhs.x, self.y // rhs.y, self.z // rhs.z)
|
||||
else
|
||||
return Vec3:new(self.x // rhs, self.y // rhs, self.z // rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__unm()
|
||||
return Vec3:new(-self.x, -self.y, -self.z)
|
||||
end
|
||||
|
||||
function Vec3:__pow(rhs)
|
||||
if type(rhs) == "number" then
|
||||
return Vec3:new(self.x ^ rhs, self.y ^ rhs, self.z ^ rhs)
|
||||
end
|
||||
end
|
||||
|
||||
function Vec3:__eq(rhs)
|
||||
return self.x == rhs.x and self.y == rhs.y and self.z == rhs.z
|
||||
end
|
||||
|
||||
function Vec3:__lt(rhs)
|
||||
return self.x < rhs.x and self.y < rhs.y and self.z < rhs.z
|
||||
end
|
||||
|
||||
function Vec3:__le(rhs)
|
||||
return self.x <= rhs.x and self.y <= rhs.y and self.z <= rhs.z
|
||||
end
|
||||
|
||||
function Vec3:__tostring()
|
||||
return "Vec3(" .. self.x .. ", " .. self.y .. ", " .. self.z .. ")"
|
||||
end
|
|
@ -0,0 +1,23 @@
|
|||
---@meta
|
||||
|
||||
---@class GltfHandle: Handle
|
||||
---
|
||||
---A handle to a GLTF asset.
|
||||
GltfHandle = {
|
||||
|
||||
}
|
||||
|
||||
---Get a list of scenes in the GLTF file.
|
||||
---
|
||||
---@return SceneHandle[]
|
||||
function GltfHandle:scenes() end
|
||||
|
||||
---Get a list of materials in the GLTF file.
|
||||
---
|
||||
---@return MaterialHandle[]
|
||||
function GltfHandle:materials() end
|
||||
|
||||
---Get a list of meshes in the GLTF file.
|
||||
---
|
||||
---@return MeshHandle[]
|
||||
function GltfHandle:meshes() end
|
|
@ -0,0 +1,43 @@
|
|||
---@meta
|
||||
|
||||
---@class Handle: userdata
|
||||
---
|
||||
---A handle to an asset. Assets are loaded asynchronously, so you cannot immediately
|
||||
---use them after you request them from the World.
|
||||
Handle = {
|
||||
---The path the asset was loaded from.
|
||||
---
|
||||
---@type string
|
||||
path = nil,
|
||||
|
||||
---The version of the resource.
|
||||
---
|
||||
---Increments every time a resource is loaded.
|
||||
---
|
||||
---@type number
|
||||
version = nil,
|
||||
|
||||
---The unique id of the resource.
|
||||
---
|
||||
---This is not changed for the entire lifetime of the handle, it does not change
|
||||
---when an asset is reloaded.
|
||||
---
|
||||
---@type string
|
||||
uuid = nil,
|
||||
|
||||
---Current state of the asset handle.
|
||||
---@type HandleState
|
||||
state = nil,
|
||||
}
|
||||
|
||||
---Returns true if the asset is watched for auto-reloading.
|
||||
---
|
||||
---@return boolean
|
||||
function Handle:is_watched() end
|
||||
|
||||
---Returns true if the asset is loaded.
|
||||
---@return boolean
|
||||
function Handle:is_loaded() end
|
||||
|
||||
---Blocks execution until the asset and its dependencies are loaded.
|
||||
function Handle:wait_until_loaded() end
|
|
@ -0,0 +1,102 @@
|
|||
---@meta
|
||||
|
||||
---@class MaterialHandle: Handle
|
||||
---
|
||||
---A handle to a material asset in a GLTF file.
|
||||
MaterialHandle = {
|
||||
---The unique id of the GPU shader.
|
||||
---@type number?
|
||||
shader_uuid = nil,
|
||||
|
||||
---The name of the material from GLTF.
|
||||
---@type string?
|
||||
name = nil,
|
||||
|
||||
---@type boolean
|
||||
double_sided = nil,
|
||||
|
||||
---The RGBA base color of the model.
|
||||
---
|
||||
---If a texture is supplied with `base_color_texture`, this value will tint the
|
||||
---texture. If a texture is not provided, this value would be the color of
|
||||
---the Material.
|
||||
---
|
||||
---@type Vec4
|
||||
base_color = nil,
|
||||
|
||||
---The metalness of the material
|
||||
---
|
||||
---From 0.0 (non-metal) to 1.0 (metal).
|
||||
---
|
||||
---@type number
|
||||
metallic = nil,
|
||||
|
||||
---The roughness of the material
|
||||
---
|
||||
---From 0.0 (smooth) to 1.0 (rough)
|
||||
---
|
||||
---@type number
|
||||
roughness = nil,
|
||||
|
||||
---The base color texture of the model.
|
||||
---@type TextureHandle?
|
||||
base_color_texture = nil,
|
||||
|
||||
---The metallic-roughness texture.
|
||||
---
|
||||
---The metalness values are sampled from the B channel. The roughness values are sampled from
|
||||
---the G channel. These values are linear. If other channels are present (R or A), they are
|
||||
---ignored for metallic-roughness calculations.
|
||||
---@type TextureHandle?
|
||||
metallic_roughness_texture = nil,
|
||||
|
||||
---A set of parameter values that are used to define the specular-glossiness material model
|
||||
---from Physically-Based Rendering (PBR) methodology.
|
||||
---GLTF extension: [KHR_materials_pbrSpecularGlossiness](https://kcoley.github.io/glTF/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness)
|
||||
---@type TextureHandle?
|
||||
pbr_glossiness = nil,
|
||||
|
||||
---The optional alpha cutoff value of the material.
|
||||
---
|
||||
---This will be used instead of the renderer's default.
|
||||
---
|
||||
---@type number?
|
||||
alpha_cutoff = nil,
|
||||
|
||||
---The alpha rendering mode of the material.
|
||||
---
|
||||
---The material's alpha rendering
|
||||
---mode enumeration specifying the interpretation of the alpha value of the main
|
||||
---factor and texture.
|
||||
---
|
||||
---* In `Opaque` mode (default) the alpha value is ignored
|
||||
--- and the rendered output is fully opaque.
|
||||
---* In `Mask` mode, the rendered
|
||||
--- output is either fully opaque or fully transparent depending on the alpha
|
||||
--- value and the specified alpha cutoff value.
|
||||
---* In `Blend` mode, the alpha value is used to composite the source and
|
||||
--- destination areas and the rendered output is combined with the background
|
||||
--- using the normal painting operation (i.e. the Porter and Duff over
|
||||
--- operator).
|
||||
---
|
||||
---@type AlphaMode
|
||||
alpha_mode = nil,
|
||||
|
||||
---@type Specular?
|
||||
specular = nil,
|
||||
}
|
||||
|
||||
---@enum AlphaMode
|
||||
AlphaMode = {
|
||||
OPAQUE = "opaque",
|
||||
MASK = "mask",
|
||||
BLEND = "blend",
|
||||
}
|
||||
|
||||
---@class PbrGlossiness
|
||||
---TODO: implement
|
||||
PbrGlossiness = {}
|
||||
|
||||
---@class Specular
|
||||
---TODO: implement
|
||||
Specular = {}
|
|
@ -0,0 +1,14 @@
|
|||
---@meta
|
||||
|
||||
---@class MeshHandle: Handle
|
||||
---
|
||||
---A handle to a mesh in a GLTF file.
|
||||
MeshHandle = {
|
||||
---The material of the mesh
|
||||
---@type MaterialHandle
|
||||
material = nil,
|
||||
}
|
||||
|
||||
---Get the indices in the mesh.
|
||||
---@return number[]
|
||||
function MeshHandle:indices() end
|
|
@ -0,0 +1,9 @@
|
|||
---@meta
|
||||
|
||||
---@class SceneHandle: Handle
|
||||
---
|
||||
---A handle to a scene asset in a GLTF file.
|
||||
SceneHandle = {
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
---@meta
|
||||
|
||||
---@class TextureHandle
|
||||
TextureHandle = {}
|
|
@ -0,0 +1,125 @@
|
|||
---@meta
|
||||
|
||||
---@class ActionHandler: userdata
|
||||
ActionHandler = {}
|
||||
|
||||
--- Create a new `ActionHandler`.
|
||||
---
|
||||
--- ```lua
|
||||
--- local handler = ActionHandler.new {
|
||||
--- -- A list of layout IDs
|
||||
--- layouts = { 0 },
|
||||
--- actions = {
|
||||
--- -- A list of action names and the `ActionKind`s.
|
||||
--- -- Actions can be buttons or axes.
|
||||
--- MoveForwardBackward = ActionKind.AXIS,
|
||||
--- MoveLeftRight = ActionKind.AXIS,
|
||||
--- MoveUpDown = ActionKind.AXIS,
|
||||
--- LookLeftRight = ActionKind.AXIS,
|
||||
--- LookUpDown = ActionKind.AXIS,
|
||||
--- LookRoll = ActionKind.AXIS,
|
||||
--- ObjectsMoveUpDown = ActionKind.AXIS
|
||||
--- },
|
||||
--- mappings = {
|
||||
--- -- Each entry here is a mapping of actions for a layout.
|
||||
--- -- This can be used so that when the current layout is changed,
|
||||
--- -- the mapping would also change.
|
||||
--- {
|
||||
--- -- Specify the layout id that this mapping is for.
|
||||
--- layout = 0,
|
||||
--- binds = {
|
||||
--- -- This is an Action bind. A bind is used to bind an input to an action.
|
||||
--- -- These actions are defined above in "actions".
|
||||
--- MoveForwardBackward = {
|
||||
--- -- This is how you bind a button. In this case the button is a key.
|
||||
--- -- "key" is the device the bind comes from, then after the colon is the
|
||||
--- -- input name, in this case a specific key. We specify a modifier to the bind
|
||||
--- -- after the equal sign.
|
||||
--- "key:w=1.0",
|
||||
--- "key:s=-1.0"
|
||||
--- },
|
||||
--- MoveLeftRight = {
|
||||
--- "key:a=-1.0", "key:d=1.0"
|
||||
--- },
|
||||
--- MoveUpDown = {
|
||||
--- "key:c=1.0", "key:z=-1.0"
|
||||
--- },
|
||||
--- LookLeftRight = {
|
||||
--- "key:left=-1.0", "key:right=1.0",
|
||||
--- -- Here is a bind to an axis.
|
||||
--- -- We use "mouse", for the device the bind is from, then "axis" to specify
|
||||
--- -- that we want to bind a specific axis, then we use the name of the axis,
|
||||
--- -- in this case "x".
|
||||
--- -- So this binds to the x axis of the mouse.
|
||||
--- "mouse:axis:x"
|
||||
--- },
|
||||
--- LookUpDown = {
|
||||
--- "key:up=-1.0", "key:down=1.0",
|
||||
--- -- Here we bind to the y axis of the mouse.
|
||||
--- "mouse:axis:y",
|
||||
--- },
|
||||
--- LookRoll = {
|
||||
--- "key:e=-1.0", "key:q=1.0",
|
||||
--- },
|
||||
--- ObjectsMoveUpDown = {
|
||||
--- "key:u=1.0", "key:j=-1.0"
|
||||
--- }
|
||||
--- }
|
||||
--- }
|
||||
--- }
|
||||
--- }
|
||||
---
|
||||
--- -- Add the handler to the world so the host will process it.
|
||||
--- world:add_resource(handler)
|
||||
--- ```
|
||||
---
|
||||
---@param table table See above example to see the format of this table.
|
||||
function ActionHandler.new(table) end
|
||||
|
||||
---Returns the action's modifier if its an updated axis.
|
||||
---
|
||||
---Returns `nil` if the action's state is not `ActionState::Axis`, or if the
|
||||
---action was not found.
|
||||
---@param action string
|
||||
---@return number?
|
||||
function ActionHandler:get_axis(action) end
|
||||
|
||||
---Returns true if the action is pressed (or was just pressed).
|
||||
---
|
||||
---Returns `nil` if the action's was not found.
|
||||
---@param action string
|
||||
---@return boolean?
|
||||
function ActionHandler:is_pressed(action) end
|
||||
|
||||
---Returns true if the action was **just** pressed.
|
||||
---
|
||||
---Returns `nil` if the action was not found
|
||||
---
|
||||
---@param action string
|
||||
---@return boolean?
|
||||
function ActionHandler:was_just_pressed(action) end
|
||||
|
||||
---Returns true if the action was just released.
|
||||
---
|
||||
---Returns `nil` if the action was not found
|
||||
---
|
||||
---@param action string
|
||||
---@return boolean?
|
||||
function ActionHandler:was_just_released(action) end
|
||||
|
||||
---Returns the action's modifier if it was just pressed.
|
||||
---
|
||||
---Returns `nil` if the action's state is not `ActionState.JUST_PRESSED`,
|
||||
---or if the action was not found.
|
||||
---
|
||||
---@param action string
|
||||
---@return number?
|
||||
function ActionHandler:get_just_pressed(action) end
|
||||
|
||||
---Returns the current state of the action.
|
||||
---
|
||||
---The first element in the returned tuple is the state enum, and the second
|
||||
---is the state modifier. The modifer will be `nil` if the state is "idle"
|
||||
---
|
||||
---@return [ActionState, number?]
|
||||
function ActionHandler:get_action_state(action) end
|
|
@ -0,0 +1,15 @@
|
|||
---@meta
|
||||
|
||||
---@class DeltaTime: userdata
|
||||
---
|
||||
---DeltaTime is an ECS world resource. When its requested from the world, a `number`
|
||||
---is returned.
|
||||
---
|
||||
---Example:
|
||||
---```lua
|
||||
------@type number
|
||||
---local dt = world:resource(DeltaTime)
|
||||
---
|
||||
---print(type(dt)) --> number
|
||||
---```
|
||||
DeltaTime = {}
|
|
@ -0,0 +1,4 @@
|
|||
---@meta
|
||||
|
||||
---@class Entity: userdata
|
||||
Entity = {}
|
|
@ -1,4 +1,4 @@
|
|||
---@class Window
|
||||
---@class Window: userdata
|
||||
Window = {
|
||||
---Gets or sets the window's focus.
|
||||
---@type boolean
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
---@meta
|
||||
|
||||
---@class World: userdata
|
||||
World = {}
|
||||
|
||||
---Spawn an entity with components.
|
||||
---
|
||||
---@param ... userdata The components to spawn on the new entity, currently must be userdata.
|
||||
---@return Entity
|
||||
function World:spawn(...) end
|
||||
|
||||
--- Query components from the world.
|
||||
---
|
||||
--- The `system` parameter is a function with the requested components. The function
|
||||
--- is ran every time for an entity. If you modify a component and want the changes to be
|
||||
--- stored, return it in the function. The order of the returned components do not matter.
|
||||
---
|
||||
--- Example:
|
||||
--- ```lua
|
||||
--- ---@type number
|
||||
--- local dt = world:resource(DeltaTime)
|
||||
---
|
||||
--- world:view(
|
||||
--- ---@param t Transform
|
||||
--- function (t)
|
||||
--- -- Move the transform of the entity a bit
|
||||
--- t:translate(0, 0.15 * dt, 0)
|
||||
--- -- Since the transform was modified, it must be returned so
|
||||
--- -- the engine can store the changes.
|
||||
--- return t
|
||||
--- end,
|
||||
--- -- Specify the requested components here
|
||||
--- Transform
|
||||
--- )
|
||||
--- ```
|
||||
---
|
||||
---@param system fun(...): ...
|
||||
---@param ... userdata
|
||||
function World:view(system, ...) end
|
||||
|
||||
---Get an ECS resource.
|
||||
---
|
||||
---Returns `nil` if the resource was not found in the world. Many resources will
|
||||
---return userdata, however some may return Lua types like `DeltaTime`
|
||||
---returning a `number`.
|
||||
---
|
||||
---Example:
|
||||
---```lua
|
||||
------@type number
|
||||
---local dt = world:resource(DeltaTime)
|
||||
---
|
||||
---print(type(dt)) --> number
|
||||
---```
|
||||
---
|
||||
---@param resource userdata This shouldn't be an instance of userdata.
|
||||
---@return any?
|
||||
function World:resource(resource) end
|
||||
|
||||
---Add a resource to the world.
|
||||
---
|
||||
---If the resource already exists, it will be overwritten.
|
||||
---
|
||||
---@param resource userdata
|
||||
function World:add_resource(resource) end
|
||||
|
||||
---Request an asset.
|
||||
---
|
||||
---Assets are loaded asyncronously, so you must wait before trying to access fields on
|
||||
---the asset. You can spawn an entity with it when its still loading.
|
||||
---
|
||||
---Returns an asset handle to the requested resource type
|
||||
---
|
||||
---@param path string
|
||||
---@return Handle asset An asset handle to the requested resource type.
|
||||
function World:request_asset(path) end
|
|
@ -0,0 +1,5 @@
|
|||
---@meta
|
||||
|
||||
---The world global that is provided to every Lua script.
|
||||
---@type World
|
||||
world = nil
|
|
@ -1,3 +1,10 @@
|
|||
require "math.vec2"
|
||||
require "math.vec3"
|
||||
require "math.vec4"
|
||||
require "math.quat"
|
||||
require "math.transform"
|
||||
|
||||
require "ecs.window"
|
||||
require "ecs.delta_time"
|
||||
|
||||
require "asset.handle"
|
|
@ -0,0 +1,188 @@
|
|||
---@meta
|
||||
|
||||
---@class Quat: userdata
|
||||
---This is a Lua export of [`glam::Quat`](https://docs.rs/glam/latest/glam/f32/struct.Quat.html)
|
||||
---
|
||||
---@operator add(self): self
|
||||
---@operator sub(self): self
|
||||
---@operator div(number): self
|
||||
---@operator mul(self|Vec3|number): self
|
||||
---@diagnostic disable-next-line: unknown-operator
|
||||
---@operator eq: self
|
||||
Quat = {
|
||||
---The x coordinate
|
||||
---@type number
|
||||
x = nil,
|
||||
|
||||
---The y coordinate
|
||||
---@type number
|
||||
y = nil,
|
||||
|
||||
---The z coordinate
|
||||
---@type number
|
||||
z = nil,
|
||||
|
||||
---The w coordinate
|
||||
---@type number
|
||||
w = nil,
|
||||
}
|
||||
|
||||
---Create a new `Quat`
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@param w number
|
||||
---@return self
|
||||
function Quat.new(x, y, z, w) end
|
||||
|
||||
---Creates a quaternion from the angle (in radians) around the x axis.
|
||||
---@param rad number
|
||||
---@return self
|
||||
function Quat.from_rotation_x(rad) end
|
||||
|
||||
---Creates a quaternion from the angle (in radians) around the y axis.
|
||||
---@param rad number
|
||||
---@return self
|
||||
function Quat.from_rotation_y(rad) end
|
||||
|
||||
---Creates a quaternion from the angle (in radians) around the z axis.
|
||||
---@param rad number
|
||||
---@return self
|
||||
function Quat.from_rotation_z(rad) end
|
||||
|
||||
---Creates a quaternion from a `Vec4`.
|
||||
---@param vec4 Vec4
|
||||
---@return self
|
||||
function Quat.from_vec4(vec4) end
|
||||
|
||||
---Create a quaternion for a normalized rotation axis and angle (in radians).
|
||||
---
|
||||
---The axis must be a unit vector.
|
||||
---
|
||||
---@param axis Vec3
|
||||
---@param rad number
|
||||
---@return self
|
||||
function Quat.from_axis_angle(axis, rad) end
|
||||
|
||||
---Computes the dot product of self and rhs.
|
||||
---
|
||||
---The dot product is equal to the cosine of the angle between two
|
||||
---quaternion rotations.
|
||||
---
|
||||
---@param rhs Quat
|
||||
---@return number
|
||||
function Quat:dot(rhs) end
|
||||
|
||||
---Computes the length of self.
|
||||
---
|
||||
---@return number
|
||||
function Quat:length() end
|
||||
|
||||
---Computes the squared length of self.
|
||||
---
|
||||
---This is generally faster than length() as it avoids a square root operation.
|
||||
---
|
||||
---@return number
|
||||
function Quat:length_squared() end
|
||||
|
||||
---Computes 1.0 / length().
|
||||
---
|
||||
---For valid results, self must not be of length zero.
|
||||
---@return number
|
||||
function length_recip() end
|
||||
|
||||
---Returns `self` normalized to length `1.0`.
|
||||
---
|
||||
---For valid results, `self` must not be of length zero.
|
||||
---
|
||||
---@return self
|
||||
function Quat:normalize() end
|
||||
|
||||
---Multipies `self` with a `Quat`
|
||||
---@param rhs Quat
|
||||
function Quat:mult_quat(rhs) end
|
||||
|
||||
---Multiplies `self` with a `Vec3`
|
||||
---@param rhs Vec3
|
||||
function Quat:mult_vec3(rhs) end
|
||||
|
||||
---Performs a linear interpolation between `self` and `rhs` based on `alpha`.
|
||||
---
|
||||
---Both `Quat`s must be normalized.
|
||||
---
|
||||
---When `alpha` is `0.0`, the result will be equal to `self`. When `alpha` is `1.0`,
|
||||
---the result will be equal to `rhs`.
|
||||
---
|
||||
---@param rhs Quat
|
||||
---@param alpha number
|
||||
function Quat:lerp(rhs, alpha) end
|
||||
|
||||
---Performs a spherical linear interpolation between `self` and `rhs` based on `alpha`.
|
||||
---
|
||||
---Both `Quat`s must be normalized.
|
||||
---
|
||||
---When `alpha` is `0.0`, the result will be equal to `self`. When `alpha` is `1.0`,
|
||||
---the result will be equal to `rhs`.
|
||||
---
|
||||
---@param rhs Quat
|
||||
---@param alpha number
|
||||
function Quat:slerp(rhs, alpha) end
|
||||
|
||||
|
||||
---Returns the inverse of a normalized quaternion.
|
||||
---
|
||||
---Typically quaternion inverse returns the conjugate of a normalized quaternion.
|
||||
---Because `self` is assumed to already be unit length this method does not
|
||||
---normalize before returning the conjugate.
|
||||
---@return self
|
||||
function Quat:inverse() end
|
||||
|
||||
---Returns `true` if, and only if, all elements are finite. If any element is either
|
||||
---`NaN`, positive or negative infinity, this will return `false`.
|
||||
---
|
||||
---@return boolean
|
||||
function Quat:is_finite() end
|
||||
|
||||
---@return boolean
|
||||
function Quat:is_nan() end
|
||||
|
||||
---Returns whether `self` is of length `1.0` or not.
|
||||
---
|
||||
---Uses a precision threshold of `1e-6`.
|
||||
---@return boolean
|
||||
function Quat:is_normalized() end
|
||||
|
||||
---@return boolean
|
||||
function Quat:is_near_identity() end
|
||||
|
||||
---Returns the angle (in radians) for the minimal rotation for transforming
|
||||
---this quaternion into another.
|
||||
---
|
||||
---Both quaternions must be normalized.
|
||||
---@return number
|
||||
function Quat:angle_between(rhs) end
|
||||
|
||||
---Rotates towards `rhs` up to `max_angle` (in radians).
|
||||
---
|
||||
---When `max_angle` is `0.0`, the result will be equal to `self`. When `max_angle`
|
||||
---is equal to `self.angle_between(rhs)`, the result will be equal to `rhs`.
|
||||
---If `max_angle` is negative, rotates towards the exact opposite of `rhs`.
|
||||
---Will not go past the target.
|
||||
---
|
||||
---Both quaternions must be normalized.
|
||||
---@return self
|
||||
function Quat:rotate_towards(rhs, max_angle) end
|
||||
|
||||
---Returns true if the absolute difference of all elements between `self` and `rhs` is less
|
||||
---than or equal to `max_abs_diff`.
|
||||
---
|
||||
---This can be used to compare if two quaternions contain similar elements. It works best when
|
||||
---comparing with a known value. The `max_abs_diff` that should be used used depends on the
|
||||
---values being compared against.
|
||||
---
|
||||
---For more see [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
|
||||
---
|
||||
---@param rhs Quat
|
||||
---@param max_abs_diff number
|
||||
---@return boolean
|
||||
function Quat:abs_diff_eq(rhs, max_abs_diff) end
|
|
@ -0,0 +1,134 @@
|
|||
---@meta
|
||||
|
||||
---@class Transform: userdata
|
||||
---
|
||||
---A Transform represents a transformation of an object. A transform includes the position
|
||||
---(called translation here), rotation, and scale. Rotation is represented using a Quaternion
|
||||
---(or Quat for short).
|
||||
---
|
||||
---Although Quats can be scary, they are much more robust than euler angles for games
|
||||
---since they do not suffer from things like
|
||||
---[gimbal-lock](https://en.wikipedia.org/wiki/Gimbal_lock).
|
||||
---
|
||||
---This is a Lua export of [`lyra_math::Transform`].
|
||||
---
|
||||
---@operator add(Quat): self
|
||||
---@operator mul(Vec3): self
|
||||
---@diagnostic disable-next-line: unknown-operator
|
||||
---@operator eq: self
|
||||
Transform = {
|
||||
---The translation/position of the transform.
|
||||
---@type Vec3
|
||||
translation = nil,
|
||||
---The rotation of the transform.
|
||||
---@type Quat
|
||||
rotation = nil,
|
||||
---The scale of the transform.
|
||||
---@type Vec3
|
||||
scale = nil,
|
||||
}
|
||||
|
||||
function Transform:__tostring() end
|
||||
|
||||
---@return self
|
||||
function Transform.default() end
|
||||
|
||||
---Create a new transform with its components.
|
||||
---
|
||||
---@param translation Vec3
|
||||
---@param rotation Quat
|
||||
---@param scale Vec3
|
||||
---@return self
|
||||
function Transform.new(translation, rotation, scale) end
|
||||
|
||||
---Create a new transform with a `Vec3` translation.
|
||||
---@param translation Vec3
|
||||
---@return self
|
||||
function Transform.from_translation(translation) end
|
||||
|
||||
---Create a new transform with a translation of `x`, `y`, and `z`.
|
||||
---
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@return self
|
||||
function Transform.from_translation(x, y, z) end
|
||||
|
||||
---Create a clone of `self`
|
||||
---@return self
|
||||
function Transform:clone() end
|
||||
|
||||
---Returns a normalized vector pointing in the direction the Transform is facing.
|
||||
---
|
||||
---This represents the front of the object can be used for movement, camera orientation, and
|
||||
---other directional calculations.
|
||||
---
|
||||
---@return Vec3
|
||||
function Transform:forward() end
|
||||
|
||||
---Returns a normalized vector pointing to the left side of the Transform.
|
||||
---
|
||||
---The vector is in local space. This represents the direction that is
|
||||
---perpendicular to the object's forward direction.
|
||||
---
|
||||
---@return Vec3
|
||||
function Transform:left() end
|
||||
|
||||
---Returns a normalized vector that indicates the upward direction of the Transform.
|
||||
---
|
||||
---This vector is commonly used to define an object's orientation and is essential for maintaining
|
||||
---consistent vertical alignment in 3D environments, such as for camera positioning and object alignment.
|
||||
---@return Vec3
|
||||
function Transform:up() end
|
||||
|
||||
---Rotate `self` using a quaternion
|
||||
---@param quat Quat
|
||||
function Transform:rotate(quat) end
|
||||
|
||||
---Rotate `self` around the x axis by **degrees**.
|
||||
---
|
||||
---@param deg number The amount of **degrees** to rotate by.
|
||||
function Transform:rotate_x(deg) end
|
||||
|
||||
---Rotate `self` around the y axis by **degrees**.
|
||||
---
|
||||
---@param deg number The amount of **degrees** to rotate by.
|
||||
function Transform:rotate_y(deg) end
|
||||
|
||||
---Rotate `self` around the z axis by **degrees**.
|
||||
---
|
||||
---@param deg number The amount of **degrees** to rotate by.
|
||||
function Transform:rotate_z(deg) end
|
||||
|
||||
---Rotate `self` around the x axis by **radians** .
|
||||
---
|
||||
---@param rad number The amount of **radians** to rotate by.
|
||||
function Transform:rotate_x_rad(rad) end
|
||||
|
||||
---Rotate `self` around the y axis by **radians** .
|
||||
---
|
||||
---@param rad number The amount of **radians** to rotate by.
|
||||
function Transform:rotate_y_rad(rad) end
|
||||
|
||||
---Rotate `self` around the z axis by **radians** .
|
||||
---
|
||||
---@param rad number The amount of **radians** to rotate by.
|
||||
function Transform:rotate_z_rad(rad) end
|
||||
|
||||
---Move `self` by `x`, `y`, and `z`.
|
||||
---
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
function Transform:translate(x, y, z) end
|
||||
|
||||
---Performs a linear interpolation between `self` and `rhs` based on `alpha`.
|
||||
---
|
||||
---This will normalize the rotation `Quat`.
|
||||
---
|
||||
---When `alpha` is `0.0`, the result will be equal to `self`. When `alpha` is `1.0`,
|
||||
---the result will be equal to `rhs`.
|
||||
---
|
||||
---@param rhs Transform
|
||||
---@param alpha number
|
||||
function Transform:lerp(rhs, alpha) end
|
|
@ -1,14 +1,125 @@
|
|||
---@class Vec2
|
||||
---@meta
|
||||
|
||||
---@class Vec2: userdata
|
||||
---This is a Lua export of [`glam::Vec2`](https://docs.rs/glam/latest/glam/f32/struct.Vec2.html)
|
||||
---
|
||||
---@operator add(self|number): self
|
||||
---@operator sub(self|number): self
|
||||
---@operator div(self|number): self
|
||||
---@operator mul(self|number): self
|
||||
---@operator mod(self|number): self
|
||||
---@operator unm: self
|
||||
---@diagnostic disable-next-line: unknown-operator
|
||||
---@operator eq: self
|
||||
Vec2 = {
|
||||
---The x coordinate
|
||||
---@type number
|
||||
x = nil,
|
||||
|
||||
---The y coordinate
|
||||
---@type number
|
||||
y = nil,
|
||||
|
||||
---Create a new `Vec2`
|
||||
---@param x number
|
||||
---@param y number
|
||||
new = function (x, y) end
|
||||
---A constant `Vec2` with coordinates as `f32::NAN`.
|
||||
---@type Vec2
|
||||
NAN = nil,
|
||||
|
||||
---A constant `Vec2` with `x` as `-1.0`.
|
||||
---@type Vec2
|
||||
NEG_X = nil,
|
||||
|
||||
---A constant `Vec2` with `y` as `-1.0`.
|
||||
---@type Vec2
|
||||
NEG_Y = nil,
|
||||
|
||||
---A constant `Vec2` with both components as `-1.0`.
|
||||
---@type Vec2
|
||||
NEG_ONE = nil,
|
||||
|
||||
---A constant `Vec2` with `x` as `1.0`.
|
||||
---@type Vec2
|
||||
POS_X = nil,
|
||||
|
||||
---A constant `Vec2` with `y` as `1.0`.
|
||||
---@type Vec2
|
||||
POS_Y = nil,
|
||||
|
||||
---A constant `Vec2` with both components as `1.0`.
|
||||
---@type Vec2
|
||||
ONE = nil,
|
||||
|
||||
---A constant `Vec2` with both components as `0.0`.
|
||||
---@type Vec2
|
||||
ZERO = nil,
|
||||
}
|
||||
|
||||
function Vec2:__tostring() end
|
||||
|
||||
---Create a new `Vec2`
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@return self
|
||||
function Vec2.new(x, y) end
|
||||
|
||||
---Returns a vector with a length no less than min and no more than max.
|
||||
---@param min number the minimum value to clamp the length to
|
||||
---@param max number the maximum value to clamp the length to
|
||||
---@return self
|
||||
function Vec2:clamp_length(min, max) end
|
||||
|
||||
---Returns true if the absolute difference of all elements between `self` and `rhs` is less
|
||||
---than or equal to `max_abs_diff`.
|
||||
---
|
||||
---This can be used to compare if two vectors contain similar elements. It works best when
|
||||
---comparing with a known value. The `max_abs_diff` that should be used used depends on the
|
||||
---values being compared against.
|
||||
---
|
||||
---For more see [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
|
||||
---
|
||||
---@param rhs Vec2 The other `Vec2` to compare to.
|
||||
---@param max_abs_diff number Maximum absolute difference between `self` and `rhs`.
|
||||
---@return boolean
|
||||
function Vec2:abs_diff_eq(rhs, max_abs_diff) end
|
||||
|
||||
---Returns a vector containing the smallest integer greater than or equal to a number for each
|
||||
---element of self.
|
||||
---@return self
|
||||
function Vec2:ceil() end
|
||||
|
||||
---Returns the angle of rotation (in radians) from `self` to `rhs` in the range [-π, +π].
|
||||
---
|
||||
---The inputs do not need to be unit vectors however they must be non-zero.
|
||||
---
|
||||
---@param rhs Vec2 The other `Vec2` to get the angle to.
|
||||
---@return number
|
||||
function Vec2:angle_to(rhs) end
|
||||
|
||||
---Returns a vector containing the absolute value of each element of `self`.
|
||||
---
|
||||
---@return self
|
||||
function Vec2:abs() end
|
||||
|
||||
---Component-wise clamping of values.
|
||||
---
|
||||
---Each element in `min` must be less-or-equal to the corresponding element in `max`.
|
||||
---
|
||||
---@param min self The minimum `Vec2` components to clamp the components of `self` to.
|
||||
---@param max self The maximum `Vec2` components to clamp the components of `self` to.
|
||||
---@return self
|
||||
function Vec2:clamp(min, max) end
|
||||
|
||||
---Converts `self` to an array `[x, y]`
|
||||
---
|
||||
---@return number[]
|
||||
function Vec2:to_array() end
|
||||
|
||||
---Move `self` by `x` and `y` values.
|
||||
---
|
||||
---@param x number
|
||||
---@param y number
|
||||
function Vec2:move_by(x, y) end
|
||||
|
||||
---Move `self` by a `Vec2`.
|
||||
---
|
||||
---@param rhs Vec2
|
||||
function Vec2:move_by(rhs) end
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
---@meta
|
||||
|
||||
---@class Vec3: userdata
|
||||
---This is a Lua export of [`glam::Vec3`](https://docs.rs/glam/latest/glam/f32/struct.Vec3.html)
|
||||
---
|
||||
---@operator add(self|number): self
|
||||
---@operator sub(self|number): self
|
||||
---@operator div(self|number): self
|
||||
---@operator mul(self|number): self
|
||||
---@operator mod(self|number): self
|
||||
---@operator unm: self
|
||||
---@diagnostic disable-next-line: unknown-operator
|
||||
---@operator eq: self
|
||||
Vec3 = {
|
||||
---The x coordinate
|
||||
---@type number
|
||||
x = nil,
|
||||
|
||||
---The y coordinate
|
||||
---@type number
|
||||
y = nil,
|
||||
|
||||
---The z coordinate
|
||||
---@type number
|
||||
z = nil,
|
||||
|
||||
---A constant `Vec3` with coordinates as `f32::NAN`.
|
||||
---@type Vec3
|
||||
NAN = nil,
|
||||
|
||||
---A constant `Vec3` with `x` as `-1.0`.
|
||||
---@type Vec3
|
||||
NEG_X = nil,
|
||||
|
||||
---A constant `Vec3` with `y` as `-1.0`.
|
||||
---@type Vec3
|
||||
NEG_Y = nil,
|
||||
|
||||
---A constant `Vec3` with `z` as `-1.0`.
|
||||
---@type Vec3
|
||||
NEG_Z = nil,
|
||||
|
||||
---A constant `Vec3` with all components as `-1.0`.
|
||||
---@type Vec3
|
||||
NEG_ONE = nil,
|
||||
|
||||
---A constant `Vec3` with `x` as `1.0`.
|
||||
---@type Vec3
|
||||
POS_X = nil,
|
||||
|
||||
---A constant `Vec3` with `y` as `1.0`.
|
||||
---@type Vec3
|
||||
POS_Y = nil,
|
||||
|
||||
---A constant `Vec3` with `z` as `1.0`.
|
||||
---@type Vec3
|
||||
POS_Z = nil,
|
||||
|
||||
---A constant `Vec3` with all components as `1.0`.
|
||||
---@type Vec3
|
||||
ONE = nil,
|
||||
|
||||
---A constant `Vec3` with all components as `0.0`.
|
||||
---@type Vec3
|
||||
ZERO = nil,
|
||||
}
|
||||
|
||||
function Vec3:__tostring() end
|
||||
|
||||
---Create a new `Vec3`
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@return self
|
||||
function Vec3.new(x, y, z) end
|
||||
|
||||
---Returns a vector with a length no less than min and no more than max.
|
||||
---@param min number the minimum value to clamp the length to
|
||||
---@param max number the maximum value to clamp the length to
|
||||
---@return self
|
||||
function Vec3:clamp_length(min, max) end
|
||||
|
||||
---Returns true if the absolute difference of all elements between `self` and `rhs` is less
|
||||
---than or equal to `max_abs_diff`.
|
||||
---
|
||||
---This can be used to compare if two vectors contain similar elements. It works best when
|
||||
---comparing with a known value. The `max_abs_diff` that should be used used depends on the
|
||||
---values being compared against.
|
||||
---
|
||||
---For more see [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
|
||||
---
|
||||
---@param rhs Vec3 The other `Vec3` to compare to.
|
||||
---@param max_abs_diff number Maximum absolute difference between `self` and `rhs`.
|
||||
---@return boolean
|
||||
function Vec3:abs_diff_eq(rhs, max_abs_diff) end
|
||||
|
||||
---Returns a vector containing the smallest integer greater than or equal to a number for each
|
||||
---element of self.
|
||||
---@return self
|
||||
function Vec3:ceil() end
|
||||
|
||||
---Returns the angle (in radians) between two vectors in the range [-π, +π].
|
||||
---
|
||||
---The inputs do not need to be unit vectors however they must be non-zero.
|
||||
---
|
||||
---@param rhs Vec3 The other `Vec3` to get the angle to.
|
||||
---@return number
|
||||
function Vec3:angle_between(rhs) end
|
||||
|
||||
---Returns a vector containing the absolute value of each element of `self`.
|
||||
---
|
||||
---@return self
|
||||
function Vec3:abs() end
|
||||
|
||||
---Component-wise clamping of values.
|
||||
---
|
||||
---Each element in `min` must be less-or-equal to the corresponding element in `max`.
|
||||
---
|
||||
---@param min self The minimum `Vec3` components to clamp the components of `self` to.
|
||||
---@param max self The maximum `Vec3` components to clamp the components of `self` to.
|
||||
---@return self
|
||||
function Vec3:clamp(min, max) end
|
||||
|
||||
---Converts `self` to an array `[x, y, z]`
|
||||
---
|
||||
---@return number[]
|
||||
function Vec3:to_array() end
|
||||
|
||||
---Move `self` by `x`, `y`, and `z` values.
|
||||
---
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
function Vec3:move_by(x, y, z) end
|
||||
|
||||
---Move `self` by a `Vec3`.
|
||||
---
|
||||
---@param rhs Vec3
|
||||
function Vec3:move_by(rhs) end
|
|
@ -0,0 +1,132 @@
|
|||
---@meta
|
||||
|
||||
---@class Vec4: userdata
|
||||
---This is a Lua export of [`glam::Vec4`](https://docs.rs/glam/latest/glam/f32/struct.Vec4.html)
|
||||
---
|
||||
---@operator add(self|number): self
|
||||
---@operator sub(self|number): self
|
||||
---@operator div(self|number): self
|
||||
---@operator mul(self|number): self
|
||||
---@operator mod(self|number): self
|
||||
---@operator unm: self
|
||||
---@diagnostic disable-next-line: unknown-operator
|
||||
---@operator eq: self
|
||||
Vec4 = {
|
||||
---The x coordinate
|
||||
---@type number
|
||||
x = nil,
|
||||
|
||||
---The y coordinate
|
||||
---@type number
|
||||
y = nil,
|
||||
|
||||
---The z coordinate
|
||||
---@type number
|
||||
z = nil,
|
||||
|
||||
---The w coordinate
|
||||
---@type number
|
||||
w = nil,
|
||||
|
||||
---A constant `Vec4` with coordinates as `f32::NAN`.
|
||||
---@type Vec4
|
||||
NAN = nil,
|
||||
|
||||
---A constant `Vec4` with `x` as `-1.0`.
|
||||
---@type Vec4
|
||||
NEG_X = nil,
|
||||
|
||||
---A constant `Vec4` with `y` as `-1.0`.
|
||||
---@type Vec4
|
||||
NEG_Y = nil,
|
||||
|
||||
---A constant `Vec4` with `z` as `-1.0`.
|
||||
---@type Vec4
|
||||
NEG_Z = nil,
|
||||
|
||||
---A constant `Vec4` with `w` as `-1.0`.
|
||||
---@type Vec4
|
||||
NEG_W = nil,
|
||||
|
||||
---A constant `Vec4` with all components as `-1.0`.
|
||||
---@type Vec4
|
||||
NEG_ONE = nil,
|
||||
|
||||
---A constant `Vec4` with `x` as `1.0`.
|
||||
---@type Vec4
|
||||
POS_X = nil,
|
||||
|
||||
---A constant `Vec4` with `y` as `1.0`.
|
||||
---@type Vec4
|
||||
POS_Y = nil,
|
||||
|
||||
---A constant `Vec4` with `z` as `1.0`.
|
||||
---@type Vec4
|
||||
POS_Z = nil,
|
||||
|
||||
---A constant `Vec4` with `w` as `1.0`.
|
||||
---@type Vec4
|
||||
POS_W = nil,
|
||||
|
||||
---A constant `Vec4` with all components as `1.0`.
|
||||
---@type Vec4
|
||||
ONE = nil,
|
||||
|
||||
---A constant `Vec4` with all components as `0.0`.
|
||||
---@type Vec4
|
||||
ZERO = nil,
|
||||
}
|
||||
|
||||
function Vec4:__tostring() end
|
||||
|
||||
---Create a new `Vec4`
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param z number
|
||||
---@param w number
|
||||
---@return self
|
||||
function Vec4.new(x, y, z, w) end
|
||||
|
||||
---Returns a vector with a length no less than min and no more than max.
|
||||
---@param min number the minimum value to clamp the length to
|
||||
---@param max number the maximum value to clamp the length to
|
||||
---@return self
|
||||
function Vec4:clamp_length(min, max) end
|
||||
|
||||
---Returns true if the absolute difference of all elements between `self` and `rhs` is less
|
||||
---than or equal to `max_abs_diff`.
|
||||
---
|
||||
---This can be used to compare if two vectors contain similar elements. It works best when
|
||||
---comparing with a known value. The `max_abs_diff` that should be used used depends on the
|
||||
---values being compared against.
|
||||
---
|
||||
---For more see [comparing floating point numbers](https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/).
|
||||
---
|
||||
---@param rhs Vec4 The other `Vec4` to compare to.
|
||||
---@param max_abs_diff number Maximum absolute difference between `self` and `rhs`.
|
||||
---@return boolean
|
||||
function Vec4:abs_diff_eq(rhs, max_abs_diff) end
|
||||
|
||||
---Returns a vector containing the smallest integer greater than or equal to a number for each
|
||||
---element of self.
|
||||
---@return self
|
||||
function Vec4:ceil() end
|
||||
|
||||
---Returns a vector containing the absolute value of each element of `self`.
|
||||
---
|
||||
---@return self
|
||||
function Vec4:abs() end
|
||||
|
||||
---Component-wise clamping of values.
|
||||
---
|
||||
---Each element in `min` must be less-or-equal to the corresponding element in `max`.
|
||||
---
|
||||
---@param min self The minimum `Vec4` components to clamp the components of `self` to.
|
||||
---@param max self The maximum `Vec4` components to clamp the components of `self` to.
|
||||
---@return self
|
||||
function Vec4:clamp(min, max) end
|
||||
|
||||
---Converts `self` to an array `[x, y, z]`
|
||||
---
|
||||
---@return number[]
|
||||
function Vec4:to_array() end
|
|
@ -40,14 +40,18 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
|||
fn expose_api(&mut self, _: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||
let ctx = ctx.lock().unwrap();
|
||||
|
||||
// load window util
|
||||
// load window enums
|
||||
let bytes = include_str!("../../../scripts/lua/window.lua");
|
||||
ctx.load(bytes).exec().unwrap();
|
||||
|
||||
// load asset handle enums
|
||||
let bytes = include_str!("../../../scripts/lua/asset_handle.lua");
|
||||
ctx.load(bytes).exec().unwrap();
|
||||
|
||||
let globals = ctx.globals();
|
||||
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
||||
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
||||
globals.set("SceneComponent", ctx.create_proxy::<LuaSceneHandle>()?)?;
|
||||
globals.set("SceneHandler", ctx.create_proxy::<LuaSceneHandle>()?)?;
|
||||
globals.set("ActionHandler", ctx.create_proxy::<LuaActionHandler>()?)?;
|
||||
globals.set("Window", ctx.create_proxy::<LuaWindow>()?)?;
|
||||
|
||||
|
|
|
@ -294,7 +294,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
|
||||
Ok(())
|
||||
});
|
||||
methods.add_method_mut("request_res", |lua, this, path: String| {
|
||||
methods.add_method_mut("request_asset", |lua, this, path: String| {
|
||||
let world = this.write();
|
||||
let man = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||
let handle = man.request_raw(&path).unwrap();
|
||||
|
|
|
@ -111,9 +111,12 @@ impl mlua::FromLua for LuaResHandle {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: fields
|
||||
wrap_lua_struct!(lyra_resource::gltf::PbrGlossiness, skip(lua_reflect)); // doesn't need internal lua reflection methods
|
||||
// TODO: fields
|
||||
wrap_lua_struct!(lyra_resource::gltf::Specular, skip(lua_reflect)); // doesn't need internal lua reflection methods
|
||||
|
||||
// TODO: fields
|
||||
lua_wrap_handle!(SceneGraph, name=Scene, {});
|
||||
|
||||
lua_wrap_handle!(Mesh,
|
||||
|
|
|
@ -127,13 +127,21 @@ impl mlua::UserData for LuaActionHandler {
|
|||
methods.add_method("get_action_state", |lua, this, action: String| {
|
||||
let state = this.handler.get_action_state(action);
|
||||
|
||||
// if the state wasn't found, return Nil.
|
||||
if state.is_none() {
|
||||
let mut v = mlua::MultiValue::new();
|
||||
v.push_back(mlua::Value::Nil);
|
||||
return Ok(v);
|
||||
}
|
||||
|
||||
let state = state.unwrap();
|
||||
let (name, val) = match state {
|
||||
ActionState::Idle => ("Idle", None),
|
||||
ActionState::Pressed(v) => ("Pressed", Some(v)),
|
||||
ActionState::JustPressed(v) => ("JustPressed", Some(v)),
|
||||
ActionState::JustReleased => ("JustReleased", None),
|
||||
ActionState::Axis(v) => ("Axis", Some(v)),
|
||||
ActionState::Other(v) => ("Other", Some(v)),
|
||||
ActionState::Idle => ("idle", None),
|
||||
ActionState::Pressed(v) => ("pressed", Some(v)),
|
||||
ActionState::JustPressed(v) => ("just_pressed", Some(v)),
|
||||
ActionState::JustReleased => ("just_released", None),
|
||||
ActionState::Axis(v) => ("axis", Some(v)),
|
||||
ActionState::Other(v) => ("other", Some(v)),
|
||||
};
|
||||
|
||||
let mut multi = Vec::new();
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use crate::lyra_engine;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{lua::Error, lyra_engine};
|
||||
use lyra_game::math;
|
||||
use lyra_scripting_derive::{lua_vec_wrap_extension, wrap_lua_struct};
|
||||
use mlua::FromLuaMulti;
|
||||
|
@ -29,7 +31,14 @@ wrap_lua_struct!(
|
|||
} else if let Ok(v) = Self::from_lua_multi(vals_clone, lua) {
|
||||
this.0 += v.0;
|
||||
} else {
|
||||
todo!("handle invalid argument error");
|
||||
return Err(mlua::Error::BadArgument {
|
||||
to: Some("Vec2:move_by".into()),
|
||||
pos: 2,
|
||||
name: None,
|
||||
cause: Arc::new(mlua::Error::runtime(
|
||||
"expected (number, number, number) or (Vec2), received neither"
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -62,7 +71,14 @@ wrap_lua_struct!(
|
|||
} else if let Ok(v) = Self::from_lua_multi(vals_clone, lua) {
|
||||
this.0 += v.0;
|
||||
} else {
|
||||
todo!("handle invalid argument error");
|
||||
return Err(mlua::Error::BadArgument {
|
||||
to: Some("Vec3:move_by".into()),
|
||||
pos: 2,
|
||||
name: None,
|
||||
cause: Arc::new(mlua::Error::runtime(
|
||||
"expected (number, number, number) or (Vec3), received neither"
|
||||
)),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -122,10 +138,27 @@ wrap_lua_struct!(
|
|||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_vec4", |_, v: LuaVec4| {
|
||||
Ok(Self(math::Quat::from_vec4(*v)))
|
||||
});
|
||||
|
||||
methods.add_function("from_axis_angle", |_, (axis, angle): (LuaVec3, f32)| {
|
||||
let q = math::Quat::from_axis_angle(*axis, angle);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_method("dot", |_, this, (rhs,): (Self,)| {
|
||||
Ok(this.dot(rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("conjugate", |_, this, ()| {
|
||||
Ok(Self(this.conjugate()))
|
||||
});
|
||||
|
||||
methods.add_method("inverse", |_, this, ()| {
|
||||
Ok(Self(this.inverse()))
|
||||
});
|
||||
|
||||
methods.add_method("length", |_, this, ()| {
|
||||
Ok(this.length())
|
||||
});
|
||||
|
@ -134,20 +167,50 @@ wrap_lua_struct!(
|
|||
Ok(this.length_squared())
|
||||
});
|
||||
|
||||
methods.add_method_mut("normalize", |_, this, ()| {
|
||||
this.0 = this.normalize();
|
||||
Ok(())
|
||||
methods.add_method("length_recip", |_, this, ()| {
|
||||
Ok(this.length_recip())
|
||||
});
|
||||
|
||||
methods.add_method_mut("mult_quat", |_, this, (rhs,): (Self,)| {
|
||||
this.0 *= rhs.0;
|
||||
Ok(())
|
||||
methods.add_method("normalize", |_, this, ()| {
|
||||
Ok(Self(this.normalize()))
|
||||
});
|
||||
|
||||
methods.add_method("mult_quat", |_, this, (rhs,): (Self,)| {
|
||||
Ok(Self(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("mult_vec3", |_, this, (rhs,): (LuaVec3,)| {
|
||||
Ok(LuaVec3(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("is_finite", |_, this, ()| {
|
||||
Ok(this.is_finite())
|
||||
});
|
||||
|
||||
methods.add_method("is_nan", |_, this, ()| {
|
||||
Ok(this.is_nan())
|
||||
});
|
||||
|
||||
methods.add_method("is_normalized", |_, this, ()| {
|
||||
Ok(this.is_normalized())
|
||||
});
|
||||
|
||||
methods.add_method("is_near_identity", |_, this, ()| {
|
||||
Ok(this.is_near_identity())
|
||||
});
|
||||
|
||||
methods.add_method("angle_between", |_, this, rhs: LuaQuat| {
|
||||
Ok(this.angle_between(*rhs))
|
||||
});
|
||||
|
||||
methods.add_method("rotate_towards", |_, this, (rhs, max_angle): (LuaQuat, f32)| {
|
||||
Ok(Self(this.rotate_towards(*rhs, max_angle)))
|
||||
});
|
||||
|
||||
methods.add_method("abs_diff_eq", |_, this, (rhs, max_abs_diff): (LuaQuat, f32)| {
|
||||
Ok(this.abs_diff_eq(*rhs, max_abs_diff))
|
||||
});
|
||||
|
||||
// manually implemented here since multiplying may not return `Self`.
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |lua, this, (val,): (mlua::Value,)| {
|
||||
use mlua::IntoLua;
|
||||
|
@ -169,7 +232,15 @@ wrap_lua_struct!(
|
|||
.into_lua(lua)
|
||||
},
|
||||
_ => {
|
||||
todo!()
|
||||
let t = val.type_name();
|
||||
Err(mlua::Error::BadArgument {
|
||||
to: Some("Quat:__mul".into()),
|
||||
pos: 2,
|
||||
name: None,
|
||||
cause: Arc::new(mlua::Error::external(
|
||||
Error::type_mismatch("Vec3, Quat, or Number", t)
|
||||
)),
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -177,6 +248,10 @@ wrap_lua_struct!(
|
|||
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.lerp(*rhs, alpha)))
|
||||
});
|
||||
|
||||
methods.add_method("slerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.slerp(*rhs, alpha)))
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -193,12 +268,22 @@ wrap_lua_struct!(
|
|||
Ok(Self(math::Transform::new(*pos, *rot, *scale)))
|
||||
});
|
||||
|
||||
methods.add_function("from_translation", |_, (pos,): (LuaVec3,)| {
|
||||
Ok(Self(math::Transform::from_translation(*pos)))
|
||||
});
|
||||
|
||||
methods.add_function("from_xyz", |_, (x, y, z)| {
|
||||
Ok(Self(math::Transform::from_xyz(x, y, z)))
|
||||
methods.add_function("from_translation", |lua, vals: mlua::MultiValue| {
|
||||
let vals_clone = vals.clone();
|
||||
if let Ok((x, y, z)) = <(f32, f32, f32) as FromLuaMulti>::from_lua_multi(vals, lua) {
|
||||
Ok(Self(math::Transform::from_xyz(x, y, z)))
|
||||
} else if let Ok(v) = LuaVec3::from_lua_multi(vals_clone, lua) {
|
||||
Ok(Self(math::Transform::from_translation(*v)))
|
||||
} else {
|
||||
Err(mlua::Error::BadArgument {
|
||||
to: Some("Transform:from_translation".into()),
|
||||
pos: 2,
|
||||
name: None,
|
||||
cause: Arc::new(mlua::Error::runtime(
|
||||
"expected (number, number, number) or (Vec3), received neither"
|
||||
)),
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
methods.add_method("clone", |_, this, ()| {
|
||||
|
|
Loading…
Reference in New Issue