如何防止这两个立方体同时被拖动呢?
How to prevent these two cubes to be dragged at the same time?
下面是拖动的例子:https://codepen.io/alexcheninfo/pen/vKkgkE。如果将一个立方体放在另一个立方体之上并抓住前面的那个,那么后面的那个也会被拖动。
完整代码如下:
<script>
AFRAME.registerComponent('draggable', {
init() {
this.mouse = new THREE.Vector2();
this.scene = this.el.sceneEl;
this.camera = this.scene.camera;
this.obj = this.el.object3D;
this.scene.addEventListener('mousemove', e => {
this.mouse.x = (e.offsetX / this.scene.canvas.offsetWidth) * 2 - 1;
this.mouse.y = -(e.offsetY / this.scene.canvas.offsetHeight) * 2 + 1;
if (this.selected) {
let r = new THREE.Raycaster();
r.setFromCamera(this.mouse, this.camera);
let dist = this.obj.position.distanceTo(this.camera.position);
let point = r.ray.direction.multiplyScalar(dist);
this.el.setAttribute('position', `${point.x} ${point.y} ${point.z}`);
}
});
this.scene.addEventListener('mousedown', e => {
let r = new THREE.Raycaster();
r.setFromCamera(this.mouse, this.camera);
let intersected = r.intersectObject(this.el.object3D, true);
let objPos = this.el.object3D.position;
let camPos = this.camera.position;
console.log(objPos.distanceTo(camPos));
if (intersected.length) this.selected = true;
});
this.scene.addEventListener('mouseup', e => {
this.selected = undefined;
});
}
});
</script>
<a-scene>
<a-entity camera look-controls></a-entity>
<a-sky src="https://raw.githubusercontent.com/aframevr/aframe/master/examples/boilerplate/panorama/puydesancy.jpg"></a-sky>
<a-box color="tomato" position="-3 0 -10" draggable></a-box>
<a-box draggable position="3 0 -5" draggable></a-box>
</a-scene>
如何预防? (比如只能拖前面的立方体?)
这是因为您放置控件的位置。您正在对一台相机进行多光线投射,而不是对多物体进行单光线投射。如果你有一个 raycaster 知道它相交的所有东西(它会 return 按距离排序的对象),那就更容易了。 http://threejs.org/docs/api/core/Raycaster.html
我的结构是:
- 使用内置的raycaster 组件。 master 分支上即将发布的0.3.0 有改进API。 https://aframe.io/docs/master/components/raycaster.html
- 有一个依赖于 raycaster 组件的拖动器组件。
- 让拖动器组件仅与具有
draggable
组件、draggable
class 或 data-draggable
属性的对象相交。
<a-scene>
<a-camera>
<a-entity dragger></a-entity>
</a-camera>
<a-entity draggable></a-entity>
</a-scene>
AFRAME.registerComponent('dragger', {
init: function () {
// Configure raycaster.
this.el.setAttribute('raycaster', {
objects: '[draggable]',
// ...
});
},
tick: function () {
// Use this.el.components.raycaster.intersectedEls
}
});
下面是拖动的例子:https://codepen.io/alexcheninfo/pen/vKkgkE。如果将一个立方体放在另一个立方体之上并抓住前面的那个,那么后面的那个也会被拖动。
完整代码如下:
<script>
AFRAME.registerComponent('draggable', {
init() {
this.mouse = new THREE.Vector2();
this.scene = this.el.sceneEl;
this.camera = this.scene.camera;
this.obj = this.el.object3D;
this.scene.addEventListener('mousemove', e => {
this.mouse.x = (e.offsetX / this.scene.canvas.offsetWidth) * 2 - 1;
this.mouse.y = -(e.offsetY / this.scene.canvas.offsetHeight) * 2 + 1;
if (this.selected) {
let r = new THREE.Raycaster();
r.setFromCamera(this.mouse, this.camera);
let dist = this.obj.position.distanceTo(this.camera.position);
let point = r.ray.direction.multiplyScalar(dist);
this.el.setAttribute('position', `${point.x} ${point.y} ${point.z}`);
}
});
this.scene.addEventListener('mousedown', e => {
let r = new THREE.Raycaster();
r.setFromCamera(this.mouse, this.camera);
let intersected = r.intersectObject(this.el.object3D, true);
let objPos = this.el.object3D.position;
let camPos = this.camera.position;
console.log(objPos.distanceTo(camPos));
if (intersected.length) this.selected = true;
});
this.scene.addEventListener('mouseup', e => {
this.selected = undefined;
});
}
});
</script>
<a-scene>
<a-entity camera look-controls></a-entity>
<a-sky src="https://raw.githubusercontent.com/aframevr/aframe/master/examples/boilerplate/panorama/puydesancy.jpg"></a-sky>
<a-box color="tomato" position="-3 0 -10" draggable></a-box>
<a-box draggable position="3 0 -5" draggable></a-box>
</a-scene>
如何预防? (比如只能拖前面的立方体?)
这是因为您放置控件的位置。您正在对一台相机进行多光线投射,而不是对多物体进行单光线投射。如果你有一个 raycaster 知道它相交的所有东西(它会 return 按距离排序的对象),那就更容易了。 http://threejs.org/docs/api/core/Raycaster.html
我的结构是:
- 使用内置的raycaster 组件。 master 分支上即将发布的0.3.0 有改进API。 https://aframe.io/docs/master/components/raycaster.html
- 有一个依赖于 raycaster 组件的拖动器组件。
- 让拖动器组件仅与具有
draggable
组件、draggable
class 或data-draggable
属性的对象相交。
<a-scene>
<a-camera>
<a-entity dragger></a-entity>
</a-camera>
<a-entity draggable></a-entity>
</a-scene>
AFRAME.registerComponent('dragger', {
init: function () {
// Configure raycaster.
this.el.setAttribute('raycaster', {
objects: '[draggable]',
// ...
});
},
tick: function () {
// Use this.el.components.raycaster.intersectedEls
}
});