public void Read( BinaryReader R ) { m_diffuse = R.ReadBoolean() ? new Texture( R ) : null; m_diffuseReUse = (REUSE_MODE) R.ReadInt32(); m_normal = R.ReadBoolean() ? new Texture( R ) : null; m_normalReUse = (REUSE_MODE) R.ReadInt32(); m_gloss = R.ReadBoolean() ? new Texture( R ) : null; m_glossReUse = (REUSE_MODE) R.ReadInt32(); m_metal = R.ReadBoolean() ? new Texture( R ) : null; m_metalReUse = (REUSE_MODE) R.ReadInt32(); m_specular = R.ReadBoolean() ? new Texture( R ) : null; m_specularReUse = (REUSE_MODE) R.ReadInt32(); m_maskingMode = (MASKING_MODE) R.ReadInt32(); m_mask = R.ReadBoolean() ? new Texture( R ) : null; m_maskReUse = (REUSE_MODE) R.ReadInt32(); // Single textures m_AO = R.ReadBoolean() ? new Texture( R ) : null; m_translucency = R.ReadBoolean() ? new Texture( R ) : null; m_emissive = R.ReadBoolean() ? new Texture( R ) : null; // UV sets m_UVSet = (UV_SET) R.ReadInt32(); m_UVOffset.x = R.ReadSingle(); m_UVOffset.y = R.ReadSingle(); m_UVScale.x = R.ReadSingle(); m_UVScale.y = R.ReadSingle(); m_maskUVSet = (UV_SET) R.ReadInt32(); m_maskUVOffset.x = R.ReadSingle(); m_maskUVOffset.y = R.ReadSingle(); m_maskUVScale.x = R.ReadSingle(); m_maskUVScale.y = R.ReadSingle(); m_useColorConstant = R.ReadBoolean(); m_colorConstant.x = R.ReadSingle(); m_colorConstant.y = R.ReadSingle(); m_colorConstant.z = R.ReadSingle(); m_colorConstant.w = R.ReadSingle(); m_errorLevel = (ERROR_LEVEL) R.ReadInt32(); m_errors = R.ReadString(); if ( m_errors == string.Empty ) m_errors = null; m_warnings = R.ReadString(); if ( m_warnings == string.Empty ) m_warnings = null; }
public void CleanUp( List< Layer > _layers, Options _options, ref int _removedTexturesCount, ref int _blackColorConstantsCount, ref int _swappedSlotsCount, ref int _missingTexturesReplacedCount, ref int _removedHasOcclusionMapOptionsCount, ref int _reUseOptionsSetCount ) { // Cleanup textures that are present although the option is not set if ( !_options.m_hasNormal && m_normal != null ) { m_normal = null; _removedTexturesCount++; } if ( !_options.m_hasGloss && m_gloss != null ) { m_gloss = null; _removedTexturesCount++; } if ( !_options.m_hasMetal && m_metal != null ) { m_metal = null; _removedTexturesCount++; } if ( !_options.m_hasEmissive && m_emissive != null ) { m_emissive = null; _removedTexturesCount++; } if ( !_options.m_hasSpecular && m_specular != null ) { m_specular = null; _removedTexturesCount++; } if ( !_options.m_hasOcclusionMap && m_AO != null ) { m_AO = null; _removedTexturesCount++; } // Cleanup textures that are present whereas a re-use option is set if ( m_diffuse != null && m_diffuseReUse != REUSE_MODE.DONT_REUSE ) m_diffuse = null; if ( m_normal != null && m_normalReUse != REUSE_MODE.DONT_REUSE ) m_normal = null; if ( m_gloss != null && m_glossReUse != REUSE_MODE.DONT_REUSE ) m_gloss = null; if ( m_metal != null && m_metalReUse != REUSE_MODE.DONT_REUSE ) m_metal = null; if ( m_specular != null && m_specularReUse != REUSE_MODE.DONT_REUSE ) m_specular = null; // Patch missing textures if ( m_diffuse == null && m_diffuseReUse == REUSE_MODE.DONT_REUSE ) { m_diffuse = new Texture( "_invalid" ); _missingTexturesReplacedCount++; } if ( _options.m_hasNormal && m_normal == null && m_normalReUse == REUSE_MODE.DONT_REUSE ) { m_normal = new Texture( "ipr_constantcolor( 0.5, 0.5, 0, 0 )" ); _missingTexturesReplacedCount++; } if ( _options.m_hasGloss && m_gloss == null && m_glossReUse == REUSE_MODE.DONT_REUSE ) { m_gloss = new Texture( "_white" ); _missingTexturesReplacedCount++; } if ( _options.m_hasMetal && m_metal == null && m_metalReUse == REUSE_MODE.DONT_REUSE ) { m_metal = new Texture( "_white" ); _missingTexturesReplacedCount++; } if ( _options.m_hasEmissive && m_emissive == null ) { m_emissive = new Texture( "_invalid" ); _missingTexturesReplacedCount++; } if ( _options.m_hasSpecular && m_specular == null && m_specularReUse == REUSE_MODE.DONT_REUSE ) { m_specular = new Texture( "_invalid" ); _missingTexturesReplacedCount++; } // Clear "hasOcclusionMap" option when we don't have a map after all if ( _options.m_hasOcclusionMap && m_AO == null && m_index == 0 ) { _options.m_hasOcclusionMap = false; _removedHasOcclusionMapOptionsCount++; } // Replace diffuse textures that use a black constant color multiplier if ( m_useColorConstant && (m_colorConstant.x*m_colorConstant.x + m_colorConstant.y*m_colorConstant.y + m_colorConstant.z*m_colorConstant.z) < 1e-6f ) { m_diffuse = new Texture( "_black" ); _blackColorConstantsCount++; } // Try swapping slots if the user made obvious mistakes TrySwapping( ref m_diffuse, ref m_normal, TextureFileInfo.USAGE.DIFFUSE, TextureFileInfo.USAGE.NORMAL, ref _swappedSlotsCount ); TrySwapping( ref m_diffuse, ref m_gloss, TextureFileInfo.USAGE.DIFFUSE, TextureFileInfo.USAGE.GLOSS, ref _swappedSlotsCount ); TrySwapping( ref m_diffuse, ref m_metal, TextureFileInfo.USAGE.DIFFUSE, TextureFileInfo.USAGE.METAL, ref _swappedSlotsCount ); TrySwapping( ref m_diffuse, ref m_emissive, TextureFileInfo.USAGE.DIFFUSE, TextureFileInfo.USAGE.EMISSIVE, ref _swappedSlotsCount ); TrySwapping( ref m_normal, ref m_gloss, TextureFileInfo.USAGE.NORMAL, TextureFileInfo.USAGE.GLOSS, ref _swappedSlotsCount ); TrySwapping( ref m_normal, ref m_metal, TextureFileInfo.USAGE.NORMAL, TextureFileInfo.USAGE.METAL, ref _swappedSlotsCount ); TrySwapping( ref m_normal, ref m_emissive, TextureFileInfo.USAGE.NORMAL, TextureFileInfo.USAGE.EMISSIVE, ref _swappedSlotsCount ); TrySwapping( ref m_gloss, ref m_metal, TextureFileInfo.USAGE.GLOSS, TextureFileInfo.USAGE.METAL, ref _swappedSlotsCount ); TrySwapping( ref m_gloss, ref m_emissive, TextureFileInfo.USAGE.GLOSS, TextureFileInfo.USAGE.EMISSIVE, ref _swappedSlotsCount ); TrySwapping( ref m_metal, ref m_emissive, TextureFileInfo.USAGE.METAL, TextureFileInfo.USAGE.EMISSIVE, ref _swappedSlotsCount ); // Apply re-use options whenever a texture is identical from the previous layer for ( int previousLayerIndex=0; previousLayerIndex < m_index; previousLayerIndex++ ) { Layer previousLayer = _layers[previousLayerIndex]; REUSE_MODE previousLayerReUseMode = REUSE_MODE.DONT_REUSE; switch ( previousLayerIndex ) { case 0: previousLayerReUseMode = REUSE_MODE.REUSE_LAYER0; break; case 1: previousLayerReUseMode = REUSE_MODE.REUSE_LAYER1; break; } if ( SameUVs( previousLayer ) ) { // Can re-use some textures? if ( m_diffuse != null && previousLayer.m_diffuse != null && m_diffuseReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_diffuseReUse == REUSE_MODE.DONT_REUSE ) { if ( m_diffuse == previousLayer.m_diffuse ) { m_diffuseReUse = previousLayerReUseMode; m_diffuse = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } if ( m_normal != null && previousLayer.m_normal != null && m_normalReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_normalReUse == REUSE_MODE.DONT_REUSE ) { if ( m_normal == previousLayer.m_normal ) { m_normalReUse = previousLayerReUseMode; m_normal = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } if ( m_gloss != null && previousLayer.m_gloss != null && m_glossReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_glossReUse == REUSE_MODE.DONT_REUSE ) { if ( m_gloss == previousLayer.m_gloss ) { m_glossReUse = previousLayerReUseMode; m_gloss = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } if ( m_metal != null && previousLayer.m_metal != null && m_metalReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_metalReUse == REUSE_MODE.DONT_REUSE ) { if ( m_metal == previousLayer.m_metal ) { m_metalReUse = previousLayerReUseMode; m_metal = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } if ( m_specular != null && previousLayer.m_specular != null && m_specularReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_specularReUse == REUSE_MODE.DONT_REUSE ) { if ( m_specular == previousLayer.m_specular ) { m_specularReUse = previousLayerReUseMode; m_specular = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } } if ( SameMaskUVs( previousLayer ) ) { // Can we re-use the masks? if ( m_mask != null && previousLayer.m_mask != null && m_maskingMode != MASKING_MODE.VERTEX_COLOR && previousLayer.m_maskingMode != MASKING_MODE.VERTEX_COLOR && m_maskReUse == REUSE_MODE.DONT_REUSE && previousLayer.m_maskReUse == REUSE_MODE.DONT_REUSE ) { if ( m_mask == previousLayer.m_mask ) { m_maskReUse = previousLayerReUseMode; m_mask = null; _reUseOptionsSetCount++; _removedTexturesCount++; } } } } }
public void CompareTextures( Texture _texture0, REUSE_MODE _reUseMode0, Texture _texture1, REUSE_MODE _reUseMode1, Layer _layer1, string T, string _textureName0, string _textureName1 ) { if ( _texture0 == null && _texture1 == null ) return; // Easy! if ( _texture0 == null ) { if ( _reUseMode0 == REUSE_MODE.DONT_REUSE ) m_errors += T + "• " + _textureName0 + " is not provided whereas " + _textureName1 + " is specified and re-use mode is " + _reUseMode0 + "\n"; return; } else if ( _texture1 == null ) { if ( _reUseMode1 == REUSE_MODE.DONT_REUSE ) _layer1.m_errors += T + "• " + _textureName1 + " is not provided whereas " + _textureName0 + " is specified and re-use mode is " + _reUseMode0 + "\n"; return; } // At this point we know both textures are set if ( _reUseMode0 != REUSE_MODE.DONT_REUSE ) m_warnings += T + "• " + _textureName0 + " is provided (\"" + _texture0.m_name + "\") whereas re-use mode is specified. It's not optimal, you should remove the texture...\n"; if ( _reUseMode1 != REUSE_MODE.DONT_REUSE ) _layer1.m_warnings += T + "• " + _textureName1 + " is provided (\"" + _texture1.m_name + "\") whereas re-use mode is specified. It's not optimal, you should remove the texture...\n"; if ( _reUseMode0 == REUSE_MODE.DONT_REUSE && _reUseMode1 == REUSE_MODE.DONT_REUSE ) { // Check if both textures are the same if ( _texture0 == _texture1 ) { // Check if UV sets and tiling is the same if ( SameUVs( _layer1 ) ) m_errors += T + "• " + _textureName0 + " and " + _textureName1 + " are identical and use the same UV sets, tiling and offsets! Consider re-using other layer texture instead!\n"; } } }
/// <summary> /// Checks the provided texture is valid /// </summary> /// <param name="_texture"></param> /// <param name="_reUseMode"></param> /// <param name="T"></param> /// <param name="_textureName"></param> /// <returns></returns> public void CheckTexture( Texture _texture, bool _hasUseOption, REUSE_MODE _reUseMode, string T, string _textureName, int _expectedChannelsCount ) { if ( _reUseMode != REUSE_MODE.DONT_REUSE ) return; // Don't error when re-using previous channel textures if ( _texture == null ) { if ( _hasUseOption ) { m_errors += T + "• No " + _textureName + " texture!\n"; RaiseErrorLevel( ERROR_LEVEL.DANGEROUS ); } } else if ( _texture.m_constantColorType == Texture.CONSTANT_COLOR_TYPE.TEXTURE ) { if ( !_hasUseOption ) m_warnings += T + "• Specifying " + _textureName + " texture whereas option is not set!\n"; // In case of texture, ensure it exists! if ( !_texture.m_fileName.Exists ) { m_errors += T + "• " + _textureName + " texture \"" + _texture.m_fileName.FullName + "\" not found on disk!\n"; RaiseErrorLevel( ERROR_LEVEL.DIRTY ); } else if ( _texture.m_textureFileInfo == null ) { m_errors += T + "• " + _textureName + " texture \"" + _texture.m_fileName.FullName + "\" not found in collected textures!\n"; RaiseErrorLevel( ERROR_LEVEL.DIRTY ); } else { // Ensure we have the proper amount of channels if ( _texture.m_textureFileInfo.ColorChannelsCount != _expectedChannelsCount ) { string errorText = T + "• " + _textureName + " texture \"" + _texture.m_fileName.FullName + "\" provides " + _texture.m_textureFileInfo.ColorChannelsCount + " color channels whereas " + _expectedChannelsCount + " are expected!\n"; if ( _texture.m_textureFileInfo.m_usage == TextureFileInfo.USAGE.DIFFUSE && _expectedChannelsCount == 1 ) { m_warnings = errorText; // If an _d was set instead of a gloss or a metal, only issue a warning } else { m_errors += errorText; // Otherwise it's an actual error! RaiseErrorLevel( ERROR_LEVEL.DANGEROUS ); } } } } }