使用投影仪和光线选择顶点

Using Projector and Ray to selected a vertex

本文关键字:选择 顶点 投影仪      更新时间:2023-09-26

我的总体目标是能够加载一个人体.obj文件。允许用户选择两个折点并使用标志突出显示它们。然后从原始 .obj 文件中查找两个顶点的索引,并运行 php 脚本来测量两个顶点之间的距离。

我已经尝试了许多方法,但没有运气,通常是选择两个顶点。我目前的方法使用了 obj 加载器,它工作正常,但我无法使用投影仪和 Ray 找到我正在单击的顶点。它始终返回一个空数组。

这是我到目前为止的代码,一旦相交数组不为空,我就会尝试从文件中找到最近的顶点,更改对象的颜色并更改单击的面。

<!doctype html>
<html lang="en">
    <head>
        <title>three.js webgl - loaders - OBJ loader</title>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
        <style>
            body {
                font-family: Monospace;
                background-color: white;
                color: #fff;
                margin: 0px;
                overflow: hidden;
            }
            #info {
                color: #fff;
                position: absolute;
                top: 10px;
                width: 100%;
                text-align: center;
                z-index: 100;
                display:block;
            }
            #info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
        </style>
    </head>
<body>
    <script src="javascripts/Three.js"></script>
    <script src="javascripts/OBJLoader.js"></script>
    <script>
        var container, stats;
        var camera, scene, renderer, model;
        var mouseX = 0, mouseY = 0;
        var windowHalfX = window.innerWidth / 2;
        var windowHalfY = window.innerHeight / 2;

        init();
        animate();

        function init() {
            container = document.createElement( 'div' );
            document.body.appendChild( container );
            scene = new THREE.Scene();
            camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 2000 );
            camera.position.z = 1;
            scene.add( camera );
            camera.position.y = -4;
            var ambient = new THREE.AmbientLight( 0x101030 );
            scene.add( ambient );
            var directionalLight = new THREE.DirectionalLight( 0xffeedd );
            directionalLight.position.set( 0, 0, 1 ).normalize();
            scene.add( directionalLight );
            var loader = new THREE.OBJLoader();
            loader.load( "img/originalMeanModel.obj", function ( object ) {
                model = object;
                scene.add( model );
            } );
            // RENDERER
            renderer = new THREE.WebGLRenderer();
            renderer.setSize( window.innerWidth, window.innerHeight );
            container.appendChild( renderer.domElement );
            document.addEventListener( 'mousemove', onDocumentMouseMove, false );
            document.addEventListener( 'mousedown', onDocumentMouseDown, false );
        }
        function onDocumentMouseDown( event ){
            console.log('Morphable-body-obj: Width '+ window.innerWidth ) ;
            console.log('Morphable-body-obj: Height '+ window.innerHeight) ;
            var vector = new THREE.Vector3 ((event.clientX / window.innerWidth) * 2 - 1, -(event.clientY / window.innerHeight)*2+1, 0.5);
            var projector = new THREE.Projector();
            projector.unprojectVector(vector, camera);
            var ray = new THREE.Ray(camera.position, vector.subSelf(camera.position).normalize());
            var intersects = ray.intersectObject(scene);
            console.log(intersects);
            if (intersects.length > 0)
              {
                var xhr = new XMLHttpRequest();
                xhr.open('GET', '/img/originalMeanModel.obj', false);
                xhr.send(null);
                var text = xhr.responseText;
                var origText = text; 
                var lines = text.split("'n");
                for (i=0; i<6449; i++){
                  lines[i] = lines[i].split(" ");
                }
                var low = Math.sqrt(
                      (Math.pow((intersects[0].point.x - parseFloat(lines[0][1])), 2))+
                      (Math.pow((intersects[0].point.y - parseFloat(lines[0][2])), 2))+
                      (Math.pow((intersects[0].point.z - parseFloat(lines[0][3])), 2))
                    );
                var c = 0;
                for(i=1; i<6449; i++){
                  var temp = Math.sqrt(
                      (Math.pow((intersects[0].point.x - parseFloat(lines[i][1])), 2))+
                      (Math.pow((intersects[0].point.y - parseFloat(lines[i][2])), 2))+
                      (Math.pow((intersects[0].point.z - parseFloat(lines[i][3])), 2))
                  );
                  if(temp < low){
                    low = temp;
                    c=i;
                  }
                }
                console.log(
                  'Mouse coordinates:' + ''nx = ' + intersects[0].point.x + ''ny = ' + intersects[0].point.y + ''nz = ' + intersects[0].point.z +''n'+
                  'Nearest Vertex' + ''nx= ' + lines[c][1] + ''ny= ' + lines[c][2] + ''nz =' + lines[c][3] + "'n" +
                  'Difference' + ''nx= ' + (intersects[0].point.x - lines[c][1]) + ''ny= ' + (intersects[0].point.y - lines[c][2]) + ''nz= ' + (intersects[0].point.z - lines[c][3]) 
                );
                intersects[0].object.materials[0].color = new THREE.Color( Math.random() * 0xffffff );
                intersects[0].face.color = new THREE.Color(0xffffff);
                intersects[0].object.geometry.colorsNeedUpdate = true;
                intersects[0].object.geometry.dynamic = true;
               }
            else{
                alert('error');
            }
        }
        function onDocumentMouseMove( event ) {
            mouseX = ( event.clientX - windowHalfX ) / 2;
            mouseY = ( event.clientY - windowHalfY ) / 2;
        }
        function animate() {
            requestAnimationFrame( animate );
            render();
        }
        function render() {
            camera.lookAt( scene.position );
            renderer.render( scene, camera );
        }
    </script>
</body>

有问题的.obj文件可以在这里找到 https://dl.dropbox.com/u/23384412/originalMeanModel.obj

如果有人能指出我正确的方向,将不胜感激。

提前感谢! :)

为了解决这个问题,我使用此代码从 obj 加载器返回的对象创建了一个网格

            var loader = new THREE.OBJLoader();
            loader.load( "img/originalMeanModel.obj", function ( object ) {
              object.children[0].geometry.computeFaceNormals();
              var  geometry = object.children[0].geometry;
                      console.log(geometry);
              THREE.GeometryUtils.center(geometry);
              var material = new THREE.MeshLambertMaterial({color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors });
              mesh = new THREE.Mesh(geometry, material);
              model = mesh;
              // model = object;
               scene.add( model );
            } );

然后在执行相交对象时,我在模型而不是场景上做了

var intersects = ray.intersectObject(model);