UNPKG

@threejs-addons/threejs-addons

Version:

free & opensource threejs addons to boost productivity

188 lines (187 loc) 8.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.RapierColliderController = void 0; const Base_1 = require("./Base"); const Vector3_1 = require("three/src/math/Vector3"); const Quaternion_1 = require("three/src/math/Quaternion"); class RapierColliderController extends Base_1.BaseController { constructor({ world, offset, options, CCC }) { super({ target: null, options, CCC }); this.collider = null; this.toi = 0; this.world = world; this.offset = offset; this.controller = this.initCharacterController(); } /** * @description sets up the character controller * @returns CharacterController */ initCharacterController() { return this.world.createCharacterController(this.offset); } /** * * @description compute movements of collider * @returns number of collisions */ computeMovement({ collider, desiredMovementVector, filterFlags, filterGroups, filterPredicate }) { let c = collider || this.collider; if (!c) return null; if (!desiredMovementVector) return null; this.controller.computeColliderMovement(c, desiredMovementVector, filterFlags, filterGroups, filterPredicate); return this.controller.numComputedCollisions(); } /** * @description get computed collisions * @returns Array of collisions */ getComputedCollisions() { let collisions = []; for (let i = 0; i < this.controller.numComputedCollisions(); i++) { let collision = this.controller.computedCollision(i); collisions.push(collision); } return collisions; } /** * @description wether or not collision is imminent */ isCollisionImminent() { let is_collision_imminent = false; for (let i = 0; i < this.controller.numComputedCollisions(); i++) { let collision = this.controller.computedCollision(i); if (collision.toi <= this.toi) is_collision_imminent = true; } return is_collision_imminent; } /** * @description get corrected movement */ getCorrectedMovement() { const { x, y, z } = this.controller.computedMovement(); return new Vector3_1.Vector3(x, y, z); } /** * @param collider * @param updateTargetPosition Wether or not to update the target position. This forces the controller to try and update target position even if the collider is null * @description sets the collider */ setCollider(collider, updateTargetPosition) { this.collider = collider; if (!this.target && !updateTargetPosition) return; const { x, y, z } = this.collider.translation(); this.desiredMovementVector = new Vector3_1.Vector3(x, y, z); this.updateTargetPosition(); } /** @description handle XYZ movements */ handleTranslateXYZDirection() { var _a, _b, _c, _d, _e; if (!this.collider) return; this.setColliderQuaternionFromCameraController(); const { x: cx, y: cy, z: cz } = this.collider.translation(); const computedTranslation = Base_1.BaseController.computeTranslationXYZDirection({ speedFactor: this.speedFactor, SPEED_UP_CONSTANT: this.SPEED_UP_CONSTANT, delta: this.delta, direction: this.direction, translation: new Vector3_1.Vector3(cx, cy, cz), cameraController: (_a = this.CCC) === null || _a === void 0 ? void 0 : _a.activeController }); if (!computedTranslation) return; const { position: desiredMovementVector, velocity: desiredVelocityVector } = computedTranslation; const shape = (_b = this.collider) === null || _b === void 0 ? void 0 : _b.shape; const shapePosition = (_c = this.collider) === null || _c === void 0 ? void 0 : _c.translation(); const shapeRotation = (_d = this.collider) === null || _d === void 0 ? void 0 : _d.rotation(); const shapeVelocity = desiredVelocityVector.clone(); let collisions = []; let hit = this.world.castShape(shapePosition, shapeRotation, shapeVelocity, shape, this.toi, false, undefined, (_e = this.options) === null || _e === void 0 ? void 0 : _e.filterGroups, this.collider); if (hit != null) { collisions.push(hit); } let is_collision_imminent = false; let collision_imminent = null; for (const collision of collisions) { if (collision.toi <= this.toi) is_collision_imminent = true; if (is_collision_imminent) collision_imminent = collision; if (is_collision_imminent) break; } if (is_collision_imminent && collision_imminent && (collision_imminent === null || collision_imminent === void 0 ? void 0 : collision_imminent.toi) <= this.toi) { this.desiredVelocityVector = new Vector3_1.Vector3(0, 0, 0); } else { this.desiredMovementVector = desiredMovementVector; /** carry out corrections based on max an min translation options */ // this.desiredMovementVector.y = Math.min(Math.max(this.desiredMovementVector.y, this.options?.translation?.max?.y), this.options?.translation?.max?.y); // this.desiredVelocityVector = desiredVelocityVector; // this.desiredVelocityVector.y = Math.min(Math.max(this.desiredMovementVector.y, this.options?.translation?.max?.y), this.options?.translation?.max?.y); this.desiredMovementVector.y = shapePosition.y; this.desiredVelocityVector = desiredVelocityVector; this.desiredVelocityVector.y = 0; } /** update computational values */ this.updateColliderPosition(); // this current colliders position this.updateTargetPosition(); //if target is attached this.updateTargetQuaternion(); // if target is attached /** update internal values */ this._updateColliderPosition(); this._updateColliderQuaternion(); this._updateColliderVelocity(); } /** * @description set max time to impact for collider */ setToi(value) { this.toi = value; } /** set collider quartenion */ setColliderQuaternionFromCameraController() { var _a, _b, _c, _d, _e; if (!this.collider) return; if (!((_a = this.CCC) === null || _a === void 0 ? void 0 : _a.activeController)) return; this.collider.setRotation({ x: (_b = this.CCC.activeController) === null || _b === void 0 ? void 0 : _b.camera.quaternion.x, y: (_c = this.CCC.activeController) === null || _c === void 0 ? void 0 : _c.camera.quaternion.y, z: (_d = this.CCC.activeController) === null || _d === void 0 ? void 0 : _d.camera.quaternion.z, w: (_e = this.CCC.activeController) === null || _e === void 0 ? void 0 : _e.camera.quaternion.w }); } updateColliderPosition() { if (this.collider) this.collider.setTranslation(this.desiredMovementVector); } /** update internal this.position value */ _updateColliderPosition() { if (!this.collider) return; this.position.copy(this.desiredMovementVector); } /** update internal this.rotation value */ _updateColliderQuaternion() { if (!this.collider) return; const { x, y, z, w } = this.collider.rotation(); this.rotation.copy(new Quaternion_1.Quaternion(x, y, z, w)); } /** update internal this.velocity */ _updateColliderVelocity() { if (!this.collider) return; this.velocity.copy(this.desiredVelocityVector); } /** update filter groups on options */ updateFilterGroups(groups) { this.options.filterGroups = groups; } /** update options */ updateOptions(options) { this.options = options; } } exports.RapierColliderController = RapierColliderController;