You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
214 lines
5.8 KiB
214 lines
5.8 KiB
5 years ago
|
//========= 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
|