我是three.js的新手,并且在同一窗口中有2个场景。似乎光线投射器没有找到相交(仅在第一个场景而不在第二个场景)。我做错了什么?
我在每个场景中创建了一个新的心形。在每个场景中我都有一个射线发生器。我创建了一个新的JavaScript对象cvRenderer,它正在创建场景,并且还具有mousedown事件,该事件将触发raycaster正常工作。第一个场景一切正常,但光线投射器未在第二个场景中找到相交。
var cvRenderer = function () {
this.scene = null,
this.camera = null,
this.renderer = null,
this.controls = null,
this.clock = null,
this.stats = null,
this.raycaster = null,
this.INTERSECTED = null,
this.mouse = null,
this.init = function (container, width, height) {
this.raycaster = new THREE.Raycaster();
this.mouse = new THREE.Vector2();
// create main scene
this.scene = new THREE.Scene();
this.scene.background = new THREE.Color(0xf0f0f0);
var SCREEN_WIDTH = width,
SCREEN_HEIGHT = height;
// prepare camera
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 1, FAR = 5000;
this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, ASPECT, NEAR, FAR);
this.scene.add(this.camera);
// this.camera.position.set(0, 100, 300);
this.camera.position.set(0, 100, 1000);
this.camera.lookAt(new THREE.Vector3(0, 0, 0));
// prepare renderer
this.renderer = new THREE.WebGLRenderer({ antialias: true });
this.renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
this.renderer.shadowMapEnabled = true;
this.renderer.shadowMapSoft = true;
// prepare container
container.appendChild(this.renderer.domElement);
// events
container.addEventListener('mousedown', (event) => {
event.preventDefault();
this.setMouse(event.clientX, event.clientY );
this.findIntersects(event.clientX, event.clientY);
}, false);
// prepare controls (OrbitControls)
this.controls = new THREE.OrbitControls(this.camera, this.renderer.domElement);
this.controls.target = new THREE.Vector3(0, 0, 0);
this.controls.maxDistance = 5000;
this.controls.enableRotate = false;
// prepare clock
this.clock = new THREE.Clock();
var light = new THREE.PointLight(0xffffff, 0.8);
this.scene.add(light);
// load a model
this.loadModel();
},
this.findIntersects = function (clientX, clientY) {
this.setMouse(clientX, clientY);
this.raycaster.setFromCamera(this.mouse, this.camera);
var intersects = this.raycaster.intersectObjects(this.scene.children, true);
if (intersects.length > 0) {
intersects[0].object.callback();
}
},
this.setMouse = function (clientX, clientY) {
this.mouse.x = (clientX / this.renderer.domElement.clientWidth) * 2 - 1;
this.mouse.y = - (clientY / this.renderer.domElement.clientHeight) * 2 + 1;
},
this.loadModel = function () {
var extrudeSettings = { depth: 8, bevelEnabled: true, bevelSegments: 2, steps: 2, bevelSize: 1, bevelThickness: 1 };
var heartShape = new THREE.Shape();
var x = 0, y = 0;
heartShape.moveTo(x + 25, y + 25);
heartShape.bezierCurveTo(x + 25, y + 25, x + 20, y, x, y);
heartShape.bezierCurveTo(x - 30, y, x - 30, y + 35, x - 30, y + 35);
heartShape.bezierCurveTo(x - 30, y + 55, x - 10, y + 77, x + 25, y + 95);
heartShape.bezierCurveTo(x + 60, y + 77, x + 80, y + 55, x + 80, y + 35);
heartShape.bezierCurveTo(x + 80, y + 35, x + 80, y, x + 50, y);
heartShape.bezierCurveTo(x + 35, y, x + 25, y + 25, x + 25, y + 25);
var heartgeometry = new THREE.ExtrudeBufferGeometry(heartShape, extrudeSettings);
var heartmesh = new THREE.Mesh(heartgeometry, new THREE.MeshPhongMaterial({ color: 0xff80f0 }));
heartmesh.position.set(0, 100, -75);
heartmesh.rotation.set(0, 0, Math.PI);
heartmesh.scale.set(1, 1, 1);
heartmesh.callback = function () {
console.log("heart was clicked");
}
this.scene.add(heartmesh);
}
};
var rs = null;
function animate() {
requestAnimationFrame(animate);
render(rs[0]);
update(rs[0]);
render(rs[1]);
update(rs[1]);
}
// Update controls and stats
function update(canvasRenderer) {
canvasRenderer.controls.update(canvasRenderer.clock.getDelta());
}
// Render the scene
function render(canvasRenderer) {
if (canvasRenderer.renderer) {
canvasRenderer.raycaster.setFromCamera(canvasRenderer.mouse, canvasRenderer.camera);
var intersects = canvasRenderer.raycaster.intersectObjects(canvasRenderer.scene.children, true);
if (intersects.length > 0) {
if (canvasRenderer.INTERSECTED != intersects[0].object) {
if (canvasRenderer.INTERSECTED) canvasRenderer.INTERSECTED.material.emissive.setHex(canvasRenderer.INTERSECTED.currentHex);
canvasRenderer.INTERSECTED = intersects[0].object;
canvasRenderer.INTERSECTED.currentHex = canvasRenderer.INTERSECTED.material.emissive.getHex();
canvasRenderer.INTERSECTED.material.emissive.setHex(0xfff000);
}
} else {
if (canvasRenderer.INTERSECTED) canvasRenderer.INTERSECTED.material.emissive.setHex(canvasRenderer.INTERSECTED.currentHex);
canvasRenderer.INTERSECTED = null;
}
canvasRenderer.renderer.render(canvasRenderer.scene, canvasRenderer.camera);
}
}
function initializeCanvas() {
this.container = document.createElement('div');
document.body.appendChild(this.container);
var canvasRenderer1 = new cvRenderer();
canvasRenderer1.init(container, 600, 400, false);
this.container2 = document.createElement('div');
document.body.appendChild(this.container2);
var canvasRenderer2 = new cvRenderer();
canvasRenderer2.init(container2, 600, 400, false);
rs = [canvasRenderer1, canvasRenderer2]
animate();
}