Skip to content Skip to sidebar Skip to footer

Three.js: How To Add An Object Perpendicular To A Face (normal)?

I'm trying to add a box (called 'marker') perpendicular to the face I'm clicking on. To do this, on click, I cast a ray, if it hits something, I get the normal's intersecting point

Solution 1:

You are adding cube and plane. And giving them position and rotation. But for intersecting normals of them correctly, you should apply matrix.

var container, stats;
    var camera, scene, renderer;
    varobjects= [];
    raycaster = newTHREE.Raycaster();
    mouse = newTHREE.Vector2();

    init();
    animate();

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

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

        scene.add ( newTHREE.AmbientLight( 0xffffff ) );

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

        varmaterial=newTHREE.MeshLambertMaterial( { color: 0x4fc2c9 } );
        varcube=newTHREE.Mesh( newTHREE.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 matrixvarfaceNormalsHelper=newTHREE.FaceNormalsHelper( cube, 1 );
        cube.add( faceNormalsHelper );

        varvertexNormalsHelper=newTHREE.VertexNormalsHelper( cube, 1 );
        cube.add( vertexNormalsHelper );

        varplaneGeo=newTHREE.PlaneGeometry( 60, 20, 1, 1 );
        varplaneMat=newTHREE.MeshLambertMaterial({ color: 0xffffff });
        varplane=newTHREE.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 );

        varaxes=newTHREE.AxisHelper( 20 );
        scene.add( axes );

        renderer = newTHREE.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 );

        varintersects= raycaster.intersectObjects( scene.children );

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

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

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

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

            varmarkerGeo=newTHREE.BoxGeometry( 1, 1, 6, 1, 1, 1 ); // I changed BoxGeometryvarmarkerMat=newTHREE.MeshLambertMaterial( { color: 0xff0000 } );
            varmarker=newTHREE.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 );
    }

There is a function named 'applyMatrixOfMesh' in code. You need use it for every 'THREE.Mesh' will you use for intersection.

Post a Comment for "Three.js: How To Add An Object Perpendicular To A Face (normal)?"