1 module inochi2d.core.nodes.defstack; 2 import inochi2d.core; 3 import inochi2d.math; 4 import inochi2d; 5 import std.exception : enforce; 6 7 /** 8 A deformation 9 */ 10 struct Deformation { 11 12 /** 13 Deformed values 14 */ 15 vec2[] vertexOffsets; 16 17 void update(vec2[] points) { 18 vertexOffsets = points.dup; 19 } 20 21 this(this) { 22 vertexOffsets = vertexOffsets.dup; 23 } 24 25 Deformation opBinary(string op : "*")(float other) { 26 Deformation new_; 27 28 new_.vertexOffsets.length = vertexOffsets.length; 29 30 foreach(i; 0..vertexOffsets.length) { 31 new_.vertexOffsets[i] = vertexOffsets[i] * other; 32 } 33 34 return new_; 35 } 36 37 Deformation opBinary(string op : "*")(vec2 scale) { 38 Deformation new_; 39 40 new_.vertexOffsets.length = vertexOffsets.length; 41 42 foreach(i; 0..vertexOffsets.length) { 43 new_.vertexOffsets[i] = vec2(vertexOffsets[i].x * scale.x, vertexOffsets[i].y * scale.y); 44 } 45 46 return new_; 47 } 48 49 Deformation opBinary(string op : "+")(Deformation other) { 50 assert(vertexOffsets.length == other.vertexOffsets.length); 51 52 Deformation new_; 53 new_.vertexOffsets.length = vertexOffsets.length; 54 55 foreach(i; 0..vertexOffsets.length) { 56 new_.vertexOffsets[i] = vertexOffsets[i] + other.vertexOffsets[i]; 57 } 58 59 return new_; 60 } 61 62 void serialize(S)(ref S serializer) { 63 import inochi2d.math.serialization : serialize; 64 auto state = serializer.arrayBegin(); 65 foreach(offset; vertexOffsets) { 66 serializer.elemBegin; 67 offset.serialize(serializer); 68 } 69 serializer.arrayEnd(state); 70 } 71 72 SerdeException deserializeFromFghj(Fghj data) { 73 import inochi2d.math.serialization : deserialize; 74 foreach(elem; data.byElement()) { 75 vec2 offset; 76 offset.deserialize(elem); 77 78 vertexOffsets ~= offset; 79 } 80 81 return null; 82 } 83 } 84 85 /** 86 A stack of local deformations to apply to the mesh 87 */ 88 struct DeformationStack { 89 private: 90 Drawable parent; 91 92 public: 93 this(Drawable parent) { 94 this.parent = parent; 95 } 96 97 /** 98 Push deformation on to stack 99 */ 100 void push(ref Deformation deformation) { 101 enforce(this.parent.deformation.length == deformation.vertexOffsets.length, "Mismatched lengths"); 102 foreach(i; 0..this.parent.deformation.length) { 103 this.parent.deformation[i] += deformation.vertexOffsets[i]; 104 } 105 } 106 107 void preUpdate() { 108 foreach(i; 0..this.parent.deformation.length) { 109 this.parent.deformation[i] = vec2(0); 110 } 111 } 112 113 void update() { 114 parent.refreshDeform(); 115 } 116 }