use super::backend::{DebugLine, DebugPoint, push_box};
use bitflags::bitflags;
use nexus::mpm::debug::{DebugGrid, DebugParticle};
bitflags! {
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
pub struct MpmDebugRenderMode: u32 {
const PARTICLES = 1 << 0;
const PARTICLE_VELOCITIES = 1 << 1;
const PARTICLE_CDF = 1 << 2;
const GRID_BLOCKS = 1 << 3;
const GRID_NODES = 1 << 4;
const GRID_VELOCITIES = 1 << 5;
}
}
impl MpmDebugRenderMode {
pub fn needs_particles(self) -> bool {
self.intersects(Self::PARTICLES | Self::PARTICLE_VELOCITIES | Self::PARTICLE_CDF)
}
pub fn needs_grid(self) -> bool {
self.intersects(Self::GRID_BLOCKS | Self::GRID_NODES | Self::GRID_VELOCITIES)
}
}
const PARTICLE_COLOR: [f32; 4] = [0.0, 0.35, 0.8, 1.0];
const PARTICLE_FIXED_COLOR: [f32; 4] = [0.8, 0.0, 0.0, 1.0];
const PARTICLE_VELOCITY_COLOR: [f32; 4] = [0.0, 0.55, 0.25, 1.0];
const PARTICLE_CDF_COLOR: [f32; 4] = [0.7, 0.55, 0.0, 1.0];
const BLOCK_COLOR: [f32; 4] = [0.25, 0.25, 0.45, 0.9];
const BLOCK_EMPTY_COLOR: [f32; 4] = [0.6, 0.5, 0.8, 0.7];
const NODE_COLOR: [f32; 4] = [0.1, 0.1, 0.1, 1.0];
const NODE_VELOCITY_COLOR: [f32; 4] = [0.85, 0.25, 0.0, 1.0];
pub fn render_particles(
particles: &[DebugParticle],
mode: MpmDebugRenderMode,
velocity_scale: f32,
lines: &mut Vec<DebugLine>,
points: &mut Vec<DebugPoint>,
) {
for particle in particles {
if !particle.enabled {
continue;
}
if mode.contains(MpmDebugRenderMode::PARTICLES) {
points.push(DebugPoint {
point: particle.position,
color: if particle.fixed {
PARTICLE_FIXED_COLOR
} else {
PARTICLE_COLOR
},
});
}
if mode.contains(MpmDebugRenderMode::PARTICLE_VELOCITIES) {
lines.push(DebugLine {
a: particle.position,
b: particle.position + particle.velocity * velocity_scale,
color: PARTICLE_VELOCITY_COLOR,
});
}
if mode.contains(MpmDebugRenderMode::PARTICLE_CDF) && particle.cdf_affinity != 0 {
lines.push(DebugLine {
a: particle.position,
b: particle.position + particle.cdf_normal * particle.radius * 4.0,
color: PARTICLE_CDF_COLOR,
});
}
}
}
pub fn render_grid(
grid: &DebugGrid,
mode: MpmDebugRenderMode,
velocity_scale: f32,
lines: &mut Vec<DebugLine>,
points: &mut Vec<DebugPoint>,
) {
if mode.contains(MpmDebugRenderMode::GRID_BLOCKS) {
for block in &grid.blocks {
let color = if block.num_particles > 0 {
BLOCK_COLOR
} else {
BLOCK_EMPTY_COLOR
};
push_box(block.mins, block.maxs, color, lines);
}
}
if !mode.intersects(MpmDebugRenderMode::GRID_NODES | MpmDebugRenderMode::GRID_VELOCITIES) {
return;
}
for node in &grid.nodes {
if mode.contains(MpmDebugRenderMode::GRID_NODES) {
points.push(DebugPoint {
point: node.position,
color: NODE_COLOR,
});
}
if mode.contains(MpmDebugRenderMode::GRID_VELOCITIES) {
lines.push(DebugLine {
a: node.position,
b: node.position + node.velocity * velocity_scale,
color: NODE_VELOCITY_COLOR,
});
}
}
}