1 /*===========================================================================*\
2 | File: Stucco.cpp
3 |
4 | Purpose: A 3D Map for creating 'stucco' type patterns.
5 | This is a port of the 3D Studio/DOS SXP by Dan Silva.
6 |
7 | History: Mark Meier, Began 02/05/97.
8 | MM, Last Change 02/05/97.
9 Updated to Param Block2 by Peter Watje 12/1/1998
10 \*===========================================================================*/
11 /*===========================================================================*\
12 | Include Files
13 \*===========================================================================*/
14 #include "procmaps.h"
15 #include "iparamm2.h"
16 #include "resource.h"
17 #include "resourceOverride.h"
18 #include "macrorec.h"
19
20 /*===========================================================================*\
21 | Miscellaneous Defines
22 \*===========================================================================*/
23
24 #define SHOW_3DMAPS_WITH_2D
25
26 // The unique ClassID
27 static Class_ID stuccoClassID(STUCCO_CLASS_ID, 0);
28
29 // This is the number of colors used
30 #define NUM_COLORS 2
31
32 // This is the number of sub-texmaps used
33 #define NUM_SUB_TEXMAPS 2
34
35 struct Col24 {
36 ULONG r, g, b;
37 };
38
ColorFromCol24(Col24 a)39 static Color ColorFromCol24(Col24 a) {
40 Color c;
41 c.r = (float)a.r/255.0f;
42 c.g = (float)a.g/255.0f;
43 c.b = (float)a.b/255.0f;
44 return c;
45 }
46
Col24FromColor(Color a)47 static Col24 Col24FromColor(Color a) {
48 Col24 c;
49 c.r = (ULONG)(a.r*255.0f);
50 c.g = (ULONG)(a.g*255.0f);
51 c.b = (ULONG)(a.b*255.0f);
52 return c;
53 }
54
55 #define STUCCO_VERS 0xfaaaa3c2
56
57 #pragma pack(1)
58 struct StuccoState {
59 ulong version;
60 float size;
61 float threshold;
62 float thickness;
63 float del;
64 Col24 col1, col2;
65 };
66 #pragma pack()
67
68 // These are various resource IDs
69 static int colID[2] = { IDC_COL1, IDC_COL2 };
70 static int subTexId[NUM_SUB_TEXMAPS] = { IDC_TEX1, IDC_TEX2 };
71 static int mapOnId[NUM_SUB_TEXMAPS] = { IDC_MAPON1, IDC_MAPON2 };
72
73 // Forward references
74 //class Stucco;
75 //class StuccoDlgProc;
76
77 /*===========================================================================*\
78 | Stucco 3D Texture Map Plug-In Class
79 \*===========================================================================*/
80 class Stucco : public Tex3D {
81 // This allows the class that manages the UI to access the private
82 // data members of this class.
83 // friend class StuccoDlg;
84
85 // These are the current colors from the color swatch controls.
86 Color col[NUM_COLORS];
87
88 // These are the parameters managed by the parameter map
89 float size;
90 float thresh;
91 float thick;
92 float del;
93 Point3 col1, col2;
94
95 // This points to the XYZGen instance used to handle the
96 // 'Coordinates' rollup in the materials editor.
97 // This is reference #0 of this class.
98 XYZGen *xyzGen;
99 // These are the sub-texmaps. If these are set by the user
100 // then the color of our texture is affected by the sub-texmaps
101 // and not the color swatches.
102 // These are reference #2 and #3 of this class.
103 Texmap *subTex[NUM_SUB_TEXMAPS];
104 // This holds the validity interval of the texmap.
105 Interval texValidity;
106 // This is the version of the texture loaded from disk.
107 int fileVersion;
108 // This points to the ParamDlg instance used to manage the UI
109 // StuccoDlg *paramDlg;
110
111 #ifdef SHOW_3DMAPS_WITH_2D
112 TexHandle *texHandle;
113 Interval texHandleValid;
114 #endif
115
116 public:
117 static ParamDlg* xyzGenDlg;
118 // This is the parameter block which manages the data for the
119 // spinner and color swatch controls.
120 // This is reference #1 of this class.
121 IParamBlock2 *pblock;
122 // Indicates if a sub-texmap is to be used or not
123 BOOL mapOn[NUM_SUB_TEXMAPS];
124
125 // --- Methods inherited from Animatable ---
ClassID()126 Class_ID ClassID() { return stuccoClassID; }
SuperClassID()127 SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
GetClassName(TSTR & s)128 void GetClassName(TSTR& s) { s= GetString(IDS_DS_STUCCO); }
DeleteThis()129 void DeleteThis() { delete this; }
130
131 // We have 4 sub-animatables. These are the xyzGen,
132 // the pblock, and the two sub-texmaps
NumSubs()133 int NumSubs() { return 2+NUM_SUB_TEXMAPS; }
134 Animatable* SubAnim(int i);
135 TSTR SubAnimName(int i);
SubNumToRefNum(int subNum)136 int SubNumToRefNum(int subNum) { return subNum; }
137
138 // --- Methods inherited from ReferenceMaker ---
139 // We have 4 references. These are the xyzGen,
140 // the pblock, and the two sub-texmaps
NumRefs()141 int NumRefs() { return 2+NUM_SUB_TEXMAPS; }
142 RefTargetHandle GetReference(int i);
143 void SetReference(int i, RefTargetHandle rtarg);
144 RefResult NotifyRefChanged(Interval changeInt,
145 RefTargetHandle hTarget, PartID& partID, RefMessage message);
146 IOResult Save(ISave *isave);
147 IOResult Load(ILoad *iload);
148
149 // --- Methods inherited from ReferenceTarget ---
150 RefTargetHandle Clone(RemapDir &remap = DefaultRemapDir());
151
152 // --- Methods inherited from MtlBase ---
LocalRequirements(int subMtlNum)153 ULONG LocalRequirements(int subMtlNum) {
154 return xyzGen->Requirements(subMtlNum);
155 }
LocalMappingsRequired(int subMtlNum,BitArray & mapreq,BitArray & bumpreq)156 void LocalMappingsRequired(int subMtlNum, BitArray & mapreq, BitArray &bumpreq) {
157 xyzGen->MappingsRequired(subMtlNum,mapreq,bumpreq);
158 }
159 void Update(TimeValue t, Interval& ivalid);
160 void Init();
161 void Reset();
162 Interval Validity(TimeValue t);
163 ParamDlg* CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp);
NumSubTexmaps()164 int NumSubTexmaps() { return NUM_SUB_TEXMAPS; }
165 Texmap* GetSubTexmap(int i);
166 void SetSubTexmap(int i, Texmap *m);
167 TSTR GetSubTexmapSlotName(int i);
168 void ReadSXPData(TCHAR *name, void *sxpdata);
169
170 // --- Methods inherited from Texmap ---
GetTheXYZGen()171 XYZGen *GetTheXYZGen() { return xyzGen; }
172 RGBA EvalColor(ShadeContext& sc);
173 Point3 EvalNormalPerturb(ShadeContext& sc);
174
175 #ifdef SHOW_3DMAPS_WITH_2D
DiscardTexHandle()176 void DiscardTexHandle() {
177 if (texHandle) {
178 texHandle->DeleteThis();
179 texHandle = NULL;
180 }
181 }
SupportTexDisplay()182 BOOL SupportTexDisplay() { return TRUE; }
ActivateTexDisplay(BOOL onoff)183 void ActivateTexDisplay(BOOL onoff) {
184 if (!onoff) DiscardTexHandle();
185 }
186 DWORD_PTR GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker);
187 #endif SHOW_3DMAPS_WITH_2D
188
189 // --- Methods of Stucco ---
190 Stucco();
~Stucco()191 ~Stucco() {
192 #ifdef SHOW_3DMAPS_WITH_2D
193 DiscardTexHandle();
194 #endif
195 }
196
197 float Func(Point3 p, float scl);
198 float EvalFunc(ShadeContext &sc);
199 void SwapInputs();
200 void NotifyChanged();
201 void SetSize(float f, TimeValue t);
202 void SetThick(float f, TimeValue t);
203 void SetThresh(float f, TimeValue t);
204 void SetColor(int i, Color c, TimeValue t);
205 void ClampFloat(float &f, float min, float max);
206
207 // JBW: direct ParamBlock access is added
NumParamBlocks()208 int NumParamBlocks() { return 1; } // return number of ParamBlocks in this instance
GetParamBlock(int i)209 IParamBlock2* GetParamBlock(int i) { return pblock; } // return i'th ParamBlock
GetParamBlockByID(BlockID id)210 IParamBlock2* GetParamBlockByID(BlockID id) { return (pblock->ID() == id) ? pblock : NULL; } // return id'd ParamBlock
211 BOOL SetDlgThing(ParamDlg* dlg);
212
IsLocalOutputMeaningful(ShadeContext & sc)213 bool IsLocalOutputMeaningful( ShadeContext& sc ) { return true; }
214
215 };
216
217 // This is the Class Descriptor for the Stucco 3D Texture plug-in
218 class StuccoClassDesc : public ClassDesc2 {
219 public:
IsPublic()220 int IsPublic() { return GetAppID() != kAPP_VIZR; }
Create(BOOL loading)221 void * Create(BOOL loading) { return new Stucco; }
ClassName()222 const TCHAR * ClassName() { return GetString(IDS_DS_STUCCO_CDESC); } // mjm - 2.3.99
SuperClassID()223 SClass_ID SuperClassID() { return TEXMAP_CLASS_ID; }
ClassID()224 Class_ID ClassID() { return stuccoClassID; }
Category()225 const TCHAR* Category() { return TEXMAP_CAT_3D; }
226 // JBW: new descriptor data accessors added. Note that the
227 // internal name is hardwired since it must not be localized.
InternalName()228 const TCHAR* InternalName() { return _T("stucco"); } // returns fixed parsable name (scripter-visible name)
HInstance()229 HINSTANCE HInstance() { return hInstance; } // returns owning module handle
230
231 };
232 static StuccoClassDesc stuccoCD;
233
GetStuccoDesc()234 ClassDesc *GetStuccoDesc() { return &stuccoCD; }
235 ParamDlg* Stucco::xyzGenDlg;
236
237 /*===========================================================================*\
238 | Class to Manage the User Interface in the Materials Editor
239 \*===========================================================================*/
240 /*
241 class StuccoDlg: public ParamDlg {
242 public:
243 // This is our UI rollup page window handle in the materials editor
244 HWND hParamDlg;
245 // Window handle of the materials editor dialog itself
246 HWND hMedit;
247 // Interface for calling methods provided by MAX
248 IMtlParams *ip;
249 // The current Stucco being edited.
250 Stucco *theTex;
251 // Parameter Map for handling UI controls
252 IParamMap *pmap;
253 // Custom buttons for texture maps
254 ICustButton *iCustButton[NUM_SUB_TEXMAPS];
255 // Custom conrols for the colors
256 IColorSwatch *cs[NUM_COLORS];
257 // This is used inside the SetTime method to only update the UI
258 // controls when the time slider has changed
259 TimeValue curTime;
260 // Point to the XYZGenDlg we use
261 ParamDlg *xyzGenDlg;
262 BOOL valid;
263 BOOL isActive;
264 TexDADMgr dadMgr;
265
266 // --- Methods inherited from ParamDlg ---
267 Class_ID ClassID();
268 void SetThing(ReferenceTarget *m);
269 ReferenceTarget* GetThing();
270 void SetTime(TimeValue t);
271 int FindSubTexFromHWND(HWND hw);
272 void ReloadDialog();
273 void ActivateDlg(BOOL onOff);
274 void DeleteThis() { delete this; }
275
276 // --- StuccoDlg Methods ---
277 StuccoDlg(HWND hwMtlEdit, IMtlParams *imp, Stucco *m);
278 ~StuccoDlg();
279 INT_PTR PanelProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
280 void UpdateSubTexNames();
281 void LoadDialog();
282 void UpdateMtlDisplay() { ip->MtlChanged(); }
283 void Invalidate();
284 };
285 */
286 /*===========================================================================*\
287 | Noise and Lerp Functions
288 \*===========================================================================*/
lerp_color(Col24 * c,Col24 * a,Col24 * b,float f)289 static void lerp_color(Col24 *c, Col24 *a, Col24 *b, float f) {
290 int alph = (int)(4096*f);
291 int ialph = 4096-alph;
292 c->r = (ialph*a->r + alph*b->r)>>12;
293 c->g = (ialph*a->g + alph*b->g)>>12;
294 c->b = (ialph*a->b + alph*b->b)>>12;
295 }
296
297 /*===========================================================================*\
298 | Parameter Map Related Data and Methods
299 \*===========================================================================*/
300 // Parameter block indices
301 /*
302 #define PB_SIZE 0
303 #define PB_THRESH 1
304 #define PB_THICK 2
305 #define PB_COL1 3
306 #define PB_COL2 4
307 */
308
309 // Spinner limits
310 #define MIN_SIZE 0.001f
311 #define MAX_SIZE 999999999.0f
312 #define MIN_THRESH 0.0f
313 #define MAX_THRESH 1.0f
314
315 #define MIN_THICK 0.0f
316 #define MAX_THICK 1.0f
317
318 // Paramter block version number
319 #define STUCCO_PB_VERSION 2
320
321 enum { stucco_params }; // pblock ID
322 // grad_params param IDs
323 enum
324 {
325 stucco_size,stucco_thickness,stucco_threshold,
326 stucco_color1, stucco_color2,
327 stucco_map1, stucco_map2,
328 stucco_mapon1,stucco_mapon2,
329 stucco_coords, // access for UVW mapping
330 };
331
332 static ParamBlockDesc2 stucco_param_blk ( stucco_params, _T("parameters"), 0, &stuccoCD, P_AUTO_CONSTRUCT + P_AUTO_UI, 1,
333 //rollout
334 IDD_STUCCO, IDS_DS_STUCCO_PARAMS, 0, 0, NULL,
335 // params
336
337
338 stucco_size, _T("size"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_SIZE,
339 p_default, 20.f,
340 p_range, MIN_SIZE, MAX_SIZE,
341 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_SIZE_EDIT,IDC_SIZE_SPIN, 0.1f,
342 end,
343 stucco_thickness, _T("thickness"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_THICKNESS,
344 p_default, .15f,
345 p_range, MIN_THICK, MAX_THICK,
346 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_THICK_EDIT,IDC_THICK_SPIN, 0.01f,
347 end,
348 stucco_threshold, _T("threshold"), TYPE_FLOAT, P_ANIMATABLE, IDS_DS_THRESH,
349 p_default, 0.57f,
350 p_range, MIN_THRESH, MAX_THRESH,
351 p_ui, TYPE_SPINNER, EDITTYPE_FLOAT, IDC_THRESH_EDIT,IDC_THRESH_SPIN, 0.01f,
352 end,
353 stucco_color1, _T("color1"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_COL1,
354 p_default, Color(0.f, 0.f, 0.0f),
355 p_ui, TYPE_COLORSWATCH, IDC_COL1,
356 end,
357 stucco_color2, _T("color2"), TYPE_RGBA, P_ANIMATABLE, IDS_DS_COL2,
358 p_default, Color(0.9f, 0.9f, 0.9f),
359 p_ui, TYPE_COLORSWATCH, IDC_COL2,
360 end,
361 stucco_map1, _T("map1"), TYPE_TEXMAP, P_OWNERS_REF, IDS_PW_MAP1,
362 p_refno, 2,
363 p_subtexno, 0,
364 p_ui, TYPE_TEXMAPBUTTON, IDC_TEX1,
365 end,
366 stucco_map2, _T("map2"), TYPE_TEXMAP, P_OWNERS_REF, IDS_PW_MAP2,
367 p_refno, 3,
368 p_subtexno, 1,
369 p_ui, TYPE_TEXMAPBUTTON, IDC_TEX2,
370 end,
371 stucco_mapon1, _T("map1On"), TYPE_BOOL, 0, IDS_PW_MAPON1,
372 p_default, TRUE,
373 p_ui, TYPE_SINGLECHEKBOX, IDC_MAPON1,
374 end,
375 stucco_mapon2, _T("map2On"), TYPE_BOOL, 0, IDS_PW_MAPON2,
376 p_default, TRUE,
377 p_ui, TYPE_SINGLECHEKBOX, IDC_MAPON2,
378 end,
379 stucco_coords, _T("coords"), TYPE_REFTARG, P_OWNERS_REF, IDS_PW_COORDINATES,
380 p_refno, 0,
381 end,
382
383 end
384 );
385
386 /*
387 // Array of parameter descriptors
388 static ParamUIDesc paramDesc[] = {
389 ParamUIDesc(
390 PB_SIZE,
391 EDITTYPE_FLOAT,
392 IDC_SIZE_EDIT,IDC_SIZE_SPIN,
393 MIN_SIZE, MAX_SIZE,
394 SPIN_AUTOSCALE),
395
396 ParamUIDesc(
397 PB_THRESH,
398 EDITTYPE_FLOAT,
399 IDC_THRESH_EDIT,IDC_THRESH_SPIN,
400 MIN_THRESH, MAX_THRESH,
401 SPIN_AUTOSCALE),
402
403 ParamUIDesc(
404 PB_THICK,
405 EDITTYPE_FLOAT,
406 IDC_THICK_EDIT,IDC_THICK_SPIN,
407 MIN_THICK, MAX_THICK,
408 SPIN_AUTOSCALE),
409
410 ParamUIDesc(PB_COL1, TYPE_COLORSWATCH, IDC_COL1),
411 ParamUIDesc(PB_COL2, TYPE_COLORSWATCH, IDC_COL2)
412 };
413 */
414 // The number of descriptors in the paramDesc array
415 #define PARAMDESC_LENGTH 5
416
417 // Parameter block parameters
418 static ParamBlockDescID pbdesc[] = {
419 { TYPE_FLOAT, NULL, TRUE, stucco_size }, // size
420 { TYPE_FLOAT, NULL, TRUE, stucco_threshold }, // thresh
421 { TYPE_FLOAT, NULL, TRUE, stucco_thickness }, // thick
422 { TYPE_RGBA, NULL, TRUE, stucco_color1 }, // color 1
423 { TYPE_RGBA, NULL, TRUE, stucco_color2 } // color 2
424 };
425 // The number of parameters in the parameter block
426 #define PB_LENGTH 5
427
428
429 static ParamVersionDesc versions[] = {
430 ParamVersionDesc(pbdesc,5,1) // Version 1 params
431 };
432
433 // The names of the parameters in the parameter block
434 static int nameIDs[] = {
435 IDS_DS_SIZE,IDS_DS_THRESH,IDS_DS_THICKNESS,
436 IDS_DS_COL1, IDS_DS_COL2 };
437 /*
438 // This is the class that allows the sub-map buttons to be processed.
439 class StuccoDlgProc : public ParamMapUserDlgProc {
440 public:
441 StuccoDlg *theDlg;
442 StuccoDlgProc(StuccoDlg *s) { theDlg = s; }
443 INT_PTR DlgProc(TimeValue t, IParamMap *map,
444 HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
445 void DeleteThis() { delete this; }
446 };
447
448 // This is the dialog proc to process the texmap buttons
449 INT_PTR StuccoDlgProc::DlgProc(TimeValue t, IParamMap *map,
450 HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
451 theDlg->isActive = TRUE;
452 BOOL res = theDlg->PanelProc(hWnd, msg, wParam, lParam);
453 theDlg->isActive = FALSE;
454 return res;
455 }
456
457 INT_PTR StuccoDlg::PanelProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) {
458 int id = LOWORD(wParam);
459 int code = HIWORD(wParam);
460 switch (msg) {
461 case WM_INITDIALOG: {
462 for (int i = 0; i < NUM_COLORS; i++)
463 cs[i] = GetIColorSwatch(GetDlgItem(hParamDlg, colID[i]),
464 theTex->col[i], theTex->GetSubTexmapSlotName(i).data());
465 for (i = 0; i < NUM_SUB_TEXMAPS; i++) {
466 iCustButton[i] = GetICustButton(GetDlgItem(hWnd, subTexId[i]));
467 iCustButton[i]->SetDADMgr(&dadMgr);
468 SetCheckBox(hWnd, mapOnId[i], theTex->mapOn[i]);
469 }
470 return TRUE;
471 }
472 break;
473
474 case WM_COMMAND:
475 switch (id) {
476 case IDC_TEX1:
477 PostMessage(hMedit, WM_TEXMAP_BUTTON, 0, (LPARAM)theTex);
478 break;
479
480 case IDC_TEX2:
481 PostMessage(hMedit, WM_TEXMAP_BUTTON, 1, (LPARAM)theTex);
482 break;
483
484 case IDC_SWAP: {
485 theTex->SwapInputs();
486 IParamBlock *pb = (IParamBlock *)pmap->GetParamBlock();
487 pb->SetValue(PB_COL1, curTime, theTex->col[0]);
488 pb->SetValue(PB_COL2, curTime, theTex->col[1]);
489 pmap->Invalidate();
490 UpdateSubTexNames();
491 UpdateMtlDisplay();
492 theTex->NotifyChanged();
493 }
494 break;
495
496 case IDC_MAPON1:
497 theTex->mapOn[0] = GetCheckBox(hWnd, id);
498 theTex->NotifyChanged();
499 UpdateMtlDisplay();
500 break;
501
502 case IDC_MAPON2:
503 theTex->mapOn[1] = GetCheckBox(hWnd, id);
504 theTex->NotifyChanged();
505 UpdateMtlDisplay();
506 break;
507 }
508 break;
509
510 case WM_LBUTTONDOWN: case WM_LBUTTONUP: case WM_MOUSEMOVE:
511 ip->RollupMouseMessage(hWnd, msg, wParam, lParam);
512 return FALSE;
513
514 case WM_PAINT:
515 if (!valid) {
516 valid = TRUE;
517 ReloadDialog();
518 }
519 break;
520
521 case WM_CLOSE:
522 break;
523
524 case WM_DESTROY:
525 break;
526 }
527 return FALSE;
528 }
529 */
530 /*===========================================================================*\
531 | StuccoDlg Methods
532 \*===========================================================================*/
533 // --- StuccoDlg Methods ---
534 // Constructor.
535 // This is called from within the Stucco::CreateParamDlg method. That
536 // method is passed the handle to the materials editor dialog, and an
537 // interface for calling methods of MAX. These are passed in here and stored.
538 /*
539 StuccoDlg::StuccoDlg(HWND hwMtlEdit, IMtlParams *imp, Stucco *m) {
540 dadMgr.Init(this);
541 hMedit = hwMtlEdit;
542 ip = imp;
543 theTex = m;
544 valid = FALSE;
545 isActive = FALSE;
546 curTime = ip->GetTime();
547
548 // This call allocates a new instance of the XYZGen class
549 xyzGenDlg = theTex->xyzGen->CreateParamDlg(hMedit, imp);
550
551 // Creates a parameter map to handle the display of texture map
552 // parameters in the material editor
553 pmap = CreateMParamMap(paramDesc, PARAMDESC_LENGTH,
554 theTex->pblock, ip, hInstance, MAKEINTRESOURCE(IDD_STUCCO),
555 GetString(IDS_DS_STUCCO_PARAMS), 0);
556
557 // Save the window handle of the rollup page
558 hParamDlg = pmap->GetHWnd();
559
560 // Establish the dialog proc to handle the custom button controls
561 pmap->SetUserDlgProc(new StuccoDlgProc(this));
562 }
563
564 // Destructor.
565 // This is called after the user changes to another sample slot in
566 // the materials editor that does not contain a Stucco texture.
567 // Note that it is not called if they do go to another Stucco -- in
568 // that case, the parameters in the rollup page are updated, but
569 // the entire page is not deleted. This is accomplished by simply
570 // changing the parameter block pointer (done inside StuccoDlg::SetThing()).
571 StuccoDlg::~StuccoDlg() {
572 theTex->paramDlg = NULL;
573 for (int i = 0; i < NUM_SUB_TEXMAPS; i++) {
574 ReleaseICustButton(iCustButton[i]);
575 iCustButton[i] = NULL;
576 }
577 // Delete the XYZGen class we created
578 xyzGenDlg->DeleteThis();
579 // Delete the parameter map
580 DestroyMParamMap(pmap);
581 pmap = NULL;
582 }
583
584 // This is called by the DADMgr
585 int StuccoDlg::FindSubTexFromHWND(HWND hw) {
586 for (int i=0; i<NUM_SUB_TEXMAPS; i++) {
587 if (hw == iCustButton[i]->GetHwnd()) return i;
588 }
589 return -1;
590 }
591
592 // This is called when the dialog is loaded to set the names of the
593 // textures displayed
594 void StuccoDlg::UpdateSubTexNames() {
595 for (int i = 0; i < NUM_SUB_TEXMAPS; i++) {
596 TSTR nm;
597 Texmap *m = theTex->subTex[i];
598 if (m)
599 nm = m->GetFullName();
600 else
601 nm = GetString(IDS_DS_NONE);
602 iCustButton[i]->SetText(nm.data());
603 }
604 }
605
606 // Update the dialog display with the values of the texture we are
607 // currently editing.
608 void StuccoDlg::LoadDialog() {
609 if (theTex) {
610 Interval ivalid;
611 theTex->Update(curTime, ivalid);
612
613 ISpinnerControl *spin = (ISpinnerControl *)
614 GetISpinner(GetDlgItem(hParamDlg, IDC_SIZE_SPIN));
615 spin->SetValue(theTex->size, FALSE);
616 ReleaseISpinner(spin);
617
618 spin = (ISpinnerControl *)
619 GetISpinner(GetDlgItem(hParamDlg, IDC_THRESH_SPIN));
620 spin->SetValue(theTex->thresh, FALSE);
621 ReleaseISpinner(spin);
622
623 spin = (ISpinnerControl *)
624 GetISpinner(GetDlgItem(hParamDlg, IDC_THICK_SPIN));
625 spin->SetValue(theTex->thick, FALSE);
626 ReleaseISpinner(spin);
627
628 cs[0]->SetColor(theTex->col[0]);
629 cs[1]->SetColor(theTex->col[1]);
630
631 for (int i = 0; i < NUM_SUB_TEXMAPS; i++)
632 SetCheckBox(hParamDlg, mapOnId[i], theTex->mapOn[i]);
633
634 UpdateSubTexNames();
635 }
636 }
637
638 // This method invalidates the rollup page so it will get redrawn
639 void StuccoDlg::Invalidate() {
640 InvalidateRect(hParamDlg, NULL, FALSE);
641 valid = FALSE;
642 }
643
644 // --- Methods inherited from ParamDlg ---
645 // Returns the Class_ID of the plug-in this dialog manages
646 Class_ID StuccoDlg::ClassID() {
647 return stuccoClassID;
648 }
649
650 // This sets the current texture being edited to the texture passed
651 void StuccoDlg::SetThing(ReferenceTarget *m) {
652 assert(m->ClassID() == stuccoClassID);
653 assert(m->SuperClassID() == TEXMAP_CLASS_ID);
654 if (theTex)
655 theTex->paramDlg = NULL;
656
657 // Set the pointer to the texmap being edited to the one passed.
658 theTex = (Stucco *)m;
659
660 // Point the parameter map parameter block pointer at the
661 // one that is now being edited.
662 pmap->SetParamBlock(theTex->pblock);
663 if (theTex)
664 theTex->paramDlg = this;
665
666 // Let the XYZGen set the new one being edited
667 xyzGenDlg->SetThing(theTex->xyzGen);
668
669 // Update the dialog display with the values of the new texmap.
670 LoadDialog();
671 }
672
673 // This returns the current texture being edited
674 ReferenceTarget *StuccoDlg::GetThing() {
675 return (ReferenceTarget *)theTex;
676 }
677
678 // This method is called when the current time has changed.
679 // This gives the developer an opportunity to update any user
680 // interface data that may need adjusting due to the change in time.
681 void StuccoDlg::SetTime(TimeValue t) {
682 Interval ivalid;
683 if (t != curTime) {
684 xyzGenDlg->SetTime(t);
685 curTime = t;
686 theTex->Update(curTime, ivalid);
687 LoadDialog();
688 InvalidateRect(hParamDlg, NULL, 0);
689 }
690 }
691
692 // This method should place values into all the parameter dialog's controls,
693 // edit fields etc.
694 void StuccoDlg::ReloadDialog() {
695 Interval ivalid;
696 theTex->Update(curTime, ivalid);
697 LoadDialog();
698 }
699
700 // This method is called when the dialog box becomes active or inactive.
701 void StuccoDlg::ActivateDlg(BOOL onOff) {
702 for (int i = 0; i < NUM_COLORS; i++) {
703 cs[i]->Activate(onOff);
704 }
705 }
706 */
707
708 //dialog stuff to get the Set Ref button
709 class StuccoDlgProc : public ParamMap2UserDlgProc {
710 //public ParamMapUserDlgProc {
711 public:
712 Stucco *stucco;
StuccoDlgProc(Stucco * m)713 StuccoDlgProc(Stucco *m) {stucco = m;}
714 INT_PTR DlgProc(TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
DeleteThis()715 void DeleteThis() {delete this;}
716 };
717
718
719
DlgProc(TimeValue t,IParamMap2 * map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)720 INT_PTR StuccoDlgProc::DlgProc(
721 TimeValue t,IParamMap2 *map,HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
722 {
723 switch (msg) {
724 case WM_COMMAND:
725 switch (LOWORD(wParam))
726 {
727 case IDC_SWAP:
728 {
729 stucco = (Stucco*)map->GetParamBlock()->GetOwner();
730
731 stucco->SwapInputs();
732 }
733 break;
734 }
735 break;
736 }
737 return FALSE;
738 }
739
740 /*===========================================================================*\
741 | Stucco Methods
742 \*===========================================================================*/
743 // --- Methods inherited from Animatable ---
744 // This method returns a pointer to the 'i-th' sub-anim.
SubAnim(int i)745 Animatable* Stucco::SubAnim(int i) {
746 switch (i) {
747 case 0: return xyzGen;
748 case 1: return pblock;
749 default: return subTex[i-2];
750 }
751 }
752
753 // This method returns the name of the 'i-th' sub-anim to appear in track view.
SubAnimName(int i)754 TSTR Stucco::SubAnimName(int i) {
755 switch (i) {
756 case 0: return GetString(IDS_DS_COORDS);
757 case 1: return GetString(IDS_DS_PARAMETERS);
758 default: return GetSubTexmapTVName(i-2);
759 }
760 }
761
762 // --- Methods inherited from ReferenceMaker ---
763 // Return the 'i-th' reference
GetReference(int i)764 RefTargetHandle Stucco::GetReference(int i) {
765 switch(i) {
766 case 0: return xyzGen;
767 case 1: return pblock ;
768 default:return subTex[i-2];
769 }
770 }
771
772 // Save the 'i-th' reference
SetReference(int i,RefTargetHandle rtarg)773 void Stucco::SetReference(int i, RefTargetHandle rtarg) {
774 switch(i) {
775 case 0: xyzGen = (XYZGen *)rtarg; break;
776 case 1: pblock = (IParamBlock2 *)rtarg; break;
777 default: subTex[i-2] = (Texmap *)rtarg; break;
778 }
779 }
780
781 // This method is responsible for responding to the change notification
782 // messages sent by the texmap dependants.
NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget,PartID & partID,RefMessage message)783 RefResult Stucco::NotifyRefChanged(Interval changeInt,
784 RefTargetHandle hTarget, PartID& partID, RefMessage message ) {
785 switch (message) {
786 case REFMSG_CHANGE:
787 texValidity.SetEmpty();
788 if (hTarget == pblock)
789 {
790 ParamID changing_param = pblock->LastNotifyParamID();
791 stucco_param_blk.InvalidateUI(changing_param);
792 #ifdef SHOW_3DMAPS_WITH_2D
793 if (changing_param != -1)
794 DiscardTexHandle();
795 #endif
796 }
797 #ifdef SHOW_3DMAPS_WITH_2D
798 else if (hTarget == xyzGen)
799 {
800 DiscardTexHandle();
801 }
802 #endif
803
804 // One of the texmap dependants have changed. We set our
805 // validity interval to empty and invalidate the dialog
806 // so it gets redrawn.
807 // texValidity.SetEmpty();
808 // if (hTarget != xyzGen) {
809 // if (paramDlg) {
810 // paramDlg->pmap->Invalidate();
811 // }
812 // }
813 break;
814
815 /*
816 case REFMSG_GET_PARAM_DIM: {
817 // This returns the 'dimension' of the parameter. This is
818 // the type and order of magnitude of the parameter.
819 GetParamDim *gpd = (GetParamDim *)partID;
820 switch (gpd->index) {
821 case PB_SIZE: gpd->dim = stdWorldDim;
822 break;
823 case PB_THRESH:
824 case PB_THICK:
825 gpd->dim = defaultDim; break;
826 case PB_COL1:
827 case PB_COL2: gpd->dim = stdColor255Dim; break;
828 }
829 return REF_STOP;
830 }
831
832 case REFMSG_GET_PARAM_NAME: {
833 // This returns the name that will appear in track view
834 // of the parameter.
835 GetParamName *gpn = (GetParamName *)partID;
836 gpn->name = GetString(nameIDs[gpn->index]);
837 return REF_STOP;
838 }
839 */
840 }
841 return(REF_SUCCEED);
842 }
843
844 // Load/Save Chunk IDs
845 #define MTL_HDR_CHUNK 0x4000
846 #define STUCCO_VERS1_CHUNK 0x4001
847 #define MAPOFF_CHUNK 0x1000
848 #define PARAM2_CHUNK 0x1010
849
850 // This is called by the system to allow the plug-in to save its data
Save(ISave * isave)851 IOResult Stucco::Save(ISave *isave) {
852 IOResult res;
853
854 // Save the common stuff from the base class
855 isave->BeginChunk(MTL_HDR_CHUNK);
856 res = MtlBase::Save(isave);
857 if (res != IO_OK)
858 return res;
859 isave->EndChunk();
860
861 isave->BeginChunk(PARAM2_CHUNK);
862 isave->EndChunk();
863 /* // Save a version number chunk
864 isave->BeginChunk(STUCCO_VERS1_CHUNK);
865 isave->EndChunk();
866 // Save the on/off status of the sub-texmaps
867 for (int i = 0; i < NUM_SUB_TEXMAPS; i++) {
868 if (mapOn[i] == 0) {
869 isave->BeginChunk(MAPOFF_CHUNK+i);
870 isave->EndChunk();
871 }
872 }
873 */
874 return IO_OK;
875 }
876
877 class StuccoPostLoad : public PostLoadCallback {
878 public:
879 Stucco *n;
880 BOOL Param1;
StuccoPostLoad(Stucco * ns,BOOL b)881 StuccoPostLoad(Stucco *ns, BOOL b) {n = ns; Param1 = b;}
proc(ILoad * iload)882 void proc(ILoad *iload) {
883 if (Param1)
884 {
885 n->pblock->SetValue( stucco_mapon1, 0, n->mapOn[0]);
886 n->pblock->SetValue( stucco_mapon2, 0, n->mapOn[1]);
887 }
888 delete this;
889
890
891 }
892 };
893
894
895 // This is called by the system to allow the plug-in to load its data
Load(ILoad * iload)896 IOResult Stucco::Load(ILoad *iload) {
897 IOResult res;
898 int id;
899 fileVersion = 0;
900 BOOL Param1 = TRUE;
901 while (IO_OK == (res = iload->OpenChunk())) {
902 switch(id = iload->CurChunkID()) {
903 case MTL_HDR_CHUNK:
904 // Load the common stuff from the base class
905 res = MtlBase::Load(iload);
906 break;
907 case STUCCO_VERS1_CHUNK:
908 // Set the version number
909 fileVersion = 1;
910 break;
911 case PARAM2_CHUNK:
912 // Set the version number
913 Param1 = FALSE;
914 break;
915 case MAPOFF_CHUNK+0:
916 case MAPOFF_CHUNK+1:
917 // Set the sub-texmap on/off settings
918 mapOn[id-MAPOFF_CHUNK] = 0;
919 break;
920 }
921 iload->CloseChunk();
922 if (res != IO_OK)
923 return res;
924 }
925 // JBW: register old version ParamBlock to ParamBlock2 converter
926 ParamBlock2PLCB* plcb = new ParamBlock2PLCB(versions, 1, &stucco_param_blk, this, 1);
927 iload->RegisterPostLoadCallback(plcb);
928
929 iload->RegisterPostLoadCallback(new StuccoPostLoad(this,Param1));
930 return IO_OK;
931 }
932
933 // --- Methods inherited from ReferenceTarget ---
934 // This method is called to have the plug-in clone itself.
Clone(RemapDir & remap)935 RefTargetHandle Stucco::Clone(RemapDir &remap) {
936 // Create a new instance of the plug-in class
937 Stucco *newStucco = new Stucco();
938
939 // Copy superclass stuff
940 *((MtlBase *)newStucco) = *((MtlBase *)this);
941
942 // Clone the items we reference
943 newStucco->ReplaceReference(0, remap.CloneRef(xyzGen));
944 newStucco->ReplaceReference(1, remap.CloneRef(pblock));
945 newStucco->col[0] = col[0];
946 newStucco->col[1] = col[1];
947 newStucco->size = size;
948 newStucco->thresh = thresh;
949 newStucco->thick = thick;
950 newStucco->texValidity.SetEmpty();
951 for (int i = 0; i < NUM_SUB_TEXMAPS; i++) {
952 newStucco->subTex[i] = NULL;
953 newStucco->mapOn[i] = mapOn[i];
954 if (subTex[i])
955 newStucco->ReplaceReference(i+2, remap.CloneRef(subTex[i]));
956 }
957 BaseClone(this, newStucco, remap);
958 // Return the new cloned texture
959 return (RefTargetHandle)newStucco;
960 }
961
962 // --- Methods inherited from MtlBase ---
963 // This method is called to return the validity interval of the texmap.
Validity(TimeValue t)964 Interval Stucco::Validity(TimeValue t) {
965 Interval v;
966 // Calling Update() sets texValidity.
967 Update(t, v);
968 return texValidity;
969 }
970
971 #define IN_TO_M(x) (x / 39.370079f)
972
973 // This method is called to reset the texmap back to its default values.
Init()974 void Stucco::Init() {
975 // Reset the XYZGen or allocate a new one
976 if (xyzGen)
977 xyzGen->Reset();
978 else
979 ReplaceReference(0, GetNewDefaultXYZGen());
980
981 // Set the inital parameters
982 SetColor(0, Color(0.0f, 0.0f, 0.0f), TimeValue(0));
983 SetColor(1, Color(0.9f, 0.9f, 0.9f), TimeValue(0));
984 RegisterDistanceDefault(_T("Stucco Params"), _T("Size"), 20.0f, IN_TO_M(20.0f));
985 float size = GetDistanceDefault(_T("Stucco Params"), _T("Size"));
986 SetSize(size, TimeValue(0));
987
988 SetThresh(0.57f, TimeValue(0));
989 SetThick(0.15f, TimeValue(0));
990
991 // Set the validity interval of the texture to empty
992 texValidity.SetEmpty();
993 }
994
Reset()995 void Stucco::Reset() {
996 stuccoCD.Reset(this, TRUE); // reset all pb2's
997 DeleteReference(2);
998 DeleteReference(3);
999 Init();
1000 }
1001
Stucco()1002 Stucco::Stucco() {
1003 #ifdef SHOW_3DMAPS_WITH_2D
1004 texHandle = NULL;
1005 #endif
1006 subTex[0] = subTex[1] = NULL;
1007 pblock = NULL;
1008 xyzGen = NULL;
1009 // paramDlg = NULL;
1010 mapOn[0] = mapOn[1] = 1;
1011 stuccoCD.MakeAutoParamBlocks(this); // make and intialize paramblock2
1012 Init();
1013 fileVersion = 0;
1014 del = 0.1f; // This is a constant for now...
1015 }
1016
1017
1018 #ifdef SHOW_3DMAPS_WITH_2D
GetActiveTexHandle(TimeValue t,TexHandleMaker & thmaker)1019 DWORD_PTR Stucco::GetActiveTexHandle(TimeValue t, TexHandleMaker& thmaker) {
1020 if (texHandle) {
1021 if (texHandleValid.InInterval(t))
1022 return texHandle->GetHandle();
1023 else DiscardTexHandle();
1024 }
1025 texHandle = thmaker.MakeHandle(GetVPDisplayDIB(t,thmaker,texHandleValid));
1026 return texHandle->GetHandle();
1027 }
1028 #endif
1029
1030 // This method gets called when the material or texture is to be displayed
1031 // in the material editor parameters area.
CreateParamDlg(HWND hwMtlEdit,IMtlParams * imp)1032 ParamDlg* Stucco::CreateParamDlg(HWND hwMtlEdit, IMtlParams *imp) {
1033 // Allocate a new instance of ParamDlg to manage the UI. This will
1034 // create the rollup page in the materials editor.
1035 // StuccoDlg *stuccoDlg = new StuccoDlg(hwMtlEdit, imp, this);
1036 // Update the dialog display with the proper values of the texture.
1037 // stuccoDlg->LoadDialog();
1038 // paramDlg = stuccoDlg;
1039 // return stuccoDlg;
1040 xyzGenDlg = xyzGen->CreateParamDlg(hwMtlEdit, imp);
1041 IAutoMParamDlg* masterDlg = stuccoCD.CreateParamDlgs(hwMtlEdit, imp, this);
1042 // add the secondary dialogs to the master
1043 masterDlg->AddDlg(xyzGenDlg);
1044 stucco_param_blk.SetUserDlgProc(new StuccoDlgProc(this));
1045
1046 return masterDlg;
1047
1048
1049 }
1050
ColrFromCol24(Col24 a)1051 static Color ColrFromCol24(Col24 a) {
1052 Color c;
1053 c.r = (float)a.r/255.0f;
1054 c.g = (float)a.g/255.0f;
1055 c.b = (float)a.b/255.0f;
1056 return c;
1057 }
1058
1059
ReadSXPData(TCHAR * name,void * sxpdata)1060 void Stucco::ReadSXPData(TCHAR *name, void *sxpdata) {
1061 StuccoState *state = (StuccoState*)sxpdata;
1062 if (state!=NULL && (state->version==STUCCO_VERS)) {
1063 SetColor(0, ColrFromCol24(state->col1),0);
1064 SetColor(1, ColrFromCol24(state->col2),0);
1065 SetSize(state->size,0);
1066 SetThick(state->thickness,0);
1067 SetThresh(state->threshold,0);
1068 del = state->del;
1069 }
1070 }
1071
SetDlgThing(ParamDlg * dlg)1072 BOOL Stucco::SetDlgThing(ParamDlg* dlg)
1073 {
1074 // JBW: set the appropriate 'thing' sub-object for each
1075 // secondary dialog
1076 if ((xyzGenDlg!= NULL) && (dlg == xyzGenDlg))
1077 xyzGenDlg->SetThing(xyzGen);
1078 else
1079 return FALSE;
1080 return TRUE;
1081 }
1082
1083
1084 // This method is called before rendering begins to allow the plug-in
1085 // to evaluate anything prior to the render so it can store this information.
Update(TimeValue t,Interval & ivalid)1086 void Stucco::Update(TimeValue t, Interval& ivalid) {
1087 if (!texValidity.InInterval(t)) {
1088 texValidity.SetInfinite();
1089 xyzGen->Update(t, texValidity);
1090 // pblock->GetValue(PB_COL1, t, col[0], texValidity);
1091 pblock->GetValue(stucco_color1, t, col[0], texValidity);
1092 col[0].ClampMinMax();
1093 // pblock->GetValue(PB_COL2, t, col[1], texValidity);
1094 pblock->GetValue(stucco_color2, t, col[1], texValidity);
1095 col[1].ClampMinMax();
1096 // pblock->GetValue(PB_SIZE, t, size, texValidity);
1097 pblock->GetValue(stucco_size, t, size, texValidity);
1098 ClampFloat(size, MIN_SIZE, MAX_SIZE);
1099 // pblock->GetValue(PB_THRESH, t, thresh, texValidity);
1100 pblock->GetValue(stucco_threshold, t, thresh, texValidity);
1101 ClampFloat(thresh, MIN_THRESH, MAX_THRESH);
1102 // pblock->GetValue(PB_THICK, t, thick, texValidity);
1103 pblock->GetValue(stucco_thickness, t, thick, texValidity);
1104 pblock->GetValue(stucco_mapon1, t, mapOn[0], texValidity);
1105 pblock->GetValue(stucco_mapon2, t, mapOn[1], texValidity);
1106 ClampFloat(thick, MIN_THICK, MAX_THICK);
1107 for (int i = 0; i < NUM_SUB_TEXMAPS; i++) {
1108 if (subTex[i])
1109 subTex[i]->Update(t, texValidity);
1110 }
1111 }
1112 ivalid &= texValidity;
1113 }
1114
ClampFloat(float & f,float min,float max)1115 void Stucco::ClampFloat(float &f, float min, float max) {
1116 if (f < min) f = min;
1117 else if (f > max) f = max;
1118 }
1119
1120 // Returns a pointer to the 'i-th' sub-texmap managed by this texture.
GetSubTexmap(int i)1121 Texmap *Stucco::GetSubTexmap(int i) {
1122 return subTex[i];
1123 }
1124
1125 // Stores the 'i-th' sub-texmap managed by the material or texture.
SetSubTexmap(int i,Texmap * m)1126 void Stucco::SetSubTexmap(int i, Texmap *m) {
1127 ReplaceReference(i+2, m);
1128 if (i==0)
1129 {
1130 stucco_param_blk.InvalidateUI(stucco_map1);
1131 texValidity.SetEmpty();
1132 }
1133 else if (i==1)
1134 {
1135 stucco_param_blk.InvalidateUI(stucco_map2);
1136 texValidity.SetEmpty();
1137 }
1138
1139 // if (paramDlg)
1140 // paramDlg->UpdateSubTexNames();
1141 }
1142
1143 // This name appears in the materials editor dialog when editing the
1144 // 'i-th' sub-map.
GetSubTexmapSlotName(int i)1145 TSTR Stucco::GetSubTexmapSlotName(int i) {
1146 switch(i) {
1147 case 0: return GetString(IDS_DS_COL1);
1148 case 1: return GetString(IDS_DS_COL2);
1149 default: return TSTR(_T(""));
1150 }
1151 }
1152
1153
compscl(Point3 dp,float size)1154 static float compscl(Point3 dp, float size) {
1155 float f;
1156 float scl = (float)fabs(dp.x);
1157 if ((f = (float)fabs(dp.y)) > scl)
1158 scl = f;
1159 if ((f = (float)fabs(dp.z)) > scl)
1160 scl = f;
1161 scl /= size;
1162 return scl;
1163 }
1164
1165 #define CRV (.2)
1166 #define K (.5/(1-CRV))
1167 #define K1 (K/CRV)
1168
1169 /*
1170 STUCCO function
1171
1172 works off a noise function 'f'in range [0..1.0]
1173
1174 when f<=threshold returns 0.0;
1175
1176 state.thickness is the fraction of the remaining interval [thresh..1.0]
1177 taken up by a transition from 0 to 1.0;
1178 Over this interval, a 2nd order curve (piecewise parabolic) is used.
1179 over the first CRV part of the transition its parablolic, then for
1180 the next 1-2*CRV part its linear, then for the last CRV part it's
1181 an inverted parabola.
1182 -------------------------------------------------------
1183 */
Func(Point3 p,float scl)1184 float Stucco::Func(Point3 p, float scl) {
1185 float f,t;
1186 f = 0.5f*(noise3(p)+1.0f); /* get number from 0 to 1.0 */
1187
1188 if (f <= thresh)
1189 return(float) 0.0f;
1190 t = thick+0.5f*scl;
1191 f = (f-thresh)/t;
1192 if (f >= 1.0f)
1193 return (float) (1.0f);
1194 if (f < CRV) {
1195 return (float) (K1*f*f);
1196 }
1197 else
1198 if (f < (1.0f-CRV)) {
1199 return (float) (K*((2.0f*f)-CRV));
1200 }
1201 else {
1202 f = 1.0f-f;
1203 return (float) (1.0f - K1*(f*f));
1204 }
1205 }
1206
EvalFunc(ShadeContext & sc)1207 float Stucco::EvalFunc(ShadeContext &sc) {
1208 Point3 p, dp;
1209 xyzGen->GetXYZ(sc, p, dp);
1210 if (size == 0.0f)
1211 size = 0.0001f;
1212 p /= size;
1213 float scl = compscl(dp, size);
1214 return Func(p, scl);
1215 }
1216
1217 // --- Methods inherited from Texmap ---
EvalColor(ShadeContext & sc)1218 RGBA Stucco::EvalColor(ShadeContext& sc) {
1219 float f;
1220 Point3 p, dp;
1221
1222 if (gbufID)
1223 sc.SetGBufferID(gbufID);
1224
1225 xyzGen->GetXYZ(sc, p, dp);
1226
1227 if (size == 0.0f)
1228 size = 0.0001f;
1229 p /= size;
1230
1231 float scl = compscl(dp, size);
1232 f = Func(p, scl);
1233
1234 // If we have sub-texmaps and they are enabled, get the colors from
1235 // the sub-texmaps, otherwise get them from the color swatch
1236 RGBA c0 = (mapOn[0]&&subTex[0]) ? subTex[0]->EvalColor(sc): col[0];
1237 RGBA c1 = (mapOn[1]&&subTex[1]) ? subTex[1]->EvalColor(sc): col[1];
1238
1239 Col24 c;
1240 Col24 col1 = Col24FromColor(c0);
1241 Col24 col2 = Col24FromColor(c1);
1242
1243 lerp_color(&c, &col1, &col2, f);
1244 return ColorFromCol24(c);
1245 }
1246
EvalNormalPerturb(ShadeContext & sc)1247 Point3 Stucco::EvalNormalPerturb(ShadeContext& sc) {
1248 float d,k;
1249 Point3 p, dp, np;
1250
1251 if (gbufID)
1252 sc.SetGBufferID(gbufID);
1253
1254 xyzGen->GetXYZ(sc, p, dp);
1255
1256 float scl = compscl(dp, size);
1257 p /= size;
1258 d = Func(p, scl);
1259 k = 0.25f/del;
1260
1261 Point3 M[3];
1262 xyzGen->GetBumpDP(sc,M);
1263 np.x = (Func(p + del*M[0], scl) - d)*k;
1264 np.y = (Func(p + del*M[1], scl) - d)*k;
1265 np.z = (Func(p + del*M[2], scl) - d)*k;
1266 np = sc.VectorFromNoScale(np,REF_OBJECT);
1267
1268 Texmap *sub0 = mapOn[0]?subTex[0]:NULL;
1269 Texmap *sub1 = mapOn[1]?subTex[1]:NULL;
1270 if (sub0||sub1) {
1271 // d((1-k)*a + k*b ) = dk*(b-a) + k*(db-da) + da
1272 float a,b;
1273 Point3 da,db;
1274 if (sub0) {
1275 a = sub0->EvalMono(sc);
1276 da = sub0->EvalNormalPerturb(sc);
1277 }
1278 else {
1279 a = Intens(col[0]);
1280 da = Point3(0.0f,0.0f,0.0f);
1281 }
1282 if (sub1) {
1283 b = sub1->EvalMono(sc);
1284 db = sub1->EvalNormalPerturb(sc);
1285 }
1286 else {
1287 b = Intens(col[1]);
1288 db= Point3(0.0f,0.0f,0.0f);
1289 }
1290 np = (b-a)*np + d*(db-da) + da;
1291 }
1292 else
1293 np *= Intens(col[1])-Intens(col[0]);
1294 return np;
1295 }
1296
1297 // --- Methods of Stucco ---
NotifyChanged()1298 void Stucco::NotifyChanged() {
1299 NotifyDependents(FOREVER, PART_ALL, REFMSG_CHANGE);
1300 }
1301
SwapInputs()1302 void Stucco::SwapInputs() {
1303 Color t = col[0]; col[0] = col[1]; col[1] = t;
1304 Texmap *x = subTex[0]; subTex[0] = subTex[1]; subTex[1] = x;
1305 // pblock->SwapControllers(PB_COL1, PB_COL2);
1306 pblock->SwapControllers(stucco_color1,0, stucco_color2,0);
1307 stucco_param_blk.InvalidateUI(stucco_color1);
1308 stucco_param_blk.InvalidateUI(stucco_color2);
1309 stucco_param_blk.InvalidateUI(stucco_map1);
1310 stucco_param_blk.InvalidateUI(stucco_map2);
1311 macroRec->FunctionCall(_T("swap"), 2, 0, mr_prop, _T("color1"), mr_reftarg, this, mr_prop, _T("color2"), mr_reftarg, this);
1312 macroRec->FunctionCall(_T("swap"), 2, 0, mr_prop, _T("map1"), mr_reftarg, this, mr_prop, _T("map2"), mr_reftarg, this);
1313 }
1314
SetColor(int i,Color c,TimeValue t)1315 void Stucco::SetColor(int i, Color c, TimeValue t) {
1316 col[i] = c;
1317 // pblock->SetValue((i == 0) ? PB_COL1 : PB_COL2, t, c);
1318 pblock->SetValue((i == 0) ? stucco_color1 : stucco_color2, t, c);
1319 }
1320
SetThick(float f,TimeValue t)1321 void Stucco::SetThick(float f, TimeValue t) {
1322 thick = f;
1323 // pblock->SetValue(PB_THICK, t, f);
1324 pblock->SetValue(stucco_thickness, t, f);
1325 }
1326
SetThresh(float f,TimeValue t)1327 void Stucco::SetThresh(float f, TimeValue t) {
1328 thresh = f;
1329 // pblock->SetValue(PB_THRESH, t, f);
1330 pblock->SetValue(stucco_threshold, t, f);
1331 }
1332
SetSize(float f,TimeValue t)1333 void Stucco::SetSize(float f, TimeValue t) {
1334 size = f;
1335 // pblock->SetValue(PB_SIZE, t, f);
1336 pblock->SetValue(stucco_size, t, f);
1337 }
1338
1339