1 /*****************************************************************************
2  *
3  *  Elmer, A Finite Element Software for Multiphysical Problems
4  *
5  *  Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6  *
7  *  This program is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU General Public License
9  *  as published by the Free Software Foundation; either version 2
10  *  of the License, or (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program (in file fem/GPL-2); if not, write to the
19  *  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301, USA.
21  *
22  *****************************************************************************/
23 
24 /*******************************************************************************
25  *
26  * Object transformations
27  *
28  *******************************************************************************
29  *
30  *                     Author:       Juha Ruokolainen
31  *
32  *                    Address: CSC - IT Center for Science Ltd.
33  *                                Keilaranta 14, P.O. BOX 405
34  *                                  02101 Espoo, Finland
35  *                                  Tel. +358 0 457 2723
36  *                                Telefax: +358 0 457 2302
37  *                              EMail: Juha.Ruokolainen@csc.fi
38  *
39  *                       Date: 1 Oct 1995
40  *
41  ******************************************************************************/
42 
43 #include "../elmerpost.h"
44 
45 /*******************************************************************************
46  *
47  *     Name:          obj_init_matrix( matrix_t )
48  *
49  *     Purpose:       Set given transformation matrix to unit matrix.
50  *                    Internal only.
51  *
52  *     Parameters:
53  *
54  *         Input:     none
55  *
56  *         Output:    (matrix_t) matrix to set
57  *
58  *   Return value:    void
59  *
60  ******************************************************************************/
obj_init_matrix(matrix_t matrix)61 static void obj_init_matrix( matrix_t matrix )
62 {
63     memset( matrix,0, sizeof(matrix_t) );
64 
65     matrix[0][0] = matrix[1][1] =
66     matrix[2][2] = matrix[3][3] = 1.0;
67 }
68 
69 /*******************************************************************************
70  *
71  *     Name:          obj_init_transform( transform_t * )
72  *
73  *     Purpose:       Initialize given transform_t structure.
74  *                    Internal only.
75  *
76  *     Parameters:
77  *
78  *         Input:     none
79  *
80  *         Output:    (transform_t *)
81  *
82  *   Return value:    void
83  *
84  ******************************************************************************/
obj_init_transform(transform_t * transform)85 void obj_init_transform( transform_t *transform )
86 {
87     transform->RotX = transform->RotY = transform->RotZ = 0.0;
88     transform->TrnX = transform->TrnY = transform->TrnZ = 0.0;
89     transform->SclX = transform->SclY = transform->SclZ = 1.0;
90 
91     transform->TransformPriority = trn_pri_str;
92     transform->RotationPriority  = rot_pri_xyz;
93 
94     obj_init_matrix( transform->Matrix );
95 
96     obj_init_matrix( transform->RotMatrix );
97     obj_init_matrix( transform->SclMatrix );
98     obj_init_matrix( transform->TrnMatrix );
99 }
100 
101 /*******************************************************************************
102  *
103  *     Name:          obj_get_matrix( matrix_t, object_t * )
104  *
105  *     Purpose:       Return objects transformation matrix given
106  *                    (object_t *) structure.
107  *
108  *     Parameters:
109  *
110  *         Input:     (object_t *)
111  *
112  *         Output:    (matrix_t)
113  *
114  *   Return value:    void
115  *
116  ******************************************************************************/
obj_get_matrix(matrix_t matrix,object_t * object)117 void obj_get_matrix(matrix_t matrix,object_t *object)
118 {
119     transform_t *transform = &object->Transform;
120 
121     memcpy( matrix,transform->Matrix,sizeof(matrix_t) );
122 }
123 
124 /*******************************************************************************
125  *
126  *     Name:          obj_get_matrix_transpose( matrix_t, object_t * )
127  *
128  *     Purpose:       Return transpose of objects transformation matrix given
129  *                    (object_t *) structure.
130  *
131  *     Parameters:
132  *
133  *         Input:     (object_t *)
134  *
135  *         Output:    (matrix_t)
136  *
137  *   Return value:    void
138  *
139  ******************************************************************************/
obj_get_matrix_transpose(matrix_t matrix,object_t * object)140 void obj_get_matrix_transpose( matrix_t matrix,object_t *object )
141 {
142     transform_t *transform = &object->Transform;
143     int i,j;
144 
145     for( i=0; i<4; i++ )
146     for( j=0; j<4; j++ ) matrix[j][i] = transform->Matrix[i][j];
147 }
148 
149 /*******************************************************************************
150  *
151  *     Name:          obj_copy_matrix( matrix_t A, matrix_t B)
152  *
153  *     Purpose:       Copy matrix A to matrix B
154  *
155  *     Parameters:
156  *
157  *         Input:     (matrix_t)
158  *
159  *         Output:    (matrix_t)
160  *
161  *   Return value:    void
162  *
163  ******************************************************************************/
obj_copy_matrix(matrix_t A,matrix_t B)164 static void obj_copy_matrix( matrix_t A,matrix_t B )
165 {
166     memcpy( A,B,sizeof(matrix_t) );
167 }
168 
169 /*******************************************************************************
170  *
171  *     Name:          obj_mult_matrix( matrix_t A, matrix_t B)
172  *                    obj_mult_matrix_left( matrix_t A, matrix_t B)
173  *
174  *     Purpose:       return A = A*B. Internal only.
175  *
176  *     Parameters:
177  *
178  *         Input:     (matrix_t)A, (matrix_t)B
179  *
180  *         Output:    (matrix_t)A
181  *
182  *   Return value:    void
183  *
184  ******************************************************************************/
185 #define obj_mult_matrix( A, B )  obj_mult_matrix_left( A,B )
obj_mult_matrix_left(matrix_t A,matrix_t B)186 static void obj_mult_matrix_left( matrix_t A,matrix_t B )
187 {
188     matrix_t R;
189     double s;
190     int i,j,k;
191 
192     for( i=0; i<4; i++ )
193     for( j=0; j<4; j++ )
194     {
195         s = 0.0;
196         for( k=0; k<4; k++ ) s += A[i][k]*B[k][j];
197         R[i][j] = s;
198     }
199 
200     obj_copy_matrix( A,R );
201 }
202 
203 /*******************************************************************************
204  *
205  *     Name:          obj_mult_matrix_right( matrix_t A, matrix_t B)
206  *
207  *     Purpose:       return A = B*A. Internal only.
208  *
209  *     Parameters:
210  *
211  *         Input:     (matrix_t)A, (matrix_t)B
212  *
213  *         Output:    (matrix_t)A
214  *
215  *   Return value:    void
216  *
217  ******************************************************************************/
obj_mult_matrix_right(matrix_t A,matrix_t B)218 static void obj_mult_matrix_right( matrix_t A,matrix_t B )
219 {
220     matrix_t R;
221     double s;
222     int i,j,k;
223 
224     for( i=0; i<4; i++ )
225     for( j=0; j<4; j++ )
226     {
227         s = 0.0;
228         for( k=0; k<4; k++ ) s += B[i][k]*A[k][j];
229         R[i][j] = s;
230     }
231 
232     obj_copy_matrix( A,R );
233 }
234 
235 /*******************************************************************************
236  *
237  *     Name:          obj_translate_matrix( matrix_t,double,double,double )
238  *
239  *     Purpose:       return matrix_t corresponding to translations x,y,z
240  *                    Internal only.
241  *
242  *     Parameters:
243  *
244  *         Input:    (double,double,double) translations x,y,and z
245  *
246  *         Output:   (matrix_t) resulting transformation matrix
247  *
248  *   Return value:    void
249  *
250  ******************************************************************************/
obj_translate_matrix(matrix_t M,double x,double y,double z)251 static void obj_translate_matrix( matrix_t M, double x, double y, double z )
252 {
253      int i;
254 
255      obj_init_matrix( M );
256 
257      M[0][3] = x;
258      M[1][3] = y;
259      M[2][3] = z;
260 /*
261  *   for( i=0; i<4; i++ )
262  *   {
263  *       M[0][i] += x*M[3][i];
264  *       M[1][i] += y*M[3][i];
265  *       M[2][i] += z*M[3][i];
266  *   }
267  */
268 }
269 
270 /*******************************************************************************
271  *
272  *     Name:          obj_scale_matrix( matrix_t,double,double,double )
273  *
274  *     Purpose:       return matrix_t corresponding to scalings x,y,z
275  *                    Internal only.
276  *
277  *     Parameters:
278  *
279  *         Input:    (double,double,double) scaleings x,y,and z
280  *
281  *         Output:   (matrix_t) resulting transformation matrix
282  *
283  *   Return value:    void
284  *
285  ******************************************************************************/
obj_scale_matrix(matrix_t M,double x,double y,double z)286 static void obj_scale_matrix( matrix_t M,double x, double y, double z )
287 {
288      int i;
289 
290      obj_init_matrix( M );
291 
292      M[0][0] = x;
293      M[1][1] = y;
294      M[2][2] = z;
295 /*
296  *   for( i=0; i<4; i++ )
297  *   {
298  *       M[0][i] *= x;
299  *       M[1][i] *= y;
300  *       M[2][i] *= z;
301  *   }
302  */
303 }
304 
305 /*******************************************************************************
306  *
307  *     Name:          obj_internal_rotate_matrix( matrix_t,double,double,int )
308  *
309  *     Purpose:       return matrix_t corresponding to rotation about axis
310  *                    given, by amount given in sin(a), cos(a).
311  *                    Internal only.
312  *
313  *     Parameters:
314  *
315  *         Input:    (double) sine of the angle to rotate
316  *                   (double) cosine of the angle to rotate
317  *                   (int)   axis about which to rotate:
318  *                       x: axis = 0, y: axis = 1, z: axis = 2
319  *
320  *         Output:   (matrix_t) resulting transformation matrix
321  *
322  *   Return value:    void
323  *
324  ******************************************************************************/
obj_internal_rotate_matrix(matrix_t M,double s,double c,int axis)325 static void obj_internal_rotate_matrix( matrix_t M,double s, double c, int axis )
326 {
327      double t;
328      int i;
329 
330      switch( axis )
331      {
332          case 0: for( i=0; i<4; i++ )
333                  {
334                      t = M[1][i];
335                      M[1][i] = c*t - s*M[2][i];
336                      M[2][i] = c*M[2][i] + s*t;
337                  }
338          break;
339 
340          case 1: for( i=0; i<4; i++ )
341                  {
342                      t = M[0][i];
343                      M[0][i] = c*t + s*M[2][i];
344                      M[2][i] = c*M[2][i] - s*t;
345                  }
346          break;
347 
348          case 2: for( i=0; i<4; i++ )
349                  {
350                      t = M[0][i];
351                      M[0][i] = c*t - s*M[1][i];
352                      M[1][i] = c*M[1][i] + s*t;
353                  }
354          break;
355      }
356 }
357 
358 /*******************************************************************************
359  *
360  *     Name:          obj_set_rotation_priority( object_t *,rot_pri_t )
361  *
362  *     Purpose:       set rotation priority for an object given
363  *
364  *     Parameters:
365  *
366  *         Input:    (rot_pri_t) rotation priority, one of:
367  *
368  *                    rot_pri_xyz
369  *                    rot_pri_xzy
370  *                    rot_pri_yxz
371  *                    rot_pri_yzx
372  *                    rot_pri_zxy
373  *                    rot_pri_zyx
374  *
375  *         Output:   (object_t *) is modified
376  *
377  *   Return value:    void
378  *
379  ******************************************************************************/
obj_set_rotation_priority(object_t * object,rot_pri_t priority)380 void obj_set_rotation_priority( object_t *object, rot_pri_t priority)
381 {
382     object->Transform.RotationPriority = priority;
383 }
384 
385 /*******************************************************************************
386  *
387  *     Name:          obj_set_transform_priority( object_t *, trn_pri_t )
388  *
389  *     Purpose:       set transformation priority for an object given
390  *
391  *     Parameters:
392  *
393  *         Input:    (trn_pri_t) transformation priority, one of:
394  *
395  *                    trn_pri_trs
396  *                    trn_pri_tsr
397  *                    trn_pri_rts
398  *                    trn_pri_rst
399  *                    trn_pri_str
400  *                    trn_pri_srt
401  *
402  *         Output:   (object_t *) is modified
403  *
404  *   Return value:    void
405  *
406  ******************************************************************************/
obj_set_transform_priority(object_t * object,trn_pri_t priority)407 void obj_set_transform_priority( object_t *object, trn_pri_t priority)
408 {
409     object->Transform.TransformPriority = priority;
410 }
411 
412 /*******************************************************************************
413  *
414  *     Name:          obj_rotate_matrix( matrix_t,rot_pri_t,double,double,double )
415  *
416  *     Purpose:       return matrix_t corresponding to rotation about
417  *                    three axes by angles given. Internal only.
418  *
419  *     Parameters:
420  *
421  *         Input:    (rot_pri_t) rotation priority, one of:
422  *
423  *                    rot_pri_xyz
424  *                    rot_pri_xzy
425  *                    rot_pri_yxz
426  *                    rot_pri_yzx
427  *                    rot_pri_zxy
428  *                    rot_pri_zyx
429  *
430  *                    (double)  angle about 'x' - axis
431  *                    (double)  angle about 'y' - axis
432  *                    (double)  angle about 'z' - axis
433  *
434  *         Output:   (matrix_t) resulting transformation matrix
435  *
436  *   Return value:    void
437  *
438  ******************************************************************************/
obj_rotate_matrix(matrix_t M,rot_pri_t rot_pri,double x,double y,double z)439 static void obj_rotate_matrix( matrix_t M,rot_pri_t rot_pri,double x,double y,double z )
440 {
441      int i,j,axis,a_ord[3];
442      double a;
443      matrix_t N,P;
444 
445      obj_init_matrix( M );
446 
447      switch( rot_pri )
448      {
449          case rot_pri_xyz: a_ord[0]=0; a_ord[1]=1; a_ord[2]=2; break;
450          case rot_pri_xzy: a_ord[0]=0; a_ord[1]=2; a_ord[2]=1; break;
451          case rot_pri_yxz: a_ord[0]=1; a_ord[1]=0; a_ord[2]=2; break;
452          case rot_pri_yzx: a_ord[0]=1; a_ord[1]=2; a_ord[2]=0; break;
453          case rot_pri_zxy: a_ord[0]=2; a_ord[1]=0; a_ord[2]=1; break;
454          case rot_pri_zyx: a_ord[0]=2; a_ord[1]=1; a_ord[2]=0; break;
455      }
456 
457      for( i=0; i<3; i++ )
458      {
459          axis = a_ord[i];
460          switch(axis)
461          {
462              case 0: a = x; break;
463              case 1: a = y; break;
464              case 2: a = z; break;
465          }
466          a *= PiDiv180;
467 
468          obj_init_matrix( N );
469          obj_internal_rotate_matrix( N,sin(a),cos(a),axis );
470 
471          obj_mult_matrix_right( M,N );
472      }
473 }
474 
475 /*******************************************************************************
476  *
477  *     Name:          obj_rotate_mult_matrix( transform_t *,double *,double *,double *)
478  *
479  *     Purpose:       return matrix_t corresponding to rotation  about
480  *                    three axes by angles given multiplied by objects
481  *                    transformation matrix. Internal only.
482  *
483  *     Parameters:
484  *
485  *         Input:    (transform_t *)
486  *
487  *                    (double *) angle about 'x' - axis
488  *                    (double *) angle about 'y' - axis
489  *                    (double *) angle about 'z' - axis
490  *
491  *         Output:   (transform_t *)->RotMatrix is modified as are the
492  *                   angles.
493  *
494  *   Return value:    void
495  *
496  ******************************************************************************/
497 #define ROUND_PI(A) (180*(int)(((A)>0?(A)+90.0:(A)-90.0)/180.0))
498 
obj_rotate_mult_matrix(transform_t * transform,double * x,double * y,double * z)499 static void obj_rotate_mult_matrix(transform_t *transform,double *x,double *y,double *z )
500 {
501    matrix_t M;
502 
503    int i,j;
504    double a;
505 
506     for( i=0; i<3; i++ )
507     {
508         switch(i)
509         {
510             case 0: a = *x; break;
511             case 1: a = *y; break;
512             case 2: a = *z; break;
513         }
514         a *= PiDiv180;
515 
516         obj_init_matrix( M );
517         obj_internal_rotate_matrix( M,sin(a),cos(a),i );
518 
519         if ( transform->RotationPriority == rot_pri_local )
520         {
521             obj_mult_matrix_left( transform->RotMatrix,M );
522         } else if ( transform->RotationPriority == rot_pri_parent )
523         {
524             obj_mult_matrix_right( transform->RotMatrix,M );
525         }
526     }
527 
528     obj_copy_matrix( M,transform->RotMatrix );
529 
530     *x =  atan2( M[2][1],M[2][2] ) / PiDiv180;
531     *y = -asin(  M[2][0] )/ PiDiv180;
532     *z =  atan2( M[1][0],M[0][0] ) / PiDiv180;
533 
534     *x += ROUND_PI( transform->RotX - *x );
535     *y += ROUND_PI( transform->RotY - *y );
536     *z += ROUND_PI( transform->RotZ - *z );
537 }
538 
539 /*******************************************************************************
540  *
541  *     Name:          obj_compute_matrix( transform_t * )
542  *
543  *     Purpose:       Return total transformation matrix_t given rotations,
544  *                    scaleing, and translations. Internal only.
545  *
546  *     Parameters:
547  *
548  *         Input:    (transform_t *)
549  *
550  *         Output:   (transform_t *)->Matrix is modified
551  *
552  *   Return value:    void
553  *
554  ******************************************************************************/
obj_compute_matrix(transform_t * transform)555 static void obj_compute_matrix( transform_t *transform )
556 {
557     transform_list_t *child;
558 
559     matrix_t M;
560 
561     obj_init_matrix( M );
562 
563     switch( transform->TransformPriority )
564     {
565        case trn_pri_trs: obj_mult_matrix( M,transform->TrnMatrix );
566                          obj_mult_matrix( M,transform->RotMatrix );
567                          obj_mult_matrix( M,transform->SclMatrix );
568        break;
569 
570        case trn_pri_tsr: obj_mult_matrix( M,transform->TrnMatrix );
571                          obj_mult_matrix( M,transform->SclMatrix );
572                          obj_mult_matrix( M,transform->RotMatrix );
573        break;
574 
575        case trn_pri_rts: obj_mult_matrix( M,transform->RotMatrix );
576                          obj_mult_matrix( M,transform->TrnMatrix );
577                          obj_mult_matrix( M,transform->SclMatrix );
578        break;
579 
580        case trn_pri_rst: obj_mult_matrix( M,transform->RotMatrix );
581                          obj_mult_matrix( M,transform->SclMatrix );
582                          obj_mult_matrix( M,transform->TrnMatrix );
583        break;
584 
585        case trn_pri_str: obj_mult_matrix( M,transform->SclMatrix );
586                          obj_mult_matrix( M,transform->TrnMatrix );
587                          obj_mult_matrix( M,transform->RotMatrix );
588        break;
589 
590        case trn_pri_srt: obj_mult_matrix( M,transform->SclMatrix );
591                          obj_mult_matrix( M,transform->RotMatrix );
592                          obj_mult_matrix( M,transform->TrnMatrix );
593        break;
594     }
595 
596     if ( transform->Parent && transform->Parent != transform )
597     {
598         memcpy( transform->Matrix, transform->Parent->Matrix, sizeof(matrix_t) );
599         obj_mult_matrix( transform->Matrix,M );
600     } else
601     {
602         obj_copy_matrix( transform->Matrix,M );
603     }
604 
605     for( child = transform->Children; child != NULL; child = child->Next )
606     {
607         obj_compute_matrix( child->Entry );
608     }
609 }
610 
611 
612 /*******************************************************************************
613  *
614  *     Name:          obj_set_parent( object_t *obj, object_t *parent )
615  *
616  *     Purpose:       Set transformation parent of an object
617  *
618  *     Parameters:
619  *
620  *         Input:    both structures are read
621  *
622  *         Output:   both structures are modified
623  *
624  *   Return value:    malloc() success
625  *
626  ******************************************************************************/
obj_set_parent(object_t * object,object_t * parent)627 int obj_set_parent( object_t *object,object_t *parent )
628 {
629     transform_t *objtrans = &object->Transform;
630     transform_t *partrans = &parent->Transform;
631 
632     transform_list_t *child;
633 
634     if ( object == parent ) return TRUE;
635 
636     objtrans->Parent = partrans;
637 
638     if ( !(child = (transform_list_t *)calloc(1,sizeof(transform_list_t)) ) )
639     {
640         fprintf( stderr, "obj_set_parent: FATAL: can't allocate a few bytes of memory.\n" );
641         return FALSE;
642     }
643 
644     child->Entry = objtrans;
645     child->Next  = partrans->Children;
646 
647     partrans->Children = child;
648 
649     obj_compute_matrix( objtrans );
650 
651     return TRUE;
652 }
653 
654 /*******************************************************************************
655  *
656  *     Name:          obj_rotate( object_t *,double,double,double,int,int )
657  *
658  *     Purpose:       Modifify object transformation matrix given rotations
659  *
660  *     Parameters:
661  *
662  *         Input:    (object_t *)
663  *                   (double,double,double) input rotations
664  *                   (int) flag if rotations should be relative (TRUE)
665  *                          or absolute (FALSE)
666  *
667  *         Output:   (object->Transform_t *)->XXXMatrix are modified
668  *
669  *   Return value:    void
670  *
671  ******************************************************************************/
obj_rotate(object_t * object,double x,double y,double z,int which,int relative)672 void obj_rotate( object_t *object,double x,double y,double z,int which,int relative )
673 {
674     double rx,ry,rz;
675 
676     transform_t *transform = &object->Transform;
677 
678     switch( which )
679     {
680         case 'x': if ( transform->RotationPriority < rot_pri_local )
681                   {
682                       if ( relative ) x += transform->RotX;
683                       y  = transform->RotY;
684                       z  = transform->RotZ;
685                   } else
686                   {
687                       if ( !relative )
688                       {
689                           x -= transform->RotX;
690                       }
691                       y = z = 0.0;
692                   }
693         break;
694 
695         case 'y': if ( transform->RotationPriority < rot_pri_local )
696                   {
697                       if ( relative ) y = x + transform->RotY; else y = x;
698                       x  = transform->RotX;
699                       z  = transform->RotZ;
700                   } else
701                   {
702                       if ( relative )
703                       {
704                           y = x;
705                       } else
706                       {
707                           y = x - transform->RotY;
708                       }
709                       x = z = 0.0;
710                   }
711         break;
712 
713         case 'z': if ( transform->RotationPriority < rot_pri_local )
714                   {
715                       if ( relative ) z = x + transform->RotZ; else z = x;
716                       x  = transform->RotX;
717                       y  = transform->RotY;
718                   } else
719                   {
720                       if ( relative )
721                       {
722                           z = x;
723                       } else
724                       {
725                           z = x - transform->RotZ;
726                       }
727                       x = y = 0.0;
728                   }
729         break;
730 
731         case 'a': if ( transform->RotationPriority < rot_pri_local )
732                   {
733                       if ( relative )
734                       {
735                           x += transform->RotX;
736                           y += transform->RotY;
737                           z += transform->RotZ;
738                       }
739                   } else
740                   {
741                       if ( !relative ) obj_init_matrix( transform->RotMatrix );
742                   }
743         break;
744     }
745 
746     if ( transform->RotationPriority >= rot_pri_local )
747     {
748         obj_rotate_mult_matrix( transform,&x,&y,&z );
749     } else
750     {
751         obj_rotate_matrix( transform->RotMatrix,transform->RotationPriority,x,y,z );
752     }
753 
754     transform->RotX = x;
755     transform->RotY = y;
756     transform->RotZ = z;
757 
758     obj_compute_matrix( transform );
759 }
760 
761 /*******************************************************************************
762  *
763  *     Name:          obj_scale( object_t *,double,double,double,int,int )
764  *
765  *     Purpose:       Modifify object transformation matrix given scaleings
766  *
767  *     Parameters:
768  *
769  *         Input:    (object_t *)
770  *                   (double,double,double) input scaleings
771  *                   (int) flag if scaleings should be relative (TRUE)
772  *                          or absolute (FALSE)
773  *
774  *         Output:   (object->Transform_t *)->XXXMatrix are modified
775  *
776  *   Return value:    void
777  *
778  ******************************************************************************/
obj_scale(object_t * object,double x,double y,double z,int which,int relative)779 void obj_scale( object_t *object,double x,double y,double z,int which, int relative )
780 {
781     transform_t *transform = &object->Transform;
782     double s;
783 
784     if ( relative )
785     {
786         switch( which )
787         {
788             case 's': s = 1+x;
789                       x = s*transform->SclX;
790                       y = s*transform->SclY;
791                       z = s*transform->SclZ;
792             break;
793 
794             case 'x': x = (1+x)*transform->SclX; break;
795             case 'y': y = (1+x)*transform->SclY; break;
796             case 'z': z = (1+x)*transform->SclZ; break;
797 
798             case 'a': x = (1+x)*transform->SclX;
799                       y = (1+y)*transform->SclY;
800                       z = (1+z)*transform->SclZ;
801             break;
802         }
803     }
804 
805     if ( x > 0 )
806     {
807         x = MAX(x, 1.0e-6);
808     } else {
809         x = MIN(x,-1.0e-6);
810     }
811 
812     if ( y > 0 )
813     {
814         y = MAX(y, 1.0e-6);
815     } else {
816         y = MIN(y,-1.0e-6);
817     }
818 
819     if ( z > 0 )
820     {
821         z = MAX(z, 1.0e-6);
822     } else {
823         z = MIN(z,-1.0e-6);
824     }
825 
826     switch( which )
827     {
828         case 'a': transform->SclX = x;
829                   transform->SclY = y;
830                   transform->SclZ = z;
831         break;
832 
833         case 'x': transform->SclX = x; break;
834         case 'y': transform->SclY = y; break;
835         case 'z': transform->SclZ = z; break;
836     }
837 
838     obj_scale_matrix(
839                                       transform->SclMatrix,
840                     transform->SclX, transform->SclY, transform->SclZ
841                 );
842 
843     obj_compute_matrix( transform );
844 }
845 
846 /*******************************************************************************
847  *
848  *     Name:          obj_translate( object_t *,double,double,double,int,int  )
849  *
850  *     Purpose:       Modifify object transformation matrix given translations
851  *
852  *     Parameters:
853  *
854  *         Input:    (object_t *)
855  *                   (double,double,double) input translations
856  *                   (int) flag if translations should be relative (TRUE)
857  *                          or absolute (FALSE)
858  *
859  *         Output:   (object->Transform_t *)->XXXMatrix are modified
860  *
861  *   Return value:    void
862  *
863  ******************************************************************************/
obj_translate(object_t * object,double x,double y,double z,int which,int relative)864 void obj_translate( object_t *object,double x,double y,double z,int which,int relative )
865 {
866     transform_t *transform = &object->Transform;
867 
868     switch( which )
869     {
870         case 'x': transform->TrnX = (relative?transform->TrnX:0.0)+x; break;
871         case 'y': transform->TrnY = (relative?transform->TrnY:0.0)+x; break;
872         case 'z': transform->TrnZ = (relative?transform->TrnZ:0.0)+x; break;
873         case 'a': if ( relative )
874                   {
875                       transform->TrnX += x;
876                       transform->TrnY += y;
877                       transform->TrnZ += z;
878                   } else
879                   {
880                       transform->TrnX  = x;
881                       transform->TrnY  = y;
882                       transform->TrnZ  = z;
883                   }
884         break;
885     }
886 
887     obj_translate_matrix(
888                                 transform->TrnMatrix,
889                     transform->TrnX, transform->TrnY, transform->TrnZ
890                 );
891 
892     obj_compute_matrix( transform );
893 }
894 
895 /*******************************************************************************
896  *
897  *     Name:          obj_set_matrix( object_t * )
898  *
899  *     Purpose:       Tell graphics module about transformation matrix of
900  *                    a given object
901  *
902  *     Parameters:
903  *
904  *         Input:     (object_t *)
905  *
906  *         Output:    none
907  *
908  *   Return value:    void
909  *
910  ******************************************************************************/
obj_set_matrix(object_t * object)911 void obj_set_matrix( object_t *object )
912 {
913     transform_t *transform = &object->Transform;
914     matrix_t matrix;
915 
916     obj_get_matrix_transpose( matrix,object );
917 
918     gra_mult_matrix( matrix );
919 }
920