Compare commits
2 Commits
d14abcc3e5
...
e5599e1d27
Author | SHA1 | Date |
---|---|---|
SeanOMik | e5599e1d27 | |
SeanOMik | 189d05e323 |
|
@ -1258,6 +1258,15 @@ dependencies = [
|
||||||
"either",
|
"either",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itertools"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0"
|
||||||
|
dependencies = [
|
||||||
|
"either",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "itoa"
|
name = "itoa"
|
||||||
version = "1.0.10"
|
version = "1.0.10"
|
||||||
|
@ -1413,6 +1422,7 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"lyra-ecs-derive",
|
"lyra-ecs-derive",
|
||||||
|
"lyra-math",
|
||||||
"rand",
|
"rand",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
]
|
]
|
||||||
|
@ -1447,8 +1457,9 @@ dependencies = [
|
||||||
"glam",
|
"glam",
|
||||||
"image",
|
"image",
|
||||||
"instant",
|
"instant",
|
||||||
"itertools",
|
"itertools 0.11.0",
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
|
"lyra-math",
|
||||||
"lyra-reflect",
|
"lyra-reflect",
|
||||||
"lyra-resource",
|
"lyra-resource",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1463,11 +1474,19 @@ dependencies = [
|
||||||
"winit",
|
"winit",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyra-math"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"glam",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lyra-reflect"
|
name = "lyra-reflect"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
|
"lyra-math",
|
||||||
"lyra-reflect-derive",
|
"lyra-reflect-derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1503,16 +1522,27 @@ name = "lyra-scripting"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
"itertools 0.12.0",
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
"lyra-game",
|
"lyra-game",
|
||||||
"lyra-reflect",
|
"lyra-reflect",
|
||||||
"lyra-resource",
|
"lyra-resource",
|
||||||
|
"lyra-scripting-derive",
|
||||||
"mlua",
|
"mlua",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lyra-scripting-derive"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.48",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mach2"
|
name = "mach2"
|
||||||
version = "0.4.2"
|
version = "0.4.2"
|
||||||
|
|
|
@ -10,7 +10,7 @@ members = [
|
||||||
"lyra-ecs",
|
"lyra-ecs",
|
||||||
"lyra-reflect",
|
"lyra-reflect",
|
||||||
"lyra-scripting",
|
"lyra-scripting",
|
||||||
"lyra-game"]
|
"lyra-game", "lyra-math"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
scripting = ["dep:lyra-scripting"]
|
scripting = ["dep:lyra-scripting"]
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
print("Hello World")
|
print("Hello World")
|
||||||
|
|
||||||
function on_init()
|
--[[ function on_init()
|
||||||
print("Lua script was initialized!")
|
print("Lua script was initialized!")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -10,16 +10,23 @@ end
|
||||||
|
|
||||||
function on_pre_update()
|
function on_pre_update()
|
||||||
print("Lua's pre-update function was called")
|
print("Lua's pre-update function was called")
|
||||||
end
|
end ]]
|
||||||
|
|
||||||
function on_update()
|
function on_update()
|
||||||
print("Lua's update function was called")
|
--print("Lua's update function was called")
|
||||||
|
|
||||||
|
world:view(function (t)
|
||||||
|
print("Found entity at " .. tostring(t))
|
||||||
|
t.translation = t.translation + Vec3.new(0, 0.0008, 0)
|
||||||
|
|
||||||
|
return t
|
||||||
|
end, Transform)
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_post_update()
|
--[[ function on_post_update()
|
||||||
print("Lua's post-update function was called")
|
print("Lua's post-update function was called")
|
||||||
end
|
end
|
||||||
|
|
||||||
function on_last()
|
function on_last()
|
||||||
print("Lua's last function was called")
|
print("Lua's last function was called")
|
||||||
end
|
end ]]
|
|
@ -1,6 +1,6 @@
|
||||||
use std::ptr::NonNull;
|
use std::ptr::NonNull;
|
||||||
|
|
||||||
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin, MouseInput, MouseAxis, CommonActionLabel}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{TransformComponent, ModelComponent, CameraComponent}, lua::{LuaScriptingPlugin, LuaScript}, Script, ScriptList};
|
use lyra_engine::{math::{self, Vec3}, math::Transform, input::{KeyCode, ActionHandler, Action, ActionKind, LayoutId, ActionMapping, ActionSource, ActionMappingId, InputActionPlugin, MouseInput, MouseAxis, CommonActionLabel}, game::Game, render::{window::{CursorGrabMode, WindowOptions}, light::{PointLight, directional::DirectionalLight, SpotLight}}, change_tracker::Ct, ecs::{system::{Criteria, CriteriaSchedule, BatchedSystem, IntoSystem}, world::World, Component}, DeltaTime, scene::{ModelComponent, CameraComponent}, lua::{LuaScriptingPlugin, LuaScript}, Script, ScriptList};
|
||||||
use lyra_engine::assets::{ResourceManager, Model};
|
use lyra_engine::assets::{ResourceManager, Model};
|
||||||
|
|
||||||
mod free_fly_camera;
|
mod free_fly_camera;
|
||||||
|
@ -77,9 +77,9 @@ struct CubeFlag;
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let setup_sys = |world: &mut World| -> anyhow::Result<()> {
|
let setup_sys = |world: &mut World| -> anyhow::Result<()> {
|
||||||
{
|
{
|
||||||
let mut window_options = world.get_resource_mut::<Ct<WindowOptions>>();
|
/* let mut window_options = world.get_resource_mut::<Ct<WindowOptions>>();
|
||||||
window_options.cursor_grab = CursorGrabMode::Confined;
|
window_options.cursor_grab = CursorGrabMode::Confined;
|
||||||
window_options.cursor_visible = false;
|
window_options.cursor_visible = false; */
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut resman = world.get_resource_mut::<ResourceManager>();
|
let mut resman = world.get_resource_mut::<ResourceManager>();
|
||||||
|
@ -92,14 +92,14 @@ async fn main() {
|
||||||
|
|
||||||
world.spawn((
|
world.spawn((
|
||||||
ModelComponent(antique_camera_model),
|
ModelComponent(antique_camera_model),
|
||||||
TransformComponent::from(Transform::from_xyz(0.0, -5.0, -10.0)),
|
Transform::from_xyz(0.0, -5.0, -10.0),
|
||||||
));
|
));
|
||||||
|
|
||||||
{
|
{
|
||||||
let cube_tran = Transform::from_xyz(-3.5, 0.0, -8.0);
|
let cube_tran = Transform::from_xyz(-3.5, 0.0, -8.0);
|
||||||
//cube_tran.rotate_y(math::Angle::Degrees(180.0));
|
//cube_tran.rotate_y(math::Angle::Degrees(180.0));
|
||||||
world.spawn((
|
world.spawn((
|
||||||
TransformComponent::from(cube_tran),
|
cube_tran,
|
||||||
ModelComponent(crate_model.clone()),
|
ModelComponent(crate_model.clone()),
|
||||||
CubeFlag,
|
CubeFlag,
|
||||||
));
|
));
|
||||||
|
@ -117,7 +117,7 @@ async fn main() {
|
||||||
diffuse: 1.0,
|
diffuse: 1.0,
|
||||||
specular: 1.3,
|
specular: 1.3,
|
||||||
},
|
},
|
||||||
TransformComponent::from(light_tran),
|
light_tran,
|
||||||
ModelComponent(cube_model.clone()),
|
ModelComponent(cube_model.clone()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -139,7 +139,7 @@ async fn main() {
|
||||||
diffuse: 7.0,
|
diffuse: 7.0,
|
||||||
specular: 1.0,
|
specular: 1.0,
|
||||||
},
|
},
|
||||||
TransformComponent::from(light_tran),
|
Transform::from(light_tran),
|
||||||
ModelComponent(cube_model.clone()),
|
ModelComponent(cube_model.clone()),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ async fn main() {
|
||||||
diffuse: 1.0,
|
diffuse: 1.0,
|
||||||
specular: 1.3,
|
specular: 1.3,
|
||||||
},
|
},
|
||||||
TransformComponent::from(light_tran),
|
Transform::from(light_tran),
|
||||||
ModelComponent(cube_model),
|
ModelComponent(cube_model),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -214,13 +214,13 @@ async fn main() {
|
||||||
const SPEED: f32 = 4.0;
|
const SPEED: f32 = 4.0;
|
||||||
let delta_time = **world.get_resource::<DeltaTime>();
|
let delta_time = **world.get_resource::<DeltaTime>();
|
||||||
|
|
||||||
for (mut transform, _) in world.view_iter::<(&mut TransformComponent, &CubeFlag)>() {
|
for (mut transform, _) in world.view_iter::<(&mut Transform, &CubeFlag)>() {
|
||||||
let t = &mut transform.transform;
|
let t = &mut transform;
|
||||||
t.rotate_y(math::Angle::Degrees(SPEED * delta_time));
|
t.rotate_y(math::Angle::Degrees(SPEED * delta_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (mut transform, _s) in world.view_iter::<(&mut TransformComponent, &mut SpotLight)>() {
|
for (mut transform, _s) in world.view_iter::<(&mut Transform, &mut SpotLight)>() {
|
||||||
let t = &mut transform.transform;
|
let t = &mut transform;
|
||||||
t.rotate_x(math::Angle::Degrees(SPEED * delta_time));
|
t.rotate_x(math::Angle::Degrees(SPEED * delta_time));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,8 +235,8 @@ async fn main() {
|
||||||
sys.with_system(spin_system.into_system());
|
sys.with_system(spin_system.into_system());
|
||||||
//sys.with_system(fps_system);
|
//sys.with_system(fps_system);
|
||||||
|
|
||||||
game.with_system("fixed", sys, &[]);
|
//game.with_system("fixed", sys, &[]);
|
||||||
fps_plugin(game);
|
//fps_plugin(game);
|
||||||
};
|
};
|
||||||
|
|
||||||
let action_handler_plugin = |game: &mut Game| {
|
let action_handler_plugin = |game: &mut Game| {
|
||||||
|
@ -293,7 +293,9 @@ async fn main() {
|
||||||
Ok(())
|
Ok(())
|
||||||
}; */
|
}; */
|
||||||
|
|
||||||
game.world().add_resource(action_handler);
|
let world = game.world();
|
||||||
|
world.add_resource(action_handler);
|
||||||
|
world.spawn((Vec3::new(0.5, 0.1, 3.0),));
|
||||||
game.with_plugin(InputActionPlugin);
|
game.with_plugin(InputActionPlugin);
|
||||||
//game.with_system("input_test", test_system, &[]);
|
//game.with_system("input_test", test_system, &[]);
|
||||||
};
|
};
|
||||||
|
|
|
@ -6,13 +6,13 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
math = ["dep:glam"]
|
math = ["dep:lyra-math"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lyra-ecs-derive = { path = "./lyra-ecs-derive" }
|
lyra-ecs-derive = { path = "./lyra-ecs-derive" }
|
||||||
|
lyra-math = { path = "../lyra-math", optional = true }
|
||||||
anyhow = "1.0.75"
|
anyhow = "1.0.75"
|
||||||
thiserror = "1.0.50"
|
thiserror = "1.0.50"
|
||||||
glam = { version = "0.24.0", optional = true }
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
rand = "0.8.5" # used for tests
|
rand = "0.8.5" # used for tests
|
||||||
|
|
|
@ -210,6 +210,8 @@ impl ArchetypeId {
|
||||||
pub struct Archetype {
|
pub struct Archetype {
|
||||||
pub id: ArchetypeId,
|
pub id: ArchetypeId,
|
||||||
pub(crate) entities: HashMap<Entity, ArchetypeEntityId>,
|
pub(crate) entities: HashMap<Entity, ArchetypeEntityId>,
|
||||||
|
/// map an Archetype entity id to an entity
|
||||||
|
pub(crate) ids_to_entity: HashMap<ArchetypeEntityId, Entity>,
|
||||||
pub(crate) columns: Vec<ComponentColumn>,
|
pub(crate) columns: Vec<ComponentColumn>,
|
||||||
pub capacity: usize,
|
pub capacity: usize,
|
||||||
}
|
}
|
||||||
|
@ -226,6 +228,7 @@ impl Archetype {
|
||||||
Archetype {
|
Archetype {
|
||||||
id: new_id,
|
id: new_id,
|
||||||
entities: HashMap::new(),
|
entities: HashMap::new(),
|
||||||
|
ids_to_entity: HashMap::new(),
|
||||||
columns,
|
columns,
|
||||||
capacity: DEFAULT_CAPACITY,
|
capacity: DEFAULT_CAPACITY,
|
||||||
}
|
}
|
||||||
|
@ -246,16 +249,17 @@ impl Archetype {
|
||||||
self.capacity = new_cap;
|
self.capacity = new_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
let entity_index = self.entities.len();
|
let entity_index = ArchetypeEntityId(self.entities.len() as u64);
|
||||||
self.entities.insert(entity, ArchetypeEntityId(entity_index as u64));
|
self.entities.insert(entity, entity_index);
|
||||||
|
self.ids_to_entity.insert(entity_index, entity);
|
||||||
|
|
||||||
bundle.take(|data, type_id, _size| {
|
bundle.take(|data, type_id, _size| {
|
||||||
let col = self.get_column_mut(type_id).unwrap();
|
let col = self.get_column_mut(type_id).unwrap();
|
||||||
unsafe { col.set_at(entity_index, data, *tick); }
|
unsafe { col.set_at(entity_index.0 as usize, data, *tick); }
|
||||||
col.len += 1;
|
col.len += 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
ArchetypeEntityId(entity_index as u64)
|
entity_index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes an entity from the Archetype and frees its components. Returns the entity record that took its place in the component column.
|
/// Removes an entity from the Archetype and frees its components. Returns the entity record that took its place in the component column.
|
||||||
|
@ -286,6 +290,7 @@ impl Archetype {
|
||||||
|
|
||||||
// safe from the .expect at the start of this method.
|
// safe from the .expect at the start of this method.
|
||||||
self.entities.remove(&entity).unwrap();
|
self.entities.remove(&entity).unwrap();
|
||||||
|
self.ids_to_entity.remove(&entity_index).unwrap();
|
||||||
|
|
||||||
// now change the ArchetypeEntityId to be the index that the moved entity was moved into.
|
// now change the ArchetypeEntityId to be the index that the moved entity was moved into.
|
||||||
removed_entity.map(|(e, _a)| (e, entity_index))
|
removed_entity.map(|(e, _a)| (e, entity_index))
|
||||||
|
@ -351,14 +356,15 @@ impl Archetype {
|
||||||
self.capacity = new_cap;
|
self.capacity = new_cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
let entity_index = self.entities.len();
|
let entity_index = ArchetypeEntityId(self.entities.len() as u64);
|
||||||
self.entities.insert(entity, ArchetypeEntityId(entity_index as u64));
|
self.entities.insert(entity, entity_index);
|
||||||
|
self.ids_to_entity.insert(entity_index, entity);
|
||||||
|
|
||||||
for col in self.columns.iter_mut() {
|
for col in self.columns.iter_mut() {
|
||||||
col.len += 1;
|
col.len += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ArchetypeEntityId(entity_index as u64)
|
entity_index
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Moves the entity from this archetype into another one.
|
/// Moves the entity from this archetype into another one.
|
||||||
|
@ -401,6 +407,10 @@ impl Archetype {
|
||||||
pub fn entities(&self) -> &HashMap<Entity, ArchetypeEntityId> {
|
pub fn entities(&self) -> &HashMap<Entity, ArchetypeEntityId> {
|
||||||
&self.entities
|
&self.entities
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn entity_of_index(&self, id: ArchetypeEntityId) -> Option<Entity> {
|
||||||
|
self.ids_to_entity.get(&id).cloned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use crate::Component;
|
use crate::Component;
|
||||||
|
|
||||||
use glam::{Vec3, Quat, Vec2, Vec4, Mat4};
|
use lyra_math::{Vec3, Quat, Vec2, Vec4, Mat4, Transform};
|
||||||
|
|
||||||
macro_rules! impl_component_math {
|
macro_rules! impl_external_component {
|
||||||
($type: ident) => {
|
($type: ident) => {
|
||||||
impl Component for $type {
|
impl Component for $type {
|
||||||
fn name() -> &'static str {
|
fn name() -> &'static str {
|
||||||
|
@ -12,8 +12,9 @@ macro_rules! impl_component_math {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_component_math!(Vec2);
|
impl_external_component!(Vec2);
|
||||||
impl_component_math!(Vec3);
|
impl_external_component!(Vec3);
|
||||||
impl_component_math!(Vec4);
|
impl_external_component!(Vec4);
|
||||||
impl_component_math!(Mat4);
|
impl_external_component!(Mat4);
|
||||||
impl_component_math!(Quat);
|
impl_external_component!(Quat);
|
||||||
|
impl_external_component!(Transform);
|
|
@ -209,6 +209,16 @@ impl World {
|
||||||
current_arch.remove_entity(entity, &tick);
|
current_arch.remove_entity(entity, &tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn entity_archetype(&self, entity: Entity) -> Option<&Archetype> {
|
||||||
|
self.entity_index.get(&entity.id)
|
||||||
|
.and_then(|record| self.archetypes.get(&record.id))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn entity_archetype_mut(&mut self, entity: Entity) -> Option<&mut Archetype> {
|
||||||
|
self.entity_index.get_mut(&entity.id)
|
||||||
|
.and_then(|record| self.archetypes.get_mut(&record.id))
|
||||||
|
}
|
||||||
|
|
||||||
/// View into the world for a set of entities that satisfy the queries.
|
/// View into the world for a set of entities that satisfy the queries.
|
||||||
pub fn view_iter<T: 'static + AsQuery>(&self) -> ViewIter<T::Query> {
|
pub fn view_iter<T: 'static + AsQuery>(&self) -> ViewIter<T::Query> {
|
||||||
let archetypes = self.archetypes.values().collect();
|
let archetypes = self.archetypes.values().collect();
|
||||||
|
|
|
@ -7,6 +7,7 @@ edition = "2021"
|
||||||
lyra-resource = { path = "../lyra-resource" }
|
lyra-resource = { path = "../lyra-resource" }
|
||||||
lyra-ecs = { path = "../lyra-ecs", features = [ "math" ] }
|
lyra-ecs = { path = "../lyra-ecs", features = [ "math" ] }
|
||||||
lyra-reflect = { path = "../lyra-reflect", features = [ "math" ] }
|
lyra-reflect = { path = "../lyra-reflect", features = [ "math" ] }
|
||||||
|
lyra-math = { path = "../lyra-math" }
|
||||||
|
|
||||||
winit = "0.28.1"
|
winit = "0.28.1"
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
|
|
|
@ -7,7 +7,6 @@ extern crate self as lyra_engine;
|
||||||
pub mod game;
|
pub mod game;
|
||||||
pub mod render;
|
pub mod render;
|
||||||
pub mod resources;
|
pub mod resources;
|
||||||
pub mod math;
|
|
||||||
pub mod input;
|
pub mod input;
|
||||||
pub mod castable_any;
|
pub mod castable_any;
|
||||||
pub mod plugin;
|
pub mod plugin;
|
||||||
|
@ -26,6 +25,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;
|
||||||
|
|
||||||
#[cfg(feature = "scripting")]
|
#[cfg(feature = "scripting")]
|
||||||
pub use lyra_scripting as script;
|
pub use lyra_scripting as script;
|
||||||
|
|
|
@ -12,7 +12,7 @@ use tracing::debug;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use crate::{math::Transform, scene::TransformComponent};
|
use crate::math::Transform;
|
||||||
|
|
||||||
use self::directional::DirectionalLight;
|
use self::directional::DirectionalLight;
|
||||||
|
|
||||||
|
@ -169,29 +169,29 @@ impl LightUniformBuffers {
|
||||||
|
|
||||||
pub fn update_lights(&mut self, queue: &wgpu::Queue, world_tick: Tick, world: &World) {
|
pub fn update_lights(&mut self, queue: &wgpu::Queue, world_tick: Tick, world: &World) {
|
||||||
for (entity, point_light, transform, light_epoch, transform_epoch)
|
for (entity, point_light, transform, light_epoch, transform_epoch)
|
||||||
in world.view_iter::<(Entities, &PointLight, &TransformComponent, TickOf<PointLight>, TickOf<TransformComponent>)>() {
|
in world.view_iter::<(Entities, &PointLight, &Transform, TickOf<PointLight>, TickOf<Transform>)>() {
|
||||||
|
|
||||||
if !self.point_lights.has_light(entity) || light_epoch == world_tick || transform_epoch == world_tick {
|
if !self.point_lights.has_light(entity) || light_epoch == world_tick || transform_epoch == world_tick {
|
||||||
let uniform = PointLightUniform::from_bundle(&point_light, &transform.transform);
|
let uniform = PointLightUniform::from_bundle(&point_light, &transform);
|
||||||
self.point_lights.update_or_add(&mut self.lights_uniform.point_lights, entity, uniform);
|
self.point_lights.update_or_add(&mut self.lights_uniform.point_lights, entity, uniform);
|
||||||
debug!("Updated point light");
|
debug!("Updated point light");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (entity, spot_light, transform, light_epoch, transform_epoch)
|
for (entity, spot_light, transform, light_epoch, transform_epoch)
|
||||||
in world.view_iter::<(Entities, &SpotLight, &TransformComponent, TickOf<SpotLight>, TickOf<TransformComponent>)>() {
|
in world.view_iter::<(Entities, &SpotLight, &Transform, TickOf<SpotLight>, TickOf<Transform>)>() {
|
||||||
|
|
||||||
if !self.spot_lights.has_light(entity) || light_epoch == world_tick || transform_epoch == world_tick {
|
if !self.spot_lights.has_light(entity) || light_epoch == world_tick || transform_epoch == world_tick {
|
||||||
let uniform = SpotLightUniform::from_bundle(&spot_light, &transform.transform);
|
let uniform = SpotLightUniform::from_bundle(&spot_light, &transform);
|
||||||
self.spot_lights.update_or_add(&mut self.lights_uniform.spot_lights, entity, uniform);
|
self.spot_lights.update_or_add(&mut self.lights_uniform.spot_lights, entity, uniform);
|
||||||
//debug!("Updated spot light");
|
//debug!("Updated spot light");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((dir_light, transform)) =
|
if let Some((dir_light, transform)) =
|
||||||
world.view_iter::<(&DirectionalLight, &TransformComponent)>().next() {
|
world.view_iter::<(&DirectionalLight, &Transform)>().next() {
|
||||||
|
|
||||||
let uniform = DirectionalLightUniform::from_bundle(&dir_light, &transform.transform);
|
let uniform = DirectionalLightUniform::from_bundle(&dir_light, &transform);
|
||||||
self.lights_uniform.directional_light = uniform;
|
self.lights_uniform.directional_light = uniform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ use winit::window::Window;
|
||||||
use crate::math::Transform;
|
use crate::math::Transform;
|
||||||
use crate::render::material::MaterialUniform;
|
use crate::render::material::MaterialUniform;
|
||||||
use crate::render::render_buffer::BufferWrapperBuilder;
|
use crate::render::render_buffer::BufferWrapperBuilder;
|
||||||
use crate::scene::{ModelComponent, TransformComponent, CameraComponent};
|
use crate::scene::{ModelComponent, CameraComponent};
|
||||||
|
|
||||||
use super::camera::{RenderCamera, CameraUniform};
|
use super::camera::{RenderCamera, CameraUniform};
|
||||||
use super::desc_buf_lay::DescVertexBufferLayout;
|
use super::desc_buf_lay::DescVertexBufferLayout;
|
||||||
|
@ -395,13 +395,13 @@ impl Renderer for BasicRenderer {
|
||||||
|
|
||||||
let now_inst = Instant::now();
|
let now_inst = Instant::now();
|
||||||
|
|
||||||
for (entity, model, model_epoch, transform, transform_epoch) in main_world.view_iter::<(Entities, &ModelComponent, TickOf<ModelComponent>, &TransformComponent, TickOf<TransformComponent>)>() {
|
for (entity, model, model_epoch, transform, transform_epoch) in main_world.view_iter::<(Entities, &ModelComponent, TickOf<ModelComponent>, &Transform, TickOf<Transform>)>() {
|
||||||
alive_entities.insert(entity);
|
alive_entities.insert(entity);
|
||||||
|
|
||||||
let cached = match self.entity_last_transforms.get_mut(&entity) {
|
let cached = match self.entity_last_transforms.get_mut(&entity) {
|
||||||
Some(last) if transform_epoch == last_epoch => {
|
Some(last) if transform_epoch == last_epoch => {
|
||||||
last.from_transform = last.to_transform;
|
last.from_transform = last.to_transform;
|
||||||
last.to_transform = transform.transform;
|
last.to_transform = *transform;
|
||||||
last.last_updated_at = Some(last.cached_at);
|
last.last_updated_at = Some(last.cached_at);
|
||||||
last.cached_at = now_inst;
|
last.cached_at = now_inst;
|
||||||
|
|
||||||
|
@ -412,8 +412,8 @@ impl Renderer for BasicRenderer {
|
||||||
let cached = CachedTransform {
|
let cached = CachedTransform {
|
||||||
last_updated_at: None,
|
last_updated_at: None,
|
||||||
cached_at: now_inst,
|
cached_at: now_inst,
|
||||||
from_transform: transform.transform,
|
from_transform: *transform,
|
||||||
to_transform: transform.transform,
|
to_transform: *transform,
|
||||||
};
|
};
|
||||||
self.entity_last_transforms.insert(entity, cached.clone());
|
self.entity_last_transforms.insert(entity, cached.clone());
|
||||||
cached
|
cached
|
||||||
|
|
|
@ -4,9 +4,6 @@ pub use mesh::*;
|
||||||
pub mod model;
|
pub mod model;
|
||||||
pub use model::*;
|
pub use model::*;
|
||||||
|
|
||||||
pub mod transform;
|
|
||||||
pub use transform::*;
|
|
||||||
|
|
||||||
pub mod camera;
|
pub mod camera;
|
||||||
pub use camera::*;
|
pub use camera::*;
|
||||||
|
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
use lyra_ecs::Component;
|
|
||||||
|
|
||||||
use crate::math::Transform;
|
|
||||||
|
|
||||||
#[derive(Clone, Component, Default)]
|
|
||||||
pub struct TransformComponent {
|
|
||||||
pub transform: Transform,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Transform> for TransformComponent {
|
|
||||||
fn from(transform: Transform) -> Self {
|
|
||||||
Self {
|
|
||||||
transform
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TransformComponent {
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_transform(transform: Transform) -> Self {
|
|
||||||
Self::from(transform)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
[package]
|
||||||
|
name = "lyra-math"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2021"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
glam = { version = "0.24.0" }
|
|
@ -1,9 +1,9 @@
|
||||||
use glam::{Vec3, Mat4, Quat};
|
use glam::{Vec3, Mat4, Quat};
|
||||||
|
|
||||||
use crate::math::angle::Angle;
|
use super::Angle;
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||||
pub struct Transform {
|
pub struct Transform {
|
||||||
pub translation: Vec3,
|
pub translation: Vec3,
|
||||||
pub rotation: Quat,
|
pub rotation: Quat,
|
||||||
|
@ -104,3 +104,17 @@ impl Transform {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds a transform to another one
|
||||||
|
///
|
||||||
|
/// The Translations of each transform is added and rotation and scale is multiplied.
|
||||||
|
impl std::ops::Add for Transform {
|
||||||
|
type Output = Transform;
|
||||||
|
|
||||||
|
fn add(mut self, rhs: Self) -> Self::Output {
|
||||||
|
self.translation += rhs.translation;
|
||||||
|
self.rotation *= rhs.rotation;
|
||||||
|
self.scale *= rhs.scale;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,9 +6,9 @@ edition = "2021"
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
math = ["dep:glam"]
|
math = ["dep:lyra-math"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
lyra-reflect-derive = { path = "lyra-reflect-derive" }
|
lyra-reflect-derive = { path = "lyra-reflect-derive" }
|
||||||
lyra-ecs = { path = "../lyra-ecs" }
|
lyra-ecs = { path = "../lyra-ecs" }
|
||||||
glam = { version = "0.24.0", optional = true }
|
lyra-math = { path = "../lyra-math", optional = true }
|
|
@ -4,7 +4,7 @@ use syn::{Token, parenthesized, punctuated::Punctuated};
|
||||||
struct Field {
|
struct Field {
|
||||||
name: syn::Ident,
|
name: syn::Ident,
|
||||||
_eq: Token![=],
|
_eq: Token![=],
|
||||||
ty: syn::Ident,
|
ty: syn::Path,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl syn::parse::Parse for Field {
|
impl syn::parse::Parse for Field {
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
use lyra_reflect_derive::{impl_reflect_simple_struct, impl_reflect_trait_value};
|
use lyra_reflect_derive::{impl_reflect_simple_struct, impl_reflect_trait_value};
|
||||||
|
|
||||||
use crate::{lyra_engine, Reflect, Method};
|
use crate::{lyra_engine, Method, Reflect};
|
||||||
|
|
||||||
impl_reflect_simple_struct!(glam::Vec2, fields(x=f32, y=f32));
|
impl_reflect_simple_struct!(lyra_math::Vec2, fields(x = f32, y = f32));
|
||||||
impl_reflect_simple_struct!(glam::Vec3, fields(x=f32, y=f32, z=f32));
|
impl_reflect_simple_struct!(lyra_math::Vec3, fields(x = f32, y = f32, z = f32));
|
||||||
impl_reflect_simple_struct!(glam::Vec4, fields(x=f32, y=f32, z=f32, w=f32));
|
impl_reflect_simple_struct!(lyra_math::Vec4, fields(x = f32, y = f32, z = f32, w = f32));
|
||||||
impl_reflect_simple_struct!(glam::Quat, fields(x=f32, y=f32, z=f32, w=f32));
|
impl_reflect_simple_struct!(lyra_math::Quat, fields(x = f32, y = f32, z = f32, w = f32));
|
||||||
|
|
||||||
impl_reflect_trait_value!(glam::Mat4);
|
impl_reflect_simple_struct!(
|
||||||
|
lyra_math::Transform,
|
||||||
|
fields(
|
||||||
|
translation = lyra_math::Vec3,
|
||||||
|
rotation = lyra_math::Quat,
|
||||||
|
scale = lyra_math::Vec3
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
impl_reflect_trait_value!(lyra_math::Mat4);
|
||||||
|
|
|
@ -21,6 +21,7 @@ tracing = "0.1.37"
|
||||||
|
|
||||||
# enabled with lua feature
|
# enabled with lua feature
|
||||||
mlua = { version = "0.9.2", features = ["lua54"], optional = true } # luajit maybe?
|
mlua = { version = "0.9.2", features = ["lua54"], optional = true } # luajit maybe?
|
||||||
|
itertools = "0.12.0"
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
|
|
@ -220,6 +220,9 @@ pub(crate) struct WrapUsage {
|
||||||
|
|
||||||
pub matrix: Option<MatWrapper>,
|
pub matrix: Option<MatWrapper>,
|
||||||
pub vec: Option<VecWrapper>,
|
pub vec: Option<VecWrapper>,
|
||||||
|
|
||||||
|
pub custom_methods: Option<syn::Block>,
|
||||||
|
pub custom_fields: Option<syn::Block>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl syn::parse::Parse for WrapUsage {
|
impl syn::parse::Parse for WrapUsage {
|
||||||
|
@ -234,6 +237,8 @@ impl syn::parse::Parse for WrapUsage {
|
||||||
meta_method_idents: Punctuated::default(),
|
meta_method_idents: Punctuated::default(),
|
||||||
matrix: None,
|
matrix: None,
|
||||||
vec: None,
|
vec: None,
|
||||||
|
custom_methods: None,
|
||||||
|
custom_fields: None,
|
||||||
};
|
};
|
||||||
/* let mut derive_idents = None;
|
/* let mut derive_idents = None;
|
||||||
let mut field_idents = None;
|
let mut field_idents = None;
|
||||||
|
@ -298,6 +303,14 @@ impl syn::parse::Parse for WrapUsage {
|
||||||
s.meta_method_idents = meta_methods;
|
s.meta_method_idents = meta_methods;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"custom_methods" => {
|
||||||
|
let methods_block = input.parse()?;
|
||||||
|
s.custom_methods = Some(methods_block);
|
||||||
|
},
|
||||||
|
"custom_fields" => {
|
||||||
|
let block = input.parse()?;
|
||||||
|
s.custom_fields = Some(block);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err(syn::Error::new_spanned(ident, "unknown wrapper command"));
|
return Err(syn::Error::new_spanned(ident, "unknown wrapper command"));
|
||||||
}
|
}
|
||||||
|
@ -335,6 +348,8 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
vec.to_method_tokens(&path, &wrapper_typename));
|
vec.to_method_tokens(&path, &wrapper_typename));
|
||||||
|
|
||||||
let derive_idents_iter = input.derive_idents.iter();
|
let derive_idents_iter = input.derive_idents.iter();
|
||||||
|
let custom_methods = input.custom_methods;
|
||||||
|
let custom_fields = input.custom_fields;
|
||||||
|
|
||||||
let field_get_set_pairs = input.field_idents.iter().map(|i| {
|
let field_get_set_pairs = input.field_idents.iter().map(|i| {
|
||||||
let is = i.to_string();
|
let is = i.to_string();
|
||||||
|
@ -566,7 +581,7 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua mlua::Lua) -> mlua::Result<Self> {
|
fn from_lua(value: mlua::Value<'lua>, _lua: &'lua mlua::Lua) -> mlua::Result<Self> {
|
||||||
match value {
|
match value {
|
||||||
mlua::Value::UserData(ud) => Ok(*ud.borrow::<Self>()?),
|
mlua::Value::UserData(ud) => Ok(*ud.borrow::<Self>()?),
|
||||||
_ => unreachable!(),
|
_ => panic!("Attempt to get {} from a {} value", stringify!(#wrapper_typename), value.type_name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -577,6 +592,8 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
|
|
||||||
#matrix_wrapper_fields
|
#matrix_wrapper_fields
|
||||||
#vec_wrapper_fields
|
#vec_wrapper_fields
|
||||||
|
|
||||||
|
#custom_fields
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -594,12 +611,16 @@ pub fn wrap_math_vec_copy(input: proc_macro::TokenStream) -> proc_macro::TokenSt
|
||||||
|
|
||||||
#matrix_wrapper_methods
|
#matrix_wrapper_methods
|
||||||
#vec_wrapper_methods
|
#vec_wrapper_methods
|
||||||
|
|
||||||
|
#custom_methods
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl lyra_scripting::lua::LuaWrapper for #wrapper_typename {
|
impl lyra_scripting::lua::LuaWrapper for #wrapper_typename {
|
||||||
fn wrapped_type_id() -> std::any::TypeId {
|
fn wrapped_type_id() -> std::any::TypeId {
|
||||||
std::any::TypeId::of::<#path>()
|
let t = std::any::TypeId::of::<#path>();
|
||||||
|
println!("Got id of {}, it is {:?}", stringify!(#path), t);
|
||||||
|
t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use std::{ptr::NonNull, ops::{Range, Deref}};
|
use std::{ptr::NonNull, ops::{Range, Deref}};
|
||||||
|
|
||||||
use lyra_ecs::{ComponentColumn, ComponentInfo, Archetype, ArchetypeId, ArchetypeEntityId, query::dynamic::{DynamicType, QueryDynamicType}, query::Fetch};
|
use lyra_ecs::{ComponentColumn, ComponentInfo, Archetype, ArchetypeId, ArchetypeEntityId, query::dynamic::{DynamicType, QueryDynamicType}, query::Fetch, Entity};
|
||||||
use lyra_reflect::TypeRegistry;
|
use lyra_reflect::TypeRegistry;
|
||||||
|
|
||||||
#[cfg(feature = "lua")]
|
#[cfg(feature = "lua")]
|
||||||
|
@ -45,6 +45,11 @@ impl<'a> From<lyra_ecs::query::dynamic::FetchDynamicType<'a>> for FetchDynamicTy
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct DynamicViewRow {
|
||||||
|
entity: Entity,
|
||||||
|
item: Vec<DynamicType>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DynamicViewIter {
|
pub struct DynamicViewIter {
|
||||||
world_ptr: ScriptWorldPtr,
|
world_ptr: ScriptWorldPtr,
|
||||||
|
@ -69,15 +74,15 @@ impl<'a> From<lyra_ecs::query::dynamic::DynamicViewIter<'a>> for DynamicViewIter
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Iterator for DynamicViewIter {
|
impl Iterator for DynamicViewIter {
|
||||||
type Item = Vec<DynamicType>;
|
type Item = DynamicViewRow;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
loop {
|
loop {
|
||||||
if let Some(entity_index) = self.component_indices.next() {
|
if let Some(entity_index) = self.component_indices.next() {
|
||||||
let mut fetch_res = vec![];
|
let mut fetch_res = vec![];
|
||||||
|
|
||||||
for fetcher in self.fetchers.iter_mut() {
|
|
||||||
let entity_index = ArchetypeEntityId(entity_index);
|
let entity_index = ArchetypeEntityId(entity_index);
|
||||||
|
for fetcher in self.fetchers.iter_mut() {
|
||||||
if !fetcher.can_visit_item(entity_index) {
|
if !fetcher.can_visit_item(entity_index) {
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
|
@ -90,7 +95,14 @@ impl Iterator for DynamicViewIter {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Some(fetch_res);
|
let arch = unsafe { self.archetypes.get_unchecked(self.next_archetype - 1).as_ref() };
|
||||||
|
let entity = arch.entity_of_index(entity_index).unwrap();
|
||||||
|
let row = DynamicViewRow {
|
||||||
|
entity,
|
||||||
|
item: fetch_res,
|
||||||
|
};
|
||||||
|
|
||||||
|
return Some(row);
|
||||||
} else {
|
} else {
|
||||||
if self.next_archetype >= self.archetypes.len() {
|
if self.next_archetype >= self.archetypes.len() {
|
||||||
return None; // ran out of archetypes to go through
|
return None; // ran out of archetypes to go through
|
||||||
|
@ -121,6 +133,19 @@ impl Iterator for DynamicViewIter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "lua")]
|
||||||
|
pub struct ReflectedItem<'a> {
|
||||||
|
pub proxy: &'a ReflectLuaProxy,
|
||||||
|
pub comp_ptr: NonNull<u8>,
|
||||||
|
pub comp_ud: mlua::AnyUserData<'a>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "lua")]
|
||||||
|
pub struct ReflectedRow<'a> {
|
||||||
|
pub entity: Entity,
|
||||||
|
pub row: Vec<ReflectedItem<'a>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct ReflectedIterator {
|
pub struct ReflectedIterator {
|
||||||
pub world: ScriptWorldPtr,
|
pub world: ScriptWorldPtr,
|
||||||
pub dyn_view: DynamicViewIter,
|
pub dyn_view: DynamicViewIter,
|
||||||
|
@ -131,7 +156,7 @@ impl ReflectedIterator {
|
||||||
|
|
||||||
|
|
||||||
#[cfg(feature = "lua")]
|
#[cfg(feature = "lua")]
|
||||||
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<Vec<( (&'a ReflectLuaProxy, NonNull<u8>), mlua::AnyUserData<'a>)>> {
|
pub fn next_lua<'a>(&mut self, lua: &'a mlua::Lua) -> Option<ReflectedRow<'a>> {
|
||||||
|
|
||||||
let n = self.dyn_view.next();
|
let n = self.dyn_view.next();
|
||||||
|
|
||||||
|
@ -142,8 +167,13 @@ impl ReflectedIterator {
|
||||||
.map(|r| NonNull::from(r.deref()));
|
.map(|r| NonNull::from(r.deref()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut dynamic_row = Vec::new();
|
/* let mut row = ReflectedRow {
|
||||||
for d in row.iter() {
|
entity: row.entity,
|
||||||
|
row: row.item,
|
||||||
|
}; */
|
||||||
|
|
||||||
|
let mut dynamic_row = vec![];
|
||||||
|
for d in row.item.iter() {
|
||||||
let id = d.info.type_id.as_rust();
|
let id = d.info.type_id.as_rust();
|
||||||
let reflected_components =
|
let reflected_components =
|
||||||
unsafe { self.reflected_components.as_ref().unwrap().as_ref() };
|
unsafe { self.reflected_components.as_ref().unwrap().as_ref() };
|
||||||
|
@ -155,10 +185,20 @@ impl ReflectedIterator {
|
||||||
|
|
||||||
let userdata = (proxy.fn_as_uservalue)(lua, d.ptr).unwrap();
|
let userdata = (proxy.fn_as_uservalue)(lua, d.ptr).unwrap();
|
||||||
|
|
||||||
dynamic_row.push(( (proxy, d.ptr), userdata));
|
dynamic_row.push(ReflectedItem {
|
||||||
|
proxy,
|
||||||
|
comp_ptr: d.ptr,
|
||||||
|
comp_ud: userdata
|
||||||
|
});
|
||||||
|
//dynamic_row.push(( (proxy, d.ptr), userdata));
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(dynamic_row)
|
let row = ReflectedRow {
|
||||||
|
entity: row.entity,
|
||||||
|
row: dynamic_row
|
||||||
|
};
|
||||||
|
|
||||||
|
Some(row)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use lyra_ecs::World;
|
use lyra_ecs::World;
|
||||||
use lyra_game::math;
|
use lyra_game::math;
|
||||||
use crate::lua::RegisterLuaType;
|
use crate::lua::RegisterLuaType;
|
||||||
use crate::lua::wrappers::LuaVec3;
|
use crate::lua::wrappers::{LuaVec3, LuaTransform};
|
||||||
|
|
||||||
use crate::{ScriptApiProvider, lua::LuaContext};
|
use crate::{ScriptApiProvider, lua::LuaContext};
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ impl ScriptApiProvider for LyraMathApiProvider {
|
||||||
|
|
||||||
fn prepare_world(&mut self, world: &mut World) {
|
fn prepare_world(&mut self, world: &mut World) {
|
||||||
world.register_lua_wrapper::<LuaVec3>();
|
world.register_lua_wrapper::<LuaVec3>();
|
||||||
|
world.register_lua_wrapper::<LuaTransform>();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
fn expose_api(&mut self, ctx: &mut Self::ScriptContext) -> Result<(), crate::ScriptError> {
|
||||||
|
@ -29,6 +30,7 @@ impl ScriptApiProvider for LyraMathApiProvider {
|
||||||
|
|
||||||
let globals = ctx.globals();
|
let globals = ctx.globals();
|
||||||
globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
|
globals.set("Vec3", ctx.create_proxy::<LuaVec3>()?)?;
|
||||||
|
globals.set("Transform", ctx.create_proxy::<LuaTransform>()?)?;
|
||||||
//globals.set("Vec3", LuaVec3(math::Vec3::ZERO).into_lua(&ctx)?)?;
|
//globals.set("Vec3", LuaVec3(math::Vec3::ZERO).into_lua(&ctx)?)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::Arc;
|
use std::{sync::Arc, ptr::NonNull};
|
||||||
|
|
||||||
use lyra_ecs::query::dynamic::QueryDynamicType;
|
use lyra_ecs::query::dynamic::QueryDynamicType;
|
||||||
use lyra_reflect::TypeRegistry;
|
use lyra_reflect::TypeRegistry;
|
||||||
|
@ -62,7 +62,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
|
|
||||||
let f = lua.create_function_mut(move |lua, ()| {
|
let f = lua.create_function_mut(move |lua, ()| {
|
||||||
if let Some(row) = reflected_iter.next_lua(lua) {
|
if let Some(row) = reflected_iter.next_lua(lua) {
|
||||||
let row = row.into_iter().map(|(_, ud)| ud.into_lua(lua))
|
let row = row.row.into_iter().map(|i| i.comp_ud.into_lua(lua))
|
||||||
.collect::<mlua::Result<Vec<mlua::Value>>>()?;
|
.collect::<mlua::Result<Vec<mlua::Value>>>()?;
|
||||||
Ok(mlua::MultiValue::from_vec(row))
|
Ok(mlua::MultiValue::from_vec(row))
|
||||||
} else {
|
} else {
|
||||||
|
@ -73,7 +73,7 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
Ok(f)
|
Ok(f)
|
||||||
});
|
});
|
||||||
|
|
||||||
methods.add_method("view", |lua, this, (system, queries): (mlua::Function, mlua::Variadic<mlua::AnyUserData>)| {
|
methods.add_method_mut("view", |lua, this, (system, queries): (mlua::Function, mlua::Variadic<mlua::AnyUserData>)| {
|
||||||
if queries.is_empty() {
|
if queries.is_empty() {
|
||||||
return Err(mlua::Error::BadArgument { to: Some("world:view".to_string()), pos: 2, name: Some("...".to_string()), cause:
|
return Err(mlua::Error::BadArgument { to: Some("world:view".to_string()), pos: 2, name: Some("...".to_string()), cause:
|
||||||
Arc::new(mlua::Error::external(WorldError::LuaInvalidUsage("no component types provided".to_string())))
|
Arc::new(mlua::Error::external(WorldError::LuaInvalidUsage("no component types provided".to_string())))
|
||||||
|
@ -99,29 +99,51 @@ impl mlua::UserData for ScriptWorldPtr {
|
||||||
reflected_components: None,
|
reflected_components: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let reg = this.as_ref().get_resource::<TypeRegistry>();
|
let mut current = world.current_tick();
|
||||||
|
let mut has_ticked = false;
|
||||||
|
|
||||||
while let Some(row) = reflected_iter.next_lua(lua) {
|
while let Some(row) = reflected_iter.next_lua(lua) {
|
||||||
let (reflects, values): (Vec<(_, _)>, Vec<_>) = row.into_iter().unzip();
|
|
||||||
|
|
||||||
|
let r = row.row.into_iter()
|
||||||
|
.map(|r| (r.proxy, r.comp_ud, r.comp_ptr))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
let (reflects, values, ptrs):
|
||||||
|
(Vec<&ReflectLuaProxy>, Vec<mlua::AnyUserData>, Vec<NonNull<u8>>)
|
||||||
|
= itertools::multiunzip(r);
|
||||||
let value_row: Vec<_> = values.into_iter().map(|ud| ud.into_lua(lua)).collect::<mlua::Result<Vec<mlua::Value>>>()?;
|
let value_row: Vec<_> = values.into_iter().map(|ud| ud.into_lua(lua)).collect::<mlua::Result<Vec<mlua::Value>>>()?;
|
||||||
let mult_val = mlua::MultiValue::from_vec(value_row);
|
let mult_val = mlua::MultiValue::from_vec(value_row);
|
||||||
let res: mlua::MultiValue = system.call(mult_val)?;
|
let res: mlua::MultiValue = system.call(mult_val)?;
|
||||||
|
|
||||||
// if values were returned, find the type in the type registry, and apply the new values
|
// if values were returned, find the type in the type registry, and apply the new values
|
||||||
if res.len() <= reflects.len() {
|
if res.len() <= reflects.len() {
|
||||||
|
// we only want to tick one time per system
|
||||||
|
if !has_ticked {
|
||||||
|
current = world.tick();
|
||||||
|
has_ticked = true;
|
||||||
|
}
|
||||||
|
|
||||||
for (i, comp) in res.into_iter().enumerate() {
|
for (i, comp) in res.into_iter().enumerate() {
|
||||||
let (_proxy, ptr) = reflects[i];
|
let ptr = ptrs[i];
|
||||||
|
|
||||||
match comp.as_userdata() {
|
match comp.as_userdata() {
|
||||||
Some(ud) => {
|
Some(ud) => {
|
||||||
let lua_comp = reflect_user_data(ud);
|
let lua_comp = reflect_user_data(ud);
|
||||||
let refl_comp = lua_comp.reflect_branch.as_component_unchecked();
|
let refl_comp = lua_comp.reflect_branch.as_component_unchecked();
|
||||||
let lua_typeid = refl_comp.info.type_id.as_rust();
|
let lua_typeid = refl_comp.info.type_id.as_rust();
|
||||||
|
|
||||||
|
// update the component tick
|
||||||
|
let world = unsafe { this.inner.as_mut() };
|
||||||
|
let arch = world.entity_archetype_mut(row.entity).unwrap();
|
||||||
|
let idx = arch.entities().get(&row.entity).unwrap().clone();
|
||||||
|
let c = arch.get_column_mut(refl_comp.type_id.into()).unwrap();
|
||||||
|
c.entity_ticks[idx.0 as usize] = current;
|
||||||
|
|
||||||
|
// apply the new component data
|
||||||
|
let reg = this.as_ref().get_resource::<TypeRegistry>();
|
||||||
let reg_type = reg.get_type(lua_typeid).unwrap();
|
let reg_type = reg.get_type(lua_typeid).unwrap();
|
||||||
|
|
||||||
let proxy = reg_type.get_data::<ReflectLuaProxy>().unwrap();
|
let proxy = reg_type.get_data::<ReflectLuaProxy>().unwrap();
|
||||||
(proxy.fn_apply)(lua, ptr, ud)?
|
(proxy.fn_apply)(lua, ptr, ud)?;
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
panic!("A userdata value was not returned!");
|
panic!("A userdata value was not returned!");
|
||||||
|
|
|
@ -5,7 +5,7 @@ use crate::lyra_engine;
|
||||||
use crate as lyra_scripting;
|
use crate as lyra_scripting;
|
||||||
|
|
||||||
// f32 types
|
// f32 types
|
||||||
/* wrap_math_vec_copy!(
|
wrap_math_vec_copy!(
|
||||||
math::Vec2,
|
math::Vec2,
|
||||||
derives(PartialEq),
|
derives(PartialEq),
|
||||||
fields(x, y),
|
fields(x, y),
|
||||||
|
@ -17,23 +17,27 @@ use crate as lyra_scripting;
|
||||||
Mod(LuaVec2, f32),
|
Mod(LuaVec2, f32),
|
||||||
Eq, Unm
|
Eq, Unm
|
||||||
)
|
)
|
||||||
); */
|
);
|
||||||
wrap_math_vec_copy!(
|
wrap_math_vec_copy!(
|
||||||
math::Vec3,
|
math::Vec3,
|
||||||
derives(PartialEq),
|
derives(PartialEq),
|
||||||
fields(x, y, z),
|
fields(x, y, z),
|
||||||
metamethods(
|
metamethods(
|
||||||
ToString,
|
Add(LuaVec3),
|
||||||
Eq, Unm
|
|
||||||
)
|
|
||||||
/* metamethods(
|
|
||||||
Add(LuaVec3, f32),
|
|
||||||
Sub(LuaVec3, f32),
|
Sub(LuaVec3, f32),
|
||||||
Div(LuaVec3, f32),
|
Div(LuaVec3, f32),
|
||||||
Mul(LuaVec3, f32),
|
Mul(LuaVec3, f32),
|
||||||
Mod(LuaVec3, f32),
|
Mod(LuaVec3, f32),
|
||||||
Eq, Unm
|
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!(
|
/* wrap_math_vec_copy!(
|
||||||
math::Vec3A,
|
math::Vec3A,
|
||||||
|
@ -363,3 +367,200 @@ wrap_math_vec_copy!(
|
||||||
Unm
|
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