Se eliminaron archivos de documentación innecesarios en el proyecto y se realizaron ajustes en la visibilidad de métodos en la clase osBase, cambiando de privado a protegido. Se implementó un nuevo método para verificar las dimensiones de los descartes y se mejoró la lógica de actualización de geometrías en ucDescarte y ucGuia, utilizando un sistema inteligente para optimizar el rendimiento. Además, se corrigieron errores en la conversión de coordenadas y se restauró el factor de conversión de velocidad en BEPU.
This commit is contained in:
parent
fd215bc677
commit
e38adc9f56
|
@ -35,6 +35,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Documentation\BEPU Forces.cs" />
|
||||
<Compile Remove="Documentation\PlantillaEstandarizacion.cs" />
|
||||
<Compile Remove="ObjetosSim\ucTransporteCurva.xaml.cs" />
|
||||
</ItemGroup>
|
||||
|
@ -84,6 +85,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="Documentation\BEPU Forces.cs" />
|
||||
<None Include="Documentation\PlantillaEstandarizacion.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -41,7 +41,7 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
partial void OnDiametroChanged(float value)
|
||||
{
|
||||
SimGeometria?.SetDiameter(Diametro);
|
||||
ActualizarGeometrias();
|
||||
}
|
||||
|
||||
public Vector2 GetCentro()
|
||||
|
@ -73,8 +73,15 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
if (SimGeometria != null)
|
||||
{
|
||||
// ✅ SISTEMA INTELIGENTE: Solo recrear si el diámetro cambió
|
||||
if (HasDiscardDimensionsChanged(SimGeometria, Diametro))
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[osDescarte] Recreando descarte por cambio de diámetro");
|
||||
SimGeometria.SetDiameter(Diametro);
|
||||
SimGeometria.SetPosition(GetCentro());
|
||||
}
|
||||
|
||||
// ✅ USAR MÉTODO COORDINATECONVERTER
|
||||
SimGeometria.UpdateFromWpfCenter(GetCentro());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -37,16 +37,30 @@ namespace CtrEditor.ObjetosSim
|
|||
[property: Name("Grosor de la Guía")]
|
||||
public float altoGuia;
|
||||
|
||||
|
||||
|
||||
private void ActualizarGeometrias()
|
||||
{
|
||||
if (_visualRepresentation is ucGuia uc)
|
||||
if (_visualRepresentation is ucGuia uc && SimGeometria != null)
|
||||
{
|
||||
// Actualizar las propiedades del objeto de simulación
|
||||
if (SimGeometria != null)
|
||||
var topLeft = new Vector2(Left, Top);
|
||||
|
||||
// ✅ SISTEMA INTELIGENTE: Solo recrear si las dimensiones han cambiado
|
||||
if (HasGuideDimensionsChanged(SimGeometria, Ancho, AltoGuia))
|
||||
{
|
||||
SimGeometria.UpdateProperties(Ancho, AltoGuia, Angulo);
|
||||
System.Diagnostics.Debug.WriteLine($"[osGuia] Recreando guía por cambio de dimensiones: {Ancho}x{AltoGuia}");
|
||||
|
||||
// ✅ RECREAR COMPLETAMENTE: Las dimensiones cambiaron
|
||||
SimGeometria.Create(Ancho, AltoGuia, topLeft, Angulo);
|
||||
SimGeometria.SetDimensions(Ancho, AltoGuia);
|
||||
}
|
||||
else
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[osGuia] Solo actualizando posición/rotación: Left={Left}, Top={Top}, Angulo={Angulo}");
|
||||
|
||||
// ✅ SOLO ACTUALIZAR POSICIÓN/ROTACIÓN: Usar dimensiones reales para conversión correcta
|
||||
SimGeometria.UpdateFromWpfParameters(topLeft, Angulo, Ancho, AltoGuia);
|
||||
}
|
||||
UpdateOrCreateLine(SimGeometria, uc.Guia);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -258,15 +258,15 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Actualizar posición en BEPU cuando cambia la posición del objeto
|
||||
/// ✅ CORREGIDO: Actualizar posición en BEPU usando métodos de conversión apropiados
|
||||
/// </summary>
|
||||
private void ActualizarPosicionBEPU()
|
||||
{
|
||||
if (Simulation_TransporteCurvaGuias != null)
|
||||
{
|
||||
// Recrear la curva con nueva posición usando el mismo patrón que ucTransporteCurva
|
||||
// ✅ USAR MÉTODOS DE COORDINATECONVERTER
|
||||
var topLeft = new Vector2(Left, Top);
|
||||
Simulation_TransporteCurvaGuias.Create(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados, topLeft, 0);
|
||||
Simulation_TransporteCurvaGuias.UpdateFromWpfParameters(topLeft, 0f, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
|
||||
|
||||
// Recrear las guías en la nueva posición
|
||||
ActualizarGuiasCurvas();
|
||||
|
@ -286,7 +286,12 @@ namespace CtrEditor.ObjetosSim
|
|||
{
|
||||
if (_visualRepresentation is ucTransporteCurvaGuias uc)
|
||||
{
|
||||
Simulation_TransporteCurvaGuias?.UpdateCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
|
||||
// ✅ USAR MÉTODO DE COORDINATECONVERTER PARA ACTUALIZACIÓN COMPLETA
|
||||
if (Simulation_TransporteCurvaGuias != null)
|
||||
{
|
||||
var topLeft = new Vector2(Left, Top);
|
||||
Simulation_TransporteCurvaGuias.UpdateFromWpfParameters(topLeft, 0f, RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados);
|
||||
}
|
||||
ActualizarGuiasCurvas();
|
||||
SetSpeed();
|
||||
}
|
||||
|
@ -327,7 +332,7 @@ namespace CtrEditor.ObjetosSim
|
|||
if (radioGuiaInferior < 0.01f)
|
||||
radioGuiaInferior = 0.01f;
|
||||
|
||||
// Convertir ángulos a radianes
|
||||
// ✅ CORREGIDO: Convertir ángulos a radianes usando método estándar
|
||||
float anguloInicioRad = simBase.GradosARadianes(Angulo);
|
||||
float anguloFinalRad = simBase.GradosARadianes(AnguloFinal);
|
||||
float rangoAngular = anguloFinalRad - anguloInicioRad;
|
||||
|
@ -390,7 +395,7 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Método helper para crear una guía desde dos puntos
|
||||
/// ✅ CORREGIDO: Método helper para crear una guía desde dos puntos usando conversiones apropiadas
|
||||
/// Convierte dos puntos Vector2 a los parámetros requeridos por AddLine
|
||||
/// </summary>
|
||||
private simGuia CrearGuiaDesdeDosPuntos(Vector2 punto1, Vector2 punto2)
|
||||
|
@ -404,10 +409,10 @@ namespace CtrEditor.ObjetosSim
|
|||
if (longitud < 0.001f) // Evitar líneas de longitud cero
|
||||
return null;
|
||||
|
||||
// Calcular el ángulo de la línea
|
||||
// ✅ CORREGIDO: Calcular el ángulo de la línea correctamente para WPF
|
||||
float angulo = (float)Math.Atan2(direccion.Y, direccion.X) * 180f / (float)Math.PI;
|
||||
|
||||
// Usar punto1 como topLeft y la longitud como width
|
||||
// ✅ USAR punto1 como topLeft - simulationManager.AddLine ya maneja las conversiones WPF->BEPU
|
||||
return simulationManager.AddLine(longitud, GrosorGuias, punto1, angulo);
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
@ -532,7 +537,7 @@ namespace CtrEditor.ObjetosSim
|
|||
|
||||
if (_visualRepresentation is ucTransporteCurvaGuias uc)
|
||||
{
|
||||
// ✅ CORRIGIDO: Usar simulationManager?.AddCurve con todos los parámetros requeridos
|
||||
// ✅ CORREGIDO: Usar simulationManager?.AddCurve con conversión WPF correcta
|
||||
var topLeft = new Vector2(Left, Top);
|
||||
Simulation_TransporteCurvaGuias = simulationManager?.AddCurve(RadioInterno, RadioExterno, Angulo, Angulo + Arco_en_grados, topLeft, 0);
|
||||
CrearGuiasCurvas(); // Crear las guías curvas
|
||||
|
|
|
@ -1747,7 +1747,7 @@ namespace CtrEditor.ObjetosSim
|
|||
/// <summary>
|
||||
/// Verifica si las dimensiones de un transporte han cambiado
|
||||
/// </summary>
|
||||
private bool HasTransportDimensionsChanged(simTransporte transport, float newWidth, float newHeight)
|
||||
protected bool HasTransportDimensionsChanged(simTransporte transport, float newWidth, float newHeight)
|
||||
{
|
||||
if (transport == null) return true;
|
||||
|
||||
|
@ -1780,7 +1780,7 @@ namespace CtrEditor.ObjetosSim
|
|||
/// <summary>
|
||||
/// Verifica si las dimensiones de una barrera han cambiado
|
||||
/// </summary>
|
||||
private bool HasBarrierDimensionsChanged(simBarrera barrier, float newWidth, float newHeight)
|
||||
protected bool HasBarrierDimensionsChanged(simBarrera barrier, float newWidth, float newHeight)
|
||||
{
|
||||
if (barrier == null) return true;
|
||||
|
||||
|
@ -1813,7 +1813,7 @@ namespace CtrEditor.ObjetosSim
|
|||
/// <summary>
|
||||
/// Verifica si las dimensiones de una guía han cambiado
|
||||
/// </summary>
|
||||
private bool HasGuideDimensionsChanged(simGuia guide, float newWidth, float newHeight)
|
||||
protected bool HasGuideDimensionsChanged(simGuia guide, float newWidth, float newHeight)
|
||||
{
|
||||
if (guide == null) return true;
|
||||
|
||||
|
@ -1843,6 +1843,41 @@ namespace CtrEditor.ObjetosSim
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO - Sistema inteligente de verificación de dimensiones de descartes
|
||||
/// Verifica si el diámetro de un descarte ha cambiado
|
||||
/// </summary>
|
||||
protected bool HasDiscardDimensionsChanged(simDescarte discard, float newDiameter)
|
||||
{
|
||||
if (discard == null) return true;
|
||||
|
||||
var newDimensions = new SimObjectDimensions
|
||||
{
|
||||
Width = newDiameter,
|
||||
Height = newDiameter,
|
||||
Radius = newDiameter / 2f,
|
||||
ObjectType = 4 // Tipo 4 = Descarte
|
||||
};
|
||||
|
||||
if (_lastKnownDimensions.TryGetValue(discard, out var lastDimensions))
|
||||
{
|
||||
bool changed = !newDimensions.Equals(lastDimensions);
|
||||
if (changed)
|
||||
{
|
||||
_lastKnownDimensions[discard] = newDimensions;
|
||||
System.Diagnostics.Debug.WriteLine($"[Dimensions] Discard dimensions CHANGED: Ø{newDiameter}");
|
||||
}
|
||||
return changed;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Primera vez - consideramos como cambio
|
||||
_lastKnownDimensions[discard] = newDimensions;
|
||||
System.Diagnostics.Debug.WriteLine($"[Dimensions] Discard first time: Ø{newDiameter}");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Limpia las dimensiones almacenadas para un objeto específico
|
||||
/// </summary>
|
||||
|
|
|
@ -231,8 +231,8 @@ namespace CtrEditor.Simulacion
|
|||
public Simulation _simulation;
|
||||
protected bool _bodyCreated = false; // Bandera para saber si hemos creado un cuerpo
|
||||
|
||||
// ✅ NUEVA CONSTANTE - unificar conversión de velocidad
|
||||
public const float SPEED_CONVERSION_FACTOR = 1f; //18.5f; // Factor de conversión de velocidad interna a m/s
|
||||
// ✅ CORREGIDO: Restaurar factor de conversión correcto
|
||||
public const float SPEED_CONVERSION_FACTOR = 1/2f; // Factor de conversión de velocidad interna a m/s - Para LinearAxisMotor es 0.5f
|
||||
|
||||
// Constantes para las posiciones Z de los objetos 3D
|
||||
public const float zPos_Transporte = 0f; // Z de la parte baja
|
||||
|
@ -390,6 +390,20 @@ namespace CtrEditor.Simulacion
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ SOBRESCRITO: SetRotation que actualiza automáticamente las propiedades cacheadas
|
||||
/// </summary>
|
||||
public new void SetRotation(float wpfAngle)
|
||||
{
|
||||
base.SetRotation(wpfAngle);
|
||||
|
||||
// ✅ CRÍTICO: Actualizar propiedades cacheadas después del cambio de rotación
|
||||
UpdateCachedProperties();
|
||||
|
||||
// ✅ CRÍTICO: Disparar evento para actualizar motores activos con nueva dirección
|
||||
OnSpeedChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public new void SetPosition(float x, float y, float z = 0)
|
||||
{
|
||||
base.SetPosition(x, y, z);
|
||||
|
@ -398,7 +412,7 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza posición desde Top-Left WPF con dimensiones y ángulo actuales
|
||||
/// </summary>
|
||||
public void SetPositionFromWpfTopLeft(Vector2 wpfTopLeft)
|
||||
internal void SetPositionFromWpfTopLeft(Vector2 wpfTopLeft)
|
||||
{
|
||||
var currentWpfAngle = GetRotationZ(); // Ya usa CoordinateConverter
|
||||
var zPosition = GetPosition().Z; // Mantener Z actual
|
||||
|
@ -409,7 +423,7 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Obtiene Top-Left WPF desde la posición actual
|
||||
/// </summary>
|
||||
public Vector2 GetWpfTopLeft()
|
||||
internal Vector2 GetWpfTopLeft()
|
||||
{
|
||||
var bepuCenter = GetPosition();
|
||||
var wpfAngle = GetRotationZ(); // Ya usa CoordinateConverter
|
||||
|
@ -419,22 +433,53 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza tanto posición como rotación desde parámetros WPF
|
||||
/// </summary>
|
||||
public void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle)
|
||||
internal void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle)
|
||||
{
|
||||
var zPosition = GetPosition().Z; // Mantener Z actual
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, Width, Height, wpfAngle, zPosition);
|
||||
CoordinateConverter.UpdateBepuBodyPose(_simulation, BodyHandle, bepuCenter, wpfAngle);
|
||||
|
||||
// Actualizar propiedades cacheadas después del cambio
|
||||
// ✅ CRÍTICO: Actualizar propiedades cacheadas después del cambio de orientación
|
||||
UpdateCachedProperties();
|
||||
|
||||
// ✅ CRÍTICO: Disparar evento para actualizar motores activos con nueva dirección
|
||||
OnSpeedChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
// ✅ NUEVO MÉTODO - actualizar propiedades cacheadas
|
||||
public void UpdateCachedProperties()
|
||||
internal void UpdateCachedProperties()
|
||||
{
|
||||
// Calcular dirección basada en rotación actual
|
||||
var angle = GetRotationZ();
|
||||
DirectionVector = new Vector3((float)Math.Cos(angle), (float)Math.Sin(angle), 0);
|
||||
// ✅ CORREGIDO: La dirección siempre es UnitX rotado por el ángulo del transporte
|
||||
// NO depende de las dimensiones (Width >= Height) sino solo de la rotación
|
||||
if (_simulation != null && _simulation.Bodies.BodyExists(BodyHandle))
|
||||
{
|
||||
var bodyReference = _simulation.Bodies.GetBodyReference(BodyHandle);
|
||||
var bepuQuaternion = bodyReference.Pose.Orientation;
|
||||
|
||||
// ✅ SIEMPRE usar UnitX y aplicar la rotación
|
||||
DirectionVector = Vector3.Transform(Vector3.UnitX, bepuQuaternion);
|
||||
|
||||
// 🔍 DEBUG: Agregar información detallada
|
||||
var wpfAngle = GetRotationZ();
|
||||
System.Diagnostics.Debug.WriteLine($"[UpdateCached] WPF Angle: {wpfAngle}°, DirectionVector: {DirectionVector}, Length: {DirectionVector.Length()}");
|
||||
}
|
||||
else
|
||||
{
|
||||
// ✅ CORREGIDO: Aplicar conversión de coordenadas WPF→BEPU en el vector
|
||||
var wpfAngle = GetRotationZ(); // Ángulo WPF en grados
|
||||
var wpfAngleRadians = GradosARadianes(wpfAngle);
|
||||
|
||||
// Calcular el vector en coordenadas WPF
|
||||
var wpfX = (float)Math.Cos(wpfAngleRadians);
|
||||
var wpfY = (float)Math.Sin(wpfAngleRadians);
|
||||
|
||||
// ✅ APLICAR CONVERSIÓN Y: En WPF Y+ es abajo, en BEPU Y+ es arriba
|
||||
DirectionVector = new Vector3(wpfX, -wpfY, 0); // Invertir Y para conversión WPF→BEPU
|
||||
|
||||
// 🔍 DEBUG: Agregar información detallada
|
||||
System.Diagnostics.Debug.WriteLine($"[UpdateCached-Fallback] WPF Angle: {wpfAngle}°, WPF Vector: ({wpfX:F3}, {wpfY:F3}), BEPU DirectionVector: {DirectionVector}, Length: {DirectionVector.Length()}");
|
||||
}
|
||||
|
||||
SpeedMetersPerSecond = Speed / SPEED_CONVERSION_FACTOR;
|
||||
}
|
||||
|
||||
|
@ -485,6 +530,12 @@ namespace CtrEditor.Simulacion
|
|||
var shapeIndex = _simulation.Shapes.Add(box);
|
||||
ChangeBodyShape(shapeIndex);
|
||||
}
|
||||
|
||||
// ✅ CRÍTICO: Actualizar propiedades cacheadas después del cambio de dimensiones
|
||||
UpdateCachedProperties();
|
||||
|
||||
// ✅ CRÍTICO: Disparar evento para actualizar motores activos con nueva dirección
|
||||
OnSpeedChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
public void Create(float width, float height, Vector2 wpfTopLeft, float wpfAngle = 0)
|
||||
|
@ -549,6 +600,9 @@ namespace CtrEditor.Simulacion
|
|||
|
||||
BodyHandle = _simulation.Bodies.Add(bodyDescription);
|
||||
_bodyCreated = true; // Marcar que hemos creado un cuerpo
|
||||
|
||||
// ✅ CRÍTICO: Actualizar propiedades cacheadas después de crear el body
|
||||
UpdateCachedProperties();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -598,7 +652,7 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza posición desde Top-Left WPF con dimensiones y ángulo actuales
|
||||
/// </summary>
|
||||
public void SetPositionFromWpfTopLeft(Vector2 wpfTopLeft)
|
||||
internal void SetPositionFromWpfTopLeft(Vector2 wpfTopLeft)
|
||||
{
|
||||
var currentWpfAngle = GetRotationZ(); // Ya usa CoordinateConverter
|
||||
var zPosition = GetPosition().Z; // Mantener Z actual
|
||||
|
@ -609,7 +663,7 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Obtiene Top-Left WPF desde la posición actual
|
||||
/// </summary>
|
||||
public Vector2 GetWpfTopLeft()
|
||||
internal Vector2 GetWpfTopLeft()
|
||||
{
|
||||
var bepuCenter = GetPosition();
|
||||
var wpfAngle = GetRotationZ(); // Ya usa CoordinateConverter
|
||||
|
@ -619,7 +673,7 @@ namespace CtrEditor.Simulacion
|
|||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza tanto posición como rotación desde parámetros WPF
|
||||
/// </summary>
|
||||
public void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle)
|
||||
internal void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle)
|
||||
{
|
||||
var zPosition = GetPosition().Z; // Mantener Z actual
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, Width, Height, wpfAngle, zPosition);
|
||||
|
@ -735,20 +789,39 @@ namespace CtrEditor.Simulacion
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO - Actualiza solo la posición sin recrear el objeto usando CoordinateConverter
|
||||
/// ✅ CORREGIDO - Actualiza solo la posición sin recrear el objeto usando CoordinateConverter
|
||||
/// Requiere las dimensiones reales para conversión correcta Top-Left → Center
|
||||
/// </summary>
|
||||
public void SetPosition(Vector2 wpfTopLeft, float wpfAngle = 0)
|
||||
public void SetPosition(Vector2 wpfTopLeft, float wpfAngle, float actualWidth, float actualHeight)
|
||||
{
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada con dimensiones reales
|
||||
var zPosition = zAltura_Guia / 2 + zPos_Guia;
|
||||
// Usar las dimensiones actuales de la guía
|
||||
var width = GuideThickness; // Para guías, el ancho puede ser derivado del espesor
|
||||
var height = GuideThickness;
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, width, height, wpfAngle, zPosition);
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, actualWidth, actualHeight, wpfAngle, zPosition);
|
||||
|
||||
// Actualizar posición y rotación simultáneamente
|
||||
CoordinateConverter.UpdateBepuBodyPose(_simulation, BodyHandle, bepuCenter, wpfAngle);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza tanto posición como rotación desde parámetros WPF (sobrecarga para compatibilidad)
|
||||
/// </summary>
|
||||
internal void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle, float width, float height)
|
||||
{
|
||||
// Usar el método SetPosition con dimensiones correctas
|
||||
SetPosition(wpfTopLeft, wpfAngle, width, height);
|
||||
|
||||
// Actualizar propiedades internas
|
||||
GuideThickness = height;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ LEGACY - Mantener compatibilidad con versión anterior (usar dimensiones almacenadas)
|
||||
/// </summary>
|
||||
public void SetPosition(Vector2 wpfTopLeft, float wpfAngle = 0)
|
||||
{
|
||||
// Fallback: usar GuideThickness como aproximación si no se proporcionan dimensiones
|
||||
SetPosition(wpfTopLeft, wpfAngle, GuideThickness * 10f, GuideThickness);
|
||||
}
|
||||
}
|
||||
|
||||
public class simBotella : simBase
|
||||
|
@ -785,9 +858,8 @@ namespace CtrEditor.Simulacion
|
|||
_neckRadius = neckRadius;
|
||||
ListOnTransports = new List<simBase>();
|
||||
|
||||
// Convertir Vector2 a Vector3 con Z=0.2 (altura estándar para botellas)
|
||||
// Invertir Y para convertir de WPF (Y hacia abajo) a 3D (Y hacia arriba)
|
||||
var position3D = new Vector3(position.X, -position.Y, Radius + zPos_Transporte + zAltura_Transporte);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
var position3D = new Vector3(position.X, CoordinateConverter.WpfYToBepuY(position.Y), Radius + zPos_Transporte + zAltura_Transporte);
|
||||
Create(position3D);
|
||||
}
|
||||
|
||||
|
@ -808,14 +880,14 @@ namespace CtrEditor.Simulacion
|
|||
{
|
||||
get
|
||||
{
|
||||
// Invertir Y de vuelta para convertir de 3D (Y hacia arriba) a WPF (Y hacia abajo)
|
||||
return -GetPosition().Y;
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
return CoordinateConverter.BepuYToWpfY(GetPosition().Y);
|
||||
}
|
||||
set
|
||||
{
|
||||
var pos = GetPosition();
|
||||
// Invertir Y para convertir de WPF (Y hacia abajo) a 3D (Y hacia arriba)
|
||||
SetPosition(pos.X, -value, pos.Z);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
SetPosition(pos.X, CoordinateConverter.WpfYToBepuY(value), pos.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -824,15 +896,15 @@ namespace CtrEditor.Simulacion
|
|||
get
|
||||
{
|
||||
var pos3D = GetPosition();
|
||||
// Invertir Y de vuelta para convertir de 3D (Y hacia arriba) a WPF (Y hacia abajo)
|
||||
return new Vector2(pos3D.X, -pos3D.Y);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
return CoordinateConverter.BepuVector3ToWpfVector2(pos3D);
|
||||
}
|
||||
set
|
||||
{
|
||||
// Mantener la Z actual, solo cambiar X, Y
|
||||
var currentPos = GetPosition();
|
||||
// Invertir Y para convertir de WPF (Y hacia abajo) a 3D (Y hacia arriba)
|
||||
SetPosition(value.X, -value.Y, currentPos.Z);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
SetPosition(value.X, CoordinateConverter.WpfYToBepuY(value.Y), currentPos.Z);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1022,8 +1094,8 @@ namespace CtrEditor.Simulacion
|
|||
|
||||
public float InnerRadius => _innerRadius;
|
||||
public float OuterRadius => _outerRadius;
|
||||
public float StartAngle => _startAngle;
|
||||
public float EndAngle => _endAngle;
|
||||
public float StartAngle => RadianesAGrados(_startAngle); // Convertir de radianes BEPU internos a grados WPF
|
||||
public float EndAngle => RadianesAGrados(_endAngle); // Convertir de radianes BEPU internos a grados WPF
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Expone los triángulos originales para visualización debug
|
||||
|
@ -1037,9 +1109,9 @@ namespace CtrEditor.Simulacion
|
|||
_simulationManager = simulationManager; // ✅ NUEVA REFERENCIA
|
||||
_innerRadius = innerRadius;
|
||||
_outerRadius = outerRadius;
|
||||
// ✅ SENTIDO HORARIO: Convertir ángulos para que vayan en sentido horario
|
||||
_startAngle = GradosARadianes(startAngle);
|
||||
_endAngle = GradosARadianes(endAngle);
|
||||
// ✅ CORREGIDO: Usar conversión WPF a BEPU y luego a radianes para consistencia
|
||||
_startAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(startAngle));
|
||||
_endAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(endAngle));
|
||||
_triangleBodyHandles = new List<BodyHandle>();
|
||||
_originalTriangles = new List<List<Vector3>>(); // ✅ NUEVO: Inicializar lista de triángulos
|
||||
|
||||
|
@ -1059,14 +1131,57 @@ namespace CtrEditor.Simulacion
|
|||
{
|
||||
_innerRadius = innerRadius;
|
||||
_outerRadius = outerRadius;
|
||||
_startAngle = GradosARadianes(startAngle);
|
||||
_endAngle = GradosARadianes(endAngle);
|
||||
// ✅ CORREGIDO: Usar conversión WPF a BEPU consistente
|
||||
_startAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(startAngle));
|
||||
_endAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(endAngle));
|
||||
|
||||
// Recrear la curva con nuevos parámetros manteniendo posición actual
|
||||
var currentPosition = GetPosition();
|
||||
Create(currentPosition);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza tanto posición como rotación desde parámetros WPF
|
||||
/// </summary>
|
||||
internal void UpdateFromWpfParameters(Vector2 wpfTopLeft, float wpfAngle, float innerRadius, float outerRadius, float startAngle, float endAngle)
|
||||
{
|
||||
// Actualizar parámetros de la curva
|
||||
_innerRadius = innerRadius;
|
||||
_outerRadius = outerRadius;
|
||||
// ✅ CORREGIDO: Usar conversión WPF a BEPU consistente
|
||||
_startAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(startAngle));
|
||||
_endAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(endAngle));
|
||||
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
var curveSize = outerRadius * 2f;
|
||||
var zPosition = zAltura_Curve / 2f + zPos_Curve;
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, curveSize, curveSize, 0f, zPosition);
|
||||
|
||||
Create(bepuCenter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza posición desde Top-Left WPF manteniendo parámetros actuales
|
||||
/// </summary>
|
||||
internal void SetPositionFromWpfTopLeft(Vector2 wpfTopLeft)
|
||||
{
|
||||
var curveSize = _outerRadius * 2f;
|
||||
var zPosition = GetPosition().Z; // Mantener Z actual
|
||||
var bepuCenter = CoordinateConverter.CalculateBepuCenterFromWpfTopLeft(wpfTopLeft, curveSize, curveSize, 0f, zPosition);
|
||||
|
||||
Create(bepuCenter);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Obtiene Top-Left WPF desde la posición actual
|
||||
/// </summary>
|
||||
internal Vector2 GetWpfTopLeft()
|
||||
{
|
||||
var bepuCenter = GetPosition();
|
||||
var curveSize = _outerRadius * 2f;
|
||||
return CoordinateConverter.CalculateWpfTopLeftFromBepuCenter(bepuCenter, curveSize, curveSize, 0f);
|
||||
}
|
||||
|
||||
public new void RemoverBody()
|
||||
{
|
||||
// ✅ CRÍTICO: Limpiar todos los motors conectados a esta curva ANTES de eliminar los bodies
|
||||
|
@ -1135,8 +1250,9 @@ namespace CtrEditor.Simulacion
|
|||
// Actualizar parámetros internos
|
||||
_innerRadius = innerRadius;
|
||||
_outerRadius = outerRadius;
|
||||
_startAngle = GradosARadianes(startAngle);
|
||||
_endAngle = GradosARadianes(endAngle);
|
||||
// ✅ CORREGIDO: Usar conversión WPF a BEPU consistente
|
||||
_startAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(startAngle));
|
||||
_endAngle = GradosARadianes(CoordinateConverter.WpfAngleToBepuAngle(endAngle));
|
||||
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
// Para curvas, el "tamaño" es el diámetro del radio exterior
|
||||
|
@ -1343,9 +1459,8 @@ namespace CtrEditor.Simulacion
|
|||
_radius = diameter / 2f;
|
||||
ListSimBotellaContact = new List<simBotella>();
|
||||
|
||||
// Convertir Vector2 a Vector3 con Z=0.3 (altura para detectar botellas)
|
||||
// Invertir Y para convertir de WPF (Y hacia abajo) a 3D (Y hacia arriba)
|
||||
var position3D = new Vector3(position.X, -position.Y, zPos_Descarte + _radius);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
var position3D = new Vector3(position.X, CoordinateConverter.WpfYToBepuY(position.Y), zPos_Descarte + _radius);
|
||||
Create(position3D);
|
||||
}
|
||||
|
||||
|
@ -1373,12 +1488,22 @@ namespace CtrEditor.Simulacion
|
|||
|
||||
public void Create(Vector2 position)
|
||||
{
|
||||
// Convertir Vector2 a Vector3 con Z=0.3 (altura para detectar botellas)
|
||||
// Invertir Y para convertir de WPF (Y hacia abajo) a 3D (Y hacia arriba)
|
||||
var position3D = new Vector3(position.X, -position.Y, zPos_Descarte + _radius);
|
||||
// ✅ USAR COORDINATECONVERTER para conversión centralizada
|
||||
var position3D = new Vector3(position.X, CoordinateConverter.WpfYToBepuY(position.Y), zPos_Descarte + _radius);
|
||||
Create(position3D);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ✅ NUEVO: Actualiza posición usando coordenadas WPF apropiadas
|
||||
/// </summary>
|
||||
internal void UpdateFromWpfCenter(Vector2 wpfCenter)
|
||||
{
|
||||
var position3D = new Vector3(wpfCenter.X, CoordinateConverter.WpfYToBepuY(wpfCenter.Y), zPos_Descarte + _radius);
|
||||
|
||||
// Actualizar solo posición manteniendo orientación
|
||||
CoordinateConverter.UpdateBepuBodyPosition(_simulation, BodyHandle, position3D);
|
||||
}
|
||||
|
||||
private void Create(Vector3 position)
|
||||
{
|
||||
RemoverBody();
|
||||
|
@ -1674,16 +1799,25 @@ namespace CtrEditor.Simulacion
|
|||
if (transport.DirectionVector.Length() < 0.001f)
|
||||
return;
|
||||
|
||||
// ✅ SIMPLIFICAR - Usar LinearAxisMotor básico
|
||||
// ✅ CORREGIDO - LocalAxis debe estar en coordenadas locales del transporte
|
||||
// Para transportes, el eje local de movimiento es siempre UnitX (eje largo)
|
||||
var localAxis = Vector3.UnitX; // Siempre UnitX en coordenadas locales del transporte
|
||||
|
||||
var motor = new LinearAxisMotor()
|
||||
{
|
||||
LocalOffsetA = Vector3.Zero,
|
||||
LocalOffsetB = Vector3.Zero,
|
||||
LocalAxis = transport.DirectionVector,
|
||||
LocalAxis = localAxis, // ✅ Usar eje local, no mundial
|
||||
TargetVelocity = transport.SpeedMetersPerSecond,
|
||||
Settings = new MotorSettings(Math.Max(bottle.Mass * 30f, 10f), 5f)
|
||||
};
|
||||
|
||||
// 🔍 DEBUG: Comparar eje local vs mundial
|
||||
System.Diagnostics.Debug.WriteLine($"[Motor] Transport angle: {transport.GetRotationZ()}°");
|
||||
System.Diagnostics.Debug.WriteLine($"[Motor] World DirectionVector: {transport.DirectionVector}");
|
||||
System.Diagnostics.Debug.WriteLine($"[Motor] Local Axis: {localAxis}");
|
||||
System.Diagnostics.Debug.WriteLine($"[Motor] Target Velocity: {transport.SpeedMetersPerSecond}");
|
||||
|
||||
var motorHandle = _simulationManager.simulation.Solver.Add(
|
||||
transport.BodyHandle,
|
||||
bottle.BodyHandle,
|
||||
|
|
Loading…
Reference in New Issue