Back to home page

EIC code displayed by LXR

 
 

    


Warning, /firebird/packages/epic/src/epic-geometry-prettifier.ts is written in an unsupported language. File is not indexed.

0001 import * as THREE from "three";
0002 import { Object3D, Scene, Group, Mesh, MeshPhysicalMaterial } from "three";
0003 import { PMREMGenerator, WebGPURenderer } from "three/webgpu";
0004 
0005 /**
0006  * EIC Geometry Prettifier
0007  *
0008  * Applies advanced visual effects to geometry elements when high-quality rendering is enabled.
0009  * Uses procedural environment with studio-style lighting for reflections.
0010  */
0011 
0012 // Cached environment map
0013 let cachedEnvMap: THREE.Texture | null = null;
0014 
0015 /**
0016  * Creates a procedural environment map with gradient and bright light sources.
0017  */
0018 function createProceduralEnvironment(renderer: WebGPURenderer): THREE.Texture | null {
0019   if (!renderer) {
0020     console.warn('[EicGeometryPrettifier]: No renderer provided');
0021     return null;
0022   }
0023 
0024   if (cachedEnvMap) {
0025     return cachedEnvMap;
0026   }
0027 
0028   const envScene = new Scene();
0029 
0030   // Create gradient sphere
0031   const envGeometry = new THREE.SphereGeometry(500, 64, 64);
0032   const colors: number[] = [];
0033   const positionAttribute = envGeometry.getAttribute('position');
0034 
0035   for (let i = 0; i < positionAttribute.count; i++) {
0036     const y = positionAttribute.getY(i);
0037     const x = positionAttribute.getX(i);
0038     const z = positionAttribute.getZ(i);
0039     const t = (y + 500) / 1000;
0040 
0041     // Gradient: dark bottom to bright top
0042     const bottomColor = new THREE.Color(0x505060);
0043     const midColor = new THREE.Color(0x8090a0);
0044     const topColor = new THREE.Color(0xd0e0f0);
0045 
0046     let color: THREE.Color;
0047     if (t < 0.4) {
0048       color = bottomColor.clone().lerp(midColor, t / 0.4);
0049     } else {
0050       color = midColor.clone().lerp(topColor, (t - 0.4) / 0.6);
0051     }
0052 
0053     // Add variation
0054     const angle = Math.atan2(z, x);
0055     const variation = Math.sin(angle * 3) * 0.1 + Math.sin(angle * 7) * 0.05;
0056     color.offsetHSL(0, 0, variation);
0057 
0058     colors.push(color.r, color.g, color.b);
0059   }
0060 
0061   envGeometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 3));
0062 
0063   const envMaterial = new THREE.MeshBasicMaterial({
0064     vertexColors: true,
0065     side: THREE.BackSide
0066   });
0067 
0068   const envMesh = new Mesh(envGeometry, envMaterial);
0069   envScene.add(envMesh);
0070 
0071   // Add bright light sources
0072   const lights: { geom: THREE.BufferGeometry; mat: THREE.Material }[] = [];
0073 
0074   const addLight = (x: number, y: number, z: number, size: number, intensity: number) => {
0075     const geom = new THREE.SphereGeometry(size, 16, 16);
0076     const mat = new THREE.MeshBasicMaterial({
0077       color: new THREE.Color(intensity, intensity, intensity * 0.98)
0078     });
0079     const mesh = new Mesh(geom, mat);
0080     mesh.position.set(x, y, z);
0081     envScene.add(mesh);
0082     lights.push({ geom, mat });
0083   };
0084 
0085   // Main lights
0086   addLight(300, 350, 150, 40, 2.0);
0087   addLight(-250, 200, -200, 25, 1.5);
0088   addLight(100, -100, 350, 20, 1.2);
0089   addLight(-150, 400, 250, 30, 1.8);
0090 
0091   // Generate PMREM
0092   const pmremGenerator = new PMREMGenerator(renderer);
0093   pmremGenerator.compileEquirectangularShader();
0094   const envMap = pmremGenerator.fromScene(envScene, 0, 0.1, 1000).texture;
0095 
0096   // Cleanup
0097   pmremGenerator.dispose();
0098   envGeometry.dispose();
0099   envMaterial.dispose();
0100   lights.forEach(l => { l.geom.dispose(); l.mat.dispose(); });
0101 
0102   cachedEnvMap = envMap;
0103 
0104   return envMap;
0105 }
0106 
0107 /**
0108  * Find objects by name pattern
0109  */
0110 function findObjectsByPattern(root: Object3D, pattern: string): Object3D[] {
0111   const results: Object3D[] = [];
0112   const regex = new RegExp(pattern.replace(/\*/g, '.*'), 'i');
0113   root.traverse((child) => {
0114     if (regex.test(child.name)) {
0115       results.push(child);
0116     }
0117   });
0118   return results;
0119 }
0120 
0121 /**
0122  * Apply mirror material
0123  */
0124 function applyMirrorMaterial(
0125   objects: Object3D[],
0126   envMap: THREE.Texture | null,
0127   clippingPlanes?: THREE.Plane[]
0128 ): void {
0129   for (const obj of objects) {
0130     if (!(obj instanceof Mesh)) continue;
0131 
0132     const mirrorMaterial = new MeshPhysicalMaterial({
0133       color: 0xffffff,
0134       metalness: 1.0,
0135       roughness: 0.0,
0136       envMap: envMap,
0137       envMapIntensity: 2.5,
0138       reflectivity: 1.0,
0139       clearcoat: 1.0,
0140       clearcoatRoughness: 0.0,
0141       side: THREE.DoubleSide,
0142       clippingPlanes: clippingPlanes,
0143       clipIntersection: true,
0144     });
0145 
0146     if (obj.material) {
0147       if (Array.isArray(obj.material)) {
0148         obj.material.forEach(m => m.dispose());
0149       } else {
0150         obj.material.dispose();
0151       }
0152     }
0153 
0154     obj.material = mirrorMaterial;
0155   }
0156 
0157   if (objects.length > 0) {
0158     console.log(`[EicGeometryPrettifier]: Applied mirror material to ${objects.length} objects`);
0159   }
0160 }
0161 
0162 export interface PrettifyOptions {
0163   renderer: WebGPURenderer;
0164   sceneGeometry: Group;
0165   scene: Scene;
0166   clippingPlanes?: THREE.Plane[];
0167 }
0168 
0169 /**
0170  * Main prettify function
0171  */
0172 export async function prettify(geometry: Object3D, options: PrettifyOptions): Promise<void> {
0173   const envMap = createProceduralEnvironment(options.renderer);
0174 
0175   if (envMap && options.scene instanceof Scene) {
0176     options.scene.environment = envMap;
0177   }
0178 
0179   const drichMirrors = findObjectsByPattern(geometry, 'DRICH_mirror');
0180   applyMirrorMaterial(drichMirrors, envMap, options.clippingPlanes);
0181 }
0182 
0183 /**
0184  * Cleanup
0185  */
0186 export function disposePrettifier(): void {
0187   if (cachedEnvMap) {
0188     cachedEnvMap.dispose();
0189     cachedEnvMap = null;
0190   }
0191 }