mostly migrated for c compatibility

This commit is contained in:
Daniel Ledda
2025-11-11 04:31:20 +01:00
parent 6958228da7
commit 344056744d
14 changed files with 3050 additions and 355 deletions

View File

@@ -4,7 +4,7 @@ layout (location = 1) in vec2 p1;
layout (location = 2) in vec4 color;
layout (location = 3) in float border_radius;
layout (location = 4) in float border_thickness;
layout (location = 6) in float edge_softness;
layout (location = 5) in float edge_softness;
uniform mat4 projection;

2
build
View File

@@ -1,6 +1,6 @@
#!/bin/bash
LIB_INCLUDE="-lglfw -lGL"
LIB_INCLUDE="-lglfw -lGL -lm"
g++ -g -g3 -DOS_LINUX=1 -DENABLE_ASSERT=1 ./src/main.cpp -o ./target/somaesque $LIB_INCLUDE
./target/somaesque

View File

@@ -1,11 +1,9 @@
#include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include "VoxelSpace.h"
/*
void get_dims_input(int dims[3]) {
std::cout << "Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n";
print("Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n");
bool success = false;
while (!success) {
std::cout << "x: ";
@@ -19,14 +17,16 @@ void get_dims_input(int dims[3]) {
if (size <= 64) {
success = true;
} else {
std::cout << "That resulted in " << size << " units. Try again.\n";
print("That resulted in %zu units. Try again", size);
}
std::cin.ignore();
}
}
*/
/*
std::vector<uint64> get_reprs_input(int units_required) {
std::cout << "Enter bit-representations (big endian, max 64 bits, total 1s must add up to " << units_required << "). press ENTER twice to finish input.\n";
print("Enter bit-representations (big endian, max 64 bits, total 1s must add up to %zu). press ENTER twice to finish input.\n", units_required );
std::vector<uint64> reprs = std::vector<uint64>();
int total_units = 0;
while (true) {
@@ -60,17 +60,19 @@ std::vector<uint64> get_reprs_input(int units_required) {
}
return reprs;
}
*/
typedef std::vector<uint64> SomaSolution;
typedef list<uint64> SomaSolution;
struct Solver {
typedef struct Solver {
list<uint64>* input;
list<size_t>* offsets;
std::vector<SomaSolution>* solutions;
};
list<SomaSolution>* solutions;
} Solver;
uint64 STD_SOMA[] = { 23ul, 30ul, 15ul, 1043ul, 24594ul, 12306ul, 11ul };
/*
void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int> *offsets) {
size_t num_inputs = offsets->size() - 1;
@@ -118,94 +120,117 @@ void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int>
}
std::cout << "Done. Found " << solns.size() << " solutions." << std::endl;
}
*/
void backtrack_solve(Solver *solver, uint64 working_solution = 0, size_t curr_piece = 0) {
void backtrackSolve(Arena *arena, Solver *solver, uint64 working_solution = 0, size_t curr_piece = 0) {
list<uint64> *input = solver->input;
list<size_t> *offsets = solver->offsets;
std::vector<SomaSolution> *solutions = solver->solutions;
list<SomaSolution> *solutions = solver->solutions;
size_t start = offsets->data[curr_piece];
size_t end = offsets->data[curr_piece + 1];
size_t num_pieces = offsets->length - 1;
size_t num_pieces = offsets->head - 1;
for (size_t i = start; i < end; i++) {
bool successful_fuse = !collides(working_solution, input->data[i]);
if (successful_fuse) {
uint64 new_working_solution = working_solution | input->data[i];
solutions->back().at(curr_piece) = input->data[i];
solutions->data[solutions->head - 1].data[curr_piece] = input->data[i];
if (curr_piece == num_pieces - 1) {
std::vector<uint64> last_soln = solutions->back();
solutions->push_back(SomaSolution(last_soln.begin(), last_soln.end()));
list<uint64> last_soln = solutions->data[solutions->head - 1];
list<uint64> last_soln_copy = PushList(arena, uint64, last_soln.head);
last_soln_copy.length = last_soln.head;
last_soln_copy.head = last_soln.head;
memcpy(last_soln_copy.data, last_soln.data, last_soln.head * sizeof(uint64));
appendList(solutions, last_soln_copy);
return;
} else {
backtrack_solve(solver, new_working_solution, curr_piece + 1);
backtrackSolve(arena, solver, new_working_solution, curr_piece + 1);
}
}
}
if (curr_piece == 0) {
solutions->pop_back();
}
solutions->head -= 1;
}
}
std::vector<SomaSolution> get_solution_rotations(Arena *arena, SomaSolution *solution, int dims[3]) {
std::vector<SomaSolution> result = std::vector<SomaSolution>(NUM_ROTS_3D);
for (int piece_i = 0; piece_i < solution->size(); piece_i++) {
Space space = {
solution->at(piece_i),
list<SomaSolution> getSolutionRotations(Arena *arena, SomaSolution *solution, int dims[3]) {
list<SomaSolution> result = PushFullList(arena, SomaSolution, NUM_ROTS_3D);
for (EachIn(result, i)) {
result.data[i] = PushList(arena, uint64, solution->head);
}
for (int piece_i = 0; piece_i < solution->head; piece_i++) {
Space space = {
solution->data[piece_i],
dims[0],
dims[1],
dims[2],
};
list<Space> piece_rotations = getAllRotations(arena, &space);
for (int rot_i = 0; rot_i < piece_rotations.length; rot_i++) {
result[rot_i].push_back(piece_rotations.data[rot_i].space);
list<Space> pieceRotations = getAllRotations(arena, &space);
for (int rot_i = 0; rot_i < pieceRotations.head; rot_i++) {
appendList(&result.data[rot_i], pieceRotations.data[rot_i].space);
}
}
return result;
}
std::vector<SomaSolution> filter_unique(Arena *arena, std::vector<SomaSolution> *solutions, int dims[3]) {
if (solutions->size() == 0) {
return std::vector<SomaSolution>();
list<SomaSolution> filterUnique(Arena *arena, list<SomaSolution> *solutions, int dims[3]) {
if (solutions->head == 0) {
return list<SomaSolution>{NULL,0,0};
}
std::vector<SomaSolution> unique_solns = std::vector<SomaSolution>{};
for (std::vector<uint64> &solution : *solutions) {
bool found_match = false;
list<SomaSolution> uniqueSolns = PushList(arena, SomaSolution, solutions->head);
for (EachIn(*solutions, i)) {
SomaSolution solution = solutions->data[i];
bool foundMatch = false;
Scratch temp = scratchStart(&arena, 1);
std::vector<SomaSolution> rots = get_solution_rotations(temp.arena, &solution, dims);
for (SomaSolution &rotation : rots) {
for (std::vector<uint64> &unique_soln : unique_solns) {
bool is_match = true;
for (int piece_i = 0; piece_i < unique_soln.size(); piece_i++) {
if (rotation[piece_i] != unique_soln[piece_i]) {
is_match = false;
list<SomaSolution> rots = getSolutionRotations(temp.arena, &solution, dims);
for (EachIn(rots, j)) {
SomaSolution rotation = rots.data[j];
for (EachIn(uniqueSolns, k)) {
SomaSolution unique_soln = uniqueSolns.data[k];
bool isMatch = true;
for (EachIn(unique_soln, piece_i)) {
if (rotation.data[piece_i] != unique_soln.data[piece_i]) {
isMatch = false;
break;
}
}
if (is_match) {
found_match = true;
if (isMatch) {
foundMatch = true;
break;
}
}
if (found_match) {
if (foundMatch) {
break;
}
}
scratchEnd(temp);
if (!found_match) {
unique_solns.push_back(SomaSolution(solution));
if (!foundMatch) {
SomaSolution solutionCopy = PushList(arena, uint64, solution.head);
solutionCopy.length = solution.head;
solutionCopy.head = solution.head;
memcpy(solutionCopy.data, solution.data, solution.head * sizeof(uint64));
appendList(&uniqueSolns, solutionCopy);
}
}
return unique_solns;
return uniqueSolns;
}
std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
uint64 factorial(int n) {
uint64 result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
list<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
Arena *arena = arenaAlloc(Megabytes(64));
Arena *permsArena = arenaAlloc(Megabytes(64));
Arena *permsArena = arenaAlloc(Megabytes(128));
list<size_t> offsets = PushList(arena, size_t, reprs_in_count + 1);
list<uint64> polycubes = PushList(arena, uint64, 0);
Space empty_voxel_space = {
Space empty_voxel_space = {
{},
dims[0],
dims[1],
@@ -214,12 +239,15 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
appendList(&offsets, (size_t)0);
list<uint64> positions = {};
uint64 possibleCombos = 0;
{
list<uint64> positions = {};
Space space = empty_voxel_space;
space.space = reprs_in[0];
cullEmptySpace(&space);
positions = getAllPositionsInPrism(permsArena, &space, dims);
possibleCombos += positions.head;
uint64 *insertion = PushArray(arena, uint64, positions.length);
polycubes.length += positions.length;
polycubes.head += positions.head;
@@ -232,24 +260,28 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
space.space = reprs_in[i];
cullEmptySpace(&space);
list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims);
possibleCombos *= perms.head;
uint64 *insertion = PushArray(arena, uint64, perms.length);
polycubes.length += perms.length;
polycubes.head += perms.head;
memcpy(insertion, perms.data, perms.length * sizeof(uint64));
}
appendList(&offsets, polycubes.length);
appendList(&offsets, polycubes.head);
list<SomaSolution> solutions = PushList(permsArena, SomaSolution, (size_t)floor(sqrt(possibleCombos)));
SomaSolution initialSoln = PushFullList(permsArena, uint64, reprs_in_count);
appendList(&solutions, initialSoln);
std::vector<SomaSolution> solutions = {std::vector<uint64>(reprs_in_count)};
Solver solver = {
&polycubes,
&offsets,
&solutions,
};
backtrack_solve(&solver);
backtrackSolve(permsArena, &solver);
return filter_unique(arena, solver.solutions, dims);
return filterUnique(permsArena, solver.solutions, dims);
}
@@ -258,7 +290,7 @@ void interactive_cmd_line_solve_soma() {
//get_dims_input(dims);
//std::cout << '\n';
//std::vector<uint64> reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
std::cout << "Great. Calculating solutions...\n";
std::vector<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
std::cout << solutions.size() << " solutions found." << std::endl;
print("Great. Calculating solutions...\n");
list<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
print("%zu solutions found.\n", solutions.head);
}

View File

@@ -1,7 +1,6 @@
#include <cstdint>
#include <vector>
#include "lib/djstdlib/core.h"
extern std::vector<uint64_t> STD_SOMA;
typedef std::vector<uint64_t> SomaSolution;
std::vector<SomaSolution> solve(std::vector<uint64_t> *reprs_in, int dims[3]);
void interactive_cmd_line_solve_soma();
extern uint64 STD_SOMA[];
typedef list<uint64> SomaSolution;
list<SomaSolution> solve(list<uint64> *reprs_in, int dims[3]);
void interactive_cmd_line_solve_soma();

View File

@@ -1,7 +1,6 @@
#ifndef VOXELSPACE_H
#define VOXELSPACE_H
#include <vector>
#include "lib/djstdlib/core.h"
constexpr int NUM_ROTS_3D = 24;
@@ -51,7 +50,7 @@ void rotate90Y(Space *space);
void rotate90Z(Space *space);
void pushNewUniqueSpins(std::vector<Space> *existingSpaces, Space* spaceToSpin);
void pushNewUniqueSpins(list<Space> *existingSpaces, Space* spaceToSpin);
list<Space> getUniqueRotations(Arena *arena, Space *space);

View File

@@ -1,4 +1,4 @@
#include <math.h>
#include "math.h"
#include "Color.h"
real32 hueToRGB(real32 p, real32 q, real32 t) {

View File

@@ -1,8 +1,8 @@
#include <glm/gtc/type_ptr.hpp>
#include "Shader.h"
#include "../lib/djstdlib/core.h"
#include "../lib/djstdlib/os.h"
#include "../lib/glad/glad.h"
#include "../lib/raymath.h"
enum ShaderType {
fragment=GL_FRAGMENT_SHADER,
@@ -60,43 +60,43 @@ Shader createShader(string vertex_path, string fragment_path) {
return result;
}
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix) {
void setUniformMat4fv(Shader *s, const char *uniformName, Matrix *matrix) {
glUniformMatrix4fv(
glGetUniformLocation(s->progId, uniformName),
1, GL_FALSE, glm::value_ptr(*matrix));
glGetUniformLocation(s->progId, uniformName),
1, GL_FALSE, MatrixToFloat(*matrix));
}
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix) {
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(*matrix));
void setUniformMat4fv(int uniformLocation, Matrix *matrix) {
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, MatrixToFloat(*matrix));
}
void setUniform4fv(Shader *s, const char *uniformName, Vector4<real32> *vector) {
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
}
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector) {
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
void setUniform4fv(Shader *s, const char *uniformName, RLVector4 *vector) {
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector);
}
void setUniform4fv(int uniformLocation, glm::vec4 *vector) {
glUniform4fv(uniformLocation, 1, glm::value_ptr(*vector));
void setUniform4fv(int uniformLocation, RLVector4 *vector) {
glUniform4fv(uniformLocation, 1, (const GLfloat *)vector);
}
void setUniform3fv(Shader *s, const char *uniformName, Vector3<real32> *vector) {
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
}
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector) {
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
void setUniform3fv(Shader *s, const char *uniformName, RLVector3 *vector) {
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, Vector3ToFloat(*vector));
}
void setUniform3fv(int uniformLocation, glm::vec3 *vector) {
glUniform3fv(uniformLocation, 1, glm::value_ptr(*vector));
void setUniform3fv(int uniformLocation, RLVector3 *vector) {
glUniform3fv(uniformLocation, 1, Vector3ToFloat(*vector));
}
void setUniform2fv(Shader *s, const char *uniformName, Vector2<real32> *vector) {
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
}
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector) {
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
void setUniform2fv(Shader *s, const char *uniformName, RLVector2 *vector) {
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector);
}
void setUniform2fv(int uniformLocation, glm::vec2 *vector) {
glUniform2fv(uniformLocation, 1, glm::value_ptr(*vector));
void setUniform2fv(int uniformLocation, RLVector2 *vector) {
glUniform2fv(uniformLocation, 1, (const GLfloat *)vector);
}
int getUniformLocation(Shader *s, const char *uniformName) {

View File

@@ -1,7 +1,7 @@
#ifndef LEDDA_SHADER_H
#define LEDDA_SHADER_H
#include "glm/glm.hpp"
#include "../lib/raymath.h"
#include "../lib/djstdlib/core.h"
struct Shader {
@@ -10,17 +10,17 @@ struct Shader {
Shader createShader(string vertex_path, string fragment_path);
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix);
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix);
void setUniformMat4fv(Shader *s, const char *uniformName, Matrix *matrix);
void setUniformMat4fv(int uniformLocation, Matrix *matrix);
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector);
void setUniform4fv(int uniformLocation, glm::vec4 *vector);
void setUniform4fv(Shader *s, const char *uniformName, RLVector4 *vector);
void setUniform4fv(int uniformLocation, RLVector4 *vector);
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector);
void setUniform3fv(int uniformLocation, glm::vec3 *vector);
void setUniform3fv(Shader *s, const char *uniformName, RLVector3 *vector);
void setUniform3fv(int uniformLocation, RLVector3 *vector);
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector);
void setUniform2fv(int uniformLocation, glm::vec2 *vector);
void setUniform2fv(Shader *s, const char *uniformName, RLVector2 *vector);
void setUniform2fv(int uniformLocation, RLVector2 *vector);
int getUniformLocation(Shader *s, const char *uniformName);

View File

@@ -1,7 +1,7 @@
#ifndef LEDDA_GEOMETRY_H
#define LEDDA_GEOMETRY_H
#include <stddef.h>
#include "stddef.h"
struct Shape {
unsigned int* indices;

2670
src/lib/raymath.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,81 +1,71 @@
// stdlib
// TODO(djledda): get rid of this
#include <vector>
// Graphics bindings and libs
#include "lib/glad/glad.c"
#include <GLFW/glfw3.h>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/ext/matrix_transform.hpp>
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtc/type_ptr.hpp>
#include <glm/gtc/matrix_transform.hpp>
// Project
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global`
#include "SomaSolve.cpp"
#include "gfx/gfx.cpp"
#include "world/world.cpp"
#include "VoxelSpace.cpp"
#include "./tests.cpp"
#include "lib/djstdlib/core.cpp"
// Graphics bindings and libs
#include "lib/glad/glad.c"
#include <GLFW/glfw3.h>
// Library initialisation
#define STB_IMAGE_IMPLEMENTATION
#include "lib/loaders/stb_image.h"
#define TINYOBJ_LOADER_C_IMPLEMENTATION
#include "lib/loaders/tinyobj.h"
#define RAYMATH_IMPLEMENTATION
#include "lib/raymath.h"
#define PI (real32)3.14159265358979323846264338327950288
void print(glm::vec3* vector) {
glm::vec3 vec = *vector;
void print(RLVector3* vector) {
RLVector3 vec = *vector;
print(
"┌ ┐\n"
"│%7.2f%, %7.2f, %7.2f │\n"
"└ ┘\n",
vec[0], vec[1], vec[2]);
"└ ┘\n",
vec.x, vec.y, vec.z);
}
void print(glm::mat4* matrix) {
glm::mat4 mat = *matrix;
void print(Matrix* matrix) {
Matrix mat = *matrix;
print(
"┌ ┐\n"
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
"└ ┘\n",
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
"└ ┘\n",
mat.m0, mat.m1, mat.m2, mat.m3,
mat.m4, mat.m5, mat.m6, mat.m7,
mat.m8, mat.m9, mat.m10, mat.m11,
mat.m12, mat.m13, mat.m14, mat.m15);
}
struct Camera {
glm::mat4 view;
glm::mat4 proj;
glm::vec3 pos;
glm::vec3 up;
glm::vec3 target;
Matrix view;
Matrix proj;
RLVector3 pos;
RLVector3 up;
RLVector3 target;
};
Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) {
Camera *result = PushStruct(arena, Camera);
result->view = glm::mat4();
result->proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
result->pos = glm::vec3(0.0f);
result->up = glm::vec3(0.0f, 1.0f, 0.0f);
result->view = (Matrix){0};
result->proj = MatrixPerspective(DEG2RAD * 45.0f, aspect_ratio, 0.1f, 100.0f);
result->pos = (RLVector3){0};
result->up = (RLVector3){0,1,0};
return result;
}
void cameraLookAt(Camera *c, float x, float y, float z) {
c->target = glm::vec3(x, y, z);
c->view = glm::lookAt(c->pos, c->target, c->up);
c->target = (RLVector3){x, y, z};
c->view = MatrixLookAt(c->pos, c->target, c->up);
}
void camera_set_up(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
c->up = glm::vec3(up_x, up_y, up_z);
void cameraSetUp(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
c->up = (RLVector3){up_x, up_y, up_z};
}
struct Frame {
@@ -146,7 +136,7 @@ struct Renderer {
struct PolycubeInput {
Space repr;
Vector4<real32> color;
Vector4<real32> color;
};
struct SomaState {
@@ -157,8 +147,8 @@ struct SomaState {
uint32 light;
list<Polycube> polycubes;
Camera* camera;
glm::vec3 rotAxisX;
glm::vec3 rotAxisY;
RLVector3 rotAxisX;
RLVector3 rotAxisY;
list<PolycubeInput> polycubeInput;
};
@@ -177,7 +167,8 @@ struct Soma {
void showEntity(Scene *scene, uint32 entityHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
for (uint32 &child : node->children) {
for (EachIn(node->children, i)) {
uint32 child = node->children.data[i];
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible;
@@ -187,7 +178,8 @@ void showEntity(Scene *scene, uint32 entityHandle) {
void hideEntity(Scene *scene, uint32 entityHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
for (uint32 &child : node->children) {
for (EachIn(node->children, i)) {
uint32 child = node->children.data[i];
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible;
@@ -195,12 +187,14 @@ void hideEntity(Scene *scene, uint32 entityHandle) {
}
}
glm::vec3 centreFromPolycube(Scene *scene, Polycube *p) {
glm::vec3 centre = glm::vec3(0.0f);
for (uint32 &child : getSceneGraphNode(scene, p->entityHandle)->children) {
centre += getSceneGraphNode(scene, child)->translation;
RLVector3 centreFromPolycube(Scene *scene, Polycube *p) {
RLVector3 centre = (RLVector3){0,0,0};
list<uint32> *children = &getSceneGraphNode(scene, p->entityHandle)->children;
for (EachIn(*children, i)) {
uint32 child = children->data[i];
centre = Vector3Add(centre, getSceneGraphNode(scene, child)->translation);
}
centre /= getSceneGraphNodeForEntity(scene, p->entityHandle)->children.size();
centre = Vector3Scale(centre, 1.0f/(getSceneGraphNodeForEntity(scene, p->entityHandle)->children.head));
return centre;
}
@@ -315,7 +309,7 @@ void processInput(Soma *soma) {
if (input->keyboard.escape) {
glfwSetWindowShouldClose(soma->window.handle, true);
}
}
if (input->keyboard.space && !prevInput->keyboard.space) {
glPolygonMode(GL_FRONT_AND_BACK, !soma->state.wireframe ? GL_LINE : GL_FILL);
@@ -343,33 +337,33 @@ void processInput(Soma *soma) {
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005;
if (deltaX > 0.00000001 || deltaX < -0.00000001) {
polycubeGraphNode->rotation *= glm::angleAxis((real32)deltaX, soma->state.rotAxisY);
polycubeGraphNode->rotation = QuaternionMultiply(polycubeGraphNode->rotation, QuaternionFromAxisAngle(soma->state.rotAxisY, -(real32)deltaX));
}
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005;
if (deltaY > 0.00000001 || deltaY < -0.00000001) {
polycubeGraphNode->rotation = glm::angleAxis(-(real32)deltaY, soma->state.rotAxisX) * polycubeGraphNode->rotation;
polycubeGraphNode->rotation = QuaternionMultiply(QuaternionFromAxisAngle(soma->state.rotAxisX, -(real32)deltaY), polycubeGraphNode->rotation);
}
}
}
Polycube createPolycubeFromRepr(Scene *s, Space *repr, Vector4<real32> color) {
uint32 polycubeMainEntityHandle = createEntity(s);
Polycube createPolycubeFromRepr(Arena *arena, Scene *s, Space *repr, Vector4<real32> color) {
uint32 polycubeMainEntityHandle = createEntity(arena, s);
Entity *polycubeMainEntity = getEntity(s, polycubeMainEntityHandle);
for (int x = 0; x < repr->dim_x; x++) {
for (int y = 0; y < repr->dim_y; y++) {
for (int z = 0; z < repr->dim_z; z++) {
if (filledAt(repr, x, y, z)) {
uint32 segmentEntityHandle = createEntity(s);
uint32 segmentEntityHandle = createEntity(arena, s);
Entity *polycubeSegment = getEntity(s, segmentEntityHandle);
polycubeSegment->mesh = &cubeMesh;
polycubeSegment->tex = &wallTex;
SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle);
graphNode->translation = glm::vec3(
graphNode->translation = RLVector3{
-((repr->dim_z - 1)/2.0f) + z,
((repr->dim_x - 1)/2.0f) - x,
-((repr->dim_y - 1)/2.0f) + y
);
-((repr->dim_x - 1)/2.0f) + x,
((repr->dim_y - 1)/2.0f) - y
};
sceneNodeAddEntity(s, polycubeMainEntity->graphNodeHandle, segmentEntityHandle);
}
}
@@ -380,8 +374,8 @@ Polycube createPolycubeFromRepr(Scene *s, Space *repr, Vector4<real32> color) {
result.color = color;
result.repr = *repr;
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(s, polycubeMainEntityHandle);
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(1, 0, 0));
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(0, 1, 0));
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){1, 0, 0}, PI / 4));
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){0, 1, 0}, -PI / 4));
return result;
}
@@ -471,7 +465,7 @@ void reinitRectangleObjectBuffers(Renderer *r) {
Renderer createRenderer(Arena *arena, Scene *scene) {
Renderer result = {0};
result.scene = scene;
result.scene->sceneRoot = createSceneGraphNode(scene);
result.scene->sceneRoot = createSceneGraphNode(arena, scene);
result.rects = createRectangleObjects(arena, 100);
initGraphNode(getSceneGraphNode(scene, scene->sceneRoot));
return result;
@@ -505,12 +499,13 @@ void renderEnd(Soma *soma, Renderer *renderer) {
setUniform4fv(&phongShader, "solid_color", &currentPolycube->color);
int model_uniform = getUniformLocation(&phongShader, "model");
for (Entity &entity : renderer->scene->entities) {
if (entity.flags & EntityFlags_Render && entity.flags & EntityFlags_Visible) {
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity.graphNodeHandle)->world);
glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices);
entity.flags &= ~EntityFlags_Render;
for (EachIn(renderer->scene->entities, i)) {
Entity *entity = &renderer->scene->entities.data[i];
if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) {
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity->graphNodeHandle)->world);
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity->mesh->num_indices);
entity->flags &= ~EntityFlags_Render;
}
}
@@ -519,7 +514,7 @@ void renderEnd(Soma *soma, Renderer *renderer) {
reinitRectangleObjectBuffers(renderer);
glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
Matrix ortho = MatrixOrtho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
setUniformMat4fv(&solidColorShader, "projection", &ortho);
glBindVertexArray(renderer->rects.vao);
@@ -549,22 +544,17 @@ bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
}
}
if (*value) {
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
rect.color,
5, 0);
} else {
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
rect.color,
5, 2);
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
} else {
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
COLOR_WHITE,
5, 0);
5, 2);
}
return clicked;
@@ -583,10 +573,10 @@ void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
bool cellActive = filledAt(&currentPolycube->repr, x, y, z);
UI_Rect rect = {
currX,
currY,
boxSize,
boxSize,
currX,
currY,
boxSize,
boxSize,
0,
currentPolycube->color,
};
@@ -602,7 +592,7 @@ void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
}
}
int main_cmd() {
int mainCmd() {
interactive_cmd_line_solve_soma();
return 0;
}
@@ -610,7 +600,7 @@ int main_cmd() {
int mainGfx() {
Arena *arena = arenaAlloc(Megabytes(128));
Scene mainScene = createScene();
Scene mainScene = createScene(arena);
Soma soma = {};
soma.window.width = 800;
@@ -634,47 +624,48 @@ int mainGfx() {
soma.state.lastPolycubeVisible = 6;
soma.state.polycubeInput = PushListZero(arena, PolycubeInput, 64);
soma.state.polycubes = PushListZero(arena, Polycube, 64);
soma.state.light = createEntity(&mainScene);
soma.state.light = createEntity(arena, &mainScene);
soma.state.camera = mainFrame.cam;
SceneGraphNode *light = getSceneGraphNode(&mainScene, getEntity(&mainScene, soma.state.light)->graphNodeHandle);
light->translation = glm::vec3(4.0f, 6.0f, 24.0f);
light->translation = RLVector3{4.0f, 6.0f, 24.0f};
/*
Shader solid_texture_shader = createShader(
"./assets/shaders/2d.vertex.glsl"_s,
"./assets/shaders/2d.vertex.glsl"_s,
"./assets/shaders/2d-tex.fragment.glsl"_s);
*/
solidColorShader = createShader(
"./assets/shaders/2d-solid.vertex.glsl"_s,
"./assets/shaders/2d-solid.vertex.glsl"_s,
"./assets/shaders/2d-solid.fragment.glsl"_s);
phongShader = createShader(
"./assets/shaders/phong-solid.vertex.glsl"_s,
"./assets/shaders/phong-solid.vertex.glsl"_s,
"./assets/shaders/phong-solid.fragment.glsl"_s);
cubeMesh = createMesh("./assets/models/cube.obj");
wallTex = createTexture("./assets/textures/brick-wall.jpg");
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
for (EachInArray(STD_SOMA, i)) {
Space voxelSpace = { STD_SOMA[i], 3, 3, 3 };
Vector4<real32> color = colorFromIndex(i);
appendList(&soma.state.polycubeInput, PolycubeInput{ voxelSpace, color });
cullEmptySpace(&voxelSpace);
Polycube polycube = createPolycubeFromRepr(soma.scene, &voxelSpace, color);
Polycube polycube = createPolycubeFromRepr(arena, soma.scene, &voxelSpace, color);
polycube.color = color;
appendList(&soma.state.polycubes, polycube);
sceneNodeAddEntity(renderer.scene, renderer.scene->sceneRoot, polycube.entityHandle);
}
soma.state.camera->pos = glm::vec3(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);
SceneGraphNode *reference_polycube_gn = getSceneGraphNodeForEntity(soma.scene, soma.state.polycubes.data[0].entityHandle);
soma.state.rotAxisY = glm::normalize(glm::vec4(0, 1, 0, 0) * glm::inverse(reference_polycube_gn->world));
glm::vec3 eyes = glm::normalize(soma.state.camera->pos - reference_polycube_gn->translation);
soma.state.rotAxisX = glm::normalize(glm::cross(eyes, soma.state.rotAxisY));
Matrix worldInverse = MatrixInvert(reference_polycube_gn->world);
soma.state.rotAxisY = Vector3Normalize(RLVector3{worldInverse.m4, worldInverse.m5, worldInverse.m6});
RLVector3 eyes = Vector3Normalize(Vector3Subtract(soma.state.camera->pos, reference_polycube_gn->translation));
soma.state.rotAxisX = Vector3Normalize(Vector3CrossProduct(eyes, soma.state.rotAxisY));
real64 lastFrame = glfwGetTime();
real64 timeDelta = 1.0f/60.0f;
@@ -695,9 +686,9 @@ int mainGfx() {
Polycube *currentPolycube = &soma.state.polycubes.data[soma.state.currentPolycube];
PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube];
removeEntity(soma.scene, currentPolycube->entityHandle);
Space culledRepr = pinput->repr;
Space culledRepr = pinput->repr;
cullEmptySpace(&culledRepr);
Polycube newPolycube = createPolycubeFromRepr(soma.scene, &culledRepr, pinput->color);
Polycube newPolycube = createPolycubeFromRepr(arena, soma.scene, &culledRepr, pinput->color);
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(soma.scene, newPolycube.entityHandle);
graphNode->rotation = getSceneGraphNodeForEntity(soma.scene, currentPolycube->entityHandle)->rotation;
soma.state.polycubes.data[soma.state.currentPolycube] = newPolycube;

View File

@@ -1,13 +1,16 @@
#include <iostream>
#include <vector>
#include <tuple>
#include "VoxelSpace.h"
#include "lib/djstdlib/core.h"
typedef struct MismatchData {
int i;
uint64 actual;
uint64 expected;
} MismatchData;
void test() {
{
Space space = {};
space.space=23ull;
space.space=23ull;
space.dim_x=3;
space.dim_y=3;
space.dim_z=3;
@@ -107,86 +110,86 @@ void test() {
int prism_dims[] = { 3, 3, 3 };
list<uint64> perms = getAllPermutationsInPrism(arena, &space1, prism_dims);
auto expected_perms = std::vector<uint64_t>{
30ull,
240ull,
15360ull,
122880ull,
7864320ull,
62914560ull,
153ull,
306ull,
78336ull,
156672ull,
40108032ull,
80216064ull,
266760ull,
533520ull,
1067040ull,
2134080ull,
4268160ull,
8536320ull,
263682ull,
527364ull,
2109456ull,
4218912ull,
16875648ull,
33751296ull,
2101761ull,
4203522ull,
8407044ull,
16814088ull,
33628176ull,
67256352ull,
525825ull,
1051650ull,
4206600ull,
8413200ull,
33652800ull,
67305600ull,
51ull,
408ull,
26112ull,
208896ull,
13369344ull,
106954752ull,
90ull,
180ull,
46080ull,
92160ull,
23592960ull,
47185920ull,
4680ull,
9360ull,
18720ull,
2396160ull,
4792320ull,
9584640ull,
1542ull,
12336ull,
98688ull,
789504ull,
6316032ull,
50528256ull,
36873ull,
73746ull,
147492ull,
18878976ull,
37757952ull,
75515904ull,
3075ull,
24600ull,
196800ull,
1574400ull,
12595200ull,
100761600ull,
uint64 expected_perms[] = {
30ull,
240ull,
15360ull,
122880ull,
7864320ull,
62914560ull,
153ull,
306ull,
78336ull,
156672ull,
40108032ull,
80216064ull,
266760ull,
533520ull,
1067040ull,
2134080ull,
4268160ull,
8536320ull,
263682ull,
527364ull,
2109456ull,
4218912ull,
16875648ull,
33751296ull,
2101761ull,
4203522ull,
8407044ull,
16814088ull,
33628176ull,
67256352ull,
525825ull,
1051650ull,
4206600ull,
8413200ull,
33652800ull,
67305600ull,
51ull,
408ull,
26112ull,
208896ull,
13369344ull,
106954752ull,
90ull,
180ull,
46080ull,
92160ull,
23592960ull,
47185920ull,
4680ull,
9360ull,
18720ull,
2396160ull,
4792320ull,
9584640ull,
1542ull,
12336ull,
98688ull,
789504ull,
6316032ull,
50528256ull,
36873ull,
73746ull,
147492ull,
18878976ull,
37757952ull,
75515904ull,
3075ull,
24600ull,
196800ull,
1574400ull,
12595200ull,
100761600ull,
};
Assert(expected_perms.size() == perms.length);
Assert(ArrayCount(expected_perms) == perms.length);
for (int i = 0; i < perms.length; i++) {
if (i <= expected_perms.size()) {
Assert(expected_perms.at(i) == perms.data[i]);
if (i <= ArrayCount(expected_perms)) {
Assert(expected_perms[i] == perms.data[i]);
}
}
@@ -194,20 +197,20 @@ void test() {
}
{
Space space1 = {};
space1.space=30ull;
Space space1 = {};
space1.space=30ull;
space1.dim_x=3;
space1.dim_y=3;
space1.dim_z=3;
Space space2 = {};
space2.space=30ull;
Space space2 = {};
space2.space=30ull;
space2.dim_x=3;
space2.dim_y=3;
space2.dim_z=3;
Space space3 = {};
space3.space=30ull;
Space space3 = {};
space3.space=30ull;
space3.dim_x=3;
space3.dim_y=3;
space3.dim_z=3;
@@ -258,7 +261,7 @@ void test() {
};
Space space3 = {};
space3.space=15ull;
space3.space=15ull;
space3.dim_x=3;
space3.dim_y=3;
space3.dim_z=3;
@@ -276,40 +279,41 @@ void test() {
list<uint64> positions1 = getAllPositionsInPrism(arena, &space1, dims);
list<uint64> positions2 = getAllPositionsInPrism(arena, &space2, dims);
list<uint64> positions3 = getAllPositionsInPrism(arena, &space3, dims);
auto mismatches1 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
auto mismatches2 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
auto mismatches3 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
list<MismatchData> mismatches1 = PushList(arena, MismatchData, 6);
list<MismatchData> mismatches2 = PushList(arena, MismatchData, 6);
list<MismatchData> mismatches3 = PushList(arena, MismatchData, 6);
for (int i = 0; i < 6; i++) {
if (positions1.data[i] != expected_results1[i]) {
mismatches1.push_back({ i, positions1.data[i], expected_results1[i] });
appendList(&mismatches1, { i, positions1.data[i], expected_results1[i] });
}
if (positions2.data[i] != expected_results2[i]) {
mismatches2.push_back({ i, positions2.data[i], expected_results2[i] });
appendList(&mismatches2, { i, positions2.data[i], expected_results2[i] });
}
if (positions3.data[i] != expected_results3[i]) {
mismatches3.push_back({ i, positions3.data[i], expected_results3[i] });
appendList(&mismatches3, { i, positions3.data[i], expected_results3[i] });
}
}
Assert(mismatches1.size() == 0);
if (mismatches1.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches1) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
Assert(mismatches1.head == 0);
if (mismatches1.head > 0) {
print("Index - Actual - Expected\n");
for (EachIn(mismatches1, i)) {
print("%zu - %zu - %zu\n", mismatches1.data[i].i, mismatches1.data[i].actual, mismatches1.data[i].expected);
}
}
Assert(mismatches2.size() == 0);
if (mismatches2.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches2) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
Assert(mismatches2.head == 0);
if (mismatches2.head > 0) {
print("Index - Actual - Expected\n");
for (EachIn(mismatches2, i)) {
print("%zu - %zu - %zu\n", mismatches2.data[i].i, mismatches2.data[i].actual, mismatches2.data[i].expected);
}
}
Assert(mismatches3.size() == 0);
if (mismatches3.size() > 0) {
std::cout << "Index - Actual - Expected" << std::endl;
for (auto &mismatch : mismatches3) {
std::cout << "At " << std::get<0>(mismatch) << ": " << std::get<1>(mismatch) << " != " << std::get<2>(mismatch) << std::endl;
Assert(mismatches3.head == 0);
if (mismatches3.head > 0) {
print("Index - Actual - Expected\n");
for (EachIn(mismatches3, i)) {
print("%zu - %zu - %zu\n", mismatches3.data[i].i, mismatches3.data[i].actual, mismatches3.data[i].expected);
}
}

View File

@@ -1,54 +1,52 @@
#include <cstring>
#include "scene.h"
Entity *getEntity(Scene *s, uint32 id) {
return &s->entities[id - 1];
return &s->entities.data[id - 1];
}
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) {
return &s->graphNodes[s->entities[entityHandle - 1].graphNodeHandle - 1];
return &s->graphNodes.data[s->entities.data[entityHandle - 1].graphNodeHandle - 1];
}
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
return &s->graphNodes[sceneGraphNodeHandle - 1];
return &s->graphNodes.data[sceneGraphNodeHandle - 1];
}
uint32 createEntity(Scene *s) {
s->entities.emplace_back();
s->graphNodes.emplace_back();
s->entities.back().graphNodeHandle = (uint32)s->graphNodes.size();
s->graphNodes.back().entityHandle = (uint32)s->entities.size();
uint32 handle = (uint32)s->entities.size();
uint32 graphNodeHandle = (uint32)s->graphNodes.size();
uint32 createSceneGraphNode(Arena *arena, Scene *s) {
appendList(&s->graphNodes, (SceneGraphNode){0});
s->graphNodes.data[s->graphNodes.head - 1].children = PushList(arena, uint32, 64);
return (uint32)s->graphNodes.head;
}
uint32 createEntity(Arena *arena, Scene *s) {
appendList(&s->entities, (Entity){0});
uint32 graphNodeId = createSceneGraphNode(arena, s);
s->entities.data[s->entities.head - 1].graphNodeHandle = graphNodeId;
getSceneGraphNode(s, graphNodeId)->entityHandle = (uint32)s->entities.head;
uint32 handle = (uint32)s->entities.head;
uint32 graphNodeHandle = (uint32)s->graphNodes.head;
initGraphNode(getSceneGraphNode(s, graphNodeHandle));
return handle;
}
uint32 createSceneGraphNode(Scene *s) {
s->graphNodes.emplace_back();
return (uint32)s->graphNodes.size();
}
void initGraphNode(SceneGraphNode *n) {
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
n->rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
n->local = glm::mat4(1.0f);
n->scale = RLVector3{1.0f, 1.0f, 1.0f};
n->translation = RLVector3{0.0f, 0.0f, 0.0f};
n->rotation = Quaternion{1.0f, 0.0f, 0.0f, 0.0f};
n->local = MatrixIdentity();
n->world = n->local;
}
void recalcGraphNode(SceneGraphNode *n) {
n->local = glm::scale(
glm::translate(
glm::mat4(1.0f),
n->translation
) * glm::toMat4(n->rotation),
n->scale
);
n->local = MatrixCompose(n->translation, n->rotation, n->scale);
}
Scene createScene() {
Scene createScene(Arena *arena) {
Scene result = {};
result.sceneRoot = createSceneGraphNode(&result);
result.entities = PushList(arena, Entity, 1024);
result.graphNodes = PushList(arena, SceneGraphNode, 1024);
result.sceneRoot = createSceneGraphNode(arena, &result);
return result;
}
@@ -57,11 +55,12 @@ void recalcSceneGraphNode(Scene *s, uint32 parentHandle) {
if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags |= EntityFlags_Render;
}
for (uint32 &nodeId : node->children) {
for (EachIn(node->children, i)) {
uint32 nodeId = node->children.data[i];
SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
graphNode->parentHandle = parentHandle;
recalcGraphNode(graphNode);
graphNode->world = node->world * graphNode->local;
graphNode->world = MatrixMultiply(graphNode->local, node->world);
recalcSceneGraphNode(s, nodeId);
}
}
@@ -76,9 +75,10 @@ void removeEntity(Scene *s, uint32 entityHandle) {
SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle);
if (graphNode->parentHandle) {
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
for (int i = 0; i < parentNode->children.size(); i++) {
if (parentNode->children.at(i) == entity->graphNodeHandle) {
parentNode->children.erase(parentNode->children.begin() + i);
for (int i = 0; i < parentNode->children.head; i++) {
if (parentNode->children.data[i] == entity->graphNodeHandle) {
memcpy(&parentNode->children.data[i], &parentNode->children.data[i + 1], parentNode->children.head - i);
parentNode->children.head -= 1;
graphNode->parentHandle = 0;
break;
}
@@ -87,5 +87,7 @@ void removeEntity(Scene *s, uint32 entityHandle) {
}
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
getSceneGraphNode(s, graphNodeHandle)->children.push_back(getEntity(s, entityHandle)->graphNodeHandle);
list<uint32> *childList = &getSceneGraphNode(s, graphNodeHandle)->children;
appendList(childList, getEntity(s, entityHandle)->graphNodeHandle);
print("%zu HI\n", childList->length);
}

View File

@@ -1,7 +1,5 @@
#include <vector>
#include "glm/glm.hpp"
#include <glm/gtx/quaternion.hpp>
#include "../gfx/gfx.h"
#include "../lib/raymath.h"
enum EntityFlags {
EntityFlags_Visible=1<<0,
@@ -17,27 +15,27 @@ struct Entity {
};
struct SceneGraphNode {
glm::mat4 local;
glm::mat4 world;
glm::vec3 translation;
glm::quat rotation;
glm::vec3 scale;
std::vector<uint32> children;
Matrix local;
Matrix world;
RLVector3 translation;
Quaternion rotation;
RLVector3 scale;
list<uint32> children;
uint32 entityHandle;
uint32 parentHandle;
};
struct Scene {
uint32 sceneRoot;
std::vector<Entity> entities;
std::vector<SceneGraphNode> graphNodes;
list<Entity> entities;
list<SceneGraphNode> graphNodes;
};
uint32 createEntity(Scene *s);
uint32 createEntity(Arena *arena, Scene *s);
Entity *getEntity(Scene *s);
SceneGraphNode *getSceneGraphNode(Scene *s, int id);
uint32 createSceneGraphNode(Scene *s);
Scene createScene(Scene *s);
uint32 createSceneGraphNode(Arena *arena, Scene *s);
Scene createScene(Arena *arena);
void initGraphNode(SceneGraphNode *n);
void recalcGraphNode(SceneGraphNode *n);
void recalcSceneGraphNode(Scene *s, uint32 parentHandle);