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() ); } }