Three.js SkinnedMesh - связать вершину с костью - PullRequest
0 голосов
/ 08 февраля 2019

Я использую OpenCV для обработки любого изображения (сегмент, выпуклая оболочка, полость).Затем я использую Three.js, чтобы использовать эти координаты как кости.Чтобы создать SkinnedMesh, я начал с этого примера цилиндра , который является 1-линейным.Поскольку моя цель - поддерживать руки / ноги, я решил пройти расстояние от вершины до ближайшей кости, что привело ко многим сбоям.

Вершины в skinIndex не реагируют.Тень движется с анимацией, но не с моделью.Стороны двигаются, но не спереди / сзади.Это похоже на проблему синхронизации, которая может потребовать обещание / асинхронность (?). Я попытался вызвать requireUpdate, присвоить счет, установить динамическое значение в true и т. Д.

Я понимаю, что это незаконченное домашнее задание, но это что-тов корне неправильно?

https://codepen.io/kpachinger/pen/ZVgejg

var skinIndices = [];
var skinWeights = [];

function distance(x1, y1, x2, y2) {
  let a = x1 - x2;
  let b = y1 - y2;
  let c = 1 - Math.sqrt(a * a + b * b);
  c = Math.abs(c);

  return c;
}

let pos = geometry.attributes.position;
var promise = new Promise(function(resolve, reject) {

  let root = sto.skind[0].id;
  let skin = [];

  for (let i = 0; i < pos.count; i++) {
    x1 = pos.array[i * 2];
    y1 = pos.array[i * 3];

    skin[i] = [];

    for (let j = 0; j < bones.length; j++) {
      x2 = bones[j].positionGlobal.x / sto.width;
      y2 = bones[j].positionGlobal.y / sto.height;

      if (bones[j].name != 'Root' && bones[j].name != 'Bone_0') {
        skin[i].push(distance(x1, y1, x2, y2) + '|' + bones[j].id);
      }
    }

    skin[i].sort();

    let closest = skin[i][0];
    closest = closest.split('|');
    closest = {
      'dist': closest[0],
      'id': closest[1] * 1
    };

    const halfHeight = area / (sto.width + sto.height) / 4;
    const segmentHeight = halfHeight / 3;

    const y = Math.abs(y1);
    var skinIndexY = Math.floor(y / segmentHeight / 2);
    var skinWeightY = ((y / segmentHeight) * (halfHeight / 2)) / 2;

    skinIndices.push(
      skinIndexY,
      closest.id,
      closest.id,
      root);

    //all add up to 1
    skinWeights.push(
      0.5 - (skinWeightY*0.50),
      (skinWeightY*0.50),
      0.25,
      0.25);

  }

  resolve('Vertices => SkinnedMesh');
});


promise.then(function(value) {
  console.log(value);

  geometry.addAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4));
  geometry.addAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4));

  mesh = new THREE.SkinnedMesh(geometry, [material, materialSides]);
  let skeleton = new THREE.Skeleton(bones);

  mesh.add(bones[0]);
  mesh.bind(skeleton);

  let skeletonHelper = new THREE.SkeletonHelper(mesh);
  skeletonHelper.material.linewidth = 2;

  group.add(mesh, skeletonHelper);

  return mesh;
});

1 Ответ

0 голосов
/ 26 марта 2019

решено: исправление (я):

  • var vertex = new THREE.Vector3 ();
  • vertex.fromBufferAttribute (position, i);
  • массив skinIndices должен увеличивать новые уникальные идентификаторы костей, в отличие от ранее существовавших ссылок.
  • не смешивать SkinnedMesh и Mesh в текстуре, иначе слезы / исчезновение / несинхронизациятень
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...