🚀 Auto-deploy: BrainWind atualizado em 28/07/2026 12:00:29
This commit is contained in:
@@ -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}
|
||||||
/>
|
/>
|
||||||
|
|||||||
Reference in New Issue
Block a user