2017-09-21 7 views
0

J'essaie d'ajouter une boîte (appelée "marqueur") perpendiculaire au visage sur lequel je clique. Pour ce faire, en cliquant, je lance un rayon, s'il touche quelque chose, j'obtiens les valeurs du point d'intersection du normal et les transfère au "marqueur" comme valeurs de rotation. Avant de poser cette question, j'ai lu cette réponse (How do I make an object perpendicular to a face with Three.js?) mais je n'ai pas pu la faire fonctionner ...Three.js: Comment ajouter un objet perpendiculaire à un visage (normal)?

Pour l'instant, il ajoute le marqueur là où il le faut, mais avec une orientation légèrement fausse attendez-vous sur le dessus du cube.

Wrong orientation on cube and uncontroled Y rotation

Je ne comprends pas deux choses: 1. pourquoi il y a une différence entre la direction et intersecte [0] .face.normal du faceNormalsHelper. 2. Comment la rotation Y est-elle contrôlée?

Quelle est mon erreur? Pour vous aider à me aider, j'ai fait un violon (https://jsfiddle.net/jpyncf62/1/) et voici le code que je utilise pour le faire:

function clickDown(e) { 
    e.preventDefault(); 

    raycaster.setFromCamera(mouse, camera); 
    var intersects = raycaster.intersectObjects(objects); 

    if (intersects.length > 0) { 
     var intersect = intersects[0]; 
     console.log(intersects[0]); 
     console.log(console.log(intersects[0].object.name)); 

     var markerGeo = new THREE.BoxGeometry(1, 6, 1, 1, 1, 1); 
     var markerMat = new THREE.MeshLambertMaterial({ color: 0xff0000 }); 
     var marker = new THREE.Mesh(markerGeo, markerMat); 
     marker.name = "marker"; 
     marker.position.copy(intersect.point); 

     marker.lookAt(intersect.face.normal); 

     scene.add(marker); 
    } 
} 

Merci pour l'aide!

Répondre

0

Vous ajoutez un cube et un plan. Et en leur donnant la position et la rotation. Mais pour en croiser correctement les normales, vous devez appliquer la matrice.

var container, stats; 
    var camera, scene, renderer; 
    var objects = []; 
    raycaster = new THREE.Raycaster(); 
    mouse = new THREE.Vector2(); 

    init(); 
    animate(); 

    function init() { 
     container = document.getElementById("webgl-output") 
     scene = new THREE.Scene(); 

     camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 1000); 
     camera.position.set(20, 50,50); 
     camera.lookAt(scene.position); 

     scene.add (new THREE.AmbientLight(0xffffff)); 

     light = new THREE.DirectionalLight(0xffffff); 
     light.position.set(0, 1, 0); 
     scene.add(light); 

     var material = new THREE.MeshLambertMaterial({ color: 0x4fc2c9 }); 
     var cube = new THREE.Mesh(new THREE.BoxGeometry(10, 10, 10, 1, 1, 1), material); 
     cube.name = "I'm a cube"; 
     objects.push(cube); 
     scene.add(cube); 


     cube.position.set(0, 5, 0); 
     cube.rotation.set(0, 0, Math.PI/4); 

     applyMatrixOfMesh(cube); // Apply matrix of cube 

     // Add helpers after applied matrix 
     var faceNormalsHelper = new THREE.FaceNormalsHelper(cube, 1); 
     cube.add(faceNormalsHelper); 

     var vertexNormalsHelper = new THREE.VertexNormalsHelper(cube, 1); 
     cube.add(vertexNormalsHelper); 

     var planeGeo = new THREE.PlaneGeometry(60, 20, 1, 1); 
     var planeMat = new THREE.MeshLambertMaterial({ color: 0xffffff }); 
     var plane = new THREE.Mesh(planeGeo, planeMat); 
     plane.position.set(0, 0, 0); 
     plane.rotation.x = -0.5 * Math.PI; 
     plane.name = "plane01"; 

     applyMatrixOfMesh(plane); // Apply matrix of plane 

        scene.add(plane); 
     objects.push(plane); 

     var axes = new THREE.AxisHelper(20); 
     scene.add(axes); 

     renderer = new THREE.WebGLRenderer({ antialias: true }); 
     renderer.setPixelRatio(window.devicePixelRatio); 
     renderer.setClearColor(0xeeeeee); 
     renderer.setSize(window.innerWidth, window.innerHeight); 
     container.appendChild(renderer.domElement); 

     document.addEventListener('mousemove', mouseMoving, false); 
     document.addEventListener('mousedown', clickDown, false); 
    } 

    function mouseMoving(e) { 
     mouse.x = (e.clientX/window.innerWidth) * 2 - 1; 
     mouse.y = - (e.clientY/window.innerHeight) * 2 + 1;    
     raycaster.setFromCamera(mouse, camera); 

     var intersects = raycaster.intersectObjects(scene.children); 

     for (var i = 0; i < intersects.length; i++) { 
      var posY = intersects[ 0 ].point.y.toFixed(2); 
     } 
    } 

    function clickDown(e) { 
     e.preventDefault(); 

     raycaster.setFromCamera(mouse, camera); 
     var intersects = raycaster.intersectObjects(objects);    

     if(intersects.length > 0) { 
      var intersect = intersects[ 0 ]; 
      console.log(intersects[ 0 ]); 
      console.log(console.log(intersects[ 0 ].face.normal)); 

      var markerGeo = new THREE.BoxGeometry(1, 1, 6, 1, 1, 1); // I changed BoxGeometry 
      var markerMat = new THREE.MeshLambertMaterial({ color: 0xff0000 }); 
      var marker = new THREE.Mesh(markerGeo, markerMat); 
      marker.name = "marker"; 



      marker.lookAt(intersect.face.normal); // First look At to normal 
      marker.position.copy(intersect.point) // After give position to marker 

      scene.add(marker); 
     } 
    } 

    function applyMatrixOfMesh(mesh) { // You should apply Matrix of cube and plane 
     mesh.updateMatrix(); 
     mesh.geometry.applyMatrix(mesh.matrix); 

     mesh.position.set(0, 0, 0); 
     mesh.rotation.set(0, 0, 0); 
     mesh.updateMatrix(); 
    } 


    function animate() { 
     requestAnimationFrame(animate); 
     render(); 
    } 

    function render() {   
     renderer.render(scene, camera); 
    } 

Il existe une fonction nommée 'applyMatrixOfMesh' dans le code. Vous devez l'utiliser pour chaque "TROIS.Mesh" que vous utiliserez pour l'intersection.

+0

Merci beaucoup! Je cherche à résoudre ce problème pendant des jours. J'ai essayé d'utiliser le "applyMatrix" mais évident pas correctement. – Student