initial commit
This commit is contained in:
76
.gitignore
vendored
Normal file
76
.gitignore
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
# Build directories
|
||||
build/
|
||||
cmake-build-*/
|
||||
out/
|
||||
bin/
|
||||
lib/
|
||||
|
||||
# IDE and editor files
|
||||
.vscode/
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.specstory/
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# CMake generated files
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
install_manifest.txt
|
||||
compile_commands.json
|
||||
CTestTestfile.cmake
|
||||
_deps
|
||||
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# Google Test
|
||||
googletest/
|
||||
|
||||
# Third party libraries (if downloaded)
|
||||
thirdparty/*/build/
|
||||
thirdparty/*/install/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Temporary files
|
||||
*.tmp
|
||||
*.temp
|
||||
12
.gitmodules
vendored
Normal file
12
.gitmodules
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
[submodule "thirdparty/SDL"]
|
||||
path = thirdparty/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "thirdparty/rapidjson"]
|
||||
path = thirdparty/rapidjson
|
||||
url = https://github.com/pah/rapidjson.git
|
||||
[submodule "thirdparty/assimp"]
|
||||
path = thirdparty/assimp
|
||||
url = https://github.com/assimp/assimp.git
|
||||
[submodule "thirdparty/SDL_image"]
|
||||
path = thirdparty/SDL_image
|
||||
url = https://github.com/libsdl-org/SDL_image.git
|
||||
56
CMakeLists.txt
Normal file
56
CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
project(nd-wfc VERSION 0.1.0 LANGUAGES CXX)
|
||||
|
||||
# Set C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# Enable testing
|
||||
enable_testing()
|
||||
|
||||
# Options
|
||||
option(ND_WFC_BUILD_TESTS "Build tests" OFF) # Temporarily disabled due to hash issue
|
||||
option(ND_WFC_BUILD_EXAMPLES "Build examples" OFF) # Temporarily disabled
|
||||
option(ND_WFC_USE_SYSTEM_LIBS "Use system libraries instead of bundled" OFF)
|
||||
|
||||
# Add subdirectories
|
||||
add_subdirectory(thirdparty)
|
||||
add_subdirectory(src)
|
||||
|
||||
if(ND_WFC_BUILD_TESTS)
|
||||
add_subdirectory(tests)
|
||||
endif()
|
||||
|
||||
if(ND_WFC_BUILD_EXAMPLES)
|
||||
add_subdirectory(examples)
|
||||
endif()
|
||||
|
||||
# Install configuration temporarily disabled
|
||||
# TODO: Fix install configuration
|
||||
# include(GNUInstallDirs)
|
||||
# install(TARGETS nd-wfc
|
||||
# EXPORT nd-wfc-targets
|
||||
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
# INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
# )
|
||||
|
||||
# Export targets
|
||||
# install(EXPORT nd-wfc-targets
|
||||
# FILE nd-wfc-targets.cmake
|
||||
# NAMESPACE nd-wfc::
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nd-wfc
|
||||
# )
|
||||
|
||||
# Generate and install package config file
|
||||
# include(CMakePackageConfigHelpers)
|
||||
# configure_package_config_file(
|
||||
# "${CMAKE_CURRENT_SOURCE_DIR}/cmake/nd-wfc-config.cmake.in"
|
||||
# "${CMAKE_CURRENT_BINARY_DIR}/nd-wfc-config.cmake"
|
||||
# INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nd-wfc
|
||||
# )
|
||||
# install(FILES "${CMAKE_CURRENT_BINARY_DIR}/nd-wfc-config.cmake"
|
||||
# DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/nd-wfc
|
||||
# )
|
||||
159
README.md
Normal file
159
README.md
Normal file
@@ -0,0 +1,159 @@
|
||||
# N-Dimensional Wave Function Collapse (nd-wfc)
|
||||
|
||||
An optimized C++ implementation of the Wave Function Collapse algorithm that supports multiple dimensions (2D, 3D, 4D, etc.).
|
||||
|
||||
## Features
|
||||
|
||||
- **N-dimensional support**: Works with 2D, 3D, 4D, and higher dimensions
|
||||
- **Optimized performance**: Efficient constraint propagation and entropy calculation
|
||||
- **Flexible tile system**: Support for weighted tiles and custom constraints
|
||||
- **Third-party integration**: Built-in support for JSON (RapidJSON), textures (STB), and 3D models (Assimp)
|
||||
- **SDL2 graphics**: Windowing and rendering capabilities for visualization
|
||||
- **Comprehensive testing**: Google Test integration for robust testing
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
nd-wfc/
|
||||
├── CMakeLists.txt # Main CMake configuration
|
||||
├── cmake/
|
||||
│ └── nd-wfc-config.cmake.in # CMake package config
|
||||
├── include/nd-wfc/ # Public headers
|
||||
│ ├── types.hpp # Core types and enums
|
||||
│ ├── wfc.hpp # Main WFC class
|
||||
│ ├── grid.hpp # N-dimensional grid
|
||||
│ ├── wave.hpp # Wave function representation
|
||||
│ ├── propagator.hpp # Constraint propagator
|
||||
│ ├── entropy.hpp # Entropy calculator
|
||||
│ ├── constraint.hpp # Constraint management
|
||||
│ └── tile.hpp # Tile system
|
||||
├── src/ # Implementation files
|
||||
├── tests/ # Google Test files
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── test_main.cpp
|
||||
│ └── test_wfc.cpp
|
||||
├── examples/ # Example programs
|
||||
│ ├── CMakeLists.txt
|
||||
│ ├── basic_wfc_2d.cpp
|
||||
│ ├── basic_wfc_3d.cpp
|
||||
│ ├── texture_generation.cpp
|
||||
│ └── model_generation.cpp
|
||||
├── thirdparty/ # External dependencies
|
||||
│ └── CMakeLists.txt
|
||||
└── build/ # Build directory (generated)
|
||||
```
|
||||
|
||||
## Building the Project
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- CMake 3.16 or higher
|
||||
- C++17 compatible compiler (GCC 8+, Clang 8+, MSVC 2019+)
|
||||
- Git
|
||||
|
||||
### Build Instructions
|
||||
|
||||
```bash
|
||||
# Clone the repository
|
||||
git clone <repository-url>
|
||||
cd nd-wfc
|
||||
|
||||
# Create build directory
|
||||
mkdir build
|
||||
cd build
|
||||
|
||||
# Configure with CMake
|
||||
cmake ..
|
||||
|
||||
# Build the project
|
||||
cmake --build . --config Release
|
||||
|
||||
# Run tests
|
||||
ctest --output-on-failure
|
||||
|
||||
# Run examples
|
||||
./examples/basic_wfc_2d
|
||||
```
|
||||
|
||||
### CMake Options
|
||||
|
||||
- `ND_WFC_BUILD_TESTS=ON/OFF` - Build tests (default: ON)
|
||||
- `ND_WFC_BUILD_EXAMPLES=ON/OFF` - Build examples (default: ON)
|
||||
- `ND_WFC_USE_SYSTEM_LIBS=ON/OFF` - Use system libraries instead of bundled (default: OFF)
|
||||
|
||||
## Usage
|
||||
|
||||
### Basic 2D Example
|
||||
|
||||
```cpp
|
||||
#include "nd-wfc/wfc.hpp"
|
||||
#include "nd-wfc/types.hpp"
|
||||
|
||||
int main() {
|
||||
// Create a 10x10 grid
|
||||
nd_wfc::Size<2> size = {10, 10};
|
||||
|
||||
// Define tile types
|
||||
std::vector<nd_wfc::TileId> tiles = {0, 1, 2, 3};
|
||||
|
||||
// Define constraints (adjacency rules)
|
||||
std::vector<nd_wfc::Constraint> constraints = {
|
||||
{0, 0, nd_wfc::Direction::North}, // Tile 0 can connect to tile 0 from North
|
||||
{0, 1, nd_wfc::Direction::South}, // Tile 0 can connect to tile 1 from South
|
||||
// ... more constraints
|
||||
};
|
||||
|
||||
// Configure WFC
|
||||
nd_wfc::WfcConfig config;
|
||||
config.seed = 12345;
|
||||
|
||||
// Create and run WFC
|
||||
nd_wfc::Wfc2D wfc(size, tiles, constraints, config);
|
||||
nd_wfc::WfcResult result = wfc.run();
|
||||
|
||||
if (result == nd_wfc::WfcResult::Success) {
|
||||
// Access the result
|
||||
const auto& grid = wfc.getGrid();
|
||||
// Use grid data...
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
### 3D Example
|
||||
|
||||
```cpp
|
||||
// Create a 3D WFC instance
|
||||
nd_wfc::Size<3> size = {8, 8, 8};
|
||||
nd_wfc::Wfc3D wfc(size, tiles, constraints, config);
|
||||
```
|
||||
|
||||
## Third-party Libraries
|
||||
|
||||
The project includes several third-party libraries:
|
||||
|
||||
- **RapidJSON**: JSON parsing and serialization
|
||||
- **STB**: Image loading and manipulation (STB Image, STB Image Write)
|
||||
- **Assimp**: 3D model loading and processing
|
||||
- **SDL2**: Graphics and windowing
|
||||
- **Google Test**: Unit testing framework
|
||||
|
||||
## Contributing
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a feature branch
|
||||
3. Make your changes
|
||||
4. Add tests for new functionality
|
||||
5. Ensure all tests pass
|
||||
6. Submit a pull request
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
|
||||
## References
|
||||
|
||||
- Original WFC Algorithm: https://github.com/mxgmn/WaveFunctionCollapse
|
||||
- N-dimensional WFC concepts and optimizations
|
||||
- Various academic papers on constraint satisfaction and procedural generation
|
||||
19
cmake/nd-wfc-config.cmake.in
Normal file
19
cmake/nd-wfc-config.cmake.in
Normal file
@@ -0,0 +1,19 @@
|
||||
@PACKAGE_INIT@
|
||||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
# Find dependencies
|
||||
find_dependency(RapidJSON REQUIRED)
|
||||
find_dependency(stb REQUIRED)
|
||||
find_dependency(assimp REQUIRED)
|
||||
# find_dependency(SDL3 REQUIRED) # Temporarily disabled
|
||||
|
||||
# Include targets
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/nd-wfc-targets.cmake")
|
||||
|
||||
# Set variables
|
||||
set(nd-wfc_FOUND TRUE)
|
||||
set(nd-wfc_VERSION "@PROJECT_VERSION@")
|
||||
|
||||
# Check required components
|
||||
check_required_components(nd-wfc)
|
||||
37
examples/CMakeLists.txt
Normal file
37
examples/CMakeLists.txt
Normal file
@@ -0,0 +1,37 @@
|
||||
set(EXAMPLE_SOURCES
|
||||
basic_wfc_2d.cpp
|
||||
basic_wfc_3d.cpp
|
||||
texture_generation.cpp
|
||||
model_generation.cpp
|
||||
)
|
||||
|
||||
# Create executables for each example
|
||||
foreach(EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
|
||||
get_filename_component(EXAMPLE_NAME ${EXAMPLE_SOURCE} NAME_WE)
|
||||
add_executable(${EXAMPLE_NAME} ${EXAMPLE_SOURCE})
|
||||
target_link_libraries(${EXAMPLE_NAME}
|
||||
PRIVATE
|
||||
nd-wfc
|
||||
# SDL3::SDL3 # Will be enabled when SDL3 is needed
|
||||
)
|
||||
target_include_directories(${EXAMPLE_NAME}
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
)
|
||||
set_target_properties(${EXAMPLE_NAME} PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/examples
|
||||
)
|
||||
endforeach()
|
||||
|
||||
# Copy resources if they exist
|
||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/resources)
|
||||
add_custom_target(copy-example-resources
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/resources
|
||||
${CMAKE_BINARY_DIR}/examples/resources
|
||||
)
|
||||
add_dependencies(basic_wfc_2d copy-example-resources)
|
||||
add_dependencies(texture_generation copy-example-resources)
|
||||
endif()
|
||||
88
examples/basic_wfc_2d.cpp
Normal file
88
examples/basic_wfc_2d.cpp
Normal file
@@ -0,0 +1,88 @@
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "nd-wfc/wfc.hpp"
|
||||
#include "nd-wfc/types.hpp"
|
||||
|
||||
int main() {
|
||||
std::cout << "Running 2D WFC Example" << std::endl;
|
||||
|
||||
// Create a 10x10 grid
|
||||
nd_wfc::Size<2> size = {10, 10};
|
||||
|
||||
// Define 4 tile types (like a simple terrain system)
|
||||
std::vector<nd_wfc::TileId> tiles = {0, 1, 2, 3}; // Empty, Grass, Water, Mountain
|
||||
|
||||
// Define adjacency constraints
|
||||
std::vector<nd_wfc::Constraint> constraints = {
|
||||
// Empty can connect to anything
|
||||
{0, 0, nd_wfc::Direction::North}, {0, 0, nd_wfc::Direction::South},
|
||||
{0, 0, nd_wfc::Direction::East}, {0, 0, nd_wfc::Direction::West},
|
||||
{0, 1, nd_wfc::Direction::North}, {0, 1, nd_wfc::Direction::South},
|
||||
{0, 1, nd_wfc::Direction::East}, {0, 1, nd_wfc::Direction::West},
|
||||
{0, 2, nd_wfc::Direction::North}, {0, 2, nd_wfc::Direction::South},
|
||||
{0, 2, nd_wfc::Direction::East}, {0, 2, nd_wfc::Direction::West},
|
||||
{0, 3, nd_wfc::Direction::North}, {0, 3, nd_wfc::Direction::South},
|
||||
{0, 3, nd_wfc::Direction::East}, {0, 3, nd_wfc::Direction::West},
|
||||
|
||||
// Grass can connect to Empty, Grass, and Mountain
|
||||
{1, 0, nd_wfc::Direction::North}, {1, 0, nd_wfc::Direction::South},
|
||||
{1, 0, nd_wfc::Direction::East}, {1, 0, nd_wfc::Direction::West},
|
||||
{1, 1, nd_wfc::Direction::North}, {1, 1, nd_wfc::Direction::South},
|
||||
{1, 1, nd_wfc::Direction::East}, {1, 1, nd_wfc::Direction::West},
|
||||
{1, 3, nd_wfc::Direction::North}, {1, 3, nd_wfc::Direction::South},
|
||||
{1, 3, nd_wfc::Direction::East}, {1, 3, nd_wfc::Direction::West},
|
||||
|
||||
// Water can only connect to Empty and Water
|
||||
{2, 0, nd_wfc::Direction::North}, {2, 0, nd_wfc::Direction::South},
|
||||
{2, 0, nd_wfc::Direction::East}, {2, 0, nd_wfc::Direction::West},
|
||||
{2, 2, nd_wfc::Direction::North}, {2, 2, nd_wfc::Direction::South},
|
||||
{2, 2, nd_wfc::Direction::East}, {2, 2, nd_wfc::Direction::West},
|
||||
|
||||
// Mountain can connect to Empty, Grass, and Mountain
|
||||
{3, 0, nd_wfc::Direction::North}, {3, 0, nd_wfc::Direction::South},
|
||||
{3, 0, nd_wfc::Direction::East}, {3, 0, nd_wfc::Direction::West},
|
||||
{3, 1, nd_wfc::Direction::North}, {3, 1, nd_wfc::Direction::South},
|
||||
{3, 1, nd_wfc::Direction::East}, {3, 1, nd_wfc::Direction::West},
|
||||
{3, 3, nd_wfc::Direction::North}, {3, 3, nd_wfc::Direction::South},
|
||||
{3, 3, nd_wfc::Direction::East}, {3, 3, nd_wfc::Direction::West},
|
||||
};
|
||||
|
||||
// Configure the WFC algorithm
|
||||
nd_wfc::WfcConfig config;
|
||||
config.seed = 12345; // For reproducible results
|
||||
config.max_iterations = 10000;
|
||||
|
||||
// Create and run WFC
|
||||
nd_wfc::Wfc2D wfc(size, tiles, constraints, config);
|
||||
|
||||
std::cout << "Running WFC algorithm..." << std::endl;
|
||||
nd_wfc::WfcResult result = wfc.run();
|
||||
|
||||
if (result == nd_wfc::WfcResult::Success) {
|
||||
std::cout << "WFC completed successfully!" << std::endl;
|
||||
std::cout << "Iterations: " << wfc.getIterationCount() << std::endl;
|
||||
|
||||
// Print the result (simple ASCII representation)
|
||||
const auto& grid = wfc.getGrid();
|
||||
for (nd_wfc::Index y = 0; y < size[1]; ++y) {
|
||||
for (nd_wfc::Index x = 0; x < size[0]; ++x) {
|
||||
nd_wfc::Coord<2> coord = {x, y};
|
||||
nd_wfc::TileId tile = grid[coord];
|
||||
char symbol;
|
||||
switch (tile) {
|
||||
case 0: symbol = '.'; break; // Empty
|
||||
case 1: symbol = 'G'; break; // Grass
|
||||
case 2: symbol = 'W'; break; // Water
|
||||
case 3: symbol = 'M'; break; // Mountain
|
||||
default: symbol = '?'; break;
|
||||
}
|
||||
std::cout << symbol << ' ';
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
} else {
|
||||
std::cout << "WFC failed with result: " << static_cast<int>(result) << std::endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
include/nd-wfc/corefiles-here
Normal file
0
include/nd-wfc/corefiles-here
Normal file
65
src/CMakeLists.txt
Normal file
65
src/CMakeLists.txt
Normal file
@@ -0,0 +1,65 @@
|
||||
set(SOURCES
|
||||
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
|
||||
)
|
||||
|
||||
# Create library
|
||||
add_library(nd-wfc ${SOURCES} ${HEADERS})
|
||||
|
||||
# Include directories
|
||||
target_include_directories(nd-wfc
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../include>
|
||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
# Link external dependencies
|
||||
# These libraries are available but not currently used in the core library
|
||||
# They will be used for future features like graphics, model loading, etc.
|
||||
|
||||
# RapidJSON - header-only, no linking needed
|
||||
if(TARGET rapidjson)
|
||||
target_link_libraries(nd-wfc INTERFACE rapidjson)
|
||||
endif()
|
||||
|
||||
# Assimp - for 3D model loading (future use)
|
||||
if(TARGET assimp)
|
||||
target_link_libraries(nd-wfc INTERFACE assimp)
|
||||
endif()
|
||||
|
||||
# SDL3 - for graphics and windowing (future use)
|
||||
if(TARGET SDL3::SDL3)
|
||||
target_link_libraries(nd-wfc INTERFACE SDL3::SDL3)
|
||||
endif()
|
||||
|
||||
# SDL_image - for image loading (future use) - temporarily disabled
|
||||
# if(TARGET SDL3_image::SDL3_image)
|
||||
# target_link_libraries(nd-wfc INTERFACE SDL3_image::SDL3_image)
|
||||
# endif()
|
||||
|
||||
# Set properties
|
||||
set_target_properties(nd-wfc PROPERTIES
|
||||
VERSION ${PROJECT_VERSION}
|
||||
SOVERSION ${PROJECT_VERSION_MAJOR}
|
||||
OUTPUT_NAME "nd-wfc"
|
||||
)
|
||||
|
||||
# Install configuration temporarily disabled
|
||||
# TODO: Fix install configuration
|
||||
# install(TARGETS nd-wfc
|
||||
# EXPORT nd-wfc-targets
|
||||
# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
# RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||
# )
|
||||
|
||||
# Install headers
|
||||
# install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../include/
|
||||
# DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
# FILES_MATCHING PATTERN "*.hpp"
|
||||
# )
|
||||
6
src/main.cpp
Normal file
6
src/main.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
|
||||
int main() {
|
||||
return 0;
|
||||
}
|
||||
56
tests/CMakeLists.txt
Normal file
56
tests/CMakeLists.txt
Normal file
@@ -0,0 +1,56 @@
|
||||
include(FetchContent)
|
||||
|
||||
# Fetch Google Test
|
||||
FetchContent_Declare(
|
||||
googletest
|
||||
URL https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip
|
||||
URL_HASH SHA256=8ad598c73ad796e0d8280b082cebd82a630d73e73cd3c70057938a6501bba5d7
|
||||
)
|
||||
FetchContent_MakeAvailable(googletest)
|
||||
|
||||
set(TEST_SOURCES
|
||||
test_main.cpp
|
||||
test_wfc.cpp
|
||||
test_grid.cpp
|
||||
test_wave.cpp
|
||||
test_propagator.cpp
|
||||
)
|
||||
|
||||
# Create test executable
|
||||
add_executable(nd-wfc-tests ${TEST_SOURCES})
|
||||
|
||||
# Include directories
|
||||
target_include_directories(nd-wfc-tests
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../include
|
||||
)
|
||||
|
||||
# Link libraries
|
||||
target_link_libraries(nd-wfc-tests
|
||||
PRIVATE
|
||||
nd-wfc
|
||||
gtest_main
|
||||
gtest
|
||||
)
|
||||
|
||||
# Set C++ standard
|
||||
set_target_properties(nd-wfc-tests PROPERTIES
|
||||
CXX_STANDARD 17
|
||||
CXX_STANDARD_REQUIRED ON
|
||||
)
|
||||
|
||||
# Register tests with CTest
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(nd-wfc-tests
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
PROPERTIES
|
||||
TIMEOUT 60
|
||||
)
|
||||
|
||||
# Add test target to run all tests
|
||||
add_custom_target(run-tests
|
||||
COMMAND nd-wfc-tests
|
||||
DEPENDS nd-wfc-tests
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
|
||||
)
|
||||
6
tests/test_main.cpp
Normal file
6
tests/test_main.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
51
tests/test_wfc.cpp
Normal file
51
tests/test_wfc.cpp
Normal file
@@ -0,0 +1,51 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "nd-wfc/wfc.hpp"
|
||||
#include "nd-wfc/types.hpp"
|
||||
|
||||
namespace nd_wfc {
|
||||
|
||||
// Basic test for 2D WFC
|
||||
TEST(WfcTest, Basic2D) {
|
||||
// Create a simple 2x2 grid with 2 tile types
|
||||
Size<2> size = {2, 2};
|
||||
std::vector<TileId> tiles = {0, 1};
|
||||
|
||||
// Simple constraints: tile 0 can connect to tile 0 and 1 in all directions
|
||||
// tile 1 can only connect to tile 1
|
||||
std::vector<Constraint> constraints = {
|
||||
{0, 0, Direction::North}, {0, 0, Direction::South},
|
||||
{0, 0, Direction::East}, {0, 0, Direction::West},
|
||||
{0, 1, Direction::North}, {0, 1, Direction::South},
|
||||
{0, 1, Direction::East}, {0, 1, Direction::West},
|
||||
{1, 1, Direction::North}, {1, 1, Direction::South},
|
||||
{1, 1, Direction::East}, {1, 1, Direction::West}
|
||||
};
|
||||
|
||||
WfcConfig config;
|
||||
config.seed = 42; // For reproducible tests
|
||||
|
||||
Wfc2D wfc(size, tiles, constraints, config);
|
||||
|
||||
WfcResult result = wfc.run();
|
||||
|
||||
// The algorithm should succeed
|
||||
EXPECT_EQ(result, WfcResult::Success);
|
||||
EXPECT_TRUE(wfc.isComplete());
|
||||
}
|
||||
|
||||
// Test grid functionality
|
||||
TEST(GridTest, Basic2D) {
|
||||
Size<2> size = {3, 3};
|
||||
Grid<2> grid(size);
|
||||
|
||||
// Test coordinate conversion
|
||||
Coord<2> coord = {1, 2};
|
||||
Index index = grid.coordToIndex(coord);
|
||||
Coord<2> back_coord = grid.indexToCoord(index);
|
||||
|
||||
EXPECT_EQ(coord, back_coord);
|
||||
EXPECT_EQ(grid.getSize(), size);
|
||||
EXPECT_EQ(grid.getTotalSize(), 9);
|
||||
}
|
||||
|
||||
} // namespace nd_wfc
|
||||
72
thirdparty/CMakeLists.txt
vendored
Normal file
72
thirdparty/CMakeLists.txt
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
# RapidJSON - header-only library
|
||||
if(ND_WFC_USE_SYSTEM_LIBS)
|
||||
find_package(RapidJSON REQUIRED)
|
||||
else()
|
||||
# Use the git submodule
|
||||
# Disable examples and tests to avoid compilation issues with newer GCC
|
||||
set(RAPIDJSON_BUILD_EXAMPLES OFF CACHE BOOL "Build RapidJSON examples" FORCE)
|
||||
set(RAPIDJSON_BUILD_TESTS OFF CACHE BOOL "Build RapidJSON tests" FORCE)
|
||||
set(RAPIDJSON_BUILD_DOC OFF CACHE BOOL "Build RapidJSON documentation" FORCE)
|
||||
add_subdirectory(rapidjson)
|
||||
|
||||
# Create a target for RapidJSON if not already created
|
||||
if(NOT TARGET rapidjson)
|
||||
add_library(rapidjson INTERFACE)
|
||||
target_include_directories(rapidjson
|
||||
INTERFACE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/rapidjson/include
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Assimp - 3D model loading
|
||||
if(ND_WFC_USE_SYSTEM_LIBS)
|
||||
find_package(assimp REQUIRED)
|
||||
else()
|
||||
# Use the git submodule
|
||||
set(ASSIMP_BUILD_TESTS OFF CACHE BOOL "Build Assimp tests" FORCE)
|
||||
set(ASSIMP_BUILD_ASSIMP_TOOLS OFF CACHE BOOL "Build Assimp tools" FORCE)
|
||||
set(ASSIMP_BUILD_SAMPLES OFF CACHE BOOL "Build Assimp samples" FORCE)
|
||||
set(ASSIMP_BUILD_DOCS OFF CACHE BOOL "Build Assimp documentation" FORCE)
|
||||
set(ASSIMP_INSTALL OFF CACHE BOOL "Install Assimp" FORCE)
|
||||
add_subdirectory(assimp)
|
||||
|
||||
# Assimp target should be created by the assimp CMakeLists.txt
|
||||
endif()
|
||||
|
||||
# SDL3 - for graphics and windowing
|
||||
if(ND_WFC_USE_SYSTEM_LIBS)
|
||||
find_package(SDL3 REQUIRED)
|
||||
else()
|
||||
# Use the git submodule
|
||||
set(SDL_SHARED OFF CACHE BOOL "Build SDL as a shared library" FORCE)
|
||||
set(SDL_STATIC ON CACHE BOOL "Build SDL as a static library" FORCE)
|
||||
set(SDL_TEST OFF CACHE BOOL "Build SDL tests" FORCE)
|
||||
set(SDL_VIDEO OFF CACHE BOOL "Enable video subsystem" FORCE) # Disable video for headless builds
|
||||
set(SDL_GPU OFF CACHE BOOL "Enable GPU subsystem" FORCE)
|
||||
set(SDL_RENDER OFF CACHE BOOL "Enable render subsystem" FORCE)
|
||||
set(SDL_CAMERA OFF CACHE BOOL "Enable camera subsystem" FORCE)
|
||||
set(SDL_UNIX_CONSOLE_BUILD ON CACHE BOOL "Build SDL for console (headless) applications" FORCE)
|
||||
add_subdirectory(SDL)
|
||||
|
||||
# SDL3 target should be created by the SDL CMakeLists.txt
|
||||
endif()
|
||||
|
||||
# SDL_image - for image loading (temporarily disabled due to SDL3 dependency issue)
|
||||
# TODO: Re-enable SDL_image once SDL3 dependency resolution is fixed
|
||||
# if(ND_WFC_USE_SYSTEM_LIBS)
|
||||
# find_package(SDL3_image REQUIRED)
|
||||
# else()
|
||||
# # Use the git submodule
|
||||
# # SDL_image should automatically find the SDL3 targets we just built
|
||||
# set(SDL3IMAGE_SHARED OFF CACHE BOOL "Build SDL_image as a shared library" FORCE)
|
||||
# set(SDL3IMAGE_STATIC ON CACHE BOOL "Build SDL_image as a static library" FORCE)
|
||||
# set(SDL3IMAGE_TESTS OFF CACHE BOOL "Build SDL_image tests" FORCE)
|
||||
# set(SDL3IMAGE_SAMPLES OFF CACHE BOOL "Build SDL_image samples" FORCE)
|
||||
# set(SDL3IMAGE_DEPS_SHARED OFF CACHE BOOL "Build SDL_image dependencies as shared libraries" FORCE)
|
||||
# set(SDL3IMAGE_VENDORED OFF CACHE BOOL "Use vendored libraries" FORCE)
|
||||
#
|
||||
# add_subdirectory(SDL_image)
|
||||
#
|
||||
# # SDL_image target should be created by the SDL_image CMakeLists.txt
|
||||
# endif()
|
||||
1
thirdparty/SDL
vendored
Submodule
1
thirdparty/SDL
vendored
Submodule
Submodule thirdparty/SDL added at ee5e249008
1
thirdparty/SDL_image
vendored
Submodule
1
thirdparty/SDL_image
vendored
Submodule
Submodule thirdparty/SDL_image added at 9415941e14
1
thirdparty/assimp
vendored
Submodule
1
thirdparty/assimp
vendored
Submodule
Submodule thirdparty/assimp added at 26e2372882
1
thirdparty/rapidjson
vendored
Submodule
1
thirdparty/rapidjson
vendored
Submodule
Submodule thirdparty/rapidjson added at fdc75bb774
Reference in New Issue
Block a user