EngPoly.cpp
上传用户:lhwx1029
上传日期:2013-03-07
资源大小:1173k
文件大小:22k
源码类别:

3D图形编程

开发平台:

Visual C++

  1. /** 3DGPL *************************************************
  2.  * ()                                                     *
  3.  * Functions for polygonal objects.                       *
  4.  *                                                        *
  5.  * Ifdefs:                                                *
  6.  *  _CI_                     Colour/Intensity model;      *
  7.  *  _RGB_                    RGB model;                   *
  8.  *  _Z_BUFFER_               Depth array;                 *
  9.  *  _PAINTER_                Back to front rendering.     *
  10.  *                                                        *
  11.  * Defines:                                               *
  12.  *  M_init_polygon_object    Compute BSP tree and normals;*
  13.  *  M_shade_polygon_object   Shadings using normals;      *
  14.  *  M_render_polygon_object  Renders a polygonal solid.   *
  15.  *                                                        *
  16.  * Internals:                                             *
  17.  *  MI_add_tuple             A result of a split;         *
  18.  *  MI_split_polygon         Called after a split;        *
  19.  *  MI_order_polygons        Creating one BSP tree node;  *
  20.  *  MI_render_polygons       Rendering polygons in order. *
  21.  *                                                        *
  22.  * (c) 1995-98 Sergei Savchenko, (savs@cs.mcgill.ca)      *
  23. **********************************************************/
  24. #include "RayTracing.h"           /* HW_copy_ints */
  25. #include "Graphics.h"           /* 2-D rendering */
  26. #include "Trans.h"                 /* 3-D transformations */
  27. #include "Clipper.h"             /* xyz clipping */
  28. #include "Engine.h"               /* 3-D engine */
  29. #include "Colour.h"               /* light related */
  30. #include <stdlib.h>                         /* NULL */
  31. int M_no_polygons;                          /* used in bsp tree building */
  32. struct M_polygon **M_polygons;              /* static polygons */
  33. int M_no_vertices;
  34. int *M_vertices;                            /* static vertices X Y Z */
  35. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  36.  * INTERNAL: Finding an index to a vertex.               *
  37.  * ---------                                             *
  38.  * RETURNS: Index the passed vertex in the array.        *
  39.  * --------                                              *
  40. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  41. int MI_add_tuple(int *vertex)
  42. {
  43.  int i;
  44.  for(i=0;i<M_no_vertices;i++)               /* comparing X Y Z only */
  45.  {
  46.   if((M_vertices[i*T_LNG_VECTOR]==vertex[0])&&
  47.      (M_vertices[i*T_LNG_VECTOR+1]==vertex[1])&&
  48.      (M_vertices[i*T_LNG_VECTOR+2]==vertex[2])
  49.     ) return(i);
  50.  }
  51.  if(i>=M_MAX_OBJECT_VERTICES)
  52.   HW_error("(Engine) Not enough internal storage for vertices.n");
  53.                                             /* X Y Z to one Tx Ty to another */
  54.  HW_copy_int(vertex,M_vertices+M_no_vertices*T_LNG_VECTOR,3);
  55.  return(M_no_vertices++);                   /* index of where inserted */
  56. }
  57. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  58.  * INTERNAL: Called after a split has occured.           *
  59.  * ---------                                             *
  60. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  61. void MI_split_polygon(struct M_polygon *root,struct M_polygon *old,
  62.                       struct M_polygon *new1,struct M_polygon *new2
  63.                      )
  64. {
  65.  int tmp1[M_MAX_POLYGON_VERTICES*M_LNG_POLYGON_VERTEX];
  66.  int tmp2[M_MAX_POLYGON_VERTICES*M_LNG_POLYGON_VERTEX];
  67.  int i;
  68.  for(i=0;i<=old->m_no_edges;i++)
  69.  {
  70.   HW_copy_int(M_vertices+old->m_vertices[i*M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  71.               tmp1+i*5,3
  72.              );                             /* X Y Z */
  73.   HW_copy_int(old->m_vertices+i*M_LNG_POLYGON_VERTEX+M_IDX_POLYGON_TEXTURE,
  74.               tmp1+i*5+3,2
  75.              );                             /* Tx Ty */
  76.  }
  77.  new1->m_type=old->m_type&M_NOT_QUAD;       /* can't be any longer M_QUAD */
  78.  new1->m_colour=old->m_colour;
  79. #if defined(_CI_)
  80.  new1->m_intensity=old->m_intensity;        /* I */
  81. #endif
  82. #if defined(_RGB_)
  83.  new1->m_red=old->m_red;                    /* R G B */
  84.  new1->m_green=old->m_green;
  85.  new1->m_blue=old->m_blue;
  86. #endif
  87.  new1->m_log_texture_space_size=old->m_log_texture_space_size;
  88.  new1->m_texture=old->m_texture;
  89.  new1->m_no_edges=
  90.   C_polygon_xyz_clipping(tmp1,tmp2,
  91.                          M_vertices+root->m_vertices[0]*T_LNG_VECTOR,
  92.                          M_vertices+root->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  93.                          M_vertices+root->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  94.                          5,old->m_no_edges
  95.                         );                  /* 5 == X Y Z Tx Ty */
  96.  new1->m_vertices=(int*)malloc(sizeof(int)*(new1->m_no_edges+1)*M_LNG_POLYGON_VERTEX);
  97.  if(new1->m_vertices==NULL) HW_error("(Engine) Not enough memory.n");
  98.  for(i=0;i<=new1->m_no_edges;i++)           /* back into indexing */
  99.  {                                          /* getting vertex Index */
  100.   new1->m_vertices[i*M_LNG_POLYGON_VERTEX]=MI_add_tuple(tmp2+i*5);
  101.   HW_copy_int(tmp2+i*5+3,new1->m_vertices+i*M_LNG_POLYGON_VERTEX+M_IDX_POLYGON_TEXTURE,2);
  102.  }                                          /* getting Tx Ty */
  103.  new2->m_type=old->m_type&M_NOT_QUAD;       /* can't be any longer */
  104.  new2->m_colour=old->m_colour;
  105. #if defined(_CI_)
  106.  new2->m_intensity=old->m_intensity;
  107. #endif
  108. #if defined(_RGB_)
  109.  new2->m_red=old->m_red;
  110.  new2->m_green=old->m_green;
  111.  new2->m_blue=old->m_blue;
  112. #endif
  113.  new2->m_log_texture_space_size=old->m_log_texture_space_size;
  114.  new2->m_texture=old->m_texture;
  115.  new2->m_no_edges=
  116.   C_polygon_xyz_clipping(tmp1,tmp2,
  117.                          M_vertices+root->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  118.                          M_vertices+root->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  119.                          M_vertices+root->m_vertices[0]*T_LNG_VECTOR,
  120.                          5,old->m_no_edges
  121.                         );                  /* 5 == X Y Z Tx Ty */
  122.  new2->m_vertices=(int*)malloc(sizeof(int)*(new2->m_no_edges+1)*M_LNG_POLYGON_VERTEX);
  123.  if(new2->m_vertices==NULL) HW_error("(Engine) Not enough memory.n");
  124.  for(i=0;i<=new2->m_no_edges;i++)           /* back into indexing */
  125.  {                                          /* getting Indx Tx Ty */
  126.   new2->m_vertices[i*M_LNG_POLYGON_VERTEX]=MI_add_tuple(tmp2+i*5);
  127.   HW_copy_int(tmp2+i*5+3,new2->m_vertices+i*M_LNG_POLYGON_VERTEX+M_IDX_POLYGON_TEXTURE,2);
  128.  }                                          /* from X Y Z [I]|[RGB] Tx Ty */
  129.  for(i=0;i<M_no_polygons;i++)
  130.  {
  131.   if(M_polygons[i]==old)                    /* searching for the one to kill */
  132.   {
  133.    free(M_polygons[i]->m_vertices);         /* killing the old one */
  134.    free(M_polygons[i]);
  135.    M_polygons[i]=new1;                      /* puting pointer to a new one */
  136.    break;
  137.   }
  138.  }
  139.  if(M_no_polygons>=M_MAX_OBJECT_POLYGONS)
  140.   HW_error("(Engine) Can't handle this many polygons.");
  141.  M_polygons[M_no_polygons++]=new2;          /* split produced two polygons */
  142. }
  143. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  144.  * INTERNAL: Creates a BSP tree order node.              *
  145.  * ---------                                             *
  146.  * RECURSIVE: Calls itself twice.                        *
  147.  * ----------                                            *
  148.  * RETURNS: Pointer to a created order structure.        *
  149.  * --------                                              *
  150.  * Minimizes on number of splits and secondary on        *
  151.  * disbalance in nodes.                                  *
  152. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  153. struct M_polygon_object_order *MI_order_polygons(struct M_polygon **polygons,
  154.                                                  int no_polygons
  155.                                                 )
  156. {
  157.  struct M_polygon *new1,*new2;              /* for splits */
  158.  struct M_polygon_object_order *tmp;
  159.  struct M_polygon *positive[M_MAX_OBJECT_POLYGONS];
  160.  struct M_polygon *negative[M_MAX_OBJECT_POLYGONS];
  161.  static int indices[M_MAX_OBJECT_POLYGONS]; /* static for the recursion sake */
  162.  static int balances[M_MAX_OBJECT_POLYGONS];
  163.  static int splits[M_MAX_OBJECT_POLYGONS];
  164.  static int plane[4];                       /* coefs of a plane equation */
  165.  int i,j,k,l,balance,bbal=0,split,itmp,no_positive=0,no_negative=0;
  166.  if(no_polygons==0) return(NULL);           /* base case */
  167.  for(i=0;i<no_polygons;i++) { indices[i]=i; balances[i]=0; splits[i]=0; }
  168.  for(i=0;i<no_polygons;i++)                 /* calculate balance and splits */
  169.  {
  170.   T_plane(M_vertices+polygons[i]->m_vertices[0]*T_LNG_VECTOR,
  171.           M_vertices+polygons[i]->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  172.           M_vertices+polygons[i]->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  173.           plane
  174.          );
  175.   for(j=0;j<no_polygons;j++)                /* for all polygons */
  176.   {
  177.    if(i==j) continue;                       /* not for the 1 assumed in root */
  178.    for(k=0,balance=0,split=0;k<polygons[j]->m_no_edges;k++)
  179.    {
  180.     for(l=0;l<polygons[i]->m_no_edges;l++)  /* check shared vertices directly */
  181.      if(polygons[i]->m_vertices[l*M_LNG_POLYGON_VERTEX]==
  182.         polygons[j]->m_vertices[k*M_LNG_POLYGON_VERTEX]) { bbal=0; break; }
  183.     if(l==polygons[i]->m_no_edges)          /* if not shared */
  184.      bbal=T_vertex_on_plane(M_vertices+     /* check plane equation */
  185.                             polygons[j]->m_vertices[k*M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  186.                             plane
  187.                            );
  188.     if(bbal==0) continue;                   /* ignore those on the plane */
  189.     if(bbal>0) bbal=1; else bbal=-1;
  190.     if(balance==0) balance=bbal;            /* initial point */
  191.     else                                    /* other then initial point */
  192.     {
  193.      if(balance!=bbal) { split=1; balance=0; break; }
  194.     }
  195.    }
  196.    balances[i]+=balance;                    /* parameters assuming i in root */
  197.    splits[i]+=split;
  198.   }
  199.  }                                          /* balances and splits found */
  200.  for(i=0;i<no_polygons;i++) balances[i]=abs(balances[i]);
  201.  for(i=no_polygons-1;i>0;i--)               /* sorting seeking best balance */
  202.  {
  203.   for(j=0;j<i;j++)
  204.   {
  205.    if(balances[j]>balances[j+1])            /* to have least first */
  206.    {
  207.     itmp=balances[j]; balances[j]=balances[j+1]; balances[j+1]=itmp;
  208.     itmp=indices[j]; indices[j]=indices[j+1]; indices[j+1]=itmp;
  209.     itmp=splits[j]; splits[j]=splits[j+1]; splits[j+1]=itmp;
  210.    }
  211.   }
  212.  }
  213.  for(i=no_polygons-1;i>0;i--)               /* sorting seeking less splits */
  214.  {
  215.   for(j=0;j<i;j++)
  216.   {
  217.    if(splits[j]>splits[j+1])                /* to have least first */
  218.    {
  219.     itmp=balances[j]; balances[j]=balances[j+1]; balances[j+1]=itmp;
  220.     itmp=indices[j]; indices[j]=indices[j+1]; indices[j+1]=itmp;
  221.     itmp=splits[j]; splits[j]=splits[j+1]; splits[j+1]=itmp;
  222.    }
  223.   }
  224.  }
  225.  tmp=(struct M_polygon_object_order*)
  226.       malloc(sizeof(struct M_polygon_object_order));
  227.  if(tmp==NULL) HW_error("(Engine) Not enough memory.n");
  228.  tmp->m_root=polygons[indices[0]];          /* the one which is best */
  229.  T_plane(M_vertices+tmp->m_root->m_vertices[0]*T_LNG_VECTOR,
  230.          M_vertices+tmp->m_root->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  231.          M_vertices+tmp->m_root->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  232.          plane
  233.         );                                  /* plane equation for the root */
  234.  for(i=0;i<no_polygons;i++)
  235.  {
  236.   if(tmp->m_root==polygons[i]) continue;    /* not for the 1 in the root */
  237.   for(j=0,balance=0,split=0;j<polygons[i]->m_no_edges;j++)
  238.   {
  239.    for(l=0;l<tmp->m_root->m_no_edges;l++)   /* check shared vertices directly */
  240.     if(tmp->m_root->m_vertices[l*M_LNG_POLYGON_VERTEX]==
  241.        polygons[i]->m_vertices[j*M_LNG_POLYGON_VERTEX]) { bbal=0; break; }
  242.    if(l==tmp->m_root->m_no_edges)           /* if not shared */
  243.     bbal=T_vertex_on_plane(M_vertices+
  244.                            polygons[i]->m_vertices[j*M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  245.                            plane
  246.                           );
  247.    if(bbal==0) continue;                    /* ignore those on the plane */
  248.    if(bbal>0) bbal=1; else bbal=-1;
  249.    if(balance==0) balance=bbal;             /* initial point */
  250.    else if(balance!=bbal) { split=1; balance=0; break; }
  251.   }
  252.   if(split)                                 /* what to do to a polygon */
  253.   {
  254.    new1=(struct M_polygon*)malloc(sizeof(struct M_polygon));
  255.    new2=(struct M_polygon*)malloc(sizeof(struct M_polygon));
  256.    if((new1==NULL)||(new2==NULL)) HW_error("(Fatal) Not enough memory.n");
  257.    MI_split_polygon(tmp->m_root,polygons[i],new1,new2);
  258.    if((no_positive>=M_MAX_OBJECT_POLYGONS)||(no_negative>=M_MAX_OBJECT_POLYGONS))
  259.     HW_error("(Fatal) Not enoght internal storage for polygons.n");
  260.    positive[no_positive++]=new1;
  261.    negative[no_negative++]=new2;
  262.   }
  263.   else
  264.   {
  265.    if(balance>0)                            /* entirely in subspaces */
  266.    {
  267.     if(no_positive>=M_MAX_OBJECT_POLYGONS)
  268.      HW_error("(Fatal) Not enoght internal storage for polygons.n");
  269.     positive[no_positive++]=polygons[i];
  270.    }
  271.    else
  272.    {
  273.     if(no_negative>=M_MAX_OBJECT_POLYGONS)
  274.      HW_error("(Fatal) Not enoght internal storage for polygons.n");
  275.     negative[no_negative++]=polygons[i];
  276.    }
  277.   }
  278.  }                                          /* constructing subspaces */
  279.  tmp->m_positive=MI_order_polygons(positive,no_positive);
  280.  tmp->m_negative=MI_order_polygons(negative,no_negative);
  281.  return(tmp);
  282. }
  283. /* * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  284.  * INTERNAL: Renders polygons in order.                  *
  285.  * ---------                                             *
  286.  * RECURSIVE: Calls itself twice.                        *
  287.  * ----------                                            *
  288. * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
  289. void MI_render_polygons(struct M_polygon_object_order *order,
  290.                         int *vertices
  291.                        )
  292. {
  293.  int plane[4];
  294.  if(order!=NULL)                            /* base case */
  295.  {
  296.   T_plane(vertices+order->m_root->m_vertices[0]*T_LNG_VECTOR,
  297.           vertices+order->m_root->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  298.           vertices+order->m_root->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  299.           plane
  300.          );                                 /* happens in the view space */
  301.   if(plane[3]>0)                            /* viewer is at (0,0,0) */
  302.   {                                         /* direct order of sub-spaces */
  303.    MI_render_polygons(order->m_negative,vertices);
  304.    M_render_polygon(order->m_root,vertices,NULL,NULL);
  305.    MI_render_polygons(order->m_positive,vertices);
  306.   }
  307.   else                                      /* reversed order of sub spaces */
  308.   {
  309.    MI_render_polygons(order->m_positive,vertices);
  310.    M_render_polygon(order->m_root,vertices,NULL,NULL);
  311.    MI_render_polygons(order->m_negative,vertices);
  312.   }
  313.  }
  314. }
  315. /**********************************************************
  316.  * Constructing a BSP tree for a polygonal object, and    *
  317.  * computing the normals.                                 *
  318. **********************************************************/
  319. void M_init_polygon_object(struct M_polygon_object *object)
  320. {
  321.  int tmp_normals[M_MAX_OBJECT_VERTICES*T_LNG_VECTOR];
  322.  int normals[M_MAX_OBJECT_VERTICES*T_LNG_VECTOR];
  323.  int i,j,k,n[5],num,norm_idx;
  324. #if defined(_PAINTER_)
  325.  int tmp_vertices[M_MAX_OBJECT_VERTICES*M_LNG_POLYGON_VERTEX];
  326.  struct M_polygon *tmp_polygons[M_MAX_OBJECT_POLYGONS];
  327.  for(i=0;i<object->m_no_polygons;i++) tmp_polygons[i]=object->m_polygons[i];
  328.  HW_copy_int(object->m_vertices,tmp_vertices,
  329.              object->m_no_vertices*T_LNG_VECTOR
  330.             );
  331.  M_polygons=tmp_polygons; M_no_polygons=object->m_no_polygons;
  332.  M_vertices=tmp_vertices; M_no_vertices=object->m_no_vertices;
  333.  object->m_order=MI_order_polygons(object->m_polygons,object->m_no_polygons);
  334.  free(object->m_polygons);                  /* number of polygons/vertices */
  335.  free(object->m_vertices);                  /* was likely to change anyway */
  336.  object->m_polygons=(struct M_polygon**)malloc(sizeof(struct M_polygon*)*
  337.                                                M_no_polygons
  338.                                               );
  339.  object->m_vertices=(int*)malloc(sizeof(int)*M_no_vertices*T_LNG_VECTOR);
  340.  if((object->m_polygons==NULL)||(object->m_vertices==NULL))
  341.   HW_error("(Engine) Not enough memory.n");
  342.  for(i=0;i<M_no_polygons;i++) object->m_polygons[i]=tmp_polygons[i];
  343.  HW_copy_int(M_vertices,object->m_vertices,M_no_vertices*T_LNG_VECTOR);
  344.  object->m_no_polygons=M_no_polygons;       /* new numbers */
  345.  object->m_no_vertices=M_no_vertices;
  346. #endif
  347.  M_vertices=tmp_normals; M_no_vertices=0;   /* nothing added yet */
  348.  for(i=0;i<object->m_no_polygons;i++)       /* for all polygons */
  349.  {
  350.   T_normal_plane(object->m_vertices+object->m_polygons[i]->m_vertices[0]*T_LNG_VECTOR,
  351.                  object->m_vertices+object->m_polygons[i]->m_vertices[M_LNG_POLYGON_VERTEX]*T_LNG_VECTOR,
  352.                  object->m_vertices+object->m_polygons[i]->m_vertices[M_LNG_POLYGON_VERTEX*2]*T_LNG_VECTOR,
  353.                  normals+i*T_LNG_VECTOR
  354.                 );
  355.   if(object->m_polygons[i]->m_type&M_PLANNAR)
  356.   {                                         /* same normal in flat polygons */
  357.    object->m_polygons[i]->m_normals=(int*)malloc(sizeof(int)*(object->m_polygons[i]->m_no_edges+1));
  358.    if(object->m_polygons[i]->m_normals==NULL)
  359.     HW_error("(Engine) Not enough memory.n");
  360.    object->m_polygons[i]->m_normals[0]=MI_add_tuple(normals+i*T_LNG_VECTOR);
  361.    for(j=1;j<=object->m_polygons[i]->m_no_edges;j++)
  362.     object->m_polygons[i]->m_normals[j]=object->m_polygons[i]->m_normals[0];
  363.   }
  364.  }
  365.  for(i=0;i<object->m_no_vertices;i++)       /* for all vertices */
  366.  {
  367.   n[0]=n[1]=n[2]=0;
  368.   for(num=0,j=0;j<object->m_no_polygons;j++)/* check all polygons which */
  369.   {
  370.    if(object->m_polygons[j]->m_type&M_CURVED)
  371.    {                                        /* emulate curved surfaces */
  372.     if(object->m_polygons[j]->m_normals==NULL)
  373.     {
  374.      object->m_polygons[j]->m_normals=(int*)malloc(sizeof(int)*(object->m_polygons[j]->m_no_edges+1));
  375.      if(object->m_polygons[j]->m_normals==NULL)
  376.       HW_error("(Engine) Not enough memory.n");
  377.      HW_set_int(object->m_polygons[j]->m_normals,object->m_polygons[j]->m_no_edges+1,0);
  378.     }
  379.     for(k=0;k<=object->m_polygons[j]->m_no_edges;k++)
  380.     {
  381.      if(object->m_polygons[j]->m_vertices[k*M_LNG_POLYGON_VERTEX]==i)
  382.      {                                      /* if the vertex belong to it */
  383.       object->m_polygons[j]->m_normals[k]=-1;
  384.       n[0]+=normals[j*T_LNG_VECTOR];        /* mark the normal */
  385.       n[1]+=normals[j*T_LNG_VECTOR+1];      /* polygon's normal */
  386.       n[2]+=normals[j*T_LNG_VECTOR+2];
  387.       num++;
  388.      }
  389.     }
  390.    }
  391.   }
  392.   if(num!=0)                                /* for curved only */
  393.   {
  394.    n[0]/=num; n[1]/=num; n[2]/=num;
  395.    norm_idx=MI_add_tuple(n);
  396.    for(j=0;j<object->m_no_polygons;j++)
  397.    {
  398.     if(object->m_polygons[j]->m_type&M_CURVED)
  399.     {                                        /* emulate curved surfaces */
  400.      for(k=0;k<=object->m_polygons[j]->m_no_edges;k++)
  401.      {
  402.       if(object->m_polygons[j]->m_normals[k]==-1)
  403.        object->m_polygons[j]->m_normals[k]=norm_idx;
  404.      }
  405.     }
  406.    }
  407.   }
  408.  }
  409.  object->m_normals=(int*)malloc(sizeof(int)*M_no_vertices*T_LNG_VECTOR);
  410.  object->m_no_normals=M_no_vertices;        /* store the normals */
  411.  HW_copy_int(M_vertices,object->m_normals,M_no_vertices*T_LNG_VECTOR);
  412. }
  413. /**********************************************************
  414.  * Shading a polygonal shape, setting both flat and       *
  415.  * interpolative intensities.                             *
  416. **********************************************************/
  417. void M_shade_polygon_object(struct M_polygon_object *object,
  418.                             int x,int y,int z,
  419.                             int alp,int bet,int gam,
  420.                             int no_lights,
  421.                             struct M_light **lights
  422.                            )
  423. {
  424.  int i;
  425.  int tmp_vertices[M_MAX_OBJECT_VERTICES*M_LNG_POLYGON_VERTEX];
  426.  int tmp_normals[M_MAX_OBJECT_VERTICES*M_LNG_POLYGON_VERTEX];
  427.  T_set_self_rotation(alp,bet,gam);          /* shading happens in world space */
  428.  T_self_rotation(object->m_normals,tmp_normals,object->m_no_normals);
  429.  T_self_rotation(object->m_vertices,tmp_vertices,object->m_no_vertices);
  430.  T_translation(tmp_vertices,tmp_vertices,object->m_no_vertices,x,y,z);
  431.  if((object->m_no_vertices>M_MAX_OBJECT_VERTICES)||
  432.     (object->m_no_normals>M_MAX_OBJECT_VERTICES)
  433.    )
  434.   HW_error("(Engine) Can't handle this many vertices or normals in polygons.");
  435.  for(i=0;i<object->m_no_polygons;i++)
  436.  {
  437.   M_shade_polygon(object->m_polygons[i],tmp_vertices,tmp_normals,
  438.                   no_lights,lights
  439.                  );
  440.  }
  441. }
  442. /**********************************************************
  443.  * Rendering a generic polygonal shape in perspective.    *
  444. **********************************************************/
  445. void M_render_polygon_object(struct M_polygon_object *object,
  446.                              int x,int y,int z,
  447.                              int alp,int bet,int gam
  448.                             )
  449. {
  450.  int tmp_vertices[M_MAX_OBJECT_VERTICES*M_LNG_POLYGON_VERTEX];
  451.  int i;
  452.  if(object->m_no_vertices>=M_MAX_OBJECT_VERTICES)
  453.   HW_error("(Engine) Can't handle this many vertices in polygons.");
  454.  T_set_self_rotation(alp,bet,gam);          /* transformations */
  455.  T_cancatinate_self_world(x+M_camera_x,y+M_camera_y,z+M_camera_z);
  456.  T_cancatinated_rotation(object->m_vertices,tmp_vertices,object->m_no_vertices);
  457.  if(object->m_order!=NULL)                  /* when order struct exists */
  458.  {
  459.   MI_render_polygons(object->m_order,tmp_vertices);
  460.  }
  461.  else                                       /* just rendering all polygons */
  462.  {                                          /* if no BSP tree structure */
  463.   for(i=0;i<object->m_no_polygons;i++)
  464.   {
  465.    M_render_polygon(object->m_polygons[i],tmp_vertices,NULL,NULL);
  466.   }
  467.  }
  468. }
  469. /**********************************************************/