2017-04-17 06:17:10 -06:00

449 lines
17 KiB
C++
Executable File

/*********************************************************************
*<
FILE: bipedapi.h
DESCRIPTION: Biped motion flow interface classes
CREATED BY: Ravi Karra, Michael Zyracki
HISTORY: Created 18 October 1999
*> Copyright (c) 1999-2003 All Rights Reserved.
**********************************************************************/
#ifndef __IMOFLOW__
#define __IMOFLOW__
#include "BipExp.h"
#include "keytrack.h"
/*
Using the Motion Flow classes.
1. You need to make sure you are linking with the biped.lib import library. This is only currently necessary
for linking with these motion flow clases. If you are just using the interface in BipedApi.h,there is no
need to link with this import library.
2. Get the IMoFlow Interface from a corresponding BipMaster.
3. The general MotionFlow class hierarcy.
A. Each Motion Flow consists of a collection of Snippets(stored animation clips) and Scripts(instances
of the Snippets strung together.).
B. Each Snippet Contains an animation (a .bip file), and a collection of Transistions.
C. Each Transistion specifies an one way motion blend from one snippet to another.
D. Each Script in the IMoFlow is a set of animations(snippets), which are contains a list of ScriptItem's.
E. Each ScriptItem contains a pointer back to the Snippet it instances.
NOTE that there is a close correspondence between these SDK classes and functions and the CS motion
flow maxscript implementation, so that may be used as reference for this SDK also.
NOTE That these classes contain internal biped classes. These classes are the actually ones used
internally, they aren't interfaces.
Example of creating a motion flow.
IBipMaster *bipMaster = GetCurrentBipMaster(); //see
POINT graphLocation;
char str[32];
//begin motion flow mode.
bipMaster->BeginModes(BMODE_MOTIONFLOW);
//get the motion flow
IMoFlow *moFlow = bipMaster->GetMoFlow();
//create a walk snippet
sprintf(str,"c:\\Sumo\\walk.bip"); //the file for the snippert
graphLocation.x = 20;
graphLocation.y = 10;
Snippet *walk = moFlow->NewSnippet(str, graphLocation,true,true);
//create a run snippet
sprintf(str,"c:\\Sumo\\run.bip"); //the file for the snippert
graphLocation.x = 50;
graphLocation.y = 10;
Snippet *run = moFlow->NewSnippet(str, graphLocation,true,true);
//create an optimized transistion between the 2 snippets.
walk->AddTransition(run,TRUE);
run->AddTransition(walk,TRUE);
//call this global function to make sure all graphs and moflows are updated.
UpdateMotionFlowGraph();
//create a script and set it to be active
sprintf(str,"SDK Script");
moFlow->AddScript(str,true);
//get the script
Script *script = moFlow->GetActiveScript();
//set the start pos and direction
Point3 startPos(0,0,0);
script->SetStartPos(startPos);
script->SetStartRot(0); //set a 0 heading degree
//create the snipped
script->AddSnippet(run);
moFlow->CurscriptToActiveLinks(); //set the transistions in the script
script->AddSnippet(walk);
moFlow->CurscriptToActiveLinks(); //set the transistions in the script
script->AddSnippet(run);
moFlow->CurscriptToActiveLinks(); //set the transistions in the script
//now compute the animation.
moFlow->ComputeAnimation(TRUE);
//end the motion flow mode
//unify the motion(convert the motion to free form)
bipMaster->UnifyMotion()
bipMaster->EndModes(BMODE_MOTIONFLOW);
return;
*/
// Forward Declarations--note that there are certain classes here (class BipMaster, class animal, etc..)
// which are internal classes.
class Snippet;
class MoFlow;
//Internal classes
class BipMaster;
class Transition;
class MFL_IOProcessor;
class animal;
class Layer;
class path_properties;
class crowd_script;
//string length defines
#define MAXNAME 280
#define MAXSCRIPTNAME 64
#define MAXTRANNOTE 256
// transition focus types
#define FOCUS_AUTO 0
#define FOCUS_COM 1
#define FOCUS_LFOOT 2
#define FOCUS_RFOOT 3
#define FOCUS_BFEET 4
//The Transistion Info. Each transistion contains an array of traninfos.
class TranInfo {
public:
//data
int start1,start2,length; //source and dest start, and length
int rolling1,rolling2,randpct;
int transFocus;
float angle,easein,easeout,cost;
float flow_angle;
path_properties prop;
TCHAR note[MAXTRANNOTE];
BIPExport TranInfo();
BIPExport TranInfo& operator=(const TranInfo& TI);
BIPExport int operator==(const TranInfo& TI);
//internal I/O functions
void Output(MFL_IOProcessor *IOProc);
void Input(MFL_IOProcessor *IOProc);
inline int GetSourceStart() const { return start1; }
inline void SetSourceStart(int s) { start1 = s; }
inline int GetDestStart() const { return start2; }
inline void SetDestStart(int s) { start2 = s; }
inline int GetSourceState() const { return rolling1; }
inline void SetSourceState(int s) { rolling1 = s; }
inline int GetDestState() const { return rolling2; }
inline void SetDestState(int s) { rolling2 = s; }
inline int GetLength() const { return length; }
inline void SetLength(int l) { length = l; }
inline float GetAngle() const { return angle; }
inline void SetAngle(float a) { angle = a; }
inline int GetRandPercent() const { return randpct; }
inline void SetRandPercent(float r) { randpct = r; }
inline float GetCost() const { return cost; }
inline void SetCost(float c) { cost = c; }
inline float GetEaseIn() const { return easein; }
inline void SetEaseIn(float in) { easein = in; }
inline float GetEaseOut() const { return easeout; }
inline void SetEaseOut(float out) { easeout = out; }
inline int GetTransFocus() const { return transFocus; }
inline void SetTransFocus(int t) { transFocus = t; }
inline const TCHAR* GetNote() const { return note; }
inline void SetNote(const TCHAR* n) { _tcscpy(note, n); }
};
class Transition {
public:
Snippet *from;
Snippet *to;
int active;
int selected;
int start1,start2,length;
int rolling1,rolling2;
float easein,easeout;
float angle;
float flow_angle;
int transFocus;
path_properties prop;
int randpct;
float cost;
int index;
int nTransInfo;
int maxTransInfo;
TranInfo *TranList;
TCHAR note[MAXTRANNOTE];
HWND hwnd;
BIPExport Transition();
BIPExport ~Transition();
BIPExport Transition& operator=(const Transition& T);
BIPExport void SetTranListSize(int NUM);
BIPExport void InfoToTransition(int i);
BIPExport void TransitionToInfo(int i);
BIPExport int NewTranInfo(); // returns the index of the inserted item
BIPExport void ShiftTranInfo(int TIindex, int storecurrent);
BIPExport void DeleteTranInfo(int TIindex);
void Output(MFL_IOProcessor *IOProc);
void Input(MFL_IOProcessor *IOProc);
inline int GetRandPercent() const { return randpct; }
inline void SetRandPercent(float r) { randpct = r; }
inline float GetCost() const { return cost; }
inline void SetCost(float c) { cost = c; }
inline int GetTranListSize() const { return nTransInfo; }
inline Snippet* GetFromSnippet() const { return from; }
inline void SetFromSnippet(Snippet* s) { from = s; }
inline Snippet* GetToSnippet() const { return to; }
inline void SetToSnippet(Snippet* s){ to = s; }
inline BOOL GetActive() const { return active; }
inline void SetActive(BOOL act) { active = act; }
inline BOOL GetSelected() const { return selected; }
inline void SetSelected(BOOL sel) { selected = sel; }
inline TranInfo GetTranInfo(int TIindex) const
{ assert (TIindex < nTransInfo); return TranList[TIindex]; }
inline void SetTranInfo(int TIindex, TranInfo ti) {
assert (TIindex < nTransInfo);
TranList[TIindex] = ti;
if (index == TIindex ) InfoToTransition(index);
}
BIPExport void UpdateUI(bool redraw=false);
};
class Script;
class Snippet {
public:
int visited; //used for depth first tranversal
float distance_to_stop;
float distance_to_loop;
int start;
int end;
TCHAR sname[MAXNAME];
TCHAR fname[MAXNAME];
int posx;
int posy;
int width;
int nTrans;
int curtime; // set anytime you compute A for a particular frame (necessary for looping)
int active;
int validload; // currently loaded file, although possibly inactive, is still valid (or not)
BOOL randstart; // can this snippet start a random traversal script
int randstartpct; // percentage of time this snippet starts a random traversal script
Transition *Transitions;
HWND hwnd;
int orgposx; // for interaction - post-fido
int orgposy; // for interaction - post-fido
public:
Snippet *next;
animal *A;
BIPExport Snippet();
BIPExport ~Snippet();
BIPExport void ClearActiveTransitions();
BIPExport void ClearSelectedTransitions();
BIPExport int ActivateTransitionTo(Snippet *toSN);
BIPExport Transition *GetTransitionTo(Snippet *toSN);
BIPExport int GetTransitionIndex(Transition *theTR);
BIPExport float AddTransition(Snippet *child, int optimize); // returns the floating point cost
BIPExport float ComputeTransitionPoints(Transition *nTR, Snippet *Src , Snippet *Dest, int preference, int optimize);
BIPExport float ComputeOptimalTransitionPoints(BOOL SearchAll,int PrefTranLen,int SearchBefore, int SearchAfter, Transition *nTR, Snippet *Src , Snippet *Dst);
BIPExport void RecomputeTransitions();// recompute existing transitions from this new snippet
BIPExport int DeleteTransitionsTo(Snippet *child);
BIPExport int DeleteTransition(int index);
BIPExport void DeleteSelectedTransitions(MoFlow *MF);
BIPExport int IsChild(Snippet *Child);
void Paint(HDC hdc, int selected, int startnode, int editnode, int transhow);
void PaintTransitions(HDC hdc, BOOL transhow);
void ComputeWidth(HDC hdc, BOOL transhow);
int Inside(POINT &mp, float *dist);
BIPExport void UpdateUI();
BIPExport Snippet& operator=(const Snippet& SN);
Transition* TranHitTest(POINT &mp);
void TranRegionSelect(POINT &min, POINT &max, int set, int active);
void Output(MFL_IOProcessor *IOProc);
void Input(MFL_IOProcessor *IOProc);
BIPExport int LoadFile(bool UpdateTheUI = true, int ErrorType = 3); // 3 => shows errors in dialog box
Snippet *GetNextRandScriptSnippet(int *transindex);
///MG added for new MF based forward simulatiom
Snippet * NextRealTime(BipMaster *mc, Script *scr, animal *A, int frame, path_properties *desired_properties, int global_frame, int global_last_clip_start, int currentScript_index, int *transindex, int *found);
inline int GetStart() const { return start; }
inline void SetStart(int s) { start = s; }
inline int GetEnd() const { return end; }
inline void SetEnd(int e) { end = e; }
inline const TCHAR* GetClipName() const { return sname; }
inline void SetClipName(const TCHAR* n) { _tcscpy(sname, n); }
inline const TCHAR* GetFileName() const { return fname; }
inline void SetFileName(const TCHAR* n) { _tcscpy(fname, n); }
inline virtual IPoint2 GetPosition() const { return IPoint2(posx, posy); }
inline virtual void SetPosition(IPoint2 p){ posx = p.x; posy = p.y; }
inline BOOL GetActive() const { return active; }
inline void SetActive(BOOL act) { active = act; }
inline BOOL GetRandStart() const { return randstart; }
inline void SetRandStart(BOOL rs) { randstart = rs; }
inline BOOL GetRandStartPercent() const { return randstartpct; }
inline void SetRandStartPercent(int rsp){ randstartpct = rsp; }
inline int NumTransitions() { return nTrans; }
inline Transition* GetTransition(int Tindex) const
{ assert (Tindex < nTrans); return &Transitions[Tindex]; }
inline void SetTransition(int Tindex, Transition* ti)
{ assert (Tindex < nTrans); Transitions[Tindex] = *ti; }
};
class ScriptItem {
public:
Snippet *snip;
int transindex;
vector flow_pos;
vector2D flow_pivot;
float flow_yaw;
int glob_snipstart;
TCHAR *tempSnipName; // for global moflow i/o
//MG added for CS4
int foothold_frame[2];
int footlift_frame[2];
inline Snippet* GetSnippet() { return snip; }
inline void SetSnippet(Snippet* s) { snip = s; }
inline int GetTransIndex() const { return transindex; }
inline void SetTransIndex(int i) { transindex = i; }
inline vector GetFlowPos() const { return flow_pos; }
inline void SetFlowPos(vector p) { flow_pos = p; }
inline vector2D GetFlowPivot() const { return flow_pivot; }
inline void SetFlowPivot(vector2D p){ flow_pivot = p; }
inline float GetFlowYaw() const { return flow_yaw; }
inline void SetFlowYaw(float y) { flow_yaw = y; }
inline int GetSnipStart() const { return glob_snipstart; }
inline void SetSnipStart(int s) { glob_snipstart = s; }
BIPExport ScriptItem();
BIPExport ScriptItem& operator=(const ScriptItem& SI);
};
class Script {
public:
TCHAR name[MAXSCRIPTNAME];
Point3 startpos;
float startrot;
int startframe;
int nitems;
int maxitems;
ScriptItem *items;
int nlayers;
Layer *layers;
Layer *EditLayer;
Script *next;
BIPExport Script();
BIPExport ~Script();
BIPExport Script& operator=(const Script& P);
BIPExport int AddSnippet(Snippet *SN);
BIPExport int InsertSnippet(int index, Snippet *SN);
BIPExport int DeleteSnippet(int index);
BIPExport int Get_Backtrackframe(); //mg
BIPExport int GetScriptItemIndex(ScriptItem *SI);
BIPExport int InsertScriptItem(int index, ScriptItem *SI);
BIPExport int GetLastTransitionIndex(); //MG m28
Transition *GetLastTransition(); //S43
inline int NumScriptItems() { return nitems; }
inline ScriptItem* GetScriptItem(int ind)
{ assert (ind < nitems); return &items[ind]; }
BIPExport int IncludesSnippet(Snippet *SN);
BIPExport int IncludesTransition(Transition *TR);
void Output(MFL_IOProcessor *IOProc);
void Input(MFL_IOProcessor *IOProc, MoFlow *MF);
inline int GetStartFrame() { return startframe; }
inline void SetStartFrame(int f) { startframe = f; }
BIPExport void Set_crowd_script(crowd_script *CS);
inline Point3 GetStartPos() { return startpos; }
inline void SetStartPos(Point3 p) { startpos = p;}
inline float GetStartRot() { return startrot; }
inline void SetStartRot(float r) { startrot = r;}
inline const TCHAR* GetName() const { return name; }
inline void SetName(const TCHAR* n) { _tcscpy(name, n); }
// The following functions are obsolete
inline int NumLayers() { return nlayers; }
inline Layer *GetEditLayer() { return EditLayer; }
BIPExport Layer *GetLayer(int index);
BIPExport int AddLayer(Script *SCR, TimeValue t);
BIPExport void DeleteLayer(Layer *delLY);
BIPExport void SortLayer(Layer *SORTLY);
BIPExport int GetLayerIndex(Layer *LYR);
BIPExport int InsertLayer(Layer *newLY);
BIPExport void CloneLayer(Layer *orgLY,TimeValue t);
BIPExport void DeleteAllLayers();
};
class IBipMaster;
class IMoFlow
{
public:
virtual int NumScripts() const=0;
virtual int NumSelected() const=0;
virtual Script* GetScript(int index)=0;
virtual Script* GetActiveScript()=0;
virtual void SetActiveScript(Script* scr)=0;
virtual int GetScriptIndex(Script *theSCR) const=0;
virtual int AddScript(TCHAR *newscriptname, bool activate=true)=0;
virtual void DeleteScript(Script *delSCR)=0;
virtual void DeleteScript(int ind)=0;
virtual void DeleteAllScripts()=0;
virtual int NumSnippets() const=0;
virtual const BitArray& GetSelected() const=0;
virtual void SetSelected(const BitArray& sel)=0;
virtual Snippet* GetSnip(int index)=0;
virtual Snippet* GetSnip(TCHAR *str)=0;
virtual int GetIndex(Snippet *theSN) const=0;
virtual int LoadSnippetFiles(bool UpdateTheUI = true, int ErrorType = 3, bool UpdateSNLengths=false)=0;
virtual int GetActiveStartFrame() const=0;
virtual int GetActiveEndFrame() const=0;
virtual int Save(TCHAR *fname)=0;
virtual int Load(TCHAR *fname, bool Append=false, bool UpdateTheUI = true, int ErrorType = 3)=0;
virtual IBipMaster* GetMaster()=0;
virtual void ComputeAnimation(int redraw, int globalsToo = FALSE)=0; //main function that computes the moflow
//NOTE if you add a snippet to the script this function must be called to make sure that
//the transistion are all active!
virtual void CurscriptToActiveLinks() = 0;
// Adds a new snippet(clip) to the motion flow network, if load==true it's immediately loaded(if not need to call LoadSnipetFiles,
//if redraw is true then the moflow graph is redraw
virtual Snippet* NewSnippet(TCHAR *fname, POINT &mp, bool load=false, bool redraw=false)=0;
virtual void DeleteSnip(Snippet *DelSnip)=0;
virtual void RedrawGraphWnd()=0; // update just motion flow editor
virtual void UpdateUI()=0; // updates the motionflow script dialog and motion flow editor
virtual void HoldTrack(int HoldAnimals, BOOL HoldScriptOffsetOnly = false)=0; // HoldAll, holds all biped limbs.use to hold the biped.
};
BIPExport void UpdateMotionFlowGraph(); // updates the motionflow graph should be called after mf functions
// that manipulate transistions
#endif // __IMOFLOW__