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.
This commit is contained in:
@@ -34,25 +34,30 @@ namespace simgear
|
|||||||
{
|
{
|
||||||
void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
|
void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
|
||||||
{
|
{
|
||||||
|
if (!_cloudsprites.size()) return;
|
||||||
|
|
||||||
osg::State& state = *renderInfo.getState();
|
osg::State& state = *renderInfo.getState();
|
||||||
osg::Matrix vm = state.getModelViewMatrix();
|
osg::Matrix vm = state.getModelViewMatrix();
|
||||||
|
|
||||||
//TODO: It isn't clear whether this is worth the perf hit ATM.
|
//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
|
// Transform the viewing direction, represented by the eye space vector (0,0,-1, 0), into model-space
|
||||||
// so that elements closest to the camera bubble to the front than
|
// (here we simply take the opposite direction and reverse the ordering when sorting)
|
||||||
// the elements further away
|
osg::Vec3f view_dir(vm(0, 2), vm(1, 2), vm(2, 2)); // Caveat: OpenSceneGraph matrices are transposed!
|
||||||
for(int i = (_cloudsprites.size() -2); i >= 0; 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 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];
|
CloudSprite c = *_cloudsprites[i];
|
||||||
*_cloudsprites[i] = *_cloudsprites[i+1];
|
*_cloudsprites[i] = *_cloudsprites[i+1];
|
||||||
*_cloudsprites[i+1] = c;
|
*_cloudsprites[i+1] = c;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
p = q;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Extensions* extensions = getExtensions(state.getContextID(),true);
|
const Extensions* extensions = getExtensions(state.getContextID(),true);
|
||||||
|
|||||||
Reference in New Issue
Block a user