用户:_F_S_2_查看:0 回复:0 评论:0 创建时间:2020-01-02T20:36:30
import { Box3Vector3, Box3Quaternion, Box3RGBAColor, Box3RGBColor, Box3Bounds3 } from './math';
/**
* [[Box3World]] is the main entry point to the engine API. Using this object you can control
* global scene properties like the weather, timeOfDay, etc. and perform searches on the set of all [[Box3Entity]]
* which exist in the world.
*/
export class Box3World {
/**
* The name of the project (read only)
*/
public projectName = 'Project';
/**
* The initial phase of the sun's motion through the sky. The time of day is calculated using the formula:
* `timeOfDay = (sunPhase + sunFrequency * tick) % 1`
* @category weather
*/
public sunPhase = 0;
/**
* The frequency at which the sun moves through the sky. Higher values = faster sun movement.
* @category weather
*/
public sunFrequency = 0;
/**
* The phase of the moon. Must be between 0 and 1
* @category weather
*/
public lunarPhase = 0;
/**
* The absorption rate and color of the fog (determines how fog absorbs light)
* @category weather
*/
public fogExtinction = new Box3RGBColor(0.001, 0.0012, 0.0014);
/**
* The reflection/scattering color of the fog (determines how fog reflects sunlight)
* @category weather
*/
public fogScattering = new Box3RGBColor(0.001, 0.0012, 0.0014);
/**
* @category weather
*/
public snowDensity = 0;
/**
* @category weather
*/
public snowSizeLo = 0;
/**
* @category weather
*/
public snowSizeHi = 1;
/**
* @category weather
*/
public snowFallSpeed = 1;
/**
* @category weather
*/
public snowSpinSpeed = 0;
/**
* @category weather
*/
public snowColor = new Box3RGBAColor(1, 1, 1, 1);
/**
* @category weather
*/
public rainDensity = 0;
/**
* @category weather
*/
public rainPhi = 0;
/**
* @category weather
*/
public rainTheta = 0;
/**
* @category weather
*/
public rainSpeed = 1;
/**
* @category weather
*/
public rainSizeLo = 0;
/**
* @category weather
*/
public rainSizeHi = 1;
/**
* @category weather
*/
public rainInterference = 0;
/**
* @category weather
*/
public rainColor = new Box3RGBAColor(1, 1, 1, 1);
/**
* Amount and direction of gravitational field
* @category physics
*/
public gravity = -0.1;
/**
* Amount of air friction
* @category physics
*/
public airFriction = 0.001;
/**
* @ignore
*/
constructor (
/**
* @returns the current game tick
* @category tick
*/
public tick:() => number,
/**
* @returns a reference to the voxels
* @category voxels
*/
public voxels:Box3Voxels,
/**
* Creates a new [[Box3Entity]] or makes a copy of an existing entity
* @param config A set of initial values for the entity or a new entity which we want to copy
* @returns A newly created entity with the given parameters
* @category entity
*/
public createEntity:(config:Partial<Box3EntityConfig>) => Box3Entity,
/**
* @returns a list of all [[Box3Entity]]'s in the world
* @category entity
*/
public entities:() => Box3Entity[],
/**
* @returns a list of all player entities in the world
* @category player
*/
public players:() => (Box3Entity & { isPlayer:true, player:Box喵layer })[],
/**
* Shoots a ray through the world from `origin` in `direction`
* @param origin the start point of the ray
* @param direction the direction of the ray
* @param options An option configuration parameter
* @returns Information about the resulting raycast
* @category search
*/
public raycast:(origin:Box3Vector3, direction:Box3Vector3, options?:Partial<Box3RaycastOptions>) => Box3RaycastResult,
/**
* Search for all entities contained in a bounding box
* @param bounds the bounding box to search
* @returns All entities contained in ``bounds``
*/
public searchBox:(bounds:Box3Bounds3) => Box3Entity[],
/**
* An event handler called each tick
* @category tick
*/
public onTick:Box3EventChannel<Box3TickEvent>,
/**
* Called whenever a player joins the game
* @category player
*/
public onPlayerJoin:Box3EventChannel<Box3EntityEvent>,
/**
* Called whenever a player leaves the game
* @category player
*/
public onPlayerLeave:Box3EventChannel<Box3EntityEvent>,
/**
* Called whenever an entity is created
* @category entity
*/
public onEntityCreate:Box3EventChannel<Box3EntityEvent>,
/**
* Called whenever an entity is destroyed
* @category chat
*/
public onEntityDestroy:Box3EventChannel<Box3EntityEvent>,
/**
* Broadcast a global message to all players
* @param message is some text we want to broadcast
* @category player
*/
public say:(message:string) => void,
/**
* Called whenever a player says something
* @category player
*/
public onChat:Box3EventChannel<Box3ChatEvent>,
/**
* Called whenever a player pushes a button
* @category player
*/
public onPress:Box3EventChannel<Box3InputEvent>,
/**
* Called whenever a player releases a button
* @category player
*/
public onRelease:Box3EventChannel<Box3InputEvent>,
/**
* Called whenever two entities collide
* @category entity
*/
public onEntityContact:Box3EventChannel<Box3EntityContactEvent>,
/**
* Called whenever two entities stop colliding
* @category entity
*/
public onEntitySeparate:Box3EventChannel<Box3EntityContactEvent>,
/**
* Called whenever an entity touches a voxel
* @category entity
*/
public onVoxelContact:Box3EventChannel<Box3VoxelContactEvent>,
/**
* Called whenever an entity stops touching a voxel
* @category entity
*/
public onVoxelSeparate:Box3EventChannel<Box3VoxelContactEvent>,
/**
* Called when an entity enters a fluid
* @category entity
*/
public onFluidEnter:Box3EventChannel<Box3FluidContactEvent>,
/**
* Called when an entity leaves a fluid
* @category entity
*/
public onFluidLeave:Box3EventChannel<Box3FluidContactEvent>,
) {}
}
/**
* [[Box3Voxels]] gives an interface for all the voxels in box3. You can use it to control the terrain
*/
export class Box3Voxels {
/**
* @ignore
*/
constructor (
/**
* Size of the voxel grid along the x/y/z dimensions
*/
public shape:Box3Vector3,
/**
* An array of all supported voxel types
* @category names
*/
public VoxelTypes:string[],
/**
* @param name the human readable name for the voxel
* @returns the voxel id number
* @category names
*/
public Id:(name:string) => number,
/**
* @param id the numerical id of a voxel
* @returns the human readable voxel name
* @category names
*/
public Name:(id:number) => string,
/**
* @param id the numerical id of the voxel
* @returns the rotation code of the voxel
* @category names
*/
public Rotation:(id:number) => number,
/**
* Sets a voxel in the grid
* @param voxel The name of the voxel or its voxel id
* @param rotation The rotation code of the voxel
* @returns the id of the updated voxel
*/
public setVoxel:(x:number, y:number, z:number, voxel:number|string, rotation?:number|string) => number,
/**
* Get the type of a voxel at some point
* @returns the voxel type code at point x/y/z
*/
public getVoxel:(x:number, y:number, z:number) => number,
/**
* Get the rotation of a voxel at point x/y/z
* @returns the voxel rotation code
*/
public getVoxelRotation:(x:number, y:number, z:number) => number,
/**
* Sets a voxel in the grid directly using its id code
* @category advanced
*/
public setVoxelID:(x:number, y:number, z:number, voxel:number) => number,
/**
* Retrieves the voxel id in the grid
* @category advanced
*/
public getVoxelID:(x:number, y:number, z:number) => number,
) {}
}
/**
* A set of parameters which can be used to specify an entity
*/
export interface Box3EntityConfig {
position:Box3Vector3;
velocity:Box3Vector3;
mass:number;
friction:number;
restitution:number;
collides:boolean;
fixed:boolean;
gravity:boolean;
meshColor:Box3RGBAColor;
mesh:string;
meshScale:Box3Vector3;
meshOrientation:Box3Quaternion;
}
/**
* Entities are game objects in box3. They can be used to encode things like players, objects, etc.
*/
export class Box3Entity implements Box3EntityConfig {
/**
* If true, entity is destroyed.
* @category destroy
*/
public destroyed = false;
/**
* @category physics
*/
public position = new Box3Vector3(0, 0, 0);
/**
* @category physics
*/
public velocity = new Box3Vector3(0, 0, 0);
/**
* Radius of the entity's bounding box along x/y/z
* @category physics
*/
public bounds = new Box3Vector3(1, 1, 1);
/**
* Mass of entity
* @category physics
*/
public mass = 1;
/**
* Controls object stickiness (0 = slippery, 1 = sticky)
* @category physics
*/
public friction = 0;
/**
* Controls bouncy (0 = soft, 1 = bouncy)
* @category physics
*/
public restitution = 0;
/**
* If false, object does not collide
* @category physics
*/
public collides = true;
/**
* If false, object does not fall
* @category physics
*/
public gravity = true;
/**
* If true, object does not move
* @category physics
*/
public fixed = false;
/**
* Hash of entity mesh. If set to empty string/'' then entity does not have a mesh.
* Unless object is a player, if mesh is set then mesh is used to compute object bounds
* @category mesh
*/
public mesh = '';
/**
* @category mesh
*/
public meshScale = new Box3Vector3(1, 1, 1);
/**
* @category mesh
*/
public meshOrientation = new Box3Quaternion(0, 0, 0, 1);
/**
* @category mesh
*/
public meshColor = new Box3RGBAColor(1, 1, 1, 1);
/**
* If true, then the entity is a player
* @category player
*/
public isPlayer = false;
/**
* Reference to all player specific state and methods
* @category player
*/
public player?:Box喵layer;
/**
* @ignore
*/
constructor (
/**
* Destroys the entity
* @category destroy
*/
public destroy:() => void,
/**
* Called when the entity is destroyed
* @category destroy
*/
public onDestroy:Box3EventChannel<Box3EntityEvent>,
/**
* Makes the entity talk
* @category chat
*/
public say:(message:string) => void,
/**
* Called when the entity touches another entity
* @category physics
*/
public onEntityContact:Box3EventChannel<Box3EntityContactEvent>,
/**
* Called when the entity stops touching another entity
* @category physics
*/
public onEntitySeparate:Box3EventChannel<Box3EntityContactEvent>,
/**
* Called when the entity touches a voxel
* @category physics
*/
public onVoxelContact:Box3EventChannel<Box3VoxelContactEvent>,
/**
* Called when the entity stops touching a voxel
* @category physics
*/
public onVoxelSeparate:Box3EventChannel<Box3VoxelContactEvent>,
/**
* Called when the entity enters a fluid
* @category physics
*/
public onFluidEnter:Box3EventChannel<Box3FluidContactEvent>,
/**
* Called when the entity leaves a fluid
* @category physics
*/
public onFluidLeave:Box3EventChannel<Box3FluidContactEvent>,
) {}
}
/**
* Players correspond to users which are connected to the game
*/
export class Box喵layer {
/**
* Name of the player. Constant.
*/
public name = 'player';
/**
* Initial spawn point of player
*/
public spawnPoint = new Box3Vector3(0, 0, 0);
/**
* Scale factor, applied to player
*/
public scale = new Box3Vector3(1, 1, 1);
/**
* Color grading look up table, applied to player to tint game state
*/
public colorLUT = '';
/**
* Camera behavior mode.
* + `"FPS"` - First person camera
* + `"FOLLOW"` - Third person follow camera (default)
* + `"FIXED"` - Third person fixed camera
* @category camera
*/
public cameraMode:'FOLLOW'|'FPS'|'FIXED' = 'FOLLOW';
/**
* In FPS or FOLLOW mode, the entity which the player's camera follows
* @category camera
*/
public cameraEntity:Box3Entity|null = null;
/**
* Target point for the camera in FIXED mode
* @category camera
*/
public cameraTarget = new Box3Vector3(0, 0, 0);
/**
* Up vector for camera in FIXED mode
* @category camera
*/
public cameraUp = new Box3Vector3(0, 1, 0);
/**
* Eye position of camera in FIXED mode
* @category camera
*/
public cameraPosition = new Box3Vector3(0, 0, 0);
/**
* If true, player is allowed to fly
* @category movement
*/
public canFly = false;
/**
* If true, player is a ghost and can pass through walls
* @category movement
*/
public spectator = false;
/**
* Maximum walking speed
* @category movement
*/
public walkSpeed = 0.22;
/**
* Walking acceleration
* @category movement
*/
public walkAcceleration = 0.19;
/**
* Maximum running speed
* @category movement
*/
public runSpeed = .4;
/**
* Running acceleration
* @category movement
*/
public runAcceleration = 0.35;
/**
* Crouching walk speed
* @category movement
*/
public crouchSpeed = 0.10;
/**
* Crouching walk acceleration
* @category movement
*/
public crouchAcceleration = 0.09;
/**
* Maximum swim speed
* @category movement
*/
public swimSpeed = 0.4;
/**
* Swim acceleration
* @category movement
*/
public swimAcceleration = 0.1;
/**
* Maximum flying speed
* @category movement
*/
public flySpeed = 2;
/**
* Flying acceleration
* @category movement
*/
public flyAcceleration = 2;
/**
* Maximum fall speed
* @category movement
*/
public fallSpeed = Infinity;
/**
* Fall acceleration
* @category movement
*/
public fallAcceleration = 0.05;
/**
* Jump speed
* @category movement
*/
public jumpSpeedFactor = 0.85;
/**
* Jump acceleration rate
* @category movement
*/
public jumpAccelerationFactor = 0.55;
/**
* Jump velocity impulse
* @category movement
*/
public jumpPower = 0.96;
/**
* Double jump velocity impulse
* @category movement
*/
public doubleJumpPower = 0.9;
/**
* @category state
*/
public swimming = false;
/**
* @category state
*/
public ground = false;
/**
* @category state
*/
public falling = false;
/**
* @category state
*/
public jumping = false;
/**
* @category state
*/
public doubleJumping = false;
/**
* @category state
*/
public flying = false;
/**
* @category state
*/
public crouching = false;
/**
* @category state
*/
public walking = false;
/**
* @category state
*/
public running = false;
/**
* @category input
*/
public walkButton = false;
/**
* @category input
*/
public crouchButton = false;
/**
* @category input
*/
public jumpButton = false;
/**
* @category input
*/
public action0Button = false;
/**
* @category input
*/
public action1Button = false;
/**
* @category input
*/
public facingDirection = new Box3Vector3(1, 0, 0);
/**
* @ignore
*/
constructor (
/**
* Sends a private message directly to player
* @category chat
*/
public directMessage:(message:string) => void,
/**
* Called whenever player initiates a chat event
* @category chat
*/
public onChat:Box3EventChannel<Box3ChatEvent>,
/**
* Called whenever player presses a button
* @category input
*/
public onPress:Box3EventChannel<Box3InputEvent>,
/**
* Called whenever a player releases a buttin
* @category input
*/
public onRelease:Box3EventChannel<Box3InputEvent>,
) {}
}
/**
* Result of performing a raycast. Contains information about the raycast and what it hit.
*/
export class Box3RaycastResult {
/**
* @ignore
*/
constructor (
/**
* If true, raycast hit an object
*/
public hit:boolean,
/**
* The entity hit by the raycast
*/
public hitEntity:Box3Entity|null,
/**
* The voxel id hit by the raycast (0 if no voxel was hit)
*/
public hitVoxel:number,
/**
* Start point of the ray cast
*/
public origin:Box3Vector3,
/**
* Direction of the raycast
*/
public direction:Box3Vector3,
/**
* Distance traveled along the ray
*/
public distance:number,
/**
* Position of the ray intersection
*/
public position:Box3Vector3,
/**
* Normal vector on surface at point of intersection
*/
public normal:Box3Vector3,
/**
* If a voxel was hit, the grid coordinates of the hit voxel
*/
public voxelIndex:Box3Vector3) {}
}
/**
* Configuration parameters passed into a raycast method
*/
export interface Box3RaycastOptions {
/**
* Maximum distance allowed for ray to travel
*/
maxDistance:number;
/**
* If true, ignore fluid voxels
*/
ignoreFluid:boolean;
/**
* If true, don't test intersection against voxels
*/
ignoreVoxel:boolean;
/**
* If true, don't test intersection against entities
*/
ignoreEntities:boolean;
}
/**
* You can subscribe to events coming from some object using an EventChannel.
*
* Event channels take an event handler as input and return a token which can be used to cancel the handler.
*
* **Example:**
* ```typescript
* const token = world.onTick(() => console.log("tick !"));
* setTimeout(() => {
* console.log('cancel tick handler');
* token.cancel();
* // no more tick events will be logged
* }, 1000);
* ```
*
* @param handler The handler callback which is invoked whenever the event is fired
* @typeparam EventType The type of the event which is emitted by the channel
* @returns An event handler token which can be used to cancel the event handler
* @category events
*/
export type Box3EventChannel<EventType> = (handler:(event:EventType) => void) => Box3EventHandlerToken;
/**
* Returned by a [[Box3EventChannel]] whenever a handler is registered. Can be used to cancel the handler.
* @category events
*/
export class Box3EventHandlerToken {
/**
* @ignore
*/
constructor (
/**
* Cancels the event handler
*/
public cancel:() => void,
/**
* Resumes listening with the event handler
*/
public resume:() => void,
) {}
}
/**
* An event which is fired each tick by [[Box3World.onTick]].
* @category events
*/
export class Box3TickEvent {
/**
* @ignore
*/
constructor (
/**
* Tick at which the event was fired
*/
public tick:number,
/**
* Last tick which was handled
*/
public prevTick:number,
/**
* If we had to skip any ticks due to the scripts lagging
*/
public skip:boolean,
/**
* Wall clock time between ticks
*/
public elapsedTimeMS:number,
) { }
}
/**
* An event which is fired whenever some entity is created or destroyed.
* Triggered by [[Box3World.onPlayerJoin]], [[Box3World.onPlayerLeave]], [[Box3World.onEntityCreate]], [[Box3World.onEntityDestroy]] and [[Box3Entity.onDestroy]]
* @category events
*/
export class Box3EntityEvent {
/**
* @ignore
*/
constructor (
/**
* The time the event occured
*/
public tick:number,
/**
* The entity that was created/destroyed
*/
public entity:Box3Entity,
) { }
}
/**
* An event which is fired whenever two entities collide
* Triggered by [[Box3World.onEntityContact]], [[Box3World.onEntitySeparate]], [[Box3Entity.onEntityContact]], [[Box3Entity.onEntitySeparate]]
* @category events
*/
export class Box3EntityContactEvent {
/**
* @ignore
*/
constructor (
/**
* Time at which the entities collided
*/
public tick:number,
/**
* The first entity in the pair
*/
public entity:Box3Entity,
/**
* The second entity in the pair
*/
public other:Box3Entity,
/**
* The separating axis of the collision
*/
public axis:Box3Vector3,
/**
* The amount of force imparted by the collision
*/
public force:Box3Vector3,
) { }
}
/**
* An event which is fired whenever an entity comes into contact with terrain
* Triggered by [[Box3World.onVoxelContact]], [[Box3World.onVoxelSeparate]], [[Box3Entity.onVoxelContact]], [[Box3Entity.onVoxelSeparate]]
* @category events
*/
export class Box3VoxelContactEvent {
/**
* @ignore
*/
constructor (
/**
* The time of the contact event
*/
public tick:number,
/**
* The entity which touched the terrain
*/
public entity:Box3Entity,
/**
* x coordinate of voxel which was touched
*/
public x:number,
/**
* y coordinate of voxel which was touched
*/
public y:number,
/**
* z coordinate of voxel which was touched
*/
public z:number,
/**
* id of voxel
*/
public voxel:number,
/**
* Separating axis
*/
public axis:Box3Vector3,
/**
* Collision force
*/
public force:Box3Vector3,
) { }
}
/**
* An event which is fired whenever an entity enters or leaves a fluid
* Triggered by [[Box3World.onFluidEnter]], [[Box3World.onFluidLeave]], [[Box3Entity.onFluidEnter]], [[Box3Entity.onFluidLeave]]
* @category events
*/
export class Box3FluidContactEvent {
/**
* @ignore
*/
constructor (
/**
* Time event occured
*/
public tick:number,
/**
* Entity which modified
*/
public entity:Box3Entity,
/**
* The id of the fluid voxel
*/
public voxel:number,
) { }
}
/**
* Triggered by [[Box3World.onChat]] and [[Box3Entity.onChat]]
* @category events
*/
export class Box3ChatEvent {
/**
* @ignore
*/
constructor (
/**
* Time chat event occured
*/
public tick:number,
/**
* Entity which initiated chat event
*/
public entity:Box3Entity,
/**
* What the entity said in the chat event
*/
public message:string,
) { }
}
/**
* Type of a button pressed by a player
* @category events
*/
export enum Box3ButtonType {
WALK='walk',
RUN='run',
CROUCH='crouch',
JUMP='jump',
DOUBLE_JUMP='jump2',
FLY='fly',
ACTION0='action0',
ACTION1='action1',
}
/**
* Input events are generated whenever a player presses a button.
* The tick of an event occurs at the exact instant the button was pressed by the player.
* Triggered by [[Box3World.onPress]], [[Box3World.onRelease]], [[Box喵layer.onPress]], [[Box喵layer.onRelease]]
* @category events
*/
export class Box3InputEvent {
/**
* @ignore
*/
constructor (
/**
* The time the button was pressed
*/
public tick:number,
/**
* A reference to the player which pressed the button
*/
public entity:Box3Entity & { isPlayer:true, player:Box喵layer },
/**
* The position of the entity at the time the pressed the button
*/
public position:Box3Vector3,
/**
* The button which was input by the player
*/
public button:Box3ButtonType,
/**
* If true, then this is a press event. Otherwise if false this is a release event
*/
public pressed:boolean,
/**
* The result of a raycast query initiated by the player at the exact instant they pressed the button from the perspective of their camera.
*/
public raycast:Box3RaycastResult,
) { }
}