glviewvol
view src/xfermap.cc @ 11:73edd1b7c2da
changed the name to glviewvol
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 31 Dec 2014 07:53:53 +0200 |
parents | f22be47a3572 |
children | 773f89037a35 |
line source
1 #include <math.h>
2 #include <algorithm>
3 #include "xfermap.h"
5 TransferFunc::~TransferFunc()
6 {
7 }
10 // ---- TransferWindow ----
12 TransferWindow::TransferWindow()
13 {
14 soft_rad = 0.5;
15 for(int i=0; i<3; i++) {
16 low[i] = 0.5;
17 high[i] = 1.5;
18 }
19 }
21 void TransferWindow::set_handle(int channel, int handle, float val)
22 {
23 float *dest = handle == HANDLE_LOW ? low : high;
25 if(channel == -1) {
26 dest[0] = dest[1] = dest[2] = val;
27 } else {
28 dest[channel] = val;
29 }
30 }
32 float TransferWindow::get_handle(int channel, int handle) const
33 {
34 const float *src = handle == HANDLE_LOW ? low : high;
36 if(channel == -1) {
37 return src[0]; // XXX this doens't make much sense
38 }
39 return src[channel];
40 }
42 int TransferWindow::nearest_handle(int channel, float pos) const
43 {
44 float ldist = 0, hdist = 0;
46 if(channel == -1) {
47 for(int i=0; i<3; i++) {
48 ldist += fabs(low[i] - pos);
49 hdist += fabs(high[i] - pos);
50 }
51 } else {
52 ldist = fabs(low[channel] - pos);
53 hdist = fabs(high[channel] - pos);
54 }
55 return ldist <= hdist ? HANDLE_LOW : HANDLE_HIGH;
56 }
58 void TransferWindow::set_interval(float a, float b)
59 {
60 float v0 = std::min(a, b);
61 float v1 = std::max(a, b);
63 for(int i=0; i<3; i++) {
64 low[i] = v0;
65 high[i] = v1;
66 }
67 }
69 void TransferWindow::set_interval(float *rgba_low, float *rgba_high)
70 {
71 for(int i=0; i<3; i++) {
72 low[i] = std::min(rgba_low[i], rgba_high[i]);
73 high[i] = std::max(rgba_low[i], rgba_high[i]);
74 }
75 }
77 void TransferWindow::set_interval_rgba(int channel, float a, float b)
78 {
79 low[channel] = std::min(a, b);
80 high[channel] = std::max(a, b);
81 }
83 void TransferWindow::get_interval(float *aptr, float *bptr) const
84 {
85 *aptr = low[0];
86 *bptr = high[0];
87 }
89 void TransferWindow::get_interval_rgba(float *rgba_low, float *rgba_high) const
90 {
91 for(int i=0; i<3; i++) {
92 rgba_low[i] = low[i];
93 rgba_high[i] = high[i];
94 }
95 }
97 void TransferWindow::get_interval_rgba(int channel, float *aptr, float *bptr) const
98 {
99 *aptr = low[channel];
100 *bptr = high[channel];
101 }
103 void TransferWindow::set_soft_radius(float s)
104 {
105 soft_rad = s;
106 }
108 float TransferWindow::get_soft_radius() const
109 {
110 return soft_rad;
111 }
113 static inline float smoothstep(float a, float b, float x)
114 {
115 if(x < a) return 0.0f;
116 if(x >= b) return 1.0f;
118 float t = (x - a) / (b - a);
119 return t * t * (3.0f - 2.0f * t);
120 }
122 float TransferWindow::map(float x) const
123 {
124 float rgb[3];
125 map(x, rgb);
127 return std::max(rgb[0], std::max(rgb[1], rgb[2]));
128 }
130 void TransferWindow::map(float x, float *rgb_value) const
131 {
132 for(int i=0; i<3; i++) {
133 float val = smoothstep(low[i] - soft_rad, low[i] + soft_rad, x);
134 val *= 1.0 - smoothstep(high[i] - soft_rad, high[i] + soft_rad, x);
135 rgb_value[i] = val;
136 }
137 }