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;