/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2009 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include #include #include #include using namespace osgVolume; ImageDetails::ImageDetails(): _texelOffset(0.0,0.0,0.0,0.0), _texelScale(1.0,1.0,1.0,1.0) { } ImageDetails::ImageDetails(const ImageDetails& rhs,const osg::CopyOp& copyop): _texelOffset(rhs._texelOffset), _texelScale(rhs._texelScale), _matrix(rhs._matrix) { } Layer::Layer(): _minFilter(osg::Texture::LINEAR), _magFilter(osg::Texture::LINEAR) { } Layer::Layer(const Layer& layer,const osg::CopyOp& copyop): osg::Object(layer,copyop), _filename(layer._filename), _minFilter(layer._minFilter), _magFilter(layer._magFilter) { } Layer::~Layer() { } osg::BoundingSphere Layer::computeBound() const { if (!getLocator()) return osg::BoundingSphere(); osg::Vec3d left, right; getLocator()->computeLocalBounds(left, right); //osg::notify(osg::NOTICE)<<"left = "<(_image->getUserData()); if (details) { details->setTexelOffset(_texelOffset); details->setTexelScale(_texelScale); } #if 0 if (computeMinMax(minValue, maxValue)) { osg::notify(osg::NOTICE)<<" after _texelOffset "<<_texelOffset<(_image.get())!=0; } void ImageLayer::update(osg::NodeVisitor& nv) { if (_image.valid()) _image->update(&nv); } ///////////////////////////////////////////////////////////////////////////// // // CompositeLayer // CompositeLayer::CompositeLayer() { } CompositeLayer::CompositeLayer(const CompositeLayer& compositeLayer,const osg::CopyOp& copyop): Layer(compositeLayer,copyop) { } void CompositeLayer::clear() { _layers.clear(); } bool CompositeLayer::requiresUpdateTraversal() const { for(Layers::const_iterator itr = _layers.begin(); itr != _layers.end(); ++itr) { if (itr->layer->requiresUpdateTraversal()) return true; } return false; } void CompositeLayer::update(osg::NodeVisitor& nv) { for(Layers::const_iterator itr = _layers.begin(); itr != _layers.end(); ++itr) { itr->layer->update(nv); } } ///////////////////////////////////////////////////////////////////////////// // // createNormalMapTexture // osg::Image* osgVolume::createNormalMapTexture(osg::Image* image_3d) { osg::notify(osg::INFO)<<"Computing NormalMapTexture"<getDataType(); unsigned int sourcePixelIncrement = 1; unsigned int alphaOffset = 0; switch(image_3d->getPixelFormat()) { case(GL_ALPHA): case(GL_LUMINANCE): sourcePixelIncrement = 1; alphaOffset = 0; break; case(GL_LUMINANCE_ALPHA): sourcePixelIncrement = 2; alphaOffset = 1; break; case(GL_RGB): sourcePixelIncrement = 3; alphaOffset = 0; break; case(GL_RGBA): sourcePixelIncrement = 4; alphaOffset = 3; break; default: osg::notify(osg::NOTICE)<<"Source pixel format not support for normal map generation."< normalmap_3d = new osg::Image; normalmap_3d->allocateImage(image_3d->s(),image_3d->t(),image_3d->r(), GL_RGBA,GL_UNSIGNED_BYTE); if (osg::getCpuByteOrder()==osg::LittleEndian) alphaOffset = sourcePixelIncrement-alphaOffset-1; for(int r=1;rr()-1;++r) { for(int t=1;tt()-1;++t) { if (dataType==GL_UNSIGNED_BYTE) { unsigned char* ptr = image_3d->data(1,t,r)+alphaOffset; unsigned char* left = image_3d->data(0,t,r)+alphaOffset; unsigned char* right = image_3d->data(2,t,r)+alphaOffset; unsigned char* above = image_3d->data(1,t+1,r)+alphaOffset; unsigned char* below = image_3d->data(1,t-1,r)+alphaOffset; unsigned char* in = image_3d->data(1,t,r+1)+alphaOffset; unsigned char* out = image_3d->data(1,t,r-1)+alphaOffset; unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); for(int s=1;ss()-1;++s) { osg::Vec3 grad((float)(*left)-(float)(*right), (float)(*below)-(float)(*above), (float)(*out) -(float)(*in)); grad.normalize(); if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f) { grad.set(128.0f,128.0f,128.0f); } else { grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f); grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f); grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f); } *(destination++) = (unsigned char)(grad.x()); // scale and bias X. *(destination++) = (unsigned char)(grad.y()); // scale and bias Y. *(destination++) = (unsigned char)(grad.z()); // scale and bias Z. *destination++ = *ptr; ptr += sourcePixelIncrement; left += sourcePixelIncrement; right += sourcePixelIncrement; above += sourcePixelIncrement; below += sourcePixelIncrement; in += sourcePixelIncrement; out += sourcePixelIncrement; } } else if (dataType==GL_SHORT) { short* ptr = (short*)(image_3d->data(1,t,r)+alphaOffset); short* left = (short*)(image_3d->data(0,t,r)+alphaOffset); short* right = (short*)(image_3d->data(2,t,r)+alphaOffset); short* above = (short*)(image_3d->data(1,t+1,r)+alphaOffset); short* below = (short*)(image_3d->data(1,t-1,r)+alphaOffset); short* in = (short*)(image_3d->data(1,t,r+1)+alphaOffset); short* out = (short*)(image_3d->data(1,t,r-1)+alphaOffset); unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); for(int s=1;ss()-1;++s) { osg::Vec3 grad((float)(*left)-(float)(*right), (float)(*below)-(float)(*above), (float)(*out) -(float)(*in)); grad.normalize(); //osg::notify(osg::NOTICE)<<"normal "<data(1,t,r)+alphaOffset); unsigned short* left = (unsigned short*)(image_3d->data(0,t,r)+alphaOffset); unsigned short* right = (unsigned short*)(image_3d->data(2,t,r)+alphaOffset); unsigned short* above = (unsigned short*)(image_3d->data(1,t+1,r)+alphaOffset); unsigned short* below = (unsigned short*)(image_3d->data(1,t-1,r)+alphaOffset); unsigned short* in = (unsigned short*)(image_3d->data(1,t,r+1)+alphaOffset); unsigned short* out = (unsigned short*)(image_3d->data(1,t,r-1)+alphaOffset); unsigned char* destination = (unsigned char*) normalmap_3d->data(1,t,r); for(int s=1;ss()-1;++s) { osg::Vec3 grad((float)(*left)-(float)(*right), (float)(*below)-(float)(*above), (float)(*out) -(float)(*in)); grad.normalize(); if (grad.x()==0.0f && grad.y()==0.0f && grad.z()==0.0f) { grad.set(128.0f,128.0f,128.0f); } else { grad.x() = osg::clampBetween((grad.x()+1.0f)*128.0f,0.0f,255.0f); grad.y() = osg::clampBetween((grad.y()+1.0f)*128.0f,0.0f,255.0f); grad.z() = osg::clampBetween((grad.z()+1.0f)*128.0f,0.0f,255.0f); } *(destination++) = (unsigned char)(grad.x()); // scale and bias X. *(destination++) = (unsigned char)(grad.y()); // scale and bias Y. *(destination++) = (unsigned char)(grad.z()); // scale and bias Z. *destination++ = *ptr/256; ptr += sourcePixelIncrement; left += sourcePixelIncrement; right += sourcePixelIncrement; above += sourcePixelIncrement; below += sourcePixelIncrement; in += sourcePixelIncrement; out += sourcePixelIncrement; } } } } osg::notify(osg::INFO)<<"Created NormalMapTexture"<getColor(l); //std::cout<<"l = "<allocateImage(image->s(),image->t(), image->r(), GL_RGBA, GL_UNSIGNED_BYTE); ApplyTransferFunctionOperator op(transferFunction, output_image->data()); osg::readImage(image,op); return output_image; }