public override Mesh decode(MeshInfo minfo, CtmInputStream input) { int vc = minfo.getVertexCount(); checkTag(input.readLittleInt(), MG2_HEADER_TAG); float vertexPrecision = input.readLittleFloat(); float normalPrecision = input.readLittleFloat(); Grid grid = Grid.fromStream(input); if(!grid.checkIntegrity()) { throw new InvalidDataException("The vertex size grid is corrupt!"); } float[] vertices = readVertices(input, grid, vc, vertexPrecision); int[] indices = readIndices(input, minfo.getTriangleCount(), vc); float[] normals = null; if (minfo.hasNormals()) { normals = readNormals(input, vertices, indices, normalPrecision, vc); } AttributeData[] uvData = new AttributeData[minfo.getUvMapCount()]; for (int i = 0; i < uvData.Length; i++) { uvData[i] = readUvData(input, vc); } AttributeData[] attributs = new AttributeData[minfo.getAttrCount()]; for (int i = 0; i < attributs.Length; i++) { attributs[i] = readAttribute(input, vc); } return new Mesh(vertices, normals, indices, uvData, attributs); }
public override Mesh decode(MeshInfo minfo, CtmInputStream input) { int vc = minfo.getVertexCount(); AttributeData[] tex = new AttributeData[minfo.getUvMapCount()]; AttributeData[] att = new AttributeData[minfo.getAttrCount()]; checkTag(input.readLittleInt(), INDX); int[] indices = readIntArray(input, minfo.getTriangleCount(), 3, false); checkTag(input.readLittleInt(), VERT); float[] vertices = readFloatArray(input, vc * Mesh.CTM_POSITION_ELEMENT_COUNT, 1); float[] normals = null; if (minfo.hasNormals()) { checkTag(input.readLittleInt(), NORM); normals = readFloatArray(input, vc, Mesh.CTM_NORMAL_ELEMENT_COUNT); } for (int i = 0; i < tex.Length; ++i) { checkTag(input.readLittleInt(), TEXC); tex[i] = readUVData(vc, input); } for (int i = 0; i < att.Length; ++i) { checkTag(input.readLittleInt(), ATTR); att[i] = readAttrData(vc, input); } return new Mesh(vertices, normals, indices, tex, att); }
/** * Calculate various forms of derivatives in order to reduce data entropy. */ private int[] makeUVCoordDeltas(AttributeData map, SortableVertex[] sortVertices) { // UV coordinate scaling factor float scale = 1.0f / map.precision; int vc = sortVertices.Length; int prevU = 0, prevV = 0; int[] intUVCoords = new int[vc * Mesh.CTM_UV_ELEMENT_COUNT]; for (int i = 0; i < vc; ++i) { // Get old UV coordinate index (before vertex sorting) int oldIdx = sortVertices [i].originalIndex; // Convert to fixed point int u = (int)Math.Floor (scale * map.values [oldIdx * 2] + 0.5f); int v = (int)Math.Floor (scale * map.values [oldIdx * 2 + 1] + 0.5f); // Calculate delta and store it in the converted array. NOTE: Here we rely // on the fact that vertices are sorted, and usually close to each other, // which means that UV coordinates should also be close to each other... intUVCoords [i * 2] = u - prevU; intUVCoords [i * 2 + 1] = v - prevV; prevU = u; prevV = v; } return intUVCoords; }
/** * Calculate various forms of derivatives in order to reduce data entropy. */ private int[] makeAttribDeltas(AttributeData map, SortableVertex[] sortVertices) { // Attribute scaling factor float scale = 1.0f / map.precision; int[] prev = new int[4]; int vc = sortVertices.Length; int[] intAttribs = new int[vc * Mesh.CTM_ATTR_ELEMENT_COUNT]; for (int i = 0; i < vc; ++i) { // Get old attribute index (before vertex sorting) int oldIdx = sortVertices [i].originalIndex; // Convert to fixed point, and calculate delta and store it in the converted // array. NOTE: Here we rely on the fact that vertices are sorted, and // usually close to each other, which means that attributes should also // be close to each other (and we assume that they somehow vary slowly with // the geometry)... for (int j = 0; j < 4; ++j) { int value = (int)Math.Floor (scale * map.values [oldIdx * 4 + j] + 0.5f); intAttribs [i * 4 + j] = value - prev [j]; prev [j] = value; } } return intAttribs; }
private void testAttributeArrays(AttributeData[] a, AttributeData[] b, int[] indexLUT) { if ((a == null || a.Length == 0) && (b == null || b.Length == 0)) return; Assert.AreEqual (a.Length, b.Length); for (int i=0; i < a.Length; i++) { Assert.AreEqual (a [i].materialName, b [i].materialName); Assert.AreEqual (a [i].name, b [i].name); Assert.AreEqual (a [i].precision, b [i].precision); float[] orig = a [i].values; float[] read = b [i].values; Assert.AreEqual (orig.Length, read.Length); int count = orig.Length / indexLUT.Length; Assert.AreEqual (count * indexLUT.Length, orig.Length); for (int vi=0; vi < indexLUT.Length; vi++) { int newIndex = indexLUT [vi]; for (int e = 0; e < count; e++) { Assert.IsTrue (compare (orig [vi * count + e], read [newIndex * count + e], a [i].precision * 2), "Attributs not in precision"); } } } }