/*==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 .
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 plMaxNodeData_inc
#define plMaxNodeData_inc
#include "HeadSpin.h"
#include "hsTemplates.h"
#include "hsColorRGBA.h"
#include "plRenderLevel.h"
#include "plPhysicalProps.h"
#include "hsBitVector.h"
#include "pnKeyedObject/plKey.h"
#include "plLoadMask.h"
class plMaxNodeBase;
class plMaxNode;
class plLocation;
class plSceneObject;
class hsGMesh;
class plGeometrySpan;
class plMaxBoneMap;
class plSharedMesh;
class plMaxNodeBaseTab : public Tab
{
};
//
// Created hoping to trim some fat so to speak for all the bools that
// we are tossing around.
//
class DataBF
{
public:
enum DatBit
{
kCanConvert = 0x0,
kForceLocal,
kDrawable, // Absence of this prop forbids making this drawable
kBlendToFB,
kItinerant,
kRunTimeLight,
kMovable,
kIsBarney,
kForceMatCopy,
kNoPreShade,
kIsInstanced,
kParticleRelated,
kNoSpanReSort,
kHasFade,
kNoFaceSort,
kNoSpanSort,
kNoDeferDraw,
kBLevelSet,
kOLevelSet,
kDup2Sided,
kRadiateNorms,
kGeoDice,
kForcePreShade,
kIsGUI,
kSwappableGeomTarget,
kNoShadow,
kForceShadow,
kFilterInherit,
kReverseSort,
kVS,
kConcave,
kCalcEdgeLens,
kEnviron,
kEnvironOnly,
kPhysical, // Absence of this prop forbids making this physical
kSmoothAll,
kForceSortable,
kOverrideHighLevelSDL,
kDisableNormal,
kHasLoadMask,
kWaterDecEnv,
kWaterHeight,
kAlphaTestHigh,
kForceMatShade,
kUnBounded,
kForceVisLOS,
kSortAsOpaque,
};
hsBitVector* fBitVector;
DataBF()
{
fBitVector = TRACKED_NEW hsBitVector;
fBitVector->SetBit(kDrawable);
fBitVector->SetBit(kPhysical);
}
virtual ~DataBF() { delete fBitVector; }
DataBF& operator=(const DataBF& ot)
{
*fBitVector = *ot.fBitVector;
return *this;
}
DataBF(const DataBF& ot)
{
fBitVector = TRACKED_NEW hsBitVector;
*fBitVector = *ot.fBitVector;
}
void Init()
{
fBitVector = TRACKED_NEW hsBitVector;
fBitVector->SetBit(kDrawable);
fBitVector->SetBit(kPhysical);
}
void DeInit() { delete fBitVector; fBitVector = nil; }
hsBool CanBF(DatBit bitChoice) { return fBitVector->IsBitSet(bitChoice); }
void SetBF(hsBool b, DatBit bitChoice) { fBitVector->SetBit(bitChoice, b); }
};
class plMaxNodeData
{
public:
plMaxNodeData() :
fpKey(nil),
fpSO(nil) ,
fDecalLevel(0),
fpMesh(nil),
fpRoomKey(nil),
fSoundIdxCounter( 0 ),
fAvatarSO(nil),
fFade(Point3(0,0,0), Point3(0,0,0)),
fNormalChan(0),
fWaterHeight(0),
fGDMaxFaces(0), fGDMaxSize(0), fGDMinFaces(0),
fSwapMesh(nil),
fSwapTargetID((uint32_t)-1),
fCachedAlphaHackLayerCounts(nil),
fBoneMap(nil),
fAnimCompression(1), // Should be plAnimCompressComp::kCompressionLow,
// but I don't want to include the entire header.
fKeyReduceThreshold(0.0002)
{ }
~plMaxNodeData()
{
fpKey = nil;
fpRoomKey = nil;
fpSO = 0;
fAvatarSO = nil;
delete fCachedAlphaHackLayerCounts;
MaxDatBF.DeInit();
}
// Call init on MaxNodeData whose constructor was never called, e.g. if it was malloc'd.
plMaxNodeData& Init()
{
memset( &fpKey, 0, sizeof( plKey ) );
memset( &fpRoomKey, 0, sizeof( plKey ) );
fRenderDependencies.Init();
fBones.Init();
fCachedAlphaHackLayerCounts = nil;
MaxDatBF.Init();
return *this;
}
// Ditto
void DeInit( void )
{
fpKey = nil;
fpRoomKey = nil;
fpSO = 0; fAvatarSO = nil;
delete fCachedAlphaHackLayerCounts;
fCachedAlphaHackLayerCounts = nil;
MaxDatBF.DeInit();
}
plKey GetKey() { return fpKey; }
void SetKey(plKey p ) { fpKey = p; }
plSceneObject * GetSceneObject() { return fpSO; }
void SetSceneObject(plSceneObject *p) { fpSO = p; }
hsBool CanConvert() { return MaxDatBF.CanBF(MaxDatBF.kCanConvert); }
void SetCanConvert(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kCanConvert); }
hsBool GetForceLocal() { return MaxDatBF.CanBF(MaxDatBF.kForceLocal); }
void SetForceLocal(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceLocal); }
void * GetMesh() { return fpMesh; } // void pointer for header simplicity
void SetMesh(hsGMesh *p) { fpMesh = p; }
hsBool GetDrawable() {return MaxDatBF.CanBF(MaxDatBF.kDrawable); }
void SetDrawable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDrawable); }
hsBool GetPhysical() {return MaxDatBF.CanBF(MaxDatBF.kPhysical); }
void SetPhysical(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kPhysical); }
hsBool GetRunTimeLight() {return MaxDatBF.CanBF(MaxDatBF.kRunTimeLight); }
void SetRunTimeLight(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kRunTimeLight); }
hsBool GetForceMatShade() {return MaxDatBF.CanBF(MaxDatBF.kForceMatShade); }
void SetForceMatShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceMatShade); }
hsBool GetForceVisLOS() {return MaxDatBF.CanBF(MaxDatBF.kForceVisLOS); }
void SetForceVisLOS(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceVisLOS); }
hsBool GetEnviron() {return MaxDatBF.CanBF(MaxDatBF.kEnviron); }
void SetEnviron(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kEnviron); }
hsBool GetEnvironOnly() {return MaxDatBF.CanBF(MaxDatBF.kEnvironOnly); }
void SetEnvironOnly(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kEnvironOnly); }
hsBool GetWaterDecEnv() { return MaxDatBF.CanBF(MaxDatBF.kWaterDecEnv); }
void SetWaterDecEnv(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kWaterDecEnv); }
hsBool GetItinerant() {return MaxDatBF.CanBF(MaxDatBF.kItinerant); }
void SetItinerant(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kItinerant); }
hsBool GetUnBounded() {return MaxDatBF.CanBF(MaxDatBF.kUnBounded); }
void SetUnBounded(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kUnBounded); }
hsBool GetDisableNormal() {return MaxDatBF.CanBF(MaxDatBF.kDisableNormal); }
void SetDisableNormal(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDisableNormal); }
hsBool GetMovable() {return MaxDatBF.CanBF(MaxDatBF.kMovable); }
void SetMovable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kMovable); }
hsBool GetNoPreShade() {return MaxDatBF.CanBF(MaxDatBF.kNoPreShade); }
void SetNoPreShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoPreShade); }
hsBool GetForcePreShade() {return MaxDatBF.CanBF(MaxDatBF.kForcePreShade); }
void SetForcePreShade(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForcePreShade); }
hsBool GetNoShadow() {return MaxDatBF.CanBF(MaxDatBF.kNoShadow); }
void SetNoShadow(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoShadow); }
hsBool GetForceShadow() {return MaxDatBF.CanBF(MaxDatBF.kForceShadow); }
void SetForceShadow(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceShadow); }
hsBool GetAlphaTestHigh() {return MaxDatBF.CanBF(MaxDatBF.kAlphaTestHigh); }
void SetAlphaTestHigh(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kAlphaTestHigh); }
hsBool GetFilterInherit() {return MaxDatBF.CanBF(MaxDatBF.kFilterInherit); }
void SetFilterInherit(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kFilterInherit); }
hsBool GetIsBarney() {return MaxDatBF.CanBF(MaxDatBF.kIsBarney); }
void SetIsBarney(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsBarney); }
hsBool GetNoSpanSort() {return MaxDatBF.CanBF(MaxDatBF.kNoSpanSort); }
void SetNoSpanSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoSpanSort); }
hsBool GetNoSpanReSort() {return MaxDatBF.CanBF(MaxDatBF.kNoSpanReSort); }
void SetNoSpanReSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoSpanReSort); }
hsBool GetNoFaceSort() {return MaxDatBF.CanBF(MaxDatBF.kNoFaceSort); }
void SetNoFaceSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoFaceSort); }
hsBool GetReverseSort() {return MaxDatBF.CanBF(MaxDatBF.kReverseSort); }
void SetReverseSort(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kReverseSort); }
hsBool GetSortAsOpaque() {return MaxDatBF.CanBF(MaxDatBF.kSortAsOpaque); }
void SetSortAsOpaque(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kSortAsOpaque); }
hsBool GetVS() {return MaxDatBF.CanBF(MaxDatBF.kVS); }
void SetVS(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kVS); }
hsBool GetHasWaterHeight() { return MaxDatBF.CanBF(MaxDatBF.kWaterHeight); }
void SetHasWaterHeight(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kWaterHeight); }
float GetWaterHeight() { return fWaterHeight; }
void SetWaterHeight(float f) { SetHasWaterHeight(true); fWaterHeight = f; }
hsBool GetSmoothAll() {return MaxDatBF.CanBF(MaxDatBF.kSmoothAll); }
void SetSmoothAll(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kSmoothAll); }
hsBool GetForceSortable() {return MaxDatBF.CanBF(MaxDatBF.kForceSortable); }
void SetForceSortable(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceSortable); }
hsBool GetConcave() {return MaxDatBF.CanBF(MaxDatBF.kConcave); }
void SetConcave(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kConcave); }
hsBool GetCalcEdgeLens() {return MaxDatBF.CanBF(MaxDatBF.kCalcEdgeLens); }
void SetCalcEdgeLens(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kCalcEdgeLens); }
hsBool GetNoDeferDraw() {return MaxDatBF.CanBF(MaxDatBF.kNoDeferDraw); }
void SetNoDeferDraw(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kNoDeferDraw); }
hsBool GetBlendToFB() {return MaxDatBF.CanBF(MaxDatBF.kBlendToFB); }
void SetBlendToFB(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kBlendToFB); }
hsBool GetForceMaterialCopy() {return MaxDatBF.CanBF(MaxDatBF.kForceMatCopy); }
void SetForceMaterialCopy(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kForceMatCopy); }
hsBool GetInstanced() {return MaxDatBF.CanBF(MaxDatBF.kIsInstanced); }
void SetInstanced(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsInstanced); }
hsBool GetParticleRelated() {return MaxDatBF.CanBF(MaxDatBF.kParticleRelated); }
void SetParticleRelated(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kParticleRelated); }
hsBool GetDup2Sided() {return MaxDatBF.CanBF(MaxDatBF.kDup2Sided); }
void SetDup2Sided(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kDup2Sided); }
hsBool GetRadiateNorms() {return MaxDatBF.CanBF(MaxDatBF.kRadiateNorms); }
void SetRadiateNorms(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kRadiateNorms); }
hsBool GetGeoDice() {return MaxDatBF.CanBF(MaxDatBF.kGeoDice); }
void SetGeoDice(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kGeoDice); }
hsBool GetIsGUI() {return MaxDatBF.CanBF(MaxDatBF.kIsGUI); }
void SetIsGUI(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kIsGUI); }
plSharedMesh* GetSwappableGeom() { return fSwapMesh;}
void SetSwappableGeom(plSharedMesh *sm) { fSwapMesh = sm; }
uint32_t GetSwappableGeomTarget() { return fSwapTargetID;}
void SetSwappableGeomTarget(uint32_t id) { fSwapTargetID = id;}
plMaxBoneMap* GetBoneMap() { return fBoneMap;}
void SetBoneMap(plMaxBoneMap *bones) { fBoneMap = bones;}
int GetGeoDiceMaxFaces() { return fGDMaxFaces; }
void SetGeoDiceMaxFaces(int f) { fGDMaxFaces = f; }
float GetGeoDiceMaxSize() { return fGDMaxSize; }
void SetGeoDiceMaxSize(float f) { fGDMaxSize = f; }
int GetGeoDiceMinFaces() { return fGDMinFaces; }
void SetGeoDiceMinFaces(int f) { fGDMinFaces = f; }
plKey GetRoomKey() { return fpRoomKey; }
void SetRoomKey(plKey p) { fpRoomKey = p; }
uint32_t GetDecalLevel() { return fDecalLevel; }
void SetDecalLevel(uint32_t i) { fDecalLevel = i; }
uint32_t GetSoundIdxCounter() { return fSoundIdxCounter; }
void SetSoundIdxCounter( uint32_t i ) { fSoundIdxCounter = i; }
plSceneObject * GetAvatarSO() { return fAvatarSO; }
void SetAvatarSO(plSceneObject *so) { fAvatarSO = so; }
int NumRenderDependencies() { return fRenderDependencies.Count(); }
plMaxNodeBase* GetRenderDependency(int i) { return fRenderDependencies[i]; }
void AddRenderDependency(plMaxNodeBase* m) { fRenderDependencies.Append(1, &m); }
void ClearRenderDependencies() { fRenderDependencies.ZeroCount(); }
int NumBones() { return fBones.Count(); }
plMaxNodeBase* GetBone(int i) { return fBones[i]; }
void AddBone(plMaxNodeBase* m) { fBones.Append(1, &m); }
void ClearBones() { fBones.ZeroCount(); }
hsBool HasFade() { return MaxDatBF.CanBF(MaxDatBF.kHasFade); }
void SetFade(const Box3& b) { MaxDatBF.SetBF((b.Min()[2] != 0)||(b.Max()[2] != 0), MaxDatBF.kHasFade); fFade = b; }
Box3 GetFade() { return fFade; }
hsBool HasLoadMask() { return MaxDatBF.CanBF(MaxDatBF.kHasLoadMask); }
plLoadMask GetLoadMask() { return HasLoadMask() ? fLoadMask : plLoadMask::kAlways; }
void AddLoadMask(const plLoadMask& m) { if( !HasLoadMask() ) { fLoadMask = m; MaxDatBF.SetBF(true, MaxDatBF.kHasLoadMask); }else{ fLoadMask |= m; } }
hsBool HasNormalChan() { return fNormalChan > 0; }
void SetNormalChan(int n) { fNormalChan = n; }
int GetNormalChan() { return fNormalChan; }
hsBool BlendLevelSet() { return MaxDatBF.CanBF(MaxDatBF.kBLevelSet); }
void SetBlendLevel(const plRenderLevel& l) { fBlendLevel = l; MaxDatBF.SetBF(true, MaxDatBF.kBLevelSet); }
const plRenderLevel& GetBlendLevel() { return fBlendLevel; }
hsBool OpaqueLevelSet() { return MaxDatBF.CanBF(MaxDatBF.kOLevelSet); }
void SetOpaqueLevel(const plRenderLevel& l) { fOpaqueLevel = l; MaxDatBF.SetBF(true, MaxDatBF.kOLevelSet); }
const plRenderLevel& GetOpaqueLevel() { return fOpaqueLevel; }
plPhysicalProps* GetPhysicalProps() { return &fPhysicalProps; }
hsTArray *GetAlphaHackLayersCache( void ) { return fCachedAlphaHackLayerCounts; }
void SetAlphaHackLayersCache( hsTArray *cache ) { fCachedAlphaHackLayerCounts = cache; }
hsBool GetOverrideHighLevelSDL() { return MaxDatBF.CanBF(MaxDatBF.kOverrideHighLevelSDL); }
void SetOverrideHighLevelSDL(hsBool b) { MaxDatBF.SetBF(b, MaxDatBF.kOverrideHighLevelSDL); }
uint8_t GetAnimCompress() { return fAnimCompression; }
void SetAnimCompress(uint8_t v) { fAnimCompression = v; }
float GetKeyReduceThreshold() { return fKeyReduceThreshold; }
void SetKeyReduceThreshold(float v) { fKeyReduceThreshold = v; }
protected:
plKey fpKey;
plSceneObject * fpSO;
// hacking this in here temporarily because everything's about to change in the mesh world...
hsGMesh* fpMesh;
plKey fpRoomKey;
uint32_t fDecalLevel;
int32_t fNormalChan;
uint32_t fSoundIdxCounter;
plSceneObject * fAvatarSO;
plMaxNodeBaseTab fRenderDependencies;
plMaxNodeBaseTab fBones;
Box3 fFade;
int fGDMaxFaces;
float fGDMaxSize;
int fGDMinFaces;
plRenderLevel fBlendLevel;
plRenderLevel fOpaqueLevel;
plPhysicalProps fPhysicalProps;
uint32_t fSwapTargetID;
hsTArray *fCachedAlphaHackLayerCounts;
plSharedMesh *fSwapMesh;
plMaxBoneMap *fBoneMap;
plLoadMask fLoadMask;
float fWaterHeight;
uint8_t fAnimCompression;
float fKeyReduceThreshold;
DataBF MaxDatBF;
};
#endif // plSimpleConvert_inc