Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions crates/processing_pyo3/examples/lights.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from processing import *

angle = 0.0

def setup():
size(800, 600)
mode_3d()

# Directional Light
dir_light = create_directional_light(0.5, 0.24, 1.0, 1500.0)

# Point Lights
point_light_a = create_point_light(1.0, 0.5, 0.25, 1000000.0, 200.0, 0.5)
point_light_a.position(-25.0, 5.0, 51.0)
point_light_a.look_at(0.0, 0.0, 0.0)

point_light_b = create_point_light(0.0, 0.5, 0.75, 2000000.0, 200.0, 0.25)
point_light_b.position(0.0, 5.0, 50.5)
point_light_b.look_at(0.0, 0.0, 0.0)

# Spot Light
spot_light = create_spot_light(0.25, 0.8, 0.19, 15.0 * 1000000.0, 200.0, 0.84, 0.0, 0.7854)
spot_light.position(40.0, 0.0, 70.0)
spot_light.look_at(0.0, 0.0, 0.0)

def draw():
global angle
camera_position(100.0, 100.0, 300.0)
camera_look_at(0.0, 0.0, 0.0)
background(220)

push_matrix()
rotate(angle)
draw_box(100.0, 100.0, 100.0)
pop_matrix()

angle += 0.02


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

75 changes: 75 additions & 0 deletions crates/processing_pyo3/src/graphics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,31 @@ impl Drop for Surface {
}
}

#[pyclass]
#[derive(Debug)]
pub struct Light {
entity: Entity,
}

#[pymethods]
impl Light {
pub fn position(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
transform_set_position(self.entity, x, y, z)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn look_at(&self, x: f32, y: f32, z: f32) -> PyResult<()> {
transform_look_at(self.entity, x, y, z).map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}
}

// TODO: implement `light_destroy`
// impl Drop for Light {
// fn drop(&mut self) {
// let _ = light_destroy(self.entity);
// }
// }

#[pyclass]
#[derive(Debug)]
pub struct Image {
Expand Down Expand Up @@ -332,6 +357,56 @@ impl Graphics {
graphics_ortho(self.entity, left, right, bottom, top, near, far)
.map_err(|e| PyRuntimeError::new_err(format!("{e}")))
}

pub fn light_directional(&self, r: f32, g: f32, b: f32, illuminance: f32) -> PyResult<Light> {
let color = bevy::color::Color::srgb(r, g, b);
match light_create_directional(self.entity, color, illuminance) {
Ok(light) => Ok(Light { entity: light }),
Err(e) => Err(PyRuntimeError::new_err(format!("{e}"))),
}
}

pub fn light_point(
&self,
r: f32,
g: f32,
b: f32,
intensity: f32,
range: f32,
radius: f32,
) -> PyResult<Light> {
let color = bevy::color::Color::srgb(r, g, b);
match light_create_point(self.entity, color, intensity, range, radius) {
Ok(light) => Ok(Light { entity: light }),
Err(e) => Err(PyRuntimeError::new_err(format!("{e}"))),
}
}

pub fn light_spot(
&self,
r: f32,
g: f32,
b: f32,
intensity: f32,
range: f32,
radius: f32,
inner_angle: f32,
outer_angle: f32,
) -> PyResult<Light> {
let color = bevy::color::Color::srgb(r, g, b);
match light_create_spot(
self.entity,
color,
intensity,
range,
radius,
inner_angle,
outer_angle,
) {
Ok(light) => Ok(Light { entity: light }),
Err(e) => Err(PyRuntimeError::new_err(format!("{e}"))),
}
}
}

// TODO: a real color type. or color parser? idk. color is confusing. let's think
Expand Down
49 changes: 47 additions & 2 deletions crates/processing_pyo3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
mod glfw;
mod graphics;

use graphics::{Geometry, Graphics, Image, Topology, get_graphics, get_graphics_mut};
use graphics::{Geometry, Graphics, Image, Light, Topology, get_graphics, get_graphics_mut};
use pyo3::{
exceptions::PyRuntimeError,
prelude::*,
Expand All @@ -25,7 +25,7 @@ use std::env;
fn processing(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_class::<Graphics>()?;
m.add_class::<Image>()?;
m.add_class::<Geometry>()?;
m.add_class::<Light>()?;
m.add_class::<Topology>()?;
m.add_function(wrap_pyfunction!(size, m)?)?;
m.add_function(wrap_pyfunction!(run, m)?)?;
Expand All @@ -45,6 +45,9 @@ fn processing(m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add_function(wrap_pyfunction!(rect, m)?)?;
m.add_function(wrap_pyfunction!(image, m)?)?;
m.add_function(wrap_pyfunction!(draw_geometry, m)?)?;
m.add_function(wrap_pyfunction!(create_directional_light, m)?)?;
m.add_function(wrap_pyfunction!(create_point_light, m)?)?;
m.add_function(wrap_pyfunction!(create_spot_light, m)?)?;

Ok(())
}
Expand Down Expand Up @@ -275,3 +278,45 @@ fn rect(
fn image(module: &Bound<'_, PyModule>, image_file: &str) -> PyResult<Image> {
get_graphics(module)?.image(image_file)
}

#[pyfunction]
#[pyo3(pass_module, signature = (r, g, b, illuminance))]
fn create_directional_light(
module: &Bound<'_, PyModule>,
r: f32,
g: f32,
b: f32,
illuminance: f32,
) -> PyResult<Light> {
get_graphics(module)?.light_directional(r, g, b, illuminance)
}

#[pyfunction]
#[pyo3(pass_module, signature = (r, g, b, intensity, range, radius))]
fn create_point_light(
module: &Bound<'_, PyModule>,
r: f32,
g: f32,
b: f32,
intensity: f32,
range: f32,
radius: f32,
) -> PyResult<Light> {
get_graphics(module)?.light_point(r, g, b, intensity, range, radius)
}

#[pyfunction]
#[pyo3(pass_module, signature = (r, g, b, intensity, range, radius, inner_angle, outer_angle))]
fn create_spot_light(
module: &Bound<'_, PyModule>,
r: f32,
g: f32,
b: f32,
intensity: f32,
range: f32,
radius: f32,
inner_angle: f32,
outer_angle: f32,
) -> PyResult<Light> {
get_graphics(module)?.light_spot(r, g, b, intensity, range, radius, inner_angle, outer_angle)
}
Loading