|
|
|
/*==LICENSE==*
|
|
|
|
|
|
|
|
CyanWorlds.com Engine - MMOG client, server and tools
|
|
|
|
Copyright (C) 2011 Cyan Worlds, Inc.
|
|
|
|
|
|
|
|
This program is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
|
|
|
or by snail mail at:
|
|
|
|
Cyan Worlds, Inc.
|
|
|
|
14617 N Newport Hwy
|
|
|
|
Mead, WA 99021
|
|
|
|
|
|
|
|
*==LICENSE==*/
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// //
|
|
|
|
// plAnimStealthNode - Stealthy hidden INode that represents a single //
|
|
|
|
// segment's worth of animation info for a material. //
|
|
|
|
// Stored as an INode so they can be "selected" //
|
|
|
|
// by components as targets of animation messages. //
|
|
|
|
// //
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#ifndef _plAnimStealthNode_h
|
|
|
|
#define _plAnimStealthNode_h
|
|
|
|
|
|
|
|
#include "Max.h"
|
|
|
|
#include "iparamb2.h"
|
|
|
|
#include "iparamm2.h"
|
|
|
|
|
|
|
|
#include "hsTypes.h"
|
|
|
|
#include "../pnKeyedObject/plKey.h"
|
|
|
|
#include "../MaxComponent/plAnimObjInterface.h"
|
|
|
|
#include "../MaxComponent/plMaxAnimUtils.h"
|
|
|
|
|
|
|
|
extern TCHAR *GetString(int id);
|
|
|
|
extern HINSTANCE hInstance;
|
|
|
|
|
|
|
|
#define ANIMSTEALTH_CLASSID Class_ID(0xd0272f8, 0x750349c9)
|
|
|
|
|
|
|
|
#define REFMSG_NOTETRACK_ADDED REFMSG_USER + 1
|
|
|
|
|
|
|
|
class plPassMtlBase;
|
|
|
|
class NoteTrack;
|
|
|
|
class plMaxNode;
|
|
|
|
class plErrorMsg;
|
|
|
|
class plAnimTimeConvert;
|
|
|
|
|
|
|
|
//// Class Def ///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class plAnimStealthNode : public HelperObject, public plAnimObjInterface
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
ClassDesc2 *fClassDesc;
|
|
|
|
|
|
|
|
IParamBlock2 *fParamBlock;
|
|
|
|
plPassMtlBase *fParentMtl;
|
|
|
|
|
|
|
|
static ParamBlockDesc2 sAnimStealthPB;
|
|
|
|
|
|
|
|
hsBool fPreppedForConvert;
|
|
|
|
SegmentMap *fCachedSegMap;
|
|
|
|
|
|
|
|
SegmentSpec *IGetSegmentSpec( void ) const;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
// Some IDs
|
|
|
|
enum
|
|
|
|
{
|
|
|
|
kBlockPB = 0
|
|
|
|
};
|
|
|
|
|
|
|
|
enum Refs
|
|
|
|
{
|
|
|
|
kRefParamBlock,
|
|
|
|
kRefParentMtl
|
|
|
|
};
|
|
|
|
// ParamBlock IDs
|
|
|
|
enum ParamBlockIDs
|
|
|
|
{
|
|
|
|
kPBAutoStart, // Start the Animation on load (V2)
|
|
|
|
kPBLoop, // Start Looping at Begin Location
|
|
|
|
kPBName, // Name of the notetrack animation to play
|
|
|
|
kPBLoopName, // Name of the notetrack specified loop
|
|
|
|
kPBEaseInType,
|
|
|
|
kPBEaseOutType,
|
|
|
|
kPBEaseInLength,
|
|
|
|
kPBEaseOutLength,
|
|
|
|
kPBEaseInMin,
|
|
|
|
kPBEaseInMax,
|
|
|
|
kPBEaseOutMin,
|
|
|
|
kPBEaseOutMax
|
|
|
|
};
|
|
|
|
|
|
|
|
plAnimStealthNode( BOOL loading );
|
|
|
|
virtual ~plAnimStealthNode();
|
|
|
|
void DeleteThis() { delete this; }
|
|
|
|
|
|
|
|
INode *GetINode( void );
|
|
|
|
plPassMtlBase *GetParentMtl( void );
|
|
|
|
void SetParentMtl( plPassMtlBase *parent );
|
|
|
|
void SetNodeName( const char *parentName );
|
|
|
|
|
|
|
|
// Create the dialog for this object and place it inside the given dialog, centering it in the given control if any
|
|
|
|
bool CreateAndEmbedDlg( IParamMap2 *parentMap, IMtlParams *parentParams, HWND frameCtrl = nil );
|
|
|
|
|
|
|
|
// Release said dialog
|
|
|
|
void ReleaseDlg( void );
|
|
|
|
|
|
|
|
// Switch underlying objects in the dialog (to avoid unnecessary deletion/recreations)
|
|
|
|
void SwitchDlg( plAnimStealthNode *toSwitchTo );
|
|
|
|
|
|
|
|
// Get the actual window handle of the currently active dialog displaying us
|
|
|
|
HWND GetWinDlg( void ) const;
|
|
|
|
|
|
|
|
// Interesting functions
|
|
|
|
const char *GetSegmentName( void ) const;
|
|
|
|
void SetSegment( const char *name ); // nil for "entire animation"
|
|
|
|
|
|
|
|
// Conversion from stealth's INode to the actual object
|
|
|
|
static bool CanConvertToStealth( INode *objNode );
|
|
|
|
static plAnimStealthNode *ConvertToStealth( INode *objNode );
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Required Max functions
|
|
|
|
//
|
|
|
|
TCHAR* GetObjectName() { return (TCHAR*)fClassDesc->ClassName(); }
|
|
|
|
void InitNodeName(TSTR& s) { s = fClassDesc->InternalName(); }
|
|
|
|
void GetClassName(TSTR& s) { s = fClassDesc->ClassName(); }
|
|
|
|
Class_ID ClassID() { return ANIMSTEALTH_CLASSID; }
|
|
|
|
|
|
|
|
RefTargetHandle Clone(RemapDir &remap);
|
|
|
|
|
|
|
|
int NumRefs();
|
|
|
|
RefTargetHandle GetReference(int i);
|
|
|
|
void SetReference(int i, RefTargetHandle rtarg);
|
|
|
|
RefResult NotifyRefChanged(Interval changeInt,RefTargetHandle hTarget, PartID& partID, RefMessage message);
|
|
|
|
|
|
|
|
// allow retreival of our paramblock from other plug-ins
|
|
|
|
// and the max core
|
|
|
|
int NumParamBlocks();
|
|
|
|
IParamBlock2* GetParamBlock(int i);
|
|
|
|
IParamBlock2* GetParamBlockByID(BlockID id);
|
|
|
|
|
|
|
|
// We override because we don't want to be able to animate this sucker
|
|
|
|
int NumSubs() { return 0; }
|
|
|
|
Animatable *SubAnim( int i ) { return nil; }
|
|
|
|
TSTR SubAnimName( int i ) { return fClassDesc->ClassName(); }
|
|
|
|
|
|
|
|
// plug-in mouse creation callback
|
|
|
|
CreateMouseCallBack* GetCreateMouseCallBack();
|
|
|
|
|
|
|
|
void BeginEditParams(IObjParam *ip, ULONG flags, Animatable *prev);
|
|
|
|
void EndEditParams(IObjParam *ip, ULONG flags, Animatable *next);
|
|
|
|
// void SelectionSetChanged(Interface *ip, IUtil *iu);
|
|
|
|
|
|
|
|
void BuildMesh(TimeValue t);
|
|
|
|
void FreeCaches();
|
|
|
|
void GetLocalBoundBox(TimeValue t, INode *node, ViewExp *vpt, Box3 &box);
|
|
|
|
void GetWorldBoundBox(TimeValue t, INode *node, ViewExp *vpt, Box3 &box);
|
|
|
|
int Display(TimeValue t, INode *node, ViewExp *vpt, int flags);
|
|
|
|
int HitTest(TimeValue t, INode *node, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt);
|
|
|
|
ObjectState Eval(TimeValue t) { return ObjectState(this); }
|
|
|
|
|
|
|
|
IOResult Save(ISave* isave);
|
|
|
|
IOResult Load(ILoad* iload);
|
|
|
|
|
|
|
|
int CanConvertToType( Class_ID obtype ) { return ( obtype == ANIMSTEALTH_CLASSID ) ? 1 : 0; }
|
|
|
|
|
|
|
|
const char *GetCategory() { return fClassDesc->Category(); }
|
|
|
|
|
|
|
|
/// Parameter access
|
|
|
|
|
|
|
|
bool GetAutoStart( void ) const;
|
|
|
|
void SetAutoStart( bool b );
|
|
|
|
|
|
|
|
bool GetLoop( void ) const;
|
|
|
|
const char *GetLoopName( void ) const;
|
|
|
|
void SetLoop( bool b, const char *name );
|
|
|
|
|
|
|
|
UInt8 GetEaseInType( void ) const;
|
|
|
|
hsScalar GetEaseInLength( void ) const;
|
|
|
|
hsScalar GetEaseInMin( void ) const;
|
|
|
|
hsScalar GetEaseInMax( void ) const;
|
|
|
|
void SetEaseIn( UInt8 type, hsScalar length, hsScalar min, hsScalar max );
|
|
|
|
|
|
|
|
UInt8 GetEaseOutType( void ) const;
|
|
|
|
hsScalar GetEaseOutLength( void ) const;
|
|
|
|
hsScalar GetEaseOutMin( void ) const;
|
|
|
|
hsScalar GetEaseOutMax( void ) const;
|
|
|
|
void SetEaseOut( UInt8 type, hsScalar length, hsScalar min, hsScalar max );
|
|
|
|
|
|
|
|
// Conversion stuff
|
|
|
|
void GetAllStopPoints( hsTArray<hsScalar> &out );
|
|
|
|
hsScalar GetSegStart( void ) const;
|
|
|
|
hsScalar GetSegEnd( void ) const;
|
|
|
|
void GetLoopPoints( hsScalar &start, hsScalar &end ) const;
|
|
|
|
void StuffToTimeConvert( plAnimTimeConvert &convert, hsScalar maxLength );
|
|
|
|
|
|
|
|
// plAnimObjInterface functions
|
|
|
|
virtual void PickTargetNode( IParamBlock2 *destPB, ParamID destParamID, ParamID typeID );
|
|
|
|
virtual hsBool IsNodeRestricted( void ) { return true; }
|
|
|
|
virtual const char *GetIfaceSegmentName( hsBool allowNil );
|
|
|
|
virtual hsBool GetKeyList( INode *restrictedNode, hsTArray<plKey> &outKeys );
|
|
|
|
virtual hsBool MightRequireSeparateMaterial( void ) { return true; }
|
|
|
|
|
|
|
|
// Convert time, called on the setupProps pass for each material applied to a node in the scene
|
|
|
|
virtual hsBool SetupProperties( plMaxNode *node, plErrorMsg *pErrMsg );
|
|
|
|
virtual hsBool ConvertDeInit( plMaxNode *node, plErrorMsg *pErrMsg );
|
|
|
|
|
|
|
|
// Returns true if the parent material is applied to any node in the scene, false otherwise
|
|
|
|
hsBool IsParentUsedInScene( void );
|
|
|
|
};
|
|
|
|
|
|
|
|
//// Accessor for Parent's ParamBlock ////////////////////////////////////////
|
|
|
|
|
|
|
|
class plStealthNodeAccessor : public PBAccessor
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
|
|
|
|
void ISetParent( ReferenceTarget *target, plPassMtlBase *parent );
|
|
|
|
|
|
|
|
void IHandleSet( PB2Value &v, ReferenceMaker *owner, ParamID id, int tabIndex, TimeValue t );
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
plStealthNodeAccessor() { }
|
|
|
|
static plStealthNodeAccessor &GetInstance( void );
|
|
|
|
|
|
|
|
virtual void Set( PB2Value &v, ReferenceMaker *owner, ParamID id, int tabIndex, TimeValue t );
|
|
|
|
virtual void TabChanged( tab_changes changeCode, Tab<PB2Value> *tab, ReferenceMaker *owner,
|
|
|
|
ParamID id, int tabIndex, int count );
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif //_plAnimStealthNode_h
|