The shader compilation story kicks ass now
This commit is contained in:
parent
806c7942e8
commit
341e69b32e
|
|
@ -21,6 +21,7 @@ const engineDepList = [_][]const u8{
|
|||
"core",
|
||||
"papyrus",
|
||||
"platform",
|
||||
"rend",
|
||||
"physics",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
.papyrus = .{ .path = "engine/papyrus" },
|
||||
.physics = .{ .path = "engine/physics" },
|
||||
.platform = .{ .path = "engine/platform" },
|
||||
.rend = .{.path = "engine/rend" },
|
||||
.SpirvReflect = .{ .path = "lib/spirv-reflect-zig" },
|
||||
.ozz = .{ .path = "lib/ozz" },
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
pub const core = @import("core");
|
||||
pub const platform = @import("platform");
|
||||
pub const assets = @import("assets");
|
||||
pub const rend = @import("rend");
|
||||
pub const audio = @import("audio");
|
||||
// pub const graphics = @import("graphics");
|
||||
// pub const vkImgui = @import("vkImgui");
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ pub const list = [_][]const u8{
|
|||
"assets",
|
||||
"audio",
|
||||
"physics",
|
||||
|
||||
"rend",
|
||||
// to be implemented
|
||||
// "graphics",
|
||||
// "ui",
|
||||
|
|
|
|||
|
|
@ -53,9 +53,8 @@ pub const PhysicsCharacter = struct {
|
|||
|
||||
const scene = self.entity.get(core.Scene).?;
|
||||
const p = self.character.getPosition();
|
||||
const position = .{ .x = p[0], .y = p[1], .z = p[2] };
|
||||
// core.debugSphere(position, 20, .{});
|
||||
scene.setPosition(position);
|
||||
scene.setPosition(.{ .x = p[0], .y = p[1], .z = p[2] });
|
||||
}
|
||||
|
||||
pub fn setVelocity(self: *@This(), v: core.Vectorf) void {
|
||||
|
|
|
|||
|
|
@ -1,14 +1,6 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
|
||||
// pub fn addLib(b: *std.Build, exe: *std.Build.Step.Compile, comptime packagePath: []const u8, cflags: []const []const u8) void {
|
||||
// _ = b;
|
||||
// _ = cflags;
|
||||
//
|
||||
// exe.addIncludePath(.{ .path = packagePath ++ "/lib" });
|
||||
// exe.addLibraryPath(.{ .path = packagePath ++ "/lib" });
|
||||
// }
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
"sdl3",
|
||||
|
|
@ -18,12 +10,6 @@ pub fn build(b: *std.Build) void {
|
|||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
// oh that is interesting. what I can do is have two
|
||||
// different modules specified here.
|
||||
//
|
||||
// one module for each graphics backend
|
||||
//
|
||||
// todo,
|
||||
const mod = b.addModule("platform", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
const std = @import("std");
|
||||
const sdl3 = @import("sdl3");
|
||||
|
||||
const dependencyList = [_][]const u8{
|
||||
"core",
|
||||
"sdl3",
|
||||
"platform",
|
||||
"shaderTypes",
|
||||
"objLoader",
|
||||
"ozz",
|
||||
};
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const mod = b.addModule("rend", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("src/rend.zig"),
|
||||
});
|
||||
|
||||
for (dependencyList) |depName| {
|
||||
const dep = b.dependency(depName, .{ .target = target, .optimize = optimize });
|
||||
const dep_mod = dep.module(depName);
|
||||
mod.addImport(depName, dep_mod);
|
||||
|
||||
if (std.mem.eql(u8, depName, "ozz")) {
|
||||
mod.linkLibrary(dep.artifact("ozz_cpp"));
|
||||
}
|
||||
}
|
||||
|
||||
sdl3.shaderDefintion(b, mod, "../../lib/sdl3", optimize, "sample.vert", b.path("shaders/sample.vert.json"));
|
||||
|
||||
// ========== tests ==========
|
||||
const tests = b.addTest(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_source_file = b.path("tests/tests.zig"),
|
||||
});
|
||||
const test_step = b.step("test", "run unit tests for rend");
|
||||
|
||||
tests.root_module.addImport("platform", mod);
|
||||
const runArtifact = b.addRunArtifact(tests);
|
||||
test_step.dependOn(&runArtifact.step);
|
||||
b.installArtifact(tests);
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
.{
|
||||
.name = .rend,
|
||||
.version = "0.0.0",
|
||||
.dependencies = .{
|
||||
.core = .{ .path = "../core" },
|
||||
.assets = .{ .path = "../assets" },
|
||||
.platform = .{ .path = "../platform" },
|
||||
|
||||
.sdl3 = .{ .path = "../../lib/sdl3" },
|
||||
.ozz = .{ .path = "../../lib/ozz" },
|
||||
.shaderTypes = .{ .path = "../../lib/sdl3/shaderTypes" },
|
||||
.cgltf = .{ .path = "../../lib/cgltf" },
|
||||
.objLoader = .{ .path = "../../lib/objLoader" },
|
||||
},
|
||||
.paths = .{
|
||||
"",
|
||||
},
|
||||
.fingerprint = 0x1fcf5da860255f09,
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
const std = @import("std");
|
||||
const core = @import("core");
|
||||
const sample_vert = @import("sample.vert");
|
||||
|
||||
// controls glfw and general windowing
|
||||
// graphics depends on this one
|
||||
|
||||
pub const Module: core.ModuleDescription = .{
|
||||
.name = "rend",
|
||||
.enabledByDefault = true,
|
||||
};
|
||||
|
||||
pub fn start_module(comptime programSpec: anytype, args: anytype, allocator: std.mem.Allocator) !void {
|
||||
_ = args;
|
||||
_ = programSpec;
|
||||
_ = allocator;
|
||||
core.engine_log("starting up [REND] module...", .{});
|
||||
core.engine_log("sample_vert.Scene size = {d}", .{@sizeOf(sample_vert.Scene)});
|
||||
}
|
||||
|
||||
pub fn shutdown_module(allocator: std.mem.Allocator) void {
|
||||
_ = allocator;
|
||||
core.engine_log("shutting down [REND] module...", .{});
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
test "this does nothing" {}
|
||||
|
|
@ -24,6 +24,18 @@ pub fn addShaderDefinition(
|
|||
return module;
|
||||
}
|
||||
|
||||
pub fn shaderDefintion(
|
||||
b: *std.Build,
|
||||
module: *std.Build.Module,
|
||||
comptime sdl3Path: []const u8,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
shaderName: []const u8,
|
||||
jsonPath: std.Build.LazyPath,
|
||||
) void {
|
||||
const mod = addShaderDefinition(b, sdl3Path, optimize, shaderName, jsonPath);
|
||||
module.addImport(shaderName, mod);
|
||||
}
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
.zig-cache/
|
||||
build_runner.zig
|
||||
.DS_Store
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2022 Alexandre Chêne
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
|
@ -0,0 +1,162 @@
|
|||
# glTF parser for Zig codebase
|
||||
|
||||
This project is a glTF 2.0 parser written in Zig, aiming to replace the use of some C/C++ libraries. All glTF types are fully documented, so it comes nicely with IDE autocompletion, reducing
|
||||
back and forth with the [specification](https://www.khronos.org/registry/glTF/specs/2.0/glTF-2.0.html).
|
||||
|
||||
This library intends to mimic the glTF file structure in memory. Thereby it's designed around arrays and indexes instead of pointers as you may see in `cgltf` or other libraries. Also, it's the **user's responsibility** to load glTF files and their related binaries in memory.
|
||||
|
||||
Note: It's not as complete as the glTF specification yet, but because it's straightforward to add new parsed fields, we'll get new stuff incrementally and on-demand.
|
||||
|
||||
If you would like to contribute, don't hesitate! :)
|
||||
|
||||
## Examples
|
||||
|
||||
```zig
|
||||
const std = @import("std");
|
||||
const Gltf = @import("zgltf");
|
||||
|
||||
const allocator = std.heap.page_allocator;
|
||||
const print = std.debug.print;
|
||||
|
||||
pub fn main() void {
|
||||
const buffer = try std.fs.cwd().readFileAllocOptions(
|
||||
allocator,
|
||||
"test-samples/rigged_simple/RiggedSimple.gltf",
|
||||
512_000,
|
||||
null,
|
||||
4,
|
||||
null
|
||||
);
|
||||
defer allocator.free(buf);
|
||||
|
||||
var gltf = Self.init(allocator);
|
||||
defer gltf.deinit();
|
||||
|
||||
try gltf.parse(buf);
|
||||
|
||||
for (gltf.nodes.items) |node| {
|
||||
const message =
|
||||
\\\ Node's name: {s}
|
||||
\\\ Children count: {}
|
||||
\\\ Have skin: {}
|
||||
;
|
||||
|
||||
print(message, .{
|
||||
node.name,
|
||||
node.children.items.len,
|
||||
node.skin != null,
|
||||
});
|
||||
}
|
||||
|
||||
// Or use the debufPrint method.
|
||||
gltf.debugPrint();
|
||||
}
|
||||
```
|
||||
|
||||
Also you could easily load data from an `Accessor` with `getDataFromBufferView`:
|
||||
|
||||
```zig
|
||||
const gltf = Gltf.init(allocator);
|
||||
try gltf.parse(my_gltf_buf);
|
||||
|
||||
const bin = try std.fs.cwd().readFileAllocOptions(
|
||||
allocator,
|
||||
"test-samples/rigged_simple/RiggedSimple0.bin",
|
||||
5_000_000,
|
||||
null,
|
||||
4,
|
||||
null
|
||||
);
|
||||
defer allocator.free(buf);
|
||||
|
||||
var vertices = ArrayList(f32).init(allocator);
|
||||
defer vertices.deinit();
|
||||
|
||||
const mesh = gltf.data.meshes.items[0];
|
||||
for (mesh.primitives.items) |primitive| {
|
||||
for (primitive.attributes.items) |attribute| {
|
||||
switch (attribute) {
|
||||
// Accessor for mesh vertices:
|
||||
.position => |accessor_index| {
|
||||
const accessor = gltf.data.accessors.items[accessor_index];
|
||||
gltf.getDataFromBufferView(f32, &vertices, accessor, bin);
|
||||
},
|
||||
else => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
Also, there is an `iterator` method that helps you pull data from accessors:
|
||||
|
||||
```zig
|
||||
// ...
|
||||
for (primitive.attributes.items) |attribute| {
|
||||
switch (attribute) {
|
||||
.position => |idx| {
|
||||
const accessor = gltf.data.accessors.items[idx];
|
||||
var it = accessor.iterator(f32, &gltf, gltf.glb_binary.?);
|
||||
while (it.next()) |v| {
|
||||
try vertices.append(.{
|
||||
.pos = .{ v[0], v[1], v[2] },
|
||||
.normal = .{ 1, 0, 0 },
|
||||
.color = .{ 1, 1, 1, 1 },
|
||||
.uv_x = 0,
|
||||
.uv_y = 0,
|
||||
});
|
||||
}
|
||||
},
|
||||
.normal => |idx| {
|
||||
const accessor = gltf.data.accessors.items[idx];
|
||||
var it = accessor.iterator(f32, &gltf, gltf.glb_binary.?);
|
||||
var i: u32 = 0;
|
||||
while (it.next()) |n| : (i += 1) {
|
||||
vertices.items[initial_vertex + i].normal = .{ n[0], n[1], n[2] };
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Install
|
||||
|
||||
Note: **Zig 0.11.x is required.**
|
||||
|
||||
```zig
|
||||
const zgltf = @import("path-to-zgltf/build.zig");
|
||||
exe.addModule("zgltf", zgltf.module(b));
|
||||
```
|
||||
|
||||
## Features
|
||||
|
||||
- [x] glTF 2.0 json file
|
||||
- [x] Scenes
|
||||
- [x] Nodes
|
||||
- [x] Buffers/BufferViews
|
||||
- [x] Meshes
|
||||
- [x] Images
|
||||
- [x] Materials
|
||||
- [x] Animations
|
||||
- [x] Skins
|
||||
- [x] Cameras
|
||||
- [x] Parse `glb` files
|
||||
- [ ] Morth targets
|
||||
- [ ] Extras data
|
||||
- [ ] glTF writer
|
||||
|
||||
Also, we supports some glTF extensions:
|
||||
|
||||
- [x] khr_lights_punctual
|
||||
- [x] khr_materials_emissive_strength
|
||||
- [x] khr_materials_ior
|
||||
- [x] khr_materials_transmission
|
||||
- [x] khr_materials_volume
|
||||
- [x] khr_materials_dispersion
|
||||
|
||||
## Contributing to the project
|
||||
|
||||
Don’t be shy about shooting any questions you may have. If you are a beginner/junior, don’t hesitate, I will always encourage you. It’s a safe place here. Also, I would be very happy to receive any kind of pull requests, you will have (at least) some feedback/guidance rapidly.
|
||||
|
||||
Behind screens, there are human beings, living any sort of story. So be always kind and respectful, because we all sheer to learn new things.
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn build(b: *std.Build) void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
_ = b.addModule("zgltf", .{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
});
|
||||
|
||||
var tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const test_step = b.step("test", "Run tests");
|
||||
test_step.dependOn(&tests.step);
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
.{
|
||||
.name = .zgltf,
|
||||
.version = "0.1.0",
|
||||
.minimum_zig_version = "0.11.0",
|
||||
.dependencies = .{},
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
"src",
|
||||
"test-samples",
|
||||
"LICENSE",
|
||||
"README.md",
|
||||
},
|
||||
.fingerprint = 0x7dfe8a12f6d6c124,
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
//
|
||||
// Mostly taken from `zalgebra`. I didn't wanted to import the all library.
|
||||
//
|
||||
|
||||
pub const Mat4 = [4][4]f32;
|
||||
pub const Vec3 = [3]f32;
|
||||
pub const Quat = [4]f32;
|
||||
pub const identity = Mat4{
|
||||
.{ 1, 0, 0, 0 },
|
||||
.{ 0, 1, 0, 0 },
|
||||
.{ 0, 0, 1, 0 },
|
||||
.{ 0, 0, 0, 1 },
|
||||
};
|
||||
|
||||
/// Return 4x4 matrix from given all transform components; `translation`, `rotation` and `scale`.
|
||||
/// The final order is T * R * S.
|
||||
pub fn recompose(translation: Vec3, rotation: Quat, scale: Vec3) Mat4 {
|
||||
const t = blk: {
|
||||
var mat = identity;
|
||||
mat[3][0] = translation[0];
|
||||
mat[3][1] = translation[1];
|
||||
mat[3][2] = translation[2];
|
||||
|
||||
break :blk mat;
|
||||
};
|
||||
|
||||
const r = blk: {
|
||||
var result = identity;
|
||||
|
||||
const x = rotation[0];
|
||||
const y = rotation[1];
|
||||
const z = rotation[2];
|
||||
const w = rotation[3];
|
||||
|
||||
const xx = x * x;
|
||||
const yy = y * y;
|
||||
const zz = z * z;
|
||||
const xy = x * y;
|
||||
const xz = x * z;
|
||||
const yz = y * z;
|
||||
const wx = w * x;
|
||||
const wy = w * y;
|
||||
const wz = w * z;
|
||||
|
||||
result[0][0] = 1.0 - 2.0 * (yy + zz);
|
||||
result[0][1] = 2.0 * (xy + wz);
|
||||
result[0][2] = 2.0 * (xz - wy);
|
||||
result[0][3] = 0.0;
|
||||
|
||||
result[1][0] = 2.0 * (xy - wz);
|
||||
result[1][1] = 1.0 - 2.0 * (xx + zz);
|
||||
result[1][2] = 2.0 * (yz + wx);
|
||||
result[1][3] = 0.0;
|
||||
|
||||
result[2][0] = 2.0 * (xz + wy);
|
||||
result[2][1] = 2.0 * (yz - wx);
|
||||
result[2][2] = 1.0 - 2.0 * (xx + yy);
|
||||
result[2][3] = 0.0;
|
||||
|
||||
result[3][0] = 0.0;
|
||||
result[3][1] = 0.0;
|
||||
result[3][2] = 0.0;
|
||||
result[3][3] = 1.0;
|
||||
|
||||
break :blk result;
|
||||
};
|
||||
|
||||
const s = blk: {
|
||||
var mat = identity;
|
||||
mat[0][0] = scale[0];
|
||||
mat[1][1] = scale[1];
|
||||
mat[2][2] = scale[2];
|
||||
|
||||
break :blk mat;
|
||||
};
|
||||
|
||||
return mul(t, mul(r, s));
|
||||
}
|
||||
|
||||
/// Matrices' multiplication.
|
||||
/// Produce a new matrix from given two matrices.
|
||||
pub fn mul(left: Mat4, right: Mat4) Mat4 {
|
||||
var result = identity;
|
||||
|
||||
for (result, 0..) |_, column| {
|
||||
for (result[column], 0..) |_, row| {
|
||||
var sum: f32 = 0;
|
||||
var left_column: usize = 0;
|
||||
|
||||
while (left_column < 4) : (left_column += 1) {
|
||||
sum += left[left_column][row] * right[column][left_column];
|
||||
}
|
||||
|
||||
result[column][row] = sum;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,636 @@
|
|||
const std = @import("std");
|
||||
const Gltf = @import("main.zig");
|
||||
const pi = std.math.pi;
|
||||
const ArrayList = std.ArrayList;
|
||||
const panic = std.debug.panic;
|
||||
|
||||
/// Index of element in data arrays.
|
||||
pub const Index = usize;
|
||||
|
||||
/// A node in the node hierarchy.
|
||||
///
|
||||
/// When the node contains skin, all mesh.primitives must contain
|
||||
/// JOINTS_0 and WEIGHTS_0 attributes. A node may have either a matrix
|
||||
/// or any combination of translation/rotation/scale (TRS) properties.
|
||||
/// TRS properties are converted to matrices and postmultiplied in
|
||||
/// the T * R * S order to compose the transformation matrix.
|
||||
/// If none are provided, the transform is the identity.
|
||||
///
|
||||
/// When a node is targeted for animation (referenced by
|
||||
/// 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,
|
||||
/// The index of the node's parent.
|
||||
/// A node is called a root node when it doesn’t have a parent.
|
||||
parent: ?Index = null,
|
||||
/// The index of the mesh in this node.
|
||||
mesh: ?Index = null,
|
||||
/// The index of the camera referenced by this node.
|
||||
camera: ?Index = null,
|
||||
/// The index of the skin referenced by this node.
|
||||
skin: ?Index = null,
|
||||
/// The indices of this node’s children.
|
||||
children: ArrayList(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),
|
||||
/// where w is the scalar.
|
||||
rotation: [4]f32 = [_]f32{ 0, 0, 0, 1 },
|
||||
/// The node’s non-uniform scale, given as the scaling factors
|
||||
/// along the x, y, and z axes.
|
||||
scale: [3]f32 = [_]f32{ 1, 1, 1 },
|
||||
/// The node’s translation along the x, y, and z axes.
|
||||
translation: [3]f32 = [_]f32{ 0, 0, 0 },
|
||||
/// The weights of the instantiated morph target.
|
||||
/// The number of array elements must match the number of morph targets
|
||||
/// of the referenced mesh. When defined, mesh mush also be defined.
|
||||
weights: ?[]usize = null,
|
||||
///The index of the light referenced by this node.
|
||||
light: ?Index = null,
|
||||
};
|
||||
|
||||
/// A buffer points to binary geometry, animation, or skins.
|
||||
pub const Buffer = struct {
|
||||
/// Relative paths are relative to the current glTF asset.
|
||||
/// It could contains a data:-URI instead of a path.
|
||||
/// Note: data-uri isn't implemented in this library.
|
||||
uri: ?[]const u8 = null,
|
||||
/// The length of the buffer in bytes.
|
||||
byte_length: usize,
|
||||
};
|
||||
|
||||
/// A view into a buffer generally representing a subset of the buffer.
|
||||
pub const BufferView = struct {
|
||||
/// The index of the buffer.
|
||||
buffer: Index,
|
||||
/// The length of the bufferView in bytes.
|
||||
byte_length: usize,
|
||||
/// The offset into the buffer in bytes.
|
||||
byte_offset: usize = 0,
|
||||
/// The stride, in bytes.
|
||||
byte_stride: ?usize = null,
|
||||
/// The hint representing the intended GPU buffer type
|
||||
/// to use with this buffer view.
|
||||
target: ?Target = null,
|
||||
};
|
||||
|
||||
/// A typed view into a buffer view that contains raw binary data.
|
||||
pub const Accessor = struct {
|
||||
/// The index of the bufferView.
|
||||
buffer_view: ?Index = null,
|
||||
/// The offset relative to the start of the buffer view in bytes.
|
||||
byte_offset: usize = 0,
|
||||
/// The datatype of the accessor’s components.
|
||||
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,
|
||||
/// Specifies whether integer data values are normalized before usage.
|
||||
normalized: bool = false,
|
||||
|
||||
pub fn iterator(
|
||||
accessor: Accessor,
|
||||
comptime T: type,
|
||||
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,
|
||||
}) {
|
||||
panic(
|
||||
"Mismatch between gltf component '{}' and given type '{}'.",
|
||||
.{ accessor.component_type, T },
|
||||
);
|
||||
}
|
||||
|
||||
if (accessor.buffer_view == null) {
|
||||
panic("Accessors without buffer_view are not supported yet.", .{});
|
||||
}
|
||||
|
||||
const buffer_view = gltf.data.buffer_views.items[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 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));
|
||||
|
||||
return .{
|
||||
.offset = offset,
|
||||
.stride = stride,
|
||||
.total_count = total_count,
|
||||
.datum_count = datum_count,
|
||||
.data = data,
|
||||
.current = 0,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
/// Iterator over accessor elements
|
||||
pub fn AccessorIterator(comptime T: type) type {
|
||||
return struct {
|
||||
offset: usize,
|
||||
stride: usize,
|
||||
total_count: usize,
|
||||
datum_count: usize,
|
||||
data: [*]const T,
|
||||
|
||||
current: usize,
|
||||
|
||||
/// Returns the next element of the accessor, or null if iteration is done.
|
||||
pub fn next(self: *@This()) ?[]const T {
|
||||
if (self.current >= self.total_count) return null;
|
||||
|
||||
const slice = (self.data + self.offset + self.current * self.stride)[0..self.datum_count];
|
||||
self.current += 1;
|
||||
return slice;
|
||||
}
|
||||
|
||||
/// Returns the next element of the accessor, or null if iteration is done. Does not change self.current.
|
||||
pub fn peek(self: *const @This()) ?[]const T {
|
||||
var copy = self.*;
|
||||
return copy.next();
|
||||
}
|
||||
|
||||
/// Resets the iterator to the first element
|
||||
pub fn reset(self: *@This()) void {
|
||||
self.current = 0;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// The root nodes of a scene.
|
||||
pub const Scene = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
/// The indices of each root node.
|
||||
nodes: ?ArrayList(Index) = null,
|
||||
};
|
||||
|
||||
/// Joints and matrices defining a skin.
|
||||
pub const Skin = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
/// 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),
|
||||
};
|
||||
|
||||
/// Reference to a texture.
|
||||
const TextureInfo = struct {
|
||||
/// The index of the texture.
|
||||
index: Index,
|
||||
/// The set index of texture’s TEXCOORD attribute
|
||||
/// used for texture coordinate mapping.
|
||||
texcoord: i32 = 0,
|
||||
};
|
||||
|
||||
/// Reference to a normal texture.
|
||||
const NormalTextureInfo = struct {
|
||||
/// The index of the texture.
|
||||
index: Index,
|
||||
/// The set index of texture’s TEXCOORD attribute
|
||||
/// used for texture coordinate mapping.
|
||||
texcoord: i32 = 0,
|
||||
/// The scalar parameter applied to each normal
|
||||
/// vector of the normal texture.
|
||||
scale: f32 = 1,
|
||||
};
|
||||
|
||||
/// Reference to an occlusion texture.
|
||||
const OcclusionTextureInfo = struct {
|
||||
/// The index of the texture.
|
||||
index: Index,
|
||||
/// The set index of texture’s TEXCOORD attribute
|
||||
/// used for texture coordinate mapping.
|
||||
texcoord: i32 = 0,
|
||||
/// A scalar multiplier controlling the amount of occlusion applied.
|
||||
strength: f32 = 1,
|
||||
};
|
||||
|
||||
/// A set of parameter values that are used to define
|
||||
/// the metallic-roughness material model
|
||||
/// from Physically-Based Rendering methodology.
|
||||
pub const MetallicRoughness = struct {
|
||||
/// The factors for the base color of the material.
|
||||
base_color_factor: [4]f32 = [_]f32{ 1, 1, 1, 1 },
|
||||
/// The base color texture.
|
||||
base_color_texture: ?TextureInfo = null,
|
||||
/// The factor for the metalness of the material.
|
||||
metallic_factor: f32 = 1,
|
||||
/// The factor for the roughness of the material.
|
||||
roughness_factor: f32 = 1,
|
||||
/// The metallic-roughness texture.
|
||||
metallic_roughness_texture: ?TextureInfo = null,
|
||||
};
|
||||
|
||||
/// The material appearance of a primitive.
|
||||
pub const Material = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
/// A set of parameter values that are used to define
|
||||
/// the metallic-roughness material model
|
||||
/// from Physically Based Rendering methodology.
|
||||
metallic_roughness: MetallicRoughness = .{},
|
||||
/// The tangent space normal texture.
|
||||
normal_texture: ?NormalTextureInfo = null,
|
||||
/// The occlusion texture.
|
||||
occlusion_texture: ?OcclusionTextureInfo = null,
|
||||
/// The emissive texture.
|
||||
emissive_texture: ?TextureInfo = null,
|
||||
/// The factors for the emissive color of the material.
|
||||
emissive_factor: [3]f32 = [_]f32{ 0, 0, 0 },
|
||||
/// The alpha rendering mode of the material.
|
||||
alpha_mode: AlphaMode = .@"opaque",
|
||||
/// The alpha cutoff value of the material.
|
||||
alpha_cutoff: f32 = 0.5,
|
||||
/// Specifies whether the material is double sided.
|
||||
/// If it's false, back-face culling is enabled.
|
||||
/// If it's true, back-face culling is disabled and
|
||||
/// double sided lighting is enabled.
|
||||
is_double_sided: bool = false,
|
||||
/// Emissive strength multiplier for the emissive factor/texture.
|
||||
/// Note: from khr_materials_emissive_strength extension.
|
||||
emissive_strength: f32 = 1.0,
|
||||
/// Index of refraction of material.
|
||||
/// Note: from khr_materials_ior extension.
|
||||
ior: f32 = 1.5,
|
||||
/// The factor for the transmission of the material.
|
||||
/// Note: from khr_materials_transmission extension.
|
||||
transmission_factor: f32 = 0.0,
|
||||
/// The transmission texture.
|
||||
/// Note: from khr_materials_transmission extension.
|
||||
transmission_texture: ?TextureInfo = null,
|
||||
/// The thickness of the volume beneath the surface.
|
||||
/// Note: from khr_materials_volume extension.
|
||||
thickness_factor: f32 = 0.0,
|
||||
/// A texture that defines the thickness, stored in the G channel.
|
||||
/// Note: from khr_materials_volume extension.
|
||||
thickness_texture: ?TextureInfo = null,
|
||||
/// Density of the medium.
|
||||
/// Note: from khr_materials_volume extension.
|
||||
attenuation_distance: f32 = std.math.inf(f32),
|
||||
/// The color that white light turns into due to absorption.
|
||||
/// Note: from khr_materials_volume extension.
|
||||
attenuation_color: [3]f32 = [_]f32{ 1, 1, 1 },
|
||||
/// The strength of the dispersion effect.
|
||||
/// Note: from khr_materials_dispersion extension.
|
||||
dispersion: f32 = 0.0,
|
||||
};
|
||||
|
||||
/// The material’s alpha rendering mode enumeration specifying
|
||||
/// the interpretation of the alpha value of the base color.
|
||||
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
|
||||
/// depending on the alpha value and the specified alpha_cutoff value.
|
||||
/// Note: The exact appearance of the edges may be subject to
|
||||
/// implementation-specific techniques such as “Alpha-to-Coverage”.
|
||||
mask,
|
||||
/// The alpha value is used to composite the source and destination areas.
|
||||
/// The rendered output is combined with the background using
|
||||
/// the normal painting operation (i.e. the Porter and Duff over operator).
|
||||
blend,
|
||||
};
|
||||
|
||||
/// A texture and its sampler.
|
||||
pub const Texture = struct {
|
||||
/// The index of the sampler used by this texture.
|
||||
/// When undefined, a sampler with repeat wrapping and
|
||||
/// auto filtering should be used.
|
||||
sampler: ?Index = null,
|
||||
/// The index of the image used by this texture.
|
||||
/// When undefined, an extension or other mechanism should supply
|
||||
/// an alternate texture source, otherwise behavior is undefined.
|
||||
source: ?Index = 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 URI (or IRI) of the image.
|
||||
uri: ?[]const u8 = null,
|
||||
/// The image’s media type.
|
||||
/// This field must be defined when bufferView is defined.
|
||||
mime_type: ?[]const u8 = null,
|
||||
/// The index of the bufferView that contains the image.
|
||||
/// Note: This field must not be defined when uri is defined.
|
||||
buffer_view: ?Index = null,
|
||||
/// The image's data calculated from the buffer/buffer_view.
|
||||
/// Only there if glb file is loaded.
|
||||
data: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
pub const WrapMode = enum(u32) {
|
||||
clamp_to_edge = 33071,
|
||||
mirrored_repeat = 33648,
|
||||
repeat = 10497,
|
||||
};
|
||||
|
||||
pub const MinFilter = enum(u32) {
|
||||
nearest = 9728,
|
||||
linear = 9729,
|
||||
nearest_mipmap_nearest = 9984,
|
||||
linear_mipmap_nearest = 9985,
|
||||
nearest_mipmap_linear = 9986,
|
||||
linear_mipmap_linear = 9987,
|
||||
};
|
||||
|
||||
pub const MagFilter = enum(u32) {
|
||||
nearest = 9728,
|
||||
linear = 9729,
|
||||
};
|
||||
|
||||
/// Texture sampler properties for filtering and wrapping modes.
|
||||
pub const TextureSampler = struct {
|
||||
/// Magnification filter.
|
||||
mag_filter: ?MagFilter = null,
|
||||
/// Minification filter.
|
||||
min_filter: ?MinFilter = null,
|
||||
/// S (U) wrapping mode.
|
||||
wrap_s: WrapMode = .repeat,
|
||||
/// T (U) wrapping mode.
|
||||
wrap_t: WrapMode = .repeat,
|
||||
};
|
||||
|
||||
/// Values are Accessor's index.
|
||||
pub const Attribute = union(enum) {
|
||||
position: Index,
|
||||
normal: Index,
|
||||
tangent: Index,
|
||||
texcoord: Index,
|
||||
color: Index,
|
||||
joints: Index,
|
||||
weights: Index,
|
||||
};
|
||||
|
||||
pub const AccessorType = enum {
|
||||
scalar,
|
||||
vec2,
|
||||
vec3,
|
||||
vec4,
|
||||
mat2x2,
|
||||
mat3x3,
|
||||
mat4x4,
|
||||
};
|
||||
|
||||
/// Enum values from GLTF 2.0 spec.
|
||||
pub const Target = enum(u32) {
|
||||
array_buffer = 34962,
|
||||
element_array_buffer = 34963,
|
||||
};
|
||||
|
||||
/// 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,
|
||||
};
|
||||
|
||||
/// The topology type of primitives to render.
|
||||
pub const Mode = enum(u32) {
|
||||
points = 0,
|
||||
lines = 1,
|
||||
line_loop = 2,
|
||||
line_strip = 3,
|
||||
triangles = 4,
|
||||
triangle_strip = 5,
|
||||
triangle_fan = 6,
|
||||
};
|
||||
|
||||
/// The name of the node’s TRS property to animate.
|
||||
pub const TargetProperty = enum {
|
||||
/// For the "translation" property, the values that are provided by the
|
||||
/// sampler are the translation along the X, Y, and Z axes.
|
||||
translation,
|
||||
/// For the "rotation" property, the values are a quaternion
|
||||
/// in the order (x, y, z, w), where w is the scalar.
|
||||
rotation,
|
||||
/// For the "scale" property, the values are the scaling
|
||||
/// factors along the X, Y, and Z axes.
|
||||
scale,
|
||||
/// The "weights" of the Morph Targets it instantiates.
|
||||
weights,
|
||||
};
|
||||
|
||||
/// An animation channel combines an animation sampler
|
||||
/// with a target property being animated.
|
||||
pub const Channel = struct {
|
||||
/// The index of a sampler in this animation used to
|
||||
/// compute the value for the target.
|
||||
sampler: Index,
|
||||
/// The descriptor of the animated property.
|
||||
target: struct {
|
||||
/// The index of the node to animate.
|
||||
/// When undefined, the animated object may be defined by an extension.
|
||||
node: Index,
|
||||
/// The name of the node’s TRS property to animate, or the "weights"
|
||||
/// of the Morph Targets it instantiates.
|
||||
property: TargetProperty,
|
||||
},
|
||||
};
|
||||
|
||||
/// Interpolation algorithm.
|
||||
pub const Interpolation = enum {
|
||||
/// The animated values are linearly interpolated between keyframes.
|
||||
/// When targeting a rotation, spherical linear interpolation (slerp)
|
||||
/// should be used to interpolate quaternions.
|
||||
linear,
|
||||
/// The animated values remain constant to the output of the first
|
||||
/// keyframe, until the next keyframe.
|
||||
step,
|
||||
/// The animation’s interpolation is computed using a cubic
|
||||
/// spline with specified tangents.
|
||||
cubicspline,
|
||||
};
|
||||
|
||||
/// An animation sampler combines timestamps
|
||||
/// with a sequence of output values and defines an interpolation algorithm.
|
||||
pub const AnimationSampler = struct {
|
||||
/// The index of an accessor containing keyframe timestamps.
|
||||
input: Index,
|
||||
/// The index of an accessor, containing keyframe output values.
|
||||
output: Index,
|
||||
/// Interpolation algorithm.
|
||||
interpolation: Interpolation = .linear,
|
||||
};
|
||||
|
||||
/// A keyframe animation.
|
||||
pub const Animation = struct {
|
||||
/// The user-defined name of this object.
|
||||
name: []const u8,
|
||||
/// 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),
|
||||
/// An array of animation samplers.
|
||||
/// An animation sampler combines timestamps with a sequence of output
|
||||
/// values and defines an interpolation algorithm.
|
||||
samplers: ArrayList(AnimationSampler),
|
||||
};
|
||||
|
||||
/// Geometry to be rendered with the given material.
|
||||
pub const Primitive = struct {
|
||||
attributes: ArrayList(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,
|
||||
};
|
||||
|
||||
/// 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,
|
||||
/// An array of primitives, each defining geometry to be rendered.
|
||||
primitives: ArrayList(Primitive),
|
||||
};
|
||||
|
||||
/// Metadata about the glTF asset.
|
||||
pub const Asset = struct {
|
||||
/// The glTF version that this asset targets.
|
||||
version: []const u8,
|
||||
/// Tool that generated this glTF model. Useful for debugging.
|
||||
generator: ?[]const u8 = null,
|
||||
/// A copyright message suitable for display to credit the content creator.
|
||||
copyright: ?[]const u8 = null,
|
||||
};
|
||||
|
||||
/// A camera’s projection.
|
||||
/// A node may reference a camera to apply a transform to place the camera
|
||||
/// in the scene.
|
||||
pub const Camera = struct {
|
||||
/// A perspective camera containing properties to create a
|
||||
/// perspective projection matrix.
|
||||
pub const Perspective = struct {
|
||||
/// The aspect ratio of the field of view.
|
||||
aspect_ratio: ?f32,
|
||||
/// The vertical field of view in radians.
|
||||
/// This value should be less than π.
|
||||
yfov: f32,
|
||||
/// The distance to the far clipping plane.
|
||||
zfar: ?f32,
|
||||
/// The distance to the near clipping plane.
|
||||
znear: f32,
|
||||
};
|
||||
|
||||
/// An orthographic camera containing properties to create an
|
||||
/// orthographic projection matrix.
|
||||
pub const Orthographic = struct {
|
||||
/// The horizontal magnification of the view.
|
||||
/// This value must not be equal to zero.
|
||||
/// This value should not be negative.
|
||||
xmag: f32,
|
||||
/// The vertical magnification of the view.
|
||||
/// This value must not be equal to zero.
|
||||
/// This value should not be negative.
|
||||
ymag: f32,
|
||||
/// The distance to the far clipping plane.
|
||||
/// This value must not be equal to zero.
|
||||
/// This value must be greater than znear.
|
||||
zfar: f32,
|
||||
/// The distance to the near clipping plane.
|
||||
znear: f32,
|
||||
};
|
||||
|
||||
name: []const u8,
|
||||
type: union(enum) {
|
||||
perspective: Perspective,
|
||||
orthographic: Orthographic,
|
||||
},
|
||||
};
|
||||
|
||||
/// Specifies the light type.
|
||||
pub const LightType = enum {
|
||||
/// Directional lights act as though they are infinitely far away and emit light in the direction of the local -z axis.
|
||||
/// This light type inherits the orientation of the node that it belongs to; position and scale are ignored
|
||||
/// except for their effect on the inherited node orientation. Because it is at an infinite distance,
|
||||
/// the light is not attenuated. Its intensity is defined in lumens per metre squared, or lux (lm/m^2).
|
||||
directional,
|
||||
/// Point lights emit light in all directions from their position in space; rotation and scale are ignored except
|
||||
/// for their effect on the inherited node position.
|
||||
/// The brightness of the light attenuates in a physically correct manner as distance increases from
|
||||
/// the light's position (i.e. brightness goes like the inverse square of the distance).
|
||||
/// Point light intensity is defined in candela, which is lumens per square radian (lm/sr).
|
||||
point,
|
||||
/// Spot lights emit light in a cone in the direction of the local -z axis.
|
||||
/// The angle and falloff of the cone is defined using two numbers, the innerConeAngle and outerConeAngle.
|
||||
/// As with point lights, the brightness also attenuates in a physically correct manner as distance
|
||||
/// increases from the light's position (i.e. brightness goes like the inverse square of the distance).
|
||||
/// Spot light intensity refers to the brightness inside the innerConeAngle (and at the location of the light) and
|
||||
/// is defined in candela, which is lumens per square radian (lm/sr).
|
||||
///
|
||||
/// Engines that don't support two angles for spotlights should use outerConeAngle as the spotlight angle,
|
||||
/// leaving innerConeAngle to implicitly be 0.
|
||||
spot,
|
||||
};
|
||||
|
||||
/// A directional, point or spot light.
|
||||
pub const Light = struct {
|
||||
name: ?[]const u8,
|
||||
/// 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)
|
||||
/// while `directional` lights use illuminance in lux (lm/m^2).
|
||||
intensity: f32 = 1,
|
||||
/// Specifies the light type.
|
||||
type: LightType,
|
||||
/// When a light's type is spot, the spot property on the light is required.
|
||||
spot: ?LightSpot,
|
||||
/// A distance cutoff at which the light's intensity may be considered to have reached zero.
|
||||
range: f32,
|
||||
};
|
||||
|
||||
pub const LightSpot = struct {
|
||||
/// Angle in radians from centre of spotlight where falloff begins.
|
||||
inner_cone_angle: f32 = 0,
|
||||
/// Angle in radians from centre of spotlight where falloff ends.
|
||||
outer_cone_angle: f32 = pi / @as(f32, 4),
|
||||
};
|
||||
|
|
@ -0,0 +1,142 @@
|
|||
{
|
||||
"asset": {
|
||||
"generator": "COLLADA2GLTF",
|
||||
"version": "2.0"
|
||||
},
|
||||
"scene": 0,
|
||||
"scenes": [
|
||||
{
|
||||
"nodes": [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes": [
|
||||
{
|
||||
"children": [
|
||||
1
|
||||
],
|
||||
"matrix": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
]
|
||||
},
|
||||
{
|
||||
"mesh": 0
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"NORMAL": 1,
|
||||
"POSITION": 2
|
||||
},
|
||||
"indices": 0,
|
||||
"mode": 4,
|
||||
"material": 0
|
||||
}
|
||||
],
|
||||
"name": "Mesh"
|
||||
}
|
||||
],
|
||||
"accessors": [
|
||||
{
|
||||
"bufferView": 0,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5123,
|
||||
"count": 36,
|
||||
"max": [
|
||||
23
|
||||
],
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
1.0,
|
||||
1.0,
|
||||
1.0
|
||||
],
|
||||
"min": [
|
||||
-1.0,
|
||||
-1.0,
|
||||
-1.0
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 288,
|
||||
"componentType": 5126,
|
||||
"count": 24,
|
||||
"max": [
|
||||
0.5,
|
||||
0.5,
|
||||
0.5
|
||||
],
|
||||
"min": [
|
||||
-0.5,
|
||||
-0.5,
|
||||
-0.5
|
||||
],
|
||||
"type": "VEC3"
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorFactor": [
|
||||
0.800000011920929,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"metallicFactor": 0.0
|
||||
},
|
||||
"name": "Red"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 576,
|
||||
"byteLength": 72,
|
||||
"target": 34963
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 0,
|
||||
"byteLength": 576,
|
||||
"byteStride": 12,
|
||||
"target": 34962
|
||||
}
|
||||
],
|
||||
"buffers": [
|
||||
{
|
||||
"byteLength": 648,
|
||||
"uri": "Box0.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
|
|
@ -0,0 +1,99 @@
|
|||
{
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [ 0, 1, 2 ]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"rotation" : [ -0.383, 0.0, 0.0, 0.92375 ],
|
||||
"mesh" : 0
|
||||
},
|
||||
{
|
||||
"translation" : [ 0.5, 0.5, 3.0 ],
|
||||
"camera" : 0
|
||||
},
|
||||
{
|
||||
"translation" : [ 0.5, 0.5, 3.0 ],
|
||||
"camera" : 1
|
||||
}
|
||||
],
|
||||
|
||||
"cameras" : [
|
||||
{
|
||||
"type": "perspective",
|
||||
"perspective": {
|
||||
"aspectRatio": 1.0,
|
||||
"yfov": 0.7,
|
||||
"zfar": 100,
|
||||
"znear": 0.01
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "orthographic",
|
||||
"orthographic": {
|
||||
"xmag": 1.0,
|
||||
"ymag": 1.0,
|
||||
"zfar": 100,
|
||||
"znear": 0.01
|
||||
}
|
||||
}
|
||||
],
|
||||
|
||||
"meshes" : [
|
||||
{
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 1
|
||||
},
|
||||
"indices" : 0
|
||||
} ]
|
||||
}
|
||||
],
|
||||
|
||||
"buffers" : [
|
||||
{
|
||||
"uri" : "simpleSquare.bin",
|
||||
"byteLength" : 60
|
||||
}
|
||||
],
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : 12,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 12,
|
||||
"byteLength" : 48,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5123,
|
||||
"count" : 6,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ 3 ],
|
||||
"min" : [ 0 ]
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : 4,
|
||||
"type" : "VEC3",
|
||||
"max" : [ 1.0, 1.0, 0.0 ],
|
||||
"min" : [ 0.0, 0.0, 0.0 ]
|
||||
}
|
||||
],
|
||||
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 60 B |
|
|
@ -0,0 +1,158 @@
|
|||
{
|
||||
"asset" : {
|
||||
"generator" : "Khronos glTF Blender I/O v1.1.46",
|
||||
"version" : "2.0"
|
||||
},
|
||||
"extensionsUsed" : [
|
||||
"KHR_lights_punctual"
|
||||
],
|
||||
"extensionsRequired" : [
|
||||
"KHR_lights_punctual"
|
||||
],
|
||||
"extensions" : {
|
||||
"KHR_lights_punctual" : {
|
||||
"lights" : [
|
||||
{
|
||||
"color" : [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"intensity" : 1000,
|
||||
"type" : "point",
|
||||
"name" : "Light"
|
||||
},
|
||||
{
|
||||
"color" : [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"intensity" : 1000,
|
||||
"type" : "spot",
|
||||
"spot": {
|
||||
"innerConeAngle": 0,
|
||||
"outerConeAngle": 1
|
||||
},
|
||||
"name" : "Light.001"
|
||||
},
|
||||
{
|
||||
"color" : [
|
||||
1,
|
||||
1,
|
||||
1
|
||||
],
|
||||
"intensity" : 1000,
|
||||
"type" : "directional",
|
||||
"name" : "Light.002"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"scene" : 0,
|
||||
"scenes" : [
|
||||
{
|
||||
"name" : "Scene",
|
||||
"nodes" : [
|
||||
1,
|
||||
3,
|
||||
5
|
||||
]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"extensions" : {
|
||||
"KHR_lights_punctual" : {
|
||||
"light" : 0
|
||||
}
|
||||
},
|
||||
"name" : "Light_Orientation",
|
||||
"rotation" : [
|
||||
-0.7071067690849304,
|
||||
0,
|
||||
0,
|
||||
0.7071067690849304
|
||||
]
|
||||
},
|
||||
{
|
||||
"children" : [
|
||||
0
|
||||
],
|
||||
"name" : "Light",
|
||||
"rotation" : [
|
||||
0.16907575726509094,
|
||||
0.7558803558349609,
|
||||
-0.27217137813568115,
|
||||
0.570947527885437
|
||||
],
|
||||
"translation" : [
|
||||
4.076245307922363,
|
||||
5.903861999511719,
|
||||
-1.0054539442062378
|
||||
]
|
||||
},
|
||||
{
|
||||
"extensions" : {
|
||||
"KHR_lights_punctual" : {
|
||||
"light" : 1
|
||||
}
|
||||
},
|
||||
"name" : "Light.001_Orientation",
|
||||
"rotation" : [
|
||||
-0.7071067690849304,
|
||||
0,
|
||||
0,
|
||||
0.7071067690849304
|
||||
]
|
||||
},
|
||||
{
|
||||
"children" : [
|
||||
2
|
||||
],
|
||||
"name" : "Light.001",
|
||||
"rotation" : [
|
||||
0.16907575726509094,
|
||||
0.7558803558349609,
|
||||
-0.27217137813568115,
|
||||
0.570947527885437
|
||||
],
|
||||
"translation" : [
|
||||
-3.9570322036743164,
|
||||
1.8591556549072266,
|
||||
-4.55197811126709
|
||||
]
|
||||
},
|
||||
{
|
||||
"extensions" : {
|
||||
"KHR_lights_punctual" : {
|
||||
"light" : 2
|
||||
}
|
||||
},
|
||||
"name" : "Light.002_Orientation",
|
||||
"rotation" : [
|
||||
-0.7071067690849304,
|
||||
0,
|
||||
0,
|
||||
0.7071067690849304
|
||||
]
|
||||
},
|
||||
{
|
||||
"children" : [
|
||||
4
|
||||
],
|
||||
"name" : "Light.002",
|
||||
"rotation" : [
|
||||
0.16907575726509094,
|
||||
0.7558803558349609,
|
||||
-0.27217137813568115,
|
||||
0.570947527885437
|
||||
],
|
||||
"translation" : [
|
||||
0.6759738922119141,
|
||||
1.6738548278808594,
|
||||
3.1679487228393555
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1,451 @@
|
|||
{
|
||||
"asset": {
|
||||
"generator": "COLLADA2GLTF",
|
||||
"version": "2.0"
|
||||
},
|
||||
"scenes": [
|
||||
{
|
||||
"nodes": [
|
||||
0
|
||||
]
|
||||
}
|
||||
],
|
||||
"scene": 0,
|
||||
"nodes": [
|
||||
{
|
||||
"children": [
|
||||
1
|
||||
],
|
||||
"matrix": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"name": "Z_UP"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
3,
|
||||
2
|
||||
],
|
||||
"matrix": [
|
||||
-4.371139894487897e-8,
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
-4.371139894487897e-8,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0
|
||||
],
|
||||
"name": "Armature"
|
||||
},
|
||||
{
|
||||
"mesh": 0,
|
||||
"skin": 0,
|
||||
"name": "Cylinder"
|
||||
},
|
||||
{
|
||||
"children": [
|
||||
4
|
||||
],
|
||||
"matrix": [
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.3597299641787689e-7,
|
||||
-4.1803297996521,
|
||||
1.0
|
||||
],
|
||||
"name": "Bone"
|
||||
},
|
||||
{
|
||||
"translation": [
|
||||
1.2150299863455948e-11,
|
||||
0.02797747030854225,
|
||||
4.187077045440674
|
||||
],
|
||||
"rotation": [
|
||||
-0.0,
|
||||
0.0002899225219152868,
|
||||
-0.0,
|
||||
-0.9999999403953552
|
||||
],
|
||||
"name": "Bone.001"
|
||||
}
|
||||
],
|
||||
"meshes": [
|
||||
{
|
||||
"primitives": [
|
||||
{
|
||||
"attributes": {
|
||||
"JOINTS_0": 1,
|
||||
"NORMAL": 2,
|
||||
"POSITION": 3,
|
||||
"WEIGHTS_0": 4
|
||||
},
|
||||
"indices": 0,
|
||||
"mode": 4,
|
||||
"material": 0
|
||||
}
|
||||
],
|
||||
"name": "Cylinder"
|
||||
}
|
||||
],
|
||||
"animations": [
|
||||
{
|
||||
"channels": [
|
||||
{
|
||||
"sampler": 0,
|
||||
"target": {
|
||||
"node": 4,
|
||||
"path": "translation"
|
||||
}
|
||||
},
|
||||
{
|
||||
"sampler": 1,
|
||||
"target": {
|
||||
"node": 4,
|
||||
"path": "rotation"
|
||||
}
|
||||
},
|
||||
{
|
||||
"sampler": 2,
|
||||
"target": {
|
||||
"node": 4,
|
||||
"path": "scale"
|
||||
}
|
||||
}
|
||||
],
|
||||
"samplers": [
|
||||
{
|
||||
"input": 5,
|
||||
"interpolation": "LINEAR",
|
||||
"output": 6
|
||||
},
|
||||
{
|
||||
"input": 5,
|
||||
"interpolation": "LINEAR",
|
||||
"output": 7
|
||||
},
|
||||
{
|
||||
"input": 5,
|
||||
"interpolation": "LINEAR",
|
||||
"output": 8
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"skins": [
|
||||
{
|
||||
"inverseBindMatrices": 9,
|
||||
"skeleton": 3,
|
||||
"joints": [
|
||||
3,
|
||||
4
|
||||
],
|
||||
"name": "Armature"
|
||||
}
|
||||
],
|
||||
"accessors": [
|
||||
{
|
||||
"bufferView": 0,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5123,
|
||||
"count": 564,
|
||||
"max": [
|
||||
159
|
||||
],
|
||||
"min": [
|
||||
0
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView": 1,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5123,
|
||||
"count": 160,
|
||||
"max": [
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"min": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"type": "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView": 2,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 160,
|
||||
"max": [
|
||||
0.9999632239341736,
|
||||
0.9999632239341736,
|
||||
1.0
|
||||
],
|
||||
"min": [
|
||||
-0.9999632239341736,
|
||||
-0.9999632239341736,
|
||||
-1.0
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 2,
|
||||
"byteOffset": 1920,
|
||||
"componentType": 5126,
|
||||
"count": 160,
|
||||
"max": [
|
||||
1.0,
|
||||
1.0,
|
||||
4.575077056884766
|
||||
],
|
||||
"min": [
|
||||
-1.0,
|
||||
-0.9999995827674866,
|
||||
-4.575077056884766
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 3,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 160,
|
||||
"max": [
|
||||
1.0,
|
||||
0.26139819622039797,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"min": [
|
||||
0.738601803779602,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"type": "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView": 4,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 50,
|
||||
"max": [
|
||||
2.083333015441895
|
||||
],
|
||||
"min": [
|
||||
0.04166661947965622
|
||||
],
|
||||
"type": "SCALAR"
|
||||
},
|
||||
{
|
||||
"bufferView": 5,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 50,
|
||||
"max": [
|
||||
-3.4530497493474868e-14,
|
||||
0.027977529913187028,
|
||||
4.187077045440674
|
||||
],
|
||||
"min": [
|
||||
-3.047870116013041e-13,
|
||||
0.027977488934993745,
|
||||
4.187077045440674
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 6,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 50,
|
||||
"max": [
|
||||
0.2953396439552307,
|
||||
0.0002899225219152868,
|
||||
4.162090377207717e-12,
|
||||
-0.9553922414779664
|
||||
],
|
||||
"min": [
|
||||
-4.6566102085421338e-9,
|
||||
0.0002769898856058717,
|
||||
-0.00008562587754568085,
|
||||
-0.9999999403953552
|
||||
],
|
||||
"type": "VEC4"
|
||||
},
|
||||
{
|
||||
"bufferView": 5,
|
||||
"byteOffset": 600,
|
||||
"componentType": 5126,
|
||||
"count": 50,
|
||||
"max": [
|
||||
1.0000001192092896,
|
||||
1.0000001192092896,
|
||||
1.0
|
||||
],
|
||||
"min": [
|
||||
0.9999999403953552,
|
||||
0.9999998211860656,
|
||||
0.9999998211860656
|
||||
],
|
||||
"type": "VEC3"
|
||||
},
|
||||
{
|
||||
"bufferView": 7,
|
||||
"byteOffset": 0,
|
||||
"componentType": 5126,
|
||||
"count": 2,
|
||||
"max": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-0.9999998211860656,
|
||||
0.0,
|
||||
0.0005798449856229126,
|
||||
0.0,
|
||||
0.0005798449856229126,
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
1.3597299641787689e-7,
|
||||
4.1803297996521,
|
||||
1.0
|
||||
],
|
||||
"min": [
|
||||
0.0,
|
||||
1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
-1.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.0,
|
||||
0.9999998211860656,
|
||||
0.0,
|
||||
-0.000003912100055458723,
|
||||
-0.02797728031873703,
|
||||
-0.006746708881109953,
|
||||
1.0
|
||||
],
|
||||
"type": "MAT4"
|
||||
}
|
||||
],
|
||||
"materials": [
|
||||
{
|
||||
"pbrMetallicRoughness": {
|
||||
"baseColorFactor": [
|
||||
0.27963539958000185,
|
||||
0.6399999856948853,
|
||||
0.21094390749931336,
|
||||
1.0
|
||||
],
|
||||
"metallicFactor": 0.0
|
||||
},
|
||||
"emissiveFactor": [
|
||||
0.0,
|
||||
0.0,
|
||||
0.0
|
||||
],
|
||||
"name": "Material_001-effect"
|
||||
}
|
||||
],
|
||||
"bufferViews": [
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 10008,
|
||||
"byteLength": 1128,
|
||||
"target": 34963
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 8528,
|
||||
"byteLength": 1280,
|
||||
"byteStride": 8,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 4688,
|
||||
"byteLength": 3840,
|
||||
"byteStride": 12,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 928,
|
||||
"byteLength": 2560,
|
||||
"byteStride": 16,
|
||||
"target": 34962
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 9808,
|
||||
"byteLength": 200
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 3488,
|
||||
"byteLength": 1200
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 128,
|
||||
"byteLength": 800
|
||||
},
|
||||
{
|
||||
"buffer": 0,
|
||||
"byteOffset": 0,
|
||||
"byteLength": 128
|
||||
}
|
||||
],
|
||||
"buffers": [
|
||||
{
|
||||
"byteLength": 11136,
|
||||
"uri": "RiggedSimple0.bin"
|
||||
}
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "frag"
|
||||
}
|
||||
],
|
||||
"inputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "in.var.TEXCOORD0",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "out.var.SV_Target0",
|
||||
"location" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
{
|
||||
"entryPoints" : [
|
||||
{
|
||||
"name" : "main",
|
||||
"mode" : "vert"
|
||||
}
|
||||
],
|
||||
"types" : {
|
||||
"_6" : {
|
||||
"name" : "Scene",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "color",
|
||||
"type" : "vec3",
|
||||
"offset" : 0
|
||||
}
|
||||
]
|
||||
},
|
||||
"_5" : {
|
||||
"name" : "type.StructuredBuffer.Scene",
|
||||
"members" : [
|
||||
{
|
||||
"name" : "_m0",
|
||||
"type" : "_6",
|
||||
"array" : [
|
||||
0
|
||||
],
|
||||
"array_size_is_literal" : [
|
||||
true
|
||||
],
|
||||
"offset" : 0,
|
||||
"array_stride" : 16
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"outputs" : [
|
||||
{
|
||||
"type" : "vec4",
|
||||
"name" : "out.var.TEXCOORD0",
|
||||
"location" : 0
|
||||
}
|
||||
],
|
||||
"ssbos" : [
|
||||
{
|
||||
"type" : "_5",
|
||||
"name" : "test",
|
||||
"readonly" : true,
|
||||
"block_size" : 0,
|
||||
"set" : 0,
|
||||
"binding" : 0
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -26,10 +26,11 @@ pub fn deinit(self: *@This()) void {
|
|||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
// std.debug.print("hello world\n", .{});
|
||||
|
||||
try backlog.initializeAndRunStandardProgram(@This(), .{
|
||||
.name = "Hello World",
|
||||
.enabledModules = .{
|
||||
.physics = true,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue