예제 #1
0
        /// <summary>
        /// Generates avatar with the selected set of resources and displayed it in AvatarViewer scene
        /// </summary>
        protected override IEnumerator GenerateAndDisplayHead(byte[] photoBytes, PipelineType pipeline)
        {
            //Get selected resources
            AvatarResources avatarResources = GetSelectedResources();

            // generate avatar from the photo and get its code in the Result of request
            var initializeRequest = avatarProvider.InitializeAvatarAsync(photoBytes, "name", "description", pipeline, avatarResources);

            yield return(Await(initializeRequest));

            string avatarCode = initializeRequest.Result;

            StartCoroutine(SampleUtils.DisplayPhotoPreview(avatarCode, photoPreview));

            var calculateRequest = avatarProvider.StartAndAwaitAvatarCalculationAsync(avatarCode);

            yield return(Await(calculateRequest));

            AvatarViewer.SetSceneParams(new AvatarViewer.SceneParams()
            {
                avatarCode     = avatarCode,
                showSettings   = false,
                sceneToReturn  = SceneManager.GetActiveScene().name,
                avatarProvider = avatarProvider,
                useAnimations  = false
            });
            SceneManager.LoadScene(Scenes.GetSceneName(SceneType.AVATAR_VIEWER));
        }
예제 #2
0
        /// <summary>
        /// Loads the preview image from the disk asynchronously, resizes it to a smaller size and displays in UI.
        /// </summary>
        private IEnumerator UpdateImageAsync()
        {
            var loadPhoto = CoreTools.LoadAvatarFileAsync(avatarCode, AvatarFile.PHOTO);

            yield return(loadPhoto);

            if (loadPhoto.IsError)
            {
                Debug.Log("Could not load photo (probably original photo was not saved for this avatar)");
                yield break;
            }

            // parse jpg bytes into texture
            Texture2D jpgTexture = new Texture2D(1, 1);

            jpgTexture.LoadImage(loadPhoto.Result);

            // rescale to reduce load time and memory usage
            Texture2D previewTexture = SampleUtils.RescaleTexture(jpgTexture, 300);

            // do not keep original hires texture in the memory (hopefully GC will collect it)
            Destroy(jpgTexture);
            jpgTexture = null;

            // make sure alpha channel is 1
            var color = image.color;

            color.a     = 1;
            image.color = color;

            // create UI sprite from texture
            image.preserveAspect = true;
            image.overrideSprite = Sprite.Create(previewTexture, new Rect(0, 0, previewTexture.width, previewTexture.height), Vector2.zero);
        }
        /// <summary>
        /// To make Getting Started sample as simple as possible all code required for creating and
        /// displaying an avatar is placed here in a single function. This function is also a good example of how to
        /// chain asynchronous requests, just like in traditional sequential code.
        /// </summary>
        protected virtual IEnumerator GenerateAndDisplayHead(byte[] photoBytes, PipelineType pipeline)
        {
            // Choose default set of resources to generate
            var resourcesRequest = avatarProvider.ResourceManager.GetResourcesAsync(AvatarResourcesSubset.DEFAULT, pipelineType);

            yield return(Await(resourcesRequest));

            // generate avatar from the photo and get its code in the Result of request
            var initializeRequest = avatarProvider.InitializeAvatarAsync(photoBytes, "name", "description", pipeline, resourcesRequest.Result);

            yield return(Await(initializeRequest));

            string avatarCode = initializeRequest.Result;

            StartCoroutine(SampleUtils.DisplayPhotoPreview(avatarCode, photoPreview));

            var calculateRequest = avatarProvider.StartAndAwaitAvatarCalculationAsync(avatarCode);

            yield return(Await(calculateRequest));

            // with known avatar code we can get TexturedMesh for head in order to show it further
            var avatarHeadRequest = avatarProvider.GetHeadMeshAsync(avatarCode, false);

            yield return(Await(avatarHeadRequest));

            TexturedMesh headTexturedMesh = avatarHeadRequest.Result;

            TexturedMesh haircutTexturedMesh = null;
            // get identities of all haircuts available for the generated avatar
            var haircutsIdRequest = avatarProvider.GetHaircutsIdAsync(avatarCode);

            yield return(Await(haircutsIdRequest));

            // randomly select a haircut
            var haircuts = haircutsIdRequest.Result;

            if (haircuts != null && haircuts.Length > 0)
            {
                var haircutIdx = UnityEngine.Random.Range(0, haircuts.Length);
                var haircut    = haircuts[haircutIdx];

                // load TexturedMesh for the chosen haircut
                var haircutRequest = avatarProvider.GetHaircutMeshAsync(avatarCode, haircut);
                yield return(Await(haircutRequest));

                haircutTexturedMesh = haircutRequest.Result;
            }

            DisplayHead(headTexturedMesh, haircutTexturedMesh);
        }
        protected virtual void Start()
        {
            var ui = buttons.Select(b => b.gameObject).ToArray();

            if (!SampleUtils.CheckIfSupported(progressText, ui, sdkType))
            {
                return;
            }

            // first of all, initialize the SDK
            if (!AvatarSdkMgr.IsInitialized)
            {
                AvatarSdkMgr.Init(sdkType: sdkType);
            }

            StartCoroutine(Initialize());

            // Anti-aliasing is required for hair shader, otherwise nice transparent texture won't work.
            // Another option is to use cutout shader, but the look with this shader isn't that great.
#if UNITY_STANDALONE_WIN || UNITY_EDITOR || UNITY_EDITOR
            QualitySettings.antiAliasing = 8;
#else
            QualitySettings.antiAliasing = 4;
#endif
            foreach (var b in buttons)
            {
#if UNITY_EDITOR || UNITY_WEBGL || UNITY_ANDROID || UNITY_IOS
                if (b.name.Contains("UserPhoto"))
                {
                    b.gameObject.SetActive(true);
                    fileBrowser = b.GetComponentInChildren <FileBrowser>();
                    if (fileBrowser != null)
                    {
                        fileBrowser.fileHandler = GenerateAvatarFunc;
                    }
                }
#endif
#if UNITY_ANDROID || UNITY_IOS
                if (b.name.Contains("CameraPhoto"))
                {
                    b.gameObject.SetActive(true);
                }
#endif
            }
        }
예제 #5
0
        protected override IEnumerator GenerateAndDisplayHead(byte[] photoBytes, PipelineType pipeline)
        {
            // We don't need blendshapes nor haircuts. So create an empty avatar resources set
            var initializeRequest = avatarProvider.InitializeAvatarAsync(photoBytes, "name", "description", pipeline, AvatarResources.Empty);

            yield return(Await(initializeRequest));

            currentAvatarCode = initializeRequest.Result;

            StartCoroutine(SampleUtils.DisplayPhotoPreview(currentAvatarCode, photoPreview));

            var calculateRequest = avatarProvider.StartAndAwaitAvatarCalculationAsync(currentAvatarCode);

            yield return(Await(calculateRequest));

            var avatarHeadRequest = avatarProvider.GetHeadMeshAsync(currentAvatarCode, false, currentDetailsLevel);

            yield return(Await(avatarHeadRequest));

            DisplayHead(avatarHeadRequest.Result, null);
            detailsLevelText.text = string.Format("Triangles count:\n{0}", avatarHeadRequest.Result.mesh.triangles.Length / 3);
        }
예제 #6
0
        /// <summary>
        /// Show avatar in the scene. Also load haircut information to allow further haircut change.
        /// </summary>
        private IEnumerator ShowAvatar(string avatarCode)
        {
            ChangeControlsInteractability(false);
            yield return(new WaitForSeconds(0.05f));

            StartCoroutine(SampleUtils.DisplayPhotoPreview(avatarCode, photoPreview));

            progressText.text = string.Empty;
            currentHaircut    = 0;

            var currentAvatar = GameObject.Find(AVATAR_OBJECT_NAME);

            if (currentAvatar != null)
            {
                Destroy(currentAvatar);
            }

            var avatarObject = new GameObject(AVATAR_OBJECT_NAME);

            var headMeshRequest = avatarProvider.GetHeadMeshAsync(avatarCode, true);

            yield return(Await(headMeshRequest));

            if (headMeshRequest.IsError)
            {
                Debug.LogError("Could not load avatar from disk!");
            }
            else
            {
                TexturedMesh texturedMesh = headMeshRequest.Result;

                // game object can be deleted if we opened another avatar
                if (avatarObject != null && avatarObject.activeSelf)
                {
                    avatarObject.AddComponent <RotateByMouse>();

                    headObject = new GameObject(HEAD_OBJECT_NAME);
                    var meshRenderer = headObject.AddComponent <SkinnedMeshRenderer>();
                    meshRenderer.sharedMesh           = texturedMesh.mesh;
                    meshRenderer.material             = IsUnlitMode ? unlitMaterial : litMaterial;
                    meshRenderer.material.mainTexture = texturedMesh.texture;
                    headObject.transform.SetParent(avatarObject.transform);
                    SetAvatarScale(avatarCode, avatarObject.transform);

                    if (useAnimations)
                    {
                        if (isWebGLDemo)
                        {
                            // don't show all animations in webgl demo
                            GetComponent <AnimationManager>().CreateAnimator(headObject, animations.GetRange(0, 5));
                        }
                        else
                        {
                            GetComponent <AnimationManager>().CreateAnimator(headObject, animations);
                        }
                    }
                    else
                    {
                        //add an empty blendshape with index -1
                        availableBlendshapes.Add(-1, "None");

                        var mesh = headObject.GetComponentInChildren <SkinnedMeshRenderer>().sharedMesh;
                        for (int i = 0; i < mesh.blendShapeCount; i++)
                        {
                            availableBlendshapes.Add(i, mesh.GetBlendShapeName(i));
                        }
                        ChangeCurrentBlendshape(-1);
                        blendshapesSelectingView.InitItems(availableBlendshapes.Values.ToList());

                        if (availableBlendshapes.Count == 1)
                        {
                            blendshapesPanel.SetActive(false);
                        }
                    }
                }
            }

            var haircutsIdsRequest = GetHaircutsIdsAsync(avatarCode);

            yield return(haircutsIdsRequest);

            string[] haircuts = haircutsIdsRequest.Result;
            if (haircuts != null && haircuts.Length > 0)
            {
                //Add fake "bald" haircut
                var haircutsList = haircuts.ToList();
                haircutsList.Insert(0, BALD_HAIRCUT_NAME);
                avatarHaircuts = haircutsList.ToArray();
                OnDisplayedHaircutChanged(avatarHaircuts[currentHaircut]);
                haircutsSelectingView.InitItems(avatarCode, avatarHaircuts.ToList(), avatarProvider);
                haircutsPanel.SetActive(true);
            }
            else
            {
                haircutsPanel.SetActive(false);
                OnDisplayedHaircutChanged(BALD_HAIRCUT_NAME);
            }

            ChangeControlsInteractability(true);
            avatarControls.SetActive(true);
        }