Merge branch 'main' into PhySH

This commit is contained in:
Diren D Bharwani 2023-01-08 13:48:28 +08:00
commit ec945693aa
12 changed files with 249 additions and 7 deletions

View File

@ -207,6 +207,11 @@ namespace SHADE
drawSphere(getMeshBatch(true, depthTested), matrix, color);
}
void SHDebugDrawSystem::DrawWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
{
drawWireCapsule(getLineBatch(depthTested), getMeshBatch(false, depthTested), position, rotation, height, radius, color);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-----------------------------------------------------------------------------------*/
@ -264,6 +269,12 @@ namespace SHADE
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::DrawPersistentWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
{
drawWireCapsule(getPersistentLineBatch(depthTested), getPersistentMeshBatch(false, depthTested), position, rotation, height, radius, color);
markPersistentDrawsDirty();
}
void SHDebugDrawSystem::ClearPersistentDraws()
{
for (auto& batch : persistentLineBatches)
@ -348,6 +359,53 @@ namespace SHADE
);
}
void SHDebugDrawSystem::drawWireCapsule(LinesBatch& lineBatch, MeshBatch& meshBatch, const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color)
{
// Get local axis vectors
const SHVec3 LOCAL_UP = SHVec3::Rotate(SHVec3::Up, rotation);
const SHVec3 LOCAL_RIGHT = SHVec3::Rotate(SHVec3::Right, rotation);
const SHVec3 LOCAL_FORWARD = SHVec3::Rotate(SHVec3::Forward, rotation);
// Rotate the circle
SHQuaternion circleOrientation = SHQuaternion::FromEuler(SHVec3(SHMath::DegreesToRadians(90.0), 0.0f, 0.0f)) * rotation;
// Compute top and bottom of the cylinder
const SHVec3 HALF_UP = LOCAL_UP * (height * 0.5f - radius);
const SHVec3 TOP_POS = position + HALF_UP;
const SHVec3 BOT_POS = position - HALF_UP;
// Render circles
const SHVec3 CIRCLE_SCALE = SHVec3(radius * 2.0f, radius * 2.0, radius * 2.0);
drawCircle(meshBatch, SHMatrix::Transform(TOP_POS, circleOrientation, CIRCLE_SCALE), color);
drawCircle(meshBatch, SHMatrix::Transform(BOT_POS, circleOrientation, CIRCLE_SCALE), color);
// Render connecting lines
drawLine(lineBatch, TOP_POS + LOCAL_RIGHT * radius, BOT_POS + LOCAL_RIGHT * radius, color);
drawLine(lineBatch, TOP_POS - LOCAL_RIGHT * radius, BOT_POS - LOCAL_RIGHT * radius, color);
drawLine(lineBatch, TOP_POS + LOCAL_FORWARD * radius, BOT_POS + LOCAL_FORWARD * radius, color);
drawLine(lineBatch, TOP_POS - LOCAL_FORWARD * radius, BOT_POS - LOCAL_FORWARD * radius, color);
// Render caps
const SHVec3 RADIUS_SCALE = SHVec3(radius * 2.0, radius * 2.0f, radius * 2.0);
const SHMatrix TOP_CAP_MAT = SHMatrix::Transform(TOP_POS, rotation, RADIUS_SCALE);
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCapsuleCap),
meshBatch, TOP_CAP_MAT, color
);
const SHMatrix BOT_CAP_MAT = SHMatrix::Transform
(
BOT_POS,
SHQuaternion::FromEuler(SHVec3(SHMath::DegreesToRadians(180.0), 0.0f, 0.0f)) * rotation,
RADIUS_SCALE
);
drawMesh
(
gfxSystem->GetMeshPrimitive(PrimitiveType::LineCapsuleCap),
meshBatch, BOT_CAP_MAT, color
);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */
/*-----------------------------------------------------------------------------------*/

View File

@ -163,6 +163,17 @@ namespace SHADE
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a capsule.
/// </summary>
/// <param name="position">Position of the wireframe capsule.</param>
/// <param name="rotation">Rotation of the capsule.</param>
/// <param name="height">Height of the overall capsule.</param>
/// <param name="radius">Radius of the capsule.</param>
/// <param name="color"></param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
@ -269,6 +280,17 @@ namespace SHADE
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentSphere(const SHMatrix& matrix, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws a persistent outline of a capsule.
/// </summary>
/// <param name="position">Position of the wireframe capsule.</param>
/// <param name="rotation">Rotation of the capsule.</param>
/// <param name="height">Height of the overall capsule.</param>
/// <param name="radius">Radius of the capsule.</param>
/// <param name="color"></param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void DrawPersistentWireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Clears any persistent drawn debug primitives.
/// </summary>
void ClearPersistentDraws();
@ -386,6 +408,7 @@ namespace SHADE
void drawCube(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawSphere(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawCircle(MeshBatch& batch, const SHMatrix& transformMatrix, const SHColour& color);
void drawWireCapsule(LinesBatch& lineBatch, MeshBatch& meshBatch, const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color);
/*---------------------------------------------------------------------------------*/
/* Helper Batch Functions - Lines */

View File

@ -419,6 +419,7 @@ namespace SHADE
primitiveMeshes[static_cast<int>(PrimitiveType::Sphere)] = SHPrimitiveGenerator::Sphere(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCube)] = SHPrimitiveGenerator::LineCube(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCircle)] = SHPrimitiveGenerator::LineCircle(meshLibrary);
primitiveMeshes[static_cast<int>(PrimitiveType::LineCapsuleCap)] = SHPrimitiveGenerator::LineCapsuleCap(meshLibrary);
BuildMeshBuffers();
// Create default materials
@ -819,6 +820,7 @@ namespace SHADE
case PrimitiveType::Sphere:
case PrimitiveType::LineCube:
case PrimitiveType::LineCircle:
case PrimitiveType::LineCapsuleCap:
return primitiveMeshes[static_cast<int>(type)];
default:
return {};

View File

@ -72,9 +72,10 @@ namespace SHADE
Cube,
Sphere,
LineCube,
LineCircle
LineCircle,
LineCapsuleCap
};
static constexpr int MAX_PRIMITIVE_TYPES = 4;
static constexpr int MAX_PRIMITIVE_TYPES = 5;
enum class DebugDrawPipelineType
{
LineNoDepthTest,

View File

@ -29,6 +29,7 @@ namespace SHADE
SHMeshData SHPrimitiveGenerator::sphereMesh;
SHMeshData SHPrimitiveGenerator::lineCubeMesh;
SHMeshData SHPrimitiveGenerator::lineCircleMesh;
SHMeshData SHPrimitiveGenerator::lineCapsuleCapMesh;
/*-----------------------------------------------------------------------------------*/
/* Primitive Generation Functions */
@ -392,6 +393,64 @@ namespace SHADE
return addMeshDataTo(lineCircleMesh, gfxSystem);
}
SHADE::SHMeshData SHPrimitiveGenerator::LineCapsuleCap() noexcept
{
SHMeshData mesh;
// Have multiple semi-circles for the cap
static constexpr int SPLITS = 36;
static constexpr float ANGLE_INCREMENTS = (std::numbers::pi_v<float> * 2.0f) / static_cast<float>(SPLITS);
/* X-Axis */
// Generate points of the circle
for (int i = 0; i <= SPLITS / 2; ++i)
{
const float ANGLE = ANGLE_INCREMENTS * i;
mesh.VertexPositions.emplace_back(cos(ANGLE) * 0.5f, sin(ANGLE) * 0.5f, 0.0f);
}
// Generate lines of the circle
for (int i = 1; i <= SPLITS / 2; ++i)
{
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
}
/* Z-Axis */
// Generate points of the circle
for (int i = 0; i <= SPLITS / 2; ++i)
{
const float ANGLE = ANGLE_INCREMENTS * i;
mesh.VertexPositions.emplace_back(0.0f, sin(ANGLE) * 0.5f, cos(ANGLE) * 0.5f);
}
// Generate lines of the circle
for (int i = 2 + SPLITS / 2; i <= SPLITS + 1; ++i)
{
mesh.Indices.emplace_back(static_cast<uint32_t>(i - 1));
mesh.Indices.emplace_back(static_cast<uint32_t>(i));
}
mesh.VertexNormals.resize(mesh.VertexPositions.size());
mesh.VertexTangents.resize(mesh.VertexPositions.size());
mesh.VertexTexCoords.resize(mesh.VertexPositions.size());
return mesh;
}
Handle<SHADE::SHMesh> SHPrimitiveGenerator::LineCapsuleCap(SHMeshLibrary& meshLibrary) noexcept
{
if (lineCapsuleCapMesh.VertexPositions.empty())
lineCapsuleCapMesh = LineCapsuleCap();
return addMeshDataTo(lineCapsuleCapMesh, meshLibrary);
}
Handle<SHADE::SHMesh> SHPrimitiveGenerator::LineCapsuleCap(SHGraphicsSystem& gfxSystem) noexcept
{
if (lineCapsuleCapMesh.VertexPositions.empty())
lineCapsuleCapMesh = LineCapsuleCap();
return addMeshDataTo(lineCapsuleCapMesh, gfxSystem);
}
/*-----------------------------------------------------------------------------------*/
/* Helper Functions */
/*-----------------------------------------------------------------------------------*/

View File

@ -194,6 +194,46 @@ namespace SHADE
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCircle(SHGraphicsSystem& gfxSystem) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cap of a wireframe capsule that is comprised only of lines and
store the data in a SHMeshData object.
\return
SHMeshData object containing vertex data for the line circle.
*/
/***********************************************************************************/
[[nodiscard]] static SHMeshData LineCapsuleCap() noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cap of a wireframe capsule that is comprised only of lines and
constructs a SHMesh using the SHGraphicsSystem provided.
\param meshLibrary
Reference to the SHMeshLibrary to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the SHMeshLibrary.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCapsuleCap(SHMeshLibrary& meshLibrary) noexcept;
/***********************************************************************************/
/*!
\brief
Produces a cap of a wireframe capsule that is comprised only of lines and
constructs a SHMesh using the SHGraphicsSystem provided.
\param gfxSystem
Reference to the SHGraphicsSystem to produce and store a line circle mesh in.
\return
SHMesh object that points to the generated line circle mesh in the
SHGraphicsSystem.
*/
/***********************************************************************************/
[[nodiscard]] static Handle<SHMesh> LineCapsuleCap(SHGraphicsSystem& gfxSystem) noexcept;
private:
/*---------------------------------------------------------------------------------*/
@ -209,5 +249,6 @@ namespace SHADE
static SHMeshData sphereMesh;
static SHMeshData lineCubeMesh;
static SHMeshData lineCircleMesh;
static SHMeshData lineCapsuleCapMesh;
};
}

View File

@ -35,7 +35,17 @@ namespace SHADE
: position { pos }
, orientation { SHQuaternion::FromEuler(rot) }
, scale { scl }
{}
{
ComputeTRS();
}
SHTransform::SHTransform(const SHVec3& pos, const SHQuaternion& quat, const SHVec3& scl) noexcept
: position { pos }
, orientation { quat }
, scale { scl }
{
ComputeTRS();
}
/*-----------------------------------------------------------------------------------*/
/* Operator Overload Definitions */

View File

@ -128,6 +128,10 @@ namespace SHADE
dbgDrawSys->DrawWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
{
dbgDrawSys->DrawWireCapsule(position, rotation, height, radius, color, depthTested);
}
/*-----------------------------------------------------------------------------------*/
/* Persistent Draw Functions */
/*-----------------------------------------------------------------------------------*/
@ -216,6 +220,10 @@ namespace SHADE
dbgDrawSys->DrawPersistentWireSphere(SHMatrix::Transform(center, SHQuaternion(), scale), color, depthTested);
}
void SHDebugDraw::Persistent::WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color, bool depthTested)
{
dbgDrawSys->DrawPersistentWireCapsule(position, rotation, height, radius, color, depthTested);
}
void SHDebugDraw::Persistent::ClearDraws()
{
dbgDrawSys->ClearPersistentDraws();

View File

@ -194,6 +194,18 @@ namespace SHADE
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a capsule.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="position">Position of the wireframe capsule.</param>
/// <param name="rotation">Rotation of the capsule.</param>
/// <param name="height">Height of the overall capsule.</param>
/// <param name="radius">Radius of the capsule.</param>
/// <param name="color"></param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/*---------------------------------------------------------------------------------*/
/* Persistent Draw Function Class "Folder" */
@ -366,6 +378,18 @@ namespace SHADE
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
static void WireSphere(const SHVec3& center, const SHVec3& scale, const SHVec4& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Draws the outline of a capsule.
/// This will remain drawn until ClearDraws() is called.
/// </summary>
/// <param name="position">Position of the wireframe capsule.</param>
/// <param name="rotation">Rotation of the capsule.</param>
/// <param name="height">Height of the overall capsule.</param>
/// <param name="radius">Radius of the capsule.</param>
/// <param name="color"></param>
/// <param name="color">Colour to draw with.</param>
/// <param name="depthTested">Whether or not drawn object will be occluded.</param>
void WireCapsule(const SHVec3& position, const SHQuaternion& rotation, float height, float radius, const SHColour& color = SHColour::WHITE, bool depthTested = false);
/// <summary>
/// Clears any persistent drawn debug primitives.
/// </summary>
static void ClearDraws();

View File

@ -107,8 +107,7 @@ namespace SHADE
Vector3 Transform::Forward::get()
{
const SHVec3 DIRECTION = SHVec3::Rotate(-SHVec3::UnitZ, Convert::ToNative(GlobalRotation));
return Convert::ToCLI(DIRECTION);
return Vector3::Rotate(Vector3::Forward, GlobalRotation);
}
/*-----------------------------------------------------------------------------------*/

View File

@ -167,6 +167,10 @@ namespace SHADE
{
return Convert::ToCLI(SHVec3::Rotate(Convert::ToNative(vec), Convert::ToNative(axis), radians));
}
Vector3 Vector3::Rotate(Vector3 vec, Quaternion quat)
{
return Convert::ToCLI(SHVec3::Rotate(Convert::ToNative(vec), Convert::ToNative(quat)));
}
Vector3 Vector3::Min(Vector3 lhs, Vector3 rhs)
{
float lx = lhs.x, rx = rhs.x;

View File

@ -19,10 +19,17 @@ of DigiPen Institute of Technology is prohibited.
// Project Includes
#include "Vector2.hxx"
value struct Quaternion;
namespace SHADE
{
/*---------------------------------------------------------------------------------*/
/* Forward Declarations */
/*-------------------------------------------------------------------------- --- */
value struct Quaternion;
/*---------------------------------------------------------------------------------*/
/* Type Definitions */
/*-------------------------------------------------------------------------- --- */
///<summary>
/// CLR version of SHADE Engine's Vector3 class that represents a 3-Dimensional Vector.
/// Designed to closely match Unity's Vector3 struct.
@ -308,6 +315,12 @@ namespace SHADE
/// <returns>The Vector3 that represents the rotated vector.</returns>
static Vector3 Rotate(Vector3 vec, Vector3 axis, float radians);
/// <summary>
/// Rotates a Vector3 using a Quaternion.
/// </summary>
/// <param name="vec">A Vector3 to rotate.</param>
/// <param name="quat">A Quaternion to rotate the vector with.</param>
static Vector3 Rotate(Vector3 vec, Quaternion quat);
/// <summary>
/// Computes and returns a Vector3 that is made from the smallest components of
/// the two specified Vector3s.
/// </summary>