2014-12-23 3 views
0

안녕하세요. 저는 raycaster를 사용하여 오브젝트를 선택하려고하는데, 선택한 첫 번째 오브젝트의 재질을 변경하고 싶습니다. 객체를 선택할 때까지 모든 것이 잘됩니다. 첫 번째 요소를 선택하면 하나의 개체 만 변경됩니다. 나는 목록 대부분의 변경하지만Three.js raycaster가 올바른 오브젝트를 선택하지 않았습니다.

내 가정은 내가 모델 또는 레이 캐스터를로드하고 방법과 점이다 빈 부분에 클릭하고 때 일부도 변경됩니다 몇 번을 반복하면

잘못된 포인트 위치를 얻고 있습니다

나는 아래의 코드를 도움을 주시면 감사하겠습니다.

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 
     }); 
    } 
} 

업데이트 비록 매우 유용했다 eventControl 스크립트하기 Almaz Vildanov에 감사합니다. 문제를 확인하기 위해 코드를 다시 살펴 보기로했습니다.

렌더러가 중첩 된 div에 있고 광선의 초기 좌표에 대한 계산이 잘못 계산된다는 점이 문제입니다. 이 문제를 해결하려면 mousevector를 다음으로 대체하십시오.

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입니다.

+0

아마도 [이] (http://stackoverflow.com/questions/26250810/three-js-get-object-name-with-mouse-click/26311582#26311582) –

+0

감사하기 Almaz 도움이 될 것 즉 보인다 당신의 도움에 감사드립니다. – Robrotheram

+0

답변을 주시면 투표에 도움이됩니다. –

답변

0

example을 통해 확인해보십시오. 콘솔의 메시지를보십시오.

<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); 

} 
관련 문제