Przeglądaj źródła

hmd large index support

Nicolas Cannasse 4 lat temu
rodzic
commit
5036c03c92
3 zmienionych plików z 90 dodań i 37 usunięć
  1. 6 4
      h3d/prim/HMDModel.hx
  2. 69 26
      hxd/fmt/fbx/HMDOut.hx
  3. 15 7
      hxd/fmt/hmd/Library.hx

+ 6 - 4
h3d/prim/HMDModel.hx

@@ -55,7 +55,8 @@ class HMDModel extends MeshPrimitive {
 
 	override function alloc(engine:h3d.Engine) {
 		dispose();
-		buffer = new h3d.Buffer(data.vertexCount, data.vertexStride);
+		var is32 = data.vertexCount >= 65534;
+		buffer = new h3d.Buffer(data.vertexCount, data.vertexStride, is32 ? [LargeBuffer] : null);
 
 		var entry = lib.resource.entry;
 		entry.open();
@@ -72,11 +73,12 @@ class HMDModel extends MeshPrimitive {
 			indexesTriPos.push(Std.int(indexCount/3));
 			indexCount += n;
 		}
-		indexes = new h3d.Indexes(indexCount);
+		indexes = new h3d.Indexes(indexCount, is32);
 
 		entry.skip(data.indexPosition - (data.vertexPosition + size));
-		var bytes = haxe.io.Bytes.alloc(indexCount * 2);
-		entry.read(bytes, 0, indexCount * 2);
+		var imult = is32 ? 4 : 2;
+		var bytes = haxe.io.Bytes.alloc(indexCount * imult);
+		entry.read(bytes, 0, indexCount * imult);
 		indexes.uploadBytes(bytes, 0, indexCount);
 
 		entry.close();

+ 69 - 26
hxd/fmt/fbx/HMDOut.hx

@@ -179,10 +179,17 @@ class HMDOut extends BaseLibrary {
 		// build geometry
 		var gm = geom.getGeomMatrix();
 		var vbuf = new hxd.FloatBuffer();
-		var ibufs = [];
-
-		if( skin != null && skin.isSplit() )
-			for( _ in skin.splitJoints ) ibufs.push(new hxd.IndexBuffer());
+		var ibufs = null, lbufs = null;
+		var isSmall = verts.length > 65534 * 3;
+		if( isSmall ) ibufs = [] else lbufs = [];
+
+		if( skin != null && skin.isSplit() ) {
+			for( _ in skin.splitJoints )
+				if( isSmall )
+					ibufs.push(new hxd.IndexBuffer());
+				else
+					lbufs.push([]);
+		}
 
 		g.bounds = new h3d.col.Bounds();
 		var tmpBuf = new hxd.impl.TypedArray.Float32Array(stride);
@@ -302,11 +309,20 @@ class HMDOut extends BaseLibrary {
 
 			// by-skin-group index
 			if( skin != null && skin.isSplit() ) {
-				for( n in 0...count - 2 ) {
-					var idx = ibufs[skin.triangleGroups[stri++]];
-					idx.push(vertexRemap[start + n]);
-					idx.push(vertexRemap[start + count - 1]);
-					idx.push(vertexRemap[start + n + 1]);
+				if( isSmall ) {
+					for( n in 0...count - 2 ) {
+						var idx = ibufs[skin.triangleGroups[stri++]];
+						idx.push(vertexRemap[start + n]);
+						idx.push(vertexRemap[start + count - 1]);
+						idx.push(vertexRemap[start + n + 1]);
+					}
+				} else {
+					for( n in 0...count - 2 ) {
+						var idx = lbufs[skin.triangleGroups[stri++]];
+						idx.push(vertexRemap[start + n]);
+						idx.push(vertexRemap[start + count - 1]);
+						idx.push(vertexRemap[start + n + 1]);
+					}
 				}
 			}
 			// by-material index
@@ -318,15 +334,28 @@ class HMDOut extends BaseLibrary {
 					mid = mats[matPos];
 					if( mats.length > 1 ) matPos++;
 				}
-				var idx = ibufs[mid];
-				if( idx == null ) {
-					idx = new hxd.IndexBuffer();
-					ibufs[mid] = idx;
-				}
-				for( n in 0...count - 2 ) {
-					idx.push(vertexRemap[start + n]);
-					idx.push(vertexRemap[start + count - 1]);
-					idx.push(vertexRemap[start + n + 1]);
+				if( isSmall ) {
+					var idx = ibufs[mid];
+					if( idx == null ) {
+						idx = new hxd.IndexBuffer();
+						ibufs[mid] = idx;
+					}
+					for( n in 0...count - 2 ) {
+						idx.push(vertexRemap[start + n]);
+						idx.push(vertexRemap[start + count - 1]);
+						idx.push(vertexRemap[start + n + 1]);
+					}
+				} else {
+					var idx = lbufs[mid];
+					if( idx == null ) {
+						idx = [];
+						lbufs[mid] = idx;
+					}
+					for( n in 0...count - 2 ) {
+						idx.push(vertexRemap[start + n]);
+						idx.push(vertexRemap[start + count - 1]);
+						idx.push(vertexRemap[start + n + 1]);
+					}
 				}
 			}
 
@@ -342,15 +371,29 @@ class HMDOut extends BaseLibrary {
 		g.indexCounts = [];
 
 		var matMap = [], matCount = 0;
-		for( idx in ibufs ) {
-			if( idx == null ) {
-				matCount++;
-				continue;
+
+		if( isSmall ) {
+			for( idx in ibufs ) {
+				if( idx == null ) {
+					matCount++;
+					continue;
+				}
+				matMap.push(matCount++);
+				g.indexCounts.push(idx.length);
+				for( i in idx )
+					dataOut.writeUInt16(i);
+			}
+		} else {
+			for( idx in lbufs ) {
+				if( idx == null ) {
+					matCount++;
+					continue;
+				}
+				matMap.push(matCount++);
+				g.indexCounts.push(idx.length);
+				for( i in idx )
+					dataOut.writeInt32(i);
 			}
-			matMap.push(matCount++);
-			g.indexCounts.push(idx.length);
-			for( i in idx )
-				dataOut.writeUInt16(i);
 		}
 
 		if( skin != null && skin.isSplit() )

+ 15 - 7
hxd/fmt/hmd/Library.hx

@@ -148,15 +148,18 @@ class Library {
 
 		entry.skip(geom.indexPosition - (geom.vertexPosition + vsize));
 
+		var isSmall = geom.vertexCount < 65534;
+		var imult = isSmall ? 4 : 2;
+
 		var isize;
 		if( material == null )
-			isize = geom.indexCount * 2;
+			isize = geom.indexCount * imult;
 		else {
 			var ipos = 0;
 			for( i in 0...material )
 				ipos += geom.indexCounts[i];
-			entry.skip(ipos * 2);
-			isize = geom.indexCounts[material] * 2;
+			entry.skip(ipos * imult);
+			isize = geom.indexCounts[material] * imult;
 		}
 		var ibuf = haxe.io.Bytes.alloc(isize);
 		entry.read(ibuf, 0, isize);
@@ -194,9 +197,14 @@ class Library {
 					m = m.next;
 				}
 			}
-			var r = 0;
-			for( i in 0...buf.indexes.length )
-				buf.indexes[i] = ibuf.get(r++) | (ibuf.get(r++) << 8);
+			if( isSmall ) {
+				var r = 0;
+				for( i in 0...buf.indexes.length )
+					buf.indexes[i] = ibuf.get(r++) | (ibuf.get(r++) << 8);
+			} else {
+				for( i in 0...buf.indexes.length )
+					buf.indexes[i] = ibuf.getInt32(i << 2);
+			}
 		} else {
 			var icount = geom.indexCounts[material];
 			var vmap = new haxe.ds.Vector(geom.vertexCount);
@@ -204,7 +212,7 @@ class Library {
 			buf.indexes = new haxe.ds.Vector(icount);
 			var r = 0, vcount = 0;
 			for( i in 0...buf.indexes.length ) {
-				var vid = ibuf.get(r++) | (ibuf.get(r++) << 8);
+				var vid = isSmall ? (ibuf.get(r++) | (ibuf.get(r++) << 8)) : ibuf.getInt32(i<<2);
 				var rid = vmap[vid];
 				if( rid == 0 ) {
 					rid = ++vcount;