Created
October 13, 2017 12:53
-
-
Save gluschenko/fb05ab8dbefc8c78f888c65e0ba24eb7 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using UnityEngine; | |
using System; | |
using System.Collections.Generic; | |
namespace GeoEngine | |
{ | |
public class WorldEditor | |
{ | |
World World; | |
Offset3 SelectionA, SelectionB; | |
public WorldEditor(World world) | |
{ | |
this.World = world; | |
} | |
public void Select(Offset3 A, Offset3 B) | |
{ | |
SelectionA = A; | |
SelectionB = B; | |
} | |
public void Fill(Brush Shape, Block Block, FillMethod Method = FillMethod.Solid) | |
{ | |
Offset3[] Blocks = GetBlocks(SelectionA, SelectionB, Shape, Method); | |
foreach (Offset3 BlockPos in Blocks) | |
{ | |
World.SetBlock(BlockPos.x, BlockPos.y, BlockPos.z, Block.ID, new Offset3(0, 0, 0), Block.Form); | |
} | |
} | |
public void Stroke(Brush Shape, Block Block) | |
{ | |
Fill(Shape, Block, FillMethod.Stroke); | |
} | |
public void Walls(Brush Shape, Block Block) | |
{ | |
Fill(Shape, Block, FillMethod.Walls); | |
} | |
public void SphereAround(Offset3 Pos, int Radius, Block Block, FillMethod Method = FillMethod.Solid) | |
{ | |
Offset3 A = new Offset3(Pos.x - Radius, Pos.y - Radius, Pos.z - Radius); | |
Offset3 B = new Offset3(Pos.x + Radius, Pos.y + Radius, Pos.z + Radius); | |
Select(A, B); | |
Fill(new Sphere(), Block, Method); | |
} | |
public void CubeAround(Offset3 Pos, int Radius, Block Block, FillMethod Method = FillMethod.Solid) | |
{ | |
Offset3 A = new Offset3(Pos.x - Radius, Pos.y - Radius, Pos.z - Radius); | |
Offset3 B = new Offset3(Pos.x + Radius, Pos.y + Radius, Pos.z + Radius); | |
Select(A, B); | |
Fill(new Cube(), Block, Method); | |
} | |
Offset3[] GetBlocks(Offset3 A, Offset3 B, Brush Shape, FillMethod Method) | |
{ | |
List<Offset3> Blocks = new List<Offset3>(); | |
int ax = Math.Min(A.x, B.x); | |
int bx = Math.Max(A.x, B.x); | |
int ay = Math.Min(A.y, B.y); | |
int by = Math.Max(A.y, B.y); | |
int az = Math.Min(A.z, B.z); | |
int bz = Math.Max(A.z, B.z); | |
for (int x = ax; x < bx; x++) | |
{ | |
for (int z = az; z < bz; z++) | |
{ | |
for (int y = ay; y < by; y++) | |
{ | |
Offset3 NormA = new Offset3(ax, ay, az); | |
Offset3 NormB = new Offset3(bx, by, bz); | |
Offset3 Pos = new Offset3(x, y, z); | |
bool needPlace = false; | |
switch (Method) | |
{ | |
case FillMethod.Solid: | |
needPlace = Shape.Fill(NormA, NormB, Pos); | |
break; | |
case FillMethod.Stroke: | |
needPlace = Shape.Stroke(NormA, NormB, Pos); | |
break; | |
case FillMethod.Walls: | |
needPlace = Shape.Walls(NormA, NormB, Pos); | |
break; | |
} | |
if(needPlace)Blocks.Add(Pos); | |
} | |
} | |
} | |
return Blocks.ToArray(); | |
} | |
} | |
// | |
public class Sphere : Brush | |
{ | |
bool Ready = false; | |
float CenterX, CenterY, CenterZ, SizeX, SizeY, SizeZ; | |
Sphere InnerSphere; | |
public override bool Fill(Offset3 A, Offset3 B, Offset3 Pos) | |
{ | |
if (!Ready) | |
{ | |
CenterX = (A.x + B.x) / 2f; | |
CenterY = (A.y + B.y) / 2f; | |
CenterZ = (A.z + B.z) / 2f; | |
SizeX = Math.Abs(A.x - B.x) / 2f; | |
SizeY = Math.Abs(A.y - B.y) / 2f; | |
SizeZ = Math.Abs(A.z - B.z) / 2f; | |
Ready = true; | |
} | |
float x = (Pos.x - CenterX) / SizeX; | |
float y = (Pos.y - CenterY) / SizeY; | |
float z = (Pos.z - CenterZ) / SizeZ; | |
return Math.Sqrt(x * x + y * y + z * z) <= 1d; | |
} | |
public override bool Stroke(Offset3 A, Offset3 B, Offset3 Pos) | |
{ | |
if (InnerSphere == null) InnerSphere = new Sphere(); | |
int ax = Math.Min(A.x, B.x); | |
int bx = Math.Max(A.x, B.x); | |
int ay = Math.Min(A.y, B.y); | |
int by = Math.Max(A.y, B.y); | |
int az = Math.Min(A.z, B.z); | |
int bz = Math.Max(A.z, B.z); | |
Offset3 InnerA = new Offset3(ax + 1, ay + 1, az + 1); | |
Offset3 InnerB = new Offset3(bx - 1, by - 1, bz - 1); | |
return Fill(A, B, Pos) && !InnerSphere.Fill(InnerA, InnerB, Pos); | |
} | |
} | |
public class Cube : Brush {} | |
public class Brush | |
{ | |
public virtual bool Fill(Offset3 A, Offset3 B, Offset3 Pos) | |
{ | |
return true; | |
} | |
public virtual bool Stroke(Offset3 A, Offset3 B, Offset3 Pos) | |
{ | |
return Pos.x == A.x | |
|| Pos.x == B.x - 1 | |
|| Pos.y == A.y | |
|| Pos.y == B.y - 1 | |
|| Pos.z == A.z | |
|| Pos.z == B.z - 1; | |
} | |
public virtual bool Walls(Offset3 A, Offset3 B, Offset3 Pos) | |
{ | |
return Pos.x == A.x | |
|| Pos.x == B.x - 1 | |
|| Pos.z == A.z | |
|| Pos.z == B.z - 1; | |
} | |
} | |
public enum FillMethod | |
{ | |
Solid, | |
Stroke, | |
Walls, | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment