public override void OnSceneGUI(Event currentEvent, int controlId, Terrain terrain, IOnSceneGUI editContext)
        {
            Event e = Event.current;

            base.OnSceneGUI(currentEvent, controlId, terrain, editContext);

            m_JitterHandler.Update();

            if (m_AdjustingStrength)
            {
                float strength = m_BrushStrength.value;

                strength += 0.001f * e.delta.x;
                m_BrushStrength.value = strength;

                int strengthPct = Mathf.RoundToInt(100.0f * strength);

                GUIStyle style = new GUIStyle();
                style.normal.background = Texture2D.whiteTexture;
                style.fontSize          = 12;
                Handles.Label(m_LastRaycastHit.point, $"Strength: {strengthPct}%", style);
                editContext.Repaint();
            }
            else
            {
                m_LastRaycastHit = editContext.raycastHit;
            }
        }
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            commonUI.OnSceneGUI2D(terrain, editContext);

            if (!editContext.hitValidTerrain && !commonUI.isInUse)
            {
                return;
            }

            commonUI.OnSceneGUI(terrain, editContext);

            Event evt = Event.current;

            if (evt.control && (evt.type == EventType.ScrollWheel))
            {
                const float k_mouseWheelToHeightRatio = -0.004f;
                stampToolProperties.stampHeight += Event.current.delta.y * k_mouseWheelToHeightRatio * editContext.raycastHit.distance;
                evt.Use();
                editContext.Repaint();
                SaveSetting();
            }

            // We're only doing painting operations, early out if it's not a repaint
            if (evt.type != EventType.Repaint)
            {
                return;
            }

            if (commonUI.isRaycastHitUnderCursorValid)
            {
                Texture brushTexture = editContext.brushTexture;
                using (IBrushRenderPreviewUnderCursor brushRender = new BrushRenderPreviewUIGroupUnderCursor(commonUI, "Stamp", brushTexture))
                {
                    if (brushRender.CalculateBrushTransform(out BrushTransform brushXform))
                    {
                        PaintContext paintContext    = brushRender.AcquireHeightmap(false, brushXform.GetBrushXYBounds(), 1);
                        Material     previewMaterial = Utility.GetDefaultPreviewMaterial();

                        var texelCtx = Utility.CollectTexelValidity(paintContext.originTerrain, brushXform.GetBrushXYBounds());
                        Utility.SetupMaterialForPaintingWithTexelValidityContext(paintContext, texelCtx, brushXform, previewMaterial);
                        TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainBrushPreviewMode.SourceRenderTexture,
                                                                   editContext.brushTexture, brushXform, previewMaterial, 0);

                        // draw result preview
                        {
                            ApplyBrushInternal(brushRender, paintContext, commonUI.brushStrength, brushTexture, brushXform, terrain);

                            // restore old render target
                            RenderTexture.active = paintContext.oldRenderTexture;

                            previewMaterial.SetTexture("_HeightmapOrig", paintContext.sourceRenderTexture);
                            TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainBrushPreviewMode.DestinationRenderTexture,
                                                                       editContext.brushTexture, brushXform, previewMaterial, 1);
                        }
                        TerrainPaintUtility.ReleaseContextResources(paintContext);
                        texelCtx.Cleanup();
                    }
                }
            }
        }
Beispiel #3
0
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            Event evt = Event.current;

            if (evt.control && (evt.type == EventType.ScrollWheel))
            {
                const float k_mouseWheelToHeightRatio = -0.0004f;
                // we use distance to modify the scroll speed, so that when a user is up close to the brush, they get fine adjustment, and when the user is far from the brush, it adjusts quickly
                m_StampHeightTerrainSpace += Event.current.delta.y * k_mouseWheelToHeightRatio * editContext.raycastHit.distance;
                evt.Use();
                editContext.Repaint();
            }
        }
Beispiel #4
0
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            Event evt = Event.current;

            if (evt.control && (evt.type == EventType.ScrollWheel))
            {
                const float k_mouseWheelToHeightRatio = -0.0004f;
                // we use distance to modify the scroll speed, so that when a user is up close to the brush, they get fine adjustment, and when the user is far from the brush, it adjusts quickly
                m_StampHeightTerrainSpace += Event.current.delta.y * k_mouseWheelToHeightRatio * editContext.raycastHit.distance;
                evt.Use();
                editContext.Repaint();
            }

            // We're only doing painting operations, early out if it's not a repaint
            if (evt.type != EventType.Repaint)
            {
                return;
            }

            if (editContext.hitValidTerrain)
            {
                BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.raycastHit.textureCoord, editContext.brushSize, 0.0f);
                PaintContext   paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);

                Material material = TerrainPaintUtilityEditor.GetDefaultBrushPreviewMaterial();

                TerrainPaintUtilityEditor.DrawBrushPreview(
                    paintContext, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture, editContext.brushTexture, brushXform, material, 0);

                // draw result preview
                {
                    ApplyBrushInternal(paintContext, editContext.brushStrength, editContext.brushTexture, brushXform, terrain, evt.shift);

                    // restore old render target
                    RenderTexture.active = paintContext.oldRenderTexture;

                    material.SetTexture("_HeightmapOrig", paintContext.sourceRenderTexture);

                    TerrainPaintUtilityEditor.DrawBrushPreview(
                        paintContext, TerrainPaintUtilityEditor.BrushPreview.DestinationRenderTexture, editContext.brushTexture, brushXform, material, 1);
                }

                TerrainPaintUtility.ReleaseContextResources(paintContext);
            }
        }
Beispiel #5
0
        public void ConsumeEvents(Terrain terrain, IOnSceneGUI editContext)
        {
            // Consume all of the events we've handled...
            foreach (Event currentEvent in m_ConsumedEvents)
            {
                currentEvent.Use();
            }
            m_ConsumedEvents.Clear();

            // Repaint everything if we need to...
            if (m_RepaintRequested)
            {
                EditorWindow view = EditorWindow.GetWindow <SceneView>();

                editContext.Repaint();
                view.Repaint();

                m_RepaintRequested = false;
            }
        }
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            // there's probably more logic we need to handle here
            if (paintInProgress && (Event.current.type == EventType.MouseUp))
            {
                MaterialManager mgr = terrain.GetComponent <MaterialManager>();
                if (mgr != null)
                {
                    mgr.GetIndexMap().SetIndexMapDirty();
                }
                paintInProgress = false;
            }

            // We're only doing painting operations, early out if it's not a repaint
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            if (editContext.hitValidTerrain)
            {
                if (lastUV != editContext.raycastHit.textureCoord)
                {
                    editContext.Repaint(RepaintFlags.UI);
                }
                lastUV        = editContext.raycastHit.textureCoord;
                lastBrushSize = editContext.brushSize;
                BrushTransform brushXform           = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.raycastHit.textureCoord, editContext.brushSize, 0.0f);
                PaintContext   ctx                  = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);
                Material       brushPreviewMaterial = GetBrushPreviewMaterial();
                Vector4        brushParams          = new Vector4(editContext.brushStrength, 0.0f, 0.0f, 0.0f);
                brushPreviewMaterial.SetVector("_BrushParams", brushParams);
                TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture, editContext.brushTexture, brushXform, brushPreviewMaterial, 0);
                TerrainPaintUtility.ReleaseContextResources(ctx);
            }
        }
Beispiel #7
0
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            commonUI.OnSceneGUI2D(terrain, editContext);
#if UNITY_2019_1_OR_NEWER
            // Don't paint if eyedropper is selected
            if (m_EyedropperSelected)
            {
                EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), MouseCursor.CustomCursor);
                editContext.Repaint();
                return;
            }
#endif

            // We're only doing painting operations, early out if it's not a repaint
            if (!editContext.hitValidTerrain && !commonUI.isInUse)
            {
                return;
            }

            // update brush UI group
            commonUI.OnSceneGUI(terrain, editContext);

            // Don't render preview if this isn't a repaint. losing performance if we do
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            Texture brushTexture = editContext.brushTexture;

            using (IBrushRenderPreviewUnderCursor brushRender = new BrushRenderPreviewUIGroupUnderCursor(commonUI, "PaintTextureTool", brushTexture))
            {
                if (brushRender.CalculateBrushTransform(out BrushTransform brushTransform))                 //cute.
                {
                    RenderTexture tmpRT            = RenderTexture.active;
                    Rect          brushBounds      = brushTransform.GetBrushXYBounds();
                    PaintContext  heightmapContext = brushRender.AcquireHeightmap(false, brushBounds, 1);
                    Material      brushMaterial    = GetBrushPreviewMaterial();

                    if (commonUI.brushMaskFilterStack.filters.Count > 0)
                    {
                        // Evaluate the brush mask filter stack
                        Vector3       brushPos = new Vector3(commonUI.raycastHitUnderCursor.point.x, 0, commonUI.raycastHitUnderCursor.point.z);
                        FilterContext fc       = new FilterContext(terrain, brushPos, commonUI.brushSize, commonUI.brushRotation);
                        fc.renderTextureCollection.GatherRenderTextures(heightmapContext.sourceRenderTexture.width, heightmapContext.sourceRenderTexture.height);
                        RenderTexture filterMaskRT = commonUI.GetBrushMask(fc, heightmapContext.sourceRenderTexture);

                        //Composite the brush texture onto the filter stack result
                        RenderTexture compRT   = RenderTexture.GetTemporary(filterMaskRT.descriptor);
                        Material      blendMat = GetBlendMaterial();
                        blendMat.SetTexture("_BlendTex", editContext.brushTexture);
                        blendMat.SetVector("_BlendParams", new Vector4(0.0f, 0.0f, -(commonUI.brushRotation * Mathf.Deg2Rad), 0.0f));
                        TerrainPaintUtility.SetupTerrainToolMaterialProperties(heightmapContext, brushTransform, blendMat);
                        Graphics.Blit(filterMaskRT, compRT, blendMat, 0);

                        RenderTexture.active = tmpRT;

                        BrushTransform identityBrushTransform = TerrainPaintUtility.CalculateBrushTransform(commonUI.terrainUnderCursor, commonUI.raycastHitUnderCursor.textureCoord, commonUI.brushSize, 0.0f);
                        TerrainPaintUtility.SetupTerrainToolMaterialProperties(heightmapContext, identityBrushTransform, brushMaterial);
                        TerrainPaintUtilityEditor.DrawBrushPreview(heightmapContext, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture, compRT, identityBrushTransform, brushMaterial, 0);
                        RenderTexture.ReleaseTemporary(compRT);
                    }

                    brushRender.RenderBrushPreview(heightmapContext, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture, brushTransform, TerrainPaintUtilityEditor.GetDefaultBrushPreviewMaterial(), 0);
                }
            }
        }
        public override void OnSceneGUI(Terrain currentTerrain, IOnSceneGUI editContext)
        {
            if (currentTerrain == null || editContext == null)
            {
                return;
            }

            ///
            /// Handle Input
            ///
            Event evt       = Event.current;
            int   controlId = GUIUtility.GetControlID(s_TerrainEditorHash, FocusType.Passive);

            switch (evt.GetTypeForControl(controlId))
            {
            case EventType.Layout:
                // nothing to do
                break;

            case EventType.MouseDown:

                if (evt.button == 0 && evt.isMouse)
                {
                    #region Delayed Action

                    delayedActionHandler.StartDelayedActions();

                    #endregion Delayed Action


                    #region PathRecorder
                    if (pathRecorderEnabled)
                    {
                        // reset path
                        pathRecorder.StartRecording();
                    }
                    #endregion PathRecorder
                }

                break;

            case EventType.MouseUp:

                if (evt.button == 0 && evt.isMouse)
                {
                    #region Delayed Action

                    delayedActionHandler.ApplyAllDelayedActions();

                    #endregion Delayed Action
                }
                break;

            case EventType.MouseDrag:
                if (evt.button == 0 && evt.isMouse)
                {
                    #region PathRecorder
                    if (pathRecorderEnabled)
                    {
                        // record path while dragging
                        pathRecorder.AddPosition(editContext.raycastHit.point);
                    }
                    #endregion PathRecorder
                }
                break;
            }

            // handle brush rotation
            if (evt.control && evt.type == EventType.ScrollWheel)
            {
                brushSettings.brushRotationDegrees += Event.current.delta.y;

                if (brushSettings.brushRotationDegrees >= 360)
                {
                    brushSettings.brushRotationDegrees -= 360;
                }

                if (brushSettings.brushRotationDegrees < 0)
                {
                    brushSettings.brushRotationDegrees += 360;
                }

                brushSettings.brushRotationDegrees %= 360;

                evt.Use();
                editContext.Repaint();
            }

            // handle brush resize
            if (evt.control && (evt.type == EventType.MouseDrag))
            {
                brushSettings.brushSize += Event.current.delta.x;

                isBrushResizing = true;

                evt.Use();
                editContext.Repaint();
            }
            else if (evt.type == EventType.MouseUp)
            {
                isBrushResizing = false;
            }

            // We're only doing painting operations, early out if it's not a repaint
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            #region PaintMode

            paintMode.OnSceneGUI(currentTerrain, editContext, brushSettings);

            #endregion PaintMode

            #region Modules

            foreach (ModuleEditor module in onSceneGuiOrderList)
            {
                if (!module.Active)
                {
                    continue;
                }

                module.OnSceneGUI(currentTerrain, editContext, brushSettings);
            }

            #endregion Modules

            #region PathRecorder

            if (pathRecorderEnabled)
            {
                // paint recorded path
                List <Vector3> positions = pathRecorder.GetPositions();
                Handles.DrawAAPolyLine(4, positions.ToArray());
            }

            #endregion PathRecorder
        }
Beispiel #9
0
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            Init();

            // m_rtCollection.DebugGUI( editContext.sceneView );

            brushUI.OnSceneGUI2D(terrain, editContext);

            // only do the rest if user mouse hits valid terrain or they are using the
            // brush parameter hotkeys to resize, etc
            if (!editContext.hitValidTerrain && !brushUI.isInUse && !m_editTransform && !debugOrtho)
            {
                return;
            }

            // update brush UI group
            brushUI.OnSceneGUI(terrain, editContext);

            bool justPressedEditKey = m_editTransform && !m_prevEditTransform;
            bool justReleaseEditKey = m_prevEditTransform && !m_editTransform;

            m_prevEditTransform = m_editTransform;

            if (justPressedEditKey)
            {
                (brushUI as MeshBrushUIGroup).LockTerrainUnderCursor(true);
                m_baseHandlePos        = brushUI.raycastHitUnderCursor.point;
                m_handleHeightOffsetWS = 0;
            }
            else if (justReleaseEditKey)
            {
                (brushUI as MeshBrushUIGroup).UnlockTerrainUnderCursor();
                m_handleHeightOffsetWS = 0;
            }

            // don't render mesh previews, etc. if the mesh field has not been populated yet
            if (activeMesh == null)
            {
                return;
            }

            // dont render preview if this isnt a repaint. losing performance if we do
            if (Event.current.type == EventType.Repaint)
            {
                Terrain currTerrain   = brushUI.terrainUnderCursor;
                Vector2 uv            = brushUI.raycastHitUnderCursor.textureCoord;
                float   brushSize     = brushUI.brushSize;
                float   brushRotation = brushUI.brushRotation;

                if (/* debugOrtho || */ brushUI.isRaycastHitUnderCursorValid)
                {
                    // if(debugOrtho)
                    // {
                    //     uv = Vector2.one * .5f;
                    // }

                    BrushTransform brushTransform = TerrainPaintUtility.CalculateBrushTransform(currTerrain, uv, brushSize, brushRotation);
                    PaintContext   ctx            = TerrainPaintUtility.BeginPaintHeightmap(brushUI.terrainUnderCursor, brushTransform.GetBrushXYBounds(), 1);
                    Material       material       = TerrainPaintUtilityEditor.GetDefaultBrushPreviewMaterial();

                    // don't draw the brush mask preview
                    // but draw the resulting mesh stamp preview
                    {
                        ApplyBrushInternal(terrain, ctx, brushTransform);

                        TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture,
                                                                   m_rtCollection[RenderTextureIDs.meshStamp], brushTransform, material, 0);

                        RenderTexture.active = ctx.oldRenderTexture;

                        material.SetTexture("_HeightmapOrig", ctx.sourceRenderTexture);
                        TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushTransform, material);
                        TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainPaintUtilityEditor.BrushPreview.DestinationRenderTexture,
                                                                   m_rtCollection[RenderTextureIDs.meshStamp], brushTransform, material, 1);

                        TerrainPaintUtility.ReleaseContextResources(ctx);
                    }
                }
            }

            if (m_editTransform)
            {
                EditorGUI.BeginChangeCheck();
                {
                    Vector3 prevHandlePosWS = m_baseHandlePos + Vector3.up * m_handleHeightOffsetWS;

                    // draw transform handles
                    float handleSize = HandleUtility.GetHandleSize(prevHandlePosWS);
                    toolSettings.scale = Handles.ScaleHandle(toolSettings.scale, prevHandlePosWS, toolSettings.rotation, handleSize * 1.5f);
                    Quaternion brushRotation = Quaternion.AngleAxis(brushUI.brushRotation, Vector3.up);
                    toolSettings.rotation = Handles.RotationHandle(toolSettings.rotation, prevHandlePosWS);

                    Vector3 currHandlePosWS = Handles.Slider(prevHandlePosWS, Vector3.up, handleSize, Handles.ArrowHandleCap, 1f);
                    float   deltaHeight     = (currHandlePosWS.y - prevHandlePosWS.y);
                    m_handleHeightOffsetWS   += deltaHeight;
                    toolSettings.stampHeight += deltaHeight;
                }

                if (EditorGUI.EndChangeCheck())
                {
                    editContext.Repaint();
                    SaveSettings();
                }
            }
        }
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            Event evt = Event.current;

            // brush rotation
            if (evt.control && !evt.shift && evt.type == EventType.ScrollWheel)
            {
                m_BrushRotation += Event.current.delta.y;

                if (m_BrushRotation >= 360)
                {
                    m_BrushRotation -= 360;
                }

                if (m_BrushRotation < 0)
                {
                    m_BrushRotation += 360;
                }

                m_BrushRotation %= 360;

                evt.Use();
                editContext.Repaint();
            }

            // brush resize
            if (evt.control && evt.type == EventType.MouseDrag)
            {
                m_BrushSize += Event.current.delta.x;

                evt.Use();
                editContext.Repaint();
            }

            // stamp height
            if (evt.control && evt.shift && evt.type == EventType.ScrollWheel)
            {
                m_StampHeight += Event.current.delta.y * k_mouseWheelToHeightRatio * editContext.raycastHit.distance;

                evt.Use();
                editContext.Repaint();
            }

            if (evt.type != EventType.Repaint)
            {
                return;
            }

            if (editContext.hitValidTerrain)
            {
                BrushTransform brushXform   = TerrainPaintUtility.CalculateBrushTransform(terrain, editContext.raycastHit.textureCoord, m_BrushSize, m_BrushRotation);
                PaintContext   paintContext = TerrainPaintUtility.BeginPaintHeightmap(terrain, brushXform.GetBrushXYBounds(), 1);

                Material material = TerrainPaintUtilityEditor.GetDefaultBrushPreviewMaterial();

                TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainPaintUtilityEditor.BrushPreview.SourceRenderTexture, editContext.brushTexture, brushXform, material, 0);

                ApplyBrushInternal(paintContext, m_BrushStrength, editContext.brushTexture, brushXform, terrain);

                RenderTexture.active = paintContext.oldRenderTexture;

                material.SetTexture("_HeightmapOrig", paintContext.sourceRenderTexture);

                TerrainPaintUtilityEditor.DrawBrushPreview(paintContext, TerrainPaintUtilityEditor.BrushPreview.DestinationRenderTexture, editContext.brushTexture, brushXform, material, 1);

                TerrainPaintUtility.ReleaseContextResources(paintContext);
            }

            #region BrushPreview3d

            if (preview3dEnabled)
            {
                UpdateBrushPreview3d(editContext);
            }

            #endregion BrushPreview3d
        }
Beispiel #11
0
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            commonUI.OnSceneGUI2D(terrain, editContext);
#if UNITY_2019_1_OR_NEWER
            // Don't paint if eyedropper is selected
            if (m_EyedropperSelected)
            {
                EditorGUIUtility.AddCursorRect(new Rect(0, 0, Screen.width, Screen.height), MouseCursor.CustomCursor);
                editContext.Repaint();
                return;
            }
#endif

            // We're only doing painting operations, early out if it's not a repaint
            if (!editContext.hitValidTerrain && !commonUI.isInUse)
            {
                return;
            }

            // update brush UI group
            commonUI.OnSceneGUI(terrain, editContext);

            // Don't render preview if this isn't a repaint. losing performance if we do
            if (Event.current.type != EventType.Repaint)
            {
                return;
            }

            Texture brushTexture = editContext.brushTexture;

            using (IBrushRenderPreviewUnderCursor brushRender = new BrushRenderPreviewUIGroupUnderCursor(commonUI, "PaintTextureTool", brushTexture))
            {
                if (brushRender.CalculateBrushTransform(out BrushTransform brushTransform)) //cute.
                {
                    RenderTexture tmpRT            = RenderTexture.active;
                    Rect          brushBounds      = brushTransform.GetBrushXYBounds();
                    PaintContext  heightmapContext = brushRender.AcquireHeightmap(false, brushBounds, 1);
                    Material      brushMaterial    = GetBrushPreviewMaterial();
                    brushMaterial.SetFloat("_BrushStrength", commonUI.brushStrength);
                    var defaultPreviewMaterial = Utility.GetDefaultPreviewMaterial();

                    var texelCtx = Utility.CollectTexelValidity(heightmapContext.originTerrain, brushTransform.GetBrushXYBounds());
                    Utility.SetupMaterialForPaintingWithTexelValidityContext(heightmapContext, texelCtx, brushTransform, defaultPreviewMaterial);

                    if (commonUI.brushMaskFilterStack.filters.Count > 0)
                    {
                        // Evaluate the brush mask filter stack
                        var brushMask = RTUtils.GetTempHandle(heightmapContext.sourceRenderTexture.width, heightmapContext.sourceRenderTexture.height, 0, FilterUtility.defaultFormat);
                        commonUI.GetBrushMask(heightmapContext.sourceRenderTexture, brushMask);

                        RenderTexture.active = tmpRT;

                        Utility.SetupMaterialForPaintingWithTexelValidityContext(heightmapContext, texelCtx, brushTransform, brushMaterial);
                        brushMaterial.SetTexture("_FilterTex", brushMask);
                        TerrainPaintUtilityEditor.DrawBrushPreview(heightmapContext, TerrainBrushPreviewMode.SourceRenderTexture, editContext.brushTexture, brushTransform, brushMaterial, 0);
                        RTUtils.Release(brushMask);
                    }

                    brushRender.RenderBrushPreview(heightmapContext, TerrainBrushPreviewMode.SourceRenderTexture, brushTransform, defaultPreviewMaterial, 0);
                    texelCtx.Cleanup();
                }
            }
        }
        public override void OnSceneGUI(Terrain terrain, IOnSceneGUI editContext)
        {
            Init();

            // m_rtCollection.OnSceneGUI( EditorWindow.GetWindow<SceneView>().position.height / 4 );

            commonUI.OnSceneGUI2D(terrain, editContext);

            // only do the rest if user mouse hits valid terrain or they are using the
            // brush parameter hotkeys to resize, etc
            if (!editContext.hitValidTerrain && !commonUI.isInUse && !m_editTransform && !debugOrtho)
            {
                return;
            }

            // update brush UI group
            commonUI.OnSceneGUI(terrain, editContext);

            bool justPressedEditKey = m_editTransform && !m_prevEditTransform;
            bool justReleaseEditKey = m_prevEditTransform && !m_editTransform;

            m_prevEditTransform = m_editTransform;

            if (justPressedEditKey)
            {
                (commonUI as MeshBrushUIGroup).LockTerrainUnderCursor(true);
                m_baseHandlePos        = commonUI.raycastHitUnderCursor.point;
                m_handleHeightOffsetWS = 0;
            }
            else if (justReleaseEditKey)
            {
                (commonUI as MeshBrushUIGroup).UnlockTerrainUnderCursor();
                m_handleHeightOffsetWS = 0;
            }

            // don't render mesh previews, etc. if the mesh field has not been populated yet
            if (activeMesh == null)
            {
                return;
            }

            // dont render preview if this isnt a repaint. losing performance if we do
            if (Event.current.type == EventType.Repaint)
            {
                Terrain currTerrain   = commonUI.terrainUnderCursor;
                Vector2 uv            = commonUI.raycastHitUnderCursor.textureCoord;
                float   brushSize     = commonUI.brushSize;
                float   brushRotation = commonUI.brushRotation;

                if (commonUI.isRaycastHitUnderCursorValid)
                {
                    BrushTransform brushTransform  = TerrainPaintUtility.CalculateBrushTransform(currTerrain, uv, brushSize, brushRotation);
                    PaintContext   ctx             = TerrainPaintUtility.BeginPaintHeightmap(commonUI.terrainUnderCursor, brushTransform.GetBrushXYBounds(), 1);
                    Material       previewMaterial = Utility.GetDefaultPreviewMaterial();

                    var texelCtx = Utility.CollectTexelValidity(ctx.originTerrain, brushTransform.GetBrushXYBounds());
                    Utility.SetupMaterialForPaintingWithTexelValidityContext(ctx, texelCtx, brushTransform, previewMaterial);

                    // don't draw the brush mask preview
                    // but draw the resulting mesh stamp preview
                    {
                        ApplyBrushInternal(terrain, ctx, brushTransform);

                        RenderTexture.active = ctx.oldRenderTexture;

                        previewMaterial.SetTexture("_HeightmapOrig", ctx.sourceRenderTexture);
                        TerrainPaintUtilityEditor.DrawBrushPreview(ctx, TerrainBrushPreviewMode.DestinationRenderTexture,
                                                                   editContext.brushTexture, brushTransform, previewMaterial, 1);

                        TerrainPaintUtility.ReleaseContextResources(ctx);
                        m_rtCollection.ReleaseRTHandles();
                    }

                    texelCtx.Cleanup();
                }
            }

            if (m_editTransform)
            {
                EditorGUI.BeginChangeCheck();
                {
                    Vector3 prevHandlePosWS = m_baseHandlePos + Vector3.up * m_handleHeightOffsetWS;

                    // draw transform handles
                    float      handleSize    = HandleUtility.GetHandleSize(prevHandlePosWS);
                    Quaternion brushRotation = Quaternion.AngleAxis(commonUI.brushRotation, Vector3.up);
                    Matrix4x4  brushRotMat   = Matrix4x4.Rotate(brushRotation);
                    Matrix4x4  toolRotMat    = Matrix4x4.Rotate(toolSettings.rotation);
                    Quaternion handleRot     = MeshUtils.QuaternionFromMatrix(brushRotMat * toolRotMat);
                    Quaternion newRot        = Handles.RotationHandle(handleRot, prevHandlePosWS);
                    toolSettings.rotation = MeshUtils.QuaternionFromMatrix(brushRotMat.inverse * Matrix4x4.Rotate(newRot));

                    toolSettings.scale = Handles.ScaleHandle(toolSettings.scale, prevHandlePosWS, handleRot, handleSize * 1.5f);

                    Vector3 currHandlePosWS = Handles.Slider(prevHandlePosWS, Vector3.up, handleSize, Handles.ArrowHandleCap, 1f);
                    float   deltaHeight     = (currHandlePosWS.y - prevHandlePosWS.y);
                    m_handleHeightOffsetWS   += deltaHeight;
                    toolSettings.stampHeight += deltaHeight;
                }

                if (EditorGUI.EndChangeCheck())
                {
                    SaveSettings();
                    editContext.Repaint();
                }
            }
        }