<commit_before>﻿using System;
using System.Linq;
using Alensia.Core.Camera;
using Alensia.Core.Character;
using Alensia.Core.Control;
using Alensia.Core.Interaction.Event;
using Alensia.Core.UI;
using UniRx;
using UnityEngine;
using Zenject;

namespace Alensia.Demo.UMA
{
    public class CameraPanel : CharacterPanel
    {
        [Inject(Id = PlayerController.PlayerAliasName)]
        public CharacterAlias PlayerAlias { get; }

        [Inject]
        public ICameraManager CameraManager { get; }

        public CharacterCamera Camera { get; private set; }

        public Animator Animator { get; private set; }

        public float InitialZoom { get; private set; }

        [Range(0.1f, 1f)] public float Sensitivity = 0.5f;

        public DragButton RotateButton;

        public DragButton MoveButton;

        public Button ResetButton;

        public Slider ZoomSlider;

        public ToggleButton AnimationToggle;

        public Panel FocusControlPanel;

        public override void Initialize(IUIContext context)
        {
            base.Initialize(context);

            Camera = CameraManager.Switch<CharacterCamera>();

            PlayerAlias.OnChange
                .Subscribe(Camera.Track)
                .AddTo(this);

            Action<IPointerDragAware, Vector3> register = (button, direction) =>
            {
                var events = button.OnDrag.Select(v => v.position);

                Observable
                    .Zip(events, events.Skip(1))
                    .TakeUntil(button.OnDragEnd)
                    .RepeatSafe()
                    .Select(i => Normalize(i[1] - i[0], direction))
                    .Subscribe(MoveCamera, Debug.LogError)
                    .AddTo(this);
            };

            register(RotateButton, Vector3.right);
            register(MoveButton, Vector3.up);

            ResetButton.OnPointerSelect
                .Subscribe(_ => ResetCamera(), Debug.LogError)
                .AddTo(this);

            var max = Camera.DistanceSettings.Maximum;
            var min = Camera.DistanceSettings.Minimum;

            var diff = max - min;

            var zoom = Mathf.Approximately(diff, 0) ? 0 : (Camera.Distance - min) / diff;

            InitialZoom = Mathf.Clamp(zoom, min, max);

            ZoomSlider.Value = InitialZoom;
            ZoomSlider
                .OnValueChange
                .Subscribe(ZoomCamera, Debug.LogError)
                .AddTo(this);

            AnimationToggle.enabled = false;
            AnimationToggle.OnValueChange
                .Where(_ => Animator != null)
                .Subscribe(v => Animator.enabled = v, Debug.LogError)
                .AddTo(this);

            var focusButtons = FocusControlPanel.Children.Cast<Button>();

            foreach (var button in focusButtons)
            {
                button.OnPointerSelect
                    .Select(v => v.selectedObject.GetComponent<FocusTarget>())
                    .Subscribe(FocusCamera, Debug.LogError)
                    .AddTo(this);
            }
        }

        protected override void LoadCharacter(IHumanoid character)
        {
            base.LoadCharacter(character);

            Animator = character?.Animator;

            AnimationToggle.enabled = Animator != null;
            AnimationToggle.Value = Animator != null && Animator.enabled;
        }

        private void MoveCamera(Vector2 delta)
        {
            var offset = new Vector3(0, delta.y * 0.02f * Sensitivity, 0);

            Camera.Heading += delta.x * Sensitivity;
            Camera.CameraOffset = Camera.CameraOffset + offset;
        }

        private void ZoomCamera(float zoom)
        {
            var max = Camera.DistanceSettings.Maximum;
            var min = Camera.DistanceSettings.Minimum;

            Camera.Distance = (ZoomSlider.MaxValue - zoom) * (max - min) + min;
        }

        private void FocusCamera(FocusTarget target)
        {
            ResetCamera();

            ZoomSlider.Value = target.Zoom;

            Camera.Focus(target.Target);
        }

        private void ResetCamera()
        {
            Camera.Heading = 0;
            Camera.CameraOffset = Vector3.zero;<commit_msg>Fix initial zoom level in character customization demo<commit_after>﻿using System;
using System.Linq;
using Alensia.Core.Camera;
using Alensia.Core.Character;
using Alensia.Core.Control;
using Alensia.Core.Interaction.Event;
using Alensia.Core.UI;
using UniRx;
using UnityEngine;
using Zenject;

namespace Alensia.Demo.UMA
{
    public class CameraPanel : CharacterPanel
    {
        [Inject(Id = PlayerController.PlayerAliasName)]
        public CharacterAlias PlayerAlias { get; }

        [Inject]
        public ICameraManager CameraManager { get; }

        public CharacterCamera Camera { get; private set; }

        public Animator Animator { get; private set; }

        public float InitialZoom { get; private set; }

        [Range(0.1f, 1f)] public float Sensitivity = 0.5f;

        public DragButton RotateButton;

        public DragButton MoveButton;

        public Button ResetButton;

        public Slider ZoomSlider;

        public ToggleButton AnimationToggle;

        public Panel FocusControlPanel;

        public override void Initialize(IUIContext context)
        {
            base.Initialize(context);

            Camera = CameraManager.Switch<CharacterCamera>();

            Action<IPointerDragAware, Vector3> register = (button, direction) =>
            {
                var events = button.OnDrag.Select(v => v.position);

                Observable
                    .Zip(events, events.Skip(1))
                    .TakeUntil(button.OnDragEnd)
                    .RepeatSafe()
                    .Select(i => Normalize(i[1] - i[0], direction))
                    .Subscribe(MoveCamera, Debug.LogError)
                    .AddTo(this);
            };

            register(RotateButton, Vector3.right);
            register(MoveButton, Vector3.up);

            ResetButton.OnPointerSelect
                .Subscribe(_ => ResetCamera(), Debug.LogError)
                .AddTo(this);

            ZoomSlider
                .OnValueChange
                .Subscribe(ZoomCamera, Debug.LogError)
                .AddTo(this);

            AnimationToggle.enabled = false;
            AnimationToggle.OnValueChange
                .Where(_ => Animator != null)
                .Subscribe(v => Animator.enabled = v, Debug.LogError)
                .AddTo(this);

            var focusButtons = FocusControlPanel.Children.Cast<Button>();

            foreach (var button in focusButtons)
            {
                button.OnPointerSelect
                    .Select(v => v.selectedObject.GetComponent<FocusTarget>())
                    .Subscribe(FocusCamera, Debug.LogError)
                    .AddTo(this);
            }
        }

        protected override void LoadCharacter(IHumanoid character)
        {
            base.LoadCharacter(character);

            Animator = character?.Animator;

            AnimationToggle.enabled = Animator != null;
            AnimationToggle.Value = Animator != null && Animator.enabled;

            Camera.Track(character);

            var target = FocusControlPanel.GetComponentInChildren<FocusTarget>();

            if (target != null)
            {
                FocusCamera(target);
            }
        }

        private void MoveCamera(Vector2 delta)
        {
            var offset = new Vector3(0, delta.y * 0.02f * Sensitivity, 0);

            Camera.Heading += delta.x * Sensitivity;
            Camera.CameraOffset = Camera.CameraOffset + offset;
        }

        private void ZoomCamera(float zoom)
        {
            var max = Camera.DistanceSettings.Maximum;
            var min = Camera.DistanceSettings.Minimum;

            Camera.Distance = (ZoomSlider.MaxValue - zoom) * (max - min) + min;
        }

        private void FocusCamera(FocusTarget target)
        {
            ResetCamera();

            InitialZoom = target.Zoom;
            ZoomSlider.Value = target.Zoom;

            Camera.Focus(target.Target);
        }

        private void ResetCamera()
        {
            Camera.Heading = 0;
            Camera.CameraOffset = Vector3.zero;
{'fraction_non_alphanumeric': 0.08877095645881077, 'fraction_numerical': 0.0050657339283560485, 'mean_word_length': 1.7411570247933885, 'pattern_counts': {'":': 0, '<': 12, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7043316', 'n_tokens_mistral': 2196, 'n_tokens_neox': 2053, 'n_words': 465}