fix testing
All checks were successful
studiorailgun/Renderer/pipeline/head This commit looks good

This commit is contained in:
austin 2024-12-04 19:30:35 -05:00
parent 85f0652d4f
commit bbf14ffd87
12 changed files with 592 additions and 60 deletions

View File

@ -23,6 +23,7 @@
"cstdlib": "c",
"pool.h": "c",
"mainfunctions.h": "c",
"solver_consts.h": "c"
"solver_consts.h": "c",
"public.h": "c"
}
}

View File

@ -1,67 +1,95 @@
cmake_minimum_required(VERSION 3.20.0)
project(StormEngine VERSION 0.1.0 LANGUAGES C)
# Find sources
file(GLOB_RECURSE SOURCES src/main/c/src/**.c)
# include header files
include_directories(src/main/c/includes)
# include jni
set(JAVA_AWT_LIBRARY NotNeeded)
if(EXISTS "/tmp/jni/jdk/include")
include_directories(/tmp/jni/jdk/include)
include_directories(/tmp/jni/jdk/include/linux)
else()
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
endif()
# Create shared library
add_library(StormEngine SHARED ${SOURCES})
# set props for the lib
target_compile_options(StormEngine PRIVATE -m64 -mavx -mavx2)
# set shared library output dir
set_target_properties(StormEngine PROPERTIES
CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/shared-folder
)
# include and enable testing
include(CTest)
enable_testing()
# Grab test files
file(GLOB_RECURSE TEST_FILES ${CMAKE_SOURCE_DIR}/test/c/**.c)
set(TEST_DRIVER test_driver.c)
# set shared library output dir
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build)
# preprocess the test files to use relative paths
set(TEST_SOURCES "")
foreach(TEST_FILE ${TEST_FILES})
file(RELATIVE_PATH REL_TEST_FILE ${CMAKE_SOURCE_DIR} ${TEST_FILE})
# get_filename_component (TEST_NAME ${TEST_FILE} NAME)
list(APPEND TEST_SOURCES ${REL_TEST_FILE})
endforeach()
#include project folders
add_subdirectory(src/main/c/src)
add_subdirectory(test/c)
# Add test sources
create_test_sourcelist(TEST_SOURCE_LIST ${TEST_DRIVER} ${TEST_SOURCES})
# Find sources
# file(GLOB_RECURSE SOURCES src/main/c/src/**.c)
# Create test executable
add_executable(test_runner ${TEST_SOURCE_LIST})
# # include jni
# set(JAVA_AWT_LIBRARY NotNeeded)
# if(EXISTS "/tmp/jni/jdk/include")
# include_directories(/tmp/jni/jdk/include)
# include_directories(/tmp/jni/jdk/include/linux)
# else()
# find_package(JNI REQUIRED)
# include_directories(${JNI_INCLUDE_DIRS})
# endif()
# emit test driver to outdir
set_target_properties(test_runner PROPERTIES
CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build
)
# # Create shared library
# add_library(StormEngine SHARED ${SOURCES})
# link the library to the test executable
target_link_libraries(test_runner StormEngine)
# # include public dirs
# target_include_directories(StormEngine PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/main/c/includes)
# add tests for each test source file
foreach (TEST_FILE ${TEST_SOURCES})
get_filename_component (TEST_NAME ${TEST_FILE} NAME_WE)
get_filename_component (TEST_PATH ${TEST_FILE} DIRECTORY)
add_test(NAME ${TEST_NAME} COMMAND test_runner ${TEST_PATH}/${TEST_NAME})
endforeach ()
# # set props for the lib
# target_compile_options(StormEngine PRIVATE -m64 -mavx -mavx2)
# set shared library output dir
# set_target_properties(StormEngine PROPERTIES
# CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build
# )
# # include and enable testing
# include(CTest)
# enable_testing()
# # Grab test files
# file(GLOB_RECURSE TEST_FILES ${CMAKE_SOURCE_DIR}/test/c/**.c)
# set(TEST_DRIVER test_driver.c)
# # preprocess the test files to use relative paths
# set(TEST_SOURCES "")
# foreach(TEST_FILE ${TEST_FILES})
# file(RELATIVE_PATH REL_TEST_FILE ${CMAKE_SOURCE_DIR} ${TEST_FILE})
# # get_filename_component (TEST_NAME ${TEST_FILE} NAME)
# list(APPEND TEST_SOURCES ${REL_TEST_FILE})
# endforeach()
# # Add test sources
# create_test_sourcelist(TEST_SOURCE_LIST ${TEST_DRIVER} ${TEST_SOURCES})
# # Create test executable
# add_executable(test_runner ${TEST_SOURCE_LIST})
# # emit test driver to outdir
# set_target_properties(test_runner PROPERTIES
# CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/out/build
# )
# # include header files
# target_include_directories(test_runner PRIVATE ${PROJECT_SOURCE_DIR}/src/main/c/includes)
# # link the library to the test executable
# target_link_libraries(test_runner PRIVATE StormEngine)
# # find_library(STORM_ENGINE_NAME StormEngine PATHS ${PROJECT_SOURCE_DIR}/shared-folder)
# # if(STORM_ENGINE_NAME)
# # target_link_libraries(test_runner PRIVATE ${STORM_ENGINE_NAME})
# # target_include_directories(test_runner PRIVATE src/main/c/includes)
# # else()
# # message("Library not found!")
# # message(${STORM_ENGINE_NAME})
# # message(FATAL_ERROR ${PROJECT_SOURCE_DIR}/shared-folder)
# # endif()
# # add tests for each test source file
# foreach (TEST_FILE ${TEST_SOURCES})
# get_filename_component (TEST_NAME ${TEST_FILE} NAME_WE)
# get_filename_component (TEST_PATH ${TEST_FILE} DIRECTORY)
# add_test(NAME ${TEST_NAME} COMMAND test_runner ${TEST_PATH}/${TEST_NAME})
# endforeach ()
# # make test runner depend on library
# add_dependencies(test_runner StormEngine)

2
Jenkinsfile vendored
View File

@ -96,7 +96,7 @@ pipeline {
steps {
script {
catchError {
sh 'cd ./out/build && ctest --output-junit ./Testing/testRes.xml && cd ../../..'
sh 'cd ./out/build && ctest --output-junit ./Testing/testRes.xml && cd ../..'
}
}
}

View File

@ -1241,6 +1241,9 @@ Fix placing character at end of world bounds
Bump ode4j version
Small collision engine code formatting
(14/04/2024)
Fix testing apparatus for native code on windows
# TODO

View File

@ -1,11 +1,19 @@
#include <jni.h>
//Must be included for public functions to be imported/exported on windows
#include "public.h"
#ifndef CHUNK_H
#define CHUNK_H
#include <jni.h>
#define MIN_VALUE 0
#define MAX_VALUE 1
/**
* The dimension of a single chunk's array
*/
#define DIM 18
/**
* A chunk
*/
@ -22,6 +30,107 @@ typedef struct {
jobject chunkJRaw;
} Chunk;
#define DIM 18
/**
* The size of the main array's real data
*/
#define MAIN_ARRAY_DIM 16
/**
* The number of chunks to place next to one another
*/
#define SPARSE_ARRAY_CHUNK_DIM 7
/**
* The total number of chunks in the chunk tracking array
*/
#define SPARSE_ARRAY_TOTAL_CHUNKS SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM
/**
* The extra values at the edges of the sparse array (to allow pulling data from borders)
*/
#define SPARSE_ARRAY_BORDER_SIZE 2
/**
* The size of the dimension of the memory of the sparse array
*/
#define SPARSE_ARRAY_RAW_DIM SPARSE_ARRAY_CHUNK_DIM * MAIN_ARRAY_DIM + SPARSE_ARRAY_BORDER_SIZE
/**
* The size of a sparse array in number of elements
*/
#define SPARSE_ARRAY_FULL_SIZE SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM
/**
* A set of sparse matricies for simulating fluids
*/
typedef struct {
/**
* The density array
*/
float * d;
/**
* The density delta array
*/
float * d0;
/**
* The x velocity array
*/
float * u;
/**
* The y velocity array
*/
float * v;
/**
* The z velocity array
*/
float * w;
/**
* The x velocity delta array
*/
float * u0;
/**
* The y velocity delta array
*/
float * v0;
/**
* The z velocity delta array
*/
float * w0;
/**
* The chunks inside the array
*/
Chunk ** chunks;
} SparseChunkArray;
/**
* Creates a sparse chunk array
*/
LIBRARY_API SparseChunkArray * fluid_create_sparse_array();
/**
* Frees a sparse chunk array
*/
LIBRARY_API void fluid_free_sparse_array(SparseChunkArray * array);
/**
* Adds a chunk to the sparse array
*/
LIBRARY_API void fluid_add_chunk(SparseChunkArray * array, Chunk * chunk, int x, int y, int z);
/**
* Adds a chunk to the sparse array
*/
LIBRARY_API void fluid_remove_chunk(SparseChunkArray * array, Chunk * chunk, int x, int y, int z, int copy);
#endif

View File

@ -0,0 +1,9 @@
#ifdef WIN32
#ifdef LIBRARY_EXPORTS
#define LIBRARY_API __declspec(dllexport)
#else
#define LIBRARY_API __declspec(dllimport)
#endif
#else
#define LIBRARY_API
#endif

View File

@ -0,0 +1,30 @@
# Find sources
file(GLOB_RECURSE SOURCES "*.c")
# include jni
set(JAVA_AWT_LIBRARY NotNeeded)
if(EXISTS "/tmp/jni/jdk/include")
include_directories(/tmp/jni/jdk/include)
include_directories(/tmp/jni/jdk/include/linux)
else()
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
endif()
# Create shared library
add_library(StormEngine SHARED ${SOURCES})
# include public dirs
target_include_directories(StormEngine PUBLIC ${PROJECT_SOURCE_DIR}/src/main/c/includes)
# set props for the lib
target_compile_options(StormEngine PRIVATE -m64 -mavx -mavx2)
if (WIN32)
# define so public header knows to export
add_definitions(-DWIN32)
# define so library knows to export, not import
add_definitions(-DLIBRARY_EXPORTS)
endif ()

View File

@ -0,0 +1,266 @@
#include <stdlib.h>
#include "fluid/chunk.h"
#include "fluid/chunkmask.h"
#include "fluid/utilities.h"
int GCI(int x, int y, int z);
int GVI(int x, int y, int z);
int solveOffset(int chunkPos);
/**
* Creates a sparse chunk array
*/
LIBRARY_API SparseChunkArray * fluid_create_sparse_array(){
//allocate the object itself
SparseChunkArray * rVal = (SparseChunkArray *)malloc(sizeof(SparseChunkArray));
//allocate the sub-arrays
rVal->d = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->d0 = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->u = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->v = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->w = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->u0 = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->v0 = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
rVal->w0 = (float *)malloc(SPARSE_ARRAY_FULL_SIZE * sizeof(float));
//allocate the chunk-tracking array
rVal->chunks = (Chunk **)malloc(sizeof(Chunk *) * SPARSE_ARRAY_TOTAL_CHUNKS);
return rVal;
}
/**
* Frees a sparse chunk array
*/
LIBRARY_API void fluid_free_sparse_array(SparseChunkArray * array){
//free the constituent arrays
free(array->d);
free(array->d0);
free(array->u);
free(array->v);
free(array->w);
free(array->u0);
free(array->v0);
free(array->w0);
//free the chunk-tracking structure
free(array->chunks);
//free the array itself
free(array);
}
/**
* Adds a chunk to the sparse array
*/
LIBRARY_API void fluid_add_chunk(SparseChunkArray * array, Chunk * chunk, int x, int y, int z){
//solve chunk offsets
int offsetX = solveOffset(x);
int offsetY = solveOffset(y);
int offsetZ = solveOffset(z);
int minPos = SPARSE_ARRAY_BORDER_SIZE / 2;
int N = DIM;
int i, j, k;
for(int m = 0; m < MAIN_ARRAY_DIM; m++){
for(int n = 0; n < MAIN_ARRAY_DIM; n++){
for(int o = 0; o < MAIN_ARRAY_DIM; o++){
i = m + 1;
j = n + 1;
k = o + 1;
array->d[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->d[CENTER_LOC][IX(i,j,k)];
array->d0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->d0[CENTER_LOC][IX(i,j,k)];
array->u[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->u[CENTER_LOC][IX(i,j,k)];
array->v[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->v[CENTER_LOC][IX(i,j,k)];
array->w[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->w[CENTER_LOC][IX(i,j,k)];
array->u0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->d[CENTER_LOC][IX(i,j,k)];
array->v0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->d[CENTER_LOC][IX(i,j,k)];
array->w0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = chunk->d[CENTER_LOC][IX(i,j,k)];
}
}
}
//set the chunk pointer
array->chunks[GCI(x,y,z)] = chunk;
}
/**
* Adds a chunk to the sparse array
*/
LIBRARY_API void fluid_remove_chunk(SparseChunkArray * array, Chunk * chunk, int x, int y, int z, int copy){
//solve chunk offsets
int offsetX = solveOffset(x);
int offsetY = solveOffset(y);
int offsetZ = solveOffset(z);
int minPos = SPARSE_ARRAY_BORDER_SIZE / 2;
int N = DIM;
int i, j, k;
for(int m = 0; m < MAIN_ARRAY_DIM; m++){
for(int n = 0; n < MAIN_ARRAY_DIM; n++){
for(int o = 0; o < MAIN_ARRAY_DIM; o++){
i = m + 1;
j = n + 1;
k = o + 1;
//copy density to chunk
chunk->d[CENTER_LOC][IX(i,j,k)] = array->d[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
chunk->d0[CENTER_LOC][IX(i,j,k)] = array->d0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
//zero density in the main array
array->d[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
array->d0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
//copy velocity to the chunk
chunk->u[CENTER_LOC][IX(i,j,k)] = array->u[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
chunk->v[CENTER_LOC][IX(i,j,k)] = array->v[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
chunk->w[CENTER_LOC][IX(i,j,k)] = array->w[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
//zero velocity in the main array
array->u[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
array->v[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
array->w[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
//copy velocity deltas to the chunk
chunk->d[CENTER_LOC][IX(i,j,k)] = array->u0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
chunk->d[CENTER_LOC][IX(i,j,k)] = array->v0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
chunk->d[CENTER_LOC][IX(i,j,k)] = array->w0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)];
//zero elocity deltas in the main array
array->u0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
array->v0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
array->w0[GVI(
minPos + offsetX + i,
minPos + offsetY + j,
minPos + offsetZ + k
)] = 0;
}
}
}
//set the chunk pointer
array->chunks[GCI(x,y,z)] = NULL;
}
/**
* Gets the index of the chunk at a given position within the sparse array
*/
int GCI(int x, int y, int z){
return x * SPARSE_ARRAY_CHUNK_DIM * SPARSE_ARRAY_CHUNK_DIM + y * SPARSE_ARRAY_CHUNK_DIM + z;
}
/**
* Gets the index of the value at a given position within the sparse array
*/
int GVI(int x, int y, int z){
return x * SPARSE_ARRAY_RAW_DIM * SPARSE_ARRAY_RAW_DIM + y * SPARSE_ARRAY_RAW_DIM + z;
}
/**
* Solves the offset into the sparse chunk aray to iterate from for this chunk's position
*/
int solveOffset(int chunkPos){
return SPARSE_ARRAY_BORDER_SIZE / 2 + chunkPos * MAIN_ARRAY_DIM;
}

67
test/c/CMakeLists.txt Normal file
View File

@ -0,0 +1,67 @@
# include jni
set(JAVA_AWT_LIBRARY NotNeeded)
if(EXISTS "/tmp/jni/jdk/include")
include_directories(/tmp/jni/jdk/include)
include_directories(/tmp/jni/jdk/include/linux)
else()
find_package(JNI REQUIRED)
include_directories(${JNI_INCLUDE_DIRS})
endif()
# Grab test files
file(GLOB_RECURSE TEST_FILES "*.c")
set(TEST_DRIVER test_driver.c)
# include and enable testing
# include(CTest)
# enable_testing()
# preprocess the test files to use relative paths
set(TEST_SOURCES "")
foreach(TEST_FILE ${TEST_FILES})
file(RELATIVE_PATH REL_TEST_FILE ${CMAKE_CURRENT_SOURCE_DIR} ${TEST_FILE})
# get_filename_component (TEST_NAME ${TEST_FILE} NAME)
list(APPEND TEST_SOURCES ${REL_TEST_FILE})
endforeach()
# Add test sources
create_test_sourcelist(TEST_SOURCE_LIST ${TEST_DRIVER} ${TEST_SOURCES})
# Create test executable
add_executable(test_runner ${TEST_SOURCE_LIST})
# include header files
# target_include_directories(test_runner PRIVATE ${PROJECT_SOURCE_DIR}/src/main/c/includes)
# link the library to the test executable
# target_link_libraries(test_runner PRIVATE -L${PROJECT_SOURCE_DIR}/out/build/)
# target_link_libraries(test_runner PRIVATE -lStormEngine)
target_link_libraries(test_runner PRIVATE StormEngine)
# find_library(STORM_ENGINE_NAME StormEngine PATHS ${PROJECT_SOURCE_DIR}/out/build)
# if(STORM_ENGINE_NAME)
# target_link_libraries(test_runner PRIVATE ${STORM_ENGINE_NAME})
# else()
# message("Library not found!")
# message(${STORM_ENGINE_NAME})
# message(FATAL_ERROR ${PROJECT_SOURCE_DIR}/out/build)
# endif()
# add tests for each test source file
foreach (TEST_FILE ${TEST_SOURCES})
get_filename_component (TEST_NAME ${TEST_FILE} NAME_WE)
get_filename_component (TEST_PATH ${TEST_FILE} DIRECTORY)
if(TEST_PATH)
add_test(NAME ${TEST_NAME} COMMAND test_runner ${TEST_PATH}/${TEST_NAME})
else()
add_test(NAME ${TEST_NAME} COMMAND test_runner ${TEST_NAME})
endif()
endforeach ()
# make test runner depend on library
add_dependencies(test_runner StormEngine)
if (WIN32)
# define so public header knows to export
add_definitions(-DWIN32)
endif ()

View File

@ -1,6 +1,6 @@
#include <stdio.h>
int test_c_StormEngineTests(int argc, char **argv){
int StormEngineTests(int argc, char **argv){
printf("it lives\n");
return 0;
}

View File

@ -1,5 +1,5 @@
int test_c_TestAsdf(){
int TestAsdf(){
return 0;
}

View File

@ -0,0 +1,19 @@
#include <stdio.h>
#include "fluid/chunk.h"
int fluid_FluidMemoryManagementTests(int argc, char **argv){
//allocate a sparse array
SparseChunkArray * sparseArray = fluid_create_sparse_array();
//free a sparse array
fluid_free_sparse_array(sparseArray);
return 0;
}