- float q = view_dir*_cloudsprites[i+1]->position.osg();
- if (p > q) {
- CloudSprite c = *_cloudsprites[i];
- *_cloudsprites[i] = *_cloudsprites[i+1];
- *_cloudsprites[i+1] = c;
+ osg::Matrix vm = state.getModelViewMatrix();
+ bool sorted = true;
+
+ // Transform the viewing direction, represented by the eye space vector (0,0,-1, 0), into model-space
+ // (here we simply take the opposite direction and reverse the ordering when sorting)
+ osg::Vec3f view_dir(vm(0, 2), vm(1, 2), vm(2, 2)); // Caveat: OpenSceneGraph matrices are transposed!
+
+ float p = view_dir*_cloudsprites[0]->position.osg();
+ // Do a single iteration of a bubble sort, sorting
+ // back to front.
+ for(int i = 0; i < _cloudsprites.size() - 1; i++)
+ {
+ float q = view_dir*_cloudsprites[i+1]->position.osg();
+ if (p > q) {
+ CloudSprite c = *_cloudsprites[i];
+ *_cloudsprites[i] = *_cloudsprites[i+1];
+ *_cloudsprites[i+1] = c;
+
+ sorted = false;
+ }
+ else
+ p = q;
+ }
+
+ if (sorted)
+ {
+ // This cloud is sorted, so no need to re-sort.
+ // Maximum of every 128 frames (2 - 4 seconds)
+ skip_info->skip_limit = skip_info->skip_limit * 2;
+ if (skip_info->skip_limit > 128)
+ {
+ skip_info->skip_limit = 128;
+ }