home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / Amiga / Jeux / demos / crystalPPC.lha / polygon.h < prev    next >
C/C++ Source or Header  |  1998-01-15  |  17KB  |  425 lines

  1. #ifndef POLYGON_H
  2. #define POLYGON_H
  3.  
  4. #ifndef DEF_H
  5. #include "def.h"
  6. #endif
  7.  
  8. #ifndef MATH3D_H
  9. #include "math3d.h"
  10. #endif
  11.  
  12. #ifndef POLYTEXT_H
  13. #include "polytext.h"
  14. #endif
  15.  
  16. #ifndef POLYSET_H
  17. #include "polyset.h"
  18. #endif
  19.  
  20. #ifndef VIEWPOLY_H
  21. #include "viewpoly.h"
  22. #endif
  23.  
  24. class Vertex;
  25. class Sector;
  26. class Light;
  27. class World;
  28. class Textures;
  29. class PolyPlane;
  30. class ViewPolygon;
  31. class Polygon2D;
  32. class LightMap;
  33. #if USE_OCCLUSION
  34. class Occlusion;
  35. #endif
  36.  
  37. // The maximum number of vertices that any polygon can have. This should
  38. // be considerably larger than what you expect to be the real maximum
  39. // number of vertices in a 3D polygon since clipping may add new vertices.
  40. // Note that 100 is probably overkill but this is no problem since there
  41. // are not going to be many of these Polygon2D objects anyway.
  42. #define MAX_VERTICES 100
  43.  
  44. // This is our main 3D polygon class. Polygons are used to construct the
  45. // outer hull of sectors and the faces of 3D things.
  46. // Polygons can be transformed in 3D (usually they are transformed so
  47. // that the camera position is at (0,0,0) and the Z-axis is forward).
  48. // Polygons cannot be transformed in 2D. That's what Polygon2D is for.
  49. // It is possible to convert a Polygon3D to a Polygon2D though, at
  50. // which point processing continues with the Polygon2D object.
  51. //
  52. // Polygons have a texture and lie on a plane. The plane does not
  53. // define the orientation of the polygon but is derived from it. The plane
  54. // does define how the texture is scaled and translated accross the surface
  55. // of the polygon.
  56. // Several planes can be shared for different polygons. As a result of this
  57. // their textures will be correctly aligned.
  58. //
  59. // If a polygon is part of a sector it can be a portal to another sector.
  60. // A portal-polygon is a see-through polygon that defines a view to another
  61. // sector. Normally the texture for a portal-polygon is not drawn unless
  62. // the texture is filtered in which case it is drawn on top of the other
  63. // sector.
  64.  
  65. class Polygon3D
  66. {
  67. private:
  68.   int* vertices_idx;    // A table of indices into the vertices of the parent PolygonSet (container).
  69.   int num_vertices;
  70.   int max_vertices;
  71.   char name[30];
  72.  
  73.   // The following two fields are somewhat related. 'poly_set' is the real
  74.   // parent (container) of this polygon. It is either a 3D thing or a sector.
  75.   // 'sector' is always a sector. If this polygon belongs to a sector ('poly_set'
  76.   // is a sector) then 'sector' will have the same value as 'poly_set'. If
  77.   // this polygon belongs to a thing then 'sector' will be set to the sector
  78.   // containing the thing.
  79.   // @@@ Note! We have to reconsider this. If a thing moves to another sector
  80.   // we would have to update this variable for all polygons of the thing.
  81.   PolygonSet* poly_set;    // Direct container of this polygon.
  82.   Sector* sector;    // Sector that this polygon is in.
  83.  
  84.   Sector* portal;    // If not-null, this polygon looks at that sector. In other
  85.               // words, this polygon is a portal.
  86.  
  87.   // If this polygon is a portal it possibly has a transformation matrix and
  88.   // vector to warp space in some way. This way mirrors can be implemented.
  89.   // @@@ Note, we should have some special place for date concerning portals
  90.   // so that not every polygon needs the following data (maybe use inheritance
  91.   // with virtual functions?).
  92.   // @@@ Note, space warping through portals is not functional yet!
  93.   int do_warp_space;    // If TRUE the space should be warped through the portal.
  94.   Matrix3 m_warp;    // Warp matrix.
  95.   Matrix3 m_warp_inv;
  96.   Vector3 v_warp;    // Warp vector.
  97.  
  98.   // The PolygonPlane for this polygon.
  99.   // If 'delete_plane' is TRUE this plane was allocated by
  100.   // this Polygon and it should also be deleted by it.
  101.   PolyPlane* plane;
  102.   int delete_plane;
  103.   PolyTexture* tex;    // The transformed texture for this polygon.
  104.   PolyTexture* tex1;    // A mipmapped texture: one step further.
  105.   PolyTexture* tex2;    // A mipmapped texture: two steps further.
  106.   PolyTexture* tex3;    // A mipmapped texture: three steps further.
  107.   LightMap* lightmap;    // The light-map for this polygon.
  108.   LightMap* lightmap1;    // The light-map for this polygon (mipmap level 1)
  109.   LightMap* lightmap2;    // The light-map for this polygon (mipmap level 2)
  110.   LightMap* lightmap3;    // The light-map for this polygon (mipmap level 3)
  111.  
  112.   // This flag indicates that we want no mipmapping for this polygon.
  113.   // This is useful for sky-textures (for example).
  114.   int no_mipmap;
  115.  
  116.   // This flag indicates that we want no lighting for this polygon.
  117.   int no_lighting;
  118.  
  119.   // This flag is used by the lighting routines to indicate that this
  120.   // polygon has already been lit by some light. It is used by 'shine'.
  121.   int shine_done;
  122.  
  123.   // The plane equation should maybe be part of PolyPlane. But currently it
  124.   // resides here:
  125.   float Ao, Bo, Co, Do;    // The object space plane equation (this is fixed).
  126.   float A, B, C, D;    // The world space plane equation.
  127.   float Ac, Bc, Cc, Dc;    // The camera space plane equation.
  128.  
  129. public:
  130.   Polygon3D (char* name, int max, Textures* textures, int texnr);
  131.   ~Polygon3D ();
  132.  
  133.   // Add a vertex from the container to the polygon.
  134.   void add_vertex (int v);
  135.  
  136.   char* get_name () { return name; }
  137.  
  138.   // Several maintenance functions.
  139.   void set_portal (Sector* portal) { Polygon3D::portal = portal; }
  140.   Sector* get_portal () { return portal; }
  141.   void set_poly_set (PolygonSet* poly_set) { Polygon3D::poly_set = poly_set; }
  142.   PolygonSet* get_poly_set () { return poly_set; }
  143.   Sector* get_sector () { return sector; }
  144.   void set_sector (Sector* sector) { Polygon3D::sector = sector; }
  145.  
  146.   PolyPlane* get_plane () { return plane; }
  147.  
  148.   int get_max_vertices () { return max_vertices; }
  149.   int get_num_vertices () { return num_vertices; }
  150.   int* get_vertices_idx () { return vertices_idx; }
  151.  
  152.   // Warp space (if this is a portal).
  153.   int is_space_warped () { return do_warp_space; }
  154.   void warp_space (Matrix3& m_w2c, Matrix3& m_c2w, Vector3& v_w2c);
  155.   void set_warp (Matrix3& m_w, Vector3& v_w);
  156.  
  157.   // 'idx' is a local index into the vertices table of the polygon.
  158.   // This index is translated to the index in the parent container and
  159.   // a reference to the vertex is returned.
  160.   Vertex& vtex (int idx) { return poly_set->vtex (vertices_idx[idx]); }
  161.  
  162.   // Set the texture number for this polygon.
  163.   void set_texnr (Textures* textures, int texnr);
  164.   int get_texnr () { return tex->get_texnr (); }
  165.   PolyTexture* get_polytex (int mipmap);
  166.   PolyTexture* get_polytex (float z_dist);
  167.   void set_no_lighting (int no) { no_lighting = no; }
  168.   void set_no_mipmap (int no) { no_mipmap = no; }
  169.   int get_no_lighting () { return no_lighting; }
  170.   int get_no_mipmap () { return no_mipmap; }
  171.  
  172.   // After the plane normal and the texture matrices have been set
  173.   // up this routine makes some needed pre-calculations for this polygon.
  174.   // It will create a texture space bounding box that
  175.   // is going to be used for lighting and the texture cache.
  176.   // Then it will allocate the light map tables for this polygons.
  177.   void precalculate ();
  178.  
  179.   // One of the set_texture_space functions should be called after
  180.   // adding all vertices to the polygon (not before) and before
  181.   // doing any processing on the polygon (not after)!
  182.   // It makes sure that the plane normal is correctly computed and
  183.   // the texture and plane are correctly initialized.
  184.   // 'precalculate ()' is called after that.
  185.   //
  186.   // Internally the transformation from 3D to texture space is
  187.   // represented by a matrix and a vector. You can supply this
  188.   // matrix directly or let it be calculated from other parameters.
  189.   // If you supply another Polygon or a PolyPlane to this function
  190.   // it will automatically share the plane.
  191.  
  192.   // Copy the plane from the other polygon. The plane is automatically shared.
  193.   void set_texture_space (Polygon3D* copy_from);
  194.  
  195.   // Use the given plane.
  196.   void set_texture_space (PolyPlane* plane);
  197.  
  198.   // Calculate the matrix using two vertices (which are preferably on the
  199.   // plane of the polygon and are possibly (but not necessarily) two vertices
  200.   // of the polygon). The first vertex is seen as the origin and the second
  201.   // as the u-axis of the texture space coordinate system. The v-axis is
  202.   // calculated on the plane of the polygon and orthogonal to the given
  203.   // u-axis. The length of the u-axis and the v-axis is given as the 'len1'
  204.   // parameter.
  205.   // For example, if 'len1' is equal to 2 this means that texture will
  206.   // be tiled exactly two times between vertex 'v_orig' and 'v1'.
  207.   // I hope this explanation is clear since I can't seem to make it
  208.   // any clearer :-)
  209.   void set_texture_space (Vertex& v_orig, Vertex& v1, float len1);
  210.   void set_texture_space (float xo, float yo, float zo,
  211.               float x1, float y1, float z1, float len1);
  212.  
  213.   // Use 'v1' and 'len1' for the u-axis and 'v2' and 'len2' for the
  214.   // v-axis. Otherwise this function is the same as the previous one.
  215.   void set_texture_space (Vertex& v_orig,
  216.                 Vertex& v1, float len1,
  217.                 Vertex& v2, float len2);
  218.   void set_texture_space (float xo, float yo, float zo,
  219.               float x1, float y1, float z1, float len1,
  220.               float x2, float y2, float z2, float len2);
  221.  
  222.   // Similar to the previous function but treat as if the lengths
  223.   // are set to 1.
  224.   void set_texture_space (Vertex& v_orig, Vertex& v_u, Vertex& v_v);
  225.   void set_texture_space (float xo, float yo, float zo,
  226.                 float xu, float yu, float zu,
  227.                 float xv, float yv, float zv);
  228.  
  229.   // The most general functions. With these you provide the matrix
  230.   // directly.
  231.   void set_texture_space (float xo, float yo, float zo,
  232.                 float xu, float yu, float zu,
  233.                 float xv, float yv, float zv,
  234.                 float xw, float yw, float zw);
  235.   void set_texture_space (Matrix3& tx_matrix, Vector3& tx_vector);
  236.  
  237.   // Shine a light on this polygon. If the polygon has already
  238.   // been lighted by this light ('shine_done' == TRUE) nothing
  239.   // will happen. Otherwise the light maps are initialized according
  240.   // to the distance of the light to the polygon and other parameters
  241.   // of the light.
  242.   void shine (Light* light);
  243.   void clear_shine_done () { shine_done = FALSE; }
  244.   void mipmap_settings (int setting);
  245.   LightMap* get_lightmap () { return lightmap; }
  246.  
  247.   // Setup a dynamic light for this polygon.
  248.   void setup_dyn_light (DynLight* light, float sq_dist);
  249.  
  250.   // Transform the plane of this polygon from object space to world space.
  251.   // This is mainly used for things since sectors currently have
  252.   // identical object and world space coordinates.
  253.   void object_to_world (Matrix3& m_o2w, Matrix3& m_w2o, Vector3& v_o2w);
  254.  
  255.   // Transform the plane normal of this polygon from object to world space.
  256.   void normal_object_to_world (Matrix3& m_o2w, Matrix3& m_w2o, Vector3& v_o2w);
  257.   void normal_world_to_camera (Matrix3& m_w2c, Matrix3& m_c2w, Vector3& v_w2c);
  258.  
  259.   // This is the link between Polygon3D and Polygon2D (see below for
  260.   // more info about Polygon2D). It should be used after the parent
  261.   // container has been transformed from world to camera space.
  262.   // It will fill the given Polygon2D with a perspective corrected
  263.   // polygon that is also clipped to the view plane (Z=SMALL_Z).
  264.   // If all vertices are behind the view plane the polygon will not
  265.   // be visible and it will return FALSE.
  266.   // 'do_perspective' will also do back-face culling and returns FALSE
  267.   // if the polygon is not visible because of this.
  268.   // If the polygon is deemed to be visible it will first transform
  269.   // the plane from world to camera space and return TRUE.
  270.   int do_perspective (Matrix3& m_w2c, Matrix3& m_c2w, Vector3& v_w2c, Polygon2D* dest);
  271.  
  272.   // Check if the polygon in world space is visible from the given point.
  273.   // To do this it will only do back-face culling. No other tests (like
  274.   // other polygons blocking this one) are performed.
  275.   int visible_from_point (Vector3& p);
  276.  
  277.   // Return POLY_IN, POLY_OUT, or POLY_ON for a vector with respect
  278.   // to the polygon.
  279.   // This algorithm assumes that the polygon is convex and that
  280.   // the vertices of the polygon are oriented in clockwise ordering.
  281.   // If this was not the case then the polygon should not be drawn (culled)
  282.   // and this routine would not be called for it.
  283.   int in_poly_3d (Vector3& vv);
  284.  
  285.   // Return the minimum squared distance from the plane of the polygon to
  286.   // a point in 3D space (using world coordinates).
  287.   float sq_distance (Vector3& v);
  288.  
  289.   // Return the closest point on the plane of the polygon to a point
  290.   // in 3D space (using world coordinates).
  291.   void closest_point (Vector3& v, Vector3& isect);
  292.  
  293.   // Return TRUE if this polygon and the given polygon are on the same
  294.   // plane. If their planes are shared this is automatically the case.
  295.   // Otherwise this function will check their respective plane equations
  296.   // to test for equality.
  297.   int same_plane (Polygon3D* p);
  298.  
  299.   // Return twice the signed area of the polygon in world space coordinates using
  300.   // the yz, zx, and xy components. In effect this calculates the (P,Q,R) or the
  301.   // plane normal of the polygon.
  302.   void PlaneNormal (float* yz, float* zx, float* xy);
  303.  
  304.   // Precompute the plane normal. Normally this is done automatically by
  305.   // set_texture_space by if needed you can call this function again when
  306.   // something has changed.
  307.   void compute_normal ();
  308.  
  309.   // Get the camera space normal as calculated by do_perspective.
  310.   void get_camera_normal (float* p_A, float* p_B, float* p_C, float* p_D);
  311.  
  312.   // Get the world space normal.
  313.   void get_world_normal (float* p_A, float* p_B, float* p_C, float* p_D);
  314.  
  315.   // Intersect world-space segment with this polygon. Return
  316.   // TRUE if it intersects and the intersection point in world coordinates.
  317.   int intersect_segment (Vector3& start, Vector3& end, Vector3& isect);
  318.  
  319.   void save (FILE* fp, int indent, Textures* textures);
  320.   void load (World* w, char** buf, Textures* textures, int default_texnr = -1,
  321.     float default_texlen = 1.);
  322.  
  323.   // Debugging dump of this polygon.
  324.   void dump ();
  325. };
  326.  
  327.  
  328. // The following class represents a 2D polygon (the 2D coordinates are
  329. // perspective corrected coordinates).
  330. //
  331. // This class is used as the main driver for the engine pipeline.
  332. // The source Polygon is first converted to 2D using Polygon3D::do_perspective.
  333.  
  334. class Polygon2D
  335. {
  336. private:
  337.   Vector2* vertices;        // The 2D vertices
  338.   int num_vertices;
  339.   int max_vertices;
  340.  
  341.   Box bbox;            // A 2D bounding box that is maintained automatically.
  342.  
  343. public:
  344.   static Polygon2D clipped;
  345.  
  346.   Polygon2D (int max);
  347.   Polygon2D (Polygon2D& copy);
  348.   ~Polygon2D ();
  349.  
  350.   // Initialize the Polygon2D to empty.
  351.   void make_empty ();
  352.  
  353.   // Maintenance functions.
  354.   int get_num_vertices () { return num_vertices; }
  355.   int get_max_vertices () { return max_vertices; }
  356.   Vector2* get_vertices () { return vertices; }
  357.  
  358.   // Add a vertex (2D) to the polygon
  359.   void add_vertex (Vector2& v) { add_vertex (v.x, v.y); }
  360.   void add_vertex (float x, float y);
  361.  
  362.   // Compute the perspective transformation of a 3D vertex and add it to the polygon.
  363.   void add_perspective (Vector3& v) { add_perspective (v.x, v.y, v.z); }
  364.   void add_perspective (float x, float y, float z);
  365.  
  366.   Box& get_bounding_box () { return bbox; }
  367.   int overlap_bounding_box (Box* box) { return bbox.overlap (box); }
  368.   int overlap_bounding_box (Polygon2D* poly) { return bbox.overlap (&poly->bbox); }
  369.  
  370. #if 0
  371.   // Rewrite using plane normals.
  372.  
  373.   // Given a perspective correct 2D point in screen space calculate the corresponding
  374.   // 3D (often camera) space point. This function is not efficient so it should not
  375.   // be used by the engine itself. Note that the polygon needs to be transformed to camera
  376.   // space but not clipped to the view.
  377.   void get_3d_point (Vector2& vs, Vector3& vc);
  378. #endif
  379.  
  380.   // Clipping routines. They return FALSE if they are not visible for some reason.
  381.   // Note that these routines must not be called if the polygon is not visible.
  382.   // These routines will not check that.
  383.   // @@@ Note that clip_poly is currently not used because of problems with
  384.   // special cases. I would prefer to use clip_poly instead of clip_poly_variant
  385.   // as I suspect the former to be faster. Please, can someone fix clip_poly?
  386.   int clip_poly (ViewPolygon* view, Polygon2D* dest, int verbose = FALSE)
  387.   {
  388.     (void)verbose;
  389.     return clip_poly (view->get_vertices (),
  390.            view->get_num_vertices (),
  391.            &view->get_bounding_box (),
  392.            dest);
  393.   }
  394.   int clip_poly (Vector2* Q, int m, Box* box, Polygon2D* dest);
  395.   void clip_poly_plane (Vector2& v1, Vector2& v2);
  396.   int clip_poly_variant (Vector2* Q, int m, Box* box);
  397.   int clip_poly_variant (ViewPolygon* view)
  398.   {
  399.     return clip_poly_variant (view->get_vertices (),
  400.                view->get_num_vertices (),
  401.                &view->get_bounding_box ());
  402.   }
  403.  
  404. #if USE_OCCLUSION
  405.   // Clip this 2D polygon to the occlusion object. This is a very
  406.   // approximate clipper that preserves convexity without having
  407.   // to split the polygon in seperate parts.
  408.   // This routine returns FALSE if the polygon is completely clipped
  409.   // away.
  410.   int clip_to_occlusion (Occlusion* o);
  411. #endif
  412.  
  413.   // Create a view polygon from this polygon. This is used for portals.
  414.   ViewPolygon* create_view ();
  415.  
  416.   // Draw the polygon.
  417.   void draw (int col);
  418.   void draw_filled (Polygon3D* poly, int use_z_buf = FALSE);
  419.  
  420.   // Debugging dump of this polygon.
  421.   void dump (char* name);
  422. };
  423.  
  424. #endif /*POLYGON_H*/
  425.