source: golgotha/src/max_plugin/util.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 14 years ago
  • Adding the Golgotha source code. Not sure what's going to be interesting in there, but since it's all public domain, there's certainly stuff to pick up.
File size: 20.8 KB
Line 
1/********************************************************************** <BR>
2  This file is part of Crack dot Com's free source code release of
3  Golgotha. <a href="http://www.crack.com/golgotha_release"> <BR> for
4  information about compiling & licensing issues visit this URL</a>
5  <PRE> If that doesn't help, contact Jonathan Clark at
6  golgotha_source@usa.net (Subject should have "GOLG" in it)
7***********************************************************************/
8
9#include <windows.h>
10#include "crkutil.hh"
11#include "obj3d.hh"
12#include <utilapi.h>
13#include <stdmat.h>
14#include <stdio.h>
15#include "maxcomm.hh"
16#include "file/file.hh"
17#include "string/string.hh"
18#include "max_object.hh"
19#include "memory/array.hh"
20#include "debug.hh"
21
22m1_mail_slot_class slot;
23
24HINSTANCE my_instance;
25int       my_nCmdShow;
26 
27
28#define G3DF_VERSION 3
29
30#define MAXANIMATIONS 2
31#define MAXFRAMES     300
32#define MAXVERT       100
33#define MAXTOTALVERT  (MAXFRAMES*MAXVERT)
34#define MAXCOUNTS     10000
35#define MAXQUAD       150
36
37#define UTILTEST_CLASS_ID   0x99bb61a5
38
39int m1_cur_trans=31;
40
41class m1_utility_class : public UtilityObj
42{
43protected:
44  class property_modifier
45  {
46    class prop_list
47    {
48    public:
49      int rotation,flip,reverse,trans,tint;
50
51      prop_list() : rotation(0), flip(0), reverse(0), trans(31) {}
52    };
53 
54  protected:
55    void modify_node(INode *node);
56  public:
57    void modify_selected(Interface *ip);
58
59    virtual void modify(prop_list &p) = 0;
60  };
61 
62  class rotate_left_modifier : public property_modifier
63  {
64  public:
65    virtual void modify(prop_list &p)
66    {
67      p.rotation = (p.rotation+11)%12;
68    }
69  };
70  class rotate_right_modifier : public property_modifier
71  {
72  public:
73    virtual void modify(prop_list &p)
74    {
75      p.rotation = (p.rotation+1)%12;
76    }
77  };
78  class flip_normal_modifier : public property_modifier
79  {
80  public:
81    virtual void modify(prop_list &p)
82    {
83      p.flip = !p.flip;
84    }
85  };
86  class reverse_texture_modifier : public property_modifier
87  {
88  public:
89    virtual void modify(prop_list &p)
90    {
91      p.reverse = !p.reverse;
92    }
93  };
94
95  class tint_texture_modifier : public property_modifier
96  {
97  public:
98    virtual void modify(prop_list &p)
99    {
100      p.tint = !p.tint;
101    }
102  };
103
104
105  class set_trans_texture_modifier : public property_modifier
106  {
107  public:
108    virtual void modify(prop_list &p)
109    {
110      p.trans=m1_cur_trans;
111    }
112  };
113 
114  char *set_g1_name(char *dest, char *name);
115
116  int add_vert(i4_array<g1_vert_class> &vert_list,
117               w32 vert_start,
118               g1_vert_class &vt);
119public:
120  IUtil *iu;
121  TimeValue time;
122  Interface *ip;
123  HWND hPanel;
124  //  HWND hwnd;
125
126  m1_poly_object_class *max_obj;
127
128  m1_utility_class();
129  void BeginEditParams(Interface *ip,IUtil *iu);
130  void EndEditParams(Interface *ip,IUtil *iu);
131  void DeleteThis() {}
132
133  void Init(HWND hWnd);
134  void Destroy(HWND hWnd);
135
136  void create_objects();
137  void grab_model_instance(int level, INode *node,
138                           m1_poly_object_class *o,
139                           w16 anim, w16 frame);
140  void grab_model_instance2(int level, INode *node,
141                            m1_poly_object_class *o,
142                            w16 anim, w16 frame);
143
144  void clean_objects();
145
146  void restart_fly();
147  void render();
148  void rotate_selected_left()
149  {
150    rotate_left_modifier tmp;
151    tmp.modify_selected(ip);
152  }
153  void rotate_selected_right()
154  {
155    rotate_right_modifier tmp;
156    tmp.modify_selected(ip);
157  }
158  void tint_toggle()
159  {
160    tint_texture_modifier tmp;
161    tmp.modify_selected(ip);
162  }
163
164  void flip_normal()
165  {
166    flip_normal_modifier tmp;
167    tmp.modify_selected(ip);
168  }
169  void reverse_texture()
170  {
171    reverse_texture_modifier tmp;
172    tmp.modify_selected(ip);
173  }
174  void set_trans()
175  {
176    if (m1_cur_trans>=1 && m1_cur_trans<=31)
177    {     
178      set_trans_texture_modifier tmp;
179      tmp.modify_selected(ip);
180    }
181  }
182
183};
184static m1_utility_class m1_utility;
185
186class m1_utility_descriptor_class : public ClassDesc
187{
188public:
189  int           IsPublic()     {return 1;}
190  void *        Create(BOOL loading = FALSE) {return &m1_utility;}
191  const TCHAR * ClassName()    {return _T("Crack Utilities");}
192  SClass_ID     SuperClassID() {return UTILITY_CLASS_ID;}
193  Class_ID      ClassID()      { return Class_ID(0x34713748, 0x5b4c1417); }
194  const TCHAR*  Category()     {return _T("");}
195};
196static m1_utility_descriptor_class m1_utility_descriptor;
197ClassDesc* GetCrackUtilDesc() {return &m1_utility_descriptor;}
198
199i4_bool accel_disabled=i4_F;
200HWND dlg_wnd;
201
202static BOOL CALLBACK UtilTestDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
203{
204  switch (msg)
205  {
206    case WM_INITDIALOG:
207      dlg_wnd=hWnd;
208      m1_utility.Init(hWnd);     
209      SetFocus(hWnd);
210      return FALSE;
211      break;
212   
213    case WM_DESTROY:
214      m1_utility.Destroy(hWnd);
215      break;
216
217    case WM_KILLFOCUS :
218    {
219      if (accel_disabled)
220      {
221        accel_disabled=i4_F;
222        EnableAccelerators();
223      }
224    } break;
225
226    case WM_COMMAND:
227      switch (LOWORD(wParam))
228      {
229        case 0x3f6 :  // not sure what command this is, but it works.. :) jc
230        {
231          if (!accel_disabled)
232          {
233            accel_disabled=i4_T;
234            DisableAccelerators();  // turn 3ds's keyboard accelerators so we can type text
235          }
236          else
237          {
238            accel_disabled=i4_F;
239            EnableAccelerators();  // turn on the accels
240          }
241
242          return FALSE;
243        } break;
244
245        case IDC_CRKUTIL_APPLY :
246        {
247          char buf[100];
248          GetDlgItemText(hWnd, IDC_CRKUTIL_EDIT, buf, 99);
249          m1_cur_trans=atoi(buf);
250          m1_utility.set_trans();
251        } break;
252
253        case IDC_CRACKUTIL_RENDER:
254          m1_utility.render();
255          break;
256
257
258        case IDC_CRACKUTIL_ROTLEFT:
259          m1_utility.rotate_selected_left();
260          break;
261
262        case IDC_CRACKUTIL_ROTRIGHT:
263          m1_utility.rotate_selected_right();
264          break;
265
266        case IDC_CRACKUTIL_FLIP:
267          m1_utility.flip_normal();
268          break;
269
270        case IDC_CRKUTIL_TINT:
271          m1_utility.tint_toggle();
272          break;
273
274        case IDC_CRACKUTIL_REVERSE:
275          m1_utility.reverse_texture();
276          break;
277      }
278      break;
279
280    case WM_LBUTTONDOWN :
281    case WM_LBUTTONUP:
282    case WM_MOUSEMOVE:
283      m1_utility.ip->RollupMouseMessage(hWnd,msg,wParam,lParam);
284      break;
285
286    default:
287      return FALSE;
288  }
289  return TRUE;
290}
291
292
293m1_utility_class::m1_utility_class()
294{
295}
296
297
298void m1_utility_class::BeginEditParams(Interface *_ip,IUtil *_iu)
299{
300  iu = _iu;
301  ip = _ip;
302  hPanel = ip->AddRollupPage(my_instance,
303                             MAKEINTRESOURCE(IDD_CRACKUTIL),
304                             (DLGPROC)UtilTestDlgProc,
305                             _T("Golgotha Utilities"),
306                             0);
307}
308
309
310void m1_utility_class::EndEditParams(Interface *_ip,IUtil *_iu)
311{
312  iu = NULL;
313  ip = NULL;
314  _ip->DeleteRollupPage(hPanel);
315  hPanel = NULL;
316}
317
318
319void m1_utility_class::Init(HWND hWnd)
320{
321  max_obj = 0;
322
323  initialize_i4();
324}
325
326
327void m1_utility_class::Destroy(HWND hWnd)
328{
329  //  clean_objects();
330}
331
332
333char *m1_utility_class::set_g1_name(char *dest, char *name)
334{
335  char s[256];
336#if 0
337  static char *remap[][2] =
338  {
339    {"f:/", "/u/"},
340    {"//alpha1/", "/u/"},
341    { 0, 0 }
342  };
343#endif
344
345  char *p,*q;
346
347  p = name;
348  q = s;
349  while (*p)
350  {
351    if (*p == '\\')
352      *q = '/';
353    else if (*p>='A' && *p<='Z')
354      *q = *p + 'a' - 'A';
355    else
356      *q = *p;
357
358    ++p;
359    ++q;
360  }
361  *q = 0;
362
363  p = s;
364  q = dest;
365#if 0
366  for (int i=0; remap[i][0]; i++)
367  {
368    int len = strlen(remap[i][0]);
369
370    if (strncmp(p, remap[i][0], len) == 0)
371    {
372      p += len;
373      strcpy(q, remap[i][1]);
374      q += strlen(q);
375    }
376  }
377#endif
378
379  strcpy(q,p);
380
381  return dest;
382}
383
384
385int m1_utility_class::add_vert(i4_array<g1_vert_class> &vert_list,
386                               w32 vert_start,
387                               g1_vert_class &vt)
388{
389  float E_DELTA=0.001;
390  for (int i=vert_start; i<vert_list.size(); i++)
391    if (fabs(vt.v.x-vert_list[i].v.x)<E_DELTA &&
392        fabs(vt.v.y-vert_list[i].v.y)<E_DELTA &&
393        fabs(vt.v.z-vert_list[i].v.z)<E_DELTA)     
394      return i;
395
396  vert_list.add(vt);
397  return vert_list.size()-1;
398}
399
400void m1_utility_class::grab_model_instance2(int level,
401                                            INode *node,
402                                            m1_poly_object_class *max_obj,
403                                            w16 anim, w16 frame)
404{
405  dbg("grab2\n");
406
407  w32 vert_start = 0;
408
409  int quad_offset = max_obj->quad_a.size();
410
411  TSTR str;
412  char *mat_name[1024], *mat_uv[1024];
413  int mat_size=0;
414
415  char *name = node->GetName();
416
417  node->GetUserPropBuffer(str);
418  char *p = str;
419
420  if (strncmp(p, gmod_sig, strlen(gmod_sig))==0)
421  {
422    // skip first signature line
423    while (*p && *p!='\n') p++;
424    if (*p) p++;
425   
426    dbg("previously assigned polygon parameters\n");
427   
428    char *mat, *uv;
429    while (*p)
430    {
431      max_obj->quad_a.add(0);
432      mat = p+1;
433
434      while (*p && *p!='\n' && *p!=' ') p++;
435      if (*p==' ')
436      {
437        // tokenize all the texture names
438        *p = 0;
439        p++;
440        uv = p;
441      }
442      while (*p && *p!='\n') p++;
443      if (*p=='\n')
444      {
445        // tokenize UV stuff
446        *p = 0;
447        p++;
448      }
449
450      mat_name[mat_size] = mat;
451      mat_uv[mat_size] = uv;
452      mat_size++;
453    }
454
455    dbg("grabbed %d polygon materials\n", mat_size);
456  }
457
458  // Get base state of object
459  Object *obj = node->EvalWorldState(0).obj;
460  if (!obj)
461  {
462    // do nothing
463  }
464  else if (obj->ClassID() == Class_ID(POINTHELP_CLASS_ID,0))
465  {
466    Matrix3 tm = node->GetObjectTM(time);
467    Point3 o(0,0,0),v;
468    v = o * tm;
469
470    max_obj->mount_a.add(new m1_mount_point_class(new i4_str(name),
471                                                  i4_3d_vector(v.x, v.y, v.z)));
472  }
473  else if (obj->CanConvertToType(triObjectClassID))
474  {
475    TriObject *tri = (TriObject *)obj->ConvertToType(time, triObjectClassID);
476    Mesh &mesh = tri->mesh;
477    Matrix3 tm = node->GetObjectTM(time);
478    w16 vert_id[1024];
479    int i,j;
480
481    int verts = mesh.getNumVerts();
482    // Add vertexes to object
483    dbg("getting %d verts\n", verts);
484
485    for(i=0; i<verts; ++i)
486    {
487      Point3 v = mesh.verts[i] * tm;
488      g1_vert_class vt;
489      vt.v.x = v.x;
490      vt.v.y = v.y;
491      vt.v.z = v.z;
492      vert_id[i] = add_vert(max_obj->anim_a[anim]->vertex_a, vert_start, vt);
493    }
494   
495    int faces = mesh.getNumFaces();
496    dbg("getting %d faces\n", faces);
497    for (i=0; i<faces; i++)
498    {
499      Face face = mesh.faces[i];
500      w16 tri[3];
501      int found, textured=0;
502
503      // find index of missing edge
504      found = -1;
505      for (j=0; j<3 && found<0; j++)
506        if (!face.getEdgeVis(j))
507          found = j;
508
509      dbg("%s(%+1d) ", found>=0? "Quad":"Tri ", found);
510
511      // order vertex from missing edge
512      tri[0] = vert_id[face.v[(found+1)%3]];
513      tri[1] = vert_id[face.v[(found+2)%3]];
514      tri[2] = vert_id[face.v[(found+3)%3]];
515
516      if (tri[0]==tri[1] || tri[0]==tri[2] || tri[1]==tri[2])
517      {
518        dbg("Malformed!\n");
519        continue;
520      }
521
522      if (found>=0)
523      {
524        // this is part of a quad
525
526        // search for matching triangle
527        found=-1;
528        for (j=quad_offset; j<max_obj->quad_a.size() && found<0; j++)
529        {
530          if (max_obj->quad_a[j] &&
531              max_obj->quad_a[j]->vertex_ref[0] == tri[2] &&
532              max_obj->quad_a[j]->vertex_ref[2] == tri[0])
533            found = j;
534        }
535
536        if (found>=0)
537        {
538          m1_quad_class *q = max_obj->quad_a[found];
539
540          dbg("Part of %d, added [%d]", found, tri[1]);
541          // found other half.  add the remaining vertex
542          q->vertex_ref[3] = tri[1];
543          q->calc_texture_scale(max_obj->anim_a[anim]->vertex_a, vert_start);
544        }
545      }
546
547      if (found<0)
548      {
549        dbg("Unallocated ");
550
551        // need to add this triangle
552        m1_quad_class *q = new m1_quad_class(tri[0], tri[1], tri[2]);
553
554        dbg("Created [%d, %d, %d]", tri[0], tri[1], tri[2]);
555
556        if (face.getMatID()>=MAX_MATERIAL_OFFSET)
557        {
558          // has a preassigned material id?
559          found = face.getMatID() - MAX_MATERIAL_OFFSET;
560          if (found>=mat_size)
561          {
562            dbg("Missing Material ");
563            found = -1;
564          }
565          else
566          {
567            if (!max_obj->quad_a[found+quad_offset])
568            {
569              dbg("Preassigned at %d ", found);
570              max_obj->quad_a[found+quad_offset] = q;
571            }
572            else
573            {
574              dbg("Repeated ");
575              // a repeat id, assume the latter ones are wrong.
576              //              found = -1;
577            }
578           
579            q->set_texture(mat_name[found]);
580
581            sscanf(mat_uv[found],"%f %f %f %f %f %f %f %f",
582                   &q->u[0],&q->v[0],&q->u[1],&q->v[1],&q->u[2],&q->v[2],&q->u[3],&q->v[3]);
583           
584            dbg(" = [%s] <%f,%f> <%f,%f> <%f,%f> <%f,%f>",
585                q->texture_name,
586                q->u[0],q->v[0],q->u[1],q->v[1],q->u[2],q->v[2],q->u[3],q->v[3]);
587           
588            q->calc_texture_scale(max_obj->anim_a[anim]->vertex_a, vert_start);
589            textured = 1;
590          }
591        }
592
593        if (!textured)
594        {
595          q->set_texture("");
596          q->u[0] = 0.0; q->v[0] = 0.0;
597          q->u[1] = 1.0; q->v[1] = 0.0;
598          q->u[2] = 1.0; q->v[2] = 1.0;
599          q->u[3] = 0.0; q->v[3] = 1.0;
600          q->calc_texture_scale(max_obj->anim_a[anim]->vertex_a,vert_start);
601        }
602       
603        if (found<0)
604        {
605          dbg("New ");
606          // add in a new quad
607          found = max_obj->quad_a.add(q);
608          dbg("at %d", found);
609        }
610      }
611      dbg("\n");
612    }
613
614    // compact quad array
615    i=quad_offset;
616    while (i<max_obj->quad_a.size())
617      if (max_obj->quad_a[i])
618        i++;
619      else
620        max_obj->quad_a.remove(i);
621
622    if (max_obj->quad_a.size()-quad_offset==1 && mat_size==0)
623      // assume old style poly
624      grab_model_instance(level, node, max_obj, anim, frame);
625
626    dbg("Final Quads %d\n", max_obj->quad_a.size());
627
628    // Delete the working object, if necessary
629    if(obj != (Object *)tri)
630      tri->DeleteThis();
631  }
632
633  // Dump children info
634  for (int i=0; i<node->NumberOfChildren(); i++)
635    grab_model_instance2(level+1,
636                         node->GetChildNode(i),
637                         max_obj, anim, frame);
638
639  dbg("Got the model!  Yes!\n");
640}
641
642void m1_utility_class::grab_model_instance(int level,
643                                           INode *node,
644                                           m1_poly_object_class *max_obj,
645                                           w16 anim, w16 frame)
646{
647  w32 vert_start = 0;
648
649  char st[256],matname[256];
650
651  memset(st,' ',level*2);
652  st[level*2] = 0;
653  strcat(st,node->GetName());
654  dbg("%-40s", st);
655
656  matname[0] = 0;
657
658  // Get material
659  Mtl *mat = node->GetMtl();
660
661  if (mat)
662  {
663    // Check for a diffuse bitmap as real texture name
664    if (mat->NumSubTexmaps())
665    {
666      Texmap *tex = mat->GetSubTexmap(ID_DI);
667
668      if (tex && tex->ClassID()==Class_ID(BMTEX_CLASS_ID,0))
669      {
670        BitmapTex *bmt = (BitmapTex*)tex;
671        set_g1_name(matname,bmt->GetMapName());
672      }
673    }
674  }
675
676  m1_quad_class *q = max_obj->quad_a[max_obj->quad_a.size()-1];
677
678  int quad_off=0,flip=0,reverse=0,trans=31,tint=0;
679  TSTR tst;
680 
681  node->GetUserPropBuffer(tst);
682  sscanf(tst,"%d %d %d %d %d",&quad_off,&flip,&reverse,&trans,&tint);
683 
684  w16 quad[4];
685  quad[0] = q->vertex_ref[0];
686  quad[1] = q->vertex_ref[1];
687  quad[2] = q->vertex_ref[2];
688  quad[3] = q->vertex_ref[3];
689
690  // Add quad to object
691  if (q->num_verts()==4)
692    if (!flip)
693      q->set(quad[(0+quad_off)%4],quad[(3+quad_off)%4],quad[(2+quad_off)%4],quad[(1+quad_off)%4]);
694    else
695      q->set(quad[(0+quad_off)%4],quad[(1+quad_off)%4],quad[(2+quad_off)%4],quad[(3+quad_off)%4]);
696  else
697    if (!flip)
698      q->set(quad[(0+quad_off)%3],quad[(2+quad_off)%3],quad[(1+quad_off)%3]);
699    else
700      q->set(quad[(0+quad_off)%3],quad[(1+quad_off)%3],quad[(2+quad_off)%3]);
701 
702  q->calc_texture(reverse,max_obj->anim_a[anim]->vertex_a,vert_start,matname);
703 
704  q->set_flags(g1_quad_class::TINT, tint?g1_quad_class::TINT:0);
705  q->set_flags(g1_quad_class::TRANSLUCENCY, trans);
706 
707  dbg("\n");
708}
709
710
711void m1_utility_class::create_objects()
712//Note:
713//  Normally, root level groups are separate objects
714//  For now, the whole scene is one object
715{
716  int i;
717
718  dbg.restart();
719
720  if (max_obj)
721    delete max_obj;
722
723  max_obj = new m1_poly_object_class;
724
725  time = ip->GetTime();
726 
727  Interval interval = ip->GetAnimRange();
728 
729  for (time=interval.Start(); time<interval.End(); time+=160)
730  {
731
732    if (time==interval.Start())
733    {             
734      max_obj->anim_a.add(new m1_animation_class(i4gets("default_animation_name")));     
735      grab_model_instance2(0,
736                           ip->GetRootNode(),
737                           max_obj, 0 ,0);
738      max_obj->num_vertex=max_obj->anim_a[0]->vertex_a.size();
739    }
740    else if (IsDlgButtonChecked(dlg_wnd, IDC_CRKUTIL_ANIM))
741    {
742      i4_array<m1_quad_class *> quad_list(100,100);
743
744      grab_model_instance2(0,
745                           ip->GetRootNode(),
746                           max_obj, 0, 0);
747
748      for (i=0; i<quad_list.size(); i++)
749        delete quad_list[i];
750    }
751  }
752}
753
754
755void m1_utility_class::clean_objects()
756{
757  if (max_obj)
758    delete max_obj;
759  dbg("Zapped\n");
760  max_obj = 0;
761}
762
763
764void m1_utility_class::restart_fly()
765{
766  if (!slot.open(i4gets("slot_name")))
767  {
768//     PROCESS_INFORMATION piProcInfo;
769//     STARTUPINFO siStartInfo;
770   
771//     /* Set up members of STARTUPINFO structure. */
772   
773//     siStartInfo.cb = sizeof(STARTUPINFO);
774//     siStartInfo.lpReserved = NULL;
775//     siStartInfo.lpReserved2 = NULL;
776//     siStartInfo.cbReserved2 = 0;
777//     siStartInfo.lpDesktop = NULL;
778//     siStartInfo.dwFlags = 0;
779   
780//     /* Create the child process. */
781   
782//     CreateProcess(NULL,
783//                   "f:\\crack\\maxtool\\maxtool.exe",   /* command line                       */
784//                   NULL,          /* process security attributes        */
785//                   NULL,          /* primary thread security attributes */
786//                   TRUE,          /* handles are inherited              */
787//                   0,             /* creation flags                     */
788//                   NULL,          /* use parent's environment           */
789//                   NULL,          /* use parent's current directory     */
790//                   &siStartInfo,  /* STARTUPINFO pointer                */
791//                   &piProcInfo);  /* receives PROCESS_INFORMATION       */
792
793//     Sleep(1000);
794
795    slot.open(i4gets("slot_name"));
796  }
797}
798
799
800void m1_utility_class::render()
801{
802  dbg("Create Objects\n");
803  create_objects();
804  if (max_obj->quad_a.size() && max_obj->num_vertex)
805  {
806    dbg("Save Objects\n");
807    i4_file_class *f = i4_open(i4gets("fly_name"),I4_WRITE);
808    i4_saver_class *g1_saver=new i4_saver_class(f);
809
810    if (f)
811    {
812      max_obj->save(g1_saver);
813      g1_saver->begin_data_write();
814      max_obj->save(g1_saver);
815      delete g1_saver;
816    }
817
818    if (!slot.initialized())
819      restart_fly();
820
821    char *name;
822
823    if (slot.initialized())
824    {
825      dbg("Contacting maxtool\n");
826      char buf[256];
827      name = i4_os_string(i4gets("fly_name"),buf, sizeof(buf));
828      if (slot.write(name, strlen(name) + 1) == 0)
829      {
830        restart_fly();
831        name = i4_os_string(i4gets("fly_name"),buf, sizeof(buf));
832        slot.write(name, strlen(name) + 1);
833      }
834    }
835  }
836  dbg("Cleaning up!\n");
837  clean_objects();
838  dbg("Done!\n");
839}
840
841
842void m1_utility_class::property_modifier::modify_selected(Interface *ip)
843{
844  for (int i=0; i<ip->GetSelNodeCount(); i++)
845    modify_node(ip->GetSelNode(i));
846}
847
848
849void m1_utility_class::property_modifier::modify_node(INode *node)
850{
851  prop_list p;
852  TSTR tst;
853  char str[1024];
854
855  node->GetUserPropBuffer(tst);
856  sscanf(tst,"%d %d %d %d %d",&p.rotation, &p.flip, &p.reverse, &p.trans, &p.tint);
857 
858  modify(p);
859
860  sprintf(str,"%d %d %d %d %d",p.rotation, p.flip, p.reverse, p.trans, p.tint);
861  node->SetUserPropBuffer(TSTR(str));
862}
863
864
Note: See TracBrowser for help on using the repository browser.