ssol.h (40815B)
1 /* Copyright (C) 2018-2026 |Méso|Star> (contact@meso-star.com) 2 * Copyright (C) 2016, 2018 CNRS 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifndef SSOL_H 18 #define SSOL_H 19 20 #include <rsys/rsys.h> 21 22 /* Library symbol management */ 23 #if defined(SSOL_SHARED_BUILD) /* Build shared library */ 24 #define SSOL_API extern EXPORT_SYM 25 #elif defined(SSOL_STATIC) /* Use/build static library */ 26 #define SSOL_API extern LOCAL_SYM 27 #else /* Use shared library */ 28 #define SSOL_API extern IMPORT_SYM 29 #endif 30 31 /* Helper macro that asserts if the invocation of the Solstice function `Func' 32 * returns an error. One should use this macro on Solstice function calls for 33 * which no explicit error checking is performed */ 34 #ifndef NDEBUG 35 #define SSOL(Func) ASSERT(ssol_ ## Func == RES_OK) 36 #else 37 #define SSOL(Func) ssol_ ## Func 38 #endif 39 40 /* Syntactic sugar used to inform the Solstice Solver library that it can use 41 * as many threads as CPU cores */ 42 #define SSOL_NTHREADS_DEFAULT (~0u) 43 44 /* Forward declaration of external types */ 45 struct logger; 46 struct mem_allocator; 47 struct ssp_rng; 48 struct tm; 49 50 /* Opaque Solstice solver types */ 51 struct ssol_atmosphere; 52 struct ssol_camera; 53 struct ssol_device; 54 struct ssol_image; 55 struct ssol_material; 56 struct ssol_object; 57 struct ssol_instance; 58 struct ssol_param_buffer; 59 struct ssol_scene; 60 struct ssol_shape; 61 struct ssol_spectrum; 62 struct ssol_sun; 63 struct ssol_estimator; 64 65 enum ssol_side_flag { 66 SSOL_FRONT = BIT(0), 67 SSOL_BACK = BIT(1), 68 SSOL_INVALID_SIDE = BIT(2) 69 }; 70 71 enum ssol_path_type { 72 SSOL_PATH_MISSING, /* The path misses the receivers */ 73 SSOL_PATH_SHADOW, /* The path is occluded before the sampled geometry */ 74 SSOL_PATH_SUCCESS, /* The path contributes to at least one receiver */ 75 SSOL_PATH_ERROR /* The path was canceled due to a path-related error */ 76 }; 77 78 enum ssol_material_type { 79 SSOL_MATERIAL_DIELECTRIC, 80 SSOL_MATERIAL_MATTE, 81 SSOL_MATERIAL_MIRROR, 82 SSOL_MATERIAL_THIN_DIELECTRIC, 83 SSOL_MATERIAL_VIRTUAL, 84 SSOL_MATERIAL_TYPES_COUNT__ 85 }; 86 87 enum ssol_microfacet_distribution { 88 SSOL_MICROFACET_BECKMANN, 89 SSOL_MICROFACET_PILLBOX, 90 SSOL_MICROFACET_DISTRIBUTIONS_COUNT__ 91 }; 92 93 enum ssol_clipping_op { 94 SSOL_AND, 95 SSOL_SUB, 96 SSOL_CLIPPING_OPS_COUNT__ 97 }; 98 99 enum ssol_pixel_format { 100 SSOL_PIXEL_DOUBLE3, 101 SSOL_PIXEL_FORMATS_COUNT__ 102 }; 103 104 enum ssol_filter_mode { 105 SSOL_FILTER_LINEAR, 106 SSOL_FILTER_NEAREST 107 }; 108 109 enum ssol_address_mode { 110 SSOL_ADDRESS_CLAMP, 111 SSOL_ADDRESS_REPEAT 112 }; 113 114 enum ssol_quadric_type { 115 SSOL_QUADRIC_PLANE, 116 SSOL_QUADRIC_PARABOL, 117 SSOL_QUADRIC_HYPERBOL, 118 SSOL_QUADRIC_PARABOLIC_CYLINDER, 119 SSOL_QUADRIC_HEMISPHERE, 120 SSOL_QUADRIC_TYPE_COUNT__ 121 }; 122 123 /* Attribute of a shape */ 124 enum ssol_attrib_usage { 125 SSOL_POSITION, /* Shape space 3D position */ 126 SSOL_NORMAL, /* Shape space 3D vertex normal */ 127 SSOL_TEXCOORD, /* 2D texture coordinates */ 128 SSOL_ATTRIBS_COUNT__ 129 }; 130 131 enum ssol_data_type { 132 SSOL_DATA_REAL, 133 SSOL_DATA_SPECTRUM 134 }; 135 136 /* The algorithm used to produce sun direction from location and date */ 137 enum ssol_sun_direction_algorithm { 138 SSOL_SUN_DIRECTION_ALGORITHM_MEEUS, 139 SSOL_SUN_DIRECTION_ALGORITHM_PSA 140 }; 141 142 /* The longitude must be in [-180, 180] degrees relative to Greenwich. 143 * The angle is positive towards the east. 144 * The latitude must be in [-90, 90] degrees relative to the equator. 145 * It is positive towards the north. */ 146 struct ssol_location { double latitude; double longitude; }; 147 148 /* Describe a vertex data */ 149 struct ssol_vertex_data { 150 enum ssol_attrib_usage usage; /* Semantic of the data */ 151 void (*get) /* Retrieve the client side data for the vertex `ivert' */ 152 (const unsigned ivert, /* Index of the vertex */ 153 /* Value of the retrieved data. Its dimension must follow the 154 * the dimension of the `usage' argument. */ 155 float value[], 156 void* ctx); /* Pointer toward user data */ 157 }; 158 159 struct ssol_spectrum_desc { 160 double (*get) 161 (const unsigned iwavelength, 162 double* wavelength, 163 double* data, 164 void* ctx); /* Pointer toward user data */ 165 }; 166 167 /* Invalid vertex data */ 168 #define SSOL_VERTEX_DATA_NULL__ { SSOL_ATTRIBS_COUNT__, NULL } 169 static const struct ssol_vertex_data SSOL_VERTEX_DATA_NULL = 170 SSOL_VERTEX_DATA_NULL__; 171 172 struct ssol_image_layout { 173 size_t row_pitch; /* #bytes between 2 consecutive row */ 174 size_t offset; /* Byte offset where the image begins */ 175 size_t size; /* Overall size of the image buffer */ 176 size_t width, height; /* #pixels in X and Y */ 177 enum ssol_pixel_format pixel_format; /* Format of a pixel */ 178 }; 179 180 /* Invalid image layout */ 181 #define SSOL_IMAGE_LAYOUT_NULL__ { 0, 0, 0, 0, 0, SSOL_PIXEL_FORMATS_COUNT__ } 182 static const struct ssol_image_layout SSOL_IMAGE_LAYOUT_NULL = 183 SSOL_IMAGE_LAYOUT_NULL__; 184 185 /* The following quadric definitions are in local coordinate system. */ 186 struct ssol_quadric_plane { 187 char dummy; /* Define z = 0 */ 188 }; 189 #define SSOL_QUADRIC_PLANE_DEFAULT__ { 0 } 190 static const struct ssol_quadric_plane SSOL_QUADRIC_PLANE_DEFAULT = 191 SSOL_QUADRIC_PLANE_DEFAULT__; 192 193 struct ssol_quadric_parabol { 194 double focal; /* Define x^2 + y^2 - 4 focal z = 0 */ 195 }; 196 #define SSOL_QUADRIC_PARABOL_NULL__ { -1.0 } 197 static const struct ssol_quadric_parabol SSOL_QUADRIC_PARABOL_NULL = 198 SSOL_QUADRIC_PARABOL_NULL__; 199 200 struct ssol_quadric_hyperbol { 201 /* Define (x^2 + y^2) / a^2 - (z - 1/2)^2 / b^2 + 1 = 0; z > 0 202 * with a^2 = f - f^2; b = f -1/2; f = real_focal/(img_focal + real_focal) */ 203 double img_focal, real_focal; 204 }; 205 #define SSOL_QUADRIC_HYPERBOL_NULL__ { -1.0 , -1.0 } 206 static const struct ssol_quadric_hyperbol SSOL_QUADRIC_HYPERBOL_NULL = 207 SSOL_QUADRIC_HYPERBOL_NULL__; 208 209 struct ssol_quadric_parabolic_cylinder { 210 double focal; /* Define y^2 - 4 focal z = 0 */ 211 }; 212 #define SSOL_QUADRIC_PARABOLIC_CYLINDER_NULL__ { -1.0 } 213 static const struct ssol_quadric_parabolic_cylinder 214 SSOL_QUADRIC_PARABOLIC_CYLINDER_NULL = SSOL_QUADRIC_PARABOLIC_CYLINDER_NULL__; 215 216 struct ssol_quadric_hemisphere { 217 /* Define x^2 + y^2 + (z-radius)^2 - radius^2 = 0 with z <= r */ 218 double radius; 219 }; 220 #define SSOL_QUADRIC_HEMISPHERE_NULL__ { -1.0 } 221 static const struct ssol_quadric_hemisphere SSOL_QUADRIC_HEMISPHERE_NULL = 222 SSOL_QUADRIC_HEMISPHERE_NULL__; 223 224 struct ssol_quadric { 225 enum ssol_quadric_type type; 226 union { 227 struct ssol_quadric_plane plane; 228 struct ssol_quadric_parabol parabol; 229 struct ssol_quadric_hyperbol hyperbol; 230 struct ssol_quadric_parabolic_cylinder parabolic_cylinder; 231 struct ssol_quadric_hemisphere hemisphere; 232 } data; 233 234 /* 3x4 column major transformation of the quadric in object space */ 235 double transform[12]; 236 237 /* Hint on how to discretise */ 238 size_t slices_count_hint; 239 }; 240 241 #define SSOL_QUADRIC_DEFAULT__ { \ 242 SSOL_QUADRIC_PLANE, \ 243 {SSOL_QUADRIC_PLANE_DEFAULT__}, \ 244 {1,0,0, 0,1,0, 0,0,1, 0,0,0}, \ 245 SIZE_MAX /* <=> Use default discretisation */ \ 246 } 247 248 static const struct ssol_quadric SSOL_QUADRIC_DEFAULT = SSOL_QUADRIC_DEFAULT__; 249 250 /* Define the contour of a 2D polygon as well as the clipping operation to 251 * apply against it */ 252 struct ssol_carving { 253 void (*get) /* Retrieve the 2D coordinates of the vertex `ivert' */ 254 (const size_t ivert, double position[2], void* ctx); 255 size_t nb_vertices; /* #vertices */ 256 enum ssol_clipping_op operation; /* Clipping operation */ 257 void* context; /* User defined data */ 258 }; 259 #define SSOL_CARVING_NULL__ { NULL, 0, SSOL_CLIPPING_OPS_COUNT__, NULL } 260 static const struct ssol_carving SSOL_CARVING_NULL = SSOL_CARVING_NULL__; 261 262 struct ssol_punched_surface { 263 struct ssol_quadric* quadric; 264 struct ssol_carving* carvings; 265 size_t nb_carvings; 266 }; 267 #define SSOL_PUNCHED_SURFACE_NULL__ { NULL, NULL, 0 } 268 static const struct ssol_punched_surface SSOL_PUNCHED_SURFACE_NULL = 269 SSOL_PUNCHED_SURFACE_NULL__; 270 271 struct ssol_data { 272 enum ssol_data_type type; 273 union { 274 double real; 275 struct ssol_spectrum* spectrum; 276 } value; 277 }; 278 #define SSOL_DATA_NULL__ {SSOL_DATA_REAL, {0.0}} 279 static const struct ssol_data SSOL_DATA_NULL = SSOL_DATA_NULL__; 280 281 struct ssol_medium { 282 struct ssol_data extinction; 283 struct ssol_data refractive_index; 284 }; 285 #define SSOL_MEDIUM_VACUUM__ {{SSOL_DATA_REAL, {0}}, {SSOL_DATA_REAL, {1}}} 286 static const struct ssol_medium SSOL_MEDIUM_VACUUM = SSOL_MEDIUM_VACUUM__; 287 288 struct ssol_surface_fragment { 289 double dir[3]; /* World space incoming direction. Point forward the surface */ 290 double P[3]; /* World space position */ 291 double Ng[3]; /* Normalized world space geometry normal */ 292 double Ns[3]; /* Normalized world space shading normal */ 293 double uv[2]; /* Texture coordinates */ 294 double dPdu[3]; /* Partial derivative of the position in u */ 295 double dPdv[3]; /* Partial derivative of the position in v */ 296 }; 297 298 #define SSOL_SURFACE_FRAGMENT_NULL__ \ 299 {{0,0,0}, {0,0,0}, {0,0,0}, {0,0,0}, {0,0}, {0,0,0}, {0,0,0}} 300 static const struct ssol_surface_fragment SSOL_SURFACE_FRAGMENT_NULL = 301 SSOL_SURFACE_FRAGMENT_NULL__; 302 303 typedef void 304 (*ssol_shader_getter_T) 305 (struct ssol_device* dev, 306 struct ssol_param_buffer* buf, 307 const double wavelength, 308 const struct ssol_surface_fragment* fragment, 309 double* val); /* Returned value */ 310 311 /* Dielectric material shader */ 312 struct ssol_dielectric_shader { 313 ssol_shader_getter_T normal; 314 }; 315 #define SSOL_DIELECTRIC_SHADER_NULL__ { NULL } 316 static const struct ssol_dielectric_shader SSOL_DIELECTRIC_SHADER_NULL = 317 SSOL_DIELECTRIC_SHADER_NULL__; 318 319 /* Mirror material shader */ 320 struct ssol_mirror_shader { 321 ssol_shader_getter_T normal; 322 ssol_shader_getter_T reflectivity; 323 ssol_shader_getter_T roughness; 324 }; 325 #define SSOL_MIRROR_SHADER_NULL__ { NULL, NULL, NULL } 326 static const struct ssol_mirror_shader SSOL_MIRROR_SHADER_NULL = 327 SSOL_MIRROR_SHADER_NULL__; 328 329 /* Matte material shader */ 330 struct ssol_matte_shader { 331 ssol_shader_getter_T normal; 332 ssol_shader_getter_T reflectivity; 333 }; 334 #define SSOL_MATTE_SHADER_NULL__ { NULL, NULL } 335 static const struct ssol_matte_shader SSOL_MATTE_SHADER_NULL = 336 SSOL_MATTE_SHADER_NULL__; 337 338 /* Thin dielectric shader */ 339 struct ssol_thin_dielectric_shader { 340 ssol_shader_getter_T normal; 341 }; 342 #define SSOL_THIN_DIELECTRIC_SHADER_NULL__ { NULL } 343 static const struct ssol_thin_dielectric_shader 344 SSOL_THIN_DIELECTRIC_SHADER_NULL = SSOL_THIN_DIELECTRIC_SHADER_NULL__; 345 346 struct ssol_instantiated_shaded_shape { 347 struct ssol_shape* shape; 348 struct ssol_material* mtl_front; 349 struct ssol_material* mtl_back; 350 351 /* Internal data */ 352 double R__[9]; 353 double T__[3]; 354 double R_invtrans__[9]; 355 }; 356 357 #define SSOL_INSTANTIATED_SHADED_SHAPE_NULL__ { 0 } 358 static const struct ssol_instantiated_shaded_shape 359 SSOL_INSTANTIATED_SHADED_SHAPE_NULL = SSOL_INSTANTIATED_SHADED_SHAPE_NULL__; 360 361 struct ssol_path_tracker { 362 /* Control the length of the path segment starting/ending from/to the 363 * infinite. A value less than zero means for default value */ 364 double sun_ray_length; 365 double infinite_ray_length; 366 }; 367 368 #define SSOL_PATH_TRACKER_DEFAULT__ {-1, -1} 369 static const struct ssol_path_tracker SSOL_PATH_TRACKER_DEFAULT = 370 SSOL_PATH_TRACKER_DEFAULT__; 371 372 struct ssol_path { 373 /* Internal data */ 374 const void* path__; 375 }; 376 377 struct ssol_path_vertex { 378 double pos[3]; /* Position */ 379 double weight; /* Monte-Carlo weight */ 380 }; 381 382 struct ssol_mc_result { 383 double E; /* Expectation */ 384 double V; /* Variance */ 385 double SE; /* Standard error, i.e. sqrt(Expectation / N) */ 386 }; 387 #define SSOL_MC_RESULT_NULL__ {0, 0, 0} 388 static const struct ssol_mc_result SSOL_MC_RESULT_NULL = SSOL_MC_RESULT_NULL__; 389 390 struct ssol_mc_global { 391 struct ssol_mc_result cos_factor; /* [0 1] */ 392 struct ssol_mc_result absorbed_by_receivers; /* In W */ 393 struct ssol_mc_result shadowed; /* In W */ 394 struct ssol_mc_result missing; /* In W */ 395 struct ssol_mc_result extinguished_by_atmosphere; /* In W */ 396 struct ssol_mc_result other_absorbed; /* In W */ 397 }; 398 #define SSOL_MC_GLOBAL_NULL__ { \ 399 SSOL_MC_RESULT_NULL__, \ 400 SSOL_MC_RESULT_NULL__, \ 401 SSOL_MC_RESULT_NULL__, \ 402 SSOL_MC_RESULT_NULL__, \ 403 SSOL_MC_RESULT_NULL__, \ 404 SSOL_MC_RESULT_NULL__ \ 405 } 406 static const struct ssol_mc_global SSOL_MC_GLOBAL_NULL = SSOL_MC_GLOBAL_NULL__; 407 408 struct ssol_mc_receiver { 409 struct ssol_mc_result incoming_flux; /* In W */ 410 struct ssol_mc_result incoming_if_no_atm_loss; /* In W */ 411 struct ssol_mc_result incoming_if_no_field_loss; /* In W */ 412 struct ssol_mc_result incoming_lost_in_field; /* In W */ 413 struct ssol_mc_result incoming_lost_in_atmosphere; /* In W */ 414 struct ssol_mc_result absorbed_flux; /* In W */ 415 struct ssol_mc_result absorbed_if_no_atm_loss; /* In W */ 416 struct ssol_mc_result absorbed_if_no_field_loss; /* In W */ 417 struct ssol_mc_result absorbed_lost_in_field; /* In W */ 418 struct ssol_mc_result absorbed_lost_in_atmosphere; /* In W */ 419 420 /* Internal data */ 421 size_t N__; 422 void* mc__; 423 const struct ssol_instance* instance__; 424 }; 425 #define SSOL_MC_RECEIVER_NULL__ { \ 426 SSOL_MC_RESULT_NULL__, \ 427 SSOL_MC_RESULT_NULL__, \ 428 SSOL_MC_RESULT_NULL__, \ 429 SSOL_MC_RESULT_NULL__, \ 430 SSOL_MC_RESULT_NULL__, \ 431 SSOL_MC_RESULT_NULL__, \ 432 SSOL_MC_RESULT_NULL__, \ 433 SSOL_MC_RESULT_NULL__, \ 434 SSOL_MC_RESULT_NULL__, \ 435 SSOL_MC_RESULT_NULL__, \ 436 0, NULL, NULL \ 437 } 438 static const struct ssol_mc_receiver SSOL_MC_RECEIVER_NULL = 439 SSOL_MC_RECEIVER_NULL__; 440 441 #define MC_RCV_NONE__ { \ 442 { -1, -1, -1 }, \ 443 { -1, -1, -1 }, \ 444 { -1, -1, -1 }, \ 445 { -1, -1, -1 }, \ 446 { -1, -1, -1 }, \ 447 { -1, -1, -1 }, \ 448 { -1, -1, -1 }, \ 449 { -1, -1, -1 }, \ 450 { -1, -1, -1 }, \ 451 { -1, -1, -1 }, \ 452 0, NULL, NULL \ 453 } 454 455 struct ssol_mc_shape { 456 /* Internal data */ 457 size_t N__; 458 void* mc__; 459 const struct ssol_shape* shape__; 460 }; 461 #define SSOL_MC_SHAPE_NULL__ { 0, NULL, NULL } 462 static const struct ssol_mc_shape SSOL_MC_SHAPE_NULL = SSOL_MC_SHAPE_NULL__; 463 464 struct ssol_mc_sampled { 465 struct ssol_mc_result cos_factor; /* [0 1] */ 466 struct ssol_mc_result shadowed; 467 size_t nb_samples; 468 }; 469 470 struct ssol_mc_primitive { 471 struct ssol_mc_result incoming_flux; /* In W */ 472 struct ssol_mc_result incoming_if_no_atm_loss; /* In W */ 473 struct ssol_mc_result incoming_if_no_field_loss; /* In W */ 474 struct ssol_mc_result incoming_lost_in_field; /* In W */ 475 struct ssol_mc_result incoming_lost_in_atmosphere; /* In W */ 476 struct ssol_mc_result absorbed_flux; /* In W */ 477 struct ssol_mc_result absorbed_if_no_atm_loss; /* In W */ 478 struct ssol_mc_result absorbed_if_no_field_loss; /* In W */ 479 struct ssol_mc_result absorbed_lost_in_field; /* In W */ 480 struct ssol_mc_result absorbed_lost_in_atmosphere; /* In W */ 481 }; 482 #define SSOL_MC_PRIMITIVE_NULL__ { \ 483 SSOL_MC_RESULT_NULL__, \ 484 SSOL_MC_RESULT_NULL__, \ 485 SSOL_MC_RESULT_NULL__, \ 486 SSOL_MC_RESULT_NULL__, \ 487 SSOL_MC_RESULT_NULL__, \ 488 SSOL_MC_RESULT_NULL__, \ 489 SSOL_MC_RESULT_NULL__, \ 490 SSOL_MC_RESULT_NULL__, \ 491 SSOL_MC_RESULT_NULL__, \ 492 SSOL_MC_RESULT_NULL__ \ 493 } 494 static const struct ssol_mc_primitive SSOL_MC_PRIMITIVE_NULL = 495 SSOL_MC_PRIMITIVE_NULL__; 496 497 typedef res_T 498 (*ssol_write_pixels_T) 499 (void* context, /* Image data */ 500 const size_t origin[2], /* 2D coordinates of the 1st pixel to write */ 501 const size_t size[2], /* Number of pixels in X and Y to write */ 502 const enum ssol_pixel_format fmt, /* Format of the submitted pixel */ 503 const void* pixels); /* List of row ordered pixels */ 504 505 static FINLINE size_t 506 ssol_sizeof_pixel_format(const enum ssol_pixel_format format) 507 { 508 switch(format) { 509 case SSOL_PIXEL_DOUBLE3: return sizeof(double[3]); 510 default: FATAL("Unreachable code.\n"); 511 } 512 } 513 514 /* 515 * All the ssol structures are ref counted. Once created with the appropriated 516 * `ssol_<TYPE>_create' function, the caller implicitly owns the created data, 517 * i.e. its reference counter is set to 1. The ssol_<TYPE>_ref_<get|put> 518 * functions get or release a reference on the data, i.e. they increment or 519 * decrement the reference counter, respectively. When this counter reaches 0, 520 * the data structure is silently destroyed and cannot be used anymore. 521 */ 522 523 BEGIN_DECLS 524 525 /******************************************************************************* 526 * Device API - Main entry point of the Solstice Solver library. Applications 527 * use the ssol_device to create others Solstice Solver resources. 528 ******************************************************************************/ 529 SSOL_API res_T 530 ssol_device_create 531 (struct logger* logger, /* May be NULL <=> use default logger */ 532 struct mem_allocator* allocator, /* May be NULL <=> use default allocator */ 533 const unsigned nthreads_hint, /* Hint on the number of threads to use */ 534 const int verbose, /* Make the library more verbose */ 535 struct ssol_device** dev); 536 537 SSOL_API res_T 538 ssol_device_ref_get 539 (struct ssol_device* dev); 540 541 SSOL_API res_T 542 ssol_device_ref_put 543 (struct ssol_device* dev); 544 545 /******************************************************************************* 546 * Camera API 547 ******************************************************************************/ 548 SSOL_API res_T 549 ssol_camera_create 550 (struct ssol_device* de, 551 struct ssol_camera** cam); 552 553 SSOL_API res_T 554 ssol_camera_ref_get 555 (struct ssol_camera* cam); 556 557 SSOL_API res_T 558 ssol_camera_ref_put 559 (struct ssol_camera* cam); 560 561 /* Width/height projection ratio */ 562 SSOL_API res_T 563 ssol_camera_set_proj_ratio 564 (struct ssol_camera* cam, 565 const double proj_ratio); 566 567 SSOL_API res_T 568 ssol_camera_set_fov /* Horizontal field of view */ 569 (struct ssol_camera* cam, 570 const double fov); /* In radian */ 571 572 SSOL_API res_T 573 ssol_camera_look_at 574 (struct ssol_camera* cam, 575 const double position[3], 576 const double target[3], 577 const double up[3]); 578 579 /******************************************************************************* 580 * Image API 581 ******************************************************************************/ 582 SSOL_API res_T 583 ssol_image_create 584 (struct ssol_device* dev, 585 struct ssol_image** image); 586 587 SSOL_API res_T 588 ssol_image_ref_get 589 (struct ssol_image* image); 590 591 SSOL_API res_T 592 ssol_image_ref_put 593 (struct ssol_image* image); 594 595 SSOL_API res_T 596 ssol_image_setup 597 (struct ssol_image* image, 598 const size_t width, 599 const size_t height, 600 const enum ssol_pixel_format format); 601 602 SSOL_API res_T 603 ssol_image_get_layout 604 (const struct ssol_image* image, 605 struct ssol_image_layout* layout); 606 607 SSOL_API res_T 608 ssol_image_map 609 (const struct ssol_image* image, 610 char** memory); 611 612 SSOL_API res_T 613 ssol_image_unmap 614 (const struct ssol_image* image); 615 616 SSOL_API res_T 617 ssol_image_sample 618 (const struct ssol_image* image, 619 const enum ssol_filter_mode filter, 620 const enum ssol_address_mode address_u, 621 const enum ssol_address_mode address_v, 622 const double uv[2], 623 void* val); 624 625 /* Helper function that matches the `ssol_write_pixels_T' functor type */ 626 SSOL_API res_T 627 ssol_image_write 628 (void* image, 629 const size_t origin[2], 630 const size_t size[2], 631 const enum ssol_pixel_format fmt, 632 const void* pixels); 633 634 /******************************************************************************* 635 * Scene API - Opaque abstraction of the virtual environment. It contains a 636 * list of instantiated objects, handles a light source and 637 * describes the environment medium properties. 638 ******************************************************************************/ 639 SSOL_API res_T 640 ssol_scene_create 641 (struct ssol_device* dev, 642 struct ssol_scene** scn); 643 644 SSOL_API res_T 645 ssol_scene_ref_get 646 (struct ssol_scene* scn); 647 648 SSOL_API res_T 649 ssol_scene_ref_put 650 (struct ssol_scene* scn); 651 652 SSOL_API res_T 653 ssol_scene_attach_instance 654 (struct ssol_scene* scn, 655 struct ssol_instance* instance); 656 657 SSOL_API res_T 658 ssol_scene_detach_instance 659 (struct ssol_scene* scn, 660 struct ssol_instance* instance); 661 662 SSOL_API res_T 663 ssol_scene_compute_aabb 664 (const struct ssol_scene* scn, 665 float lower[3], 666 float upper[3]); 667 668 /* Detach all the instances from the scene and release the reference that the 669 * scene takes onto them. 670 * Also detach the attached sun and atmosphere if any. */ 671 SSOL_API res_T 672 ssol_scene_clear 673 (struct ssol_scene* scn); 674 675 SSOL_API res_T 676 ssol_scene_attach_sun 677 (struct ssol_scene* scn, 678 struct ssol_sun* sun); 679 680 SSOL_API res_T 681 ssol_scene_detach_sun 682 (struct ssol_scene* scn, 683 struct ssol_sun* sun); 684 685 SSOL_API res_T 686 ssol_scene_attach_atmosphere 687 (struct ssol_scene* scn, 688 struct ssol_atmosphere* atm); 689 690 SSOL_API res_T 691 ssol_scene_detach_atmosphere 692 (struct ssol_scene* scn, 693 struct ssol_atmosphere* atm); 694 695 SSOL_API res_T 696 ssol_scene_for_each_instance 697 (struct ssol_scene* scn, 698 res_T (*func)(struct ssol_instance* instance, void* ctx), 699 void* ctx); 700 701 /******************************************************************************* 702 * Shape API - Define a geometry that can be generated from a quadric equation 703 * or from a triangular mesh. 704 ******************************************************************************/ 705 SSOL_API res_T 706 ssol_shape_create_mesh 707 (struct ssol_device* dev, 708 struct ssol_shape** shape); 709 710 SSOL_API res_T 711 ssol_shape_create_punched_surface 712 (struct ssol_device* dev, 713 struct ssol_shape** shape); 714 715 SSOL_API res_T 716 ssol_shape_ref_get 717 (struct ssol_shape* shape); 718 719 SSOL_API res_T 720 ssol_shape_ref_put 721 (struct ssol_shape* shape); 722 723 SSOL_API res_T 724 ssol_shape_get_vertices_count 725 (const struct ssol_shape* shape, 726 unsigned* nverts); 727 728 SSOL_API res_T 729 ssol_shape_get_vertex_attrib 730 (const struct ssol_shape* shape, 731 const unsigned ivert, 732 const enum ssol_attrib_usage usage, 733 double value[]); 734 735 SSOL_API res_T 736 ssol_shape_get_triangles_count 737 (const struct ssol_shape* shape, 738 unsigned* ntris); 739 740 SSOL_API res_T 741 ssol_shape_get_triangle_indices 742 (const struct ssol_shape* shape, 743 const unsigned itri, 744 unsigned ids[3]); 745 746 /* Define a punched surface in local space, i.e. no transformation */ 747 SSOL_API res_T 748 ssol_punched_surface_setup 749 (struct ssol_shape* shape, 750 const struct ssol_punched_surface* punched_surface); 751 752 /* Define a shape from an indexed triangular mesh */ 753 SSOL_API res_T 754 ssol_mesh_setup 755 (struct ssol_shape* shape, 756 const unsigned ntris, /* #triangles */ 757 void (*get_indices)(const unsigned itri, unsigned ids[3], void* ctx), 758 const unsigned nverts, /* #vertices */ 759 /* List of the shape vertex data. Must have at least an attrib with the 760 * SSOL_POSITION usage. */ 761 const struct ssol_vertex_data attribs[], 762 const unsigned nattribs, 763 void* data); 764 765 /******************************************************************************* 766 * Material API - Define the surfacic (e.g.: BRDF) as well as the volumic 767 * (e.g.: refractive index) properties of a geometry. 768 ******************************************************************************/ 769 SSOL_API res_T 770 ssol_material_create_dielectric 771 (struct ssol_device* dev, 772 struct ssol_material** mtl); 773 774 SSOL_API res_T 775 ssol_material_create_mirror 776 (struct ssol_device* dev, 777 struct ssol_material** mtl); 778 779 SSOL_API res_T 780 ssol_material_create_matte 781 (struct ssol_device* dev, 782 struct ssol_material** mtl); 783 784 SSOL_API res_T 785 ssol_material_create_virtual 786 (struct ssol_device* dev, 787 struct ssol_material** mtl); 788 789 SSOL_API res_T 790 ssol_material_create_thin_dielectric 791 (struct ssol_device* dev, 792 struct ssol_material** mtl); 793 794 SSOL_API res_T 795 ssol_material_get_type 796 (const struct ssol_material* mtl, 797 enum ssol_material_type* type); 798 799 SSOL_API res_T 800 ssol_material_ref_get 801 (struct ssol_material* mtl); 802 803 SSOL_API res_T 804 ssol_material_ref_put 805 (struct ssol_material* mtl); 806 807 SSOL_API res_T 808 ssol_material_set_param_buffer 809 (struct ssol_material* mtl, 810 struct ssol_param_buffer* buf); 811 812 SSOL_API res_T 813 ssol_dielectric_setup 814 (struct ssol_material* mtl, 815 const struct ssol_dielectric_shader* shader, 816 const struct ssol_medium* outside_medium, 817 const struct ssol_medium* inside_medium); 818 819 SSOL_API res_T 820 ssol_mirror_setup 821 (struct ssol_material* mtl, 822 const struct ssol_mirror_shader* shader, 823 const enum ssol_microfacet_distribution distrib); 824 825 SSOL_API res_T 826 ssol_matte_setup 827 (struct ssol_material* mtl, 828 const struct ssol_matte_shader* shader); 829 830 SSOL_API res_T 831 ssol_thin_dielectric_setup 832 (struct ssol_material* mtl, 833 const struct ssol_thin_dielectric_shader* shader, 834 const struct ssol_medium* outside_medium, 835 const struct ssol_medium* slab_medium, 836 const double thickness); 837 838 /******************************************************************************* 839 * Object API - Opaque abstraction of a geometry with its associated properties. 840 ******************************************************************************/ 841 SSOL_API res_T 842 ssol_object_create 843 (struct ssol_device* dev, 844 struct ssol_object** obj); 845 846 SSOL_API res_T 847 ssol_object_ref_get 848 (struct ssol_object* obj); 849 850 SSOL_API res_T 851 ssol_object_ref_put 852 (struct ssol_object* obj); 853 854 SSOL_API res_T 855 ssol_object_add_shaded_shape 856 (struct ssol_object* object, 857 struct ssol_shape* shape, 858 struct ssol_material* mtl_front, /* Front face material of the shape */ 859 struct ssol_material* mtl_back); /* Back face material of the shape */ 860 861 /* Remove all the shaded shapes */ 862 SSOL_API res_T 863 ssol_object_clear 864 (struct ssol_object* object); 865 866 /* Retrieve the area of the object */ 867 SSOL_API res_T 868 ssol_object_get_area 869 (const struct ssol_object* object, 870 double* area); 871 872 /******************************************************************************* 873 * Object Instance API - Clone of an object with a set of per instance data as 874 * world transformation, material parameters, etc. Note that the object 875 * resources (i.e. the material and the shape) are only stored once even though 876 * they are instantiated several times. 877 ******************************************************************************/ 878 SSOL_API res_T 879 ssol_object_instantiate 880 (struct ssol_object* object, 881 struct ssol_instance** instance); 882 883 SSOL_API res_T 884 ssol_instance_ref_get 885 (struct ssol_instance* instance); 886 887 SSOL_API res_T 888 ssol_instance_ref_put 889 (struct ssol_instance* intance); 890 891 SSOL_API res_T 892 ssol_instance_set_transform 893 (struct ssol_instance* instance, 894 const double transform[12]); /* 3x4 column major matrix */ 895 896 /* Specify which sides of the faces are receivers */ 897 SSOL_API res_T 898 ssol_instance_set_receiver 899 (struct ssol_instance* instance, 900 const int mask, /* Combination of ssol_side_flag */ 901 const int per_primitive); /* Enable the per primitive integration */ 902 903 SSOL_API res_T 904 ssol_instance_is_receiver 905 (struct ssol_instance* instance, 906 int* mask, /* Combination of ssol_side_flag */ 907 int* per_primitive); 908 909 /* Define whether or not the instance is sampled or not. By default an instance 910 * is sampled. */ 911 SSOL_API res_T 912 ssol_instance_sample 913 (struct ssol_instance* instance, 914 const int sample); 915 916 /* Retrieve the id of the shape */ 917 SSOL_API res_T 918 ssol_instance_get_id 919 (const struct ssol_instance* instance, 920 uint32_t* id); 921 922 /* Retrieve the area of the instance */ 923 SSOL_API res_T 924 ssol_instance_get_area 925 (const struct ssol_instance* instance, 926 double* area); 927 928 SSOL_API res_T 929 ssol_instance_get_shaded_shapes_count 930 (const struct ssol_instance* instance, 931 size_t* nshaded_shapes); 932 933 SSOL_API res_T 934 ssol_instance_get_shaded_shape 935 (const struct ssol_instance* instance, 936 const size_t ishaded_shape, 937 struct ssol_instantiated_shaded_shape* shaded_shape_instance); 938 939 SSOL_API res_T 940 ssol_instantiated_shaded_shape_get_vertex_attrib 941 (const struct ssol_instantiated_shaded_shape* sshape, 942 const unsigned ivert, 943 const enum ssol_attrib_usage usage, 944 double value[]); 945 946 /******************************************************************************* 947 * Param buffer API 948 ******************************************************************************/ 949 SSOL_API res_T 950 ssol_param_buffer_create 951 (struct ssol_device* dev, 952 const size_t capacity, 953 struct ssol_param_buffer** buf); 954 955 SSOL_API res_T 956 ssol_param_buffer_ref_get 957 (struct ssol_param_buffer* buf); 958 959 SSOL_API res_T 960 ssol_param_buffer_ref_put 961 (struct ssol_param_buffer* buf); 962 963 SSOL_API void* 964 ssol_param_buffer_allocate 965 (struct ssol_param_buffer* buf, 966 const size_t size, 967 const size_t alignment, /* Power of 2 in [1, 64] */ 968 /* Functor to invoke on the allocated memory priorly to its destruction. 969 * May be NULL */ 970 void (*release)(void*)); 971 972 /* Retrieve the address of the first allocated parameter */ 973 SSOL_API void* 974 ssol_param_buffer_get 975 (struct ssol_param_buffer* buf); 976 977 SSOL_API res_T 978 ssol_param_buffer_clear 979 (struct ssol_param_buffer* buf); 980 981 /******************************************************************************* 982 * Spectrum API - Collection of wavelengths with their associated data. 983 ******************************************************************************/ 984 SSOL_API res_T 985 ssol_spectrum_create 986 (struct ssol_device* dev, 987 struct ssol_spectrum** spectrum); 988 989 SSOL_API res_T 990 ssol_spectrum_ref_get 991 (struct ssol_spectrum* spectrum); 992 993 SSOL_API res_T 994 ssol_spectrum_ref_put 995 (struct ssol_spectrum* spectrum); 996 997 SSOL_API res_T 998 ssol_spectrum_setup 999 (struct ssol_spectrum* spectrum, 1000 void (*get)(const size_t iwlen, double* wlen, double* data, void* ctx), 1001 const size_t nwlens, 1002 void* ctx); 1003 1004 /******************************************************************************* 1005 * Sun API - Describe a sun model. 1006 ******************************************************************************/ 1007 /* The sun disk is infinitesimal small. The sun is thus only represented by its 1008 * main direction */ 1009 SSOL_API res_T 1010 ssol_sun_create_directional 1011 (struct ssol_device* dev, 1012 struct ssol_sun** sun); 1013 1014 /* The sun disk has a constant intensity */ 1015 SSOL_API res_T 1016 ssol_sun_create_pillbox 1017 (struct ssol_device* dev, 1018 struct ssol_sun** sun); 1019 1020 /* The sun disk intensity has a gaussian shape */ 1021 SSOL_API res_T 1022 ssol_sun_create_gaussian 1023 (struct ssol_device* dev, 1024 struct ssol_sun** sun); 1025 1026 /* The sun disk intensity is controlled by a circumsolar ratio. From the paper 1027 * "Sunshape distributions for terrestrial solar simulations". D. Buie, A.G. 1028 * Monger, C.J. Dey */ 1029 SSOL_API res_T 1030 ssol_sun_create_buie 1031 (struct ssol_device* dev, 1032 struct ssol_sun** sun); 1033 1034 SSOL_API res_T 1035 ssol_sun_ref_get 1036 (struct ssol_sun* sun); 1037 1038 SSOL_API res_T 1039 ssol_sun_ref_put 1040 (struct ssol_sun* sun); 1041 1042 /* Main sun direction, i.e. direction from the sun center toward the scene */ 1043 SSOL_API res_T 1044 ssol_sun_set_direction 1045 (struct ssol_sun* sun, 1046 const double direction[3]); 1047 1048 /* Main sun direction defined by location and date using the currently defined 1049 * algorithm. */ 1050 SSOL_API res_T 1051 ssol_sun_set_location_and_date 1052 (struct ssol_sun* sun, 1053 const struct ssol_location* location, 1054 const struct tm* date); 1055 1056 /* Set the algorithm used to produce sun direction from location and date. 1057 * Suns are created with algorithm == SSOL_SUN_DIRECTION_ALGORITHM_MEEUS, 1058 * regardless of their type. */ 1059 SSOL_API res_T 1060 ssol_sun_set_algorithm 1061 (struct ssol_sun* sun, 1062 const enum ssol_sun_direction_algorithm algorithm); 1063 1064 SSOL_API res_T 1065 ssol_sun_get_algorithm 1066 (const struct ssol_sun* sun, 1067 enum ssol_sun_direction_algorithm* algorithm); 1068 1069 /* Get direction from sun */ 1070 SSOL_API res_T 1071 ssol_sun_get_direction 1072 (const struct ssol_sun* sun, 1073 double direction[3]); 1074 1075 SSOL_API res_T 1076 ssol_sun_set_dni 1077 (struct ssol_sun* sun, 1078 const double dni); 1079 1080 SSOL_API res_T 1081 ssol_sun_get_dni 1082 (const struct ssol_sun* sun, 1083 double* dni); 1084 1085 /* List of per wavelength power of the sun */ 1086 SSOL_API res_T 1087 ssol_sun_set_spectrum 1088 (struct ssol_sun* sun, 1089 struct ssol_spectrum* spectrum); 1090 1091 SSOL_API res_T 1092 ssol_sun_pillbox_set_half_angle 1093 (struct ssol_sun* sun, 1094 const double half_angle); /* In ]0, PI/2], in radian */ 1095 1096 SSOL_API res_T 1097 ssol_sun_gaussian_set_std_dev 1098 (struct ssol_sun* sun, 1099 const double std_dev); /* In ]0, +Inf[, in radian */ 1100 1101 SSOL_API res_T 1102 ssol_sun_set_buie_param 1103 (struct ssol_sun* sun, 1104 const double param); /* In ]0, 1[ */ 1105 1106 /******************************************************************************* 1107 * Atmosphere API - Describe an atmosphere model. 1108 ******************************************************************************/ 1109 /* The atmosphere describes extinction along the light paths */ 1110 SSOL_API res_T 1111 ssol_atmosphere_create 1112 (struct ssol_device* dev, 1113 struct ssol_atmosphere** atmosphere); 1114 1115 SSOL_API res_T 1116 ssol_atmosphere_ref_get 1117 (struct ssol_atmosphere* atmosphere); 1118 1119 SSOL_API res_T 1120 ssol_atmosphere_ref_put 1121 (struct ssol_atmosphere* atmosphere); 1122 1123 SSOL_API res_T 1124 ssol_atmosphere_set_extinction 1125 (struct ssol_atmosphere* atmosphere, 1126 struct ssol_data* extinction); 1127 1128 /******************************************************************************* 1129 * Estimator API - Describe the state of a simulation. 1130 ******************************************************************************/ 1131 SSOL_API res_T 1132 ssol_estimator_ref_get 1133 (struct ssol_estimator* estimator); 1134 1135 SSOL_API res_T 1136 ssol_estimator_ref_put 1137 (struct ssol_estimator* estimator); 1138 1139 SSOL_API res_T 1140 ssol_estimator_get_mc_global 1141 (struct ssol_estimator* estimator, 1142 struct ssol_mc_global* mc_global); 1143 1144 SSOL_API res_T 1145 ssol_estimator_get_mc_sampled_x_receiver 1146 (struct ssol_estimator* estimator, 1147 const struct ssol_instance* prim_instance, 1148 const struct ssol_instance* recv_instance, 1149 const enum ssol_side_flag side, 1150 struct ssol_mc_receiver* rcv); 1151 1152 SSOL_API res_T 1153 ssol_estimator_get_realisation_count 1154 (const struct ssol_estimator* estimator, 1155 size_t* count); 1156 1157 SSOL_API res_T 1158 ssol_estimator_get_failed_count 1159 (const struct ssol_estimator* estimator, 1160 size_t* count); 1161 1162 /* Retrieve the overall area of the sampled instances */ 1163 SSOL_API res_T 1164 ssol_estimator_get_sampled_area 1165 (const struct ssol_estimator* estimator, 1166 double* area); 1167 1168 SSOL_API res_T 1169 ssol_estimator_get_sampled_count 1170 (const struct ssol_estimator* estimator, 1171 size_t* count); 1172 1173 SSOL_API res_T 1174 ssol_estimator_get_mc_sampled 1175 (struct ssol_estimator* estimator, 1176 const struct ssol_instance* samp_instance, 1177 struct ssol_mc_sampled* sampled); 1178 1179 /* Retrieve the RNG state at the end of the simulation */ 1180 SSOL_API res_T 1181 ssol_estimator_get_rng_state 1182 (const struct ssol_estimator* estimator, 1183 const struct ssp_rng** rng_state); 1184 1185 /******************************************************************************* 1186 * Tracked paths 1187 ******************************************************************************/ 1188 SSOL_API res_T 1189 ssol_estimator_get_tracked_paths_count 1190 (const struct ssol_estimator* estimator, 1191 size_t* npaths); 1192 1193 SSOL_API res_T 1194 ssol_estimator_get_tracked_path 1195 (const struct ssol_estimator* estimator, 1196 const size_t ipath, 1197 struct ssol_path* path); 1198 1199 SSOL_API res_T 1200 ssol_path_get_vertices_count 1201 (const struct ssol_path* path, 1202 size_t* nvertices); 1203 1204 SSOL_API res_T 1205 ssol_path_get_vertex 1206 (const struct ssol_path* path, 1207 const size_t ivertex, 1208 struct ssol_path_vertex* vertex); 1209 1210 SSOL_API res_T 1211 ssol_path_get_type 1212 (const struct ssol_path* path, 1213 enum ssol_path_type* type); 1214 1215 /******************************************************************************* 1216 * Per receiver MC estimations 1217 ******************************************************************************/ 1218 SSOL_API res_T 1219 ssol_estimator_get_mc_receiver 1220 (struct ssol_estimator* estimator, 1221 const struct ssol_instance* instance, 1222 const enum ssol_side_flag side, 1223 struct ssol_mc_receiver* rcv); 1224 1225 SSOL_API res_T 1226 ssol_mc_receiver_get_mc_shape 1227 (struct ssol_mc_receiver* rcv, 1228 const struct ssol_shape* shape, 1229 struct ssol_mc_shape* mc); 1230 1231 SSOL_API res_T 1232 ssol_mc_shape_get_mc_primitive 1233 (struct ssol_mc_shape* shape, 1234 const unsigned i, /* In [0, ssol_shape_get_triangles_count[ */ 1235 struct ssol_mc_primitive* prim); 1236 1237 /******************************************************************************* 1238 * Miscellaneous functions 1239 ******************************************************************************/ 1240 SSOL_API res_T 1241 ssol_solve 1242 (struct ssol_scene* scn, 1243 const struct ssp_rng* rng, 1244 const size_t realisations_count, 1245 const size_t max_failed_count, 1246 const struct ssol_path_tracker* tracker, /* NULL<=>Do not record the paths */ 1247 struct ssol_estimator** estimator); 1248 1249 SSOL_API res_T 1250 ssol_draw_draft 1251 (struct ssol_scene* scn, 1252 struct ssol_camera* cam, 1253 const size_t width, /* #pixels in X */ 1254 const size_t height, /* #pixels in Y */ 1255 const size_t spp, /* #samples per pixel */ 1256 ssol_write_pixels_T writer, 1257 void* writer_data); 1258 1259 SSOL_API res_T 1260 ssol_draw_pt 1261 (struct ssol_scene* scn, 1262 struct ssol_camera* cam, 1263 const size_t width, /* #pixels in X */ 1264 const size_t height, /* #pixels in Y */ 1265 const size_t spp, 1266 const double up[3], /* Direction toward the top of the skydome */ 1267 ssol_write_pixels_T writer, 1268 void* writer_data); 1269 1270 /******************************************************************************* 1271 * Data API 1272 ******************************************************************************/ 1273 SSOL_API struct ssol_data* 1274 ssol_data_set_real 1275 (struct ssol_data* data, 1276 const double real); 1277 1278 /* Get a reference onto the submitted spectrum */ 1279 SSOL_API struct ssol_data* 1280 ssol_data_set_spectrum 1281 (struct ssol_data* data, 1282 struct ssol_spectrum* spectrum); 1283 1284 /* Release the reference on its associated spectrum, if defined */ 1285 SSOL_API struct ssol_data* 1286 ssol_data_clear 1287 (struct ssol_data* data); 1288 1289 SSOL_API struct ssol_data* 1290 ssol_data_copy 1291 (struct ssol_data* dst, 1292 const struct ssol_data* src); 1293 1294 SSOL_API double 1295 ssol_data_get_value 1296 (const struct ssol_data* data, 1297 const double wavelength); 1298 1299 /******************************************************************************* 1300 * Medium API 1301 ******************************************************************************/ 1302 static FINLINE struct ssol_medium* 1303 ssol_medium_clear(struct ssol_medium* medium) 1304 { 1305 ASSERT(medium); 1306 ssol_data_clear(&medium->extinction); 1307 ssol_data_clear(&medium->refractive_index); 1308 return medium; 1309 } 1310 1311 static FINLINE struct ssol_medium* 1312 ssol_medium_copy(struct ssol_medium* dst, const struct ssol_medium* src) 1313 { 1314 ASSERT(dst && src); 1315 ssol_data_copy(&dst->extinction, &src->extinction); 1316 ssol_data_copy(&dst->refractive_index, &src->refractive_index); 1317 return dst; 1318 } 1319 1320 END_DECLS 1321 1322 #endif /* SSOL_H */ 1323