Add get_color_at_offset(). Ensure correct points order.

This commit is contained in:
Biliogadafr 2015-05-26 22:17:54 +03:00
parent df9d48d9b5
commit 3f975965e9
3 changed files with 67 additions and 38 deletions

View File

@ -528,35 +528,7 @@ void Particles2D::_notification(int p_what) {
if(color_ramp.is_valid()) if(color_ramp.is_valid())
{ {
Vector<ColorRamp::Point>& color_points = color_ramp->get_points(); color = color_ramp->get_color_at_offset(ptime);
int cpos=0;
while(cpos<color_points.size()) {
if (color_points[cpos].offset > ptime)
break;
cpos++;
}
cpos--;
//could be faster..
if (cpos==-1)
if(color_points.size())
color=color_points[0].color;//Extend color to the beginning
else
color=Color(1,1,1,1);//If no points just use white.
else {
if (cpos==color_points.size()-1)
color=color_points[cpos].color;
else {
float diff = (color_points[cpos+1].offset-color_points[cpos].offset);
if (diff>0)
color=color_points[cpos].color.linear_interpolate(color_points[cpos+1].color, (ptime - color_points[cpos].offset) / diff );
else
color=color_points[cpos+1].color;
}
}
} else } else
{ {
color = default_color; color = default_color;

View File

@ -17,6 +17,7 @@ ColorRamp::ColorRamp() {
points[0].offset = 0; points[0].offset = 0;
points[1].color = Color(1,1,1,1); points[1].color = Color(1,1,1,1);
points[1].offset = 1; points[1].offset = 1;
is_sorted = true;
} }
ColorRamp::~ColorRamp() { ColorRamp::~ColorRamp() {
@ -25,9 +26,6 @@ ColorRamp::~ColorRamp() {
void ColorRamp::_bind_methods() { void ColorRamp::_bind_methods() {
//ObjectTypeDB::bind_method(_MD("set_offset", "pos", "offset"),&ColorRamp::set_offset);
//ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_OFFSETS),&ColorRamp::get_offset);
ObjectTypeDB::bind_method(_MD(COLOR_RAMP_SET_OFFSETS,"offsets"),&ColorRamp::set_offsets); ObjectTypeDB::bind_method(_MD(COLOR_RAMP_SET_OFFSETS,"offsets"),&ColorRamp::set_offsets);
ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_OFFSETS),&ColorRamp::get_offsets); ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_OFFSETS),&ColorRamp::get_offsets);
@ -58,19 +56,22 @@ Vector<Color> ColorRamp::get_colors() const {
return colors; return colors;
} }
void ColorRamp::set_offsets(const Vector<float>& offsets) { void ColorRamp::set_offsets(const Vector<float>& p_offsets) {
points.resize(offsets.size()); points.resize(p_offsets.size());
for(int i = 0; i < points.size(); i++) for(int i = 0; i < points.size(); i++)
{ {
points[i].offset = offsets[i]; points[i].offset = p_offsets[i];
} }
is_sorted = false;
} }
void ColorRamp::set_colors(const Vector<Color>& colors) { void ColorRamp::set_colors(const Vector<Color>& p_colors) {
points.resize(colors.size()); if(points.size()<p_colors.size())
is_sorted = false;
points.resize(p_colors.size());
for(int i = 0; i < points.size(); i++) for(int i = 0; i < points.size(); i++)
{ {
points[i].color = colors[i]; points[i].color = p_colors[i];
} }
} }
@ -80,12 +81,14 @@ Vector<ColorRamp::Point>& ColorRamp::get_points() {
void ColorRamp::set_points(Vector<ColorRamp::Point>& p_points) { void ColorRamp::set_points(Vector<ColorRamp::Point>& p_points) {
points = p_points; points = p_points;
is_sorted = false;
} }
void ColorRamp::set_offset(int pos, const float offset) { void ColorRamp::set_offset(int pos, const float offset) {
if(points.size() <= pos) if(points.size() <= pos)
points.resize(pos + 1); points.resize(pos + 1);
points[pos].offset = offset; points[pos].offset = offset;
is_sorted = false;
} }
float ColorRamp::get_offset(int pos) const { float ColorRamp::get_offset(int pos) const {
@ -96,7 +99,10 @@ float ColorRamp::get_offset(int pos) const {
void ColorRamp::set_color(int pos, const Color& color) { void ColorRamp::set_color(int pos, const Color& color) {
if(points.size() <= pos) if(points.size() <= pos)
{
points.resize(pos + 1); points.resize(pos + 1);
is_sorted = false;
}
points[pos].color = color; points[pos].color = color;
} }
@ -106,6 +112,54 @@ Color ColorRamp::get_color(int pos) const {
return Color(0,0,0,1); //TODO: Maybe throw some error instead? return Color(0,0,0,1); //TODO: Maybe throw some error instead?
} }
Color ColorRamp::get_color_at_offset(float p_offset) {
if (points.empty())
return Color(0,0,0,1);
if (points.size() == 1)
return points[0].color;
if(!is_sorted)
{
points.sort();
is_sorted = true;
}
//binary search
int low = 0;
int high = points.size() -1;
int middle;
while( low <= high )
{
middle = ( low + high ) / 2;
Point& point = points[middle];
if( point.offset > p_offset ) {
high = middle - 1; //search low end of array
} else if ( point.offset < p_offset) {
low = middle + 1; //search high end of array
} else {
return point.color;
}
}
//return interpolated value
if (points[middle].offset>p_offset)
{
middle--;
}
int first=middle;
int second=middle+1;
if(second>=points.size())
return points[points.size()-1].color;
if(first<0)
return points[0].color;
Point& pointFirst = points[first];
Point& pointSecond = points[second];
return pointFirst.color.linear_interpolate(pointSecond.color, (p_offset-pointFirst.offset)/(pointSecond.offset - pointFirst.offset));
}
int ColorRamp::get_points_count() const { int ColorRamp::get_points_count() const {
return points.size(); return points.size();
} }

View File

@ -23,6 +23,7 @@ public:
private: private:
Vector<Point> points; Vector<Point> points;
bool is_sorted;
protected: protected:
static void _bind_methods(); static void _bind_methods();
@ -46,6 +47,8 @@ public:
void set_colors(const Vector<Color>& colors); void set_colors(const Vector<Color>& colors);
Vector<Color> get_colors() const; Vector<Color> get_colors() const;
Color get_color_at_offset(float offset);
int get_points_count() const; int get_points_count() const;
}; };