Merge remote-tracking branch 'upstream/master' into x11-window-management
|
@ -67,12 +67,16 @@ env_base.android_source_modules=[]
|
|||
env_base.android_source_files=[]
|
||||
env_base.android_module_libraries=[]
|
||||
env_base.android_manifest_chunk=""
|
||||
env_base.android_permission_chunk=""
|
||||
env_base.android_appattributes_chunk=""
|
||||
env_base.disabled_modules=[]
|
||||
|
||||
env_base.__class__.android_module_source = methods.android_module_source
|
||||
env_base.__class__.android_module_library = methods.android_module_library
|
||||
env_base.__class__.android_module_file = methods.android_module_file
|
||||
env_base.__class__.android_module_manifest = methods.android_module_manifest
|
||||
env_base.__class__.android_module_permission = methods.android_module_permission
|
||||
env_base.__class__.android_module_attribute = methods.android_module_attribute
|
||||
env_base.__class__.disable_module = methods.disable_module
|
||||
|
||||
env_base.__class__.add_source_files = methods.add_source_files
|
||||
|
|
|
@ -1778,6 +1778,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
|||
f->store_32(VERSION_MINOR);
|
||||
f->store_32(FORMAT_VERSION);
|
||||
|
||||
if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) {
|
||||
f->close();
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
//f->store_32(saved_resources.size()+external_resources.size()); // load steps -not needed
|
||||
save_unicode_string(p_resource->get_type());
|
||||
uint64_t md_at = f->get_pos();
|
||||
|
@ -1910,6 +1915,11 @@ Error ResourceFormatSaverBinaryInstance::save(const String &p_path,const RES& p_
|
|||
|
||||
f->store_buffer((const uint8_t*)"RSRC",4); //magic at end
|
||||
|
||||
if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) {
|
||||
f->close();
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
f->close();
|
||||
|
||||
|
||||
|
|
|
@ -2592,6 +2592,11 @@ Error ResourceFormatSaverXMLInstance::save(const String &p_path,const RES& p_res
|
|||
}
|
||||
|
||||
exit_tag("resource_file");
|
||||
if (f->get_error()!=OK && f->get_error()!=ERR_FILE_EOF) {
|
||||
f->close();
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
|
||||
f->close();
|
||||
//memdelete(f);
|
||||
|
||||
|
|
56
core/list.h
|
@ -30,7 +30,7 @@
|
|||
#define GLOBALS_LIST_H
|
||||
|
||||
#include "os/memory.h"
|
||||
|
||||
#include "sort.h"
|
||||
|
||||
/**
|
||||
* Generic Templatized Linked List Implementation.
|
||||
|
@ -551,7 +551,7 @@ public:
|
|||
}
|
||||
|
||||
template<class C>
|
||||
void sort_custom() {
|
||||
void sort_custom_inplace() {
|
||||
|
||||
if(size()<2)
|
||||
return;
|
||||
|
@ -603,6 +603,58 @@ public:
|
|||
_data->last=to;
|
||||
}
|
||||
|
||||
template<class C>
|
||||
struct AuxiliaryComparator {
|
||||
|
||||
C compare;
|
||||
_FORCE_INLINE_ bool operator()(const Element *a,const Element* b) const {
|
||||
|
||||
return compare(a->value,b->value);
|
||||
}
|
||||
};
|
||||
|
||||
template<class C>
|
||||
void sort_custom() {
|
||||
|
||||
//this version uses auxiliary memory for speed.
|
||||
//if you don't want to use auxiliary memory, use the in_place version
|
||||
|
||||
int s = size();
|
||||
if(s<2)
|
||||
return;
|
||||
|
||||
|
||||
Element **aux_buffer = memnew_arr(Element*,s);
|
||||
|
||||
int idx=0;
|
||||
for(Element *E=front();E;E=E->next_ptr) {
|
||||
|
||||
aux_buffer[idx]=E;
|
||||
idx++;
|
||||
}
|
||||
|
||||
SortArray<Element*,AuxiliaryComparator<C> > sort;
|
||||
sort.sort(aux_buffer,s);
|
||||
|
||||
_data->first=aux_buffer[0];
|
||||
aux_buffer[0]->prev_ptr=NULL;
|
||||
aux_buffer[0]->next_ptr=aux_buffer[1];
|
||||
|
||||
_data->last=aux_buffer[s-1];
|
||||
aux_buffer[s-1]->prev_ptr=aux_buffer[s-2];
|
||||
aux_buffer[s-1]->next_ptr=NULL;
|
||||
|
||||
for(int i=1;i<s-1;i++) {
|
||||
|
||||
aux_buffer[i]->prev_ptr=aux_buffer[i-1];
|
||||
aux_buffer[i]->next_ptr=aux_buffer[i+1];
|
||||
|
||||
}
|
||||
|
||||
memdelete_arr(aux_buffer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* copy constructor for the list
|
||||
*/
|
||||
|
|
|
@ -121,7 +121,7 @@ void CameraMatrix::set_orthogonal(float p_size, float p_aspect, float p_znear, f
|
|||
|
||||
|
||||
void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, float p_top, float p_near, float p_far) {
|
||||
|
||||
#if 0
|
||||
///@TODO, give a check to this. I'm not sure if it's working.
|
||||
set_identity();
|
||||
|
||||
|
@ -133,10 +133,27 @@ void CameraMatrix::set_frustum(float p_left, float p_right, float p_bottom, floa
|
|||
matrix[2][3]=-(2*p_far*p_near) / (p_far-p_near);
|
||||
matrix[3][2]=-1;
|
||||
matrix[3][3]=0;
|
||||
#else
|
||||
float *te = &matrix[0][0];
|
||||
float x = 2 * p_near / ( p_right - p_left );
|
||||
float y = 2 * p_near / ( p_top - p_bottom );
|
||||
|
||||
float a = ( p_right + p_left ) / ( p_right - p_left );
|
||||
float b = ( p_top + p_bottom ) / ( p_top - p_bottom );
|
||||
float c = - ( p_far + p_near ) / ( p_far - p_near );
|
||||
float d = - 2 * p_far * p_near / ( p_far - p_near );
|
||||
|
||||
te[0] = x; te[4] = 0; te[8] = a; te[12] = 0;
|
||||
te[1] = 0; te[5] = y; te[9] = b; te[13] = 0;
|
||||
te[2] = 0; te[6] = 0; te[10] = c; te[14] = d;
|
||||
te[3] = 0; te[7] = 0; te[11] = - 1; te[15] = 0;
|
||||
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
float CameraMatrix::get_z_far() const {
|
||||
|
||||
const float * matrix = (const float*)this->matrix;
|
||||
|
|
|
@ -159,8 +159,8 @@ struct Vector2 {
|
|||
|
||||
operator String() const { return String::num(x)+","+String::num(y); }
|
||||
|
||||
inline Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||
inline Vector2() { x=0; y=0; }
|
||||
_FORCE_INLINE_ Vector2(float p_x,float p_y) { x=p_x; y=p_y; }
|
||||
_FORCE_INLINE_ Vector2() { x=0; y=0; }
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ Vector2 Vector2::plane_project(real_t p_d, const Vector2& p_vec) const {
|
||||
|
@ -198,6 +198,8 @@ Vector2 Vector2::linear_interpolate(const Vector2& p_a, const Vector2& p_b,float
|
|||
typedef Vector2 Size2;
|
||||
typedef Vector2 Point2;
|
||||
|
||||
struct Matrix32;
|
||||
|
||||
|
||||
struct Rect2 {
|
||||
|
||||
|
@ -224,6 +226,8 @@ struct Rect2 {
|
|||
return true;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ bool intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const;
|
||||
|
||||
bool intersects_segment(const Point2& p_from, const Point2& p_to, Point2* r_pos=NULL, Point2* r_normal=NULL) const;
|
||||
|
||||
inline bool encloses(const Rect2& p_rect) const {
|
||||
|
@ -597,6 +601,160 @@ struct Matrix32 {
|
|||
|
||||
};
|
||||
|
||||
bool Rect2::intersects_transformed(const Matrix32& p_xform, const Rect2& p_rect) const {
|
||||
|
||||
//SAT intersection between local and transformed rect2
|
||||
|
||||
Vector2 xf_points[4]={
|
||||
p_xform.xform(p_rect.pos),
|
||||
p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y)),
|
||||
p_xform.xform(Vector2(p_rect.pos.x,p_rect.pos.y+p_rect.size.y)),
|
||||
p_xform.xform(Vector2(p_rect.pos.x+p_rect.size.x,p_rect.pos.y+p_rect.size.y)),
|
||||
};
|
||||
|
||||
real_t low_limit;
|
||||
|
||||
//base rect2 first (faster)
|
||||
|
||||
if (xf_points[0].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[1].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[2].y>pos.y)
|
||||
goto next1;
|
||||
if (xf_points[3].y>pos.y)
|
||||
goto next1;
|
||||
|
||||
return false;
|
||||
|
||||
next1:
|
||||
|
||||
low_limit=pos.y+size.y;
|
||||
|
||||
if (xf_points[0].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[1].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[2].y<low_limit)
|
||||
goto next2;
|
||||
if (xf_points[3].y<low_limit)
|
||||
goto next2;
|
||||
|
||||
return false;
|
||||
|
||||
next2:
|
||||
|
||||
if (xf_points[0].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[1].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[2].x>pos.x)
|
||||
goto next3;
|
||||
if (xf_points[3].x>pos.x)
|
||||
goto next3;
|
||||
|
||||
return false;
|
||||
|
||||
next3:
|
||||
|
||||
low_limit=pos.x+size.x;
|
||||
|
||||
if (xf_points[0].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[1].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[2].x<low_limit)
|
||||
goto next4;
|
||||
if (xf_points[3].x<low_limit)
|
||||
goto next4;
|
||||
|
||||
return false;
|
||||
|
||||
next4:
|
||||
|
||||
Vector2 xf_points2[4]={
|
||||
pos,
|
||||
Vector2(pos.x+size.x,pos.y),
|
||||
Vector2(pos.x,pos.y+size.y),
|
||||
Vector2(pos.x+size.x,pos.y+size.y),
|
||||
};
|
||||
|
||||
real_t maxa=p_xform.elements[0].dot(xf_points2[0]);
|
||||
real_t mina=maxa;
|
||||
|
||||
real_t dp = p_xform.elements[0].dot(xf_points2[1]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points2[2]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points2[3]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
real_t maxb=p_xform.elements[0].dot(xf_points[0]);
|
||||
real_t minb=maxb;
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[1]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[2]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[0].dot(xf_points[3]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
|
||||
if ( mina > maxb )
|
||||
return false;
|
||||
if ( minb > maxa )
|
||||
return false;
|
||||
|
||||
maxa=p_xform.elements[1].dot(xf_points2[0]);
|
||||
mina=maxa;
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[1]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[2]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points2[3]);
|
||||
maxa=MAX(dp,maxa);
|
||||
mina=MIN(dp,mina);
|
||||
|
||||
maxb=p_xform.elements[1].dot(xf_points[0]);
|
||||
minb=maxb;
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[1]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[2]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
dp = p_xform.elements[1].dot(xf_points[3]);
|
||||
maxb=MAX(dp,maxb);
|
||||
minb=MIN(dp,minb);
|
||||
|
||||
|
||||
if ( mina > maxb )
|
||||
return false;
|
||||
if ( minb > maxa )
|
||||
return false;
|
||||
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
Vector2 Matrix32::basis_xform(const Vector2& v) const {
|
||||
|
||||
|
|
|
@ -1033,6 +1033,13 @@ void Object::add_user_signal(const MethodInfo& p_signal) {
|
|||
signal_map[p_signal.name]=s;
|
||||
}
|
||||
|
||||
bool Object::_has_user_signal(const StringName& p_name) const {
|
||||
|
||||
if (!signal_map.has(p_name))
|
||||
return false;
|
||||
return signal_map[p_name].user.name.length()>0;
|
||||
}
|
||||
|
||||
struct _ObjectSignalDisconnectData {
|
||||
|
||||
StringName signal;
|
||||
|
@ -1431,6 +1438,7 @@ void Object::_bind_methods() {
|
|||
// ObjectTypeDB::bind_method(_MD("call_deferred","method","arg1","arg2","arg3","arg4"),&Object::_call_deferred_bind,DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()),DEFVAL(Variant()));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("add_user_signal","signal","arguments"),&Object::_add_user_signal,DEFVAL(Array()));
|
||||
ObjectTypeDB::bind_method(_MD("has_user_signal","signal"),&Object::_has_user_signal);
|
||||
// ObjectTypeDB::bind_method(_MD("emit_signal","signal","arguments"),&Object::_emit_signal,DEFVAL(Array()));
|
||||
|
||||
|
||||
|
|
|
@ -386,6 +386,7 @@ friend void postinitialize_handler(Object*);
|
|||
Dictionary metadata;
|
||||
|
||||
void _add_user_signal(const String& p_name, const Array& p_pargs=Array());
|
||||
bool _has_user_signal(const StringName& p_name) const;
|
||||
Variant _emit_signal(const Variant** p_args, int p_argcount, Variant::CallError& r_error);
|
||||
Array _get_signal_list() const;
|
||||
Array _get_signal_connection_list(const String& p_signal) const;
|
||||
|
|
|
@ -1263,8 +1263,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl
|
|||
ADDFUNC1(VECTOR2,VECTOR2,Vector2,snapped,VECTOR2,"by",varray());
|
||||
ADDFUNC0(VECTOR2,REAL,Vector2,get_aspect,varray());
|
||||
ADDFUNC1(VECTOR2,REAL,Vector2,dot,VECTOR2,"with",varray());
|
||||
ADDFUNC1(VECTOR2,REAL,Vector2,slide,VECTOR2,"vec",varray());
|
||||
ADDFUNC1(VECTOR2,REAL,Vector2,reflect,VECTOR2,"vec",varray());
|
||||
ADDFUNC1(VECTOR2,VECTOR2,Vector2,slide,VECTOR2,"vec",varray());
|
||||
ADDFUNC1(VECTOR2,VECTOR2,Vector2,reflect,VECTOR2,"vec",varray());
|
||||
//ADDFUNC1(VECTOR2,REAL,Vector2,cross,VECTOR2,"with",varray());
|
||||
|
||||
ADDFUNC0(RECT2,REAL,Rect2,get_area,varray());
|
||||
|
|
|
@ -552,6 +552,9 @@ void Variant::evaluate(const Operator& p_op, const Variant& p_a, const Variant&
|
|||
if (p_b.type==MATRIX32) {
|
||||
_RETURN( *p_a._data._matrix32 * *p_b._data._matrix32 );
|
||||
};
|
||||
if (p_b.type==VECTOR2) {
|
||||
_RETURN( p_a._data._matrix32->xform( *(const Vector2*)p_b._data._mem) );
|
||||
};
|
||||
r_valid=false;
|
||||
return;
|
||||
} break;
|
||||
|
|
|
@ -18902,7 +18902,8 @@
|
|||
collider_id: collider id of the object agaisnt which the ray was stopped[br]
|
||||
collider: collider object agaisnt which the ray was stopped[br]
|
||||
rid: [RID] of the object agaisnt which the ray was stopped[br]
|
||||
If the ray did not intersect anything, then null is returned instead of a [Dictionary].
|
||||
If the ray did not intersect anything, then an empty
|
||||
dictionary (dir.empty()==true) is returned instead.
|
||||
</description>
|
||||
</method>
|
||||
<method name="intersect_shape" >
|
||||
|
|
|
@ -10,7 +10,6 @@ SConscript('alsa/SCsub');
|
|||
SConscript('pulseaudio/SCsub');
|
||||
SConscript('windows/SCsub');
|
||||
SConscript('gles2/SCsub');
|
||||
SConscript('gles1/SCsub');
|
||||
SConscript('gl_context/SCsub');
|
||||
SConscript('openssl/SCsub');
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
|
||||
#include "drivers/gles2/shaders/material.glsl.h"
|
||||
#include "drivers/gles2/shaders/canvas.glsl.h"
|
||||
#include "drivers/gles2/shaders/canvas_shadow.glsl.h"
|
||||
#include "drivers/gles2/shaders/blur.glsl.h"
|
||||
#include "drivers/gles2/shaders/copy.glsl.h"
|
||||
#include "drivers/gles2/shader_compiler_gles2.h"
|
||||
|
@ -816,6 +817,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
bool current_depth_mask;
|
||||
VS::MaterialBlendMode current_blend_mode;
|
||||
bool use_fast_texture_filter;
|
||||
int max_texture_size;
|
||||
|
||||
bool fragment_lighting;
|
||||
RID shadow_material;
|
||||
|
@ -1127,6 +1129,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
bool active;
|
||||
|
||||
int blur_size;
|
||||
|
||||
struct Blur {
|
||||
|
||||
GLuint fbo;
|
||||
|
@ -1159,6 +1162,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
void _process_glow_and_bloom();
|
||||
//void _update_blur_buffer();
|
||||
|
||||
|
||||
/*********/
|
||||
/* FRAME */
|
||||
/*********/
|
||||
|
@ -1177,6 +1181,45 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
} _rinfo;
|
||||
|
||||
|
||||
/*******************/
|
||||
/* CANVAS OCCLUDER */
|
||||
/*******************/
|
||||
|
||||
|
||||
struct CanvasOccluder {
|
||||
|
||||
GLuint vertex_id; // 0 means, unconfigured
|
||||
GLuint index_id; // 0 means, unconfigured
|
||||
DVector<Vector2> lines;
|
||||
int len;
|
||||
};
|
||||
|
||||
RID_Owner<CanvasOccluder> canvas_occluder_owner;
|
||||
|
||||
/***********************/
|
||||
/* CANVAS LIGHT SHADOW */
|
||||
/***********************/
|
||||
|
||||
|
||||
struct CanvasLightShadow {
|
||||
|
||||
int size;
|
||||
int height;
|
||||
GLuint fbo;
|
||||
GLuint rbo;
|
||||
GLuint depth;
|
||||
GLuint rgba; //for older devices
|
||||
|
||||
GLuint blur;
|
||||
|
||||
};
|
||||
|
||||
RID_Owner<CanvasLightShadow> canvas_light_shadow_owner;
|
||||
|
||||
RID canvas_shadow_blur;
|
||||
|
||||
/* ETC */
|
||||
|
||||
RenderTarget *current_rt;
|
||||
bool current_rt_transparent;
|
||||
bool current_rt_vflip;
|
||||
|
@ -1186,11 +1229,15 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
GLuint white_tex;
|
||||
RID canvas_tex;
|
||||
float canvas_opacity;
|
||||
Color canvas_modulate;
|
||||
bool canvas_use_modulate;
|
||||
bool uses_texpixel_size;
|
||||
bool rebind_texpixel_size;
|
||||
Transform canvas_transform;
|
||||
RID canvas_last_shader;
|
||||
CanvasItemMaterial *canvas_last_material;
|
||||
bool canvas_texscreen_used;
|
||||
Vector2 normal_flip;
|
||||
_FORCE_INLINE_ void _canvas_normal_set_flip(const Vector2& p_flip);
|
||||
|
||||
|
||||
_FORCE_INLINE_ Texture* _bind_canvas_texture(const RID& p_texture);
|
||||
|
@ -1222,17 +1269,19 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
VS::ScenarioDebugMode current_debug;
|
||||
RID overdraw_material;
|
||||
|
||||
|
||||
mutable MaterialShaderGLES2 material_shader;
|
||||
mutable CanvasShaderGLES2 canvas_shader;
|
||||
BlurShaderGLES2 blur_shader;
|
||||
CopyShaderGLES2 copy_shader;
|
||||
mutable CanvasShadowShaderGLES2 canvas_shadow_shader;
|
||||
|
||||
mutable ShaderCompilerGLES2 shader_precompiler;
|
||||
|
||||
void _draw_primitive(int p_points, const Vector3 *p_vertices, const Vector3 *p_normals, const Color* p_colors, const Vector3 *p_uvs,const Plane *p_tangents=NULL,int p_instanced=1);
|
||||
_FORCE_INLINE_ void _draw_gui_primitive(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs);
|
||||
_FORCE_INLINE_ void _draw_gui_primitive2(int p_points, const Vector2 *p_vertices, const Color* p_colors, const Vector2 *p_uvs, const Vector2 *p_uvs2);
|
||||
void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false );
|
||||
void _draw_textured_quad(const Rect2& p_rect, const Rect2& p_src_region, const Size2& p_tex_size,bool p_h_flip=false, bool p_v_flip=false, bool p_transpose=false );
|
||||
void _draw_quad(const Rect2& p_rect);
|
||||
void _copy_screen_quad();
|
||||
void _copy_to_texscreen();
|
||||
|
@ -1247,6 +1296,10 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
GLuint tc0_id_cache;
|
||||
GLuint tc0_idx;
|
||||
|
||||
template<bool use_normalmap>
|
||||
_FORCE_INLINE_ void _canvas_item_render_commands(CanvasItem *p_item,CanvasItem *current_clip,bool &reclip);
|
||||
_FORCE_INLINE_ void _canvas_item_setup_shader_params(CanvasItemMaterial *material,Shader* p_shader);
|
||||
_FORCE_INLINE_ void _canvas_item_setup_shader_uniforms(CanvasItemMaterial *material,Shader* p_shader);
|
||||
public:
|
||||
|
||||
/* TEXTURE API */
|
||||
|
@ -1562,7 +1615,18 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor);
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform);
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list);
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light);
|
||||
virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow);
|
||||
|
||||
/* CANVAS LIGHT SHADOW */
|
||||
|
||||
//buffer
|
||||
virtual RID canvas_light_shadow_buffer_create(int p_width);
|
||||
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache);
|
||||
|
||||
//occluder
|
||||
virtual RID canvas_light_occluder_create();
|
||||
virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines);
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
|
@ -1601,6 +1665,8 @@ public:
|
|||
virtual bool is_environment(const RID& p_rid) const;
|
||||
virtual bool is_shader(const RID& p_rid) const;
|
||||
|
||||
virtual bool is_canvas_light_occluder(const RID& p_rid) const;
|
||||
|
||||
virtual void free(const RID& p_rid);
|
||||
|
||||
virtual void init();
|
||||
|
|
|
@ -261,6 +261,11 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
|
|||
uses_light=true;
|
||||
}
|
||||
|
||||
if (vnode->name==vname_normal) {
|
||||
uses_normal=true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (vnode->name==vname_time) {
|
||||
|
@ -636,7 +641,7 @@ Error ShaderCompilerGLES2::compile(const String& p_code, ShaderLanguage::ShaderT
|
|||
r_flags.uses_light=uses_light;
|
||||
r_flags.uses_time=uses_time;
|
||||
r_flags.uses_normalmap=uses_normalmap;
|
||||
r_flags.uses_normal=uses_normalmap;
|
||||
r_flags.uses_normal=uses_normal;
|
||||
r_flags.uses_texpixel_size=uses_texpixel_size;
|
||||
r_flags.uses_worldvec=uses_worldvec;
|
||||
r_code_line=code;
|
||||
|
|
|
@ -3,6 +3,7 @@ Import('env')
|
|||
if env['BUILDERS'].has_key('GLSL120GLES'):
|
||||
env.GLSL120GLES('material.glsl');
|
||||
env.GLSL120GLES('canvas.glsl');
|
||||
env.GLSL120GLES('canvas_shadow.glsl');
|
||||
env.GLSL120GLES('blur.glsl');
|
||||
env.GLSL120GLES('copy.glsl');
|
||||
|
||||
|
|
|
@ -26,7 +26,17 @@ uniform float time;
|
|||
#ifdef USE_LIGHTING
|
||||
|
||||
uniform highp mat4 light_matrix;
|
||||
varying vec4 light_tex_pos;
|
||||
uniform vec2 light_pos;
|
||||
varying vec4 light_uv_interp;
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
varying vec4 local_rot;
|
||||
uniform vec2 normal_flip;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHADOWS
|
||||
highp varying vec2 pos;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -57,6 +67,8 @@ VERTEX_SHADER_CODE
|
|||
outvec = modelview_matrix * outvec;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#ifdef USE_PIXEL_SNAP
|
||||
|
||||
outvec.xy=floor(outvec.xy+0.5);
|
||||
|
@ -67,8 +79,16 @@ VERTEX_SHADER_CODE
|
|||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
light_tex_pos.xy = light_matrix * gl_Position;
|
||||
light_tex_pos.zw=outvec.xy - light_matrix[4].xy; //likely wrong
|
||||
light_uv_interp.xy = (light_matrix * outvec).xy;
|
||||
light_uv_interp.zw = outvec.xy-light_pos;
|
||||
#ifdef USE_SHADOWS
|
||||
pos=outvec.xy;
|
||||
#endif
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
local_rot.xy=normalize( (modelview_matrix * ( extra_matrix * vec4(1.0,0.0,0.0,0.0) )).xy )*normal_flip.x;
|
||||
local_rot.zw=normalize( (modelview_matrix * ( extra_matrix * vec4(0.0,1.0,0.0,0.0) )).xy )*normal_flip.y;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -121,17 +141,37 @@ varying vec4 var2_interp;
|
|||
uniform float time;
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODULATE
|
||||
|
||||
uniform vec4 modulate;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
uniform sampler2D light_texture;
|
||||
varying vec4 light_tex_pos;
|
||||
uniform vec4 light_color;
|
||||
uniform float light_height;
|
||||
varying vec4 light_uv_interp;
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
varying vec4 local_rot;
|
||||
#endif
|
||||
|
||||
#ifdef USE_SHADOWS
|
||||
|
||||
uniform sampler2D shadow_texture;
|
||||
uniform float shadow_attenuation;
|
||||
|
||||
uniform highp mat4 shadow_matrix;
|
||||
uniform highp mat4 light_local_matrix;
|
||||
highp varying vec2 pos;
|
||||
uniform float shadowpixel_size;
|
||||
|
||||
#ifdef SHADOW_ESM
|
||||
uniform float shadow_esm_multiplier;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -151,6 +191,7 @@ void main() {
|
|||
vec3 normal = vec3(0,0,1);
|
||||
#endif
|
||||
|
||||
|
||||
color *= texture2D( texture, uv_interp );
|
||||
#if defined(ENABLE_SCREEN_UV)
|
||||
vec2 screen_uv = gl_FragCoord.xy*screen_uv_mult;
|
||||
|
@ -164,37 +205,141 @@ FRAGMENT_SHADER_CODE
|
|||
color = vec4(vec3(enc32),1.0);
|
||||
#endif
|
||||
|
||||
#ifdef USE_MODULATE
|
||||
|
||||
color*=modulate;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef USE_LIGHTING
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
normal.xy = mat2(local_rot.xy,local_rot.zw) * normal.xy;
|
||||
#endif
|
||||
|
||||
float att=1.0;
|
||||
|
||||
vec3 light = texture2D(light_texture,light_tex_pos).rgb;
|
||||
vec4 light = texture2D(light_texture,light_uv_interp.xy) * light_color;
|
||||
#ifdef USE_SHADOWS
|
||||
//this might not be that great on mobile?
|
||||
float light_dist = length(light_texture.zw);
|
||||
float light_angle = atan2(light_texture.x,light_texture.z) + 1.0 * 0.5;
|
||||
float shadow_dist = texture2D(shadow_texture,vec2(light_angle,0));
|
||||
if (light_dist>shadow_dist) {
|
||||
light*=shadow_attenuation;
|
||||
|
||||
|
||||
vec2 lpos = (light_local_matrix * vec4(pos,0.0,1.0)).xy;
|
||||
float angle_to_light = -atan(lpos.x,lpos.y);
|
||||
float PI = 3.14159265358979323846264;
|
||||
/*int i = int(mod(floor((angle_to_light+7.0*PI/6.0)/(4.0*PI/6.0))+1.0, 3.0)); // +1 pq os indices estao em ordem 2,0,1 nos arrays
|
||||
float ang*/
|
||||
|
||||
float su,sz;
|
||||
|
||||
float abs_angle = abs(angle_to_light);
|
||||
vec2 point;
|
||||
float sh;
|
||||
if (abs_angle<45.0*PI/180.0) {
|
||||
point = lpos;
|
||||
sh=0+(1.0/8.0);
|
||||
} else if (abs_angle>135.0*PI/180.0) {
|
||||
point = -lpos;
|
||||
sh = 0.5+(1.0/8.0);
|
||||
} else if (angle_to_light>0) {
|
||||
|
||||
point = vec2(lpos.y,-lpos.x);
|
||||
sh = 0.25+(1.0/8.0);
|
||||
} else {
|
||||
|
||||
point = vec2(-lpos.y,lpos.x);
|
||||
sh = 0.75+(1.0/8.0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
vec4 s = shadow_matrix * vec4(point,0.0,1.0);
|
||||
s.xyz/=s.w;
|
||||
su=s.x*0.5+0.5;
|
||||
sz=s.z*0.5+0.5;
|
||||
|
||||
float shadow_attenuation;
|
||||
|
||||
#ifdef SHADOW_PCF5
|
||||
|
||||
shadow_attenuation=0.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*2.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*2.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation/=5.0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_PCF13
|
||||
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*2.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*3.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*4.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*5.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su+shadowpixel_size*6.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*2.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*3.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*4.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*5.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation += texture2D(shadow_texture,vec2(su-shadowpixel_size*6.0,sh)).z<sz?0.0:1.0;
|
||||
shadow_attenuation/=13.0;
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SHADOW_ESM
|
||||
|
||||
|
||||
{
|
||||
float unnormalized = su/shadowpixel_size;
|
||||
float fractional = fract(unnormalized);
|
||||
unnormalized = floor(unnormalized);
|
||||
float zc = texture2D(shadow_texture,vec2((unnormalized-0.5)*shadowpixel_size,sh)).z;
|
||||
float zn = texture2D(shadow_texture,vec2((unnormalized+0.5)*shadowpixel_size,sh)).z;
|
||||
float z = mix(zc,zn,fractional);
|
||||
shadow_attenuation=clamp(exp(shadow_esm_multiplier* ( z - sz )),0.0,1.0);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !defined(SHADOW_PCF5) && !defined(SHADOW_PCF13) && !defined(SHADOW_ESM)
|
||||
|
||||
shadow_attenuation = texture2D(shadow_texture,vec2(su+shadowpixel_size,sh)).z<sz?0.0:1.0;
|
||||
|
||||
#endif
|
||||
|
||||
light*=shadow_attenuation;
|
||||
//use shadows
|
||||
#endif
|
||||
|
||||
#if defined(USE_LIGHT_SHADER_CODE)
|
||||
//light is written by the light shader
|
||||
{
|
||||
vec2 light_dir = normalize(light_tex_pos.zw);
|
||||
float light_distance = length(light_tex_pos.zw);
|
||||
vec2 light_dir = normalize(light_uv_interp.zw);
|
||||
float light_distance = length(light_uv_interp.zw);
|
||||
LIGHT_SHADER_CODE
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#if defined(NORMAL_USED)
|
||||
vec2 light_normal = normalize(light_tex_pos.zw);
|
||||
light = color.rgb * light * max(dot(light_normal,normal),0);
|
||||
vec3 light_normal = normalize(vec3(light_uv_interp.zw,-light_height));
|
||||
light*=max(dot(-light_normal,normal),0);
|
||||
#endif
|
||||
|
||||
color.rgb=light;
|
||||
color*=light;
|
||||
/*
|
||||
#ifdef USE_NORMAL
|
||||
color.xy=local_rot.xy;//normal.xy;
|
||||
color.zw=vec2(0.0,1.0);
|
||||
#endif
|
||||
*/
|
||||
if (any(lessThan(light_uv_interp.xy,vec2(0.0,0.0))) || any(greaterThanEqual(light_uv_interp.xy,vec2(1.0,1.0)))) {
|
||||
color.a=0.0; //invisible
|
||||
}
|
||||
|
||||
//light shader code
|
||||
#endif
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
[vertex]
|
||||
|
||||
#ifdef USE_GLES_OVER_GL
|
||||
#define mediump
|
||||
#define highp
|
||||
#else
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
uniform highp mat4 projection_matrix;
|
||||
uniform highp mat4 light_matrix;
|
||||
uniform highp mat4 world_matrix;
|
||||
|
||||
attribute highp vec3 vertex; // attrib:0
|
||||
|
||||
#ifndef USE_DEPTH_SHADOWS
|
||||
|
||||
varying vec4 position_interp;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void main() {
|
||||
|
||||
gl_Position = projection_matrix * (light_matrix * (world_matrix * vec4(vertex,1.0)));
|
||||
|
||||
#ifndef USE_DEPTH_SHADOWS
|
||||
position_interp = gl_Position;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
[fragment]
|
||||
|
||||
#ifdef USE_GLES_OVER_GL
|
||||
#define mediump
|
||||
#define highp
|
||||
#else
|
||||
precision mediump float;
|
||||
precision mediump int;
|
||||
#endif
|
||||
|
||||
#ifndef USE_DEPTH_SHADOWS
|
||||
|
||||
varying vec4 position_interp;
|
||||
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef USE_DEPTH_SHADOWS
|
||||
|
||||
#else
|
||||
highp float depth = ((position_interp.z / position_interp.w) + 1.0) * 0.5 + 0.0;//bias;
|
||||
highp vec4 comp = fract(depth * vec4(256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0));
|
||||
comp -= comp.xxyz * vec4(0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0);
|
||||
gl_FragColor = comp;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
|
@ -28,14 +28,18 @@
|
|||
/*************************************************************************/
|
||||
#ifdef WINDOWS_ENABLED
|
||||
|
||||
#include <Windows.h>
|
||||
#include "Shlwapi.h"
|
||||
#include "file_access_windows.h"
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <wchar.h>
|
||||
#include <tchar.h>
|
||||
#include "print_string.h"
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define S_ISREG(m) ((m)&_S_IFREG)
|
||||
#endif
|
||||
|
@ -111,10 +115,20 @@ void FileAccessWindows::close() {
|
|||
|
||||
//unlink(save_path.utf8().get_data());
|
||||
//print_line("renaming..");
|
||||
_wunlink(save_path.c_str()); //unlink if exists
|
||||
int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());
|
||||
//_wunlink(save_path.c_str()); //unlink if exists
|
||||
//int rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str());
|
||||
|
||||
|
||||
bool rename_error;
|
||||
if (!PathFileExistsW(save_path.c_str())) {
|
||||
//creating new file
|
||||
rename_error = _wrename((save_path+".tmp").c_str(),save_path.c_str())!=0;
|
||||
} else {
|
||||
//atomic replace for existing file
|
||||
rename_error = !ReplaceFileW(save_path.c_str(), (save_path+".tmp").c_str(), NULL, 2|4, NULL, NULL);
|
||||
}
|
||||
save_path="";
|
||||
ERR_FAIL_COND( rename_error != 0);
|
||||
ERR_FAIL_COND( rename_error );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1291,6 +1291,14 @@ def android_module_manifest(self,file):
|
|||
base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file
|
||||
f = open(base_path,"rb")
|
||||
self.android_manifest_chunk+=f.read()
|
||||
def android_module_permission(self,file):
|
||||
base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file
|
||||
f = open(base_path,"rb")
|
||||
self.android_permission_chunk+=f.read()
|
||||
def android_module_attribute(self,file):
|
||||
base_path = self.Dir(".").abspath+"/modules/"+self.current_module+"/"+file
|
||||
f = open(base_path,"rb")
|
||||
self.android_appattributes_chunk+=f.read()
|
||||
|
||||
def disable_module(self):
|
||||
self.disabled_modules.append(self.current_module)
|
||||
|
|
|
@ -2696,7 +2696,10 @@ Error ResourceFormatSaverGDScript::save(const String &p_path,const RES& p_resour
|
|||
}
|
||||
|
||||
file->store_string(source);
|
||||
|
||||
if (file->get_error()!=OK && file->get_error()!=ERR_FILE_EOF) {
|
||||
memdelete(file);
|
||||
return ERR_CANT_CREATE;
|
||||
}
|
||||
file->close();
|
||||
memdelete(file);
|
||||
return OK;
|
||||
|
|
|
@ -538,9 +538,12 @@ void GDTokenizerText::_advance() {
|
|||
is_node_path=true;
|
||||
|
||||
case '\'':
|
||||
string_mode=STRING_SINGLE_QUOTE;
|
||||
case '"': {
|
||||
|
||||
if (GETCHAR(0)=='\'')
|
||||
string_mode=STRING_SINGLE_QUOTE;
|
||||
|
||||
|
||||
int i=1;
|
||||
if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') {
|
||||
i+=2;
|
||||
|
|
|
@ -418,6 +418,7 @@ void GridMap::set_cell_item(int p_x,int p_y,int p_z, int p_item,int p_rot){
|
|||
Octant *g = memnew( Octant );
|
||||
g->dirty=true;
|
||||
g->static_body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
|
||||
PhysicsServer::get_singleton()->body_attach_object_instance_ID(g->static_body,get_instance_ID());
|
||||
if (is_inside_world())
|
||||
PhysicsServer::get_singleton()->body_set_space(g->static_body,get_world()->get_space());
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
android:largeScreens="true"
|
||||
android:xlargeScreens="true"/>
|
||||
|
||||
<application android:label="@string/godot_project_name_string" android:icon="@drawable/icon" android:allowBackup="false">
|
||||
<application android:label="@string/godot_project_name_string" android:icon="@drawable/icon" android:allowBackup="false" $$ADD_APPATTRIBUTE_CHUNKS$$ >
|
||||
<activity android:name="com.android.godot.Godot"
|
||||
android:label="@string/godot_project_name_string"
|
||||
android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
|
||||
|
@ -33,6 +33,7 @@ $$ADD_APPLICATION_CHUNKS$$
|
|||
</application>
|
||||
<uses-feature android:glEsVersion="0x00020000"/>
|
||||
|
||||
$$ADD_PERMISSION_CHUNKS$$
|
||||
<uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/>
|
||||
<uses-permission android:name="godot.ACCESS_COARSE_LOCATION"/>
|
||||
<uses-permission android:name="godot.ACCESS_FINE_LOCATION"/>
|
||||
|
|
|
@ -56,6 +56,8 @@ pp_basein = open(abspath+"/AndroidManifest.xml.template","rb")
|
|||
pp_baseout = open(abspath+"/java/AndroidManifest.xml","wb")
|
||||
manifest = pp_basein.read()
|
||||
manifest = manifest.replace("$$ADD_APPLICATION_CHUNKS$$",env.android_manifest_chunk)
|
||||
manifest = manifest.replace("$$ADD_PERMISSION_CHUNKS$$",env.android_permission_chunk)
|
||||
manifest = manifest.replace("$$ADD_APPATTRIBUTE_CHUNKS$$",env.android_appattributes_chunk)
|
||||
pp_baseout.write( manifest )
|
||||
|
||||
|
||||
|
|
|
@ -396,6 +396,14 @@ void AudioDriverOpenSL::finish(){
|
|||
void AudioDriverOpenSL::set_pause(bool p_pause) {
|
||||
|
||||
pause=p_pause;
|
||||
|
||||
if (active) {
|
||||
if (pause) {
|
||||
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PAUSED);
|
||||
} else {
|
||||
(*playItf)->SetPlayState(playItf, SL_PLAYSTATE_PLAYING);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -45,9 +45,18 @@ static JavaClassWrapper *java_class_wrapper=NULL;
|
|||
static OS_Android *os_android=NULL;
|
||||
|
||||
|
||||
jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) {
|
||||
struct jvalret {
|
||||
|
||||
jvalue v;
|
||||
jobject obj;
|
||||
jvalue val;
|
||||
jvalret() { obj=NULL; }
|
||||
|
||||
|
||||
};
|
||||
|
||||
jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_arg, bool force_jobject = false) {
|
||||
|
||||
jvalret v;
|
||||
|
||||
switch(p_type) {
|
||||
|
||||
|
@ -59,9 +68,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jvalue val;
|
||||
val.z = (bool)(*p_arg);
|
||||
jobject obj = env->NewObjectA(bclass, ctor, &val);
|
||||
v.l = obj;
|
||||
v.val.l = obj;
|
||||
v.obj=obj;
|
||||
env->DeleteLocalRef(bclass);
|
||||
} else {
|
||||
v.z=*p_arg;
|
||||
v.val.z=*p_arg;
|
||||
|
||||
};
|
||||
} break;
|
||||
case Variant::INT: {
|
||||
|
@ -73,10 +85,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jvalue val;
|
||||
val.i = (int)(*p_arg);
|
||||
jobject obj = env->NewObjectA(bclass, ctor, &val);
|
||||
v.l = obj;
|
||||
v.val.l = obj;
|
||||
v.obj=obj;
|
||||
env->DeleteLocalRef(bclass);
|
||||
|
||||
} else {
|
||||
v.i=*p_arg;
|
||||
v.val.i=*p_arg;
|
||||
|
||||
};
|
||||
} break;
|
||||
case Variant::REAL: {
|
||||
|
@ -88,17 +103,20 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jvalue val;
|
||||
val.d = (double)(*p_arg);
|
||||
jobject obj = env->NewObjectA(bclass, ctor, &val);
|
||||
v.l = obj;
|
||||
v.val.l = obj;
|
||||
v.obj=obj;
|
||||
env->DeleteLocalRef(bclass);
|
||||
|
||||
} else {
|
||||
v.f=*p_arg;
|
||||
v.val.f=*p_arg;
|
||||
};
|
||||
} break;
|
||||
case Variant::STRING: {
|
||||
|
||||
String s = *p_arg;
|
||||
jstring jStr = env->NewStringUTF(s.utf8().get_data());
|
||||
v.l=jStr;
|
||||
v.val.l=jStr;
|
||||
v.obj=jStr;
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
|
@ -107,9 +125,12 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
|
||||
for(int j=0;j<sarray.size();j++) {
|
||||
|
||||
env->SetObjectArrayElement(arr,j,env->NewStringUTF( sarray[j].utf8().get_data() ));
|
||||
jstring str = env->NewStringUTF( sarray[j].utf8().get_data() );
|
||||
env->SetObjectArrayElement(arr,j,str);
|
||||
env->DeleteLocalRef(str);
|
||||
}
|
||||
v.l=arr;
|
||||
v.val.l=arr;
|
||||
v.obj=arr;
|
||||
|
||||
} break;
|
||||
|
||||
|
@ -124,27 +145,36 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
|
||||
jobjectArray jkeys = env->NewObjectArray(keys.size(), env->FindClass("java/lang/String"), env->NewStringUTF(""));
|
||||
for (int j=0; j<keys.size(); j++) {
|
||||
env->SetObjectArrayElement(jkeys, j, env->NewStringUTF(String(keys[j]).utf8().get_data()));
|
||||
jstring str = env->NewStringUTF(String(keys[j]).utf8().get_data());
|
||||
env->SetObjectArrayElement(jkeys, j, str);
|
||||
env->DeleteLocalRef(str);
|
||||
};
|
||||
|
||||
jmethodID set_keys = env->GetMethodID(dclass, "set_keys", "([Ljava/lang/String;)V");
|
||||
jvalue val;
|
||||
val.l = jkeys;
|
||||
env->CallVoidMethodA(jdict, set_keys, &val);
|
||||
env->DeleteLocalRef(jkeys);
|
||||
|
||||
jobjectArray jvalues = env->NewObjectArray(keys.size(), env->FindClass("java/lang/Object"), NULL);
|
||||
|
||||
for (int j=0; j<keys.size(); j++) {
|
||||
Variant var = dict[keys[j]];
|
||||
val = _variant_to_jvalue(env, var.get_type(), &var, true);
|
||||
env->SetObjectArrayElement(jvalues, j, val.l);
|
||||
jvalret v = _variant_to_jvalue(env, var.get_type(), &var, true);
|
||||
env->SetObjectArrayElement(jvalues, j, v.val.l);
|
||||
if (v.obj) {
|
||||
env->DeleteLocalRef(v.obj);
|
||||
}
|
||||
};
|
||||
|
||||
jmethodID set_values = env->GetMethodID(dclass, "set_values", "([Ljava/lang/Object;)V");
|
||||
val.l = jvalues;
|
||||
env->CallVoidMethodA(jdict, set_values, &val);
|
||||
env->DeleteLocalRef(jvalues);
|
||||
env->DeleteLocalRef(dclass);
|
||||
|
||||
v.l = jdict;
|
||||
v.val.l = jdict;
|
||||
v.obj=jdict;
|
||||
} break;
|
||||
|
||||
case Variant::INT_ARRAY: {
|
||||
|
@ -153,7 +183,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jintArray arr = env->NewIntArray(array.size());
|
||||
DVector<int>::Read r = array.read();
|
||||
env->SetIntArrayRegion(arr,0,array.size(),r.ptr());
|
||||
v.l=arr;
|
||||
v.val.l=arr;
|
||||
v.obj=arr;
|
||||
|
||||
} break;
|
||||
case Variant::RAW_ARRAY: {
|
||||
|
@ -161,7 +192,8 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jbyteArray arr = env->NewByteArray(array.size());
|
||||
DVector<uint8_t>::Read r = array.read();
|
||||
env->SetByteArrayRegion(arr,0,array.size(),reinterpret_cast<const signed char*>(r.ptr()));
|
||||
v.l=arr;
|
||||
v.val.l=arr;
|
||||
v.obj=arr;
|
||||
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
@ -170,12 +202,13 @@ jvalue _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant* p_ar
|
|||
jfloatArray arr = env->NewFloatArray(array.size());
|
||||
DVector<float>::Read r = array.read();
|
||||
env->SetFloatArrayRegion(arr,0,array.size(),r.ptr());
|
||||
v.l=arr;
|
||||
v.val.l=arr;
|
||||
v.obj=arr;
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
||||
v.i = 0;
|
||||
v.val.i = 0;
|
||||
} break;
|
||||
|
||||
}
|
||||
|
@ -193,8 +226,11 @@ String _get_class_name(JNIEnv * env, jclass cls, bool* array) {
|
|||
jboolean isarr = env->CallBooleanMethod(cls, isArray);
|
||||
(*array) = isarr ? true : false;
|
||||
}
|
||||
String name = env->GetStringUTFChars( clsName, NULL );
|
||||
env->DeleteLocalRef(clsName);
|
||||
|
||||
return name;
|
||||
|
||||
return env->GetStringUTFChars( clsName, NULL );
|
||||
};
|
||||
|
||||
|
||||
|
@ -223,6 +259,8 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
|
|||
jstring string = (jstring) env->GetObjectArrayElement(arr, i);
|
||||
const char *rawString = env->GetStringUTFChars(string, 0);
|
||||
sarr.push_back(String(rawString));
|
||||
env->DeleteLocalRef(string);
|
||||
|
||||
}
|
||||
|
||||
return sarr;
|
||||
|
@ -321,30 +359,34 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
|
|||
|
||||
jobjectArray arr = (jobjectArray)obj;
|
||||
int objCount = env->GetArrayLength(arr);
|
||||
Array varr;
|
||||
Array varr(true);
|
||||
|
||||
for (int i=0; i<objCount; i++) {
|
||||
jobject jobj = env->GetObjectArrayElement(arr, i);
|
||||
Variant v = _jobject_to_variant(env, jobj);
|
||||
varr.push_back(v);
|
||||
env->DeleteLocalRef(jobj);
|
||||
|
||||
}
|
||||
|
||||
return varr;
|
||||
};
|
||||
|
||||
if (name == "com.android.godot.Dictionary") {
|
||||
if (name == "java.util.HashMap" || name == "com.android.godot.Dictionary") {
|
||||
|
||||
Dictionary ret;
|
||||
Dictionary ret(true);
|
||||
jclass oclass = c;
|
||||
jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;");
|
||||
jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys);
|
||||
|
||||
StringArray keys = _jobject_to_variant(env, arr);
|
||||
env->DeleteLocalRef(arr);
|
||||
|
||||
jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;");
|
||||
arr = (jobjectArray)env->CallObjectMethod(obj, get_values);
|
||||
|
||||
Array vals = _jobject_to_variant(env, arr);
|
||||
env->DeleteLocalRef(arr);
|
||||
|
||||
//print_line("adding " + String::num(keys.size()) + " to Dictionary!");
|
||||
for (int i=0; i<keys.size(); i++) {
|
||||
|
@ -352,9 +394,12 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
|
|||
ret[keys[i]] = vals[i];
|
||||
};
|
||||
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
env->DeleteLocalRef(c);
|
||||
|
||||
return Variant();
|
||||
};
|
||||
|
||||
|
@ -432,9 +477,13 @@ public:
|
|||
JNIEnv *env = ThreadAndroid::get_env();
|
||||
|
||||
//print_line("argcount "+String::num(p_argcount));
|
||||
List<jobject> to_erase;
|
||||
for(int i=0;i<p_argcount;i++) {
|
||||
|
||||
v[i] = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
|
||||
jvalret vr = _variant_to_jvalue(env, E->get().argtypes[i], p_args[i]);
|
||||
v[i] = vr.val;
|
||||
if (vr.obj)
|
||||
to_erase.push_back(vr.obj);
|
||||
}
|
||||
|
||||
//print_line("calling method!!");
|
||||
|
@ -468,6 +517,7 @@ public:
|
|||
jobject o = env->CallObjectMethodA(instance,E->get().method,v);
|
||||
String str = env->GetStringUTFChars((jstring)o, NULL );
|
||||
ret=str;
|
||||
env->DeleteLocalRef(o);
|
||||
} break;
|
||||
case Variant::STRING_ARRAY: {
|
||||
|
||||
|
@ -475,6 +525,7 @@ public:
|
|||
|
||||
ret = _jobject_to_variant(env, arr);
|
||||
|
||||
env->DeleteLocalRef(arr);
|
||||
} break;
|
||||
case Variant::INT_ARRAY: {
|
||||
|
||||
|
@ -488,6 +539,7 @@ public:
|
|||
env->GetIntArrayRegion(arr,0,fCount,w.ptr());
|
||||
w = DVector<int>::Write();
|
||||
ret=sarr;
|
||||
env->DeleteLocalRef(arr);
|
||||
} break;
|
||||
case Variant::REAL_ARRAY: {
|
||||
|
||||
|
@ -501,6 +553,7 @@ public:
|
|||
env->GetFloatArrayRegion(arr,0,fCount,w.ptr());
|
||||
w = DVector<float>::Write();
|
||||
ret=sarr;
|
||||
env->DeleteLocalRef(arr);
|
||||
} break;
|
||||
|
||||
case Variant::DICTIONARY: {
|
||||
|
@ -508,6 +561,7 @@ public:
|
|||
//print_line("call dictionary");
|
||||
jobject obj = env->CallObjectMethodA(instance, E->get().method, v);
|
||||
ret = _jobject_to_variant(env, obj);
|
||||
env->DeleteLocalRef(obj);
|
||||
|
||||
} break;
|
||||
default: {
|
||||
|
@ -518,6 +572,10 @@ public:
|
|||
} break;
|
||||
}
|
||||
|
||||
while (to_erase.size()) {
|
||||
env->DeleteLocalRef(to_erase.front()->get());
|
||||
to_erase.pop_front();
|
||||
}
|
||||
//print_line("success");
|
||||
|
||||
return ret;
|
||||
|
@ -872,6 +930,7 @@ static void _initialize_java_modules() {
|
|||
|
||||
String modules = Globals::get_singleton()->get("android/modules");
|
||||
Vector<String> mods = modules.split(",",false);
|
||||
print_line("ANDROID MODULES : " + modules);
|
||||
__android_log_print(ANDROID_LOG_INFO,"godot","mod count: %i",mods.size());
|
||||
|
||||
if (mods.size()) {
|
||||
|
@ -1571,6 +1630,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_callobject(JNIEnv * env,
|
|||
memnew_placement(&vlist[i], Variant);
|
||||
vlist[i] = v;
|
||||
vptr[i] = &vlist[i];
|
||||
env->DeleteLocalRef(obj);
|
||||
|
||||
};
|
||||
|
||||
Variant::CallError err;
|
||||
|
@ -1595,6 +1656,8 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_calldeferred(JNIEnv * env
|
|||
jobject obj = env->GetObjectArrayElement(params, i);
|
||||
if (obj)
|
||||
args[i] = _jobject_to_variant(env, obj);
|
||||
env->DeleteLocalRef(obj);
|
||||
|
||||
// print_line("\targ"+itos(i)+": "+Variant::get_type_name(args[i].get_type()));
|
||||
|
||||
};
|
||||
|
|
|
@ -151,7 +151,7 @@ void OS_Android::initialize(const VideoMode& p_desired,int p_video_driver,int p_
|
|||
sample_manager = memnew( SampleManagerMallocSW );
|
||||
audio_server = memnew( AudioServerSW(sample_manager) );
|
||||
|
||||
audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,false);
|
||||
audio_server->set_mixer_params(AudioMixerSW::INTERPOLATION_LINEAR,true);
|
||||
audio_server->init();
|
||||
|
||||
spatial_sound_server = memnew( SpatialSoundServerSW );
|
||||
|
|
|
@ -18,13 +18,5 @@ if env['bb10_lgles_override'] == "yes":
|
|||
|
||||
|
||||
prog = None
|
||||
if env["target"]=="release":
|
||||
prog = env_bps.Program('#platform/bb10/godot_bb10_opt', bb10_lib)
|
||||
else:
|
||||
prog = env_bps.Program('#platform/bb10/godot_bb10', bb10_lib)
|
||||
|
||||
import os
|
||||
fname = os.path.basename(str(prog[0]))
|
||||
|
||||
env.Command('#bin/'+fname, prog, Copy('bin/'+fname, prog[0]))
|
||||
prog = env_bps.Program('#bin/godot', bb10_lib)
|
||||
|
||||
|
|
|
@ -1,65 +1,53 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
||||
<?xml version='1.0' encoding='utf-8' standalone='no'?>
|
||||
<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
|
||||
|
||||
<!-- BlackBerry® 10 application descriptor file.
|
||||
|
||||
Specifies parameters for identifying, installing, and launching native applications on BlackBerry® 10 OS.
|
||||
-->
|
||||
|
||||
<!-- A universally unique application identifier. Must be unique across all BlackBerry applications.
|
||||
Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
|
||||
<id>com.godot.game</id>
|
||||
|
||||
<!-- The name that is displayed in the BlackBerry application installer.
|
||||
May have multiple values for each language. See samples or xsd schema file. Optional. -->
|
||||
<name>Godot Game</name>
|
||||
|
||||
<!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade.
|
||||
Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
|
||||
An updated version of application must have a versionNumber value higher than the previous version. Required. -->
|
||||
<versionNumber>0.0.1</versionNumber>
|
||||
|
||||
<!-- Fourth digit segment of the package version. First three segments are taken from the
|
||||
<versionNumber> element. Must be an integer from 0 to 2^16-1 -->
|
||||
<buildId>0</buildId>
|
||||
|
||||
<!-- Description, displayed in the BlackBerry application installer.
|
||||
May have multiple values for each language. See samples or xsd schema file. Optional. -->
|
||||
<description>Game made with Godot Engine</description>
|
||||
|
||||
<!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
|
||||
<author>You Name or Company</author>
|
||||
<authorId>authorIDherePlease</authorId>
|
||||
|
||||
<!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
|
||||
<!-- <authorId>ABC1234YjsnUk235h</authorId> -->
|
||||
|
||||
<initialWindow>
|
||||
<aspectRatio>landscape</aspectRatio>
|
||||
<autoOrients>false</autoOrients>
|
||||
<systemChrome>none</systemChrome>
|
||||
<transparent>false</transparent>
|
||||
</initialWindow>
|
||||
|
||||
<!-- The category where the application appears. Either core.games or core.media. -->
|
||||
<category>core.games</category>
|
||||
<permission>read_device_identifying_information</permission>
|
||||
<permission>access_internet</permission>
|
||||
<asset path="assets">assets</asset>
|
||||
<asset path="data.pck">data.pck</asset>
|
||||
<configuration name="Device-Debug">
|
||||
<platformArchitecture>armle-v7</platformArchitecture>
|
||||
<asset path="godot_bb10.qnx.armle" entry="true" type="Qnx/Elf">godot_bb10.qnx.armle</asset>
|
||||
<asset type="Qnx/Elf" path="godot.bb10.debug.qnx.armle" entry="true">godot.bb10.debug.qnx.armle</asset>
|
||||
</configuration>
|
||||
<configuration name="Device-Release">
|
||||
<platformArchitecture>armle-v7</platformArchitecture>
|
||||
<asset path="godot_bb10_opt.qnx.armle" entry="true" type="Qnx/Elf">godot_bb10_opt.qnx.armle</asset>
|
||||
<asset type="Qnx/Elf" path="godot.bb10.opt.qnx.armle" entry="true">godot.bb10.opt.qnx.armle</asset>
|
||||
</configuration>
|
||||
<!-- The icon for the application. -->
|
||||
<icon>
|
||||
<image>icon.png</image>
|
||||
</icon>
|
||||
|
||||
<!-- Ensure that shared libraries in the package are found at run-time. -->
|
||||
<env var="LD_LIBRARY_PATH" value="app/native/lib:/usr/lib/qt4/lib"/>
|
||||
|
||||
<env value="app/native/lib:/usr/lib/qt4/lib" var="LD_LIBRARY_PATH"/>
|
||||
</qnx>
|
||||
|
|
|
@ -81,8 +81,6 @@ def configure(env):
|
|||
if (env["target"]=="release"):
|
||||
|
||||
env.Append(CCFLAGS=['-O3','-DRELEASE_BUILD'])
|
||||
env['OBJSUFFIX'] = "_opt"+env['OBJSUFFIX']
|
||||
env['LIBSUFFIX'] = "_opt"+env['LIBSUFFIX']
|
||||
|
||||
elif (env["target"]=="debug"):
|
||||
|
||||
|
|
|
@ -321,12 +321,29 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
|
|||
//BE SUPER CAREFUL WITH THIS PLEASE!!!
|
||||
//BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!
|
||||
|
||||
if (bar_dir.ends_with("bb10_export")) {
|
||||
Error err = da->erase_contents_recursive();
|
||||
bool berr = bar_dir.ends_with("bb10_export");
|
||||
if (berr) {
|
||||
if (da->list_dir_begin()) {
|
||||
EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
|
||||
ERR_FAIL_COND_V(berr,FAILED);
|
||||
};
|
||||
|
||||
String f = da->get_next();
|
||||
while (f != "") {
|
||||
|
||||
if (f == "." || f == "..") {
|
||||
f = da->get_next();
|
||||
continue;
|
||||
};
|
||||
Error err = da->remove(bar_dir + "/" + f);
|
||||
if (err != OK) {
|
||||
EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
|
||||
ERR_FAIL_COND_V(err!=OK,err);
|
||||
}
|
||||
};
|
||||
f = da->get_next();
|
||||
};
|
||||
|
||||
da->list_dir_end();
|
||||
|
||||
} else {
|
||||
print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
|
||||
|
@ -405,52 +422,23 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
|
|||
ret = unzGoToNextFile(pkg);
|
||||
}
|
||||
|
||||
ep.step("Finding Files..",1);
|
||||
|
||||
Vector<StringName> files=get_dependencies(false);
|
||||
|
||||
ep.step("Adding Files..",2);
|
||||
|
||||
da->change_dir(bar_dir);
|
||||
da->make_dir("assets");
|
||||
Error err = da->change_dir("assets");
|
||||
ERR_FAIL_COND_V(err,err);
|
||||
|
||||
String asset_dir=da->get_current_dir();
|
||||
if (!asset_dir.ends_with("/"))
|
||||
asset_dir+="/";
|
||||
|
||||
for(int i=0;i<files.size();i++) {
|
||||
|
||||
String fname=files[i];
|
||||
Vector<uint8_t> data = get_exported_file(fname);
|
||||
/*
|
||||
FileAccess *f=FileAccess::open(files[i],FileAccess::READ);
|
||||
if (!f) {
|
||||
EditorNode::add_io_error("Couldn't read: "+String(files[i]));
|
||||
FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE);
|
||||
if (!dst) {
|
||||
EditorNode::add_io_error("Can't copy executable file to:\n "+p_path);
|
||||
return ERR_FILE_CANT_WRITE;
|
||||
}
|
||||
ERR_CONTINUE(!f);
|
||||
data.resize(f->get_len());
|
||||
f->get_buffer(data.ptr(),data.size());
|
||||
*/
|
||||
String dst_path=fname;
|
||||
dst_path=dst_path.replace_first("res://",asset_dir);
|
||||
|
||||
da->make_dir_recursive(dst_path.get_base_dir());
|
||||
|
||||
ep.step("Adding File: "+String(files[i]).get_file(),3+i*100/files.size());
|
||||
|
||||
FileAccessRef fr = FileAccess::open(dst_path,FileAccess::WRITE);
|
||||
fr->store_buffer(data.ptr(),data.size());
|
||||
}
|
||||
|
||||
save_pack(dst, false, 1024);
|
||||
dst->close();
|
||||
memdelete(dst);
|
||||
|
||||
ep.step("Creating BAR Package..",104);
|
||||
|
||||
String bb_packager=EditorSettings::get_singleton()->get("blackberry/host_tools");
|
||||
bb_packager=bb_packager.plus_file("blackberry-nativepackager");
|
||||
if (OS::get_singleton()->get_name()=="Windows")
|
||||
bb_packager+=".exe";
|
||||
bb_packager+=".bat";
|
||||
|
||||
|
||||
if (!FileAccess::exists(bb_packager)) {
|
||||
|
@ -482,7 +470,7 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
|
|||
|
||||
int ec;
|
||||
|
||||
err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
|
||||
Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
|
||||
|
||||
if (err!=OK)
|
||||
return err;
|
||||
|
@ -493,7 +481,6 @@ Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debu
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool EditorExportPlatformBB10::poll_devices() {
|
||||
|
||||
bool dc=devices_changed;
|
||||
|
@ -537,7 +524,7 @@ void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
|
|||
bb_deploy=bb_deploy.plus_file("blackberry-deploy");
|
||||
bool windows = OS::get_singleton()->get_name()=="Windows";
|
||||
if (windows)
|
||||
bb_deploy+=".exe";
|
||||
bb_deploy+=".bat";
|
||||
|
||||
if (!FileAccess::exists(bb_deploy)) {
|
||||
OS::get_singleton()->delay_usec(3000000);
|
||||
|
@ -639,7 +626,7 @@ Error EditorExportPlatformBB10::run(int p_device, bool p_dumb) {
|
|||
String bb_deploy=EditorSettings::get_singleton()->get("blackberry/host_tools");
|
||||
bb_deploy=bb_deploy.plus_file("blackberry-deploy");
|
||||
if (OS::get_singleton()->get_name()=="Windows")
|
||||
bb_deploy+=".exe";
|
||||
bb_deploy+=".bat";
|
||||
|
||||
if (!FileAccess::exists(bb_deploy)) {
|
||||
EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy);
|
||||
|
|
|
@ -619,7 +619,7 @@ OSBB10::OSBB10() {
|
|||
printf("godot bb10!\n");
|
||||
getcwd(launch_dir, sizeof(launch_dir));
|
||||
printf("launch dir %s\n", launch_dir);
|
||||
chdir("app/native/assets");
|
||||
chdir("app/native");
|
||||
launch_dir_ptr = launch_dir;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,6 +101,8 @@
|
|||
- (BOOL)createFramebuffer;
|
||||
- (void)destroyFramebuffer;
|
||||
|
||||
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification;
|
||||
|
||||
@property NSTimeInterval animationInterval;
|
||||
|
||||
@end
|
||||
|
|
|
@ -119,6 +119,8 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
|
|||
name:AVPlayerItemDidPlayToEndTimeNotification
|
||||
object:[_instance.avPlayer currentItem]];
|
||||
|
||||
[_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0];
|
||||
|
||||
[_instance.avPlayerLayer setFrame:_instance.bounds];
|
||||
[_instance.layer addSublayer:_instance.avPlayerLayer];
|
||||
[_instance.avPlayer play];
|
||||
|
@ -610,6 +612,39 @@ static void clear_touches() {
|
|||
printf("inserting text with character %i\n", character[0]);
|
||||
};
|
||||
|
||||
- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
|
||||
{
|
||||
printf("*********** route changed!%i\n");
|
||||
NSDictionary *interuptionDict = notification.userInfo;
|
||||
|
||||
NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue];
|
||||
|
||||
switch (routeChangeReason) {
|
||||
|
||||
case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
|
||||
NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
|
||||
NSLog(@"Headphone/Line plugged in");
|
||||
break;
|
||||
|
||||
case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
|
||||
NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
|
||||
NSLog(@"Headphone/Line was pulled. Resuming video play....");
|
||||
if (_is_video_playing) {
|
||||
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
[_instance.avPlayer play]; // NOTE: change this line according your current player implementation
|
||||
NSLog(@"resumed play");
|
||||
});
|
||||
};
|
||||
break;
|
||||
|
||||
case AVAudioSessionRouteChangeReasonCategoryChange:
|
||||
// called at start - also when other audio wants to play
|
||||
NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// When created via code however, we get initWithFrame
|
||||
-(id)initWithFrame:(CGRect)frame
|
||||
|
@ -625,6 +660,11 @@ static void clear_touches() {
|
|||
init_touches();
|
||||
self. multipleTouchEnabled = YES;
|
||||
|
||||
printf("******** adding observer for sound routing changes\n");
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:)
|
||||
name:AVAudioSessionRouteChangeNotification
|
||||
object:nil];
|
||||
|
||||
//self.autoresizesSubviews = YES;
|
||||
//[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
|
||||
|
||||
|
@ -674,6 +714,18 @@ static void clear_touches() {
|
|||
video_current_time = kCMTimeZero;
|
||||
}
|
||||
}
|
||||
|
||||
if (object == _instance.avPlayer && [keyPath isEqualToString:@"rate"]) {
|
||||
NSLog(@"Player playback rate changed: %.5f", _instance.avPlayer.rate);
|
||||
if (_is_video_playing() && _instance.avPlayer.rate == 0.0 && !_instance.avPlayer.error) {
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
|
||||
[_instance.avPlayer play]; // NOTE: change this line according your current player implementation
|
||||
NSLog(@"resumed play");
|
||||
});
|
||||
|
||||
NSLog(@" . . . PAUSED (or just started)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)playerItemDidReachEnd:(NSNotification *)notification {
|
||||
|
|
|
@ -1100,7 +1100,7 @@ void OS_OSX::warp_mouse_pos(const Point2& p_to) {
|
|||
NSPoint localPoint = { p_to.x, p_to.y };
|
||||
|
||||
NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil];
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(CGRect){.origin=pointInWindow}];
|
||||
NSPoint pointOnScreen = [[window_view window] convertRectToScreen:(NSRect){.origin=pointInWindow}].origin;
|
||||
|
||||
//point in scren coords
|
||||
CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y};
|
||||
|
|
|
@ -115,7 +115,7 @@ def configure(env):
|
|||
env.Append(CCFLAGS=['/DGLES2_ENABLED'])
|
||||
|
||||
env.Append(CCFLAGS=['/DGLEW_ENABLED'])
|
||||
LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI', 'wsock32', 'shell32','advapi32']
|
||||
LIBS=['winmm','opengl32','dsound','kernel32','ole32','user32','gdi32', 'IPHLPAPI','Shlwapi', 'wsock32', 'shell32','advapi32']
|
||||
env.Append(LINKFLAGS=[p+env["LIBSUFFIX"] for p in LIBS])
|
||||
|
||||
env.Append(LIBPATH=[os.getenv("WindowsSdkDir")+"/Lib"])
|
||||
|
@ -229,7 +229,7 @@ def configure(env):
|
|||
env.Append(CCFLAGS=['-DWINDOWS_ENABLED','-mwindows'])
|
||||
env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
|
||||
env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLEW_ENABLED'])
|
||||
env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32'])
|
||||
env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','shlwapi','wsock32','kernel32'])
|
||||
|
||||
if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"):
|
||||
# env.Append(LIBS=['gcc_s'])
|
||||
|
|
|
@ -716,8 +716,13 @@ String OS_Windows::get_joystick_name(int id, JOYCAPS jcaps)
|
|||
|
||||
_snprintf( buffer, sizeof(buffer), "%s\\%s", REGSTR_PATH_JOYOEM, OEM);
|
||||
res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, buffer, 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (res != ERROR_SUCCESS)
|
||||
{
|
||||
res = RegOpenKeyEx(HKEY_CURRENT_USER, buffer, 0, KEY_QUERY_VALUE, &hKey);
|
||||
if (res != ERROR_SUCCESS)
|
||||
return "";
|
||||
}
|
||||
|
||||
|
||||
sz = sizeof(buffer);
|
||||
res = RegQueryValueEx(hKey, REGSTR_VAL_JOYOEMNAME, 0, 0, (LPBYTE) buffer,
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/*************************************************************************/
|
||||
#include "drivers/gles2/rasterizer_gles2.h"
|
||||
#include "drivers/gles1/rasterizer_gles1.h"
|
||||
#include "os_winrt.h"
|
||||
#include "drivers/nedmalloc/memory_pool_static_nedmalloc.h"
|
||||
#include "drivers/unix/memory_pool_static_malloc.h"
|
||||
|
@ -62,11 +61,11 @@ using namespace Microsoft::WRL;
|
|||
|
||||
int OSWinrt::get_video_driver_count() const {
|
||||
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
const char * OSWinrt::get_video_driver_name(int p_driver) const {
|
||||
|
||||
return p_driver==0?"GLES2":"GLES1";
|
||||
return "GLES2";
|
||||
}
|
||||
|
||||
OS::VideoMode OSWinrt::get_default_video_mode() const {
|
||||
|
|
|
@ -323,6 +323,16 @@ void Camera2D::make_current() {
|
|||
}
|
||||
}
|
||||
|
||||
void Camera2D::clear_current() {
|
||||
|
||||
current=false;
|
||||
if (is_inside_tree()) {
|
||||
get_tree()->call_group(SceneTree::GROUP_CALL_REALTIME,group_name,"_make_current",(Object*)(NULL));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Camera2D::set_limit(Margin p_margin,int p_limit) {
|
||||
|
||||
ERR_FAIL_INDEX(p_margin,4);
|
||||
|
@ -435,6 +445,7 @@ void Camera2D::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("is_rotating"),&Camera2D::is_rotating);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("make_current"),&Camera2D::make_current);
|
||||
ObjectTypeDB::bind_method(_MD("clear_current"),&Camera2D::clear_current);
|
||||
ObjectTypeDB::bind_method(_MD("_make_current"),&Camera2D::_make_current);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_update_scroll"),&Camera2D::_update_scroll);
|
||||
|
|
|
@ -106,6 +106,7 @@ public:
|
|||
float get_follow_smoothing() const;
|
||||
|
||||
void make_current();
|
||||
void clear_current();
|
||||
bool is_current() const;
|
||||
|
||||
void set_zoom(const Vector2& p_zoom);
|
||||
|
|
|
@ -36,6 +36,192 @@
|
|||
#include "scene/resources/texture.h"
|
||||
#include "scene/resources/style_box.h"
|
||||
|
||||
|
||||
bool CanvasItemMaterial::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (p_name==SceneStringNames::get_singleton()->shader_shader) {
|
||||
set_shader(p_value);
|
||||
return true;
|
||||
} else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) {
|
||||
set_unshaded(p_value);
|
||||
print_line("set unshaded");
|
||||
return true;
|
||||
} else {
|
||||
|
||||
if (shader.is_valid()) {
|
||||
|
||||
|
||||
StringName pr = shader->remap_param(p_name);
|
||||
if (!pr) {
|
||||
String n = p_name;
|
||||
if (n.find("param/")==0) { //backwards compatibility
|
||||
pr = n.substr(6,n.length());
|
||||
}
|
||||
}
|
||||
if (pr) {
|
||||
VisualServer::get_singleton()->canvas_item_material_set_shader_param(material,pr,p_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CanvasItemMaterial::_get(const StringName& p_name,Variant &r_ret) const {
|
||||
|
||||
|
||||
if (p_name==SceneStringNames::get_singleton()->shader_shader) {
|
||||
|
||||
r_ret=get_shader();
|
||||
return true;
|
||||
} else if (p_name==SceneStringNames::get_singleton()->shader_unshaded) {
|
||||
|
||||
|
||||
r_ret=unshaded;
|
||||
return true;
|
||||
} else {
|
||||
|
||||
if (shader.is_valid()) {
|
||||
|
||||
StringName pr = shader->remap_param(p_name);
|
||||
if (pr) {
|
||||
r_ret=VisualServer::get_singleton()->canvas_item_material_get_shader_param(material,pr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void CanvasItemMaterial::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::OBJECT, "shader/shader", PROPERTY_HINT_RESOURCE_TYPE,"CanvasItemShader,CanvasItemShaderGraph" ) );
|
||||
p_list->push_back( PropertyInfo( Variant::BOOL, "shader/unshaded") );
|
||||
|
||||
if (!shader.is_null()) {
|
||||
|
||||
shader->get_param_list(p_list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::set_shader(const Ref<Shader>& p_shader) {
|
||||
|
||||
ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM);
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
if (shader.is_valid()) {
|
||||
shader->disconnect("changed",this,"_shader_changed");
|
||||
}
|
||||
#endif
|
||||
shader=p_shader;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
if (shader.is_valid()) {
|
||||
shader->connect("changed",this,"_shader_changed");
|
||||
}
|
||||
#endif
|
||||
|
||||
RID rid;
|
||||
if (shader.is_valid())
|
||||
rid=shader->get_rid();
|
||||
|
||||
VS::get_singleton()->canvas_item_material_set_shader(material,rid);
|
||||
_change_notify(); //properties for shader exposed
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
Ref<Shader> CanvasItemMaterial::get_shader() const{
|
||||
|
||||
return shader;
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::set_shader_param(const StringName& p_param,const Variant& p_value){
|
||||
|
||||
VS::get_singleton()->canvas_item_material_set_shader_param(material,p_param,p_value);
|
||||
}
|
||||
|
||||
Variant CanvasItemMaterial::get_shader_param(const StringName& p_param) const{
|
||||
|
||||
return VS::get_singleton()->canvas_item_material_get_shader_param(material,p_param);
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::_shader_changed() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
RID CanvasItemMaterial::get_rid() const {
|
||||
|
||||
return material;
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::set_unshaded(bool p_unshaded) {
|
||||
|
||||
unshaded=p_unshaded;
|
||||
VS::get_singleton()->canvas_item_material_set_unshaded(material,p_unshaded);
|
||||
}
|
||||
|
||||
bool CanvasItemMaterial::is_unshaded() const{
|
||||
|
||||
return unshaded;
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shader","shader:Shader"),&CanvasItemMaterial::set_shader);
|
||||
ObjectTypeDB::bind_method(_MD("get_shader:Shader"),&CanvasItemMaterial::get_shader);
|
||||
ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItemMaterial::set_shader_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItemMaterial::get_shader_param);
|
||||
ObjectTypeDB::bind_method(_MD("set_unshaded","unshaded"),&CanvasItemMaterial::set_unshaded);
|
||||
ObjectTypeDB::bind_method(_MD("is_unshaded"),&CanvasItemMaterial::is_unshaded);
|
||||
|
||||
}
|
||||
|
||||
void CanvasItemMaterial::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
String f = p_function.operator String();
|
||||
if ((f=="get_shader_param" || f=="set_shader_param") && p_idx==0) {
|
||||
|
||||
if (shader.is_valid()) {
|
||||
List<PropertyInfo> pl;
|
||||
shader->get_param_list(&pl);
|
||||
for (List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
Resource::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
CanvasItemMaterial::CanvasItemMaterial() {
|
||||
|
||||
material=VS::get_singleton()->canvas_item_material_create();
|
||||
unshaded=false;
|
||||
}
|
||||
|
||||
CanvasItemMaterial::~CanvasItemMaterial(){
|
||||
|
||||
VS::get_singleton()->free(material);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
bool CanvasItem::is_visible() const {
|
||||
|
||||
if (!is_inside_tree())
|
||||
|
@ -458,6 +644,16 @@ CanvasItem::BlendMode CanvasItem::get_blend_mode() const {
|
|||
return blend_mode;
|
||||
}
|
||||
|
||||
void CanvasItem::set_light_mask(int p_light_mask) {
|
||||
|
||||
light_mask=p_light_mask;
|
||||
VS::get_singleton()->canvas_item_set_light_mask(canvas_item,p_light_mask);
|
||||
}
|
||||
|
||||
int CanvasItem::get_light_mask() const{
|
||||
|
||||
return light_mask;
|
||||
}
|
||||
|
||||
|
||||
void CanvasItem::item_rect_changed() {
|
||||
|
@ -511,7 +707,7 @@ void CanvasItem::draw_texture(const Ref<Texture>& p_texture,const Point2& p_pos)
|
|||
p_texture->draw(canvas_item,p_pos);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate) {
|
||||
void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) {
|
||||
|
||||
if (!drawing) {
|
||||
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
|
@ -519,17 +715,17 @@ void CanvasItem::draw_texture_rect(const Ref<Texture>& p_texture,const Rect2& p_
|
|||
}
|
||||
|
||||
ERR_FAIL_COND(p_texture.is_null());
|
||||
p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate);
|
||||
p_texture->draw_rect(canvas_item,p_rect,p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) {
|
||||
void CanvasItem::draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) {
|
||||
|
||||
if (!drawing) {
|
||||
ERR_EXPLAIN("Drawing is only allowed inside NOTIFICATION_DRAW, _draw() function or 'draw' signal.");
|
||||
ERR_FAIL();
|
||||
}
|
||||
ERR_FAIL_COND(p_texture.is_null());
|
||||
p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate);
|
||||
p_texture->draw_rect_region(canvas_item,p_rect,p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
void CanvasItem::draw_style_box(const Ref<StyleBox>& p_style_box,const Rect2& p_rect) {
|
||||
|
@ -720,111 +916,35 @@ bool CanvasItem::is_draw_behind_parent_enabled() const{
|
|||
return behind;
|
||||
}
|
||||
|
||||
void CanvasItem::set_shader(const Ref<Shader>& p_shader) {
|
||||
void CanvasItem::set_material(const Ref<CanvasItemMaterial>& p_material) {
|
||||
|
||||
ERR_FAIL_COND(p_shader.is_valid() && p_shader->get_mode()!=Shader::MODE_CANVAS_ITEM);
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
if (shader.is_valid()) {
|
||||
shader->disconnect("changed",this,"_shader_changed");
|
||||
}
|
||||
#endif
|
||||
shader=p_shader;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
|
||||
if (shader.is_valid()) {
|
||||
shader->connect("changed",this,"_shader_changed");
|
||||
}
|
||||
#endif
|
||||
|
||||
material=p_material;
|
||||
RID rid;
|
||||
if (shader.is_valid())
|
||||
rid=shader->get_rid();
|
||||
VS::get_singleton()->canvas_item_set_shader(canvas_item,rid);
|
||||
_change_notify(); //properties for shader exposed
|
||||
if (material.is_valid())
|
||||
rid=material->get_rid();
|
||||
VS::get_singleton()->canvas_item_set_material(canvas_item,rid);
|
||||
_change_notify(); //properties for material exposed
|
||||
}
|
||||
|
||||
void CanvasItem::set_use_parent_shader(bool p_use_parent_shader) {
|
||||
void CanvasItem::set_use_parent_material(bool p_use_parent_material) {
|
||||
|
||||
use_parent_shader=p_use_parent_shader;
|
||||
VS::get_singleton()->canvas_item_set_use_parent_shader(canvas_item,p_use_parent_shader);
|
||||
use_parent_material=p_use_parent_material;
|
||||
VS::get_singleton()->canvas_item_set_use_parent_material(canvas_item,p_use_parent_material);
|
||||
}
|
||||
|
||||
bool CanvasItem::get_use_parent_shader() const{
|
||||
bool CanvasItem::get_use_parent_material() const{
|
||||
|
||||
return use_parent_shader;
|
||||
return use_parent_material;
|
||||
}
|
||||
|
||||
Ref<Shader> CanvasItem::get_shader() const{
|
||||
Ref<CanvasItemMaterial> CanvasItem::get_material() const{
|
||||
|
||||
return shader;
|
||||
return material;
|
||||
}
|
||||
|
||||
void CanvasItem::set_shader_param(const StringName& p_param,const Variant& p_value) {
|
||||
|
||||
VS::get_singleton()->canvas_item_set_shader_param(canvas_item,p_param,p_value);
|
||||
}
|
||||
|
||||
Variant CanvasItem::get_shader_param(const StringName& p_param) const {
|
||||
|
||||
return VS::get_singleton()->canvas_item_get_shader_param(canvas_item,p_param);
|
||||
}
|
||||
|
||||
bool CanvasItem::_set(const StringName& p_name, const Variant& p_value) {
|
||||
|
||||
if (shader.is_valid()) {
|
||||
StringName pr = shader->remap_param(p_name);
|
||||
if (pr) {
|
||||
set_shader_param(pr,p_value);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CanvasItem::_get(const StringName& p_name,Variant &r_ret) const{
|
||||
|
||||
if (shader.is_valid()) {
|
||||
StringName pr = shader->remap_param(p_name);
|
||||
if (pr) {
|
||||
r_ret=get_shader_param(pr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
void CanvasItem::_get_property_list( List<PropertyInfo> *p_list) const{
|
||||
|
||||
if (shader.is_valid()) {
|
||||
shader->get_param_list(p_list);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void CanvasItem::_shader_changed() {
|
||||
|
||||
_change_notify();
|
||||
}
|
||||
#endif
|
||||
|
||||
void CanvasItem::get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const {
|
||||
|
||||
if (p_idx==0 && shader.is_valid() && (p_function.operator String()=="get_shader_param" || p_function.operator String()=="set_shader_param")) {
|
||||
|
||||
List<PropertyInfo> pl;
|
||||
shader->get_param_list(&pl);
|
||||
for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
r_options->push_back("\""+E->get().name.replace_first("shader_param/","")+"\"");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Node::get_argument_options(p_function,p_idx,r_options);
|
||||
}
|
||||
|
||||
|
||||
void CanvasItem::_bind_methods() {
|
||||
|
@ -857,6 +977,9 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_blend_mode","blend_mode"),&CanvasItem::set_blend_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_blend_mode"),&CanvasItem::get_blend_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_light_mask","light_mask"),&CanvasItem::set_light_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_light_mask"),&CanvasItem::get_light_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_opacity","opacity"),&CanvasItem::set_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("get_opacity"),&CanvasItem::get_opacity);
|
||||
ObjectTypeDB::bind_method(_MD("set_self_opacity","self_opacity"),&CanvasItem::set_self_opacity);
|
||||
|
@ -867,9 +990,6 @@ void CanvasItem::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("_set_on_top","on_top"),&CanvasItem::_set_on_top);
|
||||
ObjectTypeDB::bind_method(_MD("_is_on_top"),&CanvasItem::_is_on_top);
|
||||
#ifdef TOOLS_ENABLED
|
||||
ObjectTypeDB::bind_method(_MD("_shader_changed"),&CanvasItem::_shader_changed);
|
||||
#endif
|
||||
//ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("draw_line","from","to","color","width"),&CanvasItem::draw_line,DEFVAL(1.0));
|
||||
|
@ -888,20 +1008,18 @@ void CanvasItem::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("draw_set_transform","pos","rot","scale"),&CanvasItem::draw_set_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_transform"),&CanvasItem::get_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_global_transform"),&CanvasItem::get_global_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_global_transform_with_canvas"),&CanvasItem::get_global_transform_with_canvas);
|
||||
ObjectTypeDB::bind_method(_MD("get_viewport_transform"),&CanvasItem::get_viewport_transform);
|
||||
ObjectTypeDB::bind_method(_MD("get_viewport_rect"),&CanvasItem::get_viewport_rect);
|
||||
ObjectTypeDB::bind_method(_MD("get_canvas"),&CanvasItem::get_canvas);
|
||||
ObjectTypeDB::bind_method(_MD("get_world_2d"),&CanvasItem::get_world_2d);
|
||||
//ObjectTypeDB::bind_method(_MD("get_viewport"),&CanvasItem::get_viewport);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shader","shader"),&CanvasItem::set_shader);
|
||||
ObjectTypeDB::bind_method(_MD("get_shader"),&CanvasItem::get_shader);
|
||||
ObjectTypeDB::bind_method(_MD("set_use_parent_shader","enable"),&CanvasItem::set_use_parent_shader);
|
||||
ObjectTypeDB::bind_method(_MD("get_use_parent_shader"),&CanvasItem::get_use_parent_shader);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shader_param","param","value"),&CanvasItem::set_shader_param);
|
||||
ObjectTypeDB::bind_method(_MD("get_shader_param","param"),&CanvasItem::get_shader_param);
|
||||
ObjectTypeDB::bind_method(_MD("set_material","material:CanvasItemMaterial"),&CanvasItem::set_material);
|
||||
ObjectTypeDB::bind_method(_MD("get_material:CanvasItemMaterial"),&CanvasItem::get_material);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_use_parent_material","enable"),&CanvasItem::set_use_parent_material);
|
||||
ObjectTypeDB::bind_method(_MD("get_use_parent_material"),&CanvasItem::get_use_parent_material);
|
||||
|
||||
BIND_VMETHOD(MethodInfo("_draw"));
|
||||
|
||||
|
@ -912,8 +1030,9 @@ void CanvasItem::_bind_methods() {
|
|||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"visibility/on_top",PROPERTY_HINT_NONE,"",0), _SCS("_set_on_top"),_SCS("_is_on_top") ); //compatibility
|
||||
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/blend_mode",PROPERTY_HINT_ENUM, "Mix,Add,Sub,Mul,PMAlpha"), _SCS("set_blend_mode"),_SCS("get_blend_mode") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"shader/shader",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemShader,CanvasItemShaderGraph"), _SCS("set_shader"),_SCS("get_shader") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"shader/use_parent"), _SCS("set_use_parent_shader"),_SCS("get_use_parent_shader") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::INT,"visibility/light_mask",PROPERTY_HINT_ALL_FLAGS), _SCS("set_light_mask"),_SCS("get_light_mask") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::OBJECT,"material/material",PROPERTY_HINT_RESOURCE_TYPE, "CanvasItemMaterial"), _SCS("set_material"),_SCS("get_material") );
|
||||
ADD_PROPERTYNZ( PropertyInfo(Variant::BOOL,"material/use_parent"), _SCS("set_use_parent_material"),_SCS("get_use_parent_material") );
|
||||
//exporting these two things doesn't really make much sense i think
|
||||
//ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transform/toplevel"), _SCS("set_as_toplevel"),_SCS("is_set_as_toplevel") );
|
||||
//ADD_PROPERTY(PropertyInfo(Variant::BOOL,"transform/notify"),_SCS("set_transform_notify"),_SCS("is_transform_notify_enabled"));
|
||||
|
@ -990,8 +1109,9 @@ CanvasItem::CanvasItem() : xform_change(this) {
|
|||
block_transform_notify=false;
|
||||
// viewport=NULL;
|
||||
canvas_layer=NULL;
|
||||
use_parent_shader=false;
|
||||
use_parent_material=false;
|
||||
global_invalid=true;
|
||||
light_mask=1;
|
||||
|
||||
C=NULL;
|
||||
|
||||
|
|
|
@ -40,6 +40,41 @@ class Font;
|
|||
|
||||
class StyleBox;
|
||||
|
||||
class CanvasItemMaterial : public Resource{
|
||||
|
||||
OBJ_TYPE(CanvasItemMaterial,Resource);
|
||||
RID material;
|
||||
Ref<Shader> shader;
|
||||
bool unshaded;
|
||||
|
||||
protected:
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
void _shader_changed();
|
||||
static void _bind_methods();
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
public:
|
||||
|
||||
void set_shader(const Ref<Shader>& p_shader);
|
||||
Ref<Shader> get_shader() const;
|
||||
|
||||
void set_shader_param(const StringName& p_param,const Variant& p_value);
|
||||
Variant get_shader_param(const StringName& p_param) const;
|
||||
|
||||
void set_unshaded(bool p_unshaded);
|
||||
bool is_unshaded() const;
|
||||
|
||||
virtual RID get_rid() const;
|
||||
CanvasItemMaterial();
|
||||
~CanvasItemMaterial();
|
||||
};
|
||||
|
||||
|
||||
class CanvasItem : public Node {
|
||||
|
||||
OBJ_TYPE( CanvasItem, Node );
|
||||
|
@ -71,6 +106,7 @@ private:
|
|||
List<CanvasItem*>::Element *C;
|
||||
|
||||
BlendMode blend_mode;
|
||||
int light_mask;
|
||||
|
||||
bool first_draw;
|
||||
bool hidden;
|
||||
|
@ -80,9 +116,9 @@ private:
|
|||
bool drawing;
|
||||
bool block_transform_notify;
|
||||
bool behind;
|
||||
bool use_parent_material;
|
||||
|
||||
bool use_parent_shader;
|
||||
Ref<Shader> shader;
|
||||
Ref<CanvasItemMaterial> material;
|
||||
|
||||
mutable Matrix32 global_transform;
|
||||
mutable bool global_invalid;
|
||||
|
@ -103,9 +139,6 @@ private:
|
|||
void _queue_sort_children();
|
||||
void _sort_children();
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void _shader_changed();
|
||||
#endif
|
||||
void _notify_transform(CanvasItem *p_node);
|
||||
|
||||
void _set_on_top(bool p_on_top) { set_draw_behind_parent(!p_on_top); }
|
||||
|
@ -113,11 +146,6 @@ private:
|
|||
|
||||
protected:
|
||||
|
||||
bool _set(const StringName& p_name, const Variant& p_value);
|
||||
bool _get(const StringName& p_name,Variant &r_ret) const;
|
||||
void _get_property_list( List<PropertyInfo> *p_list) const;
|
||||
|
||||
|
||||
_FORCE_INLINE_ void _notify_transform() { if (!is_inside_tree()) return; _notify_transform(this); if (!block_transform_notify) notification(NOTIFICATION_LOCAL_TRANSFORM_CHANGED); }
|
||||
|
||||
void item_rect_changed();
|
||||
|
@ -158,6 +186,9 @@ public:
|
|||
void set_blend_mode(BlendMode p_blend_mode);
|
||||
BlendMode get_blend_mode() const;
|
||||
|
||||
void set_light_mask(int p_light_mask);
|
||||
int get_light_mask() const;
|
||||
|
||||
void set_opacity(float p_opacity);
|
||||
float get_opacity() const;
|
||||
|
||||
|
@ -170,8 +201,8 @@ public:
|
|||
void draw_rect(const Rect2& p_rect, const Color& p_color);
|
||||
void draw_circle(const Point2& p_pos, float p_radius, const Color& p_color);
|
||||
void draw_texture(const Ref<Texture>& p_texture,const Point2& p_pos);
|
||||
void draw_texture_rect(const Ref<Texture>& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1));
|
||||
void draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1));
|
||||
void draw_texture_rect(const Ref<Texture>& p_texture, const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false);
|
||||
void draw_texture_rect_region(const Ref<Texture>& p_texture,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false);
|
||||
void draw_style_box(const Ref<StyleBox>& p_style_box,const Rect2& p_rect);
|
||||
void draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, Ref<Texture> p_texture=Ref<Texture>(),float p_width=1);
|
||||
void draw_polygon(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), Ref<Texture> p_texture=Ref<Texture>());
|
||||
|
@ -212,16 +243,12 @@ public:
|
|||
RID get_canvas() const;
|
||||
Ref<World2D> get_world_2d() const;
|
||||
|
||||
void set_shader(const Ref<Shader>& p_shader);
|
||||
Ref<Shader> get_shader() const;
|
||||
void set_material(const Ref<CanvasItemMaterial>& p_material);
|
||||
Ref<CanvasItemMaterial> get_material() const;
|
||||
|
||||
void set_use_parent_shader(bool p_use_parent_shader);
|
||||
bool get_use_parent_shader() const;
|
||||
void set_use_parent_material(bool p_use_parent_material);
|
||||
bool get_use_parent_material() const;
|
||||
|
||||
void set_shader_param(const StringName& p_param,const Variant& p_value);
|
||||
Variant get_shader_param(const StringName& p_param) const;
|
||||
|
||||
void get_argument_options(const StringName& p_function,int p_idx,List<String>*r_options) const;
|
||||
|
||||
CanvasItem();
|
||||
~CanvasItem();
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include "canvas_modulate.h"
|
||||
|
||||
|
||||
void CanvasModulate::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),color);
|
||||
} else if (p_what==NOTIFICATION_EXIT_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),Color(1,1,1,1));
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasModulate::_bind_methods(){
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color"),&CanvasModulate::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color"),&CanvasModulate::get_color);
|
||||
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
|
||||
}
|
||||
|
||||
|
||||
void CanvasModulate::set_color(const Color& p_color){
|
||||
|
||||
color=p_color;
|
||||
if (is_inside_tree()) {
|
||||
VS::get_singleton()->canvas_set_modulate(get_canvas(),color);
|
||||
}
|
||||
}
|
||||
Color CanvasModulate::get_color() const {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
CanvasModulate::CanvasModulate()
|
||||
{
|
||||
color=Color(1,1,1,1);
|
||||
}
|
||||
|
||||
CanvasModulate::~CanvasModulate()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
#ifndef CANVASMODULATE_H
|
||||
#define CANVASMODULATE_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class CanvasModulate : public Node2D {
|
||||
|
||||
OBJ_TYPE(CanvasModulate,Node2D);
|
||||
|
||||
Color color;
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_color(const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
CanvasModulate();
|
||||
~CanvasModulate();
|
||||
};
|
||||
|
||||
#endif // CANVASMODULATE_H
|
|
@ -0,0 +1,300 @@
|
|||
#include "light_2d.h"
|
||||
#include "servers/visual_server.h"
|
||||
|
||||
void Light2D::edit_set_pivot(const Point2& p_pivot) {
|
||||
|
||||
set_texture_offset(p_pivot);
|
||||
|
||||
}
|
||||
|
||||
Point2 Light2D::edit_get_pivot() const {
|
||||
|
||||
return get_texture_offset();
|
||||
}
|
||||
bool Light2D::edit_has_pivot() const {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Rect2 Light2D::get_item_rect() const {
|
||||
|
||||
if (texture.is_null())
|
||||
return Rect2(0,0,1,1);
|
||||
|
||||
Size2i s;
|
||||
|
||||
s = texture->get_size();
|
||||
Point2i ofs=texture_offset;
|
||||
ofs-=s/2;
|
||||
|
||||
if (s==Size2(0,0))
|
||||
s=Size2(1,1);
|
||||
|
||||
return Rect2(ofs,s);
|
||||
}
|
||||
|
||||
|
||||
void Light2D::set_enabled( bool p_enabled) {
|
||||
|
||||
VS::get_singleton()->canvas_light_set_enabled(canvas_light,p_enabled);
|
||||
enabled=p_enabled;
|
||||
}
|
||||
|
||||
bool Light2D::is_enabled() const {
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
void Light2D::set_texture( const Ref<Texture>& p_texture) {
|
||||
|
||||
texture=p_texture;
|
||||
if (texture.is_valid())
|
||||
VS::get_singleton()->canvas_light_set_texture(canvas_light,texture->get_rid());
|
||||
else
|
||||
VS::get_singleton()->canvas_light_set_texture(canvas_light,RID());
|
||||
}
|
||||
|
||||
Ref<Texture> Light2D::get_texture() const {
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
void Light2D::set_texture_offset( const Vector2& p_offset) {
|
||||
|
||||
texture_offset=p_offset;
|
||||
VS::get_singleton()->canvas_light_set_texture_offset(canvas_light,texture_offset);
|
||||
}
|
||||
|
||||
Vector2 Light2D::get_texture_offset() const {
|
||||
|
||||
return texture_offset;
|
||||
}
|
||||
|
||||
void Light2D::set_color( const Color& p_color) {
|
||||
|
||||
color=p_color;
|
||||
VS::get_singleton()->canvas_light_set_color(canvas_light,color);
|
||||
|
||||
}
|
||||
Color Light2D::get_color() const {
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
void Light2D::set_height( float p_height) {
|
||||
|
||||
height=p_height;
|
||||
VS::get_singleton()->canvas_light_set_height(canvas_light,height);
|
||||
|
||||
}
|
||||
float Light2D::get_height() const {
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void Light2D::set_z_range_min( int p_min_z) {
|
||||
|
||||
z_min=p_min_z;
|
||||
VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max);
|
||||
|
||||
}
|
||||
int Light2D::get_z_range_min() const {
|
||||
|
||||
return z_min;
|
||||
}
|
||||
|
||||
void Light2D::set_z_range_max( int p_max_z) {
|
||||
|
||||
z_max=p_max_z;
|
||||
VS::get_singleton()->canvas_light_set_z_range(canvas_light,z_min,z_max);
|
||||
|
||||
}
|
||||
int Light2D::get_z_range_max() const {
|
||||
|
||||
return z_max;
|
||||
}
|
||||
|
||||
void Light2D::set_layer_range_min( int p_min_layer) {
|
||||
|
||||
layer_min=p_min_layer;
|
||||
VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max);
|
||||
|
||||
}
|
||||
int Light2D::get_layer_range_min() const {
|
||||
|
||||
return layer_min;
|
||||
}
|
||||
|
||||
void Light2D::set_layer_range_max( int p_max_layer) {
|
||||
|
||||
layer_max=p_max_layer;
|
||||
VS::get_singleton()->canvas_light_set_layer_range(canvas_light,layer_min,layer_max);
|
||||
|
||||
}
|
||||
int Light2D::get_layer_range_max() const {
|
||||
|
||||
return layer_max;
|
||||
}
|
||||
|
||||
void Light2D::set_item_mask( int p_mask) {
|
||||
|
||||
item_mask=p_mask;
|
||||
VS::get_singleton()->canvas_light_set_item_mask(canvas_light,item_mask);
|
||||
|
||||
}
|
||||
|
||||
int Light2D::get_item_mask() const {
|
||||
|
||||
return item_mask;
|
||||
}
|
||||
|
||||
void Light2D::set_subtract_mode( bool p_enable ) {
|
||||
|
||||
subtract_mode=p_enable;
|
||||
VS::get_singleton()->canvas_light_set_subtract_mode(canvas_light,p_enable);
|
||||
}
|
||||
|
||||
bool Light2D::get_subtract_mode() const {
|
||||
|
||||
return subtract_mode;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_enabled( bool p_enabled) {
|
||||
|
||||
shadow=p_enabled;
|
||||
VS::get_singleton()->canvas_light_set_shadow_enabled(canvas_light,shadow);
|
||||
|
||||
}
|
||||
bool Light2D::is_shadow_enabled() const {
|
||||
|
||||
return shadow;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_buffer_size( int p_size ) {
|
||||
|
||||
shadow_buffer_size=p_size;
|
||||
VS::get_singleton()->canvas_light_set_shadow_buffer_size(canvas_light,shadow_buffer_size);
|
||||
}
|
||||
|
||||
int Light2D::get_shadow_buffer_size() const {
|
||||
|
||||
return shadow_buffer_size;
|
||||
}
|
||||
|
||||
void Light2D::set_shadow_esm_multiplier( float p_multiplier) {
|
||||
|
||||
shadow_esm_multiplier=p_multiplier;
|
||||
VS::get_singleton()->canvas_light_set_shadow_esm_multiplier(canvas_light,p_multiplier);
|
||||
}
|
||||
|
||||
float Light2D::get_shadow_esm_multiplier() const{
|
||||
|
||||
return shadow_esm_multiplier;
|
||||
}
|
||||
|
||||
|
||||
void Light2D::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_TREE) {
|
||||
|
||||
VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, get_canvas() );
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_TRANSFORM_CHANGED) {
|
||||
|
||||
VS::get_singleton()->canvas_light_set_transform( canvas_light, get_global_transform());
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_TREE) {
|
||||
|
||||
VS::get_singleton()->canvas_light_attach_to_canvas( canvas_light, RID() );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Light2D::_bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_enabled","enabled"),&Light2D::set_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_enabled"),&Light2D::is_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_texture","texture"),&Light2D::set_texture);
|
||||
ObjectTypeDB::bind_method(_MD("get_texture"),&Light2D::get_texture);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_texture_offset","texture_offset"),&Light2D::set_texture_offset);
|
||||
ObjectTypeDB::bind_method(_MD("get_texture_offset"),&Light2D::get_texture_offset);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_color","color"),&Light2D::set_color);
|
||||
ObjectTypeDB::bind_method(_MD("get_color"),&Light2D::get_color);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_height","height"),&Light2D::set_height);
|
||||
ObjectTypeDB::bind_method(_MD("get_height"),&Light2D::get_height);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_z_range_min","z"),&Light2D::set_z_range_min);
|
||||
ObjectTypeDB::bind_method(_MD("get_z_range_min"),&Light2D::get_z_range_min);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_z_range_max","z"),&Light2D::set_z_range_max);
|
||||
ObjectTypeDB::bind_method(_MD("get_z_range_max"),&Light2D::get_z_range_max);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_range_min","layer"),&Light2D::set_layer_range_min);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_range_min"),&Light2D::get_layer_range_min);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_layer_range_max","layer"),&Light2D::set_layer_range_max);
|
||||
ObjectTypeDB::bind_method(_MD("get_layer_range_max"),&Light2D::get_layer_range_max);
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_item_mask","item_mask"),&Light2D::set_item_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_item_mask"),&Light2D::get_item_mask);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_subtract_mode","enable"),&Light2D::set_subtract_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_subtract_mode"),&Light2D::get_subtract_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_enabled","enabled"),&Light2D::set_shadow_enabled);
|
||||
ObjectTypeDB::bind_method(_MD("is_shadow_enabled"),&Light2D::is_shadow_enabled);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_buffer_size","size"),&Light2D::set_shadow_buffer_size);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_buffer_size"),&Light2D::get_shadow_buffer_size);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_shadow_esm_multiplier","multiplier"),&Light2D::set_shadow_esm_multiplier);
|
||||
ObjectTypeDB::bind_method(_MD("get_shadow_esm_multiplier"),&Light2D::get_shadow_esm_multiplier);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_texture"),_SCS("get_texture"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"offset"),_SCS("set_texture_offset"),_SCS("get_texture_offset"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::COLOR,"color"),_SCS("set_color"),_SCS("get_color"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"subtract"),_SCS("set_subtract_mode"),_SCS("get_subtract_mode"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"range/height"),_SCS("set_height"),_SCS("get_height"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_min",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_min"),_SCS("get_z_range_min"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/z_max",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z_range_max"),_SCS("get_z_range_max"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_min",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_min"),_SCS("get_layer_range_min"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/layer_max",PROPERTY_HINT_RANGE,"-512,512,1"),_SCS("set_layer_range_max"),_SCS("get_layer_range_max"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"range/item_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_item_mask"),_SCS("get_item_mask"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"shadow/enabled"),_SCS("set_shadow_enabled"),_SCS("is_shadow_enabled"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/buffer_size",PROPERTY_HINT_RANGE,"32,16384,1"),_SCS("set_shadow_buffer_size"),_SCS("get_shadow_buffer_size"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::REAL,"shadow/esm_multiplier",PROPERTY_HINT_RANGE,"1,4096,0.1"),_SCS("set_shadow_esm_multiplier"),_SCS("get_shadow_esm_multiplier"));
|
||||
|
||||
|
||||
}
|
||||
|
||||
Light2D::Light2D() {
|
||||
|
||||
canvas_light=VisualServer::get_singleton()->canvas_light_create();
|
||||
enabled=true;
|
||||
shadow=false;
|
||||
color=Color(1,1,1);
|
||||
height=0;
|
||||
z_min=-1024;
|
||||
z_max=1024;
|
||||
layer_min=0;
|
||||
layer_max=0;
|
||||
item_mask=1;
|
||||
subtract_mode=false;
|
||||
shadow_buffer_size=2048;
|
||||
shadow_esm_multiplier=80;
|
||||
|
||||
}
|
||||
|
||||
Light2D::~Light2D() {
|
||||
|
||||
VisualServer::get_singleton()->free(canvas_light);
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
#ifndef LIGHT_2D_H
|
||||
#define LIGHT_2D_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class Light2D : public Node2D {
|
||||
|
||||
OBJ_TYPE(Light2D,Node2D);
|
||||
private:
|
||||
RID canvas_light;
|
||||
bool enabled;
|
||||
bool shadow;
|
||||
Color color;
|
||||
float height;
|
||||
int z_min;
|
||||
int z_max;
|
||||
int layer_min;
|
||||
int layer_max;
|
||||
int item_mask;
|
||||
int shadow_buffer_size;
|
||||
float shadow_esm_multiplier;
|
||||
bool subtract_mode;
|
||||
Ref<Texture> texture;
|
||||
Vector2 texture_offset;
|
||||
|
||||
protected:
|
||||
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
|
||||
virtual void edit_set_pivot(const Point2& p_pivot);
|
||||
virtual Point2 edit_get_pivot() const;
|
||||
virtual bool edit_has_pivot() const;
|
||||
|
||||
void set_enabled( bool p_enabled);
|
||||
bool is_enabled() const;
|
||||
|
||||
void set_texture( const Ref<Texture>& p_texture);
|
||||
Ref<Texture> get_texture() const;
|
||||
|
||||
void set_texture_offset( const Vector2& p_offset);
|
||||
Vector2 get_texture_offset() const;
|
||||
|
||||
void set_color( const Color& p_color);
|
||||
Color get_color() const;
|
||||
|
||||
void set_height( float p_height);
|
||||
float get_height() const;
|
||||
|
||||
void set_z_range_min( int p_min_z);
|
||||
int get_z_range_min() const;
|
||||
|
||||
void set_z_range_max( int p_max_z);
|
||||
int get_z_range_max() const;
|
||||
|
||||
void set_layer_range_min( int p_min_layer);
|
||||
int get_layer_range_min() const;
|
||||
|
||||
void set_layer_range_max( int p_max_layer);
|
||||
int get_layer_range_max() const;
|
||||
|
||||
void set_item_mask( int p_mask);
|
||||
int get_item_mask() const;
|
||||
|
||||
void set_subtract_mode( bool p_enable );
|
||||
bool get_subtract_mode() const;
|
||||
|
||||
void set_shadow_enabled( bool p_enabled);
|
||||
bool is_shadow_enabled() const;
|
||||
|
||||
void set_shadow_buffer_size( int p_size );
|
||||
int get_shadow_buffer_size() const;
|
||||
|
||||
void set_shadow_esm_multiplier( float p_multiplier);
|
||||
float get_shadow_esm_multiplier() const;
|
||||
|
||||
virtual Rect2 get_item_rect() const;
|
||||
|
||||
Light2D();
|
||||
~Light2D();
|
||||
};
|
||||
|
||||
|
||||
#endif // LIGHT_2D_H
|
|
@ -0,0 +1,201 @@
|
|||
#include "light_occluder_2d.h"
|
||||
|
||||
|
||||
void OccluderPolygon2D::set_polygon(const DVector<Vector2>& p_polygon) {
|
||||
|
||||
polygon=p_polygon;
|
||||
VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,p_polygon,closed);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
DVector<Vector2> OccluderPolygon2D::get_polygon() const{
|
||||
|
||||
return polygon;
|
||||
}
|
||||
|
||||
void OccluderPolygon2D::set_closed(bool p_closed) {
|
||||
|
||||
if (closed==p_closed)
|
||||
return;
|
||||
closed=p_closed;
|
||||
VS::get_singleton()->canvas_occluder_polygon_set_shape(occ_polygon,polygon,closed);
|
||||
emit_changed();
|
||||
}
|
||||
|
||||
bool OccluderPolygon2D::is_closed() const{
|
||||
|
||||
return closed;
|
||||
}
|
||||
|
||||
void OccluderPolygon2D::set_cull_mode(CullMode p_mode){
|
||||
|
||||
cull=p_mode;
|
||||
VS::get_singleton()->canvas_occluder_polygon_set_cull_mode(occ_polygon,VS::CanvasOccluderPolygonCullMode(p_mode));
|
||||
}
|
||||
|
||||
OccluderPolygon2D::CullMode OccluderPolygon2D::get_cull_mode() const{
|
||||
|
||||
return cull;
|
||||
}
|
||||
|
||||
|
||||
RID OccluderPolygon2D::get_rid() const {
|
||||
|
||||
return occ_polygon;
|
||||
}
|
||||
|
||||
void OccluderPolygon2D::_bind_methods() {
|
||||
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_closed","closed"),&OccluderPolygon2D::set_closed);
|
||||
ObjectTypeDB::bind_method(_MD("is_closed"),&OccluderPolygon2D::is_closed);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cull_mode","cull_mode"),&OccluderPolygon2D::set_cull_mode);
|
||||
ObjectTypeDB::bind_method(_MD("get_cull_mode"),&OccluderPolygon2D::get_cull_mode);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_polygon","polygon"),&OccluderPolygon2D::set_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_polygon"),&OccluderPolygon2D::get_polygon);
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::VECTOR2_ARRAY,"polygon"),_SCS("set_polygon"),_SCS("get_polygon"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"closed"),_SCS("set_closed"),_SCS("is_closed"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"cull_mode",PROPERTY_HINT_ENUM,"Disabled,ClockWise,CounterClockWise"),_SCS("set_cull_mode"),_SCS("get_cull_mode"));
|
||||
|
||||
BIND_CONSTANT(CULL_DISABLED);
|
||||
BIND_CONSTANT(CULL_CLOCKWISE);
|
||||
BIND_CONSTANT(CULL_COUNTER_CLOCKWISE);
|
||||
}
|
||||
|
||||
|
||||
OccluderPolygon2D::OccluderPolygon2D() {
|
||||
|
||||
occ_polygon=VS::get_singleton()->canvas_occluder_polygon_create();
|
||||
closed=true;
|
||||
cull=CULL_DISABLED;
|
||||
}
|
||||
|
||||
OccluderPolygon2D::~OccluderPolygon2D() {
|
||||
|
||||
VS::get_singleton()->free(occ_polygon);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void LightOccluder2D::_poly_changed() {
|
||||
|
||||
update();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void LightOccluder2D::_notification(int p_what) {
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder,get_canvas());
|
||||
VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform());
|
||||
|
||||
}
|
||||
if (p_what==NOTIFICATION_TRANSFORM_CHANGED) {
|
||||
|
||||
VS::get_singleton()->canvas_light_occluder_set_transform(occluder,get_global_transform());
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_DRAW) {
|
||||
|
||||
if (get_tree()->is_editor_hint()) {
|
||||
|
||||
if (occluder_polygon.is_valid()) {
|
||||
|
||||
DVector<Vector2> poly = occluder_polygon->get_polygon();
|
||||
|
||||
if (poly.size()) {
|
||||
if (occluder_polygon->is_closed()) {
|
||||
Vector<Color> color;
|
||||
color.push_back(Color(0,0,0,0.6));
|
||||
draw_polygon(Variant(poly),color);
|
||||
} else {
|
||||
|
||||
int ps=poly.size();
|
||||
DVector<Vector2>::Read r = poly.read();
|
||||
for(int i=0;i<ps-1;i++) {
|
||||
|
||||
draw_line(r[i],r[i+1],Color(0,0,0,0.6),3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (p_what==NOTIFICATION_EXIT_CANVAS) {
|
||||
|
||||
VS::get_singleton()->canvas_light_occluder_attach_to_canvas(occluder,RID());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void LightOccluder2D::set_occluder_polygon(const Ref<OccluderPolygon2D>& p_polygon) {
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (occluder_polygon.is_valid())
|
||||
occluder_polygon->disconnect("changed",this,"_poly_changed");
|
||||
#endif
|
||||
occluder_polygon=p_polygon;
|
||||
|
||||
if (occluder_polygon.is_valid())
|
||||
VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,occluder_polygon->get_rid());
|
||||
else
|
||||
VS::get_singleton()->canvas_light_occluder_set_polygon(occluder,RID());
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (occluder_polygon.is_valid())
|
||||
occluder_polygon->connect("changed",this,"_poly_changed");
|
||||
update();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
Ref<OccluderPolygon2D> LightOccluder2D::get_occluder_polygon() const {
|
||||
|
||||
return occluder_polygon;
|
||||
}
|
||||
|
||||
void LightOccluder2D::set_occluder_light_mask(int p_mask) {
|
||||
|
||||
mask=p_mask;
|
||||
VS::get_singleton()->canvas_light_occluder_set_light_mask(occluder,mask);
|
||||
}
|
||||
|
||||
int LightOccluder2D::get_occluder_light_mask() const{
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
void LightOccluder2D::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_occluder_polygon","polygon:OccluderPolygon2D"),&LightOccluder2D::set_occluder_polygon);
|
||||
ObjectTypeDB::bind_method(_MD("get_occluder_polygon:OccluderPolygon2D"),&LightOccluder2D::get_occluder_polygon);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_occluder_light_mask","mask"),&LightOccluder2D::set_occluder_light_mask);
|
||||
ObjectTypeDB::bind_method(_MD("get_occluder_light_mask"),&LightOccluder2D::get_occluder_light_mask);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
ObjectTypeDB::bind_method("_poly_changed",&LightOccluder2D::_poly_changed);
|
||||
#endif
|
||||
|
||||
ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"occluder",PROPERTY_HINT_RESOURCE_TYPE,"OccluderPolygon2D"),_SCS("set_occluder_polygon"),_SCS("get_occluder_polygon"));
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"light_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_occluder_light_mask"),_SCS("get_occluder_light_mask"));
|
||||
}
|
||||
|
||||
LightOccluder2D::LightOccluder2D() {
|
||||
|
||||
occluder=VS::get_singleton()->canvas_light_occluder_create();
|
||||
mask=1;
|
||||
}
|
||||
|
||||
LightOccluder2D::~LightOccluder2D() {
|
||||
|
||||
VS::get_singleton()->free(occluder);
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef LIGHTOCCLUDER2D_H
|
||||
#define LIGHTOCCLUDER2D_H
|
||||
|
||||
#include "scene/2d/node_2d.h"
|
||||
|
||||
class OccluderPolygon2D : public Resource {
|
||||
|
||||
OBJ_TYPE(OccluderPolygon2D,Resource);
|
||||
public:
|
||||
|
||||
enum CullMode {
|
||||
CULL_DISABLED,
|
||||
CULL_CLOCKWISE,
|
||||
CULL_COUNTER_CLOCKWISE
|
||||
};
|
||||
private:
|
||||
|
||||
|
||||
RID occ_polygon;
|
||||
DVector<Vector2> polygon;
|
||||
bool closed;
|
||||
CullMode cull;
|
||||
|
||||
protected:
|
||||
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_polygon(const DVector<Vector2>& p_polygon);
|
||||
DVector<Vector2> get_polygon() const;
|
||||
|
||||
void set_closed(bool p_closed);
|
||||
bool is_closed() const;
|
||||
|
||||
void set_cull_mode(CullMode p_mode);
|
||||
CullMode get_cull_mode() const;
|
||||
|
||||
virtual RID get_rid() const;
|
||||
OccluderPolygon2D();
|
||||
~OccluderPolygon2D();
|
||||
|
||||
};
|
||||
|
||||
VARIANT_ENUM_CAST(OccluderPolygon2D::CullMode);
|
||||
|
||||
class LightOccluder2D : public Node2D {
|
||||
OBJ_TYPE(LightOccluder2D,Node2D);
|
||||
|
||||
RID occluder;
|
||||
bool enabled;
|
||||
int mask;
|
||||
Ref<OccluderPolygon2D> occluder_polygon;
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
void _poly_changed();
|
||||
#endif
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
void set_occluder_polygon(const Ref<OccluderPolygon2D>& p_polygon);
|
||||
Ref<OccluderPolygon2D> get_occluder_polygon() const;
|
||||
|
||||
void set_occluder_light_mask(int p_mask);
|
||||
int get_occluder_light_mask() const;
|
||||
|
||||
LightOccluder2D();
|
||||
~LightOccluder2D();
|
||||
};
|
||||
|
||||
#endif // LIGHTOCCLUDER2D_H
|
|
@ -1,5 +1,7 @@
|
|||
#include "navigation2d.h"
|
||||
|
||||
#define USE_ENTRY_POINT
|
||||
|
||||
void Navigation2D::_navpoly_link(int p_id) {
|
||||
|
||||
ERR_FAIL_COND(!navpoly_map.has(p_id));
|
||||
|
@ -336,12 +338,25 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
List<Polygon*> open_list;
|
||||
|
||||
begin_poly->entry=p_start;
|
||||
|
||||
for(int i=0;i<begin_poly->edges.size();i++) {
|
||||
|
||||
if (begin_poly->edges[i].C) {
|
||||
|
||||
begin_poly->edges[i].C->prev_edge=begin_poly->edges[i].C_edge;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
Vector2 edge[2]={
|
||||
_get_vertex(begin_poly->edges[i].point),
|
||||
_get_vertex(begin_poly->edges[(i+1)%begin_poly->edges.size()].point)
|
||||
};
|
||||
|
||||
Vector2 entry = Geometry::get_closest_point_to_segment_2d(begin_poly->entry,edge);
|
||||
begin_poly->edges[i].C->distance = begin_poly->entry.distance_to(entry);
|
||||
begin_poly->edges[i].C->entry=entry;
|
||||
#else
|
||||
begin_poly->edges[i].C->distance=begin_poly->center.distance_to(begin_poly->edges[i].C->center);
|
||||
#endif
|
||||
open_list.push_back(begin_poly->edges[i].C);
|
||||
|
||||
if (begin_poly->edges[i].C==end_poly) {
|
||||
|
@ -381,8 +396,9 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
Polygon *p=least_cost_poly->get();
|
||||
//open the neighbours for search
|
||||
int es = p->edges.size();
|
||||
|
||||
for(int i=0;i<p->edges.size();i++) {
|
||||
for(int i=0;i<es;i++) {
|
||||
|
||||
|
||||
Polygon::Edge &e=p->edges[i];
|
||||
|
@ -390,8 +406,22 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
if (!e.C)
|
||||
continue;
|
||||
|
||||
#ifdef USE_ENTRY_POINT
|
||||
Vector2 edge[2]={
|
||||
_get_vertex(p->edges[i].point),
|
||||
_get_vertex(p->edges[(i+1)%es].point)
|
||||
};
|
||||
|
||||
Vector2 edge_entry = Geometry::get_closest_point_to_segment_2d(p->entry,edge);
|
||||
float distance = p->entry.distance_to(edge_entry) + p->distance;
|
||||
|
||||
#else
|
||||
|
||||
float distance = p->center.distance_to(e.C->center) + p->distance;
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (e.C->prev_edge!=-1) {
|
||||
//oh this was visited already, can we win the cost?
|
||||
|
||||
|
@ -399,12 +429,19 @@ Vector<Vector2> Navigation2D::get_simple_path(const Vector2& p_start, const Vect
|
|||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
e.C->entry=edge_entry;
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
//add to open neighbours
|
||||
|
||||
e.C->prev_edge=e.C_edge;
|
||||
e.C->distance=distance;
|
||||
#ifdef USE_ENTRY_POINT
|
||||
e.C->entry=edge_entry;
|
||||
#endif
|
||||
|
||||
open_list.push_back(e.C);
|
||||
|
||||
if (e.C==end_poly) {
|
||||
|
|
|
@ -55,6 +55,7 @@ class Navigation2D : public Node2D {
|
|||
Vector<Edge> edges;
|
||||
|
||||
Vector2 center;
|
||||
Vector2 entry;
|
||||
|
||||
float distance;
|
||||
int prev_edge;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "tile_map.h"
|
||||
#include "io/marshalls.h"
|
||||
#include "servers/physics_2d_server.h"
|
||||
|
||||
#include "method_bind_ext.inc"
|
||||
void TileMap::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
|
@ -226,11 +226,9 @@ void TileMap::_update_dirty_quadrants() {
|
|||
|
||||
rect.pos+=tile_ofs;
|
||||
if (r==Rect2()) {
|
||||
|
||||
tex->draw_rect(q.canvas_item,rect);
|
||||
tex->draw_rect(q.canvas_item,rect,false,Color(1,1,1),c.transpose);
|
||||
} else {
|
||||
|
||||
tex->draw_rect_region(q.canvas_item,rect,r);
|
||||
tex->draw_rect_region(q.canvas_item,rect,r,Color(1,1,1),c.transpose);
|
||||
}
|
||||
|
||||
Vector< Ref<Shape2D> > shapes = tile_set->tile_get_shapes(c.id);
|
||||
|
@ -244,20 +242,25 @@ void TileMap::_update_dirty_quadrants() {
|
|||
Vector2 shape_ofs = tile_set->tile_get_shape_offset(c.id);
|
||||
Matrix32 xform;
|
||||
xform.set_origin(offset.floor());
|
||||
if (c.transpose) {
|
||||
SWAP(xform.elements[0].x, xform.elements[0].y);
|
||||
SWAP(xform.elements[1].x, xform.elements[1].y);
|
||||
SWAP(shape_ofs.x, shape_ofs.y);
|
||||
SWAP(s.x, s.y);
|
||||
}
|
||||
if (c.flip_h) {
|
||||
xform.elements[0]=-xform.elements[0];
|
||||
xform.elements[2].x+=s.x-shape_ofs.x;
|
||||
} else {
|
||||
|
||||
xform.elements[2].x+=shape_ofs.x;
|
||||
xform.elements[0].x=-xform.elements[0].x;
|
||||
xform.elements[1].x=-xform.elements[1].x;
|
||||
shape_ofs.x=s.x-shape_ofs.x;
|
||||
}
|
||||
if (c.flip_v) {
|
||||
xform.elements[1]=-xform.elements[1];
|
||||
xform.elements[2].y+=s.y-shape_ofs.y;
|
||||
} else {
|
||||
|
||||
xform.elements[2].y+=shape_ofs.y;
|
||||
xform.elements[0].y=-xform.elements[0].y;
|
||||
xform.elements[1].y=-xform.elements[1].y;
|
||||
shape_ofs.y=s.y-shape_ofs.y;
|
||||
}
|
||||
xform.elements[2].x+=shape_ofs.x;
|
||||
xform.elements[2].y+=shape_ofs.y;
|
||||
|
||||
|
||||
|
||||
ps->body_add_shape(q.body,shape->get_rid(),xform);
|
||||
|
@ -386,7 +389,7 @@ void TileMap::_make_quadrant_dirty(Map<PosKey,Quadrant>::Element *Q) {
|
|||
}
|
||||
|
||||
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
||||
void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y,bool p_transpose) {
|
||||
|
||||
PosKey pk(p_x,p_y);
|
||||
|
||||
|
@ -422,7 +425,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
|||
} else {
|
||||
ERR_FAIL_COND(!Q); // quadrant should exist...
|
||||
|
||||
if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y)
|
||||
if (E->get().id==p_tile && E->get().flip_h==p_flip_x && E->get().flip_v==p_flip_y && E->get().transpose==p_transpose)
|
||||
return; //nothing changed
|
||||
|
||||
}
|
||||
|
@ -433,6 +436,7 @@ void TileMap::set_cell(int p_x,int p_y,int p_tile,bool p_flip_x,bool p_flip_y) {
|
|||
c.id=p_tile;
|
||||
c.flip_h=p_flip_x;
|
||||
c.flip_v=p_flip_y;
|
||||
c.transpose=p_transpose;
|
||||
|
||||
_make_quadrant_dirty(Q);
|
||||
|
||||
|
@ -472,6 +476,17 @@ bool TileMap::is_cell_y_flipped(int p_x,int p_y) const {
|
|||
|
||||
return E->get().flip_v;
|
||||
}
|
||||
bool TileMap::is_cell_transposed(int p_x,int p_y) const {
|
||||
|
||||
PosKey pk(p_x,p_y);
|
||||
|
||||
const Map<PosKey,Cell>::Element *E=tile_map.find(pk);
|
||||
|
||||
if (!E)
|
||||
return false;
|
||||
|
||||
return E->get().transpose;
|
||||
}
|
||||
|
||||
|
||||
void TileMap::_recreate_quadrants() {
|
||||
|
@ -536,11 +551,12 @@ void TileMap::_set_tile_data(const DVector<int>& p_data) {
|
|||
uint32_t v = decode_uint32(&local[4]);
|
||||
bool flip_h = v&(1<<29);
|
||||
bool flip_v = v&(1<<30);
|
||||
bool transpose = v&(1<<31);
|
||||
v&=(1<<29)-1;
|
||||
|
||||
// if (x<-20 || y <-20 || x>4000 || y>4000)
|
||||
// continue;
|
||||
set_cell(x,y,v,flip_h,flip_v);
|
||||
set_cell(x,y,v,flip_h,flip_v,transpose);
|
||||
|
||||
}
|
||||
|
||||
|
@ -563,6 +579,8 @@ DVector<int> TileMap::_get_tile_data() const {
|
|||
val|=(1<<29);
|
||||
if (E->get().flip_v)
|
||||
val|=(1<<30);
|
||||
if (E->get().transpose)
|
||||
val|=(1<<31);
|
||||
|
||||
encode_uint32(val,&ptr[4]);
|
||||
idx+=2;
|
||||
|
@ -829,7 +847,7 @@ void TileMap::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_collision_bounce","value"),&TileMap::set_collision_bounce);
|
||||
ObjectTypeDB::bind_method(_MD("get_collision_bounce"),&TileMap::get_collision_bounce);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y","transpose"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_x_flipped","x","y"),&TileMap::is_cell_x_flipped);
|
||||
ObjectTypeDB::bind_method(_MD("is_cell_y_flipped","x","y"),&TileMap::is_cell_y_flipped);
|
||||
|
|
|
@ -86,6 +86,7 @@ private:
|
|||
int32_t id:24;
|
||||
bool flip_h:1;
|
||||
bool flip_v:1;
|
||||
bool transpose:1;
|
||||
};
|
||||
|
||||
uint32_t _u32t;
|
||||
|
@ -168,10 +169,11 @@ public:
|
|||
void set_center_y(bool p_enable);
|
||||
bool get_center_y() const;
|
||||
|
||||
void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false);
|
||||
void set_cell(int p_x,int p_y,int p_tile,bool p_flip_x=false,bool p_flip_y=false,bool p_transpose=false);
|
||||
int get_cell(int p_x,int p_y) const;
|
||||
bool is_cell_x_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_y_flipped(int p_x,int p_y) const;
|
||||
bool is_cell_transposed(int p_x,int p_y) const;
|
||||
|
||||
Rect2 get_item_rect() const;
|
||||
|
||||
|
|
|
@ -152,11 +152,11 @@ void Camera::_get_property_list( List<PropertyInfo> *p_list) const {
|
|||
|
||||
case PROJECTION_PERSPECTIVE: {
|
||||
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_NOEDITOR) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fov" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_NOEDITOR) );
|
||||
if (keep_aspect==KEEP_WIDTH)
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovx" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
else
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,89,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
p_list->push_back( PropertyInfo( Variant::REAL, "fovy" , PROPERTY_HINT_RANGE, "1,179,0.1",PROPERTY_USAGE_EDITOR) );
|
||||
|
||||
|
||||
} break;
|
||||
|
|
|
@ -310,6 +310,17 @@ int GeometryInstance::get_baked_light_texture_id() const{
|
|||
return baked_light_texture_id;
|
||||
}
|
||||
|
||||
void GeometryInstance::set_extra_cull_margin(float p_margin) {
|
||||
|
||||
ERR_FAIL_COND(p_margin<0);
|
||||
extra_cull_margin=p_margin;
|
||||
VS::get_singleton()->instance_set_extra_visibility_margin(get_instance(),extra_cull_margin);
|
||||
}
|
||||
|
||||
float GeometryInstance::get_extra_cull_margin() const{
|
||||
|
||||
return extra_cull_margin;
|
||||
}
|
||||
|
||||
void GeometryInstance::_bind_methods() {
|
||||
|
||||
|
@ -328,6 +339,9 @@ void GeometryInstance::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_baked_light_texture_id","id"), &GeometryInstance::set_baked_light_texture_id);
|
||||
ObjectTypeDB::bind_method(_MD("get_baked_light_texture_id"), &GeometryInstance::get_baked_light_texture_id);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_extra_cull_margin","margin"), &GeometryInstance::set_extra_cull_margin);
|
||||
ObjectTypeDB::bind_method(_MD("get_extra_cull_margin"), &GeometryInstance::get_extra_cull_margin);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_baked_light_changed"), &GeometryInstance::_baked_light_changed);
|
||||
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/visible"), _SCS("set_flag"), _SCS("get_flag"),FLAG_VISIBLE);
|
||||
|
@ -336,6 +350,7 @@ void GeometryInstance::_bind_methods() {
|
|||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/receive_shadows"), _SCS("set_flag"), _SCS("get_flag"),FLAG_RECEIVE_SHADOWS);
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_begin",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_begin"), _SCS("get_draw_range_begin"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::INT, "geometry/range_end",PROPERTY_HINT_RANGE,"0,32768,0.01"), _SCS("set_draw_range_end"), _SCS("get_draw_range_end"));
|
||||
ADD_PROPERTY( PropertyInfo( Variant::REAL, "geometry/extra_cull_margin",PROPERTY_HINT_RANGE,"0,16384,0"), _SCS("set_extra_cull_margin"), _SCS("get_extra_cull_margin"));
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/billboard_y"), _SCS("set_flag"), _SCS("get_flag"),FLAG_BILLBOARD_FIX_Y);
|
||||
ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "geometry/depth_scale"), _SCS("set_flag"), _SCS("get_flag"),FLAG_DEPH_SCALE);
|
||||
|
|
|
@ -108,6 +108,7 @@ private:
|
|||
void _find_baked_light();
|
||||
BakedLightInstance *baked_light_instance;
|
||||
int baked_light_texture_id;
|
||||
float extra_cull_margin;
|
||||
|
||||
void _baked_light_changed();
|
||||
void _update_visibility();
|
||||
|
@ -132,6 +133,9 @@ public:
|
|||
void set_baked_light_texture_id(int p_id);
|
||||
int get_baked_light_texture_id() const;
|
||||
|
||||
void set_extra_cull_margin(float p_margin);
|
||||
float get_extra_cull_margin() const;
|
||||
|
||||
GeometryInstance();
|
||||
};
|
||||
|
||||
|
|
|
@ -2267,8 +2267,10 @@ void Control::_window_sort_subwindows() {
|
|||
if (!window->subwindow_order_dirty)
|
||||
return;
|
||||
|
||||
|
||||
window->modal_stack.sort_custom<CComparator>();
|
||||
window->subwindows.sort_custom<CComparator>();
|
||||
|
||||
window->subwindow_order_dirty=false;
|
||||
|
||||
}
|
||||
|
|
|
@ -972,6 +972,22 @@ bool Viewport::get_render_target_vflip() const{
|
|||
return render_target_vflip;
|
||||
}
|
||||
|
||||
void Viewport::set_render_target_clear_on_new_frame(bool p_enable) {
|
||||
|
||||
render_target_clear_on_new_frame=p_enable;
|
||||
VisualServer::get_singleton()->viewport_set_render_target_clear_on_new_frame(viewport,p_enable);
|
||||
}
|
||||
|
||||
bool Viewport::get_render_target_clear_on_new_frame() const{
|
||||
|
||||
return render_target_clear_on_new_frame;
|
||||
}
|
||||
|
||||
void Viewport::render_target_clear() {
|
||||
|
||||
//render_target_clear=true;
|
||||
VisualServer::get_singleton()->viewport_render_target_clear(viewport);
|
||||
}
|
||||
|
||||
void Viewport::set_render_target_filter(bool p_enable) {
|
||||
|
||||
|
@ -1265,6 +1281,11 @@ void Viewport::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_clear_on_new_frame","enable"), &Viewport::set_render_target_clear_on_new_frame);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_clear_on_new_frame"), &Viewport::get_render_target_clear_on_new_frame);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("render_target_clear"), &Viewport::render_target_clear);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter);
|
||||
ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter);
|
||||
|
||||
|
@ -1306,6 +1327,7 @@ void Viewport::_bind_methods() {
|
|||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/clear_on_new_frame"), _SCS("set_render_target_clear_on_new_frame"), _SCS("get_render_target_clear_on_new_frame") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/gen_mipmaps"), _SCS("set_render_target_gen_mipmaps"), _SCS("get_render_target_gen_mipmaps") );
|
||||
ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") );
|
||||
|
@ -1344,6 +1366,8 @@ Viewport::Viewport() {
|
|||
render_target_gen_mipmaps=false;
|
||||
render_target=false;
|
||||
render_target_vflip=false;
|
||||
render_target_clear_on_new_frame=true;
|
||||
//render_target_clear=true;
|
||||
render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE;
|
||||
render_target_texture = Ref<RenderTargetTexture>( memnew( RenderTargetTexture(this) ) );
|
||||
|
||||
|
|
|
@ -114,6 +114,7 @@ friend class RenderTargetTexture;
|
|||
|
||||
bool transparent_bg;
|
||||
bool render_target_vflip;
|
||||
bool render_target_clear_on_new_frame;
|
||||
bool render_target_filter;
|
||||
bool render_target_gen_mipmaps;
|
||||
|
||||
|
@ -220,6 +221,10 @@ public:
|
|||
void set_render_target_vflip(bool p_enable);
|
||||
bool get_render_target_vflip() const;
|
||||
|
||||
void set_render_target_clear_on_new_frame(bool p_enable);
|
||||
bool get_render_target_clear_on_new_frame() const;
|
||||
void render_target_clear();
|
||||
|
||||
void set_render_target_filter(bool p_enable);
|
||||
bool get_render_target_filter() const;
|
||||
|
||||
|
|
|
@ -79,6 +79,8 @@
|
|||
#include "scene/resources/video_stream.h"
|
||||
#include "scene/2d/particles_2d.h"
|
||||
#include "scene/2d/path_2d.h"
|
||||
#include "scene/2d/light_2d.h"
|
||||
#include "scene/2d/light_occluder_2d.h"
|
||||
|
||||
#include "scene/2d/canvas_item.h"
|
||||
#include "scene/2d/sprite.h"
|
||||
|
@ -103,6 +105,7 @@
|
|||
#include "scene/2d/remote_transform_2d.h"
|
||||
#include "scene/2d/y_sort.h"
|
||||
#include "scene/2d/navigation2d.h"
|
||||
#include "scene/2d/canvas_modulate.h"
|
||||
|
||||
#include "scene/2d/position_2d.h"
|
||||
#include "scene/2d/tile_map.h"
|
||||
|
@ -263,6 +266,7 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_virtual_type<RenderTargetTexture>();
|
||||
ObjectTypeDB::register_type<Timer>();
|
||||
ObjectTypeDB::register_type<CanvasLayer>();
|
||||
ObjectTypeDB::register_type<CanvasModulate>();
|
||||
ObjectTypeDB::register_type<ResourcePreloader>();
|
||||
|
||||
/* REGISTER GUI */
|
||||
|
@ -451,6 +455,7 @@ void register_scene_types() {
|
|||
//ObjectTypeDB::set_type_enabled("BodyVolumeCylinder",false);
|
||||
//ObjectTypeDB::set_type_enabled("BodyVolumeConvexPolygon",false);
|
||||
|
||||
ObjectTypeDB::register_type<CanvasItemMaterial>();
|
||||
ObjectTypeDB::register_virtual_type<CanvasItem>();
|
||||
ObjectTypeDB::register_type<Node2D>();
|
||||
ObjectTypeDB::register_type<Particles2D>();
|
||||
|
@ -472,6 +477,9 @@ void register_scene_types() {
|
|||
ObjectTypeDB::register_type<VisibilityNotifier2D>();
|
||||
ObjectTypeDB::register_type<VisibilityEnabler2D>();
|
||||
ObjectTypeDB::register_type<Polygon2D>();
|
||||
ObjectTypeDB::register_type<Light2D>();
|
||||
ObjectTypeDB::register_type<LightOccluder2D>();
|
||||
ObjectTypeDB::register_type<OccluderPolygon2D>();
|
||||
ObjectTypeDB::register_type<YSort>();
|
||||
|
||||
ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
|
||||
|
|
|
@ -38,19 +38,19 @@ Size2 Texture::get_size() const {
|
|||
}
|
||||
|
||||
|
||||
void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void Texture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, get_size()),get_rid(),false,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void Texture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,get_rid(),p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{
|
||||
void Texture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{
|
||||
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,get_rid(),p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
bool Texture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
|
||||
|
@ -70,9 +70,9 @@ void Texture::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("has_alpha"),&Texture::has_alpha);
|
||||
ObjectTypeDB::bind_method(_MD("set_flags","flags"),&Texture::set_flags);
|
||||
ObjectTypeDB::bind_method(_MD("get_flags"),&Texture::get_flags);
|
||||
ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("draw","canvas_item","pos","modulate"),&Texture::draw,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect","canvas_item","rect","tile","modulate"),&Texture::draw_rect,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("draw_rect_region","canvas_item","rect","src_rect","modulate"),&Texture::draw_rect_region,DEFVAL(Color(1,1,1)),DEFVAL(false));
|
||||
|
||||
BIND_CONSTANT( FLAG_MIPMAPS );
|
||||
BIND_CONSTANT( FLAG_REPEAT );
|
||||
|
@ -327,28 +327,27 @@ bool ImageTexture::has_alpha() const {
|
|||
}
|
||||
|
||||
|
||||
void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void ImageTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void ImageTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const{
|
||||
void ImageTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{
|
||||
|
||||
if ((w|h)==0)
|
||||
return;
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate);
|
||||
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
|
||||
void ImageTexture::set_size_override(const Size2& p_size) {
|
||||
|
||||
Size2 s=p_size;
|
||||
|
@ -546,7 +545,7 @@ void AtlasTexture::_bind_methods() {
|
|||
|
||||
|
||||
|
||||
void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
Rect2 rc=region;
|
||||
|
||||
|
@ -561,10 +560,10 @@ void AtlasTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_m
|
|||
rc.size.height=atlas->get_height();
|
||||
}
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,Rect2(p_pos+margin.pos,rc.size),atlas->get_rid(),rc,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
Rect2 rc=region;
|
||||
|
||||
|
@ -582,10 +581,10 @@ void AtlasTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,
|
|||
Vector2 scale = p_rect.size / (region.size+margin.size);
|
||||
Rect2 dr( p_rect.pos+margin.pos*scale,rc.size*scale );
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),rc,p_modulate,p_transpose);
|
||||
|
||||
}
|
||||
void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const {
|
||||
void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
//this might not necesarily work well if using a rect, needs to be fixed properly
|
||||
Rect2 rc=region;
|
||||
|
@ -615,7 +614,7 @@ void AtlasTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
}
|
||||
Rect2 dr( p_rect.pos+ofs*scale,src_c.size*scale );
|
||||
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate);
|
||||
VS::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,dr,atlas->get_rid(),src_c,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
bool AtlasTexture::get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const {
|
||||
|
@ -801,15 +800,16 @@ void LargeTexture::_bind_methods() {
|
|||
|
||||
|
||||
|
||||
void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate) const {
|
||||
void LargeTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
pieces[i].texture->draw(p_canvas_item,pieces[i].offset+p_pos,p_modulate);
|
||||
// TODO
|
||||
pieces[i].texture->draw(p_canvas_item,pieces[i].offset+p_pos,p_modulate,p_transpose);
|
||||
}
|
||||
}
|
||||
|
||||
void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate) const {
|
||||
void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
//tiling not supported for this
|
||||
if (size.x==0 || size.y==0)
|
||||
|
@ -819,11 +819,11 @@ void LargeTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,
|
|||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
pieces[i].texture->draw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate);
|
||||
// TODO
|
||||
pieces[i].texture->draw_rect(p_canvas_item,Rect2(pieces[i].offset*scale+p_rect.pos,pieces[i].texture->get_size()*scale),false,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
}
|
||||
void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate) const {
|
||||
void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const {
|
||||
|
||||
|
||||
//tiling not supported for this
|
||||
|
@ -834,6 +834,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
|
||||
for(int i=0;i<pieces.size();i++) {
|
||||
|
||||
// TODO
|
||||
Rect2 rect( pieces[i].offset, pieces[i].texture->get_size());
|
||||
if (!p_src_rect.intersects(rect))
|
||||
continue;
|
||||
|
@ -842,7 +843,7 @@ void LargeTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const
|
|||
target.size*=scale;
|
||||
target.pos=p_rect.pos+(p_src_rect.pos+rect.pos)*scale;
|
||||
local.pos-=rect.pos;
|
||||
pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate);
|
||||
pieces[i].texture->draw_rect_region(p_canvas_item,target,local,p_modulate,p_transpose);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -69,9 +69,9 @@ public:
|
|||
virtual void set_flags(uint32_t p_flags)=0;
|
||||
virtual uint32_t get_flags() const=0;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
|
||||
|
||||
|
||||
|
@ -135,10 +135,9 @@ public:
|
|||
virtual RID get_rid() const;
|
||||
|
||||
bool has_alpha() const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
void set_storage(Storage p_storage);
|
||||
Storage get_storage() const;
|
||||
|
||||
|
@ -191,9 +190,9 @@ public:
|
|||
void set_margin(const Rect2& p_margin);
|
||||
Rect2 get_margin() const ;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual bool get_rect_region(const Rect2& p_rect, const Rect2& p_src_rect,Rect2& r_rect,Rect2& r_src_rect) const;
|
||||
|
||||
|
||||
|
@ -241,9 +240,9 @@ public:
|
|||
Vector2 get_piece_offset(int p_idx) const;
|
||||
Ref<Texture> get_piece_texture(int p_idx) const;
|
||||
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1)) const;
|
||||
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
|
||||
|
||||
|
||||
LargeTexture();
|
||||
|
|
|
@ -41,6 +41,7 @@ SceneStringNames::SceneStringNames() {
|
|||
visibility_changed=StaticCString::create("visibility_changed");
|
||||
input_event=StaticCString::create("input_event");
|
||||
shader_shader=StaticCString::create("shader/shader");
|
||||
shader_unshaded=StaticCString::create("shader/unshaded");
|
||||
enter_tree=StaticCString::create("enter_tree");
|
||||
exit_tree=StaticCString::create("exit_tree");
|
||||
item_rect_changed=StaticCString::create("item_rect_changed");
|
||||
|
|
|
@ -56,6 +56,7 @@ public:
|
|||
StringName _input_event;
|
||||
StringName item_rect_changed;
|
||||
StringName shader_shader;
|
||||
StringName shader_unshaded;
|
||||
StringName enter_tree;
|
||||
StringName exit_tree;
|
||||
StringName size_flags_changed;
|
||||
|
|
|
@ -564,7 +564,76 @@ public:
|
|||
CANVAS_RECT_REGION=1,
|
||||
CANVAS_RECT_TILE=2,
|
||||
CANVAS_RECT_FLIP_H=4,
|
||||
CANVAS_RECT_FLIP_V=8
|
||||
CANVAS_RECT_FLIP_V=8,
|
||||
CANVAS_RECT_TRANSPOSE=16
|
||||
};
|
||||
|
||||
|
||||
struct CanvasLight {
|
||||
|
||||
|
||||
|
||||
bool enabled;
|
||||
Color color;
|
||||
Matrix32 xform;
|
||||
float height;
|
||||
int z_min;
|
||||
int z_max;
|
||||
int layer_min;
|
||||
int layer_max;
|
||||
int item_mask;
|
||||
bool subtract;
|
||||
RID texture;
|
||||
Vector2 texture_offset;
|
||||
RID canvas;
|
||||
RID shadow_buffer;
|
||||
int shadow_buffer_size;
|
||||
float shadow_esm_mult;
|
||||
|
||||
|
||||
void *texture_cache; // implementation dependent
|
||||
Rect2 rect_cache;
|
||||
Matrix32 xform_cache;
|
||||
float radius_cache; //used for shadow far plane
|
||||
CameraMatrix shadow_matrix_cache;
|
||||
|
||||
Matrix32 light_shader_xform;
|
||||
Vector2 light_shader_pos;
|
||||
|
||||
CanvasLight *shadows_next_ptr;
|
||||
CanvasLight *filter_next_ptr;
|
||||
CanvasLight *next_ptr;
|
||||
|
||||
CanvasLight() {
|
||||
enabled=true;
|
||||
color=Color(1,1,1);
|
||||
height=0;
|
||||
z_min=-1024;
|
||||
z_max=1024;
|
||||
layer_min=0;
|
||||
layer_max=0;
|
||||
item_mask=1;
|
||||
subtract=false;
|
||||
texture_cache=NULL;
|
||||
next_ptr=NULL;
|
||||
filter_next_ptr=NULL;
|
||||
shadow_buffer_size=2048;
|
||||
shadow_esm_mult=80;
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
struct CanvasItem;
|
||||
|
||||
struct CanvasItemMaterial {
|
||||
|
||||
RID shader;
|
||||
Map<StringName,Variant> shader_param;
|
||||
uint32_t shader_version;
|
||||
Set<CanvasItem*> owners;
|
||||
bool unshaded;
|
||||
|
||||
CanvasItemMaterial() {unshaded=false; shader_version=0; }
|
||||
};
|
||||
|
||||
struct CanvasItem {
|
||||
|
@ -689,25 +758,25 @@ public:
|
|||
bool visible;
|
||||
bool ontop;
|
||||
VS::MaterialBlendMode blend_mode;
|
||||
int light_mask;
|
||||
Vector<Command*> commands;
|
||||
mutable bool custom_rect;
|
||||
mutable bool rect_dirty;
|
||||
mutable Rect2 rect;
|
||||
CanvasItem*next;
|
||||
RID shader;
|
||||
Map<StringName,Variant> shader_param;
|
||||
uint32_t shader_version;
|
||||
CanvasItemMaterial* material;
|
||||
|
||||
|
||||
float final_opacity;
|
||||
Matrix32 final_transform;
|
||||
Rect2 final_clip_rect;
|
||||
CanvasItem* final_clip_owner;
|
||||
CanvasItem* shader_owner;
|
||||
CanvasItem* material_owner;
|
||||
ViewportRender *vp_render;
|
||||
|
||||
const Rect2& get_rect() const {
|
||||
Rect2 global_rect_cache;
|
||||
|
||||
const Rect2& get_rect() const {
|
||||
if (custom_rect || !rect_dirty)
|
||||
return rect;
|
||||
|
||||
|
@ -830,8 +899,8 @@ public:
|
|||
return rect;
|
||||
}
|
||||
|
||||
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; shader_owner=NULL;}
|
||||
CanvasItem() { vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; shader_version=0; shader_owner=NULL;}
|
||||
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true; final_clip_owner=NULL; material_owner=NULL;}
|
||||
CanvasItem() { light_mask=1; vp_render=NULL; next=NULL; final_clip_owner=NULL; clip=false; final_opacity=1; blend_mode=VS::MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; material_owner=NULL; material=NULL; }
|
||||
virtual ~CanvasItem() { clear(); }
|
||||
};
|
||||
|
||||
|
@ -853,8 +922,37 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor)=0;
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform)=0;
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list)=0;
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light)=0;
|
||||
virtual void canvas_debug_viewport_shadows(CanvasLight* p_lights_with_shadow)=0;
|
||||
/* LIGHT SHADOW MAPPING */
|
||||
|
||||
virtual RID canvas_light_occluder_create()=0;
|
||||
virtual void canvas_light_occluder_set_polylines(RID p_occluder, const DVector<Vector2>& p_lines)=0;
|
||||
|
||||
|
||||
virtual RID canvas_light_shadow_buffer_create(int p_width)=0;
|
||||
|
||||
struct CanvasLightOccluderInstance {
|
||||
|
||||
|
||||
bool enabled;
|
||||
RID canvas;
|
||||
RID polygon;
|
||||
RID polygon_buffer;
|
||||
Rect2 aabb_cache;
|
||||
Matrix32 xform;
|
||||
Matrix32 xform_cache;
|
||||
int light_mask;
|
||||
VS::CanvasOccluderPolygonCullMode cull_cache;
|
||||
|
||||
CanvasLightOccluderInstance *next;
|
||||
|
||||
CanvasLightOccluderInstance() { enabled=true; next=NULL; light_mask=1; cull_cache=VS::CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
virtual void canvas_light_shadow_buffer_update(RID p_buffer, const Matrix32& p_light_xform, int p_light_mask,float p_near, float p_far, CanvasLightOccluderInstance* p_occluders, CameraMatrix *p_xform_cache)=0;
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
|
@ -894,6 +992,8 @@ public:
|
|||
virtual bool is_environment(const RID& p_rid) const=0;
|
||||
virtual bool is_shader(const RID& p_rid) const=0;
|
||||
|
||||
virtual bool is_canvas_light_occluder(const RID& p_rid) const=0;
|
||||
|
||||
virtual void free(const RID& p_rid)=0;
|
||||
|
||||
virtual void init()=0;
|
||||
|
|
|
@ -1622,7 +1622,7 @@ void RasterizerDummy::canvas_set_transform(const Matrix32& p_transform) {
|
|||
|
||||
}
|
||||
|
||||
void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list) {
|
||||
void RasterizerDummy::canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light) {
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -710,7 +710,7 @@ public:
|
|||
virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor);
|
||||
virtual void canvas_set_transform(const Matrix32& p_transform);
|
||||
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list);
|
||||
virtual void canvas_render_items(CanvasItem *p_item_list,int p_z,const Color& p_modulate,CanvasLight *p_light);
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
|
|
|
@ -2059,7 +2059,9 @@ Error ShaderLanguage::parse_expression(Parser& parser,Node *p_parent,Node **r_ex
|
|||
at+=get_datatype_name(compute_node_type(op->arguments[i]));
|
||||
|
||||
}
|
||||
parser.set_error("Invalid arguments to operator "+String(token_names[op->op])+": "+at);
|
||||
static const char *op_names[OP_MAX]={"=","+","-","*","/","+=","-=","*=","/=","-","!","==","!=","<=",">=","<",">","||","&&","call","()"};
|
||||
|
||||
parser.set_error("Invalid arguments to operator "+String(op_names[op->op])+": "+at);
|
||||
return ERR_PARSE_ERROR;
|
||||
}
|
||||
expression.remove(next_op);
|
||||
|
|
|
@ -1576,6 +1576,15 @@ void VisualServerRaster::viewport_set_render_target_vflip(RID p_viewport,bool p_
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->render_target_clear_on_new_frame=p_enable;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
|
@ -1594,6 +1603,23 @@ bool VisualServerRaster::viewport_get_render_target_vflip(RID p_viewport) const{
|
|||
|
||||
}
|
||||
|
||||
bool VisualServerRaster::viewport_get_render_target_clear_on_new_frame(RID p_viewport) const{
|
||||
|
||||
const Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND_V(!viewport,false);
|
||||
|
||||
return viewport->render_target_clear_on_new_frame;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_render_target_clear(RID p_viewport) {
|
||||
|
||||
Viewport *viewport = viewport_owner.get( p_viewport );
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
viewport->render_target_clear=true;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::viewport_queue_screen_capture(RID p_viewport) {
|
||||
|
||||
|
@ -3195,6 +3221,7 @@ RID VisualServerRaster::canvas_create() {
|
|||
return rid;
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring) {
|
||||
|
||||
Canvas * canvas = canvas_owner.get(p_canvas);
|
||||
|
@ -3220,6 +3247,14 @@ Point2 VisualServerRaster::canvas_get_item_mirroring(RID p_canvas,RID p_item) co
|
|||
return canvas->child_items[idx].mirror;
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_set_modulate(RID p_canvas,const Color& p_color) {
|
||||
|
||||
Canvas * canvas = canvas_owner.get(p_canvas);
|
||||
ERR_FAIL_COND(!canvas);
|
||||
canvas->modulate=p_color;
|
||||
}
|
||||
|
||||
|
||||
|
||||
RID VisualServerRaster::canvas_item_create() {
|
||||
|
||||
|
@ -3305,14 +3340,27 @@ bool VisualServerRaster::canvas_item_is_visible(RID p_item) const {
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_light_mask(RID p_canvas_item,int p_mask) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
if (canvas_item->light_mask==p_mask)
|
||||
return;
|
||||
VS_CHANGED;
|
||||
|
||||
canvas_item->light_mask=p_mask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
if (!canvas_item) {
|
||||
printf("!canvas_item\n");
|
||||
};
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
||||
if (canvas_item->blend_mode==p_blend)
|
||||
|
@ -3470,7 +3518,7 @@ void VisualServerRaster::canvas_item_add_circle(RID p_item, const Point2& p_pos,
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate) {
|
||||
void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile,const Color& p_modulate,bool p_transpose) {
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -3493,12 +3541,16 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p
|
|||
rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
rect->rect.size.y = -rect->rect.size.y;
|
||||
}
|
||||
if (p_transpose) {
|
||||
rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE;
|
||||
SWAP(rect->rect.size.x, rect->rect.size.y);
|
||||
}
|
||||
rect->texture=p_texture;
|
||||
canvas_item->rect_dirty=true;
|
||||
canvas_item->commands.push_back(rect);
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate) {
|
||||
void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate,bool p_transpose) {
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
|
@ -3521,12 +3573,17 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R
|
|||
rect->flags|=Rasterizer::CANVAS_RECT_FLIP_V;
|
||||
rect->rect.size.y = -rect->rect.size.y;
|
||||
}
|
||||
if (p_transpose) {
|
||||
rect->flags|=Rasterizer::CANVAS_RECT_TRANSPOSE;
|
||||
SWAP(rect->rect.size.x, rect->rect.size.y);
|
||||
}
|
||||
|
||||
canvas_item->rect_dirty=true;
|
||||
|
||||
canvas_item->commands.push_back(rect);
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
@ -3708,55 +3765,32 @@ void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, boo
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) {
|
||||
void VisualServerRaster::canvas_item_set_use_parent_material(RID p_item, bool p_enable) {
|
||||
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
canvas_item->use_parent_shader=p_enable;
|
||||
canvas_item->use_parent_material=p_enable;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_shader(RID p_item, RID p_shader) {
|
||||
void VisualServerRaster::canvas_item_set_material(RID p_item, RID p_material) {
|
||||
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
canvas_item->shader=p_shader;
|
||||
|
||||
if (canvas_item->material)
|
||||
canvas_item->material->owners.erase(canvas_item);
|
||||
|
||||
canvas_item->material=NULL;
|
||||
|
||||
if (canvas_item_material_owner.owns(p_material)) {
|
||||
canvas_item->material=canvas_item_material_owner.get(p_material);
|
||||
canvas_item->material->owners.insert(canvas_item);
|
||||
}
|
||||
|
||||
RID VisualServerRaster::canvas_item_get_shader(RID p_item) const{
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
|
||||
ERR_FAIL_COND_V(!canvas_item,RID());
|
||||
return canvas_item->shader;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value){
|
||||
|
||||
VS_CHANGED;
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
ERR_FAIL_COND(!canvas_item);
|
||||
if (p_value.get_type()==Variant::NIL)
|
||||
canvas_item->shader_param.erase(p_param);
|
||||
else
|
||||
canvas_item->shader_param[p_param]=p_value;
|
||||
|
||||
}
|
||||
Variant VisualServerRaster::canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const{
|
||||
|
||||
CanvasItem *canvas_item = canvas_item_owner.get( p_canvas_item );
|
||||
ERR_FAIL_COND_V(!canvas_item,Variant());
|
||||
if (!canvas_item->shader_param.has(p_param)) {
|
||||
ERR_FAIL_COND_V(!canvas_item->shader.is_valid(),Variant());
|
||||
return rasterizer->shader_get_default_param(canvas_item->shader,p_param);
|
||||
}
|
||||
|
||||
return canvas_item->shader_param[p_param];
|
||||
}
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) {
|
||||
|
||||
VS_CHANGED;
|
||||
|
@ -3823,60 +3857,150 @@ void VisualServerRaster::canvas_item_raise(RID p_item) {
|
|||
|
||||
RID VisualServerRaster::canvas_light_create() {
|
||||
|
||||
return RID();
|
||||
Rasterizer::CanvasLight *clight = memnew( Rasterizer::CanvasLight );
|
||||
return canvas_light_owner.make_rid(clight);
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_attach_to_canvas(RID p_light,RID p_canvas){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
if (clight->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(clight->canvas);
|
||||
canvas->lights.erase(clight);
|
||||
}
|
||||
|
||||
if (!canvas_owner.owns(p_canvas))
|
||||
p_canvas=RID();
|
||||
clight->canvas=p_canvas;
|
||||
|
||||
if (clight->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(clight->canvas);
|
||||
canvas->lights.insert(clight);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_enabled(RID p_light, bool p_enabled){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->enabled=p_enabled;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_transform(RID p_light, const Matrix32& p_transform){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->xform=p_transform;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_texture(RID p_light, RID p_texture){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->texture=p_texture;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_texture_offset(RID p_light, const Vector2& p_offset){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->texture_offset=p_offset;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_color(RID p_light, const Color& p_color){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->color=p_color;
|
||||
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_height(RID p_light, float p_height){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->height=p_height;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->z_min=p_min_z;
|
||||
clight->z_max=p_max_z;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer) {
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->layer_min=p_min_layer;
|
||||
clight->layer_max=p_max_layer;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_item_mask(RID p_light, int p_mask){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->item_mask=p_mask;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode){
|
||||
void VisualServerRaster::canvas_light_set_subtract_mode(RID p_light, bool p_enable) {
|
||||
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->subtract=p_enable;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_shadow_enabled(RID p_light, bool p_enabled){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
if (clight->shadow_buffer.is_valid()==p_enabled)
|
||||
return;
|
||||
if (p_enabled) {
|
||||
clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size);
|
||||
} else {
|
||||
rasterizer->free(clight->shadow_buffer);
|
||||
clight->shadow_buffer=RID();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_set_shadow_buffer_size(RID p_light, int p_size){
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
|
||||
ERR_FAIL_COND(p_size<32 || p_size>16384);
|
||||
|
||||
clight->shadow_buffer_size=nearest_power_of_2(p_size);
|
||||
|
||||
|
||||
if (clight->shadow_buffer.is_valid()) {
|
||||
rasterizer->free(clight->shadow_buffer);
|
||||
clight->shadow_buffer=rasterizer->canvas_light_shadow_buffer_create(clight->shadow_buffer_size);
|
||||
}
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size){
|
||||
|
||||
void VisualServerRaster::canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier) {
|
||||
|
||||
Rasterizer::CanvasLight *clight = canvas_light_owner.get(p_light);
|
||||
ERR_FAIL_COND(!clight);
|
||||
clight->shadow_esm_mult=p_multiplier;
|
||||
|
||||
}
|
||||
|
||||
|
@ -3884,26 +4008,217 @@ void VisualServerRaster::canvas_light_set_shadow_filter(RID p_light, int p_size)
|
|||
|
||||
RID VisualServerRaster::canvas_light_occluder_create() {
|
||||
|
||||
return RID();
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = memnew( Rasterizer::CanvasLightOccluderInstance );
|
||||
|
||||
return canvas_light_occluder_owner.make_rid( occluder );
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas) {
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
if (occluder->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(occluder->canvas);
|
||||
canvas->occluders.erase(occluder);
|
||||
}
|
||||
|
||||
if (!canvas_owner.owns(p_canvas))
|
||||
p_canvas=RID();
|
||||
|
||||
occluder->canvas=p_canvas;
|
||||
|
||||
if (occluder->canvas.is_valid()) {
|
||||
|
||||
Canvas *canvas = canvas_owner.get(occluder->canvas);
|
||||
canvas->occluders.insert(occluder);
|
||||
}
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled){
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
occluder->enabled=p_enabled;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape){
|
||||
void VisualServerRaster::canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon) {
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
if (occluder->polygon.is_valid()) {
|
||||
CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon);
|
||||
if (occluder_poly) {
|
||||
occluder_poly->owners.erase(occluder);
|
||||
}
|
||||
}
|
||||
|
||||
occluder->polygon=p_polygon;
|
||||
occluder->polygon_buffer=RID();
|
||||
|
||||
if (occluder->polygon.is_valid()) {
|
||||
CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_polygon);
|
||||
if (!occluder_poly)
|
||||
occluder->polygon=RID();
|
||||
ERR_FAIL_COND(!occluder_poly);
|
||||
occluder_poly->owners.insert(occluder);
|
||||
occluder->polygon_buffer=occluder_poly->occluder;
|
||||
occluder->aabb_cache=occluder_poly->aabb;
|
||||
occluder->cull_cache=occluder_poly->cull_mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void VisualServerRaster::canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform) {
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
occluder->xform=p_xform;
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask) {
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_occluder);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
occluder->light_mask=p_mask;
|
||||
|
||||
}
|
||||
|
||||
|
||||
RID VisualServerRaster::canvas_occluder_polygon_create() {
|
||||
|
||||
CanvasLightOccluderPolygon * occluder_poly = memnew( CanvasLightOccluderPolygon );
|
||||
occluder_poly->occluder=rasterizer->canvas_light_occluder_create();
|
||||
return canvas_light_occluder_polygon_owner.make_rid(occluder_poly);
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_occluder_polygon_set_shape(RID p_occluder_polygon, const DVector<Vector2>& p_shape, bool p_close){
|
||||
|
||||
if (p_shape.size()<3) {
|
||||
canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,p_shape);
|
||||
return;
|
||||
}
|
||||
|
||||
DVector<Vector2> lines;
|
||||
int lc = p_shape.size()*2;
|
||||
|
||||
lines.resize(lc-(p_close?0:2));
|
||||
{
|
||||
DVector<Vector2>::Write w = lines.write();
|
||||
DVector<Vector2>::Read r = p_shape.read();
|
||||
|
||||
int max=lc/2;
|
||||
if (!p_close) {
|
||||
max--;
|
||||
}
|
||||
for(int i=0;i<max;i++) {
|
||||
|
||||
Vector2 a = r[i];
|
||||
Vector2 b = r[(i+1)%(lc/2)];
|
||||
w[i*2+0]=a;
|
||||
w[i*2+1]=b;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
canvas_occluder_polygon_set_shape_as_lines(p_occluder_polygon,lines);
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape) {
|
||||
|
||||
CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon);
|
||||
ERR_FAIL_COND(!occluder_poly);
|
||||
ERR_FAIL_COND(p_shape.size()&1);
|
||||
|
||||
int lc = p_shape.size();
|
||||
occluder_poly->aabb=Rect2();
|
||||
{
|
||||
DVector<Vector2>::Read r = p_shape.read();
|
||||
for(int i=0;i<lc;i++) {
|
||||
if (i==0)
|
||||
occluder_poly->aabb.pos=r[i];
|
||||
else
|
||||
occluder_poly->aabb.expand_to(r[i]);
|
||||
}
|
||||
}
|
||||
|
||||
rasterizer->canvas_light_occluder_set_polylines(occluder_poly->occluder,p_shape);
|
||||
for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) {
|
||||
E->get()->aabb_cache=occluder_poly->aabb;
|
||||
}
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode) {
|
||||
|
||||
CanvasLightOccluderPolygon * occluder_poly = canvas_light_occluder_polygon_owner.get(p_occluder_polygon);
|
||||
ERR_FAIL_COND(!occluder_poly);
|
||||
occluder_poly->cull_mode=p_mode;
|
||||
for( Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=occluder_poly->owners.front();E;E=E->next()) {
|
||||
E->get()->cull_cache=p_mode;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
RID VisualServerRaster::canvas_item_material_create() {
|
||||
|
||||
Rasterizer::CanvasItemMaterial *material = memnew( Rasterizer::CanvasItemMaterial );
|
||||
return canvas_item_material_owner.make_rid(material);
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_material_set_shader(RID p_material, RID p_shader){
|
||||
|
||||
VS_CHANGED;
|
||||
Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
|
||||
ERR_FAIL_COND(!material);
|
||||
material->shader=p_shader;
|
||||
|
||||
}
|
||||
void VisualServerRaster::canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value){
|
||||
|
||||
VS_CHANGED;
|
||||
Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
|
||||
ERR_FAIL_COND(!material);
|
||||
if (p_value.get_type()==Variant::NIL)
|
||||
material->shader_param.erase(p_param);
|
||||
else
|
||||
material->shader_param[p_param]=p_value;
|
||||
|
||||
|
||||
}
|
||||
Variant VisualServerRaster::canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const{
|
||||
Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
|
||||
ERR_FAIL_COND_V(!material,Variant());
|
||||
if (!material->shader_param.has(p_param)) {
|
||||
ERR_FAIL_COND_V(!material->shader.is_valid(),Variant());
|
||||
return rasterizer->shader_get_default_param(material->shader,p_param);
|
||||
}
|
||||
|
||||
return material->shader_param[p_param];
|
||||
}
|
||||
|
||||
void VisualServerRaster::canvas_item_material_set_unshaded(RID p_material, bool p_unshaded){
|
||||
|
||||
VS_CHANGED;
|
||||
Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get( p_material );
|
||||
ERR_FAIL_COND(!material);
|
||||
material->unshaded=p_unshaded;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/******** CANVAS *********/
|
||||
|
||||
|
||||
|
@ -4155,6 +4470,16 @@ void VisualServerRaster::free( RID p_rid ) {
|
|||
canvas->child_items[i].item->parent=RID();
|
||||
}
|
||||
|
||||
for (Set<Rasterizer::CanvasLight*>::Element *E=canvas->lights.front();E;E=E->next()) {
|
||||
|
||||
E->get()->canvas=RID();
|
||||
}
|
||||
|
||||
for (Set<Rasterizer::CanvasLightOccluderInstance*>::Element *E=canvas->occluders.front();E;E=E->next()) {
|
||||
|
||||
E->get()->canvas=RID();
|
||||
}
|
||||
|
||||
canvas_owner.free( p_rid );
|
||||
|
||||
memdelete( canvas );
|
||||
|
@ -4183,9 +4508,75 @@ void VisualServerRaster::free( RID p_rid ) {
|
|||
canvas_item->child_items[i]->parent=RID();
|
||||
}
|
||||
|
||||
if (canvas_item->material) {
|
||||
canvas_item->material->owners.erase(canvas_item);
|
||||
}
|
||||
|
||||
canvas_item_owner.free( p_rid );
|
||||
|
||||
memdelete( canvas_item );
|
||||
|
||||
} else if (canvas_item_material_owner.owns(p_rid)) {
|
||||
|
||||
Rasterizer::CanvasItemMaterial *material = canvas_item_material_owner.get(p_rid);
|
||||
ERR_FAIL_COND(!material);
|
||||
for(Set<Rasterizer::CanvasItem*>::Element *E=material->owners.front();E;E=E->next()) {
|
||||
|
||||
E->get()->material=NULL;
|
||||
}
|
||||
|
||||
canvas_item_material_owner.free(p_rid);
|
||||
memdelete(material);
|
||||
|
||||
} else if (canvas_light_owner.owns(p_rid)) {
|
||||
|
||||
Rasterizer::CanvasLight *canvas_light = canvas_light_owner.get(p_rid);
|
||||
ERR_FAIL_COND(!canvas_light);
|
||||
|
||||
if (canvas_light->canvas.is_valid()) {
|
||||
Canvas* canvas = canvas_owner.get(canvas_light->canvas);
|
||||
if (canvas)
|
||||
canvas->lights.erase(canvas_light);
|
||||
}
|
||||
|
||||
if (canvas_light->shadow_buffer.is_valid())
|
||||
rasterizer->free(canvas_light->shadow_buffer);
|
||||
|
||||
canvas_light_owner.free( p_rid );
|
||||
memdelete( canvas_light );
|
||||
|
||||
} else if (canvas_light_occluder_owner.owns(p_rid)) {
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance *occluder = canvas_light_occluder_owner.get(p_rid);
|
||||
ERR_FAIL_COND(!occluder);
|
||||
|
||||
if (occluder->polygon.is_valid()) {
|
||||
|
||||
CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(occluder->polygon);
|
||||
if (occluder_poly) {
|
||||
occluder_poly->owners.erase(occluder);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
canvas_light_occluder_owner.free( p_rid );
|
||||
memdelete(occluder);
|
||||
|
||||
} else if (canvas_light_occluder_polygon_owner.owns(p_rid)) {
|
||||
|
||||
CanvasLightOccluderPolygon *occluder_poly = canvas_light_occluder_polygon_owner.get(p_rid);
|
||||
ERR_FAIL_COND(!occluder_poly);
|
||||
rasterizer->free(occluder_poly->occluder);
|
||||
|
||||
while(occluder_poly->owners.size()) {
|
||||
|
||||
occluder_poly->owners.front()->get()->polygon=RID();
|
||||
occluder_poly->owners.erase( occluder_poly->owners.front() );
|
||||
}
|
||||
|
||||
canvas_light_occluder_polygon_owner.free( p_rid );
|
||||
memdelete(occluder_poly);
|
||||
|
||||
} else if (scenario_owner.owns(p_rid)) {
|
||||
|
||||
Scenario *scenario=scenario_owner.get(p_rid);
|
||||
|
@ -6231,7 +6622,7 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
|
|||
}
|
||||
|
||||
|
||||
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) {
|
||||
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color& p_modulate, Rasterizer::CanvasLight *p_lights) {
|
||||
|
||||
|
||||
static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
|
||||
|
@ -6249,7 +6640,7 @@ void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,cons
|
|||
for(int i=0;i<z_range;i++) {
|
||||
if (!z_list[i])
|
||||
continue;
|
||||
rasterizer->canvas_render_items(z_list[i]);
|
||||
rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_modulate,p_lights);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6264,7 +6655,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void
|
|||
|
||||
}
|
||||
|
||||
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) {
|
||||
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_material_owner) {
|
||||
|
||||
CanvasItem *ci = p_canvas_item;
|
||||
|
||||
|
@ -6309,11 +6700,11 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
ci->vp_render=NULL;
|
||||
}
|
||||
|
||||
if (ci->use_parent_shader && p_shader_owner)
|
||||
ci->shader_owner=p_shader_owner;
|
||||
if (ci->use_parent_material && p_material_owner)
|
||||
ci->material_owner=p_material_owner;
|
||||
else {
|
||||
p_shader_owner=ci;
|
||||
ci->shader_owner=NULL;
|
||||
p_material_owner=ci;
|
||||
ci->material_owner=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
@ -6347,7 +6738,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
|
||||
if (child_items[i]->ontop)
|
||||
continue;
|
||||
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
|
||||
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner);
|
||||
}
|
||||
|
||||
|
||||
|
@ -6355,7 +6746,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
//something to draw?
|
||||
ci->final_transform=xform;
|
||||
ci->final_opacity=opacity * ci->self_opacity;
|
||||
|
||||
ci->global_rect_cache=global_rect;
|
||||
|
||||
int zidx = p_z-CANVAS_ITEM_Z_MIN;
|
||||
|
||||
|
@ -6368,6 +6759,8 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
z_last_list[zidx]=ci;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ci->next=NULL;
|
||||
|
||||
}
|
||||
|
@ -6376,12 +6769,12 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
|
|||
|
||||
if (!child_items[i]->ontop)
|
||||
continue;
|
||||
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
|
||||
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_material_owner);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform) {
|
||||
void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_transform,Rasterizer::CanvasLight *p_lights) {
|
||||
|
||||
rasterizer->canvas_begin();
|
||||
|
||||
|
@ -6414,30 +6807,30 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
|
|||
for(int i=0;i<z_range;i++) {
|
||||
if (!z_list[i])
|
||||
continue;
|
||||
rasterizer->canvas_render_items(z_list[i]);
|
||||
rasterizer->canvas_render_items(z_list[i],CANVAS_ITEM_Z_MIN+i,p_canvas->modulate,p_lights);
|
||||
}
|
||||
} else {
|
||||
|
||||
for(int i=0;i<l;i++) {
|
||||
|
||||
Canvas::ChildItem& ci=p_canvas->child_items[i];
|
||||
_render_canvas_item_tree(ci.item,p_transform,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,p_transform,clip_rect,p_canvas->modulate,p_lights);
|
||||
|
||||
//mirroring (useful for scrolling backgrounds)
|
||||
if (ci.mirror.x!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
if (ci.mirror.y!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
if (ci.mirror.y!=0 && ci.mirror.x!=0) {
|
||||
|
||||
Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect);
|
||||
_render_canvas_item_tree(ci.item,xform2,clip_rect,p_canvas->modulate,p_lights);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6492,29 +6885,129 @@ void VisualServerRaster::_draw_viewport(Viewport *p_viewport,int p_ofs_x, int p_
|
|||
} else if (true /*|| !p_viewport->canvas_list.empty()*/){
|
||||
|
||||
//clear the viewport black because of no camera? i seriously should..
|
||||
if (p_viewport->render_target_clear_on_new_frame || p_viewport->render_target_clear) {
|
||||
if (p_viewport->transparent_bg) {
|
||||
rasterizer->clear_viewport(Color(0,0,0,0));
|
||||
}
|
||||
else {
|
||||
rasterizer->clear_viewport(clear_color);
|
||||
}
|
||||
p_viewport->render_target_clear=false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!p_viewport->hide_canvas) {
|
||||
int i=0;
|
||||
|
||||
Map<Viewport::CanvasKey,Viewport::CanvasData*> canvas_map;
|
||||
|
||||
Rect2 clip_rect(0,0,viewport_rect.width,viewport_rect.height);
|
||||
Rasterizer::CanvasLight *lights=NULL;
|
||||
Rasterizer::CanvasLight *lights_with_shadow=NULL;
|
||||
Rect2 shadow_rect;
|
||||
|
||||
for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) {
|
||||
|
||||
Matrix32 xf = p_viewport->global_transform * E->get().transform;
|
||||
|
||||
//find lights in canvas
|
||||
|
||||
|
||||
for(Set<Rasterizer::CanvasLight*>::Element *F=E->get().canvas->lights.front();F;F=F->next()) {
|
||||
|
||||
Rasterizer::CanvasLight* cl=F->get();
|
||||
if (cl->enabled && cl->texture.is_valid()) {
|
||||
//not super efficient..
|
||||
Size2 tsize(rasterizer->texture_get_width(cl->texture),rasterizer->texture_get_height(cl->texture));
|
||||
Vector2 offset=tsize/2.0;
|
||||
cl->rect_cache=Rect2(-offset+cl->texture_offset,tsize);
|
||||
cl->xform_cache=xf * cl->xform;
|
||||
|
||||
|
||||
if (clip_rect.intersects_transformed(cl->xform_cache,cl->rect_cache)) {
|
||||
cl->filter_next_ptr=lights;
|
||||
lights=cl;
|
||||
cl->texture_cache=NULL;
|
||||
Matrix32 scale;
|
||||
scale.scale(cl->rect_cache.size);
|
||||
scale.elements[2]=cl->rect_cache.pos;
|
||||
cl->light_shader_xform = (cl->xform_cache * scale).affine_inverse();
|
||||
cl->light_shader_pos=cl->xform_cache[2];
|
||||
if (cl->shadow_buffer.is_valid()) {
|
||||
cl->shadows_next_ptr=lights_with_shadow;
|
||||
if (lights_with_shadow==NULL) {
|
||||
shadow_rect = cl->xform_cache.xform(cl->rect_cache);
|
||||
} else {
|
||||
shadow_rect=shadow_rect.merge( cl->xform_cache.xform(cl->rect_cache) );
|
||||
}
|
||||
lights_with_shadow=cl;
|
||||
cl->radius_cache=cl->rect_cache.size.length();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
canvas_map[ Viewport::CanvasKey( E->key(), E->get().layer) ]=&E->get();
|
||||
|
||||
}
|
||||
|
||||
if (lights_with_shadow) {
|
||||
//update shadows if any
|
||||
|
||||
Rasterizer::CanvasLightOccluderInstance * occluders=NULL;
|
||||
|
||||
//make list of occluders
|
||||
for (Map<RID,Viewport::CanvasData>::Element *E=p_viewport->canvas_map.front();E;E=E->next()) {
|
||||
|
||||
Matrix32 xf = p_viewport->global_transform * E->get().transform;
|
||||
|
||||
for(Set<Rasterizer::CanvasLightOccluderInstance*>::Element *F=E->get().canvas->occluders.front();F;F=F->next()) {
|
||||
|
||||
F->get()->xform_cache = xf * F->get()->xform;
|
||||
if (shadow_rect.intersects_transformed(F->get()->xform_cache,F->get()->aabb_cache)) {
|
||||
|
||||
F->get()->next=occluders;
|
||||
occluders=F->get();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
//update the light shadowmaps with them
|
||||
Rasterizer::CanvasLight *light=lights_with_shadow;
|
||||
while(light) {
|
||||
|
||||
rasterizer->canvas_light_shadow_buffer_update(light->shadow_buffer,light->xform_cache.affine_inverse(),light->item_mask,light->radius_cache/1000.0,light->radius_cache*1.1,occluders,&light->shadow_matrix_cache);
|
||||
light=light->shadows_next_ptr;
|
||||
}
|
||||
|
||||
rasterizer->set_viewport(viewport_rect); //must reset viewport afterwards
|
||||
}
|
||||
|
||||
for (Map<Viewport::CanvasKey,Viewport::CanvasData*>::Element *E=canvas_map.front();E;E=E->next()) {
|
||||
|
||||
|
||||
// print_line("canvas "+itos(i)+" size: "+itos(I->get()->canvas->child_items.size()));
|
||||
//print_line("GT "+p_viewport->global_transform+". CT: "+E->get()->transform);
|
||||
Matrix32 xform = p_viewport->global_transform * E->get()->transform;
|
||||
_render_canvas( E->get()->canvas,xform );
|
||||
|
||||
Rasterizer::CanvasLight *canvas_lights=NULL;
|
||||
|
||||
Rasterizer::CanvasLight *ptr=lights;
|
||||
while(ptr) {
|
||||
if (E->get()->layer>=ptr->layer_min && E->get()->layer<=ptr->layer_max) {
|
||||
ptr->next_ptr=canvas_lights;
|
||||
canvas_lights=ptr;
|
||||
}
|
||||
ptr=ptr->filter_next_ptr;
|
||||
}
|
||||
|
||||
_render_canvas( E->get()->canvas,xform,canvas_lights );
|
||||
i++;
|
||||
|
||||
}
|
||||
|
||||
rasterizer->canvas_debug_viewport_shadows(lights_with_shadow);
|
||||
}
|
||||
|
||||
//capture
|
||||
|
|
|
@ -371,7 +371,7 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
|
||||
|
||||
|
||||
mutable RID_Owner<Rasterizer::CanvasItemMaterial> canvas_item_material_owner;
|
||||
|
||||
struct CanvasItem : public Rasterizer::CanvasItem {
|
||||
|
||||
|
@ -384,7 +384,7 @@ class VisualServerRaster : public VisualServer {
|
|||
bool sort_y;
|
||||
float opacity;
|
||||
float self_opacity;
|
||||
bool use_parent_shader;
|
||||
bool use_parent_material;
|
||||
|
||||
|
||||
Vector<CanvasItem*> child_items;
|
||||
|
@ -396,7 +396,7 @@ class VisualServerRaster : public VisualServer {
|
|||
opacity=1;
|
||||
self_opacity=1;
|
||||
sort_y=false;
|
||||
use_parent_shader=false;
|
||||
use_parent_material=false;
|
||||
z_relative=true;
|
||||
}
|
||||
};
|
||||
|
@ -410,6 +410,26 @@ class VisualServerRaster : public VisualServer {
|
|||
}
|
||||
};
|
||||
|
||||
struct CanvasLightOccluder;
|
||||
|
||||
struct CanvasLightOccluderPolygon {
|
||||
|
||||
bool active;
|
||||
Rect2 aabb;
|
||||
CanvasOccluderPolygonCullMode cull_mode;
|
||||
RID occluder;
|
||||
Set<Rasterizer::CanvasLightOccluderInstance*> owners;
|
||||
|
||||
CanvasLightOccluderPolygon() { active=false; cull_mode=CANVAS_OCCLUDER_POLYGON_CULL_DISABLED; }
|
||||
};
|
||||
|
||||
|
||||
RID_Owner<CanvasLightOccluderPolygon> canvas_light_occluder_polygon_owner;
|
||||
|
||||
RID_Owner<Rasterizer::CanvasLightOccluderInstance> canvas_light_occluder_owner;
|
||||
|
||||
struct CanvasLight;
|
||||
|
||||
struct Canvas {
|
||||
|
||||
Set<RID> viewports;
|
||||
|
@ -419,8 +439,11 @@ class VisualServerRaster : public VisualServer {
|
|||
CanvasItem *item;
|
||||
};
|
||||
|
||||
Set<Rasterizer::CanvasLight*> lights;
|
||||
Set<Rasterizer::CanvasLightOccluderInstance*> occluders;
|
||||
|
||||
Vector<ChildItem> child_items;
|
||||
Color modulate;
|
||||
|
||||
int find_item(CanvasItem *p_item) {
|
||||
for(int i=0;i<child_items.size();i++) {
|
||||
|
@ -435,11 +458,13 @@ class VisualServerRaster : public VisualServer {
|
|||
child_items.remove(idx);
|
||||
}
|
||||
|
||||
Canvas() { }
|
||||
Canvas() { modulate=Color(1,1,1,1); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
RID_Owner<Rasterizer::CanvasLight> canvas_light_owner;
|
||||
|
||||
|
||||
struct Viewport {
|
||||
|
||||
|
@ -462,6 +487,8 @@ class VisualServerRaster : public VisualServer {
|
|||
bool transparent_bg;
|
||||
bool queue_capture;
|
||||
bool render_target_vflip;
|
||||
bool render_target_clear_on_new_frame;
|
||||
bool render_target_clear;
|
||||
Image capture;
|
||||
|
||||
bool rendered_in_prev_frame;
|
||||
|
@ -488,7 +515,7 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
SelfList<Viewport> update_list;
|
||||
|
||||
Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false;}
|
||||
Viewport() : update_list(this) { transparent_bg=false; render_target_update_mode=RENDER_TARGET_UPDATE_WHEN_VISIBLE; queue_capture=false; rendered_in_prev_frame=false; render_target_vflip=false; render_target_clear_on_new_frame=true; render_target_clear=true;}
|
||||
};
|
||||
|
||||
SelfList<Viewport>::List viewport_update_list;
|
||||
|
@ -601,9 +628,9 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
|
||||
static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect);
|
||||
void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect);
|
||||
void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner);
|
||||
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
|
||||
void _render_canvas_item_tree(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, const Color &p_modulate, Rasterizer::CanvasLight *p_lights);
|
||||
void _render_canvas_item(CanvasItem *p_canvas_item, const Matrix32& p_transform, const Rect2& p_clip_rect, float p_opacity, int p_z, Rasterizer::CanvasItem **z_list, Rasterizer::CanvasItem **z_last_list, CanvasItem *p_canvas_clip, CanvasItem *p_material_owner);
|
||||
void _render_canvas(Canvas *p_canvas, const Matrix32 &p_transform, Rasterizer::CanvasLight *p_lights);
|
||||
Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
|
||||
Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
|
||||
|
||||
|
@ -951,6 +978,9 @@ public:
|
|||
virtual RID viewport_get_render_target_texture(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable);
|
||||
virtual bool viewport_get_render_target_vflip(RID p_viewport) const;
|
||||
virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable);
|
||||
virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const;
|
||||
virtual void viewport_render_target_clear(RID p_viewport);
|
||||
virtual void viewport_set_render_target_to_screen_rect(RID p_viewport,const Rect2& p_rect);
|
||||
|
||||
virtual void viewport_queue_screen_capture(RID p_viewport);
|
||||
|
@ -1073,6 +1103,8 @@ public:
|
|||
virtual RID canvas_create();
|
||||
virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring);
|
||||
virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const;
|
||||
virtual void canvas_set_modulate(RID p_canvas,const Color& p_color);
|
||||
|
||||
|
||||
virtual RID canvas_item_create();
|
||||
|
||||
|
@ -1083,6 +1115,8 @@ public:
|
|||
virtual bool canvas_item_is_visible(RID p_item) const;
|
||||
|
||||
virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend);
|
||||
virtual void canvas_item_set_light_mask(RID p_canvas_item,int p_mask);
|
||||
|
||||
|
||||
|
||||
//virtual void canvas_item_set_rect(RID p_item, const Rect2& p_rect);
|
||||
|
@ -1102,8 +1136,8 @@ public:
|
|||
virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0);
|
||||
virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color);
|
||||
virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color);
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false);
|
||||
virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1));
|
||||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0);
|
||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID());
|
||||
|
@ -1116,15 +1150,8 @@ public:
|
|||
virtual void canvas_item_set_z(RID p_item, int p_z);
|
||||
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
|
||||
|
||||
virtual void canvas_item_set_shader(RID p_item, RID p_shader);
|
||||
virtual RID canvas_item_get_shader(RID p_item) const;
|
||||
|
||||
virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable);
|
||||
|
||||
|
||||
|
||||
virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value);
|
||||
virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const;
|
||||
virtual void canvas_item_set_material(RID p_item, RID p_material);
|
||||
virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable);
|
||||
|
||||
virtual RID canvas_light_create();
|
||||
virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas);
|
||||
|
@ -1135,33 +1162,42 @@ public:
|
|||
virtual void canvas_light_set_color(RID p_light, const Color& p_color);
|
||||
virtual void canvas_light_set_height(RID p_light, float p_height);
|
||||
virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z);
|
||||
virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer);
|
||||
virtual void canvas_light_set_item_mask(RID p_light, int p_mask);
|
||||
|
||||
enum CanvasightBlendMode {
|
||||
CANVAS_LIGHT_BLEND_ADD,
|
||||
CANVAS_LIGHT_BLEND_SUB,
|
||||
CANVAS_LIGHT_BLEND_MULTIPLY,
|
||||
CANVAS_LIGHT_BLEND_DODGE,
|
||||
CANVAS_LIGHT_BLEND_BURN,
|
||||
CANVAS_LIGHT_BLEND_LIGHTEN,
|
||||
CANVAS_LIGHT_BLEND_DARKEN,
|
||||
CANVAS_LIGHT_BLEND_OVERLAY,
|
||||
CANVAS_LIGHT_BLEND_SCREEN,
|
||||
};
|
||||
virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode);
|
||||
virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable);
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled);
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size);
|
||||
virtual void canvas_light_set_shadow_filter(RID p_light, int p_size);
|
||||
virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier);
|
||||
|
||||
|
||||
virtual RID canvas_light_occluder_create();
|
||||
virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas);
|
||||
virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled);
|
||||
virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape);
|
||||
virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon);
|
||||
virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform);
|
||||
virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask);
|
||||
|
||||
|
||||
virtual RID canvas_occluder_polygon_create();
|
||||
virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_close);
|
||||
virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape);
|
||||
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode);
|
||||
|
||||
|
||||
|
||||
virtual void canvas_item_clear(RID p_item);
|
||||
virtual void canvas_item_raise(RID p_item);
|
||||
|
||||
/* CANVAS ITEM MATERIAL */
|
||||
|
||||
virtual RID canvas_item_material_create();
|
||||
virtual void canvas_item_material_set_shader(RID p_material, RID p_shader);
|
||||
virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value);
|
||||
virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const;
|
||||
virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded);
|
||||
|
||||
|
||||
/* CURSOR */
|
||||
virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0); // radians
|
||||
virtual void cursor_set_texture(RID p_texture, const Point2 &p_center_offset, int p_cursor=0);
|
||||
|
|
|
@ -968,6 +968,10 @@ public:
|
|||
FUNC1RC(bool,viewport_get_render_target_vflip,RID);
|
||||
FUNC2(viewport_set_render_target_to_screen_rect,RID,const Rect2&);
|
||||
|
||||
FUNC2(viewport_set_render_target_clear_on_new_frame,RID,bool);
|
||||
FUNC1RC(bool,viewport_get_render_target_clear_on_new_frame,RID);
|
||||
FUNC1(viewport_render_target_clear,RID);
|
||||
|
||||
FUNC1(viewport_queue_screen_capture,RID);
|
||||
FUNC1RC(Image,viewport_get_screen_capture,RID);
|
||||
|
||||
|
@ -1087,6 +1091,8 @@ public:
|
|||
FUNC0R(RID,canvas_create);
|
||||
FUNC3(canvas_set_item_mirroring,RID,RID,const Point2&);
|
||||
FUNC2RC(Point2,canvas_get_item_mirroring,RID,RID);
|
||||
FUNC2(canvas_set_modulate,RID,const Color&);
|
||||
|
||||
|
||||
FUNC0R(RID,canvas_item_create);
|
||||
|
||||
|
@ -1097,7 +1103,7 @@ public:
|
|||
FUNC1RC(bool,canvas_item_is_visible,RID);
|
||||
|
||||
FUNC2(canvas_item_set_blend_mode,RID,MaterialBlendMode );
|
||||
|
||||
FUNC2(canvas_item_set_light_mask,RID,int );
|
||||
|
||||
//FUNC(canvas_item_set_rect,RID, const Rect2& p_rect);
|
||||
FUNC2(canvas_item_set_transform,RID, const Matrix32& );
|
||||
|
@ -1116,9 +1122,8 @@ public:
|
|||
FUNC5(canvas_item_add_line,RID, const Point2& , const Point2& ,const Color& ,float );
|
||||
FUNC3(canvas_item_add_rect,RID, const Rect2& , const Color& );
|
||||
FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& );
|
||||
FUNC5(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color& );
|
||||
FUNC5(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color& );
|
||||
|
||||
FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool );
|
||||
FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool );
|
||||
FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& );
|
||||
FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float );
|
||||
FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID );
|
||||
|
@ -1134,14 +1139,9 @@ public:
|
|||
FUNC2(canvas_item_set_z,RID,int);
|
||||
FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool);
|
||||
|
||||
FUNC2(canvas_item_set_shader,RID, RID );
|
||||
FUNC1RC(RID,canvas_item_get_shader,RID );
|
||||
FUNC2(canvas_item_set_material,RID, RID );
|
||||
|
||||
FUNC2(canvas_item_set_use_parent_shader,RID, bool );
|
||||
|
||||
|
||||
FUNC3(canvas_item_set_shader_param,RID,const StringName&,const Variant&);
|
||||
FUNC2RC(Variant,canvas_item_get_shader_param,RID,const StringName&);
|
||||
FUNC2(canvas_item_set_use_parent_material,RID, bool );
|
||||
|
||||
FUNC1(canvas_item_clear,RID);
|
||||
FUNC1(canvas_item_raise,RID);
|
||||
|
@ -1155,20 +1155,38 @@ public:
|
|||
FUNC2(canvas_light_set_texture_offset,RID,const Vector2&);
|
||||
FUNC2(canvas_light_set_color,RID,const Color&);
|
||||
FUNC2(canvas_light_set_height,RID,float);
|
||||
FUNC3(canvas_light_set_layer_range,RID,int,int);
|
||||
FUNC3(canvas_light_set_z_range,RID,int,int);
|
||||
FUNC2(canvas_light_set_item_mask,RID,int);
|
||||
|
||||
FUNC2(canvas_light_set_blend_mode,RID,CanvasLightBlendMode);
|
||||
FUNC2(canvas_light_set_subtract_mode,RID,bool);
|
||||
FUNC2(canvas_light_set_shadow_enabled,RID,bool);
|
||||
FUNC2(canvas_light_set_shadow_buffer_size,RID,int);
|
||||
FUNC2(canvas_light_set_shadow_filter,RID,int);
|
||||
FUNC2(canvas_light_set_shadow_esm_multiplier,RID,float);
|
||||
|
||||
|
||||
/* CANVAS OCCLUDER */
|
||||
|
||||
FUNC0R(RID,canvas_light_occluder_create);
|
||||
FUNC2(canvas_light_occluder_attach_to_canvas,RID,RID);
|
||||
FUNC2(canvas_light_occluder_set_enabled,RID,bool);
|
||||
FUNC2(canvas_light_occluder_set_shape,RID,const DVector<Vector2>&);
|
||||
FUNC2(canvas_light_occluder_set_polygon,RID,RID);
|
||||
FUNC2(canvas_light_occluder_set_transform,RID,const Matrix32&);
|
||||
FUNC2(canvas_light_occluder_set_light_mask,RID,int);
|
||||
|
||||
|
||||
FUNC0R(RID,canvas_occluder_polygon_create);
|
||||
FUNC3(canvas_occluder_polygon_set_shape,RID,const DVector<Vector2>&,bool);
|
||||
FUNC2(canvas_occluder_polygon_set_shape_as_lines,RID,const DVector<Vector2>&);
|
||||
FUNC2(canvas_occluder_polygon_set_cull_mode,RID,CanvasOccluderPolygonCullMode);
|
||||
|
||||
/* CANVAS MATERIAL */
|
||||
|
||||
FUNC0R(RID,canvas_item_material_create);
|
||||
FUNC2(canvas_item_material_set_shader,RID,RID);
|
||||
FUNC3(canvas_item_material_set_shader_param,RID,const StringName&,const Variant&);
|
||||
FUNC2RC(Variant,canvas_item_material_get_shader_param,RID,const StringName&);
|
||||
FUNC2(canvas_item_material_set_unshaded,RID,bool);
|
||||
|
||||
/* CURSOR */
|
||||
FUNC2(cursor_set_rotation,float , int ); // radians
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
/*************************************************************************/
|
||||
#include "visual_server.h"
|
||||
#include "globals.h"
|
||||
#include "method_bind_ext.inc"
|
||||
|
||||
VisualServer *VisualServer::singleton=NULL;
|
||||
VisualServer* (*VisualServer::create_func)()=NULL;
|
||||
|
@ -510,8 +511,9 @@ void VisualServer::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_line"),&VisualServer::canvas_item_add_line, DEFVAL(1.0));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_rect"),&VisualServer::canvas_item_add_rect);
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect"),&VisualServer::canvas_item_add_texture_rect, DEFVAL(Color(1,1,1)), DEFVAL(false));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_texture_rect_region"),&VisualServer::canvas_item_add_texture_rect_region, DEFVAL(Color(1,1,1)), DEFVAL(false));
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_style_box"),&VisualServer::_canvas_item_add_style_box, DEFVAL(Color(1,1,1)));
|
||||
// ObjectTypeDB::bind_method(_MD("canvas_item_add_primitive"),&VisualServer::canvas_item_add_primitive,DEFVAL(Vector<Vector2>()),DEFVAL(RID()));
|
||||
ObjectTypeDB::bind_method(_MD("canvas_item_add_circle"),&VisualServer::canvas_item_add_circle);
|
||||
|
|
|
@ -684,6 +684,9 @@ public:
|
|||
virtual RID viewport_get_render_target_texture(RID p_viewport) const=0;
|
||||
virtual void viewport_set_render_target_vflip(RID p_viewport,bool p_enable)=0;
|
||||
virtual bool viewport_get_render_target_vflip(RID p_viewport) const=0;
|
||||
virtual void viewport_set_render_target_clear_on_new_frame(RID p_viewport,bool p_enable)=0;
|
||||
virtual bool viewport_get_render_target_clear_on_new_frame(RID p_viewport) const=0;
|
||||
virtual void viewport_render_target_clear(RID p_viewport)=0;
|
||||
|
||||
virtual void viewport_queue_screen_capture(RID p_viewport)=0;
|
||||
virtual Image viewport_get_screen_capture(RID p_viewport) const=0;
|
||||
|
@ -944,6 +947,8 @@ public:
|
|||
virtual RID canvas_create()=0;
|
||||
virtual void canvas_set_item_mirroring(RID p_canvas,RID p_item,const Point2& p_mirroring)=0;
|
||||
virtual Point2 canvas_get_item_mirroring(RID p_canvas,RID p_item) const=0;
|
||||
virtual void canvas_set_modulate(RID p_canvas,const Color& p_color)=0;
|
||||
|
||||
|
||||
|
||||
virtual RID canvas_item_create()=0;
|
||||
|
@ -953,6 +958,8 @@ public:
|
|||
virtual void canvas_item_set_visible(RID p_item,bool p_visible)=0;
|
||||
virtual bool canvas_item_is_visible(RID p_item) const=0;
|
||||
|
||||
virtual void canvas_item_set_light_mask(RID p_item,int p_mask)=0;
|
||||
|
||||
virtual void canvas_item_set_blend_mode(RID p_canvas_item,MaterialBlendMode p_blend)=0;
|
||||
|
||||
virtual void canvas_item_attach_viewport(RID p_item, RID p_viewport)=0;
|
||||
|
@ -974,8 +981,8 @@ public:
|
|||
virtual void canvas_item_add_line(RID p_item, const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width=1.0)=0;
|
||||
virtual void canvas_item_add_rect(RID p_item, const Rect2& p_rect, const Color& p_color)=0;
|
||||
virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0;
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;
|
||||
virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0;
|
||||
virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0;
|
||||
virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0)=0;
|
||||
virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID())=0;
|
||||
|
@ -991,13 +998,9 @@ public:
|
|||
virtual void canvas_item_clear(RID p_item)=0;
|
||||
virtual void canvas_item_raise(RID p_item)=0;
|
||||
|
||||
virtual void canvas_item_set_shader(RID p_item, RID p_shader)=0;
|
||||
virtual RID canvas_item_get_shader(RID p_item) const=0;
|
||||
virtual void canvas_item_set_material(RID p_item, RID p_material)=0;
|
||||
|
||||
virtual void canvas_item_set_use_parent_shader(RID p_item, bool p_enable)=0;
|
||||
|
||||
virtual void canvas_item_set_shader_param(RID p_canvas_item, const StringName& p_param, const Variant& p_value)=0;
|
||||
virtual Variant canvas_item_get_shader_param(RID p_canvas_item, const StringName& p_param) const=0;
|
||||
virtual void canvas_item_set_use_parent_material(RID p_item, bool p_enable)=0;
|
||||
|
||||
virtual RID canvas_light_create()=0;
|
||||
virtual void canvas_light_attach_to_canvas(RID p_light,RID p_canvas)=0;
|
||||
|
@ -1008,29 +1011,40 @@ public:
|
|||
virtual void canvas_light_set_color(RID p_light, const Color& p_color)=0;
|
||||
virtual void canvas_light_set_height(RID p_light, float p_height)=0;
|
||||
virtual void canvas_light_set_z_range(RID p_light, int p_min_z,int p_max_z)=0;
|
||||
virtual void canvas_light_set_layer_range(RID p_light, int p_min_layer,int p_max_layer)=0;
|
||||
virtual void canvas_light_set_item_mask(RID p_light, int p_mask)=0;
|
||||
|
||||
enum CanvasLightBlendMode {
|
||||
CANVAS_LIGHT_BLEND_ADD,
|
||||
CANVAS_LIGHT_BLEND_SUB,
|
||||
CANVAS_LIGHT_BLEND_MULTIPLY,
|
||||
CANVAS_LIGHT_BLEND_DODGE,
|
||||
CANVAS_LIGHT_BLEND_BURN,
|
||||
CANVAS_LIGHT_BLEND_LIGHTEN,
|
||||
CANVAS_LIGHT_BLEND_DARKEN,
|
||||
CANVAS_LIGHT_BLEND_OVERLAY,
|
||||
CANVAS_LIGHT_BLEND_SCREEN,
|
||||
};
|
||||
virtual void canvas_light_set_blend_mode(RID p_light, CanvasLightBlendMode p_blend_mode)=0;
|
||||
virtual void canvas_light_set_subtract_mode(RID p_light, bool p_enable)=0;
|
||||
virtual void canvas_light_set_shadow_enabled(RID p_light, bool p_enabled)=0;
|
||||
virtual void canvas_light_set_shadow_buffer_size(RID p_light, int p_size)=0;
|
||||
virtual void canvas_light_set_shadow_filter(RID p_light, int p_size)=0;
|
||||
virtual void canvas_light_set_shadow_esm_multiplier(RID p_light, float p_multiplier)=0;
|
||||
|
||||
|
||||
|
||||
virtual RID canvas_light_occluder_create()=0;
|
||||
virtual void canvas_light_occluder_attach_to_canvas(RID p_occluder,RID p_canvas)=0;
|
||||
virtual void canvas_light_occluder_set_enabled(RID p_occluder,bool p_enabled)=0;
|
||||
virtual void canvas_light_occluder_set_shape(RID p_occluder,const DVector<Vector2>& p_shape)=0;
|
||||
virtual void canvas_light_occluder_set_polygon(RID p_occluder,RID p_polygon)=0;
|
||||
virtual void canvas_light_occluder_set_transform(RID p_occluder,const Matrix32& p_xform)=0;
|
||||
virtual void canvas_light_occluder_set_light_mask(RID p_occluder,int p_mask)=0;
|
||||
|
||||
virtual RID canvas_occluder_polygon_create()=0;
|
||||
virtual void canvas_occluder_polygon_set_shape(RID p_occluder_polygon,const DVector<Vector2>& p_shape,bool p_closed)=0;
|
||||
virtual void canvas_occluder_polygon_set_shape_as_lines(RID p_occluder_polygon,const DVector<Vector2>& p_shape)=0;
|
||||
enum CanvasOccluderPolygonCullMode {
|
||||
CANVAS_OCCLUDER_POLYGON_CULL_DISABLED,
|
||||
CANVAS_OCCLUDER_POLYGON_CULL_CLOCKWISE,
|
||||
CANVAS_OCCLUDER_POLYGON_CULL_COUNTER_CLOCKWISE,
|
||||
};
|
||||
virtual void canvas_occluder_polygon_set_cull_mode(RID p_occluder_polygon,CanvasOccluderPolygonCullMode p_mode)=0;
|
||||
|
||||
/* CANVAS ITEM MATERIAL */
|
||||
|
||||
virtual RID canvas_item_material_create()=0;
|
||||
virtual void canvas_item_material_set_shader(RID p_material, RID p_shader)=0;
|
||||
virtual void canvas_item_material_set_shader_param(RID p_material, const StringName& p_param, const Variant& p_value)=0;
|
||||
virtual Variant canvas_item_material_get_shader_param(RID p_material, const StringName& p_param) const=0;
|
||||
virtual void canvas_item_material_set_unshaded(RID p_material, bool p_unshaded)=0;
|
||||
|
||||
/* CURSOR */
|
||||
virtual void cursor_set_rotation(float p_rotation, int p_cursor = 0)=0; // radians
|
||||
|
|
|
@ -817,7 +817,7 @@ void Collada::_parse_camera(XMLParser& parser) {
|
|||
if (name=="perspective") {
|
||||
|
||||
camera.mode=CameraData::MODE_PERSPECTIVE;
|
||||
} else if (name=="orthogonal") {
|
||||
} else if (name=="orthographic") {
|
||||
|
||||
camera.mode=CameraData::MODE_ORTHOGONAL;
|
||||
} else if (name=="xfov") {
|
||||
|
|
|
@ -337,6 +337,24 @@ public:
|
|||
if(normal==p_vert.normal) {
|
||||
if(uv==p_vert.uv) {
|
||||
if(uv2==p_vert.uv2) {
|
||||
|
||||
if (!weights.empty() || !p_vert.weights.empty()) {
|
||||
|
||||
if (weights.size()==p_vert.weights.size()) {
|
||||
|
||||
for(int i=0;i<weights.size();i++) {
|
||||
if (weights[i].bone_idx!=p_vert.weights[i].bone_idx)
|
||||
return weights[i].bone_idx<p_vert.weights[i].bone_idx;
|
||||
|
||||
if (weights[i].weight!=p_vert.weights[i].weight)
|
||||
return weights[i].weight<p_vert.weights[i].weight;
|
||||
}
|
||||
} else {
|
||||
return weights.size() < p_vert.weights.size();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return (color<p_vert.color);
|
||||
} else
|
||||
return (uv2<p_vert.uv2);
|
||||
|
|
|
@ -904,6 +904,16 @@ Error EditorExportPlatform::export_project_files(EditorExportSaveFunction p_func
|
|||
return OK;
|
||||
}
|
||||
|
||||
static int _get_pad(int p_alignment, int p_n) {
|
||||
|
||||
int rest = p_n % p_alignment;
|
||||
int pad = 0;
|
||||
if (rest > 0) {
|
||||
pad = p_alignment - rest;
|
||||
};
|
||||
|
||||
return pad;
|
||||
};
|
||||
|
||||
Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path, const Vector<uint8_t>& p_data,int p_file,int p_total) {
|
||||
|
||||
|
@ -930,11 +940,19 @@ Error EditorExportPlatform::save_pack_file(void *p_userdata,const String& p_path
|
|||
pd->ep->step("Storing File: "+p_path,2+p_file*100/p_total);
|
||||
pd->count++;
|
||||
pd->ftmp->store_buffer(p_data.ptr(),p_data.size());
|
||||
if (pd->alignment > 1) {
|
||||
|
||||
int pad = _get_pad(pd->alignment, pd->ftmp->get_pos());
|
||||
for (int i=0; i<pad; i++) {
|
||||
|
||||
pd->ftmp->store_8(0);
|
||||
};
|
||||
};
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) {
|
||||
Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles, int p_alignment) {
|
||||
|
||||
EditorProgress ep("savepack","Packing",102);
|
||||
|
||||
|
@ -952,7 +970,6 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) {
|
|||
dst->store_32(0);
|
||||
}
|
||||
|
||||
|
||||
size_t fcountpos = dst->get_pos();
|
||||
dst->store_32(0);
|
||||
|
||||
|
@ -961,11 +978,20 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) {
|
|||
pd.f=dst;
|
||||
pd.ftmp=tmp;
|
||||
pd.count=0;
|
||||
pd.alignment = p_alignment;
|
||||
Error err = export_project_files(save_pack_file,&pd,p_make_bundles);
|
||||
memdelete(tmp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (p_alignment > 1) {
|
||||
int pad = _get_pad(p_alignment, dst->get_pos());
|
||||
for (int i=0; i<pad; i++) {
|
||||
|
||||
dst->store_8(0);
|
||||
};
|
||||
};
|
||||
|
||||
size_t ofsplus = dst->get_pos();
|
||||
//append file
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@ protected:
|
|||
Vector<TempData> file_ofs;
|
||||
EditorProgress *ep;
|
||||
int count;
|
||||
int alignment;
|
||||
|
||||
};
|
||||
|
||||
|
@ -121,7 +122,7 @@ public:
|
|||
|
||||
Error export_project_files(EditorExportSaveFunction p_func, void* p_udata,bool p_make_bundles);
|
||||
|
||||
Error save_pack(FileAccess *p_where, bool p_make_bundles=false);
|
||||
Error save_pack(FileAccess *p_where, bool p_make_bundles=false, int p_alignment = 1);
|
||||
virtual String get_name() const =0;
|
||||
virtual ImageCompression get_image_compression() const=0;
|
||||
virtual Ref<Texture> get_logo() const =0;
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
#include "plugins/baked_light_editor_plugin.h"
|
||||
#include "plugins/polygon_2d_editor_plugin.h"
|
||||
#include "plugins/navigation_polygon_editor_plugin.h"
|
||||
#include "plugins/light_occluder_2d_editor_plugin.h"
|
||||
// end
|
||||
#include "tools/editor/io_plugins/editor_texture_import_plugin.h"
|
||||
#include "tools/editor/io_plugins/editor_scene_import_plugin.h"
|
||||
|
@ -4115,6 +4116,7 @@ EditorNode::EditorNode() {
|
|||
add_editor_plugin( memnew( PathEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( BakedLightEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
|
||||
add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
|
||||
|
||||
for(int i=0;i<EditorPlugins::get_plugin_count();i++)
|
||||
|
|
After Width: | Height: | Size: 835 B |
After Width: | Height: | Size: 441 B |
After Width: | Height: | Size: 342 B |
After Width: | Height: | Size: 516 B |
After Width: | Height: | Size: 581 B |
After Width: | Height: | Size: 207 B |
After Width: | Height: | Size: 303 B |
After Width: | Height: | Size: 343 B |
After Width: | Height: | Size: 256 B |
After Width: | Height: | Size: 244 B |
|
@ -285,13 +285,16 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
|
|||
|
||||
case Collada::CameraData::MODE_ORTHOGONAL: {
|
||||
|
||||
if (cd.orthogonal.x_mag) {
|
||||
if (cd.orthogonal.y_mag) {
|
||||
|
||||
camera->set_orthogonal(cd.orthogonal.x_mag,cd.z_near,cd.z_far);
|
||||
camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT);
|
||||
camera->set_orthogonal(cd.orthogonal.y_mag*2.0 ,cd.z_near,cd.z_far);
|
||||
|
||||
} else if (!cd.orthogonal.x_mag && cd.orthogonal.y_mag) {
|
||||
} else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) {
|
||||
|
||||
camera->set_orthogonal(cd.orthogonal.y_mag * cd.aspect,cd.z_near,cd.z_far);
|
||||
|
||||
camera->set_keep_aspect_mode(Camera::KEEP_WIDTH);
|
||||
camera->set_orthogonal(cd.orthogonal.x_mag*2.0,cd.z_near,cd.z_far);
|
||||
}
|
||||
|
||||
} break;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "os/file_access.h"
|
||||
#include "tools/editor/editor_settings.h"
|
||||
|
||||
|
||||
void CollisionPolygon2DEditor::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
|
|
|
@ -0,0 +1,500 @@
|
|||
#include "light_occluder_2d_editor_plugin.h"
|
||||
|
||||
#include "canvas_item_editor_plugin.h"
|
||||
#include "os/file_access.h"
|
||||
#include "tools/editor/editor_settings.h"
|
||||
|
||||
void LightOccluder2DEditor::_notification(int p_what) {
|
||||
|
||||
switch(p_what) {
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
|
||||
button_create->set_icon( get_icon("Edit","EditorIcons"));
|
||||
button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
|
||||
button_edit->set_pressed(true);
|
||||
get_tree()->connect("node_removed",this,"_node_removed");
|
||||
create_poly->connect("confirmed",this,"_create_poly");
|
||||
|
||||
} break;
|
||||
case NOTIFICATION_FIXED_PROCESS: {
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
}
|
||||
void LightOccluder2DEditor::_node_removed(Node *p_node) {
|
||||
|
||||
if(p_node==node) {
|
||||
node=NULL;
|
||||
hide();
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Vector2 LightOccluder2DEditor::snap_point(const Vector2& p_point) const {
|
||||
|
||||
if (canvas_item_editor->is_snap_active()) {
|
||||
|
||||
return p_point.snapped(Vector2(1,1)*canvas_item_editor->get_snap());
|
||||
|
||||
} else {
|
||||
return p_point;
|
||||
}
|
||||
}
|
||||
|
||||
void LightOccluder2DEditor::_menu_option(int p_option) {
|
||||
|
||||
switch(p_option) {
|
||||
|
||||
case MODE_CREATE: {
|
||||
|
||||
mode=MODE_CREATE;
|
||||
button_create->set_pressed(true);
|
||||
button_edit->set_pressed(false);
|
||||
} break;
|
||||
case MODE_EDIT: {
|
||||
|
||||
mode=MODE_EDIT;
|
||||
button_create->set_pressed(false);
|
||||
button_edit->set_pressed(true);
|
||||
} break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LightOccluder2DEditor::_wip_close(bool p_closed) {
|
||||
|
||||
undo_redo->create_action("Create Poly");
|
||||
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",node->get_occluder_polygon()->get_polygon());
|
||||
undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",wip);
|
||||
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_closed",node->get_occluder_polygon()->is_closed());
|
||||
undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_closed",p_closed);
|
||||
|
||||
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->commit_action();
|
||||
wip.clear();
|
||||
wip_active=false;
|
||||
mode=MODE_EDIT;
|
||||
button_edit->set_pressed(true);
|
||||
button_create->set_pressed(false);
|
||||
edited_point=-1;
|
||||
}
|
||||
|
||||
bool LightOccluder2DEditor::forward_input_event(const InputEvent& p_event) {
|
||||
|
||||
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
if (node->get_occluder_polygon().is_null()) {
|
||||
if (p_event.type==InputEvent::MOUSE_BUTTON && p_event.mouse_button.button_index==1 && p_event.mouse_button.pressed) {
|
||||
create_poly->set_text("No OccluderPolygon2D resource on this node.\nCreate and assign one?");
|
||||
create_poly->popup_centered_minsize();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
switch(p_event.type) {
|
||||
|
||||
case InputEvent::MOUSE_BUTTON: {
|
||||
|
||||
const InputEventMouseButton &mb=p_event.mouse_button;
|
||||
|
||||
Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||
|
||||
|
||||
Vector2 gpoint = Point2(mb.x,mb.y);
|
||||
Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
|
||||
cpoint=snap_point(cpoint);
|
||||
cpoint = node->get_global_transform().affine_inverse().xform(cpoint);
|
||||
|
||||
Vector<Vector2> poly = Variant(node->get_occluder_polygon()->get_polygon());
|
||||
|
||||
//first check if a point is to be added (segment split)
|
||||
real_t grab_treshold=EDITOR_DEF("poly_editor/point_grab_radius",8);
|
||||
|
||||
switch(mode) {
|
||||
|
||||
|
||||
case MODE_CREATE: {
|
||||
|
||||
if (mb.button_index==BUTTON_LEFT && mb.pressed) {
|
||||
|
||||
|
||||
if (!wip_active) {
|
||||
|
||||
wip.clear();
|
||||
wip.push_back( cpoint );
|
||||
wip_active=true;
|
||||
edited_point_pos=cpoint;
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
edited_point=1;
|
||||
return true;
|
||||
} else {
|
||||
|
||||
|
||||
if (wip.size()>1 && xform.xform(wip[0]).distance_to(gpoint)<grab_treshold) {
|
||||
//wip closed
|
||||
_wip_close(true);
|
||||
|
||||
return true;
|
||||
} else if (wip.size()>1 && xform.xform(wip[wip.size()-1]).distance_to(gpoint)<grab_treshold) {
|
||||
//wip closed
|
||||
_wip_close(false);
|
||||
return true;
|
||||
|
||||
} else {
|
||||
|
||||
wip.push_back( cpoint );
|
||||
edited_point=wip.size();
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
return true;
|
||||
|
||||
//add wip point
|
||||
}
|
||||
}
|
||||
} else if (mb.button_index==BUTTON_RIGHT && mb.pressed && wip_active) {
|
||||
_wip_close(true);
|
||||
}
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
|
||||
case MODE_EDIT: {
|
||||
|
||||
if (mb.button_index==BUTTON_LEFT) {
|
||||
if (mb.pressed) {
|
||||
|
||||
if (mb.mod.control) {
|
||||
|
||||
|
||||
if (poly.size() < 3) {
|
||||
|
||||
undo_redo->create_action("Edit Poly");
|
||||
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly);
|
||||
poly.push_back(cpoint);
|
||||
undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly);
|
||||
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->commit_action();
|
||||
return true;
|
||||
}
|
||||
|
||||
//search edges
|
||||
int closest_idx=-1;
|
||||
Vector2 closest_pos;
|
||||
real_t closest_dist=1e10;
|
||||
for(int i=0;i<poly.size();i++) {
|
||||
|
||||
Vector2 points[2] ={ xform.xform(poly[i]),
|
||||
xform.xform(poly[(i+1)%poly.size()]) };
|
||||
|
||||
Vector2 cp = Geometry::get_closest_point_to_segment_2d(gpoint,points);
|
||||
if (cp.distance_squared_to(points[0])<CMP_EPSILON2 || cp.distance_squared_to(points[1])<CMP_EPSILON2)
|
||||
continue; //not valid to reuse point
|
||||
|
||||
real_t d = cp.distance_to(gpoint);
|
||||
if (d<closest_dist && d<grab_treshold) {
|
||||
closest_dist=d;
|
||||
closest_pos=cp;
|
||||
closest_idx=i;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (closest_idx>=0) {
|
||||
|
||||
pre_move_edit=poly;
|
||||
poly.insert(closest_idx+1,xform.affine_inverse().xform(closest_pos));
|
||||
edited_point=closest_idx+1;
|
||||
edited_point_pos=xform.affine_inverse().xform(closest_pos);
|
||||
node->get_occluder_polygon()->set_polygon(Variant(poly));
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
||||
//look for points to move
|
||||
|
||||
int closest_idx=-1;
|
||||
Vector2 closest_pos;
|
||||
real_t closest_dist=1e10;
|
||||
for(int i=0;i<poly.size();i++) {
|
||||
|
||||
Vector2 cp =xform.xform(poly[i]);
|
||||
|
||||
real_t d = cp.distance_to(gpoint);
|
||||
if (d<closest_dist && d<grab_treshold) {
|
||||
closest_dist=d;
|
||||
closest_pos=cp;
|
||||
closest_idx=i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (closest_idx>=0) {
|
||||
|
||||
pre_move_edit=poly;
|
||||
edited_point=closest_idx;
|
||||
edited_point_pos=xform.affine_inverse().xform(closest_pos);
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
if (edited_point!=-1) {
|
||||
|
||||
//apply
|
||||
|
||||
ERR_FAIL_INDEX_V(edited_point,poly.size(),false);
|
||||
poly[edited_point]=edited_point_pos;
|
||||
undo_redo->create_action("Edit Poly");
|
||||
undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly);
|
||||
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",pre_move_edit);
|
||||
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->commit_action();
|
||||
|
||||
edited_point=-1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} if (mb.button_index==BUTTON_RIGHT && mb.pressed && edited_point==-1) {
|
||||
|
||||
|
||||
|
||||
int closest_idx=-1;
|
||||
Vector2 closest_pos;
|
||||
real_t closest_dist=1e10;
|
||||
for(int i=0;i<poly.size();i++) {
|
||||
|
||||
Vector2 cp =xform.xform(poly[i]);
|
||||
|
||||
real_t d = cp.distance_to(gpoint);
|
||||
if (d<closest_dist && d<grab_treshold) {
|
||||
closest_dist=d;
|
||||
closest_pos=cp;
|
||||
closest_idx=i;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (closest_idx>=0) {
|
||||
|
||||
|
||||
undo_redo->create_action("Edit Poly (Remove Point)");
|
||||
undo_redo->add_undo_method(node->get_occluder_polygon().ptr(),"set_polygon",poly);
|
||||
poly.remove(closest_idx);
|
||||
undo_redo->add_do_method(node->get_occluder_polygon().ptr(),"set_polygon",poly);
|
||||
undo_redo->add_do_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->add_undo_method(canvas_item_editor->get_viewport_control(),"update");
|
||||
undo_redo->commit_action();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
} break;
|
||||
case InputEvent::MOUSE_MOTION: {
|
||||
|
||||
const InputEventMouseMotion &mm=p_event.mouse_motion;
|
||||
|
||||
if (edited_point!=-1 && (wip_active || mm.button_mask&BUTTON_MASK_LEFT)) {
|
||||
|
||||
Vector2 gpoint = Point2(mm.x,mm.y);
|
||||
Vector2 cpoint = canvas_item_editor->get_canvas_transform().affine_inverse().xform(gpoint);
|
||||
cpoint=snap_point(cpoint);
|
||||
edited_point_pos = node->get_global_transform().affine_inverse().xform(cpoint);
|
||||
|
||||
canvas_item_editor->get_viewport_control()->update();
|
||||
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
void LightOccluder2DEditor::_canvas_draw() {
|
||||
|
||||
if (!node || !node->get_occluder_polygon().is_valid())
|
||||
return;
|
||||
|
||||
Control *vpc = canvas_item_editor->get_viewport_control();
|
||||
|
||||
Vector<Vector2> poly;
|
||||
|
||||
if (wip_active)
|
||||
poly=wip;
|
||||
else
|
||||
poly=Variant(node->get_occluder_polygon()->get_polygon());
|
||||
|
||||
|
||||
Matrix32 xform = canvas_item_editor->get_canvas_transform() * node->get_global_transform();
|
||||
Ref<Texture> handle= get_icon("EditorHandle","EditorIcons");
|
||||
|
||||
int len = poly.size();
|
||||
|
||||
for(int i=0;i<poly.size();i++) {
|
||||
|
||||
|
||||
Vector2 p,p2;
|
||||
p = i==edited_point ? edited_point_pos : poly[i];
|
||||
if ((wip_active && i==poly.size()-1) || (((i+1)%poly.size())==edited_point))
|
||||
p2=edited_point_pos;
|
||||
else
|
||||
p2 = poly[(i+1)%poly.size()];
|
||||
|
||||
Vector2 point = xform.xform(p);
|
||||
Vector2 next_point = xform.xform(p2);
|
||||
|
||||
Color col=Color(1,0.3,0.1,0.8);
|
||||
|
||||
if (i==poly.size()-1 && (!node->get_occluder_polygon()->is_closed() || wip_active)) {
|
||||
|
||||
} else {
|
||||
vpc->draw_line(point,next_point,col,2);
|
||||
}
|
||||
vpc->draw_texture(handle,point-handle->get_size()*0.5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void LightOccluder2DEditor::edit(Node *p_collision_polygon) {
|
||||
|
||||
if (!canvas_item_editor) {
|
||||
canvas_item_editor=CanvasItemEditor::get_singleton();
|
||||
}
|
||||
|
||||
if (p_collision_polygon) {
|
||||
|
||||
node=p_collision_polygon->cast_to<LightOccluder2D>();
|
||||
if (!canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
|
||||
canvas_item_editor->get_viewport_control()->connect("draw",this,"_canvas_draw");
|
||||
wip.clear();
|
||||
wip_active=false;
|
||||
edited_point=-1;
|
||||
|
||||
} else {
|
||||
node=NULL;
|
||||
|
||||
if (canvas_item_editor->get_viewport_control()->is_connected("draw",this,"_canvas_draw"))
|
||||
canvas_item_editor->get_viewport_control()->disconnect("draw",this,"_canvas_draw");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void LightOccluder2DEditor::_create_poly() {
|
||||
|
||||
undo_redo->create_action("Create Occluder Polygon");
|
||||
undo_redo->add_do_method(node,"set_occluder_polygon",Ref<OccluderPolygon2D>(memnew( OccluderPolygon2D)));
|
||||
undo_redo->add_undo_method(node,"set_occluder_polygon",Variant(REF()));
|
||||
undo_redo->commit_action();
|
||||
}
|
||||
|
||||
void LightOccluder2DEditor::_bind_methods() {
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("_menu_option"),&LightOccluder2DEditor::_menu_option);
|
||||
ObjectTypeDB::bind_method(_MD("_canvas_draw"),&LightOccluder2DEditor::_canvas_draw);
|
||||
ObjectTypeDB::bind_method(_MD("_node_removed"),&LightOccluder2DEditor::_node_removed);
|
||||
ObjectTypeDB::bind_method(_MD("_create_poly"),&LightOccluder2DEditor::_create_poly);
|
||||
|
||||
}
|
||||
|
||||
|
||||
LightOccluder2DEditor::LightOccluder2DEditor(EditorNode *p_editor) {
|
||||
|
||||
canvas_item_editor=NULL;
|
||||
editor=p_editor;
|
||||
undo_redo = editor->get_undo_redo();
|
||||
|
||||
add_child( memnew( VSeparator ));
|
||||
button_create = memnew( ToolButton );
|
||||
add_child(button_create);
|
||||
button_create->connect("pressed",this,"_menu_option",varray(MODE_CREATE));
|
||||
button_create->set_toggle_mode(true);
|
||||
button_create->set_tooltip("Create a new polygon from scratch");
|
||||
|
||||
button_edit = memnew( ToolButton );
|
||||
add_child(button_edit);
|
||||
button_edit->connect("pressed",this,"_menu_option",varray(MODE_EDIT));
|
||||
button_edit->set_toggle_mode(true);
|
||||
button_edit->set_tooltip("Edit existing polygon:\nLMB: Move Point.\nCtrl+LMB: Split Segment.\nRMB: Erase Point.");
|
||||
|
||||
create_poly = memnew( ConfirmationDialog );
|
||||
add_child(create_poly);
|
||||
create_poly->get_ok()->set_text("Create");
|
||||
|
||||
|
||||
//add_constant_override("separation",0);
|
||||
|
||||
#if 0
|
||||
options = memnew( MenuButton );
|
||||
add_child(options);
|
||||
options->set_area_as_parent_rect();
|
||||
options->set_text("Polygon");
|
||||
//options->get_popup()->add_item("Parse BBCODE",PARSE_BBCODE);
|
||||
options->get_popup()->connect("item_pressed", this,"_menu_option");
|
||||
#endif
|
||||
|
||||
mode = MODE_EDIT;
|
||||
wip_active=false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
void LightOccluder2DEditorPlugin::edit(Object *p_object) {
|
||||
|
||||
collision_polygon_editor->edit(p_object->cast_to<Node>());
|
||||
}
|
||||
|
||||
bool LightOccluder2DEditorPlugin::handles(Object *p_object) const {
|
||||
|
||||
return p_object->is_type("LightOccluder2D");
|
||||
}
|
||||
|
||||
void LightOccluder2DEditorPlugin::make_visible(bool p_visible) {
|
||||
|
||||
if (p_visible) {
|
||||
collision_polygon_editor->show();
|
||||
} else {
|
||||
|
||||
collision_polygon_editor->hide();
|
||||
collision_polygon_editor->edit(NULL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LightOccluder2DEditorPlugin::LightOccluder2DEditorPlugin(EditorNode *p_node) {
|
||||
|
||||
editor=p_node;
|
||||
collision_polygon_editor = memnew( LightOccluder2DEditor(p_node) );
|
||||
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(collision_polygon_editor);
|
||||
|
||||
collision_polygon_editor->hide();
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
LightOccluder2DEditorPlugin::~LightOccluder2DEditorPlugin()
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
#ifndef LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H
|
||||
#define LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H
|
||||
|
||||
|
||||
|
||||
#include "tools/editor/editor_plugin.h"
|
||||
#include "tools/editor/editor_node.h"
|
||||
#include "scene/2d/light_occluder_2d.h"
|
||||
#include "scene/gui/tool_button.h"
|
||||
#include "scene/gui/button_group.h"
|
||||
|
||||
/**
|
||||
@author Juan Linietsky <reduzio@gmail.com>
|
||||
*/
|
||||
class CanvasItemEditor;
|
||||
|
||||
class LightOccluder2DEditor : public HBoxContainer {
|
||||
|
||||
OBJ_TYPE(LightOccluder2DEditor, HBoxContainer );
|
||||
|
||||
UndoRedo *undo_redo;
|
||||
enum Mode {
|
||||
|
||||
MODE_CREATE,
|
||||
MODE_EDIT,
|
||||
|
||||
};
|
||||
|
||||
Mode mode;
|
||||
|
||||
ToolButton *button_create;
|
||||
ToolButton *button_edit;
|
||||
|
||||
CanvasItemEditor *canvas_item_editor;
|
||||
EditorNode *editor;
|
||||
Panel *panel;
|
||||
LightOccluder2D *node;
|
||||
MenuButton *options;
|
||||
|
||||
int edited_point;
|
||||
Vector2 edited_point_pos;
|
||||
Vector<Vector2> pre_move_edit;
|
||||
Vector<Vector2> wip;
|
||||
bool wip_active;
|
||||
|
||||
ConfirmationDialog *create_poly;
|
||||
|
||||
void _wip_close(bool p_closed);
|
||||
void _canvas_draw();
|
||||
void _menu_option(int p_option);
|
||||
void _create_poly();
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
void _node_removed(Node *p_node);
|
||||
static void _bind_methods();
|
||||
public:
|
||||
|
||||
Vector2 snap_point(const Vector2& p_point) const;
|
||||
bool forward_input_event(const InputEvent& p_event);
|
||||
void edit(Node *p_collision_polygon);
|
||||
LightOccluder2DEditor(EditorNode *p_editor);
|
||||
};
|
||||
|
||||
class LightOccluder2DEditorPlugin : public EditorPlugin {
|
||||
|
||||
OBJ_TYPE( LightOccluder2DEditorPlugin, EditorPlugin );
|
||||
|
||||
LightOccluder2DEditor *collision_polygon_editor;
|
||||
EditorNode *editor;
|
||||
|
||||
public:
|
||||
|
||||
virtual bool forward_input_event(const InputEvent& p_event) { return collision_polygon_editor->forward_input_event(p_event); }
|
||||
|
||||
virtual String get_name() const { return "LightOccluder2D"; }
|
||||
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);
|
||||
|
||||
LightOccluder2DEditorPlugin(EditorNode *p_node);
|
||||
~LightOccluder2DEditorPlugin();
|
||||
|
||||
};
|
||||
|
||||
#endif // LIGHT_OCCLUDER_2D_EDITOR_PLUGIN_H
|
|
@ -34,7 +34,7 @@
|
|||
#include "os/file_access.h"
|
||||
#include "tools/editor/editor_settings.h"
|
||||
#include "os/input.h"
|
||||
|
||||
#include "method_bind_ext.inc"
|
||||
|
||||
void TileMapEditor::_notification(int p_what) {
|
||||
|
||||
|
@ -42,8 +42,13 @@ void TileMapEditor::_notification(int p_what) {
|
|||
|
||||
case NOTIFICATION_READY: {
|
||||
|
||||
transpose->set_icon( get_icon("Transpose","EditorIcons"));
|
||||
mirror_x->set_icon( get_icon("MirrorX","EditorIcons"));
|
||||
mirror_y->set_icon( get_icon("MirrorY","EditorIcons"));
|
||||
rotate_0->set_icon( get_icon("Rotate0","EditorIcons"));
|
||||
rotate_90->set_icon( get_icon("Rotate90","EditorIcons"));
|
||||
rotate_180->set_icon( get_icon("Rotate180","EditorIcons"));
|
||||
rotate_270->set_icon( get_icon("Rotate270","EditorIcons"));
|
||||
|
||||
} break;
|
||||
}
|
||||
|
@ -85,24 +90,31 @@ void TileMapEditor::set_selected_tile(int p_tile) {
|
|||
}
|
||||
}
|
||||
|
||||
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v,bool p_with_undo) {
|
||||
// Wrapper to workaround five arg limit of undo/redo methods
|
||||
void TileMapEditor::_set_cell_shortened(const Point2& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose) {
|
||||
ERR_FAIL_COND(!node);
|
||||
node->set_cell(floor(p_pos.x), floor(p_pos.y), p_value, p_flip_h, p_flip_v, p_transpose);
|
||||
}
|
||||
|
||||
void TileMapEditor::_set_cell(const Point2i& p_pos,int p_value,bool p_flip_h, bool p_flip_v, bool p_transpose,bool p_with_undo) {
|
||||
|
||||
ERR_FAIL_COND(!node);
|
||||
|
||||
bool prev_flip_h=node->is_cell_x_flipped(p_pos.x,p_pos.y);
|
||||
bool prev_flip_v=node->is_cell_y_flipped(p_pos.x,p_pos.y);
|
||||
bool prev_transpose=node->is_cell_transposed(p_pos.x,p_pos.y);
|
||||
int prev_val=node->get_cell(p_pos.x,p_pos.y);
|
||||
|
||||
if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v)
|
||||
if (p_value==prev_val && p_flip_h==prev_flip_h && p_flip_v==prev_flip_v && p_transpose==prev_transpose)
|
||||
return; //check that it's actually different
|
||||
|
||||
|
||||
if (p_with_undo) {
|
||||
undo_redo->add_do_method(node,"set_cell",p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v);
|
||||
undo_redo->add_undo_method(node,"set_cell",p_pos.x,p_pos.y,prev_val,prev_flip_h,prev_flip_v);
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p_pos),p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p_pos),prev_val,prev_flip_h,prev_flip_v,prev_transpose);
|
||||
} else {
|
||||
|
||||
node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v);
|
||||
node->set_cell(p_pos.x,p_pos.y,p_value,p_flip_h,p_flip_v,p_transpose);
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,6 +180,7 @@ struct _TileMapEditorCopyData {
|
|||
int cell;
|
||||
bool flip_h;
|
||||
bool flip_v;
|
||||
bool transpose;
|
||||
};
|
||||
|
||||
bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
||||
|
@ -204,6 +217,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
tcd.cell=node->get_cell(j,i);
|
||||
tcd.flip_h=node->is_cell_x_flipped(j,i);
|
||||
tcd.flip_v=node->is_cell_y_flipped(j,i);
|
||||
tcd.transpose=node->is_cell_transposed(j,i);
|
||||
dupdata.push_back(tcd);
|
||||
|
||||
|
||||
|
@ -214,7 +228,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for (List<_TileMapEditorCopyData>::Element *E=dupdata.front();E;E=E->next()) {
|
||||
|
||||
|
||||
_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,true);
|
||||
_set_cell(E->get().pos+ofs,E->get().cell,E->get().flip_h,E->get().flip_v,E->get().transpose,true);
|
||||
}
|
||||
undo_redo->commit_action();
|
||||
|
||||
|
@ -239,6 +253,10 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
} else if (mb.mod.control) {
|
||||
tool=TOOL_PICKING;
|
||||
set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
|
||||
mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
|
||||
mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
|
||||
transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
|
||||
_update_transform_buttons();
|
||||
canvas_item_editor->update();
|
||||
return true;
|
||||
} else {
|
||||
|
@ -248,7 +266,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y))));
|
||||
paint_undo.clear();
|
||||
paint_undo[local]=_get_op_from_cell(local);
|
||||
node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -263,8 +281,8 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y));
|
||||
undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf);
|
||||
undo_redo->add_do_method(this,"_set_cell_shortened",Point2(p),node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
@ -289,7 +307,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y)));
|
||||
paint_undo.clear();
|
||||
paint_undo[local]=_get_op_from_cell(local);
|
||||
//node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
//node->set_cell(local.x,local.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
//return true;
|
||||
_set_cell(local,TileMap::INVALID_CELL);
|
||||
return true;
|
||||
|
@ -302,9 +320,9 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
for(Map<Point2i,CellOp>::Element *E=paint_undo.front();E;E=E->next()) {
|
||||
|
||||
Point2i p=E->key();
|
||||
//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y));
|
||||
_set_cell(p,TileMap::INVALID_CELL,false,false,true);
|
||||
undo_redo->add_undo_method(node,"set_cell",p.x,p.y,E->get().idx,E->get().xf,E->get().yf);
|
||||
//undo_redo->add_do_method(node,"set_cell",p.x,p.y,node->get_cell(p.x,p.y),node->is_cell_x_flipped(p.x,p.y),node->is_cell_y_flipped(p.x,p.y),node->is_cell_transposed(p.x,p.y));
|
||||
_set_cell(p,TileMap::INVALID_CELL,false,false,false,true);
|
||||
undo_redo->add_undo_method(this,"_set_cell_shortened",Point2(p),E->get().idx,E->get().xf,E->get().yf,E->get().tr);
|
||||
}
|
||||
|
||||
undo_redo->commit_action();
|
||||
|
@ -340,7 +358,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
|
||||
paint_undo[over_tile]=_get_op_from_cell(over_tile);
|
||||
}
|
||||
node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -373,13 +391,17 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) {
|
|||
if (!paint_undo.has(over_tile)) {
|
||||
paint_undo[over_tile]=_get_op_from_cell(over_tile);
|
||||
}
|
||||
//node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed());
|
||||
//node->set_cell(over_tile.x,over_tile.y,id,mirror_x->is_pressed(),mirror_y->is_pressed(),transpose->is_pressed());
|
||||
_set_cell(local,TileMap::INVALID_CELL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tool==TOOL_PICKING) {
|
||||
set_selected_tile(node->get_cell(over_tile.x, over_tile.y));
|
||||
mirror_x->set_pressed(node->is_cell_x_flipped(over_tile.x, over_tile.y));
|
||||
mirror_y->set_pressed(node->is_cell_y_flipped(over_tile.x, over_tile.y));
|
||||
transpose->set_pressed(node->is_cell_transposed(over_tile.x, over_tile.y));
|
||||
_update_transform_buttons();
|
||||
canvas_item_editor->update();
|
||||
return true;
|
||||
}
|
||||
|
@ -627,10 +649,10 @@ void TileMapEditor::_canvas_draw() {
|
|||
sc.y*=-1.0;
|
||||
if (r==Rect2()) {
|
||||
|
||||
canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5));
|
||||
canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5),transpose->is_pressed());
|
||||
} else {
|
||||
|
||||
canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5));
|
||||
canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5),transpose->is_pressed());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -697,6 +719,8 @@ void TileMapEditor::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("_canvas_mouse_enter"),&TileMapEditor::_canvas_mouse_enter);
|
||||
ObjectTypeDB::bind_method(_MD("_canvas_mouse_exit"),&TileMapEditor::_canvas_mouse_exit);
|
||||
ObjectTypeDB::bind_method(_MD("_tileset_settings_changed"),&TileMapEditor::_tileset_settings_changed);
|
||||
ObjectTypeDB::bind_method(_MD("_update_transform_buttons"),&TileMapEditor::_update_transform_buttons);
|
||||
ObjectTypeDB::bind_method(_MD("_set_cell_shortened","pos","tile","flip_x","flip_y","transpose"),&TileMapEditor::_set_cell_shortened,DEFVAL(false),DEFVAL(false),DEFVAL(false));
|
||||
|
||||
}
|
||||
|
||||
|
@ -709,10 +733,60 @@ TileMapEditor::CellOp TileMapEditor::_get_op_from_cell(const Point2i& p_pos)
|
|||
op.xf=true;
|
||||
if (node->is_cell_y_flipped(p_pos.x,p_pos.y))
|
||||
op.yf=true;
|
||||
if (node->is_cell_transposed(p_pos.x,p_pos.y))
|
||||
op.tr=true;
|
||||
}
|
||||
return op;
|
||||
}
|
||||
|
||||
void TileMapEditor::_update_transform_buttons(Object *p_button) {
|
||||
//ERR_FAIL_NULL(p_button);
|
||||
ToolButton *b=p_button->cast_to<ToolButton>();
|
||||
//ERR_FAIL_COND(!b);
|
||||
|
||||
mirror_x->set_block_signals(true);
|
||||
mirror_y->set_block_signals(true);
|
||||
transpose->set_block_signals(true);
|
||||
rotate_0->set_block_signals(true);
|
||||
rotate_90->set_block_signals(true);
|
||||
rotate_180->set_block_signals(true);
|
||||
rotate_270->set_block_signals(true);
|
||||
|
||||
if (b == rotate_0) {
|
||||
mirror_x->set_pressed(false);
|
||||
mirror_y->set_pressed(false);
|
||||
transpose->set_pressed(false);
|
||||
}
|
||||
else if (b == rotate_90) {
|
||||
mirror_x->set_pressed(true);
|
||||
mirror_y->set_pressed(false);
|
||||
transpose->set_pressed(true);
|
||||
}
|
||||
else if (b == rotate_180) {
|
||||
mirror_x->set_pressed(true);
|
||||
mirror_y->set_pressed(true);
|
||||
transpose->set_pressed(false);
|
||||
}
|
||||
else if (b == rotate_270) {
|
||||
mirror_x->set_pressed(false);
|
||||
mirror_y->set_pressed(true);
|
||||
transpose->set_pressed(true);
|
||||
}
|
||||
|
||||
rotate_0->set_pressed(!mirror_x->is_pressed() && !mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
rotate_90->set_pressed(mirror_x->is_pressed() && !mirror_y->is_pressed() && transpose->is_pressed());
|
||||
rotate_180->set_pressed(mirror_x->is_pressed() && mirror_y->is_pressed() && !transpose->is_pressed());
|
||||
rotate_270->set_pressed(!mirror_x->is_pressed() && mirror_y->is_pressed() && transpose->is_pressed());
|
||||
|
||||
mirror_x->set_block_signals(false);
|
||||
mirror_y->set_block_signals(false);
|
||||
transpose->set_block_signals(false);
|
||||
rotate_0->set_block_signals(false);
|
||||
rotate_90->set_block_signals(false);
|
||||
rotate_180->set_block_signals(false);
|
||||
rotate_270->set_block_signals(false);
|
||||
}
|
||||
|
||||
TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
||||
|
||||
node=NULL;
|
||||
|
@ -734,18 +808,52 @@ TileMapEditor::TileMapEditor(EditorNode *p_editor) {
|
|||
canvas_item_editor_hb = memnew( HBoxContainer );
|
||||
CanvasItemEditor::get_singleton()->add_control_to_menu_panel(canvas_item_editor_hb);
|
||||
canvas_item_editor_hb->add_child( memnew( VSeparator ));
|
||||
transpose = memnew( ToolButton );
|
||||
transpose->set_toggle_mode(true);
|
||||
transpose->set_tooltip("Transpose");
|
||||
transpose->set_focus_mode(FOCUS_NONE);
|
||||
transpose->connect("pressed", this, "_update_transform_buttons", make_binds(transpose));
|
||||
canvas_item_editor_hb->add_child(transpose);
|
||||
mirror_x = memnew( ToolButton );
|
||||
mirror_x->set_toggle_mode(true);
|
||||
mirror_x->set_tooltip("Mirror X (A)");
|
||||
mirror_x->set_focus_mode(FOCUS_NONE);
|
||||
mirror_x->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_x));
|
||||
canvas_item_editor_hb->add_child(mirror_x);
|
||||
mirror_y = memnew( ToolButton );
|
||||
mirror_y->set_toggle_mode(true);
|
||||
mirror_y->set_tooltip("Mirror Y (S)");
|
||||
mirror_y->set_focus_mode(FOCUS_NONE);
|
||||
mirror_y->connect("pressed", this, "_update_transform_buttons", make_binds(mirror_y));
|
||||
canvas_item_editor_hb->add_child(mirror_y);
|
||||
canvas_item_editor_hb->add_child(memnew(VSeparator));
|
||||
rotate_0 = memnew( ToolButton );
|
||||
rotate_0->set_toggle_mode(true);
|
||||
rotate_0->set_tooltip("Rotate 0 degrees");
|
||||
rotate_0->set_focus_mode(FOCUS_NONE);
|
||||
rotate_0->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_0));
|
||||
canvas_item_editor_hb->add_child(rotate_0);
|
||||
rotate_90 = memnew( ToolButton );
|
||||
rotate_90->set_toggle_mode(true);
|
||||
rotate_90->set_tooltip("Rotate 90 degrees");
|
||||
rotate_90->set_focus_mode(FOCUS_NONE);
|
||||
rotate_90->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_90));
|
||||
canvas_item_editor_hb->add_child(rotate_90);
|
||||
rotate_180 = memnew( ToolButton );
|
||||
rotate_180->set_toggle_mode(true);
|
||||
rotate_180->set_tooltip("Rotate 180 degrees");
|
||||
rotate_180->set_focus_mode(FOCUS_NONE);
|
||||
rotate_180->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_180));
|
||||
canvas_item_editor_hb->add_child(rotate_180);
|
||||
rotate_270 = memnew( ToolButton );
|
||||
rotate_270->set_toggle_mode(true);
|
||||
rotate_270->set_tooltip("Rotate 270 degrees");
|
||||
rotate_270->set_focus_mode(FOCUS_NONE);
|
||||
rotate_270->connect("pressed", this, "_update_transform_buttons", make_binds(rotate_270));
|
||||
canvas_item_editor_hb->add_child(rotate_270);
|
||||
canvas_item_editor_hb->hide();
|
||||
|
||||
rotate_0->set_pressed(true);
|
||||
tool=TOOL_NONE;
|
||||
selection_active=false;
|
||||
mouse_over=false;
|
||||
|
|
|
@ -71,8 +71,13 @@ class TileMapEditor : public VBoxContainer {
|
|||
bool mouse_over;
|
||||
|
||||
Label *mirror_label;
|
||||
ToolButton *transpose;
|
||||
ToolButton *mirror_x;
|
||||
ToolButton *mirror_y;
|
||||
ToolButton *rotate_0;
|
||||
ToolButton *rotate_90;
|
||||
ToolButton *rotate_180;
|
||||
ToolButton *rotate_270;
|
||||
|
||||
HBoxContainer *canvas_item_editor_hb;
|
||||
|
||||
|
@ -81,8 +86,8 @@ class TileMapEditor : public VBoxContainer {
|
|||
int idx;
|
||||
bool xf;
|
||||
bool yf;
|
||||
CellOp() { idx=-1; xf=false; yf=false; }
|
||||
CellOp(const CellOp& p_other) : idx(p_other.idx), xf(p_other.xf), yf(p_other.yf) {}
|
||||
bool tr;
|
||||
CellOp() { idx=-1; xf=false; yf=false; tr=false; }
|
||||
};
|
||||
|
||||
Map<Point2i,CellOp> paint_undo;
|
||||
|
@ -94,7 +99,8 @@ class TileMapEditor : public VBoxContainer {
|
|||
void _canvas_draw();
|
||||
void _menu_option(int p_option);
|
||||
|
||||
void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_with_undo=false);
|
||||
void _set_cell(const Point2i& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false, bool p_with_undo=false);
|
||||
void _set_cell_shortened(const Point2& p_pos, int p_value, bool p_flip_h=false, bool p_flip_v=false, bool p_transpose=false);
|
||||
|
||||
void _canvas_mouse_enter();
|
||||
void _canvas_mouse_exit();
|
||||
|
@ -106,6 +112,7 @@ protected:
|
|||
void _node_removed(Node *p_node);
|
||||
static void _bind_methods();
|
||||
CellOp _get_op_from_cell(const Point2i& p_pos);
|
||||
void _update_transform_buttons(Object *p_button=0);
|
||||
public:
|
||||
|
||||
HBoxContainer *get_canvas_item_editor_hb() const { return canvas_item_editor_hb; }
|
||||
|
|
|
@ -1857,7 +1857,32 @@ void PropertyEditor::set_item_text(TreeItem *p_item, int p_type, const String& p
|
|||
} else {
|
||||
p_item->set_text(1,"<"+res->get_type()+">");
|
||||
};
|
||||
|
||||
if (has_icon(res->get_type(),"EditorIcons")) {
|
||||
|
||||
p_item->set_icon(1,get_icon(res->get_type(),"EditorIcons"));
|
||||
} else {
|
||||
|
||||
Dictionary d = p_item->get_metadata(0);
|
||||
int hint=d.has("hint")?d["hint"].operator int():-1;
|
||||
String hint_text=d.has("hint_text")?d["hint_text"]:"";
|
||||
if (hint==PROPERTY_HINT_RESOURCE_TYPE) {
|
||||
|
||||
if (has_icon(hint_text,"EditorIcons")) {
|
||||
|
||||
p_item->set_icon(1,get_icon(hint_text,"EditorIcons"));
|
||||
|
||||
} else {
|
||||
p_item->set_icon(1,get_icon("Object","EditorIcons"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
} break;
|
||||
default: {};
|
||||
|
@ -2529,7 +2554,10 @@ void PropertyEditor::update_tree() {
|
|||
item->set_editable( 1, !read_only );
|
||||
item->add_button(1,get_icon("EditResource","EditorIcons"));
|
||||
String type;
|
||||
if (p.hint==PROPERTY_HINT_RESOURCE_TYPE)
|
||||
type=p.hint_string;
|
||||
bool notnil=false;
|
||||
|
||||
if (obj->get( p.name ).get_type() == Variant::NIL || obj->get( p.name ).operator RefPtr().is_null()) {
|
||||
item->set_text(1,"<null>");
|
||||
|
||||
|
@ -2553,12 +2581,18 @@ void PropertyEditor::update_tree() {
|
|||
};
|
||||
notnil=true;
|
||||
|
||||
if (has_icon(res->get_type(),"EditorIcons")) {
|
||||
type=res->get_type();
|
||||
}
|
||||
}
|
||||
|
||||
if (p.hint==PROPERTY_HINT_RESOURCE_TYPE) {
|
||||
|
||||
if (type!=String()) {
|
||||
if (type.find(",")!=-1)
|
||||
type=type.get_slice(",",0);
|
||||
//printf("prop %s , type %s\n",p.name.ascii().get_data(),p.hint_string.ascii().get_data());
|
||||
if (has_icon(p.hint_string,"EditorIcons"))
|
||||
item->set_icon( 0, get_icon(p.hint_string,"EditorIcons") );
|
||||
if (has_icon(type,"EditorIcons"))
|
||||
item->set_icon( 0, get_icon(type,"EditorIcons") );
|
||||
else
|
||||
item->set_icon( 0, get_icon("Object","EditorIcons") );
|
||||
}
|
||||
|
|
|
@ -1254,7 +1254,7 @@ SceneTreeDock::SceneTreeDock(EditorNode *p_editor,Node *p_scene_root,EditorSelec
|
|||
|
||||
tb = memnew( ToolButton );
|
||||
tb->connect("pressed",this,"_tool_selected",make_binds(TOOL_INSTANCE, false));
|
||||
tb->set_tooltip("Instance a Node from scene file.");
|
||||
tb->set_tooltip("Instance a scene file as a Node.");
|
||||
hbc_top->add_child(tb);
|
||||
tool_buttons[TOOL_INSTANCE]=tb;
|
||||
|
||||
|
|
|
@ -94,8 +94,6 @@ def strarr(arr):
|
|||
s+=" "
|
||||
return s
|
||||
|
||||
|
||||
|
||||
class DaeExporter:
|
||||
|
||||
def validate_id(self,d):
|
||||
|
@ -132,10 +130,10 @@ class DaeExporter:
|
|||
tup = tup + (self.tangent.x,self.tangent.y,self.tangent.z)
|
||||
if (self.bitangent!=None):
|
||||
tup = tup + (self.bitangent.x,self.bitangent.y,self.bitangent.z)
|
||||
#for t in self.bones:
|
||||
# tup = tup + (t)
|
||||
#for t in self.weights:
|
||||
# tup = tup + (t)
|
||||
for t in self.bones:
|
||||
tup = tup + (float(t),)
|
||||
for t in self.weights:
|
||||
tup = tup + (float(t),)
|
||||
|
||||
return tup
|
||||
|
||||
|
@ -512,12 +510,12 @@ class DaeExporter:
|
|||
mat_assign=[]
|
||||
|
||||
uv_layer_count=len(mesh.uv_textures)
|
||||
if (len(mesh.uv_textures)):
|
||||
if (has_tangents and len(mesh.uv_textures)):
|
||||
try:
|
||||
mesh.calc_tangents()
|
||||
except:
|
||||
print("Warning, blender API is fucked up, not exporting UVs for this object.")
|
||||
uv_layer_count=0
|
||||
self.operator.report({'WARNING'},'CalcTangets failed for mesh "'+mesh.name+'", no tangets will be exported.')
|
||||
#uv_layer_count=0
|
||||
mesh.calc_normals_split()
|
||||
has_tangents=False
|
||||
|
||||
|
@ -591,16 +589,30 @@ class DaeExporter:
|
|||
|
||||
if (armature!=None):
|
||||
wsum=0.0
|
||||
zero_bones=[]
|
||||
|
||||
for vg in mv.groups:
|
||||
if vg.group >= len(node.vertex_groups):
|
||||
continue;
|
||||
name = node.vertex_groups[vg.group].name
|
||||
|
||||
if (name in si["bone_index"]):
|
||||
#could still put the weight as 0.0001 maybe
|
||||
if (vg.weight>0.001): #blender has a lot of zero weight stuff
|
||||
v.bones.append(si["bone_index"][name])
|
||||
v.weights.append(vg.weight)
|
||||
wsum+=vg.weight
|
||||
if (wsum==0.0):
|
||||
if not self.wrongvtx_report:
|
||||
self.operator.report({'WARNING'},'Mesh for object "'+node.name+'" has unassigned weights. This may look wrong in exported model.')
|
||||
self.wrongvtx_report=True
|
||||
|
||||
#blender can have bones assigned that weight zero so they remain local
|
||||
#this is the best it can be done?
|
||||
v.bones.append(0)
|
||||
v.weights.append(1)
|
||||
|
||||
|
||||
|
||||
|
||||
tup = v.get_tup()
|
||||
|
@ -889,6 +901,15 @@ class DaeExporter:
|
|||
if (node.parent!=None):
|
||||
if (node.parent.type=="ARMATURE"):
|
||||
armature=node.parent
|
||||
armcount=0
|
||||
for n in node.modifiers:
|
||||
if (n.type=="ARMATURE"):
|
||||
armcount+=1
|
||||
if (armcount>1):
|
||||
self.operator.report({'WARNING'},'Object "'+node.name+'" refers to more than one armature! This is unsopported.')
|
||||
|
||||
|
||||
|
||||
|
||||
if (node.data.shape_keys!=None):
|
||||
sk = node.data.shape_keys
|
||||
|
@ -940,6 +961,12 @@ class DaeExporter:
|
|||
boneidx = si["bone_count"]
|
||||
si["bone_count"]+=1
|
||||
bonesid = si["id"]+"-"+str(boneidx)
|
||||
if (bone.name in self.used_bones):
|
||||
if (self.config["use_anim_action_all"]):
|
||||
self.operator.report({'WARNING'},'Bone name "'+bone.name+'" used in more than one skeleton. Actions might export wrong.')
|
||||
else:
|
||||
self.used_bones.append(bone.name)
|
||||
|
||||
si["bone_index"][bone.name]=boneidx
|
||||
si["bone_ids"][bone]=boneid
|
||||
si["bone_names"].append(bonesid)
|
||||
|
@ -1002,12 +1029,12 @@ class DaeExporter:
|
|||
self.writel(S_CAMS,5,'<zfar> '+str(camera.clip_end)+' </zfar>')
|
||||
self.writel(S_CAMS,4,'</perspective>')
|
||||
else:
|
||||
self.writel(S_CAMS,4,'<orthografic>')
|
||||
self.writel(S_CAMS,5,'<xmag> '+str(camera.ortho_scale)+' </xmag>') # I think?
|
||||
self.writel(S_CAMS,4,'<orthographic>')
|
||||
self.writel(S_CAMS,5,'<xmag> '+str(camera.ortho_scale*0.5)+' </xmag>') # I think?
|
||||
self.writel(S_CAMS,5,'<aspect_ratio> '+str(self.scene.render.resolution_x / self.scene.render.resolution_y)+' </aspect_ratio>')
|
||||
self.writel(S_CAMS,5,'<znear> '+str(camera.clip_start)+' </znear>')
|
||||
self.writel(S_CAMS,5,'<zfar> '+str(camera.clip_end)+' </zfar>')
|
||||
self.writel(S_CAMS,4,'</orthografic>')
|
||||
self.writel(S_CAMS,4,'</orthographic>')
|
||||
|
||||
self.writel(S_CAMS,3,'</technique_common>')
|
||||
self.writel(S_CAMS,2,'</optics>')
|
||||
|
@ -1534,10 +1561,14 @@ class DaeExporter:
|
|||
for z in tcn:
|
||||
self.writel(S_ANIM_CLIPS,2,'<instance_animation url="#'+z+'"/>')
|
||||
self.writel(S_ANIM_CLIPS,1,'</animation_clip>')
|
||||
if (len(tcn)==0):
|
||||
self.operator.report({'WARNING'},'Animation clip "'+x.name+'" contains no tracks.')
|
||||
|
||||
|
||||
|
||||
self.writel(S_ANIM_CLIPS,0,'</library_animation_clips>')
|
||||
|
||||
|
||||
for i,s in enumerate(self.skeletons):
|
||||
if (s.animation_data==None):
|
||||
continue
|
||||
|
@ -1547,6 +1578,7 @@ class DaeExporter:
|
|||
s.animation_data.action = None
|
||||
for j,bone in enumerate(s.pose.bones):
|
||||
bone.matrix_basis = tmp_mat[i][1][j]
|
||||
|
||||
else:
|
||||
self.export_animation(self.scene.frame_start,self.scene.frame_end)
|
||||
|
||||
|
@ -1617,7 +1649,8 @@ class DaeExporter:
|
|||
f.write(bytes('</COLLADA>\n',"UTF-8"))
|
||||
return True
|
||||
|
||||
def __init__(self,path,kwargs):
|
||||
def __init__(self,path,kwargs,operator):
|
||||
self.operator=operator
|
||||
self.scene=bpy.context.scene
|
||||
self.last_id=0
|
||||
self.scene_name=self.new_id("scene")
|
||||
|
@ -1631,6 +1664,10 @@ class DaeExporter:
|
|||
self.config=kwargs
|
||||
self.valid_nodes=[]
|
||||
self.armature_for_morph={}
|
||||
self.used_bones=[]
|
||||
self.wrongvtx_report=False
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1642,9 +1679,11 @@ def save(operator, context,
|
|||
**kwargs
|
||||
):
|
||||
|
||||
exp = DaeExporter(filepath,kwargs)
|
||||
exp = DaeExporter(filepath,kwargs,operator)
|
||||
exp.export()
|
||||
|
||||
|
||||
|
||||
return {'FINISHED'} # so the script wont run after we have batch exported.
|
||||
|
||||
|
||||
|
|