cool beans

This commit is contained in:
2025-11-23 00:25:45 +01:00
parent 2b410eee24
commit c300276c7d
5 changed files with 143 additions and 98 deletions

View File

@@ -220,13 +220,13 @@ uint64 factorial(int n) {
return result; return result;
} }
SomaSolutionList solve(VoxelSpaceReprList reprsInput, int dims[3]) { SomaSolutionList solveSoma(Arena *solutionsArena, VoxelSpaceReprList reprsInput, int dims[3]) {
Arena *arena = arenaAlloc(Megabytes(64)); Arena *generalArena = arenaAlloc(Megabytes(64));
Arena *permsArena = arenaAlloc(Megabytes(128)); Arena *permsArena = arenaAlloc(Megabytes(128));
OffsetList offsets = PushList(arena, OffsetList, reprsInput.length + 1); OffsetList offsets = PushList(generalArena, OffsetList, reprsInput.length + 1);
VoxelSpaceReprList polycubes = PushList(arena, VoxelSpaceReprList, 0); VoxelSpaceReprList polycubes = PushList(generalArena, VoxelSpaceReprList, 0);
VoxelSpace emptyVoxelSpace = { VoxelSpace emptyVoxelSpace = {
0, 0,
@@ -245,7 +245,7 @@ SomaSolutionList solve(VoxelSpaceReprList reprsInput, int dims[3]) {
cullEmptySpace(&voxelSpace); cullEmptySpace(&voxelSpace);
VoxelSpaceReprList positions = getAllPositionsInPrism(permsArena, &voxelSpace, dims); VoxelSpaceReprList positions = getAllPositionsInPrism(permsArena, &voxelSpace, dims);
possibleCombos += positions.length; possibleCombos += positions.length;
VoxelSpaceReprList_underlying *insertion = PushArray(arena, uint64, positions.capacity); VoxelSpaceReprList_underlying *insertion = PushArray(generalArena, uint64, positions.capacity);
polycubes.capacity += positions.capacity; polycubes.capacity += positions.capacity;
polycubes.length += positions.length; polycubes.length += positions.length;
memcpy(insertion, positions.data, positions.capacity * ListElementSize(VoxelSpaceReprList)); memcpy(insertion, positions.data, positions.capacity * ListElementSize(VoxelSpaceReprList));
@@ -258,7 +258,7 @@ SomaSolutionList solve(VoxelSpaceReprList reprsInput, int dims[3]) {
cullEmptySpace(&space); cullEmptySpace(&space);
VoxelSpaceReprList perms = getAllPermutationsInPrism(permsArena, &space, dims); VoxelSpaceReprList perms = getAllPermutationsInPrism(permsArena, &space, dims);
possibleCombos *= perms.length; possibleCombos *= perms.length;
VoxelSpaceReprList_underlying *insertion = PushArray(arena, VoxelSpaceReprList_underlying, perms.capacity); VoxelSpaceReprList_underlying *insertion = PushArray(generalArena, VoxelSpaceReprList_underlying, perms.capacity);
polycubes.capacity += perms.capacity; polycubes.capacity += perms.capacity;
polycubes.length += perms.length; polycubes.length += perms.length;
memcpy(insertion, perms.data, perms.capacity * ListElementSize(VoxelSpaceReprList)); memcpy(insertion, perms.data, perms.capacity * ListElementSize(VoxelSpaceReprList));
@@ -277,14 +277,19 @@ SomaSolutionList solve(VoxelSpaceReprList reprsInput, int dims[3]) {
backtrackSolve(permsArena, &solver, 0, 0); backtrackSolve(permsArena, &solver, 0, 0);
return filterUnique(permsArena, solver.solutions, dims); SomaSolutionList uniqueSolns = filterUnique(solutionsArena, solver.solutions, dims);
arenaFree(permsArena);
arenaFree(generalArena);
return uniqueSolns;
} }
void interactiveCmdLineSolveSoma() { void interactiveCmdLineSolveSoma() {
//get_dims_input(dims); //get_dims_input(dims);
//std::cout << '\n'; //std::cout << '\n';
//std::vector<uint64> reprs = get_reprs_input(dims[0]*dims[1]*dims[2]); //std::vector<uint64> reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
print("Great. Calculating solutions...\n"); //print("Great. Calculating solutions...\n");
SomaSolutionList solutions = solve(AsList(VoxelSpaceReprList, STD_SOMA), (int[]){ 3, 3, 3 }); //SomaSolutionList solutions = solveSoma(AsList(VoxelSpaceReprList, STD_SOMA), (int[]){ 3, 3, 3 });
print("%zu solutions found.\n", solutions.length); //print("%zu solutions found.\n", solutions.length);
} }

View File

@@ -5,5 +5,5 @@
typedef VoxelSpaceReprList SomaSolution; typedef VoxelSpaceReprList SomaSolution;
DefineList(SomaSolution, SomaSolution); DefineList(SomaSolution, SomaSolution);
SomaSolutionList solve(VoxelSpaceReprList reprs_in, int dims[3]); SomaSolutionList solveSoma(Arena *solutionsArena, VoxelSpaceReprList reprs_in, int dims[3]);
void interactive_cmd_line_solve_soma(); void interactiveCmdLineSolveSoma();

View File

@@ -76,14 +76,6 @@ struct Frame {
Camera* cam; Camera* cam;
}; };
typedef struct Polycube Polycube;
struct Polycube {
uint32 entityHandle;
VoxelSpace repr;
RLVector4 color;
};
DefineList(Polycube, Polycube);
DefineList(RLVector2, RLVec2); DefineList(RLVector2, RLVec2);
DefineList(RLVector4, RLVec4); DefineList(RLVector4, RLVec4);
DefineList(real32, Float); DefineList(real32, Float);
@@ -154,60 +146,65 @@ typedef struct SomaState SomaState;
struct SomaState { struct SomaState {
bool wireframe; bool wireframe;
bool polycubeDirty; bool polycubeDirty;
uint32 currentPolycube; uint32 displayedPolycube;
uint32 lastPolycubeVisible; size_t displayedSolution;
bool displayingSolutions;
uint32 light; uint32 light;
PolycubeList polycubes;
Camera* camera; Camera* camera;
RLVector3 rotAxisX; RLVector3 rotAxisX;
RLVector3 rotAxisY; RLVector3 rotAxisY;
PolycubeInputList polycubeInput; Input input;
}; };
typedef struct Soma Soma; typedef struct Soma Soma;
struct Soma { struct Soma {
Scene *scene; Scene *scene;
Renderer *renderer; Renderer *renderer;
SomaState state;
Input currInput;
Input prevInput;
struct { struct {
GLFWwindow *handle; GLFWwindow *handle;
uint32 width; uint32 width;
uint32 height; uint32 height;
} window; } window;
SomaState prevState;
SomaState state;
PolycubeInputList polycubeInput;
HandleList polycubes;
SomaSolutionList solutions;
HandleList solutionEntities;
}; };
void showEntity(Scene *scene, uint32 entityHandle) { void show(Scene *s, uint32 graphNodeHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle); SceneGraphNode *node = getSceneGraphNode(s, graphNodeHandle);
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags |= EntityFlags_Visible;
}
for (EachIn(node->children, i)) { for (EachIn(node->children, i)) {
uint32 child = node->children.data[i]; uint32 child = node->children.data[i];
SceneGraphNode *subNode = getSceneGraphNode(scene, child); show(s, child);
if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible;
}
} }
} }
void hideEntity(Scene *scene, uint32 entityHandle) { void hide(Scene *s, uint32 graphNodeHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle); SceneGraphNode *node = getSceneGraphNode(s, graphNodeHandle);
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags &= ~EntityFlags_Visible;
}
for (EachIn(node->children, i)) { for (EachIn(node->children, i)) {
uint32 child = node->children.data[i]; uint32 child = node->children.data[i];
SceneGraphNode *subNode = getSceneGraphNode(scene, child); hide(s, child);
if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible;
}
} }
} }
RLVector3 centreFromPolycube(Scene *scene, Polycube *p) { RLVector3 centreFromPolycube(Scene *scene, uint32 p) {
RLVector3 centre = (RLVector3){0,0,0}; RLVector3 centre = (RLVector3){0,0,0};
HandleList *children = &getSceneGraphNode(scene, p->entityHandle)->children; HandleList *children = &getSceneGraphNode(scene, p)->children;
for (EachIn(*children, i)) { for (EachIn(*children, i)) {
uint32 child = children->data[i]; uint32 child = children->data[i];
centre = Vector3Add(centre, getSceneGraphNode(scene, child)->translation); centre = Vector3Add(centre, getSceneGraphNode(scene, child)->translation);
} }
centre = Vector3Scale(centre, 1.0f/(getSceneGraphNodeForEntity(scene, p->entityHandle)->children.length)); centre = Vector3Scale(centre, 1.0f/(getSceneGraphNode(scene, p)->children.length));
return centre; return centre;
} }
@@ -328,8 +325,8 @@ Input getCurrentInput(GLFWwindow *window) {
} }
void processInput(Soma *soma) { void processInput(Soma *soma) {
Input *input = &soma->currInput; Input *input = &soma->state.input;
Input *prevInput = &soma->prevInput; Input *prevInput = &soma->prevState.input;
if (input->keyboard.escape) { if (input->keyboard.escape) {
glfwSetWindowShouldClose(soma->window.handle, true); glfwSetWindowShouldClose(soma->window.handle, true);
@@ -347,39 +344,49 @@ void processInput(Soma *soma) {
node->translation.z += 1.0 * input->keyboard.z * shiftMultiplier; node->translation.z += 1.0 * input->keyboard.z * shiftMultiplier;
if (input->keyboard.enter && !prevInput->keyboard.enter) { if (input->keyboard.enter && !prevInput->keyboard.enter) {
if (soma->state.currentPolycube == 6) { if (soma->state.displayingSolutions) {
soma->state.currentPolycube = 0; if (soma->state.displayedSolution == soma->solutions.length - 1) {
soma->state.displayedSolution = 0;
} else { } else {
soma->state.currentPolycube += 1; soma->state.displayedSolution += 1;
}
} else {
if (soma->state.displayedPolycube == 6) {
soma->state.displayedPolycube = 0;
} else {
soma->state.displayedPolycube += 1;
}
} }
} }
bool dragScene = false; bool dragScene = false;
if (input->mouse.btnLeft) { if (input->mouse.btnLeft) {
Polycube *current_polycube = &soma->state.polycubes.data[soma->state.currentPolycube]; uint32 currentObject = soma->state.displayingSolutions
SceneGraphNode *polycubeGraphNode = getSceneGraphNodeForEntity(soma->scene, current_polycube->entityHandle); ? soma->solutionEntities.data[soma->state.displayedSolution]
: soma->polycubes.data[soma->state.displayedPolycube];
SceneGraphNode *objectGraphNode = getSceneGraphNode(soma->scene, currentObject);
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005; real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005;
if (deltaX > 0.00000001 || deltaX < -0.00000001) { if (deltaX > 0.00000001 || deltaX < -0.00000001) {
polycubeGraphNode->rotation = QuaternionMultiply(polycubeGraphNode->rotation, QuaternionFromAxisAngle(soma->state.rotAxisY, -(real32)deltaX)); objectGraphNode->rotation = QuaternionMultiply(objectGraphNode->rotation, QuaternionFromAxisAngle(soma->state.rotAxisY, -(real32)deltaX));
} }
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005; real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005;
if (deltaY > 0.00000001 || deltaY < -0.00000001) { if (deltaY > 0.00000001 || deltaY < -0.00000001) {
polycubeGraphNode->rotation = QuaternionMultiply(QuaternionFromAxisAngle(soma->state.rotAxisX, -(real32)deltaY), polycubeGraphNode->rotation); objectGraphNode->rotation = QuaternionMultiply(QuaternionFromAxisAngle(soma->state.rotAxisX, -(real32)deltaY), objectGraphNode->rotation);
} }
} }
} }
Polycube createPolycubeFromRepr(Arena *arena, Scene *s, VoxelSpace *repr, RLVector4 color) { uint32 createPolycubeFromRepr(Arena *arena, Scene *s, VoxelSpace *repr, RLVector4 color) {
uint32 polycubeMainEntityHandle = createEntity(arena, s); uint32 mainGraphNode = createSceneGraphNode(arena, s);
Entity *polycubeMainEntity = getEntity(s, polycubeMainEntityHandle);
for (int x = 0; x < repr->dim_x; x++) { for (int x = 0; x < repr->dim_x; x++) {
for (int y = 0; y < repr->dim_y; y++) { for (int y = 0; y < repr->dim_y; y++) {
for (int z = 0; z < repr->dim_z; z++) { for (int z = 0; z < repr->dim_z; z++) {
if (filledAt(repr, x, y, z)) { if (filledAt(repr, x, y, z)) {
uint32 segmentEntityHandle = createEntity(arena, s); uint32 segmentEntityHandle = createEntity(arena, s);
Entity *polycubeSegment = getEntity(s, segmentEntityHandle); Entity *polycubeSegment = getEntity(s, segmentEntityHandle);
polycubeSegment->color = color;
polycubeSegment->mesh = &cubeMesh; polycubeSegment->mesh = &cubeMesh;
polycubeSegment->tex = &wallTex; polycubeSegment->tex = &wallTex;
SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle); SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle);
@@ -388,19 +395,15 @@ Polycube createPolycubeFromRepr(Arena *arena, Scene *s, VoxelSpace *repr, RLVect
-((repr->dim_x - 1)/2.0f) + x, -((repr->dim_x - 1)/2.0f) + x,
((repr->dim_y - 1)/2.0f) - y ((repr->dim_y - 1)/2.0f) - y
}; };
sceneNodeAddEntity(s, polycubeMainEntity->graphNodeHandle, segmentEntityHandle); sceneNodeAddNode(s, mainGraphNode, polycubeSegment->graphNodeHandle);
} }
} }
} }
} }
Polycube result = {}; SceneGraphNode *graphNode = getSceneGraphNode(s, mainGraphNode);
result.entityHandle = polycubeMainEntityHandle;
result.color = color;
result.repr = *repr;
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(s, polycubeMainEntityHandle);
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){1, 0, 0}, PI / 4)); graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){1, 0, 0}, PI / 4));
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){0, 1, 0}, -PI / 4)); graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){0, 1, 0}, -PI / 4));
return result; return mainGraphNode;
} }
RenderObjects_Rectangle createRectangleObjects(Arena *arena, size_t count) { RenderObjects_Rectangle createRectangleObjects(Arena *arena, size_t count) {
@@ -491,7 +494,6 @@ Renderer createRenderer(Arena *arena, Scene *scene) {
result.scene = scene; result.scene = scene;
result.scene->sceneRoot = createSceneGraphNode(arena, scene); result.scene->sceneRoot = createSceneGraphNode(arena, scene);
result.rects = createRectangleObjects(arena, 100); result.rects = createRectangleObjects(arena, 100);
initGraphNode(getSceneGraphNode(scene, scene->sceneRoot));
return result; return result;
} }
@@ -517,15 +519,15 @@ void renderEnd(Soma *soma, Renderer *renderer) {
setUniform3fv(&phongShader, "light_pos", &lightGraphNode->translation); setUniform3fv(&phongShader, "light_pos", &lightGraphNode->translation);
setUniform3fv(&phongShader, "camera", &soma->state.camera->pos); setUniform3fv(&phongShader, "camera", &soma->state.camera->pos);
Polycube *currentPolycube = &soma->state.polycubes.data[soma->state.currentPolycube]; uint32 currentPolycube = soma->polycubes.data[soma->state.displayedPolycube];
glBindVertexArray(cubeMesh.vao); glBindVertexArray(cubeMesh.vao);
setUniform4fv(&phongShader, "solid_color", &currentPolycube->color);
int model_uniform = getUniformLocation(&phongShader, "model"); int model_uniform = getUniformLocation(&phongShader, "model");
for (EachIn(renderer->scene->entities, i)) { for (EachIn(renderer->scene->entities, i)) {
Entity *entity = &renderer->scene->entities.data[i]; Entity *entity = &renderer->scene->entities.data[i];
if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) { if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) {
setUniform4fv(&phongShader, "solid_color", &entity->color);
setUniformMat4fvByLoc(model_uniform, &getSceneGraphNode(renderer->scene, entity->graphNodeHandle)->world); setUniformMat4fvByLoc(model_uniform, &getSceneGraphNode(renderer->scene, entity->graphNodeHandle)->world);
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id); glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity->mesh->num_indices); glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity->mesh->num_indices);
@@ -587,7 +589,7 @@ bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
} }
void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) { void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
PolycubeInput *currentPolycube = &soma->state.polycubeInput.data[soma->state.currentPolycube]; PolycubeInput *currentPolycube = &soma->polycubeInput.data[soma->state.displayedPolycube];
real32 boxSize = 30; real32 boxSize = 30;
real32 padding = 20; real32 padding = 20;
@@ -646,10 +648,12 @@ int mainGfx() {
GLFWcursor *pointerCursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR); GLFWcursor *pointerCursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
GLFWcursor *arrowCursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); GLFWcursor *arrowCursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
soma.state.currentPolycube = 0; soma.polycubeInput = PushListZero(arena, PolycubeInputList, 64);
soma.state.lastPolycubeVisible = 6; soma.polycubes = PushListZero(arena, HandleList, 64);
soma.state.polycubeInput = PushListZero(arena, PolycubeInputList, 64);
soma.state.polycubes = PushListZero(arena, PolycubeList, 64); soma.state.displayingSolutions = true;
soma.state.displayedPolycube = 0;
soma.state.displayedSolution = 0;
soma.state.light = createEntity(arena, &mainScene); soma.state.light = createEntity(arena, &mainScene);
soma.state.camera = mainFrame.cam; soma.state.camera = mainFrame.cam;
@@ -678,18 +682,38 @@ int mainGfx() {
VoxelSpace voxelSpace = { stdSoma.data[i], 3, 3, 3 }; VoxelSpace voxelSpace = { stdSoma.data[i], 3, 3, 3 };
RLVector4 color = colorFromIndex(i); RLVector4 color = colorFromIndex(i);
PolycubeInput input = (PolycubeInput){ voxelSpace, color }; PolycubeInput input = (PolycubeInput){ voxelSpace, color };
AppendList(&soma.state.polycubeInput, input); AppendList(&soma.polycubeInput, input);
cullEmptySpace(&voxelSpace); cullEmptySpace(&voxelSpace);
Polycube polycube = createPolycubeFromRepr(arena, soma.scene, &voxelSpace, color); uint32 polycubeGraphNodeHandle = createPolycubeFromRepr(arena, soma.scene, &voxelSpace, color);
polycube.color = color; AppendList(&soma.polycubes, polycubeGraphNodeHandle);
AppendList(&soma.state.polycubes, polycube); sceneNodeAddNode(renderer.scene, renderer.scene->sceneRoot, polycubeGraphNodeHandle);
sceneNodeAddEntity(renderer.scene, renderer.scene->sceneRoot, polycube.entityHandle);
} }
soma.solutions = solveSoma(arena, AsList(VoxelSpaceReprList, STD_SOMA), (int[]){ 3, 3, 3 });
soma.solutionEntities = PushList(arena, HandleList, soma.solutions.length);
for (EachEl(soma.solutions, SomaSolution, solution)) {
uint32 solutionGraphNodeHandle = createSceneGraphNode(arena, soma.scene);
AppendList(&soma.solutionEntities, solutionGraphNodeHandle);
sceneNodeAddNode(renderer.scene, renderer.scene->sceneRoot, solutionGraphNodeHandle);
for (EachIn(*solution, soln_i)) {
uint32 polycubeGraphNodeHandle = createPolycubeFromRepr(
arena,
soma.scene,
&(VoxelSpace){ solution->data[soln_i], 3, 3, 3 },
colorFromIndex(soln_i)
);
sceneNodeAddNode(renderer.scene, solutionGraphNodeHandle, polycubeGraphNodeHandle);
}
}
show(soma.scene, soma.solutionEntities.data[soma.state.displayedSolution]);
print("%zu\n", soma.scene->entities.length);
print("%zu\n", soma.scene->graphNodes.length);
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 = getSceneGraphNodeForEntity(soma.scene, soma.state.polycubes.data[0].entityHandle); SceneGraphNode *reference_polycube_gn = getSceneGraphNode(soma.scene, soma.polycubes.data[0]);
Matrix worldInverse = MatrixInvert(reference_polycube_gn->world); Matrix worldInverse = MatrixInvert(reference_polycube_gn->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, reference_polycube_gn->translation));
@@ -702,27 +726,35 @@ int mainGfx() {
real64 frameStart = glfwGetTime(); real64 frameStart = glfwGetTime();
glfwPollEvents(); glfwPollEvents();
soma.currInput = getCurrentInput(soma.window.handle); soma.state.input = getCurrentInput(soma.window.handle);
processInput(&soma); processInput(&soma);
/*
if (soma.state.lastPolycubeVisible != soma.state.currentPolycube) { if (soma.state.lastPolycubeVisible != soma.state.currentPolycube) {
hideEntity(soma.scene, soma.state.polycubes.data[soma.state.lastPolycubeVisible].entityHandle); hide(soma.scene, soma.state.polycubes.data[soma.state.lastPolycubeVisible].graphNodeHandle);
showEntity(soma.scene, soma.state.polycubes.data[soma.state.currentPolycube].entityHandle); show(soma.scene, soma.state.polycubes.data[soma.state.currentPolycube].graphNodeHandle);
soma.state.lastPolycubeVisible = soma.state.currentPolycube; soma.state.lastPolycubeVisible = soma.state.currentPolycube;
} }
*/
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]);
}
if (soma.state.polycubeDirty) { if (soma.state.polycubeDirty) {
Polycube *currentPolycube = &soma.state.polycubes.data[soma.state.currentPolycube]; uint32 currentPolycube = soma.polycubes.data[soma.state.displayedPolycube];
PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube]; PolycubeInput *pinput = &soma.polycubeInput.data[soma.state.displayedPolycube];
removeEntity(soma.scene, currentPolycube->entityHandle); removeEntity(soma.scene, currentPolycube);
VoxelSpace culledRepr = pinput->repr; VoxelSpace culledRepr = pinput->repr;
cullEmptySpace(&culledRepr); cullEmptySpace(&culledRepr);
Polycube newPolycube = createPolycubeFromRepr(arena, soma.scene, &culledRepr, pinput->color); uint32 newPolycube = createPolycubeFromRepr(arena, soma.scene, &culledRepr, pinput->color);
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(soma.scene, newPolycube.entityHandle); SceneGraphNode *graphNode = getSceneGraphNode(soma.scene, newPolycube);
graphNode->rotation = getSceneGraphNodeForEntity(soma.scene, currentPolycube->entityHandle)->rotation; graphNode->rotation = getSceneGraphNode(soma.scene, currentPolycube)->rotation;
soma.state.polycubes.data[soma.state.currentPolycube] = newPolycube; soma.polycubes.data[soma.state.displayedPolycube] = newPolycube;
sceneNodeAddEntity(soma.scene, soma.scene->sceneRoot, newPolycube.entityHandle); sceneNodeAddNode(soma.scene, soma.scene->sceneRoot, newPolycube);
soma.state.polycubeDirty = false; soma.state.polycubeDirty = false;
showEntity(soma.scene, newPolycube.entityHandle); show(soma.scene, newPolycube);
} }
updateViewportFromFrame(soma.window.width, soma.window.height, &mainFrame); updateViewportFromFrame(soma.window.width, soma.window.height, &mainFrame);
@@ -731,8 +763,8 @@ int mainGfx() {
renderBegin(&renderer); renderBegin(&renderer);
ui.cursorIsPointer = false; ui.cursorIsPointer = false;
ui.prevInput = &soma.prevInput; ui.prevInput = &soma.prevState.input;
ui.input = &soma.currInput; ui.input = &soma.state.input;
ui.renderer = &renderer; ui.renderer = &renderer;
uiPass(&soma, &ui, &renderer); uiPass(&soma, &ui, &renderer);
if (ui.cursorIsPointer) { if (ui.cursorIsPointer) {
@@ -750,7 +782,7 @@ int mainGfx() {
glfwSwapBuffers(soma.window.handle); glfwSwapBuffers(soma.window.handle);
soma.prevInput = soma.currInput; soma.prevState = soma.state;
} }
glfwTerminate(); glfwTerminate();
@@ -759,6 +791,6 @@ int mainGfx() {
int main() { int main() {
initialiseDjStdCore(); initialiseDjStdCore();
return mainCmd(); return mainGfx();
} }

View File

@@ -15,7 +15,9 @@ SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
uint32 createSceneGraphNode(Arena *arena, Scene *s) { uint32 createSceneGraphNode(Arena *arena, Scene *s) {
AppendList(&s->graphNodes, (SceneGraphNode){0}); AppendList(&s->graphNodes, (SceneGraphNode){0});
s->graphNodes.data[s->graphNodes.length - 1].children = PushList(arena, HandleList, 64); SceneGraphNode *node = &s->graphNodes.data[s->graphNodes.length - 1];
node->children = PushList(arena, HandleList, 1000);
initGraphNode(node);
return (uint32)s->graphNodes.length; return (uint32)s->graphNodes.length;
} }
@@ -26,7 +28,6 @@ uint32 createEntity(Arena *arena, Scene *s) {
getSceneGraphNode(s, graphNodeId)->entityHandle = (uint32)s->entities.length; getSceneGraphNode(s, graphNodeId)->entityHandle = (uint32)s->entities.length;
uint32 handle = (uint32)s->entities.length; uint32 handle = (uint32)s->entities.length;
uint32 graphNodeHandle = (uint32)s->graphNodes.length; uint32 graphNodeHandle = (uint32)s->graphNodes.length;
initGraphNode(getSceneGraphNode(s, graphNodeHandle));
return handle; return handle;
} }
@@ -44,8 +45,8 @@ void recalcGraphNode(SceneGraphNode *n) {
Scene createScene(Arena *arena) { Scene createScene(Arena *arena) {
Scene result = {}; Scene result = {};
result.entities = PushList(arena, EntityList, 1024); result.entities = PushList(arena, EntityList, 100000);
result.graphNodes = PushList(arena, SceneGraphNodeList, 1024); result.graphNodes = PushList(arena, SceneGraphNodeList, 100000);
result.sceneRoot = createSceneGraphNode(arena, &result); result.sceneRoot = createSceneGraphNode(arena, &result);
return result; return result;
} }
@@ -90,3 +91,8 @@ void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
HandleList *childList = &getSceneGraphNode(s, graphNodeHandle)->children; HandleList *childList = &getSceneGraphNode(s, graphNodeHandle)->children;
AppendList(childList, getEntity(s, entityHandle)->graphNodeHandle); AppendList(childList, getEntity(s, entityHandle)->graphNodeHandle);
} }
void sceneNodeAddNode(Scene *s, uint32 recipientNodeHandle, uint32 graphNodeHandle) {
HandleList *childList = &getSceneGraphNode(s, recipientNodeHandle)->children;
AppendList(childList, graphNodeHandle);
}

View File

@@ -11,10 +11,11 @@ enum EntityFlags {
typedef struct Entity Entity; typedef struct Entity Entity;
struct Entity { struct Entity {
Mesh *mesh;
Texture *tex;
uint32 graphNodeHandle; uint32 graphNodeHandle;
uint64 flags; uint64 flags;
RLVector4 color;
Mesh *mesh;
Texture *tex;
}; };
DefineList(Entity, Entity); DefineList(Entity, Entity);
@@ -48,5 +49,6 @@ void recalcGraphNode(SceneGraphNode *n);
void recalcSceneGraphNode(Scene *s, uint32 parentHandle); void recalcSceneGraphNode(Scene *s, uint32 parentHandle);
void recalcScene(Scene *s); void recalcScene(Scene *s);
void removeEntity(Scene *s, uint32 entityHandle); void removeEntity(Scene *s, uint32 entityHandle);
void sceneNodeAddNode(Scene *s, uint32 recipientNodeHandle, uint32 graphNodeHandle);
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle); void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle);
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle); SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle);