mostly migrated for c compatibility
This commit is contained in:
@@ -4,7 +4,7 @@ layout (location = 1) in vec2 p1;
|
||||
layout (location = 2) in vec4 color;
|
||||
layout (location = 3) in float border_radius;
|
||||
layout (location = 4) in float border_thickness;
|
||||
layout (location = 6) in float edge_softness;
|
||||
layout (location = 5) in float edge_softness;
|
||||
|
||||
uniform mat4 projection;
|
||||
|
||||
|
||||
2
build
2
build
@@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
|
||||
LIB_INCLUDE="-lglfw -lGL"
|
||||
LIB_INCLUDE="-lglfw -lGL -lm"
|
||||
g++ -g -g3 -DOS_LINUX=1 -DENABLE_ASSERT=1 ./src/main.cpp -o ./target/somaesque $LIB_INCLUDE
|
||||
./target/somaesque
|
||||
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "VoxelSpace.h"
|
||||
|
||||
/*
|
||||
void get_dims_input(int dims[3]) {
|
||||
std::cout << "Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n";
|
||||
print("Enter dimensions separated by newlines. (x*y*z must not exceed 64)\n");
|
||||
bool success = false;
|
||||
while (!success) {
|
||||
std::cout << "x: ";
|
||||
@@ -19,14 +17,16 @@ void get_dims_input(int dims[3]) {
|
||||
if (size <= 64) {
|
||||
success = true;
|
||||
} else {
|
||||
std::cout << "That resulted in " << size << " units. Try again.\n";
|
||||
print("That resulted in %zu units. Try again", size);
|
||||
}
|
||||
std::cin.ignore();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
std::vector<uint64> get_reprs_input(int units_required) {
|
||||
std::cout << "Enter bit-representations (big endian, max 64 bits, total 1s must add up to " << units_required << "). press ENTER twice to finish input.\n";
|
||||
print("Enter bit-representations (big endian, max 64 bits, total 1s must add up to %zu). press ENTER twice to finish input.\n", units_required );
|
||||
std::vector<uint64> reprs = std::vector<uint64>();
|
||||
int total_units = 0;
|
||||
while (true) {
|
||||
@@ -60,17 +60,19 @@ std::vector<uint64> get_reprs_input(int units_required) {
|
||||
}
|
||||
return reprs;
|
||||
}
|
||||
*/
|
||||
|
||||
typedef std::vector<uint64> SomaSolution;
|
||||
typedef list<uint64> SomaSolution;
|
||||
|
||||
struct Solver {
|
||||
typedef struct Solver {
|
||||
list<uint64>* input;
|
||||
list<size_t>* offsets;
|
||||
std::vector<SomaSolution>* solutions;
|
||||
};
|
||||
list<SomaSolution>* solutions;
|
||||
} Solver;
|
||||
|
||||
uint64 STD_SOMA[] = { 23ul, 30ul, 15ul, 1043ul, 24594ul, 12306ul, 11ul };
|
||||
|
||||
/*
|
||||
void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int> *offsets) {
|
||||
size_t num_inputs = offsets->size() - 1;
|
||||
|
||||
@@ -118,94 +120,117 @@ void backtrack_solve_iter(std::vector<uint64> *polycube_input, std::vector<int>
|
||||
}
|
||||
std::cout << "Done. Found " << solns.size() << " solutions." << std::endl;
|
||||
}
|
||||
*/
|
||||
|
||||
void backtrack_solve(Solver *solver, uint64 working_solution = 0, size_t curr_piece = 0) {
|
||||
void backtrackSolve(Arena *arena, Solver *solver, uint64 working_solution = 0, size_t curr_piece = 0) {
|
||||
list<uint64> *input = solver->input;
|
||||
list<size_t> *offsets = solver->offsets;
|
||||
std::vector<SomaSolution> *solutions = solver->solutions;
|
||||
list<SomaSolution> *solutions = solver->solutions;
|
||||
size_t start = offsets->data[curr_piece];
|
||||
size_t end = offsets->data[curr_piece + 1];
|
||||
size_t num_pieces = offsets->length - 1;
|
||||
size_t num_pieces = offsets->head - 1;
|
||||
for (size_t i = start; i < end; i++) {
|
||||
bool successful_fuse = !collides(working_solution, input->data[i]);
|
||||
if (successful_fuse) {
|
||||
uint64 new_working_solution = working_solution | input->data[i];
|
||||
solutions->back().at(curr_piece) = input->data[i];
|
||||
solutions->data[solutions->head - 1].data[curr_piece] = input->data[i];
|
||||
if (curr_piece == num_pieces - 1) {
|
||||
std::vector<uint64> last_soln = solutions->back();
|
||||
solutions->push_back(SomaSolution(last_soln.begin(), last_soln.end()));
|
||||
list<uint64> last_soln = solutions->data[solutions->head - 1];
|
||||
list<uint64> last_soln_copy = PushList(arena, uint64, last_soln.head);
|
||||
last_soln_copy.length = last_soln.head;
|
||||
last_soln_copy.head = last_soln.head;
|
||||
memcpy(last_soln_copy.data, last_soln.data, last_soln.head * sizeof(uint64));
|
||||
appendList(solutions, last_soln_copy);
|
||||
return;
|
||||
} else {
|
||||
backtrack_solve(solver, new_working_solution, curr_piece + 1);
|
||||
backtrackSolve(arena, solver, new_working_solution, curr_piece + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (curr_piece == 0) {
|
||||
solutions->pop_back();
|
||||
}
|
||||
solutions->head -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<SomaSolution> get_solution_rotations(Arena *arena, SomaSolution *solution, int dims[3]) {
|
||||
std::vector<SomaSolution> result = std::vector<SomaSolution>(NUM_ROTS_3D);
|
||||
for (int piece_i = 0; piece_i < solution->size(); piece_i++) {
|
||||
Space space = {
|
||||
solution->at(piece_i),
|
||||
list<SomaSolution> getSolutionRotations(Arena *arena, SomaSolution *solution, int dims[3]) {
|
||||
list<SomaSolution> result = PushFullList(arena, SomaSolution, NUM_ROTS_3D);
|
||||
for (EachIn(result, i)) {
|
||||
result.data[i] = PushList(arena, uint64, solution->head);
|
||||
}
|
||||
for (int piece_i = 0; piece_i < solution->head; piece_i++) {
|
||||
Space space = {
|
||||
solution->data[piece_i],
|
||||
dims[0],
|
||||
dims[1],
|
||||
dims[2],
|
||||
};
|
||||
list<Space> piece_rotations = getAllRotations(arena, &space);
|
||||
for (int rot_i = 0; rot_i < piece_rotations.length; rot_i++) {
|
||||
result[rot_i].push_back(piece_rotations.data[rot_i].space);
|
||||
list<Space> pieceRotations = getAllRotations(arena, &space);
|
||||
for (int rot_i = 0; rot_i < pieceRotations.head; rot_i++) {
|
||||
appendList(&result.data[rot_i], pieceRotations.data[rot_i].space);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<SomaSolution> filter_unique(Arena *arena, std::vector<SomaSolution> *solutions, int dims[3]) {
|
||||
if (solutions->size() == 0) {
|
||||
return std::vector<SomaSolution>();
|
||||
list<SomaSolution> filterUnique(Arena *arena, list<SomaSolution> *solutions, int dims[3]) {
|
||||
if (solutions->head == 0) {
|
||||
return list<SomaSolution>{NULL,0,0};
|
||||
}
|
||||
std::vector<SomaSolution> unique_solns = std::vector<SomaSolution>{};
|
||||
for (std::vector<uint64> &solution : *solutions) {
|
||||
bool found_match = false;
|
||||
list<SomaSolution> uniqueSolns = PushList(arena, SomaSolution, solutions->head);
|
||||
for (EachIn(*solutions, i)) {
|
||||
SomaSolution solution = solutions->data[i];
|
||||
bool foundMatch = false;
|
||||
Scratch temp = scratchStart(&arena, 1);
|
||||
std::vector<SomaSolution> rots = get_solution_rotations(temp.arena, &solution, dims);
|
||||
for (SomaSolution &rotation : rots) {
|
||||
for (std::vector<uint64> &unique_soln : unique_solns) {
|
||||
bool is_match = true;
|
||||
for (int piece_i = 0; piece_i < unique_soln.size(); piece_i++) {
|
||||
if (rotation[piece_i] != unique_soln[piece_i]) {
|
||||
is_match = false;
|
||||
list<SomaSolution> rots = getSolutionRotations(temp.arena, &solution, dims);
|
||||
for (EachIn(rots, j)) {
|
||||
SomaSolution rotation = rots.data[j];
|
||||
for (EachIn(uniqueSolns, k)) {
|
||||
SomaSolution unique_soln = uniqueSolns.data[k];
|
||||
bool isMatch = true;
|
||||
for (EachIn(unique_soln, piece_i)) {
|
||||
if (rotation.data[piece_i] != unique_soln.data[piece_i]) {
|
||||
isMatch = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_match) {
|
||||
found_match = true;
|
||||
if (isMatch) {
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found_match) {
|
||||
if (foundMatch) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
scratchEnd(temp);
|
||||
if (!found_match) {
|
||||
unique_solns.push_back(SomaSolution(solution));
|
||||
if (!foundMatch) {
|
||||
SomaSolution solutionCopy = PushList(arena, uint64, solution.head);
|
||||
solutionCopy.length = solution.head;
|
||||
solutionCopy.head = solution.head;
|
||||
memcpy(solutionCopy.data, solution.data, solution.head * sizeof(uint64));
|
||||
appendList(&uniqueSolns, solutionCopy);
|
||||
}
|
||||
}
|
||||
return unique_solns;
|
||||
return uniqueSolns;
|
||||
}
|
||||
|
||||
std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
|
||||
uint64 factorial(int n) {
|
||||
uint64 result = 1;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
result *= i;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
list<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dims[3]) {
|
||||
Arena *arena = arenaAlloc(Megabytes(64));
|
||||
Arena *permsArena = arenaAlloc(Megabytes(64));
|
||||
Arena *permsArena = arenaAlloc(Megabytes(128));
|
||||
|
||||
list<size_t> offsets = PushList(arena, size_t, reprs_in_count + 1);
|
||||
|
||||
list<uint64> polycubes = PushList(arena, uint64, 0);
|
||||
|
||||
Space empty_voxel_space = {
|
||||
Space empty_voxel_space = {
|
||||
{},
|
||||
dims[0],
|
||||
dims[1],
|
||||
@@ -214,12 +239,15 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
|
||||
|
||||
appendList(&offsets, (size_t)0);
|
||||
|
||||
list<uint64> positions = {};
|
||||
uint64 possibleCombos = 0;
|
||||
|
||||
{
|
||||
list<uint64> positions = {};
|
||||
Space space = empty_voxel_space;
|
||||
space.space = reprs_in[0];
|
||||
cullEmptySpace(&space);
|
||||
positions = getAllPositionsInPrism(permsArena, &space, dims);
|
||||
possibleCombos += positions.head;
|
||||
uint64 *insertion = PushArray(arena, uint64, positions.length);
|
||||
polycubes.length += positions.length;
|
||||
polycubes.head += positions.head;
|
||||
@@ -232,24 +260,28 @@ std::vector<SomaSolution> solve(uint64 *reprs_in, uint32 reprs_in_count, int dim
|
||||
space.space = reprs_in[i];
|
||||
cullEmptySpace(&space);
|
||||
list<uint64> perms = getAllPermutationsInPrism(permsArena, &space, dims);
|
||||
possibleCombos *= perms.head;
|
||||
uint64 *insertion = PushArray(arena, uint64, perms.length);
|
||||
polycubes.length += perms.length;
|
||||
polycubes.head += perms.head;
|
||||
memcpy(insertion, perms.data, perms.length * sizeof(uint64));
|
||||
}
|
||||
|
||||
appendList(&offsets, polycubes.length);
|
||||
appendList(&offsets, polycubes.head);
|
||||
|
||||
list<SomaSolution> solutions = PushList(permsArena, SomaSolution, (size_t)floor(sqrt(possibleCombos)));
|
||||
SomaSolution initialSoln = PushFullList(permsArena, uint64, reprs_in_count);
|
||||
appendList(&solutions, initialSoln);
|
||||
|
||||
std::vector<SomaSolution> solutions = {std::vector<uint64>(reprs_in_count)};
|
||||
Solver solver = {
|
||||
&polycubes,
|
||||
&offsets,
|
||||
&solutions,
|
||||
};
|
||||
|
||||
backtrack_solve(&solver);
|
||||
backtrackSolve(permsArena, &solver);
|
||||
|
||||
return filter_unique(arena, solver.solutions, dims);
|
||||
return filterUnique(permsArena, solver.solutions, dims);
|
||||
}
|
||||
|
||||
|
||||
@@ -258,7 +290,7 @@ void interactive_cmd_line_solve_soma() {
|
||||
//get_dims_input(dims);
|
||||
//std::cout << '\n';
|
||||
//std::vector<uint64> reprs = get_reprs_input(dims[0]*dims[1]*dims[2]);
|
||||
std::cout << "Great. Calculating solutions...\n";
|
||||
std::vector<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
|
||||
std::cout << solutions.size() << " solutions found." << std::endl;
|
||||
print("Great. Calculating solutions...\n");
|
||||
list<SomaSolution> solutions = solve(STD_SOMA, ArrayCount(STD_SOMA), dims);
|
||||
print("%zu solutions found.\n", solutions.head);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include "lib/djstdlib/core.h"
|
||||
|
||||
extern std::vector<uint64_t> STD_SOMA;
|
||||
typedef std::vector<uint64_t> SomaSolution;
|
||||
std::vector<SomaSolution> solve(std::vector<uint64_t> *reprs_in, int dims[3]);
|
||||
void interactive_cmd_line_solve_soma();
|
||||
extern uint64 STD_SOMA[];
|
||||
typedef list<uint64> SomaSolution;
|
||||
list<SomaSolution> solve(list<uint64> *reprs_in, int dims[3]);
|
||||
void interactive_cmd_line_solve_soma();
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#ifndef VOXELSPACE_H
|
||||
#define VOXELSPACE_H
|
||||
|
||||
#include <vector>
|
||||
#include "lib/djstdlib/core.h"
|
||||
|
||||
constexpr int NUM_ROTS_3D = 24;
|
||||
@@ -51,7 +50,7 @@ void rotate90Y(Space *space);
|
||||
|
||||
void rotate90Z(Space *space);
|
||||
|
||||
void pushNewUniqueSpins(std::vector<Space> *existingSpaces, Space* spaceToSpin);
|
||||
void pushNewUniqueSpins(list<Space> *existingSpaces, Space* spaceToSpin);
|
||||
|
||||
list<Space> getUniqueRotations(Arena *arena, Space *space);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include <math.h>
|
||||
#include "math.h"
|
||||
#include "Color.h"
|
||||
|
||||
real32 hueToRGB(real32 p, real32 q, real32 t) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include "Shader.h"
|
||||
#include "../lib/djstdlib/core.h"
|
||||
#include "../lib/djstdlib/os.h"
|
||||
#include "../lib/glad/glad.h"
|
||||
#include "../lib/raymath.h"
|
||||
|
||||
enum ShaderType {
|
||||
fragment=GL_FRAGMENT_SHADER,
|
||||
@@ -60,43 +60,43 @@ Shader createShader(string vertex_path, string fragment_path) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix) {
|
||||
void setUniformMat4fv(Shader *s, const char *uniformName, Matrix *matrix) {
|
||||
glUniformMatrix4fv(
|
||||
glGetUniformLocation(s->progId, uniformName),
|
||||
1, GL_FALSE, glm::value_ptr(*matrix));
|
||||
glGetUniformLocation(s->progId, uniformName),
|
||||
1, GL_FALSE, MatrixToFloat(*matrix));
|
||||
}
|
||||
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix) {
|
||||
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, glm::value_ptr(*matrix));
|
||||
void setUniformMat4fv(int uniformLocation, Matrix *matrix) {
|
||||
glUniformMatrix4fv(uniformLocation, 1, GL_FALSE, MatrixToFloat(*matrix));
|
||||
}
|
||||
|
||||
void setUniform4fv(Shader *s, const char *uniformName, Vector4<real32> *vector) {
|
||||
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||
}
|
||||
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector) {
|
||||
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||
void setUniform4fv(Shader *s, const char *uniformName, RLVector4 *vector) {
|
||||
glUniform4fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector);
|
||||
}
|
||||
void setUniform4fv(int uniformLocation, glm::vec4 *vector) {
|
||||
glUniform4fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||
void setUniform4fv(int uniformLocation, RLVector4 *vector) {
|
||||
glUniform4fv(uniformLocation, 1, (const GLfloat *)vector);
|
||||
}
|
||||
|
||||
void setUniform3fv(Shader *s, const char *uniformName, Vector3<real32> *vector) {
|
||||
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||
}
|
||||
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector) {
|
||||
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||
void setUniform3fv(Shader *s, const char *uniformName, RLVector3 *vector) {
|
||||
glUniform3fv(glGetUniformLocation(s->progId, uniformName), 1, Vector3ToFloat(*vector));
|
||||
}
|
||||
void setUniform3fv(int uniformLocation, glm::vec3 *vector) {
|
||||
glUniform3fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||
void setUniform3fv(int uniformLocation, RLVector3 *vector) {
|
||||
glUniform3fv(uniformLocation, 1, Vector3ToFloat(*vector));
|
||||
}
|
||||
|
||||
void setUniform2fv(Shader *s, const char *uniformName, Vector2<real32> *vector) {
|
||||
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, vector->vec);
|
||||
}
|
||||
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector) {
|
||||
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, glm::value_ptr(*vector));
|
||||
void setUniform2fv(Shader *s, const char *uniformName, RLVector2 *vector) {
|
||||
glUniform2fv(glGetUniformLocation(s->progId, uniformName), 1, (const GLfloat *)vector);
|
||||
}
|
||||
void setUniform2fv(int uniformLocation, glm::vec2 *vector) {
|
||||
glUniform2fv(uniformLocation, 1, glm::value_ptr(*vector));
|
||||
void setUniform2fv(int uniformLocation, RLVector2 *vector) {
|
||||
glUniform2fv(uniformLocation, 1, (const GLfloat *)vector);
|
||||
}
|
||||
|
||||
int getUniformLocation(Shader *s, const char *uniformName) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef LEDDA_SHADER_H
|
||||
#define LEDDA_SHADER_H
|
||||
|
||||
#include "glm/glm.hpp"
|
||||
#include "../lib/raymath.h"
|
||||
#include "../lib/djstdlib/core.h"
|
||||
|
||||
struct Shader {
|
||||
@@ -10,17 +10,17 @@ struct Shader {
|
||||
|
||||
Shader createShader(string vertex_path, string fragment_path);
|
||||
|
||||
void setUniformMat4fv(Shader *s, const char *uniformName, glm::mat4 *matrix);
|
||||
void setUniformMat4fv(int uniformLocation, glm::mat4 *matrix);
|
||||
void setUniformMat4fv(Shader *s, const char *uniformName, Matrix *matrix);
|
||||
void setUniformMat4fv(int uniformLocation, Matrix *matrix);
|
||||
|
||||
void setUniform4fv(Shader *s, const char *uniformName, glm::vec4 *vector);
|
||||
void setUniform4fv(int uniformLocation, glm::vec4 *vector);
|
||||
void setUniform4fv(Shader *s, const char *uniformName, RLVector4 *vector);
|
||||
void setUniform4fv(int uniformLocation, RLVector4 *vector);
|
||||
|
||||
void setUniform3fv(Shader *s, const char *uniformName, glm::vec3 *vector);
|
||||
void setUniform3fv(int uniformLocation, glm::vec3 *vector);
|
||||
void setUniform3fv(Shader *s, const char *uniformName, RLVector3 *vector);
|
||||
void setUniform3fv(int uniformLocation, RLVector3 *vector);
|
||||
|
||||
void setUniform2fv(Shader *s, const char *uniformName, glm::vec2 *vector);
|
||||
void setUniform2fv(int uniformLocation, glm::vec2 *vector);
|
||||
void setUniform2fv(Shader *s, const char *uniformName, RLVector2 *vector);
|
||||
void setUniform2fv(int uniformLocation, RLVector2 *vector);
|
||||
|
||||
int getUniformLocation(Shader *s, const char *uniformName);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef LEDDA_GEOMETRY_H
|
||||
#define LEDDA_GEOMETRY_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include "stddef.h"
|
||||
|
||||
struct Shape {
|
||||
unsigned int* indices;
|
||||
|
||||
2670
src/lib/raymath.h
Normal file
2670
src/lib/raymath.h
Normal file
File diff suppressed because it is too large
Load Diff
197
src/main.cpp
197
src/main.cpp
@@ -1,81 +1,71 @@
|
||||
// stdlib
|
||||
// TODO(djledda): get rid of this
|
||||
#include <vector>
|
||||
|
||||
// Graphics bindings and libs
|
||||
#include "lib/glad/glad.c"
|
||||
#include <GLFW/glfw3.h>
|
||||
#define GLM_ENABLE_EXPERIMENTAL
|
||||
#include <glm/ext/matrix_transform.hpp>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
// Project
|
||||
#include "SomaSolve.cpp" // errors from iostream also defining the keyword `global`
|
||||
#include "SomaSolve.cpp"
|
||||
#include "gfx/gfx.cpp"
|
||||
#include "world/world.cpp"
|
||||
#include "VoxelSpace.cpp"
|
||||
#include "./tests.cpp"
|
||||
#include "lib/djstdlib/core.cpp"
|
||||
|
||||
// Graphics bindings and libs
|
||||
#include "lib/glad/glad.c"
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
// Library initialisation
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "lib/loaders/stb_image.h"
|
||||
#define TINYOBJ_LOADER_C_IMPLEMENTATION
|
||||
#include "lib/loaders/tinyobj.h"
|
||||
#define RAYMATH_IMPLEMENTATION
|
||||
#include "lib/raymath.h"
|
||||
|
||||
#define PI (real32)3.14159265358979323846264338327950288
|
||||
|
||||
void print(glm::vec3* vector) {
|
||||
glm::vec3 vec = *vector;
|
||||
void print(RLVector3* vector) {
|
||||
RLVector3 vec = *vector;
|
||||
print(
|
||||
"┌ ┐\n"
|
||||
"│%7.2f%, %7.2f, %7.2f │\n"
|
||||
"└ ┘\n",
|
||||
vec[0], vec[1], vec[2]);
|
||||
"└ ┘\n",
|
||||
vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
void print(glm::mat4* matrix) {
|
||||
glm::mat4 mat = *matrix;
|
||||
void print(Matrix* matrix) {
|
||||
Matrix mat = *matrix;
|
||||
print(
|
||||
"┌ ┐\n"
|
||||
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||
"│%7.2f%, %7.2f, %7.2f, %7.2f │\n"
|
||||
"└ ┘\n",
|
||||
mat[0][0], mat[0][1], mat[0][2], mat[0][3],
|
||||
mat[1][0], mat[1][1], mat[1][2], mat[1][3],
|
||||
mat[2][0], mat[2][1], mat[2][2], mat[2][3],
|
||||
mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
|
||||
"└ ┘\n",
|
||||
mat.m0, mat.m1, mat.m2, mat.m3,
|
||||
mat.m4, mat.m5, mat.m6, mat.m7,
|
||||
mat.m8, mat.m9, mat.m10, mat.m11,
|
||||
mat.m12, mat.m13, mat.m14, mat.m15);
|
||||
}
|
||||
|
||||
struct Camera {
|
||||
glm::mat4 view;
|
||||
glm::mat4 proj;
|
||||
glm::vec3 pos;
|
||||
glm::vec3 up;
|
||||
glm::vec3 target;
|
||||
Matrix view;
|
||||
Matrix proj;
|
||||
RLVector3 pos;
|
||||
RLVector3 up;
|
||||
RLVector3 target;
|
||||
};
|
||||
|
||||
Camera *createCamera(Arena *arena, real32 aspect_ratio = 800.0f / 600.0f) {
|
||||
Camera *result = PushStruct(arena, Camera);
|
||||
result->view = glm::mat4();
|
||||
result->proj = glm::perspective(glm::radians(45.0f), aspect_ratio, 0.1f, 100.0f);
|
||||
result->pos = glm::vec3(0.0f);
|
||||
result->up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||
result->view = (Matrix){0};
|
||||
result->proj = MatrixPerspective(DEG2RAD * 45.0f, aspect_ratio, 0.1f, 100.0f);
|
||||
result->pos = (RLVector3){0};
|
||||
result->up = (RLVector3){0,1,0};
|
||||
return result;
|
||||
}
|
||||
|
||||
void cameraLookAt(Camera *c, float x, float y, float z) {
|
||||
c->target = glm::vec3(x, y, z);
|
||||
c->view = glm::lookAt(c->pos, c->target, c->up);
|
||||
c->target = (RLVector3){x, y, z};
|
||||
c->view = MatrixLookAt(c->pos, c->target, c->up);
|
||||
}
|
||||
|
||||
void camera_set_up(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
|
||||
c->up = glm::vec3(up_x, up_y, up_z);
|
||||
void cameraSetUp(Camera *c, real32 up_x, real32 up_y, real32 up_z) {
|
||||
c->up = (RLVector3){up_x, up_y, up_z};
|
||||
}
|
||||
|
||||
struct Frame {
|
||||
@@ -146,7 +136,7 @@ struct Renderer {
|
||||
|
||||
struct PolycubeInput {
|
||||
Space repr;
|
||||
Vector4<real32> color;
|
||||
Vector4<real32> color;
|
||||
};
|
||||
|
||||
struct SomaState {
|
||||
@@ -157,8 +147,8 @@ struct SomaState {
|
||||
uint32 light;
|
||||
list<Polycube> polycubes;
|
||||
Camera* camera;
|
||||
glm::vec3 rotAxisX;
|
||||
glm::vec3 rotAxisY;
|
||||
RLVector3 rotAxisX;
|
||||
RLVector3 rotAxisY;
|
||||
list<PolycubeInput> polycubeInput;
|
||||
};
|
||||
|
||||
@@ -177,7 +167,8 @@ struct Soma {
|
||||
|
||||
void showEntity(Scene *scene, uint32 entityHandle) {
|
||||
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
|
||||
for (uint32 &child : node->children) {
|
||||
for (EachIn(node->children, i)) {
|
||||
uint32 child = node->children.data[i];
|
||||
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
|
||||
if (subNode->entityHandle) {
|
||||
getEntity(scene, subNode->entityHandle)->flags |= EntityFlags_Visible;
|
||||
@@ -187,7 +178,8 @@ void showEntity(Scene *scene, uint32 entityHandle) {
|
||||
|
||||
void hideEntity(Scene *scene, uint32 entityHandle) {
|
||||
SceneGraphNode *node = getSceneGraphNodeForEntity(scene, entityHandle);
|
||||
for (uint32 &child : node->children) {
|
||||
for (EachIn(node->children, i)) {
|
||||
uint32 child = node->children.data[i];
|
||||
SceneGraphNode *subNode = getSceneGraphNode(scene, child);
|
||||
if (subNode->entityHandle) {
|
||||
getEntity(scene, subNode->entityHandle)->flags &= ~EntityFlags_Visible;
|
||||
@@ -195,12 +187,14 @@ void hideEntity(Scene *scene, uint32 entityHandle) {
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 centreFromPolycube(Scene *scene, Polycube *p) {
|
||||
glm::vec3 centre = glm::vec3(0.0f);
|
||||
for (uint32 &child : getSceneGraphNode(scene, p->entityHandle)->children) {
|
||||
centre += getSceneGraphNode(scene, child)->translation;
|
||||
RLVector3 centreFromPolycube(Scene *scene, Polycube *p) {
|
||||
RLVector3 centre = (RLVector3){0,0,0};
|
||||
list<uint32> *children = &getSceneGraphNode(scene, p->entityHandle)->children;
|
||||
for (EachIn(*children, i)) {
|
||||
uint32 child = children->data[i];
|
||||
centre = Vector3Add(centre, getSceneGraphNode(scene, child)->translation);
|
||||
}
|
||||
centre /= getSceneGraphNodeForEntity(scene, p->entityHandle)->children.size();
|
||||
centre = Vector3Scale(centre, 1.0f/(getSceneGraphNodeForEntity(scene, p->entityHandle)->children.head));
|
||||
return centre;
|
||||
}
|
||||
|
||||
@@ -315,7 +309,7 @@ void processInput(Soma *soma) {
|
||||
|
||||
if (input->keyboard.escape) {
|
||||
glfwSetWindowShouldClose(soma->window.handle, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (input->keyboard.space && !prevInput->keyboard.space) {
|
||||
glPolygonMode(GL_FRONT_AND_BACK, !soma->state.wireframe ? GL_LINE : GL_FILL);
|
||||
@@ -343,33 +337,33 @@ void processInput(Soma *soma) {
|
||||
|
||||
real64 deltaX = (input->mouse.x - prevInput->mouse.x) * 0.005;
|
||||
if (deltaX > 0.00000001 || deltaX < -0.00000001) {
|
||||
polycubeGraphNode->rotation *= glm::angleAxis((real32)deltaX, soma->state.rotAxisY);
|
||||
polycubeGraphNode->rotation = QuaternionMultiply(polycubeGraphNode->rotation, QuaternionFromAxisAngle(soma->state.rotAxisY, -(real32)deltaX));
|
||||
}
|
||||
|
||||
real64 deltaY = (input->mouse.y - prevInput->mouse.y) * 0.005;
|
||||
if (deltaY > 0.00000001 || deltaY < -0.00000001) {
|
||||
polycubeGraphNode->rotation = glm::angleAxis(-(real32)deltaY, soma->state.rotAxisX) * polycubeGraphNode->rotation;
|
||||
polycubeGraphNode->rotation = QuaternionMultiply(QuaternionFromAxisAngle(soma->state.rotAxisX, -(real32)deltaY), polycubeGraphNode->rotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Polycube createPolycubeFromRepr(Scene *s, Space *repr, Vector4<real32> color) {
|
||||
uint32 polycubeMainEntityHandle = createEntity(s);
|
||||
Polycube createPolycubeFromRepr(Arena *arena, Scene *s, Space *repr, Vector4<real32> color) {
|
||||
uint32 polycubeMainEntityHandle = createEntity(arena, s);
|
||||
Entity *polycubeMainEntity = getEntity(s, polycubeMainEntityHandle);
|
||||
for (int x = 0; x < repr->dim_x; x++) {
|
||||
for (int y = 0; y < repr->dim_y; y++) {
|
||||
for (int z = 0; z < repr->dim_z; z++) {
|
||||
if (filledAt(repr, x, y, z)) {
|
||||
uint32 segmentEntityHandle = createEntity(s);
|
||||
uint32 segmentEntityHandle = createEntity(arena, s);
|
||||
Entity *polycubeSegment = getEntity(s, segmentEntityHandle);
|
||||
polycubeSegment->mesh = &cubeMesh;
|
||||
polycubeSegment->tex = &wallTex;
|
||||
SceneGraphNode *graphNode = getSceneGraphNode(s, polycubeSegment->graphNodeHandle);
|
||||
graphNode->translation = glm::vec3(
|
||||
graphNode->translation = RLVector3{
|
||||
-((repr->dim_z - 1)/2.0f) + z,
|
||||
((repr->dim_x - 1)/2.0f) - x,
|
||||
-((repr->dim_y - 1)/2.0f) + y
|
||||
);
|
||||
-((repr->dim_x - 1)/2.0f) + x,
|
||||
((repr->dim_y - 1)/2.0f) - y
|
||||
};
|
||||
sceneNodeAddEntity(s, polycubeMainEntity->graphNodeHandle, segmentEntityHandle);
|
||||
}
|
||||
}
|
||||
@@ -380,8 +374,8 @@ Polycube createPolycubeFromRepr(Scene *s, Space *repr, Vector4<real32> color) {
|
||||
result.color = color;
|
||||
result.repr = *repr;
|
||||
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(s, polycubeMainEntityHandle);
|
||||
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(1, 0, 0));
|
||||
graphNode->rotation *= glm::angleAxis(PI / 4, glm::vec3(0, 1, 0));
|
||||
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){1, 0, 0}, PI / 4));
|
||||
graphNode->rotation = QuaternionMultiply(graphNode->rotation, QuaternionFromAxisAngle((RLVector3){0, 1, 0}, -PI / 4));
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -471,7 +465,7 @@ void reinitRectangleObjectBuffers(Renderer *r) {
|
||||
Renderer createRenderer(Arena *arena, Scene *scene) {
|
||||
Renderer result = {0};
|
||||
result.scene = scene;
|
||||
result.scene->sceneRoot = createSceneGraphNode(scene);
|
||||
result.scene->sceneRoot = createSceneGraphNode(arena, scene);
|
||||
result.rects = createRectangleObjects(arena, 100);
|
||||
initGraphNode(getSceneGraphNode(scene, scene->sceneRoot));
|
||||
return result;
|
||||
@@ -505,12 +499,13 @@ void renderEnd(Soma *soma, Renderer *renderer) {
|
||||
setUniform4fv(&phongShader, "solid_color", ¤tPolycube->color);
|
||||
|
||||
int model_uniform = getUniformLocation(&phongShader, "model");
|
||||
for (Entity &entity : renderer->scene->entities) {
|
||||
if (entity.flags & EntityFlags_Render && entity.flags & EntityFlags_Visible) {
|
||||
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity.graphNodeHandle)->world);
|
||||
glBindTexture(GL_TEXTURE_2D, entity.tex->tex_id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity.mesh->num_indices);
|
||||
entity.flags &= ~EntityFlags_Render;
|
||||
for (EachIn(renderer->scene->entities, i)) {
|
||||
Entity *entity = &renderer->scene->entities.data[i];
|
||||
if (entity->flags & EntityFlags_Render && entity->flags & EntityFlags_Visible) {
|
||||
setUniformMat4fv(model_uniform, &getSceneGraphNode(renderer->scene, entity->graphNodeHandle)->world);
|
||||
glBindTexture(GL_TEXTURE_2D, entity->tex->tex_id);
|
||||
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)entity->mesh->num_indices);
|
||||
entity->flags &= ~EntityFlags_Render;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -519,7 +514,7 @@ void renderEnd(Soma *soma, Renderer *renderer) {
|
||||
|
||||
reinitRectangleObjectBuffers(renderer);
|
||||
|
||||
glm::mat4 ortho = glm::ortho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
|
||||
Matrix ortho = MatrixOrtho(0.0, 800.0, 600.0, 0.0, -1.0, 1.0);
|
||||
setUniformMat4fv(&solidColorShader, "projection", &ortho);
|
||||
|
||||
glBindVertexArray(renderer->rects.vao);
|
||||
@@ -549,22 +544,17 @@ bool ui_checkboxRect(UI_Context *ui, bool *value, UI_Rect rect) {
|
||||
}
|
||||
}
|
||||
if (*value) {
|
||||
rendererPlaceRectangle(ui->renderer,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
rect.color,
|
||||
5, 0);
|
||||
} else {
|
||||
rendererPlaceRectangle(ui->renderer,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
rendererPlaceRectangle(ui->renderer,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
rect.color,
|
||||
5, 2);
|
||||
rendererPlaceRectangle(ui->renderer,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
} else {
|
||||
rendererPlaceRectangle(ui->renderer,
|
||||
rect.x, rect.y,
|
||||
rect.width, rect.height,
|
||||
COLOR_WHITE,
|
||||
5, 0);
|
||||
5, 2);
|
||||
}
|
||||
|
||||
return clicked;
|
||||
@@ -583,10 +573,10 @@ void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
|
||||
for (int z = 0; z < currentPolycube->repr.dim_z; z++) {
|
||||
bool cellActive = filledAt(¤tPolycube->repr, x, y, z);
|
||||
UI_Rect rect = {
|
||||
currX,
|
||||
currY,
|
||||
boxSize,
|
||||
boxSize,
|
||||
currX,
|
||||
currY,
|
||||
boxSize,
|
||||
boxSize,
|
||||
0,
|
||||
currentPolycube->color,
|
||||
};
|
||||
@@ -602,7 +592,7 @@ void uiPass(Soma *soma, UI_Context *ui, Renderer *renderer) {
|
||||
}
|
||||
}
|
||||
|
||||
int main_cmd() {
|
||||
int mainCmd() {
|
||||
interactive_cmd_line_solve_soma();
|
||||
return 0;
|
||||
}
|
||||
@@ -610,7 +600,7 @@ int main_cmd() {
|
||||
int mainGfx() {
|
||||
Arena *arena = arenaAlloc(Megabytes(128));
|
||||
|
||||
Scene mainScene = createScene();
|
||||
Scene mainScene = createScene(arena);
|
||||
|
||||
Soma soma = {};
|
||||
soma.window.width = 800;
|
||||
@@ -634,47 +624,48 @@ int mainGfx() {
|
||||
soma.state.lastPolycubeVisible = 6;
|
||||
soma.state.polycubeInput = PushListZero(arena, PolycubeInput, 64);
|
||||
soma.state.polycubes = PushListZero(arena, Polycube, 64);
|
||||
soma.state.light = createEntity(&mainScene);
|
||||
soma.state.light = createEntity(arena, &mainScene);
|
||||
soma.state.camera = mainFrame.cam;
|
||||
|
||||
SceneGraphNode *light = getSceneGraphNode(&mainScene, getEntity(&mainScene, soma.state.light)->graphNodeHandle);
|
||||
light->translation = glm::vec3(4.0f, 6.0f, 24.0f);
|
||||
light->translation = RLVector3{4.0f, 6.0f, 24.0f};
|
||||
|
||||
/*
|
||||
Shader solid_texture_shader = createShader(
|
||||
"./assets/shaders/2d.vertex.glsl"_s,
|
||||
"./assets/shaders/2d.vertex.glsl"_s,
|
||||
"./assets/shaders/2d-tex.fragment.glsl"_s);
|
||||
*/
|
||||
|
||||
solidColorShader = createShader(
|
||||
"./assets/shaders/2d-solid.vertex.glsl"_s,
|
||||
"./assets/shaders/2d-solid.vertex.glsl"_s,
|
||||
"./assets/shaders/2d-solid.fragment.glsl"_s);
|
||||
|
||||
phongShader = createShader(
|
||||
"./assets/shaders/phong-solid.vertex.glsl"_s,
|
||||
"./assets/shaders/phong-solid.vertex.glsl"_s,
|
||||
"./assets/shaders/phong-solid.fragment.glsl"_s);
|
||||
|
||||
cubeMesh = createMesh("./assets/models/cube.obj");
|
||||
wallTex = createTexture("./assets/textures/brick-wall.jpg");
|
||||
|
||||
for (int i = 0; i < ArrayCount(STD_SOMA); i++) {
|
||||
for (EachInArray(STD_SOMA, i)) {
|
||||
Space voxelSpace = { STD_SOMA[i], 3, 3, 3 };
|
||||
Vector4<real32> color = colorFromIndex(i);
|
||||
appendList(&soma.state.polycubeInput, PolycubeInput{ voxelSpace, color });
|
||||
cullEmptySpace(&voxelSpace);
|
||||
Polycube polycube = createPolycubeFromRepr(soma.scene, &voxelSpace, color);
|
||||
Polycube polycube = createPolycubeFromRepr(arena, soma.scene, &voxelSpace, color);
|
||||
polycube.color = color;
|
||||
appendList(&soma.state.polycubes, polycube);
|
||||
sceneNodeAddEntity(renderer.scene, renderer.scene->sceneRoot, polycube.entityHandle);
|
||||
}
|
||||
|
||||
soma.state.camera->pos = glm::vec3(0.0f, 0.0f, 8.0f);
|
||||
soma.state.camera->pos = (RLVector3){0.0f, 0.0f, 8.0f};
|
||||
cameraLookAt(soma.state.camera, 0.0f, 0.0f, 0.0f);
|
||||
|
||||
SceneGraphNode *reference_polycube_gn = getSceneGraphNodeForEntity(soma.scene, soma.state.polycubes.data[0].entityHandle);
|
||||
soma.state.rotAxisY = glm::normalize(glm::vec4(0, 1, 0, 0) * glm::inverse(reference_polycube_gn->world));
|
||||
glm::vec3 eyes = glm::normalize(soma.state.camera->pos - reference_polycube_gn->translation);
|
||||
soma.state.rotAxisX = glm::normalize(glm::cross(eyes, soma.state.rotAxisY));
|
||||
Matrix worldInverse = MatrixInvert(reference_polycube_gn->world);
|
||||
soma.state.rotAxisY = Vector3Normalize(RLVector3{worldInverse.m4, worldInverse.m5, worldInverse.m6});
|
||||
RLVector3 eyes = Vector3Normalize(Vector3Subtract(soma.state.camera->pos, reference_polycube_gn->translation));
|
||||
soma.state.rotAxisX = Vector3Normalize(Vector3CrossProduct(eyes, soma.state.rotAxisY));
|
||||
|
||||
real64 lastFrame = glfwGetTime();
|
||||
real64 timeDelta = 1.0f/60.0f;
|
||||
@@ -695,9 +686,9 @@ int mainGfx() {
|
||||
Polycube *currentPolycube = &soma.state.polycubes.data[soma.state.currentPolycube];
|
||||
PolycubeInput *pinput = &soma.state.polycubeInput.data[soma.state.currentPolycube];
|
||||
removeEntity(soma.scene, currentPolycube->entityHandle);
|
||||
Space culledRepr = pinput->repr;
|
||||
Space culledRepr = pinput->repr;
|
||||
cullEmptySpace(&culledRepr);
|
||||
Polycube newPolycube = createPolycubeFromRepr(soma.scene, &culledRepr, pinput->color);
|
||||
Polycube newPolycube = createPolycubeFromRepr(arena, soma.scene, &culledRepr, pinput->color);
|
||||
SceneGraphNode *graphNode = getSceneGraphNodeForEntity(soma.scene, newPolycube.entityHandle);
|
||||
graphNode->rotation = getSceneGraphNodeForEntity(soma.scene, currentPolycube->entityHandle)->rotation;
|
||||
soma.state.polycubes.data[soma.state.currentPolycube] = newPolycube;
|
||||
|
||||
220
src/tests.cpp
220
src/tests.cpp
@@ -1,13 +1,16 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <tuple>
|
||||
#include "VoxelSpace.h"
|
||||
#include "lib/djstdlib/core.h"
|
||||
|
||||
typedef struct MismatchData {
|
||||
int i;
|
||||
uint64 actual;
|
||||
uint64 expected;
|
||||
} MismatchData;
|
||||
|
||||
void test() {
|
||||
{
|
||||
Space space = {};
|
||||
space.space=23ull;
|
||||
space.space=23ull;
|
||||
space.dim_x=3;
|
||||
space.dim_y=3;
|
||||
space.dim_z=3;
|
||||
@@ -107,86 +110,86 @@ void test() {
|
||||
|
||||
int prism_dims[] = { 3, 3, 3 };
|
||||
list<uint64> perms = getAllPermutationsInPrism(arena, &space1, prism_dims);
|
||||
auto expected_perms = std::vector<uint64_t>{
|
||||
30ull,
|
||||
240ull,
|
||||
15360ull,
|
||||
122880ull,
|
||||
7864320ull,
|
||||
62914560ull,
|
||||
153ull,
|
||||
306ull,
|
||||
78336ull,
|
||||
156672ull,
|
||||
40108032ull,
|
||||
80216064ull,
|
||||
266760ull,
|
||||
533520ull,
|
||||
1067040ull,
|
||||
2134080ull,
|
||||
4268160ull,
|
||||
8536320ull,
|
||||
263682ull,
|
||||
527364ull,
|
||||
2109456ull,
|
||||
4218912ull,
|
||||
16875648ull,
|
||||
33751296ull,
|
||||
2101761ull,
|
||||
4203522ull,
|
||||
8407044ull,
|
||||
16814088ull,
|
||||
33628176ull,
|
||||
67256352ull,
|
||||
525825ull,
|
||||
1051650ull,
|
||||
4206600ull,
|
||||
8413200ull,
|
||||
33652800ull,
|
||||
67305600ull,
|
||||
51ull,
|
||||
408ull,
|
||||
26112ull,
|
||||
208896ull,
|
||||
13369344ull,
|
||||
106954752ull,
|
||||
90ull,
|
||||
180ull,
|
||||
46080ull,
|
||||
92160ull,
|
||||
23592960ull,
|
||||
47185920ull,
|
||||
4680ull,
|
||||
9360ull,
|
||||
18720ull,
|
||||
2396160ull,
|
||||
4792320ull,
|
||||
9584640ull,
|
||||
1542ull,
|
||||
12336ull,
|
||||
98688ull,
|
||||
789504ull,
|
||||
6316032ull,
|
||||
50528256ull,
|
||||
36873ull,
|
||||
73746ull,
|
||||
147492ull,
|
||||
18878976ull,
|
||||
37757952ull,
|
||||
75515904ull,
|
||||
3075ull,
|
||||
24600ull,
|
||||
196800ull,
|
||||
1574400ull,
|
||||
12595200ull,
|
||||
100761600ull,
|
||||
uint64 expected_perms[] = {
|
||||
30ull,
|
||||
240ull,
|
||||
15360ull,
|
||||
122880ull,
|
||||
7864320ull,
|
||||
62914560ull,
|
||||
153ull,
|
||||
306ull,
|
||||
78336ull,
|
||||
156672ull,
|
||||
40108032ull,
|
||||
80216064ull,
|
||||
266760ull,
|
||||
533520ull,
|
||||
1067040ull,
|
||||
2134080ull,
|
||||
4268160ull,
|
||||
8536320ull,
|
||||
263682ull,
|
||||
527364ull,
|
||||
2109456ull,
|
||||
4218912ull,
|
||||
16875648ull,
|
||||
33751296ull,
|
||||
2101761ull,
|
||||
4203522ull,
|
||||
8407044ull,
|
||||
16814088ull,
|
||||
33628176ull,
|
||||
67256352ull,
|
||||
525825ull,
|
||||
1051650ull,
|
||||
4206600ull,
|
||||
8413200ull,
|
||||
33652800ull,
|
||||
67305600ull,
|
||||
51ull,
|
||||
408ull,
|
||||
26112ull,
|
||||
208896ull,
|
||||
13369344ull,
|
||||
106954752ull,
|
||||
90ull,
|
||||
180ull,
|
||||
46080ull,
|
||||
92160ull,
|
||||
23592960ull,
|
||||
47185920ull,
|
||||
4680ull,
|
||||
9360ull,
|
||||
18720ull,
|
||||
2396160ull,
|
||||
4792320ull,
|
||||
9584640ull,
|
||||
1542ull,
|
||||
12336ull,
|
||||
98688ull,
|
||||
789504ull,
|
||||
6316032ull,
|
||||
50528256ull,
|
||||
36873ull,
|
||||
73746ull,
|
||||
147492ull,
|
||||
18878976ull,
|
||||
37757952ull,
|
||||
75515904ull,
|
||||
3075ull,
|
||||
24600ull,
|
||||
196800ull,
|
||||
1574400ull,
|
||||
12595200ull,
|
||||
100761600ull,
|
||||
};
|
||||
|
||||
Assert(expected_perms.size() == perms.length);
|
||||
Assert(ArrayCount(expected_perms) == perms.length);
|
||||
|
||||
for (int i = 0; i < perms.length; i++) {
|
||||
if (i <= expected_perms.size()) {
|
||||
Assert(expected_perms.at(i) == perms.data[i]);
|
||||
if (i <= ArrayCount(expected_perms)) {
|
||||
Assert(expected_perms[i] == perms.data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,20 +197,20 @@ void test() {
|
||||
}
|
||||
|
||||
{
|
||||
Space space1 = {};
|
||||
space1.space=30ull;
|
||||
Space space1 = {};
|
||||
space1.space=30ull;
|
||||
space1.dim_x=3;
|
||||
space1.dim_y=3;
|
||||
space1.dim_z=3;
|
||||
|
||||
Space space2 = {};
|
||||
space2.space=30ull;
|
||||
Space space2 = {};
|
||||
space2.space=30ull;
|
||||
space2.dim_x=3;
|
||||
space2.dim_y=3;
|
||||
space2.dim_z=3;
|
||||
|
||||
Space space3 = {};
|
||||
space3.space=30ull;
|
||||
Space space3 = {};
|
||||
space3.space=30ull;
|
||||
space3.dim_x=3;
|
||||
space3.dim_y=3;
|
||||
space3.dim_z=3;
|
||||
@@ -258,7 +261,7 @@ void test() {
|
||||
};
|
||||
|
||||
Space space3 = {};
|
||||
space3.space=15ull;
|
||||
space3.space=15ull;
|
||||
space3.dim_x=3;
|
||||
space3.dim_y=3;
|
||||
space3.dim_z=3;
|
||||
@@ -276,40 +279,41 @@ void test() {
|
||||
list<uint64> positions1 = getAllPositionsInPrism(arena, &space1, dims);
|
||||
list<uint64> positions2 = getAllPositionsInPrism(arena, &space2, dims);
|
||||
list<uint64> positions3 = getAllPositionsInPrism(arena, &space3, dims);
|
||||
auto mismatches1 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
|
||||
auto mismatches2 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
|
||||
auto mismatches3 = std::vector<std::tuple<int, uint64_t, uint64_t>>();
|
||||
|
||||
list<MismatchData> mismatches1 = PushList(arena, MismatchData, 6);
|
||||
list<MismatchData> mismatches2 = PushList(arena, MismatchData, 6);
|
||||
list<MismatchData> mismatches3 = PushList(arena, MismatchData, 6);
|
||||
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (positions1.data[i] != expected_results1[i]) {
|
||||
mismatches1.push_back({ i, positions1.data[i], expected_results1[i] });
|
||||
appendList(&mismatches1, { i, positions1.data[i], expected_results1[i] });
|
||||
}
|
||||
if (positions2.data[i] != expected_results2[i]) {
|
||||
mismatches2.push_back({ i, positions2.data[i], expected_results2[i] });
|
||||
appendList(&mismatches2, { i, positions2.data[i], expected_results2[i] });
|
||||
}
|
||||
if (positions3.data[i] != expected_results3[i]) {
|
||||
mismatches3.push_back({ i, positions3.data[i], expected_results3[i] });
|
||||
appendList(&mismatches3, { i, positions3.data[i], expected_results3[i] });
|
||||
}
|
||||
}
|
||||
Assert(mismatches1.size() == 0);
|
||||
if (mismatches1.size() > 0) {
|
||||
std::cout << "Index - Actual - Expected" << std::endl;
|
||||
for (auto &mismatch : mismatches1) {
|
||||
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
|
||||
Assert(mismatches1.head == 0);
|
||||
if (mismatches1.head > 0) {
|
||||
print("Index - Actual - Expected\n");
|
||||
for (EachIn(mismatches1, i)) {
|
||||
print("%zu - %zu - %zu\n", mismatches1.data[i].i, mismatches1.data[i].actual, mismatches1.data[i].expected);
|
||||
}
|
||||
}
|
||||
Assert(mismatches2.size() == 0);
|
||||
if (mismatches2.size() > 0) {
|
||||
std::cout << "Index - Actual - Expected" << std::endl;
|
||||
for (auto &mismatch : mismatches2) {
|
||||
std::cout << std::get<0>(mismatch) << " - " << std::get<1>(mismatch) << " - " << std::get<2>(mismatch) << std::endl;
|
||||
Assert(mismatches2.head == 0);
|
||||
if (mismatches2.head > 0) {
|
||||
print("Index - Actual - Expected\n");
|
||||
for (EachIn(mismatches2, i)) {
|
||||
print("%zu - %zu - %zu\n", mismatches2.data[i].i, mismatches2.data[i].actual, mismatches2.data[i].expected);
|
||||
}
|
||||
}
|
||||
Assert(mismatches3.size() == 0);
|
||||
if (mismatches3.size() > 0) {
|
||||
std::cout << "Index - Actual - Expected" << std::endl;
|
||||
for (auto &mismatch : mismatches3) {
|
||||
std::cout << "At " << std::get<0>(mismatch) << ": " << std::get<1>(mismatch) << " != " << std::get<2>(mismatch) << std::endl;
|
||||
Assert(mismatches3.head == 0);
|
||||
if (mismatches3.head > 0) {
|
||||
print("Index - Actual - Expected\n");
|
||||
for (EachIn(mismatches3, i)) {
|
||||
print("%zu - %zu - %zu\n", mismatches3.data[i].i, mismatches3.data[i].actual, mismatches3.data[i].expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,54 +1,52 @@
|
||||
#include <cstring>
|
||||
#include "scene.h"
|
||||
|
||||
Entity *getEntity(Scene *s, uint32 id) {
|
||||
return &s->entities[id - 1];
|
||||
return &s->entities.data[id - 1];
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNodeForEntity(Scene *s, uint32 entityHandle) {
|
||||
return &s->graphNodes[s->entities[entityHandle - 1].graphNodeHandle - 1];
|
||||
return &s->graphNodes.data[s->entities.data[entityHandle - 1].graphNodeHandle - 1];
|
||||
}
|
||||
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, uint32 sceneGraphNodeHandle) {
|
||||
return &s->graphNodes[sceneGraphNodeHandle - 1];
|
||||
return &s->graphNodes.data[sceneGraphNodeHandle - 1];
|
||||
}
|
||||
|
||||
uint32 createEntity(Scene *s) {
|
||||
s->entities.emplace_back();
|
||||
s->graphNodes.emplace_back();
|
||||
s->entities.back().graphNodeHandle = (uint32)s->graphNodes.size();
|
||||
s->graphNodes.back().entityHandle = (uint32)s->entities.size();
|
||||
uint32 handle = (uint32)s->entities.size();
|
||||
uint32 graphNodeHandle = (uint32)s->graphNodes.size();
|
||||
uint32 createSceneGraphNode(Arena *arena, Scene *s) {
|
||||
appendList(&s->graphNodes, (SceneGraphNode){0});
|
||||
s->graphNodes.data[s->graphNodes.head - 1].children = PushList(arena, uint32, 64);
|
||||
return (uint32)s->graphNodes.head;
|
||||
}
|
||||
|
||||
uint32 createEntity(Arena *arena, Scene *s) {
|
||||
appendList(&s->entities, (Entity){0});
|
||||
uint32 graphNodeId = createSceneGraphNode(arena, s);
|
||||
s->entities.data[s->entities.head - 1].graphNodeHandle = graphNodeId;
|
||||
getSceneGraphNode(s, graphNodeId)->entityHandle = (uint32)s->entities.head;
|
||||
uint32 handle = (uint32)s->entities.head;
|
||||
uint32 graphNodeHandle = (uint32)s->graphNodes.head;
|
||||
initGraphNode(getSceneGraphNode(s, graphNodeHandle));
|
||||
return handle;
|
||||
}
|
||||
|
||||
uint32 createSceneGraphNode(Scene *s) {
|
||||
s->graphNodes.emplace_back();
|
||||
return (uint32)s->graphNodes.size();
|
||||
}
|
||||
|
||||
void initGraphNode(SceneGraphNode *n) {
|
||||
n->scale = glm::vec3(1.0f, 1.0f, 1.0f);
|
||||
n->translation = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||
n->rotation = glm::quat(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
n->local = glm::mat4(1.0f);
|
||||
n->scale = RLVector3{1.0f, 1.0f, 1.0f};
|
||||
n->translation = RLVector3{0.0f, 0.0f, 0.0f};
|
||||
n->rotation = Quaternion{1.0f, 0.0f, 0.0f, 0.0f};
|
||||
n->local = MatrixIdentity();
|
||||
n->world = n->local;
|
||||
}
|
||||
|
||||
void recalcGraphNode(SceneGraphNode *n) {
|
||||
n->local = glm::scale(
|
||||
glm::translate(
|
||||
glm::mat4(1.0f),
|
||||
n->translation
|
||||
) * glm::toMat4(n->rotation),
|
||||
n->scale
|
||||
);
|
||||
n->local = MatrixCompose(n->translation, n->rotation, n->scale);
|
||||
}
|
||||
|
||||
Scene createScene() {
|
||||
Scene createScene(Arena *arena) {
|
||||
Scene result = {};
|
||||
result.sceneRoot = createSceneGraphNode(&result);
|
||||
result.entities = PushList(arena, Entity, 1024);
|
||||
result.graphNodes = PushList(arena, SceneGraphNode, 1024);
|
||||
result.sceneRoot = createSceneGraphNode(arena, &result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -57,11 +55,12 @@ void recalcSceneGraphNode(Scene *s, uint32 parentHandle) {
|
||||
if (node->entityHandle) {
|
||||
getEntity(s, node->entityHandle)->flags |= EntityFlags_Render;
|
||||
}
|
||||
for (uint32 &nodeId : node->children) {
|
||||
for (EachIn(node->children, i)) {
|
||||
uint32 nodeId = node->children.data[i];
|
||||
SceneGraphNode *graphNode = getSceneGraphNode(s, nodeId);
|
||||
graphNode->parentHandle = parentHandle;
|
||||
recalcGraphNode(graphNode);
|
||||
graphNode->world = node->world * graphNode->local;
|
||||
graphNode->world = MatrixMultiply(graphNode->local, node->world);
|
||||
recalcSceneGraphNode(s, nodeId);
|
||||
}
|
||||
}
|
||||
@@ -76,9 +75,10 @@ void removeEntity(Scene *s, uint32 entityHandle) {
|
||||
SceneGraphNode *graphNode = getSceneGraphNode(s, entity->graphNodeHandle);
|
||||
if (graphNode->parentHandle) {
|
||||
SceneGraphNode *parentNode = getSceneGraphNode(s, graphNode->parentHandle);
|
||||
for (int i = 0; i < parentNode->children.size(); i++) {
|
||||
if (parentNode->children.at(i) == entity->graphNodeHandle) {
|
||||
parentNode->children.erase(parentNode->children.begin() + i);
|
||||
for (int i = 0; i < parentNode->children.head; i++) {
|
||||
if (parentNode->children.data[i] == entity->graphNodeHandle) {
|
||||
memcpy(&parentNode->children.data[i], &parentNode->children.data[i + 1], parentNode->children.head - i);
|
||||
parentNode->children.head -= 1;
|
||||
graphNode->parentHandle = 0;
|
||||
break;
|
||||
}
|
||||
@@ -87,5 +87,7 @@ void removeEntity(Scene *s, uint32 entityHandle) {
|
||||
}
|
||||
|
||||
void sceneNodeAddEntity(Scene *s, uint32 graphNodeHandle, uint32 entityHandle) {
|
||||
getSceneGraphNode(s, graphNodeHandle)->children.push_back(getEntity(s, entityHandle)->graphNodeHandle);
|
||||
list<uint32> *childList = &getSceneGraphNode(s, graphNodeHandle)->children;
|
||||
appendList(childList, getEntity(s, entityHandle)->graphNodeHandle);
|
||||
print("%zu HI\n", childList->length);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#include <vector>
|
||||
#include "glm/glm.hpp"
|
||||
#include <glm/gtx/quaternion.hpp>
|
||||
#include "../gfx/gfx.h"
|
||||
#include "../lib/raymath.h"
|
||||
|
||||
enum EntityFlags {
|
||||
EntityFlags_Visible=1<<0,
|
||||
@@ -17,27 +15,27 @@ struct Entity {
|
||||
};
|
||||
|
||||
struct SceneGraphNode {
|
||||
glm::mat4 local;
|
||||
glm::mat4 world;
|
||||
glm::vec3 translation;
|
||||
glm::quat rotation;
|
||||
glm::vec3 scale;
|
||||
std::vector<uint32> children;
|
||||
Matrix local;
|
||||
Matrix world;
|
||||
RLVector3 translation;
|
||||
Quaternion rotation;
|
||||
RLVector3 scale;
|
||||
list<uint32> children;
|
||||
uint32 entityHandle;
|
||||
uint32 parentHandle;
|
||||
};
|
||||
|
||||
struct Scene {
|
||||
uint32 sceneRoot;
|
||||
std::vector<Entity> entities;
|
||||
std::vector<SceneGraphNode> graphNodes;
|
||||
list<Entity> entities;
|
||||
list<SceneGraphNode> graphNodes;
|
||||
};
|
||||
|
||||
uint32 createEntity(Scene *s);
|
||||
uint32 createEntity(Arena *arena, Scene *s);
|
||||
Entity *getEntity(Scene *s);
|
||||
SceneGraphNode *getSceneGraphNode(Scene *s, int id);
|
||||
uint32 createSceneGraphNode(Scene *s);
|
||||
Scene createScene(Scene *s);
|
||||
uint32 createSceneGraphNode(Arena *arena, Scene *s);
|
||||
Scene createScene(Arena *arena);
|
||||
void initGraphNode(SceneGraphNode *n);
|
||||
void recalcGraphNode(SceneGraphNode *n);
|
||||
void recalcSceneGraphNode(Scene *s, uint32 parentHandle);
|
||||
|
||||
Reference in New Issue
Block a user