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.
224 lines
8.1 KiB
224 lines
8.1 KiB
4 years ago
|
/*==LICENSE==*
|
||
|
|
||
|
CyanWorlds.com Engine - MMOG client, server and tools
|
||
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
||
|
|
||
|
This program is free software: you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation, either version 3 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
|
||
|
Additional permissions under GNU GPL version 3 section 7
|
||
|
|
||
|
If you modify this Program, or any covered work, by linking or
|
||
|
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||
|
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||
|
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||
|
(or a modified version of those libraries),
|
||
|
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||
|
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||
|
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||
|
licensors of this Program grant you additional
|
||
|
permission to convey the resulting work. Corresponding Source for a
|
||
|
non-source form of such a combination shall include the source code for
|
||
|
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||
|
work.
|
||
|
|
||
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||
|
or by snail mail at:
|
||
|
Cyan Worlds, Inc.
|
||
|
14617 N Newport Hwy
|
||
|
Mead, WA 99021
|
||
|
|
||
|
*==LICENSE==*/
|
||
|
|
||
|
#ifndef plCullTree_inc
|
||
|
#define plCullTree_inc
|
||
|
|
||
|
#include "hsBounds.h"
|
||
|
#include "hsGeometry3.h"
|
||
|
#include "hsBitVector.h"
|
||
|
#include "plCuller.h"
|
||
|
#include "../plScene/plCullPoly.h"
|
||
|
|
||
|
#ifdef HS_DEBUGGING
|
||
|
#define DEBUG_POINTERS
|
||
|
#endif // HS_DEBUGGING
|
||
|
|
||
|
class plCullTree;
|
||
|
class plCullNode;
|
||
|
|
||
|
// for vis
|
||
|
struct hsPoint3;
|
||
|
struct hsVector3;
|
||
|
struct hsColorRGBA;
|
||
|
|
||
|
class plCullTree : public plCuller
|
||
|
{
|
||
|
protected:
|
||
|
|
||
|
// Visualization stuff, to be nuked from production version.
|
||
|
mutable hsBool fCapturePolys;
|
||
|
mutable hsTArray<hsPoint3> fVisVerts;
|
||
|
mutable hsTArray<hsVector3> fVisNorms;
|
||
|
mutable hsTArray<hsColorRGBA> fVisColors;
|
||
|
mutable hsTArray<UInt16> fVisTris;
|
||
|
mutable hsScalar fVisYon;
|
||
|
|
||
|
mutable hsTArray<plCullPoly> fScratchPolys;
|
||
|
mutable hsLargeArray<Int16> fScratchClear;
|
||
|
mutable hsLargeArray<Int16> fScratchSplit;
|
||
|
mutable hsLargeArray<Int16> fScratchCulled;
|
||
|
mutable hsBitVector fScratchBitVec;
|
||
|
mutable hsBitVector fScratchTotVec;
|
||
|
|
||
|
void IVisPolyShape(const plCullPoly& poly, hsBool dark) const;
|
||
|
void IVisPolyEdge(const hsPoint3& p0, const hsPoint3& p1, hsBool dark) const;
|
||
|
void IVisPoly(const plCullPoly& poly, hsBool dark) const;
|
||
|
|
||
|
|
||
|
hsPoint3 fViewPos;
|
||
|
|
||
|
Int16 fRoot;
|
||
|
mutable hsTArray<plCullNode> fNodeList; // Scratch list we make the tree from.
|
||
|
plCullNode* IGetRoot() const { return IGetNode(fRoot); }
|
||
|
plCullNode* IGetNode(Int16 i) const { return i >= 0 ? &fNodeList[i] : nil; }
|
||
|
|
||
|
void ITestNode(const plSpaceTree* space, Int16 who, hsTArray<Int16>& outList) const; // Appends to outlist
|
||
|
void ITestList(const plSpaceTree* space, const hsTArray<Int16>& inList, hsTArray<Int16>& outList) const;
|
||
|
|
||
|
Int16 IAddPolyRecur(const plCullPoly& poly, Int16 iNode);
|
||
|
Int16 IMakeHoleSubTree(const plCullPoly& poly) const;
|
||
|
Int16 IMakePolySubTree(const plCullPoly& poly) const;
|
||
|
Int16 IMakePolyNode(const plCullPoly& poly, int i0, int i1) const;
|
||
|
|
||
|
// Some scratch areas for the nodes use when building the tree etc.
|
||
|
hsTArray<plCullPoly>& ScratchPolys() const { return fScratchPolys; }
|
||
|
hsLargeArray<Int16>& ScratchClear() const { return fScratchClear; }
|
||
|
hsLargeArray<Int16>& ScratchSplit() const { return fScratchSplit; }
|
||
|
hsLargeArray<Int16>& ScratchCulled() const { return fScratchCulled; }
|
||
|
hsBitVector& ScratchBitVec() const { return fScratchBitVec; }
|
||
|
hsBitVector& ScratchTotVec() const { return fScratchTotVec; }
|
||
|
|
||
|
void ISetupScratch(UInt16 nNodes);
|
||
|
|
||
|
friend class plCullNode;
|
||
|
|
||
|
public:
|
||
|
plCullTree();
|
||
|
~plCullTree();
|
||
|
|
||
|
void Reset(); // Called before starting to add polys for this frame.
|
||
|
void InitFrustum(const hsMatrix44& world2NDC);
|
||
|
void SetViewPos(const hsPoint3& pos);
|
||
|
void AddPoly(const plCullPoly& poly);
|
||
|
|
||
|
UInt32 GetNumNodes() const { return fNodeList.GetCount(); }
|
||
|
|
||
|
virtual void Harvest(const plSpaceTree* space, hsTArray<Int16>& outList) const;
|
||
|
virtual hsBool BoundsVisible(const hsBounds3Ext& bnd) const;
|
||
|
virtual hsBool SphereVisible(const hsPoint3& center, hsScalar rad) const;
|
||
|
|
||
|
// Visualization stuff. Only to be called by the pipeline (or some other vis manager).
|
||
|
void SetVisualizationYon(hsScalar y) const { fVisYon = y; }
|
||
|
void BeginCapturePolys() const { fCapturePolys = true; }
|
||
|
void EndCapturePolys() const { fCapturePolys = false; }
|
||
|
hsTArray<hsPoint3>& GetCaptureVerts() const { return fVisVerts; }
|
||
|
hsTArray<hsVector3>& GetCaptureNorms() const { return fVisNorms; }
|
||
|
hsTArray<hsColorRGBA>& GetCaptureColors() const { return fVisColors; }
|
||
|
hsTArray<UInt16>& GetCaptureTris() const { return fVisTris; }
|
||
|
void ReleaseCapture() const;
|
||
|
};
|
||
|
|
||
|
class plCullNode
|
||
|
{
|
||
|
public:
|
||
|
enum plCullStatus
|
||
|
{
|
||
|
kClear,
|
||
|
kCulled,
|
||
|
kSplit,
|
||
|
kPureSplit
|
||
|
};
|
||
|
protected:
|
||
|
hsVector3 fNorm;
|
||
|
hsScalar fDist;
|
||
|
|
||
|
hsBool fIsFace;
|
||
|
|
||
|
Int16 fInnerChild;
|
||
|
Int16 fOuterChild;
|
||
|
|
||
|
const plCullTree* fTree;
|
||
|
|
||
|
plCullNode* IGetNode(Int16 i) const;
|
||
|
|
||
|
#ifdef DEBUG_POINTERS
|
||
|
mutable plCullNode* fInnerPtr;
|
||
|
mutable plCullNode* fOuterPtr;
|
||
|
|
||
|
void ISetPointersRecur() const;
|
||
|
#else // DEBUG_POINTERS
|
||
|
void ISetPointersRecur() const {}
|
||
|
#endif // DEBUG_POINTERS
|
||
|
|
||
|
// Bounds only version
|
||
|
plCullNode::plCullStatus ITestBoundsRecur(const hsBounds3Ext& bnd) const;
|
||
|
plCullNode::plCullStatus ITestSphereRecur(const hsPoint3& center, hsScalar rad) const;
|
||
|
|
||
|
// Using the nodes
|
||
|
plCullNode::plCullStatus ITestNode(const plSpaceTree* space, Int16 who, hsLargeArray<Int16>& clear, hsLargeArray<Int16>& split, hsLargeArray<Int16>& culled) const;
|
||
|
void ITestNode(const plSpaceTree* space, Int16 who, hsBitVector& totList, hsBitVector& outList) const;
|
||
|
void IHarvest(const plSpaceTree* space, hsTArray<Int16>& outList) const;
|
||
|
|
||
|
// Constructing the tree
|
||
|
hsScalar IInterpVert(const hsPoint3& p0, const hsPoint3& p1, hsPoint3& out) const;
|
||
|
plCullNode::plCullStatus ISplitPoly(const plCullPoly& poly, plCullPoly*& innerPoly, plCullPoly*& outerPoly) const;
|
||
|
void IMarkClipped(const plCullPoly& poly, const hsBitVector& onVerts) const;
|
||
|
void ITakeHalfPoly(const plCullPoly& scrPoly,
|
||
|
const hsTArray<int>& vtxIdx,
|
||
|
const hsBitVector& onVerts,
|
||
|
plCullPoly& outPoly) const;
|
||
|
void IBreakPoly(const plCullPoly& poly, const hsTArray<hsScalar>& depths,
|
||
|
hsBitVector& inVerts,
|
||
|
hsBitVector& outVerts,
|
||
|
hsBitVector& onVerts,
|
||
|
plCullPoly& srcPoly) const;
|
||
|
|
||
|
hsTArray<plCullPoly>& ScratchPolys() const { return fTree->ScratchPolys(); }
|
||
|
hsLargeArray<Int16>& ScratchClear() const { return fTree->ScratchClear(); }
|
||
|
hsLargeArray<Int16>& ScratchSplit() const { return fTree->ScratchSplit(); }
|
||
|
hsLargeArray<Int16>& ScratchCulled() const { return fTree->ScratchCulled(); }
|
||
|
hsBitVector& ScratchBitVec() const { return fTree->ScratchBitVec(); }
|
||
|
hsBitVector& ScratchTotVec() const { return fTree->ScratchTotVec(); }
|
||
|
|
||
|
friend class plCullTree;
|
||
|
public:
|
||
|
|
||
|
void Init(const plCullTree* t, const hsVector3& n, hsScalar d) { fIsFace = false; fTree = t; fInnerChild = fOuterChild = -1; SetPlane(n, d); }
|
||
|
void Init(const plCullTree* t, const plCullPoly& poly) { Init(t, poly.fNorm, poly.fDist); }
|
||
|
|
||
|
void SetPlane(const hsVector3& n, hsScalar d) { fNorm = n; fDist = d; }
|
||
|
|
||
|
const hsVector3& GetNormal() const { return fNorm; }
|
||
|
const hsScalar GetDist() const { return fDist; }
|
||
|
|
||
|
plCullStatus TestBounds(const hsBounds3Ext& bnd) const;
|
||
|
plCullStatus TestSphere(const hsPoint3& center, hsScalar rad) const;
|
||
|
};
|
||
|
|
||
|
inline plCullNode* plCullNode::IGetNode(Int16 i) const
|
||
|
{
|
||
|
return fTree->IGetNode(i);
|
||
|
}
|
||
|
|
||
|
#endif // plCullTree_inc
|