/* * 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 #include #include #include #include #include #include #include #include #include #include #include #include using namespace osgDAE; osg::Group* daeReader::processOsgMultiSwitch(domTechnique* teq) { osgSim::MultiSwitch* msw = new osgSim::MultiSwitch; domAny* any = daeSafeCast(teq->getChild("ActiveSwitchSet")); if (any) { msw->setActiveSwitchSet(parseString(any->getValue())); } else { OSG_WARN << "Expected element 'ActiveSwitchSet' not found" << std::endl; } any = daeSafeCast(teq->getChild("ValueLists")); if (any) { unsigned int numChildren = any->getChildren().getCount(); for (unsigned int currChild = 0; currChild < numChildren; currChild++) { domAny* child = daeSafeCast(any->getChildren()[currChild]); if (child) { if (strcmp(child->getElementName(), "ValueList" ) == 0 ) { std::list stringValues; osgSim::MultiSwitch::ValueList values; cdom::tokenize(child->getValue(), " ", stringValues); cdom::tokenIter iter = stringValues.begin(); while (iter != stringValues.end()) { values.push_back(parseString(*iter)); ++iter; } msw->setValueList(currChild, values); } else { OSG_WARN << "Child of element 'ValueLists' is not of type 'ValueList'" << std::endl; } } else { OSG_WARN << "Element 'ValueLists' does not contain expected elements." << std::endl; } } } else { OSG_WARN << "Expected element 'ValueLists' not found" << std::endl; } return msw; } osg::Group* daeReader::processOsgSwitch(domTechnique* teq) { osg::Switch* sw = new osg::Switch; domAny* any = daeSafeCast< domAny >(teq->getChild("ValueList")); if (any) { std::list stringValues; cdom::tokenize(any->getValue(), " ", stringValues); cdom::tokenIter iter = stringValues.begin(); int pos = 0; while (iter != stringValues.end()) { sw->setValue(pos++, parseString(*iter)); ++iter; } } else { OSG_WARN << "Expected element 'ValueList' not found" << std::endl; } return sw; } osg::Group* daeReader::processOsgSequence(domTechnique* teq) { osg::Sequence* sq = new osg::Sequence; domAny* any = daeSafeCast< domAny >(teq->getChild("FrameTime")); if (any) { std::list stringValues; cdom::tokenize(any->getValue(), " ", stringValues); cdom::tokenIter iter = stringValues.begin(); int frame = 0; while (iter != stringValues.end()) { sq->setTime(frame++, parseString(*iter)); ++iter; } } else { OSG_WARN << "Expected element 'FrameTime' not found" << std::endl; } any = daeSafeCast< domAny >(teq->getChild("LastFrameTime")); if (any) { sq->setLastFrameTime(parseString(any->getValue())); } else { OSG_WARN << "Expected element 'LastFrameTime' not found" << std::endl; } osg::Sequence::LoopMode loopmode = osg::Sequence::LOOP; any = daeSafeCast< domAny >(teq->getChild("LoopMode")); if (any) { loopmode = (osg::Sequence::LoopMode)parseString(any->getValue()); } else { OSG_WARN << "Expected element 'LoopMode' not found" << std::endl; } int begin=0; any = daeSafeCast< domAny >(teq->getChild("IntervalBegin")); if (any) { begin = parseString(any->getValue()); } else { OSG_WARN << "Expected element 'IntervalBegin' not found" << std::endl; } int end=-1; any = daeSafeCast< domAny >(teq->getChild("IntervalEnd")); if (any) { end = parseString(any->getValue()); } else { OSG_WARN << "Expected element 'IntervalEnd' not found" << std::endl; } sq->setInterval(loopmode, begin, end); float speed = 0; any = daeSafeCast< domAny >(teq->getChild("DurationSpeed")); if (any) { speed = parseString(any->getValue()); } else { OSG_WARN << "Expected element 'DurationSpeed' not found" << std::endl; } int nreps = -1; any = daeSafeCast< domAny >(teq->getChild("DurationNReps")); if (any) { nreps = parseString(any->getValue()); } else { OSG_WARN << "Expected element 'DurationNReps' not found" << std::endl; } sq->setDuration(speed, nreps); any = daeSafeCast< domAny >(teq->getChild("SequenceMode")); if (any) { sq->setMode((osg::Sequence::SequenceMode)parseString(any->getValue())); } else { OSG_WARN << "Expected element 'SequenceMode' not found" << std::endl; } return sq; } osg::Group* daeReader::processOsgLOD(domTechnique* teq) { osg::LOD* lod = new osg::LOD; domAny* any = daeSafeCast< domAny >(teq->getChild("Center")); if (any) { // If a center is specified lod->setCenterMode(osg::LOD::USER_DEFINED_CENTER); lod->setCenter(parseVec3String(any->getValue())); any = daeSafeCast< domAny >(teq->getChild("Radius")); if (any) { lod->setRadius(parseString(any->getValue())); } else { OSG_WARN << "Expected element 'Radius' not found" << std::endl; } } any = daeSafeCast< domAny >(teq->getChild("RangeMode")); if (any) { lod->setRangeMode((osg::LOD::RangeMode)parseString(any->getValue())); } else { OSG_WARN << "Expected element 'RangeMode' not found" << std::endl; } any = daeSafeCast< domAny >(teq->getChild("RangeList")); if (any) { osg::LOD::RangeList rangelist; unsigned int numChildren = any->getChildren().getCount(); for (unsigned int currChild = 0; currChild < numChildren; currChild++) { domAny* child = daeSafeCast(any->getChildren()[currChild]); if (child) { if (strcmp(child->getElementName(), "MinMax" ) == 0 ) { std::list stringValues; osg::LOD::MinMaxPair minMaxPair; cdom::tokenize(child->getValue(), " ", stringValues); cdom::tokenIter iter = stringValues.begin(); if (iter != stringValues.end()) { minMaxPair.first = parseString(*iter); ++iter; } else { OSG_WARN << "'MinMax' does not contain a valid minimum value" << std::endl; } if (iter != stringValues.end()) { minMaxPair.second = parseString(*iter); } else { OSG_WARN << "'MinMax' does not contain a valid maximum value" << std::endl; } rangelist.push_back(minMaxPair); } else { OSG_WARN << "Child of element 'RangeList' is not of type 'MinMax'" << std::endl; } } else { OSG_WARN << "Element 'RangeList' does not contain expected elements." << std::endl; } } lod->setRangeList(rangelist); } else { OSG_WARN << "Expected element 'RangeList' not found" << std::endl; } return lod; } // // attributes: // id, name // elements: // 0..1 // 1 // 1 , , , // 0..* // 0..* osg::Node* daeReader::processLight( domLight *dlight ) { if (_numlights >= 7) { OSG_WARN << "More than 8 lights may not be supported by OpenGL driver." << std::endl; } //do light processing here. domLight::domTechnique_common::domAmbient *ambient; domLight::domTechnique_common::domDirectional *directional; domLight::domTechnique_common::domPoint *point; domLight::domTechnique_common::domSpot *spot; if ( dlight->getTechnique_common() == NULL || dlight->getTechnique_common()->getContents().getCount() == 0 ) { OSG_WARN << "Invalid content for light" << std::endl; return NULL; } osg::Light* light = new osg::Light(); light->setPosition(osg::Vec4(0,0,0,1)); light->setLightNum(_numlights); // Enable OpenGL lighting _rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); // Enable this OpenGL light _rootStateSet->setMode(GL_LIGHT0 + _numlights++, osg::StateAttribute::ON); // Set ambient of lightmodel to zero // Ambient lights are added as separate lights with only an ambient term osg::LightModel* lightmodel = new osg::LightModel; lightmodel->setAmbientIntensity(osg::Vec4(0.0f,0.0f,0.0f,1.0f)); _rootStateSet->setAttributeAndModes(lightmodel, osg::StateAttribute::ON); osg::LightSource* lightsource = new osg::LightSource(); lightsource->setLight(light); lightsource->setName(dlight->getId()); daeElement *el = dlight->getTechnique_common()->getContents()[0]; ambient = daeSafeCast< domLight::domTechnique_common::domAmbient >( el ); directional = daeSafeCast< domLight::domTechnique_common::domDirectional >( el ); point = daeSafeCast< domLight::domTechnique_common::domPoint >( el ); spot = daeSafeCast< domLight::domTechnique_common::domSpot >( el ); if ( ambient != NULL ) { if ( ambient->getColor() == NULL ) { OSG_WARN << "Invalid content for ambient light" << std::endl; return NULL; } light->setAmbient( osg::Vec4( ambient->getColor()->getValue()[0], ambient->getColor()->getValue()[1], ambient->getColor()->getValue()[2], 1.0f ) ); light->setDiffuse( osg::Vec4( 0, 0, 0, 0)); light->setSpecular( osg::Vec4( 0, 0, 0, 0)); // Tell OpenGL to make it a directional light (w=0) light->setPosition( osg::Vec4(0,0,0,0)); } else if ( directional != NULL ) { if ( directional->getColor() == NULL ) { OSG_WARN << "Invalid content for directional light" << std::endl; return NULL; } light->setAmbient( osg::Vec4( 0, 0, 0, 0)); light->setDiffuse( osg::Vec4( directional->getColor()->getValue()[0], directional->getColor()->getValue()[1], directional->getColor()->getValue()[2], 1.0f ) ); light->setSpecular( osg::Vec4( directional->getColor()->getValue()[0], directional->getColor()->getValue()[1], directional->getColor()->getValue()[2], 1.0f ) ); light->setDirection(osg::Vec3(0,0,-1)); // Tell OpenGL it is a directional light (w=0) light->setPosition( osg::Vec4(0,0,1,0)); } else if ( point != NULL ) { if ( point->getColor() == NULL ) { OSG_WARN << "Invalid content for point light" << std::endl; return NULL; } light->setAmbient( osg::Vec4( 0, 0, 0, 0)); light->setDiffuse( osg::Vec4( point->getColor()->getValue()[0], point->getColor()->getValue()[1], point->getColor()->getValue()[2], 1.0f ) ); light->setSpecular( osg::Vec4( point->getColor()->getValue()[0], point->getColor()->getValue()[1], point->getColor()->getValue()[2], 1.0f ) ); if ( point->getConstant_attenuation() != NULL ) { light->setConstantAttenuation( point->getConstant_attenuation()->getValue() ); } else { light->setConstantAttenuation( 1.0 ); } if ( point->getLinear_attenuation() != NULL ) { light->setLinearAttenuation( point->getLinear_attenuation()->getValue() ); } else { light->setLinearAttenuation( 0.0 ); } if ( point->getQuadratic_attenuation() != NULL ) { light->setQuadraticAttenuation( point->getQuadratic_attenuation()->getValue() ); } else { light->setQuadraticAttenuation( 0.0 ); } // Tell OpenGL this is an omni directional light light->setDirection(osg::Vec3(0, 0, 0)); } else if ( spot != NULL ) { if ( spot->getColor() == NULL ) { OSG_WARN << "Invalid content for spot light" << std::endl; return NULL; } light->setAmbient( osg::Vec4( 0, 0, 0, 0)); light->setDiffuse( osg::Vec4( spot->getColor()->getValue()[0], spot->getColor()->getValue()[1], spot->getColor()->getValue()[2], 1.0f ) ); light->setSpecular( osg::Vec4( spot->getColor()->getValue()[0], spot->getColor()->getValue()[1], spot->getColor()->getValue()[2], 1.0f ) ); if ( spot->getConstant_attenuation() != NULL ) { light->setConstantAttenuation( spot->getConstant_attenuation()->getValue() ); } else { light->setConstantAttenuation( 1.0f ); } if ( spot->getLinear_attenuation() != NULL ) { light->setLinearAttenuation( spot->getLinear_attenuation()->getValue() ); } else { light->setLinearAttenuation( 0.0f ); } if ( spot->getQuadratic_attenuation() != NULL ) { light->setQuadraticAttenuation( spot->getQuadratic_attenuation()->getValue() ); } else { light->setQuadraticAttenuation( 0.0f ); } // OpenGL range [0, 90] (degrees) or 180 (omni) if ( spot->getFalloff_angle() != NULL ) { float falloffAngle = spot->getFalloff_angle()->getValue(); if (falloffAngle != 180) { falloffAngle = osg::clampTo(falloffAngle, 0, 90); } light->setSpotCutoff(falloffAngle); } else { light->setSpotCutoff( 180.0f ); } // OpenGL range [0, 128], where 0 means hard edge, and 128 means soft edge if ( spot->getFalloff_exponent() != NULL ) { float falloffExponent = spot->getFalloff_exponent()->getValue(); falloffExponent = osg::clampTo(falloffExponent, 0, 128); light->setSpotExponent(falloffExponent); } else { light->setSpotExponent( 0.0f ); } light->setDirection(osg::Vec3(0, 0, -1)); } return lightsource; } // // attributes: // id, name // elements: // 0..1 // 1 // 1 // 1 , // 0..* // 0..* // 0..* // 1 // 0..* // 0..* osg::Node* daeReader::processCamera( domCamera * dcamera ) { osg::CameraView* pOsgCameraView = new osg::CameraView; pOsgCameraView->setName(dcamera->getId()); domCamera::domOptics::domTechnique_common *pDomTechniqueCommon = dcamera->getOptics()->getTechnique_common(); domCamera::domOptics::domTechnique_common::domPerspective *pDomPerspective = pDomTechniqueCommon->getPerspective(); domCamera::domOptics::domTechnique_common::domOrthographic *pDomOrthographic = pDomTechniqueCommon->getOrthographic(); if (pDomPerspective) { // // 1 , , and , and , and // 1 // 1 domTargetableFloat *pXfov = daeSafeCast< domTargetableFloat >(pDomPerspective->getXfov()); domTargetableFloat *pYfov = daeSafeCast< domTargetableFloat >(pDomPerspective->getYfov()); domTargetableFloat *pAspectRatio = daeSafeCast< domTargetableFloat >(pDomPerspective->getAspect_ratio()); if (pXfov) { if (pYfov) { // and pOsgCameraView->setFieldOfView(pXfov->getValue()); pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL); if (pAspectRatio) { OSG_WARN << "Unexpected in '" << dcamera->getId() << "'" << std::endl; } } else if (pAspectRatio) { // and pOsgCameraView->setFieldOfView(pXfov->getValue() * pAspectRatio->getValue()); pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL); } else { // pOsgCameraView->setFieldOfView(pXfov->getValue()); pOsgCameraView->setFieldOfViewMode(osg::CameraView::HORIZONTAL); } } else if (pYfov) { if (pAspectRatio) { // and pOsgCameraView->setFieldOfView(pYfov->getValue() / pAspectRatio->getValue()); pOsgCameraView->setFieldOfViewMode(osg::CameraView::VERTICAL); } else { // pOsgCameraView->setFieldOfView(pYfov->getValue()); pOsgCameraView->setFieldOfViewMode(osg::CameraView::VERTICAL); } } else { // xfov or yfov expected OSG_WARN << "Expected or in '" << dcamera->getId() << "'" << std::endl; } //domTargetableFloat *pZnear = daeSafeCast< domTargetableFloat >(pDomPerspective->getZnear()); //domTargetableFloat *pZfar = daeSafeCast< domTargetableFloat >(pDomPerspective->getZfar()); // TODO The current osg::CameraView does not support storage of near far } else if (pDomOrthographic) { // // 1 , , and , and , and // 1 // 1 //domTargetableFloat *pXmag = daeSafeCast< domTargetableFloat >(pDomOrthographic->getXmag()); //domTargetableFloat *pYmag = daeSafeCast< domTargetableFloat >(pDomOrthographic->getYmag()); //domTargetableFloat *pAspectRatio = daeSafeCast< domTargetableFloat >(pDomOrthographic->getAspect_ratio()); // TODO The current osg::CameraView does not support an orthographic view OSG_WARN << "Orthographic in '" << dcamera->getId() << "' not supported" << std::endl; //domTargetableFloat *pZnear = daeSafeCast< domTargetableFloat >(pDomOrthographic->getZnear()); //domTargetableFloat *pZfar = daeSafeCast< domTargetableFloat >(pDomOrthographic->getZfar()); // TODO The current osg::CameraView does not support storage of near far } return pOsgCameraView; }