diff --git a/MaxNifPlugins_Readme.txt b/MaxNifPlugins_Readme.txt index 810cd274d867a31ef9ab860ae796c5418dc79003..355c3fd2cac45cd83b2163b74e350f3dc2877487 100644 --- a/MaxNifPlugins_Readme.txt +++ b/MaxNifPlugins_Readme.txt @@ -1,4 +1,4 @@ - MaxPlugins 0.2.3 + MaxPlugins 0.2.4 ================ @@ -27,6 +27,23 @@ Change log ---------- + 0.2.4 + ----- + o Exporter + - Add animation export. + + o Importer + - Add option to ignore UPB buffers. + * Useful in preventing LOD Bone warnings from the Civ4 Exporter + - Fixed problem with Animation Note Tracks not being cleared + - Fixed issue with BSpline animation when too much data was present + * Specifically the Civ4 Leaderheads now import animation very well + - Import Animation Priority into user prop buffer + + o NifProps Utility + - Added Animation Priority + - Removed unused Globals + 0.2.3 ----- o Exporter diff --git a/NifCommon/AnimKey.cpp b/NifCommon/AnimKey.cpp index f5fcfdc44bc4edbedac4d12d0d27c70f4f810232..8caa4ac15022d18669288e865b1cd846395b7785 100644 --- a/NifCommon/AnimKey.cpp +++ b/NifCommon/AnimKey.cpp @@ -131,6 +131,30 @@ FloatKey MapKey<FloatKey, ILinFloatKey>(ILinFloatKey& key, float time) return InitFromLinKey(rKey, key, time); } +template<> +Vector3Key MapKey<Vector3Key, ILinPoint3Key>(ILinPoint3Key& key, float time) +{ + Vector3Key rKey; + rKey.data = TOVECTOR3(key.val); + return InitFromLinKey(rKey, key, time); +} + +template<> +QuatKey MapKey<QuatKey, ILinRotKey>(ILinRotKey& key, float time) +{ + QuatKey rKey; + rKey.data = TOQUAT(key.val, true); + return InitFromLinKey(rKey, key, time); +} + +template<> +FloatKey MapKey<FloatKey, ILinScaleKey>(ILinScaleKey& key, float time) +{ + FloatKey rKey; + rKey.data = (key.val[0] + key.val[1] + key.val[2]) / 3.0f; + return InitFromLinKey(rKey, key, time); +} + // Specialized Bezier/Hybrid mappings @@ -154,7 +178,6 @@ IBezPoint3Key MapKey<IBezPoint3Key, Vector3Key>(Vector3Key& key, float time) return InitBezKey(rKey, key, time); } - template<> IBezQuatKey MapKey<IBezQuatKey, QuatKey>(QuatKey& key, float time) { @@ -172,7 +195,7 @@ IBezScaleKey MapKey<IBezScaleKey, FloatKey>(FloatKey& key, float time) return InitBezKey(rKey, key, time); } -// Specialized Linear Mappings +// Specialized Bezier/Hybrid Mappings template<> FloatKey MapKey<FloatKey, IBezFloatKey>(IBezFloatKey& key, float time) @@ -184,6 +207,37 @@ FloatKey MapKey<FloatKey, IBezFloatKey>(IBezFloatKey& key, float time) return InitFromBezKey(rKey, key, time); } +template<> +Vector3Key MapKey<Vector3Key, IBezPoint3Key>(IBezPoint3Key& key, float time) +{ + Vector3Key rKey; + rKey.data = TOVECTOR3(key.val); + rKey.forward_tangent = TOVECTOR3(key.intan); + rKey.backward_tangent = TOVECTOR3(key.outtan); + return InitFromBezKey(rKey, key, time); +} + +template<> +QuatKey MapKey<QuatKey, IBezQuatKey>(IBezQuatKey& key, float time) +{ + QuatKey rKey; + rKey.data = TOQUAT(key.val, true); + //rKey.forward_tangent = TOQUAT(key.intan, true); + //rKey.backward_tangent = TOQUAT(key.outtan, true); + return InitFromBezKey(rKey, key, time); +} + +template<> +FloatKey MapKey<FloatKey, IBezScaleKey>(IBezScaleKey& key, float time) +{ + FloatKey rKey; + rKey.data = Average(key.val.s); + rKey.forward_tangent = Average(key.intan); + rKey.backward_tangent = Average(key.outtan); + return InitFromBezKey(rKey, key, time); +} + + // Specialized TCB Mappings template<> @@ -229,6 +283,32 @@ FloatKey MapKey<FloatKey, ITCBFloatKey>(ITCBFloatKey& key, float time) return InitFromTCBKey(rKey, key, time); } +template<> +Vector3Key MapKey<Vector3Key, ITCBPoint3Key>(ITCBPoint3Key& key, float time) +{ + Vector3Key rKey; + rKey.data = TOVECTOR3(key.val); + return InitFromTCBKey(rKey, key, time); +} + +template<> +QuatKey MapKey<QuatKey, ITCBRotKey>(ITCBRotKey& key, float time) +{ + QuatKey rKey; + rKey.data = TOQUAT(key.val, true); + return InitFromTCBKey(rKey, key, time); +} + +template<> +FloatKey MapKey<FloatKey, ITCBScaleKey>(ITCBScaleKey& key, float time) +{ + FloatKey rKey; + rKey.data = Average(key.val.s); + return InitFromTCBKey(rKey, key, time); +} + +// Merge Keys + template<> void MergeKey<ILinRotKey>(ILinRotKey& lhs, ILinRotKey& rhs) { lhs.val *= rhs.val; } diff --git a/NifCommon/AnimKey.h b/NifCommon/AnimKey.h index 1cb3462565c993e4d696429b80a3ac51184b4a1b..7766ab9a82cd60adbfa67b1e36cf622f499d1084 100644 --- a/NifCommon/AnimKey.h +++ b/NifCommon/AnimKey.h @@ -120,17 +120,38 @@ inline void SetKeys(Control *subCtrl, vector<U>& keys, float time) } template<typename T, typename U> -inline void GetKeys(Control *subCtrl, vector<T>& keys, float time) +inline int GetKeys(Control *subCtrl, vector<T>& keys, float time) { if (IKeyControl *ikeys = GetKeyControlInterface(subCtrl)){ - int n = ikeys->GetKeySize(); + int n = ikeys->GetNumKeys(); keys.reserve(n); for (int i=0; i<n; ++i){ AnyKey buf; U *key = reinterpret_cast<U*>((IKey*)buf); ikeys->GetKey(i, key); keys.push_back( MapKey<T>(*key, time) ); } + return keys.size(); } + return 0; +} + +template<typename T, typename U> +inline int GetKeys(Control *subCtrl, vector<T>& keys, Interval range) +{ + if (IKeyControl *ikeys = GetKeyControlInterface(subCtrl)){ + float timeOffset = -FrameToTime(range.Start()); + int n = ikeys->GetNumKeys(); + keys.reserve(n); + for (int i=0; i<n; ++i){ + AnyKey buf; U *key = reinterpret_cast<U*>((IKey*)buf); + ikeys->GetKey(i, key); + if (range.InInterval(key->time)) { + keys.push_back( MapKey<T>(*key, timeOffset) ); + } + } + return keys.size(); + } + return 0; } template<typename T, typename U> diff --git a/NifCommon/NifPlugins.h b/NifCommon/NifPlugins.h index ca1239c57aa1b3357fb1b78d805c7fa87b8b56fd..00905842f8a7a767a67ab51e01c56c4d396a0d9c 100644 --- a/NifCommon/NifPlugins.h +++ b/NifCommon/NifPlugins.h @@ -39,6 +39,8 @@ using Niflib::Vector3; #define NP_FRN_POS _T("np_frn_pos") +#define NP_ANM_PRI _T("np_anm_pri") + /* default values */ #define NP_DEFAULT_HVK_MATERIAL 9 #define NP_DEFAULT_HVK_LAYER 1 @@ -50,6 +52,8 @@ using Niflib::Vector3; #define NP_DEFAULT_HVK_MOTION_SYSTEM 7 #define NP_DEFAULT_HVK_QUALITY_TYPE 1 +#define NP_DEFAULT_ANM_PRI 0.0f + #define NP_DEFAULT_FRN_MARKER_TYPE NP_FRN_SLEEP_LEFT /* other constants */ diff --git a/NifCommon/niutils.h b/NifCommon/niutils.h index 2af7484621554c09f2ae117791b94162f96a47bf..294205978136de04e80ad65b70568f4c8006bc94 100644 --- a/NifCommon/niutils.h +++ b/NifCommon/niutils.h @@ -351,6 +351,14 @@ static inline Point3 GetScale(const Matrix3& mtx){ return Point3( fabs(mtx.GetRow(0)[0]), fabs(mtx.GetRow(1)[1]), fabs(mtx.GetRow(2)[2]) ); } +static inline float Average(const Point3& val) { + return (val[0] + val[1] + val[2]) / 3.0f; +} + +static inline float Average(const Niflib::Vector3& val) { + return (val.x + val.y + val.z) / 3.0f; +} + template <typename U, typename T> inline Niflib::Ref<U> SelectFirstObjectOfType( vector<Niflib::Ref<T> > const & objs ) { for (vector<Niflib::Ref<T> >::const_iterator itr = objs.begin(), end = objs.end(); itr != end; ++itr) { diff --git a/NifExport/Animation.cpp b/NifExport/Animation.cpp index 8b7994569fc955a475046d0e4596a1b04f8e254e..70eaba44f9a15c6b00a1ab3c3d45e0a7bb27e986 100644 --- a/NifExport/Animation.cpp +++ b/NifExport/Animation.cpp @@ -11,6 +11,9 @@ HISTORY: *> Copyright (c) 2006, All Rights Reserved. **********************************************************************/ #include "pch.h" +#include <IFrameTagManager.h> +#include <notetrck.h> + #include "NifExport.h" #include "AnimKey.h" @@ -39,33 +42,135 @@ struct AnimationExport { AnimationExport(Exporter& parent) : ne(parent) {} - bool doExport(); - bool exportController(INode *node, NiControllerSequenceRef seq); + INode * findTrackedNode(INode *root); + + bool doExport(NiControllerSequenceRef seq); + bool exportController(INode *node); Control *GetTMController(INode* node); Exporter ≠ + Interval range; + NiControllerSequenceRef seq; }; -bool Exporter::doAnimExport() +Exporter::Result Exporter::doAnimExport(NiControllerSequenceRef root) { AnimationExport animExporter(*this); - return animExporter.doExport(); - return true; + return animExporter.doExport(root) ? Exporter::Ok : Exporter::Abort ; } //NiControllerSequenceRef makeSequence(TimeValue start, TimeValue end); -bool AnimationExport::doExport() +INode * AnimationExport::findTrackedNode(INode *node) { - INode *root = ne.mI->GetRootNode(); - NiControllerSequenceRef seq = new NiControllerSequence(); - seq->SetStartTime(0.0f); - seq->SetStopTime(0.0f); + // locate START in note track before assuming all is well + if (node->HasNoteTracks()) { + for (int i=0, n=node->NumNoteTracks(); i<n; ++i) { + if ( NoteTrack *nt = node->GetNoteTrack(i) ) { + if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) { + DefNoteTrack *defNT = (DefNoteTrack *)nt; + if ( defNT->NumKeys() > 0 ) { + for (int j=0, m=defNT->keys.Count(); j<m; ++j) { + NoteKey* key = defNT->keys[j]; + if (wildmatch("start*", key->note)) { + return node; + } + } + } + } + } + } + } + for (int i=0; i < node->NumberOfChildren(); ++i ){ + if ( INode *root = findTrackedNode( node->GetChildNode(i) ) ) { + return root; + } + } + return NULL; +} + +bool AnimationExport::doExport(NiControllerSequenceRef seq) +{ + INode *node = findTrackedNode(ne.mI->GetRootNode()); + if (node == NULL) + throw runtime_error("No Actor Roots have been selected in the Animation Manager. Cannot continue."); + + this->seq = seq; + + vector<StringKey> textKeys; + + this->range.SetInstant(0); + + seq->SetStartTime(FloatINF); + seq->SetStopTime(FloatINF); seq->SetFrequency(1.0f); seq->SetCycleType( CYCLE_CLAMP ); - seq->SetTargetName("Bip01"); - - return true; + seq->SetTargetName( node->GetName() ); + + NiTextKeyExtraDataRef textKeyData = new NiTextKeyExtraData(); + seq->SetTextKey(textKeyData); + + // Populate Text keys and Sequence information from note tracks + for (int i=0, n=node->NumNoteTracks(); i<n; ++i) { + if ( NoteTrack *nt = node->GetNoteTrack(i) ) { + if ( nt->ClassID() == Class_ID(NOTETRACK_CLASS_ID,0) ) { + DefNoteTrack *defNT = (DefNoteTrack *)nt; + if ( defNT->NumKeys() > 0 ) { + bool stop = false; + for (int j=0, m=defNT->keys.Count(); j<m && !stop; ++j) { + NoteKey* key = defNT->keys[j]; + + if (wildmatch("start*", key->note)) { + stringlist args = TokenizeCommandLine(key->note, true); + if (args.empty()) continue; + + seq->SetStartTime(0.0f); + range.SetStart( key->time ); + for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) { + if (strmatch("-name", *itr)) { + if (++itr == args.end()) break; + seq->SetName(*itr); + } else if (strmatch("-loop", *itr)) { + seq->SetCycleType(CYCLE_LOOP); + } + } + } else if ( wildmatch("end*", key->note) ) { + range.SetEnd( key->time ); + seq->SetStopTime( FrameToTime( range.Duration()-1 ) ); + stop = true; + } + StringKey strkey; + strkey.time = FrameToTime( Interval(range.Start(), key->time).Duration()-1 ); + strkey.data = key->note; + textKeys.push_back(strkey); + } + } + } + } + } + textKeyData->SetKeys(textKeys); + + // Now let the fun begin. + + bool ok = exportController(node); + + // Handle NonAccum + if (ok) + { + NiNodeRef ninode = new NiNode(); + ninode->SetName(FormatString("%s NonAccum", node->GetName())); + + NiTransformControllerRef control = new NiTransformController(); + NiTransformInterpolatorRef interp = new NiTransformInterpolator(); + ninode->AddController(StaticCast<NiTimeController>(control)); + control->SetInterpolator(StaticCast<NiInterpolator>(interp)); + + interp->SetTranslation( Vector3(0.0f, 0.0f, 0.0f) ); + interp->SetScale( 1.0f ); + interp->SetRotation( Quaternion(1.0f, 0.0f, 0.0f, 0.0f) ); + seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), Exporter::mDefaultPriority); + } + return ok; } @@ -87,175 +192,255 @@ Control *AnimationExport::GetTMController(INode *n) } -bool AnimationExport::exportController(INode *node, NiControllerSequenceRef seq) +bool AnimationExport::exportController(INode *node) { bool ok = true; - int nKeys = node->NumKeys(); - if (nKeys >= 0) + bool skip = false; + + // Primary recursive decent routine + + ObjectState os = node->EvalWorldState(range.Start()); + + if (!Exporter::mExportCameras && os.obj && os.obj->SuperClassID()==CAMERA_CLASS_ID) + { + skip = true; + } + else if (!Exporter::mExportLights && os.obj && os.obj->SuperClassID()==LIGHT_CLASS_ID) + { + skip = true; + } + + if (!skip && Exporter::mExportTransforms) { - float timeOffset = 0.0f; - NiKeyframeDataRef data = new NiKeyframeData(); + float timeOffset = -FrameToTime(range.Start()); if (Control *tmCont = GetTMController(node)) { - if (Control *c = tmCont->GetPositionController()) + Interval validity; validity.SetEmpty(); + Matrix3 tm = node->GetObjTMAfterWSM(range.Start()); + Matrix3 pm = Inverse(node->GetParentTM(range.Start())); + tm *= pm; + + NiNodeRef ninode = new NiNode(); + ninode->SetName(node->GetName()); + + //Vector3 trans(FloatNegINF, FloatNegINF, FloatNegINF); + //Quaternion rot(FloatNegINF, FloatNegINF, FloatNegINF, FloatNegINF); + Vector3 trans = TOVECTOR3(tm.GetTrans()); + Quaternion rot = TOQUAT( Quat(tm), true ); + float scale = FloatNegINF; + bool keepData = false; + + NiTransformControllerRef control = new NiTransformController(); + NiTransformInterpolatorRef interp = new NiTransformInterpolator(); + ninode->AddController(StaticCast<NiTimeController>(control)); + control->SetInterpolator(StaticCast<NiInterpolator>(interp)); + + //if (validity.InInterval(range)) + //{ + // // Valid for entire interval. i.e. no changes + // interp->SetTranslation( TOVECTOR3(tm.GetTrans()) ); + // interp->SetScale( Average(GetScale(tm)) ); + // interp->SetRotation( TOQUAT( Quat(tm) ) ); + // seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control)); + //} + //else { - // separate xyz - if (c->ClassID() == IPOS_CONTROL_CLASS_ID) - { - KeyType kType = QUADRATIC_KEY; - vector<FloatKey> xkeys, ykeys, zkeys; - - if (Control *x = c->GetXController()){ - if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - kType = LINEAR_KEY; - GetKeys<FloatKey, ILinFloatKey>(x, xkeys, timeOffset); - } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - kType = QUADRATIC_KEY; - GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset); - } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - kType = TBC_KEY; - GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, timeOffset); - } else { - kType = QUADRATIC_KEY; - GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset); + NiTransformDataRef data = new NiTransformData(); + + if (Control *c = tmCont->GetPositionController()) + { + int nkeys = 0; + // separate xyz + if (c->ClassID() == IPOS_CONTROL_CLASS_ID) + { + KeyType kType = QUADRATIC_KEY; + vector<FloatKey> xkeys, ykeys, zkeys; + if (Control *x = c->GetXController()){ + if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + kType = LINEAR_KEY; + nkeys += GetKeys<FloatKey, ILinFloatKey>(x, xkeys, range); + } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + kType = QUADRATIC_KEY; + nkeys += GetKeys<FloatKey, IBezFloatKey>(x, xkeys, range); + } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + kType = TBC_KEY; + nkeys += GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, range); + } else { + kType = QUADRATIC_KEY; + nkeys += GetKeys<FloatKey, IBezFloatKey>(x, xkeys, range); + } } - } - if (Control *y = c->GetYController()){ - if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, ILinFloatKey>(y, ykeys, timeOffset); - } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset); - } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, timeOffset); + if (Control *y = c->GetYController()){ + if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ILinFloatKey>(y, ykeys, range); + } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, IBezFloatKey>(y, ykeys, range); + } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, range); + } else { + nkeys += GetKeys<FloatKey, IBezFloatKey>(y, ykeys, range); + } + } + if (Control *z = c->GetZController()){ + if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ILinFloatKey>(z, zkeys, range); + } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, IBezFloatKey>(z, zkeys, range); + } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, range); + } else { + nkeys += GetKeys<FloatKey, IBezFloatKey>(z, zkeys, range); + } + } + vector<Vector3Key> keys; + JoinKeys(keys, xkeys, ykeys, zkeys); + data->SetTranslateType(kType); + data->SetTranslateKeys(keys); + } else { + vector<Vector3Key> keys; + if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + data->SetTranslateType(LINEAR_KEY); + nkeys += GetKeys<Vector3Key, ILinPoint3Key>(c, keys, range); + } else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + data->SetTranslateType(QUADRATIC_KEY); + nkeys += GetKeys<Vector3Key, IBezPoint3Key>(c, keys, range); + } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + data->SetTranslateType(TBC_KEY); + nkeys += GetKeys<Vector3Key, ITCBPoint3Key>(c, keys, range); } else { - GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset); + data->SetTranslateType(QUADRATIC_KEY); + nkeys += GetKeys<Vector3Key, IBezPoint3Key>(c, keys, range); } + data->SetTranslateKeys(keys); } - if (Control *z = c->GetZController()){ - if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset); - } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset); - } else { - GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); + if (nkeys != 0) { // if no changes set the base transform + keepData = true; + //trans = TOVECTOR3(tm.GetTrans()); + } + } + + // Rotations + if (Control *c = tmCont->GetRotationController()) + { + int nkeys = 0; + if (c->ClassID() == Class_ID(LININTERP_ROTATION_CLASS_ID,0)) { + vector<QuatKey> keys; + data->SetRotateType(LINEAR_KEY); + nkeys += GetKeys<QuatKey, ILinRotKey>(c, keys, range); + data->SetQuatRotateKeys(keys); + } else if (c->ClassID() == Class_ID(HYBRIDINTERP_ROTATION_CLASS_ID,0)) { + vector<QuatKey> keys; + data->SetRotateType(QUADRATIC_KEY); + nkeys += GetKeys<QuatKey, IBezQuatKey>(c, keys, range); + data->SetQuatRotateKeys(keys); + } else if (c->ClassID() == Class_ID(EULER_CONTROL_CLASS_ID,0)) { + if (Control *x = c->GetXController()){ + vector<FloatKey> keys; + if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ILinFloatKey>(x, keys, range); + data->SetXRotateType(LINEAR_KEY); + } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, IBezFloatKey>(x, keys, range); + data->SetXRotateType(QUADRATIC_KEY); + } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ITCBFloatKey>(x, keys, range); + data->SetXRotateType(TBC_KEY); + } else { + nkeys += GetKeys<FloatKey, IBezFloatKey>(x, keys, range); + data->SetXRotateType(QUADRATIC_KEY); + } + data->SetXRotateKeys(keys); + } + if (Control *y = c->GetXController()) { + vector<FloatKey> keys; + if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ILinFloatKey>(y, keys, range); + data->SetYRotateType(LINEAR_KEY); + } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, IBezFloatKey>(y, keys, range); + data->SetYRotateType(QUADRATIC_KEY); + } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ITCBFloatKey>(y, keys, range); + data->SetYRotateType(TBC_KEY); + } else { + nkeys += GetKeys<FloatKey, IBezFloatKey>(y, keys, range); + data->SetYRotateType(QUADRATIC_KEY); + } + data->SetYRotateKeys(keys); + } + if (Control *z = c->GetZController()) { + vector<FloatKey> keys; + if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ILinFloatKey>(z, keys, range); + data->SetZRotateType(LINEAR_KEY); + } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, IBezFloatKey>(z, keys, range); + data->SetZRotateType(QUADRATIC_KEY); + } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { + nkeys += GetKeys<FloatKey, ITCBFloatKey>(z, keys, range); + data->SetZRotateType(TBC_KEY); + } else { + nkeys += GetKeys<FloatKey, IBezFloatKey>(z, keys, range); + data->SetZRotateType(QUADRATIC_KEY); + } + data->SetZRotateKeys(keys); } + } else if (c->ClassID() == Class_ID(TCBINTERP_ROTATION_CLASS_ID,0)) { + vector<QuatKey> keys; + data->SetRotateType(TBC_KEY); + nkeys += GetKeys<QuatKey, ITCBRotKey>(c, keys, range); + data->SetQuatRotateKeys(keys); + } + if (nkeys != 0) { // if no changes set the base transform + keepData = true; + //rot = TOQUAT( Quat(tm) ); } - vector<Vector3Key> keys; - JoinKeys(keys, xkeys, ykeys, zkeys); - data->SetTranslateType(kType); - data->SetTranslateKeys(keys); - - } else { - //if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - // data->SetRotateType(LINEAR_KEY); - // GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset); - //} else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - //} else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(TBC_KEY); - // GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset); - //} else { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - //} } - } - //// rotations - //if (Control *c = tmCont->GetPositionController()) - //{ - // // separate xyz - // if (c->ClassID() == IPOS_CONTROL_CLASS_ID) - // { - // if (Control *x = c->GetXController()){ - // if (x->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - // data->SetXRotateType(LINEAR_KEY); - // GetKeys<FloatKey, ILinFloatKey>(x, xkeys, timeOffset); - // } else if (x->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - // data->SetXRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset); - // } else if (x->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - // data->SetXRotateType(TBC_KEY); - // GetKeys<FloatKey, ITCBFloatKey>(x, xkeys, timeOffset); - // } else { - // data->SetXRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(x, xkeys, timeOffset); - // } - // data->SetXRotateKeys(xkeys); - // } - // if (Control *y = c->GetYController()){ - // KeyType kType = LINEAR_KEY; - // vector<FloatKey> ykeys; - // if (y->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - // data->SetYRotateType(LINEAR_KEY); - // GetKeys<FloatKey, ILinFloatKey>(y, ykeys, timeOffset); - // } else if (y->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - // data->SetYRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset); - // } else if (y->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - // data->SetYRotateType(TBC_KEY); - // GetKeys<FloatKey, ITCBFloatKey>(y, ykeys, timeOffset); - // } else { - // data->SetYRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(y, ykeys, timeOffset); - // } - // data->SetYRotateKeys(ykeys); - // } - // if (Control *z = c->GetZController()){ - // KeyType kType = LINEAR_KEY; - // vector<FloatKey> zkeys; - // if (z->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(LINEAR_KEY); - // GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset); - // } else if (z->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - // } else if (z->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(TBC_KEY); - // GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset); - // } else { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - // } - // data->SetZRotateKeys(zkeys); - // } - // } else { - // if (c->ClassID() == Class_ID(LININTERP_FLOAT_CLASS_ID,0)) { - // data->SetRotateType(LINEAR_KEY); - // GetKeys<FloatKey, ILinFloatKey>(z, zkeys, timeOffset); - // } else if (c->ClassID() == Class_ID(HYBRIDINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - // } else if (c->ClassID() == Class_ID(TCBINTERP_FLOAT_CLASS_ID,0)) { - // data->SetZRotateType(TBC_KEY); - // GetKeys<FloatKey, ITCBFloatKey>(z, zkeys, timeOffset); - // } else { - // data->SetZRotateType(QUADRATIC_KEY); - // GetKeys<FloatKey, IBezFloatKey>(z, zkeys, timeOffset); - // } - // } - //} + // Scale + if (Control *c = tmCont->GetScaleController()) + { + int nkeys = 0; + if (c->ClassID() == Class_ID(LININTERP_SCALE_CLASS_ID,0)) { + vector<FloatKey> keys; + data->SetScaleType(LINEAR_KEY); + nkeys += GetKeys<FloatKey, ILinFloatKey>(c, keys, range); + data->SetScaleKeys(keys); + } else if (c->ClassID() == Class_ID(HYBRIDINTERP_SCALE_CLASS_ID,0)) { + vector<FloatKey> keys; + data->SetScaleType(QUADRATIC_KEY); + nkeys += GetKeys<FloatKey, IBezFloatKey>(c, keys, range); + data->SetScaleKeys(keys); + } else if (c->ClassID() == Class_ID(TCBINTERP_SCALE_CLASS_ID,0)) { + vector<FloatKey> keys; + data->SetScaleType(TBC_KEY); + nkeys += GetKeys<FloatKey, ITCBFloatKey>(c, keys, range); + data->SetScaleKeys(keys); + } + if (nkeys != 0) { // if no changes set the base transform + keepData = true; + //scale = Average(GetScale(tm)); + } + } + // only add transform data object if data actually is present + if (keepData) { + interp->SetData(data); + } + interp->SetTranslation(trans); + interp->SetScale(scale); + interp->SetRotation(rot); + // Get Priority from node + float priority; + npGetProp(node, NP_ANM_PRI, priority, Exporter::mDefaultPriority); + seq->AddInterpolator(StaticCast<NiSingleInterpolatorController>(control), priority); + } } - //Class_ID c->ClassID() - //if (Control *subCtrl = MakePositionXYZ(c, Class_ID(LININTERP_FLOAT_CLASS_ID,0))) { - - //NiKeyframeDataRef data = new NiKeyframeData(); - //NiKeyframeDataRef data = CreateBlock("NiKeyframeData"); - //data->SetRotateType(QUADRATIC_KEY); - //data->SetTranslateType(QUADRATIC_KEY); - //data->SetScaleType(QUADRATIC_KEY); - //data->SetTranslateKeys( interp->SampleTranslateKeys(npoints, 4) ); - //data->SetQuatRotateKeys( interp->SampleQuatRotateKeys(npoints, 4) ); - //data->SetScaleKeys( interp->SampleScaleKeys(npoints, 4) ); } for (int i=0, n=node->NumberOfChildren(); ok && i<n; ++i) { INode *child = node->GetChildNode(i); - ok |= exportController(child, seq); + ok |= exportController(child); } return ok; } \ No newline at end of file diff --git a/NifExport/Config.cpp b/NifExport/Config.cpp index ea3262bd7c8ecb394e070f66be6ca1f64804ae82..1ff47215a3f811c63ea53af2a3b1720566b5400f 100755 --- a/NifExport/Config.cpp +++ b/NifExport/Config.cpp @@ -5,6 +5,7 @@ #define REGPATH "Software\\NifTools\\MaxPlugins" static LPCTSTR NifExportSection = TEXT("MaxNifExport"); +static LPCTSTR KfExportSection = TEXT("KfExport"); void regSet(HKEY hKey, const char *value, float f); void regSet(HKEY hKey, const char *value, bool b); @@ -127,6 +128,33 @@ 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"); + + mExportHidden = GetIniValue(KfExportSection, "IncludeHidden", false, iniName); + mExportLights = GetIniValue(KfExportSection, "Lights", false, iniName); + mExportCameras = GetIniValue(KfExportSection, "Cameras", false, iniName); + mExportTransforms = GetIniValue(KfExportSection, "Transforms", true, iniName); + mDefaultPriority = GetIniValue<float>(KfExportSection, "Priority", 0.0f, iniName); +} + +void Exporter::writeKfConfig(Interface *i) +{ + TCHAR iniName[MAX_PATH]; + LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); + PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + + SetIniValue(KfExportSection, "IncludeHidden", mExportHidden, iniName); + SetIniValue(KfExportSection, "Lights", mExportLights, iniName); + SetIniValue(KfExportSection, "Cameras", mExportCameras, iniName); + SetIniValue(KfExportSection, "Transforms", mExportTransforms, iniName); + SetIniValue<float>(KfExportSection, "Priority", mDefaultPriority, iniName); +} + + void regSet(HKEY hKey, const char *value, float f) { DWORD dw = *((DWORD*)&f); diff --git a/NifExport/DllEntry.cpp b/NifExport/DllEntry.cpp index 0e7e3aa41240323708f514992bc56e1e06930ca8..8907fa30db1f0a35a8ab4ad4837e92ad3c4bb885 100755 --- a/NifExport/DllEntry.cpp +++ b/NifExport/DllEntry.cpp @@ -60,11 +60,7 @@ __declspec( dllexport ) const TCHAR* LibDescription() //TODO: Must change this number when adding a new class __declspec( dllexport ) int LibNumberClasses() { -#if _DEBUG - return 2; -#else - return 1; -#endif + return 2; } // This function returns the number of plug-in classes this DLL diff --git a/NifExport/Exporter.cpp b/NifExport/Exporter.cpp index a13f1df7e507b17431ca5aaf92e39f9895a9b4de..8bdf74b283dc387b0a24605022d2d300ceb9700d 100755 --- a/NifExport/Exporter.cpp +++ b/NifExport/Exporter.cpp @@ -29,6 +29,8 @@ int Exporter::mNifUserVersion = 0; bool Exporter::mSkeletonOnly=false; bool Exporter::mExportCameras=false; bool Exporter::mGenerateBoneCollision=false; +bool Exporter::mExportTransforms=true; +float Exporter::mDefaultPriority=0.0f; Exporter::Exporter(Interface *i, AppSettings *appSettings) : mI(i), mAppSettings(appSettings) diff --git a/NifExport/Exporter.h b/NifExport/Exporter.h index 44dd7b7d7e28f4ac83dde840596bd85ca46c15e7..8d5b2f0dfaf90b39abe09b808d948aaa7a36e233 100755 --- a/NifExport/Exporter.h +++ b/NifExport/Exporter.h @@ -57,6 +57,9 @@ public: static bool mExportCameras; static bool mGenerateBoneCollision; + static bool mExportTransforms; + static float mDefaultPriority; + Exporter(Interface *i, AppSettings *appSettings); Result doExport(NiNodeRef &root, INode *node); @@ -70,11 +73,15 @@ public: static void writeConfig(INode *node); // writes config to registry static void writeConfig(Interface *i); + // writes config to registry + static void writeKfConfig(Interface *i); // reads config from root node static void readConfig(INode *node); // reads config from registry static void readConfig(Interface *i); + // reads config from registry + static void readKfConfig(Interface *i); public: typedef vector<unsigned short> TriStrip; @@ -176,7 +183,7 @@ public: bool exportSkin(); /* animation export */ - bool doAnimExport(); + Result doAnimExport(Ref<NiControllerSequence> root); /* misc export */ bool exportUPB(NiNodeRef &root, INode *node); diff --git a/NifExport/KfExport.cpp b/NifExport/KfExport.cpp index c865cc3f50e5868ef38819cf1144d256783be6b0..4102b0c8e651f3511caf265f32f1dff1de80dfe4 100644 --- a/NifExport/KfExport.cpp +++ b/NifExport/KfExport.cpp @@ -2,12 +2,12 @@ #include "AppSettings.h" #include "niutils.h" #include <io.h> - +#include "obj/NiControllerSequence.h" using namespace Niflib; #define KFEXPORT_CLASS_ID Class_ID(0xa57ff0a4, 0xa0374ffc) -static LPCTSTR KfExportSection = TEXT("MaxKfExport"); +static LPCTSTR KfExportSection = TEXT("KfExport"); class KfExport : public SceneExport { @@ -43,12 +43,12 @@ class KfExportClassDesc : public ClassDesc2 public: int IsPublic() { return TRUE; } void *Create(BOOL loading = FALSE) { return new KfExport(); } - const TCHAR *ClassName() { return GetString(IDS_CLASS_NAME); } + const TCHAR *ClassName() { return GetString(IDS_KF_CLASS_NAME); } SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } Class_ID ClassID() { return KFEXPORT_CLASS_ID; } const TCHAR *Category() { return GetString(IDS_CATEGORY); } - const TCHAR *InternalName() { return _T("KfExport"); } // returns fixed parsable name (scripter-visible name) + const TCHAR *InternalName() { return _T("_KfExport"); } // returns fixed parsable name (scripter-visible name) HINSTANCE HInstance() { return hInstance; } // returns owning module handle @@ -58,6 +58,128 @@ static KfExportClassDesc KfExportDesc; ClassDesc2* GetKfExportDesc() { return &KfExportDesc; } +static BOOL CALLBACK KfExportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam) { + static KfExport *imp = NULL; + + switch (message) + { + case WM_INITDIALOG: + { + // Append file version to dialog + TSTR fileVersion = GetFileVersion(NULL); + if (!fileVersion.isNull()) { + char buffer[256]; + GetWindowText(hWnd, buffer, _countof(buffer)); + _tcscat(buffer, TEXT(" ")); + _tcscat(buffer, fileVersion); + SetWindowText(hWnd, buffer); + } + + imp = (KfExport *)lParam; + CenterWindow(hWnd,GetParent(hWnd)); + + CheckDlgButton(hWnd, IDC_CHK_HIDDEN, Exporter::mExportHidden); + CheckDlgButton(hWnd, IDC_CHK_LIGHTS, Exporter::mExportLights); + CheckDlgButton(hWnd, IDC_CHK_CAMERA, Exporter::mExportCameras); + CheckDlgButton(hWnd, IDC_CHK_TRANSFORMS, Exporter::mExportTransforms); + SetDlgItemText(hWnd, IDC_ED_PRIORITY, FormatText("%.4f", Exporter::mDefaultPriority)); + + string selection = Exporter::mGameName; + string version = Exporter::mNifVersion; + string userVer = FormatString("%d", Exporter::mNifUserVersion); + for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr) + SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_ADDSTRING, 0, LPARAM(itr->Name.c_str())); + SendDlgItemMessage(hWnd, IDC_CB_GAME, CB_SELECTSTRING, WPARAM(-1), LPARAM(selection.c_str())); + SendDlgItemMessage(hWnd, IDC_CB_VERSION, WM_SETTEXT, 0, LPARAM(version.c_str())); + SendDlgItemMessage(hWnd, IDC_CB_USER_VERSION, WM_SETTEXT, 0, LPARAM(userVer.c_str())); + + imp->mDlgResult = IDCANCEL; + } + return TRUE; + + case WM_CLOSE: + EndDialog(hWnd, imp->mDlgResult); + return TRUE; + + case WM_COMMAND: + if (HIWORD(wParam) == BN_CLICKED) + { + char tmp[MAX_PATH], *end; + bool close = false; + switch (LOWORD(wParam)) + { + case IDOK: + // Validity Check + GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH); + if (tmp[0] != 0) + { + int nifVersion = GetVersion(tmp); + if (!IsVersionSupported(nifVersion)) + { + MessageBox(hWnd, FormatString("Version '%s' is not a supported version.", tmp).c_str(), "NifExport", MB_OK|MB_ICONSTOP); + return FALSE; + } + } + + Exporter::mExportHidden = IsDlgButtonChecked(hWnd, IDC_CHK_HIDDEN); + Exporter::mExportLights = IsDlgButtonChecked(hWnd, IDC_CHK_LIGHTS); + Exporter::mExportCameras = IsDlgButtonChecked(hWnd, IDC_CHK_CAMERA); + Exporter::mExportTransforms = IsDlgButtonChecked(hWnd, IDC_CHK_TRANSFORMS); + + GetDlgItemText(hWnd, IDC_ED_PRIORITY, tmp, MAX_PATH); + Exporter::mDefaultPriority = atof(tmp); + + GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH); + if (AppSettings *appSettings = FindAppSetting(tmp)) + { + Exporter::mGameName = appSettings->Name; + GetDlgItemText(hWnd, IDC_CB_VERSION, tmp, MAX_PATH); + Exporter::mNifVersion = tmp; + GetDlgItemText(hWnd, IDC_CB_USER_VERSION, tmp, MAX_PATH); + Exporter::mNifUserVersion = strtol(tmp, &end, 0); + } + + EndDialog(hWnd, imp->mDlgResult=IDOK); + close = true; + break; + + case IDCANCEL: + EndDialog(hWnd, imp->mDlgResult=IDCANCEL); + close = true; + break; + } + + if (close) + SendMessage(hWnd, WM_CLOSE, 0, 0); + } + else if (HIWORD(wParam) == STN_CLICKED) + { + if (LOWORD(wParam) == IDC_LBL_LINK) + { + ShellExecute(hWnd, "open", "http://www.niftools.org", + NULL, NULL, SW_SHOWDEFAULT); + } + } + else if (HIWORD(wParam) == CBN_SELCHANGE) + { + if (LOWORD(wParam) == IDC_CB_GAME) + { + char tmp[MAX_PATH]; + GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH); + if (AppSettings *appSettings = FindAppSetting(tmp)) + { + string version = appSettings->NiVersion; + string userVer = FormatString("%d", appSettings->NiUserVersion); + SendDlgItemMessage(hWnd, IDC_CB_VERSION, WM_SETTEXT, 0, LPARAM(version.c_str())); + SendDlgItemMessage(hWnd, IDC_CB_USER_VERSION, WM_SETTEXT, 0, LPARAM(userVer.c_str())); + } + } + } + break; + } + return FALSE; +} + //--- KfExport ------------------------------------------------------- KfExport::KfExport() { @@ -141,8 +263,103 @@ BOOL KfExport::SupportsOptions(int ext, DWORD options) int KfExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options) { - // read application settings - AppSettings::Initialize(i); + try + { + // read application settings + AppSettings::Initialize(i); + + TCHAR iniName[MAX_PATH]; + LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); + PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + bool iniNameIsValid = (-1 != _taccess(iniName, 0)); + + // read config from registry + Exporter::readKfConfig(i); + + AppSettings *appSettings = NULL; + if (iniNameIsValid) + { + string fname = name; + // Locate which application to use. If Auto, find first app where this file appears in the root path list + string curapp = GetIniValue<string>(KfExportSection, "CurrentApp", "AUTO", iniName); + if (0 == _tcsicmp(curapp.c_str(), "AUTO")) { + // Scan Root paths + for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){ + if ((*itr).IsFileInRootPaths(fname)) { + appSettings = &(*itr); + break; + } + } + } else { + appSettings = FindAppSetting(curapp); + } + } + if (appSettings == NULL && !TheAppSettings.empty()) + appSettings = &TheAppSettings.front(); + + Exporter::mGameName = appSettings->Name; + Exporter::mNifVersion = appSettings->NiVersion; + Exporter::mNifUserVersion = appSettings->NiUserVersion; + + if(!suppressPrompts) + { + if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_KF_PANEL), GetActiveWindow(), KfExportOptionsDlgProc, (LPARAM)this) != IDOK) + return true; + + // write config to registry + Exporter::writeKfConfig(i); + + // write config to root node + Exporter::writeConfig(i->GetRootNode()); + + // Update the current app version + appSettings = FindAppSetting(Exporter::mGameName); + if (appSettings == NULL && !TheAppSettings.empty()) + appSettings = &TheAppSettings.front(); + appSettings->NiVersion = Exporter::mNifVersion; + appSettings->NiUserVersion = Exporter::mNifUserVersion; + appSettings->WriteSettings(i); + } + + int nifVersion = VER_20_0_0_5; + int nifUserVer = Exporter::mNifUserVersion; + + if (!Exporter::mNifVersion.empty()) + { + nifVersion = GetVersion(Exporter::mNifVersion); + if (!IsVersionSupported(nifVersion)) + throw exception(FormatString("Version '%s' is not a supported version.").c_str()); + } + + Exporter::mSelectedOnly = (options&SCENE_EXPORT_SELECTED) != 0; + Exporter exp(i, appSettings); + + Ref<NiControllerSequence> root = new NiControllerSequence(); + + TCHAR fname[MAX_PATH]; + _tcscpy(fname, PathFindFileName(name)); + PathRemoveExtension(fname); + root->SetName(fname); + + Exporter::Result result = exp.doAnimExport(root); + + if (result!=Exporter::Ok) + throw exception("Unknown error."); + + WriteNifTree(name, StaticCast<NiObject>(root), nifVersion, nifUserVer); + } + + catch (exception &e) + { + MessageBox(NULL, e.what(), "Export Error", MB_OK); + return true; + } + + catch (...) + { + MessageBox(NULL, "Unknown error.", "Export Error", MB_OK); + return true; + } return TRUE; } \ No newline at end of file diff --git a/NifExport/MtlTex.cpp b/NifExport/MtlTex.cpp index 75b4089cd2050e44187e0961f0ab882b4a14ba92..9465d638f0ccbc8947b0a359f3ffb5dbfd208226 100755 --- a/NifExport/MtlTex.cpp +++ b/NifExport/MtlTex.cpp @@ -136,16 +136,16 @@ void Exporter::makeMaterial(NiAVObjectRef &parent, Mtl *mtl) if (smtl->SupportsShaders()) { if (Shader *s = smtl->GetShader()) { if (smtl->GetWire()){ - NiWireframePropertyRef wireProp = CreateNiObject<NiWireframeProperty>(); + NiWireframePropertyRef wireProp = new NiWireframeProperty(); wireProp->SetFlags(1); parent->AddProperty(wireProp); } if (smtl->GetTwoSided()){ - NiStencilPropertyRef stencil = CreateNiObject<NiStencilProperty>(); - stencil->SetStencilFunction(4); + NiStencilPropertyRef stencil = new NiStencilProperty(); + stencil->SetStencilFunction(TEST_GREATER); stencil->SetStencilEnabled(false); - stencil->SetPassAction(3); - stencil->SetDrawMode(3); + stencil->SetPassAction(ACTION_INCREMENT); + stencil->SetDrawMode(DRAW_BOTH); parent->AddProperty(stencil); } if (smtl->IsFaceted()) { @@ -343,10 +343,10 @@ bool Exporter::exportCiv4Shader(NiAVObjectRef parent, Mtl* mtl) } if (smtl->GetTwoSided()){ NiStencilPropertyRef stencil = CreateNiObject<NiStencilProperty>(); - stencil->SetStencilFunction(4); + stencil->SetStencilFunction(TEST_GREATER); stencil->SetStencilEnabled(false); - stencil->SetPassAction(3); - stencil->SetDrawMode(3); + stencil->SetPassAction(ACTION_INCREMENT); + stencil->SetDrawMode(DRAW_BOTH); parent->AddProperty(stencil); } if (smtl->IsFaceted()) { diff --git a/NifExport/NifExport.cpp b/NifExport/NifExport.cpp index c434a040a0617c47aa96e71c101746b1519f789f..4a7be3b46dcf171409aa11ef92ceb10ffda3f6cd 100755 --- a/NifExport/NifExport.cpp +++ b/NifExport/NifExport.cpp @@ -7,7 +7,7 @@ using namespace Niflib; #define NifExport_CLASS_ID Class_ID(0xa57ff0a4, 0xa0374ffb) -static LPCTSTR NifExportSection = TEXT("MaxNifExport"); +LPCTSTR NifExportSection = TEXT("MaxNifExport"); class NifExport : public SceneExport { @@ -41,7 +41,7 @@ class NifExportClassDesc : public ClassDesc2 public: int IsPublic() { return TRUE; } void *Create(BOOL loading = FALSE) { return new NifExport(); } - const TCHAR *ClassName() { return GetString(IDS_CLASS_NAME); } + const TCHAR *ClassName() { return GetString(IDS_NIF_CLASS_NAME); } SClass_ID SuperClassID() { return SCENE_EXPORT_CLASS_ID; } Class_ID ClassID() { return NifExport_CLASS_ID; } const TCHAR *Category() { return GetString(IDS_CATEGORY); } @@ -283,68 +283,69 @@ BOOL NifExport::SupportsOptions(int ext, DWORD options) int NifExport::DoExport(const TCHAR *name, ExpInterface *ei, Interface *i, BOOL suppressPrompts, DWORD options) { - // read application settings - AppSettings::Initialize(i); - - TCHAR iniName[MAX_PATH]; - LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); - PathCombine(iniName, pluginDir, "MaxNifTools.ini"); - bool iniNameIsValid = (-1 != _taccess(iniName, 0)); - - // Set whether Config should use registry or not - Exporter::mUseRegistry = !iniNameIsValid || GetIniValue<bool>(NifExportSection, "UseRegistry", false, iniName); - // read config from registry - Exporter::readConfig(i); - // read config from root node - Exporter::readConfig(i->GetRootNode()); - - // locate the "default" app setting - AppSettings *appSettings = NULL; - if (iniNameIsValid) - { - string fname = name; - // 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); - if (0 == _tcsicmp(curapp.c_str(), "AUTO")) { - // Scan Root paths - for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){ - if ((*itr).IsFileInRootPaths(fname)) { - appSettings = &(*itr); - break; + try + { + // read application settings + AppSettings::Initialize(i); + + TCHAR iniName[MAX_PATH]; + LPCTSTR pluginDir = i->GetDir(APP_PLUGCFG_DIR); + PathCombine(iniName, pluginDir, "MaxNifTools.ini"); + bool iniNameIsValid = (-1 != _taccess(iniName, 0)); + + // Set whether Config should use registry or not + Exporter::mUseRegistry = !iniNameIsValid || GetIniValue<bool>(NifExportSection, "UseRegistry", false, iniName); + // read config from registry + Exporter::readConfig(i); + // read config from root node + Exporter::readConfig(i->GetRootNode()); + + // locate the "default" app setting + AppSettings *appSettings = NULL; + if (iniNameIsValid) + { + string fname = name; + // 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); + if (0 == _tcsicmp(curapp.c_str(), "AUTO")) { + // Scan Root paths + for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr){ + if ((*itr).IsFileInRootPaths(fname)) { + appSettings = &(*itr); + break; + } } + } else { + appSettings = FindAppSetting(curapp); } - } else { - appSettings = FindAppSetting(curapp); } - } - if (appSettings == NULL && !TheAppSettings.empty()) - appSettings = &TheAppSettings.front(); + if (appSettings == NULL && !TheAppSettings.empty()) + appSettings = &TheAppSettings.front(); - if(!suppressPrompts) - { Exporter::mGameName = appSettings->Name; Exporter::mNifVersion = appSettings->NiVersion; Exporter::mNifUserVersion = appSettings->NiUserVersion; - if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_PANEL), GetActiveWindow(), NifExportOptionsDlgProc, (LPARAM)this) != IDOK) - return true; - - // write config to registry - Exporter::writeConfig(i); - // write config to root node - Exporter::writeConfig(i->GetRootNode()); - - // Update the current app version - appSettings = FindAppSetting(Exporter::mGameName); - if (appSettings == NULL && !TheAppSettings.empty()) - appSettings = &TheAppSettings.front(); - appSettings->NiVersion = Exporter::mNifVersion; - appSettings->NiUserVersion = Exporter::mNifUserVersion; - appSettings->WriteSettings(i); - } + if(!suppressPrompts) + { + if (DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_NIF_PANEL), GetActiveWindow(), NifExportOptionsDlgProc, (LPARAM)this) != IDOK) + return true; + + // write config to registry + Exporter::writeConfig(i); + // write config to root node + Exporter::writeConfig(i->GetRootNode()); + + // Update the current app version + appSettings = FindAppSetting(Exporter::mGameName); + if (appSettings == NULL && !TheAppSettings.empty()) + appSettings = &TheAppSettings.front(); + appSettings->NiVersion = Exporter::mNifVersion; + appSettings->NiUserVersion = Exporter::mNifUserVersion; + appSettings->WriteSettings(i); + } + - try - { int nifVersion = VER_20_0_0_5; int nifUserVer = Exporter::mNifUserVersion; diff --git a/NifExport/NifExport.rc b/NifExport/NifExport.rc index 5c6fc3a057fd45cc1c041fb16a9506a7af96a616..e9f8667ef76badcbcc0debc9b014428f172e567a 100755 --- a/NifExport/NifExport.rc +++ b/NifExport/NifExport.rc @@ -73,7 +73,32 @@ END // Dialog // -IDD_PANEL DIALOGEX 0, 0, 205, 203 +IDD_KF_PANEL DIALOGEX 0, 0, 205, 130 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_TOOLWINDOW +CAPTION "Export KF" +FONT 8, "MS Sans Serif", 0, 0, 0x1 +BEGIN + GROUPBOX "Export:",IDC_STATIC,7,7,81,66 + CONTROL "&Hidden Nodes",IDC_CHK_HIDDEN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,17,67,10 + CONTROL "Transforms",IDC_CHK_TRANSFORMS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,31,67,10 + CONTROL "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,44,67,10 + CONTROL "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,58,67,10 + GROUPBOX "Behaviors:",IDC_STATIC,94,7,104,66 + LTEXT "Priority:",IDC_LBL_PRIORITY,104,24,37,8 + EDITTEXT IDC_ED_PRIORITY,145,22,39,12,ES_AUTOHSCROLL + LTEXT "Game",IDC_STATIC,7,78,66,8 + COMBOBOX IDC_CB_GAME,7,89,105,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Version",IDC_STATIC,117,78,39,8 + EDITTEXT IDC_CB_VERSION,117,89,45,12,ES_AUTOHSCROLL + LTEXT "User",IDC_STATIC,167,78,25,8 + EDITTEXT IDC_CB_USER_VERSION,167,89,30,12,ES_AUTOHSCROLL + DEFPUSHBUTTON "&Export",IDOK,5,109,34,14 + PUSHBUTTON "&Cancel",IDCANCEL,45,109,33,14 + LTEXT "http://www.niftools.org",IDC_LBL_LINK,103,109,95,14,SS_NOTIFY | SS_CENTERIMAGE +END + +IDD_NIF_PANEL DIALOGEX 0, 0, 205, 203 STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU EXSTYLE WS_EX_TOOLWINDOW CAPTION "Export Nif" @@ -122,7 +147,15 @@ END #ifdef APSTUDIO_INVOKED GUIDELINES DESIGNINFO BEGIN - IDD_PANEL, DIALOG + IDD_KF_PANEL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 198 + TOPMARGIN, 7 + BOTTOMMARGIN, 123 + END + + IDD_NIF_PANEL, DIALOG BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 198 @@ -139,8 +172,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,3,0 - PRODUCTVERSION 0,2,3,0 + FILEVERSION 0,2,4,0 + PRODUCTVERSION 0,2,4,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -156,12 +189,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "3ds Max Nif Exporter" - VALUE "FileVersion", "0, 2, 3, 0" + VALUE "FileVersion", "0, 2, 4, 0" VALUE "InternalName", "NifExport.dle" VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved." VALUE "OriginalFilename", "NifExport.dle" VALUE "ProductName", "3ds Max Nif Exporter" - VALUE "ProductVersion", "0, 2, 3, 0" + VALUE "ProductVersion", "0, 2, 4, 0" END END BLOCK "VarFileInfo" @@ -178,9 +211,10 @@ END STRINGTABLE BEGIN - IDS_CLASS_NAME "Nif Exporter" + IDS_NIF_CLASS_NAME "Niftools NIF Exporter" IDS_PARAMS "Parameters" IDS_SPIN "Spin" + IDS_KF_CLASS_NAME "Niftools KF Exporter" END #endif // English (U.S.) resources diff --git a/NifExport/resource.h b/NifExport/resource.h index 2aeda3876b1813200b7f14bf54146135089fb35a..3d67a7f977ff854f1ab41c0ba34a65177ff3043a 100755 --- a/NifExport/resource.h +++ b/NifExport/resource.h @@ -5,9 +5,13 @@ #define IDS_LIBDESCRIPTION 1 #define IDS_CATEGORY 2 #define IDS_CLASS_NAME 3 +#define IDS_NIF_CLASS_NAME 3 #define IDS_PARAMS 4 #define IDS_SPIN 5 +#define IDS_KF_CLASS_NAME 6 #define IDD_PANEL 101 +#define IDD_NIF_PANEL 101 +#define IDD_KF_PANEL 102 #define IDC_CLOSEBUTTON 1000 #define IDC_DOSTUFF 1000 #define IDC_CHK_HIDDEN 1003 @@ -18,8 +22,10 @@ #define IDC_ED_WELDTHRESH 1008 #define IDC_LBL_WELDTHRESH 1009 #define IDC_CHK_COLL 1010 +#define IDC_ED_PRIORITY 1010 #define IDC_LBL_LINK 1011 #define IDC_CHK_VCOLORS 1012 +#define IDC_LBL_PRIORITY 1012 #define IDC_CHK_REMAP 1013 #define IDC_CB_GAME 1014 #define IDC_CB_VERSION 1015 @@ -36,6 +42,8 @@ #define IDC_CHK_CAMERA 1025 #define IDC_CHK_SKEL_ONLY2 1026 #define IDC_CHK_BONE_COLL 1026 +#define IDC_CHK_TRANSFORMS 1026 +#define IDC_EDIT1 1027 #define IDC_COLOR 1456 #define IDC_EDIT 1490 #define IDC_SPIN 1496 @@ -46,7 +54,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 102 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1025 +#define _APS_NEXT_CONTROL_VALUE 1028 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/NifFurniture/NifFurniture.rc b/NifFurniture/NifFurniture.rc index ce1e6e697d9b33904a342f40321a6c2190fb1e55..3c75f27838963c2b7681050ae1b370c57ee8180b 100755 --- a/NifFurniture/NifFurniture.rc +++ b/NifFurniture/NifFurniture.rc @@ -107,8 +107,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,3,0 - PRODUCTVERSION 0,2,3,0 + FILEVERSION 0,2,4,0 + PRODUCTVERSION 0,2,4,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -124,12 +124,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "3ds Max Nif Furniture Plugin" - VALUE "FileVersion", "0, 2, 3, 0" + VALUE "FileVersion", "0, 2, 4, 0" VALUE "InternalName", "NifFurniture.dlu" VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved." VALUE "OriginalFilename", "NifFurniture.dlu" VALUE "ProductName", "3ds Max Nif Furniture Plugin" - VALUE "ProductVersion", "0, 2, 3, 0" + VALUE "ProductVersion", "0, 2, 4, 0" END END BLOCK "VarFileInfo" diff --git a/NifImport/ImportAnimation.cpp b/NifImport/ImportAnimation.cpp index 72ee9f4f15dfe28230dc9ea07a190fde8caa44ad..58494607f163373e7991f65ffd03946a173b3287 100644 --- a/NifImport/ImportAnimation.cpp +++ b/NifImport/ImportAnimation.cpp @@ -18,6 +18,7 @@ HISTORY: #include "KFMImporter.h" #include "KFImporter.h" #include "AnimKey.h" +#include "NifPlugins.h" #include <obj/NiInterpolator.h> #include <obj/NiTransformInterpolator.h> #include <obj/NiTransformData.h> @@ -136,11 +137,20 @@ void NifImporter::ClearAnimation(INode *node) { if (node != NULL) { + if (node->HasNoteTracks()){ + for (int i = node->NumNoteTracks()-1; i>=0; --i ){ + if (NoteTrack *nt = node->GetNoteTrack(i)) + node->DeleteNoteTrack(nt, TRUE); + } + } node->DeleteKeys(TRACK_DOALL); ::ClearAnimation(node->GetTMController()); for (int i=0, n=node->NumberOfChildren(); i<n; ++i){ ClearAnimation(node->GetChildNode(i)); } + + // Clear animation priority + node->SetUserPropFloat(NP_ANM_PRI, 0.0f); } } void NifImporter::ClearAnimation() @@ -304,7 +314,48 @@ bool KFMImporter::ImportAnimation() if (addNoteTracks) { string target = cntr->GetTargetName(); if ( INode *n = gi->GetINodeByName(target.c_str()) ) { +#if 1 + DefNoteTrack* nt = (DefNoteTrack*)NewDefaultNoteTrack(); + n->AddNoteTrack(nt); + + for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) { + TimeValue t = TimeToFrame(time + (*itr).time); + + if (wildmatch("start*", (*itr).data)){ + stringlist args = TokenizeCommandLine((*itr).data.c_str(), true); + if (args.empty()) continue; + bool hasName = false; + bool hasLoop = false; + CycleType ct = cntr->GetCycleType(); + for (stringlist::iterator itr = args.begin(); itr != args.end(); ++itr) { + if (strmatch("-name", *itr)) { + if (++itr == args.end()) break; + hasName = true; + } else if (strmatch("-loop", *itr)) { + hasLoop = true; + } + } + if (!hasName) { + string name = cntr->GetName(); + if (name.empty()) + name = FormatString("EMPTY_SEQUENCE_AT_%df", int(t * FramesPerSecond / TicksPerFrame) ); + args.push_back("-name"); + args.push_back(name); + } + if (!hasLoop && ct == CYCLE_LOOP) { + args.push_back("-loop"); + } + string line = JoinCommandLine(args); + NoteKey *key = new NoteKey(t, line.c_str(), 0); + nt->keys.Append(1, &key); + } else { + NoteKey *key = new NoteKey(t, (*itr).data.c_str(), 0); + nt->keys.Append(1, &key); + } + } + +#else TSTR script; script += "fn getActorManager obj = (\n" @@ -326,7 +377,7 @@ bool KFMImporter::ImportAnimation() script += FormatText("nt = getActorManager $'%s'\n", target.c_str()); for (vector<StringKey>::iterator itr=textKeys.begin(); itr != textKeys.end(); ++itr) { - TimeValue t = TimeToFrame(time + (*itr).time) + 1; + TimeValue t = TimeToFrame(time + (*itr).time); if (wildmatch("start*", (*itr).data)){ stringlist args = TokenizeCommandLine((*itr).data.c_str(), true); @@ -363,6 +414,7 @@ bool KFMImporter::ImportAnimation() //nt->keys.Append(1, &key); } ExecuteMAXScriptScript(script, TRUE, NULL); +#endif } } @@ -396,6 +448,10 @@ bool KFMImporter::ImportAnimation() INode *n = gi->GetINodeByName(name.c_str()); + if ((*lnk).priority_ != 0.0f) { + npSetProp(n, NP_ANM_PRI, (*lnk).priority_); + } + NiKeyframeDataRef data; Point3 p; Quat q; float s; if (ai.GetTransformData(*lnk, name, data, p, q, s)) { diff --git a/NifImport/ImportSkeleton.cpp b/NifImport/ImportSkeleton.cpp index 0649cb40d39c33b5064beca07cf3f800906f4018..1d8cfc5b8a1372cd0837a187157bd81291883d25 100644 --- a/NifImport/ImportSkeleton.cpp +++ b/NifImport/ImportSkeleton.cpp @@ -686,6 +686,9 @@ void NifImporter::ImportBones(NiNodeRef node, bool recurse) bool NifImporter::ImportUPB(INode *node, Niflib::NiNodeRef block) { + if (!importUPB) + return false; + bool ok = false; if (node && block) { diff --git a/NifImport/MaxNifImport.cpp b/NifImport/MaxNifImport.cpp index dcb540767ea78219ba64fafb500572834903f57c..acd397005f135bb0bd5a350d78bd082cfcad9c5c 100644 --- a/NifImport/MaxNifImport.cpp +++ b/NifImport/MaxNifImport.cpp @@ -203,20 +203,16 @@ int MaxNifImport::DoImport(const TCHAR *filename,ImpInterface *i, Interface *gi, return FALSE; ok = importer.DoImport(); } + } + catch (exception &e) + { + MessageBox(NULL, e.what(), "Import Error", MB_OK); + return TRUE; } - catch( exception & e ) + catch (...) { - e=e; - ok = false; - } - catch( exception * e ) - { - e=e; - ok = false; - } - catch( ... ) - { - ok = false; + MessageBox(NULL, "Unknown error.", "Import Error", MB_OK); + return TRUE; } return ok ? TRUE : FALSE; } diff --git a/NifImport/MaxNifImport.rc b/NifImport/MaxNifImport.rc index 158f7c58ee899eb2a3b38a5d2ab1d138e54a3762..6ca19508c6329bf51f5241e622a9db3dd1ccbcda 100644 --- a/NifImport/MaxNifImport.rc +++ b/NifImport/MaxNifImport.rc @@ -36,27 +36,28 @@ BEGIN CONTROL "&Skeleton",IDC_CHK_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,16,67,10 CONTROL "S&kin Modifier",IDC_CHK_SKIN,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,27,67,10 CONTROL "Vertex &Colors",IDC_CHK_VCOLORS,"Button",BS_AUTO3STATE | WS_TABSTOP,14,38,67,10 - CONTROL "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,86,67,10 CONTROL "&Animation",IDC_CHK_ANIMATION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,50,67,10 + CONTROL "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,62,67,10 + CONTROL "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,74,67,10 + CONTROL "Co&llision",IDC_CHK_COLL,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,86,67,10 CONTROL "Furniture &Markers",IDC_CHK_FURN,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,14,97,67,10 - GROUPBOX "Behaviors:",IDC_STATIC,94,6,101,92 CONTROL "Flip U&V",IDC_CHK_FLIP_UV,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,16,88,10 CONTROL "&Render Textures in View",IDC_CHK_SHOW_TEX,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,27,88,10 CONTROL "Auto Sm&ooth Mesh",IDC_CHK_AUTOSMOOTH,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,38,88,11 CONTROL "Remove &Illegal Faces",IDC_CHK_ILLEGAL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,50,88,11 CONTROL "Remove &Unused Bones",IDC_CHK_REM_BONES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,62,88,10 - CONTROL "Use &Biped",IDC_CHK_BIPED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,102,84,87,10 + CONTROL "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,73,88,10 + CONTROL "Ignore User Prop Buffers",IDC_CHK_UPB,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,86,89,10 + GROUPBOX "Behaviors:",IDC_STATIC,94,6,101,105 + CONTROL "Use &Biped",IDC_CHK_BIPED,"Button",BS_AUTOCHECKBOX | WS_DISABLED | WS_TABSTOP,102,98,87,10 + LTEXT "Game:",IDC_STATIC,7,129,31,8 + COMBOBOX IDC_CB_GAME,47,127,131,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP LTEXT "Skeleton:",IDC_STC_SKELETON,7,143,31,8 EDITTEXT IDC_ED_SKELETON,7,155,171,12,ES_AUTOHSCROLL PUSHBUTTON "...",IDC_BTN_BROWSE,192,155,19,13 - LTEXT "Game:",IDC_STATIC,7,129,31,8 - COMBOBOX IDC_CB_GAME,47,127,131,70,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP DEFPUSHBUTTON "&Import",IDOK,5,172,34,14 PUSHBUTTON "&Cancel",IDCANCEL,45,172,33,14 LTEXT "http://www.niftools.org",IDC_LBL_LINK,93,172,95,14,SS_NOTIFY | SS_CENTERIMAGE - CONTROL "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,102,73,88,10 - CONTROL "&Lights",IDC_CHK_LIGHTS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,62,67,10 - CONTROL "Cameras",IDC_CHK_CAMERA,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,74,67,10 END IDD_KF_PANEL DIALOGEX 0, 0, 118, 99 @@ -66,12 +67,12 @@ CAPTION "Import KF" FONT 8, "MS Sans Serif", 0, 0, 0x1 BEGIN GROUPBOX "Import:",-1,7,6,104,51 - DEFPUSHBUTTON "&Import",IDOK,5,78,34,14 - PUSHBUTTON "&Cancel",IDCANCEL,45,78,33,14 - LTEXT "http://www.niftools.org",IDC_LBL_LINK,7,61,95,14,SS_NOTIFY | SS_CENTERIMAGE CONTROL "Clear Animation",IDC_CHK_CLEARANIM,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,72,10 CONTROL "Add Key Notes",IDC_CHK_KEYNOTES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,31,72,10 CONTROL "Add Time Tags",IDC_CHK_TIMETAGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,44,72,10 + LTEXT "http://www.niftools.org",IDC_LBL_LINK,7,61,95,14,SS_NOTIFY | SS_CENTERIMAGE + DEFPUSHBUTTON "&Import",IDOK,5,78,34,14 + PUSHBUTTON "&Cancel",IDCANCEL,45,78,33,14 END @@ -134,8 +135,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,3,0 - PRODUCTVERSION 0,2,3,0 + FILEVERSION 0,2,4,0 + PRODUCTVERSION 0,2,4,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -151,12 +152,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "3ds Max Nif Importer" - VALUE "FileVersion", "0, 2, 3, 0" + VALUE "FileVersion", "0, 2, 4, 0" VALUE "InternalName", "MaxNifImport.dli" VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved." VALUE "OriginalFilename", "MaxNifImport.dli" VALUE "ProductName", "3ds Max Nif Importer" - VALUE "ProductVersion", "0, 2, 3, 0" + VALUE "ProductVersion", "0, 2, 4, 0" END END BLOCK "VarFileInfo" @@ -175,7 +176,7 @@ STRINGTABLE BEGIN IDS_LIBDESCRIPTION "Importer for NIF files" IDS_CATEGORY "NifTools" - IDS_CLASS_NAME "MaxNifImport" + IDS_CLASS_NAME "Niftools_Nif_Importer" IDS_PARAMS "Parameters" IDS_SPIN "Spin" END diff --git a/NifImport/NIFImport.cpp b/NifImport/NIFImport.cpp index 001a36d737206f02b48ad30289abfc42ea93af89..cb52375cb6d692979d4ffa47116b8b558e91a5ee 100644 --- a/NifImport/NIFImport.cpp +++ b/NifImport/NIFImport.cpp @@ -147,6 +147,7 @@ void NifImporter::LoadIniSettings() vertexColorMode = GetIniValue<int>(NifImportSection, "VertexColorMode", 1); useCiv4Shader = GetIniValue(NifImportSection, "UseCiv4Shader", true); mergeNonAccum = GetIniValue(NifImportSection, "MergeNonAccum", true); + importUPB = GetIniValue(NifImportSection, "ImportUPB", true); // Biped importBones = GetIniValue(BipedImportSection, "ImportBones", true); @@ -210,6 +211,7 @@ void NifImporter::SaveIniSettings() SetIniValue(NifImportSection, "EnableAutoSmooth", enableAutoSmooth); SetIniValue(NifImportSection, "RemoveIllegalFaces", removeIllegalFaces); SetIniValue(NifImportSection, "RemoveDegenerateFaces", removeDegenerateFaces); + SetIniValue(NifImportSection, "ImportUPB", importUPB); SetIniValue(BipedImportSection, "ImportBones", importBones); SetIniValue(BipedImportSection, "RemoveUnusedImportedBones", removeUnusedImportedBones); diff --git a/NifImport/NIFImporter.h b/NifImport/NIFImporter.h index 087328b405962b56044304fa2905b90f7e6ffe0d..6d472028309dade4451d3ae70617d89c9130bb44 100644 --- a/NifImport/NIFImporter.h +++ b/NifImport/NIFImporter.h @@ -36,6 +36,7 @@ public: bool mergeNonAccum; bool enableLights; bool enableCameras; + bool importUPB; // Biped/Bones related settings bool importBones; diff --git a/NifImport/NifDialog.cpp b/NifImport/NifDialog.cpp index 2bf1152e9a8236f6b3e98b3fbbbe754e181f666c..4a36f8779db996420c8327b8c413b6a0ce578117 100644 --- a/NifImport/NifDialog.cpp +++ b/NifImport/NifDialog.cpp @@ -57,6 +57,8 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP CheckDlgButton(hWnd, IDC_CHK_CLEARANIM, imp->clearAnimation); CheckDlgButton(hWnd, IDC_CHK_BIPED, imp->useBiped); + CheckDlgButton(hWnd, IDC_CHK_UPB, !imp->importUPB); + string selection = (imp->appSettings) ? imp->appSettings->Name : "User"; for (AppSettingsMap::iterator itr = TheAppSettings.begin(), end = TheAppSettings.end(); itr != end; ++itr) @@ -108,6 +110,7 @@ static BOOL CALLBACK MaxNifImportOptionsDlgProc(HWND hWnd,UINT message,WPARAM wP imp->removeUnusedImportedBones = IsDlgButtonChecked(hWnd, IDC_CHK_REM_BONES) ? true : false; imp->clearAnimation = IsDlgButtonChecked(hWnd, IDC_CHK_CLEARANIM) ? true : false; imp->useBiped = IsDlgButtonChecked(hWnd, IDC_CHK_BIPED) ? true : false; + imp->importUPB = IsDlgButtonChecked(hWnd, IDC_CHK_UPB) ? false : true; GetDlgItemText(hWnd, IDC_CB_GAME, tmp, MAX_PATH); if (AppSettings *appSettings = FindAppSetting(tmp)) { diff --git a/NifImport/resource.h b/NifImport/resource.h index a608a761e71fb321548495c9ddbdc68b35d7be4e..22c9238e83a9422022be341a1ddf40d92b7d6bbf 100644 --- a/NifImport/resource.h +++ b/NifImport/resource.h @@ -21,6 +21,7 @@ #define IDC_ED_SKELETON 1006 #define IDC_CHK_BIPED 1007 #define IDC_CHK_LIGHTS 1008 +#define IDC_CHK_UPB 1009 #define IDC_CHK_COLL 1010 #define IDC_LBL_LINK 1011 #define IDC_CHK_VCOLORS 1012 diff --git a/NifProps/NifProps.cpp b/NifProps/NifProps.cpp index 62b11aea08c3b295390abf2a3a8fa12858168ddf..af0afb2cf8e9060d7e581a3317a4c14e9043aaa1 100755 --- a/NifProps/NifProps.cpp +++ b/NifProps/NifProps.cpp @@ -27,11 +27,13 @@ public: void selectionChanged(); - BOOL dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + BOOL dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + BOOL dlgAnimProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); private: - HWND mPanel; + HWND mPanel; + HWND mAnimPanel; IUtil *mIU; Interface *mIP; INode *mNode; @@ -44,7 +46,7 @@ private: NpComboBox mCbMotionSystem; NpComboBox mCbQualityType; - void enableGUI(BOOL object, BOOL hvk); + void enableGUI(BOOL object, BOOL hvk, BOOL anim); }; static NifProps plugin; @@ -74,7 +76,12 @@ ClassDesc2* GetNifPropsDesc() { return &NifPropsDesc; } static BOOL CALLBACK NifPropsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { - return plugin.dlgProc(hWnd, msg, wParam, lParam); + return plugin.dlgProc(hWnd, msg, wParam, lParam); +} + +static BOOL CALLBACK NifAnimPropsDlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + return plugin.dlgAnimProc(hWnd, msg, wParam, lParam); } @@ -86,6 +93,7 @@ NifProps::NifProps() mIU = NULL; mIP = NULL; mPanel = NULL; + mAnimPanel = NULL; } NifProps::~NifProps() @@ -163,6 +171,17 @@ void NifProps::BeginEditParams(Interface *ip, IUtil *iu) str++; } + + //mAnimPanel = ip->AddRollupPage( + // hInstance, + // MAKEINTRESOURCE(IDD_ANIM_PANEL), + // NifAnimPropsDlgProc, + // GetString(IDS_ANIM_PARAMS), + // 0); + + mSpins[IDC_SP_ANIM_PRIORITY] = + SetupFloatSpinner(mPanel, IDC_SP_ANIM_PRIORITY, IDC_ED_ANIM_PRIORITY, 0, 255, 25, .1f); + selectionChanged(); } @@ -179,7 +198,7 @@ void NifProps::EndEditParams(Interface *ip,IUtil *iu) mNode = NULL; } -void NifProps::enableGUI(BOOL obj, BOOL hvk) +void NifProps::enableGUI(BOOL obj, BOOL hvk, BOOL anim) { EnableWindow(GetDlgItem(mPanel, IDC_GRP_OBJECT), obj); EnableWindow(GetDlgItem(mPanel, IDC_CHK_ISCOLL), obj); @@ -190,8 +209,11 @@ void NifProps::enableGUI(BOOL obj, BOOL hvk) EnableWindow(GetDlgItem(mPanel, IDC_LBL_LAYER), hvk); EnableWindow(GetDlgItem(mPanel, IDC_CB_LAYER), hvk); */ - for (int i=IDC_HVK_BEGIN; i<=IDC_HVK_END; i++) - EnableWindow(GetDlgItem(mPanel, i), hvk); + for (int i=IDC_HVK_BEGIN; i<=IDC_HVK_END; i++) + EnableWindow(GetDlgItem(mPanel, i), hvk); + + for (int i=IDC_ANIM_BEGIN; i<=IDC_ANIM_END; i++) + EnableWindow(GetDlgItem(mPanel, i), anim); } void NifProps::SelectionSetChanged(Interface *ip, IUtil *iu) @@ -205,7 +227,7 @@ void NifProps::selectionChanged() if (numSel <= 0) { mNode = NULL; - enableGUI(false, false); + enableGUI(false, false, false); return; } @@ -213,7 +235,7 @@ void NifProps::selectionChanged() INode *nodeSel = mIP->GetSelNode(0); bool isColl = npIsCollision(nodeSel); - enableGUI(singleSel, singleSel && isColl); + enableGUI(singleSel, singleSel && isColl, true); mNode = singleSel?nodeSel:NULL; if (!singleSel) @@ -262,6 +284,9 @@ void NifProps::selectionChanged() mSpins[IDC_SP_MAX_LINEAR_VELOCITY]->SetValue(maxlinvel, TRUE); mSpins[IDC_SP_MAX_ANGULAR_VELOCITY]->SetValue(maxangvel, TRUE); + float priority; + npGetProp(nodeSel, NP_ANM_PRI, priority, NP_DEFAULT_ANM_PRI); + mSpins[IDC_SP_ANIM_PRIORITY]->SetValue(priority, TRUE); } @@ -383,6 +408,12 @@ BOOL NifProps::dlgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case IDC_SP_PENETRATION_DEPTH: npSetProp(mNode, NP_HVK_PENETRATION_DEPTH, mSpins[IDC_SP_PENETRATION_DEPTH]->GetFVal()); break; + + case IDC_SP_ANIM_PRIORITY: + for (int i=0, n=mIP->GetSelNodeCount(); i<n; ++i) { + npSetProp(mIP->GetSelNode(i), NP_ANM_PRI, mSpins[IDC_SP_ANIM_PRIORITY]->GetFVal()); + } + break; } break; diff --git a/NifProps/NifProps.rc b/NifProps/NifProps.rc index a070ca4e46c5465c23f6c4656e710f9099771d4c..68b5abcad3841198bf8997669839975917c566ce 100755 --- a/NifProps/NifProps.rc +++ b/NifProps/NifProps.rc @@ -73,7 +73,7 @@ END // Dialog // -IDD_PANEL DIALOGEX 0, 0, 107, 401 +IDD_PANEL DIALOGEX 0, 0, 107, 360 STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_VISIBLE FONT 8, "MS Sans Serif", 0, 0, 0x0 BEGIN @@ -84,11 +84,6 @@ BEGIN GROUPBOX "Havok",IDC_GRP_HAVOK,5,39,95,285,WS_DISABLED GROUPBOX "Object",IDC_GRP_OBJECT,5,5,95,32 CONTROL "Is Collision Mesh",IDC_CHK_ISCOLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,14,18,80,10 - GROUPBOX "Global",IDC_STATIC,5,329,95,65,WS_DISABLED - EDITTEXT IDC_ED_BSXFLAGS,13,352,80,12,ES_AUTOHSCROLL | WS_DISABLED - CONTROL "BSXFlags",IDC_LBL_BSXFLAGS,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,13,340,80,8 - EDITTEXT IDC_ED_STRINGSEXTRA,13,374,80,12,ES_AUTOHSCROLL | WS_DISABLED - CONTROL "Strings Extra Data",IDC_LBL_STRINGSEXTRA,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,13,365,80,8 CONTROL "Center",IDC_LBL_CENTER,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | WS_DISABLED | WS_GROUP,12,98,31,8 CONTROL "Mass",IDC_LBL_MASS,"Static",SS_LEFTNOWORDWRAP | WS_DISABLED | WS_GROUP,12,124,28,8 CONTROL "Friction",IDC_LBL_FRICTION,"Static",SS_LEFTNOWORDWRAP | WS_DISABLED | WS_GROUP,42,124,28,8 @@ -124,6 +119,20 @@ BEGIN LTEXT "Penetration\r\nDepth",IDC_LBL_PENETRATION_DEPTH,12,229,40,16,WS_DISABLED CONTROL "",IDC_ED_PENETRATION_DEPTH,"CustEdit",WS_DISABLED | WS_TABSTOP,12,249,35,10 CONTROL "",IDC_SP_PENETRATION_DEPTH,"SpinnerControl",WS_DISABLED,45,249,7,10 + GROUPBOX "Animation",IDC_GRP_ANIMATION,7,325,95,28 + LTEXT "Priority:",IDC_STATIC,10,338,24,8 + CONTROL "",IDC_ED_ANIM_PRIORITY,"CustEdit",WS_DISABLED | WS_TABSTOP,39,337,20,10 + CONTROL "",IDC_SP_ANIM_PRIORITY,"SpinnerControl",WS_DISABLED,57,337,7,10 +END + +IDD_ANIM_PANEL DIALOGEX 0, 0, 107, 41 +STYLE DS_SETFONT | DS_3DLOOK | WS_CHILD | WS_VISIBLE +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + GROUPBOX "Animation",IDC_GRP_ANIMATION,5,5,95,28 + LTEXT "Priority:",IDC_STATIC,8,18,24,8 + CONTROL "",IDC_ED_ANIM_PRIORITY,"CustEdit",WS_DISABLED | WS_TABSTOP,37,17,20,10 + CONTROL "",IDC_SP_ANIM_PRIORITY,"SpinnerControl",WS_DISABLED,55,17,7,10 END @@ -140,7 +149,15 @@ BEGIN LEFTMARGIN, 7 RIGHTMARGIN, 100 TOPMARGIN, 7 - BOTTOMMARGIN, 394 + BOTTOMMARGIN, 353 + END + + IDD_ANIM_PANEL, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 100 + TOPMARGIN, 7 + BOTTOMMARGIN, 34 END END #endif // APSTUDIO_INVOKED @@ -342,8 +359,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,2,3,0 - PRODUCTVERSION 0,2,3,0 + FILEVERSION 0,2,4,0 + PRODUCTVERSION 0,2,4,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -359,12 +376,12 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "3ds Max Nif Reactor Properites Plugin" - VALUE "FileVersion", "0, 2, 3, 0" + VALUE "FileVersion", "0, 2, 4, 0" VALUE "InternalName", "NifProps.dlu" VALUE "LegalCopyright", "Copyright (c) 2006, NIF File Format Library and Tools\r\nAll rights reserved." VALUE "OriginalFilename", "NifProps.dlu" VALUE "ProductName", "3ds Max Nif Reactor Properites Plugin" - VALUE "ProductVersion", "0, 2, 3, 0" + VALUE "ProductVersion", "0, 2, 4, 0" END END BLOCK "VarFileInfo" @@ -386,6 +403,7 @@ BEGIN IDS_CLASS_NAME "NifProps" IDS_PARAMS "Parameters" IDS_SPIN "Spin" + IDS_ANIM_PARAMS "Animation" END #endif // English (U.S.) resources diff --git a/NifProps/resource.h b/NifProps/resource.h index d9cfbe897a9e3257b4e93d0b1f030f2e5afe385b..fc3cc8a3db05d5889094b7265ef816acfa5bd0d6 100755 --- a/NifProps/resource.h +++ b/NifProps/resource.h @@ -7,15 +7,17 @@ #define IDS_CLASS_NAME 3 #define IDS_PARAMS 4 #define IDS_SPIN 5 +#define IDS_ANIM_PARAMS 6 #define IDD_PANEL 101 -#define IDC_LBL_BSXFLAGS 1001 -#define IDC_ED_BSXFLAGS 1002 -#define IDC_ED_STRINGSEXTRA 1003 -#define IDC_LBL_STRINGSEXTRA 1004 +#define IDD_ANIM_PANEL 102 +#define IDC_LBL_BSXFLAGS 1001 +#define IDC_ED_BSXFLAGS 1002 +#define IDC_ED_STRINGSEXTRA 1003 +#define IDC_LBL_STRINGSEXTRA 1004 #define IDC_GRP_OBJECT 1005 #define IDC_CHK_ISCOLL 1006 #define IDC_GRP_HAVOK 1007 -#define IDC_HVK_BEGIN IDC_GRP_HAVOK +#define IDC_HVK_BEGIN 1007 #define IDC_LBL_MATERIAL 1008 #define IDC_CB_MATERIAL 1009 #define IDC_LBL_LAYER 1010 @@ -51,11 +53,16 @@ #define IDC_LBL_ANGULAR_DAMPING 1517 #define IDC_ED_ANGULAR_DAMPING 1518 #define IDC_SP_ANGULAR_DAMPING 1519 -#define IDC_LBL_MOTION_SYSTEM 1520 -#define IDC_CB_MOTION_SYSTEM 1521 -#define IDC_LBL_QUALITY_TYPE 1522 -#define IDC_CB_QUALITY_TYPE 1523 -#define IDC_HVK_END IDC_CB_QUALITY_TYPE +#define IDC_LBL_MOTION_SYSTEM 1520 +#define IDC_CB_MOTION_SYSTEM 1521 +#define IDC_LBL_QUALITY_TYPE 1522 +#define IDC_CB_QUALITY_TYPE 1523 +#define IDC_HVK_END 1523 +#define IDC_ANIM_BEGIN 1600 +#define IDC_GRP_ANIMATION 1600 +#define IDC_ED_ANIM_PRIORITY 1601 +#define IDC_SP_ANIM_PRIORITY 1602 +#define IDC_ANIM_END 1602 // Next default values for new objects // @@ -63,7 +70,7 @@ #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 103 #define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1035 +#define _APS_NEXT_CONTROL_VALUE 1700 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif