Exemplo n.º 1
0
        /// <summary>
        /// Triangulate this csg and pack the triangulated data into buffers
        /// appropriate for use with gltf.
        /// </summary>
        internal static GraphicsBuffers Tessellate(this Csg.Solid csg)
        {
            var buffers = new GraphicsBuffers();

            ushort iCursor = 0;

            (Vector3 U, Vector3 V)basis;

            const float SEARCH_RADIUS = 0.001f;

            // Setup the octree to fit around the csg.
            // This requires one expensive initialization.
            var verts  = csg.Polygons.SelectMany(p => p.Vertices).Select(v => v.Pos.ToElementsVector()).ToArray();
            var bounds = new BBox3(verts);
            var center = bounds.Center();
            var origin = new Point((float)center.X, (float)center.Y, (float)center.Z);
            var size   = (float)bounds.Max.DistanceTo(bounds.Min);
            var octree = new PointOctree <(Vector3 position, Vector3 normal, ushort index)>(size, origin, SEARCH_RADIUS);

            foreach (var p in csg.Polygons)
            {
                var vertexIndices = new ushort[p.Vertices.Count];

                var a = p.Vertices[0].Pos.ToElementsVector();
                var b = p.Vertices[1].Pos.ToElementsVector();
                var c = p.Vertices[2].Pos.ToElementsVector();
                basis = ComputeBasisAndNormalForTriangle(a, b, c, out Vector3 normal);

                // Anything with 3 vertices is a triangle. Manually
                // tesselate triangles. For everything else, use
                // the tessellator.
                if (p.Vertices.Count > 2 && p.Vertices.Count <= 3)
                {
                    for (var i = 0; i < p.Vertices.Count; i++)
                    {
                        var v = p.Vertices[i];

                        var op = new Point((float)v.Pos.X, (float)v.Pos.Y, (float)v.Pos.Z);
                        var ep = v.Pos.ToElementsVector();
                        if (TryGetExistingVertex(op, ep, octree, normal, SEARCH_RADIUS, out ushort vertexIndex))
                        {
                            vertexIndices[i] = vertexIndex;
                            continue;
                        }

                        vertexIndices[i] = iCursor;
                        iCursor++;

                        var uu = basis.U.Dot(ep);
                        var vv = basis.V.Dot(ep);
                        buffers.AddVertex(ep, normal, new UV(uu, vv));

                        octree.Add((ep, normal, vertexIndices[i]), op);
Exemplo n.º 2
0
        internal static GraphicsBuffers ToGraphicsBuffers(this IList <Vector3> vertices, bool lineLoop)
        {
            var gb = new GraphicsBuffers();

            for (var i = 0; i < vertices.Count; i++)
            {
                var v = vertices[i];
                gb.AddVertex(v, default(Vector3), default(UV), null);

                var write = lineLoop ? (i < vertices.Count - 1) : (i % 2 == 0 && i < vertices.Count - 1);
                if (write)
                {
                    gb.AddIndex((ushort)i);
                    gb.AddIndex((ushort)(i + 1));
                }
            }
            return(gb);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Get all buffers required for rendering.
        /// </summary>
        public GraphicsBuffers GetBuffers()
        {
            var buffers = new GraphicsBuffers();

            for (var i = 0; i < this.Vertices.Count; i++)
            {
                var v = this.Vertices[i];
                buffers.AddVertex(v.Position, v.Normal, v.UV, v.Color);
            }

            for (var i = 0; i < this.Triangles.Count; i++)
            {
                var t = this.Triangles[i];
                buffers.AddIndex((ushort)t.Vertices[0].Index);
                buffers.AddIndex((ushort)t.Vertices[1].Index);
                buffers.AddIndex((ushort)t.Vertices[2].Index);
            }

            return(buffers);
        }