diff --git a/MaxNifTools.ini b/MaxNifTools.ini index 7c11d9c63b1957db1878be0c338ec29cc18b32a7..0b8959445e6dd52a09bc1a39526ac47aa7ab413c 100644 --- a/MaxNifTools.ini +++ b/MaxNifTools.ini @@ -15,6 +15,9 @@ Reparse=0 Website=http://www.niftools.org ; Wiki - Documentation website Wiki=http://www.niftools.org/wiki/index.php/3ds_Max +; Force Plugcfg directory (Default=1) dont use the "recommended directory by max" +ForcePlugcfg=1 + [MaxNifExport] ; Enable/Disable Exporter Class in max. Default: 1 diff --git a/NifCommon/AnimKey.cpp b/NifCommon/AnimKey.cpp index 30fdbb0cf629e0cb32b08cebd679390b3e4ecf95..04342e95ed2618b11acf04d81f199eeec2c40e4c 100644 --- a/NifCommon/AnimKey.cpp +++ b/NifCommon/AnimKey.cpp @@ -50,8 +50,10 @@ T& InitBezKey(T& rKey, U& key, float time) { rKey.time = TimeToFrame(time + key.time); rKey.flags = 0; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ SetInTanType(rKey.flags,BEZKEY_FLAT); SetOutTanType(rKey.flags,BEZKEY_FLAT); +#endif return rKey; } diff --git a/NifCommon/AppSettings.cpp b/NifCommon/AppSettings.cpp index d4697021169436ed1ebfeb1c287f2678d7068a40..2e632817d20ba69952e87c9734bff113cf411fbd 100644 --- a/NifCommon/AppSettings.cpp +++ b/NifCommon/AppSettings.cpp @@ -9,8 +9,7 @@ AppSettingsMap TheAppSettings; void AppSettings::Initialize(Interface *gi) { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); if (-1 != _taccess(iniName, 0)) { bool reparse = GetIniValue<bool>("System", "Reparse", false, iniName); if (reparse || TheAppSettings.empty()){ @@ -72,8 +71,7 @@ void AppSettings::ReadSettings(string iniFile) void AppSettings::WriteSettings(Interface *gi) { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); if (-1 != _taccess(iniName, 0)) { SetIniValue(Name.c_str(), "NiVersion", NiVersion.c_str(), iniName); diff --git a/NifCommon/IniSection.h b/NifCommon/IniSection.h index e42f6a8ded61cb5cb33612f45f897cde6298b362..624bd020deebb43b750829701ef2ea817c62f5d8 100644 --- a/NifCommon/IniSection.h +++ b/NifCommon/IniSection.h @@ -2,22 +2,28 @@ #include <string> #include <list> -enum INIDEFTYPE + +enum VARIABLETYPE { - IDT_STRING, - IDT_INT, - IDT_FLOAT, - IDT_BOOL, - IDT_FILENAME, - IDT_UNKNOWN, + vtUnknown, + vtInteger, + vtFloat, + vtDouble, + vtBoolean, + vtText, + vtPointer, + vtHandle, + vtVector = 0x1000, + vtFixedVector = vtVector | 0x2000, + vtMatrix = 0x4000, }; -struct INIDEF +struct VARIABLE { - INIDEF() : ShortName(NULL), IniName(NULL), MemberAddr(0), Description(NULL), DefaultValue(NULL), ValueSize(0) { + VARIABLE() : ShortName(NULL), IniName(NULL), MemberAddr(0), Description(NULL), DefaultValue(NULL), ValueSize(0) { } - ~INIDEF() { + ~VARIABLE() { if (ValueSize && DefaultValue) { delete DefaultValue; DefaultValue = NULL; @@ -26,36 +32,43 @@ struct INIDEF } template<typename U> - INIDEF(LPCTSTR sName, LPCTSTR iName, const U& member, U default, LPCTSTR desc, INIDEFTYPE type) + VARIABLE(LPCTSTR sName, LPCTSTR iName, const U& member, U default, LPCTSTR desc, VARIABLETYPE type) : ShortName(sName), IniName(iName), MemberAddr(NULL), Description(NULL), MemberType(type) { SetDefault(default); } template<> - INIDEF(LPCTSTR sName, LPCTSTR iName, const std::string& member, std::string default, LPCTSTR desc, INIDEFTYPE type) + VARIABLE(LPCTSTR sName, LPCTSTR iName, const std::string& member, std::string default, LPCTSTR desc, VARIABLETYPE type) : ShortName(sName), IniName(iName), MemberAddr((DWORD)&member), Description(NULL) { - MemberType = type==IDT_UNKNOWN?IDT_STRING:type; + MemberType = type==vtUnknown?vtText:type; SetDefault(default); } template<> - INIDEF(LPCTSTR sName, LPCTSTR iName, const int& member, int default, LPCTSTR desc, INIDEFTYPE type) + VARIABLE(LPCTSTR sName, LPCTSTR iName, const int& member, int default, LPCTSTR desc, VARIABLETYPE type) : ShortName(sName), IniName(iName), MemberAddr((DWORD)&member), Description(NULL) { - MemberType = type==IDT_UNKNOWN?IDT_INT:type; + MemberType = type==vtUnknown?vtInteger:type; SetDefault(default); } template<> - INIDEF(LPCTSTR sName, LPCTSTR iName, const float& member, float default, LPCTSTR desc, INIDEFTYPE type) + VARIABLE(LPCTSTR sName, LPCTSTR iName, const float& member, float default, LPCTSTR desc, VARIABLETYPE type) : ShortName(sName), IniName(iName), MemberAddr((DWORD)&member), Description(NULL) { - MemberType = type==IDT_UNKNOWN?IDT_FLOAT:type; + MemberType = type==vtUnknown?vtFloat:type; SetDefault(default); } template<> - INIDEF(LPCTSTR sName, LPCTSTR iName, const bool& member, bool default, LPCTSTR desc, INIDEFTYPE type) + VARIABLE(LPCTSTR sName, LPCTSTR iName, const double& member, double default, LPCTSTR desc, VARIABLETYPE type) + : ShortName(sName), IniName(iName), MemberAddr((DWORD)&member), Description(NULL) { + MemberType = type==vtUnknown?vtDouble:type; + SetDefault(default); + } + + template<> + VARIABLE(LPCTSTR sName, LPCTSTR iName, const bool& member, bool default, LPCTSTR desc, VARIABLETYPE type) : ShortName(sName), IniName(iName), MemberAddr((DWORD)&member), Description(NULL) { - MemberType = type==IDT_UNKNOWN?IDT_BOOL:type; + MemberType = type==vtUnknown?vtBoolean:type; SetDefault(default); } @@ -73,42 +86,42 @@ struct INIDEF LPCTSTR ShortName; LPCTSTR IniName; DWORD MemberAddr; - INIDEFTYPE MemberType; + VARIABLETYPE MemberType; LPCTSTR Description; LPVOID DefaultValue; DWORD ValueSize; }; #define BEGIN_INI_MAP(name) \ - virtual void *GetMember(const INIDEF* memptr) const { return (void*)(((char*)this) + memptr->MemberAddr); } \ - virtual const INIDEF* GetInfDefmap() const { return InternalGetInfDefmap(); } \ - static INIDEF* InternalGetInfDefmap() { \ + virtual void *GetMember(const VARIABLE* memptr) const { return (void*)(((char*)this) + memptr->MemberAddr); } \ + virtual const VARIABLE* GetInfDefmap() const { return InternalGetInfDefmap(); } \ + static VARIABLE* InternalGetInfDefmap() { \ const name* pThis = 0; \ - static INIDEF map[] = { \ + static VARIABLE map[] = { \ #define BEGIN_INI_MAP_WITH_BASE(name, base) \ - virtual void *GetMember(const INIDEF* memptr) const { return (void*)(((char*)this) + memptr->MemberAddr); } \ - virtual const INIDEF* GetInfDefmap() const { return InternalGetInfDefmap(); } \ - static INIDEF* InternalGetInfDefmap() { \ + virtual void *GetMember(const VARIABLE* memptr) const { return (void*)(((char*)this) + memptr->MemberAddr); } \ + virtual const VARIABLE* GetInfDefmap() const { return InternalGetInfDefmap(); } \ + static VARIABLE* InternalGetInfDefmap() { \ const name* pThis = 0; \ - static INIDEF map[] = { \ + static VARIABLE map[] = { \ #define END_INI_MAP() \ - INIDEF() };\ + VARIABLE() };\ return map;\ } #define ADDITEM(sName, iName, member, desc) \ - INIDEF(sName, iName, pThis->member, desc, IDT_UNKNOWN), \ + VARIABLE(sName, iName, pThis->member, desc, vtUnknown), \ #define ADDITEMEX(sName, iName, member, type, desc) \ - INIDEF(sName, iName, pThis->member, desc, type), \ + VARIABLE(sName, iName, pThis->member, desc, type), \ struct IniFileSection { virtual LPCTSTR GetName() const = 0; - virtual const INIDEF* GetInfDefmap() const = 0; - virtual void *GetMember(const INIDEF* memptr) const = 0; + virtual const VARIABLE* GetInfDefmap() const = 0; + virtual void *GetMember(const VARIABLE* memptr) const = 0; }; typedef std::list<IniFileSection*> IniFileSectionList; @@ -116,7 +129,7 @@ typedef std::list<IniFileSection*> IniFileSectionList; inline int GetIniDefSectionSize(IniFileSection *section) { int len = 0; - for (const INIDEF *inidef = section->GetInfDefmap() + for (const VARIABLE *inidef = section->GetInfDefmap() ; inidef != NULL && inidef->ShortName ; ++inidef) ++len; diff --git a/NifCommon/MAX_MemDirect.h b/NifCommon/MAX_MemDirect.h index 47340a57511e49f02b8d7176acaa2fd7c518ab3b..57af5ac2c399af1ac66bdb15f99e169072252249 100644 --- a/NifCommon/MAX_MemDirect.h +++ b/NifCommon/MAX_MemDirect.h @@ -16,6 +16,8 @@ #ifndef __MAX_MEM_H #define __MAX_MEM_H +#if VERSION_3DSMAX < ((9000<<16)+(15<<8)+0) // Version 9 + #include <crtdbg.h> #include <malloc.h> #include <new.h> @@ -191,5 +193,5 @@ CoreExport int (__cdecl *MAX_CrtDumpMemoryLeaks)(void); #endif //IS_HYBRID #endif //_DEBUG - +#endif #endif //__MAX_MEM_H diff --git a/NifCommon/niutils.cpp b/NifCommon/niutils.cpp index d50499b73df7821d157a426c002237497de30fb6..9de013614f49638420093b12d9b835bd44338e19 100644 --- a/NifCommon/niutils.cpp +++ b/NifCommon/niutils.cpp @@ -947,7 +947,6 @@ void CalcCenteredSphere(const vector<Vector3>& vertices, Vector3& center, float& static void TransformVector3(Matrix44& tm, vector<Vector3>& pts) { - Matrix44::IDENTITY; for (vector<Vector3>::iterator itr = pts.begin(); itr != pts.end(); ++itr) { Matrix44 m4(*itr, Matrix33::IDENTITY, 1.0f); @@ -1095,3 +1094,45 @@ Modifier *GetbhkCollisionModifier(INode *node) } return NULL; } + +void GetIniFileName(char *iniName) +{ +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + Interface *gi = GetCOREInterface(); +#else + Interface *gi = NULL; +#endif + if (gi) { + LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); + PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + + int forcePlugcfg = GetIniValue("System", "ForcePlugcfg", 0, iniName); + + if (forcePlugcfg == 1 || _access(iniName, 06) != 0) { + TCHAR iniPath[MAX_PATH]; + GetModuleFileName(NULL, iniPath, MAX_PATH); + if (LPTSTR fname = PathFindFileName(iniPath)) + *fname = 0; + PathAddBackslash(iniPath); + PathAppend(iniPath, "plugcfg"); + PathAppend(iniPath, "MaxNifTools.ini"); + + // Use plugcfg directory ini + if (_access(iniPath, 06) == 0) { + strcpy(iniName, iniPath); + } + } + } else { + GetModuleFileName(NULL, iniName, MAX_PATH); + if (LPTSTR fname = PathFindFileName(iniName)) + *fname = 0; + PathAddBackslash(iniName); + PathAppend(iniName, "plugcfg"); + PathAppend(iniName, "MaxNifTools.ini"); + } + + if (_access(iniName, 06) != 0) { + MessageBox(NULL, "MaxNifTools could not find a valid INI. The plugin may not work correctly.\nPlease check for proper installation.", + "MaxNifTools", MB_OK|MB_ICONWARNING); + } +} \ No newline at end of file diff --git a/NifCommon/niutils.h b/NifCommon/niutils.h index 81c2153eec99b9864f30bdfb47f19974ad40a49f..59b541a2ced55e53ec92edc0b6fa48c7c6b5a250 100644 --- a/NifCommon/niutils.h +++ b/NifCommon/niutils.h @@ -387,13 +387,9 @@ extern TriObject* GetTriObject(Object *o); extern TSTR GetFileVersion(const char *fileName); -inline Niflib::NiObjectRef CreateBlock(const char *name) { - return Niflib::CreateObject(name); -} - template<typename T> inline Niflib::Ref<T> CreateNiObject() { - return Niflib::StaticCast<T>(Niflib::CreateObject(T::TypeConst().GetTypeName())); + return Niflib::StaticCast<T>(T::Create()); } void CollapseGeomTransform(Niflib::NiTriBasedGeomRef shape); @@ -402,4 +398,6 @@ void FixNormals(std::vector<Niflib::Triangle>& tris, std::vector<Niflib::Vector3 Modifier *GetbhkCollisionModifier(INode *node); +void GetIniFileName(char *iniName); + #endif // _NIUTILS_H_ \ No newline at end of file diff --git a/NifExport/Animation.cpp b/NifExport/Animation.cpp index 07d943d9f9c1dd46879410a24ad04561e717766a..815422846aabce60daf5afed0154739264a3132c 100644 --- a/NifExport/Animation.cpp +++ b/NifExport/Animation.cpp @@ -11,7 +11,7 @@ HISTORY: *> Copyright (c) 2006, All Rights Reserved. **********************************************************************/ #include "pch.h" -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7+ #include <IFrameTagManager.h> #endif #include <notetrck.h> @@ -74,7 +74,7 @@ bool GetTextKeys(INode *node, vector<StringKey>& textKeys, Interval range) { // Populate Text keys and Sequence information from note tracks if (Exporter::mUseTimeTags) { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7+ if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) { int n = tagMgr->GetTagCount(); for (int i = 0; i<n; i++) { @@ -138,7 +138,7 @@ void Exporter::InitializeTimeController(NiTimeControllerRef ctrl, NiNodeRef pare ctrl->SetStopTime(FloatNegINF); ctrl->SetPhase(0.0f); ctrl->SetFlags(0x0C); - ctrl->SetTarget( parent ); + //ctrl->SetTarget( parent ); parent->AddController(DynamicCast<NiTimeController>(ctrl)); } @@ -328,7 +328,7 @@ bool AnimationExport::doExport(NiControllerSequenceRef seq) // Populate Text keys and Sequence information from note tracks if (Exporter::mUseTimeTags) { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7 if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) { int n = tagMgr->GetTagCount(); for (int i = 0; i<n; i++) { @@ -409,7 +409,7 @@ bool AnimationExport::doExport(NiControllerManagerRef mgr, INode *node) // Populate Text keys and Sequence information from note tracks if (Exporter::mUseTimeTags) { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7 if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) { curSeq = new NiControllerSequence(); @@ -721,13 +721,14 @@ NiTimeControllerRef AnimationExport::exportController(INode *node, Interval rang Exporter::InitializeTimeController(control, ninode); NiTransformInterpolatorRef interp = new NiTransformInterpolator(); - data = new NiTransformData(); + NiTransformDataRef tdata = new NiTransformData(); + data = StaticCast<NiKeyframeData>(tdata); control->SetInterpolator(StaticCast<NiInterpolator>(interp)); interp->SetTranslation(trans); interp->SetScale(scale); interp->SetRotation(rot); - interp->SetData(data); + interp->SetData(tdata); timeControl = StaticCast<NiTimeController>(control); } @@ -740,7 +741,7 @@ NiTimeControllerRef AnimationExport::exportController(INode *node, Interval rang // interp->SetTranslation( TOVECTOR3(tm.GetTrans()) ); // interp->SetScale( Average(GetScale(tm)) ); // interp->SetRotation( TOQUAT( Quat(tm) ) ); - // seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control)); + // seq->AddInterpolator(StaticCast<NiSingleInterpController>(control)); //} //else { @@ -954,13 +955,13 @@ bool AnimationExport::exportController(INode *node, bool hasAccum) NiTimeControllerRef control = exportController( node, range, keepTM ); if (control != NULL) { - NiSingleInterpolatorControllerRef interpControl = DynamicCast<NiSingleInterpolatorController>(control); + NiSingleInterpControllerRef interpControl = DynamicCast<NiSingleInterpController>(control); if (interpControl) { // Get Priority from node float priority; npGetProp(node, NP_ANM_PRI, priority, Exporter::mDefaultPriority); - seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), priority); + seq->AddInterpolator(StaticCast<NiSingleInterpController>(control), priority); // Handle NonAccum if (Exporter::mAllowAccum && hasAccum) @@ -985,7 +986,7 @@ bool AnimationExport::exportController(INode *node, bool hasAccum) accinterp->SetData( interp->GetData() ); interp->SetData( NiTransformDataRef() ); } - seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(acccontrol), Exporter::mDefaultPriority); + seq->AddInterpolator(StaticCast<NiSingleInterpController>(acccontrol), Exporter::mDefaultPriority); accnode->RemoveController(acccontrol); } diff --git a/NifExport/Coll.cpp b/NifExport/Coll.cpp index 8281c68fc2d36af29313d46cc3c2c64ff5596a24..0ccf0986f12df8b9ec2b565d599368fcb659472f 100755 --- a/NifExport/Coll.cpp +++ b/NifExport/Coll.cpp @@ -281,7 +281,7 @@ Exporter::Result Exporter::exportCollision(NiNodeRef &parent, INode *node) bhkCollisionObjectRef co = new bhkCollisionObject(); co->SetBody(DynamicCast<NiObject>(body)); - co->SetParent(newParent); + //co->SetTarget(newParent); // link newParent->SetCollisionObject(DynamicCast<NiCollisionObject>(co)); @@ -332,7 +332,7 @@ bhkRigidBodyRef Exporter::makeCollisionBody(INode *node) npGetProp(node, NP_HVK_CENTER, center); // setup body - bhkRigidBodyRef body = DynamicCast<bhkRigidBody>(CreateBlock("bhkRigidBodyT")); + bhkRigidBodyRef body = CreateNiObject<bhkRigidBodyT>(); body->SetLayer(OblivionLayer(lyr)); body->SetLayerCopy(OblivionLayer(lyr)); @@ -424,7 +424,7 @@ bhkSphereRepShapeRef Exporter::makeCapsuleShape(Object *obj, const Matrix3& tm) params->GetValue(obj->GetParamBlockIndex(CAPSULE_RADIUS), 0, radius, FOREVER); params->GetValue(obj->GetParamBlockIndex(CAPSULE_HEIGHT), 0, height, FOREVER); - bhkCapsuleShapeRef capsule = DynamicCast<bhkCapsuleShape>(CreateBlock("bhkCapsuleShape")); + bhkCapsuleShapeRef capsule = CreateNiObject<bhkCapsuleShape>(); return bhkSphereRepShapeRef(DynamicCast<bhkSphereRepShape>(capsule)); } @@ -476,14 +476,16 @@ bhkSphereRepShapeRef Exporter::makeTriStripsShape(INode *node, const Matrix3& tm data->SetNormals(vnorms); // setup shape - bhkNiTriStripsShapeRef shape = DynamicCast<bhkNiTriStripsShape>(CreateBlock("bhkNiTriStripsShape")); - shape->SetNumStripsData(1); - shape->SetStripsData(0, data); + bhkNiTriStripsShapeRef shape = StaticCast<bhkNiTriStripsShape>(bhkNiTriStripsShape::Create()); - if (tri != os.obj) - tri->DeleteMe(); + //bhkNiTriStripsShapeRef shape = DynamicCast<bhkNiTriStripsShape>(CreateBlock("bhkNiTriStripsShape")); + //shape->SetNumStripsData(1); + //shape->SetStripsData(0, data); + + //if (tri != os.obj) + // tri->DeleteMe(); - return bhkSphereRepShapeRef(DynamicCast<bhkSphereRepShape>(shape)); + return bhkSphereRepShapeRef(); } diff --git a/NifExport/Config.cpp b/NifExport/Config.cpp index 39ab0efcbaf817a43e6c64f0e34dc51e241611b2..5f40d78933f1adc998917d4a491eb05f5fc5224a 100755 --- a/NifExport/Config.cpp +++ b/NifExport/Config.cpp @@ -46,8 +46,7 @@ void Exporter::writeConfig(Interface *i) else { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); SetIniValue(NifExportSection, "GenerateStrips", mTriStrips, iniName); SetIniValue(NifExportSection, "IncludeHidden", mExportHidden, iniName); @@ -118,8 +117,7 @@ void Exporter::readConfig(Interface *i) else { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); //mVersion = GetIniValue<int>(NifExportSection, "Version", 013, iniName); mTriStrips = GetIniValue<bool>(NifExportSection, "GenerateStrips", true, iniName); @@ -165,8 +163,7 @@ void Exporter::readConfig(Interface *i) void Exporter::readKfConfig(Interface *i) { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); mExportHidden = GetIniValue(KfExportSection, "IncludeHidden", false, iniName); mExportLights = GetIniValue(KfExportSection, "Lights", false, iniName); @@ -192,8 +189,7 @@ void Exporter::writeKfConfig(Interface *i) AppSettings * Exporter::exportAppSettings() { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = GetCOREInterface()->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); // Update the current app version AppSettings * appSettings = FindAppSetting(Exporter::mGameName); @@ -218,8 +214,7 @@ AppSettings *Exporter::importAppSettings(string fname) { AppSettings *appSettings = NULL; TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = GetCOREInterface()->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); // Locate which application to use. If Auto, find first app where this file appears in the root path list string curapp = GetIniValue<string>(NifExportSection, "CurrentApp", "AUTO", iniName); diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp index e7fe0de59b4d3141d97e816c5a2873247f5d5cb7..6e848f1fcef07db81673d8e7404d1f251afb6c37 100755 --- a/NifExport/Exporter.cpp +++ b/NifExport/Exporter.cpp @@ -90,21 +90,21 @@ Exporter::Result Exporter::doExport(NiNodeRef &root, INode *node) BSXFlagsRef bsx = CreateNiObject<BSXFlags>(); bsx->SetName("BSX"); - bsx->SetFlags( 0x00000007 ); + bsx->SetData( 0x00000007 ); root->AddExtraData(DynamicCast<NiExtraData>(bsx)); } else if (mExportType != NIF_WO_ANIM) { BSXFlagsRef bsx = CreateNiObject<BSXFlags>(); bsx->SetName("BSX"); - bsx->SetFlags( 0x00000003 ); + bsx->SetData( 0x00000003 ); root->AddExtraData(DynamicCast<NiExtraData>(bsx)); } else if (mExportCollision) { BSXFlagsRef bsx = CreateNiObject<BSXFlags>(); bsx->SetName("BSX"); - bsx->SetFlags( 0x00000002 ); + bsx->SetData( 0x00000002 ); root->AddExtraData(DynamicCast<NiExtraData>(bsx)); } } diff --git a/NifExport/KfExport.cpp b/NifExport/KfExport.cpp index 0d85c97b45a488494901a02fd618b3f0a19ae56f..0bfcd7041bcd4a37863d38bc29cebd379b28e1b2 100644 --- a/NifExport/KfExport.cpp +++ b/NifExport/KfExport.cpp @@ -188,17 +188,7 @@ KfExport::KfExport() { Interface *gi = GetCOREInterface(); TCHAR iniName[MAX_PATH]; - if (gi) { - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); - } else { - GetModuleFileName(NULL, iniName, _countof(iniName)); - if (LPTSTR fname = PathFindFileName(iniName)) - fname = NULL; - PathAddBackslash(iniName); - PathAppend(iniName, "plugcfg"); - PathAppend(iniName, "MaxNifTools.ini"); - } + GetIniFileName(iniName); iniFileName = iniName; shortDescription = GetIniValue<TSTR>("System", "ShortDescription", "Netimmerse/Gamebryo", iniFileName); fileVersion = GetFileVersion(NULL); @@ -275,8 +265,7 @@ int KfExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL s AppSettings::Initialize(i); TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); bool iniNameIsValid = (-1 != _taccess(iniName, 0)); // read config from registry diff --git a/NifExport/Mesh.cpp b/NifExport/Mesh.cpp index 9fcc315bf596a7af40d1f9173a869768056e3de9..ddeac52119fda00a1fa536840c8c5f6c78d6e5ff 100755 --- a/NifExport/Mesh.cpp +++ b/NifExport/Mesh.cpp @@ -38,7 +38,7 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue mtx.NoTrans(); mesh = copymesh = new Mesh(*mesh); int n = mesh->getNumVerts(); - for ( uint i = 0; i < n; ++i ) { + for ( unsigned int i = 0; i < n; ++i ) { Point3& vert = mesh->getVert(i); vert = mtx * vert; } @@ -47,7 +47,7 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue MeshNormalSpec *specNorms = mesh->GetSpecifiedNormals (); if (NULL != specNorms) { specNorms->CheckNormals(); - for ( uint i = 0; i < specNorms->GetNumNormals(); ++i ) { + for ( unsigned int i = 0; i < specNorms->GetNumNormals(); ++i ) { Point3& norm = specNorms->Normal(i); norm = (mtx * norm).Normalize(); } @@ -141,7 +141,7 @@ Exporter::Result Exporter::exportMesh(NiNodeRef &ninode, INode *node, TimeValue } if (node->IsHidden()) - shape->SetHidden(true); + shape->SetVisibility(false); shape->SetName(name); shape->SetLocalTransform(tm); @@ -423,7 +423,7 @@ bool Exporter::makeSkin(NiTriBasedGeomRef shape, INode *node, FaceGroup &grp, Ti Exporter::Result SkinInstance::execute() { shape->BindSkin(boneList); - uint bone = 0; + unsigned int bone = 0; for (BoneWeightList::iterator bitr = boneWeights.begin(); bitr != boneWeights.end(); ++bitr, ++bone) { shape->SetBoneWeights(bone, (*bitr)); } diff --git a/NifExport/MtlTex.cpp b/NifExport/MtlTex.cpp index 8624b178a0f0e6ba7700b9f4325353cc20716160..587ab656ee6ec70849e4302753d674cdb331480f 100755 --- a/NifExport/MtlTex.cpp +++ b/NifExport/MtlTex.cpp @@ -79,9 +79,7 @@ bool Exporter::makeTextureDesc(BitmapTex *bmTex, TexDesc& td) if (mAppSettings) { string newPath = mAppSettings->GetRelativeTexPath(string(mapPath), mTexPrefix); - - NiObjectRef unk_link(NULL); - td.source->SetExternalTexture(newPath, unk_link); + td.source->SetExternalTexture(newPath); } else { @@ -93,8 +91,7 @@ bool Exporter::makeTextureDesc(BitmapTex *bmTex, TexDesc& td) else newPath = f; - NiObjectRef unk_link(NULL); - td.source->SetExternalTexture(newPath.data(), unk_link); + td.source->SetExternalTexture(newPath.data()); } return true; } @@ -107,7 +104,7 @@ void Exporter::makeMaterial(NiAVObjectRef &parent, Mtl *mtl) return; string name; - NiMaterialPropertyRef mtlProp(DynamicCast<NiMaterialProperty>(CreateBlock("NiMaterialProperty"))); + NiMaterialPropertyRef mtlProp(CreateNiObject<NiMaterialProperty>()); if (mtl) { Color c; @@ -143,9 +140,9 @@ void Exporter::makeMaterial(NiAVObjectRef &parent, Mtl *mtl) if (smtl->GetTwoSided()){ NiStencilPropertyRef stencil = new NiStencilProperty(); stencil->SetStencilFunction(TEST_GREATER); - stencil->SetStencilEnabled(false); + stencil->SetStencilState(false); stencil->SetPassAction(ACTION_INCREMENT); - stencil->SetDrawMode(DRAW_BOTH); + stencil->SetFaceDrawMode(DRAW_BOTH); parent->AddProperty(stencil); } if (smtl->IsFaceted()) { @@ -344,9 +341,9 @@ bool Exporter::exportCiv4Shader(NiAVObjectRef parent, Mtl* mtl) if (smtl->GetTwoSided()){ NiStencilPropertyRef stencil = CreateNiObject<NiStencilProperty>(); stencil->SetStencilFunction(TEST_GREATER); - stencil->SetStencilEnabled(false); + stencil->SetStencilState(false); stencil->SetPassAction(ACTION_INCREMENT); - stencil->SetDrawMode(DRAW_BOTH); + stencil->SetFaceDrawMode(DRAW_BOTH); parent->AddProperty(stencil); } if (smtl->IsFaceted()) { @@ -378,31 +375,31 @@ bool Exporter::exportCiv4Shader(NiAVObjectRef parent, Mtl* mtl) if (alphaMode != 0 || AlphaTestEnable) { // always add alpha ??? NiAlphaPropertyRef alphaProp = CreateNiObject<NiAlphaProperty>(); - alphaProp->SetAlphaBlend(true); + alphaProp->SetBlendState(true); if (alphaMode == 0) { // automatic - alphaProp->SetSourceBlendMode(NiAlphaProperty::BlendMode(srcBlend)); - alphaProp->SetDestBlendMode(NiAlphaProperty::BlendMode(destBlend)); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BlendFunc(srcBlend)); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BlendFunc(destBlend)); } else if (alphaMode == 1) { // None - alphaProp->SetAlphaBlend(false); - alphaProp->SetSourceBlendMode(NiAlphaProperty::BM_SRC_ALPHA); - alphaProp->SetDestBlendMode(NiAlphaProperty::BM_ONE_MINUS_SRC_ALPHA); + alphaProp->SetBlendState(false); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BF_SRC_ALPHA); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BF_ONE_MINUS_SRC_ALPHA); } else if (alphaMode == 2) { // Standard - alphaProp->SetSourceBlendMode(NiAlphaProperty::BM_SRC_ALPHA); - alphaProp->SetDestBlendMode(NiAlphaProperty::BM_ONE_MINUS_SRC_ALPHA); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BF_SRC_ALPHA); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BF_ONE_MINUS_SRC_ALPHA); } else if (alphaMode == 3) { // Additive - alphaProp->SetSourceBlendMode(NiAlphaProperty::BM_ONE); - alphaProp->SetDestBlendMode(NiAlphaProperty::BM_ONE); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BF_ONE); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BF_ONE); } else if (alphaMode == 4) { // Multiplicative - alphaProp->SetSourceBlendMode(NiAlphaProperty::BM_ZERO); - alphaProp->SetDestBlendMode(NiAlphaProperty::BM_SRC_COLOR); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BF_ZERO); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BF_SRC_COLOR); } else { // Advanced - alphaProp->SetSourceBlendMode(NiAlphaProperty::BlendMode(srcBlend)); - alphaProp->SetDestBlendMode(NiAlphaProperty::BlendMode(destBlend)); + alphaProp->SetSourceBlendFunc(NiAlphaProperty::BlendFunc(srcBlend)); + alphaProp->SetDestBlendFunc(NiAlphaProperty::BlendFunc(destBlend)); } - alphaProp->SetTestMode(NiAlphaProperty::TestMode(TestMode)); - alphaProp->SetAlphaSort(!NoSorter); - alphaProp->SetAlphaTestThreshold(TestRef); - alphaProp->SetAlphaTest(AlphaTestEnable); + alphaProp->SetTestFunc(NiAlphaProperty::TestFunc(TestMode)); + alphaProp->SetTriangleSortMode(!NoSorter); + alphaProp->SetTestThreshold(TestRef); + alphaProp->SetBlendState(AlphaTestEnable); parent->AddProperty(alphaProp); } diff --git a/NifExport/NifExport.cpp b/NifExport/NifExport.cpp index 22a8ad5ae72112d5996a999190e880ee8b3a0b9e..dfbaf9b6b2268ab41349ef6097806efd916dfec7 100755 --- a/NifExport/NifExport.cpp +++ b/NifExport/NifExport.cpp @@ -39,6 +39,13 @@ public: int DoExport(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts=FALSE, DWORD options=0); int DoExportInternal(const TCHAR *name,ExpInterface *ei,Interface *i, BOOL suppressPrompts, DWORD options); + SDK_RESERVED_METHOD(1); // russom 02/26/01 + SDK_RESERVED_METHOD(2); // russom 02/26/01 + SDK_RESERVED_METHOD(3); // russom 02/26/01 + SDK_RESERVED_METHOD(4); // russom 02/26/01 + SDK_RESERVED_METHOD(5); // russom 02/26/01 + SDK_RESERVED_METHOD(6); // russom 02/26/01 + NifExport(); ~NifExport(); }; @@ -167,12 +174,12 @@ BOOL CALLBACK NifExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARA GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH); if (tmp[0] != 0) { - int nifVersion = ParseVersionString(tmp); - if (!IsSupportedVersion(nifVersion)) - { - MessageBox(hWnd, FormatString("Version '%s' is not a supported version.", tmp).c_str(), "NifExport", MB_OK|MB_ICONSTOP); - return FALSE; - } + int nifVersion = ParseVersionString(tmp); + if (!IsSupportedVersion(nifVersion)) + { + MessageBox(hWnd, FormatString("Version '%s' is not a supported version.", tmp).c_str(), "NifExport", MB_OK|MB_ICONSTOP); + return FALSE; + } } Exporter::mTriStrips = IsDlgButtonChecked(hWnd, IDC_CHK_STRIPS); @@ -275,17 +282,7 @@ NifExport::NifExport() { Interface *gi = GetCOREInterface(); TCHAR iniName[MAX_PATH]; - if (gi) { - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); - } else { - GetModuleFileName(NULL, iniName, _countof(iniName)); - if (LPTSTR fname = PathFindFileName(iniName)) - fname = NULL; - PathAddBackslash(iniName); - PathAppend(iniName, "plugcfg"); - PathAppend(iniName, "MaxNifTools.ini"); - } + GetIniFileName(iniName); iniFileName = iniName; shortDescription = GetIniValue<TSTR>("System", "ShortDescription", "Netimmerse/Gamebryo", iniFileName); fileVersion = GetFileVersion(NULL); @@ -369,44 +366,43 @@ int NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL i->PushPrompt(title); if (!suppressPrompts) i->ProgressStart(title, TRUE, dummyProgress, NULL); - try - { - DoExportInternal(name, ei, i, suppressPrompts, options); - } - catch (Exporter::CancelExporterException&) - { - // Special user cancellation exception - } - catch (exception &e) - { - if (!suppressPrompts) - MessageBox(NULL, e.what(), "Export Error", MB_OK); + try + { + DoExportInternal(name, ei, i, suppressPrompts, options); + } + catch (Exporter::CancelExporterException&) + { + // Special user cancellation exception + } + catch (exception &e) + { + if (!suppressPrompts) + MessageBox(NULL, e.what(), "Export Error", MB_OK); } catch (...) { if (!suppressPrompts) - MessageBox(NULL, "Unknown error.", "Export Error", MB_OK); + MessageBox(NULL, "Unknown error.", "Export Error", MB_OK); } i->PopPrompt(); if (!suppressPrompts) i->ProgressEnd(); return true; -} - +} + int NifExport::DoExportInternal(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options) { - TCHAR path[MAX_PATH]; - GetFullPathName(name, MAX_PATH, path, NULL); - PathRenameExtension(path, ".nif"); - - Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0; - + TCHAR path[MAX_PATH]; + GetFullPathName(name, MAX_PATH, path, NULL); + PathRenameExtension(path, ".nif"); + + Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0; + // read application settings AppSettings::Initialize(i); TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); bool iniNameIsValid = (-1 != _taccess(iniName, 0)); // Set whether Config should use registry or not @@ -433,66 +429,66 @@ int NifExport::DoExportInternal(const TCHAR *name, ExpInterface *ei, Interface * appSettings = Exporter::exportAppSettings(); appSettings->WriteSettings(i); - } - - int nifVersion = VER_20_0_0_5; - int nifUserVer = Exporter::mNifUserVersion; - if (!Exporter::mNifVersion.empty()) - { - nifVersion = ParseVersionString(Exporter::mNifVersion); - if (!IsSupportedVersion(nifVersion)) - throw exception(FormatString("Version '%s' is not a supported version.").c_str()); - } - Exporter::mNifVersionInt = nifVersion; - - Exporter::ExportType exportType = Exporter::mExportType; - - // Hack so MW exports cleaner. Basically write tree without NiControllerManager - if ( nifVersion <= VER_10_0_1_0 - && (Exporter::mExportType != Exporter::NIF_WO_ANIM && Exporter::mExportType != Exporter::NIF_WITH_MGR) - ) - { - Exporter::mExportType = Exporter::NIF_WO_KF; - } - Niflib::NifInfo info(nifVersion, nifUserVer, nifUserVer); - info.endian = Niflib::NifInfo::INFO_LITTLE_ENDIAN; - info.creator = Exporter::mCreatorName; - info.exportInfo1 = FormatText("Niftools 3ds Max Plugins %s", fileVersion.data()); - - Exporter exp(i, appSettings); - - Ref<NiNode> root = new NiNode(); + } + + int nifVersion = VER_20_0_0_5; + int nifUserVer = Exporter::mNifUserVersion; + if (!Exporter::mNifVersion.empty()) + { + nifVersion = ParseVersionString(Exporter::mNifVersion); + if (!IsSupportedVersion(nifVersion)) + throw exception(FormatString("Version '%s' is not a supported version.").c_str()); + } + Exporter::mNifVersionInt = nifVersion; + + Exporter::ExportType exportType = Exporter::mExportType; + + // Hack so MW exports cleaner. Basically write tree without NiControllerManager + if ( nifVersion <= VER_10_0_1_0 + && (Exporter::mExportType != Exporter::NIF_WO_ANIM && Exporter::mExportType != Exporter::NIF_WITH_MGR) + ) + { + Exporter::mExportType = Exporter::NIF_WO_KF; + } + Niflib::NifInfo info(nifVersion, nifUserVer, nifUserVer); + info.endian = ENDIAN_LITTLE; + info.creator = Exporter::mCreatorName; + info.exportInfo1 = FormatText("Niftools 3ds Max Plugins %s", fileVersion.data()); + + Exporter exp(i, appSettings); + + Ref<NiNode> root = new NiNode(); Exporter::Result result = exp.doExport(root, i->GetRootNode()); if (result!=Exporter::Ok) throw exception("Unknown error."); - - if (exportType == Exporter::NIF_WO_ANIM || exportType == Exporter::NIF_WITH_MGR) - { - WriteNifTree(path, NiObjectRef(root), info); - } - else - { - Niflib::ExportOptions export_type = EXPORT_NIF; - switch (exportType) { + + if (exportType == Exporter::NIF_WO_ANIM || exportType == Exporter::NIF_WITH_MGR) + { + WriteNifTree(path, NiObjectRef(root), info); + } + else + { + Niflib::ExportOptions export_type = EXPORT_NIF; + switch (exportType) { case Exporter::SINGLE_KF_WITH_NIF: export_type = EXPORT_NIF_KF; break; case Exporter::SINGLE_KF_WO_NIF: export_type = EXPORT_KF; break; case Exporter::MULTI_KF_WITH_NIF: export_type = EXPORT_NIF_KF_MULTI; break; case Exporter::MULTI_KF_WO_NIF: export_type = EXPORT_KF_MULTI; break; - } - - Niflib::NifGame game = KF_MW; - if (nifVersion <= VER_4_0_0_2) { - game = KF_MW; - } else if (nifVersion <= VER_20_0_0_4) { - game = KF_DAOC; - } else { - game = KF_CIV4; - } - - WriteFileGroup(path, StaticCast<NiObject>(root), info, export_type, game); - } - return true; + } + + Niflib::NifGame game = KF_MW; + if (nifVersion <= VER_4_0_0_2) { + game = KF_MW; + } else if (nifVersion <= VER_20_0_0_4) { + game = KF_DAOC; + } else { + game = KF_CIV4; + } + + WriteFileGroup(path, StaticCast<NiObject>(root), info, export_type, game); + } + return true; } diff --git a/NifExport/NvTriStrip/NvTriStrip.cpp b/NifExport/NvTriStrip/NvTriStrip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..88e4c1e5fb7ac13eb91846fdfb25fbc5d7171d01 --- /dev/null +++ b/NifExport/NvTriStrip/NvTriStrip.cpp @@ -0,0 +1,504 @@ + +#include "NvTriStripObjects.h" +#include "NvTriStrip.h" + +using namespace NvTriStrip; + +namespace NvTriStrip { + +//////////////////////////////////////////////////////////////////////////////////////// +//private data +static unsigned int cacheSize = CACHESIZE_GEFORCE1_2; +static bool bStitchStrips = true; +static unsigned int minStripSize = 0; +static bool bListsOnly = false; +static unsigned int restartVal = 0; +static bool bRestart = false; + +void EnableRestart(const unsigned int _restartVal) +{ + bRestart = true; + restartVal = _restartVal; +} + +void DisableRestart() +{ + bRestart = false; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// SetListsOnly() +// +// If set to true, will return an optimized list, with no strips at all. +// +// Default value: false +// +void SetListsOnly(const bool _bListsOnly) +{ + bListsOnly = _bListsOnly; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// SetCacheSize() +// +// Sets the cache size which the stripfier uses to optimize the data. +// Controls the length of the generated individual strips. +// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2 +// You may want to play around with this number to tweak performance. +// +// Default value: 16 +// +void SetCacheSize(const unsigned int _cacheSize) +{ + cacheSize = _cacheSize; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetStitchStrips() +// +// bool to indicate whether to stitch together strips into one huge strip or not. +// If set to true, you'll get back one huge strip stitched together using degenerate +// triangles. +// If set to false, you'll get back a large number of separate strips. +// +// Default value: true +// +void SetStitchStrips(const bool _bStitchStrips) +{ + bStitchStrips = _bStitchStrips; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetMinStripSize() +// +// Sets the minimum acceptable size for a strip, in triangles. +// All strips generated which are shorter than this will be thrown into one big, separate list. +// +// Default value: 0 +// +void SetMinStripSize(const unsigned int _minStripSize) +{ + minStripSize = _minStripSize; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +//Cleanup strips / faces, used by generatestrips +void Cleanup(NvStripInfoVec& tempStrips, NvFaceInfoVec& tempFaces) +{ + //delete strips + for(size_t i = 0; i < tempStrips.size(); i++) + { + for(size_t j = 0; j < tempStrips[i]->m_faces.size(); j++) + { + delete tempStrips[i]->m_faces[j]; + tempStrips[i]->m_faces[j] = NULL; + } + tempStrips[i]->m_faces.resize(0); + delete tempStrips[i]; + tempStrips[i] = NULL; + } + + //delete faces + for(size_t i = 0; i < tempFaces.size(); i++) + { + delete tempFaces[i]; + tempFaces[i] = NULL; + } +} + + +//////////////////////////////////////////////////////////////////////////////////////// +//SameTriangle() +// +//Returns true if the two triangles defined by firstTri and secondTri are the same +// The "same" is defined in this case as having the same indices with the same winding order +// +bool SameTriangle(unsigned short firstTri0, unsigned short firstTri1, unsigned short firstTri2, + unsigned short secondTri0, unsigned short secondTri1, unsigned short secondTri2) +{ + bool isSame = false; + + if (firstTri0 == secondTri0) + { + if (firstTri1 == secondTri1) + { + if (firstTri2 == secondTri2) + isSame = true; + } + } + else if (firstTri0 == secondTri1) + { + if (firstTri1 == secondTri2) + { + if (firstTri2 == secondTri0) + isSame = true; + } + } + else if (firstTri0 == secondTri2) + { + if (firstTri1 == secondTri0) + { + if (firstTri2 == secondTri1) + isSame = true; + } + } + + return isSame; +} + + +bool TestTriangle(const unsigned short v0, const unsigned short v1, const unsigned short v2, const std::vector<NvFaceInfo>* in_bins, const int NUMBINS) +{ + //hash this triangle + bool isLegit = false; + int ctr = v0 % NUMBINS; + for (size_t k = 0; k < in_bins[ctr].size(); ++k) + { + //check triangles in this bin + if (SameTriangle(in_bins[ctr][k].m_v0, in_bins[ctr][k].m_v1, in_bins[ctr][k].m_v2, + v0, v1, v2)) + { + isLegit = true; + break; + } + } + if (!isLegit) + { + ctr = v1 % NUMBINS; + for (size_t k = 0; k < in_bins[ctr].size(); ++k) + { + //check triangles in this bin + if (SameTriangle(in_bins[ctr][k].m_v0, in_bins[ctr][k].m_v1, in_bins[ctr][k].m_v2, + v0, v1, v2)) + { + isLegit = true; + break; + } + } + + if (!isLegit) + { + ctr = v2 % NUMBINS; + for (size_t k = 0; k < in_bins[ctr].size(); ++k) + { + //check triangles in this bin + if (SameTriangle(in_bins[ctr][k].m_v0, in_bins[ctr][k].m_v1, in_bins[ctr][k].m_v2, + v0, v1, v2)) + { + isLegit = true; + break; + } + } + + } + } + + return isLegit; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// GenerateStrips() +// +// in_indices: input index list, the indices you would use to render +// in_numIndices: number of entries in in_indices +// primGroups: array of optimized/stripified PrimitiveGroups +// numGroups: number of groups returned +// +// Be sure to call delete[] on the returned primGroups to avoid leaking mem +// +bool GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices, + PrimitiveGroup** primGroups, unsigned short* numGroups, bool validateEnabled) +{ + //put data in format that the stripifier likes + WordVec tempIndices; + tempIndices.resize(in_numIndices); + unsigned short maxIndex = 0; + unsigned short minIndex = 0xFFFF; + for(size_t i = 0; i < in_numIndices; i++) + { + tempIndices[i] = in_indices[i]; + if (in_indices[i] > maxIndex) + maxIndex = in_indices[i]; + if (in_indices[i] < minIndex) + minIndex = in_indices[i]; + } + NvStripInfoVec tempStrips; + NvFaceInfoVec tempFaces; + + NvStripifier stripifier; + + //do actual stripification + stripifier.Stripify(tempIndices, cacheSize, minStripSize, maxIndex, tempStrips, tempFaces); + + //stitch strips together + IntVec stripIndices; + unsigned int numSeparateStrips = 0; + + if(bListsOnly) + { + //if we're outputting only lists, we're done + *numGroups = 1; + (*primGroups) = new PrimitiveGroup[*numGroups]; + PrimitiveGroup* primGroupArray = *primGroups; + + //count the total number of indices + unsigned int numIndices = 0; + for(size_t i = 0; i < tempStrips.size(); i++) + { + numIndices += tempStrips[i]->m_faces.size() * 3; + } + + //add in the list + numIndices += tempFaces.size() * 3; + + primGroupArray[0].type = PT_LIST; + primGroupArray[0].numIndices = numIndices; + primGroupArray[0].indices = new unsigned short[numIndices]; + + //do strips + unsigned int indexCtr = 0; + for(size_t i = 0; i < tempStrips.size(); i++) + { + for(size_t j = 0; j < tempStrips[i]->m_faces.size(); j++) + { + //degenerates are of no use with lists + if(!NvStripifier::IsDegenerate(tempStrips[i]->m_faces[j])) + { + primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v0; + primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v1; + primGroupArray[0].indices[indexCtr++] = tempStrips[i]->m_faces[j]->m_v2; + } + else + { + //we've removed a tri, reduce the number of indices + primGroupArray[0].numIndices -= 3; + } + } + } + + //do lists + for(size_t i = 0; i < tempFaces.size(); i++) + { + primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v0; + primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v1; + primGroupArray[0].indices[indexCtr++] = tempFaces[i]->m_v2; + } + } + else + { + stripifier.CreateStrips(tempStrips, stripIndices, bStitchStrips, numSeparateStrips, bRestart, restartVal); + + //if we're stitching strips together, we better get back only one strip from CreateStrips() + assert( (bStitchStrips && (numSeparateStrips == 1)) || !bStitchStrips); + + //convert to output format + *numGroups = numSeparateStrips; //for the strips + if(tempFaces.size() != 0) + (*numGroups)++; //we've got a list as well, increment + (*primGroups) = new PrimitiveGroup[*numGroups]; + + PrimitiveGroup* primGroupArray = *primGroups; + + //first, the strips + int startingLoc = 0; + for(size_t stripCtr = 0; stripCtr < numSeparateStrips; stripCtr++) + { + int stripLength = 0; + + if(!bStitchStrips) + { + //if we've got multiple strips, we need to figure out the correct length + size_t i; + for(i = startingLoc; i < stripIndices.size(); i++) + { + if(stripIndices[i] == -1) + break; + } + + stripLength = i - startingLoc; + } + else + stripLength = stripIndices.size(); + + primGroupArray[stripCtr].type = PT_STRIP; + primGroupArray[stripCtr].indices = new unsigned short[stripLength]; + primGroupArray[stripCtr].numIndices = stripLength; + + int indexCtr = 0; + for(int i = startingLoc; i < stripLength + startingLoc; i++) + primGroupArray[stripCtr].indices[indexCtr++] = stripIndices[i]; + + //we add 1 to account for the -1 separating strips + //this doesn't break the stitched case since we'll exit the loop + startingLoc += stripLength + 1; + } + + //next, the list + if(tempFaces.size() != 0) + { + int faceGroupLoc = (*numGroups) - 1; //the face group is the last one + primGroupArray[faceGroupLoc].type = PT_LIST; + primGroupArray[faceGroupLoc].indices = new unsigned short[tempFaces.size() * 3]; + primGroupArray[faceGroupLoc].numIndices = tempFaces.size() * 3; + int indexCtr = 0; + for(size_t i = 0; i < tempFaces.size(); i++) + { + primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v0; + primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v1; + primGroupArray[faceGroupLoc].indices[indexCtr++] = tempFaces[i]->m_v2; + } + } + } + + //validate generated data against input + if (validateEnabled) + { + const int NUMBINS = 100; + + std::vector<NvFaceInfo> in_bins[NUMBINS]; + + //hash input indices on first index + for (size_t i = 0; i < in_numIndices; i += 3) + { + NvFaceInfo faceInfo(in_indices[i], in_indices[i + 1], in_indices[i + 2]); + in_bins[in_indices[i] % NUMBINS].push_back(faceInfo); + } + + for (int i = 0; i < *numGroups; ++i) + { + switch ((*primGroups)[i].type) + { + case PT_LIST: + { + for (size_t j = 0; j < (*primGroups)[i].numIndices; j += 3) + { + unsigned short v0 = (*primGroups)[i].indices[j]; + unsigned short v1 = (*primGroups)[i].indices[j + 1]; + unsigned short v2 = (*primGroups)[i].indices[j + 2]; + + //ignore degenerates + if (NvStripifier::IsDegenerate(v0, v1, v2)) + continue; + + if (!TestTriangle(v0, v1, v2, in_bins, NUMBINS)) + { + Cleanup(tempStrips, tempFaces); + return false; + } + } + break; + } + + case PT_STRIP: + { + //int brokenCtr = 0; + bool flip = false; + for (size_t j = 2; j < (*primGroups)[i].numIndices; ++j) + { + unsigned short v0 = (*primGroups)[i].indices[j - 2]; + unsigned short v1 = (*primGroups)[i].indices[j - 1]; + unsigned short v2 = (*primGroups)[i].indices[j]; + + if (flip) + { + //swap v1 and v2 + unsigned short swap = v1; + v1 = v2; + v2 = swap; + } + + //ignore degenerates + if (NvStripifier::IsDegenerate(v0, v1, v2)) + { + flip = !flip; + continue; + } + + if (!TestTriangle(v0, v1, v2, in_bins, NUMBINS)) + { + Cleanup(tempStrips, tempFaces); + return false; + } + + flip = !flip; + } + break; + } + + case PT_FAN: + default: + break; + } + } + + } + + //clean up everything + Cleanup(tempStrips, tempFaces); + + return true; +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// RemapIndices() +// +// Function to remap your indices to improve spatial locality in your vertex buffer. +// +// in_primGroups: array of PrimitiveGroups you want remapped +// numGroups: number of entries in in_primGroups +// numVerts: number of vertices in your vertex buffer, also can be thought of as the range +// of acceptable values for indices in your primitive groups. +// remappedGroups: array of remapped PrimitiveGroups +// +// Note that, according to the remapping handed back to you, you must reorder your +// vertex buffer. +// +void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups, + const unsigned short numVerts, PrimitiveGroup** remappedGroups) +{ + (*remappedGroups) = new PrimitiveGroup[numGroups]; + + //caches oldIndex --> newIndex conversion + int *indexCache; + indexCache = new int[numVerts]; + memset(indexCache, -1, sizeof(int)*numVerts); + + //loop over primitive groups + unsigned int indexCtr = 0; + for(int i = 0; i < numGroups; i++) + { + unsigned int numIndices = in_primGroups[i].numIndices; + + //init remapped group + (*remappedGroups)[i].type = in_primGroups[i].type; + (*remappedGroups)[i].numIndices = numIndices; + (*remappedGroups)[i].indices = new unsigned short[numIndices]; + + for(size_t j = 0; j < numIndices; j++) + { + int cachedIndex = indexCache[in_primGroups[i].indices[j]]; + if(cachedIndex == -1) //we haven't seen this index before + { + //point to "last" vertex in VB + (*remappedGroups)[i].indices[j] = indexCtr; + + //add to index cache, increment + indexCache[in_primGroups[i].indices[j]] = indexCtr++; + } + else + { + //we've seen this index before + (*remappedGroups)[i].indices[j] = cachedIndex; + } + } + } + + delete[] indexCache; +} + +} //end namespace diff --git a/NifExport/NvTriStrip/NvTriStrip.h b/NifExport/NvTriStrip/NvTriStrip.h new file mode 100644 index 0000000000000000000000000000000000000000..0e6c695da8a043e61355324213b8d53deace304b --- /dev/null +++ b/NifExport/NvTriStrip/NvTriStrip.h @@ -0,0 +1,147 @@ +#ifndef NVTRISTRIP_H +#define NVTRISTRIP_H + +#ifndef NULL +#define NULL 0 +#endif + +namespace NvTriStrip { + +//////////////////////////////////////////////////////////////////////////////////////// +// Public interface for stripifier +//////////////////////////////////////////////////////////////////////////////////////// + +//GeForce1 and 2 cache size +#define CACHESIZE_GEFORCE1_2 16 + +//GeForce3 cache size +#define CACHESIZE_GEFORCE3 24 + +enum PrimType +{ + PT_LIST, + PT_STRIP, + PT_FAN +}; + +struct PrimitiveGroup +{ + PrimType type; + unsigned int numIndices; + unsigned short* indices; + +//////////////////////////////////////////////////////////////////////////////////////// + + PrimitiveGroup() : type(PT_STRIP), numIndices(0), indices(NULL) {} + ~PrimitiveGroup() + { + if(indices) + delete[] indices; + indices = NULL; + } +}; + + +//////////////////////////////////////////////////////////////////////////////////////// +// EnableRestart() +// +// For GPUs that support primitive restart, this sets a value as the restart index +// +// Restart is meaningless if strips are not being stitched together, so enabling restart +// makes NvTriStrip forcing stitching. So, you'll get back one strip. +// +// Default value: disabled +// +void EnableRestart(const unsigned int restartVal); + +//////////////////////////////////////////////////////////////////////////////////////// +// DisableRestart() +// +// For GPUs that support primitive restart, this disables using primitive restart +// +void DisableRestart(); + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetCacheSize() +// +// Sets the cache size which the stripfier uses to optimize the data. +// Controls the length of the generated individual strips. +// This is the "actual" cache size, so 24 for GeForce3 and 16 for GeForce1/2 +// You may want to play around with this number to tweak performance. +// +// Default value: 16 +// +void SetCacheSize(const unsigned int cacheSize); + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetStitchStrips() +// +// bool to indicate whether to stitch together strips into one huge strip or not. +// If set to true, you'll get back one huge strip stitched together using degenerate +// triangles. +// If set to false, you'll get back a large number of separate strips. +// +// Default value: true +// +void SetStitchStrips(const bool bStitchStrips); + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetMinStripSize() +// +// Sets the minimum acceptable size for a strip, in triangles. +// All strips generated which are shorter than this will be thrown into one big, separate list. +// +// Default value: 0 +// +void SetMinStripSize(const unsigned int minSize); + + +//////////////////////////////////////////////////////////////////////////////////////// +// SetListsOnly() +// +// If set to true, will return an optimized list, with no strips at all. +// +// Default value: false +// +void SetListsOnly(const bool bListsOnly); + + +//////////////////////////////////////////////////////////////////////////////////////// +// GenerateStrips() +// +// in_indices: input index list, the indices you would use to render +// in_numIndices: number of entries in in_indices +// primGroups: array of optimized/stripified PrimitiveGroups +// numGroups: number of groups returned +// +// Be sure to call delete[] on the returned primGroups to avoid leaking mem +// +bool GenerateStrips(const unsigned short* in_indices, const unsigned int in_numIndices, + PrimitiveGroup** primGroups, unsigned short* numGroups, bool validateEnabled = false); + + +//////////////////////////////////////////////////////////////////////////////////////// +// RemapIndices() +// +// Function to remap your indices to improve spatial locality in your vertex buffer. +// +// in_primGroups: array of PrimitiveGroups you want remapped +// numGroups: number of entries in in_primGroups +// numVerts: number of vertices in your vertex buffer, also can be thought of as the range +// of acceptable values for indices in your primitive groups. +// remappedGroups: array of remapped PrimitiveGroups +// +// Note that, according to the remapping handed back to you, you must reorder your +// vertex buffer. +// +// Credit goes to the MS Xbox crew for the idea for this interface. +// +void RemapIndices(const PrimitiveGroup* in_primGroups, const unsigned short numGroups, + const unsigned short numVerts, PrimitiveGroup** remappedGroups); + +} //End namespace + +#endif \ No newline at end of file diff --git a/NifExport/NvTriStrip/NvTriStripObjects.cpp b/NifExport/NvTriStrip/NvTriStripObjects.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cf11d34d006ef3a63edc13811d29b0af8f38681 --- /dev/null +++ b/NifExport/NvTriStrip/NvTriStripObjects.cpp @@ -0,0 +1,1771 @@ + +//#pragma warning( disable : 4786 ) + +#include <assert.h> +#include <set> +#include "NvTriStripObjects.h" +#include "VertexCache.h" + +using namespace NvTriStrip; + +#define CACHE_INEFFICIENCY 6 + +NvStripifier::NvStripifier() +{ + +} + +NvStripifier::~NvStripifier() +{ + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindEdgeInfo() +// +// find the edge info for these two indices +// +NvEdgeInfo * NvStripifier::FindEdgeInfo(NvEdgeInfoVec &edgeInfos, int v0, int v1){ + + // we can get to it through either array + // because the edge infos have a v0 and v1 + // and there is no order except how it was + // first created. + NvEdgeInfo *infoIter = edgeInfos[v0]; + while (infoIter != NULL){ + if (infoIter->m_v0 == v0){ + if (infoIter->m_v1 == v1) + return infoIter; + else + infoIter = infoIter->m_nextV0; + } + else { + assert(infoIter->m_v1 == v0); + if (infoIter->m_v0 == v1) + return infoIter; + else + infoIter = infoIter->m_nextV1; + } + } + return NULL; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindOtherFace +// +// find the other face sharing these vertices +// exactly like the edge info above +// +NvFaceInfo * NvStripifier::FindOtherFace(NvEdgeInfoVec &edgeInfos, int v0, int v1, NvFaceInfo *faceInfo){ + NvEdgeInfo *edgeInfo = FindEdgeInfo(edgeInfos, v0, v1); + + if( (edgeInfo == NULL) && (v0 == v1)) + { + //we've hit a degenerate + return NULL; + } + + assert(edgeInfo != NULL); + return (edgeInfo->m_face0 == faceInfo ? edgeInfo->m_face1 : edgeInfo->m_face0); +} + + +bool NvStripifier::AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos) +{ + for(size_t i = 0; i < faceInfos.size(); ++i) + { + if( (faceInfos[i]->m_v0 == faceInfo->m_v0) && + (faceInfos[i]->m_v1 == faceInfo->m_v1) && + (faceInfos[i]->m_v2 == faceInfo->m_v2) ) + return true; + } + + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// BuildStripifyInfo() +// +// Builds the list of all face and edge infos +// +void NvStripifier::BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, + const unsigned short maxIndex) +{ + // reserve space for the face infos, but do not resize them. + int numIndices = indices.size(); + faceInfos.reserve(numIndices / 3); + + // we actually resize the edge infos, so we must initialize to NULL + edgeInfos.resize(maxIndex + 1); + for (int i = 0; i < maxIndex + 1; i++) + edgeInfos[i] = NULL; + + // iterate through the triangles of the triangle list + int numTriangles = numIndices / 3; + int index = 0; + bool bFaceUpdated[3]; + + for (int i = 0; i < numTriangles; i++) + { + bool bMightAlreadyExist = true; + bFaceUpdated[0] = false; + bFaceUpdated[1] = false; + bFaceUpdated[2] = false; + + // grab the indices + int v0 = indices[index++]; + int v1 = indices[index++]; + int v2 = indices[index++]; + + //we disregard degenerates + if(IsDegenerate(v0, v1, v2)) + continue; + + // create the face info and add it to the list of faces, but only if this exact face doesn't already + // exist in the list + NvFaceInfo *faceInfo = new NvFaceInfo(v0, v1, v2); + + // grab the edge infos, creating them if they do not already exist + NvEdgeInfo *edgeInfo01 = FindEdgeInfo(edgeInfos, v0, v1); + if (edgeInfo01 == NULL) + { + //since one of it's edges isn't in the edge data structure, it can't already exist in the face structure + bMightAlreadyExist = false; + + // create the info + edgeInfo01 = new NvEdgeInfo(v0, v1); + + // update the linked list on both + edgeInfo01->m_nextV0 = edgeInfos[v0]; + edgeInfo01->m_nextV1 = edgeInfos[v1]; + edgeInfos[v0] = edgeInfo01; + edgeInfos[v1] = edgeInfo01; + + // set face 0 + edgeInfo01->m_face0 = faceInfo; + } + else + { + if (edgeInfo01->m_face1 != NULL) + { + //printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); + } + else + { + edgeInfo01->m_face1 = faceInfo; + bFaceUpdated[0] = true; + } + } + + // grab the edge infos, creating them if they do not already exist + NvEdgeInfo *edgeInfo12 = FindEdgeInfo(edgeInfos, v1, v2); + if (edgeInfo12 == NULL) + { + bMightAlreadyExist = false; + + // create the info + edgeInfo12 = new NvEdgeInfo(v1, v2); + + // update the linked list on both + edgeInfo12->m_nextV0 = edgeInfos[v1]; + edgeInfo12->m_nextV1 = edgeInfos[v2]; + edgeInfos[v1] = edgeInfo12; + edgeInfos[v2] = edgeInfo12; + + // set face 0 + edgeInfo12->m_face0 = faceInfo; + } + else + { + if (edgeInfo12->m_face1 != NULL) + { + //printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); + } + else + { + edgeInfo12->m_face1 = faceInfo; + bFaceUpdated[1] = true; + } + } + + // grab the edge infos, creating them if they do not already exist + NvEdgeInfo *edgeInfo20 = FindEdgeInfo(edgeInfos, v2, v0); + if (edgeInfo20 == NULL) + { + bMightAlreadyExist = false; + + // create the info + edgeInfo20 = new NvEdgeInfo(v2, v0); + + // update the linked list on both + edgeInfo20->m_nextV0 = edgeInfos[v2]; + edgeInfo20->m_nextV1 = edgeInfos[v0]; + edgeInfos[v2] = edgeInfo20; + edgeInfos[v0] = edgeInfo20; + + // set face 0 + edgeInfo20->m_face0 = faceInfo; + } + else + { + if (edgeInfo20->m_face1 != NULL) + { + //printf("BuildStripifyInfo: > 2 triangles on an edge... uncertain consequences\n"); + } + else + { + edgeInfo20->m_face1 = faceInfo; + bFaceUpdated[2] = true; + } + } + + if(bMightAlreadyExist) + { + if(!AlreadyExists(faceInfo, faceInfos)) + faceInfos.push_back(faceInfo); + else + { + delete faceInfo; + + //cleanup pointers that point to this deleted face + if(bFaceUpdated[0]) + edgeInfo01->m_face1 = NULL; + if(bFaceUpdated[1]) + edgeInfo12->m_face1 = NULL; + if(bFaceUpdated[2]) + edgeInfo20->m_face1 = NULL; + } + } + else + { + faceInfos.push_back(faceInfo); + } + + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindStartPoint() +// +// Finds a good starting point, namely one which has only one neighbor +// +int NvStripifier::FindStartPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos) +{ + int bestCtr = -1; + int bestIndex = -1; + + for(size_t i = 0; i < faceInfos.size(); i++) + { + int ctr = 0; + + if(FindOtherFace(edgeInfos, faceInfos[i]->m_v0, faceInfos[i]->m_v1, faceInfos[i]) == NULL) + ctr++; + if(FindOtherFace(edgeInfos, faceInfos[i]->m_v1, faceInfos[i]->m_v2, faceInfos[i]) == NULL) + ctr++; + if(FindOtherFace(edgeInfos, faceInfos[i]->m_v2, faceInfos[i]->m_v0, faceInfos[i]) == NULL) + ctr++; + if(ctr > bestCtr) + { + bestCtr = ctr; + bestIndex = i; + //return i; + } + } + //return -1; + + if(bestCtr == 0) + return -1; + else + return bestIndex; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindGoodResetPoint() +// +// A good reset point is one near other commited areas so that +// we know that when we've made the longest strips its because +// we're stripifying in the same general orientation. +// +NvFaceInfo* NvStripifier::FindGoodResetPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos){ + // we hop into different areas of the mesh to try to get + // other large open spans done. Areas of small strips can + // just be left to triangle lists added at the end. + NvFaceInfo *result = NULL; + + if(result == NULL) + { + int numFaces = faceInfos.size(); + if (numFaces == 0) + return NULL; + + int startPoint; + if(bFirstTimeResetPoint) + { + //first time, find a face with few neighbors (look for an edge of the mesh) + startPoint = FindStartPoint(faceInfos, edgeInfos); + bFirstTimeResetPoint = false; + } + else + startPoint = (int)(((float) numFaces - 1) * meshJump); + + if(startPoint == -1) + { + startPoint = (int)(((float) numFaces - 1) * meshJump); + + //meshJump += 0.1f; + //if (meshJump > 1.0f) + // meshJump = .05f; + } + + int i = startPoint; + do { + + // if this guy isn't visited, try him + if (faceInfos[i]->m_stripId < 0){ + result = faceInfos[i]; + break; + } + + // update the index and clamp to 0-(numFaces-1) + if (++i >= numFaces) + i = 0; + + } while (i != startPoint); + + // update the meshJump + meshJump += 0.1f; + if (meshJump > 1.0f) + meshJump = .05f; + } + + // return the best face we found + return result; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// GetUniqueVertexInB() +// +// Returns the vertex unique to faceB +// +int NvStripifier::GetUniqueVertexInB(NvFaceInfo *faceA, NvFaceInfo *faceB){ + + int facev0 = faceB->m_v0; + if (facev0 != faceA->m_v0 && + facev0 != faceA->m_v1 && + facev0 != faceA->m_v2) + return facev0; + + int facev1 = faceB->m_v1; + if (facev1 != faceA->m_v0 && + facev1 != faceA->m_v1 && + facev1 != faceA->m_v2) + return facev1; + + int facev2 = faceB->m_v2; + if (facev2 != faceA->m_v0 && + facev2 != faceA->m_v1 && + facev2 != faceA->m_v2) + return facev2; + + // nothing is different + return -1; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// GetSharedVertices() +// +// Returns the (at most) two vertices shared between the two faces +// +void NvStripifier::GetSharedVertices(NvFaceInfo *faceA, NvFaceInfo *faceB, int* vertex0, int* vertex1) +{ + *vertex0 = -1; + *vertex1 = -1; + + int facev0 = faceB->m_v0; + if (facev0 == faceA->m_v0 || + facev0 == faceA->m_v1 || + facev0 == faceA->m_v2) + { + if(*vertex0 == -1) + *vertex0 = facev0; + else + { + *vertex1 = facev0; + return; + } + } + + int facev1 = faceB->m_v1; + if (facev1 == faceA->m_v0 || + facev1 == faceA->m_v1 || + facev1 == faceA->m_v2) + { + if(*vertex0 == -1) + *vertex0 = facev1; + else + { + *vertex1 = facev1; + return; + } + } + + int facev2 = faceB->m_v2; + if (facev2 == faceA->m_v0 || + facev2 == faceA->m_v1 || + facev2 == faceA->m_v2) + { + if(*vertex0 == -1) + *vertex0 = facev2; + else + { + *vertex1 = facev2; + return; + } + } + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// GetNextIndex() +// +// Returns vertex of the input face which is "next" in the input index list +// +inline int NvStripifier::GetNextIndex(const WordVec &indices, NvFaceInfo *face){ + + int numIndices = indices.size(); + assert(numIndices >= 2); + + int v0 = indices[numIndices-2]; + int v1 = indices[numIndices-1]; + + int fv0 = face->m_v0; + int fv1 = face->m_v1; + int fv2 = face->m_v2; + + if (fv0 != v0 && fv0 != v1){ + if ((fv1 != v0 && fv1 != v1) || (fv2 != v0 && fv2 != v1)){ + //printf("GetNextIndex: Triangle doesn't have all of its vertices\n"); + //printf("GetNextIndex: Duplicate triangle probably got us derailed\n"); + } + return fv0; + } + if (fv1 != v0 && fv1 != v1){ + if ((fv0 != v0 && fv0 != v1) || (fv2 != v0 && fv2 != v1)){ + //printf("GetNextIndex: Triangle doesn't have all of its vertices\n"); + //printf("GetNextIndex: Duplicate triangle probably got us derailed\n"); + } + return fv1; + } + if (fv2 != v0 && fv2 != v1){ + if ((fv0 != v0 && fv0 != v1) || (fv1 != v0 && fv1 != v1)){ + //printf("GetNextIndex: Triangle doesn't have all of its vertices\n"); + //printf("GetNextIndex: Duplicate triangle probably got us derailed\n"); + } + return fv2; + } + + // shouldn't get here, but let's try and fail gracefully + if( (fv0 == fv1) || (fv0 == fv2) ) + return fv0; + else if( (fv1 == fv0) || (fv1 == fv2) ) + return fv1; + else if( (fv2 == fv0) || (fv2 == fv1) ) + return fv2; + else + return -1; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// IsMarked() +// +// If either the faceInfo has a real strip index because it is +// already assign to a committed strip OR it is assigned in an +// experiment and the experiment index is the one we are building +// for, then it is marked and unavailable +inline bool NvStripInfo::IsMarked(NvFaceInfo *faceInfo){ + return (faceInfo->m_stripId >= 0) || (IsExperiment() && faceInfo->m_experimentId == m_experimentId); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// MarkTriangle() +// +// Marks the face with the current strip ID +// +inline void NvStripInfo::MarkTriangle(NvFaceInfo *faceInfo){ + assert(!IsMarked(faceInfo)); + if (IsExperiment()){ + faceInfo->m_experimentId = m_experimentId; + faceInfo->m_testStripId = m_stripId; + } + else{ + assert(faceInfo->m_stripId == -1); + faceInfo->m_experimentId = -1; + faceInfo->m_stripId = m_stripId; + } +} + + +bool NvStripInfo::Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face) +{ + bool bv0, bv1, bv2; //bools to indicate whether a vertex is in the faceVec or not + bv0 = bv1 = bv2 = false; + + for(size_t i = 0; i < faceVec.size(); i++) + { + if(!bv0) + { + if( (faceVec[i]->m_v0 == face->m_v0) || + (faceVec[i]->m_v1 == face->m_v0) || + (faceVec[i]->m_v2 == face->m_v0) ) + bv0 = true; + } + + if(!bv1) + { + if( (faceVec[i]->m_v0 == face->m_v1) || + (faceVec[i]->m_v1 == face->m_v1) || + (faceVec[i]->m_v2 == face->m_v1) ) + bv1 = true; + } + + if(!bv2) + { + if( (faceVec[i]->m_v0 == face->m_v2) || + (faceVec[i]->m_v1 == face->m_v2) || + (faceVec[i]->m_v2 == face->m_v2) ) + bv2 = true; + } + + //the face is not unique, all it's vertices exist in the face vector + if(bv0 && bv1 && bv2) + return false; + } + + //if we get out here, it's unique + return true; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// Build() +// +// Builds a strip forward as far as we can go, then builds backwards, and joins the two lists +// +void NvStripInfo::Build(NvEdgeInfoVec &edgeInfos, NvFaceInfoVec &faceInfos) +{ + // used in building the strips forward and backward + WordVec scratchIndices; + + // build forward... start with the initial face + NvFaceInfoVec forwardFaces, backwardFaces; + forwardFaces.push_back(m_startInfo.m_startFace); + + MarkTriangle(m_startInfo.m_startFace); + + int v0 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge->m_v0 : m_startInfo.m_startEdge->m_v1); + int v1 = (m_startInfo.m_toV1 ? m_startInfo.m_startEdge->m_v1 : m_startInfo.m_startEdge->m_v0); + + // easiest way to get v2 is to use this function which requires the + // other indices to already be in the list. + scratchIndices.push_back(v0); + scratchIndices.push_back(v1); + int v2 = NvStripifier::GetNextIndex(scratchIndices, m_startInfo.m_startFace); + scratchIndices.push_back(v2); + + // + // build the forward list + // + int nv0 = v1; + int nv1 = v2; + + NvFaceInfo *nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace); + while (nextFace != NULL && !IsMarked(nextFace)) + { + //check to see if this next face is going to cause us to die soon + int testnv0 = nv1; + int testnv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); + + NvFaceInfo* nextNextFace = NvStripifier::FindOtherFace(edgeInfos, testnv0, testnv1, nextFace); + + if( (nextNextFace == NULL) || (IsMarked(nextNextFace)) ) + { + //uh, oh, we're following a dead end, try swapping + NvFaceInfo* testNextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, testnv1, nextFace); + + if( ((testNextFace != NULL) && !IsMarked(testNextFace)) ) + { + //we only swap if it buys us something + + //add a "fake" degenerate face + NvFaceInfo* tempFace = new NvFaceInfo(nv0, nv1, nv0, true); + + forwardFaces.push_back(tempFace); + MarkTriangle(tempFace); + + scratchIndices.push_back(nv0); + testnv0 = nv0; + + ++m_numDegenerates; + } + + } + + // add this to the strip + forwardFaces.push_back(nextFace); + + MarkTriangle(nextFace); + + // add the index + //nv0 = nv1; + //nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); + scratchIndices.push_back(testnv1); + + // and get the next face + nv0 = testnv0; + nv1 = testnv1; + + nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, nextFace); + + } + + // tempAllFaces is going to be forwardFaces + backwardFaces + // it's used for Unique() + NvFaceInfoVec tempAllFaces; + for(size_t i = 0; i < forwardFaces.size(); i++) + tempAllFaces.push_back(forwardFaces[i]); + + // + // reset the indices for building the strip backwards and do so + // + scratchIndices.resize(0); + scratchIndices.push_back(v2); + scratchIndices.push_back(v1); + scratchIndices.push_back(v0); + nv0 = v1; + nv1 = v0; + nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, m_startInfo.m_startFace); + while (nextFace != NULL && !IsMarked(nextFace)) + { + //this tests to see if a face is "unique", meaning that its vertices aren't already in the list + // so, strips which "wrap-around" are not allowed + if(!Unique(tempAllFaces, nextFace)) + break; + + //check to see if this next face is going to cause us to die soon + int testnv0 = nv1; + int testnv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); + + NvFaceInfo* nextNextFace = NvStripifier::FindOtherFace(edgeInfos, testnv0, testnv1, nextFace); + + if( (nextNextFace == NULL) || (IsMarked(nextNextFace)) ) + { + //uh, oh, we're following a dead end, try swapping + NvFaceInfo* testNextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, testnv1, nextFace); + if( ((testNextFace != NULL) && !IsMarked(testNextFace)) ) + { + //we only swap if it buys us something + + //add a "fake" degenerate face + NvFaceInfo* tempFace = new NvFaceInfo(nv0, nv1, nv0, true); + + backwardFaces.push_back(tempFace); + MarkTriangle(tempFace); + scratchIndices.push_back(nv0); + testnv0 = nv0; + + ++m_numDegenerates; + } + + } + + // add this to the strip + backwardFaces.push_back(nextFace); + + //this is just so Unique() will work + tempAllFaces.push_back(nextFace); + + MarkTriangle(nextFace); + + // add the index + //nv0 = nv1; + //nv1 = NvStripifier::GetNextIndex(scratchIndices, nextFace); + scratchIndices.push_back(testnv1); + + // and get the next face + nv0 = testnv0; + nv1 = testnv1; + nextFace = NvStripifier::FindOtherFace(edgeInfos, nv0, nv1, nextFace); + } + + // Combine the forward and backwards stripification lists and put into our own face vector + Combine(forwardFaces, backwardFaces); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// Combine() +// +// Combines the two input face vectors and puts the result into m_faces +// +void NvStripInfo::Combine(const NvFaceInfoVec &forward, const NvFaceInfoVec &backward){ + + // add backward faces + int numFaces = backward.size(); + for (int i = numFaces - 1; i >= 0; i--) + m_faces.push_back(backward[i]); + + // add forward faces + numFaces = forward.size(); + for (int i = 0; i < numFaces; i++) + m_faces.push_back(forward[i]); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// SharesEdge() +// +// Returns true if the input face and the current strip share an edge +// +bool NvStripInfo::SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec &edgeInfos) +{ + //check v0->v1 edge + NvEdgeInfo* currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v0, faceInfo->m_v1); + + if(IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) + return true; + + //check v1->v2 edge + currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v1, faceInfo->m_v2); + + if(IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) + return true; + + //check v2->v0 edge + currEdge = NvStripifier::FindEdgeInfo(edgeInfos, faceInfo->m_v2, faceInfo->m_v0); + + if(IsInStrip(currEdge->m_face0) || IsInStrip(currEdge->m_face1)) + return true; + + return false; + +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CommitStrips() +// +// "Commits" the input strips by setting their m_experimentId to -1 and adding to the allStrips +// vector +// +void NvStripifier::CommitStrips(NvStripInfoVec &allStrips, const NvStripInfoVec &strips) +{ + // Iterate through strips + int numStrips = strips.size(); + for (int i = 0; i < numStrips; i++){ + + // Tell the strip that it is now real + NvStripInfo *strip = strips[i]; + strip->m_experimentId = -1; + + // add to the list of real strips + allStrips.push_back(strip); + + // Iterate through the faces of the strip + // Tell the faces of the strip that they belong to a real strip now + const NvFaceInfoVec &faces = strips[i]->m_faces; + int numFaces = faces.size(); + + for (int j = 0; j < numFaces; j++) + { + strip->MarkTriangle(faces[j]); + } + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindTraversal() +// +// Finds the next face to start the next strip on. +// +bool NvStripifier::FindTraversal(NvFaceInfoVec &faceInfos, + NvEdgeInfoVec &edgeInfos, + NvStripInfo *strip, + NvStripStartInfo &startInfo){ + + // if the strip was v0->v1 on the edge, then v1 will be a vertex in the next edge. + int v = (strip->m_startInfo.m_toV1 ? strip->m_startInfo.m_startEdge->m_v1 : strip->m_startInfo.m_startEdge->m_v0); + + NvFaceInfo *untouchedFace = NULL; + NvEdgeInfo *edgeIter = edgeInfos[v]; + while (edgeIter != NULL){ + NvFaceInfo *face0 = edgeIter->m_face0; + NvFaceInfo *face1 = edgeIter->m_face1; + if ((face0 != NULL && !strip->IsInStrip(face0)) && face1 != NULL && !strip->IsMarked(face1)) + { + untouchedFace = face1; + break; + } + if ((face1 != NULL && !strip->IsInStrip(face1)) && face0 != NULL && !strip->IsMarked(face0)){ + untouchedFace = face0; + break; + } + + // find the next edgeIter + edgeIter = (edgeIter->m_v0 == v ? edgeIter->m_nextV0 : edgeIter->m_nextV1); + } + + startInfo.m_startFace = untouchedFace; + startInfo.m_startEdge = edgeIter; + if (edgeIter != NULL) + { + if(strip->SharesEdge(startInfo.m_startFace, edgeInfos)) + startInfo.m_toV1 = (edgeIter->m_v0 == v); //note! used to be m_v1 + else + startInfo.m_toV1 = (edgeIter->m_v1 == v); + } + return (startInfo.m_startFace != NULL); +} + + +//////////////////////////////////////////////////////////////////////////////////////// +// RemoveSmallStrips() +// +// allStrips is the whole strip vector...all small strips will be deleted from this list, to avoid leaking mem +// allBigStrips is an out parameter which will contain all strips above minStripLength +// faceList is an out parameter which will contain all faces which were removed from the striplist +// +void NvStripifier::RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList) +{ + faceList.clear(); + allBigStrips.clear(); //make sure these are empty + NvFaceInfoVec tempFaceList; + + for(size_t i = 0; i < allStrips.size(); i++) + { + if(allStrips[i]->m_faces.size() < size_t(minStripLength)) + { + //strip is too small, add faces to faceList + for(size_t j = 0; j < allStrips[i]->m_faces.size(); j++) + tempFaceList.push_back(allStrips[i]->m_faces[j]); + + //and free memory + delete allStrips[i]; + } + else + { + allBigStrips.push_back(allStrips[i]); + } + } + + if(tempFaceList.size()) + { + bool *bVisitedList = new bool[tempFaceList.size()]; + memset(bVisitedList, 0, tempFaceList.size()*sizeof(bool)); + + VertexCache* vcache = new VertexCache(cacheSize); + + int bestNumHits = -1; + int numHits; + int bestIndex = -1; + + while(1) + { + bestNumHits = -1; + + //find best face to add next, given the current cache + for(size_t i = 0; i < tempFaceList.size(); i++) + { + if(bVisitedList[i]) + continue; + + numHits = CalcNumHitsFace(vcache, tempFaceList[i]); + if(numHits > bestNumHits) + { + bestNumHits = numHits; + bestIndex = i; + } + } + + if(bestNumHits == -1.0f) + break; + bVisitedList[bestIndex] = true; + UpdateCacheFace(vcache, tempFaceList[bestIndex]); + faceList.push_back(tempFaceList[bestIndex]); + } + + delete vcache; + delete[] bVisitedList; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// NextIsCW() +// +// Returns true if the next face should be ordered in CW fashion +// +bool NvStripifier::NextIsCW(const int numIndices) +{ + return ((numIndices % 2) == 0); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// IsCW() +// +// Returns true if the face is ordered in CW fashion +// +bool NvStripifier::IsCW(NvFaceInfo *faceInfo, int v0, int v1) +{ + if (faceInfo->m_v0 == v0) + return (faceInfo->m_v1 == v1); + + else if (faceInfo->m_v1 == v0) + return (faceInfo->m_v2 == v1); + + else + return (faceInfo->m_v0 == v1); + + // shouldn't get here + assert(0); + return false; +} + +bool NvStripifier::FaceContainsIndex(const NvFaceInfo& face, const unsigned int index) +{ + return ( (size_t(face.m_v0) == index) || (size_t(face.m_v1) == index) || (size_t(face.m_v2) == index) ); +} + +bool NvStripifier::IsMoneyFace(const NvFaceInfo& face) +{ + if(FaceContainsIndex(face, 800) && + FaceContainsIndex(face, 812) && + FaceContainsIndex(face, 731)) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////////////// +// CreateStrips() +// +// Generates actual strips from the list-in-strip-order. +// +void NvStripifier::CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, + const bool bStitchStrips, unsigned int& numSeparateStrips, + const bool bRestart, const unsigned int restartVal) +{ + assert(numSeparateStrips == 0); + + NvFaceInfo tLastFace(0, 0, 0); + NvFaceInfo tPrevStripLastFace(0, 0, 0); + int nStripCount = allStrips.size(); + assert(nStripCount > 0); + + //we infer the cw/ccw ordering depending on the number of indices + //this is screwed up by the fact that we insert -1s to denote changing strips + //this is to account for that + int accountForNegatives = 0; + + for (int i = 0; i < nStripCount; i++) + { + NvStripInfo *strip = allStrips[i]; + int nStripFaceCount = strip->m_faces.size(); + assert(nStripFaceCount > 0); + + // Handle the first face in the strip + { + NvFaceInfo tFirstFace(strip->m_faces[0]->m_v0, strip->m_faces[0]->m_v1, strip->m_faces[0]->m_v2); + + // If there is a second face, reorder vertices such that the + // unique vertex is first + if (nStripFaceCount > 1) + { + int nUnique = NvStripifier::GetUniqueVertexInB(strip->m_faces[1], &tFirstFace); + if (nUnique == tFirstFace.m_v1) + { + SWAP(tFirstFace.m_v0, tFirstFace.m_v1); + } + else if (nUnique == tFirstFace.m_v2) + { + SWAP(tFirstFace.m_v0, tFirstFace.m_v2); + } + + // If there is a third face, reorder vertices such that the + // shared vertex is last + if (nStripFaceCount > 2) + { + if(IsDegenerate(strip->m_faces[1])) + { + int pivot = strip->m_faces[1]->m_v1; + if(tFirstFace.m_v1 == pivot) + { + SWAP(tFirstFace.m_v1, tFirstFace.m_v2); + } + } + else + { + int nShared0, nShared1; + GetSharedVertices(strip->m_faces[2], &tFirstFace, &nShared0, &nShared1); + if ( (nShared0 == tFirstFace.m_v1) && (nShared1 == -1) ) + { + SWAP(tFirstFace.m_v1, tFirstFace.m_v2); + } + } + } + } + + if( (i == 0) || !bStitchStrips || bRestart) + { + if(!IsCW(strip->m_faces[0], tFirstFace.m_v0, tFirstFace.m_v1)) + stripIndices.push_back(tFirstFace.m_v0); + } + else + { + // Double tap the first in the new strip + stripIndices.push_back(tFirstFace.m_v0); + + // Check CW/CCW ordering + if (NextIsCW(stripIndices.size() - accountForNegatives) != IsCW(strip->m_faces[0], tFirstFace.m_v0, tFirstFace.m_v1)) + { + stripIndices.push_back(tFirstFace.m_v0); + } + } + + stripIndices.push_back(tFirstFace.m_v0); + stripIndices.push_back(tFirstFace.m_v1); + stripIndices.push_back(tFirstFace.m_v2); + + // Update last face info + tLastFace = tFirstFace; + } + + for (int j = 1; j < nStripFaceCount; j++) + { + int nUnique = GetUniqueVertexInB(&tLastFace, strip->m_faces[j]); + if (nUnique != -1) + { + stripIndices.push_back(nUnique); + + // Update last face info + tLastFace.m_v0 = tLastFace.m_v1; + tLastFace.m_v1 = tLastFace.m_v2; + tLastFace.m_v2 = nUnique; + } + else + { + //we've hit a degenerate + stripIndices.push_back(strip->m_faces[j]->m_v2); + tLastFace.m_v0 = strip->m_faces[j]->m_v0;//tLastFace.m_v1; + tLastFace.m_v1 = strip->m_faces[j]->m_v1;//tLastFace.m_v2; + tLastFace.m_v2 = strip->m_faces[j]->m_v2;//tLastFace.m_v1; + + } + } + + // Double tap between strips. + if (bStitchStrips && !bRestart) + { + if (i != nStripCount - 1) + stripIndices.push_back(tLastFace.m_v2); + } + else if (bRestart) + { + stripIndices.push_back(restartVal); + } + else + { + //-1 index indicates next strip + stripIndices.push_back(-1); + accountForNegatives++; + numSeparateStrips++; + } + + // Update last face info + tLastFace.m_v0 = tLastFace.m_v1; + tLastFace.m_v1 = tLastFace.m_v2; + tLastFace.m_v2 = tLastFace.m_v2; + } + + if(bStitchStrips || bRestart) + numSeparateStrips = 1; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// Stripify() +// +// +// in_indices are the input indices of the mesh to stripify +// in_cacheSize is the target cache size +// +void NvStripifier::Stripify(const WordVec &in_indices, const int in_cacheSize, + const int in_minStripLength, const unsigned short maxIndex, + NvStripInfoVec &outStrips, NvFaceInfoVec& outFaceList) +{ + meshJump = 0.0f; + bFirstTimeResetPoint = true; //used in FindGoodResetPoint() + + //the number of times to run the experiments + int numSamples = 10; + + //the cache size, clamped to one + if ( in_cacheSize - CACHE_INEFFICIENCY < 1 ) cacheSize = 1; + else cacheSize = in_cacheSize - CACHE_INEFFICIENCY; + + minStripLength = in_minStripLength; //this is the strip size threshold below which we dump the strip into a list + + indices = in_indices; + + // build the stripification info + NvFaceInfoVec allFaceInfos; + NvEdgeInfoVec allEdgeInfos; + + BuildStripifyInfo(allFaceInfos, allEdgeInfos, maxIndex); + + NvStripInfoVec allStrips; + + // stripify + FindAllStrips(allStrips, allFaceInfos, allEdgeInfos, numSamples); + + //split up the strips into cache friendly pieces, optimize them, then dump these into outStrips + SplitUpStripsAndOptimize(allStrips, outStrips, allEdgeInfos, outFaceList); + + //clean up + for(size_t i = 0; i < allStrips.size(); i++) + { + delete allStrips[i]; + } + + for (size_t i = 0; i < allEdgeInfos.size(); i++) + { + NvEdgeInfo *info = allEdgeInfos[i]; + while (info != NULL) + { + NvEdgeInfo *next = (size_t(info->m_v0) == i ? info->m_nextV0 : info->m_nextV1); + info->Unref(); + info = next; + } + } + +} + + +bool NvStripifier::IsDegenerate(const NvFaceInfo* face) +{ + if(face->m_v0 == face->m_v1) + return true; + else if(face->m_v0 == face->m_v2) + return true; + else if(face->m_v1 == face->m_v2) + return true; + else + return false; +} + +bool NvStripifier::IsDegenerate(const unsigned short v0, const unsigned short v1, const unsigned short v2) +{ + if(v0 == v1) + return true; + else if(v0 == v2) + return true; + else if(v1 == v2) + return true; + else + return false; +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// SplitUpStripsAndOptimize() +// +// Splits the input vector of strips (allBigStrips) into smaller, cache friendly pieces, then +// reorders these pieces to maximize cache hits +// The final strips are output through outStrips +// +void NvStripifier::SplitUpStripsAndOptimize(NvStripInfoVec &allStrips, NvStripInfoVec &outStrips, + NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList) +{ + int threshold = cacheSize; + NvStripInfoVec tempStrips; + + //split up strips into threshold-sized pieces + for(size_t i = 0; i < allStrips.size(); i++) + { + NvStripInfo* currentStrip; + NvStripStartInfo startInfo(NULL, NULL, false); + + int actualStripSize = 0; + for(size_t j = 0; j < allStrips[i]->m_faces.size(); ++j) + { + if( !IsDegenerate(allStrips[i]->m_faces[j]) ) + actualStripSize++; + } + + if(actualStripSize /*allStrips[i]->m_faces.size()*/ > threshold) + { + + int numTimes = actualStripSize /*allStrips[i]->m_faces.size()*/ / threshold; + int numLeftover = actualStripSize /*allStrips[i]->m_faces.size()*/ % threshold; + + int degenerateCount = 0; + int j; + for(j = 0; j < numTimes; j++) + { + currentStrip = new NvStripInfo(startInfo, 0, -1); + + int faceCtr = j*threshold + degenerateCount; + bool bFirstTime = true; + while(faceCtr < threshold+(j*threshold)+degenerateCount) + { + if(IsDegenerate(allStrips[i]->m_faces[faceCtr])) + { + degenerateCount++; + + //last time or first time through, no need for a degenerate + if( (((faceCtr + 1) != threshold+(j*threshold)+degenerateCount) || + ((j == numTimes - 1) && (numLeftover < 4) && (numLeftover > 0))) && + !bFirstTime) + { + currentStrip->m_faces.push_back(allStrips[i]->m_faces[faceCtr++]); + } + else + { + //but, we do need to delete the degenerate, if it's marked fake, to avoid leaking + if(allStrips[i]->m_faces[faceCtr]->m_bIsFake) + { + delete allStrips[i]->m_faces[faceCtr], allStrips[i]->m_faces[faceCtr] = NULL; + } + ++faceCtr; + } + } + else + { + currentStrip->m_faces.push_back(allStrips[i]->m_faces[faceCtr++]); + bFirstTime = false; + } + } + /* + for(int faceCtr = j*threshold; faceCtr < threshold+(j*threshold); faceCtr++) + { + currentStrip->m_faces.push_back(allStrips[i]->m_faces[faceCtr]); + } + */ + if(j == numTimes - 1) //last time through + { + if( (numLeftover < 4) && (numLeftover > 0) ) //way too small + { + //just add to last strip + int ctr = 0; + while(ctr < numLeftover) + { + IsDegenerate( allStrips[i]->m_faces[faceCtr] ) ? ++degenerateCount : ++ctr; + currentStrip->m_faces.push_back(allStrips[i]->m_faces[faceCtr++]); + } + numLeftover = 0; + } + } + tempStrips.push_back(currentStrip); + } + + int leftOff = j * threshold + degenerateCount; + + if(numLeftover != 0) + { + currentStrip = new NvStripInfo(startInfo, 0, -1); + + int ctr = 0; + bool bFirstTime = true; + while(ctr < numLeftover) + { + if( !IsDegenerate(allStrips[i]->m_faces[leftOff]) ) + { + ctr++; + bFirstTime = false; + currentStrip->m_faces.push_back(allStrips[i]->m_faces[leftOff++]); + } + else if(!bFirstTime) + currentStrip->m_faces.push_back(allStrips[i]->m_faces[leftOff++]); + else + { + //don't leak + if(allStrips[i]->m_faces[leftOff]->m_bIsFake) + { + delete allStrips[i]->m_faces[leftOff], allStrips[i]->m_faces[leftOff] = NULL; + } + + leftOff++; + } + } + /* + for(int k = 0; k < numLeftover; k++) + { + currentStrip->m_faces.push_back(allStrips[i]->m_faces[leftOff++]); + } + */ + + tempStrips.push_back(currentStrip); + } + } + else + { + //we're not just doing a tempStrips.push_back(allBigStrips[i]) because + // this way we can delete allBigStrips later to free the memory + currentStrip = new NvStripInfo(startInfo, 0, -1); + + for(size_t j = 0; j < allStrips[i]->m_faces.size(); j++) + currentStrip->m_faces.push_back(allStrips[i]->m_faces[j]); + + tempStrips.push_back(currentStrip); + } + } + + //add small strips to face list + NvStripInfoVec tempStrips2; + RemoveSmallStrips(tempStrips, tempStrips2, outFaceList); + + outStrips.clear(); + //screw optimization for now +// for(i = 0; i < tempStrips.size(); ++i) +// outStrips.push_back(tempStrips[i]); + + if(tempStrips2.size() != 0) + { + //Optimize for the vertex cache + VertexCache* vcache = new VertexCache(cacheSize); + + float bestNumHits = -1.0f; + float numHits; + int bestIndex = -1; + //bool done = false; + + int firstIndex = 0; + float minCost = 10000.0f; + + for(size_t i = 0; i < tempStrips2.size(); i++) + { + int numNeighbors = 0; + + //find strip with least number of neighbors per face + for(size_t j = 0; j < tempStrips2[i]->m_faces.size(); j++) + { + numNeighbors += NumNeighbors(tempStrips2[i]->m_faces[j], edgeInfos); + } + + float currCost = (float)numNeighbors / (float)tempStrips2[i]->m_faces.size(); + if(currCost < minCost) + { + minCost = currCost; + firstIndex = i; + } + } + + UpdateCacheStrip(vcache, tempStrips2[firstIndex]); + outStrips.push_back(tempStrips2[firstIndex]); + + tempStrips2[firstIndex]->visited = true; + + bool bWantsCW = (tempStrips2[firstIndex]->m_faces.size() % 2) == 0; + + //this n^2 algo is what slows down stripification so much.... + // needs to be improved + while(1) + { + bestNumHits = -1.0f; + + //find best strip to add next, given the current cache + for(size_t i = 0; i < tempStrips2.size(); i++) + { + if(tempStrips2[i]->visited) + continue; + + numHits = CalcNumHitsStrip(vcache, tempStrips2[i]); + if(numHits > bestNumHits) + { + bestNumHits = numHits; + bestIndex = i; + } + else if(numHits >= bestNumHits) + { + //check previous strip to see if this one requires it to switch polarity + NvStripInfo *strip = tempStrips2[i]; + int nStripFaceCount = strip->m_faces.size(); + + NvFaceInfo tFirstFace(strip->m_faces[0]->m_v0, strip->m_faces[0]->m_v1, strip->m_faces[0]->m_v2); + + // If there is a second face, reorder vertices such that the + // unique vertex is first + if (nStripFaceCount > 1) + { + int nUnique = NvStripifier::GetUniqueVertexInB(strip->m_faces[1], &tFirstFace); + if (nUnique == tFirstFace.m_v1) + { + SWAP(tFirstFace.m_v0, tFirstFace.m_v1); + } + else if (nUnique == tFirstFace.m_v2) + { + SWAP(tFirstFace.m_v0, tFirstFace.m_v2); + } + + // If there is a third face, reorder vertices such that the + // shared vertex is last + if (nStripFaceCount > 2) + { + int nShared0, nShared1; + GetSharedVertices(strip->m_faces[2], &tFirstFace, &nShared0, &nShared1); + if ( (nShared0 == tFirstFace.m_v1) && (nShared1 == -1) ) + { + SWAP(tFirstFace.m_v1, tFirstFace.m_v2); + } + } + } + + // Check CW/CCW ordering + if (bWantsCW == IsCW(strip->m_faces[0], tFirstFace.m_v0, tFirstFace.m_v1)) + { + //I like this one! + bestIndex = i; + } + } + } + + if(bestNumHits == -1.0f) + break; + tempStrips2[bestIndex]->visited = true; + UpdateCacheStrip(vcache, tempStrips2[bestIndex]); + outStrips.push_back(tempStrips2[bestIndex]); + bWantsCW = (tempStrips2[bestIndex]->m_faces.size() % 2 == 0) ? bWantsCW : !bWantsCW; + } + + delete vcache; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// UpdateCacheStrip() +// +// Updates the input vertex cache with this strip's vertices +// +void NvStripifier::UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip) +{ + for(size_t i = 0; i < strip->m_faces.size(); ++i) + { + if(!vcache->InCache(strip->m_faces[i]->m_v0)) + vcache->AddEntry(strip->m_faces[i]->m_v0); + + if(!vcache->InCache(strip->m_faces[i]->m_v1)) + vcache->AddEntry(strip->m_faces[i]->m_v1); + + if(!vcache->InCache(strip->m_faces[i]->m_v2)) + vcache->AddEntry(strip->m_faces[i]->m_v2); + } +} + +/////////////////////////////////////////////////////////////////////////////////////////// +// UpdateCacheFace() +// +// Updates the input vertex cache with this face's vertices +// +void NvStripifier::UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face) +{ + if(!vcache->InCache(face->m_v0)) + vcache->AddEntry(face->m_v0); + + if(!vcache->InCache(face->m_v1)) + vcache->AddEntry(face->m_v1); + + if(!vcache->InCache(face->m_v2)) + vcache->AddEntry(face->m_v2); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CalcNumHitsStrip() +// +// returns the number of cache hits per face in the strip +// +float NvStripifier::CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip) +{ + int numHits = 0; + int numFaces = 0; + + for(size_t i = 0; i < strip->m_faces.size(); i++) + { + if(vcache->InCache(strip->m_faces[i]->m_v0)) + ++numHits; + + if(vcache->InCache(strip->m_faces[i]->m_v1)) + ++numHits; + + if(vcache->InCache(strip->m_faces[i]->m_v2)) + ++numHits; + + numFaces++; + } + + return ((float)numHits / (float)numFaces); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CalcNumHitsFace() +// +// returns the number of cache hits in the face +// +int NvStripifier::CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face) +{ + int numHits = 0; + + if(vcache->InCache(face->m_v0)) + numHits++; + + if(vcache->InCache(face->m_v1)) + numHits++; + + if(vcache->InCache(face->m_v2)) + numHits++; + + return numHits; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// NumNeighbors() +// +// Returns the number of neighbors that this face has +// +int NvStripifier::NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec) +{ + int numNeighbors = 0; + + if(FindOtherFace(edgeInfoVec, face->m_v0, face->m_v1, face) != NULL) + { + numNeighbors++; + } + + if(FindOtherFace(edgeInfoVec, face->m_v1, face->m_v2, face) != NULL) + { + numNeighbors++; + } + + if(FindOtherFace(edgeInfoVec, face->m_v2, face->m_v0, face) != NULL) + { + numNeighbors++; + } + + return numNeighbors; +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// AvgStripSize() +// +// Finds the average strip size of the input vector of strips +// +float NvStripifier::AvgStripSize(const NvStripInfoVec &strips){ + int sizeAccum = 0; + int numStrips = strips.size(); + for (int i = 0; i < numStrips; i++){ + NvStripInfo *strip = strips[i]; + sizeAccum += strip->m_faces.size(); + sizeAccum -= strip->m_numDegenerates; + } + return ((float)sizeAccum) / ((float)numStrips); +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// FindAllStrips() +// +// Does the stripification, puts output strips into vector allStrips +// +// Works by setting runnning a number of experiments in different areas of the mesh, and +// accepting the one which results in the longest strips. It then accepts this, and moves +// on to a different area of the mesh. We try to jump around the mesh some, to ensure that +// large open spans of strips get generated. +// +void NvStripifier::FindAllStrips(NvStripInfoVec &allStrips, + NvFaceInfoVec &allFaceInfos, + NvEdgeInfoVec &allEdgeInfos, + int numSamples){ + // the experiments + int experimentId = 0; + int stripId = 0; + bool done = false; + + int loopCtr = 0; + + while (!done) + { + loopCtr++; + + // + // PHASE 1: Set up numSamples * numEdges experiments + // + NvStripInfoVec *experiments = new NvStripInfoVec [numSamples * 6]; + int experimentIndex = 0; + std::set <NvFaceInfo*> resetPoints; + for (int i = 0; i < numSamples; i++) + { + + // Try to find another good reset point. + // If there are none to be found, we are done + NvFaceInfo *nextFace = FindGoodResetPoint(allFaceInfos, allEdgeInfos); + if (nextFace == NULL){ + done = true; + break; + } + // If we have already evaluated starting at this face in this slew + // of experiments, then skip going any further + else if (resetPoints.find(nextFace) != resetPoints.end()){ + continue; + } + + // trying it now... + resetPoints.insert(nextFace); + + // otherwise, we shall now try experiments for starting on the 01,12, and 20 edges + assert(nextFace->m_stripId < 0); + + // build the strip off of this face's 0-1 edge + NvEdgeInfo *edge01 = FindEdgeInfo(allEdgeInfos, nextFace->m_v0, nextFace->m_v1); + NvStripInfo *strip01 = new NvStripInfo(NvStripStartInfo(nextFace, edge01, true), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip01); + + // build the strip off of this face's 1-0 edge + NvEdgeInfo *edge10 = FindEdgeInfo(allEdgeInfos, nextFace->m_v0, nextFace->m_v1); + NvStripInfo *strip10 = new NvStripInfo(NvStripStartInfo(nextFace, edge10, false), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip10); + + // build the strip off of this face's 1-2 edge + NvEdgeInfo *edge12 = FindEdgeInfo(allEdgeInfos, nextFace->m_v1, nextFace->m_v2); + NvStripInfo *strip12 = new NvStripInfo(NvStripStartInfo(nextFace, edge12, true), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip12); + + // build the strip off of this face's 2-1 edge + NvEdgeInfo *edge21 = FindEdgeInfo(allEdgeInfos, nextFace->m_v1, nextFace->m_v2); + NvStripInfo *strip21 = new NvStripInfo(NvStripStartInfo(nextFace, edge21, false), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip21); + + // build the strip off of this face's 2-0 edge + NvEdgeInfo *edge20 = FindEdgeInfo(allEdgeInfos, nextFace->m_v2, nextFace->m_v0); + NvStripInfo *strip20 = new NvStripInfo(NvStripStartInfo(nextFace, edge20, true), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip20); + + // build the strip off of this face's 0-2 edge + NvEdgeInfo *edge02 = FindEdgeInfo(allEdgeInfos, nextFace->m_v2, nextFace->m_v0); + NvStripInfo *strip02 = new NvStripInfo(NvStripStartInfo(nextFace, edge02, false), stripId++, experimentId++); + experiments[experimentIndex++].push_back(strip02); + } + + // + // PHASE 2: Iterate through that we setup in the last phase + // and really build each of the strips and strips that follow to see how + // far we get + // + int numExperiments = experimentIndex; + for (int i = 0; i < numExperiments; i++){ + + // get the strip set + + // build the first strip of the list + experiments[i][0]->Build(allEdgeInfos, allFaceInfos); + int experimentId = experiments[i][0]->m_experimentId; + + NvStripInfo *stripIter = experiments[i][0]; + NvStripStartInfo startInfo(NULL, NULL, false); + while (FindTraversal(allFaceInfos, allEdgeInfos, stripIter, startInfo)){ + + // create the new strip info + stripIter = new NvStripInfo(startInfo, stripId++, experimentId); + + // build the next strip + stripIter->Build(allEdgeInfos, allFaceInfos); + + // add it to the list + experiments[i].push_back(stripIter); + } + } + + // + // Phase 3: Find the experiment that has the most promise + // + int bestIndex = 0; + double bestValue = 0; + for (int i = 0; i < numExperiments; i++) + { + const float avgStripSizeWeight = 1.0f; + //const float numTrisWeight = 0.0f; + const float numStripsWeight = 0.0f; + float avgStripSize = AvgStripSize(experiments[i]); + float numStrips = (float) experiments[i].size(); + float value = avgStripSize * avgStripSizeWeight + (numStrips * numStripsWeight); + //float value = 1.f / numStrips; + //float value = numStrips * avgStripSize; + + if (value > bestValue) + { + bestValue = value; + bestIndex = i; + } + } + + // + // Phase 4: commit the best experiment of the bunch + // + CommitStrips(allStrips, experiments[bestIndex]); + + // and destroy all of the others + for (int i = 0; i < numExperiments; i++) + { + if (i != bestIndex) + { + int numStrips = experiments[i].size(); + for (int j = 0; j < numStrips; j++) + { + NvStripInfo* currStrip = experiments[i][j]; + //delete all bogus faces in the experiments + for (size_t k = 0; k < currStrip->m_faces.size(); ++k) + { + if(currStrip->m_faces[k]->m_bIsFake) + { + delete currStrip->m_faces[k], currStrip->m_faces[k] = NULL; + } + } + delete currStrip, currStrip = NULL, experiments[i][j] = NULL; + } + } + } + + // delete the array that we used for all experiments + delete [] experiments; + } +} + + +/////////////////////////////////////////////////////////////////////////////////////////// +// CountRemainingTris() +// +// This will count the number of triangles left in the +// strip list starting at iter and finishing up at end +// +int NvStripifier::CountRemainingTris(std::list<NvStripInfo*>::iterator iter, + std::list<NvStripInfo*>::iterator end){ + int count = 0; + while (iter != end){ + count += (*iter)->m_faces.size(); + iter++; + } + return count; +} + diff --git a/NifExport/NvTriStrip/NvTriStripObjects.h b/NifExport/NvTriStrip/NvTriStripObjects.h new file mode 100644 index 0000000000000000000000000000000000000000..32d90f805e18ec6e0d0e843568137639cb71b86e --- /dev/null +++ b/NifExport/NvTriStrip/NvTriStripObjects.h @@ -0,0 +1,248 @@ + +#ifndef NV_TRISTRIP_OBJECTS_H +#define NV_TRISTRIP_OBJECTS_H + +#include <assert.h> +#include <vector> +#include <list> +#include "VertexCache.h" + +//Wrap these types in a namespace +namespace NvTriStrip { + +///////////////////////////////////////////////////////////////////////////////// +// +// Types defined for stripification +// +///////////////////////////////////////////////////////////////////////////////// + +struct MyVertex { + float x, y, z; + float nx, ny, nz; +}; + +typedef MyVertex MyVector; + +struct MyFace { + int v1, v2, v3; + float nx, ny, nz; +}; + + +class NvFaceInfo { +public: + + // vertex indices + NvFaceInfo(int v0, int v1, int v2, bool bIsFake = false){ + m_v0 = v0; m_v1 = v1; m_v2 = v2; + m_stripId = -1; + m_testStripId = -1; + m_experimentId = -1; + m_bIsFake = bIsFake; + } + + // data members are left public + int m_v0, m_v1, m_v2; + int m_stripId; // real strip Id + int m_testStripId; // strip Id in an experiment + int m_experimentId; // in what experiment was it given an experiment Id? + bool m_bIsFake; //if true, will be deleted when the strip it's in is deleted +}; + +// nice and dumb edge class that points knows its +// indices, the two faces, and the next edge using +// the lesser of the indices +class NvEdgeInfo { +public: + + // constructor puts 1 ref on us + NvEdgeInfo (int v0, int v1){ + m_v0 = v0; + m_v1 = v1; + m_face0 = NULL; + m_face1 = NULL; + m_nextV0 = NULL; + m_nextV1 = NULL; + + // we will appear in 2 lists. this is a good + // way to make sure we delete it the second time + // we hit it in the edge infos + m_refCount = 2; + + } + + // ref and unref + void Unref () { if (--m_refCount == 0) delete this; } + + // data members are left public + unsigned int m_refCount; + NvFaceInfo *m_face0, *m_face1; + int m_v0, m_v1; + NvEdgeInfo *m_nextV0, *m_nextV1; +}; + + +// This class is a quick summary of parameters used +// to begin a triangle strip. Some operations may +// want to create lists of such items, so they were +// pulled out into a class +class NvStripStartInfo { +public: + NvStripStartInfo(NvFaceInfo *startFace, NvEdgeInfo *startEdge, bool toV1){ + m_startFace = startFace; + m_startEdge = startEdge; + m_toV1 = toV1; + } + NvFaceInfo *m_startFace; + NvEdgeInfo *m_startEdge; + bool m_toV1; +}; + + +typedef std::vector<NvFaceInfo*> NvFaceInfoVec; +typedef std::list <NvFaceInfo*> NvFaceInfoList; +typedef std::list <NvFaceInfoVec*> NvStripList; +typedef std::vector<NvEdgeInfo*> NvEdgeInfoVec; + +typedef std::vector<short> WordVec; +typedef std::vector<int> IntVec; +typedef std::vector<MyVertex> MyVertexVec; +typedef std::vector<MyFace> MyFaceVec; + +template<class T> +inline void SWAP(T& first, T& second) +{ + T temp = first; + first = second; + second = temp; +} + +// This is a summary of a strip that has been built +class NvStripInfo { +public: + + // A little information about the creation of the triangle strips + NvStripInfo(const NvStripStartInfo &startInfo, int stripId, int experimentId = -1) : + m_startInfo(startInfo) + { + m_stripId = stripId; + m_experimentId = experimentId; + visited = false; + m_numDegenerates = 0; + } + + // This is an experiment if the experiment id is >= 0 + inline bool IsExperiment () const { return m_experimentId >= 0; } + + inline bool IsInStrip (const NvFaceInfo *faceInfo) const + { + if(faceInfo == NULL) + return false; + + return (m_experimentId >= 0 ? faceInfo->m_testStripId == m_stripId : faceInfo->m_stripId == m_stripId); + } + + bool SharesEdge(const NvFaceInfo* faceInfo, NvEdgeInfoVec &edgeInfos); + + // take the given forward and backward strips and combine them together + void Combine(const NvFaceInfoVec &forward, const NvFaceInfoVec &backward); + + //returns true if the face is "unique", i.e. has a vertex which doesn't exist in the faceVec + bool Unique(NvFaceInfoVec& faceVec, NvFaceInfo* face); + + // mark the triangle as taken by this strip + bool IsMarked (NvFaceInfo *faceInfo); + void MarkTriangle(NvFaceInfo *faceInfo); + + // build the strip + void Build(NvEdgeInfoVec &edgeInfos, NvFaceInfoVec &faceInfos); + + // public data members + NvStripStartInfo m_startInfo; + NvFaceInfoVec m_faces; + int m_stripId; + int m_experimentId; + + bool visited; + + int m_numDegenerates; +}; + +typedef std::vector<NvStripInfo*> NvStripInfoVec; + + +//The actual stripifier +class NvStripifier { +public: + + // Constructor + NvStripifier(); + ~NvStripifier(); + + //the target vertex cache size, the structure to place the strips in, and the input indices + void Stripify(const WordVec &in_indices, const int in_cacheSize, const int in_minStripLength, + const unsigned short maxIndex, NvStripInfoVec &allStrips, NvFaceInfoVec &allFaces); + void CreateStrips(const NvStripInfoVec& allStrips, IntVec& stripIndices, const bool bStitchStrips, unsigned int& numSeparateStrips, const bool bRestart, const unsigned int restartVal); + + static int GetUniqueVertexInB(NvFaceInfo *faceA, NvFaceInfo *faceB); + //static int GetSharedVertex(NvFaceInfo *faceA, NvFaceInfo *faceB); + static void GetSharedVertices(NvFaceInfo *faceA, NvFaceInfo *faceB, int* vertex0, int* vertex1); + + static bool IsDegenerate(const NvFaceInfo* face); + static bool IsDegenerate(const unsigned short v0, const unsigned short v1, const unsigned short v2); + +protected: + + WordVec indices; + int cacheSize; + int minStripLength; + float meshJump; + bool bFirstTimeResetPoint; + + ///////////////////////////////////////////////////////////////////////////////// + // + // Big mess of functions called during stripification + // + ///////////////////////////////////////////////////////////////////////////////// + + //******************** + bool IsMoneyFace(const NvFaceInfo& face); + bool FaceContainsIndex(const NvFaceInfo& face, const unsigned int index); + + bool IsCW(NvFaceInfo *faceInfo, int v0, int v1); + bool NextIsCW(const int numIndices); + + static int GetNextIndex(const WordVec &indices, NvFaceInfo *face); + static NvEdgeInfo *FindEdgeInfo(NvEdgeInfoVec &edgeInfos, int v0, int v1); + static NvFaceInfo *FindOtherFace(NvEdgeInfoVec &edgeInfos, int v0, int v1, NvFaceInfo *faceInfo); + NvFaceInfo *FindGoodResetPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos); + + void FindAllStrips(NvStripInfoVec &allStrips, NvFaceInfoVec &allFaceInfos, NvEdgeInfoVec &allEdgeInfos, int numSamples); + void SplitUpStripsAndOptimize(NvStripInfoVec &allStrips, NvStripInfoVec &outStrips, NvEdgeInfoVec& edgeInfos, NvFaceInfoVec& outFaceList); + void RemoveSmallStrips(NvStripInfoVec& allStrips, NvStripInfoVec& allBigStrips, NvFaceInfoVec& faceList); + + bool FindTraversal(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, NvStripInfo *strip, NvStripStartInfo &startInfo); + int CountRemainingTris(std::list<NvStripInfo*>::iterator iter, std::list<NvStripInfo*>::iterator end); + + void CommitStrips(NvStripInfoVec &allStrips, const NvStripInfoVec &strips); + + float AvgStripSize(const NvStripInfoVec &strips); + int FindStartPoint(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos); + + void UpdateCacheStrip(VertexCache* vcache, NvStripInfo* strip); + void UpdateCacheFace(VertexCache* vcache, NvFaceInfo* face); + float CalcNumHitsStrip(VertexCache* vcache, NvStripInfo* strip); + int CalcNumHitsFace(VertexCache* vcache, NvFaceInfo* face); + int NumNeighbors(NvFaceInfo* face, NvEdgeInfoVec& edgeInfoVec); + + void BuildStripifyInfo(NvFaceInfoVec &faceInfos, NvEdgeInfoVec &edgeInfos, const unsigned short maxIndex); + bool AlreadyExists(NvFaceInfo* faceInfo, NvFaceInfoVec& faceInfos); + + // let our strip info classes and the other classes get + // to these protected stripificaton methods if they want + friend class NvStripInfo; +}; + +} //End namespace + +#endif \ No newline at end of file diff --git a/NifExport/NvTriStrip/VertexCache.cpp b/NifExport/NvTriStrip/VertexCache.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a5f0badf87912a01768d94f737eba4e6b13b87fe --- /dev/null +++ b/NifExport/NvTriStrip/VertexCache.cpp @@ -0,0 +1,87 @@ + + +#include "VertexCache.h" +using namespace NvTriStrip; + +VertexCache::VertexCache() +{ + VertexCache(16); +} + + +VertexCache::VertexCache(int size) +{ + numEntries = size; + + entries = new int[numEntries]; + + for(int i = 0; i < numEntries; i++) + entries[i] = -1; +} + + +VertexCache::~VertexCache() +{ + delete[] entries; +} + + +int VertexCache::At(int index) +{ + return entries[index]; +} + + +void VertexCache::Set(int index, int value) +{ + entries[index] = value; +} + + +void VertexCache::Clear() +{ + for(int i = 0; i < numEntries; i++) + entries[i] = -1; +} + +void VertexCache::Copy(VertexCache* inVcache) +{ + for(int i = 0; i < numEntries; i++) + { + inVcache->Set(i, entries[i]); + } +} + +bool VertexCache::InCache(int entry) +{ + bool returnVal = false; + + for(int i = 0; i < numEntries; i++) + { + if(entries[i] == entry) + { + returnVal = true; + break; + } + } + + return returnVal; +} + + +int VertexCache::AddEntry(int entry) +{ + int removed; + + removed = entries[numEntries - 1]; + + //push everything right one + for(int i = numEntries - 2; i >= 0; i--) + { + entries[i + 1] = entries[i]; + } + + entries[0] = entry; + + return removed; +} diff --git a/NifExport/NvTriStrip/VertexCache.h b/NifExport/NvTriStrip/VertexCache.h new file mode 100644 index 0000000000000000000000000000000000000000..dcb075a92e225d435205ae98eacc663aba415121 --- /dev/null +++ b/NifExport/NvTriStrip/VertexCache.h @@ -0,0 +1,31 @@ + +#ifndef VERTEX_CACHE_H + +#define VERTEX_CACHE_H + +namespace NvTriStrip { + +class VertexCache +{ + +public: + VertexCache(int size); + VertexCache(); + ~VertexCache(); + bool InCache(int entry); + int AddEntry(int entry); + void Clear(); + void Copy(VertexCache* inVcache) ; + int At(int index); + void Set(int index, int value); + +private: + + int *entries; + int numEntries; + +}; + +} //End namespace + +#endif diff --git a/NifExport/Strips.cpp b/NifExport/Strips.cpp index 019af369d72126e0754998f1a18d510a0b4a4785..b418cdab7b5c9228f24c9a6da08e705a31a127ae 100755 --- a/NifExport/Strips.cpp +++ b/NifExport/Strips.cpp @@ -1,5 +1,7 @@ #include "pch.h" +#include "NvTriStrip/NvTriStrip.h" +using namespace NvTriStrip; /* using namespace triangle_stripper; @@ -85,7 +87,7 @@ void Exporter::strippify(FaceGroup &grp) data[i * 3 + 2] = grp.faces[i][2]; } - PrimitiveGroup * groups = 0; + PrimitiveGroup * groups = 0; unsigned short numGroups = 0; // GF 3+ diff --git a/NifExport/Util.cpp b/NifExport/Util.cpp index 6f98c6f9df0c95059d6b83d2ae3d1c68fe66f150..2a356c03e3f3ee8bdbaf852b52293a02d170e308 100755 --- a/NifExport/Util.cpp +++ b/NifExport/Util.cpp @@ -228,7 +228,7 @@ bool Exporter::removeUnreferencedBones(NiNodeRef node) { NiAVObjectRef& child = (*itr); bool childRemove = false; - if (child->IsDerivedType(NiNode::TypeConst())) + if (child->IsDerivedType(NiNode::TYPE)) { childRemove = removeUnreferencedBones(StaticCast<NiNode>(child)); } diff --git a/NifFurniture/NifFurniture.cpp b/NifFurniture/NifFurniture.cpp index d80d111c3d61954d9b88d6b1a53d4f9edd9d3efd..d4f3d5ca06d0383dd412bb140c9d7f11967696ab 100755 --- a/NifFurniture/NifFurniture.cpp +++ b/NifFurniture/NifFurniture.cpp @@ -252,7 +252,12 @@ int NifFurnitureMarker::Display(TimeValue t, INode* inode, ViewExp *vpt, int fla Material *mtl = gw->getMaterial(); DWORD rlim = gw->getRndLimits(); - gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY|GW_BACKCULL); + + DWORD newrlim = GW_WIREFRAME|GW_BACKCULL; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + newrlim |= GW_EDGES_ONLY; +#endif + gw->setRndLimits(newrlim); GetMat(t, inode, vpt, m); m.Scale(mFlip); diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp index adb3da66a79a47618ecf54e0310c57e79abbf4aa..6e0e27a4fd766e88bc0fdf5f677fa4dc4c8fc117 100644 --- a/NifImport/ImportAnimation.cpp +++ b/NifImport/ImportAnimation.cpp @@ -11,7 +11,7 @@ HISTORY: *> Copyright (c) 2006, All Rights Reserved. **********************************************************************/ #include "stdafx.h" -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 6+ +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7 # include <IFrameTagManager.h> #endif #include <notetrck.h> @@ -181,7 +181,7 @@ void NifImporter::ClearAnimation() { if (clearAnimation) { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7 if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) { int n = tagMgr->GetTagCount(); @@ -430,7 +430,7 @@ bool NifImporter::AddNoteTracks(float time, string name, string target, NiTextKe } if (addTimeTags) { -#if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 5 +#if VERSION_3DSMAX >= ((7000<<16)+(15<<8)+0) // Version 7 if (IFrameTagManager *tagMgr = (IFrameTagManager*)GetCOREInterface(FRAMETAGMANAGER_INTERFACE)) { for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) { tagMgr->CreateNewTag(const_cast<TCHAR*>((*itr).data.c_str()), TimeToFrame(time + (*itr).time), 0, FALSE); @@ -539,7 +539,7 @@ bool AnimationImport::GetTransformData(ControllerLink& lnk, string name, NiKeyfr if (npoints > 3) { - NiKeyframeDataRef data = CreateBlock("NiKeyframeData"); + NiKeyframeDataRef data = CreateNiObject<NiKeyframeData>(); data->SetRotateType(QUADRATIC_KEY); data->SetTranslateType(QUADRATIC_KEY); data->SetScaleType(QUADRATIC_KEY); diff --git a/NifImport/ImportCollision.cpp b/NifImport/ImportCollision.cpp index 53d6aed4e49f323fe33889b4fa812a6c00b86680..22f17b314ff46c0e4e04edbbd42cc951976e3e51 100644 --- a/NifImport/ImportCollision.cpp +++ b/NifImport/ImportCollision.cpp @@ -56,10 +56,10 @@ bool NifImporter::ImportCollision(NiNodeRef node) if (collObj) { CollisionImport ci(*this); - if (INode *inode = FindINode(gi, collObj->GetParent())) + if (INode *inode = FindINode(gi, collObj->GetTarget())) { NiObjectRef body = collObj->GetBody(); - if (body->IsDerivedType(bhkRigidBody::TypeConst())) + if (body->IsDerivedType(bhkRigidBody::TYPE)) { ci.ImportRigidBody(bhkRigidBodyRef(body), inode); } @@ -113,15 +113,15 @@ bool CollisionImport::ImportRigidBody(bhkRigidBodyRef body, INode* node) bool CollisionImport::ImportShape(bhkRigidBodyRef body, bhkShapeRef shape, INode* parent) { INode *shapeNode = NULL; - if (shape->IsDerivedType(bhkCapsuleShape::TypeConst())) + if (shape->IsDerivedType(bhkCapsuleShape::TYPE)) { shapeNode = ImportCapsule(body, bhkCapsuleShapeRef(shape), parent); } - else if (shape->IsDerivedType(bhkSphereShape::TypeConst())) + else if (shape->IsDerivedType(bhkSphereShape::TYPE)) { shapeNode = ImportSphere(body, bhkSphereShapeRef(shape), parent); } - else if (shape->IsDerivedType(bhkConvexVerticesShape::TypeConst())) + else if (shape->IsDerivedType(bhkConvexVerticesShape::TYPE)) { shapeNode = ImportConvexVertices(body, bhkConvexVerticesShapeRef(shape), parent); } diff --git a/NifImport/ImportLights.cpp b/NifImport/ImportLights.cpp index a48feb36f440ee9ee66f247d99c056ec2e1da35d..ed67650a86f94d7ef238d12ee1468c2b32782561 100644 --- a/NifImport/ImportLights.cpp +++ b/NifImport/ImportLights.cpp @@ -72,7 +72,7 @@ bool NifImporter::ImportLights(vector<NiLightRef> lights) GenLight *ob = NULL; NiLightRef& light = (*itr); - if (light->IsSameType(NiPointLight::TypeConst())){ + if (light->IsSameType(NiPointLight::TYPE)){ ob = CreateLight(gi, light, OMNI_LIGHT); NiPointLightRef ptLight = light; float c = ptLight->GetConstantAttenuation(); @@ -88,12 +88,12 @@ bool NifImporter::ImportLights(vector<NiLightRef> lights) ob->SetDecayType(2); ob->SetAtten(0, ATTEN_START, 4.0f/(l*l)); } - } else if (light->IsSameType(NiDirectionalLight::TypeConst())){ + } else if (light->IsSameType(NiDirectionalLight::TYPE)){ ob = CreateLight(gi, light, DIR_LIGHT); - } else if (light->IsSameType(NiAmbientLight::TypeConst())){ + } else if (light->IsSameType(NiAmbientLight::TYPE)){ ob = CreateLight(gi, light, OMNI_LIGHT); ob->SetAmbientOnly(TRUE); - } else if (light->IsSameType(NiSpotLight::TypeConst())){ + } else if (light->IsSameType(NiSpotLight::TYPE)){ ob = CreateLight(gi, light, FSPOT_LIGHT); } if (INode *n = gi->CreateObjectNode(ob)) { @@ -108,7 +108,7 @@ bool NifImporter::ImportLights(vector<NiLightRef> lights) Quat q = TOQUAT(rot.AsQuaternion()); PosRotScaleNode(n, p, q, scale, prsDefault); - n->Hide(light->GetHidden() ? TRUE : FALSE); + n->Hide(light->GetVisibility() ? FALSE : TRUE ); } ok = true; } diff --git a/NifImport/ImportMeshAndSkin.cpp b/NifImport/ImportMeshAndSkin.cpp index 5a9094512a4d2415b24926101d75febc99e7707a..552a76fd3f841da4f5c2053760ab7dfa08d971da 100644 --- a/NifImport/ImportMeshAndSkin.cpp +++ b/NifImport/ImportMeshAndSkin.cpp @@ -173,7 +173,7 @@ bool NifImporter::ImportMesh(ImpNode *node, TriObject *o, NiTriBasedGeomRef triG if (INode *parent = GetNode(triGeom->GetParent())) parent->AttachChild(inode, 1); - inode->Hide(triGeom->GetHidden() ? TRUE : FALSE); + inode->Hide(triGeom->GetVisibility() ? FALSE : TRUE); if (enableAutoSmooth){ mesh.AutoSmooth(TORAD(autoSmoothAngle), FALSE, FALSE); @@ -278,7 +278,7 @@ bool NifImporter::ImportMultipleGeometry(NiNodeRef parent, vector<NiTriBasedGeom Matrix44 transform = (*itr)->GetLocalTransform(); //Apply the transformations if (transform != Matrix44::IDENTITY) { - for ( uint i = 0; i < subverts.size(); ++i ) + for ( unsigned int i = 0; i < subverts.size(); ++i ) subverts[i] = transform * subverts[i]; } vert_range.push_back( pair<int,int>( verts.size(), verts.size() + subverts.size()) ); @@ -334,7 +334,7 @@ bool NifImporter::ImportMultipleGeometry(NiNodeRef parent, vector<NiTriBasedGeom vector<Vector3> subnorms = triGeomData->GetNormals(); Matrix44 rotation = (*itr)->GetLocalTransform().GetRotation(); if (rotation != Matrix44::IDENTITY) { - for ( uint i = 0; i < subnorms.size(); ++i ) + for ( unsigned int i = 0; i < subnorms.size(); ++i ) subnorms[i] = rotation * subnorms[i]; } if (!subnorms.empty()) @@ -410,7 +410,7 @@ bool NifImporter::ImportMultipleGeometry(NiNodeRef parent, vector<NiTriBasedGeom // attach child if (INode *parent = GetNode((*itr)->GetParent())) parent->AttachChild(inode, 1); - inode->Hide((*itr)->GetHidden() ? TRUE : FALSE); + inode->Hide((*itr)->GetVisibility() ? FALSE : TRUE); } if (removeDegenerateFaces) mesh.RemoveDegenerateFaces(); @@ -600,8 +600,10 @@ bool NifImporter::ImportSkin(ImpNode *node, NiTriBasedGeomRef triGeom, int v_sta // and the value always seems to be 4 anyway. I'd also this be more dynamic than hard coded numbers // but I cant figure out the correct values to pass the scripting engine from here so I'm giving up. int numWeightsPerVertex = 4; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ IParamBlock2 *params = skinMod->GetParamBlockByID(2/*advanced*/); params->SetValue(0x7/*bone_Limit*/, 0, numWeightsPerVertex); +#endif // Can get some truly bizarre animations without this in MAX with Civ4 Leaderheads #if VERSION_3DSMAX > ((5000<<16)+(15<<8)+0) // Version 6+ @@ -655,6 +657,13 @@ bool NifImporter::ImportSkin(ImpNode *node, NiTriBasedGeomRef triGeom, int v_sta } } + tnode->EvalWorldState(0); + skinMod->DisableModInViews(); + skinMod->EnableModInViews(); +#if VERSION_3DSMAX < ((5000<<16)+(15<<8)+0) // Version 4 + gi->SetCommandPanelTaskMode(TASK_MODE_MODIFY); + gi->SelectNode(tnode); +#endif // Assign the weights for (vector<VertexHolder>::iterator itr=vertexHolders.begin(), end=vertexHolders.end(); itr != end; ++itr){ VertexHolder& h = (*itr); diff --git a/NifImport/ImportMtlAndTex.cpp b/NifImport/ImportMtlAndTex.cpp index 2a7e698181f7ca136aa10608c90e9084f61fed61..7664618449e377588d3b7d907336987e03d69fb6 100644 --- a/NifImport/ImportMtlAndTex.cpp +++ b/NifImport/ImportMtlAndTex.cpp @@ -27,7 +27,7 @@ Texmap* NifImporter::CreateTexture(TexDesc& desc) { BitmapManager *bmpMgr = TheManager; if (NiSourceTextureRef texSrc = desc.source){ - string filename = texSrc->GetExternalFileName(); + string filename = texSrc->GetTextureFileName(); if (bmpMgr->CanImport(filename.c_str())){ BitmapTex *bmpTex = NewDefaultBitmapTex(); string name = texSrc->GetName(); @@ -83,13 +83,13 @@ Texmap* NifImporter::CreateTexture(TexDesc& desc) StdMat2 *NifImporter::ImportMaterialAndTextures(ImpNode *node, NiAVObjectRef avObject) { // Texture - NiMaterialPropertyRef matRef = avObject->GetPropertyByType(NiMaterialProperty::TypeConst()); + NiMaterialPropertyRef matRef = avObject->GetPropertyByType(NiMaterialProperty::TYPE); if (matRef != NULL){ - NiTexturingPropertyRef texRef = avObject->GetPropertyByType(NiTexturingProperty::TypeConst()); - NiWireframePropertyRef wireRef = avObject->GetPropertyByType(NiWireframeProperty::TypeConst()); - NiAlphaPropertyRef alphaRef = avObject->GetPropertyByType(NiAlphaProperty::TypeConst()); - NiStencilPropertyRef stencilRef = avObject->GetPropertyByType(NiStencilProperty::TypeConst()); - NiShadePropertyRef shadeRef = avObject->GetPropertyByType(NiShadeProperty::TypeConst()); + NiTexturingPropertyRef texRef = avObject->GetPropertyByType(NiTexturingProperty::TYPE); + NiWireframePropertyRef wireRef = avObject->GetPropertyByType(NiWireframeProperty::TYPE); + NiAlphaPropertyRef alphaRef = avObject->GetPropertyByType(NiAlphaProperty::TYPE); + NiStencilPropertyRef stencilRef = avObject->GetPropertyByType(NiStencilProperty::TYPE); + NiShadePropertyRef shadeRef = avObject->GetPropertyByType(NiShadeProperty::TYPE); StdMat2 *m = NewDefaultStdMat(); m->SetName(matRef->GetName().c_str()); @@ -120,7 +120,7 @@ StdMat2 *NifImporter::ImportMaterialAndTextures(ImpNode *node, NiAVObjectRef avO m->SetWire(value); } if (stencilRef != NULL) { - if (stencilRef->GetDrawMode() == 3 /*DRAW_BOTH*/) { + if (stencilRef->GetFaceDrawMode() == DRAW_BOTH) { BOOL value = TRUE; m->SetTwoSided(value); } @@ -267,22 +267,22 @@ bool NifImporter::ImportCiv4Shader(ImpNode *node, NiAVObjectRef avObject, StdMat setMAXScriptValue(ref, "Vertex_Color_Enable", 0, VertexColorsEnable); } if (NiAlphaPropertyRef alphaRef = SelectFirstObjectOfType<NiAlphaProperty>(props)) { - int TestRef = alphaRef->GetAlphaTestThreshold(); - int srcBlend = alphaRef->GetSourceBlendMode(); - int destBlend = alphaRef->GetDestBlendMode(); - int TestMode = alphaRef->GetTestMode(); - bool AlphaTestEnable = alphaRef->GetAlphaTest(); - bool NoSorter = !alphaRef->GetAlphaSort(); - bool alphaBlend = alphaRef->GetAlphaBlend(); + int TestRef = alphaRef->GetTestThreshold(); + int srcBlend = alphaRef->GetSourceBlendFunc(); + int destBlend = alphaRef->GetSourceBlendFunc (); + int TestMode = alphaRef->GetTestFunc(); + bool AlphaTestEnable = alphaRef->GetTestState(); + bool NoSorter = !alphaRef->GetTriangleSortMode(); + bool alphaBlend = alphaRef->GetBlendState(); int alphaMode = 1; if (!alphaBlend) { alphaMode = 1; // none - } else if (srcBlend == NiAlphaProperty::BM_SRC_ALPHA && destBlend == NiAlphaProperty::BM_ONE_MINUS_SRC_ALPHA) { + } else if (srcBlend == NiAlphaProperty::BF_SRC_ALPHA && destBlend == NiAlphaProperty::BF_ONE_MINUS_SRC_ALPHA) { alphaMode = 0; // standard or automatic? - } else if (srcBlend == NiAlphaProperty::BM_ONE && destBlend == NiAlphaProperty::BM_ONE) { + } else if (srcBlend == NiAlphaProperty::BF_ONE && destBlend == NiAlphaProperty::BF_ONE) { alphaMode = 3; - } else if (srcBlend == NiAlphaProperty::BM_ZERO && destBlend == NiAlphaProperty::BM_SRC_COLOR) { + } else if (srcBlend == NiAlphaProperty::BF_ZERO && destBlend == NiAlphaProperty::BF_SRC_COLOR) { alphaMode = 4; } else { alphaMode = 5; diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp index e5f5b6013701b8d302197b154fe4a8018b03b23c..960529025b3eeafcc3d03fb239c5abf81221c7df 100644 --- a/NifImport/ImportSkeleton.cpp +++ b/NifImport/ImportSkeleton.cpp @@ -36,7 +36,7 @@ struct NiNodeNameEquivalence : public NumericStringEquivalence void GoToSkeletonBindPosition(vector<NiNodeRef>& blocks) { //Send all skeleton roots to bind position - for (uint i = 0; i < blocks.size(); ++i) { + for (unsigned int i = 0; i < blocks.size(); ++i) { NiNodeRef node = blocks[i]; if ( node != NULL && node->IsSkeletonRoot() ) { node->GoToSkeletonBindPosition(); @@ -481,6 +481,7 @@ INode *NifImporter::CreateBone(const string& name, Point3 startPos, Point3 endPo if (INode *n = result.n) { n->SetName(const_cast<TCHAR*>(name.c_str())); + float len = Length(endPos-startPos); float width = max(minBoneWidth, min(maxBoneWidth, len * boneWidthToLengthRatio)); if (Object* o = n->GetObjectRef()) @@ -573,7 +574,7 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) vector<NiAVObjectRef> children = node->GetChildren(); vector<NiNodeRef> childNodes = DynamicCast<NiNode>(children); - NiAVObject::CollisionType cType = node->GetCollision(); + NiAVObject::CollisionType cType = node->GetCollisionMode(); if (children.empty() && name=="Bounding Box") return; @@ -654,13 +655,13 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) { bool isDummy = ( (uncontrolledDummies && !HasControllerRef(ctrlCount, name)) || (!dummyNodeMatches.empty() && wildmatch(dummyNodeMatches, name)) - || (convertBillboardsToDummyNodes && node->IsDerivedType(NiBillboardNode::TypeConst())) + || (convertBillboardsToDummyNodes && node->IsDerivedType(NiBillboardNode::TYPE)) ); if (wildmatch("Camera*", name)) { if (enableCameras) { if (bone = CreateCamera(name)) { PosRotScaleNode(bone, p, q, scale, prs); - bone->Hide(node->GetHidden() ? TRUE : FALSE); + bone->Hide(node->GetVisibility() ? FALSE : TRUE); } } }else if (isDummy && createNubsForBones) @@ -668,7 +669,7 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) else if (bone = CreateBone(name, p, pp, zAxis)) { PosRotScaleNode(bone, p, q, scale, prs); - bone->Hide(node->GetHidden() ? TRUE : FALSE); + bone->Hide(node->GetVisibility() ? FALSE : TRUE); } if (bone) { diff --git a/NifImport/MaxNifImport.cpp b/NifImport/MaxNifImport.cpp index b1903c756fbd535f75290e4a368008dcae95275f..3202ae7290329f8287df814c488e3dcfede55dd5 100644 --- a/NifImport/MaxNifImport.cpp +++ b/NifImport/MaxNifImport.cpp @@ -38,6 +38,13 @@ class MaxNifImport : public SceneImport { unsigned int Version(); // Version number * 100 (i.e. v3.01 = 301) void ShowAbout(HWND hWnd); // Show DLL's "About..." box int DoImport(const TCHAR *name,ImpInterface *i,Interface *gi, BOOL suppressPrompts=FALSE); // Import file + + SDK_RESERVED_METHOD(1); // russom 02/26/01 + SDK_RESERVED_METHOD(2); // russom 02/26/01 + SDK_RESERVED_METHOD(3); // russom 02/26/01 + SDK_RESERVED_METHOD(4); // russom 02/26/01 + SDK_RESERVED_METHOD(5); // russom 02/26/01 + SDK_RESERVED_METHOD(6); // russom 02/26/01 //Constructor/Destructor MaxNifImport(); @@ -72,17 +79,7 @@ MaxNifImport::MaxNifImport() { Interface *gi = GetCOREInterface(); TCHAR iniName[MAX_PATH]; - if (gi) { - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); - } else { - GetModuleFileName(NULL, iniName, _countof(iniName)); - if (LPTSTR fname = PathFindFileName(iniName)) - fname = NULL; - PathAddBackslash(iniName); - PathAppend(iniName, "plugcfg"); - PathAppend(iniName, "MaxNifTools.ini"); - } + GetIniFileName(iniName); iniFileName = iniName; shortDescription = GetIniValue<TSTR>("System", "ShortDescription", "Netimmerse/Gamebryo", iniFileName.c_str()); webSite = GetIniValue<TSTR>("System", "Website", "http://www.niftools.org", iniFileName.c_str()); diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp index a49134caec06d393830119f1854f86b8644b5189..628e43c941eb9f2edfcf66680cfff904241d49b5 100644 --- a/NifImport/NIFImport.cpp +++ b/NifImport/NIFImport.cpp @@ -108,8 +108,7 @@ string NifImporter::GetSkeleton(AppSettings *appSettings) void NifImporter::LoadIniSettings() { TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + GetIniFileName(iniName); this->iniFileName = iniName; iniFileValid = (-1 != _access(iniName, 0)); @@ -283,7 +282,7 @@ bool NifImporter::DoImport() if (isValid()) { - if (root->IsDerivedType(NiNode::TypeConst())) + if (root->IsDerivedType(NiNode::TYPE)) { NiNodeRef rootNode = root; @@ -317,11 +316,11 @@ bool NifImporter::DoImport() } } } - else if (root->IsDerivedType(NiTriShape::TypeConst())) + else if (root->IsDerivedType(NiTriShape::TYPE)) { ok |= ImportMesh(NiTriShapeRef(root)); } - else if (root->IsDerivedType(NiTriStrips::TypeConst())) + else if (root->IsDerivedType(NiTriStrips::TYPE)) { ok |= ImportMesh(NiTriStripsRef(root)); } diff --git a/NifPlugins/DllEntry.cpp b/NifPlugins/DllEntry.cpp index 3beef1029ce9b0960b4bef717f031f0dd46ffd16..90bc9d0b8afbe9e04cc36889646e0765c68683b6 100644 --- a/NifPlugins/DllEntry.cpp +++ b/NifPlugins/DllEntry.cpp @@ -20,6 +20,7 @@ extern ClassDesc2* GetbhkSphereDesc(); extern ClassDesc2* GetbhkCapsuleDesc(); extern ClassDesc2* GetbhkRigidBodyModifierDesc(); extern ClassDesc2* GetbhkBoxDesc(); +extern ClassDesc* GetDDSLibClassDesc(); enum ClassDescType { @@ -66,19 +67,8 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) void InitializeLibSettings() { - Interface *gi = GetCOREInterface(); TCHAR iniName[MAX_PATH]; - if (gi) { - LPCTSTR pluginDir = gi->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); - } else { - GetModuleFileName(NULL, iniName, _countof(iniName)); - if (LPTSTR fname = PathFindFileName(iniName)) - *fname = 0; - PathAddBackslash(iniName); - PathAppend(iniName, "plugcfg"); - PathAppend(iniName, "MaxNifTools.ini"); - } + GetIniFileName(iniName); libVersion = GetIniValue("System", "MaxSDKVersion", libVersion, iniName); if (libVersion == 0) libVersion = VERSION_3DSMAX; @@ -110,6 +100,9 @@ void InitializeLibSettings() classDescEnabled[CD_KFExport] = true; classDescriptions[nClasses++] = GetKfExportDesc(); } +#ifdef GAME_VER + classDescriptions[nClasses++] = (ClassDesc2 *)GetDDSLibClassDesc(); +#endif } // This function returns a string that describes the DLL and where the user diff --git a/NifPlugins_VC80.sln b/NifPlugins_VC80.sln index edd13349535598cd4864b47e04fce8c518c16618..edda3730668d56307b01ab76fadddfd962443d89 100644 --- a/NifPlugins_VC80.sln +++ b/NifPlugins_VC80.sln @@ -1,6 +1,6 @@ Microsoft Visual Studio Solution File, Format Version 9.00 # Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NIFlib", "..\niflib\niflib.vcproj", "{19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Niflib", "..\niflib\niflib.vcproj", "{19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{50B67748-0DFB-45B0-BF1F-E80135EE3823}" ProjectSection(SolutionItems) = preProject @@ -17,6 +17,12 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NifPlugins", "NifPlugins_VC EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug - gmax|Win32 = Debug - gmax|Win32 + Debug - gmax|x64 = Debug - gmax|x64 + Debug - Max 4.2|Win32 = Debug - Max 4.2|Win32 + Debug - Max 4.2|x64 = Debug - Max 4.2|x64 + Debug - Max 4|Win32 = Debug - Max 4|Win32 + Debug - Max 4|x64 = Debug - Max 4|x64 Debug - Max 5|Win32 = Debug - Max 5|Win32 Debug - Max 5|x64 = Debug - Max 5|x64 Debug - Max 6|Win32 = Debug - Max 6|Win32 @@ -27,6 +33,12 @@ Global Debug - Max 8|x64 = Debug - Max 8|x64 Debug - Max 9|Win32 = Debug - Max 9|Win32 Debug - Max 9|x64 = Debug - Max 9|x64 + Release - gmax|Win32 = Release - gmax|Win32 + Release - gmax|x64 = Release - gmax|x64 + Release - Max 4.2|Win32 = Release - Max 4.2|Win32 + Release - Max 4.2|x64 = Release - Max 4.2|x64 + Release - Max 4|Win32 = Release - Max 4|Win32 + Release - Max 4|x64 = Release - Max 4|x64 Release - Max 5|Win32 = Release - Max 5|Win32 Release - Max 5|x64 = Release - Max 5|x64 Release - Max 6|Win32 = Release - Max 6|Win32 @@ -39,36 +51,63 @@ Global Release - Max 9|x64 = Release - Max 9|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|Win32.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|Win32.Build.0 = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|x64.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|Win32.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|Win32.Build.0 = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|x64.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|Win32.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|Win32.Build.0 = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|x64.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|Win32.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|Win32.Build.0 = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|x64.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|Win32.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|Win32.Build.0 = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|x64.ActiveCfg = Debug - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|Win32.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|Win32.Build.0 = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|x64.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|Win32.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|Win32.Build.0 = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|x64.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|Win32.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|Win32.Build.0 = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|x64.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|Win32.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|Win32.Build.0 = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|x64.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|Win32.ActiveCfg = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|Win32.Build.0 = Release - PCH|Win32 - {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|x64.ActiveCfg = Release - PCH|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - gmax|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - gmax|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - gmax|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4.2|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4.2|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4.2|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 4|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 5|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 6|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 7|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 8|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|Win32.ActiveCfg = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|Win32.Build.0 = Debug - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Debug - Max 9|x64.ActiveCfg = Debug - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - gmax|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - gmax|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - gmax|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4.2|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4.2|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4.2|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 4|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 5|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 6|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 7|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 8|x64.ActiveCfg = Release - DLL|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|Win32.ActiveCfg = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|Win32.Build.0 = Release - Static|Win32 + {19FD8EE6-79CC-4BAC-9744-D9573BE47C7E}.Release - Max 9|x64.ActiveCfg = Release - DLL|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - gmax|Win32.ActiveCfg = Debug - gmax|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - gmax|Win32.Build.0 = Debug - gmax|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - gmax|x64.ActiveCfg = Debug - Max 5|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4.2|Win32.ActiveCfg = Debug - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4.2|Win32.Build.0 = Debug - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4.2|x64.ActiveCfg = Debug - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4|Win32.ActiveCfg = Debug - Max 4|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4|Win32.Build.0 = Debug - Max 4|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 4|x64.ActiveCfg = Debug - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 5|Win32.ActiveCfg = Debug - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 5|Win32.Build.0 = Debug - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 5|x64.ActiveCfg = Debug - Max 5|Win32 @@ -84,6 +123,15 @@ Global {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 9|Win32.ActiveCfg = Debug - Max 9|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 9|Win32.Build.0 = Debug - Max 9|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Debug - Max 9|x64.ActiveCfg = Debug - Max 9|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - gmax|Win32.ActiveCfg = Release - gmax|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - gmax|Win32.Build.0 = Release - gmax|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - gmax|x64.ActiveCfg = Release - Max 5|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4.2|Win32.ActiveCfg = Release - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4.2|Win32.Build.0 = Release - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4.2|x64.ActiveCfg = Release - Max 4.2|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4|Win32.ActiveCfg = Release - Max 4|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4|Win32.Build.0 = Release - Max 4|Win32 + {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 4|x64.ActiveCfg = Release - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 5|Win32.ActiveCfg = Release - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 5|Win32.Build.0 = Release - Max 5|Win32 {466F2D3E-2663-4583-A05C-128683677617}.Release - Max 5|x64.ActiveCfg = Release - Max 5|Win32 diff --git a/NifPlugins_VC80.vcproj b/NifPlugins_VC80.vcproj index 0de9f6b8547c9877b76aeddce8612f31bfb9b0fc..97163782a2ea766a75941241020acd1a023710c1 100644 --- a/NifPlugins_VC80.vcproj +++ b/NifPlugins_VC80.vcproj @@ -50,7 +50,7 @@ AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" InlineFunctionExpansion="2" AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;NIFLIB_STATIC_LINK" StringPooling="true" ExceptionHandling="2" RuntimeLibrary="0" @@ -78,18 +78,638 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax6\plugins\NifPlugins.dlu" + LinkIncremental="1" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax6\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + SetChecksum="true" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" + /> + </Configuration> + <Configuration + Name="Debug - Max 6|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + Optimization="0" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;NIFLIB_STATIC_LINK" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + ExceptionHandling="2" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" OutputFile="C:\3dsmax6\plugins\NifPlugins.dlu" + LinkIncremental="2" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax6\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="" + /> + </Configuration> + <Configuration + Name="Release - Max 7|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + WholeProgramOptimization="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="NDEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED;NIFLIB_STATIC_LINK" + StringPooling="true" + ExceptionHandling="2" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax7\plugins\NifPlugins.dlu" LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax6\maxsdk\lib;..\niflib\lib" + AdditionalLibraryDirectories="C:\3dsmax7\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + SetChecksum="true" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" + /> + </Configuration> + <Configuration + Name="Debug - Max 7|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + Optimization="0" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED;NIFLIB_STATIC_LINK" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + ExceptionHandling="2" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax7\plugins\NifPlugins.dlu" + LinkIncremental="2" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax7\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="" + /> + </Configuration> + <Configuration + Name="Release - Max 8|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + WholeProgramOptimization="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + CommandLine="" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="NDEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED;NIFLIB_STATIC_LINK" + StringPooling="true" + ExceptionHandling="2" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="NDEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax8\plugins\NifPlugins.dlu" + LinkIncremental="1" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax8\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + SetChecksum="true" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" + /> + </Configuration> + <Configuration + Name="Debug - Max 8|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + Optimization="0" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED;NIFLIB_STATIC_LINK" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + ExceptionHandling="2" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax8\plugins\NifPlugins.dlu" + LinkIncremental="2" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax8\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" + ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" + GenerateDebugInformation="true" + ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" + SubSystem="2" + BaseAddress="0x16860000" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCWebDeploymentTool" + /> + <Tool + Name="VCPostBuildEventTool" + CommandLine="" + /> + </Configuration> + <Configuration + Name="Debug - Max 5|Win32" + OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" + IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" + ConfigurationType="2" + InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" + UseOfMFC="0" + ATLMinimizesCRunTimeLibraryUsage="false" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + PreprocessorDefinitions="_DEBUG" + MkTypLibCompatible="true" + SuppressStartupBanner="true" + TargetEnvironment="1" + TypeLibraryName="$(OutDir)NifPlugins.tlb" + /> + <Tool + Name="VCCLCompilerTool" + AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + Optimization="0" + InlineFunctionExpansion="2" + AdditionalIncludeDirectories="C:\3dsmax5\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;NIFLIB_STATIC_LINK" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + ExceptionHandling="2" + BasicRuntimeChecks="3" + RuntimeLibrary="1" + ForceConformanceInForLoopScope="false" + UsePrecompiledHeader="2" + PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" + WarningLevel="3" + SuppressStartupBanner="true" + DebugInformationFormat="3" + CompileAs="0" + DisableSpecificWarnings="4244;4018" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + Culture="1033" + AdditionalIncludeDirectories=".\NifCommon" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + AdditionalOptions="/MACHINE:I386" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax5\plugins\NifPlugins.dlu" + LinkIncremental="2" + SuppressStartupBanner="true" + AdditionalLibraryDirectories="C:\3dsmax5\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" SubSystem="2" - OptimizeReferences="2" - EnableCOMDATFolding="2" - SetChecksum="true" BaseAddress="0x16860000" /> <Tool @@ -115,23 +735,25 @@ /> <Tool Name="VCPostBuildEventTool" - CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" + CommandLine="" /> </Configuration> <Configuration - Name="Debug - Max 6|Win32" + Name="Release - Max 5|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" + WholeProgramOptimization="0" > <Tool Name="VCPreBuildEventTool" /> <Tool Name="VCCustomBuildTool" + CommandLine="" /> <Tool Name="VCXMLDataGeneratorTool" @@ -141,7 +763,7 @@ /> <Tool Name="VCMIDLTool" - PreprocessorDefinitions="_DEBUG" + PreprocessorDefinitions="NDEBUG" MkTypLibCompatible="true" SuppressStartupBanner="true" TargetEnvironment="1" @@ -150,15 +772,13 @@ <Tool Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" - Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax6\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE" - GeneratePreprocessedFile="0" - MinimalRebuild="true" + AdditionalIncludeDirectories="C:\3dsmax5\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;NIFLIB_STATIC_LINK" + StringPooling="true" ExceptionHandling="2" - BasicRuntimeChecks="3" - RuntimeLibrary="1" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" ForceConformanceInForLoopScope="false" UsePrecompiledHeader="2" PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" @@ -172,7 +792,7 @@ /> <Tool Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + PreprocessorDefinitions="NDEBUG;NIFPLUGINS" Culture="1033" AdditionalIncludeDirectories=".\NifCommon" /> @@ -182,16 +802,19 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflibd.lib" - OutputFile="C:\3dsmax6\plugins\NifPlugins.dlu" - LinkIncremental="2" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax5\plugins\NifPlugins.dlu" + LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax6\maxsdk\lib;..\niflib\lib" - IgnoreDefaultLibraryNames="msvcrtd.lib" + AdditionalLibraryDirectories="C:\3dsmax5\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + SetChecksum="true" BaseAddress="0x16860000" /> <Tool @@ -217,25 +840,24 @@ /> <Tool Name="VCPostBuildEventTool" - CommandLine="" + CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" /> </Configuration> <Configuration - Name="Release - Max 7|Win32" + Name="Debug - Max 9|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" - WholeProgramOptimization="0" + CharacterSet="2" > <Tool Name="VCPreBuildEventTool" /> <Tool Name="VCCustomBuildTool" - CommandLine="" /> <Tool Name="VCXMLDataGeneratorTool" @@ -245,7 +867,7 @@ /> <Tool Name="VCMIDLTool" - PreprocessorDefinitions="NDEBUG" + PreprocessorDefinitions="_DEBUG" MkTypLibCompatible="true" SuppressStartupBanner="true" TargetEnvironment="1" @@ -254,13 +876,15 @@ <Tool Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" + Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED" - StringPooling="true" - ExceptionHandling="2" - RuntimeLibrary="0" - EnableFunctionLevelLinking="true" + AdditionalIncludeDirectories="C:\3dsmax9\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED;NIFLIB_STATIC_LINK" + GeneratePreprocessedFile="0" + MinimalRebuild="true" + ExceptionHandling="1" + BasicRuntimeChecks="3" + RuntimeLibrary="1" ForceConformanceInForLoopScope="false" UsePrecompiledHeader="2" PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" @@ -274,7 +898,7 @@ /> <Tool Name="VCResourceCompilerTool" - PreprocessorDefinitions="NDEBUG;NIFPLUGINS" + PreprocessorDefinitions="_DEBUG;NIFPLUGINS" Culture="1033" AdditionalIncludeDirectories=".\NifCommon" /> @@ -284,18 +908,16 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib" - OutputFile="C:\3dsmax7\plugins\NifPlugins.dlu" - LinkIncremental="1" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax9\plugins\NifPlugins.dlu" + LinkIncremental="2" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax7\maxsdk\lib;..\niflib\lib" + AdditionalLibraryDirectories="C:\3dsmax9\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" SubSystem="2" - OptimizeReferences="2" - EnableCOMDATFolding="2" - SetChecksum="true" BaseAddress="0x16860000" /> <Tool @@ -321,23 +943,25 @@ /> <Tool Name="VCPostBuildEventTool" - CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" + CommandLine="" /> </Configuration> <Configuration - Name="Debug - Max 7|Win32" + Name="Release - Max 9|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops" UseOfMFC="0" ATLMinimizesCRunTimeLibraryUsage="false" + WholeProgramOptimization="0" > <Tool Name="VCPreBuildEventTool" /> <Tool Name="VCCustomBuildTool" + CommandLine="" /> <Tool Name="VCXMLDataGeneratorTool" @@ -347,7 +971,7 @@ /> <Tool Name="VCMIDLTool" - PreprocessorDefinitions="_DEBUG" + PreprocessorDefinitions="NDEBUG" MkTypLibCompatible="true" SuppressStartupBanner="true" TargetEnvironment="1" @@ -356,15 +980,13 @@ <Tool Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" - Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax7\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED" - GeneratePreprocessedFile="0" - MinimalRebuild="true" + AdditionalIncludeDirectories="C:\3dsmax9\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="NIFLIB_STATIC_LINK;WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED;NIFLIB_STATIC_LINK" + StringPooling="true" ExceptionHandling="2" - BasicRuntimeChecks="3" - RuntimeLibrary="1" + RuntimeLibrary="0" + EnableFunctionLevelLinking="true" ForceConformanceInForLoopScope="false" UsePrecompiledHeader="2" PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" @@ -378,7 +1000,7 @@ /> <Tool Name="VCResourceCompilerTool" - PreprocessorDefinitions="_DEBUG;NIFPLUGINS" + PreprocessorDefinitions="NDEBUG;NIFPLUGINS" Culture="1033" AdditionalIncludeDirectories=".\NifCommon" /> @@ -389,15 +1011,18 @@ Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" - OutputFile="C:\3dsmax7\plugins\NifPlugins.dlu" - LinkIncremental="2" + OutputFile="C:\3dsmax9\plugins\NifPlugins.dlu" + LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax7\maxsdk\lib;..\niflib\lib" - IgnoreDefaultLibraryNames="msvcrtd.lib" + AdditionalLibraryDirectories="C:\3dsmax9\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" SubSystem="2" + OptimizeReferences="2" + EnableCOMDATFolding="2" + SetChecksum="true" BaseAddress="0x16860000" /> <Tool @@ -423,11 +1048,11 @@ /> <Tool Name="VCPostBuildEventTool" - CommandLine="" + CommandLine="set MaxRootDir=$(TargetDir)\..
if exist "%MaxRootDir%\plugcfg" (
if not exist "%MaxRootDir%\plugcfg\MaxNifTools.ini" (
copy "$(ProjectDir)MaxNifTools.ini" "%MaxRootDir%\plugcfg\MaxNifTools.ini"
)
)
xcopy /D /Y /I "$(ProjectDir)MaxNifPlugins_Readme.txt" "$(OutDir)"
xcopy /D /Y /I "$(ProjectDir)MaxNifTools.ini" "$(OutDir)"
xcopy /D /Y /I "$(TargetPath)" "$(OutDir)"
" /> </Configuration> <Configuration - Name="Release - Max 8|Win32" + Name="Release - Max 4|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -461,8 +1086,8 @@ Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED" + AdditionalIncludeDirectories="C:\3dsmax4\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;NIFLIB_STATIC_LINK" StringPooling="true" ExceptionHandling="2" RuntimeLibrary="0" @@ -490,11 +1115,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib" - OutputFile="C:\3dsmax8\plugins\NifPlugins.dlu" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax4\plugins\NifPlugins.dlu" LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax8\maxsdk\lib;..\niflib\lib" + AdditionalLibraryDirectories="C:\3dsmax4\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -531,7 +1157,7 @@ /> </Configuration> <Configuration - Name="Debug - Max 8|Win32" + Name="Debug - Max 4|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -564,8 +1190,8 @@ AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax8\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED" + AdditionalIncludeDirectories="C:\3dsmax4\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;NIFLIB_STATIC_LINK" GeneratePreprocessedFile="0" MinimalRebuild="true" ExceptionHandling="2" @@ -578,6 +1204,7 @@ SuppressStartupBanner="true" DebugInformationFormat="3" CompileAs="0" + DisableSpecificWarnings="4244;4018" /> <Tool Name="VCManagedResourceCompilerTool" @@ -595,11 +1222,11 @@ Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" - OutputFile="C:\3dsmax8\plugins\NifPlugins.dlu" + OutputFile="C:\3dsmax4\plugins\NifPlugins.dlu" LinkIncremental="2" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax8\maxsdk\lib;..\niflib\lib" - IgnoreDefaultLibraryNames="msvcrtd.lib" + AdditionalLibraryDirectories="C:\3dsmax4\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -633,7 +1260,7 @@ /> </Configuration> <Configuration - Name="Debug - Max 5|Win32" + Name="Debug - gmax|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -666,8 +1293,8 @@ AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax5\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE" + AdditionalIncludeDirectories="C:\gmax12\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;GAME_VER;NIFLIB_STATIC_LINK" GeneratePreprocessedFile="0" MinimalRebuild="true" ExceptionHandling="2" @@ -698,11 +1325,11 @@ Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" - OutputFile="C:\3dsmax5\plugins\NifPlugins.dlu" + OutputFile="C:\gmax12\plugins\NifPlugins.dlu" LinkIncremental="2" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax5\maxsdk\lib;..\niflib\lib" - IgnoreDefaultLibraryNames="msvcrtd.lib" + AdditionalLibraryDirectories="C:\gmax12\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -736,7 +1363,7 @@ /> </Configuration> <Configuration - Name="Release - Max 5|Win32" + Name="Release - gmax|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -770,12 +1397,12 @@ Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax5\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES" + AdditionalIncludeDirectories="C:\gmax12\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;GAME_VER;NIFLIB_STATIC_LINK" StringPooling="true" - ExceptionHandling="2" + ExceptionHandling="1" RuntimeLibrary="0" - EnableFunctionLevelLinking="true" + EnableFunctionLevelLinking="false" ForceConformanceInForLoopScope="false" UsePrecompiledHeader="2" PrecompiledHeaderThrough="$(ProjectDir)NifPlugins\pch.h" @@ -799,11 +1426,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib" - OutputFile="C:\3dsmax5\plugins\NifPlugins.dlu" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\gmax12\plugins\NifPlugins.dlu" LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax5\maxsdk\lib;..\niflib\lib" + AdditionalLibraryDirectories="C:\gmax12\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -840,7 +1468,7 @@ /> </Configuration> <Configuration - Name="Debug - Max 9|Win32" + Name="Debug - Max 4.2|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -873,8 +1501,8 @@ AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" Optimization="0" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax9\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;USE_BIPED" + AdditionalIncludeDirectories="C:\3dsmax42\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_UNSUPPORTED_CODE;NIFLIB_STATIC_LINK" GeneratePreprocessedFile="0" MinimalRebuild="true" ExceptionHandling="2" @@ -887,6 +1515,7 @@ SuppressStartupBanner="true" DebugInformationFormat="3" CompileAs="0" + DisableSpecificWarnings="4244;4018" /> <Tool Name="VCManagedResourceCompilerTool" @@ -903,12 +1532,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib_debug.lib" - OutputFile="C:\3dsmax9\plugins\NifPlugins.dlu" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax42\plugins\NifPlugins.dlu" LinkIncremental="2" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax9\maxsdk\lib;..\niflib\lib" - IgnoreDefaultLibraryNames="msvcrtd.lib" + AdditionalLibraryDirectories="C:\3dsmax42\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -942,7 +1571,7 @@ /> </Configuration> <Configuration - Name="Release - Max 9|Win32" + Name="Release - Max 4.2|Win32" OutputDirectory="$(SolutionDir)Staging\$(ConfigurationName)\" IntermediateDirectory="$(SolutionDir)Temp\$(ProjectName)\$(ConfigurationName)\" ConfigurationType="2" @@ -976,8 +1605,8 @@ Name="VCCLCompilerTool" AdditionalOptions="/LD /Zm200 /FI"$(ProjectDir)NifPlugins\pch.h"" InlineFunctionExpansion="2" - AdditionalIncludeDirectories="C:\3dsmax9\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;USE_BIPED" + AdditionalIncludeDirectories="C:\3dsmax42\maxsdk\include;..\niflib\include;..\niflib;.\NifCommon" + PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;_CRT_SECURE_NO_DEPRECATE;USE_NIFLIB_TEMPLATE_HELPERS;_USE_MATH_DEFINES;NIFLIB_STATIC_LINK" StringPooling="true" ExceptionHandling="2" RuntimeLibrary="0" @@ -1005,11 +1634,12 @@ <Tool Name="VCLinkerTool" AdditionalOptions="/MACHINE:I386" - AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib niflib.lib" - OutputFile="C:\3dsmax9\plugins\NifPlugins.dlu" + AdditionalDependencies="odbc32.lib odbccp32.lib comctl32.lib shlwapi.lib core.lib geom.lib gfx.lib mesh.lib maxutil.lib maxscrpt.lib paramblk2.lib bmm.lib" + OutputFile="C:\3dsmax42\plugins\NifPlugins.dlu" LinkIncremental="1" SuppressStartupBanner="true" - AdditionalLibraryDirectories="C:\3dsmax9\maxsdk\lib;..\niflib\lib" + AdditionalLibraryDirectories="C:\3dsmax42\maxsdk\lib;..\niflib\lib" + IgnoreDefaultLibraryNames="" ModuleDefinitionFile=".\NifPlugins\NifPlugins.def" GenerateDebugInformation="true" ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb" @@ -1104,6 +1734,762 @@ > </File> </Filter> + <Filter + Name="dds" + > + <File + RelativePath=".\NifProps\dds\dds.cpp" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCLCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\NifProps\dds\dds.h" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\NifProps\dds\dds.rc" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCResourceCompilerTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\NifProps\dds\ddsres.h" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\NifProps\dds\dxtlib.h" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + <File + RelativePath=".\NifProps\dds\veroverrides.h" + > + <FileConfiguration + Name="Release - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 6|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 7|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 8|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 5|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 9|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + ExcludedFromBuild="true" + > + <Tool + Name="VCCustomBuildTool" + /> + </FileConfiguration> + </File> + </Filter> </Filter> <Filter Name="NifFurniture" @@ -1216,6 +2602,34 @@ > </File> </Filter> + <Filter + Name="NvTriStrip" + > + <File + RelativePath=".\NifExport\NvTriStrip\NvTriStrip.cpp" + > + </File> + <File + RelativePath=".\NifExport\NvTriStrip\NvTriStrip.h" + > + </File> + <File + RelativePath=".\NifExport\NvTriStrip\NvTriStripObjects.cpp" + > + </File> + <File + RelativePath=".\NifExport\NvTriStrip\NvTriStripObjects.h" + > + </File> + <File + RelativePath=".\NifExport\NvTriStrip\VertexCache.cpp" + > + </File> + <File + RelativePath=".\NifExport\NvTriStrip\VertexCache.h" + > + </File> + </Filter> </Filter> <Filter Name="NifCommon" @@ -1401,6 +2815,60 @@ XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" /> </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + > + <Tool + Name="VCCLCompilerTool" + ObjectFile="$(IntDir)\$(InputName)1.obj" + XMLDocumentationFileName="$(IntDir)\$(InputName)1.xdc" + /> + </FileConfiguration> </File> <File RelativePath=".\NifPlugins\NifPlugins.rc" @@ -1489,6 +2957,54 @@ UsePrecompiledHeader="1" /> </FileConfiguration> + <FileConfiguration + Name="Release - Max 4|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - gmax|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - gmax|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Debug - Max 4.2|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> + <FileConfiguration + Name="Release - Max 4.2|Win32" + > + <Tool + Name="VCCLCompilerTool" + UsePrecompiledHeader="1" + /> + </FileConfiguration> </File> <File RelativePath=".\NifPlugins\pch.h" diff --git a/NifProps/bhkBoxObj.cpp b/NifProps/bhkBoxObj.cpp index 9079331290f518ed1cff0ff4ab4e70eb88a9bb38..0415051d85e0b0fcde6d9422bcf18239ae33022e 100644 --- a/NifProps/bhkBoxObj.cpp +++ b/NifProps/bhkBoxObj.cpp @@ -798,7 +798,13 @@ int bhkBoxObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) m = inode->GetObjectTM(t); gw->setTransform(m); DWORD rlim = gw->getRndLimits(); - gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY|GW_Z_BUFFER); + + DWORD newrlim = GW_WIREFRAME|GW_Z_BUFFER; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + newrlim |= GW_EDGES_ONLY; +#endif + gw->setRndLimits(newrlim); + if (inode->Selected()) gw->setColor( LINE_COLOR, GetSelColor()); else if(!inode->IsFrozen() && !inode->Dependent()) diff --git a/NifProps/bhkCapsuleObj.cpp b/NifProps/bhkCapsuleObj.cpp index 4e98bcdec76ecb0244e3f3bf0bf56d3ac60c7a44..6fa759a16a8186f1d0cc2f03fdef259dc95974d2 100644 --- a/NifProps/bhkCapsuleObj.cpp +++ b/NifProps/bhkCapsuleObj.cpp @@ -680,7 +680,13 @@ int bhkCapsuleObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags m = inode->GetObjectTM(t); gw->setTransform(m); DWORD rlim = gw->getRndLimits(); - gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY/*|GW_Z_BUFFER*/); + + DWORD newrlim = GW_WIREFRAME/*|GW_Z_BUFFER*/; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + newrlim |= GW_EDGES_ONLY; +#endif + gw->setRndLimits(newrlim); + if (inode->Selected()) gw->setColor( LINE_COLOR, GetSelColor()); else if(!inode->IsFrozen() && !inode->Dependent()) diff --git a/NifProps/bhkRigidBodyModifer.cpp b/NifProps/bhkRigidBodyModifer.cpp index 48c50f3a99495ef3421fa00f8795cb6a96b6341e..9dd47f86bb74f288463f27f03a8a0c94d1a58f1e 100644 --- a/NifProps/bhkRigidBodyModifer.cpp +++ b/NifProps/bhkRigidBodyModifer.cpp @@ -748,7 +748,12 @@ int bhkRigidBodyModifier::Display(TimeValue t, INode* inode, ViewExp *vpt, int f m = inode->GetObjectTM(t); gw->setTransform(m); DWORD rlim = gw->getRndLimits(); - gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY/*|GW_Z_BUFFER*/); + + DWORD newrlim = GW_WIREFRAME/*|GW_Z_BUFFER*/; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + newrlim |= GW_EDGES_ONLY; +#endif + gw->setRndLimits(newrlim); //UpdateMesh(t); gw->setMaterial(swMtl); diff --git a/NifProps/bhkSphereObj.cpp b/NifProps/bhkSphereObj.cpp index f0ac610f62a67db25959e9b78c58999caed858de..89ecd2532e75d72e9c51e6fa699a93cbdb7c9c15 100644 --- a/NifProps/bhkSphereObj.cpp +++ b/NifProps/bhkSphereObj.cpp @@ -591,7 +591,13 @@ int bhkSphereObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) m = inode->GetObjectTM(t); gw->setTransform(m); DWORD rlim = gw->getRndLimits(); - gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY/*|GW_Z_BUFFER*/); + + DWORD newrlim = GW_WIREFRAME/*|GW_Z_BUFFER*/; +#if VERSION_3DSMAX >= ((5000<<16)+(15<<8)+0) // Version 5+ + newrlim |= GW_EDGES_ONLY; +#endif + gw->setRndLimits(newrlim); + if (inode->Selected()) gw->setColor( LINE_COLOR, GetSelColor()); else if(!inode->IsFrozen() && !inode->Dependent()) diff --git a/NifProps/dds/ConvertColor.h b/NifProps/dds/ConvertColor.h new file mode 100644 index 0000000000000000000000000000000000000000..c334b4cdc3d7851bf213abad2ca26b902c4d238e --- /dev/null +++ b/NifProps/dds/ConvertColor.h @@ -0,0 +1,349 @@ +#pragma once +#include "tPixel.h" + +namespace nv +{ + +template < class T > inline T Min(const T &x, const T &y) +{ + if (x < y) + return x; + else + return y; +} +template < class T > inline T Max(const T &x, const T &y) +{ + if (x < y) + return y; + else + return x; +} + + + +} + + +typedef unsigned short nvhalf; + +union nv_half_data +{ + unsigned short bits; + struct + { + unsigned long m : 10; + unsigned long e : 5; + unsigned long s : 1; + } ieee; +}; + +union nv_ieee_single +{ + float f; + struct { + unsigned long m : 23; + unsigned long e : 8; + unsigned long s : 1; + } ieee; +}; + + +class nvColorConvert +{ +public: + + void RGBAToFloat(const RGBAImage & srcImage, + fpImage & dstImage); + + void RGBAToFloat(const RGBAMipMappedImage & srcMIPImage, + fpMipMappedImage & dstMIPImage); + + + void FloatToRGBA(const fpImage & srcImage, + RGBAImage & dstImage); + + void FloatToRGBA(const fpMipMappedImage & srcMIPImage, + RGBAMipMappedImage & dstMIPImage); + + fpPixel RGBEtoFloat(int r, int g, int b, int e); + + + // photoshop import export + float PSSignedToFloat(int pixel, int depth, int plane); + float PSUnsignedToFloat(int pixel, int depth); + + int FloatToUnsignedPS(float pixel, int depth); + int FloatToSignedPS(float pixel, int depth, int plane); + + // format to float + static float UnsignedToFloat(int channel); // unsigned, 8 bits + static float UnsignedToFloat(int channel, int nBits); // unsigned + static float SignedToFloat(int channel); // 8 bits + static float SignedToFloat(int channel, int nBits); + + + static void RGBAToFloat(int r, int g, int b, int a, fpPixel & fp) + { + fp.r = UnsignedToFloat(r); + fp.g = UnsignedToFloat(g); + fp.b = UnsignedToFloat(b); + fp.a = UnsignedToFloat(a); + } + + + static void RGBAToFloat( const rgba_t & inColor, fpPixel & fp) + { + + fp.r = UnsignedToFloat(inColor.r); + fp.g = UnsignedToFloat(inColor.g); + fp.b = UnsignedToFloat(inColor.b); + fp.a = UnsignedToFloat(inColor.a); + } + + + static void RGBEToFloat(fpPixel & fp, const rgba_t & rgbe); + static void RGBEToFloat(float &r, float & g, float & b, const rgba_t & rgbe); + + + + + static float HalfToFloat(nvhalf val) + { + nv_half_data h; + //h.bits = val.value_bits; + h.bits = val; + nv_ieee_single sng; + sng.ieee.s = h.ieee.s; + + // handle special cases + if ( (h.ieee.e==0) && (h.ieee.m==0) ) + { // zero + sng.ieee.m=0; + sng.ieee.e=0; + } + else if ( (h.ieee.e==0) && (h.ieee.m!=0) ) + { + // denorm -- denorm half will fit in non-denorm single + const float half_denorm = (1.0f/16384.0f); // 2^-14 + float mantissa = ((float)(h.ieee.m)) / 1024.0f; + float sgn = (h.ieee.s)? -1.0f :1.0f; + sng.f = sgn*mantissa*half_denorm; + } + else if ( (h.ieee.e==31) && (h.ieee.m==0) ) + { // infinity + sng.ieee.e = 0xff; + sng.ieee.m = 0; + } + else if ( (h.ieee.e==31) && (h.ieee.m!=0) ) + { // NaN + sng.ieee.e = 0xff; + sng.ieee.m = 1; + } + else + { + sng.ieee.e = h.ieee.e+112; + sng.ieee.m = (h.ieee.m << 13); + } + + return sng.f; + } + + + + /// float to format + static unsigned long FloatToUnsigned(float channel); // 8 bits + static unsigned long FloatToUnsigned(float channel, int nBits); + + static long FloatToSigned(float channel); // 8 bits + static long FloatToSigned(float channel, int nBits); + + + + + static unsigned long NormalToUnsigned(float inColor ) + { + return FloatToUnsigned(inColor * 0.5f + 0.5f); + } + + static unsigned long NormalToUnsigned(float inColor, int nBits ) + { + return FloatToUnsigned(inColor * 0.5f + 0.5f, nBits); + } + + static void NormalToRGBA(const fpPixel & inColor, rgba_t & outColor ) + { + outColor.r = (unsigned char)NormalToUnsigned(inColor.r); + outColor.g = (unsigned char)NormalToUnsigned(inColor.g); + outColor.b = (unsigned char)NormalToUnsigned(inColor.b); + outColor.a = (unsigned char)NormalToUnsigned(inColor.a); + + } + + static void FloatToRGBA(const fpPixel & inColor, rgba_t & p ) + { + p.r = (unsigned char)FloatToUnsigned(inColor.r); + p.g = (unsigned char)FloatToUnsigned(inColor.g); + p.b = (unsigned char)FloatToUnsigned(inColor.b); + p.a = (unsigned char)FloatToUnsigned(inColor.a); + + } + + static void FloatToBGRA(const fpPixel & inColor, unsigned long & outColor ) + { + unsigned int r = FloatToUnsigned(inColor.r); + unsigned int g = FloatToUnsigned(inColor.g); + unsigned int b = FloatToUnsigned(inColor.b); + unsigned int a = FloatToUnsigned(inColor.a); + + outColor = (a << 24) | (r << 16) | (g << 8) | b; + + } + + + + static void FloatToBGRA(float r, float g, float b, float a, unsigned long & outColor ) + { + unsigned int ri = FloatToUnsigned(r); + unsigned int gi = FloatToUnsigned(g); + unsigned int bi = FloatToUnsigned(b); + unsigned int ai = FloatToUnsigned(a); + + outColor = (ai << 24) | (ri << 16) | (gi << 8) | bi; + } + + static void FloatToQ8W8V8U8(const fpPixel & inColor, q8w8v8u8_t & outColor ) + { + outColor.q = (char)FloatToSigned(inColor.r); + outColor.v = (char)FloatToSigned(inColor.g); + outColor.w = (char)FloatToSigned(inColor.b); + outColor.u = (char)FloatToSigned(inColor.a); + + } + + + static void FloatToU16V16(float u, float v, v16u16_t & outColor ) + { + outColor.u = (short)FloatToSigned(u, 16); + outColor.v = (short)FloatToSigned(v, 16); + } + + + static void FloatToR12G12B8(const fpPixel & inColor, r12g12b8_t & outColor ) + { + outColor.r = FloatToUnsigned(inColor.r, 12); + outColor.g = FloatToUnsigned(inColor.g, 12); + outColor.b = FloatToUnsigned(inColor.b, 8); + } + + static void NormalToR12G12B8(const fpPixel & inColor, r12g12b8_t & outColor ) + { + outColor.r = FloatToUnsigned(inColor.r * 0.5f + 0.5f, 12); + outColor.g = FloatToUnsigned(inColor.g * 0.5f + 0.5f, 12); + outColor.b = FloatToUnsigned(inColor.b * 0.5f + 0.5f, 8); + } + + + + + static float FloatToRGBE_Alpha(const fpPixel & fp); + + static void FloatToRGBE(rgba_t & rgbe, const float &r, const float & g, const float & b ); + static void FloatToRGBE(rgba_t * rgbe, const float &r, const float & g, const float & b ); + + static void FloatToRGBE(fpPixel & rgbe, const fpPixel & fp); + static void FloatToRGBE(rgba_t & rgbe, const fpPixel & fp); + + static unsigned char FloatToRGBE_DXT3Alpha(const fpPixel & fp); + + + + static nvhalf FloatToHalf(float val) + { + nv_ieee_single f; + f.f = val; + nv_half_data h; + + h.ieee.s = f.ieee.s; + + // handle special cases + + //const float half_denorm = (1.0f/16384.0f); + + if ( (f.ieee.e==0) && (f.ieee.m==0) ) + { // zero + h.ieee.m = 0; + h.ieee.e = 0; + } + else if ( (f.ieee.e==0) && (f.ieee.m!=0) ) + { // denorm -- denorm float maps to 0 half + h.ieee.m = 0; + h.ieee.e = 0; + } + else if ( (f.ieee.e==0xff) && (f.ieee.m==0) ) + { + // infinity + h.ieee.m = 0; + h.ieee.e = 31; + } + else if ( (f.ieee.e==0xff) && (f.ieee.m!=0) ) + { + // NaN + h.ieee.m = 1; + h.ieee.e = 31; + } + else + { + // regular number + int new_exp = f.ieee.e-127; + + if (new_exp<-24) + { // this maps to 0 + h.ieee.m = 0; + h.ieee.e = 0; + } + + if (new_exp<-14) + { + // this maps to a denorm + h.ieee.e = 0; + unsigned int exp_val = (unsigned int) (-14 - new_exp); // 2^-exp_val + switch (exp_val) + { + case 0: + //fprintf(stderr, "ftoh: logical error in denorm creation!\n"); + h.ieee.m = 0; + break; + case 1: h.ieee.m = 512 + (f.ieee.m>>14); break; + case 2: h.ieee.m = 256 + (f.ieee.m>>15); break; + case 3: h.ieee.m = 128 + (f.ieee.m>>16); break; + case 4: h.ieee.m = 64 + (f.ieee.m>>17); break; + case 5: h.ieee.m = 32 + (f.ieee.m>>18); break; + case 6: h.ieee.m = 16 + (f.ieee.m>>19); break; + case 7: h.ieee.m = 8 + (f.ieee.m>>20); break; + case 8: h.ieee.m = 4 + (f.ieee.m>>21); break; + case 9: h.ieee.m = 2 + (f.ieee.m>>22); break; + case 10: h.ieee.m = 1; break; + } + } + else if (new_exp>15) + { // map this value to infinity + h.ieee.m = 0; + h.ieee.e = 31; + } + else + { + h.ieee.e = new_exp+15; + h.ieee.m = (f.ieee.m >> 13); + } + } + + return (*(nvhalf*)(&h.bits)); + } + + + +}; + + + + diff --git a/NifProps/dds/dds.cpp b/NifProps/dds/dds.cpp new file mode 100644 index 0000000000000000000000000000000000000000..85fbc37533f1b41e9549085760678276da747a04 --- /dev/null +++ b/NifProps/dds/dds.cpp @@ -0,0 +1,774 @@ +// File ....: dds.cpp +// ------------------ +// Author...: Sean Palmer +// Date ....: April 2001 +// Descr....: DDS File I/O Module + +//-- Include files + +#include <max.h> +#include <bmmlib.h> +#include <pixelbuf.h> +#include "dds.h" +#include "ddsres.h" + +#include <stdio.h> + +#include "dxtlib.h" + +//extern "C" FILE _iob[3] = {NULL, NULL, NULL}; + +extern HINSTANCE hInstance; + +static FILE* ghFile=NULL; + +void WriteDTXnFile(DWORD count, void *buffer) +{ + fwrite(buffer, count, 1, ghFile); +} + +void ReadDTXnFile(DWORD count, void *buffer) +{ + fread(buffer, count, 1, ghFile); +} + +//----------------------------------------------------------------------------- +//-- File Class + +class File +{ +public: + FILE *stream; + File (const TCHAR *name, const TCHAR *mode) { stream = _tfopen(name,mode); } + ~File () { Close(); } + void Close() { if(stream) fclose(stream); stream = NULL; } +}; + +//----------------------------------------------------------------------------- +// DDS Class Description + +class DDSClassDesc : public ClassDesc +{ +public: + int IsPublic () { return 1; } + void *Create (BOOL loading=FALSE) { return new BitmapIO_DDS; } + const TCHAR *ClassName () { return GetString(IDS_DDS); } + SClass_ID SuperClassID () { return BMM_IO_CLASS_ID; } + Class_ID ClassID () { return DDS_CLASS_ID; } + const TCHAR *Category () { return GetString(IDS_BITMAP_IO); } +}; + +static DDSClassDesc DDSDesc; + +//----------------------------------------------------------------------------- +// *> AboutCtrlDlgProc() +// + +BOOL CALLBACK AboutCtrlDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) +{ + switch (message) + { + case WM_INITDIALOG: + { + CenterWindow(hWnd,GetParent(hWnd)); + return 1; + } + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hWnd,1); + break; + + case IDCANCEL: + EndDialog(hWnd,0); + break; + + } + return 1; + } + return 0; +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::BitmapIO_DDS() + +BitmapIO_DDS::BitmapIO_DDS() +{ + mParams.outFormat = TF_DXT3 | TF_MIPMAPS; +} + +BitmapIO_DDS::~BitmapIO_DDS () {} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::LongDesc() + +const TCHAR *BitmapIO_DDS::LongDesc() +{ + return GetString(IDS_DDS_FILE); +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::ShortDesc() + +const TCHAR *BitmapIO_DDS::ShortDesc() +{ + return GetString(IDS_DDS); +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::LoadConfigure() + +BOOL BitmapIO_DDS::LoadConfigure (void *ptr) +{ + DDSParams *buf = (DDSParams*) ptr; + memcpy(&mParams, ptr, sizeof(DDSParams)); + return TRUE; +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::SaveConfigure() + +BOOL BitmapIO_DDS::SaveConfigure (void *ptr) +{ + if (ptr) + { + memcpy(ptr, &mParams, sizeof(DDSParams)); + return TRUE; + } + return FALSE; +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::ShowAbout() + +void BitmapIO_DDS::ShowAbout(HWND hWnd) +{ + DialogBoxParam( + hInstance, + MAKEINTRESOURCE(IDD_DDS_ABOUT), + hWnd, + (DLGPROC)AboutCtrlDlgProc, + (LPARAM)0); +} + + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::ConfigCtrlDlgProc + +BOOL BitmapIO_DDS::ConfigCtrlDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) +{ + + switch (message) + { + case WM_INITDIALOG: + switch (mParams.outFormat & TF_FMTMASK) + { + case TF_DXT1: CheckDlgButton(hWnd, IDC_DDS_DXT1, TRUE); break; + case TF_DXT1_1BitAlpha: CheckDlgButton(hWnd, IDC_DDS_DXT1ALPHA, TRUE); break; + case TF_DXT3: CheckDlgButton(hWnd, IDC_DDS_DXT3, TRUE); break; + case TF_DXT5: CheckDlgButton(hWnd, IDC_DDS_DXT5, TRUE); break; + case TF_RGB4444: CheckDlgButton(hWnd, IDC_DDS_ARGB4444, TRUE); break; + case TF_RGB1555: CheckDlgButton(hWnd, IDC_DDS_ARGB1555, TRUE); break; + case TF_RGB565: CheckDlgButton(hWnd, IDC_DDS_RGB565, TRUE); break; + case TF_RGB8888: CheckDlgButton(hWnd, IDC_DDS_ARGB8888, TRUE); break; + } + CheckDlgButton(hWnd, IDC_DDS_DITHER, (mParams.outFormat & TF_DITHER)!=0); + CheckDlgButton(hWnd, IDC_DDS_MIPMAPS, (mParams.outFormat & TF_MIPMAPS)!=0); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + EndDialog(hWnd,1); + break; + case IDCANCEL: + EndDialog(hWnd,0); + break; + + case IDC_DDS_DXT1: mParams.outFormat = TF_DXT1 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_DXT1ALPHA: mParams.outFormat = TF_DXT1_1BitAlpha | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_DXT3: mParams.outFormat = TF_DXT3 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_DXT5: mParams.outFormat = TF_DXT5 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_ARGB4444: mParams.outFormat = TF_RGB4444 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_ARGB1555: mParams.outFormat = TF_RGB1555 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_RGB565: mParams.outFormat = TF_RGB565 | (mParams.outFormat&~TF_FMTMASK); break; + case IDC_DDS_ARGB8888: mParams.outFormat = TF_RGB8888 | (mParams.outFormat&~TF_FMTMASK); break; + + case IDC_DDS_DITHER: + if (IsDlgButtonChecked(hWnd, IDC_DDS_DITHER)) + mParams.outFormat |= TF_DITHER; + else + mParams.outFormat &= ~TF_DITHER; + break; + + case IDC_DDS_MIPMAPS: + if (IsDlgButtonChecked(hWnd, IDC_DDS_MIPMAPS)) + mParams.outFormat |= TF_MIPMAPS; + else + mParams.outFormat &= ~TF_MIPMAPS; + break; + } + return TRUE; + } + return FALSE; +} + +//----------------------------------------------------------------------------- +// #> StaticDialogProc + +BOOL CALLBACK StaticDialogProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l) +{ + BitmapIO_DDS* p; + + if (msg==WM_INITDIALOG) + { + p = (BitmapIO_DDS*)l; + SetWindowLong(hwnd, GWL_USERDATA,l); + } + else + { + if ((p = (BitmapIO_DDS*)GetWindowLong(hwnd, GWL_USERDATA)) == NULL) + return FALSE; + } + return p->ConfigCtrlDlgProc(hwnd,msg,w,l); +} + + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::ShowControl() + +BOOL BitmapIO_DDS::ShowControl(HWND hWnd, DWORD flag) +{ + return DialogBoxParam( + hInstance, + MAKEINTRESOURCE (IDD_DDS_CONFIG), + hWnd, + (DLGPROC) StaticDialogProc, + (LPARAM) this); +} + + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::GetImageInfo() + +BMMRES BitmapIO_DDS::GetImageInfo (BitmapInfo *fbi) +{ + //-- Open DDS File ----------------------------------- + + File file(fbi->Name(), _T("rb")); + + if (!file.stream) + return (ProcessImageIOError(fbi)); + + //-- Read File Header -------------------------------- + + if (!ReadDDSHeader(file.stream)) + return (ProcessImageIOError(fbi,BMMRES_BADFILEHEADER)); + + //-- Update Bitmap Info ------------------------------ + + fbi->SetWidth((WORD)hdr.dwWidth); + fbi->SetHeight((WORD)hdr.dwHeight); + + switch (hdr.dwFourCC) + { + case 0: + switch (hdr.dwRGBBitCount) + { + //case 1: fbi->SetType(BMM_LINE_ART); break; + //case 4: fbi->SetType(BMM_BMP_4); break; + //case 8: fbi->SetType(BMM_PALETTED); break; + case 16: + if (hdr.dwRGBAlphaBitMask) + fbi->SetType(BMM_TRUE_32); + else + fbi->SetType(BMM_TRUE_24); + break; + case 24: fbi->SetType(BMM_TRUE_24); break; + case 32: fbi->SetType(BMM_TRUE_32); break; + default: fbi->SetType(BMM_NO_TYPE); break; + } + break; + case 'D'|('X'<<8)|('T'<<16)|('1'<<24): + case 'D'|('X'<<8)|('T'<<16)|('2'<<24): + case 'D'|('X'<<8)|('T'<<16)|('3'<<24): + case 'D'|('X'<<8)|('T'<<16)|('4'<<24): + case 'D'|('X'<<8)|('T'<<16)|('5'<<24): + fbi->SetType(BMM_TRUE_32); + break; + } + +// fbi->SetGamma(1.0f); + fbi->SetAspect(1.0f); + fbi->SetFirstFrame(0); + fbi->SetLastFrame(0); + + return BMMRES_SUCCESS; +} + +inline WORD Conv4To16(int d) { return (d<<12) | (d<<8) | (d<<4) | d; } +inline WORD Conv5To16(int d) { return (d<<11) | (d<<6) | (d<<1); } +inline WORD Conv6To16(int d) { return (d<<10) | (d<<4) | (d>>2); } +inline WORD Conv8To16(int d) { return (d<<8) | d; } + +//----------------------------------------------------------------------------- +//-- BitmapIO_DDS::Load() + +BitmapStorage *BitmapIO_DDS::Load(BitmapInfo *fbi, Bitmap *map, BMMRES *status) +{ + RGBQUAD *rgb = NULL; + BMM_Color_48 *pal = NULL; + BitmapStorage *s = NULL; + BMM_Color_64 *b = NULL; + BYTE *p = NULL; + + + int pixels = 0; + int rows = 0; + int w = 0; + int wb = 0; + int h = 0; + + //-- Initialize Status Optimistically + + *status = BMMRES_SUCCESS; + + //-- Make sure nothing weird is going on + + if(openMode != BMM_NOT_OPEN) + { + *status = ProcessImageIOError(fbi,BMMRES_INTERNALERROR); + return NULL; + } + + //-- Open DDS File ----------------------------------- + + File file(fbi->Name(), _T("rb")); + + if (!file.stream) + { + *status = ProcessImageIOError(fbi); + return(NULL); + } + + ghFile = file.stream; + + int width; + int height; + int planes; + int lTotalWidth; + int rowBytes; + + //-- Read File Header -------------------------------- + + unsigned char* data = nvDXTdecompress(width, height, planes, lTotalWidth, rowBytes); + + if (!data) + { + *status = ProcessImageIOError(fbi,BMMRES_BADFILEHEADER); + return (NULL); + } + + ghFile = NULL; + + + //-- Update Bitmap Info ------------------------------ + + fbi->SetWidth(width); + fbi->SetHeight(height); + + //fbi->SetGamma(1.0f); + fbi->SetAspect(1.0f); + + switch(planes) + { + case 3: + fbi->SetType(BMM_TRUE_24); + break; + + case 4: + fbi->SetType(BMM_TRUE_32); + break; + } + + fbi->SetFirstFrame(0); + fbi->SetLastFrame(0); + + //-- Create Image Storage ---------------------------- + + switch(planes) + { + case 3: + case 4: + s = BMMCreateStorage(map->Manager(),BMM_TRUE_32); + break; + } + + if(!s) + { + *status = ProcessImageIOError(fbi,BMMRES_CANTSTORAGE); + return NULL; + } + + //-- Allocate Image Storage -------------------------- + + if (s->Allocate(fbi,map->Manager(),BMM_OPEN_R)==0) + { + + memory_error_out: + *status = ProcessImageIOError(fbi,BMMRES_MEMORYERROR); + goto bail_out; + + io_error_out: + *status = ProcessImageIOError(fbi); + bail_out: + + if (s) delete s; + if (b) free(b); + if (p) free(p); + if (rgb) free(rgb); + if (pal) free(pal); + + return NULL; + + } + + switch (planes) + { + case 3: + { + //-- Read Image (24 Bits) ---------------------------- + + w = width; + wb = lTotalWidth*planes; //rowBytes; + h = height; + + b = (BMM_Color_64 *)malloc(width*sizeof(BMM_Color_64)); + p = (BYTE *)data; + + if(!b || !p) + goto memory_error_out; + + BYTE *ptr; + + do + { + ptr = p; + p += wb; + for (int x = 0; x < w; x++) + { + b[x].b = Conv8To16(*ptr++); + b[x].g = Conv8To16(*ptr++); + b[x].r = Conv8To16(*ptr++); + } + if (s->PutPixels(0,rows,w,b)!=1) + goto io_error_out; + rows++; + if (rows>=h) break; + + //-- Progress Report + + if (fbi->GetUpdateWindow()) + SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,h); + + } while (true); + break; + } + case 4: + { + //-- Read Image (32 Bits) ---------------------------- + + w = width; + wb = lTotalWidth*planes; //rowBytes; + h = height; + + b = (BMM_Color_64 *)malloc(width*sizeof(BMM_Color_64)); + p = (BYTE *)data; + + if(!b || !p) + goto memory_error_out; + + BYTE *ptr; + + bool foundalpha = false; + + do + { + ptr = p; + p += wb; + for (int x = 0; x < w; x++) + { + b[x].b = Conv8To16(*ptr++); + b[x].g = Conv8To16(*ptr++); + b[x].r = Conv8To16(*ptr++); + if (*ptr != 0xFF) foundalpha=true; + b[x].a = Conv8To16(*ptr++); + } + if (s->PutPixels(0,rows,w,b)!=1) + goto io_error_out; + rows++; + if (rows>=h) break; + + //-- Progress Report + + if (fbi->GetUpdateWindow()) + SendMessage(fbi->GetUpdateWindow(),BMM_PROGRESS,rows,h); + + } while (true); + if (foundalpha) + fbi->SetFlags(MAP_HAS_ALPHA); + else + fbi->SetType(BMM_TRUE_24); + break; + } + } + + //-- Clean Up ---------------------------------------- + + free(data); + + if (b) free(b); + + //-- Set the storage's BitmapInfo + + s->bi.CopyImageInfo(fbi); + + return s; + +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::OpenOutput() +// + +BMMRES BitmapIO_DDS::OpenOutput(BitmapInfo *fbi, Bitmap *map) +{ + + if (openMode != BMM_NOT_OPEN) + return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); + + if (!map) + return (ProcessImageIOError(&bi,BMMRES_INTERNALERROR)); + + //-- Save Image Info Data + + bi.CopyImageInfo(fbi); + bi.SetUpdateWindow(fbi->GetUpdateWindow()); + + this->map = map; + openMode = BMM_OPEN_W; + + return (BMMRES_SUCCESS); + +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::Write() +// +// + +BMMRES BitmapIO_DDS::Write(int frame) +{ + + BMMRES result = BMMRES_SUCCESS; + + //-- If we haven't gone through an OpenOutput(), leave + + if (openMode != BMM_OPEN_W) + return ProcessImageIOError(&bi,BMMRES_INTERNALERROR); + + //-- Resolve Filename -------------------------------- + + TCHAR filename[MAX_PATH]; + + if (frame == BMM_SINGLEFRAME) + { + _tcscpy(filename,bi.Name()); + } + else + { + if (!BMMCreateNumberedFilename(bi.Name(),frame,filename)) + return ProcessImageIOError(&bi,BMMRES_NUMBEREDFILENAMEERROR); + } + + //-- Create Image File ------------------------------- + + PBITMAPINFO pbmi = GetDitheredOutputDib(32); + if (!pbmi) + return ProcessImageIOError(&bi,GetString(IDS_CONVERT_ERROR)); + int w=map->Width(); + int h=map->Height(); + int wb=w*4; + unsigned char* data = new unsigned char[wb*h]; + const unsigned char* psrc = (const unsigned char*)pbmi->bmiColors; + unsigned char* pdst = data + wb*h; + for (int j=h; --j>=0; ) + { + pdst -= wb; + memcpy(pdst,psrc,wb); + psrc += wb; + } + + //-- Write Image File -------------------------------- + + if (bi.GetUpdateWindow()) + SendMessage(bi.GetUpdateWindow(),BMM_PROGRESS,50,100); + + File file(filename, _T("wb")); + + if (!file.stream) + { + LocalFree(pbmi); + return ProcessImageIOError(&bi); + } + + ghFile = file.stream; + +/* + Compresses an image with a user supplied callback with the data for each MIP level created + Only supports input of RGB 24 or ARGB 32 bpp + if callback is == 0 (or not specified), then WriteDTXnFile is called with all file info +*/ + HRESULT res = nvDXTcompress(data, // pointer to data (24 or 32 bit) + w, // width in texels + h, // height in texels + mParams.outFormat&TF_FMTMASK, + (mParams.outFormat&TF_MIPMAPS)!=0, // auto gen MIP maps + (mParams.outFormat&TF_DITHER)!=0, // dither + 4, // 3 or 4 bytes per pixel + 0); // callback for generated levels + + delete[] data; + + LocalFree(pbmi); + ghFile = NULL; + + if (res != 0) + { + switch (res) + { + default: + case DXTERR_INPUT_POINTER_ZERO: + return ProcessImageIOError(&bi,GetString(IDS_CONVERT_ERROR)); + case DXTERR_DEPTH_IS_NOT_3_OR_4: + return ProcessImageIOError(&bi,GetString(IDS_UNSUPPORTEDFORMAT_ERROR)); + case DXTERR_NON_POWER_2: + return ProcessImageIOError(&bi,GetString(IDS_NONPOWEROF2_ERROR)); + } + } + + if (bi.GetUpdateWindow()) + SendMessage(bi.GetUpdateWindow(),BMM_PROGRESS,100,100); + + return result; +} + +//----------------------------------------------------------------------------- +// BitmapIO_DDS::Close() +// + +int BitmapIO_DDS::Close(int flag) +{ + return 1; +} + +//----------------------------------------------------------------------------- +// #> BitmapIO_DDS::ReadDDSHeader() +// + +int BitmapIO_DDS::ReadDDSHeader(FILE *stream) +{ + //-- Read File Header -------------------------------- + + int res = fread(&hdr,1,sizeof(DDSFILEHEADER),stream); + + if (res != sizeof(DDSFILEHEADER)) + return 0; + + //-- Validate ---------------------------------------- + + if (hdr.dwMagic != 0x20534444) + return 0; + + //-- Done + return 1; +} + + +//----------------------------------------------------------------------------- +// Interface + +extern ClassDesc *GetDDSLibClassDesc() +{ + return &DDSDesc; +} + +#if 0 +//-- Globals ------------------------------------------------------------------ + +TCHAR *GetString(int id) +{ + static TCHAR buf[256]; + if (hInstance) + return LoadString(hInstance, id, buf, sizeof(buf)) ? buf : NULL; + return NULL; +} + + +DLLEXPORT const TCHAR * LibDescription () +{ + return GetString(IDS_DDS_DESC); +} + +DLLEXPORT int LibNumberClasses () +{ + return 1; +} + +DLLEXPORT ClassDesc *LibClassDesc(int i) +{ + switch(i) + { + case 0: return &DDSDesc; break; + default: return 0; break; + } +} + +DLLEXPORT ULONG LibVersion () +{ + return (VERSION_3DSMAX); +} + +// Let the plug-in register itself for deferred loading +__declspec(dllexport) ULONG CanAutoDefer() +{ + return 1; +} + +//----------------------------------------------------------------------------- +//-- DLL Declaration + +BOOL WINAPI DllMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) + { + case DLL_PROCESS_ATTACH: + if (hInstance) + return(FALSE); + hInstance = hDLLInst; + break; + case DLL_PROCESS_DETACH: + hInstance = NULL; + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + } + return TRUE; +} + +#endif \ No newline at end of file diff --git a/NifProps/dds/dds.dep b/NifProps/dds/dds.dep new file mode 100644 index 0000000000000000000000000000000000000000..076baa32f4f9156910722920246a977b39099cf8 --- /dev/null +++ b/NifProps/dds/dds.dep @@ -0,0 +1,128 @@ +# Microsoft Developer Studio Generated Dependency File, included by dds.mak + +.\dds.cpp : \ + "..\..\..\include\acolor.h"\ + "..\..\..\include\ActionTable.h"\ + "..\..\..\include\animtbl.h"\ + "..\..\..\include\appio.h"\ + "..\..\..\include\assert1.h"\ + "..\..\..\include\baseinterface.h"\ + "..\..\..\include\bitarray.h"\ + "..\..\..\include\bitmap.h"\ + "..\..\..\include\bmmlib.h"\ + "..\..\..\include\box2.h"\ + "..\..\..\include\box3.h"\ + "..\..\..\include\buildver.h"\ + "..\..\..\include\captypes.h"\ + "..\..\..\include\channels.h"\ + "..\..\..\include\cmdmode.h"\ + "..\..\..\include\color.h"\ + "..\..\..\include\coreexp.h"\ + "..\..\..\include\custcont.h"\ + "..\..\..\include\dbgprint.h"\ + "..\..\..\include\dpoint3.h"\ + "..\..\..\include\euler.h"\ + "..\..\..\include\evuser.h"\ + "..\..\..\include\excllist.h"\ + "..\..\..\include\export.h"\ + "..\..\..\include\gbuf.h"\ + "..\..\..\include\gencam.h"\ + "..\..\..\include\genhier.h"\ + "..\..\..\include\genlight.h"\ + "..\..\..\include\genshape.h"\ + "..\..\..\include\geom.h"\ + "..\..\..\include\geomlib.h"\ + "..\..\..\include\gfloat.h"\ + "..\..\..\include\gfx.h"\ + "..\..\..\include\gfxlib.h"\ + "..\..\..\include\gutil.h"\ + "..\..\..\include\hitdata.h"\ + "..\..\..\include\hold.h"\ + "..\..\..\include\iColorMan.h"\ + "..\..\..\include\iFnPub.h"\ + "..\..\..\include\impapi.h"\ + "..\..\..\include\impexp.h"\ + "..\..\..\include\impexpintf.h"\ + "..\..\..\include\imtl.h"\ + "..\..\..\include\inode.h"\ + "..\..\..\include\INodeGIProperties.h"\ + "..\..\..\include\interval.h"\ + "..\..\..\include\ioapi.h"\ + "..\..\..\include\iparamb.h"\ + "..\..\..\include\ipipelineclient.h"\ + "..\..\..\include\ipoint2.h"\ + "..\..\..\include\ipoint3.h"\ + "..\..\..\include\istdplug.h"\ + "..\..\..\include\iTreeVw.h"\ + "..\..\..\include\linklist.h"\ + "..\..\..\include\lockid.h"\ + "..\..\..\include\log.h"\ + "..\..\..\include\matrix2.h"\ + "..\..\..\include\matrix3.h"\ + "..\..\..\include\max.h"\ + "..\..\..\include\maxapi.h"\ + "..\..\..\include\maxcom.h"\ + "..\..\..\include\maxtess.h"\ + "..\..\..\include\maxtypes.h"\ + "..\..\..\include\mesh.h"\ + "..\..\..\include\meshlib.h"\ + "..\..\..\include\MNBigMat.h"\ + "..\..\..\include\MNCommon.h"\ + "..\..\..\include\mnmath.h"\ + "..\..\..\include\MNMesh.h"\ + "..\..\..\include\MNNormalSpec.h"\ + "..\..\..\include\mouseman.h"\ + "..\..\..\include\mtl.h"\ + "..\..\..\include\namesel.h"\ + "..\..\..\include\nametab.h"\ + "..\..\..\include\object.h"\ + "..\..\..\include\objmode.h"\ + "..\..\..\include\palutil.h"\ + "..\..\..\include\paramtype.h"\ + "..\..\..\include\patch.h"\ + "..\..\..\include\patchlib.h"\ + "..\..\..\include\patchobj.h"\ + "..\..\..\include\pixelbuf.h"\ + "..\..\..\include\plugapi.h"\ + "..\..\..\include\plugin.h"\ + "..\..\..\include\point2.h"\ + "..\..\..\include\point3.h"\ + "..\..\..\include\point4.h"\ + "..\..\..\include\polyobj.h"\ + "..\..\..\include\polyshp.h"\ + "..\..\..\include\ptrvec.h"\ + "..\..\..\include\quat.h"\ + "..\..\..\include\random.h"\ + "..\..\..\include\ref.h"\ + "..\..\..\include\render.h"\ + "..\..\..\include\RenderElements.h"\ + "..\..\..\include\rtclick.h"\ + "..\..\..\include\sbmtlapi.h"\ + "..\..\..\include\sceneapi.h"\ + "..\..\..\include\sfx.h"\ + "..\..\..\include\shape.h"\ + "..\..\..\include\shphier.h"\ + "..\..\..\include\shpsels.h"\ + "..\..\..\include\snap.h"\ + "..\..\..\include\soundobj.h"\ + "..\..\..\include\spline3d.h"\ + "..\..\..\include\stack.h"\ + "..\..\..\include\stack3.h"\ + "..\..\..\include\strbasic.h"\ + "..\..\..\include\strclass.h"\ + "..\..\..\include\SvCore.h"\ + "..\..\..\include\SystemUtilities.h"\ + "..\..\..\include\tab.h"\ + "..\..\..\include\templt.h"\ + "..\..\..\include\trig.h"\ + "..\..\..\include\triobj.h"\ + "..\..\..\include\udmIA64.h"\ + "..\..\..\include\units.h"\ + "..\..\..\include\utilexp.h"\ + "..\..\..\include\utilintf.h"\ + "..\..\..\include\utillib.h"\ + "..\..\..\include\vedge.h"\ + "..\..\..\include\winutil.h"\ + ".\DDS.H"\ + ".\dxtlib.h"\ + diff --git a/NifProps/dds/dds.h b/NifProps/dds/dds.h new file mode 100644 index 0000000000000000000000000000000000000000..6af084cf9bc04c4f3ee41409ba766741bd395e2a --- /dev/null +++ b/NifProps/dds/dds.h @@ -0,0 +1,159 @@ +// File ....: dds.h +// ---------------- +// Author...: Sean Palmer +// Date ....: April 2001 +// Descr....: DDS File I/O Module + +#ifndef _DDSCLASS_ +#define _DDSCLASS_ + +#define DLLEXPORT __declspec(dllexport) + +#define DDS_CLASS_ID Class_ID(0xe3061ca, 0xd2120de) + +#pragma pack(push,1) + +struct DDSCOLORKEY +{ + DWORD dwColorSpaceLowValue; // low boundary of color space that is to + // be treated as Color Key, inclusive + DWORD dwColorSpaceHighValue; // high boundary of color space that is +}; + +struct DDSFILEHEADER +{ + DWORD dwMagic; // (0x20534444, or "DDS ") + + // the following matches DDSURFACEDESC2 + DWORD dwSize; // size of the DDSURFACEDESC structure + DWORD dwFlags; // determines what fields are valid + DWORD dwHeight; // height of surface to be created + DWORD dwWidth; // width of input surface + long lPitch; // distance to start of next line (return value only) + DWORD dwDepth; // the depth if this is a volume texture + DWORD dwMipMapCount; // number of mip-map levels requested + DWORD dwAlphaBitDepth; // depth of alpha buffer requested + DWORD dwReserved; // reserved + void* lpSurface; // pointer to the associated surface memory + DDSCOLORKEY ddckCKDestOverlay; // color key for destination overlay use + DDSCOLORKEY ddckCKDestBlt; // color key for destination blt use + DDSCOLORKEY ddckCKSrcOverlay; // color key for source overlay use + DDSCOLORKEY ddckCKSrcBlt; // color key for source blt use + + // from DDPIXELFORMAT structure + DWORD dwPFSize; // size of DDPIXELFORMAT structure + DWORD dwPFFlags; // pixel format flags + DWORD dwFourCC; // (FOURCC code) + DWORD dwRGBBitCount; // how many bits per pixel + DWORD dwRBitMask; // mask for red bit + DWORD dwGBitMask; // mask for green bits + DWORD dwBBitMask; // mask for blue bits + DWORD dwRGBAlphaBitMask; // mask for alpha channel + + // from DDSCAPS2 structure + DWORD dwCaps; // capabilities of surface wanted + DWORD dwCaps2; + DWORD dwCaps3; + DWORD dwVolumeDepth; + + DWORD dwTextureStage; // stage in multitexture cascade +//BYTE bData1[]; // Data for the main surface +//[BYTE bData2[]]; // Data for attached surfaces, if any, follows. +}; + +#pragma pack(pop) + +enum +{ + TF_DITHER = 0x40000000, + TF_MIPMAPS = 0x80000000, + TF_FMTMASK = 0x0000FFFF, +}; + +struct DDSParams +{ + int outFormat; // Output format +}; + +class BitmapIO_DDS : public BitmapIO +{ + +private: + + DDSFILEHEADER hdr; + DDSParams mParams; + +public: + + //-- Constructors/Destructors + + BitmapIO_DDS (); + ~BitmapIO_DDS (); + + //-- Number of extemsions supported + + int ExtCount () { return 1; } + + //-- Extension #n (i.e. "3DS") + + const TCHAR *Ext (int n) { return _T("dds"); } + + //-- Descriptions + + const TCHAR *LongDesc (); + const TCHAR *ShortDesc (); + + //-- Miscelaneous Messages + + const TCHAR *AuthorName () { return _T("Sean Palmer");} + const TCHAR *CopyrightMessage () { return _T("Copyright 2001 Treyarch LLC");} + const TCHAR *OtherMessage1 () { return _T("");} + const TCHAR *OtherMessage2 () { return _T("");} + + unsigned int Version () { return (100);} + + //-- Driver capabilities + + int Capability () { return BMMIO_READER | +// BMMIO_WRITER | + BMMIO_EXTENSION | + BMMIO_CONTROLWRITE;} + + //-- Driver Configuration + + BOOL LoadConfigure (void *ptr); + BOOL SaveConfigure (void *ptr); + DWORD EvaluateConfigure () { return sizeof(DDSParams); } + + //-- Show DLL's "About..." box + + void ShowAbout (HWND hWnd); + + //-- Show Image's control Dlg Box + BOOL ShowControl (HWND hWnd, DWORD flag); + + //-- Return info about image + + BMMRES GetImageInfo (BitmapInfo *fbi); + + //-- Image Input + + BitmapStorage *Load (BitmapInfo *fbi, Bitmap *map, BMMRES *status); + + //-- Image Output + + BMMRES OpenOutput (BitmapInfo *fbi, Bitmap *map); + BMMRES Write (int frame); + int Close (int flag); + + //-- This handler's specialized functions + + int ReadDDSHeader (FILE *stream); + + //-- Dialog Proc for the Image control Dlg box + + BOOL ConfigCtrlDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam); +}; + +#endif _DDSCLASS_ + diff --git a/NifProps/dds/dds.rc b/NifProps/dds/dds.rc new file mode 100644 index 0000000000000000000000000000000000000000..2d6329bc6fd19bbad065c291de4a9968226f8632 --- /dev/null +++ b/NifProps/dds/dds.rc @@ -0,0 +1,156 @@ +//Microsoft Developer Studio generated resource script. +// +#include "ddsres.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include <windows.h> +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "ddsres.h\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include <windows.h>\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""veroverrides.h""\r\n" + "#include ""maxversion.r""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_DDS_ABOUT DIALOG DISCARDABLE 0, 0, 166, 97 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "About DDS Image File I/O" +FONT 8, "MS Sans Serif" +BEGIN + DEFPUSHBUTTON "OK",IDOK,108,77,50,14 + RTEXT "DDS File I/O Module",IDC_STATIC,37,9,118,9 + RTEXT "Version 1.0",IDC_STATIC,37,19,118,9 + GROUPBOX "",IDC_STATIC,8,2,151,29 + RTEXT "Author: Sean L. Palmer",IDC_STATIC,9,38,148,8 + RTEXT "Copyright 2001 Treyarch LLC",IDC_STATIC,9,50,148,8 + RTEXT "Using NVIDIA nvDXTlib DDS converter",IDC_STATIC,9,62, + 148,8 +END + +IDD_DDS_CONFIG DIALOG DISCARDABLE 0, 0, 177, 185 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "DDS Configuration" +FONT 8, "MS Sans Serif" +BEGIN + GROUPBOX "Colors",-1,6,2,164,127,WS_GROUP + CONTROL "DXT1 Compression",IDC_DDS_DXT1,"Button", + BS_AUTORADIOBUTTON | WS_GROUP,29,15,128,10 + CONTROL "DXT1 with 1 bit alpha",IDC_DDS_DXT1ALPHA,"Button", + BS_AUTORADIOBUTTON,29,29,125,10 + CONTROL "DXT3 Compressed with alpha",IDC_DDS_DXT3,"Button", + BS_AUTORADIOBUTTON,29,43,125,10 + CONTROL "DXT5 Compressed with alpha",IDC_DDS_DXT5,"Button", + BS_AUTORADIOBUTTON,29,57,125,10 + CONTROL "ARGB 4444",IDC_DDS_ARGB4444,"Button",BS_AUTORADIOBUTTON, + 29,71,125,10 + CONTROL "ARGB 1555",IDC_DDS_ARGB1555,"Button",BS_AUTORADIOBUTTON, + 29,85,125,10 + CONTROL "RGB 565",IDC_DDS_RGB565,"Button",BS_AUTORADIOBUTTON,29, + 99,125,10 + CONTROL "ARGB 8888",IDC_DDS_ARGB8888,"Button",BS_AUTORADIOBUTTON, + 29,113,125,10 + DEFPUSHBUTTON "OK",IDOK,38,165,50,14 + PUSHBUTTON "Cancel",IDCANCEL,94,165,50,14 + CONTROL "Dither",IDC_DDS_DITHER,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,30,135,95,9 + CONTROL "Generate Mipmaps",IDC_DDS_MIPMAPS,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,30,148,96,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO DISCARDABLE +BEGIN + IDD_DDS_CONFIG, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 170 + TOPMARGIN, 7 + BOTTOMMARGIN, 179 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE DISCARDABLE +BEGIN + IDS_DDS "DDS" + IDS_BITMAP_IO "Bitmap I/O" + IDS_DDS_FILE "DDS Image File" + IDS_UNSUPPORTED "Unsupported DDS Image File" + IDS_CONVERT_ERROR "Error converting bitmap" + IDS_DDS_DESC "DDS file I/O" + IDS_NONPOWEROF2_ERROR "Dimensions not power of 2" + IDS_UNSUPPORTEDFORMAT_ERROR "Unsupported format" +END + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#include "veroverrides.h" + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/NifProps/dds/ddsTypes.h b/NifProps/dds/ddsTypes.h new file mode 100644 index 0000000000000000000000000000000000000000..576b75c15e814de7d8d9cea4d0be9ac4531e8700 --- /dev/null +++ b/NifProps/dds/ddsTypes.h @@ -0,0 +1,375 @@ +#pragma once +#include <windows.h> +#include <memory.h> + +#if defined(WIN32_LEAN_AND_MEAN) + #include <mmsystem.h> // MAKEFOURCC +#endif + +#include "tPixel.h" +#include "nvErrorCodes.h" + + +typedef unsigned char BYTE; +typedef unsigned short WORD; +typedef unsigned long DWORD; + + + + +typedef enum nvD3DFORMAT +{ + nvD3DFMT_UNKNOWN = 0, + + nvD3DFMT_R8G8B8 = 20, + nvD3DFMT_A8R8G8B8 = 21, + nvD3DFMT_X8R8G8B8 = 22, + nvD3DFMT_R5G6B5 = 23, + nvD3DFMT_X1R5G5B5 = 24, + nvD3DFMT_A1R5G5B5 = 25, + nvD3DFMT_A4R4G4B4 = 26, + nvD3DFMT_R3G3B2 = 27, + nvD3DFMT_A8 = 28, + nvD3DFMT_A8R3G3B2 = 29, + nvD3DFMT_X4R4G4B4 = 30, + nvD3DFMT_A2B10G10R10 = 31, + nvD3DFMT_A8B8G8R8 = 32, + nvD3DFMT_X8B8G8R8 = 33, + nvD3DFMT_G16R16 = 34, + nvD3DFMT_A2R10G10B10 = 35, + nvD3DFMT_A16B16G16R16 = 36, + + nvD3DFMT_A8P8 = 40, + nvD3DFMT_P8 = 41, + + nvD3DFMT_L8 = 50, + nvD3DFMT_A8L8 = 51, + nvD3DFMT_A4L4 = 52, + + nvD3DFMT_V8U8 = 60, + nvD3DFMT_L6V5U5 = 61, + nvD3DFMT_X8L8V8U8 = 62, + nvD3DFMT_Q8W8V8U8 = 63, + nvD3DFMT_V16U16 = 64, + nvD3DFMT_A2W10V10U10 = 67, + + nvD3DFMT_UYVY = MAKEFOURCC('U', 'Y', 'V', 'Y'), + nvD3DFMT_R8G8_B8G8 = MAKEFOURCC('R', 'G', 'B', 'G'), + nvD3DFMT_YUY2 = MAKEFOURCC('Y', 'U', 'Y', '2'), + nvD3DFMT_G8R8_G8B8 = MAKEFOURCC('G', 'R', 'G', 'B'), + nvD3DFMT_DXT1 = MAKEFOURCC('D', 'X', 'T', '1'), + nvD3DFMT_DXT2 = MAKEFOURCC('D', 'X', 'T', '2'), + nvD3DFMT_DXT3 = MAKEFOURCC('D', 'X', 'T', '3'), + nvD3DFMT_DXT4 = MAKEFOURCC('D', 'X', 'T', '4'), + nvD3DFMT_DXT5 = MAKEFOURCC('D', 'X', 'T', '5'), + nvD3DFMT_3Dc = MAKEFOURCC('A', 'T', 'I', '2'), + + nvD3DFMT_D16_LOCKABLE = 70, + nvD3DFMT_D32 = 71, + nvD3DFMT_D15S1 = 73, + nvD3DFMT_D24S8 = 75, + nvD3DFMT_D24X8 = 77, + nvD3DFMT_D24X4S4 = 79, + nvD3DFMT_D16 = 80, + + nvD3DFMT_D32F_LOCKABLE = 82, + nvD3DFMT_D24FS8 = 83, + + + nvD3DFMT_L16 = 81, + + nvD3DFMT_VERTEXDATA =100, + nvD3DFMT_INDEX16 =101, + nvD3DFMT_INDEX32 =102, + + nvD3DFMT_Q16W16V16U16 =110, + + nvD3DFMT_MULTI2_ARGB8 = MAKEFOURCC('M','E','T','1'), + + // Floating point surface formats + + // s10e5 formats (16-bits per channel) + nvD3DFMT_R16F = 111, + nvD3DFMT_G16R16F = 112, + nvD3DFMT_A16B16G16R16F = 113, + + // IEEE s23e8 formats (32-bits per channel) + nvD3DFMT_R32F = 114, + nvD3DFMT_G32R32F = 115, + nvD3DFMT_A32B32G32R32F = 116, + + nvD3DFMT_CxV8U8 = 117, + + + nvD3DFMT_FORCE_DWORD =0x7fffffff +} nvD3DFORMAT; + +typedef enum nvRescaleTypes +{ + kRescaleNone, // no rescale + kRescaleNearestPower2, // rescale to nearest power of two + kRescaleBiggestPower2, // rescale to next bigger power of 2 + kRescaleSmallestPower2, // rescale to smaller power of 2 + kRescaleNextSmallestPower2, // rescale to next smaller power of 2 + kRescalePreScale, // rescale to this size + kRescaleRelScale, // relative rescale + +} RescaleTypes; + + +typedef enum nvSharpenFilterTypes +{ + kSharpenFilterNone, + kSharpenFilterNegative, + kSharpenFilterLighter, + kSharpenFilterDarker, + kSharpenFilterContrastMore, + kSharpenFilterContrastLess, + kSharpenFilterSmoothen, + kSharpenFilterSharpenSoft, + kSharpenFilterSharpenMedium, + kSharpenFilterSharpenStrong, + kSharpenFilterFindEdges, + kSharpenFilterContour, + kSharpenFilterEdgeDetect, + kSharpenFilterEdgeDetectSoft, + kSharpenFilterEmboss, + kSharpenFilterMeanRemoval, + kSharpenFilterUnSharp, + kSharpenFilterXSharpen, + kSharpenFilterWarpSharp, + kSharpenFilterCustom, +}; + + +typedef enum nvMipMapGeneration +{ + kGenerateMipMaps = 30, + kUseExistingMipMaps = 31, + kNoMipMaps = 32, + kCompleteMipMapChain = 33, // fill in missing MIP maps + +}; + + +typedef enum nvMipFilterTypes +{ + kMipFilterPoint , + kMipFilterBox , + kMipFilterTriangle , + kMipFilterQuadratic , + kMipFilterCubic , + + kMipFilterCatrom , + kMipFilterMitchell , + + kMipFilterGaussian , + kMipFilterSinc , + kMipFilterBessel , + + kMipFilterHanning , + kMipFilterHamming , + kMipFilterBlackman , + kMipFilterKaiser, +}; + + +enum nvTextureFormats +{ + kDXT1 , + kDXT1a , // DXT1 with one bit alpha + kDXT3 , // explicit alpha + kDXT5 , // interpolated alpha + k4444 , // a4 r4 g4 b4 + k1555 , // a1 r5 g5 b5 + k565 , // a0 r5 g6 b5 + k8888 , // a8 r8 g8 b8 + k888 , // a0 r8 g8 b8 + k555 , // a0 r5 g5 b5 + kP8c , // paletted color only + kV8U8 , // DuDv + kCxV8U8 , // normal map + kA8 , // alpha only + kP4c , // 16 bit color palette + kQ8W8V8U8, + kA8L8, + kR32F, + kA32B32G32R32F, + kA16B16G16R16F, + kL8, // luminance + kP8a , // paletted with alpha + kP4a , // 16 bit color palette with alpha + kR16F, // single component fp16 + kDXT5_NM , // normal map compression. G = Y, A = X + kX888 , // aX r8 g8 b8 + kV16U16, + kG16R16, + kG16R16F, + k3Dc, + kL16, + + kUnknownTextureFormat = 0xFFFFFFFF, + +}; + + +enum nvTextureTypes +{ + kTextureTypeTexture2D, + kTextureTypeCubeMap, + kTextureTypeVolumeMap, +}; + + +enum nvCompressionWeighting +{ + kLuminanceWeighting, + kGreyScaleWeighting, + kTangentSpaceNormalMapWeighting, + kObjectSpaceNormalMapWeighting, + kUserDefinedWeighting, // used values stored in 'weight' +}; + +enum nvNormalMapFilters +{ + kFilter4x = 1040, + kFilter3x3 = 1041, + kFilter5x5 = 1042, + kFilter7x7 = 1043, + kFilter9x9 = 1044, + kFilterDuDv = 1045, +}; + + +enum nvHeightConversionMethods +{ + kAlphaChannel = 1009, + kAverageRGB = 1010, + kBiasedRGB = 1011, + kRed = 1012, + kGreen = 1013, + kBlue = 1014, + kMaxRGB = 1015, + kColorSpace = 1016, + kNormalize = 1017, + kNormalMapToHeightMap = 1018, +}; + +enum nvAlphaResult +{ + kAlphaUnchanged = 1033, + kAlphaHeight = 1034, + kAlphaSetToZero = 1035, + kAlphaSetToOne = 1036, +}; + + +enum nvQualitySetting +{ + kQualityFastest = 68, + kQualityNormal = 69, + kQualityProduction = 71, // typical value + kQualityHighest = 72, +}; + + +enum nvPixelFormat +{ + PF_RGBA, + PF_FP32, +}; + + + +// filled in by reading a dds file +struct DDS_PIXELFORMAT +{ + DWORD dwSize; + DWORD dwFlags; + DWORD dwFourCC; + DWORD dwRGBBitCount; + DWORD dwRBitMask; + DWORD dwGBitMask; + DWORD dwBBitMask; + DWORD dwRGBAlphaBitMask; +}; + + +class nvImageContainer +{ + +public: + // loaded directly from the .dds header + DDS_PIXELFORMAT m_ddpfPixelFormat; + + + nvImageContainer() + { + + bits_per_component = 0; //image's resolution in bits per pixel per plane + paletteSize = 0; + + + + bFoundAlphaInRead = false; + bCompressed = false; + fmt = 0; // nvD3DFMT_UNKNOWN + + dwCubeMapFlags = 0; + + actualMipMapCount = 1; + //maxPossibleMipMapCount = 1; + nMIPMapsToLoad = 1; + depth = 0; + + + } + + + + // in file read + size_t width; // of MIP 0 + size_t height; // of MIP 0 + size_t depth; // for volume maps + + size_t actualMipMapCount; + size_t nMIPMapsToLoad; + + + bool bFoundAlphaInRead; // is alpha field present and non-zero + + // in the input file + + DWORD dwCubeMapFlags; + size_t bits_per_component; + size_t nPlanes; // number of planes in the file format + bool bCompressed; // is file a compressed format + size_t paletteSize; // 16 or 256 entries + rgba_t palette[256]; + + DWORD fmt; // D3DFORMAT specified in .dds file + + nvTextureFormats textureFormat; + + nvTextureTypes textureType; + + + + + + fpMipMappedImage fpMIPImage; + fpMipMappedCubeMap fpMIPCubeMap; + fpMipMappedVolumeMap fpMIPVolumeMap; + + RGBAMipMappedImage rgbaMIPImage; + RGBAMipMappedCubeMap rgbaMIPCubeMap; + RGBAMipMappedVolumeMap rgbaMIPVolumeMap; + + + ~nvImageContainer() + { + } +}; + + + diff --git a/NifProps/dds/ddsres.h b/NifProps/dds/ddsres.h new file mode 100644 index 0000000000000000000000000000000000000000..17688d0d4b7aac49b2b642a6213c1460f756c7df --- /dev/null +++ b/NifProps/dds/ddsres.h @@ -0,0 +1,46 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by dds.rc +// +#define IDS_DDS 1 +#define IDS_BITMAP_IO 2 +#define IDS_DDS_FILE 3 +#define IDS_UNSUPPORTED 4 +#define IDS_CONVERT_ERROR 5 +#define IDS_DDS_DESC 6 +#define IDS_NONPOWEROF2_ERROR 7 +#define IDS_UNSUPPORTEDFORMAT_ERROR 8 +#define IDD_DDS_ABOUT 101 +#define IDD_DDS_CONTROL 102 +#define IDD_DDS_CONFIG 102 +#define IDC_DDS_PALETTE 1000 +#define IDC_DDS_DXT1 1000 +#define IDC_RAD_NTSC 1001 +#define IDC_RAD_24 1001 +#define IDC_DDS_RGB24 1001 +#define IDC_DDS_ARGB8888 1001 +#define IDC_RAD_PAL 1002 +#define IDC_RAD_8 1002 +#define IDC_DDS_DXT3 1002 +#define IDC_EDIT_X 1003 +#define IDC_DDS_DXT1ALPHA 1003 +#define IDC_EDIT_Y 1004 +#define IDC_DDS_DXT5 1004 +#define IDC_RAD_CUSTOM 1005 +#define IDC_DDS_ARGB1555 1005 +#define IDC_DDS_ARGB4444 1006 +#define IDC_DDS_RGB565 1007 +#define IDC_DDS_DITHER 1008 +#define IDC_DDS_MIPMAPS 1009 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 103 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1010 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/NifProps/dds/dxtlib.h b/NifProps/dds/dxtlib.h new file mode 100644 index 0000000000000000000000000000000000000000..84f6852b113944914dd90ae9623543eacbb44e8d --- /dev/null +++ b/NifProps/dds/dxtlib.h @@ -0,0 +1,124 @@ +/*********************************************************************NVMH2**** +Path: C:\Dev\devrel\Nv_sdk_4\Dx8_private\PhotoShop\dxtlib +File: dxtlib.h + +Copyright (C) 1999, 2000 NVIDIA Corporation +This file is provided without support, instruction, or implied warranty of any +kind. NVIDIA makes no guarantee of its fitness for a particular purpose and is +not liable under any circumstances for any damages or loss whatsoever arising +from the use or inability to use this file or items derived from it. + +Comments: + + +******************************************************************************/ + + + + +#pragma comment(lib, "C:\\Development\\Projects\\NifLib\\niftools\\trunk\\max\\NifProps\\dds\\nvDXTlib.lib") +//#pragma comment(lib, "C:\\Development\\Projects\\NifLib\\niftools\\trunk\\max\\NifProps\\dds\\nvDXTlib.vc7.lib") + + + + + + + + +typedef HRESULT (*MIPcallback)(void * data, int miplevel, DWORD size); +// call back +// pointer to data +// mip level +// size of chunk + + +/* + Compresses an image with a user supplied callback with the data for each MIP level created + Only supports input of RGB 24 or ARGB 32 bpp +*/ +HRESULT nvDXTcompress(unsigned char * raw_data, // pointer to data (24 or 32 bit) + unsigned long w, // width in texels + unsigned long h, // height in texels + DWORD TextureFormat, // list below + bool bGenMipMaps, // auto gen MIP maps + bool bDither, + DWORD depth, // 3 or 4 + MIPcallback callback = 0); // callback for generated levels +// if callback is == 0 (or not specified), then WriteDTXnFile is called with all file info +// +// You must write the routines (or provide stubs) +// void WriteDTXnFile(count, buffer); +// void ReadDTXnFile(count, buffer); +// +// +/* returns + w width + h height + depth ( 3 or 4) + total_width + rowBytes - pitch + +*/ +unsigned char * nvDXTdecompress(int & w, int & h, int & depth, int & total_width, int & rowBytes); + + +// see examples + + +void WriteDTXnFile(DWORD count, void * buffer); +void ReadDTXnFile(DWORD count, void * buffer); + + +// TextureFormat +#define TF_DXT1 10 +#define TF_DXT1_1BitAlpha 11 +#define TF_DXT3 12 +#define TF_DXT5 13 +#define TF_RGB4444 14 +#define TF_RGB1555 15 +#define TF_RGB565 16 +#define TF_RGB8888 17 + + +#define DXTERR_INPUT_POINTER_ZERO -1 +#define DXTERR_DEPTH_IS_NOT_3_OR_4 -2 +#define DXTERR_NON_POWER_2 -3 + +/* example + +LPDIRECT3DTEXTURE8 pCurrentTexture = 0; + +HRESULT LoadAllMipSurfaces(void * data, int iLevel) +{ + HRESULT hr; + LPDIRECT3DSURFACE8 psurf; + D3DSURFACE_DESC sd; + D3DLOCKED_RECT lr; + + hr = pCurrentTexture->GetSurfaceLevel(iLevel, &psurf); + + if (FAILED(hr)) + return hr; + psurf->GetDesc(&sd); + + + hr = pCurrentTexture->LockRect(iLevel, &lr, NULL, 0); + if (FAILED(hr)) + return hr; + + memcpy(lr.pBits, data, sd.Size); + + hr = pCurrentTexture->UnlockRect(iLevel); + + ReleasePpo(&psurf); + + return 0; +} + + + hr = D3DXCreateTexture(m_pd3dDevice, Width, Height, nMips, 0, D3DFMT_DXT3, D3DPOOL_MANAGED, &pCurrentTexture); + nvDXTcompress(raw_data, Width, Height, DXT3, true, 4, LoadAllMipSurfaces); + +*/ + diff --git a/NifProps/dds/nvDXTlib.lib b/NifProps/dds/nvDXTlib.lib new file mode 100644 index 0000000000000000000000000000000000000000..8675cab326a4d86972a04a50c0ff88c9151c930c Binary files /dev/null and b/NifProps/dds/nvDXTlib.lib differ diff --git a/NifProps/dds/nvErrorCodes.h b/NifProps/dds/nvErrorCodes.h new file mode 100644 index 0000000000000000000000000000000000000000..e6fa48bc448f5f55aee6b716aaaa1804e7966f03 --- /dev/null +++ b/NifProps/dds/nvErrorCodes.h @@ -0,0 +1,112 @@ +#pragma once + +typedef enum NV_ERROR_CODE +{ + NV_OK = 0, + NV_FAIL = -1, // generic + NV_CANT_OPEN_INPUT_FILE = -2, + NV_CANT_OPEN_OUTPUT_FILE = -3, + NV_BAD_OPTION = -4, + NV_BAD_OUTPUT_DIRECTORY = -5, + NV_CANT_DECOMPRESS_IMAGE = -6, + NV_BAD_LIST_FILE = -7, + NV_CANT_OPEN_LIST_FILE = -8, + NV_BAD_LIST_FILE_CONTENTS = -9, + NV_IMAGE_NOT_SQUARE = -10, + NV_IMAGES_NOT_SAME_SIZE = -11, + NV_UNKNOWN_CONVERSION = -12, // for normal map generation + NV_CANT_OPEN_PROFILE = -13, + NV_IMAGE_NOT_MULT4 = -14, + NV_OUTPUT_FILE_IS_READ_ONLY= -15, + NV_INPUT_POINTER_ZERO = -16, + NV_DEPTH_IS_NOT_3_OR_4 = -17, + NV_IMAGE_NOT_POWER_2 = -18, + NV_CANT_MAKE_MATRIX = -19, + NV_CANT_NORMALIZE = -20, + NV_CANT_INVERT_MATRIX = -21, + NV_CANT_MAKE_VECTOR = -22, + NV_CANT_INITIALIZE_CONVOLVER = -23, + NV_EMPTY_IMAGE = -24, + NV_BAD_FLAGS = -25, + NV_GBM_IO_ERR = -26, + NV_TGA_IO_ERR = -27, + NV_TGA_RLE_ERR = -28, + NV_PNG_IO_ERR = -29, + NV_CANT_CREATE_INDEX_BUFFER= -30, + NV_CANT_CREATE_CUBE_MAP = -31, + NV_BAD_FORMAT = -32, + NV_CANT_CREATE_TEXTURE = -33, + NV_UNKNOWN_FORMAT = -34, + NV_CANT_CREATE_VERTEX_BUFFER = -35, + NV_CANT_CREATE_PIXEL_SHADER= -36, + NV_CANT_CREATE_VERTEX_DECL = -37, + NV_NEED_4_PLANES_FOR_RGBE = -38, + NV_PSD_IO_ERR = -39, + NV_NO_FILENAME = -40, + + NV_CANT_DECOMPOSE_MATRIX = -41, + NV_HDR_IO_ERR = -42, + NV_RGBA_IO_ERR = -43, + NV_READ_FAILED = -44, + NV_WRITE_FAILED = -45, + NV_BAD_ARG = -46, + NV_CANT_LOCK = -47, + NV_FAILED_UNLOCK = -48, + NV_NOT_RING_LOOP = -49, + + NV_CHART_FOLDED = -50, + NV_CHART_CANNOT_INVERT = -51, + NV_CHART_BAD_PERIMETER = -52, + NV_CHART_NO_DATA = -53, + NV_CHART_CANT_OPTIMIZE = -54, + NV_CHART_NO_POINTS_FOUND = -55, + NV_CHART_ZERO_SIZE = -56, + NV_CHART_NO_UNPINNED = -57, + NV_CHART_OVERLAP = -58, + NV_CHART_NO_FACES = -59, + NV_CHART_MAX_DISTORTION_EXCEEDED = -60, + NV_CHART_AVE_DISTORTION_EXCEEDED = -61, + + NV_CANT_CREATE_PRECONDITIONER = -70, + NV_NO_CONVERGENCE = -71, + NV_ZERO_DIAGONAL = -72, + NV_ZERO_TRIANGLE_AREA = -73, + NV_LINE_ON_PLANE = -74, + NV_LINE_AND_PLANE_PARALLEL = -75, + NV_CANT_COMPILE_EFFECT_FILE = -76, + // open + NV_CANT_UNLOCK_INDEX_BUFFER = -78, + NV_CANT_CLONE_MESH = -79, + NV_CANT_FIND_FILE = -80, + NV_INVALID_FILENAME = -81, + NV_CANT_SET_MATRIX = -82, + NV_NEED_PIXEL_SHADER2 = -83, + NV_CANT_UNLOCK_TEXTURE = -84, + NV_OUT_OF_MEMORY = -85, + NV_TIFF_IO_ERR = -86, + + + NV_FILE_BAD_INDEX = -90, + NV_FILE_NOT_ENOUGH_INDICES = -91, + NV_FILE_FORMAT_NOT_SUPPORTED= -92, + NV_CANT_CREATE_EFFECT = -93, + NV_NAN = -94, + + NV_SURFACE_IS_CUBE_MAP = -95, + NV_SURFACE_IS_VOLUME_MAP = -96, + NV_UNSUPPORTED_FORMAT = -97, + NV_MEMORY_ALLOCATION_FAILED = -98, + NV_CUBE_MAP_NEEDS_SIX_FACES = -99, + NV_IMAGE_EXCEEDS_INTERNAL_SIZE = -100, + NV_CUBE_MAP_WIDTH_IS_NOT_SIX_TIMES_HEIGHT = -101, + NV_VOLUME_MAP_IS_NOT_POWER2 = -102, + + + + +}; + + const char *getErrorString(NV_ERROR_CODE hr); + + + diff --git a/NifProps/dds/nvdxt_options.h b/NifProps/dds/nvdxt_options.h new file mode 100644 index 0000000000000000000000000000000000000000..3c8251626f77ee59368a661dc1ca5ac191aa3572 --- /dev/null +++ b/NifProps/dds/nvdxt_options.h @@ -0,0 +1,779 @@ +/**************************************************************************************** + + Copyright (C) NVIDIA Corporation 2003 + + TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED + *AS IS* AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS + OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS + BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES + WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, + BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) + ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS + BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +*****************************************************************************************/ +#pragma once + +#include <windows.h> +#include "tPixel.h" +#include "ddsTypes.h" + +inline char * GetDXTCVersion() { return "Version 8.30";} + +// max mip maps +#define MAX_MIP_MAPS 17 + + +typedef unsigned char nvBoolean; // for photoshop scripting + + + + +typedef struct nvNormalMap +{ +public: + + + nvNormalMap() + { + bEnableNormalMapConversion = false; + + minz = 0; + scale = 1; + filterKernel = kFilter3x3; + + heightConversionMethod = kAverageRGB; + alphaResult = kAlphaUnchanged; + + bWrap = false; + bInvertX = false; + bInvertY = false; + bInvertZ = false; + bAddHeightMap = false; + bNormalMapSwapRGB = false; + + + } + nvBoolean bEnableNormalMapConversion; // do not convert to a normal map + int minz; // minimum value the z value can attain in the x y z normal + // keeps normal point "upwards" + float scale; // height multiplier + + + + nvNormalMapFilters filterKernel; // kernel used to create normal maps. Done this way to be compatible with plugins + nvHeightConversionMethods heightConversionMethod; // method to convert color to height + nvAlphaResult alphaResult; // what to do with the alpha channel when done + + nvBoolean bWrap; + nvBoolean bInvertX; // flip the x direction + nvBoolean bInvertY; // flip the y direction + nvBoolean bInvertZ; // flip the z direction + + nvBoolean bAddHeightMap; + nvBoolean bNormalMapSwapRGB; // swap color channels +} nvNormalMap; + +class nvCompressionOptions +{ +public: + + nvCompressionOptions() + { + SetDefaultOptions(); + } + + + void SetDefaultOptions() + { + quality = kQualityProduction; + rmsErrorSearchThreshold = 400; // in kQualityHighest mode, rms error above which will cause a long search for a better answer + + rescaleImageType = kRescaleNone; + rescaleImageFilter = kMipFilterCubic; + scaleX = 1; + scaleY = 1; + bClamp = false; + clampX = 4096; + clampY = 4096; + + bClampScale = false; + clampScaleX = 4096; + clampScaleY = 4096; + + mipMapGeneration = kGenerateMipMaps; // dNoMipMaps, dUseExistingMipMaps, dGenerateMipMaps + numMipMapsToWrite = 0; // (number of mipmaps to write out) + + mipFilterType = kMipFilterTriangle; // for MIP maps + + bBinaryAlpha = false; // zero or one alpha channel + + bRGBE = false; + + bAlphaBorder = false; // make an alpha border + bAlphaBorderLeft = false; + bAlphaBorderRight = false; + + bAlphaBorderTop = false; + bAlphaBorderBottom = false; + + + bBorder = false; // make a color border + borderColor32F.r = 0.0f; // color of border + borderColor32F.g = 0.0f; // color of border + borderColor32F.b = 0.0f; // color of border + borderColor32F.a = 0.0f; // alpha of border + + bFadeColor = false; // fade color over MIP maps + bFadeAlpha = false; // fade alpha over MIP maps + + fadeToColor32F.r = 0.0f; // color to fade to + fadeToColor32F.g = 0.0f; // color to fade to + fadeToColor32F.b = 0.0f; // color to fade to + fadeToColor32F.a = 0.0f; // alpha to fade to + + fadeToDelay = 0; // start fading after 'n' MIP maps + + fadeAmount32F = 0.15f; // percentage of color to fade in %15 + + alphaThreshold32F = 0.5; // When Binary Alpha is selected, below this value, alpha is zero + + + bDitherColor = false; // enable dithering during 16 bit conversion + bDitherMip0 = false;// enable dithering during 16 bit conversion for each MIP level (after filtering) + + bForceDXT1FourColors = false; // do not let DXT1 use 3 color representation + + + sharpenFilterType = kSharpenFilterNone; + bErrorDiffusion = false; + errorDiffusionWidth = 1; + + weightType = kLuminanceWeighting; + bNormalizeTexels = false; + + weight[0] = 0.3086f; // luminance conversion values + weight[1] = 0.6094f; + weight[2] = 0.0820f; + + // gamma value for all filters + bEnableFilterGamma = false; + filterGamma = 2.2f; + + // alpha value for + filterBlur = 1.0f; + // width of filter + filterWidth = 10.0f; + bOverrideFilterWidth = false; + + textureType = kTextureTypeTexture2D; // regular decal, cube or volume + textureFormat = kDXT1; // + + bSwapRG = false; // swap color positions R and G + bSwapRB = false; // swap color positions R and G + user_data = NULL; // user supplied point passed down to write functions + + int i,j; + + float default_filter[5][5] = + { + 0, 0, 0, 0, 0, + 0, 0, -2, 0, 0, + 0,-2, 11,-2, 0, + 0, 0, -2, 0, 0, + 0, 0, 0, 0, 0, + }; + + + for(i = 0; i<5; i++) + { + for(j = 0; j<5; j++) + { + custom_filter_data.filter[i][j] = default_filter[i][j]; + } + } + + custom_filter_data.div = 3; // div + custom_filter_data.bias = 0; // bias + + unsharp_data.radius32F = 5.0; // radius + unsharp_data.amount32F = 0.5; // amount + unsharp_data.threshold32F = 0; // threshold + + xsharp_data.strength32F = 1.0f; // xsharp strength + xsharp_data.threshold32F = 1.0f; // xsharp threshold + + + sharpening_passes_per_mip_level[0] = 0; + + for(i = 1; i<MAX_MIP_MAPS; i++) + sharpening_passes_per_mip_level[i] = 1; + + bAlphaFilterModulate = false; + bPreModulateColorWithAlpha = false; + + + bUserSpecifiedFadingAmounts = false; + + + for(i = 0; i<256; i++) + { + color_palette[i].r = 0; + color_palette[i].g = 0; + color_palette[i].b = 0; + color_palette[i].a = 0; + } + + paletteSize = 0; // this will be set by the format read or write + autoGeneratePalette = false; + + + outputScale.r = 1.0f; // scale and bias when writing output values + outputScale.g = 1.0f; // scale and bias when writing output values + outputScale.b = 1.0f; // scale and bias when writing output values + outputScale.a = 1.0f; // scale and bias when writing output values + + outputBias.r = 0.0f; + outputBias.g = 0.0f; + outputBias.b = 0.0f; + outputBias.a = 0.0f; + + inputScale.r = 1.0f; // scale and bias after loading data + inputScale.g = 1.0f; // scale and bias + inputScale.b = 1.0f; // scale and bias + inputScale.a = 1.0f; // scale and bias + + inputBias.r = 0.0f; + inputBias.g = 0.0f; + inputBias.b = 0.0f; + inputBias.a = 0.0f; + + + + bConvertToGreyScale = false; + greyScaleWeight.r = 0.3086f; // scale and bias after loading data + greyScaleWeight.g = 0.6094f; // scale and bias + greyScaleWeight.b = 0.0820f; // scale and bias + greyScaleWeight.a = 0.0f; // scale and bias + + + brightness.r = 0.0; // adjust brightness = 0 none + brightness.g = 0.0; // + brightness.b = 0.0; // + brightness.a = 0.0; // + + contrast.r = 1; // contrast 1 == none + contrast.g = 1; + contrast.b = 1; + contrast.a = 1; + + bCalcLuminance = false; // do not convert to luminance by default + + bOutputWrap = false; // wrap the values when outputting to the desired format + // + + bCreateOnePalette = false; + + } + + /////////////////////////// COMPRESSION QUALITY ////////////////////////////////// + + nvQualitySetting quality; + float rmsErrorSearchThreshold; + + + void SetQuality(nvQualitySetting setting, float threshold) + { + quality = setting; + // if setting == kQualityHighest, if the RMS error for a 4x4 block is bigger than + // this, an extended search is performed. In practice this has been equivalent to and + // exhaustive search in the entire domain. aka it doesn't get any better than this. + + rmsErrorSearchThreshold = threshold; + + + } + + /////////////////////////////// COMPRESSION WEIGHTING ////////////////////////////// + nvCompressionWeighting weightType; // weighting type for DXT compressop + float weight[3]; // weights used for compress + + void SetCompressionWeighting(nvCompressionWeighting type, float new_weight[3]) + { + weightType = type; + + // if type == kUserDefinedWeighting, then use these weights + weight[0] = new_weight[0]; + weight[1] = new_weight[1]; + weight[2] = new_weight[2]; + + } + + + ///////////////////////////////////////////////////////////// + + nvNormalMap normalMap; // filled when processing normal maps + + nvBoolean bNormalizeTexels; // normalize the texels + + + + + /////////////////////////// SCALING IMAGE ///////////////////////////////// + + nvRescaleTypes rescaleImageType; // rescaling type before image before compression + nvMipFilterTypes rescaleImageFilter; // rescaling filter + + float scaleX; // scale to this if we are prescaling images before compressing + float scaleY; + + + // scale the image to this size first + void PreScaleImage(float x, float y, nvMipFilterTypes filter) + { + rescaleImageType = kRescalePreScale; + scaleX = x; + scaleY = y; + rescaleImageFilter = filter; + } + // relative scaling. 0.5 is half the image size + void RelativeScaling(float x, float y, nvMipFilterTypes filter) + { + rescaleImageType = kRescaleRelScale; + scaleX = x; + scaleY = y; + rescaleImageFilter = filter; + + } + + void RescaleToNearestPOW2(nvMipFilterTypes filter) + { + rescaleImageType = kRescaleNearestPower2; + rescaleImageFilter = filter; + + } + void RescaleToNearestBiggestPOW2(nvMipFilterTypes filter) + { + rescaleImageType = kRescaleBiggestPower2; + rescaleImageFilter = filter; + + } + void RescaleToNearestSmallestPOW2(nvMipFilterTypes filter) + { + rescaleImageFilter = filter; + rescaleImageType = kRescaleSmallestPower2; + + } + void RescaleToNearestNextSmallestPOW2(nvMipFilterTypes filter) + { + rescaleImageType = kRescaleNextSmallestPower2; + rescaleImageFilter = filter; + + } + + /////////////////// CLAMPING IMAGE SIZE /////////////////////////////////// + nvBoolean bClamp; // Clamp to max size + float clampX; // clamping values + float clampY; + + // image no bigger than... + void ClampMaxImageSize(float maxX, float maxY) + { + bClamp = true; + clampX = maxX; + clampY = maxY; + } + + + nvBoolean bClampScale; // maximum value of h or w (retain scale) + float clampScaleX; // clamping values + float clampScaleY; + + // clamp max image size and maintain image proportions. + // Evenly scale down in both directions so that the given image size is not exceeded + void ClampMaxImageSizeContrained(float maxX, float maxY) + { + bClampScale = true; + clampScaleX = maxX; + clampScaleY = maxY; + } + + ///////////////////////////// MIP MAPS /////////////////////////////////// + + nvMipMapGeneration mipMapGeneration; // changed MIPMaptype to an enum + + long numMipMapsToWrite; // max number of Mip maps to generate + + // 0 = all + void GenerateMIPMaps(int n) + { + mipMapGeneration = kGenerateMipMaps; + numMipMapsToWrite = n; + + } + void DoNotGenerateMIPMaps() + { + mipMapGeneration = kNoMipMaps; + + } + void UseExisitingMIPMaps() + { + // what ever is in the image + mipMapGeneration = kUseExistingMipMaps; + //numMipMapsToWrite is ignored + } + void CompleteMIPMapChain(int n) + { + mipMapGeneration = kCompleteMipMapChain; + numMipMapsToWrite = n; + } + + nvMipFilterTypes mipFilterType; // for MIP map, select from MIPFilterTypes + + + /////////////////// ALPHA ////////////////////////////////////////// + nvBoolean bBinaryAlpha; // zero or one alpha channel + + // [0,1] + float alphaThreshold32F; // threshold for alpha transparency DXT1 + // or wen Binary Alpha is selected, below this value, alpha is zero + + void SetBinaryAlpha(float threshold) + { + bBinaryAlpha = true; + alphaThreshold32F = threshold; + + } + + + + + ////////////////////////// BORDERS ///////////////////////////////////////// + + // set any of these to generate an alpha border + nvBoolean bAlphaBorder; // make an alpha border + nvBoolean bAlphaBorderLeft; // make an alpha border on just the left + nvBoolean bAlphaBorderRight; // make an alpha border on just the right + + nvBoolean bAlphaBorderTop; // make an alpha border on just the top + nvBoolean bAlphaBorderBottom; // make an alpha + + nvBoolean bBorder; // make a color border + fpPixel borderColor32F; // color of border [0,1] + + void SetBorderColor(fpPixel & color) + { + bBorder = true; + borderColor32F = color; + + } + void NoBorderColor() + { + bBorder = false; + + } + + /////////////////////// FADING MIP LEVELS //////////////////////////// + + nvBoolean bFadeColor; // fade color over MIP maps + nvBoolean bFadeAlpha; // fade alpha over MIP maps + + fpPixel fadeToColor32F; // color and alpha to fade to + + long fadeToDelay; // start fading after 'n' MIP maps + + float fadeAmount32F; // percentage of color to fade in + + nvBoolean bUserSpecifiedFadingAmounts; + float userFadingAmounts[MAX_MIP_MAPS]; + + + // [0,1] + void FadeAlphaInMIPMaps(float alpha) + { + bFadeAlpha = true; + fadeToColor32F.a = alpha; + + + } + // 0 - 255 + void FadeColorInMIPMaps(float r, float g, float b) + { + fadeToColor32F.r = r; + fadeToColor32F.g = g; + fadeToColor32F.b = b; + + + bFadeColor = true; + } + void SetFadingAsPercentage(float percentPerMIP, int mipLevelToStartFading) + { + bUserSpecifiedFadingAmounts = false; + + fadeAmount32F = percentPerMIP; + fadeToDelay = mipLevelToStartFading; + } + // or + void SpecifyFadingPerMIPLevel(float fadeAmounts[MAX_MIP_MAPS]) + { + bUserSpecifiedFadingAmounts = true; + + for(int i = 0; i < MAX_MIP_MAPS; i++) + { + userFadingAmounts[i] = fadeAmounts[i]; + } + } + + + + /////////////////////////// SHARPENING ///////////////////////////////////// + + // sharpening after creating each MIP map level + + // used when custom sharping filter is used + // 5x5 filter + struct + { + float filter[5][5]; + float div; + float bias; + + } custom_filter_data; + + + + // used when unsharpen sharping filter is used + struct + { + float radius32F; // radius + float amount32F; // amount + float threshold32F; // threshold [0,1] + + } unsharp_data; + + // used when xsharpen sharping filter is used + struct + { + // 0 - 1 + float strength32F; + float threshold32F; + } xsharp_data; + + + int sharpening_passes_per_mip_level[MAX_MIP_MAPS]; + + nvSharpenFilterTypes sharpenFilterType; // post filtering image sharpening + + + void SetNumberOfSharpeningPassesPerMIPLevel( int passes[MAX_MIP_MAPS]) + { + for (int i = 0; i < MAX_MIP_MAPS; i++) + { + sharpening_passes_per_mip_level[i] = passes[i]; + } + } + + // [0,1] + void XSharpenImage(float strength, float threshold) + { + sharpenFilterType = kSharpenFilterXSharpen; + xsharp_data.strength32F = strength; + xsharp_data.threshold32F = threshold; + } + + void UnSharpenImage(float radius, float amount, float threshold) + { + sharpenFilterType = kSharpenFilterUnSharp; + unsharp_data.radius32F = radius; + unsharp_data.amount32F = amount; + unsharp_data.threshold32F = threshold; + } + + // roll your own post filter sharpen + void SetCustomFilter(float filter[5][5], float div, float bias) + { + sharpenFilterType = kSharpenFilterCustom; + custom_filter_data.div = div; + custom_filter_data.bias = bias; + + for(int i = 0; i<5; i++) + for(int j = 0; j<5; j++) + custom_filter_data.filter[i][j] = filter[i][j]; + + } + + ///////////////////////////////////////////////////// + + + + + + nvBoolean bErrorDiffusion; // diffuse error, used for helping gradient images + int errorDiffusionWidth; // number of texel to include + + void EnableErrorDiffusion(int width) + { + bErrorDiffusion = true; + errorDiffusionWidth = width; + } + ///////////////////// FILTERING //////////////////////////////////////// + // convert to gamma space before filtering + nvBoolean bEnableFilterGamma; + float filterGamma; // gamma value for filtering (MIP map generation) + + + float filterBlur; // sharpness or blurriness of filtering + nvBoolean bOverrideFilterWidth; // use the specified width in FilterWidth,instead of the default + float filterWidth; // override fiter width with this value + + + // 0 is no gamma correction + void EnableGammaFiltering(float gamma) + { + bEnableFilterGamma = true; + + filterGamma = gamma; + } + + void OverrideFilterWidth(float w) + { + bOverrideFilterWidth = true; + filterWidth = w; + + + } + void SetFilterSharpness(float sharp) + { + filterBlur = sharp; + } + + ///////////////////////////////////////////////////// + + + + + nvTextureTypes textureType; // what type of texture is this? + + + nvTextureFormats textureFormat; // format to convert to + + void SetTextureFormat(nvTextureTypes type, nvTextureFormats format ) + { + textureType = type; + textureFormat = format; + } + + + size_t paletteSize; + rgba_t color_palette[256]; + + nvBoolean autoGeneratePalette; // generate palette for p8 and p4 formats + + + // for P4 and P8 formats + // set 16 for P4 format and 256 for P8 format + + void SetPalette(int n, rgba_t user_palette[256]) + { + paletteSize = n; + for(int i = 0; i < n; i++) + color_palette[i] = user_palette[i]; + + autoGeneratePalette = false; + + } + + + + + ////////////////// DATA SCALING + + + fpPixel outputScale; // scale and bias when writing output values + fpPixel outputBias; + + void ScaleBiasOutput(fpPixel & scale, fpPixel & bias) + { + outputScale = scale; + outputBias = bias; + + } + + + fpPixel inputScale; // scale and bias on input to compressor + fpPixel inputBias; + + void ScaleBiasInput(fpPixel & scale, fpPixel & bias) + { + inputScale = scale; + inputBias = bias; + + } + + /////////////////////////////////////////////////////////////////////////////////// + + bool bConvertToGreyScale; + fpPixel greyScaleWeight; + + void SetGreyScale(fpPixel & w) + { + bConvertToGreyScale = true; + greyScaleWeight = w; + + } + + + + + ///////////////////////////////////////////////////////////////////////////// + fpPixel brightness; + fpPixel contrast; + + + void SetBrightnessAndContrast(fpPixel & _brightness, fpPixel & _contrast) + { + brightness = _brightness; + contrast = _contrast; + } + + + + /////////// general enables + ///////////////////////////////////////////////////////////////////////////// + nvBoolean bOutputWrap; // wrap the values (before clamping to the format range) + // when outputting to the desired format + + nvBoolean bCalcLuminance; // convert color to luminance for 'L' formats + + nvBoolean bSwapRB; // swap color positions R and G + nvBoolean bSwapRG; // swap color positions R and G + + + nvBoolean bForceDXT1FourColors; // do not let DXT1 use 3 color representation + + + nvBoolean bRGBE; // rgba_t is in RGBE format + + nvBoolean bCreateOnePalette; // All 4x4 compression blocks share the same palette + + + + + /////////////////// DISABLED + + nvBoolean bDitherColor; // enable dithering during 16 bit conversion + nvBoolean bDitherMip0; // enable dithering during 16 bit conversion for each MIP level (after filtering) + + + nvBoolean bPreModulateColorWithAlpha; // modulate color by alpha + nvBoolean bAlphaFilterModulate; // modulate color by alpha for filtering only + + + + ///////////////////////// USER DATA + + void * user_data; // user supplied values passed down to write functions + +} ; + diff --git a/NifProps/dds/tPixel.h b/NifProps/dds/tPixel.h new file mode 100644 index 0000000000000000000000000000000000000000..d34f9e8663bbdd2b1392aa4af6d1d683f8b03153 --- /dev/null +++ b/NifProps/dds/tPixel.h @@ -0,0 +1,1840 @@ +#pragma once + +#include <math.h> +#include <memory.h> +#include "tVector.h" +#include "nvErrorCodes.h" + +#pragma warning(disable : 4201) + +namespace nv +{ +// modulo value x between [lo,hi] +// allows value 'hi' +template < class _Type > +inline _Type Clamp(const _Type &x, + const _Type &lo, + const _Type &hi) +{ + if (x < lo) + return lo; + else if (x > hi) + return hi; + else + return x; +} + + +inline int iClamp(int x, int lo, int hi) +{ + if (x < lo) + return lo; + if (x > hi) + return hi; + return x; +} + +inline float fClamp(float x, float lo, float hi) +{ + if (x < lo) + return lo; + if (x > hi) + return hi; + return x; +} + + +inline int fmod(int x, int size) +{ + return x % size; +} + +inline __int64 fmod(__int64 x, __int64 size) +{ + return x % size; +} +inline unsigned __int64 fmod(unsigned __int64 x, unsigned __int64 size) +{ + return x % size; +} + + +inline float __cdecl fmod(float _X, float _Y) +{ + return ( fmodf(_X, _Y) ); +} + +// calcMaxMipmap +// calculates max # of mipmap levels for given texture size +inline size_t calcMaxMipmap(size_t w, size_t h) +{ + size_t n = 0; + size_t count = 0; + + assert(w >= 0); + assert(h >= 0); + + if (w < h) + count = h; + else + count = w; + + while (count) + { + n++; + count >>= 1; + } + return n; +} + + +inline size_t calcMaxMipmap(size_t w, size_t h, size_t d) +{ + size_t n = 0; + size_t count = 0; + + assert(w >= 0); + assert(h >= 0); + assert(d >= 0); + + if (w < h) + count = h; + else + count = w; + + if (d > count) + count = d; + + + while (count) + { + n++; + count >>= 1; + } + return n; +} + + +// get next mip level size +inline size_t NextMip(size_t m) +{ + size_t next = m / 2; // round down + if (next == 0) + return 1; + else + return next; +} + + + +// lo = 0; +// allow hi value +template < class _Type > +inline _Type Modulo(const _Type &x, const _Type &hi) +{ + if (x >= 0 && x <= hi) + return x; + + _Type f = fmod(x, hi); + + if (f < 0) + f += hi; + + return f; +} +// does not allow x == size +inline int iModulo(int x, int size) +{ + if (x < 0) + { + int n = x / size; + x += size * (n + 1); + } + + return x % size; +} + + + +template < class _Type > +inline _Type Modulo(const _Type &x, const _Type &lo, const _Type &hi) +{ + if (x >= lo && x <= hi) + return x; + + _Type dw = hi - lo; + _Type t = x - lo; + + _Type f = fmod(t, dw); + + + if (f < 0) + f += dw; + + f += lo; + + return f; +} + +} + + + + +#pragma pack(push,4) + +// red and green +class v16u16_t +{ +public: + + union + { + short uv[4]; + struct + { + short u; + short v; + }; + }; + v16u16_t & operator += ( const v16u16_t & v ); // incrementation by a Vec4f + + + void set(unsigned short _u, unsigned short _v) + { + u = _u; + v = _v; + } +}; + +class r12g12b8_t +{ +public: + + union + { + + struct + { + unsigned long r:12; + unsigned long g:12; + unsigned long b:8; + }; + }; + r12g12b8_t & operator += ( const r12g12b8_t& v ); // incrementation by a Vec4f + + + void set(unsigned long _r, unsigned long _g, unsigned long _b) + { + r = _r; + g = _g; + b = _b; + } +}; + + + +class rgba_t +{ +public: + + union + { + unsigned long u; + unsigned char p[4]; + struct + { + unsigned char r; + unsigned char g; + unsigned char b; + unsigned char a; + }; + }; + + rgba_t() + { + } + + // + + unsigned long bgra() + { + + return ((unsigned long)a << 24) | ((unsigned long)r << 16) | ((unsigned long)g << 8) | ((unsigned long)b); + } + rgba_t(unsigned char _r, unsigned char _g, unsigned char _b,unsigned char _a) + { + a = _a; + r = _r; + g = _g; + b = _b; + } + + rgba_t & operator += ( const rgba_t& v ) // incrementation by a rgba_t + { + r = (unsigned char)nv::Clamp((int)((int)r + (int)v.r), 0, 255); + g = (unsigned char)nv::Clamp((int)g + (int)v.g, 0, 255); + b = (unsigned char)nv::Clamp((int)b + (int)v.b, 0, 255); + a = (unsigned char)nv::Clamp((int)a + (int)v.a, 0, 255); + + return *this; + } + + rgba_t & operator -= ( const rgba_t& v ); // decrementation by a rgba_t + rgba_t & operator *= ( const float d ); // multiplication by a constant + rgba_t & operator /= ( const float d ); // division by a constant + + + rgba_t& operator = (const rgba_t& v) + { + r = v.r; + g = v.g; + b = v.b; + a = v.a; + return *this; + } + + friend rgba_t operator + (const rgba_t & v1, const rgba_t& v2) + { + + int r,g,b,a; + r = nv::Clamp((int)v1.r + (int)v2.r, 0, 255); + g = nv::Clamp((int)v1.g + (int)v2.g, 0, 255); + b = nv::Clamp((int)v1.b + (int)v2.b, 0, 255); + a = nv::Clamp((int)v1.a + (int)v2.a, 0, 255); + + return rgba_t((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); + } + + friend rgba_t operator / (const rgba_t& v, float s) + { + return rgba_t( + (unsigned char)(v.r/s), + (unsigned char)(v.g/s), + (unsigned char)(v.b/s), + (unsigned char)(v.a/s)); + } + + friend rgba_t operator / (const rgba_t& v, int s) + { + return rgba_t( + (unsigned char)(v.r/s), + (unsigned char)(v.g/s), + (unsigned char)(v.b/s), + (unsigned char)(v.a/s)); + } + + void set(unsigned char _r, unsigned char _g, unsigned char _b, unsigned char _a) + { + r = _r; + g = _g; + b = _b; + a = _a; + } + + void SetToZero() + { + r = g = b = a = 0; + } +}; + +class rgba16_t +{ +public: + + union + { + //unsigned __int64 u; + unsigned short rgba[4]; + struct + { + unsigned short r; + unsigned short g; + unsigned short b; + unsigned short a; + }; + }; + + rgba16_t() + { + } + rgba16_t(unsigned short _r, unsigned short _g, unsigned short _b,unsigned short _a) + { + a = _a; + r = _r; + g = _g; + b = _b; + } + + rgba16_t & operator += ( const rgba16_t& v ) // incrementation by a rgba_t + { + r = (unsigned char)nv::Clamp((int)r + (int)v.r, 0, 65535); + g = (unsigned char)nv::Clamp((int)g + (int)v.g, 0, 65535); + b = (unsigned char)nv::Clamp((int)b + (int)v.b, 0, 65535); + a = (unsigned char)nv::Clamp((int)a + (int)v.a, 0, 65535); + + return *this; + } + + rgba16_t & operator -= ( const rgba16_t& v ); // decrementation by a rgba_t + rgba16_t & operator *= ( const float d ); // multiplication by a constant + rgba16_t & operator /= ( const float d ); // division by a constant + + + rgba16_t& operator = (const rgba16_t& v) + { + r = v.r; + g = v.g; + b = v.b; + a = v.a; + return *this; + } + + friend rgba16_t operator + (const rgba16_t & v1, const rgba16_t& v2) + { + + int r,g,b,a; + r = nv::Clamp((int)v1.r + (int)v2.r, 0, 65535); + g = nv::Clamp((int)v1.g + (int)v2.g, 0, 65535); + b = nv::Clamp((int)v1.b + (int)v2.b, 0, 65535); + a = nv::Clamp((int)v1.a + (int)v2.a, 0, 65535); + + return rgba16_t((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a); + } + + friend rgba16_t operator / (const rgba16_t& v, float s) + { + return rgba16_t((unsigned short)(v.r/s), + (unsigned short)(v.g/s), + (unsigned short)(v.b/s), + (unsigned short)(v.a/s)); + } + + friend rgba16_t operator / (const rgba16_t& v, int s) + { + return rgba16_t( + (unsigned short)(v.r/s), + (unsigned short)(v.g/s), + (unsigned short)(v.b/s), + (unsigned short)(v.a/s)); + } + + void set(unsigned short _r, unsigned short _g, unsigned short _b, unsigned short _a) + { + r = _r; + g = _g; + b = _b; + a = _a; + } +}; + + +class urgba_t +{ +public: + + union + { + unsigned long u; + char rgba[4]; + struct + { + char r; + char g; + char b; + char a; + }; + }; + urgba_t & operator += ( const urgba_t& v ); // incrementation by a Vec4f + + + void set(char _r, char _g, char _b, char _a) + { + r = _r; + g = _g; + b = _b; + a = _a; + } +}; + + + + +class q8w8v8u8_t +{ +public: + + union + { + char qwvu[4]; + struct + { + char q; + char w; + char v; + char u; + }; + }; + q8w8v8u8_t & operator += ( const q8w8v8u8_t& v ); // incrementation by a Vec4f + + + void set(char _r, char _g, char _b, char _a) + { + q = _r; + w = _g; + v = _b; + u = _a; + } +}; + + + + + + + +#define _R 0 +#define _G 1 +#define _B 2 +#define _A 3 + + + + +class fpPixel +{ +public: + union + { + float p[4]; + struct + { + float r; + float g; + float b; + float a; + }; + struct + { + float x; + float y; + float z; + float w; + }; + + }; + + void SetToZero() + { + r = 0; + g = 0; + b = 0; + a = 0; + + } + + + void Clamp(fpPixel & lo, fpPixel & hi) + { + + r = nv::Clamp(r, lo.r, hi.r); + g = nv::Clamp(g, lo.g, hi.g); + b = nv::Clamp(b, lo.b, hi.b); + a = nv::Clamp(a, lo.a, hi.a); + } + + void Wrap(fpPixel & lo, fpPixel & hi) + { + + r = nv::Modulo(r, lo.r, hi.r); + g = nv::Modulo(g, lo.g, hi.g); + b = nv::Modulo(b, lo.b, hi.b); + a = nv::Modulo(a, lo.a, hi.a); + + + + + } + + + void dot(fpPixel & w) + { + float grey = r * w.r + + g * w.g + + b * w.b + + a * w.a; + r = grey; + g = grey; + b = grey; + + } + + + + //float& operator () ( int i) { return p[i]; }; // indexing + //const float& operator()(int i) const { return p[i];} + + + + fpPixel() {} + fpPixel(const float _r, const float _g, const float _b, const float _a) + { + a = _a; + r = _r; + g = _g; + b = _b; + } + + + fpPixel(const fpPixel& v) + { + a = v.a; + r = v.r; + g = v.g; + b = v.b; + } // copy constructor + + void set(const float _r, const float _g, const float _b, const float _a) + { + a = _a; + r = _r; + g = _g; + b = _b; + } + + void set(const fpPixel& v) + { + a = v.a; + r = v.r; + g = v.g; + b = v.b; + } + + + fpPixel & operator += ( const fpPixel& v ) // incrementation by a rgba_t + { + r += v.r; + g += v.g; + b += v.b; + a += v.a; + + return *this; + } + + + fpPixel & operator -= ( const fpPixel& v ) // incrementation by a rgba_t + { + r -= v.r; + g -= v.g; + b -= v.b; + a -= v.a; + + return *this; + } + + + fpPixel & operator *= ( const fpPixel& v ) // incrementation by a rgba_t + { + r *= v.r; + g *= v.g; + b *= v.b; + a *= v.a; + + return *this; + } + + fpPixel & operator /= ( const fpPixel& v ) // incrementation by a rgba_t + { + r /= v.r; + g /= v.g; + b /= v.b; + a /= v.a; + + return *this; + } + + fpPixel & operator /= ( const float& s ) // incrementation by a rgba_t + { + r /= s; + g /= s; + b /= s; + a /= s; + + return *this; + } + + fpPixel & operator = ( const fpPixel& v ); // assignment of a Vec3f + + + + friend fpPixel operator + (const fpPixel& v1, const fpPixel& v2) + { + return fpPixel(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b, v1.a + v2.a); + } + + friend fpPixel operator / (const fpPixel& v, float s) + { + return fpPixel(v.r/s, v.g/s, v.b/s, v.a/s); + + } + friend int operator == (const fpPixel& v1, const fpPixel& v2); // v1 == v2 ? + + NV_ERROR_CODE normalize() + { + double u; + u = x * x + y * y + z * z; + + if ( fabs(u - 1.0) < 1e-12) + return NV_OK; // already normalized + + if ( fabs((double)u) < 1e-12) + { + x = y = z = 0.0f; + return NV_CANT_NORMALIZE; + } + + + u = 1.0 / sqrt(u); + + + x = (float)(x*u); + y = (float)(y*u); + z = (float)(z*u); + + return NV_OK; + } + + +}; + + + +class fpPixel3 +{ +public: + union + { + float p[3]; + struct + { + float r; + float g; + float b; + }; + struct + { + float x; + float y; + float z; + }; + + }; + + + void SetToZero() + { + r = 0; + g = 0; + b = 0; + } + + //float& operator () ( int i) { return p[i]; }; // indexing + //const float& operator()(int i) const { return p[i];} + + + + fpPixel3() {} + fpPixel3(const float _r, const float _g, const float _b) + { + r = _r; + g = _g; + b = _b; + } + + + fpPixel3(const fpPixel3& v) + { + r = v.r; + g = v.g; + b = v.b; + } // copy constructor + + void set(const float _r, const float _g, const float _b) + { + r = _r; + g = _g; + b = _b; + } + + void set(const fpPixel3& v) + { + r = v.r; + g = v.g; + b = v.b; + } + + fpPixel3 & operator += ( const fpPixel3& v ); // incrementation by a Vec4f + + fpPixel3 & operator = ( const fpPixel3& v ); // assignment of a Vec3f + fpPixel3 & operator -= ( const fpPixel3& v ); // decrementation by a Vec3f + fpPixel3 & operator *= ( const float d ); // multiplication by a constant + fpPixel3 & operator /= ( const float d ); // division by a constant + + + + friend fpPixel3 operator + (const fpPixel3& v1, const fpPixel3& v2) + { + return fpPixel3(v1.r + v2.r, v1.g + v2.g, v1.b + v2.b); + } + + friend fpPixel3 operator / (const fpPixel3& v, float s) + { + return fpPixel3(v.r/s, v.g/s, v.b/s); + + } + friend int operator == (const fpPixel3& v1, const fpPixel3& v2); // v1 == v2 ? + + NV_ERROR_CODE normalize() + { + double u; + u = x * x + y * y + z * z; + + if ( fabs(u - 1.0) < 1e-12) + return NV_OK; // already normalized + + if ( fabs((double)u) < 1e-12) + { + x = y = z = 0.0f; + return NV_CANT_NORMALIZE; + } + + + u = 1.0 / sqrt(u); + + + x = (float)(x*u); + y = (float)(y*u); + z = (float)(z*u); + + return NV_OK; + } + + +}; + + +typedef fpPixel * fp_i; + + +inline int operator == (const fpPixel& v1, const fpPixel& v2) +{ + return + v1.a == v2.a && + v1.r == v2.r && + v1.b == v2.g && + v1.g == v2.b; +} + +inline fpPixel& fpPixel::operator = (const fpPixel& v) +{ + a = v.a; + r = v.r; + g = v.g; + b = v.b; + return *this; +} + + + + + + + +template <class _Type> +class nvImage +{ + size_t m_width; + size_t m_height; + nvVector<_Type> m_pixels; + + bool m_RGBE; + + +public: + void SetRGBE(bool b) + { + m_RGBE = b; + } + + bool isRGBE() const + { + return m_RGBE; + } + + + + size_t size() + { + return m_width * m_height; + } + + + nvImage < _Type > & operator = ( const nvImage < _Type >& v ) + { + + // resize and copy over + resize(v.width(), v.height()); + + m_pixels = v.m_pixels; + m_RGBE = v.m_RGBE; + + return *this; + } + + + _Type& operator [] ( size_t i) + { +#ifdef _DEBUG + assert(i < m_width * m_height); +#endif + return m_pixels[i]; + }; + + const _Type& operator[](size_t i) const + { +#ifdef _DEBUG + assert(i < m_width * m_height); +#endif + return m_pixels[i]; + } + + _Type & operator () (const size_t &y, const size_t &x) + { +#if _DEBUG + assert(y < m_height); + assert(x < m_width); +#endif + return m_pixels[y * m_width + x]; + + } + const _Type & operator () (const size_t &y, const size_t &x) const + { +#if _DEBUG + assert(y < m_height); + assert(x < m_width); +#endif + return m_pixels[y * m_width + x]; + + } + + + size_t width() const + { + return m_width; + + } + + size_t height() const + { + return m_height; + + } + + + + _Type * pixels(size_t n = 0) + { + + return &m_pixels[n]; + } + _Type * pixelsXY(size_t x, size_t y) + { + return &m_pixels[y * width() + x]; + } + _Type * pixelsXY_Safe(size_t x, size_t y) + { + if (m_pixels.size() == 0) + return 0; + else + return &m_pixels[y * width() + x]; + } + + _Type * pixelsYX(size_t y, size_t x) + { + return &m_pixels[y * width() + x]; + + } + // row / column + _Type * pixelsRC(size_t y, size_t x) + { + return &m_pixels[y * width() + x]; + + } + + + _Type & pixel_ref(size_t n = 0) + { + return m_pixels[n]; + } + _Type & pixelsXY_ref(size_t x, size_t y) + { + return m_pixels[y * width() + x]; + } + + _Type & pixelsYX_ref(size_t y, size_t x) + { + return m_pixels[y * width() + x]; + + } + // row / column + _Type & pixelsRC_ref(size_t y, size_t x) + { + return m_pixels[y * width() + x]; + + } + + _Type * pixelsXY_wrapped(int x, int y) + { + y = mod(y, m_height); + x = mod(x, m_width); + + return &m_pixels[y * m_width + x]; + } + + + + nvImage( const nvImage < _Type > & other) + { + m_width = other.m_width; + m_height = other.m_height; + + m_pixels = other.m_pixels; + m_RGBE = other.m_RGBE; + + + } + + nvImage() + { + m_width = 0; + + m_height = 0; + m_RGBE = false; + + m_pixels.clear(); + + }; + ~nvImage() + { + + } + void clear() + { + m_width = 0; + m_height = 0; + m_pixels.clear(); + } + + void resize(size_t width, size_t height) + { + m_pixels.resize(width * height); + m_width = width; + m_height = height; + + } + void realloc(size_t width, size_t height) + { + m_pixels.realloc(width * height); + m_width = width; + m_height = height; + + } + + nvImage<_Type>(size_t width, size_t height) + { + m_pixels.resize(width * height); + m_width = width; + m_height = height; + m_RGBE = false; + + }; + + + void SwapRB() + { + + _Type * p = &m_pixels[0]; + _Type tmp; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + + tmp.r = p->r; + p->r = p->b; + p->b = tmp.r; + + p++; + } + } + + + + void Scale(_Type s) + { + + _Type * p = &m_pixels[0]; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + *p++ *= s; + } + + } + + void Bias(_Type b) + { + + _Type * p = &m_pixels[0]; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + *p++ += b; + } + + } + + + void dot(_Type w) + { + + + _Type * p = &m_pixels[0]; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + p->dot(w); + p++; + } + } + + + + void Clamp(_Type low, _Type hi) + { + + _Type * p = &m_pixels[0]; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + p->Clamp(low, hi); + p++; + } + + } + + void Wrap(_Type low, _Type hi) + { + _Type * p = &m_pixels[0]; + for(size_t i=0; i < m_width * m_height; i++ ); + { + + p->Wrap(low, hi); + p++; + } + + } + + + + void FlipTopToBottom() + { + + _Type * swap = new _Type[ m_width]; + + size_t row; + + _Type * end_row; + _Type * start_row; + + size_t len = sizeof(_Type) * m_width; + + for( row = 0; row < m_height / 2; row ++ ) + { + end_row = &m_pixels[ m_width * ( m_height - row - 1) ]; + start_row = &m_pixels[ m_width * row ]; + + // copy row toward end of image into temporary swap buffer + memcpy( swap, end_row, len ); + + // copy row at beginning to row at end + memcpy( end_row, start_row, len ); + + // copy old bytes from row at end (in swap) to row at beginning + memcpy( start_row, swap, len ); + } + + delete [] swap; + } + + void SetToZero() + { + + for(size_t i=0; i< m_width * m_height; i++) + { + pixel_ref(i).SetToZero(); + + } + } + void SetToZeroDirect() + { + for(size_t i=0; i< m_width * m_height; i++) + { + m_pixels[i] = 0; + + } + } + + + +}; + + + + + +typedef nvImage<rgba_t> RGBAImage; +typedef nvVector<RGBAImage> RGBAImageArray; + + +class RGBAMipMappedImage +{ + RGBAImageArray mipArray; // array of images, one for each MIP map RGBA + + +public: + + + void resize(size_t width, size_t height, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height); + + mipArray.resize(nMIPMaps); + + for(size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) + { + RGBAImage & mip = mipArray[mipLevel]; + + mip.resize(width, height); + + width = nv::NextMip(width); + height = nv::NextMip(height); + + } + + + } + + + RGBAMipMappedImage(int width, int height, int nMIPMaps) + { + resize(width, height, nMIPMaps); + + + + } + RGBAMipMappedImage() + { + + + + } + + + + RGBAImage & operator [] ( size_t i) { return mipArray[i]; }; // indexing + const RGBAImage& operator[](size_t i) const { return mipArray[i];} + + size_t numMIPMaps() const + { + return mipArray.size(); + } + + + void resize(size_t size) + { + mipArray.resize(size); + } + void realloc(size_t size) + { + mipArray.realloc(size); + } + + size_t width() const + { + if (mipArray.size() == 0) + return 0; + return mipArray[0].width(); + + } + size_t height() const + { + if (mipArray.size() == 0) + return 0; + return mipArray[0].height(); + + } + + void clear() + { + mipArray.clear(); + } + + +}; + + +class RGBAMipMappedCubeMap +{ + RGBAMipMappedImage cubeFaces[6]; // array of images, one for each MIP map RGBA + +public: + + void resize(size_t width, size_t height, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height); + + for(int f = 0; f < 6; f++) + { + RGBAMipMappedImage & mipFace = cubeFaces[f]; + mipFace.resize(width, height, nMIPMaps); + } + + + } + + RGBAMipMappedCubeMap(size_t width, size_t height, size_t nMIPMaps) + { + resize(width, height, nMIPMaps); + + } + + RGBAMipMappedCubeMap() + { + } + + RGBAMipMappedImage & operator [] ( size_t i) { return cubeFaces[i]; }; // indexing + const RGBAMipMappedImage& operator[](size_t i) const { return cubeFaces[i];} + + + size_t numMIPMaps() const + { + return cubeFaces[0].numMIPMaps(); + } + + size_t height() const + { + return cubeFaces[0].height(); + } + + size_t width() const + { + return cubeFaces[0].height(); + } + + void clear() + { + for(size_t f = 0; f < 6; f++) + { + RGBAMipMappedImage & mipFace = cubeFaces[f]; + mipFace.clear(); + } + + } + + + + +}; + + + +typedef nvVector< RGBAImageArray > RGBAVolume; + +class RGBAMipMappedVolumeMap +{ + // array of MIP mapped images + RGBAVolume volumeArray; + +public: + + void resize(size_t width, size_t height, size_t depth, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height, depth); + + volumeArray.resize(nMIPMaps); + + size_t w = width; + size_t h = height; + size_t d = depth; + + for(size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) + { + + RGBAImageArray & volImage = volumeArray[mipLevel]; + + volImage.resize(d); + + + for(size_t slice = 0; slice < d; slice++) + { + RGBAImage & mipFace = volImage[slice]; + + mipFace.resize(w, h); + } + w = nv::NextMip(w); + h = nv::NextMip(h); + d = nv::NextMip(d); + + + } + } + + + RGBAMipMappedVolumeMap(size_t width, size_t height, size_t depth, size_t nMIPMaps) + { + resize(width, height, depth, nMIPMaps); + } + + + // mip level + RGBAImageArray & operator [] ( size_t i) { return volumeArray[i]; }; // indexing + const RGBAImageArray& operator[](size_t i) const { return volumeArray[i];} + + RGBAMipMappedVolumeMap() + { + } + size_t numMIPMaps() const + { + return volumeArray.size(); + } + + + + + const RGBAImageArray * vol0() const + { + if (numMIPMaps() == 0) + return 0; + + return &volumeArray[0]; + } + + + const RGBAImage * slice0() const + { + const RGBAImageArray * v0 = vol0(); + + if (v0 == 0) + return 0; + + if (v0->size() == 0) + return 0; + + const RGBAImageArray &array = *v0; + + return &array[0]; + } + + size_t width() const + { + const RGBAImage * image0 = slice0(); + + if (image0 == 0) + return 0; + + else + return image0->width(); + + } + size_t height() const + { + const RGBAImage * image0 = slice0(); + + if (image0 == 0) + return 0; + + else + return image0->height(); + } + + size_t depth() const + { + const RGBAImageArray * v0 = vol0(); + + if (v0 == 0) + return 0; + + return v0->size(); + + } + + + + +}; + + +typedef nvMatrix<float> floatImage; +typedef nvMatrix<fpPixel> fpImage; +typedef nvMatrix<fpPixel3> fpImage3; + + +//typedef nvImage<fpPixel> fpImage; +//typedef nvImage<float> floatImage; +//typedef nvImage<fpPixel3> fpImage3; + + + +typedef nvVector<fpImage> fpImageArray; + + + + +class fpMipMappedImage +{ + fpImageArray mipArray; // array of images, one for each MIP map RGBA + +public: + + fpMipMappedImage() + { + } + + fpMipMappedImage(size_t width, size_t height, size_t nMIPMaps) + { + resize(width, height, nMIPMaps); + } + + // copy constructor + fpMipMappedImage(const fpMipMappedImage& v) + { + // copy the images over + mipArray.resize(v.mipArray.size() ); + for(size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) + { + fpImage & dst = mipArray[mipLevel]; + const fpImage & src = v.mipArray[mipLevel]; + dst = src; + } + } + + + void resize(size_t width, size_t height, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height); + + mipArray.resize(nMIPMaps); + + for(size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) + { + fpImage & mip = mipArray[mipLevel]; + + mip.resize(width, height); + + width = nv::NextMip(width); + height = nv::NextMip(height); + } + } + + void FlipTopToBottom() + { + // copy the images over + for(size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) + { + fpImage & mip = mipArray[mipLevel]; + mip.FlipTopToBottom(); + } + } + + fpImage & operator [] ( size_t i) { return mipArray[i]; }; // indexing + const fpImage& operator[](size_t i) const { return mipArray[i];} + + void SetToZero() + { + for(size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) + { + fpImage & mip = mipArray[mipLevel]; + mip.SetToZero(); + } + } + + void clear() + { + mipArray.clear(); + } + void realloc(size_t size) + { + mipArray.realloc(size); + } + void resize(size_t nMIPLevels) + { + mipArray.resize(nMIPLevels); + } + + size_t numMIPMaps() const + { + return mipArray.size(); + } + + size_t width() const + { + return mipArray[0].width(); + + } + size_t height() const + { + return mipArray[0].height(); + } + +}; + + +class fpMipMappedCubeMap +{ + fpMipMappedImage cubeFaces[6]; // array of images, one for each MIP map RGBA + +public: + + void resize(size_t width, size_t height, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height); + + for(size_t f = 0; f < 6; f++) + { + fpMipMappedImage & mipFace = cubeFaces[f]; + mipFace.resize(width, height, nMIPMaps); + } + + + } + + fpMipMappedCubeMap(int width, int height, int nMIPMaps) + { + resize(width, height, nMIPMaps); + + } + + fpMipMappedCubeMap() + { + } + + fpMipMappedImage & operator [] ( size_t i) { return cubeFaces[i]; }; // indexing + const fpMipMappedImage& operator[](size_t i) const { return cubeFaces[i];} + + + size_t numMIPMaps() const + { + return cubeFaces[0].numMIPMaps(); + } + + size_t height() const + { + return cubeFaces[0].height(); + } + + size_t width() const + { + return cubeFaces[0].height(); + } + + void clear() + { + for(size_t f = 0; f < 6; f++) + { + fpMipMappedImage & mipFace = cubeFaces[f]; + mipFace.clear(); + } + + } + + + void FlipTopToBottom() + { + for(size_t f = 0; f < 6; f++) + { + fpMipMappedImage & mipFace = cubeFaces[f]; + mipFace.FlipTopToBottom(); + } + + } + + +}; + + +// mip level, array +typedef nvVector< fpImageArray > fpVolume; + +class fpMipMappedVolumeMap +{ + // array of MIP mapped images + fpVolume volumeArray; + +public: + + void resize(size_t width, size_t height, size_t depth, size_t nMIPMaps) + { + if (nMIPMaps == 0) + nMIPMaps = nv::calcMaxMipmap(width, height, depth); + volumeArray.resize(nMIPMaps); + + size_t w = width; + size_t h = height; + size_t d = depth; + + for(size_t mipLevel = 0; mipLevel < nMIPMaps; mipLevel++) + { + + fpImageArray & volImage = volumeArray[mipLevel]; + + volImage.resize(d); + + + for(size_t slice = 0; slice < d; slice++) + { + fpImage & mipFace = volImage[slice]; + + mipFace.resize(w, h); + } + + w = nv::NextMip(w); + h = nv::NextMip(h); + d = nv::NextMip(d); + + } + } + + void FlipTopToBottom() + { + for(size_t mipLevel = 0; mipLevel < numMIPMaps(); mipLevel++) + { + + fpImageArray & volImage = volumeArray[mipLevel]; + + + for(size_t slice = 0; slice < volImage.size(); slice++) + { + fpImage & mipFace = volImage[slice]; + mipFace.FlipTopToBottom(); + } + } + } + + + + void realloc(size_t size) + { + volumeArray.realloc(size); + } + + + fpMipMappedVolumeMap(size_t width, size_t height, size_t depth, size_t nMIPMaps) + { + resize(width, height, depth, nMIPMaps); + } + + + // mip level + fpImageArray & operator [] ( size_t i) { return volumeArray[i]; }; // indexing + const fpImageArray& operator[](size_t i) const { return volumeArray[i];} + + fpMipMappedVolumeMap() + { + } + size_t numMIPMaps() const + { + return volumeArray.size(); + } + + + + + const fpImageArray * vol0() const + { + if (numMIPMaps() == 0) + return 0; + + return &volumeArray[0]; + } + + + const fpImage * slice0() const + { + const fpImageArray * v0 = vol0(); + + if (v0 == 0) + return 0; + + if (v0->size() == 0) + return 0; + + const fpImageArray &array = *v0; + + return &array[0]; + } + + size_t width() const + { + const fpImage * image0 = slice0(); + + if (image0 == 0) + return 0; + + else + return image0->width(); + + } + size_t height() const + { + const fpImage * image0 = slice0(); + + if (image0 == 0) + return 0; + + else + return image0->height(); + } + + size_t depth() const + { + const fpImageArray * v0 = vol0(); + + if (v0 == 0) + return 0; + + return v0->size(); + + } + + void clear() + { + volumeArray.clear(); + + } + + + + +}; +#pragma pack(pop) + + + + +#include "ConvertColor.h" + diff --git a/NifProps/dds/tVector.h b/NifProps/dds/tVector.h new file mode 100644 index 0000000000000000000000000000000000000000..22bbfade7180889cf3587f197668f64405bdd350 --- /dev/null +++ b/NifProps/dds/tVector.h @@ -0,0 +1,778 @@ +#pragma once +#include <assert.h> + + + + +template <class _Type> +class nvMatrix +{ + _Type **m; + + size_t rows, cols; + +public: + + nvMatrix() + { + rows = 0; + cols = 0; + m = 0; + } + + // copy constructor + nvMatrix(const nvMatrix & v) + { + rows = 0; + cols = 0; + m = 0; + + resize(v.width(), v.height()); + + for(size_t i = 0; i < v.rows; i++) + { + for(size_t j = 0; j<v.cols; j++) + m[i][j] = v.m[i][j]; + } + } + + nvMatrix(size_t width, size_t height) + { + m = 0; + rows = 0; + cols = 0; + resize(width, height); + } + ~nvMatrix() + { + tvfree(); + } + + _Type& operator [] ( size_t i) + { + size_t r = i / cols; + size_t c = i % cols; + +#if _DEBUG + assert(r < rows); + assert(c < cols); +#endif + return m[r][c]; + }; + + + _Type * pixels( size_t i = 0) + { + + size_t r = i / cols; + size_t c = i % cols; + +#if _DEBUG + assert(r < rows); + assert(c < cols); +#endif + return &m[r][c]; + }; + + + _Type & operator () (const size_t &r, const size_t &c) const + { +#if _DEBUG + assert(r < rows); + assert(c < cols); +#endif + return m[r][c]; + } + + _Type & operator () (const size_t &r, const size_t &c) + { +#if _DEBUG + assert(r < rows); + assert(c < cols); +#endif + return m[r][c]; + } + + _Type * pixelsRC( size_t r, size_t c) + { +#if _DEBUG + assert(r < rows); + assert(c < cols); +#endif + return &m[r][c]; + }; + + _Type * pixelsXY( size_t x, size_t y) + { +#if _DEBUG + assert(y < rows); + assert(x < cols); +#endif + return &m[y][x]; + }; + + + _Type * pixelsYX( size_t y, size_t x) + { +#if _DEBUG + assert(y < rows); + assert(x < cols); +#endif + return &m[y][x]; + }; + + + _Type * pixelsXY_wrapped(int x, int y) + { + y = iModulo(y, (int)rows); + x = iModulo(x, (int)cols); + + return &m[y][x]; + } + + size_t width() const + { + return cols; + } + size_t height() const + { + return rows; + } + + + void tvfree() + { + if (m) + { + for(size_t i = 0; i < rows; i++) + delete [] m[i]; + + delete [] m; + m = 0; + rows = 0; + cols = 0; + } + } + + void tvallocate(size_t r, size_t c) + { + assert(m == NULL); + + rows = r; + cols = c; + if (r == 0 || c == 0) + return; + + m = new _Type *[r]; + + + for(size_t i = 0; i < r; i++) + { + m[i] = new _Type [c]; + } + } + + nvMatrix & operator = ( const nvMatrix& v ) + { + resize(v.width(), v.height()); + + for(size_t i = 0; i < v.rows; i++) + { + for(size_t j = 0; j<v.cols; j++) + m[i][j] = v.m[i][j]; + } + return *this; + } + + + void SetToZero() + { + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + m[i][j].SetToZero(); + } + } + + + + + // destructive + void resize(size_t width, size_t height) + { + if (height != rows || width != cols) + { + tvfree (); + + tvallocate(height, width); + } + } + + + void Release() + { + tvfree (); + } + void clear() + { + tvfree(); + } + + size_t size() const + { + return rows * cols; + } + + + + void FlipTopToBottom() + { + _Type * swap = new _Type[ cols]; + + size_t row; + + //_Type * end_row; + //_Type * start_row; + int end_row; + int start_row; + + size_t len = sizeof(_Type) * cols; + + for( row = 0; row < rows / 2; row ++ ) + { + /*end_row = &m[( rows - row - 1) ][0]; + start_row = &m[ row ][0]; + + // copy row toward end of image into temporary swap buffer + memcpy( swap, end_row, len ); + + // copy row at beginning to row at end + memcpy( end_row, start_row, len ); + + // copy old bytes from row at end (in swap) to row at beginning + memcpy( start_row, swap, len );*/ + + end_row = rows - row - 1; + start_row = row ; + + // copy row toward end of image into temporary swap buffer + //memcpy( swap, end_row, len ); + for(size_t i = 0; i < cols; i++) + swap[i] = m[end_row][i]; + + // copy row at beginning to row at end + //memcpy( end_row, start_row, len ); + for(size_t i = 0; i < cols; i++) + m[end_row][i] = m[start_row][i]; + + // copy old bytes from row at end (in swap) to row at beginning + //memcpy( start_row, swap, len ); + for(size_t i = 0; i < cols; i++) + m[start_row][i] = swap[i]; + + } + + delete [] swap; + } + + + void Scale(_Type s) + { + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + m[i][j] *= s; + } + } + + void Bias(_Type s) + { + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + m[i][j] += s; + } + } + + void dot(_Type w) + { + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + m[i][j].dot(w); + } + } + + + + void Clamp(_Type low, _Type hi) + { + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + { + m[i][j].Clamp(low, hi); + } + } + } + + void Wrap(_Type low, _Type hi) + { + // to do + for(size_t i = 0; i < rows; i++) + { + for(size_t j = 0; j<cols; j++) + { + + m[i][j].Wrap(low, hi); + } + } + } + +}; + +/* +#include <vector> + +template <class T> +class nvVector : public std::vector<T> +{ +public: + + void resize(size_t newSize) + { + // Hack to emulate nvVector behaviour. + nvVector tmp; + ((std::vector<T> &)tmp).resize(newSize); + std::swap(*this, tmp); + } + + void realloc(size_t newSize) + { + std::vector<T>::resize(newSize); + } +}; + + +template <class _Type> +class nvVector +{ + _Type *m_data; + + size_t allocated_size; + size_t current_size; + +public: + + nvVector() + { + m_data = 0; + current_size = 0; + allocated_size = 0; + } + + nvVector(const nvVector<_Type> & other) + { + resize(other.size()); + + for(size_t i = 0; i < other.size(); i++) + { + m_data[i] = other.m_data[i]; + } + } + + ~nvVector() + { + Release(); + } + + static void tvfree(_Type * & ptr) + { + if (ptr) + { + delete [] ptr; + ptr = 0; + } + } + + static _Type * tvallocate(size_t elements) + { + return new _Type[elements]; + } + + nvVector & operator = ( const nvVector& v ) + { + resize(v.size()); + + for(size_t i = 0; i < v.size(); i++) + { + m_data[i] = v.m_data[i]; + } + return *this; + } + + + void FirstAllocation() + { + // start with 256 entries + + tvfree (m_data); + + allocated_size = 256; + current_size = 0; + m_data = tvallocate(allocated_size); + } + + + + void resize(size_t newSize) + { + if (newSize != allocated_size) + { + allocated_size = newSize; + + tvfree (m_data); + + m_data = tvallocate(allocated_size); + } + + current_size = newSize; + } + + // keep old contents + void realloc(size_t newSize) + { + if (newSize != allocated_size) + { + _Type * oldData = new _Type[current_size]; + size_t oldSize = current_size; + + for(size_t i = 0; i < current_size; i++) + { + oldData[i] = m_data[i]; + } + + + allocated_size = newSize; + + tvfree (m_data); + + m_data = tvallocate(allocated_size); + + size_t minSize; + if (oldSize < newSize) + minSize = oldSize; + else + minSize = newSize; + + for(size_t i = 0; i < minSize; i++) + { + m_data[i] = oldData[i]; + } + } + + current_size = newSize; + } + + void push_back(_Type item) + { + if (allocated_size == 0) + { + FirstAllocation(); + } + else if (current_size >= allocated_size) + { + allocated_size = allocated_size * 2; + + _Type *temp = tvallocate(allocated_size); + + // copy old data to new area + for(size_t i = 0; i< current_size; i++) + temp[i] = m_data[i]; + + tvfree (m_data); + + m_data = temp; + } + + + m_data[current_size] = item; + current_size++; + } + + // indexing + + _Type& operator [] ( size_t i) + { +#ifdef _DEBUG + assert(i < current_size); + assert(current_size <= allocated_size); +#endif + return m_data[i]; + }; + + const _Type& operator[](size_t i) const + { +#ifdef _DEBUG + assert(i < current_size); + assert(current_size <= allocated_size); +#endif + return m_data[i]; + } + + void Release() + { + tvfree (m_data); + + current_size = 0; + allocated_size = 0; + } + void clear() + { + Release(); + } + + size_t size() const + { + return current_size; + } + +}; +*/ + +#include <new> + +template<typename T> +class nvVector { +public: + + /** Ctor. */ + nvVector() : m_buffer(NULL), m_size(0), m_buffer_size(0) { + } + + /** Copy ctor. */ + nvVector( const nvVector & a ) : m_buffer(NULL), m_size(0), m_buffer_size(0) { + copy( a.m_buffer, a.m_size); + } + + + /** Ctor that initializes the array with the given elements. */ + nvVector( const T * ptr, size_t num ) : m_buffer(NULL), m_size(0), m_buffer_size(0) { + copy( ptr, num); + } + + + /** Dtor. */ + ~nvVector() { + clear(); + allocate(0); + } + + + /** Const and save array access. */ + const T & operator[]( size_t index ) const { + assert( index < m_size ); + return m_buffer[index]; + } + + /** Safe array access. */ + T & operator[] ( size_t index ) { + assert( index < m_size ); + return m_buffer[index]; + } + + + /** Get array size. */ + size_t size() const { return m_size; } + + + /** Push an element at the end of the array. */ + void push_back( const T & val ) { + // DO NOT pass elements of your own vector into + // push_back()! Since we're using references, + // resize() may munge the element storage! + assert( &val < &m_buffer[0] || &val > &m_buffer[m_size] ); + + int new_size = m_size + 1; + resize( new_size ); + m_buffer[new_size-1] = val; + } + + /** Pop and return element at the end of the array. */ + void pop_back() { + assert( m_size > 0 ); + resize( m_size-1 ); + } + + /** Get back element. */ + const T & back() const { + assert( m_size > 0 ); + return m_buffer[m_size-1]; + } + + /** Get back element. */ + T & back() { + assert( m_size > 0 ); + return m_buffer[m_size-1]; + } + + /** Get back element. */ + const T & front() const { + assert( m_size > 0 ); + return m_buffer[0]; + } + + /** Get back element. */ + T & front() { + assert( m_size > 0 ); + return m_buffer[0]; + } + + + // nvVector semantics: realloc preserves contents, resize does not. + void realloc( size_t new_size ) { + resize(new_size); + } + + + /** Resize the array preserving existing elements. */ + void resize( size_t new_size ) { + size_t i; + size_t old_size = m_size; + m_size = new_size; + + // Destruct old elements (if we're shrinking). + for( i = new_size; i < old_size; i++ ) { + (m_buffer+i)->~T(); // Explicit call to the destructor + } + + if( m_size == 0 ) { + //allocate(0); // Don't shrink automatically. + } + else if( m_size <= m_buffer_size && m_size > m_buffer_size >> 1) { + // don't compact yet. + assert(m_buffer != NULL); + } + else { + size_t new_buffer_size; + if( m_buffer_size == 0 ) { + // first allocation + new_buffer_size = m_size; + } + else { + // growing + new_buffer_size = m_size + (m_size >> 2); + } + allocate( new_buffer_size ); + } + + // Call default constructors + for( i = old_size; i < new_size; i++ ) { + new(m_buffer+i) T(); // placement new + } + } + + + /** + * Resize the array preserving existing elements and initializing the + * new ones with the given value. + */ + void resize( size_t new_size, const T &elem ) { + size_t i; + size_t old_size = m_size; + m_size = new_size; + + // Destruct old elements (if we're shrinking). + for( i = new_size; i < old_size; i++ ) { + (m_buffer+i)->~T(); // Explicit call to the destructor + } + + if( m_size == 0 ) { + //allocate(0); // Don't shrink automatically. + } + else if( m_size <= m_buffer_size && m_size > m_buffer_size >> 1 ) { + // don't compact yet. + assert(m_buffer != NULL); + } + else { + size_t new_buffer_size; + if( m_buffer_size == 0 ) { + // first allocation + new_buffer_size = m_size; + } + else { + // growing + new_buffer_size = m_size + (m_size >> 2); + } + allocate( new_buffer_size ); + } + + // Call copy constructors + for( i = old_size; i < new_size; i++ ) { + new(m_buffer+i) T( elem ); // placement new + } + } + + /** Clear the buffer. */ + void clear() { + resize(0); + } + + /** Shrink the allocated array. */ + void shrink() { + if( m_size < m_buffer_size) { + allocate(m_size); + } + } + + /** Preallocate space. */ + void reserve( size_t desired_size ) { + if( desired_size > m_buffer_size ) { + allocate( desired_size ); + } + } + + + /** Assignment operator. */ + void operator=( const nvVector & a ) { + copy( a.m_buffer, a.m_size ); + } + + +private: + + /** Change buffer size. */ + void allocate( size_t rsize ) { + + m_buffer_size = rsize; + + // free the buffer. + if( m_buffer_size == 0 ) { + if( m_buffer ) { + free( m_buffer ); + m_buffer = NULL; + } + } + + // realloc the buffer + else { + if( m_buffer ) m_buffer = (T *) ::realloc( m_buffer, sizeof(T) * m_buffer_size ); + else m_buffer = (T *) malloc( sizeof(T) * m_buffer_size ); + } + } + + /** Copy memory to our array. Resizes the array if needed. */ + void copy( const T * ptr, size_t num ) { + resize( num ); + for( size_t i = 0; i < m_size; i++ ) { + m_buffer[i] = ptr[i]; + } + } + +private: + + T * m_buffer; + size_t m_size; + size_t m_buffer_size; + +}; diff --git a/NifProps/dds/veroverrides.h b/NifProps/dds/veroverrides.h new file mode 100644 index 0000000000000000000000000000000000000000..744b070ba4e54a642aabccaffc9a5c7f4e77ef26 --- /dev/null +++ b/NifProps/dds/veroverrides.h @@ -0,0 +1,15 @@ +// The to be #defined in a .h file included by a .rc file before maxversion.r + + +#define MAXVER_INTERNALNAME "dds\0"//should be overidden on a per-dll level +#define MAXVER_ORIGINALFILENAME "dds.bmi\0"//should be overidden on a per-dll level +#define MAXVER_FILEDESCRIPTION "A DDS image IO plugin\0"//should be overidden on a per-dll level +#define MAXVER_COMMENTS "TECH: neil.hazzard\0"//should be overidden on a per-dll level + +// #define MAXVER_PRODUCTNAME //generally not overridden at the maxversion.r level +// #define MAXVER_COPYRIGHT //only in exceptions should this be overridden +// #define MAXVER_LEGALTRADEMARKS //only in exceptions should this be overridden +// #define MAXVER_COMPANYNAME //only in exceptions should this be overridden +// #define MAX_VERSION_MAJOR //only in exceptions should this be overridden +// #define MAX_VERSION_MINOR //only in exceptions should this be overridden +// #define MAX_VERSION_POINT //only in exceptions should this be overridden