1 /// 2 module isodi.position; 3 4 import std.meta; 5 import std.typecons; 6 import std.algorithm; 7 8 /// Represents the height of a cell 9 struct Height { 10 11 /// Position of the cell's top side. 12 float top = 0; 13 14 /// Depth of the cell; how much space does the cell occupy in this column. 15 float depth = 1; 16 17 } 18 19 /// Unique values for locating an object in the 3D space. 20 alias UniquePosition = Tuple!( 21 int, "x", 22 int, "y", 23 int, "layer", 24 ); 25 26 /// Denotes an object's position. 27 alias Position = Tuple!( 28 int, "x", 29 int, "y", 30 int, "layer", 31 Height, "height", 32 ); 33 34 /// Arguments to pass to `multiSort` to sort Object3Ds by `position`. 35 private alias positionSortArgs = AliasSeq!( 36 `a.position.layer < b.position.layer`, 37 `a.position.y < b.position.y`, 38 `a.position.x < b.position.x`, 39 ); 40 41 /// Sort Object3Ds by `position`. 42 alias positionSort = multiSort!positionSortArgs; 43 44 45 @safe: 46 47 48 /// Create a position tuple. 49 Position position(int x, int y, int layer = 0, Height height = Height.init) { 50 51 return Position(x, y, layer, height); 52 53 } 54 55 /// Create a position tuple. 56 Position position(int x, int y, Height height, int layer = 0) { 57 58 return Position(x, y, layer, height); 59 60 } 61 62 /// Create an offset tuple. 63 /// 64 /// Unlike the other position constructors, this will subtract 1 from depth. 65 Position positionOff(int x, int y, Height height = Height.init) { 66 67 height.depth -= 1; 68 69 return Position(x, y, 0, height); 70 71 } 72 73 /// Get the unique position from a Position tuple. 74 inout(UniquePosition) toUnique(inout Position position) { 75 76 return UniquePosition(position.x, position.y, position.layer); 77 78 } 79 80 Position sum(Position a, Position b) { 81 82 return Position( 83 a.x + b.x, 84 a.y + b.y, 85 a.layer + b.layer, 86 Height( 87 a.height.top + b.height.top, 88 a.height.depth + b.height.depth, 89 ) 90 ); 91 92 }