import { Mesh, MeshStandardMaterial } from 'three/webgpu'; import { DIVEComponent } from '../../engine/component/Component.ts'; import { DIVEMaterial } from '../../types/material/DIVEMaterial.ts'; /** * Base for every component that owns a mesh and its material. * * Holds only what a mesh needs whatever produced it: the mesh, the material, and * {@link setMaterial}. Where the geometry comes from is the subclass's business -- * {@link ModelComponent} loads it, {@link PrimitiveComponent} builds it, and * {@link FloorComponent} is one fixed plane. That split exists because those two * loading methods used to live here, which meant a primitive and a floor * inherited a `setFromGLTF` that would have overwritten their node's transform * with a glTF root's. * * Abstract, because a mesh component that owns no mesh has nothing to offer: the * subclass is what puts one there. * * Contributes its content to the node rather than parenting it, and tracks * exactly what it contributed -- so replacing the content leaves the node's child * nodes and every other component's content alone. * * @module */ export declare abstract class MeshComponent extends DIVEComponent { readonly isMeshComponent: true; protected _mesh: Mesh | null; protected _material: MeshStandardMaterial | null; /** * Whether the material came from {@link setMaterial} rather than from content. * * A configured material outranks whatever an asset brings, and it has to * survive a load that happens afterwards -- `setMaterial` before `setFromURL` * is the ordinary case, since the caller has the schema before the file. Only * the origin distinguishes the two: a material adopted from a previous load * must not be pushed onto the next one. */ protected _materialIsOwn: boolean; /** The first mesh found in the content, if any. */ get mesh(): Mesh | null; /** The material shared across the content, if one was set or found. */ get material(): MeshStandardMaterial | null; /** * Applies material properties, creating a material if there is none yet. * * @param material - The properties to apply. */ setMaterial(material: Partial): void; /** * Takes on the source's material, if the source configured one itself. * * Only a material from {@link setMaterial} is copied: one adopted from loaded * content belongs to that content, and the clone gets its own when it loads. * Copied into a fresh material rather than shared, so disposing either * component cannot take the other's material with it. * * @param source - The component to copy from. */ copy(source: this): this; /** * Frees everything the content this component contributed is made of. * * The policy, because releasing GPU memory needs one: a mesh component owns * the geometries, materials and textures of what it put into the node. Those * are produced per load -- the asset cache holds file bytes, not parsed * results -- so nothing here is shared with another component and there is * nothing to leave behind for someone else. * * Collected before anything is freed, and collected in sets: three allows a * mesh to carry `Material[]`, one glTF can point several meshes at the same * material, and several materials at the same texture. Disposing twice is * harmless in three, but counting once makes the intent checkable. */ dispose(): void; }