diff --git a/src/rendering/clouds/clo_tools.c b/src/rendering/clouds/clo_tools.c index 5337e54..bacf5b5 100644 --- a/src/rendering/clouds/clo_tools.c +++ b/src/rendering/clouds/clo_tools.c @@ -89,22 +89,16 @@ static Color _applyLayerLighting(CloudsLayerDefinition* definition, Renderer* re Color cloudsApplyLayer(CloudsLayerDefinition* definition, Color base, Renderer* renderer, Vector3 start, Vector3 end) { - int segment_count; - Color col; - CloudPrimarySegment segments[MAX_SEGMENT_COUNT]; + Color col = COLOR_TRANSPARENT; - segment_count = cloudsGetLayerPrimarySegments(renderer, definition, start, end, MAX_SEGMENT_COUNT, segments); - /* TODO Crawl in segments for render */ - - col = definition->material.base; - /*if (definition->transparencydepth == 0 || inside_length >= definition->transparencydepth) + if (!cloudsOptimizeWalkingBounds(definition, &start, &end)) { - col.a = 1.0; + return base; } - else - { - col.a = inside_length / definition->transparencydepth; - }*/ + + /* TODO Walk through the cloud */ + + /*segment_count = cloudsGetLayerPrimarySegments(renderer, definition, start, end, MAX_SEGMENT_COUNT, segments);*/ col = renderer->atmosphere->applyAerialPerspective(renderer, start, col).final; col.a = 0.0; diff --git a/src/rendering/clouds/clo_walking.c b/src/rendering/clouds/clo_walking.c index e4987ee..35a0029 100644 --- a/src/rendering/clouds/clo_walking.c +++ b/src/rendering/clouds/clo_walking.c @@ -2,6 +2,7 @@ #include "../renderer.h" + int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end) { Vector3 diff; @@ -51,111 +52,5 @@ int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Ve } } - /* TODO Limit the search length */ return 1; } - -int cloudsGetLayerPrimarySegments(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end, int max_segments, CloudPrimarySegment* out_segments) -{ - int inside, segment_count; - double step_length, segment_length; - Vector3 diff, walker, segment_start; - double render_precision, density; - double diff_length, progress; - - if (max_segments <= 0) - { - return 0; - } - - if (!cloudsOptimizeWalkingBounds(layer, &start, &end)) - { - return 0; - } - - diff = v3Sub(end, start); - diff_length = v3Norm(diff); - - if (diff_length < 0.000001) - { - return 0; - } - - render_precision = 1.005 - 0.01 * (double)(renderer->render_quality * renderer->render_quality); - /*if (render_precision > max_total_length / 10.0) - { - render_precision = max_total_length / 10.0; - } - else if (render_precision < max_total_length / 10000.0) - { - render_precision = max_total_length / 10000.0; - }*/ - - segment_count = 0; - segment_length = 0.0; - density = renderer->clouds->getLayerDensity(renderer, layer, start); - progress = 0.0; - step_length = render_precision; - inside = (density > 0.0); - - do - { - progress += step_length; - walker = v3Add(start, v3Scale(diff, progress / diff_length)); - - if (progress >= diff_length) - { - density = 0.0; - } - else - { - density = renderer->clouds->getLayerDensity(renderer, layer, walker); - } - - if (density > 0.0) - { - if (inside) - { - /* inside the cloud */ - segment_length += step_length; - } - else - { - /* entering the cloud */ - segment_length = step_length; - segment_start = v3Add(start, v3Scale(diff, (progress - step_length) / diff_length)); - /* TODO Refine entry position */ - - inside = 1; - } - } - else - { - if (inside) - { - /* exiting the cloud */ - segment_length += step_length; - - out_segments->entry_point = segment_start; - out_segments->exit_point = walker; - out_segments->length = segment_length; - out_segments++; - if (++segment_count >= max_segments) - { - break; - } - /* TODO Refine exit position */ - - inside = 0; - } - } - /* step = v3Scale(direction, (info.distance_to_edge < render_precision) ? render_precision : info.distance_to_edge); */ - } - while (inside || (walker.y <= layer->lower_altitude + layer->thickness + 0.001 && walker.y >= layer->lower_altitude - 0.001 && progress < diff_length)); - - return segment_count; -} - -int cloudsGetLayerSecondarySampling(Renderer* renderer, CloudsLayerDefinition* layer, CloudPrimarySegment* segment, int max_control_points, CloudSecondaryControlPoint* out_control_points) -{ -} diff --git a/src/rendering/clouds/clo_walking.h b/src/rendering/clouds/clo_walking.h index 489be79..7984c66 100644 --- a/src/rendering/clouds/clo_walking.h +++ b/src/rendering/clouds/clo_walking.h @@ -5,7 +5,7 @@ #include "../tools/euclid.h" /** - * Functions to walk through a cloud layer (sampling). + * Functions to walk through a cloud layer. */ #ifdef __cplusplus @@ -13,26 +13,47 @@ extern "C" { #endif +/** + * Information on a segment yielded by walking. + */ typedef struct { - Vector3 entry_point; - Vector3 exit_point; - double length; -} CloudPrimarySegment; + Renderer* renderer; + CloudsLayerDefinition* layer; + double walked_distance; + Vector3 start; + Vector3 end; + double length; + + int refined; + int subdivision_level; + double precision_asked; + + void* data; +} CloudWalkingInfo; + +/** + * Control of the next walking order. + */ +typedef enum +{ + CLOUD_WALKING_CONTINUE, + CLOUD_WALKING_STOP, + CLOUD_WALKING_REFINE, + CLOUD_WALKING_SUBDIVIDE +} CloudWalkingOrder; + +/** + * Additional info for walking orders. + */ typedef struct { - /** Distance factor of the control point from the segment start */ - double distance; - /** Location of the control point */ - Vector3 location; - /** Global density at the control point (no edge noise applied) */ - double global_density; - /** Particle dentisy at the control point, using edge noise */ - double particle_density; - /** Estimated distance to nearest cloud exit */ - double nearest_exit_distance; -} CloudSecondaryControlPoint; + double precision; + int max_segments; +} CloudWalkingOrderInfo; + +typedef CloudWalkingOrder(*FuncCloudSegmentCallback)(CloudWalkingInfo* segment, CloudWalkingOrderInfo* order); /** * Optimize the search limits in a layer. @@ -45,29 +66,18 @@ typedef struct int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end); /** - * Go through the cloud layer to find segments (parts of the lookup that are likely to contain cloud). + * Start walking through a segment. * + * For better performance, the segment should by optimized using cloudsOptimizeWalkingBounds. + * The callback will be called with each segment found, giving info and asking for desired alteration on walking. * @param renderer The renderer environment * @param layer The cloud layer - * @param start Start position of the lookup - * @param end End position of the lookup - * @param max_segments Maximum number of segments to collect - * @param out_segments Allocated space to fill found segments (must be at least 'max_segments' long) - * @return Number of segments found + * @param start Start position of the lookup, already optimized + * @param end End position of the lookup, already optimized + * @param callback Callback to be called with each found segment + * @param data User data that will be passed back in the callback */ -int cloudsGetLayerPrimarySegments(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end, int max_segments, CloudPrimarySegment* out_segments); - -/** - * Sample a primary segment with refined details, collecting material interaction. - * - * @param renderer The renderer environment - * @param layer The cloud layer - * @param segment The primary segment to sample - * @param max_control_points Maximum number of control points to sample - * @param out_control_points Allocated space to fill with secondary control points (must be at least 'max_control_points' long) - * @return Number of control points sampled - */ -int cloudsGetLayerSecondarySampling(Renderer* renderer, CloudsLayerDefinition* layer, CloudPrimarySegment* segment, int max_control_points, CloudSecondaryControlPoint* out_control_points); +void cloudsStartWalking(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end, FuncCloudSegmentCallback callback, void* data); #ifdef __cplusplus } diff --git a/src/testing/test_clouds.c b/src/testing/test_clouds.c index 8636c7a..4bd6c57 100644 --- a/src/testing/test_clouds.c +++ b/src/testing/test_clouds.c @@ -200,7 +200,7 @@ static double _getLayerDensitySinX(Renderer* renderer, CloudsLayerDefinition* la return (density > 0.0) ? density : 0.0; } -START_TEST(test_clouds_primary_segments) +/*START_TEST(test_clouds_primary_segments) { int segment_count, i; CloudPrimarySegment segments[10]; @@ -237,16 +237,8 @@ START_TEST(test_clouds_primary_segments) cloudsGetLayerType().callback_delete(layer); rendererDelete(renderer); } -END_TEST +END_TEST*/ -START_TEST(test_clouds_preview_color) -{ - Renderer* renderer = cloudsCreatePreviewColorRenderer(); - - /* TODO Test the density overriding */ - - rendererDelete(renderer); -} -END_TEST - -TEST_CASE(clouds, test_clouds_density, test_clouds_walking_boundaries, test_clouds_primary_segments, test_clouds_preview_color) +TEST_CASE(clouds, + test_clouds_density, + test_clouds_walking_boundaries)