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 = 2) in vec4 color;
layout (location = 3) in float border_radius; layout (location = 3) in float border_radius;
layout (location = 4) in float border_thickness; layout (location = 4) in float border_thickness;
layout (location = 6) in float edge_softness; layout (location = 5) in float edge_softness;
uniform mat4 projection; uniform mat4 projection;

2
build
View File

@@ -1,6 +1,6 @@
#!/bin/bash #!/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 g++ -g -g3 -DOS_LINUX=1 -DENABLE_ASSERT=1 ./src/main.cpp -o ./target/somaesque $LIB_INCLUDE
./target/somaesque ./target/somaesque

View File

@@ -1,11 +1,9 @@
#include <cstring> #include <cstring>
#include <iostream>
#include <string>
#include <vector>
#include "VoxelSpace.h" #include "VoxelSpace.h"
/*
void get_dims_input(int dims[3]) { 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; bool success = false;
while (!success) { while (!success) {
std::cout << "x: "; std::cout << "x: ";
@@ -19,14 +17,16 @@ void get_dims_input(int dims[3]) {
if (size <= 64) { if (size <= 64) {
success = true; success = true;
} else { } else {
std::cout << "That resulted in " << size << " units. Try again.\n"; print("That resulted in %zu units. Try again", size);
} }
std::cin.ignore(); std::cin.ignore();
} }
} }
*/
/*
std::vector<uint64> get_reprs_input(int units_required) { 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>(); std::vector<uint64> reprs = std::vector<uint64>();
int total_units = 0; int total_units = 0;
while (true) { while (true) {
@@ -60,17 +60,19 @@ std::vector<uint64> get_reprs_input(int units_required) {
} }
return reprs; return reprs;
} }
*/
typedef std::vector<uint64> SomaSolution; typedef list<uint64> SomaSolution;
struct Solver { typedef struct Solver {
list<uint64>* input; list<uint64>* input;
list<size_t>* offsets; list<size_t>* offsets;
std::vector<SomaSolution>* solutions; list<SomaSolution>* solutions;
}; } Solver;
uint64 STD_SOMA[] = { 23ul, 30ul, 15ul, 1043ul, 24594ul, 12306ul, 11ul }; uint64 STD_SOMA[] = { 23ul, 30ul, 15ul, 1043ul, 24594ul, 12306ul, 11ul };
/*
void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int> *offsets) { void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int> *offsets) {
size_t num_inputs = offsets->size() - 1; size_t num_inputs = offsets->size() - 1;
@@ -118,88 +120,111 @@ void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int>
} }
std::cout << "Done. Found " << solns.size() << " solutions." << std::endl; 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<uint64> *input = solver->input;
list<size_t> *offsets = solver->offsets; 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 start = offsets->data[curr_piece];
size_t end = offsets->data[curr_piece + 1]; 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++) { for (size_t i = start; i < end; i++) {
bool successful_fuse = !collides(working_solution, input->data[i]); bool successful_fuse = !collides(working_solution, input->data[i]);
if (successful_fuse) { if (successful_fuse) {
uint64 new_working_solution = working_solution | input->data[i]; 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) { if (curr_piece == num_pieces - 1) {
std::vector<uint64> last_soln = solutions->back(); list<uint64> last_soln = solutions->data[solutions->head - 1];
solutions->push_back(SomaSolution(last_soln.begin(), last_soln.end())); 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; return;
} else { } else {
backtrack_solve(solver, new_working_solution, curr_piece + 1); backtrackSolve(arena, solver, new_working_solution, curr_piece + 1);
} }
} }
} }
if (curr_piece == 0) { if (curr_piece == 0) {
solutions->pop_back(); solutions->head -= 1;
} }
} }
std::vector<SomaSolution> get_solution_rotations(Arena *arena, SomaSolution *solution, int dims[3]) { list<SomaSolution> getSolutionRotations(Arena *arena, SomaSolution *solution, int dims[3]) {
std::vector<SomaSolution> result = std::vector<SomaSolution>(NUM_ROTS_3D); list<SomaSolution> result = PushFullList(arena, SomaSolution, NUM_ROTS_3D);
for (int piece_i = 0; piece_i < solution->size(); piece_i++) { 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 = { Space space = {
solution->at(piece_i), solution->data[piece_i],
dims[0], dims[0],
dims[1], dims[1],
dims[2], dims[2],
}; };
list<Space> piece_rotations = getAllRotations(arena, &space); list<Space> pieceRotations = getAllRotations(arena, &space);
for (int rot_i = 0; rot_i < piece_rotations.length; rot_i++) { for (int rot_i = 0; rot_i < pieceRotations.head; rot_i++) {
result[rot_i].push_back(piece_rotations.data[rot_i].space); appendList(&result.data[rot_i], pieceRotations.data[rot_i].space);
} }
} }
return result; return result;
} }
std::vector<SomaSolution> filter_unique(Arena *arena, std::vector<SomaSolution> *solutions, int dims[3]) { list<SomaSolution> filterUnique(Arena *arena, list<SomaSolution> *solutions, int dims[3]) {
if (solutions->size() == 0) { if (solutions->head == 0) {
return std::vector<SomaSolution>(); return list<SomaSolution>{NULL,0,0};
} }
std::vector<SomaSolution> unique_solns = std::vector<SomaSolution>{}; list<SomaSolution> uniqueSolns = PushList(arena, SomaSolution, solutions->head);
for (std::vector<uint64> &solution : *solutions) { for (EachIn(*solutions, i)) {
bool found_match = false; SomaSolution solution = solutions->data[i];
bool foundMatch = false;
Scratch temp = scratchStart(&arena, 1); Scratch temp = scratchStart(&arena, 1);
std::vector<SomaSolution> rots = get_solution_rotations(temp.arena, &solution, dims); list<SomaSolution> rots = getSolutionRotations(temp.arena, &solution, dims);
for (SomaSolution &rotation : rots) { for (EachIn(rots, j)) {
for (std::vector<uint64> &unique_soln : unique_solns) { SomaSolution rotation = rots.data[j];
bool is_match = true; for (EachIn(uniqueSolns, k)) {
for (int piece_i = 0; piece_i < unique_soln.size(); piece_i++) { SomaSolution unique_soln = uniqueSolns.data[k];
if (rotation[piece_i] != unique_soln[piece_i]) { bool isMatch = true;
is_match = false; for (EachIn(unique_soln, piece_i)) {
if (rotation.data[piece_i] != unique_soln.data[piece_i]) {
isMatch = false;
break; break;
} }
} }
if (is_match) { if (isMatch) {
found_match = true; foundMatch = true;
break; break;
} }
} }
if (found_match) { if (foundMatch) {
break; break;
} }
} }
scratchEnd(temp); scratchEnd(temp);
if (!found_match) { if (!foundMatch) {
unique_solns.push_back(SomaSolution(solution)); 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 *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<size_t> offsets = PushList(arena, size_t, reprs_in_count + 1);
@@ -214,12 +239,15 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
appendList(&offsets, (size_t)0); appendList(&offsets, (size_t)0);
list<uint64> positions = {}; uint64 possibleCombos = 0;
{ {
list<uint64> positions = {};
Space space = empty_voxel_space; Space space = empty_voxel_space;
space.space = reprs_in[0]; space.space = reprs_in[0];
cullEmptySpace(&space); cullEmptySpace(&space);
positions = getAllPositionsInPrism(permsArena, &space, dims); positions = getAllPositionsInPrism(permsArena, &space, dims);
possibleCombos += positions.head;
uint64 *insertion = PushArray(arena, uint64, positions.length); uint64 *insertion = PushArray(arena, uint64, positions.length);
polycubes.length += positions.length; polycubes.length += positions.length;
polycubes.head += positions.head; 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]; space.space = reprs_in[i];
cullEmptySpace(&space); cullEmptySpace(&space);
list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims); list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims);
possibleCombos *= perms.head;
uint64 *insertion = PushArray(arena, uint64, perms.length); uint64 *insertion = PushArray(arena, uint64, perms.length);
polycubes.length += perms.length; polycubes.length += perms.length;
polycubes.head += perms.head; polycubes.head += perms.head;
memcpy(insertion, perms.data, perms.length * sizeof(uint64)); 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 = { Solver solver = {
&polycubes, &polycubes,
&offsets, &offsets,
&solutions, &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); //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]);
std::cout << "Great. Calculating solutions...\n"; print("Great. Calculating solutions...\n");
std::vector<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims); list<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
std::cout << solutions.size() << " solutions found." << std::endl; print("%zu solutions found.\n", solutions.head);
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

2670
src/lib/raymath.h Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,44 +1,34 @@
// 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 // Project
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global` #include "SomaSolve.cpp"
#include "gfx/gfx.cpp" #include "gfx/gfx.cpp"
#include "world/world.cpp" #include "world/world.cpp"
#include "VoxelSpace.cpp" #include "VoxelSpace.cpp"
#include "./tests.cpp" #include "./tests.cpp"
#include "lib/djstdlib/core.cpp" #include "lib/djstdlib/core.cpp"
// Graphics bindings and libs
#include "lib/glad/glad.c"
#include <GLFW/glfw3.h>
// Library initialisation // Library initialisation
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include "lib/loaders/stb_image.h" #include "lib/loaders/stb_image.h"
#define TINYOBJ_LOADER_C_IMPLEMENTATION #define TINYOBJ_LOADER_C_IMPLEMENTATION
#include "lib/loaders/tinyobj.h" #include "lib/loaders/tinyobj.h"
#define RAYMATH_IMPLEMENTATION
#include "lib/raymath.h"
#define PI (real32)3.14159265358979323846264338327950288 void print(RLVector3* vector) {
RLVector3 vec = *vector;
void print(glm::vec3* vector) {
glm::vec3 vec = *vector;
print( print(
"┌ ┐\n" "┌ ┐\n"
"│%7.2f%, %7.2f, %7.2f │\n" "│%7.2f%, %7.2f, %7.2f │\n"
"└ ┘\n", "└ ┘\n",
vec[0], vec[1], vec[2]); vec.x, vec.y, vec.z);
} }
void print(glm::mat4* matrix) { void print(Matrix* matrix) {
glm::mat4 mat = *matrix; Matrix mat = *matrix;
print( print(
"┌ ┐\n" "┌ ┐\n"
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n" "│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
@@ -46,36 +36,36 @@ void print(glm::mat4* matrix) {
"│%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", "└ ┘\n",
mat[0][0], mat[0][1], mat[0][2], mat[0][3], mat.m0, mat.m1, mat.m2, mat.m3,
mat[1][0], mat[1][1], mat[1][2], mat[1][3], mat.m4, mat.m5, mat.m6, mat.m7,
mat[2][0], mat[2][1], mat[2][2], mat[2][3], mat.m8, mat.m9, mat.m10, mat.m11,
mat[3][0], mat[3][1], mat[3][2], mat[3][3]); mat.m12, mat.m13, mat.m14, mat.m15);
} }
struct Camera { struct Camera {
glm::mat4 view; Matrix view;
glm::mat4 proj; Matrix proj;
glm::vec3 pos; RLVector3 pos;
glm::vec3 up; RLVector3 up;
glm::vec3 target; RLVector3 target;
}; };
Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) { Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) {
Camera *result = PushStruct(arena, Camera); Camera *result = PushStruct(arena, Camera);
result->view = glm::mat4(); result->view = (Matrix){0};
result->proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f); result->proj = MatrixPerspective(DEG2RAD * 45.0f, aspect_ratio, 0.1f, 100.0f);
result->pos = glm::vec3(0.0f); result->pos = (RLVector3){0};
result->up = glm::vec3(0.0f, 1.0f, 0.0f); result->up = (RLVector3){0,1,0};
return result; return result;
} }
void cameraLookAt(Camera *c, float x, float y, float z) { void cameraLookAt(Camera *c, float x, float y, float z) {
c->target = glm::vec3(x, y, z); c->target = (RLVector3){x, y, z};
c->view = glm::lookAt(c->pos, c->target, c->up); c->view = MatrixLookAt(c->pos, c->target, c->up);
} }
void camera_set_up(Camera *c, real32 up_x, real32 up_y, real32 up_z) { void cameraSetUp(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
c->up = glm::vec3(up_x, up_y, up_z); c->up = (RLVector3){up_x, up_y, up_z};
} }
struct Frame { struct Frame {
@@ -157,8 +147,8 @@ struct SomaState {
uint32 light; uint32 light;
list<Polycube> polycubes; list<Polycube> polycubes;
Camera* camera; Camera* camera;
glm::vec3 rotAxisX; RLVector3 rotAxisX;
glm::vec3 rotAxisY; RLVector3 rotAxisY;
list<PolycubeInput> polycubeInput; list<PolycubeInput> polycubeInput;
}; };
@@ -177,7 +167,8 @@ struct Soma {
void showEntity(Scene *scene, uint32 entityHandle) { void showEntity(Scene *scene, uint32 entityHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, 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); SceneGraphNode *subNode = getSceneGraphNode(scene, child);
if (subNode->entityHandle) { if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible; getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible;
@@ -187,7 +178,8 @@ void showEntity(Scene *scene, uint32 entityHandle) {
void hideEntity(Scene *scene, uint32 entityHandle) { void hideEntity(Scene *scene, uint32 entityHandle) {
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, 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); SceneGraphNode *subNode = getSceneGraphNode(scene, child);
if (subNode->entityHandle) { if (subNode->entityHandle) {
getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible; getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible;
@@ -195,12 +187,14 @@ void hideEntity(Scene *scene, uint32 entityHandle) {
} }
} }
glm::vec3 centreFromPolycube(Scene *scene, Polycube *p) { RLVector3 centreFromPolycube(Scene *scene, Polycube *p) {
glm::vec3 centre = glm::vec3(0.0f); RLVector3 centre = (RLVector3){0,0,0};
for (uint32 &child : getSceneGraphNode(scene, p->entityHandle)->children) { list<uint32> *children = &getSceneGraphNode(scene, p->entityHandle)->children;
centre += getSceneGraphNode(scene, child)->translation; 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; return centre;
} }
@@ -343,33 +337,33 @@ void processInput(Soma *soma) {
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 *= 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; 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 = 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) { Polycube createPolycubeFromRepr(Arena *arena, Scene *s, Space *repr, Vector4<real32> color) {
uint32 polycubeMainEntityHandle = createEntity(s); uint32 polycubeMainEntityHandle = createEntity(arena, s);
Entity *polycubeMainEntity = getEntity(s, polycubeMainEntityHandle); 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(s); uint32 segmentEntityHandle = createEntity(arena, s);
Entity *polycubeSegment = getEntity(s, segmentEntityHandle); Entity *polycubeSegment = getEntity(s, segmentEntityHandle);
polycubeSegment->mesh = &cubeMesh; polycubeSegment->mesh = &cubeMesh;
polycubeSegment->tex = &wallTex; polycubeSegment->tex = &wallTex;
SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle); SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle);
graphNode->translation = glm::vec3( graphNode->translation = RLVector3{
-((repr->dim_z - 1)/2.0f) + z, -((repr->dim_z - 1)/2.0f) + z,
((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); sceneNodeAddEntity(s, polycubeMainEntity->graphNodeHandle, segmentEntityHandle);
} }
} }
@@ -380,8 +374,8 @@ Polycube createPolycubeFromRepr(Scene *s, Space *repr, Vector4<real32> color) {
result.color = color; result.color = color;
result.repr = *repr; result.repr = *repr;
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(s, polycubeMainEntityHandle); SceneGraphNode *graphNode = getSceneGraphNodeForEntity(s, polycubeMainEntityHandle);
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(1, 0, 0)); graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){1, 0, 0}, PI / 4));
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(0, 1, 0)); graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){0, 1, 0}, -PI / 4));
return result; return result;
} }
@@ -471,7 +465,7 @@ void reinitRectangleObjectBuffers(Renderer *r) {
Renderer createRenderer(Arena *arena, Scene *scene) { Renderer createRenderer(Arena *arena, Scene *scene) {
Renderer result = {0}; Renderer result = {0};
result.scene = scene; result.scene = scene;
result.scene->sceneRoot = createSceneGraphNode(scene); result.scene->sceneRoot = createSceneGraphNode(arena, scene);
result.rects = createRectangleObjects(arena, 100); result.rects = createRectangleObjects(arena, 100);
initGraphNode(getSceneGraphNode(scene, scene->sceneRoot)); initGraphNode(getSceneGraphNode(scene, scene->sceneRoot));
return result; return result;
@@ -505,12 +499,13 @@ void renderEnd(Soma *soma, Renderer *renderer) {
setUniform4fv(&phongShader, "solid_color", &currentPolycube->color); setUniform4fv(&phongShader, "solid_color", &currentPolycube->color);
int model_uniform = getUniformLocation(&phongShader, "model"); int model_uniform = getUniformLocation(&phongShader, "model");
for (Entity &entity : renderer->scene->entities) { for (EachIn(renderer->scene->entities, i)) {
if (entity.flags & EntityFlags_Render && entity.flags & EntityFlags_Visible) { Entity *entity = &renderer->scene->entities.data[i];
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity.graphNodeHandle)->world); if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) {
glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id); setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity->graphNodeHandle)->world);
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices); glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
entity.flags &= ~EntityFlags_Render; 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); 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); setUniformMat4fv(&solidColorShader, "projection", &ortho);
glBindVertexArray(renderer->rects.vao); glBindVertexArray(renderer->rects.vao);
@@ -553,18 +548,13 @@ bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
rect.x, rect.y, rect.x, rect.y,
rect.width, rect.height, rect.width, rect.height,
rect.color, rect.color,
5, 0); 5, 2);
} else { } else {
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
rect.color,
5, 2);
rendererPlaceRectangle(ui->renderer, rendererPlaceRectangle(ui->renderer,
rect.x, rect.y, rect.x, rect.y,
rect.width, rect.height, rect.width, rect.height,
COLOR_WHITE, COLOR_WHITE,
5, 0); 5, 2);
} }
return clicked; return clicked;
@@ -602,7 +592,7 @@ void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
} }
} }
int main_cmd() { int mainCmd() {
interactive_cmd_line_solve_soma(); interactive_cmd_line_solve_soma();
return 0; return 0;
} }
@@ -610,7 +600,7 @@ int main_cmd() {
int mainGfx() { int mainGfx() {
Arena *arena = arenaAlloc(Megabytes(128)); Arena *arena = arenaAlloc(Megabytes(128));
Scene mainScene = createScene(); Scene mainScene = createScene(arena);
Soma soma = {}; Soma soma = {};
soma.window.width = 800; soma.window.width = 800;
@@ -634,11 +624,11 @@ int mainGfx() {
soma.state.lastPolycubeVisible = 6; soma.state.lastPolycubeVisible = 6;
soma.state.polycubeInput = PushListZero(arena, PolycubeInput, 64); soma.state.polycubeInput = PushListZero(arena, PolycubeInput, 64);
soma.state.polycubes = PushListZero(arena, Polycube, 64); soma.state.polycubes = PushListZero(arena, Polycube, 64);
soma.state.light = createEntity(&mainScene); soma.state.light = createEntity(arena, &mainScene);
soma.state.camera = mainFrame.cam; soma.state.camera = mainFrame.cam;
SceneGraphNode *light = getSceneGraphNode(&mainScene, getEntity(&mainScene, soma.state.light)->graphNodeHandle); 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( Shader solid_texture_shader = createShader(
@@ -657,24 +647,25 @@ int mainGfx() {
cubeMesh = createMesh("./assets/models/cube.obj"); cubeMesh = createMesh("./assets/models/cube.obj");
wallTex = createTexture("./assets/textures/brick-wall.jpg"); 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 }; Space voxelSpace = { STD_SOMA[i], 3, 3, 3 };
Vector4<real32> color = colorFromIndex(i); Vector4<real32> color = colorFromIndex(i);
appendList(&soma.state.polycubeInput, PolycubeInput{ voxelSpace, color }); appendList(&soma.state.polycubeInput, PolycubeInput{ voxelSpace, color });
cullEmptySpace(&voxelSpace); cullEmptySpace(&voxelSpace);
Polycube polycube = createPolycubeFromRepr(soma.scene, &voxelSpace, color); Polycube polycube = createPolycubeFromRepr(arena, soma.scene, &voxelSpace, color);
polycube.color = color; polycube.color = color;
appendList(&soma.state.polycubes, polycube); appendList(&soma.state.polycubes, polycube);
sceneNodeAddEntity(renderer.scene, renderer.scene->sceneRoot, polycube.entityHandle); 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); 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 = 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)); Matrix worldInverse = MatrixInvert(reference_polycube_gn->world);
glm::vec3 eyes = glm::normalize(soma.state.camera->pos - reference_polycube_gn->translation); soma.state.rotAxisY = Vector3Normalize(RLVector3{worldInverse.m4, worldInverse.m5, worldInverse.m6});
soma.state.rotAxisX = glm::normalize(glm::cross(eyes, soma.state.rotAxisY)); 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 lastFrame = glfwGetTime();
real64 timeDelta = 1.0f/60.0f; real64 timeDelta = 1.0f/60.0f;
@@ -697,7 +688,7 @@ int mainGfx() {
removeEntity(soma.scene, currentPolycube->entityHandle); removeEntity(soma.scene, currentPolycube->entityHandle);
Space culledRepr = pinput->repr; Space culledRepr = pinput->repr;
cullEmptySpace(&culledRepr); 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); SceneGraphNode *graphNode = getSceneGraphNodeForEntity(soma.scene, newPolycube.entityHandle);
graphNode->rotation = getSceneGraphNodeForEntity(soma.scene, currentPolycube->entityHandle)->rotation; graphNode->rotation = getSceneGraphNodeForEntity(soma.scene, currentPolycube->entityHandle)->rotation;
soma.state.polycubes.data[soma.state.currentPolycube] = newPolycube; soma.state.polycubes.data[soma.state.currentPolycube] = newPolycube;

View File

@@ -1,9 +1,12 @@
#include <iostream>
#include <vector>
#include <tuple>
#include "VoxelSpace.h" #include "VoxelSpace.h"
#include "lib/djstdlib/core.h" #include "lib/djstdlib/core.h"
typedef struct MismatchData {
int i;
uint64 actual;
uint64 expected;
} MismatchData;
void test() { void test() {
{ {
Space space = {}; Space space = {};
@@ -107,7 +110,7 @@ void test() {
int prism_dims[] = { 3, 3, 3 }; int prism_dims[] = { 3, 3, 3 };
list<uint64> perms = getAllPermutationsInPrism(arena, &space1, prism_dims); list<uint64> perms = getAllPermutationsInPrism(arena, &space1, prism_dims);
auto expected_perms = std::vector<uint64_t>{ uint64 expected_perms[] = {
30ull, 30ull,
240ull, 240ull,
15360ull, 15360ull,
@@ -182,11 +185,11 @@ void test() {
100761600ull, 100761600ull,
}; };
Assert(expected_perms.size() == perms.length); Assert(ArrayCount(expected_perms) == perms.length);
for (int i = 0; i < perms.length; i++) { for (int i = 0; i < perms.length; i++) {
if (i <= expected_perms.size()) { if (i <= ArrayCount(expected_perms)) {
Assert(expected_perms.at(i) == perms.data[i]); Assert(expected_perms[i] == perms.data[i]);
} }
} }
@@ -276,40 +279,41 @@ void test() {
list<uint64> positions1 = getAllPositionsInPrism(arena, &space1, dims); list<uint64> positions1 = getAllPositionsInPrism(arena, &space1, dims);
list<uint64> positions2 = getAllPositionsInPrism(arena, &space2, dims); list<uint64> positions2 = getAllPositionsInPrism(arena, &space2, dims);
list<uint64> positions3 = getAllPositionsInPrism(arena, &space3, 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>>(); list<MismatchData> mismatches1 = PushList(arena, MismatchData, 6);
auto mismatches3 = std::vector<std::tuple<int, uint64_t, uint64_t>>(); list<MismatchData> mismatches2 = PushList(arena, MismatchData, 6);
list<MismatchData> mismatches3 = PushList(arena, MismatchData, 6);
for (int i = 0; i < 6; i++) { for (int i = 0; i < 6; i++) {
if (positions1.data[i] != expected_results1[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]) { 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]) { 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); Assert(mismatches1.head == 0);
if (mismatches1.size() > 0) { if (mismatches1.head > 0) {
std::cout << "Index - Actual - Expected" << std::endl; print("Index - Actual - Expected\n");
for (auto &mismatch : mismatches1) { for (EachIn(mismatches1, i)) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl; print("%zu - %zu - %zu\n", mismatches1.data[i].i, mismatches1.data[i].actual, mismatches1.data[i].expected);
} }
} }
Assert(mismatches2.size() == 0); Assert(mismatches2.head == 0);
if (mismatches2.size() > 0) { if (mismatches2.head > 0) {
std::cout << "Index - Actual - Expected" << std::endl; print("Index - Actual - Expected\n");
for (auto &mismatch : mismatches2) { for (EachIn(mismatches2, i)) {
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl; print("%zu - %zu - %zu\n", mismatches2.data[i].i, mismatches2.data[i].actual, mismatches2.data[i].expected);
} }
} }
Assert(mismatches3.size() == 0); Assert(mismatches3.head == 0);
if (mismatches3.size() > 0) { if (mismatches3.head > 0) {
std::cout << "Index - Actual - Expected" << std::endl; print("Index - Actual - Expected\n");
for (auto &mismatch : mismatches3) { for (EachIn(mismatches3, i)) {
std::cout << "At " << std::get<0>(mismatch) << ": " << std::get<1>(mismatch) << " != " << std::get<2>(mismatch) << std::endl; 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" #include "scene.h"
Entity *getEntity(Scene *s, uint32 id) { Entity *getEntity(Scene *s, uint32 id) {
return &s->entities[id - 1]; return &s->entities.data[id - 1];
} }
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) { 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) { SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
return &s->graphNodes[sceneGraphNodeHandle - 1]; return &s->graphNodes.data[sceneGraphNodeHandle - 1];
} }
uint32 createEntity(Scene *s) { uint32 createSceneGraphNode(Arena *arena, Scene *s) {
s->entities.emplace_back(); appendList(&s->graphNodes, (SceneGraphNode){0});
s->graphNodes.emplace_back(); s->graphNodes.data[s->graphNodes.head - 1].children = PushList(arena, uint32, 64);
s->entities.back().graphNodeHandle = (uint32)s->graphNodes.size(); return (uint32)s->graphNodes.head;
s->graphNodes.back().entityHandle = (uint32)s->entities.size(); }
uint32 handle = (uint32)s->entities.size();
uint32 graphNodeHandle = (uint32)s->graphNodes.size(); 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)); initGraphNode(getSceneGraphNode(s, graphNodeHandle));
return handle; return handle;
} }
uint32 createSceneGraphNode(Scene *s) {
s->graphNodes.emplace_back();
return (uint32)s->graphNodes.size();
}
void initGraphNode(SceneGraphNode *n) { void initGraphNode(SceneGraphNode *n) {
n->scale = glm::vec3(1.0f, 1.0f, 1.0f); n->scale = RLVector3{1.0f, 1.0f, 1.0f};
n->translation = glm::vec3(0.0f, 0.0f, 0.0f); n->translation = RLVector3{0.0f, 0.0f, 0.0f};
n->rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f); n->rotation = Quaternion{1.0f, 0.0f, 0.0f, 0.0f};
n->local = glm::mat4(1.0f); n->local = MatrixIdentity();
n->world = n->local; n->world = n->local;
} }
void recalcGraphNode(SceneGraphNode *n) { void recalcGraphNode(SceneGraphNode *n) {
n->local = glm::scale( n->local = MatrixCompose(n->translation, n->rotation, n->scale);
glm::translate(
glm::mat4(1.0f),
n->translation
) * glm::toMat4(n->rotation),
n->scale
);
} }
Scene createScene() { Scene createScene(Arena *arena) {
Scene result = {}; 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; return result;
} }
@@ -57,11 +55,12 @@ void recalcSceneGraphNode(Scene *s, uint32 parentHandle) {
if (node->entityHandle) { if (node->entityHandle) {
getEntity(s, node->entityHandle)->flags |= EntityFlags_Render; 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); SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
graphNode->parentHandle = parentHandle; graphNode->parentHandle = parentHandle;
recalcGraphNode(graphNode); recalcGraphNode(graphNode);
graphNode->world = node->world * graphNode->local; graphNode->world = MatrixMultiply(graphNode->local, node->world);
recalcSceneGraphNode(s, nodeId); recalcSceneGraphNode(s, nodeId);
} }
} }
@@ -76,9 +75,10 @@ void removeEntity(Scene *s, uint32 entityHandle) {
SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle); SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle);
if (graphNode->parentHandle) { if (graphNode->parentHandle) {
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle); SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
for (int i = 0; i < parentNode->children.size(); i++) { for (int i = 0; i < parentNode->children.head; i++) {
if (parentNode->children.at(i) == entity->graphNodeHandle) { if (parentNode->children.data[i] == entity->graphNodeHandle) {
parentNode->children.erase(parentNode->children.begin() + i); memcpy(&parentNode->children.data[i], &parentNode->children.data[i + 1], parentNode->children.head - i);
parentNode->children.head -= 1;
graphNode->parentHandle = 0; graphNode->parentHandle = 0;
break; break;
} }
@@ -87,5 +87,7 @@ void removeEntity(Scene *s, uint32 entityHandle) {
} }
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, 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 "../gfx/gfx.h"
#include "../lib/raymath.h"
enum EntityFlags { enum EntityFlags {
EntityFlags_Visible=1<<0, EntityFlags_Visible=1<<0,
@@ -17,27 +15,27 @@ struct Entity {
}; };
struct SceneGraphNode { struct SceneGraphNode {
glm::mat4 local; Matrix local;
glm::mat4 world; Matrix world;
glm::vec3 translation; RLVector3 translation;
glm::quat rotation; Quaternion rotation;
glm::vec3 scale; RLVector3 scale;
std::vector<uint32> children; list<uint32> children;
uint32 entityHandle; uint32 entityHandle;
uint32 parentHandle; uint32 parentHandle;
}; };
struct Scene { struct Scene {
uint32 sceneRoot; uint32 sceneRoot;
std::vector<Entity> entities; list<Entity> entities;
std::vector<SceneGraphNode> graphNodes; list<SceneGraphNode> graphNodes;
}; };
uint32 createEntity(Scene *s); uint32 createEntity(Arena *arena, Scene *s);
Entity *getEntity(Scene *s); Entity *getEntity(Scene *s);
SceneGraphNode *getSceneGraphNode(Scene *s, int id); SceneGraphNode *getSceneGraphNode(Scene *s, int id);
uint32 createSceneGraphNode(Scene *s); uint32 createSceneGraphNode(Arena *arena, Scene *s);
Scene createScene(Scene *s); Scene createScene(Arena *arena);
void initGraphNode(SceneGraphNode *n); void initGraphNode(SceneGraphNode *n);
void recalcGraphNode(SceneGraphNode *n); void recalcGraphNode(SceneGraphNode *n);
void recalcSceneGraphNode(Scene *s, uint32 parentHandle); void recalcSceneGraphNode(Scene *s, uint32 parentHandle);