Exemple #1
0
        private void UpdateTexture()
        {
            // create preview RT here and keep until the next Repaint
            if (m_previewRT != null)
            {
                RenderTexture.ReleaseTemporary(m_previewRT);
            }

            NoiseSettings noiseSettings = m_serializedNoise.targetObject as NoiseSettings;

            m_previewRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.ARGB32);
            RenderTexture tempRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.RFloat);

            RenderTexture prevActive = RenderTexture.active;

            NoiseUtils.Blit2D(noiseSettings, tempRT);

            NoiseUtils.BlitPreview2D(tempRT, m_previewRT);

            RenderTexture.active = prevActive;

            RenderTexture.ReleaseTemporary(tempRT);

            m_image.image = m_previewRT;
        }
        /// <summary>
        /// Renders an interactive Noise Preview along with tooltip icons and an optional Export button that opens a new ExportNoiseWindow.
        /// A background image is also rendered behind the preview that takes up the entire width of the EditorWindow currently being drawn.
        /// </summary>
        /// <param name = "minSize"> Minimum size for the Preview </param>
        /// <param name = "showExportButton"> Whether or not to render the Export button </param>
        public void DrawPreviewTexture(float minSize, bool showExportButton = true)
        {
            // Draw label with tooltip
            GUILayout.Label(Styles.noisePreview);

            float padding   = 4f;
            float iconWidth = 40f;
            int   size      = (int)Mathf.Min(minSize, EditorGUIUtility.currentViewWidth);
            Rect  totalRect = GUILayoutUtility.GetRect(EditorGUIUtility.currentViewWidth, size + padding * 2); // extra pixels for highlight border

            Color prev = GUI.color;

            GUI.color = new Color(.1f, .1f, .1f, 1f);
            GUI.DrawTexture(totalRect, Texture2D.whiteTexture, ScaleMode.StretchToFill, false);
            GUI.color = Color.white;

            // draw info icon
            // if(totalRect.Contains(Event.current.mousePosition))
            {
                Rect infoIconRect = new Rect(totalRect.x + padding, totalRect.y + padding, iconWidth, iconWidth);
                GUI.Label(infoIconRect, Styles.infoIcon);
                // GUI.Label( infoIconRect, Styles.noiseTooltip );
            }

            // draw export button
            float buttonWidth  = GUI.skin.button.CalcSize(Styles.export).x;
            float buttonHeight = EditorGUIUtility.singleLineHeight;
            Rect  exportRect   = new Rect(totalRect.xMax - buttonWidth - padding, totalRect.yMax - buttonHeight - padding, buttonWidth, buttonHeight);

            if (GUI.Button(exportRect, Styles.export))
            {
                serializedNoise.ApplyModifiedProperties();
                serializedNoise.Update();

                ExportNoiseWindow.ShowWindow(serializedNoise.targetObject as NoiseSettings);
            }

            float safeSpace   = Mathf.Max(iconWidth * 2, buttonWidth * 2) + padding * 4;
            float minWidth    = Mathf.Min(size, totalRect.width - safeSpace);
            Rect  previewRect = new Rect(totalRect.x + totalRect.width / 2 - minWidth / 2, totalRect.y + totalRect.height / 2 - minWidth / 2, minWidth, minWidth);

            EditorGUIUtility.AddCursorRect(previewRect, MouseCursor.Pan);

            if (previewRect.Contains(Event.current.mousePosition))
            {
                serializedNoise.Update();

                HandlePreviewTextureInput(previewRect);

                serializedNoise.ApplyModifiedProperties();
            }

            if (Event.current.type == EventType.Repaint)
            {
                // create preview RT here and keep until the next Repaint
                if (m_previewRT != null)
                {
                    RenderTexture.ReleaseTemporary(m_previewRT);
                }

                NoiseSettings noiseSettings = serializedNoise.targetObject as NoiseSettings;

                m_previewRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.ARGB32);
                RenderTexture tempRT = RenderTexture.GetTemporary(512, 512, 0, RenderTextureFormat.RFloat);

                RenderTexture prevActive = RenderTexture.active;

                NoiseUtils.Blit2D(noiseSettings, tempRT);

                NoiseUtils.BlitPreview2D(tempRT, m_previewRT);

                RenderTexture.active = prevActive;

                GUI.DrawTexture(previewRect, m_previewRT, ScaleMode.ScaleToFit, false);

                RenderTexture.ReleaseTemporary(tempRT);
            }

            GUI.color = prev;
        }
        private void ApplyBrushInternal(Terrain terrain, PaintContext ctx, BrushTransform brushTransform)
        {
            Init();

            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(ctx.sourceRenderTexture.width, ctx.sourceRenderTexture.height);
            RenderTexture filterMaskRT = commonUI.GetBrushMask(fc, ctx.sourceRenderTexture);

            m_rtCollection.ReleaseRenderTextures();
            m_rtCollection.GatherRenderTextures(ctx.sourceRenderTexture.width, ctx.sourceRenderTexture.height, 16);

            Graphics.Blit(ctx.sourceRenderTexture, m_rtCollection[RenderTextureIDs.sourceHeight]);

            Material mat = GetMaterial();

            Matrix4x4 toolMatrix = Matrix4x4.TRS(Vector3.zero, toolSettings.rotation, toolSettings.scale);

            Bounds modelBounds   = activeMesh.bounds;
            float  maxModelScale = Mathf.Max(Mathf.Max(modelBounds.size.x, modelBounds.size.y), modelBounds.size.z);
            // maxModelScale *= Mathf.Sqrt( 2 + maxModelScale * maxModelScale / 4 ) * .5f; // mult so the mesh fits a little better within the camera / stamp texture bounds
            // maxModelScale /= 1.414f;
            float x   = .5f;
            float y   = .5f;
            float xy  = Mathf.Sqrt(x * x + y * y);
            float z   = .5f;
            float xyz = Mathf.Sqrt(xy * xy + z * z);

            maxModelScale *= xyz;

            // build the model matrix to transform the mesh with. we want to scale it to fit in the brush bounds and also center it in the brush bounds
            Matrix4x4 model = toolMatrix * Matrix4x4.Scale(Vector3.one / maxModelScale) * Matrix4x4.Translate(-modelBounds.center);

            // get the world bounds here so we can calculate the needed offset along the up axis
            // Bounds worldBounds = MeshUtility.TransformBounds( model, activeMesh.bounds );
            // float localHeightOffset = Mathf.Min( worldBounds.extents.y, toolSettings.stampHeight / brushUI.terrainUnderCursor.terrainData.size.y  * .5f );
            // Matrix4x4 localHeightOffsetMatrix = Matrix4x4.Translate( Vector3.up * localHeightOffset );
            // apply the local height offset
            // model = localHeightOffsetMatrix * model;

            Vector3 translate = Vector3.up * (toolSettings.stampHeight) / commonUI.terrainUnderCursor.terrainData.size.y;

            // translate = translate / brushUI.brushStrength * .5f;
            model = Matrix4x4.Translate(translate) * model;

            // actually render the mesh to texture to be used with the tool shader
            TerrainTools.MeshUtility.RenderTopdownProjection(activeMesh, model,
                                                             m_rtCollection[RenderTextureIDs.meshStamp],
                                                             TerrainTools.MeshUtility.defaultProjectionMaterial,
                                                             TerrainTools.MeshUtility.ShaderPass.Height);
            NoiseUtils.BlitPreview2D(m_rtCollection[RenderTextureIDs.meshStamp], m_rtCollection[RenderTextureIDs.meshStampPreview]);

            // generate a mask for the mesh to be used in the compositing shader
            TerrainTools.MeshUtility.RenderTopdownProjection(activeMesh, model,
                                                             m_rtCollection[RenderTextureIDs.meshStampMask],
                                                             TerrainTools.MeshUtility.defaultProjectionMaterial,
                                                             TerrainTools.MeshUtility.ShaderPass.Mask);

            // perform actual composite of mesh stamp and terrain source heightmap
            float   brushStrength = Event.current.control ? -commonUI.brushStrength : commonUI.brushStrength;
            Vector4 brushParams   = new Vector4(brushStrength, toolSettings.blendAmount, (commonUI.raycastHitUnderCursor.point.y - commonUI.terrainUnderCursor.GetPosition().y) / commonUI.terrainUnderCursor.terrainData.size.y * .5f, toolSettings.stampHeight / commonUI.terrainUnderCursor.terrainData.size.y * .5f);

            mat.SetVector("_BrushParams", brushParams);
            mat.SetTexture("_MeshStampTex", m_rtCollection[RenderTextureIDs.meshStamp]);
            mat.SetTexture("_FilterTex", filterMaskRT);
            mat.SetTexture("_MeshMaskTex", m_rtCollection[RenderTextureIDs.meshStampMask]);
            mat.SetFloat("_TerrainHeight", commonUI.terrainUnderCursor.terrainData.size.y);
            TerrainPaintUtility.SetupTerrainToolMaterialProperties(ctx, brushTransform, mat);
            Graphics.Blit(ctx.sourceRenderTexture, ctx.destinationRenderTexture, mat, 0);
            Graphics.Blit(ctx.destinationRenderTexture, m_rtCollection[RenderTextureIDs.combinedHeight]);

            // restore old render target
            RenderTexture.active = ctx.oldRenderTexture;
        }