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

  1. #include <stdio.h>
  2. #include <math.h>
  3. #include <string.h>
  4. #include "matrix.h"
  5. #include "suflib.h"
  6. #include "seltype.h"
  7. #include "parts.h"
  8. #include "files.h"
  9.  
  10. #include "log.h"
  11.  
  12. #ifdef __WIN32__
  13.     #define INTMAX (double)(1<<30)
  14. #else
  15.     #define INTMAX 32768.0
  16. #endif
  17.  
  18. static const int EyeLength = 500;
  19.  
  20. LightType lighttype = LightLeftUpper;
  21.  
  22. Parts::Parts(Object *obj, Vector& pos, Vector& rot, Vector& scal)
  23. {
  24.     position = pos;
  25.     rotation = rot;
  26.     scale = scal;
  27.     next = NULL;
  28.     sel = FALSE;
  29.     if (obj ==  NULL) {
  30.         object = NULL;
  31.         point_x = point_y = point_z = NULL;
  32.         view_x = view_y = view_z = NULL;
  33.         line_1 = line_2 = NULL;
  34.         lines = 0;
  35.         maxx = maxy = maxz = minx = miny = minz = 0;
  36.         polygons = 0;
  37.     } else {
  38.         object = obj;
  39.         point_x = new int[obj->points];
  40.         point_y = new int[obj->points];
  41.         point_z = new int[obj->points];
  42.         view_x = new int[obj->points];
  43.         view_y = new int[obj->points];
  44.         view_z = new int[obj->points];
  45.         line_1 = obj->line_1;
  46.         line_2 = obj->line_2;
  47.         lines = obj->lines;
  48.         maxx = obj->maxx;
  49.         maxy = obj->maxy;
  50.         maxz = obj->maxz;
  51.         minx = obj->minx;
  52.         miny = obj->miny;
  53.         minz = obj->minz;
  54.         polygons = obj->polygons;
  55.     }
  56. }
  57.  
  58. Parts::Parts(Parts *p)
  59. {
  60.     next = NULL;
  61.     sel = FALSE;
  62.     if (p == NULL || p->object ==  NULL) {
  63.         position = Vector(0,0,0);
  64.         rotation = Vector(0,0,0);
  65.         scale = Vector(1,1,1);
  66.         object = NULL;
  67.         point_x = point_y = point_z = NULL;
  68.         view_x = view_y = view_z = NULL;
  69.         line_1 = line_2 = NULL;
  70.         lines = 0;
  71.         maxx = maxy = maxz = minx = miny = minz = 0;
  72.         polygons = 0;
  73.     } else {
  74.         position = p->position;
  75.         rotation = p->rotation;
  76.         scale = p->scale;
  77.         object = p->object;
  78.         point_x = new int[object->points];
  79.         point_y = new int[object->points];
  80.         point_z = new int[object->points];
  81.         view_x = new int[object->points];
  82.         view_y = new int[object->points];
  83.         view_z = new int[object->points];
  84.         line_1 = object->line_1;
  85.         line_2 = object->line_2;
  86.         lines = object->lines;
  87.         maxx = object->maxx;
  88.         maxy = object->maxy;
  89.         maxz = object->maxz;
  90.         minx = object->minx;
  91.         miny = object->miny;
  92.         minz = object->minz;
  93.         polygons = object->polygons;
  94.     }
  95. }
  96.  
  97. Parts::~Parts(void)
  98. {
  99.     if (point_x != NULL)     delete[] point_x;
  100.     if (point_y != NULL)     delete[] point_y;
  101.     if (point_z != NULL)     delete[] point_z;
  102.     if (view_x != NULL)        delete[] view_x;
  103.     if (view_y != NULL)        delete[] view_y;
  104.     if (view_z != NULL)        delete[] view_z;
  105.  
  106. }
  107.  
  108. void Parts::CalcPoints(Matrix& m)
  109. {
  110.     if (object != NULL) {
  111.         for (int i = 0; i < object->points; ++i) {
  112.             Vector v1 = m * Vector(object->point_x[i], object->point_y[i], object->point_z[i]);
  113.             point_x[i] = int(v1.x);
  114.             point_y[i] = int(v1.y);
  115.             point_z[i] = int(v1.z);
  116.         }
  117.     }
  118. }
  119.  
  120. void Parts::CalcView(Matrix& m)
  121. {
  122.     if (object != NULL) {
  123.         for (int i = 0; i < object->points; ++i) {
  124.             Vector v1 = m * Vector(object->point_x[i], object->point_y[i], object->point_z[i]);
  125.             if (v1.z <= 1.0) {
  126.                 view_x[i] = 0;
  127.                 view_y[i] = 0;
  128.                 view_z[i] = -1;
  129.             } else {
  130.                 double vx = v1.x / v1.z;
  131.                 double vy = v1.y / v1.z;
  132.                 if (vx < -4096 || vx > 4096 || vy < -4096 || vy > 4096) {
  133.                     view_x[i] = 0;
  134.                     view_y[i] = 0;
  135.                     view_z[i] = -1;
  136.                 } else {
  137.                     view_x[i] = (int)vx;
  138.                     view_y[i] = (int)vy;
  139.                     view_z[i] = (int)(INTMAX / v1.z);
  140.                 }
  141.             }
  142. #if 0
  143.             view_x[i] = int(v1.x / v1.z);
  144.             view_y[i] = int(v1.y / v1.z);
  145.             if (v1.z > 1.0) {
  146.                 view_z[i] = int(INTMAX / v1.z);
  147.             } else {
  148.                 view_z[i] = -1;
  149.             }
  150. #endif
  151.         }
  152.     }
  153. }
  154.  
  155. void Parts::SetRotationParameter(Matrix& m)
  156. {
  157.     rotation = m.GetRotation();
  158. }
  159.  
  160. void Parts::GetMatrix(Matrix& move, Matrix& rot, Matrix& scal)
  161. {
  162.     move = Matrix(1).move(position);
  163.     rot  = Matrix(1).rotz(rotation.z).roty(rotation.y).rotx(rotation.x);
  164.     scal = Matrix(1).scale(scale);
  165. }
  166.  
  167. void Parts::Trans(SelectType t)
  168. {
  169.     switch (t) {
  170.     case SelX:
  171.         position.x = -position.x;
  172.         scale.x = -scale.x;
  173.         rotation.y = -rotation.y;
  174.         rotation.z = -rotation.z;
  175. //        if (rotation.z >= 0.0) {
  176. //            rotation.z = deg(180.0) - rotation.z;
  177. //        } else {
  178. //            rotation.z = deg(-180.0) - rotation.z;
  179. //        }
  180.         break;
  181.     case SelY:
  182.         position.y = -position.y;
  183.         scale.y = -scale.y;
  184.         rotation.x = -rotation.x;
  185.         rotation.z = -rotation.z;
  186.         break;
  187.     case SelZ:
  188.         position.z = -position.z;
  189.         scale.z = -scale.z;
  190.         rotation.x = -rotation.x;
  191.         rotation.y = -rotation.y;
  192.         break;
  193.     }
  194. }
  195.  
  196.  
  197. Matrix Parts::GetMatrix(void)
  198. {
  199.     return Matrix(1)
  200.            .move(position)
  201.            .rotz(rotation.z)
  202.            .roty(rotation.y)
  203.            .rotx(rotation.x)
  204.            .scale(scale);
  205. }
  206.  
  207. void Parts::PartsWrite(FILE *fp, char *initialdir, int len)
  208. {
  209.     char *p = object->filename;
  210.     if (len > 0 && strncmpi(object->filename, initialdir, len) == 0) {
  211.         p = object->filename + len + 1;
  212.     } else if (strncmpi(object->filename, partsdir.c_str(), partsdir.length()) == 0) {
  213.         p = object->filename + partsdir.length();
  214.     } else if (strncmpi(object->filename, simplepartsdir.c_str(), simplepartsdir.length()) == 0) {
  215.         p = object->filename + simplepartsdir.length();
  216.     }
  217.     fprintf(fp,
  218. #if 0
  219.             "\t{\tmov ( %5.0lf %5.0lf %5.0lf ) "
  220.             "rotz( %4.0lf ) roty( %4.0lf ) rotx( %4.0lf )\n"
  221.             "\t\tscal ( %5.3lf %5.3lf %5.3lf ) obj %s (: %s :)\n"
  222.             "\t}\n",
  223. #else
  224.             "\t{\tmov ( %5.0lf %5.0lf %5.0lf ) "
  225.             "rotz( %4.0lf ) roty( %4.0lf ) rotx( %4.0lf )\n"
  226.             "\t\tscal ( %5.3lf %5.3lf %5.3lf ) obj %s /* %s */\n"
  227.             "\t}\n",
  228. #endif
  229.         position.x, position.y, position.z,
  230.         rad(rotation.z), rad(rotation.y), rad(rotation.x),
  231.         scale.x, scale.y, scale.z, object->name, p);
  232. }
  233.  
  234. int Parts::FileWrite(CameraParts *cam, char *filename, char *initialdir)
  235. {
  236.     FILE *fp;
  237.     int objs = 0;
  238.     Parts *p;
  239.     int len = 0;
  240.     errormessage[0] = '\0';
  241.     if (initialdir != NULL) {
  242.         len = strlen(initialdir);
  243.     }
  244.     if ((fp = fopen(filename, "w")) == NULL) {
  245.         sprintf(errormessage, "メカデザインファイルの保存に失敗しました: %s", filename, _sys_errlist[errno]);
  246.         return FALSE;
  247.     }
  248.     for (p = this; p != NULL; p = p->next) {
  249.         if (p != cam) {
  250.             objs++;
  251.         }
  252.     }
  253.     fprintf(fp,
  254.         "/*                            Parts Assembler\n"
  255.         "                                  Version 1.1\n"
  256.         "Parts: \n");
  257.     for (p = this; p != NULL; p = p->next) {
  258.         for (Parts *op = this; op != p && op != NULL; op = op->next) {
  259.             if (op->object == p->object) {
  260.                 break;
  261.             }
  262.         }
  263.         if (op == p || op == NULL) {
  264.             char *f = p->object->filename;
  265.             if (len > 0 && strncmpi(p->object->filename, initialdir, len) == 0) {
  266.                 f = p->object->filename + len + 1;
  267.             } else if (strncmpi(p->object->filename, partsdir.c_str(), partsdir.length()) == 0) {
  268.                 f = p->object->filename + partsdir.length();
  269.             } else if (strncmpi(p->object->filename, simplepartsdir.c_str(), simplepartsdir.length()) == 0) {
  270.                 f = p->object->filename + simplepartsdir.length();
  271.             }
  272.             fprintf(fp, "\t%s\n", f);
  273.         }
  274.     }
  275.     fprintf(fp,"*/\nfram\n{\n");
  276.  
  277.     if (cam != NULL) {
  278.         Vector evec = cam->target - cam->position;
  279.         Vector lvec;
  280.         if (lighttype == LightLeftUpper || lighttype == LightLeftLower) {
  281.             lvec.x =  evec.x + evec.y;
  282.             lvec.y = -evec.x + evec.y;
  283.         } else {
  284.             lvec.x =  evec.x - evec.y;
  285.             lvec.y =  evec.x + evec.y;
  286.         }
  287.         lvec.z = sqrt(lvec.x * lvec.x + lvec.y * lvec.y);
  288.         if (evec.x == 0.0 || evec.y == 0.0 || lvec.length() < minimumdouble) {
  289.             fprintf(fp, "\tlight pal( rgb ( 1.00 1.00 1.00 ) -3.00 -2.00 -4.00 )\n");
  290.         } else {
  291.             lvec *= (100.0 / lvec.length());
  292.             if (evec.z < 0) {
  293.                 lvec.z = -lvec.z;
  294.             }
  295.             fprintf(fp, "\tlight pal( rgb ( 1.00 1.00 1.00 ) %3d %3d %3d )\n",
  296.                     (int)(lvec.x),(int)(lvec.y),(int)(lvec.z));
  297.         }
  298.         cam->PartsWrite(fp, initialdir, len);
  299.     } else {
  300.         fprintf(fp, "\tlight pal( rgb ( 1.00 1.00 1.00 ) -3.00 -2.00 -4.00 )\n");
  301.         fprintf(fp,"\t{\tmov ( 0 0 0 ) eye deg( 60 ) }\n");
  302.     }
  303.     for (p = this; p != NULL; p = p->next) {
  304.         if (p != cam) {
  305.             p->PartsWrite(fp, initialdir, len);
  306.         }
  307.     }
  308. #if 0
  309.     fprintf(fp, "}\n#endframe\n");
  310. #else
  311.     fprintf(fp, "}\n");
  312. #endif
  313.     int fe = ferror(fp);
  314.     if (ferror(fp)) {
  315.         sprintf(errormessage, "メカデザインファイルの保存に失敗しました: %s", _sys_errlist[errno]);
  316.         fclose(fp);
  317.         return FALSE;
  318.     }
  319.     fclose(fp);
  320.     return TRUE;
  321. }
  322.  
  323. CameraParts::CameraParts(Vector& pos, Vector& tar):    Parts()
  324. {
  325.     position = pos;
  326.     scale = Vector(1.0, 1.0, 1.0);
  327.     target = tar;
  328.  
  329.     SetAngle(deg(60));
  330.  
  331.     SetTarget(tar);
  332.  
  333.     line_1 = l1;
  334.     line_2 = l2;
  335.  
  336.     for (int i = 0; i < CameraLines; ++i) {
  337.         line_1[i] = 0;
  338.         line_2[i] = i+1;
  339.     }
  340.  
  341.     lines = CameraLines;;
  342.  
  343.     point_x = new int[CameraPoints];
  344.     point_y = new int[CameraPoints];
  345.     point_z = new int[CameraPoints];
  346.     view_x = new int[CameraPoints];
  347.     view_y = new int[CameraPoints];
  348.     view_z = new int[CameraPoints];
  349. }
  350.  
  351.  
  352.  
  353. //CameraParts::~CameraParts(): ~Parts()
  354. //{
  355. //}
  356.  
  357. void CameraParts::SetTarget(Vector& v)
  358. {
  359.     target = v;
  360.     Matrix m = (v - position) ^ Vector(0.0, 0.0, 1.0);
  361.     double len = (v - position).length() / (double)EyeLength;
  362.     rotation = m.GetRotation();
  363.     scale.x = scale.y = scale.z = len;
  364. }
  365.  
  366. void CameraParts::SetAngle(double a)
  367. {
  368.     angle = a;
  369.     px[0] = py[0] = pz[0] = 0;
  370.     px[1] = EyeLength;
  371.     py[1] = pz[1] = 0;
  372.     for (int i = 2; i < CameraPoints; ++i) {
  373.         px[i] = EyeLength * 10;
  374.     }
  375.     py[2] = py[3] = int(double(EyeLength * 10) * tan(angle/2.0));
  376.     py[4] = py[5] = -py[2];
  377.     pz[2] = pz[4] = py[2] * 3 / 4;
  378.     pz[3] = pz[5] = -pz[2];
  379. }
  380.  
  381.  
  382. void CameraParts::CalcPoints(Matrix& m)
  383. {
  384.     for (int i = 0; i < CameraPoints; ++i) {
  385.         Vector v1 = m * Vector(px[i], py[i], pz[i]);
  386.         point_x[i] = int(v1.x);
  387.         point_y[i] = int(v1.y);
  388.         point_z[i] = int(v1.z);
  389.     }
  390. }
  391.  
  392. void CameraParts::CalcView(Matrix& /*m*/)
  393. {
  394.     for (int i = 0; i < CameraPoints; ++i) {
  395.         view_x[i] = view_y[i] = 0;
  396.         view_z[i] = -1;
  397.     }
  398. }
  399.  
  400. void CameraParts::PartsWrite(FILE *fp, char* /*initialdir*/, int /*len*/)
  401. {
  402.     fprintf(fp,
  403.             "\t{\tmov ( %5.0lf %5.0lf %5.0lf ) eye deg( %d ) }\n"
  404.             "\t{\tmov ( %5.0lf %5.0lf %5.0lf ) target }\n",
  405.         position.x, position.y, position.z,
  406.         int(rad(angle)+0.5),
  407.         target.x, target.y, target.z);
  408. }
  409.  
  410.  
  411. CombinedParts::CombinedParts(void):
  412.     Parts()
  413. {
  414.     nparts = 0;
  415. }
  416.  
  417. CombinedParts::~CombinedParts(void)
  418. {
  419.     Parts::~Parts();
  420. }
  421.  
  422. void CombinedParts::CalcSizeAll(void)
  423. {
  424.     int i;
  425.     minx = miny = minz = 32767;
  426.     maxx = maxy = maxz = -32767;
  427.  
  428.     polygons = 0;
  429.     for (i = 0; i < nparts; i++) {
  430.         if (parts[i]->object != NULL) {
  431.             polygons += parts[i]->polygons;
  432.             Matrix m = parts[i]->GetMatrix();
  433.             int points = parts[i]->object->points;
  434.             int j;
  435.             for (j = 0; j < points; j++) {
  436.                 Vector v = m *
  437.                     Vector(    parts[i]->object->point_x[j],
  438.                             parts[i]->object->point_y[j],
  439.                             parts[i]->object->point_z[j]);
  440.                 if (minx > v.x) minx = v.x;
  441.                 if (maxx < v.x) maxx = v.x;
  442.                 if (miny > v.y) miny = v.y;
  443.                 if (maxy < v.y) maxy = v.y;
  444.                 if (minz > v.z) minz = v.z;
  445.                 if (maxz < v.z) maxz = v.z;
  446.             }
  447.         }
  448.     }
  449.  
  450.     rotation = Vector(0,0,0);
  451.     scale = Vector(1,1,1);
  452.  
  453.     position = Vector( (minx+maxx)/2, (miny+maxy)/2, (minz+maxz)/2);
  454.  
  455.     maxx = (maxx-minx)/2; minx = -maxx;
  456.     maxy = (maxy-miny)/2; miny = -maxy;
  457.     maxz = (maxz-minz)/2; minz = -maxz;
  458.     orig_position = old_position = position;
  459.     old_rotation = rotation;
  460.     old_scale = scale;
  461.  
  462. }
  463.  
  464. int CombinedParts::AddParts(Parts *p)
  465. {
  466.     int i;
  467.     for (i = 0; i < nparts; i++) {
  468.         if (parts[i] == p) {
  469.             return FALSE;
  470.         }
  471.     }
  472.     parts[nparts++] = p;
  473.     return TRUE;
  474. }
  475.  
  476. int CombinedParts::DeleteParts(Parts *p)
  477. {
  478.     for (int i = 0; i < nparts; i++) {
  479.         if (parts[i] == p) {
  480.             for (; i < nparts-1; i++) {
  481.                 parts[i] = parts[i+1];
  482.             }
  483.             nparts--;
  484.             CalcSizeAll();
  485.             return TRUE;
  486.         }
  487.     }
  488.     return FALSE;
  489. }
  490.  
  491. void CombinedParts::MoveParts(Matrix& m, double scalerate)
  492. {
  493.     Matrix m0(m);
  494.     Matrix mt;
  495. #if 0
  496.     m0.v[0] *= (1.0/m0.v[0].length());
  497.     m0.v[1] *= (1.0/m0.v[1].length());
  498.     m0.v[2] *= (1.0/m0.v[2].length());
  499.     if (scalerate < 0) {
  500.         scalerate = -scalerate;
  501.         s = TRUE;
  502.     }
  503. #endif
  504.     for (int i = 0; i < nparts; i++) {
  505.         parts[i]->scale *= scalerate;
  506.         mt = m0.move(parts[i]->position)
  507.                .rotz(parts[i]->rotation.z)
  508.                .roty(parts[i]->rotation.y)
  509.                .rotx(parts[i]->rotation.x);
  510.         mt.v[0] *= (1.0/mt.v[0].length());
  511.         mt.v[1] *= (1.0/mt.v[1].length());
  512.         mt.v[2] *= (1.0/mt.v[2].length());
  513.         if (scalerate < 0) {
  514.             mt.v[0] *= -1;
  515.             mt.v[1] *= -1;
  516.             mt.v[2] *= -1;
  517.         }
  518.         parts[i]->position = mt.v[3]; mt.v[3] = Vector(0,0,0);
  519.         parts[i]->rotation = mt.GetRotation();
  520.     }
  521. }
  522.  
  523. void CombinedParts::MoveParts(void)
  524. {
  525.     int p, r, s;
  526.     p = (old_position == position);
  527.     r = (old_rotation == rotation);
  528.     s = (old_scale == scale);
  529.     if (p && r && s) {
  530.         return;
  531.     } else if (!p && r && s) {
  532.         Vector v = position - old_position;
  533.         for (int i = 0; i < nparts; i++) {
  534.             parts[i]->position += v;
  535.         }
  536.     } else {
  537.         Matrix m0 = Matrix(1).move(old_position)
  538.             .rotz(old_rotation.z).roty(old_rotation.y).rotx(old_rotation.x)
  539.             .scale(old_scale);
  540.         Matrix m1 = Matrix(1).move(position)
  541.             .rotz(rotation.z).roty(rotation.y).rotx(rotation.x)
  542.             .scale(scale);
  543.         Matrix m = m1 * m0.inv();
  544.         MoveParts(m1 * m0.inv(), scale.x/old_scale.x);
  545.     }
  546.     old_position = position;
  547.     old_rotation = rotation;
  548.     old_scale = scale;
  549. }
  550.  
  551. void CombinedParts::CalcPoints(Matrix& m)
  552. {
  553.     MoveParts();
  554.  
  555.     Matrix mt;
  556.     mt = m * GetMatrix().inv();
  557.  
  558.     for (int i = 0; i < nparts; i++) {
  559.         parts[i]->CalcPoints(mt * parts[i]->GetMatrix());
  560.     }
  561.  
  562. }
  563.  
  564. void CombinedParts::CalcView(Matrix& m)
  565. {
  566.     MoveParts                        ();
  567.  
  568.     Matrix mt;
  569.     mt = m * GetMatrix().inv();
  570.  
  571.     for (int i = 0; i < nparts; i++) {
  572.         parts[i]->CalcView(mt * parts[i]->GetMatrix());
  573.     }
  574.  
  575. }
  576.  
  577. void CombinedParts::DeleteAllParts(void)
  578. {
  579.     nparts = 0;
  580. #if 0
  581.     position = rotation = Vector(0,0,0);
  582.     scale = Vector(1,1,1);
  583.     minx = miny = minz = 32767;
  584.     maxx = maxy = maxz = -32767;
  585. #endif
  586. }
  587.  
  588. void CombinedParts::AddAllParts(Parts *p)
  589. {
  590.     DeleteAllParts();
  591.     int i;
  592.     for (i = 0; p != NULL && i < MaxParts; p = p->next) {
  593.         parts[i++] = p;
  594.     }
  595.     nparts = i;
  596.     CalcSizeAll();
  597. }
  598.  
  599.