예제 #1
0
        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.");
        }
예제 #2
0
        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();
                }
            }
        }