Start implementing lua scripting
This commit is contained in:
parent
0e6cc64c89
commit
d6b5f82d72
1
main.lua
1
main.lua
@ -2,6 +2,7 @@ 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
|
||||
|
@ -2,34 +2,35 @@ use nalgebra_glm as glm;
|
||||
|
||||
use crate::model::Model;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
pub type NodeRef = Rc<RefCell<Node>>;
|
||||
|
||||
pub struct Node {
|
||||
pub name: String,
|
||||
pub gameobject: GameObject,
|
||||
pub children: Vec<Node>,
|
||||
pub children: Vec<NodeRef>,
|
||||
}
|
||||
|
||||
pub trait Childbearing<T> {
|
||||
pub trait Childbearing<T> { // TODO remove this
|
||||
fn add_child(&mut self, name: &str, child: T);
|
||||
fn find_node(&mut self, name: &str) -> Option<&mut Box<T>>;
|
||||
}
|
||||
|
||||
impl Node {
|
||||
pub fn find_node(&mut self, name: &str) -> Option<NodeRef> {
|
||||
match self.children.iter().find(|node| node.borrow().name == name) {
|
||||
Some(node) => Some(Rc::clone(node)),
|
||||
None => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! impl_childbearing {
|
||||
($t:ty, $e:path) => {
|
||||
impl Childbearing<$t> for Node {
|
||||
fn add_child(&mut self, name: &str, child: $t) {
|
||||
self.children.push(Node::new(name.to_string(), $e(Box::new(child))));
|
||||
}
|
||||
fn find_node(&mut self, name: &str) -> Option<&mut Box<$t>> {
|
||||
match self.children.iter_mut().find(|node| node.name == name) {
|
||||
Some(node) => {
|
||||
if let $e(child) = &mut node.gameobject {
|
||||
Some(child)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
}
|
||||
self.children.push(Rc::new(RefCell::new(Node::new(name.to_string(), $e(child)))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -49,8 +50,8 @@ impl Node {
|
||||
|
||||
pub enum GameObject {
|
||||
Null,
|
||||
Camera(Box<Camera>),
|
||||
Mesh(Box<Mesh>),
|
||||
Camera(Camera),
|
||||
Mesh(Mesh),
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
|
48
src/main.rs
48
src/main.rs
@ -1,17 +1,20 @@
|
||||
mod device;
|
||||
|
||||
mod model;
|
||||
use model::Model;
|
||||
|
||||
mod scripting;
|
||||
use scripting::{ ScriptLang, Lua };
|
||||
|
||||
mod gameobject;
|
||||
use gameobject::*;
|
||||
|
||||
#[macro_use]
|
||||
extern crate glium;
|
||||
extern crate nalgebra_glm as glm;
|
||||
|
||||
use model::Model;
|
||||
|
||||
use scripting::{ ScriptLang, Lua };
|
||||
|
||||
use gameobject::*;
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
fn main() {
|
||||
use glium::{glutin, Surface};
|
||||
@ -30,18 +33,22 @@ fn main() {
|
||||
|
||||
let mut device_manager = crate::device::DeviceManager::new();
|
||||
|
||||
let mut root = Node::new("_root_".to_string(), GameObject::Null);
|
||||
root.add_child("camera", Camera::new());
|
||||
let root = Rc::new(RefCell::new(Node::new("_root_".to_string(), GameObject::Null)));
|
||||
{
|
||||
// Initial scene setup
|
||||
let mut root = root.borrow_mut();
|
||||
root.add_child("camera", Camera::new());
|
||||
|
||||
let mut cube = Mesh::new(Model::new(&display, "Box.glb"));
|
||||
cube.set_transform(gameobject::Transform {
|
||||
position: glm::vec3(0.0, 0.0, -10.0),
|
||||
rotation: glm::vec3(0.0, 15.0_f32.to_radians(), 0.0),
|
||||
scale: glm::vec3(1.0, 1.0, 1.0),
|
||||
});
|
||||
root.add_child("cube", cube);
|
||||
let mut cube = Mesh::new(Model::new(&display, "Box.glb"));
|
||||
cube.set_transform(gameobject::Transform {
|
||||
position: glm::vec3(0.0, 0.0, -10.0),
|
||||
rotation: glm::vec3(0.0, 15.0_f32.to_radians(), 0.0),
|
||||
scale: glm::vec3(1.0, 1.0, 1.0),
|
||||
});
|
||||
root.add_child("cube", cube);
|
||||
}
|
||||
|
||||
let mut script_lang = Lua::new();
|
||||
let mut script_lang = Lua::new(Rc::clone(&root));
|
||||
script_lang.init();
|
||||
|
||||
let mut last_draw = std::time::Instant::now();
|
||||
@ -78,7 +85,14 @@ fn main() {
|
||||
};
|
||||
target.clear_color_and_depth((0.0, 0.0, 0.0, 1.0), 1.0);
|
||||
|
||||
let cube: &mut Box<Mesh> = root.find_node("cube").unwrap();
|
||||
let mut root = root.borrow_mut();
|
||||
|
||||
let cube = root.find_node("cube").unwrap();
|
||||
let mut cube = cube.borrow_mut();
|
||||
let cube: &mut Mesh = match &mut cube.gameobject {
|
||||
GameObject::Mesh(mesh) => mesh,
|
||||
_ => panic!("cube is not a mesh"),
|
||||
};
|
||||
let mut transform = cube.get_transform();
|
||||
if device_manager.is_pressed(&device::Key::W) {
|
||||
transform.position.z += 1.0 * delta;
|
||||
@ -101,8 +115,6 @@ fn main() {
|
||||
};
|
||||
cube.model.draw(&mut target, &program, &uniforms, ¶ms);
|
||||
|
||||
let _camera: &mut Box<Camera> = root.find_node("camera").unwrap();
|
||||
|
||||
target.finish().unwrap();
|
||||
}
|
||||
_ => (),
|
||||
|
@ -1,8 +1,12 @@
|
||||
extern crate mlua;
|
||||
use crate::gameobject::{ Node, Transform, Spatial };
|
||||
|
||||
extern crate mlua;
|
||||
use mlua::Lua as LuaContext;
|
||||
use mlua::chunk;
|
||||
|
||||
use std::rc::Rc;
|
||||
use std::cell::RefCell;
|
||||
|
||||
pub trait ScriptLang {
|
||||
fn init(&mut self);
|
||||
fn update(&mut self, delta: f32);
|
||||
@ -12,12 +16,35 @@ pub struct Lua {
|
||||
ctx: LuaContext,
|
||||
}
|
||||
|
||||
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 {
|
||||
Some(child) => Ok(child),
|
||||
None => Err(mlua::Error::RuntimeError("Could not find child".to_string())),
|
||||
}
|
||||
});
|
||||
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()))
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl mlua::UserData for Transform {}
|
||||
|
||||
impl Lua {
|
||||
pub fn new() -> Self {
|
||||
pub fn new(root: Rc<RefCell<Node>>) -> Self {
|
||||
// Create a lua context, load std libraries
|
||||
let ctx = LuaContext::new();
|
||||
// Create the ``couch'' api
|
||||
let couch = ctx.create_table().unwrap();
|
||||
couch.set("root", ctx.create_userdata(root).unwrap()).unwrap();
|
||||
couch.set("debug", ctx.create_function(debug).unwrap()).unwrap();
|
||||
couch.set("say_hello", ctx.create_function(say_hello).unwrap()).unwrap();
|
||||
// Hook in to globals
|
||||
|
Loading…
Reference in New Issue
Block a user