فهرست منبع

SceneLoader Instances

Sebastien Vandenberghe 7 سال پیش
والد
کامیت
90fff7ae08
3فایلهای تغییر یافته به همراه41 افزوده شده و 14 حذف شده
  1. 7 1
      loaders/src/glTF/babylon.glTFFileLoader.ts
  2. 32 11
      src/Loading/babylon.sceneLoader.ts
  3. 2 2
      src/Tools/babylon.tools.ts

+ 7 - 1
loaders/src/glTF/babylon.glTFFileLoader.ts

@@ -23,7 +23,7 @@ module BABYLON {
         loadAsync: (scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
     }
 
-    export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync {
+    export class GLTFFileLoader implements IDisposable, ISceneLoaderPluginAsync, ISceneLoaderPluginFactory {
         public static CreateGLTFLoaderV1: (parent: GLTFFileLoader) => IGLTFLoader;
         public static CreateGLTFLoaderV2: (parent: GLTFFileLoader) => IGLTFLoader;
 
@@ -102,6 +102,12 @@ module BABYLON {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         }
 
+        public rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
+
+        public createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
+            return new GLTFFileLoader();
+        }
+
         private static _parse(data: string | ArrayBuffer): IGLTFLoaderData {
             if (data instanceof ArrayBuffer) {
                 return GLTFFileLoader._parseBinary(data);

+ 32 - 11
src/Loading/babylon.sceneLoader.ts

@@ -5,12 +5,19 @@
         };
     }
 
+    export interface ISceneLoaderPluginFactory {
+        name: string;
+        createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        canDirectLoad?: (data: string) => boolean;
+    }
+
     export interface ISceneLoaderPlugin {
         name: string;
         extensions: string | ISceneLoaderPluginExtensions;
         importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[], onError?: (message: string, exception?: any) => void) => boolean;
         load: (scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void) => boolean;
         canDirectLoad?: (data: string) => boolean;
+        rewriteRootURL?: (rootUrl: string, responseURL?: string) => string;
     }
 
     export interface ISceneLoaderPluginAsync {
@@ -19,10 +26,11 @@
         importMeshAsync: (meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress: (event: ProgressEvent) => void, onError: (message: string) => void) => void;
         loadAsync: (scene: Scene, data: string, rootUrl: string, onSuccess: () => void, onProgress: (event: ProgressEvent) => void, onError: (message: string, exception?: any) => void) => void;
         canDirectLoad?: (data: string) => boolean;
+        rewriteRootURL?: (rootUrl: string, responseURL?: string) => string;
     }
 
     interface IRegisteredPlugin {
-        plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+        plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory;
         isBinary: boolean;
     }
 
@@ -138,16 +146,24 @@
             return null;
         }
 
-        private static _loadData(rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: (plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync, data: any) => void, onProgress: (event: ProgressEvent) => void, onError: (message: Nullable<string>, exception?: any) => void, pluginExtension?: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
+        private static _loadData(rootUrl: string, sceneFilename: string, scene: Scene, onSuccess: (plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync, data: any, responseURL?: string) => void, onProgress: (event: ProgressEvent) => void, onError: (message: Nullable<string>, exception?: any) => void, pluginExtension?: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
             var directLoad = SceneLoader._getDirectLoad(sceneFilename);
             var registeredPlugin = pluginExtension ? SceneLoader._getPluginForExtension(pluginExtension) : (directLoad ? SceneLoader._getPluginForDirectLoad(sceneFilename) : SceneLoader._getPluginForFilename(sceneFilename));
-            var plugin = registeredPlugin.plugin;
+
+            let plugin: ISceneLoaderPlugin | ISceneLoaderPluginAsync;
+            if ((registeredPlugin.plugin as ISceneLoaderPluginFactory).createPlugin) {
+                plugin = (registeredPlugin.plugin as ISceneLoaderPluginFactory).createPlugin();
+            }
+            else {
+                plugin = <any>registeredPlugin.plugin;
+            }
+
             var useArrayBuffer = registeredPlugin.isBinary;
             var database: Database;
 
-            SceneLoader.OnPluginActivatedObservable.notifyObservers(registeredPlugin.plugin);
+            SceneLoader.OnPluginActivatedObservable.notifyObservers(plugin);
 
-            var dataCallback = (data: any) => {
+            var dataCallback = (data: any, responseURL?: string) => {
                 if (scene.isDisposed) {
                     onError("Scene has been disposed");
                     return;
@@ -156,7 +172,7 @@
                 scene.database = database;
 
                 try {
-                    onSuccess(plugin, data);
+                    onSuccess(plugin, data, responseURL);
                 }
                 catch (e) {
                     onError(null, e);
@@ -173,7 +189,7 @@
 
             if (directLoad) {
                 dataCallback(directLoad);
-                return registeredPlugin.plugin;
+                return plugin;
             }
 
             if (rootUrl.indexOf("file:") === -1) {
@@ -197,11 +213,11 @@
                     onError("Unable to find file named " + sceneFilename);
                 }
             }
-            return registeredPlugin.plugin;
+            return plugin;
         }
 
         // Public functions
-        public static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync {
+        public static GetPluginForExtension(extension: string): ISceneLoaderPlugin | ISceneLoaderPluginAsync | ISceneLoaderPluginFactory {
             return SceneLoader._getPluginForExtension(extension).plugin;
         }
 
@@ -260,12 +276,17 @@
                 }
             };
 
-            return SceneLoader._loadData(rootUrl, sceneFilename, scene, (plugin, data) => {
+            return SceneLoader._loadData(rootUrl, sceneFilename, scene, (plugin, data, responseURL) => {
+                if (plugin.rewriteRootURL) {
+                    rootUrl = plugin.rewriteRootURL(rootUrl, responseURL);
+                }
+
                 if ((<any>plugin).importMesh) {
                     var syncedPlugin = <ISceneLoaderPlugin>plugin;
                     var meshes = new Array<AbstractMesh>();
                     var particleSystems = new Array<ParticleSystem>();
                     var skeletons = new Array<Skeleton>();
+
                     if (!syncedPlugin.importMesh(meshNames, scene, data, rootUrl, meshes, particleSystems, skeletons, errorHandler)) {
                         return;
                     }
@@ -353,7 +374,7 @@
                 }
             };
 
-            return SceneLoader._loadData(rootUrl, sceneFilename, scene, (plugin, data) => {
+            return SceneLoader._loadData(rootUrl, sceneFilename, scene, (plugin, data, responseURL) => {
                 if ((<any>plugin).load) {
                     var syncedPlugin = <ISceneLoaderPlugin>plugin;
                     if (!syncedPlugin.load(scene, data, rootUrl, errorHandler)) {

+ 2 - 2
src/Tools/babylon.tools.ts

@@ -489,7 +489,7 @@
         }
 
         //ANY
-        public static LoadFile(url: string, callback: (data: any) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): Nullable<XMLHttpRequest> {
+        public static LoadFile(url: string, callback: (data: any, responseURL?: string) => void, progressCallBack?: (data: any) => void, database?: Database, useArrayBuffer?: boolean, onError?: (request?: XMLHttpRequest, exception?: any) => void): Nullable<XMLHttpRequest> {
             url = Tools.CleanUrl(url);
 
             url = Tools.PreprocessUrl(url);
@@ -516,7 +516,7 @@
                         req.onreadystatechange = () => { };//some browsers have issues where onreadystatechange can be called multiple times with the same value
 
                         if (req.status >= 200 && req.status < 300 || (!Tools.IsWindowObjectExist() && (req.status === 0))) {
-                            callback(!useArrayBuffer ? req.responseText : req.response);
+                            callback(!useArrayBuffer ? req.responseText : req.response, req.responseURL);
                         } else { // Failed
                             let e = new Error("Error status: " + req.status + " - Unable to load " + loadUrl);
                             if (onError) {