Ejemplo n.º 1
0
        private void BuildCarRoads(Rule rule, TerrainMeshData meshData, MeshCell cell, RenderMode renderMode)
        {
            var   meshRegion     = cell.CarRoads;
            var   isScene        = renderMode == RenderMode.Scene;
            float eleNoiseFreq   = rule.GetCarLayerEleNoiseFreq();
            float colorNoiseFreq = isScene ? rule.GetCarLayerColorNoiseFreq() : 0;
            float roadOffset     = 0.3f;

            if (meshRegion.Mesh == null)
            {
                return;
            }
            var gradient = rule.GetCarLayerGradient(_customizationService);

            foreach (var triangle in meshRegion.Mesh.Triangles)
            {
                AddTriangle(rule, meshData, triangle, gradient, eleNoiseFreq, colorNoiseFreq, -roadOffset);
            }

            if (isScene)
            {
                BuildOffsetShape(meshData, meshRegion, rule.GetBackgroundLayerGradient(_customizationService),
                                 cell.Rectangle, colorNoiseFreq, roadOffset);
            }

            meshRegion.Dispose();
        }
Ejemplo n.º 2
0
        private void BuildObject(IGameObject goWrapper, Canvas canvas, Rule rule, TerrainMeshData meshData,
                                 Vector3[] vertices, int[] triangles, Color[] colors)
        {
            var gameObject = goWrapper.GetComponent <GameObject>();

            gameObject.isStatic = true;

            var mesh = new Mesh();

            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.colors    = colors;
            mesh.RecalculateNormals();

            gameObject.AddComponent <MeshRenderer>().sharedMaterial = rule
                                                                      .GetMaterial("material_background", _customizationService);
            gameObject.AddComponent <MeshFilter>().mesh = mesh;
            gameObject.AddComponent <MeshCollider>();

            gameObject.AddComponent <MeshIndexBehaviour>().Index = meshData.Index;
            meshData.Dispose();

            var behaviourTypes = rule.GetModelBehaviours(_customizationService);

            foreach (var behaviourType in behaviourTypes)
            {
                var behaviour = gameObject.AddComponent(behaviourType) as IModelBehaviour;
                if (behaviour != null)
                {
                    behaviour.Apply(goWrapper, canvas);
                }
            }
        }
Ejemplo n.º 3
0
        private void BuildCell(Canvas canvas, Rule rule, IGameObject terrainObject, MeshCell cell,
                               RenderMode renderMode, string name)
        {
            var cellGameObject = _gameObjectFactory.CreateNew(name, terrainObject);

            var meshData = new TerrainMeshData(_objectPool);

            meshData.GameObject = cellGameObject;
            meshData.Index      = renderMode == RenderMode.Scene
                ? new TerrainMeshIndex(16, 16, cell.Rectangle, meshData.Triangles)
                : (IMeshIndex)DummyMeshIndex.Default;

            // build canvas and extra layers
            BuildBackground(rule, meshData, cell.Background, renderMode);
            BuildWater(rule, meshData, cell, renderMode);
            BuildCarRoads(rule, meshData, cell, renderMode);
            BuildPedestrianLayers(rule, meshData, cell, renderMode);
            foreach (var surfaceRegion in cell.Surfaces)
            {
                BuildSurface(rule, meshData, surfaceRegion, renderMode);
            }

            Trace.Debug(LogTag, "Total triangles: {0}", meshData.Triangles.Count.ToString());

            meshData.Index.Build();

            BuildObject(cellGameObject, canvas, rule, meshData);
        }
Ejemplo n.º 4
0
        /// <summary> Builds real game object. </summary>
        protected virtual void BuildObject(IGameObject cellGameObject, Canvas canvas, Rule rule,
                                           TerrainMeshData meshData)
        {
            Vector3[] vertices;
            int[]     triangles;
            Color[]   colors;
            meshData.GenerateObjectData(out vertices, out triangles, out colors);

            Observable.Start(() => BuildObject(cellGameObject, canvas, rule,
                                               meshData, vertices, triangles, colors), Scheduler.MainThread);
        }
Ejemplo n.º 5
0
        private void AddTriangle(Rule rule, TerrainMeshData meshData, Triangle triangle, GradientWrapper gradient,
                                 float eleNoiseFreq, float colorNoiseFreq, float yOffset = 0)
        {
            var useEleNoise = Math.Abs(eleNoiseFreq) > 0.0001;

            var v0 = GetVertex(triangle.GetVertex(0), eleNoiseFreq, useEleNoise, yOffset);
            var v1 = GetVertex(triangle.GetVertex(1), eleNoiseFreq, useEleNoise, yOffset);
            var v2 = GetVertex(triangle.GetVertex(2), eleNoiseFreq, useEleNoise, yOffset);

            var triangleColor = GradientUtils.GetColor(gradient, v0, colorNoiseFreq);

            meshData.AddTriangle(v0, v1, v2, triangleColor);
        }
Ejemplo n.º 6
0
        private void BuildWaterObject(Rule rule, TerrainMeshData meshData, Vector3[] vertices, int[] triangles, Color[] colors)
        {
            var gameObject = new GameObject("water");

            gameObject.transform.parent = meshData.GameObject.GetComponent <GameObject>().transform;
            var mesh = new Mesh();

            mesh.vertices  = vertices;
            mesh.triangles = triangles;
            mesh.colors    = colors;
            mesh.RecalculateNormals();

            gameObject.AddComponent <MeshRenderer>().sharedMaterial =
                rule.GetMaterial("material_water", _customizationService);
            gameObject.AddComponent <MeshFilter>().mesh = mesh;
        }
Ejemplo n.º 7
0
        private void BuildBackground(Rule rule, TerrainMeshData meshData, MeshRegion meshRegion, RenderMode renderMode)
        {
            if (meshRegion.Mesh == null)
            {
                return;
            }
            var gradient = rule.GetBackgroundLayerGradient(_customizationService);

            float eleNoiseFreq   = rule.GetBackgroundLayerEleNoiseFreq();
            float colorNoiseFreq = renderMode == RenderMode.Scene ? rule.GetBackgroundLayerColorNoiseFreq() : 0;

            foreach (var triangle in meshRegion.Mesh.Triangles)
            {
                AddTriangle(rule, meshData, triangle, gradient, eleNoiseFreq, colorNoiseFreq);
            }

            meshRegion.Dispose();
        }
Ejemplo n.º 8
0
        private void BuildPedestrianLayers(Rule rule, TerrainMeshData meshData, MeshCell cell, RenderMode renderMode)
        {
            var meshRegion = cell.WalkRoads;

            if (meshRegion.Mesh == null)
            {
                return;
            }
            var   gradient       = rule.GetPedestrianLayerGradient(_customizationService);
            float eleNoiseFreq   = rule.GetPedestrianLayerEleNoiseFreq();
            float colorNoiseFreq = renderMode == RenderMode.Scene ? rule.GetPedestrianLayerColorNoiseFreq() : 0;

            foreach (var triangle in meshRegion.Mesh.Triangles)
            {
                AddTriangle(rule, meshData, triangle, gradient, eleNoiseFreq, colorNoiseFreq);
            }

            meshRegion.Dispose();
        }
Ejemplo n.º 9
0
        private void BuildOffsetShape(TerrainMeshData meshData, MeshRegion region, GradientWrapper gradient,
                                      Rectangle2d rect, float colorNoiseFreq, float deepLevel)
        {
            foreach (var contour in region.Contours)
            {
                var length = contour.Count;
                for (int i = 0; i < length; i++)
                {
                    var v2DIndex = i == (length - 1) ? 0 : i + 1;
                    var p1       = new Vector2d((float)contour[i].X, (float)contour[i].Y);
                    var p2       = new Vector2d((float)contour[v2DIndex].X, (float)contour[v2DIndex].Y);

                    // check whether two points are on cell rect
                    if (rect.IsOnBorder(p1) && rect.IsOnBorder(p2))
                    {
                        continue;
                    }

                    var ele1 = _elevationProvider.GetElevation(p1);
                    var ele2 = _elevationProvider.GetElevation(p2);

                    var firstColor = GradientUtils.GetColor(gradient,
                                                            new Vector3((float)p1.X, ele1, (float)p1.Y), colorNoiseFreq);

                    var secondColor = GradientUtils.GetColor(gradient,
                                                             new Vector3((float)p2.X, ele1 - deepLevel, (float)p2.Y), colorNoiseFreq);

                    meshData.AddTriangle(
                        new Vector3((float)p1.X, ele1, (float)p1.Y),
                        new Vector3((float)p2.X, ele2 - deepLevel, (float)p2.Y),
                        new Vector3((float)p2.X, ele2, (float)p2.Y),
                        firstColor);

                    meshData.AddTriangle(
                        new Vector3((float)p1.X, ele1 - deepLevel, (float)p1.Y),
                        new Vector3((float)p2.X, ele2 - deepLevel, (float)p2.Y),
                        new Vector3((float)p1.X, ele1, (float)p1.Y),
                        secondColor);
                }
            }
        }
Ejemplo n.º 10
0
        private void BuildSurface(Rule rule, TerrainMeshData meshData, MeshRegion meshRegion, RenderMode renderMode)
        {
            if (meshRegion.Mesh == null)
            {
                return;
            }

            float colorNoiseFreq = renderMode == RenderMode.Scene ? meshRegion.ColorNoiseFreq : 0;
            float eleNoiseFreq   = renderMode == RenderMode.Scene ? meshRegion.ElevationNoiseFreq : 0;
            var   gradient       = _customizationService.GetGradient(meshRegion.GradientKey);

            if (meshRegion.ModifyMeshAction != null)
            {
                meshRegion.ModifyMeshAction(meshRegion.Mesh);
            }

            foreach (var triangle in meshRegion.Mesh.Triangles)
            {
                AddTriangle(rule, meshData, triangle, gradient, eleNoiseFreq, colorNoiseFreq);
            }

            meshRegion.Dispose();
        }
Ejemplo n.º 11
0
        private void BuildWater(Rule rule, TerrainMeshData meshData, MeshCell cell, RenderMode renderMode)
        {
            var meshRegion = cell.Water;

            if (meshRegion.Mesh == null)
            {
                return;
            }

            float colorNoiseFreq = renderMode == RenderMode.Scene
                ? rule.GetWaterLayerColorNoiseFreq() : 0;
            float eleNoiseFreq = rule.GetWaterLayerEleNoiseFreq();

            var meshTriangles = meshData.Triangles;

            var bottomGradient          = rule.GetBackgroundLayerGradient(_customizationService);
            var waterSurfaceGradient    = rule.GetWaterLayerGradient(_customizationService);
            var waterBottomLevelOffset  = rule.GetWaterLayerBottomLevel();
            var waterSurfaceLevelOffset = rule.GetWaterLayerSurfaceLevel();

            var elevationOffset = waterBottomLevelOffset - waterSurfaceLevelOffset;
            var surfaceOffset   = renderMode == RenderMode.Scene ? -waterBottomLevelOffset : 0;

            // NOTE: substitute gradient in overview mode
            if (renderMode == RenderMode.Overview)
            {
                bottomGradient = waterSurfaceGradient;
            }

            int index          = 0;
            var vertexCount    = meshRegion.Mesh.Triangles.Count * 3;
            var waterVertices  = new Vector3[vertexCount];
            var waterTriangles = new int[vertexCount];
            var waterColors    = new Color[vertexCount];

            foreach (var triangle in meshRegion.Mesh.Triangles)
            {
                // bottom surface
                AddTriangle(rule, meshData, triangle, bottomGradient, eleNoiseFreq, colorNoiseFreq, surfaceOffset);

                // NOTE: build offset shape only in case of Scene mode
                if (renderMode == RenderMode.Overview)
                {
                    continue;
                }

                var meshTriangle = meshTriangles[meshTriangles.Count - 1];

                var p0 = meshTriangle.Vertex0;
                var p1 = meshTriangle.Vertex1;
                var p2 = meshTriangle.Vertex2;

                // reuse just added vertices
                waterVertices[index]     = new Vector3(p0.x, p0.y + elevationOffset, p0.z);
                waterVertices[index + 1] = new Vector3(p1.x, p1.y + elevationOffset, p1.z);
                waterVertices[index + 2] = new Vector3(p2.x, p2.y + elevationOffset, p2.z);

                var color = GradientUtils.GetColor(waterSurfaceGradient, waterVertices[index], colorNoiseFreq);
                waterColors[index]     = color;
                waterColors[index + 1] = color;
                waterColors[index + 2] = color;

                waterTriangles[index]     = index;
                waterTriangles[index + 1] = index + 2;
                waterTriangles[index + 2] = index + 1;
                index += 3;
            }

            // finalizing offset shape
            if (renderMode == RenderMode.Scene)
            {
                BuildOffsetShape(meshData, meshRegion, rule.GetBackgroundLayerGradient(_customizationService),
                                 cell.Rectangle, colorNoiseFreq, waterBottomLevelOffset);

                Observable.Start(() => BuildWaterObject(rule, meshData,
                                                        waterVertices, waterTriangles, waterColors), Scheduler.MainThread);
            }
        }