Se ajustaron los coeficientes de fricción y configuraciones de resorte en la simulación de botellas, diferenciando entre transportes con y sin freno. Además, se modificó la visibilidad de triángulos en la visualización 3D, mejorando la iluminación y corrigiendo la creación de mallas continuas a partir de triángulos de BEPU. Se eliminaron métodos obsoletos relacionados con la geometría de curvas, optimizando la lógica de creación de mallas.
This commit is contained in:
parent
eb6ed62d5b
commit
71c08d8047
|
@ -127,9 +127,22 @@ namespace CtrEditor.Simulacion
|
||||||
// en la clase simTransporte. El motor de físicas se encarga del resto.
|
// en la clase simTransporte. El motor de físicas se encarga del resto.
|
||||||
|
|
||||||
// ✅ Fricción ajustada para un arrastre firme pero no excesivo.
|
// ✅ Fricción ajustada para un arrastre firme pero no excesivo.
|
||||||
pairMaterial.FrictionCoefficient = 1.2f;
|
var transport = transportA ?? transportB;
|
||||||
pairMaterial.MaximumRecoveryVelocity = 1.0f;
|
if (transport.isBrake)
|
||||||
pairMaterial.SpringSettings = new SpringSettings(80, 1);
|
{
|
||||||
|
botella.isOnBrakeTransport = true;
|
||||||
|
pairMaterial.FrictionCoefficient = 14f;
|
||||||
|
pairMaterial.MaximumRecoveryVelocity = 1.0f;
|
||||||
|
pairMaterial.SpringSettings = new SpringSettings(80, 8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
botella.isOnBrakeTransport = false;
|
||||||
|
pairMaterial.FrictionCoefficient = 1.2f;
|
||||||
|
pairMaterial.MaximumRecoveryVelocity = 1.0f;
|
||||||
|
pairMaterial.SpringSettings = new SpringSettings(80, 1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// ✅ CONTACTO BOTELLA-CURVA: USAR FRICCIÓN Y VELOCIDAD CINEMÁTICA
|
// ✅ CONTACTO BOTELLA-CURVA: USAR FRICCIÓN Y VELOCIDAD CINEMÁTICA
|
||||||
else if (botella != null && (curveA != null || curveB != null))
|
else if (botella != null && (curveA != null || curveB != null))
|
||||||
|
@ -153,9 +166,18 @@ namespace CtrEditor.Simulacion
|
||||||
// ✅ NUEVO: CONTACTO BOTELLA-BOTELLA: Configuración más suave para evitar el comportamiento "pegajoso".
|
// ✅ NUEVO: CONTACTO BOTELLA-BOTELLA: Configuración más suave para evitar el comportamiento "pegajoso".
|
||||||
else if (botellaA != null && botellaB != null)
|
else if (botellaA != null && botellaB != null)
|
||||||
{
|
{
|
||||||
pairMaterial.FrictionCoefficient = 0.01f; // Un poco menos de fricción.
|
if (botella.isOnBrakeTransport)
|
||||||
pairMaterial.MaximumRecoveryVelocity = 1.5f; // Menos rebote.
|
{
|
||||||
pairMaterial.SpringSettings = new SpringSettings(20, 0.5f); // Muelle MUCHO más suave y críticamente amortiguado.
|
pairMaterial.FrictionCoefficient = 2.0f; // Un poco menos de fricción.
|
||||||
|
pairMaterial.MaximumRecoveryVelocity = 1.5f; // Menos rebote.
|
||||||
|
pairMaterial.SpringSettings = new SpringSettings(80, 1f); // Muelle MUCHO más suave y críticamente amortiguado.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pairMaterial.FrictionCoefficient = 0.01f; // Un poco menos de fricción.
|
||||||
|
pairMaterial.MaximumRecoveryVelocity = 1.5f; // Menos rebote.
|
||||||
|
pairMaterial.SpringSettings = new SpringSettings(20, 0.5f); // Muelle MUCHO más suave y críticamente amortiguado.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Ajustes básicos para otras botellas
|
// Ajustes básicos para otras botellas
|
||||||
else if (botella != null)
|
else if (botella != null)
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace CtrEditor.Simulacion
|
||||||
private Dictionary<simBase, ShapeDimensions> lastKnownDimensions;
|
private Dictionary<simBase, ShapeDimensions> lastKnownDimensions;
|
||||||
|
|
||||||
// ✅ CORREGIDO: Flag de debug para mostrar triángulos individuales de curvas (true temporalmente para verificar)
|
// ✅ CORREGIDO: Flag de debug para mostrar triángulos individuales de curvas (true temporalmente para verificar)
|
||||||
public static bool DebugShowIndividualTriangles { get; set; } = true;
|
public static bool DebugShowIndividualTriangles { get; set; } = false;
|
||||||
|
|
||||||
public HelixViewport3D Viewport3D
|
public HelixViewport3D Viewport3D
|
||||||
{
|
{
|
||||||
|
@ -112,14 +112,14 @@ namespace CtrEditor.Simulacion
|
||||||
// Agregar luces
|
// Agregar luces
|
||||||
var directionalLight = new DirectionalLight
|
var directionalLight = new DirectionalLight
|
||||||
{
|
{
|
||||||
Color = Colors.White,
|
Color = Color.FromRgb(150, 150, 150), // Luz direccional menos intensa
|
||||||
Direction = new Vector3D(0, 0, -1)
|
Direction = new Vector3D(-0.2, -0.3, -1) // Ligeramente angulada para evitar reflejos directos
|
||||||
};
|
};
|
||||||
viewport3D.Children.Add(new ModelVisual3D { Content = directionalLight });
|
viewport3D.Children.Add(new ModelVisual3D { Content = directionalLight });
|
||||||
|
|
||||||
var ambientLight = new AmbientLight
|
var ambientLight = new AmbientLight
|
||||||
{
|
{
|
||||||
Color = Color.FromRgb(64, 64, 64)
|
Color = Color.FromRgb(120, 120, 120) // Más luz ambiente para suavizar sombras
|
||||||
};
|
};
|
||||||
viewport3D.Children.Add(new ModelVisual3D { Content = ambientLight });
|
viewport3D.Children.Add(new ModelVisual3D { Content = ambientLight });
|
||||||
|
|
||||||
|
@ -397,7 +397,7 @@ namespace CtrEditor.Simulacion
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ✅ Usar directamente los triángulos originales de BEPU (superficie continua)
|
// ✅ CORREGIDO: Crea un arco de mesh continuo y simple desde los triángulos de BEPU
|
||||||
CreateCurveMeshFromBEPUTriangles(meshBuilder, curve);
|
CreateCurveMeshFromBEPUTriangles(meshBuilder, curve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -422,44 +422,57 @@ namespace CtrEditor.Simulacion
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// ✅ CORREGIDO: Crea mesh desde los triángulos locales de BEPU
|
/// ✅ CORREGIDO: Crea un arco de mesh continuo y simple desde los triángulos de BEPU
|
||||||
/// Extrae la geometría exacta en coordenadas locales para evitar transformación duplicada
|
/// Genera una superficie plana que forma un arco suave y eficiente
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void CreateCurveMeshFromBEPUTriangles(MeshBuilder meshBuilder, simCurve curve)
|
private void CreateCurveMeshFromBEPUTriangles(MeshBuilder meshBuilder, simCurve curve)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// ✅ EXTRAER TRIÁNGULOS LOCALES DE BEPU (sin transformación duplicada)
|
// Obtener los triángulos de BEPU
|
||||||
var localTriangles = curve.GetRealBEPUTriangles();
|
var localTriangles = curve.GetRealBEPUTriangles();
|
||||||
|
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] Creating continuous arc mesh from {localTriangles.Length} BEPU triangles");
|
||||||
|
|
||||||
if (localTriangles.Length == 0)
|
if (localTriangles.Length == 0)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D BEPU] WARNING: No se pudieron extraer triángulos locales, usando fallback");
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] WARNING: No triangles found in BEPU curve");
|
||||||
CreateCurveMeshFallback(meshBuilder, curve);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D BEPU] Creando mesh desde {localTriangles.Length} triángulos locales de BEPU");
|
// ✅ CORREGIDO: Usar altura más visible y verificar coordenadas
|
||||||
|
const float curveHeight = 0.02f; // 2cm de altura para que sea claramente visible
|
||||||
|
int triangleCount = 0;
|
||||||
|
|
||||||
// ✅ USAR TRIÁNGULOS LOCALES DE BEPU (la transformación se aplicará automáticamente en UpdateVisualization)
|
|
||||||
foreach (var triangle in localTriangles)
|
foreach (var triangle in localTriangles)
|
||||||
{
|
{
|
||||||
// Convertir triángulos de BEPU a puntos 3D de Helix
|
// ✅ LOGGING: Verificar las coordenadas del primer triángulo
|
||||||
var pointA = new Point3D(triangle.A.X, triangle.A.Y, triangle.A.Z);
|
if (triangleCount == 0)
|
||||||
var pointB = new Point3D(triangle.B.X, triangle.B.Y, triangle.B.Z);
|
{
|
||||||
var pointC = new Point3D(triangle.C.X, triangle.C.Y, triangle.C.Z);
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] First triangle: A({triangle.A.X:F3}, {triangle.A.Y:F3}, {triangle.A.Z:F3})");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] First triangle: B({triangle.B.X:F3}, {triangle.B.Y:F3}, {triangle.B.Z:F3})");
|
||||||
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] First triangle: C({triangle.C.X:F3}, {triangle.C.Y:F3}, {triangle.C.Z:F3})");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crear triángulo en la superficie superior con altura visible
|
||||||
|
var pointA = new Point3D(triangle.A.X, triangle.A.Y, triangle.A.Z + curveHeight);
|
||||||
|
var pointB = new Point3D(triangle.B.X, triangle.B.Y, triangle.B.Z + curveHeight);
|
||||||
|
var pointC = new Point3D(triangle.C.X, triangle.C.Y, triangle.C.Z + curveHeight);
|
||||||
|
|
||||||
// Agregar triángulo en coordenadas locales al mesh
|
// ✅ CORREGIDO: Probar ambos órdenes de vértices para asegurar normales correctas
|
||||||
meshBuilder.AddTriangle(pointA, pointB, pointC);
|
meshBuilder.AddTriangle(pointA, pointB, pointC);
|
||||||
|
// También agregar el triángulo con orden inverso para que sea visible desde ambos lados
|
||||||
|
meshBuilder.AddTriangle(pointA, pointC, pointB);
|
||||||
|
|
||||||
|
triangleCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D BEPU] ✅ Mesh creado usando triángulos locales de BEPU (transformación aplicada automáticamente)");
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] ✅ Continuous arc mesh created with {triangleCount} triangles (height: {curveHeight})");
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D BEPU] ERROR extrayendo triángulos locales: {ex.Message}");
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] ERROR creating continuous arc mesh: {ex.Message}");
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D BEPU] Fallback a geometría recreada");
|
System.Diagnostics.Debug.WriteLine($"[3D Curve] Stack trace: {ex.StackTrace}");
|
||||||
CreateCurveMeshFallback(meshBuilder, curve);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,7 +490,7 @@ namespace CtrEditor.Simulacion
|
||||||
if (localTriangles.Length == 0)
|
if (localTriangles.Length == 0)
|
||||||
{
|
{
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D Debug] WARNING: No hay triángulos locales para debug, usando fallback");
|
System.Diagnostics.Debug.WriteLine($"[3D Debug] WARNING: No hay triángulos locales para debug, usando fallback");
|
||||||
CreateCurveMeshFallback(meshBuilder, curve);
|
CreateBasicDebugGeometry(meshBuilder, curve);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,81 +587,6 @@ namespace CtrEditor.Simulacion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Método fallback que recrea la geometría (mantener por compatibilidad)
|
|
||||||
/// </summary>
|
|
||||||
private void CreateCurveMeshFallback(MeshBuilder meshBuilder, simCurve curve)
|
|
||||||
{
|
|
||||||
// Obtener parámetros de la curva
|
|
||||||
float innerRadius = curve.InnerRadius;
|
|
||||||
float outerRadius = curve.OuterRadius;
|
|
||||||
float startAngle = curve.StartAngle;
|
|
||||||
float endAngle = curve.EndAngle;
|
|
||||||
|
|
||||||
System.Diagnostics.Debug.WriteLine($"[3D Fallback] Parameters - Inner: {innerRadius}, Outer: {outerRadius}, Start: {startAngle}, End: {endAngle}");
|
|
||||||
|
|
||||||
// Configuración de segmentos
|
|
||||||
const float SegmentationFactor = 32f / 3f;
|
|
||||||
const int MinSegments = 8;
|
|
||||||
const int MaxSegments = 64;
|
|
||||||
|
|
||||||
// Calcular número de segmentos basado en el tamaño del arco
|
|
||||||
float arcLength = (endAngle - startAngle) * ((innerRadius + outerRadius) / 2f);
|
|
||||||
int segments = (int)(arcLength * SegmentationFactor);
|
|
||||||
segments = Math.Max(MinSegments, Math.Min(segments, MaxSegments));
|
|
||||||
|
|
||||||
float angleStep = (endAngle - startAngle) / segments;
|
|
||||||
|
|
||||||
// Altura muy pequeña para simular triángulos planos
|
|
||||||
const float curveHeight = 0.05f;
|
|
||||||
|
|
||||||
// Generar vértices para el arco interior y exterior
|
|
||||||
var innerBottomPoints = new Point3D[segments + 1];
|
|
||||||
var innerTopPoints = new Point3D[segments + 1];
|
|
||||||
var outerBottomPoints = new Point3D[segments + 1];
|
|
||||||
var outerTopPoints = new Point3D[segments + 1];
|
|
||||||
|
|
||||||
for (int i = 0; i <= segments; i++)
|
|
||||||
{
|
|
||||||
float angle = startAngle + i * angleStep;
|
|
||||||
float cosAngle = (float)Math.Cos(angle);
|
|
||||||
float sinAngle = (float)Math.Sin(angle);
|
|
||||||
|
|
||||||
// Puntos en la parte inferior (Z = 0)
|
|
||||||
innerBottomPoints[i] = new Point3D(innerRadius * cosAngle, innerRadius * sinAngle, 0);
|
|
||||||
outerBottomPoints[i] = new Point3D(outerRadius * cosAngle, outerRadius * sinAngle, 0);
|
|
||||||
|
|
||||||
// Puntos en la parte superior (Z = curveHeight)
|
|
||||||
innerTopPoints[i] = new Point3D(innerRadius * cosAngle, innerRadius * sinAngle, curveHeight);
|
|
||||||
outerTopPoints[i] = new Point3D(outerRadius * cosAngle, outerRadius * sinAngle, curveHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear la superficie superior de la curva
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
meshBuilder.AddTriangle(innerTopPoints[i], outerTopPoints[i], outerTopPoints[i + 1]);
|
|
||||||
meshBuilder.AddTriangle(innerTopPoints[i], outerTopPoints[i + 1], innerTopPoints[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear la superficie inferior de la curva
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
meshBuilder.AddTriangle(innerBottomPoints[i], outerBottomPoints[i + 1], outerBottomPoints[i]);
|
|
||||||
meshBuilder.AddTriangle(innerBottomPoints[i], innerBottomPoints[i + 1], outerBottomPoints[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear las paredes laterales
|
|
||||||
for (int i = 0; i < segments; i++)
|
|
||||||
{
|
|
||||||
meshBuilder.AddQuad(innerBottomPoints[i], innerBottomPoints[i + 1], innerTopPoints[i + 1], innerTopPoints[i]);
|
|
||||||
meshBuilder.AddQuad(outerBottomPoints[i], outerTopPoints[i], outerTopPoints[i + 1], outerBottomPoints[i + 1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Crear las paredes de los extremos
|
|
||||||
meshBuilder.AddQuad(innerBottomPoints[0], innerTopPoints[0], outerTopPoints[0], outerBottomPoints[0]);
|
|
||||||
meshBuilder.AddQuad(outerBottomPoints[segments], outerTopPoints[segments], innerTopPoints[segments], innerBottomPoints[segments]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateVisualizationFromSimBase(simBase simObj)
|
private void UpdateVisualizationFromSimBase(simBase simObj)
|
||||||
{
|
{
|
||||||
if (!simBaseToModelMap.TryGetValue(simObj, out var visual))
|
if (!simBaseToModelMap.TryGetValue(simObj, out var visual))
|
||||||
|
|
Loading…
Reference in New Issue