Added cloud walker subdivision system
This commit is contained in:
parent
5a5067e745
commit
d8695803b4
3 changed files with 252 additions and 45 deletions
|
@ -35,10 +35,15 @@ struct CloudsWalker
|
||||||
double cursor;
|
double cursor;
|
||||||
double max_length;
|
double max_length;
|
||||||
double step_size;
|
double step_size;
|
||||||
|
int skip_void;
|
||||||
|
|
||||||
int started;
|
int started;
|
||||||
CloudWalkerStepInfo last_segment;
|
CloudWalkerStepInfo last_segment;
|
||||||
|
|
||||||
|
int subdivision_current;
|
||||||
|
int subdivision_count;
|
||||||
|
CloudWalkerStepInfo subdivision_parent;
|
||||||
|
|
||||||
CloudWalkingNextAction next_action;
|
CloudWalkingNextAction next_action;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,8 +112,10 @@ CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* laye
|
||||||
result->max_length = v3Norm(result->diff);
|
result->max_length = v3Norm(result->diff);
|
||||||
result->cursor = 0.0;
|
result->cursor = 0.0;
|
||||||
result->step_size = 1.0;
|
result->step_size = 1.0;
|
||||||
|
result->skip_void = 0;
|
||||||
|
|
||||||
result->started = 0;
|
result->started = 0;
|
||||||
|
result->subdivision_count = 0;
|
||||||
result->last_segment.renderer = renderer;
|
result->last_segment.renderer = renderer;
|
||||||
result->last_segment.layer = layer;
|
result->last_segment.layer = layer;
|
||||||
|
|
||||||
|
@ -135,6 +142,11 @@ void cloudsWalkerSetStepSize(CloudsWalker* walker, double step)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cloudsWalkerSetVoidSkipping(CloudsWalker* walker, int enabled)
|
||||||
|
{
|
||||||
|
walker->skip_void = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
static void _getPoint(CloudsWalker* walker, double cursor, CloudWalkerPoint* out_point)
|
static void _getPoint(CloudsWalker* walker, double cursor, CloudWalkerPoint* out_point)
|
||||||
{
|
{
|
||||||
out_point->distance_from_start = cursor;
|
out_point->distance_from_start = cursor;
|
||||||
|
@ -187,52 +199,114 @@ static void _refineSegment(CloudsWalker* walker, double start_cursor, double sta
|
||||||
|
|
||||||
int cloudsWalkerPerformStep(CloudsWalker* walker)
|
int cloudsWalkerPerformStep(CloudsWalker* walker)
|
||||||
{
|
{
|
||||||
|
int result = -1;
|
||||||
|
|
||||||
if (!walker->started)
|
if (!walker->started)
|
||||||
{
|
{
|
||||||
_getPoint(walker, 0.0, &walker->last_segment.end);
|
_getPoint(walker, 0.0, &walker->last_segment.end);
|
||||||
walker->started = 1;
|
walker->started = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (walker->next_action.order == CLOUD_WALKING_STOP || walker->cursor >= walker->max_length)
|
while (result < 0)
|
||||||
{
|
{
|
||||||
walker->next_action.order = CLOUD_WALKING_STOP;
|
if (walker->next_action.order == CLOUD_WALKING_STOP || walker->cursor >= walker->max_length)
|
||||||
return 0;
|
{
|
||||||
|
walker->next_action.order = CLOUD_WALKING_STOP;
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
else if (walker->subdivision_count > 0)
|
||||||
|
{
|
||||||
|
if (walker->subdivision_current >= walker->subdivision_count)
|
||||||
|
{
|
||||||
|
/* Exit subdivision */
|
||||||
|
walker->subdivision_count = 0;
|
||||||
|
walker->last_segment = walker->subdivision_parent;
|
||||||
|
walker->next_action.order = CLOUD_WALKING_CONTINUE;
|
||||||
|
walker->cursor = walker->subdivision_parent.end.distance_from_start;
|
||||||
|
|
||||||
|
/* Recursive call to progress */
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Continue subdivision */
|
||||||
|
walker->last_segment.start = walker->last_segment.end;
|
||||||
|
|
||||||
|
walker->cursor += walker->subdivision_parent.length / (double)walker->subdivision_count;
|
||||||
|
|
||||||
|
_getPoint(walker, walker->cursor, &walker->last_segment.end);
|
||||||
|
walker->last_segment.length = walker->subdivision_parent.length / (double)walker->subdivision_count;
|
||||||
|
walker->last_segment.refined = 0;
|
||||||
|
walker->last_segment.subdivided = walker->subdivision_count;
|
||||||
|
|
||||||
|
walker->subdivision_current++;
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (walker->next_action.order == CLOUD_WALKING_CONTINUE)
|
||||||
|
{
|
||||||
|
/* TODO Limit to lookup end */
|
||||||
|
walker->last_segment.start = walker->last_segment.end;
|
||||||
|
|
||||||
|
walker->cursor += walker->step_size;
|
||||||
|
|
||||||
|
_getPoint(walker, walker->cursor, &walker->last_segment.end);
|
||||||
|
walker->last_segment.length = walker->step_size;
|
||||||
|
walker->last_segment.refined = 0;
|
||||||
|
walker->last_segment.subdivided = 0;
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else if (walker->next_action.order == CLOUD_WALKING_REFINE)
|
||||||
|
{
|
||||||
|
/* Refine segment with dichotomy */
|
||||||
|
_refineSegment(walker,
|
||||||
|
walker->last_segment.start.distance_from_start,
|
||||||
|
walker->last_segment.start.global_density,
|
||||||
|
walker->last_segment.end.distance_from_start,
|
||||||
|
walker->last_segment.end.global_density,
|
||||||
|
walker->next_action.precision,
|
||||||
|
(walker->last_segment.start.global_density == 0.0) ? (&walker->last_segment.start) : (&walker->last_segment.end));
|
||||||
|
walker->last_segment.length = walker->last_segment.end.distance_from_start - walker->last_segment.start.distance_from_start;
|
||||||
|
walker->last_segment.refined = 1;
|
||||||
|
walker->last_segment.subdivided = 0;
|
||||||
|
|
||||||
|
walker->next_action.order = CLOUD_WALKING_CONTINUE;
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else if (walker->next_action.order == CLOUD_WALKING_SUBDIVIDE)
|
||||||
|
{
|
||||||
|
/* Starting subdivision */
|
||||||
|
walker->subdivision_count = walker->next_action.max_segments;
|
||||||
|
walker->subdivision_current = 0;
|
||||||
|
walker->subdivision_parent = walker->last_segment;
|
||||||
|
walker->cursor = walker->subdivision_parent.start.distance_from_start;
|
||||||
|
|
||||||
|
/* Copy parent segment start, to be used as first subdivided segment start */
|
||||||
|
walker->last_segment.end = walker->subdivision_parent.start;
|
||||||
|
|
||||||
|
/* Recursive call to get first subdivided segment */
|
||||||
|
cloudsWalkerPerformStep(walker);
|
||||||
|
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Unknown order... */
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if we need to loop */
|
||||||
|
if (result > 0 && walker->skip_void && walker->last_segment.start.global_density == 0.0 && walker->last_segment.end.global_density == 0.0)
|
||||||
|
{
|
||||||
|
/* Last segment is considered void, and skipping is enabled */
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (walker->next_action.order == CLOUD_WALKING_CONTINUE)
|
|
||||||
{
|
|
||||||
/* TODO Limit to end */
|
|
||||||
walker->last_segment.start = walker->last_segment.end;
|
|
||||||
|
|
||||||
walker->cursor += walker->step_size;
|
return result;
|
||||||
|
|
||||||
_getPoint(walker, walker->cursor, &walker->last_segment.end);
|
|
||||||
walker->last_segment.length = walker->step_size;
|
|
||||||
walker->last_segment.refined = 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else if (walker->next_action.order == CLOUD_WALKING_REFINE)
|
|
||||||
{
|
|
||||||
/* Refine segment with dichotomy */
|
|
||||||
_refineSegment(walker,
|
|
||||||
walker->last_segment.start.distance_from_start,
|
|
||||||
walker->last_segment.start.global_density,
|
|
||||||
walker->last_segment.end.distance_from_start,
|
|
||||||
walker->last_segment.end.global_density,
|
|
||||||
walker->next_action.precision,
|
|
||||||
(walker->last_segment.start.global_density == 0.0) ? (&walker->last_segment.start) : (&walker->last_segment.end));
|
|
||||||
walker->last_segment.length = walker->last_segment.end.distance_from_start - walker->last_segment.start.distance_from_start;
|
|
||||||
walker->last_segment.refined = 1;
|
|
||||||
|
|
||||||
walker->next_action.order = CLOUD_WALKING_CONTINUE;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* TODO */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsWalkerOrderStop(CloudsWalker* walker)
|
void cloudsWalkerOrderStop(CloudsWalker* walker)
|
||||||
|
@ -242,14 +316,20 @@ void cloudsWalkerOrderStop(CloudsWalker* walker)
|
||||||
|
|
||||||
void cloudsWalkerOrderRefine(CloudsWalker* walker, double precision)
|
void cloudsWalkerOrderRefine(CloudsWalker* walker, double precision)
|
||||||
{
|
{
|
||||||
walker->next_action.order = CLOUD_WALKING_REFINE;
|
if (walker->subdivision_count == 0)
|
||||||
walker->next_action.precision = precision;
|
{
|
||||||
|
walker->next_action.order = CLOUD_WALKING_REFINE;
|
||||||
|
walker->next_action.precision = precision;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsWalkerOrderSubdivide(CloudsWalker* walker, double max_segments)
|
void cloudsWalkerOrderSubdivide(CloudsWalker* walker, double max_segments)
|
||||||
{
|
{
|
||||||
walker->next_action.order = CLOUD_WALKING_SUBDIVIDE;
|
if (walker->subdivision_count == 0)
|
||||||
walker->next_action.max_segments = max_segments;
|
{
|
||||||
|
walker->next_action.order = CLOUD_WALKING_SUBDIVIDE;
|
||||||
|
walker->next_action.max_segments = max_segments;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudWalkerStepInfo* cloudsWalkerGetLastSegment(CloudsWalker* walker)
|
CloudWalkerStepInfo* cloudsWalkerGetLastSegment(CloudsWalker* walker)
|
||||||
|
|
|
@ -33,8 +33,7 @@ typedef struct
|
||||||
double length;
|
double length;
|
||||||
|
|
||||||
int refined;
|
int refined;
|
||||||
/*int subdivision_level;
|
int subdivided;
|
||||||
double precision_asked;*/
|
|
||||||
|
|
||||||
void* data;
|
void* data;
|
||||||
} CloudWalkerStepInfo;
|
} CloudWalkerStepInfo;
|
||||||
|
@ -79,6 +78,14 @@ void cloudsDeleteWalker(CloudsWalker* walker);
|
||||||
*/
|
*/
|
||||||
void cloudsWalkerSetStepSize(CloudsWalker* walker, double step);
|
void cloudsWalkerSetStepSize(CloudsWalker* walker, double step);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the void skipping mode.
|
||||||
|
*
|
||||||
|
* @param walker The walker to configure
|
||||||
|
* @param enabled 1 to enable the void skipping, 0 to disable
|
||||||
|
*/
|
||||||
|
void cloudsWalkerSetVoidSkipping(CloudsWalker* walker, int enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a single step.
|
* Perform a single step.
|
||||||
*
|
*
|
||||||
|
@ -108,6 +115,8 @@ void cloudsWalkerOrderRefine(CloudsWalker* walker, double precision);
|
||||||
/**
|
/**
|
||||||
* Order the walker to subdivide the previous segment in smaller segments.
|
* Order the walker to subdivide the previous segment in smaller segments.
|
||||||
*
|
*
|
||||||
|
* Next steps will yield subdivided segments. Once subdivided segments have been processed, normal walking
|
||||||
|
* will resume automatically.
|
||||||
* @param walker The walker to use
|
* @param walker The walker to use
|
||||||
* @param max_segments Maximal number of segments
|
* @param max_segments Maximal number of segments
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -215,7 +215,7 @@ START_TEST(test_clouds_walking)
|
||||||
renderer->render_quality = 8;
|
renderer->render_quality = 8;
|
||||||
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
|
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
|
||||||
|
|
||||||
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(10.0, 0.0, 0.0));
|
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(1.75, 0.0, 0.0));
|
||||||
CloudWalkerStepInfo* segment;
|
CloudWalkerStepInfo* segment;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
|
@ -225,6 +225,7 @@ START_TEST(test_clouds_walking)
|
||||||
segment = cloudsWalkerGetLastSegment(walker);
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
ck_assert_int_eq(result, 1);
|
ck_assert_int_eq(result, 1);
|
||||||
ck_assert_false(segment->refined);
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
ck_assert_double_eq(segment->length, 0.3);
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
ck_assert_double_eq(segment->start.distance_from_start, 0.0);
|
ck_assert_double_eq(segment->start.distance_from_start, 0.0);
|
||||||
ck_assert_vector_values(segment->start.location, -0.4, 0.0, 0.0);
|
ck_assert_vector_values(segment->start.location, -0.4, 0.0, 0.0);
|
||||||
|
@ -238,6 +239,7 @@ START_TEST(test_clouds_walking)
|
||||||
segment = cloudsWalkerGetLastSegment(walker);
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
ck_assert_int_eq(result, 1);
|
ck_assert_int_eq(result, 1);
|
||||||
ck_assert_false(segment->refined);
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
ck_assert_double_eq(segment->length, 0.3);
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
ck_assert_double_eq(segment->start.distance_from_start, 0.3);
|
ck_assert_double_eq(segment->start.distance_from_start, 0.3);
|
||||||
ck_assert_vector_values(segment->start.location, -0.1, 0.0, 0.0);
|
ck_assert_vector_values(segment->start.location, -0.1, 0.0, 0.0);
|
||||||
|
@ -252,6 +254,7 @@ START_TEST(test_clouds_walking)
|
||||||
segment = cloudsWalkerGetLastSegment(walker);
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
ck_assert_int_eq(result, 1);
|
ck_assert_int_eq(result, 1);
|
||||||
ck_assert_true(segment->refined);
|
ck_assert_true(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
ck_assert_double_in_range(segment->length, 0.19, 0.20);
|
ck_assert_double_in_range(segment->length, 0.19, 0.20);
|
||||||
ck_assert_double_in_range(segment->start.distance_from_start, 0.40, 0.41);
|
ck_assert_double_in_range(segment->start.distance_from_start, 0.40, 0.41);
|
||||||
ck_assert_double_in_range(segment->start.location.x, 0.0, 0.01);
|
ck_assert_double_in_range(segment->start.location.x, 0.0, 0.01);
|
||||||
|
@ -266,6 +269,7 @@ START_TEST(test_clouds_walking)
|
||||||
segment = cloudsWalkerGetLastSegment(walker);
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
ck_assert_int_eq(result, 1);
|
ck_assert_int_eq(result, 1);
|
||||||
ck_assert_false(segment->refined);
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
ck_assert_double_eq(segment->length, 0.4);
|
ck_assert_double_eq(segment->length, 0.4);
|
||||||
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
|
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
|
||||||
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
|
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
|
||||||
|
@ -280,13 +284,127 @@ START_TEST(test_clouds_walking)
|
||||||
segment = cloudsWalkerGetLastSegment(walker);
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
ck_assert_int_eq(result, 1);
|
ck_assert_int_eq(result, 1);
|
||||||
ck_assert_true(segment->refined);
|
ck_assert_true(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
ck_assert_double_in_range(segment->length, 0.3, 0.301);
|
ck_assert_double_in_range(segment->length, 0.3, 0.301);
|
||||||
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
|
ck_assert_double_eq(segment->start.distance_from_start, 0.6);
|
||||||
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
|
ck_assert_vector_values(segment->start.location, 0.2, 0.0, 0.0);
|
||||||
ck_assert_double_gt(segment->start.global_density, 0.9);
|
ck_assert_double_gt(segment->start.global_density, 0.9);
|
||||||
ck_assert_double_in_range(segment->end.distance_from_start, 0.9, 0.901);
|
ck_assert_double_in_range(segment->end.distance_from_start, 0.9, 0.901);
|
||||||
ck_assert_double_in_range(segment->end.location.x, 0.5, 0.501);
|
ck_assert_double_in_range(segment->end.location.x, 0.5, 0.501);
|
||||||
ck_assert_double_lt(segment->end.global_density, 0.1);
|
ck_assert_double_eq(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* Find next entry point by skipping blank */
|
||||||
|
cloudsWalkerSetVoidSkipping(walker, 1);
|
||||||
|
cloudsWalkerSetStepSize(walker, 0.2);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, 0.2);
|
||||||
|
ck_assert_double_in_range(segment->start.distance_from_start, 1.2, 1.4);
|
||||||
|
ck_assert_double_in_range(segment->start.location.x, 0.8, 1.0);
|
||||||
|
ck_assert_double_eq(segment->start.global_density, 0.0);
|
||||||
|
ck_assert_double_in_range(segment->end.distance_from_start, 1.4, 1.6);
|
||||||
|
ck_assert_double_in_range(segment->end.location.x, 1.0, 1.2);
|
||||||
|
ck_assert_double_gt(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* Refine entry point */
|
||||||
|
cloudsWalkerOrderRefine(walker, 0.01);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_true(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
|
ck_assert_double_in_range(segment->length, 0.0, 0.2);
|
||||||
|
ck_assert_double_in_range(segment->start.distance_from_start, 1.4, 1.41);
|
||||||
|
ck_assert_double_in_range(segment->start.location.x, 1.0, 1.01);
|
||||||
|
ck_assert_double_gt(segment->start.global_density, 0.0);
|
||||||
|
ck_assert_double_in_range(segment->end.distance_from_start, 1.41, 1.6);
|
||||||
|
ck_assert_double_in_range(segment->end.location.x, 1.01, 1.2);
|
||||||
|
ck_assert_double_gt(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* Subdivide entry for more detail */
|
||||||
|
CloudWalkerStepInfo parent = *segment;
|
||||||
|
cloudsWalkerOrderSubdivide(walker, 3);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_true(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, parent.length / 3.0);
|
||||||
|
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start);
|
||||||
|
ck_assert_double_eq(segment->start.location.x, parent.start.location.x);
|
||||||
|
ck_assert_double_eq(segment->end.distance_from_start, parent.start.distance_from_start + segment->length);
|
||||||
|
ck_assert_double_eq(segment->end.location.x, parent.start.location.x + segment->length);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_true(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, parent.length / 3.0);
|
||||||
|
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start + segment->length);
|
||||||
|
ck_assert_double_eq(segment->start.location.x, parent.start.location.x + segment->length);
|
||||||
|
ck_assert_double_eq(segment->end.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
|
||||||
|
ck_assert_double_eq(segment->end.location.x, parent.start.location.x + 2.0 * segment->length);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_true(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, parent.length / 3.0);
|
||||||
|
ck_assert_double_eq(segment->start.distance_from_start, parent.start.distance_from_start + 2.0 * segment->length);
|
||||||
|
ck_assert_double_eq(segment->start.location.x, parent.start.location.x + 2.0 * segment->length);
|
||||||
|
ck_assert_double_eq(segment->end.distance_from_start, parent.end.distance_from_start);
|
||||||
|
ck_assert_double_eq(segment->end.location.x, parent.end.location.x);
|
||||||
|
|
||||||
|
/* After subdividing, normal walking resumes */
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, 0.2);
|
||||||
|
ck_assert_double_in_range(segment->start.distance_from_start, 1.41, 1.6);
|
||||||
|
ck_assert_double_in_range(segment->start.location.x, 1.01, 1.2);
|
||||||
|
ck_assert_double_gt(segment->start.global_density, 0.0);
|
||||||
|
ck_assert_double_in_range(segment->end.distance_from_start, 1.61, 1.8);
|
||||||
|
ck_assert_double_in_range(segment->end.location.x, 1.21, 1.4);
|
||||||
|
ck_assert_double_gt(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* Exiting cloud again */
|
||||||
|
cloudsWalkerSetStepSize(walker, 0.3);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
|
ck_assert_double_in_range(segment->start.distance_from_start, 1.61, 1.8);
|
||||||
|
ck_assert_double_in_range(segment->start.location.x, 1.21, 1.4);
|
||||||
|
ck_assert_double_gt(segment->start.global_density, 0.0);
|
||||||
|
ck_assert_double_in_range(segment->end.distance_from_start, 1.91, 2.1);
|
||||||
|
ck_assert_double_in_range(segment->end.location.x, 1.5, 1.7);
|
||||||
|
ck_assert_double_eq(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* A step in the void without skipping */
|
||||||
|
cloudsWalkerSetVoidSkipping(walker, 0);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_false(segment->refined);
|
||||||
|
ck_assert_false(segment->subdivided);
|
||||||
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
|
ck_assert_double_in_range(segment->start.distance_from_start, 1.91, 2.1);
|
||||||
|
ck_assert_double_in_range(segment->start.location.x, 1.5, 1.7);
|
||||||
|
ck_assert_double_eq(segment->start.global_density, 0.0);
|
||||||
|
ck_assert_double_in_range(segment->end.distance_from_start, 2.21, 2.4);
|
||||||
|
ck_assert_double_in_range(segment->end.location.x, 1.8, 2.0);
|
||||||
|
ck_assert_double_eq(segment->end.global_density, 0.0);
|
||||||
|
|
||||||
|
/* Walker reached the lookup segment's end, it should stop */
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
ck_assert_int_eq(result, 0);
|
||||||
|
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
cloudsDeleteWalker(walker);
|
cloudsDeleteWalker(walker);
|
||||||
|
|
Loading…
Reference in a new issue