diff --git a/src/SomaSolve.c b/src/SomaSolve.c index 3e47035..809c0ed 100644 --- a/src/SomaSolve.c +++ b/src/SomaSolve.c @@ -1,9 +1,6 @@ #include "string.h" -#include "VoxelSpace.h" #include "SomaSolve.h" #include "math.h" -#include -#include /* void get_dims_input(int dims[3]) { diff --git a/src/main.c b/src/main.c index 8131541..bd9cf47 100644 --- a/src/main.c +++ b/src/main.c @@ -10,7 +10,6 @@ #include "VoxelSpace.c" #include "./tests.c" #include "lib/djstdlib/core.c" -#include "pthread.h" // Graphics bindings and libs #include "lib/raymath.h" @@ -177,7 +176,7 @@ struct SolveTaskCtx { Arena *arena; SomaSolutionList solutions; VoxelSpaceReprList input; - int dims[3]; + IntList dims; SolveTaskStatus taskStatus; }; @@ -216,40 +215,32 @@ struct Soma { PolycubeInputList polycubeInput; HandleList polycubes; SomaSolutionList solutions; - Arena *solveArena; - SolveTaskCtx *solveTaskCtx; + SolveTaskCtx solveTaskCtx; uint32 puzzleDims[3]; HandleList solutionEntities; }; void *executeSolve(void *ctx) { SolveTaskCtx *solveTaskCtx = (SolveTaskCtx *)ctx; - solveTaskCtx->taskStatus = SolveTaskStatus_Solving; - solveTaskCtx->solutions = solveSoma(solveTaskCtx->arena, solveTaskCtx->input, solveTaskCtx->dims); + if (solveTaskCtx->dims.length == 3) { + solveTaskCtx->solutions = solveSoma(solveTaskCtx->arena, solveTaskCtx->input, solveTaskCtx->dims.data); + } solveTaskCtx->taskStatus = SolveTaskStatus_Complete; return NULL; } -SolveTaskCtx *scheduleSolve(Soma *soma) { - SolveTaskCtx *threadCtx = PushStructZero(soma->solveArena, SolveTaskCtx); - VoxelSpaceReprList mappedInputs = PushList(soma->solveArena, VoxelSpaceReprList, soma->polycubeInput.length); +void scheduleSolve(Soma *soma) { + VoxelSpaceReprList mappedInputs = PushList(soma->solveTaskCtx.arena, VoxelSpaceReprList, soma->polycubeInput.length); for (EachEl(soma->polycubeInput, PolycubeInput, polycubeInput)) { AppendList(&mappedInputs, polycubeInput->repr.space); } - *threadCtx = (SolveTaskCtx){ - .arena = soma->solveArena, - .solutions = EmptyList(), - .input = mappedInputs, - .taskStatus = SolveTaskStatus_Ready, - .dims = { soma->puzzleDims[0], soma->puzzleDims[1], soma->puzzleDims[2] }, - }; - 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; + soma->solveTaskCtx.input = mappedInputs; + soma->solveTaskCtx.taskStatus = SolveTaskStatus_Solving; + soma->solveTaskCtx.dims = PushFullList(soma->solveTaskCtx.arena, IntList, 3); + soma->solveTaskCtx.dims.data[0] = soma->puzzleDims[0]; + soma->solveTaskCtx.dims.data[1] = soma->puzzleDims[1]; + soma->solveTaskCtx.dims.data[2] = soma->puzzleDims[2]; + os_createThread(&executeSolve, &soma->solveTaskCtx); } 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 result = {0}; - result.width = width; - result.height = height; - result.x = x; - result.y = y; - result.cam = createCamera(arena, (real32)result.width / (real32)result.height); - return result; + return (Frame){ + .width = width, + .height = height, + .x = x, + .y = y, + .cam = createCamera(arena, (real32)width / (real32)height), + }; } void framebufferSizeCallback(GLFWwindow *window, int width, int height) { @@ -573,7 +564,7 @@ Renderer createRenderer(Arena *arena, Scene *scene) { scene->sceneRoot = createSceneGraphNode(scene); return (Renderer){ .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) { - if (soma->prevState.displayingSolutions) { + if (!soma->prevState.displayingSolutions && soma->state.displayingSolutions) { if (soma->prevState.displayedPolycube < soma->polycubes.length) { - hide(soma->scene, soma->polycubes.data[soma->prevState.displayedPolycube]); - show(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]); + hide(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]); } - } else { + } else if (soma->prevState.displayingSolutions && !soma->state.displayingSolutions) { if (soma->prevState.displayedSolution < soma->solutionEntities.length) { - hide(soma->scene, soma->solutionEntities.data[soma->prevState.displayedSolution]); - show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]); + hide(soma->scene, soma->solutionEntities.data[soma->state.displayedSolution]); } } if (soma->state.displayingSolutions) { if (soma->solutions.length > 0) { + show(soma->scene, soma->solutionEntities.data[soma->state.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]); } } } else { - if (soma->state.isInitialState) { + if (soma->polycubes.length > 0) { show(soma->scene, soma->polycubes.data[soma->state.displayedPolycube]); - } else 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]); + if (soma->state.displayedPolycube != 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) { 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)) { uint32 solutionGraphNodeHandle = createSceneGraphNode(soma->scene); AppendList(&soma->solutionEntities, solutionGraphNodeHandle); @@ -846,9 +839,15 @@ int mainGfx() { .renderer = &renderer, .polycubeInput = PushListZero(arena, PolycubeInputList, 64), .polycubes = PushListZero(arena, HandleList, 64), + .solutionEntities = EmptyList(), .puzzleDims = {3, 3, 3}, - .solveTaskCtx = NULL, - .solveArena = arenaAlloc(Megabytes(128)), + .solveTaskCtx = (SolveTaskCtx){ + .arena = arenaAlloc(Megabytes(128)), + .solutions = EmptyList(), + .input = EmptyList(), + .dims = EmptyList(), + .taskStatus = SolveTaskStatus_Ready, + }, .state = { .displayingSolutions = false, .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( "./assets/shaders/2d.vertex.glsl"_s, @@ -895,12 +892,14 @@ int mainGfx() { soma.state.camera->pos = (RLVector3){0.0f, 0.0f, 8.0f}; cameraLookAt(soma.state.camera, 0.0f, 0.0f, 0.0f); - SceneGraphNode *reference_polycube_gn = getSceneGraphNode(soma.scene, soma.polycubes.data[0]); - Matrix worldInverse = MatrixInvert(reference_polycube_gn->world); + SceneGraphNode *referencePolycube = getSceneGraphNode(soma.scene, soma.polycubes.data[0]); + Matrix worldInverse = MatrixInvert(referencePolycube->world); 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)); + getSceneGraphNode(&mainScene, soma.state.light)->translation = (RLVector3){4.0f, 6.0f, 24.0f}; + real64 lastFrame = glfwGetTime(); real64 timeDelta = 1.0f/60.0f; @@ -911,21 +910,22 @@ int mainGfx() { soma.state.input = getCurrentInput(soma.window.handle); processInput(&soma, &ui); - updatePolycubeDisplay(arena, &soma); - if (soma.solveTaskCtx != NULL && soma.solveTaskCtx->taskStatus == SolveTaskStatus_Complete) { - 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])); + if (soma.solveTaskCtx.taskStatus == SolveTaskStatus_Complete) { + 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])); for (EachIn(soma.solutions, i)) { - 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)); + 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)); } - createSolutionEntities(soma.solveTaskCtx->arena, &soma); - soma.solveTaskCtx->taskStatus = SolveTaskStatus_Ready; + createSolutionEntities(arena, &soma); + soma.solveTaskCtx.taskStatus = SolveTaskStatus_Ready; 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); recalcScene(soma.scene); diff --git a/src/world/scene.c b/src/world/scene.c index d7d0044..1f7e815 100644 --- a/src/world/scene.c +++ b/src/world/scene.c @@ -56,8 +56,8 @@ void recalcGraphNode(SceneGraphNode *n) { Scene createScene(Arena *arena) { Scene result = { .arena = arena, - .entities = PushList(arena, EntityList, 100000), - .graphNodes = PushList(arena, SceneGraphNodeList, 100000), + .entities = PushList(arena, EntityList, 4096), + .graphNodes = PushList(arena, SceneGraphNodeList, 8192), }; result.sceneRoot = createSceneGraphNode(&result); return result;