Files
FC1/ResourceCompilerPC/StencilShadowConnectivityBuilder.h
romkazvo 34d6c5d489 123
2023-08-07 19:29:24 +08:00

210 lines
8.4 KiB
C++

//////////////////////////////////////////////////////////////////////
//
// CryEngine Source code
//
// File:StencilShadowConnectivityBuilder.h
// Declaration of class CStencilShadowConnectivityBuilder
//
// History:
// -:Created by Sergiy Migdalskiy <sergiy@crytek.de>
//
//////////////////////////////////////////////////////////////////////
// class CStencilShadowConnectivityBuilder
//
// This class is used to pre-compute the data for a model that's gonna cast stencil
// shadows, and whose vertices may change position, but the topology
// cannot change.
//
// Ok, to put it clear: for each model, you need one instance of
// class CStencilShadowConnectivity. To create that instance, use
// this class: create an object, push the mesh of the model into it,
// then ask this class to give out the CStencilShadowConnectivity.
//
// CStencilShadowConnectivity is build for maximum run-time performance and
// minimal memory footprint, whilst this class is build for convenient
// pre-calculations and flexibility.
//
// The model is allowed to deform, but is not
// allowed to change topology (add or remove faces as well as re-assign
// face vertices or even change face orientation).
/////////////////////////////////////////////////////////////////
//
// IMPLEMENTATION NOTES should be in
// StencilShadowConnectivityBuilder.cpp
//
#pragma once
#ifndef _STENCIL_SHADOW_CONNECTIVITY_BUILDER_HDR_
#define _STENCIL_SHADOW_CONNECTIVITY_BUILDER_HDR_
// the connectivity class is required for the declarations
// of the Face, Edge, EdgeFace and BasicEdge structures which are common for both
// the builder and the built class
#include "IEdgeConnectivityBuilder.h" // IEdgeConnectivityBuilder
#include "StencilShadowConnectivity.h" // CStencilShadowConnectivity
#include <map> // STL map<>
#include <functional>
#include <algorithm>
class CStencilShadowConnectivityBuilder : public IEdgeConnectivityBuilder
{
public:
typedef IStencilShadowConnectivity::vindex vindex;
//! default constructor
//! creates an empty mesh connectivity
CStencilShadowConnectivityBuilder(void);
//! destructor
virtual ~CStencilShadowConnectivityBuilder(void);
//! return to the state right after construction
virtual void Reinit( void );
// sets the maximum distance between two points that are allowed to be welded
//virtual void SetWeldTolerance (float fTolerance) {m_fWeldTolerance = fTolerance*fTolerance;}
// reserves space for the given number of triangles that are to be added
//! /param nNumTriangles 0..
//! /param innNumVertices 0..
virtual void ReserveForTriangles( unsigned nNumTriangles, unsigned innNumVertices );
// adds a single triangle to the mesh
// the triangle is defined by three vertices, in counter-clockwise order
// these vertex indices will be used later when accessing the array of
// deformed character/model vertices to determine the shadow volume boundary
//! /param nV0 vertex index one 0..0xffff
//! /param nV1 vertex index two 0..0xffff
//! /param nV2 vertex index three 0..0xffff
//! /param inpVertexPos pointer to the vertex array (to remove vertices on same position)
virtual void AddTriangle( vindex nV0, vindex nV1, vindex nV2 );
//!
//! /param nV0 vertex index one 0..0xffff
//! /param nV1 vertex index two 0..0xffff
//! /param nV2 vertex index three 0..0xffff
//! /param vV0 original vertex one position
//! /param vV1 original vertex two position
//! /param vV2 original vertex three position
//! slower but with the auto weld feature (if there are vertices with the same position your result is smaller and therefore faster)
virtual void AddTriangleWelded( vindex nV0, vindex nV1, vindex nV2, const Vec3d &vV0, const Vec3d &vV1, const Vec3d &vV2 );
// constructs/compiles the optimum representation of the connectivity
// to be used in run-time
// WARNING: use Release method to dispose the connectivity object
//! /param inpVertexBuf vertex position buffer to check for solvable open edges (2 vertices with same position)
//! /return interface pointer, could be 0
virtual class IStencilShadowConnectivity *ConstructConnectivity( void );
// returns the number of single (with no pair faces found) or orphaned edges
// /return 0..
virtual unsigned numOrphanedEdges ()const;
//! Returns the list of faces for orphaned edges into the given buffer;
//! For each orphaned edge, one face will be returned; some faces may be duplicated
virtual void getOrphanedEdgeFaces (unsigned* pBuffer);
protected:
// for the descriptions of the following shared structures, refer to
// File:StencilShadowConnectivity.h
typedef CStencilShadowConnectivity::BasicEdge BasicEdge;
typedef CStencilShadowConnectivity::Edge Edge;
typedef CStencilShadowConnectivity::EdgeFace EdgeFace;
typedef CStencilShadowConnectivity::Face Face;
// map of single edges - edge with only one face attached
typedef std::map<BasicEdge, EdgeFace> SingleEdgeMap;
SingleEdgeMap m_mapSingleEdges; //!<
// array of double-edges - edges with both faces attached/found
typedef std::vector<Edge> DoubleEdgeArray;
DoubleEdgeArray m_vDoubleEdges; //!<
// triangles added (used to extract index to reference edge to faces, and keep the topology)
typedef std::vector<Face> FaceArray;
FaceArray m_vFaces; //!<
DWORD m_dwNumUncompressedVertices; //!<
// helper to get order for Vec3d
struct CVec3dOrder: public std::binary_function< Vec3d, Vec3d, bool>
{
bool operator() ( const Vec3d &a, const Vec3d &b ) const
{
// first sort by x
if(a.x<b.x)return(true);
if(a.x>b.x)return(false);
// then by y
if(a.y<b.y)return(true);
if(a.y>b.y)return(false);
// then by z
if(a.z<b.z)return(true);
if(a.z>b.z)return(false);
return(false);
}
};
typedef std::map<Vec3d,unsigned,CVec3dOrder> VertexWelderMap;
VertexWelderMap m_mVertexWelder; //!< used for AddTriangleWelded
// this will try to find a close match to the given vertex, and
// if found, return its index (the actual index of the vertex that's very close or
// coincide with v in space). Otherwise, creates a new vertex reference in the map
// and returns the index nNewVertex
unsigned WeldVertex (const Vec3d& v, unsigned nNewVertex);
//float m_fWeldTolerance;
// this is 1 + the max index of the vertex in the original mesh vertex array, that
// is used by the currently being built connectivity
//unsigned m_numOrigMeshVerticesUsed; // this is unneeded because connectivity calculates this itself
protected:
// adds a new single edge, or finds an adjacent edge and puts the double-edge on record
// add a new edge, if there is no complementary single edge;
// otherwise, withdraw the edge from the list of single edges and add to double edges
//! /param eEdge
//! /param efFace
void AddNewEdge (BasicEdge eEdge, EdgeFace efFace);
};
// this is the builder of connectivity that can be used for static objects
// (with non-changing face normals)
class CStencilShadowStaticConnectivityBuilder :public CStencilShadowConnectivityBuilder
{
public:
CStencilShadowStaticConnectivityBuilder();
virtual ~CStencilShadowStaticConnectivityBuilder();
void AddTriangleWelded( vindex nV0, vindex nV1, vindex nV2, const Vec3d &vV0, const Vec3d &vV1, const Vec3d &vV2 );
//! return to the state right after construction
virtual void Reinit( void );
// reserves space for the given number of triangles that are to be added
//! /param nNumTriangles 0..
//! /param innNumVertices 0..
virtual void ReserveForTriangles( unsigned nNumTriangles, unsigned innNumVertices );
// constructs/compiles the optimum representation of the connectivity
// to be used in run-time
// WARNING: use Release method to dispose the connectivity object
//! /param inpVertexBuf vertex position buffer to check for solvable open edges (2 vertices with same position)
//! /return interface pointer, could be 0
virtual class IStencilShadowConnectivity *ConstructConnectivity( void );
protected:
// WARNING: This is only to be called when the whole construction process
// is finished, to modify already created connectivity
// Goes through all vertices used by the connectivity and constructs a continuous
// array out of them; reindexes the vertices in the connectivity object
// to use these vertices; puts the new vertex array into the connectivity object
void SetVertices (CStencilShadowConnectivity * pConnectivity);
typedef CStencilShadowConnectivity::Plane Plane;
std::vector<Plane> m_vPlanes;
};
#endif // _STENCIL_SHADOW_CONNECTIVITY_BUILDER_HDR_