示例#1
0
 static void ReverseZ(BufferAccessor ba)
 {
     if (ba.ComponentType != AccessorValueType.FLOAT)
     {
         throw new Exception();
     }
     if (ba.AccessorType == AccessorVectorType.VEC3)
     {
         var span = ba.GetSpan <Vector3>();
         for (int i = 0; i < span.Length; ++i)
         {
             span[i] = span[i].ReverseZ();
         }
     }
     else if (ba.AccessorType == AccessorVectorType.MAT4)
     {
         var span = ba.GetSpan <Matrix4x4>();
         for (int i = 0; i < span.Length; ++i)
         {
             span[i] = span[i].ReverseZ();
         }
     }
     else
     {
         throw new NotImplementedException();
     }
 }
示例#2
0
        /// <summary>
        /// BoneSkinningもしくはMorphTargetの適用
        /// <summary>
        public void Skinning(VertexBuffer vertexBuffer = null)
        {
            m_indexOfRoot = (ushort)Joints.IndexOf(Root);
            var addRoot = Root != null && m_indexOfRoot == ushort.MaxValue;

            if (addRoot)
            {
                m_indexOfRoot = (ushort)Joints.Count;
                Joints.Add(Root);
            }

            if (m_matrices == null)
            {
                m_matrices = new Matrix4x4[Joints.Count];
            }

            if (InverseMatrices == null)
            {
                CalcInverseMatrices();
            }
            else
            {
                if (addRoot)
                {
                    var inverseArray = InverseMatrices.GetSpan <Matrix4x4>().ToArray();
                    InverseMatrices.Assign(inverseArray.Concat(new[] { Root.InverseMatrix }).ToArray().AsSpan());
                }
            }

            var inverse = InverseMatrices.GetSpan <Matrix4x4>();

            // if (Root != null)
            // {
            //     var rootInverse = Root.InverseMatrix;
            //     var root = Root.Matrix;
            //     for (int i = 0; i < m_matrices.Length; ++i)
            //     {
            //         m_matrices[i] = inverse[i] * Joints[i].Matrix * rootInverse;
            //     }
            // }
            // else
            {
                for (int i = 0; i < m_matrices.Length; ++i)
                {
                    var inv = i < inverse.Length ? inverse[i] : Joints[i].InverseMatrix;
                    m_matrices[i] = inv * Joints[i].Matrix;
                }
            }

            if (vertexBuffer != null)
            {
                Apply(vertexBuffer);
            }
        }
示例#3
0
        public Vector3 GetVector3(TimeSpan elapsed)
        {
            var(begin, end, ratio) = GetRange((float)elapsed.TotalSeconds);
            var values = Out.GetSpan <Vector3>();

            if (begin == end)
            {
                return(values[begin]);
            }
            else
            {
                // TODO: curve interpolation
                return(Vector3.Lerp(values[begin], values[end], ratio));
            }
        }
示例#4
0
文件: Skin.cs 项目: unitycoder/UniVRM
        /// <summary>
        /// nullになったjointを除去して、boneweightを前に詰める
        /// </summary>
        public void FixBoneWeight(BufferAccessor jointsAccessor, BufferAccessor weightsAccessor)
        {
            var map      = Joints.Select((x, i) => ValueTuple.Create(i, x)).Where(x => x.Item2 != null).ToArray();
            var indexMap = Enumerable.Repeat(-1, Joints.Count).ToArray();

            {
                for (int i = 0; i < map.Length; ++i)
                {
                    indexMap[map[i].Item1] = i;
                }
            }
            Joints.RemoveAll(x => x == null);

            var joints  = jointsAccessor.GetSpan <SkinJoints>();
            var weights = weightsAccessor.GetSpan <Vector4>();

            for (int i = 0; i < joints.Length; ++i)
            {
                var j = joints[i];
                var w = weights[i];

                Update(ref w.X, ref j.Joint0, indexMap);
                Update(ref w.Y, ref j.Joint1, indexMap);
                Update(ref w.Z, ref j.Joint2, indexMap);
                Update(ref w.W, ref j.Joint3, indexMap);

                joints[i]  = j;
                weights[i] = w;
            }

            CalcInverseMatrices();
        }
示例#5
0
        public void FixBoneWeight(BufferAccessor jointsAccessor, BufferAccessor weightsAccessor)
        {
            var map      = Joints.Select((x, i) => ValueTuple.Create(i, x)).Where(x => x.Item2 != null).ToArray();
            var indexMap = Enumerable.Repeat(-1, Joints.Count).ToArray();

            {
                for (int i = 0; i < map.Length; ++i)
                {
                    indexMap[map[i].Item1] = i;
                }
            }
            Joints.RemoveAll(x => x == null);

            var joints  = jointsAccessor.GetSpan <SkinJoints>();
            var weights = weightsAccessor.GetSpan <Vector4>();

            for (int i = 0; i < joints.Length; ++i)
            {
                ref var j = ref joints[i];
                ref var w = ref weights[i];
示例#6
0
        bool GetSubmeshOverlapped <T>() where T : struct
        {
            var indices = IndexBuffer.GetSpan <ushort>();
            var offset  = 0;
            var max     = 0;

            foreach (var x in Submeshes)
            {
                var submeshIndices = indices.Slice(offset, x.DrawCount);
                var currentMax     = 0;
                foreach (var y in submeshIndices)
                {
                    if (y < max)
                    {
                        return(true);
                    }
                    currentMax = Math.Max(y, currentMax);
                }
                offset += x.DrawCount;
                max     = currentMax;
            }
            return(false);
        }
示例#7
0
        ValueTuple <int, int, float> GetRange(float seconds)
        {
            var keys = In.GetSpan <float>();

            if (seconds <= keys[0])
            {
                return(0, 0, 0);
            }
            else if (seconds >= keys[keys.Length - 1])
            {
                return(keys.Length - 1, keys.Length - 1, 0);
            }

            // search range
            float begin = keys[0];
            float end;

            for (int i = 1; i < keys.Length; ++i)
            {
                end = keys[i];

                if (seconds == end)
                {
                    return(i, i, 0);
                }
                else if (seconds < end)
                {
                    var ratio = (seconds - begin) / (end - begin);
                    return(i - 1, i, ratio);
                }

                begin = end;
            }

            throw new Exception("not found");
        }
示例#8
0
        //
        // Memory<byte> を新規に確保して置き換える
        //
        public void Append(BufferAccessor a, int offset = -1)
        {
            if (AccessorType != a.AccessorType)
            {
                System.Console.WriteLine(AccessorType.ToString() + "!=" + a.AccessorType.ToString());
                throw new Exception("different AccessorType");
            }

            // UNSIGNED_SHORT <-> UNSIGNED_INT の変換を許容して処理を続行
            // 統合メッシュのprimitiveのIndexBufferが65,535(ushort.MaxValue)を超える場合や、変換前にindexBuffer.ComponetTypeがushortとuint混在する場合など
            if (ComponentType != a.ComponentType)
            {
                switch (a.ComponentType)
                {
                //ushort to uint
                case AccessorValueType.UNSIGNED_SHORT:
                {
                    var src   = a.GetSpan <UInt16>().Slice(0, a.Count);
                    var bytes = new byte[src.Length * 4];
                    var dst   = MemoryMarshal.Cast <byte, uint>(bytes);
                    for (int i = 0; i < src.Length; ++i)
                    {
                        dst[i] = (uint)src[i];
                    }
                    var accessor = new BufferAccessor(bytes, AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, a.Count);
                    a = accessor;

                    break;
                }

                //uint to ushort (おそらく通ることはない)
                case AccessorValueType.UNSIGNED_INT:
                {
                    var src   = a.GetSpan <UInt32>().Slice(0, a.Count);
                    var bytes = new byte[src.Length * 2];
                    var dst   = MemoryMarshal.Cast <byte, ushort>(bytes);
                    for (int i = 0; i < src.Length; ++i)
                    {
                        dst[i] = (ushort)src[i];
                    }
                    var accessor = new BufferAccessor(bytes, ComponentType, AccessorVectorType.SCALAR, a.Count);
                    a = accessor;
                    break;
                }

                default:
                    throw new Exception("Cannot Convert ComponentType");
                }
            }

            // 連結した新しいバッファを確保
            var oldLength = Bytes.Length;

            ToByteLength(oldLength + a.Bytes.Length);
            a.Bytes.CopyTo(Bytes.Slice(oldLength));
            Count += a.Count;

            if (offset > 0)
            {
                // 後半にoffsetを足す
                switch (ComponentType)
                {
                case AccessorValueType.UNSIGNED_SHORT:
                {
                    var span         = MemoryMarshal.Cast <byte, ushort>(Bytes.Slice(oldLength).Span);
                    var ushortOffset = (ushort)offset;
                    for (int i = 0; i < span.Length; ++i)
                    {
                        span[i] += ushortOffset;
                    }
                }
                break;

                case AccessorValueType.UNSIGNED_INT:
                {
                    var span       = MemoryMarshal.Cast <byte, uint>(Bytes.Slice(oldLength).Span);
                    var uintOffset = (uint)offset;
                    for (int i = 0; i < span.Length; ++i)
                    {
                        span[i] += uintOffset;
                    }
                }
                break;

                default:
                    throw new NotImplementedException();
                }
            }
        }