Skip to content

Commit ca892ac

Browse files
authored
Merge pull request #261 from gregfagan/master
Fix look-at component for vec3 targets and cameras
2 parents aec9139 + d2282ca commit ca892ac

File tree

2 files changed

+62
-18
lines changed

2 files changed

+62
-18
lines changed

components/look-at/examples/basic/index.html

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,28 @@
66
<meta property="og:image" content="https://raw.githubusercontent.com/supermedium/superframe/master/components/look-at/examples/basic/preview.gif"></meta>
77
<script src="https://aframe.io/releases/0.9.0/aframe.min.js"></script>
88
<script src="../../dist/aframe-look-at-component.min.js"></script>
9+
<script>
10+
/**
11+
* Use the spacebar to swap the camera to one that is looking at the target.
12+
*
13+
* Probably shouldn't do it in VR.
14+
*/
15+
AFRAME.registerComponent('toggleable-camera', {
16+
init: function () {
17+
document.addEventListener('keydown', AFRAME.utils.bind(this.toggleCamera, this));
18+
},
19+
toggleCamera: function (e) {
20+
if (e.code === 'Space') {
21+
if (this.el.hasAttribute('camera')) {
22+
this.el.removeAttribute('camera');
23+
this.el.sceneEl.querySelector('#look-cam').setAttribute('camera', 'active', true);
24+
} else {
25+
this.el.setAttribute('camera', { active: true });
26+
}
27+
}
28+
}
29+
})
30+
</script>
931
</head>
1032
<body>
1133
<a-scene>
@@ -29,13 +51,18 @@
2951
<a-cylinder radius="0.2" height="2" color="#7BC8A4" look-at="#target"
3052
position="-4 0 1"></a-cylinder>
3153
<a-box width="2" depth="1" height="0.25" color="#93648D" look-at="#target"
32-
position="0 0 1"></a-box>
54+
position="0 0 1" toggleable-camera></a-box>
3355
<a-box width="1" depth="2" height="0.5" color="#999" look-at="#target"
3456
position="4 0 1"></a-box>
3557

3658
<!-- This entity looks at the camera. Use WASD controls to test it -->
3759
<a-box width="2" depth="2" height="2" color="#FFC65D" look-at="#look-cam"
3860
position="-6 2.5 -2"></a-box>
61+
62+
<!-- This entity looks at the origin. Cone rotated to point in its lookAt direction. -->
63+
<a-entity position="-4 4 -8" look-at="0 0 0">
64+
<a-cone height="1" color="#C388A3" radius-bottom="0.5" radius-top="0" rotation="90 0 0"></a-cone>
65+
</a-entity>
3966
</a-entity>
4067

4168
<a-sky color="#ECECEC"></a-sky>

components/look-at/index.js

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ delete AFRAME.components['look-at'];
1717
*/
1818
AFRAME.registerComponent('look-at', {
1919
schema: {
20-
default: '',
20+
default: '0 0 0',
2121

2222
parse: function (value) {
2323
// A static position to look at.
@@ -39,6 +39,9 @@ AFRAME.registerComponent('look-at', {
3939
init: function () {
4040
this.target3D = null;
4141
this.vector = new THREE.Vector3();
42+
this.cameraListener = AFRAME.utils.bind(this.cameraListener, this);
43+
this.el.addEventListener('componentinitialized', this.cameraListener);
44+
this.el.addEventListener('componentremoved', this.cameraListener);
4245
},
4346

4447
/**
@@ -48,7 +51,6 @@ AFRAME.registerComponent('look-at', {
4851
update: function () {
4952
var self = this;
5053
var target = self.data;
51-
var object3D = self.el.object3D;
5254
var targetEl;
5355

5456
// No longer looking at anything (i.e., look-at="").
@@ -58,7 +60,7 @@ AFRAME.registerComponent('look-at', {
5860

5961
// Look at a position.
6062
if (typeof target === 'object') {
61-
return object3D.lookAt(new THREE.Vector3(target.x, target.y, target.z));
63+
return this.lookAt(new THREE.Vector3(target.x, target.y, target.z));
6264
}
6365

6466
// Assume target is a string.
@@ -83,27 +85,42 @@ AFRAME.registerComponent('look-at', {
8385
return function (t) {
8486
// Track target object position. Depends on parent object keeping global transforms up
8587
// to state with updateMatrixWorld(). In practice, this is handled by the renderer.
86-
var target;
8788
var target3D = this.target3D;
88-
var object3D = this.el.object3D;
89-
var vector = this.vector;
90-
9189
if (target3D) {
9290
target3D.getWorldPosition(vec3);
93-
if (this.el.getObject3D('camera')) {
94-
// Flip the vector to -z, looking away from target for camera entities. When using
95-
// lookat from THREE camera objects, this is applied for you, but since the camera is
96-
// nested into a Object3D, we need to apply this manually.
97-
// vector.subVectors(object3D.position, vec3).add(object3D.position);
98-
} else {
99-
vector = vec3;
100-
}
101-
object3D.lookAt(vector);
91+
this.lookAt(vec3);
10292
}
103-
};
93+
}
10494
})(),
10595

96+
remove: function () {
97+
this.el.removeEventListener('componentinitialized', this.cameraListener);
98+
this.el.removeEventListener('componentremoved', this.cameraListener);
99+
},
100+
106101
beginTracking: function (targetEl) {
107102
this.target3D = targetEl.object3D;
103+
},
104+
105+
cameraListener: function (e) {
106+
if (e.detail && e.detail.name === 'camera') {
107+
this.update();
108+
}
109+
},
110+
111+
lookAt: function (position) {
112+
var vector = this.vector;
113+
var object3D = this.el.object3D;
114+
115+
if (this.el.getObject3D('camera')) {
116+
// Flip the vector to -z, looking away from target for camera entities. When using
117+
// lookat from THREE camera objects, this is applied for you, but since the camera is
118+
// nested into a Object3D, we need to apply this manually.
119+
vector.subVectors(object3D.position, position).add(object3D.position);
120+
} else {
121+
vector.copy(position);
122+
}
123+
124+
object3D.lookAt(vector);
108125
}
109126
});

0 commit comments

Comments
 (0)