Removed physics for now.

This commit is contained in:
YourWishes committed 2023-11-12 23:29:52 -06:00
1 parent 54da3733d7
commit 2d4287a277
62 files changed
+447 -357

No files matched your search

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+10
View File
@@ -0,0 +1,10 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
Ray3D.cpp
)
File renamed without changes.
File renamed without changes.
+257
View File
@@ -0,0 +1,257 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#include "Ray3D.hpp"
using namespace Dawn;
bool_t Dawn::raytestSphere(
struct Ray3D ray,
struct PhysicsSphere sphere,
glm::vec3 *hit,
glm::vec3 *normal,
float_t *distance
) {
float_t a = glm::dot(ray.direction, ray.direction);
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;
float_t dt = b * b - 4.0f * a * c;
if(dt < 0.0f) return false;
float_t t0 = (-b - sqrtf(dt)) / (a * 2.0f);
if(t0 < 0.0f) return false;
*hit = ray.origin + t0 * ray.direction;
*normal = glm::normalize(*hit - sphere.center);
*distance = t0;
return true;
}
bool_t Dawn::raytestTriangle(
struct Ray3D ray,
struct PhysicsTriangle triangle,
glm::vec3 *hitPoint,
glm::vec3 *hitNormal,
float_t *hitDistance
) {
assertNotNull(hitPoint, "Ray3D::raytestTriangle: hitPoint cannot be null");
assertNotNull(hitNormal, "Ray3D::raytestTriangle: hitNormal cannot be null");
assertNotNull(hitDistance, "Ray3D::raytestTriangle: hitDistance cannot be null");
// Calculate the normal of the triangle
glm::vec3 e0 = triangle.v1 - triangle.v0;
glm::vec3 e1 = triangle.v2 - triangle.v0;
glm::vec3 normal = glm::normalize(glm::cross(e0, e1));
// Calculate the denominator of the ray-triangle intersection formula
float_t denominator = glm::dot(normal, ray.direction);
// If the denominator is zero, the ray and triangle are parallel and there is no intersection
if(denominator == 0) return -1;
// Calculate the distance from the ray origin to the plane of the triangle
float_t d = glm::dot(triangle.v0 - ray.origin, normal) / denominator;
// If the distance is negative, the intersection point is behind the ray origin and there is no intersection
if(d < 0) return -1;
// Calculate the intersection point
glm::vec3 intersectionPoint = ray.origin + d * ray.direction;
// Check if the intersection point is inside the triangle
glm::vec3 edge0 = triangle.v1 - triangle.v0;
glm::vec3 edge1 = triangle.v2 - triangle.v1;
glm::vec3 edge2 = triangle.v0 - triangle.v2;
glm::vec3 c0 = intersectionPoint - triangle.v0;
glm::vec3 c1 = intersectionPoint - triangle.v1;
glm::vec3 c2 = intersectionPoint - triangle.v2;
glm::vec3 n0 = glm::cross(edge0, c0);
glm::vec3 n1 = glm::cross(edge1, c1);
glm::vec3 n2 = glm::cross(edge2, c2);
if(glm::dot(n0, normal) >= 0 && glm::dot(n1, normal) >= 0 && glm::dot(n2, normal) >= 0) {
// If the intersection point is inside the triangle, set the hit point, normal and distance
*hitPoint = intersectionPoint;
*hitNormal = normal;
*hitDistance = d;
return true;
}
// If the intersection point is outside the triangle, there is no intersection
return false;
}
bool_t Dawn::raytestAABB(
struct Ray3D ray,
struct AABB3D box,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
assertNotNull(point, "Ray3D::raytestAABB: point cannot be null");
assertNotNull(normal, "Ray3D::raytestAABB: normal cannot be null");
assertNotNull(distance, "Ray3D::raytestAABB: distance cannot be null");
// Compute the inverse direction of the ray, for numerical stability
glm::vec3 invDir(1.0f / ray.direction.x, 1.0f / ray.direction.y, 1.0f / ray.direction.z);
// Compute the t-values for the two intersection candidates
glm::vec3 tMin = (box.min - ray.origin) * invDir;
glm::vec3 tMax = (box.max - ray.origin) * invDir;
// Make sure tMin is less than or equal to tMax for all components
glm::vec3 t1 = glm::min(tMin, tMax);
glm::vec3 t2 = glm::max(tMin, tMax);
float tNear = glm::compMax(t1);
float tFar = glm::compMin(t2);
// If tNear is greater than or equal to tFar, there is no intersection
if(tNear >= tFar) return false;
// If tFar is negative, the ray is pointing away from the box
if(tFar < 0.0f) return false;
// Compute the hit point and normal
glm::vec3 hitPoint = ray.origin + tNear * ray.direction;
*point = hitPoint;
*distance = tNear;
// Small value to account for floating point imprecision
const float epsilon = 0.001f;
if(std::abs(hitPoint.x - box.min.x) < epsilon) {
*normal = glm::vec3(-1, 0, 0);
} else if(std::abs(hitPoint.x - box.max.x) < epsilon) {
*normal = glm::vec3(1, 0, 0);
} else if(std::abs(hitPoint.y - box.min.y) < epsilon) {
*normal = glm::vec3(0, -1, 0);
} else if(std::abs(hitPoint.y - box.max.y) < epsilon) {
*normal = glm::vec3(0, 1, 0);
} else if(std::abs(hitPoint.z - box.min.z) < epsilon) {
*normal = glm::vec3(0, 0, -1);
} else if(std::abs(hitPoint.z - box.max.z) < epsilon) {
*normal = glm::vec3(0, 0, 1);
}
return true;
}
bool_t Dawn::raytestCube(
struct Ray3D ray,
struct AABB3D box,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
// Compute the inverse transformation matrix
glm::mat4 inverseTransform = glm::inverse(transform);
// Transform the ray into model space
struct Ray3D localRay;
localRay.origin = glm::vec3(inverseTransform * glm::vec4(ray.origin, 1.0f));
localRay.direction = glm::normalize(glm::vec3(inverseTransform * glm::vec4(ray.direction, 0.0f)));
// Call raytestAABB with the transformed ray and cube
bool_t hit = raytestAABB(localRay, box, point, normal, distance);
if(!hit) return false;
// Transform the hit point and normal back into world space
*point = glm::vec3(transform * glm::vec4(*point, 1.0f));
*normal = glm::normalize(glm::vec3(glm::transpose(inverseTransform) * glm::vec4(*normal, 0.0f)));
return true;
}
bool_t Dawn::raytestQuad(
struct Ray3D ray,
glm::vec2 min,
glm::vec2 max,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
assertNotNull(point, "Ray3D::raytestQuad: point cannot be null");
assertNotNull(normal, "Ray3D::raytestQuad: normal cannot be null");
assertNotNull(distance, "Ray3D::raytestQuad: distance cannot be null");
// transform ray into local space of the quad
glm::mat4 inverseTransform = glm::inverse(transform);
glm::vec3 localRayOrigin = glm::vec3(inverseTransform * glm::vec4(ray.origin, 1.0f));
glm::vec3 localRayDirection = glm::vec3(inverseTransform * glm::vec4(ray.direction, 0.0f));
// perform ray-quad intersection test
float_t t = -localRayOrigin.z / localRayDirection.z; // intersection distance along ray
if(t < 0) return false; // intersection is behind the ray origin
glm::vec2 intersectionPoint = glm::vec2(localRayOrigin) + t * glm::vec2(localRayDirection);
if(
glm::any(glm::lessThan(intersectionPoint, min)) ||
glm::any(glm::greaterThan(intersectionPoint, max))
) {
return false; // intersection is outside the quad
}
*distance = t;
// compute point and normal of intersection in world space
glm::vec3 localIntersectionPoint = glm::vec3(intersectionPoint, 0.0f);
*point = glm::vec3(transform * glm::vec4(localIntersectionPoint, 1.0f));
*normal = glm::normalize(glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f)));
return true; // intersection found
}
bool_t Dawn::raytestCapsule(
struct Ray3D ray,
struct PhysicsCapsule capsule,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
// Calculate the axis of the capsule
glm::vec3 capsuleAxis = glm::normalize(ray.direction);
glm::vec3 capsuleP0 = capsule.origin;
glm::vec3 capsuleP1 = capsule.origin + capsule.height * capsuleAxis;
// Calculate the sphere centers and radii of the capsule end-caps
glm::vec3 sphereP0 = capsule.origin;
glm::vec3 sphereP1 = capsule.origin + capsule.height * capsuleAxis;
float_t sphereR = capsule.radius;
// Calculate the closest points on the capsule axis and the ray
glm::vec3 closestPointRay, closestPointAxis;
if(glm::distance(ray.origin, capsuleP0) < glm::distance(ray.origin, capsuleP1)) {
closestPointAxis = glm::clamp(glm::dot(ray.origin - capsuleP0, capsuleAxis), 0.0f, capsule.height) * capsuleAxis + capsuleP0;
} else {
closestPointAxis = glm::clamp(glm::dot(ray.origin - capsuleP1, -capsuleAxis), 0.0f, capsule.height) * -capsuleAxis + capsuleP1;
}
closestPointRay = glm::clamp(
glm::dot(closestPointAxis - ray.origin, ray.direction),
0.0f, glm::length(ray.direction)
) * ray.direction + ray.origin;
// Calculate the distance between the closest points on the ray and the axis
glm::vec3 temp = (closestPointRay - closestPointAxis);
float_t distanceSquared = glm::dot(temp, temp);
// Check if the ray intersects the end-caps of the capsule
if(
raytestSphere(ray, { .center = sphereP0, .radius = sphereR }, point, normal, distance) ||
raytestSphere(ray, { .center = sphereP1, .radius = sphereR }, point, normal, distance)
) {
*normal = glm::normalize(*point - sphereP0);
return true;
}
// Check if the ray intersects the cylinder part of the capsule
if(distanceSquared > sphereR * sphereR) return false;
*distance = glm::distance(ray.origin, closestPointRay);
*point = closestPointRay;
*normal = glm::normalize(*point - closestPointAxis);
return true;
}
+70
View File
@@ -0,0 +1,70 @@
// Copyright (c) 2023 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "dawnlibs.hpp"
#include "assert/assert.hpp"
#include "PhysicsTriangle.hpp"
#include "PhysicsSphere.hpp"
#include "PhysicsCapsule.hpp"
#include "AABB3D.hpp"
namespace Dawn {
struct Ray3D {
glm::vec3 origin;
glm::vec3 direction;
};
bool_t raytestSphere(
struct Ray3D ray,
struct PhysicsSphere sphere,
glm::vec3 *hit,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestTriangle(
struct Ray3D ray,
struct PhysicsTriangle triangle,
glm::vec3 *hitPoint,
glm::vec3 *hitNormal,
float_t *hitDistance
);
bool_t raytestAABB(
struct Ray3D ray,
struct AABB3D box,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestCube(
struct Ray3D ray,
struct AABB3D box,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestQuad(
struct Ray3D ray,
glm::vec2 min,
glm::vec2 max,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestCapsule(
struct Ray3D ray,
struct PhysicsCapsule capsule,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
}
+14
View File
@@ -0,0 +1,14 @@
# Copyright (c) 2023 Dominic Masters
#
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
ScenePhysicsManager.cpp
)
# Subdirs
add_subdirectory(2d)
add_subdirectory(3d)
+1 -1
View File
@@ -25,8 +25,8 @@ add_subdirectory(game)
add_subdirectory(games)
add_subdirectory(input)
add_subdirectory(locale)
add_subdirectory(physics)
add_subdirectory(prefab)
add_subdirectory(physics)
add_subdirectory(save)
add_subdirectory(scene)
add_subdirectory(state)
+7
View File
@@ -71,5 +71,12 @@ namespace Dawn {
* Perform a synchronous frame update on the render manager.
*/
virtual void update() = 0;
/**
* Clean up the render manager.
*/
virtual ~IRenderManager() {
}
};
}
+11 -8
View File
@@ -77,10 +77,10 @@ namespace Dawn {
* @param dataFormat Data format of the texture to use.
*/
virtual void setSize(
int32_t width,
int32_t height,
enum TextureFormat format,
enum TextureDataFormat dataFormat
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataFormat
) = 0;
/**
@@ -88,8 +88,8 @@ namespace Dawn {
*
* @param color Color to fill.
*/
virtual void fill(struct Color) = 0;
virtual void fill(uint8_t) = 0;
virtual void fill(const struct Color) = 0;
virtual void fill(const uint8_t) = 0;
/**
* Returns true only when the texture has been loaded, sized and put on
@@ -106,7 +106,10 @@ namespace Dawn {
* @param pixels Array of pixels you're trying to buffer.
* @return The amount of bytes buffered to the texture.
*/
virtual void buffer(struct ColorU8 pixels[]) = 0;
virtual void buffer(uint8_t pixels[]) = 0;
virtual void buffer(const struct ColorU8 pixels[]) = 0;
virtual void buffer(const uint8_t pixels[]) = 0;
virtual ~ITexture() {
}
};
}
-2
View File
@@ -11,9 +11,7 @@
#include "input/InputManager.hpp"
#include "time/TimeManager.hpp"
#include "input/InputBinds.hpp"
#include "locale/LocaleManager.hpp"
#include "save/SaveManager.hpp"
// #include "scene/SceneItemComponentList.hpp"
#define DAWN_GAME_INIT_RESULT_SUCCESS 0
#define DAWN_GAME_UPDATE_RESULT_SUCCESS 0
+22 -228
View File
@@ -4,254 +4,48 @@
// https://opensource.org/licenses/MIT
#include "Ray3D.hpp"
#include "assert/assert.hpp"
using namespace Dawn;
bool_t Dawn::raytestSphere(
struct Ray3D ray,
struct PhysicsSphere sphere,
glm::vec3 *hit,
glm::vec3 *normal,
float_t *distance
) {
float_t a = glm::dot(ray.direction, ray.direction);
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;
float_t dt = b * b - 4.0f * a * c;
if(dt < 0.0f) return false;
float_t t0 = (-b - sqrtf(dt)) / (a * 2.0f);
if(t0 < 0.0f) return false;
*hit = ray.origin + t0 * ray.direction;
*normal = glm::normalize(*hit - sphere.center);
*distance = t0;
return true;
}
bool_t Dawn::raytestTriangle(
struct Ray3D ray,
struct PhysicsTriangle triangle,
glm::vec3 *hitPoint,
glm::vec3 *hitNormal,
float_t *hitDistance
) {
assertNotNull(hitPoint, "Ray3D::raytestTriangle: hitPoint cannot be null");
assertNotNull(hitNormal, "Ray3D::raytestTriangle: hitNormal cannot be null");
assertNotNull(hitDistance, "Ray3D::raytestTriangle: hitDistance cannot be null");
// Calculate the normal of the triangle
glm::vec3 e0 = triangle.v1 - triangle.v0;
glm::vec3 e1 = triangle.v2 - triangle.v0;
glm::vec3 normal = glm::normalize(glm::cross(e0, e1));
// Calculate the denominator of the ray-triangle intersection formula
float_t denominator = glm::dot(normal, ray.direction);
// If the denominator is zero, the ray and triangle are parallel and there is no intersection
if(denominator == 0) return -1;
// Calculate the distance from the ray origin to the plane of the triangle
float_t d = glm::dot(triangle.v0 - ray.origin, normal) / denominator;
// If the distance is negative, the intersection point is behind the ray origin and there is no intersection
if(d < 0) return -1;
// Calculate the intersection point
glm::vec3 intersectionPoint = ray.origin + d * ray.direction;
// Check if the intersection point is inside the triangle
glm::vec3 edge0 = triangle.v1 - triangle.v0;
glm::vec3 edge1 = triangle.v2 - triangle.v1;
glm::vec3 edge2 = triangle.v0 - triangle.v2;
glm::vec3 c0 = intersectionPoint - triangle.v0;
glm::vec3 c1 = intersectionPoint - triangle.v1;
glm::vec3 c2 = intersectionPoint - triangle.v2;
glm::vec3 n0 = glm::cross(edge0, c0);
glm::vec3 n1 = glm::cross(edge1, c1);
glm::vec3 n2 = glm::cross(edge2, c2);
if(glm::dot(n0, normal) >= 0 && glm::dot(n1, normal) >= 0 && glm::dot(n2, normal) >= 0) {
// If the intersection point is inside the triangle, set the hit point, normal and distance
*hitPoint = intersectionPoint;
*hitNormal = normal;
*hitDistance = d;
return true;
}
// If the intersection point is outside the triangle, there is no intersection
return false;
}
bool_t Dawn::raytestAABB(
struct Ray3D ray,
struct AABB3D box,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
assertNotNull(point, "Ray3D::raytestAABB: point cannot be null");
assertNotNull(normal, "Ray3D::raytestAABB: normal cannot be null");
assertNotNull(distance, "Ray3D::raytestAABB: distance cannot be null");
// Compute the inverse direction of the ray, for numerical stability
glm::vec3 invDir(1.0f / ray.direction.x, 1.0f / ray.direction.y, 1.0f / ray.direction.z);
// Compute the t-values for the two intersection candidates
glm::vec3 tMin = (box.min - ray.origin) * invDir;
glm::vec3 tMax = (box.max - ray.origin) * invDir;
// Make sure tMin is less than or equal to tMax for all components
glm::vec3 t1 = glm::min(tMin, tMax);
glm::vec3 t2 = glm::max(tMin, tMax);
float tNear = glm::compMax(t1);
float tFar = glm::compMin(t2);
// If tNear is greater than or equal to tFar, there is no intersection
if(tNear >= tFar) return false;
// If tFar is negative, the ray is pointing away from the box
if(tFar < 0.0f) return false;
// Compute the hit point and normal
glm::vec3 hitPoint = ray.origin + tNear * ray.direction;
*point = hitPoint;
*distance = tNear;
// Small value to account for floating point imprecision
const float epsilon = 0.001f;
if(std::abs(hitPoint.x - box.min.x) < epsilon) {
*normal = glm::vec3(-1, 0, 0);
} else if(std::abs(hitPoint.x - box.max.x) < epsilon) {
*normal = glm::vec3(1, 0, 0);
} else if(std::abs(hitPoint.y - box.min.y) < epsilon) {
*normal = glm::vec3(0, -1, 0);
} else if(std::abs(hitPoint.y - box.max.y) < epsilon) {
*normal = glm::vec3(0, 1, 0);
} else if(std::abs(hitPoint.z - box.min.z) < epsilon) {
*normal = glm::vec3(0, 0, -1);
} else if(std::abs(hitPoint.z - box.max.z) < epsilon) {
*normal = glm::vec3(0, 0, 1);
}
return true;
}
bool_t Dawn::raytestCube(
struct Ray3D ray,
struct AABB3D box,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
// Compute the inverse transformation matrix
glm::mat4 inverseTransform = glm::inverse(transform);
// Transform the ray into model space
struct Ray3D localRay;
localRay.origin = glm::vec3(inverseTransform * glm::vec4(ray.origin, 1.0f));
localRay.direction = glm::normalize(glm::vec3(inverseTransform * glm::vec4(ray.direction, 0.0f)));
// Call raytestAABB with the transformed ray and cube
bool_t hit = raytestAABB(localRay, box, point, normal, distance);
if(!hit) return false;
// Transform the hit point and normal back into world space
*point = glm::vec3(transform * glm::vec4(*point, 1.0f));
*normal = glm::normalize(glm::vec3(glm::transpose(inverseTransform) * glm::vec4(*normal, 0.0f)));
return true;
}
bool_t Dawn::raytestQuad(
struct Ray3D ray,
glm::vec2 min,
glm::vec2 max,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
const struct Ray3D ray,
const glm::vec2 min,
const glm::vec2 max,
const glm::mat4 transform,
glm::vec3 &point,
glm::vec3 &normal,
float_t &distance
) {
assertNotNull(point, "Ray3D::raytestQuad: point cannot be null");
assertNotNull(normal, "Ray3D::raytestQuad: normal cannot be null");
assertNotNull(distance, "Ray3D::raytestQuad: distance cannot be null");
// transform ray into local space of the quad
glm::mat4 inverseTransform = glm::inverse(transform);
glm::vec3 localRayOrigin = glm::vec3(inverseTransform * glm::vec4(ray.origin, 1.0f));
glm::vec3 localRayDirection = glm::vec3(inverseTransform * glm::vec4(ray.direction, 0.0f));
glm::vec3 localRayOrigin = glm::vec3(
inverseTransform * glm::vec4(ray.origin, 1.0f)
);
glm::vec3 localRayDirection = glm::vec3(
inverseTransform * glm::vec4(ray.direction, 0.0f)
);
// perform ray-quad intersection test
float_t t = -localRayOrigin.z / localRayDirection.z; // intersection distance along ray
if(t < 0) return false; // intersection is behind the ray origin
glm::vec2 intersectionPoint = glm::vec2(localRayOrigin) + t * glm::vec2(localRayDirection);
glm::vec2 intersectionPoint = (
glm::vec2(localRayOrigin) + t * glm::vec2(localRayDirection)
);
if(
glm::any(glm::lessThan(intersectionPoint, min)) ||
glm::any(glm::greaterThan(intersectionPoint, max))
) {
return false; // intersection is outside the quad
}
*distance = t;
distance = t;
// compute point and normal of intersection in world space
glm::vec3 localIntersectionPoint = glm::vec3(intersectionPoint, 0.0f);
*point = glm::vec3(transform * glm::vec4(localIntersectionPoint, 1.0f));
*normal = glm::normalize(glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f)));
point = glm::vec3(transform * glm::vec4(localIntersectionPoint, 1.0f));
normal = glm::normalize(
glm::vec3(transform * glm::vec4(0.0f, 0.0f, 1.0f, 0.0f))
);
return true; // intersection found
}
bool_t Dawn::raytestCapsule(
struct Ray3D ray,
struct PhysicsCapsule capsule,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
) {
// Calculate the axis of the capsule
glm::vec3 capsuleAxis = glm::normalize(ray.direction);
glm::vec3 capsuleP0 = capsule.origin;
glm::vec3 capsuleP1 = capsule.origin + capsule.height * capsuleAxis;
// Calculate the sphere centers and radii of the capsule end-caps
glm::vec3 sphereP0 = capsule.origin;
glm::vec3 sphereP1 = capsule.origin + capsule.height * capsuleAxis;
float_t sphereR = capsule.radius;
// Calculate the closest points on the capsule axis and the ray
glm::vec3 closestPointRay, closestPointAxis;
if(glm::distance(ray.origin, capsuleP0) < glm::distance(ray.origin, capsuleP1)) {
closestPointAxis = glm::clamp(glm::dot(ray.origin - capsuleP0, capsuleAxis), 0.0f, capsule.height) * capsuleAxis + capsuleP0;
} else {
closestPointAxis = glm::clamp(glm::dot(ray.origin - capsuleP1, -capsuleAxis), 0.0f, capsule.height) * -capsuleAxis + capsuleP1;
}
closestPointRay = glm::clamp(
glm::dot(closestPointAxis - ray.origin, ray.direction),
0.0f, glm::length(ray.direction)
) * ray.direction + ray.origin;
// Calculate the distance between the closest points on the ray and the axis
glm::vec3 temp = (closestPointRay - closestPointAxis);
float_t distanceSquared = glm::dot(temp, temp);
// Check if the ray intersects the end-caps of the capsule
if(
raytestSphere(ray, { .center = sphereP0, .radius = sphereR }, point, normal, distance) ||
raytestSphere(ray, { .center = sphereP1, .radius = sphereR }, point, normal, distance)
) {
*normal = glm::normalize(*point - sphereP0);
return true;
}
// Check if the ray intersects the cylinder part of the capsule
if(distanceSquared > sphereR * sphereR) return false;
*distance = glm::distance(ray.origin, closestPointRay);
*point = closestPointRay;
*normal = glm::normalize(*point - closestPointAxis);
return true;
}
+19 -53
View File
@@ -5,11 +5,6 @@
#pragma once
#include "dawnlibs.hpp"
#include "assert/assert.hpp"
#include "PhysicsTriangle.hpp"
#include "PhysicsSphere.hpp"
#include "PhysicsCapsule.hpp"
#include "AABB3D.hpp"
namespace Dawn {
struct Ray3D {
@@ -17,54 +12,25 @@ namespace Dawn {
glm::vec3 direction;
};
bool_t raytestSphere(
struct Ray3D ray,
struct PhysicsSphere sphere,
glm::vec3 *hit,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestTriangle(
struct Ray3D ray,
struct PhysicsTriangle triangle,
glm::vec3 *hitPoint,
glm::vec3 *hitNormal,
float_t *hitDistance
);
bool_t raytestAABB(
struct Ray3D ray,
struct AABB3D box,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestCube(
struct Ray3D ray,
struct AABB3D box,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
/**
* Tests whether a ray intersects a quad within 3D space.
*
* @param ray Ray to test.
* @param min Minimum point of the quad.
* @param max Maximum point of the quad.
* @param transform Transform of the quad.
* @param point Out point of intersection.
* @param normal Out normal of the quad at the point of intersection.
* @param distance Out distance from the ray origin to the intersection.
* @return True if the ray intersects the quad, false otherwise.
*/
bool_t raytestQuad(
struct Ray3D ray,
glm::vec2 min,
glm::vec2 max,
glm::mat4 transform,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
);
bool_t raytestCapsule(
struct Ray3D ray,
struct PhysicsCapsule capsule,
glm::vec3 *point,
glm::vec3 *normal,
float_t *distance
const struct Ray3D ray,
const glm::vec2 min,
const glm::vec2 max,
const glm::mat4 transform,
glm::vec3 &point,
glm::vec3 &normal,
float_t &distance
);
}
-8
View File
@@ -3,12 +3,4 @@
# This software is released under the MIT License.
# https://opensource.org/licenses/MIT
# Sources
target_sources(${DAWN_TARGET_NAME}
PRIVATE
ScenePhysicsManager.cpp
)
# Subdirs
add_subdirectory(2d)
add_subdirectory(3d)
@@ -10,7 +10,6 @@
#include "scene/components/display/mesh/CubeMeshHost.hpp"
#include "scene/components/display/material/SimpleTexturedMaterial.hpp"
#include "scene/components/example/ExampleSpin.hpp"
#include "scene/components/physics/3d/CubeCollider.hpp"
namespace Dawn {
class SimpleSpinningCubePrefab :
@@ -33,7 +32,6 @@ namespace Dawn {
auto meshHost = this->addComponent<CubeMeshHost>();
material = this->addComponent<SimpleTexturedMaterial>();
auto spinning = this->addComponent<ExampleSpin>();
auto collider = this->addComponent<CubeCollider>();
}
};
}
+1 -4
View File
@@ -10,10 +10,9 @@
using namespace Dawn;
Scene::Scene(std::weak_ptr<DawnGame> game) {
Scene::Scene(const std::weak_ptr<DawnGame> game) {
this->game = game;
this->nextId = 0;
this->physics = new ScenePhysicsManager(this);
}
void Scene::update() {
@@ -39,8 +38,6 @@ std::shared_ptr<SceneItem> Scene::createSceneItem() {
}
Scene::~Scene() {
delete this->physics;
// Invoke cleanup.
auto it = this->items.begin();
while(it != this->items.end()) {
+2 -5
View File
@@ -5,9 +5,6 @@
#pragma once
#include "asset/Asset.hpp"
#include "display/shader/ShaderManager.hpp"
#include "scene/debug/SceneDebugLine.hpp"
#include "physics/ScenePhysicsManager.hpp"
#include "state/StateEvent.hpp"
#include "state/StateOwner.hpp"
@@ -19,6 +16,7 @@ namespace Dawn {
typedef int32_t sceneitemid_t;
// Scene Item Forwarders
template<class T>
std::shared_ptr<T> _sceneForwardGetComponent(std::shared_ptr<SceneItem> item);
@@ -35,7 +33,6 @@ namespace Dawn {
public:
std::weak_ptr<DawnGame> game;
ScenePhysicsManager *physics;
StateEvent<float_t> eventSceneUpdate;
StateEvent<float_t> eventSceneUnpausedUpdate;
@@ -44,7 +41,7 @@ namespace Dawn {
*
* @param game Reference to the game that this scene belongs to.
*/
Scene(std::weak_ptr<DawnGame> game);
Scene(const std::weak_ptr<DawnGame> game);
/**
* Perform a one frame synchronous tick on the current scene. This may
+4 -5
View File
@@ -9,12 +9,12 @@
using namespace Dawn;
SceneItem::SceneItem(std::weak_ptr<Scene> scene, sceneitemid_t id) :
SceneItem::SceneItem(const std::weak_ptr<Scene> scene, const sceneitemid_t id) :
transformLocal(1.0f),
transformWorld(1.0f)
transformWorld(1.0f),
scene(scene),
id(id)
{
this->id = id;
this->scene = scene;
this->updateLocalValuesFromLocalTransform();
}
@@ -96,7 +96,6 @@ void SceneItem::updateWorldTransformFromLocalTransform() {
}
}
void SceneItem::updateLocalTransformFromWorldTransform() {
glm::mat4 parentMat(1.0f);
auto parent = this->getParent();
+3 -4
View File
@@ -41,9 +41,8 @@ namespace Dawn {
void updateChildrenTransforms();
public:
std::weak_ptr<Scene> scene;
sceneitemid_t id;
// I have no idea if I'm keeping this
const std::weak_ptr<Scene> scene;
const sceneitemid_t id;
StateEvent<> eventTransformUpdated;
/**
@@ -53,7 +52,7 @@ namespace Dawn {
* @param scene Weak pointer to the Scene that this SceneItem belongs to.
* @param id Scene Item ID that the Scene assigned this SceneItem.
*/
SceneItem(std::weak_ptr<Scene> scene, sceneitemid_t id);
SceneItem(const std::weak_ptr<Scene> scene, const sceneitemid_t id);
/**
* Called by the Scene the frame after we were constructed so we can begin
-4
View File
@@ -35,10 +35,6 @@ std::shared_ptr<DawnGame> SceneItemComponent::getGame() {
return game;
}
ScenePhysicsManager * SceneItemComponent::getPhysics() {
return this->getScene()->physics;
}
void SceneItemComponent::onStart() {
}
-7
View File
@@ -51,13 +51,6 @@ namespace Dawn {
*/
std::shared_ptr<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.
*/
-1
View File
@@ -7,6 +7,5 @@
add_subdirectory(debug)
add_subdirectory(display)
add_subdirectory(example)
add_subdirectory(physics)
add_subdirectory(scene)
add_subdirectory(ui)
@@ -7,7 +7,6 @@
#include "scene/SceneItemComponent.hpp"
#include "display/RenderTarget.hpp"
#include "scene/Scene.hpp"
#include "physics/3d/Ray3D.hpp"
namespace Dawn {
enum CameraType {
@@ -4,6 +4,7 @@
// https://opensource.org/licenses/MIT
#pragma once
#include "util/flag.hpp"
#include "display/Tileset.hpp"
#include "scene/components/display/mesh/QuadMeshHost.hpp"
@@ -5,6 +5,7 @@
#include "UISimpleMenu.hpp"
#include "game/DawnGame.hpp"
#include "physics/3d/Ray3D.hpp"
using namespace Dawn;
@@ -108,9 +109,9 @@ void UISimpleMenu::onStart() {
ray,
glm::vec2(0, 0), size,
highlight->item.lock()->getWorldTransform(),
&point,
&normal,
&distance
point,
normal,
distance
)) continue;
this->menu->menuX = item->menuX;
+10 -10
View File
@@ -19,7 +19,7 @@ Texture::Texture() : ITexture() {
});
}
void Texture::bind(textureslot_t slot) {
void Texture::bind(const textureslot_t slot) {
assertTrue(this->id != -1, "Texture is not ready!");
glActiveTexture(GL_TEXTURE0 + slot);
assertNoGLError();
@@ -41,10 +41,10 @@ int32_t Texture::getHeight() {
}
void Texture::setSize(
int32_t width,
int32_t height,
enum TextureFormat format,
enum TextureDataFormat dataFormat
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataFormat
) {
if(this->id != -1) {
glDeleteTextures(1, &this->id);
@@ -80,7 +80,7 @@ void Texture::fill(struct Color color) {
memoryFree(pixels);
}
void Texture::fill(uint8_t color) {
void Texture::fill(const uint8_t color) {
auto pixels = memoryAllocate<uint8_t>(
sizeof(uint8_t) * this->width * this->height
);
@@ -151,7 +151,7 @@ void Texture::updateTextureProperties() {
);
}
void Texture::bufferRaw(void *data) {
void Texture::bufferRaw(const void *data) {
assertTrue(this->isReady(), "Texture is not ready!");
GLenum format;
@@ -203,7 +203,7 @@ void Texture::bufferRaw(void *data) {
this->texturePropertiesNeedUpdating = true;
}
void Texture::buffer(struct ColorU8 pixels[]) {
void Texture::buffer(const struct ColorU8 pixels[]) {
assertTrue(
this->dataFormat == TEXTURE_DATA_FORMAT_UNSIGNED_BYTE,
"Texture data format must be unsigned byte!"
@@ -211,7 +211,7 @@ void Texture::buffer(struct ColorU8 pixels[]) {
this->bufferRaw((void*)pixels);
}
void Texture::buffer(struct Color pixels[]) {
void Texture::buffer(const struct Color pixels[]) {
assertTrue(
this->dataFormat == TEXTURE_DATA_FORMAT_FLOAT,
"Texture data format must be float!"
@@ -223,7 +223,7 @@ void Texture::buffer(struct Color pixels[]) {
this->bufferRaw((void*)pixels);
}
void Texture::buffer(uint8_t pixels[]) {
void Texture::buffer(const uint8_t pixels[]) {
assertTrue(
this->dataFormat == TEXTURE_DATA_FORMAT_UNSIGNED_BYTE,
"Texture data format must be unsigned byte!"
+11 -11
View File
@@ -21,31 +21,31 @@ namespace Dawn {
enum TextureDataFormat dataFormat;
void updateTextureProperties();
void bufferRaw(void *data);
void bufferRaw(const void *data);
public:
Texture();
int32_t getWidth() override;
int32_t getHeight() override;
void setSize(
int32_t width,
int32_t height,
enum TextureFormat format,
enum TextureDataFormat dataFormat
const int32_t width,
const int32_t height,
const enum TextureFormat format,
const enum TextureDataFormat dataFormat
) override;
void fill(struct Color) override;
void fill(uint8_t) override;
void fill(const struct Color) override;
void fill(const uint8_t) override;
bool_t isReady() override;
void buffer(struct ColorU8 pixels[]) override;
void buffer(struct Color pixels[]);
void buffer(uint8_t pixels[]) override;
void buffer(const struct ColorU8 pixels[]) override;
void buffer(const struct Color pixels[]);
void buffer(const uint8_t pixels[]) override;
/**
* Binds the texture to the given slot (for use by the shaders).
*
* @param slot Slot to bind to.
*/
void bind(textureslot_t slot);
void bind(const textureslot_t slot);
~Texture();