feat: add debug rendering for other types of colliders / split game into more logical functions / files
This commit is contained in:
@@ -30,6 +30,8 @@
|
||||
#include <destrum/Components/Physics/Collider.h>
|
||||
#include <destrum/Components/Animator.h>
|
||||
#include <destrum/Components/CameraComponent.h>
|
||||
#include <destrum/Graphics/Resources/PrimitiveMeshes.h>
|
||||
#include <destrum/Graphics/Managers/LineRenderingManager.h>
|
||||
#include <destrum/Components/LightComponent.h>
|
||||
#include <destrum/Components/Physics/Rigidbody.h>
|
||||
#include <destrum/Graphics/Material.h>
|
||||
@@ -429,6 +431,85 @@ namespace {
|
||||
SceneManager::GetInstance().Destroy();
|
||||
}
|
||||
|
||||
void testCapsuleColliderDebugLines()
|
||||
{
|
||||
GameObject object{"capsule"};
|
||||
object.GetTransform().SetWorldPosition({1.0f, 2.0f, 3.0f});
|
||||
object.GetTransform().SetWorldScale(glm::vec3{5.0f});
|
||||
auto* capsule = object.AddComponent<CapsuleCollider>(0.4f, 1.8f);
|
||||
capsule->SetCenterOffset({0.0f, 0.5f, 0.0f});
|
||||
|
||||
auto& lines = LineRenderingManager::GetInstance();
|
||||
lines.ClearLines();
|
||||
capsule->DrawDebugLines(glm::vec4{1.0f});
|
||||
|
||||
const glm::vec3 center{1.0f, 2.5f, 3.0f};
|
||||
float top = -1000.0f;
|
||||
float bottom = 1000.0f;
|
||||
bool inside = true;
|
||||
for (const Line& line : lines.GetLines()) {
|
||||
for (const glm::vec3& point : {line.start, line.end}) {
|
||||
const glm::vec3 local = point - center;
|
||||
top = std::max(top, local.y);
|
||||
bottom = std::min(bottom, local.y);
|
||||
inside = inside && glm::length(glm::vec2{local.x, local.z}) <= 0.4f + 0.001f;
|
||||
}
|
||||
}
|
||||
lines.ClearLines();
|
||||
|
||||
check(inside && close(top, 0.9f) && close(bottom, -0.9f),
|
||||
"capsule debug lines must match the collider shape in world units, ignoring the object scale");
|
||||
}
|
||||
|
||||
void testColliderCenterOffset()
|
||||
{
|
||||
Scene& scene = SceneManager::GetInstance().CreateScene("collider-offset");
|
||||
|
||||
GameObject* box = scene.CreateGameObject("offset box");
|
||||
box->AddComponent<BoxCollider>(glm::vec3{0.5f})->SetCenterOffset({0.0f, 5.0f, 0.0f});
|
||||
box->AddComponent<Rigidbody>()->SetType(RigidbodyType::Static);
|
||||
scene.CommitPendingAdditions();
|
||||
scene.GetPhysics().RefreshGameObject(*box);
|
||||
|
||||
PhysicsRaycastHit hit{};
|
||||
const bool found = box->GetComponent<Rigidbody>()->GetPhysicsWorld()->Raycast(
|
||||
{0.0f, 10.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, 20.0f, hit);
|
||||
check(found && std::abs(hit.distance - 4.5f) < 0.01f,
|
||||
"a collider center offset must move the shape, not just the center of mass");
|
||||
|
||||
SceneManager::GetInstance().Destroy();
|
||||
}
|
||||
|
||||
void testPrimitiveBoxMesh()
|
||||
{
|
||||
const glm::vec3 size{4.0f, 1.0f, 2.0f};
|
||||
const CPUMesh box = PrimitiveMeshes::MakeBox(size);
|
||||
|
||||
check(box.vertices.size() == 24 && box.indices.size() == 36, "a box must have 6 faces of 2 triangles");
|
||||
check(box.minPos == -size * 0.5f && box.maxPos == size * 0.5f, "a box must be centered on the origin");
|
||||
|
||||
float maxU = 0.0f;
|
||||
bool outward = true;
|
||||
for (const auto& vertex : box.vertices) {
|
||||
if (vertex.normal == glm::vec3{0.0f, 0.0f, 1.0f}) {
|
||||
maxU = std::max(maxU, vertex.uv_x);
|
||||
}
|
||||
outward = outward && glm::dot(vertex.position, vertex.normal) > 0.0f;
|
||||
}
|
||||
check(close(maxU, size.x), "box uvs must be in meters so textures tile at the same size");
|
||||
check(outward, "box normals must point away from the center");
|
||||
|
||||
bool counterClockwise = true;
|
||||
for (std::size_t i = 0; i < box.indices.size(); i += 3) {
|
||||
const auto& a = box.vertices[box.indices[i]];
|
||||
const auto& b = box.vertices[box.indices[i + 1]];
|
||||
const auto& c = box.vertices[box.indices[i + 2]];
|
||||
const glm::vec3 faceNormal = glm::cross(b.position - a.position, c.position - a.position);
|
||||
counterClockwise = counterClockwise && glm::dot(faceNormal, a.normal) > 0.0f;
|
||||
}
|
||||
check(counterClockwise, "box triangles must be counter clockwise seen from outside");
|
||||
}
|
||||
|
||||
void testFrozenRotationCapsule()
|
||||
{
|
||||
Scene& scene = SceneManager::GetInstance().CreateScene("frozen-capsule");
|
||||
@@ -1047,6 +1128,9 @@ int main()
|
||||
testTriggerZone();
|
||||
testSceneCurrentCamera();
|
||||
testFrozenRotationCapsule();
|
||||
testPrimitiveBoxMesh();
|
||||
testColliderCenterOffset();
|
||||
testCapsuleColliderDebugLines();
|
||||
std::cout << "destrum tests passed\n";
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user