home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / shareware / crystalppc / thing.cpp < prev    next >
C/C++ Source or Header  |  1998-06-08  |  15KB  |  557 lines

  1. #include <math.h>
  2. #include <time.h>
  3. #include "system.h"
  4.  
  5. #ifndef DEF_H
  6. #include "def.h"
  7. #endif
  8.  
  9. #ifndef THING_H
  10. #include "thing.h"
  11. #endif
  12.  
  13. #ifndef POLYGON_H
  14. #include "polygon.h"
  15. #endif
  16.  
  17. #ifndef SCAN_H
  18. #include "scan.h"
  19. #endif
  20.  
  21. #ifndef LIGHT_H
  22. #include "light.h"
  23. #endif
  24.  
  25. #ifndef CAMERA_H
  26. #include "camera.h"
  27. #endif
  28.  
  29. #ifndef TEXTURE_H
  30. #include "texture.h"
  31. #endif
  32.  
  33. #ifndef TOKEN_H
  34. #include "token.h"
  35. #endif
  36.  
  37. #ifndef WORLD_H
  38. #include "world.h"
  39. #endif
  40.  
  41. //---------------------------------------------------------------------------
  42.  
  43. Thing::Thing (char* name, int max_v, int max_p) : PolygonSet (name, CS_THING, max_v, max_p)
  44. {
  45.   v_obj2world.x = 0;
  46.   v_obj2world.y = 0;
  47.   v_obj2world.z = 0;
  48.   m_obj2world.identity ();
  49.   m_world2obj.identity ();
  50. }
  51.  
  52. Thing::~Thing ()
  53. {
  54. }
  55.  
  56. void Thing::transform ()
  57. {
  58.   int i;
  59.   for (i = 0 ; i < num_vertices ; i++)
  60.     vertices[i].object_to_world (m_obj2world, m_world2obj, v_obj2world);
  61.   for (i = 0 ; i < num_polygon ; i++)
  62.     polygon[i]->object_to_world (m_obj2world, m_world2obj, v_obj2world);
  63. }
  64.  
  65. void Thing::set_move (Sector* home, float x, float y, float z)
  66. {
  67.   v_obj2world.x = -x;
  68.   v_obj2world.y = -y;
  69.   v_obj2world.z = -z;
  70.   sector = home;
  71. }
  72.  
  73. void Thing::set_transform (Matrix3& matrix)
  74. {
  75.   m_obj2world = matrix;
  76.   m_world2obj = m_obj2world;
  77.   m_world2obj.inverse ();
  78. }
  79.  
  80. void Thing::move (float dx, float dy, float dz)
  81. {
  82.   v_obj2world.x += dx;
  83.   v_obj2world.y += dy;
  84.   v_obj2world.z += dz;
  85. }
  86.  
  87. void Thing::transform (Matrix3& matrix)
  88. {
  89.   m_obj2world *= matrix;
  90.   m_world2obj = m_obj2world;
  91.   m_world2obj.inverse ();
  92. }
  93.  
  94. void Thing::mipmap_settings (int setting)
  95. {
  96.   int i;
  97.   for (i = 0 ; i < num_polygon ; i++)
  98.   {
  99.     polygon[i]->mipmap_settings (setting);
  100.   }
  101. }
  102.  
  103. void Thing::shine (Light* light)
  104. {
  105.   int i;
  106.   for (i = 0 ; i < num_polygon ; i++)
  107.     if (polygon[i]->visible_from_point (light->get_center ()))
  108.       polygon[i]->shine (light);
  109. }
  110.  
  111. void Thing::clear_shine_done ()
  112. {
  113.   int i;
  114.   for (i = 0 ; i < num_polygon ; i++) polygon[i]->clear_shine_done ();
  115. }
  116.  
  117. void Thing::draw (ViewPolygon* view, Matrix3& m_w2c, Matrix3& m_c2w, Vector3& v_w2c)
  118. {
  119.   int i;
  120.  
  121.   if (transform_world2cam (m_w2c, m_c2w, v_w2c))
  122.   {
  123.     for (i = 0 ; i < num_polygon ; i++)
  124.     {
  125.       if (polygon[i]->do_perspective (m_w2c, m_c2w, v_w2c, &Polygon2D::clipped))
  126.       {
  127.     if (Polygon2D::clipped.clip_poly_variant (view))
  128.     {
  129.       Polygon2D::clipped.draw_filled (polygon[i], TRUE);
  130.       if (Scan::c->edit_mode != MODE_NONE && Scan::c->sel_polygon == polygon[i])
  131.         Polygon2D::clipped.draw (Scan::textures->red ());
  132.       else if (Scan::c->edit_mode == MODE_POLYGON) Polygon2D::clipped.draw (Scan::textures->white ());
  133.     }
  134.       }
  135.     }
  136.  
  137.     if (Scan::c->edit_mode != MODE_NONE) edit_draw_vertices ();
  138.   }
  139. }
  140.  
  141. void Thing::save (FILE* fp, int indent, Textures* textures)
  142. {
  143.   char sp[100]; strcpy (sp, spaces); sp[indent] = 0;
  144.   PolygonSet::save (fp, indent, textures, "THING");
  145.   fprintf (fp, "%s  MOVE (\n", sp);
  146.   m_obj2world.save (fp, indent+4);
  147.   Vector3 v = v_obj2world;
  148.   v.x = -v.x; v.y = -v.y; v.z = -v.z;
  149.   v.save (fp, indent+4);
  150.   fprintf (fp, "%s  )\n", sp);
  151.   fprintf (fp, "%s)\n", sp);
  152. }
  153.  
  154. void Thing::load (World* w, char** buf, Textures* textures)
  155. {
  156.   PolygonSet::load (w, buf, textures, "THING");
  157.   skip_token (buf, "MOVE", "Expected '%s' instead of '%s' for a THING!\n");
  158.   skip_token (buf, "(", "Expected '%s' instead of '%s' after MOVE!\n");
  159.   m_obj2world.load (buf);
  160.   Vector3 v;
  161.   v.load (buf);
  162.   v.x = -v.x; v.y = -v.y; v.z = -v.z;
  163.   v_obj2world = v;
  164.   skip_token (buf, ")", "Expected '%s' instead of '%s' to finish MOVE!\n");
  165.   skip_token (buf, ")", "Expected '%s' instead of '%s' to finish the THING!\n");
  166.   m_world2obj = m_obj2world;
  167.   m_world2obj.inverse ();
  168.  
  169.   transform ();
  170. }
  171.  
  172. typedef char ObName[30];
  173.  
  174. void Thing::load_sixface (World* w, char** buf, Textures* textures)
  175. {
  176.   char* t;
  177.   char* old_buf;
  178.   int j;
  179.  
  180.   set_max (25, 16);
  181.  
  182.   num_vertices = 0;
  183.   num_polygon = 0;
  184.  
  185.   skip_token (buf, "SIXFACE");
  186.   t = get_token (buf);
  187.   strcpy (name, t);
  188.   skip_token (buf, "(", "Expected '%s' instead of '%s' after the name of a SIXFACE!\n");
  189.  
  190.   v_obj2world.x = 0;
  191.   v_obj2world.y = 0;
  192.   v_obj2world.z = 0;
  193.   m_obj2world.identity ();
  194.   m_world2obj.identity ();
  195.  
  196.   int color;
  197.   float tscale;
  198.   color = 0;
  199.   tscale = 1;
  200.  
  201.   Vector3 v0, v1, v2, v3, v4, v5, v6, v7;
  202.   v0.x = -1; v0.y =  1; v0.z =  1;
  203.   v1.x =  1; v1.y =  1; v1.z =  1;
  204.   v2.x = -1; v2.y = -1; v2.z =  1;
  205.   v3.x =  1; v3.y = -1; v3.z =  1;
  206.   v4.x = -1; v4.y =  1; v4.z = -1;
  207.   v5.x =  1; v5.y =  1; v5.z = -1;
  208.   v6.x = -1; v6.y = -1; v6.z = -1;
  209.   v7.x =  1; v7.y = -1; v7.z = -1;
  210.   float r;
  211.  
  212.   while (TRUE)
  213.   {
  214.     old_buf = *buf;
  215.     t = get_token (buf);
  216.     if (*t == ')' || *t == 0) break;
  217.     if (!strcmp (t, "MOVE"))
  218.     {
  219.       skip_token (buf, "(", "Expected '%s' instead of '%s' after MOVE!\n");
  220.       m_obj2world.load (buf);
  221.       v_obj2world.load (buf);
  222.       m_world2obj = m_obj2world;
  223.       m_world2obj.inverse ();
  224.       v_obj2world.x = -v_obj2world.x;
  225.       v_obj2world.y = -v_obj2world.y;
  226.       v_obj2world.z = -v_obj2world.z;
  227.       skip_token (buf, ")", "Expected '%s' instead of '%s' to finish MOVE!\n");
  228.     }
  229.     else if (!strcmp (t, "TEXTURE"))
  230.     {
  231.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE!\n");
  232.       t = get_token (buf);
  233.       color = textures->get_texture_idx (t);
  234.       if (color == -1) printf ("Couldn't find texture named '%s'!\n", t);
  235.     }
  236.     else if (!strcmp (t, "TEXTURE_SCALE"))
  237.     {
  238.       skip_token (buf, "=", "Expected '%s' instead of '%s' after TEXTURE_SCALE!\n");
  239.       tscale = get_token_float (buf);
  240.     }
  241.     else if (!strcmp (t, "DIMX"))
  242.     {
  243.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMX!\n");
  244.       r = get_token_float (buf);
  245.       r /= 2;
  246.       v0.x = -r;
  247.       v1.x = r;
  248.       v2.x = -r;
  249.       v3.x = r;
  250.       v4.x = -r;
  251.       v5.x = r;
  252.       v6.x = -r;
  253.       v7.x = r;
  254.     }
  255.     else if (!strcmp (t, "DIMY"))
  256.     {
  257.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMY!\n");
  258.       r = get_token_float (buf);
  259.       r /= 2;
  260.       v0.y = r;
  261.       v1.y = r;
  262.       v2.y = -r;
  263.       v3.y = -r;
  264.       v4.y = r;
  265.       v5.y = r;
  266.       v6.y = -r;
  267.       v7.y = -r;
  268.     }
  269.     else if (!strcmp (t, "DIMZ"))
  270.     {
  271.       skip_token (buf, "=", "Expected '%s' instead of '%s' after DIMZ!\n");
  272.       r = get_token_float (buf);
  273.       r /= 2;
  274.       v0.z = r;
  275.       v1.z = r;
  276.       v2.z = r;
  277.       v3.z = r;
  278.       v4.z = -r;
  279.       v5.z = -r;
  280.       v6.z = -r;
  281.       v7.z = -r;
  282.     }
  283.     else if (!strcmp (t, "FLOOR_HEIGHT"))
  284.     {
  285.       skip_token (buf, "=", "Expected '%s' instead of '%s' after FLOOR_HEIGHT!\n");
  286.       r = get_token_float (buf);
  287.       v0.y = r+v0.y-v2.y;
  288.       v1.y = r+v1.y-v3.y;
  289.       v4.y = r+v4.y-v6.y;
  290.       v5.y = r+v5.y-v7.y;
  291.       v2.y = r;
  292.       v3.y = r;
  293.       v6.y = r;
  294.       v7.y = r;
  295.     }
  296.     else if (!strcmp (t, "HEIGHT"))
  297.     {
  298.       skip_token (buf, "=", "Expected '%s' instead of '%s' after HEIGHT!\n");
  299.       r = get_token_float (buf);
  300.       v0.y = r+v2.y;
  301.       v1.y = r+v3.y;
  302.       v4.y = r+v6.y;
  303.       v5.y = r+v7.y;
  304.     }
  305.     else if (!strcmp (t, "FLOOR") || !strcmp (t, "FLOOR_CEIL"))
  306.     {
  307.       int floor_ceil = !strcmp (t, "FLOOR_CEIL");
  308.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  309.       v2.x = get_token_float (buf);
  310.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  311.       v2.z = get_token_float (buf);
  312.       t = get_token (buf);
  313.       if (*t == ',')
  314.       {
  315.         v2.y = v2.z;
  316.         v2.z = get_token_float (buf);
  317.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  318.       }
  319.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  320.  
  321.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  322.       v3.x = get_token_float (buf);
  323.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  324.       v3.z = get_token_float (buf);
  325.       t = get_token (buf);
  326.       if (*t == ',')
  327.       {
  328.         v3.y = v3.z;
  329.         v3.z = get_token_float (buf);
  330.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  331.       }
  332.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  333.  
  334.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  335.       v7.x = get_token_float (buf);
  336.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  337.       v7.z = get_token_float (buf);
  338.       t = get_token (buf);
  339.       if (*t == ',')
  340.       {
  341.         v7.y = v7.z;
  342.         v7.z = get_token_float (buf);
  343.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  344.       }
  345.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  346.  
  347.       skip_token (buf, "(", "Expected '%s' instead of '%s' after FLOOR!\n");
  348.       v6.x = get_token_float (buf);
  349.       skip_token (buf, ",", "Expected '%s' instead of '%s' after FLOOR!\n");
  350.       v6.z = get_token_float (buf);
  351.       t = get_token (buf);
  352.       if (*t == ',')
  353.       {
  354.         v6.y = v6.z;
  355.         v6.z = get_token_float (buf);
  356.         skip_token (buf, ")", "Expected '%s' instead of '%s' after FLOOR!\n");
  357.       }
  358.       else if (*t != ')') { printf ("Expected ')' after FLOOR!\n"); exit (0); }
  359.       if (floor_ceil)
  360.       {
  361.         v0 = v2;
  362.     v1 = v3;
  363.     v5 = v7;
  364.     v4 = v6;
  365.       }
  366.     }
  367.     else if (!strcmp (t, "CEILING"))
  368.     {
  369.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  370.       v0.x = get_token_float (buf);
  371.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  372.       v0.z = get_token_float (buf);
  373.       t = get_token (buf);
  374.       if (*t == ',')
  375.       {
  376.         v0.y = v0.z;
  377.         v0.z = get_token_float (buf);
  378.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  379.       }
  380.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  381.  
  382.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  383.       v1.x = get_token_float (buf);
  384.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  385.       v1.z = get_token_float (buf);
  386.       t = get_token (buf);
  387.       if (*t == ',')
  388.       {
  389.         v1.y = v1.z;
  390.         v1.z = get_token_float (buf);
  391.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  392.       }
  393.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  394.  
  395.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  396.       v5.x = get_token_float (buf);
  397.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  398.       v5.z = get_token_float (buf);
  399.       t = get_token (buf);
  400.       if (*t == ',')
  401.       {
  402.         v5.y = v5.z;
  403.         v5.z = get_token_float (buf);
  404.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  405.       }
  406.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  407.  
  408.       skip_token (buf, "(", "Expected '%s' instead of '%s' after CEILING!\n");
  409.       v4.x = get_token_float (buf);
  410.       skip_token (buf, ",", "Expected '%s' instead of '%s' after CEILING!\n");
  411.       v4.z = get_token_float (buf);
  412.       t = get_token (buf);
  413.       if (*t == ',')
  414.       {
  415.         v4.y = v4.z;
  416.         v4.z = get_token_float (buf);
  417.         skip_token (buf, ")", "Expected '%s' instead of '%s' after CEILING!\n");
  418.       }
  419.       else if (*t != ')') { printf ("Expected ')' after CEILING!\n"); exit (0); }
  420.     }
  421.     else if (!strcmp (t, "TRIGGER"))
  422.     {
  423.       t = get_token (buf);
  424.       if (!strcmp (t, "activate"))
  425.       {
  426.     skip_token (buf, ":", "Expected '%s' instead of '%s' in TRIGGER!\n");
  427.     t = get_token (buf);
  428.     Script* s = w->get_script (t);
  429.     if (!s)
  430.     {
  431.       printf ("Don't know script '%s'!\n", t);
  432.       exit (0);
  433.     }
  434.     new_activate_trigger (s);
  435.       }
  436.       else
  437.       {
  438.     printf ("Trigger '%s' not supported or known for object '%s'!\n", t, name);
  439.     exit (0);
  440.       }
  441.     }
  442.     else
  443.     {
  444.       printf ("What is '%s' doing in a SIXFACE statement?\n", t);
  445.     }
  446.   }
  447.  
  448.   j = 0;
  449. #if 1
  450.   set_vertex (j++, v0);
  451.   set_vertex (j++, v1);
  452.   set_vertex (j++, v2);
  453.   set_vertex (j++, v3);
  454.   set_vertex (j++, v4);
  455.   set_vertex (j++, v5);
  456.   set_vertex (j++, v6);
  457.   set_vertex (j++, v7);
  458. #else
  459.   mm.transform (v0, vv); vv += vm; set_vertex (j++, vv);
  460.   mm.transform (v1, vv); vv += vm; set_vertex (j++, vv);
  461.   mm.transform (v2, vv); vv += vm; set_vertex (j++, vv);
  462.   mm.transform (v3, vv); vv += vm; set_vertex (j++, vv);
  463.   mm.transform (v4, vv); vv += vm; set_vertex (j++, vv);
  464.   mm.transform (v5, vv); vv += vm; set_vertex (j++, vv);
  465.   mm.transform (v6, vv); vv += vm; set_vertex (j++, vv);
  466.   mm.transform (v7, vv); vv += vm; set_vertex (j++, vv);
  467. #endif
  468.  
  469.   Polygon3D* p;
  470.  
  471.   struct Todo
  472.   {
  473.     ObName poly;
  474.     int v1, v2, v3, v4;
  475.     int tv1, tv2;
  476.     int color;
  477.   };
  478.   Todo todo[100];
  479.   int done = 0;
  480.   int todo_end = 0;
  481.  
  482.   strcpy (todo[todo_end].poly, "north");
  483.   todo[todo_end].v1 = 0;
  484.   todo[todo_end].v2 = 1;
  485.   todo[todo_end].v3 = 3;
  486.   todo[todo_end].v4 = 2;
  487.   todo[todo_end].tv1 = 0;
  488.   todo[todo_end].tv2 = 1;
  489.   todo[todo_end].color = color;
  490.   todo_end++;
  491.  
  492.   strcpy (todo[todo_end].poly, "east");
  493.   todo[todo_end].v1 = 1;
  494.   todo[todo_end].v2 = 5;
  495.   todo[todo_end].v3 = 7;
  496.   todo[todo_end].v4 = 3;
  497.   todo[todo_end].tv1 = 1;
  498.   todo[todo_end].tv2 = 5;
  499.   todo[todo_end].color = color;
  500.   todo_end++;
  501.  
  502.   strcpy (todo[todo_end].poly, "south");
  503.   todo[todo_end].v1 = 5;
  504.   todo[todo_end].v2 = 4;
  505.   todo[todo_end].v3 = 6;
  506.   todo[todo_end].v4 = 7;
  507.   todo[todo_end].tv1 = 5;
  508.   todo[todo_end].tv2 = 4;
  509.   todo[todo_end].color = color;
  510.   todo_end++;
  511.  
  512.   strcpy (todo[todo_end].poly, "west");
  513.   todo[todo_end].v1 = 4;
  514.   todo[todo_end].v2 = 0;
  515.   todo[todo_end].v3 = 2;
  516.   todo[todo_end].v4 = 6;
  517.   todo[todo_end].tv1 = 4;
  518.   todo[todo_end].tv2 = 0;
  519.   todo[todo_end].color = color;
  520.   todo_end++;
  521.  
  522.   strcpy (todo[todo_end].poly, "up");
  523.   todo[todo_end].v1 = 4;
  524.   todo[todo_end].v2 = 5;
  525.   todo[todo_end].v3 = 1;
  526.   todo[todo_end].v4 = 0;
  527.   todo[todo_end].tv1 = 4;
  528.   todo[todo_end].tv2 = 5;
  529.   todo[todo_end].color = color;
  530.   todo_end++;
  531.  
  532.   strcpy (todo[todo_end].poly, "down");
  533.   todo[todo_end].v1 = 2;
  534.   todo[todo_end].v2 = 3;
  535.   todo[todo_end].v3 = 7;
  536.   todo[todo_end].v4 = 6;
  537.   todo[todo_end].tv1 = 2;
  538.   todo[todo_end].tv2 = 3;
  539.   todo[todo_end].color = color;
  540.   todo_end++;
  541.  
  542.   while (done < todo_end)
  543.   {
  544.     p = new_polygon (todo[done].poly, 20, textures, todo[done].color);
  545.     p->add_vertex (todo[done].v4);
  546.     p->add_vertex (todo[done].v3);
  547.     p->add_vertex (todo[done].v2);
  548.     p->add_vertex (todo[done].v1);
  549.     p->set_texture_space (vtex (todo[done].tv2), vtex (todo[done].tv1), tscale);
  550.     done++;
  551.   }
  552.  
  553.   transform ();
  554. }
  555.  
  556. //---------------------------------------------------------------------------
  557.