class Eagle::Mesh

Overview

3D geometry: vertices with positions, normals, texture coordinates and colors, plus triangle indices.

Use the built-in primitives (.cube, .sphere, .plane, .cylinder, .capsule, .torus and more), load an OBJ file, or build your own vertex by vertex. Show a mesh with a MeshInstance3D.

floor = Mesh.plane(20, 20, uv_scale: 10)
rock = Mesh.sphere(1, segments: 8, rings: 6).flat_shaded # low-poly look
ship = Mesh.load("res://models/ship.obj")

tri = Mesh.new("triangle")
a = tri.add_vertex(v3(0, 1, 0), c: Color::RED)
b = tri.add_vertex(v3(-1, 0, 0), c: Color::GREEN)
c = tri.add_vertex(v3(1, 0, 0), c: Color::BLUE)
tri.add_triangle(a, b, c)
tri.compute_normals

Meshes upload to the GPU on first draw, and again after you change them.

Defined in:

eagle/graphics3d/mesh.cr

Constructors

Instance Method Summary

Constructor Detail

def self.axes(length : Number = 1) : Mesh #

Red, green and blue lines along X, Y and Z, for orientation while debugging.


def self.box(w : Number, h : Number, d : Number, color : Color = Color::WHITE) : Mesh #

A box of w by h by d.


def self.capsule(radius : Number = 0.5, height : Number = 1, segments : Int32 = 16, color : Color = Color::WHITE) : Mesh #

A capsule: a cylinder with rounded ends, the usual character shape.


def self.cone(radius : Number = 0.5, height : Number = 1, segments : Int32 = 24, color : Color = Color::WHITE) : Mesh #

A cone pointing up.


def self.cube(size : Number = 1, color : Color = Color::WHITE) : Mesh #

A cube with sides of size.


def self.cylinder(radius : Number = 0.5, height : Number = 1, segments : Int32 = 24, color : Color = Color::WHITE, top_radius : Number | Nil = nil) : Mesh #

A capped cylinder. Set top_radius for a tapered shape.


def self.decode(text : String, hint : String = "") : Mesh #

Parses OBJ text into a mesh.


def self.grid(size : Number = 10, divisions : Int32 = 10, color : Color = Color.gray(0.4)) : Mesh #

A line grid on the ground, drawn as lines. Use an unlit material.


def self.load(path : String) : Mesh #

Loads an OBJ file through the asset cache.


def self.new(name : String = "mesh") #

Creates an empty mesh.


def self.plane(w : Number = 1, d : Number = 1, subdivisions : Int32 = 1, color : Color = Color::WHITE, uv_scale : Number = 1) : Mesh #

A flat rectangle on the ground (the XZ plane), facing up. uv_scale repeats the texture.


def self.quad(w : Number = 1, h : Number = 1, color : Color = Color::WHITE) : Mesh #

--- primitives ---------------------------------------------------------- A flat rectangle in the XY plane, facing +Z.


def self.sphere(radius : Number = 0.5, segments : Int32 = 24, rings : Int32 = 16, color : Color = Color::WHITE) : Mesh #

A UV sphere. More segments and rings make it smoother.


def self.torus(radius : Number = 1, tube : Number = 0.3, segments : Int32 = 32, rings : Int32 = 16, color : Color = Color::WHITE) : Mesh #

A torus (donut).


Instance Method Detail

def add_quad(a : UInt32, b : UInt32, c : UInt32, d : UInt32) : Nil #

Adds a quad as two triangles.


def add_triangle(a : UInt32, b : UInt32, c : UInt32) : Nil #

Adds a triangle from three vertex indices, counter-clockwise when seen from the front.


def add_vertex(p : Vec3, n : Vec3 = Vec3::UP, uv : Vec2 = Vec2::ZERO, c : Color = Color::WHITE) : UInt32 #

Adds a vertex and returns its index.


def append(other : Mesh, mat : Mat4 | Nil = nil) : self #

Appends another mesh's geometry, optionally transformed, to merge static props into one draw call.


def bounds : AABB #

The bounding box of every vertex.


def clear : Nil #

Removes all geometry.


def color!(c : Color) : self #

Sets every vertex color. Returns self.


def colors : Array(Eagle::Color) #

Vertex colors, multiplied with the material.


def compute_normals : self #

Recomputes smooth normals from the triangles. Returns self.


def dispose : Nil #

Frees the GPU buffers.


def draw : Nil #

Draws the mesh with whatever shader is bound. Normally MeshInstance3D and the renderer do this.


def flat_shaded : Mesh #

A copy with separate vertices per face, so each triangle is lit flat. Gives a faceted, low-poly look.


def indices : Array(UInt32) #

Triangle indices, three per triangle.


def name : String #

A label for debugging.


def normals : Array(Eagle::Vec3) #

Vertex normals, used for lighting.


def positions : Array(Eagle::Vec3) #

Vertex positions.


def primitive : GPU::Primitive #

How indices are drawn: triangles, or lines for grids and wireframes.


def primitive=(primitive : GPU::Primitive) #

How indices are drawn: triangles, or lines for grids and wireframes.


def transform!(mat : Mat4) : self #

Transforms every vertex in place. Returns self.


def triangle_count : Int32 #

Number of triangles.


def upload : Nil #

Sends the geometry to the GPU. It happens automatically before drawing.


def uvs : Array(Eagle::Vec2) #

Texture coordinates.


def vertex_count : Int32 #

Number of vertices.