闰点的位置与三个JS场景不同步

时间:2015-01-07 05:20:58

标签: 3d three.js coordinates leap-motion

我一直在努力获得RiggedHand网格所呈现的位置,以便在THREEJS场景中准确地创建小球体。我试图在给定指尖的位置做这个。 X和Y似乎是正确的,但Z几乎总是关闭。更重要的是,越远离中心,歪斜甚至更明显(即X和Y也关闭)。

我能做的最好的事情就是使用以下代码找出'正确'的坐标:

var handMesh = hand.data('riggedHand.mesh'); 
//This is the best I've gotten so far with the position of the fingertip
var position = handMesh.fingers[1].tip.getWorldPosition();

不确定最好的方法是什么,但到目前为止我已经尝试了几种。转换hand.finger [x] .tipPosition,使用交互框并乘以windowsize来尝试获得准确的位置。我开始怀疑它是否与我在THREEJS中使用PerspectiveCamera并且我需要以某种方式补偿它(?)这一事实有更多关系 - 真的不确定哪种方式去做但希望有人可以指出我朝着正确的方向前进。

使用上述代码的完整示例代码片段如下:

    var renderer, scene, camera, riggedHandPlugin, fadingSpheres
    var sphereTTL = 7;

    function initScene() {
        camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 1000);
        camera.position.z = 200;
        scene = new THREE.Scene();
        scene.fog = new THREE.FogExp2(0xcccccc, 0.002);

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

        // renderer
        renderer = new THREE.WebGLRenderer({ antialias: false });

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

        container = document.getElementById('container');
        container.appendChild(renderer.domElement);

        fadingSpheres = [];
    }

    function render() {
        requestAnimationFrame(render);
        renderer.render(scene, camera);
        if (fadingSpheres) {
            fadingSpheres.forEach(removeDeadSpheres);
        }
    }

    function FadingSphere(position, size, meshColor) {
        //Draw the sphere at the position of the indexfinger tip position
        var geometry = new THREE.SphereGeometry(3, 8, 8);
        var material = new THREE.MeshLambertMaterial({ color: meshColor});

        var mesh = new THREE.Mesh(geometry, material);

        mesh.material.ambient = mesh.material.color;

        mesh.position.x = position.x;
        mesh.position.y = position.y;
        mesh.position.z = position.z;

        this.sphere = mesh;

        scene.add(this.sphere);
        fadingSpheres.push(this);

        this.ttl = sphereTTL;
        this.updateToRemove = function () {
            this.ttl--;
            return (this.ttl <= 0);
        }
    }

    function removeDeadSpheres(fadingSphere, number, array) {
        if (fadingSphere) {
            if (fadingSphere.updateToRemove()) {
                scene.remove(fadingSphere.sphere);
                var index = array.indexOf(fadingSphere);
                array.splice(index, 1);
            }
        }
    }

    //Within the leap draw loop
    //Leap loop to call drawing functions
    Leap.loop(
      function (frame) {
          frame.hands.forEach(
            function (hand) {
                var handMesh = hand.data('riggedHand.mesh');

                function createSphereAtFingerTip(fingerIndex, colorHex) {
                    new FadingSphere(handMesh.fingers[fingerIndex].tip.getWorldPosition(), 3, colorHex);
                }

                createSphereAtFingerTip(0, 0xF57E20) //Thumb
                createSphereAtFingerTip(1, 0xFFCC00) //Index
                createSphereAtFingerTip(2, 0xCCCC51) //Middle
                createSphereAtFingerTip(3, 0x8FB258) //Ring
                createSphereAtFingerTip(4, 0x336699) //pinky
            }
       )
      }
    )
    .use('riggedHand')
    .use('handEntry')

    riggedHandPlugin = Leap.loopController.plugins.riggedHand;

    initScene();
    render();

非常感谢任何可能有用的建议/建议。

2 个答案:

答案 0 :(得分:1)

绑定手插件存在一个已知问题:不幸的是,蒙皮网格模型与Leap Motion API返回的手数据(略微)有不同的比例。这意味着对于给定的姿势,网格骨骼的尖端和API返回的尖端位置数据将彼此接近,但不同。

(在内部,插件通过计算从骨骼到骨骼的正确角度来工作,然后将其提供给THREE.js Skinning API)

您可以使用此示例实际查看偏移量:http://leapmotion.github.io/leapjs-rigged-hand/?dots=1

这是你正在经历的吗?我想知道这一点,你应该能够获得正确的LM位置,或者在视觉上修正蒙皮网格位置。网格也可以通过编程或改造进行变形,以更准确地拟合LM数据。 (参见creating rigged hands wiki。)

答案 1 :(得分:1)

最后,感谢彼得的最后一个例子。测试3帮我找出了问题。

问题实际上是我似乎一直在使用不同的场景&#39; (变量恰当地命名)比被操纵的手所使用的场景。我没有意识到他们是不同的(doh!)。我将其切换为使用riggedHand.parent作为&#39;场景&#39;而不是我在initScene()中手动创建的场景实例,它现在有一个参数,我在riggedHand.parent中传递给第一次可用的场景。

function initScene(basisScene) {
    camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, sceneArea / 100,
      sceneArea * 4);
    camera.position.z = sceneArea;
    scene = basisScene;

其他事情是不要调用renderer.render(场景,相机);在render()循环中 - 即使在&#39; scene&#39;之后是从riggedHand.parent设置的。我没有意识到跳帧(?)使得不必再调用renderer.render了。

    function render() {
        //Next line no longer needed:
        //renderer.render(scene, camera);
        requestAnimationFrame(render);
    }

褪色领域的更新代码位于:http://codepen.io/GMelencio/pen/EaWqjZ

再次感谢彼得!