1 /**********************************************************************
2 *<
3 FILE: BMTEX.CPP
4
5 DESCRIPTION: BMTEX 2D Texture map.
6
7 CREATED BY: Dan Silva
8
9 HISTORY:
10
11 *> Copyright (c) 1994, All Rights Reserved.
12 **********************************************************************/
13
14 #include "bmtex.h"
15 #include "mtlhdr.h"
16 #include "mtlres.h"
17 #include "3dsmaxport.h"
18 #include "notify.h"
19 #include "macrorec.h"
20
21 extern HINSTANCE hInstance;
22
23 // Image filtering types
24 #define FILTER_PYR 0
25 #define FILTER_SAT 1
26 #define FILTER_NADA 2
27
28 // Alpha source types
29 #define ALPHA_FILE 0
30 #define ALPHA_RGB 2
31 #define ALPHA_NONE 3
32
33 // End conditions:
34 #define END_LOOP 0
35 #define END_PINGPONG 1
36 #define END_HOLD 2
37
38 #define NCOLS 0
39
40 #define UVGEN_REF 0
41 #define PBLOCK_REF 1
42 #define TEXOUT_REF 2
43 #define PBLOCKTIME_REF 3
44
45 // Interface ID used to access the particle bitmaps of the Bitmap texture
46 #define IID_BITMAPTEX_PARTICLE_BITMAP_LIST 0x3c34ffff
47
48 //------------------------------------------------------------------------
49 // Local definitions
50 //------------------------------------------------------------------------
51
52 namespace {
53
54 Class_ID bmTexClassID(BMTEX_CLASS_ID,0);
55 AColor black(0.0f,0.0f,0.0f,0.0f);
56
57
InvalidNameMsg(const TCHAR * name)58 void InvalidNameMsg(const TCHAR* name) {
59 if (name==NULL) return;
60 TCHAR msg[128];
61 wsprintf(msg,_T("Invalid File Name: %s"), name);
62 MessageBox(NULL, msg, GetString(IDS_DS_BITMAP_TEXTURE_ERR), MB_TASKMODAL);
63 }
64
GetSubjectInfo(BitmapInfo * srcInfo)65 BitmapInfo* GetSubjectInfo( BitmapInfo* srcInfo ) {
66 if( srcInfo->GetProxySubject() != NULL )
67 return srcInfo->GetProxySubject();
68 else
69 return srcInfo;
70 }
71
72 // Copy the proxy subject of srcInto into the given subject info, clear proxy request flag on subject info
CopySubjectToSubjectInfo(BitmapInfo & subjectInfo,BitmapInfo & srcInfo)73 void CopySubjectToSubjectInfo( BitmapInfo& subjectInfo, BitmapInfo& srcInfo ) {
74 subjectInfo = *GetSubjectInfo( &srcInfo );
75 subjectInfo.ResetFlags( MAP_PROXYREQUEST ); // Mark as request for non-proxy
76 }
77
78 // Copy the proxy subject of srcInto into the given request info, set proxy request flag on request info
CopySubjectToRequestInfo(BitmapInfo & requestInfo,BitmapInfo & srcInfo)79 void CopySubjectToRequestInfo( BitmapInfo& requestInfo, BitmapInfo& srcInfo ) {
80 requestInfo = *GetSubjectInfo( &srcInfo );
81 requestInfo.SetFlags( MAP_PROXYREQUEST ); // Mark as request for proxy
82 }
83
BitmapNonProxy_LoadInto(BitmapInfo & requestInfo,Bitmap ** pBitmap,BOOL forceReload)84 void BitmapNonProxy_LoadInto( BitmapInfo& requestInfo, Bitmap** pBitmap, BOOL forceReload ) {
85 requestInfo.ResetFlags( MAP_PROXYREQUEST );
86 TheManager->LoadInto(&requestInfo, pBitmap, forceReload);
87 }
88
BitmapProxy_LoadInto(BitmapInfo & subjectInfo,BitmapInfo & requestInfo,Bitmap ** pBitmap,BOOL forceReload)89 void BitmapProxy_LoadInto( BitmapInfo& subjectInfo, BitmapInfo& requestInfo, Bitmap** pBitmap, BOOL forceReload ) {
90 CopySubjectToRequestInfo( requestInfo, subjectInfo ); // Create a request info for the proxy from our subject info
91 TheManager->LoadInto( &requestInfo, pBitmap, forceReload );
92 CopySubjectToSubjectInfo( subjectInfo, requestInfo ); // Copy the the updated subject info into our subject info
93 }
94
BitmapNonProxy_Load(BitmapInfo & requestInfo,BMMRES * status)95 Bitmap* BitmapNonProxy_Load( BitmapInfo& requestInfo, BMMRES* status ) {
96 requestInfo.ResetFlags( MAP_PROXYREQUEST );
97 Bitmap* retval = TheManager->Load(&requestInfo, status);
98 return retval;
99 }
100
BitmapProxy_Load(BitmapInfo & subjectInfo,BitmapInfo & requestInfo,BMMRES * status)101 Bitmap* BitmapProxy_Load( BitmapInfo& subjectInfo, BitmapInfo& requestInfo, BMMRES* status ) {
102 CopySubjectToRequestInfo( requestInfo, subjectInfo ); // Create a request info for the proxy from our subject info
103 Bitmap* retval = TheManager->Load( &requestInfo, status );
104 CopySubjectToSubjectInfo( subjectInfo, requestInfo ); // Copy the the updated subject info into our subject info
105 return retval;
106 }
107
BitmapNonProxy_GoTo(BitmapInfo & requestInfo,Bitmap * map)108 BMMRES BitmapNonProxy_GoTo( BitmapInfo& requestInfo, Bitmap* map ) {
109 requestInfo.ResetFlags( MAP_PROXYREQUEST );
110 BMMRES retval = map->GoTo(&requestInfo);
111 return retval;
112 }
113
BitmapProxy_GoTo(BitmapInfo & subjectInfo,BitmapInfo & requestInfo,Bitmap * map)114 BMMRES BitmapProxy_GoTo( BitmapInfo& subjectInfo, BitmapInfo& requestInfo, Bitmap* map ) {
115 BitmapInfo backupRequestInfo = requestInfo;
116 CopySubjectToRequestInfo( requestInfo, subjectInfo ); // Create a request info for the proxy from our subject info
117 BMMRES retval = map->GoTo( &requestInfo );
118 CopySubjectToSubjectInfo( subjectInfo, requestInfo ); // Copy the the updated subject info into our subject info
119
120 // Restore the original request information if the bitmap doesn't have multiple frames.
121 // This is necessary to avoid losing proxy information from the requestInfo
122 if(retval == BMMRES_SINGLEFRAME) {
123 requestInfo = backupRequestInfo;
124 }
125 return retval;
126 }
127 }
128
129 //------------------------------------------------------------------------
130 // BMTexPathAccessor -- Methods
131 //------------------------------------------------------------------------
132
BMTexPathAccessor(BMTex * aTex)133 BMTexPathAccessor::BMTexPathAccessor(BMTex* aTex) : mTex(aTex) {
134 DbgAssert(aTex);
135 }
136
~BMTexPathAccessor()137 BMTexPathAccessor::~BMTexPathAccessor() {
138 }
139
GetPath() const140 MaxSDK::Util::Path BMTexPathAccessor::GetPath() const {
141 return MaxSDK::Util::Path(mTex->GetMapName());
142 }
143
144
SetPath(const MaxSDK::Util::Path & aNewPath)145 void BMTexPathAccessor::SetPath(const MaxSDK::Util::Path& aNewPath) {
146 mTex->pblock->SetValue(bmtex_filename, 0, const_cast<TCHAR*>(aNewPath.GetCStr()));
147 }
148
IsInputAsset() const149 bool BMTexPathAccessor::IsInputAsset() const {
150 return true;
151 }
152
GetAssetType() const153 int BMTexPathAccessor::GetAssetType() const {
154 return IAssetAccessor::kBitmapAsset;
155 }
156
GetAssetDesc() const157 const TCHAR* BMTexPathAccessor::GetAssetDesc() const {
158 return NULL;
159 }
GetAssetClientDesc() const160 const TCHAR* BMTexPathAccessor::GetAssetClientDesc() const {
161 return NULL;
162 }
IsAssetPathWritable() const163 bool BMTexPathAccessor::IsAssetPathWritable() const {
164 return true;
165 }
166
167
168 TCHAR BMTex::s_lastName[MAX_PATH];
169 ParamDlg* BMTex::uvGenDlg;
170 ParamDlg* BMTex::texoutDlg;
171 BMTexDlg* BMTex::paramDlg;
172
173 //------------------------------------------------------------------------
174 // BMSampler -- Methods
175 //------------------------------------------------------------------------
BMSampler()176 BMSampler::BMSampler()
177 : bm(NULL),
178 ufac(0.0f),
179 vfac(0.0f),
180 fbmw(0.0f),
181 fbmh(0.0f)
182 {
183 }
184
Init(BMTex * bmt,Bitmap * bm)185 void BMSampler::Init(BMTex *bmt, Bitmap *bm) {
186
187 if (bm == NULL)
188 this->bm = bmt->GetActiveBitmap();
189 else this->bm = bm;
190
191 tex = bmt;
192 alphaSource = bmt->alphaSource;
193 if (this->bm) {
194 u0 = tex->clipu;
195 v0 = tex->clipv;
196 u1 = tex->clipu + tex->clipw;
197 v1 = tex->clipv + tex->cliph;
198 ufac= tex->clipw;
199 vfac = tex->cliph;
200 bmw = this->bm->Width();
201 bmh = this->bm->Height();
202 fbmw = float(bmw/*-1*/); // DS 4/23/99
203 fbmh = float(bmh/*-1*/); // DS 4/23/99
204 clipx = int(tex->clipu*fbmw);
205 clipy = int(tex->clipv*fbmh);
206 fclipw = tex->clipw*fbmw;
207 fcliph = tex->cliph*fbmh;
208 cliph = int(fcliph);
209 ujit = tex->jitter*(1.0f-ufac);
210 vjit = tex->jitter*(1.0f-vfac);
211 }
212 }
213
214
Jitter(ShadeContext & sc,float ujit,float vjit,float & ru,float & rv,int iu,int iv)215 static inline void Jitter(ShadeContext &sc, float ujit, float vjit, float &ru, float &rv, int iu, int iv) {
216 // srand(((sc.uTile+593)*14693+(sc.vTile+4991)*2517)&0x7fff);
217 srand(((iu+593)*14693+(iv+967)*29517)&0x7fff);
218 int urnd = rand()&0x7fff;
219 rand(); // these extra calls seem to make the pattern more random
220 rand(); // these extra calls seem to make the pattern more random
221 int vrnd = rand()&0x7fff;
222 ru = ujit*float(urnd)/float(32767.0f);
223 rv = vjit*float(vrnd)/float(32767.0f);
224 }
225
PlaceUV(ShadeContext & sc,float & u,float & v,int iu,int iv)226 int BMSampler::PlaceUV(ShadeContext &sc, float &u, float &v, int iu, int iv) {
227 /* Avoid division by zero: make sure we don't have zero.*/
228 if((ufac != 0) && (vfac != 0)) {
229 if (tex->randPlace) {
230 float ru,rv;
231 Jitter(sc,ujit,vjit,ru,rv,iu,iv);
232 if (u<ru||v<rv||u>ru+ufac||v>rv+vfac)
233 return 0;
234 // note jitter ignores u0,v0, effectively setting them to zero
235 u = (u-ru)/ufac;
236 v = (v-rv)/vfac;
237 }
238 else {
239 if (u<u0||v<v0||u>u1||v>v1)
240 return 0;
241 u = (u-u0)/ufac;
242 v = (v-v0)/vfac;
243 }
244 return 1;
245 }
246 else {
247 return 0;
248 }
249 }
250
PlaceUVFilter(ShadeContext & sc,float & u,float & v,int iu,int iv)251 int BMSampler::PlaceUVFilter(ShadeContext &sc, float &u, float &v, int iu, int iv) {
252
253 /* Avoid division by zero: make sure we don't have zero.*/
254 if((ufac != 0) && (vfac != 0)) {
255 if (tex->randPlace) {
256 float ru,rv;
257 Jitter(sc,ujit,vjit,ru,rv,iu,iv);
258 // note jitter ignores u0,v0, effectively setting them to zero
259 u = (u-ru)/ufac;
260 v = (v-rv)/vfac;
261 }
262 else {
263 u = (u-u0)/ufac;
264 v = (v-v0)/vfac;
265 }
266 return 1;
267 }
268 else {
269 return 0;
270 }
271 }
272
Sample(ShadeContext & sc,float u,float v)273 AColor BMSampler::Sample(ShadeContext& sc, float u,float v) {
274 BMM_Color_fl c;
275 int x,y;
276 float fu,fv;
277 fu = frac(u);
278 fv = 1.0f-frac(v);
279 if (fu >= 1.0f)
280 fu = 0.0f;
281 if (fv >= 1.0f)
282 fv = 0.0f;
283 if (tex->applyCrop) {
284 if (tex->placeImage) {
285 if (!PlaceUV(sc,fu, fv, int(u), int(v)))
286 return black;
287 x = (int)(fu*fbmw);
288 y = (int)(fv*fbmh);
289 }
290 else {
291 x = mod(clipx + (int)(fu*fclipw),bmw);
292 y = mod(clipy + (int)(fv*fcliph),bmh);
293 }
294 }
295 else {
296 x = (int)(fu*fbmw);
297 y = (int)(fv*fbmh);
298 }
299 bm->GetLinearPixels(x,y,1,&c);
300 switch(alphaSource) {
301 case ALPHA_NONE: c.a = 1.0f; break;
302 case ALPHA_RGB: c.a = (c.r+c.g+c.b)/3;
303 if(c.a>1)c.a=1;
304 else if(c.a<0)c.a=0;
305 break;
306 // TBD
307 // XPCOL needs to be handled in bitmap for filtering.
308 // Need to open a bitmap with this property.
309 // case ALPHA_XPCOL: break;
310 }
311 return c;
312 }
313
314
SampleFilter(ShadeContext & sc,float u,float v,float du,float dv)315 AColor BMSampler::SampleFilter(ShadeContext& sc, float u,float v, float du, float dv) {
316 BMM_Color_fl c;
317 float fu,fv;
318 fu = frac(u);
319 fv = 1.0f-frac(v);
320 if (tex->applyCrop) {
321 if (tex->placeImage) {
322 if(!PlaceUVFilter(sc,fu, fv, int(u), int(v))) {
323 return black;
324 }
325 du /= ufac;
326 dv /= vfac;
327 float du2 = 0.5f*du;
328 float ua = fu-du2;
329 float ub = fu+du2;
330 if (ub<=0.0f||ua>=1.0f) return black;
331 float dv2 = 0.5f*dv;
332 float va = fv-dv2;
333 float vb = fv+du2;
334 if (vb<=0.0f||va>=1.0f) return black;
335 BOOL clip = 0;
336 if (ua<0.0f) { ua=0.0f; clip = 1; }
337 if (ub>1.0f) { ub=1.0f; clip = 1; }
338 if (va<0.0f) { va=0.0f; clip = 1; }
339 if (vb>1.0f) { vb=1.0f; clip = 1; }
340 bm->GetFiltered(fu,fv,du,dv,&c);
341 switch(alphaSource) {
342 case ALPHA_NONE: c.a = 1.0f; break;
343 case ALPHA_RGB: c.a = (c.r+c.g+c.b)/3;
344 if(c.a>1)c.a=1;
345 else if(c.a<0)c.a=0;
346 break;
347 }
348 AColor ac(c);
349 if (clip) {
350 float f = ((ub-ua)/du) * ((vb-va)/dv);
351 ac *= f;
352 }
353 return ac;
354 }
355 else {
356 fu = (u0 + ufac*fu);
357 fv = (v0 + vfac*fv);
358 du *= ufac;
359 dv *= vfac;
360 bm->GetFiltered(fu,fv,du,dv,&c);
361 }
362 }
363
364 else
365 bm->GetFiltered(fu,fv,du,dv,&c);
366 switch(alphaSource) {
367 case ALPHA_NONE: c.a = 1.0f; break;
368 case ALPHA_RGB: c.a = (c.r+c.g+c.b)/3;
369 if(c.a>1)c.a=1;
370 else if(c.a<0)c.a=0;
371 break;
372 }
373 return c;
374 }
375
376
377 //------------------------------------------------------------------------
378 // BMAlphaSampler -- Methods
379 //------------------------------------------------------------------------
380
SampleMono(ShadeContext & sc,float u,float v)381 float BMAlphaSampler::SampleMono(ShadeContext& sc, float u,float v) {
382 BMM_Color_fl c;
383 int x,y;
384 float fu,fv;
385 fu = frac(u);
386 fv = 1.0f-frac(v);
387 if (fu >= 1.0f)
388 fu = 0.0f;
389 if (fv >= 1.0f)
390 fv = 0.0f;
391 if (tex->applyCrop) {
392 if (tex->placeImage) {
393 if (!PlaceUV(sc,fu,fv,int(u),int(v))) return 0.0f;
394 x = (int)(fu*fclipw);
395 y = (int)(fv*fcliph);
396 }
397 else {
398 x = mod(clipx + (int)(fu*fclipw),bmw);
399 y = mod(clipy + (int)(fv*fcliph),bmh);
400 }
401 }
402 else {
403 x = (int)(fu*fbmw);
404 y = (int)(fv*fbmh);
405 }
406 bm->GetLinearPixels(x,y,1,&c);
407 return( c.a);
408 }
409
SampleMonoFilter(ShadeContext & sc,float u,float v,float du,float dv)410 float BMAlphaSampler::SampleMonoFilter(ShadeContext& sc, float u,float v, float du, float dv) {
411 BMM_Color_fl c;
412 float fu,fv;
413 fu = frac(u);
414 fv = 1.0f-frac(v);
415 if (tex->applyCrop) {
416 if (tex->placeImage) {
417 if(!PlaceUVFilter(sc,fu, fv, int(u), int(v))) {
418 return 0.0f;
419 }
420 du /= ufac;
421 dv /= vfac;
422 float du2 = 0.5f*du;
423 float ua = fu-du2;
424 float ub = fu+du2;
425 if (ub<=0.0f||ua>=1.0f) return 0.0f;
426 float dv2 = 0.5f*dv;
427 float va = fv-dv2;
428 float vb = fv+du2;
429 if (vb<=0.0f||va>=1.0f) return 0.0f;
430 BOOL clip = 0;
431 if (ua<0.0f) { ua=0.0f; clip = 1; }
432 if (ub>1.0f) { ub=1.0f; clip = 1; }
433 if (va<0.0f) { va=0.0f; clip = 1; }
434 if (vb>1.0f) { vb=1.0f; clip = 1; }
435 bm->GetFiltered(fu,fv,du,dv,&c);
436 float alph = c.a;
437 if (clip) {
438 float f = ((ub-ua)/du) * ((vb-va)/dv);
439 alph *= f;
440 }
441 return alph;
442 }
443 else {
444 fu = frac(u0 + ufac*fu);
445 fv = frac(v0 + vfac*fv);
446 du *= ufac;
447 dv *= vfac;
448 }
449 }
450 bm->GetFiltered(fu,fv,du,dv,&c);
451 return( c.a);
452 }
453
454 //------------------------------------------------------------------------
455 // BMCropper -- Methods
456 //------------------------------------------------------------------------
457
458 #ifndef NO_MTLEDITOR_BITMAP_CROPPING
Init(BMTexDlg * txdlg,TimeValue t)459 void BMCropper::Init(BMTexDlg *txdlg, TimeValue t) {
460 dlg = txdlg;
461 tex = txdlg->theBMTex;
462 u0 = tex->GetClipU(t);
463 v0 = tex->GetClipV(t);
464 w0 = tex->GetClipW(t);
465 h0 = tex->GetClipH(t);
466 mode= tex->placeImage;
467 }
468
SetValues(float u,float v,float w,float h,BOOL md)469 void BMCropper::SetValues(float u, float v, float w, float h, BOOL md) {
470 BOOL b = FALSE;
471 if (u!=tex->clipu) {
472 tex->SetClipU(dlg->ip->GetTime(), u);
473 b = TRUE;
474 }
475 if (v!=tex->clipv) {
476 tex->SetClipV(dlg->ip->GetTime(), v);
477 b = TRUE;
478 }
479 if (w!=tex->clipw) {
480 tex->SetClipW(dlg->ip->GetTime(), w);
481 b = TRUE;
482 }
483 if (h!=tex->cliph) {
484 tex->SetClipH(dlg->ip->GetTime(), h);
485 b = TRUE;
486 }
487
488 if (md!=tex->placeImage) {
489 tex->placeImage= md;
490 b = TRUE;
491 }
492
493 if(b) {
494 tex->DiscardTexHandle();
495 tex->NotifyChanged();
496 dlg->UpdateMtlDisplay();
497 }
498 }
499
OnClose()500 void BMCropper::OnClose(){
501 dlg->cropping = FALSE;
502 }
503 #endif // !NO_MTLEDITOR_BITMAP_CROPPING
504
505 //------------------------------------------------------------------------
506 // BMTexNotify -- Methods
507 //------------------------------------------------------------------------
508
Changed(ULONG flags)509 int BMTexNotify::Changed(ULONG flags) {
510 //-- File has been reloaded and it must be reflected as such
511 if (flags == BMNOTIFY_FLAG_STORAGE_CHANGE) {
512 tex->NotifyChanged();
513 tex->DiscardTexHandle();
514 //-- File has been changed and must be reloaded
515 // GG: 02/10/02
516 } else if (flags == BMNOTIFY_FLAG_FILE_CHANGE) {
517 tex->fnReload();
518 }
519 return 1;
520 }
521
522 //------------------------------------------------------------------------
523 //------------------------------------------------------------------------
524
525 int numBMTexs = 0;
526 class BMTexClassDesc:public ClassDesc2 {
527 public:
IsPublic()528 int IsPublic() { return 1; }
529 void * Create(BOOL loading);
530 // { return new BMTex; }
ClassName()531 const TCHAR * ClassName() { return GetString(IDS_DS_BITMAP_CDESC); } // mjm - 2.3.99
SuperClassID()532 SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
ClassID()533 Class_ID ClassID() { return bmTexClassID; }
Category()534 const TCHAR* Category() { return TEXMAP_CAT_2D; }
535 // PW: new descriptor data accessors added. Note that the
536 // internal name is hardwired since it must not be localized.
InternalName()537 const TCHAR* InternalName() { return _T("bitmapTex"); } // returns fixed parsable name (scripter-visible name)
HInstance()538 HINSTANCE HInstance() { return hInstance; } // returns owning module handle
539
540 };
541
542 static BMTexClassDesc bmTexCD;
543
bmFilterType(int filt_type)544 static int bmFilterType(int filt_type) {
545 switch(filt_type) {
546 case FILTER_PYR: return BMM_FILTER_PYRAMID;
547 case FILTER_SAT: return BMM_FILTER_SUM;
548 default: return BMM_FILTER_NONE;
549 }
550 }
551
552
GetBMTexDesc()553 ClassDesc* GetBMTexDesc() { return &bmTexCD; }
554
555 class BMTexPBAccessor : public PBAccessor
556 {
557 public:
Set(PB2Value & val,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)558 void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
559 {
560 BMTex* bmt = (BMTex*)owner;
561 switch (id)
562 {
563 case bmtex_bitmap:
564 {
565 // 425397
566 // The code has been removed because "ReloadBitmapAndUpdate" calls the param block to get a pointer to "bmtex_bitmap"
567 // The documentation is pretty clear about the fact that PBAccessor::Set is called right before the PB is changed.
568 // The bmtex was reloading using the old data. Because the map was getting deleted, the process was acessing deleted memory
569 //
570 // I changed "NotifyRefChanged" to properly handle the change and reload its data.
571 //if (!bmt->loading) {
572 // bmt->ReloadBitmapAndUpdate();
573 // // send message so browser/navigator name gets updated
574 // bmt->NotifyDependents(FOREVER,PART_ALL,REFMSG_SUBANIM_STRUCTURE_CHANGED);
575 // }
576 break;
577 }
578 case bmtex_filename:
579 {
580 bmt->SetMapName(val.s);
581 break;
582 }
583 case bmtex_filtering:
584 //bmt->SetFilterType(val.i);
585 bmt->filterType = val.i;
586 bmt->m_theBitmap.SetFilter(bmFilterType(val.i));
587 break;
588 case bmtex_clipu: {
589 float u = val.f;
590 float w = bmt->GetClipW(t);
591 if (u+w>1.0f)
592 bmt->SetClipW(t,1.0f-u);
593 break;
594 }
595 case bmtex_clipv: {
596 float v = val.f;
597 float h = bmt->GetClipH(t);
598 if (v+h>1.0f)
599 bmt->SetClipH(t,1.0f-v);
600 break;
601 }
602 case bmtex_clipw: {
603 float w = val.f;
604 float u = bmt->GetClipU(t);
605 if (u+w>1.0f)
606 bmt->SetClipU(t,1.0f-w);
607 break;
608 }
609 case bmtex_cliph: {
610 float h = val.f;
611 float v = bmt->GetClipV(t);
612 if (v+h>1.0f)
613 bmt->SetClipV(t,1.0f-h);
614 break;
615 }
616 }
617 }
Get(PB2Value & v,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t,Interval & valid)618 void Get(PB2Value& v, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t, Interval &valid) // get into v
619 {
620 BMTex* bmt = (BMTex*)owner;
621 switch (id)
622 {
623 case bmtex_filename:
624 {
625 v.s = bmt->GetMapName();
626 break;
627 }
628
629 }
630 }
631 };
632
633 static BMTexPBAccessor bmtex_accessor;
634
635 static ParamBlockDesc2 bmtex_param_blk ( bmtex_params, _T("parameters"), 0, &bmTexCD, P_AUTO_CONSTRUCT + P_AUTO_UI, PBLOCK_REF,
636 //rollout
637 IDD_BMTEX, IDS_DS_BITMAP_PARAMS, 0, 0, NULL,
638 // params
639
640 bmtex_clipu, _T("clipu"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_CLIPU,
641 p_default, 0.0,
642 p_range, 0.0, 1.0,
643 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_X, IDC_CLIP_XSPIN, 0.001f,
644 p_accessor, &bmtex_accessor,
645 end,
646 bmtex_clipv, _T("clipv"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_CLIPV,
647 p_default, 0.0,
648 p_range, 0.0, 1.0,
649 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_Y, IDC_CLIP_YSPIN, 0.001f,
650 p_accessor, &bmtex_accessor,
651 end,
652 bmtex_clipw, _T("clipw"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_CLIPW,
653 p_default, 0.0,
654 p_range, 0.0, 1.0,
655 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_W, IDC_CLIP_WSPIN, 0.001f,
656 p_accessor, &bmtex_accessor,
657 end,
658 bmtex_cliph, _T("cliph"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_CLIPH,
659 p_default, 0.0,
660 p_range, 0.0, 1.0,
661 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_CLIP_H, IDC_CLIP_HSPIN, 0.001f,
662 p_accessor, &bmtex_accessor,
663 end,
664 bmtex_jitter, _T("jitter"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_JITTERAMT,
665 p_default, 0.0,
666 p_range, 0.0, 1.0,
667 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_JITTER_EDIT, IDC_JITTER_SPIN, 0.01f,
668 end,
669 bmtex_usejitter, _T("useJitter"), TYPE_BOOL, 0, IDS_PW_USEJITTER,
670 p_default, FALSE,
671 p_ui, TYPE_SINGLECHEKBOX, IDC_BM_JITTER,
672 end,
673 bmtex_apply, _T("apply"), TYPE_BOOL, 0, IDS_PW_APPLY,
674 p_default, FALSE,
675 p_ui, TYPE_SINGLECHEKBOX, IDC_BM_CLIP,
676 end,
677 bmtex_crop_place, _T("cropPlace"), TYPE_INT, 0, IDS_PW_CROPPLACE,
678 p_default, 0,
679 p_range, 0, 1,
680 p_ui, TYPE_RADIO, 2, IDC_BM_CROP,IDC_BM_PLACE,
681 end,
682
683 bmtex_filtering, _T("filtering"), TYPE_INT, 0, IDS_PW_FILTERING,
684 p_default, 0,
685 p_range, 0, 2,
686 p_ui, TYPE_RADIO, 3, IDC_FILTER_PYR, IDC_FILTER_SAT,IDC_FILTER_NADA,
687 p_accessor, &bmtex_accessor,
688 end,
689 bmtex_monooutput, _T("monoOutput"), TYPE_INT, 0, IDS_PW_MONOOUTPUT,
690 p_default, 0,
691 p_range, 0, 1,
692 p_ui, TYPE_RADIO, 2, IDC_BMTEX_RGBOUT, IDC_BMTEX_ALPHAOUT,
693 end,
694 bmtex_rgboutput, _T("rgbOutput"), TYPE_INT, 0, IDS_PW_RGBOUTPUT,
695 p_default, 0,
696 p_range, 0, 1,
697 p_ui, TYPE_RADIO, 2, IDC_BMTEX_RGBOUT2, IDC_BMTEX_ALPHAOUT2,
698 end,
699 bmtex_alphasource, _T("alphaSource"), TYPE_INT, 0, IDS_PW_ALPHASOURCE,
700 p_default, 0,
701 p_range, 0, 2,
702 p_ui, TYPE_RADIO, 3, IDC_ALPHA_FILE, IDC_ALPHA_RGB,IDC_ALPHA_NONE,
703 end,
704
705 bmtex_premultalpha, _T("preMultAlpha"), TYPE_BOOL, 0, IDS_PW_PREMULT,
706 p_default, TRUE,
707 p_ui, TYPE_SINGLECHEKBOX, IDC_ALPHA_PREMULT,
708 end,
709
710 bmtex_bitmap, _T("bitmap"), TYPE_BITMAP, 0, IDS_DS_BITMAP,
711 p_ui, TYPE_BITMAPBUTTON, IDC_BMTEX_NAME,
712 p_accessor, &bmtex_accessor,
713 end,
714
715 bmtex_coords, _T("coords"), TYPE_REFTARG, P_OWNERS_REF, IDS_DS_COORDINATES,
716 p_refno, UVGEN_REF,
717 end,
718 bmtex_output, _T("output"), TYPE_REFTARG, P_OWNERS_REF, IDS_DS_TEXOUT,
719 p_refno, TEXOUT_REF,
720 end,
721
722 bmtex_filename, _T("fileName"), TYPE_FILENAME, P_TRANSIENT, IDS_JW_FILENAME,
723 p_accessor, &bmtex_accessor,
724 end,
725
726 end
727 );
728
729
730
731
732 class BMTexPBTimeAccessor : public PBAccessor
733 {
734 public:
Set(PB2Value & val,ReferenceMaker * owner,ParamID id,int tabIndex,TimeValue t)735 void Set(PB2Value& val, ReferenceMaker* owner, ParamID id, int tabIndex, TimeValue t) // set from v
736 {
737 BMTex* bmt = (BMTex*)owner;
738 switch (id) {
739 case bmtex_start:
740 bmt->startTime = val.i;
741 break;
742 case bmtex_playbackrate:
743 bmt->pbRate= val.f;
744 break;
745 case bmtex_endcondition:
746 bmt->endCond = val.i;
747 break;
748 case bmtex_matidtime:
749 bmt->FreeBitmap();
750 break;
751 }
752 }
753 };
754
755 static BMTexPBTimeAccessor bmtextime_accessor;
756
757 // aszabo|Oct.30.01 - 312037 UI for Time rollout should be built.
758 // Fixing incorrect removal of UI dates back to R3
759 #ifdef NO_MTLEDITOR_BITMAP_TIME_ROLLOUT
760 #define TIME_PB_FLAGS P_AUTO_CONSTRUCT
761 #else // !NO_MTLEDITOR_BITMAP_TIME_ROLLOUT
762 #define TIME_PB_FLAGS P_AUTO_CONSTRUCT + P_AUTO_UI
763 #endif // !NO_MTLEDITOR_BITMAP_TIME_ROLLOUT
764
765 static ParamBlockDesc2 bmtex_time_param_blk ( bmtex_time, _T("time parameters"), 0, &bmTexCD, TIME_PB_FLAGS, PBLOCKTIME_REF,
766
767 #ifndef NO_MTLEDITOR_BITMAP_TIME_ROLLOUT
768 //rollout
769 IDD_BMTEX_TIME, IDS_DS_TIME_PARAMS, 0, APPENDROLL_CLOSED, NULL,
770 #endif // !NO_MTLEDITOR_BITMAP_TIME_ROLLOUT
771
772 // params
773 bmtex_start, _T("startTime"), TYPE_TIMEVALUE, 0, IDS_PW_STARTTIME,
774 p_default, 0,
775 p_range, -1000000, 1000000,
776 p_ui, TYPE_SPINNER, EDITTYPE_INT, IDC_BMTEX_START, IDC_BMTEX_START_SPIN, 1.0f,
777 p_accessor, &bmtextime_accessor,
778 end,
779 bmtex_playbackrate, _T("playBackRate"), TYPE_FLOAT, 0, IDS_PW_PLAYBACK,
780 p_default, 1.0f,
781 p_range, 0.0f, 10000.0f,
782 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_BMTEX_RATE, IDC_BMTEX_RATE_SPIN, 1.0f,
783 p_accessor, &bmtextime_accessor,
784 end,
785 bmtex_endcondition, _T("endCondition"), TYPE_INT, 0, IDS_PW_ENDCONDITION,
786 p_default, 0,
787 p_range, 0, 2,
788 p_ui, TYPE_RADIO, 3, IDC_BMTEX_LOOP, IDC_BMTEX_PINGPONG,IDC_BMTEX_HOLD,
789 p_accessor, &bmtextime_accessor,
790 end,
791
792 bmtex_matidtime, _T("tieTimeToMatIDs"), TYPE_BOOL, 0, IDS_PW_MATIDTIME,
793 p_default, FALSE,
794 p_ui, TYPE_SINGLECHEKBOX, IDC_MATIDTIME_CHECK,
795 p_accessor, &bmtextime_accessor,
796 end,
797
798
799 end
800 );
801
802
803 //Function Publishing descriptor for Mixin interface
804 //*****************************************************
805 static FPInterfaceDesc bitmaptex_interface(
806 BITMAPTEX_INTERFACE, _T("bitmapTex"), 0, &bmTexCD, FP_MIXIN,
807 bitmaptex_reload, _T("reload"), 0, TYPE_VOID, 0, 0,
808 bitmaptex_crop, _T("viewImage"), 0, TYPE_VOID, 0, 0,
809 end
810 );
811
812
Create(BOOL loading)813 void * BMTexClassDesc::Create(BOOL loading)
814 {
815 AddInterface(&bitmaptex_interface);
816 return new BMTex;
817 }
818
819
GetDesc()820 FPInterfaceDesc* BitmapTex::GetDesc()
821 {
822 return &bitmaptex_interface;
823 }
824
825
826
SetEndCondition(int endcond)827 void BMTex::SetEndCondition(int endcond) {
828 pblockTime->SetValue( bmtex_endcondition, 0, endcond);
829 endCond = endcond;
830 // ParamID changedParam = pblockTime->LastNotifyParamID();
831 // bmtex_time_param_blk.InvalidateUI(changedParam);
832 }
SetStartTime(TimeValue t)833 void BMTex::SetStartTime(TimeValue t) {
834 pblockTime->SetValue( bmtex_start, 0, t);
835 startTime = t;
836 // ParamID changedParam = pblockTime->LastNotifyParamID();
837 // bmtex_time_param_blk.InvalidateUI(changedParam);
838 }
SetPlaybackRate(float r)839 void BMTex::SetPlaybackRate(float r) {
840 pblockTime->SetValue( bmtex_playbackrate, 0, r);
841 pbRate = r;
842 // ParamID changedParam = pblockTime->LastNotifyParamID();
843 // bmtex_time_param_blk.InvalidateUI(changedParam);
844 }
845
846
847 //------------------------------------------------------------------------
848 // BMTexDlg -- Methods
849 //------------------------------------------------------------------------
BMTexDlg(HWND hwMtlEdit,IMtlParams * imp,BMTex * m)850 BMTexDlg::BMTexDlg(HWND hwMtlEdit, IMtlParams *imp, BMTex *m)
851 : m_displayBitmap(NULL)
852 {
853 hwmedit = hwMtlEdit;
854 ip = imp;
855 hPanel = NULL;
856 theBMTex = m;
857 valid = FALSE;
858 isActive = FALSE;
859 cropping = FALSE;
860 curTime = imp->GetTime();
861
862 // hTime = 0;
863 curTime = 0;
864 }
865
ReloadDialog()866 void BMTexDlg::ReloadDialog() {
867 Interval valid;
868 theBMTex->Update(curTime, valid);
869 LoadDialog(FALSE);
870 }
871
Update(TimeValue t)872 void BMTexDlg::Update(TimeValue t) {
873 Interval valid;
874 curTime = t;
875 if (!theBMTex->ivalid.InInterval(t)) {
876 theBMTex->Update(curTime, valid);
877 #ifndef DESIGN_VER
878 LoadDialog(FALSE);
879 InvalidateRect(hPanel,NULL,0);
880 if (cropping) {
881 theBMTex->StuffCropValues();
882 }
883 #endif // !DESIGN_VER
884 }
885 }
886
887
~BMTexDlg()888 BMTexDlg::~BMTexDlg() {
889 RemoveCropImage();
890 theBMTex->paramDlg = NULL;
891 DLSetWindowLongPtr(hPanel, NULL);
892 hPanel = NULL;
893
894 // This should have been deleted, or else there'll be a memory leak.
895 DbgAssert(m_displayBitmap == NULL);
896 }
897
FreeBitmap()898 void BMTex::FreeBitmap() {
899
900 m_theBitmap.FreeBitmap();
901
902 for(int i = 0; i < m_theBitmapList.length(); ++i) {
903 BitmapHolder& bitmapHolder = m_theBitmapList[i];
904 bitmapHolder.FreeBitmap();
905 }
906
907 if (texHandle) {
908 texHandle->DeleteThis();
909 texHandle = NULL;
910 }
911 loadFailed = FALSE;
912 }
913
914
BMNameChanged()915 void BMTexDlg::BMNameChanged() {
916 theBMTex->FreeBitmap();
917 theBMTex->NotifyChanged();
918 StuffBMNameField(hPanel);
919 theBMTex->loadFailed = FALSE;
920 BMMRES res = theBMTex->LoadBitmap(ip->GetTime());
921 if (res==BMMRES_NODRIVER)
922 InvalidNameMsg(theBMTex->m_bi.Name());
923 EnableAlphaButtons(TRUE);
924 UpdateMtlDisplay();
925 }
926
KeyAtCurTime(int id)927 BOOL BMTexDlg::KeyAtCurTime(int id) { return theBMTex->pblock->KeyFrameAtTime(id,curTime); }
928
GetBMName(BitmapInfo & bi,TSTR & fname,BOOL full=FALSE)929 void GetBMName(BitmapInfo& bi, TSTR &fname, BOOL full=FALSE) {
930 TSTR fullName;
931 if (bi.Name()[0]==0)
932 fullName = bi.Device();
933 else
934 fullName = bi.Name();
935 if (full)
936 fname = fullName;
937 else
938 SplitPathFile(fullName,NULL,&fname);
939 }
940
StuffBMNameField(HWND hwndDlg)941 void BMTexDlg::StuffBMNameField(HWND hwndDlg) {
942
943 TSTR fname;
944 // GetBMName(theBMTex->bi,fname,TRUE);
945 // if (iName) {
946 // iName->SetText(fname.data());
947 // iName->SetTooltip(TRUE,fname.data());
948 // }
949 }
950
ShowCropImage()951 void BMTexDlg::ShowCropImage() {
952 if (!theBMTex) return;
953
954 // Disable proxy mode as we don't want to display a proxy image in the viewer.
955 BMTex::ProxyModeDisableGuard proxyModeDisabler(*theBMTex);
956
957 Bitmap *bm = theBMTex->GetActiveBitmap();
958 if (!bm) {
959 BMMRES res = theBMTex->LoadBitmap(ip->GetTime());
960 bm = theBMTex->GetActiveBitmap();
961 if (!bm) return;
962 }
963
964 // Create a new instance of the bitmap (pointing to the same storage), in order to ensure it's not
965 // deleted while the bitmap is being displayed, when the non-proxy is flushed as
966 // proxies are re-enabled. This fixes bug #787907.
967 if(m_displayBitmap != NULL) {
968 m_displayBitmap->DeleteThis();
969 m_displayBitmap = NULL;
970 }
971 m_displayBitmap = TheManager->NewBitmap();
972 if(m_displayBitmap != NULL) {
973 m_displayBitmap->SetStorage(bm->Storage());
974 m_displayBitmap->SetNotify(this);
975 CropCallback* cropCallback = NULL;
976
977 #ifndef NO_MTLEDITOR_BITMAP_CROPPING
978 cropper.Init(this,curTime);
979 cropCallback = &cropper;
980 #endif // !NO_MTLEDITOR_BITMAP_CROPPING
981
982 cropping = TRUE;
983 // Create an autonomous bitmap to have it deleted automatically when the viewer is closed.
984 int junk = m_displayBitmap->Display( GetString(IDS_DS_CROP_TITLE),BMM_CN, TRUE, FALSE, cropCallback);
985 }
986 else {
987 DbgAssert(false);
988 }
989 }
990
RemoveCropImage()991 void BMTexDlg::RemoveCropImage() {
992 cropping = FALSE;
993
994 // Delete the temporary bitmap that was created for the viewer.
995 if(m_displayBitmap != NULL) {
996 // UnDisplay() closes the viewer, but disables the "autonomous" mode on bitmaps, so we still
997 // need to delete the bitmap, even if it was declared as 'autonomous' when displayed.
998 // Need to use a copy of the bitmap pointer, since m_displayBitmap is null'ed in VFBClosed().
999 Bitmap* displayBM = m_displayBitmap;
1000 displayBM->UnDisplay();
1001 displayBM->DeleteThis();
1002 m_displayBitmap = NULL;
1003 }
1004 }
1005
Changed(ULONG flags)1006 int BMTexDlg::Changed(ULONG flags) {
1007
1008 // Do nothing
1009
1010 return 1;
1011 }
1012
VFBClosed()1013 void BMTexDlg::VFBClosed() {
1014
1015 // VFB was closed; the image will be deleted automatically because it was displayed
1016 // as "autonomous".
1017 m_displayBitmap = NULL;
1018 }
1019
1020 static int colID[2] = { IDC_CHECK_COL1, IDC_CHECK_COL2 };
1021
EnableAlphaButtons(BOOL isNew)1022 void BMTexDlg::EnableAlphaButtons(BOOL isNew) {
1023 if (hPanel==NULL) return;
1024 if (theBMTex->m_bi.Flags()&MAP_HAS_ALPHA) {
1025 EnableWindow(GetDlgItem(hPanel,IDC_ALPHA_FILE), 1);
1026 EnableWindow(GetDlgItem(hPanel,IDC_ALPHA_PREMULT), 1);
1027 EnableWindow(GetDlgItem(hPanel,IDC_BMTEX_ALPHAOUT), 1);
1028 EnableWindow(GetDlgItem(hPanel,IDC_BMTEX_ALPHAOUT2), 1);
1029 if (isNew) {
1030 theBMTex->SetAlphaSource(ALPHA_FILE);
1031 }
1032 }
1033 else {
1034 EnableWindow(GetDlgItem(hPanel,IDC_ALPHA_FILE), 0);
1035 EnableWindow(GetDlgItem(hPanel,IDC_ALPHA_PREMULT), 0);
1036 EnableWindow(GetDlgItem(hPanel,IDC_BMTEX_ALPHAOUT), 0);
1037 EnableWindow(GetDlgItem(hPanel,IDC_BMTEX_ALPHAOUT2), 0);
1038 if (theBMTex->alphaSource == ALPHA_FILE)
1039 theBMTex->SetAlphaSource(ALPHA_NONE);
1040 if (theBMTex->premultAlpha)
1041 theBMTex->SetPremultAlpha(TRUE);
1042 if (isNew) {
1043 if (theBMTex->alphaAsRGB)
1044 theBMTex->SetAlphaAsRGB(FALSE);
1045 if (theBMTex->alphaAsMono)
1046 theBMTex->SetAlphaAsMono(FALSE);
1047 }
1048 }
1049 }
1050
1051
EnableViewImage()1052 void BMTexDlg::EnableViewImage() {
1053 EnableWindow(GetDlgItem(hPanel,IDC_BM_CROP_IMAGE),(_tcslen(theBMTex->m_bi.Name())>0)?1:0);
1054 }
1055
DlgProc(TimeValue t,IParamMap2 * map,HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)1056 INT_PTR BMTexDlg::DlgProc(TimeValue t,IParamMap2 *map,HWND hwndDlg,UINT msg,WPARAM wParam,LPARAM lParam)
1057 {
1058 int id = LOWORD(wParam);
1059 int code = HIWORD(wParam);
1060 switch (msg) {
1061 case WM_INITDIALOG:
1062 {
1063 hPanel = map->GetHWnd();
1064 EnableAlphaButtons();
1065 EnableViewImage();
1066 return TRUE;
1067 }
1068 break;
1069 case WM_COMMAND:
1070 switch (id) {
1071 case IDC_BMTEX_NAME:
1072 {
1073 bmtex_param_blk.InvalidateUI(bmtex_bitmap);
1074
1075 if(HIWORD(wParam) == BN_CLICKED) {
1076 // Class ParamMap2UserDlgProc is called _after_ the default processing is complete,
1077 // meaning that the param block system has already recorded the new name for the bitmap.
1078 if((map != NULL) && (map->GetParamBlock() != NULL)) {
1079 ReferenceMaker* pbOwner = map->GetParamBlock()->GetOwner();
1080 if((pbOwner != NULL) && (pbOwner->ClassID() == bmTexClassID)) {
1081 BMTex* bmTex = static_cast<BMTex*>(pbOwner);
1082 bmTex->ShowBitmapProxyPrecacheDialog();
1083 }
1084 }
1085 }
1086 }
1087 break;
1088
1089 case IDC_ALPHA_FILE:
1090 case IDC_ALPHA_XPCOL:
1091 case IDC_ALPHA_RGB:
1092 case IDC_ALPHA_NONE:
1093 theBMTex->NotifyChanged();
1094 theBMTex->DiscardTexHandle();
1095 UpdateMtlDisplay();
1096 break;
1097 case IDC_FILTER_NADA:
1098 case IDC_FILTER_PYR:
1099 case IDC_FILTER_SAT:
1100 theBMTex->NotifyChanged();
1101 break;
1102 case IDC_BMTEX_RELOAD:
1103 theBMTex->ReloadBitmap(true);
1104 BroadcastNotification(NOTIFY_BITMAP_CHANGED, (void *)theBMTex->m_bi.Name());
1105 //theBMTex->NotifyChanged();
1106 UpdateMtlDisplay(); // redraw viewports
1107 Invalidate(); // incase path of map has changed.
1108 macroRec->OperandSequence(1, mr_prop, _T("bitmaptex.Reload()"),mr_reftarg, theBMTex);
1109
1110 break;
1111 case IDC_BMTEX_RGBOUT:
1112 case IDC_BMTEX_ALPHAOUT:
1113 theBMTex->NotifyChanged();
1114 break;
1115 case IDC_BMTEX_RGBOUT2:
1116 case IDC_BMTEX_ALPHAOUT2:
1117 theBMTex->NotifyChanged();
1118 theBMTex->DiscardTexHandle();
1119 UpdateMtlDisplay();
1120 break;
1121 case IDC_ALPHA_PREMULT:
1122 theBMTex->NotifyChanged();
1123 theBMTex->DiscardTexHandle();
1124 UpdateMtlDisplay();
1125 break;
1126 case IDC_BM_CLIP:
1127 // theBMTex->applyCrop = GetCheckBox(hwndDlg,id);
1128 theBMTex->NotifyChanged();
1129 theBMTex->DiscardTexHandle();
1130 UpdateMtlDisplay();
1131 break;
1132 case IDC_BM_CROP_IMAGE:
1133 ShowCropImage();
1134 macroRec->OperandSequence(1, mr_prop, _T("bitmaptex.ViewImage()"),mr_reftarg, theBMTex);
1135
1136 // macroRecorder->FunctionCall(_T("$.modifiers[#flex].quality"), 0, 0);
1137
1138 break;
1139 case IDC_BM_CROP:
1140 case IDC_BM_PLACE:
1141 // CheckRadioButton( hwndDlg, IDC_BM_CROP, IDC_BM_PLACE, id);
1142 // theBMTex->placeImage = id==IDC_BM_PLACE?1:0;
1143 theBMTex->NotifyChanged();
1144 theBMTex->DiscardTexHandle();
1145 UpdateMtlDisplay();
1146 if (cropping) theBMTex->StuffCropValues();
1147 theBMTex->EnableStuff();
1148 break;
1149 case IDC_BM_JITTER:
1150 // theBMTex->randPlace = GetCheckBox(hwndDlg,id);
1151 theBMTex->NotifyChanged();
1152 UpdateMtlDisplay();
1153 theBMTex->EnableStuff();
1154 break;
1155 }
1156 break;
1157
1158 case WM_PAINT:
1159 if (!valid) {
1160 valid = TRUE;
1161 ReloadDialog();
1162 }
1163 break;
1164
1165 case CC_SPINNER_CHANGE:
1166 if (!theHold.Holding()) theHold.Begin();
1167 // switch (id) {
1168 theBMTex->NotifyChanged();
1169 if (cropping) theBMTex->StuffCropValues();
1170 //need to make as an accesot
1171 /*
1172 case IDC_CLIP_XSPIN: {
1173 float u = 0.0f;//clipUSpin->GetFVal();
1174 theBMTex->SetClipU(curTime,u);
1175 // clipUSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPU));
1176 float w = theBMTex->GetClipW(curTime);
1177 if (u+w>1.0f) {
1178 w = 1.0f-u;
1179 theBMTex->SetClipW(curTime,w);
1180 // clipWSpin->SetValue(theBMTex->clipw,FALSE);
1181 // clipWSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPW));
1182 }
1183 theBMTex->NotifyChanged();
1184 if (cropping) theBMTex->StuffCropValues();
1185 }
1186 break;
1187 case IDC_CLIP_YSPIN: {
1188 float v = 0.0f;//clipVSpin->GetFVal();
1189 theBMTex->SetClipV(curTime,v);
1190 // clipVSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPV));
1191 float h = theBMTex->GetClipH(curTime);
1192 if (v+h>1.0f) {
1193 h = 1.0f-v;
1194 theBMTex->SetClipH(curTime,h);
1195 // clipHSpin->SetValue(theBMTex->cliph,FALSE);
1196 // clipHSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPH));
1197 }
1198 theBMTex->NotifyChanged();
1199 if (cropping) theBMTex->StuffCropValues();
1200 }
1201 break;
1202 case IDC_CLIP_WSPIN: {
1203 float w = 0.0f;//clipWSpin->GetFVal();
1204 theBMTex->SetClipW(curTime,w);
1205 // clipWSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPW));
1206 float u = theBMTex->GetClipU(curTime);
1207 if (u+w>1.0f) {
1208 u = 1.0f-w;
1209 theBMTex->SetClipU(curTime,u);
1210 // clipUSpin->SetValue(theBMTex->clipu,FALSE);
1211 // clipUSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPU));
1212 }
1213 theBMTex->NotifyChanged();
1214 if (cropping) theBMTex->StuffCropValues();
1215 }
1216 break;
1217 case IDC_CLIP_HSPIN: {
1218 float h = 0.0f;//clipHSpin->GetFVal();
1219 theBMTex->SetClipH(curTime,h);
1220 // clipHSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPH));
1221 float v = theBMTex->GetClipV(curTime);
1222 if (v+h>1.0f) {
1223 v = 1.0f-h;
1224 theBMTex->SetClipV(curTime,v);
1225 // clipVSpin->SetValue(theBMTex->clipv,FALSE);
1226 // clipVSpin->SetKeyBrackets(KeyAtCurTime(PB_CLIPV));
1227 }
1228 theBMTex->NotifyChanged();
1229 if (cropping) theBMTex->StuffCropValues();
1230 }
1231 break;
1232 case IDC_JITTER_SPIN:
1233 // theBMTex->SetJitter(curTime,jitterSpin->GetFVal());
1234 // jitterSpin->SetKeyBrackets(KeyAtCurTime(PB_JITTER));
1235 theBMTex->NotifyChanged();
1236 break;
1237 */
1238
1239 // }
1240 break;
1241 case CC_SPINNER_BUTTONDOWN:
1242 theHold.Begin();
1243 break;
1244 case WM_CUSTEDIT_ENTER:
1245 case CC_SPINNER_BUTTONUP:
1246 if (HIWORD(wParam) || msg==WM_CUSTEDIT_ENTER) theHold.Accept(GetString(IDS_DS_PARAMCHG));
1247 else theHold.Cancel();
1248 theBMTex->DiscardTexHandle();
1249 theBMTex->NotifyChanged();
1250 UpdateMtlDisplay();
1251 if (cropping) theBMTex->StuffCropValues();
1252 break;
1253 case WM_DESTROY:
1254 RemoveCropImage();
1255 break;
1256 }
1257 return FALSE;
1258 }
1259
1260
1261
LoadDialog(BOOL draw)1262 void BMTexDlg::LoadDialog(BOOL draw) {
1263 if (theBMTex) {
1264 Interval valid;
1265 theBMTex->Update(curTime,valid);
1266 StuffBMNameField(hPanel);
1267 CheckRadioButton( hPanel, IDC_ALPHA_FILE, IDC_ALPHA_NONE, IDC_ALPHA_FILE+theBMTex->alphaSource);
1268 CheckRadioButton( hPanel, IDC_FILTER_PYR, IDC_FILTER_NADA, IDC_FILTER_PYR+theBMTex->filterType);
1269 CheckRadioButton( hPanel, IDC_BMTEX_RGBOUT, IDC_BMTEX_ALPHAOUT, IDC_BMTEX_RGBOUT+theBMTex->alphaAsMono);
1270 CheckRadioButton( hPanel, IDC_BMTEX_RGBOUT2, IDC_BMTEX_ALPHAOUT2, IDC_BMTEX_RGBOUT2+theBMTex->alphaAsRGB);
1271 SetCheckBox( hPanel, IDC_ALPHA_PREMULT, theBMTex->premultAlpha);
1272 SetCheckBox( hPanel, IDC_BM_CLIP, theBMTex->applyCrop);
1273 EnableAlphaButtons(FALSE);
1274 }
1275 }
1276
ClassID()1277 Class_ID BMTexDlg::ClassID() {
1278
1279 return bmTexClassID;
1280 }
1281
SetThing(ReferenceTarget * m)1282 void BMTexDlg::SetThing(ReferenceTarget *m) {
1283 assert (m->ClassID()==bmTexClassID);
1284 assert (m->SuperClassID()==TEXMAP_CLASS_ID);
1285 RemoveCropImage();
1286 if (theBMTex) {
1287 theBMTex->paramDlg = NULL;
1288 }
1289 theBMTex = (BMTex *)m;
1290 if (theBMTex) theBMTex->paramDlg = this;
1291 LoadDialog(TRUE);
1292 }
1293
1294 //------------------------------------------------------------------------
1295 // BMTex -- Methods
1296 //------------------------------------------------------------------------
1297
1298
1299
1300 #define BMTEX_VERSION 3
1301
1302 static ParamBlockDescID pbdesc1[] = {
1303 { TYPE_FLOAT, NULL, TRUE,1} // blur
1304 };
1305
1306 static ParamBlockDescID pbdesc2[] = {
1307 { TYPE_FLOAT, NULL, TRUE,bmtex_clipu }, // clipu
1308 { TYPE_FLOAT, NULL, TRUE,bmtex_clipv }, // clipv
1309 { TYPE_FLOAT, NULL, TRUE,bmtex_clipw }, // clipw
1310 { TYPE_FLOAT, NULL, TRUE,bmtex_cliph }, // cliph
1311 { TYPE_FLOAT, NULL, TRUE,bmtex_jitter } // jitter
1312 };
1313
1314 static ParamVersionDesc oldVersions[] = {
1315 ParamVersionDesc(pbdesc1, 1, 0),
1316 ParamVersionDesc(pbdesc1, 1, 1),
1317 ParamVersionDesc(pbdesc2, 4, 2),
1318 ParamVersionDesc(pbdesc2, 5, 3)
1319 };
1320 /*
1321 static ParamVersionDesc oldVersions[] = {
1322 ParamVersionDesc(pbdesc2, 5, 2)
1323 };
1324 */
1325 #define NUMOLDVERSIONS 4
1326 //static ParamVersionDesc curVersion(pbdesc2,5,BMTEX_VERSION);
1327
1328 //static int name_id[NPARAMS] = { IDS_DS_CLIPU, IDS_DS_CLIPV, IDS_DS_CLIPW, IDS_DS_CLIPH, IDS_DS_JITTERAMT };
1329
Init()1330 void BMTex::Init() {
1331 if (uvGen) uvGen->Reset();
1332 else ReplaceReference( 0, GetNewDefaultUVGen());
1333 // ReplaceReference( 1, CreateParameterBlock( pbdesc2, NPARAMS, BMTEX_VERSION) );
1334 if (texout) texout->Reset();
1335 else ReplaceReference( 2, GetNewDefaultTextureOutput());
1336 placeImage = FALSE;
1337 randPlace = FALSE;
1338 filterType = FILTER_PYR;
1339 alphaSource = ALPHA_FILE;
1340 alphaAsMono = FALSE;
1341 alphaAsRGB = FALSE;
1342 premultAlpha = TRUE;
1343 SetClipU(0,0.0f);
1344 SetClipV(0,0.0f);
1345 SetClipW(0,1.0f);
1346 SetClipH(0,1.0f);
1347 SetJitter(0,1.0f);
1348 ivalid.SetEmpty();
1349 clipValid.SetInfinite();
1350 mTieTimeToMatID = FALSE; // LAM - 4/21/03
1351 isNew = FALSE;
1352 rumax = rvmax = -100000.0f;
1353 rumin = rvmin = +100000.0f;
1354 }
1355
Reset()1356 void BMTex::Reset() {
1357 bmTexCD.Reset(this, TRUE); // reset all pb2's
1358 if (!isNew) {
1359 FreeBitmap();
1360 NotifyChanged();
1361 if (paramDlg) paramDlg->UpdateMtlDisplay();
1362 }
1363 Init();
1364 }
1365
NotifyChanged()1366 void BMTex::NotifyChanged() {
1367 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
1368 }
1369
1370 #ifdef DESIGN_VER
SetGeoReferenceInfo(BitmapInfo & bi,StdUVGen * uvGen)1371 void BMTex::SetGeoReferenceInfo(BitmapInfo & bi, StdUVGen * uvGen)
1372 {
1373 TheManager->Execute(BMM_RETRIEVE_GEOREF_DATA,
1374 ULONG_PTR(bi.Name()), ULONG_PTR(&(uvGen->m_geoRefInfo)), 0);
1375 }
1376 #endif
1377
Notify(NotifyInfo * info)1378 void BMTex::Notify(NotifyInfo* info) {
1379
1380 switch(info->intcode) {
1381 case NOTIFY_BITMAP_CHANGED:
1382 {
1383 TCHAR *nm = (TCHAR *)info->callParam;
1384 if (nm==NULL || !_tcscmp(nm,m_bi.Name())) {
1385 NotifyChanged();
1386 }
1387 if (nm==NULL) {
1388 fileNotFound = 0;
1389 }
1390 #ifdef DESIGN_VER
1391 if (!_tcscmp(_T("TIF Image File"), m_bi.Device()))
1392 SetGeoReferenceInfo(m_bi, GetUVGen());
1393 #endif
1394 break;
1395 }
1396 case NOTIFY_PROXY_TEMPORARY_DISABLE_START:
1397 // Keep track of the number of temporary disables that occur
1398 ++m_numTemporaryDisables;
1399 if(m_numTemporaryDisables == 1) {
1400 DisableProxyMode(false);
1401 }
1402 break;
1403 case NOTIFY_PROXY_TEMPORARY_DISABLE_END:
1404 --m_numTemporaryDisables;
1405 if(m_numTemporaryDisables == 0) {
1406 EnableProxyMode(!KeepNonProxyInMemoryAfterRendering());
1407 }
1408 break;
1409 default:
1410 DbgAssert(false);
1411 break;
1412 }
1413 }
1414
BMTexNotify(void * param,NotifyInfo * info)1415 void BMTex::BMTexNotify(void *param, NotifyInfo *info) {
1416
1417 BMTex *bmt = (BMTex *) param;
1418 if(bmt != NULL) {
1419 bmt->Notify(info);
1420 }
1421 else {
1422 DbgAssert(false);
1423 }
1424 }
1425
BMTex()1426 BMTex::BMTex()
1427 : m_bi(m_theBitmap.GetBitmapInfo()),
1428 m_numTemporaryDisables(0),
1429 m_proxiesWereDisabledForRendering(false)
1430 {
1431 ip = NULL;
1432 isParm2 = TRUE;
1433 paramDlg = NULL;
1434 pblock = NULL;
1435 pblockTime = NULL;
1436 uvGen = NULL;
1437 texout = NULL;
1438 texHandle = NULL;
1439 loadFailed = FALSE;
1440 startTime = 0;
1441 pbRate = 1.0f;
1442 endCond = END_LOOP;
1443 isNew = TRUE;
1444 applyCrop = FALSE;
1445 loading = FALSE;
1446 loadingOld = FALSE;
1447 clipValid = FOREVER;
1448 fileNotFound = FALSE;
1449 bmTexCD.MakeAutoParamBlocks(this); // make and intialize paramblock2
1450 Init();
1451 bmNotify.SetTex(this);
1452 rollScroll=0;
1453 bmWasSet = FALSE;
1454 RegisterNotification(BMTexNotify, this, NOTIFY_BITMAP_CHANGED);
1455 RegisterNotification(BMTexNotify, this, NOTIFY_PROXY_TEMPORARY_DISABLE_START);
1456 RegisterNotification(BMTexNotify, this, NOTIFY_PROXY_TEMPORARY_DISABLE_END);
1457 }
1458
GetActiveBitmap() const1459 Bitmap* BMTex::GetActiveBitmap() const {
1460
1461 // We assume that the m_theBitmap is non-null if and only if
1462 // "tie time to mat ID" is false.
1463 Bitmap* bitmap = m_theBitmap.GetBitmap();
1464 if((bitmap == NULL) && !m_theBitmapList.isEmpty()) {
1465 // Use the last bitmap in the list
1466 bitmap = m_theBitmapList.last().GetBitmap();
1467 }
1468
1469 return bitmap;
1470 }
1471
SetClipU(TimeValue t,float f)1472 void BMTex::SetClipU(TimeValue t, float f) {
1473 clipu = f;
1474 pblock->SetValue(bmtex_clipu, t, f);
1475 bmtex_param_blk.InvalidateUI(bmtex_clipu);
1476
1477 }
1478
1479
SetClipV(TimeValue t,float f)1480 void BMTex::SetClipV(TimeValue t, float f) {
1481 clipv = f;
1482 pblock->SetValue( bmtex_clipv, t, f);
1483 bmtex_param_blk.InvalidateUI(bmtex_clipv);
1484 }
1485
SetClipW(TimeValue t,float f)1486 void BMTex::SetClipW(TimeValue t, float f) {
1487 clipw = f;
1488 // pblock->SetValue( PB_CLIPW, t, f);
1489 pblock->SetValue( bmtex_clipw, t, f);
1490 bmtex_param_blk.InvalidateUI(bmtex_clipw);
1491 }
1492
SetClipH(TimeValue t,float f)1493 void BMTex::SetClipH(TimeValue t, float f) {
1494 cliph = f;
1495 // pblock->SetValue( PB_CLIPH, t, f);
1496 pblock->SetValue( bmtex_cliph, t, f);
1497 bmtex_param_blk.InvalidateUI(bmtex_cliph);
1498 }
1499
SetJitter(TimeValue t,float f)1500 void BMTex::SetJitter(TimeValue t, float f) {
1501 jitter = cliph = f;
1502 // pblock->SetValue( PB_JITTER, t, f);
1503 pblock->SetValue( bmtex_jitter, t, f);
1504 bmtex_param_blk.InvalidateUI(bmtex_jitter);
1505 }
1506
GetBitmap(TimeValue t)1507 Bitmap* BMTex::GetBitmap(TimeValue t) {
1508
1509 LoadBitmap(t);
1510 return GetActiveBitmap();
1511 }
1512
EnableStuff()1513 void BMTex::EnableStuff() {
1514 if (pblock) {
1515 IParamMap2 *map = pblock->GetMap();
1516 pblock->GetValue( bmtex_crop_place, 0, placeImage, FOREVER );
1517 pblock->GetValue( bmtex_usejitter, 0, randPlace, FOREVER );
1518 if (map) {
1519 map->Enable(bmtex_jitter, placeImage);
1520 map->Enable(bmtex_usejitter, placeImage);
1521 map->Enable(bmtex_clipu, !(placeImage&&randPlace));
1522 map->Enable(bmtex_clipv, !(placeImage&&randPlace));
1523 }
1524 }
1525 }
1526
SetFilterType(int ft)1527 void BMTex::SetFilterType(int ft) {
1528
1529 pblock->SetValue( bmtex_filtering, 0, ft);
1530 bmtex_param_blk.InvalidateUI(bmtex_filtering);
1531 }
1532
SetAlphaSource(int as)1533 void BMTex::SetAlphaSource(int as) {
1534 if (as!=alphaSource) {
1535 alphaSource =as;
1536
1537 InitBitmapSamplers();
1538
1539 if (alphaSource == ALPHA_FILE) pblock->SetValue( bmtex_alphasource, 0, 0);
1540 else if (alphaSource == ALPHA_RGB) pblock->SetValue( bmtex_alphasource, 0, 1);
1541 else if (alphaSource == ALPHA_NONE) pblock->SetValue( bmtex_alphasource, 0, 2);
1542 bmtex_param_blk.InvalidateUI(bmtex_alphasource);
1543 }
1544 }
1545
SetMapName(const TCHAR * name,bool isUIAction)1546 void BMTex::SetMapName(const TCHAR *name, bool isUIAction) {
1547
1548 if (name) {
1549 TCHAR uncname[MAX_PATH];
1550 if (BMMGetUniversalName(uncname,name))
1551 m_bi.SetName(uncname);
1552 else
1553 m_bi.SetName(name);
1554
1555 PBBitmap bt(m_bi);
1556 pblock->SetValue(bmtex_bitmap, 0, &bt);
1557 fileNotFound = FALSE;
1558 if (TestMtlFlag(MTL_TEX_DISPLAY_ENABLED)) {
1559 if (ip)
1560 ip->MtlChanged();
1561 }
1562
1563 // Trigger the bitmap proxy pre-caching dialog if the reload occured
1564 // as the result of a UI command.
1565 if(isUIAction) {
1566 ShowBitmapProxyPrecacheDialog();
1567 }
1568 }
1569 }
1570
modt(TimeValue x,TimeValue m)1571 static TimeValue modt(TimeValue x, TimeValue m) {
1572 TimeValue n = (int)(x/m);
1573 x -= n*m;
1574 return (x<0)? x+m : x ;
1575 }
1576
StuffCropValues()1577 void BMTex::StuffCropValues() {
1578 pblock->GetValue( bmtex_crop_place, 0, placeImage, FOREVER );
1579
1580 m_theBitmap.SetCroppingValues(clipu,clipv,clipw,cliph, placeImage );
1581 }
1582
CalcFrame(TimeValue t)1583 int BMTex::CalcFrame(TimeValue t) {
1584 TimeValue tm,dur,td;
1585 int fstart = m_bi.FirstFrame();
1586 int fend = m_bi.LastFrame();
1587 int tpf = GetTicksPerFrame();
1588 tm = TimeValue(float(t-startTime)*pbRate);
1589 dur = (fend-fstart+1)*GetTicksPerFrame();
1590 switch (endCond) {
1591 case END_HOLD:
1592 if (tm<=0) return fstart;
1593 if (tm>=dur) return fend;
1594 return tm/tpf;
1595 case END_PINGPONG:
1596 //if ((tm/dur)&1)
1597 if ( ((tm>=0) && ((tm/dur)&1)) || ( (tm<0) && !(tm/dur)))
1598 {
1599 td = modt(tm,dur);
1600 return fstart + fend-td/tpf;
1601 }
1602 // else fall thrue--
1603 case END_LOOP:
1604 td = modt(tm,dur);
1605 return td/tpf;
1606 }
1607 return 0;
1608 }
1609
LoadBitmap(TimeValue t,bool quiet,bool reload)1610 BMMRES BMTex::LoadBitmap(TimeValue t, bool quiet, bool reload) {
1611 BOOL silent = FALSE;
1612 BMMRES status = BMMRES_SUCCESS;
1613
1614 if (bmWasSet)
1615 goto skipall;
1616
1617 PBBitmap* bitmapPB = NULL;
1618 pblock->GetValue( bmtex_bitmap, t,bitmapPB, clipValid );
1619 if ( ((bitmapPB != NULL) && (_tcscmp(m_bi.Name(), bitmapPB->bi.Name())) ) )
1620 FreeBitmap();
1621
1622 UpdateBIName(); //DS 2/18/99
1623 if (m_bi.Name()[0]==0) {
1624 if (m_bi.Device()[0]==0)
1625 return BMMRES_NODRIVER;
1626 #ifdef DESIGN_VER //KENNY MERGE
1627 //SS 10/3/2000: In the Kenny source, this line was indented an additional
1628 // level, as if the intention was to include it within the outer if
1629 // statement. Since that wasn't the case, I have adjusted indentation.
1630 // However, if you find a bug here, it could be that this should only be
1631 // called if bi.Name()[0]==0.
1632 // Additionally, I don't know if this is a general fix or is specific to
1633 // VIZ; there were no previous comments.
1634
1635 // [d.levesque | 10feb2002] I have include this line of code in the if block,
1636 // as suggested by Stew's comment. This fixes:
1637 // 313220 - GAMMA STATE OF IMAGE REVERTS TO USE SYSTEM GAMMA, DOES NOT REMEMBER STATE SET.
1638 m_bi.ResetCustomFlag(BMM_CUSTOM_FILEGAMMA);
1639 #endif
1640 }
1641
1642 BOOL tieTimeToMatID;
1643 pblockTime->GetValue( bmtex_matidtime, 0, tieTimeToMatID,FOREVER);
1644
1645 if (GetActiveBitmap()==NULL)
1646 {
1647 if (!tieTimeToMatID)
1648 {
1649 // Load bitmap
1650 int bitmapFrame = CalcFrame(t);
1651 m_bi.SetCurrentFrame(bitmapFrame);
1652 if(!m_theBitmap.LoadBitmap(status, quiet)) {
1653 fileNotFound = TRUE;
1654 return status;
1655 }
1656 if (bitmapPB) {
1657 bitmapPB->bi = m_bi; //DS 3/29/99: in case name has changed ( or flags)
1658 }
1659 fileNotFound = FALSE;
1660 m_theBitmap.SetNotify(&bmNotify);
1661 m_theBitmap.SetFilter(bmFilterType(filterType));
1662 // fixup for imported files
1663 #ifdef RENDER_VER
1664 {
1665 // Automatically set the alpha settings depending on whether
1666 // the file has an alpha channel or not. .PSD files have
1667 // alpha channels, but we are supposed to ignore them.
1668 LPCTSTR d = m_bi.Name();
1669 size_t len = _tcslen(d);
1670 if (len > 4)
1671 d += len - 4;
1672 if ((m_bi.Flags() & MAP_HAS_ALPHA) && _tcsicmp(d, ".psd") != 0) {
1673 SetAlphaAsMono(true);
1674 SetAlphaSource(ALPHA_FILE);
1675 }
1676 else {
1677 SetAlphaAsMono(false);
1678 SetAlphaSource(ALPHA_NONE);
1679 }
1680 }
1681 #endif
1682
1683 }
1684
1685 else
1686 {
1687 for (int ct = 0; ct < mysampList.Count(); ct++)
1688 {
1689 delete mysampList[ct];
1690 delete alphasampList[ct];
1691 }
1692
1693 int numberFrames = m_bi.NumberFrames();
1694 m_theBitmapList.setLengthUsed(numberFrames);
1695 mysampList.SetCount(numberFrames);
1696 alphasampList.SetCount(numberFrames);
1697 for (int ct = 0; ct < numberFrames; ct++)
1698 {
1699 mysampList[ct] = new BMSampler();
1700 alphasampList[ct] = new BMAlphaSampler();
1701 }
1702
1703 int firstFrame = m_bi.FirstFrame();
1704 int lastFrame = m_bi.LastFrame();
1705
1706
1707 for (int frameIndex = m_bi.FirstFrame(), ct=0; frameIndex <= m_bi.LastFrame(); frameIndex++)
1708 {
1709 if (frameIndex >= numberFrames) { // extend the arrays
1710 BitmapHolder nullBitmap;
1711 BMSampler* bmSampler = NULL;
1712 BMAlphaSampler* bmAlphaSampler = NULL;
1713 for(int j=numberFrames; j<=frameIndex; j++) {
1714 m_theBitmapList.append(nullBitmap);
1715 bmSampler = new BMSampler();
1716 mysampList.Append(1, &bmSampler);
1717 bmAlphaSampler = new BMAlphaSampler();
1718 alphasampList.Append(1, &bmAlphaSampler);
1719 }
1720 numberFrames = frameIndex+1;
1721 }
1722
1723 // Load bitmap, with proxy support
1724 BitmapHolder& currentBitmap = m_theBitmapList[ct];
1725 // Copy the main bitmap info as it's where our bitmap info lies.
1726 currentBitmap.GetBitmapInfo() = m_bi;
1727 currentBitmap.GetBitmapInfo().SetCurrentFrame(frameIndex);
1728 if(!currentBitmap.LoadBitmap(status, quiet)) {
1729 fileNotFound = TRUE;
1730 return status;
1731 }
1732 if (bitmapPB) {
1733 bitmapPB->bi = m_bi; //DS 3/29/99: in case name has changed ( or flags)
1734 }
1735 fileNotFound = FALSE;
1736 m_theBitmap.SetNotify(&bmNotify);
1737 m_theBitmap.SetFilter(bmFilterType(filterType));
1738
1739 m_theBitmapList[ct].SetNotify(&bmNotify);
1740 m_theBitmapList[ct].SetFilter(bmFilterType(filterType));
1741
1742 ct++;
1743
1744 }
1745 // fixup for imported files
1746 if (!(m_bi.Flags()&MAP_HAS_ALPHA)&&alphaSource==ALPHA_FILE) {
1747 if (paramDlg)
1748 paramDlg->EnableAlphaButtons(FALSE);
1749 else
1750 SetAlphaSource(ALPHA_NONE);
1751 }
1752 if (!(m_bi.Flags()&MAP_HAS_ALPHA))
1753 SetPremultAlpha(TRUE); // DS 6/9/00
1754 if (paramDlg != NULL) {
1755 paramDlg->EnableAlphaButtons(!reload);
1756 paramDlg->EnableViewImage();
1757 }
1758 }
1759 }
1760
1761 if (!tieTimeToMatID) {
1762 m_bi.SetCurrentFrame(CalcFrame(t));
1763
1764 // [dl | 11june2003] Commit the bitmap info to the param block, in case the frame changed
1765 if(bitmapPB != NULL) {
1766 bitmapPB->bi = m_bi;
1767 }
1768
1769 // Update, with proxy support
1770 status = m_theBitmap.GotoFrame(true);
1771 }
1772
1773 #ifdef DESIGN_VER
1774 if (!_tcscmp(_T("TIF Image File"), m_bi.Device()))
1775 SetGeoReferenceInfo(m_bi, GetUVGen());
1776 #endif
1777 // }
1778
1779 skipall:
1780
1781 InitBitmapSamplers();
1782
1783 return status;
1784 }
1785
RenderBegin(TimeValue t,ULONG flags)1786 int BMTex::RenderBegin(TimeValue t, ULONG flags) {
1787
1788 // Disable proxy for rendering, if necessary
1789
1790 DbgAssert(!m_proxiesWereDisabledForRendering);
1791
1792 // Don't disable the proxies if they are already temporarily disabled
1793 if(m_numTemporaryDisables == 0) {
1794 bool isMEdit = ((flags & RENDERBEGIN_IN_MEDIT) != 0);
1795 bool disableProxyMode = ShouldDisableProxiesForRendering(isMEdit);
1796 if(disableProxyMode) {
1797 DisableProxyMode(false);
1798 m_proxiesWereDisabledForRendering = true;
1799 }
1800 }
1801
1802 return 1;
1803 }
1804
RenderEnd(TimeValue t)1805 int BMTex::RenderEnd(TimeValue t) {
1806
1807 // Re-enable proxies when done rendering, if they were disabled previously.
1808
1809 if(m_proxiesWereDisabledForRendering) {
1810 m_proxiesWereDisabledForRendering = false;
1811 bool flushNonProxy = !KeepNonProxyInMemoryAfterRendering();
1812 EnableProxyMode(flushNonProxy);
1813 }
1814
1815 return 1;
1816 }
1817
LoadMapFiles(TimeValue t)1818 int BMTex::LoadMapFiles(TimeValue t) {
1819 LoadBitmap(t,1,1);
1820 return 1;
1821 }
1822
RenderBitmap(TimeValue t,Bitmap * bm,float scale3D,BOOL filter)1823 void BMTex::RenderBitmap(TimeValue t, Bitmap *bm, float scale3D, BOOL filter) {
1824
1825 // Disable proxy only when 'filter' is specified, as we assume that 'filter'
1826 // is equivalent to 'high quality'.
1827 BMTex::ProxyModeDisableGuard proxyModeDisabler(*this, (filter != 0));
1828
1829 LoadBitmap(t);
1830 Bitmap* thebm = GetActiveBitmap();
1831 if (thebm)
1832 bm->CopyImage(thebm, filter?COPY_IMAGE_RESIZE_HI_QUALITY:COPY_IMAGE_RESIZE_LO_QUALITY, 0);
1833 }
1834
ClassID()1835 Class_ID BMTex::ClassID() {
1836
1837 return bmTexClassID;
1838 }
1839
SuperClassID()1840 SClass_ID BMTex::SuperClassID() {
1841
1842 return TEXMAP_CLASS_ID;
1843 }
1844
GetClassName(TSTR & s)1845 void BMTex::GetClassName(TSTR& s) {
1846
1847 s= GetString(IDS_DS_BITMAP);
1848 }
1849
DeleteThis()1850 void BMTex::DeleteThis() {
1851
1852 delete this;
1853 }
1854
ReloadBitmap(bool isUIAction)1855 void BMTex::ReloadBitmap(bool isUIAction) {
1856 if(GetActiveBitmap() != NULL) {
1857 loadFailed = FALSE;
1858 FreeBitmap();
1859 LoadBitmap(GetCOREInterface()->GetTime(), TRUE, TRUE);
1860
1861 // Re-load the bitmap in-place, forcing a reload.
1862 m_theBitmap.LoadInto(true);
1863 }
1864 else {
1865 loadFailed = FALSE;
1866 TimeValue t;
1867 t = GetCOREInterface()->GetTime();
1868 LoadBitmap(t);
1869 }
1870
1871 //DS: 10/19/99: update path name on button in case it has changed ( fix for #196020)
1872 IParamMap2* pmap = pblock->GetMap();
1873 if (pmap != NULL)
1874 pmap->SetText(bmtex_bitmap, (char *)m_bi.Name());
1875
1876
1877 if (paramDlg)
1878 paramDlg->EnableAlphaButtons(FALSE);
1879
1880 // Trigger the bitmap proxy pre-caching dialog if the reload occured
1881 // as the result pressing the "reload" button in the UI.
1882 if(isUIAction) {
1883 ShowBitmapProxyPrecacheDialog();
1884 }
1885 }
1886
EnumAuxFiles(NameEnumCallback & nameEnum,DWORD flags)1887 void BMTex::EnumAuxFiles(NameEnumCallback& nameEnum, DWORD flags) {
1888
1889 if ((flags&FILE_ENUM_CHECK_AWORK1)&&TestAFlag(A_WORK1)) return; // LAM - 4/21/03
1890
1891 UpdateBIName(); //k2tong|May.17.2006|update the m_bi before an enum to report the most up to date info.
1892
1893 if(flags&FILE_ENUM_ACCESSOR_INTERFACE) {
1894 int idx = TheManager->ioList.ResolveDevice(&m_bi);
1895
1896 IEnumAuxAssetsCallback* callback = static_cast<IEnumAuxAssetsCallback*>(&nameEnum);
1897 if(idx >= 0 && TheManager->ioList[idx].TestCapabilities(BMMIO_IFL)) {
1898 // handle IFL case
1899 DeclareBitmapAsset(*callback, BMTexPathAccessor(this), &m_bi, BMM_ASSET_PROXY | BMM_ASSET_GROUP);
1900 m_bi.EnumAuxFiles(nameEnum, flags);
1901 callback->EndGroup();
1902 }
1903 else {
1904 // normal bitmap or unsupported type
1905 DeclareBitmapAsset(*callback, BMTexPathAccessor(this), &m_bi, BMM_ASSET_PROXY);
1906 }
1907 }
1908 else {
1909 m_bi.EnumAuxFiles(nameEnum,flags);
1910 }
1911
1912 BitmapTex::EnumAuxFiles(nameEnum,flags); // LAM - 4/21/03
1913 }
1914
1915
DiscardTexHandle()1916 void BMTex::DiscardTexHandle() {
1917 if (texHandle) {
1918 texHandle->DeleteThis();
1919 texHandle = NULL;
1920 }
1921 }
1922
ActivateTexDisplay(BOOL onoff)1923 void BMTex::ActivateTexDisplay(BOOL onoff) {
1924 if (!onoff)
1925 DiscardTexHandle();
1926 }
1927
1928 static BMM_Color_64 black64(0,0,0,0);
1929
GetVPDisplayDIB(TimeValue t,TexHandleMaker & thmaker,Interval & valid,BOOL mono,BOOL forceW,BOOL forceH)1930 BITMAPINFO* BMTex::GetVPDisplayDIB(TimeValue t, TexHandleMaker& thmaker, Interval &valid, BOOL mono, BOOL forceW, BOOL forceH) {
1931 LoadBitmap(t);
1932 valid = clipValid;
1933 if (m_bi.FirstFrame()!=m_bi.LastFrame())
1934 {
1935 // bug :424747
1936 //the image has multiple frames, the vlidity should be only for the current frame
1937 // For cases where the sequence has very few frames, it should be valid for more than just the current "t".
1938 // We have no real
1939 valid.SetInstant(t);
1940 //Without this fix, the viewport does not update with the correct image frame.
1941 // When GetVPDisplayDIB gets called, some callers look at the validity, others look at the current image frame.
1942 // When looking at the validity, the viewport was not getting updates.
1943
1944 }
1945
1946 Bitmap* thebm = GetActiveBitmap();
1947 if (thebm==NULL) {
1948 return NULL;
1949 }
1950 BITMAPINFO *bmi = NULL;
1951 int xflags = premultAlpha?0:EX_MULT_ALPHA;
1952 if (applyCrop) {
1953 int w = thebm->Width();
1954 int h = thebm->Height();
1955 Bitmap *newBM;
1956 BitmapInfo bif;
1957 bif.SetName(_T("y8798734"));
1958 bif.SetType(BMM_TRUE_32);
1959 bif.SetFlags(MAP_HAS_ALPHA);
1960 if (placeImage) {
1961 int x0,y0,nw,nh;
1962 int bmw = thmaker.Size();
1963 int bmh = int(float(bmw)*float(h)/float(w));
1964 bif.SetWidth(bmw);
1965 bif.SetHeight(bmh);
1966 newBM = TheManager->Create(&bif);
1967 newBM->Fill(0,0,0,0);
1968 nw = int(float(bmw)*clipw);
1969 nh = int(float(bmh)*cliph);
1970 x0 = int(float(bmw-1)*clipu);
1971 y0 = int(float(bmh-1)*clipv);
1972
1973 if (nw<1) nw = 1;
1974 if (nh<1) nh = 1;
1975 PixelBuf row(nw);
1976
1977 Bitmap *tmpBM;
1978 BitmapInfo bif2;
1979 bif2.SetName(_T("xxxx67878"));
1980 bif2.SetType(BMM_TRUE_32);
1981 bif2.SetFlags(MAP_HAS_ALPHA);
1982 bif2.SetWidth(nw);
1983 bif2.SetHeight(nh);
1984 tmpBM = TheManager->Create(&bif2);
1985 tmpBM->CopyImage(thebm, COPY_IMAGE_RESIZE_LO_QUALITY, 0);
1986 BMM_Color_64* p1 = row.Ptr();
1987 for (int y = 0; y<nh; y++) {
1988 tmpBM->GetLinearPixels(0,y, nw, p1);
1989 if ((mono&&alphaAsMono)||(alphaAsRGB)) {
1990 for (int ix =0; ix<nw; ix++)
1991 p1[ix].r = p1[ix].g = p1[ix].b = p1[ix].a;
1992 }
1993 //if (alphaSource==ALPHA_NONE||premultAlpha) {
1994 if (alphaSource==ALPHA_NONE) {
1995 for (int ix =0; ix<nw; ix++)
1996 p1[ix].a = 0xffff;
1997 }
1998 else if (alphaSource==ALPHA_RGB) {
1999 for (int ix =0; ix<nw; ix++)
2000 p1[ix].a = (p1[ix].r+p1[ix].g+p1[ix].b)/3;;
2001 }
2002 newBM->PutPixels(x0,y+y0, nw, p1);
2003 }
2004 tmpBM->DeleteThis();
2005 // texHandle = thmaker.CreateHandle(newBM,uvGen->SymFlags(), xflags);
2006 bmi = thmaker.BitmapToDIB(newBM,uvGen->SymFlags(), xflags, forceW, forceH);
2007 newBM->DeleteThis();
2008 }
2009 else {
2010 int x0,y0,nw,nh;
2011 nw = int(float(w)*clipw);
2012 nh = int(float(h)*cliph);
2013 x0 = int(float(w-1)*clipu);
2014 y0 = int(float(h-1)*clipv);
2015 if (nw<1) nw = 1;
2016 if (nh<1) nh = 1;
2017 bif.SetWidth(nw);
2018 bif.SetHeight(nh);
2019 PixelBuf row(nw);
2020 newBM = TheManager->Create(&bif);
2021 BMM_Color_64* p1 = row.Ptr();
2022 for (int y = 0; y<nh; y++) {
2023 thebm->GetLinearPixels(x0,y+y0, nw, p1);
2024 if ((mono&&alphaAsMono)||(alphaAsRGB)) {
2025 for (int ix =0; ix<nw; ix++)
2026 p1[ix].r = p1[ix].g = p1[ix].b = p1[ix].a;
2027 }
2028 // if (alphaSource==ALPHA_NONE||premultAlpha) {
2029 if (alphaSource==ALPHA_NONE) {
2030 for (int ix =0; ix<nw; ix++)
2031 p1[ix].a = 0xffff;
2032 }
2033 else if (alphaSource==ALPHA_RGB) {
2034 for (int ix =0; ix<nw; ix++)
2035 p1[ix].a = (p1[ix].r+p1[ix].g+p1[ix].b)/3;;
2036 }
2037 newBM->PutPixels(0,y, nw, p1);
2038 }
2039 // texHandle = thmaker.CreateHandle(newBM,uvGen->SymFlags(), xflags);
2040 bmi = thmaker.BitmapToDIB(newBM,uvGen->SymFlags(), xflags, forceW, forceH);
2041 newBM->DeleteThis();
2042 }
2043 }
2044 else {
2045 if (mono&&alphaAsMono) xflags |= EX_RGB_FROM_ALPHA;
2046 if (alphaAsRGB) xflags |= EX_RGB_FROM_ALPHA;
2047 if (alphaSource==ALPHA_NONE) xflags |= EX_OPAQUE_ALPHA;
2048 if (alphaSource==ALPHA_RGB) xflags |= EX_ALPHA_FROM_RGB;
2049 // texHandle = thmaker.CreateHandle(thebm,uvGen->SymFlags(), xflags);
2050 bmi = thmaker.BitmapToDIB(thebm,uvGen->SymFlags(), xflags, forceW, forceH);
2051 }
2052 return bmi;
2053 }
2054
GetActiveTexHandle(TimeValue t,TexHandleMaker & thmaker)2055 DWORD_PTR BMTex::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker) {
2056 if (texHandle&&texTime==CalcFrame(t)&&texValid.InInterval(t))
2057 return texHandle->GetHandle();
2058 else {
2059 DiscardTexHandle();
2060 texTime = CalcFrame(t);
2061 texHandle = thmaker.MakeHandle(GetVPDisplayDIB(t,thmaker,texValid));
2062 return texHandle->GetHandle();
2063 }
2064 }
2065
IsHighDynamicRange() const2066 int BMTex::IsHighDynamicRange( ) const
2067 {
2068 Bitmap* thebm = GetActiveBitmap();
2069 return thebm == NULL ? false : thebm->IsHighDynamicRange();
2070 }
2071
2072 //-----------------------------------------------------------
2073
EvalColor(ShadeContext & sc)2074 AColor BMTex::EvalColor(ShadeContext& sc) {
2075 if (!sc.doMaps) return black;
2076 AColor c;
2077 if (sc.GetCache(this,c))
2078 return c;
2079 IPoint3 sp = sc.ScreenCoord();
2080 if (gbufID) sc.SetGBufferID(gbufID);
2081 if (GetActiveBitmap()==NULL)
2082 return black;
2083
2084
2085
2086 if (!mTieTimeToMatID)
2087 {
2088 if (alphaAsRGB) {
2089 float a = texout->Filter(uvGen->EvalUVMapMono(sc,&alphasamp,filterType!=FILTER_NADA));
2090 c = AColor(a,a,a,a);
2091 }
2092 else {
2093 c = texout->Filter(uvGen->EvalUVMap(sc,&mysamp,filterType!=FILTER_NADA));
2094 if (!premultAlpha) c= AColor(c.r*c.a, c.g*c.a, c.b*c.a, c.a);
2095 }
2096 }
2097 else
2098 {
2099 int whichFrame = ComputeParticleFrame(sc);
2100 if (alphaAsRGB) {
2101 float a = texout->Filter(uvGen->EvalUVMapMono(sc,alphasampList[whichFrame],filterType!=FILTER_NADA));
2102 c = AColor(a,a,a,a);
2103 }
2104 else {
2105 c = texout->Filter(uvGen->EvalUVMap(sc,mysampList[whichFrame],filterType!=FILTER_NADA));
2106 if (!premultAlpha) c= AColor(c.r*c.a, c.g*c.a, c.b*c.a, c.a);
2107 }
2108 }
2109 sc.PutCache(this,c);
2110 return c;
2111 }
2112
EvalMono(ShadeContext & sc)2113 float BMTex::EvalMono(ShadeContext& sc) {
2114 if (!sc.doMaps||GetActiveBitmap()==NULL)
2115 return 0.0f;
2116 float f;
2117 if (sc.GetCache(this,f))
2118 return f;
2119 if (gbufID) sc.SetGBufferID(gbufID);
2120
2121 if (!mTieTimeToMatID)
2122 {
2123
2124 if (alphaAsMono)
2125 f = texout->Filter(uvGen->EvalUVMapMono(sc,&alphasamp,filterType!=FILTER_NADA));
2126 else
2127 f = texout->Filter(uvGen->EvalUVMapMono(sc,&mysamp,filterType!=FILTER_NADA));
2128 }
2129 else
2130 {
2131 int whichFrame = ComputeParticleFrame(sc);
2132
2133 if (alphaAsMono)
2134 f = texout->Filter(uvGen->EvalUVMapMono(sc,alphasampList[whichFrame],filterType!=FILTER_NADA));
2135 else
2136 f = texout->Filter(uvGen->EvalUVMapMono(sc,mysampList[whichFrame],filterType!=FILTER_NADA));
2137
2138 }
2139 sc.PutCache(this,f);
2140 return f;
2141 }
2142
EvalNormalPerturb(ShadeContext & sc)2143 Point3 BMTex::EvalNormalPerturb(ShadeContext& sc) {
2144 Point3 dPdu, dPdv;
2145 Point2 dM;
2146 if (!sc.doMaps) return Point3(0,0,0);
2147 if (gbufID) sc.SetGBufferID(gbufID);
2148 if (GetActiveBitmap()==NULL)
2149 return Point3(0,0,0);
2150 if (!mTieTimeToMatID)
2151 {
2152 uvGen->GetBumpDP(sc,dPdu,dPdv); // get bump basis vectors
2153 if (alphaAsMono)
2154 dM =(.01f)*uvGen->EvalDeriv(sc,&alphasamp,filterType!=FILTER_NADA);
2155 else
2156 dM =(.01f)*uvGen->EvalDeriv(sc,&mysamp,filterType!=FILTER_NADA);
2157 }
2158 else
2159 {
2160 int whichFrame = ComputeParticleFrame(sc);
2161
2162 if (alphaAsMono)
2163 dM =(.01f)*uvGen->EvalDeriv(sc,alphasampList[whichFrame],filterType!=FILTER_NADA);
2164 else
2165 dM =(.01f)*uvGen->EvalDeriv(sc,mysampList[whichFrame],filterType!=FILTER_NADA);
2166 }
2167
2168 #if 0
2169 // Blinn's algorithm
2170 Point3 N = sc.Normal();
2171 Point3 uVec = CrossProd(N,dPdv);
2172 Point3 vVec = CrossProd(N,dPdu);
2173 return texout->Filter(-dM.x*uVec+dM.y*vVec);
2174 #else
2175 return texout->Filter(dM.x*dPdu+dM.y*dPdv);
2176 #endif
2177 }
2178
Clone(RemapDir & remap)2179 RefTargetHandle BMTex::Clone(RemapDir &remap) {
2180 // AF Don't log a restore object during this create
2181 // the Undo of a new inside a clone is the deletion of the new object.
2182 // No need to undo back to uninitialized values
2183 theHold.Suspend();
2184 BMTex *mnew = new BMTex();
2185 theHold.Resume();
2186
2187 *((MtlBase*)mnew) = *((MtlBase*)this); // copy superclass stuff
2188 mnew->ReplaceReference(0,remap.CloneRef(uvGen));
2189 mnew->ReplaceReference(1,remap.CloneRef(pblock));
2190 mnew->ReplaceReference(2,remap.CloneRef(texout));
2191 mnew->ReplaceReference(3,remap.CloneRef(pblockTime));
2192 mnew->filterType = filterType;
2193 mnew->alphaSource = alphaSource;
2194 mnew->alphaAsMono = alphaAsMono;
2195 mnew->alphaAsRGB = alphaAsRGB;
2196 mnew->premultAlpha = premultAlpha;
2197 mnew->endCond = endCond;
2198 mnew->applyCrop = applyCrop;
2199 mnew->ivalid.SetEmpty();
2200 mnew->placeImage = placeImage;
2201 mnew->randPlace = randPlace;
2202 mnew->applyCrop = applyCrop;
2203 mnew->startTime = startTime;
2204 mnew->pbRate = pbRate;
2205 mnew->m_bi = m_bi;
2206 BaseClone(this, mnew, remap);
2207 mnew->LoadBitmap( GetCOREInterface()->GetTime() );
2208 return (RefTargetHandle)mnew;
2209 }
2210
CreateParamDlg(HWND hwMtlEdit,IMtlParams * imp)2211 ParamDlg* BMTex::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp) {
2212 // BMTexDlg *dm = new BMTexDlg(hwMtlEdit, imp, this);
2213 // dm->LoadDialog(TRUE);
2214 // paramDlg = dm;
2215 // return dm;
2216 // JBW: the main difference here is the automatic creation of a ParamDlg by the new
2217 // ClassDesc2 function CreateParamDlgs(). This mirrors the way BeginEditParams()
2218 // can be redirected to the ClassDesc2 for automatic ParamMap2 management. In this
2219 // case a special subclass of ParamDlg, AutoMParamDlg, defined in IParamm2.h, is
2220 // created. It can act as a 'master' ParamDlg to which you can add any number of
2221 // secondary dialogs and it will make sure all the secondary dialogs are kept
2222 // up-to-date and deleted as necessary.
2223 // Here you see we create the Coordinate, Gradient and Output ParamDlgs in the desired
2224 // order, and then add the Coordinate and Output dlgs as secondaries to the
2225 // Gradient master AutoMParamDlg so it will keep them up-to-date automatically
2226
2227 // create the rollout dialogs
2228 uvGenDlg = uvGen->CreateParamDlg(hwMtlEdit, imp);
2229 IAutoMParamDlg* masterDlg = bmTexCD.CreateParamDlgs(hwMtlEdit, imp, this);
2230 texoutDlg = texout->CreateParamDlg(hwMtlEdit, imp);
2231 // add the secondary dialogs to the master
2232 masterDlg->AddDlg(uvGenDlg);
2233 masterDlg->AddDlg(texoutDlg);
2234 paramDlg = new BMTexDlg(hwMtlEdit,imp,this);
2235 bmtex_param_blk.SetUserDlgProc(paramDlg);
2236 ip = imp;
2237 EnableStuff();
2238 return masterDlg;
2239
2240 }
2241
~BMTex()2242 BMTex::~BMTex() {
2243 UnRegisterNotification(BMTexNotify, this, NOTIFY_PROXY_TEMPORARY_DISABLE_END);
2244 UnRegisterNotification(BMTexNotify, this, NOTIFY_PROXY_TEMPORARY_DISABLE_START);
2245 UnRegisterNotification(BMTexNotify, this, NOTIFY_BITMAP_CHANGED);
2246 DiscardTexHandle();
2247 FreeBitmap();
2248 }
2249
SetDlgThing(ParamDlg * dlg)2250 BOOL BMTex::SetDlgThing(ParamDlg* dlg)
2251 {
2252 // JBW: set the appropriate 'thing' sub-object for each
2253 // secondary dialog
2254 if (paramDlg) paramDlg->SetThing(this);
2255 EnableStuff();
2256
2257 if ((uvGenDlg!= NULL) && (dlg == uvGenDlg))
2258 uvGenDlg->SetThing(uvGen);
2259 else if ((texoutDlg!= NULL) && (dlg == texoutDlg))
2260 texoutDlg->SetThing(texout);
2261 else
2262 return FALSE;
2263 return TRUE;
2264
2265 }
2266
2267
2268
Update(TimeValue t,Interval & valid)2269 void BMTex::Update(TimeValue t, Interval& valid) {
2270
2271 pblockTime->GetValue( bmtex_matidtime, 0, mTieTimeToMatID,FOREVER);
2272
2273 if (!ivalid.InInterval(t)) {
2274
2275 uvGen->SetClipFlag(FALSE);
2276
2277 ivalid.SetInfinite();
2278 uvGen->Update(t,ivalid);
2279 clipValid.SetInfinite();
2280 pblock->GetValue( bmtex_clipu, t, clipu, clipValid );
2281 pblock->GetValue( bmtex_clipv, t, clipv, clipValid );
2282 pblock->GetValue( bmtex_clipw, t, clipw, clipValid );
2283 pblock->GetValue( bmtex_cliph, t, cliph, clipValid );
2284 pblock->GetValue( bmtex_jitter, t, jitter, clipValid );
2285
2286 pblock->GetValue( bmtex_filtering, t, filterType, clipValid );
2287 pblock->GetValue( bmtex_alphasource, t, alphaSource, clipValid );
2288
2289 if (alphaSource == 0)
2290 alphaSource = ALPHA_FILE;
2291 else if (alphaSource == 1)
2292 alphaSource = ALPHA_RGB;
2293 else if (alphaSource == 2)
2294 alphaSource = ALPHA_NONE;
2295
2296 pblock->GetValue( bmtex_monooutput, t, alphaAsMono, clipValid );
2297 pblock->GetValue( bmtex_rgboutput, t, alphaAsRGB, clipValid );
2298 pblock->GetValue( bmtex_premultalpha, t, premultAlpha, clipValid );
2299 pblock->GetValue( bmtex_usejitter, t, randPlace, clipValid );
2300
2301 pblock->GetValue( bmtex_crop_place, t, placeImage, clipValid );
2302
2303 pblock->GetValue( bmtex_apply, t, applyCrop, clipValid );
2304
2305 pblockTime->GetValue( bmtex_start, t, startTime, clipValid );
2306 pblockTime->GetValue( bmtex_playbackrate, t, pbRate, clipValid );
2307 pblockTime->GetValue( bmtex_endcondition, t, endCond, clipValid );
2308
2309 if (applyCrop)
2310 ivalid &= clipValid;
2311 else
2312 clipValid.SetInfinite();
2313
2314 texout->Update(t,ivalid);
2315
2316 // [dl | 20aug2003] Set the bitmap frame to be used. This is needed by
2317 // mental ray to correctly pick up which frame of the bitmap to use.
2318 // This is only necessary if the bitmap is not using the MtlID as frame
2319 // number.
2320 if (!mTieTimeToMatID) {
2321
2322 // Get the bitmap info from the parameter block
2323 PBBitmap* bitmapPB = NULL;
2324 pblock->GetValue( bmtex_bitmap, t,bitmapPB, clipValid );
2325
2326 // Free the bitmap if the filenames don't match. We need to do this
2327 // before we overwrite 'bi', otherwise there'll be no way of
2328 // telling whether the correct bitmap file is loaded.
2329 if ( ((bitmapPB != NULL) && (_tcscmp(m_bi.Name(), bitmapPB->bi.Name())) ) )
2330 FreeBitmap();
2331
2332 // Update 'bi' to be current with the contents of the param block
2333 UpdateBIName();
2334
2335 // Calculate the frame number
2336 m_bi.SetCurrentFrame(CalcFrame(t));
2337
2338 // Commit the bitmap info to the param block, since mental ray uses
2339 // the value from the param block.
2340 if(bitmapPB != NULL) {
2341 bitmapPB->bi = m_bi;
2342 }
2343 }
2344 }
2345
2346 if (GetActiveBitmap()&&!bmWasSet) {
2347 if (m_bi.FirstFrame()!=m_bi.LastFrame())
2348 {
2349 ivalid.SetInstant(t); // force bitmap to be reloaded
2350 }
2351 }
2352 else {
2353 ivalid.SetInstant(t); // force bitmap to be reloaded
2354 }
2355
2356 UpdtSampler();
2357 valid &= ivalid;
2358 }
2359
GetReference(int i)2360 RefTargetHandle BMTex::GetReference(int i) {
2361 switch(i) {
2362 case 0: return uvGen;
2363 case 1: return pblock;
2364 case 2: return texout;
2365 case 3: return pblockTime;
2366 default: return NULL;
2367 }
2368 }
2369
RemapRefOnLoad(int iref)2370 int BMTex::RemapRefOnLoad(int iref) {
2371 if (loadingOld) {
2372 switch(iref) {
2373 case 0: return 0;
2374 case 1: return 2;
2375 default: assert(0); return 0;
2376 }
2377 }
2378 else return iref;
2379 }
2380
SetReference(int i,RefTargetHandle rtarg)2381 void BMTex::SetReference(int i, RefTargetHandle rtarg) {
2382 switch(i) {
2383 case 0: uvGen = (UVGen *)rtarg; break;
2384 case 1: pblock = (IParamBlock2 *)rtarg; break;
2385 case 2: texout = (TextureOutput *)rtarg; break;
2386 case 3: pblockTime = (IParamBlock2 *)rtarg; break;
2387 default: break;
2388 }
2389 }
2390
2391
SubAnim(int i)2392 Animatable* BMTex::SubAnim(int i) {
2393 switch (i) {
2394 case 0: return uvGen;
2395 case 1: return pblock;
2396 case 2: return texout;
2397 case 3: return pblockTime;
2398 default: assert(0); return NULL;
2399 }
2400 }
2401
GetFullName()2402 TSTR BMTex::GetFullName() {
2403 TSTR cnm,nm,fname;
2404 GetClassName(cnm);
2405 UpdateBIName(); //DS 2/18/99
2406 GetBMName(m_bi,fname);
2407 TCHAR *s = fname.Length()>0? fname.data(): cnm.data();
2408 nm.printf(_T("%s (%s)"),GetName().data(), s);
2409 return nm;
2410 }
2411
SubAnimName(int i)2412 TSTR BMTex::SubAnimName(int i) {
2413 switch (i) {
2414 case 0: return TSTR(GetString(IDS_DS_COORDINATES));
2415 case 1: return TSTR(GetString(IDS_DS_PARAMETERS));
2416 case 2: return TSTR(GetString(IDS_DS_OUTPUT));
2417 case 3: return TSTR(GetString(IDS_DS_PARAMETERS));
2418 default: assert(0); return TSTR(_T(""));
2419 }
2420 }
2421
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)2422 RefResult BMTex::NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
2423 PartID& partID, RefMessage message ) {
2424 switch (message) {
2425 case REFMSG_CHANGE:
2426 {
2427 ivalid.SetEmpty();
2428 if (hTarget == pblock)
2429 {
2430 // see if this message came from a changing parameter in the pblock,
2431 // if so, limit rollout update to the changing item and update any active viewport texture
2432 ParamID changing_param = pblock->LastNotifyParamID();
2433 bmtex_param_blk.InvalidateUI(changing_param);
2434 if (changing_param != -1)
2435 DiscardTexHandle();
2436
2437 // 435297 : Handling changes here and reload the bitmap
2438 // The code used to be in PBAccessor::Set for bmtex_bitmap.
2439 if (changing_param == bmtex_bitmap)
2440 {
2441 if (!loading)
2442 {
2443 ReloadBitmapAndUpdate();
2444 // send message so browser/navigator name gets updated
2445 NotifyDependents(FOREVER,PART_ALL,REFMSG_SUBANIM_STRUCTURE_CHANGED);
2446 }
2447 }
2448 }
2449
2450
2451
2452 //SS 10/23/2000: Since code accessing this param block is not available
2453 // to VIZ anywhere else, it made sense to me to add an ifdef check around
2454 // this entire if statement.
2455 if (hTarget == pblockTime)
2456 {
2457 // see if this message came from a changing parameter in the pblock,
2458 // if so, limit rollout update to the changing item and update any active viewport texture
2459 ParamID changing_param = pblockTime->LastNotifyParamID();
2460 bmtex_time_param_blk.InvalidateUI(changing_param);
2461 }
2462
2463 break;
2464 }
2465 case REFMSG_UV_SYM_CHANGE:
2466 DiscardTexHandle();
2467 break;
2468 }
2469 return(REF_SUCCEED);
2470 }
2471
2472
2473
2474 //------------------------------------------------------------------------
2475 // IO
2476 //------------------------------------------------------------------------
2477
2478 class BMTexPostLoad : public PostLoadCallback {
2479 public:
2480 BMTex *chk;
BMTexPostLoad(BMTex * b)2481 BMTexPostLoad(BMTex *b) {chk=b;}
proc(ILoad * iload)2482 void proc(ILoad *iload) {
2483 chk->loadingOld = FALSE;
2484 delete this;
2485 }
2486 };
2487
2488 #define MTL_HDR_CHUNK 0x4000
2489 #define OLDBMTEX_NAME_CHUNK 0x5001
2490 #define BMTEX_FILTER_CHUNK 0x5002
2491 #define BMTEX_ALPHASOURCE_CHUNK 0x5003
2492 #define BMTEX_NAME_CHUNK 0x5004
2493 #define BMTEX_IO_CHUNK 0x5010
2494 #define BMTEX_START_CHUNK 0x5011
2495 #define BMTEX_RATE_CHUNK 0x5012
2496 #define BMTEX_ALPHA_MONO_CHUNK 0x5013
2497 #define BMTEX_ENDCOND_CHUNK 0x5014
2498 #define BMTEX_ALPHA_RGB_CHUNK 0x5016
2499 #define BMTEX_VERSOLD_CHUNK 0x5021
2500 #define BMTEX_VERSION_CHUNK 0x5022
2501 #define BMTEX_ALPHA_NOTPREMULT_CHUNK 0x5030
2502 #define BMTEX_CLIP_CHUNK 0x5040
2503 #define BMTEX_PLACE_IMAGE_CHUNK 0x5050
2504 #define BMTEX_JITTER_CHUNK 0x5060
2505
Save(ISave * isave)2506 IOResult BMTex::Save(ISave *isave) {
2507 // ULONG nb;
2508 IOResult res;
2509 // Save common stuff
2510 isave->BeginChunk(MTL_HDR_CHUNK);
2511 res = MtlBase::Save(isave);
2512 if (res!=IO_OK) return res;
2513 isave->EndChunk();
2514 return IO_OK;
2515 }
2516
2517
2518 class BMTex2PostLoad : public PostLoadCallback {
2519 public:
2520 BMTex *n;
2521 BOOL isParam2;
BMTex2PostLoad(BMTex * ns,BOOL b)2522 BMTex2PostLoad(BMTex *ns, BOOL b) {n = ns;isParam2 = b;}
proc(ILoad * iload)2523 void proc(ILoad *iload) {
2524
2525 if (!isParam2)
2526 {
2527 macroRecorder->Disable();
2528 n->pblock->SetValue( bmtex_filtering, 0, n->filterType);
2529 if (n->alphaSource == ALPHA_FILE) n->alphaSource = 0;
2530 else if (n->alphaSource == ALPHA_RGB) n->alphaSource = 1;
2531 else if (n->alphaSource == ALPHA_NONE) n->alphaSource = 2;
2532
2533 n->pblock->SetValue( bmtex_alphasource, 0, n->alphaSource);
2534
2535
2536 n->pblock->SetValue( bmtex_monooutput, 0, n->alphaAsMono );
2537 n->pblock->SetValue( bmtex_rgboutput, 0, n->alphaAsRGB );
2538 n->pblock->SetValue( bmtex_premultalpha, 0, n->premultAlpha);
2539 n->pblock->SetValue( bmtex_usejitter, 0, n->randPlace );
2540
2541 n->pblock->SetValue( bmtex_crop_place, 0, n->placeImage);
2542
2543 n->pblock->SetValue( bmtex_apply, 0, n->applyCrop);
2544
2545 PBBitmap bPB(n->m_bi);
2546 n->loading = TRUE;
2547 n->pblock->SetValue( bmtex_bitmap, 0, &bPB);
2548 n->loading = FALSE;
2549
2550 n->pblockTime->SetValue( bmtex_start, 0, n->startTime);
2551 n->pblockTime->SetValue( bmtex_playbackrate, 0, n->pbRate);
2552 n->pblockTime->SetValue( bmtex_endcondition, 0, n->endCond);
2553
2554 macroRecorder->Enable();
2555
2556 }
2557 delete this;
2558
2559
2560 }
2561 };
2562
2563
Load(ILoad * iload)2564 IOResult BMTex::Load(ILoad *iload) {
2565 ULONG nb;
2566 IOResult res;
2567 TSTR oldBMName;
2568 // iload->RegisterPostLoadCallback(new ParamBlockPLCB(oldVersions, 3, &curVersion, this,1));
2569 while (IO_OK==(res=iload->OpenChunk())) {
2570 switch(iload->CurChunkID()) {
2571 case MTL_HDR_CHUNK:
2572 res = MtlBase::Load(iload);
2573 break;
2574 case BMTEX_VERSOLD_CHUNK:
2575 loadingOld = TRUE;
2576 break;
2577 case BMTEX_FILTER_CHUNK:
2578 iload->Read(&filterType,sizeof(filterType),&nb);
2579 isParm2 = FALSE;
2580 break;
2581 case BMTEX_ALPHASOURCE_CHUNK:
2582 isParm2 = FALSE;
2583 iload->Read(&alphaSource,sizeof(alphaSource),&nb);
2584 break;
2585 case BMTEX_NAME_CHUNK:
2586 {
2587 // This chunk is used for old files only
2588 isParm2 = FALSE;
2589 TCHAR *buf;
2590 if(IO_OK==iload->ReadWStringChunk(&buf)) {
2591 if((buf != NULL) && (buf[0] != _T('\0'))) {
2592 oldBMName = buf;
2593 }
2594 }
2595 }
2596 break;
2597 case BMTEX_IO_CHUNK:
2598 isParm2 = FALSE;
2599 res = m_bi.Load(iload);
2600 // DS 7/18/96 - This is to handle old files
2601 // that had the bi saved with start = end = 0,
2602 // which now screws up animation.
2603 m_bi.SetStartFrame(BMM_UNDEF_FRAME);
2604 m_bi.SetEndFrame(BMM_UNDEF_FRAME);
2605 break;
2606 case BMTEX_START_CHUNK:
2607 isParm2 = FALSE;
2608 iload->Read(&startTime,sizeof(startTime),&nb);
2609 break;
2610 case BMTEX_RATE_CHUNK:
2611 isParm2 = FALSE;
2612 iload->Read(&pbRate,sizeof(pbRate),&nb);
2613 break;
2614 case BMTEX_ALPHA_MONO_CHUNK:
2615 isParm2 = FALSE;
2616 alphaAsMono = TRUE;
2617 break;
2618 case BMTEX_ALPHA_RGB_CHUNK:
2619 isParm2 = FALSE;
2620 alphaAsRGB = TRUE;
2621 break;
2622 case BMTEX_ALPHA_NOTPREMULT_CHUNK:
2623 isParm2 = FALSE;
2624 premultAlpha = FALSE;
2625 break;
2626 case BMTEX_ENDCOND_CHUNK:
2627 isParm2 = FALSE;
2628 iload->Read(&endCond,sizeof(endCond),&nb);
2629 break;
2630 case BMTEX_CLIP_CHUNK:
2631 isParm2 = FALSE;
2632 applyCrop = TRUE;
2633 break;
2634 case BMTEX_PLACE_IMAGE_CHUNK:
2635 isParm2 = FALSE;
2636 placeImage = TRUE;
2637 break;
2638 case BMTEX_JITTER_CHUNK:
2639 isParm2 = FALSE;
2640 randPlace = TRUE;
2641 break;
2642 }
2643 iload->CloseChunk();
2644 if (res!=IO_OK)
2645 return res;
2646 }
2647 if (alphaSource<0||alphaSource>ALPHA_NONE)
2648 alphaSource = ALPHA_FILE;
2649
2650
2651 if (!isParm2)
2652 {
2653 ParamBlock2PLCB* plcb = new ParamBlock2PLCB( oldVersions, NUMOLDVERSIONS, &bmtex_param_blk, this, 1);
2654 iload->RegisterPostLoadCallback(plcb);
2655
2656 BMTex2PostLoad *bmt2PLCB = new BMTex2PostLoad(this,isParm2);
2657 iload->RegisterPostLoadCallback(bmt2PLCB);
2658 }
2659
2660 if (oldBMName.Length()>0) {
2661 m_bi.SetName(oldBMName); // for obsolete files
2662 iload->SetObsolete();
2663 }
2664
2665 return IO_OK;
2666 }
2667
SetBitmap(Bitmap * bm)2668 void BMTex::SetBitmap(Bitmap *bm) {
2669 FreeBitmap();
2670 m_theBitmap.SetBitmap(bm);
2671 bmWasSet = (bm != NULL);
2672 }
2673
2674 #define PROPID_SETBITMAP 0x111
2675
SetProperty(ULONG id,void * data)2676 int BMTex::SetProperty(ULONG id, void *data)
2677 {
2678 switch (id) {
2679 case PROPID_CLEARCACHES:
2680 FreeBitmap();
2681 return 1;
2682 case PROPID_SETBITMAP:
2683 SetBitmap((Bitmap *)data);
2684 return 1;
2685
2686 default: return 0;
2687 }
2688 }
2689
2690
2691
BitmapLoadDlg()2692 void BMTex::BitmapLoadDlg() {
2693 HWND hpanel = GetCOREInterface()->GetMAXHWnd();
2694
2695 // lrr 06/04
2696 if (_tcscmp(s_lastName, _T(""))) {
2697 m_bi.SetName(s_lastName);
2698 }
2699 else {
2700 // Use the images directory as the default dir.
2701 TCHAR dummy[MAX_PATH];
2702 _tcscpy(dummy, TheManager->GetDir(APP_IMAGE_DIR));
2703 // Need to add a dummy filename to this path
2704 BMMAppendSlash(dummy);
2705 m_bi.SetName(dummy);
2706 }
2707
2708 BOOL res = TheManager->SelectFileInputEx(&m_bi, hpanel, GetString(IDS_DS_SELECT_BMFILE));
2709
2710 //load into param block
2711 if (res) {
2712 PBBitmap bt(m_bi);
2713 loading = 1; // disable accessor
2714 pblock->SetValue(bmtex_bitmap, 0, &bt);
2715 loading = 0;
2716 FreeBitmap(); // DS 9/25/00
2717 ReloadBitmap(false); // DS 9/25/00 -- this is to fix #254986
2718
2719 if (m_bi.Name()) //LRR 06/04
2720 _tcscpy( s_lastName, m_bi.Name() );
2721
2722 ShowBitmapProxyPrecacheDialog();
2723 }
2724 }
2725
2726 //watje forces the bitmap to reload and view to be redrawn
ReloadBitmapAndUpdate()2727 void BMTex::ReloadBitmapAndUpdate()
2728 {
2729 FreeBitmap();
2730 ReloadBitmap(false);
2731 fileNotFound = FALSE; // DS 4/20/99
2732 if (TestMtlFlag(MTL_TEX_DISPLAY_ENABLED)) {
2733 if (ip)
2734 ip->MtlChanged();
2735 }
2736 }
2737
2738
fnReload()2739 void BMTex::fnReload()
2740 {
2741 ReloadBitmap(false);
2742 BroadcastNotification(NOTIFY_BITMAP_CHANGED, (void *)m_bi.Name());
2743 if (ip) ip->MtlChanged();
2744 if ((ip) && (paramDlg)) paramDlg->Invalidate(); // incase path of map has changed.
2745
2746 }
2747
fnViewImage()2748 void BMTex::fnViewImage()
2749 {
2750 if ((ip) && (paramDlg)) paramDlg->ShowCropImage();
2751 }
2752
ComputeParticleFrame(ShadeContext & sc)2753 int BMTex::ComputeParticleFrame(ShadeContext& sc)
2754 {
2755
2756 // return 0;
2757 // Evaluate...
2758 Object *ob = sc.GetEvalObject();
2759 float u=0.0f;
2760 if (ob && ob->IsParticleSystem()) {
2761 ParticleObject *obj = (ParticleObject*)ob;
2762 TimeValue age = obj->ParticleAge(sc.CurTime(),sc.mtlNum);
2763 if (age>=0)
2764 {
2765 if (m_bi.NumberFrames() <= 1) return 0;
2766 return CalcFrame(age)%m_bi.NumberFrames();
2767 }
2768
2769 }
2770 return 0;
2771
2772 }
2773
GetInterface(ULONG id)2774 void* BMTex::GetInterface(ULONG id) {
2775
2776 // [dl | 27feb2004] I added this to make it possible for mental ray to
2777 // retrieve the tab of particle bitmaps.
2778 if(id == IID_BITMAPTEX_PARTICLE_BITMAP_LIST) {
2779 MaxSDK::Array<Bitmap*>* particleBitmapList = new MaxSDK::Array<Bitmap*>();
2780 size_t count = m_theBitmapList.length();
2781 particleBitmapList->setLengthUsed(count);
2782 for(size_t i = 0; i < count; ++i) {
2783 (*particleBitmapList)[i] = m_theBitmapList[i].GetBitmap();
2784 }
2785 return particleBitmapList;
2786 }
2787 else {
2788 return Texmap::GetInterface(id);
2789 }
2790 }
2791
EnableProxyMode(bool deleteNonProxyBitmap)2792 void BMTex::EnableProxyMode(bool deleteNonProxyBitmap) {
2793
2794 m_theBitmap.EnableProxyMode(deleteNonProxyBitmap);
2795 size_t count = m_theBitmapList.length();
2796 for(size_t i = 0; i < count; ++i) {
2797 BitmapHolder& currentBitmap = m_theBitmapList[i];
2798 currentBitmap.EnableProxyMode(deleteNonProxyBitmap);
2799 }
2800
2801 // Re-initialize the bitmap samplers, since the active bitmap might have changed.
2802 // The previous active bitmap might even have been deleted.
2803 InitBitmapSamplers();
2804 }
2805
DisableProxyMode(bool deleteProxyBitmap)2806 void BMTex::DisableProxyMode(bool deleteProxyBitmap) {
2807
2808 m_theBitmap.DisableProxyMode(deleteProxyBitmap);
2809 size_t count = m_theBitmapList.length();
2810 for(size_t i = 0; i < count; ++i) {
2811 BitmapHolder& currentBitmap = m_theBitmapList[i];
2812 currentBitmap.DisableProxyMode(deleteProxyBitmap);
2813 }
2814
2815 InitBitmapSamplers();
2816 }
2817
ShowBitmapProxyPrecacheDialog()2818 void BMTex::ShowBitmapProxyPrecacheDialog() {
2819
2820 const TCHAR* bmName = m_bi.Name();
2821 if((bmName != NULL) && (bmName[0] != _T('\0'))) {
2822 // The Bitmap Proxy Pre-Caching dialog is now displayed, if necessary.
2823 // The ShowPrecacheDialog() method internally determines whether
2824 // it's necessary to display the actual dialog.
2825 IBitmapProxyManager* proxyManager = GetBitmapProxyManager();
2826 if((proxyManager != NULL) && proxyManager->GetGlobalProxyEnable()) {
2827 Tab<TCHAR*> filenames;
2828 TCHAR* bmNameNonConstHackHackHack = const_cast<TCHAR*>(bmName);
2829 filenames.Append(1, &bmNameNonConstHackHackHack);
2830 proxyManager->ShowPrecacheDialog(&filenames);
2831 }
2832 }
2833 }
2834
ShouldDisableProxiesForRendering(bool isMtlEditor)2835 bool BMTex::ShouldDisableProxiesForRendering(bool isMtlEditor) {
2836
2837 if(isMtlEditor) {
2838 return false;
2839 }
2840 else {
2841 IBitmapProxyManager* proxyManager = GetBitmapProxyManager();
2842 if(proxyManager != NULL) {
2843 IBitmapProxyManager::RenderMode renderMode = proxyManager->GetGlobalProxyRenderMode();
2844 switch(renderMode) {
2845 default:
2846 DbgAssert(false);
2847 // Fall through...
2848 case IBitmapProxyManager::kRenderMode_UseProxies:
2849 return false;
2850 case IBitmapProxyManager::kRenderMode_UseFullRes_KeepInMemory:
2851 case IBitmapProxyManager::kRenderMode_UseFullRes_FlushFromMemory:
2852 return true;
2853 }
2854 }
2855 else {
2856 DbgAssert(false);
2857 return false;
2858 }
2859 }
2860 }
2861
KeepNonProxyInMemoryAfterRendering()2862 bool BMTex::KeepNonProxyInMemoryAfterRendering() {
2863
2864 IBitmapProxyManager* proxyManager = GetBitmapProxyManager();
2865 if(proxyManager != NULL) {
2866 IBitmapProxyManager::RenderMode renderMode = proxyManager->GetGlobalProxyRenderMode();
2867 switch(renderMode) {
2868 default:
2869 DbgAssert(false);
2870 // Fall through...
2871 case IBitmapProxyManager::kRenderMode_UseProxies:
2872 case IBitmapProxyManager::kRenderMode_UseFullRes_FlushFromMemory:
2873 return false;
2874 case IBitmapProxyManager::kRenderMode_UseFullRes_KeepInMemory:
2875 return true;
2876 }
2877 }
2878 else {
2879 DbgAssert(false);
2880 return false;
2881 }
2882 }
2883
InitBitmapSamplers()2884 void BMTex::InitBitmapSamplers() {
2885
2886 BOOL tieTimeToMatID;
2887 pblockTime->GetValue( bmtex_matidtime, 0, tieTimeToMatID,FOREVER);
2888
2889 if (!tieTimeToMatID)
2890 {
2891 mysamp.Init(this);
2892 alphasamp.Init(this);
2893 }
2894 else
2895 {
2896 for (int i = 0; i < mysampList.Count(); i++)
2897 {
2898 mysampList[i]->Init(this,m_theBitmapList[i].GetBitmap());
2899 alphasampList[i]->Init(this,m_theBitmapList[i].GetBitmap());
2900 }
2901 }
2902 }
2903
2904 //==============================================================================
2905 // class BMTex::BMMSilentModeGuard
2906 //==============================================================================
2907
BMMSilentModeGuard(bool setSilentMode)2908 BMTex::BMMSilentModeGuard::BMMSilentModeGuard(bool setSilentMode)
2909 : m_setSilentMode(setSilentMode)
2910 {
2911 if(m_setSilentMode) {
2912 m_previousSilentMode = TheManager->SetSilentMode(true);
2913 }
2914 }
~BMMSilentModeGuard()2915 BMTex::BMMSilentModeGuard::~BMMSilentModeGuard() {
2916 if(m_setSilentMode) {
2917 TheManager->SetSilentMode(m_previousSilentMode);
2918 }
2919 }
2920
2921 //==============================================================================
2922 // class BMTex::BitmapHolder
2923 //==============================================================================
2924
BitmapHolder()2925 BMTex::BitmapHolder::BitmapHolder()
2926 : m_nonProxyBitmap(NULL),
2927 m_proxyBitmap(NULL),
2928 m_isProxyMode(true)
2929 {
2930 }
2931
BitmapHolder(const BitmapHolder & other)2932 BMTex::BitmapHolder::BitmapHolder(const BitmapHolder& other) {
2933
2934 *this = other;
2935 }
2936
~BitmapHolder()2937 BMTex::BitmapHolder::~BitmapHolder() {
2938 // The bitmaps should have already been freed by BMTex. I won't free them here (just in case,
2939 // to avoid double-deleting something), but I'm still putting a debug assert to catch any
2940 // possible issues.
2941 DbgAssert((m_proxyBitmap == NULL) && (m_nonProxyBitmap == NULL));
2942 }
2943
2944
operator =(const BitmapHolder & other)2945 BMTex::BitmapHolder& BMTex::BitmapHolder::operator=(const BitmapHolder& other) {
2946
2947 m_nonProxyBitmap = other.m_nonProxyBitmap;
2948 m_proxyBitmap = other.m_proxyBitmap;
2949 m_isProxyMode = other.m_isProxyMode;
2950 m_nonProxyBitmapInfo = other.m_nonProxyBitmapInfo;
2951 m_proxyBitmapInfo = other.m_proxyBitmapInfo;
2952
2953 return *this;
2954 }
2955
IsCurrentFrame(Bitmap * bitmap,int frame)2956 bool IsCurrentFrame( Bitmap* bitmap, int frame ) {
2957 BitmapStorage* storage = NULL;
2958 if( bitmap!=NULL ) storage = bitmap->Storage();
2959
2960 if( storage==NULL ) return false;
2961 BitmapInfo* info = GetSubjectInfo( &(storage->bi) );
2962
2963 return (info->CurrentFrame() == frame);
2964 }
2965
EnableProxyMode(bool deleteNonProxyBitmap)2966 void BMTex::BitmapHolder::EnableProxyMode(bool deleteNonProxyBitmap) {
2967
2968 if( m_isProxyMode!=true ) {
2969 m_isProxyMode = true;
2970
2971 // Ensure both bitmaps are on the same frame
2972 // Non-proxy info holds the desired frame, whether in proxy mode or not
2973 int currentFrame = m_nonProxyBitmapInfo.CurrentFrame();
2974 if( !IsCurrentFrame( m_proxyBitmap, currentFrame ) ) {
2975 if( m_proxyBitmap!=NULL )
2976 BitmapProxy_GoTo( m_nonProxyBitmapInfo, m_proxyBitmapInfo, m_proxyBitmap );
2977 }
2978 }
2979
2980 if(deleteNonProxyBitmap) {
2981 FreeNonProxyBitmap();
2982 }
2983 }
2984
DisableProxyMode(bool deleteProxyBitmap)2985 void BMTex::BitmapHolder::DisableProxyMode(bool deleteProxyBitmap) {
2986
2987 if( m_isProxyMode!=false ) {
2988 m_isProxyMode = false;
2989
2990 // Ensure both bitmaps are on the same frame
2991 // Non-proxy info holds the desired frame, whether in proxy mode or not
2992 int currentFrame = m_nonProxyBitmapInfo.CurrentFrame();
2993 if( !IsCurrentFrame( m_nonProxyBitmap, currentFrame ) ) {
2994 if( m_nonProxyBitmap!=NULL )
2995 BitmapNonProxy_GoTo( m_nonProxyBitmapInfo, m_nonProxyBitmap );
2996 }
2997 }
2998
2999 if(deleteProxyBitmap) {
3000 FreeProxyBitmap();
3001 }
3002 }
3003
LoadBitmap(BMMRES & status,bool silenceBitmapManager)3004 bool BMTex::BitmapHolder::LoadBitmap(BMMRES& status, bool silenceBitmapManager) {
3005
3006 // Set silent mode if necessary
3007 BMMSilentModeGuard silentModeGuard(silenceBitmapManager);
3008
3009 if(m_isProxyMode) {
3010 // The bitmap should be NULL, otherwise we'll get a memory leak
3011 DbgAssert(m_proxyBitmap == NULL);
3012 m_proxyBitmap = BitmapProxy_Load(m_nonProxyBitmapInfo, m_proxyBitmapInfo, &status);
3013 return (m_proxyBitmap != NULL);
3014 }
3015 else {
3016 // The bitmap should be NULL, otherwise we'll get a memory leak
3017 DbgAssert(m_nonProxyBitmap == NULL);
3018 m_nonProxyBitmap = BitmapNonProxy_Load(m_nonProxyBitmapInfo, &status);
3019 return (m_nonProxyBitmap != NULL);
3020 }
3021 }
3022
LoadInto(bool forceReload)3023 void BMTex::BitmapHolder::LoadInto(bool forceReload) {
3024
3025 // Reload both the proxy and non-proxy bitmaps, to ensure that none of them is invalid.
3026 if(m_nonProxyBitmap != NULL) {
3027 BitmapNonProxy_LoadInto(m_nonProxyBitmapInfo, &m_nonProxyBitmap, forceReload);
3028 }
3029
3030 if(m_proxyBitmap != NULL) {
3031 BitmapProxy_LoadInto(m_nonProxyBitmapInfo, m_proxyBitmapInfo, &m_proxyBitmap, forceReload);
3032 }
3033 }
3034
FreeBitmap()3035 void BMTex::BitmapHolder::FreeBitmap() {
3036
3037 // Free both the proxy and non-proxy bitmaps.
3038 FreeNonProxyBitmap();
3039 FreeProxyBitmap();
3040 }
3041
FreeProxyBitmap()3042 void BMTex::BitmapHolder::FreeProxyBitmap() {
3043
3044 if(m_proxyBitmap != NULL) {
3045 m_proxyBitmap->DeleteThis();
3046 m_proxyBitmap = NULL;
3047 }
3048 }
3049
FreeNonProxyBitmap()3050 void BMTex::BitmapHolder::FreeNonProxyBitmap() {
3051
3052 if(m_nonProxyBitmap != NULL) {
3053 m_nonProxyBitmap->DeleteThis();
3054 m_nonProxyBitmap = NULL;
3055 }
3056 }
3057
GotoFrame(bool silenceBitmapManager)3058 BMMRES BMTex::BitmapHolder::GotoFrame(bool silenceBitmapManager) {
3059
3060 // Forward the call to the active bitmap.
3061 // The "inactive" bitmap doesn't get the call, which I think should be fine.
3062 // If there's ever a problem, though, it might be necessary to call GoTo()
3063 // on both bitmaps.
3064
3065 BMMRES result = BMMRES_SUCCESS;
3066
3067 // Set silent mode if necessary
3068 BMMSilentModeGuard silentModeGuard(silenceBitmapManager);
3069
3070 if(m_isProxyMode) {
3071 if(m_proxyBitmap != NULL) {
3072 result = BitmapProxy_GoTo(m_nonProxyBitmapInfo, m_proxyBitmapInfo, m_proxyBitmap);
3073 }
3074 else {
3075 DbgAssert(false);
3076 }
3077 }
3078 else {
3079 if(m_nonProxyBitmap != NULL) {
3080 result = BitmapNonProxy_GoTo(m_nonProxyBitmapInfo, m_nonProxyBitmap);
3081 }
3082 else {
3083 DbgAssert(false);
3084 }
3085 }
3086
3087 return result;
3088 }
3089
GetBitmapInfo()3090 BitmapInfo& BMTex::BitmapHolder::GetBitmapInfo() {
3091
3092 return m_nonProxyBitmapInfo;
3093 }
3094
GetBitmapInfo() const3095 const BitmapInfo& BMTex::BitmapHolder::GetBitmapInfo() const {
3096
3097 return m_nonProxyBitmapInfo;
3098 }
3099
GetBitmap() const3100 Bitmap* BMTex::BitmapHolder::GetBitmap() const {
3101
3102 if(m_isProxyMode) {
3103 return m_proxyBitmap;
3104 }
3105 else {
3106 return m_nonProxyBitmap;
3107 }
3108 }
3109
SetBitmap(Bitmap * bitmap)3110 void BMTex::BitmapHolder::SetBitmap(Bitmap* bitmap) {
3111
3112 // The bitmap should first have been freed in order to avoid memroy leaks.
3113 DbgAssert((m_nonProxyBitmap == NULL) && (m_proxyBitmap == NULL));
3114
3115 // Set the proper bitmap, depending on whether it's a proxy or not.
3116 if(bitmap == NULL) {
3117 m_proxyBitmap = NULL;
3118 m_nonProxyBitmap = NULL;
3119 }
3120 else if((bitmap->Storage() != NULL) && (bitmap->Storage()->bi.Flags() & MAP_PROXY)) {
3121 m_proxyBitmap = bitmap;
3122 }
3123 else {
3124 m_nonProxyBitmap = bitmap;
3125 }
3126 }
3127
SetFilter(UINT filterType)3128 int BMTex::BitmapHolder::SetFilter(UINT filterType) {
3129
3130 int result = 0;
3131 if(m_proxyBitmap != NULL) {
3132 result |= m_proxyBitmap->SetFilter(filterType);
3133 }
3134 if(m_nonProxyBitmap != NULL) {
3135 result |= m_nonProxyBitmap->SetFilter(filterType);
3136 }
3137
3138 return result;
3139 }
3140
SetCroppingValues(float u,float v,float w,float h,BOOL placeImage)3141 void BMTex::BitmapHolder::SetCroppingValues(float u, float v, float w, float h, BOOL placeImage) {
3142
3143 if(m_proxyBitmap != NULL) {
3144 m_proxyBitmap->SetCroppingValues(u, v, w, h, placeImage);
3145 }
3146 if(m_nonProxyBitmap != NULL) {
3147 m_nonProxyBitmap->SetCroppingValues(u, v, w, h, placeImage);
3148 }
3149 }
3150
SetNotify(BitmapNotify * bmnot)3151 void BMTex::BitmapHolder::SetNotify(BitmapNotify *bmnot) {
3152
3153 // Register the notification with only one bitmap; registering it
3154 // with both bitmaps results in a crash when the notification is received
3155 // and the bitmaps are reloaded (the crash occurs when the notification system
3156 // attempts to notify the second, now defunct bitmap).
3157
3158 // Register the notification with the proxy bitmap.
3159 // The notification is responsible for updating the viewport,
3160 // so it must be registered against the proxy bitmap which is used for viewport display.
3161 // The notification also triggers a full reload if the subject changes,
3162 // which would be equivalent if registered against either bitmap.
3163
3164 if( (m_proxyBitmap != NULL) && (m_proxyBitmap->GetNotify() != bmnot) ) {
3165 m_proxyBitmap->SetNotify(bmnot);
3166 }
3167 }
3168
3169 //==============================================================================
3170 // class BMTex::ProxyModeDisableGuard
3171 //==============================================================================
3172
ProxyModeDisableGuard(BMTex & bitmapTex,bool doDisable)3173 BMTex::ProxyModeDisableGuard::ProxyModeDisableGuard(BMTex& bitmapTex, bool doDisable)
3174 : m_bitmapTex(bitmapTex),
3175 m_doDisable(doDisable)
3176 {
3177 if(m_doDisable) {
3178 m_bitmapTex.DisableProxyMode(false);
3179 }
3180 }
3181
~ProxyModeDisableGuard()3182 BMTex::ProxyModeDisableGuard::~ProxyModeDisableGuard() {
3183
3184 if(m_doDisable) {
3185 bool flushNonProxyAfterRender = !KeepNonProxyInMemoryAfterRendering();
3186 m_bitmapTex.EnableProxyMode(flushNonProxyAfterRender);
3187 }
3188 }
3189