home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / WIREVIEW.LZH / ANIM.CPP next >
C/C++ Source or Header  |  1996-07-10  |  11KB  |  388 lines

  1. #include <owl\owlpch.h>
  2. #pragma hdrstop
  3.  
  4. #include <owl\scrollba.h>
  5. #include <owl\inputdia.h>
  6. #include <owl\opensave.h>
  7. #include <owl\slider.h>
  8. #include <owl\statusba.h>
  9. #include <owl\gadget.h>
  10. #include <owl\textgadg.h>
  11. #include <dir.h>
  12. #include "matrix.h"
  13. #include "anim.h"
  14. #include "view.h"
  15. #include "winframe.h"
  16. #include "mecha.h"
  17. #include "suflib.h"
  18. #include "bezier.h"
  19. #include "motion.h"
  20. #include "files.h"
  21. #include "syscolor.h"
  22. #include "polyline.h"
  23. #include "log.h"
  24.  
  25. AnimationData::AnimationData()
  26. {
  27.  
  28.     Frame = NULL;
  29.     PersView = NULL;
  30.  
  31.     getcwd(filedir, filenamedirlength);
  32.     filename[0] = '\0';
  33.     motion = NULL;
  34.     camera = NULL;
  35.     wireframe = NULL;
  36.     InitMotion();
  37. }
  38.  
  39. void AnimationData::CalcViewMatrix(void)
  40. {
  41.     int fx, fy;
  42.  
  43.     fx = PersView->Attr.W;
  44.     fy = PersView->Attr.H;
  45.  
  46.     Matrix cmat;
  47. //    cmat = camera->GetMatrix(selectframe).inv();
  48.     camera->GetPosition(selectframe);
  49.     cmat = (Matrix::m_move(camera->position).rot(camera->rotation)).inv();
  50.  
  51. //logprintf("camera=\n");
  52. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
  53. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
  54. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
  55.  
  56.     Matrix tmpmat(0);
  57.     tmpmat.v[0].z = tmpmat.v[1].x = tmpmat.v[2].y = 1.0;
  58.     cmat = tmpmat * cmat;
  59.  
  60. //logprintf("trans=\n");
  61. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
  62. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
  63. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
  64.  
  65.     tmpmat = Matrix(1);
  66.     tmpmat.v[2].x = double(fx)/2.0;
  67.     tmpmat.v[2].y = double(fy)/2.0;
  68.     tmpmat.v[0].x = - fx / 2.0 / tan(camera->angle/2.0);
  69.     tmpmat.v[1].y = tmpmat.v[0].x;
  70.     cmat = tmpmat * cmat;
  71.  
  72. //logprintf("viewmat=\n");
  73. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].x, cmat.v[1].x, cmat.v[2].x, cmat.v[3].x);
  74. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].y, cmat.v[1].y, cmat.v[2].y, cmat.v[3].y);
  75. //logprintf("%+07.3lf %+07.3lf %+07.3lf %+07.3lf\n", cmat.v[0].z, cmat.v[1].z, cmat.v[2].z, cmat.v[3].z);
  76.  
  77.  
  78.     viewmat = cmat;
  79. }
  80.  
  81. void AnimationData::CalcView(Motion *mot)
  82. {
  83.     mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  84. }
  85.  
  86. void AnimationData::CalcViewAll(void)
  87. {
  88.     CalcViewMatrix();
  89.     for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  90.         mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  91.     }
  92. }
  93.  
  94. void AnimationData::SelectFrame(int frame)
  95. {
  96.     if (frame < BEGIN || frame > maxframe || selectframe == frame) {
  97.         return;
  98.     }
  99.     selectframe = frame;
  100.     frameCounter->SetPosition(selectframe);
  101. }
  102.  
  103.  
  104. static void split(char *dir, char *name, char *all)
  105. {
  106.     char *p;
  107.     strcpy(dir, all);
  108.     if ((p = strrchr(dir, '\\')) != NULL) {
  109.         *p = '\0';
  110.         strcpy(name, p+1);
  111.     } else if ((p = strrchr(dir, '/')) != NULL) {
  112.         *p = '\0';
  113.         strcpy(name, p+1);
  114.     } else {
  115.         dir[0] = '\0';
  116.         strcpy(name, all);
  117.     }
  118. }
  119.  
  120. void AnimationData::ReadFile(char *fname)
  121. {
  122.     if (Frame != NULL) Frame->KillTimer(OpPlay);
  123.     if (Frame != NULL) Frame->KillTimer(OpPause);
  124.     Motion *nm;
  125.     Motion *next;
  126.     CameraMotion *nc;
  127.     Vector v;
  128.     char nfiledir[_MAX_PATH], nfilename[_MAX_PATH];
  129.     split(nfiledir, nfilename, fname);
  130.     int max;
  131.     if ((max = Motion::FileRead(nm, nc, v, fname)) >= 0) {
  132.         strcpy(filedir, nfiledir);
  133.         strcpy(filename, nfilename);
  134.         for (Motion *m = motion; m != NULL; m = next) {
  135.             next = m->next;
  136.             delete m;
  137.         }
  138.         delete camera;
  139.         motion = nm;
  140.         camera = nc;
  141.         maxframe = max;
  142.         opstat = OpPause;
  143.         SelectFrame(BEGIN);
  144.         SetCaption();
  145.         wireframe = new WireFrame[maxframe - BEGIN + 1];
  146.         if (frameCounter != NULL) {
  147.             frameCounter->SetRange(BEGIN, maxframe);
  148.             frameCounter->SetRuler(10);
  149.         }
  150.         for (int i = BEGIN; i <= maxframe; ++i) {
  151.             wireframe[i-BEGIN].line = NULL;
  152.         }
  153.         opstat = OpPlay;
  154. //        if (Frame != NULL) Frame->SetTimer(OpPause, 1000);
  155.         if (Frame != NULL) Frame->SetTimer(OpPlay, 300);
  156.     }
  157. //    if (Frame != NULL) Frame->SetTimer(OpPlay, 66);
  158. }
  159.  
  160.  
  161. void AnimationData::InitMotion(void)
  162. {
  163.     if (Frame != NULL) Frame->KillTimer(OpPlay);
  164.     if (Frame != NULL) Frame->KillTimer(OpPause);
  165.     Motion *next, *m;
  166.     for (m = motion; m != NULL; m = next) {
  167.         next = m->next;
  168.         delete m;
  169.     }
  170.     FreeWireFrame();
  171.  
  172.     filename[0] = '\0';
  173.  
  174.     opstat = OpPause;
  175.     maxframe = BEGIN;
  176.     motion = NULL;
  177.     selectframe = BEGIN;
  178.  
  179.     Motion *target = new Motion(NULL, BEGIN, maxframe);
  180.  
  181.     if (camera != NULL) {
  182.         delete camera->target;
  183.         delete camera;
  184.     }
  185.     camera = new CameraMotion(target, maxframe);
  186.     camera->position = Vector(8000,6000,6000);
  187.     camera->GetPosition(BEGIN);
  188.  
  189.     viewmat = Matrix(0);
  190. }
  191.  
  192. void AnimationData::NewFile(void)
  193. {
  194.     InitMotion();
  195.     SetCaption();
  196. }
  197.  
  198. int AnimationData::GetMotionName(char *filename)
  199. {
  200.     char str[128];
  201.     strcpy(str, motiondir.c_str());
  202.     str[strlen(str)-1] = '\0';
  203.     TOpenSaveDialog::TData FileData(
  204.                             OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
  205.                             "モーションデザインファイル(*.frm)|*.frm|"
  206.                             "すべてのファイル(*.*)|*.*|",
  207.                             0, str, "fsc");
  208.     TFileOpenDialog OpenDlg(Frame, FileData);
  209.  
  210.     if (OpenDlg.Execute() == IDOK) {
  211.         strcpy(filename, FileData.FileName);
  212.         return TRUE;
  213.     } else {
  214.         filename[0] = '\0';
  215.         return FALSE;
  216.     }
  217. }
  218.  
  219. void AnimationData::SetCaption(void)
  220. {
  221.     TApplication *app = PersView->GetApplication();
  222.     TWindow *frame = app->GetMainWindow();
  223.     if (filename[0]) {
  224.         char str[_MAX_PATH];
  225.         sprintf(str, "%s - %s", app->GetName(), filename);
  226.         frame->SetCaption(str);
  227.     } else {
  228.         frame->SetCaption(app->GetName());
  229.     }
  230. }
  231.  
  232. int AnimationData::GetLinesNoBackFace(int frame, LineSegment **tmpline, PolyData *polydata)
  233. {
  234.     int W = PersView->Attr.W;
  235.     int H = PersView->Attr.H;
  236.     Motion *mot;
  237.     polydata->Init(W,H);
  238.     for (mot = motion; mot != NULL; mot = mot->next) {
  239.         if (mot->beginframe <= frame && frame <= mot->endframe) {
  240.             int inverseflag = FALSE;
  241.             if (mot->scale.x < 0) inverseflag = !inverseflag;
  242.             if (mot->scale.y < 0) inverseflag = !inverseflag;
  243.             if (mot->scale.z < 0) inverseflag = !inverseflag;
  244.  
  245.             int offp;
  246.             offp = polydata->points;
  247.             for (int i = 0; i < mot->mecha->points; ++i) {
  248.                 polydata->point[i+offp].x = mot->view_x[i];
  249.                 polydata->point[i+offp].y = mot->view_y[i];
  250.                 polydata->point[i+offp].z = mot->view_z[i];
  251.             }
  252.             polydata->points += mot->mecha->points;
  253.             for (i = 0; i < mot->mecha->polys; ++i) {
  254.                 int *pid = mot->mecha->polypoint + mot->mecha->poly[i];
  255.                 PolyPoint *p1 = &polydata->point[pid[0]+offp];
  256.                 PolyPoint *p2 = &polydata->point[pid[1]+offp];
  257.                 PolyPoint *p3 = &polydata->point[pid[2]+offp];
  258.                 long m = (long)(p1->x-p2->x)*(long)(p3->y-p2->y) - (long)(p1->y-p2->y)*(long)(p3->x-p2->x);
  259.                 if (inverseflag && m <= 0) {
  260.                    polydata->AddPolyInv(mot->mecha->polypoint + mot->mecha->poly[i], offp);
  261.                 } else if (!inverseflag && m >= 0) {
  262.                    polydata->AddPoly(mot->mecha->polypoint + mot->mecha->poly[i], offp);
  263.                 }
  264.             }
  265.         }
  266.     }
  267.     polydata->ConvertLines();
  268.     int lines = 0;
  269.     for (int i = 0; i < polydata->lines; ++i) {
  270.         if (polydata->line[i].p1 >= 0
  271.          && polydata->line[i].p2 >= 0) {
  272.             PolyPoint &p1 = polydata->point[polydata->line[i].p1];
  273.             PolyPoint &p2 = polydata->point[polydata->line[i].p2];
  274.             if (p1.z > 0 && p2.z > 0
  275.              && ((p1.x != p2.x) || (p1.y != p2.y))
  276.              && (p1.x >= 0 || p2.x >= 0)
  277.              && (p1.x <  W || p2.x <  W)
  278.              && (p1.y >= 0 || p2.y >= 0)
  279.              && (p1.y <  H || p2.y <  H)) {
  280.                 lines++;
  281.             }
  282.         }
  283.     }
  284.  
  285.     int l = 0;
  286.     *tmpline = new LineSegment[lines];
  287.     for (i = 0; i < polydata->lines; ++i) {
  288.         if (polydata->line[i].p1 >= 0 && polydata->line[i].p2 >= 0) {
  289.             PolyPoint &p1 = polydata->point[polydata->line[i].p1];
  290.             PolyPoint &p2 = polydata->point[polydata->line[i].p2];
  291.             if (p1.z > 0 && p2.z > 0
  292.              && ((p1.x != p2.x) || (p1.y != p2.y))
  293.              && (p1.x >= 0 || p2.x >= 0)
  294.              && (p1.x <  W || p2.x <  W)
  295.              && (p1.y >= 0 || p2.y >= 0)
  296.              && (p1.y <  H || p2.y <  H)) {
  297.                 (*tmpline)[l].x1 = (short)p1.x;
  298.                 (*tmpline)[l].y1 = (short)p1.y;
  299.                 (*tmpline)[l].x2 = (short)p2.x;
  300.                 (*tmpline)[l].y2 = (short)p2.y;
  301.                 l++;
  302.             }
  303.         }
  304.     }
  305.     return l;
  306. }
  307.  
  308. int AnimationData::GetLines(int frame, LineSegment *tmpline)
  309. {
  310.     int l = 0;
  311.     int W = PersView->Attr.W;
  312.     int H = PersView->Attr.H;
  313.     Motion *mot;
  314.     for (mot = motion; mot != NULL; mot = mot->next) {
  315.         if (mot->beginframe <= frame && frame <= mot->endframe) {
  316.             for (int i = 0; i < mot->lines; ++i) {
  317.                 if (mot->view_z[mot->line_1[i]] > 0 && mot->view_z[mot->line_2[i]] > 0) {
  318.                     tmpline[l].x1 = (short)mot->view_x[mot->line_1[i]];
  319.                     tmpline[l].y1 = (short)mot->view_y[mot->line_1[i]];
  320.                     tmpline[l].x2 = (short)mot->view_x[mot->line_2[i]];
  321.                     tmpline[l].y2 = (short)mot->view_y[mot->line_2[i]];
  322.                     if ((tmpline[l].x1 <  0 && tmpline[l].x2 <  0)
  323.                      || (tmpline[l].x1 >= W && tmpline[l].x2 >= W)
  324.                      || (tmpline[l].y1 <  0 && tmpline[l].y2 <  0)
  325.                      || (tmpline[l].y1 >= H && tmpline[l].y2 >= H)) {
  326.                     } else {
  327.                         l++;
  328.                     }
  329.                 }
  330.             }
  331.         }
  332.     }
  333.     return l;
  334. }
  335.  
  336. void AnimationData::BuildWireFrame(int frame)
  337. {
  338.     if (wireframe[frame-BEGIN].line != NULL) {
  339.         delete [] wireframe[frame-BEGIN+1].line;
  340.     }
  341.     int maxlines = 0;
  342.     int maxpolys = 0;
  343.     int maxpoints = 0;
  344.     int maxpolypoints = 0;
  345.     for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  346.         maxpoints += mot->mecha->points;
  347.         maxlines += mot->lines;
  348.         maxpolys += mot->mecha->polys;
  349.         maxpolypoints += mot->mecha->polypoints;
  350.     }
  351.     PolyData polydata(maxpoints, maxlines, maxpolys, maxpolypoints);
  352.  
  353.     SelectFrame(frame);
  354.     CalcViewAll();
  355.     int l = GetLinesNoBackFace(frame, &wireframe[frame-BEGIN].line, &polydata);
  356.     wireframe[frame-BEGIN].lines = l;
  357. }
  358.  
  359. void AnimationData::FreeWireFrame(void)
  360. {
  361.     if (wireframe != NULL) {
  362.         for (int i = 0; wireframe[i].line!= NULL; ++i) {
  363.             delete [] wireframe[i].line;
  364.         }
  365.         delete [] wireframe;
  366.     }
  367.     wireframe = NULL;
  368. }
  369.  
  370. void AnimationData::Resize(int x, int y, int ox, int oy)
  371. {
  372.     if (wireframe != NULL) {
  373.         for (int i = BEGIN; i <= maxframe; ++i) {
  374.             LineSegment *line = wireframe[i-BEGIN].line;
  375.             if (line != NULL) {
  376.                 for (int l = wireframe[i-BEGIN].lines; l > 0; --l) {
  377.                     line->x1 = (short)((long)line->x1 * (long)x / (long)ox);
  378.                     line->y1 = (short)((long)line->y1 * (long)y / (long)oy);
  379.                     line->x2 = (short)((long)line->x2 * (long)x / (long)ox);
  380.                     line->y2 = (short)((long)line->y2 * (long)y / (long)oy);
  381.                     line++;
  382.                 }
  383.             }
  384.         }
  385.         playmode = PmTimer;
  386.     }
  387. }
  388.