Refactored Raycasting, Added Layers for Raycasting to C#, Fixed Collision Tag Panel #331

Merged
direnbharwani merged 10 commits from SP3-2-Physics into main 2023-02-03 16:26:07 +08:00
10 changed files with 144 additions and 62 deletions
Showing only changes of commit 3593df3ada - Show all commits

View File

@ -12,7 +12,7 @@
Type: Dynamic
Drag: 0.00999999978
Angular Drag: 0.100000001
Use Gravity: true
Use Gravity: false
Interpolate: true
Sleeping Enabled: false
Freeze Position X: false
@ -22,4 +22,33 @@
Freeze Rotation Y: false
Freeze Rotation Z: false
IsActive: true
Collider Component:
Colliders:
- Is Trigger: false
Collision Tag: 1
Type: Sphere
Radius: 1
Friction: 0.400000006
Bounciness: 0
Density: 1
Position Offset: {x: 0, y: 0, z: 0}
Rotation Offset: {x: 0, y: 0, z: 0}
IsActive: true
Scripts: ~
- EID: 1
Name: Default
IsActive: true
NumberOfChildren: 0
Components:
Camera Component:
Position: {x: 0, y: 0, z: -10}
Pitch: 0
Yaw: 0
Roll: 0
Width: 1920
Height: 1080
Near: 0.00999999978
Far: 10000
Perspective: true
IsActive: true
Scripts: ~

View File

@ -161,9 +161,6 @@ namespace SHADE
SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(pivot.GetEID());
auto physicsSystem = SHSystemManager::GetSystem<SHPhysicsSystem>();
if (camera == nullptr || transform == nullptr)
return;
@ -179,13 +176,12 @@ namespace SHADE
camera->dirtyView = true;
}*/
pivot.ray.position = camera->GetPosition() + pivot.targetOffset;
pivot.ray.direction = SHVec3::Normalise((camera->position + offset)- pivot.ray.position);
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
//SHLOG_INFO("Ray position: {},{},{} direction:{},{},{}",pivot.ray.position.x, pivot.ray.position.y, pivot.ray.position.z,pivot.ray.direction.x, pivot.ray.direction.y, pivot.ray.direction.z)
//auto result = physicsSystem->Raycast(pivot.ray );
//auto result = physicsSystem->Raycast(pivot.ray);
//if (result && result.distance < pivot.GetArmLength())
//{
//
@ -203,7 +199,7 @@ namespace SHADE
//
//
//// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix);
// pivot.rtMatrix = SHMatrix::Inverse(pivot.rtMatrix);
}

View File

@ -246,8 +246,6 @@ namespace SHADE
tf.world.position = SHVec3::Transform(tf.local.position, localToWorld);
tf.world.scale = tf.local.scale * (parent ? parent->GetLocalScale() : SHVec3::One);
if (convertRotation)
{
tf.worldRotation = tf.localRotation + (parent ? parent->GetLocalRotation() : SHVec3::Zero);

View File

@ -44,7 +44,10 @@ namespace SHADE
SHVec3 SHBox::GetWorldExtents() const noexcept
{
return SHVec3{ dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->getHalfExtents() };
if (rp3dCollider)
return SHVec3{ dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->getHalfExtents() };
return relativeExtents * scale * 0.5f;
}
SHVec3 SHBox::GetRelativeExtents() const noexcept
@ -65,7 +68,8 @@ namespace SHADE
void SHBox::SetWorldExtents(const SHVec3& newWorldExtents) noexcept
{
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents);
if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(newWorldExtents);
// Recompute Relative radius
relativeExtents = 2.0f * newWorldExtents / scale;
@ -76,7 +80,8 @@ namespace SHADE
relativeExtents = newRelativeExtents;
// Recompute world radius
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
}
void SHBox::SetScale(const SHVec3& newScale) noexcept
@ -84,7 +89,8 @@ namespace SHADE
scale = SHVec3::Abs(newScale);
// Recompute world radius
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
if (rp3dCollider)
dynamic_cast<rp3d::BoxShape*>(rp3dCollider->getCollisionShape())->setHalfExtents(relativeExtents * scale * 0.5f);
}
/*-----------------------------------------------------------------------------------*/

View File

@ -123,29 +123,38 @@ namespace SHADE
void SHCollisionShape::SetFriction(float friction) noexcept
{
material.SetFriction(friction);
rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction());
if (rp3dCollider)
rp3dCollider->getMaterial().setFrictionCoefficient(material.GetFriction());
}
void SHCollisionShape::SetBounciness(float bounciness) noexcept
{
material.SetBounciness(bounciness);
rp3dCollider->getMaterial().setBounciness(material.GetBounciness());
if (rp3dCollider)
rp3dCollider->getMaterial().setBounciness(material.GetBounciness());
}
void SHCollisionShape::SetDensity(float density) noexcept
{
material.SetDensity(density);
rp3dCollider->getMaterial().setMassDensity(material.GetDensity());
if (rp3dCollider)
rp3dCollider->getMaterial().setMassDensity(material.GetDensity());
}
void SHCollisionShape::SetMaterial(const SHPhysicsMaterial& newMaterial) noexcept
{
material = newMaterial;
auto& rp3dMaterial = rp3dCollider->getMaterial();
rp3dMaterial.setFrictionCoefficient(material.GetFriction());
rp3dMaterial.setBounciness(material.GetBounciness());
rp3dMaterial.setMassDensity(material.GetDensity());
if (rp3dCollider)
{
auto& rp3dMaterial = rp3dCollider->getMaterial();
rp3dMaterial.setFrictionCoefficient(material.GetFriction());
rp3dMaterial.setBounciness(material.GetBounciness());
rp3dMaterial.setMassDensity(material.GetDensity());
}
}
void SHCollisionShape::SetPositionOffset(const SHVec3& posOffset) noexcept
@ -167,7 +176,8 @@ namespace SHADE
isTrigger ? flags |= FLAG_VALUE : flags &= ~FLAG_VALUE;
rp3dCollider->setIsTrigger(isTrigger);
if (rp3dCollider)
rp3dCollider->setIsTrigger(isTrigger);
}
/*-----------------------------------------------------------------------------------*/
@ -176,8 +186,11 @@ namespace SHADE
void SHCollisionShape::Update() noexcept
{
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) };
rp3dCollider->setLocalToBodyTransform(OFFSETS);
if (rp3dCollider)
{
const rp3d::Transform OFFSETS{ positionOffset, SHQuaternion::FromEuler(rotationOffset) };
rp3dCollider->setLocalToBodyTransform(OFFSETS);
}
}
SHMatrix SHCollisionShape::GetTRS() const noexcept

View File

@ -41,6 +41,7 @@ namespace SHADE
/*---------------------------------------------------------------------------------*/
friend class SHPhysicsSystem;
friend class SHPhysicsObjectManager;
friend class SHColliderComponent;
public:

View File

@ -45,7 +45,10 @@ namespace SHADE
float SHSphere::GetWorldRadius() const noexcept
{
return dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->getRadius();
if (rp3dCollider)
return dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->getRadius();
return relativeRadius * scale * 0.5f;
}
float SHSphere::GetRelativeRadius() const noexcept
@ -66,7 +69,8 @@ namespace SHADE
void SHSphere::SetWorldRadius(float newWorldRadius) noexcept
{
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius);
if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(newWorldRadius);
// Recompute Relative radius
relativeRadius = 2.0f * newWorldRadius / scale;
@ -77,7 +81,8 @@ namespace SHADE
relativeRadius = newRelativeRadius;
// Recompute world radius
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
}
void SHSphere::SetScale(float maxScale) noexcept
@ -85,7 +90,8 @@ namespace SHADE
scale = std::fabs(maxScale);
// Recompute world radius
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
if (rp3dCollider)
dynamic_cast<rp3d::SphereShape*>(rp3dCollider->getCollisionShape())->setRadius(relativeRadius * scale * 0.5f);
}
/*-----------------------------------------------------------------------------------*/

View File

@ -176,8 +176,6 @@ namespace SHADE
void SHPhysicsObjectManager::RemoveCollider(EntityID entityID) noexcept
{
auto* colliderComponent = SHComponentManager::GetComponent<SHColliderComponent>(entityID);
const auto PHYSICS_OBJECT_ITERATOR = physicsObjects.find(entityID);
if (PHYSICS_OBJECT_ITERATOR != physicsObjects.end())
{
@ -189,13 +187,8 @@ namespace SHADE
{
auto* rp3dCollider = physicsObject->body->getCollider(numShapes);
physicsObject->body->removeCollider(rp3dCollider);
delete colliderComponent->shapes[numShapes];
colliderComponent->shapes[numShapes] = nullptr;
}
colliderComponent->shapes.clear();
// Destroy if no rigidbody component
if (!SHComponentManager::GetComponent_s<SHRigidBodyComponent>(entityID))
destroyPhysicsObject(entityID);
@ -356,25 +349,48 @@ namespace SHADE
colliderComponent->SetCollisionBody(physicsObject->body);
// Add all shapes
for (auto& shapeDef : DEF.shapes)
for (size_t i = 0; i < colliderComponent->shapes.size(); ++i)
{
switch (shapeDef.type)
// Get the currrent shape
auto& collisionShape = colliderComponent->shapes[i];
// Add the rp3d collider to the shade collision shape
switch (collisionShape->GetType())
{
case SHCollisionShape::Type::SPHERE:
{
colliderComponent->AddSphereCollisionShape(shapeDef.size.x);
auto* sphereShape = dynamic_cast<SHSphere*>(collisionShape);
const float SPHERE_SCALE = std::fabs(SHMath::Max({ colliderComponent->transform.scale.x, colliderComponent->transform.scale.y, colliderComponent->transform.scale.z }));
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(sphereShape->GetRelativeRadius() * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ sphereShape->GetPositionOffset(), SHQuaternion::FromEuler(sphereShape->GetRotationOffset()) };
sphereShape->rp3dCollider = physicsObject->body->addCollider(rp3dSphere, OFFSETS);
sphereShape->rp3dCollider->setIsTrigger(sphereShape->IsTrigger());
break;
}
case SHCollisionShape::Type::BOX:
{
colliderComponent->AddBoxCollisionShape(shapeDef.size);
auto* boxShape = dynamic_cast<SHBox*>(collisionShape);
rp3d::BoxShape* rp3dBox = factory->createBoxShape(boxShape->GetRelativeExtents() * colliderComponent->transform.scale * 0.5f);
const rp3d::Transform OFFSETS{ boxShape->GetPositionOffset(), SHQuaternion::FromEuler(boxShape->GetRotationOffset()) };
boxShape->rp3dCollider = physicsObject->body->addCollider(rp3dBox, OFFSETS);
boxShape->rp3dCollider->setIsTrigger(boxShape->IsTrigger());
break;
}
default: break;
}
}
}
physicsObject->body->updateMassPropertiesFromColliders();
colliderQueue.pop();
}
}
/*-----------------------------------------------------------------------------------*/

View File

@ -29,9 +29,23 @@ namespace SHADE
SHColliderComponent::SHColliderComponent() noexcept
: flags { ACTIVE_FLAG | MOVED_FLAG }
, factory { nullptr }
, collisionBody { nullptr }
{}
SHColliderComponent::~SHColliderComponent()
{
int32_t numShapes = static_cast<int32_t>(shapes.size());
while (--numShapes >= 0)
{
delete shapes[numShapes];
shapes[numShapes] = nullptr;
}
shapes.clear();
}
/*-----------------------------------------------------------------------------------*/
/* Getter Function Definitions */
/*-----------------------------------------------------------------------------------*/
@ -143,10 +157,10 @@ namespace SHADE
int SHColliderComponent::AddSphereCollisionShape(float relativeRadius, const SHVec3& posOffset, const SHVec3& rotOffset)
{
SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!")
const float SPHERE_SCALE = std::fabs(SHMath::Max({ transform.scale.x, transform.scale.y, transform.scale.z }));
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Create collision shape
shapes.emplace_back(new SHSphere{});
auto* newSphere = dynamic_cast<SHSphere*>(shapes.back());
@ -157,14 +171,6 @@ namespace SHADE
newSphere->relativeRadius = relativeRadius;
newSphere->scale = SPHERE_SCALE;
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(relativeRadius * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newSphere->rp3dCollider = collisionBody->addCollider(rp3dSphere, OFFSETS);
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Broadcast Event for adding a shape
const SHPhysicsColliderAddedEvent EVENT_DATA
{
@ -175,7 +181,17 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
// Only link with react if a factory is present.
// Otherwise, it will be linked through the physics object manager once the definitions are flushed.
if (factory)
{
rp3d::SphereShape* rp3dSphere = factory->createSphereShape(relativeRadius * SPHERE_SCALE * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newSphere->rp3dCollider = collisionBody->addCollider(rp3dSphere, OFFSETS);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
}
return static_cast<int>(NEW_INDEX);
}
@ -184,6 +200,8 @@ namespace SHADE
{
SHASSERT(factory, "Physics factory missing from Collider Component! Unable to add colliders!")
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Create collision shape
shapes.emplace_back(new SHBox{});
auto* newBox = dynamic_cast<SHBox*>(shapes.back());
@ -194,15 +212,6 @@ namespace SHADE
newBox->relativeExtents = relativeExtents;
newBox->scale = SHVec3::Abs(transform.scale);
rp3d::BoxShape* rp3dBox = factory->createBoxShape(relativeExtents * newBox->scale * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newBox->rp3dCollider = collisionBody->addCollider(rp3dBox, OFFSETS);
const uint32_t NEW_INDEX = static_cast<uint32_t>(shapes.size());
// Broadcast Event for adding a shape
const SHPhysicsColliderAddedEvent EVENT_DATA
{
@ -213,7 +222,15 @@ namespace SHADE
SHEventManager::BroadcastEvent<SHPhysicsColliderAddedEvent>(EVENT_DATA, SH_PHYSICS_COLLIDER_ADDED_EVENT);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
if (factory)
{
rp3d::BoxShape* rp3dBox = factory->createBoxShape(relativeExtents * newBox->scale * 0.5f);
const rp3d::Transform OFFSETS{ posOffset, SHQuaternion::FromEuler(rotOffset) };
newBox->rp3dCollider = collisionBody->addCollider(rp3dBox, OFFSETS);
dynamic_cast<rp3d::RigidBody*>(collisionBody)->updateMassPropertiesFromColliders();
}
return static_cast<int>(NEW_INDEX);
}

View File

@ -60,7 +60,7 @@ namespace SHADE
SHColliderComponent () noexcept;
SHColliderComponent (const SHColliderComponent& rhs) noexcept = default;
SHColliderComponent (SHColliderComponent&& rhs) noexcept = default;
~SHColliderComponent () override = default;
~SHColliderComponent () override;
/*---------------------------------------------------------------------------------*/
/* Operator Overloads */