import { RegisterComponent } from '@feng3d/ecs'; import { Material, Mesh } from '../../thirdparty/three/imports'; import { Camera3D } from '../cameras/Camera3D'; import { BufferGeometry3D } from '../core/BufferGeometry3D'; import { Component3D } from '../core/Component3D'; import { Node3D } from '../core/Node3D'; import { Material3D } from '../materials/Material3D'; import { WebGLRenderer3D } from '../renderers/WebGLRenderer3D'; import { Scene3D } from '../scenes/Scene3D'; declare module '@feng3d/ecs' { interface ComponentMap { Mesh3D: Mesh3D; } } /** * 包装`three`中`Mesh` */ @RegisterComponent({ name: 'Mesh3D' }) export class Mesh3D extends Component3D { _mesh: Mesh; get geometry() { if (this._mesh) { this._geometry = BufferGeometry3D.get(this._mesh.geometry); } return this._geometry; } set geometry(v) { this._geometry = v; if (this._mesh) { this._mesh.geometry = v._geometry; } } private _geometry: BufferGeometry3D; get material() { if (this._mesh) { this._material = Material3D.get(this._mesh.material as Material); } return this._material; } set material(v) { this._material = v; if (this._mesh) { this._mesh.material = v._material; } } private _material: Material3D; get materials() { if (this._mesh) { const materials = this._mesh.material as Material[]; this._materials = materials.map((v) => Material3D.get(v)); } return this._materials; } set materials(v) { this._materials = v; if (this._mesh) { this._mesh.material = v.map((v) => v._material); } } private _materials: Material3D[]; get receiveShadow() { return this._mesh.receiveShadow; } set receiveShadow(v) { this._mesh.receiveShadow = v; } get castShadow() { return this._mesh.castShadow; } set castShadow(v) { this._mesh.castShadow = v; } get matrixAutoUpdate() { return this._mesh.matrixAutoUpdate; } set matrixAutoUpdate(v) { this._mesh.matrixAutoUpdate = v; } get renderOrder() { return this._mesh.renderOrder; } set renderOrder(v) { this._mesh.renderOrder = v; } init() { super.init(); if (!this._mesh) { if (this._materials) { const materials = this._materials.map((v) => v._material); this._mesh = new Mesh(this.geometry?._geometry, materials); } else { this._mesh = new Mesh(this.geometry?._geometry, this.material?._material); } } this._entity._group.add(this._mesh); this._entity.isMesh = true; } destroy(): void { this._entity._group.remove(this._mesh); this._mesh = null; this._entity.isMesh = false; super.destroy(); } onAfterRender(renderer: WebGLRenderer3D, scene: Scene3D, camera: Camera3D, geometry: BufferGeometry3D, material: Material3D, group: Node3D) { this._mesh.onAfterRender(renderer._webGLRenderer, scene._scene, camera._camera, geometry._geometry, material._material, group._group); } _set(mesh: Mesh) { if (this._mesh) { this._entity._group.remove(this._mesh); } this._mesh = mesh; if (this._mesh) { this._entity._group.add(this._mesh); } } static get(mesh: Mesh) { let mesh3D = this._map.get(mesh); if (!mesh3D) { mesh3D = new Node3D().addComponent('Mesh3D'); // mesh3D.entity.position = mesh.position; mesh3D.entity.scale = mesh.scale; mesh3D.entity.rotation = mesh.rotation; // mesh.position.set(0, 0, 0); mesh.rotation.set(0, 0, 0); mesh.scale.set(1, 1, 1); // mesh3D._set(mesh); // this._map.set(mesh, mesh3D); } return mesh3D; } protected static _map = new Map(); }