private static UVCoord U16LEBytesToUV(byte[] data, int offset, UVCoord posMin, UVCoord posMax) { int offs = offset; var buf = data; if (!BitConverter.IsLittleEndian) { buf = new byte[6]; Buffer.BlockCopy(data, offs, buf, 0, 6); Array.Reverse(buf, 0, 2); Array.Reverse(buf, 2, 2); Array.Reverse(buf, 4, 2); offs = 0; } var vx = BitConverter.ToUInt16(buf, offs); var vy = BitConverter.ToUInt16(buf, offs + 2); var u = (vx * (posMax.U - posMin.U) / 65535f) + posMin.U; var v = (vy * (posMax.V - posMin.V) / 65535f) + posMin.V; return(new UVCoord(u, v)); }
protected void Load(byte[] data, int physOffset, int physSize) { AnArray submeshes; using (var ms = new MemoryStream(data, physOffset, physSize)) { using (var gz = new ZlibStream(ms, CompressionMode.Decompress)) { submeshes = (AnArray)LlsdBinary.Deserialize(gz); } } int faceNo = 0; foreach (var iv in submeshes) { var submesh = (Map)iv; var posMax = new Vector3(0.5, 0.5, 0.5); var posMin = new Vector3(-0.5, -0.5, -0.5); var uvMax = new UVCoord(); var uvMin = new UVCoord(); if (submesh.ContainsKey("PositionDomain")) { var posDom = (Map)submesh["PositionDomain"]; if (posDom.ContainsKey("Max")) { var ivdom = (AnArray)posDom["Max"]; posMax = new Vector3(ivdom[0].AsReal, ivdom[1].AsReal, ivdom[2].AsReal); } if (posDom.ContainsKey("Min")) { var ivdom = (AnArray)posDom["Min"]; posMin = new Vector3(ivdom[0].AsReal, ivdom[1].AsReal, ivdom[2].AsReal); } } byte[] posBytes = (BinaryData)submesh["Position"]; byte[] normalBytes = null; byte[] texcoordBytes = null; if (submesh.ContainsKey("Normal")) { normalBytes = (BinaryData)submesh["Normal"]; } if (submesh.ContainsKey("TexCoord0")) { texcoordBytes = (BinaryData)submesh["TexCoord0"]; var texDom = (Map)submesh["TexCoord0Domain"]; if (texDom.ContainsKey("Max")) { var domData = (AnArray)texDom["Max"]; uvMax.U = (float)domData[0].AsReal; uvMax.V = (float)domData[1].AsReal; } if (texDom.ContainsKey("Min")) { var domData = (AnArray)texDom["Min"]; uvMin.U = (float)domData[0].AsReal; uvMin.V = (float)domData[1].AsReal; } } var faceIndexOffset = (ushort)Vertices.Count; int uvBytePos = 0; for (int i = 0; i < posBytes.Length; i += 6) { Vertices.Add(U16LEBytesToVertex(posBytes, i, posMin, posMax)); if (normalBytes != null) { Normals.Add(U16LEBytesToVertex(normalBytes, i, posMin, posMax)); } if (texcoordBytes != null) { UVCoords.Add(U16LEBytesToUV(texcoordBytes, uvBytePos, uvMin, uvMax)); uvBytePos += 4; } } byte[] triangleBytes = (BinaryData)submesh["TriangleList"]; for (int i = 0; i < triangleBytes.Length; i += 6) { var v1 = (ushort)(BytesLEToU16(triangleBytes, i) + faceIndexOffset); var v2 = (ushort)(BytesLEToU16(triangleBytes, i + 2) + faceIndexOffset); var v3 = (ushort)(BytesLEToU16(triangleBytes, i + 4) + faceIndexOffset); var t = new Triangle(v1, v2, v3) { FaceIdx = faceNo }; Triangles.Add(t); } ++faceNo; } NumFaces = faceNo; }