source: golgotha/src/maxtool/render.cc @ 80

Last change on this file since 80 was 80, checked in by Sam Hocevar, 12 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: 22.7 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 "render.hh"
10#include "error/error.hh"
11#include "time/timedev.hh"
12#include "math/pi.hh"
13#include "window/win_evt.hh"
14#include "window/colorwin.hh"
15#include "max_object.hh"
16#include "gui/button.hh"
17#include "gui/text.hh"
18#include "loaders/load.hh"
19#include "device/keys.hh"
20#include "image/color.hh"
21#include "error/alert.hh"
22#include "obj3d.hh"
23#include "tmanage.hh"
24#include "loaders/dir_load.hh"
25#include "saver_id.hh"
26#include "r1_clip.hh"
27#include "r1_win.hh"
28#include "m1_info.hh"
29#include "st_edit.hh"
30#include "app/app.hh"
31#include "window/wmanager.hh"
32#include "lisp/lisp.hh"
33#include "max_load.hh"
34
35#include <stdio.h>
36
37/* render.cc
38
39   Defines a window which will display an object made of polygons.
40   Right now it just shows it wireframe
41   
42
43*/
44#include "id.hh"
45#include "g1_tint.hh"
46
47i4_image_class *background_bitmap=0;
48
49i4_event_handler_reference_class<m1_utility_window_class> m1_render_window;
50
51i4_float m1_utility_state_class::center_x() const { return m1_render_window->center_x; }
52i4_float m1_utility_state_class::center_y() const { return m1_render_window->center_y; }
53i4_float m1_utility_state_class::scale_x()  const { return m1_render_window->scale_x; }
54i4_float m1_utility_state_class::scale_y()  const { return m1_render_window->scale_y; }
55int m1_utility_state_class::width() const   { return m1_render_window->width(); }
56int m1_utility_state_class::height() const  { return m1_render_window->height(); }
57int m1_utility_state_class::mouse_x() const { return m1_render_window->mouse_x; }
58int m1_utility_state_class::mouse_y() const { return m1_render_window->mouse_y; }
59int m1_utility_state_class::last_x() const  { return m1_render_window->last_x; }
60int m1_utility_state_class::last_y() const  { return m1_render_window->last_y; }
61int m1_utility_state_class::buttons() const { return m1_render_window->grab; }
62
63inline i4_float m1_near_clip_z() { return r1_near_clip_z+0.1; }
64
65void m1_utility_window_class::init()
66{
67  calc_params();
68}
69
70void m1_utility_window_class::set_object(const i4_const_str &filename)
71{
72  m1_info.obj=m1_load_model(filename, api->get_tmanager());
73
74  if (m1_st_edit.get())
75    m1_st_edit->edit_poly_changed();
76
77  if (get_obj())
78    i4_alert(i4gets("model_stats"),200, &filename, get_obj()->num_quad, get_obj()->num_vertex);
79
80  request_redraw(i4_F);
81}
82
83
84m1_utility_window_class::m1_utility_window_class(w16 window_width,
85                                                 w16 window_height,
86                                                 r1_render_api_class *api,
87                                                 i4_window_manager_class *wm,
88                                                 i4_float theta,
89                                                 i4_float phi,
90                                                 i4_float dist)
91
92  : i4_parent_window_class(window_width,window_height),
93    api(api),
94    wm(wm),
95    theta(theta),
96    phi(phi),
97    dist(dist),
98    grab(0),
99    state(0),
100    animating(0)
101{
102  pan_x=pan_y=pan_z=0;
103
104  draws_needed=0;
105
106  recalc_view();
107
108  restore_state();
109}
110
111void m1_utility_window_class::recenter()
112{
113  theta=0;
114  phi=0;
115  dist=40;
116  request_redraw(i4_F);
117}
118
119
120
121void m1_utility_window_class::recalc_view()
122{
123  i4_transform_class tmp,tmp2,tmptmp;
124  i4_float greaterdimension;
125
126  transform.identity();
127  tmp.translate(pan_x,pan_y,pan_z);
128  transform.multiply(tmp);
129
130  tmp.translate(0,0,dist);
131  transform.multiply(tmp);
132  tmp.rotate_x(i4_pi() - phi);
133  transform.multiply(tmp);
134  tmp.rotate_z(theta);
135  transform.multiply(tmp);
136
137  //  calc_params();
138}
139
140
141void m1_utility_window_class::pan(i4_float x, i4_float y)
142{
143  request_redraw(i4_F);
144
145  pan_x-=x*dist;
146  pan_y-=y*dist;
147
148  recalc_view();
149}
150
151void m1_utility_window_class::select_poly(int poly_num)
152{
153  if (!m1_info.obj) return;
154
155  if (poly_num==-1)
156    return;
157
158  g1_quad_class *q = &m1_info.obj->quad[poly_num];
159  q->set_flags(g1_quad_class::SELECTED, ~q->get_flags(g1_quad_class::SELECTED));
160  m1_st_edit->edit_poly_changed();
161
162  request_redraw(i4_F);
163}
164
165
166void m1_utility_window_class::drop_files(int t_files, i4_str **filenames)
167{
168  int i;
169  i4_array<i4_str *> gmods(0,32);
170
171  // check to see if any of the files dropped are gmods
172  for (i=0; i<t_files; i++)
173  {
174    i4_filename_struct fn;
175    i4_split_path(*filenames[i], fn);
176    if (strcmp(fn.extension,"gmod")==0)
177      gmods.add(filenames[i]);
178  }
179
180  if (gmods.size())
181  {
182    for (i=0; i<m1_info.models.size(); i++)
183      delete m1_info.models[i];
184
185    m1_info.models.clear();
186
187    for (i=0; i<gmods.size(); i++)
188      m1_info.models.add(new i4_str(*gmods[i]));
189
190    set_object(*m1_info.models[0]);
191  }
192
193}
194
195void m1_utility_window_class::receive_event(i4_event *ev)
196//{{{
197{
198  int pre_grab = grab;
199
200  switch (ev->type())
201  {
202    case i4_event::WINDOW_MESSAGE:
203    {
204      CAST_PTR(wev, i4_window_message_class, ev);
205      if (wev->sub_type==i4_window_message_class::GOT_DROP)
206      {
207        CAST_PTR(dev, i4_window_got_drop_class, ev);
208        if (dev->drag_info.drag_object_type==i4_drag_info_struct::FILENAMES)
209          drop_files(dev->drag_info.t_filenames, dev->drag_info.filenames);
210      }
211    } break;
212
213    case i4_event::MOUSE_BUTTON_DOWN:
214    {
215      CAST_PTR(bev, i4_mouse_button_down_event_class, ev);
216
217      if (bev->but == i4_mouse_button_down_event_class::LEFT)
218        grab |= LEFT_BUTTON;
219      if (bev->but == i4_mouse_button_down_event_class::RIGHT)
220        grab |= RIGHT_BUTTON;
221      if (bev->but == i4_mouse_button_down_event_class::CENTER)
222        grab |= MIDDLE_BUTTON;
223
224      i4_window_request_key_grab_class kgrab(this);
225      i4_kernel.send_event(parent, &kgrab);
226
227      state->mouse_down();
228    } break;
229     
230    case i4_event::MOUSE_BUTTON_UP:
231    {
232      CAST_PTR(bev, i4_mouse_button_up_event_class, ev);
233
234      if (bev->but == i4_mouse_button_down_event_class::LEFT)
235        grab &= ~LEFT_BUTTON;
236      if (bev->but == i4_mouse_button_down_event_class::RIGHT)
237        grab &= ~RIGHT_BUTTON;
238      if (bev->but == i4_mouse_button_down_event_class::CENTER)
239        grab &= ~MIDDLE_BUTTON;
240
241      state->mouse_up();
242    } break;
243     
244    case i4_event::MOUSE_MOVE:
245    {
246      i4_window_class::receive_event(ev);
247
248      int do_redraw = 0;
249
250      if (!grab)
251      {
252        do_redraw = find_hit(mouse_x,mouse_y);
253        if (do_redraw)
254          m1_st_edit->change_current_verts();
255      }
256      else
257        do_redraw = state->mouse_drag();
258
259      if (do_redraw)
260      {
261        recalc_view();
262        request_redraw(i4_F);
263        wm->root_draw();
264      }
265
266      last_x = mouse_x;
267      last_y = mouse_y;
268
269    } break;
270     
271    case i4_event::KEY_PRESS:
272    {
273      CAST_PTR(kev, i4_key_press_event_class, ev);
274
275      switch (kev->key)
276      {
277        case I4_LEFT  : pan(-0.05,0); break;
278        case I4_RIGHT : pan(0.05,0); break;
279        case I4_UP    : pan(0,-0.05); break;
280        case I4_DOWN  : pan(0,0.05); break;
281
282        case 'z':
283        case 'Z': grab |= LEFT_KEY;   state->mouse_down(); break;
284        case 'x':
285        case 'X': grab |= MIDDLE_KEY; state->mouse_down(); break;
286        case 'c':
287        case 'C': grab |= RIGHT_KEY;  state->mouse_down(); break;
288      }
289    } break;
290     
291    case i4_event::KEY_RELEASE:
292    {
293      CAST_PTR(kev, i4_key_release_event_class, ev);
294
295      switch (kev->key)
296      {
297        case 'z':
298        case 'Z': grab &= ~LEFT_KEY;   state->mouse_up(); break;
299        case 'x':
300        case 'X': grab &= ~MIDDLE_KEY; state->mouse_up(); break;
301        case 'c':
302        case 'C': grab &= ~RIGHT_KEY;  state->mouse_up(); break;
303      }
304    } break;
305  }
306
307  if (!pre_grab && grab)
308  {
309    i4_window_request_mouse_grab_class grab_ev(this);
310    i4_kernel.send_event(parent,&grab_ev);
311  }
312  if (pre_grab && !grab)
313  {
314    i4_window_request_mouse_ungrab_class grab_ev(this);
315    i4_kernel.send_event(parent,&grab_ev);
316  }
317
318  i4_parent_window_class::receive_event(ev);
319}
320//}}}
321
322i4_bool m1_utility_window_class::project_point(const i4_3d_point_class &p, r1_vert &v)
323//{{{
324{
325  i4_3d_vector &temp_v = (i4_3d_vector &)v.v;
326  transform.transform(p,temp_v);
327  v.v.x *= scale_x;
328  v.v.y *= scale_y;
329
330  if (v.v.z>0.001)
331  {
332    float ooz = r1_ooz(v.v.z);
333   
334    v.px = v.v.x * ooz * center_x + center_x;
335    v.py = v.v.y * ooz * center_y + center_y;
336
337    v.w = ooz;
338    return i4_T;
339
340  }
341  return i4_F;
342}
343//}}}
344
345void m1_utility_window_class::draw_3d_text(i4_3d_point_class p,
346                                           const i4_const_str &str,
347                                           w32 color,
348                                           i4_draw_context_class &context)
349{
350
351  r1_vert v;
352  if (project_point(p, v))
353  {
354    int x=(int)(v.px-m1_info.r_font->width(str)/2); 
355
356    m1_info.r_api->set_constant_color(0);
357    m1_info.r_font->set_color(0);
358    m1_info.r_font->put_string(local_image, x+1, v.py+1,  str, context);
359
360    m1_info.r_api->set_constant_color(0xffffff);
361    m1_info.r_font->set_color(color);
362    m1_info.r_font->put_string(local_image, x, v.py,  str, context);
363  }
364
365}
366
367void m1_utility_window_class::draw_3d_line(i4_3d_point_class p1,
368                                           i4_3d_point_class p2,
369                                           i4_color color,
370                                           i4_bool on_top)
371//{{{
372{
373  r1_vert v[2];
374
375  project_point(p1, v[0]);
376  project_point(p2, v[1]);
377
378  api->set_shading_mode(R1_CONSTANT_SHADING);
379  api->set_constant_color(color);
380  api->set_alpha_mode(R1_ALPHA_DISABLED);
381  api->disable_texture();
382
383  r1_clip_render_lines(1, v, center_x, center_y, api);
384  api->set_constant_color(0xffffff);
385}
386//}}}
387
388void m1_utility_window_class::draw_3d_point(i4_3d_point_class p, i4_color color, i4_bool on_top)
389//{{{
390{
391  r1_vert v;
392
393  project_point(p, v);
394  int ix = int(v.px),iy = int(v.py);
395  if (ix>0 && iy>0 && ix<center_x*2-1 && iy<center_y*2-1)
396  {
397    api->set_alpha_mode(R1_ALPHA_DISABLED);
398    api->disable_texture();
399    api->r1_render_api_class::clear_area(ix-1,iy-1,ix+1,iy+1,color,
400                                         on_top ? v.v.z : m1_near_clip_z());
401  }
402}
403//}}}
404
405void m1_utility_window_class::draw_plane(const i4_3d_vector &u, const i4_3d_vector &v, w8 color)
406//{{{
407{
408  if (color>0x10)
409  {
410    w32 col = color*0x010101;
411    i4_3d_point_class zero(0,0,0), t1, t2, s1, s2;
412
413    t1 = u;
414    t1 += v;
415    t1 *= -10;
416    t2 = u;
417    t2 -= v;
418    t2 *= -10;
419
420    s1 = t1;
421    s2 = t2;
422    s2.reverse();
423
424    for (int x=-10; x<=10; x++)
425    {
426      draw_3d_line(t1, x?t2:zero, col);
427      draw_3d_line(s1, x?s2:zero, col);
428      s1 += v;
429      s2 += v;
430      t1 += u;
431      t2 += u;
432    }
433  }
434}
435//}}}
436
437static r1_vert t_vertices[3000], clip_buf_1[3000], clip_buf_2[3000];
438static int src_quad[4], dst1[3000], dst2[3000];
439
440void m1_utility_window_class::update_object(i4_float time)
441//{{{
442{
443  get_obj()->update(m1_info.time);
444}
445//}}}
446
447void m1_utility_window_class::render_object(i4_draw_context_class &context)
448//{{{
449{
450  g1_quad_object_class *obj = get_obj();
451 
452  int i,j,k,num_vertices;
453
454  num_vertices            = obj->num_vertex;
455  r1_vert *v              = t_vertices;
456  g1_vert_class *src_vert = obj->get_verts(m1_info.current_animation,
457                                           m1_info.current_frame);
458   
459  w8 ANDCODE = 0xFF;
460  w8 ORCODE  = 0;
461
462  //api->disable_texture();
463  //api->set_shading_mode(R1_CONSTANT_SHADING);
464  //api->set_alpha_mode(R1_ALPHA_CONSTANT);
465  //api->set_constant_color(0x7F000000);
466  //api->set_write_mode(R1_COMPARE_W | R1_WRITE_COLOR);
467  api->set_shading_mode(R1_COLORED_SHADING);
468  if (!m1_info.get_flags(M1_WIREFRAME))
469  {
470    i4_3d_vector cam_in_object_space;
471    transform.inverse_transform(i4_3d_vector(0,0,0),cam_in_object_space);
472
473    i4_3d_vector light=i4_3d_vector(0,0.2, 0.9), light_dir;
474    light.normalize();
475   
476    transform.transform_3x3(light, light_dir);
477
478    for (i=0; i<num_vertices; i++, v++)
479    {       
480      i4_3d_vector &temp_v = (i4_3d_vector &)v->v;
481      transform.transform(src_vert[i].v, temp_v);
482
483      v->v.x *= scale_x;
484      v->v.y *= scale_y;
485   
486     
487      if (m1_info.get_flags(M1_SHADING))
488      {     
489        i4_float intensity = 0.5 * src_vert[i].normal.dot(light_dir) + 0.5;
490        if (intensity<0) intensity=0;
491        if (intensity>1) intensity=1;
492
493        v->r = intensity;
494        v->g = intensity;
495        v->b = intensity;
496        v->a = intensity;
497      }
498      else
499      {
500        v->r = 1;
501        v->g = 1;
502        v->b = 1;   
503        v->a = 1;
504      }
505
506      w8 code = r1_calc_outcode(v);
507
508      ANDCODE &= code;
509      ORCODE  |= code;
510    }
511
512    if (ANDCODE) return;
513
514    api->set_constant_color(0xffffff);
515    api->set_shading_mode(R1_WHITE_SHADING);
516
517    g1_quad_class *q = obj->quad;
518    for (i=0; i<obj->num_quad; i++, q++)
519    {   
520      sw32 num_poly_verts = q->num_verts();
521
522      i4_3d_vector cam_to_pt = src_vert[q->vertex_ref[0]].v;
523      cam_to_pt -= cam_in_object_space;
524
525      float dot = cam_to_pt.dot(q->normal);
526
527      if (dot<0)
528      {
529        // copy in the texture coordinates     
530        for (j=0; j<num_poly_verts; j++)     
531        {
532          int ref=q->vertex_ref[j];
533          src_quad[j]=ref;
534
535          v = &t_vertices[ref];
536          v->s = q->u[j];
537          v->t = q->v[j];
538        }
539
540     
541        if (q->get_flags(g1_quad_class::TINT) && m1_info.current_team!=100)
542          api->set_color_tint(g1_player_tint_handles[m1_info.current_team]);
543        else
544          api->set_color_tint(0);
545
546        if (ORCODE==0)
547        {
548          float nearest_w = 0;
549       
550          for (j=0; j<num_poly_verts; j++)
551          {       
552            r1_vert *temp_vert = &t_vertices[q->vertex_ref[j]];
553           
554            float ooz = r1_ooz(temp_vert->v.z);
555           
556            if (ooz > nearest_w)
557              nearest_w=ooz;
558             
559            temp_vert->px = temp_vert->v.x * ooz * center_x + center_x;
560            temp_vert->py = temp_vert->v.y * ooz * center_y + center_y;
561            temp_vert->w  = ooz;                                                 
562          }
563       
564          i4_float twidth = nearest_w * q->texture_scale * center_x * 2;
565
566          api->use_texture(q->material_ref, i4_f_to_i(twidth), m1_info.current_frame);
567
568          api->render_poly(num_poly_verts,t_vertices,q->vertex_ref);
569        }
570        else
571        {
572          r1_vert temp_buf_1[64];
573          r1_vert temp_buf_2[64];
574          r1_vert *clipped_poly = api->clip_poly(&num_poly_verts,
575                                                   t_vertices,
576                                                   q->vertex_ref,
577                                                   temp_buf_1,
578                                                   temp_buf_2,
579                                                   R1_CLIP_NO_CALC_OUTCODE);
580         
581          if (clipped_poly && num_poly_verts>=3)     
582          {
583            float nearest_w = 0;
584
585            for (j=0; j<num_poly_verts; j++)
586            {       
587              float ooz = r1_ooz(clipped_poly[j].v.z);
588              if (ooz > nearest_w)
589                nearest_w=ooz;
590             
591              clipped_poly[j].px = clipped_poly[j].v.x * ooz * center_x + center_x;
592              clipped_poly[j].py = clipped_poly[j].v.y * ooz * center_y + center_y;
593              clipped_poly[j].w  = ooz;                 
594            }
595
596            i4_float twidth = nearest_w * q->texture_scale * center_x * 2;
597
598            api->use_texture(q->material_ref, i4_f_to_i(twidth), m1_info.current_frame);
599
600            api->render_poly(num_poly_verts,clipped_poly);
601          }
602        }
603      }
604    }
605  }
606
607  // Axis display
608  if (m1_info.get_flags(M1_SHOW_AXIS))
609  {
610    draw_3d_line (i4_3d_point_class(0,0,0), i4_3d_point_class(100,0,0), 0xd0d000);
611    draw_3d_line (i4_3d_point_class(0,0,0), i4_3d_point_class(0,100,0), 0xd0d0d0);
612    draw_3d_line (i4_3d_point_class(0,0,0), i4_3d_point_class(0,0,100), 0xd0d0d0);
613
614    int x,y;
615    const i4_float axis_range=0.5;
616    w32 col;
617
618    if (dist>4)
619    {
620      col = w32(transform.z.z*transform.z.z*0x80);
621      draw_plane(i4_3d_vector(10,0,0), i4_3d_vector(0,10,0), col);
622      col = w32(transform.y.z*transform.y.z*0x60);
623      draw_plane(i4_3d_vector(10,0,0), i4_3d_vector(0,0,10), col);
624      col = w32(transform.x.z*transform.x.z*0x60);
625      draw_plane(i4_3d_vector(0,10,0), i4_3d_vector(0,0,10), col);
626    }
627    if (dist<15)
628    {
629      i4_float fade = (15 - dist)*0.2;
630      fade = fade>1.0? 1.0 : fade;
631      col = w32(fade*transform.z.z*transform.z.z*0x80);
632      draw_plane(i4_3d_vector(1,0,0), i4_3d_vector(0,1,0), col);
633      col = w32(fade*transform.y.z*transform.y.z*0x60);
634      draw_plane(i4_3d_vector(1,0,0), i4_3d_vector(0,0,1), col);
635      col = w32(fade*transform.x.z*transform.x.z*0x60);
636      draw_plane(i4_3d_vector(0,1,0), i4_3d_vector(0,0,1), col);
637    }
638  }
639
640  api->set_write_mode(R1_WRITE_COLOR);
641  // draw wire stuff
642  w32 color=0xffffff;
643
644  int q;
645  for (q=0; q<obj->num_quad; q++)
646  {     
647    if (m1_info.get_flags(M1_WIREFRAME) ||
648        obj->quad[q].get_flags(g1_quad_class::SELECTED |
649                               m1_poly_object_class::INVALID_QUAD))
650    {
651      if (obj->quad[q].get_flags(g1_quad_class::SELECTED))
652        color=0xffff00;
653      else if (obj->quad[q].get_flags(m1_poly_object_class::INVALID_QUAD))
654        color=0xff0000;
655      else
656        color=0x404040;
657     
658      i4_3d_point_class p1,p2;
659
660      p2=src_vert[obj->quad[q].vertex_ref[0]].v;
661      for (i=obj->quad[q].num_verts()-1; i>=0; i--)
662      {
663        p1=src_vert[obj->quad[q].vertex_ref[i]].v;
664        draw_3d_line(p1, p2, color, i4_T);
665        p2 = p1;
666      }
667    }
668
669  }
670
671 
672  // preselections
673
674  api->set_color_tint(0);
675
676  if (m1_info.preselect_poly>=0)
677  {
678    i4_3d_point_class p1,p2;
679    g1_quad_class *q = &obj->quad[m1_info.preselect_poly];
680    p2=src_vert[q->vertex_ref[0]].v;
681    color=0x0000ff;
682    for (i=q->num_verts()-1; i>=0; i--)
683    {
684      p1=src_vert[q->vertex_ref[i]].v;
685      draw_3d_line(p1, p2, color, i4_T);
686      p2 = p1;
687    }
688  }
689
690  if (m1_info.preselect_point>=0)
691    draw_3d_point(src_vert[m1_info.preselect_point].v, 0xff00ff, i4_T);
692
693  // mount points
694
695  for (i=0; i<obj->num_mounts; i++)
696    draw_3d_point(obj->mount[i], 0x006060, i4_T);
697
698  for (i=0; i<obj->num_mounts; i++)
699    draw_3d_point(obj->mount[i], 0x00ffff);
700
701
702  if (m1_info.flags & (M1_SHOW_FACE_NUMBERS | M1_SHOW_FACE_NAMES))
703  {
704    for (q=0; q<obj->num_quad; q++)
705    {     
706      if (obj->quad[q].get_flags(g1_quad_class::SELECTED))
707      {
708       
709        int t_verts=obj->quad[q].num_verts();
710        i4_3d_vector sum=i4_3d_vector(0,0,0);
711
712        for (i=0; i<t_verts; i++)
713          sum+=src_vert[obj->quad[q].vertex_ref[i]].v;
714
715        sum/=(float)t_verts;
716
717
718        char buf[150];
719        buf[0]=0;
720
721        if (m1_info.flags & M1_SHOW_FACE_NUMBERS)
722          sprintf(buf, "%d ", q);
723        if ((m1_info.flags & M1_SHOW_FACE_NAMES) && m1_info.obj->texture_names[q])
724          i4_os_string(*m1_info.obj->texture_names[q], buf+strlen(buf), 100);
725
726       
727        draw_3d_text(sum, buf, 0xffffff, context);
728
729      }
730    }
731  }
732
733  if (m1_info.flags & (M1_SHOW_VERT_NUMBERS))
734  {
735    for (int v=0; v<obj->num_vertex; v++)
736    {
737      int used=0;
738      for (q=0; q<obj->num_quad; q++)
739        if (obj->quad[q].get_flags(g1_quad_class::SELECTED))
740        {       
741          int t_verts=obj->quad[q].num_verts();
742          for (int qv=0; qv<t_verts; qv++)
743            if (obj->quad[q].vertex_ref[qv]==v)
744              used=1;
745        }
746
747      if (used)
748      {
749        char buf[100];
750        sprintf(buf,"%d", v);
751        draw_3d_text(src_vert[v].v, buf, 0x00ffff, context);
752      }
753
754    }
755
756
757  }
758
759}
760//}}}
761
762void m1_utility_window_class::parent_draw(i4_draw_context_class &context)
763//{{{
764{
765
766  if (m1_info.recalcing_textures)
767  {
768    local_image->clear(0, context);
769    return;
770  }
771
772  if (background_bitmap)
773  {
774    for (w32 y=0; y<height(); y+=background_bitmap->height())
775      for (w32 x=0; x<width(); x+=background_bitmap->width())
776        background_bitmap->put_image(local_image, x,y, context);
777  }
778  //  else
779  //    local_image->clear(15,context);
780  //local_image->add_dirty(0,0,width()-1,height()-1, context);
781
782  //  recalc_view();
783
784
785  ((r1_render_window_class *)parent)->begin_render();
786
787 
788  m1_poly_object_class *obj=get_obj();
789
790  if (obj)
791  {
792    obj->calc_vert_normals();
793    api->default_state();
794
795    api->set_z_range(0.01, 1000);
796    //r1_far_clip_z = 1000;
797
798    api->clear_area(0,0, width()-1, height()-1, m1_info.bg_color, 1000-1);   
799
800    api->set_filter_mode(R1_BILINEAR_FILTERING);
801
802    if (animating)
803    {
804      i4_time_class now;
805     
806      m1_info.time += i4_float(now.milli_diff(last_time)) / 100.0;
807      last_time = now;
808      update_object(m1_info.time);
809      request_redraw();
810    }
811
812    render_object(context);
813  }
814  else
815    local_image->clear(0,context);
816
817  i4_window_class::draw(context);
818
819  ((r1_render_window_class *)parent)->end_render();
820
821  //    i4_time_dev.request_event(this,new i4_user_message_event_class(0),100);
822  //  request_redraw(i4_F);
823}
824//}}}
825
826i4_bool m1_utility_window_class::find_hit(int mx, int my)
827//{{{
828{
829  i4_bool ret=i4_F;
830 
831  g1_quad_object_class *obj=get_obj();
832 
833  // select point
834  if (obj)
835  {
836    g1_vert_class *src_vert = obj->get_verts(m1_info.current_animation, m1_info.current_frame);
837    r1_vert tmp_v;
838    i4_float left = mx-3,right = mx+3, top=my-3, bottom=my+3;
839    int p=-1, np=m1_info.preselect_point;
840
841    for (int j=0; j<obj->num_quad; j++)
842    {
843      if (obj->quad[j].get_flags(g1_quad_class::SELECTED))
844        for (int i=0; i<obj->quad[j].num_verts(); i++)
845        {
846          int v = obj->quad[j].vertex_ref[i];
847          project_point(src_vert[v].v, tmp_v);
848       
849          if (tmp_v.px>=left && tmp_v.px<=right && tmp_v.py>top && tmp_v.py<bottom)
850            p = v;
851        }
852    }
853
854    m1_info.preselect_point = p;
855    if (p!=np)
856      ret = i4_T;
857  }
858 
859  int p, np=m1_info.preselect_poly;
860  if (m1_info.preselect_point<0)
861  {
862    // find ray in camera space
863    i4_float px = (i4_float(mx)-center_x)/(center_x*scale_x);
864    i4_float py = (i4_float(my)-center_y)/(center_y*scale_y);
865   
866    i4_3d_vector point,ray;
867   
868    transform.inverse_transform(i4_3d_vector(0,0,0), point);
869    transform.inverse_transform(i4_3d_vector(px,py,1.0), ray);
870    ray -= point;
871    ray *= 10000;
872   
873    // select poly
874    if (!obj || !obj->intersect(point, ray,
875                                m1_info.current_animation, m1_info.current_frame,
876                                0, &p))
877      p=-1;
878  }
879  else
880    p = -1;
881
882  m1_info.preselect_poly=p;
883  if (np!=m1_info.preselect_poly)
884    ret = i4_T;
885
886  return ret;
887}
888//}}}
889
890extern m1_utility_state_class *m1_default_state;
891void m1_utility_window_class::restore_state()
892//{{{
893{
894  state = m1_default_state;
895}
896//}}}
897
898//{{{ Emacs Locals
899// Local Variables:
900// folded-file: t
901// End:
902//}}}
Note: See TracBrowser for help on using the repository browser.