#ifndef LIGHT_H #define LIGHT_H #include "Algorithm/BVH.h" #include "Algorithm/Sobol.h" #include "Geometry/Triangle.h" #include "Material/Material.h" #include "cglm/struct/vec3.h" #define SKY_DATA_CAPACITY 64 typedef enum { SKY_TYPE_CONSTANT, } sky_type_t; typedef struct { vec3s normal; vec3s hit_point; vec3s wo; vec2s uv; uint16_t bounce_depth; const bvh_tree_t* bvh_tree; const material_t* material; } light_shading_context_t; #ifdef __STDC_ALIGN__ #define SKY_ALIGN _Alignof(max_align_t) #else #define SKY_ALIGN (sizeof(void*)) #endif typedef vec3s (*evaluate_bsdf_sky_f) (const void* data, const light_shading_context_t* context, vec3s throughput, uint32_t index); typedef struct { evaluate_bsdf_sky_f evaluate_bsdf_sky; sky_type_t type; uint16_t data_size; _Alignas(SKY_ALIGN) char data[SKY_DATA_CAPACITY]; } sky_light_t; typedef enum { LIGHT_TYPE_POINT, LIGHT_TYPE_SPOT, LIGHT_TYPE_AREA, } punctual_light_type_e; typedef struct { vec3s position; vec3s color; float intensity; punctual_light_type_e type; } punctual_light_t; typedef struct { vec3s direction; vec3s color; float intensity; float angular_diameter; } directional_light_t; typedef struct { uint32_t punctual_light_count; uint32_t directional_light_count; uint32_t max_punctual_lights; uint32_t max_directional_lights; sky_light_t sky_light; punctual_light_t* punctual_lights; directional_light_t* directional_lights; } light_collection_t; typedef struct { uint32_t id; bool is_punctual; } light_entity_t; inline bool light_collection_create(uint32_t max_punctual_lights, uint32_t max_directional_lights, light_collection_t* collection) { if (max_punctual_lights == 0 || max_directional_lights == 0) { return false; } collection->max_punctual_lights = max_punctual_lights; collection->max_directional_lights = max_directional_lights; collection->punctual_light_count = 0; collection->directional_light_count = 0; collection->punctual_lights = (punctual_light_t*)malloc(max_punctual_lights * sizeof(punctual_light_t)); if (collection->punctual_lights == NULL) { return false; } collection->directional_lights = (directional_light_t*)malloc(max_directional_lights * sizeof(directional_light_t)); if (collection->directional_lights == NULL) { free(collection->punctual_lights); return false; } return true; } inline light_entity_t light_create_punctual_light(light_collection_t* collection) { if (collection->punctual_light_count >= collection->max_punctual_lights) { return (light_entity_t){0}; } punctual_light_t light = {0}; collection->punctual_lights[collection->punctual_light_count] = light; light_entity_t entity = {.id = collection->punctual_light_count, .is_punctual = true}; collection->punctual_light_count++; return entity; } inline light_entity_t light_create_directional_light(light_collection_t* collection) { if (collection->directional_light_count >= collection->max_directional_lights) { return (light_entity_t){0}; } directional_light_t light = {0}; collection->directional_lights[collection->directional_light_count] = light; light_entity_t entity = {.id = collection->directional_light_count, .is_punctual = false}; collection->directional_light_count++; return entity; } inline void light_collection_free(light_collection_t* collection) { free(collection->punctual_lights); free(collection->directional_lights); collection->max_punctual_lights = 0; collection->max_directional_lights = 0; collection->punctual_light_count = 0; collection->directional_light_count = 0; collection->punctual_lights = NULL; collection->directional_lights = NULL; } #endif // LIGHT_H