You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

261 lines
12 KiB

/*==LICENSE==*
CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011 Cyan Worlds, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional permissions under GNU GPL version 3 section 7
If you modify this Program, or any covered work, by linking or
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
(or a modified version of those libraries),
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
licensors of this Program grant you additional
permission to convey the resulting work. Corresponding Source for a
non-source form of such a combination shall include the source code for
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
work.
You can contact Cyan Worlds, Inc. by email legal@cyan.com
or by snail mail at:
Cyan Worlds, Inc.
14617 N Newport Hwy
Mead, WA 99021
*==LICENSE==*/
#ifndef plMaxNode_inc
#define plMaxNode_inc
#include "plMaxNodeBase.h"
#include "hsTemplates.h"
#include "hsMatrix44.h"
#include "iparamb2.h"
#include "pnKeyedObject/plKey.h"
#include <map>
class plMaxNode;
class plErrorMsg;
class plConvertSettings;
class plExportProgressBar;
class plSceneNode;
class plDrawable;
class plDrawInterface;
class plDrawableSpans;
class plLightInfo;
class plSpotLightInfo;
class plOmniLightInfo;
class plGeometrySpan;
class ISkin;
class plSpotModifier;
class plOmniModifier;
class plLtdDirModifier;
class plLightModifier;
class plController;
class plAGModifier;
class plAGMasterMod;
class plAGAnim;
class plRenderLevel;
class plDrawableCriteria;
class plXImposterComp;
class plPhysicalProps;
class plLightMapComponent;
class plPageInfoComponent;
class plMaxBoneMap;
class plSynchedObject;
typedef bool (plMaxNode:: *PMaxNodeFunc) (plErrorMsg *, plConvertSettings *); // Function pointer to a plMaxNode member funtion
class plMaxNodeTab : public Tab<plMaxNode*>
{
};
//-------------------------------------------
// plMaxNode
//-------------------------------------------
// CAREFUL! This class is different, it is derived from Max's INode (as you can see)
// But we can only add (NON Virtual) functions to plMaxNode directly
// If you want some new Data members, you can add them by adding to the class
// plMaxNodeData This data is stored in each INode through some mechanisms supplied
// It would be nice of you to add GetFunctions for each new data member you add (see below)
//--------------------------------------------
// NOTE: an INode can be cast to a plMaxNode, but currently it is the MakeSceneObject Pass which
// Adds the plMaxNodeData to the Node
class plMaxNode : public plMaxNodeBase
{
public:
bool DoRecur(PMaxNodeFunc p,plErrorMsg *, plConvertSettings *, plExportProgressBar*);
bool DoAllRecur(PMaxNodeFunc p,plErrorMsg *, plConvertSettings *, plExportProgressBar*);
// DoRecur takes one of the following functions
bool ConvertValidate (plErrorMsg *, plConvertSettings *);
bool SetupPropertiesPass (plErrorMsg *, plConvertSettings *);
bool MakeSceneObject (plErrorMsg *, plConvertSettings *);
bool PrepareSkin (plErrorMsg *, plConvertSettings *);
bool MakePhysical (plErrorMsg *, plConvertSettings *);
bool FirstComponentPass (plErrorMsg *, plConvertSettings *);
bool MakeController (plErrorMsg *, plConvertSettings *);
bool MakeCoordinateInterface (plErrorMsg *, plConvertSettings *);
bool MakeModifiers (plErrorMsg *, plConvertSettings *);
bool MakeParentOrRoomConnection (plErrorMsg *, plConvertSettings *);
bool MakeMesh (plErrorMsg *, plConvertSettings *);
bool MakeLight (plErrorMsg *, plConvertSettings *);
bool MakeOccluder (plErrorMsg *, plConvertSettings *);
bool ConvertComponents (plErrorMsg *, plConvertSettings *);
bool ClearData (plErrorMsg *, plConvertSettings *);
bool ShadeMesh (plErrorMsg *, plConvertSettings *);
bool MakeIfaceReferences (plErrorMsg *, plConvertSettings *);
bool ClearMaxNodeData (plErrorMsg *, plConvertSettings *);
bool DeInitComponents (plErrorMsg *, plConvertSettings *);
// Does specified function for all components attached to this node
enum { kSetupProperties, kPreConvert, kConvert };
bool DoComponents(int convertType, plErrorMsg *, plConvertSettings *);
plKey AddModifier(plModifier *pMod, const plString& name);
bool ConvertToOccluder (plErrorMsg* pErrMsg, bool twoSided, bool isHole);
plDrawableCriteria GetDrawableCriteria(bool needBlending, bool needSorting);
Point3 GetFlexibility(); // returns Point3(flexibility, interRand, intraRand).
plXImposterComp* GetXImposterComp();
int AlphaHackLayersNeeded(int iSubMtl);
int NumUVWChannels();
bool VtxAlphaNotAvailable();
bool NonVtxPreshaded();
TriObject* GetTriObject(bool& deleteIt);
plAGModifier* HasAGMod();
plAGMasterMod* GetAGMasterMod();
plMaxNode* GetBonesRoot(); // Returns the root of my bones hierarchy, if I have any bones, else nil.
void GetBonesRootsRecur(hsTArray<plMaxNode*>& list);
plSceneObject* MakeCharacterHierarchy(plErrorMsg *pErrMsg);
void SetupBonesAliasesRecur(const char *rootName);
void SetupBoneHierarchyPalette(plMaxBoneMap *bones = nil);
void SetDISceneNodeSpans( plDrawInterface *di, bool needBlending );
bool IsLegalDecal(bool checkParent = true);
bool IsAnimatedLight();
// These are public so the animation component can use them, no one else should need them
void GetRTLightColAnim(IParamBlock2* ProperPB, plAGAnim* anim);
void GetRTConeAnim(IParamBlock2* ProperPB, plAGAnim* anim);
void GetRTLightAttenAnim(IParamBlock2* ProperPB, plAGAnim* anim);
// This is used in the shading pass, where the lightmap component can
// serve as a cache for some shading info. Returns nil if there is no LightMapComponent on this.
plLightMapComponent* GetLightMapComponent();
// Starting at 0, returns an incrementing index for each maxNode. Useful for assigning
// indices to sound objects attached to the node
uint32_t GetNextSoundIdx( void );
bool IsPhysical( void );
bool CanMakeMesh( Object *obj, plErrorMsg *pErrMsg, plConvertSettings *settings );
plDrawInterface* GetDrawInterface(); // Returns nil if there isn't a sceneobject and a drawinterface.
// Only call during convert
plPhysicalProps *GetPhysicalProps();
// Little helper function. Calls FindKey() in the resManager using the location (page) of this node
plKey FindPageKey( uint16_t classIdx, const plString &name );
const char *GetAgeName();
void CheckSynchOptions(plSynchedObject* so);
protected:
INode *GetRootNode() { return GetInterface()->GetRootNode(); }
plDrawableSpans *IGetSceneNodeSpans( plSceneNode *node, bool needBlending, bool needSorting=true );
plLightInfo* IMakeDirectional(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeOmni(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeSpot(plErrorMsg* pErrMsg, plConvertSettings* settings);
bool IGetProjection(plLightInfo* li, plErrorMsg* pErrMsg);
plLightInfo* IMakeRTDirectional(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTOmni(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTSpot(plErrorMsg* pErrMsg, plConvertSettings* settings);
plLightInfo* IMakeRTProjDirectional( plErrorMsg *pErrMsg, plConvertSettings *settings );
void IGetCone(plSpotLightInfo* liInfo, LightObject* light, LightState& ls);
void IGetLightColors(plLightInfo* liInfo, LightObject* light, LightState& ls);
void IGetLightAttenuation(plOmniLightInfo* liInfo, LightObject* light, LightState& ls);
// RunTime Lights versions
void IGetRTCone(plSpotLightInfo* liInfo, IParamBlock2* ProperPB);
void IGetRTLightColors(plLightInfo* liInfo, IParamBlock2* ProperPB);
void IGetRTLightAttenuation(plOmniLightInfo* liInfo, IParamBlock2* ProperPB);
// RunTime Light animation builders
bool IGetRTLightAttenValues(IParamBlock2* ProperPB, float& attenConst, float& attenLinear, float& attenQuadratic,float &attenCutoff);
void IAdjustRTColorByIntensity(plController* ctl, IParamBlock2* ProperPB);
bool IAttachRTLightModifier(plLightModifier* liMod);
plLightInfo* IMakeLight(plErrorMsg *pErrMsg, plConvertSettings *settings);
plSceneNode* IGetDrawableSceneNode(plErrorMsg *pErrMsg);
void IAssignSpansToDrawables( hsTArray<plGeometrySpan *> &spanArray, plDrawInterface *di,
plErrorMsg *pErrMsg, plConvertSettings *settings );
void IAssignSpan( plDrawableSpans *drawable, hsTArray<plGeometrySpan *> &spanArray, uint32_t &index,
hsMatrix44 &l2w, hsMatrix44 &w2l,
plErrorMsg *pErrMsg, plConvertSettings *settings );
void ISetupBones( plDrawableSpans *drawable, hsTArray<plGeometrySpan *> &spanArray,
hsMatrix44 &l2w, hsMatrix44 &w2l,
plErrorMsg *pErrMsg, plConvertSettings *settings );
bool IFindBones(plErrorMsg *pErrMsg, plConvertSettings *settings);
void IWipeBranchDrawable(bool b);
uint32_t IBuildInstanceList( Object *obj, TimeValue t, hsTArray<plMaxNode *> &nodes, bool beMoreAccurate = false );
bool IMakeInstanceSpans( plMaxNode *node, hsTArray<plGeometrySpan *> &spanArray,
plErrorMsg *pErrMsg, plConvertSettings *settings );
bool IMaterialsMatch( plMaxNode *otherNode, bool beMoreAccurate );
int IGetCachedAlphaHackValue( int iSubMtl );
void ISetCachedAlphaHackValue( int iSubMtl, int value );
friend class plLocationDlg;
};
class plMaxBoneMap
{
protected:
typedef std::map<plMaxNodeBase*, uint32_t> BoneMap;
BoneMap fBones;
typedef std::map<plDrawable*, uint32_t> DrawableMap;
DrawableMap fBaseMatrices;
public:
uint8_t fNumBones;
plMaxNodeBase *fOwner; // Make note of which node created us, so they can delete us.
plMaxBoneMap() : fNumBones(0), fOwner(nil) {}
void AddBone(plMaxNodeBase *bone);
uint8_t GetIndex(plMaxNodeBase *bone);
void FillBoneArray(plMaxNodeBase **boneArray);
uint32_t GetBaseMatrixIndex(plDrawable *draw);
void SetBaseMatrixIndex(plDrawable *draw, uint32_t idx);
void SortBones();
};
#endif