Leap 点的位置与 THREEJS 场景不同步
Position of Leap point not in sync with THREEJS Scene
我一直在竭尽全力获取 RiggedHand 网格呈现的位置,以便在 THREEJS 场景中准确创建小球体。我正在尝试在给定指尖的位置执行此操作。 X 和 Y 似乎是正确的,但 Z 几乎总是关闭。更重要的是,它离中心越远,倾斜就越明显(即 X 和 Y 也关闭)。
我能做的最好的事情就是使用以下代码计算出 'right' 坐标:
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,使用交互框并乘以窗口大小以尝试获得准确的位置。我开始怀疑它是否与我在 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();
非常感谢任何可能有帮助的suggestions/advice。
操纵手部插件存在一个已知问题:不幸的是,蒙皮网格模型与 Leap Motion API 返回的手部数据的比例(略有)不同。这意味着对于给定的姿势,网格骨骼的尖端和 API 返回的尖端位置数据将彼此靠近,但不同。
(在内部,插件通过计算从骨骼到骨骼的正确角度来工作,然后将其馈送到 THREE.js 蒙皮 API)
您可以使用此示例实际查看偏移量:http://leapmotion.github.io/leapjs-rigged-hand/?dots=1
这是您遇到的情况吗?我认为知道了这一点,您应该能够获得正确的 LM 位置,或者在视觉上正确的蒙皮网格位置。网格也可以通过编程方式变形或重新建模,以更准确地适应 LM 数据。 (参见creating rigged hands wiki。)
感谢 Peter 的最后一个示例,最终修复了它。是测试 3 帮助我找出了问题所在。
问题实际上是我似乎一直在使用与被操纵的手使用的场景不同的 'scene'(变量名恰如其分)。我没有意识到他们是不同的(doh!)。我将其切换为使用 riggedHand.parent 作为 'scene' 而不是我在 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() 循环中 - 即使在从 riggedHand.parent 设置 'scene' 之后。我没有意识到跳跃框架(?)使得不必再调用 renderer.render 了。
function render() {
//Next line no longer needed:
//renderer.render(scene, camera);
requestAnimationFrame(render);
}
带有渐变球体的更新代码位于:http://codepen.io/GMelencio/pen/EaWqjZ
再次感谢彼得!
我一直在竭尽全力获取 RiggedHand 网格呈现的位置,以便在 THREEJS 场景中准确创建小球体。我正在尝试在给定指尖的位置执行此操作。 X 和 Y 似乎是正确的,但 Z 几乎总是关闭。更重要的是,它离中心越远,倾斜就越明显(即 X 和 Y 也关闭)。
我能做的最好的事情就是使用以下代码计算出 'right' 坐标:
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,使用交互框并乘以窗口大小以尝试获得准确的位置。我开始怀疑它是否与我在 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();
非常感谢任何可能有帮助的suggestions/advice。
操纵手部插件存在一个已知问题:不幸的是,蒙皮网格模型与 Leap Motion API 返回的手部数据的比例(略有)不同。这意味着对于给定的姿势,网格骨骼的尖端和 API 返回的尖端位置数据将彼此靠近,但不同。
(在内部,插件通过计算从骨骼到骨骼的正确角度来工作,然后将其馈送到 THREE.js 蒙皮 API)
您可以使用此示例实际查看偏移量:http://leapmotion.github.io/leapjs-rigged-hand/?dots=1
这是您遇到的情况吗?我认为知道了这一点,您应该能够获得正确的 LM 位置,或者在视觉上正确的蒙皮网格位置。网格也可以通过编程方式变形或重新建模,以更准确地适应 LM 数据。 (参见creating rigged hands wiki。)
感谢 Peter 的最后一个示例,最终修复了它。是测试 3 帮助我找出了问题所在。
问题实际上是我似乎一直在使用与被操纵的手使用的场景不同的 'scene'(变量名恰如其分)。我没有意识到他们是不同的(doh!)。我将其切换为使用 riggedHand.parent 作为 'scene' 而不是我在 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() 循环中 - 即使在从 riggedHand.parent 设置 'scene' 之后。我没有意识到跳跃框架(?)使得不必再调用 renderer.render 了。
function render() {
//Next line no longer needed:
//renderer.render(scene, camera);
requestAnimationFrame(render);
}
带有渐变球体的更新代码位于:http://codepen.io/GMelencio/pen/EaWqjZ
再次感谢彼得!