Skip to content

Commit f74f8eb

Browse files
committed
More cleanup.
1 parent 2b9e26b commit f74f8eb

23 files changed

Lines changed: 208 additions & 486 deletions

crates/processing_pyo3/examples/particles_basic.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ def setup():
1313

1414
directional_light((0.95, 0.9, 0.85), 600.0)
1515

16-
# Source mesh whose vertices become particle positions; uvs come along for
17-
# free and we use them to color each particle.
1816
source = Geometry.sphere(5.0, 32, 24)
1917
p = Particles(
2018
geometry=source,

crates/processing_pyo3/examples/particles_emit.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ def setup():
2121
attributes=[Attribute.position(), Attribute.color()],
2222
)
2323

24-
# Push unemitted slots far off-screen so they don't all render at the
25-
# origin while the ring buffer is still filling.
24+
# Park unemitted slots far off-screen until the ring buffer fills.
2625
pos_buf = p.buffer(Attribute.position())
2726
pos_buf.write([1.0e6] * (capacity * 3))
2827

@@ -39,9 +38,7 @@ def draw():
3938
use_material(mat)
4039
particles(p, sphere)
4140

42-
# Emit 4 particles per frame in an outward-spiraling ring; once the ring
43-
# buffer fills (~500 frames at 4/frame for capacity 2000), oldest get
44-
# overwritten and the swirl continues without bound.
41+
# Emit 4 particles per frame in an outward-spiraling ring.
4542
burst = 4
4643
positions = []
4744
colors = []

crates/processing_pyo3/examples/particles_emit_gpu.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ def setup():
148148
],
149149
)
150150

151-
# Mark all unemitted slots dead so they don't render at origin.
151+
# Park unemitted slots until the spawn kernel fills them.
152152
dead_buf = p.buffer(Attribute.dead())
153153
dead_buf.write([1.0] * CAPACITY)
154154

@@ -167,7 +167,6 @@ def draw():
167167
use_material(mat)
168168
particles(p, particle)
169169

170-
# Animate spawn point in a small circle so the fountain meanders.
171170
t = elapsed_time
172171
sx = math.cos(t) * 0.4
173172
sz = math.sin(t) * 0.4

crates/processing_pyo3/examples/particles_from_mesh.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ def setup():
1313

1414
directional_light((0.95, 0.9, 0.85), 200.0)
1515

16-
# Source mesh whose vertices become the particle positions. UVs come along
17-
# for free and we'll use them to paint each particle a unique color.
1816
source = Geometry.sphere(5.0, 32, 24)
1917
p = Particles(
2018
geometry=source,

crates/processing_pyo3/examples/particles_lifecycle.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def setup():
7474
attributes=[position_attr, color_attr, scale_attr, dead_attr, age_attr],
7575
)
7676

77-
# Mark all slots dead initially so unemitted ring slots don't render.
77+
# Park unemitted slots until the spawn loop fills them.
7878
dead_buf = p.buffer(dead_attr)
7979
dead_buf.write([1.0] * capacity)
8080

@@ -92,12 +92,10 @@ def draw():
9292
use_material(mat)
9393
particles(p, sphere)
9494

95-
# Spawn `BURST` new particles per frame in a small fountain.
9695
positions = []
9796
colors = []
9897
for k in range(BURST):
9998
i = frame * BURST + k
100-
# Cheap pseudo-random offset.
10199
u = (((i * 2654435761) >> 8) & 0xFFFF) / 65535.0
102100
v = (((i * 40503) >> 8) & 0xFFFF) / 65535.0
103101
theta = u * math.tau

crates/processing_pyo3/examples/particles_noise.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ def setup():
1414

1515
directional_light((0.95, 0.9, 0.85), 200.0)
1616

17-
# Seed positions from a sphere mesh; noise will jitter them around their
18-
# initial sphere shape over time.
1917
source = Geometry.sphere(5.0, 32, 24)
2018
p = Particles(
2119
geometry=source,

crates/processing_pyo3/src/compute.rs

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,14 @@ pub struct Buffer {
1616
pub(crate) entity: Entity,
1717
element_type: Option<ShaderValue>,
1818
size: u64,
19-
/// `false` for buffers we created and own — `Drop` destroys the entity.
20-
/// `true` for buffers we wrap (e.g. a Field's attribute buffer) where the
21-
/// underlying entity belongs to someone else; destroying it would yank the
22-
/// buffer out from under the owner.
19+
/// `true` for borrowed wrappers (e.g. `Particles.buffer()`) where the
20+
/// underlying entity belongs elsewhere; `Drop` skips destroy in that case.
2321
borrowed: bool,
2422
}
2523

2624
impl Buffer {
27-
/// Wrap an existing buffer entity (e.g., one owned by a Field).
28-
/// `size` is queried from the buffer; `element_type` is supplied so typed
29-
/// reads / `__getitem__` work correctly. The wrapper does NOT destroy the
30-
/// entity on drop — ownership stays with whoever produced it.
25+
/// Wrap an existing buffer entity without taking ownership. `Drop` will
26+
/// not destroy it.
3127
pub(crate) fn from_entity(entity: Entity, element_type: Option<ShaderValue>) -> Self {
3228
let size = buffer_size(entity).unwrap_or(0);
3329
Self {
@@ -144,10 +140,8 @@ impl Buffer {
144140
}
145141

146142
pub fn write(&mut self, values: &Bound<'_, PyAny>) -> PyResult<()> {
147-
// Fast path: raw bytes go through unchanged. This is essential for
148-
// large buffers where iterating Python objects would be unworkably
149-
// slow (e.g. 1M-element fields). Element type is preserved if already
150-
// known; otherwise the buffer stays untyped (read() returns bytes).
143+
// Bytes path skips per-element conversion — the only viable route for
144+
// multi-million-element uploads.
151145
if let Ok(b) = values.cast::<PyBytes>() {
152146
return buffer_write(self.entity, b.as_bytes().to_vec())
153147
.map_err(|e| PyRuntimeError::new_err(format!("{e}")));

crates/processing_pyo3/src/graphics.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -500,8 +500,6 @@ impl Graphics {
500500

501501
#[pyo3(signature = (*args))]
502502
pub fn fill(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
503-
// `fill(buffer)` — per-particle albedo for `Particles` draws. Bypasses the
504-
// color-mode parser and feeds the buffer entity straight through.
505503
if args.len() == 1
506504
&& let Ok(buf) = args.get_item(0)?.extract::<PyRef<crate::compute::Buffer>>()
507505
{

crates/processing_pyo3/src/lib.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,10 +1146,8 @@ mod mewnala {
11461146
Ok(())
11471147
});
11481148

1149-
// Tear the App down gracefully while the thread-local is still alive,
1150-
// matching what `processing::exit()` does in Rust sketches. Without
1151-
// this the App falls to its eager thread-local destructor at process
1152-
// exit and a Bevy resource panics inside its own Drop, aborting.
1149+
// Tear down the App while the thread-local is still alive — letting
1150+
// it run via the eager TLS destructor aborts inside a Bevy resource Drop.
11531151
let _ = ::processing::exit(0);
11541152

11551153
result

crates/processing_pyo3/src/material.rs

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ pub(crate) fn py_to_shader_value(value: &Bound<'_, PyAny>) -> PyResult<shader_va
2121
return Ok(shader_value::ShaderValue::Int(v));
2222
}
2323

24-
// Accept PyVec types
2524
if let Ok(v) = value.extract::<PyRef<PyVec4>>() {
2625
return Ok(shader_value::ShaderValue::Float4(v.0.to_array()));
2726
}
@@ -36,7 +35,6 @@ pub(crate) fn py_to_shader_value(value: &Bound<'_, PyAny>) -> PyResult<shader_va
3635
return Ok(shader_value::ShaderValue::Buffer(buf.entity));
3736
}
3837

39-
// Fall back to raw arrays
4038
if let Ok(v) = value.extract::<[f32; 4]>() {
4139
return Ok(shader_value::ShaderValue::Float4(v));
4240
}
@@ -53,9 +51,8 @@ pub(crate) fn py_to_shader_value(value: &Bound<'_, PyAny>) -> PyResult<shader_va
5351
)))
5452
}
5553

56-
/// Apply an `albedo` value to a material, dispatching by Python type. The
57-
/// material's backing asset is swapped between plain-PBR and field-buffer
58-
/// variants as needed; all other `StandardMaterial` state survives the swap.
54+
/// Dispatch `albedo=` by Python type to the matching Rust setter. May swap
55+
/// the backing asset; all other StandardMaterial state survives.
5956
fn apply_albedo(entity: Entity, value: &Bound<'_, PyAny>) -> PyResult<()> {
6057
if let Ok(buf) = value.extract::<PyRef<Buffer>>() {
6158
return material_set_albedo_buffer(entity, buf.entity)
@@ -95,9 +92,8 @@ fn apply_kwargs(entity: Entity, kwargs: &Bound<'_, PyDict>) -> PyResult<()> {
9592

9693
#[pymethods]
9794
impl Material {
98-
/// Construct a material. With no args, returns a default PBR. With a
99-
/// `shader` arg, returns a custom material. Any kwargs (`albedo=...`,
100-
/// `roughness=...`, etc.) are applied after construction.
95+
/// No args: default PBR. With `shader`: custom material. Kwargs are
96+
/// applied via `set` after construction.
10197
#[new]
10298
#[pyo3(signature = (shader=None, **kwargs))]
10399
pub fn new(shader: Option<&Shader>, kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Self> {
@@ -114,8 +110,8 @@ impl Material {
114110
Ok(Self { entity })
115111
}
116112

117-
/// PBR-lit material. `albedo` accepts a `Color` (solid) or a `Buffer`
118-
/// (per-particle, indexed by per-instance tag — used with `Field`s).
113+
/// PBR-lit material. `albedo` accepts a `Color` or a `Buffer` (the latter
114+
/// being per-particle, used with `Particles`).
119115
#[staticmethod]
120116
#[pyo3(signature = (**kwargs))]
121117
pub fn pbr(kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Self> {
@@ -126,8 +122,7 @@ impl Material {
126122
Ok(Self { entity })
127123
}
128124

129-
/// Unlit material — same shape as `pbr` but skips lighting calculations
130-
/// (the per-particle / solid color is the final output).
125+
/// Like `pbr` but skips lighting; albedo is the final output color.
131126
#[staticmethod]
132127
#[pyo3(signature = (**kwargs))]
133128
pub fn unlit(kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<Self> {
@@ -140,10 +135,8 @@ impl Material {
140135
Ok(Self { entity })
141136
}
142137

143-
/// Patch one or more material properties. `albedo` is special-cased and
144-
/// may swap the backing asset type between solid-color and buffer-color
145-
/// variants — all other `StandardMaterial` state (roughness, metallic,
146-
/// emissive, alpha_mode, unlit, etc.) is preserved across the swap.
138+
/// Patch material properties. `albedo` may swap the backing asset between
139+
/// color and buffer variants; other StandardMaterial fields are preserved.
147140
#[pyo3(signature = (**kwargs))]
148141
pub fn set(&self, kwargs: Option<&Bound<'_, PyDict>>) -> PyResult<()> {
149142
let Some(kwargs) = kwargs else {

0 commit comments

Comments
 (0)