tiny.rig.skin
Defined in tiny.rig.
Rigid skinning: every vertex follows exactly one joint.
API (3)
Actions
Public operations.
bindPalette: Each joint's current world transform composed with its inverse bind transform.inverseBind: The inverse of each rest world transform, for vertices bound in the rest pose.skin: Each position moved by its joint's palette entry.
Source
Source: fun/rig/src/root.zig:25
zig
pub const skin = @import("skin.zig");Source: fun/rig/src/skin.zig
zig
//! Rigid skinning: every vertex follows exactly one joint.//!//! A palette maps each joint's vertex space to world space. Vertices//! authored in a joint's own space, as a part hung on the joint is, use//! the joint's world transform as its palette entry. Vertices authored in//! the rest pose's world space, as a bound mesh is, use the world//! transform composed with the inverse of the rest world transform, which//! `bindPalette` computes.const std = @import("std");const linear = @import("linear");const skeleton = @import("skeleton.zig");const transform = @import("transform.zig");const assert = std.debug.assert;const Joint = skeleton.Joint;const Transform = transform.Transform;const Vec3 = linear.Vec3;/// The inverse of each rest world transform, for vertices bound in the/// rest pose.pub fn inverseBind(rest_world: []const Transform, out: []Transform) void { assert(out.len == rest_world.len); for (rest_world, out) |world, *inverse| inverse.* = world.inverse();}/// Each joint's current world transform composed with its inverse bind/// transform.pub fn bindPalette( world: []const Transform, inverse_bind: []const Transform, out: []Transform,) void { assert(inverse_bind.len == world.len); assert(out.len == world.len); for (world, inverse_bind, out) |joint_world, joint_inverse, *entry| { entry.* = Transform.compose(joint_world, joint_inverse); }}/// Each position moved by its joint's palette entry.pub fn skin( palette: []const Transform, joints: []const Joint, positions: []const Vec3, out: []Vec3,) void { assert(joints.len == positions.len); assert(out.len == positions.len); for (joints, positions, out) |joint, position, *moved| { assert(joint < palette.len); moved.* = palette[joint].applyPoint(position); }}test "a joint-space vertex follows its joint" { const rest = [_]Transform{ .{}, .{ .translation = .{ .y = 2 } }, }; const parents = [_]Joint{ skeleton.none, 0 }; var world: [2]Transform = undefined; skeleton.forwardParents(&parents, &rest, &world); var out: [2]Vec3 = undefined; skin(&world, &.{ 0, 1 }, &.{ .{ .x = 1 }, .{ .x = 1 } }, &out); try std.testing.expectEqual(Vec3{ .x = 1 }, out[0]); try std.testing.expectEqual(Vec3{ .x = 1, .y = 2 }, out[1]);}Audit
| Definitions | 4 |
|---|---|
| Public names | 4 |
| Members | 0 |
| Version | 26.7.0 |
| Revision | daab053ee433 |