2
3
mirror of https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git synced 2025-07-14 02:27:40 -04:00

Fix line endings and tabs

This commit is contained in:
Branan Purvine-Riley
2011-04-11 16:27:55 -07:00
parent d4250e19b5
commit 908aaeb6f6
2738 changed files with 702562 additions and 702562 deletions

View File

@ -1,38 +1,38 @@
include_directories("../../CoreLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
set(plScene_SOURCES
plCullPoly.cpp
plOccluder.cpp
plOccluderProxy.cpp
plPageTreeMgr.cpp
plPostEffectMod.cpp
plRelevanceMgr.cpp
plRelevanceRegion.cpp
plRenderRequest.cpp
plSceneNode.cpp
plVisMgr.cpp
plVisRegion.cpp
)
set(plScene_HEADERS
plCullPoly.h
plOccluder.h
plOccluderProxy.h
plPageTreeMgr.h
plPostEffectMod.h
plRelevanceMgr.h
plRelevanceRegion.h
plRenderRequest.h
plSceneCreatable.h
plSceneNode.h
plVisMgr.h
plVisRegion.h
)
add_library(plScene STATIC ${plScene_SOURCES} ${plScene_HEADERS})
source_group("Source Files" FILES ${plScene_SOURCES})
source_group("Header Files" FILES ${plScene_HEADERS})
include_directories("../../CoreLib")
include_directories("../../NucleusLib/inc")
include_directories("../../NucleusLib")
include_directories("../../PubUtilLib")
set(plScene_SOURCES
plCullPoly.cpp
plOccluder.cpp
plOccluderProxy.cpp
plPageTreeMgr.cpp
plPostEffectMod.cpp
plRelevanceMgr.cpp
plRelevanceRegion.cpp
plRenderRequest.cpp
plSceneNode.cpp
plVisMgr.cpp
plVisRegion.cpp
)
set(plScene_HEADERS
plCullPoly.h
plOccluder.h
plOccluderProxy.h
plPageTreeMgr.h
plPostEffectMod.h
plRelevanceMgr.h
plRelevanceRegion.h
plRenderRequest.h
plSceneCreatable.h
plSceneNode.h
plVisMgr.h
plVisRegion.h
)
add_library(plScene STATIC ${plScene_SOURCES} ${plScene_HEADERS})
source_group("Source Files" FILES ${plScene_SOURCES})
source_group("Header Files" FILES ${plScene_HEADERS})

View File

@ -1,186 +1,186 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,82 +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/>.
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
/*==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/>.
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

View File

@ -1,221 +1,221 @@
/*==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/>.
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);
/*==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/>.
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);
}

View File

@ -1,164 +1,164 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,387 +1,387 @@
/*==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/>.
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();
}
/*==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/>.
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();
}

View File

@ -1,153 +1,153 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,66 +1,66 @@
/*==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/>.
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;
/*==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/>.
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;
}

View File

@ -1,51 +1,51 @@
/*==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/>.
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
/*==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/>.
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

File diff suppressed because it is too large Load Diff

View File

@ -1,117 +1,117 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,321 +1,321 @@
/*==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/>.
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();
/*==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/>.
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();
}

View File

@ -1,126 +1,126 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,255 +1,255 @@
/*==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/>.
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 &regionsImIn, hsBitVector &regionsICareAbout)
{
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;
/*==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/>.
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 &regionsImIn, hsBitVector &regionsICareAbout)
{
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;
}

View File

@ -1,76 +1,76 @@
/*==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/>.
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 &regionsImIn, hsBitVector &regionsICareAbout);
UInt32 GetNumRegions() const; // includes the secret 0 region in its count
void ParseCsvInput(hsStream *s);
std::string GetRegionNames(hsBitVector regions);
};
#endif // plRelevanceMgr_inc
/*==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/>.
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 &regionsImIn, hsBitVector &regionsICareAbout);
UInt32 GetNumRegions() const; // includes the secret 0 region in its count
void ParseCsvInput(hsStream *s);
std::string GetRegionNames(hsBitVector regions);
};
#endif // plRelevanceMgr_inc

View File

@ -1,82 +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/>.
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...
}
/*==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/>.
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...
}

View File

@ -1,61 +1,61 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,154 +1,154 @@
/*==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/>.
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);
}
/*==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/>.
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);
}

View File

@ -1,191 +1,191 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,61 +1,61 @@
/*==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/>.
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
/*==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/>.
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

File diff suppressed because it is too large Load Diff

View File

@ -1,139 +1,139 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,207 +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/>.
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;
}
/*==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/>.
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;
}
}

View File

@ -1,122 +1,122 @@
/*==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/>.
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
/*==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/>.
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

View File

@ -1,129 +1,129 @@
/*==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/>.
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);
}
/*==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/>.
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);
}

View File

@ -1,93 +1,93 @@
/*==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/>.
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
/*==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/>.
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