Skip to content

Commit 4dedf93

Browse files
authored
Add math module. (#91)
1 parent b957736 commit 4dedf93

File tree

23 files changed

+930
-234
lines changed

23 files changed

+930
-234
lines changed

crates/processing_ffi/src/lib.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use bevy::{
2+
math::{Vec2, Vec3, Vec4},
23
prelude::Entity,
34
render::render_resource::{Extent3d, TextureFormat},
45
};
@@ -376,7 +377,9 @@ pub extern "C" fn processing_reset_matrix(graphics_id: u64) {
376377
pub extern "C" fn processing_translate(graphics_id: u64, x: f32, y: f32) {
377378
error::clear_error();
378379
let graphics_entity = Entity::from_bits(graphics_id);
379-
error::check(|| graphics_record_command(graphics_entity, DrawCommand::Translate { x, y }));
380+
error::check(|| {
381+
graphics_record_command(graphics_entity, DrawCommand::Translate(Vec2::new(x, y)))
382+
});
380383
}
381384

382385
/// Rotate the coordinate system.
@@ -400,7 +403,7 @@ pub extern "C" fn processing_rotate(graphics_id: u64, angle: f32) {
400403
pub extern "C" fn processing_scale(graphics_id: u64, x: f32, y: f32) {
401404
error::clear_error();
402405
let graphics_entity = Entity::from_bits(graphics_id);
403-
error::check(|| graphics_record_command(graphics_entity, DrawCommand::Scale { x, y }));
406+
error::check(|| graphics_record_command(graphics_entity, DrawCommand::Scale(Vec2::new(x, y))));
404407
}
405408

406409
/// Shear along the X axis.
@@ -625,21 +628,21 @@ pub extern "C" fn processing_ortho(
625628
pub extern "C" fn processing_transform_set_position(entity_id: u64, x: f32, y: f32, z: f32) {
626629
error::clear_error();
627630
let entity = Entity::from_bits(entity_id);
628-
error::check(|| transform_set_position(entity, x, y, z));
631+
error::check(|| transform_set_position(entity, Vec3::new(x, y, z)));
629632
}
630633

631634
#[unsafe(no_mangle)]
632635
pub extern "C" fn processing_transform_translate(entity_id: u64, x: f32, y: f32, z: f32) {
633636
error::clear_error();
634637
let entity = Entity::from_bits(entity_id);
635-
error::check(|| transform_translate(entity, x, y, z));
638+
error::check(|| transform_translate(entity, Vec3::new(x, y, z)));
636639
}
637640

638641
#[unsafe(no_mangle)]
639642
pub extern "C" fn processing_transform_set_rotation(entity_id: u64, x: f32, y: f32, z: f32) {
640643
error::clear_error();
641644
let entity = Entity::from_bits(entity_id);
642-
error::check(|| transform_set_rotation(entity, x, y, z));
645+
error::check(|| transform_set_rotation(entity, Vec3::new(x, y, z)));
643646
}
644647

645648
#[unsafe(no_mangle)]
@@ -673,21 +676,21 @@ pub extern "C" fn processing_transform_rotate_axis(
673676
) {
674677
error::clear_error();
675678
let entity = Entity::from_bits(entity_id);
676-
error::check(|| transform_rotate_axis(entity, angle, axis_x, axis_y, axis_z));
679+
error::check(|| transform_rotate_axis(entity, angle, Vec3::new(axis_x, axis_y, axis_z)));
677680
}
678681

679682
#[unsafe(no_mangle)]
680683
pub extern "C" fn processing_transform_set_scale(entity_id: u64, x: f32, y: f32, z: f32) {
681684
error::clear_error();
682685
let entity = Entity::from_bits(entity_id);
683-
error::check(|| transform_set_scale(entity, x, y, z));
686+
error::check(|| transform_set_scale(entity, Vec3::new(x, y, z)));
684687
}
685688

686689
#[unsafe(no_mangle)]
687690
pub extern "C" fn processing_transform_scale(entity_id: u64, x: f32, y: f32, z: f32) {
688691
error::clear_error();
689692
let entity = Entity::from_bits(entity_id);
690-
error::check(|| transform_scale(entity, x, y, z));
693+
error::check(|| transform_scale(entity, Vec3::new(x, y, z)));
691694
}
692695

693696
#[unsafe(no_mangle)]
@@ -699,7 +702,7 @@ pub extern "C" fn processing_transform_look_at(
699702
) {
700703
error::clear_error();
701704
let entity = Entity::from_bits(entity_id);
702-
error::check(|| transform_look_at(entity, target_x, target_y, target_z));
705+
error::check(|| transform_look_at(entity, Vec3::new(target_x, target_y, target_z)));
703706
}
704707

705708
#[unsafe(no_mangle)]
@@ -808,14 +811,14 @@ pub extern "C" fn processing_geometry_create(topology: u8) -> u64 {
808811
pub extern "C" fn processing_geometry_normal(geo_id: u64, nx: f32, ny: f32, nz: f32) {
809812
error::clear_error();
810813
let entity = Entity::from_bits(geo_id);
811-
error::check(|| geometry_normal(entity, nx, ny, nz));
814+
error::check(|| geometry_normal(entity, Vec3::new(nx, ny, nz)));
812815
}
813816

814817
#[unsafe(no_mangle)]
815818
pub extern "C" fn processing_geometry_color(geo_id: u64, r: f32, g: f32, b: f32, a: f32) {
816819
error::clear_error();
817820
let entity = Entity::from_bits(geo_id);
818-
error::check(|| geometry_color(entity, r, g, b, a));
821+
error::check(|| geometry_color(entity, Vec4::new(r, g, b, a)));
819822
}
820823

821824
#[unsafe(no_mangle)]
@@ -932,7 +935,7 @@ pub extern "C" fn processing_geometry_attribute_float4(
932935
pub extern "C" fn processing_geometry_vertex(geo_id: u64, x: f32, y: f32, z: f32) {
933936
error::clear_error();
934937
let entity = Entity::from_bits(geo_id);
935-
error::check(|| geometry_vertex(entity, x, y, z));
938+
error::check(|| geometry_vertex(entity, Vec3::new(x, y, z)));
936939
}
937940

938941
#[unsafe(no_mangle)]
@@ -1075,7 +1078,7 @@ pub unsafe extern "C" fn processing_geometry_get_indices(
10751078
pub extern "C" fn processing_geometry_set_vertex(geo_id: u64, index: u32, x: f32, y: f32, z: f32) {
10761079
error::clear_error();
10771080
let entity = Entity::from_bits(geo_id);
1078-
error::check(|| geometry_set_vertex(entity, index, x, y, z));
1081+
error::check(|| geometry_set_vertex(entity, index, Vec3::new(x, y, z)));
10791082
}
10801083

10811084
#[unsafe(no_mangle)]
@@ -1088,7 +1091,7 @@ pub extern "C" fn processing_geometry_set_normal(
10881091
) {
10891092
error::clear_error();
10901093
let entity = Entity::from_bits(geo_id);
1091-
error::check(|| geometry_set_normal(entity, index, nx, ny, nz));
1094+
error::check(|| geometry_set_normal(entity, index, Vec3::new(nx, ny, nz)));
10921095
}
10931096

10941097
#[unsafe(no_mangle)]
@@ -1102,14 +1105,14 @@ pub extern "C" fn processing_geometry_set_color(
11021105
) {
11031106
error::clear_error();
11041107
let entity = Entity::from_bits(geo_id);
1105-
error::check(|| geometry_set_color(entity, index, r, g, b, a));
1108+
error::check(|| geometry_set_color(entity, index, Vec4::new(r, g, b, a)));
11061109
}
11071110

11081111
#[unsafe(no_mangle)]
11091112
pub extern "C" fn processing_geometry_set_uv(geo_id: u64, index: u32, u: f32, v: f32) {
11101113
error::clear_error();
11111114
let entity = Entity::from_bits(geo_id);
1112-
error::check(|| geometry_set_uv(entity, index, u, v));
1115+
error::check(|| geometry_set_uv(entity, index, Vec2::new(u, v)));
11131116
}
11141117

11151118
#[unsafe(no_mangle)]

crates/processing_pyo3/src/graphics.rs

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@ use bevy::{
55
render::render_resource::TextureFormat,
66
};
77
use processing::prelude::*;
8-
use pyo3::{exceptions::PyRuntimeError, prelude::*, types::PyDict};
8+
use pyo3::{
9+
exceptions::PyRuntimeError,
10+
prelude::*,
11+
types::{PyDict, PyTuple},
12+
};
913

1014
use crate::glfw::GlfwContext;
15+
use crate::math::{extract_vec2, extract_vec3, extract_vec4};
1116

1217
#[pyclass(unsendable)]
1318
pub struct Surface {
@@ -39,13 +44,16 @@ pub struct Light {
3944

4045
#[pymethods]
4146
impl Light {
42-
pub fn position(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
43-
transform_set_position(self.entity, x, y, z)
44-
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
47+
#[pyo3(signature = (*args))]
48+
pub fn position(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
49+
let v = extract_vec3(args)?;
50+
transform_set_position(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
4551
}
4652

47-
pub fn look_at(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
48-
transform_look_at(self.entity, x, y, z).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
53+
#[pyo3(signature = (*args))]
54+
pub fn look_at(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
55+
let v = extract_vec3(args)?;
56+
transform_look_at(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
4957
}
5058
}
5159

@@ -122,26 +130,32 @@ impl Geometry {
122130
Ok(Self { entity: geometry })
123131
}
124132

125-
pub fn color(&self, r: f32, g: f32, b: f32, a: f32) -> PyResult<()> {
126-
geometry_color(self.entity, r, g, b, a).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
133+
#[pyo3(signature = (*args))]
134+
pub fn color(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
135+
let v = extract_vec4(args)?;
136+
geometry_color(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
127137
}
128138

129-
pub fn normal(&self, nx: f32, ny: f32, nz: f32) -> PyResult<()> {
130-
geometry_normal(self.entity, nx, ny, nz)
131-
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
139+
#[pyo3(signature = (*args))]
140+
pub fn normal(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
141+
let v = extract_vec3(args)?;
142+
geometry_normal(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
132143
}
133144

134-
pub fn vertex(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
135-
geometry_vertex(self.entity, x, y, z).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
145+
#[pyo3(signature = (*args))]
146+
pub fn vertex(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
147+
let v = extract_vec3(args)?;
148+
geometry_vertex(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
136149
}
137150

138151
pub fn index(&self, i: u32) -> PyResult<()> {
139152
geometry_index(self.entity, i).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
140153
}
141154

142-
pub fn set_vertex(&self, i: u32, x: f32, y: f32, z: f32) -> PyResult<()> {
143-
geometry_set_vertex(self.entity, i, x, y, z)
144-
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
155+
#[pyo3(signature = (i, *args))]
156+
pub fn set_vertex(&self, i: u32, args: &Bound<'_, PyTuple>) -> PyResult<()> {
157+
let v = extract_vec3(args)?;
158+
geometry_set_vertex(self.entity, i, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
145159
}
146160
}
147161

@@ -388,8 +402,10 @@ impl Graphics {
388402
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
389403
}
390404

391-
pub fn translate(&self, x: f32, y: f32) -> PyResult<()> {
392-
graphics_record_command(self.entity, DrawCommand::Translate { x, y })
405+
#[pyo3(signature = (*args))]
406+
pub fn translate(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
407+
let v = extract_vec2(args)?;
408+
graphics_record_command(self.entity, DrawCommand::Translate(v))
393409
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
394410
}
395411

@@ -454,8 +470,10 @@ impl Graphics {
454470
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
455471
}
456472

457-
pub fn scale(&self, x: f32, y: f32) -> PyResult<()> {
458-
graphics_record_command(self.entity, DrawCommand::Scale { x, y })
473+
#[pyo3(signature = (*args))]
474+
pub fn scale(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
475+
let v = extract_vec2(args)?;
476+
graphics_record_command(self.entity, DrawCommand::Scale(v))
459477
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
460478
}
461479

@@ -494,14 +512,16 @@ impl Graphics {
494512
graphics_mode_2d(self.entity).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
495513
}
496514

497-
pub fn camera_position(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
498-
transform_set_position(self.entity, x, y, z)
499-
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
515+
#[pyo3(signature = (*args))]
516+
pub fn camera_position(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
517+
let v = extract_vec3(args)?;
518+
transform_set_position(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
500519
}
501520

502-
pub fn camera_look_at(&self, target_x: f32, target_y: f32, target_z: f32) -> PyResult<()> {
503-
transform_look_at(self.entity, target_x, target_y, target_z)
504-
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
521+
#[pyo3(signature = (*args))]
522+
pub fn camera_look_at(&self, args: &Bound<'_, PyTuple>) -> PyResult<()> {
523+
let v = extract_vec3(args)?;
524+
transform_look_at(self.entity, v).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
505525
}
506526

507527
pub fn perspective(&self, fov: f32, aspect: f32, near: f32, far: f32) -> PyResult<()> {

crates/processing_pyo3/src/lib.rs

Lines changed: 47 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ mod glfw;
1212
mod gltf;
1313
mod graphics;
1414
pub(crate) mod material;
15+
pub(crate) mod math;
1516
mod midi;
1617
pub(crate) mod shader;
1718
#[cfg(feature = "webcam")]
@@ -139,6 +140,46 @@ mod mewnala {
139140
#[pymodule_export]
140141
const BEVEL: u8 = 2;
141142

143+
#[pymodule]
144+
mod math {
145+
use super::*;
146+
147+
#[pymodule_export]
148+
use crate::math::PyQuat;
149+
#[pymodule_export]
150+
use crate::math::PyVec2;
151+
#[pymodule_export]
152+
use crate::math::PyVec3;
153+
#[pymodule_export]
154+
use crate::math::PyVec4;
155+
#[pymodule_export]
156+
use crate::math::PyVecIter;
157+
158+
#[pyfunction]
159+
#[pyo3(signature = (*args))]
160+
fn vec2(args: &Bound<'_, PyTuple>) -> PyResult<crate::math::PyVec2> {
161+
crate::math::PyVec2::py_new(args)
162+
}
163+
164+
#[pyfunction]
165+
#[pyo3(signature = (*args))]
166+
fn vec3(args: &Bound<'_, PyTuple>) -> PyResult<crate::math::PyVec3> {
167+
crate::math::PyVec3::py_new(args)
168+
}
169+
170+
#[pyfunction]
171+
#[pyo3(signature = (*args))]
172+
fn vec4(args: &Bound<'_, PyTuple>) -> PyResult<crate::math::PyVec4> {
173+
crate::math::PyVec4::py_new(args)
174+
}
175+
176+
#[pyfunction]
177+
#[pyo3(signature = (*args))]
178+
fn quat(args: &Bound<'_, PyTuple>) -> PyResult<crate::math::PyQuat> {
179+
crate::math::PyQuat::py_new(args)
180+
}
181+
}
182+
142183
#[cfg(feature = "webcam")]
143184
#[pymodule_export]
144185
use super::webcam::Webcam;
@@ -352,20 +393,15 @@ mod mewnala {
352393
}
353394

354395
#[pyfunction]
355-
#[pyo3(pass_module)]
356-
fn camera_position(module: &Bound<'_, PyModule>, x: f32, y: f32, z: f32) -> PyResult<()> {
357-
graphics!(module).camera_position(x, y, z)
396+
#[pyo3(pass_module, signature = (*args))]
397+
fn camera_position(module: &Bound<'_, PyModule>, args: &Bound<'_, PyTuple>) -> PyResult<()> {
398+
graphics!(module).camera_position(args)
358399
}
359400

360401
#[pyfunction]
361-
#[pyo3(pass_module)]
362-
fn camera_look_at(
363-
module: &Bound<'_, PyModule>,
364-
target_x: f32,
365-
target_y: f32,
366-
target_z: f32,
367-
) -> PyResult<()> {
368-
graphics!(module).camera_look_at(target_x, target_y, target_z)
402+
#[pyo3(pass_module, signature = (*args))]
403+
fn camera_look_at(module: &Bound<'_, PyModule>, args: &Bound<'_, PyTuple>) -> PyResult<()> {
404+
graphics!(module).camera_look_at(args)
369405
}
370406

371407
#[pyfunction]

crates/processing_pyo3/src/material.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use processing::prelude::*;
33
use pyo3::types::PyDict;
44
use pyo3::{exceptions::PyRuntimeError, prelude::*};
55

6+
use crate::math::{PyVec2, PyVec3, PyVec4};
67
use crate::shader::Shader;
78

89
#[pyclass(unsendable)]
@@ -18,6 +19,18 @@ fn py_to_material_value(value: &Bound<'_, PyAny>) -> PyResult<material::Material
1819
return Ok(material::MaterialValue::Int(v));
1920
}
2021

22+
// Accept PyVec types
23+
if let Ok(v) = value.extract::<PyRef<PyVec4>>() {
24+
return Ok(material::MaterialValue::Float4(v.0.to_array()));
25+
}
26+
if let Ok(v) = value.extract::<PyRef<PyVec3>>() {
27+
return Ok(material::MaterialValue::Float3(v.0.to_array()));
28+
}
29+
if let Ok(v) = value.extract::<PyRef<PyVec2>>() {
30+
return Ok(material::MaterialValue::Float2(v.0.to_array()));
31+
}
32+
33+
// Fall back to raw arrays
2134
if let Ok(v) = value.extract::<[f32; 4]>() {
2235
return Ok(material::MaterialValue::Float4(v));
2336
}

0 commit comments

Comments
 (0)