Beispiel #1
0
        protected override bool OnMouseDown(Viewport viewport, EMouseButtons button)
        {
            if (button == EMouseButtons.Left)
            {
                if (GetToolPosition(viewport, out var terrain, out toolModifyStartPosition))
                {
                    var layer = DocumentWindow.TerrainPaintLayersGetSelected();

                    if (IsCurrentPaintTool() && layer != null)
                    {
                        if (layer.Mask.Value != null && layer.Mask.Value.Length != 0)
                        {
                            if (layer.Mask.Value.Length != terrain.GetPaintMaskSizeInteger() * terrain.GetPaintMaskSizeInteger())
                            {
                                EditorMessageBox.ShowWarning(EditorLocalization.Translate("Terrain", "Unable to paint to selected layer because Mask size of the layer and MaskSize of the terrain are not equal."));
                                return(true);
                            }
                        }
                    }

                    if (mode == ModeEnum.PaintFlatten)
                    {
                        if (layer != null)
                        {
                            Vector2I maskIndex = terrain.GetMaskIndexByPosition(toolModifyStartPosition.ToVector2());
                            toolModifyStartMaskValue = layer.GetMaskValue(maskIndex);
                        }
                    }

                    toolModify = true;
                    return(true);
                }
            }

            return(false);
        }
Beispiel #2
0
        protected virtual void ToolPutTickPaint(Viewport viewport, double delta)
        {
            if (!GetToolPosition(viewport, out var selectedTerrain, out var position))
            {
                return;
            }

            var layer = DocumentWindow.TerrainPaintLayersGetSelected();

            if (layer == null)
            {
                return;
            }

            var toolRadius    = (float)Component_Scene_DocumentWindow.TerrainToolRadius;
            var toolHardness  = (float)Component_Scene_DocumentWindow.TerrainToolHardness;
            var toolShapeType = Component_Scene_DocumentWindow.TerrainToolShape;

            float strength = (float)(delta * Component_Scene_DocumentWindow.TerrainToolStrength * toolRadius * 0.5 * 2.0);

            Vector2 positionMin = position.ToVector2() - new Vector2(toolRadius, toolRadius);
            Vector2 positionMax = position.ToVector2() + new Vector2(toolRadius, toolRadius);

            List <Component_Terrain> terrains;

            //!!!!
            //if( selectedTerrain.HeightmapTerrainManager != null && HeightmapTerrainManager.Instance != null )
            //{
            //	terrains = HeightmapTerrainManager.Instance.GetTerrainsByArea( positionMin, positionMax, true );
            //}
            //else
            //{
            terrains = new List <Component_Terrain>();
            terrains.Add(selectedTerrain);
            //}

            foreach (var terrain in terrains)
            {
                UndoActionPropertiesChange undoSetPropertyAction = paintSetPropertyUndoActions.Find(a => a.Items[0].Obj == layer);
                var undoChangeAction = paintChangeUndoActions.Find(a => a.Terrain == terrain);

                Vector2I indexMin = terrain.GetMaskIndexByPosition(positionMin);
                Vector2I indexMax = terrain.GetMaskIndexByPosition(positionMax) + new Vector2I(1, 1);
                terrain.ClampMaskIndex(ref indexMin);
                terrain.ClampMaskIndex(ref indexMax);

                for (int y = indexMin.Y; y <= indexMax.Y; y++)
                {
                    for (int x = indexMin.X; x <= indexMax.X; x++)
                    {
                        Vector2 point = terrain.GetPositionXYByMaskIndex(new Vector2I(x, y));

                        float coef;
                        {
                            double length;
                            if (toolShapeType == ToolShape.Circle)
                            {
                                length = (point - position.ToVector2()).Length();
                            }
                            else
                            {
                                length = Math.Max(Math.Abs(point.X - position.X), Math.Abs(point.Y - position.Y));
                            }

                            if (length >= toolRadius)
                            {
                                coef = 0;
                            }
                            else if (length == 0)
                            {
                                coef = 1;
                            }
                            else if (length <= toolHardness * toolRadius)
                            {
                                coef = 1;
                            }
                            else
                            {
                                double c;
                                if (toolRadius - toolRadius * toolHardness != 0)
                                {
                                    c = (length - toolRadius * toolHardness) / (toolRadius - toolRadius * toolHardness);
                                }
                                else
                                {
                                    c = 0;
                                }
                                coef = (float)Math.Cos(Math.PI / 2 * c);
                            }
                        }

                        if (coef != 0)
                        {
                            float oldValue = layer.GetMaskValue(new Vector2I(x, y));

                            float value = oldValue;

                            //near corner (x == 0 or y == 0) take value from near terrain.
                            bool takeValueFromNearTerrain = false;
                            //!!!!
                            //if( selectedTerrain.HeightmapTerrainManager != null && HeightmapTerrainManager.Instance != null )
                            //{
                            //	if( x == 0 )
                            //	{
                            //		HeightmapTerrain terrain2 =
                            //			FindTerrainWithIndex( terrains, terrain.HeightmapTerrainManagerIndex - new Vector2I( 1, 0 ) );
                            //		if( terrain2 != null )
                            //		{
                            //			value = terrain2.GetHeight( terrain.GetPositionXY( new Vector2I( x, y ) ), false ) + terrain2.Position.Z;
                            //			value -= terrain.Position.Z;

                            //			takeValueFromNearTerrain = true;
                            //		}
                            //	}
                            //	else if( y == 0 )
                            //	{
                            //		HeightmapTerrain terrain2 =
                            //			FindTerrainWithIndex( terrains, terrain.HeightmapTerrainManagerIndex - new Vector2I( 0, 1 ) );
                            //		if( terrain2 != null )
                            //		{
                            //			value = terrain2.GetHeight( terrain.GetPositionXY( new Vector2I( x, y ) ), false ) + terrain2.Position.Z;
                            //			value -= terrain.Position.Z;

                            //			takeValueFromNearTerrain = true;
                            //		}
                            //	}
                            //}

                            if (!takeValueFromNearTerrain)
                            {
                                switch (mode)
                                {
                                case ModeEnum.PaintPaint:
                                case ModeEnum.PaintClear:
                                {
                                    bool paint = mode == ModeEnum.PaintPaint;
                                    if ((Form.ModifierKeys & Keys.Shift) != 0)
                                    {
                                        paint = !paint;
                                    }

                                    if (paint)
                                    {
                                        value = oldValue + strength * coef;
                                    }
                                    else
                                    {
                                        value = oldValue - strength * coef;
                                    }
                                }
                                break;

                                case ModeEnum.PaintSmooth:
                                {
                                    float needValue = 0;
                                    {
                                        needValue += layer.GetMaskValue(new Vector2I(x - 1, y));
                                        needValue += layer.GetMaskValue(new Vector2I(x + 1, y));
                                        needValue += layer.GetMaskValue(new Vector2I(x, y - 1));
                                        needValue += layer.GetMaskValue(new Vector2I(x, y + 1));
                                        //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x - 1, y ) ) );
                                        //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x + 1, y ) ) );
                                        //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x, y - 1 ) ) );
                                        //needValue += layer.GetMaskValue( GetClampedMaskIndex( terrain, new Vec2I( x, y + 1 ) ) );
                                        needValue /= 4;
                                    }

                                    if (oldValue < needValue)
                                    {
                                        value = oldValue + strength * coef;
                                        if (value > needValue)
                                        {
                                            value = needValue;
                                        }
                                    }
                                    else if (oldValue > needValue)
                                    {
                                        value = oldValue - strength * coef;
                                        if (value < needValue)
                                        {
                                            value = needValue;
                                        }
                                    }
                                }
                                break;

                                case ModeEnum.PaintFlatten:
                                {
                                    float needValue = toolModifyStartMaskValue;

                                    if (oldValue < needValue)
                                    {
                                        value = oldValue + strength * coef;
                                        if (value > needValue)
                                        {
                                            value = needValue;
                                        }
                                    }
                                    else if (oldValue > needValue)
                                    {
                                        value = oldValue - strength * coef;
                                        if (value < needValue)
                                        {
                                            value = needValue;
                                        }
                                    }
                                }
                                break;
                                }
                            }

                            MathEx.Clamp(ref value, 0, 1);

                            if (oldValue != value)
                            {
                                //undo
                                if (layer.Mask.Value == null || layer.Mask.Value.Length == 0 || undoSetPropertyAction != null)
                                {
                                    if (undoSetPropertyAction == null)
                                    {
                                        var oldValue2 = layer.Mask;

                                        layer.Mask = new byte[terrain.GetPaintMaskSizeInteger() * terrain.GetPaintMaskSizeInteger()];

                                        var property = (Metadata.Property)layer.MetadataGetMemberBySignature("property:Mask");
                                        var undoItem = new UndoActionPropertiesChange.Item(layer, property, oldValue2);
                                        undoSetPropertyAction = new UndoActionPropertiesChange(undoItem);
                                        paintSetPropertyUndoActions.Add(undoSetPropertyAction);
                                    }
                                }
                                else
                                {
                                    if (undoChangeAction == null)
                                    {
                                        undoChangeAction = new Component_Terrain_PaintChangeUndoAction(terrain);
                                        paintChangeUndoActions.Add(undoChangeAction);
                                    }
                                    undoChangeAction.SaveValue(layer, new Vector2I(x, y), oldValue);
                                }

                                //update terrain
                                layer.SetMaskValue(new Vector2I(x, y), value);
                            }
                        }
                    }
                }

                //!!!!use mask indexes
                //var updateRectangle = new RectangleI( indexMin, indexMax );

                //terrain.UpdateRenderingData( updateRectangle, false );

                //bool foundItemForTerrain = false;
                //foreach( var updateItem in needUpdateRectangle )
                //{
                //	if( updateItem.Terrain == terrain )
                //	{
                //		updateItem.Rectangle.Add( updateRectangle );
                //		foundItemForTerrain = true;
                //		break;
                //	}
                //}
                //if( !foundItemForTerrain )
                //{
                //	NeedUpdateRectangleItem item = new NeedUpdateRectangleItem();
                //	item.Terrain = terrain;
                //	item.Rectangle = updateRectangle;
                //	needUpdateRectangle.Add( item );
                //}
            }
        }