Commit 7006df5f3b680618a1597310683f8c334ca527fb
1 parent
0174d823
reformat of directory structure
Showing
26 changed files
with
2254 additions
and
350 deletions
Show diff stats
1 | +#ifndef RTS_GL_BIND_H | |
2 | +#define RTS_GL_BIND_H | |
3 | + | |
4 | +#include <GL/glew.h> | |
5 | +#include <GL/gl.h> | |
6 | + | |
7 | +#include <stdio.h> | |
8 | +#include <cstring> | |
9 | + | |
10 | +#include <cudaHandleError.h> | |
11 | +#include "cuda_gl_interop.h" | |
12 | +#include "rts/gl/error.h" | |
13 | + | |
14 | + | |
15 | +static void rtsInitGLEW() | |
16 | +{ | |
17 | + //Initialize the GLEW toolkit | |
18 | + | |
19 | + GLenum err = glewInit(); | |
20 | + if(GLEW_OK != err) | |
21 | + { | |
22 | + printf("Error starting GLEW."); | |
23 | + } | |
24 | + fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); | |
25 | +} | |
26 | + | |
27 | +static void rts_cudaSetDevice(int major = 1, int minor = 3) | |
28 | +{ | |
29 | + cudaDeviceProp prop; | |
30 | + int dev; | |
31 | + | |
32 | + //find a CUDA device that can handle an offscreen buffer | |
33 | + int num_gpu; | |
34 | + HANDLE_ERROR(cudaGetDeviceCount(&num_gpu)); | |
35 | + printf("Number of CUDA devices detected: %d\n", num_gpu); | |
36 | + memset(&prop, 0, sizeof(cudaDeviceProp)); | |
37 | + prop.major=major; | |
38 | + prop.minor=minor; | |
39 | + HANDLE_ERROR(cudaChooseDevice(&dev, &prop)); | |
40 | + HANDLE_ERROR(cudaGetDeviceProperties(&prop, dev)); | |
41 | + HANDLE_ERROR(cudaGLSetGLDevice(dev)); | |
42 | +} | |
43 | + | |
44 | +static void* rts_cudaMapResource(cudaGraphicsResource* cudaBufferResource) | |
45 | +{ | |
46 | + //this function takes a predefined CUDA resource and maps it to a pointer | |
47 | + void* buffer; | |
48 | + HANDLE_ERROR(cudaGraphicsMapResources(1, &cudaBufferResource, NULL)); | |
49 | + size_t size; | |
50 | + HANDLE_ERROR(cudaGraphicsResourceGetMappedPointer( (void**)&buffer, &size, cudaBufferResource)); | |
51 | + return buffer; | |
52 | +} | |
53 | +static void rts_cudaUnmapResource(cudaGraphicsResource* resource) | |
54 | +{ | |
55 | + //this function unmaps the CUDA resource so it can be used by OpenGL | |
56 | + HANDLE_ERROR(cudaGraphicsUnmapResources(1, &resource, NULL)); | |
57 | +} | |
58 | + | |
59 | +static void rts_cudaCreateRenderBuffer(GLuint &glBufferName, cudaGraphicsResource* &cudaBufferResource, int resX, int resY) | |
60 | +{ | |
61 | + //delete the previous buffer name and resource | |
62 | + if(cudaBufferResource != 0) | |
63 | + HANDLE_ERROR(cudaGraphicsUnregisterResource(cudaBufferResource)); | |
64 | + if(glBufferName != 0) | |
65 | + glDeleteBuffers(1, &glBufferName); | |
66 | + | |
67 | + //generate an OpenGL offscreen buffer | |
68 | + glGenBuffers(1, &glBufferName); | |
69 | + | |
70 | + //bind the buffer - directs all calls to this buffer | |
71 | + glBindBuffer(GL_PIXEL_UNPACK_BUFFER, glBufferName); | |
72 | + glBufferData(GL_PIXEL_UNPACK_BUFFER, resX * resY * sizeof(uchar3), NULL, GL_DYNAMIC_DRAW_ARB); | |
73 | + CHECK_OPENGL_ERROR | |
74 | + HANDLE_ERROR(cudaGraphicsGLRegisterBuffer(&cudaBufferResource, glBufferName, cudaGraphicsMapFlagsNone)); | |
75 | +} | |
76 | + | |
77 | +#endif | ... | ... |
1 | +#include "cuda_runtime.h" | |
2 | +#include "device_launch_parameters.h" | |
3 | +#include "rts/cuda/callable.h" | |
4 | + | |
5 | +#ifndef CUDA_THREADS_H | |
6 | +#define CUDA_THREADS_H | |
7 | + | |
8 | +#define MAX_GRID 65535 | |
9 | + | |
10 | +__device__ unsigned int ThreadIndex1D() | |
11 | +{ | |
12 | + return blockIdx.y * gridDim.x * blockDim.x + blockIdx.x * blockDim.x + threadIdx.x; | |
13 | +} | |
14 | + | |
15 | +dim3 GenGrid1D(unsigned int N, unsigned int blocksize = 128) | |
16 | +{ | |
17 | + dim3 dimgrid; | |
18 | + | |
19 | + dimgrid.x = (N + blocksize - 1)/blocksize; | |
20 | + dimgrid.y = 1; | |
21 | + dimgrid.z = 1; | |
22 | + | |
23 | + if(dimgrid.x > MAX_GRID) | |
24 | + { | |
25 | + dimgrid.y = (dimgrid.x + MAX_GRID - 1) / MAX_GRID; | |
26 | + dimgrid.x = MAX_GRID; | |
27 | + } | |
28 | + | |
29 | + return dimgrid; | |
30 | + | |
31 | +} | |
32 | + | |
33 | + | |
34 | +#endif | ... | ... |
rts/envi/envi.h
rts/envi/envi_header.h
... | ... | @@ -72,7 +72,7 @@ struct EnviHeader |
72 | 72 | std::string trim(std::string line) |
73 | 73 | { |
74 | 74 | //trims whitespace from the beginning and end of line |
75 | - int start_i, end_i; | |
75 | + unsigned int start_i, end_i; | |
76 | 76 | for(start_i=0; start_i < line.length(); start_i++) |
77 | 77 | if(line[start_i] != 32) |
78 | 78 | { |
... | ... | @@ -188,16 +188,12 @@ struct EnviHeader |
188 | 188 | { |
189 | 189 | //this function returns a sequence of comma-delimited strings |
190 | 190 | std::vector<double> result; |
191 | - | |
192 | - double fentry; | |
193 | - | |
194 | 191 | std::string entry; |
195 | 192 | size_t i; |
196 | 193 | do |
197 | 194 | { |
198 | 195 | i = sequence.find_first_of(','); |
199 | 196 | entry = sequence.substr(0, i); |
200 | - fentry = atof(entry.c_str()); | |
201 | 197 | sequence = sequence.substr(i+1); |
202 | 198 | result.push_back(atof(entry.c_str())); |
203 | 199 | //std::cout<<entry<<" "; |
... | ... | @@ -356,7 +352,7 @@ struct EnviHeader |
356 | 352 | if(band_names.size() > 0) |
357 | 353 | { |
358 | 354 | outfile<<"band names = {"<<std::endl; |
359 | - for(int i=0; i<band_names.size(); i++) | |
355 | + for(unsigned int i=0; i<band_names.size(); i++) | |
360 | 356 | { |
361 | 357 | outfile<<band_names[i]; |
362 | 358 | if(i < band_names.size() - 1) |
... | ... | @@ -365,7 +361,7 @@ struct EnviHeader |
365 | 361 | outfile<<"}"<<std::endl; |
366 | 362 | } |
367 | 363 | outfile<<"wavelength = {"<<std::endl; |
368 | - for(int i=0; i<wavelength.size()-1; i++) | |
364 | + for(unsigned int i=0; i<wavelength.size()-1; i++) | |
369 | 365 | outfile<<wavelength[i]<<", "; |
370 | 366 | outfile<<wavelength.back()<<"}"<<std::endl; |
371 | 367 | ... | ... |
1 | +#ifndef RTS_OPENGL_ERROR | |
2 | +#define RTS_OPENGL_ERROR | |
3 | + | |
4 | +#include <stdio.h> | |
5 | +#include <GL/gl.h> | |
6 | +#include <GL/glu.h> | |
7 | + | |
8 | +#define CHECK_OPENGL_ERROR \ | |
9 | +{ GLenum error; \ | |
10 | + while ( (error = glGetError()) != GL_NO_ERROR) { \ | |
11 | + printf( "OpenGL ERROR: %s\nCHECK POINT: %s (line %d)\n", gluErrorString(error), __FILE__, __LINE__ ); \ | |
12 | + } \ | |
13 | +} | |
14 | + | |
15 | +#endif | |
0 | 16 | \ No newline at end of file | ... | ... |
1 | +#ifndef RTSSOURCECODE_H | |
2 | +#define RTSSOURCECODE_H | |
3 | + | |
4 | +#include <string> | |
5 | +#include <fstream> | |
6 | +#include <vector> | |
7 | +#include <iostream> | |
8 | + | |
9 | +using namespace std; | |
10 | + | |
11 | +///This class defines generic source code that can be loaded from text files. It is primarily used by the rts_glShaderProgram class for GLSL programming. | |
12 | + | |
13 | +class rtsSourceCode | |
14 | +{ | |
15 | +public: | |
16 | + vector<string> source; //the actual source code | |
17 | + void clear() ///<Clears any current source code from the class. | |
18 | + { | |
19 | + source.clear(); | |
20 | + } | |
21 | + void LoadSource(const char* filename) ///<Loads source code from a specified file. | |
22 | + { | |
23 | + ifstream infile; //create an input file | |
24 | + infile.open(filename); //load the specified file | |
25 | + | |
26 | + if(!infile.is_open()) //if the file is not open, exit | |
27 | + { | |
28 | + return; | |
29 | + } | |
30 | + source.clear(); //remove any previous code | |
31 | + | |
32 | + while(!infile.eof()) | |
33 | + { | |
34 | + string current_line; | |
35 | + getline(infile, current_line); | |
36 | + current_line += '\n'; | |
37 | + source.push_back(current_line); | |
38 | + } | |
39 | + } | |
40 | + rtsSourceCode(const char* filename) ///<Constructor creates the class and loads source code from the specified file. | |
41 | + { | |
42 | + LoadSource(filename); | |
43 | + } | |
44 | + rtsSourceCode(){} ///<Constructor creates a blank class. | |
45 | + rtsSourceCode& operator+=(const rtsSourceCode& rhs) | |
46 | + { | |
47 | + int lines = rhs.source.size(); | |
48 | + for(int l=0; l<lines; l++) | |
49 | + source.push_back(rhs.source[l]); | |
50 | + return *this; | |
51 | + } | |
52 | + rtsSourceCode& operator+=(const string& rhs) | |
53 | + { | |
54 | + source.push_back(rhs); | |
55 | + return *this; | |
56 | + } | |
57 | + void ConsoleOut() ///<Sends the source code to the standard output. | |
58 | + { | |
59 | + unsigned int lines = source.size(); | |
60 | + for(unsigned int l = 0; l<lines; l++) | |
61 | + cout<<l<<": "<<source[l]; | |
62 | + } | |
63 | +}; | |
64 | + | |
65 | +#endif | |
0 | 66 | \ No newline at end of file | ... | ... |
1 | +#ifndef RTS_GLSHADERS | |
2 | +#define RTS_GLSHADERS | |
3 | + | |
4 | +#include <GL/glew.h> | |
5 | +//#include "windows.h" | |
6 | +#include <GL/gl.h> | |
7 | +#include "rtsSourceCode.h" | |
8 | + | |
9 | +class rts_glShaderObject | |
10 | +{ | |
11 | +private: | |
12 | + void init() | |
13 | + { | |
14 | + id = 0; | |
15 | + compiled = false; | |
16 | + type = GL_FRAGMENT_SHADER; | |
17 | + } | |
18 | +public: | |
19 | + bool compiled; | |
20 | + GLenum type; | |
21 | + rtsSourceCode source; | |
22 | + GLuint id; | |
23 | + string log; | |
24 | + | |
25 | + rts_glShaderObject(GLenum type, const char* filename) | |
26 | + { | |
27 | + init(); //initialize the shader | |
28 | + SetType(type); //set the shader type | |
29 | + LoadSource(filename); //load the source code | |
30 | + } | |
31 | + rts_glShaderObject(GLenum type, rtsSourceCode sourceCode) | |
32 | + { | |
33 | + init(); //initialize the shader | |
34 | + SetType(type); //set the shader type | |
35 | + source = sourceCode; | |
36 | + } | |
37 | + rts_glShaderObject() | |
38 | + { | |
39 | + init(); | |
40 | + } | |
41 | + rts_glShaderObject(GLenum type) | |
42 | + { | |
43 | + init(); | |
44 | + SetType(type); | |
45 | + } | |
46 | + void LoadSource(const char* filename) | |
47 | + { | |
48 | + source = rtsSourceCode(filename); //get the shader source code | |
49 | + | |
50 | + } | |
51 | + void SetType(GLenum type) | |
52 | + { | |
53 | + if(id != 0) //if a shader currently exists, delete it | |
54 | + { | |
55 | + glDeleteShader(id); | |
56 | + id = 0; | |
57 | + } | |
58 | + type = type; | |
59 | + id = glCreateShader(type); //create a shader object | |
60 | + if(id == 0) //if a shader was not created, log an error | |
61 | + { | |
62 | + log = "Error getting shader ID from OpenGL"; | |
63 | + return; | |
64 | + } | |
65 | + } | |
66 | + void UploadSource() | |
67 | + { | |
68 | + //create the structure for the shader source code | |
69 | + GLsizei count = source.source.size(); | |
70 | + GLchar** code_string = new GLchar*[count]; | |
71 | + GLint* length = new GLint[count]; | |
72 | + for(int l = 0; l<count; l++) //for each line of code | |
73 | + { | |
74 | + length[l] = source.source[l].size(); | |
75 | + code_string[l] = new GLchar[length[l]]; //copy the string into a new structure | |
76 | + source.source[l].copy(code_string[l], (unsigned int)length[l]); | |
77 | + | |
78 | + } | |
79 | + glShaderSource(id, count, (const GLchar**)code_string, length); //attach the shader source | |
80 | + } | |
81 | + void Compile() | |
82 | + { | |
83 | + /* | |
84 | + This function compiles the shader source code, records any errors to a log, and sets the compiled flag. | |
85 | + */ | |
86 | + //send the source code to the GPU | |
87 | + UploadSource(); | |
88 | + | |
89 | + //compile the shader | |
90 | + glCompileShader(id); //compile the shader | |
91 | + GLint compile_status; | |
92 | + glGetShaderiv(id, GL_COMPILE_STATUS, &compile_status); //get the compile status | |
93 | + if(compile_status != GL_TRUE) //if there was an error | |
94 | + { | |
95 | + GLchar buffer[1000]; //create a log buffer | |
96 | + GLsizei length; | |
97 | + glGetShaderInfoLog(id, 1000, &length, buffer); //get the log | |
98 | + log = buffer; | |
99 | + compiled = false; | |
100 | + } | |
101 | + else | |
102 | + compiled = true; | |
103 | + | |
104 | + } | |
105 | + void PrintLog() | |
106 | + { | |
107 | + cout<<log; | |
108 | + if(log.size() != 0) cout<<endl; | |
109 | + } | |
110 | + void Clean(){if(id != 0) glDeleteShader(id);} | |
111 | +}; | |
112 | + | |
113 | + | |
114 | + | |
115 | +#endif | ... | ... |
1 | +#ifndef RTS_GLSHADERPROGRAM_H | |
2 | +#define RTS_GLSHADERPROGRAM_H | |
3 | + | |
4 | +/********************************************************* | |
5 | +//create a shader program | |
6 | + rts_glShaderProgram myProgram; | |
7 | +//initialize | |
8 | + myProgram.Init(); | |
9 | +//Attach shaders | |
10 | + myProgram.AttachShader(GL_FRAGMENT_SHADER, "filename.glsl"); | |
11 | +//Compile and link | |
12 | + myProgram.Compile(); | |
13 | + myProgram.Link(); | |
14 | + myProgram.PrintLog(); | |
15 | +//attach uniform variables | |
16 | + myProgram.AttachTextureMap("texture", texture); | |
17 | + myProgram.AttachGlobalUniform("light_intensity", &intensity); | |
18 | + | |
19 | +//use the program | |
20 | + myProgram.BeginProgram(); | |
21 | + //render | |
22 | + myProgram.EndProgram(); | |
23 | +**********************************************************/ | |
24 | + | |
25 | + | |
26 | +#include "rts_glShaderObject.h" | |
27 | +#include "rts_glShaderUniform.h" | |
28 | +#include "rts_glTextureMap.h" | |
29 | +#include <algorithm> | |
30 | + | |
31 | +using namespace std; | |
32 | + | |
33 | +class rts_glShaderProgram | |
34 | +{ | |
35 | +private: | |
36 | + void get_uniforms() | |
37 | + { | |
38 | + GLint num_uniforms; | |
39 | + glGetProgramiv(id, GL_ACTIVE_UNIFORMS, &num_uniforms); //get the number of uniform variables | |
40 | + GLint max_name_length; | |
41 | + glGetProgramiv(id, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max_name_length); //get the maximum uniform name length | |
42 | + GLchar* name_buffer = new GLchar[max_name_length]; //create a buffer to store the name | |
43 | + GLsizei length; //I'm not using these yet | |
44 | + GLint size; | |
45 | + GLenum type; //variable's data type | |
46 | + GLint location; //GPU location of the variable | |
47 | + for(int i=0; i<num_uniforms; i++) //create an rts_glShaderUniform structure for each variable | |
48 | + { | |
49 | + glGetActiveUniform(id, i, max_name_length, &length, &size, &type, name_buffer); //get the uniform information | |
50 | + location = glGetUniformLocation(id, name_buffer); //get the GPU location of the variable | |
51 | + //create the rts_glShaderUniform structure | |
52 | + rts_glShaderUniform current; | |
53 | + current.location = location; | |
54 | + current.name = name_buffer; | |
55 | + current.type = type; | |
56 | + current.p_value = NULL; | |
57 | + | |
58 | + | |
59 | + uniform_list.push_back(current); | |
60 | + } | |
61 | + | |
62 | + } | |
63 | + int get_index(const char* name) | |
64 | + { | |
65 | + unsigned int size = uniform_list.size(); | |
66 | + for(unsigned int i=0; i<size; i++) | |
67 | + { | |
68 | + if(uniform_list[i].name == name) | |
69 | + return i; | |
70 | + } | |
71 | + return -1; | |
72 | + } | |
73 | + string log; | |
74 | +public: | |
75 | + GLuint id; | |
76 | + bool linked; | |
77 | + vector<rts_glShaderObject> shader_list; //list of opengl shaders | |
78 | + vector<rts_glShaderUniform> uniform_list; //list of active uniform variables | |
79 | + vector<rts_glTextureMap> texture_list; //list of texture maps | |
80 | + | |
81 | + rts_glShaderProgram() | |
82 | + { | |
83 | + linked = false; | |
84 | + id = 0; | |
85 | + } | |
86 | + void AttachShader(rts_glShaderObject shader) | |
87 | + { | |
88 | + if(id == 0) | |
89 | + { | |
90 | + Init(); | |
91 | + } | |
92 | + if(shader.id == 0) //if the shader is invalid | |
93 | + { | |
94 | + log = "Shader is invalid"; | |
95 | + return; | |
96 | + } | |
97 | + | |
98 | + //attach the shader to the program | |
99 | + glAttachShader(id, shader.id); //attach the shader to the program in OpenGL | |
100 | + CHECK_OPENGL_ERROR | |
101 | + shader_list.push_back(shader); //push the shader onto our list for later access | |
102 | + } | |
103 | + //type = GL_FRAGMENT_SHADER or GL_VERTEX_SHADER | |
104 | + void AttachShader(GLenum type, const char* filename) | |
105 | + { | |
106 | + rts_glShaderObject shader(type, filename); | |
107 | + AttachShader(shader); | |
108 | + } | |
109 | + void AttachShader(GLenum type, rtsSourceCode source) | |
110 | + { | |
111 | + rts_glShaderObject shader(type, source); | |
112 | + AttachShader(shader); | |
113 | + } | |
114 | + void PrintLog() | |
115 | + { | |
116 | + cout<<log; | |
117 | + | |
118 | + if(log.size() != 0) cout<<endl; | |
119 | + } | |
120 | + void Compile() | |
121 | + { | |
122 | + if(shader_list.size() == 0) | |
123 | + { | |
124 | + log = "No shaders to compile"; | |
125 | + return; | |
126 | + } | |
127 | + | |
128 | + vector<rts_glShaderObject>::iterator iter; | |
129 | + for(iter = shader_list.begin(); iter != shader_list.end(); iter++) | |
130 | + { | |
131 | + (*iter).Compile(); | |
132 | + //(*iter).PrintLog(); | |
133 | + } | |
134 | + } | |
135 | + void Link() | |
136 | + { | |
137 | + glLinkProgram(id); //link the current shader program | |
138 | + GLint link_status; //test to see if the link went alright | |
139 | + glGetProgramiv(id, GL_LINK_STATUS, &link_status); | |
140 | + if(link_status != GL_TRUE) | |
141 | + { | |
142 | + linked = false; | |
143 | + } | |
144 | + else | |
145 | + linked = true; | |
146 | + | |
147 | + GLsizei length; | |
148 | + GLchar buffer[1000]; | |
149 | + glGetProgramInfoLog(id, 1000, &length, buffer); | |
150 | + log = buffer; | |
151 | + | |
152 | + get_uniforms(); //create the list of active uniform variables | |
153 | + } | |
154 | + void BeginProgram() | |
155 | + { | |
156 | + CHECK_OPENGL_ERROR | |
157 | + if(id == 0) //if the program is invalid, return | |
158 | + { | |
159 | + log = "Invalid program, cannot use."; | |
160 | + return; | |
161 | + } | |
162 | + if(!linked) | |
163 | + { | |
164 | + cout<<"Shader Program used without being linked."<<endl; | |
165 | + //exit(1); | |
166 | + } | |
167 | + | |
168 | + //set up all of the texture maps | |
169 | + int num_textures = texture_list.size(); | |
170 | + | |
171 | + for(int t=0; t<num_textures; t++) | |
172 | + { | |
173 | + glActiveTexture(GL_TEXTURE0 + t); | |
174 | + CHECK_OPENGL_ERROR | |
175 | + //glEnable(texture_list[t].texture_type); | |
176 | + //CHECK_OPENGL_ERROR | |
177 | + glBindTexture(texture_list[t].texture_type, texture_list[t].name); | |
178 | + CHECK_OPENGL_ERROR | |
179 | + } | |
180 | + | |
181 | + glUseProgram(id); | |
182 | + CHECK_OPENGL_ERROR | |
183 | + } | |
184 | + void EndProgram() | |
185 | + { | |
186 | + CHECK_OPENGL_ERROR | |
187 | + //return standard functionality | |
188 | + int num_textures = texture_list.size(); | |
189 | + | |
190 | + //disable all texture units | |
191 | + for(int t=0; t<num_textures; t++) | |
192 | + { | |
193 | + glActiveTexture(GL_TEXTURE0 + t); | |
194 | + glDisable(texture_list[t].texture_type); | |
195 | + CHECK_OPENGL_ERROR | |
196 | + } | |
197 | + //make sure that the single default texture unit is active | |
198 | + if(num_textures > 0) | |
199 | + glActiveTexture(GL_TEXTURE0); | |
200 | + CHECK_OPENGL_ERROR | |
201 | + | |
202 | + //return to OpenGL default shading | |
203 | + glUseProgram(0); | |
204 | + CHECK_OPENGL_ERROR | |
205 | + } | |
206 | + void PrintUniforms() | |
207 | + { | |
208 | + cout<<"Shader Uniforms: "<<endl; | |
209 | + unsigned int i; | |
210 | + for(i=0; i<uniform_list.size(); i++) | |
211 | + { | |
212 | + cout<<i<<": "<<uniform_list[i].name<<" "<<uniform_list[i].location<<endl; | |
213 | + } | |
214 | + } | |
215 | + void AttachGlobalUniform(unsigned int index, void* param) //attaches a global variable to the indexed uniform parameter | |
216 | + { | |
217 | + uniform_list[index].p_value = param; | |
218 | + } | |
219 | + void AttachGlobalUniform(const char* name, void* param) | |
220 | + { | |
221 | + //find the index of the shader | |
222 | + int index = get_index(name); | |
223 | + if(index != -1) | |
224 | + AttachGlobalUniform(index, param); | |
225 | + else | |
226 | + { | |
227 | + string strError = "Error finding uniform variable: "; | |
228 | + strError += name; | |
229 | + cout<<strError<<endl; | |
230 | + } | |
231 | + } | |
232 | + void AttachTextureMap(unsigned int index, rts_glTextureMap texture) //attaches a texture map to the program | |
233 | + { | |
234 | + //if there is not a texture map assigned to the variable | |
235 | + if(uniform_list[index].p_value == NULL) | |
236 | + { | |
237 | + uniform_list[index].p_value = new unsigned int[1]; | |
238 | + ((unsigned int*)uniform_list[index].p_value)[0] = texture_list.size(); //set the parameter value to the index of the texture | |
239 | + texture_list.push_back(texture); //add the texture to the texture list | |
240 | + } | |
241 | + //if there is a texture map assigned, replace it | |
242 | + else | |
243 | + { | |
244 | + texture_list[((unsigned int*)(uniform_list[index].p_value))[0]] = texture; | |
245 | + } | |
246 | + | |
247 | + } | |
248 | + void AttachTextureMap(const char* name, rts_glTextureMap texture) | |
249 | + { | |
250 | + int index = get_index(name); | |
251 | + if(index != -1) //make sure that the uniform index is valid | |
252 | + AttachTextureMap(index, texture); | |
253 | + else | |
254 | + cout<<"Error finding texture index. Try linking."<<endl; | |
255 | + } | |
256 | + void UpdateGlobalUniforms() //sends updated uniform information to the GPU | |
257 | + { | |
258 | + CHECK_OPENGL_ERROR | |
259 | + BeginProgram(); | |
260 | + CHECK_OPENGL_ERROR | |
261 | + unsigned int num = uniform_list.size(); | |
262 | + for(unsigned int i=0; i<num; i++) | |
263 | + uniform_list[i].submit_to_gpu(); | |
264 | + EndProgram(); | |
265 | + } | |
266 | + void Init() //Initialize the shader program | |
267 | + { | |
268 | + CHECK_OPENGL_ERROR | |
269 | + if(id != 0) | |
270 | + Clean(); | |
271 | + id = glCreateProgram(); | |
272 | + if(id == 0) | |
273 | + log = "Error getting program ID from OpenGL"; | |
274 | + CHECK_OPENGL_ERROR | |
275 | + } | |
276 | + void Clean() | |
277 | + { | |
278 | + if(id != 0) | |
279 | + glDeleteProgram(id); | |
280 | + id = 0; | |
281 | + | |
282 | + //these are allocated outside the object and can just be cleared | |
283 | + uniform_list.clear(); | |
284 | + texture_list.clear(); | |
285 | + | |
286 | + //delete each shader from OpenGL | |
287 | + int num_shad = shader_list.size(); | |
288 | + for(int i=0; i<num_shad; i++) | |
289 | + shader_list[i].Clean(); | |
290 | + //clear the list | |
291 | + shader_list.clear(); | |
292 | + } | |
293 | +}; | |
294 | + | |
295 | +#endif | ... | ... |
1 | +#ifndef RTS_GLSHADERUNIFORM_H | |
2 | +#define RTS_GLSHADERUNIFORM_H | |
3 | + | |
4 | +#include "CHECK_OPENGL_ERROR.h" | |
5 | +#include <GL/glew.h> | |
6 | +#include <string> | |
7 | + | |
8 | +using namespace std; | |
9 | + | |
10 | +enum rtsUniformEnum {RTS_FLOAT, RTS_INT, RTS_BOOL, RTS_FLOAT_MATRIX}; | |
11 | + | |
12 | +///This class stores a single uniform variable for GLSL and is designed to be used by the rts_glShaderProgram class. | |
13 | +struct rts_glShaderUniform | |
14 | +{ | |
15 | +public: | |
16 | + string name; //the name of the variable | |
17 | + GLint location; //the location in the program | |
18 | + void* p_value; //pointer to the global data representing the value in main memory | |
19 | + GLenum type; //variable type (float, int, vec2, etc.) | |
20 | + //rtsUniformEnum rts_type; //type of variable in rts format | |
21 | + //unsigned int num; //the number of values required by the variable (1 for float, 2 for vec2, etc.) | |
22 | + string log; | |
23 | + | |
24 | + //void convert_type(GLenum gl_type); //converts the OpenGL data type to something useful for rts | |
25 | + void submit_to_gpu() | |
26 | + { | |
27 | + if(location < 0) | |
28 | + return; | |
29 | + if(p_value == NULL) | |
30 | + { | |
31 | + cout<<"Error in uniform address: "<<name<<endl; | |
32 | + return; | |
33 | + } | |
34 | + | |
35 | + | |
36 | + CHECK_OPENGL_ERROR | |
37 | + switch(type) | |
38 | + { | |
39 | + case GL_FLOAT: | |
40 | + glUniform1fv(location, 1, (float*)p_value); | |
41 | + break; | |
42 | + case GL_FLOAT_VEC2: | |
43 | + glUniform2fv(location, 1, (float*)p_value); | |
44 | + break; | |
45 | + case GL_FLOAT_VEC3: | |
46 | + glUniform3fv(location, 1, (float*)p_value); | |
47 | + break; | |
48 | + case GL_FLOAT_VEC4: | |
49 | + glUniform4fv(location, 1, (float*)p_value); | |
50 | + break; | |
51 | + case GL_INT: | |
52 | + glUniform1iv(location, 1, (int*)p_value); | |
53 | + break; | |
54 | + case GL_INT_VEC2: | |
55 | + glUniform2iv(location, 1, (int*)p_value); | |
56 | + break; | |
57 | + case GL_INT_VEC3: | |
58 | + glUniform3iv(location, 1, (int*)p_value); | |
59 | + break; | |
60 | + case GL_INT_VEC4: | |
61 | + glUniform4iv(location, 1, (int*)p_value); | |
62 | + break; | |
63 | + case GL_BOOL: | |
64 | + glUniform1iv(location, 1, (int*)p_value); | |
65 | + break; | |
66 | + case GL_BOOL_VEC2: | |
67 | + glUniform2iv(location, 1, (int*)p_value); | |
68 | + break; | |
69 | + case GL_BOOL_VEC3: | |
70 | + glUniform3iv(location, 1, (int*)p_value); | |
71 | + break; | |
72 | + case GL_BOOL_VEC4: | |
73 | + glUniform4iv(location, 1, (int*)p_value); | |
74 | + break; | |
75 | + case GL_FLOAT_MAT2: | |
76 | + glUniformMatrix2fv(location, 1, GL_FALSE, (float*)p_value); | |
77 | + break; | |
78 | + case GL_FLOAT_MAT3: | |
79 | + glUniformMatrix3fv(location, 1, GL_FALSE, (float*)p_value); | |
80 | + break; | |
81 | + case GL_FLOAT_MAT4: | |
82 | + glUniformMatrix4fv(location, 1, GL_FALSE, (float*)p_value); | |
83 | + break; | |
84 | + case GL_SAMPLER_1D: | |
85 | + case GL_SAMPLER_2D: | |
86 | + case GL_SAMPLER_3D: | |
87 | + case GL_SAMPLER_CUBE: | |
88 | + case GL_SAMPLER_1D_SHADOW: | |
89 | + case GL_SAMPLER_2D_SHADOW: | |
90 | + default: | |
91 | + glUniform1iv(location, 1, (int*)p_value); | |
92 | + break; | |
93 | + } | |
94 | + CHECK_OPENGL_ERROR | |
95 | + } | |
96 | + rts_glShaderUniform() | |
97 | + { | |
98 | + location = -1; | |
99 | + p_value = NULL; | |
100 | + } | |
101 | +}; | |
102 | + | |
103 | + | |
104 | + | |
105 | +#endif | |
0 | 106 | \ No newline at end of file | ... | ... |
1 | +#ifndef RTS_GLUTILITIES_H | |
2 | +#define RTS_GLUTILITIES_H | |
3 | + | |
4 | + | |
5 | +#define CHECK_OPENGL_ERROR \ | |
6 | +{ GLenum error; \ | |
7 | + while ( (error = glGetError()) != GL_NO_ERROR) { \ | |
8 | + printf( "OpenGL ERROR: %s\nCHECK POINT: %s (line %d)\n", gluErrorString(error), __FILE__, __LINE__ ); \ | |
9 | + } \ | |
10 | +} | |
11 | + | |
12 | +#endif | |
0 | 13 | \ No newline at end of file | ... | ... |
1 | +#ifndef RTS_GLTEXTUREMAP_H | |
2 | +#define RTS_GLTEXTUREMAP_H | |
3 | + | |
4 | +//#include <GL/glew.h> | |
5 | +#include "rts/math/vector.h" | |
6 | +#include "rts/gl/error.h" | |
7 | +#include <stdlib.h> | |
8 | + | |
9 | +namespace rts{ | |
10 | + | |
11 | +///This class stores an OpenGL texture map and is used by rts_glShaderProgram. | |
12 | +class glTexture | |
13 | +{ | |
14 | +private: | |
15 | + void get_type() //guesses the texture type based on the size | |
16 | + { | |
17 | + if(size[1] == 0) | |
18 | + texture_type = GL_TEXTURE_1D; | |
19 | + else if(size[2] == 0) | |
20 | + texture_type = GL_TEXTURE_2D; | |
21 | + else | |
22 | + texture_type = GL_TEXTURE_3D; | |
23 | + } | |
24 | + void set_wrapping() //set the texture wrapping based on the dimensions | |
25 | + { | |
26 | + CHECK_OPENGL_ERROR | |
27 | + switch(texture_type) | |
28 | + { | |
29 | + case GL_TEXTURE_3D: | |
30 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_R_EXT, GL_REPEAT); | |
31 | + case GL_TEXTURE_2D: | |
32 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_MIRRORED_REPEAT); | |
33 | + case GL_TEXTURE_1D: | |
34 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_REPEAT); | |
35 | + break; | |
36 | + case GL_TEXTURE_RECTANGLE_ARB: | |
37 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
38 | + glTexParameteri(texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
39 | + break; | |
40 | + | |
41 | + default: | |
42 | + break; | |
43 | + } | |
44 | + CHECK_OPENGL_ERROR | |
45 | + } | |
46 | + //void set_bits(GLvoid* bits); | |
47 | +public: | |
48 | + vector<GLsizei, 3> size; //vector representing the size of the texture | |
49 | + GLuint name; //texture name assigned by OpenGL | |
50 | + GLenum texture_type; //1D, 2D, 3D | |
51 | + GLint internal_format; //number of components (ex. 4 for RGBA) | |
52 | + GLenum pixel_format; //type of data (RGBA, LUMINANCE) | |
53 | + GLenum data_type; //data type of the bits (float, int, etc.) | |
54 | + | |
55 | + //constructor | |
56 | + glTexture() | |
57 | + { | |
58 | + name = 0; | |
59 | + } | |
60 | + glTexture(GLvoid *bits, | |
61 | + GLenum type = GL_TEXTURE_2D, | |
62 | + GLsizei width = 256, | |
63 | + GLsizei height = 256, | |
64 | + GLsizei depth = 0, | |
65 | + GLint internalformat = 1, | |
66 | + GLenum format = GL_LUMINANCE, | |
67 | + GLenum datatype = GL_UNSIGNED_BYTE, | |
68 | + GLint interpolation = GL_LINEAR) | |
69 | + { | |
70 | + init(bits, type, width, height, depth, internalformat, format, datatype, interpolation); | |
71 | + } | |
72 | + | |
73 | + void begin() | |
74 | + { | |
75 | + glEnable(texture_type); | |
76 | + CHECK_OPENGL_ERROR | |
77 | + glBindTexture(texture_type, name); | |
78 | + CHECK_OPENGL_ERROR | |
79 | + } | |
80 | + void end() | |
81 | + { | |
82 | + glDisable(texture_type); | |
83 | + CHECK_OPENGL_ERROR | |
84 | + } | |
85 | + | |
86 | + ///Creates an OpenGL texture map. This function requires basic information about the texture map as well as a pointer to the bit data describing the texture. | |
87 | + void init(GLvoid *bits, | |
88 | + GLenum type = GL_TEXTURE_2D, | |
89 | + GLsizei width = 256, | |
90 | + GLsizei height = 256, | |
91 | + GLsizei depth = 0, | |
92 | + GLint internalformat = 1, | |
93 | + GLenum format = GL_LUMINANCE, | |
94 | + GLenum datatype = GL_UNSIGNED_BYTE, | |
95 | + GLint interpolation = GL_LINEAR) | |
96 | + { | |
97 | + CHECK_OPENGL_ERROR | |
98 | + if(name != 0) | |
99 | + glDeleteTextures(1, &name); | |
100 | + | |
101 | + | |
102 | + CHECK_OPENGL_ERROR | |
103 | + if(datatype == GL_FLOAT) | |
104 | + { | |
105 | + glPixelStorei(GL_PACK_ALIGNMENT, 4); | |
106 | + glPixelStorei(GL_UNPACK_ALIGNMENT, 4); //I honestly don't know what this does but it fixes problems | |
107 | + } | |
108 | + else if(datatype == GL_UNSIGNED_BYTE) | |
109 | + { | |
110 | + //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); | |
111 | + //glPixelStorei(GL_PACK_ALIGNMENT, 1); | |
112 | + } | |
113 | + else if(datatype == GL_UNSIGNED_SHORT) | |
114 | + { | |
115 | + //glPixelStorei(GL_UNPACK_ALIGNMENT, 2); | |
116 | + //glPixelStorei(GL_PACK_ALIGNMENT, 2); | |
117 | + } | |
118 | + CHECK_OPENGL_ERROR | |
119 | + glGenTextures(1, &name); //get the texture name from OpenGL | |
120 | + //cout<<"OpenGL Name: "<<name<<endl; | |
121 | + CHECK_OPENGL_ERROR | |
122 | + size = vector<GLsizei, 3>(width, height, depth); //assign the texture size | |
123 | + //get_type(); //guess the type based on the size | |
124 | + texture_type = type; //set the type of texture | |
125 | + glEnable(texture_type); //enable the texture map | |
126 | + CHECK_OPENGL_ERROR | |
127 | + glBindTexture(texture_type, name); //bind the texture for editing | |
128 | + CHECK_OPENGL_ERROR | |
129 | + set_wrapping(); //set the texture wrapping parameters | |
130 | + CHECK_OPENGL_ERROR | |
131 | + glTexParameteri(texture_type, GL_TEXTURE_MAG_FILTER, interpolation); //set filtering | |
132 | + CHECK_OPENGL_ERROR | |
133 | + glTexParameteri(texture_type, GL_TEXTURE_MIN_FILTER, interpolation); | |
134 | + CHECK_OPENGL_ERROR | |
135 | + internal_format = internalformat; //set the number of components per pixel | |
136 | + pixel_format = format; //set the pixel format | |
137 | + data_type = datatype; //set the data type | |
138 | + SetBits(bits); //send the bits to the OpenGL driver | |
139 | + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); //replace the specified vertex color | |
140 | + CHECK_OPENGL_ERROR | |
141 | + glDisable(texture_type); | |
142 | + | |
143 | + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
144 | + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
145 | + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); | |
146 | + } | |
147 | + void Clean() | |
148 | + { | |
149 | + if(name != 0) | |
150 | + { | |
151 | + glDeleteTextures(1, &name); | |
152 | + CHECK_OPENGL_ERROR | |
153 | + name = 0; | |
154 | + } | |
155 | + } | |
156 | + void SetBits(GLvoid *bits) | |
157 | + { | |
158 | + glEnable(texture_type); //enable the texture map | |
159 | + CHECK_OPENGL_ERROR | |
160 | + glBindTexture(texture_type, name); | |
161 | + CHECK_OPENGL_ERROR | |
162 | + | |
163 | + switch(texture_type) | |
164 | + { | |
165 | + case GL_TEXTURE_3D: | |
166 | + glTexImage3D(texture_type, 0, internal_format, size[0], size[1], size[2], 0, pixel_format, data_type, bits); | |
167 | + CHECK_OPENGL_ERROR | |
168 | + break; | |
169 | + case GL_TEXTURE_2D: | |
170 | + case GL_TEXTURE_RECTANGLE_ARB: | |
171 | + glTexImage2D(texture_type, 0, internal_format, size[0], size[1], 0, pixel_format, data_type, bits); | |
172 | + CHECK_OPENGL_ERROR | |
173 | + break; | |
174 | + case GL_TEXTURE_1D: | |
175 | + glTexImage1D(texture_type, 0, internal_format, size[0], 0, pixel_format, data_type, bits); | |
176 | + CHECK_OPENGL_ERROR | |
177 | + break; | |
178 | + default: | |
179 | + //glTexImage2D(texture_type, 0, internal_format, size.x, size.y, 0, pixel_format, data_type, bits); | |
180 | + break; | |
181 | + } | |
182 | + CHECK_OPENGL_ERROR | |
183 | + } | |
184 | + void ResetBits(GLvoid *bits) | |
185 | + { | |
186 | + glEnable(texture_type); //enable the texture map | |
187 | + CHECK_OPENGL_ERROR | |
188 | + glBindTexture(texture_type, name); | |
189 | + CHECK_OPENGL_ERROR | |
190 | + | |
191 | + switch(texture_type) | |
192 | + { | |
193 | + case GL_TEXTURE_3D: | |
194 | + //glTexImage3D(texture_type, 0, internal_format, size.x, size.y, size.z, 0, pixel_format, data_type, bits); | |
195 | + break; | |
196 | + case GL_TEXTURE_2D: | |
197 | + case GL_TEXTURE_RECTANGLE_ARB: | |
198 | + glTexSubImage2D(texture_type, 0, 0, 0, size[0], size[1], pixel_format, data_type, bits); | |
199 | + CHECK_OPENGL_ERROR | |
200 | + break; | |
201 | + case GL_TEXTURE_1D: | |
202 | + //glTexImage1D(texture_type, 0, internal_format, size.x, 0, pixel_format, data_type, bits); | |
203 | + break; | |
204 | + default: | |
205 | + //glTexImage2D(texture_type, 0, internal_format, size.x, size.y, 0, pixel_format, data_type, bits); | |
206 | + break; | |
207 | + } | |
208 | + glDisable(texture_type); | |
209 | + CHECK_OPENGL_ERROR | |
210 | + } | |
211 | + void* GetBits(GLenum format, GLenum type) | |
212 | + { | |
213 | + //returns the texture data | |
214 | + | |
215 | + int components; | |
216 | + switch(format) | |
217 | + { | |
218 | + case GL_RED: | |
219 | + case GL_GREEN: | |
220 | + case GL_BLUE: | |
221 | + case GL_ALPHA: | |
222 | + case GL_LUMINANCE: | |
223 | + components = 1; | |
224 | + break; | |
225 | + case GL_LUMINANCE_ALPHA: | |
226 | + components = 2; | |
227 | + break; | |
228 | + case GL_RGB: | |
229 | + case GL_BGR: | |
230 | + components = 3; | |
231 | + break; | |
232 | + case GL_RGBA: | |
233 | + case GL_BGRA: | |
234 | + components = 4; | |
235 | + break; | |
236 | + } | |
237 | + | |
238 | + int type_size; | |
239 | + switch(type) | |
240 | + { | |
241 | + case GL_UNSIGNED_BYTE: | |
242 | + case GL_BYTE: | |
243 | + type_size = sizeof(char); | |
244 | + break; | |
245 | + case GL_UNSIGNED_SHORT: | |
246 | + case GL_SHORT: | |
247 | + type_size = sizeof(short); | |
248 | + break; | |
249 | + case GL_UNSIGNED_INT: | |
250 | + case GL_INT: | |
251 | + type_size = sizeof(int); | |
252 | + break; | |
253 | + case GL_FLOAT: | |
254 | + type_size = sizeof(float); | |
255 | + break; | |
256 | + } | |
257 | + | |
258 | + //allocate memory for the texture | |
259 | + void* result = malloc(components*type_size * size[0] * size[1]); | |
260 | + | |
261 | + begin(); | |
262 | + glGetTexImage(texture_type, 0, format, type, result); | |
263 | + | |
264 | + CHECK_OPENGL_ERROR | |
265 | + end(); | |
266 | + | |
267 | + | |
268 | + return result; | |
269 | + | |
270 | + } | |
271 | +}; | |
272 | + | |
273 | +} | |
274 | + | |
275 | +#define RTS_UNKNOWN 0 | |
276 | + | |
277 | +#endif | ... | ... |
rts/math/complex.h
... | ... | @@ -15,12 +15,12 @@ namespace rts |
15 | 15 | { |
16 | 16 | |
17 | 17 | template <class T> |
18 | -struct rtsComplex | |
18 | +struct complex | |
19 | 19 | { |
20 | 20 | T r, i; |
21 | 21 | |
22 | 22 | //default constructor |
23 | - CUDA_CALLABLE rtsComplex() | |
23 | + CUDA_CALLABLE complex() | |
24 | 24 | { |
25 | 25 | r = 0.0; |
26 | 26 | i = 0.0; |
... | ... | @@ -49,16 +49,16 @@ struct rtsComplex |
49 | 49 | } |
50 | 50 | |
51 | 51 | //constructor when given real and imaginary values |
52 | - CUDA_CALLABLE rtsComplex(T r, T i) | |
52 | + CUDA_CALLABLE complex(T r, T i) | |
53 | 53 | { |
54 | 54 | this->r = r; |
55 | 55 | this->i = i; |
56 | 56 | } |
57 | 57 | |
58 | 58 | //return the current value multiplied by i |
59 | - CUDA_CALLABLE rtsComplex<T> imul() | |
59 | + CUDA_CALLABLE complex<T> imul() | |
60 | 60 | { |
61 | - rtsComplex<T> result; | |
61 | + complex<T> result; | |
62 | 62 | result.r = -i; |
63 | 63 | result.i = r; |
64 | 64 | |
... | ... | @@ -68,70 +68,70 @@ struct rtsComplex |
68 | 68 | //ARITHMETIC OPERATORS-------------------- |
69 | 69 | |
70 | 70 | //binary + operator (returns the result of adding two complex values) |
71 | - CUDA_CALLABLE rtsComplex<T> operator+ (const rtsComplex<T> rhs) | |
71 | + CUDA_CALLABLE complex<T> operator+ (const complex<T> rhs) | |
72 | 72 | { |
73 | - rtsComplex<T> result; | |
73 | + complex<T> result; | |
74 | 74 | result.r = r + rhs.r; |
75 | 75 | result.i = i + rhs.i; |
76 | 76 | return result; |
77 | 77 | } |
78 | 78 | |
79 | - CUDA_CALLABLE rtsComplex<T> operator+ (const T rhs) | |
79 | + CUDA_CALLABLE complex<T> operator+ (const T rhs) | |
80 | 80 | { |
81 | - rtsComplex<T> result; | |
81 | + complex<T> result; | |
82 | 82 | result.r = r + rhs; |
83 | 83 | result.i = i; |
84 | 84 | return result; |
85 | 85 | } |
86 | 86 | |
87 | 87 | //binary - operator (returns the result of adding two complex values) |
88 | - CUDA_CALLABLE rtsComplex<T> operator- (const rtsComplex<T> rhs) | |
88 | + CUDA_CALLABLE complex<T> operator- (const complex<T> rhs) | |
89 | 89 | { |
90 | - rtsComplex<T> result; | |
90 | + complex<T> result; | |
91 | 91 | result.r = r - rhs.r; |
92 | 92 | result.i = i - rhs.i; |
93 | 93 | return result; |
94 | 94 | } |
95 | 95 | |
96 | 96 | //binary - operator (returns the result of adding two complex values) |
97 | - CUDA_CALLABLE rtsComplex<T> operator- (const T rhs) | |
97 | + CUDA_CALLABLE complex<T> operator- (const T rhs) | |
98 | 98 | { |
99 | - rtsComplex<T> result; | |
99 | + complex<T> result; | |
100 | 100 | result.r = r - rhs; |
101 | 101 | result.i = i; |
102 | 102 | return result; |
103 | 103 | } |
104 | 104 | |
105 | 105 | //binary MULTIPLICATION operators (returns the result of multiplying complex values) |
106 | - CUDA_CALLABLE rtsComplex<T> operator* (const rtsComplex<T> rhs) | |
106 | + CUDA_CALLABLE complex<T> operator* (const complex<T> rhs) | |
107 | 107 | { |
108 | - rtsComplex<T> result; | |
108 | + complex<T> result; | |
109 | 109 | result.r = r * rhs.r - i * rhs.i; |
110 | 110 | result.i = r * rhs.i + i * rhs.r; |
111 | 111 | return result; |
112 | 112 | } |
113 | - CUDA_CALLABLE rtsComplex<T> operator* (const T rhs) | |
113 | + CUDA_CALLABLE complex<T> operator* (const T rhs) | |
114 | 114 | { |
115 | - return rtsComplex<T>(r * rhs, i * rhs); | |
115 | + return complex<T>(r * rhs, i * rhs); | |
116 | 116 | } |
117 | 117 | |
118 | 118 | //binary DIVISION operators (returns the result of dividing complex values) |
119 | - CUDA_CALLABLE rtsComplex<T> operator/ (const rtsComplex<T> rhs) | |
119 | + CUDA_CALLABLE complex<T> operator/ (const complex<T> rhs) | |
120 | 120 | { |
121 | - rtsComplex<T> result; | |
121 | + complex<T> result; | |
122 | 122 | T denom = rhs.r * rhs.r + rhs.i * rhs.i; |
123 | 123 | result.r = (r * rhs.r + i * rhs.i) / denom; |
124 | 124 | result.i = (- r * rhs.i + i * rhs.r) / denom; |
125 | 125 | |
126 | 126 | return result; |
127 | 127 | } |
128 | - CUDA_CALLABLE rtsComplex<T> operator/ (const T rhs) | |
128 | + CUDA_CALLABLE complex<T> operator/ (const T rhs) | |
129 | 129 | { |
130 | - return rtsComplex<T>(r / rhs, i / rhs); | |
130 | + return complex<T>(r / rhs, i / rhs); | |
131 | 131 | } |
132 | 132 | |
133 | 133 | //ASSIGNMENT operators----------------------------------- |
134 | - CUDA_CALLABLE rtsComplex<T> & operator=(const rtsComplex<T> &rhs) | |
134 | + CUDA_CALLABLE complex<T> & operator=(const complex<T> &rhs) | |
135 | 135 | { |
136 | 136 | //check for self-assignment |
137 | 137 | if(this != &rhs) |
... | ... | @@ -141,7 +141,7 @@ struct rtsComplex |
141 | 141 | } |
142 | 142 | return *this; |
143 | 143 | } |
144 | - CUDA_CALLABLE rtsComplex<T> & operator=(const T &rhs) | |
144 | + CUDA_CALLABLE complex<T> & operator=(const T &rhs) | |
145 | 145 | { |
146 | 146 | this->r = rhs; |
147 | 147 | this->i = 0; |
... | ... | @@ -150,34 +150,34 @@ struct rtsComplex |
150 | 150 | } |
151 | 151 | |
152 | 152 | //arithmetic assignment operators |
153 | - CUDA_CALLABLE rtsComplex<T> operator+=(const rtsComplex<T> &rhs) | |
153 | + CUDA_CALLABLE complex<T> operator+=(const complex<T> &rhs) | |
154 | 154 | { |
155 | 155 | *this = *this + rhs; |
156 | 156 | return *this; |
157 | 157 | } |
158 | - CUDA_CALLABLE rtsComplex<T> operator+=(const T &rhs) | |
158 | + CUDA_CALLABLE complex<T> operator+=(const T &rhs) | |
159 | 159 | { |
160 | 160 | *this = *this + rhs; |
161 | 161 | return *this; |
162 | 162 | } |
163 | 163 | |
164 | - CUDA_CALLABLE rtsComplex<T> operator*=(const rtsComplex<T> &rhs) | |
164 | + CUDA_CALLABLE complex<T> operator*=(const complex<T> &rhs) | |
165 | 165 | { |
166 | 166 | *this = *this * rhs; |
167 | 167 | return *this; |
168 | 168 | } |
169 | - CUDA_CALLABLE rtsComplex<T> operator*=(const T &rhs) | |
169 | + CUDA_CALLABLE complex<T> operator*=(const T &rhs) | |
170 | 170 | { |
171 | 171 | *this = *this * rhs; |
172 | 172 | return *this; |
173 | 173 | } |
174 | 174 | //divide and assign |
175 | - CUDA_CALLABLE rtsComplex<T> operator/=(const rtsComplex<T> &rhs) | |
175 | + CUDA_CALLABLE complex<T> operator/=(const complex<T> &rhs) | |
176 | 176 | { |
177 | 177 | *this = *this / rhs; |
178 | 178 | return *this; |
179 | 179 | } |
180 | - CUDA_CALLABLE rtsComplex<T> operator/=(const T &rhs) | |
180 | + CUDA_CALLABLE complex<T> operator/=(const T &rhs) | |
181 | 181 | { |
182 | 182 | *this = *this / rhs; |
183 | 183 | return *this; |
... | ... | @@ -189,9 +189,9 @@ struct rtsComplex |
189 | 189 | return std::sqrt(r * r + i * i); |
190 | 190 | } |
191 | 191 | |
192 | - CUDA_CALLABLE rtsComplex<T> log() | |
192 | + CUDA_CALLABLE complex<T> log() | |
193 | 193 | { |
194 | - rtsComplex<T> result; | |
194 | + complex<T> result; | |
195 | 195 | result.r = std::log(std::sqrt(r * r + i * i)); |
196 | 196 | result.i = std::atan2(i, r); |
197 | 197 | |
... | ... | @@ -199,9 +199,9 @@ struct rtsComplex |
199 | 199 | return result; |
200 | 200 | } |
201 | 201 | |
202 | - CUDA_CALLABLE rtsComplex<T> exp() | |
202 | + CUDA_CALLABLE complex<T> exp() | |
203 | 203 | { |
204 | - rtsComplex<T> result; | |
204 | + complex<T> result; | |
205 | 205 | |
206 | 206 | T e_r = std::exp(r); |
207 | 207 | result.r = e_r * std::cos(i); |
... | ... | @@ -216,18 +216,18 @@ struct rtsComplex |
216 | 216 | return pow((double)y); |
217 | 217 | }*/ |
218 | 218 | |
219 | - CUDA_CALLABLE rtsComplex<T> pow(T y) | |
219 | + CUDA_CALLABLE complex<T> pow(T y) | |
220 | 220 | { |
221 | - rtsComplex<T> result; | |
221 | + complex<T> result; | |
222 | 222 | |
223 | 223 | result = log() * y; |
224 | 224 | |
225 | 225 | return result.exp(); |
226 | 226 | } |
227 | 227 | |
228 | - CUDA_CALLABLE rtsComplex<T> sqrt() | |
228 | + CUDA_CALLABLE complex<T> sqrt() | |
229 | 229 | { |
230 | - rtsComplex<T> result; | |
230 | + complex<T> result; | |
231 | 231 | |
232 | 232 | //convert to polar coordinates |
233 | 233 | T a = std::sqrt(r*r + i*i); |
... | ... | @@ -253,7 +253,7 @@ struct rtsComplex |
253 | 253 | } |
254 | 254 | |
255 | 255 | //COMPARISON operators |
256 | - CUDA_CALLABLE bool operator==(rtsComplex<T> rhs) | |
256 | + CUDA_CALLABLE bool operator==(complex<T> rhs) | |
257 | 257 | { |
258 | 258 | if(r == rhs.r && i == rhs.i) |
259 | 259 | return true; |
... | ... | @@ -267,72 +267,44 @@ struct rtsComplex |
267 | 267 | return false; |
268 | 268 | } |
269 | 269 | |
270 | - /*//FRIEND functions | |
271 | - //unary minus operator (for negating the complex number) | |
272 | - template<class A> CUDA_CALLABLE friend complex<A> operator-(const complex<A> &rhs); | |
273 | - | |
274 | - //multiplication by T values when the complex number isn't on the left hand side | |
275 | - template<class A> CUDA_CALLABLE friend complex<A> operator*(const A a, const complex<A> b); | |
276 | - | |
277 | - //division by T values when the complex number isn't on the left hand side | |
278 | - template<class A> CUDA_CALLABLE friend complex<A> operator/(const A a, const complex<A> b); | |
279 | - | |
280 | - //POW function | |
281 | - //template<class A> CUDA_CALLABLE friend complex<A> pow(const complex<A> x, T y); | |
282 | - template<class A> CUDA_CALLABLE friend complex<A> pow(const complex<A> x, int y); | |
283 | - | |
284 | - //log function | |
285 | - template<class A> CUDA_CALLABLE friend complex<A> log(complex<A> x); | |
286 | - | |
287 | - //exp function | |
288 | - template<class A> CUDA_CALLABLE friend complex<A> exp(complex<A> x); | |
289 | - | |
290 | - //sqrt function | |
291 | - template<class A> CUDA_CALLABLE friend complex<A> sqrt(complex<A> x); | |
292 | - | |
293 | - //trigonometric functions | |
294 | - template<class A> CUDA_CALLABLE friend complex<A> sin(complex<A> x); | |
295 | - | |
296 | - template<class A> CUDA_CALLABLE friend complex<A> cos(complex<A> x);*/ | |
297 | - | |
298 | 270 | }; |
299 | 271 | |
300 | 272 | } //end RTS namespace |
301 | 273 | |
302 | 274 | //addition |
303 | 275 | template<typename T> |
304 | -CUDA_CALLABLE static rts::rtsComplex<T> operator+(const double a, const rts::rtsComplex<T> b) | |
276 | +CUDA_CALLABLE static rts::complex<T> operator+(const double a, const rts::complex<T> b) | |
305 | 277 | { |
306 | - return rts::rtsComplex<T>(a + b.r, b.i); | |
278 | + return rts::complex<T>(a + b.r, b.i); | |
307 | 279 | } |
308 | 280 | |
309 | 281 | //subtraction with a real value |
310 | 282 | template<typename T> |
311 | -CUDA_CALLABLE static rts::rtsComplex<T> operator-(const double a, const rts::rtsComplex<T> b) | |
283 | +CUDA_CALLABLE static rts::complex<T> operator-(const double a, const rts::complex<T> b) | |
312 | 284 | { |
313 | - return rts::rtsComplex<T>(a - b.r, -b.i); | |
285 | + return rts::complex<T>(a - b.r, -b.i); | |
314 | 286 | } |
315 | 287 | |
316 | 288 | //minus sign |
317 | 289 | template<typename T> |
318 | -CUDA_CALLABLE static rts::rtsComplex<T> operator-(const rts::rtsComplex<T> &rhs) | |
290 | +CUDA_CALLABLE static rts::complex<T> operator-(const rts::complex<T> &rhs) | |
319 | 291 | { |
320 | - return rts::rtsComplex<T>(-rhs.r, -rhs.i); | |
292 | + return rts::complex<T>(-rhs.r, -rhs.i); | |
321 | 293 | } |
322 | 294 | |
323 | 295 | //multiply a T value by a complex value |
324 | 296 | template<typename T> |
325 | -CUDA_CALLABLE static rts::rtsComplex<T> operator*(const double a, const rts::rtsComplex<T> b) | |
297 | +CUDA_CALLABLE static rts::complex<T> operator*(const double a, const rts::complex<T> b) | |
326 | 298 | { |
327 | - return rts::rtsComplex<T>(a * b.r, a * b.i); | |
299 | + return rts::complex<T>((T)a * b.r, (T)a * b.i); | |
328 | 300 | } |
329 | 301 | |
330 | 302 | //divide a T value by a complex value |
331 | 303 | template<typename T> |
332 | -CUDA_CALLABLE static rts::rtsComplex<T> operator/(const double a, const rts::rtsComplex<T> b) | |
304 | +CUDA_CALLABLE static rts::complex<T> operator/(const double a, const rts::complex<T> b) | |
333 | 305 | { |
334 | 306 | //return complex<T>(a * b.r, a * b.i); |
335 | - rts::rtsComplex<T> result; | |
307 | + rts::complex<T> result; | |
336 | 308 | |
337 | 309 | T denom = b.r * b.r + b.i * b.i; |
338 | 310 | |
... | ... | @@ -350,41 +322,41 @@ CUDA_CALLABLE static complex<T> pow(complex<T> x, int y) |
350 | 322 | }*/ |
351 | 323 | |
352 | 324 | template<typename T> |
353 | -CUDA_CALLABLE static rts::rtsComplex<T> pow(rts::rtsComplex<T> x, T y) | |
325 | +CUDA_CALLABLE static rts::complex<T> pow(rts::complex<T> x, T y) | |
354 | 326 | { |
355 | 327 | return x.pow(y); |
356 | 328 | } |
357 | 329 | |
358 | 330 | //log function |
359 | 331 | template<typename T> |
360 | -CUDA_CALLABLE static rts::rtsComplex<T> log(rts::rtsComplex<T> x) | |
332 | +CUDA_CALLABLE static rts::complex<T> log(rts::complex<T> x) | |
361 | 333 | { |
362 | 334 | return x.log(); |
363 | 335 | } |
364 | 336 | |
365 | 337 | //exp function |
366 | 338 | template<typename T> |
367 | -CUDA_CALLABLE static rts::rtsComplex<T> exp(rts::rtsComplex<T> x) | |
339 | +CUDA_CALLABLE static rts::complex<T> exp(rts::complex<T> x) | |
368 | 340 | { |
369 | 341 | return x.exp(); |
370 | 342 | } |
371 | 343 | |
372 | 344 | //sqrt function |
373 | 345 | template<typename T> |
374 | -CUDA_CALLABLE static rts::rtsComplex<T> sqrt(rts::rtsComplex<T> x) | |
346 | +CUDA_CALLABLE static rts::complex<T> sqrt(rts::complex<T> x) | |
375 | 347 | { |
376 | 348 | return x.sqrt(); |
377 | 349 | } |
378 | 350 | |
379 | 351 | |
380 | 352 | template <typename T> |
381 | -CUDA_CALLABLE static T abs(rts::rtsComplex<T> a) | |
353 | +CUDA_CALLABLE static T abs(rts::complex<T> a) | |
382 | 354 | { |
383 | 355 | return a.abs(); |
384 | 356 | } |
385 | 357 | |
386 | 358 | template <typename T> |
387 | -CUDA_CALLABLE static T real(rts::rtsComplex<T> a) | |
359 | +CUDA_CALLABLE static T real(rts::complex<T> a) | |
388 | 360 | { |
389 | 361 | return a.r; |
390 | 362 | } |
... | ... | @@ -396,16 +368,16 @@ CUDA_CALLABLE static float real(float a) |
396 | 368 | } |
397 | 369 | |
398 | 370 | template <typename T> |
399 | -CUDA_CALLABLE static T imag(rts::rtsComplex<T> a) | |
371 | +CUDA_CALLABLE static T imag(rts::complex<T> a) | |
400 | 372 | { |
401 | 373 | return a.i; |
402 | 374 | } |
403 | 375 | |
404 | 376 | //trigonometric functions |
405 | 377 | template<class A> |
406 | -CUDA_CALLABLE rts::rtsComplex<A> sin(const rts::rtsComplex<A> x) | |
378 | +CUDA_CALLABLE rts::complex<A> sin(const rts::complex<A> x) | |
407 | 379 | { |
408 | - rts::rtsComplex<A> result; | |
380 | + rts::complex<A> result; | |
409 | 381 | result.r = std::sin(x.r) * std::cosh(x.i); |
410 | 382 | result.i = std::cos(x.r) * std::sinh(x.i); |
411 | 383 | |
... | ... | @@ -413,9 +385,9 @@ CUDA_CALLABLE rts::rtsComplex<A> sin(const rts::rtsComplex<A> x) |
413 | 385 | } |
414 | 386 | |
415 | 387 | template<class A> |
416 | -CUDA_CALLABLE rts::rtsComplex<A> cos(const rts::rtsComplex<A> x) | |
388 | +CUDA_CALLABLE rts::complex<A> cos(const rts::complex<A> x) | |
417 | 389 | { |
418 | - rts::rtsComplex<A> result; | |
390 | + rts::complex<A> result; | |
419 | 391 | result.r = std::cos(x.r) * std::cosh(x.i); |
420 | 392 | result.i = -(std::sin(x.r) * std::sinh(x.i)); |
421 | 393 | |
... | ... | @@ -424,12 +396,16 @@ CUDA_CALLABLE rts::rtsComplex<A> cos(const rts::rtsComplex<A> x) |
424 | 396 | |
425 | 397 | |
426 | 398 | template<class A> |
427 | -std::ostream& operator<<(std::ostream& os, rts::rtsComplex<A> x) | |
399 | +std::ostream& operator<<(std::ostream& os, rts::complex<A> x) | |
428 | 400 | { |
429 | 401 | os<<x.toStr(); |
430 | 402 | return os; |
431 | 403 | } |
432 | 404 | |
405 | +#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 | |
406 | +template<class T> using rtsComplex = rts::complex<T>; | |
407 | +#endif | |
408 | + | |
433 | 409 | |
434 | 410 | |
435 | 411 | #endif | ... | ... |
1 | +#ifndef RTS_FUNCTION_H | |
2 | +#define RTS_FUNCTION_H | |
3 | + | |
4 | +#include <string> | |
5 | + | |
6 | +namespace rts{ | |
7 | + | |
8 | +template <class X, class Y> | |
9 | +class function | |
10 | +{ | |
11 | + //datapoint class for storing function points | |
12 | + struct dataPoint | |
13 | + { | |
14 | + X x; | |
15 | + Y y; | |
16 | + }; | |
17 | + | |
18 | + //function data | |
19 | + std::vector<dataPoint> f; | |
20 | + | |
21 | + //comparison function for searching lambda | |
22 | + static bool findCeiling(dataPoint a, dataPoint b) | |
23 | + { | |
24 | + return (a.x > b.x); | |
25 | + } | |
26 | + | |
27 | + | |
28 | +public: | |
29 | + Y linear(X x) | |
30 | + { | |
31 | + //declare an iterator | |
32 | + typename std::vector< dataPoint >::iterator it; | |
33 | + | |
34 | + dataPoint s; | |
35 | + s.x = x; | |
36 | + | |
37 | + it = search(f.begin(), f.end(), &s, &s + 1, &function<X, Y>::findCeiling); | |
38 | + | |
39 | + //if the wavelength is past the end of the list, return the back | |
40 | + if(it == f.end()) | |
41 | + return f.back().y; | |
42 | + //if the wavelength is before the beginning of the list, return the front | |
43 | + else if(it == f.begin()) | |
44 | + return f.front().y; | |
45 | + //otherwise interpolate | |
46 | + else | |
47 | + { | |
48 | + X xMax = (*it).x; | |
49 | + X xMin = (*(it - 1)).x; | |
50 | + //std::cout<<lMin<<"----------"<<lMax<<std::endl; | |
51 | + | |
52 | + X a = (x - xMin) / (xMax - xMin); | |
53 | + Y riMin = (*(it - 1)).y; | |
54 | + Y riMax = (*it).y; | |
55 | + Y interp; | |
56 | + interp = riMin * a + riMax * (1.0 - a); | |
57 | + return interp; | |
58 | + } | |
59 | + } | |
60 | + | |
61 | + void insert(X x, Y y) | |
62 | + { | |
63 | + //declare an iterator | |
64 | + typename std::vector< dataPoint >::iterator it; | |
65 | + | |
66 | + dataPoint s; | |
67 | + s.x = x; | |
68 | + s.y = y; | |
69 | + | |
70 | + it = search(f.begin(), f.end(), &s, &s + 1, &function<X, Y>::findCeiling); | |
71 | + | |
72 | + //if the function value is past the end of the vector, add it to the back | |
73 | + if(it == f.end()) | |
74 | + return f.push_back(s); | |
75 | + //otherwise add the value at the iterator position | |
76 | + else | |
77 | + { | |
78 | + f.insert(it, s); | |
79 | + } | |
80 | + | |
81 | + } | |
82 | + | |
83 | + X getX(unsigned int i) | |
84 | + { | |
85 | + return f[i].x; | |
86 | + } | |
87 | + | |
88 | + Y getY(unsigned int i) | |
89 | + { | |
90 | + return f[i].y; | |
91 | + } | |
92 | + | |
93 | + unsigned int getN() | |
94 | + { | |
95 | + return f.size(); | |
96 | + } | |
97 | + | |
98 | + dataPoint operator[](int i) | |
99 | + { | |
100 | + return f[i]; | |
101 | + } | |
102 | + | |
103 | + function<X, Y> operator+(Y r) | |
104 | + { | |
105 | + function<X, Y> result; | |
106 | + | |
107 | + //add r to every point in f | |
108 | + for(int i=0; i<f.size(); i++) | |
109 | + { | |
110 | + result.f.push_back(f[i]); | |
111 | + result.f[i].y += r; | |
112 | + } | |
113 | + | |
114 | + return result; | |
115 | + } | |
116 | + | |
117 | + | |
118 | +}; | |
119 | + | |
120 | +} //end namespace rts | |
121 | + | |
122 | + | |
123 | +#endif | ... | ... |
rts/math/matrix.h
... | ... | @@ -9,12 +9,12 @@ namespace rts |
9 | 9 | { |
10 | 10 | |
11 | 11 | template <class T, int N> |
12 | -struct rtsMatrix | |
12 | +struct matrix | |
13 | 13 | { |
14 | 14 | //the matrix will be stored in column-major order (compatible with OpenGL) |
15 | 15 | T M[N*N]; |
16 | 16 | |
17 | - rtsMatrix() | |
17 | + matrix() | |
18 | 18 | { |
19 | 19 | for(int r=0; r<N; r++) |
20 | 20 | for(int c=0; c<N; c++) |
... | ... | @@ -29,7 +29,7 @@ struct rtsMatrix |
29 | 29 | return M[col * N + row]; |
30 | 30 | } |
31 | 31 | |
32 | - rtsMatrix<T, N> operator=(T rhs) | |
32 | + matrix<T, N> operator=(T rhs) | |
33 | 33 | { |
34 | 34 | int Nsq = N*N; |
35 | 35 | for(int i=0; i<Nsq; i++) |
... | ... | @@ -38,7 +38,7 @@ struct rtsMatrix |
38 | 38 | return *this; |
39 | 39 | } |
40 | 40 | |
41 | - /*rtsMatrix<T, N> operator=(rtsMatrix<T, N> rhs) | |
41 | + /*matrix<T, N> operator=(matrix<T, N> rhs) | |
42 | 42 | { |
43 | 43 | for(int i=0; i<N; i++) |
44 | 44 | M[i] = rhs.M[i]; |
... | ... | @@ -46,9 +46,9 @@ struct rtsMatrix |
46 | 46 | return *this; |
47 | 47 | }*/ |
48 | 48 | |
49 | - rtsVector<T, N> operator*(rtsVector<T, N> rhs) | |
49 | + vector<T, N> operator*(vector<T, N> rhs) | |
50 | 50 | { |
51 | - rtsVector<T, N> result; | |
51 | + vector<T, N> result; | |
52 | 52 | |
53 | 53 | for(int r=0; r<N; r++) |
54 | 54 | for(int c=0; c<N; c++) |
... | ... | @@ -82,10 +82,14 @@ struct rtsMatrix |
82 | 82 | } //end namespace rts |
83 | 83 | |
84 | 84 | template <typename T, int N> |
85 | -std::ostream& operator<<(std::ostream& os, rts::rtsMatrix<T, N> M) | |
85 | +std::ostream& operator<<(std::ostream& os, rts::matrix<T, N> M) | |
86 | 86 | { |
87 | 87 | os<<M.toStr(); |
88 | 88 | return os; |
89 | 89 | } |
90 | 90 | |
91 | +#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 | |
92 | +template<class T, int N> using rtsMatrix = rts::matrix<T, N>; | |
93 | +#endif | |
94 | + | |
91 | 95 | #endif | ... | ... |
rts/math/point.h
1 | 1 | #ifndef RTS_rtsPoint_H |
2 | 2 | #define RTS_rtsPoint_H |
3 | 3 | |
4 | -#include "rts/math/vector.h" | |
4 | +#include "rts/math/vector.h" | |
5 | 5 | #include <string.h> |
6 | 6 | #include "rts/cuda/callable.h" |
7 | 7 | |
... | ... | @@ -9,17 +9,17 @@ namespace rts |
9 | 9 | { |
10 | 10 | |
11 | 11 | template <class T, int N> |
12 | -struct rtsPoint | |
12 | +struct point | |
13 | 13 | { |
14 | 14 | T p[N]; |
15 | 15 | |
16 | - CUDA_CALLABLE rtsPoint() | |
17 | - { | |
16 | + CUDA_CALLABLE point() | |
17 | + { | |
18 | 18 | |
19 | 19 | } |
20 | 20 | |
21 | 21 | //efficiency constructor, makes construction easier for 1D-4D vectors |
22 | - CUDA_CALLABLE rtsPoint(T x, T y = (T)0.0, T z = (T)0.0, T w = (T)0.0) | |
22 | + CUDA_CALLABLE point(T x, T y = (T)0.0, T z = (T)0.0, T w = (T)0.0) | |
23 | 23 | { |
24 | 24 | if(N >= 1) |
25 | 25 | p[0] = x; |
... | ... | @@ -29,51 +29,51 @@ struct rtsPoint |
29 | 29 | p[2] = z; |
30 | 30 | if(N >= 4) |
31 | 31 | p[3] = w; |
32 | - } | |
33 | - | |
34 | - //arithmetic operators | |
35 | - CUDA_CALLABLE rts::rtsPoint<T, N> operator+(rts::rtsVector<T, N> v) | |
36 | - { | |
37 | - rts::rtsPoint<T, N> r; | |
38 | - | |
39 | - //calculate the position of the resulting rtsPoint | |
40 | - for(int i=0; i<N; i++) | |
41 | - r.p[i] = p[i] + v.v[i]; | |
42 | - | |
43 | - return r; | |
44 | - } | |
45 | - CUDA_CALLABLE rts::rtsPoint<T, N> operator-(rts::rtsVector<T, N> v) | |
46 | - { | |
47 | - rts::rtsPoint<T, N> r; | |
48 | - | |
49 | - //calculate the position of the resulting rtsPoint | |
50 | - for(int i=0; i<N; i++) | |
51 | - r.p[i] = p[i] - v.v[i]; | |
52 | - | |
53 | - return r; | |
54 | - } | |
55 | - CUDA_CALLABLE rts::rtsVector<T, N> operator-(rts::rtsPoint<T, N> rhs) | |
56 | - { | |
57 | - rts::rtsVector<T, N> r; | |
58 | - | |
59 | - //calculate the position of the resulting rtsPoint | |
60 | - for(int i=0; i<N; i++) | |
61 | - r.v[i] = p[i] - rhs.p[i]; | |
62 | - | |
63 | - return r; | |
64 | - } | |
65 | - CUDA_CALLABLE rts::rtsPoint<T, N> operator*(T rhs) | |
66 | - { | |
67 | - rts::rtsPoint<T, N> r; | |
68 | - | |
69 | - //calculate the position of the resulting rtsPoint | |
70 | - for(int i=0; i<N; i++) | |
71 | - r.p[i] = p[i] * rhs; | |
72 | - | |
73 | - return r; | |
74 | 32 | } |
75 | 33 | |
76 | - CUDA_CALLABLE rtsPoint(const T(&data)[N]) | |
34 | + //arithmetic operators | |
35 | + CUDA_CALLABLE rts::point<T, N> operator+(vector<T, N> v) | |
36 | + { | |
37 | + rts::point<T, N> r; | |
38 | + | |
39 | + //calculate the position of the resulting point | |
40 | + for(int i=0; i<N; i++) | |
41 | + r.p[i] = p[i] + v.v[i]; | |
42 | + | |
43 | + return r; | |
44 | + } | |
45 | + CUDA_CALLABLE rts::point<T, N> operator-(vector<T, N> v) | |
46 | + { | |
47 | + rts::point<T, N> r; | |
48 | + | |
49 | + //calculate the position of the resulting point | |
50 | + for(int i=0; i<N; i++) | |
51 | + r.p[i] = p[i] - v.v[i]; | |
52 | + | |
53 | + return r; | |
54 | + } | |
55 | + CUDA_CALLABLE vector<T, N> operator-(point<T, N> rhs) | |
56 | + { | |
57 | + vector<T, N> r; | |
58 | + | |
59 | + //calculate the position of the resulting point | |
60 | + for(int i=0; i<N; i++) | |
61 | + r.v[i] = p[i] - rhs.p[i]; | |
62 | + | |
63 | + return r; | |
64 | + } | |
65 | + CUDA_CALLABLE rts::point<T, N> operator*(T rhs) | |
66 | + { | |
67 | + rts::point<T, N> r; | |
68 | + | |
69 | + //calculate the position of the resulting point | |
70 | + for(int i=0; i<N; i++) | |
71 | + r.p[i] = p[i] * rhs; | |
72 | + | |
73 | + return r; | |
74 | + } | |
75 | + | |
76 | + CUDA_CALLABLE point(const T(&data)[N]) | |
77 | 77 | { |
78 | 78 | memcpy(p, data, sizeof(T) * N); |
79 | 79 | } |
... | ... | @@ -92,34 +92,36 @@ struct rtsPoint |
92 | 92 | ss<<")"; |
93 | 93 | |
94 | 94 | return ss.str(); |
95 | - } | |
96 | - | |
97 | - //bracket operator | |
98 | - CUDA_CALLABLE T& operator[](int i) | |
95 | + } | |
96 | + | |
97 | + //bracket operator | |
98 | + CUDA_CALLABLE T& operator[](int i) | |
99 | 99 | { |
100 | - return p[i]; | |
100 | + return p[i]; | |
101 | 101 | } |
102 | 102 | |
103 | -}; | |
104 | - | |
105 | -} //end namespace rts | |
106 | - | |
107 | -template <typename T, int N> | |
108 | -std::ostream& operator<<(std::ostream& os, rts::rtsPoint<T, N> p) | |
109 | -{ | |
110 | - os<<p.toStr(); | |
111 | - return os; | |
112 | -} | |
113 | - | |
114 | -//arithmetic | |
115 | -template <typename T, int N> | |
116 | -CUDA_CALLABLE rts::rtsPoint<T, N> operator*(T lhs, rts::rtsPoint<T, N> rhs) | |
117 | -{ | |
118 | - rts::rtsPoint<T, N> r; | |
119 | - | |
120 | - return rhs * lhs; | |
121 | -} | |
122 | - | |
123 | - | |
124 | - | |
125 | -#endif | |
103 | +}; | |
104 | + | |
105 | +} //end namespace rts | |
106 | + | |
107 | +template <typename T, int N> | |
108 | +std::ostream& operator<<(std::ostream& os, rts::point<T, N> p) | |
109 | +{ | |
110 | + os<<p.toStr(); | |
111 | + return os; | |
112 | +} | |
113 | + | |
114 | +//arithmetic | |
115 | +template <typename T, int N> | |
116 | +CUDA_CALLABLE rts::point<T, N> operator*(T lhs, rts::point<T, N> rhs) | |
117 | +{ | |
118 | + rts::point<T, N> r; | |
119 | + | |
120 | + return rhs * lhs; | |
121 | +} | |
122 | + | |
123 | +#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 | |
124 | +template<class T, int N> using rtsPoint = rts::point<T, N>; | |
125 | +#endif | |
126 | + | |
127 | +#endif | ... | ... |
rts/math/quad.h
... | ... | @@ -6,13 +6,14 @@ |
6 | 6 | #include "rts/math/vector.h" |
7 | 7 | #include "rts/math/point.h" |
8 | 8 | #include "rts/math/triangle.h" |
9 | +#include "rts/math/quaternion.h" | |
9 | 10 | #include <iostream> |
10 | 11 | |
11 | 12 | namespace rts{ |
12 | 13 | |
13 | -//template for a rtsQuadangle class in ND space | |
14 | +//template for a quadangle class in ND space | |
14 | 15 | template <class T, int N> |
15 | -struct rtsQuad | |
16 | +struct quad | |
16 | 17 | { |
17 | 18 | /* |
18 | 19 | C------------------>O |
... | ... | @@ -28,17 +29,17 @@ struct rtsQuad |
28 | 29 | T B[N]; |
29 | 30 | T C[N];*/ |
30 | 31 | |
31 | - rts::rtsPoint<T, N> A; | |
32 | - rts::rtsVector<T, N> X; | |
33 | - rts::rtsVector<T, N> Y; | |
32 | + rts::point<T, N> A; | |
33 | + rts::vector<T, N> X; | |
34 | + rts::vector<T, N> Y; | |
34 | 35 | |
35 | 36 | |
36 | - CUDA_CALLABLE rtsQuad() | |
37 | + CUDA_CALLABLE quad() | |
37 | 38 | { |
38 | 39 | |
39 | 40 | } |
40 | 41 | |
41 | - CUDA_CALLABLE rtsQuad(rtsPoint<T, N> a, rtsPoint<T, N> b, rtsPoint<T, N> c) | |
42 | + CUDA_CALLABLE quad(point<T, N> a, point<T, N> b, point<T, N> c) | |
42 | 43 | { |
43 | 44 | |
44 | 45 | A = a; |
... | ... | @@ -47,48 +48,90 @@ struct rtsQuad |
47 | 48 | |
48 | 49 | } |
49 | 50 | |
50 | - CUDA_CALLABLE rtsQuad(rts::rtsPoint<T, N> pMin, rts::rtsPoint<T, N> pMax, rts::rtsVector<T, N> normal) | |
51 | + /**************************************************************** | |
52 | + Constructor - create a quad from two points and a normal | |
53 | + ****************************************************************/ | |
54 | + CUDA_CALLABLE quad(rts::point<T, N> pMin, rts::point<T, N> pMax, rts::vector<T, N> normal) | |
51 | 55 | { |
52 | 56 | |
53 | - //assign the corner rtsPoint | |
57 | + //assign the corner point | |
54 | 58 | A = pMin; |
55 | 59 | |
56 | 60 | //compute the vector from pMin to pMax |
57 | - rts::rtsVector<T, 3> v0; | |
61 | + rts::vector<T, 3> v0; | |
58 | 62 | v0 = pMax - pMin; |
59 | 63 | |
60 | 64 | //compute the cross product of A and the plane normal |
61 | - rts::rtsVector<T, 3> v1; | |
65 | + rts::vector<T, 3> v1; | |
62 | 66 | v1 = v0.cross(normal); |
63 | 67 | |
64 | 68 | |
65 | - //calculate rtsPoint B | |
66 | - rts::rtsPoint<T, 3> B; | |
69 | + //calculate point B | |
70 | + rts::point<T, 3> B; | |
67 | 71 | B = A + v0 * 0.5 + v1 * 0.5; |
68 | 72 | |
69 | 73 | //calculate rtsPoint C |
70 | - rts::rtsPoint<T, 3> C; | |
74 | + rts::point<T, 3> C; | |
71 | 75 | C = A + v0 * 0.5 - v1 * 0.5; |
72 | 76 | |
73 | 77 | //calculate X and Y |
74 | 78 | X = B - A; |
75 | 79 | Y = C - A; |
80 | + } | |
81 | + | |
82 | + /******************************************************************* | |
83 | + Constructor - create a quad from a position, normal, and rotation | |
84 | + *******************************************************************/ | |
85 | + CUDA_CALLABLE quad(rts::point<T, N> c, rts::vector<T, N> normal, T width, T height, T theta) | |
86 | + { | |
87 | + | |
88 | + //compute the X direction - start along world-space X | |
89 | + Y = rts::vector<T, N>(0, 1, 0); | |
90 | + if(Y == normal) | |
91 | + Y = rts::vector<T, N>(0, 0, 1); | |
92 | + | |
93 | + X = Y.cross(normal).norm(); | |
94 | + | |
95 | + std::cout<<X<<std::endl; | |
96 | + | |
97 | + //rotate the X axis by theta radians | |
98 | + rts::quaternion<T> q; | |
99 | + q.CreateRotation(theta, normal); | |
100 | + X = q.toMatrix3() * X; | |
101 | + Y = normal.cross(X); | |
76 | 102 | |
103 | + //normalize everything | |
104 | + X = X.norm(); | |
105 | + Y = Y.norm(); | |
77 | 106 | |
107 | + //scale to match the quad width and height | |
108 | + X = X * width; | |
109 | + Y = Y * height; | |
78 | 110 | |
111 | + //set the corner of the plane | |
112 | + A = c - X * 0.5 - Y * 0.5; | |
79 | 113 | |
114 | + std::cout<<X<<std::endl; | |
80 | 115 | } |
81 | 116 | |
82 | - CUDA_CALLABLE rts::rtsPoint<T, N> p(T a, T b) | |
117 | + /******************************************* | |
118 | + Return the normal for the quad | |
119 | + *******************************************/ | |
120 | + CUDA_CALLABLE rts::vector<T, N> n() | |
83 | 121 | { |
84 | - rts::rtsPoint<T, N> result; | |
122 | + return (X.cross(Y)).norm(); | |
123 | + } | |
124 | + | |
125 | + CUDA_CALLABLE rts::point<T, N> p(T a, T b) | |
126 | + { | |
127 | + rts::point<T, N> result; | |
85 | 128 | //given the two parameters a, b = [0 1], returns the position in world space |
86 | 129 | result = A + X * a + Y * b; |
87 | 130 | |
88 | 131 | return result; |
89 | 132 | } |
90 | 133 | |
91 | - CUDA_CALLABLE rts::rtsPoint<T, N> operator()(T a, T b) | |
134 | + CUDA_CALLABLE rts::point<T, N> operator()(T a, T b) | |
92 | 135 | { |
93 | 136 | return p(a, b); |
94 | 137 | } |
... | ... | @@ -106,15 +149,15 @@ struct rtsQuad |
106 | 149 | |
107 | 150 | } |
108 | 151 | |
109 | - CUDA_CALLABLE rtsQuad<T, N> operator*(T rhs) | |
152 | + CUDA_CALLABLE quad<T, N> operator*(T rhs) | |
110 | 153 | { |
111 | 154 | //scales the plane by a scalar value |
112 | 155 | |
113 | - //compute the center rtsPoint | |
114 | - rts::rtsPoint<T, N> c = A + X*0.5 + Y*0.5; | |
156 | + //compute the center point | |
157 | + rts::point<T, N> c = A + X*0.5 + Y*0.5; | |
115 | 158 | |
116 | - //create the new rtsQuadangle | |
117 | - rtsQuad<T, N> result; | |
159 | + //create the new quadangle | |
160 | + quad<T, N> result; | |
118 | 161 | result.X = X * rhs; |
119 | 162 | result.Y = Y * rhs; |
120 | 163 | result.A = c - result.X*0.5 - result.Y*0.5; |
... | ... | @@ -123,13 +166,13 @@ struct rtsQuad |
123 | 166 | |
124 | 167 | } |
125 | 168 | |
126 | - CUDA_CALLABLE T dist(rtsPoint<T, N> p) | |
169 | + CUDA_CALLABLE T dist(point<T, N> p) | |
127 | 170 | { |
128 | 171 | //compute the distance between a point and this quad |
129 | 172 | |
130 | 173 | //first break the quad up into two triangles |
131 | - rtsTriangle<T, N> T0(A, A+X, A+Y); | |
132 | - rtsTriangle<T, N> T1(A+X+Y, A+X, A+Y); | |
174 | + triangle<T, N> T0(A, A+X, A+Y); | |
175 | + triangle<T, N> T1(A+X+Y, A+X, A+Y); | |
133 | 176 | |
134 | 177 | |
135 | 178 | ptype d0 = T0.dist(p); |
... | ... | @@ -140,12 +183,22 @@ struct rtsQuad |
140 | 183 | else |
141 | 184 | return d1; |
142 | 185 | } |
186 | + | |
187 | + CUDA_CALLABLE T dist_max(point<T, N> p) | |
188 | + { | |
189 | + T da = (A - p).len(); | |
190 | + T db = (A+X - p).len(); | |
191 | + T dc = (A+Y - p).len(); | |
192 | + T dd = (A+X+Y - p).len(); | |
193 | + | |
194 | + return max( da, max(db, max(dc, dd) ) ); | |
195 | + } | |
143 | 196 | }; |
144 | 197 | |
145 | 198 | } //end namespace rts |
146 | 199 | |
147 | 200 | template <typename T, int N> |
148 | -std::ostream& operator<<(std::ostream& os, rts::rtsQuad<T, N> R) | |
201 | +std::ostream& operator<<(std::ostream& os, rts::quad<T, N> R) | |
149 | 202 | { |
150 | 203 | os<<R.toStr(); |
151 | 204 | return os; | ... | ... |
rts/math/quaternion.h
... | ... | @@ -6,7 +6,7 @@ |
6 | 6 | namespace rts{ |
7 | 7 | |
8 | 8 | template<typename T> |
9 | -class rtsQuaternion | |
9 | +class quaternion | |
10 | 10 | { |
11 | 11 | public: |
12 | 12 | T w; |
... | ... | @@ -16,18 +16,19 @@ public: |
16 | 16 | |
17 | 17 | void normalize(); |
18 | 18 | void CreateRotation(T theta, T axis_x, T axis_y, T axis_z); |
19 | - void CreateRotation(T theta, rtsVector<T, 3> axis); | |
20 | - rtsQuaternion<T> operator*(rtsQuaternion<T> &rhs); | |
21 | - rtsMatrix<T, 3> toMatrix(); | |
19 | + void CreateRotation(T theta, vector<T, 3> axis); | |
20 | + quaternion<T> operator*(quaternion<T> &rhs); | |
21 | + matrix<T, 3> toMatrix3(); | |
22 | + matrix<T, 4> toMatrix4(); | |
22 | 23 | |
23 | 24 | |
24 | - rtsQuaternion(); | |
25 | - rtsQuaternion(T w, T x, T y, T z); | |
25 | + quaternion(); | |
26 | + quaternion(T w, T x, T y, T z); | |
26 | 27 | |
27 | 28 | }; |
28 | 29 | |
29 | 30 | template<typename T> |
30 | -void rtsQuaternion<T>::normalize() | |
31 | +void quaternion<T>::normalize() | |
31 | 32 | { |
32 | 33 | double length=sqrt(w*w + x*x + y*y + z*z); |
33 | 34 | w=w/length; |
... | ... | @@ -37,23 +38,23 @@ void rtsQuaternion<T>::normalize() |
37 | 38 | } |
38 | 39 | |
39 | 40 | template<typename T> |
40 | -void rtsQuaternion<T>::CreateRotation(T theta, T axis_x, T axis_y, T axis_z) | |
41 | +void quaternion<T>::CreateRotation(T theta, T axis_x, T axis_y, T axis_z) | |
41 | 42 | { |
42 | 43 | //assign the given Euler rotation to this quaternion |
43 | - w = cos(theta/2.0); | |
44 | - x = axis_x*sin(theta/2.0); | |
45 | - y = axis_y*sin(theta/2.0); | |
46 | - z = axis_z*sin(theta/2.0); | |
44 | + w = (T)cos(theta/2.0); | |
45 | + x = axis_x*(T)sin(theta/2.0); | |
46 | + y = axis_y*(T)sin(theta/2.0); | |
47 | + z = axis_z*(T)sin(theta/2.0); | |
47 | 48 | } |
48 | 49 | |
49 | 50 | template<typename T> |
50 | -void rtsQuaternion<T>::CreateRotation(T theta, rtsVector<T, 3> axis) | |
51 | +void quaternion<T>::CreateRotation(T theta, vector<T, 3> axis) | |
51 | 52 | { |
52 | 53 | CreateRotation(theta, axis[0], axis[1], axis[2]); |
53 | 54 | } |
54 | 55 | |
55 | 56 | template<typename T> |
56 | -rtsQuaternion<T> rtsQuaternion<T>::operator *(rtsQuaternion<T> ¶m) | |
57 | +quaternion<T> quaternion<T>::operator *(quaternion<T> ¶m) | |
57 | 58 | { |
58 | 59 | float A, B, C, D, E, F, G, H; |
59 | 60 | |
... | ... | @@ -67,7 +68,7 @@ rtsQuaternion<T> rtsQuaternion<T>::operator *(rtsQuaternion<T> &param) |
67 | 68 | G = (w + y)*(param.w - param.z); |
68 | 69 | H = (w - y)*(param.w + param.z); |
69 | 70 | |
70 | - rtsQuaternion<T> result; | |
71 | + quaternion<T> result; | |
71 | 72 | result.w = B + (-E - F + G + H) /2; |
72 | 73 | result.x = A - (E + F + G + H)/2; |
73 | 74 | result.y = C + (E - F + G - H)/2; |
... | ... | @@ -77,12 +78,12 @@ rtsQuaternion<T> rtsQuaternion<T>::operator *(rtsQuaternion<T> &param) |
77 | 78 | } |
78 | 79 | |
79 | 80 | template<typename T> |
80 | -rtsMatrix<T, 3> rtsQuaternion<T>::toMatrix() | |
81 | +matrix<T, 3> quaternion<T>::toMatrix3() | |
81 | 82 | { |
82 | - rtsMatrix<T, 3> result; | |
83 | + matrix<T, 3> result; | |
83 | 84 | |
84 | 85 | |
85 | - double wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; | |
86 | + T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; | |
86 | 87 | |
87 | 88 | |
88 | 89 | // calculate coefficients |
... | ... | @@ -92,62 +93,76 @@ rtsMatrix<T, 3> rtsQuaternion<T>::toMatrix() |
92 | 93 | yy = y * y2; yz = y * z2; zz = z * z2; |
93 | 94 | wx = w * x2; wy = w * y2; wz = w * z2; |
94 | 95 | |
95 | - result(0, 0) = 1.0 - (yy + zz); | |
96 | + result(0, 0) = (T)1.0 - (yy + zz); | |
96 | 97 | result(0, 1) = xy - wz; |
97 | - //m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz; | |
98 | 98 | |
99 | 99 | result(0, 2) = xz + wy; |
100 | - //result(0, 3) = 0.0; | |
101 | - //m[2][0] = xz + wy; m[3][0] = 0.0; | |
102 | 100 | |
103 | 101 | result(1, 0) = xy + wz; |
104 | - result(1, 1) = 1.0 - (xx + zz); | |
105 | - //m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz); | |
102 | + result(1, 1) = (T)1.0 - (xx + zz); | |
106 | 103 | |
107 | 104 | result(1, 2) = yz - wx; |
108 | - //result(1, 3) = 0.0; | |
109 | - //m[2][1] = yz - wx; m[3][1] = 0.0; | |
110 | 105 | |
111 | 106 | result(2, 0) = xz - wy; |
112 | 107 | result(2, 1) = yz + wx; |
113 | - //m[0][2] = xz - wy; m[1][2] = yz + wx; | |
114 | 108 | |
115 | - result(2, 2) = 1.0 - (xx + yy); | |
116 | - //result(3, 2) = 0.0; | |
117 | - //m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0; | |
109 | + result(2, 2) = (T)1.0 - (xx + yy); | |
110 | + | |
111 | + return result; | |
112 | +} | |
113 | + | |
114 | +template<typename T> | |
115 | +matrix<T, 4> quaternion<T>::toMatrix4() | |
116 | +{ | |
117 | + matrix<T, 4> result; | |
118 | + | |
119 | + | |
120 | + T wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; | |
118 | 121 | |
119 | - /*result(3, 0) = 0.0; | |
120 | - result(3, 1) = 0.0; | |
121 | - result(3, 2) = 0.0; | |
122 | - result(3, 3) = 1.0;*/ | |
123 | - //m[0][3] = 0; m[1][3] = 0; | |
124 | - //m[2][3] = 0; m[3][3] = 1; | |
125 | - /* | |
126 | - double* orientationmatrix=(double*)m; | |
127 | - char c; | |
128 | 122 | |
123 | + // calculate coefficients | |
124 | + x2 = x + x; y2 = y + y; | |
125 | + z2 = z + z; | |
126 | + xx = x * x2; xy = x * y2; xz = x * z2; | |
127 | + yy = y * y2; yz = y * z2; zz = z * z2; | |
128 | + wx = w * x2; wy = w * y2; wz = w * z2; | |
129 | + | |
130 | + result(0, 0) = (T)1.0 - (yy + zz); | |
131 | + result(0, 1) = xy - wz; | |
132 | + | |
133 | + result(0, 2) = xz + wy; | |
134 | + | |
135 | + result(1, 0) = xy + wz; | |
136 | + result(1, 1) = (T)1.0 - (xx + zz); | |
137 | + | |
138 | + result(1, 2) = yz - wx; | |
139 | + | |
140 | + result(2, 0) = xz - wy; | |
141 | + result(2, 1) = yz + wx; | |
129 | 142 | |
130 | - double* result=new double[16]; | |
131 | - double* array=(double*)m; | |
132 | - for(int i=0; i<16; i++) | |
133 | - result[i]=array[i]; | |
134 | - */ | |
143 | + result(2, 2) = (T)1.0 - (xx + yy); | |
144 | + | |
145 | + result(3, 3) = (T)1.0; | |
135 | 146 | |
136 | 147 | return result; |
137 | 148 | } |
138 | 149 | |
139 | 150 | template<typename T> |
140 | -rtsQuaternion<T>::rtsQuaternion() | |
151 | +quaternion<T>::quaternion() | |
141 | 152 | { |
142 | 153 | w=0.0; x=0.0; y=0.0; z=0.0; |
143 | 154 | } |
144 | 155 | |
145 | 156 | template<typename T> |
146 | -rtsQuaternion<T>::rtsQuaternion(T c, T i, T j, T k) | |
157 | +quaternion<T>::quaternion(T c, T i, T j, T k) | |
147 | 158 | { |
148 | 159 | w=c; x=i; y=j; z=k; |
149 | 160 | } |
150 | 161 | |
151 | -} //end rts namespace | |
162 | +} //end rts namespace | |
163 | + | |
164 | +#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 | |
165 | +template<class T> using rtsQuaternion = rts::quaternion<T>; | |
166 | +#endif | |
152 | 167 | |
153 | 168 | #endif | ... | ... |
rts/math/spherical_bessel.h
... | ... | @@ -10,7 +10,7 @@ namespace rts{ |
10 | 10 | #define RTS_BESSEL_MAXIMUM_FLOAT -1e33 |
11 | 11 | |
12 | 12 | template <typename T> |
13 | -CUDA_CALLABLE void sbesselj(int n, rtsComplex<T> x, rtsComplex<T>* j) | |
13 | +CUDA_CALLABLE void sbesselj(int n, complex<T> x, complex<T>* j) | |
14 | 14 | { |
15 | 15 | //compute the first bessel function |
16 | 16 | if(n >= 0) |
... | ... | @@ -36,7 +36,7 @@ CUDA_CALLABLE void sbesselj(int n, rtsComplex<T> x, rtsComplex<T>* j) |
36 | 36 | } |
37 | 37 | |
38 | 38 | template <typename T> |
39 | -CUDA_CALLABLE void sbessely(int n, rtsComplex<T> x, rtsComplex<T>* y) | |
39 | +CUDA_CALLABLE void sbessely(int n, complex<T> x, complex<T>* y) | |
40 | 40 | { |
41 | 41 | //compute the first bessel function |
42 | 42 | if(n >= 0) |
... | ... | @@ -56,14 +56,14 @@ CUDA_CALLABLE void sbessely(int n, rtsComplex<T> x, rtsComplex<T>* y) |
56 | 56 | |
57 | 57 | //spherical Hankel functions of the first kind |
58 | 58 | template <typename T> |
59 | -CUDA_CALLABLE void sbesselh1(int n, rtsComplex<T> x, rtsComplex<T>* h) | |
59 | +CUDA_CALLABLE void sbesselh1(int n, complex<T> x, complex<T>* h) | |
60 | 60 | { |
61 | 61 | //compute j_0 and j_1 |
62 | - rtsComplex<T> j[2]; | |
62 | + complex<T> j[2]; | |
63 | 63 | sbesselj(1, x, j); |
64 | 64 | |
65 | 65 | //compute y_0 and y_1 |
66 | - rtsComplex<T> y[2]; | |
66 | + complex<T> y[2]; | |
67 | 67 | sbessely(1, x, y); |
68 | 68 | |
69 | 69 | //compute the first-order Hhankel function | ... | ... |
1 | +#ifndef RTS_TRIANGLE_H | |
2 | +#define RTS_TRIANGLE_H | |
3 | + | |
4 | +//enable CUDA_CALLABLE macro | |
5 | +#include "rts/cuda/callable.h" | |
6 | +#include "rts/math/vector.h" | |
7 | +#include "rts/math/point.h" | |
8 | +#include <iostream> | |
9 | + | |
10 | +namespace rts{ | |
11 | + | |
12 | +template <class T, int N> | |
13 | +struct triangle | |
14 | +{ | |
15 | + /* | |
16 | + A------>B | |
17 | + | / | |
18 | + | / | |
19 | + | / | |
20 | + | / | |
21 | + | / | |
22 | + | / | |
23 | + C | |
24 | + */ | |
25 | + private: | |
26 | + | |
27 | + point<T, N> A; | |
28 | + point<T, N> B; | |
29 | + point<T, N> C; | |
30 | + | |
31 | + CUDA_CALLABLE point<T, N> _p(T s, T t) | |
32 | + { | |
33 | + //This function returns the point specified by p = A + s(B-A) + t(C-A) | |
34 | + vector<T, N> E0 = B-A; | |
35 | + vector<T, N> E1 = C-A; | |
36 | + | |
37 | + return A + s*E0 + t*E1; | |
38 | + } | |
39 | + | |
40 | + | |
41 | + public: | |
42 | + | |
43 | + | |
44 | + | |
45 | + CUDA_CALLABLE triangle() | |
46 | + { | |
47 | + | |
48 | + } | |
49 | + | |
50 | + CUDA_CALLABLE triangle(point<T, N> a, point<T, N> b, point<T, N> c) | |
51 | + { | |
52 | + A = a; | |
53 | + B = b; | |
54 | + C = c; | |
55 | + } | |
56 | + | |
57 | + CUDA_CALLABLE rts::point<T, N> operator()(T s, T t) | |
58 | + { | |
59 | + return _p(s, t); | |
60 | + } | |
61 | + | |
62 | + CUDA_CALLABLE point<T, N> nearest(point<T, N> p) | |
63 | + { | |
64 | + //comptue the distance between a point and this triangle | |
65 | + // This code is adapted from: http://www.geometrictools.com/Documentation/DistancePoint3Triangle3.pdf | |
66 | + | |
67 | + vector<T, N> E0 = B-A; | |
68 | + vector<T, N> E1 = C-A; | |
69 | + vector<T, N> D = A - p; | |
70 | + | |
71 | + T a = E0.dot(E0); | |
72 | + T b = E0.dot(E1); | |
73 | + T c = E1.dot(E1); | |
74 | + T d = E0.dot(D); | |
75 | + T e = E1.dot(D); | |
76 | + //T f = D.dot(D); | |
77 | + | |
78 | + T det = a*c - b*b; | |
79 | + T s = b*e - c*d; | |
80 | + T t = b*d - a*e; | |
81 | + | |
82 | + /*std::cout<<"E0: "<<E0<<std::endl; | |
83 | + std::cout<<"E1: "<<E1<<std::endl; | |
84 | + std::cout<<"a: "<<a<<std::endl; | |
85 | + std::cout<<"b: "<<b<<std::endl; | |
86 | + std::cout<<"c: "<<c<<std::endl; | |
87 | + std::cout<<"d: "<<d<<std::endl; | |
88 | + std::cout<<"e: "<<e<<std::endl; | |
89 | + std::cout<<"f: "<<f<<std::endl; | |
90 | + std::cout<<"det: "<<det<<std::endl; | |
91 | + std::cout<<"s: "<<s<<std::endl; | |
92 | + std::cout<<"t: "<<t<<std::endl;*/ | |
93 | + | |
94 | + | |
95 | + if( s+t <= det) | |
96 | + { | |
97 | + if(s < 0) | |
98 | + { | |
99 | + if(t < 0) | |
100 | + { | |
101 | + //region 4 | |
102 | + //std::cout<<"Region 4"<<std::endl; | |
103 | + s = 0; | |
104 | + t = 0; | |
105 | + //done? | |
106 | + } | |
107 | + else | |
108 | + { | |
109 | + //region 3 | |
110 | + //std::cout<<"Region 3"<<std::endl; | |
111 | + s=0; | |
112 | + t = ( e >= 0 ? 0 : ( -e >= c ? 1 : -e/c ) ); | |
113 | + //done | |
114 | + } | |
115 | + } | |
116 | + else if(t < 0) | |
117 | + { | |
118 | + //region 5 | |
119 | + //std::cout<<"Region 5"<<std::endl; | |
120 | + s = ( d >= 0 ? 0 : ( -d >= a ? 1 : -d/a ) ); | |
121 | + t = 0; | |
122 | + //done | |
123 | + } | |
124 | + else | |
125 | + { | |
126 | + //region 0 | |
127 | + //std::cout<<"Region 0"<<std::endl; | |
128 | + T invDet = (ptype)1.0/det; | |
129 | + s *= invDet; | |
130 | + t *= invDet; | |
131 | + //done | |
132 | + } | |
133 | + } | |
134 | + else | |
135 | + { | |
136 | + if(s < 0) | |
137 | + { | |
138 | + //region 2 | |
139 | + //std::cout<<"Region 2"<<std::endl; | |
140 | + s = 0; | |
141 | + t = 1; | |
142 | + //done? | |
143 | + | |
144 | + } | |
145 | + else if(t < 0) | |
146 | + { | |
147 | + //region 6 | |
148 | + //std::cout<<"Region 6"<<std::endl; | |
149 | + s = 1; | |
150 | + t = 0; | |
151 | + //done? | |
152 | + } | |
153 | + else | |
154 | + { | |
155 | + //region 1 | |
156 | + //std::cout<<"Region 1"<<std::endl; | |
157 | + T numer = c + e - b - d; | |
158 | + if( numer <= 0 ) | |
159 | + s = 0; | |
160 | + else | |
161 | + { | |
162 | + T denom = a - 2 * b + c; | |
163 | + s = ( numer >= denom ? 1 : numer/denom ); | |
164 | + } | |
165 | + t = 1 - s; | |
166 | + //done | |
167 | + } | |
168 | + } | |
169 | + | |
170 | + //std::cout<<"s: "<<s<<std::endl; | |
171 | + //std::cout<<"t: "<<t<<std::endl; | |
172 | + | |
173 | + //std::cout<<"p: "<<_p(s, t)<<std::endl; | |
174 | + | |
175 | + return _p(s, t); | |
176 | + | |
177 | + } | |
178 | + | |
179 | + CUDA_CALLABLE T dist(point<T, N> p) | |
180 | + { | |
181 | + point<T, N> n = nearest(p); | |
182 | + | |
183 | + return (p - n).len(); | |
184 | + } | |
185 | +}; | |
186 | + | |
187 | +} | |
188 | + | |
189 | +#endif | ... | ... |
rts/math/vector.h
1 | 1 | #ifndef RTS_VECTOR_H |
2 | 2 | #define RTS_VECTOR_H |
3 | 3 | |
4 | -#include <iostream> | |
5 | -#include <cmath> | |
4 | +#include <iostream> | |
5 | +#include <cmath> | |
6 | 6 | #include <sstream> |
7 | 7 | //#include "rts/point.h" |
8 | 8 | #include "rts/cuda/callable.h" |
... | ... | @@ -13,11 +13,11 @@ namespace rts |
13 | 13 | |
14 | 14 | |
15 | 15 | template <class T, int N> |
16 | -struct rtsVector | |
16 | +struct vector | |
17 | 17 | { |
18 | 18 | T v[N]; |
19 | 19 | |
20 | - CUDA_CALLABLE rtsVector() | |
20 | + CUDA_CALLABLE vector() | |
21 | 21 | { |
22 | 22 | //memset(v, 0, sizeof(T) * N); |
23 | 23 | for(int i=0; i<N; i++) |
... | ... | @@ -25,7 +25,7 @@ struct rtsVector |
25 | 25 | } |
26 | 26 | |
27 | 27 | //efficiency constructor, makes construction easier for 1D-4D vectors |
28 | - CUDA_CALLABLE rtsVector(T x, T y = (T)0.0, T z = (T)0.0, T w = (T)0.0) | |
28 | + CUDA_CALLABLE vector(T x, T y = (T)0.0, T z = (T)0.0, T w = (T)0.0) | |
29 | 29 | { |
30 | 30 | if(N >= 1) |
31 | 31 | v[0] = x; |
... | ... | @@ -37,7 +37,7 @@ struct rtsVector |
37 | 37 | v[3] = w; |
38 | 38 | } |
39 | 39 | |
40 | - CUDA_CALLABLE rtsVector(const T(&data)[N]) | |
40 | + CUDA_CALLABLE vector(const T(&data)[N]) | |
41 | 41 | { |
42 | 42 | memcpy(v, data, sizeof(T) * N); |
43 | 43 | } |
... | ... | @@ -54,25 +54,25 @@ struct rtsVector |
54 | 54 | |
55 | 55 | } |
56 | 56 | |
57 | - CUDA_CALLABLE rtsVector<T, N> cart2sph() | |
57 | + CUDA_CALLABLE vector<T, N> cart2sph() | |
58 | 58 | { |
59 | 59 | //convert the vector from cartesian to spherical coordinates |
60 | 60 | //x, y, z -> r, theta, phi (where theta = 0 to 2*pi) |
61 | 61 | |
62 | - rtsVector<T, N> sph; | |
63 | - sph[0] = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); | |
64 | - sph[1] = std::atan2(v[1], v[0]); | |
62 | + vector<T, N> sph; | |
63 | + sph[0] = std::sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2]); | |
64 | + sph[1] = std::atan2(v[1], v[0]); | |
65 | 65 | sph[2] = std::acos(v[2] / sph[0]); |
66 | 66 | |
67 | 67 | return sph; |
68 | 68 | } |
69 | 69 | |
70 | - CUDA_CALLABLE rtsVector<T, N> sph2cart() | |
70 | + CUDA_CALLABLE vector<T, N> sph2cart() | |
71 | 71 | { |
72 | 72 | //convert the vector from cartesian to spherical coordinates |
73 | 73 | //r, theta, phi -> x, y, z (where theta = 0 to 2*pi) |
74 | 74 | |
75 | - rtsVector<T, N> cart; | |
75 | + vector<T, N> cart; | |
76 | 76 | cart[0] = v[0] * std::cos(v[1]) * std::sin(v[2]); |
77 | 77 | cart[1] = v[0] * std::sin(v[1]) * std::sin(v[2]); |
78 | 78 | cart[2] = v[0] * std::cos(v[2]); |
... | ... | @@ -80,10 +80,10 @@ struct rtsVector |
80 | 80 | return cart; |
81 | 81 | } |
82 | 82 | |
83 | - CUDA_CALLABLE rtsVector<T, N> norm() | |
83 | + CUDA_CALLABLE vector<T, N> norm() | |
84 | 84 | { |
85 | 85 | //compute and return the vector norm |
86 | - rtsVector<T, N> result; | |
86 | + vector<T, N> result; | |
87 | 87 | |
88 | 88 | //compute the vector length |
89 | 89 | T l = len(); |
... | ... | @@ -97,9 +97,9 @@ struct rtsVector |
97 | 97 | return result; |
98 | 98 | } |
99 | 99 | |
100 | - CUDA_CALLABLE rtsVector<T, 3> cross(rtsVector<T, 3> rhs) | |
100 | + CUDA_CALLABLE vector<T, 3> cross(vector<T, 3> rhs) | |
101 | 101 | { |
102 | - rtsVector<T, 3> result; | |
102 | + vector<T, 3> result; | |
103 | 103 | |
104 | 104 | //compute the cross product (only valid for 3D vectors) |
105 | 105 | result[0] = v[1] * rhs[2] - v[2] * rhs[1]; |
... | ... | @@ -109,7 +109,7 @@ struct rtsVector |
109 | 109 | return result; |
110 | 110 | } |
111 | 111 | |
112 | - CUDA_CALLABLE T dot(rtsVector<T, N> rhs) | |
112 | + CUDA_CALLABLE T dot(vector<T, N> rhs) | |
113 | 113 | { |
114 | 114 | T result = (T)0; |
115 | 115 | |
... | ... | @@ -121,41 +121,49 @@ struct rtsVector |
121 | 121 | } |
122 | 122 | |
123 | 123 | //arithmetic |
124 | - CUDA_CALLABLE rtsVector<T, N> operator+(rtsVector<T, N> rhs) | |
124 | + CUDA_CALLABLE vector<T, N> operator+(vector<T, N> rhs) | |
125 | 125 | { |
126 | - rtsVector<T, N> result; | |
126 | + vector<T, N> result; | |
127 | 127 | |
128 | 128 | for(int i=0; i<N; i++) |
129 | 129 | result.v[i] = v[i] + rhs.v[i]; |
130 | 130 | |
131 | 131 | return result; |
132 | 132 | } |
133 | - CUDA_CALLABLE rtsVector<T, N> operator-(rtsVector<T, N> rhs) | |
133 | + CUDA_CALLABLE vector<T, N> operator-(vector<T, N> rhs) | |
134 | 134 | { |
135 | - rtsVector<T, N> result; | |
135 | + vector<T, N> result; | |
136 | 136 | |
137 | 137 | for(int i=0; i<N; i++) |
138 | 138 | result.v[i] = v[i] - rhs.v[i]; |
139 | 139 | |
140 | 140 | return result; |
141 | 141 | } |
142 | - CUDA_CALLABLE rtsVector<T, N> operator*(T rhs) | |
142 | + CUDA_CALLABLE vector<T, N> operator*(T rhs) | |
143 | 143 | { |
144 | - rtsVector<T, N> result; | |
144 | + vector<T, N> result; | |
145 | 145 | |
146 | 146 | for(int i=0; i<N; i++) |
147 | 147 | result.v[i] = v[i] * rhs; |
148 | 148 | |
149 | 149 | return result; |
150 | 150 | } |
151 | - CUDA_CALLABLE rtsVector<T, N> operator/(T rhs) | |
151 | + CUDA_CALLABLE vector<T, N> operator/(T rhs) | |
152 | 152 | { |
153 | - rtsVector<T, N> result; | |
153 | + vector<T, N> result; | |
154 | 154 | |
155 | 155 | for(int i=0; i<N; i++) |
156 | 156 | result.v[i] = v[i] / rhs; |
157 | 157 | |
158 | 158 | return result; |
159 | + } | |
160 | + | |
161 | + CUDA_CALLABLE bool operator==(vector<T, N> rhs) | |
162 | + { | |
163 | + if ( (rhs.v[0] == v[0]) && (rhs.v[1] == v[1]) && (rhs.v[2] == v[2]) ) | |
164 | + return true; | |
165 | + | |
166 | + return false; | |
159 | 167 | } |
160 | 168 | |
161 | 169 | std::string toStr() |
... | ... | @@ -186,7 +194,7 @@ struct rtsVector |
186 | 194 | } //end namespace rts |
187 | 195 | |
188 | 196 | template <typename T, int N> |
189 | -std::ostream& operator<<(std::ostream& os, rts::rtsVector<T, N> v) | |
197 | +std::ostream& operator<<(std::ostream& os, rts::vector<T, N> v) | |
190 | 198 | { |
191 | 199 | os<<v.toStr(); |
192 | 200 | return os; |
... | ... | @@ -194,9 +202,9 @@ std::ostream& operator<<(std::ostream& os, rts::rtsVector<T, N> v) |
194 | 202 | |
195 | 203 | //arithmetic operators |
196 | 204 | template <typename T, int N> |
197 | -CUDA_CALLABLE rts::rtsVector<T, N> operator-(rts::rtsVector<T, N> v) | |
205 | +CUDA_CALLABLE rts::vector<T, N> operator-(rts::vector<T, N> v) | |
198 | 206 | { |
199 | - rts::rtsVector<T, N> r; | |
207 | + rts::vector<T, N> r; | |
200 | 208 | |
201 | 209 | //negate the vector |
202 | 210 | for(int i=0; i<N; i++) |
... | ... | @@ -206,11 +214,15 @@ CUDA_CALLABLE rts::rtsVector<T, N> operator-(rts::rtsVector<T, N> v) |
206 | 214 | } |
207 | 215 | |
208 | 216 | template <typename T, int N> |
209 | -CUDA_CALLABLE rts::rtsVector<T, N> operator*(T lhs, rts::rtsVector<T, N> rhs) | |
217 | +CUDA_CALLABLE rts::vector<T, N> operator*(T lhs, rts::vector<T, N> rhs) | |
210 | 218 | { |
211 | - rts::rtsVector<T, N> r; | |
219 | + rts::vector<T, N> r; | |
212 | 220 | |
213 | 221 | return rhs * lhs; |
214 | 222 | } |
215 | 223 | |
224 | +#if __GNUC__ > 3 && __GNUC_MINOR__ > 7 | |
225 | +template<class T, int N> using rtsVector = rts::vector<T, N>; | |
226 | +#endif | |
227 | + | |
216 | 228 | #endif | ... | ... |
rts/optics/material.h
... | ... | @@ -9,6 +9,7 @@ |
9 | 9 | #include <algorithm> |
10 | 10 | #include <sstream> |
11 | 11 | #include "rts/math/complex.h" |
12 | +#include "rts/math/function.h" | |
12 | 13 | |
13 | 14 | #define PI 3.14159 |
14 | 15 | |
... | ... | @@ -49,7 +50,7 @@ namespace rts{ |
49 | 50 | { |
50 | 51 | //wavelength (in microns) |
51 | 52 | T lambda; |
52 | - rtsComplex<T> n; | |
53 | + complex<T> n; | |
53 | 54 | }; |
54 | 55 | |
55 | 56 | template <class T> |
... | ... | @@ -111,10 +112,10 @@ namespace rts{ |
111 | 112 | |
112 | 113 | |
113 | 114 | //read the entry from an input string |
114 | - for(int i=0; i<valueList.size(); i++) | |
115 | + for(unsigned int i=0; i<valueList.size(); i++) | |
115 | 116 | { |
116 | 117 | |
117 | - char c; | |
118 | + | |
118 | 119 | while(ss.peek() < '0' || ss.peek() > '9') |
119 | 120 | { |
120 | 121 | //cout<<"bad char"<<endl; |
... | ... | @@ -195,25 +196,17 @@ namespace rts{ |
195 | 196 | { |
196 | 197 | std::string name; |
197 | 198 | //dispersion (refractive index as a function of wavelength) |
198 | - std::vector< refIndex<T> > dispersion; | |
199 | + //std::vector< refIndex<T> > dispersion; | |
200 | + function< T, complex<T> > dispersion; | |
199 | 201 | |
200 | 202 | //average refractive index (approximately 1.4) |
201 | 203 | T n0; |
202 | 204 | |
203 | - void add(refIndex<T> ri) | |
205 | + /*void add(refIndex<T> ri) | |
204 | 206 | { |
205 | 207 | //refIndex<T> converted = convert(ri, measurement); |
206 | 208 | dispersion.push_back(ri); |
207 | - } | |
208 | - | |
209 | - void add(T lambda, rtsComplex<T> n) | |
210 | - { | |
211 | - refIndex<T> ri; | |
212 | - ri.lambda = lambda; | |
213 | - ri.n = n; | |
214 | - | |
215 | - dispersion.push_back(ri); | |
216 | - } | |
209 | + }*/ | |
217 | 210 | |
218 | 211 | //comparison function for sorting |
219 | 212 | static bool compare(refIndex<T> a, refIndex<T> b) |
... | ... | @@ -222,12 +215,17 @@ namespace rts{ |
222 | 215 | } |
223 | 216 | |
224 | 217 | //comparison function for searching lambda |
225 | - static bool findCeiling(refIndex<T> a, refIndex<T> b) | |
218 | + /*static bool findCeiling(refIndex<T> a, refIndex<T> b) | |
226 | 219 | { |
227 | 220 | return (a.lambda > b.lambda); |
228 | - } | |
221 | + }*/ | |
229 | 222 | |
230 | 223 | public: |
224 | + void add(T lambda, complex<T> n) | |
225 | + { | |
226 | + dispersion.insert(lambda, n); | |
227 | + } | |
228 | + | |
231 | 229 | std::string getName() |
232 | 230 | { |
233 | 231 | return name; |
... | ... | @@ -244,6 +242,11 @@ namespace rts{ |
244 | 242 | { |
245 | 243 | n0 = n; |
246 | 244 | } |
245 | + | |
246 | + void setM(function< T, complex<T> > m) | |
247 | + { | |
248 | + dispersion = m; | |
249 | + } | |
247 | 250 | unsigned int nSamples() |
248 | 251 | { |
249 | 252 | return dispersion.size(); |
... | ... | @@ -268,9 +271,9 @@ namespace rts{ |
268 | 271 | |
269 | 272 | #ifdef FFTW_AVAILABLE |
270 | 273 | //allocate memory for the FFT |
271 | - rtsComplex<T>* Chi2 = (rtsComplex<T>*)fftw_malloc(sizeof(rtsComplex<T>) * N * pf); | |
272 | - rtsComplex<T>* Chi2FFT = (rtsComplex<T>*)fftw_malloc(sizeof(rtsComplex<T>) * N * pf); | |
273 | - rtsComplex<T>* Chi1 = (rtsComplex<T>*)fftw_malloc(sizeof(rtsComplex<T>) * N * pf); | |
274 | + complex<T>* Chi2 = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
275 | + complex<T>* Chi2FFT = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
276 | + complex<T>* Chi1 = (complex<T>*)fftw_malloc(sizeof(complex<T>) * N * pf); | |
274 | 277 | |
275 | 278 | //create an FFT plan for the forward and inverse transforms |
276 | 279 | fftw_plan planForward, planInverse; |
... | ... | @@ -301,8 +304,8 @@ namespace rts{ |
301 | 304 | } |
302 | 305 | |
303 | 306 | //use linear interpolation between the start and end points to pad the spectrum |
304 | - //rtsComplex<T> nMin = dispersion.back(); | |
305 | - //rtsComplex<T> nMax = dispersion.front(); | |
307 | + //complex<T> nMin = dispersion.back(); | |
308 | + //complex<T> nMax = dispersion.front(); | |
306 | 309 | T a; |
307 | 310 | for(int i=N; i<N*pf; i++) |
308 | 311 | { |
... | ... | @@ -316,7 +319,7 @@ namespace rts{ |
316 | 319 | fftw_execute(planForward); |
317 | 320 | |
318 | 321 | //perform the Hilbert transform in the Fourier domain |
319 | - rtsComplex<T> j(0, 1); | |
322 | + complex<T> j(0, 1); | |
320 | 323 | for(int i=0; i<N*pf; i++) |
321 | 324 | { |
322 | 325 | //if w = 0, set the DC component to zero |
... | ... | @@ -400,13 +403,14 @@ namespace rts{ |
400 | 403 | |
401 | 404 | material(T lambda = 1.0, T n = 1.4, T k = 0.0) |
402 | 405 | { |
403 | - //create a default refractive index | |
406 | + dispersion.insert(lambda, complex<T>(0.0, k)); | |
407 | + /*//create a default refractive index | |
404 | 408 | refIndex<T> def; |
405 | 409 | def.lambda = lambda; |
406 | 410 | def.n.real(n); |
407 | 411 | def.n.imag(k); |
408 | 412 | add(def); |
409 | - | |
413 | + */ | |
410 | 414 | //set n0 |
411 | 415 | n0 = n; |
412 | 416 | } |
... | ... | @@ -419,9 +423,9 @@ namespace rts{ |
419 | 423 | |
420 | 424 | void fromFile(std::string filename, std::string format = "", T scaleA = 1.0) |
421 | 425 | { |
422 | - name = filename; | |
426 | + name = filename; | |
423 | 427 | //clear any previous values |
424 | - dispersion.clear(); | |
428 | + dispersion = rts::function< T, complex<T> >(); | |
425 | 429 | |
426 | 430 | //load the file into a string |
427 | 431 | std::ifstream ifs(filename.c_str()); |
... | ... | @@ -437,7 +441,6 @@ namespace rts{ |
437 | 441 | //process the file as a string |
438 | 442 | std::string instr((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>()); |
439 | 443 | fromStr(instr, format, scaleA); |
440 | - | |
441 | 444 | } |
442 | 445 | |
443 | 446 | void fromStr(std::string str, std::string format = "", T scaleA = 1.0) |
... | ... | @@ -480,7 +483,6 @@ namespace rts{ |
480 | 483 | |
481 | 484 | //std::cout<<"Loading material with format: "<<format<<std::endl; |
482 | 485 | |
483 | - T lambda, n, k; | |
484 | 486 | while(!ss.eof()) |
485 | 487 | { |
486 | 488 | //read a line from the string |
... | ... | @@ -490,14 +492,14 @@ namespace rts{ |
490 | 492 | if(line[0] != '#') |
491 | 493 | { |
492 | 494 | //load the entry and add it to the dispersion list |
493 | - add(entry.inputEntry(line, scaleA)); | |
495 | + add(entry.inputEntry(line, scaleA).lambda, entry.inputEntry(line, scaleA).n); | |
494 | 496 | } |
495 | 497 | //generally have to peek to trigger the eof flag |
496 | 498 | ss.peek(); |
497 | 499 | } |
498 | 500 | |
499 | 501 | //sort the vector by lambda |
500 | - sort(dispersion.begin(), dispersion.end(), &material<T>::compare); | |
502 | + //sort(dispersion.begin(), dispersion.end(), &material<T>::compare); | |
501 | 503 | } |
502 | 504 | |
503 | 505 | //convert the material to a string |
... | ... | @@ -555,51 +557,30 @@ namespace rts{ |
555 | 557 | |
556 | 558 | } |
557 | 559 | |
558 | - rtsComplex<T> getN(T l) | |
560 | + complex<T> getN(T l) | |
559 | 561 | { |
560 | - //declare an iterator | |
561 | - typename std::vector< refIndex<T> >::iterator it; | |
562 | - | |
563 | - refIndex<T> r; | |
564 | - r.lambda = l; | |
565 | - | |
566 | - it = search(dispersion.begin(), dispersion.end(), &r, &r + 1, &material<T>::findCeiling); | |
567 | - | |
568 | - //if the wavelength is past the end of the list, return the back | |
569 | - if(it == dispersion.end()) | |
570 | - return dispersion.back().n; | |
571 | - //if the wavelength is before the beginning of the list, return the front | |
572 | - else if(it == dispersion.begin()) | |
573 | - return dispersion.front().n; | |
574 | - //otherwise interpolate | |
575 | - else | |
576 | - { | |
577 | - T lMax = (*it).lambda; | |
578 | - T lMin = (*(it - 1)).lambda; | |
579 | - //std::cout<<lMin<<"----------"<<lMax<<std::endl; | |
580 | - | |
581 | - T a = (l - lMin) / (lMax - lMin); | |
582 | - rtsComplex<T> riMin = (*(it - 1)).n; | |
583 | - rtsComplex<T> riMax = (*it).n; | |
584 | - rtsComplex<T> interp; | |
585 | - interp = rtsComplex<T>(a, 0.0) * riMin + rtsComplex<T>(1.0 - a, 0.0) * riMax; | |
586 | - return interp; | |
587 | - } | |
562 | + //return complex<T>(1.0, 0.0); | |
563 | + complex<T> ri = dispersion.linear(l) + n0; | |
564 | + return ri; | |
565 | + } | |
588 | 566 | |
567 | + function<T, complex<T> > getF() | |
568 | + { | |
569 | + return dispersion + complex<T>(n0, 0.0); | |
589 | 570 | } |
590 | 571 | |
591 | 572 | //returns the scattering efficiency at wavelength l |
592 | - rtsComplex<T> eta(T l) | |
573 | + complex<T> eta(T l) | |
593 | 574 | { |
594 | 575 | //get the refractive index |
595 | - rtsComplex<T> ri = getN(l); | |
576 | + complex<T> ri = getN(l); | |
596 | 577 | |
597 | 578 | //convert the refractive index to scattering efficiency |
598 | 579 | return ri*ri - 1.0; |
599 | 580 | |
600 | 581 | } |
601 | 582 | //interpolate the given lambda value and return the index of refraction |
602 | - rtsComplex<T> operator()(T l) | |
583 | + complex<T> operator()(T l) | |
603 | 584 | { |
604 | 585 | return getN(l); |
605 | 586 | } | ... | ... |
1 | +#include <qimage.h> | |
2 | +#include <qcolor.h> | |
3 | +#include <iostream> | |
4 | + | |
5 | +void qt_buffer2image(unsigned char* buffer, std::string filename, unsigned int x_size, unsigned int y_size) | |
6 | +{ | |
7 | + //x_size = 256; | |
8 | + //y_size = 256; | |
9 | + //create an image object | |
10 | + QImage image(x_size, y_size, QImage::Format_RGB32); | |
11 | + if(image.isNull()) | |
12 | + { | |
13 | + std::cout<<"Error creating QImage."<<std::endl; | |
14 | + return; | |
15 | + } | |
16 | + | |
17 | + int i; | |
18 | + unsigned char r, g, b; | |
19 | + unsigned int x, y; | |
20 | + for(y=0; y<y_size; y++) | |
21 | + for(x=0; x<x_size; x++) | |
22 | + { | |
23 | + //calculate the 1D index | |
24 | + i = y * x_size + x; | |
25 | + | |
26 | + r = buffer[i * 3 + 0]; | |
27 | + g = buffer[i * 3 + 1]; | |
28 | + b = buffer[i * 3 + 2]; | |
29 | + | |
30 | + //set the image pixel | |
31 | + QColor color(r, g, b); | |
32 | + image.setPixel(x, y, color.rgb()); | |
33 | + } | |
34 | + | |
35 | + if(!image.save(filename.c_str())) | |
36 | + std::cout<<"Error saving QImage."<<std::endl; | |
37 | +} | ... | ... |
1 | +#include <rts/math/vector.h> | |
2 | +#include <rts/math/point.h> | |
3 | +#include <rts/math/quaternion.h> | |
4 | +#include <rts/math/matrix.h> | |
5 | + | |
6 | +#include <ostream> | |
7 | + | |
8 | +#ifndef RTS_CAMERA_H | |
9 | +#define RTS_CAMERA_H | |
10 | + | |
11 | +namespace rts{ | |
12 | + | |
13 | +class camera | |
14 | +{ | |
15 | + vector<float, 3> d; //direction that the camera is pointing | |
16 | + point<float, 3> p; //position of the camera | |
17 | + vector<float, 3> up; //"up" direction | |
18 | + float focus; //focal length of the camera | |
19 | + float fov; | |
20 | + | |
21 | + //private function makes sure that the up vector is orthogonal to the direction vector and both are normalized | |
22 | + void stabalize() | |
23 | + { | |
24 | + vector<float, 3> side = up.cross(d); | |
25 | + up = d.cross(side); | |
26 | + up = up.norm(); | |
27 | + d = d.norm(); | |
28 | + } | |
29 | + | |
30 | +public: | |
31 | + void setPosition(point<float, 3> pos) | |
32 | + { | |
33 | + p = pos; | |
34 | + } | |
35 | + void setPosition(float x, float y, float z){setPosition(point<float, 3>(x, y, z));} | |
36 | + | |
37 | + void setFocalDistance(float distance){focus = distance;} | |
38 | + void setFOV(float field_of_view){fov = field_of_view;} | |
39 | + | |
40 | + void LookAt(point<float, 3> pos) | |
41 | + { | |
42 | + //find the new direction | |
43 | + d = pos - p; | |
44 | + | |
45 | + //find the distance from the look-at point to the current position | |
46 | + focus = d.len(); | |
47 | + | |
48 | + //stabalize the camera | |
49 | + stabalize(); | |
50 | + } | |
51 | + void LookAt(float px, float py, float pz){LookAt(point<float, 3>(px, py, pz));} | |
52 | + void LookAt(point<float, 3> pos, vector<float, 3> new_up){up = new_up; LookAt(pos);} | |
53 | + void LookAt(float px, float py, float pz, float ux, float uy, float uz){LookAt(point<float, 3>(px, py, pz), vector<float, 3>(ux, uy, uz));} | |
54 | + void LookAtDolly(float lx, float ly, float lz) | |
55 | + { | |
56 | + //find the current focus point | |
57 | + point<float, 3> f = p + focus*d; | |
58 | + vector<float, 3> T = point<float, 3>(lx, ly, lz) - f; | |
59 | + p = p + T; | |
60 | + } | |
61 | + | |
62 | + void Dolly(vector<float, 3> direction) | |
63 | + { | |
64 | + p = p+direction; | |
65 | + } | |
66 | + void Dolly(float x, float y, float z){Dolly(vector<float, 3>(x, y, z));} | |
67 | + void Push(float delta) | |
68 | + { | |
69 | + if(delta > focus) | |
70 | + delta = focus; | |
71 | + | |
72 | + focus -= delta; | |
73 | + | |
74 | + Dolly(d*delta); | |
75 | + } | |
76 | + | |
77 | + void Pan(float theta_x, float theta_y, float theta_z) | |
78 | + { | |
79 | + //x rotation is around the up axis | |
80 | + quaternion<float> qx; | |
81 | + qx.CreateRotation(theta_x, up[0], up[1], up[2]); | |
82 | + | |
83 | + //y rotation is around the side axis | |
84 | + vector<float, 3> side = up.cross(d); | |
85 | + quaternion<float> qy; | |
86 | + qy.CreateRotation(theta_y, side[0], side[1], side[2]); | |
87 | + | |
88 | + //z rotation is around the direction vector | |
89 | + quaternion<float> qz; | |
90 | + qz.CreateRotation(theta_z, d[0], d[1], d[2]); | |
91 | + | |
92 | + //combine the rotations in x, y, z order | |
93 | + quaternion<float> final = qz*qy*qx; | |
94 | + | |
95 | + //get the rotation matrix | |
96 | + matrix<float, 3> rot_matrix = final.toMatrix3(); | |
97 | + | |
98 | + //apply the rotation | |
99 | + d = rot_matrix*d; | |
100 | + up = rot_matrix*up; | |
101 | + | |
102 | + //stabalize the camera | |
103 | + stabalize(); | |
104 | + | |
105 | + } | |
106 | + void Pan(float theta_x){Pan(theta_x, 0, 0);} | |
107 | + void Tilt(float theta_y){Pan(0, theta_y, 0);} | |
108 | + void Twist(float theta_z){Pan(0, 0, theta_z);} | |
109 | + | |
110 | + void Zoom(float delta) | |
111 | + { | |
112 | + fov -= delta; | |
113 | + if(fov < 0.5) | |
114 | + fov = 0.5; | |
115 | + if(fov > 180) | |
116 | + fov = 180; | |
117 | + } | |
118 | + | |
119 | + void OrbitFocus(float theta_x, float theta_y) | |
120 | + { | |
121 | + //find the focal point | |
122 | + point<float, 3> focal_point = p + focus*d; | |
123 | + | |
124 | + //center the coordinate system on the focal point | |
125 | + point<float, 3> centered = p - (focal_point - point<float, 3>(0, 0, 0)); | |
126 | + | |
127 | + //create the x rotation (around the up vector) | |
128 | + quaternion<float> qx; | |
129 | + qx.CreateRotation(theta_x, up[0], up[1], up[2]); | |
130 | + centered = point<float, 3>(0, 0, 0) + qx.toMatrix3()*(centered - point<float, 3>(0, 0, 0)); | |
131 | + | |
132 | + //get a side vector for theta_y rotation | |
133 | + vector<float, 3> side = up.cross((point<float, 3>(0, 0, 0) - centered).norm()); | |
134 | + | |
135 | + quaternion<float> qy; | |
136 | + qy.CreateRotation(theta_y, side[0], side[1], side[2]); | |
137 | + centered = point<float, 3>(0, 0, 0) + qy.toMatrix3()*(centered - point<float, 3>(0, 0, 0)); | |
138 | + | |
139 | + //perform the rotation on the centered camera position | |
140 | + //centered = final.toMatrix()*centered; | |
141 | + | |
142 | + //re-position the camera | |
143 | + p = centered + (focal_point - point<float, 3>(0, 0, 0)); | |
144 | + | |
145 | + //make sure we are looking at the focal point | |
146 | + LookAt(focal_point); | |
147 | + | |
148 | + //stabalize the camera | |
149 | + stabalize(); | |
150 | + | |
151 | + } | |
152 | + | |
153 | + void Slide(float u, float v) | |
154 | + { | |
155 | + vector<float, 3> V = up.norm(); | |
156 | + vector<float, 3> U = up.cross(d).norm(); | |
157 | + | |
158 | + p = p + (V * v) + (U * u); | |
159 | + } | |
160 | + | |
161 | + //accessor methods | |
162 | + point<float, 3> getPosition(){return p;} | |
163 | + vector<float, 3> getUp(){return up;} | |
164 | + vector<float, 3> getDirection(){return d;} | |
165 | + point<float, 3> getLookAt(){return p + focus*d;} | |
166 | + float getFOV(){return fov;} | |
167 | + | |
168 | + //output the camera settings | |
169 | + const void print(std::ostream& output) | |
170 | + { | |
171 | + output<<"Position: "<<p<<std::endl; | |
172 | + | |
173 | + } | |
174 | + friend std::ostream& operator<<(std::ostream& out, const camera& c) | |
175 | + { | |
176 | + out<<"Position: "<<c.p<<std::endl; | |
177 | + out<<"Direction: "<<c.d<<std::endl; | |
178 | + out<<"Up: "<<c.up<<std::endl; | |
179 | + out<<"Focal Distance: "<<c.focus<<std::endl; | |
180 | + return out; | |
181 | + } | |
182 | + | |
183 | + //constructor | |
184 | + camera() | |
185 | + { | |
186 | + p = point<float, 3>(0, 0, 0); | |
187 | + d = vector<float, 3>(0, 0, 1); | |
188 | + up = vector<float, 3>(0, 1, 0); | |
189 | + focus = 1; | |
190 | + | |
191 | + } | |
192 | +}; | |
193 | + | |
194 | +} | |
195 | + | |
196 | + | |
197 | + | |
198 | +#endif | ... | ... |
1 | +#ifndef RTS_COLORMAP_H | |
2 | +#define RTS_COLORMAP_H | |
3 | + | |
4 | +#include <string> | |
5 | +#include <stdlib.h> | |
6 | +#include "rts/cuda/error.h" | |
7 | + | |
8 | + | |
9 | +#define BREWER_CTRL_PTS 11 | |
10 | + | |
11 | +void qt_buffer2image(unsigned char* buffer, std::string filename, unsigned int x_size, unsigned int y_size); | |
12 | + | |
13 | +static float BREWERCP[BREWER_CTRL_PTS*4] = {0.192157f, 0.211765f, 0.584314f, 1.0f, | |
14 | + 0.270588f, 0.458824f, 0.705882f, 1.0f, | |
15 | + 0.454902f, 0.678431f, 0.819608f, 1.0f, | |
16 | + 0.670588f, 0.85098f, 0.913725f, 1.0f, | |
17 | + 0.878431f, 0.952941f, 0.972549f, 1.0f, | |
18 | + 1.0f, 1.0f, 0.74902f, 1.0f, | |
19 | + 0.996078f, 0.878431f, 0.564706f, 1.0f, | |
20 | + 0.992157f, 0.682353f, 0.380392f, 1.0f, | |
21 | + 0.956863f, 0.427451f, 0.262745f, 1.0f, | |
22 | + 0.843137f, 0.188235f, 0.152941f, 1.0f, | |
23 | + 0.647059f, 0.0f, 0.14902f, 1.0f}; | |
24 | + | |
25 | + | |
26 | +#ifdef __CUDACC__ | |
27 | +texture<float4, cudaTextureType1D> cudaTexBrewer; | |
28 | +static cudaArray* gpuBrewer; | |
29 | +#endif | |
30 | + | |
31 | + | |
32 | + | |
33 | +namespace rts{ | |
34 | + | |
35 | +enum colormapType {cmBrewer, cmGrayscale}; | |
36 | + | |
37 | +static void buffer2image(unsigned char* buffer, std::string filename, unsigned int x_size, unsigned int y_size) | |
38 | +{ | |
39 | + qt_buffer2image(buffer, filename, x_size, y_size); | |
40 | +} | |
41 | + | |
42 | +#ifdef __CUDACC__ | |
43 | +static void initBrewer() | |
44 | +{ | |
45 | + //initialize the Brewer colormap | |
46 | + | |
47 | + //allocate CPU space | |
48 | + float4 cpuColorMap[BREWER_CTRL_PTS]; | |
49 | + | |
50 | + //define control rtsPoints | |
51 | + cpuColorMap[0] = make_float4(0.192157f, 0.211765f, 0.584314f, 1.0f); | |
52 | + cpuColorMap[1] = make_float4(0.270588f, 0.458824f, 0.705882f, 1.0f); | |
53 | + cpuColorMap[2] = make_float4(0.454902f, 0.678431f, 0.819608f, 1.0f); | |
54 | + cpuColorMap[3] = make_float4(0.670588f, 0.85098f, 0.913725f, 1.0f); | |
55 | + cpuColorMap[4] = make_float4(0.878431f, 0.952941f, 0.972549f, 1.0f); | |
56 | + cpuColorMap[5] = make_float4(1.0f, 1.0f, 0.74902f, 1.0f); | |
57 | + cpuColorMap[6] = make_float4(0.996078f, 0.878431f, 0.564706f, 1.0f); | |
58 | + cpuColorMap[7] = make_float4(0.992157f, 0.682353f, 0.380392f, 1.0f); | |
59 | + cpuColorMap[8] = make_float4(0.956863f, 0.427451f, 0.262745f, 1.0f); | |
60 | + cpuColorMap[9] = make_float4(0.843137f, 0.188235f, 0.152941f, 1.0f); | |
61 | + cpuColorMap[10] = make_float4(0.647059f, 0.0f, 0.14902f, 1.0f); | |
62 | + | |
63 | + | |
64 | + int width = BREWER_CTRL_PTS; | |
65 | + int height = 0; | |
66 | + | |
67 | + | |
68 | + // allocate array and copy colormap data | |
69 | + cudaChannelFormatDesc channelDesc = cudaCreateChannelDesc(32, 32, 32, 32, cudaChannelFormatKindFloat); | |
70 | + | |
71 | + HANDLE_ERROR(cudaMallocArray(&gpuBrewer, &channelDesc, width, height)); | |
72 | + | |
73 | + HANDLE_ERROR(cudaMemcpyToArray(gpuBrewer, 0, 0, cpuColorMap, sizeof(float4)*width, cudaMemcpyHostToDevice)); | |
74 | + | |
75 | + // set texture parameters | |
76 | + cudaTexBrewer.addressMode[0] = cudaAddressModeClamp; | |
77 | + //texBrewer.addressMode[1] = cudaAddressModeClamp; | |
78 | + cudaTexBrewer.filterMode = cudaFilterModeLinear; | |
79 | + cudaTexBrewer.normalized = true; // access with normalized texture coordinates | |
80 | + | |
81 | + // Bind the array to the texture | |
82 | + HANDLE_ERROR(cudaBindTextureToArray( cudaTexBrewer, gpuBrewer, channelDesc)); | |
83 | + | |
84 | +} | |
85 | + | |
86 | +static void destroyBrewer() | |
87 | +{ | |
88 | + HANDLE_ERROR(cudaFreeArray(gpuBrewer)); | |
89 | + | |
90 | +} | |
91 | + | |
92 | +template<class T> | |
93 | +__global__ static void applyBrewer(T* gpuSource, unsigned char* gpuDest, unsigned int N, T minVal = 0, T maxVal = 1) | |
94 | +{ | |
95 | + | |
96 | + int i = blockIdx.y * gridDim.x * blockDim.x + blockIdx.x * blockDim.x + threadIdx.x; | |
97 | + if(i >= N) return; | |
98 | + | |
99 | + //compute the normalized value on [minVal maxVal] | |
100 | + float a = (gpuSource[i] - minVal) / (maxVal - minVal); | |
101 | + | |
102 | + //lookup the color | |
103 | + float shift = 1.0/(2*BREWER_CTRL_PTS); | |
104 | + float4 color = tex1D(cudaTexBrewer, a+shift); | |
105 | + //float4 color = tex1D(cudaTexBrewer, a); | |
106 | + | |
107 | + gpuDest[i * 3 + 0] = 255 * color.x; | |
108 | + gpuDest[i * 3 + 1] = 255 * color.y; | |
109 | + gpuDest[i * 3 + 2] = 255 * color.z; | |
110 | +} | |
111 | + | |
112 | +template<class T> | |
113 | +__global__ static void applyGrayscale(T* gpuSource, unsigned char* gpuDest, unsigned int N, T minVal = 0, T maxVal = 1) | |
114 | +{ | |
115 | + int i = blockIdx.y * gridDim.x * blockDim.x + blockIdx.x * blockDim.x + threadIdx.x; | |
116 | + if(i >= N) return; | |
117 | + | |
118 | + //compute the normalized value on [minVal maxVal] | |
119 | + float a = (gpuSource[i] - minVal) / (maxVal - minVal); | |
120 | + | |
121 | + //threshold | |
122 | + if(a > 1.0) | |
123 | + a = 1.0; | |
124 | + if(a < 0.0) | |
125 | + a = 0.0; | |
126 | + | |
127 | + gpuDest[i * 3 + 0] = 255 * a; | |
128 | + gpuDest[i * 3 + 1] = 255 * a; | |
129 | + gpuDest[i * 3 + 2] = 255 * a; | |
130 | +} | |
131 | + | |
132 | +template<class T> | |
133 | +static void gpu2gpu(T* gpuSource, unsigned char* gpuDest, unsigned int nVals, T minVal = 0, T maxVal = 1, colormapType cm = cmGrayscale, int blockDim = 128) | |
134 | +{ | |
135 | + //This function converts a scalar field on the GPU to a color image on the GPU | |
136 | + int gridX = (nVals + blockDim - 1)/blockDim; | |
137 | + int gridY = 1; | |
138 | + if(gridX > 65535) | |
139 | + { | |
140 | + gridY = (gridX + 65535 - 1) / 65535; | |
141 | + gridX = 65535; | |
142 | + } | |
143 | + dim3 dimGrid(gridX, gridY); | |
144 | + //int gridDim = (nVals + blockDim - 1)/blockDim; | |
145 | + if(cm == cmGrayscale) | |
146 | + applyGrayscale<<<dimGrid, blockDim>>>(gpuSource, gpuDest, nVals, minVal, maxVal); | |
147 | + else if(cm == cmBrewer) | |
148 | + { | |
149 | + initBrewer(); | |
150 | + applyBrewer<<<dimGrid, blockDim>>>(gpuSource, gpuDest, nVals, minVal, maxVal); | |
151 | + //HANDLE_ERROR(cudaMemset(gpuDest, 0, sizeof(unsigned char) * nVals * 3)); | |
152 | + destroyBrewer(); | |
153 | + } | |
154 | + | |
155 | +} | |
156 | + | |
157 | +template<class T> | |
158 | +static void gpu2cpu(T* gpuSource, unsigned char* cpuDest, unsigned int nVals, T minVal, T maxVal, colormapType cm = cmGrayscale) | |
159 | +{ | |
160 | + //this function converts a scalar field on the GPU to a color image on the CPU | |
161 | + | |
162 | + //first create the color image on the GPU | |
163 | + | |
164 | + //allocate GPU memory for the color image | |
165 | + unsigned char* gpuDest; | |
166 | + HANDLE_ERROR(cudaMalloc( (void**)&gpuDest, sizeof(unsigned char) * nVals * 3 )); | |
167 | + | |
168 | + //HANDLE_ERROR(cudaMemset(gpuSource, 0, sizeof(T) * nVals)); | |
169 | + | |
170 | + //create the image on the gpu | |
171 | + gpu2gpu(gpuSource, gpuDest, nVals, minVal, maxVal, cm); | |
172 | + | |
173 | + //HANDLE_ERROR(cudaMemset(gpuDest, 0, sizeof(unsigned char) * nVals * 3)); | |
174 | + | |
175 | + //copy the image from the GPU to the CPU | |
176 | + HANDLE_ERROR(cudaMemcpy(cpuDest, gpuDest, sizeof(unsigned char) * nVals * 3, cudaMemcpyDeviceToHost)); | |
177 | + | |
178 | + HANDLE_ERROR(cudaFree( gpuDest )); | |
179 | + | |
180 | +} | |
181 | + | |
182 | +template<typename T> | |
183 | +static void gpu2image(T* gpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, T valMin, T valMax, colormapType cm = cmGrayscale) | |
184 | +{ | |
185 | + //allocate a color buffer | |
186 | + unsigned char* cpuBuffer = NULL; | |
187 | + cpuBuffer = (unsigned char*) malloc(sizeof(unsigned char) * 3 * x_size * y_size); | |
188 | + | |
189 | + //do the mapping | |
190 | + gpu2cpu<T>(gpuSource, cpuBuffer, x_size * y_size, valMin, valMax, cm); | |
191 | + | |
192 | + //copy the buffer to an image | |
193 | + buffer2image(cpuBuffer, fileDest, x_size, y_size); | |
194 | + | |
195 | + free(cpuBuffer); | |
196 | +} | |
197 | + | |
198 | +#endif | |
199 | + | |
200 | +template<class T> | |
201 | +static void cpuApplyBrewer(T* cpuSource, unsigned char* cpuDest, unsigned int N, T minVal = 0, T maxVal = 1) | |
202 | +{ | |
203 | + for(int i=0; i<N; i++) | |
204 | + { | |
205 | + //compute the normalized value on [minVal maxVal] | |
206 | + T v = cpuSource[i]; | |
207 | + float a = (cpuSource[i] - minVal) / (maxVal - minVal); | |
208 | + if(a < 0) a = 0; | |
209 | + if(a > 1) a = 1; | |
210 | + | |
211 | + float c = a * (float)(BREWER_CTRL_PTS-1); | |
212 | + int ptLow = (int)c; | |
213 | + float m = c - (float)ptLow; | |
214 | + //std::cout<<m<<std::endl; | |
215 | + | |
216 | + float r, g, b; | |
217 | + if(ptLow == BREWER_CTRL_PTS - 1) | |
218 | + { | |
219 | + r = BREWERCP[ptLow * 4 + 0]; | |
220 | + g = BREWERCP[ptLow * 4 + 1]; | |
221 | + b = BREWERCP[ptLow * 4 + 2]; | |
222 | + } | |
223 | + else | |
224 | + { | |
225 | + r = BREWERCP[ptLow * 4 + 0] * (1.0-m) + BREWERCP[ (ptLow+1) * 4 + 0] * m; | |
226 | + g = BREWERCP[ptLow * 4 + 1] * (1.0-m) + BREWERCP[ (ptLow+1) * 4 + 1] * m; | |
227 | + b = BREWERCP[ptLow * 4 + 2] * (1.0-m) + BREWERCP[ (ptLow+1) * 4 + 2] * m; | |
228 | + } | |
229 | + | |
230 | + | |
231 | + cpuDest[i * 3 + 0] = 255 * r; | |
232 | + cpuDest[i * 3 + 1] = 255 * g; | |
233 | + cpuDest[i * 3 + 2] = 255 * b; | |
234 | + | |
235 | + } | |
236 | +} | |
237 | + | |
238 | +template<class T> | |
239 | +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, T valMin, T valMax, colormapType cm = cmGrayscale) | |
240 | +{ | |
241 | + | |
242 | + if(cm == cmBrewer) | |
243 | + cpuApplyBrewer(cpuSource, cpuDest, nVals, valMin, valMax); | |
244 | + else if(cm == cmGrayscale) | |
245 | + { | |
246 | + int i; | |
247 | + float a; | |
248 | + float range = valMax - valMin; | |
249 | + for(i = 0; i<nVals; i++) | |
250 | + { | |
251 | + //normalize to the range [valMin valMax] | |
252 | + a = (cpuSource[i] - valMin) / range; | |
253 | + | |
254 | + if(a < 0) a = 0.0; | |
255 | + if(a > 1) a = 1.0; | |
256 | + | |
257 | + cpuDest[i * 3 + 0] = 255 * a; | |
258 | + cpuDest[i * 3 + 1] = 255 * a; | |
259 | + cpuDest[i * 3 + 2] = 255 * a; | |
260 | + } | |
261 | + } | |
262 | +} | |
263 | + | |
264 | +template<class T> | |
265 | +static void cpu2cpu(T* cpuSource, unsigned char* cpuDest, unsigned int nVals, colormapType cm = cmGrayscale, bool positive = false) | |
266 | +{ | |
267 | + //computes the max and min range automatically | |
268 | + | |
269 | + //find the largest magnitude value | |
270 | + T maxVal = fabs(cpuSource[0]); | |
271 | + for(int i=0; i<nVals; i++) | |
272 | + { | |
273 | + if(fabs(cpuSource[i]) > maxVal) | |
274 | + maxVal = fabs(cpuSource[i]); | |
275 | + } | |
276 | + | |
277 | + if(positive) | |
278 | + cpu2cpu(cpuSource, cpuDest, nVals, (T)0.0, maxVal, cm); | |
279 | + else | |
280 | + cpu2cpu(cpuSource, cpuDest, nVals, -maxVal, maxVal, cm); | |
281 | + | |
282 | +} | |
283 | + | |
284 | + | |
285 | + | |
286 | +template<typename T> | |
287 | +static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, T valMin, T valMax, colormapType cm = cmGrayscale) | |
288 | +{ | |
289 | + //allocate a color buffer | |
290 | + unsigned char* cpuBuffer = (unsigned char*) malloc(sizeof(unsigned char) * 3 * x_size * y_size); | |
291 | + | |
292 | + //do the mapping | |
293 | + cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, valMin, valMax, cm); | |
294 | + | |
295 | + //copy the buffer to an image | |
296 | + buffer2image(cpuBuffer, fileDest, x_size, y_size); | |
297 | + | |
298 | + free(cpuBuffer); | |
299 | + | |
300 | +} | |
301 | + | |
302 | +template<typename T> | |
303 | +static void cpu2image(T* cpuSource, std::string fileDest, unsigned int x_size, unsigned int y_size, colormapType cm = cmGrayscale, bool positive = false) | |
304 | +{ | |
305 | + //allocate a color buffer | |
306 | + unsigned char* cpuBuffer = (unsigned char*) malloc(sizeof(unsigned char) * 3 * x_size * y_size); | |
307 | + | |
308 | + //do the mapping | |
309 | + cpu2cpu<T>(cpuSource, cpuBuffer, x_size * y_size, cm, positive); | |
310 | + | |
311 | + //copy the buffer to an image | |
312 | + buffer2image(cpuBuffer, fileDest, x_size, y_size); | |
313 | + | |
314 | + free(cpuBuffer); | |
315 | + | |
316 | +} | |
317 | + | |
318 | +} //end namespace colormap and rts | |
319 | + | |
320 | +#endif | |
321 | + | ... | ... |