public void QuaternionTests() { var q = new XbimQuaternion(); Assert.AreEqual(true, q.IsIdentity(), "Uninitialised quaternion should be identity."); q = new XbimQuaternion(0.0f, 0.0f, 0.0f, 1.0f); Assert.AreEqual(true, q.IsIdentity(), "Should be identity when initialised with floats."); var mat = new XbimMatrix3D(); q = mat.GetRotationQuaternion(); Assert.AreEqual(true, q.IsIdentity(), "Quaternion from identity matrix shold be identity."); }
internal void AddMesh(byte[] mesh, XbimMatrix3D?transform = null) { int indexBase = Positions.Count; bool needRotate = false; bool needTransform = false; XbimQuaternion xq = new XbimQuaternion(0.0, 0.0, 0.0, 1.0); XbimMatrix3D transformValue = XbimMatrix3D.Identity; if (transform.HasValue) { transformValue = transform.Value; needTransform = !transformValue.IsIdentity; xq = transformValue.GetRotationQuaternion(); // we have to build a rotation transform from the quaternion (to tranform normals later on) needRotate = !xq.IsIdentity(); } using (var ms = new MemoryStream(mesh)) using (var br = new BinaryReader(ms)) { var t = br.ReadShapeTriangulation(); List <float[]> pts; List <int> idx; t.ToPointsWithNormalsAndIndices(out pts, out idx); // add to lists // // Commented because of https://github.com/xBimTeam/XbimGltf/issues/2 //Positions.Capacity += pts.Count; //Normals.Capacity += pts.Count; //Indices.Capacity += idx.Count; foreach (var floatsArray in pts) { var tmpPosition = new XbimPoint3D(floatsArray[0], floatsArray[1], floatsArray[2]); if (needTransform) { tmpPosition = transformValue.Transform(tmpPosition); } Positions.Add(tmpPosition); var tmpNormal = new XbimVector3D(floatsArray[3], floatsArray[4], floatsArray[5]); if (needRotate) //transform the normal if we have to { XbimQuaternion.Transform(ref tmpNormal, ref xq, out tmpNormal); } Normals.Add(tmpNormal); } foreach (var index in idx) { Indices.Add(index + indexBase); } } }
public static void Read(this XbimMeshGeometry3D m3D, byte[] mesh, XbimMatrix3D?transform = null) { var indexBase = m3D.Positions.Count; var qrd = new XbimQuaternion(); XbimMatrix3D?matrix3D = null; if (transform.HasValue) { qrd = transform.Value.GetRotationQuaternion(); matrix3D = transform.Value; } using (var ms = new MemoryStream(mesh)) { using (var br = new BinaryReader(ms)) { // ReSharper disable once UnusedVariable var version = br.ReadByte(); //stream format version var numVertices = br.ReadInt32(); var numTriangles = br.ReadInt32(); var uniqueVertices = new List <XbimPoint3D>(numVertices); var vertices = new List <XbimPoint3D>(numVertices * 4); //approx the size var triangleIndices = new List <int>(numTriangles * 3); var normals = new List <XbimVector3D>(numVertices * 4); for (var i = 0; i < numVertices; i++) { double x = br.ReadSingle(); double y = br.ReadSingle(); double z = br.ReadSingle(); var p = new XbimPoint3D(x, y, z); if (matrix3D.HasValue) { p = matrix3D.Value.Transform(p); } uniqueVertices.Add(p); } var numFaces = br.ReadInt32(); for (var i = 0; i < numFaces; i++) { var numTrianglesInFace = br.ReadInt32(); if (numTrianglesInFace == 0) { continue; } var isPlanar = numTrianglesInFace > 0; numTrianglesInFace = Math.Abs(numTrianglesInFace); if (isPlanar) { var normal = br.ReadPackedNormal().Normal; if (!qrd.IsIdentity()) { var baseVal = new XbimVector3D(normal.X, normal.Y, normal.Z); XbimQuaternion.Transform(ref baseVal, ref qrd, out normal); } var uniqueIndices = new Dictionary <int, int>(); for (var j = 0; j < numTrianglesInFace; j++) { for (var k = 0; k < 3; k++) { var idx = ReadIndex(br, numVertices); int writtenIdx; if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it { writtenIdx = vertices.Count; vertices.Add(uniqueVertices[idx]); uniqueIndices.Add(idx, writtenIdx); //add a matching normal normals.Add(normal); } triangleIndices.Add(indexBase + writtenIdx); } } } else { var uniqueIndices = new Dictionary <int, int>(); for (var j = 0; j < numTrianglesInFace; j++) { for (var k = 0; k < 3; k++) { var idx = ReadIndex(br, numVertices); var normal = br.ReadPackedNormal().Normal; int writtenIdx; if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it { writtenIdx = vertices.Count; vertices.Add(uniqueVertices[idx]); uniqueIndices.Add(idx, writtenIdx); if (!qrd.IsIdentity()) { var baseVal = new XbimVector3D(normal.X, normal.Y, normal.Z); XbimQuaternion.Transform(ref baseVal, ref qrd, out normal); } normals.Add(normal); } triangleIndices.Add(indexBase + writtenIdx); } } } } m3D.Positions = m3D.Positions.Concat(vertices).ToList(); m3D.TriangleIndices = m3D.TriangleIndices.Concat(triangleIndices).ToList(); m3D.Normals = m3D.Normals.Concat(normals).ToList(); } } }