scripting: fix math type wrapper macro for lua. Expose math types as userdata through LuaProxy trait
This commit is contained in:
parent
ea958f9f18
commit
e6b4e83dee
|
@ -1,5 +1,3 @@
|
|||
print("Hello World")
|
||||
|
||||
--[[ function on_init()
|
||||
print("Lua script was initialized!")
|
||||
end
|
||||
|
@ -13,27 +11,11 @@ function on_pre_update()
|
|||
end ]]
|
||||
|
||||
function on_update()
|
||||
--print("Lua's update function was called")
|
||||
|
||||
--[[ world:view(
|
||||
---@param t Transform
|
||||
function (t)
|
||||
print("Found entity at a really cool place: " .. tostring(t))
|
||||
t.translation:move_by(0, 0.001, 0)
|
||||
|
||||
return t
|
||||
end,
|
||||
Transform
|
||||
) ]]
|
||||
|
||||
---@type number
|
||||
local dt = world:resource(DeltaTime)
|
||||
--print("DeltaTime was " .. tostring(dt) .. "s")
|
||||
|
||||
world:view(function (t)
|
||||
--print("Found entity at a really cool place: " .. tostring(t))
|
||||
--t.translation = t.translation + (Vec3.new(0, 0.5, 0) * dt:get())
|
||||
t.translation:move_by(0, 0.5 * dt, 0)
|
||||
t:translate(0, 0.5 * dt, 0)
|
||||
|
||||
return t
|
||||
end, Transform)
|
||||
|
|
|
@ -342,7 +342,7 @@ impl Game {
|
|||
.with(fmt::layer().with_writer(stdout_layer))
|
||||
.with(filter::Targets::new()
|
||||
// done by prefix, so it includes all lyra subpackages
|
||||
.with_target("lyra", Level::TRACE)
|
||||
.with_target("lyra", Level::DEBUG)
|
||||
.with_target("wgpu", Level::WARN)
|
||||
.with_default(Level::INFO))
|
||||
.init();
|
||||
|
|
|
@ -85,6 +85,13 @@ impl Transform {
|
|||
pub fn rotate_z(&mut self, angle: Angle) {
|
||||
self.rotate(Quat::from_rotation_z(angle.to_radians()))
|
||||
}
|
||||
|
||||
pub fn translate(&mut self, x: f32, y: f32, z: f32) {
|
||||
let trans = &mut self.translation;
|
||||
trans.x += x;
|
||||
trans.y += y;
|
||||
trans.z += z;
|
||||
}
|
||||
|
||||
/// Performs a linear interpolation between `self` and `rhs` based on the value `alpha`.
|
||||
///
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 9b542fb523a3dc5d2eb77b246136111ad8bc4dd2
|
||||
Subproject commit d32c138e996ec2fe17b7a5f7c0d3ff1562e446f0
|
|
@ -140,7 +140,7 @@ impl MetaMethod {
|
|||
let body = Self::get_method_body(&self.ident, other);
|
||||
|
||||
quote! {
|
||||
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (#wrapper_ident,)| {
|
||||
builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (#wrapper_ident,)| {
|
||||
#body
|
||||
});
|
||||
}
|
||||
|
@ -149,12 +149,12 @@ impl MetaMethod {
|
|||
let body = Self::get_body_for_arg(&self.ident, first, quote!(v));
|
||||
|
||||
quote! {
|
||||
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (#first,)| {
|
||||
builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (#first,)| {
|
||||
#body
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// an optional match arm that matches mlua::Value:Number
|
||||
// an optional match arm that matches elua::Value:Number
|
||||
let number_arm = {
|
||||
let num_ident = self.mods.iter().find(|i| {
|
||||
let is = i.to_string();
|
||||
|
@ -171,7 +171,7 @@ impl MetaMethod {
|
|||
let body = Self::get_body_for_arg(&self.ident, num_ident, quote!(n as #num_ident));
|
||||
|
||||
quote! {
|
||||
mlua::Value::Number(n) => {
|
||||
elua::Value::Number(n) => {
|
||||
#body
|
||||
},
|
||||
}
|
||||
|
@ -187,7 +187,7 @@ impl MetaMethod {
|
|||
let body = Self::get_method_body(&self.ident, quote!(other.0));
|
||||
|
||||
quote! {
|
||||
if let Ok(other) = ud.borrow::<#i>() {
|
||||
if let Ok(other) = ud.as_ref::<#i>() {
|
||||
#body
|
||||
}
|
||||
}
|
||||
|
@ -195,30 +195,30 @@ impl MetaMethod {
|
|||
});
|
||||
|
||||
quote! {
|
||||
mlua::Value::UserData(ud) => {
|
||||
elua::Value::Userdata(ud) => {
|
||||
#(#if_statements else)*
|
||||
// this is the body of the else statement
|
||||
{
|
||||
// try to get the name of the userdata for the error message
|
||||
if let Ok(mt) = ud.get_metatable() {
|
||||
if let Ok(name) = mt.get::<String>("__name") {
|
||||
return Err(mlua::Error::BadArgument {
|
||||
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(mlua::Error::RuntimeError(
|
||||
if let Ok(name) = mt.get::<_, String>("__name") {
|
||||
return Err(elua::Error::BadArgument {
|
||||
func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
arg_index: 2,
|
||||
arg_name: Some("rhs".to_string()),
|
||||
error: Arc::new(elua::Error::Runtime(
|
||||
format!("cannot multiply with unknown userdata named {}", name)
|
||||
))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Err(mlua::Error::BadArgument {
|
||||
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(
|
||||
mlua::Error::runtime("cannot multiply with unknown userdata")
|
||||
Err(elua::Error::BadArgument {
|
||||
func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
arg_index: 2,
|
||||
arg_name: Some("rhs".to_string()),
|
||||
error: Arc::new(
|
||||
elua::Error::runtime("cannot multiply with unknown userdata")
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -227,16 +227,16 @@ impl MetaMethod {
|
|||
};
|
||||
|
||||
quote! {
|
||||
methods.add_meta_method(mlua::MetaMethod::#mt_ident, |_, this, (v,): (mlua::Value,)| {
|
||||
builder.meta_method(elua::MetaMethod::#mt_ident, |_, this, (v,): (elua::Value,)| {
|
||||
match v {
|
||||
#number_arm
|
||||
#userdata_arm
|
||||
_ => Err(mlua::Error::BadArgument {
|
||||
to: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(
|
||||
mlua::Error::RuntimeError(format!("cannot multiply with {}", v.type_name()))
|
||||
_ => Err(elua::Error::BadArgument {
|
||||
func: Some(format!("{}.__{}", #wrapped_str, #mt_lua_name)),
|
||||
arg_index: 2,
|
||||
arg_name: Some("rhs".to_string()),
|
||||
error: Arc::new(
|
||||
elua::Error::Runtime(format!("cannot multiply with {}", v.type_name()))
|
||||
)
|
||||
})
|
||||
}
|
||||
|
@ -293,8 +293,8 @@ impl VecWrapper {
|
|||
|
||||
if axis_type_name.contains("b") {
|
||||
return quote! {
|
||||
fields.add_field("FALSE", #wrapper_ident(#wrapped_path::FALSE));
|
||||
fields.add_field("TRUE", #wrapper_ident(#wrapped_path::TRUE));
|
||||
builder.field("FALSE", #wrapper_ident(#wrapped_path::FALSE));
|
||||
builder.field("TRUE", #wrapper_ident(#wrapped_path::TRUE));
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -331,7 +331,7 @@ impl VecWrapper {
|
|||
let const_name = cnst.to_string();
|
||||
|
||||
quote! {
|
||||
fields.add_field(#const_name, #wrapper_ident(#wrapped_path::#cnst));
|
||||
builder.field(#const_name, #wrapper_ident(#wrapped_path::#cnst));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -356,17 +356,17 @@ impl VecWrapper {
|
|||
|
||||
optional_methods.push(
|
||||
quote! {
|
||||
methods.add_method("clamp_length",
|
||||
builder.method("clamp_length",
|
||||
|_, this, (min, max): (#type_id, #type_id)| {
|
||||
Ok(#wrapper_ident(this.clamp_length(min, max)))
|
||||
});
|
||||
|
||||
methods.add_method("abs_diff_eq",
|
||||
builder.method("abs_diff_eq",
|
||||
|_, this, (rhs, max_abs_diff): (#wrapper_ident, #type_id)| {
|
||||
Ok(this.abs_diff_eq(rhs.0, max_abs_diff))
|
||||
});
|
||||
|
||||
methods.add_method("ceil",
|
||||
builder.method("ceil",
|
||||
|_, this, (): ()| {
|
||||
Ok(#wrapper_ident(this.ceil()))
|
||||
});
|
||||
|
@ -376,7 +376,7 @@ impl VecWrapper {
|
|||
if vec_size != 4 {
|
||||
optional_methods.push(
|
||||
quote! {
|
||||
methods.add_method("angle_between",
|
||||
builder.method("angle_between",
|
||||
|_, this, (rhs,): (#wrapper_ident,)| {
|
||||
Ok(this.angle_between(rhs.0))
|
||||
});
|
||||
|
@ -388,7 +388,7 @@ impl VecWrapper {
|
|||
if !axis_type_name.contains("u") {
|
||||
optional_methods.push(
|
||||
quote! {
|
||||
methods.add_method("abs",
|
||||
builder.method("abs",
|
||||
|_, this, (): ()| {
|
||||
Ok(#wrapper_ident(this.abs()))
|
||||
});
|
||||
|
@ -400,19 +400,19 @@ impl VecWrapper {
|
|||
quote! {
|
||||
|
||||
|
||||
methods.add_method("clamp",
|
||||
builder.method("clamp",
|
||||
|_, this, (min, max): (#wrapper_ident, #wrapper_ident)| {
|
||||
Ok(#wrapper_ident(this.clamp(min.0, max.0)))
|
||||
});
|
||||
|
||||
// TODO: Not all Vecs have this
|
||||
/* methods.add_method("clamp_length",
|
||||
/* builder.method("clamp_length",
|
||||
|_, this, (min, max): (f32, f32)| {
|
||||
Ok(#wrapper_ident(this.clamp_length(min, max)))
|
||||
}); */
|
||||
|
||||
|
||||
methods.add_method("to_array",
|
||||
builder.method("to_array",
|
||||
|_, this, (): ()| {
|
||||
Ok(this.to_array())
|
||||
});
|
||||
|
@ -570,10 +570,10 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
let field_get_set_pairs = input.field_idents.iter().map(|i| {
|
||||
let is = i.to_string();
|
||||
quote! {
|
||||
fields.add_field_method_get(#is, |_, this| {
|
||||
builder.field_getter(#is, |_, this| {
|
||||
Ok(this.#i)
|
||||
});
|
||||
fields.add_field_method_set(#is, |_, this, #i| {
|
||||
builder.field_setter(#is, |_, this, #i| {
|
||||
this.#i = #i;
|
||||
Ok(())
|
||||
});
|
||||
|
@ -591,7 +591,7 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
|
||||
if !input.skip_new_fn {
|
||||
quote! {
|
||||
methods.add_function("new", |_, ( #(#idents_c),* )| {
|
||||
builder.function("new", |_, ( #(#idents_c),* )| {
|
||||
Ok(#wrapper_typename(#path::new( #(#idents),* )))
|
||||
});
|
||||
}
|
||||
|
@ -631,33 +631,35 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for #wrapper_typename {
|
||||
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
impl<'lua> elua::FromLua<'lua> for #wrapper_typename {
|
||||
fn from_lua(_lua: &'lua elua::State, value: elua::Value<'lua>) -> elua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(*ud.borrow::<Self>()?),
|
||||
elua::Value::Userdata(ud) => Ok(*ud.as_ref::<Self>()?),
|
||||
_ => panic!("Attempt to get {} from a {} value", stringify!(#wrapper_typename), value.type_name()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::UserData for #wrapper_typename {
|
||||
fn add_fields<'lua, F: mlua::prelude::LuaUserDataFields<'lua, Self>>(fields: &mut F) {
|
||||
impl elua::Userdata for #wrapper_typename {
|
||||
fn name() -> String {
|
||||
stringify!(#type_name).to_string()
|
||||
}
|
||||
|
||||
fn build<'a>(_: &elua::State, builder: &mut elua::UserdataBuilder<'a, Self>) -> elua::Result<()> {
|
||||
#(#field_get_set_pairs)*
|
||||
|
||||
#matrix_wrapper_fields
|
||||
#vec_wrapper_fields
|
||||
|
||||
#custom_fields
|
||||
}
|
||||
|
||||
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
|
||||
#new_fn_idents
|
||||
|
||||
methods.add_method(#FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
|
||||
builder.method(#FN_NAME_INTERNAL_REFLECT, |_, this, ()| {
|
||||
Ok(crate::ScriptBorrow::from_component::<#path>(Some(this.0.clone())))
|
||||
});
|
||||
|
||||
methods.add_function(#FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| {
|
||||
builder.function(#FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| {
|
||||
Ok(crate::ScriptBorrow::from_component::<#path>(None))
|
||||
});
|
||||
|
||||
|
@ -667,6 +669,8 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
#vec_wrapper_methods
|
||||
|
||||
#custom_methods
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -677,5 +681,20 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
|||
t
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> elua::FromLuaVec<'a> for #wrapper_typename {
|
||||
fn from_lua_value_vec(state: &'a elua::State, mut values: elua::ValueVec<'a>) -> elua::Result<Self> {
|
||||
use elua::FromLua;
|
||||
|
||||
if let Some(val) = values.pop_front() {
|
||||
#wrapper_typename::from_lua(state, val)
|
||||
} else {
|
||||
Err(elua::Error::IncorrectArgCount {
|
||||
arg_expected: 1,
|
||||
arg_count: values.len() as i32,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
use elua::TableProxy;
|
||||
use lyra_ecs::World;
|
||||
use lyra_game::math::{Quat, Transform, Vec3};
|
||||
use crate::lua::wrappers::{LuaQuat, LuaTransform, LuaVec3};
|
||||
use crate::ScriptData;
|
||||
use crate::lua::RegisterLuaType;
|
||||
|
||||
|
@ -13,31 +12,21 @@ impl ScriptApiProvider for LyraMathApiProvider {
|
|||
type ScriptContext = LuaContext;
|
||||
|
||||
fn prepare_world(&mut self, world: &mut World) {
|
||||
// TODO
|
||||
/* world.register_lua_wrapper::<LuaVec3>();
|
||||
world.register_lua_wrapper::<LuaTransform>(); */
|
||||
world.register_lua_table_proxy::<LuaVec3, Vec3>();
|
||||
world.register_lua_table_proxy::<LuaQuat, Quat>();
|
||||
world.register_lua_table_proxy::<LuaTransform, Transform>();
|
||||
world.register_lua_wrapper::<LuaVec3>();
|
||||
world.register_lua_wrapper::<LuaQuat>();
|
||||
world.register_lua_wrapper::<LuaTransform>();
|
||||
}
|
||||
|
||||
fn expose_api(&mut self, _data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||
let ctx = ctx.lock().unwrap();
|
||||
|
||||
let bytes = include_bytes!("../../../scripts/lua/math/vec3.lua");
|
||||
ctx.load("lyra/math/vec2.lua", bytes.as_slice())?.execute(())?;
|
||||
/* let bytes = include_bytes!("../../../scripts/lua/math/transform.lua");
|
||||
ctx.load("lyra/math/transform.lua", bytes.as_slice())?.execute(())?; */
|
||||
|
||||
let bytes = include_bytes!("../../../scripts/lua/math/quat.lua");
|
||||
ctx.load("lyra/math/quat.lua", bytes.as_slice())?.execute(())?;
|
||||
|
||||
let bytes = include_bytes!("../../../scripts/lua/math/transform.lua");
|
||||
ctx.load("lyra/math/transform.lua", bytes.as_slice())?.execute(())?;
|
||||
|
||||
// TODO
|
||||
//let globals = ctx.globals()?;
|
||||
//globals.set("Vec3", elua::Proxy::<LuaVec3>::from(LuaVec3(Vec3::ZERO)))?;
|
||||
//globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
|
||||
//globals.set("Transform", ctx.create_proxy::<LuaTransform>()?)?;
|
||||
let globals = ctx.globals()?;
|
||||
globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
|
||||
globals.set("Quat", ctx.create_proxy::<LuaQuat>()?)?;
|
||||
globals.set("Transform", ctx.create_proxy::<LuaTransform>()?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -49,156 +38,4 @@ impl ScriptApiProvider for LyraMathApiProvider {
|
|||
fn update_script_environment(&mut self, _: crate::ScriptWorldPtr, _: &crate::ScriptData, _: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct LuaVec3(Vec3);
|
||||
|
||||
impl TableProxy for LuaVec3 {
|
||||
fn from_table<'a>(_: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
|
||||
let x: f32 = table.get("x")?;
|
||||
let y: f32 = table.get("y")?;
|
||||
let z: f32 = table.get("z")?;
|
||||
|
||||
Ok(LuaVec3(Vec3 {
|
||||
x,
|
||||
y,
|
||||
z,
|
||||
}))
|
||||
}
|
||||
|
||||
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
|
||||
let globals = state.globals()?;
|
||||
let vec3: elua::Table = globals.get("Vec3")?;
|
||||
let new_fn: elua::Function = vec3.get("new")?;
|
||||
new_fn.exec((vec3, self.0.x, self.0.y, self.0.z))
|
||||
}
|
||||
|
||||
fn table_name() -> String {
|
||||
"Vec3".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct LuaQuat(Quat);
|
||||
|
||||
impl TableProxy for LuaQuat {
|
||||
fn from_table<'a>(_: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
|
||||
let x: f32 = table.get("x")?;
|
||||
let y: f32 = table.get("y")?;
|
||||
let z: f32 = table.get("z")?;
|
||||
let w: f32 = table.get("w")?;
|
||||
|
||||
Ok(LuaQuat(Quat::from_xyzw(x, y, z, w)))
|
||||
}
|
||||
|
||||
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
|
||||
let globals = state.globals()?;
|
||||
let quat: elua::Table = globals.get("Quat")?;
|
||||
let new_fn: elua::Function = quat.get("new")?;
|
||||
new_fn.exec((quat, self.0.x, self.0.y, self.0.z, self.0.w))
|
||||
}
|
||||
|
||||
fn table_name() -> String {
|
||||
"Quat".to_string()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
struct LuaTransform(Transform);
|
||||
|
||||
impl TableProxy for LuaTransform {
|
||||
fn from_table<'a>(lua: &'a elua::State, table: elua::Table<'a>) -> elua::Result<Self> {
|
||||
let translation: elua::Table = table.get("translation")?;
|
||||
let rotation: elua::Table = table.get("rotation")?;
|
||||
let scale: elua::Table = table.get("scale")?;
|
||||
|
||||
let translation = LuaVec3::from_table(lua, translation)?;
|
||||
let rotation = LuaQuat::from_table(lua, rotation)?;
|
||||
let scale = LuaVec3::from_table(lua, scale)?;
|
||||
|
||||
Ok(LuaTransform(Transform::new(translation.0, rotation.0, scale.0)))
|
||||
}
|
||||
|
||||
fn as_table<'a>(&self, state: &'a elua::State) -> elua::Result<elua::Table<'a>> {
|
||||
let globals = state.globals()?;
|
||||
let transform: elua::Table = globals.get("Transform")?;
|
||||
let new_fn: elua::Function = transform.get("new")?;
|
||||
|
||||
let translation = LuaVec3(self.0.translation).as_table(state)?;
|
||||
let rotation = LuaQuat(self.0.rotation).as_table(state)?;
|
||||
let scale = LuaVec3(self.0.scale).as_table(state)?;
|
||||
|
||||
new_fn.exec((transform, translation, rotation, scale))
|
||||
}
|
||||
|
||||
fn table_name() -> String {
|
||||
"Transform".to_string()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* #[derive(Clone, Copy, PartialEq, Debug, lyra_reflect::Reflect)]
|
||||
pub struct LuaVec3(#[reflect(skip)] math::Vec3);
|
||||
|
||||
impl From<math::Vec3> for LuaVec3 {
|
||||
fn from(value: math::Vec3) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::IntoLua<'lua> for LuaVec3 {
|
||||
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
|
||||
let globals = lua.globals();
|
||||
|
||||
let v3 = globals.get::<_, mlua::Table>("Vec3")?;
|
||||
let v3_new = v3.get::<_, mlua::Function>("new")?;
|
||||
v3_new.call::<_, mlua::Table>((v3, self.0.x, self.0.y, self.0.z))
|
||||
.and_then(|t| t.into_lua(lua))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Debug, lyra_reflect::Reflect)]
|
||||
pub struct LuaQuat(#[reflect(skip)] math::Quat);
|
||||
|
||||
impl From<math::Quat> for LuaQuat {
|
||||
fn from(value: math::Quat) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::IntoLua<'lua> for LuaQuat {
|
||||
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
|
||||
let globals = lua.globals();
|
||||
|
||||
let q = globals.get::<_, mlua::Table>("Quat")?;
|
||||
let q_new = q.get::<_, mlua::Function>("new")?;
|
||||
q_new.call::<_, mlua::Table>((q, self.0.x, self.0.y, self.0.z, self.0.w))
|
||||
.and_then(|t| t.into_lua(lua))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug, lyra_reflect::Reflect)]
|
||||
pub struct LuaTransform(#[reflect(skip)] math::Transform);
|
||||
|
||||
impl From<math::Transform> for LuaTransform {
|
||||
fn from(value: math::Transform) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::IntoLua<'lua> for LuaTransform {
|
||||
fn into_lua(self, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<mlua::prelude::LuaValue<'lua>> {
|
||||
let globals = lua.globals();
|
||||
|
||||
let translation = LuaVec3(self.0.translation).into_lua(lua)?;
|
||||
let rot = LuaQuat(self.0.rotation).into_lua(lua)?;
|
||||
let scale = LuaVec3(self.0.scale).into_lua(lua)?;
|
||||
|
||||
let transf = globals.get::<_, mlua::Table>("Transform")?;
|
||||
let transf_new = transf.get::<_, mlua::Function>("new")?;
|
||||
transf_new.call::<_, mlua::Table>((transf, translation, rot, scale))
|
||||
.and_then(|t| t.into_lua(lua))
|
||||
}
|
||||
} */
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
use std::sync::Mutex;
|
||||
|
||||
use elua::{AsLua, StdLibrary};
|
||||
use elua::{AsLua, StdLibraries};
|
||||
|
||||
use crate::{ScriptHost, ScriptError, ScriptWorldPtr, ScriptEntity};
|
||||
|
||||
|
@ -25,12 +25,10 @@ impl ScriptHost for LuaHost {
|
|||
fn load_script(&mut self, script: &[u8], script_data: &crate::ScriptData, providers: &mut crate::ScriptApiProviders<Self>) -> Result<Self::ScriptContext, crate::ScriptError> {
|
||||
let mut ctx = Mutex::new({
|
||||
let s = elua::State::new();
|
||||
s.expose_libraries(&[StdLibrary::Debug, StdLibrary::Package]);
|
||||
s.expose_libraries(StdLibraries::all());
|
||||
s
|
||||
});
|
||||
|
||||
//Mutex::new(elua::State::new_with_libraries(StdLibraries::all()));
|
||||
|
||||
for provider in providers.apis.iter_mut() {
|
||||
provider.expose_api(script_data, &mut ctx)?;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,8 @@ impl elua::Userdata for ScriptWorldPtr {
|
|||
elua::Value::Table(t) => {
|
||||
let name: String = t.get(elua::MetaMethod::Name)?;
|
||||
|
||||
let lookup = world.get_resource::<LuaTableProxyLookup>();
|
||||
let lookup = world.try_get_resource::<LuaTableProxyLookup>()
|
||||
.ok_or(elua::Error::runtime("Unable to lookup table proxy, none were ever registered!"))?;
|
||||
let info = lookup.comp_info_from_name.get(&name)
|
||||
.ok_or_else(||
|
||||
elua::Error::BadArgument {
|
||||
|
|
|
@ -19,7 +19,7 @@ use crate as lyra_scripting;
|
|||
Mod(LuaVec2, f32),
|
||||
Eq, Unm, ToString
|
||||
)
|
||||
);
|
||||
); */
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec3,
|
||||
derives(PartialEq),
|
||||
|
@ -32,7 +32,7 @@ wrap_math_vec_copy!(
|
|||
Mod(LuaVec3, f32),
|
||||
Eq, Unm, ToString
|
||||
)
|
||||
); */
|
||||
);
|
||||
|
||||
|
||||
// =================================================
|
||||
|
@ -396,7 +396,7 @@ wrap_math_vec_copy!(
|
|||
|
||||
|
||||
|
||||
/* wrap_math_vec_copy!(
|
||||
wrap_math_vec_copy!(
|
||||
math::Quat,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
|
@ -409,55 +409,55 @@ wrap_math_vec_copy!(
|
|||
Div(f32),
|
||||
),
|
||||
custom_methods {
|
||||
methods.add_function("new", |_, (x, y, z, w)| {
|
||||
builder.function("new", |_, (x, y, z, w)| {
|
||||
Ok(Self(math::Quat::from_xyzw(x, y, z, w)))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_x", |_, (rad,)| {
|
||||
builder.function("from_rotation_x", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_x(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_y", |_, (rad,)| {
|
||||
builder.function("from_rotation_y", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_y(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_z", |_, (rad,)| {
|
||||
builder.function("from_rotation_z", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_z(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_method("dot", |_, this, (rhs,): (Self,)| {
|
||||
builder.method("dot", |_, this, (rhs,): (Self,)| {
|
||||
Ok(this.dot(rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("length", |_, this, ()| {
|
||||
builder.method("length", |_, this, ()| {
|
||||
Ok(this.length())
|
||||
});
|
||||
|
||||
methods.add_method("length_squared", |_, this, ()| {
|
||||
builder.method("length_squared", |_, this, ()| {
|
||||
Ok(this.length_squared())
|
||||
});
|
||||
|
||||
methods.add_method("normalize", |_, this, ()| {
|
||||
builder.method("normalize", |_, this, ()| {
|
||||
Ok(Self(this.normalize()))
|
||||
});
|
||||
|
||||
methods.add_method("mult_quat", |_, this, (rhs,): (Self,)| {
|
||||
builder.method("mult_quat", |_, this, (rhs,): (Self,)| {
|
||||
Ok(Self(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("mult_vec3", |_, this, (rhs,): (LuaVec3,)| {
|
||||
builder.method("mult_vec3", |_, this, (rhs,): (LuaVec3,)| {
|
||||
Ok(LuaVec3(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
// manually implemented here since it doesn't return `Self`
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| {
|
||||
builder.meta_method(elua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| {
|
||||
Ok(LuaVec3(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
builder.method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.lerp(*rhs, alpha)))
|
||||
});
|
||||
}
|
||||
|
@ -469,111 +469,119 @@ wrap_math_vec_copy!(
|
|||
no_new,
|
||||
metamethods(ToString, Eq),
|
||||
custom_fields {
|
||||
fields.add_field_method_get("translation", |_, this| {
|
||||
builder.field_getter("translation", |_, this| {
|
||||
Ok(LuaVec3(this.translation))
|
||||
});
|
||||
fields.add_field_method_set("translation", |_, this, v: LuaVec3| {
|
||||
builder.field_setter("translation", |_, this, v: LuaVec3| {
|
||||
this.translation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("rotation", |_, this| {
|
||||
builder.field_getter("rotation", |_, this| {
|
||||
Ok(LuaQuat(this.rotation))
|
||||
});
|
||||
fields.add_field_method_set("rotation", |_, this, v: LuaQuat| {
|
||||
builder.field_setter("rotation", |_, this, v: LuaQuat| {
|
||||
this.rotation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("scale", |_, this| {
|
||||
builder.field_getter("scale", |_, this| {
|
||||
Ok(LuaVec3(this.scale))
|
||||
});
|
||||
fields.add_field_method_set("scale", |_, this, v: LuaVec3| {
|
||||
builder.field_setter("scale", |_, this, v: LuaVec3| {
|
||||
this.scale = *v;
|
||||
Ok(())
|
||||
});
|
||||
},
|
||||
custom_methods {
|
||||
methods.add_function("default", |_, ()| {
|
||||
builder.function("default", |_, ()| {
|
||||
Ok(Self(math::Transform::default()))
|
||||
});
|
||||
|
||||
methods.add_function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| {
|
||||
builder.function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| {
|
||||
Ok(Self(math::Transform::new(*pos, *rot, *scale)))
|
||||
});
|
||||
|
||||
methods.add_function("from_translation", |_, (pos,): (LuaVec3,)| {
|
||||
|
||||
builder.function("from_translation", |_, (pos,): (LuaVec3,)| {
|
||||
Ok(Self(math::Transform::from_translation(*pos)))
|
||||
});
|
||||
|
||||
methods.add_function("from_xyz", |_, (x, y, z)| {
|
||||
|
||||
builder.function("from_xyz", |_, (x, y, z)| {
|
||||
Ok(Self(math::Transform::from_xyz(x, y, z)))
|
||||
});
|
||||
|
||||
methods.add_method("forward", |_, this, ()| {
|
||||
builder.method("clone", |_, this, ()| {
|
||||
Ok(this.clone())
|
||||
});
|
||||
|
||||
builder.method("forward", |_, this, ()| {
|
||||
Ok(LuaVec3(this.forward()))
|
||||
});
|
||||
|
||||
methods.add_method("left", |_, this, ()| {
|
||||
builder.method("left", |_, this, ()| {
|
||||
Ok(LuaVec3(this.left()))
|
||||
});
|
||||
|
||||
methods.add_method("up", |_, this, ()| {
|
||||
builder.method("up", |_, this, ()| {
|
||||
Ok(LuaVec3(this.up()))
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate", |_, this, (quat,): (LuaQuat,)| {
|
||||
builder.method_mut("rotate", |_, this, (quat,): (LuaQuat,)| {
|
||||
this.rotate(*quat);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_x", |_, this, (deg,): (f32,)| {
|
||||
builder.method_mut("rotate_x", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_x(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_y", |_, this, (deg,): (f32,)| {
|
||||
builder.method_mut("rotate_y", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_y(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_z", |_, this, (deg,): (f32,)| {
|
||||
builder.method_mut("rotate_z", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_z(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_x_rad", |_, this, (rad,): (f32,)| {
|
||||
builder.method_mut("rotate_x_rad", |_, this, (rad,): (f32,)| {
|
||||
this.rotate_x(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_y_rad", |_, this, (rad,): (f32,)| {
|
||||
builder.method_mut("rotate_y_rad", |_, this, (rad,): (f32,)| {
|
||||
this.rotate_y(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_z_rad", |_, this, (rad,): (f32,)| {
|
||||
builder.method_mut("rotate_z_rad", |_, this, (rad,): (f32,)| {
|
||||
this.rotate_z(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
builder.method_mut("translate", |_, this, (x, y, z): (f32, f32, f32)| {
|
||||
this.translate(x, y, z);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
builder.method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.lerp(*rhs, alpha)))
|
||||
});
|
||||
|
||||
// rotate a transform
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (quat,): (LuaQuat,)| {
|
||||
builder.meta_method(elua::MetaMethod::Mul, |_, this, (quat,): (LuaQuat,)| {
|
||||
let mut t = *this;
|
||||
t.rotation *= *quat;
|
||||
Ok(t)
|
||||
});
|
||||
|
||||
// move a transform
|
||||
methods.add_meta_method(mlua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| {
|
||||
builder.meta_method(elua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| {
|
||||
let mut t = *this;
|
||||
t.translation += *pos;
|
||||
Ok(t)
|
||||
});
|
||||
}
|
||||
);
|
||||
*/
|
|
@ -12,9 +12,11 @@ mkShell rec {
|
|||
heaptrack
|
||||
mold
|
||||
udev
|
||||
lua5_4_compat
|
||||
];
|
||||
buildInputs = [
|
||||
udev alsa-lib vulkan-loader
|
||||
udev alsa-lib libGL gcc
|
||||
vulkan-loader vulkan-headers vulkan-tools
|
||||
xorg.libX11 xorg.libXcursor xorg.libXi xorg.libXrandr # To use the x11 feature
|
||||
libxkbcommon wayland # To use the wayland feature
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue