Skip to content

Instantly share code, notes, and snippets.

@gluschenko
Created October 13, 2017 12:53
Show Gist options
  • Save gluschenko/fb05ab8dbefc8c78f888c65e0ba24eb7 to your computer and use it in GitHub Desktop.
Save gluschenko/fb05ab8dbefc8c78f888c65e0ba24eb7 to your computer and use it in GitHub Desktop.
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