如何在 ThreeJS 中有效地更新几何体的拓扑结构?
How to update the topology of a geometry efficiently in ThreeJS?
我想避免创建新的类型化数组和随之而来的 gc()。
我使用 BufferedGeometry 制作了几何图形。收到事件后,我的顶点和 faces
索引会更新。我可以通过设置 verticesNeedUpdate
来更新坐标,但它不会更新面孔。每秒调用约 20-50 次更新,这对浏览器来说可能很繁重。如何通过避免为 JavaScript 垃圾收集器创建大量垃圾来做到这一点? (参见下面的方法 update()
)。
function WGeometry77(verts, faces) {
THREE.Geometry.call( this );
this.type = 'WGeometry77';
this.parameters = {};
// Initially create the mesh the easy way, by copying from a BufferGeometry
this.fromBufferGeometry( new MyBufferGeometry77( verts, faces ) );
};
WGeometry77.prototype = Object.create( THREE.Geometry.prototype );
WGeometry77.prototype.constructor = WGeometry77;
WGeometry77.prototype.update = function(verts, faces) {
var geom = this;
var nl = Math.min(geom.vertices.length, verts.length/3);
for ( var vi = 0; vi < nl; vi ++ ) {
geom.vertices[ vi ].x = verts[vi*3+0];
geom.vertices[ vi ].y = verts[vi*3+1];
geom.vertices[ vi ].z = verts[vi*3+2];
}
var nf = Math.min(geom.faces.length, faces.length/3);
for ( var fi = 0; fi < nf; fi ++ ) {
geom.faces[ fi ].a = faces[fi*3+0];
geom.faces[ fi ].b = faces[fi*3+1];
geom.faces[ fi ].c = faces[fi*3+2];
}
geom.verticesNeedUpdate = true; // Does not update the geom.faces
}
PS。我的代码是用 Emscripten 编写的,它的作用如下:
var verts = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 3*nverts);
我想做的几乎是动画,或者动态几何体(使用移动立方体计算)。但是我的拓扑(网格图)也更新了。我应该使用哪个 ThreeJS class?如果不存在这样的 class,我应该创建我们创建一个像 UpdatableBufferedGeometry
的新 class 吗?
如果你想要效率,你应该创建一个 BufferGeometry
而不是 Geometry
。
您可以参考本例源码:
http://threejs.org/examples/#webgl_buffergeometry_uint
要在呈现后更新 THREE.BufferGeometry
,您可以使用此模式:
geometry.attributes.position.setXYZ( index, x, y, z );
geometry.attributes.position.needsUpdate = true;
对于索引 BufferGeometry
,您可以像这样更改 index
数组:
geometry.index.array[ index ] = value;
geometry.index.needsUpdate = true;
您无法调整缓冲区大小 -- 只能更改其内容。您可以预先分配更大的数组并使用
geometry.setDrawRange( 0, numVertices );
three.js r.78
我想避免创建新的类型化数组和随之而来的 gc()。
我使用 BufferedGeometry 制作了几何图形。收到事件后,我的顶点和 faces
索引会更新。我可以通过设置 verticesNeedUpdate
来更新坐标,但它不会更新面孔。每秒调用约 20-50 次更新,这对浏览器来说可能很繁重。如何通过避免为 JavaScript 垃圾收集器创建大量垃圾来做到这一点? (参见下面的方法 update()
)。
function WGeometry77(verts, faces) {
THREE.Geometry.call( this );
this.type = 'WGeometry77';
this.parameters = {};
// Initially create the mesh the easy way, by copying from a BufferGeometry
this.fromBufferGeometry( new MyBufferGeometry77( verts, faces ) );
};
WGeometry77.prototype = Object.create( THREE.Geometry.prototype );
WGeometry77.prototype.constructor = WGeometry77;
WGeometry77.prototype.update = function(verts, faces) {
var geom = this;
var nl = Math.min(geom.vertices.length, verts.length/3);
for ( var vi = 0; vi < nl; vi ++ ) {
geom.vertices[ vi ].x = verts[vi*3+0];
geom.vertices[ vi ].y = verts[vi*3+1];
geom.vertices[ vi ].z = verts[vi*3+2];
}
var nf = Math.min(geom.faces.length, faces.length/3);
for ( var fi = 0; fi < nf; fi ++ ) {
geom.faces[ fi ].a = faces[fi*3+0];
geom.faces[ fi ].b = faces[fi*3+1];
geom.faces[ fi ].c = faces[fi*3+2];
}
geom.verticesNeedUpdate = true; // Does not update the geom.faces
}
PS。我的代码是用 Emscripten 编写的,它的作用如下:
var verts = Module.HEAPF32.subarray(verts_address/_FLOAT_SIZE, verts_address/_FLOAT_SIZE + 3*nverts);
我想做的几乎是动画,或者动态几何体(使用移动立方体计算)。但是我的拓扑(网格图)也更新了。我应该使用哪个 ThreeJS class?如果不存在这样的 class,我应该创建我们创建一个像 UpdatableBufferedGeometry
的新 class 吗?
如果你想要效率,你应该创建一个 BufferGeometry
而不是 Geometry
。
您可以参考本例源码: http://threejs.org/examples/#webgl_buffergeometry_uint
要在呈现后更新 THREE.BufferGeometry
,您可以使用此模式:
geometry.attributes.position.setXYZ( index, x, y, z );
geometry.attributes.position.needsUpdate = true;
对于索引 BufferGeometry
,您可以像这样更改 index
数组:
geometry.index.array[ index ] = value;
geometry.index.needsUpdate = true;
您无法调整缓冲区大小 -- 只能更改其内容。您可以预先分配更大的数组并使用
geometry.setDrawRange( 0, numVertices );
three.js r.78