Example #1
0
        /// <summary>
        /// Creates a resource loader if none is provided. This resource loader replaces
        /// "package:/" with <paramref name="dataDirectory"/> and <paramref name="dataDirectory"/>
        /// must be relative to a resource folder, i.e., if you put the data in Something/Resources/foo
        /// the <paramref name="dataDirectory"/> should be "foo".
        ///
        /// When Collada is a resource any rotation of the loaded game objects are removed.
        /// </summary>
        /// <remarks>
        ///   - If a Collada resource is missing, this loader checks if there's a .obj file with
        ///     the same name.
        ///   - If this method is used within the Editor, <paramref name="dataDirectory"/> should be relative
        ///     to the project directory (i.e, start with "Assets").
        /// </remarks>
        /// <param name="dataDirectory">Directory relative to a resource folder. Default: "" assuming
        ///                             the data to be structured as referenced in the URDF file inside
        ///                             a "Resources" folder.</param>
        /// <param name="resourceLoad">The actual call to Load. UnityEngine.Resources.Load by default (if null) and, e.g.,
        ///                            AssetDataBase.LoadAssetAtPath can be used when in the editor.</param>
        /// <returns>Resource loader function.</returns>
        public static Func <string, ResourceType, Object> CreateDefaultResourceLoader(string dataDirectory = "",
                                                                                      Func <string, ResourceType, Object> resourceLoad = null)
        {
            var isPlayerResource = resourceLoad == null;

            if (!string.IsNullOrEmpty(dataDirectory))
            {
                dataDirectory.Replace('\\', '/');
                if (!dataDirectory.EndsWith("/"))
                {
                    dataDirectory += '/';
                }
            }

            var loadedInstances = new List <GameObject>();
            Func <string, ResourceType, Object> resourceLoader = (resourceFilename, type) =>
            {
                if (type == ResourceType.FinalizedLoad)
                {
                    loadedInstances.ForEach(instance => Object.DestroyImmediate(instance));
                    loadedInstances = null;
                    return(null);
                }

                if (resourceFilename.StartsWith("package:/"))
                {
                    resourceFilename = dataDirectory + resourceFilename.Substring("package://".Length);
                }
                else if (!string.IsNullOrEmpty(dataDirectory))
                {
                    resourceFilename = dataDirectory + resourceFilename;
                }

                var hasExtension = Path.HasExtension(resourceFilename);
                var isStlFile    = hasExtension && Path.GetExtension(resourceFilename).ToLowerInvariant() == ".stl";
                var isCollada    = hasExtension && !isStlFile && Path.GetExtension(resourceFilename).ToLowerInvariant() == ".dae";

                // STL file we instantiate it and delete them at FinalizeLoad.
                if (isStlFile)
                {
                    var stlInstances = StlFileImporter.Instantiate(resourceFilename);
                    loadedInstances.AddRange(stlInstances);
                    return(stlInstances.FirstOrDefault());
                }
                // Remove file extension when using Resources.Load.
                else if (isPlayerResource && hasExtension)
                {
                    resourceFilename = resourceFilename.Substring(0, resourceFilename.LastIndexOf('.'));
                }

                // Search for .obj file instead of Collada if we're not loading from Resources.
                if (!isPlayerResource &&
                    !File.Exists(resourceFilename) &&
                    isCollada)
                {
                    resourceFilename = resourceFilename.Substring(0, resourceFilename.Length - 3) + "obj";
                }

                var resource = resourceLoad != null?
                               resourceLoad(resourceFilename, type) :
                                   Resources.Load <Object>(resourceFilename);

                if (!isPlayerResource && isCollada && resource != null)
                {
                    var colladaInfo = Utils.ParseColladaInfo(resourceFilename);
                    var resourceGo  = resource as GameObject;
                    // Model implementation assumes Z-up, anything other than that
                    // has to be transformed.
                    if (resourceGo != null && !colladaInfo.IsDefault)
                    {
                        var colladaInstance = Object.Instantiate <GameObject>(resourceGo);
                        if (colladaInfo.UpAxis == Utils.ColladaInfo.Axis.Y)
                        {
                            colladaInstance.transform.rotation = Quaternion.Euler(-90, 0, 0) * colladaInstance.transform.rotation;
                        }
                        else if (colladaInfo.UpAxis == Utils.ColladaInfo.Axis.X)
                        {
                            colladaInstance.transform.rotation = Quaternion.Euler(-90, 0, 90) * colladaInstance.transform.rotation;
                        }
                        loadedInstances.Add(colladaInstance);
                        resource = colladaInstance;
                    }
                }

                return(resource);
            };

            return(resourceLoader);
        }
Example #2
0
        /// <summary>
        /// Creates a resource loader if none is provided. This resource loader replaces
        /// "package:/" with <paramref name="dataDirectory"/> and <paramref name="dataDirectory"/>
        /// must be relative to a resource folder, i.e., if you put the data in Something/Resources/foo
        /// the <paramref name="dataDirectory"/> should be "foo".
        ///
        /// When Collada is a resource any rotation of the loaded game objects are removed.
        /// </summary>
        /// <remarks>
        ///   - If a Collada resource is missing, this loader checks if there's a .obj file with
        ///     the same name.
        ///   - If this method is used within the Editor, <paramref name="dataDirectory"/> should be relative
        ///     to the project directory (i.e, start with "Assets").
        /// </remarks>
        /// <param name="dataDirectory">Directory relative to a resource folder. Default: "" assuming
        ///                             the data to be structured as referenced in the URDF file inside
        ///                             a "Resources" folder.</param>
        /// <param name="resourceLoad">The actual call to Load. UnityEngine.Resources.Load by default (if null) and, e.g.,
        ///                            AssetDataBase.LoadAssetAtPath can be used when in the editor.</param>
        /// <returns>Resource loader function.</returns>
        public static Func <string, ResourceType, Object> CreateDefaultResourceLoader(string dataDirectory = "",
                                                                                      Func <string, ResourceType, Object> resourceLoad = null)
        {
            var isPlayerResource = resourceLoad == null;

            if (!string.IsNullOrEmpty(dataDirectory))
            {
                dataDirectory.Replace('\\', '/');
                if (!dataDirectory.EndsWith("/"))
                {
                    dataDirectory += '/';
                }
            }

            var loadedInstances = new List <GameObject>();
            Func <string, ResourceType, Object> resourceLoader = (resourceFilename, type) =>
            {
                if (type == ResourceType.FinalizedLoad)
                {
                    loadedInstances.ForEach(instance => Object.DestroyImmediate(instance));
                    loadedInstances = null;
                    return(null);
                }

                if (resourceFilename.StartsWith("package:/"))
                {
                    resourceFilename = dataDirectory + resourceFilename.Substring("package://".Length);
                }
                else if (!string.IsNullOrEmpty(dataDirectory))
                {
                    resourceFilename = dataDirectory + resourceFilename;
                }

                var hasExtension  = Path.HasExtension(resourceFilename);
                var patchRotation = hasExtension && Path.GetExtension(resourceFilename).ToLower() == ".dae";
                var isStlFile     = hasExtension && Path.GetExtension(resourceFilename).ToLower() == ".stl";

                // STL file we instantiate it and delete them at FinalizeLoad.
                if (isStlFile)
                {
                    var stlInstances = StlFileImporter.Instantiate(resourceFilename);
                    loadedInstances.AddRange(stlInstances);
                    return(stlInstances.FirstOrDefault());
                }
                // Remove file extension when using Resources.Load.
                else if (isPlayerResource && Path.HasExtension(resourceFilename))
                {
                    resourceFilename = resourceFilename.Substring(0, resourceFilename.LastIndexOf('.'));
                }

                // Search for .obj file instead of Collada if we're not loading from Resources.
                if (!isPlayerResource &&
                    !File.Exists(resourceFilename) &&
                    resourceFilename.EndsWith(".dae"))
                {
                    resourceFilename = resourceFilename.Substring(0, resourceFilename.Length - 3) + "obj";
                }
                var resource = resourceLoad != null?
                               resourceLoad(resourceFilename, type) :
                                   Resources.Load <Object>(resourceFilename);

                // Unity adds a -90 rotation about x for unknown reasons - reverting that.
                if (resource != null && patchRotation)
                {
                    var resourceGo = resource as GameObject;
                    var transforms = resourceGo.GetComponentsInChildren <Transform>();
                    foreach (var transform in transforms)
                    {
                        transform.rotation = Quaternion.identity;
                    }
                }

                return(resource);
            };

            return(resourceLoader);
        }