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