예제 #1
0
void LuminanceOp::modifyPrimitive( Primitive * primitive, const CompoundObject * operands )
{
	DataPtr luminanceData = 0;
	PrimitiveVariable::Interpolation interpolation = PrimitiveVariable::Invalid;
	int steps[3] = { 1, 1, 1 };

	PrimitiveVariableMap::iterator colorIt = primitive->variables.find( m_colorPrimVarParameter->getTypedValue() );
	if( colorIt!=primitive->variables.end() && colorIt->second.data )
	{
		// RGB in a single channel
		switch( colorIt->second.data->typeId() )
		{
			case Color3fDataTypeId :
				{
					FloatDataPtr l = new FloatData;
					const float *d = staticPointerCast<Color3fData>( colorIt->second.data )->baseReadable();
					calculate( d, d + 1, d + 2, steps, 1, l->baseWritable() );
					luminanceData = l;
				}
				break;
			case Color3fVectorDataTypeId :
				{
					FloatVectorDataPtr l = new FloatVectorData;
					Color3fVectorDataPtr d = staticPointerCast<Color3fVectorData>( colorIt->second.data );
					l->writable().resize( d->readable().size() );
					const float *dd = d->baseReadable();
					steps[0] = steps[1] = steps[2] = 3;
					calculate( dd, dd + 1, dd + 2, steps, d->readable().size(), l->baseWritable() );
					luminanceData = l;
				}
				break;
			default :
				throw Exception( "PrimitiveVariable has unsupported type." );
				break;
		}
		interpolation = colorIt->second.interpolation;
	}
	else
	{
		// separate RGB channels?
		PrimitiveVariableMap::iterator rIt = primitive->variables.find( m_redPrimVarParameter->getTypedValue() );
		PrimitiveVariableMap::iterator gIt = primitive->variables.find( m_greenPrimVarParameter->getTypedValue() );
		PrimitiveVariableMap::iterator bIt = primitive->variables.find( m_bluePrimVarParameter->getTypedValue() );
		if( rIt==primitive->variables.end() || gIt==primitive->variables.end() || bIt==primitive->variables.end() )
		{
			throw Exception( "Primitive does not have appropriately named PrimitiveVariables." );
		}
		TypeId type = rIt->second.data->typeId();
		if( gIt->second.data->typeId() != type || bIt->second.data->typeId() != type )
		{
			throw Exception( "PrimitiveVariable types do not match." );
		}
		size_t rSize = despatchTypedData<TypedDataSize>( rIt->second.data );
		size_t gSize = despatchTypedData<TypedDataSize>( gIt->second.data );
		size_t bSize = despatchTypedData<TypedDataSize>( bIt->second.data );
		if( rSize!=gSize || rSize!=bSize )
		{
			throw Exception( "PrimitiveVariable sizes do not match." );
		}
		switch( type )
		{
			case HalfDataTypeId :
				{
					HalfDataPtr l = new HalfData;
					calculate(
						staticPointerCast<HalfData>( rIt->second.data )->baseReadable(),
						staticPointerCast<HalfData>( gIt->second.data )->baseReadable(),
						staticPointerCast<HalfData>( bIt->second.data )->baseReadable(),
						steps,
						rSize,
						l->baseWritable()
					);
					luminanceData = l;
				}
				break;
			case HalfVectorDataTypeId :
				{
					HalfVectorDataPtr l = new HalfVectorData;
					l->writable().resize( rSize );
					calculate(
						staticPointerCast<HalfVectorData>( rIt->second.data )->baseReadable(),
						staticPointerCast<HalfVectorData>( gIt->second.data )->baseReadable(),
						staticPointerCast<HalfVectorData>( bIt->second.data )->baseReadable(),
						steps,
						rSize,
						l->baseWritable()
					);
					luminanceData = l;
				}
				break;
			case FloatDataTypeId :
				{
					FloatDataPtr l = new FloatData;
					calculate(
						staticPointerCast<FloatData>( rIt->second.data )->baseReadable(),
						staticPointerCast<FloatData>( gIt->second.data )->baseReadable(),
						staticPointerCast<FloatData>( bIt->second.data )->baseReadable(),
						steps,
						rSize,
						l->baseWritable()
					);
					luminanceData = l;
				}
				break;
			case FloatVectorDataTypeId :
				{
					FloatVectorDataPtr l = new FloatVectorData;
					l->writable().resize( rSize );
					calculate(
						staticPointerCast<FloatVectorData>( rIt->second.data )->baseReadable(),
						staticPointerCast<FloatVectorData>( gIt->second.data )->baseReadable(),
						staticPointerCast<FloatVectorData>( bIt->second.data )->baseReadable(),
						steps,
						rSize,
						l->baseWritable()
					);
					luminanceData = l;
				}
				break;
			default :
				throw Exception( "PrimitiveVariables have unsupported type." );
				break;
		}
		interpolation = rIt->second.interpolation;
	}

	assert( interpolation != PrimitiveVariable::Invalid );
	assert( luminanceData );

	primitive->variables[luminancePrimVarParameter()->getTypedValue()] = PrimitiveVariable( interpolation, luminanceData );

	if( removeColorPrimVarsParameter()->getTypedValue() )
	{
		primitive->variables.erase( colorPrimVarParameter()->getTypedValue() );
		primitive->variables.erase( redPrimVarParameter()->getTypedValue() );
		primitive->variables.erase( greenPrimVarParameter()->getTypedValue() );
		primitive->variables.erase( bluePrimVarParameter()->getTypedValue() );
	}
}