< Summary

Class:CharacterPreviewController
Assembly:AvatarEditorHUD
File(s):/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/CharacterPreviewController.cs
Covered lines:38
Uncovered lines:38
Coverable lines:76
Total lines:200
Line coverage:50% (38 of 76)
Covered branches:0
Total branches:0

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
CharacterPreviewController()0%110100%
Awake()0%110100%
UpdateModel(...)0%330100%
OnDestroy()0%440100%
UpdateModelRoutine()0%660100%
TakeSnapshots(...)0%12300%
TakeSnapshots_Routine()0%30500%
Snapshot(...)0%2100%
SetFocus(...)0%110100%
SetFocus(...)0%4.543044.44%
CameraTransition()0%4.134080%
Rotate(...)0%2100%

File(s)

/tmp/workspace/unity-renderer/unity-renderer/Assets/Scripts/MainScripts/DCL/Controllers/HUD/AvatarEditorHUD/Scripts/CharacterPreviewController.cs

#LineLine coverage
 1using System;
 2using System.Collections;
 3using System.Collections.Generic;
 4using System.Linq;
 5using System.Threading;
 6using AvatarSystem;
 7using Cysharp.Threading.Tasks;
 8using DCL;
 9using GPUSkinning;
 10using UnityEngine;
 11
 12public class CharacterPreviewController : MonoBehaviour
 13{
 14    private const int SNAPSHOT_BODY_WIDTH_RES = 256;
 15    private const int SNAPSHOT_BODY_HEIGHT_RES = 512;
 16
 17    private const int SNAPSHOT_FACE_256_WIDTH_RES = 256;
 18    private const int SNAPSHOT_FACE_256_HEIGHT_RES = 256;
 19
 20    private const int SUPERSAMPLING = 1;
 21    private const float CAMERA_TRANSITION_TIME = 0.5f;
 22
 23    public delegate void OnSnapshotsReady(Texture2D face256, Texture2D body);
 24
 25    public enum CameraFocus
 26    {
 27        DefaultEditing,
 28        FaceEditing,
 29        FaceSnapshot,
 30        BodySnapshot
 31    }
 32
 33    private System.Collections.Generic.Dictionary<CameraFocus, Transform> cameraFocusLookUp;
 34
 35    public new Camera camera;
 36
 37    public Transform defaultEditingTemplate;
 38    public Transform faceEditingTemplate;
 39
 40    public Transform faceSnapshotTemplate;
 41    public Transform bodySnapshotTemplate;
 42
 43    [SerializeField] private GameObject avatarContainer;
 44    private IAvatar avatar;
 4745    private readonly AvatarModel currentAvatarModel = new AvatarModel { wearables = new List<string>() };
 4746    private CancellationTokenSource loadingCts = new CancellationTokenSource();
 47
 48    private void Awake()
 49    {
 4650        cameraFocusLookUp = new Dictionary<CameraFocus, Transform>()
 51        {
 52            { CameraFocus.DefaultEditing, defaultEditingTemplate },
 53            { CameraFocus.FaceEditing, faceEditingTemplate },
 54            { CameraFocus.FaceSnapshot, faceSnapshotTemplate },
 55            { CameraFocus.BodySnapshot, bodySnapshotTemplate },
 56        };
 4657        IAnimator animator = avatarContainer.gameObject.GetComponentInChildren<IAnimator>();
 4658        avatar = new AvatarSystem.Avatar(
 59            new AvatarCurator(new WearableItemResolver()),
 60            new Loader(new WearableLoaderFactory(), avatarContainer, new AvatarMeshCombinerHelper()),
 61            animator,
 62            new Visibility(),
 63            new NoLODs(),
 64            new SimpleGPUSkinning(),
 65            new GPUSkinningThrottler(),
 66            new EmoteAnimationEquipper(animator, DataStore.i.emotes)
 67        );
 4668    }
 69
 70    public void UpdateModel(AvatarModel newModel, Action onDone)
 71    {
 12172        loadingCts?.Cancel();
 12173        loadingCts?.Dispose();
 12174        loadingCts = new CancellationTokenSource();
 12175        UpdateModelRoutine(newModel, onDone, loadingCts.Token);
 12176    }
 77
 78    private void OnDestroy()
 79    {
 4680        loadingCts?.Cancel();
 4681        loadingCts?.Dispose();
 4682        loadingCts = null;
 4683        avatar?.Dispose();
 4684    }
 85
 86    private async UniTaskVoid UpdateModelRoutine(AvatarModel newModel, Action onDone, CancellationToken ct)
 87    {
 12188        if (newModel.HaveSameWearablesAndColors(currentAvatarModel))
 89        {
 4590            onDone?.Invoke();
 4591            return;
 92        }
 93
 7694        currentAvatarModel.CopyFrom(newModel);
 7695        List<string> wearables = new List<string>(newModel.wearables);
 7696        wearables.Add(newModel.bodyShape);
 22897        await avatar.Load(wearables, new AvatarSettings
 98        {
 99            bodyshapeId = newModel.bodyShape,
 100            eyesColor = newModel.eyeColor,
 101            hairColor = newModel.hairColor,
 102            skinColor = newModel.skinColor
 103
 104        }, ct);
 105
 76106        onDone?.Invoke();
 121107    }
 108
 109    public void TakeSnapshots(OnSnapshotsReady onSuccess, Action onFailed)
 110    {
 0111        if (avatar.status != IAvatar.Status.Loaded)
 112        {
 0113            onFailed?.Invoke();
 0114            return;
 115        }
 116
 0117        StartCoroutine(TakeSnapshots_Routine(onSuccess));
 0118    }
 119
 120    private IEnumerator TakeSnapshots_Routine(OnSnapshotsReady callback)
 121    {
 0122        DCL.Environment.i.platform.cullingController.Stop();
 123
 0124        var current = camera.targetTexture;
 0125        camera.targetTexture = null;
 0126        var avatarAnimator = avatarContainer.gameObject.GetComponentInChildren<AvatarAnimatorLegacy>();
 127
 0128        SetFocus(CameraFocus.FaceSnapshot, false);
 0129        avatarAnimator.Reset();
 0130        yield return null;
 0131        Texture2D face256 = Snapshot(SNAPSHOT_FACE_256_WIDTH_RES, SNAPSHOT_FACE_256_HEIGHT_RES);
 132
 0133        SetFocus(CameraFocus.BodySnapshot, false);
 0134        avatarAnimator.Reset();
 0135        yield return null;
 0136        Texture2D body = Snapshot(SNAPSHOT_BODY_WIDTH_RES, SNAPSHOT_BODY_HEIGHT_RES);
 137
 0138        SetFocus(CameraFocus.DefaultEditing, false);
 139
 0140        camera.targetTexture = current;
 141
 0142        DCL.Environment.i.platform.cullingController.Start();
 0143        callback?.Invoke(face256, body);
 0144    }
 145
 146    private Texture2D Snapshot(int width, int height)
 147    {
 0148        RenderTexture rt = new RenderTexture(width * SUPERSAMPLING, height * SUPERSAMPLING, 32);
 0149        camera.targetTexture = rt;
 0150        Texture2D screenShot = new Texture2D(rt.width, rt.height, TextureFormat.RGBA32, false);
 0151        camera.Render();
 0152        RenderTexture.active = rt;
 0153        screenShot.ReadPixels(new Rect(0, 0, rt.width, rt.height), 0, 0);
 0154        screenShot.Apply();
 155
 0156        return screenShot;
 157    }
 158
 159    private Coroutine cameraTransitionCoroutine;
 160
 90161    public void SetFocus(CameraFocus focus, bool useTransition = true) { SetFocus(cameraFocusLookUp[focus], useTransitio
 162
 163    private void SetFocus(Transform transform, bool useTransition = true)
 164    {
 45165        if (cameraTransitionCoroutine != null)
 166        {
 0167            StopCoroutine(cameraTransitionCoroutine);
 168        }
 169
 45170        if (useTransition)
 171        {
 45172            cameraTransitionCoroutine = StartCoroutine(CameraTransition(camera.transform.position, transform.position, c
 45173        }
 174        else
 175        {
 0176            var cameraTransform = camera.transform;
 0177            cameraTransform.position = transform.position;
 0178            cameraTransform.rotation = transform.rotation;
 179        }
 0180    }
 181
 182    private IEnumerator CameraTransition(Vector3 initPos, Vector3 endPos, Quaternion initRotation, Quaternion endRotatio
 183    {
 45184        var cameraTransform = camera.transform;
 45185        float currentTime = 0;
 186
 45187        float inverseTime = 1 / time;
 45188        while (currentTime < time)
 189        {
 45190            currentTime = Mathf.Clamp(currentTime + Time.deltaTime, 0, time);
 45191            cameraTransform.position = Vector3.Lerp(initPos, endPos, currentTime * inverseTime);
 45192            cameraTransform.rotation = Quaternion.Lerp(initRotation, endRotation, currentTime * inverseTime);
 45193            yield return null;
 194        }
 195
 0196        cameraTransitionCoroutine = null;
 0197    }
 198
 0199    public void Rotate(float rotationVelocity) { avatarContainer.transform.Rotate(Time.deltaTime * rotationVelocity * Ve
 200}