home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / 3 / 3d120.zip / RTOBJ.PAS < prev    next >
Pascal/Delphi Source File  |  1992-08-08  |  32KB  |  782 lines

  1. (******************************************************************************
  2. *                                    rtObj                                    *
  3. ******************************************************************************)
  4. Unit rtObj;
  5.  
  6.  
  7. (*
  8.        please notice -
  9.        this unit includes both the object3d unit, and the superobj unit,
  10.        and it is used with no reference to the window GUI library,
  11.        uses project3, instead of prjWind
  12. *)
  13.  
  14. (*******************************************************************************
  15. *                                 3D Objects                                  *
  16. *                                 ----------                                  *
  17. *                                                                             *
  18. *   A 3D object is a collection of points and lines in the 3D universe,        *
  19. *   that represent the body we want to draw on the screen.                    *
  20. *   A 3D object is allways centered around point (0, 0, 0) in the 3D universe. *
  21. *   (Its center of gravity assuming it is has a uniform weight distribution    *
  22. *    is in point (0, 0, 0)                                                    *
  23. *   At any moment during the object's life, we know it's distance from the     *
  24. *   origin, And it's rotation using reveres rotation CTM.                      *
  25. *                                                                             *
  26. *   3D Object methods:                                                        *
  27. *      constructor Open                                                       *
  28. *      destructor  CloseMe                                                    *
  29. *      procedures: Rotate, Scale, Move, Show, Hide, Load, Save                *
  30. *                  SetToOrigin, Paint                                         *
  31. *                                                                             *
  32. *******************************************************************************)
  33.  
  34.  
  35. interface
  36. uses
  37.     Graph
  38.     ,Ctm3d
  39.     ,hdr3d
  40.     ,project3
  41.     ;
  42.  
  43. type
  44.  
  45.     f_real = file of real;
  46.  
  47.     {===================================================================}
  48.     {  Base object is the base class for 3D-objects. some functions    }
  49.     { are dummy virtual do-nothing, which are are implemented only for }
  50.     { the descendend objects derived from BaseObject                   }
  51.     {===================================================================}
  52.  
  53.     BaseObjectPtr = ^BaseObject;
  54.     BaseObject = object
  55.        MyCtm       : Ctm;      { This CTM applied to the object gives the  }
  56.                                {  objects Position after transformations   }
  57.        Name        : String;   { Identifies the object                     }
  58.        myColor     : word;     { Main color for the object                 }
  59.        Location    : point3d;  { Central of gravity in real space          }
  60.        scrPntUpdt  : boolean;  { True if screen points updated             }
  61.  
  62.        constructor open(myName : string; color : word);
  63.        destructor  CloseMe; virtual;
  64.        procedure   show; virtual;
  65.        procedure   hide; virtual;
  66.        procedure   paint; virtual; {in specified color}
  67.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  68.        procedure   move(axis : axisType; by : real); virtual;
  69.        procedure   translate(dx, dy, dz : integer); virtual;
  70.                {multy dimentional move in 1 call}
  71.        procedure   scale(axis : axisType; factor : real); virtual;
  72.        procedure   allScale(sx, sy, sz : real); virtual;
  73.                {multy dimentional scale in 1 call}
  74.        procedure   rotate(axis : axisType; deg : real); virtual;
  75.  
  76.        procedure   goto3dPos(x, y, z : real); virtual; {translate to absolute place}
  77.        procedure   setToOrigin; virtual;
  78.                {translate to 0,0,0, update points, and set myCtm to unit}
  79.        procedure   calcLocation; virtual; {set Location to central gravity}
  80.        procedure   deleteTransform; virtual; {set MyCtm to unit}
  81.  
  82.        function load : word; virtual; {from disk}
  83.        function save : word; virtual; {to   disk}
  84.        procedure writeMe(var elementFile : f_real); virtual; {to disk .. without opening file..}
  85.        procedure readMe(var elementFile : f_real); virtual;
  86.     end;
  87.     {===================================================================}
  88.     { Obj3d is an object which represents a 3-D object with a poligon  }
  89.     {  mesh.                                                           }
  90.     {===================================================================}
  91.  
  92.     Obj3dPtr = ^Obj3d;
  93.     Obj3d = object(BaseObject)
  94.        Points      : array[1..MaxPoints] of point3d;
  95.        Lines       : array[1..MaxLines]   of Line3d;
  96.        scrPoints   : array[1..MaxPoints] of screenPoints;
  97.        NumOfLines  : integer;
  98.        NumOfPoints : integer;
  99.        ReverseRot  : Ctm;  { Saves only the reverse rotations }
  100.        unReverseRot: Ctm;  { reverse of the above}
  101.  
  102.        constructor open(myName : string; ref : point3d; color : word);
  103.        destructor  CloseMe; virtual;
  104.        procedure   paint; virtual; {in specified color}
  105.        procedure   updateScreenPoints; virtual; {transform object 3D -> 2D}
  106.  
  107.        procedure   calcLocation; virtual; {set Location to central gravity}
  108.        procedure   setToOrigin; virtual;
  109.  
  110.        procedure writeMe(var elementFile : f_real); virtual;
  111.        procedure readMe(var elementFile : f_real); virtual;
  112.     end;
  113.  
  114. const
  115.    maxSubObjects = 15;
  116.  
  117. type
  118.     complexObjPtr = ^complexObj;
  119.     ComplexObj = object(BaseObject)
  120.        childs      : array [1..maxSubObjects] of obj3dPtr;
  121.        ctms        : array [1..maxSubObjects] of ctm;
  122.        numOfChilds : integer; {counter of # of obj3d childs}
  123.  
  124.        constructor open(myName : string; color : word);
  125.        destructor  closeMe; virtual;
  126.        procedure   updateScreenPoints; virtual;
  127.        procedure   writeMe(var elementFile : f_real); virtual;
  128.        procedure   readMe(var elementFile : f_real); virtual;
  129.        procedure   calcLocation; virtual;
  130.        procedure   paint; virtual;
  131.        procedure   move(axis : axisType; by : real); virtual;
  132.        procedure   rotate(axis : axisType; deg : real); virtual;
  133.        procedure   scale(axis : axisType; factor : real); virtual;
  134.  
  135.        function    addSubObject(myName : string; refPoint : point3d) : word;
  136.        function    getChildPtr(index : integer) : obj3dPtr;
  137.        procedure   rotateChild(child : integer; axis : axisType;
  138.                                        deg : real);
  139.        procedure   scaleChild(child : integer; axis : axisType;
  140.                                        factor : real);
  141.        procedure   moveChild(child : integer; axis : axisType;
  142.                                by : real);
  143.     end;
  144.  
  145.  
  146. implementation
  147.  
  148.  
  149.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  150.     {                     BaseObject implementation                       }
  151.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  152.  
  153. (*******************************************************************************
  154. *                              BaseObject.Open                                *
  155. *******************************************************************************)
  156. constructor BaseObject.Open;
  157. begin
  158.     name      := myName;
  159.     myColor   := color;
  160.     location  := ZeroPoint;
  161.     MyCtm.SetUnit;
  162. end;
  163.  
  164. (*******************************************************************************
  165. *                             BaseObject.CloseMe                              *
  166. *******************************************************************************)
  167. destructor BaseObject.CloseMe;
  168. begin
  169.     { I'm here so my children will Close-themselfs properly }
  170. end;
  171.  
  172. (*******************************************************************************
  173. *                              BaseObject.move                                *
  174. *******************************************************************************)
  175. procedure BaseObject.move(axis : axisType; by: real);
  176. begin
  177.        case axis of
  178.                x : begin
  179.                        myCtm.translateX(by);
  180.                        location.x :=location.x+by;
  181.                    end;
  182.                y : begin
  183.                        myCtm.translateY(by);
  184.                        location.y :=location.y+by;
  185.                    end;
  186.                z : begin
  187.                        myCtm.translateZ(by);
  188.                        location.z :=location.z+by;
  189.                    end;
  190.        end; {case}
  191.        scrPntUpdt := False;
  192. end; {BaseObject.move}
  193.  
  194. (*******************************************************************************
  195. *                            BaseObject.translate                             *
  196. *******************************************************************************)
  197. procedure BaseObject.translate(dx, dy, dz : integer);
  198. begin
  199.        myCtm.translate(dx,dy,dz);
  200.        location.x :=location.x+dx;
  201.        location.y :=location.y+dy;
  202.        location.z :=location.z+dz;
  203.        scrPntUpdt := False;
  204. end; {BaseObject.translate}
  205.  
  206. {use this routine when you know you need to translate more then one axis
  207.        before painting, you will use only one call, which will probably be
  208.        faster, and make your program easier to read, and maintain}
  209.  
  210.  
  211.  
  212. (*******************************************************************************
  213. *                              BaseObject.show                                *
  214. *******************************************************************************)
  215. procedure BaseObject.show;
  216. begin
  217.     setColor(myColor);
  218.     paint;
  219. end;
  220.  
  221. (*******************************************************************************
  222. *                              BaseObject.hide                                *
  223. *******************************************************************************)
  224. procedure BaseObject.hide;
  225. begin
  226.     setColor(0); {backGround}
  227.     paint;      {at this color}
  228. end;
  229.  
  230. (*******************************************************************************
  231. *                              BaseObject.Paint                               *
  232. *******************************************************************************)
  233. procedure BaseObject.Paint;
  234. begin
  235.     if (not(scrPntUpdt)) then
  236.        updateScreenPoints;
  237.     { alas,  BaseObject cannot really paint becuase it does not have   }
  238.     { screen points (what a shame ...)                                 }
  239. end;
  240.  
  241. (*******************************************************************************
  242. *                       BaseObject.UpdateScreenPoints                         *
  243. *******************************************************************************)
  244. procedure BaseObject.UpdateScreenPoints;
  245. begin
  246.     scrPntUpdt := True; { Have no screen points or any other points, so     }
  247.                        { points are already updated (I think)              }
  248. end;
  249.  
  250. (*******************************************************************************
  251. *                              BaseObject.scale                               *
  252. *******************************************************************************)
  253. procedure BaseObject.scale(axis : axisType; factor : real);
  254. begin
  255.        myCtm.translate(-location.x,-location.y,-location.z);
  256.        case axis of
  257.                x : myCtm.scaleX(factor);
  258.                y : myCtm.scaleY(factor);
  259.                z : myCtm.scaleZ(factor);
  260.        end; {scale}
  261.        myCtm.translate(location.x,location.y,location.z);
  262.        scrPntUpdt := False;
  263. end;
  264.  
  265. (*******************************************************************************
  266. *                            BaseObject.allScale                              *
  267. *******************************************************************************)
  268. procedure BaseObject.allScale(sx,sy,sz : real);
  269. begin
  270.     myCtm.translate(-location.x, -location.y, -location.z);
  271.     myCtm.scale(sx,sy,sz);
  272.     myCtm.translate(location.x, location.y, location.z);
  273.     scrPntUpdt := False;
  274. end;
  275. {call this routine to scale more then one axis at a time, with a single call}
  276.  
  277.  
  278. (*******************************************************************************
  279. *                            BaseObject.goto3dPos                             *
  280. *******************************************************************************)
  281. procedure BaseObject.goto3dPos;
  282. begin
  283.        translate(round(x - location.x), round(y - location.y)
  284.                        , round(z - location.z));
  285. end; {obj3d.goto3dPos}
  286.  
  287. (*******************************************************************************
  288. *                           BaseObject.setToOrigin                            *
  289. *******************************************************************************)
  290. procedure BaseObject.setToOrigin;
  291. begin
  292.     goto3dPos(0, 0, 0);
  293.     myCtm.setUnit;
  294.     location := zeroPoint;
  295. end; {BaseObject.setToOrign}
  296.  
  297. (*******************************************************************************
  298. *                          BaseObject.CalcLocation                            *
  299. *******************************************************************************)
  300. procedure BaseObject.CalcLocation;
  301. begin
  302.     location := zeroPoint; { What else could it be when there are no points ?}
  303. end;
  304.  
  305. (*******************************************************************************
  306. *                         BaseObject.deleteTransform                          *
  307. *******************************************************************************)
  308. procedure BaseObject.deleteTransform;
  309. begin
  310.     myCtm.setUnit;
  311.     scrPntUpdt := false;
  312. end;
  313.  
  314. (******************************************************************************
  315. *                              BaseObject.rotate                              *
  316. ******************************************************************************)
  317. procedure BaseObject.rotate;
  318. begin
  319.        myCtm.translate(-location.x,-location.y,-location.z);
  320.        case axis of
  321.                x :     myCtm.rotateX(deg);
  322.                y :     myCtm.rotateY(deg);
  323.                z :     myCtm.rotateZ(deg);
  324.        end; {case}
  325.        myCtm.translate(location.x,location.y,location.z);
  326.  
  327.        {rotation means : go to origin (translate -location),
  328.                          rotate       (rotate axis degrees),
  329.                          go to prev pos (translate location);
  330.        }
  331.  
  332.        scrPntUpdt := False;
  333. end; {BaseObject.rotate, see interface for comments}
  334.  
  335. (******************************************************************************
  336. *                               baseObject.load                               *
  337. ******************************************************************************)
  338. function baseObject.load;
  339. var
  340.     elementFile : f_real;
  341.     errC       : word;
  342. begin
  343.     {$i-} {supposed to be so, just making sure}
  344.     assign(elementFile,name);
  345.     reset(elementFile); {o.k. open it}
  346.     errC := ioResult;
  347.     load := errC;
  348.     if (errC = 0) then begin
  349.        readMe(elementFile);
  350.        errC := ioResult;
  351.        load := errC;
  352.        close(elementFile);
  353.        calcLocation;
  354.        scrPntUpdt := false;
  355.     end; {if}
  356. end;
  357.  
  358. (******************************************************************************
  359. *                               baseObject.save                               *
  360. ******************************************************************************)
  361. function baseObject.save;
  362. var
  363.     elementFile : f_real;
  364.     errC       : word;
  365. begin
  366.     {$i-} {supposed to be so, just making sure}
  367.     assign(elementFile,name);
  368.     rewrite(elementFile); {o.k. open it}
  369.     errC := ioResult;
  370.     save := errC;
  371.     if (errC = 0) then begin
  372.        writeMe(elementFile);
  373.        errC := ioResult; save := errC;
  374.        close(elementFile);
  375.     end; {if}
  376. end;
  377.  
  378. (******************************************************************************
  379. *                             baseObject.writeMe                              *
  380. ******************************************************************************)
  381. procedure baseObject.writeMe;
  382. begin
  383. end;
  384.  
  385. (******************************************************************************
  386. *                              baseObject.readMe                              *
  387. ******************************************************************************)
  388. procedure baseObject.readMe;
  389. begin
  390. end;
  391.  
  392.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  393.     {                        Obj3d implementation                         }
  394.     {%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%}
  395.  
  396.  
  397. (*******************************************************************************
  398. *                                 Obj3d.open                                  *
  399. *******************************************************************************)
  400. constructor Obj3d.open;
  401. begin
  402.     BaseObject.Open(myName, color);
  403.     scrPntUpdt := False; {not calculated yet}
  404.     numOfLines := 0;
  405.     numOfPoints := 0;
  406.     myCtm.setUnit; {initialize to unit matrix}
  407.     reverseRot.setUnit;
  408.     unReverseRot.setUnit;
  409. end; {Obj3d.open}
  410.  
  411. (*******************************************************************************
  412. *                               Obj3d.CloseMe                                 *
  413. *******************************************************************************)
  414. destructor Obj3d.CloseMe;
  415. begin
  416. end;  {Obj3d.Close}
  417.  
  418.  
  419. (*******************************************************************************
  420. *                          Obj3d.updateScreenPoints                           *
  421. *******************************************************************************)
  422. procedure Obj3d.updateScreenPoints;
  423. var i : integer;
  424.     p : point3d;
  425. begin
  426.     for i := 1 to numOfPoints do begin
  427.        myCtm.transform(p,points[i]); {transform by ctm}
  428.        calcPoint(p, scrPoints[i]);
  429.     end; {for}
  430.     scrPntUpdt := True; {make sure for next time..}
  431.            {make all points ready}
  432. end;
  433.  
  434. (*******************************************************************************
  435. *                                Obj3d.paint                                  *
  436. *******************************************************************************)
  437. procedure Obj3d.paint;
  438. {do the actual painting here}
  439. var
  440.     i : integer;
  441. begin
  442.     if ((numOfPoints = 0) or (numOfLines = 0)) then exit;
  443.     if (not(scrPntUpdt)) then
  444.        updateScreenPoints;
  445.     for i := 1 to numOfLines do
  446.        line(   scrPoints[lines[i].fromP].sX,
  447.                scrPoints[lines[i].fromP].sY,
  448.                scrPoints[lines[i].toP].sX,
  449.                scrPoints[lines[i].toP].sY  );
  450.     {it should be noted that calcPoint has to convert points to integers}
  451. end;
  452.  
  453. (******************************************************************************
  454. *                                obj3d.readMe                                 *
  455. ******************************************************************************)
  456. procedure obj3d.readMe;
  457. var
  458.     tmp1,tmp2  : real;
  459.     i,j        : byte;
  460. begin
  461.        read(elementFile, tmp1);
  462.        numOfPoints := trunc(tmp1);
  463.        for j := 1 to numOfPoints do begin
  464.            read(elementFile, points[j].x);
  465.            read(elementFile, points[j].y);
  466.            read(elementFile, points[j].z);
  467.        end; {for}
  468.        read(elementFile, tmp1);
  469.        numOfLines := trunc(tmp1);
  470.        for j := 1 to numOfLines do begin
  471.            read(elementFile, tmp1, tmp2);
  472.            lines[j].fromP := trunc(tmp1);
  473.            lines[j].toP   := trunc(tmp2);
  474.        end; {for}
  475. end; {obj3d.readMe}
  476.  
  477. (******************************************************************************
  478. *                                obj3d.writeMe                                *
  479. ******************************************************************************)
  480. procedure obj3d.writeMe;
  481. var
  482.     tmp1,tmp2  : real;
  483.     i,j        : byte;
  484. begin
  485.        tmp1 := numOfPoints;
  486.        write(elementFile, tmp1);
  487.        for j := 1 to numOfPoints do begin
  488.            write(elementFile, points[j].x);
  489.            write(elementFile, points[j].y);
  490.            write(elementFile, points[j].z);
  491.        end; {for}
  492.        tmp1 := numOfLines;
  493.        write(elementFile, tmp1);
  494.        for j := 1 to numOfLines do begin
  495.            tmp1 := lines[j].fromP;
  496.            tmp2 := lines[j].toP;
  497.            write(elementFile, tmp1, tmp2);
  498.        end;
  499. end;
  500.  
  501. (*******************************************************************************
  502. *                             obj3d.calcLocation                              *
  503. *******************************************************************************)
  504. procedure obj3d.calcLocation;
  505. var
  506.        ce : point3d;
  507.        p  : point3d;
  508.        i  : integer;
  509. begin
  510.        ce := zeroPoint; { (0, 0, 0) -> ce }
  511.        for i := 1 to numOfPoints do begin
  512.                myCtm.transform(p, points[i]);
  513.                ce.x := ce.x + p.x;
  514.                ce.y := ce.y + p.y;
  515.                ce.z := ce.z + p.z;
  516.        end; {for}
  517.        location.x := ce.x / numOfPoints;
  518.        location.y := ce.y / numOfPoints;
  519.        location.z := ce.z / numOfPoints;
  520. end; {obj3d.calcLocation}
  521.  
  522. (*******************************************************************************
  523. *                             Obj3d.setToOrigin                               *
  524. *******************************************************************************)
  525. procedure Obj3d.setToOrigin;
  526. var
  527.        i : integer;
  528.        p : point3d;
  529. begin
  530.     goto3dPos(0, 0, 0);
  531.     for i := 1 to numOfPoints do begin
  532.            myCtm.transform(p, points[i]);
  533.            points[i] := p;
  534.     end; {for}
  535.     scrPntUpdt := False; (** Instead of that THING above **)
  536.     myCtm.setUnit;
  537.     location := zeroPoint;
  538. end; {BaseObject.setToOrign}
  539.  
  540.  
  541.  
  542. (*******************************************************************************
  543. *                              ComplexObj.Open                                *
  544. *******************************************************************************)
  545. constructor ComplexObj.Open;
  546. begin
  547.     BaseObject.Open(myName, color);
  548.     numOfChilds := 0;
  549. end;
  550.  
  551. (*******************************************************************************
  552. *                             ComplexObj.CloseMe                              *
  553. *******************************************************************************)
  554. destructor ComplexObj.CloseMe;
  555. var
  556.        i : integer;
  557.  
  558. begin
  559.        for i := 1 to numOfChilds do
  560.                dispose(childs[i],closeMe);
  561.        baseObject.closeMe;
  562. end;
  563.  
  564. (*******************************************************************************
  565. *                          ComplexObj.addSubObject                            *
  566. *******************************************************************************)
  567. function ComplexObj.addSubObject;
  568. var
  569.     ret_code : word;
  570. begin
  571.        if (numOfChilds >= maxSubObjects) then begin
  572.                addSubObject := 255; {signal error}
  573.                exit;
  574.        end;
  575.        inc(numOfChilds);
  576.        childs[numOfChilds] := new(obj3dPtr, open(myName, zeroPoint, myColor));
  577.        ret_code := childs[numOfChilds]^.load;
  578.        if (ret_code = 0) then begin
  579.                with refPoint do
  580.                        childs[numOfChilds]^.translate(round(x),
  581.                                                round(y), round(z));
  582.                ctms[numOfChilds].copy(childs[numOfChilds]^.myCtm);
  583.        end; {if ret_c..}
  584.        addSubObject := ret_code;
  585. end;
  586.  
  587. (*******************************************************************************
  588. *                       complexObj.updateScreenPoints                         *
  589. *******************************************************************************)
  590. procedure complexObj.updateScreenPoints;
  591. var
  592.     i : integer;
  593. begin
  594.     for i := 1 to numOfChilds do begin
  595.        childs[i]^.myCtm.multiply_2(ctms[i], myCtm);
  596.        childs[i]^.updateScreenPoints;
  597.     end;
  598.     scrPntUpdt := True;
  599. end; {complexObj.updateScreenPoints}
  600.  
  601. (*******************************************************************************
  602. *                           complexObj.getChildPtr                            *
  603. *******************************************************************************)
  604. function complexObj.getChildPtr;
  605. begin
  606.        getChildPtr := childs[index];
  607. end;
  608.  
  609. (*******************************************************************************
  610. *                           ComplexObj.rotateChild                            *
  611. *******************************************************************************)
  612. procedure ComplexObj.rotateChild;
  613. begin
  614.     with childs[child]^ do begin
  615.        myCtm.copy(ctms[child]);
  616.        rotate(axis, deg);
  617.        ctms[Child].copy(MyCtm);
  618.        myCtm.Multiply(Self.myCtm);
  619.     end;
  620. end;
  621.  
  622. (*******************************************************************************
  623. *                           ComplexObj.scaleChild                             *
  624. *******************************************************************************)
  625. procedure ComplexObj.scaleChild;
  626. begin
  627.     with childs[child]^ do begin
  628.        myCtm.copy(ctms[child]);
  629.        scale(axis, factor);
  630.        ctms[Child].copy(MyCtm);
  631.        myCtm.Multiply(Self.myCtm);
  632.     end;
  633. end;
  634.  
  635. (*******************************************************************************
  636. *                            ComplexObj.moveChild                             *
  637. *******************************************************************************)
  638. procedure ComplexObj.moveChild;
  639. begin
  640.     with childs[child]^ do begin
  641.        myCtm.copy(ctms[child]);
  642.        move(axis, by);
  643.        ctms[Child].copy(MyCtm);
  644.        myCtm.Multiply(Self.myCtm);
  645.     end;
  646. end;
  647.  
  648. (******************************************************************************
  649. *                              complexObj.paint                               *
  650. ******************************************************************************)
  651. procedure complexObj.paint;
  652. var
  653.        i : integer;
  654. begin
  655.     if (not(scrPntUpdt)) then
  656.        updateScreenPoints;
  657.     for i := 1 to numOfChilds do
  658.        childs[i]^.paint;
  659. end;
  660.  
  661. procedure complexObj.writeMe;
  662. var
  663.        i : integer;
  664.        r : real;
  665. begin
  666.        r := 0.0 + numOfChilds;
  667.        write(elementFile, r);
  668.        for i := 1 to numOfChilds do
  669.                childs[i]^.writeMe(elementFile); {let all the kids write themselvs}
  670. end;
  671.  
  672. (******************************************************************************
  673. *                              complexObj.readMe                              *
  674. ******************************************************************************)
  675. procedure complexObj.readMe;
  676. var
  677.        i : integer;
  678.        r : real;
  679. begin
  680.        read(elementFile, r);
  681.        numOfChilds := round(r);
  682.        for i := 1 to numOfChilds do begin
  683.               childs[i] := new(Obj3dPtr, Open('Child', ZeroPoint, myColor));
  684.               childs[i]^.readMe(elementFile);
  685.               childs[i]^.calcLocation;
  686.               ctms[i].setUnit;
  687.        end; {for}
  688. end; {complexObj.readMe}
  689.  
  690. (******************************************************************************
  691. *                           complexObj.calcLocation                           *
  692. ******************************************************************************)
  693. procedure complexObj.calcLocation;
  694. var
  695.        i : integer;
  696. begin
  697.        location := zeroPoint;
  698.        for i := 1 to numOfChilds do
  699.                with childs[i]^ do begin
  700.                        calcLocation;
  701.                        self.location.x := location.x + self.location.x;
  702.                        self.location.y := location.y + self.location.y;
  703.                        self.location.z := location.z + self.location.z;
  704.                end; {with}
  705.        with location do begin
  706.                x := x / numOfChilds;
  707.                y := y / numOfChilds;
  708.                z := z / numOfChilds;
  709.        end; {with..}
  710. end; {complexObj.calclocation}
  711.  
  712. (******************************************************************************
  713. *                               complexObj.move                               *
  714. ******************************************************************************)
  715. procedure complexObj.move;
  716. var
  717.        i : integer;
  718. begin
  719. (*       for i := 1 to numOfChilds do
  720.                with childs[i]^ do
  721.                        case axis of
  722.                                x : location.x := location.x + by;
  723.                                y : location.y := location.y + by;
  724.                                z : location.z := location.z + by;
  725.                        end; {case}  *)
  726.        baseObject.move(axis, by);
  727. end; {complexObj.move}
  728.  
  729. (******************************************************************************
  730. *                              complexObj.rotate                              *
  731. ******************************************************************************)
  732. procedure complexObj.rotate;
  733. var
  734.        i : integer;
  735.        sint, cost : real;
  736. begin
  737. (*       cost := cos(deg / 180.0 * 3.1415926535897932385);
  738.        sint := sin(deg / 180.0 * 3.1415926535897932385);
  739.        for i := 1 to numOfChilds do
  740.                with childs[i]^ do
  741.                        case axis of
  742.                                x : begin
  743.                                        location.y := location.y * cost -
  744.                                                location.z * sint;
  745.                                        location.z := location.y * sint +
  746.                                                location.z * cost;
  747.                                end; {x}
  748.                                y : begin
  749.                                        location.x := location.x * cost +
  750.                                                location.z * sint;
  751.                                        location.z := location.z * cost -
  752.                                                location.x * sint;
  753.                                end; {y}
  754.                                z : begin
  755.                                        location.x := location.x * cost -
  756.                                                location.y * sint;
  757.                                        location.y := location.y * cost +
  758.                                                location.x * sint;
  759.                                end; {z}
  760.                        end; {case} *)
  761.        baseObject.rotate(axis, deg);
  762. end; {complexObj.rotate}
  763.  
  764. (******************************************************************************
  765. *                              complexObj.scale                               *
  766. ******************************************************************************)
  767. procedure complexObj.scale;
  768. var
  769.        i : integer;
  770. begin
  771. (*       for i := 1 to numOfChilds do
  772.                with childs[i]^ do
  773.                        case axis of
  774.                                x : location.x := location.x * factor;
  775.                                y : location.y := location.y * factor;
  776.                                z : location.z := location.z * factor;
  777.                        end; {case} *)
  778.        baseObject.scale(axis, factor);
  779. end; {complexObj.scale}
  780.  
  781. end.
  782.