示例#1
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            var strength      = p.Strength * 1000.0f;
            var brushPosition = p.Gizmo.CursorPosition;

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx           = x + p.ModifiedOffset.X;
                    var sourceHeight = p.SourceHeightMap[zz * p.HeightmapSize + xx];

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, sourceHeight, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);

                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld);

                    p.TempBuffer[z * p.ModifiedSize.X + x] = sourceHeight + paintAmount * strength;
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifyHeightMap(p.Terrain, ref p.PatchCoord, new IntPtr(p.TempBuffer), ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#2
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            var strength      = p.Strength * -10.0f;
            var brushPosition = p.Gizmo.CursorPosition;
            var tempBuffer    = (byte *)p.TempBuffer;

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx         = x + p.ModifiedOffset.X;
                    var sourceMask = p.SourceHolesMask[zz * p.HeightmapSize + xx] != 0 ? 1.0f : 0.0f;

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, 0, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);
                    samplePositionWorld.Y = brushPosition.Y;

                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld);

                    tempBuffer[z * p.ModifiedSize.X + x] = (byte)((sourceMask + paintAmount * strength) < 0.8f ? 0 : 255);
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifyHolesMask(p.Terrain, ref p.PatchCoord, tempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#3
0
        /// <summary>
        /// Draws the scene plateaus.
        /// </summary>
        /// <param name="_ground">Ground.</param>
        /// <param name="_player">Player.</param>
        public static void DrawScenePlateaus(GameObject _ground, GameObject _player)
        {
            ICEEditorStyle.Splitter();
            ICEEditorLayout.BeginHorizontal();
            TerrainTools.TerrainPlateaus = (int)ICEEditorLayout.DefaultSlider("Plateaus (max.)", "", TerrainTools.TerrainPlateaus, 1, 0, 500, 50);
            EditorGUI.BeginDisabledGroup(TerrainTools.TerrainPlateaus == 0 || _ground == null || _ground.GetComponent <Terrain>() == null);
            if (ICEEditorLayout.ButtonMiddle("UPDATE", ""))
            {
                if (_ground != null && _ground.GetComponent <Terrain>() != null)
                {
                    Undo.RegisterCompleteObjectUndo(_ground.GetComponent <Terrain>().terrainData, "Wizard Terrain Data");
                    TerrainTools.CreatePlateaus(_ground.GetComponent <Terrain>().terrainData);
                    UpdateLevel(_player, _ground);
                }
            }
            EditorGUI.EndDisabledGroup();
            ICEEditorLayout.EndHorizontal(Info.WIZARD_TERRAIN_PLATEAUS);

            EditorGUI.BeginDisabledGroup(TerrainTools.TerrainPlateaus == 0);
            EditorGUI.indentLevel++;
            TerrainTools.TerrainPlateausMaxHeight = ICEEditorLayout.DefaultSlider("Max. Height", "", TerrainTools.TerrainPlateausMaxHeight, Init.DECIMAL_PRECISION_INDICATOR, 0, 1, 0.3f);
            TerrainTools.TerrainPlateausMaxRadius = (int)ICEEditorLayout.DefaultSlider("Max. Radius", "", TerrainTools.TerrainPlateausMaxRadius, Init.DECIMAL_PRECISION_INDICATOR, 0, TerrainTools.TerrainSize / 2, 100);
            EditorGUI.indentLevel--;
            EditorGUI.EndDisabledGroup();
        }
示例#4
0
        /// <inheritdoc />
        public override void Pick()
        {
            if (Mode.EditMode == EditTerrainGizmoMode.Modes.Add && TryAddPatch())
            {
                // Patch added!
            }
            else
            {
                // Get mouse ray and try to hit terrain
                var ray          = Owner.MouseRay;
                var rayCastFlags = SceneGraphNode.RayCastData.FlagTypes.SkipColliders;
                var hit          = Editor.Instance.Scene.Root.RayCast(ref ray, out _, rayCastFlags) as TerrainNode;

                // Update selection
                var sceneEditing = Editor.Instance.SceneEditing;
                if (hit != null)
                {
                    if (Mode.EditMode != EditTerrainGizmoMode.Modes.Add)
                    {
                        // Perform detailed tracing
                        var terrain = (FlaxEngine.Terrain)hit.Actor;
                        TerrainTools.RayCastChunk(terrain, ray, out _, out var patchCoord, out var chunkCoord);
                        Mode.SetSelectedChunk(ref patchCoord, ref chunkCoord);
                    }

                    sceneEditing.Select(hit);
                }
                else
                {
                    sceneEditing.Deselect();
                }
            }
        }
示例#5
0
        /// <summary>
        /// Draws the scene valleys.
        /// </summary>
        /// <param name="_ground">Ground.</param>
        /// <param name="_player">Player.</param>
        public static void DrawSceneValleys(GameObject _ground, GameObject _player)
        {
            ICEEditorStyle.Splitter();
            ICEEditorLayout.BeginHorizontal();
            TerrainTools.TerrainValleys = (int)ICEEditorLayout.DefaultSlider("Valleys (max.)", "", TerrainTools.TerrainValleys, 1, 0, 500, TerrainTools.DefaultTerrainValleys);
            EditorGUI.BeginDisabledGroup(TerrainTools.TerrainHills == 0 || _ground == null || _ground.GetComponent <Terrain>() == null);
            if (ICEEditorLayout.ButtonMiddle("UPDATE", ""))
            {
                if (_ground != null && _ground.GetComponent <Terrain>() != null)
                {
                    Undo.RegisterCompleteObjectUndo(_ground.GetComponent <Terrain>().terrainData, "Wizard Terrain Data");
                    TerrainTools.CreateValleys(_ground.GetComponent <Terrain>().terrainData);
                    TerrainTools.UpdateSplatmap(_ground.GetComponent <Terrain>().terrainData);
                    UpdateLevel(_player, _ground);
                }
            }
            EditorGUI.EndDisabledGroup();
            ICEEditorLayout.EndHorizontal(Info.WIZARD_TERRAIN_VALLEYS);
            EditorGUI.BeginDisabledGroup(TerrainTools.TerrainHills == 0);
            EditorGUI.indentLevel++;

            int _terrain_height = TerrainTools.GetTerrainHeight(_ground);
            int _terrain_size   = TerrainTools.GetTerrainSize(_ground);

            float _deep   = (int)MathTools.Denormalize(TerrainTools.TerrainValleysMaxDeep, 0, _terrain_height);
            float _radius = (int)MathTools.Denormalize(TerrainTools.TerrainValleysMaxRadius * 2, 0, _terrain_size * 0.5f);

            TerrainTools.TerrainValleysMaxDeep   = ICEEditorLayout.DefaultSlider("Max. Deep (" + _deep + ")", "", TerrainTools.TerrainValleysMaxDeep, Init.DECIMAL_PRECISION_INDICATOR, 0, 1, TerrainTools.DefaultTerrainValleysMaxDeep * TerrainTools.GetSizeMultiplier());
            TerrainTools.TerrainValleysMaxRadius = ICEEditorLayout.DefaultSlider("Max. Radius (" + _radius + ")", "", TerrainTools.TerrainValleysMaxRadius, Init.DECIMAL_PRECISION_INDICATOR, 0, 1, TerrainTools.DefaultTerrainValleysMaxRadius * TerrainTools.GetSizeMultiplier());

            EditorGUI.indentLevel--;
            EditorGUI.EndDisabledGroup();
        }
示例#6
0
        /// <inheritdoc />
        public override void Update(float dt)
        {
            base.Update(dt);

            if (!IsActive)
            {
                return;
            }

            if (Mode.EditMode == EditTerrainGizmoMode.Modes.Add)
            {
                var sceneEditing = Editor.Instance.SceneEditing;
                var terrainNode  = sceneEditing.SelectionCount == 1 ? sceneEditing.Selection[0] as TerrainNode : null;
                if (terrainNode != null)
                {
                    // Check if mouse ray hits any of the terrain patches sides to add a new patch there
                    var mouseRay   = Owner.MouseRay;
                    var terrain    = (FlaxEngine.Terrain)terrainNode.Actor;
                    var chunkCoord = Int2.Zero;
                    if (!TerrainTools.TryGetPatchCoordToAdd(terrain, mouseRay, out var patchCoord))
                    {
                        // If terrain has no patches TryGetPatchCoordToAdd will always return the default patch to add, otherwise fallback to already used location
                        terrain.GetPatchCoord(0, out patchCoord);
                    }
                    Mode.SetSelectedChunk(ref patchCoord, ref chunkCoord);
                }
            }
        }
示例#7
0
 // Use this for initialization
 void Start()
 {
     cam             = Camera.main;
     terraindata     = terrain.terrainData;
     TerrainTextures = terraindata.alphamapTextures;
     terrainTools    = GetComponent <TerrainTools>();
 }
示例#8
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            // Prepare
            var brushPosition = p.Gizmo.CursorPosition;
            var noise         = new PerlinNoise(0, NoiseScale, p.Strength * NoiseAmount);
            var chunkSize     = p.Terrain.ChunkSize;
            var patchSize     = chunkSize * FlaxEngine.Terrain.PatchEdgeChunksCount;
            var patchOffset   = p.PatchCoord * patchSize;

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx           = x + p.ModifiedOffset.X;
                    var sourceHeight = p.SourceHeightMap[zz * p.HeightmapSize + xx];

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, sourceHeight, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);

                    var noiseSample = noise.Sample(xx + patchOffset.X, zz + patchOffset.Y);
                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld);

                    p.TempBuffer[z * p.ModifiedSize.X + x] = sourceHeight + noiseSample * paintAmount;
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifyHeightMap(p.Terrain, ref p.PatchCoord, p.TempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#9
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            // Prepare
            var brushPosition = p.Gizmo.CursorPosition;
            var radius        = Mathf.Max(Mathf.CeilToInt(FilterRadius * 0.01f * p.Brush.Size), 2);
            var max           = p.HeightmapSize - 1;
            var strength      = Mathf.Saturate(p.Strength);

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx           = x + p.ModifiedOffset.X;
                    var sourceHeight = p.SourceHeightMap[zz * p.HeightmapSize + xx];

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, sourceHeight, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);

                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld) * strength;

                    if (paintAmount > 0)
                    {
                        // Sum the nearby values
                        float smoothValue        = 0;
                        int   smoothValueSamples = 0;
                        int   minX = Math.Max(x - radius + p.ModifiedOffset.X, 0);
                        int   minZ = Math.Max(z - radius + p.ModifiedOffset.Y, 0);
                        int   maxX = Math.Min(x + radius + p.ModifiedOffset.X, max);
                        int   maxZ = Math.Min(z + radius + p.ModifiedOffset.Y, max);
                        for (int dz = minZ; dz <= maxZ; dz++)
                        {
                            for (int dx = minX; dx <= maxX; dx++)
                            {
                                var height = p.SourceHeightMap[dz * p.HeightmapSize + dx];
                                smoothValue += height;
                                smoothValueSamples++;
                            }
                        }

                        // Normalize
                        smoothValue /= smoothValueSamples;

                        // Blend between the height and smooth value
                        p.TempBuffer[z * p.ModifiedSize.X + x] = Mathf.Lerp(sourceHeight, smoothValue, paintAmount);
                    }
                    else
                    {
                        p.TempBuffer[z * p.ModifiedSize.X + x] = sourceHeight;
                    }
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifyHeightMap(p.Terrain, ref p.PatchCoord, p.TempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#10
0
        /// <inheritdoc />
        protected override void SetData(ref Int2 patchCoord, IntPtr data, object tag)
        {
            var offset = Int2.Zero;
            var size   = new Int2((int)Mathf.Sqrt(_heightmapLength));

            if (TerrainTools.ModifyHolesMask(_terrain, ref patchCoord, data, ref offset, ref size))
            {
                throw new FlaxException("Failed to modify the terrain holes.");
            }
        }
示例#11
0
        /// <inheritdoc />
        protected override void SetData(ref Int2 patchCoord, IntPtr data, object tag)
        {
            var offset = Int2.Zero;
            var size   = new Int2((int)Mathf.Sqrt(_heightmapLength));

            if (TerrainTools.ModifyHeightMap(Terrain, ref patchCoord, (float *)data, ref offset, ref size))
            {
                throw new Exception("Failed to modify the heightmap.");
            }
        }
示例#12
0
            public DeletePatchAction(FlaxEngine.Terrain terrain, ref Int2 patchCoord)
            {
                if (terrain == null)
                {
                    throw new ArgumentException(nameof(terrain));
                }

                _terrainId  = terrain.ID;
                _patchCoord = patchCoord;
                _data       = TerrainTools.SerializePatch(terrain, ref patchCoord);
            }
示例#13
0
        private void OnExportTerrainButtonClicked()
        {
            if (_isUpdatingUI)
            {
                return;
            }

            string outputFolder = MessageBox.BrowseFolderDialog(null, null, "Select the output folder");

            TerrainTools.ExportTerrain(CarveTab.SelectedTerrain, outputFolder);
        }
示例#14
0
    static void OpenWindows()
    {
        // EditorWindow windows = EditorWindow.GetWindowWithRect<SceneExport>(new Rect(0, 0, 400, 300));
        TerrainTools windows = EditorWindow.GetWindow <TerrainTools>();

        windows.minSize = new Vector2(400, 300);
        windows.maxSize = new Vector2(400, 800);
        windows.Show();
        //
        //Tool.View = ViewTool.None;
    }
示例#15
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            var strength       = p.Strength;
            var layer          = (int)Layer;
            var brushPosition  = p.Gizmo.CursorPosition;
            var layerComponent = layer % 4;

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx  = x + p.ModifiedOffset.X;
                    var src = p.SourceData[zz * p.HeightmapSize + xx];

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, 0, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);

                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld) * strength;

                    // Extract layer weight
                    byte *srcPtr    = &src.R;
                    var   srcWeight = *(srcPtr + layerComponent) / 255.0f;

                    // Accumulate weight
                    float dstWeight = srcWeight + paintAmount;

                    // Check for solid layer case
                    if (dstWeight >= 1.0f)
                    {
                        // Erase other layers
                        // TODO: maybe erase only the higher layers?
                        // TODO: need to erase also weights form the other splatmaps
                        src = Color32.Transparent;

                        // Use limit value
                        dstWeight = 1.0f;
                    }

                    // Modify packed weight
                    *(srcPtr + layerComponent) = (byte)(dstWeight * 255.0f);

                    // Write back
                    p.TempBuffer[z * p.ModifiedSize.X + x] = src;
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifySplatMap(p.Terrain, ref p.PatchCoord, p.SplatmapIndex, p.TempBuffer, ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#16
0
        private void OnExportTerrainButtonClicked()
        {
            if (_isUpdatingUI)
            {
                return;
            }

            if (FileSystem.ShowBrowseFolderDialog(null, null, "Select the output folder", out var outputFolder))
            {
                return;
            }
            TerrainTools.ExportTerrain(CarveTab.SelectedTerrain, outputFolder);
        }
示例#17
0
 // Update is called once per frame
 void Update()
 {
     if (Input.GetKey("p"))
     {
         // PaintMaxima ();
         // paintSlopes();
         paintUnderMouse();
     }
     if (Input.GetKey("o"))
     {
         //TerrainTools genericTools = GetComponent<TerrainTools>();
         TerrainTools genericTools = GetComponent("TerrainTools") as TerrainTools;
     }
 }
示例#18
0
    /// <summary>
    /// Changes Terrain Feature Type
    /// </summary>
    /// <param name="tool">Terrain Feature Type</param>
    public void TerrainOption(string tool)
    {
        terrainToolSelected = (TerrainTools)Enum.Parse(typeof(TerrainTools), tool);
        switch (terrainToolSelected)
        {
        case TerrainTools.Up:
            terrainSpawnSpacing = terrainUpSpacing;
            break;

        case TerrainTools.Plants:
            terrainSpawnSpacing = terrainPlantsSpacing;
            break;
        }
    }
示例#19
0
        private void Generate()
        {
            _isWorking = true;
            _isDone    = false;

            // Call tool to generate the terrain patches from the input data
            if (TerrainTools.GenerateTerrain(_terrain, ref _options.NumberOfPatches, _options.Heightmap, _options.HeightmapScale, _options.Splatmap1, _options.Splatmap2))
            {
                Editor.LogError("Failed to generate terrain. See log for more info.");
            }

            _isWorking = false;
            _isDone    = true;
        }
示例#20
0
            /// <inheritdoc />
            public void Undo()
            {
                var terrain = Object.Find <FlaxEngine.Terrain>(ref _terrainId);

                if (terrain == null)
                {
                    Editor.LogError("Missing terrain actor.");
                    return;
                }

                terrain.AddPatch(ref _patchCoord);
                TerrainTools.DeserializePatch(terrain, ref _patchCoord, _data);

                _editor.Scene.MarkSceneEdited(terrain.Scene);
            }
示例#21
0
            /// <inheritdoc />
            public void Undo()
            {
                var terrain = Object.Find <FlaxEngine.Terrain>(ref _terrainId);

                if (terrain == null)
                {
                    Editor.LogError("Missing terrain actor.");
                    return;
                }

                terrain.AddPatch(ref _patchCoord);
                TerrainTools.DeserializePatch(terrain, ref _patchCoord, _data);
                terrain.GetPatchBounds(terrain.GetPatchIndex(ref _patchCoord), out var patchBounds);
                OnPatchEdit(terrain, ref patchBounds);
            }
示例#22
0
        static TerrainSettings()
        {
            Power              = EditorPrefs.GetInt("TerrainSettings.Power", 3);
            TerrainToolSize    = EditorPrefs.GetFloat("TerrainSettings.TerrainToolSize", 1.5f);
            CurrentTerrainTool = (TerrainTools)EditorPrefs.GetInt("TerrainSettings.CurrentTerrainTool", 0);

            EditorApplication.quitting += SaveEditorPrefs;
            AssemblyReloadEvents.beforeAssemblyReload += SaveEditorPrefs;

            void SaveEditorPrefs()
            {
                EditorPrefs.SetInt("TerrainSettings.Power", Power);
                EditorPrefs.SetFloat("TerrainSettings.TerrainToolSize", TerrainToolSize);
                EditorPrefs.SetInt("TerrainSettings.CurrentTerrainTool", (int)CurrentTerrainTool);
            }
        }
示例#23
0
            /// <inheritdoc />
            public void Do()
            {
                var terrain = Object.Find <FlaxEngine.Terrain>(ref _terrainId);

                if (terrain == null)
                {
                    Editor.LogError("Missing terrain actor.");
                    return;
                }

                terrain.AddPatch(ref _patchCoord);
                if (TerrainTools.InitializePatch(terrain, ref _patchCoord))
                {
                    Editor.LogError("Failed to initialize terrain patch.");
                }
                terrain.GetPatchBounds(terrain.GetPatchIndex(ref _patchCoord), out var patchBounds);
                OnPatchEdit(terrain, ref patchBounds);
            }
示例#24
0
        /// <summary>
        /// Draws the scene trees.
        /// </summary>
        /// <param name="_ground">Ground.</param>
        /// <param name="_player">Player.</param>
        public static void DrawSceneTrees(GameObject _ground, GameObject _player)
        {
            ICEEditorStyle.Splitter();
            ICEEditorLayout.BeginHorizontal();
            TerrainTools.TerrainTreesMax      = (int)ICEEditorLayout.DefaultSlider("Trees", "", TerrainTools.TerrainTreesMax, 1, 0, 10000, TerrainTools.DefaultTerrainTreesMax);
            TerrainTools.TerrainTreesMaxAngle = EditorGUILayout.FloatField(TerrainTools.TerrainTreesMaxAngle, GUILayout.MaxWidth(45));

            if (ICEEditorLayout.ButtonMiddle("UPDATE", ""))
            {
                if (_ground != null && _ground.GetComponent <Terrain>() != null)
                {
                    Undo.RegisterCompleteObjectUndo(_ground.GetComponent <Terrain>().terrainData, "Wizard Terrain Data");
                    TerrainTools.UpdateTrees(_ground.GetComponent <Terrain>().terrainData);
                }
            }

            ICEEditorLayout.EndHorizontal(Info.WIZARD_TERRAIN_TREES);
        }
示例#25
0
            /// <inheritdoc />
            public void Do()
            {
                var terrain = Object.Find <FlaxEngine.Terrain>(ref _terrainId);

                if (terrain == null)
                {
                    Editor.LogError("Missing terrain actor.");
                    return;
                }

                terrain.AddPatch(ref _patchCoord);
                if (TerrainTools.InitializePatch(terrain, ref _patchCoord))
                {
                    Editor.LogError("Failed to initialize terrain patch.");
                }

                Editor.Instance.Scene.MarkSceneEdited(terrain.Scene);
            }
示例#26
0
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUILayout.PropertyField(serializedObject.FindProperty("terrainParent"), true);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("tileObject"), true);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("rows"), true);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("columns"), true);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("spacingX"), true);
        EditorGUILayout.PropertyField(serializedObject.FindProperty("spacingY"), true);
        serializedObject.ApplyModifiedProperties();

        TerrainTools tools = (TerrainTools)target;

        if (GUILayout.Button("Create Layout"))
        {
            tools.CreateLayout();
        }
    }
示例#27
0
        /// <inheritdoc />
        public override unsafe void Apply(ref ApplyParams p)
        {
            // If used with invert mode pick the target height level
            if (p.Options.Invert)
            {
                var center = p.ModifiedOffset + p.ModifiedSize / 2;
                TargetHeight = p.SourceHeightMap[center.Y * p.HeightmapSize + center.X];
                return;
            }

            // Prepare
            var brushPosition = p.Gizmo.CursorPosition;
            var targetHeight  = TargetHeight;
            var strength      = Mathf.Saturate(p.Strength);

            // Apply brush modification
            Profiler.BeginEvent("Apply Brush");
            for (int z = 0; z < p.ModifiedSize.Y; z++)
            {
                var zz = z + p.ModifiedOffset.Y;
                for (int x = 0; x < p.ModifiedSize.X; x++)
                {
                    var xx           = x + p.ModifiedOffset.X;
                    var sourceHeight = p.SourceHeightMap[zz * p.HeightmapSize + xx];

                    var samplePositionLocal = p.PatchPositionLocal + new Vector3(xx * FlaxEngine.Terrain.UnitsPerVertex, sourceHeight, zz * FlaxEngine.Terrain.UnitsPerVertex);
                    Vector3.Transform(ref samplePositionLocal, ref p.TerrainWorld, out Vector3 samplePositionWorld);

                    var paintAmount = p.Brush.Sample(ref brushPosition, ref samplePositionWorld) * strength;

                    // Blend between the height and the target value
                    p.TempBuffer[z * p.ModifiedSize.X + x] = Mathf.Lerp(sourceHeight, targetHeight, paintAmount);
                }
            }
            Profiler.EndEvent();

            // Update terrain patch
            TerrainTools.ModifyHeightMap(p.Terrain, ref p.PatchCoord, new IntPtr(p.TempBuffer), ref p.ModifiedOffset, ref p.ModifiedSize);
        }
示例#28
0
        /// <inheritdoc />
        public override void Update(float dt)
        {
            base.Update(dt);

            // Check if gizmo is not active
            if (!IsActive)
            {
                PaintEnd();
                return;
            }

            // Check if no terrain is selected
            var terrain = SelectedTerrain;

            if (!terrain)
            {
                PaintEnd();
                return;
            }

            // Check if selected terrain was changed during painting
            if (terrain != _paintTerrain && IsPainting)
            {
                PaintEnd();
            }

            // Special case if user is sculpting terrain and mouse is not moving then freeze the brush location to help painting vertical tip objects
            var mouseRay = Owner.MouseRay;

            if (IsPainting && _prevRay == mouseRay)
            {
                // Freeze cursor
            }
            // Perform detailed tracing to find cursor location on the terrain
            else if (TerrainTools.RayCastChunk(terrain, mouseRay, out var closest, out var patchCoord, out var chunkCoord))
            {
                var hitLocation = mouseRay.GetPoint(closest);
                Mode.SetCursor(ref hitLocation);
            }
示例#29
0
        /// <summary>
        /// Draws the scene grass.
        /// </summary>
        /// <param name="_ground">Ground.</param>
        /// <param name="_player">Player.</param>
        public static void DrawSceneGrass(GameObject _ground, GameObject _player)
        {
            //ICEEditorStyle.Splitter();
            ICEEditorLayout.BeginHorizontal();

            TerrainTools.TerrainGrassDensity = ICEEditorLayout.DefaultSlider("Grass", "", TerrainTools.TerrainGrassDensity, 0.5f, 0, 50, TerrainTools.DefaultTerrainGrassDensity);
            TerrainTools.TerrainGrassAngle   = EditorGUILayout.FloatField(TerrainTools.TerrainGrassAngle, GUILayout.MaxWidth(45));

            if (ICEEditorLayout.ButtonMiddle("UPDATE", ""))
            {
                if (_ground != null && _ground.GetComponent <Terrain>() != null)
                {
                    Undo.RegisterCompleteObjectUndo(_ground.GetComponent <Terrain>().terrainData, "Wizard Terrain Data");
                    TerrainTools.UpdateDetailLayer(_ground.GetComponent <Terrain>().terrainData);
                }
            }

            ICEEditorLayout.EndHorizontal(Info.WIZARD_TERRAIN_GRAS);

            //ICEEditorStyle.Splitter();
            ICEEditorLayout.BeginHorizontal();

            TerrainTools.TerrainMeshDensity = ICEEditorLayout.DefaultSlider("Bushes", "", TerrainTools.TerrainMeshDensity, 0.5f, 0, 50, TerrainTools.DefaultTerrainMeshDensity);
            TerrainTools.TerrainMeshAngle   = EditorGUILayout.FloatField(TerrainTools.TerrainMeshAngle, GUILayout.MaxWidth(45));

            if (ICEEditorLayout.ButtonMiddle("UPDATE", ""))
            {
                if (_ground != null && _ground.GetComponent <Terrain>() != null)
                {
                    Undo.RegisterCompleteObjectUndo(_ground.GetComponent <Terrain>().terrainData, "Wizard Terrain Data");
                    TerrainTools.UpdateDetailLayer(_ground.GetComponent <Terrain>().terrainData);
                }
            }

            ICEEditorLayout.EndHorizontal(Info.WIZARD_TERRAIN_BUSHES);
        }
示例#30
0
 /// <inheritdoc />
 protected override IntPtr GetData(ref Int2 patchCoord, object tag)
 {
     return(new IntPtr(TerrainTools.GetHeightmapData(Terrain, ref patchCoord)));
 }