//------------------------------ BitmapTex* MaterialCreator::createTexture( const COLLADAFW::EffectCommon& effectCommon, const COLLADAFW::Texture& texture ) { BitmapTex* bitmapTexture = NewDefaultBitmapTex(); COLLADAFW::SamplerID samplerId = texture.getSamplerId(); const COLLADAFW::Sampler* sampler = effectCommon.getSamplerPointerArray()[ samplerId ]; const COLLADAFW::UniqueId& imageUniqueId = sampler->getSourceImage(); const COLLADAFW::Image* image = getFWImageByUniqueId( imageUniqueId ); if ( !image ) return 0; COLLADABU::URI imageUri( getFileInfo().absoluteFileUri, image->getImageURI().getURIString() ); COLLADABU::NativeString imageFileName( imageUri.toNativePath().c_str(), COLLADABU::NativeString::ENCODING_UTF8 ); bitmapTexture->SetMapName(const_cast<char*>(imageFileName.c_str())); bitmapTexture->LoadMapFiles(0); UVGen* uvGen = bitmapTexture->GetTheUVGen(); StdUVGen* stdUVGen = (StdUVGen*)uvGen; // reset all flags //stdUVGen->SetFlag(U_WRAP|V_WRAP, 1); //stdUVGen->SetFlag(U_MIRROR|V_MIRROR, 0); int tiling = 0; if ( sampler->getWrapS() == COLLADAFW::Sampler::WRAP_MODE_WRAP ) { tiling += 1<<0; } else if ( sampler->getWrapS() == COLLADAFW::Sampler::WRAP_MODE_MIRROR ) { tiling += 1<<2; } if ( sampler->getWrapT() == COLLADAFW::Sampler::WRAP_MODE_WRAP ) { tiling += 1<<1; } else if ( sampler->getWrapT() == COLLADAFW::Sampler::WRAP_MODE_MIRROR ) { tiling += 1<<3; } stdUVGen->SetTextureTiling(tiling); return bitmapTexture; }
void UtilTest::SetEnvironmentMap() { // Make a bitmap texture map. BitmapTex *map = NewDefaultBitmapTex(); // Get the UVGen StdUVGen *uvGen = map->GetUVGen(); // Set up the coords. to be screen environment. uvGen->SetCoordMapping(UVMAP_SCREEN_ENV); // Set the bitmap file. map->SetMapName(_T("A_MAX.TGA")); // Make this the new environment map. ip->SetEnvironmentMap(map); }
void plLayerConverter::IProcessUVGen( plPlasmaMAXLayer *srcLayer, plLayer *destLayer, plBitmapData *bitmapData, bool preserveUVOffset ) { hsGuardBegin( "plPlasmaMAXLayer::IProcessUVGen" ); StdUVGen *uvGen = (StdUVGen *)srcLayer->GetTheUVGen(); int tiling = uvGen->GetTextureTiling(); // If set this indicates the texture map is tiled in U if (!(tiling & U_WRAP)) { destLayer->SetClampFlags( destLayer->GetClampFlags() | hsGMatState::kClampTextureU ); if( bitmapData != nil ) bitmapData->clampFlags |= plBitmapData::kClampU; } // If set this indicates the texture map is tiled in V if (!(tiling & V_WRAP)) { destLayer->SetClampFlags( destLayer->GetClampFlags() | hsGMatState::kClampTextureV ); if( bitmapData != nil ) bitmapData->clampFlags |= plBitmapData::kClampV; } // UVW Src int32_t uvwSrc = srcLayer->GetMapChannel() - 1; if( fErrorMsg->Set( !( fWarned & kWarnedTooManyUVs ) && ( ( uvwSrc < 0 ) || ( uvwSrc >= plGeometrySpan::kMaxNumUVChannels ) ), destLayer->GetKeyName().c_str(), "Only %d UVW channels (1-%d) currently supported", plGeometrySpan::kMaxNumUVChannels, plGeometrySpan::kMaxNumUVChannels).CheckAskOrCancel() ) fWarned |= kWarnedTooManyUVs; fErrorMsg->Set( false ); destLayer->SetUVWSrc( uvwSrc ); // Get the actual texture transform hsMatrix44 hsTopX; if (uvGen && (hsControlConverter::Instance().StdUVGenToHsMatrix44(&hsTopX, uvGen, preserveUVOffset == true))) destLayer->SetTransform( hsTopX ); // All done! hsGuardEnd; }
static void setLayerTex( GmMaterial::TextureLayer& layer, BitmapTex* bmptex, const String& materialName ) { int mapChannel = bmptex->GetMapChannel(); if ( mapChannel > 8 ) throw IOException( Format("Too large Map Channel ({1}) in material {0}", materialName, mapChannel) ); layer.filename = bmptex->GetMapName(); layer.coordset = mapChannel - 1; layer.filter = (FILTER_NADA != bmptex->GetFilterType()); layer.env = GmMaterial::ENV_NONE; StdUVGen* uvgen = bmptex->GetUVGen(); if ( uvgen && uvgen->GetSlotType() == MAPSLOT_ENVIRON ) { int type = uvgen->GetCoordMapping(0); switch ( type ) { case UVMAP_EXPLICIT: layer.env = GmMaterial::ENV_NONE; break; case UVMAP_SPHERE_ENV: layer.env = GmMaterial::ENV_SPHERICAL; break; case UVMAP_CYL_ENV: layer.env = GmMaterial::ENV_CYLINDRICAL; break; case UVMAP_SHRINK_ENV: layer.env = GmMaterial::ENV_SHRINKWRAP; break; case UVMAP_SCREEN_ENV: layer.env = GmMaterial::ENV_SCREEN; break; } TimeValue time = 0; layer.uoffs = 0.5f + uvgen->GetUOffs(time); layer.voffs = 0.5f - uvgen->GetVOffs(time); layer.uscale = 0.5f * uvgen->GetUScl(time); layer.vscale = -0.5f * uvgen->GetVScl(time); } }
CVertexCandidate *CMaxMesh::GetVertexCandidate(CSkeletonCandidate *pSkeletonCandidate, int faceId, int faceVertexId) { // check for valid mesh and physique modifier if((m_pIMesh == 0)) { theExporter.SetLastError("Invalid handle.", __FILE__, __LINE__); return 0; } // check if face id is valid if((faceId < 0) || (faceId >= m_pIMesh->getNumFaces())) { theExporter.SetLastError("Invalid face id found.", __FILE__, __LINE__); return 0; } // check if face vertex id is valid if((faceVertexId < 0) || (faceVertexId >= 3)) { theExporter.SetLastError("Invalid face vertex id found.", __FILE__, __LINE__); return 0; } // allocate a new vertex candidate CVertexCandidate *pVertexCandidate; pVertexCandidate = new CVertexCandidate(); if(pVertexCandidate == 0) { theExporter.SetLastError("Memory allocation failed.", __FILE__, __LINE__); return 0; } // create the new vertex candidate if(!pVertexCandidate->Create()) { delete pVertexCandidate; return 0; } // get vertex id int vertexId; vertexId = m_pIMesh->faces[faceId].v[faceVertexId]; // get the absolute vertex position Point3 vertex; vertex = m_pIMesh->getVert(vertexId) * m_tm; // set the vertex candidate position pVertexCandidate->SetPosition(vertex.x, vertex.y, vertex.z); pVertexCandidate->SetUniqueId(vertexId); // get the absolute vertex normal Point3 normal; normal = GetVertexNormal(faceId, vertexId); normal = normal * Inverse(Transpose(m_tm)); normal = normal.Normalize(); // set the vertex candidate normal pVertexCandidate->SetNormal(normal.x, normal.y, normal.z); if(m_pIMesh->numCVerts > 0) { VertColor vc; vc = m_pIMesh->vertCol[m_pIMesh->vcFace[faceId].t[faceVertexId]]; CalVector vcCal(vc.x, vc.y, vc.z); pVertexCandidate->SetVertColor(vcCal); } // get the vertex weight array float *pVertexWeights; pVertexWeights = m_pIMesh->getVertexWeights(); //if( pVertexWeights == NULL ) { // delete pVertexCandidate; // theExporter.SetLastError("Mesh has no vertex weights", __FILE__, __LINE__); // return 0; //} // get the vertex weight (if possible) float weight; if(pVertexWeights != 0) { weight = pVertexWeights[vertexId]; } else { weight = 0.0f; } // another 3ds max weird behaviour: // zero out epsilon weights if(weight < 0.0005f) weight = 0.0f; // set the vertex candidate weight pVertexCandidate->SetPhysicalProperty(weight); // get the material id of the face int materialId; materialId = GetFaceMaterialId(faceId); if((materialId < 0) || (materialId >= (int)m_vectorStdMat.size())) { delete pVertexCandidate; theExporter.SetLastError("Invalid material id found.", __FILE__, __LINE__); return 0; } // get the material of the face StdMat *pStdMat; pStdMat = m_vectorStdMat[materialId]; // loop through all the mapping channels and extract texture coordinates int mapId; for(mapId = 0; mapId < pStdMat->NumSubTexmaps(); mapId++) { // get texture map Texmap *pTexMap; pTexMap = pStdMat->GetSubTexmap(mapId); // check if map is valid if((pTexMap != 0) && (pStdMat->MapEnabled(mapId))) { // get the mapping channel int channel; channel = pTexMap->GetMapChannel(); bool bValidUV; bValidUV = false; // extract the texture coordinate UVVert uvVert; if(m_pIMesh->mapSupport(channel)) { TVFace *pTVFace; pTVFace = m_pIMesh->mapFaces(channel); UVVert *pUVVert; pUVVert = m_pIMesh->mapVerts(channel); uvVert = pUVVert[pTVFace[faceId].t[faceVertexId]]; bValidUV = true; } else if(m_pIMesh->numTVerts > 0) { uvVert = m_pIMesh->tVerts[m_pIMesh->tvFace[faceId].t[faceVertexId]]; bValidUV = true; } // if we found valid texture coordinates, add them to the vertex candidate if(bValidUV) { // apply a possible uv generator StdUVGen *pStdUVGen; pStdUVGen = (StdUVGen *)pTexMap->GetTheUVGen(); if(pStdUVGen != 0) { Matrix3 tmUV; pStdUVGen->GetUVTransform(tmUV); uvVert = uvVert * tmUV; } // add texture coordinate to the vertex candidate, inverting the y coordinate pVertexCandidate->AddTextureCoordinate(uvVert.x, 1.0f - uvVert.y); } } } // check for physique modifier if(m_modifierType == MODIFIER_PHYSIQUE) { // create a physique export interface IPhysiqueExport *pPhysiqueExport; pPhysiqueExport = (IPhysiqueExport *)m_pModifier->GetInterface(I_PHYINTERFACE); if(pPhysiqueExport == 0) { delete pVertexCandidate; theExporter.SetLastError("Physique modifier interface not found.", __FILE__, __LINE__); return 0; } // create a context export interface IPhyContextExport *pContextExport; pContextExport = (IPhyContextExport *)pPhysiqueExport->GetContextInterface(m_pINode); if(pContextExport == 0) { m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport); delete pVertexCandidate; theExporter.SetLastError("Context export interface not found.", __FILE__, __LINE__); return 0; } // set the flags in the context export interface pContextExport->ConvertToRigid(TRUE); pContextExport->AllowBlending(TRUE); // get the vertex export interface IPhyVertexExport *pVertexExport; pVertexExport = (IPhyVertexExport *)pContextExport->GetVertexInterface(vertexId); if(pVertexExport == 0) { pPhysiqueExport->ReleaseContextInterface(pContextExport); m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport); delete pVertexCandidate; theExporter.SetLastError("Vertex export interface not found.", __FILE__, __LINE__); return 0; } // get the vertex type int vertexType; vertexType = pVertexExport->GetVertexType(); // handle the specific vertex type if(vertexType == RIGID_TYPE) { // typecast to rigid vertex IPhyRigidVertex *pTypeVertex; pTypeVertex = (IPhyRigidVertex *)pVertexExport; // add the influence to the vertex candidate // get the influencing bone if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pTypeVertex->GetNode(), 1.0f)) { pPhysiqueExport->ReleaseContextInterface(pContextExport); m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport); delete pVertexCandidate; theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__); return 0; } } else if(vertexType == RIGID_BLENDED_TYPE) { // typecast to blended vertex IPhyBlendedRigidVertex *pTypeVertex; pTypeVertex = (IPhyBlendedRigidVertex *)pVertexExport; // loop through all influencing bones int nodeId; for(nodeId = 0; nodeId < pTypeVertex->GetNumberNodes(); nodeId++) { // add the influence to the vertex candidate if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pTypeVertex->GetNode(nodeId), pTypeVertex->GetWeight(nodeId))) { pPhysiqueExport->ReleaseContextInterface(pContextExport); m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport); delete pVertexCandidate; theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__); return 0; } } } // release all interfaces pPhysiqueExport->ReleaseContextInterface(pContextExport); m_pModifier->ReleaseInterface(I_PHYINTERFACE, pPhysiqueExport); } #if MAX_RELEASE >= 4000 // check for skin modifier else if(m_modifierType == MODIFIER_SKIN) { // create a skin interface ISkin *pSkin; pSkin = (ISkin*)m_pModifier->GetInterface(I_SKIN); if(pSkin == 0) { delete pVertexCandidate; theExporter.SetLastError("Skin modifier interface not found.", __FILE__, __LINE__); return 0; } // create a skin context data interface ISkinContextData *pSkinContextData; pSkinContextData = (ISkinContextData *)pSkin->GetContextInterface(m_pINode); if(pSkinContextData == 0) { m_pModifier->ReleaseInterface(I_SKIN, pSkin); delete pVertexCandidate; theExporter.SetLastError("Skin context data interface not found.", __FILE__, __LINE__); return 0; } // loop through all influencing bones int nodeId; for(nodeId = 0; nodeId < pSkinContextData->GetNumAssignedBones(vertexId); nodeId++) { // get the bone id int boneId; boneId = pSkinContextData->GetAssignedBone(vertexId, nodeId); if(boneId < 0) continue; // add the influence to the vertex candidate if(!AddBoneInfluence(pSkeletonCandidate, pVertexCandidate, pSkin->GetBone(boneId), pSkinContextData->GetBoneWeight(vertexId, nodeId))) { m_pModifier->ReleaseInterface(I_SKIN, pSkin); delete pVertexCandidate; theExporter.SetLastError("Invalid bone assignment.", __FILE__, __LINE__); return 0; } } // release all interfaces m_pModifier->ReleaseInterface(I_SKIN, pSkin); } #endif else if( m_modifierType == MODIFIER_MORPHER || m_modifierType == MODIFIER_NONE ) { } else { theExporter.SetLastError("No physique/skin/morpher modifier found.", __FILE__, __LINE__); return 0; } return pVertexCandidate; }
// --[ Method ]--------------------------------------------------------------- // // - Class : CStravaganzaMaxTools // // - prototype : bool BuildShaders() // // - Purpose : Builds the shader list from MAX's materials. // Preview mode requires texture files to be stored with full // path in order to load them. When we export, we only store the // filename. Another thing is that in the export mode, we copy // all textures into the path specified by the user if that // option is checked. // // ----------------------------------------------------------------------------- bool CStravaganzaMaxTools::BuildShaders() { std::vector<Mtl*>::iterator it; assert(m_vecShaders.empty()); if(!m_bPreview && m_bCopyTextures && m_strTexturePath == "") { CLogger::NotifyWindow("Textures won't be copied\nSpecify a valid output texture path first"); } LOG.Write("\n\n-Building shaders: "); for(it = m_vecMaterials.begin(); it != m_vecMaterials.end(); ++it) { Mtl* pMaxMaterial = *it; assert(pMaxMaterial); LOG.Write("\n %s", pMaxMaterial->GetName().data()); CShaderStandard* pShaderStd = new CShaderStandard; pShaderStd->SetName(pMaxMaterial->GetName().data()); // Properties StdMat2 *pMaxStandardMtl = NULL; StdMat2 *pMaxBakedMtl = NULL; float fAlpha; if(pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial; } else if(pMaxMaterial->ClassID() == Class_ID(BAKE_SHELL_CLASS_ID, 0)) { pMaxStandardMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(0); pMaxBakedMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(1); } if(pMaxStandardMtl) { // Standard material fAlpha = pMaxStandardMtl->GetOpacity(0); Shader* pMaxShader = pMaxStandardMtl->GetShader(); CVector4 v4Specular = ColorToVector4(pMaxStandardMtl->GetSpecular(0), 0.0f) * pMaxShader->GetSpecularLevel(0, 0); pShaderStd->SetAmbient (ColorToVector4(pMaxStandardMtl->GetAmbient(0), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxStandardMtl->GetDiffuse(0), fAlpha)); pShaderStd->SetSpecular (v4Specular); pShaderStd->SetShininess(pMaxShader->GetGlossiness(0, 0) * 128.0f); if(pMaxStandardMtl->GetTwoSided() == TRUE) { pShaderStd->SetTwoSided(true); } // Need to cast to StdMat2 in order to get access to IsFaceted(). // ¿Is StdMat2 always the interface for standard materials? if(((StdMat2*)pMaxStandardMtl)->IsFaceted()) { pShaderStd->SetFaceted(true); } if(pMaxStandardMtl->GetWire() == TRUE) { pShaderStd->SetPostWire(true); pShaderStd->SetWireLineThickness(pMaxStandardMtl->GetWireSize(0)); } } else { // Material != Standard fAlpha = 1.0f; // pMaxMaterial->GetXParency(); pShaderStd->SetAmbient (ColorToVector4(pMaxMaterial->GetAmbient(), 0.0f)); pShaderStd->SetDiffuse (ColorToVector4(pMaxMaterial->GetDiffuse(), fAlpha)); pShaderStd->SetSpecular (CVector4(0.0f, 0.0f, 0.0f, 0.0f)); pShaderStd->SetShininess(0.0f); } // Layers if(!pMaxStandardMtl) { m_vecShaders.push_back(pShaderStd); continue; } bool bDiffuseMap32Bits = false; StdMat2 *pStandardMtl; for(int i = 0; i < 3; i++) { int nMap; pStandardMtl = pMaxStandardMtl; // 0 = diffuse, 1 == bump, 2 = lightmap (self illumination slot) or envmap (reflection slot) if(i == 0) { nMap = ID_DI; } else if(i == 1) { nMap = ID_BU; // If its a baked material, get the bump map from there if(pMaxBakedMtl) { pStandardMtl = pMaxBakedMtl; } } else if(i == 2) { bool bBaked = false; // If its a baked material, get the map2 (lightmap) from there if(pMaxBakedMtl) { if(pMaxBakedMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { bBaked = true; nMap = ID_SI; pStandardMtl = pMaxBakedMtl; } } if(!bBaked) { if(pStandardMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED) { nMap = ID_SI; } else { nMap = ID_RL; } } } // Check validity if(pStandardMtl->GetMapState(nMap) != MAXMAPSTATE_ENABLED) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } Texmap* pMaxTexmap = pStandardMtl->GetSubTexmap(nMap); if(!pMaxTexmap) { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } // Get texmaps std::vector<std::string> vecTextures, vecPaths; CShaderStandard::SLayerInfo layerInfo; CShaderStandard::SBitmapInfo bitmapInfo; if(pMaxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0)) { BitmapTex* pMaxBitmapTex = (BitmapTex*)pMaxTexmap; Bitmap* pMaxBitmap = pMaxBitmapTex->GetBitmap(SECONDS_TO_TICKS(m_fStartTime)); StdUVGen* pMaxUVGen = pMaxBitmapTex->GetUVGen(); if(!pMaxBitmap) { if(i == 0) { LOG.Write("\n Invalid diffuse. Skipping."); break; } continue; } assert(pMaxUVGen); BitmapInfo bi = pMaxBitmap->Storage()->bi; // bi.Name() returns the full path // bi.Filename() returns just the filename vecTextures.push_back(bi.Filename()); vecPaths. push_back(bi.Name()); LOG.Write("\n Bitmap %s", vecTextures[0].data()); // Check if diffuse texture has alpha channel if(i == 0) { CBitmap bitmap; CInputFile bitmapFile; if(!bitmapFile.Open(bi.Name(), false)) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load file %s", bi.Name()); } else { if(!bitmap.Load(&bitmapFile, GetFileExt(bi.Name()))) { CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load bitmap %s", bi.Name()); } else { if(bitmap.GetBpp() == 32) { bDiffuseMap32Bits = true; LOG.Write(" (with alpha channel)"); } bitmap.Free(); } bitmapFile.Close(); } } // Ok, copy properties layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURE2D; bitmapInfo.strFile = m_bPreview ? bi.Name() : bi.Filename(); bitmapInfo.bTile = ((pMaxUVGen->GetTextureTiling() & (U_WRAP | V_WRAP)) == (U_WRAP | V_WRAP)) ? true : false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; // won't be used (forcefiltering = false) layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = pMaxUVGen->GetCoordMapping(0) == UVMAP_SPHERE_ENV ? CShaderStandard::UVGEN_ENVMAPPING : CShaderStandard::UVGEN_EXPLICITMAPPING; layerInfo.uMapChannel = pMaxUVGen->GetMapChannel(); layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(pMaxUVGen->GetUOffs(0), pMaxUVGen->GetVOffs(0), 0.0f); layerInfo.v3RotationOffset = CVector3(pMaxUVGen->GetUAng(0), pMaxUVGen->GetVAng(0), pMaxUVGen->GetWAng(0)); } else if(pMaxTexmap->ClassID() == Class_ID(ACUBIC_CLASS_ID, 0)) { ACubic* pMaxCubic = (ACubic*)pMaxTexmap; IParamBlock2* pBlock = pMaxCubic->pblock; Interval validRange = m_pMaxInterface->GetAnimRange(); for(int nFace = 0; nFace < 6; nFace++) { int nMaxFace; switch(nFace) { case 0: nMaxFace = 3; break; case 1: nMaxFace = 2; break; case 2: nMaxFace = 1; break; case 3: nMaxFace = 0; break; case 4: nMaxFace = 5; break; case 5: nMaxFace = 4; break; } TCHAR *name; pBlock->GetValue(acubic_bitmap_names, TICKS_TO_SECONDS(m_fStartTime), name, validRange, nMaxFace); vecPaths.push_back(name); CStr path, file, ext; SplitFilename(CStr(name), &path, &file, &ext); std::string strFile = std::string(file.data()) + ext.data(); vecTextures.push_back(strFile); bitmapInfo.strFile = m_bPreview ? name : strFile; bitmapInfo.bTile = false; bitmapInfo.fSeconds = 0.0f; bitmapInfo.bForceFiltering = false; bitmapInfo.eFilter = UtilGL::Texturing::FILTER_TRILINEAR; layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo); } layerInfo.texInfo.bLoop = false; layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURECUBEMAP; layerInfo.eTexEnv = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE; layerInfo.eUVGen = CShaderStandard::UVGEN_ENVMAPPING; layerInfo.uMapChannel = 0; layerInfo.v3ScrollSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationSpeed = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3ScrollOffset = CVector3(0.0f, 0.0f, 0.0f); layerInfo.v3RotationOffset = CVector3(0.0f, 0.0f, 0.0f); } else { if(i == 0) { LOG.Write("\n No diffuse. Skipping."); break; } continue; } if(!m_bPreview && m_bCopyTextures && m_strTexturePath != "") { for(int nTex = 0; nTex != vecTextures.size(); nTex++) { // Copy textures into the specified folder std::string strDestPath = m_strTexturePath; if(strDestPath[strDestPath.length() - 1] != '\\') { strDestPath.append("\\", 1); } strDestPath.append(vecTextures[nTex]); if(!CopyFile(vecPaths[nTex].data(), strDestPath.data(), FALSE)) { CLogger::NotifyWindow("Unable to copy %s to\n%s", vecPaths[i], strDestPath.data()); } } } if(layerInfo.eUVGen == CShaderStandard::UVGEN_ENVMAPPING && i == 1) { CLogger::NotifyWindow("%s : Bump with spheremapping not supported", pShaderStd->GetName().data()); } else { // Add layer switch(i) { case 0: pShaderStd->SetLayer(CShaderStandard::LAYER_DIFF, layerInfo); break; case 1: pShaderStd->SetLayer(CShaderStandard::LAYER_BUMP, layerInfo); break; case 2: pShaderStd->SetLayer(CShaderStandard::LAYER_MAP2, layerInfo); break; } } } // ¿Do we need blending? if(ARE_EQUAL(fAlpha, 1.0f) && !bDiffuseMap32Bits) { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_ONE); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_ZERO); } else { pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_SRCALPHA); pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_INVSRCALPHA); } // Add shader m_vecShaders.push_back(pShaderStd); } return true; }
bool SGP_MaxInterface::GetMtlAnim( StdMat* pStdMtl, ColorTrack& track, int nChannel ) { if( pStdMtl == NULL ) { assert( false && "std mtl is NULL" ); return false; } int nFrameCount = 0; TimeValue nStartTick = GetStartTick(); TimeValue nEndTick = GetEndTick(); int nTickPerFrame = GetTickPerFrame(); track.bTiling = false; StdUVGen *uv = NULL; Texmap *tx = pStdMtl->GetSubTexmap(nChannel); if( tx ) { if( tx->ClassID() == Class_ID( BMTEX_CLASS_ID, 0 ) ) { BitmapTex *bmt = (BitmapTex*)tx; uv = bmt->GetUVGen(); if( uv ) { track.nUTile = (int)uv->GetUScl(0); track.nVTile = (int)uv->GetVScl(0); if( track.nUTile == 1 && track.nVTile == 1 ) track.bTiling = false; else track.bTiling = true; track.nStartFrame = bmt->GetStartTime(); track.fPlaybackRate = bmt->GetPlaybackRate(); track.nLoopMode = bmt->GetEndCondition(); if( uv->GetUAng( 0 ) != 0.0f || uv->GetVAng( 0 ) != 0.0f ) { track.fUSpeed = uv->GetUAng( 0 ) / piOver180; track.fVSpeed = uv->GetVAng( 0 ) / piOver180; track.bUVMoving = true; } else track.bUVMoving = false; } } } TimeValue t; for( t = nStartTick; t <= nEndTick; t += nTickPerFrame ) nFrameCount++; track.ColorKeyFrame.resize( nFrameCount ); t = nStartTick; for( int i = 0; i < nFrameCount; i++, t += nTickPerFrame ) { SGP_ColorKey key; memset( &key, 0x00, sizeof( key ) ); Color diffuse = pStdMtl->GetDiffuse( t ); Color ambient = pStdMtl->GetAmbient( t ); Color specular = pStdMtl->GetSpecular( t ); Color filter = pStdMtl->GetFilter( t ); float alpha = pStdMtl->GetOpacity( t ); float shinstr = pStdMtl->GetShinStr(t); float selfillum = pStdMtl->GetSelfIllum( t ); float uoffset = 0; float voffset = 0; if( uv ) { uoffset = uv->GetUOffs( t ); voffset = uv->GetVOffs( t ); } /* int nTransparencyType = pStdMtl->GetTransparencyType(); key.dwBlendMode = 0; switch( nTransparencyType ) { case TRANSP_SUBTRACTIVE: key.dwBlendMode |= HR3D_MDX2_MODULATE; break; case TRANSP_ADDITIVE: key.dwBlendMode |= HR3D_MDX2_ADD; break; case TRANSP_FILTER: key.dwBlendMode |= HR3D_MDX2_MODULATE2X; break; default: break; }; */ key.dr = diffuse.r; key.dg = diffuse.g; key.db = diffuse.b; key.da = alpha; if( uv ) { key.uoffset = uv->GetUOffs( t ); key.voffset = uv->GetVOffs( t ); } else { key.uoffset = 0; key.voffset = 0; } track.ColorKeyFrame.getReference(i) = key; } return true; }
//---------------------------------------------------------------------------------- // dump material textures void DumpTexture(m_material *pMat, IGameMaterial *pGMaxMat) { std::vector<tex_channel> bk_tex_channel; std::vector<unsigned int> bk_tex_idx; std::vector<MatTextureInfo> TexInfos; int texCount = pGMaxMat->GetNumberOfTextureMaps(); for (int i = 0; i < texCount; ++i) { IGameTextureMap * pGMaxTex = pGMaxMat->GetIGameTextureMap(i); int tex_type = pGMaxTex->GetStdMapSlot(); if (pGMaxTex->IsEntitySupported() && tex_type >= 0) //its a bitmap texture { MatTextureInfo TexInfo; tex_channel tc; TexInfo.mat_id = pMat->id; m_texture * pTex = new m_texture; std::string pathname = pGMaxTex->GetBitmapFileName(); int idx = (int)pathname.rfind('\\'); if (idx == INDEX_NONE){ idx = (int)pathname.rfind('/'); } std::string filename = pathname.substr(idx + 1, INDEX_NONE); pTex->name = filename; // set the texture xform... IGameUVGen *pUVGen = pGMaxTex->GetIGameUVGen(); GMatrix UVMat = pUVGen->GetUVTransform(); TexInfo.tex_mat = pTex->tex_mat = (scalar*)UVMat.GetAddr(); // save mapping matrix // get the uv channel to use... Texmap *pTMap = pGMaxTex->GetMaxTexmap(); BitmapTex *pBTex = (BitmapTex*)pTMap; StdUVGen *pStdUVGen = pBTex->GetUVGen(); if (pStdUVGen){ tc.channel = pStdUVGen->GetMapChannel() - 1; } IParamBlock2 *pUVWCropParam = (IParamBlock2*)(pBTex->GetReference(1)); if (pUVWCropParam) { pUVWCropParam->GetValue(0, ExporterMAX::GetExporter()->GetStaticFrame(), TexInfo.uv_offset.x, FOREVER); pUVWCropParam->GetValue(1, ExporterMAX::GetExporter()->GetStaticFrame(), TexInfo.uv_offset.y, FOREVER); pUVWCropParam->GetValue(2, ExporterMAX::GetExporter()->GetStaticFrame(), TexInfo.uv_scale.x, FOREVER); pUVWCropParam->GetValue(3, ExporterMAX::GetExporter()->GetStaticFrame(), TexInfo.uv_scale.y, FOREVER); } // set the type of texture... pTex->type = texture_type[tex_type]; // if we have a bump map, we create a normal map with the convention // that the filename will be the same name as the bump map + "_normal" // appended to it. if (pTex->type == m_texture::BUMP) { std::string normal_map = pTex->name; std::string::size_type pos = normal_map.rfind("."); normal_map.insert(pos, "_normal"); m_texture *pTexNormal = new m_texture; *pTexNormal = *pTex; pTexNormal->name = normal_map; pTexNormal->type = m_texture::NORMAL; tc.pTex = pTexNormal; bk_tex_channel.push_back(tc); // add the new texture to the local TOC TexInfos.push_back(TexInfo); } tc.pTex = pTex; bk_tex_channel.push_back(tc); // add the new texture to the local TOC TexInfos.push_back(TexInfo); } } // lets check if we don't have them already in our global TOC... for (size_t index = 0; index < bk_tex_channel.size(); ++index) { m_texture * pTex = bk_tex_channel[index].pTex; unsigned int idx = ExporterMAX::GetExporter()->FindTexture(pTex); if (idx == INDEX_NONE){ idx = ExporterMAX::GetExporter()->AddTexture(pTex); // add the new texture to the TOC } bk_tex_idx.push_back(idx); pMat->tex_channel.push_back(bk_tex_channel[index].channel); TexInfos[index].base_channel = bk_tex_channel[index].channel; bk_texs.insert(IdxBKTexMapPair(idx, TexInfos[index])); } // set the texture indices... for (size_t index = 0; index < bk_tex_idx.size(); ++index){ pMat->textures.push_back(bk_tex_idx[index]); } }
Texmap* NifImporter::CreateTexture(TexDesc& desc) { BitmapManager *bmpMgr = TheManager; if (NiSourceTextureRef texSrc = desc.source){ string filename = texSrc->GetTextureFileName(); if (bmpMgr->CanImport(filename.c_str())){ BitmapTex *bmpTex = NewDefaultBitmapTex(); string name = texSrc->GetName(); if (name.empty()) { TCHAR buffer[MAX_PATH]; _tcscpy(buffer, PathFindFileName(filename.c_str())); PathRemoveExtension(buffer); name = buffer; } bmpTex->SetName(name.c_str()); bmpTex->SetMapName(const_cast<TCHAR*>(FindImage(filename).c_str())); bmpTex->SetAlphaAsMono(TRUE); bmpTex->SetAlphaSource(ALPHA_DEFAULT); switch (desc.filterMode) { case FILTER_TRILERP: bmpTex->SetFilterType(FILTER_PYR); break; case FILTER_BILERP: bmpTex->SetFilterType(FILTER_SAT); break; case FILTER_NEAREST: bmpTex->SetFilterType(FILTER_NADA); break; } if (UVGen *uvGen = bmpTex->GetTheUVGen()){ if (uvGen && uvGen->IsStdUVGen()) { StdUVGen *uvg = (StdUVGen*)uvGen; uvg->SetMapChannel(desc.uvSet + 1); } switch (desc.clampMode) { case WRAP_S_WRAP_T : uvGen->SetTextureTiling(3); break; case WRAP_S_CLAMP_T: uvGen->SetTextureTiling(1); break; case CLAMP_S_WRAP_T: uvGen->SetTextureTiling(2); break; case CLAMP_S_CLAMP_T:uvGen->SetTextureTiling(0); break; } if (desc.hasTextureTransform) { if (RefTargetHandle ref = uvGen->GetReference(0)){ TexCoord trans = desc.translation; TexCoord tiling = desc.tiling; float wangle = TODEG(desc.wRotation); setMAXScriptValue(ref, "U_Offset", 0, trans.u); setMAXScriptValue(ref, "V_Offset", 0, trans.v); setMAXScriptValue(ref, "U_Tiling", 0, tiling.u); setMAXScriptValue(ref, "V_Tiling", 0, tiling.v); setMAXScriptValue(ref, "W_Angle", 0, wangle); } } } if (showTextures) { bmpTex->SetMtlFlag(MTL_TEX_DISPLAY_ENABLED, TRUE); bmpTex->ActivateTexDisplay(TRUE); bmpTex->NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); } return bmpTex; } } return NULL; }