【问题标题】:Position of Leap point not in sync with THREEJS Scene跳跃点的位置与 THREEJS 场景不同步
【发布时间】:2015-01-17 15:31:31
【问题描述】:

我一直在尽最大努力获得 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,使用interactionbox并乘以windowsize来尝试得到一个准确的位置。我开始怀疑这是否与我在 THREEJS 中使用 PerspectiveCamera 并且我需要以某种方式补偿它(?)这一事实有更多关系 - 真的不知道该怎么做,但希望有人能指出我在正确的方向。

使用上述代码的完整sn-p示例代码如下:

    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();

将不胜感激任何可能有帮助的建议/建议。

【问题讨论】:

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


    【解决方案1】:

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

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

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

    这是你正在经历的吗?我认为知道了这一点,您应该能够获得正确的 LM 位置,或视觉上正确的蒙皮网格位置。网格也有可能以编程方式变形或重新建模,以更准确地拟合 LM 数据。 (见creating rigged hands wiki。)

    【讨论】:

    • 谢谢彼得!我的问题实际上似乎比你的节目更明显。我在这里提供了我的代码示例gmelencio.github.io
    • 从我在link 的示例中可以看到,在网格的手指“尖端”位置绘制的球体完全关闭。然而,这是我模拟手指点相对于网格的正确位置的最接近的方法。我觉得我缺少一些基本的东西;如果我什至可以让球体与您的示例中的操纵手网格一样接近 - 我觉得使用 Leap 与 THREEJS 时我缺少一些基本的东西,如果我能接近你所在的地方我会开心就好!
    • 注意,将上面的链接替换为:codepen.io/GMelencio/pen/QwdzYp
    • 好的! riggedHand 插件中有一个(另一个)错误,导致“点”的偏移甚至超出预期。我已经发布了 0.1.6,并更新了您的示例以进行演示。插件本身已被简化为不管理数据转换:原始跳跃数据应该是可用的,未经修改的。 -------- 在这支笔中,我在底部添加了三个测试。 1:覆盖被操纵的手的boneHand插件,2:白色球体,3:主循环内的白色球体。 ------- codepen.io/leapmotion/pen/QwderK ------- 使用 FadingSphere 时仍有一些问题,但我认为这可能在你身上
    【解决方案2】:

    感谢彼得的最后一个例子,终于解决了这个问题。正是测试 3 帮助我找出了问题所在。

    问题实际上是我似乎一直在使用与被操纵的手使用的场景不同的“场景”(恰当命名的变量)。我没有意识到它们是不同的(doh!)。我将其切换为使用 riggedHand.parent 作为“场景”,而不是我在 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(scene, camera);在 render() 循环中 - 即使在 riggedHand.parent 设置了“场景”之后。我没有意识到闰帧(?)使得不必再调用 renderer.render 了。

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

    带有渐变球体的更新代码位于:http://codepen.io/GMelencio/pen/EaWqjZ

    再次感谢彼得!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      相关资源
      最近更新 更多