mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
CWE Directory Reorganization
Rearrange directory structure of CWE to be loosely equivalent to the H'uru Plasma repository. Part 1: Movement of directories and files.
This commit is contained in:
202
Sources/Plasma/PubUtilLib/plScene/plCullPoly.cpp
Normal file
202
Sources/Plasma/PubUtilLib/plScene/plCullPoly.cpp
Normal file
@ -0,0 +1,202 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plCullPoly.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsFastMath.h"
|
||||
|
||||
plCullPoly& plCullPoly::InitFromVerts(UInt32 f)
|
||||
{
|
||||
fFlags = f;
|
||||
|
||||
hsAssert(fVerts.GetCount() > 2, "Initializing from degenerate poly");
|
||||
|
||||
hsVector3 a;
|
||||
hsVector3 b;
|
||||
a.Set(&fVerts[1], &fVerts[0]);
|
||||
b.Set(&fVerts[2], &fVerts[0]);
|
||||
fNorm = a % b;
|
||||
hsFastMath::Normalize(fNorm);
|
||||
fDist = -(fNorm.InnerProduct(fVerts[0]));
|
||||
|
||||
fCenter.Set(0,0,0);
|
||||
int i;
|
||||
for( i = 0; i < fVerts.GetCount(); i++ )
|
||||
{
|
||||
fCenter += fVerts[i];
|
||||
}
|
||||
fCenter *= 1.f / hsScalar(fVerts.GetCount());
|
||||
|
||||
fRadius = ICalcRadius();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
hsScalar plCullPoly::ICalcRadius() const
|
||||
{
|
||||
hsScalar radSq = 0;
|
||||
int i;
|
||||
for( i = 0; i < fVerts.GetCount(); i++ )
|
||||
{
|
||||
hsScalar tmpSq = hsVector3(&fVerts[i], &fCenter).MagnitudeSquared();
|
||||
if( tmpSq > radSq )
|
||||
radSq = tmpSq;
|
||||
}
|
||||
return radSq * hsFastMath::InvSqrt(radSq);
|
||||
}
|
||||
|
||||
plCullPoly& plCullPoly::Flip(const plCullPoly& p)
|
||||
{
|
||||
fFlags = p.fFlags;
|
||||
|
||||
fNorm = -p.fNorm;
|
||||
fDist = -p.fDist;
|
||||
fCenter = p.fCenter;
|
||||
fRadius = p.fRadius;
|
||||
|
||||
int n = p.fVerts.GetCount();
|
||||
fVerts.SetCount(n);
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
fVerts[n-i-1] = p.fVerts[i];
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
plCullPoly& plCullPoly::Transform(const hsMatrix44& l2w, const hsMatrix44& w2l, plCullPoly& dst) const
|
||||
{
|
||||
hsMatrix44 tpose;
|
||||
w2l.GetTranspose(&tpose);
|
||||
|
||||
dst.fFlags = fFlags;
|
||||
|
||||
dst.fVerts.SetCount(fVerts.GetCount());
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fVerts.GetCount(); i++ )
|
||||
{
|
||||
dst.fVerts[i] = l2w * fVerts[i];
|
||||
}
|
||||
dst.fCenter = l2w * fCenter;
|
||||
|
||||
dst.fNorm = tpose * fNorm;
|
||||
|
||||
dst.fDist = -(dst.fNorm .InnerProduct(dst.fVerts[0]));
|
||||
|
||||
ICalcRadius();
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void plCullPoly::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
fFlags = s->ReadSwap32();
|
||||
|
||||
fNorm.Read(s);
|
||||
fDist = s->ReadSwapScalar();
|
||||
fCenter.Read(s);
|
||||
|
||||
fRadius = s->ReadSwapScalar();
|
||||
|
||||
int n = s->ReadSwap32();
|
||||
fVerts.SetCount(n);
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
fVerts[i].Read(s);
|
||||
}
|
||||
|
||||
void plCullPoly::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
s->WriteSwap32(fFlags);
|
||||
|
||||
fNorm.Write(s);
|
||||
s->WriteSwapScalar(fDist);
|
||||
fCenter.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fRadius);
|
||||
|
||||
s->WriteSwap32(fVerts.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fVerts.GetCount(); i++ )
|
||||
fVerts[i].Write(s);
|
||||
}
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
#define MF_VALIDATE_POLYS
|
||||
#endif // HS_DEBUGGING
|
||||
|
||||
#ifdef MF_VALIDATE_POLYS
|
||||
hsBool plCullPoly::Validate() const
|
||||
{
|
||||
const hsScalar kMinMag = 1.e-8f;
|
||||
hsScalar magSq = fNorm.MagnitudeSquared();
|
||||
if( magSq < kMinMag )
|
||||
return false;
|
||||
if( fVerts.GetCount() < 3 )
|
||||
return false;
|
||||
hsVector3 norm = hsVector3(&fVerts[1], &fVerts[0]) % hsVector3(&fVerts[2], &fVerts[0]);
|
||||
magSq = norm.MagnitudeSquared();
|
||||
if( magSq < kMinMag )
|
||||
return false;
|
||||
norm *= hsFastMath::InvSqrtAppr(magSq);
|
||||
int i;
|
||||
for( i = 3; i < fVerts.GetCount(); i++ )
|
||||
{
|
||||
hsVector3 nextNorm = hsVector3(&fVerts[i-1], &fVerts[0]) % hsVector3(&fVerts[i], &fVerts[0]);
|
||||
magSq = nextNorm.MagnitudeSquared();
|
||||
if( magSq < kMinMag )
|
||||
return false;
|
||||
nextNorm *= hsFastMath::InvSqrtAppr(magSq);
|
||||
if( nextNorm.InnerProduct(norm) < kMinMag )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#else // MF_VALIDATE_POLYS
|
||||
hsBool plCullPoly::Validate() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif // MF_VALIDATE_POLYS
|
||||
|
98
Sources/Plasma/PubUtilLib/plScene/plCullPoly.h
Normal file
98
Sources/Plasma/PubUtilLib/plScene/plCullPoly.h
Normal file
@ -0,0 +1,98 @@
|
||||
/*==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 plCullPoly_inc
|
||||
#define plCullPoly_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
struct hsMatrix44;
|
||||
|
||||
const hsScalar kCullPolyDegen = 1.e-4f;
|
||||
|
||||
class plCullPoly
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kHole = 0x1,
|
||||
kTwoSided = 0x2
|
||||
};
|
||||
|
||||
UInt32 fFlags;
|
||||
mutable hsBitVector fClipped; // fClipped[i] => edge(fVerts[i], fVerts[(i+1)%n])
|
||||
|
||||
hsTArray<hsPoint3> fVerts;
|
||||
hsVector3 fNorm;
|
||||
hsScalar fDist;
|
||||
hsPoint3 fCenter;
|
||||
hsScalar fRadius;
|
||||
|
||||
const hsPoint3& GetCenter() const { return fCenter; }
|
||||
hsScalar GetRadius() const { return fRadius; }
|
||||
|
||||
void SetHole(hsBool on) { if( on )fFlags |= kHole; else fFlags &= ~kHole; }
|
||||
void SetTwoSided(hsBool on) { if( on )fFlags |= kTwoSided; else fFlags &= ~kTwoSided; }
|
||||
|
||||
hsBool IsHole() const { return fFlags & kHole; } // Assumes kHole is 0x1
|
||||
hsBool IsTwoSided() const { return 0 != (fFlags & kTwoSided); }
|
||||
|
||||
plCullPoly& Init(const plCullPoly& p) { fClipped.Clear(); fVerts.SetCount(0); fFlags = p.fFlags; fNorm = p.fNorm; fDist = p.fDist; fCenter = p.fCenter; return *this; }
|
||||
plCullPoly& Flip(const plCullPoly& p);
|
||||
plCullPoly& InitFromVerts(UInt32 f=kNone);
|
||||
hsScalar ICalcRadius() const;
|
||||
|
||||
plCullPoly& Transform(const hsMatrix44& l2w, const hsMatrix44& w2l, plCullPoly& dst) const;
|
||||
|
||||
void Read(hsStream* s, hsResMgr* mgr);
|
||||
void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
hsBool DegenerateVert(const hsPoint3& p) const { return fVerts.GetCount() && (kCullPolyDegen > hsVector3(&p, &fVerts[fVerts.GetCount()-1]).MagnitudeSquared()); }
|
||||
|
||||
hsBool Validate() const; // no-op, except for special debugging circumstances.
|
||||
};
|
||||
|
||||
#endif // plCullPoly_inc
|
237
Sources/Plasma/PubUtilLib/plScene/plOccTree.cpp
Normal file
237
Sources/Plasma/PubUtilLib/plScene/plOccTree.cpp
Normal file
@ -0,0 +1,237 @@
|
||||
/*==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==*/
|
||||
|
||||
|
||||
void plOccTree::AddPoly(plPolygon* poly)
|
||||
{
|
||||
fBasePolys.Append(*poly);
|
||||
}
|
||||
|
||||
void plOccTree::MakeOccTree()
|
||||
{
|
||||
if( !fBasePolys.GetCount() )
|
||||
return;
|
||||
|
||||
ISortBasePolys();
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fBasePolys.GetCount(); i++ )
|
||||
fRoot = IAddPolyRecur(fRoot, fBasePolys[i], false);
|
||||
|
||||
fBasePolys.SetCount(0);
|
||||
}
|
||||
|
||||
plOccNode* poOccTree::IMakeSubTree(plOccPoly* poly)
|
||||
{
|
||||
plOccNode* nextNode = nil;
|
||||
plOccNode* lastNode = nil;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < poly->fVerts.GetCount(); i++ )
|
||||
{
|
||||
if( poly->fEdgeFlags[i] & plOccPoly::kEdgeClipped )
|
||||
continue;
|
||||
|
||||
nextNode = fNodePool.Append();
|
||||
nextNode->fFlags = 0;
|
||||
nextNode->fOutChild = nil;
|
||||
|
||||
int j = i+1 < poly->fVerts.GetCount() ? i+1 : 0;
|
||||
|
||||
// Need to set the viewplane here. Calc once per base poly and use
|
||||
// that for fragments?
|
||||
nextNode->Init(poly->fVerts[i], poly->fVerts[j], fViewPos);
|
||||
|
||||
if( nextNode->fInChild = lastChild )
|
||||
nextNode->fFlags = plOccNode::kHasInChild;
|
||||
else
|
||||
{
|
||||
nextNode->fInChild = fNodePool.Append();
|
||||
nextNode->fInChild->Init(poly, false);
|
||||
}
|
||||
|
||||
lastNode = nextNode;
|
||||
}
|
||||
|
||||
// If we have no nextNode, all our edges were clipped. In
|
||||
// that case, we'll just return an "out" leaf.
|
||||
if( !nextNode )
|
||||
{
|
||||
nextNode = fNodePool.Append();
|
||||
nextNode->fFlags = 0;
|
||||
nextNode->fInChild = nextNode->fOutChild = nil;
|
||||
nextNode->Init(poly, true);
|
||||
}
|
||||
|
||||
return nextNode;
|
||||
}
|
||||
|
||||
void plOccNode::Init(const hsPoint3& p0, const hsPoint3& p1, const hsPoint3& pv)
|
||||
{
|
||||
hsVector3 v0, v1;
|
||||
v0.Set(&p0, &pv);
|
||||
v1.Set(&p1, &pv);
|
||||
|
||||
fPlane.fNormal = v0 % v1;
|
||||
fPlane.fDist = fPlane.fNormal.InnerProduct(v0);
|
||||
}
|
||||
|
||||
void plOccNode::Init(plOccPoly* poly)
|
||||
{
|
||||
fPlane = poly->fPlane;
|
||||
// set the viewplane
|
||||
fFlags = kIsLeaf;
|
||||
}
|
||||
|
||||
// Adding a poly to a node
|
||||
// if the node is nil
|
||||
// IMakeSubTree(poly) replaces the node
|
||||
// else
|
||||
// if the node is a leaf
|
||||
// pitch the poly
|
||||
// return node (no replacement)
|
||||
// else
|
||||
// if poly is inside the node
|
||||
// recur on node's inner child
|
||||
// return node (no replacement)
|
||||
// else
|
||||
// if poly is ouside the node
|
||||
// recur on node's outer child
|
||||
// return node (no replacement)
|
||||
// else (node splits poly)
|
||||
// recur on node's inner child
|
||||
// recur on node's outer child
|
||||
// return node (no replacement)
|
||||
// end
|
||||
//
|
||||
// Special case - Degenarate poly's can come
|
||||
// from ITestPoly if an edge of the input poly
|
||||
// is on the plane. In that case, the function
|
||||
// will return kSplit, but either inPoly or outPoly
|
||||
// will have no vertices. That degenerate poly,
|
||||
// when added to a node, should just be pitched.
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
// Returns new root, in case it changed.
|
||||
// This assumes polys are being added front to back.
|
||||
// This function will break the poly into fragments that fit in the
|
||||
// current planes within the tree. Planes are added when a final fragment
|
||||
// is added (in IMakeSubTree).
|
||||
// We count on ITestPoly to properly mark edges which were created by
|
||||
// clipping, as those won't generate leaf nodes.
|
||||
plOccNode* plOccTree::IAddPolyRecur(plOccNode* node, plOccPoly* poly)
|
||||
{
|
||||
if( !poly->fVerts.GetCount() )
|
||||
return node;
|
||||
|
||||
if( !node )
|
||||
{
|
||||
return IMakeSubTree(poly);
|
||||
}
|
||||
|
||||
plOccPoly* inPoly = nil;
|
||||
plOccPoly* outPoly = nil;
|
||||
|
||||
|
||||
UInt32 test = ITestPoly(node->fPlane, poly, inPoly, outPoly);
|
||||
|
||||
switch( test )
|
||||
{
|
||||
case kAllIn:
|
||||
node->fInChild = IAddPolyRecur(node->fInChild, poly);
|
||||
break;
|
||||
case kAllOut:
|
||||
node->fOutChild = IAddPolyRecur(node->fOutChild, poly);
|
||||
break;
|
||||
case kSplit:
|
||||
node->fInChild = IAddPolyRecur(node->fInChild, inPoly);
|
||||
node->fOutChild = IAddPolyRecur(node->fOutChild, outPoly);
|
||||
break;
|
||||
};
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
hsBool plOccTree::BoundsVisible(const hsBounds3Ext& bnd) const
|
||||
{
|
||||
if( !fRoot )
|
||||
return true;
|
||||
|
||||
return fRoot->IBoundsVisible(bnd);
|
||||
}
|
||||
|
||||
|
||||
hsBool plOccNode::IInChildBoundsVisible(const hsBounds3Ext& bnd) const
|
||||
{
|
||||
return fInChild
|
||||
? fInChild->IBoundsVisible(bnd)
|
||||
: false;
|
||||
}
|
||||
|
||||
hsBool plOccNode::IOutChildBoundsVisible(const hsBounds3Ext& bnd) const
|
||||
{
|
||||
return fOutChild
|
||||
? fOutChild->IBoundsVisible(bnd)
|
||||
: true;
|
||||
}
|
||||
|
||||
hsBool plOccNode::IBoundsVisible(const hsBounds3Ext& bnd) const
|
||||
{
|
||||
hsPoint2 depth;
|
||||
bnd.TestPlane(fPlane.fNormal, depth);
|
||||
if( depth.fX > fPlane.fDist )
|
||||
{
|
||||
return IOutChildVisible(bnd);
|
||||
}
|
||||
else if( depth.fY < fPlane.fDist )
|
||||
{
|
||||
return IInChildVisible(bnd);
|
||||
}
|
||||
|
||||
// here's where it gets wierd. we pass the bounds in
|
||||
// both directions. if either says it's visible, it's visible.
|
||||
// doesn't seem like it would work, but you never know.
|
||||
return IOutChildVisible(bnd) || IInChildVisible(bnd);
|
||||
}
|
180
Sources/Plasma/PubUtilLib/plScene/plOccTree.h
Normal file
180
Sources/Plasma/PubUtilLib/plScene/plOccTree.h
Normal file
@ -0,0 +1,180 @@
|
||||
/*==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 plOccTree_inc
|
||||
#define plOccTree_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
#include "hsGeometry3.h"
|
||||
|
||||
class plBoundsHierarchy;
|
||||
|
||||
class plOccPlane
|
||||
{
|
||||
public:
|
||||
hsVector3 fNormal;
|
||||
hsScalar fDist;
|
||||
|
||||
};
|
||||
|
||||
class plOccPoly
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kEdgeClipped = 0x1
|
||||
};
|
||||
|
||||
plOccPlane fPlane;
|
||||
|
||||
hsTArray<hsPoint3> fVerts;
|
||||
hsTArray<UInt8> fEdgeFlags; // flag[i] => edge(fVerts[i], fVerts[(i+1)%n])
|
||||
};
|
||||
|
||||
class plOccNode
|
||||
{
|
||||
protected:
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kIsLeaf = 0x1
|
||||
};
|
||||
enum {
|
||||
kAllIn = 0x0,
|
||||
kAllOut = 0x1,
|
||||
kSplit = 0x2
|
||||
};
|
||||
|
||||
UInt32 fFlags;
|
||||
|
||||
plOccPlane fPolyPlane; // Plane of the poly we came from
|
||||
plOccPlane fViewPlane; // Plane perp to view dir.
|
||||
// For an interior node, ViewPlane is for the nearest (to view) point
|
||||
// on the poly. A bound closer than that will not be occluded by this
|
||||
// node or any nodes deeper in the tree.
|
||||
// For a leaf it's the farthest point on the poly. A bound inside this
|
||||
// plane OR the PolyPlane is occluded.
|
||||
|
||||
plOccNode* fInChild;
|
||||
|
||||
plOccNode* fOutChild;
|
||||
};
|
||||
|
||||
class plOccTree
|
||||
{
|
||||
protected:
|
||||
|
||||
enum {
|
||||
kNone = 0x0,
|
||||
kNeedsBuild = 0x1
|
||||
};
|
||||
|
||||
UInt8 fFlags;
|
||||
|
||||
// Temp pools for building our trees each frame.
|
||||
hsTArray<plOccPoly> fPolyPool;
|
||||
hsTArray<plOccPoly> fBasePolys;
|
||||
|
||||
// The BSP used to add our polys front to back. This BSP is constant.
|
||||
plOccNode* fBSP;
|
||||
|
||||
// This current frame's view pos and occluder tree.
|
||||
plOccNode* fRoot;
|
||||
hsPoint3 fViewPos;
|
||||
|
||||
|
||||
plOccNode* IAddPolyRecur(plOccNode* n, plOccPoly* poly);
|
||||
|
||||
void ITrimPoly(plOccPlane& plane, plOccPoly* polyIn, plOccPoly*& polyIn, plOccPoly*& polyOut);
|
||||
|
||||
plOccNode* IBuildOccTree();
|
||||
|
||||
public:
|
||||
|
||||
plOccTree() : fFlags(kNone), fBSP(nil), fRoot(nil) {}
|
||||
~plOccTree() {}
|
||||
|
||||
// We'll take in the view position (for sorting and building).
|
||||
// The view direction isn't necessary, but may be useful for
|
||||
// selecting a subset of occluders (like don't bother with ones parallel to the view dir).
|
||||
// What we really want is to pass in the viewport walls, or all the clip planes to initialize
|
||||
// the occtree, then occluders out of view are automatically pruned, and the single test
|
||||
// does the full view/portal/occluder test.
|
||||
void SetView(const hsPoint3& pos, const hsVector3& dir);
|
||||
|
||||
|
||||
// The algorithm is:
|
||||
// if bnd is totally inside this node's plane
|
||||
// recur bnd on inside child/leaf
|
||||
// else if bnd is totaly outside this node's plane
|
||||
// recur bnd on outside child
|
||||
// else
|
||||
// recur bnd's children on this node
|
||||
//
|
||||
// There's two ways to output the visibility info
|
||||
// 1) Set a visible/invisible bit for each of the bnd leaves
|
||||
// 2) output a list of visible bnds.
|
||||
// The second is preferable, since leaves determined invisible by interior
|
||||
// node tests never get traversed. But if the rendering pipeline has needs
|
||||
// to traverse the drawable data in some other order (for depth or material
|
||||
// sorting for example), then the list of visible bnds needs to be translated
|
||||
// into the first option anyway.
|
||||
//
|
||||
// Notes on the vague algorithm:
|
||||
// When recurring on the inside child, hitting a leaf checks against the source
|
||||
// occluder poly, with the usual inside=hidden, outside=visible, split recurs
|
||||
// the bnd's children on this leaf.
|
||||
// Hitting a nil outside child == visible
|
||||
// It's a double recursion, recurring first on the bnd hierarchy, and second on the occluder tree.
|
||||
// Recursion stops when:
|
||||
// 1) A bnd is totally in or totally out of a leaf of the occluder tree
|
||||
// 2) A bnd is a leaf of the bnd hierarchy.
|
||||
//
|
||||
void TestHeirarchy(plBoundsHierarchy* bnd);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
// Export only
|
||||
void AddPoly(plOccPoly* poly);
|
||||
void BuildBSP();
|
||||
};
|
||||
|
||||
#endif // plOccTree_inc
|
403
Sources/Plasma/PubUtilLib/plScene/plOccluder.cpp
Normal file
403
Sources/Plasma/PubUtilLib/plScene/plOccluder.cpp
Normal file
@ -0,0 +1,403 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plOccluder.h"
|
||||
#include "hsStream.h"
|
||||
#include "plOccluderProxy.h"
|
||||
#include "../plDrawable/plDrawableGenerator.h"
|
||||
#include "../plSurface/hsGMaterial.h"
|
||||
#include "../plSurface/plLayerInterface.h"
|
||||
#include "../plSurface/plLayer.h"
|
||||
#include "../pnMessage/plNodeRefMsg.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "plVisRegion.h"
|
||||
#include "plVisMgr.h"
|
||||
|
||||
plOccluder::plOccluder()
|
||||
: fSceneNode(nil)
|
||||
{
|
||||
fProxyGen = TRACKED_NEW plOccluderProxy;
|
||||
fProxyGen->Init(this);
|
||||
|
||||
fVisSet.SetBit(0);
|
||||
}
|
||||
|
||||
plOccluder::~plOccluder()
|
||||
{
|
||||
delete fProxyGen;
|
||||
}
|
||||
|
||||
hsBool plOccluder::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
switch( refMsg->fType )
|
||||
{
|
||||
case kRefVisRegion:
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
IAddVisRegion(plVisRegion::ConvertNoRef(refMsg->GetRef()));
|
||||
}
|
||||
else
|
||||
{
|
||||
IRemoveVisRegion(plVisRegion::ConvertNoRef(refMsg->GetRef()));
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
return plObjInterface::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plOccluder::IAddVisRegion(plVisRegion* reg)
|
||||
{
|
||||
if( reg )
|
||||
{
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( fVisRegions.kMissingIndex == idx )
|
||||
{
|
||||
fVisRegions.Append(reg);
|
||||
if( reg->GetProperty(plVisRegion::kIsNot) )
|
||||
fVisNot.SetBit(reg->GetIndex());
|
||||
else
|
||||
{
|
||||
fVisSet.SetBit(reg->GetIndex());
|
||||
if( reg->ReplaceNormal() )
|
||||
fVisSet.ClearBit(plVisMgr::kNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plOccluder::IRemoveVisRegion(plVisRegion* reg)
|
||||
{
|
||||
if( reg )
|
||||
{
|
||||
int idx = fVisRegions.Find(reg);
|
||||
if( fVisRegions.kMissingIndex != idx )
|
||||
{
|
||||
fVisRegions.Remove(idx);
|
||||
if( reg->GetProperty(plVisRegion::kIsNot) )
|
||||
fVisNot.ClearBit(reg->GetIndex());
|
||||
else
|
||||
fVisSet.ClearBit(reg->GetIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plDrawableSpans* plOccluder::CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo)
|
||||
{
|
||||
hsTArray<hsPoint3> pos;
|
||||
hsTArray<hsVector3> norm;
|
||||
hsTArray<hsColorRGBA> color;
|
||||
hsTArray<UInt16> tris;
|
||||
|
||||
plLayer* lay = plLayer::ConvertNoRef(mat->GetLayer(0)->BottomOfStack());
|
||||
if( lay )
|
||||
lay->SetMiscFlags(lay->GetMiscFlags() & ~hsGMatState::kMiscTwoSided);
|
||||
|
||||
const hsTArray<plCullPoly>& polys = GetLocalPolyList();
|
||||
int i;
|
||||
for( i = 0; i < polys.GetCount(); i++ )
|
||||
{
|
||||
hsColorRGBA col;
|
||||
if( polys[i].IsHole() )
|
||||
col.Set(0,0,0,1.f);
|
||||
else
|
||||
col.Set(1.f, 1.f, 1.f, 1.f);
|
||||
|
||||
int triStart = tris.GetCount();
|
||||
|
||||
int idx0 = pos.GetCount();
|
||||
pos.Append(polys[i].fVerts[0]);
|
||||
norm.Append(polys[i].fNorm);
|
||||
color.Append(col);
|
||||
pos.Append(polys[i].fVerts[1]);
|
||||
norm.Append(polys[i].fNorm);
|
||||
color.Append(col);
|
||||
int j;
|
||||
for( j = 2; j < polys[i].fVerts.GetCount(); j++ )
|
||||
{
|
||||
int idxCurr = pos.GetCount();
|
||||
pos.Append(polys[i].fVerts[j]);
|
||||
norm.Append(polys[i].fNorm);
|
||||
color.Append(col);
|
||||
tris.Append(idx0);
|
||||
tris.Append(idxCurr-1);
|
||||
tris.Append(idxCurr);
|
||||
}
|
||||
#if 1
|
||||
if( polys[i].IsTwoSided() )
|
||||
{
|
||||
int n = tris.GetCount();
|
||||
while( --n >= triStart )
|
||||
{
|
||||
int idx = tris[n];
|
||||
tris.Append(idx);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return plDrawableGenerator::GenerateDrawable(pos.GetCount(),
|
||||
pos.AcquireArray(),
|
||||
norm.AcquireArray(),
|
||||
nil, 0,
|
||||
color.AcquireArray(),
|
||||
true,
|
||||
nil,
|
||||
tris.GetCount(),
|
||||
tris.AcquireArray(),
|
||||
mat,
|
||||
GetLocalToWorld(),
|
||||
true,
|
||||
&idx,
|
||||
addTo);
|
||||
}
|
||||
|
||||
void plOccluder::SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l)
|
||||
{
|
||||
// Commenting out the following asserts. Although they are fundamentally correct,
|
||||
//essentially identity matrices which aren't so flagged (because of numerical
|
||||
// precision) are triggering bogus asserts. mf
|
||||
// hsAssert(l2w.fFlags & hsMatrix44::kIsIdent, "Non-identity transform to non-movable Occluder");
|
||||
// hsAssert(w2l.fFlags & hsMatrix44::kIsIdent, "Non-identity transform to non-movable Occluder");
|
||||
}
|
||||
|
||||
const hsMatrix44& plOccluder::GetLocalToWorld() const
|
||||
{
|
||||
return hsMatrix44::IdentityMatrix();
|
||||
}
|
||||
|
||||
const hsMatrix44& plOccluder::GetWorldToLocal() const
|
||||
{
|
||||
return hsMatrix44::IdentityMatrix();
|
||||
}
|
||||
|
||||
void plOccluder::ComputeFromPolys()
|
||||
{
|
||||
IComputeBounds();
|
||||
IComputeSurfaceArea();
|
||||
}
|
||||
|
||||
void plOccluder::IComputeBounds()
|
||||
{
|
||||
fWorldBounds.MakeEmpty();
|
||||
|
||||
const hsTArray<plCullPoly>& polys = GetLocalPolyList();
|
||||
int i;
|
||||
for( i =0 ; i < polys.GetCount(); i++ )
|
||||
{
|
||||
int j;
|
||||
for( j = 0; j < polys[i].fVerts.GetCount(); j++ )
|
||||
fWorldBounds.Union(&polys[i].fVerts[j]);
|
||||
}
|
||||
}
|
||||
|
||||
hsScalar plOccluder::IComputeSurfaceArea()
|
||||
{
|
||||
hsScalar area = 0;
|
||||
const hsTArray<plCullPoly>& polys = GetLocalPolyList();
|
||||
int i;
|
||||
for( i =0 ; i < polys.GetCount(); i++ )
|
||||
{
|
||||
int j;
|
||||
for( j = 2; j < polys[i].fVerts.GetCount(); j++ )
|
||||
{
|
||||
area += (hsVector3(&polys[i].fVerts[j], &polys[i].fVerts[j-2]) % hsVector3(&polys[i].fVerts[j-1], &polys[i].fVerts[j-2])).Magnitude();
|
||||
}
|
||||
}
|
||||
area *= 0.5f;
|
||||
|
||||
return fPriority = area;
|
||||
}
|
||||
|
||||
void plOccluder::SetPolyList(const hsTArray<plCullPoly>& list)
|
||||
{
|
||||
UInt16 n = list.GetCount();
|
||||
fPolys.SetCount(n);
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
fPolys[i] = list[i];
|
||||
}
|
||||
|
||||
void plOccluder::ISetSceneNode(plKey node)
|
||||
{
|
||||
if( fSceneNode != node )
|
||||
{
|
||||
if( node )
|
||||
{
|
||||
plNodeRefMsg* refMsg = TRACKED_NEW plNodeRefMsg(node, plRefMsg::kOnCreate, -1, plNodeRefMsg::kOccluder);
|
||||
hsgResMgr::ResMgr()->AddViaNotify(GetKey(), refMsg, plRefFlags::kPassiveRef);
|
||||
}
|
||||
if( fSceneNode )
|
||||
{
|
||||
fSceneNode->Release(GetKey());
|
||||
}
|
||||
fSceneNode = node;
|
||||
}
|
||||
}
|
||||
|
||||
void plOccluder::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Read(s, mgr);
|
||||
|
||||
fWorldBounds.Read(s);
|
||||
fPriority = s->ReadSwapScalar();
|
||||
|
||||
hsTArray<plCullPoly>& localPolys = IGetLocalPolyList();
|
||||
UInt16 n = s->ReadSwap16();
|
||||
localPolys.SetCount(n);
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
localPolys[i].Read(s, mgr);
|
||||
|
||||
plKey nodeKey = mgr->ReadKey(s);
|
||||
ISetSceneNode(nodeKey);
|
||||
|
||||
n = s->ReadSwap16();
|
||||
fVisRegions.SetCountAndZero(n);
|
||||
for( i = 0; i < n; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefVisRegion), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
void plOccluder::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Write(s, mgr);
|
||||
|
||||
fWorldBounds.Write(s);
|
||||
s->WriteSwapScalar(fPriority);
|
||||
|
||||
const hsTArray<plCullPoly>& localPolys = IGetLocalPolyList();
|
||||
s->WriteSwap16(localPolys.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < localPolys.GetCount(); i++ )
|
||||
localPolys[i].Write(s, mgr);
|
||||
|
||||
mgr->WriteKey(s, fSceneNode);
|
||||
|
||||
s->WriteSwap16(fVisRegions.GetCount());
|
||||
for( i = 0; i < fVisRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fVisRegions[i]);
|
||||
}
|
||||
|
||||
plMobileOccluder::plMobileOccluder()
|
||||
{
|
||||
fLocalToWorld.Reset();
|
||||
fWorldToLocal.Reset();
|
||||
}
|
||||
|
||||
plMobileOccluder::~plMobileOccluder()
|
||||
{
|
||||
}
|
||||
|
||||
void plMobileOccluder::IComputeBounds()
|
||||
{
|
||||
plOccluder::IComputeBounds();
|
||||
fLocalBounds = fWorldBounds;
|
||||
fWorldBounds.Transform(&fLocalToWorld);
|
||||
}
|
||||
|
||||
void plMobileOccluder::SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l)
|
||||
{
|
||||
fLocalToWorld = l2w;
|
||||
fWorldToLocal = w2l;
|
||||
|
||||
if( fPolys.GetCount() != fOrigPolys.GetCount() )
|
||||
fPolys.SetCount(fOrigPolys.GetCount());
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fPolys.GetCount(); i++ )
|
||||
fOrigPolys[i].Transform(l2w, w2l, fPolys[i]);
|
||||
|
||||
if( fProxyGen )
|
||||
fProxyGen->SetTransform(l2w, w2l);
|
||||
}
|
||||
|
||||
void plMobileOccluder::SetPolyList(const hsTArray<plCullPoly>& list)
|
||||
{
|
||||
UInt16 n = list.GetCount();
|
||||
fOrigPolys.SetCount(n);
|
||||
fPolys.SetCount(n);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
fPolys[i] = fOrigPolys[i] = list[i];
|
||||
}
|
||||
}
|
||||
|
||||
void plMobileOccluder::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plOccluder::Read(s, mgr);
|
||||
|
||||
fLocalToWorld.Read(s);
|
||||
fWorldToLocal.Read(s);
|
||||
|
||||
fLocalBounds.Read(s);
|
||||
|
||||
fPolys.SetCount(fOrigPolys.GetCount());
|
||||
|
||||
SetTransform(fLocalToWorld, fWorldToLocal);
|
||||
}
|
||||
|
||||
void plMobileOccluder::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plOccluder::Write(s, mgr);
|
||||
|
||||
fLocalToWorld.Write(s);
|
||||
fWorldToLocal.Write(s);
|
||||
|
||||
fLocalBounds.Write(s);
|
||||
}
|
||||
|
||||
void plMobileOccluder::ComputeFromPolys()
|
||||
{
|
||||
SetTransform(fLocalToWorld, fWorldToLocal);
|
||||
plOccluder::ComputeFromPolys();
|
||||
}
|
||||
|
169
Sources/Plasma/PubUtilLib/plScene/plOccluder.h
Normal file
169
Sources/Plasma/PubUtilLib/plScene/plOccluder.h
Normal file
@ -0,0 +1,169 @@
|
||||
/*==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 plOccluder_inc
|
||||
#define plOccluder_inc
|
||||
|
||||
#include "../pnSceneObject/plObjInterface.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "plCullPoly.h"
|
||||
#include "hsBounds.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
class plOccluderProxy;
|
||||
class plDrawableSpans;
|
||||
class hsGMaterial;
|
||||
class plVisRegion;
|
||||
|
||||
class plOccluder : public plObjInterface
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kDisable = 0x0,
|
||||
|
||||
kNumProps
|
||||
};
|
||||
enum {
|
||||
kRefVisRegion
|
||||
};
|
||||
protected:
|
||||
hsTArray<plCullPoly> fPolys;
|
||||
|
||||
plOccluderProxy* fProxyGen;
|
||||
|
||||
hsBitVector fVisSet;
|
||||
hsTArray<plVisRegion*> fVisRegions;
|
||||
hsBitVector fVisNot;
|
||||
|
||||
hsScalar fPriority;
|
||||
hsBounds3Ext fWorldBounds;
|
||||
|
||||
plKey fSceneNode;
|
||||
|
||||
virtual hsScalar IComputeSurfaceArea();
|
||||
virtual void IComputeBounds();
|
||||
|
||||
virtual hsTArray<plCullPoly>& IGetLocalPolyList() { return fPolys; }
|
||||
|
||||
virtual void ISetSceneNode(plKey node);
|
||||
|
||||
void IAddVisRegion(plVisRegion* reg);
|
||||
void IRemoveVisRegion(plVisRegion* reg);
|
||||
|
||||
public:
|
||||
plOccluder();
|
||||
virtual ~plOccluder();
|
||||
|
||||
CLASSNAME_REGISTER( plOccluder );
|
||||
GETINTERFACE_ANY( plOccluder, plObjInterface);
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual hsScalar GetPriority() const { return fPriority; }
|
||||
|
||||
hsBool InVisSet(const hsBitVector& visSet) const { return fVisSet.Overlap(visSet); }
|
||||
hsBool InVisNot(const hsBitVector& visNot) const { return fVisNot.Overlap(visNot); }
|
||||
|
||||
virtual const hsBounds3Ext& GetWorldBounds() const { return fWorldBounds; }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
virtual const hsMatrix44& GetLocalToWorld() const;
|
||||
virtual const hsMatrix44& GetWorldToLocal() const;
|
||||
|
||||
virtual void SetPolyList(const hsTArray<plCullPoly>& list);
|
||||
virtual const hsTArray<plCullPoly>& GetWorldPolyList() const { return fPolys; }
|
||||
virtual const hsTArray<plCullPoly>& GetLocalPolyList() const { return fPolys; }
|
||||
|
||||
virtual Int32 GetNumProperties() const { return kNumProps; }
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
// Visualization
|
||||
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
|
||||
|
||||
// Export only function to initialize.
|
||||
virtual void ComputeFromPolys();
|
||||
|
||||
// These two should only be called internally and on export/convert
|
||||
virtual plKey GetSceneNode() const { return fSceneNode; }
|
||||
};
|
||||
|
||||
class plMobileOccluder : public plOccluder
|
||||
{
|
||||
protected:
|
||||
hsMatrix44 fLocalToWorld;
|
||||
hsMatrix44 fWorldToLocal;
|
||||
|
||||
hsBounds3Ext fLocalBounds;
|
||||
|
||||
hsTArray<plCullPoly> fOrigPolys;
|
||||
|
||||
virtual void IComputeBounds();
|
||||
|
||||
virtual hsTArray<plCullPoly>& IGetLocalPolyList() { return fOrigPolys; }
|
||||
|
||||
public:
|
||||
|
||||
plMobileOccluder();
|
||||
virtual ~plMobileOccluder();
|
||||
|
||||
CLASSNAME_REGISTER( plMobileOccluder );
|
||||
GETINTERFACE_ANY( plMobileOccluder, plOccluder );
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
virtual const hsMatrix44& GetLocalToWorld() const { return fLocalToWorld; }
|
||||
virtual const hsMatrix44& GetWorldToLocal() const { return fWorldToLocal; }
|
||||
|
||||
virtual void SetPolyList(const hsTArray<plCullPoly>& list);
|
||||
|
||||
virtual const hsTArray<plCullPoly>& GetLocalPolyList() const { return fOrigPolys; }
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
// Export only function to initialize.
|
||||
virtual void ComputeFromPolys();
|
||||
};
|
||||
|
||||
#endif // plOccluder_inc
|
82
Sources/Plasma/PubUtilLib/plScene/plOccluderProxy.cpp
Normal file
82
Sources/Plasma/PubUtilLib/plScene/plOccluderProxy.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plOccluderProxy.h"
|
||||
#include "plOccluder.h"
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../plDrawable/plDrawableGenerator.h"
|
||||
#include "../pnMessage/plProxyDrawMsg.h"
|
||||
|
||||
plOccluderProxy::plOccluderProxy()
|
||||
: plProxyGen(hsColorRGBA().Set(0.2f,0.2f,0.8f,1.f), hsColorRGBA().Set(1.f,0.5f,0.5f,1.f), 0.5f),
|
||||
fOwner(nil)
|
||||
{
|
||||
}
|
||||
|
||||
plOccluderProxy::~plOccluderProxy()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plOccluderProxy::Init(plOccluder* occluder)
|
||||
{
|
||||
plProxyGen::Init(occluder);
|
||||
|
||||
fOwner = occluder;
|
||||
fProxyMsgType = plProxyDrawMsg::kOccluder;
|
||||
|
||||
return fOwner != nil;
|
||||
}
|
||||
|
||||
plKey plOccluderProxy::IGetNode() const
|
||||
{
|
||||
return fOwner ? fOwner->GetSceneNode() : nil;
|
||||
}
|
||||
|
||||
plDrawableSpans* plOccluderProxy::ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo)
|
||||
{
|
||||
if( fOwner )
|
||||
{
|
||||
return fOwner->CreateProxy(mat, idx, addTo);
|
||||
}
|
||||
return nil;
|
||||
}
|
67
Sources/Plasma/PubUtilLib/plScene/plOccluderProxy.h
Normal file
67
Sources/Plasma/PubUtilLib/plScene/plOccluderProxy.h
Normal file
@ -0,0 +1,67 @@
|
||||
/*==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 plOccluderProxy_inc
|
||||
#define plOccluderProxy_inc
|
||||
|
||||
#include "../plDrawable/plProxyGen.h"
|
||||
|
||||
class plOccluder;
|
||||
class plDrawableSpans;
|
||||
class hsGMaterial;
|
||||
|
||||
class plOccluderProxy : public plProxyGen
|
||||
{
|
||||
protected:
|
||||
plOccluder* fOwner;
|
||||
|
||||
|
||||
virtual plDrawableSpans* ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo=nil);
|
||||
virtual plKey IGetNode() const;
|
||||
public:
|
||||
plOccluderProxy();
|
||||
virtual ~plOccluderProxy();
|
||||
|
||||
hsBool Init(plOccluder* occluder);
|
||||
};
|
||||
|
||||
#endif // plOccluderProxy_inc
|
712
Sources/Plasma/PubUtilLib/plScene/plPageTreeMgr.cpp
Normal file
712
Sources/Plasma/PubUtilLib/plScene/plPageTreeMgr.cpp
Normal file
@ -0,0 +1,712 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plPageTreeMgr.h"
|
||||
#include "../plDrawable/plSpaceTreeMaker.h"
|
||||
#include "../plDrawable/plSpaceTree.h"
|
||||
#include "plDrawable.h"
|
||||
#include "../plScene/plSceneNode.h"
|
||||
#include "plPipeline.h"
|
||||
#include "../plMath/hsRadixSort.h"
|
||||
#include "plCullPoly.h"
|
||||
#include "plOccluder.h"
|
||||
#include "hsFastMath.h"
|
||||
#include "plProfile.h"
|
||||
#include "plVisMgr.h"
|
||||
|
||||
#include "plTweak.h"
|
||||
|
||||
static hsTArray<hsRadixSortElem> scratchList;
|
||||
|
||||
hsBool plPageTreeMgr::fDisableVisMgr = 0;
|
||||
|
||||
plProfile_CreateTimer("Object Sort", "Draw", DrawObjSort);
|
||||
plProfile_CreateCounter("Objects Sorted", "Draw", DrawObjSorted);
|
||||
plProfile_CreateTimer("Occluder Sort", "Draw", DrawOccSort);
|
||||
plProfile_CreateCounter("Occluders Used", "Draw", DrawOccUsed);
|
||||
plProfile_CreateTimer("Occluder Build", "Draw", DrawOccBuild);
|
||||
plProfile_CreateCounter("Occluder Polys Processed", "Draw", DrawOccPolyProc);
|
||||
plProfile_CreateTimer("Occluder Poly Sort", "Draw", DrawOccPolySort);
|
||||
|
||||
plPageTreeMgr::plPageTreeMgr()
|
||||
: fSpaceTree(nil)
|
||||
{
|
||||
fVisMgr = plGlobalVisMgr::Instance();
|
||||
}
|
||||
|
||||
plPageTreeMgr::~plPageTreeMgr()
|
||||
{
|
||||
delete fSpaceTree;
|
||||
}
|
||||
|
||||
void plPageTreeMgr::AddNode(plSceneNode* node)
|
||||
{
|
||||
ITrashSpaceTree();
|
||||
|
||||
node->Init();
|
||||
|
||||
fNodes.Append(node);
|
||||
}
|
||||
|
||||
void plPageTreeMgr::RemoveNode(plSceneNode* node)
|
||||
{
|
||||
ITrashSpaceTree();
|
||||
|
||||
int idx = fNodes.Find(node);
|
||||
if( idx != fNodes.kMissingIndex )
|
||||
fNodes.Remove(idx);
|
||||
}
|
||||
|
||||
void plPageTreeMgr::Reset()
|
||||
{
|
||||
fNodes.Reset();
|
||||
|
||||
ITrashSpaceTree();
|
||||
}
|
||||
|
||||
void plPageTreeMgr::ITrashSpaceTree()
|
||||
{
|
||||
delete fSpaceTree;
|
||||
fSpaceTree = nil;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::Harvest(plVolumeIsect* isect, hsTArray<plDrawVisList>& levList)
|
||||
{
|
||||
levList.SetCount(0);
|
||||
if( !(GetSpaceTree() || IBuildSpaceTree()) )
|
||||
return false;
|
||||
|
||||
static hsTArray<Int16> list;
|
||||
|
||||
GetSpaceTree()->HarvestLeaves(isect, list);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < list.GetCount(); i++ )
|
||||
{
|
||||
fNodes[list[i]]->Harvest(isect, levList);
|
||||
}
|
||||
|
||||
return levList.GetCount() > 0;
|
||||
}
|
||||
|
||||
#include "plProfile.h"
|
||||
plProfile_CreateTimer("DrawableTime", "Draw", DrawableTime);
|
||||
plProfile_Extern(RenderScene);
|
||||
|
||||
int plPageTreeMgr::Render(plPipeline* pipe)
|
||||
{
|
||||
// If we don't have a space tree and can't make one, just bail
|
||||
if( !(GetSpaceTree() || IBuildSpaceTree()) )
|
||||
return 0;
|
||||
|
||||
static hsTArray<Int16> list;
|
||||
list.SetCount(0);
|
||||
|
||||
plProfile_BeginTiming(RenderScene);
|
||||
|
||||
plVisMgr* visMgr = fDisableVisMgr ? nil : fVisMgr;
|
||||
|
||||
if( visMgr )
|
||||
{
|
||||
plProfile_Extern(VisEval);
|
||||
plProfile_BeginTiming(VisEval);
|
||||
visMgr->Eval(pipe->GetViewPositionWorld());
|
||||
plProfile_EndTiming(VisEval);
|
||||
}
|
||||
|
||||
pipe->BeginVisMgr(visMgr);
|
||||
|
||||
IRefreshTree(pipe);
|
||||
|
||||
IGetOcclusion(pipe, list);
|
||||
pipe->HarvestVisible(GetSpaceTree(), list);
|
||||
|
||||
static hsTArray<plDrawVisList> levList;
|
||||
levList.SetCount(0);
|
||||
int i;
|
||||
for( i = 0; i < list.GetCount(); i++ )
|
||||
{
|
||||
fNodes[list[i]]->CollectForRender(pipe, levList, visMgr);
|
||||
}
|
||||
|
||||
int numDrawn = IRenderVisList(pipe, levList);
|
||||
|
||||
IResetOcclusion(pipe);
|
||||
|
||||
pipe->EndVisMgr(visMgr);
|
||||
|
||||
plProfile_EndTiming(RenderScene);
|
||||
|
||||
return numDrawn;
|
||||
|
||||
}
|
||||
|
||||
int plPageTreeMgr::IRenderVisList(plPipeline* pipe, hsTArray<plDrawVisList>& levList)
|
||||
{
|
||||
// Sort levList into sortedDrawList, which is just a list
|
||||
// of drawable/visList pairs in ascending render priority order.
|
||||
// visLists are just lists of span indices, but only of the
|
||||
// spans which are visible (on screen and non-occluded and non-disabled).
|
||||
static hsTArray<plDrawVisList> sortedDrawList;
|
||||
if( !ISortByLevel(pipe, levList, sortedDrawList) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int numDrawn = 0;
|
||||
|
||||
plVisMgr* visMgr = fDisableVisMgr ? nil : fVisMgr;
|
||||
|
||||
// Going through the list in order, if we hit a drawable which doesn't need
|
||||
// its spans sorted, we can just draw it.
|
||||
// If we hit a drawable which does need its spans sorted, we could just draw
|
||||
// it, but that precludes sorting spans between drawables (like the player avatar
|
||||
// sorting with normal scene objects). So when we hit a drawable which needs
|
||||
// span sorting, we sort its spans with the spans of the next N drawables in
|
||||
// the sorted list which have the same render priority and which also want their
|
||||
// spans sorted.
|
||||
int i;
|
||||
for( i = 0; i < sortedDrawList.GetCount(); i++ )
|
||||
{
|
||||
plDrawable* p = sortedDrawList[i].fDrawable;
|
||||
|
||||
|
||||
plProfile_BeginLap(DrawableTime, p->GetKey()->GetUoid().GetObjectName());
|
||||
|
||||
if( sortedDrawList[i].fDrawable->GetNativeProperty(plDrawable::kPropSortSpans) )
|
||||
{
|
||||
// IPrepForRenderSortingSpans increments "i" to the next index to be drawn (-1 so the i++
|
||||
// at the top of the loop is correct.
|
||||
numDrawn += IPrepForRenderSortingSpans(pipe, sortedDrawList, i);
|
||||
}
|
||||
else
|
||||
{
|
||||
pipe->PrepForRender(sortedDrawList[i].fDrawable, sortedDrawList[i].fVisList, visMgr);
|
||||
|
||||
pipe->Render(sortedDrawList[i].fDrawable, sortedDrawList[i].fVisList);
|
||||
|
||||
numDrawn += sortedDrawList[i].fVisList.GetCount();
|
||||
|
||||
}
|
||||
|
||||
plProfile_EndLap(DrawableTime, p->GetKey()->GetUoid().GetObjectName());
|
||||
}
|
||||
|
||||
return numDrawn;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::ISortByLevel(plPipeline* pipe, hsTArray<plDrawVisList>& drawList, hsTArray<plDrawVisList>& sortedDrawList)
|
||||
{
|
||||
sortedDrawList.SetCount(0);
|
||||
|
||||
if( !drawList.GetCount() )
|
||||
return false;
|
||||
|
||||
scratchList.SetCount(drawList.GetCount());
|
||||
|
||||
hsRadixSort::Elem* listTrav = nil;
|
||||
int i;
|
||||
for( i = 0; i < drawList.GetCount(); i++ )
|
||||
{
|
||||
listTrav = &scratchList[i];
|
||||
listTrav->fBody = (void*)&drawList[i];
|
||||
listTrav->fNext = listTrav+1;
|
||||
listTrav->fKey.fULong = drawList[i].fDrawable->GetRenderLevel().Level();
|
||||
}
|
||||
listTrav->fNext = nil;
|
||||
|
||||
hsRadixSort rad;
|
||||
hsRadixSort::Elem* sortedList = rad.Sort(scratchList.AcquireArray(), hsRadixSort::kUnsigned);
|
||||
|
||||
listTrav = sortedList;
|
||||
|
||||
while( listTrav )
|
||||
{
|
||||
plDrawVisList& drawVis = *(plDrawVisList*)listTrav->fBody;
|
||||
sortedDrawList.Append(drawVis);
|
||||
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Render from iDrawStart in drawVis list all drawables with the sort by spans property, well, sorting
|
||||
// by spans.
|
||||
// Returns the index of the last one drawn.
|
||||
int plPageTreeMgr::IPrepForRenderSortingSpans(plPipeline* pipe, hsTArray<plDrawVisList>& drawVis, int& iDrawStart)
|
||||
{
|
||||
UInt32 renderLevel = drawVis[iDrawStart].fDrawable->GetRenderLevel().Level();
|
||||
|
||||
int i;
|
||||
|
||||
static hsTArray<plDrawVisList*> drawables;
|
||||
static hsTArray<plDrawSpanPair> pairs;
|
||||
|
||||
// Given the input drawVisList (list of drawable/visList pairs), we make two new
|
||||
// lists. The list "drawables" is just the excerpted sub-list from drawVis starting
|
||||
// from the input index and going through all compatible drawables (drawables which
|
||||
// are appropriate to sort (and hence intermix) with the first drawable in the list.
|
||||
// The second list is the drawableIndex/spanIndex pairs convenient for sorting (where
|
||||
// drawIndex indexes into drawables and spanIndex indexes into drawVis[iDraw].fVisList.
|
||||
// So pairs[i] resolves into
|
||||
// drawables[pairs[i].fDrawable].fDrawable->GetSpan(pairs[i].fSpan)
|
||||
|
||||
drawables.Append(&drawVis[iDrawStart]);
|
||||
for( i = 0; i < drawVis[iDrawStart].fVisList.GetCount(); i++ )
|
||||
{
|
||||
plDrawSpanPair* pair = pairs.Push();
|
||||
pair->fDrawable = 0;
|
||||
pair->fSpan = drawVis[iDrawStart].fVisList[i];
|
||||
}
|
||||
|
||||
int iDraw;
|
||||
for( iDraw = iDrawStart+1;
|
||||
(iDraw < drawVis.GetCount())
|
||||
&& (drawVis[iDraw].fDrawable->GetRenderLevel().Level() == renderLevel)
|
||||
&& drawVis[iDraw].fDrawable->GetNativeProperty(plDrawable::kPropSortSpans);
|
||||
iDraw++ )
|
||||
{
|
||||
plDrawable* drawable = drawVis[iDraw].fDrawable;
|
||||
hsTArray<Int16>& visList = drawVis[iDraw].fVisList;
|
||||
for( i = 0; i < visList.GetCount(); i++ )
|
||||
{
|
||||
plDrawSpanPair* pair = pairs.Push();
|
||||
pair->fDrawable = drawables.GetCount();
|
||||
pair->fSpan = visList[i];
|
||||
}
|
||||
drawables.Append(&drawVis[iDraw]);
|
||||
}
|
||||
|
||||
// Now that we have them in a more convenient format, sort them and render.
|
||||
IRenderSortingSpans(pipe, drawables, pairs);
|
||||
|
||||
int numDrawn = pairs.GetCount();
|
||||
|
||||
drawables.SetCount(0);
|
||||
pairs.SetCount(0);
|
||||
|
||||
iDrawStart = iDraw - 1;
|
||||
|
||||
return numDrawn;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::IRenderSortingSpans(plPipeline* pipe, hsTArray<plDrawVisList*>& drawList, hsTArray<plDrawSpanPair>& pairs)
|
||||
{
|
||||
|
||||
if( !pairs.GetCount() )
|
||||
return false;
|
||||
|
||||
hsPoint3 viewPos = pipe->GetViewPositionWorld();
|
||||
|
||||
plProfile_BeginTiming(DrawObjSort);
|
||||
plProfile_IncCount(DrawObjSorted, pairs.GetCount());
|
||||
|
||||
hsRadixSort::Elem* listTrav;
|
||||
scratchList.SetCount(pairs.GetCount());
|
||||
|
||||
// First, sort on distance to the camera (squared).
|
||||
listTrav = nil;
|
||||
int iSort = 0;
|
||||
int i;
|
||||
for( i = 0; i < pairs.GetCount(); i++ )
|
||||
{
|
||||
plDrawable* drawable = drawList[pairs[i].fDrawable]->fDrawable;
|
||||
|
||||
listTrav = &scratchList[iSort++];
|
||||
listTrav->fBody = (void*)*(UInt32*)&pairs[i];
|
||||
listTrav->fNext = listTrav + 1;
|
||||
|
||||
if( drawable->GetNativeProperty(plDrawable::kPropSortAsOne) )
|
||||
{
|
||||
const hsBounds3Ext& bnd = drawable->GetSpaceTree()->GetNode(drawable->GetSpaceTree()->GetRoot()).fWorldBounds;
|
||||
plConst(hsScalar) kDistFudge(1.e-1f);
|
||||
listTrav->fKey.fFloat = -(bnd.GetCenter() - viewPos).MagnitudeSquared() + hsScalar(pairs[i].fSpan) * kDistFudge;
|
||||
}
|
||||
else
|
||||
{
|
||||
const hsBounds3Ext& bnd = drawable->GetSpaceTree()->GetNode(pairs[i].fSpan).fWorldBounds;
|
||||
listTrav->fKey.fFloat = -(bnd.GetCenter() - viewPos).MagnitudeSquared();
|
||||
}
|
||||
}
|
||||
if( !listTrav )
|
||||
{
|
||||
plProfile_EndTiming(DrawObjSort);
|
||||
return false;
|
||||
}
|
||||
listTrav->fNext = nil;
|
||||
|
||||
hsRadixSort rad;
|
||||
hsRadixSort::Elem* sortedList = rad.Sort(scratchList.AcquireArray(), 0);
|
||||
|
||||
plProfile_EndTiming(DrawObjSort);
|
||||
|
||||
static hsTArray<Int16> visList;
|
||||
visList.SetCount(0);
|
||||
|
||||
plVisMgr* visMgr = fDisableVisMgr ? nil : fVisMgr;
|
||||
|
||||
// Call PrepForRender on each of these bad boys. We only want to call
|
||||
// PrepForRender once on each drawable, no matter how many times we're
|
||||
// going to pass it off to be rendered (like if we render span 0 from
|
||||
// drawable A, span 1 from drawable A, span 0 from drawable B, span 1 from Drawable A, we
|
||||
// don't want to PrepForRender twice or three times on drawable A).
|
||||
// So we're going to convert our sorted list back into a list of drawable/visList
|
||||
// pairs. We could have done this with our original drawable/visList, but we've
|
||||
// hopefully trimmed out some spans because of the fades. This drawable/visList
|
||||
// isn't appropriate for rendering (because it doesn't let us switch back and forth
|
||||
// from a drawable, but it's right for the PrepForRenderCall (which does things like
|
||||
// face sorting).
|
||||
for( i = 0; i < drawList.GetCount(); i++ )
|
||||
drawList[i]->fVisList.SetCount(0);
|
||||
listTrav = sortedList;
|
||||
while( listTrav )
|
||||
{
|
||||
plDrawSpanPair& curPair = *(plDrawSpanPair*)&listTrav->fBody;
|
||||
drawList[curPair.fDrawable]->fVisList.Append(curPair.fSpan);
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
for( i = 0; i < drawList.GetCount(); i++ )
|
||||
{
|
||||
pipe->PrepForRender(drawList[i]->fDrawable, drawList[i]->fVisList, visMgr);
|
||||
}
|
||||
|
||||
// We'd like to call Render once on a drawable for each contiguous
|
||||
// set of spans (so we want to render span 0 and span 1 on a single Render
|
||||
// of drawable A in the above, then render drawable B, then back to A).
|
||||
// So we go through the sorted drawable/spanIndex pairs list, building
|
||||
// a visList for as long as the drawable remains the same. When it
|
||||
// changes, we render what we have so far, and start again with the
|
||||
// next drawable. Repeat until done.
|
||||
|
||||
#if 0
|
||||
listTrav = sortedList;
|
||||
plDrawSpanPair& curPair = *(plDrawSpanPair*)&listTrav->fBody;
|
||||
int curDraw = curPair.fDrawable;
|
||||
visList.Append(curPair.fSpan);
|
||||
listTrav = listTrav->fNext;
|
||||
|
||||
while( listTrav )
|
||||
{
|
||||
curPair = *(plDrawSpanPair*)&listTrav->fBody;
|
||||
if( curPair.fDrawable != curDraw )
|
||||
{
|
||||
pipe->Render(drawList[curDraw]->fDrawable, visList);
|
||||
curDraw = curPair.fDrawable;
|
||||
visList.SetCount(0);
|
||||
visList.Append(curPair.fSpan);
|
||||
}
|
||||
else
|
||||
{
|
||||
visList.Append(curPair.fSpan);
|
||||
}
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
pipe->Render(drawList[curDraw]->fDrawable, visList);
|
||||
#else
|
||||
listTrav = sortedList;
|
||||
plDrawSpanPair& curPair = *(plDrawSpanPair*)&listTrav->fBody;
|
||||
int curDraw = curPair.fDrawable;
|
||||
listTrav = listTrav->fNext;
|
||||
|
||||
static hsTArray<UInt32> numDrawn;
|
||||
numDrawn.SetCountAndZero(drawList.GetCount());
|
||||
|
||||
visList.Append(drawList[curDraw]->fVisList[numDrawn[curDraw]++]);
|
||||
|
||||
while( listTrav )
|
||||
{
|
||||
curPair = *(plDrawSpanPair*)&listTrav->fBody;
|
||||
if( curPair.fDrawable != curDraw )
|
||||
{
|
||||
pipe->Render(drawList[curDraw]->fDrawable, visList);
|
||||
curDraw = curPair.fDrawable;
|
||||
visList.SetCount(0);
|
||||
}
|
||||
visList.Append(drawList[curDraw]->fVisList[numDrawn[curDraw]++]);
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
pipe->Render(drawList[curDraw]->fDrawable, visList);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::IBuildSpaceTree()
|
||||
{
|
||||
if( !fNodes.GetCount() )
|
||||
return false;
|
||||
|
||||
plSpaceTreeMaker maker;
|
||||
maker.Reset();
|
||||
int i;
|
||||
for( i = 0; i < fNodes.GetCount(); i++ )
|
||||
{
|
||||
maker.AddLeaf(fNodes[i]->GetSpaceTree()->GetWorldBounds(), fNodes[i]->GetSpaceTree()->IsEmpty());
|
||||
}
|
||||
fSpaceTree = maker.MakeTree();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::IRefreshTree(plPipeline* pipe)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fNodes.GetCount(); i++ )
|
||||
{
|
||||
if( fNodes[i]->GetSpaceTree()->IsDirty() )
|
||||
{
|
||||
fNodes[i]->GetSpaceTree()->Refresh();
|
||||
|
||||
GetSpaceTree()->MoveLeaf(i, fNodes[i]->GetSpaceTree()->GetWorldBounds());
|
||||
|
||||
if( !fNodes[i]->GetSpaceTree()->IsEmpty() && fSpaceTree->HasLeafFlag(i, plSpaceTreeNode::kDisabled) )
|
||||
fSpaceTree->SetLeafFlag(i, plSpaceTreeNode::kDisabled, false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
GetSpaceTree()->SetViewPos(pipe->GetViewPositionWorld());
|
||||
|
||||
GetSpaceTree()->Refresh();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void plPageTreeMgr::AddOccluderList(const hsTArray<plOccluder*> occList)
|
||||
{
|
||||
int iStart = fOccluders.GetCount();
|
||||
fOccluders.Expand(iStart + occList.GetCount());
|
||||
fOccluders.SetCount(iStart + occList.GetCount());
|
||||
|
||||
plVisMgr* visMgr = fDisableVisMgr ? nil : fVisMgr;
|
||||
|
||||
if( visMgr )
|
||||
{
|
||||
const hsBitVector& visSet = visMgr->GetVisSet();
|
||||
const hsBitVector& visNot = visMgr->GetVisNot();
|
||||
int i;
|
||||
for( i = 0; i < occList.GetCount(); i++ )
|
||||
{
|
||||
if( occList[i] && !occList[i]->InVisNot(visNot) && occList[i]->InVisSet(visSet) )
|
||||
fOccluders[iStart++] = occList[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < occList.GetCount(); i++ )
|
||||
{
|
||||
if( occList[i] )
|
||||
fOccluders[iStart++] = occList[i];
|
||||
}
|
||||
}
|
||||
fOccluders.SetCount(iStart);
|
||||
|
||||
}
|
||||
|
||||
void plPageTreeMgr::IAddCullPolyList(const hsTArray<plCullPoly>& polyList)
|
||||
{
|
||||
int iStart = fCullPolys.GetCount();
|
||||
fCullPolys.Expand(iStart + polyList.GetCount());
|
||||
fCullPolys.SetCount(iStart + polyList.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < polyList.GetCount(); i++ )
|
||||
{
|
||||
fCullPolys[i + iStart] = &polyList[i];
|
||||
}
|
||||
}
|
||||
|
||||
void plPageTreeMgr::ISortCullPolys(plPipeline* pipe)
|
||||
{
|
||||
fSortedCullPolys.SetCount(0);
|
||||
if( !fCullPolys.GetCount() )
|
||||
return;
|
||||
|
||||
const int kMaxCullPolys = 300;
|
||||
int numSubmit = 0;
|
||||
|
||||
hsPoint3 viewPos = pipe->GetViewPositionWorld();
|
||||
|
||||
hsRadixSort::Elem* listTrav;
|
||||
scratchList.SetCount(fCullPolys.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fCullPolys.GetCount(); i++ )
|
||||
{
|
||||
hsBool backFace = fCullPolys[i]->fNorm.InnerProduct(viewPos) + fCullPolys[i]->fDist <= 0;
|
||||
if( backFace )
|
||||
{
|
||||
if( !fCullPolys[i]->IsHole() && !fCullPolys[i]->IsTwoSided() )
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( fCullPolys[i]->IsHole() )
|
||||
continue;
|
||||
}
|
||||
|
||||
listTrav = &scratchList[numSubmit];
|
||||
listTrav->fBody = (void*)fCullPolys[i];
|
||||
listTrav->fNext = listTrav + 1;
|
||||
listTrav->fKey.fFloat = (fCullPolys[i]->GetCenter() - viewPos).MagnitudeSquared();
|
||||
|
||||
numSubmit++;
|
||||
}
|
||||
if( !numSubmit )
|
||||
return;
|
||||
|
||||
listTrav->fNext = nil;
|
||||
|
||||
hsRadixSort rad;
|
||||
hsRadixSort::Elem* sortedList = rad.Sort(scratchList.AcquireArray(), 0);
|
||||
listTrav = sortedList;
|
||||
|
||||
if( numSubmit > kMaxCullPolys )
|
||||
numSubmit = kMaxCullPolys;
|
||||
|
||||
fSortedCullPolys.SetCount(numSubmit);
|
||||
|
||||
for( i = 0; i < numSubmit; i++ )
|
||||
{
|
||||
fSortedCullPolys[i] = (const plCullPoly*)listTrav->fBody;
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::IGetCullPolys(plPipeline* pipe)
|
||||
{
|
||||
if( !fOccluders.GetCount() )
|
||||
return false;
|
||||
|
||||
plProfile_BeginTiming(DrawOccSort);
|
||||
|
||||
hsRadixSort::Elem* listTrav = nil;
|
||||
scratchList.SetCount(fOccluders.GetCount());
|
||||
|
||||
hsPoint3 viewPos = pipe->GetViewPositionWorld();
|
||||
|
||||
// cull test the occluders submitted
|
||||
int numSubmit = 0;
|
||||
int i;
|
||||
for( i = 0; i < fOccluders.GetCount(); i++ )
|
||||
{
|
||||
if( pipe->TestVisibleWorld(fOccluders[i]->GetWorldBounds()) )
|
||||
{
|
||||
hsScalar invDist = -hsFastMath::InvSqrtAppr((viewPos - fOccluders[i]->GetWorldBounds().GetCenter()).MagnitudeSquared());
|
||||
listTrav = &scratchList[numSubmit++];
|
||||
listTrav->fBody = (void*)fOccluders[i];
|
||||
listTrav->fNext = listTrav+1;
|
||||
listTrav->fKey.fFloat = fOccluders[i]->GetPriority() * invDist;
|
||||
}
|
||||
}
|
||||
if( !listTrav )
|
||||
{
|
||||
plProfile_EndTiming(DrawOccSort);
|
||||
return false;
|
||||
}
|
||||
|
||||
listTrav->fNext = nil;
|
||||
|
||||
|
||||
// Sort the occluders by priority
|
||||
hsRadixSort rad;
|
||||
hsRadixSort::Elem* sortedList = rad.Sort(scratchList.AcquireArray(), 0);
|
||||
listTrav = sortedList;
|
||||
|
||||
const UInt32 kMaxOccluders = 1000;
|
||||
if( numSubmit > kMaxOccluders )
|
||||
numSubmit = kMaxOccluders;
|
||||
|
||||
plProfile_IncCount(DrawOccUsed, numSubmit);
|
||||
|
||||
// Take the polys from the first N of them
|
||||
for( i = 0; i < numSubmit; i++ )
|
||||
{
|
||||
plOccluder* occ = (plOccluder*)listTrav->fBody;
|
||||
IAddCullPolyList(occ->GetWorldPolyList());
|
||||
|
||||
listTrav = listTrav->fNext;
|
||||
}
|
||||
|
||||
plProfile_EndTiming(DrawOccSort);
|
||||
|
||||
return fCullPolys.GetCount() > 0;
|
||||
}
|
||||
|
||||
hsBool plPageTreeMgr::IGetOcclusion(plPipeline* pipe, hsTArray<Int16>& list)
|
||||
{
|
||||
plProfile_BeginTiming(DrawOccBuild);
|
||||
|
||||
fCullPolys.SetCount(0);
|
||||
fOccluders.SetCount(0);
|
||||
int i;
|
||||
for( i = 0; i < fNodes.GetCount(); i++ )
|
||||
{
|
||||
fNodes[i]->SubmitOccluders(this);
|
||||
}
|
||||
|
||||
if( !IGetCullPolys(pipe) )
|
||||
{
|
||||
plProfile_EndTiming(DrawOccBuild);
|
||||
return false;
|
||||
}
|
||||
|
||||
plProfile_IncCount(DrawOccPolyProc, fCullPolys.GetCount());
|
||||
|
||||
plProfile_BeginTiming(DrawOccPolySort);
|
||||
ISortCullPolys(pipe);
|
||||
plProfile_EndTiming(DrawOccPolySort);
|
||||
|
||||
if( fSortedCullPolys.GetCount() )
|
||||
pipe->SubmitOccluders(fSortedCullPolys);
|
||||
|
||||
plProfile_EndTiming(DrawOccBuild);
|
||||
|
||||
return fSortedCullPolys.GetCount() > 0;
|
||||
}
|
||||
|
||||
void plPageTreeMgr::IResetOcclusion(plPipeline* pipe)
|
||||
{
|
||||
fCullPolys.SetCount(0);
|
||||
fSortedCullPolys.SetCount(0);
|
||||
}
|
133
Sources/Plasma/PubUtilLib/plScene/plPageTreeMgr.h
Normal file
133
Sources/Plasma/PubUtilLib/plScene/plPageTreeMgr.h
Normal file
@ -0,0 +1,133 @@
|
||||
/*==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 plPageTreeMgr_inc
|
||||
#define plPageTreeMgr_inc
|
||||
|
||||
#include "hsTemplates.h"
|
||||
|
||||
class plSceneNode;
|
||||
class plSpaceTree;
|
||||
class plPipeline;
|
||||
class plCullPoly;
|
||||
class plOccluder;
|
||||
class plDrawable;
|
||||
class plDrawVisList;
|
||||
class plVolumeIsect;
|
||||
class plVisMgr;
|
||||
|
||||
class plDrawSpanPair
|
||||
{
|
||||
public:
|
||||
plDrawSpanPair() {}
|
||||
plDrawSpanPair(UInt16 d, UInt16 s) : fDrawable(d), fSpan(s) {}
|
||||
UInt16 fDrawable;
|
||||
UInt16 fSpan;
|
||||
};
|
||||
|
||||
class plDrawVisList
|
||||
{
|
||||
public:
|
||||
plDrawVisList() : fDrawable(nil) {}
|
||||
virtual ~plDrawVisList() {}
|
||||
|
||||
plDrawable* fDrawable;
|
||||
hsTArray<Int16> fVisList;
|
||||
|
||||
plDrawVisList& operator=(const plDrawVisList& v) { fDrawable = v.fDrawable; fVisList = v.fVisList; return *this; }
|
||||
};
|
||||
|
||||
class plPageTreeMgr
|
||||
{
|
||||
protected:
|
||||
hsTArray<plSceneNode*> fNodes;
|
||||
|
||||
plSpaceTree* fSpaceTree;
|
||||
plVisMgr* fVisMgr;
|
||||
|
||||
static hsBool fDisableVisMgr;
|
||||
|
||||
hsTArray<const plOccluder*> fOccluders;
|
||||
hsTArray<const plCullPoly*> fCullPolys;
|
||||
hsTArray<const plCullPoly*> fSortedCullPolys;
|
||||
|
||||
void ITrashSpaceTree();
|
||||
hsBool IBuildSpaceTree();
|
||||
hsBool IRefreshTree(plPipeline* pipe);
|
||||
void ISortCullPolys(plPipeline* pipe);
|
||||
hsBool IGetOcclusion(plPipeline* pipe, hsTArray<Int16>& list);
|
||||
hsBool IGetCullPolys(plPipeline* pipe);
|
||||
void IResetOcclusion(plPipeline* pipe);
|
||||
void IAddCullPolyList(const hsTArray<plCullPoly>& polyList);
|
||||
|
||||
hsBool ISortByLevel(plPipeline* pipe, hsTArray<plDrawVisList>& drawList, hsTArray<plDrawVisList>& sortedDrawList);
|
||||
int IPrepForRenderSortingSpans(plPipeline* pipe, hsTArray<plDrawVisList>& drawVis, int& iDrawStart);
|
||||
hsBool IRenderSortingSpans(plPipeline* pipe, hsTArray<plDrawVisList*>& drawList, hsTArray<plDrawSpanPair>& pairs);
|
||||
int IRenderVisList(plPipeline* pipe, hsTArray<plDrawVisList>& visList);
|
||||
|
||||
public:
|
||||
plPageTreeMgr();
|
||||
virtual ~plPageTreeMgr();
|
||||
|
||||
const hsTArray<plSceneNode*>& GetNodes() const { return fNodes; }
|
||||
|
||||
void AddNode(plSceneNode* node);
|
||||
void RemoveNode(plSceneNode* node);
|
||||
virtual void Reset(); // remove all nodes, nuke the space tree
|
||||
virtual hsBool Empty() const { return !fNodes.GetCount(); }
|
||||
|
||||
virtual int Render(plPipeline* pipe);
|
||||
|
||||
hsBool Harvest(plVolumeIsect* isect, hsTArray<plDrawVisList>& levList);
|
||||
|
||||
void AddOccluderList(const hsTArray<plOccluder*> occList);
|
||||
|
||||
plSpaceTree* GetSpaceTree() { if( !fSpaceTree ) IBuildSpaceTree(); return fSpaceTree; }
|
||||
|
||||
void SetVisMgr(plVisMgr* visMgr) { fVisMgr = visMgr; }
|
||||
plVisMgr* GetVisMgr() const { return fVisMgr; }
|
||||
|
||||
static void EnableVisMgr(hsBool on) { fDisableVisMgr = !on; }
|
||||
static hsBool VisMgrEnabled() { return !fDisableVisMgr; }
|
||||
};
|
||||
|
||||
#endif // plPageTreeMgr_inc
|
337
Sources/Plasma/PubUtilLib/plScene/plPostEffectMod.cpp
Normal file
337
Sources/Plasma/PubUtilLib/plScene/plPostEffectMod.cpp
Normal file
@ -0,0 +1,337 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plPostEffectMod.h"
|
||||
#include "plPageTreeMgr.h"
|
||||
#include "plSceneNode.h"
|
||||
#include "plRenderRequest.h"
|
||||
|
||||
#include "../plPipeline/plRenderTarget.h"
|
||||
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
#include "../plMessage/plAnimCmdMsg.h"
|
||||
#include "../plMessage/plRenderMsg.h"
|
||||
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "plDrawable.h"
|
||||
#include "plPipeline.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
|
||||
plPostEffectMod::plPostEffectMod()
|
||||
: fHither(1.f),
|
||||
fYon(100.f),
|
||||
fFovX(hsScalarPI * 0.25f),
|
||||
fFovY(hsScalarPI * 0.25f * 0.75f),
|
||||
fPageMgr(nil),
|
||||
fRenderTarget(nil),
|
||||
fRenderRequest(nil)
|
||||
{
|
||||
fDefaultW2C = hsMatrix44::IdentityMatrix();
|
||||
fDefaultC2W = hsMatrix44::IdentityMatrix();
|
||||
|
||||
ISetupRenderRequest();
|
||||
}
|
||||
|
||||
plPostEffectMod::~plPostEffectMod()
|
||||
{
|
||||
IDestroyRenderRequest();
|
||||
}
|
||||
|
||||
void plPostEffectMod::ISetupRenderRequest()
|
||||
{
|
||||
UInt32 rtFlags = 0;
|
||||
|
||||
// If we go to rendering to sub-window, we'll want to explicitly set width and height
|
||||
UInt32 width = 0;
|
||||
UInt32 height = 0;
|
||||
|
||||
UInt32 colorDepth = 0;
|
||||
UInt32 zDepth = 0;
|
||||
UInt32 stencilDepth = 0;
|
||||
|
||||
fRenderRequest = TRACKED_NEW plRenderRequest;
|
||||
UInt32 renderState = plPipeline::kRenderNormal
|
||||
| plPipeline::kRenderNoProjection
|
||||
| plPipeline::kRenderNoLights
|
||||
| plPipeline::kRenderClearDepth;
|
||||
fRenderRequest->SetRenderState(renderState);
|
||||
|
||||
fRenderRequest->SetDrawableMask(plDrawable::kNormal);
|
||||
fRenderRequest->SetSubDrawableMask(plDrawable::kSubAllTypes);
|
||||
|
||||
fRenderRequest->SetPerspective();
|
||||
|
||||
fRenderRequest->SetRenderTarget(fRenderTarget);
|
||||
|
||||
fPageMgr = TRACKED_NEW plPageTreeMgr;
|
||||
|
||||
fRenderRequest->SetPageTreeMgr(fPageMgr);
|
||||
|
||||
fRenderRequest->SetPriority(1.f);
|
||||
|
||||
IUpdateRenderRequest();
|
||||
}
|
||||
void plPostEffectMod::EnableLightsOnRenderRequest( void )
|
||||
{
|
||||
fRenderRequest->SetRenderState( fRenderRequest->GetRenderState() & ~plPipeline::kRenderNoLights );
|
||||
}
|
||||
|
||||
void plPostEffectMod::IDestroyRenderRequest()
|
||||
{
|
||||
delete fRenderTarget;
|
||||
fRenderTarget = nil;
|
||||
delete fRenderRequest;
|
||||
fRenderRequest = nil;
|
||||
delete fPageMgr;
|
||||
fPageMgr = nil;
|
||||
}
|
||||
|
||||
void plPostEffectMod::IRegisterForRenderMsg(hsBool on)
|
||||
{
|
||||
if( on )
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
else
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plPostEffectMod::ISetEnable(hsBool on)
|
||||
{
|
||||
if( on )
|
||||
{
|
||||
IRegisterForRenderMsg(true);
|
||||
fState.SetBit(kEnabled);
|
||||
}
|
||||
else
|
||||
{
|
||||
IRegisterForRenderMsg(false);
|
||||
fState.ClearBit(kEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plPostEffectMod::IIsEnabled() const
|
||||
{
|
||||
return /*GetTarget() &&*/ !fPageMgr->Empty() && fState.IsBitSet(kEnabled);
|
||||
}
|
||||
|
||||
hsBool plPostEffectMod::IEval(double secs, hsScalar del, UInt32 dirty)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void plPostEffectMod::IUpdateRenderRequest()
|
||||
{
|
||||
fRenderRequest->SetHither(fHither);
|
||||
fRenderRequest->SetYon(fYon);
|
||||
|
||||
fRenderRequest->SetFovX(fFovX);
|
||||
fRenderRequest->SetFovY(fFovY);
|
||||
|
||||
if( GetTarget() )
|
||||
{
|
||||
hsMatrix44 w2c = GetTarget()->GetWorldToLocal();
|
||||
hsMatrix44 c2w = GetTarget()->GetLocalToWorld();
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
w2c.fMap[2][i] *= -1.f;
|
||||
c2w.fMap[i][2] *= -1.f;
|
||||
}
|
||||
w2c.NotIdentity();
|
||||
c2w.NotIdentity();
|
||||
|
||||
fRenderRequest->SetCameraTransform(w2c, c2w);
|
||||
}
|
||||
else
|
||||
fRenderRequest->SetCameraTransform( fDefaultW2C, fDefaultC2W );
|
||||
// fRenderRequest->SetCameraTransform(hsMatrix44::IdentityMatrix(), hsMatrix44::IdentityMatrix());
|
||||
}
|
||||
|
||||
// If translating from a scene object, send WorldToLocal() and LocalToWorld(), in that order
|
||||
void plPostEffectMod::SetWorldToCamera( hsMatrix44 &w2c, hsMatrix44 &c2w )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
fDefaultW2C = w2c;
|
||||
fDefaultC2W = c2w;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
fDefaultW2C.fMap[2][i] *= -1.f;
|
||||
fDefaultC2W.fMap[i][2] *= -1.f;
|
||||
}
|
||||
fDefaultW2C.NotIdentity();
|
||||
fDefaultC2W.NotIdentity();
|
||||
}
|
||||
|
||||
void plPostEffectMod::GetDefaultWorldToCamera( hsMatrix44 &w2c, hsMatrix44 &c2w )
|
||||
{
|
||||
w2c = fDefaultW2C;
|
||||
c2w = fDefaultC2W;
|
||||
}
|
||||
|
||||
void plPostEffectMod::ISubmitRequest()
|
||||
{
|
||||
hsAssert(fState.IsBitSet(kEnabled), "Submitting request when not active");
|
||||
// No target is now valid...
|
||||
// hsAssert(GetTarget(), "Submitting request without target loaded");
|
||||
|
||||
IUpdateRenderRequest();
|
||||
|
||||
plRenderRequestMsg* req = TRACKED_NEW plRenderRequestMsg(GetKey(), fRenderRequest);
|
||||
plgDispatch::MsgSend(req);
|
||||
}
|
||||
|
||||
void plPostEffectMod::IAddToPageMgr(plSceneNode* node)
|
||||
{
|
||||
fPageMgr->AddNode(node);
|
||||
}
|
||||
|
||||
void plPostEffectMod::IRemoveFromPageMgr(plSceneNode* node)
|
||||
{
|
||||
fPageMgr->RemoveNode(node);
|
||||
}
|
||||
|
||||
#include "plProfile.h"
|
||||
plProfile_CreateTimer("PostEffect", "RenderSetup", PostEffect);
|
||||
|
||||
hsBool plPostEffectMod::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderMsg* rend = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rend && IIsEnabled() )
|
||||
{
|
||||
plProfile_BeginLap(PostEffect, this->GetKey()->GetUoid().GetObjectName());
|
||||
ISubmitRequest();
|
||||
plProfile_EndLap(PostEffect, this->GetKey()->GetUoid().GetObjectName());
|
||||
|
||||
return true;
|
||||
}
|
||||
plAnimCmdMsg* anim = plAnimCmdMsg::ConvertNoRef(msg);
|
||||
if( anim )
|
||||
{
|
||||
if( anim->Cmd(plAnimCmdMsg::kContinue) )
|
||||
ISetEnable(true);
|
||||
else if( anim->Cmd(plAnimCmdMsg::kStop) )
|
||||
ISetEnable(false);
|
||||
else if( anim->Cmd(plAnimCmdMsg::kToggleState) )
|
||||
ISetEnable(!fState.IsBitSet(kEnabled));
|
||||
|
||||
return true;
|
||||
}
|
||||
plGenRefMsg* ref = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( ref )
|
||||
{
|
||||
switch( ref->fType )
|
||||
{
|
||||
case kNodeRef:
|
||||
if( ref->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest) )
|
||||
{
|
||||
IAddToPageMgr(plSceneNode::ConvertNoRef(ref->GetRef()));
|
||||
}
|
||||
else if( ref->GetContext() & plRefMsg::kOnReplace )
|
||||
{
|
||||
IRemoveFromPageMgr(plSceneNode::ConvertNoRef(ref->GetOldRef()));
|
||||
IAddToPageMgr(plSceneNode::ConvertNoRef(ref->GetRef()));
|
||||
}
|
||||
else if( ref->GetContext() & (plRefMsg::kOnRemove | plRefMsg::kOnDestroy) )
|
||||
{
|
||||
IRemoveFromPageMgr(plSceneNode::ConvertNoRef(ref->GetRef()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return plSingleModifier::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plPostEffectMod::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSingleModifier::Read(s, mgr);
|
||||
|
||||
fState.Read(s);
|
||||
|
||||
#if 0 // FORCE ENABLE ON LOAD - ONLY FOR DEBUGGING
|
||||
ISetEnable(true);
|
||||
#endif // FORCE ENABLE ON LOAD - ONLY FOR DEBUGGING
|
||||
|
||||
fHither = s->ReadSwapScalar();
|
||||
fYon = s->ReadSwapScalar();
|
||||
fFovX = s->ReadSwapScalar();
|
||||
fFovY = s->ReadSwapScalar();
|
||||
|
||||
fNodeKey = mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, -1, kNodeRef), plRefFlags::kPassiveRef);
|
||||
|
||||
fDefaultW2C.Read( s );
|
||||
fDefaultC2W.Read( s );
|
||||
|
||||
IUpdateRenderRequest();
|
||||
}
|
||||
|
||||
void plPostEffectMod::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSingleModifier::Write(s, mgr);
|
||||
|
||||
fState.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fHither);
|
||||
s->WriteSwapScalar(fYon);
|
||||
s->WriteSwapScalar(fFovX);
|
||||
s->WriteSwapScalar(fFovY);
|
||||
|
||||
mgr->WriteKey(s, fNodeKey);
|
||||
|
||||
fDefaultW2C.Write( s );
|
||||
fDefaultC2W.Write( s );
|
||||
}
|
||||
|
||||
const plViewTransform& plPostEffectMod::GetViewTransform()
|
||||
{
|
||||
IUpdateRenderRequest();
|
||||
return fRenderRequest->GetViewTransform();
|
||||
}
|
142
Sources/Plasma/PubUtilLib/plScene/plPostEffectMod.h
Normal file
142
Sources/Plasma/PubUtilLib/plScene/plPostEffectMod.h
Normal file
@ -0,0 +1,142 @@
|
||||
/*==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 plPostEffectMod_inc
|
||||
#define plPostEffectMod_inc
|
||||
|
||||
#include "../pnModifier/plSingleModifier.h"
|
||||
|
||||
#include "hsMatrix44.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
class plSceneNode;
|
||||
class plPageTreeMgr;
|
||||
class plMessage;
|
||||
class plRenderTarget;
|
||||
class plRenderRequest;
|
||||
class plViewTransform;
|
||||
|
||||
class plPostEffectMod : public plSingleModifier
|
||||
{
|
||||
public:
|
||||
enum plPostEffectModStates {
|
||||
kEnabled = 0
|
||||
};
|
||||
|
||||
enum {
|
||||
kNodeRef = 0x0
|
||||
};
|
||||
protected:
|
||||
|
||||
hsBitVector fState;
|
||||
|
||||
hsScalar fHither;
|
||||
hsScalar fYon;
|
||||
|
||||
hsScalar fFovX;
|
||||
hsScalar fFovY;
|
||||
|
||||
plKey fNodeKey;
|
||||
plPageTreeMgr* fPageMgr;
|
||||
|
||||
plRenderTarget* fRenderTarget;
|
||||
plRenderRequest* fRenderRequest;
|
||||
|
||||
hsMatrix44 fDefaultW2C, fDefaultC2W;
|
||||
|
||||
|
||||
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty); // called only by owner object's Eval()
|
||||
|
||||
void ISetupRenderRequest();
|
||||
void IDestroyRenderRequest();
|
||||
void IUpdateRenderRequest();
|
||||
|
||||
void IRegisterForRenderMsg(hsBool on);
|
||||
void ISubmitRequest();
|
||||
|
||||
void IAddToPageMgr(plSceneNode* node);
|
||||
void IRemoveFromPageMgr(plSceneNode* node);
|
||||
|
||||
void ISetEnable(hsBool on);
|
||||
hsBool IIsEnabled() const;
|
||||
|
||||
public:
|
||||
plPostEffectMod();
|
||||
virtual ~plPostEffectMod();
|
||||
|
||||
CLASSNAME_REGISTER( plPostEffectMod );
|
||||
GETINTERFACE_ANY( plPostEffectMod, plSingleModifier );
|
||||
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* pMsg);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
void GetDefaultWorldToCamera( hsMatrix44 &w2c, hsMatrix44 &c2w );
|
||||
|
||||
// Export only
|
||||
void SetNodeKey(plKey key) { fNodeKey = key; }
|
||||
plKey GetNodeKey() const { return fNodeKey; }
|
||||
|
||||
void SetHither(hsScalar h) { fHither = h; }
|
||||
void SetYon(hsScalar y) { fYon = y; }
|
||||
void SetFovX(hsScalar f) { fFovX = f; }
|
||||
void SetFovY(hsScalar f) { fFovY = f; }
|
||||
|
||||
hsScalar GetHither() const { return fHither; }
|
||||
hsScalar GetYon() const { return fYon; }
|
||||
hsScalar GetFovX() const { return fFovX; }
|
||||
hsScalar GetFovY() const { return fFovY; }
|
||||
|
||||
plPageTreeMgr* GetPageMgr() const { return fPageMgr; }
|
||||
|
||||
const plViewTransform& GetViewTransform();
|
||||
|
||||
// If translating from a scene object, send WorldToLocal() and LocalToWorld(), in that order
|
||||
void SetWorldToCamera( hsMatrix44 &w2c, hsMatrix44 &c2w );
|
||||
|
||||
// Very bad
|
||||
void EnableLightsOnRenderRequest( void );
|
||||
};
|
||||
|
||||
#endif // plPostEffectMod_inc
|
271
Sources/Plasma/PubUtilLib/plScene/plRelevanceMgr.cpp
Normal file
271
Sources/Plasma/PubUtilLib/plScene/plRelevanceMgr.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
/*==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==*/
|
||||
#include "plRelevanceMgr.h"
|
||||
#include "plRelevanceRegion.h"
|
||||
#include "../plIntersect/plRegionBase.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsStringTokenizer.h"
|
||||
|
||||
plRelevanceMgr* plRelevanceMgr::fInstance = nil;
|
||||
|
||||
plRelevanceMgr::plRelevanceMgr() : fEnabled(true)
|
||||
{
|
||||
}
|
||||
|
||||
void plRelevanceMgr::Init()
|
||||
{
|
||||
fInstance = TRACKED_NEW plRelevanceMgr;
|
||||
fInstance->RegisterAs(kRelevanceMgr_KEY);
|
||||
}
|
||||
|
||||
void plRelevanceMgr::DeInit()
|
||||
{
|
||||
if (fInstance)
|
||||
{
|
||||
fInstance->UnRegisterAs(kRelevanceMgr_KEY);
|
||||
fInstance = nil;
|
||||
}
|
||||
}
|
||||
|
||||
void plRelevanceMgr::IAddRegion(plRelevanceRegion *region)
|
||||
{
|
||||
int i;
|
||||
int dstIdx = fRegions.GetCount();
|
||||
for (i = 0; i < fRegions.GetCount(); i++)
|
||||
{
|
||||
if (fRegions[i] == nil)
|
||||
{
|
||||
dstIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dstIdx == fRegions.GetCount())
|
||||
fRegions.Append(region);
|
||||
else
|
||||
fRegions[i] = region;
|
||||
|
||||
region->SetMgrIndex(dstIdx + 1);
|
||||
}
|
||||
|
||||
void plRelevanceMgr::IRemoveRegion(plRelevanceRegion *region)
|
||||
{
|
||||
fRegions[region->fMgrIdx - 1] = nil;
|
||||
}
|
||||
|
||||
void plRelevanceMgr::SetRegionVectors(const hsPoint3 &pos, hsBitVector ®ionsImIn, hsBitVector ®ionsICareAbout)
|
||||
{
|
||||
regionsImIn.Clear();
|
||||
regionsICareAbout.Clear();
|
||||
regionsICareAbout.SetBit(0, true); // Always care about region zero, the special "No region" node
|
||||
|
||||
hsBool inAnyRegion = false;
|
||||
|
||||
int i;
|
||||
for (i = 0; i < fRegions.GetCount(); i++)
|
||||
{
|
||||
if (fRegions[i] && fRegions[i]->fRegion->IsInside(pos))
|
||||
{
|
||||
regionsImIn.SetBit(i + 1, true);
|
||||
regionsICareAbout |= fRegions[i]->fRegionsICareAbout;
|
||||
inAnyRegion = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If I'm not in any region, that means I'm in the special zero region and care about everything.
|
||||
if (!inAnyRegion)
|
||||
{
|
||||
regionsImIn.SetBit(0, true);
|
||||
regionsICareAbout.Set(fRegions.GetCount());
|
||||
}
|
||||
}
|
||||
|
||||
UInt32 plRelevanceMgr::GetNumRegions() const
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = fRegions.GetCount(); i > 0 && fRegions[i - 1] == nil; i--);
|
||||
|
||||
return i + 1; // Add 1 for the special zero-region
|
||||
}
|
||||
|
||||
|
||||
hsBool plRelevanceMgr::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plGenRefMsg *genMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if (genMsg)
|
||||
{
|
||||
plRelevanceRegion *region = plRelevanceRegion::ConvertNoRef(genMsg->GetRef());
|
||||
if( genMsg->GetContext() & (plRefMsg::kOnCreate) )
|
||||
{
|
||||
IAddRegion(region);
|
||||
}
|
||||
else if( genMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
{
|
||||
IRemoveRegion(region);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return hsKeyedObject::MsgReceive(msg);
|
||||
}
|
||||
|
||||
UInt32 plRelevanceMgr::GetIndex(char *regionName)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < fRegions.GetCount(); i++)
|
||||
{
|
||||
if (fRegions[i] && !stricmp(regionName, fRegions[i]->GetKeyName()))
|
||||
return i + 1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void plRelevanceMgr::MarkRegion(UInt32 localIdx, UInt32 remoteIdx, hsBool doICare)
|
||||
{
|
||||
if (localIdx == (UInt32)-1 || remoteIdx == (UInt32)-1)
|
||||
return;
|
||||
|
||||
if (localIdx - 1 >= fRegions.GetCount() || remoteIdx - 1 >= fRegions.GetCount() || fRegions[localIdx - 1] == nil)
|
||||
return;
|
||||
|
||||
fRegions[localIdx - 1]->fRegionsICareAbout.SetBit(remoteIdx, doICare);
|
||||
}
|
||||
|
||||
// tiny class for the function below
|
||||
class plRegionInfo
|
||||
{
|
||||
public:
|
||||
char *fName;
|
||||
int fIndex;
|
||||
|
||||
plRegionInfo() : fName(nil), fIndex(-1) {}
|
||||
~plRegionInfo() { delete [] fName; }
|
||||
};
|
||||
|
||||
/*
|
||||
* This function expects a CSV file representing the matrix
|
||||
*
|
||||
* name1 name2 name3
|
||||
* name1 value value value
|
||||
* name2 value value value
|
||||
* name3 value value value
|
||||
*
|
||||
* where the value determines how much the that row's region cares about the region in the current column.
|
||||
* (Currently, the possible values are:
|
||||
* 0: Doesn't care
|
||||
* 1 or greater: row cares about column
|
||||
*/
|
||||
void plRelevanceMgr::ParseCsvInput(hsStream *s)
|
||||
{
|
||||
const int kBufSize = 512;
|
||||
char buff[kBufSize];
|
||||
hsTArray<plRegionInfo*> regions;
|
||||
hsStringTokenizer toke;
|
||||
hsBool firstLine = true;
|
||||
|
||||
while (!s->AtEnd())
|
||||
{
|
||||
if (!s->ReadLn(buff, kBufSize))
|
||||
break;
|
||||
|
||||
if (firstLine)
|
||||
{
|
||||
firstLine = false;
|
||||
toke.Reset(buff, ",");
|
||||
|
||||
while (toke.Next(buff, kBufSize))
|
||||
{
|
||||
if (strcmp(buff, "") == 0)
|
||||
continue; // ignore the initial blank one
|
||||
|
||||
plRegionInfo *info = TRACKED_NEW plRegionInfo;
|
||||
regions.Append(info);
|
||||
info->fName = hsStrcpy(buff);
|
||||
info->fIndex = GetIndex(buff);
|
||||
}
|
||||
}
|
||||
else // parsing actual settings.
|
||||
{
|
||||
toke.Reset(buff, ",");
|
||||
if (!toke.Next(buff, kBufSize))
|
||||
continue;
|
||||
|
||||
int rowIndex = GetIndex(buff);
|
||||
int column = 0;
|
||||
while (toke.Next(buff, kBufSize) && column < regions.GetCount())
|
||||
{
|
||||
int value = atoi(buff);
|
||||
MarkRegion(rowIndex, regions[column]->fIndex, value != 0);
|
||||
|
||||
column++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i;
|
||||
for (i = regions.GetCount() - 1; i >= 0; i--)
|
||||
delete regions[i];
|
||||
}
|
||||
|
||||
std::string plRelevanceMgr::GetRegionNames(hsBitVector regions)
|
||||
{
|
||||
std::string retVal = "";
|
||||
if (regions.IsBitSet(0))
|
||||
retVal = "-Nowhere (0)-";
|
||||
|
||||
for (int i = 0; i < fRegions.GetCount(); ++i)
|
||||
{
|
||||
if (regions.IsBitSet(i + 1))
|
||||
{
|
||||
if (retVal.length() != 0)
|
||||
retVal += ", ";
|
||||
if (fRegions[i])
|
||||
retVal += fRegions[i]->GetKeyName();
|
||||
}
|
||||
}
|
||||
|
||||
if (retVal.length() == 0)
|
||||
retVal = "<NONE>";
|
||||
return retVal;
|
||||
}
|
92
Sources/Plasma/PubUtilLib/plScene/plRelevanceMgr.h
Normal file
92
Sources/Plasma/PubUtilLib/plScene/plRelevanceMgr.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*==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 plRelevanceMgr_inc
|
||||
#define plRelevanceMgr_inc
|
||||
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsBitVector.h"
|
||||
#include "hsStlUtils.h"
|
||||
|
||||
|
||||
class plRelevanceRegion;
|
||||
class hsStream;
|
||||
|
||||
class plRelevanceMgr : public hsKeyedObject
|
||||
{
|
||||
protected:
|
||||
static plRelevanceMgr *fInstance;
|
||||
public:
|
||||
static plRelevanceMgr *Instance() { return fInstance; }
|
||||
|
||||
static void Init();
|
||||
static void DeInit();
|
||||
|
||||
protected:
|
||||
hsTArray<plRelevanceRegion*> fRegions;
|
||||
hsBool fEnabled;
|
||||
|
||||
void IAddRegion(plRelevanceRegion *);
|
||||
void IRemoveRegion(plRelevanceRegion *);
|
||||
|
||||
public:
|
||||
plRelevanceMgr();
|
||||
|
||||
CLASSNAME_REGISTER( plRelevanceMgr );
|
||||
GETINTERFACE_ANY( plRelevanceMgr, hsKeyedObject );
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
hsBool GetEnabled() { return fEnabled; }
|
||||
void SetEnabled(hsBool val) { fEnabled = val; }
|
||||
|
||||
UInt32 GetIndex(char *regionName);
|
||||
void MarkRegion(UInt32 localIdx, UInt32 remoteIdx, hsBool doICare);
|
||||
void SetRegionVectors(const hsPoint3 &pos, hsBitVector ®ionsImIn, hsBitVector ®ionsICareAbout);
|
||||
UInt32 GetNumRegions() const; // includes the secret 0 region in its count
|
||||
void ParseCsvInput(hsStream *s);
|
||||
|
||||
std::string GetRegionNames(hsBitVector regions);
|
||||
};
|
||||
|
||||
#endif // plRelevanceMgr_inc
|
98
Sources/Plasma/PubUtilLib/plScene/plRelevanceRegion.cpp
Normal file
98
Sources/Plasma/PubUtilLib/plScene/plRelevanceRegion.cpp
Normal file
@ -0,0 +1,98 @@
|
||||
/*==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==*/
|
||||
#include "hsResMgr.h"
|
||||
#include "plRelevanceRegion.h"
|
||||
#include "plRelevanceMgr.h"
|
||||
#include "../plIntersect/plRegionBase.h"
|
||||
|
||||
void plRelevanceRegion::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Read(s, mgr);
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, 0), plRefFlags::kActiveRef);
|
||||
|
||||
// Added to the manager when read in.
|
||||
// Removed when paged out, due to passive ref.
|
||||
if (plRelevanceMgr::Instance())
|
||||
{
|
||||
plGenRefMsg *msg = TRACKED_NEW plGenRefMsg(plRelevanceMgr::Instance()->GetKey(), plRefMsg::kOnCreate, -1, -1);
|
||||
hsgResMgr::ResMgr()->AddViaNotify(GetKey(), msg, plRefFlags::kPassiveRef);
|
||||
}
|
||||
}
|
||||
|
||||
void plRelevanceRegion::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Write(s, mgr);
|
||||
|
||||
mgr->WriteKey(s, fRegion);
|
||||
}
|
||||
|
||||
hsBool plRelevanceRegion::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plGenRefMsg *genMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if (genMsg)
|
||||
{
|
||||
plRegionBase *base = plRegionBase::ConvertNoRef(genMsg->GetRef());
|
||||
if( genMsg->GetContext() & (plRefMsg::kOnCreate) )
|
||||
{
|
||||
fRegion = base;
|
||||
}
|
||||
else if( genMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
{
|
||||
fRegion = nil;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return plObjInterface::MsgReceive(msg);
|
||||
}
|
||||
|
||||
|
||||
void plRelevanceRegion::SetMgrIndex(UInt32 index)
|
||||
{
|
||||
if (fMgrIdx != (UInt32)-1)
|
||||
fRegionsICareAbout.SetBit(fMgrIdx, false);
|
||||
|
||||
fMgrIdx = index;
|
||||
fRegionsICareAbout.SetBit(index, true); // I care about myself. Awww...
|
||||
}
|
||||
|
77
Sources/Plasma/PubUtilLib/plScene/plRelevanceRegion.h
Normal file
77
Sources/Plasma/PubUtilLib/plScene/plRelevanceRegion.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*==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 plRelevanceRegion_inc
|
||||
#define plRelevanceRegion_inc
|
||||
|
||||
#include "../pnSceneObject/plObjInterface.h"
|
||||
|
||||
class plRelevanceMgr;
|
||||
class plRegionBase;
|
||||
|
||||
class plRelevanceRegion : public plObjInterface
|
||||
{
|
||||
friend class plRelevanceMgr;
|
||||
|
||||
protected:
|
||||
plRegionBase *fRegion;
|
||||
hsBitVector fRegionsICareAbout;
|
||||
UInt32 fMgrIdx;
|
||||
|
||||
public:
|
||||
plRelevanceRegion() : fRegion(nil), fMgrIdx((UInt32)-1) {}
|
||||
virtual ~plRelevanceRegion() {}
|
||||
|
||||
CLASSNAME_REGISTER( plRelevanceRegion );
|
||||
GETINTERFACE_ANY( plRelevanceRegion, plObjInterface );
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) {}
|
||||
virtual Int32 GetNumProperties() const { return 1; }
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
void SetMgrIndex(UInt32 idx);
|
||||
};
|
||||
|
||||
#endif // plRelevanceRegion_inc
|
170
Sources/Plasma/PubUtilLib/plScene/plRenderRequest.cpp
Normal file
170
Sources/Plasma/PubUtilLib/plScene/plRenderRequest.cpp
Normal file
@ -0,0 +1,170 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plRenderRequest.h"
|
||||
#include "plPageTreeMgr.h"
|
||||
#include "../plPipeline/plRenderTarget.h"
|
||||
#include "hsFastMath.h"
|
||||
#include "hsStream.h"
|
||||
#include "plPipeline.h"
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
#include "plgDispatch.h"
|
||||
#include "plVisMgr.h"
|
||||
|
||||
plRenderRequest::plRenderRequest()
|
||||
: fRenderTarget(nil),
|
||||
fPageMgr(nil),
|
||||
fAck(nil),
|
||||
fOverrideMat(nil),
|
||||
fEraseMat(nil),
|
||||
fDrawableMask(UInt32(-1)),
|
||||
fSubDrawableMask(UInt32(-1)),
|
||||
fRenderState(0),
|
||||
fClearDepth(1.f),
|
||||
fFogStart(-1.f),
|
||||
fClearDrawable(nil),
|
||||
fPriority(-1.e6f),
|
||||
fUserData(0),
|
||||
fIgnoreOccluders(false)
|
||||
{
|
||||
fClearColor.Set(0,0,0,1.f);
|
||||
|
||||
fLocalToWorld.Reset();
|
||||
fWorldToLocal.Reset();
|
||||
|
||||
}
|
||||
|
||||
plRenderRequest::~plRenderRequest()
|
||||
{
|
||||
}
|
||||
|
||||
void plRenderRequest::SetLocalTransform(const hsMatrix44& l2w, const hsMatrix44& w2l)
|
||||
{
|
||||
fLocalToWorld = l2w;
|
||||
fWorldToLocal = w2l;
|
||||
}
|
||||
|
||||
void plRenderRequest::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
fClearDrawable = nil;
|
||||
fRenderTarget = nil;
|
||||
fPageMgr = nil;
|
||||
|
||||
fDrawableMask = s->ReadSwap32();
|
||||
fSubDrawableMask = s->ReadSwap32();
|
||||
|
||||
fRenderState = s->ReadSwap32();
|
||||
|
||||
fLocalToWorld.Read(s);
|
||||
fWorldToLocal.Read(s);
|
||||
|
||||
fPriority = s->ReadSwapScalar();
|
||||
}
|
||||
|
||||
void plRenderRequest::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
s->WriteSwap32(fDrawableMask);
|
||||
s->WriteSwap32(fSubDrawableMask);
|
||||
|
||||
s->WriteSwap32(fRenderState);
|
||||
|
||||
fLocalToWorld.Write(s);
|
||||
fWorldToLocal.Write(s);
|
||||
|
||||
s->WriteSwapScalar(fPriority);
|
||||
}
|
||||
|
||||
void plRenderRequest::Render(plPipeline* pipe, plPageTreeMgr* pageMgr)
|
||||
{
|
||||
if( !fVisForce.Empty() )
|
||||
{
|
||||
plGlobalVisMgr::Instance()->DisableNormal();
|
||||
plGlobalVisMgr::Instance()->ForceVisSets(fVisForce, false);
|
||||
}
|
||||
|
||||
pipe->PushRenderRequest(this);
|
||||
|
||||
pipe->ClearRenderTarget(GetClearDrawable());
|
||||
|
||||
int numDrawn = 0;
|
||||
if( GetPageTreeMgr() )
|
||||
numDrawn = GetPageTreeMgr()->Render(pipe);
|
||||
else
|
||||
numDrawn = pageMgr->Render(pipe);
|
||||
|
||||
pipe->PopRenderRequest(this);
|
||||
|
||||
if( GetAck() )
|
||||
{
|
||||
plRenderRequestAck* ack = TRACKED_NEW plRenderRequestAck( GetAck(), GetUserData() );
|
||||
ack->SetNumDrawn(numDrawn);
|
||||
plgDispatch::MsgSend( ack );
|
||||
}
|
||||
}
|
||||
|
||||
void plRenderRequest::SetRenderTarget(plRenderTarget* t)
|
||||
{
|
||||
if( t != fRenderTarget )
|
||||
{
|
||||
fRenderTarget = t;
|
||||
|
||||
if( fRenderTarget )
|
||||
{
|
||||
fViewTransform.SetWidth(t->GetWidth());
|
||||
fViewTransform.SetHeight(t->GetHeight());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plRenderRequest::SetVisForce(const hsBitVector& b)
|
||||
{
|
||||
if( b.Empty() )
|
||||
fVisForce.Reset();
|
||||
else
|
||||
fVisForce = b;
|
||||
}
|
||||
|
||||
hsBool plRenderRequest::GetRenderCharacters() const
|
||||
{
|
||||
return fVisForce.IsBitSet(plVisMgr::kCharacter);
|
||||
}
|
207
Sources/Plasma/PubUtilLib/plScene/plRenderRequest.h
Normal file
207
Sources/Plasma/PubUtilLib/plScene/plRenderRequest.h
Normal file
@ -0,0 +1,207 @@
|
||||
/*==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 plRenderRequest_inc
|
||||
#define plRenderRequest_inc
|
||||
|
||||
#include "hsMatrix44.h"
|
||||
#include "hsColorRGBA.h"
|
||||
#include "plViewTransform.h"
|
||||
#include "hsRefCnt.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
#include "../plMessage/plRenderRequestMsg.h"
|
||||
|
||||
class plRenderTarget;
|
||||
class plPageTreeMgr;
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plDrawable;
|
||||
class hsGMaterial;
|
||||
class plPipeline;
|
||||
|
||||
class plRenderRequest : public plRenderRequestBase
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
UInt32 fRenderState; // Or'ed from plPipeline::RenderStateSettings::kRender*
|
||||
|
||||
plDrawable* fClearDrawable;
|
||||
plRenderTarget* fRenderTarget;
|
||||
plPageTreeMgr* fPageMgr;
|
||||
|
||||
hsGMaterial* fOverrideMat;
|
||||
hsGMaterial* fEraseMat;
|
||||
|
||||
plKey fAck;
|
||||
|
||||
hsScalar fPriority;
|
||||
|
||||
UInt32 fDrawableMask;
|
||||
UInt32 fSubDrawableMask;
|
||||
|
||||
hsColorRGBA fClearColor;
|
||||
hsScalar fClearDepth;
|
||||
|
||||
hsScalar fFogStart;
|
||||
|
||||
hsMatrix44 fLocalToWorld;
|
||||
hsMatrix44 fWorldToLocal;
|
||||
|
||||
plViewTransform fViewTransform;
|
||||
|
||||
hsBitVector fVisForce;
|
||||
|
||||
UInt32 fUserData;
|
||||
hsBool fIgnoreOccluders;
|
||||
|
||||
public:
|
||||
plRenderRequest();
|
||||
~plRenderRequest();
|
||||
|
||||
hsBool GetRenderSelect() const { return !fVisForce.Empty(); }
|
||||
hsBool GetRenderCharacters() const;
|
||||
|
||||
void SetRenderState(UInt32 st) { fRenderState = st; }
|
||||
UInt32 GetRenderState() const { return fRenderState; }
|
||||
|
||||
void SetDrawableMask(UInt32 m) { fDrawableMask = m; }
|
||||
UInt32 GetDrawableMask() const { return fDrawableMask; }
|
||||
|
||||
void SetSubDrawableMask(UInt32 m) { fSubDrawableMask = m; }
|
||||
UInt32 GetSubDrawableMask() const { return fSubDrawableMask; }
|
||||
|
||||
void RequestAck(plKey key) { fAck = key; }
|
||||
plKey GetAck() const { return fAck; }
|
||||
|
||||
plDrawable* GetClearDrawable() const { return fClearDrawable; }
|
||||
void SetClearDrawable(plDrawable* d) { fClearDrawable = d; }
|
||||
|
||||
hsGMaterial* GetOverrideMat() const { return fOverrideMat; }
|
||||
void SetOverrideMat(hsGMaterial* m) { fOverrideMat = m; }
|
||||
|
||||
hsGMaterial* GetEraseMat() const { return fEraseMat; }
|
||||
void SetEraseMat(hsGMaterial* m) { fEraseMat = m; }
|
||||
|
||||
plRenderTarget* GetRenderTarget() const { return fRenderTarget; }
|
||||
void SetRenderTarget(plRenderTarget* t);
|
||||
|
||||
plPageTreeMgr* GetPageTreeMgr() const { return fPageMgr; }
|
||||
void SetPageTreeMgr(plPageTreeMgr* mgr) { fPageMgr = mgr; }
|
||||
|
||||
const hsBitVector& GetVisForce() const { return fVisForce; }
|
||||
void SetVisForce(const hsBitVector& b);
|
||||
|
||||
const hsMatrix44& GetLocalToWorld() const { return fLocalToWorld; }
|
||||
const hsMatrix44& GetWorldToLocal() const { return fWorldToLocal; }
|
||||
const hsMatrix44& GetWorldToCamera() const { return fViewTransform.GetWorldToCamera(); }
|
||||
const hsMatrix44& GetCameraToWorld() const { return fViewTransform.GetCameraToWorld(); }
|
||||
|
||||
const plViewTransform& GetViewTransform() const { return fViewTransform; }
|
||||
|
||||
hsScalar GetHither() const { return fViewTransform.GetHither(); }
|
||||
hsScalar GetYon() const { return fViewTransform.GetYon(); }
|
||||
|
||||
hsScalar GetFovX() const { return fViewTransform.GetFovXDeg(); }
|
||||
hsScalar GetFovY() const { return fViewTransform.GetFovYDeg(); }
|
||||
|
||||
hsScalar GetSizeX() const { return fViewTransform.GetOrthoWidth(); }
|
||||
hsScalar GetSizeY() const { return fViewTransform.GetOrthoHeight(); }
|
||||
|
||||
UInt16 GetScreenWidth() const { return fViewTransform.GetScreenWidth(); }
|
||||
UInt16 GetScreenHeight() const { return fViewTransform.GetScreenHeight(); }
|
||||
|
||||
const hsColorRGBA& GetClearColor() const { return fClearColor; }
|
||||
hsScalar GetClearDepth() const { return fClearDepth; }
|
||||
// FogStart
|
||||
// negative => use current settings (default)
|
||||
// 0 => no fog == fog starts at yon
|
||||
// 1 => fog starts at camera.
|
||||
// Fog start greater than 1 is legal. Fog always linear.
|
||||
hsScalar GetFogStart() const { return fFogStart; }
|
||||
|
||||
hsScalar GetPriority() const { return fPriority; }
|
||||
|
||||
void SetLocalTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
void SetViewTransform(const plViewTransform& v) { fViewTransform = v; }
|
||||
|
||||
void SetCameraTransform(const hsMatrix44& w2c, const hsMatrix44& c2w) { fViewTransform.SetCameraTransform(w2c, c2w); }
|
||||
|
||||
void SetPerspective(hsBool on=true) { fViewTransform.SetPerspective(on); }
|
||||
void SetOrthogonal(hsBool on=true) { fViewTransform.SetOrthogonal(on); }
|
||||
|
||||
void SetHither(hsScalar f) { fViewTransform.SetHither(f); }
|
||||
void SetYon(hsScalar f) { fViewTransform.SetYon(f); }
|
||||
|
||||
void SetFovX(hsScalar f) { fViewTransform.SetFovXDeg(f); }
|
||||
void SetFovY(hsScalar f) { fViewTransform.SetFovYDeg(f); }
|
||||
|
||||
void SetSizeX(hsScalar f) { fViewTransform.SetWidth(f); }
|
||||
void SetSizeY(hsScalar f) { fViewTransform.SetHeight(f); }
|
||||
|
||||
void SetClearColor(const hsColorRGBA& c) { fClearColor = c; }
|
||||
void SetClearDepth(hsScalar d) { fClearDepth = d; }
|
||||
// FogStart
|
||||
// negative => use current settings (default)
|
||||
// 0 => no fog == fog starts at yon
|
||||
// 1 => fog starts at camera.
|
||||
// Fog start greater than 1 is legal. Fog always linear.
|
||||
void SetFogStart(hsScalar d) { fFogStart = d; }
|
||||
|
||||
void SetPriority(hsScalar p) { fPriority = p; }
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
void SetUserData(UInt32 n) { fUserData = n; }
|
||||
UInt32 GetUserData() const { return fUserData; }
|
||||
|
||||
void SetIgnoreOccluders(hsBool b) { fIgnoreOccluders = b; }
|
||||
hsBool GetIgnoreOccluders() { return fIgnoreOccluders; }
|
||||
|
||||
// This function is called after the render request is processed by the client
|
||||
virtual void Render(plPipeline* pipe, plPageTreeMgr* pageMgr);
|
||||
};
|
||||
|
||||
#endif // plRenderRequest_inc
|
77
Sources/Plasma/PubUtilLib/plScene/plSceneCreatable.h
Normal file
77
Sources/Plasma/PubUtilLib/plScene/plSceneCreatable.h
Normal file
@ -0,0 +1,77 @@
|
||||
/*==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 plSceneCreatable_inc
|
||||
#define plSceneCreatable_inc
|
||||
|
||||
#include "../pnFactory/plCreatable.h"
|
||||
|
||||
#include "plSceneNode.h"
|
||||
|
||||
REGISTER_CREATABLE( plSceneNode );
|
||||
|
||||
#include "plOccluder.h"
|
||||
|
||||
REGISTER_CREATABLE( plOccluder );
|
||||
REGISTER_CREATABLE( plMobileOccluder );
|
||||
|
||||
#include "plPostEffectMod.h"
|
||||
|
||||
REGISTER_CREATABLE( plPostEffectMod );
|
||||
|
||||
#include "plVisMgr.h"
|
||||
|
||||
REGISTER_CREATABLE( plVisMgr );
|
||||
|
||||
#include "plVisRegion.h"
|
||||
|
||||
REGISTER_CREATABLE( plVisRegion );
|
||||
|
||||
#include "plRelevanceMgr.h"
|
||||
|
||||
REGISTER_CREATABLE( plRelevanceMgr );
|
||||
|
||||
#include "plRelevanceRegion.h"
|
||||
|
||||
REGISTER_CREATABLE( plRelevanceRegion );
|
||||
|
||||
#endif // plSceneCreatable_inc
|
523
Sources/Plasma/PubUtilLib/plScene/plSceneNode.cpp
Normal file
523
Sources/Plasma/PubUtilLib/plScene/plSceneNode.cpp
Normal file
@ -0,0 +1,523 @@
|
||||
/*==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==*/
|
||||
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plSceneNode.h"
|
||||
#include "../pnDispatch/plDispatch.h"
|
||||
#include "../plMessage/plNodeCleanupMsg.h"
|
||||
#include "../pnMessage/plNodeRefMsg.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
#include "../pnSceneObject/plSceneObject.h"
|
||||
#include "plDrawable.h"
|
||||
#include "plPhysical.h"
|
||||
#include "plAudible.h"
|
||||
#include "../plGLight/plLightInfo.h"
|
||||
#include "../pnMessage/plRefMsg.h"
|
||||
#include "plPipeline.h"
|
||||
#include "../pnKeyedObject/plKey.h"
|
||||
#include "../plDrawable/plSpaceTreeMaker.h"
|
||||
#include "../plDrawable/plSpaceTree.h"
|
||||
#include "plPageTreeMgr.h"
|
||||
#include "plOccluder.h"
|
||||
|
||||
//MFHORSE
|
||||
//BLACK
|
||||
// temp hack for debugging
|
||||
#include "../plDrawable/plDrawableSpans.h"
|
||||
#include "../pnKeyedObject/plKeyImp.h"
|
||||
|
||||
plSceneNode::plSceneNode()
|
||||
: fDepth(0),
|
||||
fSpaceTree(nil),
|
||||
fFilterGenerics(false)
|
||||
{
|
||||
}
|
||||
|
||||
plSceneNode::~plSceneNode()
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plNodeCleanupMsg::Index(), GetKey());
|
||||
|
||||
delete fSpaceTree;
|
||||
}
|
||||
|
||||
//// Init ////////////////////////////////////////////////////////////////////
|
||||
// Because we can't register for messages on construction. Doh.
|
||||
|
||||
void plSceneNode::Init()
|
||||
{
|
||||
/// :P
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plNodeCleanupMsg::Index(), GetKey());
|
||||
}
|
||||
|
||||
void plSceneNode::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
|
||||
UInt32 n;
|
||||
int i;
|
||||
|
||||
n = s->ReadSwap32();
|
||||
fSceneObjects.Reset();
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
plNodeRefMsg* refMsg = TRACKED_NEW plNodeRefMsg(GetKey(), plRefMsg::kOnCreate, i, plNodeRefMsg::kObject);
|
||||
plKey key = mgr->ReadKeyNotifyMe(s, refMsg, plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
n = s->ReadSwap32();
|
||||
fGenericPool.Reset();
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
plNodeRefMsg* refMsg = TRACKED_NEW plNodeRefMsg(GetKey(), plRefMsg::kOnCreate, -1, plNodeRefMsg::kGeneric);
|
||||
mgr->ReadKeyNotifyMe(s, refMsg, plRefFlags::kActiveRef);
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
|
||||
int i;
|
||||
|
||||
s->WriteSwap32(fSceneObjects.GetCount());
|
||||
for( i = 0; i < fSceneObjects.GetCount(); i++ )
|
||||
mgr->WriteKey(s,fSceneObjects[i]);
|
||||
|
||||
s->WriteSwap32(fGenericPool.GetCount());
|
||||
for( i = 0; i < fGenericPool.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fGenericPool[i]);
|
||||
}
|
||||
|
||||
void plSceneNode::Harvest(plVolumeIsect* isect, hsTArray<plDrawVisList>& levList)
|
||||
{
|
||||
static hsTArray<Int16> visList;
|
||||
visList.SetCount(0);
|
||||
GetSpaceTree()->HarvestLeaves(isect, visList);
|
||||
static hsTArray<Int16> visSpans;
|
||||
visSpans.SetCount(0);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < visList.GetCount(); i++ )
|
||||
{
|
||||
int idx = visList[i];
|
||||
fDrawPool[idx]->GetSpaceTree()->HarvestLeaves(isect, visSpans);
|
||||
if( visSpans.GetCount() )
|
||||
{
|
||||
plDrawVisList* drawVis = levList.Push();
|
||||
drawVis->fDrawable = fDrawPool[idx];
|
||||
drawVis->fVisList.Swap(visSpans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::CollectForRender(plPipeline* pipe, hsTArray<plDrawVisList>& levList, plVisMgr* visMgr)
|
||||
{
|
||||
static hsTArray<Int16> visList;
|
||||
visList.SetCount(0);
|
||||
pipe->HarvestVisible(GetSpaceTree(), visList);
|
||||
static hsTArray<Int16> visSpans;
|
||||
visSpans.SetCount(0);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < visList.GetCount(); i++ )
|
||||
{
|
||||
int idx = visList[i];
|
||||
if( pipe->PreRender(fDrawPool[idx], visSpans, visMgr) )
|
||||
{
|
||||
plDrawVisList* drawVis = levList.Push();
|
||||
drawVis->fDrawable = fDrawPool[idx];
|
||||
drawVis->fVisList.Swap(visSpans);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::SubmitOccluders(plPageTreeMgr* pageMgr) const
|
||||
{
|
||||
pageMgr->AddOccluderList(fOccluders);
|
||||
}
|
||||
|
||||
plSpaceTree* plSceneNode::IBuildSpaceTree()
|
||||
{
|
||||
plSpaceTreeMaker maker;
|
||||
maker.Reset();
|
||||
|
||||
hsBounds3Ext bnd;
|
||||
bnd.Reset(&hsPoint3(0,0,0));
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fDrawPool.GetCount(); i++ )
|
||||
{
|
||||
if( fDrawPool[i] )
|
||||
maker.AddLeaf(fDrawPool[i]->GetSpaceTree()->GetWorldBounds());
|
||||
else
|
||||
maker.AddLeaf(bnd, true);
|
||||
}
|
||||
|
||||
fSpaceTree = maker.MakeTree();
|
||||
fSpaceTree->MakeDirty();
|
||||
|
||||
return fSpaceTree;
|
||||
}
|
||||
|
||||
plSpaceTree* plSceneNode::ITrashSpaceTree()
|
||||
{
|
||||
delete fSpaceTree;
|
||||
return fSpaceTree = nil;
|
||||
}
|
||||
|
||||
void plSceneNode::IDirtySpaceTree()
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fDrawPool.GetCount(); i++ )
|
||||
{
|
||||
if( fDrawPool[i] && fDrawPool[i]->GetSpaceTree()->IsDirty() )
|
||||
{
|
||||
fDrawPool[i]->GetSpaceTree()->Refresh();
|
||||
fSpaceTree->MoveLeaf(i, fDrawPool[i]->GetSpaceTree()->GetWorldBounds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
plSpaceTree* plSceneNode::GetSpaceTree()
|
||||
{
|
||||
if( !fSpaceTree )
|
||||
{
|
||||
IBuildSpaceTree();
|
||||
}
|
||||
IDirtySpaceTree();
|
||||
return fSpaceTree;
|
||||
}
|
||||
|
||||
void plSceneNode::ISetDrawable(plDrawable* d)
|
||||
{
|
||||
if( !d )
|
||||
return;
|
||||
|
||||
if (fDrawPool.Find(d) == fDrawPool.kMissingIndex)
|
||||
{
|
||||
fDrawPool.Append(d);
|
||||
}
|
||||
|
||||
ITrashSpaceTree();
|
||||
}
|
||||
|
||||
void plSceneNode::ISetAudible(plAudible* a)
|
||||
{
|
||||
if( !a )
|
||||
return;
|
||||
|
||||
if( fAudioPool.kMissingIndex == fAudioPool.Find(a) )
|
||||
{
|
||||
fAudioPool.Append(a);
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::ISetPhysical(plPhysical* p)
|
||||
{
|
||||
if( !p )
|
||||
return;
|
||||
|
||||
if( fSimulationPool.kMissingIndex == fSimulationPool.Find(p) )
|
||||
{
|
||||
fSimulationPool.Append(p);
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::ISetObject(plSceneObject* o)
|
||||
{
|
||||
if( o && (fSceneObjects.kMissingIndex == fSceneObjects.Find(o)) )
|
||||
{
|
||||
fSceneObjects.Append(o);
|
||||
|
||||
// MF_NET_GROUPS_TEST
|
||||
// This will have no effect on members of NetGroupConstants
|
||||
o->SetNetGroup(o->SelectNetGroup(GetKey()));
|
||||
|
||||
o->SetSceneNode(GetKey());
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::ISetLight(plLightInfo* l)
|
||||
{
|
||||
if( fLightPool.kMissingIndex == fLightPool.Find(l) )
|
||||
fLightPool.Append( l );
|
||||
|
||||
}
|
||||
|
||||
void plSceneNode::ISetOccluder(plOccluder* o)
|
||||
{
|
||||
if( fOccluders.kMissingIndex == fOccluders.Find(o) )
|
||||
{
|
||||
fOccluders.Append(o);
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::ISetGeneric(hsKeyedObject* k)
|
||||
{
|
||||
if( fGenericPool.kMissingIndex == fGenericPool.Find(k) )
|
||||
fGenericPool.Append(k);
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveDrawable(plDrawable* d)
|
||||
{
|
||||
int idx = fDrawPool.Find(d);
|
||||
if( idx != fDrawPool.kMissingIndex )
|
||||
fDrawPool.Remove(idx);
|
||||
|
||||
ITrashSpaceTree();
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveAudible(plAudible* a)
|
||||
{
|
||||
int idx = fAudioPool.Find(a);
|
||||
if( idx != fAudioPool.kMissingIndex )
|
||||
fAudioPool.Remove(idx);
|
||||
|
||||
}
|
||||
|
||||
void plSceneNode::IRemovePhysical(plPhysical* p)
|
||||
{
|
||||
hsAssert(p, "Removing nil physical");
|
||||
|
||||
#ifdef HS_DEBUGGING
|
||||
if (p)
|
||||
{
|
||||
plKey oldNodeKey = p->GetSceneNode();
|
||||
if (oldNodeKey && oldNodeKey != GetKey())
|
||||
{
|
||||
char buf[256];
|
||||
sprintf(buf, "Trying to remove physical %s from scenenode %s,\nbut it's actually in %s",
|
||||
p->GetKeyName(), GetKeyName(), oldNodeKey->GetName());
|
||||
hsAssert(0, buf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int idx = fSimulationPool.Find(p);
|
||||
if( idx != fSimulationPool.kMissingIndex )
|
||||
fSimulationPool.Remove(idx);
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveObject(plSceneObject* o)
|
||||
{
|
||||
int idx = fSceneObjects.Find(o);
|
||||
if( idx != fSceneObjects.kMissingIndex )
|
||||
fSceneObjects.Remove(idx);
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveLight(plLightInfo* l)
|
||||
{
|
||||
hsAssert(l, "Removing nil light");
|
||||
|
||||
int idx = fLightPool.Find(l);
|
||||
if( idx != fLightPool.kMissingIndex )
|
||||
{
|
||||
fLightPool.Remove(idx);
|
||||
}
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveOccluder(plOccluder* o)
|
||||
{
|
||||
int idx = fOccluders.Find(o);
|
||||
if( idx != fOccluders.kMissingIndex )
|
||||
fOccluders.Remove(idx);
|
||||
}
|
||||
|
||||
void plSceneNode::IRemoveGeneric(hsKeyedObject* k)
|
||||
{
|
||||
int idx = fGenericPool.Find(k);
|
||||
if( idx != fGenericPool.kMissingIndex )
|
||||
fGenericPool.Remove(idx);
|
||||
}
|
||||
|
||||
hsBool plSceneNode::IOnRemove(plNodeRefMsg* refMsg)
|
||||
{
|
||||
|
||||
switch( refMsg->fType )
|
||||
{
|
||||
case plNodeRefMsg::kDrawable:
|
||||
IRemoveDrawable(plDrawable::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kPhysical:
|
||||
IRemovePhysical(plPhysical::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kAudible:
|
||||
IRemoveAudible(plAudible::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kObject:
|
||||
IRemoveObject(plSceneObject::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kLight:
|
||||
IRemoveLight(plLightInfo::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kOccluder:
|
||||
IRemoveOccluder(plOccluder::ConvertNoRef(refMsg->GetRef()));
|
||||
break;
|
||||
case plNodeRefMsg::kGeneric:
|
||||
IRemoveGeneric(refMsg->GetRef());
|
||||
break;
|
||||
}
|
||||
if( refMsg->GetRef() && (refMsg->GetContext() & plRefMsg::kOnRemove) )
|
||||
GetKey()->Release(refMsg->GetRef()->GetKey());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plSceneNode::IOnAdd(plNodeRefMsg* refMsg)
|
||||
{
|
||||
int which = refMsg->fWhich;
|
||||
|
||||
switch( refMsg->fType )
|
||||
{
|
||||
case plNodeRefMsg::kDrawable:
|
||||
ISetDrawable(plDrawable::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kPhysical:
|
||||
ISetPhysical(plPhysical::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kAudible:
|
||||
ISetAudible(plAudible::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kObject:
|
||||
ISetObject(plSceneObject::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kLight:
|
||||
ISetLight(plLightInfo::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kOccluder:
|
||||
ISetOccluder(plOccluder::ConvertNoRef(refMsg->GetRef()));
|
||||
return true;
|
||||
case plNodeRefMsg::kGeneric:
|
||||
ISetGeneric(refMsg->GetRef());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plSceneNode::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plNodeCleanupMsg *cleanMsg = plNodeCleanupMsg::ConvertNoRef( msg );
|
||||
|
||||
if( cleanMsg )
|
||||
{
|
||||
ICleanUp();
|
||||
return true;
|
||||
}
|
||||
|
||||
plNodeRefMsg* refMsg = plNodeRefMsg::ConvertNoRef(msg);
|
||||
|
||||
if( refMsg )
|
||||
{
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
return IOnAdd(refMsg);
|
||||
else if( refMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
return IOnRemove(refMsg);
|
||||
|
||||
}
|
||||
|
||||
return hsKeyedObject::MsgReceive(msg);
|
||||
}
|
||||
|
||||
//// ICleanUp ////////////////////////////////////////////////////////////////
|
||||
// Export only: Clean up the scene node (i.e. make sure drawables optimize)
|
||||
|
||||
void plSceneNode::ICleanUp( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
/// Go find drawables to delete
|
||||
for( i = 0; i < fDrawPool.GetCount(); i++ )
|
||||
fDrawPool[ i ]->Optimize();
|
||||
|
||||
if (fFilterGenerics)
|
||||
{
|
||||
for( i = fSceneObjects.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fSceneObjects[i]->GetKey());
|
||||
for( i = fDrawPool.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fDrawPool[i]->GetKey());
|
||||
for( i = fSimulationPool.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fSimulationPool[i]->GetKey());
|
||||
for( i = fAudioPool.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fAudioPool[i]->GetKey());
|
||||
for( i = fOccluders.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fOccluders[i]->GetKey());
|
||||
for( i = fLightPool.GetCount() - 1; i >= 0; i--)
|
||||
GetKey()->Release(fLightPool[i]->GetKey());
|
||||
}
|
||||
|
||||
ITrashSpaceTree();
|
||||
}
|
||||
|
||||
//// GetMatchingDrawable /////////////////////////////////////////////////////
|
||||
// Export only: Query for a given drawable.
|
||||
|
||||
plDrawable *plSceneNode::GetMatchingDrawable( const plDrawableCriteria& crit )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < fDrawPool.GetCount(); i++ )
|
||||
{
|
||||
if( fDrawPool[ i ]->DoIMatch( crit ) )
|
||||
return fDrawPool[ i ];
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
//// OptimizeDrawables ///////////////////////////////////////////////////////
|
||||
// Loops through all the drawables and calls Optimize on each one. For the
|
||||
// export side, to be called right before writing the drawables to disk.
|
||||
|
||||
void plSceneNode::OptimizeDrawables( void )
|
||||
{
|
||||
int i;
|
||||
|
||||
|
||||
for( i = 0; i < fDrawPool.GetCount(); i++ )
|
||||
fDrawPool[ i ]->Optimize();
|
||||
}
|
||||
|
155
Sources/Plasma/PubUtilLib/plScene/plSceneNode.h
Normal file
155
Sources/Plasma/PubUtilLib/plScene/plSceneNode.h
Normal file
@ -0,0 +1,155 @@
|
||||
/*==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 plSceneNode_inc
|
||||
#define plSceneNode_inc
|
||||
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
|
||||
class plSceneObject;
|
||||
class plDrawable;
|
||||
class plPhysical;
|
||||
class plAudible;
|
||||
class plLightInfo;
|
||||
class plPipeline;
|
||||
class plNodeRefMsg;
|
||||
class plDispatchBase;
|
||||
class plSpaceTree;
|
||||
class plDrawSpanPair;
|
||||
class plDrawVisList;
|
||||
class plOccluder;
|
||||
class plPageTreeMgr;
|
||||
class plDrawableCriteria;
|
||||
class plVolumeIsect;
|
||||
class plVisMgr;
|
||||
|
||||
class plSceneNode : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
kMaxSceneDepth = 4
|
||||
};
|
||||
|
||||
protected:
|
||||
hsBool fFilterGenerics; // Export only
|
||||
|
||||
Int16 fDepth;
|
||||
|
||||
hsTArray<plSceneObject*> fSceneObjects;
|
||||
|
||||
hsTArray<plDrawable*> fDrawPool;
|
||||
hsTArray<plPhysical*> fSimulationPool;
|
||||
hsTArray<plAudible*> fAudioPool;
|
||||
|
||||
hsTArray<plOccluder*> fOccluders;
|
||||
|
||||
hsTArray<plLightInfo*> fLightPool;
|
||||
|
||||
hsTArray<hsKeyedObject*> fGenericPool;
|
||||
|
||||
plSpaceTree* fSpaceTree;
|
||||
|
||||
void IDirtySpaceTree();
|
||||
plSpaceTree* ITrashSpaceTree();
|
||||
plSpaceTree* IBuildSpaceTree();
|
||||
|
||||
void IRemoveDrawable(plDrawable* d);
|
||||
void IRemoveAudible(plAudible* a);
|
||||
void IRemovePhysical(plPhysical* p);
|
||||
void IRemoveObject(plSceneObject* o);
|
||||
void IRemoveLight(plLightInfo* l);
|
||||
void IRemoveOccluder(plOccluder* o);
|
||||
void IRemoveGeneric(hsKeyedObject* k);
|
||||
|
||||
void ISetObject(plSceneObject* o);
|
||||
void ISetPhysical(plPhysical* p);
|
||||
void ISetAudible(plAudible* a);
|
||||
void ISetDrawable(plDrawable* d);
|
||||
void ISetLight(plLightInfo* l);
|
||||
void ISetOccluder(plOccluder* o);
|
||||
void ISetGeneric(hsKeyedObject* k);
|
||||
|
||||
hsBool IOnRemove(plNodeRefMsg* refMsg);
|
||||
hsBool IOnAdd(plNodeRefMsg* refMsg);
|
||||
|
||||
// Export only: Clean up empty drawables
|
||||
void ICleanUp( void );
|
||||
|
||||
public:
|
||||
plSceneNode();
|
||||
virtual ~plSceneNode();
|
||||
|
||||
CLASSNAME_REGISTER( plSceneNode );
|
||||
GETINTERFACE_ANY( plSceneNode, hsKeyedObject );
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
|
||||
virtual void Harvest(plVolumeIsect* isect, hsTArray<plDrawVisList>& levList);
|
||||
virtual void CollectForRender(plPipeline* pipe, hsTArray<plDrawVisList>& levList, plVisMgr* visMgr);
|
||||
|
||||
virtual void SubmitOccluders(plPageTreeMgr* pageMgr) const;
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
Int16 GetDepth() { return fDepth; }
|
||||
Int16 IncDepth() { return ++fDepth; }
|
||||
Int16 DecDepth() { return --fDepth; }
|
||||
|
||||
void Init( void );
|
||||
|
||||
plSpaceTree* GetSpaceTree();
|
||||
|
||||
// Export only: Query for a given drawable
|
||||
virtual plDrawable *GetMatchingDrawable( const plDrawableCriteria& crit );
|
||||
|
||||
// Export only: Optimize all my stinkin' drawables
|
||||
virtual void OptimizeDrawables( void );
|
||||
|
||||
void SetFilterGenericsOnly(hsBool b) { fFilterGenerics = b; }
|
||||
|
||||
const hsTArray<plDrawable*>& GetDrawPool() const { return fDrawPool; }
|
||||
};
|
||||
|
||||
#endif // plSceneNode_inc
|
223
Sources/Plasma/PubUtilLib/plScene/plVisMgr.cpp
Normal file
223
Sources/Plasma/PubUtilLib/plScene/plVisMgr.cpp
Normal file
@ -0,0 +1,223 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plVisMgr.h"
|
||||
|
||||
#include "plVisRegion.h"
|
||||
|
||||
hsBitVector plVisMgr::fIdxSet;
|
||||
hsBitVector plVisMgr::fIdxNot;
|
||||
|
||||
plVisMgr::plVisMgr()
|
||||
: fMaxSet(kCharacter),
|
||||
fMaxNot(-1)
|
||||
{
|
||||
ResetNormal();
|
||||
}
|
||||
|
||||
plVisMgr::~plVisMgr()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plVisMgr::MsgReceive(plMessage* msg)
|
||||
{
|
||||
|
||||
return hsKeyedObject::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plVisMgr::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Read(s, mgr);
|
||||
|
||||
}
|
||||
|
||||
void plVisMgr::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
hsKeyedObject::Write(s, mgr);
|
||||
}
|
||||
|
||||
void plVisMgr::Register(plVisRegion* reg, hsBool not)
|
||||
{
|
||||
// This should happen pretty infrequently, or
|
||||
// I wouldn't be doing it so cloth-headed-ly.
|
||||
hsTArray<plVisRegion*>& regions = not ? fNotRegions : fRegions;
|
||||
hsBitVector& indices = not ? fIdxNot : fIdxSet;
|
||||
int& maxIdx = not ? fMaxNot : fMaxSet;
|
||||
int i;
|
||||
for( i = kNumReserved; ; i++ )
|
||||
{
|
||||
if( !indices.IsBitSet(i) )
|
||||
{
|
||||
if( i > maxIdx )
|
||||
maxIdx = i;
|
||||
|
||||
indices.SetBit(i);
|
||||
reg->SetIndex(i);
|
||||
regions.Append(reg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
hsAssert(false, "Infinite bitvector has all bits set?");
|
||||
}
|
||||
|
||||
void plVisMgr::UnRegister(plVisRegion* reg, hsBool not)
|
||||
{
|
||||
// Mark our index for recycling
|
||||
hsBitVector& indices= not ? fIdxNot : fIdxSet;
|
||||
indices.ClearBit(reg->GetIndex());
|
||||
|
||||
// Nuke the region from our list.
|
||||
hsTArray<plVisRegion*>& regions = not ? fNotRegions : fRegions;
|
||||
int idx = regions.Find(reg);
|
||||
if( regions.kMissingIndex != idx )
|
||||
regions.Remove(idx);
|
||||
}
|
||||
|
||||
void plVisMgr::Eval(const hsPoint3& pos)
|
||||
{
|
||||
fVisSet = fOnBitSet;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fRegions.GetCount(); i++ )
|
||||
{
|
||||
hsAssert(fRegions[i], "Nil region in list");
|
||||
if( !fOffBitSet.IsBitSet(fRegions[i]->GetIndex()) )
|
||||
{
|
||||
if( fRegions[i]->Eval(pos) )
|
||||
{
|
||||
fVisSet.SetBit(fRegions[i]->GetIndex());
|
||||
if( fRegions[i]->DisableNormal() )
|
||||
{
|
||||
fVisSet.ClearBit(kNormal);
|
||||
fVisSet.SetBit(kCharacter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fVisNot = fOnBitNot;
|
||||
|
||||
for( i = 0; i < fNotRegions.GetCount(); i++ )
|
||||
{
|
||||
hsAssert(fNotRegions[i], "Nil region in list");
|
||||
if( !fOffBitNot.IsBitSet(fNotRegions[i]->GetIndex()) )
|
||||
{
|
||||
if( fNotRegions[i]->Eval(pos) )
|
||||
{
|
||||
fVisNot.SetBit(fNotRegions[i]->GetIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResetNormal();
|
||||
}
|
||||
|
||||
void plVisMgr::ResetNormal()
|
||||
{
|
||||
fOnBitSet.Clear();
|
||||
fOnBitSet.SetBit(kNormal);
|
||||
|
||||
fOffBitSet.Clear();
|
||||
fOnBitNot.Clear();
|
||||
fOffBitNot.Clear();
|
||||
}
|
||||
|
||||
void plVisMgr::DisableNormal()
|
||||
{
|
||||
fOnBitSet.Clear();
|
||||
if( fMaxSet > 0 )
|
||||
fOffBitSet.Set(fMaxSet);
|
||||
|
||||
fOnBitNot.Clear();
|
||||
if( fMaxNot > 0 )
|
||||
fOffBitNot.Set(fMaxNot);
|
||||
}
|
||||
|
||||
void plVisMgr::EnableVisSet(int idx, hsBool isNot)
|
||||
{
|
||||
hsBitVector& offs = isNot ? fOffBitNot : fOffBitSet;
|
||||
|
||||
offs.ClearBit(idx);
|
||||
}
|
||||
|
||||
void plVisMgr::EnableVisSets(const hsBitVector& enabled, hsBool isNot)
|
||||
{
|
||||
hsBitVector& offs = isNot ? fOffBitNot : fOffBitSet;
|
||||
offs -= enabled;
|
||||
}
|
||||
|
||||
void plVisMgr::ForceVisSet(int idx, hsBool isNot)
|
||||
{
|
||||
EnableVisSet(idx, isNot);
|
||||
hsBitVector& ons = isNot ? fOnBitNot : fOnBitSet;
|
||||
ons.SetBit(idx);
|
||||
}
|
||||
|
||||
void plVisMgr::ForceVisSets(const hsBitVector& enabled, hsBool isNot)
|
||||
{
|
||||
EnableVisSets(enabled, isNot);
|
||||
hsBitVector& ons = isNot ? fOnBitNot : fOnBitSet;
|
||||
ons |= enabled;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plVisMgr* plGlobalVisMgr::fInstance = nil;
|
||||
|
||||
void plGlobalVisMgr::Init()
|
||||
{
|
||||
fInstance = TRACKED_NEW plVisMgr;
|
||||
fInstance->RegisterAs(kGlobalVisMgr_KEY);
|
||||
}
|
||||
|
||||
void plGlobalVisMgr::DeInit()
|
||||
{
|
||||
if (fInstance)
|
||||
{
|
||||
fInstance->UnRegisterAs(kGlobalVisMgr_KEY);
|
||||
fInstance = nil;
|
||||
}
|
||||
}
|
138
Sources/Plasma/PubUtilLib/plScene/plVisMgr.h
Normal file
138
Sources/Plasma/PubUtilLib/plScene/plVisMgr.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*==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 plVisMgr_inc
|
||||
#define plVisMgr_inc
|
||||
|
||||
#include "../pnKeyedObject/hsKeyedObject.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsBitVector.h"
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plVisRegion;
|
||||
class plMessage;
|
||||
struct hsPoint3;
|
||||
|
||||
class plVisMgr : public hsKeyedObject
|
||||
{
|
||||
public:
|
||||
enum RsvBits
|
||||
{
|
||||
kNormal,
|
||||
kCharacter,
|
||||
|
||||
kNumReserved
|
||||
};
|
||||
protected:
|
||||
hsTArray<plVisRegion*> fRegions;
|
||||
hsTArray<plVisRegion*> fNotRegions;
|
||||
|
||||
hsBitVector fVisSet;
|
||||
hsBitVector fVisNot;
|
||||
|
||||
int fMaxSet;
|
||||
int fMaxNot;
|
||||
|
||||
hsBitVector fOnBitSet; // Forces a true response from that enabling region
|
||||
hsBitVector fOffBitSet; // Forces a false response from that enabling region
|
||||
|
||||
hsBitVector fOnBitNot; // Forces a true response from that disabling region
|
||||
hsBitVector fOffBitNot; // Forces a falseresponse from that disabling region
|
||||
|
||||
static hsBitVector fIdxSet;
|
||||
static hsBitVector fIdxNot;
|
||||
|
||||
// There's currently no reason why you would call ResetNormal
|
||||
// because it's called after every Eval.
|
||||
void ResetNormal();
|
||||
|
||||
public:
|
||||
plVisMgr();
|
||||
virtual ~plVisMgr();
|
||||
|
||||
CLASSNAME_REGISTER( plVisMgr );
|
||||
GETINTERFACE_ANY( plVisMgr, hsKeyedObject );
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
void Register(plVisRegion* reg, hsBool not);
|
||||
void UnRegister(plVisRegion* reg, hsBool not);
|
||||
|
||||
void Eval(const hsPoint3& pos);
|
||||
|
||||
const hsBitVector& GetVisSet() const { return fVisSet; }
|
||||
const hsBitVector& GetVisNot() const { return fVisNot; }
|
||||
|
||||
// All the following persist only through the next Eval. So a normal
|
||||
// use would be to call DisableNormal() in your RenderRequest's Render method,
|
||||
// then Enable a few vissets of personal interest, then call the base RenderRequest::Render().
|
||||
//
|
||||
// Turns all regions off, so NOTHING gets drawn. That includes Normal and Character.
|
||||
void DisableNormal();
|
||||
|
||||
// Enable drawing of selected sets. Either one index at a time or pass in a bitvector.
|
||||
// The regions are just enabled, they can still say no.
|
||||
void EnableVisSet(int idx, hsBool isNot = false);
|
||||
void EnableVisSets(const hsBitVector& enabled, hsBool isNot = false);
|
||||
|
||||
// Make specified regions say yes, no matter where the camera is.
|
||||
// This will implicitly call EnableVisSet for you.
|
||||
void ForceVisSet(int idx, hsBool isNot = false);
|
||||
void ForceVisSets(const hsBitVector& enabled, hsBool isNot = false);
|
||||
};
|
||||
|
||||
class plGlobalVisMgr
|
||||
{
|
||||
protected:
|
||||
static plVisMgr* fInstance;
|
||||
public:
|
||||
static plVisMgr* Instance() { return fInstance; }
|
||||
|
||||
static void Init();
|
||||
static void DeInit();
|
||||
};
|
||||
|
||||
#endif // plVisMgr_inc
|
145
Sources/Plasma/PubUtilLib/plScene/plVisRegion.cpp
Normal file
145
Sources/Plasma/PubUtilLib/plScene/plVisRegion.cpp
Normal file
@ -0,0 +1,145 @@
|
||||
/*==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==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plVisRegion.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
#include "plVisMgr.h"
|
||||
|
||||
#include "../pnMessage/plEnableMsg.h"
|
||||
#include "../plIntersect/plRegionBase.h"
|
||||
|
||||
plVisRegion::plVisRegion()
|
||||
: fIndex(0),
|
||||
fRegion(nil),
|
||||
fMgr(nil)
|
||||
{
|
||||
fMgr = plGlobalVisMgr::Instance();
|
||||
|
||||
SetProperty(kReplaceNormal, true);
|
||||
}
|
||||
|
||||
plVisRegion::~plVisRegion()
|
||||
{
|
||||
if( fMgr )
|
||||
fMgr->UnRegister(this, GetProperty(kIsNot));
|
||||
}
|
||||
|
||||
hsBool plVisRegion::Eval(const hsPoint3& pos) const
|
||||
{
|
||||
if( GetProperty(kDisable) )
|
||||
return false;
|
||||
|
||||
if( !fRegion )
|
||||
return true;
|
||||
|
||||
return fRegion->IsInside(pos);
|
||||
}
|
||||
|
||||
hsBool plVisRegion::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plEnableMsg* enaMsg = plEnableMsg::ConvertNoRef(msg);
|
||||
if( enaMsg )
|
||||
{
|
||||
SetProperty(kDisable, enaMsg->Cmd(plEnableMsg::kDisable));
|
||||
return true;
|
||||
}
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
switch( refMsg->fType )
|
||||
{
|
||||
case kRefRegion:
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
fRegion = plRegionBase::ConvertNoRef(refMsg->GetRef());
|
||||
}
|
||||
else
|
||||
{
|
||||
fRegion = nil;
|
||||
}
|
||||
return true;
|
||||
case kRefVisMgr:
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
|
||||
{
|
||||
if( fMgr )
|
||||
fMgr->UnRegister(this, GetProperty(kIsNot));
|
||||
fMgr = plVisMgr::ConvertNoRef(refMsg->GetRef());
|
||||
hsAssert(fMgr, "Just set my manager to nil.");
|
||||
fMgr->Register(this, GetProperty(kIsNot));
|
||||
}
|
||||
else
|
||||
{
|
||||
fMgr = nil;
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return plObjInterface::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plVisRegion::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Read(s, mgr);
|
||||
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefRegion), plRefFlags::kActiveRef);
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kRefVisMgr), plRefFlags::kActiveRef);
|
||||
|
||||
if( fMgr )
|
||||
fMgr->Register(this, GetProperty(kIsNot));
|
||||
}
|
||||
|
||||
void plVisRegion::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plObjInterface::Write(s, mgr);
|
||||
|
||||
mgr->WriteKey(s, fRegion);
|
||||
|
||||
mgr->WriteKey(s, fMgr);
|
||||
}
|
||||
|
109
Sources/Plasma/PubUtilLib/plScene/plVisRegion.h
Normal file
109
Sources/Plasma/PubUtilLib/plScene/plVisRegion.h
Normal file
@ -0,0 +1,109 @@
|
||||
/*==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 plVisRegion_inc
|
||||
#define plVisRegion_inc
|
||||
|
||||
#include "../pnSceneObject/plObjInterface.h"
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plMessage;
|
||||
class plVisMgr;
|
||||
class plRegionBase;
|
||||
struct hsPoint3;
|
||||
|
||||
class plVisRegion : public plObjInterface
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
kRefRegion,
|
||||
kRefVisMgr
|
||||
};
|
||||
enum
|
||||
{
|
||||
kDisable = 0, // Always disable is zero
|
||||
kIsNot,
|
||||
kReplaceNormal, // Defaults to true
|
||||
kDisableNormal
|
||||
};
|
||||
protected:
|
||||
plRegionBase* fRegion;
|
||||
|
||||
plVisMgr* fMgr;
|
||||
|
||||
Int32 fIndex;
|
||||
|
||||
void SetIndex(Int32 i) { fIndex = i; }
|
||||
|
||||
friend class plVisMgr;
|
||||
public:
|
||||
plVisRegion();
|
||||
virtual ~plVisRegion();
|
||||
|
||||
CLASSNAME_REGISTER( plVisRegion );
|
||||
GETINTERFACE_ANY( plVisRegion, plObjInterface );
|
||||
|
||||
virtual Int32 GetNumProperties() const { return 3; } // This is stupid.
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
// Set transform doesn't do anything, because the regions themselves are
|
||||
// object interfaces, so they'll move when their sceneobjects move.
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) {}
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
hsBool Eval(const hsPoint3& pos) const;
|
||||
|
||||
Int32 GetIndex() const { return fIndex; }
|
||||
|
||||
hsBool Registered() const { return GetIndex() > 0; }
|
||||
|
||||
hsBool IsNot() const { return GetProperty(kIsNot); }
|
||||
hsBool ReplaceNormal() const { return GetProperty(kReplaceNormal); }
|
||||
hsBool DisableNormal() const { return GetProperty(kDisableNormal); }
|
||||
};
|
||||
|
||||
#endif // plVisRegion_inc
|
Reference in New Issue
Block a user