import Node from "../elements/Node";
import Mesh from "../elements/Mesh";
import Primitive from "../elements/Primitive";
import Camera from 'nanogl-camera';
import Material from 'nanogl-pbr/Material';
import MorphDeformer from 'nanogl-pbr/MorphDeformer';
import { GLContext } from "nanogl/types";
import Program from "nanogl/program";
import Bounds from "nanogl-pbr/Bounds";
import GLConfig from "nanogl-state/GLConfig";
import Gltf from "../Gltf";
/**
 * A MeshRenderer is a renderable object that contains a mesh and its rendering properties.
 */
export default class MeshRenderer {
    /**
     * The node that contains the mesh
     */
    readonly node: Node;
    /**
     * The mesh to render
     */
    readonly mesh: Mesh;
    private _skinDeformers;
    private _morphDeformers;
    /**
     * All the materials used by this Mesh's primitives
     */
    materials: Material[];
    /**
     * Custom GLConfig to use when rendering this mesh
     */
    glconfig?: GLConfig;
    /**
     * The bounds of this mesh
     */
    readonly bounds: Bounds;
    /**
     * @param gtlf GLTF file where this mesh comes from
     * @param node Node that contains this mesh
     */
    constructor(gtlf: Gltf, node: Node);
    /**
     * For each primitives, create a material based on primitive's material pass.
     * If skin or morph targets are present, deformers are set on the created material.
     */
    setupMaterials(gtlf: Gltf): void;
    /**
     * Configure the SkinDeformers and MorphDeformers on the material, if the node has skinning or the primitive has morph targets.
     * @param material Material to configure
     * @param primitive Primitive to get the skinning data and morph targets from
     */
    configureDeformers(material: Material, primitive: Primitive): void;
    /**
     * If the primitive has morph targets, create a nanogl-pbr MorphDeformer and add it to the material.
     * @param material Material on which the MorphDeformer will be added
     * @param primitive Primitive to get the morph targets from
     */
    configureMorph(material: Material, primitive: Primitive): void;
    /**
     * Get the morph weights from the node or the mesh and set them on the nanogl-pbr MorphDeformer.
     * @param morph MorphDeformer to set the weights on
     */
    setupMorphWeights(morph: MorphDeformer): void;
    /**
     * If the node has skinning, create a nanogl-pbr SkinDeformer and add it to the material.
     * @param material Material on which the SkinDeformer will be added
     * @param primitive Primitive to get the skinning data from (joints and weights)
     */
    configureSkin(material: Material, primitive: Primitive): void;
    /**
     * Compute the bounds of the mesh by merging the bounds of all its primitives.
     */
    computeBounds(): void;
    /**
     * Render the mesh.
     * @param gl GLContext to use for rendering
     * @param camera Camera from which the mesh will be rendered
     * @param mask Render mask to use (Opaque, Blended, ...)
     * @param passId ID of the current rendering pass (Color, Depth, ...)
     * @param glconfig Custom GLConfig to use for rendering
     */
    render(gl: GLContext, camera: Camera, mask: number, passId: string, glconfig?: GLConfig): void;
    /**
     * Draw a primitive with a program.
     * Low-level function, binding the Primitive's VAO before rendering, and unbinding it after.
     * @param camera Camera to use for rendering, unused here
     * @param prg Program to bind for rendering
     * @param sub Primitive to render
     */
    drawCall(camera: Camera, prg: Program, sub: Primitive): void;
}
