trying out the depot project
This commit is contained in:
parent
338954aa8a
commit
cf0f27cc92
15
CLAUDE.md
15
CLAUDE.md
|
|
@ -114,7 +114,9 @@ This project uses git-bug for distributed bug tracking. Bug data is stored direc
|
||||||
- `git bug bug show <id>` - Display bug details
|
- `git bug bug show <id>` - Display bug details
|
||||||
- `git bug bug comment <id>` - Add a comment to a bug
|
- `git bug bug comment <id>` - Add a comment to a bug
|
||||||
- `git bug bug status <id>` - Display bug status
|
- `git bug bug status <id>` - Display bug status
|
||||||
- `git bug bug label <id> <label>` - Add a label to a bug
|
- `git bug bug label new <id> <label>` - Add a label to a bug
|
||||||
|
- `git bug bug label rm <id> <label>` - Remove a label from a bug
|
||||||
|
- `git bug bug label <id>` - Display labels for a bug
|
||||||
- `git bug bug status:open` - List only open bugs
|
- `git bug bug status:open` - List only open bugs
|
||||||
- `git bug pull` - Pull bug updates from remote
|
- `git bug pull` - Pull bug updates from remote
|
||||||
- `git bug push` - Push bug updates to remote
|
- `git bug push` - Push bug updates to remote
|
||||||
|
|
@ -126,3 +128,14 @@ This project uses git-bug for distributed bug tracking. Bug data is stored direc
|
||||||
- Use labels to categorize bugs by component (e.g., `core`, `rendering`, `physics`, `build-system`)
|
- Use labels to categorize bugs by component (e.g., `core`, `rendering`, `physics`, `build-system`)
|
||||||
- Use `--non-interactive` flag for scripting
|
- Use `--non-interactive` flag for scripting
|
||||||
- Keep bug descriptions factual - describe what happens, not speculation about why
|
- Keep bug descriptions factual - describe what happens, not speculation about why
|
||||||
|
|
||||||
|
### Standard Labels
|
||||||
|
|
||||||
|
Use these standard labels to categorize bugs:
|
||||||
|
|
||||||
|
- **Component labels**: `core`, `rendering`, `physics`, `build-system`, `platform`, `assets`, `audio`, `ui`
|
||||||
|
- **Type labels**:
|
||||||
|
- `memory` - Memory allocation, leaks, or performance issues
|
||||||
|
- `threading` - Job system, parallelization, race conditions, or deadlocks
|
||||||
|
- `crash` - Application crashes or critical failures
|
||||||
|
- `build` - Build system or compilation issues
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
const std = @import("std");
|
||||||
|
const Backlog = @import("Backlog");
|
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void {
|
||||||
|
const target = b.standardTargetOptions(.{});
|
||||||
|
const optimize = b.standardOptimizeOption(.{});
|
||||||
|
|
||||||
|
var blbuild = Backlog.init(b, .{
|
||||||
|
.target = target,
|
||||||
|
.optimize = optimize,
|
||||||
|
.backlogRoot = "../",
|
||||||
|
});
|
||||||
|
|
||||||
|
// blbuild.addDependencyInstalls(b, .ReleaseFast); //.ReleaseFast);
|
||||||
|
const exileMain = blbuild.program(.{
|
||||||
|
.name = "exileMain",
|
||||||
|
.desc = "A tiny shooter made with this engine.",
|
||||||
|
.root_source_file = b.path("src/main.zig"),
|
||||||
|
});
|
||||||
|
|
||||||
|
exileMain.setModuleEnabled("imgui", true);
|
||||||
|
exileMain.setModuleEnabled("audio", true);
|
||||||
|
exileMain.setModuleEnabled("physics", true);
|
||||||
|
exileMain.setModuleEnabled("ui", true);
|
||||||
|
exileMain.setModuleEnabled("sys", true);
|
||||||
|
exileMain.setModuleEnabled("net", true);
|
||||||
|
|
||||||
|
{
|
||||||
|
const exileGame = exileMain.addDynamicModule("exileGame", b.path("src/exileGame.zig"));
|
||||||
|
|
||||||
|
_ = exileGame.compileInstall();
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = exileMain.compileInstall();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
.{
|
||||||
|
.name = .MyProjects,
|
||||||
|
.version = "0.0.0",
|
||||||
|
.dependencies = .{
|
||||||
|
// Neonwood's /lib folder contains
|
||||||
|
// third party libraries.
|
||||||
|
//
|
||||||
|
// They can be directly accessed
|
||||||
|
//
|
||||||
|
// as well as any of the engine/ libraries
|
||||||
|
//
|
||||||
|
// in the general case though,
|
||||||
|
|
||||||
|
// engine libraries
|
||||||
|
.Backlog = .{ .path = "../" },
|
||||||
|
|
||||||
|
|
||||||
|
.SpirvReflect = .{ .path = "../lib/spirv-reflect-zig" },
|
||||||
|
|
||||||
|
.gameExtras = .{.path = "../extras/gameExtras"},
|
||||||
|
.videoplayer = .{.path = "../extras/videoplayer"},
|
||||||
|
.doomplayer = .{.path = "../extras/doomplayer"},
|
||||||
|
.bsp = .{.path = "../extras/bsp"},
|
||||||
|
|
||||||
|
.zphysics = .{.path = "../lib/zphysics"},
|
||||||
|
.spng = .{ .path = "../lib/spng" },
|
||||||
|
.ozz = .{ .path = "../lib/ozz" },
|
||||||
|
.sdl3 = .{ .path = "../lib/sdl3" },
|
||||||
|
.miniaudio = .{ .path = "../lib/miniaudio" },
|
||||||
|
.lua = .{ .path = "../lib/lua" },
|
||||||
|
|
||||||
|
.enet = .{ .path = "../lib/enet" },
|
||||||
|
},
|
||||||
|
.paths = .{
|
||||||
|
"",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# studio games depot
|
||||||
|
|
||||||
|
!! not for open source.
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
pub var NeonObjectTable = core.EngineObjectVTable.from(@This(), "main");
|
||||||
|
|
||||||
|
allocator: std.mem.Allocator,
|
||||||
|
|
||||||
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
|
const self = try allocator.create(@This());
|
||||||
|
self.* = .{
|
||||||
|
.allocator = allocator,
|
||||||
|
};
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepare(self: *@This()) !void {
|
||||||
|
_ = self;
|
||||||
|
try api.loadDynamicModules();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
_ = self;
|
||||||
|
_ = dt;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *@This()) void {
|
||||||
|
self.allocator.destroy(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() anyerror!void {
|
||||||
|
var spec = try api.getSpec("minimal");
|
||||||
|
_ = api.startEngine(&NeonObjectTable, &spec);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std = @import("std");
|
||||||
|
const api = @import("backlog");
|
||||||
|
const core = api.core;
|
||||||
|
|
@ -367,13 +367,14 @@ pub fn shutdown_module(_: std.mem.Allocator) void {
|
||||||
|
|
||||||
ecs.shutdown();
|
ecs.shutdown();
|
||||||
algorithm.destroyNameRegistry();
|
algorithm.destroyNameRegistry();
|
||||||
gEngine.deinit();
|
|
||||||
gPackerFS.destroy();
|
gPackerFS.destroy();
|
||||||
// LUA BEGIN
|
// LUA BEGIN
|
||||||
// script.shutdown_lua();
|
// script.shutdown_lua();
|
||||||
// LUA END
|
// LUA END
|
||||||
console.shutdown();
|
console.shutdown();
|
||||||
algorithm.string_pool.shutdown();
|
algorithm.string_pool.shutdown();
|
||||||
|
|
||||||
|
gEngine.deinit();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -239,7 +239,7 @@ pub const JobWorker = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const Src = std.builtin.SourceLocation;
|
const Src = std.builtin.SourceLocation;
|
||||||
pub fn Barrier(src: Src) type {
|
pub fn BarrierCV(src: Src) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub const Src = src;
|
pub const Src = src;
|
||||||
|
|
||||||
|
|
@ -248,7 +248,7 @@ pub fn Barrier(src: Src) type {
|
||||||
pub var mutex: std.Thread.Mutex = .{};
|
pub var mutex: std.Thread.Mutex = .{};
|
||||||
pub var cv: std.Thread.Condition = .{};
|
pub var cv: std.Thread.Condition = .{};
|
||||||
|
|
||||||
pub fn sync(threadId: u32, threadCount: u32) !void {
|
pub fn sync(threadId: u32, barrierCount: u32) !void {
|
||||||
_ = threadId;
|
_ = threadId;
|
||||||
|
|
||||||
mutex.lock();
|
mutex.lock();
|
||||||
|
|
@ -256,18 +256,47 @@ pub fn Barrier(src: Src) type {
|
||||||
|
|
||||||
count += 1;
|
count += 1;
|
||||||
|
|
||||||
if (count == threadCount) {
|
if (count == barrierCount) {
|
||||||
|
// 2 second timeout
|
||||||
count = 0;
|
count = 0;
|
||||||
generation += 1;
|
generation += 1;
|
||||||
cv.broadcast();
|
cv.broadcast();
|
||||||
} else {
|
} else {
|
||||||
// 2 second timeout
|
|
||||||
try cv.timedWait(&mutex, 1000 * 1000 * 1000 * 2);
|
try cv.timedWait(&mutex, 1000 * 1000 * 1000 * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn BarrierSpin(src: Src) type {
|
||||||
|
return struct {
|
||||||
|
pub const Src = src;
|
||||||
|
|
||||||
|
pub var count: std.atomic.Value(u32) = std.atomic.Value(u32).init(0);
|
||||||
|
pub var park: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||||
|
|
||||||
|
pub fn sync(threadId: u32, barrierCount: u32) !void {
|
||||||
|
_ = threadId;
|
||||||
|
|
||||||
|
const c = count.fetchAdd(1, .release);
|
||||||
|
if(c + 1 == barrierCount)
|
||||||
|
{
|
||||||
|
park.store(true, .release);
|
||||||
|
while(count.load(.acquire) > 1) {}
|
||||||
|
_ = count.fetchSub(1, .release);
|
||||||
|
park.store(false, .release);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
while(park.load(.acquire) == false) {}
|
||||||
|
_ = count.fetchSub(1, .seq_cst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Barrier = BarrierSpin;
|
||||||
|
|
||||||
pub const ThreadContext = struct {
|
pub const ThreadContext = struct {
|
||||||
const Self = @This();
|
const Self = @This();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,8 @@ pub const SceneObjectRepr = struct {
|
||||||
attachmentMode: SceneAttachMode = .relative, // doesn't do anything yet, only support relative right now
|
attachmentMode: SceneAttachMode = .relative, // doesn't do anything yet, only support relative right now
|
||||||
transformOverride: ?*core.Transform = null,
|
transformOverride: ?*core.Transform = null,
|
||||||
lastUpdate: u32 = 0,
|
lastUpdate: u32 = 0,
|
||||||
|
|
||||||
|
merge: std.atomic.Value(bool) = std.atomic.Value(bool).init(false), // set to true if we've merged already, false if we havent
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SceneObject = struct {
|
pub const SceneObject = struct {
|
||||||
|
|
@ -300,6 +302,9 @@ pub const SceneSystem = struct {
|
||||||
tickCount: u32 = 0,
|
tickCount: u32 = 0,
|
||||||
sceneObjectContainer: *SceneObjectSet = undefined,
|
sceneObjectContainer: *SceneObjectSet = undefined,
|
||||||
|
|
||||||
|
cachedOutputs: std.ArrayList(std.ArrayList(core.Transform)) = .{},
|
||||||
|
writeOutList: std.ArrayList(std.ArrayList(usize)) = .{},
|
||||||
|
|
||||||
pub const Field = SceneObjectSet.Field;
|
pub const Field = SceneObjectSet.Field;
|
||||||
pub const FieldType = SceneObjectSet.FieldType;
|
pub const FieldType = SceneObjectSet.FieldType;
|
||||||
|
|
||||||
|
|
@ -326,16 +331,6 @@ pub const SceneSystem = struct {
|
||||||
} else {}
|
} else {}
|
||||||
}
|
}
|
||||||
|
|
||||||
// core.engine_log("final\n{d} {d} {d} {d}\n{d} {d} {d} {d}", .{
|
|
||||||
// final[0][0],
|
|
||||||
// final[0][1],
|
|
||||||
// final[0][2],
|
|
||||||
// final[0][3],
|
|
||||||
// final[1][0],
|
|
||||||
// final[1][1],
|
|
||||||
// final[1][2],
|
|
||||||
// final[1][3],
|
|
||||||
// });
|
|
||||||
repr.transform = core.zm.mul(
|
repr.transform = core.zm.mul(
|
||||||
core.zm.mul(
|
core.zm.mul(
|
||||||
core.zm.mul(
|
core.zm.mul(
|
||||||
|
|
@ -347,17 +342,6 @@ pub const SceneSystem = struct {
|
||||||
final,
|
final,
|
||||||
);
|
);
|
||||||
|
|
||||||
// core.engine_log("final\n{d} {d} {d} {d}\n{d} {d} {d} {d}", .{
|
|
||||||
// repr.transform[0][0],
|
|
||||||
// repr.transform[0][1],
|
|
||||||
// repr.transform[0][2],
|
|
||||||
// repr.transform[0][3],
|
|
||||||
// repr.transform[1][0],
|
|
||||||
// repr.transform[1][1],
|
|
||||||
// repr.transform[1][2],
|
|
||||||
// repr.transform[1][3],
|
|
||||||
// });
|
|
||||||
|
|
||||||
repr.lastUpdate = self.tickCount;
|
repr.lastUpdate = self.tickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -375,6 +359,8 @@ pub const SceneSystem = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const MaxWorkerCount = 24;
|
||||||
|
|
||||||
// ----- NeonObject interace ----
|
// ----- NeonObject interace ----
|
||||||
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
pub fn init(allocator: std.mem.Allocator) !*@This() {
|
||||||
const self = try allocator.create(@This());
|
const self = try allocator.create(@This());
|
||||||
|
|
@ -387,9 +373,28 @@ pub const SceneSystem = struct {
|
||||||
Scene.SceneObjectContainer = try SceneObjectSet.create(allocator);
|
Scene.SceneObjectContainer = try SceneObjectSet.create(allocator);
|
||||||
self.sceneObjectContainer = Scene.SceneObjectContainer;
|
self.sceneObjectContainer = Scene.SceneObjectContainer;
|
||||||
|
|
||||||
|
for (0..MaxWorkerCount) |i| {
|
||||||
|
_ = i;
|
||||||
|
try self.cachedOutputs.append(self.allocator, .{});
|
||||||
|
try self.writeOutList.append(self.allocator, .{});
|
||||||
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn getOutputList(self: *@This(), threadId: u32) !*std.ArrayList(usize) {
|
||||||
|
const outputLen = self.sceneObjectContainer.denseItems(._repr).len;
|
||||||
|
try self.writeOutList.items[threadId].ensureTotalCapacity(self.allocator, outputLen);
|
||||||
|
self.writeOutList.items[threadId].shrinkRetainingCapacity(0);
|
||||||
|
return &self.writeOutList.items[threadId];
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn getOutputForWorker(self: *@This(), threadId: u32) ![]core.Transform {
|
||||||
|
const outputLen = self.sceneObjectContainer.denseItems(._repr).len;
|
||||||
|
try self.cachedOutputs.items[threadId].resize(self.allocator, outputLen);
|
||||||
|
return self.cachedOutputs.items[threadId].items;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn preTick(self: *@This(), dt: f64) !void {
|
pub fn preTick(self: *@This(), dt: f64) !void {
|
||||||
_ = dt;
|
_ = dt;
|
||||||
self.tickCount +%= 1;
|
self.tickCount +%= 1;
|
||||||
|
|
@ -407,9 +412,17 @@ pub const SceneSystem = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *@This()) void {
|
pub fn deinit(self: *@This()) void {
|
||||||
|
for (self.cachedOutputs.items) |*i| {
|
||||||
|
i.deinit(self.allocator);
|
||||||
|
}
|
||||||
|
for (self.writeOutList.items) |*i| {
|
||||||
|
i.deinit(self.allocator);
|
||||||
|
}
|
||||||
self.dynamicObjects.deinit(self.allocator);
|
self.dynamicObjects.deinit(self.allocator);
|
||||||
self.childrenArena.deinit();
|
self.childrenArena.deinit();
|
||||||
Scene.SceneObjectContainer.destroy();
|
Scene.SceneObjectContainer.destroy();
|
||||||
|
self.cachedOutputs.deinit(self.allocator);
|
||||||
|
self.writeOutList.deinit(self.allocator);
|
||||||
self.allocator.destroy(self);
|
self.allocator.destroy(self);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub fn build(b: *std.Build) void {
|
||||||
|
|
||||||
//const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false;
|
//const tracy_enabled = b.option(bool, "tracy", "Enables tracy integration") orelse false;
|
||||||
|
|
||||||
const tracy_enabled: bool = true; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
|
const tracy_enabled: bool = false; //if (b.graph.env_map.hash_map.get("WITH_TRACY") != null) true else false;
|
||||||
// if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| {
|
// if (b.graph.env_map.hash_map.get("WITH_TRACY")) |with_tracy| {
|
||||||
// tracy_enabled = with_tracy;
|
// tracy_enabled = with_tracy;
|
||||||
// }
|
// }
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,7 @@ pub fn create(allocator: std.mem.Allocator) !*@This() {
|
||||||
pub fn prepare(self: *@This()) !void {
|
pub fn prepare(self: *@This()) !void {
|
||||||
_ = self;
|
_ = self;
|
||||||
|
|
||||||
for(0..120_000) |i|
|
for (0..120_000) |i| {
|
||||||
{
|
|
||||||
_ = i;
|
_ = i;
|
||||||
const e = try core.createEntity();
|
const e = try core.createEntity();
|
||||||
const x = e.addComponent(core.Scene).?;
|
const x = e.addComponent(core.Scene).?;
|
||||||
|
|
@ -31,7 +30,7 @@ pub fn tick(self: *@This(), dt: f64) void {
|
||||||
|
|
||||||
const start = core.getEngineTime();
|
const start = core.getEngineTime();
|
||||||
|
|
||||||
core.parallelJob(UpdateWorldTransformsJob{}, false, 10) catch unreachable;
|
core.parallelJob(UpdateWorldTransformsJob{}, false, 1) catch unreachable;
|
||||||
|
|
||||||
// wait 10 ms
|
// wait 10 ms
|
||||||
while (core.getEngineTime() - start < 0.010) {
|
while (core.getEngineTime() - start < 0.010) {
|
||||||
|
|
@ -47,7 +46,7 @@ pub fn deinit(self: *@This()) void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Src = std.builtin.SourceLocation;
|
const Src = std.builtin.SourceLocation;
|
||||||
pub fn Barrier(src: Src) type {
|
pub fn BarrierCV(src: Src) type {
|
||||||
return struct {
|
return struct {
|
||||||
pub const Src = src;
|
pub const Src = src;
|
||||||
|
|
||||||
|
|
@ -76,6 +75,32 @@ pub fn Barrier(src: Src) type {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn BarrierSpin(src: Src) type {
|
||||||
|
return struct {
|
||||||
|
pub const Src = src;
|
||||||
|
|
||||||
|
pub var count: std.atomic.Value(u32) = std.atomic.Value(u32).init(0);
|
||||||
|
pub var park: std.atomic.Value(bool) = std.atomic.Value(bool).init(false);
|
||||||
|
|
||||||
|
pub fn sync(threadId: u32, barrierCount: u32) !void {
|
||||||
|
_ = threadId;
|
||||||
|
|
||||||
|
const c = count.fetchAdd(1, .release);
|
||||||
|
if (c + 1 == barrierCount) {
|
||||||
|
park.store(true, .release);
|
||||||
|
while (count.load(.acquire) > 1) {}
|
||||||
|
_ = count.fetchSub(1, .release);
|
||||||
|
park.store(false, .release);
|
||||||
|
} else {
|
||||||
|
while (park.load(.acquire) == false) {}
|
||||||
|
_ = count.fetchSub(1, .seq_cst);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const Barrier = BarrierSpin;
|
||||||
|
|
||||||
const MultiJob = struct {
|
const MultiJob = struct {
|
||||||
threadId: u32 = 0,
|
threadId: u32 = 0,
|
||||||
threadCount: u32 = 1,
|
threadCount: u32 = 1,
|
||||||
|
|
@ -120,10 +145,10 @@ const UpdateWorldTransformsJob = struct {
|
||||||
defer z.End();
|
defer z.End();
|
||||||
thread.barrier(@src()) catch unreachable;
|
thread.barrier(@src()) catch unreachable;
|
||||||
|
|
||||||
var outputs: std.ArrayList(core.math.Transform) = .{};
|
const outputs = core.get(core.SceneSystem).getOutputForWorker(thread.threadId) catch return;
|
||||||
var outputList: std.ArrayList(usize) = .{};
|
const outputList = core.get(core.SceneSystem).getOutputList(thread.threadId) catch return;
|
||||||
|
|
||||||
self.updateTransformsHierarchy(thread, &outputs, &outputList) catch |err| switch (err) {
|
self.updateTransformsHierarchy(thread, outputs, outputList) catch |err| switch (err) {
|
||||||
error.OutOfMemory => {
|
error.OutOfMemory => {
|
||||||
unreachable;
|
unreachable;
|
||||||
},
|
},
|
||||||
|
|
@ -133,43 +158,80 @@ const UpdateWorldTransformsJob = struct {
|
||||||
// },
|
// },
|
||||||
};
|
};
|
||||||
|
|
||||||
// sync results of output List
|
const denseRepr = core.Scene.SceneObjectContainer.denseItems(._repr);
|
||||||
thread.barrier(@src()) catch unreachable;
|
|
||||||
|
|
||||||
// write out all results, there likely is no issue with false sharing as transforms are exactly 64 bytes
|
const z3 = core.tracy.ZoneN(@src(), "Merge Outputs");
|
||||||
// const dense = self.world.denseScenes();
|
// merge outputs
|
||||||
// for (outputList.items) |i| {
|
// current a noop just iterate over the outputlist
|
||||||
// // dense[i].transform = outputs.items[i];
|
for (outputList.items) |outIndex| {
|
||||||
// }
|
if (denseRepr[outIndex].merge.cmpxchgStrong(false, true, .seq_cst, .acquire) != null) {
|
||||||
|
denseRepr[outIndex].transform = outputs[outIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
z3.End();
|
||||||
|
thread.barrier(@src()) catch unreachable;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn updateTransformsHierarchy(self: @This(), thread: *core.ThreadContext, outputs: *std.ArrayList(core.math.Transform), outputList: *std.ArrayList(usize)) !void {
|
fn updateTransform(
|
||||||
_ = outputList;
|
self: @This(),
|
||||||
_ = self;
|
thread: *core.ThreadContext,
|
||||||
|
index: usize,
|
||||||
|
densePosRot: []core.scene.ScenePosRot,
|
||||||
|
denseRepr: []core.scene.SceneObjectRepr,
|
||||||
|
outputs: []core.math.Transform,
|
||||||
|
outputList: *std.ArrayList(usize),
|
||||||
|
) void {
|
||||||
|
var final: core.Transform = core.zm.identity();
|
||||||
|
|
||||||
|
const repr = denseRepr[index];
|
||||||
|
|
||||||
|
if (repr.parent) |parent| {
|
||||||
|
if (core.Scene.SceneObjectContainer.sparseToDense(parent)) |parentIndex| {
|
||||||
|
self.updateTransform(thread, parentIndex, densePosRot, denseRepr, outputs, outputList);
|
||||||
|
const parentTransform = outputs[parentIndex];
|
||||||
|
final = core.zm.mul(parentTransform, final);
|
||||||
|
} else {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const posRot = densePosRot[index];
|
||||||
|
|
||||||
|
outputs[index] = core.zm.mul(
|
||||||
|
core.zm.mul(
|
||||||
|
core.zm.mul(
|
||||||
|
core.zm.scalingV(posRot.scale.toZm()),
|
||||||
|
core.zm.matFromQuat(posRot.rotation.quat),
|
||||||
|
),
|
||||||
|
core.zm.translationV(posRot.position.toZm()),
|
||||||
|
),
|
||||||
|
final,
|
||||||
|
);
|
||||||
|
|
||||||
|
outputList.appendAssumeCapacity(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn updateTransformsHierarchy(self: @This(), thread: *core.ThreadContext, outputs: []core.math.Transform, outputList: *std.ArrayList(usize)) !void {
|
||||||
const z = core.tracy.ZoneN(@src(), "updateTransformsHierarchy");
|
const z = core.tracy.ZoneN(@src(), "updateTransformsHierarchy");
|
||||||
defer z.End();
|
defer z.End();
|
||||||
//const dense = self.world.denseScenes();
|
//const dense = self.world.denseScenes();
|
||||||
const densePosRot = core.Scene.SceneObjectContainer.denseItems(.posRot);
|
const densePosRot = core.Scene.SceneObjectContainer.denseItems(.posRot);
|
||||||
|
const denseRepr = core.Scene.SceneObjectContainer.denseItems(._repr);
|
||||||
|
|
||||||
// everything allocated with thread.scratch is blown away when the thread is complete
|
// everything allocated with thread.scratch is blown away when the thread is complete
|
||||||
try outputs.resize(thread.scratch(), densePosRot.len);
|
// try outputs.resize(thread.scratch(), densePosRot.len);
|
||||||
|
|
||||||
// scan and mark all root nodes for update
|
// scan and mark all root nodes for update
|
||||||
const split = thread.splitSlice(core.scene.ScenePosRot, densePosRot);
|
const split = thread.splitSlice(core.scene.SceneObjectRepr, denseRepr);
|
||||||
|
|
||||||
const locals:[]core.math.Transform = try thread.scratch().alloc(core.math.Transform, split.slice.len);
|
// const locals:[]core.math.Transform = try thread.scratch().alloc(core.math.Transform, split.slice.len);
|
||||||
|
|
||||||
const z2 = core.tracy.ZoneN(@src(), "WalkAndResolve");
|
const z2 = core.tracy.ZoneN(@src(), "WalkAndResolve");
|
||||||
defer z2.End();
|
for (split.slice, 0..) |*repr, i| {
|
||||||
for (split.slice, 0..) |posRot, i| {
|
|
||||||
const index = split.startIndex + i;
|
const index = split.startIndex + i;
|
||||||
_ = index;
|
self.updateTransform(thread, index, densePosRot, denseRepr, outputs, outputList);
|
||||||
|
//repr.cmpxchgStrong(false, true, .seq_cst, .acquire)
|
||||||
locals[i] = posRot.toTransform();
|
repr.merge.store(false, .seq_cst); // reset the merge big
|
||||||
}
|
}
|
||||||
|
z2.End();
|
||||||
//for (split.slice, 0..) |repr, i| {
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue