185 lines
6.0 KiB
C++
185 lines
6.0 KiB
C++
//========= Copyright Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose: This module defines the CPowerInfo class, which contains a
|
|
// whole bunch of precalculated data for each displacement power.
|
|
// It holds data that indicates how to tesselate, how to access
|
|
// neighbor displacements, etc.
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#ifndef DISP_POWERINFO_H
|
|
#define DISP_POWERINFO_H
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
#include "bspfile.h"
|
|
#include "disp_vertindex.h"
|
|
|
|
#define NUM_POWERINFOS (MAX_MAP_DISP_POWER + 1)
|
|
|
|
struct DispNodeInfo_t {
|
|
enum {
|
|
// Indicates if any children at all have triangles
|
|
CHILDREN_HAVE_TRIANGLES = 0x1
|
|
};
|
|
|
|
// Indicates which tesselation indices are associated with a node
|
|
unsigned short m_FirstTesselationIndex;
|
|
unsigned char m_Count;
|
|
unsigned char m_Flags;
|
|
};
|
|
|
|
// ------------------------------------------------------------------------ //
|
|
// CTesselateWindings are used to tell what order a node needs to visit
|
|
// vertices while tesselating.
|
|
// ------------------------------------------------------------------------ //
|
|
class CTesselateVert {
|
|
public:
|
|
CTesselateVert(CVertIndex const &index, int iNode);
|
|
|
|
CVertIndex m_Index;
|
|
short m_iNode; // Which node this vert is a part of (-1 on left, right, up,
|
|
// and down).
|
|
};
|
|
|
|
class CTesselateWinding {
|
|
public:
|
|
CTesselateVert *m_Verts;
|
|
short m_nVerts; // (includes the last vert)
|
|
};
|
|
|
|
class CVertDependency {
|
|
public:
|
|
// Returns false if there is no dependency stored here.
|
|
bool IsValid() { return m_iVert.x != -1; }
|
|
|
|
public:
|
|
// The vert index is in the same power as the source displacement.
|
|
// It is also wrapped, so for example, on the middle of the right edge
|
|
// of a 3x3, it will have a dependency on the 3x3's root node (1,1), and it
|
|
// will have another (1,1) entry that references a neighbor.
|
|
CVertIndex m_iVert;
|
|
|
|
// This is -1 if the vert exists inside the source displacement.
|
|
// It is one of the NEIGHBOREDGE_ codes above if it reaches into a neighbor.
|
|
short m_iNeighbor;
|
|
};
|
|
|
|
// Precalculated data about displacement vertices.
|
|
class CVertInfo {
|
|
public:
|
|
CVertInfo();
|
|
|
|
// These are the vertices that this vertex depends on (vertices that must be
|
|
// active for this vert to exist).
|
|
CVertDependency m_Dependencies[2];
|
|
|
|
// These are the vertices that have this vert in their m_Dependencies.
|
|
enum { NUM_REVERSE_DEPENDENCIES = 4 };
|
|
CVertDependency m_ReverseDependencies[NUM_REVERSE_DEPENDENCIES];
|
|
|
|
short m_iNodeLevel; // -1 if this is not a node. Otherwise, the recursion
|
|
// level of this node (root node = 1).
|
|
CVertIndex
|
|
m_iParent; // x=-1 if this is a not a node or if it's the root node.
|
|
};
|
|
|
|
class CTwoUShorts {
|
|
public:
|
|
unsigned short m_Values[2];
|
|
};
|
|
|
|
class CFourVerts {
|
|
public:
|
|
CVertIndex m_Verts[4];
|
|
};
|
|
|
|
// Used for referencing triangles in the fully-tesselated displacement by index.
|
|
class CTriInfo {
|
|
public:
|
|
unsigned short m_Indices[3];
|
|
};
|
|
|
|
// Precalculated data for displacements of a certain power.
|
|
class CPowerInfo {
|
|
public:
|
|
CPowerInfo(CVertInfo *pVertInfo, CFourVerts *pSideVerts,
|
|
CFourVerts *pChildVerts, CFourVerts *pSideVertCorners,
|
|
CTwoUShorts *pErrorEdges, CTriInfo *pTriInfos);
|
|
|
|
int GetPower() const { return m_Power; }
|
|
int GetSideLength() const { return m_SideLength; }
|
|
const CVertIndex &GetRootNode() const { return m_RootNode; }
|
|
int GetMidPoint() const { return m_MidPoint; } // Half the edge length.
|
|
|
|
// Get at the tri list.
|
|
int GetNumTriInfos() const { return m_nTriInfos; }
|
|
const CTriInfo *GetTriInfo(int i) const { return &m_pTriInfos[i]; }
|
|
|
|
// Get the number of vertices in a displacement of this power.
|
|
int GetNumVerts() const { return m_MaxVerts; }
|
|
|
|
// Return a corner point index. Indexed by the CORNER_ defines.
|
|
const CVertIndex &GetCornerPointIndex(int iCorner) const;
|
|
|
|
public:
|
|
CVertInfo *m_pVertInfo;
|
|
CFourVerts *m_pSideVerts; // The 4 side verts for each node.
|
|
CFourVerts *m_pChildVerts; // The 4 children for each node.
|
|
CFourVerts *m_pSideVertCorners;
|
|
CTwoUShorts *m_pErrorEdges; // These are the edges
|
|
// that are used to measure the screenspace
|
|
// error with respect to each vert.
|
|
|
|
CTriInfo *m_pTriInfos;
|
|
int m_nTriInfos;
|
|
|
|
int m_Power;
|
|
|
|
CVertIndex m_RootNode;
|
|
int m_SideLength;
|
|
int m_SideLengthM1; // Side length minus 1.
|
|
int m_MidPoint; // Side length / 2.
|
|
int m_MaxVerts; // m_SideLength * m_SideLength
|
|
int m_NodeCount; // total # of nodes, including children
|
|
|
|
// Precalculated increments if you're using a bit vector to represent nodes.
|
|
// Starting at level 0 of the tree, this stores the increment between the
|
|
// nodes at this level. Vectors holding node data are stored in preorder
|
|
// traversal, and these increments tell the number of elements between nodes
|
|
// at each level.
|
|
int m_NodeIndexIncrements[MAX_MAP_DISP_POWER];
|
|
|
|
CVertIndex m_EdgeStartVerts[4];
|
|
CVertIndex m_EdgeIncrements[4];
|
|
|
|
CVertIndex m_NeighborStartVerts[4][4]; // [side][orientation]
|
|
CVertIndex m_NeighborIncrements[4][4]; // [side][orientation]
|
|
|
|
private:
|
|
friend void InitPowerInfo(CPowerInfo *pInfo, int iMaxPower);
|
|
|
|
CVertIndex m_CornerPointIndices[4];
|
|
};
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// // Globals.
|
|
// -----------------------------------------------------------------------------
|
|
// //
|
|
|
|
// Indexed by the TWINDING_ enums.
|
|
extern CTesselateWinding g_TWinding;
|
|
|
|
// -----------------------------------------------------------------------------
|
|
// // Functions.
|
|
// -----------------------------------------------------------------------------
|
|
// //
|
|
|
|
// Valid indices are MIN_MAP_DISP_POWER through (and including)
|
|
// MAX_MAP_DISP_POWER.
|
|
const CPowerInfo *GetPowerInfo(int iPower);
|
|
|
|
#endif // DISP_POWERINFO_H
|