diff --git a/Source/Editor/Tools/ClothPainting.cs b/Source/Editor/Tools/ClothPainting.cs index c831eb35d..226c7b49c 100644 --- a/Source/Editor/Tools/ClothPainting.cs +++ b/Source/Editor/Tools/ClothPainting.cs @@ -54,6 +54,13 @@ namespace FlaxEngine.Tools Owner.Gizmos.Active = Gizmo; } + + public override void Dispose() + { + Owner.Gizmos.Remove(Gizmo); + + base.Dispose(); + } } sealed class ClothPaintingGizmo : GizmoBase @@ -85,9 +92,19 @@ namespace FlaxEngine.Tools return; PaintEnd(); _cloth = cloth; - _clothParticles = cloth?.GetParticles(); + _clothParticles = null; _clothPaint = null; _hasHit = false; + if (cloth != null) + { + _clothParticles = cloth.GetParticles(); + if (_clothParticles == null || _clothParticles.Length == 0) + { + // Setup cloth to get proper particles (eg. if cloth is not on a scene like in Prefab Window) + cloth.Rebuild(); + _clothParticles = cloth.GetParticles(); + } + } } public void Fill() diff --git a/Source/Engine/Physics/Actors/Cloth.cpp b/Source/Engine/Physics/Actors/Cloth.cpp index 45e4df067..492dedc51 100644 --- a/Source/Engine/Physics/Actors/Cloth.cpp +++ b/Source/Engine/Physics/Actors/Cloth.cpp @@ -46,7 +46,10 @@ void Cloth::SetMesh(const ModelInstanceActor::MeshReference& value) _mesh = value; _mesh.Actor = nullptr; // Don't store this reference - Rebuild(); +#if WITH_CLOTH + if (_cloth) + Rebuild(); +#endif } void Cloth::SetForce(const ForceSettings& value) @@ -88,18 +91,15 @@ void Cloth::SetFabric(const FabricSettings& value) void Cloth::Rebuild() { #if WITH_CLOTH - if (_cloth) - { - // Remove old - if (IsDuringPlay()) - PhysicsBackend::RemoveCloth(GetPhysicsScene()->GetPhysicsScene(), _cloth); - DestroyCloth(); + // Remove old + if (IsDuringPlay()) + PhysicsBackend::RemoveCloth(GetPhysicsScene()->GetPhysicsScene(), _cloth); + DestroyCloth(); - // Create new - CreateCloth(); - if (IsDuringPlay()) - PhysicsBackend::AddCloth(GetPhysicsScene()->GetPhysicsScene(), _cloth); - } + // Create new + CreateCloth(); + if (IsDuringPlay()) + PhysicsBackend::AddCloth(GetPhysicsScene()->GetPhysicsScene(), _cloth); #endif } @@ -308,8 +308,10 @@ void Cloth::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) #endif // Refresh cloth when settings were changed - if (IsDuringPlay()) +#if WITH_CLOTH + if (_cloth) Rebuild(); +#endif } #if USE_EDITOR @@ -424,7 +426,6 @@ void Cloth::BeginPlay(SceneBeginData* data) #if WITH_CLOTH if (CreateCloth()) LOG(Error, "Failed to create cloth '{0}'", GetNamePath()); - #endif Actor::BeginPlay(data); @@ -434,10 +435,7 @@ void Cloth::EndPlay() { Actor::EndPlay(); -#if WITH_CLOTH - if (_cloth) - DestroyCloth(); -#endif + DestroyCloth(); } void Cloth::OnEnable() @@ -466,11 +464,21 @@ void Cloth::OnDisable() #endif } +void Cloth::OnDeleteObject() +{ + DestroyCloth(); + + Actor::OnDeleteObject(); +} + void Cloth::OnParentChanged() { Actor::OnParentChanged(); - Rebuild(); +#if WITH_CLOTH + if (_cloth) + Rebuild(); +#endif } void Cloth::OnTransformChanged() @@ -588,8 +596,11 @@ void Cloth::DestroyCloth() _meshDeformation->RemoveDeformer(_mesh.LODIndex, _mesh.MeshIndex, MeshBufferType::Vertex1, deformer); _meshDeformation = nullptr; } - PhysicsBackend::DestroyCloth(_cloth); - _cloth = nullptr; + if (_cloth) + { + PhysicsBackend::DestroyCloth(_cloth); + _cloth = nullptr; + } #endif } diff --git a/Source/Engine/Physics/Actors/Cloth.h b/Source/Engine/Physics/Actors/Cloth.h index 9a9f69577..2f39f8015 100644 --- a/Source/Engine/Physics/Actors/Cloth.h +++ b/Source/Engine/Physics/Actors/Cloth.h @@ -288,7 +288,7 @@ public: public: /// - /// Recreates the cloth by removing current instance data and creating a new physical cloth object. Does nothing if cloth was not created (eg. no parent mesh). + /// Recreates the cloth by removing current instance data and creating a new physical cloth object. /// API_FUNCTION() void Rebuild(); @@ -332,6 +332,7 @@ protected: void EndPlay() override; void OnEnable() override; void OnDisable() override; + void OnDeleteObject() override; void OnParentChanged() override; void OnTransformChanged() override; void OnPhysicsSceneChanged(PhysicsScene* previous) override;