//----------------------------------------------------------------------- bool HardwareSkinning::preAddToRenderState(const RenderState* renderState, Pass* srcPass, Pass* dstPass) { bool isValid = true; Technique* pFirstTech = srcPass->getParent()->getParent()->getTechnique(0); const Any& hsAny = pFirstTech->getUserObjectBindings().getUserAny(HS_DATA_BIND_NAME); if (hsAny.isEmpty() == false) { HardwareSkinning::SkinningData pData = (any_cast<HardwareSkinning::SkinningData>(hsAny)); isValid = pData.isValid; //If the skinning data is being passed through the material, we need to create an instance of the appropriate //skinning type and set its parameters here setHardwareSkinningParam(pData.maxBoneCount, pData.maxWeightCount, pData.skinningType, pData.correctAntipodalityHandling, pData.scalingShearingSupport); } //If there is no associated technique, default to linear skinning as a pass-through if(mActiveTechnique.isNull()) { setHardwareSkinningParam(0, 0, ST_LINEAR, false, false); } int boneCount = mActiveTechnique->getBoneCount(); int weightCount = mActiveTechnique->getWeightCount(); bool doBoneCalculations = isValid && (boneCount != 0) && (boneCount <= 256) && (weightCount != 0) && (weightCount <= 4) && ((mCreator == NULL) || (boneCount <= mCreator->getMaxCalculableBoneCount())); mActiveTechnique->setDoBoneCalculations(doBoneCalculations); if ((doBoneCalculations) && (mCreator)) { //update the receiver and caster materials if (dstPass->getParent()->getShadowCasterMaterial().isNull()) { dstPass->getParent()->setShadowCasterMaterial( mCreator->getCustomShadowCasterMaterial(mSkinningType, weightCount - 1)); } if (dstPass->getParent()->getShadowReceiverMaterial().isNull()) { dstPass->getParent()->setShadowReceiverMaterial( mCreator->getCustomShadowReceiverMaterial(mSkinningType, weightCount - 1)); } } return true; }
//------------------------------------------------------------------------ MatGenParams MaterialUtil::getMatGenParams(const MaterialPtr& _material) { if(!_material->getNumTechniques()) return MatGenParams(); Technique* technique = _material->getTechnique(0); UserObjectBindings& uob = technique->getUserObjectBindings(); Any matGenParamsAny = uob.getUserAny( USER_MAT_GEN_PARAMS ); if(matGenParamsAny.isEmpty()) return MatGenParams(); return *any_cast<MatGenParams>(&matGenParamsAny); }
//------------------------------------------------------------------------ MtlPtr MaterialUtil::getMtl(const MaterialPtr& _material) { if(!_material->getNumTechniques()) return MtlPtr(); Technique* technique = _material->getTechnique(0); UserObjectBindings& uob = technique->getUserObjectBindings(); Any mtlAny = uob.getUserAny( USER_MTL ); if(mtlAny.isEmpty()) return MtlPtr(); MtlPtr mtl = *any_cast<MtlPtr>(&mtlAny); return mtl; }
static MaterialInternal* get(const MaterialPtr& _material) { Technique* technique = _material->getTechnique(0); UserObjectBindings& uob = technique->getUserObjectBindings(); const Any& any = uob.getUserAny(); if(any.isEmpty()) { MaterialInternal* ret = new MaterialInternal; uob.setUserAny(Any(MaterialInternalPtr(ret))); return ret; } MaterialInternalPtr ptr = any.operator ()<MaterialInternalPtr>(); MaterialInternal* ret = ptr.get(); return ret; }
//------------------------------------------------------------------------ MtlPtr MaterialUtil::getMtl(const MaterialPtr& _material, MatGenParams& _rMatGenParams) { if(!_material->getNumTechniques()) return MtlPtr(); Technique* technique = _material->getTechnique(0); UserObjectBindings& uob = technique->getUserObjectBindings(); Any mtlAny = uob.getUserAny( USER_MTL ); Any matGenParamsAny = uob.getUserAny( USER_MAT_GEN_PARAMS ); if(mtlAny.isEmpty() || matGenParamsAny.isEmpty()) return MtlPtr(); MtlPtr mtl = *any_cast<MtlPtr>(&mtlAny); _rMatGenParams = *any_cast<MatGenParams>(&matGenParamsAny); return mtl; }
//------------------------------------------------------------------------ MaterialPtr MaterialUtil::generateMaterial(const MtlPtr& _mtl, const MatGenParams& _matGenParams) { MaterialPtr material; Mtl::MaterialHandles::iterator it = _mtl->mMaterialHandles.find(_matGenParams); if(it != _mtl->mMaterialHandles.end()) { // Material was generated already, just return it // (Materials can be shared.) ResourceHandle handle = it->second; material = MaterialManager::getSingleton().getByHandle(handle); } else { // Generate a new material String materialName = s_MaterialNameGenerator.generate(); material = MaterialManager::getSingleton().create(materialName, StringUtil::BLANK); // We need a material generator. MaterialGenerator* generator = MaterialGeneratorRegistration::getSingleton().getGenerator(); // Initalise the material with the specified params. generator->_updateMaterial(material, _mtl, _matGenParams); // Store the smart pointer to the mtl and the material generation params // in the material's "user any" member. if(!material->getNumTechniques()) { MaterialManager::getSingleton().remove( (ResourcePtr) material); return MaterialPtr(); } Technique* technique = material->getTechnique(0); UserObjectBindings& uob = technique->getUserObjectBindings(); uob.setUserAny( USER_MTL, (Any) _mtl ); uob.setUserAny( USER_MAT_GEN_PARAMS, (Any) _matGenParams ); // Store the handle to the new material in the mtl. ResourceHandle handle = material->getHandle(); _mtl->mMaterialHandles.insert(std::make_pair(_matGenParams, handle)); } return material; }