Fix invalid Rigidbody bounds if it has no shapes attached
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user