Add get_color_at_offset(). Ensure correct points order.
This commit is contained in:
parent
df9d48d9b5
commit
3f975965e9
@ -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;
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user