我有一个Three.js程序,每当我将指针放在一个立方体上时,它就会给我它的位置。这很好(这就是我需要的),但是当我将指针放在线上时,我的程序停止了。谁能告诉我为什么以及如何解决这个问题?无论我的指针在哪里,我都需要我的程序继续运行。
当我将指针放在白线上时,我得到以下错误:
未捕获的TypeError:无法读取未定义的属性'getHex'。
代码:
var container, stats;
var scene, camera, renderer, raycaster;
var cube;
var clock = new THREE.Clock();
var mouse = new THREE.Vector2(), INTERSECTED;
var radius = 100, theta = 0;
var composer;
initScene();
//Let's add a cube
var geometry = new THREE.BoxGeometry( 20, 20, 20 );
cube = new THREE.Mesh(geometry, new THREE.MeshLambertMaterial({
color : Math.random() * 0xffffff
}));
cube.position.set(0,20,50)
scene.add( cube );
//Let's add another cube
var geometry2 = new THREE.BoxGeometry( 20, 20, 20 );
var cube2 = new THREE.Mesh(geometry2, new THREE.MeshLambertMaterial({
color : Math.random() * 0xffffff
}));
cube2.position.set(200,20,50)
scene.add( cube2 );
//Let's add a line
var material = new THREE.LineBasicMaterial({
color: 0xffffff
});
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3(0, 20, 50));
geometry.vertices.push(new THREE.Vector3(200, 20, 50));
var line = new THREE.Line(geometry, material);
scene.add(line);
animate();
function initScene() {
container = document.createElement('div');
document.body.appendChild(container);
var fov = 70;
var aspect = window.innerWidth / window.innerHeight;
var near = 1;
var far = 10000;
var zpos = 300;
// Initialize camera
GlobalCamera(fov, aspect, near, far, zpos);
scene = new THREE.Scene();
// Set camera controls
cameraControls2();
// renderer controls
rendererControls2();
}
function GlobalCamera(fov, aspect, near, far, zpos) {
camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = zpos;
}
function cameraControls2() {
controls = new THREE.FlyControls(camera);
controls.movementSpeed = 2500;
controls.domElement = container;
controls.rollSpeed = Math.PI / 6;
controls.autoForward = false;
controls.dragToLook = false
}
function rendererControls2() {
renderer = new THREE.WebGLRenderer({
antialias : true,
alpha : true
});
renderer.setClearColor(0xf0f0f0);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.sortObjects = false;
container.appendChild(renderer.domElement);
renderer.gammaInput = true;
renderer.gammaOutput = true;
}
function findIntersection() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED)
INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = intersects[0].object;
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
INTERSECTED.material.emissive.setHex(0xff0000);
console.log(INTERSECTED.position);
}
} else {
if (INTERSECTED)
INTERSECTED.material.emissive.setHex(INTERSECTED.currentHex);
INTERSECTED = null;
}
}
function onDocumentMouseMove(event) {
event.preventDefault();
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function preAnimate(){
raycaster = new THREE.Raycaster();
// events
document.addEventListener('mousemove', onDocumentMouseMove, false);
}
function animate() {
preAnimate();
requestAnimationFrame(animate);
render();
}
function render() {
var delta = clock.getDelta();
findIntersection();
controls.update(delta);
renderer.render(scene, camera);
}
答案 0 :(得分:1)
这是我与Three.js的第一次冒险,但我想我已经找到了你的问题。会发生什么是THREE.LineBasicMaterial没有像THREE.MeshLambertMaterial那样的自发属性。要在THREE.LineBasicMaterial对象上操作的属性是color属性。
这是一个有效的jsFiddle,我已经在emissive属性可用的地方添加了一些检查: https://jsfiddle.net/thedole/4wkFu/162/区别在于在findIntersection方法中添加了提到的检查:
function findIntersection() {
raycaster.setFromCamera(mouse, camera);
var intersects = raycaster.intersectObjects(scene.children),
material;
if (intersects.length > 0) {
if (INTERSECTED != intersects[0].object) {
if (INTERSECTED){
material = INTERSECTED.material;
if(material.emissive){
material.emissive.setHex(INTERSECTED.currentHex);
}
else{
material.color.setHex(INTERSECTED.currentHex);
}
}
INTERSECTED = intersects[0].object;
material = INTERSECTED.material;
if(material.emissive){
INTERSECTED.currentHex = INTERSECTED.material.emissive.getHex();
material.emissive.setHex(0xff0000);
}
else{
INTERSECTED.currentHex = material.color.getHex();
material.color.setHex(0xff0000);
}
console.log(INTERSECTED.position);
}
} else {
if (INTERSECTED){
material = INTERSECTED.material;
if(material.emissive){
material.emissive.setHex(INTERSECTED.currentHex);
}
else
{
material.color.setHex(INTERSECTED.currentHex);
}
}
INTERSECTED = null;
}
}