UNPKG

@c-frame/aframe-physics-system

Version:

Physics system for A-Frame VR, built on Cannon.js & Ammo.js

81 lines (66 loc) 2.25 kB
/** * Force Pushable component. * * Applies behavior to the current entity such that cursor clicks will apply a * strong impulse, pushing the entity away from the viewer. * * Requires: physics */ AFRAME.registerComponent('force-pushable', { schema: { force: { default: 10 } }, init: function () { if (this.el.sceneEl.getAttribute('physics').driver === "ammo") { this.driver = "ammo" } else { this.driver = "cannon" } this.pStart = new THREE.Vector3(); this.sourceEl = this.el.sceneEl.querySelector('[camera]'); if (this.driver === "cannon") { this.el.addEventListener('click', this.forcePushCannon.bind(this)); } else { this.el.addEventListener('click', this.forcePushAmmo.bind(this)); this.force = new THREE.Vector3(); this.pos = new THREE.Vector3(); this.el.addEventListener("body-loaded", e => { this.impulseBtVector = new Ammo.btVector3(); this.posBtVector = new Ammo.btVector3(); }); } }, forcePushCannon: function () { var force, el = this.el, pStart = this.pStart.copy(this.sourceEl.getAttribute('position')); // Compute direction of force, normalize, then scale. force = el.body.position.vsub(pStart); force.normalize(); force.scale(this.data.force, force); el.body.applyImpulse(force, el.body.position); }, forcePushAmmo: function (e) { if (!this.impulseBtVector) return; const el = this.el const force = this.force const impulseBt = this.impulseBtVector const pusher = e.detail.cursorEl.object3D force.copy(pusher.position) pusher.localToWorld(force) force.copy(el.object3D.position.sub(force)) force.normalize(); force.multiplyScalar(this.data.force); impulseBt.setValue(force.x, force.y, force.z) // use data from intersection to determine point at which to apply impulse. const pos = this.pos const posBt = this.posBtVector pos.copy(e.detail.intersection.point) el.object3D.worldToLocal(pos) posBt.setValue(pos.x, pos.y, pos.z) el.body.activate() el.body.applyImpulse(impulseBt, posBt); } });