00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef __CH_Segment_h__
00022 #define __CH_Segment_h__
00023
00024 #include "CH_API.h"
00025 #include <iostream.h>
00026 #include <deque>
00027 #include <UT/UT_Vector3.h>
00028 #include "CH_Channel.h"
00029
00030 #define CH_EXPRESSION_CONSTANT "constant()"
00031 #define CH_EXPRESSION_BEZIER "bezier()"
00032 #define CH_EXPRESSION_LINEAR "linear()"
00033 #define CH_EXPRESSION_CUBIC "cubic()"
00034 #define CH_EXPRESSION_EASE "ease()"
00035 #define CH_EXPRESSION_EASEIN "easein()"
00036 #define CH_EXPRESSION_EASEOUT "easeout()"
00037 #define CH_EXPRESSION_SPLINE "spline()"
00038 #define CH_EXPRESSION_QLINEAR "qlinear()"
00039 #define CH_EXPRESSION_QCUBIC "qcubic()"
00040
00041 class CH_Manager;
00042 class CH_Channel;
00043 class CH_Segment;
00044 class CH_Expression;
00045 class CH_TimeGroup;
00046
00047 enum
00048 {
00049 CH_STRETCH_IN = 0x01,
00050 CH_STRETCH_OUT = 0x02
00051 };
00052
00053 class CH_API CH_SegmentFlags
00054 {
00055 public:
00056 CH_SegmentFlags()
00057 {
00058 setDefaults();
00059 }
00060 void save(ostream &os, int binary) const;
00061 bool load(UT_IStream &is);
00062
00063 unsigned getFlag() const;
00064 void parseFlag(unsigned flag);
00065 void setDefaults();
00066 unsigned isDefault() const;
00067
00068 CH_SegmentFlags &operator=(unsigned f) { parseFlag(f); return *this; }
00069 operator unsigned() { return getFlag(); }
00070
00071 unsigned isConstant:1,
00072 isBezier:1,
00073 isLinear:1,
00074 isCubic:1,
00075 isEase:1,
00076 isEaseIn:1,
00077 isEaseOut:1,
00078 isLocked:1,
00079 isSpline:1,
00080 modified:1,
00081 tieOutAccel:1,
00082 tieInAccel:1,
00083 tieOutSlope:1,
00084 tieInSlope:1,
00085 tieOutValue:1,
00086 tieInValue:1,
00087 lockEnd:1,
00088 lockStart:1,
00089 lockLength:1,
00090 isCooking:1,
00091 isQLinear:1,
00092 isQCubic:1;
00093 };
00094
00095 class CH_API CH_SegmentValues
00096 {
00097 public:
00098 float t0, t1;
00099 float iv, ov, im, om, isl, osl;
00100
00101 CH_SegmentValues() {}
00102
00103 CH_SegmentValues( CH_Segment const& seg );
00104
00105 void display();
00106 };
00107
00108 #define CH_MAX_SLOPE 1e8
00109 #define CH_MAX_ACCEL 1e8
00110
00111 class CH_API CH_Segment
00112 {
00113 public:
00114
00115
00116 CH_Segment(float defVal, CH_Channel *mom, float len = 0);
00117
00118
00119 CH_Segment(const CH_Segment &from);
00120
00121
00122
00123 CH_Segment(const char *expr, CH_ExprLanguage language, CH_Channel *mom,
00124 float len = 0);
00125
00126 ~CH_Segment();
00127
00128 CH_Manager *getManager() const { return myParent->getManager(); }
00129 float getTolerance() const { return getManager()->getTolerance(); }
00130
00131 void save(ostream &os, int binary, bool compiled,
00132 bool disabled) const;
00133 bool load(UT_IStream &is, bool disabled,
00134 bool reload=false);
00135
00136
00137
00138 CH_Segment &operator= (const CH_Segment &from);
00139 int operator==(const CH_Segment &) { return 0; }
00140
00141
00142
00143
00144
00145
00146 float evaluate(float ltime, bool extend ,
00147 int thread);
00148 void evaluateString(UT_String &result,
00149 float ltime, bool extend ,
00150 int thread);
00151
00152
00153 void unresolveLocalVars(int thread);
00154
00155 CH_Channel *getChannel(void) const { return myParent; }
00156 void setChannel(CH_Channel *chp) { myParent = chp; }
00157
00158 void setExprLanguage(CH_ExprLanguage language);
00159 CH_ExprLanguage getExprLanguage() const;
00160
00161
00162
00163
00164 CH_StringMeaning getStringMeaning();
00165
00166 int isMatchFunction(void) const;
00167 int isLockedSegment() const { return myFlags.isLocked; }
00168
00169 CH_SegmentFlags getFlags() const { return myFlags; }
00170 void lockLength(int onoff) { myFlags.lockLength = onoff; }
00171 void lockStart(int onoff) { myFlags.lockStart = onoff; }
00172 void lockEnd(int onoff) { myFlags.lockEnd = onoff; }
00173 void tieInValue(int onoff, bool dotie = true);
00174 void tieOutValue(int onoff, bool dotie = true);
00175 void tieInSlope(int onoff, bool dotie = true,
00176 float ar = 0.0 );
00177 void tieOutSlope(int onoff, bool dotie = true,
00178 float ar = 0.0 );
00179 void tieInAccel(int onoff, bool dotie = true);
00180 void tieOutAccel(int onoff, bool dotie = true);
00181
00182
00183 void cook(int state, int nsamples);
00184
00185 int isCooking() const { return myFlags.isCooking; }
00186 int isLengthLocked() const { return myFlags.lockLength; }
00187 int isStartLocked() const { return myFlags.lockStart; }
00188 int isEndLocked() const { return myFlags.lockEnd; }
00189 int isInValueTied() const { return myFlags.tieInValue; }
00190 int isOutValueTied() const { return myFlags.tieOutValue; }
00191 int isInSlopeTied() const { return myFlags.tieInSlope; }
00192 int isOutSlopeTied() const { return myFlags.tieOutSlope; }
00193 int isInAccelTied() const { return myFlags.tieInAccel; }
00194 int isOutAccelTied() const { return myFlags.tieOutAccel; }
00195 int isConstant() const { return myFlags.isConstant; }
00196 int isCubic() const { return myFlags.isCubic; }
00197 int isBezier() const { return myFlags.isBezier; }
00198 int isQLinear() const { return myFlags.isQLinear; }
00199 int isQCubic() const { return myFlags.isQCubic; }
00200 int isQuaternion() const
00201 { return isQLinear() || isQCubic(); }
00202
00203 int isInValueUsed();
00204 int isOutValueUsed();
00205 int isInSlopeUsed();
00206 int isOutSlopeUsed();
00207 int isInAccelUsed();
00208 int isOutAccelUsed();
00209 int isSplineUsed();
00210
00211
00212
00213 bool isTimeDependent() const;
00214
00215
00216
00217
00218 bool isTimeDependent(bool evaluate_to_find_out,
00219 int thread) const;
00220
00221
00222
00223
00224
00225
00226 bool isTimeDependentAndGetFloat(float &value,
00227 int thread) const;
00228
00229
00230
00231
00232
00233 bool isTimeDependentAndGetString(UT_String &value,
00234 int thread) const;
00235
00236 bool hasNonIntegerKeys() const;
00237 unsigned isDataDependent() const;
00238
00239
00240
00241
00242 int canChange(float start, float end) const;
00243 void changeLength(float len,
00244 CH_SegmentScale how=CH_SCALE_ANY,
00245 bool accel_ratio = true);
00246 void changeTimes(float s, float e);
00247
00248
00249 void stretch(float scale, int adjust_slopes,
00250 int adjust_accel);
00251
00252
00253 const char *getExpression(void) const;
00254 CH_Expression *getCHExpr(void) const {return myExpression;}
00255
00256 const UT_Vector3 *getSplineKnots(void) const { return mySplineKnots; }
00257 const UT_Vector3 *getSplineKnot(int n) const { return &mySplineKnots[n];}
00258 int getNKnots(void) const { return nKnots; }
00259
00260 bool isEndSegment() const
00261 {
00262 return myLength == CONST_FPREAL(0);
00263 }
00264 float getInValue(void) const { return inValue; }
00265 float getOutValue(void) const { return outValue; }
00266 float getInSlope(void) const { return inSlope; }
00267 float getOutSlope(void) const { return outSlope; }
00268 float getInAccel(void) const { return inAccel; }
00269 float getOutAccel(void) const { return outAccel; }
00270 fpreal getInAccelRatio() const
00271 {
00272 return getAccelRatio( inSlope, inAccel, myLength );
00273 }
00274 fpreal getOutAccelRatio() const
00275 {
00276 return getAccelRatio( outSlope, outAccel,
00277 myLength );
00278 }
00279 static fpreal getAccelRatio( float slope, float accel,
00280 float length );
00281 static fpreal getAccelFromRatio( float slope, float ratio,
00282 float length )
00283 {
00284 if( length==0.0 )
00285 length = 1.0;
00286 return length * ratio * SYSsqrt( slope*slope + 1 );
00287 }
00288
00289 CH_Segment *getNext() { return myNext; }
00290 const CH_Segment *getNext() const { return myNext; }
00291 CH_Segment *getPrev() { return myPrev; }
00292 const CH_Segment *getPrev() const { return myPrev; }
00293
00294 float getLength (void) const { return myLength; }
00295 float getILength(void) const { return myInverseLength; }
00296
00297 float getStart(void) const { return myStart; }
00298 float getEnd (void) const { return myEnd; }
00299
00300 float relativeTime(float t) const
00301 {
00302 return (t - myStart) * myInverseLength;
00303 }
00304
00305 void changeExpression(const char *expr,
00306 CH_ExprLanguage language, bool convert_accels);
00307 void changeExpression(const char *expr,
00308 CH_ExprLanguage language);
00309
00310
00311
00312
00313
00314 static bool expressionIsAnimationFunctionCall(
00315 const char *expression);
00316 bool expressionIsAnimationFunctionCall();
00317
00318 void addSplineKnot(float x, float y);
00319 void setSplineKnot(int n, float x, float y);
00320
00321
00322
00323 void setInValue(float v, bool dotie = true);
00324 void setOutValue(float v, bool dotie = true);
00325 void setInSlope(float v, bool dotie = true, float ar = 0.0);
00326 void setOutSlope(float v, bool dotie = true, float ar = 0.0);
00327 void setInAccel(float v, bool dotie = true);
00328 void setOutAccel(float v, bool dotie = true);
00329 void setInAccelRatio( float ratio, bool dotie = true )
00330 {
00331 fpreal v = getAccelFromRatio( inSlope, ratio,
00332 myLength );
00333 setInAccel( v, dotie );
00334 }
00335 void setOutAccelRatio( float ratio, bool dotie = true )
00336 {
00337 fpreal v = getAccelFromRatio( outSlope, ratio,
00338 myLength );
00339 setOutAccel( v, dotie );
00340 }
00341 void clampInAccel();
00342 void clampOutAccel();
00343 void normalizeAccels();
00344
00345 void setPrevNext(CH_Segment *p, CH_Segment *n)
00346 {
00347 myPrev = p;
00348 myNext = n;
00349 }
00350
00351
00352
00353 void setChanged();
00354
00355
00356 void reverse();
00357
00358
00359 void buildOpDependencies(void *ref_id, int thread);
00360 int changeOpRef(const char *new_fullpath,
00361 const char *old_fullpath,
00362 const char *old_cwd,
00363 const char *chan_name,
00364 const char *old_chan_name,
00365 int thread);
00366
00367 int findString(const char *str, bool fullword,
00368 bool usewildcards) const;
00369 int changeString(const char *from, const char *to,
00370 bool fullword, int thread);
00371
00372 void transferGroup(CH_Segment &from);
00373
00374 int wasModified() const { return myFlags.modified; }
00375 void setModified(int onOff);
00376
00377 void dirtyExprCache();
00378
00379 float getValue(bool left, CH_ValueTypes t) const;
00380 void setValue(bool left, CH_ValueTypes t, float value);
00381 bool getValueValid(bool left, CH_ValueTypes t);
00382 bool getValueTied(bool left, CH_ValueTypes t) const;
00383 void setValueTied(bool left, CH_ValueTypes t, bool on_off);
00384
00385 void display();
00386
00387 CH_TimeGroup *getTimeGroup(void) const { return myTimeGroup; }
00388
00389 private:
00390 void setTimeGroup(CH_TimeGroup *g, bool refresh=true);
00391
00392 void setExpression(const CH_Expression *newexpr);
00393 void checkExpression();
00394 void constructorInit(void);
00395 void isCooking(int state)
00396 { myFlags.isCooking = state; }
00397 void recook(float *values, int nsamples, int thread);
00398 void clearCache();
00399 void fillCache(int cache_start, int cache_end, int thread);
00400 void updateCacheToIncludeSample(int include_sample,
00401 int thread);
00402 float evaluateFromCache(float ltime, int thread);
00403 bool loadTimeGroups(UT_IStream &is);
00404 void saveTimeGroups(ostream &is, int binary) const;
00405
00406 void holdLastKey(float v, bool dotie);
00407
00408 void updateExprFlags();
00409
00410
00411
00412
00413 CH_SegmentFlags myFlags;
00414
00415
00416
00417
00418
00419 CH_Expression *myExpression;
00420
00421 std::deque<float> myCookedValues;
00422 int myCacheStart;
00423
00424
00425
00426 UT_Vector3 *mySplineKnots;
00427 int nKnots;
00428
00429 float inValue, outValue;
00430 float inSlope, outSlope;
00431 float inAccel, outAccel;
00432
00433 CH_TimeGroup *myTimeGroup;
00434
00435
00436
00437 float myLength;
00438 float myInverseLength;
00439
00440
00441 float myStart, myEnd;
00442
00443 CH_Channel *myParent;
00444
00445
00446
00447
00448 CH_Segment *myPrev, *myNext;
00449
00450 friend class CH_TimeGroup;
00451 };
00452
00453 #endif