예제 #1
0
        private void OnBeginRender(Camera cam)
        {
            if (cam.cameraType != CameraType.SceneView)
            {
                return;
            }

            if (painter.Editor_EnableLivePreview)
            {
                bool canDrawLivePreview = painter.ActivePainter != null && painter.ActivePainter is IGTexturePainterWithLivePreview;
                if (canDrawLivePreview)
                {
                    Ray        r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
                    RaycastHit hit;
                    if (GStylizedTerrain.Raycast(r, out hit, float.MaxValue, painter.GroupId))
                    {
                        DrawLivePreview(cam, hit);
                    }
                }
            }

            if (painter.EnableTerrainMask)
            {
                DrawMask(cam);
            }
        }
 private void Update()
 {
     try
     {
         UpdateParameters();
         if (Camera.main == null)
         {
             return;
         }
         if (Painter == null)
         {
             return;
         }
         Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);
         RaycastHit hit = new RaycastHit();
         if (GStylizedTerrain.Raycast(ray, out hit, 1000, Painter.GroupId))
         {
             DrawCursor(hit, true);
             Paint(hit);
         }
         else
         {
             DrawCursor(hit, false);
         }
     }
     catch (System.Exception e)
     {
         logs.Add(e.ToString());
         ShowLogs();
     }
 }
        private void SnapAnchorToSurface(GSplineAnchor a)
        {
            Ray        r = new Ray(new Vector3(a.Position.x, 10000, a.Position.z), Vector3.down);
            RaycastHit hit;

            if (GStylizedTerrain.Raycast(r, out hit, float.MaxValue, instance.GroupId))
            {
                a.Position = hit.point;
            }
        }
        private void HandleAddAnchor()
        {
            Ray        r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            RaycastHit hit;

            if (GStylizedTerrain.Raycast(r, out hit, float.MaxValue, instance.GroupId))
            {
                instance.AddAnchorAutoTangent(hit.point, selectedAnchorIndex);
                selectedAnchorIndex  = instance.Spline.Anchors.Count - 1;
                selectedSegmentIndex = -1;
                GUI.changed          = true;
                Event.current.Use();
            }
        }
예제 #5
0
        private void HandleTerrainEditingInSceneView()
        {
            if (!painter.enabled)
            {
                return;
            }

            if (Event.current == null)
            {
                return;
            }

            if (Event.current.alt == true)
            {
                return;
            }

            if (Event.current.type != EventType.Repaint &&
                Event.current.type != EventType.MouseDown &&
                Event.current.type != EventType.MouseDrag &&
                Event.current.type != EventType.MouseUp &&
                Event.current.type != EventType.KeyDown)
            {
                return;
            }

            int controlId = GUIUtility.GetControlID(this.GetHashCode(), FocusType.Passive);

            if (Event.current.type == EventType.MouseDown)
            {
                if (Event.current.button == 0)
                {
                    //Set the hot control to this tool, to disable marquee selection tool on mouse dragging
                    GUIUtility.hotControl = controlId;
                }
            }
            else if (Event.current.type == EventType.MouseUp)
            {
                GGriffinSettings.Instance.IsHidingFoliageOnEditing = false;
                if (GUIUtility.hotControl == controlId)
                {
                    //Return the hot control back to Unity, use the default
                    GUIUtility.hotControl = 0;
                }
            }

            Ray        r = HandleUtility.GUIPointToWorldRay(Event.current.mousePosition);
            RaycastHit hit;

            if (GStylizedTerrain.Raycast(r, out hit, float.MaxValue, painter.GroupId))
            {
                OnRaycast(true, hit);
            }
            else
            {
                OnRaycast(false, hit);
            }

            if (GGuiEventUtilities.IsLeftMouse)
            {
                Event.current.Use();
            }
        }
예제 #6
0
        private void HandleSpawnGrass(GStylizedTerrain terrain, GFoliagePainterArgs args)
        {
            int        grassIndex   = -1;
            Vector3    randomPos    = Vector3.zero;
            Vector3    rayOrigin    = Vector3.zero;
            Vector3    rayDirection = Vector3.down;
            float      sqrtTwo      = Mathf.Sqrt(2);
            Ray        ray          = new Ray();
            RaycastHit samplePoint;
            Vector3    bary0  = Vector3.zero;
            Vector3    bary1  = Vector3.zero;
            Vector2    maskUv = Vector2.zero;
            Vector2    samplePointTexcoord = 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;
            }

            int prototypeCount = terrain.TerrainData.Foliage.Grasses.Prototypes.Count;
            int sampleCount    = args.Density;
            List <GGrassInstance> newInstances = new List <GGrassInstance>();

            for (int i = 0; i < sampleCount; ++i)
            {
                grassIndex = args.GrassIndices[Random.Range(0, args.GrassIndices.Count)];
                if (grassIndex < 0 || grassIndex >= prototypeCount)
                {
                    continue;
                }
                randomPos = args.HitPoint + Random.insideUnitSphere * args.Radius * sqrtTwo;
                rayOrigin.Set(
                    randomPos.x,
                    10000,
                    randomPos.z);
                ray.origin    = rayOrigin;
                ray.direction = rayDirection;
                if (terrain.Raycast(ray, out samplePoint, float.MaxValue))
                {
                    GUtilities.CalculateBarycentricCoord(
                        new Vector2(samplePoint.point.x, samplePoint.point.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(samplePoint.point.x, samplePoint.point.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
                    {
                        continue;
                    }

                    //sample mask
                    if (clonedMask != null)
                    {
                        maskColor = clonedMask.GetPixelBilinear(maskUv.x, maskUv.y);
                        if (Random.value > maskColor.grayscale)
                        {
                            continue;
                        }
                    }
                    //sample terrain mask
                    if (args.EnableTerrainMask)
                    {
                        samplePointTexcoord = samplePoint.textureCoord;
                        maskColor           = terrainMask.GetPixelBilinear(samplePointTexcoord.x, samplePointTexcoord.y);
                        if (Random.value < maskColor.r)
                        {
                            continue;
                        }
                    }

                    //apply filter
                    GSpawnFilterArgs filterArgs = GSpawnFilterArgs.Create();
                    filterArgs.Terrain         = terrain;
                    filterArgs.Position        = samplePoint.point;
                    filterArgs.SurfaceNormal   = samplePoint.normal;
                    filterArgs.SurfaceTexcoord = samplePoint.textureCoord;

                    List <Type> suitableFilter = SuitableFilterTypes;
                    if (args.Filters != null)
                    {
                        for (int fIndex = 0; fIndex < args.Filters.Length; ++fIndex)
                        {
                            if (args.Filters[fIndex] != null &&
                                args.Filters[fIndex].Ignore != true)
                            {
                                if (suitableFilter.Contains(args.Filters[fIndex].GetType()))
                                {
                                    args.Filters[fIndex].Apply(ref filterArgs);
                                }
                            }
                            if (filterArgs.ShouldExclude)
                            {
                                break;
                            }
                        }
                    }

                    //spawn
                    if (filterArgs.ShouldExclude)
                    {
                        continue;
                    }

                    GGrassInstance grass = GGrassInstance.Create(grassIndex);
                    grass.Position = terrain.WorldPointToNormalized(filterArgs.Position);
                    grass.Rotation = filterArgs.Rotation;
                    grass.Scale    = filterArgs.Scale;
                    newInstances.Add(grass);
                }
            }

            terrain.TerrainData.Foliage.AddGrassInstances(newInstances);
            if (clonedMask != null)
            {
                Object.DestroyImmediate(clonedMask);
            }
        }
        private void SpawnObjectOnTerrain(GStylizedTerrain t, Color[] maskData, int layerIndex)
        {
            GObjectStampLayer layer       = Layers[layerIndex];
            Vector3           centerPos   = Vector3.zero;
            Vector3           samplePos   = Vector3.zero;
            Vector2           uv          = Vector2.zero;
            float             maskValue   = 0;
            Vector3           terrainSize = new Vector3(
                t.TerrainData.Geometry.Width,
                t.TerrainData.Geometry.Height,
                t.TerrainData.Geometry.Length);
            Vector3 scale = new Vector3(
                GUtilities.InverseLerpUnclamped(0, terrainSize.x, Scale.x),
                1,
                GUtilities.InverseLerpUnclamped(0, terrainSize.z, Scale.z));
            Matrix4x4 matrix = Matrix4x4.TRS(
                t.WorldPointToNormalized(Position),
                Rotation,
                scale);

            int        index         = -1;
            int        instanceCount = 0;
            int        attempt       = 0;
            int        maxAttempt    = layer.InstanceCount * 100;
            RaycastHit hit;

#if UNITY_EDITOR
            string title           = "Stamping on " + t.name;
            string info            = string.Format("Layer: {0}", !string.IsNullOrEmpty(layer.Name) ? layer.Name : layerIndex.ToString());
            int    currentPercent  = 0;
            int    attemptPercent  = 0;
            int    instancePercent = 0;
            GCommonGUI.CancelableProgressBar(title, info, 0);
#endif

            while (instanceCount < layer.InstanceCount && attempt <= maxAttempt)
            {
                attempt += 1;

#if UNITY_EDITOR
                attemptPercent  = (int)(attempt * 100.0f / maxAttempt);
                instancePercent = (int)(instanceCount * 100.0f / layer.InstanceCount);
                if (currentPercent != Mathf.Max(attemptPercent, instancePercent))
                {
                    currentPercent = Mathf.Max(attemptPercent, instancePercent);
                    GCommonGUI.CancelableProgressBar(title, string.Format("{0} ... {1}%", info, currentPercent), currentPercent / 100.0f);
                }
#endif

                index = layer.PrototypeIndices[Random.Range(0, layer.PrototypeIndices.Count)];
                if (index < 0 || index >= layer.Prototypes.Count)
                {
                    continue;
                }
                GameObject g = layer.Prototypes[index];
                if (g == null)
                {
                    continue;
                }

                centerPos.Set(Random.value - 0.5f, 0, Random.value - 0.5f);
                samplePos = matrix.MultiplyPoint(centerPos);
                if (samplePos.x < 0 || samplePos.x > 1 ||
                    samplePos.z < 0 || samplePos.z > 1)
                {
                    continue;
                }
                uv.Set(samplePos.x, samplePos.z);
                maskValue = GUtilities.GetColorBilinear(maskData, MaskResolution, MaskResolution, uv).r;
                if (Random.value > maskValue)
                {
                    continue;
                }

                if (t.Raycast(samplePos, out hit))
                {
                    GameObject instance = GSpawner.Spawn(t, g, hit.point);
                    instance.transform.rotation   = Quaternion.Euler(0, Random.Range(layer.MinRotation, layer.MaxRotation), 0);
                    instance.transform.localScale = Vector3.Lerp(layer.MinScale, layer.MaxScale, Random.value);
                    if (layer.AlignToSurface)
                    {
                        instance.transform.up = hit.normal;
                    }

                    instanceCount += 1;
                }
            }
#if UNITY_EDITOR
            GCommonGUI.ClearProgressBar();
#endif
        }
예제 #8
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;
                        }
                    }
                }
            }
        }