|
kurono, Sr. Member
Posted: 16 December 2012 02:26 PM Total Posts: 103
Hi all!
I’ve always use a Merge.as in order to increase rendering performance for large scenes. And everything worked perfect until version 4.1. Recent Merge.as works not as I expected: it does something strange with vertex’s normals, and as a result the image is wrong. By the way, now Merge.as can’t increase performance as in previous versions. It seems, that it creates multiple geometries for mesh instead of building the single geometry of merged objects.
Is the way of using Merge.as changed since last update, so I’m doing something wrong? Or is it a bug?
I’m looking forward to your help!
For test purposes I wrote the following part of code and attached two screenshots to see the difference between 10 separate spheres and the ones merged to single mesh.
var merge:Merge = new Merge(true); var finalMesh:Mesh; var o:Mesh = new Mesh(new SphereGeometry(), defaultMtl); var m:Mesh; var i:uint; var xz:Point; var cont:ObjectContainer3D = new ObjectContainer3D(); for (i=0; i<10; i++) { m = o.clone() as Mesh; xz = new Point(view.camera.lens.far / 2 * (1 - 2 * Math.random()), view.camera.lens.far / 2 * (1 - 2 * Math.random())); m.positi Vector3D(xz.x, 10, xz.y); m.scale(.8 + .2 * Math.random()); //view.scene.addChild(m); trace(i); cont.addChild(m); } finalMesh = merge.applyToContainer(cont); view.scene.addChild(finalMesh);
|
kurono, Sr. Member
Posted: 16 December 2012 06:37 PM Total Posts: 103
[ # 1 ]
Ok, I decided to make kinda merge.
I collected 10 spheres to the vector of “Meshes” (var meshes:Vector.<Mesh>).
Then
var isub:ISubGeometry; var rawVertsAll:Vector.<Number> = new Vector.<Number>(); var rawIndicesAll:Vector.<uint> = new Vector.<uint>(); var rawUVsAll:Vector.<Number> = new Vector.<Number>(); var rawVerts:Vector.<Number>; var rawIndices:Vector.<uint>; var rawUVs:Vector.<Number>; var index:uint; var length:uint; for each (m in meshes) { isub = m.geometry.subGeometries[0]; rawVerts = isub.vertexData; rawIndices = isub.indexData; rawUVs = isub.UVData; // concat vertices rawVertsAll = rawVertsAll.concat(rawVerts); // shift indices length = rawVertsAll.length; for each (index in rawIndices) { index += length; } // concat indices rawIndicesAll = rawIndicesAll.concat(rawIndices); // concat uvs rawUVsAll = rawUVsAll.concat(rawUVs); } // build geometry var geometry:Geometry = new Geometry(); var subGeometry:SubGeometry = new SubGeometry(); subGeometry.autoDeriveVertexNormals = true; subGeometry.autoDeriveVertexTangents = true; subGeometry.updateVertexData(rawVertsAll); subGeometry.updateIndexData(rawIndicesAll); subGeometry.updateUVData(rawUVsAll); geometry.subGeometries.push(subGeometry); finalMesh = new Mesh(geometry, defaultMtl); view.scene.addChild(finalMesh);
So, I just wanted to build Geometry from raw sets of vertices, indices and uvs. Digging into GeomHelper.as I founded a CompactSubGeometry class, but decided to use good old SubGeometry. Eventually I get an error when engine tries to compute bounding volume:
Exception fault: RangeError: Error #1125: The index 2873 is out of range 2873. at away3d.bounds::BoundingVolumeBase/fromGeometry()[/Users/kurono/Documents/mergetest/src/away3d/bounds/BoundingVolumeBase.as:160]
|
kurono, Sr. Member
Posted: 16 December 2012 11:08 PM Total Posts: 103
[ # 2 ]
I understood, that for the current release each vertex of subgemetry has 13 attributes: x,y,z, nx,ny,nz, tx,ty,tz, u,v, ... Version 4.0 has only 3 attributes per vertex.
So, previous post is [closed].
Merge is not proper, BTW.
|
kurono, Sr. Member
Posted: 17 December 2012 02:34 AM Total Posts: 103
[ # 3 ]
At last! I did it!
For those, who interested in, here’s the complete and properly working merging code It merges 100 meshes, for example.
var finalMesh:Mesh; var o:Mesh = new Mesh(new SphereGeometry(), defaultMtl); var m:Mesh; var i:uint; var xz:Point; var cont:ObjectContainer3D = new ObjectContainer3D(); var meshes:Vector.<Mesh> = new Vector.<Mesh>(); for (i=0; i<100; i++) { m = o.clone() as Mesh; xz = new Point(view.camera.lens.far / 2 * (1 - 2 * Math.random()), view.camera.lens.far / 2 * (1 - 2 * Math.random())); m.positi Vector3D(xz.x, 10, xz.y); m.scale(.8 + .2 * Math.random()); trace(i); meshes.push(m); } trace(); var isub:ISubGeometry; var rawVertsAll:Vector.<Number> = new Vector.<Number>(); var rawIndicesAll:Vector.<uint> = new Vector.<uint>(); var rawUVsAll:Vector.<Number> = new Vector.<Number>(); var rawNormalsAll:Vector.<Number> = new Vector.<Number>(); var rawTangentsAll:Vector.<Number> = new Vector.<Number>(); var index:uint; var offset:uint = 0; var verts:Vector.<Number>; var normals:Vector.<Number>; var tangents:Vector.<Number>; var uvs:Vector.<Number>; var indices:Vector.<uint>; var j:uint; var k:uint; for (k = 0; k < meshes.length; k++) { // take a mesh m = meshes[k]; // take a geometry, make sure the buffer is free isub = m.geometry.subGeometries[0].cloneWithSeperateBuffers(); // take into accout mesh's transformations isub.applyTransformation(m.transform.clone()); // convert 13-sized vertices to 3+3+3+2+[0,0] verts = new Vector.<Number>(); normals = new Vector.<Number>(); tangents = new Vector.<Number>(); uvs = new Vector.<Number>(); indices = isub.indexData; for (i = 0; i < isub.numVertices; i++) { // xyz verts.push(isub.vertexData[i * isub.vertexStride + isub.vertexOffset]); verts.push(isub.vertexData[i * isub.vertexStride + isub.vertexOffset + 1]); verts.push(isub.vertexData[i * isub.vertexStride + isub.vertexOffset + 2]); // n normals.push(isub.vertexNormalData[i * isub.vertexNormalStride + isub.vertexNormalOffset]); normals.push(isub.vertexNormalData[i * isub.vertexNormalStride + isub.vertexNormalOffset + 1]); normals.push(isub.vertexNormalData[i * isub.vertexNormalStride + isub.vertexNormalOffset + 2]); // t tangents.push(isub.vertexTangentData[i * isub.vertexTangentStride + isub.vertexTangentOffset]); tangents.push(isub.vertexTangentData[i * isub.vertexTangentStride + isub.vertexTangentOffset + 1]); tangents.push(isub.vertexTangentData[i * isub.vertexTangentStride + isub.vertexTangentOffset + 2]); // uv uvs.push(isub.UVData[i * isub.UVStride + isub.UVOffset]); uvs.push(isub.UVData[i * isub.UVStride + isub.UVOffset + 1]); } // shift indices for (j = 0; j < indices.length; j++) { indices[j] += offset; } offset += isub.numVertices; // concat geometries rawVertsAll = rawVertsAll.concat(verts); rawNormalsAll = rawNormalsAll.concat(normals); rawTangentsAll = rawTangentsAll.concat(tangents); rawUVsAll = rawUVsAll.concat(uvs); rawIndicesAll = rawIndicesAll.concat(indices); trace(k); } trace(); // build geometry var geometry:Geometry = new Geometry(); var subGeometry:SubGeometry = new SubGeometry(); subGeometry.updateVertexData(rawVertsAll); subGeometry.updateIndexData(rawIndicesAll); subGeometry.updateUVData(rawUVsAll); subGeometry.updateVertexNormalData(rawNormalsAll); subGeometry.updateVertexTangentData(rawTangentsAll); geometry.subGeometries.push(subGeometry); finalMesh = new Mesh(geometry, defaultMtl); view.scene.addChild(finalMesh);
|
Baush, Sr. Member
Posted: 08 January 2013 09:34 PM Total Posts: 135
[ # 4 ]
Your merge method should offer much better performance I believe, I wonder if it could be added to the Merge class as an alternate merge method..
|
Raino, Newbie
Posted: 15 January 2013 09:33 AM Total Posts: 12
[ # 5 ]
kurono did great work!! finally I found this post,thanks.
How to keep different material for each mesh in this method?
|
NAZ, Newbie
Posted: 05 April 2013 01:48 PM Total Posts: 9
[ # 6 ]
hey Kurono Thanks a lot!,
Could you please explain how to access the meshes after they are merged? i would like to move them independently.
Thanks!
|