1use crate::commands::{CommandQueue, ScriptCommand};
7use gizmo_core::World;
8use gizmo_math::{Quat, Vec3};
9use mlua::prelude::*;
10use std::sync::Arc;
11
12pub fn register_entity_api(lua: &Lua, command_queue: Arc<CommandQueue>) -> Result<(), LuaError> {
14 let entity_table = lua.create_table()?;
15
16 {
18 let cq = command_queue.clone();
19 entity_table.set(
20 "set_position",
21 lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
22 cq.push(ScriptCommand::SetPosition(id, Vec3::new(x, y, z)));
23 Ok(())
24 })?,
25 )?;
26 }
27
28 {
30 let cq = command_queue.clone();
31 entity_table.set(
32 "set_rotation",
33 lua.create_function(move |_, (id, x, y, z, w): (u32, f32, f32, f32, f32)| {
34 cq.push(ScriptCommand::SetRotation(id, Quat::from_xyzw(x, y, z, w)));
35 Ok(())
36 })?,
37 )?;
38 }
39
40 {
42 let cq = command_queue.clone();
43 entity_table.set(
44 "set_scale",
45 lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
46 cq.push(ScriptCommand::SetScale(id, Vec3::new(x, y, z)));
47 Ok(())
48 })?,
49 )?;
50 }
51
52 {
54 let cq = command_queue.clone();
55 entity_table.set(
56 "set_velocity",
57 lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
58 cq.push(ScriptCommand::SetVelocity(id, Vec3::new(x, y, z)));
59 Ok(())
60 })?,
61 )?;
62 }
63
64 {
65 let cq = command_queue.clone();
66 entity_table.set(
67 "set_angular_velocity",
68 lua.create_function(move |_, (id, x, y, z): (u32, f32, f32, f32)| {
69 cq.push(ScriptCommand::SetAngularVelocity(id, Vec3::new(x, y, z)));
70 Ok(())
71 })?,
72 )?;
73 }
74
75 {
77 let cq = command_queue.clone();
78 entity_table.set(
79 "spawn",
80 lua.create_function(move |_, (name, x, y, z): (String, f32, f32, f32)| {
81 cq.push(ScriptCommand::SpawnEntity {
82 name,
83 position: Vec3::new(x, y, z),
84 });
85 Ok(())
86 })?,
87 )?;
88 }
89
90 {
92 let cq = command_queue.clone();
93 entity_table.set(
94 "spawn_prefab",
95 lua.create_function(
96 move |_, (name, prefab_type, x, y, z): (String, String, f32, f32, f32)| {
97 cq.push(ScriptCommand::SpawnPrefab {
98 name,
99 prefab_type,
100 position: Vec3::new(x, y, z),
101 });
102 Ok(())
103 },
104 )?,
105 )?;
106 }
107
108 {
110 let cq = command_queue.clone();
111 entity_table.set(
112 "destroy",
113 lua.create_function(move |_, id: u32| {
114 cq.push(ScriptCommand::DestroyEntity(id));
115 Ok(())
116 })?,
117 )?;
118 }
119
120 {
122 let cq = command_queue.clone();
123 entity_table.set(
124 "set_name",
125 lua.create_function(move |_, (id, name): (u32, String)| {
126 cq.push(ScriptCommand::SetEntityName(id, name));
127 Ok(())
128 })?,
129 )?;
130 }
131
132 lua.globals().set("entity", entity_table)?;
133 Ok(())
134}
135
136pub fn update_entity_read_api(lua: &Lua, world: &World) -> Result<(), LuaError> {
138 let entity_table: LuaTable = lua.globals().get("entity")?;
139
140 let positions = lua.create_table()?;
143 let velocities = lua.create_table()?;
144 let rotations = lua.create_table()?;
145 let scales = lua.create_table()?;
146 let names = lua.create_table()?;
147
148 let transforms = world.borrow::<gizmo_physics_core::Transform>();
149 for (eid, _) in transforms.iter() {
150 if let Some(t) = transforms.get(eid) {
151 let pos = lua.create_table()?;
152 pos.set("x", t.position.x)?;
153 pos.set("y", t.position.y)?;
154 pos.set("z", t.position.z)?;
155 positions.set(eid, pos)?;
156
157 let rot = lua.create_table()?;
158 rot.set("x", t.rotation.x)?;
159 rot.set("y", t.rotation.y)?;
160 rot.set("z", t.rotation.z)?;
161 rot.set("w", t.rotation.w)?;
162 rotations.set(eid, rot)?;
163
164 let scl = lua.create_table()?;
165 scl.set("x", t.scale.x)?;
166 scl.set("y", t.scale.y)?;
167 scl.set("z", t.scale.z)?;
168 scales.set(eid, scl)?;
169 }
170 }
171
172 let vels = world.borrow::<gizmo_physics_rigid::components::Velocity>();
173 for (eid, _) in vels.iter() {
174 if let Some(v) = vels.get(eid) {
175 let vel = lua.create_table()?;
176 vel.set("x", v.linear.x)?;
177 vel.set("y", v.linear.y)?;
178 vel.set("z", v.linear.z)?;
179 velocities.set(eid, vel)?;
180 }
181 }
182
183 let entity_names = world.borrow::<gizmo_core::EntityName>();
184 for (eid, _) in entity_names.iter() {
185 if let Some(n) = entity_names.get(eid) {
186 names.set(eid, n.0.clone())?;
187 }
188 }
189
190 entity_table.set("_positions", positions)?;
192 entity_table.set("_velocities", velocities)?;
193 entity_table.set("_rotations", rotations)?;
194 entity_table.set("_scales", scales)?;
195 entity_table.set("_names", names)?;
196
197 lua.load(
199 r#"
200 function entity.get_position(id)
201 return entity._positions[id] or {x=0, y=0, z=0}
202 end
203 function entity.get_velocity(id)
204 return entity._velocities[id] or {x=0, y=0, z=0}
205 end
206 function entity.get_rotation(id)
207 return entity._rotations[id] or {x=0, y=0, z=0, w=1}
208 end
209 function entity.get_scale(id)
210 return entity._scales[id] or {x=1, y=1, z=1}
211 end
212 function entity.get_name(id)
213 return entity._names[id] or ""
214 end
215 "#,
216 )
217 .exec()?;
218
219 Ok(())
220}