📄 daermaterials.cpp
字号:
/* * Copyright 2006 Sony Computer Entertainment Inc. * * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this * file except in compliance with the License. You may obtain a copy of the License at: * http://research.scea.com/scea_shared_source_license.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing permissions and limitations under the * License. */#include "daeReader.h"#include <dae.h>#include <dae/daeSIDResolver.h>#include <dae/domAny.h>#include <dom/domCOLLADA.h>#include <dom/domProfile_COMMON.h>#include <osg/BlendColor>#include <osg/BlendFunc>#include <osg/Texture2D>#include <osgDB/Registry>#include <osgDB/ReadFile>#include <sstream>using namespace osgdae;void daeReader::processBindMaterial( domBind_material *bm, osg::Node *geo ){ if ( bm->getTechnique_common() == NULL ) { osg::notify( osg::WARN ) << "No COMMON technique for bind_material" << std::endl; return; } osg::Group *group = geo->asGroup(); if ( group == NULL ) { //this shouldn't happen unless something is terribly wrong return; } domInstance_material_Array &ima = bm->getTechnique_common()->getInstance_material_array(); size_t count = ima.getCount(); for ( size_t i = 0; i < count; i++ ) { std::string symbol = ima[i]->getSymbol(); domMaterial *mat = daeSafeCast< domMaterial >( getElementFromURI( ima[i]->getTarget() ) ); if ( mat == NULL ) { osg::notify( osg::WARN ) << "Failed to locate material " << ima[i]->getTarget().getURI() << std::endl; continue; } osg::StateSet *ss; //check material cache if this material already exists std::map< domMaterial*, osg::StateSet*>::iterator iter = materialMap.find( mat ); if ( iter != materialMap.end() ) { ss = iter->second; } else { ss = processMaterial( mat ); materialMap.insert( std::make_pair( mat, ss ) ); } if ( ss == NULL ) { continue; } //TODO: process all of the <bind>s and <bind_vertex_input>s that are here in the instance_material. for ( unsigned int x = 0; x < group->getNumChildren(); x++ ) { //I named the geode with the material symbol so I can do this check for binding if ( group->getChild( x )->getName() == symbol ) { /*if ( group->getChild( x )->getStateSet() != NULL ) { //already have a stateSet this means I am an instance so clone me. group->replaceChild( group->getChild( x ), (osg::Node*)group->getChild( x )->cloneType() ); }*/ group->getChild( x )->setStateSet( ss ); } } }}osg::StateSet *daeReader::processMaterial( domMaterial *mat ){ currentInstance_effect = mat->getInstance_effect(); domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( currentInstance_effect->getUrl() ) ); if ( effect == NULL ) { osg::notify( osg::WARN ) << "Failed to locate effect " << mat->getInstance_effect()->getUrl().getURI() << std::endl; return NULL; } osg::StateSet *ss = processEffect( effect ); //TODO: process all of the setParams that could happen here in the material. ESP. the textures return ss;}osg::StateSet *daeReader::processEffect( domEffect *effect ){ bool hasCOMMON = false; osg::StateSet *ss = NULL; for ( size_t i = 0; i < effect->getFx_profile_abstract_array().getCount(); i++ ) { domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->getFx_profile_abstract_array()[i] ); if ( pc != NULL ) { if ( hasCOMMON ) { osg::notify( osg::WARN ) << "Effect already has a profile_COMMON. Skipping this one" << std::endl; continue; } currentEffect = effect; ss = processProfileCOMMON( pc ); hasCOMMON = true; continue; } osg::notify( osg::WARN ) << "unsupported effect profile " << effect->getFx_profile_abstract_array()[i]->getTypeName() << std::endl; } return ss;}osg::StateSet *daeReader::processProfileCOMMON( domProfile_COMMON *pc ){ osg::StateSet *ss = new osg::StateSet(); domProfile_COMMON::domTechnique *teq = pc->getTechnique(); domProfile_COMMON::domTechnique::domConstant *c = teq->getConstant(); domProfile_COMMON::domTechnique::domLambert *l = teq->getLambert(); domProfile_COMMON::domTechnique::domPhong *p = teq->getPhong(); domProfile_COMMON::domTechnique::domBlinn *b = teq->getBlinn(); ss->setMode( GL_CULL_FACE, GL_TRUE ); if (m_AuthoringTool == GOOGLE_SKETCHUP) { const domExtra_Array& ExtraArray = pc->getExtra_array(); size_t NumberOfExtras = ExtraArray.getCount(); size_t CurrentExtra; for (CurrentExtra = 0; CurrentExtra < NumberOfExtras; CurrentExtra++) { const domTechnique_Array& TechniqueArray = ExtraArray[CurrentExtra]->getTechnique_array(); size_t NumberOfTechniques = TechniqueArray.getCount(); size_t CurrentTechnique; for (CurrentTechnique = 0; CurrentTechnique < NumberOfTechniques; CurrentTechnique++) { if (strcmp(TechniqueArray[CurrentTechnique]->getProfile(), "GOOGLEEARTH") == 0) { const daeElementRefArray& ElementArray = TechniqueArray[CurrentTechnique]->getContents(); size_t NumberOfElements = ElementArray.getCount(); size_t CurrentElement; for (CurrentElement = 0; CurrentElement < NumberOfElements; CurrentElement++) { domAny* pAny = (domAny*)ElementArray[CurrentElement].cast(); if (strcmp(pAny->getElementName(), "double_sided") == 0) { daeString Value = pAny->getValue(); if (strcmp(Value, "1") == 0) ss->setMode( GL_CULL_FACE, GL_FALSE ); } } } } } } //ss->setMode( GL_LIGHTING, GL_FALSE ); osg::ref_ptr< osg::Material > mat = new osg::Material(); bool insertMat = false; if ( b != NULL ) { bool tmp; tmp = processColorOrTextureType( b->getEmission(), osg::Material::EMISSION, mat.get() ); insertMat = insertMat || tmp; tmp = processColorOrTextureType( b->getAmbient(), osg::Material::AMBIENT, mat.get() ); insertMat = insertMat || tmp; osg::StateAttribute *sa = NULL; tmp = processColorOrTextureType( b->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &sa ); insertMat = insertMat || tmp; if ( sa != NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa ); } tmp = processColorOrTextureType( b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() ); insertMat = insertMat || tmp; osg::StateAttribute *sa2 = NULL; sa2 = processTransparencySettings(b->getTransparent(), b->getTransparency(), ss); if ( sa2 != NULL ) { if ( sa == NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa2 ); } else { osg::notify( osg::WARN ) << "Already have a texture in the diffuse channel" << std::endl; } } } else if ( p != NULL ) { bool tmp; tmp = processColorOrTextureType( p->getEmission(), osg::Material::EMISSION, mat.get() ); insertMat = insertMat || tmp; tmp = processColorOrTextureType( p->getAmbient(), osg::Material::AMBIENT, mat.get() ); insertMat = insertMat || tmp; osg::StateAttribute *sa = NULL; tmp = processColorOrTextureType( p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &sa ); insertMat = insertMat || tmp; if ( sa != NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa ); } tmp = processColorOrTextureType( p->getSpecular(), osg::Material::SPECULAR, mat.get(), p->getShininess() ); insertMat = insertMat || tmp; osg::StateAttribute *sa2 = NULL; sa2 = processTransparencySettings(p->getTransparent(), p->getTransparency(), ss); if ( sa2 != NULL ) { if ( sa == NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa2 ); } else { osg::notify( osg::WARN ) << "Already have a texture in the diffuse channel" << std::endl; } } } else if ( l != NULL ) { bool tmp; tmp = processColorOrTextureType( l->getEmission(), osg::Material::EMISSION, mat.get() ); insertMat = insertMat || tmp; tmp = processColorOrTextureType( l->getAmbient(), osg::Material::AMBIENT, mat.get() ); insertMat = insertMat || tmp; osg::StateAttribute *sa = NULL; tmp = processColorOrTextureType( l->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &sa ); insertMat = insertMat || tmp; if ( sa != NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa ); } osg::StateAttribute *sa2 = NULL; sa2 = processTransparencySettings(l->getTransparent(), l->getTransparency(), ss); if ( sa2 != NULL ) { if ( sa == NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa2 ); } else { osg::notify( osg::WARN ) << "Already have a texture in the diffuse channel" << std::endl; } } } else if ( c != NULL ) { insertMat = processColorOrTextureType( c->getEmission(), osg::Material::EMISSION, mat.get() ); osg::StateAttribute *sa2 = NULL; sa2 = processTransparencySettings(c->getTransparent(), c->getTransparency(), ss); if ( sa2 != NULL ) { ss->setTextureMode( 0, GL_TEXTURE_2D, GL_TRUE ); ss->setTextureAttribute( 0, sa2 ); } } if ( insertMat ) { ss->setAttribute( mat.get() ); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -