Commit a7b403827fb3abdd039092fbde19bf58bec40323
merged Dev into Branch_Detection
Showing
8 changed files
with
567 additions
and
302 deletions
Show diff stats
stim/envi/binary.h
... | ... | @@ -225,6 +225,10 @@ public: |
225 | 225 | return true; |
226 | 226 | } |
227 | 227 | |
228 | + /// Reads a plane given a coordinate along the 0-axis (YZ plane) | |
229 | + | |
230 | + /// @param p is a pointer to pre-allocated memory of size R[1] * R[2] * sizeof(T) | |
231 | + /// @param n is the 0-axis coordinate used to retrieve the plane | |
228 | 232 | bool read_plane_0(T* p, unsigned int n){ |
229 | 233 | |
230 | 234 | if (n >= R[0]){ //make sure the number is within the possible range |
... | ... | @@ -247,6 +251,10 @@ public: |
247 | 251 | |
248 | 252 | } |
249 | 253 | |
254 | + /// Reads a plane given a coordinate along the 1-axis (XZ plane) | |
255 | + | |
256 | + /// @param p is a pointer to pre-allocated memory of size R[0] * R[2] * sizeof(T) | |
257 | + /// @param n is the 1-axis coordinate used to retrieve the plane | |
250 | 258 | bool read_plane_1(T* p, unsigned int n){ |
251 | 259 | |
252 | 260 | unsigned int L = R[0] * sizeof(T); //caculate the number of bytes in a sample line |
... | ... | @@ -268,10 +276,18 @@ public: |
268 | 276 | return true; |
269 | 277 | } |
270 | 278 | |
279 | + /// Reads a plane given a coordinate along the 2-axis (XY plane) | |
280 | + | |
281 | + /// @param p is a pointer to pre-allocated memory of size R[0] * R[1] * sizeof(T) | |
282 | + /// @param n is the 2-axis coordinate used to retrieve the plane | |
271 | 283 | bool read_plane_2(T* p, unsigned int n){ |
272 | 284 | return read_page(p, n); |
273 | 285 | } |
274 | 286 | |
287 | + /// Reads a single pixel, treating the entire data set as a linear array | |
288 | + | |
289 | + /// @param p is a pointer to pre-allocated memory of size sizeof(T) | |
290 | + /// @param i is the index to the pixel using linear indexing | |
275 | 291 | bool read_pixel(T* p, unsigned int i){ |
276 | 292 | if(i >= R[0] * R[1] * R[2]){ |
277 | 293 | std::cout<<"ERROR read_pixel: n is out of range"<<std::endl; |
... | ... | @@ -283,6 +299,12 @@ public: |
283 | 299 | |
284 | 300 | } |
285 | 301 | |
302 | + /// Reads a single pixel, given an x, y, z coordinate | |
303 | + | |
304 | + /// @param p is a pointer to pre-allocated memory of size sizeof(T) | |
305 | + /// @param x is the x (0) axis coordinate | |
306 | + /// @param y is the y (1) axis coordinate | |
307 | + /// @param z is the z (2) axis coordinate | |
286 | 308 | bool read_pixel(T* p, unsigned int x, unsigned int y, unsigned int z){ |
287 | 309 | |
288 | 310 | if(x < 0 || x >= R[0] || y < 0 || y >= R[1] || z < 0 || z > R[2]){ |
... | ... | @@ -294,54 +316,6 @@ public: |
294 | 316 | return read_pixel(p, i); |
295 | 317 | } |
296 | 318 | |
297 | - //saves a hyperplane orthogonal to dimension d at intersection n | |
298 | - /*bool read_plane(T * dest, unsigned int d, unsigned int n){ | |
299 | - | |
300 | - //reset the file pointer back to the beginning of the file | |
301 | - file.seekg(0, std::ios::beg); | |
302 | - | |
303 | - //compute the contiguous size C for each readable block | |
304 | - unsigned int C = 1; | |
305 | - for(unsigned int i = 0; i < d; i++) //for each dimension less than d | |
306 | - C *= R[i]; //compute the product | |
307 | - | |
308 | - //compute the non-contiguous size NC for each readable block | |
309 | - unsigned int NC = 1; | |
310 | - for(unsigned int i = d + 1; i < D; i++) | |
311 | - NC *= R[i]; | |
312 | - | |
313 | - //for all noncontiguous blocks, read each contiguous block that makes up the hyper-plane | |
314 | - for(unsigned int nc = 0; nc < NC; nc++){ | |
315 | - file.seekg(n * C * sizeof(T), std::ios::cur); //skip n contiguous blocks | |
316 | - file.read( (char*)&dest[nc * C], C * sizeof(T)); //read one contiguous block | |
317 | - file.seekg( (R[d] - n - 1) * C * sizeof(T), std::ios::cur); //skip R[d] - n contiguous blocks | |
318 | - } | |
319 | - | |
320 | - return true; | |
321 | - | |
322 | - }*/ | |
323 | - | |
324 | - //save one pixel of the file into the memory, and return the pointer | |
325 | - /*bool read_spectrum(T * p, unsigned x, unsigned y){ | |
326 | - | |
327 | - unsigned int i; | |
328 | - | |
329 | - if ( x >= R[0] || y >= R[1]){ //make sure the sample and line number is right | |
330 | - std::cout<<"ERROR: sample or line out of range"<<std::endl; | |
331 | - return false; | |
332 | - } | |
333 | - | |
334 | - file.seekg((x + y * R[0]) * sizeof(T), std::ios::beg); //point to the certain sample and line | |
335 | - for (i = 0; i < R[2]; i++) | |
336 | - { | |
337 | - file.read((char *)(p + i), sizeof(T)); | |
338 | - file.seekg((R[1] * R[0] - 1) * sizeof(T), std::ios::cur); //go to the next band | |
339 | - } | |
340 | - | |
341 | - return true; | |
342 | - }*/ | |
343 | - | |
344 | - | |
345 | 319 | }; |
346 | 320 | |
347 | 321 | } | ... | ... |
stim/envi/envi.h
... | ... | @@ -710,6 +710,11 @@ public: |
710 | 710 | return false; |
711 | 711 | } |
712 | 712 | |
713 | + /// Retrieve a spectrum from the specified location | |
714 | + | |
715 | + /// @param ptr is a pointer to pre-allocated memory of size B*sizeof(T) | |
716 | + /// @param x is the x-coordinate of the spectrum | |
717 | + /// @param y is the y-coordinate of the spectrum | |
713 | 718 | bool spectrum(void* ptr, unsigned int x, unsigned int y){ |
714 | 719 | |
715 | 720 | if(header.interleave == envi_header::BSQ){ //if the infile is bsq file | ... | ... |
stim/gl/gl_spider.h
... | ... | @@ -29,32 +29,33 @@ namespace stim |
29 | 29 | { |
30 | 30 | |
31 | 31 | template<typename T> |
32 | -class gl_spider : public virtual gl_texture<T> | |
32 | +class gl_spider | |
33 | 33 | { |
34 | 34 | //doen't use gl_texture really, just needs the GLuint id. |
35 | 35 | //doesn't even need the texture iD really. |
36 | 36 | private: |
37 | - stim::vec<float> position; //vector designating the position of the spider. | |
38 | - stim::vec<float> direction; //vector designating the orientation of the spider | |
37 | + stim::vec<float> p; //vector designating the position of the spider. | |
38 | + stim::vec<float> d; //vector designating the orientation of the spider | |
39 | 39 | //always a unit vector. |
40 | - stim::vec<float> magnitude; //magnitude of the direction vector. | |
40 | + stim::vec<float> m; //magnitude of the spider vector. | |
41 | 41 | //mag[0] = length. |
42 | 42 | //mag[1] = width. |
43 | - std::vector<stim::vec<float> > dirVectors; | |
44 | - std::vector<stim::vec<float> > posVectors; | |
45 | - std::vector<stim::vec<float> > magVectors; | |
46 | - stim::matrix<float, 4> currentTransform; | |
47 | - using gl_texture<T>::texID; | |
48 | - using gl_texture<T>::S; | |
49 | - using gl_texture<T>::R; | |
43 | + std::vector<stim::vec<float> > dV; | |
44 | + std::vector<stim::vec<float> > pV; | |
45 | + std::vector<stim::vec<float> > mV; | |
46 | + //currentTransform | |
47 | + stim::matrix<float, 4> cT; | |
48 | + GLuint texID; | |
49 | + stim::vec<float> S; | |
50 | + stim::vec<float> R; | |
50 | 51 | cudaGraphicsResource_t resource; |
51 | 52 | |
52 | 53 | GLuint dList; |
53 | - GLubyte list[4]; | |
54 | 54 | GLuint fboID; |
55 | 55 | GLuint texbufferID; |
56 | 56 | int iter; //temporary for testing |
57 | 57 | int numSamples; |
58 | + float stepsize = 3.0; | |
58 | 59 | |
59 | 60 | /// Method for finding the best scale for the spider. |
60 | 61 | /// changes the x, y, z size of the spider to minimize the cost |
... | ... | @@ -62,45 +63,41 @@ class gl_spider : public virtual gl_texture<T> |
62 | 63 | void |
63 | 64 | findOptimalDirection() |
64 | 65 | { |
65 | - //genTemplate(dirVectors, 0); | |
66 | - Bind(); | |
67 | - positionTemplate(); | |
66 | + //genTemplate(dV, 0); | |
67 | + setMatrix(); | |
68 | 68 | glCallList(dList); |
69 | 69 | int best = getCost(); |
70 | 70 | stim::vec<float, 4> next; |
71 | - next[0] = dirVectors[best][0]*S[1]*R[1]; | |
72 | - next[1] = dirVectors[best][1]*S[2]*R[2]; | |
73 | - next[2] = dirVectors[best][2]*S[3]*R[3]; | |
71 | + next[0] = dV[best][0]*S[0]*R[0]; | |
72 | + next[1] = dV[best][1]*S[1]*R[1]; | |
73 | + next[2] = dV[best][2]*S[2]*R[2]; | |
74 | 74 | next[3] = 1; |
75 | - next = (currentTransform*next).norm(); | |
76 | - setPosition( position[0]+next[0]*magnitude[0]/3, | |
77 | - position[1]+next[1]*magnitude[0]/3, | |
78 | - position[2]+next[2]*magnitude[0]/3); | |
75 | + next = (cT*next).norm(); | |
76 | + setPosition( p[0]+next[0]*m[0]/stepsize, | |
77 | + p[1]+next[1]*m[0]/stepsize, | |
78 | + p[2]+next[2]*m[0]/stepsize); | |
79 | 79 | setDirection(next[0], next[1], next[2]); |
80 | - Unbind(); | |
81 | 80 | } |
82 | 81 | |
83 | - /// Method for finding the best direction for the spider. | |
84 | - /// Not sure if necessary since the next position for the spider | |
85 | - /// will be at direction * magnitude. | |
82 | + /// Method for finding the best d for the spider. | |
83 | + /// Not sure if necessary since the next p for the spider | |
84 | + /// will be at d * m. | |
86 | 85 | void |
87 | 86 | findOptimalPosition() |
88 | 87 | { |
89 | - Bind(); | |
90 | - positionTemplate(); | |
88 | + setMatrix(); | |
91 | 89 | glCallList(dList+1); |
92 | 90 | int best = getCost(); |
93 | 91 | stim::vec<float, 4> next; |
94 | - next[0] = posVectors[best][0]; | |
95 | - next[1] = posVectors[best][1]; | |
96 | - next[2] = posVectors[best][2]; | |
92 | + next[0] = pV[best][0]; | |
93 | + next[1] = pV[best][1]; | |
94 | + next[2] = pV[best][2]; | |
97 | 95 | next[3] = 1; |
98 | - next = currentTransform*next; | |
99 | - std::cout << "Optimal Position:"<< next << std::endl; | |
100 | - setPosition( next[0]*S[1]*R[1], | |
101 | - next[1]*S[2]*R[2], | |
102 | - next[2]*S[3]*R[3]); | |
103 | - Unbind(); | |
96 | + next = cT*next; | |
97 | + std::cout << "Optimal p:"<< next << std::endl; | |
98 | + setPosition( next[0]*S[0]*R[0], | |
99 | + next[1]*S[1]*R[1], | |
100 | + next[2]*S[2]*R[2]); | |
104 | 101 | } |
105 | 102 | |
106 | 103 | /// Method for finding the best scale for the spider. |
... | ... | @@ -109,19 +106,17 @@ class gl_spider : public virtual gl_texture<T> |
109 | 106 | void |
110 | 107 | findOptimalScale() |
111 | 108 | { |
112 | - Bind(); | |
113 | - positionTemplate(); | |
109 | + setMatrix(); | |
114 | 110 | glCallList(dList+2); |
115 | 111 | int best = getCost(); |
116 | 112 | stim::vec<float, 4> next; |
117 | - next[0] = magVectors[best][0]*S[1]*R[1]; | |
118 | - next[1] = magVectors[best][1]*S[2]*R[2]; | |
119 | - next[2] = magVectors[best][2]*S[3]*R[3]; | |
113 | + next[0] = mV[best][0]*S[0]*R[0]; | |
114 | + next[1] = mV[best][1]*S[1]*R[1]; | |
115 | + next[2] = mV[best][2]*S[2]*R[2]; | |
120 | 116 | next[3] = 1; |
121 | - next = currentTransform*next; | |
117 | + next = cT*next; | |
122 | 118 | std::cout << "Optimal Scale:"<< next << std::endl; |
123 | 119 | setMagnitude(next[0]); |
124 | - Unbind(); | |
125 | 120 | } |
126 | 121 | |
127 | 122 | void |
... | ... | @@ -140,7 +135,7 @@ class gl_spider : public virtual gl_texture<T> |
140 | 135 | void |
141 | 136 | Optimize() |
142 | 137 | { |
143 | - /*find the optimum direction and scale */ | |
138 | + /*find the optimum d and scale */ | |
144 | 139 | } |
145 | 140 | |
146 | 141 | |
... | ... | @@ -152,35 +147,53 @@ class gl_spider : public virtual gl_texture<T> |
152 | 147 | |
153 | 148 | ///@param solidAngle, the size of the arc to sample. |
154 | 149 | ///Method for populating the vector arrays with sampled vectors. |
155 | - ///uses the default direction vector <0,0,1> | |
150 | + ///uses the default d vector <0,0,1> | |
156 | 151 | void |
157 | 152 | genDirectionVectors(float solidAngle = M_PI) |
158 | 153 | { |
159 | - float x = 0.0; | |
154 | + //Set up the vectors necessary for Rectangle creation. | |
160 | 155 | vec<float> Y(1.0,0.0,0.0); |
161 | 156 | vec<float> pos(0.0,0.0,0.0); |
162 | 157 | vec<float> mag(1.0, 1.0, 1.0); |
163 | 158 | vec<float> dir(0.0, 0.0, 1.0); |
164 | 159 | |
165 | 160 | vec<float> d_s = direction.cart2sph().norm(); |
161 | + //Set up the variable necessary for vector creation. | |
162 | + vec<float> d_s = d.cart2sph().norm(); | |
166 | 163 | vec<float> temp; |
167 | 164 | int dim = (sqrt(numSamples)-1)/2; |
168 | 165 | float p0 = -M_PI; |
169 | 166 | float dt = solidAngle/(2.0 * ((float)dim + 1.0)); |
170 | 167 | float dp = p0/(2.0*((float)dim + 1.0)); |
168 | + | |
169 | + glNewList(dList, GL_COMPILE); | |
170 | + //Loop over the space | |
171 | + int idx = 0; | |
171 | 172 | for(int i = -dim; i <= dim; i++){ |
172 | 173 | for(int j = -dim; j <= dim; j++){ |
173 | 174 | |
174 | 175 | //Create linear index |
175 | - | |
176 | + idx = (j+dim)+(i+dim)*((dim*2)+1); | |
176 | 177 | temp[0] = d_s[0]; //rotate vector |
177 | 178 | temp[1] = d_s[1]+dp*(float) i; |
178 | 179 | temp[2] = d_s[2]+dt*(float) j; |
179 | 180 | |
180 | 181 | temp = (temp.sph2cart()).norm(); //back to cart |
181 | - dirVectors.push_back(temp); | |
182 | + dV.push_back(temp); | |
183 | + if(cos(Y.dot(temp))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} | |
184 | + else{Y[0] = 1.0; Y[1] = 0.0;} | |
185 | + | |
186 | + hor = stim::rect<float>(mag, | |
187 | + pos, temp, | |
188 | + ((Y.cross(temp)).cross(temp)).norm()); | |
189 | + ver = stim::rect<float>(mag, | |
190 | + pos, temp, | |
191 | + hor.n()); | |
192 | + UpdateBuffer(0.0, 0.0+idx*10.0); | |
193 | + CHECK_OPENGL_ERROR | |
182 | 194 | } |
183 | 195 | } |
196 | + glEndList(); | |
184 | 197 | } |
185 | 198 | |
186 | 199 | ///@param solidAngle, the size of the arc to sample. |
... | ... | @@ -189,38 +202,61 @@ class gl_spider : public virtual gl_texture<T> |
189 | 202 | void |
190 | 203 | genPositionVectors(float delta = 0.2) |
191 | 204 | { |
192 | - ofstream file; | |
193 | - //file.open("dvectors.txt"); | |
205 | + //Set up the vectors necessary for Rectangle creation. | |
206 | + vec<float> Y(1.0,0.0,0.0); | |
207 | + vec<float> pos(0.0,0.0,0.0); | |
208 | + vec<float> mag(1.0, 1.0, 1.0); | |
209 | + vec<float> dir(0.0, 0.0, 1.0); | |
210 | + | |
211 | + //Set up the variable necessary for vector creation. | |
194 | 212 | vec<float> temp; |
195 | 213 | int dim = (sqrt(numSamples)-1)/2; |
196 | 214 | stim::rect<float> samplingPlane = |
197 | - stim::rect<float>(magnitude[0]*delta, position, direction); | |
215 | + stim::rect<float>(m[0]*delta, p, d); | |
198 | 216 | float step = 1.0/(dim); |
199 | - //Loop over the samples, keeping the original position sample | |
200 | - //in the center of the resulting texture. | |
201 | 217 | |
218 | + //Loop over the samples, keeping the original p sample | |
219 | + //in the center of the resulting texture. | |
220 | + int idx; | |
221 | + glNewList(dList+1, GL_COMPILE); | |
202 | 222 | for(int i = -dim; i <= dim; i++){ |
203 | 223 | for(int j = -dim; j <= dim; j++){ |
204 | 224 | //Create linear index |
225 | + idx = (j+dim)+(i+dim)*((dim*2)+1); | |
205 | 226 | |
206 | 227 | temp = samplingPlane.p( |
207 | 228 | 0.5+step*i, |
208 | 229 | 0.5+step*j |
209 | 230 | ); |
210 | - //file << temp[0] << ";" << temp[1] | |
211 | - // << ";" << temp[2] << endl; | |
212 | - posVectors.push_back(temp); | |
231 | + pV.push_back(temp); | |
232 | + hor = stim::rect<float>(mag, | |
233 | + temp, dir, | |
234 | + ((Y.cross(d)).cross(d)) | |
235 | + .norm()); | |
236 | + ver = stim::rect<float>(mag, | |
237 | + temp, dir, | |
238 | + hor.n()); | |
239 | + UpdateBuffer(0.0, 0.0+idx*10.0); | |
240 | + CHECK_OPENGL_ERROR | |
213 | 241 | } |
214 | 242 | } |
243 | + glEndList(); | |
215 | 244 | } |
216 | 245 | |
217 | 246 | ///@param solidAngle, the size of the arc to sample. |
218 | 247 | ///Method for populating the buffer with the sampled texture. |
219 | - ///uses the default magnitude <1,1,0> | |
248 | + ///uses the default m <1,1,0> | |
220 | 249 | void |
221 | 250 | genMagnitudeVectors(float delta = 0.5) |
222 | 251 | { |
223 | 252 | |
253 | + //Set up the vectors necessary for Rectangle creation. | |
254 | + vec<float> Y(1.0,0.0,0.0); | |
255 | + vec<float> pos(0.0,0.0,0.0); | |
256 | + vec<float> mag(1.0, 1.0, 1.0); | |
257 | + vec<float> dir(0.0, 0.0, 1.0); | |
258 | + | |
259 | + //Set up the variable necessary for vector creation. | |
224 | 260 | int dim = (sqrt(numSamples)-1)/2; |
225 | 261 | float min = 1.0-delta; |
226 | 262 | float max = 1.0+delta; |
... | ... | @@ -228,95 +264,23 @@ class gl_spider : public virtual gl_texture<T> |
228 | 264 | float factor; |
229 | 265 | vec<float> temp; |
230 | 266 | |
267 | + glNewList(dList+2, GL_COMPILE); | |
231 | 268 | for(int i = 0; i < numSamples; i++){ |
232 | 269 | //Create linear index |
233 | - factor = (min+step*i)*magnitude[0]; | |
270 | + factor = (min+step*i)*m[0]; | |
234 | 271 | temp = factor; |
235 | - magVectors.push_back(temp); | |
272 | + mV.push_back(temp); | |
273 | + hor = stim::rect<float>(temp, | |
274 | + pos, dir, | |
275 | + ((Y.cross(d)).cross(d)) | |
276 | + .norm()); | |
277 | + ver = stim::rect<float>(temp, | |
278 | + pos, dir, | |
279 | + hor.n()); | |
280 | + UpdateBuffer(0.0, 0.0+i*10.0); | |
281 | + CHECK_OPENGL_ERROR | |
236 | 282 | } |
237 | - } | |
238 | - ///@param vector of stim::vec in that stores all of the samplable vectors. | |
239 | - ///@param type, one of three operations, 0 for Direction vectors | |
240 | - /// 1 for Position, 2 for Magnitude. | |
241 | - ///Function for filling the buffer up with the data based on the vectors | |
242 | - ///Each vector represents a two rectangular templates. | |
243 | - ///Loops through all of the vectors and transfers rect. associated with it | |
244 | - ///Into buffer-space. | |
245 | - void | |
246 | - genTemplate(std::vector<stim::vec<float> > in, int type) | |
247 | - { | |
248 | - float x = 0.0; | |
249 | - vec<float> Y(1.0,0.0,0.0); | |
250 | - vec<float> pos(0.0,0.0,0.0); | |
251 | - vec<float> mag(1.0, 1.0, 1.0); | |
252 | - vec<float> dir(0.0, 0.0, 1.0); | |
253 | - switch(type) { | |
254 | - case 0: //Direction | |
255 | - Bind(); | |
256 | - glNewList(dList+type, GL_COMPILE); | |
257 | - for(int i = 0; i < in.size(); i++) | |
258 | - { | |
259 | - if(cos(Y.dot(in[i]))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} | |
260 | - else{Y[0] = 1.0; Y[1] = 0.0;} | |
261 | - | |
262 | - hor = stim::rect<float>(mag, | |
263 | - pos, in[i], | |
264 | - ((Y.cross(in[i])).cross(in[i])).norm()); | |
265 | - ver = stim::rect<float>(mag, | |
266 | - pos, in[i], | |
267 | - hor.n()); | |
268 | - UpdateBuffer(x, x+i*10.0); | |
269 | - } | |
270 | - glEndList(); | |
271 | - Unbind(); | |
272 | - break; | |
273 | - case 1: //Position | |
274 | - Bind(); | |
275 | - glNewList(dList+type, GL_COMPILE); | |
276 | - if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} | |
277 | - else{Y[0] = 1.0; Y[1] = 0.0;} | |
278 | - | |
279 | - for(int i = 0; i < in.size(); i++) | |
280 | - { | |
281 | - hor = stim::rect<float>(mag, | |
282 | - in[i], dir, | |
283 | - ((Y.cross(direction)).cross(direction)) | |
284 | - .norm()); | |
285 | - ver = stim::rect<float>(mag, | |
286 | - in[i], dir, | |
287 | - hor.n()); | |
288 | - UpdateBuffer(x, x+i*10.0); | |
289 | - } | |
290 | - glEndList(); | |
291 | - Unbind(); | |
292 | - break; | |
293 | - case 2: //Scale | |
294 | - Bind(); | |
295 | - glNewList(dList+type, GL_COMPILE); | |
296 | - if(cos(Y.dot(direction))< 0.087){ Y[0] = 0.0; Y[1] = 1.0;} | |
297 | - else{Y[0] = 1.0; Y[1] = 0.0;} | |
298 | - | |
299 | - for(int i = 0; i < in.size(); i++) | |
300 | - { | |
301 | - hor = stim::rect<float>(in[i], | |
302 | - pos, dir, | |
303 | - ((Y.cross(direction)).cross(direction)) | |
304 | - .norm()); | |
305 | - ver = stim::rect<float>(in[i], | |
306 | - pos, dir, | |
307 | - hor.n()); | |
308 | - UpdateBuffer(x, x+i*10.0); | |
309 | - } | |
310 | - glEndList(); | |
311 | - Unbind(); | |
312 | - break; | |
313 | - default: | |
314 | - std::cout << "unknown case have been passed" | |
315 | - << std::endl; | |
316 | - break; | |
317 | - } | |
318 | - Unbind(); | |
319 | - CHECK_OPENGL_ERROR | |
283 | + glEndList(); | |
320 | 284 | } |
321 | 285 | ///@param v_x x-coordinate in buffer-space, |
322 | 286 | ///@param v_y y-coordinate in buffer-space. |
... | ... | @@ -392,7 +356,6 @@ class gl_spider : public virtual gl_texture<T> |
392 | 356 | ); |
393 | 357 | glVertex2f(v_x+len, v_y+len); |
394 | 358 | glEnd(); |
395 | - CHECK_OPENGL_ERROR | |
396 | 359 | } |
397 | 360 | |
398 | 361 | |
... | ... | @@ -468,25 +431,25 @@ class gl_spider : public virtual gl_texture<T> |
468 | 431 | |
469 | 432 | ///Method for using the gl manipulation to alighn templates from |
470 | 433 | ///Template space (-0.5 0.5) to Texture space (0.0, 1.0), |
471 | - ///Based on the position of the spider in real space (arbitrary). | |
472 | - void positionTemplate() | |
434 | + ///Based on the p of the spider in real space (arbitrary). | |
435 | + void setMatrix() | |
473 | 436 | { |
474 | - stim::vec<float, 4> rot = getRotation(direction); | |
437 | + stim::vec<float, 4> rot = getRotation(d); | |
475 | 438 | glMatrixMode(GL_TEXTURE); |
476 | 439 | glLoadIdentity(); |
477 | 440 | |
478 | 441 | glRotatef(rot[0], rot[1], rot[2], rot[3]); |
479 | - glScalef(1.0/S[1]/R[1], 1.0/S[2]/R[2], 1.0/S[3]/R[3]); | |
480 | - glTranslatef(position[0], | |
481 | - position[1], | |
482 | - position[2]); | |
483 | - glScalef(magnitude[0], | |
484 | - magnitude[1], | |
485 | - magnitude[0]); | |
442 | + glScalef(1.0/S[0]/R[0], 1.0/S[1]/R[1], 1.0/S[2]/R[2]); | |
443 | + glTranslatef(p[0], | |
444 | + p[1], | |
445 | + p[2]); | |
446 | + glScalef(m[0], | |
447 | + m[1], | |
448 | + m[0]); | |
486 | 449 | |
487 | 450 | float curTrans[16]; |
488 | 451 | glGetFloatv(GL_TEXTURE_MATRIX, curTrans); |
489 | - fillTransform(curTrans); | |
452 | + cT.set(curTrans); | |
490 | 453 | printTransform(); |
491 | 454 | |
492 | 455 | CHECK_OPENGL_ERROR |
... | ... | @@ -545,21 +508,11 @@ class gl_spider : public virtual gl_texture<T> |
545 | 508 | //--------------------------------------------------------------------------// |
546 | 509 | |
547 | 510 | |
548 | - ///Default Constructor | |
549 | - gl_spider | |
550 | - () | |
551 | - { | |
552 | - setPosition(0.0,0.0,0.0); | |
553 | - setDirection(0.0,0.0,1.0); | |
554 | - setMagnitude(1.0); | |
555 | - numSamples = 1089; | |
556 | - //numSamples = 9; | |
557 | - } | |
558 | 511 | ///@param samples, the number of samples this spider is going to use. |
559 | 512 | ///best results if samples is can create a perfect root. |
560 | 513 | ///Default Constructor |
561 | 514 | gl_spider |
562 | - (int samples) | |
515 | + (int samples = 1089) | |
563 | 516 | { |
564 | 517 | setPosition(0.0,0.0,0.0); |
565 | 518 | setDirection(0.0,0.0,1.0); |
... | ... | @@ -577,9 +530,18 @@ class gl_spider : public virtual gl_texture<T> |
577 | 530 | setMagnitude(mag_x); |
578 | 531 | |
579 | 532 | } |
533 | + | |
534 | + ~gl_spider | |
535 | + (void) | |
536 | + { | |
537 | + Unbind(); | |
538 | + glDeleteTextures(1, &texbufferID); | |
539 | + glDeleteBuffers(1, &fboID); | |
540 | + } | |
541 | + | |
580 | 542 | ///@param GLuint id texture that is going to be sampled. |
581 | 543 | ///Attached the spider to the texture with the given GLuint ID. |
582 | - ///Samples in the default direction acting as the init method. | |
544 | + ///Samples in the default d acting as the init method. | |
583 | 545 | ///Also acts an init. |
584 | 546 | void |
585 | 547 | attachSpider(GLuint id) |
... | ... | @@ -587,110 +549,116 @@ class gl_spider : public virtual gl_texture<T> |
587 | 549 | texID = id; |
588 | 550 | iter = 0; ///for debugging purposes |
589 | 551 | GenerateFBO(20, numSamples*10); |
590 | - genDirectionVectors(); | |
591 | - genPositionVectors(); | |
592 | - genMagnitudeVectors(); | |
593 | - | |
594 | - gl_texture<T>::setDims(0.6, 0.6, 1.0); | |
595 | - setSize(512, 512, 426); | |
552 | + setDims(0.6, 0.6, 1.0); | |
553 | + setSize(512.0, 512.0, 426.0); | |
596 | 554 | |
597 | - dList = glGenLists(4); | |
598 | - list[0] = 0; list[1] = 1; list[2] = 2; list[3] = 3; | |
555 | + dList = glGenLists(3); | |
599 | 556 | glListBase(dList); |
600 | - genTemplate(dirVectors, 0); | |
601 | - genTemplate(posVectors, 1); | |
602 | - genTemplate(magVectors, 2); | |
557 | + Bind(); | |
558 | + genDirectionVectors(5*M_PI/4); | |
559 | + genPositionVectors(); | |
560 | + genMagnitudeVectors(); | |
603 | 561 | DrawCylinder(); |
562 | + Unbind(); | |
604 | 563 | } |
605 | 564 | |
606 | 565 | //--------------------------------------------------------------------------// |
607 | 566 | //-----------------------------ACCESS METHODS-------------------------------// |
608 | 567 | //--------------------------------------------------------------------------// |
609 | - ///Returns the position vector. | |
568 | + ///Returns the p vector. | |
610 | 569 | vec<float> |
611 | 570 | getPosition() |
612 | 571 | { |
613 | - return position; | |
572 | + return p; | |
614 | 573 | } |
615 | 574 | |
616 | - ///Returns the direction vector. | |
575 | + ///Returns the d vector. | |
617 | 576 | vec<float> |
618 | 577 | getDirection() |
619 | 578 | { |
620 | - return direction; | |
579 | + return d; | |
621 | 580 | } |
622 | 581 | |
623 | - ///Returns the magnitude vector. | |
582 | + ///Returns the m vector. | |
624 | 583 | vec<float> |
625 | 584 | getMagnitude() |
626 | 585 | { |
627 | - return magnitude; | |
586 | + return m; | |
628 | 587 | } |
629 | 588 | |
630 | - ///@param vector pos, the new position. | |
631 | - ///Sets the position vector to input vector pos. | |
589 | + ///@param vector pos, the new p. | |
590 | + ///Sets the p vector to input vector pos. | |
632 | 591 | void |
633 | 592 | setPosition(vec<float> pos) |
634 | 593 | { |
635 | - position = pos; | |
594 | + p = pos; | |
636 | 595 | } |
637 | 596 | |
638 | 597 | ///@param x x-coordinate. |
639 | 598 | ///@param y y-coordinate. |
640 | 599 | ///@param z z-coordinate. |
641 | - ///Sets the position vector to the input float coordinates x,y,z. | |
600 | + ///Sets the p vector to the input float coordinates x,y,z. | |
642 | 601 | void |
643 | 602 | setPosition(float x, float y, float z) |
644 | 603 | { |
645 | - position[0] = x; | |
646 | - position[1] = y; | |
647 | - position[2] = z; | |
604 | + p[0] = x; | |
605 | + p[1] = y; | |
606 | + p[2] = z; | |
648 | 607 | } |
649 | 608 | |
650 | - ///@param vector dir, the new direction. | |
651 | - ///Sets the direction vector to input vector dir. | |
609 | + ///@param vector dir, the new d. | |
610 | + ///Sets the d vector to input vector dir. | |
652 | 611 | void |
653 | 612 | setDirection(vec<float> dir) |
654 | 613 | { |
655 | - direction = dir; | |
614 | + d = dir; | |
656 | 615 | } |
657 | 616 | |
658 | 617 | ///@param x x-coordinate. |
659 | 618 | ///@param y y-coordinate. |
660 | 619 | ///@param z z-coordinate. |
661 | - ///Sets the direction vector to the input float coordinates x,y,z. | |
620 | + ///Sets the d vector to the input float coordinates x,y,z. | |
662 | 621 | void |
663 | 622 | setDirection(float x, float y, float z) |
664 | 623 | { |
665 | - direction[0] = x; | |
666 | - direction[1] = y; | |
667 | - direction[2] = z; | |
624 | + d[0] = x; | |
625 | + d[1] = y; | |
626 | + d[2] = z; | |
668 | 627 | } |
669 | 628 | |
670 | - ///@param vector dir, the new direction. | |
671 | - ///Sets the magnitude vector to the input vector mag. | |
629 | + ///@param vector dir, the new d. | |
630 | + ///Sets the m vector to the input vector mag. | |
672 | 631 | void |
673 | 632 | setMagnitude(vec<float> mag) |
674 | 633 | { |
675 | - magnitude[0] = mag[0]; | |
676 | - magnitude[1] = mag[0]; | |
634 | + m[0] = mag[0]; | |
635 | + m[1] = mag[0]; | |
677 | 636 | } |
678 | 637 | |
679 | 638 | ///@param mag size of the sampled region. |
680 | - ///Sets the magnitude vector to the input mag for both templates. | |
639 | + ///Sets the m vector to the input mag for both templates. | |
681 | 640 | void |
682 | 641 | setMagnitude(float mag) |
683 | 642 | { |
684 | - magnitude[0] = mag; | |
685 | - magnitude[1] = mag; | |
643 | + m[0] = mag; | |
644 | + m[1] = mag; | |
686 | 645 | } |
687 | 646 | |
647 | + | |
648 | + void | |
649 | + setDims(float x, float y, float z) | |
650 | + { | |
651 | + S[0] = x; | |
652 | + S[1] = y; | |
653 | + S[2] = z; | |
654 | + } | |
655 | + | |
688 | 656 | void |
689 | - setSize(int x, int y, int z) | |
657 | + setSize(float x, float y, float z) | |
690 | 658 | { |
691 | - R[1] = x; | |
692 | - R[2] = y; | |
693 | - R[3] = z; | |
659 | + R[0] = x; | |
660 | + R[1] = y; | |
661 | + R[2] = z; | |
694 | 662 | } |
695 | 663 | |
696 | 664 | ///@param dir, the vector to which we are rotating |
... | ... | @@ -716,18 +684,6 @@ class gl_spider : public virtual gl_texture<T> |
716 | 684 | } |
717 | 685 | return out; |
718 | 686 | } |
719 | - ///Function that fills the transform data from GL output to a matrix format. | |
720 | - ///@param mat, a 16 value matrix representing the transformation in row order. | |
721 | - void | |
722 | - fillTransform(float mat[16]) | |
723 | - { | |
724 | - for(int r = 0; r < 4; r++){ | |
725 | - for(int c = 0; c < 4; c++){ | |
726 | - currentTransform(r,c) = mat[c*4+r]; | |
727 | - } | |
728 | - } | |
729 | - | |
730 | - } | |
731 | 687 | |
732 | 688 | ///Function to get back the framebuffer Object attached to the spider. |
733 | 689 | ///For external access. |
... | ... | @@ -746,11 +702,11 @@ class gl_spider : public virtual gl_texture<T> |
746 | 702 | Update() |
747 | 703 | { |
748 | 704 | vec<float> Y(1.0,0.0,0.0); |
749 | - if(cos(Y.dot(direction))< 0.087){ | |
705 | + if(cos(Y.dot(d))< 0.087){ | |
750 | 706 | Y[0] = 0.0; Y[1] = 1.0;} |
751 | - hor = stim::rect<float>(magnitude, position, direction.norm(), | |
752 | - ((Y.cross(direction)).cross(direction)).norm()); | |
753 | - ver = stim::rect<float>(magnitude, position, direction.norm(), | |
707 | + hor = stim::rect<float>(m, p, d.norm(), | |
708 | + ((Y.cross(d)).cross(d)).norm()); | |
709 | + ver = stim::rect<float>(m, p, d.norm(), | |
754 | 710 | hor.n()); |
755 | 711 | } |
756 | 712 | |
... | ... | @@ -758,17 +714,19 @@ class gl_spider : public virtual gl_texture<T> |
758 | 714 | void |
759 | 715 | Step() |
760 | 716 | { |
761 | - // findOptimalDirection(); | |
762 | - // findOptimalPosition(); | |
763 | - // findOptimalScale(); | |
717 | + Bind(); | |
718 | + findOptimalDirection(); | |
719 | + findOptimalPosition(); | |
720 | + findOptimalScale(); | |
764 | 721 | branchDetection(); |
722 | + Unbind(); | |
765 | 723 | } |
766 | 724 | |
767 | 725 | |
768 | 726 | void |
769 | 727 | printTransform() |
770 | 728 | { |
771 | - std::cout << currentTransform << std::endl; | |
729 | + std::cout << cT << std::endl; | |
772 | 730 | } |
773 | 731 | |
774 | 732 | /* Method for initializing the cuda devices, necessary only | ... | ... |
stim/math/matrix.h
... | ... | @@ -25,6 +25,17 @@ struct matrix |
25 | 25 | (*this)(r, c) = 0; |
26 | 26 | } |
27 | 27 | |
28 | + CUDA_CALLABLE matrix(T rhs[N*N]) | |
29 | + { | |
30 | + memcpy(M,rhs, sizeof(T)*N*N); | |
31 | + } | |
32 | + | |
33 | + CUDA_CALLABLE matrix<T,N> set(T rhs[N*N]) | |
34 | + { | |
35 | + memcpy(M, rhs, sizeof(T)*N*N); | |
36 | + return *this; | |
37 | + } | |
38 | + | |
28 | 39 | CUDA_CALLABLE T& operator()(int row, int col) |
29 | 40 | { |
30 | 41 | return M[col * N + row]; |
... | ... | @@ -39,6 +50,7 @@ struct matrix |
39 | 50 | return *this; |
40 | 51 | } |
41 | 52 | |
53 | + | |
42 | 54 | template<typename Y> |
43 | 55 | CUDA_CALLABLE vec<Y, N> operator*(vec<Y, N> rhs) |
44 | 56 | { |
... | ... | @@ -51,18 +63,18 @@ struct matrix |
51 | 63 | return result; |
52 | 64 | } |
53 | 65 | |
54 | - CUDA_CALLABLE std::string toStr() | |
66 | + std::string toStr() | |
55 | 67 | { |
56 | 68 | std::stringstream ss; |
57 | 69 | |
58 | 70 | for(int r = 0; r < N; r++) |
59 | 71 | { |
60 | - ss<<"| "; | |
72 | + ss << "| "; | |
61 | 73 | for(int c=0; c<N; c++) |
62 | 74 | { |
63 | - ss<<(*this)(r, c)<<" "; | |
75 | + ss << (*this)(r, c) << " "; | |
64 | 76 | } |
65 | - ss<<"|"<<std::endl; | |
77 | + ss << "|" << std::endl; | |
66 | 78 | } |
67 | 79 | |
68 | 80 | return ss.str(); | ... | ... |
stim/parser/arguments.h
... | ... | @@ -256,14 +256,16 @@ namespace stim{ |
256 | 256 | args.add("foo", "foo takes a single integer value", "", "[intval]"); |
257 | 257 | args.add("bar", "bar takes two floating point values", "", "[value1], [value2]"); |
258 | 258 | |
259 | - 4) You generally want to immediately test for help and output available arguments: | |
259 | + 4) Parse the command line: | |
260 | + | |
261 | + args.parse(argc, argv); | |
262 | + | |
263 | + 5) You generally want to immediately test for help and output available arguments: | |
260 | 264 | |
261 | 265 | if(args["help"].is_set()) |
262 | 266 | std::cout<<args.str(); |
263 | 267 | |
264 | - 5) Parse the command line: | |
265 | - | |
266 | - args.parse(argc, argv); | |
268 | + | |
267 | 269 | |
268 | 270 | 6) Retrieve values: |
269 | 271 | |
... | ... | @@ -436,7 +438,8 @@ namespace stim{ |
436 | 438 | } |
437 | 439 | |
438 | 440 | //set the last option |
439 | - set(name, params); | |
441 | + if(name != "") | |
442 | + set(name, params); | |
440 | 443 | } |
441 | 444 | |
442 | 445 | ///Determines of a parameter has been set and returns true if it has | ... | ... |
stim/visualization/camera.h
... | ... | @@ -167,14 +167,14 @@ public: |
167 | 167 | //output the camera settings |
168 | 168 | const void print(std::ostream& output) |
169 | 169 | { |
170 | - output<<"Position: "<<p<<std::endl; | |
170 | + output<<"Position: "<<p.str()<<std::endl; | |
171 | 171 | |
172 | 172 | } |
173 | 173 | friend std::ostream& operator<<(std::ostream& out, const camera& c) |
174 | 174 | { |
175 | - out<<"Position: "<<c.p<<std::endl; | |
176 | - out<<"Direction: "<<c.d<<std::endl; | |
177 | - out<<"Up: "<<c.up<<std::endl; | |
175 | + out<<"Position: "<<c.p.str()<<std::endl; | |
176 | + out<<"Direction: "<<c.d.str()<<std::endl; | |
177 | + out<<"Up: "<<c.up.str()<<std::endl; | |
178 | 178 | out<<"Focal Distance: "<<c.focus<<std::endl; |
179 | 179 | return out; |
180 | 180 | } | ... | ... |
stim/visualization/colormap.h
... | ... | @@ -221,7 +221,11 @@ static void cpuApplyBrewer(T* cpuSource, unsigned char* cpuDest, unsigned int N, |
221 | 221 | for(int i=0; i<N; i++) |
222 | 222 | { |
223 | 223 | //compute the normalized value on [minVal maxVal] |
224 | - float a = (cpuSource[i] - minVal) / (maxVal - minVal); | |
224 | + float a; | |
225 | + if(minVal != maxVal) | |
226 | + a = (cpuSource[i] - minVal) / (maxVal - minVal); | |
227 | + else | |
228 | + a = 0.5; | |
225 | 229 | if(a < 0) a = 0; |
226 | 230 | if(a > 1) a = 1; |
227 | 231 | |
... | ... | @@ -263,11 +267,15 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T |
263 | 267 | int i; |
264 | 268 | float a; |
265 | 269 | float range = valMax - valMin; |
270 | + | |
266 | 271 | for(i = 0; i<nVals; i++) |
267 | 272 | { |
268 | 273 | //normalize to the range [valMin valMax] |
269 | - a = (cpuSource[i] - valMin) / range; | |
270 | - | |
274 | + if(range != 0) | |
275 | + a = (cpuSource[i] - valMin) / range; | |
276 | + else | |
277 | + a = 0.5; | |
278 | + | |
271 | 279 | if(a < 0) a = 0; |
272 | 280 | if(a > 1) a = 1; |
273 | 281 | |
... | ... | @@ -279,22 +287,26 @@ static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T |
279 | 287 | } |
280 | 288 | |
281 | 289 | template<class T> |
282 | -static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale, bool positive = false) | |
290 | +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale)//, bool positive = false) | |
283 | 291 | { |
284 | 292 | //computes the max and min range automatically |
285 | 293 | |
286 | 294 | //find the largest magnitude value |
287 | - T maxVal = fabs(cpuSource[0]); | |
288 | - for(int i=0; i<nVals; i++) | |
295 | + T maxVal = cpuSource[0]; | |
296 | + T minVal = cpuSource[0]; | |
297 | + for(int i=1; i<nVals; i++) | |
289 | 298 | { |
290 | - if(fabs(cpuSource[i]) > maxVal) | |
291 | - maxVal = fabs(cpuSource[i]); | |
299 | + if(cpuSource[i] > maxVal) | |
300 | + maxVal = cpuSource[i]; | |
301 | + if(cpuSource[i] < minVal) | |
302 | + minVal = cpuSource[i]; | |
292 | 303 | } |
293 | 304 | |
294 | - if(positive) | |
295 | - cpu2cpu(cpuSource, cpuDest, nVals, (T)0, maxVal, cm); | |
296 | - else | |
297 | - cpu2cpu(cpuSource, cpuDest, nVals, -maxVal, maxVal, cm); | |
305 | + //if(positive) | |
306 | + // cpu2cpu(cpuSource, cpuDest, nVals, (T)0, maxVal, cm); | |
307 | + //else | |
308 | + // cpu2cpu(cpuSource, cpuDest, nVals, -maxVal, maxVal, cm); | |
309 | + cpu2cpu(cpuSource, cpuDest, nVals, minVal, maxVal, cm); | |
298 | 310 | |
299 | 311 | } |
300 | 312 | ... | ... |
1 | +#ifndef STIM_SPH_HARMONICS | |
2 | +#define STIM_SPH_HARMONICS | |
3 | + | |
4 | +#include <GL/gl.h> | |
5 | + | |
6 | +#include <stim/gl/error.h> | |
7 | +#include <stim/visualization/colormap.h> | |
8 | +#include <vector> | |
9 | + | |
10 | +#define PI 3.14159 | |
11 | +#define WIRE_SCALE 1.001 | |
12 | +namespace stim{ | |
13 | + | |
14 | + class sph_harmonics{ | |
15 | + | |
16 | + private: | |
17 | + | |
18 | + double* func; //stores the raw function data (samples at each point) | |
19 | + | |
20 | + GLuint color_tex; //texture map that acts as a colormap for the spherical function | |
21 | + | |
22 | + unsigned int N; //resolution of the spherical grid | |
23 | + | |
24 | + std::vector<double> C; //list of SH coefficients | |
25 | + | |
26 | + | |
27 | + //evaluates an associated Legendre polynomial (-l <= m <= l) | |
28 | + double P(int l,int m,double x) | |
29 | + { | |
30 | + // evaluate an Associated Legendre Polynomial P(l,m,x) at x | |
31 | + double pmm = 1.0; | |
32 | + if(m>0) { | |
33 | + double somx2 = sqrt((1.0-x)*(1.0+x)); | |
34 | + double fact = 1.0; | |
35 | + for(int i=1; i<=m; i++) { | |
36 | + pmm *= (-fact) * somx2; | |
37 | + fact += 2.0; | |
38 | + } | |
39 | + } | |
40 | + if(l==m) return pmm; | |
41 | + double pmmp1 = x * (2.0*m+1.0) * pmm; | |
42 | + if(l==m+1) return pmmp1; | |
43 | + double pll = 0.0; | |
44 | + for(int ll=m+2; ll<=l; ++ll) { | |
45 | + pll = ( (2.0*ll-1.0)*x*pmmp1-(ll+m-1.0)*pmm ) / (ll-m); | |
46 | + pmm = pmmp1; | |
47 | + pmmp1 = pll; | |
48 | + } | |
49 | + return pll; | |
50 | + } | |
51 | + | |
52 | + //recursively calculate a factorial given a positive integer n | |
53 | + unsigned int factorial(unsigned int n) { | |
54 | + if (n == 0) | |
55 | + return 1; | |
56 | + return n * factorial(n - 1); | |
57 | + } | |
58 | + | |
59 | + //calculate the SH scaling constant | |
60 | + double K(int l, int m){ | |
61 | + | |
62 | + // renormalisation constant for SH function | |
63 | + double temp = ((2.0*l+1.0)*factorial(l-m)) / (4.0*PI*factorial(l+m)); | |
64 | + return sqrt(temp); | |
65 | + } | |
66 | + | |
67 | + //calculate the value of the SH basis function (l, m) at (theta, phi) | |
68 | + //here, theta = [0, PI], phi = [0, 2*PI] | |
69 | + double SH(int l, int m, double theta, double phi){ | |
70 | + // return a point sample of a Spherical Harmonic basis function | |
71 | + // l is the band, range [0..N] | |
72 | + // m in the range [-l..l] | |
73 | + // theta in the range [0..Pi] | |
74 | + // phi in the range [0..2*Pi] | |
75 | + const double sqrt2 = sqrt(2.0); | |
76 | + if(m==0) return K(l,0)*P(l,m,cos(theta)); | |
77 | + else if(m>0) return sqrt2*K(l,m)*cos(m*phi)*P(l,m,cos(theta)); | |
78 | + else return sqrt2*K(l,-m)*sin(-m*phi)*P(l,-m,cos(theta)); | |
79 | + } | |
80 | + | |
81 | + void gen_function(){ | |
82 | + | |
83 | + //initialize the function to zero | |
84 | + memset(func, 0, sizeof(double) * N * N); | |
85 | + | |
86 | + double theta, phi; | |
87 | + double result; | |
88 | + int l, m; | |
89 | + | |
90 | + l = m = 0; | |
91 | + for(unsigned int c = 0; c < C.size(); c++){ | |
92 | + | |
93 | + | |
94 | + for(unsigned int xi = 0; xi < N; xi++) | |
95 | + for(unsigned int yi = 0; yi < N; yi++){ | |
96 | + | |
97 | + theta = (2 * PI) * ((double)xi / (N-1)); | |
98 | + phi = PI * ((double)yi / (N-1)); | |
99 | + result = C[c] * SH(l, m, phi, theta); //phi and theta are reversed here (damn physicists) | |
100 | + func[yi * N + xi] += result; | |
101 | + } | |
102 | + | |
103 | + m++; //increment m | |
104 | + | |
105 | + //if we're in a new tier, increment l and set m = -l | |
106 | + if(m > l){ | |
107 | + l++; | |
108 | + m = -l; | |
109 | + } | |
110 | + } | |
111 | + } | |
112 | + | |
113 | + void gl_prep_draw(){ | |
114 | + | |
115 | + //enable depth testing | |
116 | + //this has to be used instead of culling because the sphere can have negative values | |
117 | + glEnable(GL_DEPTH_TEST); | |
118 | + glDepthMask(GL_TRUE); | |
119 | + glEnable(GL_TEXTURE_2D); //enable 2D texture mapping | |
120 | + } | |
121 | + | |
122 | + //draw a texture mapped sphere representing the function surface | |
123 | + void gl_draw_sphere() { | |
124 | + | |
125 | + //PI is used to convert from spherical to cartesian coordinates | |
126 | + //const double PI = 3.14159; | |
127 | + | |
128 | + //bind the 2D texture representing the color map | |
129 | + glBindTexture(GL_TEXTURE_2D, color_tex); | |
130 | + | |
131 | + //Draw the Sphere | |
132 | + int i, j; | |
133 | + | |
134 | + for(i = 1; i <= N-1; i++) { | |
135 | + double phi0 = PI * ((double) (i - 1) / (N-1)); | |
136 | + double phi1 = PI * ((double) i / (N-1)); | |
137 | + | |
138 | + glBegin(GL_QUAD_STRIP); | |
139 | + for(j = 0; j <= N; j++) { | |
140 | + | |
141 | + //calculate the indices into the function array | |
142 | + int phi0_i = i-1; | |
143 | + int phi1_i = i; | |
144 | + int theta_i = j; | |
145 | + if(theta_i == N) | |
146 | + theta_i = 0; | |
147 | + | |
148 | + double v0 = func[phi0_i * N + theta_i]; | |
149 | + double v1 = func[phi1_i * N + theta_i]; | |
150 | + | |
151 | + v0 = fabs(v0); | |
152 | + v1 = fabs(v1); | |
153 | + | |
154 | + | |
155 | + double theta = 2 * PI * (double) (j - 1) / N; | |
156 | + double x0 = v0 * cos(theta) * sin(phi0); | |
157 | + double y0 = v0 * sin(theta) * sin(phi0); | |
158 | + double z0 = v0 * cos(phi0); | |
159 | + | |
160 | + double x1 = v1 * cos(theta) * sin(phi1); | |
161 | + double y1 = v1 * sin(theta) * sin(phi1); | |
162 | + double z1 = v1 * cos(phi1); | |
163 | + | |
164 | + glTexCoord2f(theta / (2 * PI), phi0 / PI); | |
165 | + glVertex3f(x0, y0, z0); | |
166 | + | |
167 | + glTexCoord2f(theta / (2 * PI), phi1 / PI); | |
168 | + glVertex3f(x1, y1, z1); | |
169 | + } | |
170 | + glEnd(); | |
171 | + } | |
172 | + } | |
173 | + | |
174 | + //draw a wire frame sphere representing the function surface | |
175 | + void gl_draw_wireframe() { | |
176 | + | |
177 | + //PI is used to convert from spherical to cartesian coordinates | |
178 | + //const double PI = 3.14159; | |
179 | + | |
180 | + //bind the 2D texture representing the color map | |
181 | + glDisable(GL_TEXTURE_2D); | |
182 | + glColor3f(0.0f, 0.0f, 0.0f); | |
183 | + | |
184 | + //Draw the Sphere | |
185 | + int i, j; | |
186 | + | |
187 | + for(i = 1; i <= N-1; i++) { | |
188 | + double phi0 = PI * ((double) (i - 1) / (N-1)); | |
189 | + double phi1 = PI * ((double) i / (N-1)); | |
190 | + | |
191 | + glBegin(GL_LINE_STRIP); | |
192 | + for(j = 0; j <= N; j++) { | |
193 | + | |
194 | + //calculate the indices into the function array | |
195 | + int phi0_i = i-1; | |
196 | + int phi1_i = i; | |
197 | + int theta_i = j; | |
198 | + if(theta_i == N) | |
199 | + theta_i = 0; | |
200 | + | |
201 | + double v0 = func[phi0_i * N + theta_i]; | |
202 | + double v1 = func[phi1_i * N + theta_i]; | |
203 | + | |
204 | + v0 = fabs(v0); | |
205 | + v1 = fabs(v1); | |
206 | + | |
207 | + | |
208 | + double theta = 2 * PI * (double) (j - 1) / N; | |
209 | + double x0 = WIRE_SCALE * v0 * cos(theta) * sin(phi0); | |
210 | + double y0 = WIRE_SCALE * v0 * sin(theta) * sin(phi0); | |
211 | + double z0 = WIRE_SCALE * v0 * cos(phi0); | |
212 | + | |
213 | + double x1 = WIRE_SCALE * v1 * cos(theta) * sin(phi1); | |
214 | + double y1 = WIRE_SCALE * v1 * sin(theta) * sin(phi1); | |
215 | + double z1 = WIRE_SCALE * v1 * cos(phi1); | |
216 | + | |
217 | + glTexCoord2f(theta / (2 * PI), phi0 / PI); | |
218 | + glVertex3f(x0, y0, z0); | |
219 | + | |
220 | + glTexCoord2f(theta / (2 * PI), phi1 / PI); | |
221 | + glVertex3f(x1, y1, z1); | |
222 | + } | |
223 | + glEnd(); | |
224 | + } | |
225 | + } | |
226 | + | |
227 | + void init(unsigned int n){ | |
228 | + | |
229 | + //set the sphere resolution | |
230 | + N = n; | |
231 | + | |
232 | + //allocate space for the color map | |
233 | + unsigned int bytes = N * N * sizeof(unsigned char) * 3; | |
234 | + unsigned char* color_image; | |
235 | + color_image = (unsigned char*) malloc(bytes); | |
236 | + | |
237 | + //allocate space for the function | |
238 | + func = (double*) malloc(N * N * sizeof(double)); | |
239 | + | |
240 | + //generate a function (temporary) | |
241 | + gen_function(); | |
242 | + | |
243 | + //generate a colormap from the function | |
244 | + stim::cpu2cpu<double>(func, color_image, N*N, stim::cmBrewer); | |
245 | + | |
246 | + //prep everything for drawing | |
247 | + gl_prep_draw(); | |
248 | + | |
249 | + //generate an OpenGL texture map in the current context | |
250 | + glGenTextures(1, &color_tex); | |
251 | + //bind the texture | |
252 | + glBindTexture(GL_TEXTURE_2D, color_tex); | |
253 | + | |
254 | + //copy the color data from the buffer to the GPU | |
255 | + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, N, N, 0, GL_RGB, GL_UNSIGNED_BYTE, color_image); | |
256 | + | |
257 | + //initialize all of the texture parameters | |
258 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
259 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); | |
260 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
261 | + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
262 | + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); | |
263 | + | |
264 | + //free the buffer | |
265 | + free(color_image); | |
266 | + } | |
267 | + | |
268 | + | |
269 | + public: | |
270 | + | |
271 | + void glRender(){ | |
272 | + //set all OpenGL parameters required for drawing | |
273 | + gl_prep_draw(); | |
274 | + | |
275 | + //draw the sphere | |
276 | + gl_draw_sphere(); | |
277 | + //gl_draw_wireframe(); | |
278 | + | |
279 | + } | |
280 | + | |
281 | + void glInit(unsigned int n){ | |
282 | + init(n); | |
283 | + } | |
284 | + | |
285 | + void push(double c){ | |
286 | + C.push_back(c); | |
287 | + } | |
288 | + | |
289 | + | |
290 | + | |
291 | + | |
292 | + | |
293 | + }; //end class sph_harmonics | |
294 | + | |
295 | + | |
296 | + | |
297 | + | |
298 | +} | |
299 | + | |
300 | + | |
301 | +#endif | ... | ... |