Removed physics for now.
This commit is contained in:
		@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
 | 
			
		||||
      }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -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() {
 | 
			
		||||
      }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -1,97 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "Box.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
bool_t boxIsPointInside(glm::vec2 point, glm::vec2 min, glm::vec2 max) {
 | 
			
		||||
  return (
 | 
			
		||||
    point.x >= min.x && point.x <= max.x &&
 | 
			
		||||
    point.y >= min.y && point.y <= max.y
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Dawn::boxCheckCollision(
 | 
			
		||||
  glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA,
 | 
			
		||||
  glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB,
 | 
			
		||||
  glm::vec2 velocity,
 | 
			
		||||
  glm::vec2 &normal,
 | 
			
		||||
  float_t &entryTime,
 | 
			
		||||
  float_t &exitTime,
 | 
			
		||||
  glm::vec2 &entryPoint,
 | 
			
		||||
  glm::vec2 &exitPoint
 | 
			
		||||
) {
 | 
			
		||||
  // Calculate the time intervals of overlap in the x and y axes
 | 
			
		||||
  glm::vec2 invEntry = glm::vec2(0.0f);
 | 
			
		||||
  glm::vec2 invExit = glm::vec2(0.0f);
 | 
			
		||||
 | 
			
		||||
  if (velocity.x >= 0.0f) {
 | 
			
		||||
    invEntry.x = ((minB.x + posB.x) - (maxA.x + posA.x)) / velocity.x;
 | 
			
		||||
    invExit.x = ((maxB.x + posB.x) - (minA.x + posA.x)) / velocity.x;
 | 
			
		||||
  } else {
 | 
			
		||||
    invEntry.x = ((maxB.x + posB.x) - (minA.x + posA.x)) / velocity.x;
 | 
			
		||||
    invExit.x = ((minB.x + posB.x) - (maxA.x + posA.x)) / velocity.x;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  if (velocity.y >= 0.0f) {
 | 
			
		||||
    invEntry.y = ((minB.y + posB.y) - (maxA.y + posA.y)) / velocity.y;
 | 
			
		||||
    invExit.y = ((maxB.y + posB.y) - (minA.y + posA.y)) / velocity.y;
 | 
			
		||||
  } else {
 | 
			
		||||
    invEntry.y = ((maxB.y + posB.y) - (minA.y + posA.y)) / velocity.y;
 | 
			
		||||
    invExit.y = ((minB.y + posB.y) - (maxA.y + posA.y)) / velocity.y;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate the time of entry and exit for each axis
 | 
			
		||||
  glm::vec2 entry = glm::max(invEntry, glm::vec2(0.0f));
 | 
			
		||||
  glm::vec2 exit = glm::min(invExit, glm::vec2(1.0f));
 | 
			
		||||
 | 
			
		||||
  // Find the time of entry and exit
 | 
			
		||||
  entryTime = glm::max(entry.x, entry.y);
 | 
			
		||||
  exitTime = glm::min(exit.x, exit.y);
 | 
			
		||||
 | 
			
		||||
  // If there is no overlap in either axis, there is no collision
 | 
			
		||||
  if (entryTime > exitTime || entry.x < 0.0f && entry.y < 0.0f || entry.x > 1.0f || entry.y > 1.0f) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate the normal of the collision
 | 
			
		||||
  if (entry.x > entry.y) {
 | 
			
		||||
    if (invEntry.x < 0.0f) {
 | 
			
		||||
      normal = glm::vec2(1.0f, 0.0f);
 | 
			
		||||
    } else {
 | 
			
		||||
      normal = glm::vec2(-1.0f, 0.0f);
 | 
			
		||||
    }
 | 
			
		||||
  } else {
 | 
			
		||||
    if (invEntry.y < 0.0f) {
 | 
			
		||||
      normal = glm::vec2(0.0f, 1.0f);
 | 
			
		||||
    } else {
 | 
			
		||||
      normal = glm::vec2(0.0f, -1.0f);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Calculate the entry and exit points
 | 
			
		||||
  entryPoint = posA + velocity * entryTime;
 | 
			
		||||
  exitPoint = posA + velocity * exitTime;
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Dawn::boxIsBoxColliding(
 | 
			
		||||
  glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA,
 | 
			
		||||
  glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB
 | 
			
		||||
) {
 | 
			
		||||
  // Check for no overlap in X axis
 | 
			
		||||
  if (posA.x + maxA.x < posB.x + minB.x || posB.x + maxB.x < posA.x + minA.x) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Check for no overlap in Y axis
 | 
			
		||||
  if (posA.y + maxA.y < posB.y + minB.y || posB.y + maxB.y < posA.y + minA.y) {
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,48 +0,0 @@
 | 
			
		||||
// 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 "util/mathutils.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  bool_t boxCheckCollision(
 | 
			
		||||
    glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA,
 | 
			
		||||
    glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB,
 | 
			
		||||
    glm::vec2 velocity,
 | 
			
		||||
    glm::vec2 &normal,
 | 
			
		||||
    float_t &entryTime,
 | 
			
		||||
    float_t &exitTime,
 | 
			
		||||
    glm::vec2 &entryPoint,
 | 
			
		||||
    glm::vec2 &exitPoint
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Checks if two boxes are colliding.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param posA Position of the first box.
 | 
			
		||||
   * @param minA Minimum point on the first box.
 | 
			
		||||
   * @param maxA Maximum point on the first box.
 | 
			
		||||
   * @param posB Position of the second box.
 | 
			
		||||
   * @param minB Minimum point on the second box.
 | 
			
		||||
   * @param maxB Maximum point on the second box.
 | 
			
		||||
   * @return True if the boxes are colliding with each other, false otherwise.
 | 
			
		||||
   */
 | 
			
		||||
  bool_t boxIsBoxColliding(
 | 
			
		||||
    glm::vec2 posA, glm::vec2 minA, glm::vec2 maxA,
 | 
			
		||||
    glm::vec2 posB, glm::vec2 minB, glm::vec2 maxB
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Checks if a given point is within the 2D Boundaries of an object.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param point Point to test.
 | 
			
		||||
   * @param min Minimum point on the box.
 | 
			
		||||
   * @param max Maximum point on the box.
 | 
			
		||||
   * @return True if the point is within the box.
 | 
			
		||||
   */
 | 
			
		||||
  static bool_t boxIsPointInside(glm::vec2 point, glm::vec2 min, glm::vec2 max);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
# 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
 | 
			
		||||
    Box.cpp
 | 
			
		||||
    Ray2D.cpp
 | 
			
		||||
)
 | 
			
		||||
@@ -1,12 +0,0 @@
 | 
			
		||||
// 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
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  static inline glm::vec2 physics3Dto2D(glm::vec3 v) {
 | 
			
		||||
    return glm::vec2(v.x, v.z);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "Ray2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
Ray2D::Ray2D(glm::vec2 pos, glm::vec2 dir) :
 | 
			
		||||
  position(pos),
 | 
			
		||||
  direction(dir)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Ray2D::intersects(struct Ray2D ray, glm::vec2 *out) {
 | 
			
		||||
  glm::vec2 j = this->position - ray.position;
 | 
			
		||||
  float_t f = -ray.direction.x * direction.y + direction.x * ray.direction.y;
 | 
			
		||||
  float_t s = (-direction.y * j.x + direction.x * j.y) / f;
 | 
			
		||||
  float_t t = (ray.direction.x * j.y - ray.direction.y * j.x) / f;
 | 
			
		||||
  if(s >= 0 && s <= 1 && t >= 0 && t <= 1) {
 | 
			
		||||
    *out = position + (t * direction);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct Ray2D {
 | 
			
		||||
    const glm::vec2 position;
 | 
			
		||||
    const glm::vec2 direction;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Constructs a new Ray 2D.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param position Position of this ray in 2D space.
 | 
			
		||||
     * @param direction Direction from the origin in 2D space of this ray.
 | 
			
		||||
     */
 | 
			
		||||
    Ray2D(glm::vec2 position, glm::vec2 direction);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether one ray is intersecting with another ray.
 | 
			
		||||
     * 
 | 
			
		||||
     * @param ray The ray to check if this ray is intersecting.
 | 
			
		||||
     * @param out The point in space where the two rays intersect.
 | 
			
		||||
     * @return True if they intersect, otherwise false.
 | 
			
		||||
     */
 | 
			
		||||
    bool_t intersects(struct Ray2D ray, glm::vec2 *out);
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,71 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "AABB3D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
bool_t Dawn::aabb3dIntersect(struct AABB3D cube1, struct AABB3D cube2) {
 | 
			
		||||
  return (
 | 
			
		||||
    (cube1.min.x <= cube2.max.x && cube1.max.x >= cube2.min.x) &&
 | 
			
		||||
    (cube1.min.y <= cube2.max.y && cube1.max.y >= cube2.min.y) &&
 | 
			
		||||
    (cube1.min.z <= cube2.max.z && cube1.max.z >= cube2.min.z)
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t aabb3dSweep(
 | 
			
		||||
  struct AABB3D cube1, glm::vec3 velocity1,
 | 
			
		||||
  struct AABB3D cube2, glm::vec3 velocity2,
 | 
			
		||||
  glm::vec3 *normal
 | 
			
		||||
) {
 | 
			
		||||
  glm::vec3 relVel = vel1 - vel2;
 | 
			
		||||
  glm::vec3 relPos = pos1 - pos2;
 | 
			
		||||
 | 
			
		||||
  // If the relative velocity is zero, the cubes are already intersecting
 | 
			
		||||
  if(glm::length2(relVel) == 0.0f) {
 | 
			
		||||
    fraction = 0.0f;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Expand the size of the cubes by the magnitude of the relative velocity
 | 
			
		||||
  glm::vec3 size1exp = size1 + glm::abs(relVel);
 | 
			
		||||
  glm::vec3 size2exp = size2 + glm::abs(relVel);
 | 
			
		||||
 | 
			
		||||
  // Compute the times at which the cubes first and last overlap on each axis
 | 
			
		||||
  float_t tminx = (size1exp.x + size2exp.x - glm::abs(relPos.x)) / glm::abs(relVel.x);
 | 
			
		||||
  float_t tmaxx = (size1.x + size2.x - glm::abs(relPos.x)) / glm::abs(relVel.x);
 | 
			
		||||
  float_t tminy = (size1exp.y + size2exp.y - glm::abs(relPos.y)) / glm::abs(relVel.y);
 | 
			
		||||
  float_t tmaxy = (size1.y + size2.y - glm::abs(relPos.y)) / glm::abs(relVel.y);
 | 
			
		||||
  float_t tminz = (size1exp.z + size2exp.z - glm::abs(relPos.z)) / glm::abs(relVel.z);
 | 
			
		||||
  float_t tmaxz = (size1.z + size2.z - glm::abs(relPos.z)) / glm::abs(relVel.z);
 | 
			
		||||
 | 
			
		||||
  // Find the earliest and latest times of overlap
 | 
			
		||||
  float_t tmin = glm::max(glm::max(glm::min(tminx, tmaxx), glm::min(tminy, tmaxy)), glm::min(tminz, tmaxz));
 | 
			
		||||
  float_t tmax = glm::min(glm::min(glm::max(tminx, tmaxx), glm::max(tminy, tmaxy)), glm::max(tminz, tmaxz));
 | 
			
		||||
 | 
			
		||||
  // If the earliest time of overlap is greater than the length of the timestep, the cubes
 | 
			
		||||
  // will not collide during the timestep
 | 
			
		||||
  if(tmin > 1.0f) {
 | 
			
		||||
    fraction = 1.0f;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If the latest time of overlap is less than or equal to zero, the cubes are already
 | 
			
		||||
  // colliding and will collide throughout the timestep
 | 
			
		||||
  if(tmax <= 0.0f) {
 | 
			
		||||
    fraction = 0.0f;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Compute the fraction of the timestep at which the collision occurs
 | 
			
		||||
  fraction = glm::clamp(tmin, 0.0f, 1.0f);
 | 
			
		||||
 | 
			
		||||
  // Check if the two AABB cubes are intersecting at the time of collision
 | 
			
		||||
  glm::vec3 min1 = pos1 + vel1 * fraction - size1 / 2.0f;
 | 
			
		||||
  glm::vec3 max1 = pos1 + vel1 * fraction + size1 / 2.0f;
 | 
			
		||||
  glm::vec3 min2 = pos2 + vel2 * fraction - size2 / 2.0f;
 | 
			
		||||
  glm::vec3 max2 = pos2 + vel2 * fraction + size2 / 2.0f;
 | 
			
		||||
  return aabbIntersect(min1, max1, min2, max2);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,30 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct AABB3D {
 | 
			
		||||
    glm::vec3 min;
 | 
			
		||||
    glm::vec3 max;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Checks whether two 3D AABB are intersecting or not.
 | 
			
		||||
   * 
 | 
			
		||||
   * @param cube1 First cube.
 | 
			
		||||
   * @param cube2 Second cube.
 | 
			
		||||
   * @return True if the two cubes are intersecting, otherwise false.
 | 
			
		||||
   */
 | 
			
		||||
  bool_t aabb3dIntersect(struct AABB3D cube1, struct AABB3D cube2);
 | 
			
		||||
 | 
			
		||||
  
 | 
			
		||||
  bool_t aabb3dSweep(
 | 
			
		||||
    glm::vec3 pos1, glm::vec3 size1, glm::vec3 vel1,
 | 
			
		||||
    glm::vec3 pos2, glm::vec3 size2, glm::vec3 vel2,
 | 
			
		||||
    float_t& fraction
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct PhysicsCapsule {
 | 
			
		||||
    float_t height;
 | 
			
		||||
    float_t radius;
 | 
			
		||||
    glm::vec3 origin;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct PhysicsSphere {
 | 
			
		||||
    glm::vec3 center;
 | 
			
		||||
    float_t radius;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,15 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct PhysicsTriangle {
 | 
			
		||||
    glm::vec3 v0;
 | 
			
		||||
    glm::vec3 v1;
 | 
			
		||||
    glm::vec3 v2;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
}
 | 
			
		||||
@@ -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
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,6 @@
 | 
			
		||||
# 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)
 | 
			
		||||
# Copyright (c) 2023 Dominic Masters
 | 
			
		||||
# 
 | 
			
		||||
# This software is released under the MIT License.
 | 
			
		||||
# https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
add_subdirectory(3d)
 | 
			
		||||
@@ -1,36 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "ScenePhysicsManager.hpp"
 | 
			
		||||
#include "scene/Scene.hpp"
 | 
			
		||||
#include "scene/components/physics/3d/Collider3D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
ScenePhysicsManager::ScenePhysicsManager(Scene *scene) {
 | 
			
		||||
  this->scene = scene;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "dawnlibs.hpp"
 | 
			
		||||
#include "physics/3d/Ray3D.hpp"
 | 
			
		||||
 | 
			
		||||
typedef int64_t scenechunk_t;
 | 
			
		||||
 | 
			
		||||
#define SCENE_CHUNK_SIZE_2D 512
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class Scene;
 | 
			
		||||
  class Collider3D;
 | 
			
		||||
  struct Collider3DRayResult;
 | 
			
		||||
 | 
			
		||||
  class ScenePhysicsManager {
 | 
			
		||||
    protected:
 | 
			
		||||
      Scene *scene;
 | 
			
		||||
      // std::map<scenechunk_t, std::vector<SceneItem*>> chunkItems;
 | 
			
		||||
      // std::map<SceneItem*, std::vector<scenechunk_t>> itemChunks;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
      ScenePhysicsManager(Scene *scene);
 | 
			
		||||
 | 
			
		||||
      void update();
 | 
			
		||||
 | 
			
		||||
      std::vector<struct Collider3DRayResult> raycast3DAll(struct Ray3D ray);
 | 
			
		||||
 | 
			
		||||
      friend class Scene;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -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>();
 | 
			
		||||
        }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -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()) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -35,10 +35,6 @@ std::shared_ptr<DawnGame> SceneItemComponent::getGame() {
 | 
			
		||||
  return game;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ScenePhysicsManager * SceneItemComponent::getPhysics() {
 | 
			
		||||
  return this->getScene()->physics;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void SceneItemComponent::onStart() {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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.
 | 
			
		||||
       */
 | 
			
		||||
 
 | 
			
		||||
@@ -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"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "BoxCollider.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
BoxCollider::BoxCollider(std::weak_ptr<SceneItem> item) : Collider2D(item) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum Collider2DType BoxCollider::getColliderType() {
 | 
			
		||||
  return COLLIDER2D_TYPE_BOX;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "physics/2d/Box.hpp"
 | 
			
		||||
#include "physics/2d/Physics2D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class BoxCollider : public Collider2D {
 | 
			
		||||
    public:
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec2 min = glm::vec2(-0.5f, -0.5f);
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec2 max = glm::vec2( 0.5f,  0.5f);
 | 
			
		||||
 | 
			
		||||
      BoxCollider(std::weak_ptr<SceneItem> item);
 | 
			
		||||
      enum Collider2DType getColliderType() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
# 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
 | 
			
		||||
    BoxCollider.cpp
 | 
			
		||||
    Collider2D.cpp
 | 
			
		||||
    CharacterController2D.cpp
 | 
			
		||||
    SolidController2D.cpp
 | 
			
		||||
    TriggerController2D.cpp
 | 
			
		||||
)
 | 
			
		||||
@@ -1,92 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "CharacterController2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
CharacterController2D::CharacterController2D(std::weak_ptr<SceneItem> i) :
 | 
			
		||||
  SceneItemComponent(i)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CharacterController2D::onStart() {
 | 
			
		||||
  useEvent([&](float_t delta){
 | 
			
		||||
    // if(velocity == glm::vec2(0, 0)) return;
 | 
			
		||||
 | 
			
		||||
    // Common variables
 | 
			
		||||
    auto item = this->item.lock();
 | 
			
		||||
    auto myCollider = item->getComponent<Collider2D>();
 | 
			
		||||
 | 
			
		||||
    // Friction
 | 
			
		||||
    velocity -= velocity * friction * delta;
 | 
			
		||||
 | 
			
		||||
    // Solid Collision Check
 | 
			
		||||
    glm::vec2 moveAmount;
 | 
			
		||||
    if(myCollider == nullptr) {
 | 
			
		||||
      moveAmount = velocity;
 | 
			
		||||
    } else {
 | 
			
		||||
      // Perform sweep
 | 
			
		||||
      auto allColliders = getScene()->findComponents<SolidController2D>();
 | 
			
		||||
      auto itColliders = allColliders.begin();
 | 
			
		||||
 | 
			
		||||
      struct CharacterController2DCollisionEventInfo info;
 | 
			
		||||
      bool_t result = false;
 | 
			
		||||
 | 
			
		||||
      // Check for collisions, definitely not working 100% yet 
 | 
			
		||||
      while(itColliders != allColliders.end()) {
 | 
			
		||||
        auto c = *itColliders;
 | 
			
		||||
        ++itColliders;
 | 
			
		||||
        auto cItem = c->item.lock();
 | 
			
		||||
        if(cItem == item || cItem->isChildOf(item)) continue;
 | 
			
		||||
        result = c->getCollidingResult(
 | 
			
		||||
          velocity,
 | 
			
		||||
          myCollider,
 | 
			
		||||
          info.normal,
 | 
			
		||||
          info.entryTime,
 | 
			
		||||
          info.exitTime,
 | 
			
		||||
          info.entryPoint,
 | 
			
		||||
          info.exitPoint
 | 
			
		||||
        ) && info.entryTime <= delta;
 | 
			
		||||
 | 
			
		||||
        if(result) {
 | 
			
		||||
          info.collider = c;
 | 
			
		||||
          break;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      if(result) {
 | 
			
		||||
        moveAmount = glm::vec2(0, 0);
 | 
			
		||||
        velocity = glm::vec2(0, 0);
 | 
			
		||||
        this->eventCollision.invoke(info);
 | 
			
		||||
      } else {
 | 
			
		||||
        moveAmount = velocity;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(moveAmount != glm::vec2(0, 0)) {
 | 
			
		||||
      item->setLocalPosition(
 | 
			
		||||
        item->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Now perform trigger collision check
 | 
			
		||||
    auto allTriggers = getScene()->findComponents<TriggerController2D>();
 | 
			
		||||
    auto itTriggers = allTriggers.begin();
 | 
			
		||||
    while(itTriggers != allTriggers.end()) {
 | 
			
		||||
      auto c = *itTriggers;
 | 
			
		||||
      ++itTriggers;
 | 
			
		||||
      auto cItem = c->item.lock();
 | 
			
		||||
      if(cItem == item || cItem->isChildOf(item)) continue;
 | 
			
		||||
      if(c->getCollidingResult(myCollider)) {
 | 
			
		||||
        c->eventTriggerEnter.invoke(this);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Stop velocity near zero.
 | 
			
		||||
    if(mathAbs<float_t>(velocity.x) <= 0.001f) velocity.x = 0;
 | 
			
		||||
    if(mathAbs<float_t>(velocity.y) <= 0.001f) velocity.y = 0;
 | 
			
		||||
  }, getScene()->eventSceneUpdate);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "SolidController2D.hpp"
 | 
			
		||||
#include "TriggerController2D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct CharacterController2DCollisionEventInfo {
 | 
			
		||||
    std::shared_ptr<SolidController2D> collider;
 | 
			
		||||
    glm::vec2 normal;
 | 
			
		||||
    float_t entryTime;
 | 
			
		||||
    float_t exitTime;
 | 
			
		||||
    glm::vec2 entryPoint;
 | 
			
		||||
    glm::vec2 exitPoint;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  class CharacterController2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec2 velocity = glm::vec2(0, 0);
 | 
			
		||||
      // @optional
 | 
			
		||||
      float_t friction = 12.0f;
 | 
			
		||||
 | 
			
		||||
      StateEvent<struct CharacterController2DCollisionEventInfo> eventCollision;
 | 
			
		||||
      
 | 
			
		||||
      CharacterController2D(std::weak_ptr<SceneItem> i);
 | 
			
		||||
      void onStart() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,13 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "BoxCollider.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
Collider2D::Collider2D(std::weak_ptr<SceneItem> i) : SceneItemComponent(i) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
@@ -1,34 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "scene/SceneItemComponent.hpp"
 | 
			
		||||
#include "physics/2d/Box.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  enum Collider2DType {
 | 
			
		||||
    COLLIDER2D_TYPE_BOX
 | 
			
		||||
  };
 | 
			
		||||
  
 | 
			
		||||
  struct Collider2DAxisAlignedCollidingResult {
 | 
			
		||||
    glm::vec2 normal;
 | 
			
		||||
    float_t entryTime;
 | 
			
		||||
    float_t exitTime;
 | 
			
		||||
    glm::vec2 entryPoint;
 | 
			
		||||
    glm::vec2 exitPoint;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  class Collider2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      Collider2D(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Returns which type of collider this is.
 | 
			
		||||
       * 
 | 
			
		||||
       * @return The collider type that this is.
 | 
			
		||||
       */
 | 
			
		||||
      virtual enum Collider2DType getColliderType() = 0;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,69 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "SolidController2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
SolidController2D::SolidController2D(std::weak_ptr<SceneItem> item) : SceneItemComponent(item) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::shared_ptr<SceneItemComponent>> SolidController2D::getDependencies() {
 | 
			
		||||
  return {
 | 
			
		||||
    (this->collider = item.lock()->getComponent<Collider2D>())
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t SolidController2D::getCollidingResult(
 | 
			
		||||
  glm::vec2 movement,
 | 
			
		||||
  std::shared_ptr<Collider2D> movingObject,
 | 
			
		||||
  glm::vec2 &normal,
 | 
			
		||||
  float_t &entryTime,
 | 
			
		||||
  float_t &exitTime,
 | 
			
		||||
  glm::vec2 &entryPoint,
 | 
			
		||||
  glm::vec2 &exitPoint
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(this->collider, "SolidController2D::getCollidingResult: Collider cannot be null");
 | 
			
		||||
  assertNotNull(movingObject, "SolidController2D::getCollidingResult: Moving object cannot be null");
 | 
			
		||||
  if(movement.x == 0 && movement.y == 0) return false;
 | 
			
		||||
 | 
			
		||||
  auto myPos = physics3Dto2D(movingObject->item.lock()->getWorldPosition());
 | 
			
		||||
 | 
			
		||||
  // Check what the moving object is
 | 
			
		||||
  switch(movingObject->getColliderType()) {
 | 
			
		||||
    case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
      auto box1 = std::static_pointer_cast<BoxCollider>(movingObject);
 | 
			
		||||
      assertNotNull(box1, "SolidController2D::getCollidingResult: Moving object is not a BoxCollider");
 | 
			
		||||
 | 
			
		||||
      // Box VS (this)?
 | 
			
		||||
      switch(this->collider->getColliderType()) {
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = std::static_pointer_cast<BoxCollider>(this->collider);
 | 
			
		||||
          assertNotNull(box2, "SolidController2D::getCollidingResult: Collider is not a BoxCollider");
 | 
			
		||||
          auto otherPos = physics3Dto2D(box2->item.lock()->getWorldPosition());
 | 
			
		||||
 | 
			
		||||
          return boxCheckCollision(
 | 
			
		||||
            myPos, box1->min, box1->max,
 | 
			
		||||
            otherPos, box2->min, box2->max,
 | 
			
		||||
            movement,
 | 
			
		||||
            normal, entryTime, exitTime, entryPoint, exitPoint
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        default: {
 | 
			
		||||
          assertUnreachable("SolidController2D::getCollidingResult: Collider type not implemented");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default: {
 | 
			
		||||
      assertUnreachable("SolidController2D::getCollidingResult: Moving object type not implemented");
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  assertUnreachable("SolidController2D::getCollidingResult: Should never reach this point");
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,42 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "BoxCollider.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class SolidController2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      std::shared_ptr<Collider2D> collider;
 | 
			
		||||
 | 
			
		||||
      SolidController2D(std::weak_ptr<SceneItem> item);
 | 
			
		||||
      std::vector<std::shared_ptr<SceneItemComponent>> getDependencies() override;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Gets the result of checking if two collider bodies are intersecting.
 | 
			
		||||
       * This is performed WITH movement to return entry and exit times.
 | 
			
		||||
       * 
 | 
			
		||||
       * @param result Where to store the results of the calculation.
 | 
			
		||||
       * @param movement Movement operation that THIS object is performing.
 | 
			
		||||
       * @param movingObject Moving Object Collider that is being compared.
 | 
			
		||||
       * @param normal Output normal of the intersection.
 | 
			
		||||
       * @param entryTime Output entry time when the two objects will intersect.
 | 
			
		||||
       * @param exitTime Output exit time when the object will pass through.
 | 
			
		||||
       * @param entryPoint Output point in 2D space where object will enter.
 | 
			
		||||
       * @param exitPoint Output point where object will have passed through.
 | 
			
		||||
       * @return True if the two objects will intersect at move otherwise false.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t getCollidingResult(
 | 
			
		||||
        glm::vec2 movement,
 | 
			
		||||
        std::shared_ptr<Collider2D> movingObject,
 | 
			
		||||
        glm::vec2 &normal,
 | 
			
		||||
        float_t &entryTime,
 | 
			
		||||
        float_t &exitTime,
 | 
			
		||||
        glm::vec2 &entryPoint,
 | 
			
		||||
        glm::vec2 &exitPoint
 | 
			
		||||
      );
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,51 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "TriggerController2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
TriggerController2D::TriggerController2D(std::weak_ptr<SceneItem> i) : SceneItemComponent(i) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<std::shared_ptr<SceneItemComponent>> TriggerController2D::getDependencies() {
 | 
			
		||||
  return {
 | 
			
		||||
    (this->collider = this->item.lock()->getComponent<Collider2D>())
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t TriggerController2D::getCollidingResult(std::shared_ptr<Collider2D> movingObject) {
 | 
			
		||||
  assertNotNull(this->collider, "TriggerController2D::getCollidingResult: Collider cannot be null");
 | 
			
		||||
  assertNotNull(movingObject, "TriggerController2D::getCollidingResult: Moving object cannot be null");
 | 
			
		||||
 | 
			
		||||
  switch(movingObject->getColliderType()) {
 | 
			
		||||
    case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
      auto box1 = std::static_pointer_cast<BoxCollider>(movingObject);
 | 
			
		||||
      assertNotNull(box1, "TriggerController2D::getCollidingResult: Moving object is not a BoxCollider");
 | 
			
		||||
 | 
			
		||||
      // Box VS ?
 | 
			
		||||
      switch(collider->getColliderType()) {
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = std::static_pointer_cast<BoxCollider>(collider);
 | 
			
		||||
          assertNotNull(box2, "TriggerController2D::getCollidingResult: Collider is not a BoxCollider");
 | 
			
		||||
          return boxIsBoxColliding(
 | 
			
		||||
            physics3Dto2D(box1->item.lock()->getWorldPosition()), box1->min, box1->max,
 | 
			
		||||
            physics3Dto2D(box2->item.lock()->getWorldPosition()), box2->min, box2->max
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        default: {
 | 
			
		||||
          assertUnreachable("TriggerController2D::getCollidingResult: Collider type not implemented");
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    default: {
 | 
			
		||||
      assertUnreachable("TriggerController2D::getCollidingResult: Moving object type not implemented");
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,27 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "BoxCollider.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class CharacterController2D;
 | 
			
		||||
  
 | 
			
		||||
  class TriggerController2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      std::shared_ptr<Collider2D> collider;
 | 
			
		||||
      StateEvent<CharacterController2D*> eventTriggerEnter;
 | 
			
		||||
 | 
			
		||||
      TriggerController2D(std::weak_ptr<SceneItem> i);
 | 
			
		||||
      std::vector<std::shared_ptr<SceneItemComponent>> getDependencies() override;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Returns whether or not the given moving object is colliding with this
 | 
			
		||||
       * trigger collider.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t getCollidingResult(std::shared_ptr<Collider2D> movingObject);
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,14 +0,0 @@
 | 
			
		||||
# 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
 | 
			
		||||
    Collider3D.cpp
 | 
			
		||||
    CubeCollider.cpp
 | 
			
		||||
    CapsuleCollider.cpp
 | 
			
		||||
    SphereCollider.cpp
 | 
			
		||||
    CharacterController3D.cpp
 | 
			
		||||
)
 | 
			
		||||
@@ -1,35 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "CapsuleCollider.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
CapsuleCollider::CapsuleCollider(std::weak_ptr<SceneItem> item) : Collider3D(item) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t CapsuleCollider::performRaycast(
 | 
			
		||||
  struct Collider3DRayResult *result,
 | 
			
		||||
  struct Ray3D ray
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(result, "CapsuleCollider::performRaycast: Result cannot be null");
 | 
			
		||||
 | 
			
		||||
  return raytestCapsule(
 | 
			
		||||
    ray,
 | 
			
		||||
    {
 | 
			
		||||
      .height = this->height,
 | 
			
		||||
      .radius = this->radius,
 | 
			
		||||
      .origin = item.lock()->getWorldPosition()
 | 
			
		||||
    },
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
    &result->distance
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum Collider3DType CapsuleCollider::getColliderType() {
 | 
			
		||||
  return COLLIDER3D_TYPE_CAPSULE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider3D.hpp"
 | 
			
		||||
#include "physics/3d/Ray3D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class CapsuleCollider : public Collider3D {
 | 
			
		||||
    protected:
 | 
			
		||||
      bool_t performRaycast(
 | 
			
		||||
        struct Collider3DRayResult *result,
 | 
			
		||||
        struct Ray3D ray
 | 
			
		||||
      ) override;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
      // @optional
 | 
			
		||||
      float_t height = 1;
 | 
			
		||||
      // @optional
 | 
			
		||||
      float_t radius = 0.5f;
 | 
			
		||||
 | 
			
		||||
      CapsuleCollider(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      enum Collider3DType getColliderType() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,37 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "CharacterController3D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
CharacterController3D::CharacterController3D(std::weak_ptr<SceneItem> item) :
 | 
			
		||||
  SceneItemComponent(item)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CharacterController3D::onStart() {
 | 
			
		||||
  useEvent([&](float_t delta){
 | 
			
		||||
    auto item = this->item.lock();
 | 
			
		||||
 | 
			
		||||
    // Friction
 | 
			
		||||
    velocity -= glm::vec3(velocity.x, 0, velocity.z) * friction * delta;
 | 
			
		||||
 | 
			
		||||
    // Gravity
 | 
			
		||||
    velocity += this->gravity * delta;
 | 
			
		||||
 | 
			
		||||
    auto myCollider = item->getComponent<Collider3D>();
 | 
			
		||||
    auto colliders = getScene()->findComponents<Collider3D>();
 | 
			
		||||
    auto itCollider = colliders.begin();
 | 
			
		||||
    // while(itCollider != colliders.end()) {
 | 
			
		||||
    //   (*itCollider)->
 | 
			
		||||
    //   ++itCollider;
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // Move / Update
 | 
			
		||||
    item->setLocalPosition(item->getLocalPosition() + (velocity * delta));
 | 
			
		||||
  }, getScene()->eventSceneUpdate);
 | 
			
		||||
}
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
// 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 CharacterController3D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec3 velocity = glm::vec3(0, 0, 0);
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec3 gravity = glm::vec3(0, -1, 0);
 | 
			
		||||
      // @optional
 | 
			
		||||
      float_t friction = 12.0f;
 | 
			
		||||
 | 
			
		||||
      CharacterController3D(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      void onStart() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "Collider3D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
Collider3D::Collider3D(std::weak_ptr<SceneItem> item) : SceneItemComponent(item) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Collider3D::raycast(
 | 
			
		||||
  struct Collider3DRayResult *result,
 | 
			
		||||
  struct Ray3D ray
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(result, "Collider3D::raycast: Result cannot be null");
 | 
			
		||||
  if(!this->performRaycast(result, ray)) return false;
 | 
			
		||||
  result->collider = this;
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,58 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "scene/SceneItemComponent.hpp"
 | 
			
		||||
#include "physics/3d/Ray3D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct Collider3DRayResult {
 | 
			
		||||
    glm::vec3 point;
 | 
			
		||||
    float_t distance;
 | 
			
		||||
    glm::vec3 normal;
 | 
			
		||||
    Collider3D *collider;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct Collider3DAABBSweepResult {
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  enum Collider3DType {
 | 
			
		||||
    COLLIDER3D_TYPE_CUBE,
 | 
			
		||||
    COLLIDER3D_TYPE_CAPSULE,
 | 
			
		||||
    COLLIDER3D_TYPE_SPHERE
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  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(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Perform a raycast against this collider.
 | 
			
		||||
       * 
 | 
			
		||||
       * @param result Where to store the result of the raycast collision 
 | 
			
		||||
       * @param ray The ray to cast against.
 | 
			
		||||
       * @return True if the ray intercepts this collider, otherwise false.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t raycast(struct Collider3DRayResult *result, struct Ray3D ray);
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Returns which type of collider this is. Useful for performing dynamic
 | 
			
		||||
       * casting in your event listeners.
 | 
			
		||||
       * 
 | 
			
		||||
       * @return The collider type this is.
 | 
			
		||||
       */
 | 
			
		||||
      virtual enum Collider3DType getColliderType() = 0;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "CubeCollider.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
CubeCollider::CubeCollider(std::weak_ptr<SceneItem> item) : Collider3D(item) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t CubeCollider::performRaycast(
 | 
			
		||||
  struct Collider3DRayResult *result,
 | 
			
		||||
  struct Ray3D ray
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(result, "CubeCollider::performRaycast: Result cannot be null");
 | 
			
		||||
 | 
			
		||||
  return Dawn::raytestCube(
 | 
			
		||||
    ray,
 | 
			
		||||
    { .min = this->min, .max = this->max },
 | 
			
		||||
    item.lock()->getWorldTransform(),
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
    &result->distance
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum Collider3DType CubeCollider::getColliderType() {
 | 
			
		||||
  return COLLIDER3D_TYPE_CUBE;
 | 
			
		||||
}
 | 
			
		||||
@@ -1,28 +0,0 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider3D.hpp"
 | 
			
		||||
#include "physics/3d/Ray3D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class CubeCollider : public Collider3D {
 | 
			
		||||
    protected:
 | 
			
		||||
      bool_t performRaycast(
 | 
			
		||||
        struct Collider3DRayResult *result,
 | 
			
		||||
        struct Ray3D ray
 | 
			
		||||
      ) override;
 | 
			
		||||
 | 
			
		||||
    public:
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec3 min = glm::vec3(-0.5f, -0.5f, -0.5f);
 | 
			
		||||
      // @optional
 | 
			
		||||
      glm::vec3 max = glm::vec3(0.5f, 0.5f, 0.5f);
 | 
			
		||||
 | 
			
		||||
      CubeCollider(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      enum Collider3DType getColliderType() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,31 +0,0 @@
 | 
			
		||||
// 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(std::weak_ptr<SceneItem> item) : Collider3D(item) {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
enum Collider3DType SphereCollider::getColliderType() {
 | 
			
		||||
  return COLLIDER3D_TYPE_SPHERE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t SphereCollider::performRaycast(
 | 
			
		||||
  struct Collider3DRayResult *result,
 | 
			
		||||
  struct Ray3D ray
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(result, "SphereCollider::performRaycast: Result cannot be null");
 | 
			
		||||
 | 
			
		||||
  return raytestSphere(
 | 
			
		||||
    ray,
 | 
			
		||||
    { .center = item.lock()->getLocalPosition(), .radius = this->radius },
 | 
			
		||||
    &result->point,
 | 
			
		||||
    &result->normal,
 | 
			
		||||
    &result->distance
 | 
			
		||||
  );
 | 
			
		||||
}
 | 
			
		||||
@@ -1,25 +0,0 @@
 | 
			
		||||
// 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:
 | 
			
		||||
      // @optional
 | 
			
		||||
      float_t radius = 1.0f;
 | 
			
		||||
      
 | 
			
		||||
      SphereCollider(std::weak_ptr<SceneItem> item);
 | 
			
		||||
 | 
			
		||||
      enum Collider3DType getColliderType() override;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +0,0 @@
 | 
			
		||||
# Copyright (c) 2023 Dominic Masters
 | 
			
		||||
# 
 | 
			
		||||
# This software is released under the MIT License.
 | 
			
		||||
# https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
# Subdirs
 | 
			
		||||
add_subdirectory(2d)
 | 
			
		||||
add_subdirectory(3d)
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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!"
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user