Skip to content

Commit

Permalink
Merge pull request #28 from diarmidmackenzie/mouse-manipulation-trans…
Browse files Browse the repository at this point in the history
…form-mode

Add controlMethod: transform to mouse-manipulation
  • Loading branch information
diarmidmackenzie committed Dec 15, 2023
2 parents 21063dd + 55306a0 commit 161cc54
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 1,374 deletions.
3 changes: 2 additions & 1 deletion components/mouse-manipulation/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Controls are as follows:
Via CDN

```
<script src="https://cdn.jsdelivr.net/npm/aframe-mouse-manipulation@0.2.1/dist/mouse-manipulation.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/aframe-mouse-manipulation@0.3.0/dist/mouse-manipulation.min.js"></script>
```

Or via [npm](https://www.npmjs.com/package/aframe-laser-manipulation)
Expand Down Expand Up @@ -61,6 +61,7 @@ npm install aframe-mouse-manipulation
| grabEvents | Whether to generate events when an entity is grabbed / released | false |
| grabEvent | If `grabEvents` is true, the name of the event to generate when an entity is grabbed | laserGrab |
| releaseEvent | If `grabEvents` is true, the name of the event to generate when an entity is released | laserRelease |
| controlMethod | Either 'parent' or 'transform'. <br />'parent' mode re-parents the object to become a descendant of the controller. This is a simpler method, and may be more performant and stable. However re-parenting can cause issues if code in other components makes assumptions about objects' positions in the THREE.js scene graph. 'transform' mode leaves the object in the same position in the THREE.js scene graph, and instead adjusts its transform every tick as required. | parent |



Expand Down
2 changes: 1 addition & 1 deletion components/mouse-manipulation/dist/mouse-manipulation.js

Large diffs are not rendered by default.

Large diffs are not rendered by default.

56 changes: 50 additions & 6 deletions components/mouse-manipulation/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ AFRAME.registerComponent('mouse-manipulation', {
showHints: {type: 'boolean', default: true},
grabEvents: {type: 'boolean', default: false},
grabEvent: {type: 'string', default: 'mouseGrab'},
releaseEvent: {type: 'string', default: 'mouseRelease'}
releaseEvent: {type: 'string', default: 'mouseRelease'},
controlMethod: {type: 'string', default: 'parent', oneOf: ['parent', 'transform']}
},

events: {
Expand All @@ -30,8 +31,10 @@ AFRAME.registerComponent('mouse-manipulation', {
// Take a root of this to get a scaling factor.
this.moveSpeed = 3;

// variable to track any grabbed element
// variable to track any grabbed element, and active controls state.
this.grabbedEl = null;
this.activeContactPoint = null;
this.activeControlMethod = '';

// We create 2 children beneath the camera
// - cursorTracker. This is set up to match the orientation of the cursor
Expand Down Expand Up @@ -83,6 +86,8 @@ AFRAME.registerComponent('mouse-manipulation', {

// adjustments to control ratio of mouse pixels to radians for otations.
this.radiansPerMousePixel = 0.01

this.lastContactPointTransform = new THREE.Object3D()
},

update: function() {
Expand Down Expand Up @@ -315,7 +320,15 @@ AFRAME.registerComponent('mouse-manipulation', {
const pos = contactPoint.object3D.position
this.grabbedEl.object3D.getWorldPosition(pos)
contactPoint.object3D.parent.worldToLocal(pos)
this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector)

if (this.data.controlMethod === 'parent') {
this.activeControlMethod = 'parent'
this.grabbedEl.setAttribute('object-parent', 'parent', contactPointSelector)
}
else {
this.activeControlMethod = 'transform'
this.saveContactPointTransform(contactPoint)
}

this.hints.object3D.position.set(0, 0 , 0)
contactPoint.object3D.add(this.hints.object3D)
Expand All @@ -327,13 +340,21 @@ AFRAME.registerComponent('mouse-manipulation', {

releaseEl() {
const contactPoint = this.grabbedEl.object3D.parent
this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`)

if (this.activeControlMethod === 'parent') {
this.grabbedEl.setAttribute('object-parent', 'parent', `#${this.originalParentEl.id}`)
}

if (this.data.grabEvents) {
this.grabbedEl.emit(this.data.releaseEvent)
// defer event to next schedule, to allow reparenting to have completed.
const releasedEl = this.grabbedEl
setTimeout(() => {
releasedEl.emit(this.data.releaseEvent)
})
}

this.grabbedEl = null
this.activeControlMethod = ''
this.originalParentEl = null

this.el.object3D.add(this.hints.object3D)
Expand Down Expand Up @@ -393,8 +414,31 @@ AFRAME.registerComponent('mouse-manipulation', {

const els = cursorEl.components.raycaster.intersectedEls
return els
}
},

saveContactPointTransform(contactPoint) {
const transform = this.lastContactPointTransform
transform.quaternion.identity()
transform.position.set(0, 0, 0)
transform.scale.set(1, 1, 1)
contactPoint.object3D.add(transform)
this.el.sceneEl.object3D.attach(transform)

this.activeContactPoint = contactPoint
},

followContactPoint() {
const object = this.grabbedEl.object3D
this.lastContactPointTransform.attach(object)
this.saveContactPointTransform(this.activeContactPoint)
this.originalParentEl.object3D.attach(object)
},

tick() {
if (this.activeControlMethod === 'transform') {
this.followContactPoint()
}
}
});

AFRAME.registerComponent('mouse-manipulation-hints', {
Expand Down
Loading

0 comments on commit 161cc54

Please sign in to comment.