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 |
|
---|
22 | m1_mail_slot_class slot;
|
---|
23 |
|
---|
24 | HINSTANCE my_instance;
|
---|
25 | int 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 |
|
---|
39 | int m1_cur_trans=31;
|
---|
40 |
|
---|
41 | class m1_utility_class : public UtilityObj
|
---|
42 | {
|
---|
43 | protected:
|
---|
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);
|
---|
119 | public:
|
---|
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 | };
|
---|
184 | static m1_utility_class m1_utility;
|
---|
185 |
|
---|
186 | class m1_utility_descriptor_class : public ClassDesc
|
---|
187 | {
|
---|
188 | public:
|
---|
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 | };
|
---|
196 | static m1_utility_descriptor_class m1_utility_descriptor;
|
---|
197 | ClassDesc* GetCrackUtilDesc() {return &m1_utility_descriptor;}
|
---|
198 |
|
---|
199 | i4_bool accel_disabled=i4_F;
|
---|
200 | HWND dlg_wnd;
|
---|
201 |
|
---|
202 | static 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 |
|
---|
293 | m1_utility_class::m1_utility_class()
|
---|
294 | {
|
---|
295 | }
|
---|
296 |
|
---|
297 |
|
---|
298 | void 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 |
|
---|
310 | void 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 |
|
---|
319 | void m1_utility_class::Init(HWND hWnd)
|
---|
320 | {
|
---|
321 | max_obj = 0;
|
---|
322 |
|
---|
323 | initialize_i4();
|
---|
324 | }
|
---|
325 |
|
---|
326 |
|
---|
327 | void m1_utility_class::Destroy(HWND hWnd)
|
---|
328 | {
|
---|
329 | // clean_objects();
|
---|
330 | }
|
---|
331 |
|
---|
332 |
|
---|
333 | char *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 |
|
---|
385 | int 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 |
|
---|
400 | void 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 |
|
---|
642 | void 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 |
|
---|
711 | void 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 |
|
---|
755 | void 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 |
|
---|
764 | void 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 |
|
---|
800 | void 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 |
|
---|
842 | void 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 |
|
---|
849 | void 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 |
|
---|