1 /** 2 Inochi2D Animated Part Node 3 4 Copyright: 5 Copyright © 2020-2026, Inochi2D Project 6 7 License: 8 $(LINK2 https://github.com/Inochi2D/inochi2d/blob/main/LICENSE, BSD 2-clause License) 9 10 Authors: 11 Luna Nielsen 12 */ 13 module inochi2d.nodes.visual.animatedpart; 14 import inochi2d.nodes.visual.part; 15 import inochi2d.common; 16 import inochi2d.nodes; 17 import inochi2d.core; 18 19 /** 20 Parts which contain spritesheet animation 21 */ 22 @TypeId("AnimatedPart", IN_MAKE_TAG!(2, 1)) 23 class AnimatedPart : Part { 24 private: 25 @nogc: 26 vec2 frameSize_; 27 vec2u frameCount_; 28 vec2u frame_; 29 30 protected: 31 32 /** 33 Serializes this node to a DataNode. 34 35 Params: 36 object = The DataNode to serialize to. 37 */ 38 override 39 void onSerialize(ref DataNode object) { 40 super.onSerialize(object); 41 42 object["frameSize"] = frameSize_.serialize(); 43 object["frameCount"] = frameCount_.serialize(); 44 } 45 46 /** 47 Deserializes this node from a DataNode. 48 49 Params: 50 object = The DataNode to deserialize from. 51 state = The state of the deserializer. 52 */ 53 override 54 void onDeserialize(ref DataNode object, ref ModelState state) { 55 super.onDeserialize(object, state); 56 57 object.tryGetRef(state, frameSize_, "frameSize"); 58 object.tryGetRef(state, frameCount_, "frameCount"); 59 } 60 61 /** 62 Called when the node is to define its properties. 63 64 Call $(D propList.define) with a quark to do this. 65 66 Params: 67 propList = The property list to populate. 68 */ 69 override 70 void onDefineProperties(ref PropertyStore propList) { 71 super.onDefineProperties(propList); 72 73 propList.define!float(PROP_FRAME_X, 0); 74 propList.define!float(PROP_FRAME_Y, 0); 75 76 // Define combined overlays. 77 propList.defineOverlay!vec3(PROP_FRAME_XY, propList.offsetOf(PROP_FRAME_X)); 78 } 79 80 /** 81 Called during the late update phase of a new frame. 82 83 Params: 84 drawList = The drawlist for the active scene. 85 */ 86 override 87 void onPostUpdate(DrawList drawList) { 88 this.deformedMesh.applyUVOffset(vec2( 89 frameSize_.x * cast(float)frame_.x, 90 frameSize_.y * cast(float)frame_.y, 91 )); 92 super.onPostUpdate(drawList); 93 } 94 95 public: 96 97 /** 98 The size of a single frame in texel coordinates. 99 */ 100 @property ref vec2 frameSize() => frameSize_; 101 102 /** 103 The amount of frames and animations in the animated part. 104 */ 105 @property ref vec2u frameCount() => frameCount_; 106 } 107 108 mixin Register!(AnimatedPart, in_node_registry); 109 // dfmt off 110 111 112 113 114 // 115 // QUARKS 116 // 117 118 mixin RegisterQuarks!(); 119 120 /** 121 X frame index. 122 */ 123 @propkey("frame.xy") 124 __gshared immutable(quark) PROP_FRAME_XY; 125 126 /** 127 X frame index. 128 */ 129 @propkey("frame.x") 130 __gshared immutable(quark) PROP_FRAME_X; 131 132 /** 133 Y frame index. 134 */ 135 @propkey("frame.y") 136 __gshared immutable(quark) PROP_FRAME_Y;