This commit is contained in:
2025-11-25 23:12:05 +01:00
parent ff41c8ace4
commit e1ee236905
3 changed files with 61 additions and 64 deletions

View File

@@ -1,9 +1,6 @@
#include "string.h" #include "string.h"
#include "VoxelSpace.h"
#include "SomaSolve.h" #include "SomaSolve.h"
#include "math.h" #include "math.h"
#include <stdlib.h>
#include <unistd.h>
/* /*
void get_dims_input(int dims[3]) { void get_dims_input(int dims[3]) {

View File

@@ -10,7 +10,6 @@
#include "VoxelSpace.c" #include "VoxelSpace.c"
#include "./tests.c" #include "./tests.c"
#include "lib/djstdlib/core.c" #include "lib/djstdlib/core.c"
#include "pthread.h"
// Graphics bindings and libs // Graphics bindings and libs
#include "lib/raymath.h" #include "lib/raymath.h"
@@ -177,7 +176,7 @@ struct SolveTaskCtx {
Arena *arena; Arena *arena;
SomaSolutionList solutions; SomaSolutionList solutions;
VoxelSpaceReprList input; VoxelSpaceReprList input;
int dims[3]; IntList dims;
SolveTaskStatus taskStatus; SolveTaskStatus taskStatus;
}; };
@@ -216,40 +215,32 @@ struct Soma {
PolycubeInputList polycubeInput; PolycubeInputList polycubeInput;
HandleList polycubes; HandleList polycubes;
SomaSolutionList solutions; SomaSolutionList solutions;
Arena *solveArena; SolveTaskCtx solveTaskCtx;
SolveTaskCtx *solveTaskCtx;
uint32 puzzleDims[3]; uint32 puzzleDims[3];
HandleList solutionEntities; HandleList solutionEntities;
}; };
void *executeSolve(void *ctx) { void *executeSolve(void *ctx) {
SolveTaskCtx *solveTaskCtx = (SolveTaskCtx *)ctx; SolveTaskCtx *solveTaskCtx = (SolveTaskCtx *)ctx;
solveTaskCtx->taskStatus = SolveTaskStatus_Solving; if (solveTaskCtx->dims.length == 3) {
solveTaskCtx->solutions = solveSoma(solveTaskCtx->arena, solveTaskCtx->input, solveTaskCtx->dims); solveTaskCtx->solutions = solveSoma(solveTaskCtx->arena, solveTaskCtx->input, solveTaskCtx->dims.data);
}
solveTaskCtx->taskStatus = SolveTaskStatus_Complete; solveTaskCtx->taskStatus = SolveTaskStatus_Complete;
return NULL; return NULL;
} }
SolveTaskCtx *scheduleSolve(Soma *soma) { void scheduleSolve(Soma *soma) {
SolveTaskCtx *threadCtx = PushStructZero(soma->solveArena, SolveTaskCtx); VoxelSpaceReprList mappedInputs = PushList(soma->solveTaskCtx.arena, VoxelSpaceReprList, soma->polycubeInput.length);
VoxelSpaceReprList mappedInputs = PushList(soma->solveArena, VoxelSpaceReprList, soma->polycubeInput.length);
for (EachEl(soma->polycubeInput, PolycubeInput, polycubeInput)) { for (EachEl(soma->polycubeInput, PolycubeInput, polycubeInput)) {
AppendList(&mappedInputs, polycubeInput->repr.space); AppendList(&mappedInputs, polycubeInput->repr.space);
} }
*threadCtx = (SolveTaskCtx){ soma->solveTaskCtx.input = mappedInputs;
.arena = soma->solveArena, soma->solveTaskCtx.taskStatus = SolveTaskStatus_Solving;
.solutions = EmptyList(), soma->solveTaskCtx.dims = PushFullList(soma->solveTaskCtx.arena, IntList, 3);
.input = mappedInputs, soma->solveTaskCtx.dims.data[0] = soma->puzzleDims[0];
.taskStatus = SolveTaskStatus_Ready, soma->solveTaskCtx.dims.data[1] = soma->puzzleDims[1];
.dims = { soma->puzzleDims[0], soma->puzzleDims[1], soma->puzzleDims[2] }, soma->solveTaskCtx.dims.data[2] = soma->puzzleDims[2];
}; os_createThread(&executeSolve, &soma->solveTaskCtx);
soma->solveTaskCtx = threadCtx;
pthread_t threadId;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_create(&threadId, &attr, &executeSolve, threadCtx);
pthread_attr_destroy(&attr);
return threadCtx;
} }
void show(Scene *s, uint32 graphNodeHandle) { void show(Scene *s, uint32 graphNodeHandle) {
@@ -286,13 +277,13 @@ RLVector3 centreFromPolycube(Scene *scene, uint32 p) {
} }
Frame createFrame(Arena *arena, uint32 width, uint32 height, uint32 x, uint32 y) { Frame createFrame(Arena *arena, uint32 width, uint32 height, uint32 x, uint32 y) {
Frame result = {0}; return (Frame){
result.width = width; .width = width,
result.height = height; .height = height,
result.x = x; .x = x,
result.y = y; .y = y,
result.cam = createCamera(arena, (real32)result.width / (real32)result.height); .cam = createCamera(arena, (real32)width / (real32)height),
return result; };
} }
void framebufferSizeCallback(GLFWwindow *window, int width, int height) { void framebufferSizeCallback(GLFWwindow *window, int width, int height) {
@@ -573,7 +564,7 @@ Renderer createRenderer(Arena *arena, Scene *scene) {
scene->sceneRoot = createSceneGraphNode(scene); scene->sceneRoot = createSceneGraphNode(scene);
return (Renderer){ return (Renderer){
.scene = scene, .scene = scene,
.rects = createRectangleObjects(arena, 100), .rects = createRectangleObjects(arena, 1024),
}; };
} }
@@ -742,31 +733,29 @@ void uiPass(Soma *soma, UI_Context *ui) {
} }
void updatePolycubeDisplay(Arena *arena, Soma *soma) { void updatePolycubeDisplay(Arena *arena, Soma *soma) {
if (soma->prevState.displayingSolutions) { if (!soma->prevState.displayingSolutions && soma->state.displayingSolutions) {
if (soma->prevState.displayedPolycube < soma->polycubes.length) { if (soma->prevState.displayedPolycube < soma->polycubes.length) {
hide(soma->scene, soma->polycubes.data[soma->prevState.displayedPolycube]); hide(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]);
show(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]);
} }
} else { } else if (soma->prevState.displayingSolutions && !soma->state.displayingSolutions) {
if (soma->prevState.displayedSolution < soma->solutionEntities.length) { if (soma->prevState.displayedSolution < soma->solutionEntities.length) {
hide(soma->scene, soma->solutionEntities.data[soma->prevState.displayedSolution]); hide(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]);
show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]);
} }
} }
if (soma->state.displayingSolutions) { if (soma->state.displayingSolutions) {
if (soma->solutions.length > 0) { if (soma->solutions.length > 0) {
show(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]);
if (soma->state.displayedSolution != soma->prevState.displayedSolution) { if (soma->state.displayedSolution != soma->prevState.displayedSolution) {
show(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]);
hide(soma->scene, soma->solutionEntities.data[soma->prevState.displayedSolution]); hide(soma->scene, soma->solutionEntities.data[soma->prevState.displayedSolution]);
} }
} }
} else { } else {
if (soma->state.isInitialState) { if (soma->polycubes.length > 0) {
show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]); show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]);
} else if (soma->state.displayedPolycube != soma->prevState.displayedPolycube) { if (soma->state.displayedPolycube != soma->prevState.displayedPolycube) {
show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]); hide(soma->scene, soma->polycubes.data[soma->prevState.displayedPolycube]);
hide(soma->scene, soma->polycubes.data[soma->prevState.displayedPolycube]); }
} }
} }
@@ -791,7 +780,11 @@ void updatePolycubeDisplay(Arena *arena, Soma *soma) {
void createSolutionEntities(Arena *arena, Soma *soma) { void createSolutionEntities(Arena *arena, Soma *soma) {
if (soma->solutions.length > 0) { if (soma->solutions.length > 0) {
soma->solutionEntities = PushList(arena, HandleList, soma->solutions.length); if (soma->solutionEntities.capacity === 0) {
soma->solutionEntities = PushList(arena, HandleList, soma->solutions.length);
} else {
ZeroList(&soma->solutionEntities);
}
for (EachEl(soma->solutions, SomaSolution, solution)) { for (EachEl(soma->solutions, SomaSolution, solution)) {
uint32 solutionGraphNodeHandle = createSceneGraphNode(soma->scene); uint32 solutionGraphNodeHandle = createSceneGraphNode(soma->scene);
AppendList(&soma->solutionEntities, solutionGraphNodeHandle); AppendList(&soma->solutionEntities, solutionGraphNodeHandle);
@@ -846,9 +839,15 @@ int mainGfx() {
.renderer = &renderer, .renderer = &renderer,
.polycubeInput = PushListZero(arena, PolycubeInputList, 64), .polycubeInput = PushListZero(arena, PolycubeInputList, 64),
.polycubes = PushListZero(arena, HandleList, 64), .polycubes = PushListZero(arena, HandleList, 64),
.solutionEntities = EmptyList(),
.puzzleDims = {3, 3, 3}, .puzzleDims = {3, 3, 3},
.solveTaskCtx = NULL, .solveTaskCtx = (SolveTaskCtx){
.solveArena = arenaAlloc(Megabytes(128)), .arena = arenaAlloc(Megabytes(128)),
.solutions = EmptyList(),
.input = EmptyList(),
.dims = EmptyList(),
.taskStatus = SolveTaskStatus_Ready,
},
.state = { .state = {
.displayingSolutions = false, .displayingSolutions = false,
.displayedPolycube = 0, .displayedPolycube = 0,
@@ -859,8 +858,6 @@ int mainGfx() {
}, },
}; };
getSceneGraphNode(&mainScene, soma.state.light)->translation = (RLVector3){4.0f, 6.0f, 24.0f};
/* /*
Shader solid_texture_shader = createShader( Shader solid_texture_shader = createShader(
"./assets/shaders/2d.vertex.glsl"_s, "./assets/shaders/2d.vertex.glsl"_s,
@@ -895,12 +892,14 @@ int mainGfx() {
soma.state.camera->pos = (RLVector3){0.0f, 0.0f, 8.0f}; soma.state.camera->pos = (RLVector3){0.0f, 0.0f, 8.0f};
cameraLookAt(soma.state.camera, 0.0f, 0.0f, 0.0f); cameraLookAt(soma.state.camera, 0.0f, 0.0f, 0.0f);
SceneGraphNode *reference_polycube_gn = getSceneGraphNode(soma.scene, soma.polycubes.data[0]); SceneGraphNode *referencePolycube = getSceneGraphNode(soma.scene, soma.polycubes.data[0]);
Matrix worldInverse = MatrixInvert(reference_polycube_gn->world); Matrix worldInverse = MatrixInvert(referencePolycube->world);
soma.state.rotAxisY = Vector3Normalize((RLVector3){worldInverse.m4, worldInverse.m5, worldInverse.m6}); soma.state.rotAxisY = Vector3Normalize((RLVector3){worldInverse.m4, worldInverse.m5, worldInverse.m6});
RLVector3 eyes = Vector3Normalize(Vector3Subtract(soma.state.camera->pos, reference_polycube_gn->translation)); RLVector3 eyes = Vector3Normalize(Vector3Subtract(soma.state.camera->pos, referencePolycube->translation));
soma.state.rotAxisX = Vector3Normalize(Vector3CrossProduct(eyes, soma.state.rotAxisY)); soma.state.rotAxisX = Vector3Normalize(Vector3CrossProduct(eyes, soma.state.rotAxisY));
getSceneGraphNode(&mainScene, soma.state.light)->translation = (RLVector3){4.0f, 6.0f, 24.0f};
real64 lastFrame = glfwGetTime(); real64 lastFrame = glfwGetTime();
real64 timeDelta = 1.0f/60.0f; real64 timeDelta = 1.0f/60.0f;
@@ -911,21 +910,22 @@ int mainGfx() {
soma.state.input = getCurrentInput(soma.window.handle); soma.state.input = getCurrentInput(soma.window.handle);
processInput(&soma, &ui); processInput(&soma, &ui);
updatePolycubeDisplay(arena, &soma);
if (soma.solveTaskCtx != NULL && soma.solveTaskCtx->taskStatus == SolveTaskStatus_Complete) { if (soma.solveTaskCtx.taskStatus == SolveTaskStatus_Complete) {
soma.solutions = PushFullList(solutionsArena, SomaSolutionList, soma.solveTaskCtx->solutions.length); soma.solutions = PushFullList(solutionsArena, SomaSolutionList, soma.solveTaskCtx.solutions.length);
memcpy(soma.solutions.data, soma.solveTaskCtx->solutions.data, soma.solutions.length*sizeof(soma.solutions.data[0])); memcpy(soma.solutions.data, soma.solveTaskCtx.solutions.data, soma.solutions.length*sizeof(soma.solutions.data[0]));
for (EachIn(soma.solutions, i)) { for (EachIn(soma.solutions, i)) {
soma.solutions.data[i] = PushFullList(solutionsArena, SomaSolution, soma.solveTaskCtx->input.length); soma.solutions.data[i] = PushFullList(solutionsArena, SomaSolution, soma.solveTaskCtx.input.length);
memcpy(&soma.solutions.data[i], &soma.solveTaskCtx->solutions.data[i], soma.solveTaskCtx->input.length*sizeof(uint64)); memcpy(&soma.solutions.data[i], &soma.solveTaskCtx.solutions.data[i], soma.solveTaskCtx.input.length*sizeof(uint64));
} }
createSolutionEntities(soma.solveTaskCtx->arena, &soma); createSolutionEntities(arena, &soma);
soma.solveTaskCtx->taskStatus = SolveTaskStatus_Ready; soma.solveTaskCtx.taskStatus = SolveTaskStatus_Ready;
soma.state.displayingSolutions = true; soma.state.displayingSolutions = true;
arenaFreeFrom(soma.solveTaskCtx->arena, 0); arenaFreeFrom(soma.solveTaskCtx.arena, 0);
} }
updatePolycubeDisplay(arena, &soma);
updateViewportFromFrame(soma.window.width, soma.window.height, &mainFrame); updateViewportFromFrame(soma.window.width, soma.window.height, &mainFrame);
recalcScene(soma.scene); recalcScene(soma.scene);

View File

@@ -56,8 +56,8 @@ void recalcGraphNode(SceneGraphNode *n) {
Scene createScene(Arena *arena) { Scene createScene(Arena *arena) {
Scene result = { Scene result = {
.arena = arena, .arena = arena,
.entities = PushList(arena, EntityList, 100000), .entities = PushList(arena, EntityList, 4096),
.graphNodes = PushList(arena, SceneGraphNodeList, 100000), .graphNodes = PushList(arena, SceneGraphNodeList, 8192),
}; };
result.sceneRoot = createSceneGraphNode(&result); result.sceneRoot = createSceneGraphNode(&result);
return result; return result;