Three.js: Как создать новую "изменяющуюся" геометрию, если у меня есть все необходимые буферы?

Я использую веб-работника, чтобы загрузить .json файл анимированной 3D модели. Для каждого из больших массивов (вершин, нормалей и т. Д.) Я передаю Float32Array Буфер обратно в поток пользовательского интерфейса. Поскольку такие буферы являются переносимыми объектами, это займет (почти) нулевое время.

Теперь выясняется, что WebGL (и, следовательно, Three.js) используют Float32Array Внутренние буферы тоже. Это означает, что я мог бы загрузить эту 3D-анимацию, ничего не копируя, потратив почти нулевое время в основном потоке. Разве это не мило?

Но не ясно, как это сделать: в главном потоке у нас есть буферы массивов для вершин, нормалей (основных и морфовых) и граней. Как мне создать рабочий Geometry (или же BufferGeometry) из этих, без перевода или копирования данных?

var scene,
    vertices, normals, faces,
    morphVertices, morphNormals; // <-- we have all these as typed arrays

var geometry = ...; // <-- insert code here

var material = new THREE.MeshLambertMaterial({ morphTargets: true });
var object3D = new THREE.MorphAnimMesh(geometry, material);
scene.add(object3D);

Этот ответ дает подсказку, но только пункт 7 представляется актуальным, он предполагает, что уже есть некоторые Geometry экземпляр, и он не обрабатывает морф-цели.

1 ответ

Вот пример, основанный на части загрузки сетки в THREE.GLTF2Loader.

// Create BufferGeometry and assign vertices and normals.
var geometry = new THREE.BufferGeometry();
geometry.addAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) );
geometry.addAttribute( 'normal', new THREE.BufferAttribute( normals, 3 ) );
geometry.setIndex( new THREE.BufferAttribute( faces, 3 ) );

// Create material.
var material = new THREE.MeshStandardMaterial({
  morphTargets: true,
  morphNormals: true
});

// Set up morph target attributes.
var posAttr = new THREE.BufferAttribute( morphVertices, 3 );
var normAttr = new THREE.BufferAttribute( morphNormals, 3 );
for (var i = 0; i < posAttr.array.length; i++) {
  posAttr.array[i] += geometry.attributes.position.array[i];
}
for (var j = 0; j < normAttr.array.length; j++) {
  normAttr.array[j] += geometry.attributes.normal.array[j];
}

// Assign morph target attributes.
geometry.morphAttributes.position = [ posAttr ];
geometry.morphAttributes.normal = [ normAttr ];

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

// Apply 50/50 blend of morph targets and default position/normals.
mesh.morphTargetInfluences[0] = 0.5;

three.js r86-dev.

Другие вопросы по тегам