zgltf upgrade
This commit is contained in:
parent
d738dd2260
commit
385dccd666
|
|
@ -1,3 +1,4 @@
|
|||
.zig-cache/
|
||||
build_runner.zig
|
||||
.DS_Store
|
||||
zig-out
|
||||
|
|
|
|||
|
|
@ -9,11 +9,13 @@ Note: It's not as complete as the glTF specification yet, but because it's strai
|
|||
|
||||
If you would like to contribute, don't hesitate! :)
|
||||
|
||||
Note: The main branch is for the latest Zig release (0.15.1).
|
||||
|
||||
## Examples
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
const Gltf = @import("zgltf");
|
||||
const Gltf = @import("zgltf").Gltf;
|
||||
|
||||
const allocator = std.heap.page_allocator;
|
||||
const print = std.debug.print;
|
||||
|
|
@ -29,7 +31,7 @@ pub fn main() void {
|
|||
);
|
||||
defer allocator.free(buf);
|
||||
|
||||
var gltf = Self.init(allocator);
|
||||
var gltf = Gltf.init(allocator);
|
||||
defer gltf.deinit();
|
||||
|
||||
try gltf.parse(buf);
|
||||
|
|
@ -42,7 +44,7 @@ pub fn main() void {
|
|||
;
|
||||
|
||||
print(message, .{
|
||||
node.name,
|
||||
node.name orelse "Unnamed Node",
|
||||
node.children.items.len,
|
||||
node.skin != null,
|
||||
});
|
||||
|
|
@ -122,11 +124,15 @@ for (primitive.attributes.items) |attribute| {
|
|||
|
||||
## Install
|
||||
|
||||
Note: **Zig 0.11.x is required.**
|
||||
Note: **Zig 0.15.1 is required.**
|
||||
|
||||
```sh
|
||||
zig fetch --save git+https://github.com/kooparse/zgltf
|
||||
```
|
||||
|
||||
```zig
|
||||
const zgltf = @import("path-to-zgltf/build.zig");
|
||||
exe.addModule("zgltf", zgltf.module(b));
|
||||
const zgltf = b.dependency("zgltf", .{});
|
||||
exe.addModule("zgltf", zgltf.module("zgltf"));
|
||||
```
|
||||
|
||||
## Features
|
||||
|
|
|
|||
|
|
@ -3,19 +3,20 @@ const std = @import("std");
|
|||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
const static_build = b.option(bool, "static_build", "builds backlog dependencies for static linking") orelse false;
|
||||
_ = static_build;
|
||||
|
||||
_ = b.addModule("zgltf", .{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
});
|
||||
|
||||
var tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
const mod = b.addModule("zgltf", .{
|
||||
.root_source_file = b.path("src/zgltf.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const tests = b.addTest(.{
|
||||
.root_module = mod,
|
||||
});
|
||||
b.installArtifact(tests);
|
||||
|
||||
var run_tests = b.addRunArtifact(tests);
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&tests.step);
|
||||
test_step.dependOn(&run_tests.step);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
.{
|
||||
.name = .zgltf,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.11.0",
|
||||
.fingerprint = 0x7dfe8a1202907eb1,
|
||||
.minimum_zig_version = "0.15.1",
|
||||
.dependencies = .{},
|
||||
.paths = .{
|
||||
".github",
|
||||
".gitignore",
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
|
|
@ -11,5 +14,4 @@
|
|||
"LICENSE",
|
||||
"README.md",
|
||||
},
|
||||
.fingerprint = 0x7dfe8a12f6d6c124,
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +1,8 @@
|
|||
const std = @import("std");
|
||||
const Gltf = @import("main.zig");
|
||||
const Gltf = @import("Gltf.zig");
|
||||
const pi = std.math.pi;
|
||||
const ArrayList = std.ArrayList;
|
||||
const panic = std.debug.panic;
|
||||
const json = @import("std").json;
|
||||
|
||||
/// Index of element in data arrays.
|
||||
pub const Index = usize;
|
||||
|
|
@ -20,8 +20,7 @@ pub const Index = usize;
|
|||
/// an animation.channel.target), matrix must not be present.
|
||||
pub const Node = struct {
|
||||
/// The user-defined name of this object.
|
||||
/// Default to `Node_{index}`.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// The index of the node's parent.
|
||||
/// A node is called a root node when it doesn’t have a parent.
|
||||
parent: ?Index = null,
|
||||
|
|
@ -32,7 +31,7 @@ pub const Node = struct {
|
|||
/// The index of the skin referenced by this node.
|
||||
skin: ?Index = null,
|
||||
/// The indices of this node’s children.
|
||||
children: ArrayList(Index),
|
||||
children: []Index = &[_]Index{},
|
||||
/// A floating-point 4x4 transformation matrix stored in column-major order.
|
||||
matrix: ?[16]f32 = null,
|
||||
/// The node’s unit quaternion rotation in the order (x, y, z, w),
|
||||
|
|
@ -49,6 +48,8 @@ pub const Node = struct {
|
|||
weights: ?[]usize = null,
|
||||
///The index of the light referenced by this node.
|
||||
light: ?Index = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A buffer points to binary geometry, animation, or skins.
|
||||
|
|
@ -59,6 +60,8 @@ pub const Buffer = struct {
|
|||
uri: ?[]const u8 = null,
|
||||
/// The length of the buffer in bytes.
|
||||
byte_length: usize,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A view into a buffer generally representing a subset of the buffer.
|
||||
|
|
@ -74,6 +77,8 @@ pub const BufferView = struct {
|
|||
/// The hint representing the intended GPU buffer type
|
||||
/// to use with this buffer view.
|
||||
target: ?Target = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A typed view into a buffer view that contains raw binary data.
|
||||
|
|
@ -86,12 +91,12 @@ pub const Accessor = struct {
|
|||
component_type: ComponentType,
|
||||
/// Specifies if the accessor’s elements are scalars, vectors, or matrices.
|
||||
type: AccessorType,
|
||||
/// Computed stride: @sizeOf(component_type) * type.
|
||||
stride: usize,
|
||||
/// The number of elements referenced by this accessor.
|
||||
count: i32,
|
||||
count: usize,
|
||||
/// Specifies whether integer data values are normalized before usage.
|
||||
normalized: bool = false,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
|
||||
pub fn iterator(
|
||||
accessor: Accessor,
|
||||
|
|
@ -99,14 +104,7 @@ pub const Accessor = struct {
|
|||
gltf: *const Gltf,
|
||||
binary: []align(4) const u8,
|
||||
) AccessorIterator(T) {
|
||||
if (switch (accessor.component_type) {
|
||||
.byte => T != i8,
|
||||
.unsigned_byte => T != u8,
|
||||
.short => T != i16,
|
||||
.unsigned_short => T != u16,
|
||||
.unsigned_integer => T != u32,
|
||||
.float => T != f32,
|
||||
}) {
|
||||
if (ComponentType.fromType(T) != accessor.component_type) {
|
||||
panic(
|
||||
"Mismatch between gltf component '{}' and given type '{}'.",
|
||||
.{ accessor.component_type, T },
|
||||
|
|
@ -117,30 +115,14 @@ pub const Accessor = struct {
|
|||
panic("Accessors without buffer_view are not supported yet.", .{});
|
||||
}
|
||||
|
||||
const buffer_view = gltf.data.buffer_views.items[accessor.buffer_view.?];
|
||||
const buffer_view = gltf.data.buffer_views[accessor.buffer_view.?];
|
||||
|
||||
const comp_size = @sizeOf(T);
|
||||
const offset = (accessor.byte_offset + buffer_view.byte_offset) / comp_size;
|
||||
|
||||
const stride = blk: {
|
||||
if (buffer_view.byte_stride) |byte_stride| {
|
||||
break :blk byte_stride / comp_size;
|
||||
} else {
|
||||
break :blk accessor.stride / comp_size;
|
||||
}
|
||||
};
|
||||
const offset = (accessor.byte_offset + buffer_view.byte_offset) / @sizeOf(T);
|
||||
const datum_count: usize = accessor.type.componentCount();
|
||||
// When byte_stride is null, data is tightly packed, so stride = datum_count
|
||||
const stride = if (buffer_view.byte_stride) |byte_stride| (byte_stride / @sizeOf(T)) else datum_count;
|
||||
|
||||
const total_count: usize = @intCast(accessor.count);
|
||||
const datum_count: usize = switch (accessor.type) {
|
||||
.scalar => 1,
|
||||
.vec2 => 2,
|
||||
.vec3 => 3,
|
||||
.vec4 => 4,
|
||||
.mat4x4 => 16,
|
||||
else => {
|
||||
panic("Accessor type '{}' not implemented.", .{accessor.type});
|
||||
},
|
||||
};
|
||||
|
||||
const data: [*]const T = @ptrCast(@alignCast(binary.ptr));
|
||||
|
||||
|
|
@ -191,22 +173,26 @@ pub fn AccessorIterator(comptime T: type) type {
|
|||
/// The root nodes of a scene.
|
||||
pub const Scene = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// The indices of each root node.
|
||||
nodes: ?ArrayList(Index) = null,
|
||||
nodes: ?[]Index = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Joints and matrices defining a skin.
|
||||
pub const Skin = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// The index of the accessor containing the floating-point
|
||||
/// 4x4 inverse-bind matrices.
|
||||
inverse_bind_matrices: ?Index = null,
|
||||
/// The index of the node used as a skeleton root.
|
||||
skeleton: ?Index = null,
|
||||
/// Indices of skeleton nodes, used as joints in this skin.
|
||||
joints: ArrayList(Index),
|
||||
joints: []Index = &[_]Index{},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Reference to a texture.
|
||||
|
|
@ -260,7 +246,7 @@ pub const MetallicRoughness = struct {
|
|||
/// The material appearance of a primitive.
|
||||
pub const Material = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// A set of parameter values that are used to define
|
||||
/// the metallic-roughness material model
|
||||
/// from Physically Based Rendering methodology.
|
||||
|
|
@ -309,11 +295,13 @@ pub const Material = struct {
|
|||
/// The strength of the dispersion effect.
|
||||
/// Note: from khr_materials_dispersion extension.
|
||||
dispersion: f32 = 0.0,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// The material’s alpha rendering mode enumeration specifying
|
||||
/// the interpretation of the alpha value of the base color.
|
||||
const AlphaMode = enum {
|
||||
pub const AlphaMode = enum {
|
||||
/// The alpha value is ignored, and the rendered output is fully opaque.
|
||||
@"opaque",
|
||||
/// The rendered output is either fully opaque or fully transparent
|
||||
|
|
@ -337,11 +325,22 @@ pub const Texture = struct {
|
|||
/// When undefined, an extension or other mechanism should supply
|
||||
/// an alternate texture source, otherwise behavior is undefined.
|
||||
source: ?Index = null,
|
||||
/// Extension object with extension-specific objects.
|
||||
extensions: struct {
|
||||
EXT_texture_webp: ?struct {
|
||||
/// The index of the WebP image used by this texture.
|
||||
source: Index,
|
||||
} = null,
|
||||
} = .{},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Image data used to create a texture.
|
||||
/// Image may be referenced by an uri or a buffer view index.
|
||||
pub const Image = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: ?[]const u8 = null,
|
||||
/// The URI (or IRI) of the image.
|
||||
uri: ?[]const u8 = null,
|
||||
/// The image’s media type.
|
||||
|
|
@ -353,6 +352,8 @@ pub const Image = struct {
|
|||
/// The image's data calculated from the buffer/buffer_view.
|
||||
/// Only there if glb file is loaded.
|
||||
data: ?[]const u8 = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
pub const WrapMode = enum(u32) {
|
||||
|
|
@ -385,6 +386,8 @@ pub const TextureSampler = struct {
|
|||
wrap_s: WrapMode = .repeat,
|
||||
/// T (U) wrapping mode.
|
||||
wrap_t: WrapMode = .repeat,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Values are Accessor's index.
|
||||
|
|
@ -406,6 +409,18 @@ pub const AccessorType = enum {
|
|||
mat2x2,
|
||||
mat3x3,
|
||||
mat4x4,
|
||||
|
||||
pub fn componentCount(self: AccessorType) usize {
|
||||
return switch (self) {
|
||||
.scalar => 1,
|
||||
.vec2 => 2,
|
||||
.vec3 => 3,
|
||||
.vec4 => 4,
|
||||
.mat2x2 => 4,
|
||||
.mat3x3 => 9,
|
||||
.mat4x4 => 16,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Enum values from GLTF 2.0 spec.
|
||||
|
|
@ -416,18 +431,35 @@ pub const Target = enum(u32) {
|
|||
|
||||
/// Enum values from GLTF 2.0 spec.
|
||||
pub const ComponentType = enum(u32) {
|
||||
/// i8.
|
||||
byte = 5120,
|
||||
/// u8.
|
||||
unsigned_byte = 5121,
|
||||
/// i16.
|
||||
short = 5122,
|
||||
/// u16.
|
||||
unsigned_short = 5123,
|
||||
/// u32.
|
||||
unsigned_integer = 5125,
|
||||
/// f32.
|
||||
float = 5126,
|
||||
|
||||
pub fn fromType(T: type) ComponentType {
|
||||
return switch (T) {
|
||||
i8 => .byte,
|
||||
u8 => .unsigned_byte,
|
||||
i16 => .short,
|
||||
u16 => .unsigned_short,
|
||||
u32 => .unsigned_integer,
|
||||
f32 => .float,
|
||||
else => @compileError("invalid type " ++ @typeName(T) ++ " for ComponentType.fromType"),
|
||||
};
|
||||
}
|
||||
|
||||
pub fn byteSize(self: ComponentType) usize {
|
||||
return switch (self) {
|
||||
.byte => @sizeOf(i8),
|
||||
.unsigned_byte => @sizeOf(u8),
|
||||
.short => @sizeOf(i16),
|
||||
.unsigned_short => @sizeOf(u16),
|
||||
.unsigned_integer => @sizeOf(u32),
|
||||
.float => @sizeOf(f32),
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// The topology type of primitives to render.
|
||||
|
|
@ -471,6 +503,8 @@ pub const Channel = struct {
|
|||
/// of the Morph Targets it instantiates.
|
||||
property: TargetProperty,
|
||||
},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Interpolation algorithm.
|
||||
|
|
@ -496,41 +530,49 @@ pub const AnimationSampler = struct {
|
|||
output: Index,
|
||||
/// Interpolation algorithm.
|
||||
interpolation: Interpolation = .linear,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A keyframe animation.
|
||||
pub const Animation = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// An array of animation channels.
|
||||
/// An animation channel combines an animation sampler with a target
|
||||
/// property being animated.
|
||||
/// Different channels of the same animation must not have the same targets.
|
||||
channels: ArrayList(Channel),
|
||||
channels: []Channel = &[_]Channel{},
|
||||
/// An array of animation samplers.
|
||||
/// An animation sampler combines timestamps with a sequence of output
|
||||
/// values and defines an interpolation algorithm.
|
||||
samplers: ArrayList(AnimationSampler),
|
||||
samplers: []AnimationSampler = &[_]AnimationSampler{},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Geometry to be rendered with the given material.
|
||||
pub const Primitive = struct {
|
||||
attributes: ArrayList(Attribute),
|
||||
attributes: []Attribute = &[_]Attribute{},
|
||||
/// The topology type of primitives to render.
|
||||
mode: Mode = .triangles,
|
||||
/// The index of the accessor that contains the vertex indices.
|
||||
indices: ?Index = null,
|
||||
/// The index of the material to apply to this primitive when rendering.
|
||||
material: ?Index = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A set of primitives to be rendered.
|
||||
/// Its global transform is defined by a node that references it.
|
||||
pub const Mesh = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// An array of primitives, each defining geometry to be rendered.
|
||||
primitives: ArrayList(Primitive),
|
||||
primitives: []Primitive = &[_]Primitive{},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Metadata about the glTF asset.
|
||||
|
|
@ -541,6 +583,8 @@ pub const Asset = struct {
|
|||
generator: ?[]const u8 = null,
|
||||
/// A copyright message suitable for display to credit the content creator.
|
||||
copyright: ?[]const u8 = null,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// A camera’s projection.
|
||||
|
|
@ -580,11 +624,13 @@ pub const Camera = struct {
|
|||
znear: f32,
|
||||
};
|
||||
|
||||
name: []const u8,
|
||||
name: ?[]const u8 = null,
|
||||
type: union(enum) {
|
||||
perspective: Perspective,
|
||||
orthographic: Orthographic,
|
||||
},
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
/// Specifies the light type.
|
||||
|
|
@ -614,7 +660,7 @@ pub const LightType = enum {
|
|||
|
||||
/// A directional, point or spot light.
|
||||
pub const Light = struct {
|
||||
name: ?[]const u8,
|
||||
name: ?[]const u8 = null,
|
||||
/// Color of the light source.
|
||||
color: [3]f32 = .{ 1, 1, 1 },
|
||||
/// Intensity of the light source. `point` and `spot` lights use luminous intensity in candela (lm/sr)
|
||||
|
|
@ -626,6 +672,8 @@ pub const Light = struct {
|
|||
spot: ?LightSpot,
|
||||
/// A distance cutoff at which the light's intensity may be considered to have reached zero.
|
||||
range: f32,
|
||||
/// Any extra, custom attributes.
|
||||
extras: ?json.ObjectMap = null,
|
||||
};
|
||||
|
||||
pub const LightSpot = struct {
|
||||
|
|
|
|||
Loading…
Reference in New Issue