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.
223 lines
8.3 KiB
223 lines
8.3 KiB
/*==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
|
|
|