1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2024-12-22 17:47:38 +08:00
hl2sdk/public/disp_powerinfo.h
2013-06-26 15:22:04 -07:00

214 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 "disp_vertindex.h"
#include "bspfile.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