javascript - Three.js - 使用投影仪和射线选择顶点

标签 javascript three.js

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

我尝试了多种方法,但没有运气,通常是选择两个顶点。我当前的方法使用了 obj 加载器,它工作得很好,但是我无法找到使用投影仪和射线单击的顶点。它总是返回一个空数组。

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

<!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 );
            } );

然后,当执行 intersectObject 时,我是在模型而不是场景上进行的

var intersects = ray.intersectObject(model);

关于javascript - Three.js - 使用投影仪和射线选择顶点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11205784/

相关文章:

javascript - Visual Studio 使用明确类型化的 Typescript 编译问题

javascript - Office.js 在搜索中转义特殊字符

javascript - 基于距离的点添加到顶点(网格几何)

javascript - Three.js 顶点位置未使用自定义着色器更新

javascript - 将OBJ文件加载到Three.js中的过程

javascript - 如何使用 js 或 jquery 在一个页面中使用多个 css 切换开关

javascript - jQuery输入文件点击方法和IE上拒绝访问

仅在 Firefox 中出现 Javascript 引用错误

javascript - three.js - 如何渲染带有 alpha channel 的线条?

javascript - ThreeJS 在异步加载后更新 FBX 对象的属性