Fix invalid Rigidbody bounds if it has no shapes attached
This commit is contained in:
@@ -1396,7 +1396,7 @@ bool Actor::HasActorInChildren(Actor* a) const
|
|||||||
|
|
||||||
bool Actor::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
bool Actor::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
||||||
{
|
{
|
||||||
return GetBox().Intersects(ray, distance, normal);
|
return _box.Intersects(ray, distance, normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Actor* Actor::Intersects(const Ray& ray, float& distance, Vector3& normal)
|
Actor* Actor::Intersects(const Ray& ray, float& distance, Vector3& normal)
|
||||||
|
|||||||
@@ -1,54 +0,0 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#include "PhysicsActor.h"
|
|
||||||
#include "../PhysicsBackend.h"
|
|
||||||
|
|
||||||
PhysicsActor::PhysicsActor(const SpawnParams& params)
|
|
||||||
: Actor(params)
|
|
||||||
, _cachedScale(1.0f)
|
|
||||||
, _isUpdatingTransform(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsActor::OnActiveTransformChanged()
|
|
||||||
{
|
|
||||||
// Change actor transform (but with locking)
|
|
||||||
ASSERT(!_isUpdatingTransform);
|
|
||||||
_isUpdatingTransform = true;
|
|
||||||
Transform transform;
|
|
||||||
PhysicsBackend::GetRigidActorPose(GetPhysicsActor(), transform.Translation, transform.Orientation);
|
|
||||||
transform.Scale = _transform.Scale;
|
|
||||||
if (_parent)
|
|
||||||
{
|
|
||||||
_parent->GetTransform().WorldToLocal(transform, _localTransform);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_localTransform = transform;
|
|
||||||
}
|
|
||||||
OnTransformChanged();
|
|
||||||
_isUpdatingTransform = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsActor::OnTransformChanged()
|
|
||||||
{
|
|
||||||
// Base
|
|
||||||
Actor::OnTransformChanged();
|
|
||||||
|
|
||||||
UpdateBounds();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PhysicsActor::UpdateBounds()
|
|
||||||
{
|
|
||||||
void* actor = GetPhysicsActor();
|
|
||||||
if (actor)
|
|
||||||
PhysicsBackend::GetActorBounds(actor, _box);
|
|
||||||
else
|
|
||||||
_box = BoundingBox(_transform.Translation);
|
|
||||||
BoundingSphere::FromBox(_box, _sphere);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PhysicsActor::IntersectsItself(const Ray& ray, float& distance, Vector3& normal)
|
|
||||||
{
|
|
||||||
return _box.Intersects(ray, distance, normal);
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
// Copyright (c) 2012-2022 Wojciech Figat. All rights reserved.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Engine/Level/Actor.h"
|
|
||||||
#include "Engine/Physics/Types.h"
|
|
||||||
#include "IPhysicsActor.h"
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A base class for all physical actors.
|
|
||||||
/// </summary>
|
|
||||||
/// <seealso cref="Actor" />
|
|
||||||
API_CLASS(Abstract) class FLAXENGINE_API PhysicsActor : public Actor, public IPhysicsActor
|
|
||||||
{
|
|
||||||
DECLARE_SCENE_OBJECT_ABSTRACT(PhysicsActor);
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Vector3 _cachedScale;
|
|
||||||
bool _isUpdatingTransform;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Updates the bounding box.
|
|
||||||
/// </summary>
|
|
||||||
void UpdateBounds();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// [Actor]
|
|
||||||
bool IntersectsItself(const Ray& ray, float& distance, Vector3& normal) override;
|
|
||||||
|
|
||||||
// [IPhysicsActor]
|
|
||||||
void OnActiveTransformChanged() override;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
// [Actor]
|
|
||||||
void OnTransformChanged() override;
|
|
||||||
};
|
|
||||||
@@ -8,8 +8,9 @@
|
|||||||
#include "Engine/Serialization/Serialization.h"
|
#include "Engine/Serialization/Serialization.h"
|
||||||
|
|
||||||
RigidBody::RigidBody(const SpawnParams& params)
|
RigidBody::RigidBody(const SpawnParams& params)
|
||||||
: PhysicsActor(params)
|
: Actor(params)
|
||||||
, _actor(nullptr)
|
, _actor(nullptr)
|
||||||
|
, _cachedScale(1.0f)
|
||||||
, _mass(1.0f)
|
, _mass(1.0f)
|
||||||
, _linearDamping(0.01f)
|
, _linearDamping(0.01f)
|
||||||
, _angularDamping(0.05f)
|
, _angularDamping(0.05f)
|
||||||
@@ -24,6 +25,7 @@ RigidBody::RigidBody(const SpawnParams& params)
|
|||||||
, _startAwake(true)
|
, _startAwake(true)
|
||||||
, _updateMassWhenScaleChanges(false)
|
, _updateMassWhenScaleChanges(false)
|
||||||
, _overrideMass(false)
|
, _overrideMass(false)
|
||||||
|
, _isUpdatingTransform(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,13 +226,13 @@ bool RigidBody::IsSleeping() const
|
|||||||
void RigidBody::Sleep() const
|
void RigidBody::Sleep() const
|
||||||
{
|
{
|
||||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||||
PhysicsBackend::GetRigidActorSleep(_actor);
|
PhysicsBackend::RigidDynamicActorSleep(_actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::WakeUp() const
|
void RigidBody::WakeUp() const
|
||||||
{
|
{
|
||||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||||
PhysicsBackend::GetRigidDynamicActorWakeUp(_actor);
|
PhysicsBackend::RigidDynamicActorWakeUp(_actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::UpdateMass()
|
void RigidBody::UpdateMass()
|
||||||
@@ -323,6 +325,16 @@ void RigidBody::OnColliderChanged(Collider* c)
|
|||||||
// WakeUp();
|
// WakeUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RigidBody::UpdateBounds()
|
||||||
|
{
|
||||||
|
void* actor = GetPhysicsActor();
|
||||||
|
if (actor && PhysicsBackend::GetRigidActorShapesCount(actor) != 0)
|
||||||
|
PhysicsBackend::GetActorBounds(actor, _box);
|
||||||
|
else
|
||||||
|
_box = BoundingBox(_transform.Translation);
|
||||||
|
BoundingSphere::FromBox(_box, _sphere);
|
||||||
|
}
|
||||||
|
|
||||||
void RigidBody::UpdateScale()
|
void RigidBody::UpdateScale()
|
||||||
{
|
{
|
||||||
const Vector3 scale = GetScale();
|
const Vector3 scale = GetScale();
|
||||||
@@ -339,7 +351,7 @@ void RigidBody::UpdateScale()
|
|||||||
void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
PhysicsActor::Serialize(stream, otherObj);
|
Actor::Serialize(stream, otherObj);
|
||||||
|
|
||||||
SERIALIZE_GET_OTHER_OBJ(RigidBody);
|
SERIALIZE_GET_OTHER_OBJ(RigidBody);
|
||||||
|
|
||||||
@@ -364,7 +376,7 @@ void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
|||||||
void RigidBody::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
void RigidBody::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
PhysicsActor::Deserialize(stream, modifier);
|
Actor::Deserialize(stream, modifier);
|
||||||
|
|
||||||
DESERIALIZE_BIT_MEMBER(OverrideMass, _overrideMass);
|
DESERIALIZE_BIT_MEMBER(OverrideMass, _overrideMass);
|
||||||
DESERIALIZE_MEMBER(Mass, _mass);
|
DESERIALIZE_MEMBER(Mass, _mass);
|
||||||
@@ -389,6 +401,26 @@ void* RigidBody::GetPhysicsActor() const
|
|||||||
return _actor;
|
return _actor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RigidBody::OnActiveTransformChanged()
|
||||||
|
{
|
||||||
|
// Change actor transform (but with locking)
|
||||||
|
ASSERT(!_isUpdatingTransform);
|
||||||
|
_isUpdatingTransform = true;
|
||||||
|
Transform transform;
|
||||||
|
PhysicsBackend::GetRigidActorPose(GetPhysicsActor(), transform.Translation, transform.Orientation);
|
||||||
|
transform.Scale = _transform.Scale;
|
||||||
|
if (_parent)
|
||||||
|
{
|
||||||
|
_parent->GetTransform().WorldToLocal(transform, _localTransform);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_localTransform = transform;
|
||||||
|
}
|
||||||
|
OnTransformChanged();
|
||||||
|
_isUpdatingTransform = false;
|
||||||
|
}
|
||||||
|
|
||||||
void RigidBody::BeginPlay(SceneBeginData* data)
|
void RigidBody::BeginPlay(SceneBeginData* data)
|
||||||
{
|
{
|
||||||
// Create rigid body
|
// Create rigid body
|
||||||
@@ -441,13 +473,13 @@ void RigidBody::BeginPlay(SceneBeginData* data)
|
|||||||
UpdateBounds();
|
UpdateBounds();
|
||||||
|
|
||||||
// Base
|
// Base
|
||||||
PhysicsActor::BeginPlay(data);
|
Actor::BeginPlay(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::EndPlay()
|
void RigidBody::EndPlay()
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
PhysicsActor::EndPlay();
|
Actor::EndPlay();
|
||||||
|
|
||||||
if (_actor)
|
if (_actor)
|
||||||
{
|
{
|
||||||
@@ -462,7 +494,7 @@ void RigidBody::EndPlay()
|
|||||||
void RigidBody::OnActiveInTreeChanged()
|
void RigidBody::OnActiveInTreeChanged()
|
||||||
{
|
{
|
||||||
// Base
|
// Base
|
||||||
PhysicsActor::OnActiveInTreeChanged();
|
Actor::OnActiveInTreeChanged();
|
||||||
|
|
||||||
if (_actor)
|
if (_actor)
|
||||||
{
|
{
|
||||||
@@ -480,23 +512,18 @@ void RigidBody::OnActiveInTreeChanged()
|
|||||||
|
|
||||||
void RigidBody::OnTransformChanged()
|
void RigidBody::OnTransformChanged()
|
||||||
{
|
{
|
||||||
|
// Base
|
||||||
|
Actor::OnTransformChanged();
|
||||||
|
|
||||||
// Update physics is not during physics state synchronization
|
// Update physics is not during physics state synchronization
|
||||||
if (!_isUpdatingTransform && _actor)
|
if (!_isUpdatingTransform && _actor)
|
||||||
{
|
{
|
||||||
// Base (skip PhysicsActor call to optimize)
|
|
||||||
Actor::OnTransformChanged();
|
|
||||||
|
|
||||||
const bool kinematic = GetIsKinematic() && GetEnableSimulation();
|
const bool kinematic = GetIsKinematic() && GetEnableSimulation();
|
||||||
PhysicsBackend::SetRigidActorPose(_actor, _transform.Translation, _transform.Orientation, kinematic, true);
|
PhysicsBackend::SetRigidActorPose(_actor, _transform.Translation, _transform.Orientation, kinematic, true);
|
||||||
|
|
||||||
UpdateScale();
|
UpdateScale();
|
||||||
UpdateBounds();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Base
|
|
||||||
PhysicsActor::OnTransformChanged();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UpdateBounds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RigidBody::OnPhysicsSceneChanged(PhysicsScene* previous)
|
void RigidBody::OnPhysicsSceneChanged(PhysicsScene* previous)
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "PhysicsActor.h"
|
#include "Engine/Level/Actor.h"
|
||||||
|
#include "Engine/Physics/Types.h"
|
||||||
|
#include "Engine/Physics/Actors/IPhysicsActor.h"
|
||||||
#include "Engine/Physics/Collisions.h"
|
#include "Engine/Physics/Collisions.h"
|
||||||
|
|
||||||
class PhysicsColliderActor;
|
class PhysicsColliderActor;
|
||||||
@@ -11,8 +13,8 @@ class Collider;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Physics simulation driven object.
|
/// Physics simulation driven object.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <seealso cref="PhysicsActor" />
|
/// <seealso cref="Actor" />
|
||||||
API_CLASS() class FLAXENGINE_API RigidBody : public PhysicsActor
|
API_CLASS() class FLAXENGINE_API RigidBody : public Actor, public IPhysicsActor
|
||||||
{
|
{
|
||||||
DECLARE_SCENE_OBJECT(RigidBody);
|
DECLARE_SCENE_OBJECT(RigidBody);
|
||||||
protected:
|
protected:
|
||||||
@@ -35,6 +37,7 @@ protected:
|
|||||||
int32 _startAwake : 1;
|
int32 _startAwake : 1;
|
||||||
int32 _updateMassWhenScaleChanges : 1;
|
int32 _updateMassWhenScaleChanges : 1;
|
||||||
int32 _overrideMass : 1;
|
int32 _overrideMass : 1;
|
||||||
|
int32 _isUpdatingTransform : 1;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -537,7 +540,10 @@ public:
|
|||||||
// Called when collider gets detached from this rigidbody or activated/deactivated. Used to update rigidbody mass.
|
// Called when collider gets detached from this rigidbody or activated/deactivated. Used to update rigidbody mass.
|
||||||
virtual void OnColliderChanged(Collider* c);
|
virtual void OnColliderChanged(Collider* c);
|
||||||
|
|
||||||
protected:
|
/// <summary>
|
||||||
|
/// Updates the bounding box.
|
||||||
|
/// </summary>
|
||||||
|
void UpdateBounds();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Updates the rigidbody scale dependent properties like mass (may be modified when actor transformation changes).
|
/// Updates the rigidbody scale dependent properties like mass (may be modified when actor transformation changes).
|
||||||
@@ -546,14 +552,17 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// [PhysicsActor]
|
// [Actor]
|
||||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||||
|
|
||||||
|
// [IPhysicsActor]
|
||||||
void* GetPhysicsActor() const override;
|
void* GetPhysicsActor() const override;
|
||||||
|
void OnActiveTransformChanged() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// [PhysicsActor]
|
// [Actor]
|
||||||
void BeginPlay(SceneBeginData* data) override;
|
void BeginPlay(SceneBeginData* data) override;
|
||||||
void EndPlay() override;
|
void EndPlay() override;
|
||||||
void OnActiveInTreeChanged() override;
|
void OnActiveInTreeChanged() override;
|
||||||
|
|||||||
@@ -1607,6 +1607,12 @@ void PhysicsBackend::GetActorBounds(void* actor, BoundingBox& bounds)
|
|||||||
bounds = P2C(actorPhysX->getWorldBounds(boundsScale));
|
bounds = P2C(actorPhysX->getWorldBounds(boundsScale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 PhysicsBackend::GetRigidActorShapesCount(void* actor)
|
||||||
|
{
|
||||||
|
auto actorPhysX = (PxRigidActor*)actor;
|
||||||
|
return actorPhysX->getNbShapes();
|
||||||
|
}
|
||||||
|
|
||||||
void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation)
|
void* PhysicsBackend::CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation)
|
||||||
{
|
{
|
||||||
const PxTransform trans(C2P(position), C2P(orientation));
|
const PxTransform trans(C2P(position), C2P(orientation));
|
||||||
@@ -1749,13 +1755,13 @@ bool PhysicsBackend::GetRigidDynamicActorIsSleeping(void* actor)
|
|||||||
return actorPhysX->isSleeping();
|
return actorPhysX->isSleeping();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::GetRigidActorSleep(void* actor)
|
void PhysicsBackend::RigidDynamicActorSleep(void* actor)
|
||||||
{
|
{
|
||||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||||
actorPhysX->putToSleep();
|
actorPhysX->putToSleep();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PhysicsBackend::GetRigidDynamicActorWakeUp(void* actor)
|
void PhysicsBackend::RigidDynamicActorWakeUp(void* actor)
|
||||||
{
|
{
|
||||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||||
actorPhysX->wakeUp();
|
actorPhysX->wakeUp();
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ public:
|
|||||||
static ActorFlags GetActorFlags(void* actor);
|
static ActorFlags GetActorFlags(void* actor);
|
||||||
static void SetActorFlags(void* actor, ActorFlags value);
|
static void SetActorFlags(void* actor, ActorFlags value);
|
||||||
static void GetActorBounds(void* actor, BoundingBox& bounds);
|
static void GetActorBounds(void* actor, BoundingBox& bounds);
|
||||||
|
static int32 GetRigidActorShapesCount(void* actor);
|
||||||
static void* CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
static void* CreateRigidDynamicActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
||||||
static void* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
static void* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
||||||
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
||||||
@@ -148,8 +149,8 @@ public:
|
|||||||
static Vector3 GetRigidDynamicActorCenterOfMass(void* actor);
|
static Vector3 GetRigidDynamicActorCenterOfMass(void* actor);
|
||||||
static void SetRigidDynamicActorCenterOfMassOffset(void* actor, const Vector3& value);
|
static void SetRigidDynamicActorCenterOfMassOffset(void* actor, const Vector3& value);
|
||||||
static bool GetRigidDynamicActorIsSleeping(void* actor);
|
static bool GetRigidDynamicActorIsSleeping(void* actor);
|
||||||
static void GetRigidActorSleep(void* actor);
|
static void RigidDynamicActorSleep(void* actor);
|
||||||
static void GetRigidDynamicActorWakeUp(void* actor);
|
static void RigidDynamicActorWakeUp(void* actor);
|
||||||
static float GetRigidDynamicActorSleepThreshold(void* actor);
|
static float GetRigidDynamicActorSleepThreshold(void* actor);
|
||||||
static void SetRigidDynamicActorSleepThreshold(void* actor, float value);
|
static void SetRigidDynamicActorSleepThreshold(void* actor, float value);
|
||||||
static float GetRigidDynamicActorMaxDepenetrationVelocity(void* actor);
|
static float GetRigidDynamicActorMaxDepenetrationVelocity(void* actor);
|
||||||
|
|||||||
Reference in New Issue
Block a user