void ReplaceMaterialParam(const Palleon::MaterialPtr& material, const char* paramName, const CVector4& newParamValue) { auto param = material->GetEffectParameter(paramName); CVector4 paramValue(0, 0, 0, 0); if(param.IsVector3()) { paramValue = CVector4(param.GetVector3(), 0); } else { paramValue = param.GetVector4(); } paramValue.x = (newParamValue.x == 1000.f) ? paramValue.x : newParamValue.x; paramValue.y = (newParamValue.y == 1000.f) ? paramValue.y : newParamValue.y; paramValue.z = (newParamValue.z == 1000.f) ? paramValue.z : newParamValue.z; paramValue.w = (newParamValue.w == 1000.f) ? paramValue.w : newParamValue.w; if(param.IsVector3()) { param.SetVector3(paramValue.xyz()); } else { param.SetVector4(paramValue); } material->SetEffectParameter(paramName, param); }
bool SetPropertyFromNode( const TreeNode& node, Property::Value& value, const Replacement& replacer ) { bool done = false; // some values are ambiguous as we have no Property::Type but can be disambiguated in the json // Currently Rotations and Rectangle must always be disambiguated when a type isnt available if( Disambiguated( node, value, replacer ) ) { done = true; } else { if( node.Size() ) { // our current heuristic for deciding an array is actually a vector and not say a map // is to check if the values are all floats bool allNumbers = true; for(TreeConstIter iter = node.CBegin(); iter != node.CEnd(); ++iter) { OptionalFloat f = IsFloat((*iter).second); if(!f) { allNumbers = false; break; } } if( allNumbers ) { // prefer finding vectors over presuming composite Property::Array... if( OptionalMatrix v = IsMatrix(node) ) { value = *v; done = true; } else if( OptionalMatrix3 v = IsMatrix3(node) ) { value = *v; done = true; } else if( OptionalVector4 v = IsVector4(node) ) { value = *v; done = true; } else if( OptionalVector3 v = IsVector3(node) ) { value = *v; done = true; } else if( OptionalVector2 v = IsVector2(node) ) { value = *v; done = true; } else if( 4 == node.Size() ) { if( OptionalVector4 v = IsVector4(node) ) { value = *v; done = true; } } else { value = Property::Value(Property::ARRAY); Property::Array* array = value.GetArray(); if( array ) { for(TreeConstIter iter = node.CBegin(); iter != node.CEnd(); ++iter) { Property::Value childValue; if( SetPropertyFromNode( (*iter).second, childValue, replacer ) ) { array->PushBack( childValue ); done = true; } } } } } if(!done) { // presume an array or map // container of size 1 TreeNode::ConstIterator iter = node.CBegin(); // its seems legal with current json parser for a map to have an empty key // but here we take that to mean the structure is a list if( ((*iter).first) == 0 ) { value = Property::Value(Property::ARRAY); Property::Array* array = value.GetArray(); if( array ) { for(unsigned int i = 0; i < node.Size(); ++i, ++iter) { Property::Value childValue; if( SetPropertyFromNode( (*iter).second, childValue, replacer ) ) { array->PushBack( childValue ); done = true; } } } } else { value = Property::Value(Property::MAP); Property::Map* map = value.GetMap(); if( map ) { for(unsigned int i = 0; i < node.Size(); ++i, ++iter) { Property::Value childValue; if( SetPropertyFromNode( (*iter).second, childValue, replacer ) ) { map->Insert( (*iter).first, childValue ); done = true; } } } } } // if!done } // if node.size() else // if( 0 == node.size() ) { // no children so either one of bool, float, integer, string OptionalBoolean aBool = replacer.IsBoolean(node); OptionalInteger anInt = replacer.IsInteger(node); OptionalFloat aFloat = replacer.IsFloat(node); OptionalString aString = replacer.IsString(node); if(aBool) { // a bool is also an int but here we presume int if(anInt) { value = *anInt; done = true; } else { value = *aBool; done = true; } } else { // Note: These are both floats and strings // {"value":"123"} // {"value":123} // This means we can't have a string with purely numeric content without disambiguation. if(aFloat) { value = *aFloat; done = true; } else if(anInt) { value = *anInt; done = true; } else { // string always succeeds with the current json parser so its last value = *aString; done = true; } } // if aBool } // if( node.size() ) } // if Disambiguated() return done; } // bool SetPropertyFromNode( const TreeNode& node, Property::Value& value )