Skip to content

Commit

Permalink
Add primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
tommy-xr committed May 30, 2024
1 parent 3eea142 commit 4f73e37
Show file tree
Hide file tree
Showing 11 changed files with 454 additions and 184 deletions.
2 changes: 1 addition & 1 deletion examples/Pong/Pong.fs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ let init (_args: array<string>) =
game
|> GameBuilder.draw3d (fun model ->
printfn "Tick: %d" model.counter;
Graphics.Scene3D.cube()
Graphics.Scene3D.sphere()
)
|> GameBuilder.tick tick
|> Runtime.runGame
Expand Down
181 changes: 0 additions & 181 deletions runtime/functor-runtime-common/src/geometry.rs

This file was deleted.

22 changes: 22 additions & 0 deletions runtime/functor-runtime-common/src/geometry/cube.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
use super::mesh::{self, Mesh};

pub struct Cube;

impl Cube {
pub fn create() -> Mesh {
mesh::create(vec![
-0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5,
0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5,
0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, 0.5, 1.0,
1.0, -0.5, 0.5, 0.5, 0.0, 1.0, -0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0,
-0.5, 0.5, -0.5, 1.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0, -0.5, -0.5, -0.5, 0.0, 1.0,
-0.5, -0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, 0.5, 0.5,
-0.5, 1.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, 0.5,
0.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, -0.5, -0.5, 0.0, 1.0, 0.5, -0.5, -0.5, 1.0,
1.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, -0.5, -0.5, 0.5, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, 0.5, 0.5, -0.5, 1.0, 1.0, 0.5,
0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, -0.5,
0.0, 1.0,
])
}
}
139 changes: 139 additions & 0 deletions runtime/functor-runtime-common/src/geometry/cylinder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
use std::{f32::consts::PI, os::macos::raw};

use cgmath::{vec2, vec3, Vector2, Vector3};

use super::mesh::{self, Mesh};

pub struct Cylinder;

#[derive(Debug, Clone, Copy)]
struct Vertex {
position: Vector3<f32>,
normal: Vector3<f32>,
tex_coords: Vector2<f32>,
}

fn generate_cylinder(
slices: u32,
stacks: u32,
height: f32,
radius: f32,
) -> (Vec<Vertex>, Vec<usize>) {
let mut vertices = Vec::new();
let mut indices = Vec::new();

// Generate the vertices for the side surface
for stack in 0..=stacks {
let stack_fraction = stack as f32 / stacks as f32;
let y = stack_fraction * height - (height / 2.0);

for slice in 0..=slices {
let slice_fraction = slice as f32 / slices as f32;
let angle = slice_fraction * 2.0 * PI;

let x = angle.cos() * radius;
let z = angle.sin() * radius;

let position = Vector3::new(x, y, z);
let normal = Vector3::new(angle.cos(), 0.0, angle.sin());
let tex_coords = Vector2::new(slice_fraction, stack_fraction);

vertices.push(Vertex {
position,
normal,
tex_coords,
});

if stack < stacks && slice < slices {
let first = (stack * (slices + 1) + slice) as usize;
let second = first + slices as usize + 1;

indices.push(first);
indices.push(second);
indices.push(first + 1);

indices.push(second);
indices.push(second + 1);
indices.push(first + 1);
}
}
}

// Generate the vertices and indices for the top and bottom caps
let top_center_index = vertices.len() as usize;
vertices.push(Vertex {
position: Vector3::new(0.0, height / 2.0, 0.0),
normal: Vector3::new(0.0, 1.0, 0.0),
tex_coords: Vector2::new(0.5, 0.5),
});

let bottom_center_index = vertices.len() as usize;
vertices.push(Vertex {
position: Vector3::new(0.0, -height / 2.0, 0.0),
normal: Vector3::new(0.0, -1.0, 0.0),
tex_coords: Vector2::new(0.5, 0.5),
});

for slice in 0..=slices {
let slice_fraction = slice as f32 / slices as f32;
let angle = slice_fraction * 2.0 * PI;

let x = angle.cos() * radius;
let z = angle.sin() * radius;

let top_position = Vector3::new(x, height / 2.0, z);
let bottom_position = Vector3::new(x, -height / 2.0, z);
let normal = Vector3::new(0.0, 1.0, 0.0);
let tex_coords = Vector2::new(slice_fraction, 0.0);

vertices.push(Vertex {
position: top_position,
normal,
tex_coords: Vector2::new(slice_fraction, 1.0),
});

vertices.push(Vertex {
position: bottom_position,
normal: -normal,
tex_coords,
});

let top_index = (top_center_index + slice as usize + 1) as usize;
let bottom_index = (bottom_center_index + slice as usize + 1) as usize;

if slice < slices {
indices.push(top_center_index);
indices.push(top_index);
indices.push(top_index + 1);

indices.push(bottom_center_index);
indices.push(bottom_index + 1);
indices.push(bottom_index);
}
}

(vertices, indices)
}

impl Cylinder {
pub fn create() -> Mesh {
let slices = 20;
let stacks = 20;
let height = 1.0;
let radius = 0.5;
let (sphere_vertices, sphere_indices) = generate_cylinder(slices, stacks, height, radius);

let mut raw_vertices: Vec<f32> = Vec::new();

for idx in sphere_indices {
let vertex = sphere_vertices[idx];
raw_vertices.push(vertex.position.x);
raw_vertices.push(vertex.position.y);
raw_vertices.push(vertex.position.z);
raw_vertices.push(vertex.tex_coords.x);
raw_vertices.push(vertex.tex_coords.y);
}

mesh::create(raw_vertices)
}
}
9 changes: 9 additions & 0 deletions runtime/functor-runtime-common/src/geometry/empty_mesh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
use super::Geometry;

pub struct EmptyMesh;

impl Geometry for EmptyMesh {
fn draw(&mut self, _gl: &glow::Context) {
// do nothing, the mesh is empty
}
}
Loading

0 comments on commit 4f73e37

Please sign in to comment.