Struct Mesh

Source
pub struct Mesh(pub NonNull<_MeshT>);
Expand description

A Mesh is a single collection of triangular faces with extra surface information to enhance rendering! StereoKit meshes are composed of a list of vertices, and a list of indices to connect the vertices into faces. Nothing more than that is stored here, so typically meshes are combined with Materials, or added to Models in order to draw them.

Mesh vertices are composed of a position, a normal (direction of the vert), a uv coordinate (for mapping a texture to the mesh’s surface), and a 32 bit color containing red, green, blue, and alpha (transparency).

Mesh indices are stored as unsigned ints, so you can have a mesh with a fudgeton of verts! 4 billion or so :) https://stereokit.net/Pages/StereoKit/Mesh.html

§Examples

use stereokit_rust::{maths::{Vec3, Matrix, Quat}, util::{named_colors,Color32},
                     mesh::Mesh, material::Material};

// Create Meshes
let cube = Mesh::generate_cube(Vec3::ONE * 0.8, None);
let sphere = Mesh::generate_sphere(1.0, None);

let material_cube = Material::pbr().copy();
let mut material_sphere = Material::pbr().copy();
material_sphere.color_tint(named_colors::GREEN);
let cube_transform = Matrix::r([40.0, 50.0, 20.0]);

filename_scr = "screenshots/meshes.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    cube.draw(token, &material_cube, cube_transform, None, None);
    sphere.draw(token, &material_sphere, Matrix::IDENTITY, None, None);
);
screenshot

Tuple Fields§

§0: NonNull<_MeshT>

Implementations§

Source§

impl Mesh

Source

pub fn new() -> Mesh

Creates an empty Mesh asset. Use SetVerts and SetInds to add data to it! https://stereokit.net/Pages/StereoKit/Mesh/Mesh.html

see also mesh_create Mesh::default

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::new();

assert_eq!(mesh.get_inds().len(), 0);
assert_eq!(mesh.get_verts().len(), 0);
Source

pub fn generate_plane<V: Into<Vec3>>( dimensions: impl Into<Vec2>, plane_normal: V, plane_top_direction: V, subdivisions: Option<i32>, double_sided: bool, ) -> Mesh

Generates a plane with an arbitrary orientation that is optionally subdivided, pre-sized to the given dimensions. UV coordinates start at the top left indicated with plane_top_direction.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. You may also be interested in using the pre-generated Mesh.Quad asset if it already meets your needs. https://stereokit.net/Pages/StereoKit/Mesh/GeneratePlane.html

  • dimension - How large is this plane on the XZ axis, in meters?
  • plane_normal - What is the normal of the surface this plane is generated on?
  • plane_top_direction - A normal defines the plane, but this is technically a rectangle on the plane. So which direction is up? It’s important for UVs, but doesn’t need to be exact. This function takes the planeNormal as law, and uses this vector to find the right and up vectors via cross-products.
  • subdivisions - Use this to add extra slices of vertices across the plane. This can be useful for some types of vertex-based effects! None is 0.
  • double_sided - Should both sides of the plane be rendered?

Returns a plane mesh, pre-sized to the given dimensions. see also mesh_gen_plane

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_plane([1.0, 1.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], None, false);
assert_eq!(mesh.get_ind_count(), 6);
assert_eq!(mesh.get_vert_count(), 4);

let mesh = Mesh::generate_plane([1.0, 1.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], None, true);
assert_eq!(mesh.get_ind_count(), 12);
assert_eq!(mesh.get_vert_count(), 8);

let mesh = Mesh::generate_plane([1.0, 1.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], Some(1), true);
assert_eq!(mesh.get_ind_count(), 48);
assert_eq!(mesh.get_vert_count(), 18);
Source

pub fn generate_plane_up( dimensions: impl Into<Vec2>, subdivisions: Option<i32>, double_sided: bool, ) -> Mesh

Generates a plane on the XZ axis facing up that is optionally subdivided, pre-sized to the given dimensions. UV coordinates start at 0,0 at the -X,-Z corner, and go to 1,1 at the +X,+Z corner!

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. You may also be interested in using the pre-generated Mesh.Quad asset if it already meets your needs. https://stereokit.net/Pages/StereoKit/Mesh/GeneratePlane.html

  • dimension - How large is this plane on the XZ axis, in meters?
  • subdivisions - Use this to add extra slices of vertices across the plane. This can be useful for some types of vertex-based effects! None is 0.
  • double_sided - Should both sides of the plane be rendered?

Returns a plane mesh, pre-sized to the given dimensions. see also mesh_gen_plane

§Examples
use stereokit_rust::{mesh::{Mesh, Vertex}, maths::{Vec2, Vec3}};

// Create Meshes
let mesh = Mesh::generate_plane_up([1.0, 1.0],  None, false);
let mesh_b = Mesh::generate_plane([1.0, 1.0], [0.0, 1.0, 0.0], [0.0, 0.0, -1.0], None, false);
assert_eq!(mesh.get_verts(), mesh_b.get_verts());
assert_eq!(mesh.get_inds(), mesh_b.get_inds());
assert_eq!(mesh.get_ind_count(), 6);
assert_eq!(mesh.get_vert_count(), 4);
let vertices0 = [
   Vertex::new([-0.5, 0.0,-0.5].into(),Vec3::UP,Some(Vec2::ZERO), None),
   Vertex::new([ 0.5, 0.0,-0.5].into(),Vec3::UP,Some(Vec2::X)   , None),
   Vertex::new([-0.5, 0.0, 0.5].into(),Vec3::UP,Some(Vec2::Y)   , None),
   Vertex::new([ 0.5, 0.0, 0.5].into(),Vec3::UP,Some(Vec2::ONE) , None),
   ];
assert_eq!(mesh.get_verts(), vertices0);

let mesh = Mesh::generate_plane_up([1.0, 1.0], None, true);
assert_eq!(mesh.get_inds().len(), 12);
assert_eq!(mesh.get_verts().len(), 8);

let mesh = Mesh::generate_plane_up([1.0, 1.0], Some(1), true);
assert_eq!(mesh.get_inds().len(), 48);
assert_eq!(mesh.get_verts().len(), 18);
Source

pub fn generate_circle<V: Into<Vec3>>( diameter: f32, plane_normal: V, plane_top_direction: V, spokes: Option<i32>, double_sided: bool, ) -> Mesh

Generates a circle with an arbitrary orientation that is pre-sized to the given diameter. UV coordinates start at the top left indicated with ‘plane_top_direction’ and correspond to a unit circle centered at 0.5, 0.5.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. https://stereokit.net/Pages/StereoKit/Mesh/GenerateCircle.html

  • diameter - The diameter of the circle in meters, or 2*radius. This is the full length from one side to the other.
  • plane_normal - What is the normal of the surface this circle is generated on?
  • plane_top_direction - A normal defines the plane, but this is technically a rectangle on the plane. So which direction is up? It’s important for UVs, but doesn’t need to be exact. This function takes the plane_normal as law, and uses this vector to find the right and up vectors via cross-products.
  • spokes - How many vertices compose the circumference of the circle? Clamps to a minimum of 3. More is smoother, but less performant. if None has default value of 16.
  • double_sided - Should both sides of the circle be rendered?

Returns A circle mesh, pre-sized to the given dimensions.

see also mesh_gen_circle

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_circle(1.0, [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], None, false);
assert_eq!(mesh.get_ind_count(), 42);
assert_eq!(mesh.get_vert_count(), 16);

let mesh = Mesh::generate_circle(1.0, [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], None, true);
assert_eq!(mesh.get_inds().len(), 84);
assert_eq!(mesh.get_verts().len(), 32);

let mesh = Mesh::generate_circle(1.0, [0.0, 1.0, 0.0], [0.0, 0.0, 1.0], Some(1), true);
assert_eq!(mesh.get_inds().len(), 6);
assert_eq!(mesh.get_verts().len(), 6);
Source

pub fn generate_circle_up( diameter: f32, spokes: Option<i32>, double_sided: bool, ) -> Mesh

Generates a circle on the XZ axis facing up that is pre-sized to the given diameter. UV coordinates correspond to a unit circle centered at 0.5, 0.5! That is, the right-most point on the circle has UV coordinates 1, 0.5 and the top-most point has UV coordinates 0.5, 1.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. https://stereokit.net/Pages/StereoKit/Mesh/GenerateCircle.html

  • diameter - The diameter of the circle in meters, or 2*radius. This is the full length from one side to the other.
  • spokes - How many vertices compose the circumference of the circle? Clamps to a minimum of 3. More is smoother, but less performant. if None has default value of 16.
  • double_sided - Should both sides of the circle be rendered?

Returns A circle mesh, pre-sized to the given dimensions. see also mesh_gen_circle

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_circle_up(1.0 , None, false);
let mesh_b = Mesh::generate_circle(1.0, [0.0, 1.0, 0.0], [0.0, 0.0, -1.0], None, false);
assert_eq!(mesh.get_verts(), mesh_b.get_verts());
assert_eq!(mesh.get_inds(), mesh_b.get_inds());
assert_eq!(mesh.get_ind_count(), 42);
assert_eq!(mesh.get_vert_count(), 16);

let mesh = Mesh::generate_circle_up(1.0 , None, true);
assert_eq!(mesh.get_inds().len(), 84);
assert_eq!(mesh.get_verts().len(), 32);

let mesh = Mesh::generate_circle_up(1.0 , Some(1), true);
assert_eq!(mesh.get_inds().len(), 6);
assert_eq!(mesh.get_verts().len(), 6);
Source

pub fn generate_cube( dimensions: impl Into<Vec3>, subdivisions: Option<i32>, ) -> Mesh

Generates a flat-shaded cube mesh, pre-sized to the given dimensions. UV coordinates are projected flat on each face, 0,0 -> 1,1.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. You may also be interested in using the pre-generated Mesh::cube() asset if it already meets your needs. https://stereokit.net/Pages/StereoKit/Mesh/GenerateCube.html

  • dimension - How large is this cube on each axis, in meters?
  • subdivisions - Use this to add extra slices of vertices across the cube’s faces. This can be useful for some types of vertex-based effects! None is 0.

Returns a flat-shaded cube mesh, pre-sized to the given dimensions. see also mesh_gen_circle

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_cube([1.0, 1.0, 1.0], None);
assert_eq!(mesh.get_ind_count(), 36);
assert_eq!(mesh.get_vert_count(), 24);

let mesh = Mesh::generate_cube([1.0, 1.0, 1.0], Some(1));
assert_eq!(mesh.get_inds().len(), 144);
assert_eq!(mesh.get_verts().len(), 54);
Source

pub fn generate_rounded_cube( dimensions: impl Into<Vec3>, edge_radius: f32, subdivisions: Option<i32>, ) -> Mesh

Generates a cube mesh with rounded corners, pre-sized to the given dimensions. UV coordinates are 0,0 -> 1,1 on each face, meeting at the middle of the rounded corners.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. https://stereokit.net/Pages/StereoKit/Mesh/GenerateRoundedCube.html

  • dimension - How large is this cube on each axis, in meters?
  • edge_radius - Radius of the corner rounding, in meters.
  • subdivisions -How many subdivisions should be used for creating the corners? A larger value results in smoother corners, but can decrease performance.! None is 4.

Returns a cube mesh with rounded corners, pre-sized to the given dimensions see also mesh_gen_rounded_cube

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_rounded_cube([1.0, 1.0, 1.0], 0.1, None);
assert_eq!(mesh.get_ind_count(), 900);
assert_eq!(mesh.get_vert_count(), 216);

let mesh = Mesh::generate_rounded_cube([1.0, 1.0, 1.0], 0.1, Some(1));
assert_eq!(mesh.get_inds().len(), 324);
assert_eq!(mesh.get_verts().len(), 96);

let mesh = Mesh::generate_rounded_cube([1.0, 1.0, 1.0], 0.2, Some(1));
assert_eq!(mesh.get_inds().len(), 324);
assert_eq!(mesh.get_verts().len(), 96);
Source

pub fn generate_sphere(diameter: f32, subdivisions: Option<i32>) -> Mesh

Generates a sphere mesh, pre-sized to the given diameter, created by sphereifying a subdivided cube! UV coordinates are taken from the initial unspherified cube.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. You may also be interested in using the pre-generated Mesh::sphere() asset if it already meets your needs. https://stereokit.net/Pages/StereoKit/Mesh/GenerateSphere.html

  • diameter - The diameter of the sphere in meters, or 2*radius. This is the full length from one side to the other.
  • subdivisions - How many times should the initial cube be subdivided? None is 4.

Returns - A sphere mesh, pre-sized to the given diameter, created by sphereifying a subdivided cube! UV coordinates are taken from the initial unspherified cube. see also mesh_gen_sphere

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_sphere(1.0 , None);
assert_eq!(mesh.get_ind_count(), 900);
assert_eq!(mesh.get_vert_count(), 216);


let mesh = Mesh::generate_sphere(1.0 , Some(1));
assert_eq!(mesh.get_inds().len(), 144);
assert_eq!(mesh.get_verts().len(), 54);
Source

pub fn generate_cylinder( diameter: f32, depth: f32, direction: impl Into<Vec3>, subdivisions: Option<i32>, ) -> Mesh

Generates a cylinder mesh, pre-sized to the given diameter and depth, UV coordinates are from a flattened top view right now. Additional development is needed for making better UVs for the edges.

NOTE: This generates a completely new Mesh asset on the GPU, and is best done during ‘initialization’ of your app/scene. https://stereokit.net/Pages/StereoKit/Mesh/GenerateCylinder.html

  • diameter - Diameter of the circular part of the cylinder in meters. Diameter is 2*radius.
  • depth - How tall is this cylinder, in meters?
  • direction - What direction do the circular surfaces face? This is the surface normal for the top, it does not need to be normalized.
  • subdivisions - How many vertices compose the edges of the cylinder? More is smoother, but less performant. None is 16.

Returns a cylinder mesh, pre-sized to the given diameter and depth, UV coordinates are from a flattened top view right now. see also mesh_gen_cylinder

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh = Mesh::generate_cylinder(1.0, 1.0, [0.0, 1.0, 0.0], None);
assert_eq!(mesh.get_ind_count(), 192);
assert_eq!(mesh.get_vert_count(), 70);

let mesh = Mesh::generate_cylinder(1.0, 1.0, [0.0, 1.0, 0.0], Some(1));
assert_eq!(mesh.get_inds().len(), 12);
assert_eq!(mesh.get_verts().len(), 10);
Source

pub fn find<S: AsRef<str>>(id: S) -> Result<Mesh, StereoKitError>

Finds the Mesh with the matching id, and returns a reference to it. If no Mesh is found, it returns StereoKitError::MeshFind. https://stereokit.net/Pages/StereoKit/Mesh/Find.html

  • id - The id of the Mesh to find.

see also mesh_find

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mut mesh = Mesh::generate_circle_up(1.0 , None, false);
mesh.id("my_circle");

let same_mesh = Mesh::find("my_circle").expect("Mesh should be here");

assert_eq!(mesh, same_mesh);
Source

pub fn clone_ref(&self) -> Mesh

Creates a clone of the same reference. Basically, the new variable is the same asset. This is what you get by calling find() method. https://stereokit.net/Pages/StereoKit/Mesh/Find.html

see also mesh_find()

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mesh =          Mesh::generate_circle_up(1.0 , None, false);
let not_same_mesh = Mesh::generate_circle_up(1.0 , None, false);

let same_mesh = mesh.clone_ref();

assert_eq!(mesh, same_mesh);
assert_ne!(mesh, not_same_mesh);
Source

pub fn id<S: AsRef<str>>(&mut self, id: S) -> &mut Self

Sets the unique identifier of this asset resource! This can be helpful for debugging, managing your assets, or finding them later on! https://stereokit.net/Pages/StereoKit/Mesh/Id.html

  • id - The unique identifier for this asset! Be sure it’s unique!

see also mesh_set_id

§Examples
use stereokit_rust::mesh::Mesh;

// Create Meshes
let mut mesh = Mesh::generate_circle_up(1.0 , None, false);
assert!(mesh.get_id().starts_with("auto/mesh_"));
mesh.id("my_circle");

assert_eq!(mesh.get_id(), "my_circle");
Source

pub fn bounds(&mut self, bounds: impl AsRef<Bounds>) -> &mut Self

This is a bounding box that encapsulates the Mesh! It’s used for collision, visibility testing, UI layout, and probably other things. While it’s normally calculated from the mesh vertices, you can also override this to suit your needs. https://stereokit.net/Pages/StereoKit/Mesh/Bounds.html

  • bounds - The bounding box to set.

see also mesh_set_bounds

§Examples
use stereokit_rust::{maths::{Vec3, Matrix, Bounds},
                     mesh::Mesh, material::Material, util::named_colors};

let mut sphere = Mesh::generate_sphere(1.0, None);
let material_sphere = Material::pbr();
let transform = Matrix::IDENTITY;

let cube =   Mesh::cube();
let mut material_before = Material::ui_box();
material_before.color_tint(named_colors::GOLD)
               .border_size(0.025);

let mut material_after = material_before.copy();
material_after.color_tint(named_colors::RED);

let bounds = sphere.get_bounds();
let transform_before = Matrix::t_s( bounds.center, bounds.dimensions);

sphere.bounds( Bounds::bounds_centered(Vec3::ONE * 0.7));
let new_bounds = sphere.get_bounds();
let transform_after = Matrix::t_s( new_bounds.center, new_bounds.dimensions);

filename_scr = "screenshots/mesh_bounds.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    sphere.draw(token, &material_sphere, transform, None, None);
    cube.draw(  token, &material_before, transform_before, None, None);
    cube.draw(  token, &material_after,  transform_after,  None, None);
);
screenshot
Source

pub fn keep_data(&mut self, keep_data: bool) -> &mut Self

Should StereoKit keep the mesh data on the CPU for later access, or collision detection? Defaults to true. If you set this to false before setting data, the data won’t be stored. If you call this after setting data, that stored data will be freed! If you set this to true again later on, it will not contain data until it’s set again. https://stereokit.net/Pages/StereoKit/Mesh/KeepData.html

see also mesh_set_keep_data

§Examples
use stereokit_rust::{mesh::Mesh, maths::Bounds};

// Create Meshes
let mut mesh = Mesh::generate_circle_up(1.0 , None, false);
assert_eq!(mesh.get_keep_data(), true);
assert_ne!(mesh.get_bounds(), Bounds::default());

mesh.keep_data(false);
assert_eq!(mesh.get_keep_data(), false);
mesh.keep_data(true);
assert_eq!(mesh.get_keep_data(), true);
Source

pub fn set_data( &mut self, vertices: &[Vertex], indices: &[u32], calculate_bounds: bool, ) -> &mut Self

Assigns the vertices and indices for this Mesh! This will create a vertex buffer and index buffer object on the graphics card. If you’re calling this a second time, the buffers will be marked as dynamic and re-allocated. If you’re calling this a third time, the buffer will only re-allocate if the buffer is too small, otherwise it just copies in the data!

Remember to set all the relevant values! Your material will often show black if the Normals or Colors are left at their default values.

Calling SetData is slightly more efficient than calling SetVerts and SetInds separately. https://stereokit.net/Pages/StereoKit/Mesh/SetData.html

  • vertices - An array of vertices to add to the mesh. Remember to set all the relevant values! Your material will often show black if the Normals or Colors are left at their default values.
  • indices - A list of face indices, must be a multiple of 3. Each index represents a vertex from the provided vertex array.
  • calculate_bounds - If true, this will also update the Mesh’s bounds based on the vertices provided. Since this does require iterating through all the verts with some logic, there is performance cost to doing this. If you’re updating a mesh frequently or need all the performance you can get, setting this to false is a nice way to gain some speed!

see also mesh_set_data see exampleVertex

Source

pub fn set_verts( &mut self, vertices: &[Vertex], calculate_bounds: bool, ) -> &mut Self

Assigns the vertices for this Mesh! This will create a vertex buffer object on the graphics card. If you’re calling this a second time, the buffer will be marked as dynamic and re-allocated. If you’re calling this a third time, the buffer will only re-allocate if the buffer is too small, otherwise it just copies in the data!

Remember to set all the relevant values! Your material will often show black if the Normals or Colors are left at their default values. https://stereokit.net/Pages/StereoKit/Mesh/SetVerts.html

  • vertices - An array of vertices to add to the mesh. Remember to set all the relevant values! Your material will often show black if the Normals or Colors are left at their default values.
  • calculate_bounds - If true, this will also update the Mesh’s bounds based on the vertices provided. Since this does require iterating through all the verts with some logic, there is performance cost to doing this. If you’re updating a mesh frequently or need all the performance you can get, setting this to false is a nice way to gain some speed!

see also mesh_set_verts Vertex Mesh::set_data

§Examples
use stereokit_rust::{maths::{Vec2, Vec3, Matrix, Bounds}, mesh::{Mesh, Vertex},
                     material::Material, util::named_colors};

let material = Material::pbr();
let mut square = Mesh::new();
square.set_verts(&[
    Vertex::new([-1.0, -1.0, 0.0].into(), Vec3::UP, None,            Some(named_colors::BLUE)),
    Vertex::new([ 1.0, -1.0, 0.0].into(), Vec3::UP, Some(Vec2::X),   None),
    Vertex::new([-1.0,  1.0, 0.0].into(), Vec3::UP, Some(Vec2::Y),   None),
    Vertex::new([ 1.0,  1.0, 0.0].into(), Vec3::UP, Some(Vec2::ONE), Some(named_colors::YELLOW)),
    ], true)
   .set_inds(&[0, 1, 2, 2, 1, 3]);

filename_scr = "screenshots/mesh_set_verts.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    square.draw(token, &material , Matrix::IDENTITY, None, None);
);
screenshot
Source

pub fn set_inds(&mut self, indices: &[u32]) -> &mut Self

Assigns the face indices for this Mesh! Faces are always triangles, there are only ever three indices per face. This function will create a index buffer object on the graphics card. If you’re calling this a second time, the buffer will be marked as dynamic and re-allocated. If you’re calling this a third time, the buffer will only re-allocate if the buffer is too small, otherwise it just copies in the data! https://stereokit.net/Pages/StereoKit/Mesh/SetInds.html

  • indices - A list of face indices, must be a multiple of 3. Each index represents a vertex from the array assigned using SetVerts.

see also mesh_set_inds Vertex Mesh::set_data

§Examples
use stereokit_rust::{maths::{Vec2, Vec3, Matrix, Bounds}, mesh::{Mesh, Vertex},
                     material::Material, util::named_colors};

let material = Material::pbr();
let mut sphere = Mesh::generate_sphere(1.5, Some(16));

// Let's remove half of the triangles.
let indices = sphere.get_inds();
let mut new_indices = vec![];
let mut iter = 0;
for i in 0..indices.len() {
    if iter < 3 {   
       new_indices.push(indices[i]);
    } else if iter == 5 {
       iter = -1;
    }
   iter += 1;
}

sphere.set_inds(&new_indices);

filename_scr = "screenshots/mesh_set_inds.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    sphere.draw(token, &material , Matrix::IDENTITY,  Some(named_colors::PINK.into()), None);
);
screenshot
Source

pub fn draw( &self, _token: &MainThreadToken, material: impl AsRef<Material>, transform: impl Into<Matrix>, color_linear: Option<Color128>, layer: Option<RenderLayer>, )

Adds a mesh to the render queue for this frame! If the Hierarchy has a transform on it, that transform is combined with the Matrix provided here. https://stereokit.net/Pages/StereoKit/Mesh/Draw.html

  • material - A Material to apply to the Mesh.
  • transform - A Matrix that will transform the mesh from Model Space into the current Hierarchy Space.
  • color_linear - A per-instance linear space color value to pass into the shader! Normally this gets used like a material tint. If you’re adventurous and don’t need per-instance colors, this is a great spot to pack in extra per-instance data for the shader! If None has default value of WHITE
  • layer - All visuals are rendered using a layer bit-flag. By default, all layers are rendered, but this can be useful for filtering out objects for different rendering purposes! For example: rendering a mesh over the user’s head from a 3rd person perspective, but filtering it out from the 1st person perspective.If None has default value of Layer0

see also mesh_draw

§Examples
use stereokit_rust::{maths::{Vec2, Vec3, Matrix, Bounds}, mesh::{Mesh, Vertex},
                     material::Material, util::named_colors, system::RenderLayer};

let material = Material::pbr();
let cylinder1 = Mesh::generate_cylinder(0.25, 1.5, Vec3::ONE,        None);
let cylinder2 = Mesh::generate_cylinder(0.25, 1.5, [-0.5, 0.5, 0.5], None);
let cylinder3 = Mesh::generate_cylinder(0.25, 1.2, [0.0, -0.5, 0.5], None);

filename_scr = "screenshots/mesh_draw.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    cylinder1.draw(token, &material , Matrix::IDENTITY, None, None);
    cylinder2.draw(token, &material , Matrix::IDENTITY, Some(named_colors::RED.into()),
        Some(RenderLayer::Layer1));
    cylinder3.draw(token, &material , Matrix::IDENTITY, Some(named_colors::GREEN.into()),
        Some(RenderLayer::ThirdPerson));
);
screenshot
Source

pub fn get_id(&self) -> &str

Gets the unique identifier of this asset resource! This can be helpful for debugging, managing your assets, or finding them later on! https://stereokit.net/Pages/StereoKit/Mesh/id.html

see also mesh_get_id see example in Mesh::id

Source

pub fn get_bounds(&self) -> Bounds

This is a bounding box that encapsulates the Mesh! It’s used for collision, visibility testing, UI layout, and probably other things. While it’s normally calculated from the mesh vertices, you can also override this to suit your needs. https://stereokit.net/Pages/StereoKit/Mesh/Bounds.html

see also mesh_get_bounds see example in Mesh::bounds

Source

pub fn get_keep_data(&self) -> bool

Should StereoKit keep the mesh data on the CPU for later access, or collision detection? Defaults to true. If you set this to false before setting data, the data won’t be stored. If you call this after setting data, that stored data will be freed! If you set this to true again later on, it will not contain data until it’s set again. https://stereokit.net/Pages/StereoKit/Mesh/KeepData.html

see also mesh_get_keep_data see example in Mesh::keep_data

Source

pub fn get_ind_count(&self) -> i32

Get the number of indices stored in this Mesh! This is available to you regardless of whether or not keep_data is set. https://stereokit.net/Pages/StereoKit/Mesh/IndCount.html

see also mesh_get_ind_count

Source

pub fn get_vert_count(&self) -> i32

Get the number of vertices stored in this Mesh! This is available to you regardless of whether or not keep_data is set. https://stereokit.net/Pages/StereoKit/Mesh/VertCount.html

see also mesh_get_vert_count

Source

pub fn get_inds(&self) -> &[u32]

This marshalls the Mesh’s index data into an array. If keep_data is false, then the Mesh is not storing indices on the CPU, and this information will not be available.

Due to the way marshalling works, this is not a cheap function! https://stereokit.net/Pages/StereoKit/Mesh/GetInds.html Returns - An array of indices representing the Mesh, or null if keep_data is false.

see also Mesh::get_inds_copy mesh_get_inds see example in Mesh::set_inds

Source

pub fn get_inds_copy(&self) -> Vec<u32>

Get the indices by value This marshalls the Mesh’s index data into an array. If keep_data is false, then the Mesh is not storing indices on the CPU, and this information will not be available.

Due to the way marshalling works, this is not a cheap function! https://stereokit.net/Pages/StereoKit/Mesh/GetInds.html

see also Mesh::get_inds mesh_get_inds

Source

pub fn get_verts(&self) -> &[Vertex]

This marshalls the Mesh’s vertex data into an array. If keep_data is false, then the Mesh is not storing verts on the CPU, and this information will not be available.

Due to the way marshalling works, this is not a cheap function! https://stereokit.net/Pages/StereoKit/Mesh/GetVerts.html

see also Mesh::get_verts_copy mesh_get_verts see example in Mesh::set_verts

Source

pub fn get_verts_copy(&self) -> Vec<Vertex>

Get the vertices by value This marshalls the Mesh’s vertex data into an array. If keep_data is false, then the Mesh is not storing verts on the CPU, and this information will not be available.

Due to the way marshalling works, this is not a cheap function! https://stereokit.net/Pages/StereoKit/Mesh/GetVerts.html

see also Mesh::get_verts mesh_get_verts

Source

pub fn get_triangle(&self, triangle_index: u32) -> Option<[Vertex; 3]>

Retrieves the vertices associated with a particular triangle on the Mesh. https://stereokit.net/Pages/StereoKit/Mesh/GetTriangle.html

  • triangle_index - Starting index of the triangle, should be a multiple of 3.

Returns an array of 3 vertices if triangle index was valid. see also mesh_get_triangle

§Examples
use stereokit_rust::{maths::{Vec2, Vec3, Matrix, Bounds}, mesh::{Mesh, Vertex},
                     material::Material, util::named_colors, system::RenderLayer};

let material = Material::pbr();
let plane = Mesh::generate_plane_up(Vec2::ONE, None, false);
assert_eq!(plane.get_vert_count(), 4, "plane should have 4 vertices");
assert_eq!(plane.get_ind_count(), 6, "plane should have 6 indices");

let triangle0 = plane.get_triangle(0 * 3).expect("triangle 0 should exist");    
let triangle1 = plane.get_triangle(1 * 3).expect("triangle 1 should exist");
//assert!(plane.get_triangle(5).is_some(), "triangle 5 should exist");
assert!(plane.get_triangle(2 * 3).is_none(), "triangle 6 should not exist");

let vertices0 = [
   Vertex::new([ 0.5, 0.0, 0.5].into(),Vec3::UP,Some(Vec2::ONE) , None),
   Vertex::new([ 0.5, 0.0,-0.5].into(),Vec3::UP,Some(Vec2::X)   , None),
   Vertex::new([-0.5, 0.0,-0.5].into(),Vec3::UP,Some(Vec2::ZERO), None),
   ];
assert_eq!(triangle0, vertices0);

let vertices1 = [
   Vertex::new([-0.5, 0.0, 0.5].into(),Vec3::UP,Some(Vec2::Y)   , None),
   Vertex::new([ 0.5, 0.0, 0.5].into(),Vec3::UP,Some(Vec2::ONE) , None),
   Vertex::new([-0.5, 0.0,-0.5].into(),Vec3::UP,Some(Vec2::ZERO), None),
   ];
assert_eq!(triangle1, vertices1);
Source

pub fn intersect( &self, model_space_ray: Ray, cull: Option<Cull>, ) -> Option<(Vec3, VindT)>

Checks the intersection point of a ray and this Mesh with collision data stored on the CPU. A mesh without collision data will always return None. Ray must be in model space, intersection point will be in model space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space, see the example in the docs! https://stereokit.net/Pages/StereoKit/Mesh/Intersect.html

  • model_space_ray - Ray must be in model space, the intersection point will be in model space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space, see the example in the docs!
  • cull - If None has default value of Cull::Back.

Returns a tuple with

  • The intersection point of the ray and the mesh, if an intersection occurs. This is in model space, and must be transformed back into world space later.
  • The indice of the mesh where the intersection occurs.

see also mesh_ray_intersect Ray::intersect_mesh

§Examples
use stereokit_rust::{maths::{Vec3, Matrix, Quat, Ray}, system::Lines,
    util::{named_colors}, mesh::Mesh, material::{Material, Cull}};

// Create Meshes
let cube = Mesh::generate_cube(Vec3::ONE * 0.8, None);
let sphere = Mesh::generate_sphere(1.0, Some(4));

let material = Material::pbr().copy();
let transform = Matrix::r(Quat::from_angles(40.0, 50.0, 20.0));
let inv = transform.get_inverse();

let ray = Ray::new([-1.0, 2.0, 2.5 ], [1.0, -2.0, -2.25]);
let inv_ray = inv.transform_ray(ray);

let (contact_cube, ind_cube) = cube.intersect( inv_ray, Some(Cull::Back))
    .expect("Ray should touch cube");
assert_eq!(ind_cube, 12);

let transform_contact_cube = Matrix::t_s(
    transform.transform_point(contact_cube), Vec3::ONE * 0.1);

filename_scr = "screenshots/mesh_intersect.jpeg";
test_screenshot!( // !!!! Get a proper main loop !!!!
    cube.draw(token, &material, transform, Some(named_colors::CYAN.into()), None);
    Lines::add_ray(token, ray, 2.2, named_colors::WHITE, None, 0.02);
    sphere.draw(token, &material, transform_contact_cube, Some(named_colors::YELLOW.into()), None );
);
screenshot
Source

pub fn intersect_to_ptr( &self, ray: Ray, cull: Option<Cull>, out_model_space_ray: *mut Ray, out_start_inds: *mut u32, ) -> bool

Checks the intersection point of a Ray and this Mesh with collision data stored on the CPU. A mesh without collision data will always return false. Ray must be in model space, intersection point will be in model space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space, see the example in the docs! https://stereokit.net/Pages/StereoKit/Mesh/Intersect.html

  • model_space_ray - Ray must be in model space, the intersection point will be in model space too. You can use the inverse of the mesh’s world transform matrix to bring the ray into model space, see the example in the docs!
  • cull - If None has default value of Cull::Back.
  • out_model_space_ray -The intersection point and surface direction of the ray and the mesh, if an intersection occurs. This is in model space, and must be transformed back into world space later. Direction is not guaranteed to be normalized, especially if your own model->world transform contains scale/skew in it.
  • out_start_inds - The index of the first index of the triangle that was hit

Returns true if an intersection occurs. see also mesh_ray_intersect Ray::intersect_mesh Mesh::intersect

§Examples
use stereokit_rust::{maths::{Vec3, Matrix, Quat, Ray}, system::Lines,
    util::{named_colors}, mesh::Mesh, material::{Material, Cull}};

// Create Meshes
let cube = Mesh::generate_cube(Vec3::ONE * 0.8, None);
let sphere = Mesh::generate_sphere(1.0, Some(4));

let material = Material::pbr().copy();
let transform = Matrix::r(Quat::from_angles(40.0, 50.0, 20.0));
let inv = transform.get_inverse();

let ray = Ray::new([-3.0, 2.0, 0.5 ], [3.0, -2.0, -0.25]);
let inv_ray = inv.transform_ray(ray);

let (mut contact_sphere_ray, mut ind_sphere) = (Ray::default(), 0u32);
assert!(sphere.intersect_to_ptr(inv_ray, Some(Cull::Front),
            &mut contact_sphere_ray, &mut ind_sphere)
    ,"Ray should touch sphere");

let (mut contact_cube_ray, mut ind_cube) = (Ray::default(), 0u32);
assert!( cube.intersect_to_ptr(
            inv_ray, Some(Cull::Back),
            &mut contact_cube_ray, &mut ind_cube)
    ,"Ray should touch cube");

assert_eq!(ind_sphere, 672);
assert_eq!(ind_cube, 9);

assert_eq!(transform.transform_ray(contact_sphere_ray),
        Ray { position:  Vec3 { x: 0.36746234, y: -0.244975, z: 0.21937825 },
              direction: Vec3 { x: 0.58682406, y: -0.6427875, z: 0.49240398 }});
assert_eq!(transform.transform_ray(contact_cube_ray),
        Ray { position:  Vec3 { x: -0.39531866, y: 0.26354572, z: 0.2829433 },
              direction: Vec3 { x: -0.77243483, y: -0.2620026, z: 0.57853174 } });
Source

pub fn cube() -> Self

A cube with dimensions of (1,1,1), this is equivalent to Mesh.GenerateCube(Vec3.One). https://stereokit.net/Pages/StereoKit/Mesh/Cube.html

§Examples
use stereokit_rust::mesh::Mesh;

// Get the mesh
let mesh = Mesh::cube();
assert_eq!(mesh.get_id(), "default/mesh_cube");
Source

pub fn screen_quad() -> Self

A default quad mesh, 2 triangles, 4 verts, from (-0.5,-0.5,0) to (0.5,0.5,0) and facing forward on the Z axis (0,0,-1). White vertex colors, and UVs from (1,1) at vertex (-0.5,-0.5,0) to (0,0) at vertex (0.5,0.5,0). https://stereokit.net/Pages/StereoKit/Mesh/Quad.html

§Examples
use stereokit_rust::mesh::Mesh;

// Get the mesh
let mesh = Mesh::screen_quad();
assert_eq!(mesh.get_id(), "default/mesh_screen_quad");
Source

pub fn sphere() -> Self

A sphere mesh with a diameter of 1. This is equivalent to Mesh.GenerateSphere(1,4). https://stereokit.net/Pages/StereoKit/Mesh/Sphere.html

§Examples
use stereokit_rust::mesh::Mesh;

// Get the mesh
let mesh = Mesh::sphere();
assert_eq!(mesh.get_id(), "default/mesh_sphere");
Source

pub fn left_hand() -> Self

A clone mesh of the left hand https://stereokit.net/Pages/StereoKit/Mesh.html

§Examples
use stereokit_rust::mesh::Mesh;

// Get the mesh
let mesh = Mesh::left_hand();
assert_eq!(mesh.get_id(), "default/mesh_lefthand");
screenshot
Source

pub fn right_hand() -> Self

A clone mesh of the right hand https://stereokit.net/Pages/StereoKit/Mesh.html

§Examples
use stereokit_rust::mesh::Mesh;

// Get the mesh
let mesh = Mesh::right_hand();
assert_eq!(mesh.get_id(), "default/mesh_righthand");

Trait Implementations§

Source§

impl AsRef<Mesh> for Mesh

Source§

fn as_ref(&self) -> &Mesh

Converts this type into a shared reference of the (usually inferred) input type.
Source§

impl Debug for Mesh

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for Mesh

Source§

fn default() -> Self

Creates an empty Mesh asset. Use SetVerts and SetInds to add data to it! https://stereokit.net/Pages/StereoKit/Mesh/Mesh.html

see also: Vertex Mesh::new

Source§

impl Drop for Mesh

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

impl IAsset for Mesh

Source§

fn get_id(&self) -> &str

gets the unique identifier of this asset resource! This can be helpful for debugging, managing your assets, or finding them later on! https://stereokit.net/Pages/StereoKit/IAsset/Id.html
Source§

impl PartialEq for Mesh

Source§

fn eq(&self, other: &Mesh) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl StructuralPartialEq for Mesh

Auto Trait Implementations§

§

impl Freeze for Mesh

§

impl RefUnwindSafe for Mesh

§

impl !Send for Mesh

§

impl !Sync for Mesh

§

impl Unpin for Mesh

§

impl UnwindSafe for Mesh

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more