using BepuPhysics.Collidables; using BepuPhysics; using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using System.Text; using System.Threading.Tasks; namespace CtrEditor.Simulacion { public class simBase { public object WpfObject { get; set; } public string SimObjectType { get; set; } public BodyHandle BodyHandle { get; protected set; } public Simulation _simulation; protected bool _bodyCreated = false; // Bandera para saber si hemos creado un cuerpo protected SimulationManagerBEPU _simulationManager; // ✅ NUEVO: Referencia al manager // ✅ CORREGIDO: Restaurar factor de conversión correcto static public float SpeedConversionFactor { get => 60f; // Factor de conversión de velocidad interna a m/s } // Constantes para las posiciones Z de los objetos 3D public const float zPos_Transporte = 0f; // Z de la parte baja public const float zAltura_Transporte = 0.1f; // Altura del transporte sobre zPos public const float zPos_Guia = 0.05f; // Z de la parte baja public const float zAltura_Guia = 0.20f; // Altura de la guía sobre zPos public const float zPos_Barrera = zPos_Transporte + zAltura_Transporte + 0.05f; // Z de la parte baja - 0.1 Altura Botella public const float zPos_Descarte = 0.1f; // Z de la parte baja // Constantes para configuración public const float zPos_Curve = zPos_Transporte+ zAltura_Transporte; // Z de la parte alta de la curva public void RemoverBody() { try { // Solo intentar remover si realmente hemos creado un cuerpo antes if (_bodyCreated && _simulation != null && _simulation.Bodies != null && _simulation.Bodies.BodyExists(BodyHandle)) { _simulation.Bodies.Remove(BodyHandle); _bodyCreated = false; // Marcar como no creado después de remover //System.Diagnostics.Debug.WriteLine($"[simBase.RemoverBody] ✅ Body eliminado: {BodyHandle}"); } //else //{ // System.Diagnostics.Debug.WriteLine($"[simBase.RemoverBody] ⚠️ Body no existe o no creado: {BodyHandle}"); //} } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[simBase.RemoverBody] ❌ ERROR: {ex.Message}"); _bodyCreated = false; // Marcar como no creado en caso de error } } /// /// ✅ NUEVO: Cambia la forma de un body existente, limpiando la forma anterior para evitar memory leaks /// protected void ChangeBodyShape(TypedIndex newShapeIndex) { if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle)) { var bodyReference = _simulation.Bodies.GetBodyReference(BodyHandle); // ✅ CRÍTICO: Obtener la forma anterior para limpiarla del pool de shapes var oldShapeIndex = bodyReference.Collidable.Shape; // Cambiar a la nueva forma _simulation.Bodies.SetShape(BodyHandle, newShapeIndex); // ✅ CRÍTICO: Limpiar la forma anterior del pool para evitar memory leaks // Nota: Solo limpiar si es diferente (para evitar limpiar la forma que acabamos de asignar) if (oldShapeIndex.Packed != newShapeIndex.Packed) { try { _simulation.Shapes.RemoveAndDispose(oldShapeIndex, _simulation.BufferPool); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine($"[simBase] Warning: Could not dispose old shape: {ex.Message}"); // Continuar - esto no es crítico para la funcionalidad } } } } public static float Min(float Value, float Min = 0.01f) { return Math.Max(Value, Min); } public static float GradosARadianes(float grados) { return grados * (float)Math.PI / 180f; } public static float RadianesAGrados(float radianes) { return radianes * 180f / (float)Math.PI; } public void SetPosition(float x, float y, float z = 0) { CoordinateConverter.UpdateBepuBodyPosition(_simulation, BodyHandle, new Vector3(x, y, z)); } public void SetPosition(Vector2 wpfPosition) { // Mantener la coordenada Z actual para preservar la altura del objeto var currentBepuPosition = CoordinateConverter.GetBepuBodyPosition(_simulation, BodyHandle); var newBepuPosition = new Vector3(wpfPosition.X, CoordinateConverter.WpfYToBepuY(wpfPosition.Y), currentBepuPosition.Z); CoordinateConverter.UpdateBepuBodyPosition(_simulation, BodyHandle, newBepuPosition); } public void SetPosition(Vector3 bepuPosition) { CoordinateConverter.UpdateBepuBodyPosition(_simulation, BodyHandle, bepuPosition); } public Vector3 GetPosition() { return CoordinateConverter.GetBepuBodyPosition(_simulation, BodyHandle); } public void SetRotation(float wpfAngle) { CoordinateConverter.UpdateBepuBodyRotation(_simulation, BodyHandle, wpfAngle); } public float GetRotationZ() { return CoordinateConverter.GetWpfAngleFromBepuBody(_simulation, BodyHandle); } } }