clouds_walking: Added iterator system for walking
This commit is contained in:
parent
6e8e1bc307
commit
a484479fb7
3 changed files with 120 additions and 5 deletions
|
@ -23,6 +23,24 @@ typedef struct
|
||||||
int max_segments;
|
int max_segments;
|
||||||
} CloudWalkingNextAction;
|
} CloudWalkingNextAction;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Private structure for the walker.
|
||||||
|
*/
|
||||||
|
struct CloudsWalker
|
||||||
|
{
|
||||||
|
Vector3 start;
|
||||||
|
Vector3 end;
|
||||||
|
Vector3 diff;
|
||||||
|
|
||||||
|
double cursor;
|
||||||
|
double max_length;
|
||||||
|
double step_size;
|
||||||
|
|
||||||
|
CloudWalkerStepInfo last_segment;
|
||||||
|
|
||||||
|
CloudWalkingNextAction next_action;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end)
|
int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Vector3* end)
|
||||||
{
|
{
|
||||||
|
@ -78,32 +96,91 @@ int cloudsOptimizeWalkingBounds(CloudsLayerDefinition* layer, Vector3* start, Ve
|
||||||
|
|
||||||
CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end)
|
CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* layer, Vector3 start, Vector3 end)
|
||||||
{
|
{
|
||||||
|
CloudsWalker* result;
|
||||||
|
|
||||||
|
result = (CloudsWalker*)malloc(sizeof (CloudsWalker));
|
||||||
|
|
||||||
|
result->start = start;
|
||||||
|
result->end = end;
|
||||||
|
result->diff = v3Sub(end, start);
|
||||||
|
result->max_length = v3Norm(result->diff);
|
||||||
|
result->cursor = 0.0;
|
||||||
|
result->step_size = 1.0;
|
||||||
|
|
||||||
|
result->last_segment.renderer = renderer;
|
||||||
|
result->last_segment.layer = layer;
|
||||||
|
result->last_segment.walked_distance = 0.0;
|
||||||
|
result->last_segment.end = start;
|
||||||
|
|
||||||
|
result->next_action.order = CLOUD_WALKING_CONTINUE;
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsDeleteWalker(CloudsWalker* walker)
|
void cloudsDeleteWalker(CloudsWalker* walker)
|
||||||
{
|
{
|
||||||
|
free(walker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsWalkerPerformStep(CloudsWalker* walker)
|
void cloudsSetStepSize(CloudsWalker* walker, double step)
|
||||||
{
|
{
|
||||||
|
/* TODO Negative step => automatic */
|
||||||
|
walker->step_size = step;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cloudsWalkerPerformStep(CloudsWalker* walker)
|
||||||
|
{
|
||||||
|
if (walker->next_action.order == CLOUD_WALKING_STOP || walker->cursor >= walker->max_length)
|
||||||
|
{
|
||||||
|
walker->next_action.order = CLOUD_WALKING_STOP;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (walker->next_action.order == CLOUD_WALKING_CONTINUE)
|
||||||
|
{
|
||||||
|
/* TODO Limit to end */
|
||||||
|
walker->last_segment.start = walker->last_segment.end;
|
||||||
|
walker->last_segment.walked_distance = walker->cursor;
|
||||||
|
|
||||||
|
walker->cursor += walker->step_size;
|
||||||
|
|
||||||
|
walker->last_segment.end = v3Add(walker->start, v3Scale(walker->diff, walker->cursor / walker->max_length));
|
||||||
|
walker->last_segment.length = walker->step_size;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* TODO */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsWalkerOrderStop(CloudsWalker* walker)
|
void cloudsWalkerOrderStop(CloudsWalker* walker)
|
||||||
{
|
{
|
||||||
|
walker->next_action.order = CLOUD_WALKING_STOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsWalkerOrderRefine(CloudsWalker* walker, double precision)
|
void cloudsWalkerOrderRefine(CloudsWalker* walker, double 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;
|
||||||
|
walker->next_action.max_segments = max_segments;
|
||||||
}
|
}
|
||||||
|
|
||||||
CloudWalkerStepInfo* cloudsWalkerGetLastSegment(CloudsWalker* walker)
|
CloudWalkerStepInfo* cloudsWalkerGetLastSegment(CloudsWalker* walker)
|
||||||
{
|
{
|
||||||
|
return &walker->last_segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cloudsStartWalking(CloudsWalker* walker, FuncCloudsWalkingCallback callback, void* data)
|
void cloudsStartWalking(CloudsWalker* walker, FuncCloudsWalkingCallback callback, void* data)
|
||||||
{
|
{
|
||||||
|
while (cloudsWalkerPerformStep(walker))
|
||||||
|
{
|
||||||
|
callback(walker);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,9 @@ typedef struct
|
||||||
Vector3 end;
|
Vector3 end;
|
||||||
double length;
|
double length;
|
||||||
|
|
||||||
int refined;
|
/*int refined;
|
||||||
int subdivision_level;
|
int subdivision_level;
|
||||||
double precision_asked;
|
double precision_asked;*/
|
||||||
|
|
||||||
void* data;
|
void* data;
|
||||||
} CloudWalkerStepInfo;
|
} CloudWalkerStepInfo;
|
||||||
|
@ -65,12 +65,21 @@ CloudsWalker* cloudsCreateWalker(Renderer* renderer, CloudsLayerDefinition* laye
|
||||||
*/
|
*/
|
||||||
void cloudsDeleteWalker(CloudsWalker* walker);
|
void cloudsDeleteWalker(CloudsWalker* walker);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define the segment size for next steps.
|
||||||
|
*
|
||||||
|
* @param walker The walker to configure
|
||||||
|
* @param step The step length, negative for automatic
|
||||||
|
*/
|
||||||
|
void cloudsSetStepSize(CloudsWalker* walker, double step);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Perform a single step.
|
* Perform a single step.
|
||||||
*
|
*
|
||||||
* @param walker The walker to use
|
* @param walker The walker to use
|
||||||
|
* @return 1 to continue the loop, 0 to stop
|
||||||
*/
|
*/
|
||||||
void cloudsWalkerPerformStep(CloudsWalker* walker);
|
int cloudsWalkerPerformStep(CloudsWalker* walker);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Order the walker to stop.
|
* Order the walker to stop.
|
||||||
|
|
|
@ -202,6 +202,7 @@ static double _getLayerDensitySinX(Renderer* renderer, CloudsLayerDefinition* la
|
||||||
|
|
||||||
START_TEST(test_clouds_walking)
|
START_TEST(test_clouds_walking)
|
||||||
{
|
{
|
||||||
|
/* Init */
|
||||||
CloudsLayerDefinition* layer;
|
CloudsLayerDefinition* layer;
|
||||||
layer = cloudsGetLayerType().callback_create();
|
layer = cloudsGetLayerType().callback_create();
|
||||||
layer->lower_altitude = -1.0;
|
layer->lower_altitude = -1.0;
|
||||||
|
@ -214,7 +215,35 @@ START_TEST(test_clouds_walking)
|
||||||
renderer->render_quality = 8;
|
renderer->render_quality = 8;
|
||||||
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
|
renderer->clouds->getLayerDensity = _getLayerDensitySinX;
|
||||||
|
|
||||||
// TODO
|
CloudsWalker* walker = cloudsCreateWalker(renderer, layer, v3(-0.4, 0.0, 0.0), v3(10.0, 0.0, 0.0));
|
||||||
|
CloudWalkerStepInfo* segment;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
/* First step */
|
||||||
|
cloudsSetStepSize(walker, 0.3);
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_double_eq(segment->walked_distance, 0.0);
|
||||||
|
ck_assert_vector_values(segment->start, -0.4, 0.0, 0.0);
|
||||||
|
ck_assert_vector_values(segment->end, -0.1, 0.0, 0.0);
|
||||||
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
|
|
||||||
|
/* Second step */
|
||||||
|
result = cloudsWalkerPerformStep(walker);
|
||||||
|
segment = cloudsWalkerGetLastSegment(walker);
|
||||||
|
ck_assert_int_eq(result, 1);
|
||||||
|
ck_assert_double_eq(segment->walked_distance, 0.3);
|
||||||
|
ck_assert_vector_values(segment->start, -0.1, 0.0, 0.0);
|
||||||
|
ck_assert_vector_values(segment->end, 0.2, 0.0, 0.0);
|
||||||
|
ck_assert_double_eq(segment->length, 0.3);
|
||||||
|
|
||||||
|
/* Order to refine second step around the entry point */
|
||||||
|
cloudsWalkerOrderRefine(walker, 0.01);
|
||||||
|
/* TODO */
|
||||||
|
|
||||||
|
/* Clean up */
|
||||||
|
cloudsDeleteWalker(walker);
|
||||||
|
|
||||||
cloudsGetLayerType().callback_delete(layer);
|
cloudsGetLayerType().callback_delete(layer);
|
||||||
rendererDelete(renderer);
|
rendererDelete(renderer);
|
||||||
|
|
Loading…
Reference in a new issue