Three.js raycaster没有选择正确的对象 [英] Three.js raycaster not selecting right object
问题描述
Hello Guys我正在尝试使用raycaster选择一个对象,我希望它能够更改所选第一个对象的材质。在我选择对象之前,一切顺利。如果我选择第一个元素,则只有一个对象发生变化。
Hello Guys I am trying to select an object using the raycaster and I would like it to change the material of the first object that is selected. Every thing goes well until I select the object. If I pick the first element only one object changes.
如果我遍历列表,大部分内容会发生变化,但有时候即使我点击一个空白,部分也会发生变化部分
If I iterate through the list most part changes but some times a part will change even when I am clicking in a blank section
我的假设是,我是如何加载模型或光线施法者得到错误的点位置
My assumption is that it is with how I am loading the models or the ray caster is getting the wrong point location
我已经发布了以下代码,帮助我们不胜感激。
I have posted the code below help help be appreciated.
var camera, scene, renderer, loader, controls, play;
var jetEngine = [];
var x = 0;
var texture = THREE.ImageUtils.loadTexture('images/metal2.jpg');
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(10, 10);
var play = false;
var container;
var $container;
var _this;
function Jet($con) {
$container = $con;
_this = this;
width = $con.width();
height = $con.height();
renderer = new THREE.WebGLRenderer({alpha: true});
renderer.setClearColor(0xffffff, 1);
renderer.setSize(width, height);
$container.append(renderer.domElement);
raycaster = new THREE.Raycaster();
camera = new THREE.PerspectiveCamera(60, width / height, 1, 2000);
camera.position.z = 200;
camera.position.y = 0;
camera.position.x = 30;
controls = new THREE.TrackballControls(camera,renderer.domElement );
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1.2;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
controls.keys = [65, 83, 68];
scene = new THREE.Scene();
loader = new THREE.JSONLoader();
loader.load("jetengine/fan.json", _this.addmodel);
loader.load("jetengine/shaft.json", _this.addmodel);
loader.load("jetengine/nose.json", _this.addmodel);
loader.load("jetengine/compressor.json", _this.addmodel);
loader.load("jetengine/compressor2.json", _this.addmodel);
loader.load("jetengine/combustion.json", _this.addmodel);
var directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(0, 1, 0);
scene.add(directionalLight);
var light = new THREE.AmbientLight(0x404040); // soft white light
scene.add(light);
window.addEventListener('resize', _this.onWindowResize, false);
window.addEventListener( 'click', _this.onMouseMove, false );
_this.animate();
}
Jet.prototype.changeColor = function () {
for (i = 0; i < jetEngine.length; i++) {
jetEngine[i].material = new THREE.MeshPhongMaterial({
// light
map: texture,
// dark
shininess: 50
});
}
};
Jet.prototype.playPause = function (btn) {
play = !play;
if(play){$(playbtn).html('Puase');}else{$(playbtn).html('Play');}
};
Jet.prototype.reset = function () {
play = false;
for (i = 0; i < jetEngine.length; i++) {
jetEngine[i].material = new THREE.MeshNormalMaterial()
}
camera.position.z = 200;
camera.position.y = 0;
camera.position.x = 30;
camera.lookAt(new THREE.Vector3(0,0,0));
};
Jet.prototype.addmodel = function (geometry, materials) {
var obj = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial());
obj.scale.set(15, 15, 15);
jetEngine[x] = obj;
scene.add(jetEngine[x]);
x++;
};
Jet.prototype.onWindowResize = function () {
width = container.width();
height = container.height();
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
controls.handleResize();
};
Jet.prototype.animate = function () {
if (play) {
if (jetEngine[0] != null) {
try{
jetEngine[0].rotateZ(1);
jetEngine[1].rotateZ(1);
jetEngine[2].rotateZ(10);
jetEngine[3].rotateZ(0);
jetEngine[4].rotateZ(1);
jetEngine[5].rotateZ(30);
}catch (err){
}
}
}
requestAnimationFrame(_this.animate);
renderer.render(scene, camera);
controls.update();
};
Jet.prototype.onMouseMove = function( e ) {
var isHovered = $container.is(":hover");
console.log(isHovered);
if (isHovered) {
mouseVector = new THREE.Vector3();
mouseVector.x = 2 * (e.clientX / width ) - 1;
mouseVector.y = 1 - 2 * ( e.clientY / height );
var vector = mouseVector.clone().unproject(camera);
var direction = new THREE.Vector3(0, 0, -1).transformDirection(camera.matrixWorld);
raycaster.set(vector, direction);
var intersects = raycaster.intersectObjects(jetEngine);
var intersection = intersects[0];
obj = intersection.object;
obj.material = new THREE.MeshPhongMaterial({
// light
map: texture,
// dark
shininess: 50
});
}
}
更新
虽然感谢Almaz Vildanov提供的eventControl脚本非常有用。我决定再看一下代码来确定问题。
Update Although thanks to Almaz Vildanov for the eventControl script which was very useful. I decided to have another look through the code to identify the problem.
问题在于渲染器位于嵌套div中,并且错误地计算了射线的初始坐标。要解决这个问题,请用以下方法替换mousevector:
The problem lies in the fact that the renderer is in a nested div and the calculation for the initial co-ordinate of the ray is calculated incorrectly. To solve it replace the mousevector with this:
var mouse = { x: 0, y: 0 };
mouse.x = ((event.clientX - $container.offset().left) /$container.width() ) * 2 - 1;
mouse.y = -(((event.clientY - $container.offset().top) / $container.innerHeight() ) * 2 - 1);
console.log('x: ' + mouse.x+ '| y:'+ mouse.y);
vector.set( mouse.x, mouse.y, 0.5 );
vector.unproject( camera );
raycaster.set( camera.position, vector.sub( camera.position ).normalize() );
其中$ container是渲染器所在的嵌套div。
where $container is the nested div where the renderer is.
推荐答案
尝试通过此示例。查看控制台中的消息。
Try to make through this example. Look at messages in the console.
<script src="js/controls/EventsControls.js"></script>
EventsControls = new EventsControls( camera, renderer.domElement );
EventsControls.draggable = false;
EventsControls.onclick = function() {
console.log( this.focused.name );
}
var jsonLoader = new THREE.JSONLoader();
jsonLoader.load( "models/Tux.js", addModelToScene );
function addModelToScene( geometry, materials ) {
var material = new THREE.MeshFaceMaterial( materials );
model = new THREE.Mesh( geometry, material );
model.scale.set( 10, 10, 10 ); model.name = 'Tux';
model.rotation.x = -Math.PI/2;
model.position.set( 175, 45, 125 );
scene.add( model );
EventsControls.attach( model );
}
这篇关于Three.js raycaster没有选择正确的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!