UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

960 lines (959 loc) 31.1 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import { Quat } from "../../../core/math/quat.js"; import { Vec3 } from "../../../core/math/vec3.js"; import { Component } from "../component.js"; import { BODYTYPE_STATIC, BODYGROUP_DYNAMIC, BODYGROUP_KINEMATIC, BODYGROUP_STATIC, BODYMASK_ALL, BODYMASK_NOT_STATIC, BODYTYPE_DYNAMIC, BODYTYPE_KINEMATIC } from "./constants.js"; const _quat1 = new Quat(); const _quat2 = new Quat(); const _vec3 = new Vec3(); const _position = new Vec3(); const _rotation = new Quat(); const _vecA = new Vec3(); const _vecB = new Vec3(); class RigidBodyComponent extends Component { constructor() { super(...arguments); /** @private */ __publicField(this, "_angularDamping", 0); /** @private */ __publicField(this, "_angularFactor", new Vec3(1, 1, 1)); /** @private */ __publicField(this, "_angularVelocity", new Vec3()); /** * The physics backend body, when created. * * @type {PhysicsBody|null} * @private */ __publicField(this, "_body", null); /** @private */ __publicField(this, "_friction", 0.5); /** @private */ __publicField(this, "_group", BODYGROUP_STATIC); /** @private */ __publicField(this, "_linearDamping", 0); /** @private */ __publicField(this, "_linearFactor", new Vec3(1, 1, 1)); /** @private */ __publicField(this, "_linearVelocity", new Vec3()); /** @private */ __publicField(this, "_mask", BODYMASK_NOT_STATIC); /** @private */ __publicField(this, "_mass", 1); /** @private */ __publicField(this, "_restitution", 0); /** @private */ __publicField(this, "_rollingFriction", 0); /** @private */ __publicField(this, "_simulationEnabled", false); /** * @type {BODYTYPE_DYNAMIC|BODYTYPE_KINEMATIC|BODYTYPE_STATIC} * @private */ __publicField(this, "_type", BODYTYPE_STATIC); } /** * Sets the rate at which a body loses angular velocity over time. * * @type {number} */ set angularDamping(damping) { if (this._angularDamping !== damping) { this._angularDamping = damping; if (this._body) { this._body.setDamping(this._linearDamping, damping); } } } /** * Gets the rate at which a body loses angular velocity over time. * * @type {number} */ get angularDamping() { return this._angularDamping; } /** * Sets the scaling factor for angular movement of the body in each axis. Only valid for rigid * bodies of type {@link BODYTYPE_DYNAMIC}. Defaults to 1 in all axes (body can freely rotate). * * @type {Vec3} */ set angularFactor(factor) { if (!this._angularFactor.equals(factor)) { this._angularFactor.copy(factor); if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.setAngularFactor(factor); } } } /** * Gets the scaling factor for angular movement of the body in each axis. Use the setter to * update the physics body. * * @type {Readonly<Vec3>} */ get angularFactor() { return this._angularFactor; } /** * Sets the rotational speed of the body around each world axis. * * @type {Vec3} */ set angularVelocity(velocity) { if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.activate(); this._body.setAngularVelocity(velocity); this._angularVelocity.copy(velocity); } } /** * Gets the rotational speed of the body around each world axis. Use the setter to update the * physics body. * * @type {Readonly<Vec3>} */ get angularVelocity() { if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.getAngularVelocity(this._angularVelocity); } return this._angularVelocity; } /** * @type {*} * @ignore */ set body(body) { if (this._body !== body) { this._body = body; if (body && this._simulationEnabled) { body.activate(); } } } /** * The native physics body - btRigidBody when the Ammo backend is active, null otherwise. * The setter takes the backend {@link PhysicsBody} and is internal. * * @type {*} * @ignore */ get body() { return this._body ? this._body.nativeBody : null; } /** * Sets the friction value used when contacts occur between two bodies. A higher value indicates * more friction. Should be set in the range 0 to 1. Defaults to 0.5. * * @type {number} */ set friction(friction) { if (this._friction !== friction) { this._friction = friction; if (this._body) { this._body.setFriction(friction); } } } /** * Gets the friction value used when contacts occur between two bodies. * * @type {number} */ get friction() { return this._friction; } /** * Sets the collision group this body belongs to. Combine the group and the mask to prevent bodies * colliding with each other. Defaults to 1. * * @type {number} */ set group(group) { if (this._group !== group) { this._group = group; if (this.enabled && this.entity.enabled) { this.disableSimulation(); this.enableSimulation(); } } } /** * Gets the collision group this body belongs to. * * @type {number} */ get group() { return this._group; } /** * Sets the rate at which a body loses linear velocity over time. Defaults to 0. * * @type {number} */ set linearDamping(damping) { if (this._linearDamping !== damping) { this._linearDamping = damping; if (this._body) { this._body.setDamping(damping, this._angularDamping); } } } /** * Gets the rate at which a body loses linear velocity over time. * * @type {number} */ get linearDamping() { return this._linearDamping; } /** * Sets the scaling factor for linear movement of the body in each axis. Only valid for rigid * bodies of type {@link BODYTYPE_DYNAMIC}. Defaults to 1 in all axes (body can freely move). * * @type {Vec3} */ set linearFactor(factor) { if (!this._linearFactor.equals(factor)) { this._linearFactor.copy(factor); if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.setLinearFactor(factor); } } } /** * Gets the scaling factor for linear movement of the body in each axis. Use the setter to * update the physics body. * * @type {Readonly<Vec3>} */ get linearFactor() { return this._linearFactor; } /** * Sets the speed of the body in a given direction. * * @type {Vec3} */ set linearVelocity(velocity) { if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.activate(); this._body.setLinearVelocity(velocity); this._linearVelocity.copy(velocity); } } /** * Gets the speed of the body in a given direction. Use the setter to update the physics body. * * @type {Readonly<Vec3>} */ get linearVelocity() { if (this._body && this._type === BODYTYPE_DYNAMIC) { this._body.getLinearVelocity(this._linearVelocity); } return this._linearVelocity; } /** * Sets the collision mask sets which groups this body collides with. It is a bit field of 16 * bits, the first 8 bits are reserved for engine use. Defaults to 65535. * * @type {number} */ set mask(mask) { if (this._mask !== mask) { this._mask = mask; if (this.enabled && this.entity.enabled) { this.disableSimulation(); this.enableSimulation(); } } } /** * Gets the collision mask sets which groups this body collides with. * * @type {number} */ get mask() { return this._mask; } /** * Sets the mass of the body. This is only relevant for {@link BODYTYPE_DYNAMIC} bodies, other * types have infinite mass. Defaults to 1. * * @type {number} */ set mass(mass) { if (this._mass !== mass) { this._mass = mass; if (this._body && this._type === BODYTYPE_DYNAMIC) { const enabled = this.enabled && this.entity.enabled; if (enabled) { this.disableSimulation(); } this._body.setMass(mass); if (enabled) { this.enableSimulation(); } } } } /** * Gets the mass of the body. * * @type {number} */ get mass() { return this._mass; } /** * Sets the value that controls the amount of energy lost when two rigid bodies collide. The * calculation multiplies the restitution values for both colliding bodies. A multiplied value * of 0 means that all energy is lost in the collision while a value of 1 means that no energy * is lost. Should be set in the range 0 to 1. Defaults to 0. * * @type {number} */ set restitution(restitution) { if (this._restitution !== restitution) { this._restitution = restitution; if (this._body) { this._body.setRestitution(restitution); } } } /** * Gets the value that controls the amount of energy lost when two rigid bodies collide. * * @type {number} */ get restitution() { return this._restitution; } /** * Sets the torsional friction orthogonal to the contact point. Defaults to 0. * * @type {number} */ set rollingFriction(friction) { if (this._rollingFriction !== friction) { this._rollingFriction = friction; if (this._body) { this._body.setRollingFriction(friction); } } } /** * Gets the torsional friction orthogonal to the contact point. * * @type {number} */ get rollingFriction() { return this._rollingFriction; } /** * Sets the rigid body type determines how the body is simulated. Can be: * * - {@link BODYTYPE_STATIC}: infinite mass and cannot move. * - {@link BODYTYPE_DYNAMIC}: simulated according to applied forces. * - {@link BODYTYPE_KINEMATIC}: infinite mass and does not respond to forces (can only be * moved by setting the position and rotation of component's {@link Entity}). * * Defaults to {@link BODYTYPE_STATIC}. * * @type {BODYTYPE_DYNAMIC|BODYTYPE_KINEMATIC|BODYTYPE_STATIC} */ set type(type) { if (this._type !== type) { this._type = type; this.disableSimulation(); switch (type) { case BODYTYPE_DYNAMIC: this._group = BODYGROUP_DYNAMIC; this._mask = BODYMASK_ALL; break; case BODYTYPE_KINEMATIC: this._group = BODYGROUP_KINEMATIC; this._mask = BODYMASK_ALL; break; case BODYTYPE_STATIC: default: this._group = BODYGROUP_STATIC; this._mask = BODYMASK_NOT_STATIC; break; } this.createBody(); } } /** * Gets the rigid body type determines how the body is simulated. * * @type {BODYTYPE_DYNAMIC|BODYTYPE_KINEMATIC|BODYTYPE_STATIC} */ get type() { return this._type; } /** * If the Entity has a Collision shape attached then create a rigid body using this shape. This * method destroys the existing body. * * @private */ createBody() { const entity = this.entity; let shape; if (entity.collision) { shape = entity.collision.shape; if (entity.trigger) { entity.trigger.destroy(); delete entity.trigger; } } const world = this.system.physicsWorld; if (shape && world) { if (this._body) { world.removeBody(this._body); world.destroyBody(this._body); this._body = null; } const mass = this._type === BODYTYPE_DYNAMIC ? this._mass : 0; this._getEntityTransform(_position, _rotation); const body = world.createBody({ type: this._type, mass, shape, position: _position, rotation: _rotation, entity }); body.setRestitution(this._restitution); body.setFriction(this._friction); body.setRollingFriction(this._rollingFriction); body.setDamping(this._linearDamping, this._angularDamping); if (this._type === BODYTYPE_DYNAMIC) { body.setLinearFactor(this._linearFactor); body.setAngularFactor(this._angularFactor); } this.body = body; if (this.enabled && entity.enabled) { this.enableSimulation(); } } } /** * Returns true if the rigid body is currently actively being simulated. I.e. Not 'sleeping'. * * @returns {boolean} True if the body is active. */ isActive() { return this._body ? this._body.isActive() : false; } /** * Forcibly activate the rigid body simulation. Only affects rigid bodies of type * {@link BODYTYPE_DYNAMIC}. */ activate() { if (this._body) { this._body.activate(); } } /** * Add a body to the simulation. * * @ignore */ enableSimulation() { this.system.enableSimulation(this); } /** * Remove a body from the simulation. * * @ignore */ disableSimulation() { this.system.disableSimulation(this); } /** * Apply a force to the body at a point. By default, the force is applied at the origin of the * body. However, the force can be applied at an offset from this point by specifying a world * space vector from the body's origin to the point of application. * * @overload * @param {number} x - X-component of the force in world space. * @param {number} y - Y-component of the force in world space. * @param {number} z - Z-component of the force in world space. * @param {number} [px] - X-component of the relative point at which to apply the force in * world space. * @param {number} [py] - Y-component of the relative point at which to apply the force in * world space. * @param {number} [pz] - Z-component of the relative point at which to apply the force in * world space. * @returns {void} * @example * // Apply an approximation of gravity at the body's center * this.entity.rigidbody.applyForce(0, -10, 0); * @example * // Apply an approximation of gravity at 1 unit down the world Z from the center of the body * this.entity.rigidbody.applyForce(0, -10, 0, 0, 0, 1); */ /** * Apply a force to the body at a point. By default, the force is applied at the origin of the * body. However, the force can be applied at an offset from this point by specifying a world * space vector from the body's origin to the point of application. * * @overload * @param {Vec3} force - Vector representing the force in world space. * @param {Vec3} [relativePoint] - Optional vector representing the relative point at which to * apply the force in world space. * @returns {void} * @example * // Calculate a force vector pointing in the world space direction of the entity * const force = this.entity.forward.clone().mulScalar(100); * * // Apply the force at the body's center * this.entity.rigidbody.applyForce(force); * @example * // Apply a force at some relative offset from the body's center * // Calculate a force vector pointing in the world space direction of the entity * const force = this.entity.forward.clone().mulScalar(100); * * // Calculate the world space relative offset * const relativePoint = new Vec3(); * const childEntity = this.entity.findByName('Engine'); * relativePoint.sub2(childEntity.getPosition(), this.entity.getPosition()); * * // Apply the force * this.entity.rigidbody.applyForce(force, relativePoint); */ /** * @param {number|Vec3} x - X-component of the force in world space or a vector representing * the force in world space. * @param {number|Vec3} [y] - Y-component of the force in world space or a vector representing * the force in world space. * @param {number} [z] - Z-component of the force in world space. * @param {number} [px] - X-component of the relative point at which to apply the force in * world space. * @param {number} [py] - Y-component of the relative point at which to apply the force in * world space. * @param {number} [pz] - Z-component of the relative point at which to apply the force in * world space. */ applyForce(x, y, z, px, py, pz) { const body = this._body; if (body) { body.activate(); if (x instanceof Vec3) { _vecA.copy(x); } else { _vecA.set(x, y, z); } if (y instanceof Vec3) { _vecB.copy(y); } else if (px !== void 0) { _vecB.set(px, py, pz); } else { _vecB.set(0, 0, 0); } body.applyForce(_vecA, _vecB); } } /** * Apply torque (rotational force) to the body. * * @overload * @param {number} x - The x-component of the torque force in world space. * @param {number} y - The y-component of the torque force in world space. * @param {number} z - The z-component of the torque force in world space. * @returns {void} * @example * entity.rigidbody.applyTorque(0, 10, 0); */ /** * Apply torque (rotational force) to the body. * * @overload * @param {Vec3} torque - Vector representing the torque force in world space. * @returns {void} * @example * const torque = new Vec3(0, 10, 0); * entity.rigidbody.applyTorque(torque); */ /** * @param {number|Vec3} x - X-component of the torque force in world space or a vector * representing the torque force in world space. * @param {number} [y] - Y-component of the torque force in world space. * @param {number} [z] - Z-component of the torque force in world space. */ applyTorque(x, y, z) { const body = this._body; if (body) { body.activate(); if (x instanceof Vec3) { _vecA.copy(x); } else { _vecA.set(x, y, z); } body.applyTorque(_vecA); } } /** * Apply an impulse (instantaneous change of velocity) to the body at a point. * * @overload * @param {number} x - X-component of the impulse in world space. * @param {number} y - Y-component of the impulse in world space. * @param {number} z - Z-component of the impulse in world space. * @param {number} [px] - X-component of the point at which to apply the impulse in the local * space of the entity. * @param {number} [py] - Y-component of the point at which to apply the impulse in the local * space of the entity. * @param {number} [pz] - Z-component of the point at which to apply the impulse in the local * space of the entity. * @returns {void} * @example * // Apply an impulse along the world space positive y-axis at the entity's position. * entity.rigidbody.applyImpulse(0, 10, 0); * @example * // Apply an impulse along the world space positive y-axis at 1 unit down the positive * // z-axis of the entity's local space. * entity.rigidbody.applyImpulse(0, 10, 0, 0, 0, 1); */ /** * Apply an impulse (instantaneous change of velocity) to the body at a point. * * @overload * @param {Vec3} impulse - Vector representing the impulse in world space. * @param {Vec3} [relativePoint] - Optional vector representing the relative point at which to * apply the impulse in the local space of the entity. * @returns {void} * @example * // Apply an impulse along the world space positive y-axis at the entity's position. * const impulse = new Vec3(0, 10, 0); * entity.rigidbody.applyImpulse(impulse); * @example * // Apply an impulse along the world space positive y-axis at 1 unit down the positive * // z-axis of the entity's local space. * const impulse = new Vec3(0, 10, 0); * const relativePoint = new Vec3(0, 0, 1); * entity.rigidbody.applyImpulse(impulse, relativePoint); */ /** * @param {number|Vec3} x - X-component of the impulse in world space or a vector representing * the impulse in world space. * @param {number|Vec3} [y] - Y-component of the impulse in world space or a vector representing * the relative point at which to apply the impulse in the local space of the entity. * @param {number} [z] - Z-component of the impulse in world space. * @param {number} [px] - X-component of the point at which to apply the impulse in the local * space of the entity. * @param {number} [py] - Y-component of the point at which to apply the impulse in the local * space of the entity. * @param {number} [pz] - Z-component of the point at which to apply the impulse in the local * space of the entity. */ applyImpulse(x, y, z, px, py, pz) { const body = this._body; if (body) { body.activate(); if (x instanceof Vec3) { _vecA.copy(x); } else { _vecA.set(x, y, z); } if (y instanceof Vec3) { _vecB.copy(y); } else if (px !== void 0) { _vecB.set(px, py, pz); } else { _vecB.set(0, 0, 0); } body.applyImpulse(_vecA, _vecB); } } /** * Apply a torque impulse (rotational force applied instantaneously) to the body. * * @overload * @param {number} x - X-component of the torque impulse in world space. * @param {number} y - Y-component of the torque impulse in world space. * @param {number} z - Z-component of the torque impulse in world space. * @returns {void} * @example * entity.rigidbody.applyTorqueImpulse(0, 10, 0); */ /** * Apply a torque impulse (rotational force applied instantaneously) to the body. * * @overload * @param {Vec3} torque - Vector representing the torque impulse in world space. * @returns {void} * @example * const torque = new Vec3(0, 10, 0); * entity.rigidbody.applyTorqueImpulse(torque); */ /** * @param {number|Vec3} x - X-component of the torque impulse in world space or a vector * representing the torque impulse in world space. * @param {number} [y] - Y-component of the torque impulse in world space. * @param {number} [z] - Z-component of the torque impulse in world space. */ applyTorqueImpulse(x, y, z) { const body = this._body; if (body) { body.activate(); if (x instanceof Vec3) { _vecA.copy(x); } else { _vecA.set(x, y, z); } body.applyTorqueImpulse(_vecA); } } /** * Returns true if the rigid body is of type {@link BODYTYPE_STATIC}. * * @returns {boolean} True if static. */ isStatic() { return this._type === BODYTYPE_STATIC; } /** * Returns true if the rigid body is of type {@link BODYTYPE_STATIC} or {@link BODYTYPE_KINEMATIC}. * * @returns {boolean} True if static or kinematic. */ isStaticOrKinematic() { return this._type === BODYTYPE_STATIC || this._type === BODYTYPE_KINEMATIC; } /** * Returns true if the rigid body is of type {@link BODYTYPE_KINEMATIC}. * * @returns {boolean} True if kinematic. */ isKinematic() { return this._type === BODYTYPE_KINEMATIC; } /** * Reads the entity transform (with any collision component offsets applied) but ignoring * scale. * * @param {Vec3} position - The vector to write the world space position to. * @param {Quat} rotation - The quaternion to write the world space rotation to. * @private */ _getEntityTransform(position, rotation) { const entity = this.entity; const component = entity.collision; if (component) { position.copy(component.getShapePosition()); rotation.copy(component.getShapeRotation()); } else { position.copy(entity.getPosition()); rotation.copy(entity.getRotation()); } } /** * Set the rigid body transform to be the same as the Entity transform. This must be called * after any Entity transformation functions (e.g. {@link Entity#setPosition}) are called in * order to update the rigid body to match the Entity. * * @private */ syncEntityToBody() { const body = this._body; if (body) { this._getEntityTransform(_position, _rotation); body.setTransform(_position, _rotation); } } /** * Sets an entity's transform to match that of the world transformation matrix of a dynamic * rigid body's motion state. * * @private */ _updateDynamic() { const body = this._body; if (body.isActive()) { const entity = this.entity; body.getTransform(_position, _rotation); const component = entity.collision; if (component && component._hasOffset) { const lo = component.linearOffset; const ao = component.angularOffset; const invertedAo = _quat2.copy(ao).invert(); const entityRot = _quat1.copy(_rotation).mul(invertedAo); entityRot.transformVector(lo, _vec3); entity.setPositionAndRotation(_position.sub(_vec3), entityRot); } else { entity.setPositionAndRotation(_position, _rotation); } } } /** * Writes the entity's world transform into the kinematic target of a kinematic body. * * @private */ _updateKinematic() { this._getEntityTransform(_position, _rotation); this._body.setKinematicTarget(_position, _rotation); } /** * Teleport an entity to a new world space position, optionally setting orientation. This * function should only be called for rigid bodies that are dynamic. * * @overload * @param {number} x - X-coordinate of the new world space position. * @param {number} y - Y-coordinate of the new world space position. * @param {number} z - Z-coordinate of the new world space position. * @param {number} [rx] - X-rotation of the world space Euler angles in degrees. * @param {number} [ry] - Y-rotation of the world space Euler angles in degrees. * @param {number} [rz] - Z-rotation of the world space Euler angles in degrees. * @returns {void} * @example * // Teleport the entity to the origin * entity.rigidbody.teleport(0, 0, 0); * @example * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation * entity.rigidbody.teleport(1, 2, 3, 0, 0, 0); */ /** * Teleport an entity to a new world space position, optionally setting orientation. This * function should only be called for rigid bodies that are dynamic. * * @overload * @param {Vec3} position - Vector holding the new world space position. * @param {Vec3} [angles] - Vector holding the new world space Euler angles in degrees. * @returns {void} * @example * // Teleport the entity to the origin * entity.rigidbody.teleport(Vec3.ZERO); * @example * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation * const position = new Vec3(1, 2, 3); * entity.rigidbody.teleport(position, Vec3.ZERO); */ /** * Teleport an entity to a new world space position, optionally setting orientation. This * function should only be called for rigid bodies that are dynamic. * * @overload * @param {Vec3} position - Vector holding the new world space position. * @param {Quat} [rotation] - Quaternion holding the new world space rotation. * @returns {void} * @example * // Teleport the entity to the origin * entity.rigidbody.teleport(Vec3.ZERO); * @example * // Teleport the entity to world space coordinate [1, 2, 3] and reset orientation * const position = new Vec3(1, 2, 3); * entity.rigidbody.teleport(position, Quat.IDENTITY); */ /** * @param {number|Vec3} x - X-coordinate of the new world space position or a vector holding * the new world space position. * @param {number|Quat|Vec3} [y] - Y-coordinate of the new world space position or a * quaternion holding the new world space rotation or a vector holding the new world space * Euler angles in degrees. * @param {number} [z] - Z-coordinate of the new world space position. * @param {number} [rx] - X-rotation of the new world space Euler angles in degrees. * @param {number} [ry] - Y-rotation of the new world space Euler angles in degrees. * @param {number} [rz] - Z-rotation of the new world space Euler angles in degrees. */ teleport(x, y, z, rx, ry, rz) { if (x instanceof Vec3) { this.entity.setPosition(x); } else { this.entity.setPosition(x, y, z); } if (y instanceof Quat) { this.entity.setRotation(y); } else if (y instanceof Vec3) { this.entity.setEulerAngles(y); } else if (rx !== void 0) { this.entity.setEulerAngles(rx, ry, rz); } this.syncEntityToBody(); } /** @ignore */ onEnable() { if (!this._body) { this.createBody(); } this.enableSimulation(); } /** @ignore */ onDisable() { this.disableSimulation(); } } /** * Fired when a contact occurs between two rigid bodies. The handler is passed a * {@link ContactResult} object containing details of the contact between the two rigid bodies. * * @event * @example * entity.rigidbody.on('contact', (result) => { * console.log(`Contact between ${entity.name} and ${result.other.name}`); * }); */ __publicField(RigidBodyComponent, "EVENT_CONTACT", "contact"); /** * Fired when two rigid bodies start touching. The handler is passed a {@link ContactResult} * object containing details of the contact between the two rigid bodies. * * @event * @example * entity.rigidbody.on('collisionstart', (result) => { * console.log(`Collision started between ${entity.name} and ${result.other.name}`); * }); */ __publicField(RigidBodyComponent, "EVENT_COLLISIONSTART", "collisionstart"); /** * Fired when two rigid bodies stop touching. The handler is passed an {@link Entity} that * represents the other rigid body involved in the collision. * * @event * @example * entity.rigidbody.on('collisionend', (other) => { * console.log(`${entity.name} stopped touching ${other.name}`); * }); */ __publicField(RigidBodyComponent, "EVENT_COLLISIONEND", "collisionend"); /** * Fired when a rigid body enters a trigger volume. The handler is passed an {@link Entity} * representing the trigger volume that this rigid body entered. * * @event * @example * entity.rigidbody.on('triggerenter', (trigger) => { * console.log(`Entity ${entity.name} entered trigger volume ${trigger.name}`); * }); */ __publicField(RigidBodyComponent, "EVENT_TRIGGERENTER", "triggerenter"); /** * Fired when a rigid body exits a trigger volume. The handler is passed an {@link Entity} * representing the trigger volume that this rigid body exited. * * @event * @example * entity.rigidbody.on('triggerleave', (trigger) => { * console.log(`Entity ${entity.name} exited trigger volume ${trigger.name}`); * }); */ __publicField(RigidBodyComponent, "EVENT_TRIGGERLEAVE", "triggerleave"); __publicField(RigidBodyComponent, "order", -1); export { RigidBodyComponent };