diff options
| author | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
|---|---|---|
| committer | Joe Ludwig <[email protected]> | 2013-06-26 15:22:04 -0700 |
| commit | 39ed87570bdb2f86969d4be821c94b722dc71179 (patch) | |
| tree | abc53757f75f40c80278e87650ea92808274aa59 /mp/src/public/disp_common.h | |
| download | source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip | |
First version of the SOurce SDK 2013
Diffstat (limited to 'mp/src/public/disp_common.h')
| -rw-r--r-- | mp/src/public/disp_common.h | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/mp/src/public/disp_common.h b/mp/src/public/disp_common.h new file mode 100644 index 00000000..921fd9c1 --- /dev/null +++ b/mp/src/public/disp_common.h @@ -0,0 +1,262 @@ +//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//=============================================================================//
+
+#ifndef DISP_COMMON_H
+#define DISP_COMMON_H
+#ifdef _WIN32
+#pragma once
+#endif
+
+#include "disp_vertindex.h"
+#include "bspfile.h"
+#include "utlvector.h"
+
+class CPowerInfo;
+class CCoreDispInfo;
+
+// ----------------------------------------------------------------------------- //
+// Classes.
+// ----------------------------------------------------------------------------- //
+
+// This class provides a set of utility functions for displacements that work in the tools and the engine.
+abstract_class CDispUtilsHelper
+{
+// Derived classes must implement these.
+public:
+ virtual const CPowerInfo* GetPowerInfo() const = 0;
+ virtual CDispNeighbor* GetEdgeNeighbor( int index ) = 0;
+ virtual CDispCornerNeighbors* GetCornerNeighbors( int index ) = 0;
+ virtual CDispUtilsHelper* GetDispUtilsByIndex( int index ) = 0;
+
+// Helper functions.
+public:
+
+ int GetPower() const;
+ int GetSideLength() const;
+ const CVertIndex& GetCornerPointIndex( int iCorner ) const;
+ int VertIndexToInt( const CVertIndex &i ) const;
+ CVertIndex GetEdgeMidPoint( int iEdge ) const;
+};
+
+
+// Use this to walk along two neighboring displacements and touch all the
+// common vertices.
+class CDispSubEdgeIterator
+{
+public:
+
+ CDispSubEdgeIterator();
+
+ // Normally, this will iterate all shared verts along the edge except the corners.
+ // If you want the corners to be touched too, then pass in bTouchCorners=true.
+ void Start( CDispUtilsHelper *pDisp, int iEdge, int iSub, bool bTouchCorners = false );
+ bool Next();
+
+ const CVertIndex& GetVertIndex() const { return m_Index; } // Get the vert index for the displacement in pUtils.
+ const CVertIndex& GetNBVertIndex() const { return m_NBIndex; } // Get the neighbor's vert index.
+ CDispUtilsHelper* GetNeighbor() const { return m_pNeighbor; }
+
+ // Returns true if you're on the last vert (ie: the next Next() call will return false).ssssss
+ bool IsLastVert() const;
+
+
+private:
+ CDispUtilsHelper *m_pNeighbor; // The neighbor to the edge we were setup on.
+
+ CVertIndex m_Index;
+ CVertIndex m_Inc;
+
+ CVertIndex m_NBIndex;
+ CVertIndex m_NBInc;
+
+ int m_End;
+ int m_FreeDim;
+};
+
+
+// Use this to walk along the edge of a displacement, touching the points in common
+// between the two neighbors. Note: this won't hit the corner points of any of the displacements.
+// (As a result, it won't hit the midpoint of pDisps's edge if there are 2 neighbors).
+class CDispEdgeIterator
+{
+public:
+ CDispEdgeIterator( CDispUtilsHelper *pDisp, int iEdge );
+
+ // Seek to the next point on the edge.
+ bool Next();
+
+ const CVertIndex& GetVertIndex() const { return m_It.GetVertIndex(); } // Get the vert index for the displacement in pUtils.
+ const CVertIndex& GetNBVertIndex() const { return m_It.GetNBVertIndex(); } // Get the neighbor's vert index.
+
+ // What is the current neighbor?
+ CDispUtilsHelper* GetCurrentNeighbor() const { return m_It.GetNeighbor(); }
+
+
+private:
+ CDispUtilsHelper *m_pDisp;
+ int m_iEdge;
+ int m_iCurSub;
+
+ CDispSubEdgeIterator m_It;
+};
+
+
+// Use this to walk all the corners and edge verts in the displacement.
+// It walks the edges in the order of the NEIGHBOREDGE_ defines.
+// Iterate like this:
+// CDispCircumferenceIterator iterator( pDisp->GetSideLength() );
+// while ( iterator.Next() )
+// ...
+class CDispCircumferenceIterator
+{
+public:
+ CDispCircumferenceIterator( int sideLength );
+
+ // Seek to the next point. Returns false when there are no more points.
+ bool Next();
+
+ const CVertIndex& GetVertIndex() const { return m_VertIndex; }
+
+
+private:
+ int m_SideLengthM1;
+ int m_iCurEdge;
+ CVertIndex m_VertIndex;
+};
+
+
+// These store info about how to scale and shift coordinates between neighbors
+// of different relations (in g_ShiftInfos).
+class CShiftInfo
+{
+public:
+ int m_MidPointScale;
+ int m_PowerShiftAdd;
+ bool m_bValid;
+};
+
+class CDispBox
+{
+public:
+ Vector m_Min, m_Max;
+};
+
+// ----------------------------------------------------------------------------- //
+// Globals.
+// ----------------------------------------------------------------------------- //
+
+
+extern int g_EdgeDims[4]; // This tells which dimension (0 or 1) is locked on an edge for each NEIGHBOREDGE_ enum.
+extern CShiftInfo g_ShiftInfos[3][3]; // See CShiftInfo.
+extern int g_EdgeSideLenMul[4];// Multiply these by the side length to get the index of the edge.
+
+
+// ----------------------------------------------------------------------------- //
+// Helper functions.
+// ----------------------------------------------------------------------------- //
+
+// Reference implementation to generate triangle indices for a displacement.
+int DispCommon_GetNumTriIndices( int power );
+void DispCommon_GenerateTriIndices( int power, unsigned short *indices );
+
+// Returns a NEIGHBOREDGE_ value for the edge that the index is on.
+// Returns -1 if the index is not on a side.
+// If the point is on a corner, the edges are tested in the order of the NEIGHBOREDGE_ defines.
+int GetEdgeIndexFromPoint( CVertIndex const &index, int iPower );
+
+// Returns a CORNER_ value for the corner the point is on, or -1 if it's not on a corner.
+int GetEdgeIndexFromPoint( CVertIndex const &index, int iPower );
+
+// This returns the neighbor's power, possibly +1 or -1.
+//
+// It will add one if the neighbor takes up half of your edge (ie: if it took up your
+// whole edge, its resolution would be twice what it really is).
+//
+// It will subtract one if you take up half of its edge (ie: you only touch half of its verts).
+//
+// Returns -1 if the edge connection is invalid.
+int GetNeighborEdgePower( CDispUtilsHelper *pDisp, int iEdge, int iSub );
+
+// This function sets you up so you can walk along an edge that joins two neighbors.
+// Add myInc to myIndex and nbInc to nbIndex until myIndex[iFreeDim] >= myEnd.
+//
+// Returns the neighbor displacement, or NULL if the specified sub neighbor isn't valid.
+CDispUtilsHelper* SetupEdgeIncrements(
+ CDispUtilsHelper *pDisp,
+ int iEdge,
+ int iSub,
+ CVertIndex &myIndex,
+ CVertIndex &myInc,
+ CVertIndex &nbIndex,
+ CVertIndex &nbInc,
+ int &myEnd,
+ int &iFreeDim );
+
+// Figure out which sub neighbor nodeIndex touches.
+// Returns -1 if there is no valid sub neighbor at the specified index.
+int GetSubNeighborIndex(
+ CDispUtilsHelper *pDisp,
+ int iEdge,
+ CVertIndex const &nodeIndex
+ );
+
+// Given a vert index and the CSubNeighbor the vert lies on, this
+// transforms the specified vert into the neighbor's space.
+//
+// Note: for corner verts, there may be multiple neighbors touching the same vert, so the
+// result you get depends on the edge you specify in iEdge (ie: if you specify the same
+// node index but a different edge, you may get a different neighbor).
+//
+// Note: This only returns a point if the point at nodeIndex actually touches a neighbor point.
+// An example where this might be unexpected is if pDisp is power 4 and its neighbor on iEdge
+// is power 3, and nodeIndex points at a vert in between two of its neighbor's verts.
+// In that case, even though there is a neighbor displacement, nodeIndex doesn't touch
+// any points on it, so NULL is returned.
+CDispUtilsHelper* TransformIntoSubNeighbor(
+ CDispUtilsHelper *pDisp,
+ int iEdge,
+ int iSub,
+ CVertIndex const &nodeIndex,
+ CVertIndex &out
+ );
+
+// Transform pDisp's node at nodeIndex into its neighboring connection.
+// Returns the neighbor displacement and sets out to the index in the neighbor.
+//
+// Note: for corner verts, there may be multiple neighbors touching the same vert, so the
+// result you get depends on the edge you specify in iEdge (ie: if you specify the same
+// node index but a different edge, you may get a different neighbor).
+//
+// Note: This only returns a point if the point at nodeIndex actually touches a neighbor point.
+// An example where this might surprise you is if pDisp is power 4 and its neighbor on iEdge
+// is power 3, and nodeIndex points at a vert in between two of its neighbor's verts.
+// In that case, even though there is a neighbor displacement, nodeIndex doesn't touch
+// any points on it, so NULL is returned.
+CDispUtilsHelper* TransformIntoNeighbor(
+ CDispUtilsHelper *pDisp,
+ int iEdge,
+ CVertIndex const &nodeIndex,
+ CVertIndex &out );
+
+// Returns true if the specified point has one or more neighbors.
+bool DoesPointHaveAnyNeighbors(
+ CDispUtilsHelper *pDisp,
+ const CVertIndex &index );
+
+
+void FindNeighboringDispSurfs( CCoreDispInfo **ppListBase, int nListSize );
+void SetupAllowedVerts( CCoreDispInfo **ppListBase, int nListSize );
+void GetDispBox( CCoreDispInfo *pDisp, CDispBox &box );
+
+// ----------------------------------------------------------------------------- //
+// Inlines.
+// ----------------------------------------------------------------------------- //
+
+#include "disp_powerinfo.h"
+
+
+#endif // DISP_COMMON_H
|