Refactored Raycasting, Added Layers for Raycasting to C#, Fixed Collision Tag Panel #331
|
@ -1,16 +1,16 @@
|
|||
0 1
|
||||
1 2
|
||||
2 3
|
||||
3 4
|
||||
4 5
|
||||
5 6
|
||||
6 7
|
||||
7 8
|
||||
8 9
|
||||
9 10
|
||||
10 11
|
||||
11 12
|
||||
12 13
|
||||
13 14
|
||||
14 15
|
||||
15 16
|
||||
0 1 3
|
||||
1 2 65535
|
||||
2 3 65534
|
||||
3 4 65534
|
||||
4 5 65534
|
||||
5 6 65534
|
||||
6 7 65534
|
||||
7 8 65534
|
||||
8 9 65534
|
||||
9 10 65534
|
||||
10 11 65534
|
||||
11 12 65534
|
||||
12 13 65534
|
||||
13 14 65534
|
||||
14 15 65534
|
||||
15 16 65534
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,8 +4,8 @@
|
|||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 2, y: 0, z: 0}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Translate: {x: 2, y: 2, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
|
@ -58,8 +58,8 @@
|
|||
NumberOfChildren: 0
|
||||
Components:
|
||||
Transform Component:
|
||||
Translate: {x: 0, y: -3, z: 0}
|
||||
Rotate: {x: 0, y: 0, z: 0}
|
||||
Translate: {x: 0, y: 0, z: 0}
|
||||
Rotate: {x: -0, y: 0, z: -0}
|
||||
Scale: {x: 1, y: 1, z: 1}
|
||||
IsActive: true
|
||||
RigidBody Component:
|
||||
|
@ -79,7 +79,7 @@
|
|||
Collider Component:
|
||||
Colliders:
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Collision Tag: 3
|
||||
Type: Sphere
|
||||
Radius: 1
|
||||
Friction: 0.400000006
|
||||
|
@ -88,7 +88,7 @@
|
|||
Position Offset: {x: 0, y: 0, z: 0}
|
||||
Rotation Offset: {x: 0, y: 0, z: 0}
|
||||
- Is Trigger: false
|
||||
Collision Tag: 1
|
||||
Collision Tag: 2
|
||||
Type: Box
|
||||
Half Extents: {x: 1, y: 1, z: 1}
|
||||
Friction: 0.400000006
|
||||
|
|
|
@ -14,18 +14,36 @@
|
|||
// Primary Header
|
||||
#include "SHCollisionTagMatrix.h"
|
||||
|
||||
#include "Tools/Utilities/SHUtilities.h"
|
||||
|
||||
namespace SHADE
|
||||
{
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Static Data Member Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHCollisionTagMatrix::dirty = true;
|
||||
SHCollisionTag SHCollisionTagMatrix::collisionTags[SHCollisionTag::NUM_LAYERS];
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHCollisionTagMatrix::IsDirty() noexcept
|
||||
{
|
||||
// Check if any collision tag is dirty
|
||||
for (auto& tag : collisionTags)
|
||||
{
|
||||
if (tag.IsDirty())
|
||||
{
|
||||
dirty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return dirty;
|
||||
}
|
||||
|
||||
const std::string& SHCollisionTagMatrix::GetTagName(int tagIndex)
|
||||
{
|
||||
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
|
||||
|
@ -91,6 +109,8 @@ namespace SHADE
|
|||
if (collisionTag.GetName() != tagName)
|
||||
continue;
|
||||
|
||||
dirty = true;
|
||||
|
||||
collisionTag = newTag;
|
||||
return;
|
||||
}
|
||||
|
@ -105,6 +125,8 @@ namespace SHADE
|
|||
if (collisionTag.GetName() != tagName)
|
||||
continue;
|
||||
|
||||
dirty = true;
|
||||
|
||||
collisionTag.SetMask(mask);
|
||||
return;
|
||||
}
|
||||
|
@ -125,6 +147,8 @@ namespace SHADE
|
|||
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
|
||||
throw std::invalid_argument("Index out of range!");
|
||||
|
||||
dirty = true;
|
||||
|
||||
collisionTags[tagIndex] = newTag;
|
||||
}
|
||||
|
||||
|
@ -133,6 +157,8 @@ namespace SHADE
|
|||
if (tagIndex < 0 || tagIndex > SHCollisionTag::NUM_LAYERS)
|
||||
throw std::invalid_argument("Index out of range!");
|
||||
|
||||
dirty = true;
|
||||
|
||||
collisionTags[tagIndex].SetMask(mask);
|
||||
}
|
||||
|
||||
|
@ -145,8 +171,9 @@ namespace SHADE
|
|||
/**
|
||||
* I HATE FILE IO
|
||||
*
|
||||
* Each line in the file should be "index<space>tag name".
|
||||
* If the line fails to follow this format, use the default tag name (index + 1)
|
||||
* Each line in the file should be "index<space>tag name<space>mask".
|
||||
* If the line fails to follow this format, use the default tag name (index + 1) and default mask.
|
||||
* If no mask was read, use a default mask.
|
||||
*/
|
||||
|
||||
// Populate tag names with default
|
||||
|
@ -187,18 +214,40 @@ namespace SHADE
|
|||
{
|
||||
SHLOG_ERROR
|
||||
(
|
||||
"Collision tag file line {} does not match the required format of 'index<space>tag name'. Default tag used for index {}"
|
||||
"Collision tag file line {} does not match the required format of 'index<space>tag name<space>mask'. Default tag used for index {}"
|
||||
, linesRead + 1
|
||||
, tagIndex
|
||||
)
|
||||
|
||||
// Use default
|
||||
collisionTags[tagIndex].SetName(std::to_string(tagIndex + 1));
|
||||
collisionTags[tagIndex].SetMask(SHUtilities::ConvertEnum(SHCollisionTag::Layer::ALL));
|
||||
continue;
|
||||
}
|
||||
|
||||
collisionTags[tagIndex].SetName(tagName);
|
||||
|
||||
// Next element is the mask value
|
||||
std::string maskString;
|
||||
ss >> maskString;
|
||||
|
||||
uint16_t mask = std::numeric_limits<uint16_t>::max();
|
||||
if (maskString.empty())
|
||||
{
|
||||
SHLOG_ERROR
|
||||
(
|
||||
"Collision tag file line {} does not match the required format of 'index<space>tag name<space>mask'. Default mask used for index {}"
|
||||
, linesRead + 1
|
||||
, tagIndex
|
||||
)
|
||||
}
|
||||
else
|
||||
{
|
||||
mask = static_cast<uint16_t>(std::stoi(maskString));
|
||||
}
|
||||
|
||||
collisionTags[tagIndex].SetMask(mask);
|
||||
|
||||
ss.clear();
|
||||
}
|
||||
|
||||
|
@ -215,9 +264,19 @@ namespace SHADE
|
|||
return;
|
||||
}
|
||||
|
||||
// Index Name Mask
|
||||
for (int i = 0; i < SHCollisionTag::NUM_LAYERS; ++i)
|
||||
collisionTagNamesFile << i << " " << collisionTags[i].GetName() << std::endl;
|
||||
collisionTagNamesFile << i << " " << collisionTags[i].GetName() << " " << collisionTags[i].GetMask() << std::endl;
|
||||
|
||||
collisionTagNamesFile.close();
|
||||
}
|
||||
|
||||
void SHCollisionTagMatrix::Clear() noexcept
|
||||
{
|
||||
dirty = false;
|
||||
|
||||
for (auto& tag : collisionTags)
|
||||
tag.dirty = false;
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
|
@ -29,6 +29,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] static bool IsDirty () noexcept;
|
||||
[[nodiscard]] static const std::string& GetTagName (int tagIndex);
|
||||
[[nodiscard]] static int GetTagIndex (const std::string& tagName) noexcept;
|
||||
|
||||
|
@ -57,11 +58,18 @@ namespace SHADE
|
|||
static void Init (const std::filesystem::path& tagNameFilePath) noexcept;
|
||||
static void Exit (const std::filesystem::path& tagNameFilePath) noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Clears the dirty flag.
|
||||
*/
|
||||
static void Clear () noexcept;
|
||||
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
static bool dirty;
|
||||
static SHCollisionTag collisionTags[SHCollisionTag::NUM_LAYERS];
|
||||
};
|
||||
}
|
|
@ -23,15 +23,18 @@ namespace SHADE
|
|||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
SHCollisionTag::SHCollisionTag() noexcept
|
||||
: mask { SHUtilities::ConvertEnum(Layer::ALL) }
|
||||
: dirty { true }
|
||||
, mask { SHUtilities::ConvertEnum(Layer::ALL) }
|
||||
{}
|
||||
|
||||
SHCollisionTag::SHCollisionTag(uint16_t _mask) noexcept
|
||||
: mask { _mask }
|
||||
: dirty { true }
|
||||
, mask { _mask }
|
||||
{}
|
||||
|
||||
SHCollisionTag::SHCollisionTag(Layer layer) noexcept
|
||||
: mask { SHUtilities::ConvertEnum(layer) }
|
||||
: dirty { true }
|
||||
, mask { SHUtilities::ConvertEnum(layer) }
|
||||
{}
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -57,6 +60,11 @@ namespace SHADE
|
|||
/* Getter Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
bool SHCollisionTag::IsDirty() const noexcept
|
||||
{
|
||||
return dirty;
|
||||
}
|
||||
|
||||
uint16_t SHCollisionTag::GetMask() const noexcept
|
||||
{
|
||||
return mask;
|
||||
|
@ -86,6 +94,7 @@ namespace SHADE
|
|||
|
||||
void SHCollisionTag::SetMask(uint16_t newMask) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
mask = newMask;
|
||||
}
|
||||
|
||||
|
@ -96,6 +105,8 @@ namespace SHADE
|
|||
|
||||
void SHCollisionTag::SetLayerState(Layer layer, bool state) noexcept
|
||||
{
|
||||
dirty = true;
|
||||
|
||||
const auto VALUE = SHUtilities::ConvertEnum(layer);
|
||||
state ? mask |= VALUE : mask &= ~(VALUE);
|
||||
}
|
||||
|
@ -105,6 +116,8 @@ namespace SHADE
|
|||
if (layerIndex < 0 || layerIndex > NUM_LAYERS)
|
||||
throw std::invalid_argument("Index out of range!");
|
||||
|
||||
dirty = true;
|
||||
|
||||
const auto VALUE = 1U << layerIndex;
|
||||
state ? mask |= (VALUE) : mask &= ~(VALUE);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,13 @@ namespace SHADE
|
|||
|
||||
class SH_API SHCollisionTag
|
||||
{
|
||||
private:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Friends */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
friend class SHCollisionTagMatrix;
|
||||
|
||||
public:
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
/* Type Definitions */
|
||||
|
@ -82,6 +89,7 @@ namespace SHADE
|
|||
/* Getter Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
[[nodiscard]] bool IsDirty () const noexcept;
|
||||
[[nodiscard]] uint16_t GetMask () const noexcept;
|
||||
[[nodiscard]] const std::string& GetName () const noexcept;
|
||||
[[nodiscard]] bool GetLayerState (Layer layer) const noexcept;
|
||||
|
@ -101,6 +109,7 @@ namespace SHADE
|
|||
/* Data Members */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
bool dirty;
|
||||
uint16_t mask;
|
||||
std::string name;
|
||||
};
|
||||
|
|
|
@ -102,11 +102,7 @@ namespace SHADE
|
|||
const SHTransform& PARENT_TRANSFORM = collider->GetTransform();
|
||||
SetScale(PARENT_TRANSFORM.scale);
|
||||
|
||||
if (rp3dCollider)
|
||||
{
|
||||
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) };
|
||||
rp3dCollider->setLocalToBodyTransform(OFFSETS);
|
||||
}
|
||||
SHCollisionShape::Update();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -118,6 +118,9 @@ namespace SHADE
|
|||
void SHCollisionShape::SetCollisionTag(SHCollisionTag* newCollisionTag) noexcept
|
||||
{
|
||||
collisionTag = newCollisionTag;
|
||||
|
||||
if (rp3dCollider)
|
||||
rp3dCollider->setCollideWithMaskBits(collisionTag->GetMask());
|
||||
}
|
||||
|
||||
void SHCollisionShape::SetFriction(float friction) noexcept
|
||||
|
@ -184,6 +187,13 @@ namespace SHADE
|
|||
/* Public Member Function Definitions */
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
||||
void SHCollisionShape::UpdateCollisionTags() noexcept
|
||||
{
|
||||
if (collisionTag->IsDirty())
|
||||
rp3dCollider->setCollideWithMaskBits(collisionTag->GetMask());
|
||||
}
|
||||
|
||||
|
||||
void SHCollisionShape::Update() noexcept
|
||||
{
|
||||
if (rp3dCollider)
|
||||
|
|
|
@ -123,6 +123,12 @@ namespace SHADE
|
|||
/* Member Functions */
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Re-sets the collision tags if it is dirty.
|
||||
*/
|
||||
void UpdateCollisionTags() noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Computes the transform of the shape.
|
||||
|
|
|
@ -105,11 +105,7 @@ namespace SHADE
|
|||
const float SPHERE_SCALE = std::fabs(SHMath::Max({ PARENT_TRANSFORM.scale.x, PARENT_TRANSFORM.scale.y, PARENT_TRANSFORM.scale.z }));
|
||||
SetScale(SPHERE_SCALE);
|
||||
|
||||
if (rp3dCollider)
|
||||
{
|
||||
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) };
|
||||
rp3dCollider->setLocalToBodyTransform(OFFSETS);
|
||||
}
|
||||
SHCollisionShape::Update();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
// Project Headers
|
||||
#include "Math/Transform/SHTransformComponent.h"
|
||||
#include "Physics/Collision/CollisionTags/SHCollisionTagMatrix.h"
|
||||
#include "Physics/Collision/Shapes/SHSphere.h"
|
||||
#include "Physics/Collision/Shapes/SHBox.h"
|
||||
#include "Physics/Interface/SHColliderComponent.h"
|
||||
|
@ -385,6 +386,11 @@ namespace SHADE
|
|||
}
|
||||
default: break;
|
||||
}
|
||||
|
||||
collisionShape->SetMaterial(collisionShape->GetMaterial());
|
||||
|
||||
const auto& COLLISION_TAG = collisionShape->GetCollisionTag();
|
||||
collisionShape->SetCollisionTag(SHCollisionTagMatrix::GetTag(COLLISION_TAG.GetName()));
|
||||
}
|
||||
|
||||
physicsObject->body->updateMassPropertiesFromColliders();
|
||||
|
|
|
@ -272,6 +272,12 @@ namespace SHADE
|
|||
shape->Update();
|
||||
}
|
||||
|
||||
void SHColliderComponent::UpdateCollisionTags() noexcept
|
||||
{
|
||||
for (auto& shape : shapes)
|
||||
shape->UpdateCollisionTags();
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace SHADE
|
||||
|
|
|
@ -158,6 +158,12 @@ namespace SHADE
|
|||
*/
|
||||
void Update () noexcept;
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Re-sets any dirty collision tags on collision shapes.
|
||||
*/
|
||||
void UpdateCollisionTags () noexcept;
|
||||
|
||||
private:
|
||||
|
||||
/*---------------------------------------------------------------------------------*/
|
||||
|
|
|
@ -36,6 +36,9 @@ namespace SHADE
|
|||
{
|
||||
auto* physicsSystem = reinterpret_cast<SHPhysicsSystem*>(GetSystem());
|
||||
|
||||
// Update colliders since collision tag has changed
|
||||
const bool UPDATE_COLLISION_TAGS = SHCollisionTagMatrix::IsDirty();
|
||||
|
||||
// Get all physics objects & sync transforms
|
||||
auto& physicsObjects = physicsSystem->objectManager.GetPhysicsObjects();
|
||||
for (auto& [entityID, physicsObject] : physicsObjects)
|
||||
|
@ -44,14 +47,16 @@ namespace SHADE
|
|||
// Assume transform is always active
|
||||
const bool UPDATE_TRANSFORM = TRANSFORM_COMPONENT && TRANSFORM_COMPONENT->HasChanged();
|
||||
|
||||
if (!UPDATE_TRANSFORM)
|
||||
continue;
|
||||
|
||||
// We assume that all engine components and physics object components have been successfully linked
|
||||
|
||||
if (!physicsObject.body)
|
||||
continue;
|
||||
|
||||
auto* shadeBody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID);
|
||||
auto* shadeCollider = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID);
|
||||
|
||||
if (UPDATE_TRANSFORM)
|
||||
{
|
||||
// Set body transform
|
||||
const SHVec3& WORLD_POS = TRANSFORM_COMPONENT->GetWorldPosition();
|
||||
const SHQuaternion& WORLD_ROT = TRANSFORM_COMPONENT->GetWorldOrientation();
|
||||
|
@ -60,7 +65,7 @@ namespace SHADE
|
|||
physicsObject.body->setTransform(NEW_TRANSFORM);
|
||||
|
||||
// Sync rigid body active states if one exists
|
||||
if (auto* shadeBody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID); shadeBody)
|
||||
if (shadeBody)
|
||||
{
|
||||
const bool SHADE_BODY_ACTIVE = SHSceneManager::CheckNodeAndComponentsActive<SHRigidBodyComponent>(entityID);
|
||||
const bool RP3D_BODY_ACTIVE = physicsObject.body->isActive();
|
||||
|
@ -73,7 +78,7 @@ namespace SHADE
|
|||
}
|
||||
|
||||
// Sync collider active states if one exists
|
||||
if (auto* shadeCollider = SHComponentManager::GetComponent_s<SHColliderComponent>(entityID); shadeCollider)
|
||||
if (shadeCollider)
|
||||
{
|
||||
const bool SHADE_COLLIDER_ACTIVE = SHSceneManager::CheckNodeAndComponentsActive<SHColliderComponent>(entityID);
|
||||
const bool RP3D_COLLIDERS_ACTIVE = shadeCollider->flags & SHColliderComponent::ACTIVE_FLAG;
|
||||
|
@ -90,6 +95,13 @@ namespace SHADE
|
|||
shadeCollider->Update();
|
||||
}
|
||||
}
|
||||
|
||||
if (UPDATE_COLLISION_TAGS && shadeCollider)
|
||||
shadeCollider->UpdateCollisionTags();
|
||||
}
|
||||
|
||||
// Clear collision tag dirty flags
|
||||
SHCollisionTagMatrix::Clear();
|
||||
}
|
||||
|
||||
} // namespace SHADE
|
Loading…
Reference in New Issue