mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
Initial work on a perlin noise brush.
This commit is contained in:
parent
3052c098e7
commit
595c8206ef
@ -40,7 +40,7 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
{ "checkered", CheckeredBrush.Process }, { "rainbow", RainbowBrush.Process },
|
||||
{ "bwrainbow", BWRainbowBrush.Process }, { "striped", StripedBrush.Process },
|
||||
{ "replace", ReplaceBrush.Process }, { "replacenot", ReplaceNotBrush.Process },
|
||||
{ "random", RandomBrush.Process },
|
||||
{ "random", RandomBrush.Process }, { "noise", NoiseBrush.Process },
|
||||
};
|
||||
|
||||
public static Dictionary<string, string[]> BrushesHelp = new Dictionary<string, string[]> {
|
||||
@ -48,7 +48,7 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
{ "checkered", CheckeredBrush.HelpString }, { "rainbow", RainbowBrush.HelpString },
|
||||
{ "bwrainbow", BWRainbowBrush.HelpString }, { "striped", StripedBrush.HelpString },
|
||||
{ "replace", ReplaceBrush.HelpString }, { "replacenot", ReplaceNotBrush.HelpString },
|
||||
{ "random", RandomBrush.HelpString },
|
||||
{ "random", RandomBrush.HelpString }, { "noise", NoiseBrush.HelpString },
|
||||
};
|
||||
}
|
||||
|
||||
|
77
Drawing/Brushes/FrequencyBrush.cs
Normal file
77
Drawing/Brushes/FrequencyBrush.cs
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MCGalaxy.Commands;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
public abstract class FrequencyBrush : Brush {
|
||||
|
||||
protected static ExtBlock[] GetBlocks(Player p, string[] parts,
|
||||
int[] count, Predicate<string> filter,
|
||||
Predicate<string> handler) {
|
||||
ExtBlock[] blocks = new ExtBlock[parts.Length];
|
||||
for (int i = 0; i < blocks.Length; i++) {
|
||||
blocks[i].Type = Block.Zero;
|
||||
count[i] = filter(parts[i]) ? 1 : 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < parts.Length; i++ ) {
|
||||
// Brush specific args
|
||||
if (!filter(parts[i])) {
|
||||
if (!handler(parts[i])) return null;
|
||||
continue;
|
||||
}
|
||||
|
||||
byte extType = 0;
|
||||
int sepIndex = parts[i].IndexOf('/');
|
||||
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
|
||||
byte type = DrawCmd.GetBlock(p, block, out extType);
|
||||
if (type == Block.Zero) return null;
|
||||
|
||||
blocks[i].Type = type; blocks[i].ExtType = extType;
|
||||
if (sepIndex < 0) continue;
|
||||
int chance;
|
||||
if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance)
|
||||
|| chance <= 0 || chance > 10000) {
|
||||
Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null;
|
||||
}
|
||||
count[i] = chance;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
protected static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < count.Length; i++) sum += count[i];
|
||||
if (toAffect.Length == 1) sum += 1;
|
||||
|
||||
ExtBlock[] blocks = new ExtBlock[sum];
|
||||
for (int i = 0, index = 0; i < toAffect.Length; i++) {
|
||||
for (int j = 0; j < count[i]; j++)
|
||||
blocks[index++] = toAffect[i];
|
||||
}
|
||||
// For one block argument, leave every other block untouched.
|
||||
if (toAffect.Length == 1)
|
||||
blocks[blocks.Length - 1] = new ExtBlock(Block.Zero, 0);
|
||||
return blocks;
|
||||
}
|
||||
}
|
||||
}
|
76
Drawing/Brushes/NoiseBrush.cs
Normal file
76
Drawing/Brushes/NoiseBrush.cs
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright 2015 MCGalaxy
|
||||
|
||||
Dual-licensed under the Educational Community License, Version 2.0 and
|
||||
the GNU General Public License, Version 3 (the "Licenses"); you may
|
||||
not use this file except in compliance with the Licenses. You may
|
||||
obtain a copy of the Licenses at
|
||||
|
||||
http://www.opensource.org/licenses/ecl2.php
|
||||
http://www.gnu.org/licenses/gpl-3.0.html
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the Licenses are distributed on an "AS IS"
|
||||
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
|
||||
or implied. See the Licenses for the specific language governing
|
||||
permissions and limitations under the Licenses.
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using MCGalaxy.Commands;
|
||||
using MCGalaxy.Drawing.Ops;
|
||||
using MCGalaxy.Generator;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
public sealed class NoiseBrush : FrequencyBrush {
|
||||
readonly ExtBlock[] blocks;
|
||||
readonly ImprovedNoise noise;
|
||||
|
||||
public NoiseBrush(ExtBlock[] blocks) {
|
||||
this.blocks = blocks;
|
||||
noise = new ImprovedNoise(new Random());
|
||||
noise.Octaves = 4;
|
||||
}
|
||||
|
||||
public override string Name { get { return "Noise"; } }
|
||||
|
||||
public override string[] Help { get { return HelpString; } }
|
||||
|
||||
public static string[] HelpString = new [] {
|
||||
"%TArguments: [block1/frequency] [block2]..",
|
||||
"%HDraws by selecting blocks from the given [blocks] using perlin noise.",
|
||||
"%Hfrequency is optional (defaults to 1), and specifies the number of times " +
|
||||
"the block should appear (as a fraction of the total of all the frequencies).",
|
||||
};
|
||||
|
||||
public static Brush Process(BrushArgs args) {
|
||||
if (args.Message == "")
|
||||
return new NoiseBrush(new[] { new ExtBlock(args.Type, args.ExtType),
|
||||
new ExtBlock(Block.Zero, 0) });
|
||||
|
||||
string[] parts = args.Message.Split(' ');
|
||||
int[] count = new int[parts.Length];
|
||||
ExtBlock[] toAffect = GetBlocks(args.Player, parts, count, P => true, null);
|
||||
if (toAffect == null) return null;
|
||||
|
||||
ExtBlock[] blocks = Combine(toAffect, count);
|
||||
return new NoiseBrush(blocks);
|
||||
}
|
||||
|
||||
int next;
|
||||
public override byte NextBlock(DrawOp op) {
|
||||
float N = noise.NormalisedNoise(op.Coords.X, op.Coords.Y, op.Coords.Z);
|
||||
N = (N + 1) * 0.5f; // rescale to [0, 1];
|
||||
next = (int)(N * blocks.Length);
|
||||
|
||||
if (next < 0) next = 0;
|
||||
if (next >= blocks.Length) next = blocks.Length - 1;
|
||||
return blocks[next].Type;
|
||||
}
|
||||
|
||||
public override byte NextExtBlock(DrawOp op) {
|
||||
return blocks[next].ExtType;
|
||||
}
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ using MCGalaxy.Drawing.Ops;
|
||||
|
||||
namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
public sealed class RandomBrush : Brush {
|
||||
public sealed class RandomBrush : FrequencyBrush {
|
||||
readonly ExtBlock[] blocks;
|
||||
readonly int seed;
|
||||
|
||||
@ -49,54 +49,13 @@ namespace MCGalaxy.Drawing.Brushes {
|
||||
|
||||
string[] parts = args.Message.Split(' ');
|
||||
int[] count = new int[parts.Length];
|
||||
ExtBlock[] toAffect = GetBlocks(args.Player, parts.Length, parts, count);
|
||||
ExtBlock[] toAffect = GetBlocks(args.Player, parts, count, P => true, null);
|
||||
if (toAffect == null) return null;
|
||||
|
||||
ExtBlock[] blocks = Combine(toAffect, count);
|
||||
return new RandomBrush(blocks);
|
||||
}
|
||||
|
||||
static ExtBlock[] GetBlocks(Player p, int max, string[] parts, int[] count) {
|
||||
ExtBlock[] blocks = new ExtBlock[max];
|
||||
for (int i = 0; i < blocks.Length; i++) {
|
||||
blocks[i].Type = Block.Zero;
|
||||
count[i] = 1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < max; i++ ) {
|
||||
byte extType = 0;
|
||||
int sepIndex = parts[i].IndexOf('/');
|
||||
string block = sepIndex >= 0 ? parts[i].Substring(0, sepIndex) : parts[i];
|
||||
byte type = DrawCmd.GetBlock(p, block, out extType);
|
||||
if (type == Block.Zero) return null;
|
||||
|
||||
blocks[i].Type = type; blocks[i].ExtType = extType;
|
||||
if (sepIndex < 0) continue;
|
||||
int chance;
|
||||
if (!int.TryParse(parts[i].Substring(sepIndex + 1), out chance) || chance <= 0 || chance > 10000) {
|
||||
Player.Message(p, "frequency must be an integer between 1 and 10,000."); return null;
|
||||
}
|
||||
count[i] = chance;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
static ExtBlock[] Combine(ExtBlock[] toAffect, int[] count) {
|
||||
int sum = 0;
|
||||
for (int i = 0; i < count.Length; i++) sum += count[i];
|
||||
if (toAffect.Length == 1) sum += 1;
|
||||
|
||||
ExtBlock[] blocks = new ExtBlock[sum];
|
||||
for (int i = 0, index = 0; i < toAffect.Length; i++) {
|
||||
for (int j = 0; j < count[i]; j++)
|
||||
blocks[index++] = toAffect[i];
|
||||
}
|
||||
// For one block argument, leave everything else untouched.
|
||||
if (toAffect.Length == 1)
|
||||
blocks[blocks.Length - 1] = new ExtBlock(Block.Zero, 0);
|
||||
return blocks;
|
||||
}
|
||||
|
||||
int next;
|
||||
const int mask = 0x7fffffff;
|
||||
public override byte NextBlock(DrawOp op) {
|
||||
|
@ -431,6 +431,8 @@
|
||||
<Compile Include="Database\SQLite\SQLiteParameterisedQuery.cs" />
|
||||
<Compile Include="Drawing\Brushes\Brush.cs" />
|
||||
<Compile Include="Drawing\Brushes\CheckeredBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\FrequencyBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\NoiseBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\PasteBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\RainbowBrush.cs" />
|
||||
<Compile Include="Drawing\Brushes\RandomBrush.cs" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user