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