2014-09-04 3 views
0

그래서 Threejs에서 사용할 수있는 기본 객체에서 마우스 피킹을 사용하는 방법에 대한 자습서가 많이 있지만, .obj 파일과 같은 가져온 모델에서 마우스 피킹을 사용하고 구를 표시하는 것이 가능합니다. 사용자가 모델을 클릭하는 정확한 위치에? 그렇다면 누군가 내가 튜토리얼이나 최소한 소스 코드 예제를 제공하여 사용할 수 있습니다. 튜토리얼을 더 선호합니다. ;)Three.js 마우스 피킹 객체

편집 : 그래서 마우스 모델링 작업을 얻었습니다! 하지만 이제는 사용자가 모델을 클릭하는 위치에 약간의 점을 표시하려고합니다. 나는이 데모가 작동하는 방식으로 해 보았습니다 : http://mrdoob.github.io/three.js/examples/#canvas_interactive_cubes하지만 그 이유를 아는 사람은 제대로 작동하지 않습니다. 아래 코드를 참조하십시오.

// once everything is loaded, we run our Three.js stuff. 
var clock = new THREE.Clock(); 
var stats = initStats(); 
var particleMaterial; 

// create a scene, that will hold all our elements such as objects, cameras and lights. 
var PI2 = Math.PI * 2; 
particleMaterial = new THREE.SpriteCanvasMaterial({ 
    color: 0x000000, 
    program: function (context) { 
     context.beginPath(); 
     context.arc(0, 0, 0.5, 0, PI2, true); 
     context.fill(); 
    } 
}); 
var projector = new THREE.Projector(); 
var scene = new THREE.Scene(); 

// create a camera, which defines where we're looking at. 
var camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 0.1, 1000); 


// create a render and set the size 
var webGLRenderer = new THREE.WebGLRenderer(); 
webGLRenderer.setClearColor(new THREE.Color(0xEFEFEF, 1.0)); 
webGLRenderer.setSize(window.innerWidth, window.innerHeight); 
webGLRenderer.shadowMapEnabled = true; 

// position and point the camera to the center of the scene 
camera.position.x = 0; 
camera.position.y = 0; 
camera.position.z = 40; 
camera.lookAt(new THREE.Vector3(0, 0, 0)); 


var trackballControls = new THREE.TrackballControls(camera); 

trackballControls.rotateSpeed = 3.0; 
trackballControls.zoomSpeed = 3.0; 
trackballControls.panSpeed = 0.4; 
trackballControls.staticMoving = false; 

var ambientLight = new THREE.AmbientLight(0xffffff); 
scene.add(ambientLight); 
hemiLight = new THREE.HemisphereLight(0xFFFFFF, 0xFFFFFF, 0.9); 
scene.add(hemiLight); 
// add spotlight for the shadows 
var spotLight = new THREE.SpotLight(0xffffff); 
spotLight.position.set(300, 300, 300); 
spotLight.intensity = 1; 
scene.add(spotLight); 

// add the output of the renderer to the html element 
$("#WebGL-output").append(webGLRenderer.domElement); 

// call the render function 
var step = 0; 


// setup the control gui 
//var controls = new function() { 
    // we need the first child, since it's a multimaterial 


//} 

//var gui = new dat.GUI(); 
var mesh; 
var objects = []; 

var loader = new THREE.OBJMTLLoader(); 
loader.addEventListener('load', function (event) { 
    var object = event.content; 
    object.traverse(function (child) { 
     if (child instanceof THREE.Mesh) { 
      //The child is the bit needed for the raycaster.intersectObject() method 
     } 
    }); 
    object.scale.set(4, 4, 4); 
    object.position.set(0, -10, 0); 
    object.name = "test"; 
    scene.add(object); 
    objects.push(object); 
}); 

loader.load('models/dancer07.obj', 'models/dancer07.mtl', {side: THREE.DoubleSide}); 

var plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 400, 50, 50), new THREE.MeshBasicMaterial({ color: 0x808080, wireframe: true })); 
plane.rotation.x = -Math.PI/2; 
plane.name = 'Ground'; 
plane.position.set(0, -10, 0); 
scene.add(plane); 
objects.push(plane); 

render(); 

function render() { 
    stats.update(); 
    var delta = clock.getDelta(); 

    if (mesh) { 
     // mesh.rotation.y+=0.006; 
    } 


    trackballControls.update(delta); 

    //webGLRenderer.clear(); 
    // render using requestAnimationFrame 
    requestAnimationFrame(render); 
    webGLRenderer.render(scene, camera) 
} 

function initStats() { 

    var stats = new Stats(); 
    stats.setMode(0); // 0: fps, 1: ms 

    // Align top-left 
    stats.domElement.style.position = 'absolute'; 
    stats.domElement.style.left = '0px'; 
    stats.domElement.style.top = '0px'; 

    $("#Stats-output").append(stats.domElement); 

    return stats; 
} 
document.addEventListener('mousedown', onDocumentMouseDown, false); 
window.addEventListener('resize', onWindowResize, false); 

function onWindowResize() { 

     camera.aspect = window.innerWidth/window.innerHeight; 
     camera.updateProjectionMatrix(); 

     renderer.setSize(window.innerWidth, window.innerHeight); 

    } 

function onDocumentMouseDown(event){ 
    event.preventDefault(); 
    var mouseX = (event.clientX/window.innerWidth)*2-1; 
    var mouseY = -(event.clientY /window.innerHeight)*2+1; 
    var vector = new THREE.Vector3(mouseX, mouseY, 0.5); 
    projector.unprojectVector(vector, camera); 
    var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize()); 
    var intersects = raycaster.intersectObjects(objects, true); 
    if (intersects.length > 0) { 
     alert("intersect!"); 
     var particle = new THREE.Sprite(particleMaterial); 
     particle.position.copy(intersects[0].point); 
     particle.scale.x = particle.scale.y = 300; 
     scene.add(particle);  
    } 

} 

$('#reset').click(function() { 
    trackballControls.reset(); 
}); 

$('#female').click(function() { 
    scene.remove(scene.getObjectByName("test")); 
    loader.load('models/dancer07.obj', 'models/dancer07.mtl', {side: THREE.DoubleSide}); 
}); 

$('#male').click(function() { 
    scene.remove(scene.getObjectByName("test")); 
    loader.load('models/doorman.obj', 'models/doorman.mtl', {side: THREE.DoubleSide}); 
}); 
+0

그래, 대답은 100 % 완료되지 않았는데, 왜냐하면 누군가 구형을 표시하는 방법과 방법을 알고 있는지 물어 봤기 때문이다. 그리고 그것이 작동하지 않았기 때문에 나는 코드와 솔루션을 추가하여 내 질문을 업데이트하기로 결정했다. –

답변

1

가져온 모델이나 기본 개체는 중요하지 않습니다. Three.JS 예제의 마우스 피킹 코드는 모든 종류의 메쉬에서 작동합니다.

http://threejs.org/examples/#webgl_interactive_buffergeometry

var vector = new THREE.Vector3(mouse.x, mouse.y, 1); 
projector.unprojectVector(vector, camera); 

raycaster.set(camera.position, vector.sub(camera.position).normalize()); 

var intersects = raycaster.intersectObject(mesh); 

raycaster.intersectObject 기능에 로더에 의해 생성 된 메쉬를 사용합니다. 귀하의 경우에는 아래의 코드로 객체를 구성하는 모든 메쉬를 얻을 수 있습니다.

var loader = new THREE.OBJLoader(manager); 
loader.load('example.obj', function (object) { 
    object.traverse(function (child) { 
     if (child instanceof THREE.Mesh) { 
      //The child is the bit needed for the raycaster.intersectObject() method 
     } 
    }); 
    object.position.y = - 80; 
    scene.add(object); 
}); 
+0

그래, 정말 고마워! 나는 그것에 도착하자마자 노력할 것이다. –

+0

고마워요! 나는 구형/점을 표시하기가 쉽다고 생각했기 때문에 나의 질문을 업데이트했다. 하지만 그렇지 않았습니다. 도와주세요. –