1 /** 2 Copyright: Copyright (c) 2016-2017 Andrey Penechko. 3 License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 4 Authors: Andrey Penechko. 5 */ 6 module voxelman.world.storage.arraycopy; 7 8 import voxelman.math; 9 import voxelman.geometry.box; 10 11 /// writes source to a box within dest 12 void setSubArray(T)( 13 T[] dest, 14 ivec3 destSize, // 7x8x9 15 ivec3 destPos, 16 T[] source, 17 ivec3 sourceSize, // 4x5x6 18 Box sourceBox, // (1,2,3) 2x3x4 19 ) @nogc 20 { 21 assert(dest.length == destSize.x * destSize.y * destSize.z); 22 assert(source.length == sourceSize.x * sourceSize.y * sourceSize.z); 23 24 const auto dest_size_y = destSize.x * destSize.z; // 1 y slice 25 const auto source_size_y = sourceSize.x * sourceSize.z; // 1 y slice 26 27 foreach(y; 0..sourceBox.size.y) 28 foreach(z; 0..sourceBox.size.z) 29 { 30 auto destY = y + destPos.y; 31 auto destZ = z + destPos.z; 32 auto fromDest = destY * dest_size_y + destZ * destSize.x + destPos.x; 33 auto toDest = fromDest + sourceBox.size.x; 34 35 auto sourceY = y + sourceBox.position.y; 36 auto sourceZ = z + sourceBox.position.z; 37 auto fromSource = sourceY * source_size_y + sourceZ * sourceSize.x + sourceBox.position.x; 38 auto toSource = fromSource + sourceBox.size.x; 39 40 dest[fromDest..toDest] = source[fromSource..toSource]; 41 } 42 } 43 44 /// writes full source to a box within dest 45 void setSubArray(T)(T[] dest, ivec3 destSize, Box box, T[] source) @nogc 46 { 47 const int dest_size_y = destSize.x * destSize.z; // 1 y slice 48 assert(dest.length == dest_size_y * destSize.y); 49 assert(source.length == box.volume); 50 51 if (box.position.x == 0 && box.size.x == destSize.x) 52 { 53 if (box.position.z == 0 && box.size.z == destSize.z) 54 { 55 if (box.position.y == 0 && box.size.y == destSize.y) 56 { 57 dest[] = source; 58 } 59 else 60 { 61 auto from = box.position.y * dest_size_y; 62 auto to = (box.position.y + box.size.y) * dest_size_y; 63 dest[from..to] = source; 64 } 65 } 66 else 67 { 68 auto box_size_sqr = box.size.x * box.size.z; 69 foreach(y; box.position.y..(box.position.y + box.size.y)) 70 { 71 auto fromDest = y * dest_size_y + box.position.z * destSize.x; 72 auto toDest = y * dest_size_y + (box.position.z + box.size.z) * destSize.x; 73 auto sourceY = y - box.position.y; 74 auto fromSource = sourceY * box_size_sqr + box.size.z; 75 auto toSource = sourceY * box_size_sqr + box.position.z * box.size.z; 76 dest[fromDest..toDest] = source[fromSource..toSource]; 77 } 78 } 79 } 80 else 81 { 82 int posx = box.position.x; 83 int endx = box.position.x + box.size.x; 84 int endy = box.position.y + box.size.y; 85 int endz = box.position.z + box.size.z; 86 auto box_size_sqr = box.size.x * box.size.z; 87 88 foreach(y; box.position.y..endy) 89 foreach(z; box.position.z..endz) 90 { 91 auto fromDest = y * dest_size_y + z * destSize.x + box.position.x; 92 auto toDest = fromDest + box.size.x; 93 auto sourceY = y - box.position.y; 94 auto sourceZ = z - box.position.z; 95 auto fromSource = sourceY * box_size_sqr + sourceZ * box.size.x; 96 auto toSource = fromSource + box.size.x; 97 98 dest[fromDest..toDest] = source[fromSource..toSource]; 99 } 100 } 101 } 102 103 void setSubArray(T)(T[] dest, ivec3 destSize, Box box, T item) @nogc 104 { 105 const int dest_size_y = destSize.x * destSize.z; // 1 y slice 106 assert(dest.length == destSize.x * destSize.y * destSize.z); 107 108 if (box.position.x == 0 && box.size.x == destSize.x) 109 { 110 if (box.position.z == 0 && box.size.z == destSize.z) 111 { 112 if (box.position.y == 0 && box.size.y == destSize.y) 113 { 114 dest[] = item; 115 } 116 else 117 { 118 auto from = box.position.y * dest_size_y; 119 auto to = (box.position.y + box.size.y) * dest_size_y; 120 dest[from..to] = item; 121 } 122 } 123 else 124 { 125 foreach(y; box.position.y..(box.position.y + box.size.y)) 126 { 127 auto from = y * dest_size_y + box.position.z * destSize.x; 128 auto to = y * dest_size_y + (box.position.z + box.size.z) * destSize.x; 129 dest[from..to] = item; 130 } 131 } 132 } 133 else 134 { 135 int endy = box.position.y + box.size.y; 136 int endz = box.position.z + box.size.z; 137 foreach(y; box.position.y..endy) 138 foreach(z; box.position.z..endz) 139 { 140 auto from = y * dest_size_y + z * destSize.x + box.position.x; 141 auto to = from + box.size.x; 142 dest[from..to] = item; 143 } 144 } 145 }