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)
|
||||
{
|
||||
return GetBox().Intersects(ray, distance, normal);
|
||||
return _box.Intersects(ray, distance, 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"
|
||||
|
||||
RigidBody::RigidBody(const SpawnParams& params)
|
||||
: PhysicsActor(params)
|
||||
: Actor(params)
|
||||
, _actor(nullptr)
|
||||
, _cachedScale(1.0f)
|
||||
, _mass(1.0f)
|
||||
, _linearDamping(0.01f)
|
||||
, _angularDamping(0.05f)
|
||||
@@ -24,6 +25,7 @@ RigidBody::RigidBody(const SpawnParams& params)
|
||||
, _startAwake(true)
|
||||
, _updateMassWhenScaleChanges(false)
|
||||
, _overrideMass(false)
|
||||
, _isUpdatingTransform(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -224,13 +226,13 @@ bool RigidBody::IsSleeping() const
|
||||
void RigidBody::Sleep() const
|
||||
{
|
||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||
PhysicsBackend::GetRigidActorSleep(_actor);
|
||||
PhysicsBackend::RigidDynamicActorSleep(_actor);
|
||||
}
|
||||
|
||||
void RigidBody::WakeUp() const
|
||||
{
|
||||
if (_actor && GetEnableSimulation() && !GetIsKinematic() && IsActiveInHierarchy())
|
||||
PhysicsBackend::GetRigidDynamicActorWakeUp(_actor);
|
||||
PhysicsBackend::RigidDynamicActorWakeUp(_actor);
|
||||
}
|
||||
|
||||
void RigidBody::UpdateMass()
|
||||
@@ -323,6 +325,16 @@ void RigidBody::OnColliderChanged(Collider* c)
|
||||
// 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()
|
||||
{
|
||||
const Vector3 scale = GetScale();
|
||||
@@ -339,7 +351,7 @@ void RigidBody::UpdateScale()
|
||||
void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::Serialize(stream, otherObj);
|
||||
Actor::Serialize(stream, otherObj);
|
||||
|
||||
SERIALIZE_GET_OTHER_OBJ(RigidBody);
|
||||
|
||||
@@ -364,7 +376,7 @@ void RigidBody::Serialize(SerializeStream& stream, const void* otherObj)
|
||||
void RigidBody::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::Deserialize(stream, modifier);
|
||||
Actor::Deserialize(stream, modifier);
|
||||
|
||||
DESERIALIZE_BIT_MEMBER(OverrideMass, _overrideMass);
|
||||
DESERIALIZE_MEMBER(Mass, _mass);
|
||||
@@ -389,6 +401,26 @@ void* RigidBody::GetPhysicsActor() const
|
||||
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)
|
||||
{
|
||||
// Create rigid body
|
||||
@@ -441,13 +473,13 @@ void RigidBody::BeginPlay(SceneBeginData* data)
|
||||
UpdateBounds();
|
||||
|
||||
// Base
|
||||
PhysicsActor::BeginPlay(data);
|
||||
Actor::BeginPlay(data);
|
||||
}
|
||||
|
||||
void RigidBody::EndPlay()
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::EndPlay();
|
||||
Actor::EndPlay();
|
||||
|
||||
if (_actor)
|
||||
{
|
||||
@@ -462,7 +494,7 @@ void RigidBody::EndPlay()
|
||||
void RigidBody::OnActiveInTreeChanged()
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::OnActiveInTreeChanged();
|
||||
Actor::OnActiveInTreeChanged();
|
||||
|
||||
if (_actor)
|
||||
{
|
||||
@@ -480,23 +512,18 @@ void RigidBody::OnActiveInTreeChanged()
|
||||
|
||||
void RigidBody::OnTransformChanged()
|
||||
{
|
||||
// Base
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
// Update physics is not during physics state synchronization
|
||||
if (!_isUpdatingTransform && _actor)
|
||||
{
|
||||
// Base (skip PhysicsActor call to optimize)
|
||||
Actor::OnTransformChanged();
|
||||
|
||||
const bool kinematic = GetIsKinematic() && GetEnableSimulation();
|
||||
PhysicsBackend::SetRigidActorPose(_actor, _transform.Translation, _transform.Orientation, kinematic, true);
|
||||
|
||||
UpdateScale();
|
||||
UpdateBounds();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Base
|
||||
PhysicsActor::OnTransformChanged();
|
||||
}
|
||||
|
||||
UpdateBounds();
|
||||
}
|
||||
|
||||
void RigidBody::OnPhysicsSceneChanged(PhysicsScene* previous)
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
#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"
|
||||
|
||||
class PhysicsColliderActor;
|
||||
@@ -11,8 +13,8 @@ class Collider;
|
||||
/// <summary>
|
||||
/// Physics simulation driven object.
|
||||
/// </summary>
|
||||
/// <seealso cref="PhysicsActor" />
|
||||
API_CLASS() class FLAXENGINE_API RigidBody : public PhysicsActor
|
||||
/// <seealso cref="Actor" />
|
||||
API_CLASS() class FLAXENGINE_API RigidBody : public Actor, public IPhysicsActor
|
||||
{
|
||||
DECLARE_SCENE_OBJECT(RigidBody);
|
||||
protected:
|
||||
@@ -35,6 +37,7 @@ protected:
|
||||
int32 _startAwake : 1;
|
||||
int32 _updateMassWhenScaleChanges : 1;
|
||||
int32 _overrideMass : 1;
|
||||
int32 _isUpdatingTransform : 1;
|
||||
|
||||
public:
|
||||
|
||||
@@ -537,7 +540,10 @@ public:
|
||||
// Called when collider gets detached from this rigidbody or activated/deactivated. Used to update rigidbody mass.
|
||||
virtual void OnColliderChanged(Collider* c);
|
||||
|
||||
protected:
|
||||
/// <summary>
|
||||
/// Updates the bounding box.
|
||||
/// </summary>
|
||||
void UpdateBounds();
|
||||
|
||||
/// <summary>
|
||||
/// Updates the rigidbody scale dependent properties like mass (may be modified when actor transformation changes).
|
||||
@@ -546,14 +552,17 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
// [PhysicsActor]
|
||||
// [Actor]
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override;
|
||||
|
||||
// [IPhysicsActor]
|
||||
void* GetPhysicsActor() const override;
|
||||
void OnActiveTransformChanged() override;
|
||||
|
||||
protected:
|
||||
|
||||
// [PhysicsActor]
|
||||
// [Actor]
|
||||
void BeginPlay(SceneBeginData* data) override;
|
||||
void EndPlay() override;
|
||||
void OnActiveInTreeChanged() override;
|
||||
|
||||
@@ -1607,6 +1607,12 @@ void PhysicsBackend::GetActorBounds(void* actor, BoundingBox& bounds)
|
||||
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)
|
||||
{
|
||||
const PxTransform trans(C2P(position), C2P(orientation));
|
||||
@@ -1749,13 +1755,13 @@ bool PhysicsBackend::GetRigidDynamicActorIsSleeping(void* actor)
|
||||
return actorPhysX->isSleeping();
|
||||
}
|
||||
|
||||
void PhysicsBackend::GetRigidActorSleep(void* actor)
|
||||
void PhysicsBackend::RigidDynamicActorSleep(void* actor)
|
||||
{
|
||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||
actorPhysX->putToSleep();
|
||||
}
|
||||
|
||||
void PhysicsBackend::GetRigidDynamicActorWakeUp(void* actor)
|
||||
void PhysicsBackend::RigidDynamicActorWakeUp(void* actor)
|
||||
{
|
||||
auto actorPhysX = (PxRigidDynamic*)actor;
|
||||
actorPhysX->wakeUp();
|
||||
|
||||
@@ -131,6 +131,7 @@ public:
|
||||
static ActorFlags GetActorFlags(void* actor);
|
||||
static void SetActorFlags(void* actor, ActorFlags value);
|
||||
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* CreateRigidStaticActor(IPhysicsActor* actor, const Vector3& position, const Quaternion& orientation);
|
||||
static RigidDynamicFlags GetRigidDynamicActorFlags(void* actor);
|
||||
@@ -148,8 +149,8 @@ public:
|
||||
static Vector3 GetRigidDynamicActorCenterOfMass(void* actor);
|
||||
static void SetRigidDynamicActorCenterOfMassOffset(void* actor, const Vector3& value);
|
||||
static bool GetRigidDynamicActorIsSleeping(void* actor);
|
||||
static void GetRigidActorSleep(void* actor);
|
||||
static void GetRigidDynamicActorWakeUp(void* actor);
|
||||
static void RigidDynamicActorSleep(void* actor);
|
||||
static void RigidDynamicActorWakeUp(void* actor);
|
||||
static float GetRigidDynamicActorSleepThreshold(void* actor);
|
||||
static void SetRigidDynamicActorSleepThreshold(void* actor, float value);
|
||||
static float GetRigidDynamicActorMaxDepenetrationVelocity(void* actor);
|
||||
|
||||
Reference in New Issue
Block a user