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