1 | /**********************************************************************
|
---|
2 | *<
|
---|
3 | FILE: control.h
|
---|
4 |
|
---|
5 | DESCRIPTION: Control definitions
|
---|
6 |
|
---|
7 | CREATED BY: Dan Silva and Rolf Berteig
|
---|
8 |
|
---|
9 | HISTORY: created 9 September 1994
|
---|
10 |
|
---|
11 | *> Copyright (c) 1994, All Rights Reserved.
|
---|
12 | **********************************************************************/
|
---|
13 |
|
---|
14 | #ifndef __CONTROL__
|
---|
15 |
|
---|
16 | #define __CONTROL__
|
---|
17 |
|
---|
18 | #include "plugapi.h"
|
---|
19 |
|
---|
20 | extern CoreExport void ApplyScaling(Matrix3 &m, const ScaleValue &v);
|
---|
21 | extern CoreExport void InitControlLists();
|
---|
22 |
|
---|
23 |
|
---|
24 | class ScaleValue;
|
---|
25 | class ViewExp;
|
---|
26 | class INode;
|
---|
27 | class XFormModes;
|
---|
28 | class INodeTab;
|
---|
29 |
|
---|
30 | CoreExport ScaleValue operator+(const ScaleValue& s0, const ScaleValue& s1);
|
---|
31 | CoreExport ScaleValue operator-(const ScaleValue& s0, const ScaleValue& s1);
|
---|
32 | CoreExport ScaleValue operator*(const ScaleValue& s, float f);
|
---|
33 | CoreExport ScaleValue operator*(float f, const ScaleValue& s);
|
---|
34 | CoreExport ScaleValue operator+(const ScaleValue& s, float f);
|
---|
35 | CoreExport ScaleValue operator+(float f, const ScaleValue& s);
|
---|
36 |
|
---|
37 | class ScaleValue {
|
---|
38 | public:
|
---|
39 | Point3 s;
|
---|
40 | Quat q;
|
---|
41 | ScaleValue() {}
|
---|
42 | ScaleValue(const Point3& as) { s = as; q = IdentQuat(); }
|
---|
43 | ScaleValue(const Point3& as, const Quat& aq) {s = as; q = aq;}
|
---|
44 | ScaleValue& operator+=(const ScaleValue& s) {(*this)=(*this)+s;return (*this);}
|
---|
45 | ScaleValue& operator*=(const float s) {(*this)=(*this)*s;return (*this);}
|
---|
46 | ScaleValue& operator=(const ScaleValue &v) {s=v.s;q=v.q;return (*this);}
|
---|
47 | float& operator[](int el) {return s[el];}
|
---|
48 | };
|
---|
49 |
|
---|
50 | // Types of ORTs
|
---|
51 | #define ORT_BEFORE 1
|
---|
52 | #define ORT_AFTER 2
|
---|
53 |
|
---|
54 | // ORTs
|
---|
55 | #define ORT_CONSTANT 1
|
---|
56 | #define ORT_CYCLE 2
|
---|
57 | #define ORT_LOOP 3 // This is cycle with continuity.
|
---|
58 | #define ORT_OSCILLATE 4
|
---|
59 | #define ORT_LINEAR 5
|
---|
60 | #define ORT_IDENTITY 6
|
---|
61 | #define ORT_RELATIVE_REPEAT 7
|
---|
62 |
|
---|
63 | /*---------------------------------------------------------------------*/
|
---|
64 |
|
---|
65 | // A list of ease curves.
|
---|
66 | class EaseCurveList : public ReferenceTarget {
|
---|
67 | friend class AddEaseRestore;
|
---|
68 | friend class DeleteEaseRestore;
|
---|
69 |
|
---|
70 | private:
|
---|
71 | Tab<Control*> eases;
|
---|
72 |
|
---|
73 | public:
|
---|
74 | EaseCurveList() {OpenTreeEntry(1);}
|
---|
75 | CoreExport ~EaseCurveList();
|
---|
76 |
|
---|
77 | CoreExport TimeValue ApplyEase(TimeValue t,Interval &valid);
|
---|
78 | CoreExport void AppendEaseCurve(Control *cont);
|
---|
79 | CoreExport void DeleteEaseCurve(int i);
|
---|
80 | CoreExport void DisableEaseCurve(int i);
|
---|
81 | CoreExport void EnableEaseCurve(int i);
|
---|
82 | CoreExport BOOL IsEaseEnabled(int i);
|
---|
83 | int NumEaseCurves() {return eases.Count();}
|
---|
84 |
|
---|
85 | // Animatable
|
---|
86 | void GetClassName(TSTR& s) { s= TSTR(_T("EaseCurve")); }
|
---|
87 | Class_ID ClassID() { return Class_ID(EASE_LIST_CLASS_ID,0); }
|
---|
88 | SClass_ID SuperClassID() { return EASE_LIST_CLASS_ID; }
|
---|
89 | CoreExport int NumSubs();
|
---|
90 | CoreExport Animatable* SubAnim(int i);
|
---|
91 | CoreExport TSTR SubAnimName(int i);
|
---|
92 | BOOL BypassTreeView() { return TRUE; }
|
---|
93 | void DeleteThis() { delete this; }
|
---|
94 | ParamDimension* GetParamDimension(int i) {return stdTimeDim;}
|
---|
95 | CoreExport BOOL AssignController(Animatable *control,int subAnim);
|
---|
96 | CoreExport void* GetInterface(ULONG id);
|
---|
97 |
|
---|
98 | CoreExport IOResult Save(ISave *isave);
|
---|
99 | CoreExport IOResult Load(ILoad *iload);
|
---|
100 |
|
---|
101 | // Reference
|
---|
102 | CoreExport int NumRefs();
|
---|
103 | CoreExport RefTargetHandle GetReference(int i);
|
---|
104 | CoreExport void SetReference(int i, RefTargetHandle rtarg);
|
---|
105 | CoreExport RefTargetHandle Clone(RemapDir &remap = NoRemap());
|
---|
106 | CoreExport RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
---|
107 | PartID& partID, RefMessage message);
|
---|
108 | };
|
---|
109 |
|
---|
110 | class EaseCurveAnimProp : public AnimProperty {
|
---|
111 | public:
|
---|
112 | EaseCurveList *el;
|
---|
113 | EaseCurveAnimProp() { el=NULL; }
|
---|
114 | DWORD ID() {return PROPID_EASELIST;}
|
---|
115 | };
|
---|
116 |
|
---|
117 | #define GetEaseListInterface(anim) ((EaseCurveList*)anim->GetInterface(I_EASELIST))
|
---|
118 |
|
---|
119 | /*---------------------------------------------------------------------*/
|
---|
120 | // A list of multiplier curves.
|
---|
121 | class MultCurveList : public ReferenceTarget {
|
---|
122 | friend class AddMultRestore;
|
---|
123 | friend class DeleteMultRestore;
|
---|
124 | private:
|
---|
125 | Tab<Control*> mults;
|
---|
126 |
|
---|
127 | public:
|
---|
128 | MultCurveList() {OpenTreeEntry(1);}
|
---|
129 | CoreExport ~MultCurveList();
|
---|
130 |
|
---|
131 | CoreExport float GetMultVal(TimeValue t,Interval &valid);
|
---|
132 | CoreExport void AppendMultCurve(Control *cont);
|
---|
133 | CoreExport void DeleteMultCurve(int i);
|
---|
134 | CoreExport void DisableMultCurve(int i);
|
---|
135 | CoreExport void EnableMultCurve(int i);
|
---|
136 | CoreExport BOOL IsMultEnabled(int i);
|
---|
137 | int NumMultCurves() {return mults.Count();}
|
---|
138 |
|
---|
139 | // Animatable
|
---|
140 | void GetClassName(TSTR& s) { s= TSTR(_T("MultCurve")); }
|
---|
141 | Class_ID ClassID() { return Class_ID(MULT_LIST_CLASS_ID,0); }
|
---|
142 | SClass_ID SuperClassID() { return MULT_LIST_CLASS_ID; }
|
---|
143 | CoreExport int NumSubs();
|
---|
144 | CoreExport Animatable* SubAnim(int i);
|
---|
145 | CoreExport TSTR SubAnimName(int i);
|
---|
146 | BOOL BypassTreeView() { return TRUE; }
|
---|
147 | void DeleteThis() { delete this; }
|
---|
148 | ParamDimension* GetParamDimension(int i) {return stdNormalizedDim;}
|
---|
149 | CoreExport BOOL AssignController(Animatable *control,int subAnim);
|
---|
150 | CoreExport void* GetInterface(ULONG id);
|
---|
151 |
|
---|
152 | CoreExport IOResult Save(ISave *isave);
|
---|
153 | CoreExport IOResult Load(ILoad *iload);
|
---|
154 |
|
---|
155 | // Reference
|
---|
156 | CoreExport int NumRefs();
|
---|
157 | CoreExport RefTargetHandle GetReference(int i);
|
---|
158 | CoreExport void SetReference(int i, RefTargetHandle rtarg);
|
---|
159 | CoreExport RefTargetHandle Clone(RemapDir &remap = NoRemap());
|
---|
160 | CoreExport RefResult NotifyRefChanged(Interval changeInt, RefTargetHandle hTarget,
|
---|
161 | PartID& partID, RefMessage message);
|
---|
162 | };
|
---|
163 |
|
---|
164 | class MultCurveAnimProp : public AnimProperty {
|
---|
165 | public:
|
---|
166 | MultCurveList *ml;
|
---|
167 | MultCurveAnimProp() { ml=NULL; }
|
---|
168 | DWORD ID() {return PROPID_MULTLIST;}
|
---|
169 | };
|
---|
170 |
|
---|
171 | #define GetMultListInterface(anim) ((MultCurveList*)anim->GetInterface(I_MULTLIST))
|
---|
172 |
|
---|
173 | /*---------------------------------------------------------------------*/
|
---|
174 |
|
---|
175 |
|
---|
176 | //
|
---|
177 | // For hit testing controller apparatus
|
---|
178 | //
|
---|
179 |
|
---|
180 | class CtrlHitRecord {
|
---|
181 | friend class CtrlHitLog;
|
---|
182 | CtrlHitRecord *next;
|
---|
183 | public:
|
---|
184 | INode *nodeRef;
|
---|
185 | DWORD distance;
|
---|
186 | ulong hitInfo;
|
---|
187 | DWORD infoExtra;
|
---|
188 | CtrlHitRecord() {next=NULL; distance=0; hitInfo=0; nodeRef=NULL;}
|
---|
189 | CtrlHitRecord(CtrlHitRecord *nxt,INode *nr, DWORD d, ulong inf, DWORD extra) {
|
---|
190 | next=nxt;nodeRef=nr;distance=d;hitInfo=inf;infoExtra=extra;}
|
---|
191 | CtrlHitRecord *Next() {return next;}
|
---|
192 | };
|
---|
193 |
|
---|
194 | class CtrlHitLog {
|
---|
195 | CtrlHitRecord *first;
|
---|
196 | public:
|
---|
197 | CtrlHitLog() { first = NULL; }
|
---|
198 | ~CtrlHitLog() { Clear(); }
|
---|
199 | CoreExport void Clear();
|
---|
200 | CtrlHitRecord* First() { return first; }
|
---|
201 | CoreExport CtrlHitRecord* ClosestHit();
|
---|
202 | void LogHit(INode *nr,DWORD dist,ulong info,DWORD infoExtra)
|
---|
203 | {first = new CtrlHitRecord(first,nr,dist,info,infoExtra);}
|
---|
204 | };
|
---|
205 |
|
---|
206 |
|
---|
207 | // For enumerating IK paramaters
|
---|
208 | class IKEnumCallback {
|
---|
209 | public:
|
---|
210 | virtual void proc(Control *c, int index)=0;
|
---|
211 | };
|
---|
212 |
|
---|
213 | class IKDeriv {
|
---|
214 | public:
|
---|
215 | virtual int NumEndEffectors()=0;
|
---|
216 | virtual Point3 EndEffectorPos(int index)=0;
|
---|
217 | virtual void DP(Point3 dp,int index)=0;
|
---|
218 | virtual void DR(Point3 dr,int index)=0;
|
---|
219 | virtual void NextDOF()=0;
|
---|
220 | };
|
---|
221 |
|
---|
222 | // Flags passed to CompDerivs
|
---|
223 | #define POSITION_DERIV (1<<0)
|
---|
224 | #define ROTATION_DERIV (1<<1)
|
---|
225 |
|
---|
226 |
|
---|
227 | // This class is used to store IK parameters that have been
|
---|
228 | // copied to a clipboard.
|
---|
229 | class IKClipObject {
|
---|
230 | public:
|
---|
231 | // Identifies the creator of the clip object
|
---|
232 | virtual SClass_ID SuperClassID()=0;
|
---|
233 | virtual Class_ID ClassID()=0;
|
---|
234 |
|
---|
235 | virtual void DeleteThis()=0;
|
---|
236 | };
|
---|
237 |
|
---|
238 | // Values for 'which' pasted to Copy/PasteIKParams
|
---|
239 | #define COPYPASTE_IKPOS 1
|
---|
240 | #define COPYPASTE_IKROT 2
|
---|
241 |
|
---|
242 | // Passed to InitIKJoints() which is called when importing
|
---|
243 | // R4 3DS files that have IK joint data.
|
---|
244 | class InitJointData {
|
---|
245 | public:
|
---|
246 | BOOL active[3];
|
---|
247 | BOOL limit[3];
|
---|
248 | BOOL ease[3];
|
---|
249 | Point3 min, max, damping;
|
---|
250 | };
|
---|
251 |
|
---|
252 |
|
---|
253 | // These two ways values can be retreived or set.
|
---|
254 | // For get:
|
---|
255 | // RELATIVE = Apply
|
---|
256 | // ABSOLUTE = Just get the value
|
---|
257 | // For set:
|
---|
258 | // RELATIVE = Add the value to the existing value (i.e Move/Rotate/Scale)
|
---|
259 | // ABSOLUTE = Just set the value
|
---|
260 | enum GetSetMethod {CTRL_RELATIVE,CTRL_ABSOLUTE};
|
---|
261 |
|
---|
262 |
|
---|
263 | // Control class provides default implementations for load and save which save the ORT type in these chunks:
|
---|
264 | #define CONTROLBASE_CHUNK 0x8499
|
---|
265 | #define INORT_CHUNK 0x3000
|
---|
266 | #define OUTORT_CHUNK 0x3001
|
---|
267 | #define CONT_DISABLED_CHUNK 0x3002
|
---|
268 |
|
---|
269 | // Inheritance flags.
|
---|
270 | #define INHERIT_POS_X (1<<0)
|
---|
271 | #define INHERIT_POS_Y (1<<1)
|
---|
272 | #define INHERIT_POS_Z (1<<2)
|
---|
273 | #define INHERIT_ROT_X (1<<3)
|
---|
274 | #define INHERIT_ROT_Y (1<<4)
|
---|
275 | #define INHERIT_ROT_Z (1<<5)
|
---|
276 | #define INHERIT_SCL_X (1<<6)
|
---|
277 | #define INHERIT_SCL_Y (1<<7)
|
---|
278 | #define INHERIT_SCL_Z (1<<8)
|
---|
279 | #define INHERIT_ALL 511
|
---|
280 |
|
---|
281 | class Control : public ReferenceTarget {
|
---|
282 | public:
|
---|
283 | Control() {SetORT(ORT_CONSTANT,ORT_BEFORE);SetORT(ORT_CONSTANT,ORT_AFTER);};
|
---|
284 | virtual ~Control() {};
|
---|
285 |
|
---|
286 | virtual void Copy(Control *from)=0;
|
---|
287 | virtual void CommitValue(TimeValue t) {}
|
---|
288 | virtual void RestoreValue(TimeValue t) {}
|
---|
289 | virtual INode* GetTarget() { return NULL; }
|
---|
290 | virtual RefResult SetTarget(INode *targ) {return REF_SUCCEED;}
|
---|
291 |
|
---|
292 | // Implemented by transform controllers that have position controller
|
---|
293 | // that can be edited in the trajectory branch
|
---|
294 | virtual Control *GetPositionController() {return NULL;}
|
---|
295 | virtual Control *GetRotationController() {return NULL;}
|
---|
296 | virtual Control *GetScaleController() {return NULL;}
|
---|
297 | virtual BOOL SetPositionController(Control *c) {return FALSE;}
|
---|
298 | virtual BOOL SetRotationController(Control *c) {return FALSE;}
|
---|
299 | virtual BOOL SetScaleController(Control *c) {return FALSE;}
|
---|
300 |
|
---|
301 | // Implemented by look at controllers that have a float valued roll
|
---|
302 | // controller so that the roll can be edited via the transform type-in
|
---|
303 | virtual Control *GetRollController() {return NULL;}
|
---|
304 | virtual BOOL SetRollController(Control *c) {return FALSE;}
|
---|
305 |
|
---|
306 | // Implemented by any Point3 controller that wishes to indicate that it is intended
|
---|
307 | // to control floating point RGB color values
|
---|
308 | virtual BOOL IsColorController() {return FALSE;}
|
---|
309 |
|
---|
310 | // Implemented by TM controllers that support
|
---|
311 | // filtering out inheritance
|
---|
312 | virtual DWORD GetInheritanceFlags() {return INHERIT_ALL;}
|
---|
313 | virtual BOOL SetInheritanceFlags(DWORD f,BOOL keepPos) {return FALSE;} // return TRUE if TM controller supports inheritance
|
---|
314 |
|
---|
315 | virtual BOOL IsLeaf() {return TRUE;}
|
---|
316 | virtual int IsKeyable() {return 1;}
|
---|
317 |
|
---|
318 | // If a controller does not want to allow another controller
|
---|
319 | // to be assigned on top of it, it can return FALSE to this method.
|
---|
320 | virtual BOOL IsReplaceable() {return TRUE;}
|
---|
321 |
|
---|
322 | // This is called on TM, pos, rot, and scale controllers when their
|
---|
323 | // input matrix is about to change. If they return FALSE, the node will
|
---|
324 | // call SetValue() to make the necessary adjustments.
|
---|
325 | virtual BOOL ChangeParents(TimeValue t,const Matrix3& oldP,const Matrix3& newP,const Matrix3& tm) {return FALSE;}
|
---|
326 |
|
---|
327 | // val points to an instance of a data type that corresponds with the controller
|
---|
328 | // type. float for float controllers, etc.
|
---|
329 | // Note that for SetValue on Rotation controllers, if the SetValue is
|
---|
330 | // relative, val points to an AngAxis while if it is absolute it points
|
---|
331 | // to a Quat.
|
---|
332 | virtual void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE)=0;
|
---|
333 | virtual void SetValue(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE)=0;
|
---|
334 |
|
---|
335 | // Transform controllers that do not inherit their parent's transform
|
---|
336 | // should override this method. Returning FALSE will cause SetValue
|
---|
337 | // to be called even in the case when the parent is also being transformed.
|
---|
338 | virtual BOOL InheritsParentTransform() { return TRUE; }
|
---|
339 |
|
---|
340 | virtual int GetORT(int type) {return (aflag>>(type==ORT_BEFORE?A_ORT_BEFORESHIFT:A_ORT_AFTERSHIFT))&A_ORT_MASK;}
|
---|
341 | CoreExport virtual void SetORT(int ort,int type);
|
---|
342 |
|
---|
343 | // Sets the enabled/disabled state for ORTs
|
---|
344 | CoreExport virtual void EnableORTs(BOOL enable);
|
---|
345 |
|
---|
346 | // Default implementations of load and save handle loading and saving of out of range type.
|
---|
347 | // Call these from derived class load and save.
|
---|
348 | // NOTE: Must call these before any of the derived class chunks are loaded or saved.
|
---|
349 | CoreExport IOResult Save(ISave *isave);
|
---|
350 | CoreExport IOResult Load(ILoad *iload);
|
---|
351 |
|
---|
352 | // For IK
|
---|
353 | // Note: IK params must be given in the order they are applied to
|
---|
354 | // the parent matrix. When derivatives are computed for a parameter
|
---|
355 | // that parameter will apply itself to the parent matrix so the next
|
---|
356 | // parameter has the appropriate reference frame. If a controller isn't
|
---|
357 | // participating in IK then it should return FALSE and the client (usually PRS)
|
---|
358 | // will apply the controller's value to the parent TM.
|
---|
359 | virtual void EnumIKParams(IKEnumCallback &callback) {}
|
---|
360 | virtual BOOL CompDeriv(TimeValue t,Matrix3& ptm,IKDeriv& derivs,DWORD flags) {return FALSE;}
|
---|
361 | virtual float IncIKParam(TimeValue t,int index,float delta) {return 0.0f;}
|
---|
362 | virtual void ClearIKParam(Interval iv,int index) {return;}
|
---|
363 | virtual BOOL CanCopyIKParams(int which) {return FALSE;}
|
---|
364 | virtual IKClipObject *CopyIKParams(int which) {return NULL;}
|
---|
365 | virtual BOOL CanPasteIKParams(IKClipObject *co,int which) {return FALSE;}
|
---|
366 | virtual void PasteIKParams(IKClipObject *co,int which) {}
|
---|
367 | virtual void InitIKJoints(InitJointData *posData,InitJointData *rotData) {}
|
---|
368 |
|
---|
369 | // Ease curves
|
---|
370 | virtual BOOL CanApplyEaseMultCurves() {return TRUE;}
|
---|
371 | CoreExport TimeValue ApplyEase(TimeValue t,Interval &valid);
|
---|
372 | CoreExport void AppendEaseCurve(Control *cont);
|
---|
373 | CoreExport void DeleteEaseCurve(int i);
|
---|
374 | CoreExport int NumEaseCurves();
|
---|
375 |
|
---|
376 | // Multiplier curves
|
---|
377 | CoreExport float GetMultVal(TimeValue t,Interval &valid);
|
---|
378 | CoreExport void AppendMultCurve(Control *cont);
|
---|
379 | CoreExport void DeleteMultCurve(int i);
|
---|
380 | CoreExport int NumMultCurves();
|
---|
381 |
|
---|
382 | // These are implemented to handle ease curves. If a controller
|
---|
383 | // is a leaf controller, then it MUST NOT BY DEFINITION have any
|
---|
384 | // sub controllers or references. If it is a leaf controller, then
|
---|
385 | // these are implemented to handle the ease curve list.
|
---|
386 | // If it is NOT a leaf controller, then these can be overridden.
|
---|
387 | CoreExport int NumRefs();
|
---|
388 | CoreExport RefTargetHandle GetReference(int i);
|
---|
389 | CoreExport void SetReference(int i, RefTargetHandle rtarg);
|
---|
390 | CoreExport int NumSubs();
|
---|
391 | CoreExport Animatable* SubAnim(int i);
|
---|
392 | CoreExport TSTR SubAnimName(int i);
|
---|
393 |
|
---|
394 | // Default implementations of some Animatable methods
|
---|
395 | CoreExport void* GetInterface(ULONG id);
|
---|
396 | CoreExport int PaintFCurves(
|
---|
397 | ParamDimensionBase *dim,
|
---|
398 | HDC hdc,
|
---|
399 | Rect& rcGraph,
|
---|
400 | Rect& rcPaint,
|
---|
401 | float tzoom,
|
---|
402 | int tscroll,
|
---|
403 | float vzoom,
|
---|
404 | int vscroll,
|
---|
405 | DWORD flags );
|
---|
406 | CoreExport int GetFCurveExtents(
|
---|
407 | ParamDimensionBase *dim,
|
---|
408 | float &min, float &max, DWORD flags);
|
---|
409 |
|
---|
410 |
|
---|
411 | //-------------------------------------------------------
|
---|
412 | // Controllers that wish to have an apparatus available in
|
---|
413 | // the scene will implement these methods:
|
---|
414 | // NOTE: Most of these methods are duplicated in BaseObject or Object
|
---|
415 | // (see object.h for descriptions).
|
---|
416 | virtual int Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) { return 0; };
|
---|
417 | virtual int HitTest(TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt) { return 0; }
|
---|
418 | virtual void GetWorldBoundBox(TimeValue t,INode* inode, ViewExp *vpt, Box3& box) {}
|
---|
419 |
|
---|
420 | virtual void ActivateSubobjSel(int level, XFormModes& modes ) {}
|
---|
421 |
|
---|
422 | virtual void SelectSubComponent(CtrlHitRecord *hitRec, BOOL selected, BOOL all, BOOL invert=FALSE) {}
|
---|
423 | virtual void ClearSelection(int selLevel) {}
|
---|
424 | virtual int SubObjectIndex(CtrlHitRecord *hitRec) {return 0;}
|
---|
425 |
|
---|
426 | virtual void GetSubObjectCenters(SubObjAxisCallback *cb,TimeValue t,INode *node) {}
|
---|
427 | virtual void GetSubObjectTMs(SubObjAxisCallback *cb,TimeValue t,INode *node) {}
|
---|
428 |
|
---|
429 | // Modify sub object apparatuses
|
---|
430 | virtual void SubMove( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}
|
---|
431 | virtual void SubRotate( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Quat& val, BOOL localOrigin=FALSE ){}
|
---|
432 | virtual void SubScale( TimeValue t, Matrix3& partm, Matrix3& tmAxis, Point3& val, BOOL localOrigin=FALSE ){}
|
---|
433 | virtual void MouseCycleCompleted(TimeValue t) {}
|
---|
434 |
|
---|
435 | };
|
---|
436 |
|
---|
437 |
|
---|
438 | // Any controller that does not evaluate itself as a function of it's
|
---|
439 | // input can subclass off this class.
|
---|
440 | // GetValueLocalTime() will never ask the controller to apply the value,
|
---|
441 | // it will always ask for it absolute.
|
---|
442 | class StdControl : public Control {
|
---|
443 | public:
|
---|
444 | virtual void GetValueLocalTime(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE)=0;
|
---|
445 | virtual void SetValueLocalTime(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE)=0;
|
---|
446 | CoreExport void GetValue(TimeValue t, void *val, Interval &valid, GetSetMethod method=CTRL_ABSOLUTE);
|
---|
447 | CoreExport void SetValue(TimeValue t, void *val, int commit=1, GetSetMethod method=CTRL_ABSOLUTE);
|
---|
448 |
|
---|
449 | virtual void Extrapolate(Interval range,TimeValue t,void *val,Interval &valid,int type)=0;
|
---|
450 |
|
---|
451 | virtual void *CreateTempValue()=0;
|
---|
452 | virtual void DeleteTempValue(void *val)=0;
|
---|
453 | virtual void ApplyValue(void *val, void *delta)=0;
|
---|
454 | virtual void MultiplyValue(void *val, float m)=0;
|
---|
455 | };
|
---|
456 |
|
---|
457 |
|
---|
458 | // Each super class of controller may have a specific packet defined that
|
---|
459 | // the 'val' pointer will point to instead of a literal value.
|
---|
460 | // In reality, probably only the Transform controller will do this.
|
---|
461 | enum SetXFormCommand { XFORM_MOVE, XFORM_ROTATE, XFORM_SCALE, XFORM_SET };
|
---|
462 | class SetXFormPacket {
|
---|
463 | public:
|
---|
464 | SetXFormCommand command;
|
---|
465 | Matrix3 tmParent;
|
---|
466 | Matrix3 tmAxis; // if command is XFORM_SET, this will contain the new value for the XFORM.
|
---|
467 | Point3 p;
|
---|
468 | Quat q;
|
---|
469 | AngAxis aa;
|
---|
470 | BOOL localOrigin;
|
---|
471 |
|
---|
472 | // XFORM_SET
|
---|
473 | SetXFormPacket(const Matrix3& mat,const Matrix3& par=Matrix3(1))
|
---|
474 | {command=XFORM_SET,tmParent=par,tmAxis=mat;}
|
---|
475 |
|
---|
476 | // XFORM_MOVE
|
---|
477 | SetXFormPacket(Point3 pt, const Matrix3& par=Matrix3(1),
|
---|
478 | const Matrix3& a=Matrix3(1))
|
---|
479 | {command=XFORM_MOVE;tmParent=par;tmAxis=a;p=pt;localOrigin=FALSE;}
|
---|
480 |
|
---|
481 | // XFORM_ROTATE
|
---|
482 | SetXFormPacket(Quat qt, BOOL l, const Matrix3& par=Matrix3(1),
|
---|
483 | const Matrix3& a=Matrix3(1))
|
---|
484 | {command=XFORM_ROTATE;tmParent=par;tmAxis=a;q=qt;aa=AngAxis(q);localOrigin=l;}
|
---|
485 | SetXFormPacket(AngAxis aA, BOOL l, const Matrix3& par=Matrix3(1),
|
---|
486 | const Matrix3& a=Matrix3(1))
|
---|
487 | {command=XFORM_ROTATE;tmParent=par;tmAxis=a;q=Quat(aA);aa=aA;localOrigin=l;}
|
---|
488 |
|
---|
489 | // XFORM_SCALE
|
---|
490 | SetXFormPacket(Point3 pt, BOOL l, const Matrix3& par=Matrix3(1),
|
---|
491 | const Matrix3& a=Matrix3(1))
|
---|
492 | {command=XFORM_SCALE;tmParent=par;tmAxis=a;p=pt;localOrigin=l;}
|
---|
493 |
|
---|
494 | // Just in case you want to do it by hand...
|
---|
495 | SetXFormPacket() {};
|
---|
496 | };
|
---|
497 |
|
---|
498 |
|
---|
499 |
|
---|
500 | // This is a special control base class for controllers that control
|
---|
501 | // morphing of geomoetry.
|
---|
502 | //
|
---|
503 | // The 'val' pointer used with GetValue will point to an object state.
|
---|
504 | // This would be the result of evaluating a combination of targets and
|
---|
505 | // producing a new object that is some combination of the targets.
|
---|
506 | //
|
---|
507 | // The 'val' pointer used with SetValue will point to a
|
---|
508 | // SetMorphTargetPacket data structure. This has a pointer to
|
---|
509 | // an object (entire pipeline) and the name of the target.
|
---|
510 |
|
---|
511 | // A pointer to one of these is passed to SetValue
|
---|
512 | class SetMorphTargetPacket {
|
---|
513 | public:
|
---|
514 | Matrix3 tm;
|
---|
515 | Object *obj;
|
---|
516 | TSTR name;
|
---|
517 | BOOL forceCreate; // Make sure the key is created even if it is at frame 0
|
---|
518 | SetMorphTargetPacket(Object *o,TSTR n,Matrix3 &m,BOOL fc=FALSE) {obj = o;name = n;tm = m;forceCreate=fc;}
|
---|
519 | SetMorphTargetPacket(Object *o,TSTR n,BOOL fc=FALSE) {obj = o;name = n;tm = Matrix3(1);forceCreate=fc;}
|
---|
520 | };
|
---|
521 |
|
---|
522 | class MorphControl : public Control {
|
---|
523 | public:
|
---|
524 |
|
---|
525 | // Access the object pipelines of the controller's targets. Note
|
---|
526 | // that these are pointers to the pipelines, not the result of
|
---|
527 | // evaluating the pipelines.
|
---|
528 | virtual int NumMorphTargs() {return 0;}
|
---|
529 | virtual Object *GetMorphTarg(int i) {return NULL;}
|
---|
530 | virtual void GetMorphTargName(int i,TSTR &name) {name.printf(_T("Target #%d"),i);}
|
---|
531 | virtual Matrix3 GetMorphTargTM(int i) {return Matrix3(1);}
|
---|
532 |
|
---|
533 | // Checks an object to see if it is an acceptable target.
|
---|
534 | virtual BOOL ValidTarget(TimeValue t,Object *obj) {return FALSE;}
|
---|
535 | };
|
---|
536 |
|
---|
537 | //----------------------------------------------------------------//
|
---|
538 | //
|
---|
539 | // Some stuff to help with ORTs - these could actually be Interval methods
|
---|
540 |
|
---|
541 | inline TimeValue CycleTime(Interval i,TimeValue t)
|
---|
542 | {
|
---|
543 | int res, dur = i.Duration()-1;
|
---|
544 | if (dur<=0) return t;
|
---|
545 | res = (t-i.Start())%dur;
|
---|
546 | if (res<0) {
|
---|
547 | return i.End()+res;
|
---|
548 | } else {
|
---|
549 | return i.Start()+res;
|
---|
550 | }
|
---|
551 | }
|
---|
552 |
|
---|
553 | inline int NumCycles(Interval i,TimeValue t)
|
---|
554 | {
|
---|
555 | int dur = i.Duration()-1;
|
---|
556 | if (dur<=0) return 1;
|
---|
557 | if (t<i.Start()) {
|
---|
558 | return (abs(t-i.Start())/dur)+1;
|
---|
559 | } else
|
---|
560 | if (t>i.End()) {
|
---|
561 | return (abs(t-i.End())/dur)+1;
|
---|
562 | } else {
|
---|
563 | return 0;
|
---|
564 | }
|
---|
565 | }
|
---|
566 |
|
---|
567 |
|
---|
568 |
|
---|
569 | // Types that use this template must support:
|
---|
570 | // T + T, T - T, T * float, T + float
|
---|
571 |
|
---|
572 | template <class T> T
|
---|
573 | LinearExtrapolate(TimeValue t0, TimeValue t1, T &val0, T &val1, T &endVal)
|
---|
574 | {
|
---|
575 | return (T)(endVal + (val1-val0) * float(t1-t0));
|
---|
576 | }
|
---|
577 |
|
---|
578 | template <class T> T
|
---|
579 | RepeatExtrapolate(Interval range, TimeValue t,
|
---|
580 | T &startVal, T &endVal, T &cycleVal)
|
---|
581 | {
|
---|
582 | int cycles = NumCycles(range,t);
|
---|
583 | T delta;
|
---|
584 | if (t<range.Start()) {
|
---|
585 | delta = startVal - endVal;
|
---|
586 | } else {
|
---|
587 | delta = endVal - startVal;
|
---|
588 | }
|
---|
589 | return (T)(cycleVal + delta * float(cycles));
|
---|
590 | }
|
---|
591 |
|
---|
592 | template <class T> T
|
---|
593 | IdentityExtrapolate(TimeValue endPoint, TimeValue t, T &endVal )
|
---|
594 | {
|
---|
595 | return (T)(endVal + float(t-endPoint));
|
---|
596 | }
|
---|
597 |
|
---|
598 | CoreExport Quat LinearExtrapolate(TimeValue t0, TimeValue t1, Quat &val0, Quat &val1, Quat &endVal);
|
---|
599 | CoreExport Quat RepeatExtrapolate(Interval range, TimeValue t,
|
---|
600 | Quat &startVal, Quat &endVal, Quat &cycleVal);
|
---|
601 | CoreExport Quat IdentityExtrapolate(TimeValue endPoint, TimeValue t, Quat &endVal );
|
---|
602 |
|
---|
603 |
|
---|
604 | template <class T> T
|
---|
605 | LinearInterpolate(const T &v0,const T &v1,float u)
|
---|
606 | {
|
---|
607 | return (T)((1.0f-u)*v0 + u*v1);
|
---|
608 | }
|
---|
609 |
|
---|
610 | inline Quat
|
---|
611 | LinearInterpolate(const Quat &v0,const Quat &v1,float u)
|
---|
612 | {
|
---|
613 | return Slerp(v0,v1,u);
|
---|
614 | }
|
---|
615 |
|
---|
616 | inline ScaleValue
|
---|
617 | LinearInterpolate(const ScaleValue &v0,const ScaleValue &v1,float u)
|
---|
618 | {
|
---|
619 | ScaleValue res;
|
---|
620 | res.s = ((float)1.0-u)*v0.s + u*v1.s;
|
---|
621 | res.q = Slerp(v0.q,v1.q,u);
|
---|
622 | return res;
|
---|
623 | }
|
---|
624 |
|
---|
625 |
|
---|
626 | inline Interval TestInterval(Interval iv, DWORD flags)
|
---|
627 | {
|
---|
628 | TimeValue start = iv.Start();
|
---|
629 | TimeValue end = iv.End();
|
---|
630 | if (!(flags&TIME_INCLEFT)) {
|
---|
631 | start++;
|
---|
632 | }
|
---|
633 | if (!(flags&TIME_INCRIGHT)) {
|
---|
634 | end--;
|
---|
635 | }
|
---|
636 | if (end<start) {
|
---|
637 | iv.SetEmpty();
|
---|
638 | } else {
|
---|
639 | iv.Set(start,end);
|
---|
640 | }
|
---|
641 | return iv;
|
---|
642 | }
|
---|
643 |
|
---|
644 | inline Quat ScaleQuat(Quat q, float s)
|
---|
645 | {
|
---|
646 | float angle;
|
---|
647 | Point3 axis;
|
---|
648 | AngAxisFromQ(q,&angle,axis);
|
---|
649 | return QFromAngAxis(angle*s,axis);
|
---|
650 | }
|
---|
651 |
|
---|
652 | //-------------------------------------------------------------------
|
---|
653 | // A place to store values during Hold/Restore periods
|
---|
654 | //
|
---|
655 | //********************************************************
|
---|
656 | // TempStore: This is a temporary implementation:
|
---|
657 | // It uses a linear search-
|
---|
658 | // A hash-coded dictionary would be faster.
|
---|
659 | // (if there are ever a lot of entries)
|
---|
660 | //********************************************************
|
---|
661 |
|
---|
662 | struct Slot {
|
---|
663 | void *key;
|
---|
664 | void *pdata;
|
---|
665 | int nbytes;
|
---|
666 | Slot *next;
|
---|
667 | public:
|
---|
668 | Slot() { pdata = NULL; }
|
---|
669 | ~Slot() {
|
---|
670 | if (pdata) free(pdata);
|
---|
671 | pdata = NULL;
|
---|
672 | }
|
---|
673 |
|
---|
674 | };
|
---|
675 |
|
---|
676 | class TempStore {
|
---|
677 | Slot *slotList;
|
---|
678 | Slot* Find(int n, void *data, void *ptr);
|
---|
679 | public:
|
---|
680 | TempStore() { slotList = NULL; }
|
---|
681 | ~TempStore() { ClearAll(); }
|
---|
682 | CoreExport void ClearAll(); // empty out the store
|
---|
683 | CoreExport void PutBytes(int n, void *data, void *ptr);
|
---|
684 | CoreExport void GetBytes(int n, void *data, void *ptr);
|
---|
685 | CoreExport void Clear(void *ptr); // Remove single entry
|
---|
686 | void PutFloat(float f, void *ptr) {
|
---|
687 | PutBytes(sizeof(float),(void *)&f,ptr);
|
---|
688 | }
|
---|
689 | CoreExport void PutInt(int i, void *ptr) {
|
---|
690 | PutBytes(sizeof(int),(void *)&i,ptr);
|
---|
691 | }
|
---|
692 | CoreExport void GetFloat(float *f, void *ptr) {
|
---|
693 | GetBytes(sizeof(float),(void *)f,ptr);
|
---|
694 | }
|
---|
695 | CoreExport void GetInt(int *i, void *ptr) {
|
---|
696 | GetBytes(sizeof(int),(void *)i,ptr);
|
---|
697 | }
|
---|
698 | CoreExport void PutPoint3(Point3 f, void *ptr) {
|
---|
699 | PutBytes(sizeof(Point3),(void *)&f,ptr);
|
---|
700 | }
|
---|
701 | CoreExport void GetPoint3(Point3 *f, void *ptr) {
|
---|
702 | GetBytes(sizeof(Point3),(void *)f,ptr);
|
---|
703 | }
|
---|
704 | CoreExport void PutQuat( Quat f, void *ptr) {
|
---|
705 | PutBytes(sizeof(Quat),(void *)&f,ptr);
|
---|
706 | }
|
---|
707 | CoreExport void GetQuat( Quat *f, void *ptr) {
|
---|
708 | GetBytes(sizeof(Quat),(void *)f,ptr);
|
---|
709 | }
|
---|
710 | CoreExport void PutScaleValue( ScaleValue f, void *ptr) {
|
---|
711 | PutBytes(sizeof(ScaleValue),(void *)&f,ptr);
|
---|
712 | }
|
---|
713 | CoreExport void GetScaleValue( ScaleValue *f, void *ptr) {
|
---|
714 | GetBytes(sizeof(ScaleValue),(void *)f,ptr);
|
---|
715 | }
|
---|
716 | };
|
---|
717 |
|
---|
718 |
|
---|
719 | extern CoreExport TempStore tmpStore; // this should be in the scene data struct.
|
---|
720 |
|
---|
721 |
|
---|
722 | CoreExport int Animating(); // is the animate switch on??
|
---|
723 | CoreExport void AnimateOn(); // turn animate on
|
---|
724 | CoreExport void AnimateOff(); // turn animate off
|
---|
725 | CoreExport void SuspendAnimate(); // suspend animation (uses stack)
|
---|
726 | CoreExport void ResumeAnimate(); // resume animation ( " )
|
---|
727 |
|
---|
728 | CoreExport TimeValue GetAnimStart();
|
---|
729 | CoreExport TimeValue GetAnimEnd();
|
---|
730 | CoreExport void SetAnimStart(TimeValue s);
|
---|
731 | CoreExport void SetAnimEnd(TimeValue e);
|
---|
732 |
|
---|
733 | CoreExport Control *NewDefaultFloatController();
|
---|
734 | CoreExport Control *NewDefaultPoint3Controller();
|
---|
735 | CoreExport Control *NewDefaultMatrix3Controller();
|
---|
736 | CoreExport Control *NewDefaultPositionController();
|
---|
737 | CoreExport Control *NewDefaultRotationController();
|
---|
738 | CoreExport Control *NewDefaultScaleController();
|
---|
739 | CoreExport Control *NewDefaultBoolController();
|
---|
740 | CoreExport Control *NewDefaultColorController();
|
---|
741 |
|
---|
742 | CoreExport void SetDefaultController(SClass_ID sid, ClassDesc *desc);
|
---|
743 | CoreExport ClassDesc *GetDefaultController(SClass_ID sid);
|
---|
744 |
|
---|
745 | CoreExport void SetDefaultColorController(ClassDesc *desc);
|
---|
746 | CoreExport void SetDefaultBoolController(ClassDesc *desc);
|
---|
747 |
|
---|
748 |
|
---|
749 |
|
---|
750 | #endif //__CONTROL__
|
---|