private string CreateModelKey(string filePath, ModelImportOptions options) { string searchKey = filePath; if (options != null) { searchKey = searchKey + options.litDiffuse + options.localEulerAngles + options.localPosition + options.localScale + options.modelScaling + options.zUp; } return(searchKey); }
protected IEnumerator CreateRepresentationObject(EntityData entityData, VrXmlRepresentation representation) { string representationId = representation.id; string representationAssetName = representation.assetName; string representationAssetBundleName = representation.assetBundleName; EntityRepresentation.AssetType representationAssetType = EntityRepresentation.AssetType.None; EntityRepresentation.AssetPrimType representationAssetPrimType = EntityRepresentation.AssetPrimType.None; ModelImportOptions importOptions = representation.importOptions; switch (representation.assetType) { case VrXmlRepresentation.AssetType.Model: representationAssetType = EntityRepresentation.AssetType.Model; break; case VrXmlRepresentation.AssetType.AssetBundle: case VrXmlRepresentation.AssetType.Prefab: representationAssetType = EntityRepresentation.AssetType.Prefab; break; case VrXmlRepresentation.AssetType.Cube: case VrXmlRepresentation.AssetType.Sphere: case VrXmlRepresentation.AssetType.Cylinder: case VrXmlRepresentation.AssetType.Capsule: case VrXmlRepresentation.AssetType.Quad: case VrXmlRepresentation.AssetType.Plane: representationAssetType = EntityRepresentation.AssetType.Primitive; break; } if (representationAssetType == EntityRepresentation.AssetType.Primitive) { representationAssetPrimType = ConvertAssetTypeToAssetPrimType(representation.assetType); } yield return(CreateRepresentationObject( entityData, representationId, representationAssetName, representationAssetBundleName, representationAssetType, representationAssetPrimType, importOptions)); }
protected IEnumerator CreateRepresentationObject( EntityData entityData, string representationId, string representationAssetName, string representationAssetBundleName, EntityRepresentation.AssetType representationAssetType, EntityRepresentation.AssetPrimType representationAssetPrimType, ModelImportOptions importOptions ) { bool created = false; EntityRepresentation entityRepresentation = null; //if (!string.IsNullOrEmpty(representationId)) { PrimitiveType?primitiveCreated = null; EntityRepresentation.AssetPrimType primType = EntityRepresentation.AssetPrimType.None; switch (representationAssetType) { //case EntityRepresentation.AssetType.AssetBundle: // if (!string.IsNullOrEmpty(representationAssetBundleName) // && !string.IsNullOrEmpty(representationAssetName)) // { // yield return InstantiateGameObjectAsync(representationAssetBundleName, representationAssetName, representationId, entityData.id); // created = true; // } // break; case EntityRepresentation.AssetType.Model: if (!string.IsNullOrEmpty(representationAssetName)) { ModelLoader importer = GetComponent <ModelLoader>(); if (importer == null) { importer = gameObject.AddComponent <ModelLoader>(); importer.CreatedModel += OnModelCreated; importer.ImportedModel += OnModelImported; importer.ImportError += OnModelError; } importer.ImportModelAsync(representationId, representationAssetName, entityObjects[entityData.id].transform, importOptions); while (importer.Running) { yield return(null); } EntityRepresentation entityRepr = null; while (entityRepr == null && !importer.ErrorOccurred) { yield return(null); entityRepr = entityObjects[entityData.id].GetComponentInChildren <EntityRepresentation>(); } if (entityRepr != null) { entityRepresentation = entityRepr; while (entityRepr.assetType != EntityRepresentation.AssetType.Model) { yield return(null); } entityRepr.assetName = representationAssetName; entityRepr.importOptions = importOptions; entityObjects[entityData.id].GetComponent <EntityData>().activeRepresentation = entityRepr; created = true; } } break; case EntityRepresentation.AssetType.AssetBundle: case EntityRepresentation.AssetType.Prefab: if (!string.IsNullOrEmpty(representationAssetName)) { // TODO: this must be documented string folder = "Representations/"; if (!string.IsNullOrEmpty(representationAssetBundleName)) { folder += representationAssetBundleName + "/"; } string resourceName = folder + representationAssetName; GameObject go = null; try { go = Instantiate(Resources.Load(resourceName), Vector3.zero, Quaternion.identity) as GameObject; } catch (Exception e) { Debug.LogError($"Failed to load resource {resourceName}: {e}"); } if (go) { go.transform.SetParent(entityData.transform, false); EntityRepresentation entityRepr = go.GetComponent <EntityRepresentation>(); if (entityRepr == null) { entityRepr = go.AddComponent <EntityRepresentation>(); } go.name = representationId; entityRepr.name = representationAssetName; entityRepr.assetName = representationAssetName; created = true; entityRepresentation = entityRepr; } } break; case EntityRepresentation.AssetType.Primitive: primitiveCreated = ConvertEntityToUnityPrimType(representationAssetPrimType); primType = representationAssetPrimType; break; } if (primitiveCreated.HasValue) { GameObject go = GameObject.CreatePrimitive(primitiveCreated.Value); if (go) { go.transform.SetParent(entityData.transform, false); EntityRepresentation entityRepr = go.GetComponent <EntityRepresentation>(); if (entityRepr == null) { entityRepr = go.AddComponent <EntityRepresentation>(); } entityRepr.assetType = EntityRepresentation.AssetType.Primitive; entityRepr.assetPrimType = primType; entityRepr.name = representationId; if (string.IsNullOrEmpty(entityRepr.name)) { entityRepr.name = primitiveCreated.Value.ToString(); } entityRepr.assetBundleName = null; entityRepr.assetName = null; created = true; entityRepresentation = entityRepr; } } } if (!created) { if (representationAssetType != EntityRepresentation.AssetType.None) { if (string.IsNullOrEmpty(representationAssetName)) { Debug.LogWarning($"Asset information missing for the representation {representationId}"); } else { Debug.LogWarning($"Failed to load representation from asset {representationAssetName}"); // TODO: Add a symbolic representation (cube/text)? } } } if (entityRepresentation) { entityData.activeRepresentation = entityRepresentation; createdRepresentations++; } }
/// <summary> /// Request to load a file asynchronously. /// </summary> /// <param name="objName"></param> /// <param name="filePath"></param> /// <param name="parentTransform"></param> /// <param name="options"></param> public void ImportModelAsync(string objName, string filePath, Transform parentTransform, ModelImportOptions options) { filePath = filePath.Replace('/', Path.DirectorySeparatorChar); RootPathSettings rootPath = GetComponent <RootPathSettings>(); if (!Path.IsPathRooted(filePath) && rootPath != null) { filePath = rootPath + filePath; } if (options != null && options.reuseLoaded) { useCache = true; } //useCache = false; lastModelCacheKey = CreateModelKey(filePath, options); if (useCache && objectCache.ContainsKey(lastModelCacheKey)) { if (objectCache[lastModelCacheKey] == null) { objectCache.Remove(lastModelCacheKey); } else { GameObject cachedObj = Instantiate(objectCache[lastModelCacheKey], parentTransform); cachedObj.name = objName; OnImportingStart(); OnCreatedModel(cachedObj, filePath); OnImportedModel(cachedObj, filePath); OnImportingComplete(); return; } } if (filePath.EndsWith(".obj", true, CultureInfo.InvariantCulture)) { ImportOptions objOptions = new ImportOptions(); if (options != null) { objOptions.buildColliders = options.buildColliders; objOptions.convertToDoubleSided = options.convertToDoubleSided; objOptions.inheritLayer = options.inheritLayer; objOptions.litDiffuse = options.litDiffuse; objOptions.localEulerAngles = options.localEulerAngles; objOptions.localPosition = options.localPosition; objOptions.localScale = options.localScale; objOptions.modelScaling = options.modelScaling; } else { //TODO: define global default options objOptions.buildColliders = true; objOptions.convertToDoubleSided = false; objOptions.inheritLayer = false; objOptions.litDiffuse = false; objOptions.localEulerAngles = Vector3.zero; objOptions.localPosition = Vector3.zero; objOptions.localScale = Vector3.one; objOptions.modelScaling = 0.01f; } objOptions.colliderConvex = true; objOptions.reuseLoaded = false; objOptions.use32bitIndices = true; objOptions.zUp = options.zUp; objOptions.hideWhileLoading = true; objLoader.ImportModelAsync(objName, filePath, parentTransform, objOptions); } else if (filePath.EndsWith(".gltf", true, CultureInfo.InvariantCulture)) { ImportGltfAsync(objName, filePath, parentTransform, options); } }
public async Task LoadGltfAsync(GameObject newObject, string fullPath, ModelImportOptions importOptions) { asyncCoroutineHelper = newObject.GetComponent <AsyncCoroutineHelper>() ?? gameObject.AddComponent <AsyncCoroutineHelper>(); //GLTFSceneImporter sceneImporter = null; ILoader loader = null; try { // Path.Combine treats paths that start with the separator character // as absolute paths, ignoring the first path passed in. This removes // that character to properly handle a filename written with it. fullPath = fullPath.TrimStart(new[] { Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar }); string directoryPath = URIHelper.GetDirectoryName(fullPath); loader = new FileLoader(directoryPath); sceneImporter = new GLTFSceneImporter( Path.GetFileName(fullPath), loader, asyncCoroutineHelper ); sceneImporter.SceneParent = newObject.transform; sceneImporter.Collider = Collider; if (importOptions != null) { if (importOptions.buildColliders) { sceneImporter.Collider = GLTFSceneImporter.ColliderType.MeshConvex; //if (importOptions.colliderConvex) //{ // sceneImporter.Collider = GLTFSceneImporter.ColliderType.MeshConvex; //} //else //{ // sceneImporter.Collider = GLTFSceneImporter.ColliderType.Mesh; //} } else { sceneImporter.Collider = GLTFSceneImporter.ColliderType.None; } } sceneImporter.MaximumLod = MaximumLod; sceneImporter.Timeout = Timeout; sceneImporter.isMultithreaded = Multithreaded; sceneImporter.CustomShaderName = shaderOverride ? shaderOverride.name : null; await sceneImporter.LoadSceneAsync(); // Override the shaders on all materials if a shader is provided if (shaderOverride != null) { Renderer[] renderers = gameObject.GetComponentsInChildren <Renderer>(); foreach (Renderer renderer in renderers) { renderer.sharedMaterial.shader = shaderOverride; } } if (PlayAnimationOnLoad) { Animation[] animations = sceneImporter.LastLoadedScene.GetComponents <Animation>(); foreach (Animation anim in animations) { anim.Play(); } } } finally { if (loader != null) { sceneImporter?.Dispose(); sceneImporter = null; loader = null; } } }
private async void ImportGltfAsync(string objName, string filePath, Transform parentTransform, ModelImportOptions importOptions) { GameObject newObj = new GameObject(objName); if (parentTransform != null) { newObj.transform.SetParent(parentTransform, false); } OnCreatedModel(newObj, filePath); bool error = false; OnImportingStart(); // https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await try { await LoadGltfAsync(newObj, filePath, importOptions); } catch (Exception e) { error = true; Debug.LogWarning($"Failed loading {filePath}: {e}"); } if (error) { OnImportError($"Failed loading {filePath}"); } else { if (newObj.transform.childCount > 0) { GameObject childObj = newObj.transform.GetChild(0).gameObject; newObj.name = childObj.name; if (importOptions != null) { childObj.transform.localPosition = importOptions.localPosition; childObj.transform.localRotation = Quaternion.Euler(importOptions.localEulerAngles);; childObj.transform.localScale = importOptions.localScale; if (importOptions.inheritLayer) { childObj.layer = childObj.transform.parent.gameObject.layer; MeshRenderer[] mrs = childObj.transform.GetComponentsInChildren <MeshRenderer>(true); for (int i = 0; i < mrs.Length; i++) { mrs[i].gameObject.layer = childObj.transform.parent.gameObject.layer; } } Shader unlitTextureShader = Shader.Find("Unlit/Texture"); Shader unlitTransparentShader = Shader.Find("Unlit/Transparent"); if (importOptions.litDiffuse && unlitTextureShader != null && unlitTransparentShader != null) { MeshRenderer[] mrs = childObj.transform.GetComponentsInChildren <MeshRenderer>(true); for (int i = 0; i < mrs.Length; i++) { Material mtl = mrs[i].sharedMaterial; Texture2D tex = mtl.GetTexture("_MainTex") as Texture2D; if (tex != null) { //if (tex.format == TextureFormat.ARGB32) if (mtl.IsKeywordEnabled("_ALPHABLEND_ON")) { mtl.shader = unlitTransparentShader; } else { mtl.shader = unlitTextureShader; } } } } } } OnImportedModel(newObj, filePath); OnImportingComplete(); } }