Bug Fixes

-=-=-=-=-

-Fixed problem with scaling shapes (#827), related to not taking scale in consideration for calculating the moment of inertia
-Added support for multiline strings (or comments) using """
-Save subscene bug, properties not being saved in root node (#806)
-Fix Crash in CollisionPolygon2DEditor (#814)
-Restored Ability to compile without 3D (#795)
-Fix InterpolatedCamera (#803)
-Fix UV Import for OBJ Meshes (#771)
-Fixed issue with modifier gizmos (#794)
-Fixed CapsuleShape gizmo handle (#50)
-Fixed Import Button (not properly working in 3D) (#733)
-Many misc fixes (though no new features)
This commit is contained in:
Juan Linietsky 2014-11-02 11:31:01 -03:00
parent 738eb2c1a8
commit d85b67be53
56 changed files with 7513 additions and 1908 deletions

View file

@ -597,7 +597,15 @@ void _OS::native_video_stop() {
OS::get_singleton()->native_video_stop();
};
bool _OS::is_debug_build() const {
#ifdef DEBUG_ENABLED
return true;
#else
return false;
#endif
}
String _OS::get_custom_level() const {
return OS::get_singleton()->get_custom_level();
@ -668,6 +676,8 @@ void _OS::_bind_methods() {
ObjectTypeDB::bind_method(_MD("can_use_threads"),&_OS::can_use_threads);
ObjectTypeDB::bind_method(_MD("is_debug_build"),&_OS::is_debug_build);
//ObjectTypeDB::bind_method(_MD("get_mouse_button_state"),&_OS::get_mouse_button_state);
ObjectTypeDB::bind_method(_MD("dump_memory_to_file","file"),&_OS::dump_memory_to_file);

View file

@ -154,6 +154,8 @@ public:
bool has_touchscreen_ui_hint() const;
bool is_debug_build() const;
String get_unique_ID() const;
/*

View file

@ -81,6 +81,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_BUNDLE=128, //used for optimized bundles
PROPERTY_USAGE_CATEGORY=256,
PROPERTY_USAGE_STORE_IF_NONZERO=512, //only store if nonzero
PROPERTY_USAGE_NO_INSTANCE_STATE=1024,
PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED,

View file

@ -243,6 +243,11 @@ void UndoRedo::_process_operation_list(List<Operation>::Element *E) {
case Operation::TYPE_PROPERTY: {
obj->set(op.name,op.args[0]);
#ifdef TOOLS_ENABLED
Resource* res = obj->cast_to<Resource>();
if (res)
res->set_edited(true);
#endif
} break;
case Operation::TYPE_REFERENCE: {
//do nothing

File diff suppressed because it is too large Load diff

View file

@ -360,17 +360,19 @@ void RasterizerGLES2::_draw_primitive(int p_points, const Vector3 *p_vertices, c
/* TEXTURE API */
Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed) {
Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,GLenum& r_gl_internal_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed) {
r_has_alpha_cache=false;
r_compressed=false;
r_gl_format=0;
Image image=p_image;
switch(p_format) {
case Image::FORMAT_GRAYSCALE: {
r_gl_components=1;
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_NV:GL_LUMINANCE;
r_gl_format=GL_LUMINANCE;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_NV:GL_LUMINANCE;
} break;
case Image::FORMAT_INTENSITY: {
@ -378,14 +380,16 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (!image.empty())
image.convert(Image::FORMAT_RGBA);
r_gl_components=4;
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
r_gl_format=GL_RGBA;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_ALPHA_EXT:GL_RGBA;
r_has_alpha_cache=true;
} break;
case Image::FORMAT_GRAYSCALE_ALPHA: {
//image.convert(Image::FORMAT_RGBA);
r_gl_components=2;
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_ALPHA_NV:GL_LUMINANCE_ALPHA;
r_gl_format=GL_LUMINANCE_ALPHA;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_SLUMINANCE_ALPHA_NV:GL_LUMINANCE_ALPHA;
r_has_alpha_cache=true;
} break;
@ -394,7 +398,8 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (!image.empty())
image.convert(Image::FORMAT_RGB);
r_gl_components=3;
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB;
r_gl_format=GL_RGB;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_GL_SRGB_EXT:GL_RGB;
} break;
@ -407,14 +412,15 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
@ -426,14 +432,15 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_EXT;
} else {
r_gl_internal_format=_GL_SRGB_EXT;
r_gl_format=GL_RGB;
} else {
r_gl_internal_format=GL_RGB;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGB;
r_gl_internal_format=GL_RGB;
}
} break;
case Image::FORMAT_RGBA: {
@ -442,14 +449,16 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
r_gl_format=GL_RGBA;
//r_gl_internal_format=GL_RGBA;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
@ -465,21 +474,22 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_components=1; //doesn't matter much
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT1_EXT;
r_compressed=true;
};
@ -495,20 +505,21 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_components=1; //doesn't matter much
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT3_EXT;
r_has_alpha_cache=true;
r_compressed=true;
@ -526,20 +537,21 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_components=1; //doesn't matter much
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_NV:_EXT_COMPRESSED_RGBA_S3TC_DXT5_EXT;
r_has_alpha_cache=true;
r_compressed=true;
};
@ -556,20 +568,21 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=_EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
r_gl_internal_format=_EXT_COMPRESSED_LUMINANCE_LATC1_EXT;
r_gl_components=1; //doesn't matter much
r_compressed=true;
};
@ -586,19 +599,20 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=_EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
r_gl_internal_format=_EXT_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
r_gl_components=1; //doesn't matter much
r_compressed=true;
};
@ -614,21 +628,22 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
r_gl_components=1; //doesn't matter much
r_compressed=true;
@ -645,22 +660,23 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_internal_format=_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
r_gl_components=1; //doesn't matter much
r_compressed=true;
@ -677,19 +693,20 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -705,19 +722,20 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=_GL_SRGB_ALPHA_EXT;
} else {
r_gl_internal_format=GL_RGBA;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
}
r_has_alpha_cache=true;
} else {
r_gl_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
r_gl_internal_format=(srgb_supported && p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR)?_EXT_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT:_EXT_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -734,21 +752,22 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (p_flags&VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) {
if (srgb_supported) {
r_gl_format=_GL_SRGB_EXT;
} else {
r_gl_format=GL_RGB;
r_gl_internal_format=_GL_SRGB_EXT;
} else {
r_gl_internal_format=GL_RGB;
if (!image.empty())
image.srgb_to_linear();
}
} else {
r_gl_format=GL_RGB;
r_gl_internal_format=GL_RGB;
}
r_gl_format=GL_RGB;
r_gl_internal_format=GL_RGB;
} else {
r_gl_format=_EXT_ETC1_RGB8_OES;
r_gl_internal_format=_EXT_ETC1_RGB8_OES;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -762,12 +781,12 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
image.decompress();
}
r_gl_components=3;
r_gl_format=GL_RGB;
r_gl_internal_format=GL_RGB;
} else {
r_gl_format=_EXT_ATC_RGB_AMD;
r_gl_internal_format=_EXT_ATC_RGB_AMD;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -781,12 +800,12 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
image.decompress();
}
r_gl_components=4;
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
} else {
r_gl_format=_EXT_ATC_RGBA_EXPLICIT_ALPHA_AMD;
r_gl_internal_format=_EXT_ATC_RGBA_EXPLICIT_ALPHA_AMD;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -800,12 +819,12 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
image.decompress();
}
r_gl_components=4;
r_gl_format=GL_RGBA;
r_gl_internal_format=GL_RGBA;
} else {
r_gl_format=_EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
r_gl_internal_format=_EXT_ATC_RGBA_INTERPOLATED_ALPHA_AMD;
r_gl_components=1; //doesn't matter much
r_compressed=true;
}
@ -816,7 +835,7 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
if (!image.empty())
image.convert(Image::FORMAT_RGB);
r_gl_format=GL_RGB;
r_gl_internal_format=GL_RGB;
r_gl_components=3;
} break;
@ -827,6 +846,10 @@ Image RasterizerGLES2::_get_gl_image_and_format(const Image& p_image, Image::For
}
}
if (r_gl_format==0) {
r_gl_format=r_gl_internal_format;
}
return image;
}
@ -858,6 +881,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
bool has_alpha_cache;
int components;
GLenum format;
GLenum internal_format;
bool compressed;
int po2_width = nearest_power_of_2(p_width);
@ -876,7 +900,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
texture->flags=p_flags;
texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
_get_gl_image_and_format(Image(),texture->format,texture->flags,format,components,has_alpha_cache,compressed);
_get_gl_image_and_format(Image(),texture->format,texture->flags,format,internal_format,components,has_alpha_cache,compressed);
bool scale_textures = !compressed && !(p_flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) && (!npo2_textures_available || p_flags&VS::TEXTURE_FLAG_MIPMAPS);
@ -894,6 +918,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
texture->gl_components_cache=components;
texture->gl_format_cache=format;
texture->gl_internal_format_cache=internal_format;
texture->format_has_alpha=has_alpha_cache;
texture->compressed=compressed;
texture->has_alpha=false; //by default it doesn't have alpha unless something with alpha is blitteds
@ -908,7 +933,7 @@ void RasterizerGLES2::texture_allocate(RID p_texture,int p_width, int p_height,I
if (p_flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) {
//prealloc if video
glTexImage2D(texture->target, 0, format, p_width, p_height, 0, format, GL_UNSIGNED_BYTE,NULL);
glTexImage2D(texture->target, 0, internal_format, p_width, p_height, 0, format, GL_UNSIGNED_BYTE,NULL);
}
texture->active=true;
@ -926,6 +951,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
int components;
GLenum format;
GLenum internal_format;
bool alpha;
bool compressed;
@ -933,7 +959,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
texture->image[p_cube_side]=p_image;
}
Image img = _get_gl_image_and_format(p_image, p_image.get_format(),texture->flags,format,components,alpha,compressed);
Image img = _get_gl_image_and_format(p_image, p_image.get_format(),texture->flags,format,internal_format,components,alpha,compressed);
if (texture->alloc_width != img.get_width() || texture->alloc_height != img.get_height()) {
@ -1017,7 +1043,7 @@ void RasterizerGLES2::texture_set_data(RID p_texture,const Image& p_image,VS::Cu
if (texture->flags&VS::TEXTURE_FLAG_VIDEO_SURFACE) {
glTexSubImage2D( blit_target, i, 0,0,w,h,format,GL_UNSIGNED_BYTE,&read[ofs] );
} else {
glTexImage2D(blit_target, i, format, w, h, 0, format, GL_UNSIGNED_BYTE,&read[ofs]);
glTexImage2D(blit_target, i, internal_format, w, h, 0, format, GL_UNSIGNED_BYTE,&read[ofs]);
}
}

View file

@ -106,7 +106,7 @@ class RasterizerGLES2 : public Rasterizer {
Vector<float> skel_default;
Image _get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
Image _get_gl_image_and_format(const Image& p_image, Image::Format p_format, uint32_t p_flags,GLenum& r_gl_format,GLenum& r_gl_internal_format,int &r_gl_components,bool &r_has_alpha_cache,bool &r_compressed);
class RenderTarget;
@ -119,6 +119,7 @@ class RasterizerGLES2 : public Rasterizer {
GLenum target;
GLenum gl_format_cache;
GLenum gl_internal_format_cache;
int gl_components_cache;
int data_size; //original data size, useful for retrieving back
bool has_alpha;

View file

@ -102,6 +102,9 @@ Error ImageLoaderPNG::_load_image(void *rf_up,png_rw_ptr p_func,Image *p_image)
png_read_info(png, info);
png_get_IHDR(png, info, &width, &height, &depth, &color, NULL, NULL, NULL);
png_textp t;
//https://svn.gov.pt/projects/ccidadao/repository/middleware-offline/trunk/_src/eidmw/FreeImagePTEiD/Source/FreeImage/PluginPNG.cpp
//png_get_text(png,info,)
/*
printf("Image width:%i\n", width);
printf("Image Height:%i\n", height);

View file

@ -30,6 +30,7 @@
#include "scene/resources/texture.h"
#include "drivers/png/png.h"
#include "os/file_access.h"
#include "globals.h"
static void _write_png_data(png_structp png_ptr,png_bytep data, png_size_t p_length) {
@ -165,6 +166,42 @@ Error ResourceSaverPNG::save(const String &p_path,const RES& p_resource,uint32_t
memdelete(f);
if (true) {
bool global_filter = Globals::get_singleton()->get("image_loader/filter");
bool global_mipmaps = Globals::get_singleton()->get("image_loader/gen_mipmaps");
bool global_repeat = Globals::get_singleton()->get("image_loader/repeat");
String text;
if (global_filter!=bool(texture->get_flags()&Texture::FLAG_FILTER)) {
text+=bool(texture->get_flags()&Texture::FLAG_FILTER)?"filter=true\n":"filter=false\n";
}
if (global_mipmaps!=bool(texture->get_flags()&Texture::FLAG_MIPMAPS)) {
text+=bool(texture->get_flags()&Texture::FLAG_FILTER)?"gen_mipmaps=true\n":"gen_mipmaps=false\n";
}
if (global_repeat!=bool(texture->get_flags()&Texture::FLAG_REPEAT)) {
text+=bool(texture->get_flags()&Texture::FLAG_FILTER)?"repeat=true\n":"repeat=false\n";
}
if (bool(texture->get_flags()&Texture::FLAG_ANISOTROPIC_FILTER)) {
text+="anisotropic=true\n";
}
if (bool(texture->get_flags()&Texture::FLAG_CONVERT_TO_LINEAR)) {
text+="tolinear=true\n";
}
if (text!="" || FileAccess::exists(p_path+".flags")) {
f = FileAccess::open(p_path+".flags",FileAccess::WRITE);
if (f) {
f->store_string(text);
memdelete(f);
}
}
}
/* cleanup heap allocation */
return OK;

View file

@ -306,18 +306,28 @@ int VideoStreamTheoraplayer::get_pending_frame_count() const {
if (!clip)
return 0;
if (!frame.empty())
return 1;
TheoraVideoFrame* f = clip->getNextFrame();
return f ? 1 : 0;
};
void VideoStreamTheoraplayer::pop_frame(Ref<ImageTexture> p_tex) {
TheoraVideoFrame* f = clip->getNextFrame();
if (!f)
return 0;
if (!f) {
return;
};
#ifdef GLES2_ENABLED
// RasterizerGLES2* r = RasterizerGLES2::get_singleton();
// r->_texture_set_data(p_tex, f->mBpp == 3 ? Image::Format_RGB : Image::Format_RGBA, f->mBpp, w, h, f->getBuffer());
#endif
float w=clip->getWidth(),h=clip->getHeight();
int imgsize = w * h * f->mBpp;
int size = f->getStride() * f->getHeight() * f->mBpp;
DVector<uint8_t> data;
data.resize(imgsize);
DVector<uint8_t>::Write wr = data.write();
uint8_t* ptr = wr.ptr();
@ -329,24 +339,32 @@ int VideoStreamTheoraplayer::get_pending_frame_count() const {
copymem(ptr + dstofs, f->getBuffer() + dstofs, w * f->mBpp);
};
*/
frame = Image();
Image frame = Image();
frame.create(w, h, 0, f->mBpp == 3 ? Image::FORMAT_RGB : Image::FORMAT_RGBA, data);
clip->popFrame();
return 1;
if (p_tex->get_width() == 0) {
p_tex->create(frame.get_width(),frame.get_height(),frame.get_format(),Texture::FLAG_VIDEO_SURFACE|Texture::FLAG_FILTER);
p_tex->set_data(frame);
} else {
p_tex->set_data(frame);
};
};
/*
Image VideoStreamTheoraplayer::pop_frame() {
Image ret = frame;
frame = Image();
return ret;
};
*/
Image VideoStreamTheoraplayer::peek_frame() const {
return frame;
return Image();
};
void VideoStreamTheoraplayer::update(float p_time) {
@ -386,7 +404,7 @@ void VideoStreamTheoraplayer::set_file(const String& p_file) {
if (p_file.find(".mp4") != -1) {
std::string file = p_file.replace("res://", "").utf8().get_data();
clip = mgr->createVideoClip(file);
clip = mgr->createVideoClip(file, TH_BGRX, 16);
memdelete(f);
} else {

View file

@ -3,6 +3,7 @@
#include "scene/resources/video_stream.h"
#include "io/resource_loader.h"
#include "scene/resources/texture.h"
class TheoraVideoManager;
class TheoraVideoClip;
@ -11,7 +12,7 @@ class VideoStreamTheoraplayer : public VideoStream {
OBJ_TYPE(VideoStreamTheoraplayer,VideoStream);
mutable Image frame;
mutable DVector<uint8_t> data;
TheoraVideoManager* mgr;
TheoraVideoClip* clip;
bool started;
@ -37,7 +38,7 @@ public:
virtual float get_length() const;
virtual int get_pending_frame_count() const;
virtual Image pop_frame();
virtual void pop_frame(Ref<ImageTexture> p_tex);
virtual Image peek_frame() const;
void update(float p_time);

View file

@ -65,18 +65,18 @@ bool GDCompiler::_create_unary_operator(CodeGen& codegen,const GDParser::Operato
return true;
}
bool GDCompiler::_create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level) {
bool GDCompiler::_create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level,bool p_initializer) {
ERR_FAIL_COND_V(on->arguments.size()!=2,false);
int src_address_a = _parse_expression(codegen,on->arguments[0],p_stack_level);
int src_address_a = _parse_expression(codegen,on->arguments[0],p_stack_level,false,p_initializer);
if (src_address_a<0)
return false;
if (src_address_a&GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS)
p_stack_level++; //uses stack for return, increase stack
int src_address_b = _parse_expression(codegen,on->arguments[1],p_stack_level);
int src_address_b = _parse_expression(codegen,on->arguments[1],p_stack_level,false,p_initializer);
if (src_address_b<0)
return false;
@ -111,6 +111,7 @@ int GDCompiler::_parse_assign_right_expression(CodeGen& codegen,const GDParser::
Variant::Operator var_op=Variant::OP_MAX;
switch(p_expression->op) {
case GDParser::OperatorNode::OP_ASSIGN_ADD: var_op=Variant::OP_ADD; break;
@ -123,6 +124,7 @@ int GDCompiler::_parse_assign_right_expression(CodeGen& codegen,const GDParser::
case GDParser::OperatorNode::OP_ASSIGN_BIT_AND: var_op=Variant::OP_BIT_AND; break;
case GDParser::OperatorNode::OP_ASSIGN_BIT_OR: var_op=Variant::OP_BIT_OR; break;
case GDParser::OperatorNode::OP_ASSIGN_BIT_XOR: var_op=Variant::OP_BIT_XOR; break;
case GDParser::OperatorNode::OP_INIT_ASSIGN:
case GDParser::OperatorNode::OP_ASSIGN: {
//none
@ -133,12 +135,14 @@ int GDCompiler::_parse_assign_right_expression(CodeGen& codegen,const GDParser::
}
}
bool initializer = p_expression->op==GDParser::OperatorNode::OP_INIT_ASSIGN;
if (var_op==Variant::OP_MAX) {
return _parse_expression(codegen,p_expression->arguments[1],p_stack_level);
return _parse_expression(codegen,p_expression->arguments[1],p_stack_level,false,initializer);
}
if (!_create_binary_operator(codegen,p_expression,var_op,p_stack_level))
if (!_create_binary_operator(codegen,p_expression,var_op,p_stack_level,initializer))
return -1;
int dst_addr=(p_stack_level)|(GDFunction::ADDR_TYPE_STACK<<GDFunction::ADDR_BITS);
@ -148,7 +152,7 @@ int GDCompiler::_parse_assign_right_expression(CodeGen& codegen,const GDParser::
}
int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root) {
int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root,bool p_initializer) {
switch(p_expression->type) {
@ -165,17 +169,16 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
StringName identifier = in->name;
// TRY STACK!
if (codegen.stack_identifiers.has(identifier)) {
if (!p_initializer && codegen.stack_identifiers.has(identifier)) {
int pos = codegen.stack_identifiers[identifier];
return pos|(GDFunction::ADDR_TYPE_STACK_VARIABLE<<GDFunction::ADDR_BITS);
}
//TRY ARGUMENTS!
//TRY MEMBERS!
if (!codegen.function_node || !codegen.function_node->_static) {
// TRY MEMBER VARIABLES!
//static function
if (codegen.script->member_indices.has(identifier)) {
@ -686,6 +689,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
case GDParser::OperatorNode::OP_ASSIGN_BIT_AND:
case GDParser::OperatorNode::OP_ASSIGN_BIT_OR:
case GDParser::OperatorNode::OP_ASSIGN_BIT_XOR:
case GDParser::OperatorNode::OP_INIT_ASSIGN:
case GDParser::OperatorNode::OP_ASSIGN: {
ERR_FAIL_COND_V(on->arguments.size()!=2,-1);
@ -843,7 +847,7 @@ int GDCompiler::_parse_expression(CodeGen& codegen,const GDParser::Node *p_expre
int slevel = p_stack_level;
int dst_address_a = _parse_expression(codegen,on->arguments[0],slevel);
int dst_address_a = _parse_expression(codegen,on->arguments[0],slevel,false,on->op==GDParser::OperatorNode::OP_INIT_ASSIGN);
if (dst_address_a<0)
return -1;

View file

@ -153,11 +153,11 @@ class GDCompiler {
void _set_error(const String& p_error,const GDParser::Node *p_node);
bool _create_unary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level);
bool _create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level);
bool _create_binary_operator(CodeGen& codegen,const GDParser::OperatorNode *on,Variant::Operator op, int p_stack_level,bool p_initializer=false);
//int _parse_subexpression(CodeGen& codegen,const GDParser::BlockNode *p_block,const GDParser::Node *p_expression);
int _parse_assign_right_expression(CodeGen& codegen,const GDParser::OperatorNode *p_expression, int p_stack_level);
int _parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root=false);
int _parse_expression(CodeGen& codegen,const GDParser::Node *p_expression, int p_stack_level,bool p_root=false,bool p_initializer=false);
Error _parse_block(CodeGen& codegen,const GDParser::BlockNode *p_block,int p_stack_level=0,int p_break_addr=-1,int p_continue_addr=-1);
Error _parse_function(GDScript *p_script,const GDParser::ClassNode *p_class,const GDParser::FunctionNode *p_func);
Error _parse_class(GDScript *p_script,GDScript *p_owner,const GDParser::ClassNode *p_class);

View file

@ -33,6 +33,7 @@
void GDScriptLanguage::get_comment_delimiters(List<String> *p_delimiters) const {
p_delimiters->push_back("#");
p_delimiters->push_back("\"\"\"");
}
void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const {

View file

@ -2429,7 +2429,7 @@ void GDParser::_parse_class(ClassNode *p_class) {
id->name=member.identifier;
OperatorNode *op = alloc_node<OperatorNode>();
op->op=OperatorNode::OP_ASSIGN;
op->op=OperatorNode::OP_INIT_ASSIGN;
op->arguments.push_back(id);
op->arguments.push_back(subexpr);

View file

@ -215,6 +215,7 @@ public:
OP_MOD,
OP_SHIFT_LEFT,
OP_SHIFT_RIGHT,
OP_INIT_ASSIGN,
OP_ASSIGN,
OP_ASSIGN_ADD,
OP_ASSIGN_SUB,

View file

@ -2448,6 +2448,7 @@ void GDScriptLanguage::get_reserved_words(List<String> *p_words) const {
"if" ,
"in" ,
"null" ,
"not" ,
"return" ,
"self" ,
"while" ,

View file

@ -239,8 +239,7 @@ void GDTokenizerText::_advance() {
bool is_node_path = false;
bool is_string = false;
bool is_string_alt = false;
StringMode string_mode=STRING_DOUBLE_QUOTE;
switch(GETCHAR(0)) {
case 0:
@ -538,22 +537,35 @@ void GDTokenizerText::_advance() {
is_node_path=true;
case '\'':
is_string_alt = true;
string_mode=STRING_SINGLE_QUOTE;
case '"': {
is_string = is_string_alt ? false : true;
int i=1;
if (string_mode==STRING_DOUBLE_QUOTE && GETCHAR(i)=='"' && GETCHAR(i+1)=='"') {
i+=2;
string_mode=STRING_MULTILINE;
}
String str;
while(true) {
if (CharType(GETCHAR(i)==0)) {
if (CharType(GETCHAR(i))==0) {
_make_error("Unterminated String");
return;
} else if( CharType(GETCHAR(i)=='"') && is_string ) {
} else if( string_mode==STRING_DOUBLE_QUOTE && CharType(GETCHAR(i))=='"' ) {
break;
} else if( CharType(GETCHAR(i)=='\'') && is_string_alt ) {
break;
} else if (CharType(GETCHAR(i)=='\\')) {
} else if( string_mode==STRING_SINGLE_QUOTE && CharType(GETCHAR(i))=='\'' ) {
break;
} else if( string_mode==STRING_MULTILINE && CharType(GETCHAR(i))=='\"' && CharType(GETCHAR(i+1))=='\"' && CharType(GETCHAR(i+2))=='\"') {
i+=2;
break;
} else if( string_mode!=STRING_MULTILINE && CharType(GETCHAR(i))=='\n') {
_make_error("Unexpected EOL at String.");
return;
} else if (CharType(GETCHAR(i))=='\\') {
//escaped characters...
i++;
CharType next = GETCHAR(i);

View file

@ -122,6 +122,13 @@ public:
};
protected:
enum StringMode {
STRING_SINGLE_QUOTE,
STRING_DOUBLE_QUOTE,
STRING_MULTILINE
};
static const char* token_names[TK_MAX];
public:
static const char *get_token_name(Token p_token);

View file

@ -101,7 +101,16 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
AudioBuffer *abuf;
AudioDriverOSX* ad = (AudioDriverOSX*)inRefCon;
if (!ad->active) {
bool mix = true;
if (!ad->active)
mix = false;
else if (ad->mutex) {
mix = ad->mutex->try_lock() == OK;
};
if (!mix) {
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
abuf = &ioData->mBuffers[i];
zeromem(abuf->mData, abuf->mDataByteSize);
@ -120,9 +129,9 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
while (frames_left) {
int frames = MIN(frames_left, ad->buffer_frames);
ad->lock();
//ad->lock();
ad->audio_server_process(frames, ad->samples_in);
ad->unlock();
//ad->unlock();
for(int i = 0; i < frames * ad->channels; i++) {
@ -134,6 +143,9 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
};
};
if (ad->mutex)
ad->mutex->unlock();
return 0;
};
@ -149,12 +161,27 @@ AudioDriverSW::OutputFormat AudioDriverOSX::get_output_format() const {
return OUTPUT_STEREO;
};
void AudioDriverOSX::lock() {};
void AudioDriverOSX::unlock() {};
void AudioDriverOSX::lock() {
if (active && mutex)
mutex->lock();
};
void AudioDriverOSX::unlock() {
if (active && mutex)
mutex->unlock();
};
void AudioDriverOSX::finish() {
memdelete_arr(samples_in);
};
AudioDriverOSX::AudioDriverOSX() {
mutex=Mutex::create();//NULL;
};
AudioDriverOSX::~AudioDriverOSX() {
};
#endif

View file

@ -39,6 +39,7 @@ class AudioDriverOSX : public AudioDriverSW {
AudioComponentInstance audio_unit;
bool active;
Mutex *mutex;
int channels;
int32_t* samples_in;
@ -64,6 +65,9 @@ public:
virtual void lock();
virtual void unlock();
virtual void finish();
AudioDriverOSX();
~AudioDriverOSX();
};
#endif

View file

@ -209,6 +209,16 @@ def configure(env):
env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DGLES2_ENABLED','-DGLES1_ENABLED','-DGLEW_ENABLED'])
env.Append(LIBS=['mingw32','opengl32', 'dsound', 'ole32', 'd3d9','winmm','gdi32','iphlpapi','wsock32','kernel32'])
if (env["bits"]=="32" and env["mingw64_for_32"]!="yes"):
# env.Append(LIBS=['gcc_s'])
#--with-arch=i686
env.Append(CPPFLAGS=['-march=i686'])
env.Append(LINKFLAGS=['-march=i686'])
#'d3dx9d'
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
env.Append(LINKFLAGS=['-g'])

View file

@ -156,13 +156,13 @@ bool CollisionObject2D::_get(const StringName& p_name,Variant &r_ret) const {
void CollisionObject2D::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
for(int i=0;i<shapes.size();i++) {
String path="shapes/"+itos(i)+"/";
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape2D",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
}
}

View file

@ -44,7 +44,6 @@
void CollisionShape::_update_body() {
if (get_parent() && get_parent()->cast_to<CollisionObject>())
get_parent()->cast_to<CollisionObject>()->_update_shapes_from_children();
@ -72,7 +71,7 @@ void CollisionShape::make_convex_from_brothers() {
}
}
/*
void CollisionShape::_update_indicator() {
@ -300,9 +299,12 @@ void CollisionShape::_update_indicator() {
}
*/
void CollisionShape::_add_to_collision_object(Object* p_cshape) {
if (unparenting)
return;
CollisionObject *co=p_cshape->cast_to<CollisionObject>();
ERR_FAIL_COND(!co);
@ -318,22 +320,25 @@ void CollisionShape::_notification(int p_what) {
switch(p_what) {
case NOTIFICATION_ENTER_WORLD: {
indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
case NOTIFICATION_ENTER_SCENE: {
unparenting=false;
//indicator_instance = VisualServer::get_singleton()->instance_create2(indicator,get_world()->get_scenario());
} break;
case NOTIFICATION_TRANSFORM_CHANGED: {
VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
// VisualServer::get_singleton()->instance_set_transform(indicator_instance,get_global_transform());
if (updating_body) {
_update_body();
}
} break;
case NOTIFICATION_EXIT_WORLD: {
if (indicator_instance.is_valid()) {
case NOTIFICATION_EXIT_SCENE: {
/* if (indicator_instance.is_valid()) {
VisualServer::get_singleton()->free(indicator_instance);
indicator_instance=RID();
}
}*/
} break;
case NOTIFICATION_UNPARENTED: {
unparenting=true;
if (updating_body)
_update_body();
} break;
@ -411,15 +416,16 @@ bool CollisionShape::is_trigger() const{
CollisionShape::CollisionShape() {
indicator = VisualServer::get_singleton()->mesh_create();
//indicator = VisualServer::get_singleton()->mesh_create();
updating_body=true;
unparenting=false;
trigger=false;
}
CollisionShape::~CollisionShape() {
if (!shape.is_null())
shape->unregister_owner(this);
VisualServer::get_singleton()->free(indicator);
//VisualServer::get_singleton()->free(indicator);
}
#if 0

View file

@ -37,19 +37,23 @@ class CollisionShape : public Spatial {
OBJ_TYPE( CollisionShape, Spatial );
OBJ_CATEGORY("3D Physics Nodes");
Ref<Shape> shape;
/*
RID _get_visual_instance_rid() const;
Ref<Shape> shape;
void _update_indicator();
RID material;
RID indicator;
RID indicator_instance;
*/
void resource_changed(RES res);
bool updating_body;
bool unparenting;
bool trigger;
void _update_body();

View file

@ -160,13 +160,13 @@ bool CollisionObject::_get(const StringName& p_name,Variant &r_ret) const {
void CollisionObject::_get_property_list( List<PropertyInfo> *p_list) const {
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::INT,"shape_count",PROPERTY_HINT_RANGE,"0,256,1",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
for(int i=0;i<shapes.size();i++) {
String path="shapes/"+itos(i)+"/";
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) );
p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR|PROPERTY_USAGE_NO_INSTANCE_STATE) );
}
}

View file

@ -50,7 +50,7 @@ void InterpolatedCamera::_notification(int p_what) {
float delta = speed*get_process_delta_time();
Transform target_xform = node->get_global_transform();
Transform local_transform = get_transform();
Transform local_transform = get_global_transform();
local_transform = local_transform.interpolate_with(target_xform,delta);
set_global_transform(local_transform);
@ -136,7 +136,7 @@ void InterpolatedCamera::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_target_path","target_path"),&InterpolatedCamera::set_target_path);
ObjectTypeDB::bind_method(_MD("get_target_path"),&InterpolatedCamera::get_target_path);
ObjectTypeDB::bind_method(_MD("set_target","target"),&InterpolatedCamera::_set_target);
ObjectTypeDB::bind_method(_MD("set_target","target:Camera"),&InterpolatedCamera::_set_target);
ObjectTypeDB::bind_method(_MD("set_speed","speed"),&InterpolatedCamera::set_speed);
ObjectTypeDB::bind_method(_MD("get_speed"),&InterpolatedCamera::get_speed);

View file

@ -346,6 +346,8 @@ bool BaseButton::get_click_on_press() const {
}
void BaseButton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_input_event"),&BaseButton::_input_event);
@ -358,6 +360,7 @@ void BaseButton::_bind_methods() {
ObjectTypeDB::bind_method(_MD("is_disabled"),&BaseButton::is_disabled);
ObjectTypeDB::bind_method(_MD("set_click_on_press","enable"),&BaseButton::set_click_on_press);
ObjectTypeDB::bind_method(_MD("get_click_on_press"),&BaseButton::get_click_on_press);
ObjectTypeDB::bind_method(_MD("get_draw_mode"),&BaseButton::get_draw_mode);
ADD_SIGNAL( MethodInfo("pressed" ) );
ADD_SIGNAL( MethodInfo("toggled", PropertyInfo( Variant::BOOL,"pressed") ) );
@ -365,6 +368,11 @@ void BaseButton::_bind_methods() {
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "toggle_mode"), _SCS("set_toggle_mode"), _SCS("is_toggle_mode"));
ADD_PROPERTY( PropertyInfo( Variant::BOOL, "click_on_press"), _SCS("set_click_on_press"), _SCS("get_click_on_press"));
BIND_CONSTANT( DRAW_NORMAL );
BIND_CONSTANT( DRAW_PRESSED );
BIND_CONSTANT( DRAW_HOVER );
BIND_CONSTANT( DRAW_DISABLED );
}
BaseButton::BaseButton() {

View file

@ -61,15 +61,8 @@ class BaseButton : public Control {
protected:
enum DrawMode {
DRAW_NORMAL,
DRAW_PRESSED,
DRAW_HOVER,
DRAW_DISABLED,
};
DrawMode get_draw_mode() const;
virtual void pressed();
virtual void toggled(bool p_pressed);
@ -78,7 +71,16 @@ protected:
void _notification(int p_what);
public:
enum DrawMode {
DRAW_NORMAL,
DRAW_PRESSED,
DRAW_HOVER,
DRAW_DISABLED,
};
DrawMode get_draw_mode() const;
/* Signals */
bool is_pressed() const; ///< return wether button is pressed (toggled in)
@ -101,4 +103,6 @@ public:
};
VARIANT_ENUM_CAST( BaseButton::DrawMode );
#endif

View file

@ -45,20 +45,15 @@ void VideoPlayer::_notification(int p_notification) {
return;
if (paused)
return;
if (!stream->is_playing())
return;
stream->update(get_scene()->get_idle_process_time());
while (stream->get_pending_frame_count()) {
Image img = stream->pop_frame();
if (texture->get_width() == 0) {
texture->create(img.get_width(),img.get_height(),img.get_format(),Texture::FLAG_VIDEO_SURFACE|Texture::FLAG_FILTER);
update();
minimum_size_changed();
} else {
if (stream->get_pending_frame_count() == 0)
texture->set_data(img);
};
int prev_width = texture->get_width();
stream->pop_frame(texture);
if (prev_width == 0) {
update();
minimum_size_changed();
};
} break;
@ -257,9 +252,9 @@ void VideoPlayer::_bind_methods() {
VideoPlayer::VideoPlayer() {
volume=1;
loops=false;
paused=false;
autoplay=false;
loops = false;
paused = false;
autoplay = false;
expand = true;
loops = false;
};

View file

@ -131,14 +131,55 @@ RES ResourceFormatLoaderImage::load(const String &p_path,const String& p_origina
uint32_t flags=0;
if (bool(GLOBAL_DEF("image_loader/filter",true)))
FileAccess *f2 = FileAccess::open(p_path+".flags",FileAccess::READ);
Map<String,bool> flags_found;
if (f2) {
while(!f2->eof_reached()) {
String l2 = f2->get_line();
int eqpos = l2.find("=");
if (eqpos!=-1) {
String flag=l2.substr(0,eqpos).strip_edges();
String val=l2.substr(eqpos+1,l2.length()).strip_edges().to_lower();
flags_found[flag]=(val=="true" || val=="1")?true:false;
}
}
memdelete(f2);
}
if (flags_found.has("filter")) {
if (flags_found["filter"])
flags|=Texture::FLAG_FILTER;
} else if (bool(GLOBAL_DEF("image_loader/filter",true))) {
flags|=Texture::FLAG_FILTER;
if (bool(GLOBAL_DEF("image_loader/gen_mipmaps",true)))
}
if (flags_found.has("gen_mipmaps")) {
if (flags_found["gen_mipmaps"])
flags|=Texture::FLAG_MIPMAPS;
} else if (bool(GLOBAL_DEF("image_loader/gen_mipmaps",true))) {
flags|=Texture::FLAG_MIPMAPS;
if (bool(GLOBAL_DEF("image_loader/repeat",false)))
}
if (flags_found.has("repeat")) {
if (flags_found["repeat"])
flags|=Texture::FLAG_REPEAT;
} else if (bool(GLOBAL_DEF("image_loader/repeat",true))) {
flags|=Texture::FLAG_REPEAT;
}
if (flags_found.has("anisotropic")) {
if (flags_found["anisotropic"])
flags|=Texture::FLAG_ANISOTROPIC_FILTER;
}
if (flags_found.has("tolinear")) {
if (flags_found["tolinear"])
flags|=Texture::FLAG_CONVERT_TO_LINEAR;
}
if (debug_load_times)
begtime=OS::get_singleton()->get_ticks_usec();

View file

@ -1234,7 +1234,7 @@ void Node::generate_instance_state() {
for( List<PropertyInfo>::Element *E=properties.front();E;E=E->next() ) {
PropertyInfo &pi=E->get();
if (!(pi.usage&PROPERTY_USAGE_EDITOR) || !(pi.usage&PROPERTY_USAGE_STORAGE))
if ((pi.usage&PROPERTY_USAGE_NO_INSTANCE_STATE) || !(pi.usage&PROPERTY_USAGE_EDITOR) || !(pi.usage&PROPERTY_USAGE_STORAGE))
continue;
data.instance_state[pi.name]=get(pi.name);
@ -1424,6 +1424,20 @@ Node *Node::duplicate_and_reown(const Map<Node*,Node*>& p_reown_map) const {
node->set_name(get_name());
List<PropertyInfo> plist;
get_property_list(&plist);
for(List<PropertyInfo>::Element *E=plist.front();E;E=E->next()) {
if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
continue;
String name = E->get().name;
node->set( name, get(name) );
}
for(int i=0;i<get_child_count();i++) {
get_child(i)->_duplicate_and_reown(node,p_reown_map);

View file

@ -243,7 +243,7 @@ void Viewport::update_worlds() {
void Viewport::_test_new_mouseover(ObjectID new_collider) {
#ifndef _3D_DISABLED
if (new_collider!=physics_object_over) {
if (physics_object_over) {
@ -271,7 +271,7 @@ void Viewport::_test_new_mouseover(ObjectID new_collider) {
physics_object_over=new_collider;
}
#endif
}
@ -353,7 +353,7 @@ void Viewport::_notification(int p_what) {
case NOTIFICATION_FIXED_PROCESS: {
if (physics_object_picking) {
#ifndef _3D_DISABLED
Vector2 last_pos(1e20,1e20);
CollisionObject *last_object;
ObjectID last_id=0;
@ -499,6 +499,7 @@ void Viewport::_notification(int p_what) {
}
}
#endif
}
} break;

View file

@ -397,6 +397,13 @@ void register_scene_types() {
ObjectTypeDB::register_type<BakedLightSampler>();
ObjectTypeDB::register_type<WorldEnvironment>();
ObjectTypeDB::register_virtual_type<Joint>();
ObjectTypeDB::register_type<PinJoint>();
ObjectTypeDB::register_type<HingeJoint>();
ObjectTypeDB::register_type<SliderJoint>();
ObjectTypeDB::register_type<ConeTwistJoint>();
ObjectTypeDB::register_type<Generic6DOFJoint>();
//scenariofx
OS::get_singleton()->yield(); //may take time to init
@ -405,6 +412,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<SpatialStreamPlayer>();
ObjectTypeDB::register_type<SoundRoomParams>();
#endif
ObjectTypeDB::register_type<MeshLibrary>();
AcceptDialog::set_swap_ok_cancel( GLOBAL_DEF("display/swap_ok_cancel",bool(OS::get_singleton()->get_swap_ok_cancel())) );
@ -422,12 +430,6 @@ void register_scene_types() {
//ObjectTypeDB::register_type<PhysicsJointPin>();
ObjectTypeDB::register_virtual_type<Joint>();
ObjectTypeDB::register_type<PinJoint>();
ObjectTypeDB::register_type<HingeJoint>();
ObjectTypeDB::register_type<SliderJoint>();
ObjectTypeDB::register_type<ConeTwistJoint>();
ObjectTypeDB::register_type<Generic6DOFJoint>();
ObjectTypeDB::register_type<StreamPlayer>();

View file

@ -1266,7 +1266,7 @@ T Animation::_interpolate( const Vector< TKey<T> >& p_keys, float p_time, Inter
}
} else { // no loop
if (idx>=0) {
if ((idx+1) < len) {

View file

@ -743,6 +743,225 @@ Ref<TriangleMesh> Mesh::generate_triangle_mesh() const {
}
Ref<Mesh> Mesh::create_outline(float p_margin) const {
Array arrays;
int index_accum=0;
for(int i=0;i<get_surface_count();i++) {
if (surface_get_primitive_type(i)!=PRIMITIVE_TRIANGLES)
continue;
Array a = surface_get_arrays(i);
int vcount=0;
if (i==0) {
arrays=a;
DVector<Vector3> v=a[ARRAY_VERTEX];
index_accum+=v.size();
} else {
for(int j=0;j<arrays.size();j++) {
if (arrays[j].get_type()==Variant::NIL || a[j].get_type()==Variant::NIL) {
//mismatch, do not use
arrays[j]=Variant();
continue;
}
switch(j) {
case ARRAY_VERTEX:
case ARRAY_NORMAL: {
DVector<Vector3> dst = arrays[j];
DVector<Vector3> src = a[j];
if (j==ARRAY_VERTEX)
vcount=src.size();
if (dst.size()==0 || src.size()==0) {
arrays[j]=Variant();
continue;
}
dst.append_array(src);
arrays[j]=dst;
} break;
case ARRAY_TANGENT:
case ARRAY_BONES:
case ARRAY_WEIGHTS: {
DVector<real_t> dst = arrays[j];
DVector<real_t> src = a[j];
if (dst.size()==0 || src.size()==0) {
arrays[j]=Variant();
continue;
}
dst.append_array(src);
arrays[j]=dst;
} break;
case ARRAY_COLOR: {
DVector<Color> dst = arrays[j];
DVector<Color> src = a[j];
if (dst.size()==0 || src.size()==0) {
arrays[j]=Variant();
continue;
}
dst.append_array(src);
arrays[j]=dst;
} break;
case ARRAY_TEX_UV:
case ARRAY_TEX_UV2: {
DVector<Vector2> dst = arrays[j];
DVector<Vector2> src = a[j];
if (dst.size()==0 || src.size()==0) {
arrays[j]=Variant();
continue;
}
dst.append_array(src);
arrays[j]=dst;
} break;
case ARRAY_INDEX: {
DVector<int> dst = arrays[j];
DVector<int> src = a[j];
if (dst.size()==0 || src.size()==0) {
arrays[j]=Variant();
continue;
}
{
int ss = src.size();
DVector<int>::Write w = src.write();
for(int k=0;k<ss;k++) {
w[k]+=index_accum;
}
}
dst.append_array(src);
arrays[j]=dst;
index_accum+=vcount;
} break;
}
}
}
}
{
int tc=0;
DVector<int>::Write ir;
DVector<int> indices =arrays[ARRAY_INDEX];
bool has_indices=false;
DVector<Vector3> vertices =arrays[ARRAY_VERTEX];
int vc = vertices.size();
ERR_FAIL_COND_V(!vc,Ref<Mesh>());
DVector<Vector3>::Write r=vertices.write();
if (indices.size()) {
vc=indices.size();
ir=indices.write();
has_indices=true;
}
Map<Vector3,Vector3> normal_accum;
//fill normals with triangle normals
for(int i=0;i<vc;i+=3) {
Vector3 t[3];
if (has_indices) {
t[0]=r[ir[i+0]];
t[1]=r[ir[i+1]];
t[2]=r[ir[i+2]];
} else {
t[0]=r[i+0];
t[1]=r[i+1];
t[2]=r[i+2];
}
Vector3 n = Plane(t[0],t[1],t[2]).normal;
for(int j=0;j<3;j++) {
Map<Vector3,Vector3>::Element *E=normal_accum.find(t[j]);
if (!E) {
normal_accum[t[j]]=n;
} else {
float d = n.dot(E->get());
if (d<1.0)
E->get()+=n*(1.0-d);
//E->get()+=n;
}
}
}
//normalize
for (Map<Vector3,Vector3>::Element *E=normal_accum.front();E;E=E->next()) {
E->get().normalize();
}
//displace normals
int vc2 = vertices.size();
for(int i=0;i<vc2;i++) {
Vector3 t=r[i];
Map<Vector3,Vector3>::Element *E=normal_accum.find(t);
ERR_CONTINUE(!E);
t+=E->get()*p_margin;
r[i]=t;
}
r = DVector<Vector3>::Write();
arrays[ARRAY_VERTEX]=vertices;
if (!has_indices) {
DVector<int> new_indices;
new_indices.resize(vertices.size());
DVector<int>::Write iw = new_indices.write();
for(int j=0;j<vc2;j+=3) {
iw[j]=j;
iw[j+1]=j+2;
iw[j+2]=j+1;
}
iw=DVector<int>::Write();
arrays[ARRAY_INDEX]=new_indices;
} else {
for(int j=0;j<vc;j+=3) {
SWAP(ir[j+1],ir[j+2]);
}
ir=DVector<int>::Write();
arrays[ARRAY_INDEX]=indices;
}
}
Ref<Mesh> newmesh = memnew( Mesh );
newmesh->add_surface(PRIMITIVE_TRIANGLES,arrays);
return newmesh;
}
void Mesh::_bind_methods() {
ObjectTypeDB::bind_method(_MD("add_morph_target","name"),&Mesh::add_morph_target);

View file

@ -166,6 +166,8 @@ public:
Ref<Shape> create_trimesh_shape() const;
Ref<Shape> create_convex_shape() const;
Ref<Mesh> create_outline(float p_margin) const;
void center_geometry();
void regen_normalmaps();

View file

@ -272,6 +272,10 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map<
continue;
}*/
if (E->get().usage & PROPERTY_USAGE_NO_INSTANCE_STATE) {
continue;
}
if (instance_state[name]==value) {
continue;
}

View file

@ -30,7 +30,7 @@
#define VIDEO_STREAM_H
#include "audio_stream_resampled.h"
#include "scene/resources/texture.h"
class VideoStream : public Resource {
@ -59,7 +59,7 @@ public:
virtual void seek_pos(float p_time)=0;
virtual int get_pending_frame_count() const=0;
virtual Image pop_frame()=0;
virtual void pop_frame(Ref<ImageTexture> p_tex)=0;
virtual Image peek_frame() const=0;
virtual void update(float p_time)=0;

View file

@ -65,7 +65,13 @@ void Body2DSW::update_inertias() {
float mass = area * this->mass / total_area;
_inertia += shape->get_moment_of_inertia(mass) + mass * get_shape_transform(i).get_origin().length_squared();
Matrix32 mtx = get_shape_transform(i);
Vector2 scale = mtx.get_scale();
_inertia += shape->get_moment_of_inertia(mass,scale) + mass * mtx.get_origin().length_squared();
//Rect2 ab = get_shape_aabb(i);
//_inertia+=mass*ab.size.dot(ab.size)/12.0f;
}

View file

@ -1086,6 +1086,7 @@ static void _collision_rectangle_convex_polygon(const Shape2DSW* p_a,const Matri
SeparatorAxisTest2D<RectangleShape2DSW,ConvexPolygonShape2DSW,castA,castB,withMargin> separator(rectangle_A,p_transform_a,convex_B,p_transform_b,p_collector,p_motion_a,p_motion_b,p_margin_A,p_margin_B);
if (!separator.test_previous_axis())
return;

View file

@ -131,7 +131,7 @@ bool LineShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_en
return true;
}
real_t LineShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t LineShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale) const {
return 0;
}
@ -180,7 +180,7 @@ bool RayShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_end
}
real_t RayShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t RayShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale) const {
return 0; //rays are mass-less
}
@ -237,10 +237,12 @@ bool SegmentShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p
return true;
}
real_t SegmentShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t SegmentShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale) const {
real_t l = b.distance_to(a);
Vector2 ofs = (a+b)*0.5;
Vector2 s[2]={a*p_scale,b*p_scale};
real_t l = s[1].distance_to(s[0]);
Vector2 ofs = (s[0]+s[1])*0.5;
return p_mass*(l*l/12.0f + ofs.length_squared());
}
@ -312,9 +314,10 @@ bool CircleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p_
return true;
}
real_t CircleShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t CircleShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale) const {
return (radius*radius)*(p_scale.x*0.5+p_scale.y*0.5);
return radius*radius;
}
void CircleShape2DSW::set_data(const Variant& p_data) {
@ -377,9 +380,9 @@ bool RectangleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2&
return get_aabb().intersects_segment(p_begin,p_end,&r_point,&r_normal);
}
real_t RectangleShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t RectangleShape2DSW::get_moment_of_inertia(float p_mass,const Vector2& p_scale) const {
Vector2 he2=half_extents*2;
Vector2 he2=half_extents*2*p_scale;
return p_mass*he2.dot(he2)/12.0f;
}
@ -499,9 +502,9 @@ bool CapsuleShape2DSW::intersect_segment(const Vector2& p_begin,const Vector2& p
return collided; //todo
}
real_t CapsuleShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t CapsuleShape2DSW::get_moment_of_inertia(float p_mass, const Vector2 &p_scale) const {
Vector2 he2(radius*2,height+radius*2);
Vector2 he2=Vector2(radius*2,height+radius*2)*p_scale;
return p_mass*he2.dot(he2)/12.0f;
}
@ -610,16 +613,16 @@ bool ConvexPolygonShape2DSW::intersect_segment(const Vector2& p_begin,const Vect
return inters; //todo
}
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(float p_mass) const {
real_t ConvexPolygonShape2DSW::get_moment_of_inertia(float p_mass,const Vector2& p_scale) const {
Rect2 aabb;
aabb.pos=points[0].pos;
aabb.pos=points[0].pos*p_scale;
for(int i=0;i<point_count;i++) {
aabb.expand_to(points[i].pos);
aabb.expand_to(points[i].pos*p_scale);
}
return p_mass*aabb.size.dot(aabb.size)/12.0f;
return p_mass*aabb.size.dot(aabb.size)/12.0f + p_mass * (aabb.pos+aabb.size*0.5).length_squared();
}
void ConvexPolygonShape2DSW::set_data(const Variant& p_data) {

View file

@ -84,7 +84,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const=0;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const=0;
virtual real_t get_moment_of_inertia(float p_mass) const=0;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const=0;
virtual void set_data(const Variant& p_data)=0;
virtual Variant get_data() const=0;
@ -173,7 +173,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -215,7 +215,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -262,7 +262,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -299,7 +299,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -338,20 +338,25 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
_FORCE_INLINE_ void project_range(const Vector2& p_normal, const Matrix32& p_transform, real_t &r_min, real_t &r_max) const {
// no matter the angle, the box is mirrored anyway
Vector2 local_normal=p_transform.basis_xform_inv(p_normal);
r_max=-1e20;
r_min=1e20;
for(int i=0;i<4;i++) {
float length = local_normal.abs().dot(half_extents);
float distance = p_normal.dot( p_transform.get_origin() );
real_t d=p_normal.dot(p_transform.xform(Vector2( ((i&1)*2-1)*half_extents.x, ((i>>1)*2-1)*half_extents.y )));
r_min = distance - length;
r_max = distance + length;
if (d>r_max)
r_max=d;
if (d<r_min)
r_min=d;
}
}
@ -420,7 +425,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -482,7 +487,7 @@ public:
virtual void get_supports(const Vector2& p_normal,Vector2 *r_supports,int & r_amount) const;
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const;
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const;
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;
@ -570,7 +575,7 @@ public:
virtual bool intersect_segment(const Vector2& p_begin,const Vector2& p_end,Vector2 &r_point, Vector2 &r_normal) const;
virtual real_t get_moment_of_inertia(float p_mass) const { return 0; }
virtual real_t get_moment_of_inertia(float p_mass,const Vector2& p_scale) const { return 0; }
virtual void set_data(const Variant& p_data);
virtual Variant get_data() const;

View file

@ -5621,7 +5621,7 @@ void VisualServerRaster::_process_sampled_light(const Transform& p_camera,Instan
if (distance>r)
distance=r;
float mult = powf(1.0-distance/r,att)*str;
float mult = Math::pow(1.0-distance/r,att)*str;
if (mult>0) {
col.r*=mult;
col.g*=mult;

View file

@ -1310,6 +1310,8 @@ void EditorNode::_edit_current() {
p->add_item("Copy Params",OBJECT_COPY_PARAMS);
p->add_item("Set Params",OBJECT_PASTE_PARAMS);
p->add_separator();
p->add_item("Make Resources Unique",OBJECT_UNIQUE_RESOURCES);
p->add_separator();
p->add_icon_item(gui_base->get_icon("Help","EditorIcons"),"Class Reference",OBJECT_REQUEST_HELP);
List<MethodInfo> methods;
current_obj->get_method_list(&methods);
@ -2023,6 +2025,47 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
editor_data.paste_object_params(current);
editor_data.get_undo_redo().clear_history();
} break;
case OBJECT_UNIQUE_RESOURCES: {
editor_data.apply_changes_in_editors();;
if (current) {
List<PropertyInfo> props;
current->get_property_list(&props);
Map<RES,RES> duplicates;
for (List<PropertyInfo>::Element *E=props.front();E;E=E->next()) {
if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
continue;
Variant v = current->get(E->get().name);
if (v.is_ref()) {
REF ref = v;
if (ref.is_valid()) {
RES res = ref;
if (res.is_valid()) {
if (!duplicates.has(res)) {
duplicates[res]=res->duplicate();
}
res=duplicates[res];
current->set(E->get().name,res);
}
}
}
}
}
editor_data.get_undo_redo().clear_history();
if (editor_plugin_screen) { //reload editor plugin
editor_plugin_over->edit(NULL);
editor_plugin_over->edit(current);
}
} break;
case OBJECT_CALL_METHOD: {
editor_data.apply_changes_in_editors();;
@ -3950,8 +3993,8 @@ EditorNode::EditorNode() {
Ref<EditorSceneImportPlugin> _scene_import = memnew(EditorSceneImportPlugin(this) );
Ref<EditorSceneImporterCollada> _collada_import = memnew( EditorSceneImporterCollada);
_scene_import->add_importer(_collada_import);
Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
_scene_import->add_importer(_fbxconv_import);
// Ref<EditorSceneImporterFBXConv> _fbxconv_import = memnew( EditorSceneImporterFBXConv);
// _scene_import->add_importer(_fbxconv_import);
editor_import_export->add_import_plugin( _scene_import);
editor_import_export->add_import_plugin( Ref<EditorSceneAnimationImportPlugin>( memnew(EditorSceneAnimationImportPlugin(this))));
editor_import_export->add_import_plugin( Ref<EditorMeshImportPlugin>( memnew(EditorMeshImportPlugin(this))));

View file

@ -133,6 +133,7 @@ class EditorNode : public Node {
RESOURCE_COPY,
OBJECT_COPY_PARAMS,
OBJECT_PASTE_PARAMS,
OBJECT_UNIQUE_RESOURCES,
OBJECT_CALL_METHOD,
OBJECT_REQUEST_HELP,
RUN_PLAY,

View file

@ -61,6 +61,7 @@ struct ColladaImport {
Color ambient;
bool found_directional;
bool force_make_tangents;
float bake_fps;
@ -95,6 +96,7 @@ struct ColladaImport {
found_ambient=false;
found_directional=false;
force_make_tangents=false;
bake_fps=15;
}
};
@ -1835,7 +1837,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
Vector<float> base_snapshots;
float f=0;
float snapshot_interval = 1.0/20.0; //should be customizable somewhere...
float snapshot_interval = 1.0/bake_fps; //should be customizable somewhere...
float anim_length=collada.state.animation_length;
if (p_clip>=0 && collada.state.animation_clips[p_clip].end)
@ -2142,14 +2144,14 @@ void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) cons
r_extensions->push_back("dae");
}
Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags, List<String> *r_missing_deps, Error* r_err) {
Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags,int p_bake_fps, List<String> *r_missing_deps, Error* r_err) {
ColladaImport state;
uint32_t flags=Collada::IMPORT_FLAG_SCENE;
if (p_flags&IMPORT_ANIMATION)
flags|=Collada::IMPORT_FLAG_ANIMATION;
state.bake_fps=p_bake_fps;
Error err = state.load(p_path,flags,p_flags&EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS);
@ -2174,7 +2176,7 @@ Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_
if (p_flags&IMPORT_ANIMATION) {
state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
state.create_animations(p_flags&IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
AnimationPlayer *ap = memnew( AnimationPlayer );
for(int i=0;i<state.animations.size();i++) {
String name;
@ -2213,7 +2215,7 @@ Ref<Animation> EditorSceneImporterCollada::import_animation(const String& p_path
ERR_FAIL_COND_V(err!=OK,RES());
state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
state.create_animations(p_flags&EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
if (state.scene)
memdelete(state.scene);

View file

@ -40,7 +40,7 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps=NULL,Error* r_err=NULL);
virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps=NULL,Error* r_err=NULL);
virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags);
EditorSceneImporterCollada();

View file

@ -425,7 +425,7 @@ Error EditorMeshImportPlugin::import(const String& p_path, const Ref<ResourceImp
ERR_FAIL_COND_V(v.size()<3,ERR_INVALID_DATA);
Vector2 uv;
uv.x=v[1].to_float();
uv.y=v[2].to_float();
uv.y=1.0-v[2].to_float();
uvs.push_back(uv);
} else if (l.begins_with("vn ")) {

View file

@ -78,12 +78,23 @@ class EditorImportAnimationOptions : public VBoxContainer {
OBJ_TYPE( EditorImportAnimationOptions, VBoxContainer );
TreeItem *fps;
TreeItem *clips_base;
TextEdit *filters;
Vector<TreeItem*> clips;
Tree *flags;
Tree *clips_tree;
Vector<TreeItem*> items;
bool updating;
bool validating;
void _changed();
void _item_edited();
void _button_action(Object *p_obj,int p_col,int p_id);
protected:
static void _bind_methods();
void _notification(int p_what);
@ -93,6 +104,14 @@ public:
void set_flags(uint32_t p_flags);
uint32_t get_flags() const;
void set_fps(int p_fps);
int get_fps() const;
void setup_clips(const Array& p_clips);
Array get_clips() const;
void set_filter(const String& p_filter);
String get_filter() const;
EditorImportAnimationOptions();
@ -141,6 +160,9 @@ class EditorSceneImportDialog : public ConfirmationDialog {
Map<Ref<Mesh>,Ref<Shape> > collision_map;
ConfirmationDialog *error_dialog;
OptionButton *this_import;
OptionButton *next_import;
void _choose_file(const String& p_path);
void _choose_save_file(const String& p_path);
void _choose_script(const String& p_path);
@ -178,7 +200,7 @@ static const char *anim_flag_names[]={
"Detect Loop (-loop,-cycle)",
"Keep Value Tracks",
"Optimize",
"Force Tracks in All Bones",
"Force All Tracks in All Clips",
NULL
};
@ -223,9 +245,101 @@ void EditorImportAnimationOptions::_changed() {
}
void EditorImportAnimationOptions::_button_action(Object *p_obj,int p_col,int p_id) {
memdelete(p_obj);
}
void EditorImportAnimationOptions::_item_edited() {
if (validating)
return;
if (clips.size()==0)
return;
validating=true;
print_line("edited");
TreeItem *item = clips_tree->get_edited();
if (item==clips[clips.size()-1]) {
//add new
print_line("islast");
if (item->get_text(0).find("<")!=-1 || item->get_text(0).find(">")!=-1) {
validating=false;
return; //fuckit
}
item->set_editable(1,true);
item->set_editable(2,true);
item->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons"));
item->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
item->set_range_config(1,0,3600,0.01);
item->set_range(1,0);
item->set_editable(1,true);
item->set_cell_mode(2,TreeItem::CELL_MODE_RANGE);
item->set_range_config(2,0,3600,0.01);
item->set_range(2,0);
item->set_cell_mode(3,TreeItem::CELL_MODE_CHECK);
item->set_editable(3,true);
TreeItem *newclip = clips_tree->create_item(clips_base);
newclip->set_text(0,"<new clip>");
newclip->set_editable(0,true);
newclip->set_editable(1,false);
newclip->set_editable(2,false);
clips.push_back(newclip);
}
//make name unique JUST IN CASE
String name = item->get_text(0);
name=name.replace("/","_").replace(":","_").strip_edges();
if (name=="")
name="New Clip";
if (clips.size()>2) {
int index=1;
while(true) {
bool valid = true;
String try_name=name;
if (index>1)
try_name+=" "+itos(index);
for(int i=0;i<clips.size()-1;i++) {
if (clips[i]==item)
continue;
if (clips[i]->get_text(0)==try_name) {
index++;
valid=false;
break;
}
}
if (valid) {
name=try_name;
break;
}
}
}
if (item->get_text(0)!=name)
item->set_text(0,name);
validating=false;
}
void EditorImportAnimationOptions::_bind_methods() {
ObjectTypeDB::bind_method("_changed",&EditorImportAnimationOptions::_changed);
ObjectTypeDB::bind_method("_item_edited",&EditorImportAnimationOptions::_item_edited);
ObjectTypeDB::bind_method("_button_action",&EditorImportAnimationOptions::_button_action);
// ObjectTypeDB::bind_method("_changedp",&EditorImportAnimationOptions::_changedp);
ADD_SIGNAL(MethodInfo("changed"));
@ -237,17 +351,84 @@ void EditorImportAnimationOptions::_notification(int p_what) {
if (p_what==NOTIFICATION_ENTER_SCENE) {
flags->connect("item_edited",this,"_changed");
clips_tree->connect("item_edited",this,"_item_edited");
clips_tree->connect("button_pressed",this,"_button_action",varray(),CONNECT_DEFERRED);
// format->connect("item_selected",this,"_changedp");
}
}
Array EditorImportAnimationOptions::get_clips() const {
Array arr;
for(int i=0;i<clips.size()-1;i++) {
arr.push_back(clips[i]->get_text(0));
arr.push_back(clips[i]->get_range(1));
arr.push_back(clips[i]->get_range(2));
arr.push_back(clips[i]->is_checked(3));
}
return arr;
}
void EditorImportAnimationOptions::setup_clips(const Array& p_clips) {
ERR_FAIL_COND(p_clips.size()%4!=0);
for(int i=0;i<clips.size();i++) {
memdelete(clips[i]);
}
clips.clear();
for(int i=0;i<p_clips.size();i+=4) {
TreeItem *clip = clips_tree->create_item(clips_base);
clip->set_text(0,p_clips[i]);
clip->add_button(0,EditorNode::get_singleton()->get_gui_base()->get_icon("Del","EditorIcons"));
clip->set_editable(0,true);
clip->set_cell_mode(1,TreeItem::CELL_MODE_RANGE);
clip->set_range_config(1,0,3600,0.01);
clip->set_range(1,p_clips[i+1]);
clip->set_editable(1,true);
clip->set_cell_mode(2,TreeItem::CELL_MODE_RANGE);
clip->set_range_config(2,0,3600,0.01);
clip->set_range(2,p_clips[i+2]);
clip->set_editable(2,true);
clip->set_cell_mode(3,TreeItem::CELL_MODE_CHECK);
clip->set_editable(3,true);
clip->set_checked(3,p_clips[i+3]);
clips.push_back(clip);
}
TreeItem *newclip = clips_tree->create_item(clips_base);
newclip->set_text(0,"<new clip>");
newclip->set_editable(0,true);
newclip->set_editable(1,false);
newclip->set_editable(2,false);
newclip->set_editable(3,false);
clips.push_back(newclip);
}
EditorImportAnimationOptions::EditorImportAnimationOptions() {
updating=false;
validating=false;
TabContainer *tab= memnew(TabContainer);
add_margin_child("Animation Options",tab,true);
flags = memnew( Tree );
flags->set_hide_root(true);
tab->add_child(flags);
flags->set_name("Flags");
TreeItem *root = flags->create_item();
const char ** fname=anim_flag_names;
@ -263,15 +444,70 @@ EditorImportAnimationOptions::EditorImportAnimationOptions() {
items.push_back(ti);
fname++;
fdescr++;
}
}
add_margin_child("Animation Options",flags,true);
TreeItem *fps_base = flags->create_item(root);
fps_base->set_text(0,"Bake FPS:");
fps_base->set_editable(0,false);
fps = flags->create_item(fps_base);
fps->set_cell_mode(0,TreeItem::CELL_MODE_RANGE);
fps->set_editable(0,true);
fps->set_range(0,15);
fps->set_range_config(0,1,120,1);
clips_tree = memnew( Tree );
clips_tree->set_hide_root(true);
tab->add_child(clips_tree);
clips_tree->set_name("Clips");
clips_tree->set_columns(4);
clips_tree->set_column_expand(0,1);
clips_tree->set_column_expand(1,0);
clips_tree->set_column_expand(2,0);
clips_tree->set_column_expand(3,0);
clips_tree->set_column_min_width(1,60);
clips_tree->set_column_min_width(2,60);
clips_tree->set_column_min_width(3,40);
clips_tree->set_column_titles_visible(true);
clips_tree->set_column_title(0,"Name");
clips_tree->set_column_title(1,"Start(s)");
clips_tree->set_column_title(2,"End(s)");
clips_tree->set_column_title(3,"Loop");
clips_base =clips_tree->create_item(0);
setup_clips(Array());
filters = memnew( TextEdit );
tab->add_child(filters);
filters->set_name("Filters");
}
void EditorImportAnimationOptions::set_fps(int p_fps) {
fps->set_range(0,p_fps);
}
int EditorImportAnimationOptions::get_fps() const {
return fps->get_range(0);
}
void EditorImportAnimationOptions::set_filter(const String& p_filter) {
filters->set_text(p_filter);
}
String EditorImportAnimationOptions::get_filter() const {
return filters->get_text();
}
@ -413,7 +649,12 @@ void EditorSceneImportDialog::_import(bool p_and_open) {
rim->set_option("texture_format",texture_options->get_format());
rim->set_option("texture_quality",texture_options->get_quality());
rim->set_option("animation_flags",animation_options->get_flags());
rim->set_option("animation_bake_fps",animation_options->get_fps());
rim->set_option("animation_filters",animation_options->get_filter());
rim->set_option("animation_clips",animation_options->get_clips());
rim->set_option("post_import_script",script_path->get_text()!=String()?EditorImportPlugin::validate_source_path(script_path->get_text()):String());
rim->set_option("import_this_time",this_import->get_selected());
rim->set_option("import_next_time",next_import->get_selected());
rim->set_option("reimport",true);
List<String> missing;
@ -526,7 +767,7 @@ void EditorSceneImportDialog::_browse_script() {
void EditorSceneImportDialog::popup_import(const String &p_from) {
popup_centered(Size2(700,500));
popup_centered(Size2(750,550));
if (p_from!="") {
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from);
if (rimd.is_null())
@ -544,7 +785,17 @@ void EditorSceneImportDialog::popup_import(const String &p_from) {
texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("texture_format"))));
texture_options->set_quality(rimd->get_option("texture_quality"));
animation_options->set_flags(rimd->get_option("animation_flags"));
if (rimd->has_option("animation_clips"))
animation_options->setup_clips(rimd->get_option("animation_clips"));
if (rimd->has_option("animation_filters"))
animation_options->set_filter(rimd->get_option("animation_filters"));
if (rimd->has_option("animation_bake_fps"))
animation_options->set_fps(rimd->get_option("animation_bake_fps"));
script_path->set_text(rimd->get_option("post_import_script"));
if (rimd->has_option("import_this_time"))
this_import->select(rimd->get_option("import_this_time"));
if (rimd->has_option("import_next_time"))
next_import->select(rimd->get_option("import_next_time"));
save_path->set_text(p_from.get_base_dir());
import_path->set_text(EditorImportPlugin::expand_source_path(rimd->get_source_path(0)));
@ -619,7 +870,7 @@ void EditorSceneImportDialog::_bind_methods() {
ObjectTypeDB::bind_method("_choose_file",&EditorSceneImportDialog::_choose_file);
ObjectTypeDB::bind_method("_choose_save_file",&EditorSceneImportDialog::_choose_save_file);
ObjectTypeDB::bind_method("_choose_script",&EditorSceneImportDialog::_choose_script);
ObjectTypeDB::bind_method("_import",&EditorSceneImportDialog::_import);
ObjectTypeDB::bind_method("_import",&EditorSceneImportDialog::_import,DEFVAL(false));
ObjectTypeDB::bind_method("_browse",&EditorSceneImportDialog::_browse);
ObjectTypeDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target);
ObjectTypeDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script);
@ -792,6 +1043,20 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
error_dialog->get_ok()->set_text("Accept");
// error_dialog->get_cancel()->hide();
this_import = memnew( OptionButton );
this_import->add_item("Overwrite Existing Scene");
this_import->add_item("Owerwrite Existing, Keep Materials");
this_import->add_item("Keep Existing, Merge with New");
this_import->add_item("Keep Existing, Ignore New");
vbc->add_margin_child("This Time:",this_import);
next_import = memnew( OptionButton );
next_import->add_item("Overwrite Existing Scene");
next_import->add_item("Owerwrite Existing, Keep Materials");
next_import->add_item("Keep Existing, Merge with New");
next_import->add_item("Keep Existing, Ignore New");
vbc->add_margin_child("Next Time:",next_import);
set_hide_on_ok(false);
GLOBAL_DEF("import/shared_textures","res://");
@ -814,7 +1079,7 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
animation_options = memnew( EditorImportAnimationOptions );
ovb->add_child(animation_options);
animation_options->set_v_size_flags(SIZE_EXPAND_FILL);
animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_TRACKS_IN_ALL_BONES);
animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE|EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
confirm_import = memnew( ConfirmationDialog );
@ -1815,6 +2080,79 @@ void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) {
}
void EditorSceneImportPlugin::_scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials) {
if (!p_base && p_node->get_owner()!=p_base)
return;
MeshInstance *mi=p_node->cast_to<MeshInstance>();
if (mi) {
if (mi->get_material_override().is_valid()) {
String path = p_base->get_path_to(p_node);
override_materials[path]=mi->get_material_override();
}
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
for(int i=0;i<mesh->get_surface_count();i++) {
String name = mesh->get_name()+":"+mesh->surface_get_name(i);
if (!mesh_materials.has(name)) {
mesh_materials[name]=mesh->surface_get_material(i);
}
}
}
}
for(int i=0;i<p_node->get_child_count();i++) {
_scan_materials(p_base,p_node->get_child(i),mesh_materials,override_materials);
}
}
void EditorSceneImportPlugin::_apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed) {
if (!p_base && p_node->get_owner()!=p_base)
return;
MeshInstance *mi=p_node->cast_to<MeshInstance>();
if (mi) {
String path = p_base->get_path_to(p_node);
if (override_materials.has(path))
mi->set_material_override(override_materials[path]);
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid() && !meshes_processed.has(mesh)) {
meshes_processed.insert(mesh);
for(int i=0;i<mesh->get_surface_count();i++) {
String name = mesh->get_name()+":"+mesh->surface_get_name(i);
if (mesh_materials.has(name)) {
Ref<Material> mat = mesh_materials[name];
mesh->surface_set_material(i,mat);
}
}
}
}
for(int i=0;i<p_node->get_child_count();i++) {
_apply_materials(p_base,p_node->get_child(i),mesh_materials,override_materials,meshes_processed);
}
}
void EditorSceneImportPlugin::_merge_materials(Node *p_node,Node *p_imported) {
Map<String,Ref<Material> > mesh_materials;
Map<String,Ref<Material> > override_materials;
_scan_materials(p_node,p_node,mesh_materials,override_materials);
Set<Ref<Mesh> > mp;
_apply_materials(p_imported,p_imported,mesh_materials,override_materials,mp);
}
#if 0
@ -1882,14 +2220,20 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
int animation_flags=p_from->get_option("animation_flags");
int scene_flags = from->get_option("flags");
int fps = 24;
if (from->has_option("animation_bake_fps"))
fps=from->get_option("animation_bake_fps");
Array clips;
if (from->has_option("animation_clips"))
clips=from->get_option("animation_clips");
uint32_t import_flags=0;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_TRACKS_IN_ALL_BONES)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES;
if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS;
if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS)
import_flags|=EditorSceneImporter::IMPORT_ANIMATION;
//if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES)
@ -1902,7 +2246,7 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
Error err=OK;
Node *scene = importer->import_scene(src_path,import_flags,r_missing,&err);
Node *scene = importer->import_scene(src_path,import_flags,fps,r_missing,&err);
if (!scene || err!=OK) {
return err;
}
@ -1913,19 +2257,231 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
return OK;
}
void EditorSceneImportPlugin::_create_clips(Node *scene, const Array& p_clips,bool p_bake_all) {
if (!scene->has_node(String("AnimationPlayer")))
return;
Node* n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
ERR_FAIL_COND(!anim);
if (!anim->has_animation("default"))
return;
Ref<Animation> default_anim = anim->get_animation("default");
for(int i=0;i<p_clips.size();i+=4) {
String name = p_clips[i];
float from=p_clips[i+1];
float to=p_clips[i+2];
bool loop=p_clips[i+3];
if (from>=to)
continue;
Ref<Animation> new_anim = memnew( Animation );
for(int j=0;j<default_anim->get_track_count();j++) {
List<float> keys;
int kc = default_anim->track_get_key_count(j);
int dtrack=-1;
for(int k=0;k<kc;k++) {
float kt = default_anim->track_get_key_time(j,k);
if (kt>=from && kt<to) {
//found a key within range, so create track
if (dtrack==-1) {
new_anim->add_track(default_anim->track_get_type(j));
dtrack = new_anim->get_track_count()-1;
new_anim->track_set_path(dtrack,default_anim->track_get_path(j));
if (kt>(from+0.01) && k>0) {
if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
Vector3 s;
default_anim->transform_track_interpolate(j,from,&p,&q,&s);
new_anim->transform_track_insert_key(dtrack,0,p,q,s);
}
}
}
if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
Vector3 s;
default_anim->transform_track_get_key(j,k,&p,&q,&s);
new_anim->transform_track_insert_key(dtrack,kt-from,p,q,s);
}
}
if (dtrack!=-1 && kt>=to) {
if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
Vector3 s;
default_anim->transform_track_interpolate(j,to,&p,&q,&s);
new_anim->transform_track_insert_key(dtrack,to-from,p,q,s);
}
}
}
if (dtrack==-1 && p_bake_all) {
new_anim->add_track(default_anim->track_get_type(j));
dtrack = new_anim->get_track_count()-1;
new_anim->track_set_path(dtrack,default_anim->track_get_path(j));
if (default_anim->track_get_type(j)==Animation::TYPE_TRANSFORM) {
Quat q;
Vector3 p;
Vector3 s;
default_anim->transform_track_interpolate(j,from,&p,&q,&s);
new_anim->transform_track_insert_key(dtrack,0,p,q,s);
default_anim->transform_track_interpolate(j,to,&p,&q,&s);
new_anim->transform_track_insert_key(dtrack,to-from,p,q,s);
}
}
}
new_anim->set_loop(loop);
new_anim->set_length(to-from);
anim->add_animation(name,new_anim);
}
anim->remove_animation("default"); //remove default (no longer needed)
}
void EditorSceneImportPlugin::_filter_tracks(Node *scene, const String& p_text) {
if (!scene->has_node(String("AnimationPlayer")))
return;
Node* n = scene->get_node(String("AnimationPlayer"));
ERR_FAIL_COND(!n);
AnimationPlayer *anim = n->cast_to<AnimationPlayer>();
ERR_FAIL_COND(!anim);
Vector<String> strings = p_text.split("\n");
for(int i=0;i<strings.size();i++) {
strings[i]=strings[i].strip_edges();
}
List<StringName> anim_names;
anim->get_animation_list(&anim_names);
Set<String> keep;
for(List<StringName>::Element *E=anim_names.front();E;E=E->next()) {
String name = E->get();
bool valid_for_this=false;
for(int i=0;i<strings.size();i++) {
if (strings[i].begins_with("@")) {
valid_for_this=false;
keep.clear();
Vector<String> filters=strings[i].substr(1,strings[i].length()).split(",");
for(int j=0;j<filters.size();j++) {
String fname = filters[i].strip_edges();
if (fname=="")
continue;
int fc = fname[0];
bool plus;
if (fc=='+')
plus=true;
else if (fc=='-')
plus=false;
else
continue;
String filter=fname.substr(1,fname.length()).strip_edges();
if (!name.matchn(filter))
continue;
valid_for_this=plus;
}
} else if (valid_for_this) {
Ref<Animation> a = anim->get_animation(name);
if (!a.is_valid())
continue;
for(int j=0;j<a->get_track_count();j++) {
String path = a->track_get_path(j);
String tname = strings[i];
if (tname=="")
continue;
int fc = tname[0];
bool plus;
if (fc=='+')
plus=true;
else if (fc=='-')
plus=false;
else
continue;
String filter=tname.substr(1,tname.length()).strip_edges();
if (!path.matchn(filter))
continue;
if (plus)
keep.insert(path);
else if (!keep.has(path)) {
a->remove_track(j);
j--;
}
}
}
}
}
}
Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {
Error err=OK;
Ref<ResourceImportMetadata> from=p_from;
String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
int animation_flags=p_from->get_option("animation_flags");
Array animation_clips = p_from->get_option("animation_clips");
String animation_filter = p_from->get_option("animation_filters");
int scene_flags = from->get_option("flags");
EditorProgress progress("import","Import Scene",104);
progress.step("Importing Scene..",2);
bool merge = !bool(from->get_option("reimport"));
bool reimport = bool(from->get_option("reimport"));
int this_time_action = from->get_option("import_this_time");
int next_time_action = from->get_option("import_next_time");
int import_action = reimport?this_time_action:next_time_action;
from->set_source_md5(0,FileAccess::get_md5(src_path));
from->set_editor(get_name());
@ -1940,6 +2496,11 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
Map< Ref<ImageTexture>,TextureRole > imagemap;
scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
if (animation_clips.size())
_create_clips(scene,animation_clips,animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS);
_filter_tracks(scene,animation_filter);
/// BEFORE ANYTHING, RUN SCRIPT
@ -2063,7 +2624,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
/// BEFORE SAVING - MERGE
if (merge) {
if (import_action!=SCENE_UPDATE_REPLACE_WITH_NEW) {
progress.step("Merging..",103);
@ -2082,10 +2643,30 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
if (existing) {
_merge_scenes(existing,scene);
memdelete(scene);
scene=existing;
switch(import_action) {
case SCENE_UPDATE_REPLACE_WITH_NEW: break;
case SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS: {
_merge_materials(existing,scene);
memdelete(existing);
} break;
case SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES: {
_merge_scenes(existing,scene);
memdelete(scene);
scene=existing;
} break;
case SCENE_UPDATE_KEEP_OLD: {
memdelete(scene);
scene=existing;
} break;
}
}
}

View file

@ -58,7 +58,7 @@ public:
IMPORT_ANIMATION=2,
IMPORT_ANIMATION_DETECT_LOOP=4,
IMPORT_ANIMATION_OPTIMIZE=8,
IMPORT_ANIMATION_FORCE_TRACKS_IN_ALL_BONES=16,
IMPORT_ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=16,
IMPORT_GENERATE_TANGENT_ARRAYS=256,
IMPORT_FAIL_ON_MISSING_DEPENDENCIES=512
@ -66,7 +66,7 @@ public:
virtual uint32_t get_import_flags() const=0;
virtual void get_extensions(List<String> *r_extensions) const=0;
virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps,Error* r_err=NULL)=0;
virtual Node* import_scene(const String& p_path,uint32_t p_flags,int p_bake_fps,List<String> *r_missing_deps,Error* r_err=NULL)=0;
virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0;
@ -108,10 +108,16 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,TextureRole >& image_map,int p_flags);
Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,TextureRole >& image_map);
void _create_clips(Node *scene, const Array& p_clips, bool p_bake_all);
void _filter_tracks(Node *scene, const String& p_text);
void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes);
void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes);
void _merge_scenes(Node *p_node, Node *p_imported);
void _scan_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials);
void _apply_materials(Node*p_base,Node *p_node,Map<String,Ref<Material> > &mesh_materials,Map<String,Ref<Material> >& override_materials,Set<Ref<Mesh> >& meshes_processed);
void _merge_materials(Node *p_node,Node *p_imported);
void _tag_import_paths(Node *p_scene,Node *p_node);
@ -142,6 +148,13 @@ public:
SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30,
};
enum SceneUpdate {
SCENE_UPDATE_REPLACE_WITH_NEW,
SCENE_UPDATE_REPLACE_WITH_NEW_KEEP_MATERIALS,
SCENE_UPDATE_KEEP_OLD_MERGE_CHANGES,
SCENE_UPDATE_KEEP_OLD,
};
virtual String get_name() const;
virtual String get_visible_name() const;
@ -171,7 +184,7 @@ public:
ANIMATION_DETECT_LOOP=1,
ANIMATION_KEEP_VALUE_TRACKS=2,
ANIMATION_OPTIMIZE=4,
ANIMATION_FORCE_TRACKS_IN_ALL_BONES=8
ANIMATION_FORCE_ALL_TRACKS_IN_ALL_CLIPS=8
};
virtual String get_name() const;
@ -185,5 +198,4 @@ public:
};
#endif // EDITOR_SCENE_IMPORT_PLUGIN_H

View file

@ -2,7 +2,34 @@
#include "typedefs.h"
#ifdef WINDOWS_ENABLED
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
void baked_light_baker_add_64f(double *dst,double value) {
union {
int64_t i;
double f;
} swapy;
while(true) {
swapy.f=*dst;
int64_t from = swapy.i;
swapy.f+=value;
int64_t to=swapy.i;
if (__sync_bool_compare_and_swap((int64_t*)dst,from,to))
break;
}
}
void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {}
}
#elif defined(WINDOWS_ENABLED)
#include "windows.h"
@ -37,32 +64,6 @@ void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
}
}
#elif (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
void baked_light_baker_add_64f(double *dst,double value) {
union {
int64_t i;
double f;
} swapy;
while(true) {
swapy.f=*dst;
int64_t from = swapy.i;
swapy.f+=value;
int64_t to=swapy.i;
if (__sync_bool_compare_and_swap((int64_t*)dst,from,to))
break;
}
}
void baked_light_baker_add_64i(int64_t *dst,int64_t value) {
while(!__sync_bool_compare_and_swap(dst,*dst,(*dst)+value)) {}
}
#else

View file

@ -13,7 +13,7 @@ void CollisionPolygon2DEditor::_notification(int p_what) {
button_create->set_icon( get_icon("Edit","EditorIcons"));
button_edit->set_icon( get_icon("MovePoint","EditorIcons"));
button_edit->set_pressed(true);
get_scene()->connect("node_removed",this,"_node_removed");
} break;
case NOTIFICATION_FIXED_PROCESS: {
@ -28,6 +28,7 @@ void CollisionPolygon2DEditor::_node_removed(Node *p_node) {
if(p_node==node) {
node=NULL;
hide();
canvas_item_editor->get_viewport_control()->update();
}
}
@ -83,6 +84,9 @@ void CollisionPolygon2DEditor::_wip_close() {
bool CollisionPolygon2DEditor::forward_input_event(const InputEvent& p_event) {
if (!node)
return false;
switch(p_event.type) {
case InputEvent::MOUSE_BUTTON: {
@ -379,6 +383,7 @@ void CollisionPolygon2DEditor::_bind_methods() {
ObjectTypeDB::bind_method(_MD("_menu_option"),&CollisionPolygon2DEditor::_menu_option);
ObjectTypeDB::bind_method(_MD("_canvas_draw"),&CollisionPolygon2DEditor::_canvas_draw);
ObjectTypeDB::bind_method(_MD("_node_removed"),&CollisionPolygon2DEditor::_node_removed);
}

View file

@ -158,13 +158,54 @@ void MeshInstanceEditor::_menu_option(int p_option) {
ur->add_undo_method(node,"remove_child",nmi);
ur->commit_action();
} break;
case MENU_OPTION_CREATE_OUTLINE_MESH: {
outline_dialog->popup_centered(Size2(200,80));
} break;
}
}
void MeshInstanceEditor::_create_outline_mesh() {
Ref<Mesh> mesh = node->get_mesh();
if (mesh.is_null()) {
err_dialog->set_text("MeshInstance lacks a Mesh!");
err_dialog->popup_centered(Size2(100,50));
return;
}
Ref<Mesh> mesho = mesh->create_outline(outline_size->get_val());
if (mesho.is_null()) {
err_dialog->set_text("Could not create outline!");
err_dialog->popup_centered(Size2(100,50));
return;
}
MeshInstance *mi = memnew( MeshInstance );
mi->set_mesh(mesho);
Node *owner=node->get_owner();
if (get_scene()->get_edited_scene_root()==node) {
owner=node;
}
UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
ur->create_action("Create Outline");
ur->add_do_method(node,"add_child",mi);
ur->add_do_method(mi,"set_owner",owner);
ur->add_do_reference(mi);
ur->add_undo_method(node,"remove_child",mi);
ur->commit_action();
}
void MeshInstanceEditor::_bind_methods() {
ObjectTypeDB::bind_method("_menu_option",&MeshInstanceEditor::_menu_option);
ObjectTypeDB::bind_method("_create_outline_mesh",&MeshInstanceEditor::_create_outline_mesh);
}
MeshInstanceEditor::MeshInstanceEditor() {
@ -182,9 +223,23 @@ MeshInstanceEditor::MeshInstanceEditor() {
options->get_popup()->add_item("Create Convex Collision Sibling",MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE);
options->get_popup()->add_separator();
options->get_popup()->add_item("Create Navigation Mesh",MENU_OPTION_CREATE_NAVMESH);
options->get_popup()->add_separator();
options->get_popup()->add_item("Create Outline Mesh..",MENU_OPTION_CREATE_OUTLINE_MESH);
options->get_popup()->connect("item_pressed", this,"_menu_option");
outline_dialog = memnew( ConfirmationDialog );
outline_dialog->set_title("Outline Size: ");
outline_size = memnew( SpinBox );
outline_size->set_min(0.001);
outline_size->set_max(1024);
outline_size->set_step(0.001);
outline_size->set_val(0.05);
outline_dialog->add_child(outline_size);
outline_dialog->set_child_rect(outline_size);
add_child(outline_dialog);
outline_dialog->connect("confirmed",this,"_create_outline_mesh");
}

View file

@ -20,8 +20,12 @@ class MeshInstanceEditor : public Node {
MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE,
MENU_OPTION_CREATE_NAVMESH,
MENU_OPTION_CREATE_OUTLINE_MESH,
};
ConfirmationDialog *outline_dialog;
SpinBox *outline_size;
AcceptDialog *err_dialog;
@ -33,6 +37,8 @@ class MeshInstanceEditor : public Node {
void _menu_option(int p_option);
void _create_outline_mesh();
friend class MeshInstanceEditorPlugin;
MenuButton * options;

View file

@ -1779,7 +1779,7 @@ void CollisionShapeSpatialGizmo::set_handle(int p_idx,Camera *p_camera, const Po
Ref<CapsuleShape> cs = s;
Vector3 ra,rb;
Geometry::get_closest_points_between_segments(Vector3(),axis*4096,sg[0],sg[1],ra,rb);
float d = ra[p_idx];
float d = axis.dot(ra);
if (p_idx==1)
d-=cs->get_radius();
if (d<0.001)