enabled parallel job, added optimizeBroadphase, and more scopes

This commit is contained in:
peterino2 2025-10-26 22:31:48 -07:00
parent 2e4f7d98e4
commit b5dad13bd7
4 changed files with 207 additions and 8 deletions

View File

@ -1,14 +1,103 @@
# Backlog
zig version: 0.15.1
Backlog Labs Game Engine.
## Getting Started
run tools/scripts/first-time-setup.py
ffmpeg -i INPUT.mp4 -c:v libtheora -q:v 7 -c:a libvorbis -q:a 4 OUTPUT.ogv
## git-bug Cheat Sheet
This project uses git-bug for distributed issue tracking. Issues are stored directly in the repository.
### Common Commands
**Listing Issues**
```bash
git bug bug # List all issues
git bug bug status:open # List only open issues
git bug bug status:closed # List only closed issues
```
**Creating Issues**
```bash
git bug bug new -t "title" -m "message" # Create new issue
git bug bug new -t "Add feature X" -m "Description" # Example
```
**Viewing & Managing Issues**
```bash
git bug bug show <id> # Show issue details
git bug bug comment <id> # Add a comment to an issue
git bug bug close <id> # Close an issue
git bug bug open <id> # Reopen an issue
git bug bug status <id> # Show issue status
```
**Labels**
```bash
git bug bug label <id> # Show labels for an issue
git bug bug label new <id> <label> # Add a label
git bug bug label rm <id> <label> # Remove a label
```
**Syncing**
```bash
git bug pull # Pull issue updates from remote
git bug push # Push issue updates to remote
```
### Standard Labels
**Component Labels**: `core`, `rendering`, `physics`, `build-system`, `platform`, `assets`, `audio`, `ui`, `documentation`
**Type Labels**:
- `bug` - Defects or incorrect behavior
- `feature` - New functionality
- `enhancement` - Improvements to existing features
- `task` - General development work
- `documentation` - Documentation improvements
- `question` - Design decisions or discussions
- `refactoring` - Code cleanup
**Problem Type Labels** (for bugs):
- `memory` - Memory issues
- `threading` - Concurrency issues
- `crash` - Application crashes
- `build` - Build system issues
### Quick Examples
```bash
# Create a bug report
git bug bug new -t "Memory leak in asset loader" -m "Assets not freed when unloading scenes"
git bug bug label new <id> bug assets memory
# Create a feature request
git bug bug new -t "Add terrain generation" -m "Implement heightmap-based terrain"
git bug bug label new <id> feature rendering
# Create a task
git bug bug new -t "Update to Zig 0.15" -m "Migrate to latest Zig version"
git bug bug label new <id> task build-system
# View and comment on an issue
git bug bug show abc123
git bug bug comment abc123
```
### Tips
- Issue IDs can be abbreviated (first few characters)
- Use `--non-interactive` flag for scripting
- Issues sync with `git bug pull/push`
- Keep descriptions factual and clear
---
/// --------------------------------------------------------
void* malloc(size_t size); // gives you a pointer to a memory buffer of size

View File

@ -345,11 +345,17 @@ pub const SceneSystem = struct {
repr.lastUpdate = self.tickCount;
}
const useParallelJob = true;
pub fn updateTransforms(self: *@This()) void {
// todo. calculate a running load factor for the number of movable objects
// vs static objects
// if we have a small amount of movable vs static AND if we have > 1000 objects,
// then iterate over dynamicObjects array instead
if (useParallelJob) {
core.parallelJob(UpdateWorldTransformsJob{}, false, 6) catch unreachable;
} else {
for (Scene.SceneObjectContainer.denseItems(._repr), 0..) |*repr, i| {
const settings = Scene.SceneObjectContainer.readDense(i, .settings);
if (settings.sceneMode == .moveable or repr.lastUpdate == 0) {
@ -358,6 +364,7 @@ pub const SceneSystem = struct {
}
}
}
}
pub const MaxWorkerCount = 24;
@ -427,6 +434,102 @@ pub const SceneSystem = struct {
}
};
const UpdateWorldTransformsJob = struct {
world: ?*anyopaque = null,
pub fn func(self: @This(), thread: *core.ThreadContext) void {
const z = core.tracy.ZoneN(@src(), "Transform Hierarchy - wide");
defer z.End();
thread.barrier(@src()) catch unreachable;
const outputs = core.get(core.SceneSystem).getOutputForWorker(thread.threadId) catch return;
const outputList = core.get(core.SceneSystem).getOutputList(thread.threadId) catch return;
self.updateTransformsHierarchy(thread, outputs, outputList) catch |err| switch (err) {
error.OutOfMemory => {
unreachable;
},
// else => {
// thread.abort(@src(), "unknown error", err);
// return;
// },
};
const denseRepr = core.Scene.SceneObjectContainer.denseItems(._repr);
const z3 = core.tracy.ZoneN(@src(), "Merge Outputs");
// merge outputs
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;
}
fn updateTransform(
self: @This(),
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 = parentTransform;
} 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");
defer z.End();
//const dense = self.world.denseScenes();
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
// try outputs.resize(thread.scratch(), densePosRot.len);
// scan and mark all root nodes for update
const split = thread.splitSlice(core.scene.SceneObjectRepr, denseRepr);
// const locals:[]core.math.Transform = try thread.scratch().alloc(core.math.Transform, split.slice.len);
const z2 = core.tracy.ZoneN(@src(), "WalkAndResolve");
for (split.slice, 0..) |*repr, i| {
repr.merge.store(false, .seq_cst); // reset the merge big
const index = split.startIndex + i;
self.updateTransform(thread, index, densePosRot, denseRepr, outputs, outputList);
}
z2.End();
}
};
// LUA_BEGIN
// because scene objects are a special sparse-multiset type,

View File

@ -176,7 +176,9 @@ pub const PhysicsRuntime = struct {
// self.timeSinceUpdate -= self.updatePeriod;
// self.system.update(@floatCast(self.updatePeriod), .{}) catch unreachable;
// }
var z = core.tracy.ZoneN(@src(), "physics system update ");
self.system.update(@floatCast(dt), .{}) catch unreachable;
defer z.End();
// todo.. interpolation kinda easy here.
self.updateScenes(dt);
@ -196,6 +198,8 @@ pub const PhysicsRuntime = struct {
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
physChar.update(dt);
}
var z = core.tracy.ZoneN(@src(), "Updating physics transform");
defer z.End();
// update physics colliders
for (PhysicsCollider.BaseContainer.list.items) |collider| {

View File

@ -151,13 +151,14 @@ pub const ExternGameObject = struct {
}
// change this into a parallel for
for (0..4000) |i| {
for (0..400) |i| {
_ = try core.get(core.GameObjectSystem).spawnObject(BoxObject, "Box", .{
.posRot = .{
.position = .{ .x = core.itof32((i % 100)) * 2, .y = 15.0, .z = core.itof32(@divFloor(i, 100) * 2) },
.position = .{ .x = core.itof32((i % 100)) * 2, .z = 15.0, .y = core.itof32(@divFloor(i, 100) * 2) },
},
});
}
physics.optimizeBroadPhase();
}
pub fn onMapReload(ctx: ?*anyopaque, _: core.ActionEvent) void {
@ -448,6 +449,8 @@ pub const ExternGameObject = struct {
rend.context().lightPosition = p;
}
physics.applyForce(r.body, ray.dir.fmul(400), r.point);
// core.debugLine(ray.start, ray.start.add(ray.dir.fmul(1000)), .{ .duration = 2.5 });
// physics.applyForce(r.body, ray.dir.fmul(400), r.point);
}