UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

138 lines (103 loc) 3.83 kB
import { Mesh, SkinnedMesh } from "three"; import { returnTrue } from "../../../../core/function/returnTrue.js"; const stack = []; export class ThreeBypassRenderer { constructor() { /** * * @type {WeakMap<THREE.Object3D, THREE.Object3D>} * @private */ this.__object_map = new WeakMap(); } /** * * @param {Mesh|SkinnedMesh} source * @return {Mesh|SkinnedMesh} * @private */ __get_object_twin(source) { const existing = this.__object_map.get(source); if (existing !== undefined) { return existing; } let mesh; const geometry = source.geometry; if (source.isSkinnedMesh) { mesh = new SkinnedMesh(geometry, null); } else { mesh = new Mesh(geometry, null); } mesh.matrixAutoUpdate = false; mesh.matrixWorldNeedsUpdate = false; mesh.frustumCulled = false; this.__object_map.set(source, mesh); return mesh; } /** * * @param {THREE.Object3D} scene * @param {THREE.Object3D[]} input * @param {number} input_size * @param {function(THREE.Object3D):boolean} input_filter * @param {function(THREE.Object3D):boolean} object_filter * @param {function(THREE.Object3D):THREE.Material} material_extractor * @param {*} [material_extractor_context] */ build_scene({ scene, input, input_size, input_filter = returnTrue, object_filter, material_extractor, material_extractor_context }) { // prepare shadow scene const scene_children = scene.children; scene_children.length = 0; let stack_top = 0; let j = 0; let i = 0; for (; i < input_size; i++) { const object3D = input[i]; if (input_filter(object3D)) { stack[stack_top++] = object3D; } } while (stack_top > 0) { const object3D = stack[--stack_top]; if ( object_filter(object3D) ) { if (object3D.isMesh) { const geometry = object3D.geometry; if (geometry !== null) { const mesh = this.__get_object_twin(object3D); const material = material_extractor.call(material_extractor_context, object3D); mesh.geometry = geometry; mesh.material = material; if (object3D.isSkinnedMesh) { mesh.bindMatrix.copy(object3D.bindMatrix); mesh.bindMatrixInverse.copy(object3D.bindMatrixInverse); mesh.skeleton = object3D.skeleton; } mesh.matrix.copy(object3D.matrix); mesh.matrixWorld.copy(object3D.matrixWorld); mesh.normalMatrix.copy(object3D.normalMatrix); scene_children[j++] = mesh; mesh.parent = scene; } } } const children = object3D.children; const child_count = children.length; for (i = 0; i < child_count; i++) { const child = children[i]; stack[stack_top++] = child; } } scene_children.length = j; } } ThreeBypassRenderer.INSTANCE = new ThreeBypassRenderer();