PRetty good collision detection but there is still some small bug I don't know about
This commit is contained in:
@ -40,10 +40,13 @@ void Transform::updateLocalTransformFromLocalValues() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Transform::updateWorldTransformFromLocalTransform() {
|
void Transform::updateWorldTransformFromLocalTransform() {
|
||||||
glm::mat4 newWorld(1.0f);
|
|
||||||
auto parent = this->getParent();
|
auto parent = this->getParent();
|
||||||
if(parent != nullptr) newWorld = parent->getWorldTransform();
|
if(parent != nullptr) {
|
||||||
this->transformWorld = newWorld * transformLocal;
|
auto newWorld = parent->getWorldTransform();
|
||||||
|
this->transformWorld = newWorld * transformLocal;
|
||||||
|
} else {
|
||||||
|
this->transformWorld = transformLocal;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Transform::updateLocalTransformFromWorldTransform() {
|
void Transform::updateLocalTransformFromWorldTransform() {
|
||||||
@ -128,7 +131,7 @@ void Transform::setLocalTransform(glm::mat4 transform) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 Transform::getWorldPosition() {
|
glm::vec3 Transform::getWorldPosition() {
|
||||||
return glm::vec3(this->transformWorld[3]);
|
return glm::inverse(this->transformWorld)[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 Transform::getWorldTransform() {
|
glm::mat4 Transform::getWorldTransform() {
|
||||||
|
@ -5,13 +5,32 @@
|
|||||||
|
|
||||||
#include "ScenePhysicsManager.hpp"
|
#include "ScenePhysicsManager.hpp"
|
||||||
#include "scene/Scene.hpp"
|
#include "scene/Scene.hpp"
|
||||||
|
#include "scene/components/physics/3d/Collider3D.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
ScenePhysicsManager::ScenePhysicsManager() {
|
ScenePhysicsManager::ScenePhysicsManager(Scene *scene) {
|
||||||
|
this->scene = scene;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScenePhysicsManager::update() {
|
void ScenePhysicsManager::update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<struct Collider3DRayResult> ScenePhysicsManager::raycast3DAll(
|
||||||
|
struct Ray3D ray
|
||||||
|
) {
|
||||||
|
// TODO: Optimize the crap out of this.
|
||||||
|
struct Collider3DRayResult result;
|
||||||
|
auto colliders = scene->findComponents<Collider3D>();
|
||||||
|
std::vector<struct Collider3DRayResult> results;
|
||||||
|
auto itCollider = colliders.begin();
|
||||||
|
while(itCollider != colliders.end()) {
|
||||||
|
if((*itCollider)->raycast(&result, ray)) {
|
||||||
|
results.push_back(result);
|
||||||
|
}
|
||||||
|
++itCollider;
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "dawnlibs.hpp"
|
#include "dawnlibs.hpp"
|
||||||
#include "scene/SceneItem.hpp"
|
#include "physics/3d/Ray3D.hpp"
|
||||||
|
|
||||||
typedef int64_t scenechunk_t;
|
typedef int64_t scenechunk_t;
|
||||||
|
|
||||||
@ -13,17 +13,22 @@ typedef int64_t scenechunk_t;
|
|||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class Scene;
|
class Scene;
|
||||||
|
class Collider3D;
|
||||||
|
struct Collider3DRayResult;
|
||||||
|
|
||||||
class ScenePhysicsManager {
|
class ScenePhysicsManager {
|
||||||
protected:
|
protected:
|
||||||
std::map<scenechunk_t, std::vector<SceneItem*>> chunkItems;
|
Scene *scene;
|
||||||
std::map<SceneItem*, std::vector<scenechunk_t>> itemChunks;
|
// std::map<scenechunk_t, std::vector<SceneItem*>> chunkItems;
|
||||||
|
// std::map<SceneItem*, std::vector<scenechunk_t>> itemChunks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ScenePhysicsManager();
|
ScenePhysicsManager(Scene *scene);
|
||||||
|
|
||||||
void update();
|
void update();
|
||||||
|
|
||||||
|
std::vector<struct Collider3DRayResult> raycast3DAll(struct Ray3D ray);
|
||||||
|
|
||||||
friend class Scene;
|
friend class Scene;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -12,9 +12,9 @@ using namespace Dawn;
|
|||||||
|
|
||||||
Scene::Scene(DawnGame *game) {
|
Scene::Scene(DawnGame *game) {
|
||||||
assertNotNull(game);
|
assertNotNull(game);
|
||||||
|
|
||||||
this->game = game;
|
this->game = game;
|
||||||
this->nextId = 0;
|
this->nextId = 0;
|
||||||
|
this->physics = new ScenePhysicsManager(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scene::update() {
|
void Scene::update() {
|
||||||
@ -30,6 +30,7 @@ void Scene::update() {
|
|||||||
#if DAWN_DEBUG_BUILD
|
#if DAWN_DEBUG_BUILD
|
||||||
this->debugGrid();
|
this->debugGrid();
|
||||||
this->debugOrigin();
|
this->debugOrigin();
|
||||||
|
this->debugHitboxes();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Cleanup old scene items
|
// TODO: Cleanup old scene items
|
||||||
@ -44,6 +45,8 @@ SceneItem * Scene::createSceneItem() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Scene::~Scene() {
|
Scene::~Scene() {
|
||||||
|
delete this->physics;
|
||||||
|
|
||||||
// Early cleanup without disposing.
|
// Early cleanup without disposing.
|
||||||
auto it = this->items.begin();
|
auto it = this->items.begin();
|
||||||
while(it != this->items.end()) {
|
while(it != this->items.end()) {
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include "event/Event.hpp"
|
#include "event/Event.hpp"
|
||||||
#include "asset/Asset.hpp"
|
#include "asset/Asset.hpp"
|
||||||
#include "scene/debug/SceneDebugLine.hpp"
|
#include "scene/debug/SceneDebugLine.hpp"
|
||||||
|
#include "physics/ScenePhysicsManager.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class DawnGame;
|
class DawnGame;
|
||||||
@ -27,6 +28,7 @@ namespace Dawn {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
DawnGame *game;
|
DawnGame *game;
|
||||||
|
ScenePhysicsManager *physics;
|
||||||
Event<> eventSceneUpdate;
|
Event<> eventSceneUpdate;
|
||||||
Event<> eventSceneUnpausedUpdate;
|
Event<> eventSceneUnpausedUpdate;
|
||||||
|
|
||||||
@ -139,6 +141,7 @@ namespace Dawn {
|
|||||||
void debugCube(struct SceneDebugCube cube);
|
void debugCube(struct SceneDebugCube cube);
|
||||||
void debugOrigin();
|
void debugOrigin();
|
||||||
void debugGrid();
|
void debugGrid();
|
||||||
|
void debugHitboxes();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,6 +33,10 @@ DawnGame * SceneItemComponent::getGame() {
|
|||||||
return this->item->scene->game;
|
return this->item->scene->game;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScenePhysicsManager * SceneItemComponent::getPhysics() {
|
||||||
|
return this->item->scene->physics;
|
||||||
|
}
|
||||||
|
|
||||||
void SceneItemComponent::onStart() {
|
void SceneItemComponent::onStart() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,13 @@ namespace Dawn {
|
|||||||
*/
|
*/
|
||||||
DawnGame * getGame();
|
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.
|
* Same as init, but intended for your subclass to override.
|
||||||
*/
|
*/
|
||||||
|
@ -9,4 +9,14 @@ using namespace Dawn;
|
|||||||
|
|
||||||
Collider3D::Collider3D(SceneItem *item) : SceneItemComponent(item) {
|
Collider3D::Collider3D(SceneItem *item) : SceneItemComponent(item) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool_t Collider3D::raycast(
|
||||||
|
struct Collider3DRayResult *result,
|
||||||
|
struct Ray3D ray
|
||||||
|
) {
|
||||||
|
assertNotNull(result);
|
||||||
|
if(!this->performRaycast(result, ray)) return false;
|
||||||
|
result->collider = this;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@ namespace Dawn {
|
|||||||
glm::vec3 point;
|
glm::vec3 point;
|
||||||
float_t distance;
|
float_t distance;
|
||||||
glm::vec3 normal;
|
glm::vec3 normal;
|
||||||
|
Collider3D *collider;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Collider3DType {
|
enum Collider3DType {
|
||||||
@ -20,6 +21,14 @@ namespace Dawn {
|
|||||||
|
|
||||||
class Collider3D : public SceneItemComponent {
|
class Collider3D : public SceneItemComponent {
|
||||||
protected:
|
protected:
|
||||||
|
/**
|
||||||
|
* Internal per-collider raycast implementation. Same arguments as
|
||||||
|
* Collider3D::raycast()
|
||||||
|
*/
|
||||||
|
virtual bool_t performRaycast(
|
||||||
|
struct Collider3DRayResult *result,
|
||||||
|
struct Ray3D ray
|
||||||
|
) = 0;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Collider3D(SceneItem *item);
|
Collider3D(SceneItem *item);
|
||||||
@ -31,10 +40,7 @@ namespace Dawn {
|
|||||||
* @param ray The ray to cast against.
|
* @param ray The ray to cast against.
|
||||||
* @return True if the ray intercepts this collider, otherwise false.
|
* @return True if the ray intercepts this collider, otherwise false.
|
||||||
*/
|
*/
|
||||||
virtual bool_t raycast(
|
bool_t raycast(struct Collider3DRayResult *result, struct Ray3D ray);
|
||||||
struct Collider3DRayResult *result,
|
|
||||||
struct Ray3D ray
|
|
||||||
) = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns which type of collider this is. Useful for performing dynamic
|
* Returns which type of collider this is. Useful for performing dynamic
|
||||||
|
@ -11,7 +11,7 @@ CubeCollider::CubeCollider(SceneItem *item) : Collider3D(item) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t CubeCollider::raycast(
|
bool_t CubeCollider::performRaycast(
|
||||||
struct Collider3DRayResult *result,
|
struct Collider3DRayResult *result,
|
||||||
struct Ray3D ray
|
struct Ray3D ray
|
||||||
) {
|
) {
|
||||||
|
@ -9,17 +9,18 @@
|
|||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
class CubeCollider : public Collider3D {
|
class CubeCollider : public Collider3D {
|
||||||
|
protected:
|
||||||
|
bool_t performRaycast(
|
||||||
|
struct Collider3DRayResult *result,
|
||||||
|
struct Ray3D ray
|
||||||
|
) override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
glm::vec3 min = glm::vec3(-0.5f, -0.5f, -0.5f);
|
glm::vec3 min = glm::vec3(-0.5f, -0.5f, -0.5f);
|
||||||
glm::vec3 max = glm::vec3(0.5f, 0.5f, 0.5f);
|
glm::vec3 max = glm::vec3(0.5f, 0.5f, 0.5f);
|
||||||
|
|
||||||
CubeCollider(SceneItem *item);
|
CubeCollider(SceneItem *item);
|
||||||
|
|
||||||
bool_t raycast(
|
|
||||||
struct Collider3DRayResult *result,
|
|
||||||
struct Ray3D ray
|
|
||||||
) override;
|
|
||||||
|
|
||||||
enum Collider3DType getColliderType() override;
|
enum Collider3DType getColliderType() override;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -7,6 +7,8 @@
|
|||||||
#include "display/shader/SimpleTexturedShader.hpp"
|
#include "display/shader/SimpleTexturedShader.hpp"
|
||||||
#include "scene/components/display/Camera.hpp"
|
#include "scene/components/display/Camera.hpp"
|
||||||
#include "scene/Scene.hpp"
|
#include "scene/Scene.hpp"
|
||||||
|
#include "scene/components/physics/3d/Collider3D.hpp"
|
||||||
|
#include "scene/components/physics/3d/CubeCollider.hpp"
|
||||||
|
|
||||||
using namespace Dawn;
|
using namespace Dawn;
|
||||||
|
|
||||||
@ -140,4 +142,24 @@ void Scene::debugGrid() {
|
|||||||
line.v0 = glm::vec3(-s, 0, z), line.v1 = glm::vec3(s, 0, z);
|
line.v0 = glm::vec3(-s, 0, z), line.v1 = glm::vec3(s, 0, z);
|
||||||
this->debugLine(line);
|
this->debugLine(line);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::debugHitboxes() {
|
||||||
|
auto colliders = this->findComponents<Collider3D>();
|
||||||
|
auto itColliders = colliders.begin();
|
||||||
|
while(itColliders != colliders.end()) {
|
||||||
|
auto c = *itColliders;
|
||||||
|
switch(c->getColliderType()) {
|
||||||
|
case COLLIDER3D_TYPE_CUBE:
|
||||||
|
auto asCube = dynamic_cast<CubeCollider*>(c);
|
||||||
|
this->debugCube((struct SceneDebugCube){
|
||||||
|
.min = asCube->min,
|
||||||
|
.max = asCube->max,
|
||||||
|
.color = COLOR_BLUE,
|
||||||
|
.transform = asCube->transform->getWorldTransform()
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
++itColliders;
|
||||||
|
}
|
||||||
}
|
}
|
@ -28,18 +28,19 @@ void TicTacToeGame::onSceneUpdate() {
|
|||||||
if(camera == nullptr) return;
|
if(camera == nullptr) return;
|
||||||
|
|
||||||
struct Ray3D ray;
|
struct Ray3D ray;
|
||||||
ray.origin = glm::vec3(1,2,3);
|
ray.origin = camera->transform->getWorldPosition();
|
||||||
ray.direction = camera->getRayDirectionFromScreenSpace(mouse);
|
ray.direction = camera->getRayDirectionFromScreenSpace(mouse);
|
||||||
|
std::cout << "World " << ray.origin.x << ", " << ray.origin.y << ", " << ray.origin.z << std::endl;
|
||||||
|
|
||||||
auto collider = getScene()->findComponent<CubeCollider>();
|
auto results = getPhysics()->raycast3DAll(ray);
|
||||||
if(collider == nullptr) return;
|
auto itResult = results.begin();
|
||||||
|
while(itResult != results.end()) {
|
||||||
struct Collider3DRayResult result;
|
auto result = *itResult;
|
||||||
auto test = collider->raycast(&result, ray);
|
getScene()->debugRay((struct SceneDebugRay){
|
||||||
|
.start = result.point,
|
||||||
if(test) {
|
.direction = result.normal,
|
||||||
getScene()->debugRay((struct SceneDebugRay){ .start = result.point, .direction = result.normal, .color = COLOR_BLUE });
|
.color = COLOR_BLUE
|
||||||
} else {
|
});
|
||||||
getScene()->debugRay((struct SceneDebugRay){ .start = ray.origin, .direction = ray.direction });
|
++itResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,7 +9,7 @@
|
|||||||
#include "scene/components/display/MeshHost.hpp"
|
#include "scene/components/display/MeshHost.hpp"
|
||||||
#include "scene/components/display/MeshRenderer.hpp"
|
#include "scene/components/display/MeshRenderer.hpp"
|
||||||
#include "scene/components/display/material/SimpleTexturedMaterial.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"
|
#include "components/TicTacToeTile.hpp"
|
||||||
|
|
||||||
namespace Dawn {
|
namespace Dawn {
|
||||||
@ -28,7 +28,7 @@ namespace Dawn {
|
|||||||
MeshRenderer *meshRenderer;
|
MeshRenderer *meshRenderer;
|
||||||
SimpleTexturedMaterial *material;
|
SimpleTexturedMaterial *material;
|
||||||
TicTacToeTile *ticTacToe;
|
TicTacToeTile *ticTacToe;
|
||||||
BoxCollider *boxCollider;
|
CubeCollider *collider;
|
||||||
|
|
||||||
TicTacToeTilePrefab(Scene *s, sceneitemid_t i) :
|
TicTacToeTilePrefab(Scene *s, sceneitemid_t i) :
|
||||||
SceneItemPrefab<TicTacToeTilePrefab>(s,i)
|
SceneItemPrefab<TicTacToeTilePrefab>(s,i)
|
||||||
@ -52,9 +52,9 @@ namespace Dawn {
|
|||||||
sprite->setSize(glm::vec2(1, 1));
|
sprite->setSize(glm::vec2(1, 1));
|
||||||
sprite->setTile(0x01);
|
sprite->setTile(0x01);
|
||||||
|
|
||||||
boxCollider = this->addComponent<BoxCollider>();
|
collider = this->addComponent<CubeCollider>();
|
||||||
boxCollider->min = glm::vec2();
|
collider->min = glm::vec3(-0.5f, -0.5f, -0.1f);
|
||||||
boxCollider->max = glm::vec2(1, 1);
|
collider->max = glm::vec3( 0.5f, 0.5f, 0.1f);
|
||||||
|
|
||||||
ticTacToe = this->addComponent<TicTacToeTile>();
|
ticTacToe = this->addComponent<TicTacToeTile>();
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,8 @@ namespace Dawn {
|
|||||||
camera = Camera::create(this);
|
camera = Camera::create(this);
|
||||||
// camera->transform->lookAt(glm::vec3(0, 0, 5), glm::vec3(0, 0, 0));
|
// camera->transform->lookAt(glm::vec3(0, 0, 5), glm::vec3(0, 0, 0));
|
||||||
// camera->type = CAMERA_TYPE_ORTHONOGRAPHIC;
|
// 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;
|
float_t s = 2.0f;
|
||||||
camera->orthoTop = s;
|
camera->orthoTop = s;
|
||||||
@ -29,10 +30,6 @@ namespace Dawn {
|
|||||||
camera->orthoLeft = -s * ratio;
|
camera->orthoLeft = -s * ratio;
|
||||||
camera->orthoRight = 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 gameItem = this->createSceneItem();
|
||||||
auto game = gameItem->addComponent<TicTacToeGame>();
|
auto game = gameItem->addComponent<TicTacToeGame>();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user