Commit 7006df5f3b680618a1597310683f8c334ca527fb

Authored by David Mayerich
1 parent 0174d823

reformat of directory structure

rts/biology/fibernet.h 0 → 100644
rts/cuda/glbind.h 0 → 100644
  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
... ...
rts/cuda/memory.h 0 → 100644
  1 +#include <cuda.h>
  2 +
... ...
rts/cuda/threads.h 0 → 100644
  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
... ... @@ -173,7 +173,7 @@ class EnviFile
173 173 exit(1);
174 174 }
175 175  
176   - float r, v0, v1;
  176 + float v0, v1;
177 177 for(int n=0; n<N; n++)
178 178 {
179 179 v0 = ((float*)A)[n];
... ...
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  
... ...
rts/gl/error.h 0 → 100755
  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
... ...
rts/gl/rtsSourceCode.h 0 → 100755
  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
... ...
rts/gl/rts_glShaderObject.h 0 → 100755
  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
... ...
rts/gl/rts_glShaderProgram.h 0 → 100755
  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
... ...
rts/gl/rts_glShaderUniform.h 0 → 100755
  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
... ...
rts/gl/rts_glUtilities.h 0 → 100755
  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
... ...
rts/gl/texture.h 0 → 100755
  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&lt;T&gt; pow(complex&lt;T&gt; 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&lt;A&gt; sin(const rts::rtsComplex&lt;A&gt; 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&lt;A&gt; cos(const rts::rtsComplex&lt;A&gt; 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
... ...
rts/math/function.h 0 → 100644
  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&lt;T&gt;::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> &param)
  57 +quaternion<T> quaternion<T>::operator *(quaternion<T> &param)
57 58 {
58 59 float A, B, C, D, E, F, G, H;
59 60  
... ... @@ -67,7 +68,7 @@ rtsQuaternion&lt;T&gt; rtsQuaternion&lt;T&gt;::operator *(rtsQuaternion&lt;T&gt; &amp;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&lt;T&gt; rtsQuaternion&lt;T&gt;::operator *(rtsQuaternion&lt;T&gt; &amp;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&lt;T, 3&gt; rtsQuaternion&lt;T&gt;::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&lt;T&gt; x, rtsComplex&lt;T&gt;* 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&lt;T&gt; x, rtsComplex&lt;T&gt;* 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
... ...
rts/math/triangle.h 0 → 100644
  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&amp; operator&lt;&lt;(std::ostream&amp; os, rts::rtsVector&lt;T, N&gt; 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&lt;T, N&gt; operator-(rts::rtsVector&lt;T, N&gt; 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 }
... ...
rts/source/colormap.cpp 0 → 100644
  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 +}
... ...
rts/visualization/camera.h 0 → 100755
  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
... ...
rts/visualization/colormap.h 0 → 100644
  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 +
... ...