void PinwheelEffect::Draw_arm(RenderBuffer &buffer, int base_degrees,int max_radius,int pinwheel_twist, const xlColor &rgb,int xc_adj,int yc_adj) { float r,phi; int x,y,xc,yc; float pi_180 = M_PI/180; int degrees_twist,degrees; xc= (int)(buffer.BufferWi/2); yc= (int)(buffer.BufferHt/2); xc = xc + (xc_adj/100.0)*xc; // xc_adj is from -100 to 100 yc = yc + (yc_adj/100.0)*yc; for(r=0.0; r<=max_radius; r+=0.5) { degrees_twist=(r/max_radius)*pinwheel_twist; degrees = base_degrees + degrees_twist; phi = degrees * pi_180; x = r * buffer.cos (phi) + xc; y = r * buffer.sin (phi) + yc; buffer.SetPixel(x, y, rgb); } }
void GalaxyEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int center_x = SettingsMap.GetInt("SLIDER_Galaxy_CenterX"); int center_y = SettingsMap.GetInt("SLIDER_Galaxy_CenterY"); int start_radius = SettingsMap.GetInt("SLIDER_Galaxy_Start_Radius"); int end_radius = SettingsMap.GetInt("SLIDER_Galaxy_End_Radius"); int start_angle = SettingsMap.GetInt("SLIDER_Galaxy_Start_Angle"); int revolutions = SettingsMap.GetInt("SLIDER_Galaxy_Revolutions"); int start_width = SettingsMap.GetInt("SLIDER_Galaxy_Start_Width"); int end_width = SettingsMap.GetInt("SLIDER_Galaxy_End_Width"); int duration = SettingsMap.GetInt("SLIDER_Galaxy_Duration"); int acceleration = SettingsMap.GetInt("SLIDER_Galaxy_Accel"); bool reverse_dir = SettingsMap.GetBool("CHECKBOX_Galaxy_Reverse"); bool blend_edges = SettingsMap.GetBool("CHECKBOX_Galaxy_Blend_Edges"); bool inward = SettingsMap.GetBool("CHECKBOX_Galaxy_Inward"); if( revolutions == 0 ) return; std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt)); std::vector< std::vector<double> > pixel_age(buffer.BufferWi, std::vector<double>(buffer.BufferHt)); double eff_pos = buffer.GetEffectTimeIntervalPosition(); int num_colors = buffer.palette.Size(); xlColor color, c_old, c_new; HSVValue hsv1; double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration); double revs = (double)revolutions; double pos_x = buffer.BufferWi * center_x/100.0; double pos_y = buffer.BufferHt * center_y/100.0; double head_duration = duration/100.0; // time the head is in the frame double tail_length = revs * (1.0 - head_duration); double color_length = tail_length / num_colors; if(color_length < 1.0) color_length = 1.0; double tail_end_of_tail = ((revs + tail_length) * eff_pos_adj) - tail_length; double head_end_of_tail = tail_end_of_tail + tail_length; double radius1 = start_radius; double radius2 = end_radius; double width1 = start_width; double width2 = end_width; double step = buffer.GetStepAngle(radius1, radius2); for( int x = 0; x < buffer.BufferWi; x++ ) { for( int y = 0; y < buffer.BufferHt; y++ ) { temp_colors_pct[x][y] = 0.0; pixel_age[x][y] = 0.0; } } buffer.ClearTempBuf(); double last_check = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail) ) + (double)start_angle; for( double i = (inward ? std::min(head_end_of_tail,revs) : std::max(0.0, tail_end_of_tail)); (inward ? i >= std::max(0.0, tail_end_of_tail) : i <= std::min(head_end_of_tail,revs)); (inward ? i -= step : i += step) ) { double adj_angle = i + (double)start_angle; if( reverse_dir ) { adj_angle *= -1.0; } double color_val = (head_end_of_tail-i) / color_length; int color_int = (int)color_val; double color_pct = color_val - (double)color_int; int color2 = std::min(color_int+1, num_colors-1); if( color_int < color2 ) { buffer.Get2ColorBlend(color_int, color2, std::min( color_pct, 1.0), color); } else { buffer.palette.GetColor(color2, color); } HSVValue hsv(color); double full_brightness = hsv.value; double pct = i/revs; double current_radius = radius2 * pct + radius1 * (1.0 - pct); double current_width = width2 * pct + width1 * (1.0 - pct); double half_width = current_width / 2.0; double inside_radius = current_radius - half_width; for( double r = inside_radius; ; r += 0.5 ) { if( r > current_radius ) r = current_radius; double x1 = buffer.sin(ToRadians(adj_angle)) * r + (double)pos_x; double y1 = buffer.cos(ToRadians(adj_angle)) * r + (double)pos_y; double outside_radius = current_radius + (current_radius - r); double x2 = buffer.sin(ToRadians(adj_angle)) * outside_radius + (double)pos_x; double y2 = buffer.cos(ToRadians(adj_angle)) * outside_radius + (double)pos_y; double color_pct2 = (r-inside_radius)/(current_radius-inside_radius); if( blend_edges ) { if( hsv.value > 0.0 ) { if ((int)x1 >= 0 && (int)x1 < buffer.BufferWi && (int)y1 >= 0 && (int)y1 < buffer.BufferHt) { buffer.SetTempPixel((int)x1,(int)y1,color); temp_colors_pct[(int)x1][(int)y1] = color_pct2; pixel_age[(int)x1][(int)y1] = adj_angle; } if ((int)x2 >= 0 && (int)x2 < buffer.BufferWi && (int)y2 >= 0 && (int)y2 < buffer.BufferHt) { buffer.SetTempPixel((int)x2,(int)y2,color); temp_colors_pct[(int)x2][(int)y2] = color_pct2; pixel_age[(int)x2][(int)y2] = adj_angle; } } } else { hsv.value = full_brightness * color_pct2; if( hsv.value > 0.0 ) { buffer.SetPixel(x1,y1,hsv); buffer.SetPixel(x2,y2,hsv); } } if( r >= current_radius ) break; } // blend old data down into final buffer if( blend_edges && ( (inward ? (last_check-adj_angle) : (adj_angle-last_check)) >= 90.0) ) { for( int x = 0; x < buffer.BufferWi; x++ ) { for( int y = 0; y < buffer.BufferHt; y++ ) { if( temp_colors_pct[x][y] > 0.0 && ((inward ? (pixel_age[x][y]-adj_angle) : (adj_angle-pixel_age[x][y])) >= 180.0) ) { buffer.GetTempPixel(x,y,c_new); buffer.GetPixel(x,y,c_old); buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color); buffer.SetPixel(x,y,color); temp_colors_pct[x][y] = 0.0; pixel_age[x][y] = 0.0; } } } last_check = adj_angle; } } // blend remaining data down into final buffer if( blend_edges ) { for( int x = 0; x < buffer.BufferWi; x++ ) { for( int y = 0; y < buffer.BufferHt; y++ ) { if( temp_colors_pct[x][y] > 0.0 ) { buffer.GetTempPixel(x,y,c_new); buffer.GetPixel(x,y,c_old); buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color); buffer.SetPixel(x,y,color); } } } } }
void ShockwaveEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { int center_x = SettingsMap.GetInt("SLIDER_Shockwave_CenterX", 0); int center_y = SettingsMap.GetInt("SLIDER_Shockwave_CenterY", 0); int start_radius = SettingsMap.GetInt("SLIDER_Shockwave_Start_Radius", 0); int end_radius = SettingsMap.GetInt("SLIDER_Shockwave_End_Radius", 0); int start_width = SettingsMap.GetInt("SLIDER_Shockwave_Start_Width", 0); int end_width = SettingsMap.GetInt("SLIDER_Shockwave_End_Width", 0); int acceleration = SettingsMap.GetInt("SLIDER_Shockwave_Accel", 0); bool blend_edges = SettingsMap.GetBool("CHECKBOX_Shockwave_Blend_Edges"); std::vector< std::vector<double> > temp_colors_pct(buffer.BufferWi, std::vector<double>(buffer.BufferHt)); double eff_pos = buffer.GetEffectTimeIntervalPosition(); int num_colors = buffer.palette.Size(); if( num_colors == 0 ) num_colors = 1; xlColor color, c_old, c_new; double eff_pos_adj = buffer.calcAccel(eff_pos, acceleration); double blend_pct = 1.0 / (num_colors-1); double color_pct1 = eff_pos_adj / blend_pct; int color_index = (int)color_pct1; blend_pct = color_pct1 - (double)color_index; buffer.Get2ColorBlend(color_index, std::min(color_index+1,num_colors-1), std::min( blend_pct, 1.0), color); double pos_x = buffer.BufferWi * center_x/100.0; double pos_y = buffer.BufferHt * center_y/100.0; double radius1 = start_radius; double radius2 = end_radius; double radius_center = radius1 + (radius2 - radius1) * eff_pos_adj; double half_width = (start_width + (end_width - start_width) * eff_pos_adj) / 2.0; radius1 = radius_center - half_width; radius2 = radius_center + half_width; double step = buffer.GetStepAngle(radius1, radius2); for( int x = 0; x < buffer.BufferWi; x++ ) { for( int y = 0; y < buffer.BufferHt; y++ ) { temp_colors_pct[x][y] = 0.0; } } buffer.ClearTempBuf(); for( double current_angle = 0.0; current_angle <= 360.0; current_angle += step ) { for( double r = std::max(0.0, radius1); r <= radius2; r += 0.5 ) { double x1 = buffer.sin(ToRadians(current_angle)) * r + (double)pos_x; double y1 = buffer.cos(ToRadians(current_angle)) * r + (double)pos_y; if( blend_edges ) { double color_pct = 1.0 - std::abs(r-radius_center)/half_width; if( color_pct > 0.0 ) { if (x1 >= 0 && x1 < buffer.BufferWi && y1 >= 0 && y1 < buffer.BufferHt) { if (buffer.allowAlpha) { color.alpha = 255.0 * color_pct; buffer.SetPixel((int)x1,(int)y1,color); } else { temp_colors_pct[(int)x1][(int)y1] = color_pct; buffer.SetTempPixel((int)x1,(int)y1,color); } } } } else { buffer.SetPixel((int)x1,(int)y1,color); } } } // blend element data into final buffer if( blend_edges && !buffer.allowAlpha ) { for( int x = 0; x < buffer.BufferWi; x++ ) { for( int y = 0; y < buffer.BufferHt; y++ ) { if( temp_colors_pct[x][y] > 0.0 ) { buffer.GetTempPixel(x,y,c_new); buffer.GetPixel(x,y,c_old); buffer.Get2ColorAlphaBlend(c_old, c_new, temp_colors_pct[x][y], color); buffer.SetPixel(x,y,color); temp_colors_pct[x][y] = 0.0; } } } } }
void PinwheelEffect::Render(Effect *effect, const SettingsMap &SettingsMap, RenderBuffer &buffer) { float oset = buffer.GetEffectTimeIntervalPosition(); int pinwheel_arms = SettingsMap.GetInt("SLIDER_Pinwheel_Arms", 3); int pinwheel_twist = GetValueCurveInt("Pinwheel_Twist", 0, SettingsMap, oset); int pinwheel_thickness = GetValueCurveInt("Pinwheel_Thickness", 0, SettingsMap, oset); bool pinwheel_rotation = SettingsMap.GetBool("CHECKBOX_Pinwheel_Rotation"); const std::string &pinwheel_3d = SettingsMap["CHOICE_Pinwheel_3D"]; int xc_adj = GetValueCurveInt("PinwheelXC", 0, SettingsMap, oset); int yc_adj = GetValueCurveInt("PinwheelYC", 0, SettingsMap, oset); int pinwheel_armsize = GetValueCurveInt("Pinwheel_ArmSize", 100, SettingsMap, oset); int pspeed = GetValueCurveInt("Pinwheel_Speed", 10, SettingsMap, oset); const std::string &pinwheel_style = SettingsMap["CHOICE_Pinwheel_Style"]; int xc; float tmax; HSVValue hsv, hsv1; double pos = (buffer.curPeriod - buffer.curEffStartPer) * pspeed * buffer.frameTimeInMs / 50; int degrees_per_arm = 1; if (pinwheel_arms > 0) degrees_per_arm = 360 / pinwheel_arms; float armsize = (pinwheel_armsize / 100.0); if (pinwheel_style == "New Render Method") { std::vector<size_t> colorarray; colorarray.resize(pinwheel_arms); for (int i = 0; i < pinwheel_arms; i++) { colorarray[i] = i%buffer.GetColorCount(); } xc = (int)(ceil(std::hypot(buffer.BufferWi, buffer.BufferHt) / 2)); xc_adj = xc_adj*buffer.BufferWi / 200; yc_adj = yc_adj*buffer.BufferHt / 200; int max_radius = xc * armsize; if (pinwheel_thickness == 0) pinwheel_thickness = 1; tmax = (pinwheel_thickness / 100.0)*degrees_per_arm; // Force single visible line in case width is narrower than visible float pi_180 = M_PI/180; for(int a=0; a<pinwheel_arms; a++) { int ColorIdx = a%pinwheel_arms; xlColor color; buffer.palette.GetHSV(colorarray[ColorIdx], hsv); color = xlColor(hsv); int angle = (a*degrees_per_arm); if (pinwheel_rotation == 1) // do we have CW rotation { angle = (270 - angle) + pos; } else { angle = angle - 90 - pos; } int x,y, degrees_twist; for (float r=0; r<=max_radius; r+=0.5) { degrees_twist = (r/max_radius) * pinwheel_twist; int t2 = (int)angle%degrees_per_arm; double round = (float)t2 / (float)tmax; x = floor((int)(r * buffer.cos((angle + degrees_twist) * pi_180)) + xc_adj + buffer.BufferWi / 2); y = floor((int)(r * buffer.sin((angle + degrees_twist) * pi_180)) + yc_adj + buffer.BufferHt / 2); if (buffer.palette.IsSpatial(colorarray[ColorIdx])) { buffer.palette.GetSpatialColor(colorarray[ColorIdx], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color); } buffer.SetPixel(x,y,color); } } // Draw actual pinwheel arms for (int x = 0; x < buffer.BufferWi; x++) { int x1 = x - xc_adj - (buffer.BufferWi / 2); for (int y = 0; y < buffer.BufferHt; y++) { int y1 = y - yc_adj - (buffer.BufferHt / 2); double r = std::hypot(x1, y1); if (r <= max_radius) { double degrees_twist = (r / max_radius)*pinwheel_twist; double theta = (std::atan2(x1, y1) * 180 / 3.14159) + degrees_twist; if (pinwheel_rotation == 1) // do we have CW rotation { theta = pos + theta + (tmax/2); } else { theta = pos - theta + (tmax/2); } theta = theta + 540.0; int t2 = (int)theta%degrees_per_arm; if (t2 <= tmax) { double round = (float)t2 / (float)tmax; t2 = std::abs(t2 - (tmax/2)) * 2; xlColor color; int ColorIdx2 = ((int)((theta/degrees_per_arm)))%pinwheel_arms; if (buffer.palette.IsSpatial(colorarray[ColorIdx2])) { buffer.palette.GetSpatialColor(colorarray[ColorIdx2], xc_adj + buffer.BufferWi / 2, yc_adj + buffer.BufferHt / 2, x, y, round, max_radius, color); hsv = color.asHSV(); } else { buffer.palette.GetHSV(colorarray[ColorIdx2], hsv); } hsv1=hsv; color = xlColor(hsv1); if(pinwheel_3d=="3D") { if (buffer.allowAlpha) { color.alpha = 255.0 * ((tmax - t2) / tmax); } else { hsv1.value = hsv.value * ((tmax - t2) / tmax); color = hsv1; } } else if (pinwheel_3d == "3D Inverted") { if (buffer.allowAlpha) { color.alpha = 255.0 * ((t2) / tmax); } else { hsv1.value = hsv.value * ((t2) / tmax); color = hsv1; } } buffer.SetPixel(x, y, color); } } } } } else { // Old Render Method int a,xc,ColorIdx,base_degrees; float t,tmax; float radius; HSVValue hsv,hsv0,hsv1; size_t colorcnt=buffer.GetColorCount(); xc= (int)(std::max(buffer.BufferWi, buffer.BufferHt)/2); radius = xc/100.0; for(a=1; a<=pinwheel_arms; a++) { ColorIdx=a%colorcnt; buffer.palette.GetHSV(ColorIdx, hsv); // Now go and get the hsv value for this ColorIdx if(pinwheel_rotation==1) // do we have CW rotation { base_degrees = (a-1)*degrees_per_arm + pos; // yes } else { base_degrees = (a-1)*degrees_per_arm - pos; // no, we are CCW } Draw_arm(buffer, base_degrees, xc*armsize, pinwheel_twist,hsv,xc_adj,yc_adj); if(pinwheel_thickness>0) { tmax= (pinwheel_thickness/100.0)*degrees_per_arm/2.0; hsv1=hsv; xlColor color(hsv1); for (t=1; t<=tmax; t++) { if(pinwheel_3d=="3D") { if (buffer.allowAlpha) { color.alpha = 255.0 * ((tmax-t)/tmax); } else { hsv1.value = hsv.value * ((tmax-t)/tmax); color = hsv1; } } else if(pinwheel_3d=="3D Inverted") { if (buffer.allowAlpha) { color.alpha = 255.0 * ((t)/tmax); } else { hsv1.value = hsv.value * ((t)/tmax); color = hsv1; } } Draw_arm(buffer, base_degrees-t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj); Draw_arm(buffer, base_degrees+t, xc*armsize, pinwheel_twist,color,xc_adj,yc_adj); } } } } }