안녕하세요. 저는 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입니다.
아마도 [이] (http://stackoverflow.com/questions/26250810/three-js-get-object-name-with-mouse-click/26311582#26311582) –
감사하기 Almaz 도움이 될 것 즉 보인다 당신의 도움에 감사드립니다. – Robrotheram
답변을 주시면 투표에 도움이됩니다. –