UNPKG

@c-frame/physx

Version:

Physics for A-Frame using Nvidia PhysX

96 lines (76 loc) 2.94 kB
/** * Grab component. * * Based on an original component by Don McCurdy in aframe-physics-system * * Copyright (c) 2016 Don McCurdy */ AFRAME.registerComponent('physx-grab', { init: function () { // If a state of "grabbed" is set on a physx-body entity, // the entity is automatically transformed into a kinematic entity. // To avoid triggering this (we want to grab using constraints, and leave the // body as dynamic), we use a non-clashing name for the state we set on the entity when // grabbing it. this.GRABBED_STATE = 'grabbed-dynamic'; this.grabbing = false; this.hitEl = /** @type {AFRAME.Element} */ null; // Bind event handlers this.onHit = this.onHit.bind(this); this.onGripOpen = this.onGripOpen.bind(this); this.onGripClose = this.onGripClose.bind(this); }, play: function () { var el = this.el; el.addEventListener('contactbegin', this.onHit); el.addEventListener('gripdown', this.onGripClose); el.addEventListener('gripup', this.onGripOpen); el.addEventListener('trackpaddown', this.onGripClose); el.addEventListener('trackpadup', this.onGripOpen); el.addEventListener('triggerdown', this.onGripClose); el.addEventListener('triggerup', this.onGripOpen); }, pause: function () { var el = this.el; el.removeEventListener('contactbegin', this.onHit); el.removeEventListener('gripdown', this.onGripClose); el.removeEventListener('gripup', this.onGripOpen); el.removeEventListener('trackpaddown', this.onGripClose); el.removeEventListener('trackpadup', this.onGripOpen); el.removeEventListener('triggerdown', this.onGripClose); el.removeEventListener('triggerup', this.onGripOpen); }, onGripClose: function (evt) { this.grabbing = true; }, onGripOpen: function (evt) { var hitEl = this.hitEl; this.grabbing = false; if (!hitEl) { return; } hitEl.removeState(this.GRABBED_STATE); this.hitEl = undefined; this.removeJoint() }, onHit: function (evt) { var hitEl = evt.detail.otherComponent?.el; if (hitEl && hitEl.components['physx-body'].data.type === 'static') return; // If the element is already grabbed (it could be grabbed by another controller). // If the hand is not grabbing the element does not stick. // If we're already grabbing something you can't grab again. if (!hitEl || hitEl.is(this.GRABBED_STATE) || !this.grabbing || this.hitEl) { return; } hitEl.addState(this.GRABBED_STATE); this.hitEl = hitEl; this.addJoint(hitEl, evt.target) }, addJoint(el, target) { this.removeJoint() this.joint = document.createElement('a-entity') this.joint.setAttribute("physx-joint", `type: Fixed; target: #${target.id}`) el.appendChild(this.joint) }, removeJoint() { if (!this.joint) return this.joint.parentElement.removeChild(this.joint) this.joint = null } });