glviewvol
diff src/xfermap.cc @ 7:71b479ffb9f7
curve manipulation works
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Tue, 30 Dec 2014 17:28:38 +0200 |
parents | f22be47a3572 |
children | 773f89037a35 |
line diff
1.1 --- a/src/xfermap.cc Tue Dec 30 06:22:54 2014 +0200 1.2 +++ b/src/xfermap.cc Tue Dec 30 17:28:38 2014 +0200 1.3 @@ -1,3 +1,4 @@ 1.4 +#include <math.h> 1.5 #include <algorithm> 1.6 #include "xfermap.h" 1.7 1.8 @@ -11,18 +12,55 @@ 1.9 TransferWindow::TransferWindow() 1.10 { 1.11 soft_rad = 0.5; 1.12 - for(int i=0; i<4; i++) { 1.13 + for(int i=0; i<3; i++) { 1.14 low[i] = 0.5; 1.15 - high[i] = 2.0; 1.16 + high[i] = 1.5; 1.17 } 1.18 } 1.19 1.20 +void TransferWindow::set_handle(int channel, int handle, float val) 1.21 +{ 1.22 + float *dest = handle == HANDLE_LOW ? low : high; 1.23 + 1.24 + if(channel == -1) { 1.25 + dest[0] = dest[1] = dest[2] = val; 1.26 + } else { 1.27 + dest[channel] = val; 1.28 + } 1.29 +} 1.30 + 1.31 +float TransferWindow::get_handle(int channel, int handle) const 1.32 +{ 1.33 + const float *src = handle == HANDLE_LOW ? low : high; 1.34 + 1.35 + if(channel == -1) { 1.36 + return src[0]; // XXX this doens't make much sense 1.37 + } 1.38 + return src[channel]; 1.39 +} 1.40 + 1.41 +int TransferWindow::nearest_handle(int channel, float pos) const 1.42 +{ 1.43 + float ldist = 0, hdist = 0; 1.44 + 1.45 + if(channel == -1) { 1.46 + for(int i=0; i<3; i++) { 1.47 + ldist += fabs(low[i] - pos); 1.48 + hdist += fabs(high[i] - pos); 1.49 + } 1.50 + } else { 1.51 + ldist = fabs(low[channel] - pos); 1.52 + hdist = fabs(high[channel] - pos); 1.53 + } 1.54 + return ldist <= hdist ? HANDLE_LOW : HANDLE_HIGH; 1.55 +} 1.56 + 1.57 void TransferWindow::set_interval(float a, float b) 1.58 { 1.59 float v0 = std::min(a, b); 1.60 float v1 = std::max(a, b); 1.61 1.62 - for(int i=0; i<4; i++) { 1.63 + for(int i=0; i<3; i++) { 1.64 low[i] = v0; 1.65 high[i] = v1; 1.66 } 1.67 @@ -30,7 +68,7 @@ 1.68 1.69 void TransferWindow::set_interval(float *rgba_low, float *rgba_high) 1.70 { 1.71 - for(int i=0; i<4; i++) { 1.72 + for(int i=0; i<3; i++) { 1.73 low[i] = std::min(rgba_low[i], rgba_high[i]); 1.74 high[i] = std::max(rgba_low[i], rgba_high[i]); 1.75 } 1.76 @@ -42,6 +80,26 @@ 1.77 high[channel] = std::max(a, b); 1.78 } 1.79 1.80 +void TransferWindow::get_interval(float *aptr, float *bptr) const 1.81 +{ 1.82 + *aptr = low[0]; 1.83 + *bptr = high[0]; 1.84 +} 1.85 + 1.86 +void TransferWindow::get_interval_rgba(float *rgba_low, float *rgba_high) const 1.87 +{ 1.88 + for(int i=0; i<3; i++) { 1.89 + rgba_low[i] = low[i]; 1.90 + rgba_high[i] = high[i]; 1.91 + } 1.92 +} 1.93 + 1.94 +void TransferWindow::get_interval_rgba(int channel, float *aptr, float *bptr) const 1.95 +{ 1.96 + *aptr = low[channel]; 1.97 + *bptr = high[channel]; 1.98 +} 1.99 + 1.100 void TransferWindow::set_soft_radius(float s) 1.101 { 1.102 soft_rad = s; 1.103 @@ -63,15 +121,17 @@ 1.104 1.105 float TransferWindow::map(float x) const 1.106 { 1.107 - return smoothstep(low[3] - soft_rad, high[3] - soft_rad, x) * 1.108 - (1.0 - smoothstep(low[3] + soft_rad, high[3] + soft_rad, x)); 1.109 + float rgb[3]; 1.110 + map(x, rgb); 1.111 + 1.112 + return std::max(rgb[0], std::max(rgb[1], rgb[2])); 1.113 } 1.114 1.115 -void TransferWindow::map(float x, float *rgba_value) const 1.116 +void TransferWindow::map(float x, float *rgb_value) const 1.117 { 1.118 - for(int i=0; i<4; i++) { 1.119 - float val = smoothstep(low[i] - soft_rad, high[i] - soft_rad, x); 1.120 - val *= 1.0 - smoothstep(low[i] + soft_rad, high[i] + soft_rad, x); 1.121 - rgba_value[i] = val; 1.122 + for(int i=0; i<3; i++) { 1.123 + float val = smoothstep(low[i] - soft_rad, low[i] + soft_rad, x); 1.124 + val *= 1.0 - smoothstep(high[i] - soft_rad, high[i] + soft_rad, x); 1.125 + rgb_value[i] = val; 1.126 } 1.127 }