|
|
|
/*==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 __HSMATERIALCONVERTER_H
|
|
|
|
#define __HSMATERIALCONVERTER_H
|
|
|
|
|
|
|
|
#include "HeadSpin.h"
|
|
|
|
#include "hsTemplates.h"
|
|
|
|
|
|
|
|
#include "Max.h"
|
|
|
|
|
|
|
|
class Interface;
|
|
|
|
|
|
|
|
class hsStream;
|
|
|
|
class hsScene;
|
|
|
|
class hsGMaterial;
|
|
|
|
class plLayer;
|
|
|
|
class plLayerInterface;
|
|
|
|
class hsGBitmapClass;
|
|
|
|
class hsGQTLayer;
|
|
|
|
class hsGAVILayer;
|
|
|
|
class hsGBinkLayer;
|
|
|
|
class hsConverterUtils;
|
|
|
|
class hsGAnimLayer;
|
|
|
|
class plBitmap;
|
|
|
|
class plMipmap;
|
|
|
|
class plErrorMsg;
|
|
|
|
|
|
|
|
class Mtl;
|
|
|
|
class Texmap;
|
|
|
|
class plMaxNode;
|
|
|
|
class StdUVGen;
|
|
|
|
class BitmapTex;
|
|
|
|
class StdMat;
|
|
|
|
class TSTR;
|
|
|
|
class Animatable;
|
|
|
|
class Bitmap;
|
|
|
|
class plLocation;
|
|
|
|
|
|
|
|
class plLayerTex;
|
|
|
|
class plBitmapData;
|
|
|
|
class plCubicRenderTarget;
|
|
|
|
class plStaticEnvLayer;
|
|
|
|
class plDynamicEnvLayer;
|
|
|
|
class plDynamicTextLayer;
|
|
|
|
class plPassMtlBase;
|
|
|
|
class plClothingItem;
|
|
|
|
class plClothingMtl;
|
|
|
|
class hsBitVector;
|
|
|
|
|
|
|
|
class plExportMaterialData
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
UInt32 fNumBlendChannels;
|
|
|
|
hsGMaterial *fMaterial;
|
|
|
|
};
|
|
|
|
|
|
|
|
class hsMaterialConverter
|
|
|
|
{
|
|
|
|
private:
|
|
|
|
hsMaterialConverter();
|
|
|
|
|
|
|
|
public:
|
|
|
|
~hsMaterialConverter();
|
|
|
|
static hsMaterialConverter& Instance();
|
|
|
|
|
|
|
|
void Init(hsBool save, plErrorMsg *msg);
|
|
|
|
|
|
|
|
void FreeMaterialCache(const char* path);
|
|
|
|
|
|
|
|
static void GetUsedMaterials(plMaxNode* node, hsBitVector& used);
|
|
|
|
static hsBool IsTwoSided(Mtl* m, int iFace);
|
|
|
|
static hsBool PreserveUVOffset(Mtl* m);
|
|
|
|
static hsBool IsMultiMat(Mtl *m);
|
|
|
|
static hsBool IsMultipassMat(Mtl *m);
|
|
|
|
static hsBool IsHsMaxMat(Mtl *m);
|
|
|
|
static hsBool IsDecalMat(Mtl *m);
|
|
|
|
static hsBool IsCompositeMat(Mtl *m);
|
|
|
|
static hsBool IsParticleMat(Mtl *m);
|
|
|
|
static hsBool IsHsEnvironMapMat(Mtl *m);
|
|
|
|
static hsBool IsClothingMat(Mtl *m);
|
|
|
|
// static hsBool IsPortalMat(Mtl *m);
|
|
|
|
static hsBool HasAnimatedTextures(Texmap* texMap);
|
|
|
|
static hsBool HasAnimatedMaterial(plMaxNode* node);
|
|
|
|
static hsBool IsAnimatedMaterial(Mtl* mtl);
|
|
|
|
static hsBool HasMaterialDiffuseOrOpacityAnimation(plMaxNode* node, Mtl* mtl=nil);
|
|
|
|
static hsBool HasEmissiveLayer(plMaxNode* node, Mtl* mtl=nil);
|
|
|
|
static hsBool IsWaterLayer(plMaxNode* node, Texmap* texMap);
|
|
|
|
static hsBool IsFireLayer(plMaxNode* node, Texmap* texMap);
|
|
|
|
static hsBool IsAVILayer(Texmap* texMap);
|
|
|
|
static hsBool IsQTLayer(Texmap* texMap);
|
|
|
|
static hsBool IsBinkLayer(Texmap* texMap);
|
|
|
|
// static hsBool IsEnvironMapped(plMaxNode *node);
|
|
|
|
// static hsBool IsPortal(plMaxNode* node);
|
|
|
|
static hsBool ForceNoUvsFlatten(plMaxNode* node);
|
|
|
|
// static hsBool IsRenderProc(Mtl* mtl);
|
|
|
|
static Mtl* GetBaseMtl(Mtl* mtl);
|
|
|
|
static Mtl* GetBaseMtl(plMaxNode* node);
|
|
|
|
static int GetCoordMapping(StdUVGen *uvgen);
|
|
|
|
static void GetNodesByMaterial(Mtl *mtl, hsTArray<plMaxNode*> &out);
|
|
|
|
|
|
|
|
static UInt32 VertexChannelsRequestMask(plMaxNode* node, int iSubMtl, Mtl* mtl);
|
|
|
|
static UInt32 VertexChannelsRequiredMask(plMaxNode* node, int iSubMtl);
|
|
|
|
static int NumVertexOpacityChannelsRequired(plMaxNode* node, int iSubMtl);
|
|
|
|
static UInt32 ColorChannelsUseMask(plMaxNode* node, int iSubMtl);
|
|
|
|
static int MaxUsedUVWSrc(plMaxNode* node, Mtl* mtl);
|
|
|
|
|
|
|
|
|
|
|
|
static hsBool IsBumpLayer(Texmap* texMap);
|
|
|
|
static hsBool IsBumpMtl(Mtl* mtl);
|
|
|
|
static hsBool HasBumpLayer(plMaxNode* node, Mtl* mtl);
|
|
|
|
static BitmapTex* GetBumpLayer(plMaxNode* node, Mtl* mtl);
|
|
|
|
|
|
|
|
static hsBool HasVisDists(plMaxNode* node, Mtl* subMtl, hsScalar& minDist, hsScalar& maxDist);
|
|
|
|
static hsBool HasVisDists(plMaxNode* node, int iSubMtl, hsScalar& minDist, hsScalar& maxDist);
|
|
|
|
|
|
|
|
static hsBool IMustBeUniqueMaterial( Mtl *mtl );
|
|
|
|
static hsBool IMustBeUniqueLayer( Texmap *layer );
|
|
|
|
|
|
|
|
static Mtl* FindSubMtlByName(TSTR& name, Animatable* anim);
|
|
|
|
Mtl* FindSceneMtlByName(TSTR& name);
|
|
|
|
|
|
|
|
hsTArray<plExportMaterialData> *CreateMaterialArray(Mtl *maxMaterial, plMaxNode *node, UInt32 multiIndex);
|
|
|
|
|
|
|
|
// true if last material creation changed MAX time, invalidating current mesh
|
|
|
|
hsBool ChangedTimes() { return fChangedTimes; }
|
|
|
|
|
|
|
|
Texmap *GetUVChannelBase(plMaxNode *node, Mtl* mtl, int which);
|
|
|
|
|
|
|
|
hsBool ClearDoneMaterials(plMaxNode* node);
|
|
|
|
|
|
|
|
int GetMaterialArray(Mtl *mtl, plMaxNode* node, hsTArray<hsGMaterial*>& out, UInt32 multiIndex = 0 );
|
|
|
|
int GetMaterialArray(Mtl *mtl, hsTArray<hsGMaterial*>& out, UInt32 multiIndex = 0);
|
|
|
|
void CollectConvertedMaterials(Mtl *mtl, hsTArray<hsGMaterial *> &out);
|
|
|
|
|
|
|
|
plClothingItem *GenerateClothingItem(plClothingMtl *mtl, const plLocation &loc);
|
|
|
|
hsGMaterial* AlphaHackVersion(plMaxNode* node, Mtl* mtl, int subIndex); // used by DynamicDecals
|
|
|
|
hsGMaterial* NonAlphaHackVersion(plMaxNode* node, Mtl* mtl, int subIndex);
|
|
|
|
hsGMaterial* AlphaHackPrint(plMaxNode* node, Texmap* baseTex, UInt32 blendFlags);
|
|
|
|
hsGMaterial* NonAlphaHackPrint(plMaxNode* node, Texmap* baseTex, UInt32 blendFlags);
|
|
|
|
|
|
|
|
plMipmap* GetStaticColorTexture(Color c, plLocation &loc); // Creates a 4x4 texture of the specified solid color;
|
|
|
|
|
|
|
|
enum {
|
|
|
|
kColorRedBlack = 0x1,
|
|
|
|
kColorRedGrey = 0x2,
|
|
|
|
kColorRedWhite = 0x4,
|
|
|
|
kColorRed = kColorRedBlack | kColorRedGrey | kColorRedWhite,
|
|
|
|
|
|
|
|
kColorGreenBlack = 0x8,
|
|
|
|
kColorGreenGrey = 0x10,
|
|
|
|
kColorGreenWhite = 0x20,
|
|
|
|
kColorGreen = kColorGreenBlack | kColorGreenGrey | kColorGreenWhite,
|
|
|
|
|
|
|
|
kColorBlueBlack = 0x40,
|
|
|
|
kColorBlueGrey = 0x80,
|
|
|
|
kColorBlueWhite = 0x100,
|
|
|
|
kColorBlue = kColorBlueBlack | kColorBlueGrey | kColorBlueWhite,
|
|
|
|
|
|
|
|
kColor = kColorRed | kColorGreen | kColorBlue,
|
|
|
|
|
|
|
|
kIllumRedBlack = 0x200,
|
|
|
|
kIllumRedGrey = 0x400,
|
|
|
|
kIllumRedWhite = 0x800,
|
|
|
|
kIllumRed = kIllumRedBlack | kIllumRedGrey | kIllumRedWhite,
|
|
|
|
|
|
|
|
kIllumGreenBlack = 0x1000,
|
|
|
|
kIllumGreenGrey = 0x2000,
|
|
|
|
kIllumGreenWhite = 0x4000,
|
|
|
|
kIllumGreen = kIllumGreenBlack | kIllumGreenGrey | kIllumGreenWhite,
|
|
|
|
|
|
|
|
kIllumBlueBlack = 0x8000,
|
|
|
|
kIllumBlueGrey = 0x10000,
|
|
|
|
kIllumBlueWhite = 0x20000,
|
|
|
|
kIllumBlue = kIllumBlueBlack | kIllumBlueGrey | kIllumBlueWhite,
|
|
|
|
|
|
|
|
kIllum = kIllumRed | kIllumGreen | kIllumBlue,
|
|
|
|
|
|
|
|
kAlphaBlack = 0x40000,
|
|
|
|
kAlphaGrey = 0x80000,
|
|
|
|
kAlphaWhite = 0x100000,
|
|
|
|
kAlpha = kAlphaBlack | kAlphaGrey | kAlphaWhite,
|
|
|
|
|
|
|
|
kAllChannels = kColor | kIllum | kAlpha // Adjust if more channels added.
|
|
|
|
};
|
|
|
|
|
|
|
|
// All this to catch duplicate mats with same name. Sigh.
|
|
|
|
struct DoneMaterialData
|
|
|
|
{
|
|
|
|
DoneMaterialData() : fHsMaterial(nil), fMaxMaterial(nil), fNode(nil),
|
|
|
|
fSubMultiMat(false), fOwnedCopy(false) { }
|
|
|
|
|
|
|
|
hsGMaterial *fHsMaterial;
|
|
|
|
Mtl *fMaxMaterial;
|
|
|
|
plMaxNode *fNode;
|
|
|
|
hsBool fSubMultiMat;
|
|
|
|
hsBool fOwnedCopy;
|
|
|
|
hsBool fRuntimeLit;
|
|
|
|
UInt32 fSubMtlFlags;
|
|
|
|
int fNumUVChannels;
|
|
|
|
hsBool fMakeAlphaLayer;
|
|
|
|
};
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum {
|
|
|
|
kWarnedNoMoreDub = 0x1,
|
|
|
|
kWarnedNoMoreMult = 0x2,
|
|
|
|
kWarnedNoMoreBitmapLoadErr = 0x4,
|
|
|
|
kWarnedSubMulti = 0x8,
|
|
|
|
kWarnedCompMtlBadBlend = 0x10,
|
|
|
|
kWarnedNoLayers = 0x20,
|
|
|
|
kWarnedTooManyUVs = 0x40,
|
|
|
|
kWarnedAlphaAddCombo = 0x80,
|
|
|
|
kWarnedNoBaseTexture = 0x100,
|
|
|
|
kWarnedNoUpperTexture = 0x200,
|
|
|
|
kWarnedUpperTextureMissing = 0x400,
|
|
|
|
kWarnedMissingClothingTexture = 0x800,
|
|
|
|
kWarnedBadAnimSDLVarName = 0x1000,
|
|
|
|
};
|
|
|
|
|
|
|
|
DoneMaterialData* IFindDoneMaterial(DoneMaterialData& done);
|
|
|
|
hsBool IClearDoneMaterial(Mtl* mtl, plMaxNode* node);
|
|
|
|
|
|
|
|
hsGMaterial *IAddDefaultMaterial(plMaxNode *node);
|
|
|
|
plMipmap *IGetUVTransTexture(plMaxNode *node, hsBool useU = true);
|
|
|
|
void IInsertSingleBlendLayer(plMipmap *texture, hsGMaterial *mat, plMaxNode *node,
|
|
|
|
int layerIdx, int UVChan);
|
|
|
|
|
|
|
|
hsGMaterial *ICreateMaterial(Mtl *mtl, plMaxNode *node, const char *name, int subIndex, int numUVChannels, hsBool makeAlphaLayer);
|
|
|
|
hsGMaterial *IProcessMaterial(Mtl *mtl, plMaxNode *node, const char *name, int UVChan, int subMtlFlags = 0);
|
|
|
|
|
|
|
|
// ... calls one of:
|
|
|
|
hsGMaterial *IProcessMultipassMtl(Mtl *mtl, plMaxNode *node, const char *name, int UVChan);
|
|
|
|
hsGMaterial *IProcessCompositeMtl(Mtl *mtl, plMaxNode *node, const char *name, int UVChan, int subMtlFlags);
|
|
|
|
hsGMaterial *IProcessParticleMtl(Mtl *mtl, plMaxNode *node, const char *name);
|
|
|
|
hsBool IProcessPlasmaMaterial(Mtl *mtl, plMaxNode *node, hsGMaterial *mat, const char* namePrefix);
|
|
|
|
|
|
|
|
hsGMaterial* IInsertDoneMaterial(Mtl *mtl, hsGMaterial *hMat, plMaxNode *node, hsBool isMultiMat,
|
|
|
|
hsBool forceCopy, hsBool runtimeLit, UInt32 subMtlFlags, int numUVChannels, hsBool makeAlphaLayer);
|
|
|
|
|
|
|
|
void IInsertBumpLayers(plMaxNode* node, hsGMaterial* mat, int bumpLayerIdx);
|
|
|
|
void IInsertBumpLayers(plMaxNode* node, hsGMaterial* mat);
|
|
|
|
plLayer* IMakeBumpLayer(plMaxNode* node, const char* nameBase, hsGMaterial* mat, UInt32 miscFlag);
|
|
|
|
plMipmap* IGetBumpLutTexture(plMaxNode* node);
|
|
|
|
|
|
|
|
hsBool IHasSubMtl(Mtl* base, Mtl* sub);
|
|
|
|
int IFindSubIndex(plMaxNode* node, Mtl* mtl);
|
|
|
|
|
|
|
|
// NOTE: each insert function potentially modifies the layers,
|
|
|
|
// so make sure you own the material copy before calling these
|
|
|
|
void IInsertAlphaBlendingLayers(Mtl *mtl, plMaxNode *node, hsGMaterial *mat, int UVChan,
|
|
|
|
hsBool makeAlphaLayer);
|
|
|
|
void IInsertMultipassBlendingLayers(Mtl *mtl, plMaxNode *node, hsGMaterial *mat, int UVChan,
|
|
|
|
hsBool makeAlphaLayer);
|
|
|
|
void IInsertCompBlendingLayers(Mtl *mtl, plMaxNode *node, hsGMaterial *mat, int subMtlFlags,
|
|
|
|
int UVChan, hsBool makeAlphaLayer);
|
|
|
|
|
|
|
|
|
|
|
|
void IAddLayerToMaterial(hsGMaterial *mat, plLayerInterface *layer);
|
|
|
|
#if 0 // Out for now...
|
|
|
|
void IInitAttrSurface(hsGLayer *hLay, StdMat *stdMtl, plMaxNode *node);
|
|
|
|
void IInitAttrTexture(plMaxNode *node, Mtl *mtl, hsGLayer* hLay, Texmap *texMap, char *nodeName);
|
|
|
|
void IInitAttrLayer(hsGLayer* hLay, Mtl *mtl, Texmap* layer, plMaxNode* node);
|
|
|
|
#endif
|
|
|
|
// ... and so forth
|
|
|
|
hsBool IUVGenHasDynamicScale(plMaxNode* node, StdUVGen *uvGen);
|
|
|
|
void IScaleLayerOpacity(plLayer* hLay, hsScalar scale);
|
|
|
|
|
|
|
|
hsGMaterial *ICheckForProjectedTexture(plMaxNode *node);
|
|
|
|
hsGMaterial *IWrapTextureInMaterial(Texmap *texMap, plMaxNode *node);
|
|
|
|
|
|
|
|
BMM_Color_64 ICubeSample(Bitmap *bitmap[6], double phi, double theta);
|
|
|
|
void IBuildSphereMap(Bitmap *bitmap[6], Bitmap *bm);
|
|
|
|
#if 0 // DEFER_ANIM_MAT
|
|
|
|
void IProcessAnimMaterial(BitmapTex *bitmapTex, hsGAnimLayer* at, UInt32 texFlags, UInt32 procFlags);
|
|
|
|
#endif // DEFER_ANIM_MAT
|
|
|
|
static hsBool ITextureTransformIsAnimated(Texmap *texmap);
|
|
|
|
static hsBool IHasAnimatedControllers(Animatable* anim);
|
|
|
|
static hsBool IIsAnimatedTexmap(Texmap* texmap);
|
|
|
|
|
|
|
|
static UInt32 ICheckPoints(const Point3& p0, const Point3& p1, const Point3& p2, const Point3& p3,
|
|
|
|
int chan,
|
|
|
|
UInt32 mBlack, UInt32 mGrey, UInt32 mWhite);
|
|
|
|
static UInt32 ICheckPoints(const Point3& p0, const Point3& p1, const Point3& p2,
|
|
|
|
int chan,
|
|
|
|
UInt32 mBlack, UInt32 mGrey, UInt32 mWhite);
|
|
|
|
|
|
|
|
void IAppendWetLayer(plMaxNode* node, hsGMaterial* mat);
|
|
|
|
static plBitmap* IGetFunkyRamp(plMaxNode* node, UInt32 funkyType);
|
|
|
|
static void IAppendFunkyLayer(plMaxNode* node, Texmap* texMap, hsGMaterial* mat);
|
|
|
|
static hsBool IHasFunkyOpacity(plMaxNode* node, Texmap* texMap);
|
|
|
|
static UInt32 IGetFunkyType(Texmap* texMap);
|
|
|
|
static UInt32 IGetOpacityRanges(plMaxNode* node, Texmap* texMap, hsScalar& tr0, hsScalar& op0, hsScalar& op1, hsScalar& tr1);
|
|
|
|
|
|
|
|
Interface *fInterface;
|
|
|
|
hsConverterUtils& fConverterUtils;
|
|
|
|
hsBool fSave;
|
|
|
|
plErrorMsg *fErrorMsg;
|
|
|
|
|
|
|
|
Int32 fSubIndex;
|
|
|
|
hsBool fChangedTimes;
|
|
|
|
|
|
|
|
char *fNodeName;
|
|
|
|
UInt32 fWarned;
|
|
|
|
|
|
|
|
|
|
|
|
DoneMaterialData fLastMaterial;
|
|
|
|
hsTArray<DoneMaterialData> fDoneMaterials;
|
|
|
|
|
|
|
|
hsBool IsMatchingDoneMaterial(DoneMaterialData *dmd,
|
|
|
|
Mtl *mtl, hsBool isMultiMat, UInt32 subMtlFlags, hsBool forceCopy, hsBool runtimeLit,
|
|
|
|
plMaxNode *node, int numUVChannels, hsBool makeAlphaLayer);
|
|
|
|
|
|
|
|
void ISortDoneMaterials(hsTArray<DoneMaterialData*>& doneMats);
|
|
|
|
hsBool IEquivalent(DoneMaterialData* one, DoneMaterialData* two);
|
|
|
|
void IPrintDoneMat(hsStream* stream, const char* prefix, DoneMaterialData* doneMat);
|
|
|
|
void IPrintDoneMaterials(const char* path, hsTArray<DoneMaterialData*>& doneMats);
|
|
|
|
void IGenMaterialReport(const char* path);
|
|
|
|
|
|
|
|
public:
|
|
|
|
// Apologies all around, but I need this list for dumping some export warnings. mf
|
|
|
|
const hsTArray<struct DoneMaterialData>& DoneMaterials() { return fDoneMaterials; }
|
|
|
|
|
|
|
|
//hsBool CheckValidityOfSDLVarAnim(plPassMtlBase *mtl, char *varName, plMaxNode *node);
|
|
|
|
};
|
|
|
|
|
|
|
|
extern hsMaterialConverter gMaterialConverter;
|
|
|
|
|
|
|
|
#endif
|