Create an early scripting engine #2
|
@ -15,9 +15,12 @@ end ]]
|
|||
function on_update()
|
||||
--print("Lua's update function was called")
|
||||
|
||||
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.0008, 0)
|
||||
t.translation = t.translation + (Vec3.new(0, 0.5, 0) * dt:get())
|
||||
|
||||
return t
|
||||
end, Transform)
|
||||
|
|
|
@ -6,7 +6,7 @@ impl<T: 'static> ResourceObject for T {}
|
|||
|
||||
/// A type erased storage for a Resource.
|
||||
pub struct ResourceData {
|
||||
data: Box<RefCell<dyn Any>>,
|
||||
pub(crate) data: Box<RefCell<dyn Any>>,
|
||||
type_id: TypeId,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::{collections::{HashMap, VecDeque}, any::TypeId, cell::{Ref, RefMut}, ptr::NonNull};
|
||||
|
||||
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, query::{Query, ViewIter, View, AsQuery}, resource::ResourceData, query::{dynamic::DynamicView, ViewOne}, ComponentInfo, DynTypeId, TickTracker, Tick};
|
||||
use crate::{archetype::{ArchetypeId, Archetype}, bundle::Bundle, query::{Query, ViewIter, View, AsQuery}, resource::ResourceData, query::{dynamic::DynamicView, ViewOne}, ComponentInfo, DynTypeId, TickTracker, Tick, ResourceObject};
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct EntityId(pub u64);
|
||||
|
@ -306,6 +306,12 @@ impl World {
|
|||
pub fn tick_tracker(&self) -> &TickTracker {
|
||||
&self.tracker
|
||||
}
|
||||
|
||||
/// Attempts to find a resource in the world and returns a NonNull pointer to it
|
||||
pub unsafe fn try_get_resource_ptr<T: ResourceObject>(&self) -> Option<NonNull<T>> {
|
||||
self.resources.get(&TypeId::of::<T>())
|
||||
.map(|d| unsafe { NonNull::new_unchecked(d.data.as_ptr() as *mut T) })
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use instant::Instant;
|
||||
use lyra_ecs::{Component, world::World};
|
||||
use lyra_reflect::Reflect;
|
||||
|
||||
use crate::{plugin::Plugin, game::GameStages};
|
||||
|
||||
#[derive(Clone, Component)]
|
||||
pub struct DeltaTime(f32, Option<Instant>);
|
||||
#[derive(Clone, Component, Default, Reflect)]
|
||||
pub struct DeltaTime(f32, #[reflect(skip)] Option<Instant>);
|
||||
|
||||
impl std::ops::Deref for DeltaTime {
|
||||
type Target = f32;
|
||||
|
|
|
@ -26,6 +26,7 @@ pub mod scene;
|
|||
pub use lyra_resource as assets;
|
||||
pub use lyra_ecs as ecs;
|
||||
pub use lyra_math as math;
|
||||
pub use lyra_reflect as reflect;
|
||||
|
||||
#[cfg(feature = "scripting")]
|
||||
pub use lyra_scripting as script;
|
||||
|
|
|
@ -0,0 +1,70 @@
|
|||
use std::{any::TypeId, cell::{Ref, RefMut}};
|
||||
|
||||
use lyra_ecs::{Component, ComponentInfo, World, Entity, DynamicBundle};
|
||||
|
||||
use crate::{Reflect, FromType};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectedComponent {
|
||||
pub type_id: TypeId,
|
||||
pub info: ComponentInfo,
|
||||
//value: Value,
|
||||
//from_world:
|
||||
|
||||
//from_world: for<'a> fn (world: &'a mut World) -> Box<dyn Reflect>,
|
||||
/// Inserts component into entity in the world
|
||||
fn_insert: for<'a> fn (world: &'a mut World, entity: Entity, component: &dyn Reflect),
|
||||
/// Inserts component into a bundle
|
||||
fn_bundle_insert: for<'a> fn (dynamic_bundle: &'a mut DynamicBundle, component: &dyn Reflect),
|
||||
fn_reflect: for<'a> fn (world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>>,
|
||||
fn_reflect_mut: for<'a> fn (world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>>,
|
||||
}
|
||||
|
||||
impl ReflectedComponent {
|
||||
/// Insert the reflected component into an entity.
|
||||
pub fn insert(&self, world: &mut World, entity: Entity, component: &dyn Reflect) {
|
||||
(self.fn_insert)(world, entity, component);
|
||||
}
|
||||
|
||||
/// Insert this component into a DynamicBundle
|
||||
pub fn bundle_insert(&self, dynamic_bundle: &mut DynamicBundle, component: &dyn Reflect) {
|
||||
(self.fn_bundle_insert)(dynamic_bundle, component)
|
||||
}
|
||||
|
||||
/// Retrieves a reflected component from an entity.
|
||||
pub fn reflect<'a>(&'a self, world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>> {
|
||||
(self.fn_reflect)(world, entity)
|
||||
}
|
||||
|
||||
/// Retrieves a reflected component from an entity.
|
||||
pub fn reflect_mut<'a>(&'a mut self, world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>> {
|
||||
(self.fn_reflect_mut)(world, entity)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Component + Reflect + Default> FromType<C> for ReflectedComponent {
|
||||
fn from_type() -> Self {
|
||||
ReflectedComponent {
|
||||
type_id: TypeId::of::<C>(),
|
||||
info: ComponentInfo::new::<C>(),
|
||||
fn_insert: |world: &mut World, entity: Entity, component: &dyn Reflect| {
|
||||
let mut c = C::default();
|
||||
c.apply(component);
|
||||
world.insert(entity, (c,));
|
||||
},
|
||||
fn_bundle_insert: |bundle: &mut DynamicBundle, component: &dyn Reflect| {
|
||||
let mut c = C::default();
|
||||
c.apply(component);
|
||||
bundle.push(c);
|
||||
},
|
||||
fn_reflect: |world: &World, entity: Entity| {
|
||||
world.view_one::<&C>(entity)
|
||||
.get().map(|c| c as Ref<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_mut: |world: &mut World, entity: Entity| {
|
||||
world.view_one::<&mut C>(entity)
|
||||
.get().map(|c| c as RefMut<dyn Reflect>)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,6 +36,12 @@ pub use dynamic_tuple::*;
|
|||
pub mod reflected_field;
|
||||
pub use reflected_field::*;
|
||||
|
||||
pub mod component;
|
||||
pub use component::*;
|
||||
|
||||
pub mod resource;
|
||||
pub use resource::*;
|
||||
|
||||
pub mod util;
|
||||
pub mod field;
|
||||
pub use field::*;
|
||||
|
@ -237,67 +243,48 @@ pub trait FromType<T> {
|
|||
fn from_type() -> Self;
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectedComponent {
|
||||
pub type_id: TypeId,
|
||||
pub info: ComponentInfo,
|
||||
//value: Value,
|
||||
//from_world:
|
||||
|
||||
//from_world: for<'a> fn (world: &'a mut World) -> Box<dyn Reflect>,
|
||||
/// Inserts component into entity in the world
|
||||
fn_insert: for<'a> fn (world: &'a mut World, entity: Entity, component: &dyn Reflect),
|
||||
/// Inserts component into a bundle
|
||||
fn_bundle_insert: for<'a> fn (dynamic_bundle: &'a mut DynamicBundle, component: &dyn Reflect),
|
||||
fn_reflect: for<'a> fn (world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>>,
|
||||
fn_reflect_mut: for<'a> fn (world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>>,
|
||||
pub trait ReflectWorldExt {
|
||||
/// Retrieves the type registry from the world.
|
||||
fn get_type_registry(&self) -> Ref<TypeRegistry>;
|
||||
/// Retrieves the type registry mutably from the world.
|
||||
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry>;
|
||||
/// Get a registered type from the type registry. Returns `None` if the type is not registered
|
||||
fn get_type<T>(&self, type_id: TypeId) -> Option<Ref<RegisteredType>>;
|
||||
/// Get a mutable registered type from the type registry in the world. returns `None` if the type is not registered.
|
||||
fn get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>>;
|
||||
/// Get a registered type, or register a new type and return it.
|
||||
fn get_type_or_default<T>(&self, type_id: TypeId) -> RefMut<RegisteredType>;
|
||||
}
|
||||
|
||||
impl ReflectedComponent {
|
||||
/// Insert the reflected component into an entity.
|
||||
pub fn insert(&self, world: &mut World, entity: Entity, component: &dyn Reflect) {
|
||||
(self.fn_insert)(world, entity, component);
|
||||
impl ReflectWorldExt for World {
|
||||
fn get_type_registry(&self) -> Ref<TypeRegistry> {
|
||||
self.get_resource::<TypeRegistry>()
|
||||
}
|
||||
|
||||
/// Insert this component into a DynamicBundle
|
||||
pub fn bundle_insert(&self, dynamic_bundle: &mut DynamicBundle, component: &dyn Reflect) {
|
||||
(self.fn_bundle_insert)(dynamic_bundle, component)
|
||||
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry> {
|
||||
self.get_resource_mut::<TypeRegistry>()
|
||||
}
|
||||
|
||||
/// Retrieves a reflected component from an entity.
|
||||
pub fn reflect<'a>(&'a self, world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>> {
|
||||
(self.fn_reflect)(world, entity)
|
||||
fn get_type<T>(&self, type_id: TypeId) -> Option<Ref<RegisteredType>> {
|
||||
let r = self.get_resource::<TypeRegistry>();
|
||||
if r.has_type(type_id) {
|
||||
Some(Ref::map(r, |tr| tr.get_type(type_id).unwrap()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// Retrieves a reflected component from an entity.
|
||||
pub fn reflect_mut<'a>(&'a mut self, world: &'a mut World, entity: Entity) -> Option<RefMut<'a, dyn Reflect>> {
|
||||
(self.fn_reflect_mut)(world, entity)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Component + Reflect + Default> FromType<C> for ReflectedComponent {
|
||||
fn from_type() -> Self {
|
||||
ReflectedComponent {
|
||||
type_id: TypeId::of::<C>(),
|
||||
info: ComponentInfo::new::<C>(),
|
||||
fn_insert: |world: &mut World, entity: Entity, component: &dyn Reflect| {
|
||||
let mut c = C::default();
|
||||
c.apply(component);
|
||||
world.insert(entity, (c,));
|
||||
},
|
||||
fn_bundle_insert: |bundle: &mut DynamicBundle, component: &dyn Reflect| {
|
||||
let mut c = C::default();
|
||||
c.apply(component);
|
||||
bundle.push(c);
|
||||
},
|
||||
fn_reflect: |world: &World, entity: Entity| {
|
||||
world.view_one::<&C>(entity)
|
||||
.get().map(|c| c as Ref<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_mut: |world: &mut World, entity: Entity| {
|
||||
world.view_one::<&mut C>(entity)
|
||||
.get().map(|c| c as RefMut<dyn Reflect>)
|
||||
},
|
||||
}
|
||||
fn get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>> {
|
||||
let r = self.get_resource_mut::<TypeRegistry>();
|
||||
if r.has_type(type_id) {
|
||||
Some(RefMut::map(r, |tr| tr.get_type_mut(type_id).unwrap()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_type_or_default<T>(&self, type_id: TypeId) -> RefMut<RegisteredType> {
|
||||
let r = self.get_resource_mut::<TypeRegistry>();
|
||||
RefMut::map(r, |tr| tr.get_type_or_default(type_id))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
use std::{any::TypeId, cell::{Ref, RefMut}, ptr::NonNull};
|
||||
|
||||
use lyra_ecs::{World, ResourceObject};
|
||||
|
||||
use crate::{Reflect, FromType};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectedResource {
|
||||
pub type_id: TypeId,
|
||||
|
||||
fn_reflect: for<'a> fn (world: &'a World) -> Option<Ref<'a, dyn Reflect>>,
|
||||
fn_reflect_mut: for<'a> fn (world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>>,
|
||||
fn_reflect_ptr: fn (world: &mut World) -> Option<NonNull<u8>>,
|
||||
}
|
||||
|
||||
impl ReflectedResource {
|
||||
/// Retrieves the reflected resource from the world.
|
||||
pub fn reflect<'a>(&self, world: &'a World) -> Option<Ref<'a, dyn Reflect>> {
|
||||
(self.fn_reflect)(world)
|
||||
}
|
||||
|
||||
/// Retrieves a mutable reflected resource from the world.
|
||||
pub fn reflect_mut<'a>(&self, world: &'a mut World) -> Option<RefMut<'a, dyn Reflect>> {
|
||||
(self.fn_reflect_mut)(world)
|
||||
}
|
||||
|
||||
pub fn reflect_ptr(&self, world: &mut World) -> Option<NonNull<u8>> {
|
||||
(self.fn_reflect_ptr)(world)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: ResourceObject + Reflect> FromType<T> for ReflectedResource {
|
||||
fn from_type() -> Self {
|
||||
Self {
|
||||
type_id: TypeId::of::<T>(),
|
||||
fn_reflect: |world: &World| {
|
||||
world.try_get_resource::<T>()
|
||||
.map(|r| r as Ref<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_mut: |world: &mut World| {
|
||||
world.try_get_resource_mut::<T>()
|
||||
.map(|r| r as RefMut<dyn Reflect>)
|
||||
},
|
||||
fn_reflect_ptr: |world: &mut World| unsafe {
|
||||
world.try_get_resource_ptr::<T>()
|
||||
.map(|ptr| ptr.cast::<u8>())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,9 @@
|
|||
pub mod lua;
|
||||
|
||||
pub mod world;
|
||||
use lyra_ecs::Component;
|
||||
use std::any::TypeId;
|
||||
|
||||
use lyra_ecs::{Component, ResourceObject};
|
||||
pub use world::*;
|
||||
|
||||
pub mod wrap;
|
||||
|
@ -16,17 +18,19 @@ pub use script::*;
|
|||
|
||||
use lyra_game::game::Game;
|
||||
|
||||
// required for some proc macros :(
|
||||
#[allow(unused_imports)]
|
||||
pub(crate) mod lyra_engine {
|
||||
pub use lyra_ecs as ecs;
|
||||
pub use lyra_reflect as reflect;
|
||||
}
|
||||
|
||||
use lyra_reflect::{ReflectedComponent, Reflect, FromType};
|
||||
use lyra_reflect::{ReflectedComponent, Reflect, FromType, ReflectedResource};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ReflectBranch {
|
||||
Component(ReflectedComponent),
|
||||
Resource(ReflectedResource),
|
||||
}
|
||||
|
||||
impl ReflectBranch {
|
||||
|
@ -37,13 +41,38 @@ impl ReflectBranch {
|
|||
pub fn as_component_unchecked(&self) -> &ReflectedComponent {
|
||||
match self {
|
||||
ReflectBranch::Component(c) => c,
|
||||
//_ => panic!("`self` is not an instance of `ReflectBranch::Component`")
|
||||
_ => panic!("`self` is not an instance of `ReflectBranch::Component`")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a boolean indicating if `self` is a reflection of a Component.
|
||||
pub fn is_component(&self) -> bool {
|
||||
matches!(self, ReflectBranch::Component(_))
|
||||
}
|
||||
|
||||
/// Gets self as a [`ReflectedResource`].
|
||||
///
|
||||
/// # Panics
|
||||
/// If `self` is not a variant of [`ReflectBranch::Resource`].
|
||||
pub fn as_resource_unchecked(&self) -> &ReflectedResource {
|
||||
match self {
|
||||
ReflectBranch::Resource(v) => v,
|
||||
_ => panic!("`self` is not an instance of `ReflectBranch::Component`")
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a boolean indicating if `self` is a reflection of a Resource.
|
||||
pub fn is_resource(&self) -> bool {
|
||||
matches!(self, ReflectBranch::Resource(_))
|
||||
}
|
||||
|
||||
/// Returns the type id of the reflected thing
|
||||
pub fn reflect_type_id(&self) -> TypeId {
|
||||
match self {
|
||||
ReflectBranch::Component(c) => c.type_id,
|
||||
ReflectBranch::Resource(r) => r.type_id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ScriptBorrow {
|
||||
|
@ -63,6 +92,7 @@ impl Clone for ScriptBorrow {
|
|||
}
|
||||
|
||||
impl ScriptBorrow {
|
||||
/// Creates a ScriptBorrow from a Component
|
||||
pub fn from_component<T>(data: Option<T>) -> Self
|
||||
where
|
||||
T: Reflect + Component + Default + 'static
|
||||
|
@ -74,10 +104,24 @@ impl ScriptBorrow {
|
|||
data,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a ScriptBorrow from a Resource.
|
||||
pub fn from_resource<T>(data: Option<T>) -> Self
|
||||
where
|
||||
T: Reflect + ResourceObject + Default + 'static
|
||||
{
|
||||
let data = data.map(|d| Box::new(d) as Box<(dyn Reflect + 'static)>);
|
||||
|
||||
Self {
|
||||
reflect_branch: ReflectBranch::Resource(<ReflectedResource as FromType<T>>::from_type()),
|
||||
data,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// An extension trait that adds some helpful methods that makes it easier to do scripting things
|
||||
pub trait GameScriptExt {
|
||||
/// A helper method for adding a ScriptApiProvider into the world.
|
||||
fn add_script_api_provider<T, P>(&mut self, provider: P)
|
||||
where
|
||||
T: ScriptHost,
|
||||
|
|
|
@ -5,7 +5,7 @@ pub use dynamic_iter::*;
|
|||
pub mod world;
|
||||
use lyra_game::{game::GameStages, plugin::Plugin};
|
||||
use lyra_resource::ResourceManager;
|
||||
use tracing::{debug, error, trace, debug_span};
|
||||
use tracing::{debug, debug_span, error, trace};
|
||||
pub use world::*;
|
||||
|
||||
pub mod script;
|
||||
|
@ -17,6 +17,9 @@ pub use loader::*;
|
|||
pub mod providers;
|
||||
pub mod wrappers;
|
||||
|
||||
pub mod proxy;
|
||||
pub use proxy::*;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
|
@ -43,24 +46,22 @@ use crate::{
|
|||
use self::providers::{LyraEcsApiProvider, LyraMathApiProvider, UtilityApiProvider};
|
||||
|
||||
pub trait RegisterLuaType {
|
||||
/// Register a lua type that **is not wrapped**.
|
||||
fn register_lua_type<'a, T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData>(
|
||||
&mut self,
|
||||
);
|
||||
/// Register a type to lua that **is not wrapped**.
|
||||
fn register_lua_type<'a, T>(&mut self)
|
||||
where
|
||||
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData;
|
||||
|
||||
/// Registers a wrapped lua type.
|
||||
/// You provide the wrapper as `W`, and the type that the wrapper wraps, as `T`.
|
||||
fn register_lua_wrapper<
|
||||
'a,
|
||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData,
|
||||
>(
|
||||
&mut self,
|
||||
);
|
||||
fn register_lua_wrapper<'a, W>(&mut self)
|
||||
where
|
||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData;
|
||||
}
|
||||
|
||||
impl RegisterLuaType for World {
|
||||
fn register_lua_type<'a, T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData>(
|
||||
&mut self,
|
||||
) {
|
||||
fn register_lua_type<'a, T>(&mut self)
|
||||
where
|
||||
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||
{
|
||||
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
||||
|
||||
let type_id = TypeId::of::<T>();
|
||||
|
@ -70,12 +71,10 @@ impl RegisterLuaType for World {
|
|||
//reg_type.add_data(<ReflectedComponent as FromType<T>>::from_type());
|
||||
}
|
||||
|
||||
fn register_lua_wrapper<
|
||||
'a,
|
||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData,
|
||||
>(
|
||||
&mut self,
|
||||
) {
|
||||
fn register_lua_wrapper<'a, W>(&mut self)
|
||||
where
|
||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||
{
|
||||
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
||||
|
||||
let reg_type = registry.get_type_or_default(W::wrapped_type_id());
|
||||
|
@ -99,88 +98,6 @@ pub fn reflect_user_data(ud: &mlua::AnyUserData) -> ScriptBorrow {
|
|||
.expect("Type does not implement '__internal_reflect' properly")
|
||||
}
|
||||
|
||||
pub trait LuaWrapper {
|
||||
/// The type id of the wrapped type.
|
||||
fn wrapped_type_id() -> TypeId;
|
||||
}
|
||||
|
||||
pub trait LuaProxy {
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::AnyUserData<'lua>>;
|
||||
fn apply(
|
||||
lua: &mlua::Lua,
|
||||
this: &mut dyn Reflect,
|
||||
apply: &mlua::AnyUserData,
|
||||
) -> mlua::Result<()>;
|
||||
}
|
||||
|
||||
impl<'a, T: Reflect + Clone + mlua::FromLua<'a> + mlua::UserData> LuaProxy for T {
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::AnyUserData<'lua>> {
|
||||
let this = this.as_any().downcast_ref::<T>().unwrap();
|
||||
lua.create_userdata(this.clone())
|
||||
}
|
||||
|
||||
fn apply(
|
||||
_lua: &mlua::Lua,
|
||||
this: &mut dyn Reflect,
|
||||
apply: &mlua::AnyUserData,
|
||||
) -> mlua::Result<()> {
|
||||
let this = this.as_any_mut().downcast_mut::<T>().unwrap();
|
||||
let apply = apply.borrow::<T>()?;
|
||||
|
||||
*this = apply.clone();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectLuaProxy {
|
||||
fn_as_uservalue:
|
||||
for<'a> fn(lua: &'a Lua, this_ptr: NonNull<u8>) -> mlua::Result<mlua::AnyUserData<'a>>,
|
||||
fn_apply: for<'a> fn(
|
||||
lua: &'a Lua,
|
||||
this_ptr: NonNull<u8>,
|
||||
apply: &'a mlua::AnyUserData<'a>,
|
||||
) -> mlua::Result<()>,
|
||||
}
|
||||
|
||||
impl<'a, T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData> FromType<T>
|
||||
for ReflectLuaProxy
|
||||
{
|
||||
fn from_type() -> Self {
|
||||
Self {
|
||||
fn_as_uservalue: |lua, this| -> mlua::Result<mlua::AnyUserData> {
|
||||
let this = unsafe { this.cast::<T>().as_ref() };
|
||||
<T as LuaProxy>::as_lua_value(lua, this)
|
||||
},
|
||||
fn_apply: |lua, ptr, apply| {
|
||||
let this = unsafe { ptr.cast::<T>().as_mut() };
|
||||
<T as LuaProxy>::apply(lua, this, apply)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptDynamicBundle {
|
||||
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
mlua::Value::Nil => Err(mlua::Error::FromLuaConversionError {
|
||||
from: "Nil",
|
||||
to: "DynamicBundle",
|
||||
message: Some("Value was nil".to_string()),
|
||||
}),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::UserData for ScriptDynamicBundle {
|
||||
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_function("new", |_, ()| Ok(ScriptDynamicBundle(DynamicBundle::new())));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use crate::{lua::LuaContext, ScriptApiProvider, ScriptWorldPtr, ScriptDynamicBundle, ScriptData};
|
||||
use crate::{lua::{LuaContext, wrappers::LuaDeltaTime, RegisterLuaType}, ScriptApiProvider, ScriptWorldPtr, ScriptDynamicBundle, ScriptData};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct LyraEcsApiProvider;
|
||||
|
@ -6,6 +6,10 @@ pub struct LyraEcsApiProvider;
|
|||
impl ScriptApiProvider for LyraEcsApiProvider {
|
||||
type ScriptContext = LuaContext;
|
||||
|
||||
fn prepare_world(&mut self, world: &mut lyra_ecs::World) {
|
||||
world.register_lua_wrapper::<LuaDeltaTime>();
|
||||
}
|
||||
|
||||
fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||
let ctx = ctx.lock().unwrap();
|
||||
|
||||
|
@ -13,6 +17,8 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
|||
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
||||
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
||||
|
||||
globals.set("DeltaTime", ctx.create_proxy::<LuaDeltaTime>()?)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,92 @@
|
|||
use std::{any::TypeId, ptr::NonNull};
|
||||
|
||||
use lyra_reflect::{Reflect, FromType};
|
||||
|
||||
use crate::ScriptDynamicBundle;
|
||||
|
||||
pub trait LuaWrapper {
|
||||
/// The type id of the wrapped type.
|
||||
fn wrapped_type_id() -> TypeId;
|
||||
}
|
||||
|
||||
pub trait LuaProxy {
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::AnyUserData<'lua>>;
|
||||
|
||||
fn apply(
|
||||
lua: &mlua::Lua,
|
||||
this: &mut dyn Reflect,
|
||||
apply: &mlua::AnyUserData,
|
||||
) -> mlua::Result<()>;
|
||||
}
|
||||
|
||||
impl<'a, T> LuaProxy for T
|
||||
where
|
||||
T: Reflect + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||
{
|
||||
fn as_lua_value<'lua>(
|
||||
lua: &'lua mlua::Lua,
|
||||
this: &dyn Reflect,
|
||||
) -> mlua::Result<mlua::AnyUserData<'lua>> {
|
||||
let this = this.as_any().downcast_ref::<T>().unwrap();
|
||||
lua.create_userdata(this.clone())
|
||||
}
|
||||
|
||||
fn apply(
|
||||
_lua: &mlua::Lua,
|
||||
this: &mut dyn Reflect,
|
||||
apply: &mlua::AnyUserData,
|
||||
) -> mlua::Result<()> {
|
||||
let this = this.as_any_mut().downcast_mut::<T>().unwrap();
|
||||
let apply = apply.borrow::<T>()?;
|
||||
|
||||
*this = apply.clone();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ReflectLuaProxy {
|
||||
pub fn_as_uservalue:
|
||||
for<'a> fn(lua: &'a mlua::Lua, this_ptr: NonNull<u8>) -> mlua::Result<mlua::AnyUserData<'a>>,
|
||||
pub fn_apply: for<'a> fn(
|
||||
lua: &'a mlua::Lua,
|
||||
this_ptr: NonNull<u8>,
|
||||
apply: &'a mlua::AnyUserData<'a>,
|
||||
) -> mlua::Result<()>,
|
||||
}
|
||||
|
||||
impl<'a, T> FromType<T> for ReflectLuaProxy
|
||||
where
|
||||
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||
{
|
||||
fn from_type() -> Self {
|
||||
Self {
|
||||
fn_as_uservalue: |lua, this| -> mlua::Result<mlua::AnyUserData> {
|
||||
let this = unsafe { this.cast::<T>().as_ref() };
|
||||
<T as LuaProxy>::as_lua_value(lua, this)
|
||||
},
|
||||
fn_apply: |lua, ptr, apply| {
|
||||
let this = unsafe { ptr.cast::<T>().as_mut() };
|
||||
<T as LuaProxy>::apply(lua, this, apply)
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for ScriptDynamicBundle {
|
||||
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
mlua::Value::Nil => Err(mlua::Error::FromLuaConversionError {
|
||||
from: "Nil",
|
||||
to: "DynamicBundle",
|
||||
message: Some("Value was nil".to_string()),
|
||||
}),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
use std::{sync::Arc, ptr::NonNull};
|
||||
use std::{sync::Arc, ptr::NonNull, any::Any, ops::Deref};
|
||||
|
||||
use lyra_ecs::query::dynamic::QueryDynamicType;
|
||||
use lyra_reflect::TypeRegistry;
|
||||
use lyra_reflect::{TypeRegistry, ReflectWorldExt, RegisteredType};
|
||||
use mlua::{AnyUserDataExt, IntoLua, IntoLuaMulti};
|
||||
|
||||
use crate::{ScriptWorldPtr, ScriptEntity, ScriptDynamicBundle, ScriptBorrow};
|
||||
|
@ -159,5 +159,26 @@ impl mlua::UserData for ScriptWorldPtr {
|
|||
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("resource", |lua, this, (ty,): (mlua::AnyUserData,)| {
|
||||
let reflect = ty
|
||||
.call_function::<_, ScriptBorrow>(FN_NAME_INTERNAL_REFLECT_TYPE, ())
|
||||
.expect("Type does not implement 'reflect_type' properly");
|
||||
|
||||
let res = reflect.reflect_branch.as_resource_unchecked();
|
||||
if let Some(res_ptr) = res.reflect_ptr(this.as_mut()) {
|
||||
//.expect("Failed to find resource pointer in world!");
|
||||
let reg_type = this.as_ref().get_type::<RegisteredType>(reflect.reflect_branch.reflect_type_id())
|
||||
.unwrap();
|
||||
let proxy = reg_type.get_data::<ReflectLuaProxy>()
|
||||
.expect("Type does not have ReflectLuaProxy as a TypeData");
|
||||
|
||||
(proxy.fn_as_uservalue)(lua, res_ptr)
|
||||
.and_then(|ud| ud.into_lua(lua))
|
||||
} else {
|
||||
// if the resource is not found in the world, return nil
|
||||
Ok(mlua::Value::Nil)
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
use std::{ops::Deref, any::TypeId};
|
||||
|
||||
use lyra_game::DeltaTime;
|
||||
use crate::{lyra_engine, lua::{FN_NAME_INTERNAL_REFLECT_TYPE, LuaWrapper}, ScriptBorrow};
|
||||
|
||||
#[derive(Clone, lyra_reflect::Reflect, Default)]
|
||||
pub struct LuaDeltaTime(#[reflect(skip)] pub(crate) DeltaTime);
|
||||
|
||||
impl std::ops::Deref for LuaDeltaTime {
|
||||
type Target = DeltaTime;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for LuaDeltaTime {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<'lua> mlua::FromLua<'lua> for LuaDeltaTime {
|
||||
fn from_lua(value: mlua::prelude::LuaValue<'lua>, lua: &'lua mlua::prelude::Lua) -> mlua::prelude::LuaResult<Self> {
|
||||
match value {
|
||||
mlua::Value::UserData(ud) => Ok(ud.borrow::<Self>()?.clone()),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::UserData for LuaDeltaTime {
|
||||
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||
methods.add_method("get", |_, this, ()| {
|
||||
Ok(*this.0.deref())
|
||||
});
|
||||
|
||||
methods.add_meta_method(mlua::MetaMethod::ToString, |_, this, ()| {
|
||||
Ok(format!("{}", this.0.deref()))
|
||||
});
|
||||
|
||||
methods.add_function(FN_NAME_INTERNAL_REFLECT_TYPE, |_, ()| {
|
||||
Ok(ScriptBorrow::from_resource::<DeltaTime>(None))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl LuaWrapper for LuaDeltaTime {
|
||||
fn wrapped_type_id() -> std::any::TypeId {
|
||||
TypeId::of::<DeltaTime>()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,605 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use crate::lyra_engine;
|
||||
use lyra_game::math;
|
||||
use lyra_scripting_derive::wrap_math_vec_copy;
|
||||
|
||||
use crate as lyra_scripting;
|
||||
|
||||
// f32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec2,
|
||||
derives(PartialEq),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaVec2, f32),
|
||||
Sub(LuaVec2, f32),
|
||||
Div(LuaVec2, f32),
|
||||
Mul(LuaVec2, f32),
|
||||
Mod(LuaVec2, f32),
|
||||
Eq,
|
||||
Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec3,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec3),
|
||||
Sub(LuaVec3, f32),
|
||||
Div(LuaVec3, f32),
|
||||
//Mul(LuaVec3, f32),
|
||||
Mod(LuaVec3, f32),
|
||||
Eq, Unm, ToString,
|
||||
),
|
||||
custom_methods {
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (v,): (mlua::Value,)| {
|
||||
match v {
|
||||
mlua::Value::Number(n) => {
|
||||
Ok(Self(this.0 * (n as f32)))
|
||||
},
|
||||
mlua::Value::UserData(ud) => {
|
||||
if let Ok(other_this) = ud.borrow::<Self>() {
|
||||
Ok(Self(this.0 * other_this.0))
|
||||
} else {
|
||||
if let Ok(mt) = ud.get_metatable() {
|
||||
if let Ok(name) = mt.get::<String>("__name") {
|
||||
return Err(mlua::Error::BadArgument {
|
||||
to: Some("LuaVec3.__mul".to_string()),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(mlua::Error::RuntimeError(
|
||||
format!("cannot multiply with unknown userdata named {}", name)
|
||||
))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Err(mlua::Error::BadArgument {
|
||||
to: Some("LuaVec3.__mul".to_string()),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(
|
||||
mlua::Error::runtime("cannot multiply with unknown userdata")
|
||||
)
|
||||
})
|
||||
}
|
||||
},
|
||||
_ => Err(mlua::Error::BadArgument {
|
||||
to: Some("LuaVec3.__mul".to_string()),
|
||||
pos: 2,
|
||||
name: Some("rhs".to_string()),
|
||||
cause: Arc::new(
|
||||
mlua::Error::RuntimeError(format!("cannot multiply with {}", v.type_name()))
|
||||
)
|
||||
})
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
/* wrap_math_vec_copy!(
|
||||
math::Vec3A,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec3A, f32),
|
||||
Sub(LuaVec3A, f32),
|
||||
Div(LuaVec3A, f32),
|
||||
Mul(LuaVec3A, f32),
|
||||
Mod(LuaVec3A, f32),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec4,
|
||||
derives(PartialEq),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec4, f32),
|
||||
Sub(LuaVec4, f32),
|
||||
Div(LuaVec4, f32),
|
||||
Mul(LuaVec4, f32),
|
||||
Mod(LuaVec4, f32),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
|
||||
// f64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec2,
|
||||
derives(PartialEq),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaDVec2, f64),
|
||||
Sub(LuaDVec2, f64),
|
||||
Div(LuaDVec2, f64),
|
||||
Mul(LuaDVec2, f64),
|
||||
Mod(LuaDVec2, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec3,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaDVec3, f64),
|
||||
Sub(LuaDVec3, f64),
|
||||
Div(LuaDVec3, f64),
|
||||
Mul(LuaDVec3, f64),
|
||||
Mod(LuaDVec3, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec4,
|
||||
derives(PartialEq),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaDVec4, f64),
|
||||
Sub(LuaDVec4, f64),
|
||||
Div(LuaDVec4, f64),
|
||||
Mul(LuaDVec4, f64),
|
||||
Mod(LuaDVec4, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
|
||||
// i32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaIVec2, i32),
|
||||
Sub(LuaIVec2, i32),
|
||||
Div(LuaIVec2, i32),
|
||||
Mul(LuaIVec2, i32),
|
||||
Mod(LuaIVec2, i32),
|
||||
Shl(LuaIVec2, LuaUVec2, i32),
|
||||
Shr(LuaIVec2, LuaUVec2, i32),
|
||||
BAnd(LuaIVec2, i32),
|
||||
BOr(LuaIVec2, i32),
|
||||
BXor(LuaIVec2, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaIVec3, i32),
|
||||
Sub(LuaIVec3, i32),
|
||||
Div(LuaIVec3, i32),
|
||||
Mul(LuaIVec3, i32),
|
||||
Mod(LuaIVec3, i32),
|
||||
Shl(LuaIVec3, LuaUVec3, i32),
|
||||
Shr(LuaIVec3, LuaUVec3, i32),
|
||||
BAnd(LuaIVec3, i32),
|
||||
BOr(LuaIVec3, i32),
|
||||
BXor(LuaIVec3, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaIVec4, i32),
|
||||
Sub(LuaIVec4, i32),
|
||||
Div(LuaIVec4, i32),
|
||||
Mul(LuaIVec4, i32),
|
||||
Mod(LuaIVec4, i32),
|
||||
Shl(LuaIVec4, LuaUVec4, i32),
|
||||
Shr(LuaIVec4, LuaUVec4, i32),
|
||||
BAnd(LuaIVec4, i32),
|
||||
BOr(LuaIVec4, i32),
|
||||
BXor(LuaIVec4, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// u32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaUVec2, u32),
|
||||
Sub(LuaUVec2, u32),
|
||||
Div(LuaUVec2, u32),
|
||||
Mul(LuaUVec2, u32),
|
||||
Mod(LuaUVec2, u32),
|
||||
Shl(LuaUVec2, LuaIVec2, i32),
|
||||
Shr(LuaUVec2, LuaIVec2, i32),
|
||||
BAnd(LuaUVec2, u32),
|
||||
BOr(LuaUVec2, u32),
|
||||
BXor(LuaUVec2, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaUVec3, u32),
|
||||
Sub(LuaUVec3, u32),
|
||||
Div(LuaUVec3, u32),
|
||||
Mul(LuaUVec3, u32),
|
||||
Mod(LuaUVec3, u32),
|
||||
Shl(LuaUVec3, LuaIVec3, i32),
|
||||
Shr(LuaUVec3, LuaIVec3, i32),
|
||||
BAnd(LuaUVec3, u32),
|
||||
BOr(LuaUVec3, u32),
|
||||
BXor(LuaUVec3, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaUVec4, u32),
|
||||
Sub(LuaUVec4, u32),
|
||||
Div(LuaUVec4, u32),
|
||||
Mul(LuaUVec4, u32),
|
||||
Mod(LuaUVec4, u32),
|
||||
Shl(LuaUVec4, LuaIVec4, i32),
|
||||
Shr(LuaUVec4, LuaIVec4, i32),
|
||||
BAnd(LuaUVec4, u32),
|
||||
BOr(LuaUVec4, u32),
|
||||
BXor(LuaUVec4, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// i64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaI64Vec2, i64),
|
||||
Sub(LuaI64Vec2, i64),
|
||||
Div(LuaI64Vec2, i64),
|
||||
Mul(LuaI64Vec2, i64),
|
||||
Mod(LuaI64Vec2, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec2, i64),
|
||||
BOr(LuaI64Vec2, i64),
|
||||
BXor(LuaI64Vec2, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaI64Vec3, i64),
|
||||
Sub(LuaI64Vec3, i64),
|
||||
Div(LuaI64Vec3, i64),
|
||||
Mul(LuaI64Vec3, i64),
|
||||
Mod(LuaI64Vec3, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec3, i64),
|
||||
BOr(LuaI64Vec3, i64),
|
||||
BXor(LuaI64Vec3, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaI64Vec4, i64),
|
||||
Sub(LuaI64Vec4, i64),
|
||||
Div(LuaI64Vec4, i64),
|
||||
Mul(LuaI64Vec4, i64),
|
||||
Mod(LuaI64Vec4, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec4, i64),
|
||||
BOr(LuaI64Vec4, i64),
|
||||
BXor(LuaI64Vec4, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// u64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaU64Vec2, u64),
|
||||
Sub(LuaU64Vec2, u64),
|
||||
Div(LuaU64Vec2, u64),
|
||||
Mul(LuaU64Vec2, u64),
|
||||
Mod(LuaU64Vec2, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec2, u64),
|
||||
BOr(LuaU64Vec2, u64),
|
||||
BXor(LuaU64Vec2, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaU64Vec3, u64),
|
||||
Sub(LuaU64Vec3, u64),
|
||||
Div(LuaU64Vec3, u64),
|
||||
Mul(LuaU64Vec3, u64),
|
||||
Mod(LuaU64Vec3, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec3, u64),
|
||||
BOr(LuaU64Vec3, u64),
|
||||
BXor(LuaU64Vec3, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaU64Vec4, u64),
|
||||
Sub(LuaU64Vec4, u64),
|
||||
Div(LuaU64Vec4, u64),
|
||||
Mul(LuaU64Vec4, u64),
|
||||
Mod(LuaU64Vec4, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec4, u64),
|
||||
BOr(LuaU64Vec4, u64),
|
||||
BXor(LuaU64Vec4, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// bool types
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
|
||||
// mat2
|
||||
wrap_math_vec_copy!(
|
||||
math::Mat2,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
matrix {
|
||||
col_type = LuaVec2
|
||||
},
|
||||
metamethods(
|
||||
Eq,
|
||||
Add,
|
||||
Sub,
|
||||
Mul(LuaMat2, f32),
|
||||
Unm
|
||||
)
|
||||
); */
|
||||
|
||||
/* wrap_math_vec_copy!(
|
||||
math::Mat4,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
matrix {
|
||||
col_type = LuaVec4
|
||||
},
|
||||
metamethods(
|
||||
Eq,
|
||||
Add,
|
||||
Sub,
|
||||
Mul(LuaMat4, f32),
|
||||
Unm
|
||||
)
|
||||
); */
|
||||
|
||||
wrap_math_vec_copy!(
|
||||
math::Quat,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
metamethods(
|
||||
Eq,
|
||||
// __mul for LuaVec3 is manually implemented below since it doesn't return Self
|
||||
Mul(LuaQuat, f32),
|
||||
Add,
|
||||
Sub,
|
||||
Div(f32),
|
||||
),
|
||||
custom_methods {
|
||||
methods.add_function("new", |_, (x, y, z, w)| {
|
||||
Ok(Self(math::Quat::from_xyzw(x, y, z, w)))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_x", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_x(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_y", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_y(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_z", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_z(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_method("dot", |_, this, (rhs,): (Self,)| {
|
||||
Ok(this.dot(rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("length", |_, this, ()| {
|
||||
Ok(this.length())
|
||||
});
|
||||
|
||||
methods.add_method("length_squared", |_, this, ()| {
|
||||
Ok(this.length_squared())
|
||||
});
|
||||
|
||||
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))
|
||||
});
|
||||
|
||||
// manually implemented here since it doesn't return `Self`
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| {
|
||||
Ok(LuaVec3(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.lerp(*rhs, alpha)))
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
wrap_math_vec_copy!(
|
||||
math::Transform,
|
||||
//derives(PartialEq),
|
||||
no_new,
|
||||
metamethods(ToString, Eq),
|
||||
custom_fields {
|
||||
fields.add_field_method_get("translation", |_, this| {
|
||||
Ok(LuaVec3(this.translation))
|
||||
});
|
||||
fields.add_field_method_set("translation", |_, this, v: LuaVec3| {
|
||||
this.translation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("rotation", |_, this| {
|
||||
Ok(LuaQuat(this.rotation))
|
||||
});
|
||||
fields.add_field_method_set("rotation", |_, this, v: LuaQuat| {
|
||||
this.rotation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("scale", |_, this| {
|
||||
Ok(LuaVec3(this.scale))
|
||||
});
|
||||
fields.add_field_method_set("scale", |_, this, v: LuaVec3| {
|
||||
this.scale = *v;
|
||||
Ok(())
|
||||
});
|
||||
},
|
||||
custom_methods {
|
||||
methods.add_function("default", |_, ()| {
|
||||
Ok(Self(math::Transform::default()))
|
||||
});
|
||||
|
||||
methods.add_function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| {
|
||||
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_method("forward", |_, this, ()| {
|
||||
Ok(LuaVec3(this.forward()))
|
||||
});
|
||||
|
||||
methods.add_method("left", |_, this, ()| {
|
||||
Ok(LuaVec3(this.left()))
|
||||
});
|
||||
|
||||
methods.add_method("up", |_, this, ()| {
|
||||
Ok(LuaVec3(this.up()))
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate", |_, this, (quat,): (LuaQuat,)| {
|
||||
this.rotate(*quat);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_x", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_x(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_y", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_y(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
this.rotate_x(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
this.rotate_z(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
let mut t = *this;
|
||||
t.rotation *= *quat;
|
||||
Ok(t)
|
||||
});
|
||||
|
||||
// move a transform
|
||||
methods.add_meta_method(mlua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| {
|
||||
let mut t = *this;
|
||||
t.translation += *pos;
|
||||
Ok(t)
|
||||
});
|
||||
}
|
||||
);
|
|
@ -1,566 +1,5 @@
|
|||
use lyra_game::math;
|
||||
use lyra_scripting_derive::wrap_math_vec_copy;
|
||||
use crate::lyra_engine;
|
||||
pub mod math;
|
||||
pub use math::*;
|
||||
|
||||
use crate as lyra_scripting;
|
||||
|
||||
// f32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec2,
|
||||
derives(PartialEq),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaVec2, f32),
|
||||
Sub(LuaVec2, f32),
|
||||
Div(LuaVec2, f32),
|
||||
Mul(LuaVec2, f32),
|
||||
Mod(LuaVec2, f32),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec3,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec3),
|
||||
Sub(LuaVec3, f32),
|
||||
Div(LuaVec3, f32),
|
||||
Mul(LuaVec3, f32),
|
||||
Mod(LuaVec3, f32),
|
||||
Eq, Unm, ToString,
|
||||
),
|
||||
custom_methods {
|
||||
/* methods.add_meta_method(mlua::MetaMethod::Add, |_, this, (trans,): (LuaTransform,)| {
|
||||
println!("Adding");
|
||||
let mut t = *trans;
|
||||
t.translation += **this;
|
||||
Ok(LuaTransform(t))
|
||||
}); */
|
||||
}
|
||||
);
|
||||
/* wrap_math_vec_copy!(
|
||||
math::Vec3A,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec3A, f32),
|
||||
Sub(LuaVec3A, f32),
|
||||
Div(LuaVec3A, f32),
|
||||
Mul(LuaVec3A, f32),
|
||||
Mod(LuaVec3A, f32),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::Vec4,
|
||||
derives(PartialEq),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaVec4, f32),
|
||||
Sub(LuaVec4, f32),
|
||||
Div(LuaVec4, f32),
|
||||
Mul(LuaVec4, f32),
|
||||
Mod(LuaVec4, f32),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
|
||||
// f64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec2,
|
||||
derives(PartialEq),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaDVec2, f64),
|
||||
Sub(LuaDVec2, f64),
|
||||
Div(LuaDVec2, f64),
|
||||
Mul(LuaDVec2, f64),
|
||||
Mod(LuaDVec2, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec3,
|
||||
derives(PartialEq),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaDVec3, f64),
|
||||
Sub(LuaDVec3, f64),
|
||||
Div(LuaDVec3, f64),
|
||||
Mul(LuaDVec3, f64),
|
||||
Mod(LuaDVec3, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::DVec4,
|
||||
derives(PartialEq),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaDVec4, f64),
|
||||
Sub(LuaDVec4, f64),
|
||||
Div(LuaDVec4, f64),
|
||||
Mul(LuaDVec4, f64),
|
||||
Mod(LuaDVec4, f64),
|
||||
Eq, Unm
|
||||
)
|
||||
);
|
||||
|
||||
// i32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaIVec2, i32),
|
||||
Sub(LuaIVec2, i32),
|
||||
Div(LuaIVec2, i32),
|
||||
Mul(LuaIVec2, i32),
|
||||
Mod(LuaIVec2, i32),
|
||||
Shl(LuaIVec2, LuaUVec2, i32),
|
||||
Shr(LuaIVec2, LuaUVec2, i32),
|
||||
BAnd(LuaIVec2, i32),
|
||||
BOr(LuaIVec2, i32),
|
||||
BXor(LuaIVec2, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaIVec3, i32),
|
||||
Sub(LuaIVec3, i32),
|
||||
Div(LuaIVec3, i32),
|
||||
Mul(LuaIVec3, i32),
|
||||
Mod(LuaIVec3, i32),
|
||||
Shl(LuaIVec3, LuaUVec3, i32),
|
||||
Shr(LuaIVec3, LuaUVec3, i32),
|
||||
BAnd(LuaIVec3, i32),
|
||||
BOr(LuaIVec3, i32),
|
||||
BXor(LuaIVec3, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::IVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaIVec4, i32),
|
||||
Sub(LuaIVec4, i32),
|
||||
Div(LuaIVec4, i32),
|
||||
Mul(LuaIVec4, i32),
|
||||
Mod(LuaIVec4, i32),
|
||||
Shl(LuaIVec4, LuaUVec4, i32),
|
||||
Shr(LuaIVec4, LuaUVec4, i32),
|
||||
BAnd(LuaIVec4, i32),
|
||||
BOr(LuaIVec4, i32),
|
||||
BXor(LuaIVec4, i32),
|
||||
Eq, Unm, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// u32 types
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaUVec2, u32),
|
||||
Sub(LuaUVec2, u32),
|
||||
Div(LuaUVec2, u32),
|
||||
Mul(LuaUVec2, u32),
|
||||
Mod(LuaUVec2, u32),
|
||||
Shl(LuaUVec2, LuaIVec2, i32),
|
||||
Shr(LuaUVec2, LuaIVec2, i32),
|
||||
BAnd(LuaUVec2, u32),
|
||||
BOr(LuaUVec2, u32),
|
||||
BXor(LuaUVec2, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaUVec3, u32),
|
||||
Sub(LuaUVec3, u32),
|
||||
Div(LuaUVec3, u32),
|
||||
Mul(LuaUVec3, u32),
|
||||
Mod(LuaUVec3, u32),
|
||||
Shl(LuaUVec3, LuaIVec3, i32),
|
||||
Shr(LuaUVec3, LuaIVec3, i32),
|
||||
BAnd(LuaUVec3, u32),
|
||||
BOr(LuaUVec3, u32),
|
||||
BXor(LuaUVec3, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::UVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaUVec4, u32),
|
||||
Sub(LuaUVec4, u32),
|
||||
Div(LuaUVec4, u32),
|
||||
Mul(LuaUVec4, u32),
|
||||
Mod(LuaUVec4, u32),
|
||||
Shl(LuaUVec4, LuaIVec4, i32),
|
||||
Shr(LuaUVec4, LuaIVec4, i32),
|
||||
BAnd(LuaUVec4, u32),
|
||||
BOr(LuaUVec4, u32),
|
||||
BXor(LuaUVec4, u32),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// i64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaI64Vec2, i64),
|
||||
Sub(LuaI64Vec2, i64),
|
||||
Div(LuaI64Vec2, i64),
|
||||
Mul(LuaI64Vec2, i64),
|
||||
Mod(LuaI64Vec2, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec2, i64),
|
||||
BOr(LuaI64Vec2, i64),
|
||||
BXor(LuaI64Vec2, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaI64Vec3, i64),
|
||||
Sub(LuaI64Vec3, i64),
|
||||
Div(LuaI64Vec3, i64),
|
||||
Mul(LuaI64Vec3, i64),
|
||||
Mod(LuaI64Vec3, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec3, i64),
|
||||
BOr(LuaI64Vec3, i64),
|
||||
BXor(LuaI64Vec3, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::I64Vec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaI64Vec4, i64),
|
||||
Sub(LuaI64Vec4, i64),
|
||||
Div(LuaI64Vec4, i64),
|
||||
Mul(LuaI64Vec4, i64),
|
||||
Mod(LuaI64Vec4, i64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaI64Vec4, i64),
|
||||
BOr(LuaI64Vec4, i64),
|
||||
BXor(LuaI64Vec4, i64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// u64 types
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(
|
||||
Add(LuaU64Vec2, u64),
|
||||
Sub(LuaU64Vec2, u64),
|
||||
Div(LuaU64Vec2, u64),
|
||||
Mul(LuaU64Vec2, u64),
|
||||
Mod(LuaU64Vec2, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec2, u64),
|
||||
BOr(LuaU64Vec2, u64),
|
||||
BXor(LuaU64Vec2, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(
|
||||
Add(LuaU64Vec3, u64),
|
||||
Sub(LuaU64Vec3, u64),
|
||||
Div(LuaU64Vec3, u64),
|
||||
Mul(LuaU64Vec3, u64),
|
||||
Mod(LuaU64Vec3, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec3, u64),
|
||||
BOr(LuaU64Vec3, u64),
|
||||
BXor(LuaU64Vec3, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::U64Vec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(
|
||||
Add(LuaU64Vec4, u64),
|
||||
Sub(LuaU64Vec4, u64),
|
||||
Div(LuaU64Vec4, u64),
|
||||
Mul(LuaU64Vec4, u64),
|
||||
Mod(LuaU64Vec4, u64),
|
||||
Shl(i64),
|
||||
Shr(i64),
|
||||
BAnd(LuaU64Vec4, u64),
|
||||
BOr(LuaU64Vec4, u64),
|
||||
BXor(LuaU64Vec4, u64),
|
||||
Eq, BNot
|
||||
)
|
||||
);
|
||||
|
||||
// bool types
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec2,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec3,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(x, y, z),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
wrap_math_vec_copy!(
|
||||
math::BVec4,
|
||||
derives(PartialEq, Eq, Hash),
|
||||
fields(w, x, y, z),
|
||||
metamethods(Eq, BAnd, BOr, BXor, BNot)
|
||||
);
|
||||
|
||||
// mat2
|
||||
wrap_math_vec_copy!(
|
||||
math::Mat2,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
matrix {
|
||||
col_type = LuaVec2
|
||||
},
|
||||
metamethods(
|
||||
Eq,
|
||||
Add,
|
||||
Sub,
|
||||
Mul(LuaMat2, f32),
|
||||
Unm
|
||||
)
|
||||
); */
|
||||
|
||||
/* wrap_math_vec_copy!(
|
||||
math::Mat4,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
matrix {
|
||||
col_type = LuaVec4
|
||||
},
|
||||
metamethods(
|
||||
Eq,
|
||||
Add,
|
||||
Sub,
|
||||
Mul(LuaMat4, f32),
|
||||
Unm
|
||||
)
|
||||
); */
|
||||
|
||||
wrap_math_vec_copy!(
|
||||
math::Quat,
|
||||
derives(PartialEq),
|
||||
no_new,
|
||||
metamethods(
|
||||
Eq,
|
||||
// __mul for LuaVec3 is manually implemented below since it doesn't return Self
|
||||
Mul(LuaQuat, f32),
|
||||
Add,
|
||||
Sub,
|
||||
Div(f32),
|
||||
),
|
||||
custom_methods {
|
||||
methods.add_function("new", |_, (x, y, z, w)| {
|
||||
Ok(Self(math::Quat::from_xyzw(x, y, z, w)))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_x", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_x(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_y", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_y(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_function("from_rotation_z", |_, (rad,)| {
|
||||
let q = math::Quat::from_rotation_z(rad);
|
||||
Ok(Self(q))
|
||||
});
|
||||
|
||||
methods.add_method("dot", |_, this, (rhs,): (Self,)| {
|
||||
Ok(this.dot(rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("length", |_, this, ()| {
|
||||
Ok(this.length())
|
||||
});
|
||||
|
||||
methods.add_method("length_squared", |_, this, ()| {
|
||||
Ok(this.length_squared())
|
||||
});
|
||||
|
||||
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))
|
||||
});
|
||||
|
||||
// manually implemented here since it doesn't return `Self`
|
||||
methods.add_meta_method(mlua::MetaMethod::Mul, |_, this, (rhs,): (LuaVec3,)| {
|
||||
Ok(LuaVec3(this.0 * rhs.0))
|
||||
});
|
||||
|
||||
methods.add_method("lerp", |_, this, (rhs, alpha): (Self, f32)| {
|
||||
Ok(Self(this.lerp(*rhs, alpha)))
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
wrap_math_vec_copy!(
|
||||
math::Transform,
|
||||
//derives(PartialEq),
|
||||
no_new,
|
||||
metamethods(ToString, Eq),
|
||||
custom_fields {
|
||||
fields.add_field_method_get("translation", |_, this| {
|
||||
Ok(LuaVec3(this.translation))
|
||||
});
|
||||
fields.add_field_method_set("translation", |_, this, v: LuaVec3| {
|
||||
this.translation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("rotation", |_, this| {
|
||||
Ok(LuaQuat(this.rotation))
|
||||
});
|
||||
fields.add_field_method_set("rotation", |_, this, v: LuaQuat| {
|
||||
this.rotation = *v;
|
||||
Ok(())
|
||||
});
|
||||
|
||||
fields.add_field_method_get("scale", |_, this| {
|
||||
Ok(LuaVec3(this.scale))
|
||||
});
|
||||
fields.add_field_method_set("scale", |_, this, v: LuaVec3| {
|
||||
this.scale = *v;
|
||||
Ok(())
|
||||
});
|
||||
},
|
||||
custom_methods {
|
||||
methods.add_function("default", |_, ()| {
|
||||
Ok(Self(math::Transform::default()))
|
||||
});
|
||||
|
||||
methods.add_function("new", |_, (pos, rot, scale): (LuaVec3, LuaQuat, LuaVec3)| {
|
||||
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_method("forward", |_, this, ()| {
|
||||
Ok(LuaVec3(this.forward()))
|
||||
});
|
||||
|
||||
methods.add_method("left", |_, this, ()| {
|
||||
Ok(LuaVec3(this.left()))
|
||||
});
|
||||
|
||||
methods.add_method("up", |_, this, ()| {
|
||||
Ok(LuaVec3(this.up()))
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate", |_, this, (quat,): (LuaQuat,)| {
|
||||
this.rotate(*quat);
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_x", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_x(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_method_mut("rotate_y", |_, this, (deg,): (f32,)| {
|
||||
this.rotate_y(math::Angle::Degrees(deg));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
this.rotate_x(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
this.rotate_z(math::Angle::Radians(rad));
|
||||
Ok(())
|
||||
});
|
||||
|
||||
methods.add_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,)| {
|
||||
let mut t = *this;
|
||||
t.rotation *= *quat;
|
||||
Ok(t)
|
||||
});
|
||||
|
||||
// move a transform
|
||||
methods.add_meta_method(mlua::MetaMethod::Add, |_, this, (pos,): (LuaVec3,)| {
|
||||
let mut t = *this;
|
||||
t.translation += *pos;
|
||||
Ok(t)
|
||||
});
|
||||
}
|
||||
);
|
||||
pub mod delta_time;
|
||||
pub use delta_time::*;
|
Loading…
Reference in New Issue