javascript - Three.js raycaster no selecciona el objeto correcto
jquery raycasting (1)
Hola chicos, estoy tratando de seleccionar un objeto usando el raycaster y me gustaría que cambie el material del primer objeto que se selecciona. Todo va bien hasta que selecciono el objeto. Si selecciono el primer elemento, solo cambia un objeto.
Si repito la lista, la mayoría de las partes cambian, pero algunas veces una parte cambiará incluso cuando hago clic en una sección en blanco
Mi suposición es que es con la forma en que estoy cargando los modelos o que el lanzador de rayos está recibiendo la ubicación incorrecta del punto
He publicado el código a continuación, ayudar a que se aprecie la ayuda.
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
});
}
}
Actualización Aunque gracias a Almaz Vildanov por el script eventControl que fue muy útil. Decidí echarle otro vistazo al código para identificar el problema.
El problema radica en el hecho de que el procesador está en un div anidado y el cálculo de la coordenada inicial del rayo se calcula incorrectamente. Para resolverlo, reemplace el mousevector con esto:
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() );
donde $ contenedor es el div anidado donde está el renderizador.
Intenta hacer a través de este ejemplo . Mira los mensajes en la consola.
<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 );
}