🚀 Auto-deploy: BrainWind atualizado em 01/09/2026 14:55:28

This commit is contained in:
2026-09-01 14:55:28 +00:00
parent 02811b09a4
commit 7b179aaeea
2 changed files with 59 additions and 22 deletions
+44 -10
View File
@@ -138,24 +138,58 @@ function ShelterModel({
{/* Parede Lateral Direita (X = +halfW) */} {/* Parede Lateral Direita (X = +halfW) */}
{renderWallWithGap(depth, height, rightClosure, 'distributed', Math.PI / 2, [halfW, 0, 0])} {renderWallWithGap(depth, height, rightClosure, 'distributed', Math.PI / 2, [halfW, 0, 0])}
{/* Seta de Vento Global (Sempre visível para não pular de posição) */} {/* Setas de Vento Global (0°, 45°, 90°) */}
<group> {[
{
angle: 0,
label: 'Vento 0°',
target: [0, height * 1.5 - 1.5, -halfD - 4] as [number, number, number],
direction: [0, 0, 1] as [number, number, number],
textPos: [0, height * 1.5, -halfD - 6] as [number, number, number],
textRot: [0, Math.PI, 0] as [number, number, number],
},
{
angle: 45,
label: 'Vento 45°',
target: [-halfW - 3, height * 1.5 - 1.5, -halfD - 3] as [number, number, number],
direction: [0.707, 0, 0.707] as [number, number, number],
textPos: [-halfW - 5, height * 1.5, -halfD - 5] as [number, number, number],
textRot: [0, Math.PI * 0.75, 0] as [number, number, number],
},
{
angle: 90,
label: 'Vento 90°',
target: [-halfW - 4, height * 1.5 - 1.5, 0] as [number, number, number],
direction: [1, 0, 0] as [number, number, number],
textPos: [-halfW - 6, height * 1.5, 0] as [number, number, number],
textRot: [0, Math.PI / 2, 0] as [number, number, number],
}
].map((arrow) => {
const isActive = windAngle === arrow.angle;
const arrowColor = isActive ? (isDark ? '#60a5fa' : '#2563eb') : (isDark ? '#475569' : '#94a3b8');
return (
<group key={`wind-${arrow.angle}`}>
<GlobalWindArrow <GlobalWindArrow
target={[0, height * 1.5 - 1.5, -halfD - 8 + 2]} target={arrow.target}
direction={[0, 0, 1]} direction={arrow.direction}
scale={3.2} scale={isActive ? 3.2 : 2.0}
color={arrowColor}
opacity={isActive ? 1 : 0.3}
/> />
<Text <Text
position={[0, height * 1.5, -halfD - 8]} position={arrow.textPos}
rotation={[0, Math.PI, 0]} rotation={arrow.textRot}
fontSize={0.96} fontSize={isActive ? 0.96 : 0.75}
color={isDark ? '#60a5fa' : '#2563eb'} color={arrowColor}
fillOpacity={isActive ? 1 : 0.5}
anchorX="center" anchorX="center"
anchorY="bottom" anchorY="bottom"
> >
Vento {arrow.label}
</Text> </Text>
</group> </group>
);
})}
{/* Partículas de Ar */} {/* Partículas de Ar */}
{isAirflow && ( {isAirflow && (
+7 -4
View File
@@ -8,11 +8,14 @@ export interface WindArrowProps {
direction: THREE.Vector3 | [number, number, number]; direction: THREE.Vector3 | [number, number, number];
/** Fator de escala da seta (default: 1) */ /** Fator de escala da seta (default: 1) */
scale?: number; scale?: number;
/** Cor da seta */
color?: string;
/** Opacidade da seta (0 a 1) */
opacity?: number;
} }
export function WindArrow({ target, direction, scale = 1 }: WindArrowProps) { export function WindArrow({ target, direction, scale = 1, color = '#3b82f6', opacity = 1 }: WindArrowProps) {
const length = 2.5 * scale; // Tamanho visual fixo const length = 2.5 * scale; // Tamanho visual fixo
const color = '#3b82f6'; // Azul padrão do vento
const targetVec = target instanceof THREE.Vector3 ? target : new THREE.Vector3(...target); const targetVec = target instanceof THREE.Vector3 ? target : new THREE.Vector3(...target);
const dirVec = direction instanceof THREE.Vector3 ? direction : new THREE.Vector3(...direction); const dirVec = direction instanceof THREE.Vector3 ? direction : new THREE.Vector3(...direction);
@@ -46,13 +49,13 @@ export function WindArrow({ target, direction, scale = 1 }: WindArrowProps) {
{shaftLength > 0 && ( {shaftLength > 0 && (
<mesh position={midPoint.toArray()} rotation={rotation} castShadow> <mesh position={midPoint.toArray()} rotation={rotation} castShadow>
<cylinderGeometry args={[shaftRadius, shaftRadius, shaftLength, 12]} /> <cylinderGeometry args={[shaftRadius, shaftRadius, shaftLength, 12]} />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} transparent={opacity < 1} opacity={opacity} />
</mesh> </mesh>
)} )}
{/* Ponta da seta (cone) */} {/* Ponta da seta (cone) */}
<mesh position={[end.x, end.y, end.z]} rotation={rotation} castShadow> <mesh position={[end.x, end.y, end.z]} rotation={rotation} castShadow>
<coneGeometry args={[headRadius, headLen, 12]} /> <coneGeometry args={[headRadius, headLen, 12]} />
<meshStandardMaterial color={color} /> <meshStandardMaterial color={color} transparent={opacity < 1} opacity={opacity} />
</mesh> </mesh>
</group> </group>
); );