From e6371cbf9c399a1505b13c2d073c81e331b35c77 Mon Sep 17 00:00:00 2001 From: curt Date: Sun, 9 Nov 2008 15:39:54 +0000 Subject: [PATCH] Manuel Massing: Attached is a small fix for the sorting in CloudShaderGeometry.cxx. I think the sorting problem stems from the osg idiosyncracy to store transposed matrices...so the intuitive osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f); needs to be replaced with... osg::Vec4f p = vm.preMult(osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f); The patch also optimizes the distance calculation - it evaluates the distances in model space instead of eye space, which reduces computation to a dot- product instead of a matrix multiplication. --- simgear/scene/sky/CloudShaderGeometry.cxx | 25 ++++++++++++++--------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/simgear/scene/sky/CloudShaderGeometry.cxx b/simgear/scene/sky/CloudShaderGeometry.cxx index eaa9450f..3d8f4320 100755 --- a/simgear/scene/sky/CloudShaderGeometry.cxx +++ b/simgear/scene/sky/CloudShaderGeometry.cxx @@ -34,27 +34,32 @@ namespace simgear { void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const { + if (!_cloudsprites.size()) return; + osg::State& state = *renderInfo.getState(); osg::Matrix vm = state.getModelViewMatrix(); //TODO: It isn't clear whether this is worth the perf hit ATM. - // Do a single iteration of a bubble sort. We do this in reverse - // so that elements closest to the camera bubble to the front than - // the elements further away - for(int i = (_cloudsprites.size() -2); i >= 0; i--) + // 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++) { - osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(), 1.0f); - osg::Vec4f q = vm * osg::Vec4f(_cloudsprites[i+1]->position.osg(), 1.0f); - - if (p.z() > q.z()) - { + 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; } + else + p = q; } - + const Extensions* extensions = getExtensions(state.getContextID(),true); for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t) -- 2.39.5