enabled parallel job, added optimizeBroadphase, and more scopes
This commit is contained in:
parent
2e4f7d98e4
commit
b5dad13bd7
91
README.md
91
README.md
|
|
@ -1,14 +1,103 @@
|
||||||
# Backlog
|
# Backlog
|
||||||
|
|
||||||
|
|
||||||
zig version: 0.15.1
|
zig version: 0.15.1
|
||||||
|
|
||||||
Backlog Labs Game Engine.
|
Backlog Labs Game Engine.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
run tools/scripts/first-time-setup.py
|
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
|
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
|
void* malloc(size_t size); // gives you a pointer to a memory buffer of size
|
||||||
|
|
|
||||||
|
|
@ -345,11 +345,17 @@ pub const SceneSystem = struct {
|
||||||
repr.lastUpdate = self.tickCount;
|
repr.lastUpdate = self.tickCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const useParallelJob = true;
|
||||||
|
|
||||||
pub fn updateTransforms(self: *@This()) void {
|
pub fn updateTransforms(self: *@This()) void {
|
||||||
// todo. calculate a running load factor for the number of movable objects
|
// todo. calculate a running load factor for the number of movable objects
|
||||||
// vs static objects
|
// vs static objects
|
||||||
// if we have a small amount of movable vs static AND if we have > 1000 objects,
|
// if we have a small amount of movable vs static AND if we have > 1000 objects,
|
||||||
// then iterate over dynamicObjects array instead
|
// then iterate over dynamicObjects array instead
|
||||||
|
|
||||||
|
if (useParallelJob) {
|
||||||
|
core.parallelJob(UpdateWorldTransformsJob{}, false, 6) catch unreachable;
|
||||||
|
} else {
|
||||||
for (Scene.SceneObjectContainer.denseItems(._repr), 0..) |*repr, i| {
|
for (Scene.SceneObjectContainer.denseItems(._repr), 0..) |*repr, i| {
|
||||||
const settings = Scene.SceneObjectContainer.readDense(i, .settings);
|
const settings = Scene.SceneObjectContainer.readDense(i, .settings);
|
||||||
if (settings.sceneMode == .moveable or repr.lastUpdate == 0) {
|
if (settings.sceneMode == .moveable or repr.lastUpdate == 0) {
|
||||||
|
|
@ -358,6 +364,7 @@ pub const SceneSystem = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const MaxWorkerCount = 24;
|
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
|
// LUA_BEGIN
|
||||||
|
|
||||||
// because scene objects are a special sparse-multiset type,
|
// because scene objects are a special sparse-multiset type,
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,9 @@ pub const PhysicsRuntime = struct {
|
||||||
// self.timeSinceUpdate -= self.updatePeriod;
|
// self.timeSinceUpdate -= self.updatePeriod;
|
||||||
// self.system.update(@floatCast(self.updatePeriod), .{}) catch unreachable;
|
// self.system.update(@floatCast(self.updatePeriod), .{}) catch unreachable;
|
||||||
// }
|
// }
|
||||||
|
var z = core.tracy.ZoneN(@src(), "physics system update ");
|
||||||
self.system.update(@floatCast(dt), .{}) catch unreachable;
|
self.system.update(@floatCast(dt), .{}) catch unreachable;
|
||||||
|
defer z.End();
|
||||||
|
|
||||||
// todo.. interpolation kinda easy here.
|
// todo.. interpolation kinda easy here.
|
||||||
self.updateScenes(dt);
|
self.updateScenes(dt);
|
||||||
|
|
@ -196,6 +198,8 @@ pub const PhysicsRuntime = struct {
|
||||||
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
|
for (PhysicsCharacter.BaseContainer.list.items) |physChar| {
|
||||||
physChar.update(dt);
|
physChar.update(dt);
|
||||||
}
|
}
|
||||||
|
var z = core.tracy.ZoneN(@src(), "Updating physics transform");
|
||||||
|
defer z.End();
|
||||||
|
|
||||||
// update physics colliders
|
// update physics colliders
|
||||||
for (PhysicsCollider.BaseContainer.list.items) |collider| {
|
for (PhysicsCollider.BaseContainer.list.items) |collider| {
|
||||||
|
|
|
||||||
|
|
@ -151,13 +151,14 @@ pub const ExternGameObject = struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// change this into a parallel for
|
// change this into a parallel for
|
||||||
for (0..4000) |i| {
|
for (0..400) |i| {
|
||||||
_ = try core.get(core.GameObjectSystem).spawnObject(BoxObject, "Box", .{
|
_ = try core.get(core.GameObjectSystem).spawnObject(BoxObject, "Box", .{
|
||||||
.posRot = .{
|
.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 {
|
pub fn onMapReload(ctx: ?*anyopaque, _: core.ActionEvent) void {
|
||||||
|
|
@ -448,6 +449,8 @@ pub const ExternGameObject = struct {
|
||||||
rend.context().lightPosition = p;
|
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 });
|
// core.debugLine(ray.start, ray.start.add(ray.dir.fmul(1000)), .{ .duration = 2.5 });
|
||||||
// physics.applyForce(r.body, ray.dir.fmul(400), r.point);
|
// physics.applyForce(r.body, ray.dir.fmul(400), r.point);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue