/// <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();

            Debug.Log(CoreTools.GetAvatarCalculationParamsJson(avatarResources));
            yield return(Await(null));

            // 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));
             */
        }
        protected IEnumerator UpdateResources()
        {
            SetControlsInteractable(false);

            // Get all available resources
            var allResourcesRequest = avatarProvider.ResourceManager.GetResourcesAsync(AvatarResourcesSubset.ALL, pipelineType);
            // Get default resources
            var defaultResourcesRequest = avatarProvider.ResourceManager.GetResourcesAsync(AvatarResourcesSubset.DEFAULT, pipelineType);

            yield return(Await(allResourcesRequest, defaultResourcesRequest));

            if (allResourcesRequest.IsError || defaultResourcesRequest.IsError)
            {
                Debug.LogError("Unable to get resources list");
                haircutsSelectingView.InitItems(new List <string>());
                blendshapesSelectingView.InitItems(new List <string>());
            }
            else
            {
                AvatarResources allResources     = allResourcesRequest.Result;
                AvatarResources defaultResources = defaultResourcesRequest.Result;

                haircutsSelectingView.InitItems(allResources.haircuts);
                haircutsSelectingView.Show(defaultResources.haircuts, null);

                blendshapesSelectingView.InitItems(allResources.blendshapes);
                blendshapesSelectingView.Show(defaultResources.blendshapes, null);
            }

            SetControlsInteractable(true);
        }
        /// <summary>
        /// Initializes avatar and uploads photo to the server.
        /// </summary>
        /// <param name="photoBytes">Photo bytes (jpg or png encoded).</param>
        /// <param name="name">Name of the avatar</param>
        /// <param name="description">Description of the avatar</param>
        /// <param name="pipeline">Calculation pipeline to use</param>
        /// <returns>Avatar unique code</returns>
        public AsyncRequest <string> InitializeAvatarAsync(byte[] photoBytes, string name, string description, PipelineType pipeline = PipelineType.FACE,
                                                           AvatarResources avatarResources = null)
        {
            var request = new AsyncRequest <string>(AvatarSdkMgr.Str(Strings.GeneratingAvatar));

            AvatarSdkMgr.SpawnCoroutine(InitializeAvatarFunc(photoBytes, name, description, pipeline, avatarResources, request));
            return(request);
        }
        /// <summary>
        /// Forms selected resources lists
        /// </summary>
        protected AvatarResources GetSelectedResources()
        {
            AvatarResources resources = AvatarResources.Empty;

            resources.haircuts    = haircutsSelectingView.CurrentSelection;
            resources.blendshapes = blendshapesSelectingView.CurrentSelection;
            return(resources);
        }
        /// <summary>
        /// InitializeAvatarAsync implementation
        /// </summary>
        private IEnumerator InitializeAvatarFunc(byte[] photoBytes, string name, string description, PipelineType pipeline,
                                                 AvatarResources resources, AsyncRequest <string> request)
        {
            // uploading photo and registering new avatar on the server
            var createAvatar = connection.CreateAvatarWithPhotoAsync(name, description, photoBytes, false, pipeline, resources);

            // Wait until async request is completed (without blocking the main thread).
            // Instead of using AwaitSubrequest we could just use `yield return createAvatar;`
            // AwaitSubrequest is a helper function that allows to track progress on composite
            // requests automatically. It also provides info for the caller about current subrequest
            // (and it's progress) and propagetes error from subrequest to the parent request.
            // finalProgress is a value between 0 and 1, a desired progress of parent request when given
            // subrequest is completed.
            yield return(request.AwaitSubrequest(createAvatar, finalProgress: 0.99f));

            // must check whether request was successful before proceeding
            if (request.IsError)
            {
                yield break;
            }

            string avatarCode = createAvatar.Result.code;

            // save photo for later use
            var savePhoto = CoreTools.SaveAvatarFileAsync(photoBytes, avatarCode, AvatarFile.PHOTO);
            // save pipeline type
            var savePipeline = CoreTools.SaveAvatarFileAsync(Encoding.ASCII.GetBytes(pipeline.GetPipelineTypeName()), avatarCode, AvatarFile.PIPELINE_INFO);

            yield return(request.AwaitSubrequests(1.0f, savePhoto, savePipeline));

            // again, must check for the error, there's no point in proceeding otherwise
            if (request.IsError)
            {
                yield break;
            }

            request.Result = avatarCode;
            request.IsDone = true;
        }
        private IEnumerator GetResourcesFunc(AvatarResourcesSubset resourcesSubset, PipelineType pipelineType, AsyncRequest <AvatarResources> request)
        {
            if (avatarResourcesCache[pipelineType].ContainsKey(resourcesSubset))
            {
                request.Result = avatarResourcesCache[pipelineType][resourcesSubset];
                request.IsDone = true;
            }
            else
            {
                var resourcesWebRequest = connection.GetResourcesAsync(pipelineType, resourcesSubset);
                yield return(resourcesWebRequest);

                if (resourcesWebRequest.IsError)
                {
                    Debug.LogError(resourcesWebRequest.ErrorMessage);
                    request.SetError(resourcesWebRequest.ErrorMessage);
                    yield break;
                }
                AvatarResources avatarResources = GetResourcesFromJson(resourcesWebRequest.Result);
                avatarResourcesCache[pipelineType].Add(resourcesSubset, avatarResources);
                request.IsDone = true;
                request.Result = avatarResources;
            }
        }
Beispiel #7
0
        private IEnumerator GenerateAvatarFunc(byte[] selectedImageBytes, PipelineType pipelineType, AsyncRequest <AvatarData> request)
        {
            UpdateAvatarState(WebglAvatarState.UPLOADING, pipelineType);

            var defaultResourcesRequest = avatarProvider.ResourceManager.GetResourcesAsync(AvatarResourcesSubset.DEFAULT, pipelineType);

            yield return(Await(defaultResourcesRequest, pipelineType));

            // Generate all haircuts and default blendshapes to play animations
            var allResourcesRequest = avatarProvider.ResourceManager.GetResourcesAsync(AvatarResourcesSubset.ALL, pipelineType);

            yield return(Await(allResourcesRequest, pipelineType));

            if (defaultResourcesRequest.IsError || allResourcesRequest.IsError)
            {
                string msg = "Unable to get resources list";
                Debug.LogError(msg);
                UpdateAvatarState(WebglAvatarState.FAILED, pipelineType);
                request.SetError(msg);
                yield break;
            }
            AvatarResources resources = allResourcesRequest.Result;

            resources.blendshapes = defaultResourcesRequest.Result.blendshapes;

            var createAvatar = connection.CreateAvatarWithPhotoAsync("test_avatar", "test_description", selectedImageBytes, false, pipelineType, resources);

            yield return(Await(createAvatar, pipelineType));

            if (createAvatar.IsError)
            {
                Debug.LogError(createAvatar.ErrorMessage);
                UpdateAvatarState(WebglAvatarState.FAILED, pipelineType);
                request.SetError(createAvatar.ErrorMessage);
                yield break;
            }

            var avatar    = createAvatar.Result;
            var savePhoto = CoreTools.SaveAvatarFileAsync(selectedImageBytes, avatar.code, AvatarFile.PHOTO);

            yield return(savePhoto);

            var savePipeline = CoreTools.SaveAvatarFileAsync(Encoding.ASCII.GetBytes(pipelineType.GetPipelineTypeName()), avatar.code, AvatarFile.PIPELINE_INFO);

            yield return(savePipeline);

            if (savePhoto.IsError)
            {
                Debug.LogError(savePhoto.ErrorMessage);
                UpdateAvatarState(WebglAvatarState.FAILED, pipelineType);
                request.SetError(savePhoto.ErrorMessage);
                yield break;
            }

            UpdateAvatarState(WebglAvatarState.CALCULATING_IN_CLOUD, pipelineType);

            var awaitCalculations = connection.AwaitAvatarCalculationsAsync(avatar);

            yield return(Await(awaitCalculations, pipelineType));

            if (awaitCalculations.IsError)
            {
                Debug.LogError(awaitCalculations.ErrorMessage);
                UpdateAvatarState(WebglAvatarState.FAILED, pipelineType);
                request.SetError(awaitCalculations.ErrorMessage);
                yield break;
            }

            AvatarData avatarData = awaitCalculations.Result;

            UpdateAvatarState(WebglAvatarState.DOWNLOADING, pipelineType);
            var downloadRequest = DownloadAvatarAsync(avatarData, pipelineType);

            yield return(downloadRequest);

            if (downloadRequest.IsError)
            {
                Debug.LogError(downloadRequest.ErrorMessage);
                UpdateAvatarState(WebglAvatarState.FAILED, pipelineType);
                request.SetError(downloadRequest.ErrorMessage);
                yield break;
            }

            UpdateAvatarState(WebglAvatarState.FINISHED, pipelineType);
            request.Result = avatarData;
            request.IsDone = true;
        }
 void Start()
 {
     boxCollider2D   = GetComponent <BoxCollider2D>();
     avatarResources = avatar.GetComponent <AvatarResources>();
 }
Beispiel #9
0
        /// <summary>
        /// Upload photo and create avatar instance on the server. Calculations will start right away after the photo is uploaded.
        /// </summary>
        public virtual AsyncWebRequest <AvatarData> CreateAvatarWithPhotoAsync(
            string name, string description, byte[] photoBytes, bool forcePowerOfTwoTexture = false,
            PipelineType pipeline = PipelineType.FACE, AvatarResources resources = null
            )
        {
            var request = new AsyncWebRequest <AvatarData> (AvatarSdkMgr.Str(Strings.UploadingPhoto), TrackProgress.UPLOAD);

#if UNITY_2017_1_OR_NEWER
            Func <UnityWebRequest> webRequestFactory = () =>
            {
                List <IMultipartFormSection> formData = new List <IMultipartFormSection>();
                formData.Add(new MultipartFormDataSection("name", name));
                if (!string.IsNullOrEmpty(description))
                {
                    formData.Add(new MultipartFormDataSection("description", description));
                }
                formData.Add(new MultipartFormFileSection("photo", photoBytes, "photo.jpg", "application/octet-stream"));
                formData.Add(new MultipartFormDataSection("preserve_original_texture", (!forcePowerOfTwoTexture).ToString()));
                formData.Add(new MultipartFormDataSection("pipeline", pipeline.GetPipelineTypeName()));

                if (resources != null)
                {
                    formData.Add(new MultipartFormDataSection("pipeline_subtype", pipeline_subtype));
                    formData.Add(new MultipartFormDataSection("resources", CoreTools.GetAvatarCalculationParamsJson(resources)));
                }

                var webRequest = UnityWebRequest.Post(GetUrl("avatars"), formData);
                webRequest.chunkedTransfer = false;
                SetAuthHeaders(webRequest);
                return(webRequest);
            };

            Debug.LogFormat("Uploading photo...");
            AvatarSdkMgr.SpawnCoroutine(AwaitJsonWebRequest(webRequestFactory, request));
            return(request);
#else
            // Unity 5.5.0 (and probably earlier versions) have a weird bug in default multipart form data
            // implementation, which causes incorrect boundaries between data fields. To work around this bug the
            // multipart request body is constructed manually, see below.
            byte[] requestBodyData = null;
            using (var requestBody = new MultipartBody()) {
                requestBody.WriteTextField("name", name);
                requestBody.WriteTextField("description", description);
                requestBody.WriteFileField("photo", "photo.jpg", photoBytes);
                requestBody.WriteTextField("preserve_original_texture", (!forcePowerOfTwoTexture).ToString());
                requestBody.WriteTextField("pipeline", pipeline.GetPipelineTypeName());

                if (resources != null)
                {
                    requestBody.WriteTextField("pipeline_subtype", pipeline_subtype);
                    requestBody.WriteTextField("resources", CoreTools.GetAvatarCalculationParamsJson(resources));
                }

                requestBody.WriteFooter();
                requestBodyData = requestBody.GetRequestBodyData();

                Func <UnityWebRequest> webRequestFactory = () => {
                    var webRequest = UnityWebRequest.Post(GetUrl("avatars"), " ");
                    webRequest.uploadHandler = new UploadHandlerRaw(requestBodyData);
                    webRequest.SetRequestHeader(
                        "Content-Type", string.Format("multipart/form-data; boundary=\"{0}\"", requestBody.Boundary)
                        );
                    webRequest.chunkedTransfer = false;
                    SetAuthHeaders(webRequest);
                    return(webRequest);
                };

                Debug.LogFormat("Uploading photo...");
                AvatarSdkMgr.SpawnCoroutine(AwaitJsonWebRequest(webRequestFactory, request));
                return(request);
            }
#endif
        }
 void Start()
 {
     avatarResources  = GetComponent <AvatarResources>();
     avatarController = GetComponent <Avatar2DCharacterCTRL>();
     isAvatarGrounded = avatarController.playerIsGrounded;
 }