Fixed raycast sphere.

This commit is contained in:
2023-03-18 22:58:26 -07:00
parent 669b02ca06
commit f8ab4e2abc
9 changed files with 249 additions and 189 deletions

View File

@ -131,7 +131,7 @@ void Transform::setLocalTransform(glm::mat4 transform) {
} }
glm::vec3 Transform::getWorldPosition() { glm::vec3 Transform::getWorldPosition() {
return glm::inverse(this->transformWorld)[3]; return this->transformWorld[3];
} }
glm::mat4 Transform::getWorldTransform() { glm::mat4 Transform::getWorldTransform() {

View File

@ -14,20 +14,23 @@ bool_t Dawn::raytestSphere(
glm::vec3 *normal, glm::vec3 *normal,
float_t *distance float_t *distance
) { ) {
assertNotNull(hit); float_t a = glm::dot(ray.direction, ray.direction);
assertNotNull(normal); float_t b = 2.0f * glm::dot(ray.direction, ray.origin - sphere.center);
float_t c = glm::dot(ray.origin - sphere.center, ray.origin - sphere.center);
c -= sphere.radius * sphere.radius;
glm::vec3 h, n; float_t dt = b * b - 4.0f * a * c;
auto result = glm::intersectRaySphere( if(dt < 0.0f) return false;
ray.origin, ray.direction,
sphere.center, sphere.radius, float_t t0 = (-b - sqrtf(dt)) / (a * 2.0f);
h, n if(t0 < 0.0f) return false;
);
if(!result) return result; *hit = ray.origin + t0 * ray.direction;
*hit = h; *normal = glm::normalize(*hit - sphere.center);
*normal = n; *distance = t0;
*distance = glm::distance(ray.origin, h);
return result;
return true;
} }
bool_t Dawn::raytestTriangle( bool_t Dawn::raytestTriangle(

View File

@ -9,4 +9,5 @@ target_sources(${DAWN_TARGET_NAME}
Collider3D.cpp Collider3D.cpp
CubeCollider.cpp CubeCollider.cpp
CapsuleCollider.cpp CapsuleCollider.cpp
SphereCollider.cpp
) )

View File

@ -17,7 +17,8 @@ namespace Dawn {
enum Collider3DType { enum Collider3DType {
COLLIDER3D_TYPE_CUBE, COLLIDER3D_TYPE_CUBE,
COLLIDER3D_TYPE_CAPSULE COLLIDER3D_TYPE_CAPSULE,
COLLIDER3D_TYPE_SPHERE
}; };
class Collider3D : public SceneItemComponent { class Collider3D : public SceneItemComponent {

View File

@ -0,0 +1,31 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "SphereCollider.hpp"
using namespace Dawn;
SphereCollider::SphereCollider(SceneItem *item) : Collider3D(item) {
}
enum Collider3DType SphereCollider::getColliderType() {
return COLLIDER3D_TYPE_SPHERE;
}
bool_t SphereCollider::performRaycast(
struct Collider3DRayResult *result,
struct Ray3D ray
) {
assertNotNull(result);
return raytestSphere(
ray,
{ .center = transform->getLocalPosition(), .radius = this->radius },
&result->point,
&result->normal,
&result->distance
);
}

View File

@ -0,0 +1,24 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "Collider3D.hpp"
namespace Dawn {
class SphereCollider : public Collider3D {
protected:
bool_t performRaycast(
struct Collider3DRayResult *result,
struct Ray3D ray
) override;
public:
float_t radius = 1.0f;
SphereCollider(SceneItem *item);
enum Collider3DType getColliderType() override;
};
}

View File

@ -31,7 +31,7 @@ struct ShaderPassItem SceneDebugLine::createShaderItem(
auto i = *lineIndex; auto i = *lineIndex;
item.mesh = mesh; item.mesh = mesh;
item.drawMode = MESH_DRAW_MODE_LINES; item.drawMode = MESH_DRAW_MODE_LINES;
item.renderFlags = 0x00; item.renderFlags = RENDER_MANAGER_RENDER_FLAG_DEPTH_TEST;
item.start = i * SCENE_DEBUG_LINE_INDICE_COUNT; item.start = i * SCENE_DEBUG_LINE_INDICE_COUNT;
item.count = SCENE_DEBUG_LINE_INDICE_COUNT; item.count = SCENE_DEBUG_LINE_INDICE_COUNT;

View File

@ -39,12 +39,13 @@ void PlayerController::onStart() {
// tEST // tEST
auto collider = item->getComponent<CapsuleCollider>(); auto collider = item->getComponent<Collider3D>();
assertNotNull(collider);
Collider3DRayResult result; Collider3DRayResult result;
struct Ray3D ray; struct Ray3D ray;
ray.origin = glm::vec3(0, 0.5f, 1); ray.origin = glm::vec3(0, 0.0f, 5);
ray.direction = glm::vec3(10, 0, 0); ray.direction = glm::vec3(0, 0.0f, -4);
struct Color color = COLOR_MAGENTA; struct Color color = COLOR_MAGENTA;
@ -54,7 +55,7 @@ void PlayerController::onStart() {
getScene()->debugRay({ getScene()->debugRay({
.start = result.point, .start = result.point,
.direction = (result.normal * 100.0f), .direction = result.normal,
.color = COLOR_GREEN .color = COLOR_GREEN
}); });
} }

View File

@ -7,14 +7,14 @@
#include "scene/Scene.hpp" #include "scene/Scene.hpp"
#include "scene/components/PlayerController.hpp" #include "scene/components/PlayerController.hpp"
#include "scene/components/GameCamera.hpp" #include "scene/components/GameCamera.hpp"
#include "scene/components/physics/3d/CubeCollider.hpp"
#include "scene/components/physics/3d/CapsuleCollider.hpp"
#include "scene/components/GameCamera.hpp" #include "scene/components/GameCamera.hpp"
#include "scene/components/display/MeshRenderer.hpp" #include "scene/components/display/MeshRenderer.hpp"
#include "scene/components/display/MeshHost.hpp" #include "scene/components/display/MeshHost.hpp"
#include "scene/components/display/material/SimpleTexturedMaterial.hpp" #include "scene/components/display/material/SimpleTexturedMaterial.hpp"
#include "display/mesh/CapsuleMesh.hpp"
#include "scene/components/example/ExampleSpin.hpp" #include "scene/components/example/ExampleSpin.hpp"
#include "scene/components/physics/3d/SphereCollider.hpp"
#include "scene/components/physics/3d/CubeCollider.hpp"
#include "display/mesh/SphereMesh.hpp"
namespace Dawn { namespace Dawn {
class HelloWorldScene : public Scene { class HelloWorldScene : public Scene {
@ -25,12 +25,11 @@ namespace Dawn {
auto playerItem = this->createSceneItem(); auto playerItem = this->createSceneItem();
auto player = playerItem->addComponent<PlayerController>(); auto player = playerItem->addComponent<PlayerController>();
auto hitbox = playerItem->addComponent<CapsuleCollider>();
playerItem->addComponent<MeshRenderer>(); playerItem->addComponent<MeshRenderer>();
auto meshHost = playerItem->addComponent<MeshHost>(); auto meshHost = playerItem->addComponent<MeshHost>();
playerItem->addComponent<SimpleTexturedMaterial>(); playerItem->addComponent<SimpleTexturedMaterial>();
auto hitbox = playerItem->addComponent<SphereCollider>();
CapsuleMesh::create(&meshHost->mesh, hitbox->radius, hitbox->height); SphereMesh::createSphere(&meshHost->mesh, hitbox->radius, 32, 32);
auto wall = this->createSceneItem(); auto wall = this->createSceneItem();
auto wallHitbox = wall->addComponent<CubeCollider>(); auto wallHitbox = wall->addComponent<CubeCollider>();