CtrEditor/Simulacion/simBase.cs

143 lines
5.6 KiB
C#

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 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
}
}
/// <summary>
/// ✅ NUEVO: Cambia la forma de un body existente, limpiando la forma anterior para evitar memory leaks
/// </summary>
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);
}
}
}