Changeset 11129
- Timestamp:
- 02/26/10 15:41:50 (2 years ago)
- Location:
- OpenSceneGraph/trunk
- Files:
-
- 3 added
- 19 modified
-
include/osg/Array (modified) (7 diffs)
-
include/osg/Matrixf (modified) (1 diff)
-
src/osgPlugins/dae/CMakeLists.txt (modified) (2 diffs)
-
src/osgPlugins/dae/ReaderWriterDAE.cpp (modified) (4 diffs)
-
src/osgPlugins/dae/ReaderWriterDAE.h (modified) (2 diffs)
-
src/osgPlugins/dae/daeRAnimations.cpp (added)
-
src/osgPlugins/dae/daeRGeometry.cpp (modified) (2 diffs)
-
src/osgPlugins/dae/daeRMaterials.cpp (modified) (34 diffs)
-
src/osgPlugins/dae/daeRSceneObjects.cpp (modified) (6 diffs)
-
src/osgPlugins/dae/daeRSkinning.cpp (added)
-
src/osgPlugins/dae/daeRTransforms.cpp (modified) (8 diffs)
-
src/osgPlugins/dae/daeReader.cpp (modified) (12 diffs)
-
src/osgPlugins/dae/daeReader.h (modified) (7 diffs)
-
src/osgPlugins/dae/daeWAnimations.cpp (added)
-
src/osgPlugins/dae/daeWGeometry.cpp (modified) (13 diffs)
-
src/osgPlugins/dae/daeWMaterials.cpp (modified) (16 diffs)
-
src/osgPlugins/dae/daeWSceneObjects.cpp (modified) (5 diffs)
-
src/osgPlugins/dae/daeWTransforms.cpp (modified) (9 diffs)
-
src/osgPlugins/dae/daeWriter.cpp (modified) (7 diffs)
-
src/osgPlugins/dae/daeWriter.h (modified) (13 diffs)
-
src/osgPlugins/dae/domSourceReader.cpp (modified) (4 diffs)
-
src/osgPlugins/dae/domSourceReader.h (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
OpenSceneGraph/trunk/include/osg/Array
r10650 r11129 30 30 #include <osg/Vec3b> 31 31 #include <osg/Vec4b> 32 #include <osg/Matrix> 32 33 33 34 #include <osg/BufferObject> … … 72 73 Vec2dArrayType = 19, 73 74 Vec3dArrayType = 20, 74 Vec4dArrayType = 21 75 Vec4dArrayType = 21, 76 MatrixArrayType = 22 75 77 }; 76 78 … … 309 311 typedef TemplateArray<Vec3d,Array::Vec3dArrayType,3,GL_DOUBLE> Vec3dArray; 310 312 typedef TemplateArray<Vec4d,Array::Vec4dArrayType,4,GL_DOUBLE> Vec4dArray; 313 314 typedef TemplateArray<Matrixf,Array::MatrixArrayType,16,GL_FLOAT> MatrixfArray; 311 315 312 316 … … 344 348 virtual void apply(Vec3dArray&) {} 345 349 virtual void apply(Vec4dArray&) {} 350 351 virtual void apply(MatrixfArray&) {} 346 352 }; 347 353 … … 379 385 virtual void apply(const Vec3dArray&) {} 380 386 virtual void apply(const Vec4dArray&) {} 387 388 virtual void apply(const MatrixfArray&) {} 381 389 }; 382 390 … … 415 423 virtual void apply(Vec3d&) {} 416 424 virtual void apply(Vec4d&) {} 425 426 virtual void apply(Matrixf&) {} 417 427 }; 418 428 … … 449 459 virtual void apply(const Vec3d&) {} 450 460 virtual void apply(const Vec4d&) {} 461 462 virtual void apply(const Matrixf&) {} 451 463 }; 452 464 -
OpenSceneGraph/trunk/include/osg/Matrixf
r8868 r11129 384 384 } 385 385 386 /** Multiply by scalar. */ 387 inline Matrixf operator * (value_type rhs) const 388 { 389 return Matrixf( 390 _mat[0][0]*rhs, _mat[0][1]*rhs, _mat[0][2]*rhs, _mat[0][3]*rhs, 391 _mat[1][0]*rhs, _mat[1][1]*rhs, _mat[1][2]*rhs, _mat[1][3]*rhs, 392 _mat[2][0]*rhs, _mat[2][1]*rhs, _mat[2][2]*rhs, _mat[2][3]*rhs, 393 _mat[3][0]*rhs, _mat[3][1]*rhs, _mat[3][2]*rhs, _mat[3][3]*rhs); 394 } 395 396 /** Unary multiply by scalar. */ 397 inline Matrixf& operator *= (value_type rhs) 398 { 399 _mat[0][0]*=rhs; 400 _mat[0][1]*=rhs; 401 _mat[0][2]*=rhs; 402 _mat[0][3]*=rhs; 403 _mat[1][0]*=rhs; 404 _mat[1][1]*=rhs; 405 _mat[1][2]*=rhs; 406 _mat[1][3]*=rhs; 407 _mat[2][0]*=rhs; 408 _mat[2][1]*=rhs; 409 _mat[2][2]*=rhs; 410 _mat[2][3]*=rhs; 411 _mat[3][0]*=rhs; 412 _mat[3][1]*=rhs; 413 _mat[3][2]*=rhs; 414 _mat[3][3]*=rhs; 415 return *this; 416 } 417 418 /** Divide by scalar. */ 419 inline Matrixf operator / (value_type rhs) const 420 { 421 return Matrixf( 422 _mat[0][0]/rhs, _mat[0][1]/rhs, _mat[0][2]/rhs, _mat[0][3]/rhs, 423 _mat[1][0]/rhs, _mat[1][1]/rhs, _mat[1][2]/rhs, _mat[1][3]/rhs, 424 _mat[2][0]/rhs, _mat[2][1]/rhs, _mat[2][2]/rhs, _mat[2][3]/rhs, 425 _mat[3][0]/rhs, _mat[3][1]/rhs, _mat[3][2]/rhs, _mat[3][3]/rhs); 426 } 427 428 /** Unary divide by scalar. */ 429 inline Matrixf& operator /= (value_type rhs) 430 { 431 _mat[0][0]/=rhs; 432 _mat[0][1]/=rhs; 433 _mat[0][2]/=rhs; 434 _mat[0][3]/=rhs; 435 _mat[1][0]/=rhs; 436 _mat[1][1]/=rhs; 437 _mat[1][2]/=rhs; 438 _mat[1][3]/=rhs; 439 _mat[2][0]/=rhs; 440 _mat[2][1]/=rhs; 441 _mat[2][2]/=rhs; 442 _mat[2][3]/=rhs; 443 _mat[3][0]/=rhs; 444 _mat[3][1]/=rhs; 445 _mat[3][2]/=rhs; 446 _mat[3][3]/=rhs; 447 return *this; 448 } 449 450 /** Binary vector add. */ 451 inline Matrixf operator + (const Matrixf& rhs) const 452 { 453 return Matrixf( 454 _mat[0][0] + rhs._mat[0][0], 455 _mat[0][1] + rhs._mat[0][1], 456 _mat[0][2] + rhs._mat[0][2], 457 _mat[0][3] + rhs._mat[0][3], 458 _mat[1][0] + rhs._mat[1][0], 459 _mat[1][1] + rhs._mat[1][1], 460 _mat[1][2] + rhs._mat[1][2], 461 _mat[1][3] + rhs._mat[1][3], 462 _mat[2][0] + rhs._mat[2][0], 463 _mat[2][1] + rhs._mat[2][1], 464 _mat[2][2] + rhs._mat[2][2], 465 _mat[2][3] + rhs._mat[2][3], 466 _mat[3][0] + rhs._mat[3][0], 467 _mat[3][1] + rhs._mat[3][1], 468 _mat[3][2] + rhs._mat[3][2], 469 _mat[3][3] + rhs._mat[3][3]); 470 } 471 472 /** Unary vector add. Slightly more efficient because no temporary 473 * intermediate object. 474 */ 475 inline Matrixf& operator += (const Matrixf& rhs) 476 { 477 _mat[0][0] += rhs._mat[0][0]; 478 _mat[0][1] += rhs._mat[0][1]; 479 _mat[0][2] += rhs._mat[0][2]; 480 _mat[0][3] += rhs._mat[0][3]; 481 _mat[1][0] += rhs._mat[1][0]; 482 _mat[1][1] += rhs._mat[1][1]; 483 _mat[1][2] += rhs._mat[1][2]; 484 _mat[1][3] += rhs._mat[1][3]; 485 _mat[2][0] += rhs._mat[2][0]; 486 _mat[2][1] += rhs._mat[2][1]; 487 _mat[2][2] += rhs._mat[2][2]; 488 _mat[2][3] += rhs._mat[2][3]; 489 _mat[3][0] += rhs._mat[3][0]; 490 _mat[3][1] += rhs._mat[3][1]; 491 _mat[3][2] += rhs._mat[3][2]; 492 _mat[3][3] += rhs._mat[3][3]; 493 return *this; 494 } 495 386 496 protected: 387 497 value_type _mat[4][4]; -
OpenSceneGraph/trunk/src/osgPlugins/dae/CMakeLists.txt
r10336 r11129 3 3 SET(TARGET_SRC 4 4 daeReader.cpp 5 daeRAnimations.cpp 5 6 daeRGeometry.cpp 6 7 daeRMaterials.cpp 7 8 daeRSceneObjects.cpp 9 daeRSkinning.cpp 8 10 daeRTransforms.cpp 11 daeWAnimations.cpp 9 12 daeWGeometry.cpp 10 13 daeWMaterials.cpp … … 67 70 ENDIF() 68 71 69 SET(TARGET_ADDED_LIBRARIES osgSim )72 SET(TARGET_ADDED_LIBRARIES osgSim osgAnimation) 70 73 71 74 #### end var setup ### -
OpenSceneGraph/trunk/src/osgPlugins/dae/ReaderWriterDAE.cpp
r9529 r11129 58 58 } 59 59 60 osg dae::daeReader daeReader(pDAE, options && options->getOptionString().find("StrictTransparency") != std::string::npos ) ;60 osgDAE::daeReader daeReader(pDAE, options && options->getOptionString().find("StrictTransparency") != std::string::npos ) ; 61 61 62 62 // Convert file name to URI … … 76 76 // Return some additional information about the document 77 77 if (options->getPluginData("DAE-AssetUnitName")) 78 *(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader. m_AssetUnitName;78 *(std::string*)options->getPluginData("DAE-AssetUnitName") = daeReader.getAssetUnitName(); 79 79 if (options->getPluginData("DAE-AssetUnitMeter")) 80 *(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader. m_AssetUnitMeter;80 *(float*)options->getPluginData("DAE-AssetUnitMeter") = daeReader.getAssetUnitMeter(); 81 81 if (options->getPluginData("DAE-AssetUp_axis")) 82 *(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader. m_AssetUp_axis;82 *(domUpAxisType*)options->getPluginData("DAE-AssetUp_axis") = daeReader.getAssetUpAxis(); 83 83 } 84 84 … … 142 142 osg::NodeVisitor::TraversalMode traversalMode = writeExtras ? osg::NodeVisitor::TRAVERSE_ALL_CHILDREN : osg::NodeVisitor::TRAVERSE_ACTIVE_CHILDREN; 143 143 144 osg dae::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode, traversalMode, writeExtras);144 osgDAE::daeWriter daeWriter(pDAE, fileURI, usePolygon, GoogleMode, traversalMode, writeExtras); 145 145 daeWriter.setRootNode( node ); 146 146 const_cast<osg::Node*>(&node)->accept( daeWriter ); … … 149 149 if ( daeWriter.isSuccess() ) 150 150 { 151 if ( daeWriter.writeFile())151 if (pDAE->write(fileURI)) 152 152 retVal = WriteResult::FILE_SAVED; 153 153 } -
OpenSceneGraph/trunk/src/osgPlugins/dae/ReaderWriterDAE.h
r8578 r11129 9 9 // See http://collada.org/ and http://khronos.org/collada/ 10 10 11 #define EXTENSION_NAME "dae"12 13 11 class ReaderWriterDAE : public osgDB::ReaderWriter 14 12 { … … 16 14 ReaderWriterDAE() 17 15 { 18 supportsExtension(EXTENSION_NAME,"COLLADA 1.4.x DAE format"); 16 // Collada document 17 supportsExtension("dae","COLLADA 1.4.x DAE format"); 18 // Collada zip archive (contains one or more dae files and a manifest.xml) 19 supportsExtension("zae","COLLADA 1.4.x ZAE format"); 19 20 } 20 21 -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeRGeometry.cpp
r10901 r11129 2 2 * Copyright 2006 Sony Computer Entertainment Inc. 3 3 * 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 5 5 * file except in compliance with the License. You may obtain a copy of the License at: 6 6 * http://research.scea.com/scea_shared_source_license.html 7 7 * 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 12 12 */ 13 13 … … 19 19 #include <dom/domInstance_controller.h> 20 20 #include <dom/domController.h> 21 #include <dom/domConstants.h> 21 22 #include <osg/StateSet> 22 23 #include <osg/ShapeDrawable> 23 24 #include <osg/Geometry> 24 25 25 using namespace osgdae; 26 27 osg::Geode* daeReader::processInstanceGeometry( domInstance_geometry *ig ) 28 { 29 daeElement *el = getElementFromURI( ig->getUrl() ); 30 domGeometry *geom = daeSafeCast< domGeometry >( el ); 31 if ( geom == NULL ) 32 { 33 osg::notify( osg::WARN ) << "Failed to locate geometry " << ig->getUrl().getURI() << std::endl; 26 #include <osgAnimation/MorphGeometry> 27 #include <osgAnimation/RigGeometry> 28 #include <osgAnimation/UpdateBone> 29 30 using namespace osgDAE; 31 32 osg::Geode* daeReader::getOrCreateGeometry(domGeometry *pDomGeometry, domBind_material* pDomBindMaterial, const osg::Geode** ppOriginalGeode) 33 { 34 // Check cache if geometry already exists 35 osg::Geode* pOsgGeode; 36 37 domGeometryGeodeMap::iterator iter = _geometryMap.find( pDomGeometry ); 38 if ( iter != _geometryMap.end() ) 39 { 40 pOsgGeode = iter->second.get(); 41 } 42 else 43 { 44 pOsgGeode = processGeometry( pDomGeometry ); 45 _geometryMap.insert( std::make_pair( pDomGeometry, pOsgGeode ) ); 46 } 47 48 if (ppOriginalGeode) 49 { 50 *ppOriginalGeode = pOsgGeode; 51 } 52 53 if (!pOsgGeode) 34 54 return NULL; 35 }36 37 // Check cache if geometry already exists38 osg::Geode* cachedGeode;39 40 domGeometryGeodeMap::iterator iter = geometryMap.find( geom );41 if ( iter != geometryMap.end() )42 {43 cachedGeode = iter->second.get();44 }45 else46 {47 cachedGeode = processGeometry( geom );48 geometryMap.insert( std::make_pair( geom, cachedGeode ) );49 }50 55 51 56 // Create a copy of the cached Geode with a copy of the drawables, 52 57 // because we may be using a different material or texture unit bindings. 53 osg::Geode * geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES));54 if ( geode == NULL )55 { 56 osg::notify( osg::WARN ) << "Failed to load geometry " << ig->getUrl().getURI() << std::endl;58 osg::Geode *pCopiedOsgGeode = static_cast<osg::Geode*>(pOsgGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES)); 59 if ( pCopiedOsgGeode == NULL ) 60 { 61 osg::notify( osg::WARN ) << "Failed to load geometry " << pDomGeometry->getName() << std::endl; 57 62 return NULL; 58 63 } 59 64 60 // process material bindings 61 if ( ig->getBind_material() != NULL ) 62 { 63 processBindMaterial( ig->getBind_material(), geom, geode, cachedGeode ); 64 } 65 66 return geode; 67 } 68 69 // <controller> 70 // attributes: 71 // id, name 72 // elements: 65 // Compute optimized geometry by expanding all indexed arrays so we are no longer rendering with the slow path 66 for(unsigned int i=0;i < pCopiedOsgGeode->getNumDrawables();++i) 67 { 68 osg::Geometry* geom = pCopiedOsgGeode->getDrawable(i)->asGeometry(); 69 if (geom) 70 { 71 if (!geom->areFastPathsUsed() && !geom->getInternalOptimizedGeometry()) 72 { 73 //geom->computeInternalOptimizedGeometry(); 74 } 75 } 76 } 77 78 if (pDomBindMaterial) 79 { 80 processBindMaterial( pDomBindMaterial, pDomGeometry, pCopiedOsgGeode, pOsgGeode ); 81 } 82 83 return pCopiedOsgGeode; 84 } 85 86 osgAnimation::Bone* daeReader::getOrCreateBone(domNode *pDomNode) 87 { 88 // Check cache if bone already exists 89 osgAnimation::Bone *pOsgBone = NULL; 90 91 domNodeOsgBoneMap::iterator iterBone = _jointMap.find( pDomNode ); 92 if ( iterBone != _jointMap.end() ) 93 return iterBone->second.get(); 94 95 std::string name; 96 if (pDomNode->getId()) 97 name = pDomNode->getId(); 98 if (name.empty() && pDomNode->getSid()) 99 name = pDomNode->getSid(); 100 if (name.empty() && pDomNode->getName()) 101 name = pDomNode->getName(); 102 pOsgBone = new osgAnimation::Bone(name); 103 pOsgBone->setDataVariance(osg::Object::DYNAMIC); 104 105 pOsgBone->setUpdateCallback(new osgAnimation::UpdateBone(name)); 106 107 _jointMap.insert( std::make_pair( pDomNode, pOsgBone ) ); 108 109 return pOsgBone; 110 } 111 112 osgAnimation::Skeleton* daeReader::getOrCreateSkeleton(domNode *pDomNode) 113 { 114 // Check cache if skeleton already exists 115 osgAnimation::Skeleton *pOsgSkeleton = NULL; 116 117 domNodeOsgSkeletonMap::iterator iter = _skeletonMap.find( pDomNode ); 118 if ( iter != _skeletonMap.end() ) 119 return iter->second.get(); 120 121 pOsgSkeleton = new osgAnimation::Skeleton; 122 pOsgSkeleton->setDefaultUpdateCallback(); 123 pOsgSkeleton->setDataVariance(osg::Object::DYNAMIC); 124 125 _skeletonMap.insert( std::make_pair( pDomNode, pOsgSkeleton ) ); 126 127 return pOsgSkeleton; 128 } 129 130 131 132 osg::Geode* daeReader::processInstanceGeometry( domInstance_geometry *pDomInstanceGeometry ) 133 { 134 domGeometry *pDomGeometry = daeSafeCast< domGeometry >(getElementFromURI(pDomInstanceGeometry->getUrl())); 135 if (!pDomGeometry) 136 { 137 osg::notify( osg::WARN ) << "Failed to locate geometry " << pDomInstanceGeometry->getUrl().getURI() << std::endl; 138 return NULL; 139 } 140 141 return getOrCreateGeometry(pDomGeometry, pDomInstanceGeometry->getBind_material()); 142 } 143 144 // <morph source (method)> 145 // 2..* <source> 146 // 1 <targets> 147 // 2..* <input semantic source> 148 // 0..* <extra> 149 // 0..* <extra> 150 osg::Node* daeReader::processMorph(domMorph* pDomMorph, domBind_material* pDomBindMaterial) 151 { 152 domGeometry* pDomGeometry = daeSafeCast< domGeometry >(getElementFromURI( pDomMorph->getSource())); 153 154 if (!pDomGeometry) 155 { 156 osg::notify( osg::WARN ) << "Failed to locate geometry " << pDomMorph->getSource().getURI() << std::endl; 157 return NULL; 158 } 159 160 // Base mesh 161 osg::Geode* pOsgGeode = getOrCreateGeometry(pDomGeometry, pDomBindMaterial); 162 if (!pOsgGeode) 163 return NULL; 164 165 // Expects a single geometry inside the geode, should change this 166 osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(pOsgGeode->getDrawable(0)); 167 if (!pOsgGeometry) 168 return NULL; 169 170 osgAnimation::MorphGeometry* pOsgMorphGeometry = new osgAnimation::MorphGeometry(*pOsgGeometry); 171 pOsgGeode->removeDrawables(0); 172 pOsgGeode->addDrawable(pOsgMorphGeometry); 173 174 domMorphMethodType morphMethod = pDomMorph->getMethod(); 175 176 //Files exported by the FBX converter always seem to say they're relative 177 //when in fact they should be normalized. 178 if (_authoringTool == FBX_CONVERTER) 179 { 180 morphMethod = MORPHMETHODTYPE_NORMALIZED; 181 } 182 183 switch (morphMethod) 184 { 185 case MORPHMETHODTYPE_RELATIVE: 186 pOsgMorphGeometry->setMethod(osgAnimation::MorphGeometry::RELATIVE); 187 break; 188 case MORPHMETHODTYPE_NORMALIZED: 189 pOsgMorphGeometry->setMethod(osgAnimation::MorphGeometry::NORMALIZED); 190 break; 191 default: 192 osg::notify( osg::WARN ) << "Unknown morph method method type " << std::endl; 193 } 194 195 // 1 <targets> 196 domMorph::domTargets* pDomMorhpTargets = pDomMorph->getTargets(); 197 domInputLocal_Array domInputs = pDomMorhpTargets->getInput_array(); 198 199 // TODO how to handle multiple pairs of morph inputs? 200 if (domInputs.getCount() > 2) 201 { 202 osg::notify( osg::WARN ) << "Only a single pair of morph inputs is supported." << std::endl; 203 } 204 205 for (size_t i=0; i < 2; i++) 206 { 207 if (!strcmp(domInputs[i]->getSemantic(), COMMON_PROFILE_INPUT_MORPH_TARGET)) 208 { 209 domSource* pDomSource = daeSafeCast<domSource>(getElementFromURI(domInputs[i]->getSource())); 210 if (pDomSource) 211 { 212 if (const domName_array* pDomNames = pDomSource->getName_array()) 213 { 214 const domListOfNames& names = pDomNames->getValue(); 215 for (size_t j=0; j < names.getCount(); j++) 216 { 217 daeSIDResolver resolver(_visualScene, names.get(j)); 218 pDomGeometry = daeSafeCast< domGeometry >(resolver.getElement()); 219 220 if (pDomGeometry) 221 { 222 osg::Geode* targetgeode = getOrCreateGeometry(pDomGeometry, NULL); 223 224 // Expects a single geometry inside the geode, should change this 225 osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(targetgeode->getDrawable(0)); 226 if (pOsgGeometry) 227 { 228 pOsgMorphGeometry->addMorphTarget(pOsgGeometry); 229 } 230 } 231 else 232 { 233 osg::notify( osg::WARN ) << "Failed to locate morph geometry '" << names.get(j) << "'" << std::endl; 234 } 235 } 236 } 237 else if (domIDREF_array* pDomIDREFs = pDomSource->getIDREF_array()) 238 { 239 xsIDREFS* pIDREFS = &(pDomIDREFs->getValue()); 240 for (size_t j=0; j < pIDREFS->getCount(); j++) 241 { 242 pDomGeometry = daeSafeCast< domGeometry >(getElementFromIDRef(pIDREFS->get(j))); 243 244 if (pDomGeometry) 245 { 246 osg::Geode* targetgeode = getOrCreateGeometry(pDomGeometry, NULL); 247 248 // Expects a single geometry inside the geode, should change this 249 osg::Geometry* pOsgGeometry = dynamic_cast<osg::Geometry*>(targetgeode->getDrawable(0)); 250 if (pOsgGeometry) 251 { 252 pOsgMorphGeometry->addMorphTarget(pOsgGeometry); 253 } 254 } 255 else 256 { 257 osg::notify( osg::WARN ) << "Failed to locate morph geometry '" << pIDREFS->get(j).getID() << "'" << std::endl; 258 } 259 } 260 } 261 } 262 else 263 { 264 osg::notify( osg::WARN ) << "Could not find morph source '" << domInputs[i]->getSource().getURI() << "'" <<std::endl; 265 return NULL; 266 } 267 } 268 else if (!strcmp(domInputs[i]->getSemantic(), COMMON_PROFILE_INPUT_MORPH_WEIGHT)) 269 { 270 domSource* pDomSource = daeSafeCast<domSource>(getElementFromURI(domInputs[i]->getSource())); 271 if (pDomSource) 272 { 273 domFloat_array* pDomFloatArray = pDomSource->getFloat_array(); 274 domListOfFloats weights = pDomFloatArray->getValue(); 275 for (size_t j=0; j < pDomFloatArray->getCount(); j++) 276 { 277 pOsgMorphGeometry->setWeight(j, weights.get(j)); 278 } 279 280 // See if morph weights are targetted by animations 281 daeElementDomChannelMap::iterator iter = _daeElementDomChannelMap.find(pDomSource); 282 if (iter != _daeElementDomChannelMap.end()) 283 { 284 std::string name = pDomSource->getId() ? pDomSource->getId() : ""; 285 osgAnimation::UpdateMorph* pUpdateCallback = new osgAnimation::UpdateMorph(name); 286 pOsgGeode->setUpdateCallback(pUpdateCallback); 287 pOsgGeode->setDataVariance(osg::Object::DYNAMIC); 288 289 // Associate all animation channels with this update callback 290 do 291 { 292 _domChannelOsgAnimationUpdateCallbackMap[iter->second] = pUpdateCallback; 293 ++iter; 294 } 295 while (iter != _daeElementDomChannelMap.upper_bound(pDomSource)); 296 } 297 } 298 else 299 { 300 osg::notify( osg::WARN ) << "Could not find morph source '" << domInputs[i]->getSource().getURI() << "'" <<std::endl; 301 return NULL; 302 } 303 } 304 } 305 306 return pOsgGeode; 307 } 308 309 // <controller (id) (name)> 73 310 // 0..1 <asset> 74 311 // 1 <skin>, <morph> 75 312 // 0..* <extra> 76 osg::Geode* daeReader::processInstanceController( domInstance_controller *ictrl ) 77 { 78 //TODO: support skinning 79 daeElement *el = getElementFromURI( ictrl->getUrl()); 80 domController *ctrl = daeSafeCast< domController >( el ); 81 if ( ctrl == NULL ) 82 { 83 osg::notify( osg::WARN ) << "Failed to locate conroller " << ictrl->getUrl().getURI() << std::endl; 313 osg::Node* daeReader::processInstanceController( domInstance_controller *pDomInstanceController ) 314 { 315 domController *pDomController = daeSafeCast< domController >(getElementFromURI(pDomInstanceController->getUrl())); 316 if (!pDomController) 317 { 318 osg::notify( osg::WARN ) << "Failed to locate controller " << pDomInstanceController->getUrl().getURI() << std::endl; 84 319 return NULL; 85 320 } 86 321 87 osg::notify( osg::WARN ) << "Processing <controller>. There is not skinning support but will display the base mesh." << std::endl; 88 89 el = NULL; 90 //## non init 91 daeURI *src=NULL; 92 if ( ctrl->getSkin() != NULL ) 93 { 94 src = &ctrl->getSkin()->getSource(); 95 el = getElementFromURI( ctrl->getSkin()->getSource() ); 96 } 97 else if ( ctrl->getMorph() != NULL ) 98 { 99 src = &ctrl->getSkin()->getSource(); 100 el = getElementFromURI( ctrl->getMorph()->getSource() ); 101 } 102 103 //non init case 104 if ( !src ) 105 { 106 osg::notify( osg::WARN ) << "Failed to locate geometry : URI is NULL" << std::endl; 322 if (pDomController->getSkin()) 323 { 324 _skinInstanceControllers.push_back(pDomInstanceController); 107 325 return NULL; 108 326 } 109 110 domGeometry *geom = daeSafeCast< domGeometry >( el ); 111 if ( geom == NULL ) 112 { 113 osg::notify( osg::WARN ) << "Failed to locate geometry " << src->getURI() << std::endl; 114 return NULL; 115 } 116 117 // Check cache if geometry already exists 118 osg::Geode* cachedGeode; 119 domGeometryGeodeMap::iterator iter = geometryMap.find( geom ); 120 if ( iter != geometryMap.end() ) 121 { 122 cachedGeode = iter->second.get(); 123 } 124 else 125 { 126 cachedGeode = processGeometry( geom ); 127 geometryMap.insert( std::make_pair( geom, cachedGeode ) ); 128 } 129 130 // Create a copy of the cached Geode with a copy of the drawables, 131 // because we may be using a different material or texture unit bindings. 132 osg::Geode *geode = static_cast<osg::Geode*>(cachedGeode->clone(osg::CopyOp::DEEP_COPY_DRAWABLES)); 133 if ( geode == NULL ) 134 { 135 osg::notify( osg::WARN ) << "Failed to load geometry " << src->getURI() << std::endl; 136 return NULL; 137 } 138 //process material bindings 139 if ( ictrl->getBind_material() != NULL ) 140 { 141 processBindMaterial( ictrl->getBind_material(), geom, geode, cachedGeode ); 142 } 143 144 return geode; 145 } 146 147 // <geometry> 148 // attributes: 149 // id, name 150 // elements: 327 else if (pDomController->getMorph()) 328 { 329 return processMorph(pDomController->getMorph(), pDomInstanceController->getBind_material()); 330 } 331 332 osg::notify( osg::WARN ) << "Expected skin or morph element in controller '" << pDomController->getName() << "'" << std::endl; 333 334 return NULL; 335 } 336 337 // <mesh> 338 // 1..* <source> 339 // 1 <vertices> 340 // 0..* <lines>, <linestrips>, <polygons>, <polylist>, <triangles>, <trifans>, <tristrips> 341 // 0..* <extra> 342 osg::Geode *daeReader::processMesh(domMesh* pDomMesh) 343 { 344 osg::Geode* pOsgGeode = new osg::Geode; 345 // if (pDomMesh->getId() != NULL ) 346 { 347 // pOsgGeode->setName( pDomMesh->getId() ); 348 } 349 350 // size_t count = mesh->getContents().getCount(); 351 352 // 1..* <source> 353 SourceMap sources; 354 domSource_Array sourceArray = pDomMesh->getSource_array(); 355 for ( size_t i = 0; i < sourceArray.getCount(); i++) 356 { 357 sources.insert(std::make_pair((daeElement*)sourceArray[i], domSourceReader(sourceArray[i]))); 358 } 359 360 // 0..* <lines> 361 domLines_Array linesArray = pDomMesh->getLines_array(); 362 for ( size_t i = 0; i < linesArray.getCount(); i++) 363 { 364 processSinglePPrimitive<domLines>(pOsgGeode, pDomMesh, linesArray[i], sources, GL_LINES); 365 } 366 367 // 0..* <linestrips> 368 domLinestrips_Array linestripsArray = pDomMesh->getLinestrips_array(); 369 for ( size_t i = 0; i < linestripsArray.getCount(); i++) 370 { 371 processMultiPPrimitive<domLinestrips>(pOsgGeode, pDomMesh, linestripsArray[i], sources, GL_LINE_STRIP); 372 } 373 374 // 0..* <polygons> 375 domPolygons_Array polygonsArray = pDomMesh->getPolygons_array(); 376 for ( size_t i = 0; i < polygonsArray.getCount(); i++) 377 { 378 processPolygons<domPolygons>(pOsgGeode, pDomMesh, polygonsArray[i], sources); 379 } 380 381 // 0..* <polylist> 382 domPolylist_Array polylistArray = pDomMesh->getPolylist_array(); 383 for ( size_t i = 0; i < polylistArray.getCount(); i++) 384 { 385 processPolylist(pOsgGeode, pDomMesh, polylistArray[i], sources); 386 } 387 388 // 0..* <triangles> 389 domTriangles_Array trianglesArray = pDomMesh->getTriangles_array(); 390 for ( size_t i = 0; i < trianglesArray.getCount(); i++) 391 { 392 processSinglePPrimitive<domTriangles>(pOsgGeode, pDomMesh, trianglesArray[i], sources, GL_TRIANGLES); 393 } 394 395 // 0..* <trifans> 396 domTrifans_Array trifansArray = pDomMesh->getTrifans_array(); 397 for ( size_t i = 0; i < trifansArray.getCount(); i++) 398 { 399 processPolygons<domTrifans>(pOsgGeode, pDomMesh, trifansArray[i], sources); 400 } 401 402 // 0..* <tristrips> 403 domTristrips_Array tristripsArray = pDomMesh->getTristrips_array(); 404 for ( size_t i = 0; i < tristripsArray.getCount(); i++) 405 { 406 processMultiPPrimitive<domTristrips>(pOsgGeode, pDomMesh, tristripsArray[i], sources, GL_TRIANGLE_STRIP); 407 } 408 409 return pOsgGeode; 410 } 411 412 // <convexmesh> 413 osg::Geode *daeReader::processConvexMesh(domConvex_mesh* pDomConvexMesh) 414 { 415 // osg::notify( osg::WARN ) << "Unsupported geometry convex mesh '" << pDomConvexMesh->getId() << "'" << std::endl; 416 return NULL; 417 } 418 419 // <spline> 420 osg::Geode *daeReader::processSpline(domSpline* pDomSpline) 421 { 422 // osg::notify( osg::WARN ) << "Unsupported geometry type spline '" << pDomSpline->getId() << "'" << std::endl; 423 return NULL; 424 } 425 426 // <geometry (id) (name)> 151 427 // 0..1 <asset> 152 428 // 1 <convex_mesh>, <mesh>, <spline> 153 429 // 0..* <extra> 154 osg::Geode *daeReader::processGeometry( domGeometry *geo ) 155 { 156 domMesh *mesh = geo->getMesh(); 157 if ( mesh == NULL ) 158 { 159 osg::notify( osg::WARN ) << "Unsupported Geometry type loading " << geo->getId() << std::endl; 160 return NULL; 161 } 162 163 osg::Geode* geode = new osg::Geode; 164 if (geo->getId() != NULL ) 165 { 166 geode->setName( geo->getId() ); 167 } 168 169 // <mesh> 170 // elements: 171 // 1..* <source> 172 // 1 <vertices> 173 // 0..* <lines>, <linestrips>, <polygons>, <polylist>, <triangles>, <trifans>, <tristrips> 174 // 0..* <extra> 175 176 // size_t count = mesh->getContents().getCount(); 177 178 // 1..* <source> 179 SourceMap sources; 180 domSource_Array sourceArray = mesh->getSource_array(); 181 for ( size_t i = 0; i < sourceArray.getCount(); i++) 182 { 183 sources.insert( std::make_pair((daeElement*)sourceArray[i], domSourceReader( sourceArray[i] ) ) ); 184 } 185 186 // 0..* <lines> 187 domLines_Array linesArray = mesh->getLines_array(); 188 for ( size_t i = 0; i < linesArray.getCount(); i++) 189 { 190 processSinglePPrimitive<domLines>(geode, linesArray[i], sources, GL_LINES ); 191 } 192 193 // 0..* <linestrips> 194 domLinestrips_Array linestripsArray = mesh->getLinestrips_array(); 195 for ( size_t i = 0; i < linestripsArray.getCount(); i++) 196 { 197 processMultiPPrimitive<domLinestrips>(geode, linestripsArray[i], sources, GL_LINE_STRIP ); 198 } 199 200 // 0..* <polygons> 201 domPolygons_Array polygonsArray = mesh->getPolygons_array(); 202 for ( size_t i = 0; i < polygonsArray.getCount(); i++) 203 { 204 processMultiPPrimitive<domPolygons>(geode, polygonsArray[i], sources, GL_POLYGON ); 205 } 206 207 // 0..* <polylist> 208 domPolylist_Array polylistArray = mesh->getPolylist_array(); 209 for ( size_t i = 0; i < polylistArray.getCount(); i++) 210 { 211 processPolylist(geode, polylistArray[i], sources ); 212 } 213 214 // 0..* <triangles> 215 domTriangles_Array trianglesArray = mesh->getTriangles_array(); 216 for ( size_t i = 0; i < trianglesArray.getCount(); i++) 217 { 218 processSinglePPrimitive<domTriangles>(geode, trianglesArray[i], sources, GL_TRIANGLES ); 219 } 220 221 // 0..* <trifans> 222 domTrifans_Array trifansArray = mesh->getTrifans_array(); 223 for ( size_t i = 0; i < trifansArray.getCount(); i++) 224 { 225 processMultiPPrimitive<domTrifans>(geode, trifansArray[i], sources, GL_TRIANGLE_FAN ); 226 } 227 228 // 0..* <tristrips> 229 domTristrips_Array tristripsArray = mesh->getTristrips_array(); 230 for ( size_t i = 0; i < tristripsArray.getCount(); i++) 231 { 232 processMultiPPrimitive<domTristrips>(geode, tristripsArray[i], sources, GL_TRIANGLE_STRIP ); 233 } 234 235 return geode; 430 osg::Geode *daeReader::processGeometry(domGeometry *pDomGeometry) 431 { 432 if (pDomGeometry->getMesh()) 433 { 434 return processMesh(pDomGeometry->getMesh()); 435 } 436 else if (pDomGeometry->getConvex_mesh()) 437 { 438 return processConvexMesh(pDomGeometry->getConvex_mesh()); 439 } 440 else if (pDomGeometry->getSpline()) 441 { 442 return processSpline(pDomGeometry->getSpline()); 443 } 444 #ifdef COLLADA15 445 else if (pDomGeometry->getBRep()) 446 { 447 return processBRep(pDomGeometry->getBRep()); 448 } 449 #endif 450 451 osg::notify( osg::WARN ) << "Unexpected geometry type in geometry '" << pDomGeometry->getId() << "'" << std::endl; 452 return NULL; 236 453 } 237 454 238 455 239 456 template< typename T > 240 void daeReader::processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ) 241 { 242 osg::Geometry *geometry = new ReaderGeometry(); 243 if (group->getMaterial() != NULL ) 244 { 245 geometry->setName(group->getMaterial()); 246 } 247 248 IndexMap index_map; 249 resolveArrays( group->getInput_array(), geometry, sources, index_map ); 250 251 osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( mode ); 252 processP( group->getP(), geometry, index_map, dal/*mode*/ ); 253 geometry->addPrimitiveSet( dal ); 254 457 void daeReader::processSinglePPrimitive(osg::Geode* geode, 458 const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode) 459 { 460 osg::Geometry *geometry = new osg::Geometry(); 461 geometry->setName(group->getMaterial()); 255 462 geode->addDrawable( geometry ); 463 464 osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode); 465 geometry->addPrimitiveSet(pDrawElements); 466 467 domP_Array domPArray; 468 domPArray.append(group->getP()); 469 std::vector<std::vector<GLuint> > indexLists; 470 resolveMeshArrays(domPArray, group->getInput_array(), pDomMesh, 471 geometry, sources, indexLists); 472 pDrawElements->asVector().swap(indexLists.front()); 256 473 } 257 474 258 475 template< typename T > 259 void daeReader::processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ) 260 { 261 osg::Geometry *geometry = new ReaderGeometry(); 262 if (group->getMaterial() != NULL ) 263 { 264 geometry->setName(group->getMaterial()); 265 } 266 267 IndexMap index_map; 268 resolveArrays( group->getInput_array(), geometry, sources, index_map ); 269 270 osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( mode ); 271 272 for ( size_t i = 0; i < group->getP_array().getCount(); i++ ) 273 { 274 processP( group->getP_array()[i], geometry, index_map, dal/*mode*/ ); 275 } 276 geometry->addPrimitiveSet( dal ); 277 476 void daeReader::processMultiPPrimitive(osg::Geode* geode, 477 const domMesh* pDomMesh, const T* group, SourceMap &sources, GLenum mode) 478 { 479 osg::Geometry *geometry = new osg::Geometry(); 480 geometry->setName(group->getMaterial()); 278 481 geode->addDrawable( geometry ); 279 } 280 281 void daeReader::processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources ) 282 { 283 osg::Geometry *geometry = new ReaderGeometry(); 284 if (group->getMaterial() != NULL ) 285 { 286 geometry->setName(group->getMaterial()); 287 } 288 289 IndexMap index_map; 290 resolveArrays( group->getInput_array(), geometry, sources, index_map ); 291 292 osg::DrawArrayLengths* dal = new osg::DrawArrayLengths( GL_POLYGON ); 293 294 //domPRef p = (domP*)(daeElement*)domP::_Meta->create(); //I don't condone creating elements like this but I don't care 295 domPRef p = (domP*)domP::registerElement(*dae)->create().cast(); 296 //if it created properly because I never want it as part of the document. Its just a temporary 297 //element to trick the importer into loading polylists easier. 298 unsigned int maxOffset = 0; 299 for ( unsigned int i = 0; i < group->getInput_array().getCount(); i++ ) 300 { 301 if ( group->getInput_array()[i]->getOffset() > maxOffset ) 302 { 303 maxOffset = group->getInput_array()[i]->getOffset(); 304 } 305 } 306 maxOffset++; 307 unsigned int pOffset = 0; 308 for ( unsigned int i = 0; i < group->getCount(); i++ ) 309 { 310 p->getValue().clear(); 311 for ( unsigned int x = 0; x < group->getVcount()->getValue()[i]; x++ ) 312 { 313 for ( unsigned int y = 0; y < maxOffset; y++ ) 314 { 315 p->getValue().append( group->getP()->getValue()[ pOffset + x*maxOffset + y ] ); 316 } 317 } 318 pOffset += group->getVcount()->getValue()[i] * maxOffset; 319 processP( p, geometry, index_map, dal/*mode*/ ); 320 } 321 322 geometry->addPrimitiveSet( dal ); 323 324 geode->addDrawable( geometry ); 325 } 326 327 void daeReader::processP( domP *p, osg::Geometry *&/*geom*/, IndexMap &index_map, osg::DrawArrayLengths* dal /*GLenum mode*/ ) 328 { 329 int idxcount = index_map.size(); 330 int count = p->getValue().getCount(); 331 count = (count/idxcount)*idxcount; 332 dal->push_back(count/idxcount); 333 334 int j = 0; 335 while ( j < count ) { 336 for ( IndexMap::iterator k = index_map.begin(); k != index_map.end(); k++,j++ ) { 337 int tmp = p->getValue()[j]; 338 k->second->push_back(tmp); 339 } 340 } 341 } 342 343 void daeReader::resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *geom, 344 SourceMap &sources, IndexMap &index_map ) 345 { 346 domVertices* vertices = NULL; 482 483 std::vector<std::vector<GLuint> > indexLists; 484 resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh, 485 geometry, sources, indexLists); 486 487 for (size_t i = 0; i < indexLists.size(); ++i) 488 { 489 osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(mode); 490 geometry->addPrimitiveSet(pDrawElements); 491 pDrawElements->asVector().swap(indexLists[i]); 492 } 493 } 494 495 void daeReader::processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources) 496 { 497 const domPolylist::domVcount* pDomVcount = group->getVcount(); 498 if (!pDomVcount) 499 { 500 osg::notify(osg::WARN) << "Index counts not found." << std::endl; 501 return; 502 } 503 504 osg::Geometry* geometry = new osg::Geometry(); 505 geometry->setName(group->getMaterial()); 506 geode->addDrawable(geometry); 507 508 std::vector<std::vector<GLuint> > vertexLists; 509 domP_Array domPArray; 510 domPArray.append(group->getP()); 511 resolveMeshArrays(domPArray, group->getInput_array(), pDomMesh, geometry, sources, vertexLists); 512 513 const std::vector<GLuint>& vertexList = vertexLists.front(); 514 515 osg::DrawElementsUInt* pDrawTriangles = new osg::DrawElementsUInt(GL_TRIANGLES); 516 geometry->addPrimitiveSet(pDrawTriangles); 517 518 const domListOfUInts& vCount = pDomVcount->getValue(); 519 for (size_t i = 0, j = 0; i < vCount.getCount(); ++i) 520 { 521 size_t primitiveLength = vCount[i]; 522 if (j + primitiveLength > vertexList.size()) 523 { 524 osg::notify(osg::WARN) << "Error: vertex counts are greater than the number of indices." << std::endl; 525 return; 526 } 527 for (size_t k = 2; k < primitiveLength; ++k) 528 { 529 pDrawTriangles->push_back(vertexList[j]); 530 pDrawTriangles->push_back(vertexList[j+k-1]); 531 pDrawTriangles->push_back(vertexList[j+k]); 532 } 533 j += primitiveLength; 534 } 535 } 536 537 template <typename T> 538 void daeReader::processPolygons(osg::Geode* geode, 539 const domMesh* pDomMesh, const T *group, SourceMap& sources) 540 { 541 osg::Geometry *geometry = new osg::Geometry(); 542 geometry->setName(group->getMaterial()); 543 geode->addDrawable(geometry); 544 545 osg::DrawElementsUInt* pDrawElements = new osg::DrawElementsUInt(GL_TRIANGLES); 546 geometry->addPrimitiveSet(pDrawElements); 547 548 std::vector<std::vector<GLuint> > indexLists; 549 resolveMeshArrays(group->getP_array(), group->getInput_array(), pDomMesh, 550 geometry, sources, indexLists); 551 552 for ( size_t i = 0; i < indexLists.size(); ++i) 553 { 554 const std::vector<GLuint>& indices = indexLists[i]; 555 556 for (size_t j = 2; j < indices.size(); ++j) 557 { 558 pDrawElements->push_back(indices.front()); 559 pDrawElements->push_back(indices[j - 1]); 560 pDrawElements->push_back(indices[j]); 561 } 562 } 563 } 564 565 void processVertices( 566 domVertices* vertices, 567 daeElement*& position_source, 568 daeElement*& color_source, 569 daeElement*& normal_source, 570 daeElement*& texcoord_source) 571 { 572 const domInputLocal_Array& inputs = vertices->getInput_array(); 573 574 // Process input elements within the vertices element. These are of the unshared type 575 // and therefore cannot have set and offset attributes 576 577 for (size_t i = 0; i < inputs.getCount(); ++i) 578 { 579 xsNMTOKEN semantic = inputs[i]->getSemantic(); 580 daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 581 if (strcmp(COMMON_PROFILE_INPUT_POSITION, semantic) == 0) 582 { 583 position_source = pDaeElement; 584 } 585 else if (strcmp(COMMON_PROFILE_INPUT_COLOR, semantic) == 0) 586 { 587 color_source = pDaeElement; 588 } 589 else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, semantic) == 0) 590 { 591 normal_source = pDaeElement; 592 } 593 else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, semantic) == 0) 594 { 595 texcoord_source = pDaeElement; 596 } 597 } 598 } 599 600 // I've never seen more than 2 used so this should be enough. If you find that 601 // a greater number is needed then increase it accordingly and submit the change 602 // to OpenSceneGraph. 603 // Why not use a vector? Because a large map of VertexIndices is used and 604 // allocating vectors for each element would make it a lot slower. 605 const int MAX_TEXTURE_COORDINATE_SETS = 4; 606 607 void resolveMeshInputs( 608 const domInputLocalOffset_Array &inputs, 609 daeElement*& position_source, 610 daeElement*& color_source, 611 daeElement*& normal_source, 612 daeElement* texcoord_sources[MAX_TEXTURE_COORDINATE_SETS], 613 int& position_offset, 614 int& color_offset, 615 int& normal_offset, 616 int texcoord_offsets[MAX_TEXTURE_COORDINATE_SETS]) 617 { 618 position_source = color_source = normal_source = NULL; 619 position_offset = color_offset = normal_offset = 0; 620 for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) 621 { 622 texcoord_sources[i] = NULL; 623 texcoord_offsets[i] = NULL; 624 } 625 626 for ( size_t i = 0; i < inputs.getCount(); i++ ) 627 { 628 if (strcmp(COMMON_PROFILE_INPUT_VERTEX, inputs[i]->getSemantic()) == 0) 629 { 630 daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 631 if (domVertices* vertices = daeSafeCast<domVertices>(pDaeElement)) 632 { 633 processVertices(vertices, position_source, color_source, normal_source, texcoord_sources[0]); 634 position_offset = inputs[i]->getOffset(); 635 636 if (color_source) color_offset = position_offset; 637 if (normal_source) normal_offset = position_offset; 638 if (texcoord_sources[0]) texcoord_offsets[0] = position_offset; 639 } 640 break; 641 } 642 } 643 644 for ( size_t i = 0; i < inputs.getCount(); i++ ) 645 { 646 xsNMTOKEN semantic = inputs[i]->getSemantic(); 647 daeElement* pDaeElement = getElementFromURI(inputs[i]->getSource()); 648 int offset = inputs[i]->getOffset(); 649 650 if (strcmp(COMMON_PROFILE_INPUT_COLOR, semantic) == 0) 651 { 652 if (color_source != NULL) 653 osg::notify( osg::WARN )<<"Overwriting vertices input(COLOR) with input from primitive"<<std::endl; 654 color_source = pDaeElement; 655 color_offset = offset; 656 } 657 else if (strcmp(COMMON_PROFILE_INPUT_NORMAL, semantic) == 0) 658 { 659 if (normal_source != NULL) 660 osg::notify( osg::WARN )<<"Overwriting vertices input(NORMAL) with input from primitive"<<std::endl; 661 normal_source = pDaeElement; 662 normal_offset = offset; 663 } 664 else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, semantic) == 0) 665 { 666 unsigned set = inputs[i]->getSet(); 667 if (set >= MAX_TEXTURE_COORDINATE_SETS) 668 { 669 osg::notify( osg::WARN )<<"Texture coordinate set "<< set << 670 "was requested, the maximum allowed is " << MAX_TEXTURE_COORDINATE_SETS - 1 << "." << std::endl; 671 continue; 672 } 673 if (texcoord_sources[set]) 674 osg::notify( osg::WARN )<<"Overwriting vertices input(TEXCOORD) with input from primitive"<<std::endl; 675 676 texcoord_sources[set] = pDaeElement; 677 texcoord_offsets[set] = offset; 678 } 679 } 680 } 681 682 struct VertexIndices 683 { 684 VertexIndices(int p, int c, int n, const int t[MAX_TEXTURE_COORDINATE_SETS]) 685 : position_index(p), color_index(c), normal_index(n) 686 { 687 for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) texcoord_indices[i] = t[i]; 688 } 689 bool operator < (const VertexIndices& rhs) const 690 { 691 if (position_index != rhs.position_index) return position_index < rhs.position_index; 692 if (color_index != rhs.color_index) return color_index < rhs.color_index; 693 if (normal_index != rhs.normal_index) return normal_index < rhs.normal_index; 694 for (int i = 0; i < MAX_TEXTURE_COORDINATE_SETS; ++i) 695 { 696 if (texcoord_indices[i] != rhs.texcoord_indices[i]) return texcoord_indices[i] < rhs.texcoord_indices[i]; 697 } 698 return false; 699 } 700 701 int position_index, color_index, normal_index, texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 702 }; 703 704 void daeReader::resolveMeshArrays(const domP_Array& domPArray, 705 const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh, 706 osg::Geometry* geometry, SourceMap &sources, 707 std::vector<std::vector<GLuint> >& vertexLists) 708 { 347 709 daeElement* position_source = NULL; 348 710 daeElement* color_source = NULL; 349 711 daeElement* normal_source = NULL; 350 daeElement* texcoord_source = NULL; 351 352 daeElement *tmp_el; 353 domInputLocalOffset *tmp_input; 354 ReaderGeometry* GeometryWrapper = dynamic_cast<ReaderGeometry*>(geom); 355 356 int TexCoordSetsUsed = 0; 357 358 if ( findInputSourceBySemantic( inputs, "VERTEX", tmp_el, &tmp_input ) ) 359 { 360 vertices = daeSafeCast< domVertices >( tmp_el ); 361 if ( vertices == NULL ) 362 { 363 osg::notify( osg::WARN )<<"Could not get vertices"<<std::endl; 364 return; 365 } 366 367 // Process mandatory offset attribute 368 int offset = tmp_input->getOffset(); 369 if ( index_map[offset] == NULL ) 370 index_map[offset] = new osg::IntArray(); 371 geom->setVertexIndices( index_map[offset] ); 372 373 // Process input elements within the vertices element. These are of the unshared type 374 // and therefore cannot have set and offset attributes 375 376 // The vertices POSITION semantic input element is mandatory 377 domInputLocal *tmp; 378 findInputSourceBySemantic( vertices->getInput_array(), "POSITION", position_source, &tmp ); 379 if ( position_source != NULL ) 380 { 381 geom->setVertexArray( sources[position_source].getVec3Array() ); 382 } 383 else 384 { 385 osg::notify( osg::FATAL )<<"Mandatory POSITION semantic missing"<<std::endl; 386 return; 387 } 388 389 // Process additional vertices input elements 390 findInputSourceBySemantic( vertices->getInput_array(), "COLOR", color_source, &tmp ); 391 findInputSourceBySemantic( vertices->getInput_array(), "NORMAL", normal_source, &tmp ); 392 findInputSourceBySemantic( vertices->getInput_array(), "TEXCOORD", texcoord_source, &tmp ); 393 394 395 int VertexCount = sources[position_source].getCount(); 396 if ( color_source != NULL ) 397 { 398 // Check matching arrays 399 if ( sources[color_source].getCount() >= VertexCount ) 400 { 401 geom->setColorArray( sources[color_source].getVec4Array() ); 402 geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 403 geom->setColorIndices( index_map[offset] ); // Use the vertex indices 404 } 405 else 406 { 407 osg::notify( osg::WARN )<<"Not enough entries in color array"<<std::endl; 408 } 409 } 410 if ( normal_source != NULL ) 411 { 412 // Check matching arrays 413 if ( sources[normal_source].getCount() >= VertexCount ) 414 { 415 geom->setNormalArray( sources[normal_source].getVec3Array() ); 416 geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); 417 geom->setNormalIndices( index_map[offset] ); // Use the vertex indices 418 } 419 else 420 { 421 osg::notify( osg::WARN )<<"Not enough entries in normal array"<<std::endl; 422 } 423 } 424 // It seems sensible to only process the first input found here with a TEXCOORD semantic. 425 // as offsets are not allowed here. 426 // I assume that this belongs to set zero as the DOM returns 0 for the set attribute on shared 427 // input elements even if the attribute is absent. 428 if ( texcoord_source != NULL ) 429 { 430 domSourceReader *sc = &sources[texcoord_source]; 431 if ( sc->getCount() >= VertexCount ) 432 { 433 if (NULL != GeometryWrapper) 434 GeometryWrapper->_TexcoordSetMap[0] = TexCoordSetsUsed; 435 switch( sc->getArrayType() ) 712 daeElement* texcoord_sources[MAX_TEXTURE_COORDINATE_SETS] = {NULL}; 713 int position_offset = 0; 714 int color_offset = 0; 715 int normal_offset = 0; 716 int texcoord_offsets[MAX_TEXTURE_COORDINATE_SETS] = {0}; 717 718 resolveMeshInputs(inputs, 719 position_source, 720 color_source, 721 normal_source, 722 texcoord_sources, 723 position_offset, 724 color_offset, 725 normal_offset, 726 texcoord_offsets); 727 728 unsigned stride = 0; 729 for (size_t i = 0; i < inputs.getCount(); ++i) 730 { 731 stride = osg::maximum<unsigned>(stride, inputs[i]->getOffset()); 732 } 733 ++stride; 734 735 typedef std::map<VertexIndices, GLuint> VertexIndicesIndexMap; 736 VertexIndicesIndexMap vertexIndicesIndexMap; 737 738 for (size_t j = 0; j < domPArray.getCount(); ++j) 739 { 740 const domListOfUInts& p = domPArray[j]->getValue(); 741 742 for (size_t i = 0; i < p.getCount(); i += stride) 743 { 744 int texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 745 for (int t = 0; t < MAX_TEXTURE_COORDINATE_SETS; ++t) 746 { 747 texcoord_indices[t] = p.get(i + texcoord_offsets[t]); 748 } 749 VertexIndices v( 750 p.get(i + position_offset), 751 p.get(i + color_offset), 752 p.get(i + normal_offset), 753 texcoord_indices); 754 vertexIndicesIndexMap.insert(VertexIndicesIndexMap::value_type(v, 0)); 755 } 756 } 757 758 { 759 VertexIndicesIndexMap::iterator it = vertexIndicesIndexMap.begin(), end = vertexIndicesIndexMap.end(); 760 for (GLuint i = 0; it != end; ++it, ++i) 761 { 762 it->second = i; 763 } 764 } 765 766 vertexLists.resize(domPArray.getCount()); 767 768 for (size_t j = 0; j < domPArray.getCount(); ++j) 769 { 770 const domListOfUInts& p = domPArray[j]->getValue(); 771 772 for (size_t i = 0; i < p.getCount(); i += stride) 773 { 774 int texcoord_indices[MAX_TEXTURE_COORDINATE_SETS]; 775 for (int t = 0; t < MAX_TEXTURE_COORDINATE_SETS; ++t) 776 { 777 texcoord_indices[t] = p.get(i + texcoord_offsets[t]); 778 } 779 VertexIndices v( 780 p.get(i + position_offset), 781 p.get(i + color_offset), 782 p.get(i + normal_offset), 783 texcoord_indices); 784 785 GLuint index = vertexIndicesIndexMap.find(v)->second; 786 787 _oldToNewIndexMap.insert(OldToNewIndexMap::value_type( 788 OldToNewIndexMap::key_type(pDomMesh, v.position_index), 789 OldToNewIndexMap::mapped_type(geometry, index))); 790 vertexLists[j].push_back(index); 791 } 792 } 793 794 if (const osg::Vec3Array* source = sources[position_source].getVec3Array()) 795 { 796 osg::Vec3Array* pArray = new osg::Vec3Array; 797 798 for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 799 end = vertexIndicesIndexMap.end(); it != end; ++it) 800 { 801 pArray->push_back(source->at(it->first.position_index)); 802 } 803 804 geometry->setVertexData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 805 } 806 807 if (color_source) 808 { 809 if (const osg::Vec4Array* source = sources[color_source].getVec4Array()) 810 { 811 osg::Vec4Array* pArray = new osg::Vec4Array; 812 813 for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 814 end = vertexIndicesIndexMap.end(); it != end; ++it) 815 { 816 pArray->push_back(source->at(it->first.color_index)); 817 } 818 819 geometry->setColorData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 820 } 821 } 822 823 if (normal_source) 824 { 825 if (const osg::Vec3Array* source = sources[normal_source].getVec3Array()) 826 { 827 osg::Vec3Array* pArray = new osg::Vec3Array; 828 829 for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 830 end = vertexIndicesIndexMap.end(); it != end; ++it) 831 { 832 pArray->push_back(source->at(it->first.normal_index)); 833 } 834 835 geometry->setNormalData(osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 836 } 837 } 838 839 for (int texcoord_set = 0; texcoord_set < MAX_TEXTURE_COORDINATE_SETS; ++texcoord_set) 840 { 841 if (daeElement* texcoord_source = texcoord_sources[texcoord_set]) 842 { 843 osg::Array* pArray = NULL; 844 845 if (const osg::Vec2Array* source = sources[texcoord_source].getVec2Array()) 846 { 847 osg::Vec2Array* pVec2Array = new osg::Vec2Array; 848 pArray = pVec2Array; 849 850 for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 851 end = vertexIndicesIndexMap.end(); it != end; ++it) 436 852 { 437 case domSourceReader::Vec2: 438 geom->setTexCoordArray( TexCoordSetsUsed, sc->getVec2Array() ); 439 break; 440 case domSourceReader::Vec3: 441 geom->setTexCoordArray( TexCoordSetsUsed, sc->getVec3Array() ); 442 break; 443 default: 444 osg::notify( osg::WARN )<<"Unsupported array type: "<< sc->getArrayType() <<std::endl; 445 break; 853 pVec2Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); 446 854 } 447 TexCoordSetsUsed++; 448 } 449 else 450 { 451 osg::notify( osg::WARN )<<"Not enough entries in texcoord array"<<std::endl; 452 } 453 } 454 if ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, 1 ) ) 455 { 456 osg::notify( osg::WARN )<<"More than one input element with TEXCOORD semantic found in vertices element"<<std::endl; 457 } 458 } 459 else 460 { 461 osg::notify( osg::WARN )<<"Vertex data not found"<<std::endl; 462 return; 463 } 464 465 if ( findInputSourceBySemantic( inputs, "COLOR", tmp_el, &tmp_input )) 466 { 467 if (color_source != NULL) 468 osg::notify( osg::WARN )<<"Overwriting vertices input(COLOR) with input from primitive"<<std::endl; 469 else 470 geom->setColorBinding( osg::Geometry::BIND_PER_VERTEX ); 471 472 int offset = tmp_input->getOffset(); 473 if ( index_map[offset] == NULL ) 474 index_map[offset] = new osg::IntArray(); 475 geom->setColorIndices( index_map[offset] ); 476 geom->setColorArray( sources[tmp_el].getVec4Array() ); 477 } 478 479 if ( findInputSourceBySemantic( inputs, "NORMAL", tmp_el, &tmp_input ) ) 480 { 481 if (normal_source != NULL) 482 osg::notify( osg::WARN )<<"Overwriting vertices input(NORMAL) with input from primitive"<<std::endl; 483 else 484 geom->setNormalBinding( osg::Geometry::BIND_PER_VERTEX ); 485 486 int offset = tmp_input->getOffset(); 487 if ( index_map[offset] == NULL ) 488 index_map[offset] = new osg::IntArray(); 489 geom->setNormalIndices( index_map[offset] ); 490 geom->setNormalArray( sources[tmp_el].getVec3Array() ); 491 } 492 493 int inputNumber = 0; 494 while ( findInputSourceBySemantic( inputs, "TEXCOORD", texcoord_source, &tmp_input, inputNumber ) ) 495 { 496 int offset = tmp_input->getOffset(); 497 int set = tmp_input->getSet(); 498 if (NULL != GeometryWrapper) 499 { 500 if (GeometryWrapper->_TexcoordSetMap.find(set) != GeometryWrapper->_TexcoordSetMap.end()) 501 osg::notify( osg::WARN )<<"Duplicate texcoord set: "<< set <<std::endl; 502 GeometryWrapper->_TexcoordSetMap[set] = TexCoordSetsUsed; 503 } 504 505 if ( index_map[offset] == NULL ) 506 { 507 index_map[offset] = new osg::IntArray(); 508 } 509 geom->setTexCoordIndices( TexCoordSetsUsed, index_map[offset] ); 510 511 if ( texcoord_source != NULL ) 512 { 513 domSourceReader &sc = sources[texcoord_source]; 514 switch( sc.getArrayType() ) { 515 case domSourceReader::Vec2: 516 geom->setTexCoordArray( TexCoordSetsUsed, sc.getVec2Array() ); 517 break; 518 case domSourceReader::Vec3: 519 geom->setTexCoordArray( TexCoordSetsUsed, sc.getVec3Array() ); 520 break; 521 default: 522 osg::notify( osg::WARN )<<"Unsupported array type: "<< sc.getArrayType() <<std::endl; 523 break; 524 } 525 } 526 TexCoordSetsUsed++; 527 inputNumber++; 528 } 529 } 530 855 } 856 else if (const osg::Vec3Array* source = sources[texcoord_source].getVec3Array()) 857 { 858 osg::Vec3Array* pVec3Array = new osg::Vec3Array; 859 pArray = pVec3Array; 860 861 for (VertexIndicesIndexMap::const_iterator it = vertexIndicesIndexMap.begin(), 862 end = vertexIndicesIndexMap.end(); it != end; ++it) 863 { 864 pVec3Array->push_back(source->at(it->first.texcoord_indices[texcoord_set])); 865 } 866 } 867 868 if (pArray) 869 { 870 geometry->setTexCoordData(texcoord_set, osg::Geometry::ArrayData(pArray, osg::Geometry::BIND_PER_VERTEX)); 871 } 872 } 873 } 874 } -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeRMaterials.cpp
r9956 r11129 19 19 #include <dom/domCOLLADA.h> 20 20 #include <dom/domProfile_COMMON.h> 21 #include <dom/domConstants.h> 21 22 22 23 #include <osg/BlendColor> … … 30 31 #include <sstream> 31 32 32 using namespace osgdae; 33 33 using namespace osgDAE; 34 35 template <typename T> 36 void daeReader::getTransparencyCounts(daeDatabase* database, int& zero, int& one) const 37 { 38 std::vector<T*> constantVec; 39 database->typeLookup(constantVec); 40 41 for (size_t i = 0; i < constantVec.size(); ++i) 42 { 43 if (const domCommon_transparent_type* pTransparent = constantVec[i]->getTransparent()) 44 { 45 domFx_opaque_enum opaque = pTransparent->getOpaque(); 46 if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 47 { 48 ++one; 49 continue; 50 } 51 } 52 53 if (const domCommon_float_or_param_type* pTransparency = constantVec[i]->getTransparency()) 54 { 55 float transparency; 56 57 domFloat transparencyParam = 1.0; 58 if (pTransparency->getFloat()) 59 { 60 transparency = pTransparency->getFloat()->getValue(); 61 } 62 else if (pTransparency->getParam() && 63 GetFloatParam(pTransparency->getParam()->getRef(), transparencyParam)) 64 { 65 transparency = transparencyParam; 66 } 67 else 68 { 69 continue; 70 } 71 72 if (transparency < 0.01f) 73 { 74 ++zero; 75 } 76 else if (transparency > 0.99f) 77 { 78 ++one; 79 } 80 } 81 82 } 83 84 } 85 86 bool daeReader::findInvertTransparency(daeDatabase* database) const 87 { 88 int zero = 0, one = 0; 89 getTransparencyCounts<domProfile_COMMON::domTechnique::domConstant>(database, zero, one); 90 getTransparencyCounts<domProfile_COMMON::domTechnique::domLambert>(database, zero, one); 91 getTransparencyCounts<domProfile_COMMON::domTechnique::domPhong>(database, zero, one); 92 getTransparencyCounts<domProfile_COMMON::domTechnique::domBlinn>(database, zero, one); 93 94 return zero > one; 95 } 34 96 35 97 // <bind_material> … … 64 126 osg::Drawable* drawable = geode->getDrawable(i); 65 127 std::string materialName = drawable->getName(); 66 ReaderGeometry *cachedGeometry = dynamic_cast<ReaderGeometry*>(cachedGeode->getDrawable(i)->asGeometry());128 osg::Geometry *cachedGeometry = dynamic_cast<osg::Geometry*>(cachedGeode->getDrawable(i)->asGeometry()); 67 129 68 130 domInstance_material_Array &ima = bm->getTechnique_common()->getInstance_material_array(); … … 80 142 // Check material cache if this material already exists 81 143 osg::StateSet* ss; 82 domMaterialStateSetMap::iterator iter = materialMap.find( mat );83 if ( iter !=materialMap.end() )144 domMaterialStateSetMap::iterator iter = _materialMap.find( mat ); 145 if (iter != _materialMap.end() ) 84 146 { 85 147 // Reuse material … … 91 153 ss = new osg::StateSet; 92 154 processMaterial(ss, mat); 93 materialMap.insert(std::make_pair(mat, ss));155 _materialMap.insert(std::make_pair(mat, ss)); 94 156 } 95 157 drawable->setStateSet(ss); 96 158 // Need to process bind_vertex_inputs here 97 // This all feels like a horrible kludge to me98 // I wish somebody with a better knowledge of Collada and OSG than me would have a go at it!99 159 // 1. Clear the texcoord arrays and associated texcoord vertex indices 100 160 // from the current (cloned) drawable. … … 106 166 } 107 167 clonedGeometry->getTexCoordArrayList().clear(); 168 108 169 // 2. For each possible texture unit find the correct texcoord array and 109 // indices from the original (uncloned)drawable and place in the cloned drawable170 // indices from the cached drawable and place in the cloned drawable 110 171 // in the correct texture unit slot 111 std::string TransparencyMapTexcoordName; 112 osg::Texture2D *Texture; 113 if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(AMBIENT_OCCLUSION_UNIT, osg::StateAttribute::TEXTURE)))) 114 { 115 std::string AmbientOcclusionTexcoordName = Texture->getName(); 116 if (!AmbientOcclusionTexcoordName.empty()) 117 { 118 domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 119 size_t k; 120 for ( k = 0; k < bvia.getCount(); k++) 121 { 122 if (!strcmp(bvia[k]->getSemantic(), AmbientOcclusionTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 123 { 124 // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 125 if (NULL != cachedGeometry) 126 { 127 std::map<int, int>::iterator iTr; 128 if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 129 { 130 // Copy the texture cordinates and indices (if any) into the cloned geometry 131 clonedGeometry->setTexCoordData(AMBIENT_OCCLUSION_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 132 } 133 } 134 break; 135 } 136 } 137 if (k == bvia.getCount()) 138 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << AmbientOcclusionTexcoordName << std::endl; 139 } 140 } 141 if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE)))) 142 { 143 std::string MainTextureTexcoordName = Texture->getName(); 144 if (!MainTextureTexcoordName.empty()) 145 { 146 domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 147 size_t k; 148 for ( k = 0; k < bvia.getCount(); k++) 149 { 150 if (!strcmp(bvia[k]->getSemantic(), MainTextureTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 151 { 152 // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 153 if (NULL != cachedGeometry) 154 { 155 std::map<int, int>::iterator iTr; 156 if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 157 { 158 // Copy the texture cordinates and indices (if any) into the cloned geometry 159 clonedGeometry->setTexCoordData(MAIN_TEXTURE_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 160 } 161 } 162 break; 163 } 164 } 165 if (k == bvia.getCount()) 166 { 167 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << MainTextureTexcoordName << std::endl; 168 // This may be a departure from the spec. For the time being I am only going to do this 169 // for the MAIN_TEXTURE_UNIT. 170 // Not found so just use the first TEXCOORD we have if any. 171 if (cachedGeometry->_TexcoordSetMap.size() > 0) 172 clonedGeometry->setTexCoordData(MAIN_TEXTURE_UNIT, cachedGeometry->getTexCoordData(cachedGeometry->_TexcoordSetMap.begin()->second)); 173 } 174 } 175 } 176 if (NULL != (Texture = dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(TRANSPARENCY_MAP_UNIT, osg::StateAttribute::TEXTURE)))) 177 { 178 std::string TransparencyMapTexcoordName = Texture->getName(); 179 if (!TransparencyMapTexcoordName.empty()) 180 { 181 domInstance_material::domBind_vertex_input_Array &bvia = ima[j]->getBind_vertex_input_array(); 182 size_t k; 183 for ( k = 0; k < bvia.getCount(); k++) 184 { 185 if (!strcmp(bvia[k]->getSemantic(), TransparencyMapTexcoordName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), "TEXCOORD")) 186 { 187 // OK - found the effect name, now see if I can find a matching set in the cachedGeometry 188 if (NULL != cachedGeometry) 189 { 190 std::map<int, int>::iterator iTr; 191 if (cachedGeometry->_TexcoordSetMap.end() != (iTr = cachedGeometry->_TexcoordSetMap.find(bvia[k]->getInput_set()))) 192 { 193 // Copy the texture cordinates and indices (if any) into the cloned geometry 194 clonedGeometry->setTexCoordData(TRANSPARENCY_MAP_UNIT, cachedGeometry->getTexCoordData(iTr->second)); 195 } 196 } 197 break; 198 } 199 } 200 if (k == bvia.getCount()) 201 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << TransparencyMapTexcoordName << std::endl; 202 } 203 } 172 copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], AMBIENT_OCCLUSION_UNIT); 173 copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], MAIN_TEXTURE_UNIT); 174 copyTextureCoordinateSet(ss, cachedGeometry, clonedGeometry, ima[j], TRANSPARENCY_MAP_UNIT); 204 175 } 205 176 else … … 228 199 void daeReader::processMaterial(osg::StateSet *ss, domMaterial *mat ) 229 200 { 230 currentInstance_effect = mat->getInstance_effect();231 domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( currentInstance_effect->getUrl() ) );201 _currentInstance_effect = mat->getInstance_effect(); 202 domEffect *effect = daeSafeCast< domEffect >( getElementFromURI( _currentInstance_effect->getUrl() ) ); 232 203 if (effect) 233 204 { … … 260 231 { 261 232 domProfile_COMMON *pc = daeSafeCast< domProfile_COMMON >( effect->getFx_profile_abstract_array()[i] ); 262 if ( pc != NULL )263 { 264 if ( hasCOMMON )233 if (pc != NULL ) 234 { 235 if (hasCOMMON ) 265 236 { 266 237 osg::notify( osg::WARN ) << "Effect already has a profile_COMMON. Skipping this one" << std::endl; 267 238 continue; 268 239 } 269 currentEffect = effect;240 _currentEffect = effect; 270 241 processProfileCOMMON(ss, pc); 271 242 hasCOMMON = true; … … 346 317 // 0..1 <transparency> 347 318 // 0..1 <index_of_refraction> 348 if ( b != NULL )349 { 350 osg:: StateAttribute*EmissionStateAttribute = NULL;351 osg:: StateAttribute*AmbientStateAttribute = NULL;352 osg:: StateAttribute*DiffuseStateAttribute = NULL;353 processColorOrTextureType( b->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute );319 if (b != NULL ) 320 { 321 osg::Texture2D *EmissionStateAttribute = NULL; 322 osg::Texture2D *AmbientStateAttribute = NULL; 323 osg::Texture2D *DiffuseStateAttribute = NULL; 324 processColorOrTextureType(ss, b->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 354 325 if (NULL != EmissionStateAttribute) 355 326 osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 356 327 357 processColorOrTextureType( b->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute );328 processColorOrTextureType(ss, b->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute ); 358 329 359 processColorOrTextureType( b->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute );360 if ( DiffuseStateAttribute != NULL )361 { 362 if ( AmbientStateAttribute != NULL )330 processColorOrTextureType(ss, b->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 331 if (DiffuseStateAttribute != NULL ) 332 { 333 if (AmbientStateAttribute != NULL ) 363 334 { 364 335 // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a … … 392 363 else 393 364 { 394 if ( NULL != AmbientStateAttribute )365 if (NULL != AmbientStateAttribute ) 395 366 osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 396 367 } 397 368 398 if (processColorOrTextureType(b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() ) && (NULL != DiffuseStateAttribute) )369 if (processColorOrTextureType(ss, b->getSpecular(), osg::Material::SPECULAR, mat.get(), b->getShininess() ) && (NULL != DiffuseStateAttribute) ) 399 370 { 400 371 // Diffuse texture will defeat specular highlighting … … 420 391 // 0..1 <transparency> 421 392 // 0..1 <index_of_refraction> 422 else if ( p != NULL )423 { 424 osg:: StateAttribute*EmissionStateAttribute = NULL;425 osg:: StateAttribute*AmbientStateAttribute = NULL;426 osg:: StateAttribute*DiffuseStateAttribute = NULL;427 processColorOrTextureType( p->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute );393 else if (p != NULL ) 394 { 395 osg::Texture2D *EmissionStateAttribute = NULL; 396 osg::Texture2D *AmbientStateAttribute = NULL; 397 osg::Texture2D *DiffuseStateAttribute = NULL; 398 processColorOrTextureType(ss, p->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 428 399 if (NULL != EmissionStateAttribute) 429 400 osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 430 401 431 processColorOrTextureType( p->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute );402 processColorOrTextureType(ss, p->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute ); 432 403 433 processColorOrTextureType( p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute );434 if ( DiffuseStateAttribute != NULL )435 { 436 if ( AmbientStateAttribute != NULL )404 processColorOrTextureType(ss, p->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 405 if (DiffuseStateAttribute != NULL ) 406 { 407 if (AmbientStateAttribute != NULL ) 437 408 { 438 409 // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a … … 466 437 else 467 438 { 468 if ( NULL != AmbientStateAttribute )439 if (NULL != AmbientStateAttribute ) 469 440 osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 470 441 } 471 442 472 if (processColorOrTextureType(p->getSpecular(), osg::Material::SPECULAR, mat.get(), p->getShininess() ) && (NULL != DiffuseStateAttribute) )443 if (processColorOrTextureType(ss, p->getSpecular(), osg::Material::SPECULAR, mat.get(), p->getShininess() ) && (NULL != DiffuseStateAttribute) ) 473 444 { 474 445 // Diffuse texture will defeat specular highlighting … … 492 463 // 0..1 <transparency> 493 464 // 0..1 <index_of_refraction> 494 else if ( l != NULL )495 { 496 osg:: StateAttribute*EmissionStateAttribute = NULL;497 osg:: StateAttribute*AmbientStateAttribute = NULL;498 osg:: StateAttribute*DiffuseStateAttribute = NULL;499 processColorOrTextureType( l->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute );465 else if (l != NULL ) 466 { 467 osg::Texture2D *EmissionStateAttribute = NULL; 468 osg::Texture2D *AmbientStateAttribute = NULL; 469 osg::Texture2D *DiffuseStateAttribute = NULL; 470 processColorOrTextureType(ss, l->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &EmissionStateAttribute ); 500 471 if (NULL != EmissionStateAttribute) 501 472 osg::notify( osg::WARN ) << "Currently no support for <texture> in Emission channel " << std::endl; 502 473 503 processColorOrTextureType( l->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute);504 505 processColorOrTextureType( l->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute );506 if ( DiffuseStateAttribute != NULL )507 { 508 if ( AmbientStateAttribute != NULL )474 processColorOrTextureType(ss, l->getAmbient(), osg::Material::AMBIENT, mat.get(), NULL, &AmbientStateAttribute); 475 476 processColorOrTextureType(ss, l->getDiffuse(), osg::Material::DIFFUSE, mat.get(), NULL, &DiffuseStateAttribute ); 477 if (DiffuseStateAttribute != NULL ) 478 { 479 if (AmbientStateAttribute != NULL ) 509 480 { 510 481 // Set the ambient and diffuse colour white so that the incoming fragment colour ends up as a … … 538 509 else 539 510 { 540 if ( NULL != AmbientStateAttribute )511 if (NULL != AmbientStateAttribute ) 541 512 osg::notify( osg::WARN ) << "Ambient occlusion map only supported when diffuse texture also specified" << std::endl; 542 513 } … … 552 523 // 0..1 <transparency> 553 524 // 0..1 <index_of_refraction> 554 else if ( c != NULL )555 { 556 osg:: StateAttribute*sa = NULL;557 processColorOrTextureType( c->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &sa );558 if ( sa != NULL )525 else if (c != NULL ) 526 { 527 osg::Texture2D *sa = NULL; 528 processColorOrTextureType(ss, c->getEmission(), osg::Material::EMISSION, mat.get(), NULL, &sa ); 529 if (sa != NULL ) 559 530 { 560 531 ss->setTextureMode( MAIN_TEXTURE_UNIT, GL_TEXTURE_2D, GL_TRUE ); … … 586 557 // 1 texcoord 587 558 // 0..* extra 588 bool daeReader::processColorOrTextureType( domCommon_color_or_texture_type *cot, 589 osg::Material::ColorMode channel, 590 osg::Material *mat, 591 domCommon_float_or_param_type *fop, 592 osg::StateAttribute **sa, 593 bool blinn) 594 { 595 if ( cot == NULL ) 559 bool daeReader::processColorOrTextureType(const osg::StateSet* ss, 560 domCommon_color_or_texture_type *cot, 561 osg::Material::ColorMode channel, 562 osg::Material *mat, 563 domCommon_float_or_param_type *fop, 564 osg::Texture2D **sa, 565 bool blinn) 566 { 567 if (cot == NULL ) 596 568 { 597 569 return false; 598 570 } 599 571 bool retVal = false; 572 573 std::string texCoordSet; 600 574 601 575 //osg::StateAttribute *sa = NULL; 602 576 //TODO: Make all channels process <param ref=""> type of value 603 if ( channel == osg::Material::EMISSION )604 { 605 if ( cot->getColor() != NULL )577 if (channel == osg::Material::EMISSION ) 578 { 579 if (cot->getColor() != NULL ) 606 580 { 607 581 domFloat4 &f4 = cot->getColor()->getValue(); … … 622 596 if (sa != NULL) 623 597 { 624 *sa = processTexture( cot->getTexture() );598 *sa = processTexture( cot->getTexture(), ss, MAIN_TEXTURE_UNIT); 625 599 retVal = true; 626 600 } … … 633 607 } 634 608 } 635 else if ( channel == osg::Material::AMBIENT )636 { 637 if ( cot->getColor() != NULL )609 else if (channel == osg::Material::AMBIENT ) 610 { 611 if (cot->getColor() != NULL ) 638 612 { 639 613 domFloat4 &f4 = cot->getColor()->getValue(); … … 653 627 { 654 628 if (sa != NULL) 655 *sa = processTexture( cot->getTexture() );629 *sa = processTexture( cot->getTexture(), ss, AMBIENT_OCCLUSION_UNIT); 656 630 else 657 631 { … … 666 640 } 667 641 } 668 else if ( channel == osg::Material::DIFFUSE )669 { 670 if ( cot->getColor() != NULL )642 else if (channel == osg::Material::DIFFUSE ) 643 { 644 if (cot->getColor() != NULL ) 671 645 { 672 646 domFloat4 &f4 = cot->getColor()->getValue(); … … 674 648 retVal = true; 675 649 } 676 else if ( cot->getTexture() != NULL)650 else if (cot->getTexture() != NULL) 677 651 { 678 652 if (sa != NULL) 679 *sa = processTexture( cot->getTexture() );653 *sa = processTexture( cot->getTexture(), ss, MAIN_TEXTURE_UNIT); 680 654 else 681 655 { … … 684 658 } 685 659 domExtra *extra = cot->getTexture()->getExtra(); 686 if ( extra != NULL && extra->getType() != NULL && strcmp( extra->getType(), "color" ) == 0 )660 if (extra != NULL && extra->getType() != NULL && strcmp( extra->getType(), "color" ) == 0 ) 687 661 { 688 662 //the extra data for osg. Diffuse color can happen with a texture. … … 690 664 { 691 665 domTechnique *teq = extra->getTechnique_array()[i]; 692 if ( strcmp( teq->getProfile(), "SCEI" ) == 0 )666 if (strcmp( teq->getProfile(), "SCEI" ) == 0 ) 693 667 { 694 668 osg::Vec4 col; … … 717 691 } 718 692 } 719 else if ( channel == osg::Material::SPECULAR )720 { 721 if ( cot->getColor() != NULL )693 else if (channel == osg::Material::SPECULAR ) 694 { 695 if (cot->getColor() != NULL ) 722 696 { 723 697 domFloat4 &f4 = cot->getColor()->getValue(); … … 743 717 } 744 718 745 if ( fop != NULL && fop->getFloat() != NULL )719 if (fop != NULL && fop->getFloat() != NULL ) 746 720 { 747 721 float shininess = fop->getFloat()->getValue(); … … 759 733 } 760 734 761 bool daeReader::GetFloat4Param(xsNCName Reference, domFloat4 &f4) 735 bool daeReader::GetFloat4Param(xsNCName Reference, domFloat4 &f4) const 762 736 { 763 737 std::string MyReference = Reference; 764 738 765 739 MyReference.insert(0, "./"); 766 daeSIDResolver Resolver( currentEffect, MyReference.c_str());740 daeSIDResolver Resolver(_currentEffect, MyReference.c_str()); 767 741 daeElement *el = Resolver.getElement(); 768 742 if (NULL == el) 769 743 return false; 770 744 771 if (NULL != currentInstance_effect)745 if (NULL != _currentInstance_effect) 772 746 { 773 747 // look here first for setparams 774 748 // I am sure there must be a better way of doing this 775 749 // Maybe the Collada DAE guys can give us a parameter management mechanism ! 776 const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array();750 const domInstance_effect::domSetparam_Array& SetParamArray = _currentInstance_effect->getSetparam_array(); 777 751 size_t NumberOfSetParams = SetParamArray.getCount(); 778 752 for (size_t i = 0; i < NumberOfSetParams; i++) … … 806 780 } 807 781 808 bool daeReader::GetFloatParam(xsNCName Reference, domFloat &f) 782 bool daeReader::GetFloatParam(xsNCName Reference, domFloat &f) const 809 783 { 810 784 std::string MyReference = Reference; 811 785 812 786 MyReference.insert(0, "./"); 813 daeSIDResolver Resolver( currentEffect, MyReference.c_str());787 daeSIDResolver Resolver(_currentEffect, MyReference.c_str()); 814 788 daeElement *el = Resolver.getElement(); 815 789 if (NULL == el) 816 790 return false; 817 791 818 if (NULL != currentInstance_effect)792 if (NULL != _currentInstance_effect) 819 793 { 820 794 // look here first for setparams 821 795 // I am sure there must be a better way of doing this 822 796 // Maybe the Collada DAE guys can give us a parameter management mechanism ! 823 const domInstance_effect::domSetparam_Array& SetParamArray = currentInstance_effect->getSetparam_array();797 const domInstance_effect::domSetparam_Array& SetParamArray = _currentInstance_effect->getSetparam_array(); 824 798 size_t NumberOfSetParams = SetParamArray.getCount(); 825 799 for (size_t i = 0; i < NumberOfSetParams; i++) … … 853 827 } 854 828 855 osg::StateAttribute *daeReader::processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex ) 856 { 829 osg::Texture::WrapMode getWrapMode(domFx_sampler_wrap_common domWrap) 830 { 831 switch (domWrap) 832 { 833 case FX_SAMPLER_WRAP_COMMON_WRAP: 834 return osg::Texture::REPEAT; 835 case FX_SAMPLER_WRAP_COMMON_MIRROR: 836 return osg::Texture::MIRROR; 837 case FX_SAMPLER_WRAP_COMMON_CLAMP: 838 return osg::Texture::CLAMP_TO_EDGE; 839 case FX_SAMPLER_WRAP_COMMON_NONE: 840 case FX_SAMPLER_WRAP_COMMON_BORDER: 841 return osg::Texture::CLAMP_TO_BORDER; 842 } 843 844 return osg::Texture::CLAMP; 845 } 846 847 osg::Texture::FilterMode getFilterMode(domFx_sampler_filter_common domFilter, bool allowMipMap) 848 { 849 switch (domFilter) 850 { 851 case FX_SAMPLER_FILTER_COMMON_NEAREST: 852 return osg::Texture::NEAREST; 853 case FX_SAMPLER_FILTER_COMMON_LINEAR: 854 return osg::Texture::LINEAR; 855 } 856 857 if (allowMipMap) 858 { 859 switch (domFilter) 860 { 861 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 862 return osg::Texture::NEAREST_MIPMAP_NEAREST; 863 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 864 return osg::Texture::LINEAR_MIPMAP_NEAREST; 865 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 866 return osg::Texture::NEAREST_MIPMAP_LINEAR; 867 case FX_SAMPLER_FILTER_COMMON_NONE: 868 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 869 return osg::Texture::LINEAR_MIPMAP_LINEAR; 870 } 871 } 872 873 return osg::Texture::LINEAR; 874 } 875 876 std::string daeReader::processImagePath(const domImage* pDomImage) const 877 { 878 if (pDomImage == NULL) 879 { 880 osg::notify( osg::WARN ) << "Could not locate image for texture" << std::endl; 881 return std::string(); 882 } 883 884 //Got a sampler and a surface and an imaged. Time to create the texture stuff for osg 885 if (pDomImage->getInit_from()) 886 { 887 pDomImage->getInit_from()->getValue().validate(); 888 if (strcmp(pDomImage->getInit_from()->getValue().getProtocol(), "file") == 0) 889 { 890 std::string path = pDomImage->getInit_from()->getValue().pathDir() + 891 pDomImage->getInit_from()->getValue().pathFile(); 892 path = cdom::uriToNativePath(path); 893 if (path.empty()) 894 { 895 osg::notify( osg::WARN ) << "Unable to get path from URI." << std::endl; 896 return std::string(); 897 } 898 #ifdef WIN32 899 // If the path has a drive specifier or a UNC name then strip the leading / 900 const char* szFilename = path.c_str(); 901 if (path.size() > 2 && (path[2] == ':' || (path[1] == '/' && path[2] == '/'))) 902 return szFilename + 1; 903 #endif 904 return path; 905 } 906 else 907 { 908 osg::notify( osg::WARN ) << "Only images with a \"file\" scheme URI are supported in this version." << std::endl; 909 } 910 } 911 else 912 { 913 osg::notify( osg::WARN ) << "Embedded image data is not supported in this version." << std::endl; 914 } 915 return std::string(); 916 } 917 918 float luminance(const osg::Vec4& color) 919 { 920 return 921 color.r() * 0.212671f + 922 color.g() * 0.715160f + 923 color.b() * 0.072169f; 924 } 925 926 osg::Image* daeReader::processImageTransparency(const osg::Image* srcImg, domFx_opaque_enum opaque, float transparency) const 927 { 928 int s = srcImg->s(); 929 int t = srcImg->t(); 930 unsigned char* pixels = new unsigned char [s * t]; 931 932 if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 933 { 934 for (int i = 0; i < t; ++i) 935 { 936 for (int j = 0; j < s; ++j) 937 { 938 osg::Vec4 color(srcImg->getColor(j, i)); 939 940 pixels[i * s + j] = static_cast<unsigned char>( 941 (1.0f - luminance(color) * transparency) * 255.0f); 942 } 943 } 944 } 945 else 946 { 947 bool texHasAlpha = false; 948 switch (srcImg->getPixelFormat()) 949 { 950 case GL_ALPHA: 951 case GL_LUMINANCE_ALPHA: 952 case GL_RGBA: 953 case GL_BGRA: 954 texHasAlpha = true; 955 } 956 957 if (texHasAlpha) 958 { 959 for (int i = 0; i < t; ++i) 960 { 961 for (int j = 0; j < s; ++j) 962 { 963 osg::Vec4 color(srcImg->getColor(j, i)); 964 965 pixels[i * s + j] = static_cast<unsigned char>( 966 color.a() * transparency * 255.0f); 967 } 968 } 969 } 970 else 971 { 972 for (int i = 0; i < t; ++i) 973 { 974 for (int j = 0; j < s; ++j) 975 { 976 osg::Vec4 color(srcImg->getColor(j, i)); 977 978 pixels[i * s + j] = static_cast<unsigned char>( 979 luminance(color) * transparency * 255.0f); 980 } 981 } 982 } 983 } 984 985 osg::Image* transparentImage = new osg::Image; 986 transparentImage->setWriteHint(osg::Image::STORE_INLINE); 987 transparentImage->setImage(s, t, 1, GL_ALPHA, GL_ALPHA, GL_UNSIGNED_BYTE, pixels, osg::Image::USE_NEW_DELETE); 988 989 return transparentImage; 990 } 991 992 osg::Texture2D* daeReader::processTexture( 993 domCommon_color_or_texture_type_complexType::domTexture *tex, 994 const osg::StateSet* ss, TextureUnitUsage tuu, 995 domFx_opaque_enum opaque, float transparency) 996 { 997 TextureParameters parameters; 998 parameters.transparent = tuu == TRANSPARENCY_MAP_UNIT; 999 parameters.opaque = opaque; 1000 parameters.transparency = transparency; 1001 857 1002 //find the newparam for the sampler based on the texture attribute 858 1003 domFx_sampler2D_common *sampler = NULL; … … 863 1008 osg::notify(osg::NOTICE)<<"processTexture("<<target<<")"<<std::endl; 864 1009 865 daeSIDResolver res1( currentEffect, target.c_str() );1010 daeSIDResolver res1( _currentEffect, target.c_str() ); 866 1011 daeElement *el = res1.getElement(); 867 1012 868 if ( el == NULL )869 { 870 osg::notify( osg::WARN ) << "Could not locate newparam for texture sampler2D " << tex->getTexture() << std::endl;871 osg::notify( osg::WARN ) << "Checking if data does incorrect linking straight to the image" << std::endl;872 dae->getDatabase()->getElement( (daeElement**)&dImg, 0, tex->getTexture(), "image" );873 if ( dImg != NULL )1013 if (el == NULL ) 1014 { 1015 osg::notify( osg::WARN ) << "Could not locate newparam for texture sampler2D \"" << tex->getTexture() << 1016 "\". Checking if data does incorrect linking straight to the image" << std::endl; 1017 _dae->getDatabase()->getElement( (daeElement**)&dImg, 0, tex->getTexture(), "image" ); 1018 if (dImg != NULL ) 874 1019 { 875 1020 osg::notify( osg::WARN ) << "Direct image link found. Data is incorrect but will continue to load texture" << std::endl; … … 881 1026 domFx_newparam_common *npc = daeSafeCast< domFx_newparam_common >( el ); 882 1027 883 if ( cnp != NULL )1028 if (cnp != NULL ) 884 1029 { 885 1030 sampler = cnp->getSampler2D(); 886 1031 } 887 else if ( npc != NULL )1032 else if (npc != NULL ) 888 1033 { 889 1034 sampler = npc->getFx_basic_type_common()->getSampler2D(); 890 1035 } 891 1036 892 if ( sampler == NULL )1037 if (sampler == NULL ) 893 1038 { 894 1039 osg::notify( osg::WARN ) << "Wrong newparam type. Expected sampler2D" << std::endl; … … 898 1043 //find the newparam for the surface based on the sampler2D->source value 899 1044 target = std::string("./") + std::string( sampler->getSource()->getValue() ); 900 daeSIDResolver res2( currentEffect, target.c_str() );1045 daeSIDResolver res2( _currentEffect, target.c_str() ); 901 1046 el = res2.getElement(); 902 if ( el == NULL )1047 if (el == NULL ) 903 1048 { 904 1049 osg::notify( osg::WARN ) << "Could not locate newparam for source " << sampler->getSource()->getValue() << std::endl; … … 908 1053 npc = daeSafeCast< domFx_newparam_common >( el ); 909 1054 910 if ( cnp != NULL )1055 if (cnp != NULL ) 911 1056 { 912 1057 surface = cnp->getSurface(); 913 1058 } 914 else if ( npc != NULL )1059 else if (npc != NULL ) 915 1060 { 916 1061 surface = npc->getFx_basic_type_common()->getSurface(); 917 1062 } 918 1063 919 if ( surface == NULL )1064 if (surface == NULL ) 920 1065 { 921 1066 osg::notify( osg::WARN ) << "Wrong newparam type. Expected surface" << std::endl; … … 927 1072 dImg = daeSafeCast< domImage >( getElementFromIDRef( ref ) ); 928 1073 } 929 if ( dImg == NULL ) 930 { 931 osg::notify( osg::WARN ) << "Could not locate image for texture" << std::endl; 1074 1075 parameters.filename = processImagePath(dImg); 1076 if (parameters.filename.empty()) 1077 { 932 1078 return NULL; 933 1079 } 934 //Got a sampler and a surface and an imaged. Time to create the texture stuff for osg 935 osg::ref_ptr<osg::Image> img = NULL; 936 if ( dImg->getInit_from() != NULL ) 937 { 938 // daeURI uri = dImg->getInit_from()->getValue(); 939 dImg->getInit_from()->getValue().validate(); 940 if ( std::string( dImg->getInit_from()->getValue().getProtocol() ) == std::string( "file" ) ) 941 { 942 //unsigned int bufSize = 1; //for the null char 943 //bufSize += dImg->getInit_from()->getValue().pathDir().size(); 944 //bufSize += dImg->getInit_from()->getValue().pathFile().size(); 945 std::string path = dImg->getInit_from()->getValue().pathDir()+ 946 dImg->getInit_from()->getValue().pathFile(); 947 // remove space encodings 948 // 949 path = cdom::uriToNativePath(path); 950 if(path.empty()) 951 { 952 osg::notify( osg::WARN ) << "Unable to get path from URI." << std::endl; 953 return NULL; 954 } 955 #ifdef WIN32 956 // If the path has a drive specifier or a UNC name then strip the leading / 957 const char* filename =path.c_str(); 958 if ((path[2] == ':') || ((path[1] == '/') && (path[2] == '/'))) 959 ++filename;// = path+1; 960 // else 961 // filename = path; 962 #else 963 const char* filename = path.c_str(); 964 #endif 965 img = osgDB::readRefImageFile( filename ); 966 967 osg::notify(osg::INFO)<<" processTexture(..) - readImage("<<filename<<")"<<std::endl; 968 969 //Moved this below the osg::notify - Parag, 24/7/2007 970 //delete [] path; 971 972 973 } 974 else 975 { 976 osg::notify( osg::WARN ) << "Only images with a \"file\" scheme URI are supported in this version." << std::endl; 1080 1081 //set texture parameters 1082 if (sampler) 1083 { 1084 if (sampler->getWrap_s()) 1085 { 1086 parameters.wrap_s = getWrapMode(sampler->getWrap_s()->getValue()); 1087 } 1088 if (sampler->getWrap_t()) 1089 { 1090 parameters.wrap_t = getWrapMode(sampler->getWrap_s()->getValue()); 1091 } 1092 1093 if (sampler->getMinfilter()) 1094 { 1095 parameters.filter_min = getFilterMode(sampler->getMinfilter()->getValue(), true); 1096 } 1097 if (sampler->getMagfilter()) 1098 { 1099 parameters.filter_min = getFilterMode(sampler->getMagfilter()->getValue(), false); 1100 } 1101 1102 if (sampler->getBorder_color() != NULL ) 1103 { 1104 const domFloat4& col = sampler->getBorder_color()->getValue(); 1105 parameters.border.set(col[0], col[1], col[2], col[3]); 1106 } 1107 } 1108 1109 osg::Texture2D* t2D = NULL; 1110 TextureParametersMap::const_iterator mapIt = _textureParamMap.find(parameters); 1111 if (mapIt != _textureParamMap.end()) 1112 { 1113 t2D = mapIt->second.get(); 1114 } 1115 else 1116 { 1117 osg::ref_ptr<osg::Image> img = osgDB::readRefImageFile(parameters.filename); 1118 1119 if (!img.valid()) 1120 { 1121 _textureParamMap[parameters] = NULL; 977 1122 return NULL; 978 1123 } 979 } 980 else 981 { 982 osg::notify( osg::WARN ) << "Embedded image data is not supported in this version." << std::endl; 983 return NULL; 984 } 985 986 osg::Texture2D *t2D = new osg::Texture2D( img.get() ); 987 //set texture parameters 988 if ( sampler != NULL ) 989 { 990 if ( sampler->getWrap_s() != NULL ) 991 { 992 osg::Texture::WrapMode wrap; 993 switch( sampler->getWrap_s()->getValue() ) 994 { 995 case FX_SAMPLER_WRAP_COMMON_WRAP: 996 wrap = osg::Texture::REPEAT; 997 break; 998 case FX_SAMPLER_WRAP_COMMON_MIRROR: 999 wrap = osg::Texture::MIRROR; 1000 break; 1001 case FX_SAMPLER_WRAP_COMMON_CLAMP: 1002 wrap = osg::Texture::CLAMP_TO_EDGE; 1003 break; 1004 case FX_SAMPLER_WRAP_COMMON_NONE: 1005 case FX_SAMPLER_WRAP_COMMON_BORDER: 1006 wrap = osg::Texture::CLAMP_TO_BORDER; 1007 break; 1008 default: 1009 wrap = osg::Texture::CLAMP; 1010 break; 1011 } 1012 t2D->setWrap( osg::Texture::WRAP_S, wrap ); 1013 } 1014 else 1015 { 1016 t2D->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); 1017 } 1018 if ( sampler->getWrap_t() != NULL ) 1019 { 1020 osg::Texture::WrapMode wrap; 1021 switch( sampler->getWrap_t()->getValue() ) 1022 { 1023 case FX_SAMPLER_WRAP_COMMON_WRAP: 1024 wrap = osg::Texture::REPEAT; 1025 break; 1026 case FX_SAMPLER_WRAP_COMMON_MIRROR: 1027 wrap = osg::Texture::MIRROR; 1028 break; 1029 case FX_SAMPLER_WRAP_COMMON_CLAMP: 1030 wrap = osg::Texture::CLAMP_TO_EDGE; 1031 break; 1032 case FX_SAMPLER_WRAP_COMMON_NONE: 1033 case FX_SAMPLER_WRAP_COMMON_BORDER: 1034 wrap = osg::Texture::CLAMP_TO_BORDER; 1035 break; 1036 default: 1037 wrap = osg::Texture::CLAMP; 1038 break; 1039 } 1040 t2D->setWrap( osg::Texture::WRAP_T, wrap ); 1041 } 1042 else 1043 { 1044 t2D->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); 1045 } 1046 if ( sampler->getMinfilter() != NULL ) 1047 { 1048 osg::Texture::FilterMode mode; 1049 switch( sampler->getMinfilter()->getValue() ) 1050 { 1051 case FX_SAMPLER_FILTER_COMMON_NEAREST: 1052 mode = osg::Texture::NEAREST; 1053 break; 1054 case FX_SAMPLER_FILTER_COMMON_LINEAR: 1055 mode = osg::Texture::LINEAR; 1056 break; 1057 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 1058 mode = osg::Texture::NEAREST_MIPMAP_NEAREST; 1059 break; 1060 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 1061 mode = osg::Texture::LINEAR_MIPMAP_NEAREST; 1062 break; 1063 case FX_SAMPLER_FILTER_COMMON_NONE: 1064 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 1065 mode = osg::Texture::NEAREST_MIPMAP_LINEAR; 1066 break; 1067 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 1068 mode = osg::Texture::LINEAR_MIPMAP_LINEAR; 1069 break; 1070 default: 1071 mode = osg::Texture::LINEAR; 1072 break; 1073 } 1074 t2D->setFilter( osg::Texture::MIN_FILTER, mode ); 1075 } 1076 else 1077 { 1078 t2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_LINEAR ); 1079 } 1080 if ( sampler->getMagfilter() != NULL ) 1081 { 1082 osg::Texture::FilterMode mode; 1083 switch( sampler->getMagfilter()->getValue() ) 1084 { 1085 case FX_SAMPLER_FILTER_COMMON_NEAREST: 1086 mode = osg::Texture::NEAREST; 1087 break; 1088 case FX_SAMPLER_FILTER_COMMON_NONE: 1089 case FX_SAMPLER_FILTER_COMMON_LINEAR: 1090 mode = osg::Texture::LINEAR; 1091 break; 1092 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_NEAREST: 1093 mode = osg::Texture::NEAREST_MIPMAP_NEAREST; 1094 break; 1095 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_NEAREST: 1096 mode = osg::Texture::LINEAR_MIPMAP_NEAREST; 1097 break; 1098 case FX_SAMPLER_FILTER_COMMON_NEAREST_MIPMAP_LINEAR: 1099 mode = osg::Texture::NEAREST_MIPMAP_LINEAR; 1100 break; 1101 case FX_SAMPLER_FILTER_COMMON_LINEAR_MIPMAP_LINEAR: 1102 mode = osg::Texture::LINEAR_MIPMAP_LINEAR; 1103 break; 1104 default: 1105 mode = osg::Texture::LINEAR; 1106 break; 1107 } 1108 t2D->setFilter( osg::Texture::MAG_FILTER, mode ); 1109 } 1110 else 1111 { 1112 t2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); 1113 } 1114 if ( sampler->getBorder_color() != NULL ) 1115 { 1116 const domFloat4 &col = sampler->getBorder_color()->getValue(); 1117 t2D->setBorderColor( osg::Vec4( col[0], col[1], col[2], col[3] ) ); 1118 } 1119 } 1120 else 1121 { 1122 t2D->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); 1123 t2D->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); 1124 t2D->setFilter( osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_LINEAR ); 1125 t2D->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); 1126 } 1127 1128 // Store the texcoord name in the texture object 1129 t2D->setName(tex->getTexcoord()); 1124 1125 osg::notify(osg::INFO)<<" processTexture(..) - readImage("<<parameters.filename<<")"<<std::endl; 1126 1127 if (tuu == TRANSPARENCY_MAP_UNIT) 1128 { 1129 img = processImageTransparency(img.get(), opaque, transparency); 1130 } 1131 1132 t2D = new osg::Texture2D(img.get()); 1133 1134 t2D->setWrap( osg::Texture::WRAP_S, parameters.wrap_s); 1135 t2D->setWrap( osg::Texture::WRAP_T, parameters.wrap_t); 1136 t2D->setFilter( osg::Texture::MIN_FILTER, parameters.filter_min); 1137 t2D->setFilter( osg::Texture::MAG_FILTER, parameters.filter_mag); 1138 t2D->setBorderColor(parameters.border); 1139 1140 _textureParamMap[parameters] = t2D; 1141 } 1142 1143 _texCoordSetMap[TextureToCoordSetMap::key_type(ss, tuu)] = tex->getTexcoord(); 1144 1130 1145 return t2D; 1131 1146 } … … 1160 1175 xsNCName diffuseTextureName ) 1161 1176 { 1177 if (ss == NULL) 1178 return; 1179 1162 1180 if (NULL == ctt && NULL == pTransparency) 1163 1181 return; 1164 1182 1165 if (ctt && ctt->getTexture() != NULL) 1166 { 1167 if (!diffuseTextureName || (strcmp( ctt->getTexture()->getTexture(), diffuseTextureName))) 1168 { 1169 osg::notify( osg::WARN ) << "Currently no support for different textures in diffuse and transparent channels." << std::endl; 1170 return; 1171 } 1172 } 1173 1174 // Fix up defaults according to 1.4.1 release notes 1175 domFloat4 f4; 1176 domFx_opaque_enum Opaque = FX_OPAQUE_ENUM_A_ONE; 1177 if (NULL == ctt) 1178 { 1179 f4.append(0.0f); 1180 f4.append(0.0f); 1181 f4.append(0.0f); 1182 f4.append(1.0f); 1183 float transparency = 1.0f; 1184 if (pTransparency) 1185 { 1186 if (pTransparency->getFloat()) 1187 { 1188 transparency = pTransparency->getFloat()->getValue(); 1189 } 1190 else if (pTransparency->getParam()) 1191 { 1192 domFloat transparencyParam; 1193 if (GetFloatParam(pTransparency->getParam()->getRef(), transparencyParam)) 1194 { 1195 transparency = transparencyParam; 1196 } 1197 } 1198 1199 if (_invertTransparency) 1200 { 1201 transparency = 1.0f - transparency; 1202 } 1203 } 1204 1205 osg::Texture2D* pTransparentTexture = NULL; 1206 osg::Vec4 transparentColor(transparency, transparency, transparency, transparency); 1207 1208 // Fix up defaults according to "Determining Transparency" chapter of 1.4.1 spec 1209 domFx_opaque_enum opaque = FX_OPAQUE_ENUM_A_ONE; 1210 if (ctt) 1211 { 1212 opaque = ctt->getOpaque(); 1213 if (ctt->getColor()) 1214 { 1215 const domFx_color_common& domColorValue = ctt->getColor()->getValue(); 1216 transparentColor.set( 1217 domColorValue.get(0), 1218 domColorValue.get(1), 1219 domColorValue.get(2), 1220 domColorValue.get(3)); 1221 1222 if (opaque == FX_OPAQUE_ENUM_RGB_ZERO) 1223 { 1224 transparentColor.set( 1225 1.0f - transparentColor.r() * transparency, 1226 1.0f - transparentColor.g() * transparency, 1227 1.0f - transparentColor.b() * transparency, 1228 1.0f - luminance(transparentColor) * transparency); 1229 } 1230 else 1231 { 1232 float a = transparentColor.a() * transparency; 1233 transparentColor.set(a, a, a, a); 1234 } 1235 } 1236 else if (ctt->getTexture()) 1237 { 1238 pTransparentTexture = processTexture(ctt->getTexture(), ss, TRANSPARENCY_MAP_UNIT, opaque, transparency); 1239 } 1240 } 1241 1242 if (pTransparentTexture) 1243 { 1244 ss->setTextureAttributeAndModes(TRANSPARENCY_MAP_UNIT, pTransparentTexture); 1245 ss->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); 1183 1246 } 1184 1247 else 1185 1248 { 1186 Opaque = ctt->getOpaque(); 1187 if (NULL != ctt->getColor()) 1188 { 1189 f4 = ctt->getColor()->getValue(); 1190 } 1191 else if ((NULL == ctt->getParam()) || !GetFloat4Param(ctt->getParam()->getRef(), f4)) 1192 { 1193 f4.append(0.0f); 1194 f4.append(0.0f); 1195 f4.append(0.0f); 1196 f4.append(1.0f); 1197 } 1198 } 1199 1200 domFloat Transparency = 1.0f; 1201 if (NULL != pTransparency) 1202 { 1203 if (NULL != pTransparency->getFloat()) 1204 { 1205 Transparency = pTransparency->getFloat()->getValue(); 1206 if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support 1207 Transparency = 1.0f - Transparency; 1208 } 1209 else if (NULL != pTransparency->getParam()) 1210 { 1211 if (GetFloatParam(pTransparency->getParam()->getRef(), Transparency)) 1212 { 1213 if (m_AuthoringTool == GOOGLE_SKETCHUP) // Google back to front support 1214 Transparency = 1.0f - Transparency; 1215 } 1216 else 1217 Transparency = 1.0f; 1218 } 1219 } 1220 1221 if (NULL != ctt || NULL != pTransparency) 1222 { 1223 int SourceBlendFactor; 1224 int DestBlendFactor; 1225 bool SwitchOnTheBlender = false; 1226 if (m_StrictTransparency) 1227 { 1228 // Process transparent and transparency settings accroding to a strict interpretation of the spec 1229 // See https://collada.org/public_forum/viewtopic.php?f=12&t=1210 1230 SwitchOnTheBlender = true; 1231 switch(Opaque) 1232 { 1233 /* 1234 case FX_OPAQUE_ENUM_RGB_ONE: 1235 if (ctt->getTexture() != NULL) 1236 { 1237 SourceBlendFactor = GL_SRC_COLOR; 1238 DestBlendFactor = GL_ONE_MINUS_SRC_COLOR; 1239 } 1240 else 1241 { 1242 SourceBlendFactor = GL_CONSTANT_COLOR; 1243 DestBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 1244 } 1245 break; 1246 case FX_OPAQUE_ALPHA_ZERO: 1247 if (ctt->getTexture() != NULL) 1248 { 1249 SourceBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 1250 DestBlendFactor = GL_SRC_ALPHA; 1251 } 1252 else 1253 { 1254 SourceBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 1255 DestBlendFactor = GL_CONSTANT_ALPHA; 1256 } 1257 break; 1258 */ 1259 case FX_OPAQUE_ENUM_RGB_ZERO: 1260 if (ctt->getTexture() != NULL) 1261 { 1262 SourceBlendFactor = GL_ONE_MINUS_SRC_COLOR; 1263 DestBlendFactor = GL_SRC_COLOR; 1264 } 1265 else 1266 { 1267 SourceBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 1268 DestBlendFactor = GL_CONSTANT_COLOR; 1269 } 1270 break; 1271 default: 1272 if (ctt->getTexture() != NULL) 1273 { 1274 SourceBlendFactor = GL_SRC_ALPHA; 1275 DestBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 1276 } 1277 else 1278 { 1279 SourceBlendFactor = GL_CONSTANT_ALPHA; 1280 DestBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 1281 } 1282 break; 1283 } 1249 bool strictTransparency = _strictTransparency; 1250 if (!strictTransparency) 1251 { 1252 const osg::Texture* pMainTexture = dynamic_cast<osg::Texture*>( 1253 ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE)); 1254 bool haveTranslucentTexture = pMainTexture && 1255 pMainTexture->getImage(0) && pMainTexture->getImage(0)->isImageTranslucent(); 1256 strictTransparency = !haveTranslucentTexture; 1257 } 1258 1259 if (strictTransparency) 1260 { 1261 if (transparentColor == osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)) 1262 { 1263 return; 1264 } 1265 1266 ss->setAttributeAndModes(new osg::BlendColor(transparentColor)); 1267 ss->setAttributeAndModes(new osg::BlendFunc(GL_CONSTANT_COLOR, GL_ONE_MINUS_CONSTANT_COLOR)); 1284 1268 } 1285 1269 else 1286 1270 { 1287 // Jump through various hoops to accomodate the multiplicity of different ways 1288 // that various people have interpreted the specification 1289 // I assume that the presence of either a <tansparent> or a <transparency> element 1290 // means that the user may want some kind of alpha blending 1291 bool HaveDiffuseTexture = false; 1292 bool HaveTranslucentDiffuseTexture = false; 1293 // Unfortunately isImageTransparent only works for A_ONE_OPAQUE 1294 if ((NULL != ss) && 1295 (HaveDiffuseTexture = (GL_TRUE == ss->getTextureMode(MAIN_TEXTURE_UNIT, GL_TEXTURE_2D))) && 1296 (NULL != dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))) && 1297 (NULL != dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))->getImage()) && 1298 (dynamic_cast<osg::Texture2D*>(ss->getTextureAttribute(MAIN_TEXTURE_UNIT, osg::StateAttribute::TEXTURE))->getImage()->isImageTranslucent())) 1299 HaveTranslucentDiffuseTexture = true; 1300 osg::Vec4 Diffuse; 1301 if (material) 1302 Diffuse = material->getDiffuse(osg::Material::FRONT_AND_BACK); 1303 1304 // Determine whether or not to switch on the blender and which blending factors to use. 1305 // I switch the blender on if the supplied (or default) <transparent> and <transparency> elements work out as non opaque, 1306 // or if they work out opaque and I have a translucent texture in the MAIN_TEXTURE_UNIT or a non opaque value in the diffuse colour 1307 switch(Opaque) 1308 { 1309 /* 1310 case FX_OPAQUE_ENUM_RGB_ONE: 1311 if ((Transparency * f4[0] > 0.99f) && 1312 (Transparency * f4[1] > 0.99f) && 1313 (Transparency * f4[2] > 0.99f)) 1314 { 1315 SourceBlendFactor = GL_SRC_COLOR; 1316 DestBlendFactor = GL_ONE_MINUS_SRC_COLOR; 1317 // It would be nice to check for a translucent texture here as well 1318 if (!HaveDiffuseTexture && (Diffuse.r() < 0.99f) && (Diffuse.g() < 0.99f) && (Diffuse.b() < 0.99f)) 1319 SwitchOnTheBlender = true; 1320 } 1321 else 1322 { 1323 SourceBlendFactor = GL_CONSTANT_COLOR; 1324 DestBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 1325 SwitchOnTheBlender = true; 1326 } 1327 break; 1328 case FX_OPAQUE_ALPHA_ZERO: 1329 if (Transparency * f4[3] < 0.01f) 1330 { 1331 SourceBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 1332 DestBlendFactor = GL_SRC_ALPHA; 1333 // It would be nice to check for a translucent texture here as well 1334 if (Diffuse.a() > 0.01f) 1335 SwitchOnTheBlender = true; 1336 } 1337 else 1338 { 1339 SourceBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 1340 DestBlendFactor = GL_CONSTANT_ALPHA; 1341 SwitchOnTheBlender = true; 1342 } 1343 break; 1344 */ 1345 case FX_OPAQUE_ENUM_RGB_ZERO: 1346 if ((Transparency * f4[0] < 0.01f) && 1347 (Transparency * f4[1] < 0.01f) && 1348 (Transparency * f4[2] < 0.01f)) 1349 { 1350 SourceBlendFactor = GL_ONE_MINUS_SRC_COLOR; 1351 DestBlendFactor = GL_SRC_COLOR; 1352 // It would be nice to check for a translucent texture here as well 1353 // if (!HaveDiffuseTexture && (Diffuse.r() > 0.01f) && (Diffuse.g() > 0.01f) && (Diffuse.b() > 0.01f)) 1354 // SwitchOnTheBlender = true; 1355 } 1356 else 1357 { 1358 SourceBlendFactor = GL_ONE_MINUS_CONSTANT_COLOR; 1359 DestBlendFactor = GL_CONSTANT_COLOR; 1360 SwitchOnTheBlender = true; 1361 } 1362 break; 1363 default: 1364 if (Transparency * f4[3] > 0.99f) 1365 { 1366 SourceBlendFactor = GL_SRC_ALPHA; 1367 DestBlendFactor = GL_ONE_MINUS_SRC_ALPHA; 1368 if (HaveTranslucentDiffuseTexture || (Diffuse.a() < 0.99f)) 1369 SwitchOnTheBlender = true; 1370 } 1371 else 1372 { 1373 SourceBlendFactor = GL_CONSTANT_ALPHA; 1374 DestBlendFactor = GL_ONE_MINUS_CONSTANT_ALPHA; 1375 SwitchOnTheBlender = true; 1376 } 1377 break; 1378 } 1379 } 1380 if (SwitchOnTheBlender) 1381 { 1382 if ((SourceBlendFactor == GL_CONSTANT_COLOR) || 1383 (SourceBlendFactor == GL_ONE_MINUS_CONSTANT_COLOR) || 1384 (SourceBlendFactor == GL_CONSTANT_ALPHA) || 1385 (SourceBlendFactor == GL_ONE_MINUS_CONSTANT_ALPHA)) 1386 { 1387 osg::BlendColor *bc = new osg::BlendColor(); 1388 bc->setConstantColor(osg::Vec4( f4[0] * Transparency, f4[1] * Transparency, f4[2] * Transparency, f4[3] * Transparency )); 1389 ss->setAttribute( bc ); 1390 } 1391 osg::BlendFunc *bf = new osg::BlendFunc(SourceBlendFactor, DestBlendFactor); 1392 ss->setAttribute( bf ); 1393 ss->setMode( GL_BLEND, osg::StateAttribute::ON ); 1394 1395 ss->setRenderingHint( osg::StateSet::TRANSPARENT_BIN ); 1396 } 1397 } 1398 } 1271 ss->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)); 1272 } 1273 } 1274 1275 ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN); 1276 } 1277 1278 void daeReader::copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage tuu) 1279 { 1280 if (!ss->getTextureAttribute(tuu, osg::StateAttribute::TEXTURE)) 1281 return; 1282 1283 const std::string& texCoordSetName = _texCoordSetMap 1284 [TextureToCoordSetMap::key_type(ss, tuu)]; 1285 if (!texCoordSetName.empty()) 1286 { 1287 const domInstance_material::domBind_vertex_input_Array &bvia = im->getBind_vertex_input_array(); 1288 size_t k; 1289 for (k = 0; k < bvia.getCount(); k++) 1290 { 1291 if (!strcmp(bvia[k]->getSemantic(), texCoordSetName.c_str()) && !strcmp(bvia[k]->getInput_semantic(), COMMON_PROFILE_INPUT_TEXCOORD)) 1292 { 1293 unsigned set = bvia[k]->getInput_set(); 1294 if (set < cachedGeometry->getNumTexCoordArrays()) 1295 { 1296 clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(set)); 1297 } 1298 else 1299 { 1300 osg::notify(osg::WARN) << "Texture coordinate set " << set << " not found." << std::endl; 1301 } 1302 break; 1303 } 1304 } 1305 if (k == bvia.getCount()) 1306 { 1307 osg::notify( osg::WARN ) << "Failed to find matching <bind_vertex_input> for " << texCoordSetName << std::endl; 1308 if (cachedGeometry->getNumTexCoordArrays()) 1309 { 1310 clonedGeometry->setTexCoordData(tuu, cachedGeometry->getTexCoordData(0)); 1311 } 1312 } 1313 } 1314 } -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeRSceneObjects.cpp
r10234 r11129 28 28 #include <osg/LightModel> 29 29 30 using namespace osg dae;31 32 osg:: Node* daeReader::processOsgMultiSwitch(domTechnique* teq)30 using namespace osgDAE; 31 32 osg::Group* daeReader::processOsgMultiSwitch(domTechnique* teq) 33 33 { 34 34 osgSim::MultiSwitch* msw = new osgSim::MultiSwitch; … … 87 87 } 88 88 89 osg:: Node* daeReader::processOsgSwitch(domTechnique* teq)89 osg::Group* daeReader::processOsgSwitch(domTechnique* teq) 90 90 { 91 91 osg::Switch* sw = new osg::Switch; … … 113 113 } 114 114 115 osg:: Node* daeReader::processOsgSequence(domTechnique* teq)115 osg::Group* daeReader::processOsgSequence(domTechnique* teq) 116 116 { 117 117 osg::Sequence* sq = new osg::Sequence; … … 220 220 221 221 222 osg:: Node* daeReader::processOsgLOD(domTechnique* teq)222 osg::Group* daeReader::processOsgLOD(domTechnique* teq) 223 223 { 224 224 osg::LOD* lod = new osg::LOD; … … 324 324 osg::Node* daeReader::processLight( domLight *dlight ) 325 325 { 326 if ( m_numlights >= 7)326 if (_numlights >= 7) 327 327 { 328 328 osg::notify( osg::WARN ) << "More than 8 lights may not be supported by OpenGL driver." << std::endl; … … 344 344 osg::Light* light = new osg::Light(); 345 345 light->setPosition(osg::Vec4(0,0,0,1)); 346 light->setLightNum( m_numlights);346 light->setLightNum(_numlights); 347 347 348 348 // Enable OpenGL lighting 349 349 _rootStateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON); 350 350 // Enable this OpenGL light 351 _rootStateSet->setMode(GL_LIGHT0 + m_numlights++, osg::StateAttribute::ON);351 _rootStateSet->setMode(GL_LIGHT0 + _numlights++, osg::StateAttribute::ON); 352 352 353 353 // Set ambient of lightmodel to zero -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeRTransforms.cpp
r9228 r11129 2 2 * Copyright 2006 Sony Computer Entertainment Inc. 3 3 * 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 5 5 * file except in compliance with the License. You may obtain a copy of the License at: 6 6 * http://research.scea.com/scea_shared_source_license.html 7 7 * 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 12 12 */ 13 13 … … 17 17 #include <dom/domCOLLADA.h> 18 18 19 #include <osgAnimation/UpdateMatrixTransform> 20 #include <osgAnimation/StackedMatrixElement> 21 #include <osgAnimation/StackedRotateAxisElement> 22 #include <osgAnimation/StackedScaleElement> 23 #include <osgAnimation/StackedTranslateElement> 19 24 #include <osg/MatrixTransform> 20 25 #include <osgSim/DOFTransform> 21 26 22 using namespace osg dae;27 using namespace osgDAE; 23 28 24 29 // Note <lookat>, <matrix>, <rotate>, <scale>, <skew> and <translate> may appear in any order 25 30 // These transformations can be combined in any number and ordering to produce the desired 26 // coordinate system for the parent <node> element. The COLLADA specificatin requires that the27 // transformation elements are processed in order and accumulate the result as if they were 31 // coordinate system for the parent <node> element. The COLLADA specificatin requires that the 32 // transformation elements are processed in order and accumulate the result as if they were 28 33 // converted to column-order matrices and concatenated using matrix post-multiplication. 29 osg:: Node* daeReader::processOsgMatrixTransform( domNode *node)34 osg::Transform* daeReader::processOsgMatrixTransform(domNode *node, bool isBone) 30 35 { 31 osg::MatrixTransform* matNode = new osg::MatrixTransform; 32 osg::Matrix matrix; 36 osg::MatrixTransform* resultNode = NULL; 37 38 if (isBone) 39 { 40 resultNode = getOrCreateBone(node); 41 } 42 else 43 { 44 resultNode = new osg::MatrixTransform; 45 } 46 47 osg::NodeCallback* pNodeCallback = resultNode->getUpdateCallback(); 48 std::vector<osg::ref_ptr<osgAnimation::StackedTransformElement> > transformElements; 49 osg::ref_ptr<osgAnimation::StackedTransformElement> pLastStaticTransformElement; 33 50 34 51 // Process all coordinate system contributing elements in order! 35 52 size_t count = node->getContents().getCount(); 36 for (size_t i = 0; i < count; i++ ) 37 { 38 domRotate * rot = daeSafeCast< domRotate >( node->getContents()[i] ); 39 if (rot) 40 { 41 domFloat4& r = rot->getValue(); 42 if (r.getCount() != 4 ) 43 { 44 osg::notify(osg::WARN)<<"Data is wrong size for rotate"<<std::endl; 45 continue; 46 } 47 48 // Build rotation matrix 49 osg::Matrix rotMat; 50 rotMat.makeRotate(osg::DegreesToRadians(r[3]), r[0], r[1], r[2]); 51 52 matrix = rotMat * matrix; 53 continue; 54 } 55 56 domTranslate * trans = daeSafeCast< domTranslate >( node->getContents()[i] ); 57 if (trans != NULL) 58 { 59 domFloat3& t = trans->getValue(); 60 if (t.getCount() != 3 ) 53 for (size_t i = 0; i < count; i++ ) 54 { 55 daeElement* pDaeElement = node->getContents()[i]; 56 osg::ref_ptr<osgAnimation::StackedTransformElement> pTransformElement = NULL; 57 58 if (domRotate * pDomRotate = daeSafeCast< domRotate >( pDaeElement )) 59 { 60 const domFloat4& r = pDomRotate->getValue(); 61 if (r.getCount() != 4 ) 62 { 63 osg::notify(osg::WARN) << "Data is wrong size for rotate" << std::endl; 64 continue; 65 } 66 67 pTransformElement = new osgAnimation::StackedRotateAxisElement(pDomRotate->getSid() ? pDomRotate->getSid() : "", osg::Vec3(r[0], r[1], r[2]), osg::DegreesToRadians(r[3])); 68 } 69 else if (domTranslate * pDomTranslate = daeSafeCast< domTranslate >( pDaeElement )) 70 { 71 const domFloat3& t = pDomTranslate->getValue(); 72 if (t.getCount() != 3 ) 61 73 { 62 74 osg::notify(osg::WARN)<<"Data is wrong size for translate"<<std::endl; … … 64 76 } 65 77 66 // Build translation matrix 67 osg::Matrix transMat; 68 transMat.makeTranslate(t[0], t[1], t[2]); 69 70 matrix = transMat * matrix; 71 continue; 72 } 73 74 domScale * scale = daeSafeCast< domScale >( node->getContents()[i] ); 75 if (scale != NULL) 76 { 77 domFloat3& s = scale->getValue(); 78 if (s.getCount() != 3 ) 78 pTransformElement = new osgAnimation::StackedTranslateElement(pDomTranslate->getSid() ? pDomTranslate->getSid() : "", osg::Vec3(t[0], t[1], t[2])); 79 } 80 else if (domScale * pDomScale = daeSafeCast< domScale >( pDaeElement )) 81 { 82 const domFloat3& s = pDomScale->getValue(); 83 if (s.getCount() != 3 ) 79 84 { 80 85 osg::notify(osg::WARN)<<"Data is wrong size for scale"<<std::endl; … … 82 87 } 83 88 84 // Build scale matrix 85 osg::Matrix scaleMat; 86 scaleMat.makeScale(s[0], s[1], s[2]); 87 88 matrix = scaleMat * matrix; 89 continue; 90 } 91 92 domMatrix * mat = daeSafeCast< domMatrix >( node->getContents()[i] ); 93 if (mat != NULL) 94 { 95 if (mat->getValue().getCount() != 16 ) 89 pTransformElement = new osgAnimation::StackedScaleElement(pDomScale->getSid() ? pDomScale->getSid() : "", osg::Vec3(s[0], s[1], s[2])); 90 } 91 else if (domMatrix * pDomMatrix = daeSafeCast< domMatrix >( pDaeElement )) 92 { 93 if (pDomMatrix->getValue().getCount() != 16 ) 96 94 { 97 95 osg::notify(osg::WARN)<<"Data is wrong size for matrix"<<std::endl; … … 99 97 } 100 98 101 // Build matrix 102 osg::Matrix mMat( mat->getValue()[0], mat->getValue()[4], mat->getValue()[8], mat->getValue()[12], 103 mat->getValue()[1], mat->getValue()[5], mat->getValue()[9], mat->getValue()[13], 104 mat->getValue()[2], mat->getValue()[6], mat->getValue()[10], mat->getValue()[14], 105 mat->getValue()[3], mat->getValue()[7], mat->getValue()[11], mat->getValue()[15] ); 106 107 matrix = mMat * matrix; 108 continue; 109 } 110 111 domLookat * la = daeSafeCast< domLookat >( node->getContents()[i] ); 112 if (la != NULL) 113 { 114 if (la->getValue().getCount() != 9 ) 99 pTransformElement = new osgAnimation::StackedMatrixElement(pDomMatrix->getSid() ? pDomMatrix->getSid() : "", 100 osg::Matrix( pDomMatrix->getValue()[0], pDomMatrix->getValue()[4], pDomMatrix->getValue()[8], pDomMatrix->getValue()[12], 101 pDomMatrix->getValue()[1], pDomMatrix->getValue()[5], pDomMatrix->getValue()[9], pDomMatrix->getValue()[13], 102 pDomMatrix->getValue()[2], pDomMatrix->getValue()[6], pDomMatrix->getValue()[10], pDomMatrix->getValue()[14], 103 pDomMatrix->getValue()[3], pDomMatrix->getValue()[7], pDomMatrix->getValue()[11], pDomMatrix->getValue()[15])); 104 } 105 else if (domLookat * pDomLookat = daeSafeCast< domLookat >( pDaeElement )) 106 { 107 if (pDomLookat->getValue().getCount() != 9 ) 115 108 { 116 109 osg::notify(osg::WARN)<<"Data is wrong size for lookat"<<std::endl; … … 118 111 } 119 112 120 // Build lookat matrix 121 osg::Matrix lookatMat; 122 osg::Vec3 eye(la->getValue()[0], la->getValue()[1], la->getValue()[2]); 123 osg::Vec3 center(la->getValue()[3], la->getValue()[4], la->getValue()[5] ); 124 osg::Vec3 up( la->getValue()[6], la->getValue()[7], la->getValue()[8] ); 125 lookatMat.makeLookAt( eye, center, up ); 126 127 matrix = lookatMat * matrix; 128 continue; 129 } 130 131 domSkew * skew = daeSafeCast< domSkew >( node->getContents()[i] ); 132 if (skew != NULL) 133 { 134 if (skew->getValue().getCount() != 7 ) 113 pTransformElement = new osgAnimation::StackedMatrixElement(pDomLookat->getSid() ? pDomLookat->getSid() : "", 114 osg::Matrix::lookAt( 115 osg::Vec3(pDomLookat->getValue()[0], pDomLookat->getValue()[1], pDomLookat->getValue()[2]), 116 osg::Vec3(pDomLookat->getValue()[3], pDomLookat->getValue()[4], pDomLookat->getValue()[5]), 117 osg::Vec3(pDomLookat->getValue()[6], pDomLookat->getValue()[7], pDomLookat->getValue()[8]))); 118 } 119 else if (domSkew * pDomSkew = daeSafeCast< domSkew >( pDaeElement )) 120 { 121 if (pDomSkew->getValue().getCount() != 7 ) 135 122 { 136 123 osg::notify(osg::WARN)<<"Data is wrong size for skew"<<std::endl; … … 138 125 } 139 126 140 // Skew matrix building derived from GNURealistic ShaderMan GMANMatrix4 (LGPL) matrix class 141 142 // Build skew matrix 143 domFloat7& s = skew->getValue(); 127 const domFloat7& s = pDomSkew->getValue(); 144 128 145 129 float shear = sin(osg::DegreesToRadians(s[0])); … … 149 133 osg::Vec3f along(s[4],s[5],s[6]); 150 134 151 along.normalize(); 152 osg::Vec3f a = around - (along * (around * along)); 153 a.normalize(); 154 155 float an1 = around * a; 156 float an2 = around * along; 157 158 float rx = an1 * cos(shear) - an2 * sin(shear); 159 float ry = an1 * sin(shear) + an2 * cos(shear); 160 161 if (rx <= 0.0) 162 { 163 osg::notify(osg::WARN)<<"skew angle too large"<<std::endl; 164 continue; 165 } 166 167 float alpha; 168 // A parallel to B?? 169 if (an1==0) 170 { 171 alpha=0; 172 } 173 else 174 { 175 alpha=ry/rx-an2/an1; 176 } 177 178 179 osg::Matrix skewMat(a.x()*along.x()*alpha+1.0, a.x()*along.y()*alpha, a.x()*along.z()*alpha, 0, 180 a.y()*along.x()*alpha, a.y()*along.y()*alpha+1.0, a.y()*along.z()*alpha, 0, 181 a.z()*along.x()*alpha, a.z()*along.y()*alpha, a.z()*along.z()*alpha+1.0, 0, 182 0, 0, 0, 1); 183 184 185 matrix = skewMat * matrix; 186 continue; 187 } 188 } 189 190 matNode->setMatrix(matrix); 135 //This maths is untested so may be transposed or negated or just completely wrong. 136 osg::Vec3f normal = along ^ around; 137 normal.normalize(); 138 around.normalize(); 139 along *= shear / along.length(); 140 141 pTransformElement = new osgAnimation::StackedMatrixElement(pDomLookat->getSid() ? pDomLookat->getSid() : "", 142 osg::Matrix( 143 normal.x() * along.x() + 1.0f, normal.x() * along.y(), normal.x() * along.z(), 0.0f, 144 normal.y() * along.x(), normal.y() * along.y() + 1.0f, normal.y() * along.z(), 0.0f, 145 normal.z() * along.x(), normal.z() * along.y(), normal.z() * along.z() + 1.0f, 0.0f, 146 0.0f, 0.0f, 0.0f, 1.0f)); 147 } 148 149 if (pTransformElement) 150 { 151 daeElementDomChannelMap::iterator iter = _daeElementDomChannelMap.find(pDaeElement); 152 if (iter != _daeElementDomChannelMap.end()) 153 { 154 // The element is animated 155 156 // First add single or collapsed transform element if any 157 if (pLastStaticTransformElement) 158 { 159 transformElements.push_back(pLastStaticTransformElement); 160 pLastStaticTransformElement = NULL; 161 } 162 transformElements.push_back(pTransformElement); 163 164 // Animated element so we need an AnimationUpdateCallback 165 if (!pNodeCallback) 166 { 167 std::string name = node->getId() ? node->getId() : node->getSid() ? node->getSid() : ""; 168 resultNode->setDataVariance(osg::Object::DYNAMIC); 169 170 pNodeCallback = new osgAnimation::UpdateMatrixTransform(name); 171 resultNode->setUpdateCallback(pNodeCallback); 172 } 173 174 do 175 { 176 _domChannelOsgAnimationUpdateCallbackMap[iter->second] = pNodeCallback; 177 ++iter; 178 } while (iter != _daeElementDomChannelMap.end() && iter->first == pDaeElement); 179 } 180 else if (pLastStaticTransformElement) 181 { 182 // Add transform element only if not identity 183 if (!pTransformElement->isIdentity()) 184 { 185 // Collapse static transform elements 186 osg::Matrix matrix = pLastStaticTransformElement->getAsMatrix(); 187 pTransformElement->applyToMatrix(matrix); 188 pLastStaticTransformElement = new osgAnimation::StackedMatrixElement("collapsed", matrix); 189 } 190 } 191 else if (!pTransformElement->isIdentity()) 192 { 193 // Store single static transform element only if not identity 194 pLastStaticTransformElement = pTransformElement; 195 } 196 } 197 } 198 199 // Add final collapsed element (if any) 200 if (pLastStaticTransformElement) 201 { 202 transformElements.push_back(pLastStaticTransformElement); 203 } 204 205 // Build a matrix for the MatrixTransform and add the elements to the updateCallback 206 osg::Matrix matrix; 207 208 osgAnimation::UpdateMatrixTransform* pUpdateStackedTransform = 209 dynamic_cast<osgAnimation::UpdateMatrixTransform*>(pNodeCallback); 210 211 for (size_t i=0; i < transformElements.size(); i++) 212 { 213 transformElements[i]->applyToMatrix(matrix); 214 if (pUpdateStackedTransform) 215 { 216 pUpdateStackedTransform->getStackedTransforms().push_back(transformElements[i].get()); 217 } 218 } 219 220 resultNode->setMatrix(matrix); 191 221 192 222 osg::Vec3 scale = matrix.getScale(); 193 223 if ((scale.x() != 1) || (scale.y() != 1) || (scale.z() != 1)) 194 224 { 195 osg::StateSet* ss = matNode->getOrCreateStateSet();225 osg::StateSet* ss = resultNode->getOrCreateStateSet(); 196 226 ss->setMode(GL_RESCALE_NORMAL, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE); 197 227 } 198 228 199 return matNode;229 return resultNode; 200 230 } 201 231 202 osg:: Node* daeReader::processOsgDOFTransform(domTechnique* teq)232 osg::Group* daeReader::processOsgDOFTransform(domTechnique* teq) 203 233 { 204 234 osgSim::DOFTransform* dof = new osgSim::DOFTransform; -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeReader.cpp
r10351 r11129 19 19 #include <dom/domConstants.h> 20 20 #include <osg/MatrixTransform> 21 22 using namespace osgdae; 23 24 daeReader::daeReader(DAE *dae_, bool strictTransparency) : 25 m_AssetUnitName("meter"), 26 m_AssetUnitMeter(1.0), 27 m_AssetUp_axis(UPAXISTYPE_Y_UP), 28 dae(dae_), 29 rootNode(NULL), 30 m_numlights(0), 31 currentInstance_effect(NULL), 32 currentEffect(NULL), 33 m_AuthoringTool(UNKNOWN), 34 m_StrictTransparency(strictTransparency) 21 #include <osg/PositionAttitudeTransform> 22 23 using namespace osgDAE; 24 25 daeReader::daeReader(DAE *dae_, bool strictTransparency) : 26 _dae(dae_), 27 _rootNode(NULL), 28 _visualScene(NULL), 29 _numlights(0), 30 _currentInstance_effect(NULL), 31 _currentEffect(NULL), 32 _authoringTool(UNKNOWN), 33 _strictTransparency(strictTransparency), 34 _invertTransparency(false), 35 _assetUnitName("meter"), 36 _assetUnitMeter(1.0), 37 _assetUp_axis(UPAXISTYPE_Y_UP) 35 38 { 36 39 } … … 42 45 bool daeReader::convert( const std::string &fileURI ) 43 46 { 47 // Clear caches 48 _geometryMap.clear(); 49 _materialMap.clear(); 50 _materialMap2.clear(); 51 44 52 daeElement *colladaElement; 45 domInstance_rigid_body *irb;53 46 54 47 55 daeInt count, result; 48 56 49 daeInt res = dae->load( fileURI.c_str());57 _document = _dae->open(fileURI); 50 58 51 if ( res != DAE_OK && res != DAE_ERR_COLLECTION_ALREADY_EXISTS)59 if (!_document) 52 60 { 53 61 osg::notify( osg::WARN ) << "Load failed in COLLADA DOM" << std::endl; … … 56 64 osg::notify( osg::INFO ) << "URI loaded: " << fileURI << std::endl; 57 65 58 domCOLLADA* document = dae->getDom( fileURI.c_str() ); 59 60 if ( !document->getScene() || !document->getScene()->getInstance_visual_scene() ) 66 if ( !_document->getScene() || !_document->getScene()->getInstance_visual_scene() ) 61 67 { 62 68 osg::notify( osg::WARN ) << "No scene found!" << std::endl; … … 64 70 } 65 71 66 if ( document->getAsset())67 { 68 const domAsset::domContributor_Array& ContributorArray = document->getAsset()->getContributor_array();72 if (_document->getAsset()) 73 { 74 const domAsset::domContributor_Array& ContributorArray = _document->getAsset()->getContributor_array(); 69 75 size_t NumberOfContributors = ContributorArray.getCount(); 70 76 size_t CurrentContributor; … … 73 79 if (ContributorArray[CurrentContributor]->getAuthoring_tool()) 74 80 { 81 const char szBlender[] = "Blender"; 82 const char szDazStudio[] = "DAZ|Studio"; 83 const char szSketchup[] = "Google SketchUp"; 84 const char szFbx[] = "FBX"; 85 const char szMaya[] = "Maya"; 86 75 87 xsString Tool = ContributorArray[CurrentContributor]->getAuthoring_tool()->getValue(); 76 if (strncmp(Tool, "Google SketchUp", 15) == 0) 77 m_AuthoringTool = GOOGLE_SKETCHUP; 78 } 79 } 80 if (document->getAsset()->getUnit()) 81 { 82 if (NULL != document->getAsset()->getUnit()->getName()) 83 m_AssetUnitName = std::string(document->getAsset()->getUnit()->getName()); 84 if (0 != document->getAsset()->getUnit()->getMeter()) 85 m_AssetUnitMeter = document->getAsset()->getUnit()->getMeter(); 86 } 87 if (document->getAsset()->getUp_axis()) 88 m_AssetUp_axis = document->getAsset()->getUp_axis()->getValue(); 89 } 90 91 if (dae->getDatabase()) 92 { 93 count = dae->getDatabase()->getElementCount(NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY, NULL); 88 89 if (strncmp(Tool, szBlender, strlen(szBlender)) == 0) 90 _authoringTool = BLENDER; 91 else if (strncmp(Tool, szDazStudio, strlen(szDazStudio)) == 0) 92 _authoringTool = DAZ_STUDIO; 93 else if (strncmp(Tool, szFbx, strlen(szFbx)) == 0) 94 _authoringTool = FBX_CONVERTER; 95 else if (strncmp(Tool, szSketchup, strlen(szSketchup)) == 0) 96 _authoringTool = GOOGLE_SKETCHUP; 97 else if (strncmp(Tool, szMaya, strlen(szMaya)) == 0) 98 _authoringTool = MAYA; 99 } 100 } 101 if (_document->getAsset()->getUnit()) 102 { 103 if (NULL != _document->getAsset()->getUnit()->getName()) 104 _assetUnitName = std::string(_document->getAsset()->getUnit()->getName()); 105 if (0 != _document->getAsset()->getUnit()->getMeter()) 106 _assetUnitMeter = _document->getAsset()->getUnit()->getMeter(); 107 } 108 if (_document->getAsset()->getUp_axis()) 109 _assetUp_axis = _document->getAsset()->getUp_axis()->getValue(); 110 } 111 112 domInstanceWithExtra *ivs = _document->getScene()->getInstance_visual_scene(); 113 _visualScene = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) ); 114 if ( _visualScene == NULL ) 115 { 116 osg::notify( osg::WARN ) << "Unable to locate visual scene!" << std::endl; 117 return false; 118 } 119 120 if (daeDatabase* database = _dae->getDatabase()) 121 { 122 _invertTransparency = findInvertTransparency(database); 94 123 95 124 // build a std::map for lookup if Group or PositionAttitudeTransform should be created, 96 125 // i.e, make it easy to check if a instance_rigid_body targets a visual node 126 domInstance_rigid_body *pDomInstanceRigidBody; 127 count = database->getElementCount(NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY, NULL); 97 128 for (int i=0; i<count; i++) 98 129 { 99 result = da e->getDatabase()->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY);130 result = database->getElement(&colladaElement, i, NULL, COLLADA_TYPE_INSTANCE_RIGID_BODY); 100 131 101 132 if (result == DAE_OK) 102 133 { 103 irb= daeSafeCast<domInstance_rigid_body>(colladaElement);104 if ( irb)105 { 106 domNode *node = daeSafeCast<domNode>( irb->getTarget().getElement());134 pDomInstanceRigidBody = daeSafeCast<domInstance_rigid_body>(colladaElement); 135 if (pDomInstanceRigidBody) 136 { 137 domNode *node = daeSafeCast<domNode>(pDomInstanceRigidBody->getTarget().getElement()); 107 138 if (node && node->getId()) 108 139 { … … 112 143 } 113 144 } 114 } 115 116 domInstanceWithExtra *ivs = document->getScene()->getInstance_visual_scene(); 117 domVisual_scene *vs = daeSafeCast< domVisual_scene >( getElementFromURI( ivs->getUrl() ) ); 118 if ( vs == NULL ) 119 { 120 osg::notify( osg::WARN ) << "Unable to locate visual scene!" << std::endl; 121 return false; 122 } 123 rootNode = processVisualScene( vs ); 124 145 146 // Build a map of elements that are targetted by animations 147 count = database->getElementCount(NULL, COLLADA_TYPE_CHANNEL, NULL); 148 for (int i=0; i<count; i++) 149 { 150 result = database->getElement(&colladaElement, i, NULL, COLLADA_TYPE_CHANNEL); 151 152 if (result == DAE_OK) 153 { 154 domChannel* pDomChannel = daeSafeCast<domChannel>(colladaElement); 155 if (pDomChannel) 156 { 157 std::string target = pDomChannel->getTarget(); 158 size_t openparenthesis = target.find_first_of('('); 159 if (openparenthesis != std::string::npos) target.erase(openparenthesis); 160 daeSIDResolver resolver(pDomChannel, target.c_str()); 161 daeElement *pDaeElement = resolver.getElement(); 162 if (pDaeElement) 163 { 164 _daeElementDomChannelMap.insert(daeElementDomChannelMap::value_type(pDaeElement, pDomChannel)); 165 } 166 else 167 { 168 osg::notify( osg::WARN ) << "Could not locate <channel> target " << pDomChannel->getTarget()<< std::endl; 169 } 170 } 171 } 172 } 173 174 // Find all nodes that are used as bones. Note that while many files 175 // identify nodes with type="JOINT", some don't do this, while others 176 // identify every node as a joint, making it meaningless. 177 std::vector<domInstance_controller*> instanceControllers; 178 database->typeLookup(instanceControllers); 179 for (size_t i = 0; i < instanceControllers.size(); ++i) 180 { 181 domInstance_controller* pInstanceController = instanceControllers[i]; 182 183 domController *pDomController = daeSafeCast<domController>(getElementFromURI(pInstanceController->getUrl())); 184 if (!pDomController) 185 { 186 osg::notify( osg::WARN ) << "Failed to locate controller " << pInstanceController->getUrl().getURI() << std::endl; 187 continue; 188 } 189 190 const domInstance_controller::domSkeleton_Array& domSkeletonURIs = pInstanceController->getSkeleton_array(); 191 std::vector<daeElement*> searchIn; 192 193 for (size_t i = 0; i < domSkeletonURIs.getCount(); ++i) 194 { 195 if (daeElement* el = getElementFromURI(domSkeletonURIs[i]->getValue())) 196 { 197 searchIn.push_back(el); 198 if (domNode* pJoint = daeSafeCast<domNode>(el)) 199 { 200 _jointSet.insert(pJoint); 201 } 202 } 203 } 204 205 if (searchIn.empty()) 206 { 207 searchIn.push_back(_visualScene); 208 } 209 210 const domSkin* pSkin = pDomController->getSkin(); 211 if (!pSkin) continue; 212 const domSkin::domJoints* pJoints = pSkin->getJoints(); 213 if (!pJoints) continue; 214 const domInputLocal_Array& inputURIs = pJoints->getInput_array(); 215 216 domSource* pDomJointsSource = NULL; 217 for (size_t i=0; i < inputURIs.getCount(); i++) 218 { 219 if (!strcmp(inputURIs[i]->getSemantic(), COMMON_PROFILE_INPUT_JOINT)) 220 { 221 pDomJointsSource = daeSafeCast<domSource>(getElementFromURI(inputURIs[i]->getSource())); 222 if (!pDomJointsSource) 223 { 224 osg::notify( osg::WARN ) << "Could not find skin joints source '" << inputURIs[i]->getSource().getURI() << "'" <<std::endl; 225 } 226 } 227 } 228 229 if (!pDomJointsSource) 230 { 231 } 232 else if (domIDREF_array* pDomIDREFs = pDomJointsSource->getIDREF_array()) 233 { 234 for (size_t i = 0; i < pDomIDREFs->getCount(); ++i) 235 { 236 if (domNode* pJoint = daeSafeCast<domNode>(getElementFromIDRef(pDomIDREFs->getValue().get(i)))) 237 { 238 _jointSet.insert(pJoint); 239 } 240 } 241 } 242 else if (domName_array* pDomNames = pDomJointsSource->getName_array()) 243 { 244 for (size_t i = 0; i < pDomNames->getCount(); ++i) 245 { 246 daeString target = pDomNames->getValue().get(i); 247 for (size_t j = 0; j < searchIn.size(); ++j) 248 { 249 daeSIDResolver resolver(searchIn[j], target); 250 if (domNode* pJoint = daeSafeCast<domNode>(resolver.getElement())) 251 { 252 _jointSet.insert(pJoint); 253 } 254 } 255 } 256 } 257 } 258 } 259 260 // Build the actual scene graph based on the visual scene 261 _rootNode = processVisualScene( _visualScene ); 262 263 osgAnimation::BasicAnimationManager* pOsgAnimationManager = processAnimationLibraries(_document); 264 if (pOsgAnimationManager) 265 { 266 _rootNode->addUpdateCallback(pOsgAnimationManager); 267 } 268 125 269 return true; 126 270 } 127 271 128 osg::Node* daeReader::processVisualScene( domVisual_scene *scene ) 129 { 130 osg::Node *retVal; 272 void daeReader::addChild(osg::Group* group, osg::Node* node) 273 { 274 if (dynamic_cast<osgAnimation::Bone*>(node)) 275 { 276 unsigned index = 0; 277 while (index < group->getNumChildren() && 278 dynamic_cast<osgAnimation::Bone*>(group->getChild(index))) 279 { 280 ++index; 281 } 282 group->insertChild(index, node); 283 } 284 else 285 { 286 group->addChild(node); 287 } 288 } 289 290 osg::Group* daeReader::turnZUp() 291 { 292 osg::PositionAttitudeTransform* pat = NULL; 293 294 // If not Z axis up we need to rotate scene to bring the Z axis up 295 if (_assetUp_axis != UPAXISTYPE_Z_UP) 296 { 297 pat = new osg::PositionAttitudeTransform(); 298 if (_assetUp_axis == UPAXISTYPE_Y_UP) 299 { 300 pat->setAttitude(osg::Quat(osg::inDegrees(90.0f), osg::Vec3(1.0f,0.0f,0.0f))); 301 } 302 else //(m_AssetUp_axis == UPAXISTYPE_X_UP) 303 { 304 pat->setAttitude(osg::Quat(osg::inDegrees(90.0f), osg::Vec3(0.0f,1.0f,0.0f))); 305 } 306 } 307 308 _assetUp_axis = UPAXISTYPE_Z_UP; 309 return pat; 310 } 311 312 osg::Group* daeReader::processVisualScene( domVisual_scene *scene ) 313 { 314 osg::Group *retVal; 131 315 _rootStateSet = new osg::StateSet(); 132 316 … … 138 322 retVal->setName("Empty Collada scene"); 139 323 } 140 else if (nbVisualSceneGroup==1)141 {142 osg::Node *node = processNode( scene->getNode_array()[0] );143 if ( node != NULL )144 retVal = node;145 else146 {147 retVal = new osg::Group();148 retVal->setName("Empty Collada scene (import failure)");149 }150 }151 324 else 152 { 153 retVal = new osg::Group(); 154 retVal->setName("Collada visual scene group"); 155 for ( size_t i = 0; i < scene->getNode_array().getCount(); i++ ) 156 { 157 osg::Node *node = processNode( scene->getNode_array()[i] ); 158 if ( node != NULL ) 159 { 160 retVal->asGroup()->addChild( node ); 161 } 162 } 325 { 326 retVal = turnZUp(); 327 328 if (!retVal) 329 { 330 retVal = new osg::Group; 331 } 332 333 _skinInstanceControllers.clear(); 334 335 const domNode_Array& node_array = scene->getNode_array(); 336 for (size_t i = 0; i < node_array.getCount(); i++) 337 { 338 if (osg::Node* node = processNode(node_array[i], false)) 339 { 340 addChild(retVal, node); 341 } 342 } 343 344 processSkins(); 345 346 if (retVal->getName().empty()) 347 { 348 if (retVal->getNumChildren()) 349 { 350 retVal->setName("Collada visual scene group"); 351 } 352 else 353 { 354 retVal->setName("Empty Collada scene (import failure)"); 355 } 356 } 163 357 } 164 358 retVal->setStateSet(_rootStateSet.get()); … … 167 361 } 168 362 169 osg::Node* daeReader::processExtras(domNode *node) 363 364 365 osg::Group* daeReader::processExtras(domNode *node) 170 366 { 171 367 // See if one of the extras contains OpenSceneGraph specific information … … 304 500 // 0..* <node> 305 501 // 0..* <extra> 306 osg::Node* daeReader::processNode( domNode *node )502 osg::Node* daeReader::processNode( domNode *node, bool skeleton) 307 503 { 308 504 // First we need to determine what kind of OSG node we need … … 316 512 node->getSkew_array().getCount(); 317 513 318 // See if it is targeted 514 // See if it is targeted by an animation 319 515 bool targeted = false; 320 516 if (node->getId()) … … 323 519 } 324 520 325 osg::Node *resultNode; 326 if (coordcount > 0 || targeted ) 327 { 328 resultNode = processOsgMatrixTransform(node); 521 522 osg::Group *resultNode = NULL; 523 524 bool isBone = skeleton || isJoint(node); 525 526 if (coordcount > 0 || targeted || isBone) 527 { 528 // TODO 529 // single matrix -> MatrixTransform 530 // scale, euler, translate -> PositionAttitudeTransform 531 // if targeted -> StackedTransform 532 // otherwise a flattened -> MatrixTransform 533 resultNode = processOsgMatrixTransform(node, isBone); 329 534 } 330 535 else … … 337 542 processNodeExtra(resultNode, node); 338 543 339 resultNode->setName( node->getId() ? node->getId() : "" ); 340 341 osg::Group* groupNode = resultNode->asGroup(); 342 343 if (groupNode) 344 { 345 // 0..* <instance_camera> 346 domInstance_camera_Array cameraInstanceArray = node->getInstance_camera_array(); 347 for ( size_t i = 0; i < cameraInstanceArray.getCount(); i++ ) 348 { 349 daeElement *el = getElementFromURI( cameraInstanceArray[i]->getUrl()); 350 domCamera *c = daeSafeCast< domCamera >( el ); 351 352 if (c) 353 groupNode->addChild( processCamera( c )); 354 else 355 osg::notify( osg::WARN ) << "Failed to locate camera " << cameraInstanceArray[i]->getUrl().getURI() << std::endl; 356 } 357 358 // 0..* <instance_controller> 359 domInstance_controller_Array controllerInstanceArray = node->getInstance_controller_array(); 360 for ( size_t i = 0; i < controllerInstanceArray.getCount(); i++ ) 361 { 362 groupNode->addChild( processInstanceController( controllerInstanceArray[i] )); 363 } 364 365 // 0..* <instance_geometry> 366 domInstance_geometry_Array geometryInstanceArray = node->getInstance_geometry_array(); 367 for ( size_t i = 0; i < geometryInstanceArray.getCount(); i++ ) 368 { 369 groupNode->addChild( processInstanceGeometry( geometryInstanceArray[i] )); 370 } 371 372 // 0..* <instance_light> 373 domInstance_light_Array lightInstanceArray = node->getInstance_light_array(); 374 for ( size_t i = 0; i < lightInstanceArray.getCount(); i++ ) 375 { 376 daeElement *el = getElementFromURI( lightInstanceArray[i]->getUrl()); 377 domLight *l = daeSafeCast< domLight >( el ); 378 379 if (l) 380 groupNode->addChild( processLight( l )); 381 else 382 osg::notify( osg::WARN ) << "Failed to locate light " << lightInstanceArray[i]->getUrl().getURI() << std::endl; 383 } 384 385 // 0..* <instance_node> 386 domInstance_node_Array nodeInstanceArray = node->getInstance_node_array(); 387 for ( size_t i = 0; i < nodeInstanceArray.getCount(); i++ ) 388 { 389 daeElement *el = getElementFromURI( nodeInstanceArray[i]->getUrl()); 390 domNode *n = daeSafeCast< domNode >( el ); 391 392 if (n) 393 // Recursive call 394 groupNode->addChild( processNode( n )); 395 else 396 osg::notify( osg::WARN ) << "Failed to locate node " << nodeInstanceArray[i]->getUrl().getURI() << std::endl; 397 } 398 399 // 0..* <node> 400 domNode_Array nodeArray = node->getNode_array(); 401 for ( size_t i = 0; i < nodeArray.getCount(); i++ ) 402 { 544 if (resultNode->getName().empty()) 545 { 546 resultNode->setName( node->getId() ? node->getId() : "" ); 547 } 548 549 osg::Group* attachTo = resultNode; 550 551 if (!skeleton && isJoint(node)) 552 { 553 skeleton = true; 554 osgAnimation::Skeleton* pOsgSkeleton = getOrCreateSkeleton(node); 555 pOsgSkeleton->addChild(resultNode); 556 attachTo = resultNode; 557 resultNode = pOsgSkeleton; 558 } 559 560 // 0..* <instance_camera> 561 const domInstance_camera_Array& cameraInstanceArray = node->getInstance_camera_array(); 562 for ( size_t i = 0; i < cameraInstanceArray.getCount(); i++ ) 563 { 564 daeElement *el = getElementFromURI( cameraInstanceArray[i]->getUrl()); 565 domCamera *c = daeSafeCast< domCamera >( el ); 566 567 if (c) 568 addChild(attachTo, processCamera( c )); 569 else 570 osg::notify( osg::WARN ) << "Failed to locate camera " << cameraInstanceArray[i]->getUrl().getURI() << std::endl; 571 } 572 573 // 0..* <instance_controller> 574 const domInstance_controller_Array& controllerInstanceArray = node->getInstance_controller_array(); 575 for ( size_t i = 0; i < controllerInstanceArray.getCount(); i++ ) 576 { 577 osg::Node* pOsgNode = processInstanceController( controllerInstanceArray[i]); 578 579 // A skin controller may return NULL, since the RigGeometry is added as 580 // child of the skeleton and the skeleton already is added to the scenegraph 581 if (pOsgNode) 582 { 583 addChild(attachTo, pOsgNode); 584 } 585 } 586 587 // 0..* <instance_geometry> 588 const domInstance_geometry_Array& geometryInstanceArray = node->getInstance_geometry_array(); 589 for ( size_t i = 0; i < geometryInstanceArray.getCount(); i++ ) 590 { 591 addChild(attachTo, processInstanceGeometry( geometryInstanceArray[i] )); 592 } 593 594 // 0..* <instance_light> 595 const domInstance_light_Array& lightInstanceArray = node->getInstance_light_array(); 596 for ( size_t i = 0; i < lightInstanceArray.getCount(); i++ ) 597 { 598 daeElement *el = getElementFromURI( lightInstanceArray[i]->getUrl()); 599 domLight *pDomLight = daeSafeCast< domLight >( el ); 600 601 if (pDomLight) 602 addChild(attachTo, processLight(pDomLight)); 603 else 604 osg::notify( osg::WARN ) << "Failed to locate light " << lightInstanceArray[i]->getUrl().getURI() << std::endl; 605 } 606 607 // 0..* <instance_node> 608 const domInstance_node_Array& nodeInstanceArray = node->getInstance_node_array(); 609 for ( size_t i = 0; i < nodeInstanceArray.getCount(); i++ ) 610 { 611 daeElement *el = getElementFromURI( nodeInstanceArray[i]->getUrl()); 612 domNode *n = daeSafeCast< domNode >( el ); 613 614 if (n) 403 615 // Recursive call 404 groupNode->addChild( processNode( nodeArray[i] )); 405 } 616 addChild(attachTo, processNode( n, skeleton )); 617 else 618 osg::notify( osg::WARN ) << "Failed to locate node " << nodeInstanceArray[i]->getUrl().getURI() << std::endl; 619 } 620 621 // 0..* <node> 622 const domNode_Array& nodeArray = node->getNode_array(); 623 for ( size_t i = 0; i < nodeArray.getCount(); i++ ) 624 { 625 // Recursive call 626 addChild(attachTo, processNode( nodeArray[i], skeleton )); 406 627 } 407 628 -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeReader.h
r10234 r11129 21 21 #include <dae/daeElement.h> 22 22 #include <dom/domCommon_color_or_texture_type.h> 23 #include <dom/domInputLocalOffset.h> 24 #include <dom/domInstance_controller.h> 23 25 24 26 #include <osg/Node> 25 #include <osg/Transform>26 27 #include <osg/Notify> 27 #include <osg/PositionAttitudeTransform>28 28 #include <osgDB/ReaderWriter> 29 29 #include <osgDB/FileNameUtils> … … 31 31 #include <osgDB/Registry> 32 32 #include <osg/Material> 33 33 #include <osg/Texture2D> 34 #include <osgAnimation/BasicAnimationManager> 35 #include <osgAnimation/Bone> 36 #include <osgAnimation/Skeleton> 34 37 35 38 class domBind_material; … … 53 56 class domVisual_scene; 54 57 55 #include <dom/domInputLocalOffset.h> 56 57 namespace osgdae { 58 namespace osgDAE 59 { 58 60 59 61 class domSourceReader; … … 137 139 bool convert( const std::string &fileURI ); 138 140 139 osg::Node* getRootNode() { return rootNode; } 140 141 // Additional Information 142 std::string m_AssetUnitName; 143 float m_AssetUnitMeter; 144 domUpAxisType m_AssetUp_axis; 145 146 // Texture unit useage 147 enum 141 osg::Node* getRootNode() { return _rootNode; } 142 143 const std::string& getAssetUnitName() const {return _assetUnitName;} 144 float getAssetUnitMeter() const {return _assetUnitMeter;} 145 domUpAxisType getAssetUpAxis() const {return _assetUp_axis;} 146 147 enum TextureUnitUsage 148 148 { 149 149 AMBIENT_OCCLUSION_UNIT = 0, … … 152 152 }; 153 153 154 protected: 155 //scene processing 156 osg::Node* processVisualScene( domVisual_scene *scene ); 157 osg::Node* processNode( domNode *node ); 158 osg::Node* processOsgMatrixTransform( domNode *node ); 159 //osg::Node* processInstance( domInstanceWithExtra *iwe ); 154 enum InterpolationType 155 { 156 INTERPOLATION_UNKNOWN, 157 INTERPOLATION_STEP, 158 INTERPOLATION_LINEAR, 159 INTERPOLATION_BEZIER, 160 INTERPOLATION_HERMITE, 161 INTERPOLATION_CARDINAL, 162 INTERPOLATION_BSPLINE, 163 164 //COLLADA spec states that if interpolation is not specified then 165 //interpolation is application defined. Linear is a sensible default. 166 INTERPOLATION_DEFAULT = INTERPOLATION_LINEAR 167 }; 168 169 enum AuthoringTool 170 { 171 UNKNOWN, 172 BLENDER, 173 DAZ_STUDIO, 174 FBX_CONVERTER, 175 AUTODESK_3DS_MAX = FBX_CONVERTER,//3ds Max exports to DAE via Autodesk's FBX converter 176 GOOGLE_SKETCHUP, 177 MAYA 178 }; 179 180 class TextureParameters 181 { 182 public: 183 TextureParameters() 184 : wrap_s(osg::Texture::REPEAT), wrap_t(osg::Texture::REPEAT), 185 filter_min(osg::Texture::LINEAR_MIPMAP_LINEAR), filter_mag(osg::Texture::LINEAR), 186 transparent(false), opaque(FX_OPAQUE_ENUM_A_ONE), transparency(1.0f) 187 {} 188 189 bool operator < (const TextureParameters& rhs) const 190 { 191 int diffStr = filename.compare(rhs.filename); 192 if (diffStr) return diffStr < 0; 193 if (wrap_s != rhs.wrap_s) return wrap_s < rhs.wrap_s; 194 if (wrap_t != rhs.wrap_t) return wrap_t < rhs.wrap_t; 195 if (filter_min != rhs.filter_min) return filter_min < rhs.filter_min; 196 if (filter_mag != rhs.filter_mag) return filter_mag < rhs.filter_mag; 197 if (transparency != rhs.transparency) return transparency < rhs.transparency; 198 if (opaque != rhs.opaque) return opaque < rhs.opaque; 199 if (transparent != rhs.transparent) return transparent < rhs.transparent; 200 return border < rhs.border; 201 } 202 203 std::string filename; 204 osg::Texture::WrapMode wrap_s, wrap_t; 205 osg::Texture::FilterMode filter_min, filter_mag; 206 osg::Vec4 border; 207 208 //The following parameters are for transparency textures, to handle 209 //COLLADA's horrible transparency spec. 210 bool transparent; 211 domFx_opaque_enum opaque; 212 float transparency; 213 }; 214 215 class ChannelPart : public osg::Referenced 216 { 217 public: 218 std::string name; 219 osg::ref_ptr<osgAnimation::KeyframeContainer> keyframes; 220 InterpolationType interpolation; 221 }; 222 223 typedef std::map<domGeometry*, osg::ref_ptr<osg::Geode> > domGeometryGeodeMap; 224 typedef std::map<domMaterial*, osg::ref_ptr<osg::StateSet> > domMaterialStateSetMap; 225 typedef std::map<std::string, osg::ref_ptr<osg::StateSet> > MaterialStateSetMap; 226 typedef std::multimap< daeElement*, domChannel*> daeElementDomChannelMap; 227 typedef std::map<domChannel*, osg::ref_ptr<osg::NodeCallback> > domChannelOsgAnimationUpdateCallbackMap; 228 typedef std::map<domNode*, osg::ref_ptr<osgAnimation::Bone> > domNodeOsgBoneMap; 229 typedef std::map<domNode*, osg::ref_ptr<osgAnimation::Skeleton> > domNodeOsgSkeletonMap; 230 typedef std::map<TextureParameters, osg::ref_ptr<osg::Texture2D> > TextureParametersMap; 231 typedef std::map<std::pair<const osg::StateSet*, TextureUnitUsage>, std::string> TextureToCoordSetMap; 232 233 typedef std::map< daeElement*, domSourceReader > SourceMap; 234 typedef std::map< int, osg::IntArray*, std::less<int> > IndexMap; 235 typedef std::map< int, osg::Array*, std::less<int> > ArrayMap; 236 237 typedef std::multimap< osgAnimation::Target*, osg::ref_ptr<ChannelPart> > TargetChannelPartMap; 238 typedef std::multimap<std::pair<const domMesh*, unsigned>, std::pair<osg::ref_ptr<osg::Geometry>, GLuint> > OldToNewIndexMap; 239 240 private: 241 // If the node is a bone then it should be added before any other types of 242 // node, this function makes that happen. 243 static void addChild(osg::Group*, osg::Node*); 244 245 //scene processing 246 osg::Group* turnZUp(); 247 osg::Group* processVisualScene( domVisual_scene *scene ); 248 osg::Node* processNode( domNode *node, bool skeleton ); 249 osg::Transform* processOsgMatrixTransform( domNode *node, bool isBone); 250 251 template <typename T> 252 inline void getTransparencyCounts(daeDatabase*, int& zero, int& one) const; 253 254 /** Earlier versions of the COLLADA 1.4 spec state that transparency values 255 of 0 mean 100% opacity, but this has been changed in later versions to state 256 that transparency values of 1 mean 100% opacity. Documents created by 257 different tools at different times adhere to different versions of the 258 standard. This function looks at all transparency values in the database and 259 heuristically decides which way the values should be interpreted.*/ 260 bool findInvertTransparency(daeDatabase*) const; 261 262 osgAnimation::BasicAnimationManager* processAnimationLibraries(domCOLLADA* document); 263 void processAnimationClip(osgAnimation::BasicAnimationManager* pOsgAnimationManager, domAnimation_clip* pDomAnimationClip); 264 void processAnimation(domAnimation* pDomAnimation, osgAnimation::Animation* pOsgAnimation); 265 ChannelPart* processSampler(domChannel* pDomChannel, SourceMap &sources); 266 void processAnimationChannels(domAnimation* pDomAnimation, TargetChannelPartMap& tcm); 267 void processChannel(domChannel* pDomChannel, SourceMap &sources, TargetChannelPartMap& tcm); 268 void extractTargetName(const std::string&, std::string&, std::string&, std::string&); 160 269 161 270 // Processing of OSG specific info stored in node extras 162 osg:: Node* processExtras(domNode *node);271 osg::Group* processExtras(domNode *node); 163 272 void processNodeExtra(osg::Node* osgNode, domNode *node); 164 273 domTechnique* getOpenSceneGraphProfile(domExtra* extra); 165 274 void processAsset( domAsset *node ); 166 275 167 osg::Node* processOsgSwitch(domTechnique* teq); 168 osg::Node* processOsgMultiSwitch(domTechnique* teq); 169 osg::Node* processOsgLOD(domTechnique* teq); 170 osg::Node* processOsgDOFTransform(domTechnique* teq); 171 osg::Node* processOsgSequence(domTechnique* teq); 172 173 //geometry processing 174 class ReaderGeometry : public osg::Geometry 175 { 176 public: 177 std::map<int, int> _TexcoordSetMap; 178 }; 276 osg::Group* processOsgSwitch(domTechnique* teq); 277 osg::Group* processOsgMultiSwitch(domTechnique* teq); 278 osg::Group* processOsgLOD(domTechnique* teq); 279 osg::Group* processOsgDOFTransform(domTechnique* teq); 280 osg::Group* processOsgSequence(domTechnique* teq); 281 282 // geometry processing 283 osg::Geode* getOrCreateGeometry(domGeometry *geom, domBind_material* pDomBindMaterial, const osg::Geode** ppOriginalGeode = NULL); 284 osgAnimation::Bone* getOrCreateBone(domNode *pDomNode); 285 osgAnimation::Skeleton* getOrCreateSkeleton(domNode *pDomNode); 179 286 osg::Geode* processInstanceGeometry( domInstance_geometry *ig ); 180 osg::Geode* processGeometry( domGeometry *geo ); 181 osg::Geode* processInstanceController( domInstance_controller *ictrl ); 182 183 typedef std::map< daeElement*, domSourceReader > SourceMap; 184 typedef std::map< int, osg::IntArray*, std::less<int> > IndexMap; 287 288 osg::Geode* processMesh(domMesh* pDomMesh); 289 osg::Geode* processConvexMesh(domConvex_mesh* pDomConvexMesh); 290 osg::Geode* processSpline(domSpline* pDomSpline); 291 osg::Geode* processGeometry(domGeometry *pDomGeometry); 292 293 typedef std::vector<domInstance_controller*> domInstance_controllerList; 294 295 void processSkins(); 296 //Process skins attached to one skeleton 297 void processSkeletonSkins(domNode* skeletonRoot, const domInstance_controllerList&); 298 void processSkin(domSkin* pDomSkin, domNode* skeletonRoot, osgAnimation::Skeleton*, domBind_material* pDomBindMaterial); 299 osg::Node* processMorph(domMorph* pDomMorph, domBind_material* pDomBindMaterial); 300 osg::Node* processInstanceController( domInstance_controller *ictrl ); 185 301 186 302 template< typename T > 187 void processSinglePPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode);303 void processSinglePPrimitive(osg::Geode* geode, const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode); 188 304 189 305 template< typename T > 190 void processMultiPPrimitive(osg::Geode* geode, T *group, SourceMap &sources, GLenum mode ); 191 192 void processPolylist(osg::Geode* geode, domPolylist *group, SourceMap &sources ); 193 194 void resolveArrays( domInputLocalOffset_Array &inputs, osg::Geometry *geom, 195 SourceMap &sources, IndexMap &index_map ); 196 197 void processP( domP *p, osg::Geometry *&geom, IndexMap &index_map, osg::DrawArrayLengths* dal/*GLenum mode*/ ); 306 void processMultiPPrimitive(osg::Geode* geode, const domMesh* pDomMesh, const T* group, SourceMap& sources, GLenum mode); 307 308 template <typename T> 309 void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const T *group, SourceMap& sources); 310 311 void processPolylist(osg::Geode* geode, const domMesh* pDomMesh, const domPolylist *group, SourceMap &sources); 312 void processPolygons(osg::Geode* geode, const domMesh* pDomMesh, const domPolygons *group, SourceMap &sources); 313 314 void resolveMeshArrays(const domP_Array&, 315 const domInputLocalOffset_Array& inputs, const domMesh* pDomMesh, 316 osg::Geometry* geometry, SourceMap &sources, 317 std::vector<std::vector<GLuint> >& vertexLists); 198 318 199 319 //material/effect processing … … 202 322 void processEffect(osg::StateSet *ss, domEffect *effect ); 203 323 void processProfileCOMMON(osg::StateSet *ss, domProfile_COMMON *pc ); 204 bool processColorOrTextureType( domCommon_color_or_texture_type *cot, 324 bool processColorOrTextureType(const osg::StateSet*, 325 domCommon_color_or_texture_type *cot, 205 326 osg::Material::ColorMode channel, 206 327 osg::Material *mat, 207 328 domCommon_float_or_param_type *fop = NULL, 208 osg:: StateAttribute**sa = NULL,329 osg::Texture2D **sa = NULL, 209 330 bool normalizeShininess=false); 210 331 void processTransparencySettings( domCommon_transparent_type *ctt, 211 332 domCommon_float_or_param_type *pTransparency, 212 osg::StateSet *ss,333 osg::StateSet*, 213 334 osg::Material *material, 214 335 xsNCName diffuseTextureName ); 215 bool GetFloat4Param(xsNCName Reference, domFloat4 &f4); 216 bool GetFloatParam(xsNCName Reference, domFloat &f); 217 218 osg::StateAttribute *processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex ); 336 bool GetFloat4Param(xsNCName Reference, domFloat4 &f4) const; 337 bool GetFloatParam(xsNCName Reference, domFloat &f) const; 338 339 std::string processImagePath(const domImage*) const; 340 osg::Image* processImageTransparency(const osg::Image*, domFx_opaque_enum, float transparency) const; 341 osg::Texture2D* processTexture( domCommon_color_or_texture_type_complexType::domTexture *tex, const osg::StateSet*, TextureUnitUsage, domFx_opaque_enum = FX_OPAQUE_ENUM_A_ONE, float transparency = 1.0f); 342 void copyTextureCoordinateSet(const osg::StateSet* ss, const osg::Geometry* cachedGeometry, osg::Geometry* clonedGeometry, const domInstance_material* im, TextureUnitUsage); 219 343 220 344 //scene objects … … 222 346 osg::Node* processCamera( domCamera *dcamera ); 223 347 224 protected: 225 DAE *dae; 226 osg::Node* rootNode; 348 domNode* getRootJoint(domNode*) const; 349 domNode* findJointNode(daeElement* searchFrom, domInstance_controller*) const; 350 domNode* findSkeletonNode(daeElement* searchFrom, domInstance_controller*) const; 351 352 /// Return whether the node is used as a bone. Note that while many files 353 /// identify joints with type="JOINT", some don't do this, while others 354 /// incorrectly identify every node as a joint. 355 bool isJoint(const domNode* node) const {return _jointSet.find(node) != _jointSet.end();} 356 357 private: 358 359 DAE *_dae; 360 osg::Node* _rootNode; 227 361 osg::ref_ptr<osg::StateSet> _rootStateSet; 362 domCOLLADA* _document; 363 domVisual_scene* _visualScene; 228 364 229 365 std::map<std::string,bool> _targetMap; 230 366 231 int m_numlights; 232 233 domInstance_effect *currentInstance_effect; 234 domEffect *currentEffect; 235 236 typedef std::map< domGeometry*, osg::ref_ptr<osg::Geode> > domGeometryGeodeMap; 237 typedef std::map< domMaterial*, osg::ref_ptr<osg::StateSet> > domMaterialStateSetMap; 238 typedef std::map< std::string, osg::ref_ptr<osg::StateSet> > MaterialStateSetMap; 239 367 int _numlights; 368 369 domInstance_effect *_currentInstance_effect; 370 domEffect *_currentEffect; 371 372 /// Maps an animated element to a domchannel to quickly find which animation influence this element 373 // TODO a single element can be animated by multiple channels (with different members like translate.x or morphweights(2) ) 374 daeElementDomChannelMap _daeElementDomChannelMap; 375 /// Maps a domchannel to an animationupdatecallback 376 domChannelOsgAnimationUpdateCallbackMap _domChannelOsgAnimationUpdateCallbackMap; 240 377 /// Maps geometry to a Geode 241 domGeometryGeodeMap geometryMap; 378 domGeometryGeodeMap _geometryMap; 379 /// All nodes in the document that are used as joints. 380 std::set<const domNode*> _jointSet; 381 /// Maps a node (of type joint) to a osgAnimation::Bone 382 domNodeOsgBoneMap _jointMap; 383 /// Maps a node (of type joint) to a osgAnimation::Skeleton 384 domNodeOsgSkeletonMap _skeletonMap; 242 385 // Maps material target to stateset 243 domMaterialStateSetMap materialMap;386 domMaterialStateSetMap _materialMap; 244 387 // Maps material symbol to stateset 245 MaterialStateSetMap materialMap2; 246 247 enum AuthoringTool 248 { 249 UNKNOWN, 250 GOOGLE_SKETCHUP 251 }; 252 AuthoringTool m_AuthoringTool; 253 bool m_StrictTransparency; 388 MaterialStateSetMap _materialMap2; 389 TextureParametersMap _textureParamMap; 390 TextureToCoordSetMap _texCoordSetMap; 391 domInstance_controllerList _skinInstanceControllers; 392 OldToNewIndexMap _oldToNewIndexMap; 393 394 AuthoringTool _authoringTool; 395 bool _strictTransparency, _invertTransparency; 396 397 // Additional Information 398 std::string _assetUnitName; 399 float _assetUnitMeter; 400 domUpAxisType _assetUp_axis; 254 401 }; 255 402 -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWGeometry.cpp
r10234 r11129 13 13 14 14 #include "daeWriter.h" 15 #include <osgAnimation/RigGeometry> 15 16 16 17 #include <dom/domCOLLADA.h> … … 20 21 #include <dom/domGeometry.h> 21 22 #include <dom/domConstants.h> 23 //#include <dom/domSkin.h> 22 24 23 25 #include <sstream> 24 26 25 using namespace osgdae; 27 using namespace osgDAE; 28 29 domGeometry* daeWriter::getOrCreateDomGeometry(osg::Geometry* pOsgGeometry) 30 { 31 // See if geometry exists in cache 32 OsgGeometryDomGeometryMap::iterator iter = geometryMap.find( pOsgGeometry ); 33 if ( iter != geometryMap.end() ) 34 { 35 return iter->second; 36 } 37 else 38 { 39 if (!lib_geoms) 40 { 41 lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) ); 42 } 43 domGeometry* pDomGeometry = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) ); 44 45 std::string name = pOsgGeometry->getName(); 46 if (name.empty()) 47 name = uniquify("geometry"); 48 else 49 name = uniquify(name); 50 pDomGeometry->setId( name.c_str() ); 51 #ifndef EARTH_GEO 52 geometryMap.insert( std::make_pair( pOsgGeometry, pDomGeometry ) ); 53 #endif 54 55 if ( !processGeometry( pOsgGeometry, pDomGeometry, name ) ) 56 { 57 daeElement::removeFromParent( pDomGeometry ); 58 return NULL; 59 } 60 return pDomGeometry; 61 } 62 } 63 64 void daeWriter::writeRigGeometry(osgAnimation::RigGeometry *pOsgRigGeometry) 65 { 66 // See if controller exists in cache 67 OsgRigGeometryDomControllerMap::iterator iter = _osgRigGeometryDomControllerMap.find(pOsgRigGeometry); 68 domController* pDomController = NULL; 69 if ( iter != _osgRigGeometryDomControllerMap.end() ) 70 { 71 pDomController = iter->second; 72 } 73 else 74 { 75 domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgRigGeometry); 76 if (pDomGeometry) 77 { 78 if (!lib_controllers) 79 { 80 lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) ); 81 } 82 83 // <controller> 84 // 1 <skin> 85 // source 86 // 0..1 <bind_shape_matrix> 87 // 3..* <source> 88 // 1 <joints> 89 // 1 <vertex_weights> 90 // 0..1 <extra> 91 pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); 92 std::string name = pOsgRigGeometry->getName(); 93 if (name.empty()) 94 name = uniquify("skincontroller"); 95 else 96 name = uniquify(name); 97 pDomController->setId( name.c_str() ); 98 _osgRigGeometryDomControllerMap.insert( std::make_pair( pOsgRigGeometry, pDomController ) ); 99 100 // Link <skin> to cache hit or created <geometry> 101 domSkin* pDomSkin = daeSafeCast< domSkin >(pDomController->add( COLLADA_ELEMENT_SKIN )); 102 std::string url = "#" + std::string(pDomGeometry->getId()); 103 pDomSkin->setSource(url.c_str()); 104 105 domSkin::domBind_shape_matrix* pDomBindShapeMatrix = daeSafeCast< domSkin::domBind_shape_matrix >(pDomSkin->add( COLLADA_ELEMENT_BIND_SHAPE_MATRIX )); 106 107 domSource* pDomJointsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 108 std::string skinJointsName = name + "_skin_joints"; 109 pDomJointsSource->setId(skinJointsName.c_str()); 110 111 domListOfNames jointNames; // TODO fill with joint ids 112 int size = 0; // TODO number of animated joints 113 114 osgAnimation::VertexInfluenceMap* vim = pOsgRigGeometry->getInfluenceMap(); 115 osgAnimation::VertexInfluenceMap::iterator iter = vim->begin(); 116 while (iter != vim->end()) 117 { 118 jointNames.append(iter->first.c_str()); 119 //iter->second.getn 120 ++iter; 121 } 122 123 domName_array* pDomJointsNameArray = daeSafeCast< domName_array >(pDomJointsSource->add(COLLADA_ELEMENT_NAME_ARRAY)); 124 std::string jointsNameArrayName = name + "_joints_array"; 125 pDomJointsNameArray->setId(jointsNameArrayName.c_str()); 126 pDomJointsNameArray->setCount(size); 127 pDomJointsNameArray->setValue(jointNames); 128 { 129 domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomJointsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 130 131 domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 132 std::string url = "#" + jointsNameArrayName; 133 pDomAccessor->setSource(url.c_str()); 134 pDomAccessor->setCount(size); 135 136 domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 137 pDomParam->setType(COLLADA_TYPE_NAME); 138 } 139 140 domSource* pDomSkinBindPoseSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 141 std::string skinBindPoseName = name + "_skin_bind_pose"; 142 pDomSkinBindPoseSource->setId(skinBindPoseName.c_str()); 143 144 domListOfFloats matrices; // TODO fill with bind matrices 145 int numMatrices = 0; // TODO number of bind matrices 146 domFloat_array* pDomMatricesArray = daeSafeCast< domFloat_array >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 147 std::string matricesArrayName = name + "_matrices_array"; 148 pDomMatricesArray->setId(matricesArrayName.c_str()); 149 pDomMatricesArray->setCount(numMatrices); 150 pDomMatricesArray->setValue(matrices); 151 { 152 domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinBindPoseSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 153 154 domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 155 std::string url = "#" + matricesArrayName; 156 pDomAccessor->setSource(url.c_str()); 157 pDomAccessor->setCount(size); 158 pDomAccessor->setStride(16); 159 160 domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 161 pDomParam->setType(COLLADA_TYPE_FLOAT4X4); 162 } 163 164 domSource* pDomSkinWeightsSource = daeSafeCast< domSource >(pDomSkin->add( COLLADA_ELEMENT_SOURCE )); 165 std::string skinWeightsName = name + "_skin_weights"; 166 pDomSkinWeightsSource->setId(skinWeightsName.c_str()); 167 168 domListOfFloats weights; // TODO fill with vertex weights 169 int numWeights = 0; // TODO number of vertices vertex weights 170 domFloat_array* pDomWeightsArray = daeSafeCast< domFloat_array >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 171 std::string weightsArrayName = name + "_weights_array"; 172 pDomWeightsArray->setId(weightsArrayName.c_str()); 173 pDomWeightsArray->setCount(numWeights); 174 pDomWeightsArray->setValue(weights); 175 { 176 domSource::domTechnique_common* pDomSourceTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomSkinWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 177 178 domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomSourceTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 179 std::string url = "#" + weightsArrayName; 180 pDomAccessor->setSource(url.c_str()); 181 pDomAccessor->setCount(size); 182 183 domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 184 pDomParam->setType(COLLADA_TYPE_FLOAT); 185 } 186 187 domSkin::domJoints* pDomJoints = daeSafeCast< domSkin::domJoints >(pDomSkin->add( COLLADA_ELEMENT_JOINTS )); 188 189 domInputLocal* pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT)); 190 pDomInput->setSemantic(COMMON_PROFILE_INPUT_JOINT); 191 url = "#" + skinJointsName; 192 pDomInput->setSource(url.c_str()); 193 194 pDomInput = daeSafeCast< domInputLocal >(pDomJoints->add(COLLADA_ELEMENT_INPUT)); 195 pDomInput->setSemantic(COMMON_PROFILE_INPUT_INV_BIND_MATRIX); 196 url = "#" + skinBindPoseName; 197 pDomInput->setSource(url.c_str()); 198 199 domSkin::domVertex_weights* pDomVertexWeights = daeSafeCast< domSkin::domVertex_weights >(pDomSkin->add( COLLADA_ELEMENT_VERTEX_WEIGHTS )); 200 pDomVertexWeights->setCount(0);// TODO set number of vertex weights 201 202 domInputLocalOffset* pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT)); 203 pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_JOINT); 204 url = "#" + skinJointsName; 205 pDomInputLocalOffset->setSource(url.c_str()); 206 pDomInputLocalOffset->setOffset(0); 207 208 pDomInputLocalOffset = daeSafeCast< domInputLocalOffset >(pDomVertexWeights->add(COLLADA_ELEMENT_INPUT)); 209 pDomInputLocalOffset->setSemantic(COMMON_PROFILE_INPUT_WEIGHT); 210 url = "#" + weightsArrayName; 211 pDomInputLocalOffset->setSource(url.c_str()); 212 pDomInputLocalOffset->setOffset(1); 213 214 domSkin::domVertex_weights::domVcount* pDomVcount = daeSafeCast< domSkin::domVertex_weights::domVcount >(pDomVertexWeights->add(COLLADA_ELEMENT_VCOUNT)); 215 domListOfUInts valueCounts; 216 // TODO 217 pDomVcount->setValue(valueCounts); 218 domSkin::domVertex_weights::domV* pDomV = daeSafeCast< domSkin::domVertex_weights::domV >(pDomVertexWeights->add(COLLADA_ELEMENT_V)); 219 domListOfInts values; 220 //TODO 221 pDomV->setValue(values); 222 } 223 } 224 225 if (pDomController) 226 { 227 // Link <instance_controller> to cache hit or created <controller> 228 domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) ); 229 std::string url = "#" + std::string(pDomController->getId()); 230 pDomInstanceController->setUrl( url.c_str() ); 231 } 232 } 233 234 void daeWriter::writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometry) 235 { 236 // See if controller exists in cache 237 OsgMorphGeometryDomControllerMap::iterator iter = _osgMorphGeometryDomControllerMap.find(pOsgMorphGeometry); 238 domController* pDomController = NULL; 239 if ( iter != _osgMorphGeometryDomControllerMap.end() ) 240 { 241 pDomController = iter->second; 242 } 243 else 244 { 245 domGeometry* pDomGeometry = getOrCreateDomGeometry(pOsgMorphGeometry); 246 if (pDomGeometry) 247 { 248 if (!lib_controllers) 249 { 250 lib_controllers = daeSafeCast< domLibrary_controllers >( dom->add( COLLADA_ELEMENT_LIBRARY_CONTROLLERS ) ); 251 } 252 253 // <controller> 254 // 1 <morph source (method)> 255 // 2..* <source> 256 // 1 <targets> 257 // 2..* <input semantic source> 258 // 0..* <extra> 259 // 0..* <extra> 260 pDomController = daeSafeCast< domController >( lib_controllers->add( COLLADA_ELEMENT_CONTROLLER) ); 261 std::string name = pOsgMorphGeometry->getName(); 262 if (name.empty()) 263 name = uniquify("morphcontroller"); 264 else 265 name = uniquify(name); 266 pDomController->setId( name.c_str() ); 267 _osgMorphGeometryDomControllerMap.insert( std::make_pair( pOsgMorphGeometry, pDomController ) ); 268 269 // Link <morph> to cache hit or created <geometry> 270 domMorph* pDomMorph = daeSafeCast< domMorph >(pDomController->add( COLLADA_ELEMENT_MORPH )); 271 std::string url = "#" + std::string(pDomGeometry->getId()); 272 pDomMorph->setSource(url.c_str()); 273 pDomMorph->setMethod(MORPHMETHODTYPE_NORMALIZED); 274 //pDomMorph->setMethod(MORPHMETHODTYPE_RELATIVE); 275 276 domSource* pDomTargetsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE )); 277 std::string targetsName = name + "_morph_targets"; 278 pDomTargetsSource->setId(targetsName.c_str()); 279 280 domIDREF_array* pDomIDREFArray = daeSafeCast< domIDREF_array >(pDomTargetsSource->add(COLLADA_ELEMENT_IDREF_ARRAY)); 281 xsIDREFS idrefs; 282 osgAnimation::MorphGeometry::MorphTargetList morphTargetList = pOsgMorphGeometry->getMorphTargetList(); 283 for (unsigned int i=0; i < morphTargetList.size(); i++) 284 { 285 domGeometry* pDomGeometry = getOrCreateDomGeometry(morphTargetList[i].getGeometry()); 286 idrefs.append(pDomGeometry->getId()); 287 } 288 pDomIDREFArray->setValue(idrefs); 289 std::string targetsArrayName = targetsName + "_array"; 290 pDomIDREFArray->setId(targetsArrayName.c_str()); 291 pDomIDREFArray->setCount(morphTargetList.size()); 292 293 domSource::domTechnique_common* pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomTargetsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 294 domAccessor* pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 295 pDomAccessor->setCount(morphTargetList.size()); 296 url = "#" + targetsArrayName; 297 pDomAccessor->setSource(url.c_str()); 298 299 domParam* pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 300 pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_TARGET); 301 pDomParam->setType("IDREF"); // COLLADA_TYPE_IDREF does not exist 302 303 domSource* pDomWeightsSource = daeSafeCast< domSource >(pDomMorph->add( COLLADA_ELEMENT_SOURCE )); 304 std::string weightsName = name + "_morph_weights"; 305 pDomWeightsSource->setId(weightsName.c_str()); 306 307 domFloat_array* pDomFloatArray = daeSafeCast< domFloat_array >(pDomWeightsSource->add(COLLADA_ELEMENT_FLOAT_ARRAY)); 308 domListOfFloats weights; 309 for (unsigned int i=0; i < morphTargetList.size(); i++) 310 { 311 weights.append(morphTargetList[i].getWeight()); 312 } 313 pDomFloatArray->setValue(weights); 314 std::string weigthsArrayName = weightsName + "_array"; 315 pDomFloatArray->setId(weigthsArrayName.c_str()); 316 pDomFloatArray->setCount(morphTargetList.size()); 317 318 pDomTechniqueCommon = daeSafeCast< domSource::domTechnique_common >(pDomWeightsSource->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 319 pDomAccessor = daeSafeCast< domAccessor >(pDomTechniqueCommon->add(COLLADA_ELEMENT_ACCESSOR)); 320 pDomAccessor->setCount(morphTargetList.size()); 321 url = "#" + weightsName; 322 pDomAccessor->setSource(url.c_str()); 323 324 pDomParam = daeSafeCast< domParam >(pDomAccessor->add(COLLADA_ELEMENT_PARAM)); 325 pDomParam->setName(COMMON_PROFILE_INPUT_MORPH_WEIGHT); 326 pDomParam->setType(COLLADA_TYPE_FLOAT); 327 328 domMorph::domTargets* pDomTargets = daeSafeCast< domMorph::domTargets >(pDomMorph->add( COLLADA_ELEMENT_TARGETS )); 329 330 domInputLocal* pDomTargetsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT )); 331 pDomTargetsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_TARGET); 332 url = "#" + targetsName; 333 pDomTargetsInput->setSource(url.c_str()); 334 335 domInputLocal* pDomWeightsInput = daeSafeCast< domInputLocal >(pDomTargets->add( COLLADA_ELEMENT_INPUT )); 336 pDomWeightsInput->setSemantic(COMMON_PROFILE_INPUT_MORPH_WEIGHT); 337 url = "#" + weightsName; 338 pDomWeightsInput->setSource(url.c_str()); 339 } 340 } 341 342 if (pDomController) 343 { 344 // Transparency at drawable level 345 if (pOsgMorphGeometry->getStateSet()) 346 m_CurrentRenderingHint = pOsgMorphGeometry->getStateSet()->getRenderingHint(); 347 348 pushStateSet(pOsgMorphGeometry->getStateSet()); 349 350 // Link <instance_controller> to cache hit or created <controller> 351 domInstance_controller* pDomInstanceController = daeSafeCast< domInstance_controller >( currentNode->add( COLLADA_ELEMENT_INSTANCE_CONTROLLER ) ); 352 std::string url = "#" + std::string(pDomController->getId()); 353 pDomInstanceController->setUrl( url.c_str() ); 354 355 if (!stateSetStack.empty()) 356 { 357 domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceController->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 358 processMaterial( currentStateSet.get(), pDomBindMaterial, pOsgMorphGeometry->getName() ); 359 } 360 361 popStateSet(pOsgMorphGeometry->getStateSet()); 362 } 363 } 26 364 27 365 void daeWriter::apply( osg::Geode &node ) … … 43 381 if ( g != NULL ) 44 382 { 45 // Transparency at drawable level 46 if (NULL != g->getStateSet()) 47 m_CurrentRenderingHint = g->getStateSet()->getRenderingHint(); 48 49 pushStateSet(g->getStateSet()); 50 std::map< osg::Geometry*, domGeometry *>::iterator iter = geometryMap.find( g ); 51 if ( iter != geometryMap.end() ) 52 { 53 domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 383 osgAnimation::RigGeometry *pOsgRigGeometry = dynamic_cast<osgAnimation::RigGeometry*>(g); 384 if (pOsgRigGeometry) 385 { 386 writeRigGeometry(pOsgRigGeometry); 387 } 388 else 389 { 390 osgAnimation::MorphGeometry *pOsgMorphGeometry = dynamic_cast<osgAnimation::MorphGeometry*>(g); 391 if (pOsgMorphGeometry) 392 { 393 writeMorphGeometry(pOsgMorphGeometry); 394 } 395 else 396 { 397 // Write a default osg::Geometry 398 399 // Transparency at drawable level 400 if (NULL != g->getStateSet()) 401 m_CurrentRenderingHint = g->getStateSet()->getRenderingHint(); 402 403 pushStateSet(g->getStateSet()); 54 404 55 std::string url = "#" + std::string( iter->second->getId() ); 56 ig->setUrl( url.c_str() ); 57 if (!stateSetStack.empty()) 58 processMaterial( currentStateSet.get(), ig, iter->second->getId() ); 59 } 60 else 61 { 62 if ( lib_geoms == NULL ) 63 { 64 lib_geoms = daeSafeCast< domLibrary_geometries >( dom->add( COLLADA_ELEMENT_LIBRARY_GEOMETRIES ) ); 65 } 66 std::string name = node.getName(); 67 if ( name.empty() ) name = "geometry"; 68 name = uniquify( name ); 69 70 domGeometryRef geo = daeSafeCast< domGeometry >( lib_geoms->add( COLLADA_ELEMENT_GEOMETRY ) ); 71 geo->setId( name.c_str() ); 72 73 if ( !processGeometry( g, geo, name ) ) 74 { 75 daeElement::removeFromParent( geo ); 76 continue; 77 } 78 79 domInstance_geometry *ig = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 80 81 std::string url = "#" + name; 82 ig->setUrl( url.c_str() ); 83 84 #ifndef EARTH_GEO 85 geometryMap.insert( std::make_pair( g, geo ) ); 86 #endif 87 88 if (!stateSetStack.empty()) 89 processMaterial( currentStateSet.get(), ig, name ); 90 } 91 popStateSet(g->getStateSet()); 405 domGeometry* pDomGeometry = getOrCreateDomGeometry(g); 406 if (pDomGeometry) 407 { 408 // Link <instance_geometry> to cache hit or created <geometry> 409 domInstance_geometry *pDomInstanceGeometry = daeSafeCast< domInstance_geometry >( currentNode->add( COLLADA_ELEMENT_INSTANCE_GEOMETRY ) ); 410 std::string url = "#" + std::string(pDomGeometry->getId()); 411 pDomInstanceGeometry->setUrl( url.c_str() ); 412 413 if (!stateSetStack.empty()) 414 { 415 domBind_material *pDomBindMaterial = daeSafeCast< domBind_material >( pDomInstanceGeometry->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 416 processMaterial( currentStateSet.get(), pDomBindMaterial, pDomGeometry->getId() ); 417 } 418 } 419 420 popStateSet(g->getStateSet()); 421 } 422 } 423 } 424 else 425 { 426 osg::notify( osg::WARN ) << "Non-geometry drawables are not supported" << std::endl; 92 427 } 93 428 } … … 143 478 domSource *color = NULL; 144 479 std::vector< domSource * >texcoord; 480 std::vector< domSource * > vertexAttribute; 145 481 domLines *lines = NULL; 146 482 domLinestrips *linestrips = NULL; … … 149 485 domTrifans *trifans = NULL; 150 486 domPolygons *polys = NULL; 151 domPolylist *polylist = NULL;487 domPolylist *polylist = NULL; 152 488 153 //TODO: Make sure the assumptions about arrays is correct.154 // Probably not so I should make each thing more flexible so arrays can be different sizes.155 156 /*osg::Vec3Array *verts = (osg::Vec3Array *)geom->getVertexArray();157 osg::IndexArray *vertInds = geom->getVertexIndices();158 159 osg::Vec3Array *normals = (osg::Vec3Array *)geom->getNormalArray();160 osg::IndexArray *normalInds = geom->getNormalIndices();161 162 osg::Vec4Array *colors = (osg::Vec4Array *)geom->getColorArray();163 osg::IndexArray *colorInds = geom->getColorIndices();*/164 165 489 ArrayNIndices verts( geom->getVertexArray(), geom->getVertexIndices() ); 166 490 ArrayNIndices normals( geom->getNormalArray(), geom->getNormalIndices() ); 167 491 ArrayNIndices colors( geom->getColorArray(), geom->getColorIndices() ); 492 493 // RS BUG 494 // getNumTexCoordArrays may return larger number 495 // where getTexCoordArray(0) may have a BIND_OFF and an empty arrat 168 496 std::vector<ArrayNIndices> texcoords; 169 497 for ( unsigned int i = 0; i < geom->getNumTexCoordArrays(); i++ ) 170 498 { 171 texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) ); 172 } 173 174 //process POSITION 499 if (geom->getTexCoordArray(i)) 500 { 501 texcoords.push_back( ArrayNIndices( geom->getTexCoordArray( i ), geom->getTexCoordIndices( i ) ) ); 502 } 503 } 504 std::vector<ArrayNIndices> vertexAttributes; 505 for ( unsigned int i = 0; i < geom->getNumVertexAttribArrays(); i++ ) 506 { 507 if (geom->getVertexAttribArray(i)) 508 { 509 vertexAttributes.push_back(ArrayNIndices( geom->getVertexAttribArray( i ), geom->getVertexAttribIndices(i))); 510 } 511 } 512 513 // process POSITION 175 514 std::string sName = name + "-positions"; 176 515 pos = createSource( mesh, sName, verts.mode ); … … 219 558 220 559 //make a POSITION input in it 221 domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );222 il->setSemantic( COMMON_PROFILE_INPUT_POSITION);560 domInputLocal *il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 561 il->setSemantic( COMMON_PROFILE_INPUT_POSITION ); 223 562 std::string url = "#" + std::string( pos->getId() ); 224 563 il->setSource( url.c_str() ); … … 273 612 //if NORMAL shares same indices as POSITION put it in the vertices 274 613 /*if ( normalInds == vertInds && vertInds != NULL ) { 275 il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );276 il->setSemantic( COMMON_PROFILE_INPUT_NORMAL);614 il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 615 il->setSemantic( COMMON_PROFILE_INPUT_NORMAL ); 277 616 url = "#" + std::string(md->norm->getId()); 278 617 il->setSource( url.c_str() ); … … 324 663 //if COLOR shares same indices as POSITION put it in the vertices 325 664 /*if ( colorInds == vertInds && vertInds != NULL ) { 326 il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) );327 il->setSemantic( COMMON_PROFILE_INPUT_COLOR);665 il = daeSafeCast< domInputLocal >( vertices->add( COLLADA_ELEMENT_INPUT ) ); 666 il->setSemantic( COMMON_PROFILE_INPUT_COLOR ); 328 667 url = "#" + std::string(md->color->getId()); 329 668 il->setSource( url.c_str() ); … … 366 705 for ( unsigned int i = 0; i < texcoords[ti].vec4->size(); i++ ) 367 706 { 368 t->getFloat_array()->getValue().append( (*texcoords[ i].vec4)[ti].x() );369 t->getFloat_array()->getValue().append( (*texcoords[ i].vec4)[ti].y() );370 t->getFloat_array()->getValue().append( (*texcoords[ i].vec4)[ti].z() );371 t->getFloat_array()->getValue().append( (*texcoords[ i].vec4)[ti].w() );707 t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].x() ); 708 t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].y() ); 709 t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].z() ); 710 t->getFloat_array()->getValue().append( (*texcoords[ti].vec4)[i].w() ); 372 711 } 373 712 break; … … 378 717 } 379 718 texcoord.push_back( t ); 719 } 720 721 //RS 722 //process TEXCOORD 723 //TODO: Do the same as normal and colors for texcoods. But in a loop since you can have many 724 for ( unsigned int ti = 0; ti < vertexAttributes.size(); ti++ ) 725 { 726 if (vertexAttributes[ti].mode != ArrayNIndices::NONE) 727 { 728 std::ostringstream intstr; 729 intstr << std::dec << ti; 730 sName = name + "-vertexAttribute_" + intstr.str(); 731 732 domSource *t = createSource( mesh, sName, vertexAttributes[ti].mode, false, true ); 733 switch( vertexAttributes[ti].mode ) 734 { 735 case ArrayNIndices::VEC2: 736 t->getFloat_array()->setCount( vertexAttributes[ti].vec2->size() *2 ); 737 t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec2->size() ); 738 for ( unsigned int i = 0; i < vertexAttributes[ti].vec2->size(); i++ ) 739 { 740 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].x() ); 741 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec2)[i].y() ); 742 } 743 break; 744 case ArrayNIndices::VEC3: 745 t->getFloat_array()->setCount( vertexAttributes[ti].vec3->size() *3 ); 746 t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec3->size() ); 747 for ( unsigned int i = 0; i < vertexAttributes[ti].vec3->size(); i++ ) 748 { 749 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].x() ); 750 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].y() ); 751 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec3)[i].z() ); 752 } 753 break; 754 case ArrayNIndices::VEC4: 755 t->getFloat_array()->setCount( vertexAttributes[ti].vec4->size() *4 ); 756 t->getTechnique_common()->getAccessor()->setCount( vertexAttributes[ti].vec4->size() ); 757 for ( unsigned int i = 0; i < vertexAttributes[ti].vec4->size(); i++ ) 758 { 759 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].x() ); 760 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].y() ); 761 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].z() ); 762 t->getFloat_array()->getValue().append( (*vertexAttributes[ti].vec4)[i].w() ); 763 } 764 break; 765 default: 766 //##ti and not i 767 osg::notify( osg::WARN ) << "Invalid array type for vertex attribute" << ti << std::endl; 768 break; 769 } 770 vertexAttribute.push_back( t ); 771 } 772 else 773 { 774 osg::notify( osg::WARN ) << "Invalid array type for vertex attribute" << ti << std::endl; 775 } 380 776 } 381 777 … … 1136 1532 unsigned int offset = 0; 1137 1533 Ty *retVal = daeSafeCast< Ty >( mesh->add( type ) ); 1138 domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT));1534 domInputLocalOffset *ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 1139 1535 ilo->setOffset( offset++ ); 1140 ilo->setSemantic( COMMON_PROFILE_INPUT_VERTEX);1536 ilo->setSemantic( COMMON_PROFILE_INPUT_VERTEX ); 1141 1537 std::string url = "#" + std::string(mesh->getVertices()->getId()); 1142 1538 ilo->setSource( url.c_str() ); 1143 1539 if ( norm != NULL ) 1144 1540 { 1145 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT));1541 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 1146 1542 ilo->setOffset( offset++ ); 1147 ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL );1543 ilo->setSemantic( COMMON_PROFILE_INPUT_NORMAL ); 1148 1544 url = "#" + std::string( norm->getId() ); 1149 1545 ilo->setSource( url.c_str() ); … … 1151 1547 if ( color != NULL ) 1152 1548 { 1153 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT));1549 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 1154 1550 ilo->setOffset( offset++ ); 1155 ilo->setSemantic( COMMON_PROFILE_INPUT_COLOR);1551 ilo->setSemantic( COMMON_PROFILE_INPUT_COLOR ); 1156 1552 url = "#" + std::string( color->getId() ); 1157 1553 ilo->setSource( url.c_str() ); … … 1159 1555 for ( unsigned int i = 0; i < texcoord.size(); i++ ) 1160 1556 { 1161 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT));1557 ilo = daeSafeCast< domInputLocalOffset >( retVal->add( COLLADA_ELEMENT_INPUT ) ); 1162 1558 ilo->setOffset( offset++ ); 1163 ilo->setSemantic( COMMON_PROFILE_INPUT_TEXCOORD);1559 ilo->setSemantic( COMMON_PROFILE_INPUT_TEXCOORD ); 1164 1560 ilo->setSet( i ); 1165 1561 url = "#" + std::string( texcoord[i]->getId() ); -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWMaterials.cpp
r10234 r11129 29 29 #endif 30 30 31 using namespace osg dae;32 33 void daeWriter::processMaterial( osg::StateSet *ss, dom Instance_geometry *ig, const std::string &geoName )31 using namespace osgDAE; 32 33 void daeWriter::processMaterial( osg::StateSet *ss, domBind_material *pDomBindMaterial, const std::string &geoName ) 34 34 { 35 35 osg::ref_ptr<osg::StateSet> ssClean = CleanStateSet(ss); // Need to hold a ref to this or the materialMap.find() will delete it 36 domBind_material *bm = daeSafeCast< domBind_material >( ig->add( COLLADA_ELEMENT_BIND_MATERIAL ) ); 37 domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( bm->add(COLLADA_ELEMENT_TECHNIQUE_COMMON)); 38 domInstance_material *im = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) ); 36 domBind_material::domTechnique_common *tc = daeSafeCast< domBind_material::domTechnique_common >( pDomBindMaterial->add( COLLADA_ELEMENT_TECHNIQUE_COMMON ) ); 37 domInstance_material *pDomInstanceMaterial = daeSafeCast< domInstance_material >( tc->add( COLLADA_ELEMENT_INSTANCE_MATERIAL ) ); 39 38 std::string symbol = geoName + "_material"; 40 im->setSymbol( symbol.c_str() ); 41 39 pDomInstanceMaterial->setSymbol( symbol.c_str() ); 40 41 // See if material already exists in cache 42 42 MaterialMap::iterator iter = materialMap.find( ssClean ); 43 43 if ( iter != materialMap.end() ) 44 44 { 45 45 std::string url = "#" + std::string( iter->second->getId() ); 46 im->setTarget( url.c_str() );46 pDomInstanceMaterial->setTarget( url.c_str() ); 47 47 return; 48 48 } … … 64 64 65 65 std::string url = "#" + name; 66 im->setTarget( url.c_str() );66 pDomInstanceMaterial->setTarget( url.c_str() ); 67 67 68 68 domInstance_effect *ie = daeSafeCast<domInstance_effect>( mat->add( COLLADA_ELEMENT_INSTANCE_EFFECT ) ); … … 83 83 domProfile_COMMON::domTechnique *pc_teq = daeSafeCast< domProfile_COMMON::domTechnique >( pc->add( COLLADA_ELEMENT_TECHNIQUE ) ); 84 84 pc_teq->setSid( "t0" ); 85 domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add( COLLADA_ELEMENT_PHONG));85 domProfile_COMMON::domTechnique::domPhong *phong = daeSafeCast< domProfile_COMMON::domTechnique::domPhong >( pc_teq->add( COLLADA_ELEMENT_PHONG ) ); 86 86 87 87 osg::Texture *tex = static_cast<osg::Texture*>(ssClean->getTextureAttribute( 0, osg::StateAttribute::TEXTURE )); … … 98 98 99 99 osg::Image *osgimg = tex->getImage( 0 ); 100 domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add(COLLADA_ELEMENT_INIT_FROM)); 100 101 domImage::domInit_from *imgif = daeSafeCast< domImage::domInit_from >( img->add( COLLADA_ELEMENT_INIT_FROM ) ); 101 102 std::string fileURI = ReaderWriterDAE::ConvertFilePathToColladaCompatibleURI(osgDB::findDataFile(osgimg->getFileName())); 102 daeURI dd(*dae, fileURI);//fileURI.c_str());103 daeURI dd(*dae, fileURI); 103 104 imgif->setValue( dd ); 104 105 // The document URI should contain the canonical path it was created with 105 106 imgif->getValue().makeRelativeTo(doc->getDocumentURI()); 106 107 108 107 109 #ifndef EARTH_TEX 108 domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM));110 domCommon_newparam_type *np = daeSafeCast< domCommon_newparam_type >( pc->add(COLLADA_ELEMENT_NEWPARAM) ); 109 111 std::string surfName = efName + "-surface"; 110 112 np->setSid( surfName.c_str() ); 111 domFx_surface_common *surface = daeSafeCast< domFx_surface_common >( np->add(COLLADA_ELEMENT_SURFACE));112 domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add(COLLADA_ELEMENT_INIT_FROM) );113 domFx_surface_common *surface = daeSafeCast< domFx_surface_common >( np->add(COLLADA_ELEMENT_SURFACE) ); 114 domFx_surface_init_from_common *sif = daeSafeCast< domFx_surface_init_from_common >( surface->add(COLLADA_ELEMENT_INIT_FROM) ); 113 115 sif->setValue( iName.c_str() ); 114 116 surface->setType( FX_SURFACE_TYPE_ENUM_2D ); 115 117 116 np = daeSafeCast< domCommon_newparam_type >( pc->add( COLLADA_ELEMENT_NEWPARAM));118 np = daeSafeCast< domCommon_newparam_type >( pc->add( COLLADA_ELEMENT_NEWPARAM ) ); 117 119 std::string sampName = efName + "-sampler"; 118 120 np->setSid( sampName.c_str() ); 119 domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add( COLLADA_ELEMENT_SAMPLER2D) );120 domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >( sampler->add(COLLADA_ELEMENT_SOURCE));121 domFx_sampler2D_common *sampler = daeSafeCast< domFx_sampler2D_common >( np->add( COLLADA_ELEMENT_SAMPLER2D ) ); 122 domFx_sampler2D_common_complexType::domSource *source = daeSafeCast< domFx_sampler2D_common_complexType::domSource >( sampler->add( COLLADA_ELEMENT_SOURCE ) ); 121 123 source->setValue( surfName.c_str() ); 122 124 123 125 //set sampler state 124 domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->add(COLLADA_ELEMENT_WRAP_S));126 domFx_sampler2D_common_complexType::domWrap_s *wrap_s = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_s >( sampler->add( COLLADA_ELEMENT_WRAP_S ) ); 125 127 osg::Texture::WrapMode wrap = tex->getWrap( osg::Texture::WRAP_S ); 126 128 switch( wrap ) … … 144 146 } 145 147 146 domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >( sampler->add( COLLADA_ELEMENT_WRAP_T));148 domFx_sampler2D_common_complexType::domWrap_t *wrap_t = daeSafeCast< domFx_sampler2D_common_complexType::domWrap_t >( sampler->add( COLLADA_ELEMENT_WRAP_T ) ); 147 149 wrap = tex->getWrap( osg::Texture::WRAP_T ); 148 150 switch( wrap ) … … 167 169 168 170 const osg::Vec4 &bcol = tex->getBorderColor(); 169 domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >( sampler->add(COLLADA_ELEMENT_BORDER_COLOR));171 domFx_sampler2D_common_complexType::domBorder_color *dbcol = daeSafeCast< domFx_sampler2D_common_complexType::domBorder_color >( sampler->add( COLLADA_ELEMENT_BORDER_COLOR ) ); 170 172 dbcol->getValue().append( bcol.r() ); 171 173 dbcol->getValue().append( bcol.g() ); … … 173 175 dbcol->getValue().append( bcol.a() ); 174 176 175 domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >( sampler->add(COLLADA_ELEMENT_MINFILTER));177 domFx_sampler2D_common_complexType::domMinfilter *minfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMinfilter >( sampler->add( COLLADA_ELEMENT_MINFILTER ) ); 176 178 osg::Texture::FilterMode mode = tex->getFilter( osg::Texture::MIN_FILTER ); 177 179 switch( mode ) … … 197 199 } 198 200 199 domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >( sampler->add(COLLADA_ELEMENT_MAGFILTER));201 domFx_sampler2D_common_complexType::domMagfilter *magfilter = daeSafeCast< domFx_sampler2D_common_complexType::domMagfilter >( sampler->add( COLLADA_ELEMENT_MAGFILTER ) ); 200 202 mode = tex->getFilter( osg::Texture::MAG_FILTER ); 201 203 switch( mode ) … … 222 224 223 225 224 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE) );225 domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add(COLLADA_ELEMENT_TEXTURE));226 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 227 domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( COLLADA_ELEMENT_TEXTURE ) ); 226 228 dtex->setTexture( sampName.c_str() ); 227 229 dtex->setTexcoord( "texcoord0" ); 228 230 #else 229 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE) );230 domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( COLLADA_ELEMENT_TEXTURE));231 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 232 domCommon_color_or_texture_type_complexType::domTexture *dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( cot->add( COLLADA_ELEMENT_TEXTURE ) ); 231 233 dtex->setTexture( iName.c_str() ); 232 234 dtex->setTexcoord( "texcoord0" ); 233 235 #endif 234 236 235 domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( im->add(COLLADA_ELEMENT_BIND_VERTEX_INPUT));237 domInstance_material::domBind_vertex_input *bvi = daeSafeCast< domInstance_material::domBind_vertex_input >( pDomInstanceMaterial->add( COLLADA_ELEMENT_BIND_VERTEX_INPUT ) ); 236 238 bvi->setSemantic( "texcoord0" ); 237 bvi->setInput_semantic( "TEXCOORD");239 bvi->setInput_semantic( COMMON_PROFILE_INPUT_TEXCOORD ); 238 240 bvi->setInput_set( 0 ); 239 241 } … … 247 249 float shininess = osgmat->getShininessFrontAndBack()?osgmat->getShininess( osg::Material::FRONT_AND_BACK ):osgmat->getShininess( osg::Material::FRONT ); 248 250 249 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_EMISSION));250 domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR));251 domCommon_color_or_texture_type *cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_EMISSION ) ); 252 domCommon_color_or_texture_type_complexType::domColor *col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 251 253 col->getValue().append( eCol.r() ); 252 254 col->getValue().append( eCol.g() ); … … 254 256 col->getValue().append( eCol.a() ); 255 257 256 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_AMBIENT));257 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add(COLLADA_ELEMENT_COLOR));258 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_AMBIENT ) ); 259 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 258 260 col->getValue().append( aCol.r() ); 259 261 col->getValue().append( aCol.g() ); … … 265 267 if ( phong->getDiffuse() == NULL ) 266 268 { 267 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE));268 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR));269 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_DIFFUSE ) ); 270 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 269 271 col->getValue().append( dCol.r() ); 270 272 col->getValue().append( dCol.g() ); … … 291 293 domTechnique *teq = daeSafeCast< domTechnique >( extra->add( COLLADA_ELEMENT_TECHNIQUE ) ); 292 294 teq->setProfile( "SCEI" ); 293 domAny *any = (domAny*)(daeElement*)teq->add( COLLADA_ELEMENT_COLOR);295 domAny *any = (domAny*)(daeElement*)teq->add( COLLADA_ELEMENT_COLOR ); 294 296 295 297 std::ostringstream colVal; … … 299 301 } 300 302 301 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_SPECULAR));302 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR));303 cot = daeSafeCast< domCommon_color_or_texture_type >( phong->add( COLLADA_ELEMENT_SPECULAR ) ); 304 col = daeSafeCast< domCommon_color_or_texture_type_complexType::domColor >( cot->add( COLLADA_ELEMENT_COLOR ) ); 303 305 col->getValue().append( sCol.r() ); 304 306 col->getValue().append( sCol.g() ); … … 306 308 col->getValue().append( sCol.a() ); 307 309 308 domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add( COLLADA_ELEMENT_SHININESS));309 domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add(COLLADA_ELEMENT_FLOAT) );310 domCommon_float_or_param_type *fop = daeSafeCast< domCommon_float_or_param_type >( phong->add( COLLADA_ELEMENT_SHININESS ) ); 311 domCommon_float_or_param_type_complexType::domFloat *f = daeSafeCast< domCommon_float_or_param_type_complexType::domFloat >( fop->add(COLLADA_ELEMENT_FLOAT) ); 310 312 f->setValue( shininess ); 311 313 } … … 365 367 else if (tex != NULL && tex->getImage( 0 ) != NULL) 366 368 { 367 domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add(COLLADA_ELEMENT_TRANSPARENT) );369 domCommon_transparent_type *ctt = daeSafeCast< domCommon_transparent_type >( phong->add(COLLADA_ELEMENT_TRANSPARENT) ); 368 370 ctt->setOpaque( FX_OPAQUE_ENUM_A_ONE ); 369 domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE) );371 domCommon_color_or_texture_type_complexType::domTexture * dtex = daeSafeCast< domCommon_color_or_texture_type_complexType::domTexture >( ctt->add(COLLADA_ELEMENT_TEXTURE) ); 370 372 371 373 #ifndef EARTH_TEX -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWSceneObjects.cpp
r10234 r11129 29 29 #include <osg/CameraView> 30 30 31 using namespace osg dae;31 using namespace osgDAE; 32 32 33 33 // Write non-standard node data as extra of type "Node" with "OpenSceneGraph" technique … … 129 129 else 130 130 { 131 writeAnimations(node); 132 131 133 currentNode->setId(getNodeName(node,"group").c_str()); 132 134 } … … 354 356 debugPrint( node ); 355 357 356 domInstance_light * pDomInstanceLight = daeSafeCast< domInstance_light >( currentNode->add(COLLADA_ELEMENT_INSTANCE_LIGHT));358 domInstance_light *il = daeSafeCast< domInstance_light >( currentNode->add( COLLADA_ELEMENT_INSTANCE_LIGHT ) ); 357 359 std::string name = node.getName(); 358 360 if ( name.empty() ) … … 361 363 } 362 364 std::string url = "#" + name; 363 pDomInstanceLight->setUrl( url.c_str() );365 il->setUrl( url.c_str() ); 364 366 365 367 if ( lib_lights == NULL ) … … 367 369 lib_lights = daeSafeCast< domLibrary_lights >( dom->add( COLLADA_ELEMENT_LIBRARY_LIGHTS ) ); 368 370 } 371 domLight *light = daeSafeCast< domLight >( lib_lights->add( COLLADA_ELEMENT_LIGHT ) ); 372 light->setId( name.c_str() ); 369 373 370 374 osg::Light* pOsgLight = node.getLight(); -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWTransforms.cpp
r9476 r11129 2 2 * Copyright 2006 Sony Computer Entertainment Inc. 3 3 * 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 5 5 * file except in compliance with the License. You may obtain a copy of the License at: 6 6 * http://research.scea.com/scea_shared_source_license.html 7 7 * 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 12 12 */ 13 13 … … 20 20 #include <dae/domAny.h> 21 21 22 #include <osgAnimation/Bone> 22 23 #include <osgSim/DOFTransform> 23 24 24 using namespace osgdae; 25 using namespace osgDAE; 26 27 28 void daeWriter::writeUpdateTransformElements(const osg::Vec3 &pos, const osg::Quat &q, const osg::Vec3 &s) 29 { 30 // Make a scale place element 31 domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) ); 32 scale->setSid("scale"); 33 scale->getValue().append3( s.x(), s.y(), s.z() ); 34 35 // Make a three rotate place elements for the euler angles 36 // TODO decompose quaternion into three euler angles 37 double angle; 38 osg::Vec3 axis; 39 q.getRotate( angle, axis ); 40 41 domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 42 rot->setSid("rotateZ"); 43 rot->getValue().append4( 0, 0, 1, osg::RadiansToDegrees(angle) ); 44 45 rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 46 rot->setSid("rotateY"); 47 rot->getValue().append4( 0, 1, 0, osg::RadiansToDegrees(angle) ); 48 49 rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 50 rot->setSid("rotateX"); 51 rot->getValue().append4( 1, 0, 0, osg::RadiansToDegrees(angle) ); 52 53 // Make a translate place element 54 domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 55 trans->setSid("translate"); 56 trans->getValue().append3( pos.x(), pos.y(), pos.z() ); 57 } 25 58 26 59 //MATRIX … … 39 72 40 73 currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 41 currentNode->setId(getNodeName(node,"matrixTransform").c_str()); 42 43 domMatrix *mat = daeSafeCast< domMatrix >(currentNode->add( COLLADA_ELEMENT_MATRIX ) ); 44 const osg::Matrix::value_type *mat_vals = node.getMatrix().ptr(); 45 //for ( int i = 0; i < 16; i++ ) 46 //{ 47 // mat->getValue().append( mat_vals[i] ); 48 //} 49 mat->getValue().append( mat_vals[0] ); 50 mat->getValue().append( mat_vals[4] ); 51 mat->getValue().append( mat_vals[8] ); 52 mat->getValue().append( mat_vals[12] ); 53 mat->getValue().append( mat_vals[1] ); 54 mat->getValue().append( mat_vals[5] ); 55 mat->getValue().append( mat_vals[9] ); 56 mat->getValue().append( mat_vals[13] ); 57 mat->getValue().append( mat_vals[2] ); 58 mat->getValue().append( mat_vals[6] ); 59 mat->getValue().append( mat_vals[10] ); 60 mat->getValue().append( mat_vals[14] ); 61 mat->getValue().append( mat_vals[3] ); 62 mat->getValue().append( mat_vals[7] ); 63 mat->getValue().append( mat_vals[11] ); 64 mat->getValue().append( mat_vals[15] ); 74 std::string nodeName = getNodeName(node,"matrixTransform"); 75 currentNode->setId(nodeName.c_str()); 76 77 osg::NodeCallback* ncb = node.getUpdateCallback(); 78 bool handled = false; 79 if (ncb) 80 { 81 osgAnimation::UpdateMatrixTransform* ut = dynamic_cast<osgAnimation::UpdateMatrixTransform*>(ncb); 82 // If targeted by an animation we split up the matrix into multiple place element so they can be targeted individually 83 if (ut) 84 { 85 handled = true; 86 87 const osg::Matrix &mat = node.getMatrix(); 88 89 // Note: though this is a generic matrix, based on the fact that it will be animated by and UpdateMatrixTransform, 90 // we assume the initial matrix can be decomposed into translation, rotation and scale elements 91 writeUpdateTransformElements(mat.getTrans(), mat.getRotate(), mat.getScale()); 92 } 93 } 94 95 // If not targeted by an animation simply write a single matrix place element 96 if (!handled) 97 { 98 domMatrix *mat = daeSafeCast< domMatrix >(currentNode->add( COLLADA_ELEMENT_MATRIX ) ); 99 nodeName += "_matrix"; 100 mat->setSid(nodeName.c_str()); 101 102 const osg::Matrix::value_type *mat_vals = node.getMatrix().ptr(); 103 for ( int i = 0; i < 4; i++ ) 104 { 105 for ( int j = 0; j < 4; j++ ) 106 { 107 mat->getValue().append( mat_vals[i + j*4] ); 108 } 109 } 110 } 65 111 66 112 lastDepth = _nodePath.size(); … … 85 131 } 86 132 currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 87 currentNode->setId(getNodeName(node,"positionAttitudeTransform").c_str()); 88 133 std::string nodeName = getNodeName(node,"positionAttitudeTransform"); 134 currentNode->setId(nodeName.c_str()); 135 89 136 const osg::Vec3 &pos = node.getPosition(); 90 137 const osg::Quat &q = node.getAttitude(); 91 138 const osg::Vec3 &s = node.getScale(); 92 139 93 if ( pos.x() != 0 || pos.y() != 0 || pos.z() != 0 ) 94 { 95 //make a translate 96 domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 97 trans->getValue().append( pos.x() ); 98 trans->getValue().append( pos.y() ); 99 trans->getValue().append( pos.z() ); 100 } 101 102 double angle; 103 osg::Vec3 axis; 104 q.getRotate( angle, axis ); 105 if ( angle != 0 ) 106 { 107 //make a rotate 108 domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 109 rot->getValue().append( axis.x() ); 110 rot->getValue().append( axis.y() ); 111 rot->getValue().append( axis.z() ); 112 rot->getValue().append( osg::RadiansToDegrees(angle) ); 113 } 140 osg::NodeCallback* ncb = node.getUpdateCallback(); 141 bool handled = false; 142 if (ncb) 143 { 144 osgAnimation::UpdateMatrixTransform* ut = dynamic_cast<osgAnimation::UpdateMatrixTransform*>(ncb); 145 // If targeted by an animation we split up the matrix into multiple place element so they can be targeted individually 146 if (ut) 147 { 148 handled = true; 149 150 writeUpdateTransformElements(pos, q, s); 151 } 152 } 153 154 // If not targeted by an animation simply add the elements that actually contribute to placement 155 if (!handled) 156 { 157 if ( s.x() != 1 || s.y() != 1 || s.z() != 1 ) 158 { 159 // Make a scale place element 160 domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) ); 161 scale->setSid("scale"); 162 scale->getValue().append3( s.x(), s.y(), s.z() ); 163 } 164 165 double angle; 166 osg::Vec3 axis; 167 q.getRotate( angle, axis ); 168 if ( angle != 0 ) 169 { 170 // Make a rotate place element 171 domRotate *rot = daeSafeCast< domRotate >( currentNode->add( COLLADA_ELEMENT_ROTATE ) ); 172 rot->setSid("rotate"); 173 rot->getValue().append4( axis.x(), axis.y(), axis.z(), osg::RadiansToDegrees(angle) ); 174 } 114 175 115 176 if ( s.x() != 1 || s.y() != 1 || s.z() != 1 ) 116 {117 //make a scale118 domScale *scale = daeSafeCast< domScale >( currentNode->add( COLLADA_ELEMENT_SCALE ) );119 scale->getValue().append( s.x());120 scale->getValue().append( s.y() );121 scale->getValue().append( s.z() );177 { 178 // Make a translate place element 179 domTranslate *trans = daeSafeCast< domTranslate >( currentNode->add( COLLADA_ELEMENT_TRANSLATE ) ); 180 trans->setSid("translate"); 181 trans->getValue().append3( pos.x(), pos.y(), pos.z() ); 182 } 122 183 } 123 184 … … 129 190 } 130 191 131 void daeWriter::apply( osg::Transform &node ) 192 void daeWriter::apply( osg::Transform &node ) 132 193 { 133 194 debugPrint( node ); … … 140 201 } 141 202 currentNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE ) ); 142 203 143 204 // If a DOFTransform node store it's data as extra "DOFTransform" data in the "OpenSceneGraph" technique 144 205 osgSim::DOFTransform* dof = dynamic_cast<osgSim::DOFTransform*>(&node); … … 224 285 225 286 domAny *putMatrix = (domAny*)teq->add("PutMatrix" ); 226 putMatrix->setValue(toString(dof->getPutMatrix()).c_str()); 287 putMatrix->setValue(toString(dof->getPutMatrix()).c_str()); 227 288 228 289 currentNode->setId(getNodeName(node, "doftransform").c_str()); … … 230 291 else 231 292 { 232 currentNode->setId(getNodeName(node, "transform").c_str()); 233 osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children" << std::endl; 293 osgAnimation::Bone* bone = dynamic_cast<osgAnimation::Bone*>(&node); 294 if (bone) 295 { 296 domNode *pDomNode = daeSafeCast< domNode >(currentNode->add( COLLADA_ELEMENT_NODE )); 297 pDomNode->setType(NODETYPE_JOINT); 298 pDomNode->setId(getNodeName(node, "bone").c_str()); 299 } 300 else 301 { 302 currentNode->setId(getNodeName(node, "transform").c_str()); 303 osg::notify( osg::WARN ) << "some other transform type. Missing " << node.getNumChildren() << " children" << std::endl; 304 } 234 305 } 235 306 … … 241 312 } 242 313 243 void daeWriter::apply( osg::CoordinateSystemNode &node ) 314 void daeWriter::apply( osg::CoordinateSystemNode &node ) 244 315 { 245 316 osg::notify( osg::WARN ) << "CoordinateSystemNode. Missing " << node.getNumChildren() << " children" << std::endl; 246 317 } 318 319 -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWriter.cpp
r10295 r11129 22 22 23 23 24 namespace osgdae { 25 26 std::string toString(osg::Vec3f value) 27 { 28 std::stringstream str; 29 str << value.x() << " " << value.y() << " " << value.z(); 30 return str.str(); 31 } 32 33 std::string toString(osg::Vec3d value) 24 namespace osgDAE { 25 26 std::string toString(osg::Vec3 value) 34 27 { 35 28 std::stringstream str; … … 51 44 daeWriter::daeWriter( DAE *dae_, const std::string &fileURI, bool _usePolygons, bool GoogleMode, TraversalMode tm, bool _writeExtras) : osg::NodeVisitor( tm ), 52 45 dae(dae_), 46 _domLibraryAnimations(NULL), 53 47 writeExtras(_writeExtras), 54 48 rootName(*dae_), 55 49 usePolygons (_usePolygons), 56 m_GoogleMode(GoogleMode), 57 m_CurrentRenderingHint(osg::StateSet::DEFAULT_BIN) 50 m_GoogleMode(GoogleMode) 58 51 { 59 52 success = true; … … 65 58 dom = (domCOLLADA*)doc->getDomRoot(); 66 59 //create scene and instance visual scene 67 domCOLLADA::domScene *scene = daeSafeCast< domCOLLADA::domScene >( dom->add( COLLADA_ELEMENT_SCENE));68 domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->add( COLLADA_ELEMENT_INSTANCE_VISUAL_SCENE));60 domCOLLADA::domScene *scene = daeSafeCast< domCOLLADA::domScene >( dom->add( COLLADA_ELEMENT_SCENE ) ); 61 domInstanceWithExtra *ivs = daeSafeCast< domInstanceWithExtra >( scene->add( COLLADA_ELEMENT_INSTANCE_VISUAL_SCENE ) ); 69 62 ivs->setUrl( "#defaultScene" ); 70 63 //create library visual scenes and a visual scene and the root node 71 lib_vis_scenes = daeSafeCast<domLibrary_visual_scenes>( dom->add( COLLADA_ELEMENT_LIBRARY_VISUAL_SCENES));72 vs = daeSafeCast< domVisual_scene >( lib_vis_scenes->add( COLLADA_ELEMENT_VISUAL_SCENE));64 lib_vis_scenes = daeSafeCast<domLibrary_visual_scenes>( dom->add( COLLADA_ELEMENT_LIBRARY_VISUAL_SCENES ) ); 65 vs = daeSafeCast< domVisual_scene >( lib_vis_scenes->add( COLLADA_ELEMENT_VISUAL_SCENE ) ); 73 66 vs->setId( "defaultScene" ); 74 67 currentNode = daeSafeCast< domNode >( vs->add( COLLADA_ELEMENT_NODE ) ); … … 80 73 lib_cameras = NULL; 81 74 lib_effects = NULL; 75 lib_controllers = NULL; 82 76 lib_geoms = NULL; 83 77 lib_lights = NULL; … … 85 79 86 80 lastDepth = 0; 81 82 // Clean up caches 83 uniqueNames.clear(); 87 84 88 85 currentStateSet = new osg::StateSet(); … … 105 102 } 106 103 107 bool daeWriter::writeFile()108 {109 if ( dae->save( (daeUInt)0 ) != DAE_OK )110 {111 success = false;112 }113 return success;114 }115 104 116 105 void daeWriter::setRootNode( const osg::Node &node ) 117 106 { 118 107 std::string fname = osgDB::findDataFile( node.getName() ); 119 //rootName = fname.c_str(); 120 //rootName.validate();108 109 const_cast<osg::Node*>(&node)->accept( _animatedNodeCollector ); 121 110 } 122 111 … … 167 156 domAsset::domModified *m = daeSafeCast< domAsset::domModified >(asset->add(COLLADA_ELEMENT_MODIFIED)); 168 157 domAsset::domUnit *u = daeSafeCast< domAsset::domUnit >(asset->add(COLLADA_ELEMENT_UNIT)); 158 domAsset::domUp_axis *up = daeSafeCast< domAsset::domUp_axis >(asset->add(COLLADA_ELEMENT_UP_AXIS)); 159 up->setValue(UPAXISTYPE_Z_UP); 169 160 170 161 //TODO : set date and time -
OpenSceneGraph/trunk/src/osgPlugins/dae/daeWriter.h
r10295 r11129 2 2 * Copyright 2006 Sony Computer Entertainment Inc. 3 3 * 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 4 * Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this 5 5 * file except in compliance with the License. You may obtain a copy of the License at: 6 6 * http://research.scea.com/scea_shared_source_license.html 7 7 * 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 8 * Unless required by applicable law or agreed to in writing, software distributed under the License 9 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 10 * implied. See the License for the specific language governing permissions and limitations under the 11 * License. 12 12 */ 13 13 … … 41 41 #include <osgDB/Registry> 42 42 #include <osgSim/MultiSwitch> 43 #include <osgAnimation/AnimationManagerBase> 44 #include <osgAnimation/UpdateBone> 45 #include <osgAnimation/RigGeometry> 46 #include <osgAnimation/MorphGeometry> 43 47 44 48 #include <dae.h> 45 49 #include <dae/daeDocument.h> 50 #include <dom/domChannel.h> 46 51 47 52 … … 55 60 class domLibrary_materials; 56 61 class domLibrary_visual_scenes; 62 class domLibrary_animations; 57 63 class domMaterial; 58 64 class domMesh; … … 62 68 class domP; 63 69 64 namespace osg dae{70 namespace osgDAE { 65 71 66 72 /// Convert value to string using it's stream operator … … 75 81 std::string toString(osg::Vec3d value); 76 82 std::string toString(osg::Matrix value); 77 83 84 // Collects all nodes that are targeted by an animation 85 class FindAnimatedNodeVisitor : public osg::NodeVisitor 86 { 87 public: 88 FindAnimatedNodeVisitor(): 89 osg::NodeVisitor(osg::NodeVisitor::TRAVERSE_ALL_CHILDREN) 90 {} 91 92 virtual void apply(osg::Node& node) 93 { 94 osg::NodeCallback* ncb = node.getUpdateCallback(); 95 if (ncb) 96 { 97 osgAnimation::AnimationUpdateCallback<osg::NodeCallback>* ut = dynamic_cast<osgAnimation::AnimationUpdateCallback<osg::NodeCallback>*>(ncb); 98 if (ut) 99 { 100 if (_updateCallbackNameNodeMap[ut->getName()] == NULL) 101 { 102 _updateCallbackNameNodeMap[ut->getName()] = &node; 103 } 104 else 105 { 106 // TODO store in a multimap and let the exporter create multiple <channel>s for each connected node 107 osg::notify( osg::WARN ) << "Multiple nodes using the same update callback not supported" << std::endl; 108 } 109 } 110 } 111 traverse(node); 112 } 113 114 osg::Node* getTargetNode(const std::string& targetName) 115 { 116 UpdateCallbackNameNodeMap::iterator it = _updateCallbackNameNodeMap.find(targetName); 117 if (it != _updateCallbackNameNodeMap.end()) 118 { 119 return it->second; 120 } 121 return NULL; 122 } 123 124 private: 125 typedef std::map< std::string, osg::Node*> UpdateCallbackNameNodeMap; 126 UpdateCallbackNameNodeMap _updateCallbackNameNodeMap; 127 }; 128 78 129 /** 79 130 @class daeWriter 80 @brief Write a OSG scene into a DAE file 81 */ 131 @brief Write a OSG scene into a DAE file 132 */ 82 133 class daeWriter : public osg::NodeVisitor 83 134 { … … 117 168 //virtual void apply( osg::OccluderNode &node) 118 169 170 void traverse (osg::Node &node); 171 172 173 174 175 protected: //methods 176 177 void writeAnimations(osg::Node& node); 119 178 void writeNodeExtra(osg::Node &node); 120 121 122 123 void traverse (osg::Node &node); 124 125 /*protected: 126 struct MeshData { 127 domMesh *mesh; 128 domSource *pos; 129 domSource *norm; 130 domSource *color; 131 std::vector< domSource * > texcoord; 132 std::string name; 133 };*/ 134 135 136 protected: //methods 179 void writeUpdateTransformElements(const osg::Vec3 &pos, const osg::Quat &q, const osg::Vec3 &s); 180 void writeRigGeometry(osgAnimation::RigGeometry *pOsgRigGeometry); 181 void writeMorphGeometry(osgAnimation::MorphGeometry *pOsgMorphGeometry); 182 137 183 void debugPrint( osg::Node &node ); 138 139 184 185 domGeometry* getOrCreateDomGeometry(osg::Geometry* pOsgGeometry); 140 186 bool processGeometry( osg::Geometry *geom, domGeometry *geo, const std::string &name ); 141 187 domSource* createSource( daeElement *parent, const std::string &baseName, int size, bool color = false, bool uv = false ); … … 143 189 Ty *createPrimGroup( daeString type, domMesh *mesh, domSource *norm, domSource *color, const std::vector< domSource* > &texcoord ); 144 190 145 void processMaterial( osg::StateSet *ss, dom Instance_geometry *ig, const std::string &geoName );191 void processMaterial( osg::StateSet *ss, domBind_material *pDomBindMaterial, const std::string &geoName ); 146 192 147 193 void createAssetTag(); … … 157 203 domLibrary_cameras *lib_cameras; 158 204 domLibrary_effects *lib_effects; 205 domLibrary_controllers *lib_controllers; 159 206 domLibrary_geometries *lib_geoms; 160 207 domLibrary_lights *lib_lights; 161 208 domLibrary_materials *lib_mats; 162 209 domLibrary_visual_scenes *lib_vis_scenes; 210 domLibrary_animations* _domLibraryAnimations; 163 211 domNode *currentNode; 164 212 domVisual_scene *vs; … … 177 225 } 178 226 }; 179 180 227 228 229 typedef std::map< osg::ref_ptr<osg::StateSet>, domMaterial *, CompareStateSet> MaterialMap; 230 typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack; 231 typedef std::map< osg::Geometry*, domGeometry *> OsgGeometryDomGeometryMap; 232 typedef std::map< osgAnimation::RigGeometry*, domController *> OsgRigGeometryDomControllerMap; 233 typedef std::map< osgAnimation::MorphGeometry*, domController *> OsgMorphGeometryDomControllerMap; 181 234 182 235 std::map< std::string, int > uniqueNames; 183 184 std::map< osg::Geometry*, domGeometry * > geometryMap; 185 186 typedef std::map< osg::ref_ptr<osg::StateSet>, domMaterial *, CompareStateSet> MaterialMap; 236 OsgGeometryDomGeometryMap geometryMap; 237 OsgRigGeometryDomControllerMap _osgRigGeometryDomControllerMap; 238 OsgMorphGeometryDomControllerMap _osgMorphGeometryDomControllerMap; 187 239 188 240 MaterialMap materialMap; 189 190 typedef std::stack<osg::ref_ptr<osg::StateSet> > StateSetStack;191 192 241 StateSetStack stateSetStack; 193 242 … … 201 250 202 251 protected: //inner classes 203 class ArrayNIndices 252 class ArrayNIndices 204 253 { 205 254 public: … … 238 287 239 288 private: //members 240 289 241 290 /** append elements (verts, normals, colors and texcoord) for file write */ 242 291 void appendGeometryIndices(osg::Geometry *geom, … … 254 303 /** provide a name to node */ 255 304 std::string getNodeName(const osg::Node & node,const std::string & defaultName); 256 305 257 306 /** provide an unique name */ 258 307 std::string uniquify( const std::string &name ); … … 264 313 /** This are needed because the stateSet merge code currently does not handle it */ 265 314 int m_CurrentRenderingHint; 315 316 FindAnimatedNodeVisitor _animatedNodeCollector; 266 317 }; 267 318 -
OpenSceneGraph/trunk/src/osgPlugins/dae/domSourceReader.cpp
r5465 r11129 16 16 #include <dom/domSource.h> 17 17 18 using namespace osg dae;18 using namespace osgDAE; 19 19 20 20 domSourceReader::domSourceReader() : m_array_type( None ), m_count( 0 ) … … 33 33 m_count = accessor->getCount(); 34 34 35 switch ( stride ) { 35 // Only handle floats or name array for now... 36 daeDoubleArray* float_array = NULL; 37 if (src->getFloat_array()) 38 { 39 float_array = &(src->getFloat_array()->getValue()); 40 } 41 else if (src->getName_array()) 42 { 43 m_array_type = String; 44 return; 45 } 46 47 switch (stride) 48 { 36 49 case 1: 37 50 m_array_type = Float; … … 50 63 m_vec4_array = new osg::Vec4Array(); 51 64 break; 65 case 16: 66 m_array_type = Matrix; 67 m_matrix_array = new osg::MatrixfArray(); 68 break; 52 69 default: 53 70 osg::notify(osg::WARN)<<"Unsupported stride: "<<stride<<std::endl; … … 55 72 } 56 73 57 // Only handle floats for now... 58 daeDoubleArray* float_array = NULL; 59 if ( src->getFloat_array() != NULL ) { 60 float_array = &(src->getFloat_array()->getValue()); 61 } 62 if ( !float_array ) { 63 osg::notify(osg::WARN)<<"No float array found"<<std::endl; 64 return; 65 } 66 67 daeDoubleArray& va = *float_array; 68 for ( size_t i = 0; i < accessor->getCount(); i++ ) { 69 switch ( accessor->getStride() ) { 70 case 1: 71 m_float_array->push_back( va[i] ); 72 break; 73 case 2: 74 m_vec2_array->push_back( osg::Vec2( va[i*2], va[i*2+1] ) ); 75 break; 76 case 3: 77 m_vec3_array->push_back( osg::Vec3( va[i*3], va[i*3+1], va[i*3+2] ) ); 78 break; 79 case 4: 80 m_vec4_array->push_back( osg::Vec4( va[i*4], va[i*4+1], va[i*4+2], va[i*4+3] ) ); 81 break; 82 default: 83 osg::notify(osg::WARN)<<"Unsupported stride in Source: "<<accessor->getStride()<<std::endl; 84 return; 74 if (float_array) 75 { 76 daeDoubleArray& va = *float_array; 77 for ( size_t i = 0; i < accessor->getCount(); i++ ) 78 { 79 switch ( accessor->getStride() ) 80 { 81 case 1: 82 m_float_array->push_back(va[i]); 83 break; 84 case 2: 85 m_vec2_array->push_back( osg::Vec2( va[i*2], va[i*2+1])); 86 break; 87 case 3: 88 m_vec3_array->push_back( osg::Vec3( va[i*3], va[i*3+1], va[i*3+2])); 89 break; 90 case 4: 91 m_vec4_array->push_back( osg::Vec4( va[i*4], va[i*4+1], va[i*4+2], va[i*4+3])); 92 break; 93 case 16: 94 m_matrix_array->push_back(osg::Matrixf( va[i*16+0], va[i*16+4], va[i*16+8], va[i*16+12], 95 va[i*16+1], va[i*16+5], va[i*16+9], va[i*16+13], 96 va[i*16+2], va[i*16+6], va[i*16+10], va[i*16+14], 97 va[i*16+3], va[i*16+7], va[i*16+11], va[i*16+15])); 98 break; 99 default: 100 osg::notify(osg::WARN) << "Unsupported stride in Source: " << accessor->getStride() << std::endl; 101 return; 102 } 85 103 } 86 104 } 105 else 106 { 107 osg::notify(osg::WARN) << "No float array found" << std::endl; 108 } 87 109 } -
OpenSceneGraph/trunk/src/osgPlugins/dae/domSourceReader.h
r5465 r11129 20 20 class domSource; 21 21 22 namespace osg dae{22 namespace osgDAE { 23 23 24 24 /** … … 29 29 { 30 30 public: 31 enum ArrayType {None,Float,Vec2,Vec3,Vec4 };31 enum ArrayType {None,Float,Vec2,Vec3,Vec4,Matrix,String}; 32 32 33 33 public: … … 45 45 46 46 osg::Vec4Array* getVec4Array() { return m_vec4_array.get(); }; 47 47 48 osg::MatrixfArray* getMatrixArray() { return m_matrix_array.get(); }; 49 48 50 int getCount() const { return m_count; }; 49 51 … … 58 60 osg::Vec4 const& getVec4( int index ) { ASSERT_TYPE( Vec4 ); return (*m_vec4_array)[index]; }; 59 61 62 osg::Matrixf const& getMatrix( int index ) { ASSERT_TYPE( Matrix ); return (*m_matrix_array)[index]; }; 63 60 64 #undef ASSERT_TYPE 61 65 … … 69 73 osg::ref_ptr<osg::Vec3Array> m_vec3_array; 70 74 osg::ref_ptr<osg::Vec4Array> m_vec4_array; 75 osg::ref_ptr<osg::MatrixfArray> m_matrix_array; 71 76 72 77 };
