|
|
//========= Copyright � 1996-2005, 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; Vector m_mins; // AABB for node triangles
Vector m_maxs; };
// ------------------------------------------------------------------------ //
// 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
|