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 }