1 /// 2 module isodi.resource; 3 4 import core.time; 5 import std.typecons; 6 7 import rcdata.json; 8 9 import isodi.pack_list; 10 11 12 @safe: 13 14 15 /// Defines an object that makes use of some resources, or is a resource itself. It will be signaled every time the 16 /// pack list is updated. 17 interface WithResources { 18 19 /// Reload the resource's dependencies using the given pack list. 20 /// 21 /// Those dependencies are usually textures, audio files, etc. 22 void reload(); 23 24 } 25 26 /// Defines an object that uses drawable resources, or is one itself. 27 /// 28 /// Note that some renderers, for example Godot, automatically manage drawing and don't let the user draw manually. 29 /// In this case, the `draw` implementation should be omitted. 30 interface WithDrawableResources : WithResources { 31 32 /// Draw this resource, if supported by the renderer. 33 void draw(); 34 35 } 36 37 /// Represents a node in the skeleton. 38 struct SkeletonNode { 39 40 /// Parent index 41 @JSONExclude 42 size_t parent; 43 44 /// If true, this node shouldn't be displayed and its bone resource shouldn't be loaded. 45 bool hidden; 46 47 /// Name of the used bone resource. 48 string name; 49 50 /// ID of the node, defauls to the bone name. Must be unique, so should be defined in case a bone occurs more than 51 /// one time. 52 string id; 53 54 /// List of bone variants compatible with this node. 55 /// 56 /// If this is empty, all variants are allowed. 57 string[] variants; 58 59 /// Offset for the bone's start relative to the parent's end. 60 /// 61 /// If the node is rotated, the whole bone will be rotated relative to this point. 62 float[3] boneStart = [0, 0, 0]; 63 64 /// Position of the bone's end, relative to this node's start. 65 float[3] boneEnd = [0, 0, 0]; 66 67 /// Position of the bone's texture relative to this node's start. 68 float[3] texturePosition = [0, 0, 0]; 69 70 /// Rotation of the node. 71 ushort rotation; 72 invariant(rotation >= 0); 73 invariant(rotation < 360); 74 75 /// $(TCOLON Bone) If true, the bone textures will be mirrored. 76 bool mirror; 77 78 } 79 80 /// Represents a running animation. 81 struct Animation { 82 83 // Constructor properties 84 public { 85 86 /// Frames per second. 87 const float fps = 0; 88 89 /// Amount of times this animation is supposed to play for. 0 for infinite. 90 uint times; 91 92 /// Parts of the animation. 93 AnimationPart[] parts; 94 // TODO: const? 95 96 } 97 98 // Other fields 99 public { 100 101 /// Current frame. 102 float frame = 0; 103 104 /// Current part 105 uint current = 0; 106 107 } 108 109 /// Continue to the next part of the animation. 110 /// Returns: `Yes.ended` if the animation ended. 111 Flag!"ended" advance() { 112 113 // Switch to the next part 114 current += 1; 115 116 // Check if there are more parts 117 if (current < parts.length) return No.ended; 118 119 // Check for infinite playback 120 if (!times) { 121 122 // Reset the animation 123 frame = 0; 124 current = 0; 125 126 return No.ended; 127 128 } 129 130 // Check for repeat and advance to the next loop 131 if (--times) return No.ended; 132 133 // The animation ended 134 return Yes.ended; 135 136 } 137 138 } 139 140 // TODO: Remove the priority field, it just makes the whole process unnecessarily more complex and most likely isn't 141 // needed anyway. Currently it's being ignored anyway. 142 // E: removed from objects, should also be removed from the animation file. 143 144 /// Represents a single part of the animation, it may be a single or a few frames. 145 struct AnimationPart { 146 147 /// Length of the part in frames. 148 uint length = 1; 149 150 /// Change the model offset or position. 151 float[3] offset; 152 153 /// Apply changes to a bone 154 AnimationBone[string] bone; 155 156 } 157 158 /// Changeable bone properties. 159 struct AnimationBone { 160 161 /// Rotate the bone. 162 float[3] rotate; 163 164 /// Rotate the bone. 165 float scale; 166 167 }