コード例 #1
0
        protected HexMapMesh(GraphicsDevice gd, List <Hexagon> hexes, IGeometryBuilder builder, Texture2D texture)
        {
            Interlocked.Increment(ref meshCounter);
            Texture       = texture;
            Hexes         = hexes;
            PatchID       = meshCounter;
            Vertices      = new List <VertexPositionNormalTexture>();
            Indices       = new List <uint>();
            TriangleCount = hexes.Count * 6;
            HexSize       = hexes[0].Geometry.HexWidth;
            foreach (var hexagon in hexes)
            {
                hexagon.PatchID = PatchID;
            }

            builder.BuildGeometry(hexes, Vertices, Indices);

            BoundingBox = hexes[0].Geometry.BoundingBox;
            foreach (var hexagon in hexes.Skip(1))
            {
                BoundingBox = BoundingBox.CreateMerged(BoundingBox, hexagon.Geometry.BoundingBox);
            }

            VertexBuffer = new VertexBuffer(gd, typeof(VertexPositionNormalTexture), Vertices.Count, BufferUsage.WriteOnly);
            var vpcs = Vertices.ToArray();

            builder.GenerateNormals(vpcs, Indices);
            VertexBuffer.SetData(vpcs);
            IndexBuffer = new IndexBuffer(gd, IndexElementSize.ThirtyTwoBits, Indices.Count, BufferUsage.WriteOnly);
            IndexBuffer.SetData(Indices.ToArray());
            Grid = new HexGrid(gd, Hexes, Color.Gray);
        }
コード例 #2
0
ファイル: Cone.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, int tessellation)
        {
            Vector3 offset = new Vector3(0, -0.25f, 0);

            builder.AddVertex(Vector3.UnitY + offset, Vector3.UnitY);
            builder.AddVertex(Vector3.Zero + offset, -Vector3.UnitY);

            for (int i = 0; i < tessellation; ++i)
            {
                float angle = i * Algorithms.Helpers.TwoPi / tessellation;

                float dx = MathF.Cos(angle);
                float dz = MathF.Sin(angle);

                Vector3 normal = new Vector3(dx, 0, dz);

                builder.AddVertex(normal + offset, normal);

                builder.AddIndex(0);
                builder.AddIndex(2 + i);
                builder.AddIndex(2 + (i + 1) % tessellation);

                builder.AddIndex(1);
                builder.AddIndex(2 + (i + 1) % tessellation);
                builder.AddIndex(2 + i);
            }
        }
コード例 #3
0
        private void OnGUI()
        {
            GUILayout.BeginVertical();

            GUILayout.BeginHorizontal();
            GUILayout.Label("Primitive");
            var index = Mathf.Max(EditorGUILayout.Popup(_selectedBuilderIndex, _builderNames.ToArray()), 0);

            GUILayout.EndHorizontal();

            if (index >= 0 && _renderers.Count > index)
            {
                if (index != _selectedBuilderIndex || null == _renderer)
                {
                    _settings = (GeometryBuilderSettings)GeometryProvider.Factories[index].Invoke(null, null);

                    _renderer = _renderers[index];
                    _builder  = GeometryProvider.Builders[index];

                    _settings.Name        = Name(_builder);
                    _settings.Description = Description(_builder);
                }

                _renderer.Draw(_settings);

                _selectedBuilderIndex = index;
            }

            GUILayout.EndVertical();
        }
コード例 #4
0
        private static IGeometryBuilderRenderer Renderer(IGeometryBuilder builder)
        {
            var builderType   = builder.GetType();
            var rendererTypes = typeof(IGeometryBuilderRenderer).Implementors();

            foreach (var rendererType in rendererTypes)
            {
                var customRenderer = rendererType.Attribute <CustomRenderer>();
                if (null == customRenderer)
                {
                    continue;
                }

                if (customRenderer.Type == builderType)
                {
                    try
                    {
                        var customRendererInstance = (IGeometryBuilderRenderer)Activator.CreateInstance(rendererType);
                        return(customRendererInstance);
                    }
                    catch
                    {
                        Debug.LogError(string.Format(
                                           "Could not instantiate custom IGeometryBuilderRenderer {0}. Does it have a public default constructor?",
                                           rendererType));
                        break;
                    }
                }
            }

            return(new StandardGeometryBuilderRenderer());
        }
コード例 #5
0
        private void _ReadGeometry(JsonReader reader, IGeometryBuilder builder, GeometryType type)
        {
            switch (type)
            {
            case GeometryType.GeometryCollection:
            case GeometryType.MultiLineString:
            //case GeometryType.MultiPoint:
            case GeometryType.MultiPolygon:
            case GeometryType.Polygon:
                if (reader.TokenType != JsonToken.StartArray)
                {
                    throw new JsonReaderException(SR.InvalidGeoJsonLineInfoException);
                }
                if (!reader.Read())
                {
                    _ThrowGeoJsonException(reader, null);
                }
                break;
            }
            builder.BeginGeometry(type);

            switch (type)
            {
            case GeometryType.MultiPolygon:
                do
                {
                    _ReadGeometry(reader, builder, GeometryType.Polygon);
                } while ((reader.TokenType != JsonToken.EndArray) && (reader.TokenType != JsonToken.EndObject));
                break;

            default:
                do
                {
                    _ReadFigure(reader, builder, type);
                } while ((reader.TokenType != JsonToken.EndArray) && (reader.TokenType != JsonToken.EndObject));
                break;
            }

            switch (type)
            {
            case GeometryType.GeometryCollection:
            case GeometryType.MultiLineString:
            //case GeometryType.MultiPoint:
            case GeometryType.MultiPolygon:
            case GeometryType.Polygon:
                if (reader.TokenType != JsonToken.EndArray)
                {
                    _ThrowGeoJsonException(reader, JsonToken.EndArray);
                }
                if (!reader.Read())
                {
                    _ThrowGeoJsonException(reader, null);
                }
                break;
            }
            builder.EndGeometry();
        }
コード例 #6
0
        private static string Description(IGeometryBuilder builder)
        {
            var builderType = builder.GetType();
            var customName  = builderType.Attribute <DescriptionAttribute>();

            if (null != customName)
            {
                return(customName.Description);
            }

            return("[No description]");
        }
コード例 #7
0
        private static string Name(IGeometryBuilder builder)
        {
            var builderType = builder.GetType();
            var customName  = builderType.Attribute <DisplayNameAttribute>();

            if (null != customName)
            {
                return(customName.DisplayName);
            }

            return(builderType.Name);
        }
コード例 #8
0
        private void _ReadFigure(JsonReader reader, IGeometryBuilder builder, GeometryType type)
        {
            if (type != GeometryType.Point)
            {
                if (reader.TokenType != JsonToken.StartArray)
                {
                    _ThrowGeoJsonException(reader, JsonToken.StartArray);
                }
                if (!reader.Read() || (reader.TokenType != JsonToken.StartArray))
                {
                    _ThrowGeoJsonException(reader, JsonToken.StartArray);
                }
            }

            bool first = true;

            do
            {
                if (!reader.Read())
                {
                    _ThrowGeoJsonException(reader, null);
                }

                var p = _ReadPoint(reader);
                if (first)
                {
                    builder.BeginFigure(p.X, p.Y, p.Z);
                    first = false;
                }
                else
                {
                    builder.AddLine(p.X, p.Y, p.Z);
                }
            } while (reader.TokenType == JsonToken.StartArray);

            if (type != GeometryType.Point)
            {
                if (reader.TokenType != JsonToken.EndArray)
                {
                    _ThrowGeoJsonException(reader, JsonToken.EndArray);
                }
                if (!reader.Read())
                {
                    _ThrowGeoJsonException(reader, null);
                }
            }

            builder.EndFigure();
        }
コード例 #9
0
        /// <summary>
        /// Retrieves a factory.
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="factories"></param>
        /// <returns></returns>
        private static MethodInfo Factory(
            IGeometryBuilder builder,
            MethodInfo[] factories)
        {
            foreach (var method in factories)
            {
                var attribute = method.Attribute <CustomFactory>();
                if (null != attribute && attribute.Type == builder.GetType())
                {
                    return(method);
                }
            }

            return(typeof(GeometryProvider).GetMethod(
                       "DefaultFactory",
                       BindingFlags.Static | BindingFlags.NonPublic));
        }
コード例 #10
0
ファイル: Torus.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, int tessellation)
        {
            // First we loop around the main ring of the torus.
            for (int i = 0; i < tessellation; ++i)
            {
                float outerAngle = i * Algorithms.Helpers.TwoPi / tessellation;

                // Create a transform matrix that will align geometry to
                // slice perpendicularly though the current ring position.
                var transform = Matrix4x4.CreateTranslation(1, 0, 0) *
                                Matrix4x4.CreateRotationY(outerAngle);

                // Now we loop along the other axis, around the side of the tube.
                for (int j = 0; j < tessellation; j++)
                {
                    float innerAngle = j * Algorithms.Helpers.TwoPi / tessellation;

                    float dx = MathF.Cos(innerAngle);
                    float dy = MathF.Sin(innerAngle);

                    // Create a vertex.
                    Vector3 normal   = new Vector3(dx, dy, 0);
                    Vector3 position = normal / 2.0f;

                    position = Vector3.Transform(position, transform);
                    normal   = Vector3.TransformNormal(normal, transform);

                    builder.AddVertex(position, normal);

                    // And create indices for two triangles.
                    int nextI = (i + 1) % tessellation;
                    int nextJ = (j + 1) % tessellation;

                    builder.AddIndex(i * tessellation + j);
                    builder.AddIndex(i * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + j);

                    builder.AddIndex(i * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + nextJ);
                    builder.AddIndex(nextI * tessellation + j);
                }
            }
        }
コード例 #11
0
        /// <summary>Parses the geometry defined by the specified WKT representation, in the specified coordinate system.</summary>
        /// <param name="text">The WKT representation of the geometry.</param>
        /// <param name="system">The coordinate system of the WKT representation.</param>
        public void Parse(string text, ICoordinateSystem system)
        {
            Debug.Assert(system != null);
            if (system == null)
            {
                throw new ArgumentNullException("system");
            }

            IGeometryBuilder builder = CreateBuilder(system);

            builder.Parse(text, system);
            IGeometry g = (IGeometry)builder.ConstructedGeometry;

            if ((TargetSystem != null) && !system.IsEquivalentTo(TargetSystem))
            {
                g.Populate(this);
            }
            else
            {
                _Geometry = g;
            }
        }
コード例 #12
0
ファイル: Cube.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, Vector3 size)
        {
            for (int i = 0; i < normals.Length; i++)
            {
                var normal = normals[i];

                Vector3 side1 = new Vector3(normal.Y, normal.Z, normal.X);
                Vector3 side2 = Vector3.Cross(normal, side1);

                builder.AddIndex(builder.CurrentVertex + 0);
                builder.AddIndex(builder.CurrentVertex + 1);
                builder.AddIndex(builder.CurrentVertex + 2);

                builder.AddIndex(builder.CurrentVertex + 0);
                builder.AddIndex(builder.CurrentVertex + 2);
                builder.AddIndex(builder.CurrentVertex + 3);

                builder.AddVertex(((normal - side1 - side2) / 2.0f) * size, normal, Vector2.Zero);
                builder.AddVertex(((normal - side1 + side2) / 2.0f) * size, normal, Vector2.UnitX);
                builder.AddVertex(((normal + side1 + side2) / 2.0f) * size, normal, Vector2.One);
                builder.AddVertex(((normal + side1 - side2) / 2.0f) * size, normal, Vector2.UnitY);
            }
        }
コード例 #13
0
        public static void CreateSolid(this IGeometryBuilder builder, Vector3 start, Vector3 end, float radius, int tessellation)
        {
            builder.AddVertex(start * 0.5f, start);
            builder.AddVertex(-end * 0.5f, -end);

            float diameter = radius / 2.0f;

            for (int i = 0; i < tessellation; ++i)
            {
                float angle = i * Algorithms.Helpers.TwoPi / tessellation;

                float dx = MathF.Cos(angle);
                float dz = MathF.Sin(angle);

                Vector3 normal = new Vector3(dx, 0.0f, dz);

                builder.AddVertex(normal + (diameter * start), normal);
                builder.AddVertex(normal - (diameter * start), normal);

                builder.AddIndex(0);
                builder.AddIndex(2 + (i * 2));
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));

                builder.AddIndex(2 + (i * 2));
                builder.AddIndex(2 + (i * 2) + 1);
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));

                builder.AddIndex(1);
                builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2)));
                builder.AddIndex(2 + (i * 2) + 1);

                builder.AddIndex(2 + (i * 2) + 1);
                builder.AddIndex(2 + (((i * 2) + 3) % (tessellation * 2)));
                builder.AddIndex(2 + (((i * 2) + 2) % (tessellation * 2)));
            }
        }
コード例 #14
0
 public static void CreateSolid(this IGeometryBuilder builder, float radius, int tessellation)
 => CreateSolid(builder, Vector3.UnitY, -Vector3.UnitY, radius, tessellation);
コード例 #15
0
        /// <summary>
        /// Builds geometry.
        /// </summary>
        /// <param name="mesh"></param>
        /// <param name="builder"></param>
        /// <param name="settings"></param>
        public static void Build(
            Mesh mesh,
            IGeometryBuilder builder,
            GeometryBuilderSettings settings)
        {
            if (null == mesh || null == builder || null == settings)
            {
                return;
            }

            // begin flow
            builder.Start(mesh, settings);

            // create buffers
            int[]     triangles = null;
            Vector3[] vertices  = null;
            Vector2[] uvs       = null;
            Vector2[] uv1s      = null;
            Vector2[] uv2s      = null;
            Vector3[] normals   = null;
            Color[]   colors    = null;

            // must always have a layout
            builder.Layout(out vertices, out triangles);
            settings.Vertex.Transform(ref vertices, ref triangles);

            // fill other buffers
            if (settings.UV.Enabled)
            {
                builder.UV(out uvs, settings.UV);
                settings.UV.Transform(ref uvs);
            }

            if (settings.UV1.Enabled)
            {
                builder.UV(out uv1s, settings.UV1);
                settings.UV1.Transform(ref uv1s);
            }

            if (settings.UV2.Enabled)
            {
                builder.UV(out uv2s, settings.UV2);
                settings.UV2.Transform(ref uv2s);
            }

            if (settings.Color.Enabled)
            {
                builder.Colors(out colors);
                settings.Color.Transform(ref colors);
            }

            if (settings.Normals.Enabled)
            {
                builder.Normals(out normals);
                settings.Normals.Transform(ref normals);
            }

            // set buffers, layout first
            mesh.SetLayout(ref vertices, ref triangles);
            mesh.uv      = uvs;
            mesh.uv2     = uv1s;
            mesh.uv2     = uv2s;
            mesh.colors  = colors;
            mesh.normals = normals;
        }
コード例 #16
0
 public static void CreateSolid(this IGeometryBuilder builder, float radius)
 => CreateSolid(builder, Vector3.UnitY, -Vector3.UnitY, radius, 32);
コード例 #17
0
        private void _ReadFigure(JsonReader reader, IGeometryBuilder builder, GeometryType type)
        {
            if (type!=GeometryType.Point)
            {
                if (reader.TokenType!=JsonToken.StartArray)
                    _ThrowGeoJsonException(reader, JsonToken.StartArray);
                if (!reader.Read() || (reader.TokenType!=JsonToken.StartArray))
                    _ThrowGeoJsonException(reader, JsonToken.StartArray);
            }

            bool first=true;
            do
            {
                if (!reader.Read())
                    _ThrowGeoJsonException(reader, null);

                var p=_ReadPoint(reader);
                if (first)
                {
                    builder.BeginFigure(p.X, p.Y, p.Z);
                    first=false;
                } else
                    builder.AddLine(p.X, p.Y, p.Z);
            } while (reader.TokenType==JsonToken.StartArray);

            if (type!=GeometryType.Point)
            {
                if (reader.TokenType!=JsonToken.EndArray)
                    _ThrowGeoJsonException(reader, JsonToken.EndArray);
                if (!reader.Read())
                    _ThrowGeoJsonException(reader, null);
            }

            builder.EndFigure();
        }
コード例 #18
0
        private void _ReadGeometry(JsonReader reader, IGeometryBuilder builder, GeometryType type)
        {
            switch (type)
            {
            case GeometryType.GeometryCollection:
            case GeometryType.MultiLineString:
            //case GeometryType.MultiPoint:
            case GeometryType.MultiPolygon:
            case GeometryType.Polygon:
                if (reader.TokenType!=JsonToken.StartArray)
                    throw new JsonReaderException(SR.InvalidGeoJsonLineInfoException);
                if (!reader.Read())
                    _ThrowGeoJsonException(reader, null);
                break;
            }
            builder.BeginGeometry(type);

            switch (type)
            {
            case GeometryType.MultiPolygon:
                do
                {
                    _ReadGeometry(reader, builder, GeometryType.Polygon);
                } while ((reader.TokenType!=JsonToken.EndArray) && (reader.TokenType!=JsonToken.EndObject));
                break;
            default:
                do
                {
                    _ReadFigure(reader, builder, type);
                } while ((reader.TokenType!=JsonToken.EndArray) && (reader.TokenType!=JsonToken.EndObject));
                break;
            }

            switch (type)
            {
            case GeometryType.GeometryCollection:
            case GeometryType.MultiLineString:
            //case GeometryType.MultiPoint:
            case GeometryType.MultiPolygon:
            case GeometryType.Polygon:
                if (reader.TokenType!=JsonToken.EndArray)
                    _ThrowGeoJsonException(reader, JsonToken.EndArray);
                if (!reader.Read())
                _ThrowGeoJsonException(reader, null);
                break;
            }
            builder.EndGeometry();
        }
コード例 #19
0
ファイル: Sphere.cs プロジェクト: erictuvesson/CSG
 public static void CreateSolid(this IGeometryBuilder builder)
 => CreateSolid(builder, 1.0f, 12);
コード例 #20
0
ファイル: Sphere.cs プロジェクト: erictuvesson/CSG
        public static void CreateSolid(this IGeometryBuilder builder, float radius, int tessellation)
        {
            int verticalSegments   = tessellation;
            int horizontalSegments = tessellation * 2;

            // Start with a single vertex at the bottom of the sphere.
            builder.AddVertex(Vector3.UnitY, -Vector3.UnitY);

            // Create rings of vertices at progressively higher latitudes.
            for (int i = 0; i < verticalSegments - 1; ++i)
            {
                float latitude = ((i + 1.0f) * Algorithms.Helpers.Pi / verticalSegments) - Algorithms.Helpers.PiOver2;

                float dy  = MathF.Sin(latitude);
                float dxz = MathF.Cos(latitude);

                // Create a single ring of vertices at this latitude.
                for (int j = 0; j < horizontalSegments; j++)
                {
                    float longitude = j * Algorithms.Helpers.TwoPi / horizontalSegments;

                    float dx = MathF.Cos(longitude) * dxz;
                    float dz = MathF.Sin(longitude) * dxz;

                    Vector3 normal = new Vector3(dx, dy, dz) * radius;

                    builder.AddVertex(normal, normal);
                }
            }

            // Finish with a single vertex at the top of the sphere.
            builder.AddVertex(Vector3.UnitY, Vector3.UnitY);

            // Create a fan connecting the bottom vertex to the bottom latitude ring.
            for (int i = 0; i < horizontalSegments; ++i)
            {
                builder.AddIndex(0);
                builder.AddIndex(1 + ((i + 1) % horizontalSegments));
                builder.AddIndex(1 + i);
            }

            // Fill the sphere body with triangles joining each pair of latitude rings.
            for (int i = 0; i < verticalSegments - 2; ++i)
            {
                for (int j = 0; j < horizontalSegments; j++)
                {
                    int nextI = i + 1;
                    int nextJ = (j + 1) % horizontalSegments;

                    builder.AddIndex(1 + (i * horizontalSegments) + j);
                    builder.AddIndex(1 + (i * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + j);

                    builder.AddIndex(1 + (i * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + nextJ);
                    builder.AddIndex(1 + (nextI * horizontalSegments) + j);
                }
            }

            // Create a fan connecting the top vertex to the top latitude ring.
            for (int i = 0; i < horizontalSegments; ++i)
            {
                builder.AddIndex(builder.CurrentVertex - 1);
                builder.AddIndex(builder.CurrentVertex - 2 - ((i + 1) % horizontalSegments));
                builder.AddIndex(builder.CurrentVertex - 2 - i);
            }
        }
コード例 #21
0
ファイル: Sphere.cs プロジェクト: erictuvesson/CSG
 public static void CreateSolid(this IGeometryBuilder builder, float radius)
 => CreateSolid(builder, radius, 12);
コード例 #22
0
        public void BuildGeometry(IGeometryBuilder geometryBuilder)
        {
            // An icosahedron can be created from the vertices of three intersecting golden rectangles.
            // https://en.wikipedia.org/wiki/Golden_rectangle
            List <Vector3> v = new List <Vector3>();

            const float goldenRatio = 1.6180339887498948482045868343656f;

            // plane with z = 0
            v.Add(new Vector3(-1, -goldenRatio, 0));
            v.Add(new Vector3(1, -goldenRatio, 0));
            v.Add(new Vector3(1, goldenRatio, 0));
            v.Add(new Vector3(-1, goldenRatio, 0));

            // plane with y = 0
            v.Add(new Vector3(-goldenRatio, 0, -1));
            v.Add(new Vector3(goldenRatio, 0, -1));
            v.Add(new Vector3(goldenRatio, 0, 1));
            v.Add(new Vector3(-goldenRatio, 0, 1));

            // plane with x = 0
            v.Add(new Vector3(0, -1, -goldenRatio));
            v.Add(new Vector3(0, 1, -goldenRatio));
            v.Add(new Vector3(0, 1, goldenRatio));
            v.Add(new Vector3(0, -1, goldenRatio));

            // Normalize them so the points sit on the unit sphere
            for (int i = 0; i < v.Count; i++)
            {
                v[i].Normalize();
            }

            int[] vertexIndices = new[] {
                1, 6, 10, 2,
                13, 3, 2, 10,
                11, 7, 3, 10,
                19, 11, 10, 6,
                9, 7, 10, 11,

                3, 1, 11, 6,
                17, 1, 6, 5,
                7, 5, 6, 2,

                15, 9, 5, 2,
                5, 9, 2, 3,

                16, 11, 1, 0,
                8, 1, 8, 0,
                10, 5, 8, 1,

                2, 9, 4, 8,
                18, 3, 4, 9,
                4, 3, 7, 4,

                6, 11, 0, 7,
                12, 5, 9, 8,
                20, 4, 0, 8,
                14, 7, 0, 4,

                000000000
            };

            for (int i = 0; i < 20; i++)
            {
                int startIndex = 4 * i;

                geometryBuilder.AddTriangle(vertexIndices[startIndex] - 1,
                                            v[vertexIndices[startIndex + 1]],
                                            v[vertexIndices[startIndex + 2]],
                                            v[vertexIndices[startIndex + 3]]);
            }
        }