Se añadió un comando para alternar la actualización 3D en MainViewModel, permitiendo habilitar o deshabilitar esta función para mejorar el rendimiento. Se implementó la lógica correspondiente en la visualización 3D y se eliminaron propiedades redundantes en varias clases, optimizando la gestión de objetos en la simulación.

This commit is contained in:
Miguel 2025-07-01 23:08:05 +02:00
parent 3773da0ee3
commit 3e53a51e8b
9 changed files with 233 additions and 329 deletions

View File

@ -0,0 +1,33 @@
using System;
using System.Globalization;
using System.Windows.Data;
namespace CtrEditor.Converters
{
public class BooleanToLocalizedTextConverter : IValueConverter
{
public string TrueText { get; set; } = "True";
public string FalseText { get; set; } = "False";
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is bool boolValue)
{
return boolValue ? TrueText : FalseText;
}
return FalseText;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string text)
{
if (text == TrueText)
return true;
if (text == FalseText)
return false;
}
return false;
}
}
}

View File

@ -419,6 +419,7 @@ namespace CtrEditor
TB3DViewSideCommand = new RelayCommand(() => Visualization3DManager?.SetCameraView(CameraView.Side));
TB3DViewFrontCommand = new RelayCommand(() => Visualization3DManager?.SetCameraView(CameraView.Front));
TB3DViewIsometricCommand = new RelayCommand(() => Visualization3DManager?.SetCameraView(CameraView.Isometric));
TBToggle3DUpdateCommand = new RelayCommand(() => Is3DUpdateEnabled = !Is3DUpdateEnabled);
RenameImageCommand = new RelayCommand<string>(RenameImage);
stopwatch_Sim = new Stopwatch();
@ -1195,6 +1196,20 @@ namespace CtrEditor
[ObservableProperty]
private double plcUpdateSpeed;
[ObservableProperty]
private bool is3DUpdateEnabled = true;
public ICommand TBToggle3DUpdateCommand { get; }
partial void OnIs3DUpdateEnabledChanged(bool value)
{
// Sincronizar la propiedad con el simulationManager
if (simulationManager != null)
{
simulationManager.Is3DUpdateEnabled = value;
}
}
private void OnDisplayUpdate(object? sender, EventArgs e)
{
if (simSampleCount > 0)
@ -1348,9 +1363,9 @@ namespace CtrEditor
private void OnTick3DUpdate(object? sender, EventArgs e)
{
// Solo actualizar Helix3D si la simulación está detenida
// Solo actualizar Helix3D si la simulación está detenida y la actualización 3D está habilitada
// Cuando la simulación está corriendo, la sincronización se hace en simulationManager.Step()
if (!IsSimulationRunning && Visualization3DManager != null)
if (!IsSimulationRunning && Is3DUpdateEnabled && Visualization3DManager != null)
{
Visualization3DManager.SynchronizeWorld();
}

View File

@ -202,6 +202,36 @@
</StackPanel>
</Button>
<Button Command="{Binding TBToggle3DUpdateCommand}" ToolTip="Activar/Desactivar actualización Debug 3D para mejorar rendimiento">
<StackPanel>
<Image Source="Icons/app.png" Width="24" Height="24" />
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="Debug3D: {0}">
<Binding Path="Is3DUpdateEnabled">
<Binding.Converter>
<converters:BooleanToLocalizedTextConverter TrueText="Activado" FalseText="Desactivado" />
</Binding.Converter>
</Binding>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
<Button.Style>
<Style TargetType="Button">
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<DataTrigger Binding="{Binding Is3DUpdateEnabled}" Value="True">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
<DataTrigger Binding="{Binding Is3DUpdateEnabled}" Value="False">
<Setter Property="Background" Value="LightCoral" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</ToolBar>
</ToolBarTray>

View File

@ -81,12 +81,6 @@ namespace CtrEditor.ObjetosSim
[property: Name("Inercia de Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Conservar objeto cuando sale de transporte")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Porcentaje de tracción con transporte")]
@ -136,7 +130,6 @@ namespace CtrEditor.ObjetosSim
Diametro = 0.10f;
Mass = 1;
ColorButton_oculto = Brushes.Gray;
Preserve_Outside_Transport = true;
}
public void UpdateAfterMove()
@ -190,9 +183,7 @@ namespace CtrEditor.ObjetosSim
if (SimGeometria.Descartar)
RemoverDesdeSimulacion = true;
// Eliminar la botella si esta fuera de un transporte
if (!Preserve_Outside_Transport && !SimGeometria.IsOnAnyTransport())
RemoverDesdeSimulacion = true;
// ✅ ELIMINADO: Lógica redundante - BEPU.cs ya elimina botellas que caen en Z automáticamente
Velocidad_desde_simulacion = SimGeometria.GetLinearVelocity().ToString();
Inercia_desde_simulacion = SimGeometria.Mass; // En BEPU usamos masa en lugar de inercia directa

View File

@ -80,12 +80,6 @@ namespace CtrEditor.ObjetosSim
[property: Name("Inercia Simulación")]
private float inercia_desde_simulacion;
[ObservableProperty]
[property: Category("Configuración")]
[property: Description("Conservar objeto cuando sale de transporte")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
[ObservableProperty]
[property: Category("Información")]
[property: Description("Porcentaje de tracción con transporte")]
@ -173,9 +167,7 @@ namespace CtrEditor.ObjetosSim
if (SimGeometria.Descartar)
RemoverDesdeSimulacion = true;
// Eliminar la botella si esta fuera de un transporte
if (!Preserve_Outside_Transport && !SimGeometria.IsOnAnyTransport())
RemoverDesdeSimulacion = true;
// ✅ ELIMINADO: Lógica redundante - BEPU.cs ya elimina botellas que caen en Z automáticamente
Velocidad_desde_simulacion = SimGeometria.GetLinearVelocity().ToString();
Inercia_desde_simulacion = SimGeometria.Mass; // En BEPU usamos masa en lugar de inercia directa

View File

@ -40,11 +40,8 @@ namespace CtrEditor.ObjetosSim
[property: Name("Offset Vertical")]
private float offsetTopSalida;
[ObservableProperty]
[property: Description("Las botellas se destruirán si caen fuera del transporte")]
[property: Category("Configuración")]
[property: Name("Conservar Fuera de Transporte")]
private bool preserve_Outside_Transport;
// ✅ ELIMINADO: preserve_Outside_Transport - Redundante con ProcessCleanupSystem de BEPU
// Las botellas que caen en Z son eliminadas automáticamente por BEPU.cs
[ObservableProperty]
[property: Description("Tag PLC para habilitar funcionamiento. 1 => siempre activo")]
[property: Category("Enlace PLC")]
@ -185,7 +182,7 @@ namespace CtrEditor.ObjetosSim
{
var nuevaBotella = _mainViewModel.CrearObjetoSimulable(typeof(osBotella), X, Y);
((osBotella)nuevaBotella).Diametro = Diametro_botella;
((osBotella)nuevaBotella).Preserve_Outside_Transport = Preserve_Outside_Transport;
// ✅ ELIMINADO: Preserve_Outside_Transport - Ya no es necesario
nuevaBotella.AutoCreated = true;
// Recalcular el tiempo entre botellas por si cambió la velocidad

View File

@ -93,7 +93,7 @@ namespace CtrEditor.ObjetosSim
[property: Category("Enlace PLC")]
[property: Description("Motor enlazado al transporte")]
[property: Name("Motor Enlazado")]
//[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
[property: ItemsSource(typeof(osBaseItemsSource<osVMmotorSim>))]
string id_Motor;
[JsonIgnore]
@ -101,24 +101,24 @@ namespace CtrEditor.ObjetosSim
partial void OnId_MotorChanged(string value)
{
//if (Motor != null && motorPropertyChangedHandler != null)
// Motor.PropertyChanged -= motorPropertyChangedHandler;
if (Motor != null && motorPropertyChangedHandler != null)
Motor.PropertyChanged -= motorPropertyChangedHandler;
//if (_mainViewModel != null && !string.IsNullOrEmpty(value))
//{
// Motor = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => s is osVMmotorSim motor && motor.Nombre == value);
// if (Motor != null)
// {
// motorPropertyChangedHandler = (sender, e) =>
// {
// if (e.PropertyName == nameof(osVMmotorSim.Nombre))
// {
// Id_Motor = ((osVMmotorSim)sender).Nombre;
// }
// };
// Motor.PropertyChanged += motorPropertyChangedHandler;
// }
//}
if (_mainViewModel != null && !string.IsNullOrEmpty(value))
{
Motor = (osVMmotorSim)_mainViewModel.ObjetosSimulables.FirstOrDefault(s => s is osVMmotorSim motor && motor.Nombre == value);
if (Motor != null)
{
motorPropertyChangedHandler = (sender, e) =>
{
if (e.PropertyName == nameof(osVMmotorSim.Nombre))
{
Id_Motor = ((osVMmotorSim)sender).Nombre;
}
};
Motor.PropertyChanged += motorPropertyChangedHandler;
}
}
}
public override void AltoChanged(float value)
@ -337,12 +337,12 @@ namespace CtrEditor.ObjetosSim
public override void UpdatePLC(PLCViewModel plc, int elapsedMilliseconds)
{
//if (Motor != null)
// if (Motor is osVMmotorSim id_motor)
// if (LeerBitTag(Tag_ReleActivatedMotor))
// VelocidadActual = id_motor.Velocidad;
// else
// VelocidadActual = 0;
if (Motor != null)
if (Motor is osVMmotorSim id_motor)
if (LeerBitTag(Tag_ReleActivatedMotor))
VelocidadActual = id_motor.Velocidad;
else
VelocidadActual = 0;
// Actualizar información de botellas en tiempo real si es un transporte con freno
if (EsFreno)

View File

@ -696,33 +696,7 @@ namespace CtrEditor.Simulacion
public void SetSpeed(float speed)
{
Speed = speed;
}
/// <summary>
/// Configura la velocidad de la curva en metros por segundo
/// Valores positivos mueven en sentido horario, negativos en sentido antihorario
/// </summary>
/// <param name="speedMeterPerSecond">Velocidad en m/s (típicamente entre -5.0 y 5.0)</param>
public void SetCurveSpeed(float speedMeterPerSecond)
{
Speed = speedMeterPerSecond;
}
/// <summary>
/// Detiene completamente la curva
/// </summary>
public void StopCurve()
{
Speed = 0f;
}
/// <summary>
/// Invierte la dirección de la curva manteniendo la misma velocidad
/// </summary>
public void ReverseCurve()
{
Speed = -Speed;
Speed = -speed;
}
public void UpdateCurve(float innerRadius, float outerRadius, float startAngle, float endAngle)
@ -1514,6 +1488,9 @@ namespace CtrEditor.Simulacion
// Referencia al manager de visualización 3D
public BEPUVisualization3DManager Visualization3DManager { get; set; }
// Propiedad para controlar si la actualización 3D está habilitada
public bool Is3DUpdateEnabled { get; set; } = true;
// Sistema de contactos de transporte para aplicar fuerzas
private Dictionary<simBotella, simTransporte> _transportContacts;
// Sistema de contactos de barrera para detección de paso
@ -1767,8 +1744,11 @@ namespace CtrEditor.Simulacion
_brakeTransportContacts.Clear();
}
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
// Sincronizar con la visualización 3D solo si está habilitado
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
}
catch (Exception ex)
{
@ -1804,7 +1784,10 @@ namespace CtrEditor.Simulacion
Cuerpos.Remove(Objeto);
// Actualizar visualización 3D tras eliminar objeto
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
}
public simBotella AddCircle(float diameter, Vector2 position, float mass)
@ -1813,7 +1796,10 @@ namespace CtrEditor.Simulacion
Cuerpos.Add(botella);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return botella;
}
@ -1823,7 +1809,10 @@ namespace CtrEditor.Simulacion
var transporte = new simTransporte(simulation, _deferredActions, width, height, position, angle);
Cuerpos.Add(transporte);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return transporte;
}
@ -1833,7 +1822,10 @@ namespace CtrEditor.Simulacion
var barrera = new simBarrera(simulation, _deferredActions, width, height, position, angle, detectarCuello);
Cuerpos.Add(barrera);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return barrera;
}
@ -1845,7 +1837,10 @@ namespace CtrEditor.Simulacion
var guia = new simGuia(simulation, _deferredActions, width, height, topLeft, angle);
Cuerpos.Add(guia);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return guia;
}
@ -1855,7 +1850,10 @@ namespace CtrEditor.Simulacion
var descarte = new simDescarte(simulation, _deferredActions, diameter, position);
Cuerpos.Add(descarte);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return descarte;
}
@ -1865,7 +1863,10 @@ namespace CtrEditor.Simulacion
var curve = new simCurve(simulation, _deferredActions, innerRadius, outerRadius, startAngle, endAngle, topLeft, unused);
Cuerpos.Add(curve);
// Sincronizar con la visualización 3D
Visualization3DManager?.SynchronizeWorld();
if (Is3DUpdateEnabled)
{
Visualization3DManager?.SynchronizeWorld();
}
return curve;
}

View File

@ -284,28 +284,7 @@ namespace CtrEditor.Simulacion
var meshBuilder = new MeshBuilder();
meshBuilder.AddSphere(new Point3D(0, 0, 0), (double)radius, 16, 16);
Material material;
if (simObj is simDescarte)
{
// Material semi-transparente para descartes (85% transparente = 15% opacidad)
var descarteBrush = new SolidColorBrush(Color.FromRgb(255, 100, 255)); // Magenta
descarteBrush.Opacity = 0.15; // 15% opacidad = 85% transparencia
material = MaterialHelper.CreateMaterial(
descarteBrush,
specularPower: 60,
ambient: 120
);
}
else
{
// Material plástico brillante para botellas (rojo)
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(255, 80, 80)),
specularPower: 120,
ambient: 200
);
}
var model = new GeometryModel3D(meshBuilder.ToMesh(), material);
var model = new GeometryModel3D(meshBuilder.ToMesh(), GetMaterialForSimBase(simObj));
return new ModelVisual3D { Content = model };
}
@ -315,47 +294,7 @@ namespace CtrEditor.Simulacion
var meshBuilder = new MeshBuilder();
meshBuilder.AddBox(new Point3D(0, 0, 0), (double)width, (double)height, (double)length);
// Determinar el color según el tipo de simBase y crear material plástico brillante
Material material;
if (simObj is simGuia)
{
// Material plástico brillante negro para guías
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(50, 50, 50)),
specularPower: 150,
ambient: 180
);
}
else if (simObj is simBarrera)
{
// Material semi-transparente amarillo para barreras (haz de luz)
var yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
yellowBrush.Opacity = 0.3; // 30% opacidad para simular haz de luz
material = MaterialHelper.CreateMaterial(
yellowBrush,
specularPower: 50,
ambient: 150
);
}
else if (simObj is simTransporte)
{
// Material plástico brillante verde para transportes
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 180, 80)),
specularPower: 140,
ambient: 200
);
}
else
{
// Material plástico brillante gris por defecto
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(128, 128, 128)),
specularPower: 100,
ambient: 190
);
}
var model = new GeometryModel3D(meshBuilder.ToMesh(), material);
var model = new GeometryModel3D(meshBuilder.ToMesh(), GetMaterialForSimBase(simObj));
return new ModelVisual3D { Content = model };
}
@ -385,58 +324,8 @@ namespace CtrEditor.Simulacion
var p2 = new Point3D(0, 0, length / 2);
meshBuilder.AddCylinder(p1, p2, radius: (double)radius, thetaDiv: 16, cap1: true, cap2: true);
// Determinar el color según el tipo de simBase - Material plástico con reflexión (valores originales)
Material material;
if (simObj is simBotella)
{
// Material plástico brillante rojo para botellas (cilindros)
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Colors.Red),
specularPower: 120,
ambient: 200
);
}
else if (simObj is simTransporte)
{
// Material plástico verde para transportes (valores originales)
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 180, 80)),
specularPower: 140,
ambient: 200
);
}
else if (simObj is simGuia)
{
// Material plástico gris oscuro para guías (valores originales)
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(50, 50, 50)),
specularPower: 150,
ambient: 180
);
}
else if (simObj is simBarrera)
{
// Material semi-transparente amarillo para barreras (haz de luz)
var yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
yellowBrush.Opacity = 0.3; // 30% opacidad para simular haz de luz
material = MaterialHelper.CreateMaterial(
yellowBrush,
specularPower: 50,
ambient: 150
);
}
else
{
// Material plástico gris estándar para objetos no identificados (valores originales)
material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(128, 128, 128)),
specularPower: 100,
ambient: 190
);
}
var geometry = meshBuilder.ToMesh();
var model = new GeometryModel3D(geometry, material);
var model = new GeometryModel3D(geometry, GetMaterialForSimBase(simObj));
var visual = new ModelVisual3D();
visual.Content = model;
@ -452,15 +341,8 @@ namespace CtrEditor.Simulacion
// ✅ NUEVO: Usar directamente los triángulos originales de BEPU (debug real)
CreateCurveMeshFromBEPUTriangles(meshBuilder, curve);
// Material plástico brillante para curvas (azul verdoso)
var material = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 150, 200)),
specularPower: 130,
ambient: 190
);
var geometry = meshBuilder.ToMesh();
var model = new GeometryModel3D(geometry, material);
var model = new GeometryModel3D(geometry, GetMaterialForSimBase(curve));
var visual = new ModelVisual3D();
visual.Content = model;
@ -781,13 +663,7 @@ namespace CtrEditor.Simulacion
meshBuilder.AddCylinder(p1, p2, radius: (double)botella.Radius, thetaDiv: 16, cap1: true, cap2: true);
newGeometry = meshBuilder.ToMesh();
// Material específico para botellas - rojo brillante
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Colors.Red),
specularPower: 120,
ambient: 200
);
newMaterial = GetMaterialForSimBase(simObj);
}
// Caso especial: simCurve necesita recreación completa de geometría
else if (simObj is simCurve curve)
@ -800,13 +676,7 @@ namespace CtrEditor.Simulacion
CreateCurveMeshFromBEPUTriangles(meshBuilder, curve);
newGeometry = meshBuilder.ToMesh();
// Material específico para curvas - azul verdoso brillante
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 150, 200)),
specularPower: 130,
ambient: 190
);
newMaterial = GetMaterialForSimBase(simObj);
System.Diagnostics.Debug.WriteLine($"[3D Recreate] CURVE mesh created successfully with {newGeometry?.Positions?.Count ?? 0} vertices");
}
@ -815,112 +685,14 @@ namespace CtrEditor.Simulacion
var meshBuilder = new MeshBuilder();
meshBuilder.AddSphere(new Point3D(0, 0, 0), dimensions.Radius);
newGeometry = meshBuilder.ToMesh();
// Color según tipo de objeto - Material plástico con reflexión (valores originales)
if (simObj is simDescarte)
{
// Material semi-transparente para descartes (85% transparente = 15% opacidad)
var descarteBrush = new SolidColorBrush(Color.FromRgb(255, 100, 255)); // Magenta
descarteBrush.Opacity = 0.15; // 15% opacidad = 85% transparencia
newMaterial = MaterialHelper.CreateMaterial(
descarteBrush,
specularPower: 60,
ambient: 120
);
}
else if (simObj is simBotella)
{
// Material plástico brillante rojo para botellas
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Colors.Red),
specularPower: 120,
ambient: 200
);
}
else if (simObj is simTransporte)
{
// Material plástico verde para transportes (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 180, 80)),
specularPower: 140,
ambient: 200
);
}
else if (simObj is simGuia)
{
// Material plástico gris oscuro para guías (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(50, 50, 50)),
specularPower: 150,
ambient: 180
);
}
else if (simObj is simBarrera)
{
// Material semi-transparente amarillo para barreras (haz de luz)
var yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
yellowBrush.Opacity = 0.3; // 30% opacidad para simular haz de luz
newMaterial = MaterialHelper.CreateMaterial(
yellowBrush,
specularPower: 50,
ambient: 150
);
}
else
{
// Material plástico gris estándar para otras esferas (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(128, 128, 128)),
specularPower: 100,
ambient: 190
);
}
newMaterial = GetMaterialForSimBase(simObj);
}
else if (dimensions.ShapeType == BepuPhysics.Collidables.Box.Id)
{
var meshBuilder = new MeshBuilder();
meshBuilder.AddBox(new Point3D(0, 0, 0), dimensions.Width, dimensions.Height, dimensions.Length);
newGeometry = meshBuilder.ToMesh();
// Color según tipo de objeto - Material plástico con reflexión (valores originales)
if (simObj is simTransporte)
{
// Material plástico verde para transportes (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 180, 80)),
specularPower: 140,
ambient: 200
);
}
else if (simObj is simGuia)
{
// Material plástico gris oscuro para guías (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(50, 50, 50)),
specularPower: 150,
ambient: 180
);
}
else if (simObj is simBarrera)
{
// Material semi-transparente amarillo para barreras (haz de luz)
var yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
yellowBrush.Opacity = 0.3; // 30% opacidad para simular haz de luz
newMaterial = MaterialHelper.CreateMaterial(
yellowBrush,
specularPower: 50,
ambient: 150
);
}
else
{
// Material plástico gris estándar para otros boxes (valores originales)
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(128, 128, 128)),
specularPower: 100,
ambient: 190
);
}
newMaterial = GetMaterialForSimBase(simObj);
}
else if (dimensions.ShapeType == BepuPhysics.Collidables.Cylinder.Id)
{
@ -932,12 +704,7 @@ namespace CtrEditor.Simulacion
meshBuilder.AddCylinder(p1, p2, radius: (double)dimensions.Radius, thetaDiv: 16, cap1: true, cap2: true);
newGeometry = meshBuilder.ToMesh();
newMaterial = MaterialHelper.CreateMaterial(
new SolidColorBrush(Colors.Green),
specularPower: 135,
ambient: 205
);
newMaterial = GetMaterialForSimBase(simObj);
}
if (newGeometry != null)
@ -963,6 +730,84 @@ namespace CtrEditor.Simulacion
lastKnownDimensions.Clear();
}
/// <summary>
/// Función centralizada para obtener el material apropiado según el tipo de simBase
/// </summary>
/// <param name="simObj">Objeto de simulación para determinar el material</param>
/// <returns>Material configurado para el tipo de objeto</returns>
private Material GetMaterialForSimBase(simBase simObj)
{
if (simObj is simTransporte)
{
// Material plástico verde para transportes
return MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 180, 80)),
specularPower: 140,
ambient: 200
);
}
else if (simObj is simGuia)
{
// Material semitransparente gris oscuro para guías
var guiaBrush = new SolidColorBrush(Color.FromRgb(80, 80, 80));
guiaBrush.Opacity = 0.4; // 40% opacidad para mejor visualización semitransparente
return MaterialHelper.CreateMaterial(
guiaBrush,
specularPower: 30,
ambient: 100
);
}
else if (simObj is simBarrera)
{
// Material semi-transparente amarillo para barreras (haz de luz)
var yellowBrush = new SolidColorBrush(Color.FromRgb(255, 255, 0));
yellowBrush.Opacity = 0.3; // 30% opacidad para simular haz de luz
return MaterialHelper.CreateMaterial(
yellowBrush,
specularPower: 50,
ambient: 150
);
}
else if (simObj is simBotella)
{
// Material plástico brillante rojo para botellas
return MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(255, 80, 80)),
specularPower: 120,
ambient: 200
);
}
else if (simObj is simDescarte)
{
// Material semi-transparente magenta para descartes (85% transparente)
var descarteBrush = new SolidColorBrush(Color.FromRgb(255, 100, 255));
descarteBrush.Opacity = 0.15; // 15% opacidad = 85% transparencia
return MaterialHelper.CreateMaterial(
descarteBrush,
specularPower: 60,
ambient: 120
);
}
else if (simObj is simCurve)
{
// Material plástico brillante para curvas (azul verdoso)
return MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(80, 150, 200)),
specularPower: 130,
ambient: 190
);
}
else
{
// Material plástico gris estándar para objetos no identificados
return MaterialHelper.CreateMaterial(
new SolidColorBrush(Color.FromRgb(128, 128, 128)),
specularPower: 100,
ambient: 190
);
}
}
public void SetCameraView(CameraView view)
{
if (viewport3D?.Camera is not PerspectiveCamera camera) return;