glviewvol

annotate src/xfermap.cc @ 12:773f89037a35

added copyright headers
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 31 Dec 2014 07:57:04 +0200
parents 71b479ffb9f7
children
rev   line source
nuclear@12 1 /*
nuclear@12 2 glviewvol is an OpenGL 3D volume data viewer
nuclear@12 3 Copyright (C) 2014 John Tsiombikas <nuclear@member.fsf.org>
nuclear@12 4
nuclear@12 5 This program is free software: you can redistribute it and/or modify
nuclear@12 6 it under the terms of the GNU General Public License as published by
nuclear@12 7 the Free Software Foundation, either version 3 of the License, or
nuclear@12 8 (at your option) any later version.
nuclear@12 9
nuclear@12 10 This program is distributed in the hope that it will be useful,
nuclear@12 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
nuclear@12 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
nuclear@12 13 GNU General Public License for more details.
nuclear@12 14
nuclear@12 15 You should have received a copy of the GNU General Public License
nuclear@12 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
nuclear@12 17 */
nuclear@7 18 #include <math.h>
nuclear@6 19 #include <algorithm>
nuclear@6 20 #include "xfermap.h"
nuclear@6 21
nuclear@6 22 TransferFunc::~TransferFunc()
nuclear@6 23 {
nuclear@6 24 }
nuclear@6 25
nuclear@6 26
nuclear@6 27 // ---- TransferWindow ----
nuclear@6 28
nuclear@6 29 TransferWindow::TransferWindow()
nuclear@6 30 {
nuclear@6 31 soft_rad = 0.5;
nuclear@7 32 for(int i=0; i<3; i++) {
nuclear@6 33 low[i] = 0.5;
nuclear@7 34 high[i] = 1.5;
nuclear@6 35 }
nuclear@6 36 }
nuclear@6 37
nuclear@7 38 void TransferWindow::set_handle(int channel, int handle, float val)
nuclear@7 39 {
nuclear@7 40 float *dest = handle == HANDLE_LOW ? low : high;
nuclear@7 41
nuclear@7 42 if(channel == -1) {
nuclear@7 43 dest[0] = dest[1] = dest[2] = val;
nuclear@7 44 } else {
nuclear@7 45 dest[channel] = val;
nuclear@7 46 }
nuclear@7 47 }
nuclear@7 48
nuclear@7 49 float TransferWindow::get_handle(int channel, int handle) const
nuclear@7 50 {
nuclear@7 51 const float *src = handle == HANDLE_LOW ? low : high;
nuclear@7 52
nuclear@7 53 if(channel == -1) {
nuclear@7 54 return src[0]; // XXX this doens't make much sense
nuclear@7 55 }
nuclear@7 56 return src[channel];
nuclear@7 57 }
nuclear@7 58
nuclear@7 59 int TransferWindow::nearest_handle(int channel, float pos) const
nuclear@7 60 {
nuclear@7 61 float ldist = 0, hdist = 0;
nuclear@7 62
nuclear@7 63 if(channel == -1) {
nuclear@7 64 for(int i=0; i<3; i++) {
nuclear@7 65 ldist += fabs(low[i] - pos);
nuclear@7 66 hdist += fabs(high[i] - pos);
nuclear@7 67 }
nuclear@7 68 } else {
nuclear@7 69 ldist = fabs(low[channel] - pos);
nuclear@7 70 hdist = fabs(high[channel] - pos);
nuclear@7 71 }
nuclear@7 72 return ldist <= hdist ? HANDLE_LOW : HANDLE_HIGH;
nuclear@7 73 }
nuclear@7 74
nuclear@6 75 void TransferWindow::set_interval(float a, float b)
nuclear@6 76 {
nuclear@6 77 float v0 = std::min(a, b);
nuclear@6 78 float v1 = std::max(a, b);
nuclear@6 79
nuclear@7 80 for(int i=0; i<3; i++) {
nuclear@6 81 low[i] = v0;
nuclear@6 82 high[i] = v1;
nuclear@6 83 }
nuclear@6 84 }
nuclear@6 85
nuclear@6 86 void TransferWindow::set_interval(float *rgba_low, float *rgba_high)
nuclear@6 87 {
nuclear@7 88 for(int i=0; i<3; i++) {
nuclear@6 89 low[i] = std::min(rgba_low[i], rgba_high[i]);
nuclear@6 90 high[i] = std::max(rgba_low[i], rgba_high[i]);
nuclear@6 91 }
nuclear@6 92 }
nuclear@6 93
nuclear@6 94 void TransferWindow::set_interval_rgba(int channel, float a, float b)
nuclear@6 95 {
nuclear@6 96 low[channel] = std::min(a, b);
nuclear@6 97 high[channel] = std::max(a, b);
nuclear@6 98 }
nuclear@6 99
nuclear@7 100 void TransferWindow::get_interval(float *aptr, float *bptr) const
nuclear@7 101 {
nuclear@7 102 *aptr = low[0];
nuclear@7 103 *bptr = high[0];
nuclear@7 104 }
nuclear@7 105
nuclear@7 106 void TransferWindow::get_interval_rgba(float *rgba_low, float *rgba_high) const
nuclear@7 107 {
nuclear@7 108 for(int i=0; i<3; i++) {
nuclear@7 109 rgba_low[i] = low[i];
nuclear@7 110 rgba_high[i] = high[i];
nuclear@7 111 }
nuclear@7 112 }
nuclear@7 113
nuclear@7 114 void TransferWindow::get_interval_rgba(int channel, float *aptr, float *bptr) const
nuclear@7 115 {
nuclear@7 116 *aptr = low[channel];
nuclear@7 117 *bptr = high[channel];
nuclear@7 118 }
nuclear@7 119
nuclear@6 120 void TransferWindow::set_soft_radius(float s)
nuclear@6 121 {
nuclear@6 122 soft_rad = s;
nuclear@6 123 }
nuclear@6 124
nuclear@6 125 float TransferWindow::get_soft_radius() const
nuclear@6 126 {
nuclear@6 127 return soft_rad;
nuclear@6 128 }
nuclear@6 129
nuclear@6 130 static inline float smoothstep(float a, float b, float x)
nuclear@6 131 {
nuclear@6 132 if(x < a) return 0.0f;
nuclear@6 133 if(x >= b) return 1.0f;
nuclear@6 134
nuclear@6 135 float t = (x - a) / (b - a);
nuclear@6 136 return t * t * (3.0f - 2.0f * t);
nuclear@6 137 }
nuclear@6 138
nuclear@6 139 float TransferWindow::map(float x) const
nuclear@6 140 {
nuclear@7 141 float rgb[3];
nuclear@7 142 map(x, rgb);
nuclear@7 143
nuclear@7 144 return std::max(rgb[0], std::max(rgb[1], rgb[2]));
nuclear@6 145 }
nuclear@6 146
nuclear@7 147 void TransferWindow::map(float x, float *rgb_value) const
nuclear@6 148 {
nuclear@7 149 for(int i=0; i<3; i++) {
nuclear@7 150 float val = smoothstep(low[i] - soft_rad, low[i] + soft_rad, x);
nuclear@7 151 val *= 1.0 - smoothstep(high[i] - soft_rad, high[i] + soft_rad, x);
nuclear@7 152 rgb_value[i] = val;
nuclear@6 153 }
nuclear@6 154 }