Create an early scripting engine #2
|
@ -15,9 +15,12 @@ end ]]
|
||||||
function on_update()
|
function on_update()
|
||||||
--print("Lua's update function was called")
|
--print("Lua's update function was called")
|
||||||
|
|
||||||
|
local dt = world:resource(DeltaTime)
|
||||||
|
--print("DeltaTime was " .. tostring(dt) .. "s")
|
||||||
|
|
||||||
world:view(function (t)
|
world:view(function (t)
|
||||||
--print("Found entity at a really cool place: " .. tostring(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
|
return t
|
||||||
end, Transform)
|
end, Transform)
|
||||||
|
|
|
@ -6,7 +6,7 @@ impl<T: 'static> ResourceObject for T {}
|
||||||
|
|
||||||
/// A type erased storage for a Resource.
|
/// A type erased storage for a Resource.
|
||||||
pub struct ResourceData {
|
pub struct ResourceData {
|
||||||
data: Box<RefCell<dyn Any>>,
|
pub(crate) data: Box<RefCell<dyn Any>>,
|
||||||
type_id: TypeId,
|
type_id: TypeId,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{collections::{HashMap, VecDeque}, any::TypeId, cell::{Ref, RefMut}, ptr::NonNull};
|
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)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct EntityId(pub u64);
|
pub struct EntityId(pub u64);
|
||||||
|
@ -306,6 +306,12 @@ impl World {
|
||||||
pub fn tick_tracker(&self) -> &TickTracker {
|
pub fn tick_tracker(&self) -> &TickTracker {
|
||||||
&self.tracker
|
&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)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use instant::Instant;
|
use instant::Instant;
|
||||||
use lyra_ecs::{Component, world::World};
|
use lyra_ecs::{Component, world::World};
|
||||||
|
use lyra_reflect::Reflect;
|
||||||
|
|
||||||
use crate::{plugin::Plugin, game::GameStages};
|
use crate::{plugin::Plugin, game::GameStages};
|
||||||
|
|
||||||
#[derive(Clone, Component)]
|
#[derive(Clone, Component, Default, Reflect)]
|
||||||
pub struct DeltaTime(f32, Option<Instant>);
|
pub struct DeltaTime(f32, #[reflect(skip)] Option<Instant>);
|
||||||
|
|
||||||
impl std::ops::Deref for DeltaTime {
|
impl std::ops::Deref for DeltaTime {
|
||||||
type Target = f32;
|
type Target = f32;
|
||||||
|
|
|
@ -26,6 +26,7 @@ pub mod scene;
|
||||||
pub use lyra_resource as assets;
|
pub use lyra_resource as assets;
|
||||||
pub use lyra_ecs as ecs;
|
pub use lyra_ecs as ecs;
|
||||||
pub use lyra_math as math;
|
pub use lyra_math as math;
|
||||||
|
pub use lyra_reflect as reflect;
|
||||||
|
|
||||||
#[cfg(feature = "scripting")]
|
#[cfg(feature = "scripting")]
|
||||||
pub use lyra_scripting as script;
|
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 mod reflected_field;
|
||||||
pub use reflected_field::*;
|
pub use reflected_field::*;
|
||||||
|
|
||||||
|
pub mod component;
|
||||||
|
pub use component::*;
|
||||||
|
|
||||||
|
pub mod resource;
|
||||||
|
pub use resource::*;
|
||||||
|
|
||||||
pub mod util;
|
pub mod util;
|
||||||
pub mod field;
|
pub mod field;
|
||||||
pub use field::*;
|
pub use field::*;
|
||||||
|
@ -237,67 +243,48 @@ pub trait FromType<T> {
|
||||||
fn from_type() -> Self;
|
fn from_type() -> Self;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub trait ReflectWorldExt {
|
||||||
pub struct ReflectedComponent {
|
/// Retrieves the type registry from the world.
|
||||||
pub type_id: TypeId,
|
fn get_type_registry(&self) -> Ref<TypeRegistry>;
|
||||||
pub info: ComponentInfo,
|
/// Retrieves the type registry mutably from the world.
|
||||||
//value: Value,
|
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry>;
|
||||||
//from_world:
|
/// 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>>;
|
||||||
//from_world: for<'a> fn (world: &'a mut World) -> Box<dyn Reflect>,
|
/// Get a mutable registered type from the type registry in the world. returns `None` if the type is not registered.
|
||||||
/// Inserts component into entity in the world
|
fn get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>>;
|
||||||
fn_insert: for<'a> fn (world: &'a mut World, entity: Entity, component: &dyn Reflect),
|
/// Get a registered type, or register a new type and return it.
|
||||||
/// Inserts component into a bundle
|
fn get_type_or_default<T>(&self, type_id: TypeId) -> RefMut<RegisteredType>;
|
||||||
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 {
|
impl ReflectWorldExt for World {
|
||||||
/// Insert the reflected component into an entity.
|
fn get_type_registry(&self) -> Ref<TypeRegistry> {
|
||||||
pub fn insert(&self, world: &mut World, entity: Entity, component: &dyn Reflect) {
|
self.get_resource::<TypeRegistry>()
|
||||||
(self.fn_insert)(world, entity, component);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert this component into a DynamicBundle
|
fn get_type_registry_mut(&self) -> RefMut<TypeRegistry> {
|
||||||
pub fn bundle_insert(&self, dynamic_bundle: &mut DynamicBundle, component: &dyn Reflect) {
|
self.get_resource_mut::<TypeRegistry>()
|
||||||
(self.fn_bundle_insert)(dynamic_bundle, component)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves a reflected component from an entity.
|
fn get_type<T>(&self, type_id: TypeId) -> Option<Ref<RegisteredType>> {
|
||||||
pub fn reflect<'a>(&'a self, world: &'a World, entity: Entity) -> Option<Ref<'a, dyn Reflect>> {
|
let r = self.get_resource::<TypeRegistry>();
|
||||||
(self.fn_reflect)(world, entity)
|
if r.has_type(type_id) {
|
||||||
}
|
Some(Ref::map(r, |tr| tr.get_type(type_id).unwrap()))
|
||||||
|
} else {
|
||||||
/// Retrieves a reflected component from an entity.
|
None
|
||||||
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 get_type_mut<T>(&self, type_id: TypeId) -> Option<RefMut<RegisteredType>> {
|
||||||
fn from_type() -> Self {
|
let r = self.get_resource_mut::<TypeRegistry>();
|
||||||
ReflectedComponent {
|
if r.has_type(type_id) {
|
||||||
type_id: TypeId::of::<C>(),
|
Some(RefMut::map(r, |tr| tr.get_type_mut(type_id).unwrap()))
|
||||||
info: ComponentInfo::new::<C>(),
|
} else {
|
||||||
fn_insert: |world: &mut World, entity: Entity, component: &dyn Reflect| {
|
None
|
||||||
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_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 lua;
|
||||||
|
|
||||||
pub mod world;
|
pub mod world;
|
||||||
use lyra_ecs::Component;
|
use std::any::TypeId;
|
||||||
|
|
||||||
|
use lyra_ecs::{Component, ResourceObject};
|
||||||
pub use world::*;
|
pub use world::*;
|
||||||
|
|
||||||
pub mod wrap;
|
pub mod wrap;
|
||||||
|
@ -16,17 +18,19 @@ pub use script::*;
|
||||||
|
|
||||||
use lyra_game::game::Game;
|
use lyra_game::game::Game;
|
||||||
|
|
||||||
|
// required for some proc macros :(
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
pub(crate) mod lyra_engine {
|
pub(crate) mod lyra_engine {
|
||||||
pub use lyra_ecs as ecs;
|
pub use lyra_ecs as ecs;
|
||||||
pub use lyra_reflect as reflect;
|
pub use lyra_reflect as reflect;
|
||||||
}
|
}
|
||||||
|
|
||||||
use lyra_reflect::{ReflectedComponent, Reflect, FromType};
|
use lyra_reflect::{ReflectedComponent, Reflect, FromType, ReflectedResource};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum ReflectBranch {
|
pub enum ReflectBranch {
|
||||||
Component(ReflectedComponent),
|
Component(ReflectedComponent),
|
||||||
|
Resource(ReflectedResource),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReflectBranch {
|
impl ReflectBranch {
|
||||||
|
@ -37,13 +41,38 @@ impl ReflectBranch {
|
||||||
pub fn as_component_unchecked(&self) -> &ReflectedComponent {
|
pub fn as_component_unchecked(&self) -> &ReflectedComponent {
|
||||||
match self {
|
match self {
|
||||||
ReflectBranch::Component(c) => c,
|
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 {
|
pub fn is_component(&self) -> bool {
|
||||||
matches!(self, ReflectBranch::Component(_))
|
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 {
|
pub struct ScriptBorrow {
|
||||||
|
@ -63,6 +92,7 @@ impl Clone for ScriptBorrow {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ScriptBorrow {
|
impl ScriptBorrow {
|
||||||
|
/// Creates a ScriptBorrow from a Component
|
||||||
pub fn from_component<T>(data: Option<T>) -> Self
|
pub fn from_component<T>(data: Option<T>) -> Self
|
||||||
where
|
where
|
||||||
T: Reflect + Component + Default + 'static
|
T: Reflect + Component + Default + 'static
|
||||||
|
@ -74,10 +104,24 @@ impl ScriptBorrow {
|
||||||
data,
|
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
|
/// An extension trait that adds some helpful methods that makes it easier to do scripting things
|
||||||
pub trait GameScriptExt {
|
pub trait GameScriptExt {
|
||||||
|
/// A helper method for adding a ScriptApiProvider into the world.
|
||||||
fn add_script_api_provider<T, P>(&mut self, provider: P)
|
fn add_script_api_provider<T, P>(&mut self, provider: P)
|
||||||
where
|
where
|
||||||
T: ScriptHost,
|
T: ScriptHost,
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub use dynamic_iter::*;
|
||||||
pub mod world;
|
pub mod world;
|
||||||
use lyra_game::{game::GameStages, plugin::Plugin};
|
use lyra_game::{game::GameStages, plugin::Plugin};
|
||||||
use lyra_resource::ResourceManager;
|
use lyra_resource::ResourceManager;
|
||||||
use tracing::{debug, error, trace, debug_span};
|
use tracing::{debug, debug_span, error, trace};
|
||||||
pub use world::*;
|
pub use world::*;
|
||||||
|
|
||||||
pub mod script;
|
pub mod script;
|
||||||
|
@ -17,6 +17,9 @@ pub use loader::*;
|
||||||
pub mod providers;
|
pub mod providers;
|
||||||
pub mod wrappers;
|
pub mod wrappers;
|
||||||
|
|
||||||
|
pub mod proxy;
|
||||||
|
pub use proxy::*;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test;
|
mod test;
|
||||||
|
|
||||||
|
@ -43,24 +46,22 @@ use crate::{
|
||||||
use self::providers::{LyraEcsApiProvider, LyraMathApiProvider, UtilityApiProvider};
|
use self::providers::{LyraEcsApiProvider, LyraMathApiProvider, UtilityApiProvider};
|
||||||
|
|
||||||
pub trait RegisterLuaType {
|
pub trait RegisterLuaType {
|
||||||
/// Register a lua type that **is not wrapped**.
|
/// Register a type to lua that **is not wrapped**.
|
||||||
fn register_lua_type<'a, T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData>(
|
fn register_lua_type<'a, T>(&mut self)
|
||||||
&mut self,
|
where
|
||||||
);
|
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData;
|
||||||
|
|
||||||
/// Registers a wrapped lua type.
|
/// 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>(&mut self)
|
||||||
fn register_lua_wrapper<
|
where
|
||||||
'a,
|
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData;
|
||||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData,
|
|
||||||
>(
|
|
||||||
&mut self,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RegisterLuaType for World {
|
impl RegisterLuaType for World {
|
||||||
fn register_lua_type<'a, T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData>(
|
fn register_lua_type<'a, T>(&mut self)
|
||||||
&mut self,
|
where
|
||||||
) {
|
T: Reflect + LuaProxy + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||||
|
{
|
||||||
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
||||||
|
|
||||||
let type_id = TypeId::of::<T>();
|
let type_id = TypeId::of::<T>();
|
||||||
|
@ -70,12 +71,10 @@ impl RegisterLuaType for World {
|
||||||
//reg_type.add_data(<ReflectedComponent as FromType<T>>::from_type());
|
//reg_type.add_data(<ReflectedComponent as FromType<T>>::from_type());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn register_lua_wrapper<
|
fn register_lua_wrapper<'a, W>(&mut self)
|
||||||
'a,
|
where
|
||||||
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData,
|
W: Reflect + LuaProxy + LuaWrapper + Clone + mlua::FromLua<'a> + mlua::UserData
|
||||||
>(
|
{
|
||||||
&mut self,
|
|
||||||
) {
|
|
||||||
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
let mut registry = self.get_resource_mut::<TypeRegistry>();
|
||||||
|
|
||||||
let reg_type = registry.get_type_or_default(W::wrapped_type_id());
|
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")
|
.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 {
|
impl mlua::UserData for ScriptDynamicBundle {
|
||||||
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
fn add_methods<'lua, M: mlua::prelude::LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
|
||||||
methods.add_function("new", |_, ()| Ok(ScriptDynamicBundle(DynamicBundle::new())));
|
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)]
|
#[derive(Default)]
|
||||||
pub struct LyraEcsApiProvider;
|
pub struct LyraEcsApiProvider;
|
||||||
|
@ -6,6 +6,10 @@ pub struct LyraEcsApiProvider;
|
||||||
impl ScriptApiProvider for LyraEcsApiProvider {
|
impl ScriptApiProvider for LyraEcsApiProvider {
|
||||||
type ScriptContext = LuaContext;
|
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> {
|
fn expose_api(&mut self, data: &ScriptData, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||||
let ctx = ctx.lock().unwrap();
|
let ctx = ctx.lock().unwrap();
|
||||||
|
|
||||||
|
@ -13,6 +17,8 @@ impl ScriptApiProvider for LyraEcsApiProvider {
|
||||||
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
globals.set("World", ctx.create_proxy::<ScriptWorldPtr>()?)?;
|
||||||
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
globals.set("DynamicBundle", ctx.create_proxy::<ScriptDynamicBundle>()?)?;
|
||||||
|
|
||||||
|
globals.set("DeltaTime", ctx.create_proxy::<LuaDeltaTime>()?)?;
|
||||||
|
|
||||||
Ok(())
|
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_ecs::query::dynamic::QueryDynamicType;
|
||||||
use lyra_reflect::TypeRegistry;
|
use lyra_reflect::{TypeRegistry, ReflectWorldExt, RegisteredType};
|
||||||
use mlua::{AnyUserDataExt, IntoLua, IntoLuaMulti};
|
use mlua::{AnyUserDataExt, IntoLua, IntoLuaMulti};
|
||||||
|
|
||||||
use crate::{ScriptWorldPtr, ScriptEntity, ScriptDynamicBundle, ScriptBorrow};
|
use crate::{ScriptWorldPtr, ScriptEntity, ScriptDynamicBundle, ScriptBorrow};
|
||||||
|
@ -159,5 +159,26 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
|
|
||||||
Ok(())
|
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;
|
pub mod math;
|
||||||
use lyra_scripting_derive::wrap_math_vec_copy;
|
pub use math::*;
|
||||||
use crate::lyra_engine;
|
|
||||||
|
|
||||||
use crate as lyra_scripting;
|
pub mod delta_time;
|
||||||
|
pub use delta_time::*;
|
||||||
// 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)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
Loading…
Reference in New Issue