瀏覽代碼

Merge branch 'master' of https://github.com/okamstudio/godot

Anton Yabchinskiy 10 年之前
父節點
當前提交
99676d7e74

+ 15 - 0
core/bind/core_bind.cpp

@@ -606,6 +606,12 @@ bool _OS::is_debug_build() const {
 #endif
 
 }
+
+String _OS::get_system_dir(SystemDir p_dir) const {
+
+	return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
+}
+
 String _OS::get_custom_level() const {
 
 	return OS::get_singleton()->get_custom_level();
@@ -690,6 +696,7 @@ void _OS::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_dynamic_memory_usage"),&_OS::get_dynamic_memory_usage);
 
 	ObjectTypeDB::bind_method(_MD("get_data_dir"),&_OS::get_data_dir);
+	ObjectTypeDB::bind_method(_MD("get_system_dir","dir"),&_OS::get_system_dir);
 	ObjectTypeDB::bind_method(_MD("get_unique_ID"),&_OS::get_unique_ID);
 
 	ObjectTypeDB::bind_method(_MD("get_frames_per_second"),&_OS::get_frames_per_second);
@@ -728,6 +735,14 @@ void _OS::_bind_methods() {
 	BIND_CONSTANT( MONTH_NOVEMBER );
 	BIND_CONSTANT( MONTH_DECEMBER );
 
+	BIND_CONSTANT( SYSTEM_DIR_DESKTOP);
+	BIND_CONSTANT( SYSTEM_DIR_DCIM );
+	BIND_CONSTANT( SYSTEM_DIR_DOCUMENTS );
+	BIND_CONSTANT( SYSTEM_DIR_DOWNLOADS );
+	BIND_CONSTANT( SYSTEM_DIR_MOVIES );
+	BIND_CONSTANT( SYSTEM_DIR_MUSIC );
+	BIND_CONSTANT( SYSTEM_DIR_PICTURES );
+	BIND_CONSTANT( SYSTEM_DIR_RINGTONES );
 
 }
 

+ 17 - 0
core/bind/core_bind.h

@@ -201,6 +201,20 @@ public:
 
 	int get_processor_count() const;
 
+	enum SystemDir {
+		SYSTEM_DIR_DESKTOP,
+		SYSTEM_DIR_DCIM,
+		SYSTEM_DIR_DOCUMENTS,
+		SYSTEM_DIR_DOWNLOADS,
+		SYSTEM_DIR_MOVIES,
+		SYSTEM_DIR_MUSIC,
+		SYSTEM_DIR_PICTURES,
+		SYSTEM_DIR_RINGTONES,
+	};
+
+	String get_system_dir(SystemDir p_dir) const;
+
+
 	String get_data_dir() const;
 
 	void set_time_scale(float p_scale);
@@ -211,6 +225,9 @@ public:
 	_OS();
 };
 
+VARIANT_ENUM_CAST(_OS::SystemDir);
+
+
 class _Geometry : public Object {
 
 	OBJ_TYPE(_Geometry, Object);

+ 1 - 1
core/globals.cpp

@@ -674,7 +674,7 @@ static Variant _decode_variant(const String& p_string) {
 		int w=params[2].to_int();
 		int h=params[3].to_int();
 
-		if (w == 0 && w == 0) {
+		if (w == 0 && h == 0) {
 			//r_v = Image(w, h, imgformat);
 			return Image();
 		};

+ 1 - 1
core/io/config_file.cpp

@@ -580,7 +580,7 @@ static Variant _decode_variant(const String& p_string) {
 		int w=params[2].to_int();
 		int h=params[3].to_int();
 
-		if (w == 0 && w == 0) {
+		if (w == 0 && h == 0) {
 			//r_v = Image(w, h, imgformat);
 			return Image();
 		};

+ 1 - 1
core/io/resource_format_xml.cpp

@@ -571,7 +571,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
 			int w=width.to_int();
 			int h=height.to_int();
 
-			if (w == 0 && w == 0) {
+			if (w == 0 && h == 0) {
 				//r_v = Image(w, h, imgformat);
 				r_v=Image();
 				String sdfsdfg;

+ 6 - 0
core/os/os.cpp

@@ -280,6 +280,12 @@ String OS::get_resource_dir() const {
 	return Globals::get_singleton()->get_resource_path();
 }
 
+
+String OS::get_system_dir(SystemDir p_dir) const {
+
+	return ".";
+}
+
 String OS::get_data_dir() const {
 
 	return ".";

+ 14 - 0
core/os/os.h

@@ -286,6 +286,20 @@ public:
 	virtual String get_data_dir() const;
 	virtual String get_resource_dir() const;
 
+	enum SystemDir {
+		SYSTEM_DIR_DESKTOP,
+		SYSTEM_DIR_DCIM,
+		SYSTEM_DIR_DOCUMENTS,
+		SYSTEM_DIR_DOWNLOADS,
+		SYSTEM_DIR_MOVIES,
+		SYSTEM_DIR_MUSIC,
+		SYSTEM_DIR_PICTURES,
+		SYSTEM_DIR_RINGTONES,
+	};
+
+	virtual String get_system_dir(SystemDir p_dir) const;
+
+
 	virtual void set_no_window_mode(bool p_enable);
 	virtual bool is_no_window_mode_enabled() const;
 

+ 1 - 1
core/typedefs.h

@@ -41,7 +41,7 @@
 #define _MKSTR(m_x) _STR(m_x)
 #endif
 // have to include version.h for this to work, include it in the .cpp not the .h
-#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"."_MKSTR(VERSION_MINOR)"."_MKSTR(VERSION_REVISION)"-"_MKSTR(VERSION_STATUS)
+#define VERSION_MKSTRING _MKSTR(VERSION_MAJOR)"."_MKSTR(VERSION_MINOR)"."_MKSTR(VERSION_STATUS)"."_MKSTR(VERSION_REVISION)
 #define VERSION_FULL_NAME _MKSTR(VERSION_NAME)" v"VERSION_MKSTRING
 
 

+ 1 - 1
main/main.cpp

@@ -111,7 +111,7 @@ static String unescape_cmdline(const String& p_str) {
 
 void Main::print_help(const char* p_binary) {
 
-	OS::get_singleton()->print(VERSION_FULL_NAME" (c) 2008-2010 Juan Linietsky, Ariel Manzur.\n");
+	OS::get_singleton()->print(VERSION_FULL_NAME" (c) 2008-2015 Juan Linietsky, Ariel Manzur.\n");
 	OS::get_singleton()->print("Usage: %s [options] [scene]\n",p_binary);
 	OS::get_singleton()->print("Options:\n");
 	OS::get_singleton()->print("\t-path [dir] : Path to a game, containing engine.cfg\n");

+ 5 - 36
methods.py

@@ -1083,44 +1083,13 @@ def build_gles2_headers( target, source, env ):
 
 def update_version():
 
-	rev = 0
+	rev = "custom_build"
 	
-	try:
-		f = open("custom_version.txt","rb")
-		rev = int( f.readline().strip() )
-	except:
-		pass
-			
-	if (rev==0):	
-		try:							
-			f = open(".svn/entries")
-			line = f.readline();
-			next_rev = False
-			while line != "":
-				line = line.rstrip('\r\n')
-				if next_rev:
-					rev = line
-					break
-				if line == "dir":
-					next_rev = True
-				line = f.readline();
-				
-			if rev != 0:
-				f = open("version.py")
-				ver = f.read()
-				import re
-				ver = re.sub(r'\$Rev: \d* \$', '$Rev: '+str(rev)+' $', ver)
-				f = open("version.py", "wb")
-				f.write(ver)
-				f.close()
-				
-		except:
-			pass
-
+	if (os.getenv("BUILD_REVISION")!=None):
+		rev=os.getenv("BUILD_REVISION")
+		print("Using custom revision: "+rev)
 	import version
-
-	rev=version.revision
-	rev=rev[5:-1].strip()
+	
 
 	f=open("core/version.h","wb")
 	f.write("#define VERSION_SHORT_NAME "+str(version.short_name)+"\n")

+ 52 - 0
platform/android/java/src/com/android/godot/GodotIO.java

@@ -557,6 +557,58 @@ public class GodotIO {
 		}
 	}
 
+
+	public static final int SYSTEM_DIR_DESKTOP=0;
+	public static final int SYSTEM_DIR_DCIM=1;
+	public static final int SYSTEM_DIR_DOCUMENTS=2;
+	public static final int SYSTEM_DIR_DOWNLOADS=3;
+	public static final int SYSTEM_DIR_MOVIES=4;
+	public static final int SYSTEM_DIR_MUSIC=5;
+	public static final int SYSTEM_DIR_PICTURES=6;
+	public static final int SYSTEM_DIR_RINGTONES=7;
+
+
+	public String getSystemDir(int idx) {
+
+		String what="";
+		switch(idx) {
+			case SYSTEM_DIR_DESKTOP: {
+				//what=Environment.DIRECTORY_DOCUMENTS;
+				what=Environment.DIRECTORY_DOWNLOADS;
+			} break;
+			case SYSTEM_DIR_DCIM: {
+				what=Environment.DIRECTORY_DCIM;
+
+			} break;
+			case SYSTEM_DIR_DOCUMENTS: {
+				what=Environment.DIRECTORY_DOWNLOADS;
+				//what=Environment.DIRECTORY_DOCUMENTS;
+			} break;
+			case SYSTEM_DIR_DOWNLOADS: {
+				what=Environment.DIRECTORY_DOWNLOADS;
+
+			} break;
+			case SYSTEM_DIR_MOVIES: {
+				what=Environment.DIRECTORY_MOVIES;
+
+			} break;
+			case SYSTEM_DIR_MUSIC: {
+				what=Environment.DIRECTORY_MUSIC;
+			} break;
+			case SYSTEM_DIR_PICTURES: {
+				what=Environment.DIRECTORY_PICTURES;
+			} break;
+			case SYSTEM_DIR_RINGTONES: {
+				what=Environment.DIRECTORY_RINGTONES;
+
+			} break;
+		}
+
+		if (what.equals(""))
+			return "";
+		return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath();
+	}
+
 	protected static final String PREFS_FILE = "device_id.xml";
 	protected static final String PREFS_DEVICE_ID = "device_id";
 

+ 11 - 3
platform/android/java_glue.cpp

@@ -599,7 +599,7 @@ static jmethodID _showKeyboard=0;
 static jmethodID _hideKeyboard=0;
 static jmethodID _setScreenOrientation=0;
 static jmethodID _getUniqueID=0;
-
+static jmethodID _getSystemDir=0;
 static jmethodID _playVideo=0;
 static jmethodID _isVideoPlaying=0;
 static jmethodID _pauseVideo=0;
@@ -659,6 +659,14 @@ static void _set_screen_orient(int p_orient) {
 	env->CallVoidMethod(godot_io, _setScreenOrientation, p_orient );
 };
 
+static String _get_system_dir(int p_dir) {
+
+	JNIEnv *env = ThreadAndroid::get_env();
+	jstring s =(jstring)env->CallObjectMethod(godot_io,_getSystemDir,p_dir);
+	return String(env->GetStringUTFChars( s, NULL ));
+};
+
+
 static void _hide_vk() {
 
 	JNIEnv* env = ThreadAndroid::get_env();
@@ -738,7 +746,7 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
 			_showKeyboard = env->GetMethodID(c,"showKeyboard","(Ljava/lang/String;)V");
 			_hideKeyboard = env->GetMethodID(c,"hideKeyboard","()V");
 			_setScreenOrientation = env->GetMethodID(c,"setScreenOrientation","(I)V");
-
+			_getSystemDir = env->GetMethodID(c,"getSystemDir","(I)Ljava/lang/String;");
 			_playVideo = env->GetMethodID(c,"playVideo","(Ljava/lang/String;)V");
 			_isVideoPlaying = env->GetMethodID(c,"isVideoPlaying","()Z");
 			_pauseVideo = env->GetMethodID(c,"pauseVideo","()V");
@@ -781,7 +789,7 @@ JNIEXPORT void JNICALL Java_com_android_godot_GodotLib_initialize(JNIEnv * env,
 
 	__android_log_print(ANDROID_LOG_INFO,"godot","CMDLINE LEN %i - APK EXPANSION %I\n",cmdlen,int(use_apk_expansion));
 
-	os_android = new OS_Android(_gfx_init_func,env,_open_uri,_get_data_dir,_get_locale, _get_model,_show_vk, _hide_vk,_set_screen_orient,_get_unique_id, _play_video, _is_video_playing, _pause_video, _stop_video,use_apk_expansion);
+	os_android = new OS_Android(_gfx_init_func,env,_open_uri,_get_data_dir,_get_locale, _get_model,_show_vk, _hide_vk,_set_screen_orient,_get_unique_id, _get_system_dir, _play_video,_is_video_playing, _pause_video, _stop_video,use_apk_expansion);
 	os_android->set_need_reload_hooks(p_need_reload_hook);
 
 	char wd[500];

+ 1 - 1
platform/android/libs/downloader_library/gen/com/android/vending/expansion/downloader/BuildConfig.java

@@ -2,5 +2,5 @@
 package com.android.vending.expansion.downloader;
 
 public final class BuildConfig {
-    public final static boolean DEBUG = false;
+    public final static boolean DEBUG = true;
 }

+ 9 - 1
platform/android/os_android.cpp

@@ -699,12 +699,19 @@ void OS_Android::native_video_pause() {
 		video_pause_func();
 }
 
+String OS_Android::get_system_dir(SystemDir p_dir) const {
+
+	if (get_system_dir_func)
+		return get_system_dir_func(p_dir);
+	return String(".");
+}
+
 void OS_Android::native_video_stop() {
 	if (video_stop_func)
 		video_stop_func();
 }
 
-OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk,  SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion) {
+OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk,  SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion) {
 
 
 	use_apk_expansion=p_use_apk_expansion;
@@ -726,6 +733,7 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFu
 	get_locale_func=p_get_locale_func;
 	get_model_func=p_get_model_func;
 	get_unique_id_func=p_get_unique_id;
+	get_system_dir_func=p_get_sdir_func;
     
 	video_play_func = p_video_play_func;
 	video_is_playing_func = p_video_is_playing_func;

+ 9 - 4
platform/android/os_android.h

@@ -63,6 +63,7 @@ typedef String (*GetUniqueIDFunc)();
 typedef void (*ShowVirtualKeyboardFunc)(const String&);
 typedef void (*HideVirtualKeyboardFunc)();
 typedef void (*SetScreenOrientationFunc)(int);
+typedef String (*GetSystemDirFunc)(int);
 
 typedef void (*VideoPlayFunc)(const String&);
 typedef bool (*VideoIsPlayingFunc)();
@@ -98,6 +99,7 @@ private:
 	SpatialSound2DServerSW *spatial_sound_2d_server;
 	PhysicsServer *physics_server;
 	Physics2DServer *physics_2d_server;
+
 #if 0
 	AudioDriverAndroid audio_driver_android;
 #else
@@ -118,6 +120,7 @@ private:
 	HideVirtualKeyboardFunc hide_virtual_keyboard_func;
 	SetScreenOrientationFunc set_screen_orientation_func;
 	GetUniqueIDFunc get_unique_id_func;
+	GetSystemDirFunc get_system_dir_func;
 
 	VideoPlayFunc video_play_func;
 	VideoIsPlayingFunc video_is_playing_func;
@@ -203,6 +206,8 @@ public:
 
 	virtual String get_unique_ID() const;
 
+	virtual String get_system_dir(SystemDir p_dir) const;
+
 
 	void process_accelerometer(const Vector3& p_accelerometer);
 	void process_touch(int p_what,int p_pointer, const Vector<TouchPos>& p_points);
@@ -210,11 +215,11 @@ public:
 	void init_video_mode(int p_video_width,int p_video_height);
 
 	virtual Error native_video_play(String p_path, float p_volume);
-    virtual bool native_video_is_playing();
-    virtual void native_video_pause();
-    virtual void native_video_stop();
+	virtual bool native_video_is_playing();
+	virtual void native_video_pause();
+	virtual void native_video_stop();
 
-	OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk,  SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion);
+	OS_Android(GFXInitFunc p_gfx_init_func,void*p_gfx_init_ud, OpenURIFunc p_open_uri_func, GetDataDirFunc p_get_data_dir_func,GetLocaleFunc p_get_locale_func,GetModelFunc p_get_model_func, ShowVirtualKeyboardFunc p_show_vk, HideVirtualKeyboardFunc p_hide_vk,  SetScreenOrientationFunc p_screen_orient,GetUniqueIDFunc p_get_unique_id,GetSystemDirFunc p_get_sdir_func, VideoPlayFunc p_video_play_func, VideoIsPlayingFunc p_video_is_playing_func, VideoPauseFunc p_video_pause_func, VideoStopFunc p_video_stop_func,bool p_use_apk_expansion);
 	~OS_Android();
 
 };

+ 3 - 1
platform/iphone/app_delegate.h

@@ -31,12 +31,14 @@
 #import "view_controller.h"
 
 @interface AppDelegate : NSObject <UIApplicationDelegate, UIAccelerometerDelegate, GLViewDelegate> {
-	UIWindow *window;
+	//@property (strong, nonatomic) UIWindow *window;
 	ViewController* view_controller;
 	UIAccelerationValue accel[3];
 	UIAccelerationValue last_accel[3];
 };
 
+@property (strong, nonatomic) UIWindow *window;
+
 + (ViewController*)getViewController;
 
 @end

+ 10 - 2
platform/iphone/app_delegate.mm

@@ -65,6 +65,8 @@ Error _shell_open(String p_uri) {
 
 @implementation AppDelegate
 
+@synthesize window;
+
 extern int gargc;
 extern char** gargv;
 extern int iphone_main(int, int, int, char**);
@@ -127,7 +129,7 @@ static int frame_count = 0;
 
 		OSIPhone::get_singleton()->set_unique_ID(String::utf8([uuid UTF8String]));
 
-	}; // break;
+	}; break;
 /*
 	case 1: {
 		++frame_count;
@@ -154,7 +156,7 @@ static int frame_count = 0;
 		[Appirater appLaunched:YES app_id:aid];
 		#endif
 
-	}; //  break; fallthrough
+	}; break; // no fallthrough
 
 	default: {
 
@@ -260,6 +262,9 @@ static int frame_count = 0;
 	if (OS::get_singleton()->get_main_loop())
 		OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
 	[view_controller.view stopAnimation];
+	if (OS::get_singleton()->native_video_is_playing()) {
+		OSIPhone::get_singleton()->native_video_focus_out();
+	};
 }
 
 - (void)applicationWillEnterForeground:(UIApplication *)application
@@ -286,6 +291,9 @@ static int frame_count = 0;
 	if (OS::get_singleton()->get_main_loop())
 		OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
 	[view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere
+	if (OSIPhone::get_singleton()->native_video_is_playing()) {
+		OSIPhone::get_singleton()->native_video_unpause();
+	};
 }
 
 - (void)accelerometer:(UIAccelerometer*)accelerometer didAccelerate:(UIAcceleration*)acceleration {

+ 4 - 4
platform/iphone/detect.py

@@ -21,8 +21,7 @@ def get_opts():
 	return [
 		('IPHONEPLATFORM', 'name of the iphone platform', 'iPhoneOS'),
 		('IPHONEPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'),
-		#('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS7.0'),
-		('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS8.1'),
+		('IOS_SDK_VERSION', 'The SDK version', 'iPhoneOS'),
 		('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/${IOS_SDK_VERSION}.sdk/'),
 		('game_center', 'Support for game center', 'yes'),
 		('store_kit', 'Support for in-app store', 'yes'),
@@ -81,6 +80,7 @@ def configure(env):
 							#'-framework', 'AdSupport',
 							'-framework', 'MediaPlayer',
 							'-framework', 'AVFoundation',
+							'-framework', 'CoreMedia',
 							])
 
 	if env['game_center'] == 'yes':
@@ -95,8 +95,8 @@ def configure(env):
 
 	if (env["target"]=="release"):
 
-		env.Append(CCFLAGS=['-Os', '-ffast-math', '-DNS_BLOCK_ASSERTIONS=1','-Wall'])
-		env.Append(LINKFLAGS=['-Os', '-ffast-math'])
+		env.Append(CCFLAGS=['-O3', '-ffast-math', '-DNS_BLOCK_ASSERTIONS=1','-Wall'])
+		env.Append(LINKFLAGS=['-O3', '-ffast-math'])
 
 	elif env["target"] == "release_debug":
 		env.Append(CCFLAGS=['-Os', '-ffast-math', '-DNS_BLOCK_ASSERTIONS=1','-Wall','-DDEBUG_ENABLED'])

+ 54 - 3
platform/iphone/gl_view.mm

@@ -52,6 +52,7 @@ static GLView* _instance = NULL;
 static bool video_found_error = false;
 static bool video_playing = false;
 static float video_previous_volume = 0.0f;
+static CMTime video_current_time;
 
 void _show_keyboard(String p_existing) {
 	keyboard_text = p_existing;
@@ -107,6 +108,8 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
 
 	_instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]];
 	_instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset];
+	[_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil];
+
     _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
     _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
 
@@ -122,6 +125,7 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
 
 	AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible];
 
+	NSMutableArray *allAudioParams = [NSMutableArray array];
 	for (id track in audioGroup.options)
 	{
 		NSString* language = [[track locale] localeIdentifier];
@@ -129,7 +133,17 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
         
         if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]])
         {
-            [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: audioGroup];
+			AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
+			[audioInputParams setVolume:p_volume atTime:kCMTimeZero];
+			[audioInputParams setTrackID:[track trackID]];
+			[allAudioParams addObject:audioInputParams];
+
+			AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
+			[audioMix setInputParameters:allAudioParams];
+
+			[_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: audioGroup];
+			[_instance.avPlayer.currentItem setAudioMix:audioMix];
+
             break;
         }
 	}
@@ -166,10 +180,24 @@ bool _is_video_playing() {
 
 void _pause_video() {
 	//[_instance.moviePlayerController pause];
+	video_current_time = _instance.avPlayer.currentTime;
 	[_instance.avPlayer pause];
 	video_playing = false;
 }
 
+void _focus_out_video() {
+	printf("focus out pausing video\n");
+	[_instance.avPlayer pause];
+};
+
+void _unpause_video() {
+
+	[_instance.avPlayer play];
+	video_playing = true;
+
+	//video_current_time = kCMTimeZero;
+};
+
 void _stop_video() {
 	//[_instance.moviePlayerController stop];
 	//[_instance.moviePlayerController.view removeFromSuperview];
@@ -390,6 +418,11 @@ static void clear_touches() {
 	active = TRUE;
 	printf("start animation!\n");
 	animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
+
+	if (video_playing)
+	{
+		_unpause_video();
+	}
 }
 
 - (void)stopAnimation
@@ -401,6 +434,11 @@ static void clear_touches() {
 	[animationTimer invalidate];
 	animationTimer = nil;
 	clear_touches();
+
+	if (video_playing)
+	{
+		// save position
+	}
 }
 
 - (void)setAnimationInterval:(NSTimeInterval)interval
@@ -439,9 +477,11 @@ static void clear_touches() {
 	glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
 	[context presentRenderbuffer:GL_RENDERBUFFER_OES];
 	
+#ifdef DEBUG_ENABLED
 	GLenum err = glGetError();
 	if(err)
 		NSLog(@"%x error", err);
+#endif
 }
 
 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
@@ -589,11 +629,22 @@ static void clear_touches() {
 
 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
                         change:(NSDictionary *)change context:(void *)context {
-    if (object == _instance.avPlayer && [keyPath isEqualToString:@"status"]) {
-        if (_instance.avPlayer.status == AVPlayerStatusFailed) {
+
+	if (object == _instance.avPlayerItem && [keyPath isEqualToString:@"status"]) {
+        if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) {
         	_stop_video();
             video_found_error = true;
         }
+
+        if(_instance.avPlayer.status == AVPlayerStatusReadyToPlay && 
+        	_instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay && 
+        	CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) {
+
+        	//NSLog(@"time: %@", video_current_time);
+
+    		[_instance.avPlayer seekToTime:video_current_time];
+    		video_current_time = kCMTimeZero;
+		}
     }
 }
 

+ 42 - 18
platform/iphone/os_iphone.cpp

@@ -40,6 +40,7 @@
 #include "audio_driver_iphone.h"
 
 #include "core/os/dir_access.h"
+#include "core/os/file_access.h"
 #include "core/globals.h"
 
 #include "sem_iphone.h"
@@ -77,7 +78,7 @@ void OSIPhone::set_data_dir(String p_dir) {
 	DirAccess* da = DirAccess::open(p_dir);
 
 	data_dir = da->get_current_dir();
-
+	printf("setting data dir to %ls from %ls\n", data_dir.c_str(), p_dir.c_str());
 	memdelete(da);
 };
 
@@ -211,14 +212,16 @@ void OSIPhone::key(uint32_t p_key, bool p_pressed) {
 
 void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) {
 
-	InputEvent ev;
-	ev.type = InputEvent::SCREEN_TOUCH;
-	ev.ID = ++last_event_id;
-	ev.screen_touch.index=p_idx;
-	ev.screen_touch.pressed=p_pressed;
-	ev.screen_touch.x=p_x;
-	ev.screen_touch.y=p_y;
-	queue_event(ev);
+	if (!GLOBAL_DEF("debug/disable_touch", false)) {
+		InputEvent ev;
+		ev.type = InputEvent::SCREEN_TOUCH;
+		ev.ID = ++last_event_id;
+		ev.screen_touch.index=p_idx;
+		ev.screen_touch.pressed=p_pressed;
+		ev.screen_touch.x=p_x;
+		ev.screen_touch.y=p_y;
+		queue_event(ev);
+	};
 
 	if (p_use_as_mouse) {
 
@@ -234,6 +237,7 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
 		ev.mouse_button.x = ev.mouse_button.global_x = p_x;
 		ev.mouse_button.y = ev.mouse_button.global_y = p_y;
 
+		input->set_mouse_pos(Point2(ev.mouse_motion.x,ev.mouse_motion.y));
 		ev.mouse_button.button_index = BUTTON_LEFT;
 		ev.mouse_button.doubleclick = p_doubleclick;
 		ev.mouse_button.pressed = p_pressed;
@@ -246,15 +250,18 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
 
 void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, bool p_use_as_mouse) {
 
-	InputEvent ev;
-	ev.type=InputEvent::SCREEN_DRAG;
-	ev.ID = ++last_event_id;
-	ev.screen_drag.index=p_idx;
-	ev.screen_drag.x=p_x;
-	ev.screen_drag.y=p_y;
-	ev.screen_drag.relative_x = p_x - p_prev_x;
-	ev.screen_drag.relative_y = p_y - p_prev_y;
-	queue_event(ev);
+	if (!GLOBAL_DEF("debug/disable_touch", false)) {
+
+		InputEvent ev;
+		ev.type=InputEvent::SCREEN_DRAG;
+		ev.ID = ++last_event_id;
+		ev.screen_drag.index=p_idx;
+		ev.screen_drag.x=p_x;
+		ev.screen_drag.y=p_y;
+		ev.screen_drag.relative_x = p_x - p_prev_x;
+		ev.screen_drag.relative_y = p_y - p_prev_y;
+		queue_event(ev);
+	};
 
 	if (p_use_as_mouse) {
 		InputEvent ev;
@@ -488,9 +495,18 @@ String OSIPhone::get_locale() const {
 extern bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
 extern bool _is_video_playing();
 extern void _pause_video();
+extern void _unpause_video();
 extern void _stop_video();
+extern void _focus_out_video();
 
 Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
+	FileAccess* f = FileAccess::open(p_path, FileAccess::READ);
+	bool exists = f && f->is_open();
+	printf("file exists for %ls, %i, %p\n", p_path.c_str(), (int)exists, f);
+	if (f)
+		memdelete(f);
+	if (!exists)
+		return FAILED;
     if ( _play_video(p_path, p_volume, p_audio_track, p_subtitle_track) )
 		return OK;
 	return FAILED;
@@ -505,6 +521,14 @@ void OSIPhone::native_video_pause() {
     	_pause_video();
 }
 
+void OSIPhone::native_video_unpause() {
+	_unpause_video();
+};
+
+void OSIPhone::native_video_focus_out() {
+	_focus_out_video();
+};
+
 void OSIPhone::native_video_stop() {
 	if (native_video_is_playing())
     	_stop_video();

+ 2 - 0
platform/iphone/os_iphone.h

@@ -187,6 +187,8 @@ public:
     virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
     virtual bool native_video_is_playing() const;
     virtual void native_video_pause();
+	virtual void native_video_unpause();
+	virtual void native_video_focus_out();
     virtual void native_video_stop();
 
 	OSIPhone(int width, int height);

+ 42 - 0
platform/windows/os_windows.cpp

@@ -52,8 +52,11 @@
 #include "os/memory_pool_dynamic_prealloc.h"
 #include "globals.h"
 #include "io/marshalls.h"
+
+#include "shlobj.h"
 static const WORD MAX_CONSOLE_LINES = 1500;
 
+
 //#define STDOUT_FILE
 
 extern HINSTANCE godot_hinstance;
@@ -1875,7 +1878,46 @@ MainLoop *OS_Windows::get_main_loop() const {
 	return main_loop;
 }
 
+String OS_Windows::get_system_dir(SystemDir p_dir) const {
+
+
+	int id;
+
+
+
+	switch(p_dir) {
+		case SYSTEM_DIR_DESKTOP: {
+			id=CSIDL_DESKTOPDIRECTORY;
+		} break;
+		case SYSTEM_DIR_DCIM: {
+			id=CSIDL_MYPICTURES;
+		} break;
+		case SYSTEM_DIR_DOCUMENTS: {
+			id=0x000C;
+		} break;
+		case SYSTEM_DIR_DOWNLOADS: {
+			id=0x000C ;
+		} break;
+		case SYSTEM_DIR_MOVIES: {
+			id=CSIDL_MYVIDEO;
+		} break;
+		case SYSTEM_DIR_MUSIC: {
+			id=CSIDL_MYMUSIC;
+		} break;
+		case SYSTEM_DIR_PICTURES: {
+			id=CSIDL_MYPICTURES;
+		} break;
+		case SYSTEM_DIR_RINGTONES: {
+			id=CSIDL_MYMUSIC;
+		} break;
+	}
+
+	WCHAR szPath[MAX_PATH];
+	HRESULT res = SHGetFolderPathW(NULL,id,NULL,0,szPath);
+	ERR_FAIL_COND_V(res!=S_OK,String());
+	return String(szPath);
 
+}
 String OS_Windows::get_data_dir() const {
 
 	String an = Globals::get_singleton()->get("application/name");

+ 2 - 0
platform/windows/os_windows.h

@@ -249,6 +249,8 @@ public:
 
 	virtual void move_window_to_foreground();
 	virtual String get_data_dir() const;
+	virtual String get_system_dir(SystemDir p_dir) const;
+
 
 	virtual void release_rendering_thread();
 	virtual void make_rendering_thread();

+ 67 - 1
platform/x11/os_x11.cpp

@@ -1089,7 +1089,73 @@ String OS_X11::get_name() {
 
 Error OS_X11::shell_open(String p_uri) {
 
-	return ERR_UNAVAILABLE;
+	Error ok;
+	List<String> args;
+	args.push_back(p_uri);
+	ok = execute("/usr/bin/xdg-open",args,false);
+	if (ok==OK)
+		return OK;
+	ok = execute("gnome-open",args,false);
+	if (ok==OK)
+		return OK;
+	ok = execute("kde-open",args,false);
+	return ok;
+}
+
+String OS_X11::get_system_dir(SystemDir p_dir) const {
+
+
+	String xdgparam;
+
+	switch(p_dir) {
+		case SYSTEM_DIR_DESKTOP: {
+
+			xdgparam="DESKTOP";
+		} break;
+		case SYSTEM_DIR_DCIM: {
+
+			xdgparam="PICTURES";
+
+		} break;
+		case SYSTEM_DIR_DOCUMENTS: {
+
+			xdgparam="DOCUMENTS";
+
+		} break;
+		case SYSTEM_DIR_DOWNLOADS: {
+
+			xdgparam="DOWNLOAD";
+
+		} break;
+		case SYSTEM_DIR_MOVIES: {
+
+			xdgparam="VIDEOS";
+
+		} break;
+		case SYSTEM_DIR_MUSIC: {
+
+			xdgparam="MUSIC";
+
+		} break;
+		case SYSTEM_DIR_PICTURES: {
+
+			xdgparam="PICTURES";
+
+		} break;
+		case SYSTEM_DIR_RINGTONES: {
+
+			xdgparam="MUSIC";
+
+		} break;
+	}
+
+	String pipe;
+	List<String> arg;
+	arg.push_back(xdgparam);
+	Error err = const_cast<OS_X11*>(this)->execute("/usr/bin/xdg-user-dir",arg,true,NULL,&pipe);
+	if (err!=OK)
+		return ".";
+	return pipe.strip_edges();
 }
 
 

+ 2 - 0
platform/x11/os_x11.h

@@ -202,6 +202,8 @@ public:
 	virtual void make_rendering_thread();
 	virtual void swap_buffers();
 
+	virtual String get_system_dir(SystemDir p_dir) const;
+
 	virtual Error shell_open(String p_uri);
 
 	virtual void set_video_mode(const VideoMode& p_video_mode,int p_screen=0);

+ 1 - 1
scene/animation/animation_player.cpp

@@ -374,7 +374,7 @@ void AnimationPlayer::_animation_process_animation(AnimationData* p_anim,float p
 
 
 				Error err = a->transform_track_interpolate(i,p_time,&loc,&rot,&scale);
-				ERR_CONTINUE(err!=OK); //used for testing, should be removed
+				//ERR_CONTINUE(err!=OK); //used for testing, should be removed
 
 
 				if (err!=OK)

+ 3 - 3
scene/audio/sound_room_params.cpp

@@ -54,7 +54,7 @@ void SoundRoomParams::_notification(int p_what) {
 
 
 		case NOTIFICATION_ENTER_TREE: {
-#if 0
+//#if 0
 			Node *n=this;
 			Room *room_instance=NULL;
 			while(n) {
@@ -74,11 +74,11 @@ void SoundRoomParams::_notification(int p_what) {
 			if (room_instance) {
 				room=room_instance->get_sound_room();
 			} else {
-				room=get_scene()->get_default_world()->get_sound_space();
+				room=get_viewport()->find_world()->get_sound_space();
 			}
 
 			_update_sound_room();
-#endif
+//#endif
 
 		} break;
 		case NOTIFICATION_EXIT_TREE: {

+ 26 - 1
scene/gui/base_button.cpp

@@ -30,7 +30,7 @@
 #include "os/keyboard.h"
 #include "print_string.h"
 #include "button_group.h"
-
+#include "scene/scene_string_names.h"
 
 void BaseButton::_input_event(InputEvent p_event) {
 
@@ -60,12 +60,21 @@ void BaseButton::_input_event(InputEvent p_event) {
 						status.pressing_inside=true;
 
 						pressed();
+						if (get_script_instance()) {
+							Variant::CallError ce;
+							get_script_instance()->call(SceneStringNames::get_singleton()->_pressed,NULL,0,ce);
+						}
+
 						emit_signal("pressed");
 
 					} else {
 
 						status.pressed=!status.pressed;
 						pressed();
+						if (get_script_instance()) {
+							Variant::CallError ce;
+							get_script_instance()->call(SceneStringNames::get_singleton()->_pressed,NULL,0,ce);
+						}
 						emit_signal("pressed");
 
 						toggled(status.pressed);
@@ -99,6 +108,11 @@ void BaseButton::_input_event(InputEvent p_event) {
 					if (!toggle_mode) { //mouse press attempt
 
 						pressed();
+						if (get_script_instance()) {
+							Variant::CallError ce;
+							get_script_instance()->call(SceneStringNames::get_singleton()->_pressed,NULL,0,ce);
+						}
+
 						emit_signal("pressed");
 						
 					} else {
@@ -110,6 +124,10 @@ void BaseButton::_input_event(InputEvent p_event) {
 						
 						toggled(status.pressed);
 						emit_signal("toggled",status.pressed);
+						if (get_script_instance()) {
+							get_script_instance()->call(SceneStringNames::get_singleton()->_toggled,status.pressed);
+						}
+
 
 					}
 
@@ -177,6 +195,9 @@ void BaseButton::_input_event(InputEvent p_event) {
 						emit_signal("pressed");
 						
 						toggled(status.pressed);
+						if (get_script_instance()) {
+							get_script_instance()->call(SceneStringNames::get_singleton()->_toggled,status.pressed);
+						}
 						emit_signal("toggled",status.pressed);
 					}
 				}
@@ -362,6 +383,9 @@ void BaseButton::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("get_click_on_press"),&BaseButton::get_click_on_press);
 	ObjectTypeDB::bind_method(_MD("get_draw_mode"),&BaseButton::get_draw_mode);
 
+	BIND_VMETHOD(MethodInfo("_pressed"));
+	BIND_VMETHOD(MethodInfo("_toggled",PropertyInfo(Variant::BOOL,"pressed")));
+
 	ADD_SIGNAL( MethodInfo("pressed" ) );
 	ADD_SIGNAL( MethodInfo("released" ) );
 	ADD_SIGNAL( MethodInfo("toggled", PropertyInfo( Variant::BOOL,"pressed") ) );
@@ -369,6 +393,7 @@ 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 );

+ 1 - 3
scene/resources/circle_shape_2d.cpp

@@ -54,9 +54,7 @@ void CircleShape2D::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_radius","radius"),&CircleShape2D::set_radius);
 	ObjectTypeDB::bind_method(_MD("get_radius"),&CircleShape2D::get_radius);
 
-
-
-	ADD_PROPERTY( PropertyInfo(Variant::REAL,"radius"),_SCS("set_radius"),_SCS("get_radius") );
+	ADD_PROPERTY( PropertyInfo(Variant::REAL,"radius",PROPERTY_HINT_RANGE,"0.01,16384,0.5"),_SCS("set_radius"),_SCS("get_radius") );
 
 }
 

+ 3 - 0
scene/scene_string_names.cpp

@@ -147,4 +147,7 @@ SceneStringNames::SceneStringNames() {
 	_mouse_enter=StaticCString::create("_mouse_enter");
 	_mouse_exit=StaticCString::create("_mouse_exit");
 
+	_pressed=StaticCString::create("_pressed");
+	_toggled=StaticCString::create("_toggled");
+
 }

+ 3 - 0
scene/scene_string_names.h

@@ -95,6 +95,9 @@ public:
 	StringName _input;
 	StringName _ready;
 
+	StringName _pressed;
+	StringName _toggled;
+
 	StringName _update_scroll;
 	StringName _update_xform;
 

+ 24 - 13
tools/collada/collada.cpp

@@ -2250,29 +2250,35 @@ void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
 	}
 }
 
-void Collada::_create_skeletons(Collada::Node **p_node) {
+void Collada::_create_skeletons(Collada::Node **p_node,NodeSkeleton *p_skeleton) {
 
 
 	Node *node = *p_node;
 
-
-
 	if (node->type==Node::TYPE_JOINT) {
 
-		// ohohohoohoo it's a joint node, time to work!
+		if (!p_skeleton) {
+
+			// ohohohoohoo it's a joint node, time to work!
+			NodeSkeleton *sk = memnew( NodeSkeleton );
+			*p_node=sk;
+			sk->children.push_back(node);
+			sk->parent=node->parent;
+			node->parent=sk;
+			p_skeleton=sk;
+		}
 
-		NodeSkeleton *sk = memnew( NodeSkeleton );
-		*p_node=sk;
-		sk->children.push_back(node);
-		sk->parent=node->parent;
-		node->parent=sk;
-		_joint_set_owner(node,sk);
+		NodeJoint *nj = static_cast<NodeJoint*>(node);
+		nj->owner=p_skeleton;
 	} else {
+		p_skeleton=NULL;
+	}
 
-		for(int i=0;i<node->children.size();i++) {
-			_create_skeletons(&node->children[i]);
-		}
+
+	for(int i=0;i<node->children.size();i++) {
+		_create_skeletons(&node->children[i],p_skeleton);
 	}
+
 }
 
 bool Collada::_remove_node(Node *p_parent,Node *p_node) {
@@ -2325,6 +2331,9 @@ void Collada::_merge_skeletons(VisualScene *p_vscene,Node *p_node) {
 
 
 				NodeJoint *nj = SAFE_CAST<NodeJoint*>(state.scene_map[nodeid]);
+				if (!nj->owner) {
+					print_line("no owner for: "+String(nodeid));
+				}
 				ERR_CONTINUE( !nj->owner ); //weird, node should have a skeleton owner
 
 				skeletons.insert(nj->owner);
@@ -2626,6 +2635,7 @@ void Collada::_optimize() {
 			_create_skeletons(&vs.root_nodes[i]);
 
 		}
+#if 1
 		for(int i=0;i<vs.root_nodes.size();i++) {
 			_merge_skeletons(&vs,vs.root_nodes[i]);
 		}
@@ -2653,6 +2663,7 @@ void Collada::_optimize() {
 			}
 
 		}
+#endif
 		for(int i=0;i<vs.root_nodes.size();i++) {
 			_find_morph_nodes(&vs,vs.root_nodes[i]);
 		}

+ 1 - 1
tools/collada/collada.h

@@ -619,7 +619,7 @@ private: // private stuff
 	Transform _read_transform(XMLParser& parser);
 
 	void _joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner);
-	void _create_skeletons(Collada::Node **p_node);
+	void _create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton=NULL);
 	void _find_morph_nodes(VisualScene *p_vscene,Node *p_node);
 	bool _remove_node(Node *p_parent,Node *p_node);
 	void _remove_node(VisualScene *p_vscene,Node *p_node);

+ 1 - 1
tools/editor/editor_import_export.cpp

@@ -938,7 +938,7 @@ Error EditorExportPlatform::save_pack(FileAccess *dst,bool p_make_bundles) {
 	dst->store_32(0); //pack version
 	dst->store_32(VERSION_MAJOR);
 	dst->store_32(VERSION_MINOR);
-	dst->store_32(VERSION_REVISION);
+	dst->store_32(0); //hmph
 	for(int i=0;i<16;i++) {
 		//reserved
 		dst->store_32(0);

+ 54 - 12
tools/editor/io_plugins/editor_import_collada.cpp

@@ -61,6 +61,7 @@ struct ColladaImport {
 	Color ambient;
 	bool found_directional;
 	bool force_make_tangents;
+	bool apply_mesh_xform_to_vertices;
 	float bake_fps;
 
 
@@ -69,6 +70,7 @@ struct ColladaImport {
 	Map<String, Ref<Mesh> > mesh_cache;
 	Map<String, Ref<Curve3D> > curve_cache;
 	Map<String, Ref<Material> > material_cache;
+	Map<Collada::Node*,Skeleton*> skeleton_map;
 
 	Map< Skeleton*, Map< String, int> > skeleton_bone_map;
 
@@ -77,6 +79,7 @@ struct ColladaImport {
 	Map<String,bool> bones_with_animation;
 
 	Error _populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_node, int &r_bone, int p_parent);
+	Error _create_scene_skeletons(Collada::Node *p_node);
 	Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
 	Error _create_resources(Collada::Node *p_node);
 	Error _create_material(const String& p_material);
@@ -96,6 +99,7 @@ struct ColladaImport {
 		found_ambient=false;
 		found_directional=false;
 		force_make_tangents=false;
+		apply_mesh_xform_to_vertices=true;
 		bake_fps=15;
 
 	}
@@ -110,7 +114,7 @@ Error ColladaImport::_populate_skeleton(Skeleton *p_skeleton,Collada::Node *p_no
 
 	Collada::NodeJoint *joint = static_cast<Collada::NodeJoint*>(p_node);
 
-
+	print_line("populating joint "+joint->name);
 	p_skeleton->add_bone(p_node->name);
 	if (p_parent>=0)
 		p_skeleton->set_bone_parent(r_bone,p_parent);
@@ -170,6 +174,34 @@ void ColladaImport::_pre_process_lights(Collada::Node *p_node) {
 		_pre_process_lights(p_node->children[i]);
 }
 
+Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
+
+
+	if (p_node->type==Collada::Node::TYPE_SKELETON) {
+
+		Skeleton *sk = memnew( Skeleton );
+		int bone = 0;
+
+		for(int i=0;i<p_node->children.size();i++) {
+
+			_populate_skeleton(sk,p_node->children[i],bone,-1);
+		}
+		sk->localize_rests(); //after creating skeleton, rests must be localized...!
+		skeleton_map[p_node]=sk;
+	}
+
+
+	for(int i=0;i<p_node->children.size();i++) {
+
+		Error err = _create_scene_skeletons(p_node->children[i]);
+		if (err)
+			return err;
+	}
+	return OK;
+
+}
+
+
 Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
 
 	Spatial * node=NULL;
@@ -297,15 +329,8 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
 		} break;
 		case Collada::Node::TYPE_SKELETON: {
 
-			Skeleton *sk = memnew( Skeleton );
-			int bone = 0;
-
-			for(int i=0;i<p_node->children.size();i++) {
-
-				_populate_skeleton(sk,p_node->children[i],bone,-1);
-			}
-			sk->localize_rests(); //after creating skeleton, rests must be localized...!
-
+			ERR_FAIL_COND_V(!skeleton_map.has(p_node),ERR_CANT_CREATE);
+			Skeleton *sk = skeleton_map[p_node];
 			node=sk;
 		} break;
 
@@ -1502,6 +1527,9 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
 					ERR_FAIL_COND_V( skeletons.empty(), ERR_INVALID_DATA );
 
 					String skname = skeletons[0];
+					if (!node_map.has(skname)) {
+						print_line("no node for skeleton "+skname);
+					}
 					ERR_FAIL_COND_V( !node_map.has(skname), ERR_INVALID_DATA );
 					NodeMap nmsk = node_map[skname];
 					Skeleton *sk = nmsk.node->cast_to<Skeleton>();
@@ -1518,8 +1546,12 @@ Error ColladaImport::_create_resources(Collada::Node *p_node) {
 						meshid=morph->mesh;
 					}
 
-					apply_xform=collada.fix_transform(p_node->default_transform);
-					node->set_transform(Transform());
+					if (apply_mesh_xform_to_vertices) {
+						apply_xform=collada.fix_transform(p_node->default_transform);
+						node->set_transform(Transform());
+					} else {
+						apply_xform=Transform();
+					}
 
 					Collada::SkinControllerData::Source *joint_src=NULL;
 
@@ -1615,6 +1647,16 @@ Error ColladaImport::load(const String& p_path,int p_flags,bool p_force_make_tan
 
 	}
 	//import scene
+
+	for(int i=0;i<vs.root_nodes.size();i++) {
+
+		Error err = _create_scene_skeletons(vs.root_nodes[i]);
+		if (err!=OK)  {
+			memdelete(scene);
+			ERR_FAIL_COND_V(err,err);
+		}
+	}
+
 	for(int i=0;i<vs.root_nodes.size();i++) {
 
 		Error err = _create_scene(vs.root_nodes[i],scene);

+ 33 - 4
tools/export/blender25/io_scene_dae/export_dae.py

@@ -863,6 +863,20 @@ class DaeExporter:
 			if (node.parent.type=="ARMATURE"):
 				armature=node.parent
 
+		if (node.data.shape_keys!=None):
+				sk = node.data.shape_keys
+				if (sk.animation_data):
+					print("HAS ANIM")
+					print("DRIVERS: "+str(len(sk.animation_data.drivers)))
+					for d in sk.animation_data.drivers:
+						if (d.driver):
+							for v in d.driver.variables:
+								for t in v.targets:
+									if (t.id!=None and t.id.name in self.scene.objects):
+										print("LINKING "+str(node)+" WITH "+str(t.id.name))
+										self.armature_for_morph[node]=self.scene.objects[t.id.name]
+
+
 		meshdata = self.export_mesh(node,armature)
 		close_controller=False
 
@@ -1157,7 +1171,7 @@ class DaeExporter:
 
 
 	def export_node(self,node,il):
-		if (not self.is_node_valid(node)):
+		if (not node in self.valid_nodes):
 			return
 		bpy.context.scene.objects.active = node
 
@@ -1177,7 +1191,6 @@ class DaeExporter:
 		elif (node.type=="LAMP"):
 			self.export_lamp_node(node,il)
 
-		self.valid_nodes.append(node)
 		for x in node.children:
 			self.export_node(x,il)
 
@@ -1189,6 +1202,7 @@ class DaeExporter:
 			return False
 		if (self.config["use_active_layers"]):
 			valid=False
+			print("NAME: "+node.name)
 			for i in range(20):
 				if (node.layers[i] and  self.scene.layers[i]):
 					valid=True
@@ -1208,8 +1222,21 @@ class DaeExporter:
 		self.writel(S_NODES,0,'<library_visual_scenes>')
 		self.writel(S_NODES,1,'<visual_scene id="'+self.scene_name+'" name="scene">')
 
+		#validate nodes
 		for obj in self.scene.objects:
-			if (obj.parent==None):
+			if (obj in self.valid_nodes):
+				continue
+			if (self.is_node_valid(obj)):
+				n = obj
+				while (n!=None):
+					if (not n in self.valid_nodes):
+						self.valid_nodes.append(n)
+					n=n.parent
+
+
+
+		for obj in self.scene.objects:
+			if (obj in self.valid_nodes and obj.parent==None):
 				self.export_node(obj,2)
 
 		self.writel(S_NODES,1,'</visual_scene>')
@@ -1339,6 +1366,7 @@ class DaeExporter:
 					if (node.type=="MESH" and node.data!=None and (node in self.armature_for_morph) and (self.armature_for_morph[node] in allowed)):
 						pass #all good you pass with flying colors for morphs inside of action
 					else:
+						#print("fail "+str((node in self.armature_for_morph)))
 						continue
 				if (node.type=="MESH" and node.data!=None and node.data.shape_keys!=None and (node.data in self.mesh_cache) and len(node.data.shape_keys.key_blocks)):
 					target = self.mesh_cache[node.data]["morph_id"]
@@ -1453,7 +1481,7 @@ class DaeExporter:
 									allowed_skeletons.append(y)
 						y.animation_data.action=x;
 
-
+				print("allowed skeletons "+str(allowed_skeletons))
 
 				print(str(x))
 
@@ -1563,6 +1591,7 @@ class DaeExporter:
 
 
 
+
 def save(operator, context,
 	filepath="",
 	use_selection=False,

+ 1 - 2
version.py

@@ -2,7 +2,6 @@ short_name="godot"
 name="Godot Engine"
 major=1
 minor=0
-revision="$Rev: 3917 $"
-status="beta1"
+status="rc1"