chore(workspace): add gitea repository url to all packages
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 3m48s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 6s
Build & Deploy / 🧪 QA (push) Failing after 3m48s
Build & Deploy / 🏗️ Build (push) Has been skipped
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🧪 Post-Deploy Verification (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 4s
This commit is contained in:
126
components/home/hero-webgl/ObjectInstances.tsx
Normal file
126
components/home/hero-webgl/ObjectInstances.tsx
Normal file
@@ -0,0 +1,126 @@
|
||||
import React, { useMemo } from 'react';
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
import { SceneData, SceneNode } from './Generator';
|
||||
import * as THREE from 'three';
|
||||
|
||||
const ObjectInstances: React.FC<{ data: SceneData }> = ({ data }) => {
|
||||
// We'll separate nodes by type to feed into distinct InstancedMeshes
|
||||
const windNodes = useMemo(() => data.nodes.filter(n => n.type === 'wind'), [data]);
|
||||
const solarNodes = useMemo(() => data.nodes.filter(n => n.type === 'solar'), [data]);
|
||||
const cityNodes = useMemo(() => data.nodes.filter(n => n.type === 'city_building'), [data]);
|
||||
const treeNodes = useMemo(() => data.nodes.filter(n => n.type === 'tree'), [data]);
|
||||
const towerNodes = useMemo(() => data.nodes.filter(n => n.type === 'tower'), [data]);
|
||||
const subNodes = useMemo(() => data.nodes.filter(n => n.type === 'substation'), [data]);
|
||||
|
||||
const setMatrixAt = (mesh: THREE.InstancedMesh, i: number, node: SceneNode) => {
|
||||
const obj = new THREE.Object3D();
|
||||
obj.position.set(node.position[0], node.position[1], node.position[2]);
|
||||
obj.rotation.set(node.rotation[0], node.rotation[1], node.rotation[2]);
|
||||
obj.scale.set(node.scale[0], node.scale[1], node.scale[2]);
|
||||
obj.updateMatrix();
|
||||
mesh.setMatrixAt(i, obj.matrix);
|
||||
};
|
||||
|
||||
// Precompute instance matrices
|
||||
const windMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), windNodes.length);
|
||||
windNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [windNodes]);
|
||||
|
||||
const solarMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), solarNodes.length);
|
||||
solarNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [solarNodes]);
|
||||
|
||||
const treeMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), treeNodes.length);
|
||||
treeNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [treeNodes]);
|
||||
|
||||
const towerMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), towerNodes.length);
|
||||
towerNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [towerNodes]);
|
||||
|
||||
const subMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), subNodes.length);
|
||||
subNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [subNodes]);
|
||||
|
||||
const cityMatrices = useMemo(() => {
|
||||
const mesh = new THREE.InstancedMesh(new THREE.BoxGeometry(), new THREE.MeshBasicMaterial(), cityNodes.length);
|
||||
cityNodes.forEach((node, i) => setMatrixAt(mesh, i, node));
|
||||
mesh.instanceMatrix.needsUpdate = true;
|
||||
return mesh.instanceMatrix;
|
||||
}, [cityNodes]);
|
||||
|
||||
return (
|
||||
<group>
|
||||
{/* Trees */}
|
||||
{treeNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, treeNodes.length]} castShadow receiveShadow>
|
||||
<coneGeometry args={[1.5, 5, 4]} />
|
||||
<meshStandardMaterial color="#0b2e1b" roughness={0.9} />
|
||||
<primitive object={treeMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
|
||||
{/* Wind Turbines Towers */}
|
||||
{windNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, windNodes.length]} castShadow receiveShadow>
|
||||
<cylinderGeometry args={[0.3, 0.5, 12, 8]} />
|
||||
<meshStandardMaterial color="#ffffff" roughness={0.5} />
|
||||
<primitive object={windMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
|
||||
{/* Solar Panels */}
|
||||
{solarNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, solarNodes.length]} castShadow receiveShadow>
|
||||
<boxGeometry args={[4, 0.2, 2]} />
|
||||
<meshStandardMaterial color="#0055ff" roughness={0.2} metalness={0.8} />
|
||||
<primitive object={solarMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
|
||||
{/* City Buildings */}
|
||||
{cityNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, cityNodes.length]} castShadow receiveShadow>
|
||||
<boxGeometry args={[2, 1, 2]} />
|
||||
<meshStandardMaterial color="#1a2b4c" roughness={0.7} emissive="#002b49" emissiveIntensity={0.2} />
|
||||
<primitive object={cityMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
|
||||
{/* Substations */}
|
||||
{subNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, subNodes.length]} castShadow receiveShadow>
|
||||
<boxGeometry args={[6, 3, 6]} />
|
||||
<meshStandardMaterial color="#4a5568" roughness={0.8} metalness={0.2} />
|
||||
<primitive object={subMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
|
||||
{/* Transition Towers (Grid) */}
|
||||
{towerNodes.length > 0 && (
|
||||
<instancedMesh args={[undefined, undefined, towerNodes.length]} castShadow receiveShadow>
|
||||
<cylinderGeometry args={[0.5, 1.5, 12, 4]} />
|
||||
<meshStandardMaterial color="#a0aec0" wireframe={true} roughness={0.8} metalness={0.6} />
|
||||
<primitive object={towerMatrices} attach="instanceMatrix" />
|
||||
</instancedMesh>
|
||||
)}
|
||||
</group>
|
||||
);
|
||||
};
|
||||
|
||||
export default ObjectInstances;
|
||||
Reference in New Issue
Block a user