private void SpawnGrassesOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int grassIndex = -1;
            List <GGrassInstance> grassInstances = new List <GGrassInstance>();
            Vector2 v0          = Vector2.zero;
            Vector2 v1          = Vector2.zero;
            Vector2 v2          = Vector2.zero;
            Vector2 center      = Vector2.zero;
            float   radius      = 0;
            Vector2 pos         = Vector2.zero;
            Vector3 bary        = Vector3.zero;
            float   maskValue   = 0;
            int     sampleCount = Mathf.Clamp(GrassDensity * GrassDensity / 10, 1, 1000);

            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < sampleCount; ++s)
                {
                    grassIndex = GrassPrototypeIndices[Random.Range(0, GrassPrototypeIndices.Count)];
                    pos        = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }

                    GGrassInstance grass = GGrassInstance.Create(grassIndex);
                    grass.Position = new Vector3(pos.x, 0, pos.y);
                    grass.Rotation = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                    grass.Scale    = Vector3.Lerp(MinScale, MaxScale, Random.value);

                    grassInstances.Add(grass);
                }
            }

            t.TerrainData.Foliage.AddGrassInstances(grassInstances);
        }
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Shading.AlbedoMap;
            int           albedoResolution = terrain.TerrainData.Shading.AlbedoMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, albedoResolution);
            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.AlbedoPainterMaterial;
            mat.SetColor("_Color", args.Color);
            mat.SetTexture("_MainTex", bg);
            SetupTextureGrid(terrain, mat);
            mat.SetTexture("_Mask", args.Mask);
            mat.SetFloat("_Opacity", args.Opacity);
            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 :
                args.ActionType == GPainterActionType.Alternative ? 2 : 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            GLivePreviewDrawer.DrawAlbedoLivePreview(terrain, cam, rt, dirtyRect);
#endif
        }
Пример #3
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, heightMapResolution);
            GCommon.CopyToRT(bg, rt);

            Vector3  localSamplePoint = terrain.transform.InverseTransformPoint(args.SamplePoint);
            Material mat = GInternalMaterials.HeightSamplingPainterMaterial;
            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.Mask);
            mat.SetFloat("_Opacity", args.Opacity);
            mat.SetFloat("_TargetGray", Mathf.InverseLerp(0, terrain.TerrainData.Geometry.Height, localSamplePoint.y));
            int pass = 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            GLivePreviewDrawer.DrawGeometryLivePreview(terrain, cam, rt, dirtyRect);
#endif
        }
        private void DrawLivePreview(GStylizedTerrain t, Camera cam)
        {
            if (t.transform.rotation != Quaternion.identity ||
                t.transform.lossyScale != Vector3.one)
            {
                return;
            }
            RenderTexture[] brushes = new RenderTexture[instance.Layers.Count];
            for (int i = 0; i < brushes.Length; ++i)
            {
                brushes[i] = GetPreviewTexture(t, "brush" + i.ToString(), instance.MaskResolution, FilterMode.Bilinear);
            }

            Vector3[] worldPoints = instance.GetQuad();
            Vector2[] uvPoint     = new Vector2[worldPoints.Length];
            for (int i = 0; i < uvPoint.Length; ++i)
            {
                uvPoint[i] = t.WorldPointToUV(worldPoints[i]);
            }
            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvPoint);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Color[] colors = new Color[instance.Layers.Count];
            for (int i = 0; i < colors.Length; ++i)
            {
                colors[i] = instance.Layers[i].VisualizeColor;
            }

            GLivePreviewDrawer.DrawMasksLivePreview(t, cam, brushes, colors, dirtyRect);
        }
Пример #5
0
 private void GetUvPoints(GStylizedTerrain t, Vector3[] worldPoint, Vector2[] uvPoint)
 {
     for (int i = 0; i < uvPoints.Length; ++i)
     {
         uvPoints[i] = t.WorldPointToUV(worldPoints[i]);
     }
 }
        private void DrawLivePreview(GStylizedTerrain t, Camera cam)
        {
            if (t.transform.rotation != Quaternion.identity ||
                t.transform.lossyScale != Vector3.one)
            {
                return;
            }


            //Mesh previewMesh = GGriffinSettings.Instance.GetLivePreviewMesh(t.TerrainData.Geometry.MeshResolution);
            RenderTexture rt = GetPreviewTexture(t);

            instance.GetQuad(worldPoints);
            for (int i = 0; i < normalizedPoints.Length; ++i)
            {
                normalizedPoints[i] = t.WorldPointToUV(worldPoints[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(normalizedPoints);

            if (instance.Channel == GGeometryStamper.GStampChannel.Elevation)
            {
                GLivePreviewDrawer.DrawGeometryLivePreview(t, cam, rt, dirtyRect);
            }
            else if (instance.Channel == GGeometryStamper.GStampChannel.Visibility)
            {
                Matrix4x4 worldToMaskMatrix = Matrix4x4.TRS(
                    worldPoints[0],
                    instance.Rotation,
                    instance.Scale).inverse;
                GLivePreviewDrawer.DrawVisibilityLivePreview(t, cam, rt, dirtyRect, instance.Stamp, worldToMaskMatrix);
            }
        }
Пример #7
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, heightMapResolution);
            GCommon.CopyToRT(bg, rt);

            Texture2D remapTex = GCommon.CreateTextureFromCurve(GTexturePainterCustomParams.Instance.Remap.Curve, 512, 1);
            Material  mat      = GInternalMaterials.RemapPainterMaterial;
            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.Mask);
            mat.SetFloat("_Opacity", args.Opacity);
            mat.SetTexture("_RemapTex", remapTex);
            int pass = 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            GLivePreviewDrawer.DrawGeometryLivePreview(terrain, cam, rt, dirtyRect);

            GUtilities.DestroyObject(remapTex);
#endif
        }
Пример #8
0
        private void DrawCursorProjected(GStylizedTerrain t)
        {
            for (int i = 0; i < normalizedPoints.Length; ++i)
            {
                normalizedPoints[i] = t.WorldPointToUV(worldPoints[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(normalizedPoints);

            GTerrainChunk[] chunks = t.GetChunks();
            for (int i = 0; i < chunks.Length; ++i)
            {
                Rect uvRect = chunks[i].GetUvRange();
                if (!uvRect.Overlaps(dirtyRect))
                {
                    continue;
                }
                Mesh m = chunks[i].MeshFilterComponent.sharedMesh;
                if (m == null)
                {
                    continue;
                }
                Graphics.DrawMeshNow(
                    m,
                    Matrix4x4.TRS(chunks[i].transform.position, chunks[i].transform.rotation, chunks[i].transform.lossyScale));
            }
        }
Пример #9
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg             = terrain.TerrainData.Mask.MaskMap;
            int           maskResolution = terrain.TerrainData.Mask.MaskMapResolution;
            RenderTexture rt             = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, maskResolution);
            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.MaskPainterMaterial;
            mat.SetTexture("_MainTex", bg);
            SetupTextureGrid(terrain, mat);
            mat.SetTexture("_Mask", args.BrushMask);
            mat.SetFloat("_Opacity", args.Opacity);

            GMaskPainterParams param = GTexturePainterCustomParams.Instance.Mask;
            Vector4            channel;
            if (param.Channel == GTextureChannel.R)
            {
                channel = new Vector4(1, 0, 0, 0);
            }
            else if (param.Channel == GTextureChannel.G)
            {
                channel = new Vector4(0, 1, 0, 0);
            }
            else if (param.Channel == GTextureChannel.B)
            {
                channel = new Vector4(0, 0, 1, 0);
            }
            else
            {
                channel = new Vector4(0, 0, 0, 1);
            }
            mat.SetVector("_Channel", channel);

            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 :
                args.ActionType == GPainterActionType.Alternative ? 2 : 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            GLivePreviewDrawer.DrawMask4ChannelsLivePreview(
                terrain, cam,
                rt,
                GCommon.UnitRect);
#endif
        }
Пример #10
0
        public void Paint(GStylizedTerrain terrain, GTexturePainterArgs args)
        {
            if (terrain.TerrainData == null)
            {
                return;
            }
            if (args.MouseEventType == GPainterMouseEventType.Down)
            {
                terrain.ForceLOD(0);
                GGriffinSettings.Instance.IsHidingFoliageOnEditing = true;
            }
            if (args.MouseEventType == GPainterMouseEventType.Up)
            {
                terrain.ForceLOD(-1);
                GGriffinSettings.Instance.IsHidingFoliageOnEditing = false;
                return;
            }

            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(heightMapResolution);

            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.VisibilityPainterMaterial;

            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.Mask);
            mat.SetFloat("_Opacity", args.Opacity);
            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 : 0;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            RenderTexture.active = rt;
            terrain.TerrainData.Geometry.HeightMap.ReadPixels(
                new Rect(0, 0, heightMapResolution, heightMapResolution), 0, 0);
            terrain.TerrainData.Geometry.HeightMap.Apply();
            RenderTexture.active = null;

            terrain.TerrainData.Geometry.SetRegionDirty(dirtyRect);
            terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry);
        }
Пример #11
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }
            Material mat = GInternalMaterials.SplatPainterMaterial;
            mat.SetTexture("_Mask", args.Mask);
            mat.SetFloat("_Opacity", args.Opacity);

            int controlMapResolution = terrain.TerrainData.Shading.SplatControlResolution;
            int controlMapCount      = terrain.TerrainData.Shading.SplatControlMapCount;
            for (int i = 0; i < controlMapCount; ++i)
            {
                Texture2D     splatControl = terrain.TerrainData.Shading.GetSplatControl(i);
                RenderTexture rt           = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, controlMapResolution, i);
                GCommon.CopyToRT(splatControl, rt);

                mat.SetTexture("_MainTex", splatControl);
                if (args.SplatIndex / 4 == i)
                {
                    mat.SetInt("_ChannelIndex", args.SplatIndex % 4);
                }
                else
                {
                    mat.SetInt("_ChannelIndex", -1);
                }
                int pass =
                    args.ActionType == GPainterActionType.Normal ? 0 :
                    args.ActionType == GPainterActionType.Negative ? 1 :
                    args.ActionType == GPainterActionType.Alternative ? 2 : 0;
                GCommon.DrawQuad(rt, uvCorners, mat, pass);
            }

            Texture[] controls = new Texture[controlMapCount];
            for (int i = 0; i < controlMapCount; ++i)
            {
                controls[i] = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, controlMapResolution, i);
            }

            GLivePreviewDrawer.DrawSplatLivePreview(terrain, cam, controls, dirtyRect);
#endif
        }
Пример #12
0
        public void Internal_Apply(GStylizedTerrain t, RenderTexture rt)
        {
            GCommon.CopyToRT(t.TerrainData.Geometry.HeightMap, rt);

            Vector3[] worldCorner = GetQuad();
            Vector2[] uvCorners   = new Vector2[worldCorner.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = t.WorldPointToUV(worldCorner[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Vector3 normalizedPos = t.WorldPointToNormalized(Position);
            float   stampHeight   = GUtilities.InverseLerpUnclamped(0, t.TerrainData.Geometry.Height, Scale.y);

            Material mat = GInternalMaterials.StamperMaterial;

            mat.SetTexture("_HeightMap", t.TerrainData.Geometry.HeightMap);
            mat.SetTexture("_Stamp", Stamp);
            mat.SetTexture("_Falloff", falloffTexture);
            mat.SetInt("_Operation", (int)Operation);
            mat.SetFloat("_LerpFactor", LerpFactor);
            mat.SetFloat("_StampHeight", stampHeight);
            mat.SetFloat("_StampPositionY", normalizedPos.y);
            mat.SetFloat("_Inverse", InverseStamp ? 1 : 0);
            mat.SetFloat("_UseFalloffAsBlendFactor", UseFalloffAsBlendFactor ? 1 : 0);
            mat.SetFloat("_AdditionalMeshResolution", GCommon.SUB_DIV_STEP * AdditionalMeshResolution);
            if (EnableTerrainMask)
            {
                mat.SetTexture("_TerrainMask", t.TerrainData.Mask.MaskMap);
            }
            else
            {
                mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
            }

            int pass = (int)Channel;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);
        }
Пример #13
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, heightMapResolution);
            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.SubDivPainterMaterial;
            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.BrushMask);
            mat.SetFloat("_Opacity", Mathf.Pow(args.Opacity, GTerrainTexturePainter.GEOMETRY_OPACITY_EXPONENT));
            if (args.EnableTerrainMask)
            {
                mat.SetTexture("_TerrainMask", terrain.TerrainData.Mask.MaskMap);
            }
            else
            {
                mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
            }
            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 : 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            Matrix4x4 worldToMaskMatrix = Matrix4x4.TRS(
                args.WorldPointCorners[0],
                Quaternion.Euler(0, args.Rotation, 0),
                args.Radius * 2 * Vector3.one).inverse;

            GLivePreviewDrawer.DrawSubdivLivePreview(terrain, cam, rt, dirtyRect, args.BrushMask, worldToMaskMatrix);
#endif
        }
Пример #14
0
        public void Editor_DrawLivePreview(GStylizedTerrain terrain, GTexturePainterArgs args, Camera cam)
        {
#if UNITY_EDITOR
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, heightMapResolution);
            GCommon.CopyToRT(bg, rt);

            RenderTexture noiseMap = GTerrainTexturePainter.Internal_GetRenderTexture(terrain, heightMapResolution, 1);
            RenderNoiseTexture(noiseMap, terrain);

            Material mat = GInternalMaterials.NoisePainterMaterial;
            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.BrushMask);
            mat.SetFloat("_Opacity", Mathf.Pow(args.Opacity, GTerrainTexturePainter.GEOMETRY_OPACITY_EXPONENT));
            mat.SetTexture("_NoiseMap", noiseMap);
            if (args.EnableTerrainMask)
            {
                mat.SetTexture("_TerrainMask", terrain.TerrainData.Mask.MaskMap);
            }
            else
            {
                mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
            }
            GCommon.SetMaterialKeywordActive(mat, "USE_WORLD_SPACE", GTexturePainterCustomParams.Instance.Noise.UseWorldSpace);
            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 : 0;
            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            GLivePreviewDrawer.DrawGeometryLivePreview(terrain, cam, rt, dirtyRect);
#endif
        }
Пример #15
0
        private void DrawTerrainMeshPreview(GStylizedTerrain t, Camera cam)
        {
            Material mat = t.TerrainData.Shading.MaterialToRender;

            if (mat == null)
            {
                return;
            }

            GTerrainChunk[] chunks = t.GetChunks();
            instance.GetQuad(worldPoints);
            for (int i = 0; i < normalizedPoints.Length; ++i)
            {
                normalizedPoints[i] = t.WorldPointToUV(worldPoints[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(normalizedPoints);

            for (int i = 0; i < chunks.Length; ++i)
            {
                Rect uvRange = chunks[i].GetUvRange();
                if (uvRange.Overlaps(dirtyRect))
                {
                    string chunkMeshName = GTerrainChunk.GetChunkMeshName(chunks[i].Index, 0);
                    Mesh   chunkMesh     = t.TerrainData.GeometryData.GetMesh(chunkMeshName);
                    if (chunkMesh != null)
                    {
                        Graphics.DrawMesh(
                            chunkMesh,
                            chunks[i].transform.localToWorldMatrix,
                            mat,
                            chunks[i].gameObject.layer,
                            cam,
                            0,
                            previewPropertyBlock,
                            t.TerrainData.Rendering.CastShadow,
                            t.TerrainData.Rendering.ReceiveShadow);
                    }
                }
            }
        }
Пример #16
0
        private void DrawLivePreview(GStylizedTerrain t, Camera cam)
        {
            if (t.transform.rotation != Quaternion.identity ||
                t.transform.lossyScale != Vector3.one)
            {
                return;
            }

            instance.GetQuad(worldPoints);
            for (int i = 0; i < normalizedPoints.Length; ++i)
            {
                normalizedPoints[i] = t.WorldPointToUV(worldPoints[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(normalizedPoints);


            if (instance.Channel == GTextureStampChannel.AlbedoMetallicSmoothness)
            {
                int        albedoResolution = t.TerrainData.Shading.AlbedoMapResolution;
                FilterMode albedoFilter     = t.TerrainData.Shading.AlbedoMap.filterMode;

                int        metallicResolution = t.TerrainData.Shading.MetallicMapResolution;
                FilterMode metallicFilter     = t.TerrainData.Shading.MetallicMap.filterMode;

                Texture albedo   = GetPreviewTexture(t, "albedo", albedoResolution, albedoFilter);
                Texture metallic = GetPreviewTexture(t, "metallic", metallicResolution, metallicFilter);
                GLivePreviewDrawer.DrawAMSLivePreview(t, cam, albedo, metallic, dirtyRect);
            }
            else if (instance.Channel == GTextureStampChannel.Splat)
            {
                int       controlMapResolution = t.TerrainData.Shading.SplatControlResolution;
                Texture[] controls             = new Texture[t.TerrainData.Shading.SplatControlMapCount];
                for (int i = 0; i < controls.Length; ++i)
                {
                    Texture currentControl = t.TerrainData.Shading.GetSplatControl(i);
                    controls[i] = GetPreviewTexture(t, "splatControl" + i, controlMapResolution, currentControl.filterMode);
                }
                GLivePreviewDrawer.DrawSplatLivePreview(t, cam, controls, dirtyRect);
            }
        }
        private void UpdatePreview(GStylizedTerrain t)
        {
            RenderTexture[] brushes = new RenderTexture[instance.Layers.Count];
            for (int i = 0; i < brushes.Length; ++i)
            {
                brushes[i] = GetPreviewTexture(t, "brush" + i.ToString(), instance.MaskResolution, FilterMode.Bilinear);
            }

            Vector3[] worldPoints = instance.GetQuad();
            Vector2[] uvPoint     = new Vector2[worldPoints.Length];
            for (int i = 0; i < uvPoint.Length; ++i)
            {
                uvPoint[i] = t.WorldPointToUV(worldPoints[i]);
            }
            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvPoint);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }
            instance.Internal_RenderBrushes(brushes, t, uvPoint);
        }
        private void RemoveObjectFromTerrain(GStylizedTerrain t, Color[] maskData)
        {
            for (int i = 0; i < PrototypeIndices.Count; ++i)
            {
                int prototypeIndex = PrototypeIndices[i];
                if (prototypeIndex < 0 || prototypeIndex >= Prototypes.Count)
                {
                    continue;
                }
                GameObject g = Prototypes[prototypeIndex];
                if (g == null)
                {
                    continue;
                }

                GSpawner.DestroyIf(t, g, (instance) =>
                {
                    Vector2 uv  = t.WorldPointToUV(instance.transform.position);
                    float alpha = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                    return(Random.value <= alpha);
                });
            }
        }
Пример #19
0
        private void DrawOnTerrain(GStylizedTerrain t)
        {
            Vector3[] worldCorners = GCommon.GetBrushQuadCorners(transform.position, Radius, 0);
            Vector2[] uvCorners    = new Vector2[worldCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = t.WorldPointToUV(worldCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            RenderTexture rt  = t.GetGrassVectorFieldRenderTexture();
            Material      mat = GInternalMaterials.InteractiveGrassVectorFieldMaterial;

            mat.SetFloat("_Opacity", t.TerrainData.Foliage.BendSensitive);
            int pass = 0;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);
        }
Пример #20
0
        private void SpawnTreesOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int     treeIndex      = -1;
            Vector2 v0             = Vector2.zero;
            Vector2 v1             = Vector2.zero;
            Vector2 v2             = Vector2.zero;
            Vector2 center         = Vector2.zero;
            float   radius         = 0;
            Vector2 pos            = Vector2.zero;
            Vector3 bary           = Vector3.zero;
            float   maskValue      = 0;
            int     prototypeCount = t.TerrainData.Foliage.Trees.Prototypes.Count;

            List <GTreeInstance> newInstances = new List <GTreeInstance>();
            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < TreeDensity; ++s)
                {
                    treeIndex = TreePrototypeIndices[Random.Range(0, TreePrototypeIndices.Count)];
                    if (treeIndex < 0 || treeIndex >= prototypeCount)
                    {
                        continue;
                    }

                    pos = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }


                    GTreeInstance tree = GTreeInstance.Create(treeIndex);
                    tree.Position = new Vector3(pos.x, 0, pos.y);
                    tree.Rotation = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                    tree.Scale    = Vector3.Lerp(MinScale, MaxScale, Random.value);

                    newInstances.Add(tree);
                }
            }
            t.TerrainData.Foliage.AddTreeInstances(newInstances);
            newInstances.Clear();
        }
Пример #21
0
        public void Paint(GStylizedTerrain terrain, GTexturePainterArgs args)
        {
            if (terrain.TerrainData == null)
            {
                return;
            }
            if (args.MouseEventType == GPainterMouseEventType.Down)
            {
            }
            if (args.MouseEventType == GPainterMouseEventType.Up)
            {
                return;
            }

            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg             = terrain.TerrainData.Mask.MaskMap;
            int           maskResolution = terrain.TerrainData.Mask.MaskMapResolution;
            RenderTexture rt             = GTerrainTexturePainter.Internal_GetRenderTexture(maskResolution);

            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.MaskPainterMaterial;

            mat.SetTexture("_MainTex", bg);
            SetupTextureGrid(terrain, mat);
            mat.SetTexture("_Mask", args.BrushMask);
            mat.SetFloat("_Opacity", args.Opacity);
            GMaskPainterParams param = GTexturePainterCustomParams.Instance.Mask;
            Vector4            channel;

            if (param.Channel == GTextureChannel.R)
            {
                channel = new Vector4(1, 0, 0, 0);
            }
            else if (param.Channel == GTextureChannel.G)
            {
                channel = new Vector4(0, 1, 0, 0);
            }
            else if (param.Channel == GTextureChannel.B)
            {
                channel = new Vector4(0, 0, 1, 0);
            }
            else
            {
                channel = new Vector4(0, 0, 0, 1);
            }
            mat.SetVector("_Channel", channel);

            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 :
                args.ActionType == GPainterActionType.Alternative ? 2 : 0;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            RenderTexture.active = rt;
            terrain.TerrainData.Mask.MaskMap.ReadPixels(
                new Rect(0, 0, maskResolution, maskResolution), 0, 0);
            terrain.TerrainData.Mask.MaskMap.Apply();
            RenderTexture.active = null;

            if (!args.ForceUpdateGeometry)
            {
                return;
            }
            terrain.TerrainData.Geometry.SetRegionDirty(dirtyRect);
            terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry);
        }
Пример #22
0
        private void SpawnObjectsOnTerrain(GStylizedTerrain t, Color[] maskData, List <Vector4> vertices)
        {
            int        prototypeIndex = -1;
            Vector2    v0             = Vector2.zero;
            Vector2    v1             = Vector2.zero;
            Vector2    v2             = Vector2.zero;
            Vector2    center         = Vector2.zero;
            float      radius         = 0;
            Vector2    pos            = Vector2.zero;
            Vector3    bary           = Vector3.zero;
            float      maskValue      = 0;
            RaycastHit hit;

            int trisCount = vertices.Count / 3;

            for (int i = 0; i < trisCount; ++i)
            {
                v0 = t.WorldPointToUV(vertices[i * 3 + 0]);
                v1 = t.WorldPointToUV(vertices[i * 3 + 1]);
                v2 = t.WorldPointToUV(vertices[i * 3 + 2]);

                center = (v0 + v1 + v2) / 3;
                radius = Vector2.Distance(center, v0);

                for (int s = 0; s < Density; ++s)
                {
                    prototypeIndex = PrototypeIndices[Random.Range(0, PrototypeIndices.Count)];
                    if (prototypeIndex < 0 || prototypeIndex >= Prototypes.Count)
                    {
                        continue;
                    }
                    GameObject g = Prototypes[prototypeIndex];
                    if (g == null)
                    {
                        continue;
                    }

                    pos = center + Random.insideUnitCircle * radius;
                    if (pos.x < 0 || pos.x > 1 ||
                        pos.y < 0 || pos.x > 1)
                    {
                        continue;
                    }

                    GUtilities.CalculateBarycentricCoord(pos, v0, v1, v2, ref bary);
                    if (bary.x < 0 || bary.y < 0 || bary.z < 0)
                    {
                        continue;
                    }

                    maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, pos).r;
                    if (Random.value > maskValue)
                    {
                        continue;
                    }

                    if (t.Raycast(pos.ToX0Y(), out hit))
                    {
                        GameObject instance = GSpawner.Spawn(t, g, hit.point);
                        instance.transform.rotation   = Quaternion.Euler(0, Random.Range(MinRotation, MaxRotation), 0);
                        instance.transform.localScale = Vector3.Lerp(MinScale, MaxScale, Random.value);
                        if (AlignToSurface)
                        {
                            instance.transform.up = hit.normal;
                        }
                    }
                }
            }
        }
Пример #23
0
        private void HandleEraseObject(GStylizedTerrain terrain, GObjectPainterArgs args)
        {
            int     prototypeIndex = -1;
            Vector2 terrainUv      = Vector3.zero;
            Vector3 worldPos       = Vector3.zero;
            Vector3 bary0          = Vector3.zero;
            Vector3 bary1          = Vector3.zero;
            Vector2 maskUv         = Vector2.zero;
            Color   maskColor      = Color.white;

            Texture2D clonedMask  = null;
            Texture2D terrainMask = null;

            if (args.Mask != null)
            {
                clonedMask = GCommon.CloneAndResizeTexture(args.Mask, 256, 256);
            }
            if (args.EnableTerrainMask)
            {
                terrainMask = terrain.TerrainData.Mask.MaskMap;
            }

            for (int i = 0; i < args.PrototypeIndices.Count; ++i)
            {
                prototypeIndex = args.PrototypeIndices[i];
                if (prototypeIndex < 0 || prototypeIndex >= args.Prototypes.Count)
                {
                    continue;
                }
                GameObject g = args.Prototypes[prototypeIndex];
                if (g == null)
                {
                    continue;
                }
                GSpawner.DestroyIf(terrain, g, (instance =>
                {
                    worldPos = instance.transform.position;
                    GUtilities.CalculateBarycentricCoord(
                        new Vector2(worldPos.x, worldPos.z),
                        new Vector2(args.WorldPointCorners[0].x, args.WorldPointCorners[0].z),
                        new Vector2(args.WorldPointCorners[1].x, args.WorldPointCorners[1].z),
                        new Vector2(args.WorldPointCorners[2].x, args.WorldPointCorners[2].z),
                        ref bary0);
                    GUtilities.CalculateBarycentricCoord(
                        new Vector2(worldPos.x, worldPos.z),
                        new Vector2(args.WorldPointCorners[0].x, args.WorldPointCorners[0].z),
                        new Vector2(args.WorldPointCorners[2].x, args.WorldPointCorners[2].z),
                        new Vector2(args.WorldPointCorners[3].x, args.WorldPointCorners[3].z),
                        ref bary1);
                    if (bary0.x >= 0 && bary0.y >= 0 && bary0.z >= 0)
                    {
                        maskUv = bary0.x * Vector2.zero + bary0.y * Vector2.up + bary0.z * Vector2.one;
                    }
                    else if (bary1.x >= 0 && bary1.y >= 0 && bary1.z >= 0)
                    {
                        maskUv = bary1.x * Vector2.zero + bary1.y * Vector2.one + bary1.z * Vector2.right;
                    }
                    else
                    {
                        return(false);
                    }

                    //sample mask
                    if (clonedMask != null)
                    {
                        maskColor = clonedMask.GetPixelBilinear(maskUv.x, maskUv.y);
                        if (Random.value > maskColor.grayscale * args.EraseRatio)
                        {
                            return(false);
                        }
                    }
                    if (args.EnableTerrainMask)
                    {
                        terrainUv = terrain.WorldPointToUV(worldPos);
                        maskColor = terrainMask.GetPixelBilinear(terrainUv.x, terrainUv.y);
                        if (Random.value < maskColor.r)
                        {
                            return(false);
                        }
                    }

                    return(true);
                }));
            }

            if (clonedMask != null)
            {
                Object.DestroyImmediate(clonedMask);
            }
        }
Пример #24
0
        private void HandleEraseGrass(GStylizedTerrain terrain, GFoliagePainterArgs args)
        {
            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }
            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            int     grassIndex  = -1;
            Vector3 terrainSize = new Vector3(
                terrain.TerrainData.Geometry.Width,
                terrain.TerrainData.Geometry.Height,
                terrain.TerrainData.Geometry.Length);
            Vector3   localPos    = Vector3.zero;
            Vector3   worldPos    = Vector3.zero;
            Vector3   bary0       = Vector3.zero;
            Vector3   bary1       = Vector3.zero;
            Vector2   maskUv      = Vector2.zero;
            Color     maskColor   = Color.white;
            Texture2D clonedMask  = null;
            Texture2D terrainMask = null;

            if (args.Mask != null)
            {
                clonedMask = GCommon.CloneAndResizeTexture(args.Mask, 256, 256);
            }
            if (args.EnableTerrainMask)
            {
                terrainMask = terrain.TerrainData.Mask.MaskMap;
            }

            GGrassPatch[] patches = terrain.TerrainData.Foliage.GrassPatches;

            for (int i = 0; i < patches.Length; ++i)
            {
                if (!patches[i].GetUvRange().Overlaps(dirtyRect))
                {
                    continue;
                }

                if (args.ActionType == GPainterActionType.Alternative)
                {
                    patches[i].RequireFullUpdate = true;
                }

                patches[i].RemoveInstances(grass =>
                {
                    grassIndex = args.GrassIndices[Random.Range(0, args.GrassIndices.Count)];
                    localPos.Set(
                        grass.position.x * terrainSize.x,
                        grass.position.y * terrainSize.y,
                        grass.position.z * terrainSize.z);
                    worldPos = terrain.transform.TransformPoint(localPos);
                    GUtilities.CalculateBarycentricCoord(
                        new Vector2(worldPos.x, worldPos.z),
                        new Vector2(args.WorldPointCorners[0].x, args.WorldPointCorners[0].z),
                        new Vector2(args.WorldPointCorners[1].x, args.WorldPointCorners[1].z),
                        new Vector2(args.WorldPointCorners[2].x, args.WorldPointCorners[2].z),
                        ref bary0);
                    GUtilities.CalculateBarycentricCoord(
                        new Vector2(worldPos.x, worldPos.z),
                        new Vector2(args.WorldPointCorners[0].x, args.WorldPointCorners[0].z),
                        new Vector2(args.WorldPointCorners[2].x, args.WorldPointCorners[2].z),
                        new Vector2(args.WorldPointCorners[3].x, args.WorldPointCorners[3].z),
                        ref bary1);
                    if (bary0.x >= 0 && bary0.y >= 0 && bary0.z >= 0)
                    {
                        maskUv = bary0.x * Vector2.zero + bary0.y * Vector2.up + bary0.z * Vector2.one;
                    }
                    else if (bary1.x >= 0 && bary1.y >= 0 && bary1.z >= 0)
                    {
                        maskUv = bary1.x * Vector2.zero + bary1.y * Vector2.one + bary1.z * Vector2.right;
                    }
                    else
                    {
                        return(false);
                    }

                    //sample mask
                    if (clonedMask != null)
                    {
                        maskColor = clonedMask.GetPixelBilinear(maskUv.x, maskUv.y);
                        if (Random.value > maskColor.grayscale * args.EraseRatio)
                        {
                            return(false);
                        }
                    }
                    //sample terrain mask
                    if (args.EnableTerrainMask)
                    {
                        maskColor = terrainMask.GetPixelBilinear(grass.position.x, grass.position.z);
                        if (Random.value < maskColor.r)
                        {
                            return(false);
                        }
                    }

                    if (args.ActionType == GPainterActionType.Negative &&
                        grass.PrototypeIndex == grassIndex)
                    {
                        return(true);
                    }
                    else if (args.ActionType == GPainterActionType.Alternative)
                    {
                        return(true);
                    }

                    return(false);
                });
            }

            if (clonedMask != null)
            {
                Object.DestroyImmediate(clonedMask);
            }
        }
Пример #25
0
        public void Paint(GStylizedTerrain terrain, GTexturePainterArgs args)
        {
            if (terrain.TerrainData == null)
            {
                return;
            }
            if (args.MouseEventType == GPainterMouseEventType.Down)
            {
                terrain.ForceLOD(0);
                GRuntimeSettings.Instance.isEditingGeometry = true;
            }
            if (args.MouseEventType == GPainterMouseEventType.Up)
            {
                terrain.ForceLOD(-1);
                GRuntimeSettings.Instance.isEditingGeometry = false;
                terrain.UpdateTreesPosition();
                terrain.UpdateGrassPatches();
                terrain.TerrainData.Foliage.ClearTreeDirtyRegions();
                terrain.TerrainData.Foliage.ClearGrassDirtyRegions();
                return;
            }

            Vector2[] uvCorners = new Vector2[args.WorldPointCorners.Length];
            for (int i = 0; i < uvCorners.Length; ++i)
            {
                uvCorners[i] = terrain.WorldPointToUV(args.WorldPointCorners[i]);
            }

            Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);

            if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
            {
                return;
            }

            Texture2D     bg = terrain.TerrainData.Geometry.HeightMap;
            int           heightMapResolution = terrain.TerrainData.Geometry.HeightMapResolution;
            RenderTexture rt = GTerrainTexturePainter.Internal_GetRenderTexture(heightMapResolution);

            GCommon.CopyToRT(bg, rt);

            Material mat = GInternalMaterials.SubDivPainterMaterial;

            mat.SetTexture("_MainTex", bg);
            mat.SetTexture("_Mask", args.BrushMask);
            mat.SetFloat("_Opacity", Mathf.Pow(args.Opacity, GTerrainTexturePainter.GEOMETRY_OPACITY_EXPONENT));
            if (args.EnableTerrainMask)
            {
                mat.SetTexture("_TerrainMask", terrain.TerrainData.Mask.MaskMap);
            }
            else
            {
                mat.SetTexture("_TerrainMask", Texture2D.blackTexture);
            }
            int pass =
                args.ActionType == GPainterActionType.Normal ? 0 :
                args.ActionType == GPainterActionType.Negative ? 1 : 0;

            GCommon.DrawQuad(rt, uvCorners, mat, pass);

            RenderTexture.active = rt;
            terrain.TerrainData.Geometry.HeightMap.ReadPixels(
                new Rect(0, 0, heightMapResolution, heightMapResolution), 0, 0);
            terrain.TerrainData.Geometry.HeightMap.Apply();
            RenderTexture.active = null;

            terrain.TerrainData.Geometry.SetRegionDirty(dirtyRect);
            terrain.TerrainData.Foliage.SetTreeRegionDirty(dirtyRect);
            terrain.TerrainData.Foliage.SetGrassRegionDirty(dirtyRect);
            terrain.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry);
        }