Fix crash if Num_walls=0
[btb/d2x.git] / 3d / instance.c
1 /* $Id: instance.c,v 1.5 2004-08-28 23:17:45 schaffner Exp $ */
2 /*
3 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
4 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
5 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
6 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
7 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
8 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
9 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
10 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
11 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
12 COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
13 */
14 /*
15  * 
16  * Instancing routines
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <conf.h>
22 #endif
23
24 #include <stdlib.h>
25 #include "error.h"
26
27 #include "3d.h"
28 #include "globvars.h"
29
30 #define MAX_INSTANCE_DEPTH      5
31
32 struct instance_context {
33         vms_matrix m;
34         vms_vector p;
35 } instance_stack[MAX_INSTANCE_DEPTH];
36
37 int instance_depth = 0;
38
39 //instance at specified point with specified orientation
40 //if matrix==NULL, don't modify matrix.  This will be like doing an offset   
41 void g3_start_instance_matrix(vms_vector *pos,vms_matrix *orient)
42 {
43         vms_vector tempv;
44         vms_matrix tempm,tempm2;
45
46 #ifdef D1XD3D
47         Win32_start_instance_matrix (pos, orient);
48 #endif
49
50         Assert(instance_depth<MAX_INSTANCE_DEPTH);
51
52         instance_stack[instance_depth].m = View_matrix;
53         instance_stack[instance_depth].p = View_position;
54         instance_depth++;
55
56         //step 1: subtract object position from view position
57
58         vm_vec_sub(&tempv,&View_position,pos);
59
60
61         if (orient) {
62
63                 //step 2: rotate view vector through object matrix
64
65                 vm_vec_rotate(&View_position,&tempv,orient);
66
67                 //step 3: rotate object matrix through view_matrix (vm = ob * vm)
68
69                 vm_copy_transpose_matrix(&tempm2,orient);
70
71                 vm_matrix_x_matrix(&tempm,&tempm2,&View_matrix);
72                 View_matrix = tempm;
73         }
74 }
75
76
77 //instance at specified point with specified orientation
78 //if angles==NULL, don't modify matrix.  This will be like doing an offset
79 void g3_start_instance_angles(vms_vector *pos,vms_angvec *angles)
80 {
81         vms_matrix tm;
82
83         if (angles==NULL) {
84                 g3_start_instance_matrix(pos,NULL);
85                 return;
86         }
87
88         vm_angles_2_matrix(&tm,angles);
89
90         g3_start_instance_matrix(pos,&tm);
91
92 }
93
94
95 //pops the old context
96 void g3_done_instance()
97 {
98 #ifdef D1XD3D
99         Win32_done_instance ();
100 #endif
101
102         instance_depth--;
103
104         Assert(instance_depth >= 0);
105
106         View_position = instance_stack[instance_depth].p;
107         View_matrix = instance_stack[instance_depth].m;
108 }
109
110