Я пытаюсь визуализировать облака точек, используя программу просмотра Autodesk Forge. Это прекрасно работает, используя THREE.Geometry
, как описано здесь https://forge.autodesk.com/blog/using-pointcloud-forge-viewer. В этой статье указано, что нельзя использовать BufferGeometry.
Однако я хочу быть абсолютно уверенным, есть ли какой-либо способ использования PointCloud с BufferGeometry без необходимости создания THREE.Geometry
. У меня уже есть данные как Float32Array
для точек и Uint8Array
для цветов, поэтому их вставка в THREE.Vector3
выглядит как чрезмерная нагрузка.
Просматривая источник https://autodeskviewer.com/viewers/latest/viewer3D.js есть некоторые упоминания о буферах облака точек, (ищите createPointCloudBuffers(geometry)
.
Edit:
При попытке использовать THREE.BufferGeometry с THREE.PointCloud
с:
const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(position, 3));
geometry.addAttribute('color', new THREE.BufferAttribute(color, 3));
const pc = THREE.PointCloud(geometry, <material>);
Я получаю следующее сообщение:
Only THREE.Mesh can be rendered by the Firefly renderer. Use THREE.Mesh to draw lines.
(посмотрите на функцию renderBufferDirect в https://autodeskviewer.com/viewers/latest/viewer3D.js)
Редактировать 2 : Благодаря этому комментарию Мне удалось решить вышеуказанную проблему. Я просто должен был использовать THREE.Mesh
и установить isPoints=true
:
const geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(position, 3));
geometry.addAttribute('color', new THREE.BufferAttribute(color, 3));
geometry.isPoints = true;
const mesh = new THREE.Mesh(geometry, <material>);
Однако некоторые данные о местоположении, которые у меня есть, а также данные о цвете сохраняются как Uint8Array
, и приведенное выше может привести к следующей ошибке с WebGL:
ERROR :GL_INVALID_OPERATION : glDrawArrays: attempt to access out of range vertices in attribute 0
Преобразование в Float32Array
решит проблему. Было бы неплохо пройти этот дополнительный шаг, есть ли способ использовать Uint8Array, не копируя его во Float32Array (используя Float32Array.from(<Uint8Array>)
)?
Редактировать 3:
Я понял, что возможна поддержка Uint8Array
и Uint16Array
, делая следующее:
geometry.attributes.position.bytesPerItem = <1 | 2>; // set 1 for Uint8Arrays and 2 for Uint16
geometry.attributes.position.normalize = true;