1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
|
#pragma once
#include "render.h"
#include "PatchControl.h"
struct FaceTangents;
/// Representation of a patch as mesh geometry
class PatchTesselation
{
public:
// The vertex data, each vertex equipped with texcoord and ntb vectors
std::vector<MeshVertex> vertices;
// The indices, arranged in the way it's expected by GL_QUAD_STRIPS
// The number of indices is (lenStrips*numStrips), which is the same as (width*height)
std::vector<RenderIndex> indices;
// Strip index layout
std::size_t numStrips;
std::size_t lenStrips;
// Geometry of the tesselated mesh
std::size_t width;
std::size_t height;
private:
// Used during the tesselation phase
std::size_t _maxWidth;
std::size_t _maxHeight;
public:
/// Construct an uninitialised patch tesselation
PatchTesselation() :
numStrips(0),
lenStrips(0),
width(0),
height(0),
_maxWidth(0),
_maxHeight(0)
{}
/// Clear all patch data
void clear();
// Generates the tesselated mesh based on the input parameters
void generate(std::size_t width, std::size_t height, const PatchControlArray& controlPoints,
bool subdivionsFixed, const Subdivisions& subdivs, IRenderEntity* renderEntity);
private:
// Private methods used for tesselation, modeled after the patch subdivision code found in idTech4
void generateIndices();
void generateNormals();
void subdivideMesh();
void subdivideMeshFixed(std::size_t subdivX, std::size_t subdivY);
void collapseMesh();
void expandMesh();
void resizeExpandedMesh(std::size_t newHeight, std::size_t newWidth);
void putOnCurve();
void removeLinearColumnsRows();
static void lerpVert(const MeshVertex& a, const MeshVertex& b, MeshVertex&out);
static Vector3 projectPointOntoVector(const Vector3& point, const Vector3& vStart, const Vector3& vEnd);
void sampleSinglePatch(const MeshVertex ctrl[3][3], std::size_t baseCol, std::size_t baseRow,
std::size_t width, std::size_t horzSub, std::size_t vertSub,
std::vector<MeshVertex>& outVerts) const;
void sampleSinglePatchPoint(const MeshVertex ctrl[3][3], float u, float v, MeshVertex& out) const;
void deriveTangents();
void deriveFaceTangents(std::vector<FaceTangents>& faceTangents);
};
|