Exemplo n.º 1
0
void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
	// set up the iterators
	LLSD::map_iterator cIt = mParamValues.beginMap();

	// keep cloud positions and coverage the same
	/// TODO masking will do this later
	F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
	F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
	F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
	F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
	F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();

	LLSD srcVal;
	LLSD destVal;

	// do the interpolation for all the ones saved as vectors
	// skip the weird ones
	for(; cIt != mParamValues.endMap(); cIt++) {

		// check params to make sure they're actually there
		if(src.mParamValues.has(cIt->first))
		{
			srcVal = src.mParamValues[cIt->first];
		}
		else
		{
			continue;
		}
		
		if(dest.mParamValues.has(cIt->first))
		{
			destVal = dest.mParamValues[cIt->first];
		}
		else
		{
			continue;
		}		
				
		// skip if not a vector
		if(!cIt->second.isArray()) 
		{
			continue;
		}

		// only Real vectors allowed
		if(!cIt->second[0].isReal()) 
		{
			continue;
		}
		
		// make sure all the same size
		if(	cIt->second.size() != srcVal.size() ||
			cIt->second.size() != destVal.size())
		{
			continue;
		}
		
		// more error checking might be necessary;
		
		for(int i=0; i < cIt->second.size(); ++i) 
		{
			cIt->second[i] = (1.0f - weight) * (F32) srcVal[i].asReal() + 
				weight * (F32) destVal[i].asReal();
		}
	}

	// now mix the extra parameters
	setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
		+ weight * (F32) dest.getStarBrightness());

	llassert(src.getSunAngle() >= - F_PI && 
					src.getSunAngle() <= 3 * F_PI);
	llassert(dest.getSunAngle() >= - F_PI && 
					dest.getSunAngle() <= 3 * F_PI);
	llassert(src.getEastAngle() >= 0 && 
					src.getEastAngle() <= 4 * F_PI);
	llassert(dest.getEastAngle() >= 0 && 
					dest.getEastAngle() <= 4 * F_PI);

	// sun angle and east angle require some handling to make sure
	// they go in circles.  Yes quaternions would work better.
	F32 srcSunAngle = src.getSunAngle();
	F32 destSunAngle = dest.getSunAngle();
	F32 srcEastAngle = src.getEastAngle();
	F32 destEastAngle = dest.getEastAngle();
	
	if(fabsf(srcSunAngle - destSunAngle) > F_PI) 
	{
		if(srcSunAngle > destSunAngle) 
		{
			destSunAngle += 2 * F_PI;
		} 
		else 
		{
			srcSunAngle += 2 * F_PI;
		}
	}

	if(fabsf(srcEastAngle - destEastAngle) > F_PI) 
	{
		if(srcEastAngle > destEastAngle) 
		{
			destEastAngle += 2 * F_PI;
		} 
		else 
		{
			srcEastAngle += 2 * F_PI;
		}
	}

	setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
	setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
	
	// now setup the sun properly

	// reset those cloud positions
	mParamValues["cloud_pos_density1"][0] = cloudPos1X;
	mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
	mParamValues["cloud_pos_density2"][0] = cloudPos2X;
	mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
	mParamValues["cloud_shadow"][0] = cloudCover;
}
Exemplo n.º 2
0
void LLWLParamSet::mix(LLWLParamSet& src, LLWLParamSet& dest, F32 weight)
{
	// set up the iterators

	// keep cloud positions and coverage the same
	/// TODO masking will do this later
	F32 cloudPos1X = (F32) mParamValues["cloud_pos_density1"][0].asReal();
	F32 cloudPos1Y = (F32) mParamValues["cloud_pos_density1"][1].asReal();
	F32 cloudPos2X = (F32) mParamValues["cloud_pos_density2"][0].asReal();
	F32 cloudPos2Y = (F32) mParamValues["cloud_pos_density2"][1].asReal();
	F32 cloudCover = (F32) mParamValues["cloud_shadow"][0].asReal();

	LLSD srcVal;
	LLSD destVal;

	// Iterate through values
	for(LLSD::map_iterator iter = mParamValues.beginMap(); iter != mParamValues.endMap(); ++iter)
	{

		// If param exists in both src and dest, set the holder variables, otherwise skip
		if(src.mParamValues.has(iter->first) && dest.mParamValues.has(iter->first))
		{
			srcVal = src.mParamValues[iter->first];
			destVal = dest.mParamValues[iter->first];
		}
		else
		{
			continue;
		}
		
		if(iter->second.isReal())									// If it's a real, interpolate directly
		{
			iter->second = srcVal.asReal() + ((destVal.asReal() - srcVal.asReal()) * weight);
		}
		else if(iter->second.isArray() && iter->second[0].isReal()	// If it's an array of reals, loop through the reals and interpolate on those
				&& iter->second.size() == srcVal.size() && iter->second.size() == destVal.size())
		{
			// Actually do interpolation: old value + (difference in values * factor)
			for(int i=0; i < iter->second.size(); ++i) 
			{
				// iter->second[i] = (1.f-weight)*(F32)srcVal[i].asReal() + weight*(F32)destVal[i].asReal();	// old way of doing it -- equivalent but one more operation
				iter->second[i] = srcVal[i].asReal() + ((destVal[i].asReal() - srcVal[i].asReal()) * weight);
			}
		}
		else														// Else, skip
		{
			continue;
		}		
	}

	// now mix the extra parameters
	setStarBrightness((1 - weight) * (F32) src.getStarBrightness()
		+ weight * (F32) dest.getStarBrightness());

	llassert(src.getSunAngle() >= - F_PI && 
					src.getSunAngle() <= 3 * F_PI);
	llassert(dest.getSunAngle() >= - F_PI && 
					dest.getSunAngle() <= 3 * F_PI);
	llassert(src.getEastAngle() >= 0 && 
					src.getEastAngle() <= 4 * F_PI);
	llassert(dest.getEastAngle() >= 0 && 
					dest.getEastAngle() <= 4 * F_PI);

	// sun angle and east angle require some handling to make sure
	// they go in circles.  Yes quaternions would work better.
	F32 srcSunAngle = src.getSunAngle();
	F32 destSunAngle = dest.getSunAngle();
	F32 srcEastAngle = src.getEastAngle();
	F32 destEastAngle = dest.getEastAngle();
	
	if(fabsf(srcSunAngle - destSunAngle) > F_PI) 
	{
		if(srcSunAngle > destSunAngle) 
		{
			destSunAngle += 2 * F_PI;
		} 
		else 
		{
			srcSunAngle += 2 * F_PI;
		}
	}

	if(fabsf(srcEastAngle - destEastAngle) > F_PI) 
	{
		if(srcEastAngle > destEastAngle) 
		{
			destEastAngle += 2 * F_PI;
		} 
		else 
		{
			srcEastAngle += 2 * F_PI;
		}
	}

	setSunAngle((1 - weight) * srcSunAngle + weight * destSunAngle);
	setEastAngle((1 - weight) * srcEastAngle + weight * destEastAngle);
	
	// now setup the sun properly

	// reset those cloud positions
	mParamValues["cloud_pos_density1"][0] = cloudPos1X;
	mParamValues["cloud_pos_density1"][1] = cloudPos1Y;
	mParamValues["cloud_pos_density2"][0] = cloudPos2X;
	mParamValues["cloud_pos_density2"][1] = cloudPos2Y;
	mParamValues["cloud_shadow"][0] = cloudCover;
}