StdMat2 *NifImporter::ImportMaterialAndTextures(ImpNode *node, NiAVObjectRef avObject) { // Texture NiMaterialPropertyRef matRef = avObject->GetPropertyByType(NiMaterialProperty::TYPE); if (matRef != NULL){ StdMat2 *m = NewDefaultStdMat(); m->SetName(matRef->GetName().c_str()); if (showTextures) { m->SetMtlFlag(MTL_DISPLAY_ENABLE_FLAGS, TRUE); } // try the civ4 shader first then default back to normal shaders if (ImportNiftoolsShader(node, avObject, m)) { return m; } NiTexturingPropertyRef texRef = avObject->GetPropertyByType(NiTexturingProperty::TYPE); NiWireframePropertyRef wireRef = avObject->GetPropertyByType(NiWireframeProperty::TYPE); NiAlphaPropertyRef alphaRef = avObject->GetPropertyByType(NiAlphaProperty::TYPE); NiStencilPropertyRef stencilRef = avObject->GetPropertyByType(NiStencilProperty::TYPE); NiShadePropertyRef shadeRef = avObject->GetPropertyByType(NiShadeProperty::TYPE); vector<NiPropertyRef> props = avObject->GetProperties(); if (IsFallout3()) { m->SetAmbient(Color(0.588f, 0.588f, 0.588f),0); m->SetDiffuse(Color(0.588f, 0.588f, 0.588f),0); m->SetSpecular(Color(0.902f, 0.902f, 0.902f),0); } else { m->SetAmbient(TOCOLOR(matRef->GetAmbientColor()),0); m->SetDiffuse(TOCOLOR(matRef->GetDiffuseColor()),0); m->SetSpecular(TOCOLOR(matRef->GetSpecularColor()),0); } Color c = TOCOLOR(matRef->GetEmissiveColor()); if (c.r != 0 || c.b != 0 || c.g != 0) { m->SetSelfIllumColorOn(TRUE); m->SetSelfIllumColor(c,0); } m->SetShinStr(0.0,0); m->SetShininess(matRef->GetGlossiness()/100.0,0); m->SetOpacity(matRef->GetTransparency(),0); bool hasShaderAttributes = (wireRef != NULL) || (stencilRef != NULL) || (shadeRef != NULL); if (m->SupportsShaders() && hasShaderAttributes) { if (Shader *s = m->GetShader()) { if (wireRef != NULL && (wireRef->GetFlags() & 1)) { BOOL value = TRUE; m->SetWire(value); } if (stencilRef != NULL) { if (stencilRef->GetFaceDrawMode() == DRAW_BOTH) { BOOL value = TRUE; m->SetTwoSided(value); } } if (shadeRef != NULL && shadeRef->GetFlags() & 1) { m->SetFaceted(TRUE); } } } if (NULL != texRef) { // Handle Base/Detail ??? if (texRef->HasTexture(DECAL_0_MAP)){ if (Texmap* tex = CreateTexture(texRef->GetTexture(DECAL_0_MAP))) m->SetSubTexmap(ID_DI, tex); if (texRef->HasTexture(BASE_MAP)){ m->LockAmbDiffTex(FALSE); if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP))) m->SetSubTexmap(ID_AM, tex); } } else if (texRef->HasTexture(BASE_MAP)) { if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP))) { m->SetSubTexmap(ID_DI, tex); if (showTextures) gi->ActivateTexture(tex,m); } } // Handle Bump map if (texRef->HasTexture(BUMP_MAP)) { if (Texmap* tex = CreateTexture(texRef->GetTexture(BUMP_MAP))) m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex)); } // Shiny map if (texRef->HasTexture(GLOSS_MAP)) { if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOSS_MAP))) m->SetSubTexmap(ID_SS, tex); } // Self illumination if (texRef->HasTexture(GLOW_MAP)) { if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOW_MAP))) m->SetSubTexmap(ID_SI, tex); } // Custom Shader Handling int nTex = texRef->GetShaderTextureCount(); if (nTex > 0) { list<NiExtraDataRef> data = avObject->GetExtraData(); NiGeometryRef trigeom = DynamicCast<NiGeometry>(avObject); if (trigeom->HasShader()) { for (list<NiExtraDataRef>::iterator itr = data.begin(); itr != data.end(); ++itr) { if ( NiIntegerExtraDataRef idx = DynamicCast<NiIntegerExtraData>(*itr) ) { string name = idx->GetName(); if ( wildmatch("*Index", name) ) { int shader = idx->GetData(); if (shader < nTex) { if ( name == "NormalMapIndex" ) { if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader))) m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex)); } else if ( name == "SpecularIntensity" ) { if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader))) m->SetSubTexmap(ID_SP, CreateNormalBump(NULL, tex)); } } } } } } } } if (NiTexturePropertyRef tex2Ref = avObject->GetPropertyByType(NiTextureProperty::TYPE)){ // Handle Base/Detail ??? if (Texmap* tex = CreateTexture(tex2Ref)) { m->SetSubTexmap(ID_DI, tex); } } if (BSShaderNoLightingPropertyRef noLightShadeRef = SelectFirstObjectOfType<BSShaderNoLightingProperty>(props)) { if ( Texmap* tex = CreateTexture( noLightShadeRef->GetFileName() ) ) { m->SetSubTexmap(ID_DI, tex); } } if (BSShaderPPLightingPropertyRef ppLightShadeRef = SelectFirstObjectOfType<BSShaderPPLightingProperty>(props)) { if ( BSShaderTextureSetRef textures = ppLightShadeRef->GetTextureSet() ) { if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) ) m->SetSubTexmap(ID_DI, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) ) m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex)); if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) ) m->SetSubTexmap(ID_SI, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) ) m->SetSubTexmap(ID_RL, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) { if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) ) tex = CreateMask(NULL, tex, mask); m->SetSubTexmap(ID_SP, tex); } } } if (SkyShaderPropertyRef skyShadeRef = SelectFirstObjectOfType<SkyShaderProperty>(props)) { if ( Texmap* tex = CreateTexture( skyShadeRef->GetFileName() ) ) { m->SetSubTexmap(ID_DI, tex); } } if (TileShaderPropertyRef tileShadeRef = SelectFirstObjectOfType<TileShaderProperty>(props)) { if ( Texmap* tex = CreateTexture( tileShadeRef->GetFileName() ) ) { m->SetSubTexmap(ID_DI, tex); } } if (TallGrassShaderPropertyRef grassShadeRef = SelectFirstObjectOfType<TallGrassShaderProperty>(props)) { if ( Texmap* tex = CreateTexture( grassShadeRef->GetFileName() ) ) { m->SetSubTexmap(ID_DI, tex); } } if (Lighting30ShaderPropertyRef lighting30ShadeRef = SelectFirstObjectOfType<Lighting30ShaderProperty>(props)) { if ( BSShaderTextureSetRef textures = lighting30ShadeRef->GetTextureSet() ) { if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) ) m->SetSubTexmap(ID_DI, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) ) m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex)); if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) ) m->SetSubTexmap(ID_SI, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) ) m->SetSubTexmap(ID_RL, tex); if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) { if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) ) tex = CreateMask(NULL, tex, mask); m->SetSubTexmap(ID_SP, tex); } } } return m; } return NULL; }
//------------------------------ StdMat2* MaterialCreator::createStandardMaterial( const COLLADAFW::EffectCommon& effectCommon, const String& name, const MaterialCreator::MaterialIdentifier& materialIdentifier ) { StdMat2* material = NewDefaultStdMat(); COLLADAFW::EffectCommon::ShaderType shaderType = effectCommon.getShaderType(); switch ( shaderType ) { case COLLADAFW::EffectCommon::SHADER_CONSTANT: material->SetFaceted(true); // BUG393: Max actually does not support a constant shader! case COLLADAFW::EffectCommon::SHADER_BLINN: material->SwitchShader(Class_ID(StandardMaterial::STD2_BLINN_SHADER_CLASS_ID, 0)); break; case COLLADAFW::EffectCommon::SHADER_LAMBERT: case COLLADAFW::EffectCommon::SHADER_PHONG: case COLLADAFW::EffectCommon::SHADER_UNKNOWN: default: material->SwitchShader(Class_ID(StandardMaterial::STD2_PHONG_CLASS_ID, 0)); break; } // Retrieve the shader parameter blocks Shader* materialShader = material->GetShader(); IParamBlock2* shaderParameters = (IParamBlock2*) materialShader->GetReference(0); IParamBlock2* extendedParameters = (IParamBlock2*) material->GetReference(StandardMaterial::EXTENDED_PB_REF); // Common material parameters material->SetName(name.c_str()); const COLLADAFW::ColorOrTexture& diffuse = effectCommon.getDiffuse(); if ( diffuse.isColor() ) material->SetDiffuse( toMaxColor(diffuse), 0); const COLLADAFW::ColorOrTexture& emission = effectCommon.getEmission(); if ( emission.isColor() ) { material->SetSelfIllumColorOn(TRUE); material->SetSelfIllumColor( toMaxColor(emission), 0); } else { material->SetSelfIllumColorOn(FALSE); material->SetSelfIllum( 0, 0 ); } float maxOpacity = 1; const COLLADAFW::ColorOrTexture& opacity = effectCommon.getOpacity(); if ( opacity.isColor() ) { const COLLADAFW::Color& opacityColor = opacity.getColor(); float averageTransparent = (float)(opacityColor.getRed() + opacityColor.getGreen() + opacityColor.getBlue())/3; maxOpacity = averageTransparent; } if ( getDocumentImporter()->getInvertTransparency() ) { maxOpacity = 1 - maxOpacity; } // Max seems to like to have opacity 0 for opacity textures if ( opacity.isTexture() ) { material->SetOpacity( 0, 0); } else { material->SetOpacity( maxOpacity, 0); } if (shaderType != COLLADAFW::EffectCommon::SHADER_CONSTANT && shaderType != COLLADAFW::EffectCommon::SHADER_UNKNOWN) { // Unlock the ambient and diffuse colors materialShader->SetLockAD(FALSE); materialShader->SetLockADTex(FALSE); material->LockAmbDiffTex(FALSE); material->SyncADTexLock(FALSE); // Lambert/Phong material parameters const COLLADAFW::ColorOrTexture& ambient = effectCommon.getAmbient(); if ( ambient.isColor() ) material->SetAmbient( toMaxColor(ambient), 0); } else { // Approximate constant shader, specular is the same color if ( diffuse.isColor() ) material->SetSpecular( toMaxColor(diffuse), 0 ); } const COLLADAFW::ColorOrTexture& specular = effectCommon.getSpecular(); const COLLADAFW::FloatOrParam& shininessFloatOrParam = effectCommon.getShininess(); float shininess = 1; if ( shininessFloatOrParam.getType() == COLLADAFW::FloatOrParam::FLOAT ) { shininess = shininessFloatOrParam.getFloatValue(); } if ( shaderType == COLLADAFW::EffectCommon::SHADER_PHONG || shaderType == COLLADAFW::EffectCommon::SHADER_BLINN) { // Phong material parameters if ( specular.isColor() ) material->SetSpecular( toMaxColor(specular), 0 ); material->SetShininess(ConversionFunctors::fromPercent(shininess), 0); material->SetShinStr(ConversionFunctors::fromPercent(shininess), 0); } //create and assign textures createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getAmbient, ID_AM, materialIdentifier.ambientMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getDiffuse, ID_DI, materialIdentifier.diffuseMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getSpecular, ID_SP, materialIdentifier.specularMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getEmission, ID_SI, materialIdentifier.emissionMapChannel); createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getOpacity, ID_OP, materialIdentifier.opacityMapChannel); return material; }