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,94 +120,117 @@ 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)) {
Space space = { result.data[i] = PushList(arena, uint64, solution->head);
solution->at(piece_i), }
for (int piece_i = 0; piece_i < solution->head; piece_i++) {
Space space = {
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);
list<uint64> polycubes = PushList(arena, uint64, 0); list<uint64> polycubes = PushList(arena, uint64, 0);
Space empty_voxel_space = { Space empty_voxel_space = {
{}, {},
dims[0], dims[0],
dims[1], dims[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,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 // 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"
"│%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"
"│%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 {
@@ -146,7 +136,7 @@ struct Renderer {
struct PolycubeInput { struct PolycubeInput {
Space repr; Space repr;
Vector4<real32> color; Vector4<real32> color;
}; };
struct SomaState { struct SomaState {
@@ -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;
} }
@@ -315,7 +309,7 @@ void processInput(Soma *soma) {
if (input->keyboard.escape) { if (input->keyboard.escape) {
glfwSetWindowShouldClose(soma->window.handle, true); glfwSetWindowShouldClose(soma->window.handle, true);
} }
if (input->keyboard.space && !prevInput->keyboard.space) { if (input->keyboard.space && !prevInput->keyboard.space) {
glPolygonMode(GL_FRONT_AND_BACK, !soma->state.wireframe ? GL_LINE : GL_FILL); 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; 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);
@@ -549,22 +544,17 @@ bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
} }
} }
if (*value) { if (*value) {
rendererPlaceRectangle(ui->renderer, rendererPlaceRectangle(ui->renderer,
rect.x, rect.y, rect.x, rect.y,
rect.width, rect.height, rect.width, rect.height,
rect.color,
5, 0);
} else {
rendererPlaceRectangle(ui->renderer,
rect.x, rect.y,
rect.width, rect.height,
rect.color, rect.color,
5, 2); 5, 2);
rendererPlaceRectangle(ui->renderer, } else {
rect.x, rect.y, rendererPlaceRectangle(ui->renderer,
rect.width, rect.height, rect.x, rect.y,
rect.width, rect.height,
COLOR_WHITE, COLOR_WHITE,
5, 0); 5, 2);
} }
return clicked; 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++) { for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
bool cellActive = filledAt(&currentPolycube->repr, x, y, z); bool cellActive = filledAt(&currentPolycube->repr, x, y, z);
UI_Rect rect = { UI_Rect rect = {
currX, currX,
currY, currY,
boxSize, boxSize,
boxSize, boxSize,
0, 0,
currentPolycube->color, 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(); 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,47 +624,48 @@ 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(
"./assets/shaders/2d.vertex.glsl"_s, "./assets/shaders/2d.vertex.glsl"_s,
"./assets/shaders/2d-tex.fragment.glsl"_s); "./assets/shaders/2d-tex.fragment.glsl"_s);
*/ */
solidColorShader = createShader( solidColorShader = createShader(
"./assets/shaders/2d-solid.vertex.glsl"_s, "./assets/shaders/2d-solid.vertex.glsl"_s,
"./assets/shaders/2d-solid.fragment.glsl"_s); "./assets/shaders/2d-solid.fragment.glsl"_s);
phongShader = createShader( phongShader = createShader(
"./assets/shaders/phong-solid.vertex.glsl"_s, "./assets/shaders/phong-solid.vertex.glsl"_s,
"./assets/shaders/phong-solid.fragment.glsl"_s); "./assets/shaders/phong-solid.fragment.glsl"_s);
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;
@@ -695,9 +686,9 @@ int mainGfx() {
Polycube *currentPolycube = &soma.state.polycubes.data[soma.state.currentPolycube]; Polycube *currentPolycube = &soma.state.polycubes.data[soma.state.currentPolycube];
PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube]; PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube];
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,13 +1,16 @@
#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 = {};
space.space=23ull; space.space=23ull;
space.dim_x=3; space.dim_x=3;
space.dim_y=3; space.dim_y=3;
space.dim_z=3; space.dim_z=3;
@@ -107,86 +110,86 @@ 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,
122880ull, 122880ull,
7864320ull, 7864320ull,
62914560ull, 62914560ull,
153ull, 153ull,
306ull, 306ull,
78336ull, 78336ull,
156672ull, 156672ull,
40108032ull, 40108032ull,
80216064ull, 80216064ull,
266760ull, 266760ull,
533520ull, 533520ull,
1067040ull, 1067040ull,
2134080ull, 2134080ull,
4268160ull, 4268160ull,
8536320ull, 8536320ull,
263682ull, 263682ull,
527364ull, 527364ull,
2109456ull, 2109456ull,
4218912ull, 4218912ull,
16875648ull, 16875648ull,
33751296ull, 33751296ull,
2101761ull, 2101761ull,
4203522ull, 4203522ull,
8407044ull, 8407044ull,
16814088ull, 16814088ull,
33628176ull, 33628176ull,
67256352ull, 67256352ull,
525825ull, 525825ull,
1051650ull, 1051650ull,
4206600ull, 4206600ull,
8413200ull, 8413200ull,
33652800ull, 33652800ull,
67305600ull, 67305600ull,
51ull, 51ull,
408ull, 408ull,
26112ull, 26112ull,
208896ull, 208896ull,
13369344ull, 13369344ull,
106954752ull, 106954752ull,
90ull, 90ull,
180ull, 180ull,
46080ull, 46080ull,
92160ull, 92160ull,
23592960ull, 23592960ull,
47185920ull, 47185920ull,
4680ull, 4680ull,
9360ull, 9360ull,
18720ull, 18720ull,
2396160ull, 2396160ull,
4792320ull, 4792320ull,
9584640ull, 9584640ull,
1542ull, 1542ull,
12336ull, 12336ull,
98688ull, 98688ull,
789504ull, 789504ull,
6316032ull, 6316032ull,
50528256ull, 50528256ull,
36873ull, 36873ull,
73746ull, 73746ull,
147492ull, 147492ull,
18878976ull, 18878976ull,
37757952ull, 37757952ull,
75515904ull, 75515904ull,
3075ull, 3075ull,
24600ull, 24600ull,
196800ull, 196800ull,
1574400ull, 1574400ull,
12595200ull, 12595200ull,
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]);
} }
} }
@@ -194,20 +197,20 @@ void test() {
} }
{ {
Space space1 = {}; Space space1 = {};
space1.space=30ull; space1.space=30ull;
space1.dim_x=3; space1.dim_x=3;
space1.dim_y=3; space1.dim_y=3;
space1.dim_z=3; space1.dim_z=3;
Space space2 = {}; Space space2 = {};
space2.space=30ull; space2.space=30ull;
space2.dim_x=3; space2.dim_x=3;
space2.dim_y=3; space2.dim_y=3;
space2.dim_z=3; space2.dim_z=3;
Space space3 = {}; Space space3 = {};
space3.space=30ull; space3.space=30ull;
space3.dim_x=3; space3.dim_x=3;
space3.dim_y=3; space3.dim_y=3;
space3.dim_z=3; space3.dim_z=3;
@@ -258,7 +261,7 @@ void test() {
}; };
Space space3 = {}; Space space3 = {};
space3.space=15ull; space3.space=15ull;
space3.dim_x=3; space3.dim_x=3;
space3.dim_y=3; space3.dim_y=3;
space3.dim_z=3; space3.dim_z=3;
@@ -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);