import { IMaterial, IMaterialEventMap, IMaterialSetDirtyOptions } from './IMaterial';
import { Box3, EventListener2, Material, Object3D, Object3DEventMap, Sphere, Vector3 } from 'three';
import { ChangeEvent, IUiConfigContainer, UiObjectConfig } from 'uiconfig.js';
import { IGeometry, IGeometryEventMap, IGeometrySetDirtyOptions } from './IGeometry';
import { IImportResultUserData } from '../assetmanager';
import { GLTF } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { ICamera, ICameraSetDirtyOptions } from './ICamera';
export interface IObject3DEventMap extends Object3DEventMap {
    dispose: {
        bubbleToParent: false;
    };
    materialUpdate: {
        material: IMaterial | IMaterial[];
    } & IMaterialSetDirtyOptions;
    objectUpdate: {
        object: IObject3D;
        args?: any[];
        bubbleToParent: boolean;
    } & Omit<IObjectSetDirtyOptions, 'bubbleToParent'>;
    textureUpdate: IMaterialEventMap['textureUpdate'];
    geometryChanged: {
        object: IObject3D;
        geometry: IGeometry | null;
        oldGeometry: IGeometry | null;
        bubbleToParent: boolean;
    };
    materialChanged: {
        object: IObject3D;
        material: IMaterial | IMaterial[] | null;
        oldMaterial: IMaterial | IMaterial[] | null;
        bubbleToParent: boolean;
    };
    texturesChanged: Omit<IMaterialEventMap['texturesChanged'], 'material'> & {
        object: IObject3D;
        bubbleToParent: boolean;
    };
    geometryUpdate: {
        object: IObject3D;
        geometry: IGeometry;
        bubbleToParent: boolean;
    } & IGeometrySetDirtyOptions;
    added: {};
    removed: {};
    beforeDeserialize: {
        material: IMaterial;
    } & IMaterialEventMap['beforeDeserialize'];
    setView: {
        ui?: boolean;
        camera: ICamera;
        bubbleToParent: boolean;
    };
    activateMain: {
        ui?: boolean;
        /**
         * Set to the camera being activated as main camera.
         * If null, the default camera will be set
         * If undefined, the last activated camera will be set, or the default camera if no camera was activated before.
         */
        camera?: ICamera | null | undefined;
        bubbleToParent: boolean;
    };
    cameraUpdate: {
        ui?: boolean;
        camera?: ICamera;
        bubbleToParent: boolean;
    } & Omit<ICameraSetDirtyOptions, 'bubbleToParent'>;
    parentRootChanged: {
        object: IObject3D;
        oldParentRoot: IObject3D | undefined;
        bubbleToParent: boolean;
    };
    select: {
        ui?: boolean;
        focusCamera?: boolean;
        bubbleToParent?: boolean;
        object: IObject3D;
        trackUndo?: boolean;
        value?: IObject3D | null;
        source?: string;
    };
}
export interface ISetDirtyCommonOptions {
    /**
     * Trigger UI Config Refresh along with setDirty.
     * Default `true`. Set to `false` to prevent UI Config refresh.
     */
    refreshUi?: boolean;
    /**
     * Enable/disable frame fade using {@link FrameFadePlugin}
     * Default `true`. when the plugin is enabled and has corresponding flags enabled
     */
    frameFade?: boolean;
    /**
     * Duration for `frameFade` in ms. Check {@link FrameFadePlugin} for more details.
     */
    fadeDuration?: number;
    /**
     * Event from uiconfig.js when some value changes from the UI.
     */
    uiChangeEvent?: ChangeEvent;
    /**
     * Source identifier of who is triggering the event. so that recursive events can be prevented
     */
    source?: string;
    /**
     * Key to identify the change. This is used to identify the change in the event. Can be used interchangeably with {@link change}.
     * Set from `onChange3` etc.
     */
    key?: string;
    /**
     * New value that triggered the change. Set from `onChange3` etc.
     */
    value?: any;
    /**
     * Old value before the change. Set from `onChange3` etc.
     */
    oldValue?: any;
    /**
     * Set to true if this is the last value in a user input chain. (like when mouse up on slider)
     */
    last?: boolean;
    /**
     * Indicates that this change in from an `undo` operation.
     */
    undo?: boolean;
}
export interface IObjectSetDirtyOptions extends ISetDirtyCommonOptions {
    /**
     * Bubble event to parent root(scene).
     */
    bubbleToParent?: boolean;
    /**
     * Change identifier that triggered the `setDirty` call.
     * This is different from `key` in that it is used to identify the property/key that is changed. In many cases these could be same, but they could also be different eg, key might be x, with change being position.
     */
    change?: string | keyof IObject3D;
    /**
     * Update scene(bounds, shadows, plugins, etc) after setting dirty.
     */
    refreshScene?: boolean;
    /**
     * Indicate whether the geometry has been changed to properly refresh plugins like ground, shadows.
     */
    geometryChanged?: boolean;
    /**
     * update scene after setting dirty
     *
     * @deprecated use {@link refreshScene} instead
     */
    sceneUpdate?: boolean;
}
export interface IObjectProcessor {
    processObject: (object: IObject3D) => void;
}
export interface IObject3DUserData extends IImportResultUserData {
    uuid?: string;
    /**
     * When true, this object will not be exported when exporting the scene with {@link AssetExporter.exportObject}
     */
    excludeFromExport?: boolean;
    autoCentered?: boolean;
    isCentered?: boolean;
    autoScaleRadius?: number;
    autoScaled?: boolean;
    geometriesCentered?: boolean;
    /**
     * should this object be taken into account when calculating bounding box, default true
     */
    bboxVisible?: boolean;
    /**
     * Is centered in a parent object.
     */
    pseudoCentered?: boolean;
    license?: string;
    /**
     * When false, this object will not be selectable when clicking on it.
     */
    userSelectable?: boolean;
    /**
     * Disables `bubbleToParent` in setDirty calls on the object. As an effect scene, viewer are not updated on property change. See progressive-hdr-shadows-exp or any baker.
     */
    autoUpdateParent?: boolean;
    /**
     * For Physics plugins
     */
    physicsMass?: number;
    /**
     * see {@link GLTFAnimationPlugin}
     */
    gltfAnim_SyncMaxDuration?: boolean;
    /**
     * Automatically register this object in the {@link AssetManager} when added to the scene.
     * This provides hook to other plugins to extend the object, add uiconfig, etc.
     * @default true
     */
    autoRegisterInManager?: boolean;
    /**
     * Settings for TransformControls2 when this object is selected. See {@link TransformControlsPlugin}
     */
    transformControls?: {
        showX?: boolean;
        showY?: boolean;
        showZ?: boolean;
        translationSnap?: number;
        rotationSnap?: number;
        scaleSnap?: number;
        space?: 'local' | 'world';
        mode?: 'translate' | 'rotate' | 'scale';
        lockProps?: string[];
    };
    /**
     * is it modelRoot in RootScene, used during serialization nad traversing ancestors
     */
    rootSceneModelRoot?: boolean;
    __gltfAsset?: GLTF['asset'];
    __gltfExtras?: GLTF['userData'];
    /**
     * Auto dispose when removed from the scene.
     * Note - this is only used when {@link Object3DManager.autoDisposeObjects} is `true`
     * @default true
     */
    disposeOnIdle?: boolean;
    /**
     * List of properties that will be saved in the glb files when this object is saved.
     * The other properties are expected to be loaded/filled at runtime by default values or from an external object loaded from {@link IImportResultUserData.rootPath}.
     * Note - this is not implemented, added to userData for future.
     */
    sProperties?: string[];
    /**
     * @deprecated
     */
    dispose?: any;
    /**
     * @deprecated
     */
    setMaterial?: any;
    /**
     * @deprecated
     */
    setGeometry?: any;
    /**
     * @deprecated
     */
    setDirty?: any;
    /**
     * Used in {@link GLTFObject3DExtrasExtension} and {@link iObjectCommons.upgradeObject3D}
     */
    __keepShadowDef?: boolean;
    /**
     * Events that should be bubbled to parent root without the need to set bubbleToParent in the event.
     * todo: remove support for this
     */
    __autoBubbleToParentEvents?: string[];
    [key: string]: any;
}
export interface IObjectExtension {
    uuid: string;
    /**
     * Function to check if this object extension is compatible with the given object.
     * If not compatible, the object extension will not be added to the object.
     * This is only checked when the extension is registered.
     *
     * The extension is assumed to be compatible if this function is not defined
     * @param object
     */
    isCompatible?: (object: IObject3D) => boolean | undefined;
    /**
     * Function to return the UI config for this material extension.
     * This is called once when the material extension is registered.
     * @param material
     */
    getUiConfig?: (material: IObject3D, refreshUi?: UiObjectConfig['uiRefresh']) => (UiObjectConfig['children'] | undefined);
    /**
     * Function to be called when the object the extension is added on the object. This generally happens when either the object is registered or extnsion is added
     * @param object
     */
    onRegister?: (object: IObject3D) => void;
}
export interface IObject3D<TE extends IObject3DEventMap = IObject3DEventMap, TG extends IGeometry | undefined = IGeometry | undefined, TM extends IMaterial | IMaterial[] | undefined = IMaterial | IMaterial[] | undefined> extends Object3D<TE>, IUiConfigContainer {
    assetType?: 'model' | 'light' | 'camera' | 'widget';
    readonly isObject3D: true;
    geometry?: TG;
    material?: TM;
    /**
     * Same as material but always returns an array.
     * To set, just set `material` property
     */
    readonly materials?: IMaterial[];
    currentMaterial?: IMaterial | IMaterial[] | null;
    morphTargetDictionary?: Record<string, number>;
    morphTargetInfluences?: number[];
    updateMorphTargets?(): void;
    _currentGeometry?: IGeometry | null;
    /**
     * Dispatches 'objectUpdate' event on object.
     * @param e
     */
    setDirty?(e?: IObjectSetDirtyOptions): void;
    /**
     * Parent/Ancestor of this object to bubble events to. This is set internally by setupObject3D.
     */
    parentRoot?: IObject3D | null;
    uiConfig?: UiObjectConfig;
    refreshUi?(): void;
    userData: IObject3DUserData;
    /**
     * Scales the object to fit the given radius.
     *
     * @param autoScaleRadius - optional (taken from userData.autoScaleRadius by default)
     * @param isCentered - optional (taken from userData.isCentered by default)
     * @param setDirty - true by default
     * @param undo - undo any previous autoScale operation
     */
    autoScale?(autoScaleRadius?: number, isCentered?: boolean, setDirty?: boolean, undo?: boolean): void;
    /**
     * Moves the bounding box center of the object to the center of the world
     *
     * @param setDirty - calls {@link setDirty} @default true
     * @param undo - undo any previous autoCenter operation
     */
    autoCenter?(setDirty?: boolean, undo?: boolean): void;
    /**
     * Moves the object pivot to the center of the bounding box.
     *
     * The object will rotate around the new pivot.
     *
     * @param setDirty - calls {@link setDirty} @default true
     * @returns undo function
     */
    pivotToBoundsCenter?(setDirty?: boolean): () => void;
    /**
     * Moves the object pivot to the given point
     *
     * The object will rotate around the new pivot.
     *
     * @param point - point to move the pivot to
     * @param setDirty - calls {@link setDirty} @default true
     * @param compensateSharedGeometry - adjust positions of other meshes sharing the same geometry so they stay in place @default true
     * @returns undo function
     */
    pivotToPoint?(point: Vector3, setDirty?: boolean, compensateSharedGeometry?: boolean): this;
    objectProcessor?: IObjectProcessor;
    objectExtensions?: IObjectExtension[];
    /**
     * @param removeFromParent - remove from parent. Default true
     */
    dispose?(removeFromParent?: boolean): any;
    /**
     * A promise can be set by the object to indicate that the object is loading.
     * This can be used by the scene, viewer, plugins to defer actions until the object is loaded.
     */
    _loadingPromise?: Promise<any>;
    /**
     * For InstancedMesh, SkinnedMesh etc
     */
    boundingBox?: Box3 | null;
    /**
     * For InstancedMesh, SkinnedMesh etc
     */
    boundingSphere?: Sphere | null;
    /**
     * For InstancedMesh, SkinnedMesh etc
     * Computes bounding box, updating {@link boundingBox | .boundingBox} attribute.
     * @remarks Bounding boxes aren't computed by default. They need to be explicitly computed, otherwise they are `null`.
     */
    computeBoundingBox?(): void;
    /**
     * For InstancedMesh, SkinnedMesh etc
     * Computes bounding sphere, updating {@link boundingSphere | .boundingSphere} attribute.
     * @remarks bounding spheres aren't computed by default. They need to be explicitly computed, otherwise they are `null`.
     */
    computeBoundingSphere?(): void;
    /**
     * For LineSegments, Line2 etc
     */
    computeLineDistances?(): void;
    /**
     * Set to `false` to disable propagation of any events from its children.
     */
    acceptChildEvents?: boolean;
    /**
     * Set to `false` to disable automatic call of `upgradeObject3D` when a child is added.
     */
    autoUpgradeChildren?: boolean;
    /**
     * Required for Light shadows and plugins like DepthBufferPlugin
     */
    customDepthMaterial?: Material;
    /**
     * Required for PointLight shadows
     */
    customDistanceMaterial?: Material;
    /**
     * Required for plugins like GBufferPlugin
     */
    customGBufferMaterial?: Material;
    /**
     * Required for plugins like NormalBufferPlugin
     */
    customNormalMaterial?: Material;
    /**
     * If this is set, it will be returned when accessing `material` property.
     * see {@link GBufferRenderPass} for sample usage
     */
    forcedOverrideMaterial?: Material | Material[];
    /**
     * If this is set, it will be returned when accessing `geometry` property.
     */
    forcedOverrideGeometry?: IGeometry;
    /**
     * Traverse only upgraded objects with extra options
     * @param callback
     * @param options - visible: traverse only visible objects, widgets: traverse widgets also
     */
    traverseModels?(callback: (object: IObject3D) => boolean | void, options: {
        visible: boolean;
        widgets: boolean;
        [key: string]: any;
    }): void;
    isLight?: boolean;
    isCamera?: boolean;
    isMesh?: boolean;
    isMeshLine?: boolean;
    isLine?: boolean;
    isLine2?: boolean;
    isLineSegments?: boolean;
    isLineSegments2?: boolean;
    isWireframe?: boolean;
    isScene?: boolean;
    isWidget?: boolean;
    isPoints?: boolean;
    isDirectionalLight?: boolean;
    isPointLight?: boolean;
    isSpotLight?: boolean;
    isHemisphereLight?: boolean;
    isAmbientLight?: boolean;
    isRectAreaLight?: boolean;
    isSkinnedMesh?: boolean;
    isInstancedMesh?: boolean;
    /**
     * @internal - store for the actual material. see also {@link currentMaterial}
     */
    ['_currentMaterial']?: IMaterial | IMaterial[] | null;
    /**
     * @internal - store for the actual customDepthMaterial
     */
    ['_customDepthMaterial']?: Material;
    /**
     * @internal - store for the actual customNormalMaterial
     */
    ['_customNormalMaterial']?: Material;
    /**
     * @internal - store for the actual customGBufferMaterial
     */
    ['_customGBufferMaterial']?: Material;
    /**
     * @internal - for embedded objects
     */
    ['_onGeometryUpdate']?: EventListener2<'geometryUpdate', IGeometryEventMap, IGeometry>;
    /**
     * @internal - for embedded objects
     */
    ['_rootPathRefreshed']?: boolean;
    /**
     * @internal - when embedded objects are loading
     */
    ['_rootPathRefreshing']?: boolean;
    /**
     * If this is present, only the objects in this array will be saved in the glb/gltf files, and the object.children array will be ignored.
     * The other properties are expected to be loaded/filled at runtime by default values or from an external asset loaded from {@link IImportResultUserData.rootPath}.
     * @internal - for embedded objects.
     */
    ['_sChildren']?: Object3D[];
    /**
     * If an object has been converted to IObject3D using `upgradeObject3D`, this flag is set to true.
     * @internal
     */
    __objectSetup?: boolean;
    /**
     * If a mesh has been converted to IObject3D using `upgradeObject3D`, this flag is set to true.
     * @internal
     */
    __meshSetup?: boolean;
    traverse(callback: (object: IObject3D) => void): void;
    traverseVisible(callback: (object: IObject3D) => void): void;
    traverseAncestors(callback: (object: IObject3D) => void): void;
    getObjectById(id: number): IObject3D | undefined;
    getObjectByName(name: string): IObject3D | undefined;
    getObjectByProperty(name: string, value: string): IObject3D | undefined;
    parent: IObject3D | null;
    children: IObject3D[];
}
export interface IMesh<TE extends IObject3DEventMap = IObject3DEventMap, TG extends IGeometry = IGeometry, TM extends IMaterial | IMaterial[] = IMaterial | IMaterial[]> extends IObject3D<TE, TG, TM>, IUiConfigContainer {
    geometry: TG;
    material: TM;
}
//# sourceMappingURL=../src/core/IObject.d.ts.map