diff --git a/main.lua b/main.lua index 2d5ee3a..5d3deda 100644 --- a/main.lua +++ b/main.lua @@ -2,10 +2,10 @@ print("Hello from a lua script!") function init() print("Hello from \"init\"") - print(couch.root:find_node("cube"):get_transform()) couch.debug("init") couch.say_hello("dane", "Hi!") end function update(delta) + print(couch.root:find_node("cube"):get_transform().position[3]) end diff --git a/src/gameobject.rs b/src/gameobject.rs index 052ce58..9fe6477 100644 --- a/src/gameobject.rs +++ b/src/gameobject.rs @@ -54,6 +54,25 @@ pub enum GameObject { Mesh(Mesh), } +impl GameObject { + pub fn get_transform(&self) -> Result { + use GameObject::*; + match self { + Camera(camera) => Ok(camera.get_transform()), + Mesh(mesh) => Ok(mesh.get_transform()), + _ => Err("object does not implement \"get_transform\"".to_string()) + } + } + pub fn set_transform(&mut self, transform: Transform) -> Result<(), String> { + use GameObject::*; + match self { + Camera(camera) => { camera.set_transform(transform); Ok(()) } + Mesh(mesh) => { mesh.set_transform(transform); Ok(()) } + _ => Err("object does not implement \"set_transform\"".to_string()) + } + } +} + #[derive(Clone, Copy)] pub struct Transform { pub position: glm::Vec3, diff --git a/src/scripting.rs b/src/scripting.rs index 6d0ef19..256eef9 100644 --- a/src/scripting.rs +++ b/src/scripting.rs @@ -1,7 +1,8 @@ -use crate::gameobject::{ Node, Transform, Spatial }; +use crate::gameobject::{ Node, Transform }; extern crate mlua; use mlua::Lua as LuaContext; +use mlua::Error::RuntimeError as LuaError; use mlua::chunk; use std::rc::Rc; @@ -18,7 +19,6 @@ pub struct Lua { impl mlua::UserData for Node { fn add_methods<'lua, M: mlua::UserDataMethods<'lua, Self>>(methods: &mut M) { - use crate::gameobject::GameObject::*; methods.add_method_mut("find_node", |_, this, name: String| { let child = this.find_node(&name); match child { @@ -27,16 +27,47 @@ impl mlua::UserData for Node { } }); methods.add_method("get_transform", |_, this, _: ()| { - match &this.gameobject { - Mesh(mesh) => Ok(mesh.get_transform()), - Camera(camera) => Ok(camera.get_transform()), - _ => Err(mlua::Error::RuntimeError("Node does not implement get_transform".to_string())) + match this.gameobject.get_transform() { + Ok(transform) => Ok(transform), + Err(msg) => Err(LuaError(msg)), + } + }); + methods.add_method_mut("set_transform", |_, this, transform: Transform| { + match this.gameobject.set_transform(transform) { + Ok(()) => Ok(()), + Err(msg) => Err(LuaError(msg)), } }); } } -impl mlua::UserData for Transform {} +impl<'lua> mlua::ToLua<'lua> for Transform { + fn to_lua(self, ctx: &'lua LuaContext) -> mlua::Result> { + let table = ctx.create_table().unwrap(); + table.set("position", <[f32; 3]>::from(self.position))?; + table.set("rotation", <[f32; 3]>::from(self.rotation))?; + table.set("scale", <[f32; 3]>::from(self.scale))?; + mlua::Result::Ok(mlua::Value::Table(table)) + } +} + +impl<'lua> mlua::FromLua<'lua> for Transform { + fn from_lua(lua_value: mlua::Value<'lua>, _: &'lua LuaContext) -> mlua::Result { + match lua_value { + mlua::Value::Table(table) => { + let position: [f32; 3] = table.get("position")?; + let rotation: [f32; 3] = table.get("rotation")?; + let scale: [f32; 3] = table.get("scale")?; + Ok(Transform { + position: glm::Vec3::from(position), + rotation: glm::Vec3::from(rotation), + scale: glm::Vec3::from(scale), + }) + } + _ => Err(LuaError("Could not convert to Transform".to_string())), + } + } +} impl Lua { pub fn new(root: Rc>) -> Self {