1 /**
2     Inochi2D C FFI
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.cffi;
14 import inochi2d.common;
15 import inochi2d.effect;
16 import inochi2d.nodes;
17 import inochi2d.param;
18 import inochi2d.core;
19 import nulib.string;
20 import nulib.quark;
21 import numem;
22 
23 // dfmt off
24 
25 version (IN_DYNLIB):
26 extern (C) export @nogc:
27 
28 version (WebAssembly) { }
29 else version = hasFileIO;
30 
31 
32 
33 
34 //
35 //      BASE DATA TYPES
36 //
37 
38 /**
39     2D Vector
40 */
41 struct in_vec2_t {
42     float x;
43     float y;
44 }
45 
46 /**
47     Vertex position vector.
48 */
49 struct in_vtx_t {
50     float x;
51     float y;
52     version (IN_VEC3_POSITION) float z;
53 }
54 
55 /**
56     A single vertex in the renderer.
57 */
58 struct in_vtxdata_t {
59     in_vtx_t vtx;
60     in_vec2_t uv;
61 }
62 
63 /**
64     A GUID.
65 */
66 struct in_guid_t {
67     ubyte[16] data = 0;
68 }
69 
70 /**
71     IO sink functions
72 */
73 struct io_sink_t {
74 
75     /**
76         Error sink to write errors to.
77     */
78     extern (C) void function(const(char)* msg, const(char)* file, uint line) @nogc nothrow error;
79 
80     /**
81         Warning sink to write warnings to.
82     */
83     extern (C) void function(const(char)* msg, const(char)* file, uint line) @nogc nothrow warning;
84 
85     /**
86         Info sink to write informational messages to.
87     */
88     extern (C) void function(const(char)* msg, const(char)* file, uint line) @nogc nothrow info;
89 }
90 
91 
92 
93 
94 //
95 //          TYPEDEFS
96 //
97 
98 /**
99     A quark.
100 */
101 alias quark_t = uint;
102 
103 /**
104     Opaque handle to a puppet.
105 */
106 struct in_puppet_t;
107 
108 /**
109     Opaque handle to a parameter.
110 */
111 struct in_parameter_t;
112 
113 /**
114     Opaque handle for a node.
115 */
116 struct in_node_t;
117 
118 /**
119     Opaque handle for a visual node.
120 */
121 struct in_visual_t;
122 
123 /**
124     Opaque handle for a part node.
125 */
126 struct in_part_t;
127 
128 /**
129     Opaque handle for a animated part node.
130 */
131 struct in_animated_part_t;
132 
133 /**
134     Opaque handle for a compsite node.
135 */
136 struct in_composite_t;
137 
138 /**
139     Opaque handle for a mask node.
140 */
141 struct in_mask_t;
142 
143 /**
144     Opaque handle for a solo node.
145 */
146 struct in_solo_t;
147 
148 /**
149     Opaque handle for a deformer node.
150 */
151 struct in_deformer_t;
152 
153 /**
154     Opaque handle for a bone node.
155 */
156 struct in_bone_t;
157 
158 /**
159     Opaque handle for a bone modifier node.
160 */
161 struct in_bone_modifier_t;
162 
163 /**
164     Opaque handle for a mesh.
165 */
166 struct in_mesh_t;
167 
168 /**
169     Opaque handle for a mesh effect.
170 */
171 struct in_mesh_effect_t;
172 
173 /**
174     Opaque handle for a texture cache.
175 */
176 struct in_texture_cache_t;
177 
178 /**
179     Opaque handle for a resource that can be 
180     transferred between CPU and GPU.
181 */
182 struct in_resource_t;
183 
184 /**
185     Opaque handle for a texture.
186 */
187 struct in_texture_t;
188 
189 /**
190     Opaque handle for a drawlist.
191 */
192 struct in_drawlist_t;
193 
194 
195 
196 
197 //
198 //          CORE API
199 //
200 
201 /**
202     Retains a reference to a Inochi2D Object.
203 
204     Params:
205         obj = The object to retain.
206     
207     Returns:
208         The object.
209 */
210 void* in_retain(void* obj) {
211     return cast(void*)(cast(NuRefCounted)obj).retain();
212 }
213 
214 /**
215     Releases a reference to a Inochi2D Object.
216 
217     Params:
218         obj = The object to release.
219     
220     Returns:
221         The object.
222 */
223 void* in_release(void* obj) {
224     return cast(void*)(cast(NuRefCounted)obj).release();
225 }
226 
227 /**
228     Gets the quark associated with the given key string.
229 
230     Params:
231         key = The key to look up.
232 
233     Returns:
234         The quark for the given key, or 0.
235 */
236 quark_t quarkof(const(char)* key) {
237     return nu_quarkof(cast(string)key.fromStringz());
238 }
239 
240 
241 
242 
243 //
244 //              PUPPET
245 //
246 
247 /**
248     Loads a puppet into memory.
249 
250     Params:
251         file =  The file to load.
252         sink =  Optional IO sink to write messages to.
253     
254     Returns:
255         A new puppet instance, or $(D null) on failure.
256 */
257 version(hasFileIO)
258 in_puppet_t* in_puppet_load(const(char)* file, io_sink_t* sink) {
259     import nulib.string : fromStringz;
260     return cast(in_puppet_t*)Puppet.fromFile(
261         cast(string)file.fromStringz, 
262         sink ? *cast(IOSink*)sink : IOSink.init
263     ).getOr(null);
264 }
265 
266 /**
267     Loads a puppet into memory.
268 
269     Params:
270         data =      The data of the puppet.
271         length =    The length of that data in bytes.
272         sink =      Optional IO sink to write messages to.
273     
274     Returns:
275         A new puppet instance, or $(D null) on failure.
276 */
277 in_puppet_t* in_puppet_load_from_memory(const(ubyte)* data, uint length, io_sink_t* sink) {
278     import nulib.io.stream : MemoryStream;
279     auto stream = nogc_new!MemoryStream(cast(ubyte[])data[0 .. length]);
280     scope (exit) {
281         stream.take();
282         nogc_delete(stream);
283     }
284 
285     return cast(in_puppet_t*)Puppet.fromStream(
286         stream, 
287         sink ? *cast(IOSink*)sink : IOSink.init
288     ).getOr(null);
289 }
290 
291 /**
292     Frees a puppet from memory.
293 
294     Notes:
295         The main Inochi2D type hirearchy hasn't been converted
296         to numem types yet, as such this simply unpins it
297         from the D GC.
298 
299     Params:
300         obj = The puppet object.
301 */
302 void in_puppet_free(in_puppet_t* obj) {
303     if (Puppet puppet = cast(Puppet)cast(NuObject)obj) {
304         nogc_delete(puppet);
305     }
306 }
307 
308 /**
309     Gets the name of a puppet.
310 
311     Params:
312         obj = The puppet object.
313 
314     Returns:
315         The name of the puppet as specified by
316         its author.
317 */
318 const(char)* in_puppet_get_name(in_puppet_t* obj) {
319     auto props = (cast(Puppet)obj).properties;
320     return (props !is null) ? props.name.ptr : null;
321 }
322 
323 /**
324     Gets the author of a puppet.
325 
326     Params:
327         obj = The puppet object.
328 
329     Returns:
330         The author of the puppet.
331 */
332 const(char)* in_puppet_get_author(in_puppet_t* obj) {
333     auto props = (cast(Puppet)obj).properties;
334     return (props !is null) ? props.author.ptr : null;
335 }
336 
337 /**
338     Gets whether to calculate physics for the puppet.
339 
340     Params:
341         obj = The puppet object.
342 
343     Returns:
344         Whether physics are enabled.
345 */
346 bool in_puppet_get_physics_enabled(in_puppet_t* obj) {
347     return (cast(Puppet)obj).enableDrivers;
348 }
349 
350 /**
351     Sets whether to calculate physics for the puppet.
352 
353     Params:
354         obj =   The puppet object.
355         value = The value to set.
356 */
357 void in_puppet_set_physics_enabled(in_puppet_t* obj, bool value) {
358     (cast(Puppet)obj).enableDrivers = value;
359 }
360 
361 /**
362     Gets the pixel-to-meter unit mapping for the physics system.
363 
364     Params:
365         obj = The puppet object.
366 
367     Returns:
368         A value describing how many pixels count as a meter.
369 */
370 float in_puppet_get_pixels_per_meter(in_puppet_t* obj) {
371     return (cast(Puppet)obj).properties.physicsPixelsPerMeter;
372 }
373 
374 /**
375     Sets the pixel-to-meter unit mapping for the physics system.
376 
377     Params:
378         obj =   The puppet object.
379         value = The value to set.
380 */
381 void in_puppet_set_pixels_per_meter(in_puppet_t* obj, float value) {
382     (cast(Puppet)obj).properties.physicsPixelsPerMeter = value;
383 }
384 
385 /**
386     Gets the gravity constant for the puppet.
387 
388     Params:
389         obj = The puppet object.
390 
391     Returns:
392         A value describing how many meters a second gravity
393         pulls on the puppet. Normally is 9.8.
394 */
395 float in_puppet_get_gravity(in_puppet_t* obj) {
396     return (cast(Puppet)obj).properties.physicsGravity;
397 }
398 
399 /**
400     Sets the gravity constant for the puppet.
401 
402     Params:
403         obj =   The puppet object.
404         value = The value to set.
405 */
406 void in_puppet_set_gravity(in_puppet_t* obj, float value) {
407     (cast(Puppet)obj).properties.physicsGravity = value;
408 }
409 
410 /**
411     Updates a puppet.
412 
413     Params:
414         obj = The puppet object.
415         delta = Time since last frame.
416 */
417 void in_puppet_update(in_puppet_t* obj, float delta) {
418     (cast(Puppet)obj).update(delta);
419 }
420 
421 /**
422     Draws a puppet.
423 
424     Params:
425         obj = The puppet object.
426         delta = Time since last frame.
427 */
428 void in_puppet_draw(in_puppet_t* obj, float delta) {
429     (cast(Puppet)obj).draw(delta);
430 }
431 
432 /**
433     Resets the physics state for the puppet.
434 
435     Params:
436         obj = The puppet object.
437 */
438 void in_puppet_reset_drivers(in_puppet_t* obj) {
439     assumeNoThrowNoGC(&(cast(Puppet)obj).resetDrivers);
440 }
441 
442 /**
443     Gets the texture cache belonging to the puppet.
444 
445     Params:
446         obj = The puppet object.
447     
448     Returns:
449         The texture cache associated with the puppet.
450 */
451 in_texture_cache_t* in_puppet_get_texture_cache(in_puppet_t* obj) {
452     return cast(in_texture_cache_t*)(cast(Puppet)obj).textureCache;
453 }
454 
455 /**
456     Gets the parameters of the puppet.
457 
458     Params:
459         obj = The puppet object.
460         count = Where to store the parameter element count.
461     
462     Returns:
463         A puppet-owned array of parameters.
464 */
465 in_parameter_t** in_puppet_get_parameters(in_puppet_t* obj, ref uint count) {
466     count = cast(uint)(cast(Puppet)obj).parameters.length;
467     return cast(in_parameter_t**)(cast(Puppet)obj).parameters.ptr;
468 }
469 
470 /**
471     Gets the puppet's draw list.
472 
473     Params:
474         obj = The puppet object.
475     
476     Returns:
477         The drawlist used by the puppet.
478 */
479 in_drawlist_t* in_puppet_get_drawlist(in_puppet_t* obj) {
480     return cast(in_drawlist_t*)(cast(Puppet)obj).drawList;
481 }
482 
483 /**
484     Gets the root node of the puppet.
485 
486     Params:
487         self = The puppet object.
488 
489     Returns:
490         The root node of the puppet, or $(D null) on failure.
491 */
492 in_node_t* in_puppet_get_root_node(in_puppet_t* self) {
493     if (Puppet n_self = cast(Puppet)self)
494         return cast(in_node_t*)n_self.root;
495 
496     return null;
497 }
498 
499 
500 
501 
502 //
503 //              PARAMETERS
504 //
505 
506 /**
507     Gets the name of the parameter.
508     
509     Params:
510         obj = The parameter object.
511     
512     Returns:
513         The name of the parameter.
514 */
515 const(char)* in_parameter_get_name(in_parameter_t* obj) {
516     return (cast(Parameter)obj).name.ptr;
517 }
518 
519 /**
520     Gets whether the parameter is active.
521     
522     Params:
523         obj = The parameter object.
524     
525     Returns:
526         $(D true) if the parameter is active,
527         $(D false) otherwise.
528 */
529 bool in_parameter_get_active(in_parameter_t* obj) {
530     return (cast(Parameter)obj).active;
531 }
532 
533 /**
534     Gets how many dimensions the parameter has.
535     
536     Params:
537         obj = The parameter object.
538     
539     Returns:
540         A number which indicates how many dimensions
541         the parameter has.
542 */
543 uint in_parameter_get_dimensions(in_parameter_t* obj) {
544     return (cast(Parameter)obj).dimensions;
545 }
546 
547 /**
548     Gets the parameter's lower bounds.
549     
550     Params:
551         obj = The parameter object.
552     
553     Returns:
554         Pointer to a series of parameter-owned floats,
555         use $(D in_parameter_get_dimensions) to get the dimensionality.
556 */
557 const(float)* in_parameter_get_lower_bounds(in_parameter_t* obj) {
558     return (cast(Parameter)obj).lowerBound.ptr;
559 }
560 
561 /**
562     Gets the parameter's upper bounds.
563     
564     Params:
565         obj = The parameter object.
566     
567     Returns:
568         Pointer to a series of parameter-owned floats,
569         use $(D in_parameter_get_dimensions) to get the dimensionality.
570 */
571 const(float)* in_parameter_get_upper_bounds(in_parameter_t* obj) {
572     return (cast(Parameter)obj).upperBound.ptr;
573 }
574 
575 /**
576     Gets the parameter's current value.
577     
578     Params:
579         obj = The parameter object.
580     
581     Returns:
582         Pointer to a series of parameter-owned floats,
583         use $(D in_parameter_get_dimensions) to get the dimensionality.
584 */
585 float* in_parameter_get_value(in_parameter_t* obj) {
586     return (cast(Parameter)obj).currentValue.ptr;
587 }
588 
589 /**
590     Sets the parameter's current value.
591     
592     Params:
593         obj =       The parameter object.
594         values =    The values to set for the parameter.
595 */
596 void in_parameter_set_value(in_parameter_t* obj, float* values) {
597     size_t dims = (cast(Parameter)obj).dimensions;
598     (cast(Parameter)obj).currentValue[0 .. dims] = values[0 .. dims];
599 }
600 
601 
602 
603 
604 //
605 //              TEXTURE CACHE
606 //
607 
608 /**
609     Gets the size (amount of textures) of the texture cache.
610 
611     Params:
612         obj = The texture cache object.
613 
614     Returns:
615         The amount of textures within the cache.
616 */
617 uint in_texture_cache_get_size(in_texture_cache_t* obj) {
618     return cast(uint)(cast(TextureCache)obj).size;
619 }
620 
621 /**
622     Gets a texture from the cache.
623 
624     Params:
625         obj = The texture cache object.
626         slot = The slot to get the texture from.
627 
628     Returns:
629         The requested texture if found,
630         otherwise $(D null).
631 */
632 in_texture_t* in_texture_cache_get_texture(in_texture_cache_t* obj, uint slot) {
633     return cast(in_texture_t*)(cast(TextureCache)obj).get(slot);
634 }
635 
636 /**
637     Gets a texture from the cache.
638 
639     Params:
640         obj = The texture cache object.
641         count = Where to store the texture count.
642 
643     Returns:
644         A puppet-owned array of textures.
645 */
646 in_texture_t** in_texture_cache_get_textures(in_texture_cache_t* obj, ref uint count) {
647     count = cast(uint)(cast(TextureCache)obj).size;
648     return cast(in_texture_t**)(cast(TextureCache)obj).cache.ptr;
649 }
650 
651 /**
652     Prunes the texture cache of unreferenced textures.
653 
654     Params:
655         obj = The texture cache object.
656 */
657 void in_texture_cache_prune(in_texture_cache_t* obj) {
658     (cast(TextureCache)obj).prune();
659 }
660 
661 
662 
663 
664 //
665 //              NODE
666 //
667 
668 /**
669     Creates a new basic node, optionally parented to the given node.
670 
671     Params:
672         parent = The parent of the newly created node, or null.
673     
674     Returns:
675         The newly allocated node.
676 */
677 in_node_t* in_node_new(in_node_t* parent) {
678     return cast(in_node_t*)nogc_new!Node(cast(Node)parent);
679 }
680 
681 /**
682     Gets the name of the node.
683 
684     Params:
685         self = The node to operate on.
686 
687     Returns:
688         The name of the node.
689 */
690 const(char)* in_node_get_name(in_node_t* self) {
691     if (Node n_self = cast(Node)self)
692         return n_self.name.ptr;
693 
694     return null;
695 }
696 
697 /**
698     Gets the type of the node.
699 
700     Params:
701         self = The node to operate on.
702 
703     Returns:
704         The type id of the node.
705 */
706 const(char)* in_node_get_type(in_node_t* self) {
707     if (Node n_self = cast(Node)self)
708         return n_self.typeId.sid.ptr;
709 
710     return null;
711 }
712 
713 /**
714     Gets the GUID of a node.
715 
716     Params:
717         self =  The node to operate on.
718 
719     Returns:
720         A pointer to node-owned GUID data,
721         $(D null) on failure.
722 */
723 const(in_guid_t)* in_node_get_guid(in_node_t* self) {
724     if (Node n_self = cast(Node)self) {
725         return cast(in_guid_t*)n_self.guid.data.ptr;
726     }
727     return null;
728 }
729 
730 /**
731     Gets the puppet that the node belongs to.
732 
733     Params:
734         self = The node to operate on.
735     
736     Returns:
737         The parent puppet or $(D null) if puppet is unrooted.
738 */
739 in_puppet_t* in_node_get_puppet(in_node_t* self) {
740     if (Node n_self = cast(Node)self)
741         return cast(in_puppet_t*)n_self.puppet;
742     return null;
743 }
744 
745 /**
746     Gets the parent node of the given node.
747 
748     Params:
749         self = The node to operate on.
750     
751     Returns:
752         Pointer to the parent node, or $(D null)
753         if the node is the root of its tree.
754 */
755 in_node_t* in_node_get_parent(in_node_t* self) {
756     if (Node n_self = cast(Node)self)
757         return cast(in_node_t*)n_self.parent;
758     return null;
759 }
760 
761 /**
762     Sets the parent of the given node.
763 
764     Params:
765         self =      The node to operate on.
766         parent =    The parent to set, or $(D null).
767 */
768 void in_node_set_parent(in_node_t* self, in_node_t* parent) {
769     if (Node n_self = cast(Node)self)
770         n_self.parent = cast(Node)parent;
771 }
772 
773 /**
774     Gets the child nodes of the given node.
775 
776     Params:
777         self =  The node to operate on.
778         count = Where to store the node count.
779 
780     Returns:
781         A node-owned array of nodes.
782 */
783 in_node_t** in_node_get_children(in_node_t* self, uint* count) {
784     if (Node n_self = cast(Node)self) {
785         *count = cast(uint)n_self.children.length;
786         return cast(in_node_t**)n_self.children.ptr;
787     }
788 
789     return null;
790 }
791 
792 /**
793     Gets whether the node is enabled.
794 
795     Params:
796         self = The node to operate on.
797 
798     Returns:
799         $(D true) if the node is enabled,
800         $(D false) otherwise.
801 */
802 bool in_node_get_enabled(in_node_t* self) {
803     if (Node n_self = cast(Node)self)
804         return n_self.enabled;
805 
806     return false;
807 }
808 
809 /**
810     Sets whether the node is enabled.
811 
812     Params:
813         self =  The node to operate on.
814         value = The value to set.
815 */
816 void in_node_set_enabled(in_node_t* self, bool value) {
817     if (Node n_self = cast(Node)self)
818         n_self.enabled = value;
819 }
820 
821 /**
822     Gets whether the node's transform is locked to the root
823     node.
824 
825     Params:
826         self = The node to operate on.
827 
828     Returns:
829         $(D true) if the transformation of the node is locked
830         to the root node, $(D false) otherwise.
831 */
832 bool in_node_get_lock_to_root(in_node_t* self) {
833     if (Node n_self = cast(Node)self)
834         return n_self.lockToRoot;
835 
836     return false;
837 }
838 
839 /**
840     Sets whether the node's transform is locked to the root
841     node.
842 
843     Params:
844         self =  The node to operate on.
845         value = The value to set.
846 */
847 void in_node_set_lock_to_root(in_node_t* self, bool value) {
848     if (Node n_self = cast(Node)self)
849         n_self.lockToRoot = value;
850 }
851 
852 /**
853     Gets the depth of the node in the node tree.
854 
855     Params:
856         self =  The node to operate on.
857     
858     Returns:
859         The depth of the node in the tree.
860 */
861 uint in_node_get_tree_depth(in_node_t* self) {
862     if (Node n_self = cast(Node)self)
863         return n_self.depth;
864 
865     return 0;
866 }
867 
868 /**
869     Gets whether the node has the given property.
870 
871     Params:
872         self =  The node to operate on.
873         key =   Name of the property to query.
874     
875     Returns:
876         $(D true) if the node has the given property,
877         $(D false) otherwise.
878 */
879 bool in_node_has_property(in_node_t* self, quark_t key) {
880     if (key) {
881         if (Node n_self = cast(Node)self)
882             return n_self.hasProperty(key);
883     }
884     return false;
885 }
886 
887 /**
888     Gets the value of the given property.
889 
890     Params:
891         self =  The node to operate on.
892         key =   Name of the property to query.
893     
894     Returns:
895         The value of the property.
896 */
897 float in_node_get_property(in_node_t* self, quark_t key) {
898     if (key) {
899         if (Node n_self = cast(Node)self)
900             return n_self.getProperty(key);
901     }
902     return 0;
903 }
904 
905 /**
906     Gets the default value of the given property.
907 
908     Params:
909         self =  The node to operate on.
910         key =   Name of the property to query.
911     
912     Returns:
913         The default value of the property.
914 */
915 float in_node_get_property_default(in_node_t* self, quark_t key) {
916     if (key) {
917         if (Node n_self = cast(Node)self)
918             return n_self.getPropertyDefault(key);
919     }
920     return 0;
921 }
922 
923 /**
924     Sets the value of the given property.
925 
926     Params:
927         self =  The node to operate on.
928         key =   Name of the property to query.
929         value = Value to assign the property to.
930     
931     Returns:
932         The default value of the property.
933 */
934 void in_node_set_property(in_node_t* self, quark_t key, float value) {
935     if (key) {
936         if (Node n_self = cast(Node)self)
937             return n_self.setProperty(key, value);
938     }
939 }
940 
941 /**
942     Resets the value of the given property.
943 
944     Params:
945         self =  The node to operate on.
946         key =   Name of the property to query.
947 */
948 void in_node_reset_property(in_node_t* self, quark_t key) {
949     if (key) {
950         if (Node n_self = cast(Node)self)
951             return n_self.resetProperty(key);
952     }
953 }
954 
955 /**
956     Resets the values of all properties in the node.
957 
958     Params:
959         self =  The node to operate on.
960 */
961 void in_node_reset_properties(in_node_t* self) {
962     if (Node n_self = cast(Node)self)
963         return n_self.resetProperties();
964 }
965 
966 /**
967     Gets all the property keys for the given node.
968     
969     Params:
970         self =  The node to operate on.
971         count = Variable to store the quark count in.
972 
973     Returns:
974         A pointer to the key list of the node on success,
975         $(D null) otherwise.
976 */
977 const(quark_t)* in_node_get_properties(in_node_t* self, ref uint count) {
978     if (Node n_self = cast(Node)self) {
979         count = cast(uint)n_self.props.keys.length;
980         return cast(const(quark_t)*)n_self.props.keys.ptr;
981     }
982     return null;
983 }
984 
985 
986 
987 
988 //
989 //              VISUALS
990 //
991 
992 /**
993     Casts the given node to a visual.
994 
995     Params:
996         self =  The node to operate on.
997 
998     Returns:
999         A $(D in_visual_t*) representing the Visual,
1000         $(D null) if the cast failed.
1001 */
1002 in_visual_t* in_as_visual(in_node_t* self) {
1003     return cast(in_visual_t*)(cast(Visual)(cast(Node)self));
1004 }
1005 
1006 /**
1007     Gets whether the renderer should delegate 
1008     rendering logic to the visual node.
1009 
1010     Params:
1011         self =  The visual to operate on.
1012     
1013     Returns:
1014         $(D true) if the visual is delegated,
1015         $(D false) otherwise.
1016 */
1017 bool in_visual_get_is_delegated(in_visual_t* self) {
1018     if (auto visual = cast(Visual)self)
1019         return visual.isDelegated;
1020     return false;
1021 }
1022 
1023 /**
1024     Gets whether the node can be used as a 
1025     source of masking operations.
1026 
1027     Params:
1028         self =  The visual to operate on.
1029     
1030     Returns:
1031         $(D true) if the visual can be used for masking,
1032         $(D false) otherwise.
1033 */
1034 bool in_visual_get_is_masking(in_visual_t* self) {
1035     if (auto visual = cast(Visual)self)
1036         return visual.isMasking;
1037     return false;
1038 }
1039 
1040 /**
1041     Gets the z-sorting value of the given visual.
1042 
1043     Params:
1044         self =  The visual to operate on.
1045     
1046     Returns:
1047         The z-sorting value of the visual.
1048 */
1049 int in_visual_get_zsort(in_visual_t* self) {
1050     if (auto visual = cast(Visual)self)
1051         return visual.zSort;
1052     return 0;
1053 }
1054 
1055 /**
1056     Sets the z-sorting value of the given visual.
1057 
1058     Params:
1059         self =  The visual to operate on.
1060         value = The value to set.
1061 */
1062 void in_visual_set_zsort(in_visual_t* self, int value) {
1063     if (auto visual = cast(Visual)self)
1064         visual.zSort = value;
1065 }
1066 
1067 /**
1068     Gets the render-time z-sorting value for the
1069     given visual.
1070 
1071     Params:
1072         self =  The visual to operate on.
1073     
1074     Returns:
1075         The z-sorting value of the visual.
1076 */
1077 int in_visual_get_zsort_render(in_visual_t* self) {
1078     if (auto visual = cast(Visual)self)
1079         return cast(int)visual.zSortRender;
1080     return 0;
1081 }
1082 
1083 
1084 
1085 
1086 //
1087 //              PARTS
1088 //
1089 
1090 /**
1091     Casts the given node to a part.
1092 
1093     Params:
1094         self =  The node to operate on.
1095 
1096     Returns:
1097         A $(D in_part_t*) representing the part,
1098         $(D null) if the cast failed.
1099 */
1100 in_part_t* in_as_part(in_node_t* self) {
1101     return cast(in_part_t*)(cast(Part)(cast(Node)self));
1102 }
1103 
1104 /**
1105     Gets the mesh of a part.
1106 
1107     Params:
1108         self =  The part to operate on.
1109     
1110     Returns:
1111         The mesh of the part if present,
1112         $(D null) otherwise.
1113 */
1114 in_mesh_t* in_part_get_mesh(in_part_t* self) {
1115     if (auto n_self = cast(Part)self)
1116         return cast(in_mesh_t*)n_self.mesh;
1117     return null;
1118 }
1119 
1120 /**
1121     Gets the blending mode of the given part.
1122 
1123     Params:
1124         self =  The part to operate on.
1125 
1126     Returns:
1127         The blending mode of the part.
1128 */
1129 in_blend_mode_t in_part_get_blend_mode(in_part_t* self) {
1130     if (auto n_self = cast(Part)self)
1131         return cast(in_blend_mode_t)n_self.blendingMode;
1132 
1133     return IN_BLEND_MODE_NORMAL;
1134 }
1135 
1136 /**
1137     Sets the blending mode of the given part.
1138 
1139     Params:
1140         self =  The part to operate on.
1141         value = The value to set.
1142 */
1143 void in_part_set_blend_mode(in_part_t* self, in_blend_mode_t value) {
1144     if (auto n_self = cast(Part)self)
1145         n_self.blendingMode = cast(BlendMode)value;
1146 }
1147 
1148 /**
1149     Gets the opacity of the given part.
1150 
1151     Params:
1152         self =  The part to operate on.
1153 
1154     Returns:
1155         The opacity of the part.
1156 */
1157 float in_part_get_opacity(in_part_t* self) {
1158     if (auto n_self = cast(Part)self)
1159         return n_self.opacity;
1160 
1161     return 1;
1162 }
1163 
1164 /**
1165     Sets the opacity of the given part.
1166 
1167     Params:
1168         self =  The part to operate on.
1169         value = The value to set.
1170 */
1171 void in_part_set_opacity(in_part_t* self, float value) {
1172     if (auto n_self = cast(Part)self)
1173         n_self.opacity = clamp(value, 0, 1);
1174 }
1175 
1176 /**
1177     Gets the emission strength of the given part.
1178 
1179     Params:
1180         self =  The part to operate on.
1181 
1182     Returns:
1183         The opacity of the part.
1184 */
1185 float in_part_get_emission(in_part_t* self) {
1186     if (auto n_self = cast(Part)self)
1187         return n_self.emissionStrength;
1188 
1189     return 1;
1190 }
1191 
1192 /**
1193     Sets the emission strength of the given part.
1194 
1195     Params:
1196         self =  The part to operate on.
1197         value = The value to set.
1198 */
1199 void in_part_set_emission(in_part_t* self, float value) {
1200     if (auto n_self = cast(Part)self)
1201         n_self.emissionStrength = value;
1202 }
1203 
1204 /**
1205     Adds a mesh effect to the part.
1206 
1207     Params:
1208         self =      The part to operate on.
1209         effect =    The mesh effect to add.
1210 */
1211 void in_part_add_effect(in_part_t* self, in_mesh_effect_t* effect) {
1212     if (auto n_self = cast(Part)self)
1213         n_self.addEffect(cast(MeshEffect)effect);
1214 }
1215 
1216 /**
1217     Removes a given mesh effect from the part.
1218 
1219     Params:
1220         self =      The part to operate on.
1221         effect =    The effect to remove.
1222 */
1223 void in_part_remove_effect(in_part_t* self, in_mesh_effect_t* effect) {
1224     if (auto n_self = cast(Part)self)
1225         n_self.removeEffect(cast(MeshEffect)effect);
1226 }
1227 
1228 /**
1229     Gets the mesh effects attached to a node.
1230 
1231     Params:
1232         self =      The part to operate on.
1233         count = Variablt to store the effect count in.
1234     
1235     Returns:
1236         A Part-owned array of mesh effects.
1237 */
1238 in_mesh_effect_t** in_node_part_get_mesh_effects(in_part_t* self, ref uint count) {
1239     if (auto n_self = cast(Part)self) {
1240         count = cast(uint)n_self.effects.length;
1241         return cast(in_mesh_effect_t**)n_self.effects.ptr;
1242     }
1243     return null;
1244 }
1245 
1246 
1247 
1248 
1249 //
1250 //              ANIMATED PARTS
1251 //
1252 
1253 /**
1254     Casts the given node to a animated part.
1255 
1256     Params:
1257         self =  The node to operate on.
1258 
1259     Returns:
1260         A $(D in_animated_part_t*) representing the animated part,
1261         $(D null) if the cast failed.
1262 */
1263 in_animated_part_t* in_as_animated_part(in_node_t* self) {
1264     return cast(in_animated_part_t*)(cast(AnimatedPart)(cast(Node)self));
1265 }
1266 
1267 // TODO: Add the API.
1268 
1269 
1270 
1271 
1272 
1273 //
1274 //              COMPOSITES
1275 //
1276 
1277 /**
1278     Casts the given node to a composite.
1279 
1280     Params:
1281         self =  The node to operate on.
1282 
1283     Returns:
1284         A $(D in_composite_t*) representing the composite,
1285         $(D null) if the cast failed.
1286 */
1287 in_composite_t* in_as_composite(in_node_t* self) {
1288     return cast(in_composite_t*)(cast(Composite)(cast(Node)self));
1289 }
1290 
1291 /**
1292     Gets the blending mode of the given composite.
1293 
1294     Params:
1295         self =  The composite to operate on.
1296 
1297     Returns:
1298         The blending mode of the composite.
1299 */
1300 in_blend_mode_t in_composite_get_blend_mode(in_composite_t* self) {
1301     if (auto n_self = cast(Composite)self)
1302         return cast(in_blend_mode_t)n_self.blendingMode;
1303 
1304     return IN_BLEND_MODE_NORMAL;
1305 }
1306 
1307 /**
1308     Sets the blending mode of the given composite.
1309 
1310     Params:
1311         self =  The composite to operate on.
1312         value = The value to set.
1313 */
1314 void in_composite_set_blend_mode(in_composite_t* self, in_blend_mode_t value) {
1315     if (auto n_self = cast(Composite)self)
1316         n_self.blendingMode = cast(BlendMode)value;
1317 }
1318 
1319 /**
1320     Gets the opacity of the given composite.
1321 
1322     Params:
1323         self =  The composite to operate on.
1324 
1325     Returns:
1326         The opacity of the composite.
1327 */
1328 float in_composite_get_opacity(in_composite_t* self) {
1329     if (auto n_self = cast(Composite)self)
1330         return n_self.opacity;
1331 
1332     return 1;
1333 }
1334 
1335 /**
1336     Sets the opacity of the given composite.
1337 
1338     Params:
1339         self =  The composite to operate on.
1340         value = The value to set.
1341 */
1342 void in_composite_set_opacity(in_composite_t* self, float value) {
1343     if (auto n_self = cast(Composite)self)
1344         n_self.opacity = clamp(value, 0, 1);
1345 }
1346 
1347 
1348 
1349 
1350 //
1351 //              MASKS
1352 //
1353 
1354 /**
1355     Casts the given node to a mask.
1356 
1357     Params:
1358         self =  The node to operate on.
1359 
1360     Returns:
1361         A $(D in_mask_t*) representing the mask,
1362         $(D null) if the cast failed.
1363 */
1364 in_mask_t* in_as_mask(in_node_t* self) {
1365     return cast(in_mask_t*)(cast(Mask)(cast(Node)self));
1366 }
1367 
1368 // TODO: Add the API.
1369 
1370 
1371 
1372 
1373 //
1374 //              SOLOS
1375 //
1376 
1377 /**
1378     Casts the given node to a solo.
1379 
1380     Params:
1381         self =  The node to operate on.
1382 
1383     Returns:
1384         A $(D in_solo_t*) representing the solo,
1385         $(D null) if the cast failed.
1386 */
1387 in_solo_t* in_as_solo(in_node_t* self) {
1388     return cast(in_solo_t*)(cast(Solo)(cast(Node)self));
1389 }
1390 
1391 // TODO: Add the API.
1392 
1393 
1394 
1395 
1396 //
1397 //              DEFORMERS
1398 //
1399 
1400 /**
1401     Casts the given node to a deformer.
1402 
1403     Params:
1404         self =  The node to operate on.
1405 
1406     Returns:
1407         A $(D in_deformer_t*) representing the deformer,
1408         $(D null) if the cast failed.
1409 */
1410 in_deformer_t* in_as_deformer(in_node_t* self) {
1411     return cast(in_deformer_t*)(cast(Deformer)(cast(Node)self));
1412 }
1413 
1414 // TODO: Add the API.
1415 
1416 
1417 
1418 //
1419 //              BONES
1420 //
1421 
1422 /**
1423     Casts the given node to a bone.
1424 
1425     Params:
1426         self =  The node to operate on.
1427 
1428     Returns:
1429         A $(D in_bone_t*) representing the bone,
1430         $(D null) if the cast failed.
1431 */
1432 in_bone_t* in_as_bone(in_node_t* self) {
1433     return cast(in_bone_t*)(cast(Bone)(cast(Node)self));
1434 }
1435 
1436 // TODO: Add the API.
1437 
1438 
1439 
1440 //
1441 //              BONE MODIFIERS
1442 //
1443 
1444 /**
1445     Casts the given node to a bone modifier.
1446 
1447     Params:
1448         self =  The node to operate on.
1449 
1450     Returns:
1451         A $(D in_bone_modifier_t*) representing the solo,
1452         $(D null) if the cast failed.
1453 */
1454 in_bone_modifier_t* in_as_bone_modifier(in_node_t* self) {
1455     return cast(in_bone_modifier_t*)(cast(BoneModifier)(cast(Node)self));
1456 }
1457 
1458 // TODO: Add the API.
1459 
1460 
1461 
1462 
1463 //
1464 //              RESOURCES
1465 //
1466 
1467 /**
1468     Gets the length of the resource in bytes.
1469 
1470     Params:
1471         obj = The resource object.
1472     
1473     Returns:
1474         The length of the resource's GPU memory allocation
1475         in bytes.
1476 */
1477 uint in_resource_get_length(in_resource_t* obj) {
1478     return (cast(Resource)obj).length;
1479 }
1480 
1481 /**
1482     Gets the renderer ID of the resource.
1483 
1484     Params:
1485         obj = The resource object.
1486     
1487     Returns:
1488         The renderer ID of the resource.
1489 */
1490 void* in_resource_get_id(in_resource_t* obj) {
1491     return cast(void*)(cast(Resource)obj).id;
1492 }
1493 
1494 /**
1495     Sets the renderer ID of the resource.
1496 
1497     Params:
1498         obj = The resource object.
1499         value = The value to set.
1500 */
1501 void in_resource_set_id(in_resource_t* obj, void* value) {
1502     (cast(Resource)obj).id = value;
1503 }
1504 
1505 
1506 
1507 
1508 //
1509 //              TEXTURES
1510 //
1511 
1512 /**
1513     Creates a texture from a resource.
1514 
1515     Params:
1516         obj = The resource object.
1517     
1518     Returns:
1519         The texture object that is represented by the
1520         resource, or $(D null) if the resource is not
1521         a texture.
1522 */
1523 in_texture_t* in_texture_from_resource(in_resource_t* obj) {
1524     return cast(in_texture_t*)(cast(Texture)(cast(Resource)obj));
1525 }
1526 
1527 /**
1528     Gets the width of the texture in pixels.
1529 
1530     Params:
1531         obj = The texture object.
1532 
1533     Returns:
1534         The width of the texture in pixels.
1535 */
1536 uint in_texture_get_width(in_texture_t* obj) {
1537     return (cast(Texture)obj).width;
1538 }
1539 
1540 /**
1541     Gets the height of the texture in pixels.
1542 
1543     Params:
1544         obj = The texture object.
1545 
1546     Returns:
1547         The height of the texture in pixels.
1548 */
1549 uint in_texture_get_height(in_texture_t* obj) {
1550     return (cast(Texture)obj).height;
1551 }
1552 
1553 /**
1554     Gets the channels of the texture.
1555 
1556     Params:
1557         obj = The texture object.
1558 
1559     Returns:
1560         The channel count of the texture.
1561 */
1562 uint in_texture_get_channels(in_texture_t* obj) {
1563     return (cast(Texture)obj).channels;
1564 }
1565 
1566 /**
1567     Flips the texture's data vertically.
1568     Some engines read in a different direction from Inochi2D.
1569 
1570     Params:
1571         obj = The texture object.
1572 */
1573 void in_texture_flip_vertically(in_texture_t* obj) {
1574     (cast(Texture)obj).data.vflip();
1575 }
1576 
1577 /**
1578     Premultiplies the alpha channel of the texture.
1579 
1580     Params:
1581         obj = The texture object.
1582 */
1583 void in_texture_premultiply(in_texture_t* obj) {
1584     (cast(Texture)obj).data.premultiply();
1585 }
1586 
1587 /**
1588     Un-premultiplies the alpha channel of the texture.
1589 
1590     Params:
1591         obj = The texture object.
1592 */
1593 void in_texture_unpremultiply(in_texture_t* obj) {
1594     (cast(Texture)obj).data.unpremultiply();
1595 }
1596 
1597 /**
1598     Pads the texture with a border.
1599 
1600     Params:
1601         obj =       The texture object.
1602         thickness = Thickness of the border in pixels.
1603 */
1604 void in_texture_pad(in_texture_t* obj, uint thickness) {
1605     (cast(Texture)obj).data.pad(thickness);
1606 }
1607 
1608 /**
1609     Gets the pixels of the texture.
1610 
1611     Params:
1612         obj = The texture object.
1613 
1614     Returns:
1615         The pixels of the texture.
1616 */
1617 void* in_texture_get_pixels(in_texture_t* obj) {
1618     return (cast(Texture)obj).pixels.ptr;
1619 }
1620 
1621 
1622 
1623 
1624 //
1625 //              DRAWLIST
1626 //
1627 
1628 /**
1629     DrawState flags
1630 */
1631 alias in_drawstate_t = uint;
1632 enum : in_drawstate_t {
1633     IN_DRAW_STATE_NORMAL            = 0,
1634     IN_DRAW_STATE_DEFINE_MASK       = 1,
1635     IN_DRAW_STATE_PUSH_MASK         = 2,
1636     IN_DRAW_STATE_POP_MASK          = 3,
1637     IN_DRAW_STATE_COMPOSITE_BEGIN   = 4,
1638     IN_DRAW_STATE_COMPOSITE_END     = 5,
1639     IN_DRAW_STATE_COMPOSITE_BLIT    = 6
1640 }
1641 
1642 /**
1643     Masking modes
1644 */
1645 alias in_mask_mode_t = uint;
1646 enum : in_mask_mode_t {
1647     IN_MASK_MODE_MASK   = 0,
1648     IN_MASK_MODE_DODGE  = 1
1649 }
1650 
1651 /**
1652     Blending modes
1653 */
1654 alias in_blend_mode_t = uint;
1655 enum : in_blend_mode_t { 
1656     IN_BLEND_MODE_NORMAL        = 0x00,
1657     IN_BLEND_MODE_MULTIPLY      = 0x01,
1658     IN_BLEND_MODE_SCREEN        = 0x02,
1659     IN_BLEND_MODE_OVERLAY       = 0x03,
1660     IN_BLEND_MODE_DARKEN        = 0x04,
1661     IN_BLEND_MODE_LIGHTEN       = 0x05,
1662     IN_BLEND_MODE_COLOR_DODGE   = 0x06,
1663     IN_BLEND_MODE_LINEAR_DODGE  = 0x07,
1664     IN_BLEND_MODE_ADD_GLOW      = 0x08,
1665     IN_BLEND_MODE_COLOR_BURN    = 0x09,
1666     IN_BLEND_MODE_HARD_LIGHT    = 0x0A,
1667     IN_BLEND_MODE_SOFT_LIGHT    = 0x0B,
1668     IN_BLEND_MODE_DIFFERENCE    = 0x0C,
1669     IN_BLEND_MODE_EXCLUSION     = 0x0D,
1670     IN_BLEND_MODE_SUBTRACT      = 0x0E,
1671     IN_BLEND_MODE_INVERSE       = 0x0F,
1672     IN_BLEND_MODE_DESTINATION_IN= 0x10,
1673     IN_BLEND_MODE_SOURCE_IN     = 0x11,
1674     IN_BLEND_MODE_SOURCE_OUT    = 0x12
1675 }
1676 
1677 /**
1678     A drawing command from the Inochi2D draw list
1679 */
1680 struct in_drawcmd_t {
1681     in_texture_t*[IN_MAX_ATTACHMENTS] sources;
1682     in_drawstate_t state;
1683     in_blend_mode_t blendMode;
1684     in_mask_mode_t maskMode;
1685     uint allocId;
1686     uint vtxOffset;
1687     uint idxOffset;
1688     uint elemCount;
1689     uint type;
1690     void[64] vars;
1691 }
1692 
1693 /**
1694     A drawlist mesh allocation
1695 */
1696 struct in_drawalloc_t {
1697     uint vtxOffset;
1698     uint idxOffset;
1699     uint idxCount;
1700     uint vtxCount;
1701     uint allocId;
1702 }
1703 
1704 /**
1705     Gets whether the draw list uses base vertex offsets.
1706 
1707     Params:
1708         obj = The drawlist
1709     
1710     Returns:
1711         $(D true) if base vertex offsets are being generated,
1712         $(D false) otherwise.
1713 */
1714 bool in_drawlist_get_use_base_vertex(in_drawlist_t* obj) {
1715     return (cast(DrawList)obj).useBaseVertex;
1716 }
1717 
1718 /**
1719     Sets whether the draw list uses base vertex offsets.
1720 
1721     Params:
1722         obj =   The drawlist
1723         value = The value to set.
1724 */
1725 void in_drawlist_set_use_base_vertex(in_drawlist_t* obj, bool value) {
1726     (cast(DrawList)obj).useBaseVertex = value;
1727 }
1728 
1729 /**
1730     Gets all of the commands stored in the draw list for iteration.
1731     
1732     This memory is owned by the draw list and should not be freed
1733     by you.
1734 
1735     Params:
1736         obj =   The drawlist
1737         count = Where to store the command count
1738     
1739     Returns:
1740         A pointer to an array of draw commands
1741 */
1742 in_drawcmd_t* in_drawlist_get_commands(in_drawlist_t* obj, ref uint count) {
1743     count = cast(uint)(cast(DrawList)obj).commands.length;
1744     return cast(in_drawcmd_t*)(cast(DrawList)obj).commands.ptr;
1745 }
1746 
1747 /**
1748     Gets all of the vertex data stored in the draw list.
1749     
1750     This memory is owned by the draw list and should not be freed
1751     by you.
1752 
1753     Params:
1754         obj =   The drawlist
1755         bytes = Where to store the byte count of the data.
1756     
1757     Returns:
1758         A pointer to the data
1759 */
1760 in_vtxdata_t* in_drawlist_get_vertex_data(in_drawlist_t* obj, ref uint bytes) {
1761     bytes = cast(uint)((cast(DrawList)obj).vertices.length * VtxData.sizeof);
1762     return cast(in_vtxdata_t*)(cast(DrawList)obj).vertices.ptr;
1763 }
1764 
1765 /**
1766     Gets all of the index data stored in the draw list.
1767     
1768     This memory is owned by the draw list and should not be freed
1769     by you.
1770 
1771     Params:
1772         obj =   The drawlist
1773         bytes = Where to store the byte count of the data.
1774     
1775     Returns:
1776         A pointer to the data
1777 */
1778 void* in_drawlist_get_index_data(in_drawlist_t* obj, ref uint bytes) {
1779     bytes = cast(uint)((cast(DrawList)obj).indices.length * uint.sizeof);
1780     return cast(void*)(cast(DrawList)obj).indices.ptr;
1781 }
1782 
1783 /**
1784     Gets all of the allocated meshes of the drawlist.
1785     
1786     This memory is owned by the draw list and should not be freed
1787     by you.
1788 
1789     Params:
1790         obj =   The drawlist
1791         count = Where to store the element count
1792     
1793     Returns:
1794         A pointer to the data
1795 */
1796 in_drawalloc_t* in_drawlist_get_allocations(in_drawlist_t* obj, ref uint count) {
1797     count = cast(uint)((cast(DrawList)obj).allocations.length);
1798     return cast(in_drawalloc_t*)(cast(DrawList)obj).allocations.ptr;
1799 }