//------------------------------ bool LibraryEffectsLoader::fillSamplerArray () { COLLADAFW::EffectCommon& commonEffect = *mCurrentEffect->getCommonEffects().back(); COLLADAFW::SamplerPointerArray& samplerArray = commonEffect.getSamplerPointerArray(); // Iterate over the list of used samplers in the current effect profile // and push them in the sampler array. size_t samplerCount = mEffectProfileSamplersMap.size(); samplerArray.reallocMemory(samplerCount); samplerArray.setCount(samplerCount); StringIndexMap::const_iterator it = mEffectProfileSamplersMap.begin (); while ( it != mEffectProfileSamplersMap.end () ) { String samplerSid = it->first; size_t samplerIndex = it->second; bool validSampler = false; SidSamplerInfoMap::iterator samplerIt = mEffectProfileSidSamplerInfoMap.find ( samplerSid ); if ( samplerIt == mEffectProfileSidSamplerInfoMap.end () ) { samplerIt = mEffectSidSamplerInfoMap.find ( samplerSid ); if ( samplerIt != mEffectSidSamplerInfoMap.end () ) validSampler = true; } else validSampler = true; if ( validSampler ) { SamplerInfo& samplerInfo = samplerIt->second; samplerInfo.id = samplerArray.getCount(); COLLADAFW::Sampler* sampler = samplerInfo.sampler; sampler->setSid(samplerSid); if ( !sampler->getSourceImage().isValid() ) { bool validSurface = false; SidSurfaceMap::const_iterator surfaceIt = mEffectProfileSidSurfaceMap.find( samplerInfo.surfaceSid ); if ( surfaceIt == mEffectProfileSidSurfaceMap.end() ) { surfaceIt = mEffectSidSurfaceMap.find( samplerInfo.surfaceSid ); if ( surfaceIt != mEffectSidSurfaceMap.end() ) validSurface = true; } else validSurface = true; if ( validSurface ) { const Surface& surface = surfaceIt->second; sampler->setSource(surface.imageUniqueId); // copy sampler into common effect samplerArray[samplerIndex] = sampler->clone(); } } else { samplerArray[samplerIndex] = sampler->clone(); } } else { // we a null sampler here, to ensure the index of all of the following sampler remain correct samplerArray[samplerIndex] = 0; if ( !handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, "No sampler for texture \"" + samplerSid + "\" defined!" )) return false; } ++it; } return true; }
//------------------------------ bool LibraryEffectsLoader::handleExtraEffectTextures( const COLLADAFW::PointerArray<COLLADAFW::TextureAttributes>& effectTextures ) { bool success = true; size_t countExtraTextures = effectTextures.getCount(); if( countExtraTextures == 0 ) return success; // switch ( mCurrentProfile ) // { // case PROFILE_COMMON: // { for( size_t iTexture = 0; iTexture < countExtraTextures; ++iTexture ) { COLLADAFW::TextureAttributes* textureAttributes = effectTextures[iTexture]; if( textureAttributes == 0 ) continue; // Check if the texture is referenced. const String& textureSid = textureAttributes->textureSampler; SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid); if ( it == mEffectProfileSidSamplerInfoMap.end() ) { it = mEffectSidSamplerInfoMap.find( textureSid ); if ( it == mEffectSidSamplerInfoMap.end() ) { String msg("Texture with sid \"" + textureSid + "\" not found"); if ( mCurrentEffect ) { msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\""; } msg += "."; success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg ); continue;; } } // Push the texture sid of the current sampler in the list of used samplers // of the current effect profile. size_t samplerIndex = 0; StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid); if ( samplerIt == mEffectProfileSamplersMap.end() ) { // This sid has not been used before. Add to map with next index samplerIndex = mNextSamplerIndex; mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++)); } else { // This sid is already in the map. Use its index samplerIndex = samplerIt->second; } // Initialize the texture element. //bumpMap.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) ); //texture id? textureAttributes->samplerId = samplerIndex; if ( !(textureAttributes->texCoord.empty()) ) textureAttributes->textureMapId = getTextureMapIdBySematic( textureAttributes->texCoord ); } // break; // } // } return success; }
//----------------------------- bool DocumentProcessor::createAndWriteSkinController( const Loader::InstanceControllerData& instanceControllerData, const COLLADAFW::UniqueId& controllerDataUniqueId, const COLLADAFW::UniqueId& sourceUniqueId, const StringList& sidsOrIds, bool resolveIds) { if ( !controllerDataUniqueId.isValid() ) return false; const URIList& skeletonRoots = instanceControllerData.skeletonRoots; NodeList joints; for ( StringList::const_iterator it = sidsOrIds.begin(); it != sidsOrIds.end(); ++it) { const String sidOrId = *it; bool jointFound = false; if ( resolveIds ) { const SidTreeNode* joint = resolveSid( sidOrId ); if ( joint ) { // the joint could be found if ( joint->getTargetType() == SidTreeNode::TARGETTYPECLASS_OBJECT ) { const COLLADAFW::Object* object = joint->getObjectTarget(); if ( object->getClassId() == COLLADAFW::Node::ID() ) { joints.push_back( (COLLADAFW::Node*)object ); jointFound = true; //search for the next joint } else { // we could resolve the sid, but is not a joint/node } } else { // we could resolve the sid, but is not a joint/node } } } else { for ( URIList::const_iterator skeletonIt = skeletonRoots.begin(); skeletonIt != skeletonRoots.end(); ++skeletonIt) { const COLLADABU::URI& skeletonUri = *skeletonIt; SidAddress sidAddress( skeletonUri, sidOrId ); const SidTreeNode* joint = resolveSid( sidAddress ); if ( joint ) { // the joint could be found if ( joint->getTargetType() != SidTreeNode::TARGETTYPECLASS_OBJECT ) { // we could resolve the sid, but is not a joint/node break; } const COLLADAFW::Object* object = joint->getObjectTarget(); if ( object->getClassId() != COLLADAFW::Node::ID() ) { // we could resolve the sid, but is not a joint/node break; } joints.push_back( (COLLADAFW::Node*)object ); jointFound = true; //search for the next joint break; } } } if ( !jointFound ) { std::stringstream msg; msg << "Could not resolve " << (resolveIds ? "id" : "sid") << " \""; msg << sidOrId << "\" referenced in skin controller."; if ( handleFWLError( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg.str() )) { return false; } } } COLLADAFW::SkinController skinController( createUniqueId(COLLADAFW::SkinController::ID())); COLLADAFW::UniqueIdArray &jointsUniqueIds = skinController.getJoints(); jointsUniqueIds.allocMemory( joints.size() ); jointsUniqueIds.setCount(joints.size()); size_t i = 0; NodeList::const_iterator it = joints.begin(); for ( ; it != joints.end(); ++it, ++i ) { const COLLADAFW::Node* node = *it; jointsUniqueIds[i] = node->getUniqueId(); } skinController.setSkinControllerData(controllerDataUniqueId); skinController.setSource(sourceUniqueId); bool success = true; // Check if we have already wrote a skin controller that describes the same controller, i.e. has same // source, skin data and joints. If so, do not write it again and reference the previously used in the // scene graph const COLLADAFW::SkinController* skinControllerToWrite = 0; Loader::SkinControllerSet::const_iterator skinControllerIt = mSkinControllerSet.find( skinController ); if ( skinControllerIt == mSkinControllerSet.end() ) { skinControllerToWrite = &skinController; success = writer()->writeController(skinControllerToWrite); mSkinControllerSet.insert( skinController ); } else { skinControllerToWrite = &(*skinControllerIt); } instanceControllerData.instanceController->setInstanciatedObjectId( skinControllerToWrite->getUniqueId() ); return success; }
//------------------------------ bool LibraryEffectsLoader::handleTexture( const texture__AttributeData& attributeData ) { bool success = true; switch ( mCurrentProfile ) { case PROFILE_COMMON: { // Get the current color or texture element. COLLADAFW::ColorOrTexture* colorOrTexture = getCurrentColorOrTexture ( true ); // Check if the texture is referenced. String textureSid = (const char *)attributeData.texture; SidSamplerInfoMap::const_iterator it = mEffectProfileSidSamplerInfoMap.find(textureSid); if ( it == mEffectProfileSidSamplerInfoMap.end() ) { it = mEffectSidSamplerInfoMap.find((const char*)attributeData.texture); if ( it == mEffectSidSamplerInfoMap.end() ) { String msg("Texture with sid \"" + textureSid + "\" not found"); if ( mCurrentEffect ) { msg += " in effect with id \"" + mCurrentEffect->getOriginalId() + "\""; } msg += "."; success = handleFWLError ( SaxFWLError::ERROR_UNRESOLVED_REFERENCE, msg ); break; } } // Push the texture sid of the current sampler in the list of used samplers // of the current effect profile. size_t samplerIndex = 0; StringIndexMap::const_iterator samplerIt = mEffectProfileSamplersMap.find(textureSid); if ( samplerIt == mEffectProfileSamplersMap.end() ) { // This sid has not been used before. Add to map with next index samplerIndex = mNextSamplerIndex; mEffectProfileSamplersMap.insert(std::make_pair(textureSid, mNextSamplerIndex++)); } else { // This sid is already in the map. Use its index samplerIndex = samplerIt->second; } // Initialize the texture element. /* const SamplerInfo& samplerInfo = it->second; */ /* UNUSED */ colorOrTexture->setType(COLLADAFW::ColorOrTexture::TEXTURE); COLLADAFW::Texture& texture = colorOrTexture->getTexture(); texture.setUniqueId ( createUniqueId(COLLADAFW::Texture::ID()) ); texture.setSamplerId( samplerIndex ); if ( attributeData.texcoord ) { texture.setTextureMapId( getTextureMapIdBySematic( attributeData.texcoord) ); texture.setTexcoord(attributeData.texcoord); } break; } /* PROFILE_BRIDGE, PROFILE_CG, PROFILE_GLES, PROFILE_GLES2, PROFILE_GLSL, PROFILE_COMMON, PROFILE_NONE */ default: break; } return success; }
//------------------------------ bool LibraryControllersLoader::begin__input____InputLocal( const input____InputLocal__AttributeData& attributeData ) { // we ignore inputs that don't have semantics or source if ( !attributeData.semantic || !attributeData.source ) { return true; } ControllerInputSemantics semantic = getControllerInputSemanticsBySemanticStr( attributeData.semantic ); if ( semantic == SEMANTIC_UNKNOWN ) { return true; } switch ( mCurrentControllerType ) { case SKIN_CONTROLLER: { switch ( semantic ) { case SEMANTIC_JOINT: { if ( !mCurrentSkinControllerData ) { break; } String sourceId = getIdFromURIFragmentType(attributeData.source); const StringList* nodeSidsOrIds = 0; bool isIdArray = false; StringListMap::const_iterator itSid = mJointSidsMap.find(sourceId); // check if the node sid array could be found if ( itSid != mJointSidsMap.end() ) { nodeSidsOrIds = &itSid->second; isIdArray = false; } else { // check if it is an id_array StringListMap::const_iterator itId = mJointIdsMap.find(sourceId); if ( itId != mJointIdsMap.end() ) { nodeSidsOrIds = &itId->second; isIdArray = true; } else { if ( !handleFWLError ( SaxFWLError::ERROR_SOURCE_NOT_FOUND, "Source with id \"" + sourceId + "\" in skin controller with id \"" + mOriginalId + "\" used in input with semantic SEMANTIC_JOINT could not be found!" )) return false; break; } } const COLLADAFW::UniqueId& controllerUniqueId = mCurrentSkinControllerData->getUniqueId(); addSkinDataJointSidsPair( controllerUniqueId, *nodeSidsOrIds, isIdArray); // try to write the SkinController here if ( ((getObjectFlags() & Loader::CONTROLLER_FLAG) != 0) && (mCurrentControllerSourceUniqueId.isValid()) ) { Loader::InstanceControllerDataList& instanceControllerDataList = getInstanceControllerDataListByControllerUniqueId(controllerUniqueId); Loader::InstanceControllerDataList::iterator listIt = instanceControllerDataList.begin(); while ( listIt != instanceControllerDataList.end() ) { const Loader::InstanceControllerData& instanceControllerData = *listIt; bool success = getFileLoader()->createAndWriteSkinController( instanceControllerData, controllerUniqueId, mCurrentControllerSourceUniqueId, *nodeSidsOrIds, isIdArray); //on success we need to remove this controller instance if ( success ) { listIt = instanceControllerDataList.erase( listIt ); } else { listIt++; } } } mCurrentSkinControllerData->setJointsCount(nodeSidsOrIds->size()); } break; case SEMANTIC_INV_BIND_MATRIX: { if ( !mCurrentSkinControllerData) { break; } String sourceId = getIdFromURIFragmentType(attributeData.source); SourceBase* sourceBase = getSourceById ( sourceId ); if ( !sourceBase || (sourceBase->getDataType() != SourceBase::DATA_TYPE_REAL) ) { handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "SourceBase of skin controller with semantic SEMANTIC_INV_BIND_MATRIX not valid!" ); break; } if ( sourceBase->getStride() != 16 ) { handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "Stride of sourceBase of skin controller with semantic SEMANTIC_INV_BIND_MATRIX not valid!" ); break; } const RealSource *inverseBindMatricesSource = (const RealSource *)sourceBase; const RealArrayElement& inverseBindMatricesElement = inverseBindMatricesSource->getArrayElement(); const RealArray& inverseBindMatricesArray = inverseBindMatricesElement.getValues(); size_t matrixElementsCount = inverseBindMatricesArray.getCount(); size_t matrixCount = matrixElementsCount / 16; COLLADAFW::Matrix4Array& inverseBindMatrices = mCurrentSkinControllerData->getInverseBindMatrices(); inverseBindMatrices.allocMemory( matrixCount ); inverseBindMatrices.setCount( matrixCount ); size_t index = 0; for ( size_t i = 0; i < matrixCount; ++i) { // fill the matrix COLLADABU::Math::Matrix4 matrix; for ( size_t j = 0; j < 16; ++j,++index) { matrix.setElement( j, inverseBindMatricesArray[index]); } inverseBindMatrices[i] = matrix; } } break; } } break; case MORPH_CONTROLLER: { switch ( semantic ) { case SEMANTIC_MORPH_TARGET: { if ( !mCurrentMorphController ) { break; } String sourceId = getIdFromURIFragmentType(attributeData.source); StringListMap::const_iterator it = mJointIdsMap.find(sourceId); // check if the node sid array could be found if ( it == mJointIdsMap.end() ) { if ( !handleFWLError ( SaxFWLError::ERROR_SOURCE_NOT_FOUND, "Source with id \"" + sourceId + "\" in morph controller with id \"" + mOriginalId + "\" used in input with semantic SEMANTIC_MORPH_TARGET could not be found!" )) return false; break; } const StringList& meshIds = it->second; size_t meshIdCount = meshIds.size(); COLLADAFW::UniqueIdArray& morphTargets = mCurrentMorphController->getMorphTargets(); morphTargets.allocMemory(meshIdCount); morphTargets.setCount(meshIdCount); StringList::const_iterator itTarget = meshIds.begin(); for ( size_t i = 0 ; itTarget != meshIds.end(); ++itTarget, ++i) { morphTargets[i] = createUniqueIdFromId( itTarget->c_str(), COLLADAFW::Geometry::ID()); } } break; case SEMANTIC_MORPH_WEIGHT: { if ( !mCurrentMorphController) { break; } String sourceId = getIdFromURIFragmentType(attributeData.source); SourceBase* sourceBase = getSourceById( sourceId ); if ( !sourceBase || (sourceBase->getDataType() != SourceBase::DATA_TYPE_REAL) ) { handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "SourceBase of skin controller with semantic SEMANTIC_MORPH_WEIGHT not valid!" ); break; } unsigned long long stride = sourceBase->getStride(); if( stride == 0 ) { handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "Stride of sourceBase of skin controller with semantic SEMANTIC_MORPH_WEIGHT not found! Assuming stride 1!" ); stride = 1; } if ( stride != 1 ) { handleFWLError ( SaxFWLError::ERROR_DATA_NOT_VALID, "Stride of sourceBase of skin controller with semantic SEMANTIC_MORPH_WEIGHT not valid!" ); break; } const RealSource *weightSource = (const RealSource *)sourceBase; COLLADAFW::FloatOrDoubleArray& morphWeights = mCurrentMorphController->getMorphWeights(); addToSidTree( sourceId.c_str(), 0, &morphWeights ); moveUpInSidTree(); setRealValues( morphWeights, weightSource ); } break; } } break; } return true; }