More header unification...
[btb/d2x.git] / 3d / instance.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13 /*
14  * $Source: /cvs/cvsroot/d2x/3d/instance.c,v $
15  * $Revision: 1.1.1.1 $
16  * $Author: bradleyb $
17  * $Date: 2001-01-19 03:29:58 $
18  * 
19  * Instancing routines
20  * 
21  * $Log: not supported by cvs2svn $
22  * Revision 1.1.1.1  1999/06/14 21:57:45  donut
23  * Import of d1x 1.37 source.
24  *
25  * Revision 1.2  1995/06/12  12:36:57  allender
26  * fixed bug where g3_start_instance_angles recursively called itself
27  *
28  * Revision 1.1  1995/05/05  08:51:27  allender
29  * Initial revision
30  *
31  * Revision 1.1  1995/04/17  06:43:29  matt
32  * Initial revision
33  * 
34  * 
35  */
36
37 #ifdef RCS
38 static char rcsid[] = "$Id: instance.c,v 1.1.1.1 2001-01-19 03:29:58 bradleyb Exp $";
39 #endif
40
41 #include <conf.h>
42 #include <stdlib.h>
43 #include "error.h"
44
45 #include "fix.h"
46 #include "vecmat.h"
47 #include "gr.h"
48 #include "3d.h"
49 #include "globvars.h"
50
51 #define MAX_INSTANCE_DEPTH      5
52
53 struct instance_context {
54         vms_matrix m;
55         vms_vector p;
56 } instance_stack[MAX_INSTANCE_DEPTH];
57
58 int instance_depth = 0;
59
60 //instance at specified point with specified orientation
61 //if matrix==NULL, don't modify matrix.  This will be like doing an offset   
62 void g3_start_instance_matrix(vms_vector *pos,vms_matrix *orient)
63 {
64         vms_vector tempv;
65         vms_matrix tempm,tempm2;
66
67 #ifdef D1XD3D
68         Win32_start_instance_matrix (pos, orient);
69 #endif
70
71         Assert(instance_depth<MAX_INSTANCE_DEPTH);
72
73         instance_stack[instance_depth].m = View_matrix;
74         instance_stack[instance_depth].p = View_position;
75         instance_depth++;
76
77         //step 1: subtract object position from view position
78
79         vm_vec_sub(&tempv,&View_position,pos);
80
81
82         if (orient) {
83
84                 //step 2: rotate view vector through object matrix
85
86                 vm_vec_rotate(&View_position,&tempv,orient);
87
88                 //step 3: rotate object matrix through view_matrix (vm = ob * vm)
89
90                 vm_copy_transpose_matrix(&tempm2,orient);
91
92                 vm_matrix_x_matrix(&tempm,&tempm2,&View_matrix);
93                 View_matrix = tempm;
94         }
95 }
96
97
98 //instance at specified point with specified orientation
99 //if angles==NULL, don't modify matrix.  This will be like doing an offset
100 void g3_start_instance_angles(vms_vector *pos,vms_angvec *angles)
101 {
102         vms_matrix tm;
103
104         if (angles==NULL) {
105                 g3_start_instance_matrix(pos,NULL);
106                 return;
107         }
108
109         vm_angles_2_matrix(&tm,angles);
110
111         g3_start_instance_matrix(pos,&tm);
112
113 }
114
115
116 //pops the old context
117 void g3_done_instance()
118 {
119 #ifdef D1XD3D
120         Win32_done_instance ();
121 #endif
122
123         instance_depth--;
124
125         Assert(instance_depth >= 0);
126
127         View_position = instance_stack[instance_depth].p;
128         View_matrix = instance_stack[instance_depth].m;
129 }
130
131