star-3d

Surface structuring for efficient 3D geometric queries
git clone git://git.meso-star.com/star-3d.git
Log | Files | Refs | README | LICENSE

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