diff --git a/src/dawn/display/Transform.cpp b/src/dawn/display/Transform.cpp index 89528cad..ba1ce810 100644 --- a/src/dawn/display/Transform.cpp +++ b/src/dawn/display/Transform.cpp @@ -40,10 +40,13 @@ void Transform::updateLocalTransformFromLocalValues() { } void Transform::updateWorldTransformFromLocalTransform() { - glm::mat4 newWorld(1.0f); auto parent = this->getParent(); - if(parent != nullptr) newWorld = parent->getWorldTransform(); - this->transformWorld = newWorld * transformLocal; + if(parent != nullptr) { + auto newWorld = parent->getWorldTransform(); + this->transformWorld = newWorld * transformLocal; + } else { + this->transformWorld = transformLocal; + } } void Transform::updateLocalTransformFromWorldTransform() { @@ -128,7 +131,7 @@ void Transform::setLocalTransform(glm::mat4 transform) { } glm::vec3 Transform::getWorldPosition() { - return glm::vec3(this->transformWorld[3]); + return glm::inverse(this->transformWorld)[3]; } glm::mat4 Transform::getWorldTransform() { diff --git a/src/dawn/physics/ScenePhysicsManager.cpp b/src/dawn/physics/ScenePhysicsManager.cpp index 26fb15a0..169efa08 100644 --- a/src/dawn/physics/ScenePhysicsManager.cpp +++ b/src/dawn/physics/ScenePhysicsManager.cpp @@ -5,13 +5,32 @@ #include "ScenePhysicsManager.hpp" #include "scene/Scene.hpp" +#include "scene/components/physics/3d/Collider3D.hpp" using namespace Dawn; -ScenePhysicsManager::ScenePhysicsManager() { - +ScenePhysicsManager::ScenePhysicsManager(Scene *scene) { + this->scene = scene; } void ScenePhysicsManager::update() { +} + +std::vector ScenePhysicsManager::raycast3DAll( + struct Ray3D ray +) { + // TODO: Optimize the crap out of this. + struct Collider3DRayResult result; + auto colliders = scene->findComponents(); + std::vector results; + auto itCollider = colliders.begin(); + while(itCollider != colliders.end()) { + if((*itCollider)->raycast(&result, ray)) { + results.push_back(result); + } + ++itCollider; + } + + return results; } \ No newline at end of file diff --git a/src/dawn/physics/ScenePhysicsManager.hpp b/src/dawn/physics/ScenePhysicsManager.hpp index e1e0d222..39989e90 100644 --- a/src/dawn/physics/ScenePhysicsManager.hpp +++ b/src/dawn/physics/ScenePhysicsManager.hpp @@ -5,7 +5,7 @@ #pragma once #include "dawnlibs.hpp" -#include "scene/SceneItem.hpp" +#include "physics/3d/Ray3D.hpp" typedef int64_t scenechunk_t; @@ -13,17 +13,22 @@ typedef int64_t scenechunk_t; namespace Dawn { class Scene; + class Collider3D; + struct Collider3DRayResult; class ScenePhysicsManager { protected: - std::map> chunkItems; - std::map> itemChunks; + Scene *scene; + // std::map> chunkItems; + // std::map> itemChunks; public: - ScenePhysicsManager(); + ScenePhysicsManager(Scene *scene); void update(); + std::vector raycast3DAll(struct Ray3D ray); + friend class Scene; }; } \ No newline at end of file diff --git a/src/dawn/scene/Scene.cpp b/src/dawn/scene/Scene.cpp index a2815628..46bf1fa6 100644 --- a/src/dawn/scene/Scene.cpp +++ b/src/dawn/scene/Scene.cpp @@ -12,9 +12,9 @@ using namespace Dawn; Scene::Scene(DawnGame *game) { assertNotNull(game); - this->game = game; this->nextId = 0; + this->physics = new ScenePhysicsManager(this); } void Scene::update() { @@ -30,6 +30,7 @@ void Scene::update() { #if DAWN_DEBUG_BUILD this->debugGrid(); this->debugOrigin(); + this->debugHitboxes(); #endif // TODO: Cleanup old scene items @@ -44,6 +45,8 @@ SceneItem * Scene::createSceneItem() { } Scene::~Scene() { + delete this->physics; + // Early cleanup without disposing. auto it = this->items.begin(); while(it != this->items.end()) { diff --git a/src/dawn/scene/Scene.hpp b/src/dawn/scene/Scene.hpp index c38459fc..3e8a0add 100644 --- a/src/dawn/scene/Scene.hpp +++ b/src/dawn/scene/Scene.hpp @@ -7,6 +7,7 @@ #include "event/Event.hpp" #include "asset/Asset.hpp" #include "scene/debug/SceneDebugLine.hpp" +#include "physics/ScenePhysicsManager.hpp" namespace Dawn { class DawnGame; @@ -27,6 +28,7 @@ namespace Dawn { public: DawnGame *game; + ScenePhysicsManager *physics; Event<> eventSceneUpdate; Event<> eventSceneUnpausedUpdate; @@ -139,6 +141,7 @@ namespace Dawn { void debugCube(struct SceneDebugCube cube); void debugOrigin(); void debugGrid(); + void debugHitboxes(); #endif /** diff --git a/src/dawn/scene/SceneItemComponent.cpp b/src/dawn/scene/SceneItemComponent.cpp index 2bad3e81..94c147ea 100644 --- a/src/dawn/scene/SceneItemComponent.cpp +++ b/src/dawn/scene/SceneItemComponent.cpp @@ -33,6 +33,10 @@ DawnGame * SceneItemComponent::getGame() { return this->item->scene->game; } +ScenePhysicsManager * SceneItemComponent::getPhysics() { + return this->item->scene->physics; +} + void SceneItemComponent::onStart() { } diff --git a/src/dawn/scene/SceneItemComponent.hpp b/src/dawn/scene/SceneItemComponent.hpp index 265b2ce9..5672669e 100644 --- a/src/dawn/scene/SceneItemComponent.hpp +++ b/src/dawn/scene/SceneItemComponent.hpp @@ -52,6 +52,13 @@ namespace Dawn { */ DawnGame * getGame(); + /** + * Shorthand to return the physics manager that the scene this item + * belongs to, belongs to. + * @return The scene physics manager. + */ + ScenePhysicsManager * getPhysics(); + /** * Same as init, but intended for your subclass to override. */ diff --git a/src/dawn/scene/components/physics/3d/Collider3D.cpp b/src/dawn/scene/components/physics/3d/Collider3D.cpp index a431828a..ee5ce5b0 100644 --- a/src/dawn/scene/components/physics/3d/Collider3D.cpp +++ b/src/dawn/scene/components/physics/3d/Collider3D.cpp @@ -9,4 +9,14 @@ using namespace Dawn; Collider3D::Collider3D(SceneItem *item) : SceneItemComponent(item) { -} \ No newline at end of file +} + +bool_t Collider3D::raycast( + struct Collider3DRayResult *result, + struct Ray3D ray +) { + assertNotNull(result); + if(!this->performRaycast(result, ray)) return false; + result->collider = this; + return true; +} diff --git a/src/dawn/scene/components/physics/3d/Collider3D.hpp b/src/dawn/scene/components/physics/3d/Collider3D.hpp index 34ad698d..677ade27 100644 --- a/src/dawn/scene/components/physics/3d/Collider3D.hpp +++ b/src/dawn/scene/components/physics/3d/Collider3D.hpp @@ -12,6 +12,7 @@ namespace Dawn { glm::vec3 point; float_t distance; glm::vec3 normal; + Collider3D *collider; }; enum Collider3DType { @@ -20,6 +21,14 @@ namespace Dawn { class Collider3D : public SceneItemComponent { protected: + /** + * Internal per-collider raycast implementation. Same arguments as + * Collider3D::raycast() + */ + virtual bool_t performRaycast( + struct Collider3DRayResult *result, + struct Ray3D ray + ) = 0; public: Collider3D(SceneItem *item); @@ -31,10 +40,7 @@ namespace Dawn { * @param ray The ray to cast against. * @return True if the ray intercepts this collider, otherwise false. */ - virtual bool_t raycast( - struct Collider3DRayResult *result, - struct Ray3D ray - ) = 0; + bool_t raycast(struct Collider3DRayResult *result, struct Ray3D ray); /** * Returns which type of collider this is. Useful for performing dynamic diff --git a/src/dawn/scene/components/physics/3d/CubeCollider.cpp b/src/dawn/scene/components/physics/3d/CubeCollider.cpp index abc33765..c0b789fa 100644 --- a/src/dawn/scene/components/physics/3d/CubeCollider.cpp +++ b/src/dawn/scene/components/physics/3d/CubeCollider.cpp @@ -11,7 +11,7 @@ CubeCollider::CubeCollider(SceneItem *item) : Collider3D(item) { } -bool_t CubeCollider::raycast( +bool_t CubeCollider::performRaycast( struct Collider3DRayResult *result, struct Ray3D ray ) { diff --git a/src/dawn/scene/components/physics/3d/CubeCollider.hpp b/src/dawn/scene/components/physics/3d/CubeCollider.hpp index 434161a4..03f15650 100644 --- a/src/dawn/scene/components/physics/3d/CubeCollider.hpp +++ b/src/dawn/scene/components/physics/3d/CubeCollider.hpp @@ -9,17 +9,18 @@ namespace Dawn { class CubeCollider : public Collider3D { + protected: + bool_t performRaycast( + struct Collider3DRayResult *result, + struct Ray3D ray + ) override; + public: glm::vec3 min = glm::vec3(-0.5f, -0.5f, -0.5f); glm::vec3 max = glm::vec3(0.5f, 0.5f, 0.5f); CubeCollider(SceneItem *item); - bool_t raycast( - struct Collider3DRayResult *result, - struct Ray3D ray - ) override; - enum Collider3DType getColliderType() override; }; } \ No newline at end of file diff --git a/src/dawn/scene/debug/SceneDebugLine.cpp b/src/dawn/scene/debug/SceneDebugLine.cpp index e8782837..e3c71fbc 100644 --- a/src/dawn/scene/debug/SceneDebugLine.cpp +++ b/src/dawn/scene/debug/SceneDebugLine.cpp @@ -7,6 +7,8 @@ #include "display/shader/SimpleTexturedShader.hpp" #include "scene/components/display/Camera.hpp" #include "scene/Scene.hpp" +#include "scene/components/physics/3d/Collider3D.hpp" +#include "scene/components/physics/3d/CubeCollider.hpp" using namespace Dawn; @@ -140,4 +142,24 @@ void Scene::debugGrid() { line.v0 = glm::vec3(-s, 0, z), line.v1 = glm::vec3(s, 0, z); this->debugLine(line); } +} + +void Scene::debugHitboxes() { + auto colliders = this->findComponents(); + auto itColliders = colliders.begin(); + while(itColliders != colliders.end()) { + auto c = *itColliders; + switch(c->getColliderType()) { + case COLLIDER3D_TYPE_CUBE: + auto asCube = dynamic_cast(c); + this->debugCube((struct SceneDebugCube){ + .min = asCube->min, + .max = asCube->max, + .color = COLOR_BLUE, + .transform = asCube->transform->getWorldTransform() + }); + break; + } + ++itColliders; + } } \ No newline at end of file diff --git a/src/dawntictactoe/components/TicTacToeGame.cpp b/src/dawntictactoe/components/TicTacToeGame.cpp index 83250940..c7b4b56f 100644 --- a/src/dawntictactoe/components/TicTacToeGame.cpp +++ b/src/dawntictactoe/components/TicTacToeGame.cpp @@ -28,18 +28,19 @@ void TicTacToeGame::onSceneUpdate() { if(camera == nullptr) return; struct Ray3D ray; - ray.origin = glm::vec3(1,2,3); + ray.origin = camera->transform->getWorldPosition(); ray.direction = camera->getRayDirectionFromScreenSpace(mouse); + std::cout << "World " << ray.origin.x << ", " << ray.origin.y << ", " << ray.origin.z << std::endl; - auto collider = getScene()->findComponent(); - if(collider == nullptr) return; - - struct Collider3DRayResult result; - auto test = collider->raycast(&result, ray); - - if(test) { - getScene()->debugRay((struct SceneDebugRay){ .start = result.point, .direction = result.normal, .color = COLOR_BLUE }); - } else { - getScene()->debugRay((struct SceneDebugRay){ .start = ray.origin, .direction = ray.direction }); + auto results = getPhysics()->raycast3DAll(ray); + auto itResult = results.begin(); + while(itResult != results.end()) { + auto result = *itResult; + getScene()->debugRay((struct SceneDebugRay){ + .start = result.point, + .direction = result.normal, + .color = COLOR_BLUE + }); + ++itResult; } } \ No newline at end of file diff --git a/src/dawntictactoe/prefabs/TicTacToeTilePrefab.hpp b/src/dawntictactoe/prefabs/TicTacToeTilePrefab.hpp index 633f6f4b..9f7cbfd3 100644 --- a/src/dawntictactoe/prefabs/TicTacToeTilePrefab.hpp +++ b/src/dawntictactoe/prefabs/TicTacToeTilePrefab.hpp @@ -9,7 +9,7 @@ #include "scene/components/display/MeshHost.hpp" #include "scene/components/display/MeshRenderer.hpp" #include "scene/components/display/material/SimpleTexturedMaterial.hpp" -#include "scene/components/physics/2d/BoxCollider.hpp" +#include "scene/components/physics/3d/CubeCollider.hpp" #include "components/TicTacToeTile.hpp" namespace Dawn { @@ -28,7 +28,7 @@ namespace Dawn { MeshRenderer *meshRenderer; SimpleTexturedMaterial *material; TicTacToeTile *ticTacToe; - BoxCollider *boxCollider; + CubeCollider *collider; TicTacToeTilePrefab(Scene *s, sceneitemid_t i) : SceneItemPrefab(s,i) @@ -52,9 +52,9 @@ namespace Dawn { sprite->setSize(glm::vec2(1, 1)); sprite->setTile(0x01); - boxCollider = this->addComponent(); - boxCollider->min = glm::vec2(); - boxCollider->max = glm::vec2(1, 1); + collider = this->addComponent(); + collider->min = glm::vec3(-0.5f, -0.5f, -0.1f); + collider->max = glm::vec3( 0.5f, 0.5f, 0.1f); ticTacToe = this->addComponent(); } diff --git a/src/dawntictactoe/scenes/TicTacToeScene.hpp b/src/dawntictactoe/scenes/TicTacToeScene.hpp index 6c6f20d6..8a193ab5 100644 --- a/src/dawntictactoe/scenes/TicTacToeScene.hpp +++ b/src/dawntictactoe/scenes/TicTacToeScene.hpp @@ -19,7 +19,8 @@ namespace Dawn { camera = Camera::create(this); // camera->transform->lookAt(glm::vec3(0, 0, 5), glm::vec3(0, 0, 0)); // camera->type = CAMERA_TYPE_ORTHONOGRAPHIC; - camera->transform->lookAt(glm::vec3(1, 2, 3), glm::vec3(0, 0, 0)); + // camera->transform->lookAt(glm::vec3(1, 2, 3), glm::vec3(0, 0, 0)); + camera->transform->lookAt(glm::vec3(0, 0, 3), glm::vec3(0, 0, 0)); float_t s = 2.0f; camera->orthoTop = s; @@ -29,10 +30,6 @@ namespace Dawn { camera->orthoLeft = -s * ratio; camera->orthoRight = s * ratio; - auto cube = SimpleSpinningCubePrefab::create(this); - // TriangleMesh::createTriangleMesh(&cube->meshHost->mesh); - // SphereMesh::createSphere(&cube->meshHost->mesh, 1.0f, 16, 16); - auto gameItem = this->createSceneItem(); auto game = gameItem->addComponent();