home *** CD-ROM | disk | FTP | other *** search
/ DOS/V Power Report 1997 March / VPR9703A.ISO / VPR_DATA / DOGA / SOURCES / MEDIT.LZH / ANIM.CPP < prev    next >
C/C++ Source or Header  |  1996-07-18  |  30KB  |  1,157 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 <stdio.h>
  12. #include <dir.h>
  13. #include "matrix.h"
  14. #include "anim.h"
  15. #include "display.h"
  16. #include "status.h"
  17. #include "pers.h"
  18. #include "winframe.h"
  19. #include "mecha.h"
  20. #include "bezier.h"
  21. #include "motion.h"
  22. #include "files.h"
  23. #include "timebar.h"
  24. #include "drange.h"
  25. #include "syscolor.h"
  26. #include "polyline.h"
  27. #include "bmpopen.h"
  28. #include "log.h"
  29.  
  30. const double scalemax = (1/8.0);
  31. const double scalemin = (1/256.0);
  32. const double scalerate = 1.414213562373;
  33.  
  34. AnimationData::AnimationData()
  35. {
  36.  
  37.     Frame = NULL;
  38.     FrontView = SideView = TopView = NULL;
  39.     PersView = NULL;
  40.     Status = NULL;
  41.     scrollX = scrollY = scrollZ = NULL;
  42.     frameCounter = 0;
  43.     for (int i = 0; i < buttons; ++i) {
  44.         button[i] = NULL;
  45.     }
  46.     button_ok = button_cancel = NULL;
  47.     statusbar = NULL;
  48.     statusbar_time = NULL;
  49.     drawflag = SelNone;
  50.  
  51.     HelpState = FALSE;
  52.  
  53.     ViewType[0] = SelX;
  54.     ViewType[1] = SelY;
  55.     ViewType[2] = SelZ;
  56.  
  57.     hiddenremove = FALSE;
  58.  
  59.     meshflag = TRUE;
  60.     meshspacing = 2500;
  61.  
  62.     gridflag = TRUE;
  63.     gridspacing = 500;
  64.     rotspacing = 10;
  65.     scalespacing = (int)(0.1 * scalespacingfactor);
  66.  
  67.     getcwd(filedir, filenamedirlength);
  68.     filename[0] = '\0';
  69.     strcpy(lastopenmechadir, mechadir.c_str());
  70.  
  71.     drawmode = DrawWire;
  72.  
  73.     motion = select = camera = NULL;
  74.  
  75.     wireframe.line = NULL;
  76.     wireframe.lines = 0;
  77.  
  78.     InitMotion();
  79. }
  80.  
  81. void AnimationData::SetScrollLimit(int flag)
  82. {
  83.     int WX = TopView->Attr.W;
  84.     int WY = TopView->Attr.H;
  85.     int WZ = SideView->Attr.H;
  86.  
  87.     int lx = limitdim/scrollstep - (WX/2) / displayscale / scrollstep;
  88.     int ly = limitdim/scrollstep - (WY/2) / displayscale / scrollstep;
  89.     int lz = limitdim/scrollstep - (WZ/2) / displayscale / scrollstep;
  90.     scrollX->SetRange(-lx, lx);
  91.     scrollY->SetRange(-ly, ly);
  92.     scrollZ->SetRange(-lz, lz);
  93.  
  94.     scrollX->PageMagnitude = WX / displayscale / scrollstep;
  95.     scrollX->LineMagnitude = (scrollX->PageMagnitude+7) / 8;
  96.     scrollY->PageMagnitude = WY / displayscale / scrollstep;
  97.     scrollY->LineMagnitude = (scrollY->PageMagnitude+7) / 8;
  98.     scrollZ->PageMagnitude = WZ / displayscale / scrollstep;
  99.     scrollZ->LineMagnitude = (scrollZ->PageMagnitude+7) / 8;
  100.  
  101.     if (flag) {
  102.         scrollX->SetPosition(-displayoffset.x / displayscale / scrollstep);
  103.         scrollY->SetPosition(displayoffset.y / displayscale / scrollstep);
  104.         scrollZ->SetPosition(displayoffset.z / displayscale / scrollstep);
  105.     }
  106.  
  107.     if (-displayoffset.x / displayscale / scrollstep < -lx) {
  108.         displayoffset.x =  lx * displayscale * scrollstep;
  109.         scrollX->SetPosition(-lx);
  110.     } else if (-displayoffset.x / displayscale / scrollstep> lx) {
  111.         displayoffset.x = -lx * displayscale * scrollstep;
  112.         scrollX->SetPosition(lx);
  113.     }
  114.     if (displayoffset.y / displayscale / scrollstep < -ly) {
  115.         displayoffset.y = -ly * displayscale * scrollstep;
  116.         scrollX->SetPosition(-ly);
  117.     } else if (displayoffset.y / displayscale / scrollstep> ly) {
  118.         displayoffset.y =  ly * displayscale * scrollstep;
  119.         scrollX->SetPosition(ly);
  120.     }
  121.     if (displayoffset.z / displayscale / scrollstep< -lz) {
  122.         displayoffset.z = -lz * displayscale * scrollstep;
  123.         ;scrollX->SetPosition(-lz);
  124.     } else if (displayoffset.z / displayscale / scrollstep> lz) {
  125.         displayoffset.z =  lz * displayscale * scrollstep;
  126.         scrollX->SetPosition(lz);
  127.     }
  128.     if (zoomflag == FALSE) {
  129.         scrollX->Show(SW_HIDE); scrollX->Show(SW_SHOW);
  130.         scrollY->Show(SW_HIDE); scrollY->Show(SW_SHOW);
  131.         scrollZ->Show(SW_HIDE); scrollZ->Show(SW_SHOW);
  132.     }
  133.  
  134. }
  135.  
  136. void AnimationData::ScaleUp(void)
  137. {
  138.     if (displayscale * scalerate <= scalemax) {
  139.         displayscale *= scalerate;
  140.         displayoffset *= scalerate;
  141.  
  142.         SetScrollLimit();
  143.  
  144.         CalcPointsAll();
  145.         Redraw();
  146.     }
  147. }
  148.  
  149. void AnimationData::ScaleDown(void)
  150. {
  151.     if (displayscale / scalerate >= scalemin) {
  152.         displayscale /= scalerate;
  153.         displayoffset *= (1.0/scalerate);
  154.  
  155.         SetScrollLimit();
  156.  
  157.         CalcPointsAll();
  158.         Redraw();
  159.     }
  160. }
  161.  
  162. int AnimationData::ScaleUpLimitCheck(void)
  163. {
  164.     return displayscale <= scalemax/scalerate;
  165. }
  166.  
  167. int AnimationData::ScaleDownLimitCheck(void)
  168. {
  169.     return displayscale >= scalemin*scalerate;
  170. }
  171.  
  172. void AnimationData::DeleteMotion(Motion *m)
  173. {
  174.     if (m == NULL || m == camera || m == camera->target) {
  175.         return;
  176.     }
  177.     for (Motion *mt = motion; mt != NULL; mt = mt->next) {
  178.         if (mt->next == m) {
  179.             mt->next = m->next;
  180.             break;
  181.         }
  182.     }
  183.     if (motion == m) {
  184.         motion = m->next;
  185.     }
  186.     SelectMotion(NULL);
  187.     Redraw();
  188.     delete m;
  189.     editflag++;
  190. }
  191.  
  192. void AnimationData::CopyMotion(Motion *m)
  193. {
  194.     if (m == NULL || m == camera || m == camera->target) {
  195.         return;
  196.     }
  197.     Motion *nm = new Motion(*m);
  198.     nm->next = motion;
  199.     motion = nm;
  200.  
  201.     Vector wh(TopView->Attr.W, TopView->Attr.H, 0);
  202.     wh *= (1.0/displayscale/8.0);
  203.     if (nm->motiondata == NULL) {
  204.         nm->position += wh;
  205.     } else {
  206.         for (int i = 0; i < nm->motiondata->bezier->points*3+2; ++i) {
  207.             nm->motiondata->bezier->point[i] += wh;
  208.         }
  209.     }
  210.     nm->GetPosition(selectframe);
  211.     CalcPoints(nm);
  212.     SelectMotion(nm);
  213.     Redraw();
  214.     editflag++;
  215. }
  216.  
  217. void AnimationData::AddMotion(Mechanic *m, Bezier *b)
  218. {
  219.     int begin = BEGIN, end = maxframe;
  220.     Motion *mot;
  221.     if (b->points == 0) {
  222.         mot = new Motion(m, begin, end);
  223.         mot->position = b->point[0];
  224.     } else {
  225.         mot = new Motion(m, begin, end, b);
  226.     }
  227.     mot->next = motion;
  228.     motion = mot;
  229.  
  230.     mot->GetPosition(selectframe);
  231.     CalcPoints(mot);
  232.     SelectMotion(mot);
  233.     editflag++;
  234. }
  235.  
  236.  
  237. int AnimationData::GetMechaName(char *filename)
  238. {
  239. #if 0
  240.     char str[filenamedirlength];
  241.     strcpy(str, mechadir.c_str());
  242.     str[strlen(str)-1] = '\0';
  243. #endif
  244.     OpModeDefault();
  245. #if 0
  246.     TOpenSaveDialog::TData FileData(
  247.                             OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
  248.                             "メカデザインファイル(*.fsc)|*.fsc|"
  249.                             "すべてのファイル(*.*)|*.*|",
  250.                             0, lastopenmechadir, "fsc");
  251.     TFileOpenDialog OpenDlg(Frame, FileData);
  252.     if (OpenDlg.Execute() == IDOK) {
  253.         strcpy(filename, FileData.FileName);
  254.         return TRUE;
  255.     } else {
  256.         filename[0] = '\0';
  257.         return FALSE;
  258.     }
  259. #else
  260.     if (FileOpenDialogWithBMP(Frame, filename,
  261.                             OFN_FILEMUSTEXIST | OFN_HIDEREADONLY,
  262.                             "メカデザインファイル(*.fsc)|*.fsc|"
  263.                             "すべてのファイル(*.*)|*.*|",
  264.                             0, lastopenmechadir, "fsc") == IDOK) {
  265.  
  266.         if (filename[0] && filename[1] == ':' && filename[2] == '\\') {
  267.             char *p;
  268.             strcpy(lastopenmechadir, filename);
  269.             if ((p = strrchr(lastopenmechadir, '\\')) != NULL) {
  270.                 *p = '\0';
  271.             }
  272.         }
  273.         return TRUE;
  274.     } else {
  275.         filename[0] = '\0';
  276.         return FALSE;
  277.     }
  278. #endif
  279. }
  280.  
  281. static inline void engrid(Vector& v, int grid)
  282. {
  283.     if (v.x > 0) {
  284.         v.x =  (double)( ((long)( v.x) + grid/2) / grid) * (double) grid;
  285.     } else {
  286.         v.x = -(double)( ((long)(-v.x) + grid/2) / grid) * (double) grid;
  287.     }
  288.     if (v.y > 0) {
  289.         v.y =  (double)( ((long)( v.y) + grid/2) / grid) * (double) grid;
  290.     } else {
  291.         v.y = -(double)( ((long)(-v.y) + grid/2) / grid) * (double) grid;
  292.     }
  293.     if (v.z > 0) {
  294.         v.z =  (double)( ((long)( v.z) + grid/2) / grid) * (double) grid;
  295.     } else {
  296.         v.z = -(double)( ((long)(-v.z) + grid/2) / grid) * (double) grid;
  297.     }
  298. }
  299.  
  300. void AnimationData::AddMechanicFix(char *filename)
  301. {
  302.     OpModeDefault();
  303.  
  304.     Mechanic *mec;
  305.     char str[_MAX_PATH];
  306.     if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
  307.         strcpy(str, mechadir.c_str());
  308.         strcat(str, filename);
  309.         if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
  310.             Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
  311.             return;
  312.         }
  313.     }
  314.     Bezier *bezier = new Bezier();
  315.     Vector v((-1.0/displayscale) * displayoffset);
  316.  
  317.     if (gridflag) {
  318.         engrid(v, gridspacing);
  319.     }
  320.  
  321.     bezier->AddPoint(v, v);
  322.  
  323.     AddMotion(mec, bezier);
  324.     Redraw();
  325. }
  326.  
  327. void AnimationData::AddMechanicMove(char *filename)
  328. {
  329.     OpModeDefault();
  330.  
  331.     Mechanic *mec;
  332.     char str[_MAX_PATH];
  333.     if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
  334.         strcpy(str, mechadir.c_str());
  335.         strcat(str, filename);
  336.         if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
  337.             Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
  338.             return;
  339.         }
  340.     }
  341.  
  342.     Bezier *bezier = new Bezier();
  343.     Vector v0((-1.0/displayscale) * displayoffset);
  344.     Vector v1(1.0/displayscale * TopView->Attr.W / 3.0, 0.0, 0.0);
  345.     Vector va(v0-v1), vb(v0+v1);
  346.     if (gridflag) {
  347.         engrid(va, gridspacing);
  348.         engrid(vb, gridspacing);
  349.     }
  350.     bezier->AddPoint(va, va+(2.0/3.0)*v1);
  351.     bezier->AddPoint(vb, vb+(2.0/3.0)*v1);
  352.     AddMotion(mec, bezier);
  353.     Redraw();
  354. }
  355.  
  356. void AnimationData::ExchangeMechanic(char *filename)
  357. {
  358.     if (select == NULL || select == camera || select == camera->target) {
  359.         return;
  360.     }
  361.     OpModeDefault();
  362.  
  363.     Mechanic *mec;
  364.     char str[_MAX_PATH];
  365.     if ((mec = MechaFile::OpenMechanic(filename)) == NULL) {
  366.         strcpy(str, mechadir.c_str());
  367.         strcat(str, filename);
  368.         if ((mec = MechaFile::OpenMechanic(str)) == NULL) {
  369.             Frame->MessageBox("メカを読み込めませんでした。", Frame->GetApplication()->GetName(), MB_OK);
  370.             return;
  371.         }
  372.     }
  373.  
  374.     select->SetMech(mec);
  375.     CalcPoints(select);
  376.     editflag++;
  377.     Redraw();
  378. }
  379.  
  380. void AnimationData::Redraw(SelectType t, int flag)
  381. {
  382.     if (flag) {
  383.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  384.             mot->GetPosition(selectframe);
  385.             CalcPoints(mot);
  386.         }
  387.         camera->GetPosition(selectframe);
  388.         CalcPoints(camera);
  389.         BuildWireFrame(selectframe);
  390.     } else {
  391.         if (wireframe.line == NULL) {
  392.             BuildWireFrame(selectframe);
  393.         }
  394.     }
  395.  
  396.     if (t & SelZ)     TopView->Redraw();
  397.     if (t & SelY)     SideView->Redraw();
  398.     if (t & SelX)    FrontView->Redraw();
  399.     if (t & SelPers) PersView->Redraw();
  400.     if (t & SelStat) Status->Redraw();
  401.  
  402.     if (opstat == OpLight) {
  403.         if (t & SelZ)    TopView->ShowLight(org_point, TRUE);
  404.         if (t & SelY)    SideView->ShowLight(org_point, TRUE);
  405.         if (t & SelX)    FrontView->ShowLight(org_point, TRUE);
  406.         if (t & SelPers)PersView->ShowLight(org_point, TRUE);
  407.         return;
  408.     } else if (opstat == OpPlay) {
  409.         return;
  410.     } else if (drawmode == DrawPlaneObject) {
  411.         if (select == camera || select == camera->target) {
  412.             if ((camera->motiondata == NULL && camera->beginframe <= selectframe && selectframe <= camera->endframe)
  413.              || selectframe == camera->beginframe
  414.              || selectframe == camera->endframe) {
  415.                 Matrix m = GetCubeMatrix(camera);
  416.                 if (t & SelZ)     TopView->ShowCamera(m, TRUE);
  417.                 if (t & SelY)     SideView->ShowCamera(m, TRUE);
  418.                 if (t & SelX)    FrontView->ShowCamera(m, TRUE);
  419.              }
  420.          }
  421.         return;
  422.     }
  423.  
  424.     if (select == camera || select == camera->target) {
  425.         if ((camera->motiondata == NULL && camera->beginframe <= selectframe && selectframe <= camera->endframe)
  426.          || selectframe == camera->beginframe
  427.          || selectframe == camera->endframe) {
  428.             Matrix m = GetCubeMatrix(camera);
  429.             if (t & SelZ)     TopView->ShowCamera(m, TRUE);
  430.             if (t & SelY)     SideView->ShowCamera(m, TRUE);
  431.             if (t & SelX)    FrontView->ShowCamera(m, TRUE);
  432.          }
  433.     } else if (select != NULL) {
  434.         if ((select->motiondata == NULL && select->beginframe <= selectframe && selectframe <= select->endframe)
  435.          || selectframe == select->beginframe
  436.          || selectframe == select->endframe) {
  437.             SelectType nt[3];
  438.             Matrix m = GetCubeMatrix(select);
  439.             SelectAxis(nt, m);
  440.             if (t & SelZ)     TopView->ShowCube(m, TRUE, nt[0]);
  441.             if (t & SelY)     SideView->ShowCube(m, TRUE, nt[1]);
  442.             if (t & SelX)    FrontView->ShowCube(m, TRUE, nt[2]);
  443.         }
  444.     }
  445. }
  446.  
  447.  
  448. void AnimationData::DrawBezier(Bezier *bezier)
  449. {
  450.     FrontView->DrawBezier(bezier);
  451.     SideView->DrawBezier(bezier);
  452.     TopView->DrawBezier(bezier);
  453. }
  454.  
  455. void AnimationData::ShowCube(Matrix& omat, Matrix& nmat)
  456. {
  457.     if (select == camera || select == camera->target) {
  458.         TopView->ShowCamera(omat, FALSE);
  459.         TopView->ShowCamera(nmat, FALSE);
  460.         SideView->ShowCamera(omat, FALSE);
  461.         SideView->ShowCamera(nmat, FALSE);
  462.         FrontView->ShowCamera(omat, FALSE);
  463.         FrontView->ShowCamera(nmat, FALSE);
  464.     } else {
  465.         TopView->ShowCube(omat, FALSE, SelNone);
  466.         TopView->ShowCube(nmat, FALSE, SelNone);
  467.         SideView->ShowCube(omat, FALSE, SelNone);
  468.         SideView->ShowCube(nmat, FALSE, SelNone);
  469.         FrontView->ShowCube(omat, FALSE, SelNone);
  470.         FrontView->ShowCube(nmat, FALSE, SelNone);
  471.     }
  472. }
  473.  
  474. void AnimationData::ShowLight(Vector& ovec, Vector& nvec)
  475. {
  476.     TopView->ShowLight(ovec, FALSE);
  477.     TopView->ShowLight(nvec, FALSE);
  478.     SideView->ShowLight(ovec, FALSE);
  479.     SideView->ShowLight(nvec, FALSE);
  480.     FrontView->ShowLight(ovec, FALSE);
  481.     FrontView->ShowLight(nvec, FALSE);
  482.     PersView->ShowLight(ovec, FALSE);
  483.     PersView->ShowLight(nvec, FALSE);
  484. }
  485.  
  486. Matrix AnimationData::GetMatrix(Motion *mot, int frame)
  487. {
  488.     return Matrix::m_move(displayoffset).scale(displayscale) * mot->GetMatrix(frame);
  489. }
  490.  
  491. Matrix AnimationData::GetMatrix(Motion *mot)
  492. {
  493.     return Matrix::m_move(displayoffset).scale(displayscale) * mot->GetMatrix(selectframe);
  494. }
  495.  
  496. void AnimationData::GetCubeMatrix(Motion *mot, Matrix& move, Matrix& rot, Matrix& scal)
  497. {
  498.     double maxx, maxy, maxz;
  499.     const int minimumsize = markersize * 8;
  500.     maxx = maxy = maxz = 1;
  501.     if (mot == camera) {
  502.         maxy = tan(camera->angle/2.0);
  503.         maxz = maxy * 3 / 4;
  504.     } else {
  505.         Mechanic *mecha = mot->mecha;
  506.         if (mecha != NULL) {
  507.             if (mecha->maxx > -mecha->minx) {
  508.                 maxx = mecha->maxx;
  509.             } else {
  510.                 maxx = -mecha->minx;
  511.             }
  512.             if (mecha->maxy > -mecha->miny) {
  513.                 maxy = mecha->maxy;
  514.             } else {
  515.                 maxy = -mecha->miny;
  516.             }
  517.             if (mecha->maxz > -mecha->minz) {
  518.                 maxz = mecha->maxz;
  519.             } else {
  520.                 maxz = -mecha->minz;
  521.             }
  522.         }
  523.     }
  524.     mot->GetMatrix(move, rot, scal, selectframe);
  525.     move = Matrix::m_move(displayoffset).scale(displayscale) * move;
  526.     scal = scal.scale(maxx, maxy, maxz);
  527.     if (mot != camera) {
  528.         if (scal.v[0].x > 0.0) {
  529.             if (scal.v[0].x <  minimumsize/displayscale) scal.v[0].x =  minimumsize/displayscale;
  530.         } else {
  531.             if (scal.v[0].x > -minimumsize/displayscale) scal.v[0].x = -minimumsize/displayscale;
  532.         }
  533.         if (scal.v[1].y > 0.0) {
  534.             if (scal.v[1].y <  minimumsize/displayscale) scal.v[1].y =  minimumsize/displayscale;
  535.         } else {
  536.             if (scal.v[1].y > -minimumsize/displayscale) scal.v[1].y = -minimumsize/displayscale;
  537.         }
  538.         if (scal.v[2].z > 0.0) {
  539.             if (scal.v[2].z <  minimumsize/displayscale) scal.v[2].z =  minimumsize/displayscale;
  540.         } else {
  541.             if (scal.v[2].z > -minimumsize/displayscale) scal.v[2].z = -minimumsize/displayscale;
  542.         }
  543.     }
  544. }
  545.  
  546. Matrix AnimationData::GetCubeMatrix(Motion *mot)
  547. {
  548.     Matrix m,r,s;
  549.     GetCubeMatrix(mot, m, r, s);
  550.     return m * r * s;
  551. }
  552.  
  553. void AnimationData::CalcViewMatrix(void)
  554. {
  555.     int fx, fy;
  556.  
  557.     fx = PersView->Attr.W;
  558.     fy = PersView->Attr.H;
  559.  
  560.     Matrix cmat;
  561. //    cmat = camera->GetMatrix(selectframe).inv();
  562.     cmat = (Matrix::m_move(camera->position).rot(camera->rotation)).inv();
  563.  
  564.     Matrix tmpmat(0);
  565.     tmpmat.v[0].z = tmpmat.v[1].x = tmpmat.v[2].y = 1.0;
  566.     cmat = tmpmat * cmat;
  567.  
  568.     tmpmat = Matrix(1);
  569.     tmpmat.v[2].x = double(fx)/2.0;
  570.     tmpmat.v[2].y = double(fy)/2.0;
  571.     tmpmat.v[0].x = - fx / 2.0 / tan(camera->angle/2.0);
  572.     tmpmat.v[1].y = tmpmat.v[0].x;
  573.     cmat = tmpmat * cmat;
  574.  
  575.     viewmat = cmat;
  576. }
  577.  
  578. void AnimationData::CalcView(Motion *mot)
  579. {
  580. //    if (drawmode != DrawWire) return;
  581.     if (drawmode == DrawWire || (drawmode == DrawPlane && mot == select)) {
  582.         mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  583.     } else {
  584.         mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  585.     }
  586. }
  587.  
  588. void AnimationData::CalcViewAll(void)
  589. {
  590. //    if (drawmode != DrawWire) return;
  591.  
  592.     CalcViewMatrix();
  593.     if (drawmode == DrawWire) {
  594.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  595.             mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  596.         }
  597.     } else if (drawmode == DrawPlane) {
  598.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  599.             if (mot == select) {
  600.                 mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  601.             } else {
  602.                 mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  603.             }
  604.         }
  605.     } else {
  606.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  607.             mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  608.         }
  609.     }
  610. }
  611.  
  612. void AnimationData::CalcPoints(Motion *mot)
  613. {
  614. //    if (mot != camera && mot != select) return;
  615.     if (drawmode == DrawWire || (drawmode == DrawPlane && mot == select)) {
  616.         mot->CalcPoints(GetMatrix(mot));
  617.         mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  618.     } else {
  619.         mot->CalcPointsBox(GetMatrix(mot));
  620.         mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  621.     }
  622.     if (wireframe.line != NULL) {
  623.         delete[] wireframe.line;
  624.         wireframe.lines = 0;
  625.         wireframe.line = NULL;
  626.     }
  627. }
  628.  
  629. void AnimationData::CalcPointsAll(void)
  630. {
  631.     camera->CalcPoints(GetMatrix(camera));
  632.     CalcViewMatrix();
  633. //    if (drawmode != DrawWire) return;
  634.     if (drawmode == DrawWire) {
  635.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  636.             mot->CalcPoints(GetMatrix(mot));
  637.             mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  638.         }
  639.         BuildWireFrame(selectframe);
  640.     } else if (drawmode == DrawPlane) {
  641.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  642.             if (mot == select) {
  643.                 mot->CalcPoints(GetMatrix(mot));
  644.                 mot->CalcView(viewmat * mot->GetMatrix(selectframe));
  645.             } else {
  646.                 mot->CalcPointsBox(GetMatrix(mot));
  647.                 mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  648.             }
  649.         }
  650.     } else {
  651.         for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  652.             mot->CalcPointsBox(GetMatrix(mot));
  653.             mot->CalcViewBox(viewmat * mot->GetMatrix(selectframe));
  654.         }
  655.     }
  656. }
  657.  
  658. void AnimationData::SetDrawMode(DrawMode mode)
  659. {
  660.     if (drawmode != mode) {
  661.         drawmode = mode;
  662.         CalcPointsAll();
  663.         Redraw();
  664.     }
  665. }
  666.  
  667. void AnimationData::ExpandFrame(int frame)
  668. {
  669.     if (frame <= BEGIN || frame == maxframe) {
  670.         return;
  671.     }
  672.     for (Motion *m = motion;m != NULL; m = m->next) {
  673.         int b = (double)(m->beginframe - BEGIN) * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
  674.         int f = (double)(m->endframe - BEGIN)   * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
  675.         if (b > frame) b = frame;
  676.         if (f > frame) f = frame;
  677.         if (m->motiondata != NULL && b == f) {
  678.             if (b > BEGIN) {
  679.                 b = f-1;
  680.             } else {
  681.                 f = b+1;
  682.             }
  683.         }
  684.         m->Zoom(b,f);
  685.     }
  686.     camera->Zoom(BEGIN, frame);
  687.     camera->target->Zoom(BEGIN, frame);
  688.     int ns = (double)(selectframe- BEGIN) * (double)(frame-BEGIN) / (double)(maxframe-BEGIN) + 0.5 + BEGIN;
  689.     maxframe = frame;
  690.     frameCounter->SetRange(1, maxframe);
  691.     SelectFrame(ns);
  692.     Redraw();
  693.     editflag++;
  694. }
  695.  
  696. void AnimationData::SelectFrame(int frame)
  697. {
  698.     if (frame < BEGIN || frame > maxframe) {
  699.         return;
  700.     }
  701.     selectframe = frame;
  702.     frameCounter->SetPosition(selectframe);
  703.     CalcPointsAll();
  704.     char str[32];
  705.     sprintf(str, "時刻: %d", selectframe);
  706.     statusbar_time->SetText(str);
  707.     Frame->GetApplication()->PumpWaitingMessages();
  708. }
  709.  
  710.  
  711. void AnimationData::SelectMotion(Motion *m)
  712. {
  713.     if (select != m) {
  714.         Motion *os = select;
  715.         select = m;
  716.         if (drawmode == DrawPlane) {
  717.             if (os != NULL) CalcPoints(os);
  718.             if (m  != NULL) CalcPoints(m);
  719.         }
  720.     }
  721. }
  722.  
  723. static void split(char *dir, char *name, char *all)
  724. {
  725.     char *p;
  726.     strcpy(dir, all);
  727.     if ((p = strrchr(dir, '\\')) != NULL) {
  728.         *p = '\0';
  729.         strcpy(name, p+1);
  730.     } else if ((p = strrchr(dir, '/')) != NULL) {
  731.         *p = '\0';
  732.         strcpy(name, p+1);
  733.     } else {
  734.         dir[0] = '\0';
  735.         strcpy(name, all);
  736.     }
  737. }
  738.  
  739. static void merge(char *all, char *dir, char *name)
  740. {
  741.     if (dir[0] == '\0') {
  742.         strcpy(all, name);
  743.     } else if (dir[1] == ':' && dir[2] == '\0') {
  744.         strcpy(all, dir);
  745.         strcat(all, name);
  746.     } else {
  747.         strcpy(all, dir);
  748.         strcat(all, "\\");
  749.         strcat(all, name);
  750.     }
  751. }
  752.  
  753.  
  754. void AnimationData::WriteFile(char *fname)
  755. {
  756.     char str[filenamedirlength];
  757.     if (fname != NULL) {
  758.         split(filedir, filename, fname);
  759.         SetCaption();
  760.     }
  761.     merge(str, filedir, filename);
  762.     if (Motion::FileWrite(motion, camera, light, str) == FALSE && errormessage[0]) {
  763.         PersView->GetApplication()->GetMainWindow()->MessageBox(errormessage);
  764.     }
  765.     editflag = 0;
  766. }
  767.  
  768. void AnimationData::ReadFile(char *fname)
  769. {
  770.     OpModeDefault();
  771.     Motion *nm;
  772.     Motion *next;
  773.     CameraMotion *nc;
  774.     Vector v;
  775.     char nfiledir[_MAX_PATH], nfilename[_MAX_PATH];
  776.     split(nfiledir, nfilename, fname);
  777.     int max;
  778.     if ((max = Motion::FileRead(nm, nc, v, fname)) >= 0) {
  779.         strcpy(filedir, nfiledir);
  780.         strcpy(filename, nfilename);
  781.         for (Motion *m = motion; m != NULL; m = next) {
  782.             next = m->next;
  783.             delete m;
  784.         }
  785.         delete camera;
  786.         SelectMotion(NULL);
  787.         motion = nm;
  788.         camera = nc;
  789.         maxframe = max;
  790.         light = v;
  791.         SelectFrame(BEGIN);
  792.         opstat = OpDefault;
  793.         frameCounter->SetRange(BEGIN, maxframe);
  794.         CalcPointsAll();
  795.         Redraw();
  796.         editflag = 0;
  797.         SetCaption();
  798.     }
  799. }
  800.  
  801.  
  802. void AnimationData::InitMotion(void)
  803. {
  804.     Motion *next, *m;
  805.     for (m = motion; m != NULL; m = next) {
  806.         next = m->next;
  807.         delete m;
  808.     }
  809.     filename[0] = '\0';
  810.  
  811.     backup_displayscale = displayscale = 1.0 / 64.0;
  812.     backup_displayoffset = displayoffset = Vector(0.0, 0.0, 0.0);
  813.  
  814.     zoomflag = FALSE;
  815.     opstat = OpDefault;
  816.     light = Vector(-3.0, -2.0, -4.0);
  817.     light *= (1.0/light.length());
  818.  
  819.     maxframe = 100;
  820.  
  821.     motion = select = NULL;
  822.     selectstatus = SelNone;
  823.  
  824.     selectframe = 1;
  825.  
  826.     Motion *target = new Motion(NULL, BEGIN, maxframe);
  827.  
  828.     camera = new CameraMotion(target, maxframe);
  829.     camera->position = Vector(8000,6000,6000);
  830.     camera->GetPosition(BEGIN);
  831.  
  832.     viewmat = Matrix(0);
  833.     drag_mat = drag_scale = drag_rot = drag_move = Matrix(1);
  834.  
  835. //    if (scrollX) scrollX->Show(SW_SHOW);
  836. //    if (scrollY) scrollY->Show(SW_SHOW);
  837. //    if (scrollZ) scrollZ->Show(SW_SHOW);
  838.  
  839.     editflag = 0;
  840. }
  841.  
  842. void AnimationData::NewFile(void)
  843. {
  844.     OpModeDefault();
  845.     InitMotion();
  846.     frameCounter->SetPosition(selectframe);
  847.     frameCounter->SetRange(BEGIN, maxframe);
  848.  
  849.     SetCaption();
  850.     SelectMotion(NULL);
  851.     SelectFrame(BEGIN);
  852.     Redraw();
  853. //    Redraw(SelAll, TRUE);
  854.     editflag = 0;
  855. }
  856.  
  857. void AnimationData::SetCaption(void)
  858. {
  859.     TApplication *app = TopView->GetApplication();
  860.     TWindow *frame = app->GetMainWindow();
  861.     if (filename[0]) {
  862.         char str[_MAX_PATH];
  863.         sprintf(str, "%s - %s", app->GetName(), filename);
  864.         frame->SetCaption(str);
  865.     } else {
  866.         frame->SetCaption(app->GetName());
  867.     }
  868. }
  869.  
  870. void AnimationData::OpModeDefault(void)
  871. {
  872.     switch (opstat) {
  873.     case OpDefault:
  874.         break;
  875.     case OpLight:
  876. #if 0
  877.         TopView->ShowLight(org_point, FALSE);
  878.         SideView->ShowLight(org_point, FALSE);
  879.         FrontView->ShowLight(org_point, FALSE);
  880. #else
  881.         opstat = OpDefault;
  882.         Redraw();
  883. #endif
  884.         if (org_point.length() > minimumdouble) {
  885.             light = (1.0 / org_point.length()) * org_point;
  886.             editflag++;
  887.         }
  888.         break;
  889.     case OpSelZoom:
  890.         zoomflag = FALSE;
  891. //        scrollX->Show(SW_SHOW);
  892. //        scrollY->Show(SW_SHOW);
  893. //        scrollZ->Show(SW_SHOW);
  894.         break;
  895.     case OpPlay:
  896.         Frame->KillTimer(OpPlay);
  897.         CalcPointsAll();
  898.         opstat = OpDefault;
  899.         Redraw();
  900.         break;
  901.     }
  902.     opstat = OpDefault;
  903.     Status->Redraw();
  904. }
  905.  
  906. void AnimationData::OpModeLight(void)
  907. {
  908.     OpModeDefault();
  909.     SelectMotion(NULL);
  910.     int size = TopView->Attr.W;
  911.     if (size > TopView->Attr.H) {
  912.         size = TopView->Attr.H;
  913.     }
  914.     if (size > FrontView->Attr.H) {
  915.         size = FrontView->Attr.H;
  916.     }
  917.     org_point = (size / 3) * light;
  918.     opstat = OpLight;
  919.     Redraw();
  920. }
  921.  
  922. void AnimationData::OpModeZoom(void)
  923. {
  924.     if (zoomflag != FALSE) {
  925.         displayoffset = backup_displayoffset;
  926.         displayscale  = backup_displayscale;
  927.         SetScrollLimit(TRUE);
  928. //        scrollX->Show(SW_SHOW);
  929. //        scrollY->Show(SW_SHOW);
  930. //        scrollZ->Show(SW_SHOW);
  931.         Redraw(SelXYZ, TRUE);
  932.         zoomflag = FALSE;
  933.     } else {
  934.         backup_displayoffset = displayoffset;
  935.         backup_displayscale  = displayscale;
  936. //        scrollX->Show(SW_HIDE);
  937. //        scrollY->Show(SW_HIDE);
  938. //        scrollZ->Show(SW_HIDE);
  939.         zoomflag = TRUE;
  940.         opstat = OpSelZoom;
  941.     }
  942.     Status->Redraw();
  943. }
  944.  
  945. void AnimationData::OpModePlay(void)
  946. {
  947.     OpModeDefault();
  948.     Frame->SetTimer(OpPlay, 33);
  949.  
  950. //    DrawMode oldmode = drawmode;
  951. //    drawmode = DrawPlaneObject;
  952.  
  953. //    CalcPointsAll();
  954. //    drawmode = oldmode;
  955.     opstat = OpPlay;
  956.     Status->Redraw();
  957. }
  958.  
  959. void AnimationData::SelectAxis(SelectType t[3], Matrix& m)
  960. {
  961.     Vector vx = m.v[0].unit() ;
  962.     Vector vy = m.v[1].unit() ;
  963.     Vector vz = m.v[2].unit() ;
  964.  
  965.     if (vx.x < 0) vx.x = -vx.x;
  966.     if (vx.y < 0) vx.y = -vx.y;
  967.     if (vx.z < 0) vx.z = -vx.z;
  968.     if (vy.x < 0) vy.x = -vy.x;
  969.     if (vy.y < 0) vy.y = -vy.y;
  970.     if (vy.z < 0) vy.z = -vy.z;
  971.     if (vz.x < 0) vz.x = -vz.x;
  972.     if (vz.y < 0) vz.y = -vz.y;
  973.     if (vz.z < 0) vz.z = -vz.z;
  974.  
  975.     if (vx.z > vy.z && vx.z > vz.z) { // Z成分のもっとも少ないベクトルを選択
  976.         t[0] = SelX;
  977.         if (vy.y > vz.y) {            // Y成分のもっとも少ないベクトルを選択
  978.             t[1] = SelY;
  979.             t[2] = SelZ;
  980.         } else {
  981.             t[1] = SelZ;
  982.             t[2] = SelY;
  983.         }
  984.     } else if (vy.z > vz.z) {
  985.         t[0] = SelY;
  986.         if (vx.y > vz.y) {
  987.             t[1] = SelX;
  988.             t[2] = SelZ;
  989.         } else {
  990.             t[1] = SelZ;
  991.             t[2] = SelX;
  992.         }
  993.     } else {
  994.         t[0] = SelZ;
  995.         if (vx.y > vy.y) {
  996.             t[1] = SelX;
  997.             t[2] = SelY;
  998.         } else {
  999.             t[1] = SelY;
  1000.             t[2] = SelX;
  1001.         }
  1002.     }
  1003. }
  1004.  
  1005. TStatusBar *AnimationData::InitStatusBar(void)
  1006. {
  1007.     statusbar = new TStatusBar(0, TGadget::Recessed);
  1008. //    statusbar_mode = new TTextGadget(0, TGadget::Recessed, TTextGadget::Left, 10);
  1009. //    statusbar->Insert(*statusbar_mode);
  1010.     statusbar_time = new TTextGadget(0, TGadget::Recessed, TTextGadget::Left, 8);
  1011.     statusbar->Insert(*statusbar_time);
  1012.     return statusbar;
  1013. }
  1014.  
  1015.  
  1016.  
  1017.  
  1018. int AnimationData::GetLinesNoBackFace(int frame, LineSegment **tmpline, PolyData *polydata)
  1019. {
  1020.     int W = PersView->Attr.W;
  1021.     int H = PersView->Attr.H;
  1022.     Motion *mot;
  1023.     polydata->Init(W, H);
  1024.     for (mot = motion; mot != NULL; mot = mot->next) {
  1025.         if (mot->beginframe <= frame && frame <= mot->endframe) {
  1026.             int inverseflag = FALSE;
  1027.             if (mot->scale.x < 0) inverseflag = !inverseflag;
  1028.             if (mot->scale.y < 0) inverseflag = !inverseflag;
  1029.             if (mot->scale.z < 0) inverseflag = !inverseflag;
  1030.  
  1031.             int offp;
  1032.             offp = polydata->points;
  1033.             for (int i = 0; i < mot->mecha->points; ++i) {
  1034.                 polydata->point[i+offp].x = mot->view_x[i];
  1035.                 polydata->point[i+offp].y = mot->view_y[i];
  1036.                 polydata->point[i+offp].z = mot->view_z[i];
  1037.             }
  1038.             polydata->points += mot->mecha->points;
  1039.             for (i = 0; i < mot->mecha->polys; ++i) {
  1040.                 int *pid = mot->mecha->polypoint + mot->mecha->poly[i];
  1041.                 PolyPoint *p1 = &polydata->point[pid[0]+offp];
  1042.                 PolyPoint *p2 = &polydata->point[pid[1]+offp];
  1043.                 PolyPoint *p3 = &polydata->point[pid[2]+offp];
  1044.                 long m = (long)(p1->x-p2->x)*(long)(p3->y-p2->y) - (long)(p1->y-p2->y)*(long)(p3->x-p2->x);
  1045.                 if (inverseflag && m <= 0) {
  1046.                    polydata->AddPolyInv(mot->mecha->polypoint + mot->mecha->poly[i], offp, mot);
  1047.                 } else if (!inverseflag && m >= 0) {
  1048.                    polydata->AddPoly(mot->mecha->polypoint + mot->mecha->poly[i], offp, mot);
  1049.                 }
  1050.             }
  1051.         }
  1052.     }
  1053.     polydata->ConvertLines();
  1054.     int lines = 0;
  1055.     for (int i = 0; i < polydata->lines; ++i) {
  1056.         if (polydata->line[i].p1 >= 0
  1057.          && polydata->line[i].p2 >= 0) {
  1058.             PolyPoint &p1 = polydata->point[polydata->line[i].p1];
  1059.             PolyPoint &p2 = polydata->point[polydata->line[i].p2];
  1060.             if (p1.z > 0 && p2.z > 0
  1061.              && ((p1.x != p2.x) || (p1.y != p2.y))
  1062.              && (p1.x >= 0 || p2.x >= 0)
  1063.              && (p1.x <  W || p2.x <  W)
  1064.              && (p1.y >= 0 || p2.y >= 0)
  1065.              && (p1.y <  H || p2.y <  H)) {
  1066.                 lines++;
  1067.             }
  1068.         }
  1069.     }
  1070.  
  1071.     int l = 0;
  1072.     *tmpline = new LineSegment[lines];
  1073.     for (i = 0; i < polydata->lines; ++i) {
  1074.         if (polydata->line[i].p1 >= 0 && polydata->line[i].p2 >= 0) {
  1075.             PolyPoint &p1 = polydata->point[polydata->line[i].p1];
  1076.             PolyPoint &p2 = polydata->point[polydata->line[i].p2];
  1077.             if (p1.z > 0 && p2.z > 0
  1078.              && ((p1.x != p2.x) || (p1.y != p2.y))
  1079.              && (p1.x >= 0 || p2.x >= 0)
  1080.              && (p1.x <  W || p2.x <  W)
  1081.              && (p1.y >= 0 || p2.y >= 0)
  1082.              && (p1.y <  H || p2.y <  H)) {
  1083.                 (*tmpline)[l].x1 = (short)p1.x;
  1084.                 (*tmpline)[l].y1 = (short)p1.y;
  1085.                 (*tmpline)[l].x2 = (short)p2.x;
  1086.                 (*tmpline)[l].y2 = (short)p2.y;
  1087.                 (*tmpline)[l].id = polydata->line[i].id;
  1088.                 l++;
  1089.             }
  1090.         }
  1091.     }
  1092.     return l;
  1093. }
  1094.  
  1095. int AnimationData::GetLines(int frame, LineSegment *tmpline)
  1096. {
  1097.     int l = 0;
  1098.     int W = PersView->Attr.W;
  1099.     int H = PersView->Attr.H;
  1100.     Motion *mot;
  1101.     for (mot = motion; mot != NULL; mot = mot->next) {
  1102.         if (mot->beginframe <= frame && frame <= mot->endframe) {
  1103.             for (int i = 0; i < mot->lines; ++i) {
  1104.                 if (mot->view_z[mot->line_1[i]] > 0 && mot->view_z[mot->line_2[i]] > 0) {
  1105.                     tmpline[l].x1 = (short)mot->view_x[mot->line_1[i]];
  1106.                     tmpline[l].y1 = (short)mot->view_y[mot->line_1[i]];
  1107.                     tmpline[l].x2 = (short)mot->view_x[mot->line_2[i]];
  1108.                     tmpline[l].y2 = (short)mot->view_y[mot->line_2[i]];
  1109.                     if ((tmpline[l].x1 <  0 && tmpline[l].x2 <  0)
  1110.                      || (tmpline[l].x1 >= W && tmpline[l].x2 >= W)
  1111.                      || (tmpline[l].y1 <  0 && tmpline[l].y2 <  0)
  1112.                      || (tmpline[l].y1 >= H && tmpline[l].y2 >= H)) {
  1113.                     } else {
  1114.                         l++;
  1115.                     }
  1116.                 }
  1117.             }
  1118.         }
  1119.     }
  1120.     return l;
  1121. }
  1122.  
  1123. void AnimationData::BuildWireFrame(int frame)
  1124. {
  1125.     if (wireframe.line != NULL) {
  1126.         delete[] wireframe.line;
  1127.         wireframe.line = NULL;
  1128.     }
  1129.     if (!hiddenremove) {
  1130.         return;
  1131.     }
  1132.     int maxlines = 0;
  1133.     int maxpolys = 0;
  1134.     int maxpoints = 0;
  1135.     int maxpolypoints = 0;
  1136.     for (Motion *mot = motion; mot != NULL; mot = mot->next) {
  1137.         maxpoints += mot->mecha->points;
  1138.         maxlines += mot->lines;
  1139.         maxpolys += mot->mecha->polys;
  1140.         maxpolypoints += mot->mecha->polypoints;
  1141.     }
  1142.     PolyData polydata(maxpoints, maxlines, maxpolys, maxpolypoints);
  1143.  
  1144. //    SelectFrame(frame);
  1145. //    CalcViewAll();
  1146.     int l = GetLinesNoBackFace(frame, &wireframe.line, &polydata);
  1147.     wireframe.lines = l;
  1148. }
  1149.  
  1150. void AnimationData::WinHelp(UINT fuCommand,DWORD dwData)
  1151. {
  1152.     char helpfile[256];
  1153.     strcpy(helpfile, pathdir.c_str());
  1154.     strcat(helpfile, "MEDIT.HLP");
  1155.     HelpState = TopView->GetApplication()->GetMainWindow()->WinHelp(helpfile, fuCommand, dwData);
  1156. }
  1157.