Skip to content

Commit 5a24804

Browse files
committed
add a sphere function to geometry
1 parent a3cddd3 commit 5a24804

File tree

5 files changed

+92
-7
lines changed

5 files changed

+92
-7
lines changed

crates/processing_pyo3/examples/particles.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,19 @@ def draw():
2121
def create_geometry():
2222
global geometry
2323

24-
beginGeometry()
24+
begin_geometry()
2525

2626
for i in range(60):
2727
x = gauss(400, 200)
2828
y = gauss(350, 175)
2929
z = gauss(0, 100)
3030

3131
push_matrix()
32-
translate(x, y, z)
32+
translate_3d(x, y, z)
3333
sphere(10)
3434
pop_matrix()
3535

36-
geometry = endGeometry()
36+
geometry = end_geometry()
3737

3838
# TODO: this should happen implicitly on module load somehow
3939
run()

crates/processing_pyo3/src/graphics.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,10 @@ impl Graphics {
324324
Err(e) => Err(PyRuntimeError::new_err(format!("{e}"))),
325325
}
326326
}
327+
328+
pub fn sphere(&self, radius: f32) -> PyResult<()> {
329+
geometry_sphere(self.entity, radius).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
330+
}
327331
}
328332

329333
// TODO: a real color type. or color parser? idk. color is confusing. let's think

crates/processing_pyo3/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ fn processing(m: &Bound<'_, PyModule>) -> PyResult<()> {
4444
m.add_function(wrap_pyfunction!(draw_geometry, m)?)?;
4545
m.add_function(wrap_pyfunction!(begin_geometry, m)?)?;
4646
m.add_function(wrap_pyfunction!(end_geometry, m)?)?;
47+
m.add_function(wrap_pyfunction!(sphere, m)?)?;
4748

4849
Ok(())
4950
}
@@ -251,3 +252,9 @@ fn begin_geometry(module: &Bound<'_, PyModule>) -> PyResult<()> {
251252
fn end_geometry(module: &Bound<'_, PyModule>) -> PyResult<Geometry> {
252253
get_graphics(module)?.end_geometry()
253254
}
255+
256+
#[pyfunction]
257+
#[pyo3(pass_module, signature = (radius))]
258+
fn sphere(module: &Bound<'_, PyModule>, radius: f32) -> PyResult<()> {
259+
get_graphics(module)?.sphere(radius)
260+
}

crates/processing_render/src/geometry/mod.rs

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ pub fn destroy(
370370
}
371371

372372
pub fn begin(
373-
In(graphics_entity): In<Entity>,
373+
In(entity): In<Entity>,
374374
mut commands: Commands,
375375
mut state_query: Query<&mut RenderState>,
376376
mut meshes: ResMut<Assets<Mesh>>,
@@ -392,24 +392,90 @@ pub fn begin(
392392
let handle = meshes.add(mesh);
393393

394394
let mut state = state_query
395-
.get_mut(graphics_entity)
395+
.get_mut(entity)
396396
.map_err(|_| ProcessingError::GraphicsNotFound)?;
397397

398398
state.running_geometry = Some(Geometry::new(handle, layout_entity));
399399
Ok(())
400400
}
401401

402402
pub fn end(
403-
In(graphics_entity): In<Entity>,
403+
In(entity): In<Entity>,
404404
mut commands: Commands,
405405
mut state_query: Query<&mut RenderState>,
406406
) -> Result<Entity> {
407407
let geometry = state_query
408-
.get_mut(graphics_entity)
408+
.get_mut(entity)
409409
.map_err(|_| ProcessingError::GraphicsNotFound)?
410410
.running_geometry
411411
.take()
412412
.ok_or(ProcessingError::GeometryNotFound)?;
413413

414414
Ok(commands.spawn(geometry).id())
415415
}
416+
417+
pub fn sphere(
418+
In((entity, radius)): In<(Entity, f32)>,
419+
state_query: Query<&mut RenderState>,
420+
mut meshes: ResMut<Assets<Mesh>>,
421+
) -> Result<()> {
422+
let geometry = state_query
423+
.get(entity)
424+
.map_err(|_| ProcessingError::GraphicsNotFound)?
425+
.running_geometry
426+
.as_ref()
427+
.ok_or(ProcessingError::GeometryNotFound)?;
428+
429+
let mesh = meshes
430+
.get_mut(&geometry.handle)
431+
.ok_or(ProcessingError::GeometryNotFound)?;
432+
433+
let base_index = mesh.count_vertices() as u32;
434+
let sphere_mesh = Sphere::new(radius).mesh().build();
435+
436+
// Append positions
437+
if let Some(VertexAttributeValues::Float32x3(new_pos)) =
438+
sphere_mesh.attribute(Mesh::ATTRIBUTE_POSITION)
439+
&& let Some(VertexAttributeValues::Float32x3(positions)) =
440+
mesh.attribute_mut(Mesh::ATTRIBUTE_POSITION)
441+
{
442+
positions.extend_from_slice(new_pos);
443+
}
444+
445+
// Append normals
446+
if let Some(VertexAttributeValues::Float32x3(new_normals)) =
447+
sphere_mesh.attribute(Mesh::ATTRIBUTE_NORMAL)
448+
&& let Some(VertexAttributeValues::Float32x3(normals)) =
449+
mesh.attribute_mut(Mesh::ATTRIBUTE_NORMAL)
450+
{
451+
normals.extend_from_slice(new_normals);
452+
}
453+
454+
// Append UVs
455+
if let Some(VertexAttributeValues::Float32x2(new_uvs)) =
456+
sphere_mesh.attribute(Mesh::ATTRIBUTE_UV_0)
457+
&& let Some(VertexAttributeValues::Float32x2(uvs)) =
458+
mesh.attribute_mut(Mesh::ATTRIBUTE_UV_0)
459+
{
460+
uvs.extend_from_slice(new_uvs);
461+
}
462+
463+
// Append indices with offset
464+
let new_indices: Vec<u32> = match sphere_mesh.indices() {
465+
Some(Indices::U16(vec)) => vec.iter().map(|&i| i as u32 + base_index).collect(),
466+
Some(Indices::U32(vec)) => vec.iter().map(|&i| i + base_index).collect(),
467+
None => Vec::new(),
468+
};
469+
470+
match mesh.indices_mut() {
471+
Some(Indices::U32(indices)) => indices.extend(new_indices),
472+
Some(Indices::U16(indices)) => {
473+
indices.extend(new_indices.iter().map(|&i| i as u16));
474+
}
475+
None => {
476+
mesh.insert_indices(Indices::U32(new_indices));
477+
}
478+
}
479+
480+
Ok(())
481+
}

crates/processing_render/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,3 +1087,11 @@ pub fn geometry_end(graphics_entity: Entity) -> error::Result<Entity> {
10871087
.unwrap()
10881088
})
10891089
}
1090+
1091+
pub fn geometry_sphere(graphics_entity: Entity, radius: f32) -> error::Result<()> {
1092+
app_mut(|app| {
1093+
app.world_mut()
1094+
.run_system_cached_with(geometry::sphere, (graphics_entity, radius))
1095+
.unwrap()
1096+
})
1097+
}

0 commit comments

Comments
 (0)