tiny.geometry.Mesh
Defined in tiny.geometry.
A borrowed triangle list: triangle i joins the positions named by indices[3 i .. 3 i + 3].
API (12)
Actions
Public operations.
bounds: The box around every triangle, empty for a mesh with none.isWellFormed: Whether the index list names whole triangles over existing, finite positions, withinmax_triangles.overlapCapsule: The triangles the capsule touches, lowest indices first, intoout.overlapSphere: The triangles the sphere touches, lowest indices first, intoout.raycast: The nearest triangle the ray meets withtin[t_min, t_max].raycastAny: Whether the ray meets any triangle withtin[t_min, t_max].sweepCapsule: The first triangle the capsule touches as it moves bydisplacement.sweepSphere: The first triangle the sphere touches as it moves bydisplacement.triangletriangleCount
Fields and members
Public fields and members.
Source
Source: lib/geometry/src/mesh.zig:27
zig
/// A borrowed triangle list: triangle `i` joins the positions named by/// `indices[3 i .. 3 i + 3]`.pub const Mesh = struct { positions: []const Vec3, indices: []const u32, pub fn triangleCount(mesh: Mesh) usize { assert(mesh.indices.len % 3 == 0); return mesh.indices.len / 3; } /// Whether the index list names whole triangles over existing, finite /// positions, within `max_triangles`. pub fn isWellFormed(mesh: Mesh) bool { if (mesh.indices.len % 3 != 0) return false; if (mesh.indices.len / 3 > max_triangles) return false; for (mesh.indices) |index| { if (index >= mesh.positions.len) return false; } for (mesh.positions) |p| { if (!std.math.isFinite(p.x) or !std.math.isFinite(p.y) or !std.math.isFinite(p.z)) return false; } return true; } pub fn triangle(mesh: Mesh, index: usize) Triangle { const base = index * 3; assert(base + 3 <= mesh.indices.len); return .{ .a = mesh.positions[mesh.indices[base + 0]], .b = mesh.positions[mesh.indices[base + 1]], .c = mesh.positions[mesh.indices[base + 2]], }; } /// The box around every triangle, empty for a mesh with none. pub fn bounds(mesh: Mesh) Aabb { var box = Aabb.empty; for (mesh.indices) |index| box = box.joinPoint(mesh.positions[index]); return box; } /// The nearest triangle the ray meets with `t` in `[t_min, t_max]`. pub fn raycast(mesh: Mesh, ray: Ray, t_min: f32, t_max: f32) ?RayHit { assert(t_min <= t_max); var best: ?RayHit = null; for (0..mesh.triangleCount()) |index| { const hit = intersect.rayTriangle(ray, mesh.triangle(index)) orelse continue; if (hit.t < t_min or hit.t > t_max) continue; if (best) |held| { if (hit.t >= held.t) continue; } best = .{ .t = hit.t, .u = hit.u, .v = hit.v, .triangle = @intCast(index) }; } return best; } /// Whether the ray meets any triangle with `t` in `[t_min, t_max]`. pub fn raycastAny(mesh: Mesh, ray: Ray, t_min: f32, t_max: f32) bool { assert(t_min <= t_max); for (0..mesh.triangleCount()) |index| { const hit = intersect.rayTriangle(ray, mesh.triangle(index)) orelse continue; if (hit.t >= t_min and hit.t <= t_max) return true; } return false; } /// The triangles the sphere touches, lowest indices first, into `out`. pub fn overlapSphere(mesh: Mesh, sphere: Sphere, out: []u32) Overlap { var count: usize = 0; for (0..mesh.triangleCount()) |index| { if (!intersect.sphereTriangle(sphere, mesh.triangle(index))) continue; if (count == out.len) return .{ .count = count, .complete = false }; out[count] = @intCast(index); count += 1; } return .{ .count = count, .complete = true }; } /// The triangles the capsule touches, lowest indices first, into `out`. pub fn overlapCapsule(mesh: Mesh, capsule: Capsule, out: []u32) Overlap { var count: usize = 0; for (0..mesh.triangleCount()) |index| { if (!intersect.capsuleTriangle(capsule, mesh.triangle(index))) continue; if (count == out.len) return .{ .count = count, .complete = false }; out[count] = @intCast(index); count += 1; } return .{ .count = count, .complete = true }; } /// The first triangle the sphere touches as it moves by `displacement`. pub fn sweepSphere(mesh: Mesh, sphere: Sphere, displacement: Vec3) ?SweepHit { var best: ?SweepHit = null; for (0..mesh.triangleCount()) |index| { const hit = sweep.sphereTriangle(sphere, displacement, mesh.triangle(index)) orelse continue; if (best) |held| { if (hit.t >= held.t) continue; } best = .{ .t = hit.t, .point = hit.point, .normal = hit.normal, .triangle = @intCast(index) }; } return best; } /// The first triangle the capsule touches as it moves by `displacement`. pub fn sweepCapsule(mesh: Mesh, capsule: Capsule, displacement: Vec3) ?SweepHit { var best: ?SweepHit = null; for (0..mesh.triangleCount()) |index| { const hit = sweep.capsuleTriangle(capsule, displacement, mesh.triangle(index)) orelse continue; if (best) |held| { if (hit.t >= held.t) continue; } best = .{ .t = hit.t, .point = hit.point, .normal = hit.normal, .triangle = @intCast(index) }; } return best; }};Source: lib/geometry/src/root.zig:22
zig
pub const Mesh = mesh.Mesh;Audit
| Definitions | 11 |
|---|---|
| Public names | 11 |
| Members | 2 |
| Version | 26.7.0 |
| Revision | daab053ee433 |