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

CWE Directory Reorganization

Rearrange directory structure of CWE to be loosely equivalent to
the H'uru Plasma repository.

Part 1: Movement of directories and files.
This commit is contained in:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View File

@ -0,0 +1,205 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plDirectShadowMaster.h"
#include "plShadowSlave.h"
#include "plPerspDirSlave.h"
#include "plShadowCaster.h"
#include "../plMessage/plShadowCastMsg.h"
#include "plLightInfo.h"
#include "hsMatrix44.h"
#include "hsBounds.h"
#include "hsFastMath.h"
////////////////////////////////////////////////////////////////////////////////////
// Point first, directional lights follow
////////////////////////////////////////////////////////////////////////////////////
plDirectShadowMaster::plDirectShadowMaster()
{
}
plDirectShadowMaster::~plDirectShadowMaster()
{
fIsectPool.SetCount(fIsectPool.GetNumAlloc());
int i;
for( i = 0; i < fIsectPool.GetCount(); i++ )
delete fIsectPool[i];
}
plShadowSlave* plDirectShadowMaster::INewSlave(const plShadowCaster* caster)
{
if( caster->GetPerspective() )
return TRACKED_NEW plPerspDirSlave;
return TRACKED_NEW plDirectShadowSlave;
}
plShadowSlave* plDirectShadowMaster::INextSlave(const plShadowCaster* caster)
{
if( !caster->GetPerspective() )
return plShadowMaster::INextSlave(caster);
int iSlave = fPerspSlavePool.GetCount();
fPerspSlavePool.ExpandAndZero(iSlave+1);
plShadowSlave* slave = fPerspSlavePool[iSlave];
if( !slave )
{
fPerspSlavePool[iSlave] = slave = INewSlave(caster);
}
return slave;
}
plShadowSlave* plDirectShadowMaster::IRecycleSlave(plShadowSlave* slave)
{
if( fSlavePool.GetCount() && (fSlavePool[fSlavePool.GetCount()-1] == slave) )
fSlavePool.SetCount(fSlavePool.GetCount()-1);
else
if( fPerspSlavePool.GetCount() && (fPerspSlavePool[fPerspSlavePool.GetCount()-1] == slave) )
fPerspSlavePool.SetCount(fPerspSlavePool.GetCount()-1);
return nil;
}
void plDirectShadowMaster::IBeginRender()
{
plShadowMaster::IBeginRender();
fPerspSlavePool.SetCount(0);
fIsectPool.SetCount(0);
}
void plDirectShadowMaster::IComputeWorldToLight(const hsBounds3Ext& wBnd, plShadowSlave* slave) const
{
hsMatrix44 kFlipDir;
kFlipDir.Reset();
kFlipDir.NotIdentity();
kFlipDir.fMap[2][2] = -1.f;
hsMatrix44 worldToLight = kFlipDir * fLightInfo->GetWorldToLight();
hsMatrix44 lightToWorld = fLightInfo->GetLightToWorld() * kFlipDir;
hsBounds3Ext bnd = wBnd;
bnd.Transform(&worldToLight);
hsPoint3 pos = bnd.GetCenter();
pos.fZ = bnd.GetMins().fZ;
hsPoint3 wPos = lightToWorld * pos;
lightToWorld.NotIdentity();
lightToWorld.fMap[0][3] = wPos[0];
lightToWorld.fMap[1][3] = wPos[1];
lightToWorld.fMap[2][3] = wPos[2];
// Need worldToLight and hate doing an inverse.
// worldToLight = pureTrans * pureRot;
// lightToWorld = Inv(pureRot) * Inv(pureTran);
// So Inv(pureTran) = pureRot * Inv(pureRot) * Inv(pureTran) = pureRot * lightToWorld
// Make worldToLight pure rotation inverse of lightToWorld
worldToLight.fMap[0][3] = 0;
worldToLight.fMap[1][3] = 0;
worldToLight.fMap[2][3] = 0;
hsMatrix44 trans = worldToLight * lightToWorld;
worldToLight.fMap[0][3] = -trans.fMap[0][3];
worldToLight.fMap[1][3] = -trans.fMap[1][3];
worldToLight.fMap[2][3] = -trans.fMap[2][3];
//#define CHECK_INVERSE
#ifdef CHECK_INVERSE
hsMatrix44 inv;
lightToWorld.GetInverse(&inv);
#endif // CHECK_INVERSE
slave->fWorldToLight = worldToLight;
slave->fLightToWorld = lightToWorld;
}
void plDirectShadowMaster::IComputeProjections(plShadowCastMsg* castMsg, plShadowSlave* slave) const
{
slave->fView.SetPerspective(false);
}
void plDirectShadowMaster::IComputeISect(const hsBounds3Ext& casterBnd, plShadowSlave* slave) const
{
int iIsect = fIsectPool.GetCount();
fIsectPool.ExpandAndZero(iIsect+1);
if( !fIsectPool[iIsect] )
{
fIsectPool[iIsect] = TRACKED_NEW plBoundsIsect;
}
plBoundsIsect* isect = fIsectPool[iIsect];
const hsBounds3Ext& wBnd = slave->fWorldBounds;
isect->SetBounds(wBnd);
slave->fIsect = isect;
}
void plDirectShadowMaster::IComputeBounds(const hsBounds3Ext& casterBnd, plShadowSlave* slave) const
{
// Plan here is to look at the bounds in the slave's local space.
// Our slave's bounds will clearly contain the shadow caster's bounds. It will also
// contain the bnd's corners extended out in light space Z.
// They will extend fAttenDist farther than the center pointof the bound.
hsBounds3Ext bnd = casterBnd;
bnd.Transform(&slave->fWorldToLight);
hsPoint3 farPt = bnd.GetCenter();
farPt.fZ += slave->fAttenDist;
bnd.Union(&farPt);
bnd.Transform(&slave->fLightToWorld);
slave->fWorldBounds = bnd;
}

View File

@ -0,0 +1,79 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plDirectShdowMaster_inc
#define plDirectShdowMaster_inc
#include "plShadowMaster.h"
#include "hsGeometry3.h"
class plBoundsIsect;
class plDirectShadowMaster : public plShadowMaster
{
protected:
mutable hsTArray<plBoundsIsect*> fIsectPool;
hsTArray<plShadowSlave*> fPerspSlavePool;
virtual void IComputeWorldToLight(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual void IComputeProjections(plShadowCastMsg* castMsg, plShadowSlave* slave) const;
virtual void IComputeISect(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual void IComputeBounds(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual plShadowSlave* INewSlave(const plShadowCaster* caster);
virtual plShadowSlave* INextSlave(const plShadowCaster* caster);
virtual plShadowSlave* IRecycleSlave(plShadowSlave* slave);
virtual void IBeginRender();
public:
plDirectShadowMaster();
virtual ~plDirectShadowMaster();
CLASSNAME_REGISTER( plDirectShadowMaster );
GETINTERFACE_ANY( plDirectShadowMaster, plShadowMaster );
};
#endif // plDirectShdowMaster_inc

View File

@ -0,0 +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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plGLightCreatable_inc
#define plGLightCreatable_inc
#include "../pnFactory/plCreator.h"
#include "plLightInfo.h"
REGISTER_NONCREATABLE( plLightInfo );
REGISTER_CREATABLE( plDirectionalLightInfo );
REGISTER_CREATABLE( plLimitedDirLightInfo );
REGISTER_CREATABLE( plOmniLightInfo );
REGISTER_CREATABLE( plSpotLightInfo );
#include "plLightSpace.h"
REGISTER_CREATABLE( plLightSpace );
#include "plShadowMaster.h"
REGISTER_NONCREATABLE( plShadowMaster );
#include "plPointShadowMaster.h"
REGISTER_CREATABLE( plPointShadowMaster );
#include "plDirectShadowMaster.h"
REGISTER_CREATABLE( plDirectShadowMaster );
#include "plShadowCaster.h"
REGISTER_CREATABLE( plShadowCaster );
#endif // plGLightCreatable_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,419 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plLightInfo_inc
#define plLightInfo_inc
#include "../pnSceneObject/plObjInterface.h"
#include "hsMatrix44.h"
#include "hsColorRGBA.h"
#include "../plIntersect/plVolumeIsect.h"
#include "hsBitVector.h"
class hsStream;
class hsResMgr;
class plSpaceTree;
class hsGDeviceRef;
class hsGMaterial;
class plDrawableSpans;
class plLayerInterface;
class plPipeline;
class plDrawable;
class plSoftVolume;
class hsBounds3Ext;
class plVisRegion;
class plRenderRequest;
class plRenderTarget;
class plLightProxy;
class plLightInfo : public plObjInterface
{
public:
enum {
kDisable = 0x0, // prop 0 is always disable, declared in plObjInterface
kLPObsolete,
kLPCastShadows,
kLPMovable,
kLPHasIncludes,
kLPIncludesChars,
kLP_OBSOLECTE_0, // OLD
kLPOverAll,
kLPHasSpecular, // This is the same as a non-black specular color, but we use it here to make it faster to check
kLPShadowOnly,
kLPShadowLightGroup,
kLPForceProj,
kNumProps
};
enum LIRefType
{
kProjection = 0,
k_OBSOLECTE_REF_0, // OLD
k_OBSOLECTE_REF_1, // OLD
k_OBSOLECTE_REF_2, // OLD
kSoftVolume,
kVisRegion
};
protected:
// Volatile properties that shouldn't be network propagated.
enum VolatileFlags {
kVolNone = 0x0,
kVolDirty = 0x1,
kVolEmpty = 0x2,
kVolZero = 0x4
};
UInt8 fVolFlags;
hsBitVector fVisSet;
hsBitVector fVisNot;
hsTArray<plVisRegion*> fVisRegions;
plLightInfo** fPrevDevPtr;
plLightInfo* fNextDevPtr;
hsGDeviceRef* fDeviceRef;
plLayerInterface* fProjection;
hsMatrix44 fWorldToProj;
hsColorRGBA fAmbient;
hsColorRGBA fDiffuse;
hsColorRGBA fSpecular;
hsMatrix44 fLightToLocal;
hsMatrix44 fLocalToLight;
hsMatrix44 fLocalToWorld;
hsMatrix44 fWorldToLocal;
hsMatrix44 fLightToWorld;
hsMatrix44 fWorldToLight;
plKey fSceneNode;
plLightProxy* fProxyGen;
plSoftVolume* fSoftVolume;
hsScalar fMaxStrength;
hsBool fRegisteredForRenderMsg;
// Small shadow section
hsBitVector fSlaveBits;
virtual void IMakeIsect() = 0;
virtual plVolumeIsect* IGetIsect() = 0;
virtual void IRefresh();
virtual const hsMatrix44& IGetWorldToProj() const { return fWorldToProj; }
void IAddVisRegion(plVisRegion* reg);
void IRemoveVisRegion(plVisRegion* reg);
virtual void ISetSceneNode(plKey node);
void ICheckMaxStrength();
public:
plLightInfo();
virtual ~plLightInfo();
CLASSNAME_REGISTER( plLightInfo );
GETINTERFACE_ANY( plLightInfo, plObjInterface );
void SetDeviceRef(hsGDeviceRef* ref);
hsGDeviceRef* GetDeviceRef() const { return fDeviceRef; }
// Dirty state is local to this machine, so shouldn't be in the network synchronized properties.
hsBool IsDirty() const { return 0 != (fVolFlags & kVolDirty); }
void SetDirty(hsBool on=true) { if(on)fVolFlags |= kVolDirty; else fVolFlags &= ~kVolDirty; }
hsBool IsEmpty() const { return 0 != (fVolFlags & kVolEmpty); }
void SetEmpty(hsBool on=true) { if(on)fVolFlags |= kVolEmpty; else fVolFlags &= ~kVolEmpty; }
hsBool IsZero() const { return 0 != (fVolFlags & kVolZero); }
void SetZero(hsBool on) { if(on)fVolFlags |= kVolZero; else fVolFlags &= ~kVolZero; }
inline hsBool IsIdle() const;
hsBool OverAll() const { return GetProperty(kLPOverAll); }
hsBool IsShadowCaster() const { return GetProperty(kLPCastShadows); }
void SetShadowCaster(hsBool on) { SetProperty(kLPCastShadows, on); }
void Refresh() { if( IsDirty() ) { IRefresh(); SetDirty(false); } }
virtual void GetStrengthAndScale(const hsBounds3Ext& bnd, hsScalar& strength, hsScalar& scale) const;
hsBool AffectsBound(const hsBounds3Ext& bnd) { return IGetIsect() ? IGetIsect()->Test(bnd) != kVolumeCulled : true; }
void GetAffectedForced(const plSpaceTree* space, hsBitVector& list, hsBool charac);
void GetAffected(const plSpaceTree* space, hsBitVector& list, hsBool charac);
const hsTArray<Int16>& GetAffected(plSpaceTree* space, const hsTArray<Int16>& visList, hsTArray<Int16>& litList, hsBool charac);
hsBool InVisSet(const hsBitVector& visSet) const { return fVisSet.Overlap(visSet); }
hsBool InVisNot(const hsBitVector& visNot) const { return fVisNot.Overlap(visNot); }
void SetAmbient(const hsColorRGBA& c) { fAmbient = c; SetDirty(); }
void SetDiffuse(const hsColorRGBA& c) { fDiffuse = c; SetDirty(); }
void SetSpecular(const hsColorRGBA& c);
const hsColorRGBA& GetAmbient() const { return fAmbient; }
const hsColorRGBA& GetDiffuse() const { return fDiffuse; }
const hsColorRGBA& GetSpecular() const { return fSpecular; }
plLayerInterface* GetProjection() const { return fProjection; }
virtual void SetProperty(int prop, hsBool on);
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
virtual const hsMatrix44& GetLocalToWorld() const;
virtual const hsMatrix44& GetWorldToLocal() const;
virtual const hsMatrix44& GetLightToWorld() const;
virtual const hsMatrix44& GetWorldToLight() const;
virtual Int32 GetNumProperties() const { return kNumProps; }
const plSoftVolume* GetSoftVolume() const { return fSoftVolume; }
virtual hsVector3 GetNegativeWorldDirection(const hsPoint3& pos) const = 0;
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
virtual hsBool MsgReceive(plMessage* msg);
virtual void Unlink( void );
virtual void Link( plLightInfo **back );
virtual plLightInfo *GetNext( void ) { return fNextDevPtr; }
virtual hsBool IsLinked( void ) { return ( fNextDevPtr != nil || fPrevDevPtr != nil ) ? true : false; }
// New shadow
void ClearSlaveBits() { fSlaveBits.Clear(); }
void SetSlaveBit(int which) { fSlaveBits.SetBit(which); }
const hsBitVector& GetSlaveBits() const { return fSlaveBits; }
// These two should only be called internally and on export/convert
virtual plKey GetSceneNode() const;
// Export only. At runtime, the LocalToLight should be considered const.
void SetLocalToLight(const hsMatrix44& l2lt, const hsMatrix44& lt2l);
// Visualization
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo) { return addTo; }
};
class plDirectionalLightInfo : public plLightInfo
{
protected:
virtual void IMakeIsect() {}
virtual plVolumeIsect* IGetIsect() { return nil; }
public:
plDirectionalLightInfo();
virtual ~plDirectionalLightInfo();
CLASSNAME_REGISTER( plDirectionalLightInfo );
GETINTERFACE_ANY( plDirectionalLightInfo, plLightInfo );
virtual void GetStrengthAndScale(const hsBounds3Ext& bnd, hsScalar& strength, hsScalar& scale) const;
hsVector3 GetWorldDirection() const;
virtual hsVector3 GetNegativeWorldDirection(const hsPoint3& pos) const { return -GetWorldDirection(); }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
};
class plLimitedDirLightInfo : public plDirectionalLightInfo
{
protected:
hsScalar fWidth;
hsScalar fHeight;
hsScalar fDepth;
plParallelIsect* fParPlanes;
virtual void IMakeIsect();
virtual plVolumeIsect* IGetIsect() { return fParPlanes; }
virtual void IRefresh();
public:
plLimitedDirLightInfo();
virtual ~plLimitedDirLightInfo();
CLASSNAME_REGISTER( plLimitedDirLightInfo );
GETINTERFACE_ANY( plLimitedDirLightInfo, plDirectionalLightInfo );
virtual void GetStrengthAndScale(const hsBounds3Ext& bnd, hsScalar& strength, hsScalar& scale) const;
hsScalar GetWidth() const { return fWidth; }
hsScalar GetHeight() const { return fHeight; }
hsScalar GetDepth() const { return fDepth; }
void SetWidth(hsScalar w) { fWidth = w; }
void SetHeight(hsScalar h) { fHeight = h; }
void SetDepth(hsScalar d) { fDepth = d; }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
// Visualization
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
};
class plOmniLightInfo : public plLightInfo
{
protected:
// Omni and spot
hsScalar fAttenConst;
hsScalar fAttenLinear;
hsScalar fAttenQuadratic;
hsScalar fAttenCutoff; // Only for attenuate-but-not-really mode, 0 otherwise
plSphereIsect* fSphere;
virtual void IMakeIsect();
virtual plVolumeIsect* IGetIsect() { return fSphere; }
virtual void IRefresh();
public:
plOmniLightInfo();
virtual ~plOmniLightInfo();
CLASSNAME_REGISTER( plOmniLightInfo );
GETINTERFACE_ANY( plOmniLightInfo, plLightInfo );
virtual void GetStrengthAndScale(const hsBounds3Ext& bnd, hsScalar& strength, hsScalar& scale) const;
virtual hsVector3 GetNegativeWorldDirection(const hsPoint3& pos) const;
hsBool IsAttenuated() const { return (fAttenLinear != 0)||(fAttenQuadratic != 0) || ( fAttenCutoff != 0 ); }
hsScalar GetRadius() const;
hsScalar GetConstantAttenuation() const { return fAttenConst; }
hsScalar GetLinearAttenuation() const { return fAttenLinear; }
hsScalar GetQuadraticAttenuation() const { return fAttenQuadratic; }
hsScalar GetCutoffAttenuation() const { return fAttenCutoff; }
hsPoint3 GetWorldPosition() const { return fLightToWorld.GetTranslate(); }
void SetConstantAttenuation(hsScalar a) { fAttenConst = a; SetDirty(true); }
void SetLinearAttenuation(hsScalar a) { fAttenLinear = a; SetDirty(true); }
void SetQuadraticAttenuation(hsScalar a) { fAttenQuadratic = a; SetDirty(true); }
void SetCutoffAttenuation( hsScalar a ) { fAttenCutoff = a; SetDirty( true ); }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
// Visualization
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
};
class plSpotLightInfo : public plOmniLightInfo
{
protected:
// Valid only for spot
hsScalar fFalloff;
// Note - these are half angles, D3D wants whole angles, so fSpotInner*2 etc.
hsScalar fSpotInner;
hsScalar fSpotOuter;
hsScalar fEffectiveFOV;
plConeIsect* fCone;
virtual void IMakeIsect();
virtual plVolumeIsect* IGetIsect() { return fCone; }
virtual void IRefresh();
public:
plSpotLightInfo();
virtual ~plSpotLightInfo();
CLASSNAME_REGISTER( plSpotLightInfo );
GETINTERFACE_ANY( plSpotLightInfo, plOmniLightInfo );
virtual void GetStrengthAndScale(const hsBounds3Ext& bnd, hsScalar& strength, hsScalar& scale) const;
hsVector3 GetWorldDirection() const;
virtual hsVector3 GetNegativeWorldDirection(const hsPoint3& pos) const { return -GetWorldDirection(); }
void SetFalloff(hsScalar f) { fFalloff = f; SetDirty(true); }
void SetSpotInner(hsScalar rads) { fSpotInner = rads; SetDirty(true); }
void SetSpotOuter(hsScalar rads) { fSpotOuter = rads; SetDirty(true); }
hsScalar GetFalloff() const { return fFalloff; }
hsScalar GetSpotInner() const { return fSpotInner; }
hsScalar GetSpotOuter() const { return fSpotOuter; }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
// Visualization
virtual plDrawableSpans* CreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo);
};
inline hsBool plLightInfo::IsIdle() const
{
if( GetProperty(kDisable) )
return true;
if( IsZero() )
return true;
if( IsEmpty() )
return true;
return false;
}
#endif // plLightInfo_inc

View File

@ -0,0 +1,57 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plLightKonstants_inc
#define plLightKonstants_inc
class plSillyLightKonstants
{
public:
static const float GetFarPowerKonst( void )
{
// arbitrary const, make light drop to 1/kFarPower at attenEnd. 15 just looked good to me. mf
// Done as a function so we don't have to worry about a separate .cpp file
return 15.f;
}
};
#endif // plLightKonstants_inc

View File

@ -0,0 +1,82 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plLightProxy.h"
#include "plLightInfo.h"
#include "../plDrawable/plDrawableSpans.h"
#include "../plDrawable/plDrawableGenerator.h"
#include "../pnMessage/plProxyDrawMsg.h"
plLightProxy::plLightProxy()
: plProxyGen(hsColorRGBA().Set(0,0,0,1.f), hsColorRGBA().Set(0.5f,1.0,0.5f,1.f), 0.2f),
fOwner(nil)
{
}
plLightProxy::~plLightProxy()
{
}
hsBool plLightProxy::Init(plLightInfo* liInfo)
{
plProxyGen::Init(liInfo);
fOwner = liInfo;
fProxyMsgType = plProxyDrawMsg::kLight;
return fOwner != nil;
}
plKey plLightProxy::IGetNode() const
{
return fOwner ? fOwner->GetSceneNode() : nil;
}
plDrawableSpans* plLightProxy::ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo)
{
if( fOwner )
{
return fOwner->CreateProxy(mat, idx, addTo);
}
return nil;
}

View File

@ -0,0 +1,65 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plLightProxy_inc
#define plLightProxy_inc
#include "../plDrawable/plProxyGen.h"
class plLightInfo;
class plLightProxy : public plProxyGen
{
protected:
plLightInfo* fOwner;
virtual plDrawableSpans* ICreateProxy(hsGMaterial* mat, hsTArray<UInt32>& idx, plDrawableSpans* addTo=nil);
virtual plKey IGetNode() const;
public:
plLightProxy();
virtual ~plLightProxy();
hsBool Init(plLightInfo* liInfo);
};
#endif // plLightProxy_inc

View File

@ -0,0 +1,92 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plLightSpace.h"
#include "hsStream.h"
#include "hsResMgr.h"
#include "../plMessage/plLightRefMsg.h"
#include "../plMessage/plCollideMsg.h"
#include "plgDispatch.h"
hsBool plLightSpace::MsgReceive(plMessage* msg)
{
plCollideMsg* collMsg = plCollideMsg::ConvertNoRef(msg);
if( collMsg )
{
// HACK - CollideMsg doesn't have sufficient info yet. Need at least object
// which is entering and leaving, and whether it is entering or leaving.
plKey otherKey = nil;
hsBool enter = true;
UInt8 ctx = enter ? plRefMsg::kOnRequest : plRefMsg::kOnRemove;
plLightRefMsg* liMsg = TRACKED_NEW plLightRefMsg(GetKey(), otherKey, IGetLightInfo(), ctx);
plgDispatch::MsgSend(liMsg);
return true;
}
plLightRefMsg* liMsg = plLightRefMsg::ConvertNoRef(msg);
if( liMsg )
{
if( liMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest|plRefMsg::kOnReplace) )
fLightInfo = liMsg->GetRef();
else if( liMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
fLightInfo = nil;
return true;
}
return false;
}
void plLightSpace::Read(hsStream* s, hsResMgr* mgr)
{
plMultiModifier::Read(s, mgr);
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plLightRefMsg(nil, GetKey(), nil, plRefMsg::kOnCreate), plRefFlags::kPassiveRef);
}
void plLightSpace::Write(hsStream* s, hsResMgr* mgr)
{
plMultiModifier::Write(s, mgr);
mgr->WriteKey(s, fLightInfo);
}

View File

@ -0,0 +1,75 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plLightSpace_inc
#define plLightSpace_inc
class hsStream;
class hsResMgr;
#include "../pnModifier/plMultiModifier.h"
class plLightSpace : public plMultiModifier
{
protected:
hsKeyedObject* fLightInfo;
hsKeyedObject* IGetLightInfo() const { return fLightInfo; }
public:
plLightSpace() : fLightInfo(nil) {}
virtual ~plLightSpace() {}
CLASSNAME_REGISTER( plLightSpace );
GETINTERFACE_ANY( plLightSpace, plMultiModifier );
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty) { return false; }
virtual void Read(hsStream* s, hsResMgr* mgr);
virtual void Write(hsStream* s, hsResMgr* mgr);
virtual hsBool MsgReceive(plMessage* msg);
};
#endif // plLightSpace_inc

View File

@ -0,0 +1,388 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plPipeline.h"
#include "plTweak.h"
#include "hsFastMath.h"
#include "plPerspDirSlave.h"
#include <float.h>
void plPerspDirSlave::Init()
{
plShadowSlave::Init();
fFlags |= kCastInCameraSpace;
}
hsPoint3 plPerspDirSlave::IProject(const hsMatrix44& world2NDC, const hsPoint3& pos, hsScalar w) const
{
hsPoint3 retVal;
retVal.fX = world2NDC.fMap[0][0] * pos.fX
+ world2NDC.fMap[0][1] * pos.fY
+ world2NDC.fMap[0][2] * pos.fZ
+ world2NDC.fMap[0][3] * w;
retVal.fY = world2NDC.fMap[1][0] * pos.fX
+ world2NDC.fMap[1][1] * pos.fY
+ world2NDC.fMap[1][2] * pos.fZ
+ world2NDC.fMap[1][3] * w;
retVal.fZ = world2NDC.fMap[2][0] * pos.fX
+ world2NDC.fMap[2][1] * pos.fY
+ world2NDC.fMap[2][2] * pos.fZ
+ world2NDC.fMap[2][3] * w;
hsScalar invW = 1.f / (
world2NDC.fMap[3][0] * pos.fX
+ world2NDC.fMap[3][1] * pos.fY
+ world2NDC.fMap[3][2] * pos.fZ
+ world2NDC.fMap[3][3] * w);
retVal *= invW;
return retVal;
}
hsBounds3Ext plPerspDirSlave::IGetPerspCasterBound(const hsMatrix44& world2NDC) const
{
hsPoint3 corners[8];
fCasterWorldBounds.GetCorners(corners);
hsPoint3 perspCorners[8];
int i;
for( i = 0; i < 8; i++ )
{
perspCorners[i] = IProject(world2NDC, corners[i]);
if( perspCorners[i].fX < -1.f )
perspCorners[i].fX = -1.f;
else if( perspCorners[i].fX > 1.f )
perspCorners[i].fX = 1.f;
if( perspCorners[i].fY < -1.f )
perspCorners[i].fY = -1.f;
else if( perspCorners[i].fY > 1.f )
perspCorners[i].fY = 1.f;
if( perspCorners[i].fZ < 0 )
perspCorners[i].Set(0.f, 0.f, 0.f);
}
hsBounds3Ext bnd;
bnd.MakeEmpty();
for( i = 0; i < 8; i++ )
bnd.Union(&perspCorners[i]);
return bnd;
}
bool plPerspDirSlave::SetupViewTransform(plPipeline* pipe)
{
plViewTransform pipeView = pipe->GetViewTransform();
plConst(hsScalar) kYon(100.f);
plConst(hsScalar) kHither(30.f);
pipeView.SetHither(kHither);
pipeView.SetYon(kYon);
hsMatrix44 cam2NDC = pipeView.GetCameraToNDC();
hsMatrix44 world2NDC = cam2NDC * pipeView.GetWorldToCamera();
fLightDir = fLightToWorld.GetAxis(hsMatrix44::kUp);
hsVector3 worldLiDir = fLightDir;
hsPoint3 pWorldLiDir(worldLiDir.fX, worldLiDir.fY, worldLiDir.fZ);
hsPoint3 perspLiPos = IProject(world2NDC, pWorldLiDir, 0);
hsBool reverseZ = fLightDir.InnerProduct(pipe->GetViewDirWorld()) > 0;
SetFlag(kReverseZ, reverseZ);
SetFlag(kReverseCull, reverseZ);
hsPoint3 lookAt;
plConst(hsBool) kUsePerspCenter(true);
plConst(hsBool) kUseFrustCenter(true);
if( kUsePerspCenter )
{
hsPoint3 lookAtCam = pipeView.GetWorldToCamera() * fCasterWorldBounds.GetCenter();
hsPoint3 lookAtNDC = IProject(pipeView.GetCameraToNDC(), lookAtCam);
lookAt = IProject(world2NDC, fCasterWorldBounds.GetCenter());
}
else if( kUseFrustCenter )
{
plConst(hsScalar) kDist(50.f);
hsPoint3 camFrustCenter(0.f, 0.f, kDist);
lookAt = IProject(cam2NDC, camFrustCenter);
}
else
{
hsBounds3Ext ndcBnd(IGetPerspCasterBound(world2NDC));
lookAt = ndcBnd.GetCenter();
}
hsMatrix44 camNDC2Li;
hsMatrix44 li2CamNDC;
IComputeCamNDCToLight(perspLiPos, lookAt, camNDC2Li, li2CamNDC);
hsScalar minZ, maxZ;
hsScalar cotX, cotY;
plConst(hsBool) kFixedPersp(true);
if( !kFixedPersp )
{
hsBounds3Ext bnd(IGetPerspCasterBound(camNDC2Li * world2NDC));
hsBounds3Ext bnd2(IGetPerspCasterBound(world2NDC));
bnd2.Transform(&camNDC2Li);
plConst(hsBool) kUseBnd2(false);
if( kUseBnd2 )
bnd = bnd2;
minZ = bnd.GetMins().fZ;
maxZ = bnd.GetMaxs().fZ; // THIS IS WRONG
// EAP
// This is my hack to get the Nexus age working. The real problem
// is probably data-side. I take full responsibility for this
// hack-around breaking the entire system, loosing data, causing
// unauthorized credit card transactions, etc.
if (_isnan(bnd.GetMins().fX) || _isnan(bnd.GetMins().fY))
return false;
if (_isnan(bnd.GetMaxs().fX) || _isnan(bnd.GetMaxs().fY))
return false;
// THIS IS EVEN MORE WRONG
plConst(hsBool) kFakeDepth(false);
if( kFakeDepth )
{
plConst(hsScalar) kMin(1.f);
plConst(hsScalar) kMax(30.f);
minZ = kMin;
maxZ = kMax;
}
plConst(hsScalar) kMinMinZ(1.f);
if( minZ < kMinMinZ )
minZ = kMinMinZ;
if( -bnd.GetMins().fX > bnd.GetMaxs().fX )
{
hsAssert(bnd.GetMins().fX < 0, "Empty shadow caster bounds?");
cotX = -minZ / bnd.GetMins().fX;
}
else
{
hsAssert(bnd.GetMaxs().fX > 0, "Empty shadow caster bounds?");
cotX = minZ / bnd.GetMaxs().fX;
}
if( -bnd.GetMins().fY > bnd.GetMaxs().fY )
{
hsAssert(bnd.GetMins().fY < 0, "Empty shadow caster bounds?");
cotY = -minZ / bnd.GetMins().fY;
}
else
{
hsAssert(bnd.GetMaxs().fY > 0, "Empty shadow caster bounds?");
cotY = minZ / bnd.GetMaxs().fY;
}
}
else
{
plConst(hsScalar) kHi(1.f);
hsBounds3Ext bnd;
const hsPoint3 lo(-1.f, -1.f, 0.f);
const hsPoint3 hi(1.f, 1.f, kHi);
bnd.MakeEmpty();
bnd.Union(&lo);
bnd.Union(&hi);
bnd.Transform(&camNDC2Li);
minZ = bnd.GetMins().fZ;
maxZ = bnd.GetMaxs().fZ; // THIS IS WRONG
// EAP
// This is my hack to get the Nexus age working. The real problem
// is probably data-side. I take full responsibility for this
// hack-around breaking the entire system, loosing data, causing
// unauthorized credit card transactions, etc.
if (_isnan(bnd.GetMins().fX) || _isnan(bnd.GetMins().fY))
return false;
if (_isnan(bnd.GetMaxs().fX) || _isnan(bnd.GetMaxs().fY))
return false;
plConst(hsScalar) kMinMinZ(1.f);
if( minZ < kMinMinZ )
minZ = kMinMinZ;
if( -bnd.GetMins().fX > bnd.GetMaxs().fX )
{
hsAssert(bnd.GetMins().fX < 0, "Empty shadow caster bounds?");
cotX = -minZ / bnd.GetMins().fX;
}
else
{
hsAssert(bnd.GetMaxs().fX > 0, "Empty shadow caster bounds?");
cotX = minZ / bnd.GetMaxs().fX;
}
if( -bnd.GetMins().fY > bnd.GetMaxs().fY )
{
hsAssert(bnd.GetMins().fY < 0, "Empty shadow caster bounds?");
cotY = -minZ / bnd.GetMins().fY;
}
else
{
hsAssert(bnd.GetMaxs().fY > 0, "Empty shadow caster bounds?");
cotY = minZ / bnd.GetMaxs().fY;
}
}
hsMatrix44 proj;
proj.Reset();
proj.NotIdentity();
// LightToTexture
// First the LightToTexture, which uses the above pretty much as is.
// Note the remapping to range [0.5..width-0.5] etc. Also, the perspective
// divide is by the 3rd output (not the fourth), so we make the 3rd
// output be W (instead of Z).
// This also means that our translate goes into [i][2] instead of [i][3].
proj.fMap[0][0] = cotX * 0.5f;
proj.fMap[0][2] = 0.5f * (1.f + 0.5f/fWidth);
proj.fMap[1][1] = -cotY * 0.5f;
proj.fMap[1][2] = 0.5f * (1.f + 0.5f/fHeight);
#if 1 // This computes correct Z, but we really just want W in 3rd component. HACKFISH
proj.fMap[2][2] = maxZ / (maxZ - minZ);
proj.fMap[2][3] = -minZ * maxZ / (maxZ - minZ);
#elif 1
proj.fMap[2][2] = 1.f;
proj.fMap[2][3] = 0;
#endif
proj.fMap[3][2] = 1.f;
proj.fMap[3][3] = 0;
// fWorldToTexture = proj * camNDC2Li * pipeView.GetWorldToNDC();
fWorldToTexture = proj * camNDC2Li * world2NDC;
fWorldToTexture.fMap[2][0] = fWorldToTexture.fMap[3][0];
fWorldToTexture.fMap[2][1] = fWorldToTexture.fMap[3][1];
fWorldToTexture.fMap[2][2] = fWorldToTexture.fMap[3][2];
fWorldToTexture.fMap[2][3] = fWorldToTexture.fMap[3][3];
// Now the LightToNDC. This one's a little trickier, because we want to compensate for
// having brought in the viewport to keep our border constant, so we can clamp the
// projected texture and not have the edges smear off to infinity.
cotX -= cotX / (fWidth * 0.5f);
cotY -= cotY / (fHeight * 0.5f);
hsScalar tanX = 1.f / cotX;
hsScalar tanY = 1.f / cotY;
fView.SetScreenSize((UInt16)fWidth, (UInt16)fHeight);
fView.SetCameraTransform(pipe->GetViewTransform().GetWorldToCamera(), pipe->GetViewTransform().GetCameraToWorld());
fView.SetPerspective(true);
fView.SetViewPort(0, 0, (float)fWidth, (float)fHeight, false);
fView.SetView(hsPoint3(-tanX, -tanY, minZ), hsPoint3(tanX, tanY, maxZ));
hsMatrix44 cam2Light = camNDC2Li * pipeView.GetCameraToNDC();
fView.PostMultCameraToNDC(cam2Light);
fLightPos = fLightToWorld.GetTranslate();
SetFlag(kPositional, false);
return true;
}
static inline hsVector3 CrossProd(const hsVector3& a, const hsPoint3& b)
{
return hsVector3(a.fY*b.fZ - a.fZ*b.fY, a.fZ*b.fX - a.fX*b.fZ, a.fX*b.fY - a.fY*b.fX);
}
static inline void InverseOfPureRotTran(const hsMatrix44& src, hsMatrix44& inv)
{
inv = src;
// We know this is a pure rotation and translation matrix, so
// we won't have to do a full inverse. Okay kids, don't try this
// at home.
inv.fMap[0][1] = src.fMap[1][0];
inv.fMap[0][2] = src.fMap[2][0];
inv.fMap[1][0] = src.fMap[0][1];
inv.fMap[1][2] = src.fMap[2][1];
inv.fMap[2][0] = src.fMap[0][2];
inv.fMap[2][1] = src.fMap[1][2];
hsPoint3 newTran(-src.fMap[0][3], -src.fMap[1][3], -src.fMap[2][3]);
inv.fMap[0][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[0][0]);
inv.fMap[1][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[1][0]);
inv.fMap[2][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[2][0]);
}
void plPerspDirSlave::IComputeCamNDCToLight(const hsPoint3& from, const hsPoint3& at, hsMatrix44& camNDC2Li, hsMatrix44& li2CamNDC)
{
hsVector3 atToFrom(&from, &at);
hsScalar distSq = atToFrom.MagnitudeSquared();
atToFrom *= hsFastMath::InvSqrtAppr(distSq);
const hsScalar kMinMag = 0.5f;
hsVector3 up(0,0,1.f);
if( CrossProd(up, (at - from)).MagnitudeSquared() < kMinMag )
{
up.Set(0, 1.f, 0);
}
hsMatrix44 w2light;
w2light.MakeCamera(&from, &at, &up);
hsMatrix44 light2w;
InverseOfPureRotTran(w2light, light2w);
#ifdef CHECK_INVERSE
hsMatrix44 inv;
w2light.GetInverse(&inv);
#endif // CHECK_INVERSE
camNDC2Li = w2light;
li2CamNDC = light2w;
}

View File

@ -0,0 +1,63 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plPerspDirSlave_inc
#define plPerspDirSlave_inc
#include "plShadowSlave.h"
class plPerspDirSlave : public plShadowSlave
{
protected:
hsBounds3Ext IGetPerspCasterBound(const hsMatrix44& world2NDC) const;
hsPoint3 IProject(const hsMatrix44& world2NDC, const hsPoint3& pos, hsScalar w=1.f) const;
void IComputeCamNDCToLight(const hsPoint3& from, const hsPoint3& at, hsMatrix44& camNDC2Li, hsMatrix44& li2CamNDC);
public:
virtual void Init();
virtual bool SetupViewTransform(plPipeline* pipe);
};
#endif // plPerspDirSlave_inc

View File

@ -0,0 +1,219 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plPointShadowMaster.h"
#include "plShadowSlave.h"
#include "plShadowCaster.h"
#include "../plMessage/plShadowCastMsg.h"
#include "plLightInfo.h"
#include "hsMatrix44.h"
#include "hsBounds.h"
#include "hsFastMath.h"
static const hsScalar kMinMinZ = 1.f; // totally random arbitrary number (has to be > 0).
static inline void QuickNorm( hsVector3& a, hsScalar& b )
{
hsScalar len = hsFastMath::InvSqrtAppr((a).MagnitudeSquared());
a *= len;
b *= len;
}
static inline hsVector3 CrossProd(const hsVector3& a, const hsPoint3& b)
{
return hsVector3(a.fY*b.fZ - a.fZ*b.fY, a.fZ*b.fX - a.fX*b.fZ, a.fX*b.fY - a.fY*b.fX);
}
static inline void InverseOfPureRotTran(const hsMatrix44& src, hsMatrix44& inv)
{
inv = src;
// We know this is a pure rotation and translation matrix, so
// we won't have to do a full inverse. Okay kids, don't try this
// at home.
inv.fMap[0][1] = src.fMap[1][0];
inv.fMap[0][2] = src.fMap[2][0];
inv.fMap[1][0] = src.fMap[0][1];
inv.fMap[1][2] = src.fMap[2][1];
inv.fMap[2][0] = src.fMap[0][2];
inv.fMap[2][1] = src.fMap[1][2];
hsPoint3 newTran(-src.fMap[0][3], -src.fMap[1][3], -src.fMap[2][3]);
inv.fMap[0][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[0][0]);
inv.fMap[1][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[1][0]);
inv.fMap[2][3] = newTran.InnerProduct((hsVector3*)&inv.fMap[2][0]);
}
////////////////////////////////////////////////////////////////////////////////////
// Point first
////////////////////////////////////////////////////////////////////////////////////
plPointShadowMaster::plPointShadowMaster()
{
fLastUp.Set(0,0,0);
}
plPointShadowMaster::~plPointShadowMaster()
{
fIsectPool.SetCount(fIsectPool.GetNumAlloc());
int i;
for( i = 0; i < fIsectPool.GetCount(); i++ )
delete fIsectPool[i];
}
plShadowSlave* plPointShadowMaster::INewSlave(const plShadowCaster* caster)
{
return TRACKED_NEW plPointShadowSlave;
}
void plPointShadowMaster::IBeginRender()
{
plShadowMaster::IBeginRender();
fIsectPool.SetCount(0);
}
void plPointShadowMaster::IComputeWorldToLight(const hsBounds3Ext& bnd, plShadowSlave* slave) const
{
const hsScalar kMinMag = 0.5f;
hsPoint3 from = fLightInfo->GetLightToWorld().GetTranslate();
hsPoint3 at = bnd.GetCenter();
hsVector3 atToFrom(&from, &at);
hsScalar distSq = atToFrom.MagnitudeSquared();
atToFrom *= hsFastMath::InvSqrtAppr(distSq);
hsPoint2 depth;
bnd.TestPlane(atToFrom, depth);
hsScalar fromDepth = atToFrom.InnerProduct(from);
hsScalar dist = fromDepth - depth.fY;
static hsScalar kMinDist = 3.f;
if( dist < kMinDist )
{
atToFrom *= kMinDist - dist;
from += atToFrom;
}
hsVector3 up(0,0,1.f);
if( CrossProd(up, (at - from)).MagnitudeSquared() < kMinMag )
{
up.Set(0, 1.f, 0);
}
hsMatrix44 w2light;
w2light.MakeCamera(&from, &at, &up); // mf_flip_up - mf
hsMatrix44 light2w;
InverseOfPureRotTran(w2light, light2w);
#ifdef CHECK_INVERSE
hsMatrix44 inv;
w2light.GetInverse(&inv);
#endif // CHECK_INVERSE
slave->fWorldToLight = w2light;
slave->fLightToWorld = light2w;
}
void plPointShadowMaster::IComputeProjections(plShadowCastMsg* castMsg, plShadowSlave* slave) const
{
slave->fView.SetPerspective(true);
}
void plPointShadowMaster::IComputeISect(const hsBounds3Ext& bnd, plShadowSlave* slave) const
{
int iIsect = fIsectPool.GetCount();
fIsectPool.ExpandAndZero(iIsect+1);
if( !fIsectPool[iIsect] )
{
fIsectPool[iIsect] = TRACKED_NEW plBoundsIsect;
}
plBoundsIsect* isect = fIsectPool[iIsect];
const hsBounds3Ext& wBnd = slave->fWorldBounds;
isect->SetBounds(wBnd);
slave->fIsect = isect;
}
void plPointShadowMaster::IComputeBounds(const hsBounds3Ext& wBnd, plShadowSlave* slave) const
{
// Plan here is to look at the bounds in the slave's local space.
// Our slave's bounds will clearly contain the shadow caster's bounds. It will also
// contain the bnd's corners projected out along the ray from the slave's position
// through each corner. They will extend fAttenDist farther than the center point
// of the bound.
hsBounds3Ext sBnd = wBnd;
sBnd.Transform(&slave->fWorldToLight);
hsBounds3Ext bnd = sBnd;
hsScalar dist = sBnd.GetCenter().fZ;
dist += slave->fAttenDist;
hsScalar minZ = sBnd.GetMaxs().fZ;
hsPoint3 p(sBnd.GetMins().fX * dist / minZ, sBnd.GetMins().fY * dist / minZ, dist);
bnd.Union(&p);
p.Set(sBnd.GetMaxs().fX * dist / minZ, sBnd.GetMaxs().fY * dist / minZ, dist);
bnd.Union(&p);
bnd.Transform(&slave->fLightToWorld);
slave->fWorldBounds = bnd;
}

View File

@ -0,0 +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/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plPointShadowMaster_inc
#define plPointShadowMaster_inc
#include "plShadowMaster.h"
#include "hsGeometry3.h"
class plBoundsIsect;
class plPointShadowMaster : public plShadowMaster
{
protected:
mutable hsVector3 fLastUp;
mutable hsTArray<plBoundsIsect*> fIsectPool;
virtual void IComputeWorldToLight(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual void IComputeProjections(plShadowCastMsg* castMsg, plShadowSlave* slave) const;
virtual void IComputeISect(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual void IComputeBounds(const hsBounds3Ext& bnd, plShadowSlave* slave) const;
virtual plShadowSlave* INewSlave(const plShadowCaster* caster);
virtual void IBeginRender();
public:
plPointShadowMaster();
virtual ~plPointShadowMaster();
CLASSNAME_REGISTER( plPointShadowMaster );
GETINTERFACE_ANY( plPointShadowMaster, plShadowMaster );
};
#endif // plPointShadowMaster_inc

View File

@ -0,0 +1,224 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plShadowCaster.h"
#include "../plMessage/plShadowCastMsg.h"
#include "../pnSceneObject/plSceneObject.h"
#include "../pnSceneObject/plDrawInterface.h"
#include "../plDrawable/plDrawableSpans.h"
#include "../plDrawable/plSpanTypes.h"
#include "../plSurface/hsGMaterial.h"
#include "../plSurface/plLayerInterface.h"
#include "../plMessage/plRenderMsg.h"
#include "plgDispatch.h"
#include "plShadowMaster.h"
hsBool plShadowCaster::fShadowCastDisabled = false;
hsBool plShadowCaster::fCanShadowCast = true;
plShadowCaster::plShadowCaster()
: fMaxOpacity(0),
fCastFlags(0),
fAttenScale(1.f),
fBlurScale(0.f),
fBoost(1.f)
{
}
plShadowCaster::~plShadowCaster()
{
Deactivate();
}
void plShadowCaster::Read(hsStream* stream, hsResMgr* mgr)
{
plMultiModifier::Read(stream, mgr);
fCastFlags = stream->ReadByte();
// HACKTESTPERSP
// if( !(fCastFlags & kPerspective) )
// fCastFlags |= kPerspective;
// else
fCastFlags &= ~kPerspective;
fBoost = stream->ReadSwapScalar();
fAttenScale = stream->ReadSwapScalar();
fBlurScale = stream->ReadSwapScalar();
Activate();
}
void plShadowCaster::Write(hsStream* stream, hsResMgr* mgr)
{
plMultiModifier::Write(stream, mgr);
stream->WriteByte(fCastFlags);
stream->WriteSwapScalar(fBoost);
stream->WriteSwapScalar(fAttenScale);
stream->WriteSwapScalar(fBlurScale);
}
void plShadowCaster::Activate() const
{
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
}
void plShadowCaster::Deactivate() const
{
plgDispatch::Dispatch()->UnRegisterForExactType(plRenderMsg::Index(), GetKey());
}
void plShadowCaster::ICollectAllSpans()
{
fSpans.SetCount(0);
int i;
for( i = 0; i < GetNumTargets(); i++ )
{
plSceneObject* so = GetTarget(i);
// Nil target? Shouldn't happen.
if( so )
{
const plDrawInterface* di = so->GetDrawInterface();
// Nil di- either it hasn't loaded yet, or we've been applied to something that isn't visible (oops).
if( di && !di->GetProperty(plDrawInterface::kDisable) )
{
int j;
for( j = 0; j < di->GetNumDrawables(); j++ )
{
plDrawableSpans* dr = plDrawableSpans::ConvertNoRef(di->GetDrawable(j));
// Nil dr - it hasn't loaded yet.
if( dr )
{
plDISpanIndex& diIndex = dr->GetDISpans(di->GetDrawableMeshIndex(j));
if( !diIndex.IsMatrixOnly() )
{
int k;
for( k = 0; k < diIndex.GetCount(); k++ )
{
const plSpan* span = dr->GetSpan(diIndex[k]);
// if( !(span->fProps & plSpan::kPropNoShadowCast) )
{
fSpans.Append(DrawSpan().Set(dr, span, diIndex[k]));
}
}
}
}
}
}
}
}
}
hsBool plShadowCaster::IOnRenderMsg(plRenderMsg* msg)
{
if( ShadowCastDisabled() )
return true;
const UInt8 shadowQuality = UInt8(plShadowMaster::GetGlobalShadowQuality() * 3.9f);
if( !GetKey()->GetUoid().GetLoadMask().MatchesQuality(shadowQuality) )
return true;
// Don't really like having to gather these guys up every frame,
// but with the avatar customization, it's all pretty volatile,
// subject to infrequent change, but change without warning.
// The number of actual targets (and hence shadow casting spans)
// for any ShadowCasterModifier should always be on the order of
// 10, so chances are we can get away with this. If not, we can
// figure some way of caching, like a broadcast message warning us
// that an avatar customization event has occurred.
ICollectAllSpans();
// Max opacity used to fade out shadows during link
//find max opacity of all spans
//clear shadowBits of all spans
fMaxOpacity = 0.f;
int i;
for( i = 0; i < fSpans.GetCount(); i++ )
{
hsGMaterial* mat = fSpans[i].fDraw->GetSubMaterial(fSpans[i].fSpan->fMaterialIdx);
if( mat )
{
plLayerInterface* baseLay = mat->GetLayer(0);
if( baseLay && (baseLay->GetOpacity() > fMaxOpacity) )
fMaxOpacity = baseLay->GetOpacity();
}
fSpans[i].fSpan->ClearShadowBits();
}
if( fMaxOpacity > 0 )
{
plShadowCastMsg* cast = TRACKED_NEW plShadowCastMsg(GetKey(), this, msg->Pipeline());
cast->Send();
}
return true;
}
#include "plProfile.h"
plProfile_CreateTimer("ShadowCaster", "RenderSetup", ShadowCaster);
hsBool plShadowCaster::MsgReceive(plMessage* msg)
{
plRenderMsg* rendMsg = plRenderMsg::ConvertNoRef(msg);
if( rendMsg )
{
plProfile_BeginLap(ShadowCaster, this->GetKey()->GetUoid().GetObjectName());
IOnRenderMsg(rendMsg);
plProfile_EndLap(ShadowCaster, this->GetKey()->GetUoid().GetObjectName());
return true;
}
return plMultiModifier::MsgReceive(msg);
}

View File

@ -0,0 +1,157 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plShadowCaster_inc
#define plShadowCaster_inc
#include "../pnModifier/plMultiModifier.h"
#include "hsBounds.h"
#include "hsTemplates.h"
class plDrawableSpans;
class plSpan;
class plMessage;
class hsStream;
class hsResMgr;
class plShadowMaster;
class plRenderMsg;
class plShadowCaster : public plMultiModifier
{
public:
enum {
kNone = 0x0,
kSelfShadow = 0x1,
kPerspective = 0x2,
kLimitRes = 0x4
};
class DrawSpan
{
public:
DrawSpan& Set(plDrawableSpans* dr, const plSpan* sp, UInt32 idx) { fDraw = (dr); fSpan = (sp); fIndex = (idx); return *this; }
plDrawableSpans* fDraw;
const plSpan* fSpan;
UInt32 fIndex;
};
protected:
// Global state to just turn off the whole gig. Not just
// debugging, we'll probably want a user option for this.
static hsBool fShadowCastDisabled;
static hsBool fCanShadowCast;
// Properties really just to be read and written,
// never expected to change. Anything that might be
// triggered should go into plMultiModifier::fProps,
// to be network synced.
UInt8 fCastFlags;
hsScalar fBoost;
hsScalar fAttenScale;
hsScalar fBlurScale;
// Casting attributes calculated each frame.
hsScalar fMaxOpacity;
hsTArray<DrawSpan> fSpans;
friend plShadowMaster;
void ICollectAllSpans();
hsBool IOnRenderMsg(plRenderMsg* msg);
friend class plDXPipeline;
static void SetCanShadowCast(hsBool b) { fCanShadowCast = b; }
public:
plShadowCaster();
virtual ~plShadowCaster();
CLASSNAME_REGISTER( plShadowCaster );
GETINTERFACE_ANY( plShadowCaster, plMultiModifier );
virtual hsBool IEval(double secs, hsScalar del, UInt32 dirty) { return true; }
virtual hsBool MsgReceive(plMessage* msg);
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
hsScalar MaxOpacity() const { return fMaxOpacity; }
const hsTArray<DrawSpan>& Spans() const { return fSpans; }
hsBool GetSelfShadow() const { return 0 != (fCastFlags & kSelfShadow); }
void SetSelfShadow(hsBool on) { if(on) fCastFlags |= kSelfShadow; else fCastFlags &= ~kSelfShadow; }
hsBool GetPerspective() const { return 0 != (fCastFlags & kPerspective); }
void SetPerspective(hsBool on) { if(on) fCastFlags |= kPerspective; else fCastFlags &= ~kPerspective; }
hsBool GetLimitRes() const { return 0 != (fCastFlags & kLimitRes); }
void SetLimitRes(hsBool on) { if(on) fCastFlags |= kLimitRes; else fCastFlags &= ~kLimitRes; }
hsScalar GetAttenScale() const { return fAttenScale; }
void SetAttenScale(hsScalar s) { fAttenScale = s; }
hsScalar GetBlurScale() const { return fBlurScale; }
void SetBlurScale(hsScalar s) { fBlurScale = s; }
hsScalar GetBoost() const { return fBoost; }
void SetBoost(hsScalar s) { fBoost = s; }
// These are usually handled internally, activating on read and deactivating
// on destruct. Made public in case they need to be manually handled, like
// on dynamic construction and use.
void Deactivate() const;
void Activate() const;
static void DisableShadowCast(hsBool on=true) { fShadowCastDisabled = on; }
static void EnableShadowCast(hsBool on=true) { fShadowCastDisabled = !on; }
static void ToggleShadowCast() { fShadowCastDisabled = !fShadowCastDisabled; }
static hsBool ShadowCastDisabled() { return !CanShadowCast() || fShadowCastDisabled; }
static hsBool CanShadowCast() { return fCanShadowCast; }
};
typedef plShadowCaster::DrawSpan plShadowCastSpan;
#endif // plShadowCaster_inc

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,170 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plShadowMaster_inc
#define plShadowMaster_inc
#include "../pnSceneObject/plObjInterface.h"
class plShadowCaster;
class plShadowSlave;
struct hsMatrix44;
class hsBounds3Ext;
class hsStream;
class hsResMgr;
class plMessage;
class plLightInfo;
class plShadowCastMsg;
class plShadowMaster : public plObjInterface
{
public:
// Props inc by 1 (bit shift in bitvector).
enum plDrawProperties {
kDisable = 0,
kSelfShadow,
kNumProps // last in the list
};
protected:
// Global clamp on shadow map size and stuff
static UInt32 fGlobalMaxSize;
static hsScalar fGlobalMaxDist;
static hsScalar fGlobalVisParm;
// Constant parameter(s) for this master.
hsScalar fAttenDist;
hsScalar fMaxDist;
hsScalar fMinDist;
UInt32 fMaxSize;
UInt32 fMinSize;
hsScalar fPower;
// Temp data used for one frame and recycled.
hsTArray<plShadowSlave*> fSlavePool;
plLightInfo* fLightInfo;
// These are specific to the projection type (perspective or orthogonal), so have to
// be implemented by the derived class.
virtual void IComputeWorldToLight(const hsBounds3Ext& bnd, plShadowSlave* slave) const = 0;
virtual void IComputeProjections(plShadowCastMsg* castMsg, plShadowSlave* slave) const = 0;
virtual void IComputeISect(const hsBounds3Ext& bnd, plShadowSlave* slave) const = 0;
virtual void IComputeBounds(const hsBounds3Ext& bnd, plShadowSlave* slave) const = 0;
// Base class implementations of the rest. These might need to be overridden later, especially
// on computing the width and height. That's really specific to the projection type, but
// to get started I'll probably just always return 256x256.
virtual void IComputeCasterBounds(const plShadowCaster* caster, hsBounds3Ext& casterBnd);
virtual void IComputeWidthAndHeight(plShadowCastMsg* castMsg, plShadowSlave* slave) const;
virtual void IComputeLUT(plShadowCastMsg* castMsg, plShadowSlave* slave) const;
virtual hsScalar IComputePower(const plShadowCaster* caster, const hsBounds3Ext& casterBnd) const;
virtual plShadowSlave* ILastChanceToBail(plShadowCastMsg* castMsg, plShadowSlave* slave);
virtual plShadowSlave* ICreateShadowSlave(plShadowCastMsg* castMsg, const hsBounds3Ext& casterBnd, hsScalar power);
virtual plShadowSlave* INewSlave(const plShadowCaster* caster) = 0;
virtual plShadowSlave* INextSlave(const plShadowCaster* caster);
virtual plShadowSlave* IRecycleSlave(plShadowSlave* slave);
plLightInfo* ISetLightInfo();
virtual void IBeginRender();
virtual hsBool IOnCastMsg(plShadowCastMsg* castMsg);
public:
plShadowMaster();
virtual ~plShadowMaster();
CLASSNAME_REGISTER( plShadowMaster );
GETINTERFACE_ANY( plShadowMaster, plObjInterface );
virtual hsBool MsgReceive(plMessage* msg);
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) {}
Int32 GetNumProperties() const { return kNumProps; }
virtual void Read(hsStream* stream, hsResMgr* mgr);
virtual void Write(hsStream* stream, hsResMgr* mgr);
// These are usually handled internally, activating on read and deactivating
// on destruct. Made public in case they need to be manually handled, like
// on dynamic construction and use.
void Deactivate() const;
void Activate() const;
// These should only be useful on scene conversion.
hsScalar GetAttenDist() const { return fAttenDist; }
void SetAttenDist(hsScalar d) { fAttenDist = d; }
hsScalar GetMaxDist() const { return fMaxDist; }
hsScalar GetMinDist() const { return fMinDist; }
void SetMaxDist(hsScalar m);
UInt32 GetMaxSize() const { return fMaxSize; }
UInt32 GetMinSize() const { return fMinSize; }
void SetMaxSize(UInt32 s) { fMaxSize = s; }
void SetMinSize(UInt32 s) { fMinSize = s; }
hsScalar GetPower() const { return fPower; }
void SetPower(hsScalar f) { fPower = f; }
static void SetGlobalMaxSize(UInt32 s) ;
static UInt32 GetGlobalMaxSize() { return fGlobalMaxSize; }
static void SetGlobalMaxDist(hsScalar s) { fGlobalMaxDist = s; }
static hsScalar GetGlobalMaxDist() { return fGlobalMaxDist; }
static void SetGlobalShadowQuality(hsScalar s);
static hsScalar GetGlobalShadowQuality() { return fGlobalVisParm; }
};
#endif // plShadowMaster_inc

View File

@ -0,0 +1,216 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#include "hsTypes.h"
#include "plShadowSlave.h"
#include "plTweak.h"
#include <float.h>
static const hsScalar kMinMinZ = 1.f; // totally random arbitrary number (has to be > 0).
bool plShadowSlave::ISetupOrthoViewTransform()
{
hsBounds3Ext bnd = fCasterWorldBounds;
bnd.Transform(&fWorldToLight);
hsScalar minZ = bnd.GetMins().fZ;
hsScalar maxZ = bnd.GetCenter().fZ + fAttenDist;
hsScalar minX = bnd.GetMins().fX;
hsScalar maxX = bnd.GetMaxs().fX;
hsScalar minY = bnd.GetMins().fY;
hsScalar maxY = bnd.GetMaxs().fY;
hsMatrix44 proj;
proj.Reset();
proj.NotIdentity();
// First the LightToTexture, which uses the above pretty much as is.
// Note the remapping to range [0.5..width-0.5] etc.
// About this kAdjustBias. According to the docs, it should be 0.5,
// and on the perspective projection 0.5 works great. But on the
// directional (ortho) projection, it just makes the mapping wrong,
// and an offset of zero works great. This could be a driver bug, or
// hardware "dependency" (read IHV bug), but whatever, zero is working
// now. Might need to adjust for new drivers or other hardware.
const hsScalar kAdjustBias = 0.0f;
proj.fMap[0][0] = 1.f / (maxX - minX);
proj.fMap[0][3] = -minX / (maxX - minX) + kAdjustBias / fWidth;
proj.fMap[1][1] = -1.f / (maxY - minY);
proj.fMap[1][3] = -minY / (maxY - minY) + kAdjustBias / fHeight;
proj.fMap[2][2] = 1.f;
proj.fMap[3][3] = 1.f;
fWorldToTexture = proj * fWorldToLight;
// Now the LightToNDC. This one's a little trickier, because we want to compensate for
// having brought in the viewport to keep our border constant, so we can clamp the
// projected texture and not have the edges smear off to infinity.
// Like the adjust bias above, this part is correct in theory, but only
// screws things up (increases Z-acne).
#if 0
hsScalar delX = maxX - minX;
minX += delX / (fWidth * 0.5f);
maxX -= delX / (fWidth * 0.5f);
hsScalar delY = maxY - minY;
minY += delY / (fHeight * 0.5f);
maxY -= delY / (fHeight * 0.5f);
#endif
fView.SetView(hsPoint3(minX, minY, minZ), hsPoint3(maxX, maxY, maxZ));
fView.SetScreenSize((UInt16)fWidth, (UInt16)fHeight);
fView.SetCameraTransform(fWorldToLight, fLightToWorld);
fView.SetPerspective(false);
fView.SetViewPort(0, 0, hsScalar(fWidth), hsScalar(fHeight), false);
fLightDir = fLightToWorld.GetAxis(hsMatrix44::kUp);
SetFlag(kPositional, false);
SetFlag(kReverseCull, true);
return true;
}
bool plShadowSlave::ISetupPerspViewTransform()
{
hsBounds3Ext bnd = fCasterWorldBounds;
bnd.Transform(&fWorldToLight);
hsScalar minZ = bnd.GetMins().fZ;
hsScalar maxZ = bnd.GetCenter().fZ + fAttenDist;
if( minZ < kMinMinZ )
minZ = kMinMinZ;
// EAP
// This is my hack to get the Nexus age working. The real problem
// is probably data-side. I take full responsibility for this
// hack-around breaking the entire system, loosing data, causing
// unauthorized credit card transactions, etc.
if (_isnan(bnd.GetMins().fX) || _isnan(bnd.GetMins().fY))
return false;
if (_isnan(bnd.GetMaxs().fX) || _isnan(bnd.GetMaxs().fY))
return false;
hsScalar cotX, cotY;
if( -bnd.GetMins().fX > bnd.GetMaxs().fX )
{
hsAssert(bnd.GetMins().fX < 0, "Empty shadow caster bounds?");
cotX = -minZ / bnd.GetMins().fX;
}
else
{
hsAssert(bnd.GetMaxs().fX > 0, "Empty shadow caster bounds?");
cotX = minZ / bnd.GetMaxs().fX;
}
if( -bnd.GetMins().fY > bnd.GetMaxs().fY )
{
hsAssert(bnd.GetMins().fY < 0, "Empty shadow caster bounds?");
cotY = -minZ / bnd.GetMins().fY;
}
else
{
hsAssert(bnd.GetMaxs().fY > 0, "Empty shadow caster bounds?");
cotY = minZ / bnd.GetMaxs().fY;
}
hsMatrix44 proj;
proj.Reset();
proj.NotIdentity();
// First the LightToTexture, which uses the above pretty much as is.
// Note the remapping to range [0.5..width-0.5] etc. Also, the perspective
// divide is by the 3rd output (not the fourth), so we make the 3rd
// output be W (instead of Z).
// This also means that our translate goes into [i][2] instead of [i][3].
#if 0
proj.fMap[0][0] = cotX * 0.5f;
proj.fMap[0][2] = -0.5f * (1.f + 0.5f/fWidth);
proj.fMap[1][1] = cotY * 0.5f;
proj.fMap[1][2] = -0.5f * (1.f + 0.5f/fHeight);
#else
plConst(hsScalar) kBiasScale(1.f);
plConst(hsScalar) kBiasTrans(1.f);
proj.fMap[0][0] = cotX * 0.5f * ( hsScalar(fWidth-2.f) / hsScalar(fWidth) ) * kBiasScale;
proj.fMap[0][2] = 0.5f * (1.f - kBiasTrans * 0.5f/fWidth);
proj.fMap[1][1] = -cotY * 0.5f * ( hsScalar(fHeight-2.f) / hsScalar(fHeight) ) * kBiasScale;
proj.fMap[1][2] = 0.5f * (1.f - kBiasTrans * 0.5f/fHeight);
#endif
#if 0 // This computes correct Z, but we really just want W in 3rd component. HACKFISH
proj.fMap[2][2] = maxZ / (maxZ - minZ);
proj.fMap[2][3] = -minZ * maxZ / (maxZ - minZ);
#elif 1
proj.fMap[2][2] = 1.f;
proj.fMap[2][3] = 0;
#endif
proj.fMap[3][2] = 1.f;
proj.fMap[3][3] = 0;
fWorldToTexture = proj * fWorldToLight;
// Now the LightToNDC. This one's a little trickier, because we want to compensate for
// having brought in the viewport to keep our border constant, so we can clamp the
// projected texture and not have the edges smear off to infinity.
cotX -= cotX / (fWidth * 0.5f);
cotY -= cotY / (fHeight * 0.5f);
hsScalar tanX = 1.f / cotX;
hsScalar tanY = 1.f / cotY;
fView.SetView(hsPoint3(-tanX, -tanY, minZ), hsPoint3(tanX, tanY, maxZ));
fView.SetScreenSize((UInt16)fWidth, (UInt16)fHeight);
fView.SetCameraTransform(fWorldToLight, fLightToWorld);
fView.SetPerspective(true);
fView.SetViewPort(0, 0, hsScalar(fWidth), hsScalar(fHeight), false);
fLightPos = fLightToWorld.GetTranslate();
SetFlag(kPositional, true);
return true;
}

View File

@ -0,0 +1,140 @@
/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plShadowSlave_inc
#define plShadowSlave_inc
#include "hsMatrix44.h"
#include "hsBounds.h"
#include "plViewTransform.h"
#include "hsGeometry3.h"
class plShadowCaster;
class plVolumeIsect;
class plPipeline;
class plShadowSlave
{
public:
UInt32 fIndex;
hsMatrix44 fWorldToLight;
hsMatrix44 fLightToWorld;
hsPoint3 fLightPos;
hsVector3 fLightDir;
hsMatrix44 fWorldToTexture;
hsMatrix44 fCastLUT;
hsMatrix44 fRcvLUT;
plViewTransform fView;
hsScalar fPower;
hsScalar fBlurScale;
hsBounds3Ext fCasterWorldBounds;
hsBounds3Ext fWorldBounds;
plVolumeIsect* fIsect;
UInt32 fWidth;
UInt32 fHeight;
hsScalar fAttenDist;
hsScalar fPriority;
UInt32 fFlags;
enum SlaveFlag
{
kObeysLightGroups = 0x1,
kIncludesChars = 0x2,
kSelfShadow = 0x4,
kCastInCameraSpace = 0x8,
kReverseZ = 0x10,
kTwoSided = 0x20,
kReverseCull = 0x40,
kPositional = 0x80
};
void SetFlag(SlaveFlag f, hsBool on) { if(on) fFlags |= f; else fFlags &= ~f; }
hsBool HasFlag(SlaveFlag f) const { return 0 != (fFlags & f); }
hsBool ObeysLightGroups() const { return HasFlag(kObeysLightGroups); }
hsBool IncludesChars() const { return HasFlag(kIncludesChars); }
hsBool SelfShadow() const { return HasFlag(kSelfShadow); }
hsBool CastInCameraSpace() const { return HasFlag(kCastInCameraSpace); }
hsBool ReverseZ() const { return HasFlag(kReverseZ); }
hsBool TwoSided() const { return HasFlag(kTwoSided); }
hsBool ReverseCull() const { return HasFlag(kReverseCull); }
hsBool Positional() const { return HasFlag(kPositional); }
virtual void Init() { fFlags = 0; }
const plShadowCaster* fCaster;
// Internal to pipeline, no touch!!!
int fLightIndex;
int fLightRefIdx;
int fSelfShadowOn;
void* fPipeData;
bool ISetupOrthoViewTransform();
bool ISetupPerspViewTransform();
virtual bool SetupViewTransform(plPipeline* pipe) = 0;
};
class plDirectShadowSlave : public plShadowSlave
{
virtual bool SetupViewTransform(plPipeline* pipe) { return ISetupOrthoViewTransform(); }
};
class plPointShadowSlave : public plShadowSlave
{
virtual bool SetupViewTransform(plPipeline* pipe) { return ISetupPerspViewTransform(); }
};
#endif // plShadowSlave_inc