Matrix32 Camera2D::get_camera_transform() { if (!get_tree()) return Matrix32(); Size2 screen_size = get_viewport_rect().size; screen_size=get_viewport_rect().size; Point2 new_camera_pos = get_global_transform().get_origin(); Point2 ret_camera_pos; if (!first) { if (anchor_mode==ANCHOR_MODE_DRAG_CENTER) { if (h_drag_enabled && !get_tree()->is_editor_hint()) { camera_pos.x = MIN( camera_pos.x, (new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT])); camera_pos.x = MAX( camera_pos.x, (new_camera_pos.x - screen_size.x * 0.5 * drag_margin[MARGIN_LEFT])); } else { if (h_ofs<0) { camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_RIGHT] * h_ofs; } else { camera_pos.x = new_camera_pos.x + screen_size.x * 0.5 * drag_margin[MARGIN_LEFT] * h_ofs; } } if (v_drag_enabled && !get_tree()->is_editor_hint()) { camera_pos.y = MIN( camera_pos.y, (new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM])); camera_pos.y = MAX( camera_pos.y, (new_camera_pos.y - screen_size.y * 0.5 * drag_margin[MARGIN_TOP])); } else { if (v_ofs<0) { camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_TOP] * v_ofs; } else { camera_pos.y = new_camera_pos.y + screen_size.y * 0.5 * drag_margin[MARGIN_BOTTOM] * v_ofs; } } } else if (anchor_mode==ANCHOR_MODE_FIXED_TOP_LEFT){ camera_pos=new_camera_pos; } if (smoothing_enabled && !get_tree()->is_editor_hint()) { float c = smoothing*get_fixed_process_delta_time(); smoothed_camera_pos = ((camera_pos-smoothed_camera_pos)*c)+smoothed_camera_pos; ret_camera_pos=smoothed_camera_pos; // camera_pos=camera_pos*(1.0-smoothing)+new_camera_pos*smoothing; } else { ret_camera_pos=smoothed_camera_pos=camera_pos; } } else { ret_camera_pos=smoothed_camera_pos=camera_pos=new_camera_pos; first=false; } Point2 screen_offset = (anchor_mode==ANCHOR_MODE_DRAG_CENTER ? (screen_size * 0.5 * zoom) : Point2()); float angle = get_global_transform().get_rotation(); if(rotating){ screen_offset = screen_offset.rotated(angle); } Rect2 screen_rect(-screen_offset+ret_camera_pos,screen_size*zoom); if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT]) screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x; if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y; if (screen_rect.pos.x < limit[MARGIN_LEFT]) screen_rect.pos.x=limit[MARGIN_LEFT]; if (screen_rect.pos.y < limit[MARGIN_TOP]) screen_rect.pos.y =limit[MARGIN_TOP]; if (offset!=Vector2()) { screen_rect.pos+=offset; if (screen_rect.pos.x + screen_rect.size.x > limit[MARGIN_RIGHT]) screen_rect.pos.x = limit[MARGIN_RIGHT] - screen_rect.size.x; if (screen_rect.pos.y + screen_rect.size.y > limit[MARGIN_BOTTOM]) screen_rect.pos.y = limit[MARGIN_BOTTOM] - screen_rect.size.y; if (screen_rect.pos.x < limit[MARGIN_LEFT]) screen_rect.pos.x=limit[MARGIN_LEFT]; if (screen_rect.pos.y < limit[MARGIN_TOP]) screen_rect.pos.y =limit[MARGIN_TOP]; } camera_screen_center=screen_rect.pos+screen_rect.size*0.5; Matrix32 xform; if(rotating){ xform.set_rotation(angle); } xform.scale_basis(zoom); xform.set_origin(screen_rect.pos/*.floor()*/); /* if (0) { xform = get_global_transform() * xform; } else { xform.elements[2]+=get_global_transform().get_origin(); } */ return (xform).affine_inverse(); }
void Particles2D::_notification(int p_what) { switch(p_what) { case NOTIFICATION_PROCESS: { _process_particles( get_process_delta_time() ); } break; case NOTIFICATION_ENTER_TREE: { float ppt=preprocess; while(ppt>0) { _process_particles(0.1); ppt-=0.1; } } break; case NOTIFICATION_DRAW: { if (particles.size()==0 || lifetime==0) return; RID ci=get_canvas_item(); Size2 size(1,1); Point2 center; int total_frames=1; if (!texture.is_null()) { size=texture->get_size(); size.x/=h_frames; size.y/=v_frames; total_frames=h_frames*v_frames; } float time_pos=(time/lifetime); Particle *pdata=&particles[0]; int particle_count=particles.size(); RID texrid; if (texture.is_valid()) texrid = texture->get_rid(); Matrix32 invxform; if (!local_space) invxform=get_global_transform().affine_inverse(); int start_particle = (int)(time * (float)particle_count / lifetime); for (int id=0;id<particle_count;++id) { int i = start_particle + id; if (i >= particle_count) { i -= particle_count; } Particle &p=pdata[i]; if (!p.active) continue; float ptime = ((float)i / particle_count)*explosiveness; if (ptime<time_pos) ptime=time_pos-ptime; else ptime=(1.0-ptime)+time_pos; uint32_t rand_seed=p.seed*(i+1); Color color; if(color_ramp.is_valid()) { color = color_ramp->get_color_at_offset(ptime); } else { color = default_color; } { float huerand=_rand_from_seed(&rand_seed); float huerot = param[PARAM_HUE_VARIATION] + randomness[PARAM_HUE_VARIATION] * huerand; if (Math::abs(huerot) > CMP_EPSILON) { float h=color.get_h(); float s=color.get_s(); float v=color.get_v(); float a=color.a; //float preh=h; h+=huerot; h=Math::abs(Math::fposmod(h,1.0)); //print_line("rand: "+rtos(randomness[PARAM_HUE_VARIATION])+" rand: "+rtos(huerand)); //print_line(itos(i)+":hue: "+rtos(preh)+" + "+rtos(huerot)+" = "+rtos(h)); color.set_hsv(h,s,v); color.a=a; } } float initial_size = param[PARAM_INITIAL_SIZE]+param[PARAM_INITIAL_SIZE]*_rand_from_seed(&rand_seed)*randomness[PARAM_FINAL_SIZE]; float final_size = param[PARAM_FINAL_SIZE]+param[PARAM_FINAL_SIZE]*_rand_from_seed(&rand_seed)*randomness[PARAM_FINAL_SIZE]; float size_mult=initial_size*(1.0-ptime) + final_size*ptime; //Size2 rectsize=size * size_mult; //rectsize=rectsize.floor(); //Rect2 r = Rect2(Vecto,rectsize); Matrix32 xform; if (p.rot) { xform.set_rotation(p.rot); xform.translate(-size*size_mult/2.0); xform.elements[2]+=p.pos; } else { xform.elements[2]=-size*size_mult/2.0; xform.elements[2]+=p.pos; } if (!local_space) { xform = invxform * xform; } xform.scale_basis(Size2(size_mult,size_mult)); VisualServer::get_singleton()->canvas_item_add_set_transform(ci,xform); if (texrid.is_valid()) { Rect2 src_rect; src_rect.size=size; if (total_frames>1) { int frame = Math::fast_ftoi(Math::floor(p.frame*total_frames)) % total_frames; src_rect.pos.x = size.x * (frame%h_frames); src_rect.pos.y = size.y * (frame/h_frames); } texture->draw_rect_region(ci,Rect2(Point2(),size),src_rect,color); //VisualServer::get_singleton()->canvas_item_add_texture_rect(ci,r,texrid,false,color); } else { VisualServer::get_singleton()->canvas_item_add_rect(ci,Rect2(Point2(),size),color); } } } break; } }