void mrShaderButtonHandler::OnCommand() { DbgAssert(m_dialogHWnd != NULL); // Add the filter IMtlBrowserFilter_Manager* filterManager = Get_IMtlBrowserFilter_Manager(); if(filterManager != NULL) { filterManager->AddFilter(m_shaderFilter); } // Browse for a texmap BOOL newMat; BOOL cancel; MtlBase* mtlBase = GetCOREInterface()->DoMaterialBrowseDlg(m_dialogHWnd, (BROWSE_MAPSONLY | BROWSE_INCNONE), newMat, cancel); if(!cancel) { DbgAssert((mtlBase == NULL) || ((mtlBase->SuperClassID() == TEXMAP_CLASS_ID))); Texmap* texmap = static_cast<Texmap*>(mtlBase); SetShader(texmap); Update(); } if(filterManager != NULL) { filterManager->RemoveFilter(m_shaderFilter); } }
void CMaxMaterialCollection::OnScratchLibChanged() { #ifdef PERSIST_SCRATCH //figure out which materials were added or deleted and fire appropriate events. //this is currently pretty inefficient since we hav to walk the entire list of materials to //figure out which ones to add or remove. Could improve this by adding better messagin from //mpSceneLib if(s_PreventRecursion) return; s_PreventRecursion = true; int numLibMtls = mpScratchMtlLib->Count(); //int numMtlsWrapped = mMtlMap.size(); //adding material if(numLibMtls > mLastScratchMtlLibSize ) { for(int i=0; i< numLibMtls; i++) { //get the max material to be wrapped MtlBase *pMtl = mpScratchMtlLib->operator[](i); assert(pMtl); //can this be empty? if(pMtl == NULL || pMtl->SuperClassID() != MATERIAL_CLASS_ID) continue; DWORD_PTR key = (DWORD_PTR) pMtl; if(mMtlMap.find(key)!= mMtlMap.end()) continue;//found //Create the wrapper CComObject<CMaxMaterial> *pWrapperObject; HRESULT hr = CComObject<CMaxMaterial>::CreateInstance(&pWrapperObject); assert(SUCCEEDED(hr)); if(!SUCCEEDED(hr)) { s_PreventRecursion = false; return; } //Initalize the new wrapper pWrapperObject->setCollection(this); //TODO validate the downcast pWrapperObject->setMtl((Mtl *)pMtl); } } s_PreventRecursion = false; mLastScratchMtlLibSize = numLibMtls; #endif }
bool mrShaderFilter::Include(MtlBase& mtlBase, DWORD flags) { // Validate using the class ID ClassDesc* classDesc = GetCOREInterface()->GetDllDir().ClassDir().FindClass(mtlBase.SuperClassID(), mtlBase.ClassID()); DbgAssert(classDesc != NULL); if(classDesc != NULL) { return Include(*classDesc, flags); } else { return true; } }
//stop gap method //if the material editor becomes visible and teh material in it is not //already wrapped we better add it. void CMaxMaterialCollection::OnMeditVisible() { if(!m_suspendCount) { MtlBase *m = GetMtlEditInterface()->GetCurMtl(); if(m->SuperClassID()!=MATERIAL_CLASS_ID) return; CComPtr<IMaxMaterial> pWrapper; FindItemKey((DWORD_PTR)(m), &pWrapper.p); if(!pWrapper) { MakeWrapperObject((Mtl*)m); FindItemKey((DWORD_PTR)(m), &pWrapper.p); if(pWrapper) AddPersistence(pWrapper); } } }
void CMaxMaterialCollection::OnSceneLibChanged() { //figure out which materials were added or deleted and fire appropriate events. //this is currently pretty inefficient since we hav to walk the entire list of materials to //figure out which ones to add or remove. Could improve this by adding better messagin from //mpSceneLib if(s_PreventRecursion) return; s_PreventRecursion = true; int numLibMtls = mpSceneMtlLib->Count(); //int numMtlsWrapped = mMtlMap.size(); //adding material if(numLibMtls > mLastSceneMtlLibSize ) { for(int i=0; i< numLibMtls; i++) { //get the max material to be wrapped MtlBase *pMtl = mpSceneMtlLib->operator[](i); //assert(pMtl); //can this be empty? //the assertion is no good because a makerefrestore may be setting the ref from //lib to material to null. The lib notifies us. if(pMtl == NULL || pMtl->SuperClassID() != MATERIAL_CLASS_ID) continue; //TODO validate the downcast HRESULT hr = MakeWrapperObject(static_cast<Mtl*>(pMtl)); assert(SUCCEEDED(hr)); if (!SUCCEEDED(hr)) { s_PreventRecursion = false; return; } } } //removing material /* We no longer track removals other than to update our record of the new size (mLastSceneMtlLibSize) The idea is that we keep all of our wrappers alive unless explicitly destroyed. We assume that all new materials will pass through the scenematerials lib via OkMtlForScene or some equivalent method. else if(numLibMtls < mLastSceneMtlLibSize ) { ifxClxnType::iterator it=mMtlMap.begin(); while(it!=mMtlMap.end()) { Mtl *pMtlToCheck = (Mtl *) (*it).first; if(mpSceneMtlLib->FindMtl(pMtlToCheck) == -1)//no longer in scene { pMtlWrapper.Attach((*it).second); #ifdef XXXRECYCLE_MATS //add the wrapper to our data structure mRecycledMtlMap.insert(*it); pMtlWrapper.p->AddRef(); #endif Fire_OnMaterialRemoved(this, pMtlWrapper); it = mMtlMap.erase(it); pMtlWrapper.Release(); } else it++; } } */ //update our record of the size of sceneMtlLib mLastSceneMtlLibSize = numLibMtls; s_PreventRecursion = false; /* TO DO implement an integrity checker #ifndef NDEBUG else CheckIntegrity(); #endif */ }