123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212 |
- import RAPIER from '@dimforge/rapier3d-compat';
- import * as RE from 'rogue-engine';
- import * as THREE from 'three';
- import RogueRapier from '../Lib/RogueRapier';
- export type RapierCollisionInfo = {ownCollider: RAPIER.Collider, otherCollider: RAPIER.Collider, otherBody: RapierBody};
- export default class RapierBody extends RE.Component {
- @RE.props.select() type = 0;
- typeOptions = ["Dynamic", "Fixed", "KinematicPositionBased", "KinematicVelocityBased"];
- @RE.props.num() mass = 1;
- private _gravityScale = 1;
- @RE.props.num()
- get gravityScale() {
- return this._gravityScale;
- }
- set gravityScale(value: number) {
- this._gravityScale = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setGravityScale(value, true));
- }
-
- private _angularDamping = 0;
- @RE.props.num()
- get angularDamping() {
- return this._angularDamping;
- }
- set angularDamping(value: number) {
- this._angularDamping = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setAngularDamping(value));
- }
- private _linearDamping = 0;
- @RE.props.num()
- get linearDamping() {
- this.body
- return this._linearDamping;
- }
- set linearDamping(value: number) {
- this._linearDamping = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setLinearDamping(value));
- }
- private _xTranslation = true;
- @RE.props.checkbox()
- get xTranslation() {
- return this._xTranslation;
- }
- set xTranslation(value: boolean) {
- this._xTranslation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledTranslations(value, this._yTranslation, this._zTranslation, true));
- }
- private _yTranslation = true;
- @RE.props.checkbox()
- get yTranslation() {
- return this._yTranslation;
- }
- set yTranslation(value: boolean) {
- this._yTranslation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledTranslations(this._xTranslation, value, this._zTranslation, true));
- }
- private _zTranslation = true;
- @RE.props.checkbox()
- get zTranslation() {
- return this._zTranslation;
- }
- set zTranslation(value: boolean) {
- this._zTranslation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledTranslations(this._xTranslation, this._yTranslation, value, true));
- }
- private _xRotation = true;
- @RE.props.checkbox()
- get xRotation() {
- return this._xRotation;
- }
- set xRotation(value: boolean) {
- this._xRotation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledRotations(value, this._yRotation, this._zRotation, true));
- }
- private _yRotation = true;
- @RE.props.checkbox()
- get yRotation() {
- return this._yRotation;
- }
- set yRotation(value: boolean) {
- this._yRotation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledRotations(this._xRotation, value, this._zRotation, true));
- }
- private _zRotation = true;
- @RE.props.checkbox()
- get zRotation() {
- return this._zRotation;
- }
- set zRotation(value: boolean) {
- this._zRotation = value;
- RE.Runtime.isRunning &&
- this.body && (this.body.setEnabledRotations(this._xRotation, this._yRotation, value, true));
- }
- body: RAPIER.RigidBody;
- initialized = false;
- onCollisionStart: (info: RapierCollisionInfo) => void = () => {};
- onCollisionEnd: (info: RapierCollisionInfo) => void = () => {};
- private newPos = new THREE.Vector3();
- private newRot = new THREE.Quaternion();
- private matrixA = new THREE.Matrix4();
- private matrixB = new THREE.Matrix4();
- private matrixC = new THREE.Matrix4();
- init() {
- let rigidBodyDesc = this.getType();
- // const pos = this.object3d.position;
- // const rot = this.object3d.quaternion;
- this.object3d.getWorldPosition(this.newPos);
- this.object3d.getWorldQuaternion(this.newRot);
-
- rigidBodyDesc
- .setGravityScale(this._gravityScale)
- .setTranslation(this.newPos.x, this.newPos.y, this.newPos.z)
- .setRotation(this.newRot)
- .setAngularDamping(this._angularDamping)
- .setLinearDamping(this._linearDamping)
- .enabledRotations(this._xRotation, this._yRotation, this._zRotation)
- .enabledTranslations(this._xTranslation, this._yTranslation, this._zTranslation);
- rigidBodyDesc.mass = this.mass;
- this.body = RogueRapier.world.createRigidBody(rigidBodyDesc);
- this.body.userData = {object3d: this.object3d.uuid};
- this.initialized = true;
- }
- private getType() {
- if (Number(this.type) === 1) return RAPIER.RigidBodyDesc.fixed();
- else if (Number(this.type) === 2) return RAPIER.RigidBodyDesc.kinematicPositionBased();
- else if (Number(this.type) === 3) return RAPIER.RigidBodyDesc.kinematicVelocityBased();
- else return RAPIER.RigidBodyDesc.dynamic();
- }
- onBeforeRemoved(): void {
- if (this.body) {
- RogueRapier.world.removeRigidBody(this.body);
- }
- }
- onDisabled(): void {
- if (this.body) {
- RogueRapier.world.removeRigidBody(this.body);
- }
- }
- beforeUpdate(): void {
- if (!RogueRapier.initialized) return;
- !this.initialized && this.init();
- this.type !== RAPIER.RigidBodyType.Fixed &&
- this.updatePhysics();
- }
- updatePhysics() {
- this.copyBodyPosition();
- this.copyBodyRotation();
- }
- private copyBodyPosition() {
- const pos = this.body.translation();
- this.newPos.set(pos.x, pos.y, pos.z);
-
- this.object3d.parent?.worldToLocal(this.newPos);
- this.object3d.position.copy(this.newPos);
- }
- private copyBodyRotation() {
- const rot = this.body.rotation();
- this.newRot.set(rot.x, rot.y, rot.z, rot.w);
- this.matrixA.makeRotationFromQuaternion(this.newRot);
- this.object3d.updateMatrixWorld();
- this.matrixB.copy((this.object3d.parent as THREE.Object3D).matrixWorld).invert();
- this.matrixC.extractRotation(this.matrixB);
- this.matrixA.premultiply(this.matrixC);
- this.object3d.quaternion.setFromRotationMatrix(this.matrixA);
- }
- }
- RE.registerComponent(RapierBody);
|