@vrspace/babylonjs
Version:
vrspace.org babylonjs client
770 lines (769 loc) • 23.3 kB
TypeScript
/**
Object ID, consisting of class name and UUID.
*/
export class ID {
constructor(className: any, id: any);
/** Class name
* @type {string}
*/
className: string;
/** Identifier (UUID)
* @type {string}
*/
id: string;
/** class name + ' ' + id
* @returns {string}
*/
toString(): string;
}
/**
* Rotation
* @typedef {Object} Rotation
* @prop {number} [x=0]
* @prop {number} [y=1]
* @prop {number} [z=0]
*/
export class Rotation {
x: number;
y: number;
z: number;
}
/**
* Quaternion
* @typedef {Object} Quaternion
* @prop {number|null} [x]
* @prop {number|null} [y]
* @prop {number|null} [z]
* @prop {number|null} [w]
*/
export class Quaternion {
x: any;
y: any;
z: any;
w: any;
}
/**
Point in space, x, y, z
*/
export class Point {
/** @type {number} */
x: number;
/** @type {number} */
y: number;
/** @type {number} */
z: number;
}
/**
Currently active animation of an object.
*/
export class Animation {
name: any;
loop: boolean;
speedRatio: number;
}
/**
Welcome message received from the server when entering a world.
*/
export class Welcome {
/** TODO classname first, e.g. client.User.fields */
client: any;
/** @type {Array.<VRObject>} */
permanents: Array<VRObject>;
}
/**
Activate message received when de/activating an object
*/
export class Activate {
/** @type {string} */
className: string;
/** @type {string} */
id: string;
/** @type {boolean} */
active: boolean;
}
/**
Basic VRObject, has the same properties as server counterpart.
*/
export class VRObject extends ID {
constructor();
/** Position, Point
* @type {Point}
*/
position: Point;
/** Rotation
* @type {Rotation|null}
*/
rotation: Rotation | null;
/** Scale, Point
* @type {Point|null}
*/
scale: Point | null;
/** Default false, permanent objects remain in the scene forever
* @type {boolean}
*/
permanent: boolean;
/** Everything created by guest client is by default temporary
* @type {boolean}
*/
temporary: boolean;
/** URL of 3D mesh
* @type {string|null}
*/
mesh: string | null;
/** Active i.e. online users
* @type {boolean}
*/
active: boolean;
/** Name of the animation that is currently active
* @type {string|null}
*/
animation: string | null;
/** URL of dynamically loaded script
* @type {string|null}
*/
script: string | null;
/** Custom properties of an object - shared transient object
* @type {Object}
*/
properties: any;
/** Event listeners. Typically world manager listens to changes, and moves objects around. */
listeners: any[];
/** Load listeners, functions that trigger after the mesh or script is loaded. Managed by WorldManager. CHECKME SoC */
loadListeners: any[];
/** Internal, set by WorldManager after the mesh/script has loaded. */
_isLoaded: boolean;
/** Handy reference to VRSpace instance */
VRSPACE: any;
/**
Add a change listener to the object.
*/
addListener(listener: any): void;
/**
Add a load listener function to the object. Triggers immediatelly if mesh/script has already loaded (_isLoaded is true).
*/
addLoadListener(listener: any): void;
/**
Remove the listener.
*/
removeListener(listener: any): void;
/**
Remove a load listener.
*/
removeLoadListener(listener: any): void;
/**
Called when server sends notification that the object has changed.
Notifies all listeners of object and changes.
*/
notifyListeners(changes: any): void;
/** Triggers all load listeners */
notifyLoadListeners(): void;
/** Publish the object to the server. Can be used only on new objects. */
publish(): void;
/**
* Returns ID of this VRObject
* @returns {ID}
*/
getID(): ID;
/**
* Executedwhile handling network event. Empty implementation, overridden by EventRouter.
*/
positionChanged(): void;
/**
* Executedwhile handling network event. Empty implementation, overridden by EventRouter.
*/
rotationChanged(): void;
/**
* Executedwhile handling network event. Empty implementation, overridden by EventRouter.
*/
scaleChanged(): void;
}
/**
Scene properties, same as server counterpart.
*/
export class SceneProperties {
/** Visibility range, default 2000
* @type {number}
*/
range: number;
/** Movement resolution, default 10
* @type {number}
*/
resolution: number;
/** Maximum size, default 1000
* @type {number}
*/
size: number;
/** Invalidation timeout in ms, default 30000
* @type {number}
*/
timeout: number;
}
/**
Representation of a client (user, bot, remote server...).
@extends VRObject
*/
export class Client extends VRObject {
/** Client name, must be unique
* @type {string}
*/
name: string;
/** Scene properties
* @type {SceneProperties}
*/
sceneProperties: SceneProperties;
/** Private tokens, map of strings */
tokens: any;
/** true if the client has an avatar
* @type {boolean}
*/
hasAvatar: boolean;
/** avatar picture url
* @type {string|null}
*/
picture: string | null;
/** Handy function, returns name if not null, else class and id */
getNameOrId(): string;
}
/**
Representation of a user.
@extends Client
*/
export class User extends Client {
/** Does this client have humanoid avatar, default true
* @type {boolean}
*/
humanoid: boolean;
/** Does this client have video avatar, default false
* @type {boolean}
*/
video: boolean;
/** Left arm position
* @type {Point}
*/
leftArmPos: Point;
/** Right arm position
* @type {Point}
*/
rightArmPos: Point;
/** Left arm rotation, quaternion
* @type {Quaternion}
*/
leftArmRot: Quaternion;
/** Right arm rotation, quaternion
* @type {Quaternion}
*/
rightArmRot: Quaternion;
/** User height, default 1.8
* @type {number}
*/
userHeight: number;
}
export class RemoteServer extends Client {
url: any;
thumbnail: any;
humanoid: boolean;
}
/**
See server side counterpart.
@extends Client
*/
export class EventRecorder extends Client {
}
/**
Robot base class, useful for chatbots.
@extends User
*/
export class Bot extends User {
gender: any;
lang: any;
}
export class BotLibre extends Bot {
}
export class OllamaBot extends Bot {
}
export class Terrain extends VRObject {
diffuseColor: any;
diffuseTexture: any;
emissiveColor: any;
specularColor: any;
points: any;
}
export class Content {
/** @type {string|null} */
fileName: string | null;
/** @type {string|null} */
contentType: string | null;
/** @type {number|null} */
length: number | null;
}
export class VRFile extends VRObject {
/** @type {Content|null} */
content: Content | null;
}
export class Background extends VRObject {
texture: any;
ambientIntensity: number;
}
export class Game extends VRObject {
name: any;
numberOfPlayers: number;
status: any;
players: any[];
}
/**
An event that happened to an object.
@param obj VRObject instance
@param changes optional object encapsulating changes to the object (field:value)
*/
export class VREvent {
constructor(obj: any, changes: any);
/** VRObject that has changed */
object: Object;
changes: any;
}
/**
A scene event - addition or removal of some objects, typically users.
An object is either added or removed, the other value is null.
*/
export class SceneEvent {
constructor(scene: any, className: any, objectId: any, added: any, removed: any);
/** Class name of object added/removed
* @type {string}
*/
className: string;
/** Id of added/removed object
* @type {ID}
*/
objectId: ID;
/** Added object
* @type {VRObject|null}
*/
added: VRObject | null;
/** Removed object
* @type {VRObject|null}
*/
removed: VRObject | null;
/** New scene
* @type {Map<String, Object>}
*/
scene: Map<string, any>;
}
/**
* Streaming session data, used to match the client avatar or other mesh to the video/audio stream.
*/
export class SessionData {
/**
* @param {String} json string representation of this object (passed along connection as user data)
*/
constructor(json: string);
/** Client id, long
* @type {number}
*/
clientId: number;
/** Session name, matches either world name for public world, or world token for private world
* @type {string}
*/
name: string;
/** Session type - 'main' or 'screen'
* @type {string}
*/
type: string;
}
export class UserGroup {
id: any;
name: any;
isPublic: any;
temporary: any;
direct: any;
}
export class GroupMember {
id: any;
/** @type {UserGroup} */
group: UserGroup;
/** @type {Client} */
client: Client;
pendingInvite: any;
pendingRequest: any;
/** @type {Client} */
sponsor: Client;
lastUpdate: any;
}
export class GroupMessage {
/** @type {String} */
id: string;
/** @type {Client} */
from: Client;
/** @type {UserGroup} */
group: UserGroup;
/** @type {string} */
content: string;
/** @type {string} */
link: string;
/** @type {Date} */
timestamp: Date;
/** @type {boolean} */
local: boolean;
/** @type {Array.<Content>} */
attachments: Array<Content>;
}
/** Notification from a UserGroup */
export class GroupEvent {
/** @type {GroupMessage} */
message: GroupMessage;
/** @type {GroupMember} */
invite: GroupMember;
/** @type {GroupMember} */
ask: GroupMember;
/** @type {GroupMember} */
allowed: GroupMember;
/** @type {GroupMessage} */
attachment: GroupMessage;
}
/**
Main client API class, no external dependencies.
Provides send methods to send messages to the server, to be distributed to other clients.
Listeners receive remote events.
*/
export class VRSpace {
/** Underlying websocket */
ws: WebSocket;
/** Representation of own Client, available once the connection is established
* @type {User}
*/
me: User;
/** Map containing all objects in the scene
* @type {Map<string, VRObject>}
*/
scene: Map<string, VRObject>;
/**
* Connection URL, set once connection is established
* @type {string}
*/
url: string;
/** Debug logging, default false */
debug: boolean;
/** Reconnect automatically, experimental */
autoReconnect: boolean;
reconnecting: boolean;
retryTimer: any;
connectionListeners: any[];
dataListeners: any[];
sceneListeners: any[];
activationListeners: any[];
welcomeListeners: any[];
errorListeners: any[];
groupListeners: any[];
/** Listeners to responses to commands, processed one at a time. */
responseListeners: any[];
sharedClasses: {
ID: typeof ID;
Rotation: any;
Point: typeof Point;
VRObject: typeof VRObject;
SceneProperties: typeof SceneProperties;
Client: typeof Client;
User: typeof User;
RemoteServer: typeof RemoteServer;
VREvent: typeof VREvent;
SceneEvent: typeof SceneEvent;
EventRecorder: typeof EventRecorder;
Bot: typeof Bot;
BotLibre: typeof BotLibre;
OllamaBot: typeof OllamaBot;
Terrain: typeof Terrain;
VRFile: typeof VRFile;
Game: typeof Game;
Background: typeof Background;
};
messageHandlers: {
object: (message: any) => void;
Add: (message: any) => void;
Remove: (message: any) => void;
Activate: (message: any) => void;
ERROR: (message: any) => void;
Welcome: (message: any) => void;
response: (message: any) => void;
GroupEvent: (message: any) => void;
};
log(msg: any): void;
addListener(array: any, callback: any): any;
removeListener(array: any, listener: any): void;
/**
Add a connection listener that gets notified when connection is activated/broken.
Callback is passed boolean argument indicating connection state.
*/
addConnectionListener(callback: any): any;
removeConnectionListener(callback: any): void;
/** Add a data listener that receives everything from the server (JSON string argument) */
addDataListener(callback: any): any;
/**
* @callback sceneCallback
* @param {SceneEvent} event
*/
/**
Add a scene listener that gets notified when the scene is changed.
Scene listeners receive SceneEvent argument for each change.
@param {sceneCallback} callback
*/
addSceneListener(callback: (event: SceneEvent) => any): any;
/**
Remove a scene listener.
*/
removeSceneListener(callback: any): void;
/**
Add an activation listener, that gets called when active property of a VRObject changes.
Lister needs to update event model then, i.e. start/stop listening to events from the object.
@param {*} callback
*/
addActivationListener(callback: any): any;
/**
Remove an activation listener.
*/
removeActivationListener(callback: any): void;
/**
Add a Welcome listener, notified when entering a world.
The listener receives Welcome object.
*/
addWelcomeListener(callback: any): any;
/**
Remove welcome listener
@param callback listener to remove
*/
removeWelcomeListener(callback: any): void;
/**
Add error listener, notified when server sends error notifications.
Error listener is passed the string containing the server error message, e.g. java exception.
*/
addErrorListener(callback: any): any;
/**
Remove error listener
@param callback listener to remove
*/
removeErrorListener(callback: any): void;
/**
Add a group listener, notified when entering a world.
The listener receives Welcome object.
@param {function(GroupEvent)} callback
*/
addGroupListener(callback: (arg0: GroupEvent) => any): any;
/**
Remove group listener
@param callback listener to remove
*/
removeGroupListener(callback: any): void;
/**
Return the current scene, optionally filtered
@param filter string to match current members, usually class name, or function that takes VRObject as argument
@return {Map<string, VRObject>} scene
*/
getScene(filter: any): Map<string, VRObject>;
/**
* @private
*/
private defaultWebsocketUrl;
/**
Connect to the server, attach connection listeners and data listeners to the websocket.
@param {string} [url] optional websocket url, defaults to /vrspace/client on the same server
@returns {Promise} promise resolved once the connection is successful
*/
connect(url?: string): Promise<any>;
isConnected(): boolean;
reconnect(interval?: number, retries?: number): void;
/** Disconnect, notify connection listeners */
disconnect(): void;
/** Convert a vector to json string
@param vec object having x,y,z properties
*/
stringifyVector(vec: any): string;
/** Convert a quaternion to json string
@param vec object having x,y,z,w properties
*/
stringifyQuaternion(quat: any): string;
/** Convert a key/value pair to json string.
FIXME improperly stringifies objects having properties x, _x, or w. Properties other than x,y,z,w will be ignored.
See stringifyVector and stringifyQuaternion.
This is essentially workaround for bablyon types, e.g. Vector3, that have _x, _y, _z properties.
@param field name of the field
@param value string, object or number to convert
*/
stringifyPair(field: any, value: any): string;
/** Create a local field of an object existing on the server FIXME Obsolete */
createField(className: any, fieldName: any, callback: any): void;
/**
Share an object.
@param {VRObject} obj the new VRObject, containing all properties
@param {string|undefined} [className] optional class name to create, defaults to obj.className if exists, otherwise VRObject
@param {boolean} [temporary] Create temporary object. Defaults to true for scripts.
@returns {Promise<VRObject>} Promise with the created VRObject instance
*/
createSharedObject(obj: VRObject, className?: string | undefined, temporary?: boolean): Promise<VRObject>;
/**
Delete a shared object.
@param {ID} obj to be removed from the server
@param {*} [callback] optional, called after removal from the server
*/
deleteSharedObject(obj: ID, callback?: any): void;
/**
Send notification of own property changes
@param {string} field name of member variable that has changed
@param {*} value new field value
*/
sendMy(field: string, value: any): void;
/**
Send a command to the server
@param {string} command to execute
@param {Object} args optional object with command arguments
*/
sendCommand(command: string, args: any): void;
/**
Send a command to the server
@param {string} command to execute
@param callback function that's called with command return value
*/
callCommand(command: string, callback: any): void;
/**
Send a command to the server
@param {string} command to execute
*/
callCommandAsync(command: string): Promise<any>;
/**
* Set a client token e.g. required to enter a world
* @param {string} name token name
* @param {string} value token value
*/
setToken(name: string, value: string): void;
/**
* Enter a world, optionally with a token (that may be required for private worlds).
* The server sends Welcome message, that's supposed to be processed with Welcome listeners.
*
* @param {string} world Name of the world to enter
* @param {string} [token] optional token value
*/
enter(world: string, token?: string): void;
/**
* Enter a world, optionally with a token (that may be required for private worlds).
* The servers sends back Welcome response message, that is resolved in Promise.
*
* @param {string} world Name of the world to enter
* @param {string} [token] optional token value
* @returns {Promise<Welcome>} promise with the welcome message
*/
enterAsync(world: string, token?: string): Promise<Welcome>;
/**
* Start the session: sends Session command to the server
* @returns {Promise} resolves when server responds
*/
sessionStart(): Promise<any>;
/**
Send changes to an object
@param obj VRObject that changes
@param changes array containing field/value pairs
*/
sendChanges(obj: any, changes: any): void;
/**
Send changes to an object
@param {ID} obj VRObject that changes
@param {Object} changes object containing changed fields
*/
sendEvent(obj: ID, changes: any): void;
/**
Send changes to own avatar
@param changes array with field/value pairs
*/
sendMyChanges(changes: any): void;
/**
Send changes to own avatar
@param {Object} changes object containing changed fields
*/
sendMyEvent(changes: any): void;
send(message: any): void;
/**
Perform a synchronous call, used internally by callCommand etc.
Enqueues callback, and executes it when the response to command arrives.
Successful call chaining depends on server executing them sequentially.
REST API calls are better option for synchronous calls.
@param {string} message JSON string to send
@param {*} callback function to execute upon receiving the response
*/
call(message: string, callback: any): Promise<void>;
/**
* Perfom a synchronous call.
* @param {string} message JSON string to send
* @returns {Promise} resolves with response from the server
*/
callAsync(message: string): Promise<any>;
/**
Factory method
@param className shared class name
@returns new shared object instance
*/
newInstance(className: any): any;
addToScene(className: any, object: any): void;
addObject(obj: any): void;
/** Remove object, used internally
* @param {object} objectId object taken from Remove command, e.g. {User:123}
*/
removeObject(objectId: object): void;
/**
* Remove object from the scene and notify listeners
* @param {ID} id
*/
removeByID(id: ID): void;
/**
Called when a message is received from the server. JSON message is converted to an object,
then depending on object type, forwarded to one of this.messageHandlers.
@param {String} message text message from the server over the websocket
*/
receive(message: string): void;
/**
* Handle event of a shared VRObject: find the object in the scene, apply changes, notify listeners.
* @param {VREvent} message containing object id and changes
*/
handleEvent(message: VREvent): void;
/**
* Handle Add message: add every object to the scene, and notify listeners. Calls addObject.
* @param {Add} add Add command containing addedd objects
*/
handleAdd(add: Add): void;
/**
* Handle Remove message: remove every object from the scene, and notify listeners. Calls removeObject.
* @param {Remove} remove Remove command containing list of object IDs to remove
*/
handleRemove(remove: Remove): void;
/**
* Handle Activate message: update the object and call listeners.
* @param {Activate} activate
*/
handleActivate(activate: Activate): void;
/**
* Handle server error: log the error, and notify error listeners.
* @param {object} error object containing error message received from the server
*/
handleError(error: object): void;
/**
* Handle Welcome message: create own user object, and notify welcome listeners. Adds all permanent objects to the scene.
* @param {Welcome} welcome the Welcome message.
*/
handleWelcome(welcome: Welcome): void;
/**
* Handle response to command: if responseListener is installed, execute it with the message, ignore otherwise.
* @param {object} response object containing response to the command, can be anything, depending on the command.
*/
handleResponse(response: object): void;
/**
* Handle a group event, simply forward the event to all groupListeners.
* @param {GroupEvent} event
*/
handleGroupEvent(event: GroupEvent): void;
/**
* Experimental. Executes StreamingSession start command on the server that returns session token,
* the executes callback, passing the token to it
*/
startStreaming(callback: any): Promise<any>;
/**
* Experimental. Executes StreamingSession stop command on the server.
* CHECKME Since the server manages streaming sessions anyway, this may not be needed at all.
*/
stopStreaming(): void;
}
export const VRSPACE: VRSpace;