🚀 Auto-deploy: BrainWind atualizado em 28/07/2026 12:00:29

This commit is contained in:
2026-07-28 12:00:29 +00:00
parent e8334c3603
commit ce793d2213
+54 -19
View File
@@ -21,7 +21,7 @@ interface AirflowSystemProps {
} }
export function AirflowSystem({ windAngle, width, length, height, permeabilityCase, wallCpe, roofCpe, cpi }: AirflowSystemProps) { export function AirflowSystem({ windAngle, width, length, height, permeabilityCase, wallCpe, roofCpe, cpi }: AirflowSystemProps) {
const count = 1000; const count = 400; // Quantidade reduzida
const meshRef = useRef<THREE.InstancedMesh>(null); const meshRef = useRef<THREE.InstancedMesh>(null);
const particles = useMemo(() => { const particles = useMemo(() => {
@@ -33,7 +33,7 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
Math.random() * (height * 3), Math.random() * (height * 3),
(Math.random() - 0.5) * (length * 4) (Math.random() - 0.5) * (length * 4)
), ),
baseSpeed: 0.15 + Math.random() * 0.2, baseSpeed: 0.10 + Math.random() * 0.08, // Velocidade reduzida em ~20%
wobbleSpeed: Math.random() * 0.05, wobbleSpeed: Math.random() * 0.05,
wobbleOffset: Math.random() * Math.PI * 2, wobbleOffset: Math.random() * Math.PI * 2,
currentCpe: 0, currentCpe: 0,
@@ -61,8 +61,8 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
if (!meshRef.current) return; if (!meshRef.current) return;
const time = state.clock.elapsedTime; const time = state.clock.elapsedTime;
// Agora 0° é paralelo à Parede A e bate na Parede C (Eixo X) // 0° = Eixo X
// E 90° é paralelo à Parede C e bate na Parede A (Eixo Z) // 90° = Eixo Z
const isZAxis = windAngle === 90; const isZAxis = windAngle === 90;
const windDir = isZAxis ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0); const windDir = isZAxis ? new THREE.Vector3(0, 0, 1) : new THREE.Vector3(1, 0, 0);
@@ -87,6 +87,46 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
const inY = py >= 0 && py <= height; const inY = py >= 0 && py <= height;
const aboveRoof = py > height && py <= height + 3 && inX && inZ; const aboveRoof = py > height && py <= height + 3 && inX && inZ;
// ====== FLUXO AERODINÂMICO (CONTORNO DO TELHADO) ======
// Modifica o Y para subir antes do prédio e descer na esteira de sucção
const speedModifier = Math.max(0.2, 1 - (p.currentCpe * 0.5));
const currentSpeed = p.baseSpeed * speedModifier;
if (windAngle === 0 && Math.abs(pz) < halfL + margin * 2) {
if (px < -halfW && px > -halfW - height * 2) {
// Subindo antes de bater (Barlavento)
const dist = (-halfW - px);
const lift = Math.max(0, (height - py)) / (dist + 1);
deflectY += lift * currentSpeed * 0.5;
} else if (px >= -halfW && px <= 0 && py > height - 1) {
// Subindo no telhado (1ª Água)
deflectY += currentSpeed * 0.3;
} else if (px > 0 && px <= halfW && py > height - 1) {
// Descendo no telhado (2ª Água)
deflectY -= currentSpeed * 0.2;
} else if (px > halfW && px < halfW + height * 2) {
// Turbilhão de descida (Sotavento)
deflectY -= currentSpeed * 0.3;
}
} else if (windAngle === 90 && Math.abs(px) < halfW + margin * 2) {
if (pz < -halfL && pz > -halfL - height * 2) {
// Subindo antes de bater (Barlavento)
const dist = (-halfL - pz);
const lift = Math.max(0, (height - py)) / (dist + 1);
deflectY += lift * currentSpeed * 0.5;
} else if (pz >= -halfL && pz <= 0 && py > height - 1) {
// Subindo no telhado (1ª Água)
deflectY += currentSpeed * 0.3;
} else if (pz > 0 && pz <= halfL && py > height - 1) {
// Descendo no telhado (2ª Água)
deflectY -= currentSpeed * 0.2;
} else if (pz > halfL && pz < halfL + height * 2) {
// Turbilhão de descida (Sotavento)
deflectY -= currentSpeed * 0.3;
}
}
// =======================================================
if (inY && inX && inZ) { if (inY && inX && inZ) {
// Perto das paredes // Perto das paredes
if (Math.abs(pz - (-halfL)) < margin) localCpe = wallCpe.A; if (Math.abs(pz - (-halfL)) < margin) localCpe = wallCpe.A;
@@ -95,32 +135,27 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
else if (Math.abs(px - (halfW)) < margin) localCpe = wallCpe.D; else if (Math.abs(px - (halfW)) < margin) localCpe = wallCpe.D;
else localCpe = cpi; else localCpe = cpi;
// Colisão: Expulsar as partículas do interior com força (Desvio realístico) // Colisão dura (Impede entrar na parede sólida)
const isAirtight = permeabilityCase !== 'four-equally-permeable'; const isAirtight = permeabilityCase !== 'four-equally-permeable';
if (isAirtight) { if (isAirtight) {
if (windAngle === 90 && pz < -halfL + margin) { if (windAngle === 90 && pz < -halfL + margin) {
deflectY = p.baseSpeed * 2.0; // Levanta pro telhado deflectY += p.baseSpeed * 2.0;
deflectX = px > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0; // Contorna laterais deflectX += px > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0;
p.position.z -= p.baseSpeed * 1.5; // Impede de avançar p.position.z -= p.baseSpeed * 1.5;
} else if (windAngle === 0 && px < -halfW + margin) { } else if (windAngle === 0 && px < -halfW + margin) {
deflectY = p.baseSpeed * 2.0; // Levanta pro telhado deflectY += p.baseSpeed * 2.0;
deflectZ = pz > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0; // Contorna laterais deflectZ += pz > 0 ? p.baseSpeed * 2.0 : -p.baseSpeed * 2.0;
p.position.x -= p.baseSpeed * 1.5; // Impede de avançar p.position.x -= p.baseSpeed * 1.5;
} }
} }
} else if (aboveRoof) { } else if (aboveRoof) {
localCpe = roofAvgCpe; localCpe = roofAvgCpe;
// Turbulência de vórtice severo no telhado p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.05; // Vórtice
p.position.y += Math.sin(time * 5 + p.wobbleOffset) * 0.05;
} }
// Suaviza a transição de Cpe para a cor fluir // Suaviza a transição de Cpe para a cor fluir
p.currentCpe += (localCpe - p.currentCpe) * 0.1; p.currentCpe += (localCpe - p.currentCpe) * 0.1;
// Modifica velocidade com base no Cpe (Pressão > 0 diminui, Sucção < 0 aumenta)
const speedModifier = Math.max(0.2, 1 - (p.currentCpe * 0.5));
const currentSpeed = p.baseSpeed * speedModifier;
// Move a partícula // Move a partícula
p.position.x += windDir.x * currentSpeed + deflectX; p.position.x += windDir.x * currentSpeed + deflectX;
p.position.y += deflectY; p.position.y += deflectY;
@@ -176,11 +211,11 @@ export function AirflowSystem({ windAngle, width, length, height, permeabilityCa
return ( return (
<instancedMesh ref={meshRef} args={[undefined, undefined, count]}> <instancedMesh ref={meshRef} args={[undefined, undefined, count]}>
<cylinderGeometry args={[0.02, 0.02, 1.5, 4]} /> <cylinderGeometry args={[0.01, 0.01, 1.5, 4]} /> {/* Partículas ultra finas */}
<meshBasicMaterial <meshBasicMaterial
color="#ffffff" color="#ffffff"
transparent transparent
opacity={0.7} opacity={0.6}
blending={THREE.AdditiveBlending} blending={THREE.AdditiveBlending}
depthWrite={false} depthWrite={false}
/> />