171 lines
5.0 KiB
C++
171 lines
5.0 KiB
C++
#define TEST_NO_MAIN
|
|
#include "acutest.h"
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include <cstdlib>
|
|
#include "../include/ECSComponents.h"
|
|
#include "../include/SceneGraph.h"
|
|
#include "../include/SceneLoader.h"
|
|
#include "../include/ModelManager.h"
|
|
#include "../include/ShaderManager.h"
|
|
#include "raylib.h"
|
|
#include "entt.hpp"
|
|
|
|
static bool HasDisplay() {
|
|
#if defined(_WIN32)
|
|
return true;
|
|
#elif defined(__APPLE__)
|
|
return true;
|
|
#else
|
|
const char* display = std::getenv("DISPLAY");
|
|
const char* wayland = std::getenv("WAYLAND_DISPLAY");
|
|
return (display && *display) || (wayland && *wayland);
|
|
#endif
|
|
}
|
|
|
|
static bool InitRaylibHidden() {
|
|
const char* forceHeadless = std::getenv("SIMIAN_HEADLESS");
|
|
if (forceHeadless && forceHeadless[0] == '1') {
|
|
return false;
|
|
}
|
|
|
|
if (!HasDisplay()) {
|
|
return false;
|
|
}
|
|
|
|
if (!IsWindowReady()) {
|
|
SetConfigFlags(FLAG_WINDOW_HIDDEN);
|
|
InitWindow(1, 1, "simian_test_scene");
|
|
SetTargetFPS(60);
|
|
}
|
|
|
|
return IsWindowReady();
|
|
}
|
|
|
|
static void ShutdownRaylibHidden() {
|
|
if (IsWindowReady()) {
|
|
CloseWindow();
|
|
}
|
|
}
|
|
|
|
void test_scenegraph_world_transform(void) {
|
|
entt::registry registry;
|
|
|
|
entt::entity parent = registry.create();
|
|
entt::entity child = registry.create();
|
|
|
|
registry.emplace<ECSTransform>(parent, Vector3{1.0f, 0.0f, 0.0f}, Vector3{2.0f, 2.0f, 2.0f}, 0.0f);
|
|
registry.emplace<ECSTransform>(child, Vector3{1.0f, 0.0f, 0.0f}, Vector3{1.0f, 1.0f, 1.0f}, 0.0f);
|
|
|
|
AttachChild(registry, child, parent);
|
|
UpdateWorldTransforms(registry);
|
|
|
|
auto* childWorld = registry.try_get<WorldTransform>(child);
|
|
TEST_CHECK(childWorld != nullptr);
|
|
if (childWorld) {
|
|
TEST_CHECK(childWorld->position.x == 3.0f);
|
|
TEST_CHECK(childWorld->position.y == 0.0f);
|
|
TEST_CHECK(childWorld->position.z == 0.0f);
|
|
}
|
|
}
|
|
|
|
void test_scenegraph_detach(void) {
|
|
entt::registry registry;
|
|
|
|
entt::entity parent = registry.create();
|
|
entt::entity child = registry.create();
|
|
|
|
AttachChild(registry, child, parent);
|
|
DetachFromParent(registry, child);
|
|
|
|
auto* childHierarchy = registry.try_get<Hierarchy>(child);
|
|
TEST_CHECK(childHierarchy != nullptr);
|
|
if (childHierarchy) {
|
|
TEST_CHECK(childHierarchy->parent == entt::null);
|
|
TEST_CHECK(childHierarchy->prev == entt::null);
|
|
TEST_CHECK(childHierarchy->next == entt::null);
|
|
}
|
|
|
|
auto* parentHierarchy = registry.try_get<Hierarchy>(parent);
|
|
TEST_CHECK(parentHierarchy != nullptr);
|
|
if (parentHierarchy) {
|
|
TEST_CHECK(parentHierarchy->first == entt::null);
|
|
}
|
|
}
|
|
|
|
void test_scene_loader_basic(void) {
|
|
if (!InitRaylibHidden()) {
|
|
TEST_SKIP("No display available for raylib");
|
|
return;
|
|
}
|
|
|
|
entt::registry registry;
|
|
ModelManager modelManager;
|
|
ShaderManager shaderManager;
|
|
SetSceneContext(®istry, &modelManager, &shaderManager);
|
|
|
|
std::filesystem::path tmpDir = std::filesystem::current_path() / "tmp_scene";
|
|
std::filesystem::create_directories(tmpDir);
|
|
std::filesystem::path scenePath = tmpDir / "scene.toml";
|
|
|
|
{
|
|
std::ofstream scene(scenePath);
|
|
scene << "[[entity]]\n";
|
|
scene << "id = \"root\"\n";
|
|
scene << "tag = \"Root\"\n";
|
|
scene << "position = [0.0, 0.0, 0.0]\n";
|
|
scene << "\n";
|
|
scene << "[[entity]]\n";
|
|
scene << "id = \"parent\"\n";
|
|
scene << "parent = \"root\"\n";
|
|
scene << "tag = \"Parent\"\n";
|
|
scene << "position = [1.0, 0.0, 0.0]\n";
|
|
scene << "model = \"cube\"\n";
|
|
scene << "model_size = [1.0, 1.0, 1.0]\n";
|
|
scene << "color = 0x00FF00FF\n";
|
|
scene << "\n";
|
|
scene << "[[entity]]\n";
|
|
scene << "id = \"child\"\n";
|
|
scene << "parent = \"parent\"\n";
|
|
scene << "tag = \"Child\"\n";
|
|
scene << "position = [0.0, 1.0, 0.0]\n";
|
|
scene << "model = \"sphere\"\n";
|
|
scene << "radius = 0.5\n";
|
|
scene << "color = 0xFF0000FF\n";
|
|
}
|
|
|
|
entt::entity root = LoadSceneFromFile(scenePath.string(), true);
|
|
TEST_CHECK(root != entt::null);
|
|
|
|
entt::entity parentEntity = entt::null;
|
|
entt::entity childEntity = entt::null;
|
|
|
|
auto tagView = registry.view<Tag>();
|
|
for (auto entity : tagView) {
|
|
const auto& tag = tagView.get<Tag>(entity);
|
|
if (tag.name == "Parent") {
|
|
parentEntity = entity;
|
|
} else if (tag.name == "Child") {
|
|
childEntity = entity;
|
|
}
|
|
}
|
|
|
|
TEST_CHECK(parentEntity != entt::null);
|
|
TEST_CHECK(childEntity != entt::null);
|
|
|
|
if (parentEntity != entt::null && childEntity != entt::null) {
|
|
auto* childHierarchy = registry.try_get<Hierarchy>(childEntity);
|
|
TEST_CHECK(childHierarchy != nullptr);
|
|
if (childHierarchy) {
|
|
TEST_CHECK(childHierarchy->parent == parentEntity);
|
|
}
|
|
TEST_CHECK(registry.all_of<Sprite>(parentEntity));
|
|
TEST_CHECK(registry.all_of<Sprite>(childEntity));
|
|
}
|
|
|
|
std::filesystem::remove(scenePath);
|
|
std::filesystem::remove(tmpDir);
|
|
|
|
ShutdownRaylibHidden();
|
|
}
|