home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / gfx / 3d / irit / geom_lib / animate.c next >
Encoding:
C/C++ Source or Header  |  1995-03-08  |  16.3 KB  |  522 lines

  1. /*****************************************************************************
  2. *   Animation module - machine independent part.                  *
  3. *                                         *
  4. * Written by:  Haggay Dagan, Zvika Zilberman and Gershon Elber             *
  5. *                            Ver 0.1, Feb. 1995.  *
  6. *****************************************************************************/
  7.  
  8. #ifdef USE_VARARGS
  9. #include <varargs.h>
  10. #else
  11. #include <stdarg.h>
  12. #endif /* USE_VARARGS */
  13. #include <stdio.h>
  14. #include <ctype.h>
  15. #include <math.h>
  16. #include <string.h>
  17. #include "irit_sm.h"
  18. #include "iritprsr.h"
  19. #include "attribut.h"
  20. #include "allocate.h"
  21. #include "geomat3d.h"
  22. #include "iritgrap.h"
  23. #include "animate.h"
  24.  
  25. static CagdRType *EvalCurveObject(IPObjectStruct *CrvObj, RealType t);
  26. static int IsAnimation(IPObjectStruct *PObjs);
  27. static void ExecuteAnimation(AnimationStruct *Anim, IPObjectStruct *PObjs);
  28.  
  29. /*****************************************************************************
  30. * DESCRIPTION:                                     M
  31. *   Resets the slots of an animation structure.                              M
  32. *                                         *
  33. * PARAMETERS:                                     M
  34. *   Anim:      The animation state to reset.                     M
  35. *                                         *
  36. * RETURN VALUE:                                     M
  37. *   void                                     M
  38. *                                                                            *
  39. * KEYWORDS:                                                                  M
  40. *   AnimResetAnimStruct, animation                                           M
  41. *****************************************************************************/
  42. void AnimResetAnimStruct(AnimationStruct *Anim)
  43. {
  44.     Anim -> StartT = 0.0;
  45.     Anim -> FinalT = 1.0;
  46.     Anim -> Dt = 0.01;
  47.     Anim -> RunTime = 0.0;
  48.     Anim -> TwoWaysAnimation = FALSE;
  49.     Anim -> SaveAnimation = FALSE;
  50.     Anim -> BackToOrigin = FALSE;
  51.     Anim -> NumOfRepeat = 1;
  52.     Anim -> StopAnim = FALSE;
  53.     Anim -> SingleStep = FALSE;
  54.     Anim -> TextInterface = TRUE;
  55.     Anim -> ExecEachStep = NULL;
  56.     strcpy(Anim -> BaseFileName, ANIM_DEFAULT_ANIM_FILE_NAME);
  57. }
  58.  
  59. /*****************************************************************************
  60. * DESCRIPTION:                                     M
  61. *   Getting input parameters of animation from user using textual user       M
  62. * interface.                                     M
  63. *                                         *
  64. * PARAMETERS:                                     M
  65. *   Anim:      The animation state to update.                     M
  66. *                                         *
  67. * RETURN VALUE:                                     M
  68. *   void                                     M
  69. *                                                                            *
  70. * KEYWORDS:                                                                  M
  71. *   AnimGenAnimInfoText, animation                                           M
  72. *****************************************************************************/
  73. void AnimGetAnimInfoText(AnimationStruct *Anim)
  74. {
  75.     char Line[LINE_LEN];
  76.  
  77. #ifdef DOUBLE
  78. #    define REAL_FRMT "%lf"
  79. #else
  80. #    define REAL_FRMT "%f"
  81. #endif /* DOUBLE */
  82.     do {
  83.     printf("Start time [%f] : ", Anim -> StartT);
  84.     gets(Line);
  85.     }
  86.     while (strlen(Line) > 0 &&
  87.        sscanf(Line, REAL_FRMT, &Anim -> StartT) != 1);
  88.  
  89.     do {
  90.     printf("Final time [%f] : ", Anim -> FinalT);
  91.     gets(Line);
  92.     }
  93.     while (strlen(Line) > 0 &&
  94.        sscanf(Line, REAL_FRMT, &Anim -> FinalT) != 1);
  95.  
  96.     do {
  97.     printf("Interval of time [%f] : ", Anim -> Dt);
  98.     gets(Line);
  99.     }
  100.     while (strlen(Line) > 0 &&
  101.        sscanf(Line, REAL_FRMT, &Anim -> Dt) != 1);
  102.  
  103.     printf("\nSpecial Commands (y/n) [n] : ");
  104.     gets(Line);
  105.     if (Line[0] != 'y' && Line[0] != 'Y') {
  106.         Anim -> TwoWaysAnimation = FALSE;
  107.         Anim -> SaveAnimation = FALSE;
  108.     Anim -> BackToOrigin = FALSE;
  109.         Anim -> NumOfRepeat = 1;
  110.         return;
  111.     }
  112.  
  113.     printf("Bounce Animation (y/n) [n] : ");
  114.     gets(Line);
  115.     if (Line[0] == 'y' || Line[0] == 'Y') {
  116.           Anim -> TwoWaysAnimation = TRUE;
  117.     Anim -> BackToOrigin = FALSE;
  118.     }
  119.     else {
  120.           Anim -> TwoWaysAnimation = FALSE;
  121.     printf("Back to origin (y/n) [n] : ");
  122.     gets(Line);
  123.     if (Line[0] == 'y' || Line[0] == 'Y')
  124.         Anim -> BackToOrigin = TRUE;
  125.     else
  126.         Anim -> BackToOrigin = FALSE;
  127.     }
  128.  
  129.     do {
  130.     printf("Number of repetitions [%d] : ", Anim -> NumOfRepeat);
  131.     gets(Line);
  132.     }
  133.     while (strlen(Line) > 0 &&
  134.        sscanf(Line, "%d", &Anim -> NumOfRepeat) != 1);
  135.     Anim -> NumOfRepeat = MAX(Anim -> NumOfRepeat, 1);
  136.  
  137.     printf("Save iterations into data files (y/n) [n] : ");
  138.     gets(Line);
  139.     if (Line[0] == 'y' || Line[0] == 'Y') {
  140.         Anim -> SaveAnimation = TRUE; 
  141.     do {
  142.         printf("Base name of data files : ");
  143.         gets(Line);
  144.     }
  145.     while (strlen(Line) > 0 &&
  146.            sscanf(Line, "%s", Anim -> BaseFileName) != 1 &&
  147.            strlen(Anim -> BaseFileName) <= 0);
  148.     } 
  149.     else
  150.     Anim -> SaveAnimation = FALSE;
  151. }
  152.  
  153. /*****************************************************************************
  154. * DESCRIPTION:                                          *
  155. *   Evaluate curve in specified parameter value and project it to Euclidean  *
  156. * space, if necessary.                                 *
  157. *                                         *
  158. * PARAMETERS:                                     *
  159. *   CrvObj:    a pointer to the curve's object.                 *
  160. *   t:        the parameter of time to calculate the value of the curve.   * 
  161. *                                         *
  162. * RETURN VALUE:                                     *
  163. *   CagdRType *: The value(s) of the curve at t.                 *
  164. *****************************************************************************/
  165. static CagdRType *EvalCurveObject(IPObjectStruct *CrvObj, RealType t)
  166. {
  167.     int i;
  168.     CagdRType
  169.     *Pt = CagdCrvEval(CrvObj -> U.Crvs, t);
  170.  
  171.     switch (CrvObj -> U.Crvs -> PType)  {
  172.         case CAGD_PT_E1_TYPE:
  173.         case CAGD_PT_E3_TYPE:
  174.              break;
  175.         case CAGD_PT_P1_TYPE:
  176.          Pt[1] /= Pt[0];
  177.          break;
  178.         case CAGD_PT_P3_TYPE:
  179.              for (i = 1; i <= 3; i++)
  180.               Pt[i] /= Pt[0];
  181.          break;
  182.          default:
  183.          break;
  184.     }
  185.     return Pt;
  186. }
  187.  
  188.  
  189. /*****************************************************************************
  190. * DESCRIPTION:                                     *
  191. *   Scan the given geometry for possible animation attributes.             *
  192. *                                         *
  193. * PARAMETERS:                                     *
  194. *   PObjs:      Objects to scan for animation attributes.             *
  195. *                                         *
  196. * RETURN VALUE:                                     *
  197. *   int:    TRUE if there are animation attributes. FALSE otherwise.     *
  198. *****************************************************************************/
  199. static int IsAnimation(IPObjectStruct *PObjs)
  200. {
  201.     IPObjectStruct *PObj;
  202.  
  203.     for (PObj = PObjs; PObj != NULL; PObj = PObj -> Pnext)
  204.         if (AttrGetObjectObjAttrib(PObj, "animation") != NULL)
  205.         return TRUE; 
  206.  
  207.     return FALSE;   
  208. }
  209.  
  210. /*****************************************************************************
  211. * DESCRIPTION:                                     M
  212. *   Computes the time span for which the animation executes.             M
  213. *                                         *
  214. * PARAMETERS:                                     M
  215. *   Anim:    Animation structure to update.                     M
  216. *   PObjs:      Objects to scan for animation attributes.             M
  217. *                                         *
  218. * RETURN VALUE:                                     M
  219. *   void                                     M
  220. *                                                                            *
  221. * KEYWORDS:                                                                  M
  222. *   AnimFindAnimationTime, animation                                         M
  223. *****************************************************************************/
  224. void AnimFindAnimationTime(AnimationStruct *Anim, IPObjectStruct *PObjs)
  225. {
  226.     IPObjectStruct *PObj, *ObjPtr, *AnimationP;
  227.     RealType T1, T2, StartT, FinalT;
  228.  
  229.     StartT = INFINITY;
  230.     FinalT = -INFINITY;
  231.     for (PObj = PObjs; PObj != NULL; PObj = PObj -> Pnext) {
  232.         if ((AnimationP = AttrGetObjectObjAttrib(PObj, "animation")) != NULL) {
  233.         int i = 0;
  234.  
  235.         if (IP_IS_OLST_OBJ(AnimationP)) {
  236.         while ((ObjPtr = ListObjectGet(AnimationP, i++)) != NULL) {
  237.             if (IP_IS_CRV_OBJ(ObjPtr)) {
  238.             CagdCrvDomain(ObjPtr -> U.Crvs, &T1, &T2);
  239.             StartT = MIN(StartT, T1);
  240.             FinalT = MAX(FinalT, T2);
  241.             }
  242.         }
  243.         }
  244.         else if (IP_IS_CRV_OBJ(AnimationP)) {
  245.         CagdCrvDomain(AnimationP -> U.Crvs, &T1, &T2);
  246.         StartT = MIN(StartT, T1);
  247.         FinalT = MAX(FinalT, T2);
  248.         }
  249.     }
  250.     }
  251.  
  252.     if (StartT < INFINITY)
  253.     Anim -> RunTime = Anim -> StartT = StartT;
  254.     if (FinalT > -INFINITY)
  255.     Anim -> FinalT = FinalT;
  256. }
  257.  
  258. /*****************************************************************************
  259. * DESCRIPTION:                                     *
  260. *   executes one time step of the animation.                      *
  261. *                                         *
  262. * PARAMETERS:                                     *
  263. *   Anim:    Animation structure.                         *
  264. *   PObjs:    Objects to render.                         *
  265. *                                         *
  266. * RETURN VALUE:                                     *
  267. *   void                                      *
  268. *****************************************************************************/
  269. static void ExecuteAnimation(AnimationStruct *Anim, IPObjectStruct *PObjs)
  270. {
  271.     IPObjectStruct *AnimationP, *PObj, *ObjPtr;
  272.     MatrixType ObjMat, Mat;
  273.     int i, NeedToMult;
  274.  
  275.     if (Anim -> TextInterface) {
  276.     printf("\b\b\b\b\b\b\b%7.3f", Anim -> RunTime);
  277.     fflush(stdout);
  278.     }
  279.  
  280.     for ( ; PObjs != NULL && !Anim -> StopAnim; PObjs = PObjs -> Pnext) {
  281.         MatGenUnitMat(ObjMat);
  282.         
  283.         if ((AnimationP = AttrGetObjAttrib(PObjs -> Attrs, "animation"))
  284.                                 != NULL) {
  285.         i = 0;
  286.             while (IP_IS_OLST_OBJ(AnimationP) ?
  287.            (PObj = ListObjectGet(AnimationP, i++)) != NULL :
  288.            (PObj = (i++ == 0 ? AnimationP : NULL)) != NULL) {
  289.         CagdRType *CurveResult, CurveRes, TMin, TMax, t;
  290.         char
  291.             *Name = PObj -> Name; 
  292.  
  293.         AttrSetObjectIntAttrib(PObjs, "_isvisible", TRUE);
  294.  
  295.         NeedToMult = TRUE;
  296.           switch (PObj -> ObjType) {
  297.                      case IP_OBJ_MATRIX:
  298.                  GEN_COPY(Mat, *PObj -> U.Mat, sizeof(MatrixType)); 
  299.                         break;
  300.                     case IP_OBJ_CURVE :
  301.                 CagdCrvDomain(PObj -> U.Crvs, &TMin, &TMax);
  302.  
  303.                         t = Anim -> RunTime;
  304.                         if (t < TMin)
  305.                 t = TMin;
  306.                         else if (t > TMax)
  307.                 t = TMax;
  308.  
  309.                         CurveResult = EvalCurveObject(PObj, t); 
  310.                         CurveRes = CurveResult[1];
  311.             if (strnicmp(Name, "scl", 3) == 0) {
  312.                     if (stricmp(Name, "scl") == 0) 
  313.                     MatGenMatUnifScale(CurveRes, Mat);
  314.                 else if (stricmp(Name, "scl_x") == 0)
  315.                     MatGenMatScale(CurveRes, 1, 1, Mat);
  316.                 else if (stricmp(Name, "scl_y") == 0)
  317.                     MatGenMatScale(1, CurveRes, 1, Mat);
  318.                 else if (stricmp(Name, "scl_z") == 0)
  319.                     MatGenMatScale(1, 1, CurveRes, Mat);
  320.             }
  321.                 else if (strnicmp(Name, "rot", 3) == 0) {
  322.                 if (stricmp(Name, "rot_x") == 0)
  323.                 MatGenMatRotX1(-DEG2RAD(CurveRes), Mat );
  324.                 else if (stricmp(Name, "rot_y") == 0)
  325.                 MatGenMatRotY1(-DEG2RAD(CurveRes), Mat);
  326.                 else if (stricmp(Name, "rot_z") == 0)
  327.                 MatGenMatRotZ1(-DEG2RAD(CurveRes), Mat);
  328.             }
  329.             else if (strnicmp(Name, "mov", 3) == 0) {
  330.                 if (stricmp(Name, "mov_x") == 0)
  331.                     MatGenMatTrans(CurveRes, 0, 0, Mat);
  332.                 else if (stricmp(Name, "mov_y") == 0)
  333.                     MatGenMatTrans(0, CurveRes, 0, Mat);
  334.                 else if (stricmp(Name, "mov_z") == 0)
  335.                     MatGenMatTrans(0, 0, CurveRes, Mat);
  336.                 else if (stricmp(Name, "mov_xyz") == 0)
  337.                 MatGenMatTrans(CurveResult[1],
  338.                            CurveResult[2],
  339.                            CurveResult[3],
  340.                            Mat);
  341.             }
  342.             else if (stricmp(Name, "visible") == 0) { 
  343.                 NeedToMult = FALSE;
  344.                    if (CurveRes < 0)
  345.                 AttrSetObjectIntAttrib(PObjs,
  346.                                "_isvisible", FALSE); 
  347.             }
  348.                         break;
  349.                     default:
  350.             NeedToMult = FALSE;
  351.             fprintf(stderr,
  352.                 "Only matrices and curves are supported in animation, name = \"%s\"\n",
  353.                 Name);
  354.                 break;
  355.         }
  356.         if (NeedToMult)
  357.             MatMultTwo4by4(ObjMat, ObjMat, Mat);
  358.         }
  359.     }
  360.  
  361.           ObjPtr = GenMatObject("transform", ObjMat, NULL);
  362.           AttrSetObjAttrib(&PObjs -> Attrs, "_animation_mat", ObjPtr, FALSE);
  363.  
  364.           if (AnimCheckInterrupt(Anim))
  365.         break;
  366.     }
  367.  
  368.     IGRedrawViewWindow();
  369. }
  370.  
  371. /*****************************************************************************
  372. * DESCRIPTION:                                     M
  373. *   Routine to run a sequence of objects through an animation according to   M
  374. * animation attributes of matrices and curves that are attached to them.     M
  375. *                                          *
  376. * PARAMETERS:                                     M
  377. *   Anim:    Animation structure.                         M
  378. *   PObjs:    Objects to render.                         M
  379. *                                         *
  380. * RETURN VALUE:                                     M
  381. *   void.                                     M
  382. *                                         *
  383. * KEYWORDS:                                     M
  384. *   AnimDoAnimation, animation                             M
  385. *****************************************************************************/
  386. void AnimDoAnimation(AnimationStruct *Anim, IPObjectStruct *PObjs)
  387.     int Loops;
  388.  
  389.     Anim -> StopAnim = FALSE;
  390.  
  391.     if (!IsAnimation(PObjs)) {          /* Checking if there is any animation */ 
  392.         fprintf(stderr, "No animation attributes were found.");
  393.         return;
  394.     }
  395.  
  396.     if (Anim -> TextInterface) {
  397.     printf("Animate from %f to %f step %f\n",
  398.            Anim -> StartT, Anim -> FinalT, Anim -> Dt);
  399.     printf("\nAnimation time:        ");
  400.     }
  401.  
  402.     Anim -> _Count = 1;
  403.     for (Loops = 1; Loops <= Anim -> NumOfRepeat; Loops++) {
  404.         for (Anim -> RunTime = Anim -> StartT;
  405.          Anim -> RunTime <= Anim -> FinalT + EPSILON &&
  406.          !Anim -> StopAnim;
  407.          Anim -> RunTime += Anim -> Dt) {
  408.             ExecuteAnimation(Anim, PObjs);
  409.         if (Loops == 1) {
  410.         if (Anim -> SaveAnimation)
  411.             AnimSaveIterationsToFiles(Anim, PObjs);
  412.         else if (Anim -> ExecEachStep != NULL) {
  413.             char Line[LINE_LEN];
  414.  
  415.             sprintf(Line, "%s %d",
  416.                 Anim -> ExecEachStep, Anim -> _Count++);
  417.             system(Line);
  418.         }
  419.         }
  420.     }
  421.  
  422.         if (Anim -> TwoWaysAnimation) 
  423.         for (Anim -> RunTime = Anim -> FinalT;
  424.          Anim -> RunTime >= Anim -> StartT - EPSILON &&
  425.          !Anim -> StopAnim;
  426.          Anim -> RunTime -= Anim -> Dt)
  427.              ExecuteAnimation(Anim, PObjs);
  428.     }
  429.  
  430.     if (Anim -> BackToOrigin && !APX_EQ(Anim -> RunTime, Anim -> StartT)) {
  431.     Anim -> RunTime = Anim -> StartT;
  432.     ExecuteAnimation(Anim, PObjs);
  433.     }
  434.  
  435.     if (Anim -> TextInterface) {
  436.     printf("\n\nAnimation is done.\n");
  437.     fflush(stdout);
  438.     }
  439. }
  440.  
  441. /*****************************************************************************
  442. * DESCRIPTION:                                     M
  443. *   Routine to exectue a single step the animation, at current time.         M
  444. *                                          *
  445. * PARAMETERS:                                     M
  446. *   Anim:    Animation structure.                         M
  447. *   PObjs:    Objects to render.                         M
  448. *                                         *
  449. * RETURN VALUE:                                     M
  450. *   void.                                     M
  451. *                                         *
  452. * KEYWORDS:                                     M
  453. *   AnimDoSingleStep, animation                             M
  454. *****************************************************************************/
  455. void AnimDoSingleStep(AnimationStruct *Anim, IPObjectStruct *PObjs)
  456.     Anim -> StopAnim = FALSE;
  457.  
  458.     if (!IsAnimation(PObjs)) {          /* Checking if there is any animation */ 
  459.         fprintf(stderr, "No animation attributes were found.");
  460.         return;
  461.     }
  462.  
  463.     ExecuteAnimation(Anim, PObjs);
  464. }
  465.  
  466. /*****************************************************************************
  467. * DESCRIPTION:                                     M
  468. *   Saves one iteration of the animation sequence as IRIT data (*.dat).      M
  469. *   The objects that are saved are those that are visibled on the current    M
  470. * time frame as set via current animation_mat attribute.                 M
  471. *                                         *
  472. * PARAMETERS:                                     M
  473. *   Anim:    Animation structure.                         M
  474. *   PObjs:    Objects to render.                         M
  475. *                                         *
  476. * RETURN VALUE:                                     M
  477. *   void                                     M
  478. *                                         *
  479. * KEYWORDS:                                     M
  480. *   AnimSaveIterationsToFiles, animation                     M
  481. *****************************************************************************/
  482. void AnimSaveIterationsToFiles(AnimationStruct *Anim, IPObjectStruct *PObjs)
  483. {
  484.     IPObjectStruct *MatObj, *PObj;
  485.     int Handler;
  486.     char FileName[LINE_LEN];
  487.  
  488.     sprintf(FileName, "%s%03d.dat", Anim -> BaseFileName, Anim -> _Count++);
  489.     Handler = IritPrsrOpenDataFile(FileName, FALSE, TRUE);
  490.  
  491.     for (PObj = PObjs; PObj != NULL; PObj = PObj -> Pnext) {
  492.     if ((MatObj = AttrGetObjectObjAttrib(PObj, "_animation_mat")) != NULL &&
  493.             IP_IS_MAT_OBJ(MatObj) &&
  494.         AttrGetObjectIntAttrib(PObj, "_isvisible")) {
  495.         IPObjectStruct *CopyObj, *CopyTObj;
  496.  
  497.         CopyObj = CopyObject(NULL, PObj, TRUE);
  498.         AttrFreeOneAttribute(&CopyObj -> Attrs, "animation");
  499.         CopyObj -> Pnext = NULL;
  500.         CopyTObj = GMTransformObject(CopyObj, *MatObj -> U.Mat);
  501.  
  502.         IritPrsrPutObjectToHandler(Handler, CopyTObj);
  503.  
  504.         IPFreeObject(CopyObj);
  505.         IPFreeObject(CopyTObj);
  506.     }
  507.     }
  508.  
  509.     PObj = GenMatObject("view_mat", IritPrsrViewMat, NULL);
  510.     IritPrsrPutObjectToHandler(Handler, PObj);
  511.     IPFreeObject(PObj);
  512.     if (IGGlblViewMode == IG_VIEW_PERSPECTIVE) {
  513.     PObj = GenMatObject("prsp_mat", IritPrsrPrspMat, NULL);
  514.     IritPrsrPutObjectToHandler(Handler, PObj);
  515.         IPFreeObject(PObj);
  516.     }
  517.  
  518.     IritPrsrCloseStream(Handler, TRUE); 
  519. }
  520.