s3d.h (22067B)
1 /* Copyright (C) 2015-2023, 2026 |Méso|Star> (contact@meso-star.com) 2 * 3 * This file is part of Star-3D. 4 * 5 * Star-3D is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * Star-3D is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with Star-3D. If not, see <http://www.gnu.org/licenses/>. */ 17 18 #ifndef S3D_H 19 #define S3D_H 20 21 #include <rsys/rsys.h> 22 #include <float.h> 23 24 /* Library symbol management */ 25 #if defined(S3D_SHARED_BUILD) /* Build shared library */ 26 #define S3D_API extern EXPORT_SYM 27 #elif defined(S3D_STATIC) /* Use/build static library */ 28 #define S3D_API extern LOCAL_SYM 29 #else /* Use shared library */ 30 #define S3D_API extern IMPORT_SYM 31 #endif 32 33 /* Helper macro that asserts if the invocation of the s3d function `Func' 34 * returns an error. One should use this macro on s3d function calls for which 35 * no explicit error checking is performed */ 36 #ifndef NDEBUG 37 #define S3D(Func) ASSERT(s3d_ ## Func == RES_OK) 38 #else 39 #define S3D(Func) s3d_ ## Func 40 #endif 41 42 /* Syntactic sugar use during the setup of the shape. Setting a vertex data 43 * functor to S3D_KEEP means that this vertex data will not be updated */ 44 #define S3D_KEEP NULL 45 46 #define S3D_INVALID_ID ((unsigned)-1) /* Value of an invalid identifer */ 47 48 enum s3d_rays_flag { 49 S3D_RAYS_SINGLE_ORIGIN = BIT(0), /* The rays have the same origin */ 50 S3D_RAYS_SINGLE_DIRECTION = BIT(1), /* The rays have the same direction */ 51 S3D_RAYS_SINGLE_RANGE = BIT(2), /* The rays have the same range */ 52 S3D_RAYS_SINGLE_DATA = BIT(3) /* The rays shared the same user defined data */ 53 }; 54 55 /* Attributes of a shape */ 56 enum s3d_attrib_usage { 57 S3D_POSITION, /* World space position */ 58 S3D_ATTRIB_0, /* Generic attrib 0 */ 59 S3D_ATTRIB_1, /* Generic attrib 1 */ 60 S3D_ATTRIB_2, /* Generic attrib 2 */ 61 S3D_ATTRIB_3, /* Generic attrib 3 */ 62 S3D_ATTRIBS_COUNT__, 63 /* Unormalized world space face normal. For triangular meshes, the outward 64 * orientation is defined with respect to the Clock Wise vertex ordering */ 65 S3D_GEOMETRY_NORMAL 66 }; 67 68 enum s3d_type { 69 S3D_FLOAT, 70 S3D_FLOAT2, 71 S3D_FLOAT3, 72 S3D_FLOAT4 73 }; 74 75 enum s3d_transform_space { 76 S3D_LOCAL_TRANSFORM, /* The transformation is local to the shape space */ 77 S3D_WORLD_TRANSFORM /* The transformation is expressed in world space */ 78 }; 79 80 /* Primitive descriptor. The <geom|inst> indentifiers cover a compact ranges of 81 * value. They can be used in conjunction with a dynamic array to map from s3d 82 * geometry to application geometry */ 83 struct s3d_primitive { 84 unsigned prim_id; /* Primitive identifier */ 85 unsigned geom_id; /* Geometry identifier */ 86 unsigned inst_id; /* Instance identifier */ 87 unsigned scene_prim_id; /* Identifier of the primitive in the scene */ 88 /* Internal data. Should not be accessed */ 89 void* shape__; 90 void* inst__; 91 }; 92 93 #define S3D_PRIMITIVE_NULL__ { \ 94 S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL \ 95 } 96 static const struct s3d_primitive S3D_PRIMITIVE_NULL = S3D_PRIMITIVE_NULL__; 97 98 /* Helper macro that defines whether or not 2 primites are equal */ 99 #define S3D_PRIMITIVE_EQ(Prim0, Prim1) \ 100 ( (Prim0)->prim_id == (Prim1)->prim_id \ 101 && (Prim0)->geom_id == (Prim1)->geom_id \ 102 && (Prim0)->inst_id == (Prim1)->inst_id) 103 104 /* Untyped vertex attribute */ 105 struct s3d_attrib { 106 float value[4]; 107 enum s3d_type type; 108 enum s3d_attrib_usage usage; 109 }; 110 111 /* Describe a per vertex data */ 112 struct s3d_vertex_data { 113 /* Semantic of the data. Note that the S3D_GEOMETRY_NORMAL is not a valid 114 * vertex usage */ 115 enum s3d_attrib_usage usage; 116 enum s3d_type type; 117 /* Retreive the vertex data value of `ivert'. Set it to S3D_KEEP, to keep the 118 * previously set data */ 119 void (*get) 120 (const unsigned ivert, /* Index of the vertex */ 121 float* value, /* Retrieved attrib value */ 122 void* ctx); /* Pointer to user data */ 123 }; 124 125 /* Invalid vertex data */ 126 #define S3D_VERTEX_DATA_NULL__ { S3D_ATTRIBS_COUNT__, S3D_FLOAT, NULL } 127 static const struct s3d_vertex_data S3D_VERTEX_DATA_NULL = S3D_VERTEX_DATA_NULL__; 128 129 /* Intersection point */ 130 struct s3d_hit { 131 struct s3d_primitive prim; /* Intersected primitive */ 132 float normal[3]; /* Un-normalized geometry normal (left hand convention) */ 133 float uv[2]; /* Barycentric coordinates of the hit onto `prim' */ 134 float distance; /* Hit distance from the query origin */ 135 }; 136 137 /* Constant defining a NULL intersection. Should be used to initialize a hit */ 138 #define S3D_HIT_NULL__ { \ 139 {S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, S3D_INVALID_ID, NULL, NULL},\ 140 {0.f, 0.f, 0.f}, \ 141 {0.f, 0.f}, \ 142 FLT_MAX \ 143 } 144 145 static const struct s3d_hit S3D_HIT_NULL = S3D_HIT_NULL__; 146 147 enum s3d_scene_view_flag { 148 S3D_TRACE = BIT(0), 149 S3D_SAMPLE = BIT(1), 150 S3D_GET_PRIMITIVE = BIT(2) 151 }; 152 153 /* Helper macro that defines whether or not the hit is valid, i.e. the ray 154 * intersects a shape or not */ 155 #define S3D_HIT_NONE(Hit) ((Hit)->distance >= FLT_MAX) 156 157 /* Quality of the partitioning data structure used to accelerate geometry 158 * queries. The lowest the structure quality is, the fastest it is built. On 159 * the counterpart, a weak structure quality means that the partitioning of the 160 * geometry is sub-optimal, leading to lower geometry query performances. */ 161 enum s3d_accel_struct_quality { 162 S3D_ACCEL_STRUCT_QUALITY_LOW, 163 S3D_ACCEL_STRUCT_QUALITY_MEDIUM, 164 S3D_ACCEL_STRUCT_QUALITY_HIGH 165 }; 166 167 /* Define the properties of the partitioning data structure used to accelerate 168 * geometry queries */ 169 enum s3d_accel_struct_flag { 170 /* Avoid optimisations that reduce arithmetic accuracy */ 171 S3D_ACCEL_STRUCT_FLAG_ROBUST = BIT(0), 172 /* Improve the building performances of the acceleration structure for 173 * dynamic scenes */ 174 S3D_ACCEL_STRUCT_FLAG_DYNAMIC = BIT(1), 175 /* Reduce the memory consumption of the acceleration structure */ 176 S3D_ACCEL_STRUCT_FLAG_COMPACT = BIT(2) 177 }; 178 179 /* Configuration of the partitioning structure used to accelerate geometry 180 * queries */ 181 struct s3d_accel_struct_conf { 182 enum s3d_accel_struct_quality quality; 183 int mask; /* combination of s3d_accel_struct_flag */ 184 }; 185 #define S3D_ACCEL_STRUCT_CONF_DEFAULT__ { \ 186 S3D_ACCEL_STRUCT_QUALITY_MEDIUM, \ 187 S3D_ACCEL_STRUCT_FLAG_ROBUST \ 188 } 189 static const struct s3d_accel_struct_conf S3D_ACCEL_STRUCT_CONF_DEFAULT = 190 S3D_ACCEL_STRUCT_CONF_DEFAULT__; 191 192 /* Filter function data type. One can define such function to discard 193 * intersections along a ray or the result of a closest point query with 194 * respect to user defined criteria, e.g.: masked/transparent primitive, etc. 195 * Return 0 if or the intersection is not discarded and a value not equal to zero 196 * otherwise. */ 197 typedef int 198 (*s3d_hit_filter_function_T) 199 (const struct s3d_hit* hit, 200 const float org[3], 201 const float dir[3], /* Direction from `org' to `hit' */ 202 const float range[2], /* Submitted range */ 203 void* query_data, /* User data submitted on query invocation */ 204 void* filter_data); /* Data defined on the setup of the filter function */ 205 206 /* Forward declaration of s3d opaque data types */ 207 struct s3d_device; /* Entry point of the library */ 208 struct s3d_scene; /* Collection of shapes */ 209 struct s3d_scene_view; /* Scene state */ 210 struct s3d_shape; /* Surfacic geometry */ 211 212 /* Forward declaration of external data types */ 213 struct logger; 214 struct mem_allocator; 215 216 /* 217 * All the s3d structures are ref counted. Once created with the appropriated 218 * `s3d_<TYPE>_create' function, the caller implicitly owns the created data, 219 * i.e. its reference counter is set to 1. The s3d_<TYPE>_ref_<get|put> 220 * functions get or release a reference on the data, i.e. they increment or 221 * decrement the reference counter, respectively. When this counter reach 0 the 222 * object is silently destroyed and cannot be used anymore. 223 */ 224 225 BEGIN_DECLS 226 227 /******************************************************************************* 228 * Device API - A device is the entry point of the s3d library. Applications 229 * use a s3d_device to create others s3d resources. 230 ******************************************************************************/ 231 S3D_API res_T 232 s3d_device_create 233 (struct logger* logger, /* May be NULL <=> use default logger */ 234 struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ 235 const int verbose, /* Define the level of verbosity */ 236 struct s3d_device** dev); 237 238 S3D_API res_T 239 s3d_device_ref_get 240 (struct s3d_device* dev); 241 242 S3D_API res_T 243 s3d_device_ref_put 244 (struct s3d_device* dev); 245 246 /******************************************************************************* 247 * Scene API - A scene is a collection of untyped shapes. It can be ray-traced 248 * and/or "instantiated" through a shape. 249 ******************************************************************************/ 250 S3D_API res_T 251 s3d_scene_create 252 (struct s3d_device* dev, 253 struct s3d_scene** scn); 254 255 S3D_API res_T 256 s3d_scene_ref_get 257 (struct s3d_scene* scn); 258 259 S3D_API res_T 260 s3d_scene_ref_put 261 (struct s3d_scene* scn); 262 263 S3D_API res_T 264 s3d_scene_instantiate 265 (struct s3d_scene* scn, 266 struct s3d_shape** shape); 267 268 /* Attach the shape to the scene. On success, the scene gets a reference onto 269 * the attached shape */ 270 S3D_API res_T 271 s3d_scene_attach_shape 272 (struct s3d_scene* scn, 273 struct s3d_shape* shape); 274 275 /* Remove the shape from the scene. After its detachment, the scene 276 * release its reference on the shape */ 277 S3D_API res_T 278 s3d_scene_detach_shape 279 (struct s3d_scene* scn, 280 struct s3d_shape* shape); 281 282 /* Detach all the shapes from the scene and release the reference that the 283 * scene takes onto them */ 284 S3D_API res_T 285 s3d_scene_clear 286 (struct s3d_scene* scn); 287 288 S3D_API res_T 289 s3d_scene_get_device 290 (struct s3d_scene* scn, 291 struct s3d_device** dev); 292 293 S3D_API res_T 294 s3d_scene_get_shapes_count 295 (struct s3d_scene* scn, 296 size_t* nshapes); 297 298 /******************************************************************************* 299 * Scene view API - State of the scene geometry 300 ******************************************************************************/ 301 S3D_API res_T 302 s3d_scene_view_create 303 (struct s3d_scene* scn, 304 const int mask, /* Combination of s3d_scene_view_flag */ 305 struct s3d_scene_view** scnview); 306 307 S3D_API res_T 308 s3d_scene_view_create2 309 (struct s3d_scene* scn, 310 const int mask, /* Combination of s3d_scene_view_flag */ 311 /* Ignored if (mask & S3D_TRACE) == 0 312 * NULL <=> use S3D_ACCEL_STRUCT_CONF_DEFAULT */ 313 const struct s3d_accel_struct_conf* cfg, 314 struct s3d_scene_view** scnview); 315 316 S3D_API res_T 317 s3d_scene_view_ref_get 318 (struct s3d_scene_view* scnview); 319 320 S3D_API res_T 321 s3d_scene_view_ref_put 322 (struct s3d_scene_view* scnview); 323 324 S3D_API res_T 325 s3d_scene_view_get_mask 326 (struct s3d_scene_view* scnview, 327 int* mask); 328 329 /* Trace a ray into the scene and return the closest intersection along it. The 330 * ray is defined by `origin' + t*`direction' = 0 with t in [`range[0]', 331 * `range[1]'). Note that if a range is degenerated (i.e. `range[0]' >= 332 * `range[1]') then the ray is not traced and `hit' is set to S3D_HIT_NULL. Can 333 * be called only if the scnview was created with the S3D_TRACE flag. */ 334 S3D_API res_T 335 s3d_scene_view_trace_ray 336 (struct s3d_scene_view* scnview, 337 const float origin[3], /* Ray origin */ 338 const float direction[3], /* Ray direction. Must be normalized */ 339 const float range[2], /* In [0, INF)^2 */ 340 void* ray_data, /* User ray data sent to the hit filter func. May be NULL */ 341 struct s3d_hit* hit); 342 343 /* Trace a bundle of rays into the scene. Can be called only if the scnview was 344 * created with the S3D_TRACE flag. */ 345 S3D_API res_T 346 s3d_scene_view_trace_rays 347 (struct s3d_scene_view* scnview, 348 const size_t nrays, /* # rays */ 349 const int mask, /* Combination of s3d_rays_flag */ 350 const float* origins, /* List of 3D ray origins */ 351 const float* directions, /* List of 3D ray directions */ 352 const float* ranges, /* List of 2D ray ranges. in [0, INF)^2 */ 353 void* rays_data, /* User ray data sent to the hit filter func. May be NULL */ 354 const size_t sizeof_ray_data, /* Size in Bytes of *one* ray data */ 355 struct s3d_hit* hits); 356 357 /* Return the point onto the scene surfaces that is the closest of the 358 * submitted `pos'. Note that even though only one point is returned, several 359 * position can have the same minimal distance to the queried position. The 360 * `radius' parameter defines the maximum search distance around `pos'. Each 361 * candidate position are internally filtered by the hit_filter_function 362 * attached to the corresponding shape; the user can thus reject a candidate 363 * position according to its own criteria. This function can be called only if 364 * the scnview was created with the S3D_TRACE flag which is actually the flag 365 * used to tell Star-3D to internally build an acceleration structure on which 366 * this function relies. */ 367 S3D_API res_T 368 s3d_scene_view_closest_point 369 (struct s3d_scene_view* scnview, 370 const float pos[3], /* Position to query */ 371 const float radius, /* Search distance in [0, radius[ */ 372 void* query_data, /* User data sent to the hit filter func. May be NULL */ 373 struct s3d_hit* hit); 374 375 /* Uniformly sample the scene and return the sampled primitive and its sample 376 * uv position. Can be called only if the scnview was created with the 377 * S3D_SAMPLE flag */ 378 S3D_API res_T 379 s3d_scene_view_sample 380 (struct s3d_scene_view* scnview, 381 const float u, const float v, const float w, /* Random numbers in [0, 1) */ 382 struct s3d_primitive* primitive, /* Sampled primitive */ 383 float st[2]); /* Sampled parametric coordinates on the primitive */ 384 385 /* Retrieve a primitive from the scene. Can be called only if the scnview was 386 * created with the S3D_GET_PRIMITIVE flag */ 387 S3D_API res_T 388 s3d_scene_view_get_primitive 389 (struct s3d_scene_view* scnview, 390 const unsigned iprim, /* in [0, #prims) */ 391 struct s3d_primitive* prim); 392 393 /* Return the overall number of scene primitives */ 394 S3D_API res_T 395 s3d_scene_view_primitives_count 396 (struct s3d_scene_view* scnview, 397 size_t* primitives_count); 398 399 /* Compute the overall scene surface area */ 400 S3D_API res_T 401 s3d_scene_view_compute_area 402 (struct s3d_scene_view* scnview, 403 float* area); 404 405 /* This function assumes that the scene defines a closed volume and that the 406 * normals point into the volume. */ 407 S3D_API res_T 408 s3d_scene_view_compute_volume 409 (struct s3d_scene_view* scnview, 410 float* volume); 411 412 /* Retrieve the Axis Aligned Bounding Box of the scene */ 413 S3D_API res_T 414 s3d_scene_view_get_aabb 415 (struct s3d_scene_view* scnview, 416 float lower[3], /* AABB lower bound */ 417 float upper[3]); /* AABB upper bound */ 418 419 /******************************************************************************* 420 * Shape API - A shape defines a geometry that can be attached to a scene. 421 ******************************************************************************/ 422 S3D_API res_T 423 s3d_shape_ref_get 424 (struct s3d_shape* shape); 425 426 S3D_API res_T 427 s3d_shape_ref_put 428 (struct s3d_shape* shape); 429 430 /* Retrieve the id of the shape. This id covers a compact range of value. 431 * Consequently, it can be used to map from the s3d shapes to the geometry 432 * representation of the caller with a simple dynamic array */ 433 S3D_API res_T 434 s3d_shape_get_id 435 (const struct s3d_shape* shape, 436 unsigned* id); 437 438 /* Enable/disable the shape, i.e. it cannot be hit when its associated scene is 439 * ray-traced or sampled */ 440 S3D_API res_T 441 s3d_shape_enable 442 (struct s3d_shape* shape, 443 const char enable); 444 445 /* Return whether or not the shape is enabled, i.e. ray-traced. Default is 1 */ 446 S3D_API res_T 447 s3d_shape_is_enabled 448 (const struct s3d_shape* shape, 449 char* is_enabled); 450 451 /* Flip the surface orientation, i.e. flip the geometric normal of the surface */ 452 S3D_API res_T 453 s3d_shape_flip_surface 454 (struct s3d_shape* shape); 455 456 /******************************************************************************* 457 * Primitive API - Define a geometric primitive of a shape 458 ******************************************************************************/ 459 /* Retrieve the attribute of the shape primitive `prim' at the barycentric 460 * coordinates `uv' */ 461 S3D_API res_T 462 s3d_primitive_get_attrib 463 (const struct s3d_primitive* prim, 464 const enum s3d_attrib_usage attr, /* Attribute to retrieve */ 465 const float st[2], /* Parametric coordinates of `attr' on `prim' */ 466 struct s3d_attrib* attrib); /* Resulting attrib */ 467 468 /* Retrieve if the primitive `prim' has the attribute `attr' */ 469 S3D_API res_T 470 s3d_primitive_has_attrib 471 (const struct s3d_primitive* prim, 472 const enum s3d_attrib_usage attr, 473 char* has_attrib); 474 475 /* Uniform sampling of the primitive */ 476 S3D_API res_T 477 s3d_primitive_sample 478 (const struct s3d_primitive* prim, 479 const float u, const float v, /* Random numbers in [0, 1) */ 480 float st[2]); /* Sampled parametric coordinates on prim */ 481 482 S3D_API res_T 483 s3d_primitive_compute_area 484 (const struct s3d_primitive* prim, 485 float* area); 486 487 S3D_API res_T 488 s3d_primitive_get_transform 489 (const struct s3d_primitive* prim, 490 float transform[12]); /* 3x4 column major matrix */ 491 492 S3D_API res_T 493 s3d_triangle_get_vertex_attrib 494 (const struct s3d_primitive* prim, 495 const size_t ivertex, /* in [0..3[ */ 496 const enum s3d_attrib_usage usage, 497 struct s3d_attrib* attrib); 498 499 /******************************************************************************* 500 * Sphere API - Manage a spherical shape. By default, the sphere normals point 501 * outward the sphere. One can use the s3d_shape_flip_surface function to 502 * revert them. 503 ******************************************************************************/ 504 S3D_API res_T 505 s3d_shape_create_sphere 506 (struct s3d_device* dev, 507 struct s3d_shape** sphere); 508 509 S3D_API res_T 510 s3d_sphere_setup 511 (struct s3d_shape* shape, 512 const float position[3], 513 const float radius); 514 515 /* Define an intersection filter function. The filter function is invoked at 516 * each intersection found during the s3d_scene_trace_ray(s) calls. If func 517 * does not return 0, then the intersection is ignored and the ray pursues its 518 * traversal. */ 519 S3D_API res_T 520 s3d_sphere_set_hit_filter_function 521 (struct s3d_shape* shape, 522 s3d_hit_filter_function_T func, 523 void* filter_data); 524 525 S3D_API res_T 526 s3d_sphere_get_hit_filter_data 527 (struct s3d_shape* shape, 528 void** data); 529 530 /******************************************************************************* 531 * Mesh API - Manage a triangular meshes 532 ******************************************************************************/ 533 S3D_API res_T 534 s3d_shape_create_mesh 535 (struct s3d_device* dev, 536 struct s3d_shape** shape); 537 538 /* Set/update the data of the indexed triangular meshes */ 539 S3D_API res_T 540 s3d_mesh_setup_indexed_vertices 541 (struct s3d_shape* shape, 542 const unsigned ntris, 543 void (*get_indices) /* May be S3D_KEEP, i.e. do not update the indices */ 544 (const unsigned itri, unsigned ids[3], void* ctx), 545 const unsigned nverts, 546 /* List of the shape vertex data. Must have at least an attrib with the 547 * S3D_POSITION usage. */ 548 struct s3d_vertex_data attribs[], 549 const unsigned nattribs, /* # attributes in the attribs list */ 550 void* data); /* Client data set as the last param of the callbacks */ 551 552 /* Copy the mesh data from `src' to `dst' */ 553 S3D_API res_T 554 s3d_mesh_copy 555 (const struct s3d_shape* src, 556 struct s3d_shape* dst); 557 558 S3D_API res_T 559 s3d_mesh_get_vertices_count 560 (const struct s3d_shape* shape, 561 unsigned* nverts); 562 563 S3D_API res_T 564 s3d_mesh_get_vertex_attrib 565 (const struct s3d_shape* shape, 566 const unsigned ivert, 567 const enum s3d_attrib_usage usage, 568 struct s3d_attrib* attrib); 569 570 S3D_API res_T 571 s3d_mesh_get_triangles_count 572 (const struct s3d_shape* shape, 573 unsigned* ntris); 574 575 S3D_API res_T 576 s3d_mesh_get_triangle_indices 577 (const struct s3d_shape* shape, 578 const unsigned itri, 579 unsigned ids[3]); 580 581 /* Define an intersection filter function. The filter function is invoked at 582 * each intersection found during the s3d_scene_trace_ray(s) calls. If func 583 * does not return 0, then the intersection is ignored and the ray pursues its 584 * traversal. */ 585 S3D_API res_T 586 s3d_mesh_set_hit_filter_function 587 (struct s3d_shape* shape, 588 s3d_hit_filter_function_T func, 589 void* filter_data); 590 591 S3D_API res_T 592 s3d_mesh_get_hit_filter_data 593 (struct s3d_shape* shape, 594 void** data); 595 596 /******************************************************************************* 597 * Instance API - An instance is a shape that encapsulates a scene and that 598 * supports a local to world transformation. Since the scene geometry is stored 599 * only a single time even though it is instantiated in several positions, one 600 * can use this feature to create extremely large scene. 601 ******************************************************************************/ 602 S3D_API res_T 603 s3d_instance_set_position 604 (struct s3d_shape* shape, 605 const float position[3]); 606 607 S3D_API res_T 608 s3d_instance_translate 609 (struct s3d_shape* shape, 610 const enum s3d_transform_space space, 611 const float translation[3]); 612 613 S3D_API res_T 614 s3d_instance_set_transform 615 (struct s3d_shape* shape, 616 const float transform[12]); /* 3x4 column major matrix */ 617 618 S3D_API res_T 619 s3d_instance_transform 620 (struct s3d_shape* shape, 621 const enum s3d_transform_space space, 622 const float transform[12]); /* 3x4 column major matrix */ 623 624 END_DECLS 625 626 #endif /* S3D_H */ 627