Keep CMake module names and trim switches, but stop flattening editing/editor and runtime bridges as top-level src/modules directories. Parent scans skip nested facets so runtime-3d can drop authoring by directory leaf. Co-authored-by: Cursor <cursoragent@cursor.com>
72 lines
3.7 KiB
C++
72 lines
3.7 KiB
C++
#include "physics/editor/EditorPhysicsAsset.h"
|
|
|
|
#include "zeroerr/assert.h"
|
|
#include "zeroerr/unittest.h"
|
|
|
|
using namespace eve::editor;
|
|
|
|
namespace {
|
|
AssetRecord collider(const char* id, const char* uri, EditorValue metadata) {
|
|
AssetRecord record;
|
|
record.guid = AssetGuid(id); record.logicalUri = uri; record.typeId = "mesh";
|
|
record.sourceUri = std::string("source/") + id; record.sourceHash = "hash";
|
|
record.importerId = "physics-test"; record.artifacts = {std::string("artifact/") + id};
|
|
record.metadata = std::move(metadata); return record;
|
|
}
|
|
}
|
|
|
|
TEST_CASE("editor.physics.asset_resolver_validates_triangle_geometry_and_uri_lookup") {
|
|
MemoryAssetDatabase database;
|
|
EditorValue::Array vertices{0.0,0.0,0.0, 1.0,0.0,0.0, 0.0,1.0,0.0};
|
|
EditorValue::Array indices{int64_t{0},int64_t{1},int64_t{2}};
|
|
CHECK(database.publish(collider("triangle", "physics/triangle", EditorValue::Object{
|
|
{"kind","triangle-mesh"},{"vertices",vertices},{"indices",indices}})).ok());
|
|
AssetDatabasePhysicsColliderResolver resolver(&database);
|
|
auto resolved = resolver.resolve("physics/triangle", "triangle-mesh");
|
|
REQUIRE(resolved.ok());
|
|
CHECK_EQ(resolved.value().vertices.size(), 9U);
|
|
CHECK_EQ(resolved.value().indices.size(), 3U);
|
|
CHECK_EQ(static_cast<int>(resolver.resolve("physics/triangle", "convex-hull").code()),
|
|
static_cast<int>(EditorStatus::Conflict));
|
|
}
|
|
|
|
TEST_CASE("editor.physics.asset_resolver_rejects_out_of_range_indices_and_builds_height_metadata") {
|
|
MemoryAssetDatabase database;
|
|
CHECK(database.publish(collider("bad", "physics/bad", EditorValue::Object{
|
|
{"kind","triangle-mesh"}, {"vertices",EditorValue::Array{0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0}},
|
|
{"indices",EditorValue::Array{int64_t{0},int64_t{1},int64_t{9}}}})).ok());
|
|
CHECK(database.publish(collider("terrain", "physics/terrain", EditorValue::Object{
|
|
{"kind","height-field"},{"countX",int64_t{2}},{"countZ",int64_t{2}},
|
|
{"cellSizeX",1.0},{"cellSizeZ",2.0},{"heights",EditorValue::Array{0.0,1.0,2.0,3.0}}})).ok());
|
|
AssetDatabasePhysicsColliderResolver resolver(&database);
|
|
CHECK_EQ(static_cast<int>(resolver.resolve("bad", "triangle-mesh").code()),
|
|
static_cast<int>(EditorStatus::Rejected));
|
|
auto height = resolver.resolve("terrain", "height-field"); REQUIRE(height.ok());
|
|
CHECK_EQ(height.value().countX, 2); CHECK_EQ(height.value().countZ, 2);
|
|
CHECK_EQ(height.value().minimumHeight, 0.0F); CHECK_EQ(height.value().maximumHeight, 3.0F);
|
|
}
|
|
|
|
TEST_CASE("editor.physics.asset_resolver_validates_2d_polygon_and_chain_metadata") {
|
|
MemoryAssetDatabase database;
|
|
CHECK(database.publish(collider("polygon", "physics/polygon", EditorValue::Object{
|
|
{"kind", "polygon"},
|
|
{"vertices", EditorValue::Array{0.0, 0.0, 2.0, 0.0, 2.0, 1.0, 0.0, 1.0}}})).ok());
|
|
CHECK(database.publish(collider("chain", "physics/chain", EditorValue::Object{
|
|
{"kind", "chain"}, {"loop", true},
|
|
{"vertices", EditorValue::Array{0.0, 0.0, 1.0, 0.0, 1.0, 1.0}}})).ok());
|
|
AssetDatabasePhysicsColliderResolver resolver(&database);
|
|
auto polygon = resolver.resolve("physics/polygon", "polygon");
|
|
REQUIRE(polygon.ok());
|
|
CHECK_EQ(polygon.value().vertices.size(), size_t{8});
|
|
auto chain = resolver.resolve("physics/chain", "chain");
|
|
REQUIRE(chain.ok());
|
|
CHECK(chain.value().loop);
|
|
|
|
CHECK(database.publish(collider("concave", "physics/concave", EditorValue::Object{
|
|
{"kind", "polygon"},
|
|
{"vertices", EditorValue::Array{0.0, 0.0, 2.0, 0.0, 1.0, 0.5, 2.0, 1.0,
|
|
0.0, 1.0}}})).ok());
|
|
CHECK_EQ(static_cast<int>(resolver.resolve("physics/concave", "polygon").code()),
|
|
static_cast<int>(EditorStatus::Rejected));
|
|
}
|