home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / MEDIT.LZH / MOTIONRW.CPP < prev    next >
C/C++ Source or Header  |  1996-07-12  |  13KB  |  439 lines

  1. #include <iostream.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include "matrix.h"
  5. #include "bezier.h"
  6. #include "motion.h"
  7. #include "mecha.h"
  8. #include "token.h"
  9. #include "files.h"
  10.  
  11. #include "log.h"
  12.  
  13. static Vector readvector(TokenReader& reader, char *str)
  14. {
  15.     Vector vec(0,0,0);
  16.     if (                             str[0] != '(') return vec;
  17.     if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
  18.     if (sscanf(str, "%lf", &(vec.x)) == 0)          return vec;
  19.     if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
  20.     if (sscanf(str, "%lf", &(vec.y)) == 0)          return vec;
  21.     if (reader.GetToken(str) == 0 || str[0] == ')') return vec;
  22.     if (sscanf(str, "%lf", &(vec.z)) == 0)          return vec;
  23.     if (reader.GetToken(str) == 0 || str[0] != ')') return vec;
  24.     return vec;
  25. }
  26.  
  27. static int readheader(TokenReader& reader, int& begin, int& end, Vector& light, char *token)
  28. {
  29.     reader.GetLine(token);
  30.     reader.GetLine(token);
  31.     reader.GetToken(token);
  32.     if (strcmpi(token, "Frame:") != 0) {
  33.         return FALSE;
  34.     }
  35.     reader.GetToken(token); begin = atoi(token);
  36.     reader.GetToken(token); end  = atoi(token);
  37.     if (begin < 0 || end < begin) {
  38.         return FALSE;
  39.     }
  40.  
  41.     light = Vector(-3.0, -2.0, -4.0);
  42.     light *= (1.0/light.length());
  43.  
  44.     while (reader.GetToken(token)) {
  45.         if (strcmpi(token, "Light:") == 0) {
  46.             reader.GetToken(token);
  47.             if (token[0] == '(') {
  48.                 Vector v = readvector(reader, token);
  49.                 if (v.length() != 0.0) {
  50.                     light = (1.0 / v.length()) * v;
  51.                 }
  52.             }
  53.         }
  54.         if (strcmpi(token, "Motion:") == 0) {
  55.             return TRUE;
  56.         }
  57.     }
  58.     return FALSE;
  59. }
  60.  
  61. Motion *Motion::ReadMotion(TokenReader& reader, char *token, int defaultbegin, int defaultend)
  62. {
  63.     if (strcmpi(token, "Motion:") != 0) return NULL;
  64.     reader.GetToken(token);
  65.     reader.GetToken(token);
  66.  
  67.     if (strcmpi(token, "Mechanic:") != 0)  return NULL;
  68.     char filename[120]; reader.GetToken(filename);
  69.     reader.GetToken(token);
  70.     Mechanic *mec = NULL;
  71.     if (strcmpi(filename, "CAMERA") != 0
  72.      && strcmpi(filename, "NONE") != 0
  73.      && strcmpi(filename, "なし") != 0
  74.      && strcmpi(filename, "TARGET") != 0) {
  75.         mec = MechaFile::OpenMechanic(filename);
  76.     }
  77.  
  78.     int begin, end;
  79.     if (strcmpi(token, "Frame:") == 0) {
  80.         reader.GetToken(token); begin = atoi(token);
  81.         reader.GetToken(token); end   = atoi(token);
  82.         if (begin < 0 || end < begin) return NULL;
  83.         reader.GetToken(token);
  84.     } else {
  85.         begin = defaultbegin;
  86.         end = defaultend;
  87.     }
  88.     if (strcmpi(token, "Bezier:") != 0) return NULL;
  89.     reader.GetToken(token);
  90.  
  91.     if (token[0] != '(') return NULL;
  92.     Vector v = readvector(reader, token);
  93.     Bezier *b = new Bezier(v);
  94.     reader.GetToken(token);
  95.     while (token[0] == '(') {
  96.         Vector v1 = readvector(reader, token);
  97.         if (reader.GetToken(token) == 0 || token[0] != '(') break;
  98.         Vector v2 = readvector(reader, token);
  99.         if (reader.GetToken(token) == 0 || token[0] != '(') break;
  100.         Vector v3 = readvector(reader, token);
  101.         b->AddPoint(v1, v2, v3);
  102.  
  103.  
  104.         if (reader.GetToken(token) == 0) break;
  105.     }
  106.     if (b->points > 0) {
  107.         b->point[b->points*3+1] = 2.0 * b->point[b->points*3] - b->point[b->points*3-1];
  108.     } else {
  109.         b->point[1] = b->point[0];
  110.     }
  111.     b->UpdateLength();
  112.  
  113.     Motion *m;
  114.     MotionData *md = NULL;
  115.     if (b->points == 0) {
  116.         m = new Motion(mec, begin, end, NULL);
  117.         m->position = b->point[0];
  118.         delete b;
  119.     } else {
  120.         m = new Motion(mec, begin, end, b);
  121.         md = m->motiondata;
  122.         md->dirtype = DirLinear;
  123.     }
  124.  
  125.     if (strcmpi(token, "Position:") == 0) {
  126.         reader.GetToken(token);
  127.         int count = 0;
  128.         while (isdigit(token[0])) {
  129.             double speed;
  130.             if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
  131.             if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
  132.             if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
  133.             sscanf(token, "%lf", &speed);
  134.             if (md != NULL && count < 2) {
  135.                 md->speed[count++] = speed;
  136.             }
  137.             if (reader.GetToken(token) == 0) break;
  138.         }
  139.     }
  140.     if (strcmpi(token, "Direction:") == 0) {
  141.         int count = 0;
  142.         reader.GetToken(token);
  143.         while (isdigit(token[0])) {
  144.             if (reader.GetToken(token) == 0) break;
  145.             if (token[0] == '(') {
  146.                 Vector v = readvector(reader, token);
  147.                 if (reader.GetToken(token) == 0 || !isdigit(token[0])) break;
  148.                 if (md == NULL && count == 0) {
  149.                     m->rotation = deg(1.0) * v;
  150.                     count++;
  151.                 } else if (md != NULL && count < 2) {
  152.                     md->rotation[count++] = deg(1.0) * v;
  153.                 }
  154.                 if (reader.GetToken(token) == 0) break;
  155.                 if (strcmpi(token, "Forward") == 0) {
  156.                     if (md != NULL) {
  157.                         md->dirtype = DirForward;
  158.                     }
  159.                     if (reader.GetToken(token) == 0) break;
  160.                 }
  161.             } else {
  162.                 break;
  163.             }
  164.         }
  165.     }
  166.     if (strcmpi(token, "Scale:") == 0) {
  167.         int count = 0;
  168.         reader.GetToken(token);
  169.         while (isdigit(token[0])) {
  170.             Vector v;
  171.             if (reader.GetToken(token) == 0 || token[0] != '(') break;
  172.             v = readvector(reader, token);
  173.             if (md == NULL && count == 0) {
  174.                 m->scale = v;
  175.                 count++;
  176.             } else if (md != NULL && count < 2) {
  177.                 md->scale[count++] = v;
  178.             }
  179.             if (reader.GetToken(token) == 0) break;
  180.         }
  181.     }
  182.     return m;
  183. }
  184.  
  185. int Motion::FileRead(Motion* &motion, CameraMotion* &camera, Vector& light, char *filename)
  186. {
  187.     char token[128];
  188.     TokenReader reader(filename);
  189.     if (!reader.Suceed()) {
  190.         return -1;
  191.     }
  192.     int begin, end;
  193.     if (readheader(reader, begin, end, light, token) == FALSE) {
  194.         return -1;
  195.     }
  196.  
  197.     Motion *m = Motion::ReadMotion(reader, token, begin, end);
  198.     if (m == NULL) {
  199.         return -1;
  200.     }
  201.     Motion *mt = Motion::ReadMotion(reader, token, begin, end);
  202.     if (mt == NULL) {
  203.         return -1;
  204.     }
  205.     camera = new CameraMotion(m, mt);
  206.     delete m;
  207.  
  208.     motion = NULL;
  209.     while ((m = Motion::ReadMotion(reader, token, begin, end)) != NULL) {
  210.         m->next = motion;
  211.         motion = m;
  212.     }
  213.     return end;
  214. }
  215.  
  216. void Motion::FileWriteList(Motion* motion, FILE *fp)
  217. {
  218.     fprintf(fp, "Mechanic:\n");
  219.     for (Motion *m = motion; m != NULL; m = m->next) {
  220.         for (Motion *om = motion; om != m && om != NULL; om = om->next) {
  221.             if (om->mecha == m->mecha) {
  222.                 break;
  223.             }
  224.         }
  225.         if (m->mecha != NULL && (om == m || om == NULL)) {
  226.             char str[120], *f;
  227.             f = m->mecha->filename;
  228.             if (strncmpi(m->mecha->filename, mechadir.c_str(), mechadir.length()) == 0) {
  229.                 f = m->mecha->filename + mechadir.length();
  230.             }
  231.             strcpy(str, f);
  232.             int l = strlen(str);
  233.             if (l > 4 && str[l-4] == '.') {
  234.                 str[l-4] = '\0';
  235.             }
  236.             fprintf(fp, "\t%s\n", str);
  237.         }
  238.     }
  239. }
  240.  
  241. void Motion::GetName(char *str)
  242. {
  243.     if (mecha != NULL) {
  244.         strcpy(str, mecha->name);
  245.         int l = strlen(str);
  246.         if (l > 4 && str[l-4] == '.') {
  247.             str[l-4] = '\0';
  248.         }
  249.     } else {
  250.         strcpy(str, "なし");
  251.     }
  252. }
  253.  
  254. void CameraMotion::GetName(char *str)
  255. {
  256.     strcpy(str, "CAMERA\n");
  257. }
  258.  
  259. void Motion::MotionWrite(FILE *fp)
  260. {
  261.     int i;
  262.     fprintf(fp, "Motion: 0\n");
  263.     char *f;
  264.     if (mecha == NULL) {
  265.         f = "NONE";
  266.     } else {
  267.         f = mecha->filename;
  268.         if (strncmpi(mecha->filename, mechadir.c_str(), mechadir.length()) == 0) {
  269.             f = mecha->filename + mechadir.length();
  270.         }
  271.     }
  272.     fprintf(fp, "\tMechanic: %s\n", f);
  273.     fprintf(fp, "\tFrame: %d %d\n", beginframe, endframe);
  274.     if (motiondata == NULL) {
  275.         fprintf(fp, "\tBezier:\n");
  276.         fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", position.x, position.y, position.z);
  277.         fprintf(fp, "\tPosition:\n");
  278.         fprintf(fp, "\tDirection:\n");
  279.         fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", beginframe, rad(rotation.x), rad(rotation.y), rad(rotation.z));
  280.         fprintf(fp, "\tScale:\n");
  281.         fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", beginframe, scale.x, scale.y, scale.z);
  282.     } else {
  283.         fprintf(fp, "\tBezier:\n");
  284.         Bezier *bezier = motiondata->bezier;
  285.         for (i = 0; i < bezier->points*3+1; ++i) {
  286.             fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
  287.         }
  288.         fprintf(fp, "\tPosition:\n");
  289.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, motiondata->speed[0]);
  290.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe,   bezier->TotalLength(), 0, motiondata->speed[1]);
  291.         fprintf(fp, "\tDirection:\n");
  292.         if (motiondata->dirtype == DirForward) {
  293.             fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0 Forward\n", beginframe,
  294.                 rad(motiondata->rotation[0].x),
  295.                 rad(motiondata->rotation[0].y),
  296.                 rad(motiondata->rotation[0].z));
  297.         } else {
  298.             fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", beginframe,
  299.                 rad(motiondata->rotation[0].x),
  300.                 rad(motiondata->rotation[0].y),
  301.                 rad(motiondata->rotation[0].z));
  302.             fprintf(fp, "\t\t%3d ( %5.0lf %5.0lf %5.0lf ) 0\n", endframe,
  303.                 rad(motiondata->rotation[1].x),
  304.                 rad(motiondata->rotation[1].y),
  305.                 rad(motiondata->rotation[1].z));
  306.         }
  307.         fprintf(fp, "\tScale:\n");
  308.         fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", beginframe,
  309.                 motiondata->scale[0].x,
  310.                 motiondata->scale[0].y,
  311.                 motiondata->scale[0].z);
  312.         fprintf(fp, "\t\t%3d ( %5.3lf %5.3lf %5.3lf )\n", endframe,
  313.                 motiondata->scale[1].x,
  314.                 motiondata->scale[1].y,
  315.                 motiondata->scale[1].z);
  316.     }
  317. }
  318.  
  319. void CameraMotion::MotionWrite(FILE *fp)
  320. {
  321.     int i;
  322.     fprintf(fp, "Motion: 0\n");
  323.     fprintf(fp, "\tMechanic: CAMERA\n");
  324.     fprintf(fp, "\tBezier:\n");
  325.     if (motiondata == NULL) {
  326.         fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", position.x, position.y, position.z);
  327.     } else {
  328.         Bezier *bezier = motiondata->bezier;
  329.         for (i = 0; i < bezier->points*3+1; ++i) {
  330.             fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
  331.         }
  332.         fprintf(fp, "\tPosition:\n");
  333.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, motiondata->speed[0]);
  334.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe,   bezier->TotalLength(), 0, motiondata->speed[1]);
  335.     }
  336.  
  337.     fprintf(fp, "Motion: 0\n");
  338.     fprintf(fp, "\tMechanic: TARGET\n");
  339.     fprintf(fp, "\tBezier:\n");
  340.     if (motiondata == NULL) {
  341.         fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", target->position.x, target->position.y, target->position.z);
  342.     } else {
  343.         Bezier *bezier = target->motiondata->bezier;
  344.         for (i = 0; i < bezier->points*3+1; ++i) {
  345.             fprintf(fp, "\t\t( %5.0lf %5.0lf %5.0lf )\n", bezier->point[i].x, bezier->point[i].y, bezier->point[i].z);
  346.         }
  347.         fprintf(fp, "\tPosition:\n");
  348.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", beginframe, 0.0, 0, target->motiondata->speed[0]);
  349.         fprintf(fp, "\t\t%3d %5.0lf %d %5.0lf\n", endframe,   bezier->TotalLength(), 0, target->motiondata->speed[1]);
  350.     }
  351. }
  352.  
  353. void Motion::PoseWrite(int frame, FILE *fp)
  354. {
  355.     if (frame < beginframe || frame > endframe || mecha == NULL) {
  356.         return;
  357.     }
  358.     GetPosition(frame);
  359.  
  360.     char n[120];
  361.     GetName(n);
  362.     fprintf(fp,
  363.             "\t{\tmov ( %8.1lf %8.1lf %8.1lf ) "
  364.             "rotz( %7.3lf ) roty( %7.3lf ) rotx( %7.3lf ) "
  365.             "scal ( %5.3lf %5.3lf %5.3lf ) obj %8s "
  366.             "}\n",
  367.         position.x, position.y, position.z,
  368.         rad(rotation.z), rad(rotation.y), rad(rotation.x),
  369.         scale.x, scale.y, scale.z, n);
  370. }
  371.  
  372. void CameraMotion::PoseWrite(int frame, FILE *fp)
  373. {
  374.     GetPosition(frame);
  375.     fprintf(fp,
  376.             "\t{\tmov ( %5.0lf %5.0lf %5.0lf ) "
  377.             "rotz( %7.3lf ) roty( %7.3lf ) rotx( %7.3lf ) "
  378.             "eye deg ( %d ) }\n",
  379.         position.x, position.y, position.z,
  380.         rad(rotation.z), rad(rotation.y), rad(rotation.x),
  381.         int(rad(angle)+0.5)
  382.         );
  383. }
  384.  
  385. int Motion::FileWrite(Motion* motion, CameraMotion* camera, Vector& light, char *filename)
  386. {
  387.  
  388.     FILE *fp;
  389.     errormessage[0] = '\0';
  390.     if ((fp = fopen(filename, "w")) == NULL) {
  391.         sprintf(errormessage, "モーションファイルの保存に失敗しました : %s", _sys_errlist[errno]);
  392.         return FALSE;
  393.     }
  394.     Motion *m;
  395.     int maxframe = camera->endframe;
  396.     for (m = motion; m != NULL; m = m->next) {
  397.         if (maxframe < m->endframe) {
  398.             maxframe = m->endframe;
  399.         }
  400.     }
  401.  
  402.     fprintf(fp,
  403.         "/*                            Motion Editor\n"
  404.         "                                  Version 1.00γ\n"
  405.         "Frame: %d %d\n", BEGIN, maxframe);
  406.  
  407.     FileWriteList(motion, fp);
  408.     fprintf(fp, "Light: ( %4.0lf %4.0lf %4.0lf )\n",
  409.             100.0 * light.x, 100.0 * light.y, 100.0 * light.z);
  410.  
  411.     camera->MotionWrite(fp);
  412.     for (m = motion; m != NULL; m = m->next) {
  413.         if (m != camera && m != camera->target) {
  414.             m->MotionWrite(fp);
  415.         }
  416.     }
  417.     fprintf(fp, "*/\n");
  418.     for (int i = BEGIN; i <= maxframe; ++i) {
  419.         fprintf(fp, "fram\n{\n"
  420.                     "\tlight pal( rgb ( 1.00 1.00 1.00 ) %4.0lf %4.0lf %4.0lf)\n",
  421.                     100.0 * light.x, 100.0 * light.y, 100.0 * light.z);
  422.         camera->PoseWrite(i, fp);
  423.         for (m = motion; m != NULL; m = m->next) {
  424.             if (m != camera) {
  425.                 m->PoseWrite(i, fp);
  426.             }
  427.         }
  428.         fprintf(fp, "}\n");
  429.     }
  430.     if (ferror(fp)) {
  431.         sprintf(errormessage, "モーションファイルの保存に失敗しました : %s", _sys_errlist[errno]);
  432.         fclose(fp);
  433.         return FALSE;
  434.     }
  435.     fclose(fp);
  436.     return TRUE;
  437. }
  438.  
  439.