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  }