import { Euler, Object3D, Quaternion, Vector3 } from "three";
import { type AssetReference } from "./engine_addressables.js";
import { Context } from "./engine_setup.js";
import { type Constructor, type IComponent as Component, type IComponent, type IGameObject as GameObject, type UIDProvider } from "./engine_types.js";
export type IInstantiateOptions = {
    idProvider?: UIDProvider;
    parent?: string | Object3D;
    /** position in local space. Set `keepWorldPosition` to true if this is world space */
    position?: Vector3 | [number, number, number];
    /** for duplicatable parenting */
    keepWorldPosition?: boolean;
    /** rotation in local space. Set `keepWorldPosition` to true if this is world space */
    rotation?: Quaternion | Euler | [number, number, number];
    scale?: Vector3 | [number, number, number];
    /** if the instantiated object should be visible */
    visible?: boolean;
    context?: Context;
    /** If true the components will be cloned as well
     * @default true
     */
    components?: boolean;
};
/**
 * Instantiation options for {@link syncInstantiate}
 */
export declare class InstantiateOptions implements IInstantiateOptions {
    idProvider?: UIDProvider | undefined;
    parent?: string | undefined | Object3D;
    keepWorldPosition?: boolean;
    position?: Vector3 | [number, number, number] | undefined;
    rotation?: Quaternion | Euler | [number, number, number] | undefined;
    scale?: Vector3 | [number, number, number] | undefined;
    visible?: boolean | undefined;
    context?: Context | undefined;
    components?: boolean | undefined;
    clone(): InstantiateOptions;
    /** Copy fields from another object, clone field references */
    cloneAssign(other: InstantiateOptions | IInstantiateOptions): void;
}
export declare function isActiveSelf(go: Object3D): boolean;
export declare function setActive(go: Object3D, active: boolean | number): boolean;
export declare function isActiveInHierarchy(go: Object3D): boolean;
export declare function markAsInstancedRendered(go: Object3D, instanced: boolean): void;
export declare function isUsingInstancing(instance: Object3D): boolean;
export declare function findByGuid(guid: string, hierarchy: Object3D): GameObject | IComponent | null | undefined;
export declare function isDestroyed(go: Object3D): boolean;
export declare function setDestroyed(go: Object3D, value: boolean): void;
/** Mark an Object3D or component as not destroyable
 * @param instance the object to be marked as not destroyable
 * @param value true if the object should not be destroyed in `destroy`
 */
export declare function setDontDestroy(instance: Object3D | Component, value?: boolean): void;
/**
 * Destroys a GameObject or Component, removing it from the scene and cleaning up resources.
 * Calls `onDisable()` and `onDestroy()` lifecycle methods on all affected components.
 *
 * @param instance The Object3D or Component to destroy
 * @param recursive If true (default), also destroys all children recursively
 * @param dispose If true, also disposes GPU resources (geometries, materials, textures)
 *
 * @example Destroy an object
 * ```ts
 * import { destroy } from "@needle-tools/engine";
 * destroy(this.gameObject);
 * ```
 *
 * @example Destroy with resource disposal
 * ```ts
 * destroy(myObject, true, true); // recursive + dispose GPU resources
 * ```
 *
 * @see {@link GameObject.destroy} for the static method equivalent
 * @see {@link setDontDestroy} to mark objects as non-destroyable
 */
export declare function destroy(instance: Object3D | Component, recursive?: boolean, dispose?: boolean): void;
declare type ForEachComponentCallback = (comp: Component) => any;
/**
 * Iterates over all components on an Object3D and optionally its children.
 * The callback can return a value to stop iteration early.
 *
 * @param instance The Object3D to iterate components on
 * @param cb Callback function called for each component. Return a value to stop iteration.
 * @param recursive If true (default), also iterates components on all children
 * @returns The first non-undefined value returned by the callback, or undefined
 *
 * @example Find first Rigidbody in hierarchy
 * ```ts
 * const rb = foreachComponent(myObject, comp => {
 *   if (comp instanceof Rigidbody) return comp;
 * });
 * ```
 */
export declare function foreachComponent(instance: Object3D, cb: ForEachComponentCallback, recursive?: boolean): any;
export declare function foreachComponentEnumerator<T extends IComponent>(instance: Object3D, type?: Constructor<T>, includeChildren?: boolean, maxLevel?: number, _currentLevel?: number): Generator<T>;
declare type ObjectCloneReference = {
    readonly original: object;
    readonly clone: object;
};
declare type InstantiateReferenceMap = Record<string, ObjectCloneReference>;
/**
 * Provides access to the instantiated object and its clone
 */
export declare type InstantiateContext = Readonly<InstantiateReferenceMap>;
/**
 * Creates a copy (clone) of a GameObject or loads and instantiates an AssetReference.
 * All components on the original object are cloned and `awake()` is called on them.
 *
 * @param instance The Object3D to clone, or an AssetReference to load and instantiate
 * @param opts Optional instantiation settings (position, rotation, scale, parent)
 * @returns The cloned GameObject, or a Promise<Object3D> if instantiating from AssetReference
 *
 * @example Clone an object
 * ```ts
 * import { instantiate } from "@needle-tools/engine";
 * const clone = instantiate(original);
 * clone.position.set(1, 0, 0);
 * this.context.scene.add(clone);
 * ```
 *
 * @example Instantiate with options
 * ```ts
 * const clone = instantiate(original, {
 *   parent: parentObject,
 *   position: new Vector3(0, 1, 0),
 *   rotation: new Quaternion()
 * });
 * ```
 *
 * @example Instantiate from AssetReference
 * ```ts
 * const instance = await instantiate(myAssetRef);
 * if (instance) this.context.scene.add(instance);
 * ```
 *
 * @see {@link GameObject.instantiate} for the static method equivalent
 * @see {@link destroy} to remove instantiated objects
 */
export declare function instantiate(instance: AssetReference, opts?: IInstantiateOptions | null): Promise<Object3D | null>;
export declare function instantiate(instance: GameObject | Object3D, opts?: IInstantiateOptions | null): GameObject;
export {};
