Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>.
  3.  * It is copyright by its individual contributors, as recorded in the
  4.  * project's Git history.  See COPYING.txt at the top level for license
  5.  * terms and a link to the Git history.
  6.  */
  7. /*
  8.  *
  9.  * Rod routines
  10.  *
  11.  */
  12.  
  13.  
  14. #include "3d.h"
  15. #include "globvars.h"
  16. #include "maths.h"
  17. #if !DXX_USE_OGL
  18. #include "gr.h"
  19. #endif
  20.  
  21. #include "compiler-range_for.h"
  22.  
  23. namespace dcx {
  24.  
  25. namespace {
  26.  
  27. struct rod_4point
  28. {
  29.         std::array<cg3s_point *, 4> point_list;
  30.         std::array<g3s_point, 4> points;
  31. };
  32.  
  33. }
  34.  
  35. //compute the corners of a rod.  fills in vertbuf.
  36. static int calc_rod_corners(rod_4point &rod_point_group, const g3s_point &bot_point,fix bot_width,const g3s_point &top_point,fix top_width)
  37. {
  38.         //compute vector from one point to other, do cross product with vector
  39.         //from eye to get perpendiclar
  40.  
  41.         auto delta_vec = vm_vec_sub(bot_point.p3_vec,top_point.p3_vec);
  42.  
  43.         //unscale for aspect
  44.  
  45.         delta_vec.x = fixdiv(delta_vec.x,Matrix_scale.x);
  46.         delta_vec.y = fixdiv(delta_vec.y,Matrix_scale.y);
  47.  
  48.         //calc perp vector
  49.  
  50.         //do lots of normalizing to prevent overflowing.  When this code works,
  51.         //it should be optimized
  52.  
  53.         vm_vec_normalize(delta_vec);
  54.  
  55.         const auto top = vm_vec_normalized(top_point.p3_vec);
  56.  
  57.         auto rod_norm = vm_vec_cross(delta_vec,top);
  58.  
  59.         vm_vec_normalize(rod_norm);
  60.  
  61.         //scale for aspect
  62.  
  63.         rod_norm.x = fixmul(rod_norm.x,Matrix_scale.x);
  64.         rod_norm.y = fixmul(rod_norm.y,Matrix_scale.y);
  65.  
  66.         //now we have the usable edge.  generate four points
  67.  
  68.         //top points
  69.  
  70.         auto tempv = vm_vec_copy_scale(rod_norm,top_width);
  71.         tempv.z = 0;
  72.  
  73.         rod_point_group.point_list[0] = &rod_point_group.points[0];
  74.         rod_point_group.point_list[1] = &rod_point_group.points[1];
  75.         rod_point_group.point_list[2] = &rod_point_group.points[2];
  76.         rod_point_group.point_list[3] = &rod_point_group.points[3];
  77.         auto &rod_points = rod_point_group.points;
  78.         vm_vec_add(rod_points[0].p3_vec,top_point.p3_vec,tempv);
  79.         vm_vec_sub(rod_points[1].p3_vec,top_point.p3_vec,tempv);
  80.  
  81.         vm_vec_copy_scale(tempv,rod_norm,bot_width);
  82.         tempv.z = 0;
  83.  
  84.         vm_vec_sub(rod_points[2].p3_vec,bot_point.p3_vec,tempv);
  85.         vm_vec_add(rod_points[3].p3_vec,bot_point.p3_vec,tempv);
  86.  
  87.  
  88.         //now code the four points
  89.  
  90.         ubyte codes_and = 0xff;
  91.         range_for (auto &i, rod_points)
  92.         {
  93.                 codes_and &= g3_code_point(i);
  94.         //clear flags for new points (not projected)
  95.                 i.p3_flags = 0;
  96.         }
  97.         return codes_and;
  98. }
  99.  
  100. //draw a bitmap object that is always facing you
  101. //returns 1 if off screen, 0 if drew
  102. void g3_draw_rod_tmap(grs_canvas &canvas, grs_bitmap &bitmap, const g3s_point &bot_point, fix bot_width, const g3s_point &top_point, fix top_width, g3s_lrgb light)
  103. {
  104.         rod_4point rod;
  105.         if (calc_rod_corners(rod,bot_point,bot_width,top_point,top_width))
  106.                 return;
  107.  
  108.         const fix average_light = static_cast<unsigned>(light.r+light.g+light.b)/3;
  109.         const std::array<g3s_uvl, 4> uvl_list{{
  110.                 { 0x0200, 0x0200, average_light },
  111.                 { 0xfe00, 0x0200, average_light },
  112.                 { 0xfe00, 0xfe00, average_light },
  113.                 { 0x0200, 0xfe00, average_light }
  114.         }};
  115.         const std::array<g3s_lrgb, 4> lrgb_list{{
  116.                 light,
  117.                 light,
  118.                 light,
  119.                 light,
  120.         }};
  121.  
  122.         g3_draw_tmap(canvas, rod.point_list, uvl_list, lrgb_list, bitmap);
  123. }
  124.  
  125. #if !DXX_USE_OGL
  126. //draws a bitmap with the specified 3d width & height
  127. //returns 1 if off screen, 0 if drew
  128. void g3_draw_bitmap(grs_canvas &canvas, const vms_vector &pos, fix width, fix height, grs_bitmap &bm)
  129. {
  130.         g3s_point pnt;
  131.         fix w,h;
  132.         if (g3_rotate_point(pnt,pos) & CC_BEHIND)
  133.                 return;
  134.         g3_project_point(pnt);
  135.         if (pnt.p3_flags & PF_OVERFLOW)
  136.                 return;
  137. #ifndef __powerc
  138.         fix t;
  139.         if (checkmuldiv(&t,width,Canv_w2,pnt.p3_z))
  140.                 w = fixmul(t,Matrix_scale.x);
  141.         else
  142.                 return;
  143.  
  144.         if (checkmuldiv(&t,height,Canv_h2,pnt.p3_z))
  145.                 h = fixmul(t,Matrix_scale.y);
  146.         else
  147.                 return;
  148. #else
  149.         if (pnt.p3_z == 0)
  150.                 return;
  151.         double fz = f2fl(pnt.p3_z);
  152.         w = fixmul(fl2f(((f2fl(width)*fCanv_w2) / fz)), Matrix_scale.x);
  153.         h = fixmul(fl2f(((f2fl(height)*fCanv_h2) / fz)), Matrix_scale.y);
  154. #endif
  155.         const fix blob0y = pnt.p3_sy - h, blob1x = pnt.p3_sx + w;
  156.         const std::array<grs_point, 3> blob_vertices{{
  157.                 {pnt.p3_sx - w, blob0y},
  158.                 {blob1x, blob0y},
  159.                 {blob1x, pnt.p3_sy + h},
  160.         }};
  161.         scale_bitmap(bm, blob_vertices, 0, canvas.cv_bitmap);
  162. }
  163. #endif
  164.  
  165.  
  166.  
  167. }
  168.