Starshatter_Open
Open source Starshatter engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
DetailSet.cpp
Go to the documentation of this file.
1 /* Project Starshatter 4.5
2  Destroyer Studios LLC
3  Copyright © 1997-2004. All Rights Reserved.
4 
5  SUBSYSTEM: Stars.exe
6  FILE: DetailSet.cpp
7  AUTHOR: John DiCamillo
8 
9 
10  OVERVIEW
11  ========
12  Level of Detail manager class
13 */
14 
15 #include "MemDebug.h"
16 #include "DetailSet.h"
17 #include "Random.h"
18 
19 #include "Game.h"
20 
21 // +--------------------------------------------------------------------+
22 
25 
26 // +--------------------------------------------------------------------+
27 
29 {
30  for (int i = 0; i < MAX_DETAIL; i++)
31  rad[i] = 0;
32 
33  index = -1;
34  levels = 0;
35  rgn = 0;
36 }
37 
39 {
40  Destroy();
41 }
42 
43 // +--------------------------------------------------------------------+
44 
45 int
46 DetailSet::DefineLevel(double r, Graphic* g, Point* o, Point* spin_rate)
47 {
48  if (levels < MAX_DETAIL && rep[levels].size() == 0) {
49  rad[levels] = r;
50 
51  if (g)
52  rep[levels].append(g);
53 
54  if (o)
55  off[levels].append(o);
56 
57  else if (g)
58  off[levels].append(new(__FILE__,__LINE__) Point(0,0,0));
59 
60  if (rate.size() == 0) {
61  if (spin_rate) {
62  rate.append(spin_rate);
63 
64  // randomize the initial orientation:
65  Point* initial_spin = new(__FILE__,__LINE__) Point();
66  if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI);
67  if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI);
68  if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI);
69 
70  spin.append(initial_spin);
71  }
72  else {
73  rate.append(new(__FILE__,__LINE__) Point());
74  spin.append(new(__FILE__,__LINE__) Point());
75  }
76  }
77  else {
78  if (spin_rate)
79  rate[ rep[levels].size() - 1 ] = spin_rate;
80  }
81 
82  levels++;
83  }
84 
85  return levels-1;
86 }
87 
88 void
89 DetailSet::AddToLevel(int level, Graphic* g, Point* offset, Point* spin_rate)
90 {
91  if (g && level >= 0 && level < levels) {
92  rep[level].append(g);
93 
94  if (!offset)
95  offset = new(__FILE__,__LINE__) Point(0,0,0);
96 
97  off[level].append(offset);
98 
99  if (spin_rate) {
100  int nrep = rep[level].size();
101  if (nrep > rate.size())
102  rate.append(spin_rate);
103  else
104  rate[ nrep-1 ] = spin_rate;
105  }
106 
107  if (spin.size() < rep[level].size()) {
108  Point* initial_spin = new(__FILE__,__LINE__) Point();
109 
110  if (spin_rate) {
111  // randomize the initial orientation:
112  if (spin_rate->x != 0) initial_spin->x = Random(-PI, PI);
113  if (spin_rate->y != 0) initial_spin->y = Random(-PI, PI);
114  if (spin_rate->z != 0) initial_spin->z = Random(-PI, PI);
115  }
116 
117  spin.append(initial_spin);
118  }
119  }
120 }
121 
122 int
123 DetailSet::NumModels(int level) const
124 {
125  if (level >= 0 && level < levels)
126  return rep[level].size();
127 
128  return 0;
129 }
130 
131 // +--------------------------------------------------------------------+
132 
133 void
134 DetailSet::ExecFrame(double seconds)
135 {
136  for (int i = 0; i < spin.size() && i < rate.size(); i++)
137  (*spin[i]) += (*rate[i]) * seconds;
138 }
139 
140 // +--------------------------------------------------------------------+
141 
142 void
144 {
145  rgn = r;
146  loc = p;
147 }
148 
149 // +--------------------------------------------------------------------+
150 
151 void
153 {
154  ref_rgn = r;
155  ref_loc = p;
156 }
157 
158 // +--------------------------------------------------------------------+
159 
160 int
162 {
163  index = 0;
164 
165  if (rgn == ref_rgn) {
166  double screen_width = Game::GetScreenWidth();
167  Point delta = loc - ref_loc;
168  double distance = delta.length();
169 
170  for (int i = 1; i < levels && rad[i] > 0; i++) {
171  double apparent_feature_size = (rad[i] * screen_width) / distance;
172 
173  if (apparent_feature_size > 0.4)
174  index = i;
175  }
176  }
177 
178  return index;
179 }
180 
181 // +--------------------------------------------------------------------+
182 
183 Graphic*
184 DetailSet::GetRep(int level, int n)
185 {
186  if (level >= 0 && level < levels && n >= 0 && n < rep[level].size())
187  return rep[level].at(n);
188 
189  return 0;
190 }
191 
192 Point
193 DetailSet::GetOffset(int level, int n)
194 {
195  if (level >= 0 && level < levels && n >= 0 && n < off[level].size())
196  return *(off[level].at(n));
197 
198  return Point();
199 }
200 
201 Point
202 DetailSet::GetSpin(int level, int n)
203 {
204  if (n >= 0 && n < spin.size())
205  return *(spin.at(n));
206 
207  return Point();
208 }
209 
210 // +--------------------------------------------------------------------+
211 
212 void
214 {
215  for (int i = 0; i < levels; i++) {
216  ListIter<Graphic> iter = rep[i];
217 
218  while (++iter) {
219  Graphic* g = iter.removeItem();
220  g->Destroy(); // this will delete the object (g)
221  }
222 
223  off[i].destroy();
224  }
225 
226  rate.destroy();
227  spin.destroy();
228 }