/** * This source file is part of OgreColladaPlugin * an addon for OGRE (Object-oriented Graphics Rendering Engine) * For the latest info, see http://www.ogre3d.org/ * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * This program 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 GNU Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA, or go to * http://www.gnu.org/copyleft/lesser.txt. * * @author Philipp Hartl * @see README */ #include "OgreColladaLight.h" #include "OgreColladaDocument.h" #include "OgreColladaScene.h" #include "OgreColladaSyntax.h" #include "OgreColladaUtils.h" #include "OgreSceneManager.h" #include "OgreStringConverter.h" namespace Ogre { //------------------------------------------------------------------------- ColladaLight::ColladaLight(ColladaDocument *d, xmlNode *n) : ColladaEntity(d, n) { } //------------------------------------------------------------------------- ColladaLight::~ColladaLight(void) { } //------------------------------------------------------------------------- MovableObject *ColladaLight::getOgreInstance(void) const { if (mType == ColladaLightSpecific::AMBIENT) { mDoc->getSceneManager()->setAmbientLight(mColour); return NULL; } // Light *light = new Light(mId); Light *light = mDoc->getSceneManager()->createLight(mId); light->setDiffuseColour(mColour); light->setSpecularColour(mColour); light->setDirection(Vector3(0, 0, -1)); // see collada spec if (mType == ColladaLightSpecific::DIRECTIONAL) light->setType(Light::LT_DIRECTIONAL); else if (mType == ColladaLightSpecific::POINT) light->setType(Light::LT_POINT); else if (mType == ColladaLightSpecific::SPOT) light->setType(Light::LT_SPOTLIGHT); if (mType == ColladaLightSpecific::POINT || mType == ColladaLightSpecific::SPOT) { float constant = (mAttenuation == ColladaLightSpecific::CONSTANT) ? mAttenuationScale : 0; float linear = (mAttenuation == ColladaLightSpecific::LINEAR) ? mAttenuationScale : 0; float quadratic = (mAttenuation == ColladaLightSpecific::QUADRATIC) ? mAttenuationScale : 0; float range = 100000; ColladaBoundingBox *scenebox = mDoc->getScene()->getBoundingBox(); if (scenebox != NULL) range = scenebox->getRadius() * 2; light->setAttenuation(range, constant, linear, quadratic); } if (mType == ColladaLightSpecific::SPOT) { light->setSpotlightRange(Radian(0), Radian(Math::DegreesToRadians(mAngle)), mFalloffScale); } return light; } //------------------------------------------------------------------------- bool ColladaLight::doImport(void) { if (mLoaded) return mStatus; else mLoaded = true; // get light type String lighttype = ColladaUtils::getProperty(mNode, CS_ATR_TYPE); mType = ColladaLightSpecific::getType(lighttype); if (mType == ColladaLightSpecific::UNKNOWN) { LogManager::getSingleton().logMessage("ColladaLight::doImport - light type " + lighttype + " unknown! " + mId); return false; } // child // xmlNode *asset = ColladaUtils::getChildByTagName(mNode, CS_ELM_ASSET); // childs, describes the values that the light contributes xmlNodePtrVector params = ColladaUtils::getChildsByTagName(mNode, CS_ELM_PARAM); for (xmlNodePtrVector::iterator it = params.begin(); it != params.end(); ++it) { String name = ColladaUtils::getProperty(*it, CS_ATR_NAME); String content = ColladaUtils::getContentDirect(*it); /** * if the type attribute value is DIRECTIONAL or SPOT * then the light's default direction vector in local * coordinates is [0,0,-1], pointing down the -Z axis */ // should be in every case if (name == CS_VAL_LIGHT_PARAM_COLOR) { mColour = StringConverter::parseColourValue(content); } // point or spot else if (name == CS_VAL_LIGHT_PARAM_ATTENUATION) { mAttenuation = ColladaLightSpecific::getFunction(content); } else if (name == CS_VAL_LIGHT_PARAM_ATTENUATION_SCALE) { mAttenuationScale = StringConverter::parseReal(content); } // especially for spot light else if (name == CS_VAL_LIGHT_PARAM_ANGLE) { mAngle = StringConverter::parseReal(content); } else if (name == CS_VAL_LIGHT_PARAM_FALLOFF) { mFalloff = ColladaLightSpecific::getFunction(content); } else if (name == CS_VAL_LIGHT_PARAM_FALLOFF_SCALE) { mFalloffScale = StringConverter::parseReal(content); } else { LogManager::getSingleton().logMessage("ColladaLight::doImport - unknown attribute of light param " + name + "! " + mId); } } mStatus = true; return mStatus; } //------------------------------------------------------------------------- namespace ColladaLightSpecific { Type getType(const String &s) { if (s == CS_VAL_LIGHT_TYPE_AMBIENT) return AMBIENT; else if (s == CS_VAL_LIGHT_TYPE_DIRECTIONAL) return DIRECTIONAL; else if (s == CS_VAL_LIGHT_TYPE_POINT) return POINT; else if (s == CS_VAL_LIGHT_TYPE_SPOT) return SPOT; else return UNKNOWN; } Function getFunction(const String &s) { if (s == CS_VAL_LIGHT_FUNCTION_CONSTANT) return CONSTANT; else if (s == CS_VAL_LIGHT_FUNCTION_LINEAR) return LINEAR; else if (s == CS_VAL_LIGHT_FUNCTION_QUADRATIC) return QUADRATIC; else return CONSTANT; } } }