Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

physics/Material.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002   Copyright (C)1996 David Jung <opensim@pobox.com>
00003 
00004   This program/file is free software; you can redistribute it and/or modify
00005   it under the terms of the GNU General Public License as published by
00006   the Free Software Foundation; either version 2 of the License, or
00007   (at your option) any later version.
00008   
00009   This program is distributed in the hope that it will be useful,
00010   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012   GNU General Public License for more details. (http://www.gnu.org)
00013   
00014   You should have received a copy of the GNU General Public License
00015   along with this program; if not, write to the Free Software
00016   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018   $Id: Material.cpp 1031 2004-02-11 20:46:36Z jungd $
00019   $Revision: 1.6 $
00020   $Date: 2004-02-11 15:46:36 -0500 (Wed, 11 Feb 2004) $
00021   $Author: jungd $
00022   
00023 ****************************************************************************/
00024 
00025 #include <physics/Material>
00026 
00027 #include <base/Application>
00028 #include <base/VFile>
00029 #include <base/Externalizer>
00030 #include <base/externalization_error>
00031 #include <base/Vector>
00032 #include <gfx/Color3>
00033 #include <gfx/Color4>
00034 
00035 #include <osg/Material>
00036 #include <osg/Texture2D>
00037 #include <osg/Vec4>
00038 #include <osgDB/ReadFile>
00039 
00040 
00041 using base::Application;
00042 using base::VFile;
00043 using base::Vector;
00044 using base::externalization_error;
00045 
00046 using base::dom::DOMNode;
00047 using base::dom::DOMElement;
00048 
00049 using physics::Material;
00050 using gfx::Color3;
00051 using gfx::Color4;
00052 
00053 using osg::Vec4;
00054 using osg::StateSet;
00055 
00056 
00057 Material::Material(const String& label, const gfx::Color4& color)
00058         : label(label), mDensity(1.0), 
00059           surfaceAppearanceType(BaseColor),
00060           mBaseColor(color),
00061           stateSetCached(false)
00062 {
00063 }
00064 
00065 
00066 Material::Material(const Material& m)
00067   : label(m.label), mDensity(m.mDensity), 
00068     surfaceAppearanceType(m.surfaceAppearanceType),
00069     mBaseColor(m.mBaseColor),
00070     surfaceTextureImage(m.surfaceTextureImage),
00071     stateSetCached(m.stateSetCached),
00072     stateSet(m.stateSet)
00073 {
00074 }
00075 
00076 
00077 Material::~Material()
00078 {
00079 }
00080 
00081 
00082 void Material::setSurfaceAppearance(const base::PathName& image)
00083 {
00084   surfaceAppearanceType = TextureImage;
00085   surfaceTextureImage = image;
00086   stateSetCached = false;
00087 }
00088 
00089 
00090 osg::ref_ptr<osg::StateSet> Material::createState() const
00091 {
00092   if (stateSetCached) return stateSet;
00093 
00094   osg::ref_ptr<StateSet> state = new osg::StateSet();
00095   osg::ref_ptr<osg::Material> mat = new osg::Material();
00096   Vec4 col( (float)baseColor().r, 
00097             (float)baseColor().g, 
00098             (float)baseColor().b, 
00099             (float)baseColor().a );
00100   mat->setEmission( osg::Material::FRONT_AND_BACK, Vec4(0,0,0,0) );
00101   mat->setAmbient( osg::Material::FRONT_AND_BACK, col );
00102   mat->setDiffuse( osg::Material::FRONT_AND_BACK, col );
00103   mat->setSpecular( osg::Material::FRONT_AND_BACK, Vec4(1,1,1,0) );
00104   mat->setShininess( osg::Material::FRONT_AND_BACK, 128);
00105   mat->setAlpha( osg::Material::FRONT_AND_BACK, (float)baseColor().a );
00106   state->setAttribute( &(*mat) );
00107   if (!Math::equals(baseColor().a, 1.0)) {
00108     state->setMode(GL_BLEND, osg::StateAttribute::ON);
00109     state->setRenderingHint( osg::StateSet::TRANSPARENT_BIN );
00110   }
00111 
00112   if (surfaceAppearanceType == TextureImage) {
00113 
00114     ref<VFile> imageFile(Application::getInstance()->universe()->cache()->findFile(surfaceTextureImage));
00115 
00116     // load image
00117     ///!!! unfortunately, the osgDB only reads from filesystem files, not
00118     ///    streams, so we only support files here for now
00119     String filename( imageFile->pathName().str() );
00120 
00121     osg::ref_ptr<osg::Image> image = osgDB::readImageFile(filename);
00122     if (image == (osg::Image*)0)
00123       throw std::runtime_error(Exception(String("unable to read texture image file:")+filename));
00124 
00125     osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();
00126     texture->setImage(&(*image));
00127     texture->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR_MIPMAP_NEAREST);
00128     texture->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
00129     texture->setInternalFormatMode(osg::Texture2D::USE_ARB_COMPRESSION);
00130     texture->setWrap(osg::Texture2D::WRAP_S,osg::Texture2D::REPEAT);
00131     texture->setWrap(osg::Texture2D::WRAP_T,osg::Texture2D::REPEAT);
00132 
00133     state->setTextureAttributeAndModes(0,&(*texture),osg::StateAttribute::ON);
00134   }
00135 
00136   stateSetCached = true;
00137   stateSet = state;
00138 
00139   return stateSet;
00140 }
00141 
00142 
00143 void Material::externalize(base::Externalizer& e, String format, Real version)
00144 {
00145   if (format=="") format="xml";
00146 
00147   if (!formatSupported(format,version,e.ioType()))
00148     throw std::invalid_argument(Exception(String("format ")+format+" v"+base::realToString(version)+" unsupported"));
00149   
00150   if (format == "xml") {
00151 
00152     if (e.isOutput()) {
00153 
00154       DOMElement* matElem = e.createElement("material");
00155       e.setElementAttribute(matElem,"name",label);
00156       e.setElementAttribute(matElem,"type","simple");
00157       
00158       DOMElement* dElem = e.createElement("density",false);
00159       e.appendText(dElem, base::realToString(mDensity));
00160       e.appendNode(matElem,dElem);
00161       e.appendBreak(matElem);
00162 
00163       DOMElement* cElem = e.createElement("basecolor",false);
00164       Vector c(3);
00165       c[0]=mBaseColor.r; c[1]=mBaseColor.g; c[2]=mBaseColor.b;
00166       e.appendText(cElem, e.toString(c,true));
00167       e.appendNode(matElem,cElem);
00168       
00169       if (surfaceAppearanceType == TextureImage) {
00170         DOMElement* saElem = e.createElement("surfaceappearance",false);
00171         e.setElementAttribute(saElem,"type","image");
00172         e.appendText(saElem, surfaceTextureImage.str() );
00173         e.appendNode(matElem,saElem);
00174       }
00175 
00176       e.appendElement(matElem);
00177 
00178     }
00179     else { // input
00180 
00181       DOMNode* context = e.context();
00182     
00183       DOMElement* matElem = e.getFirstChildElement(context, "material");
00184 
00185       if ( e.getElementAttribute(matElem, "type") != "simple" )
00186         throw externalization_error(Exception("unsupported material type"));
00187 
00188       label = e.getDefaultedElementAttribute(matElem, "name", "untitled");
00189 
00190       DOMElement* dElem = e.getFirstChildElement(matElem, "density", false);
00191       if (dElem) {
00192         String densityText = e.getContainedText(dElem);
00193         mDensity = base::stringToReal(densityText);
00194       }
00195       else
00196         mDensity=1.0;
00197 
00198       surfaceAppearanceType = BaseColor;
00199       DOMElement* cElem = e.getFirstChildElement(matElem, "basecolor",false);
00200       if (cElem) {
00201         String colorText = e.getContainedText(cElem);
00202         Vector3 cv( e.toVector3(colorText) );
00203         mBaseColor = Color3(cv.x,cv.y,cv.z);
00204       }
00205       else
00206         mBaseColor = Color3(0,1,0);
00207 
00208 
00209       DOMElement* saElem = e.getFirstChildElement(matElem, "surfaceappearance",false);
00210       if (saElem) {
00211         String type = e.getDefaultedElementAttribute(saElem,"type","image");
00212         if (type == "image") {
00213           surfaceAppearanceType = TextureImage;
00214           surfaceTextureImage = e.getContainedText(saElem);
00215         }
00216         else
00217           throw externalization_error(Exception("unsupported value of 'type' attribute of element 'surfaceappearance'"));
00218       }
00219 
00220 
00221 
00222       e.removeElement(matElem);
00223 
00224     }
00225 
00226   }
00227 
00228 }
00229 

Generated on Thu Jul 29 15:56:24 2004 for OpenSim by doxygen 1.3.6