UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

239 lines (238 loc) • 9.58 kB
import { Object3D, Vector3 } from "three"; import { Model, Vec3 } from "../engine/engine_types.js"; import { Behaviour } from "./Component.js"; import { EventList } from "./EventList.js"; /** * Events dispatched by the DropListener component * @enum {string} */ export declare enum DropListenerEvents { /** * Dispatched when a file is dropped into the scene. The detail of the event is the {@link File} that was dropped. * The event is called once for each dropped file. */ FileDropped = "file-dropped", /** * Dispatched when a new object is added to the scene. The detail of the event contains {@link DropListenerOnDropArguments} for the content that was added. */ ObjectAdded = "object-added" } /** * Network event arguments passed between clients when using the DropListener with networking */ export declare type DropListenerNetworkEventArguments = { /** Unique identifier of the sender */ guid: string; /** Name of the dropped object */ name: string; /** URL or array of URLs to the dropped content */ url: string | string[]; /** Worldspace point where the object was placed in the scene */ point: Vec3; /** Bounding box size */ size: Vec3; /** MD5 hash of the content for verification */ contentMD5: string; }; /** * Arguments provided to handlers when an object is dropped or added to the scene */ export declare type DropListenerOnDropArguments = { /** The DropListener component that processed the drop event */ sender: DropListener; /** The root object added to the scene */ object: Object3D; /** The complete model with all associated data */ model: Model; /** MD5 hash of the content for verification */ contentMD5: string; /** The original dropped URL or File object */ dropped: URL | File | undefined; }; /** * DropListener enables drag-and-drop loading of 3D files directly into your scene. * Users can drop glTF/GLB files onto the canvas to dynamically add new objects at runtime. * * [![](https://cloud.needle.tools/-/media/p5LNPTQ0u4mRXA6WiSmzIQ.gif)](https://engine.needle.tools/samples/droplistener) * * **Supported formats:** glTF, GLB, FBX, OBJ, USDZ, VRM * * **Key features:** * - Drop files directly onto canvas or onto a specific {@link dropArea} * - Paste URLs from clipboard (Ctrl/Cmd+V) * - Auto-fit objects to a specific size with {@link fitIntoVolume} * - Network sync to share dropped objects with other users * - Special handling for GitHub and Polyhaven URLs * * **Events:** * - `file-dropped` - Fired for each dropped file * - `object-added` - Fired when object is loaded and added to scene * * **Debug:** Use `?debugdroplistener` URL parameter * * @example Listen for dropped objects * ```ts * const dropListener = myObject.addComponent(DropListener); * dropListener.useNetworking = true; * dropListener.fitIntoVolume = true; * * dropListener.on(DropListenerEvents.ObjectAdded, (evt) => { * const { object, model } = evt.detail; * console.log("Added:", object.name); * }); * ``` * * @example Load from URL programmatically * ```ts * const obj = await dropListener.loadFromURL("https://example.com/model.glb"); * ``` * Hint: We recommend to use {@link AssetReference} for preloading and referencing assets in code if you simply want to load a model. * * @summary Drag-and-drop file loading for 3D assets * @category Asset Management * @group Components * @see {@link SceneSwitcher} for loading entire scenes * @see {@link AssetReference} for preloading assets * @see {@link SyncedTransform} for networking support * @link https://engine.needle.tools/samples/droplistener for a live demo */ export declare class DropListener extends Behaviour { /** * When assigned, the DropListener will only accept files that are dropped on this specific object. * This allows creating designated drop zones in your scene. */ dropArea?: Object3D; /** * When enabled, dropped objects will be automatically scaled to fit within the volume defined by fitVolumeSize. * Useful for ensuring dropped models appear at an appropriate scale. * * **Tip**: Use the handy `fitObjectIntoVolume` function (`import { fitObjectIntoVolume } from "@needle-tools/engine"`) for custom fitting needs. * * @default false */ fitIntoVolume: boolean; /** * Defines the dimensions of the volume that dropped objects will be scaled to fit within. * Only used when fitIntoVolume is enabled. */ fitVolumeSize: Vector3; /** * When enabled, dropped objects will be positioned at the point where the cursor hit the scene. * When disabled, objects will be placed at the origin of the DropListener. * @default true */ placeAtHitPosition: boolean; /** * When enabled, the DropListener will automatically synchronize dropped files to other connected clients. * When a file is dropped locally, it will be uploaded to blob storage and the URL will be shared with other clients. * @default false */ useNetworking: boolean; /** * Event list that gets invoked after a file has been successfully added to the scene. * Receives {@link DropListenerOnDropArguments} containing the added object and related information. * @event object-added * @example * ```typescript * dropListener.onDropped.addEventListener((evt) => { * console.log("Object added", evt.model); * }); */ onDropped: EventList<DropListenerOnDropArguments>; /** * Loads a file from the given URL and adds it to the scene. * @returns A promise that resolves to the loaded object or null if loading failed. */ loadFromURL(url: string, data?: { point?: Vec3; size?: Vec3; }): Promise<Object3D | null>; /** * Forgets all previously added objects. * The droplistener will then not be able to remove previously added objects. */ forgetObjects(): void; awake(): void; /** @internal */ onEnable(): void; /** @internal */ onDisable(): void; /** * Handles network events received from other clients containing information about dropped objects * @param evt Network event data containing object information, position, and content URL */ private onNetworkEvent; /** * Handles clipboard paste events and processes them as potential URL drops * Only URLs are processed by this handler, and only when editing is allowed * @param evt The paste event */ private handlePaste; /** * Handles drag events over the renderer's canvas * Prevents default behavior to enable drop events * @param evt The drag event */ private onDrag; /** * Processes drop events to add files to the scene * Handles both file drops and text/URL drops * @param evt The drop event */ private onDrop; /** * Processes a dropped or pasted URL and tries to load it as a 3D model * Handles special cases like GitHub URLs and Polyhaven asset URLs * @param url The URL to process * @param ctx Context information about where the drop occurred * @param isRemote Whether this URL was shared from a remote client * @returns The added object or null if loading failed */ private addFromUrl; private _abort; /** * Processes dropped files and loads them as 3D models. * When enabled, it also handles network drops (sending files between clients). * Automatically handles cancelling previous uploads if new files are dropped. * @param fileList Array of dropped files * @param ctx Context information about where on the screen or in 3D space the drop occurred */ private addFromFiles; /** Previously added objects */ private readonly _addedObjects; private readonly _addedModels; /** * Removes all previously added objects from the scene * @param doDestroy When true, destroys the objects; when false, just clears the references */ private removePreviouslyAddedObjects; /** * Adds a loaded model to the scene with proper positioning and scaling. * Handles placement based on component settings and raycasting. * If {@link fitIntoVolume} is enabled, the object will be scaled to fit within the volume defined by {@link fitVolumeSize}. * @param data The loaded model data and content hash * @param ctx Context information about where the drop occurred * @param isRemote Whether this object was shared from a remote client * @returns The added object or null if adding failed */ private onObjectLoaded; /** * Sends a network event to other clients about a dropped object * Only triggered when networking is enabled and the connection is established * @param url The URL to the content that was dropped * @param obj The object that was added to the scene * @param contentmd5 The content hash for verification */ private sendDropEvent; /** * Deletes remote state for this DropListener's objects * Called when new files are dropped to clean up previous state */ private deleteDropEvent; /** * Tests if a drop event occurred within the designated drop area if one is specified * @param ctx The drop context containing screen position information * @returns True if the drop is valid (either no drop area is set or the drop occurred inside it) */ private testIfIsInDropArea; }