mirror of
https://github.com/OpenTrespasser/JurassicParkTrespasser.git
synced 2024-12-19 15:11:57 +00:00
286 lines
8.7 KiB
C++
286 lines
8.7 KiB
C++
/***********************************************************************************************
|
|
*
|
|
* Copyright © DreamWorks Interactive. 1996
|
|
*
|
|
* Contents:
|
|
* CClipPlane
|
|
*
|
|
* To do:
|
|
*
|
|
***********************************************************************************************
|
|
*
|
|
* $Log:: /JP2_PC/Source/Lib/Renderer/Clip.hpp $
|
|
*
|
|
* 9 98.08.13 4:26p Mmouni
|
|
* Changes for VC++ 5.0sp3 compatibility.
|
|
*
|
|
* 8 1/07/98 4:05p Pkeet
|
|
* Added the clip region function and globals.
|
|
*
|
|
* 7 12/23/97 1:55p Pkeet
|
|
* Added a parameter to use when splitting polygons to move the coordinate slightly outwards to
|
|
* avoid a crack due to T-junctions.
|
|
*
|
|
* 6 97/07/23 18:03 Speter
|
|
* Replaced CCamera argument to clipping functions with b_perspective flag. Added similar
|
|
* clipping functions for mesh polygons.
|
|
*
|
|
* 5 97/06/10 15:47 Speter
|
|
* Now takes camera as an argument (for new vertex projection).
|
|
*
|
|
* 4 97/05/23 6:24p Pkeet
|
|
* Untemplatized CPlaneDef.
|
|
*
|
|
* 3 97-04-21 17:26 Speter
|
|
* Totally rewrote CClipPlane interface, based more cleanly on templates, and inherited from
|
|
* CPlane. Removed InterpolateVertex(), now use SRenderVertex constructor.
|
|
*
|
|
* 1 97-04-14 20:41 Speter
|
|
* Contains code moved from GeomTypes.hpp.
|
|
*
|
|
**********************************************************************************************/
|
|
|
|
#ifndef HEADER_LIB_RENDERER_CLIP_HPP
|
|
#define HEADER_LIB_RENDERER_CLIP_HPP
|
|
|
|
#include "ScreenRender.hpp"
|
|
#include "PipelineHeap.hpp"
|
|
#include "Lib/GeomDBase/Plane.hpp"
|
|
#include "Lib/GeomDBase/Mesh.hpp"
|
|
|
|
//**********************************************************************************************
|
|
//
|
|
class CClipPlane
|
|
//
|
|
// Abstract class which provides plane clipping functions.
|
|
//
|
|
// Prefix: clp
|
|
//
|
|
//**************************************
|
|
{
|
|
public:
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual TReal rEdgeT
|
|
(
|
|
const CVector3<>& v3_0, // Vectors describing edge to intersect.
|
|
const CVector3<>& v3_1
|
|
) const = 0;
|
|
//
|
|
// Calculate the point of intersection between an edge and this plane.
|
|
//
|
|
// Returns:
|
|
// The parameter of the point of intersection between the edge and the bounding
|
|
// volume. (e.g this value will be 0 if the point of intersection falls at the
|
|
// starting point of the edge and 1 if it falls at the end point.)
|
|
//
|
|
// Cross-references:
|
|
// Invoked by bClipPolygon... functions, to create new vertices on the plane when
|
|
// clipping. Must be implemented by derived class.
|
|
//
|
|
//**********************************
|
|
|
|
//
|
|
// Clipping functions for CRenderPolygons.
|
|
//
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual ESideOf esfIntersectPolygon
|
|
(
|
|
CPArray<SRenderVertex*> paprv_poly, // Polygon to test, in this volume's space.
|
|
ESideOf aesf_sides[] // Array of ESideOf codes to set.
|
|
) const = 0;
|
|
//
|
|
// Calculates the side codes of each vertex, and stores them in the array.
|
|
//
|
|
// Returns:
|
|
// Where this polygon is in relation to the volume (the combination of the side codes
|
|
// of the vertices).
|
|
//
|
|
// Cross-references:
|
|
// Invoked by bClipPolygon... functions, where the array of side codes is used to clip
|
|
// the polygon if it intersects the plane. Must be implemented by derived class.
|
|
//
|
|
//**********************************
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual ESideOf esfClipPolygonInside
|
|
(
|
|
CRenderPolygon& rpoly, // The render polygon to clip.
|
|
CPipelineHeap& plh, // The heap object to allocate new vertices on.
|
|
bool b_perspective = true // Whether to interpolate the screen coords as projected.
|
|
) const;
|
|
//
|
|
// Clips the polygon against this volume. If the polygon intersects the boundary of the
|
|
// volume, this function converts it to a new polygon lying entirely inside the volume.
|
|
// Otherwise (it is entirely inside or outside the volume), it leaves it unchanged.
|
|
//
|
|
// Returns:
|
|
// The side code of the original polygon. If esfOUTSIDE or esfINSIDE, the polygon
|
|
// is unchanged; if esfINTERSECT, it was clipped, and is now inside the plane.
|
|
//
|
|
//**********************************
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual ESideOf esfSplitPolygon
|
|
(
|
|
CRenderPolygon& rpoly, // The render polygon to split.
|
|
CPipelineHeap& plh, // The heap object to allocate new objects on.
|
|
bool b_perspective = true, // Whether to interpolate the screen coords as projected.
|
|
CRenderPolygon** pprpoly_out = 0, // Returns the outside polygon, if split.
|
|
float f_adjust_out = 0.0f
|
|
) const;
|
|
//
|
|
// Splits the polygon by this plane, if it intersects: the original polygon is converted
|
|
// to one lying inside the plane; a new polygon is created on the pipeline heap, lying
|
|
// outside the plane. If the polygon does not intersect the plane, nothing happens.
|
|
//
|
|
// Returns:
|
|
// The intersection code of the polygon; if esfINTERSECT, it was split.
|
|
//
|
|
//**********************************
|
|
|
|
//
|
|
// Similar functions for CMesh::SPolygons.
|
|
//
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual ESideOf esfIntersectPolygonMesh
|
|
(
|
|
CPArray<CMesh::SVertex*> papmv_poly, // Polygon to test, in this volume's space.
|
|
ESideOf aesf_sides[] // Array of ESideOf codes to set.
|
|
) const = 0;
|
|
//
|
|
//**********************************
|
|
|
|
//******************************************************************************************
|
|
//
|
|
virtual ESideOf esfClipPolygon
|
|
(
|
|
CMesh::SPolygon& mp, // The mesh polygon to clip.
|
|
CMesh::CHeap& mh, // Where to allocate new mesh data.
|
|
ESideOf esf_sides // Which sides to keep: esfINSIDE or esfOUTSIDE;
|
|
// if both, creates the outside polygon on the heap.
|
|
) const;
|
|
//
|
|
//**********************************
|
|
};
|
|
|
|
//**********************************************************************************************
|
|
//
|
|
template<class P> class CClipPlaneT : public CClipPlane, public CPlaneT<P>
|
|
//
|
|
// Implements CClipPlane by extending a CPlaneT<P>.
|
|
//
|
|
//**************************************
|
|
{
|
|
public:
|
|
|
|
//******************************************************************************************
|
|
//
|
|
// Constructors.
|
|
//
|
|
|
|
// Use plane's default constructor.
|
|
CClipPlaneT()
|
|
{
|
|
}
|
|
|
|
// Initialise with a plane object.
|
|
CClipPlaneT(const P& p)
|
|
: CPlaneT<P>(p)
|
|
{
|
|
}
|
|
|
|
//******************************************************************************************
|
|
TReal rEdgeT(const CVector3<>& v3_0, const CVector3<>& v3_1) const
|
|
{
|
|
// Implemented with rDistance().
|
|
TReal r_0 = rDistance(v3_0);
|
|
TReal r_1 = rDistance(v3_1);
|
|
return r_0 / (r_0 - r_1);
|
|
}
|
|
|
|
//******************************************************************************************
|
|
virtual ESideOf esfIntersectPolygon(CPArray<SRenderVertex*> paprv_poly, ESideOf aesf_sides[]) const
|
|
{
|
|
// Return combination of all points. Use esfSideOf, to return esfON when appropriate,
|
|
// for storage in array.
|
|
ESideOf esf = esfON;
|
|
|
|
for (uint u = 0; u < paprv_poly.uLen; u++)
|
|
{
|
|
aesf_sides[u] = esfSideOf(paprv_poly[u]->v3Cam);
|
|
esf |= aesf_sides[u];
|
|
}
|
|
return esf;
|
|
}
|
|
|
|
//******************************************************************************************
|
|
virtual ESideOf esfIntersectPolygonMesh(CPArray<CMesh::SVertex*> papmv_poly, ESideOf aesf_sides[]) const
|
|
{
|
|
// Return combination of all points. Use esfSideOf, to return esfON when appropriate,
|
|
// for storage in array.
|
|
ESideOf esf = esfON;
|
|
|
|
for (uint u = 0; u < papmv_poly.uLen; u++)
|
|
{
|
|
aesf_sides[u] = esfSideOf(*papmv_poly[u]->pv3Point);
|
|
esf |= aesf_sides[u];
|
|
}
|
|
return esf;
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// Typedefs for general purpose plane classes
|
|
//
|
|
|
|
typedef CClipPlaneT<CPlaneDef> CClipPlaneGeneral;
|
|
|
|
//**********************************************************************************************
|
|
//
|
|
class CClipPlaneTolerance: public CClipPlaneT<CPlaneDefTolerance>
|
|
//
|
|
// Inherit rather than typedef, to add a convenient constructor.
|
|
//
|
|
//**************************************
|
|
{
|
|
public:
|
|
|
|
//******************************************************************************************
|
|
//
|
|
// Constructors.
|
|
//
|
|
|
|
// Use plane's default constructor.
|
|
CClipPlaneTolerance(const CPlane& pl, TReal r_tolerance = fPLANE_TOLERANCE)
|
|
: CClipPlaneT<CPlaneDefTolerance>(CPlaneTolerance(pl, r_tolerance))
|
|
{
|
|
}
|
|
};
|
|
|
|
|
|
//**********************************************************************************************
|
|
//
|
|
void SetClipRegion
|
|
(
|
|
float f_x_0,
|
|
float f_y_0,
|
|
float f_x_1,
|
|
float f_y_1
|
|
);
|
|
//
|
|
// Sets the clip region globally. Currently the clip region is only used for polygons "grown" by
|
|
// the depth sort.
|
|
//
|
|
//**************************************
|
|
|
|
#endif
|