| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 | /** * Copyright(c) Live2D Inc. All rights reserved. * * Use of this source code is governed by the Live2D Open Software license * that can be found at https://www.live2d.com/eula/live2d-open-software-license-agreement_en.html. */using Live2D.Cubism.Core.Unmanaged;using Live2D.Cubism.Framework;using UnityEngine;namespace Live2D.Cubism.Core{    /// <summary>    /// Single <see cref="CubismModel"/> drawable.    /// </summary>    [CubismDontMoveOnReimport]    public sealed class CubismDrawable : MonoBehaviour    {        #region Factory Methods        /// <summary>        /// Creates drawables for a <see cref="CubismModel"/>.        /// </summary>        /// <param name="unmanagedModel">Handle to unmanaged model.</param>        /// <returns>Drawables root.</returns>        internal static GameObject CreateDrawables(CubismUnmanagedModel unmanagedModel)        {            var root = new GameObject("Drawables");            // Create drawables.            var unmanagedDrawables = unmanagedModel.Drawables;            var buffer = new CubismDrawable[unmanagedDrawables.Count];            for (var i = 0; i < buffer.Length; ++i)            {                var proxy = new GameObject();                buffer[i] = proxy.AddComponent<CubismDrawable>();                buffer[i].transform.SetParent(root.transform);                buffer[i].Reset(unmanagedModel, i);            }            return root;        }        #endregion        /// <summary>        /// Unmanaged drawables from unmanaged model.        /// </summary>        private CubismUnmanagedDrawables UnmanagedDrawables { get; set; }        /// <summary>        /// <see cref="UnmanagedIndex"/> backing field.        /// </summary>        [SerializeField, HideInInspector]        private int _unmanagedIndex = -1;        /// <summary>        /// Position in unmanaged arrays.        /// </summary>        internal int UnmanagedIndex        {            get { return _unmanagedIndex; }            private set { _unmanagedIndex = value; }        }        /// <summary>        /// Copy of Id.        /// </summary>        public string Id        {            get            {                // Pull data.                return UnmanagedDrawables.Ids[UnmanagedIndex];            }        }        /// <summary>        /// Texture UnmanagedIndex.        /// </summary>        public int TextureIndex        {            get            {                // Pull data.                return UnmanagedDrawables.TextureIndices[UnmanagedIndex];            }        }        /// <summary>        /// Copy of the masks.        /// </summary>        public CubismDrawable[] Masks        {            get            {                var drawables = this                    .FindCubismModel(true)                    .Drawables;                // Get addresses.                var counts = UnmanagedDrawables.MaskCounts;                var indices = UnmanagedDrawables.Masks;                // Pull data.                var buffer = new CubismDrawable[counts[UnmanagedIndex]];                for (var i = 0; i < buffer.Length; ++i)                {                    for (var j = 0; j < drawables.Length; ++j)                    {                        if (drawables[j].UnmanagedIndex != indices[UnmanagedIndex][i])                        {                            continue;                        }                        buffer[i] = drawables[j];                        break;                    }                }                return buffer;            }        }        /// <summary>        /// Copy of vertex positions.        /// </summary>        public Vector3[] VertexPositions        {            get            {                // Get addresses.                var counts = UnmanagedDrawables.VertexCounts;                var positions = UnmanagedDrawables.VertexPositions;                // Pull data.                var buffer = new Vector3[counts[UnmanagedIndex]];                for (var i = 0; i < buffer.Length; ++i)                {                    buffer[i] = new Vector3(                        positions[UnmanagedIndex][(i * 2) + 0],                        positions[UnmanagedIndex][(i * 2) + 1]                    );                }                return buffer;            }        }        /// <summary>        /// Copy of vertex texture coordinates.        /// </summary>        public Vector2[] VertexUvs        {            get            {                // Get addresses.                var counts = UnmanagedDrawables.VertexCounts;                var uvs = UnmanagedDrawables.VertexUvs;                // Pull data.                var buffer = new Vector2[counts[UnmanagedIndex]];                for (var i = 0; i < buffer.Length; ++i)                {                    buffer[i] = new Vector2(                        uvs[UnmanagedIndex][(i * 2) + 0],                        uvs[UnmanagedIndex][(i * 2) + 1]                    );                }                return buffer;            }        }        /// <summary>        /// Copy of triangle indices.        /// </summary>        public int[] Indices        {            get            {                // Get addresses.                var counts = UnmanagedDrawables.IndexCounts;                var indices = UnmanagedDrawables.Indices;                // Pull data.                var buffer = new int[counts[UnmanagedIndex]];                for (var i = 0; i < buffer.Length; ++i)                {                    buffer[i] = indices[UnmanagedIndex][i];                }                return buffer;            }        }        /// <summary>        /// True if double-sided.        /// </summary>        public bool IsDoubleSided        {            get            {                // Get address.                var flags = UnmanagedDrawables.ConstantFlags;                // Pull data.                return flags[UnmanagedIndex].HasIsDoubleSidedFlag();            }        }        /// <summary>        /// True if masking is requested.        /// </summary>        public bool IsMasked        {            get            {                // Get address.                var counts = UnmanagedDrawables.MaskCounts;                // Pull data.                return counts[UnmanagedIndex] > 0;            }        }        /// <summary>        /// True if inverted mask.        /// </summary>        public bool IsInverted        {            get            {                // Get address.                var flags = UnmanagedDrawables.ConstantFlags;                // Pull data.                return flags[UnmanagedIndex].HasIsInvertedMaskFlag();            }        }        /// <summary>        /// True if additive blending is requested.        /// </summary>        public bool BlendAdditive        {            get            {                // Get address.                var flags = UnmanagedDrawables.ConstantFlags;                // Pull data.                return flags[UnmanagedIndex].HasBlendAdditiveFlag();            }        }        /// <summary>        /// True if multiply blending is setd.        /// </summary>        public bool MultiplyBlend        {            get            {                // Get address.                var flags = UnmanagedDrawables.ConstantFlags;                // Pull data.                return flags[UnmanagedIndex].HasBlendMultiplicativeFlag();            }        }        /// <summary>        /// Revives instance.        /// </summary>        /// <param name="unmanagedModel">Handle to unmanaged model.</param>        internal void Revive(CubismUnmanagedModel unmanagedModel)        {            UnmanagedDrawables = unmanagedModel.Drawables;        }        /// <summary>        /// Restores instance to initial state.        /// </summary>        /// <param name="unmanagedModel">Handle to unmanaged model.</param>        /// <param name="unmanagedIndex">Position in unmanaged arrays.</param>        private void Reset(CubismUnmanagedModel unmanagedModel, int unmanagedIndex)        {            Revive(unmanagedModel);            UnmanagedIndex = unmanagedIndex;            name = Id;        }    }}
 |