Replace color phases with color ramp for Particles2D.

This commit is contained in:
Biliogadafr 2015-05-24 21:18:52 +03:00
parent f8f3362cab
commit df9d48d9b5
13 changed files with 836 additions and 69 deletions

View file

@ -503,19 +503,6 @@ void Particles2D::_notification(int p_what) {
if (!local_space)
invxform=get_global_transform().affine_inverse();
int col_count=0;
float last=-1;
ColorPhase cphase[MAX_COLOR_PHASES];
for(int i=0;i<color_phase_count;i++) {
if (color_phases[i].pos<=last)
break;
cphase[i]=color_phases[i];
col_count++;
}
int start_particle = (int)(time * (float)particle_count / lifetime);
for (int id=0;id<particle_count;++id) {
@ -537,32 +524,42 @@ void Particles2D::_notification(int p_what) {
uint32_t rand_seed=p.seed*(i+1);
int cpos=0;
while(cpos<col_count) {
if (cphase[cpos].pos > ptime)
break;
cpos++;
}
cpos--;
Color color;
//could be faster..
if (cpos==-1)
color=Color(1,1,1,1);
else {
if (cpos==col_count-1)
color=cphase[cpos].color;
else {
float diff = (cphase[cpos+1].pos-cphase[cpos].pos);
if (diff>0)
color=cphase[cpos].color.linear_interpolate(cphase[cpos+1].color, (ptime - cphase[cpos].pos) / diff );
else
color=cphase[cpos+1].color;
if(color_ramp.is_valid())
{
Vector<ColorRamp::Point>& color_points = color_ramp->get_points();
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
{
color = default_color;
}
@ -813,6 +810,27 @@ Ref<Texture> Particles2D::get_texture() const {
return texture;
}
void Particles2D::set_color(const Color& p_color) {
default_color = p_color;
}
Color Particles2D::get_color() const {
return default_color;
}
void Particles2D::set_color_ramp(const Ref<ColorRamp>& p_color_ramp) {
color_ramp=p_color_ramp;
}
Ref<ColorRamp> Particles2D::get_color_ramp() const {
return color_ramp;
}
void Particles2D::set_emissor_offset(const Point2& p_offset) {
emissor_offset=p_offset;
@ -834,40 +852,76 @@ bool Particles2D::is_using_local_space() const {
return local_space;
}
//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phases(int p_phases) {
ERR_FAIL_INDEX(p_phases,MAX_COLOR_PHASES+1);
color_phase_count=p_phases;
//Create color ramp if we have 2 or more phases.
//Otherwise first phase phase will be assigned to default color.
if(p_phases > 1 && color_ramp.is_null())
{
color_ramp = Ref<ColorRamp>(memnew (ColorRamp()));
}
if(color_ramp.is_valid())
{
color_ramp->get_points().resize(p_phases);
}
}
//Deprecated.
int Particles2D::get_color_phases() const {
return color_phase_count;
if(color_ramp.is_valid())
{
return color_ramp->get_points_count();
}
return 0;
}
//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phase_color(int p_phase,const Color& p_color) {
ERR_FAIL_INDEX(p_phase,MAX_COLOR_PHASES);
color_phases[p_phase].color=p_color;
if(color_ramp.is_valid())
{
if(color_ramp->get_points_count() > p_phase)
color_ramp->set_color(p_phase, p_color);
} else
{
if(p_phase == 0)
default_color = p_color;
}
}
//Deprecated.
Color Particles2D::get_color_phase_color(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase,MAX_COLOR_PHASES,Color());
return color_phases[p_phase].color;
if(color_ramp.is_valid())
{
return color_ramp->get_color(p_phase);
}
return Color(0,0,0,1);
}
//Deprecated. Converts color phases to color ramp
void Particles2D::set_color_phase_pos(int p_phase,float p_pos) {
ERR_FAIL_INDEX(p_phase,MAX_COLOR_PHASES);
ERR_FAIL_COND(p_pos<0.0 || p_pos>1.0);
color_phases[p_phase].pos=p_pos;
if(color_ramp.is_valid() && color_ramp->get_points_count() > p_phase)
{
return color_ramp->set_offset(p_phase, p_pos);
}
}
//Deprecated.
float Particles2D::get_color_phase_pos(int p_phase) const {
ERR_FAIL_INDEX_V(p_phase,MAX_COLOR_PHASES,0);
return color_phases[p_phase].pos;
if(color_ramp.is_valid())
{
return color_ramp->get_offset(p_phase);
}
return 0;
}
void Particles2D::set_emission_half_extents(const Vector2& p_extents) {
@ -997,6 +1051,12 @@ void Particles2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_texture:Texture","texture"),&Particles2D::set_texture);
ObjectTypeDB::bind_method(_MD("get_texture:Texture"),&Particles2D::get_texture);
ObjectTypeDB::bind_method(_MD("set_color","color"),&Particles2D::set_color);
ObjectTypeDB::bind_method(_MD("get_color"),&Particles2D::get_color);
ObjectTypeDB::bind_method(_MD("set_color_ramp:ColorRamp","color_ramp"),&Particles2D::set_color_ramp);
ObjectTypeDB::bind_method(_MD("get_color_ramp:ColorRamp"),&Particles2D::get_color_ramp);
ObjectTypeDB::bind_method(_MD("set_emissor_offset","offset"),&Particles2D::set_emissor_offset);
ObjectTypeDB::bind_method(_MD("get_emissor_offset"),&Particles2D::get_emissor_offset);
@ -1055,7 +1115,6 @@ void Particles2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::INT,"config/v_frames",PROPERTY_HINT_RANGE,"1,512,1"),_SCS("set_v_frames"),_SCS("get_v_frames"));
for(int i=0;i<PARAM_MAX;i++) {
ADD_PROPERTYI(PropertyInfo(Variant::REAL,_particlesframe_property_names[i],PROPERTY_HINT_RANGE,_particlesframe_property_ranges[i]),_SCS("set_param"),_SCS("get_param"),i);
}
@ -1064,14 +1123,17 @@ void Particles2D::_bind_methods() {
ADD_PROPERTYI(PropertyInfo(Variant::REAL,_particlesframe_property_rnames[i],PROPERTY_HINT_RANGE,"-1,1,0.01"),_SCS("set_randomness"),_SCS("get_randomness"),i);
}
ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1"), _SCS("set_color_phases"), _SCS("get_color_phases"));
ADD_PROPERTY( PropertyInfo( Variant::INT, "color_phases/count",PROPERTY_HINT_RANGE,"0,4,1", 0), _SCS("set_color_phases"), _SCS("get_color_phases"));
//Backward compatibility. They will be converted to color ramp
for(int i=0;i<MAX_COLOR_PHASES;i++) {
String phase="phase_"+itos(i)+"/";
ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_color_phase_pos"),_SCS("get_color_phase_pos"),i );
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color"),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
ADD_PROPERTYI( PropertyInfo( Variant::REAL, phase+"pos", PROPERTY_HINT_RANGE,"0,1,0.01", 0),_SCS("set_color_phase_pos"),_SCS("get_color_phase_pos"),i );
ADD_PROPERTYI( PropertyInfo( Variant::COLOR, phase+"color", PROPERTY_HINT_NONE, "", 0),_SCS("set_color_phase_color"),_SCS("get_color_phase_color"),i );
}
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "color/color"),_SCS("set_color"),_SCS("get_color"));
ADD_PROPERTY(PropertyInfo(Variant::OBJECT,"color/color_ramp",PROPERTY_HINT_RESOURCE_TYPE,"ColorRamp"),_SCS("set_color_ramp"),_SCS("get_color_ramp"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2_ARRAY,"emission_points",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("set_emission_points"),_SCS("get_emission_points"));
@ -1097,8 +1159,6 @@ void Particles2D::_bind_methods() {
}
Particles2D::Particles2D() {
for(int i=0;i<PARAM_MAX;i++) {
@ -1118,6 +1178,7 @@ Particles2D::Particles2D() {
set_param(PARAM_FINAL_SIZE,1.0);
set_param(PARAM_ANIM_SPEED_SCALE,1.0);
set_color(Color(1,1,1,1));
time=0;
lifetime=2;
@ -1129,17 +1190,6 @@ Particles2D::Particles2D() {
preprocess=0;
time_scale=1.0;
color_phase_count=1;
set_color_phase_pos(0,0.0);
set_color_phase_pos(1,1.0);
set_color_phase_pos(2,1.0);
set_color_phase_pos(3,1.0);
set_color_phase_color(0,Color(1,1,1));
set_color_phase_color(1,Color(0,0,0));
set_color_phase_color(2,Color(0,0,0));
set_color_phase_color(3,Color(0,0,0));
flip_h=false;
flip_v=false;

View file

@ -31,6 +31,7 @@
#include "scene/2d/node_2d.h"
#include "scene/resources/texture.h"
#include "scene/resources/color_ramp.h"
class Particles2D;
class ParticleAttractor2D : public Node2D {
@ -125,11 +126,6 @@ private:
};
Vector<Particle> particles;
int color_phase_count;
struct ColorPhase {
Color color;
float pos;
} color_phases[MAX_COLOR_PHASES];
struct AttractorCache {
@ -161,6 +157,9 @@ private:
Ref<Texture> texture;
//If no color ramp is set then default color is used. Created as simple alternative to color_ramp.
Color default_color;
Ref<ColorRamp> color_ramp;
void testee(int a, int b, int c, int d, int e);
void _process_particles(float p_delta);
@ -230,6 +229,12 @@ public:
void set_texture(const Ref<Texture>& p_texture);
Ref<Texture> get_texture() const;
void set_color(const Color& p_color);
Color get_color() const;
void set_color_ramp(const Ref<ColorRamp>& p_texture);
Ref<ColorRamp> get_color_ramp() const;
void set_emissor_offset(const Point2& p_offset);
Point2 get_emissor_offset() const;

View file

@ -0,0 +1,368 @@
#include "color_ramp_edit.h"
#include "os/keyboard.h"
ColorRampEdit::ColorRampEdit(){
grabbed=-1;
grabbing=false;
set_focus_mode(FOCUS_ALL);
popup = memnew( PopupPanel );
picker = memnew( ColorPicker );
popup->add_child(picker);
popup->set_child_rect(picker);
add_child(popup);
checker = Ref<ImageTexture>(memnew( ImageTexture ));
checker->create_from_image( Image(checker_bg_png),ImageTexture::FLAG_REPEAT );
}
int ColorRampEdit::_get_point_from_pos(int x) {
int result = -1;
int total_w = get_size().width-get_size().height-3;
for(int i=0;i<points.size();i++) {
//Check if we clicked at point
if (ABS(x-points[i].offset*total_w+1)<(POINT_WIDTH/2+1)) {
result=i;
}
}
return result;
}
void ColorRampEdit::_show_color_picker() {
if (grabbed==-1)
return;
Size2 ms = Size2(350, picker->get_combined_minimum_size().height+10);
picker->set_color(points[grabbed].color);
popup->set_pos(get_global_pos()-Vector2(ms.width-get_size().width,ms.height));
popup->set_size(ms);
popup->popup();
}
ColorRampEdit::~ColorRampEdit() {
}
void ColorRampEdit::_input_event(const InputEvent& p_event) {
if (p_event.type==InputEvent::KEY && p_event.key.pressed && p_event.key.scancode==KEY_DELETE && grabbed!=-1) {
points.remove(grabbed);
grabbed=-1;
update();
emit_signal("ramp_changed");
accept_event();
}
//Show color picker on double click.
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.doubleclick && p_event.mouse_button.pressed) {
grabbed=_get_point_from_pos(p_event.mouse_button.x);
_show_color_picker();
accept_event();
}
//Delete point on right click
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==2 && p_event.mouse_button.pressed) {
grabbed=_get_point_from_pos(p_event.mouse_button.x);
if(grabbed != -1)
{
points.remove(grabbed);
grabbed=-1;
update();
emit_signal("ramp_changed");
accept_event();
}
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
update();
int x = p_event.mouse_button.x;
int total_w = get_size().width-get_size().height-3;
//Check if color selector was clicked.
if (x>total_w+3) {
_show_color_picker();
return;
}
grabbing=true;
grabbed=_get_point_from_pos(x);
//grab or select
if (grabbed!=-1) {
return;
}
//insert
ColorRamp::Point newPoint;
newPoint.offset=CLAMP(x/float(total_w),0,1);
ColorRamp::Point prev;
ColorRamp::Point next;
int pos=-1;
for(int i=0;i<points.size();i++) {
if (points[i].offset<newPoint.offset)
pos=i;
}
if (pos==-1) {
prev.color=Color(0,0,0);
prev.offset=0;
if (points.size()) {
next=points[0];
} else {
next.color=Color(1,1,1);
next.offset=1.0;
}
} else {
if (pos==points.size()-1) {
next.color=Color(1,1,1);
next.offset=1.0;
} else {
next=points[pos+1];
}
prev=points[pos];
}
newPoint.color=prev.color.linear_interpolate(next.color,(newPoint.offset-prev.offset)/(next.offset-prev.offset));
points.push_back(newPoint);
points.sort();
for(int i=0;i<points.size();i++) {
if (points[i].offset==newPoint.offset) {
grabbed=i;
break;
}
}
emit_signal("ramp_changed");
}
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && !p_event.mouse_button.pressed) {
if (grabbing) {
grabbing=false;
emit_signal("ramp_changed");
}
update();
}
if (p_event.type==InputEvent::MOUSE_MOTION && grabbing) {
int total_w = get_size().width-get_size().height-3;
int x = p_event.mouse_motion.x;
float newofs = CLAMP(x/float(total_w),0,1);
bool valid=true;
for(int i=0;i<points.size();i++) {
if (points[i].offset==newofs && i!=grabbed) {
valid=false;
}
}
if (!valid)
return;
points[grabbed].offset=newofs;
points.sort();
for(int i=0;i<points.size();i++) {
if (points[i].offset==newofs) {
grabbed=i;
break;
}
}
emit_signal("ramp_changed");
update();
}
}
void ColorRampEdit::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_TREE) {
picker->connect("color_changed",this,"_color_changed");
}
if (p_what==NOTIFICATION_DRAW) {
int w = get_size().x;
int h = get_size().y;
if (w == 0 || h == 0)
return; //Safety check. We have division by 'h'. And in any case there is nothing to draw with such size
int total_w = get_size().width-get_size().height-3;
//Draw checker pattern for ramp
_draw_checker(0,0, total_w, h);
//Draw color ramp
ColorRamp::Point prev;
prev.offset=0;
if(points.size() == 0)
prev.color=Color(0,0,0); //Draw black rectangle if we have no points
else
prev.color = points[0].color; //Extend color of first point to the beginning.
for(int i=-1;i<points.size();i++) {
ColorRamp::Point next;
//If there is no next point
if (i+1 == points.size()) {
if(points.size() == 0)
next.color=Color(0,0,0); //Draw black rectangle if we have no points
else
next.color=points[i].color; //Extend color of last point to the end.
next.offset=1;
} else {
next=points[i+1];
}
if (prev.offset==next.offset) {
prev=next;
continue;
}
Vector<Vector2> points;
Vector<Color> colors;
points.push_back(Vector2(prev.offset*total_w,h));
points.push_back(Vector2(prev.offset*total_w,0));
points.push_back(Vector2(next.offset*total_w,0));
points.push_back(Vector2(next.offset*total_w,h));
colors.push_back(prev.color);
colors.push_back(prev.color);
colors.push_back(next.color);
colors.push_back(next.color);
draw_primitive(points,colors,Vector<Point2>());
prev=next;
}
//Draw point markers
for(int i=0;i<points.size();i++) {
Color col = i==grabbed?Color(1,0.0,0.0,0.9):points[i].color.contrasted();
col.a = 0.9;
draw_line(Vector2(points[i].offset*total_w,0),Vector2(points[i].offset*total_w,h/2),col);
draw_rect(Rect2(points[i].offset*total_w-POINT_WIDTH/2, h/2, POINT_WIDTH, h/2), Color(0.6, 0.6, 0.6, i==grabbed?0.9:0.4));
draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w-POINT_WIDTH/2,h-1),col);
draw_line(Vector2(points[i].offset*total_w+POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h-1),col);
draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h/2),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h/2),col);
draw_line(Vector2(points[i].offset*total_w-POINT_WIDTH/2,h-1),Vector2(points[i].offset*total_w+POINT_WIDTH/2,h-1),col);
}
//Draw "button" for color selector
_draw_checker(total_w+3,0, h, h);
if (grabbed!=-1) {
//Draw with selection color
draw_rect(Rect2(total_w+3,0,h,h),points[grabbed].color);
} else {
//if no color selected draw grey color with 'X' on top.
draw_rect(Rect2(total_w+3,0,h,h), Color(0.5, 0.5, 0.5, 1));
draw_line(Vector2(total_w+3,0),Vector2(total_w+3+h,h),Color(1,1,1,0.6));
draw_line(Vector2(total_w+3,h),Vector2(total_w+3+h,0),Color(1,1,1,0.6));
}
//Draw borders around color ramp if in focus
if (has_focus()) {
draw_line(Vector2(-1,-1),Vector2(total_w+1,-1),Color(1,1,1,0.6));
draw_line(Vector2(total_w+1,-1),Vector2(total_w+1,h+1),Color(1,1,1,0.6));
draw_line(Vector2(total_w+1,h+1),Vector2(-1,h+1),Color(1,1,1,0.6));
draw_line(Vector2(-1,-1),Vector2(-1,h+1),Color(1,1,1,0.6));
}
}
}
void ColorRampEdit::_draw_checker(int x, int y, int w, int h) {
//Draw it with polygon to insert UVs for scale
Vector<Vector2> backPoints;
backPoints.push_back(Vector2(x, y));
backPoints.push_back(Vector2(x, y+h));
backPoints.push_back(Vector2(x+w, y+h));
backPoints.push_back(Vector2(x+w, y));
Vector<Color> colorPoints;
colorPoints.push_back(Color(1, 1, 1, 1));
colorPoints.push_back(Color(1, 1, 1, 1));
colorPoints.push_back(Color(1, 1, 1, 1));
colorPoints.push_back(Color(1, 1, 1, 1));
Vector<Vector2> uvPoints;
//Draw checker pattern pixel-perfect and scale it by 2.
uvPoints.push_back(Vector2(x, y));
uvPoints.push_back(Vector2(x, y+h*.5f/checker->get_height()));
uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y+h*.5f/checker->get_height()));
uvPoints.push_back(Vector2(x+w*.5f/checker->get_width(), y));
draw_polygon(backPoints, colorPoints, uvPoints, checker);
}
Size2 ColorRampEdit::get_minimum_size() const {
return Vector2(0,16);
}
void ColorRampEdit::_color_changed(const Color& p_color) {
if (grabbed==-1)
return;
points[grabbed].color=p_color;
update();
emit_signal("ramp_changed");
}
void ColorRampEdit::set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors) {
ERR_FAIL_COND(p_offsets.size()!=p_colors.size());
points.clear();
for(int i=0;i<p_offsets.size();i++) {
ColorRamp::Point p;
p.offset=p_offsets[i];
p.color=p_colors[i];
points.push_back(p);
}
points.sort();
update();
}
Vector<float> ColorRampEdit::get_offsets() const {
Vector<float> ret;
for(int i=0;i<points.size();i++)
ret.push_back(points[i].offset);
return ret;
}
Vector<Color> ColorRampEdit::get_colors() const {
Vector<Color> ret;
for(int i=0;i<points.size();i++)
ret.push_back(points[i].color);
return ret;
}
void ColorRampEdit::set_points(Vector<ColorRamp::Point>& p_points) {
if(points.size() != p_points.size())
grabbed = -1;
points.clear();
points = p_points;
}
Vector<ColorRamp::Point>& ColorRampEdit::get_points() {
return points;
}
void ColorRampEdit::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&ColorRampEdit::_input_event);
ObjectTypeDB::bind_method(_MD("_color_changed"),&ColorRampEdit::_color_changed);
ADD_SIGNAL(MethodInfo("ramp_changed"));
}

View file

@ -0,0 +1,52 @@
#ifndef SCENE_GUI_COLOR_RAMP_EDIT_H_
#define SCENE_GUI_COLOR_RAMP_EDIT_H_
#include "scene/gui/popup.h"
#include "scene/gui/color_picker.h"
#include "scene/resources/color_ramp.h"
#include "scene/resources/default_theme/theme_data.h"
#define POINT_WIDTH 8
class ColorRampEdit : public Control {
OBJ_TYPE(ColorRampEdit,Control);
PopupPanel *popup;
ColorPicker *picker;
Ref<ImageTexture> checker;
bool grabbing;
int grabbed;
Vector<ColorRamp::Point> points;
void _draw_checker(int x, int y, int w, int h);
void _color_changed(const Color& p_color);
int _get_point_from_pos(int x);
void _show_color_picker();
protected:
void _input_event(const InputEvent& p_event);
void _notification(int p_what);
static void _bind_methods();
public:
void set_ramp(const Vector<float>& p_offsets,const Vector<Color>& p_colors);
Vector<float> get_offsets() const;
Vector<Color> get_colors() const;
void set_points(Vector<ColorRamp::Point>& p_points);
Vector<ColorRamp::Point>& get_points();
virtual Size2 get_minimum_size() const;
ColorRampEdit();
virtual ~ColorRampEdit();
};
/*class ColorRampEditPanel : public Panel
{
OBJ_TYPE(ColorRampEditPanel, Panel );
};*/
#endif /* SCENE_GUI_COLOR_RAMP_EDIT_H_ */

View file

@ -170,6 +170,7 @@
#include "scene/resources/audio_stream.h"
#include "scene/resources/gibberish_stream.h"
#include "scene/resources/bit_mask.h"
#include "scene/resources/color_ramp.h"
#include "scene/scene_string_names.h"
@ -565,6 +566,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<PolygonPathFinder>();
ObjectTypeDB::register_type<BitMap>();
ObjectTypeDB::register_type<ColorRamp>();
OS::get_singleton()->yield(); //may take time to init

View file

@ -0,0 +1,111 @@
/*
* color_ramp.h
*/
#include "color_ramp.h"
//setter and getter names for property serialization
#define COLOR_RAMP_GET_OFFSETS "get_offsets"
#define COLOR_RAMP_GET_COLORS "get_colors"
#define COLOR_RAMP_SET_OFFSETS "set_offsets"
#define COLOR_RAMP_SET_COLORS "set_colors"
ColorRamp::ColorRamp() {
//Set initial color ramp transition from black to white
points.resize(2);
points[0].color = Color(0,0,0,1);
points[0].offset = 0;
points[1].color = Color(1,1,1,1);
points[1].offset = 1;
}
ColorRamp::~ColorRamp() {
}
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_GET_OFFSETS),&ColorRamp::get_offsets);
ObjectTypeDB::bind_method(_MD(COLOR_RAMP_SET_COLORS,"colors"),&ColorRamp::set_colors);
ObjectTypeDB::bind_method(_MD(COLOR_RAMP_GET_COLORS),&ColorRamp::get_colors);
ADD_PROPERTY( PropertyInfo(Variant::REAL,"offsets"),_SCS(COLOR_RAMP_SET_OFFSETS),_SCS(COLOR_RAMP_GET_OFFSETS) );
ADD_PROPERTY( PropertyInfo(Variant::REAL,"colors"),_SCS(COLOR_RAMP_SET_COLORS),_SCS(COLOR_RAMP_GET_COLORS) );
}
Vector<float> ColorRamp::get_offsets() const {
Vector<float> offsets;
offsets.resize(points.size());
for(int i = 0; i < points.size(); i++)
{
offsets[i] = points[i].offset;
}
return offsets;
}
Vector<Color> ColorRamp::get_colors() const {
Vector<Color> colors;
colors.resize(points.size());
for(int i = 0; i < points.size(); i++)
{
colors[i] = points[i].color;
}
return colors;
}
void ColorRamp::set_offsets(const Vector<float>& offsets) {
points.resize(offsets.size());
for(int i = 0; i < points.size(); i++)
{
points[i].offset = offsets[i];
}
}
void ColorRamp::set_colors(const Vector<Color>& colors) {
points.resize(colors.size());
for(int i = 0; i < points.size(); i++)
{
points[i].color = colors[i];
}
}
Vector<ColorRamp::Point>& ColorRamp::get_points() {
return points;
}
void ColorRamp::set_points(Vector<ColorRamp::Point>& p_points) {
points = p_points;
}
void ColorRamp::set_offset(int pos, const float offset) {
if(points.size() <= pos)
points.resize(pos + 1);
points[pos].offset = offset;
}
float ColorRamp::get_offset(int pos) const {
if(points.size() > pos)
return points[pos].offset;
return 0; //TODO: Maybe throw some error instead?
}
void ColorRamp::set_color(int pos, const Color& color) {
if(points.size() <= pos)
points.resize(pos + 1);
points[pos].color = color;
}
Color ColorRamp::get_color(int pos) const {
if(points.size() > pos)
return points[pos].color;
return Color(0,0,0,1); //TODO: Maybe throw some error instead?
}
int ColorRamp::get_points_count() const {
return points.size();
}

View file

@ -0,0 +1,52 @@
/*
* color_ramp.h
*/
#ifndef SCENE_RESOURCES_COLOR_RAMP_H_
#define SCENE_RESOURCES_COLOR_RAMP_H_
#include "resource.h"
class ColorRamp: public Resource {
OBJ_TYPE( ColorRamp, Resource );
OBJ_SAVE_TYPE( ColorRamp );
public:
struct Point {
float offset;
Color color;
bool operator<(const Point& p_ponit) const {
return offset<p_ponit.offset;
}
};
private:
Vector<Point> points;
protected:
static void _bind_methods();
public:
ColorRamp();
virtual ~ColorRamp();
void set_points(Vector<Point>& points);
Vector<Point>& get_points();
void set_offset(int pos, const float offset);
float get_offset(int pos) const;
void set_color(int pos, const Color& color);
Color get_color(int pos) const;
void set_offsets(const Vector<float>& offsets);
Vector<float> get_offsets() const;
void set_colors(const Vector<Color>& colors);
Vector<Color> get_colors() const;
int get_points_count() const;
};
#endif /* SCENE_RESOURCES_COLOR_RAMP_H_ */

Binary file not shown.

After

Width:  |  Height:  |  Size: 180 B

View file

@ -49,6 +49,11 @@ static const unsigned char checked_png[]={
};
static const unsigned char checker_bg_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x8,0x0,0x0,0x0,0x8,0x8,0x6,0x0,0x0,0x0,0xc4,0xf,0xbe,0x8b,0x0,0x0,0x0,0x1,0x73,0x52,0x47,0x42,0x0,0xae,0xce,0x1c,0xe9,0x0,0x0,0x0,0x4,0x67,0x41,0x4d,0x41,0x0,0x0,0xb1,0x8f,0xb,0xfc,0x61,0x5,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xe,0xc4,0x0,0x0,0xe,0xc4,0x1,0x95,0x2b,0xe,0x1b,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0xff,0x0,0xff,0x0,0xff,0xa0,0xbd,0xa7,0x93,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xde,0x9,0x14,0xd,0x1c,0x1b,0x52,0x41,0x72,0xa4,0x0,0x0,0x0,0x24,0x49,0x44,0x41,0x54,0x28,0x53,0x63,0xfc,0xf,0x4,0xc,0x48,0xa0,0xa1,0xa1,0x1,0xca,0x82,0x0,0x26,0x28,0x8d,0x13,0x50,0xae,0x80,0xb1,0xbe,0xbe,0x7e,0x60,0xdd,0xc0,0xc0,0x0,0x0,0x78,0x11,0x9,0x87,0x2b,0xa,0xe1,0x69,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
static const unsigned char close_png[]={
0x89,0x50,0x4e,0x47,0xd,0xa,0x1a,0xa,0x0,0x0,0x0,0xd,0x49,0x48,0x44,0x52,0x0,0x0,0x0,0x10,0x0,0x0,0x0,0x10,0x8,0x6,0x0,0x0,0x0,0x1f,0xf3,0xff,0x61,0x0,0x0,0x0,0x6,0x62,0x4b,0x47,0x44,0x0,0x73,0x0,0x29,0x0,0x7c,0x29,0x1e,0x61,0x18,0x0,0x0,0x0,0x9,0x70,0x48,0x59,0x73,0x0,0x0,0xb,0x13,0x0,0x0,0xb,0x13,0x1,0x0,0x9a,0x9c,0x18,0x0,0x0,0x0,0x7,0x74,0x49,0x4d,0x45,0x7,0xdd,0x9,0x19,0x1,0x14,0x3,0xf4,0x10,0x33,0xed,0x0,0x0,0x1,0x53,0x49,0x44,0x41,0x54,0x38,0xcb,0xcd,0x92,0xbd,0x4e,0x5b,0x41,0x10,0x85,0xbf,0xd9,0x9d,0xfd,0xb9,0xd7,0xb2,0xb9,0x81,0x8e,0x26,0xf4,0x69,0x53,0x50,0x44,0xa2,0x74,0x3,0xd,0xd,0x48,0x48,0xf4,0x3c,0x16,0x8f,0xc1,0x23,0xf0,0x0,0xf4,0x8e,0x90,0x11,0x96,0x25,0xa2,0x10,0x45,0x4a,0x9c,0x6b,0x4f,0xa,0xf6,0x4a,0xe6,0xc6,0x4e,0xb,0x47,0x5a,0xed,0xee,0x9c,0xd9,0xd1,0x99,0xb3,0x3,0x6f,0xd,0xd9,0x70,0xd7,0x72,0xfe,0xd3,0xe3,0x42,0xd9,0x5b,0xc0,0xba,0xa0,0xef,0x3d,0xfe,0xe0,0x9c,0x3b,0x35,0xb3,0x21,0xf0,0x1d,0xf8,0x5d,0xe2,0xd,0xf0,0xd9,0x39,0xf7,0xc5,0xcc,0xee,0x81,0x5f,0x9b,0xd4,0x4,0xe7,0xdc,0x65,0xd3,0x34,0x3f,0x53,0x4a,0x73,0xe0,0x18,0xd8,0x2b,0xeb,0x78,0x38,0x1c,0x3e,0xe5,0x9c,0x7f,0x38,0xe7,0x2e,0xd7,0xd4,0xfc,0x23,0xf1,0x30,0xc6,0x38,0x4b,0x29,0x59,0x8,0xe1,0x1e,0xb8,0x0,0x2e,0xea,0xba,0x7e,0xa8,0xaa,0xca,0x42,0x8,0x33,0xe0,0x70,0x5b,0x1,0x80,0x1d,0x60,0xac,0xaa,0x93,0x9c,0xb3,0xa9,0xea,0x63,0x8c,0x71,0x36,0x18,0xc,0x4c,0x55,0x27,0xc0,0xb8,0xe4,0xfc,0xd7,0xd4,0x5d,0xe0,0x5c,0x55,0xa7,0x39,0x67,0xcb,0x39,0x9b,0xf7,0x7e,0xa,0x9c,0x17,0xee,0x95,0xf1,0xba,0xa5,0x90,0x17,0x11,0x6f,0xf6,0x62,0xb6,0x88,0xb8,0x9e,0xe1,0x5b,0xd1,0x0,0x27,0x75,0x5d,0x3f,0x14,0xd9,0xd3,0x4e,0x49,0xf1,0xe4,0xa4,0xe4,0x6c,0x44,0x10,0x91,0xa3,0xd1,0x68,0xf4,0x54,0x55,0x55,0xd7,0xf3,0x19,0x70,0xa6,0xaa,0x93,0x94,0x92,0xc5,0x18,0xe7,0x22,0x72,0xb4,0x6e,0xe2,0xab,0x16,0xbc,0xf7,0x7,0x8b,0xc5,0x42,0x97,0xcb,0xe5,0xbc,0x6d,0xdb,0x2b,0xe0,0x16,0xa0,0x6d,0xdb,0x67,0xe7,0xdc,0xb5,0x88,0x24,0x11,0xd9,0xef,0x5a,0xeb,0x4f,0x62,0x37,0x48,0xe3,0xd5,0x6a,0xf5,0x15,0xb8,0x3,0x9e,0xb,0x37,0x2,0x3e,0x89,0xc8,0x47,0x33,0xbb,0x1,0xbe,0xad,0x4f,0x63,0xff,0x17,0xc2,0x16,0x73,0xb5,0x70,0xc2,0xbb,0xc2,0x5f,0x47,0xa5,0x56,0x8a,0x30,0xdd,0x7d,0xae,0x0,0x0,0x0,0x0,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};

View file

@ -91,6 +91,7 @@
#include "plugins/polygon_2d_editor_plugin.h"
#include "plugins/navigation_polygon_editor_plugin.h"
#include "plugins/light_occluder_2d_editor_plugin.h"
#include "plugins/color_ramp_editor_plugin.h"
// end
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
@ -4157,6 +4158,7 @@ EditorNode::EditorNode() {
add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) );
add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) );
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
add_editor_plugin( EditorPlugins::create(i,this) );

Binary file not shown.

After

Width:  |  Height:  |  Size: 290 B

View file

@ -0,0 +1,83 @@
/*
* color_ramp_editor_plugin.cpp
*/
#include "color_ramp_editor_plugin.h"
ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
editor=p_node;
ramp_editor = memnew( ColorRampEdit );
add_custom_control(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
//add_custom_control(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
ramp_editor->set_custom_minimum_size(Size2(100, 48));
ramp_editor->hide();
ramp_editor->connect("ramp_changed", this, "ramp_changed");
}
void ColorRampEditorPlugin::edit(Object *p_object) {
ColorRamp* color_ramp = p_object->cast_to<ColorRamp>();
if (!color_ramp)
return;
color_ramp_ref = Ref<ColorRamp>(color_ramp);
ramp_editor->set_points(color_ramp_ref->get_points());
}
bool ColorRampEditorPlugin::handles(Object *p_object) const {
return p_object->is_type("ColorRamp");
}
void ColorRampEditorPlugin::make_visible(bool p_visible) {
if (p_visible) {
ramp_editor->show();
} else {
ramp_editor->hide();
}
}
void ColorRampEditorPlugin::_ramp_changed() {
if(color_ramp_ref.is_valid())
{
UndoRedo *ur=EditorNode::get_singleton()->get_undo_redo();
//Not sure if I should convert this data to DVector
Vector<float> new_offsets=ramp_editor->get_offsets();
Vector<Color> new_colors=ramp_editor->get_colors();
Vector<float> old_offsets=color_ramp_ref->get_offsets();
Vector<Color> old_colors=color_ramp_ref->get_colors();
if (old_offsets.size()!=new_offsets.size())
ur->create_action("Add/Remove Color Ramp Point");
else
ur->create_action("Modify Color Ramp",true);
ur->add_do_method(this,"undo_redo_color_ramp",new_offsets,new_colors);
ur->add_undo_method(this,"undo_redo_color_ramp",old_offsets,old_colors);
ur->commit_action();
//color_ramp_ref->set_points(ramp_editor->get_points());
}
}
void ColorRampEditorPlugin::_undo_redo_color_ramp(const Vector<float>& offsets,
const Vector<Color>& colors) {
color_ramp_ref->set_offsets(offsets);
color_ramp_ref->set_colors(colors);
ramp_editor->set_points(color_ramp_ref->get_points());
ramp_editor->update();
}
ColorRampEditorPlugin::~ColorRampEditorPlugin(){
}
void ColorRampEditorPlugin::_bind_methods() {
ObjectTypeDB::bind_method(_MD("ramp_changed"),&ColorRampEditorPlugin::_ramp_changed);
ObjectTypeDB::bind_method(_MD("undo_redo_color_ramp","offsets","colors"),&ColorRampEditorPlugin::_undo_redo_color_ramp);
}

View file

@ -0,0 +1,37 @@
/*
* color_ramp_editor_plugin.h
*/
#ifndef TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_
#define TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_
#include "tools/editor/editor_plugin.h"
#include "tools/editor/editor_node.h"
#include "scene/gui/color_ramp_edit.h"
class ColorRampEditorPlugin : public EditorPlugin {
OBJ_TYPE( ColorRampEditorPlugin, EditorPlugin );
Ref<ColorRamp> color_ramp_ref;
ColorRampEdit *ramp_editor;
EditorNode *editor;
protected:
static void _bind_methods();
void _ramp_changed();
void _undo_redo_color_ramp(const Vector<float>& offsets, const Vector<Color>& colors);
public:
virtual String get_name() const { return "ColorRamp"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
virtual bool handles(Object *p_node) const;
virtual void make_visible(bool p_visible);
ColorRampEditorPlugin(EditorNode *p_node);
~ColorRampEditorPlugin();
};
#endif /* TOOLS_EDITOR_PLUGINS_COLOR_RAMP_EDITOR_PLUGIN_H_ */