From d8997b59d30b63218f594d840d924a10287ce509 Mon Sep 17 00:00:00 2001 From: Adam Frisby Date: Tue, 24 Jul 2007 05:22:33 +0000 Subject: [PATCH] * Terrain should now send just updated patches. --- OpenSim/Region/Environment/Scenes/Scene.cs | 51 ++++++++++++------- .../Region/Environment/Scenes/SceneBase.cs | 4 +- .../Terrain.BasicTerrain/TerrainEngine.cs | 16 ++++++ .../libTerrainBSD/Channel/Channel.cs | 3 ++ .../libTerrainBSD/Channel/Common.cs | 33 ++++++++++++ .../libTerrainBSD/Channel/Editing/Flatten.cs | 2 +- .../libTerrainBSD/Channel/Editing/Raise.cs | 6 +-- .../libTerrainBSD/Channel/File.cs | 2 + .../Channel/Generators/Fracture.cs | 2 + .../Channel/Generators/Gradient.cs | 2 + .../Channel/Generators/HillPlanter.cs | 8 +++ .../libTerrainBSD/Channel/Generators/Noise.cs | 2 + .../Channel/Generators/Spiral.cs | 9 +++- .../Channel/Generators/Voronoi.cs | 7 ++- .../libTerrainBSD/Channel/Generators/Worms.cs | 2 + .../libTerrainBSD/Channel/Grid.cs | 18 +++++-- .../Channel/Manipulators/AerobicErosion.cs | 4 +- .../Channel/Manipulators/HydraulicErosion.cs | 2 + .../Channel/Manipulators/ThermalWeathering.cs | 2 + .../libTerrainBSD/Channel/Operators.cs | 25 +++++++++ 20 files changed, 170 insertions(+), 30 deletions(-) diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 16b8b4c533..564ba5fff6 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs @@ -235,25 +235,40 @@ namespace OpenSim.Region.Environment.Scenes storageCount = 0; } - if (Terrain.tainted > 0) + if (Terrain.Tainted()) { - lock (m_syncRoot) + lock (Terrain.heightmap) { - phyScene.SetTerrain(Terrain.GetHeights1D()); + lock (m_syncRoot) + { + phyScene.SetTerrain(Terrain.GetHeights1D()); + } + + storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); + + float[] terData = Terrain.GetHeights1D(); + + ForEachScenePresence(delegate(ScenePresence presence) + { + for (int x = 0; x < 16; x++) + { + for (int y = 0; y < 16; y++) + { + if (Terrain.Tainted(x, y)) + { + SendLayerData(x, y, presence.ControllingClient, terData); + } + } + } + }); + + foreach (LLUUID UUID in Entities.Keys) + { + Entities[UUID].LandRenegerated(); + } + + Terrain.ResetTaint(); } - - storageManager.DataStore.StoreTerrain(Terrain.GetHeights2DD()); - - ForEachScenePresence(delegate(ScenePresence presence) - { - SendLayerData(presence.ControllingClient); - }); - - foreach (LLUUID UUID in Entities.Keys) - { - Entities[UUID].LandRenegerated(); - } - Terrain.tainted = 0; } landPrimCheckCount++; @@ -365,9 +380,11 @@ namespace OpenSim.Region.Environment.Scenes { /* Dont save here, rely on tainting system instead */ + float[] terrain = Terrain.GetHeights1D(); + ForEachScenePresence(delegate(ScenePresence presence) { - SendLayerData(pointx, pointy, presence.ControllingClient); + SendLayerData(pointx, pointy, presence.ControllingClient, terrain); }); } } diff --git a/OpenSim/Region/Environment/Scenes/SceneBase.cs b/OpenSim/Region/Environment/Scenes/SceneBase.cs index fb7624a416..76a8439e4e 100644 --- a/OpenSim/Region/Environment/Scenes/SceneBase.cs +++ b/OpenSim/Region/Environment/Scenes/SceneBase.cs @@ -90,9 +90,9 @@ namespace OpenSim.Region.Environment.Scenes /// Patch coordinate (x) 0..16 /// Patch coordinate (y) 0..16 /// The client to send to - public virtual void SendLayerData(int px, int py, IClientAPI RemoteClient) + public virtual void SendLayerData(int px, int py, IClientAPI RemoteClient, float[] terrain) { - RemoteClient.SendLayerData(px, py, Terrain.GetHeights1D()); + RemoteClient.SendLayerData(px, py, terrain); } #endregion diff --git a/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs index 9c58874fd4..a609623cc8 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/TerrainEngine.cs @@ -99,6 +99,22 @@ namespace OpenSim.Region.Terrain tainted++; } + public bool Tainted() + { + return (tainted != 0); + } + + public bool Tainted(int x, int y) + { + return (heightmap.diff[x / 16, y / 16] != 0); + } + + public void ResetTaint() + { + tainted = 0; + heightmap.diff = new int[w / 16, h / 16]; + } + /// /// Checks to make sure the terrain is within baked values +/- maxRaise/minLower /// diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs index 53fb6b222c..6dfee1fb94 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Channel.cs @@ -40,6 +40,7 @@ namespace libTerrain partial class Channel { public double[,] map; + public int[,] diff; public int w; public int h; @@ -50,6 +51,7 @@ namespace libTerrain w = 256; h = 256; map = new double[w, h]; + diff = new int[(int)(w / 16), (int)(h / 16)]; } public Channel(int width, int height) @@ -57,6 +59,7 @@ namespace libTerrain w = width; h = height; map = new double[w, h]; + diff = new int[(int)(w / 16), (int)(h / 16)]; } } diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs index 0d6d0fc409..5715c70f68 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Common.cs @@ -51,8 +51,31 @@ namespace libTerrain return x; } + public void SetDiff() + { + SetDiff(1); + } + + public void SetDiff(int val) + { + for (int x = 0; x < w / 16; x++) + { + for (int y = 0; y < h / 16; y++) + { + diff[x, y] = val; + } + } + } + + public void SetDiff(int x, int y) + { + diff[x / 16, y / 16]++; + } + public void Set(int x, int y, double val) { + SetDiff(x, y); + if (x >= w) throw new Exception("Bounds error while setting pixel (width)"); if (y >= h) @@ -67,6 +90,8 @@ namespace libTerrain public void SetClip(int x, int y, double val) { + SetDiff(x, y); + if (x >= w) throw new Exception("Bounds error while setting pixel (width)"); if (y >= h) @@ -129,11 +154,15 @@ namespace libTerrain public void SetWrap(int x, int y, double val) { + SetDiff(x, y); + map[x % w, y % h] = val; } public void SetWrapClip(int x, int y, double val) { + SetDiff(x, y); + if (val > 1.0) val = 1.0; if (val < 0.0) @@ -144,6 +173,8 @@ namespace libTerrain public void Fill(double val) { + SetDiff(); + int x, y; for (x = 0; x < w; x++) { @@ -156,6 +187,8 @@ namespace libTerrain public void Fill(double min, double max, double val) { + SetDiff(); + int x, y; for (x = 0; x < w; x++) { diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs index 03b88a4fb0..ef7a6a7bcf 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Flatten.cs @@ -115,7 +115,7 @@ namespace libTerrain if (z < 0) z = 0; - map[x, y] = Tools.linearInterpolate(map[x, y], height, z); + Set(x, y, Tools.linearInterpolate(map[x, y], height, z)); } } } diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs index 7bccef3cc8..1d04a4f7a8 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Editing/Raise.cs @@ -68,7 +68,7 @@ namespace libTerrain if (z < 0) z = 0; - map[x, y] += z * amount; + Set(x, y, map[x, y] + (z * amount)); } } } @@ -93,7 +93,7 @@ namespace libTerrain if (z < 0) z = 0; - map[x, y] += z * amount; + Set(x, y, map[x, y] + (z * amount)); } } } @@ -131,7 +131,7 @@ namespace libTerrain if (z < 0) z = 0; - map[x, y] -= z * amount; + Set(x, y, map[x, y] - (z * amount)); } } } diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs index e09dc5a15b..b147004750 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/File.cs @@ -37,6 +37,8 @@ namespace libTerrain { public Channel LoadImage(string filename) { + SetDiff(); + Bitmap bit = new Bitmap(filename); Channel chan = new Channel(bit.Width, bit.Height); diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs index 8427eabef3..13dd1bc4c5 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Fracture.cs @@ -82,6 +82,8 @@ namespace libTerrain public void Fracture(int number, double scalemin, double scalemax) { + SetDiff(); + Random rand = new Random(seed); for (int i = 0; i < number; i++) diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs index 0c9b3c3214..47b7a66bf1 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Gradient.cs @@ -37,6 +37,8 @@ namespace libTerrain public void GradientCube() { + SetDiff(); + int x, y; for (x = 0; x < w; x++) { diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs index 3b8e9633b6..5a697b1e17 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/HillPlanter.cs @@ -46,6 +46,8 @@ namespace libTerrain /// Generates hill-shaped noise instead of consistent hills public void HillsSpheres(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) { + SetDiff(); + Random random = new Random(seed); int x, y; @@ -110,6 +112,8 @@ namespace libTerrain /// Generates hill-shaped noise instead of consistent hills public void HillsCones(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) { + SetDiff(); + Random random = new Random(seed); int x, y; @@ -163,6 +167,8 @@ namespace libTerrain public void HillsBlocks(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) { + SetDiff(); + Random random = new Random(seed); int x, y; @@ -217,6 +223,8 @@ namespace libTerrain public void HillsSquared(int number, double scale_min, double scale_range, bool island, bool additive, bool noisy) { + SetDiff(); + Random random = new Random(seed); int x, y; diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs index ebb1771faf..3cefcfee22 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Noise.cs @@ -40,6 +40,8 @@ namespace libTerrain /// 3-Clause BSD Licensed public void Noise() { + SetDiff(); + Random rand = new Random(seed); int x, y; for (x = 0; x < w; x++) diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs index aeff730b3b..80abfe5b2e 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Spiral.cs @@ -36,7 +36,6 @@ namespace libTerrain { private double[] CoordinatesToPolar(int x, int y) { - double theta = Math.Atan2(x - (w / 2), y - (h / 2)); double rx = (double)x - ((double)w / 2); double ry = (double)y - ((double)h / 2); @@ -78,6 +77,8 @@ namespace libTerrain public void Polar() { + SetDiff(); + Channel n = this.Copy(); int x, y; @@ -97,6 +98,8 @@ namespace libTerrain public void SpiralPlanter(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle) { + SetDiff(); + int i; double r = offsetRadius; double theta = offsetAngle; @@ -112,6 +115,8 @@ namespace libTerrain public void SpiralCells(int steps, double incAngle, double incRadius, double offsetRadius, double offsetAngle, double[] c) { + SetDiff(); + List points = new List(); int i; @@ -131,6 +136,8 @@ namespace libTerrain public void Spiral(double wid, double hig, double offset) { + SetDiff(); + int x, y, z; z = 0; for (x = 0; x < w; x++) diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs index e973d14f86..eb8f7baa5c 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Voronoi.cs @@ -44,6 +44,8 @@ namespace libTerrain /// The Voronoi diagram type. Usually an array with values consisting of [-1,1]. Experiment with the chain, you can have as many values as you like. public void VoronoiDiagram(int pointsPerBlock, int blockSize, double[] c) { + SetDiff(); + List points = new List(); Random generator = new Random(seed); @@ -103,7 +105,8 @@ namespace libTerrain public void VoronoiDiagram(List points, double[] c) { - + SetDiff(); + Random generator = new Random(seed); int x, y, i; double[] distances = new double[points.Count]; @@ -146,6 +149,8 @@ namespace libTerrain public void VoroflatDiagram(int pointsPerBlock, int blockSize) { + SetDiff(); + List points = new List(); Random generator = new Random(seed); diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs index 38a8023f40..ce36daf2b8 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Generators/Worms.cs @@ -44,6 +44,8 @@ namespace libTerrain /// Do worms start in the middle, or randomly? public void Worms(int number, int rounds, double movement, double size, bool centerspawn) { + SetDiff(); + Random random = new Random(seed); int i, j; diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs index a9106b42d3..a39db50fcd 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Grid.cs @@ -36,6 +36,8 @@ namespace libTerrain { public Channel Normalise() { + SetDiff(); + double max = FindMax(); double min = FindMin(); @@ -54,6 +56,8 @@ namespace libTerrain public Channel Normalise(double minv, double maxv) { + SetDiff(); + double max = FindMax(); double min = FindMin(); @@ -99,7 +103,8 @@ namespace libTerrain double val = map[x, y]; if (val > max) val = max; if (val < min) val = min; - map[x, y] = val; + + Set(x, y, val); } } return this; @@ -132,6 +137,8 @@ namespace libTerrain public Channel AddClip(Channel other) { + SetDiff(); + int x, y; for (x = 0; x < w; x++) { @@ -149,6 +156,8 @@ namespace libTerrain public void Smooth(double amount) { + SetDiff(); + double area = amount; double step = amount / 4.0; @@ -179,6 +188,8 @@ namespace libTerrain public void Pertubation(double amount) { + SetDiff(); + // Simple pertubation filter double[,] manipulated = new double[w, h]; Random generator = new Random(seed); // Seeds FTW! @@ -227,6 +238,7 @@ namespace libTerrain double p = GetBilinearInterpolate(offset_x, offset_y); manipulated[x, y] = p; + SetDiff(x, y); } } map = manipulated; @@ -239,7 +251,7 @@ namespace libTerrain { for (y = 0; y < h; y++) { - map[x, y] = Tools.linearInterpolate(map[x,y],other.map[x,y],amount); + Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount)); } } return this; @@ -252,7 +264,7 @@ namespace libTerrain { for (y = 0; y < h; y++) { - map[x, y] = Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x,y]); + Set(x, y, Tools.linearInterpolate(map[x, y], other.map[x, y], amount.map[x, y])); } } return this; diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs index 198c337049..f4dfe1d2cd 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/AerobicErosion.cs @@ -118,7 +118,7 @@ namespace libTerrain if (surfacearea > pickupTalusMinimum) { - this.map[x, y] -= amount; + Set(x, y, map[x, y] - amount); sediment.map[x, y] += amount; } } @@ -168,7 +168,7 @@ namespace libTerrain if (surfacearea > dropTalusMinimum) { - this.map[x + minside[0], y + minside[1]] += amount; + Set(x + minside[0], y + minside[1], map[x + minside[0], y + minside[1]] + amount); sediment.map[x, y] -= amount; } } diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs index 5ace241440..36da77cb1d 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/HydraulicErosion.cs @@ -36,6 +36,8 @@ namespace libTerrain { public void HydraulicErosion(Channel rain, double evaporation, double solubility, int frequency, int rounds) { + SetDiff(); + Channel water = new Channel(w, h); Channel sediment = new Channel(w, h); Channel terrain = this; diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs index 449bf85703..07c7d66b15 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Manipulators/ThermalWeathering.cs @@ -42,6 +42,8 @@ namespace libTerrain /// The amount of rock to carry each round public Channel ThermalWeathering(double talus, int rounds, double c) { + SetDiff(); + double[,] lastFrame; double[,] thisFrame; diff --git a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs index 623c85c195..3199ddc4b8 100644 --- a/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs +++ b/OpenSim/Region/Terrain.BasicTerrain/libTerrainBSD/Channel/Operators.cs @@ -49,6 +49,9 @@ namespace libTerrain { for (y = 0; y < A.h; y++) { + if (B.map[x, y] != 0) + A.SetDiff(x, y); + A.map[x, y] += B.map[x, y]; } } @@ -73,6 +76,8 @@ namespace libTerrain } } + A.SetDiff(); + return A; } @@ -89,6 +94,8 @@ namespace libTerrain { for (y = 0; y < A.h; y++) { + if (B.map[x, y] != 0) + A.SetDiff(x, y); A.map[x, y] -= B.map[x, y]; } } @@ -113,6 +120,8 @@ namespace libTerrain } } + A.SetDiff(); + return A; } @@ -133,6 +142,8 @@ namespace libTerrain } } + A.SetDiff(); + return A; } @@ -151,6 +162,9 @@ namespace libTerrain } } + if (B != 0) + A.SetDiff(); + return A; } @@ -166,6 +180,9 @@ namespace libTerrain } } + if (B != 0) + A.SetDiff(); + return A; } @@ -181,6 +198,9 @@ namespace libTerrain } } + if (B != 1) + A.SetDiff(); + return A; } @@ -196,6 +216,9 @@ namespace libTerrain } } + if (B != 1) + A.SetDiff(); + return A; } @@ -211,6 +234,8 @@ namespace libTerrain } } + A.SetDiff(); + return A; }