void CompositeMat::PreShade(ShadeContext& sc, IReshadeFragment* pFrag) { int i(0); Mtl *submtl = NULL; // BOOL enabled(FALSE); char texLengths[12]; int lengthChan = pFrag->NTextures(); pFrag->AddIntChannel(0); pFrag->AddIntChannel(0); pFrag->AddIntChannel(0); int nPrevTex = 3 + lengthChan; // preshade any submaterials for (i=0; i<MAX_NUM_MTLS; i++) { pblock2->GetValue(compmat_mtls, sc.CurTime(), submtl, FOREVER, i); if (submtl){ IReshading* pReshading = (IReshading*)(submtl->GetInterface(IID_IReshading)); if( pReshading ){ pReshading->PreShade(sc, pFrag); int nTex = pFrag->NTextures(); texLengths[i] = char( nTex - nPrevTex); nPrevTex = nTex; } } } int* pI = (int*)&texLengths[0]; pFrag->SetIntChannel( lengthChan++, pI[0] ); pFrag->SetIntChannel( lengthChan++, pI[1] ); pFrag->SetIntChannel( lengthChan, pI[2] ); }
RefResult CompositeMat::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message) { switch (message) { case REFMSG_CHANGE: if (hTarget == pblock2) { ivalid.SetEmpty(); // compmat_param_blk.InvalidateUI(); ParamID changing_param = pblock2->LastNotifyParamID(); compmat_param_blk.InvalidateUI(changing_param); if( (changing_param == compmat_amount ) ||(changing_param == compmat_map_on ) ||(changing_param == compmat_type )) { mReshadeRQ = RR_NeedReshade; } else if( changing_param == compmat_mtls ) { mReshadeRQ = RR_NeedPreshade; // really want to get from mtl, but dont have it // NotifyChanged(); } } else { ivalid.SetEmpty(); NotifyChanged(); } if (hTarget != NULL) { switch (hTarget->SuperClassID()) { case MATERIAL_CLASS_ID: { // never hit for this mtl ???? IReshading* r = static_cast<IReshading*>(hTarget->GetInterface(IID_IReshading)); mReshadeRQ = r == NULL ? RR_None : r->GetReshadeRequirements(); } break; } } break; case REFMSG_SUBANIM_STRUCTURE_CHANGED: if ((hTarget!=this)) return REF_SUCCEED; mReshadeRQ = RR_NeedPreshade; NotifyChanged(); break; } return REF_SUCCEED; }
RefResult M3Mat::NotifyRefChanged( Interval changeInt, RefTargetHandle hTarget, PartID& partID, RefMessage message) { switch (message) { case REFMSG_CHANGE: if (matDlg && matDlg->theMtl==this) { matDlg->Invalidate(); } if( hTarget == pblockMat ){ mReshadeRQ = RR_NeedPreshade; NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); } else if (hTarget != NULL) { switch (hTarget->SuperClassID()) { case MATERIAL_CLASS_ID: { IReshading* r = static_cast<IReshading*>(hTarget->GetInterface(IID_IReshading)); mReshadeRQ = (r == NULL)? RR_None : r->GetReshadeRequirements(); } break; } } break; case REFMSG_SUBANIM_STRUCTURE_CHANGED: mReshadeRQ = RR_NeedPreshade; NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE); break; case REFMSG_GET_PARAM_DIM: { GetParamDim *gpd = (GetParamDim*)partID; gpd->dim = stdPercentDim; return REF_STOP; } case REFMSG_GET_PARAM_NAME: { GetParamName *gpn = (GetParamName*)partID; char s[50]; sprintf(s,GetString(IDS_MTL_CNAME),gpn->index); gpn->name = s; return REF_STOP; } } return REF_SUCCEED; }
void M3Mat::PreShade(ShadeContext& sc, IReshadeFragment* pFrag) { int i; IReshading* pReshading; TimeValue t = sc.CurTime(); Interval valid = FOREVER; // get the base material value into i pblockMat->GetValue(100, t, i, valid ); Mtl *sm1 = mTex[100]; // handle no base mat if(sm1 == NULL) { return; } if(i==0||(i==1&&inRender)) { for( i=0;i<100;i++) { float u; pblockMat->GetValue(i,t,u,valid); if(mTex[i]!=NULL && u!=0 && mapOn[i]) { Mtl *comb = mTex[i]; pReshading = (IReshading*)(comb->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PreShade(sc, pFrag); } } pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PreShade(sc, pFrag); } else { // i == 1 && not inRender pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PreShade(sc, pFrag); } }
void CompositeMat::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ) { int i(0), type(2); Mtl* submtl = NULL; BOOL enabled(TRUE); ShadeOutput out1, out2; float amount(100.0f); // , gamount(0.0f); char texLengths[12]; int* pI = (int*)&texLengths[0]; pI[0] = pFrag->GetIntChannel(nextTexIndex++); pI[1] = pFrag->GetIntChannel(nextTexIndex++); pI[2] = pFrag->GetIntChannel(nextTexIndex++); // postshade any submaterials for ( i=0; i<MAX_NUM_MTLS; i++) { if( i>0 ) pblock2->GetValue(compmat_map_on, sc.CurTime(), enabled, FOREVER, i-1); else enabled = TRUE; pblock2->GetValue(compmat_mtls, sc.CurTime(), submtl, FOREVER, i); if ( enabled && submtl ){ if( i > 0 ){ pblock2->GetValue(compmat_amount, sc.CurTime(), amount, FOREVER, i-1); pblock2->GetValue(compmat_type, sc.CurTime(), type, FOREVER, i-1); } amount = amount * 0.01f; sc.ResetOutput(); IReshading* pReshading = (IReshading*)(submtl->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex); // first check for base material if( i > 0 ) { // not base material, composite the next material out2 = sc.out; if (type == 0) // additive { out2.t.r += 1.0f-amount; out2.t.g += 1.0f-amount; out2.t.b += 1.0f-amount; out2.c *= amount; out2.t.ClampMinMax(); out2.ior *= amount; float f1 = 1.0f - (out1.t.r + out1.t.g + out1.t.b) / 3.0f; float f2 = 1.0f - (out2.t.r + out2.t.g + out2.t.b) / 3.0f; out1.c = out1.c * (1.0f-f2) + out2.c * f1; out1.t = out1.t - (1.0f-out2.t); out1.ior = out1.ior + out2.ior; out1.t.ClampMinMax(); } else if (type == 1) // subtractive { out2.t.r += 1.0f-amount; out2.t.g += 1.0f-amount; out2.t.b += 1.0f-amount; out2.c *= amount; out2.t.ClampMinMax(); out2.ior *= amount; float f1 = 1.0f - (out1.t.r + out1.t.g + out1.t.b) / 3.0f; float f2 = 1.0f - (out2.t.r + out2.t.g + out2.t.b) / 3.0f; out1.c = out1.c * (1.0f-f2) - out2.c * f1; out1.t = out1.t - (1.0f-out2.t); out1.ior = out1.ior + out2.ior; out1.t.ClampMinMax(); } else //mix { out1.MixIn(out2, 1.0f-amount); } }// end, not base mtl else { // base material. out1 = sc.out; out1.ior *= amount; } }// end, if has submtl & enabled else { nextTexIndex += texLengths[i]; } }// end, for each mtl sc.out = out1; }
void M3Mat::PostShade(ShadeContext& sc, IReshadeFragment* pFrag, int& nextTexIndex, IllumParams* ip) { int i; IReshading* pReshading; TimeValue t = sc.CurTime(); Interval valid = FOREVER; pblockMat->GetValue(100,t,i,FOREVER); Mtl *sm1 = mTex[100]; float total(0.0f); ShadeOutput sDatabase[100]; float u[100]; ShadeOutput sFinal; // handle no base mat if(!sm1) { sc.ResetOutput(); sc.out.c = black; sc.out.t = black; return; } if(i==0 || (i==1 && inRender) ) { for( i=0; i<100; i++) { pblockMat->GetValue(i,t,u[i],valid); u[i] /= 100.0f; if( mTex[i]!=NULL && u[i]!=0 && mapOn[i] ) { Mtl *comb = mTex[i]; pReshading = (IReshading*)(comb->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); sDatabase[i] = sc.out; sc.ResetOutput(); total += u[i]; } } sc.ResetOutput(); pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); sFinal.c = black; sFinal.t = black; sFinal.ior = 0.0f; for( i=0;i<100;i++) { if(mTex[i]!=NULL && u[i]!=0 && mapOn[i]) { sc.out.flags |= sDatabase[i].flags; if(total>1.0f){ sFinal.c += u[i]/total * sDatabase[i].c; sFinal.t += u[i]/total * sDatabase[i].t; sFinal.ior += u[i]/total * sDatabase[i].ior; } else{ sFinal.c += u[i] * sDatabase[i].c; sFinal.t += u[i] * sDatabase[i].t; sFinal.ior += u[i] * sDatabase[i].ior; } } } if(total) { sc.out.MixIn(sFinal, 1.0f-total); } } else { pReshading = (IReshading*)(sm1->GetInterface(IID_IReshading)); if( pReshading ) pReshading->PostShade(sc, pFrag, nextTexIndex, ip ); } }