Exemple #1
0
            public void Execute(
                Entity entity,
                int index,
                DynamicBuffer <BoneWorldMatrix> boneWorldMatrices,
                [ReadOnly] DynamicBuffer <RigIndex> rigIndices,
                [ReadOnly] DynamicBuffer <RigParentIndex> rigParentIndices,
                [ReadOnly] ref RigEntity rigEntity,
                [ReadOnly] ref BoneSize boneSize
                )
            {
                if (GlobalMatrices.Exists(rigEntity.Value))
                {
                    var rigTransforms = GlobalMatrices[rigEntity.Value].Reinterpret <float4x4>();

                    for (int i = 0; i != rigIndices.Length; ++i)
                    {
                        var start = rigTransforms[rigParentIndices[i].Value].c3.xyz;
                        var end   = rigTransforms[rigIndices[i].Value].c3.xyz;
                        boneWorldMatrices[i] = new BoneWorldMatrix {
                            Value = BoneRendererUtils.ComputeBoneMatrix(start, end, boneSize.Value)
                        };
                    }
                }
            }
        protected override unsafe void OnUpdate()
        {
            k_Marker.Begin();

            var boneWireMaterial = BoneRendererUtils.GetBoneWireMaterial();
            var boneFaceMaterial = BoneRendererUtils.GetBoneFaceMaterial();

            // Pack the rendering for each mesh to benefit from DrawInstanced.
            foreach (var boneShape in m_BoneShapes)
            {
                m_Query.SetSharedComponentFilter(new BoneRenderer.BoneShape {
                    Value = boneShape
                });
                var chunks = m_Query.CreateArchetypeChunkArray(Allocator.TempJob);

                var boneColorType = GetArchetypeChunkComponentType <BoneRenderer.BoneColor>(true);
                var entityType    = GetArchetypeChunkComponentType <BoneRenderer.BoneRendererEntity>(true);

                var srcOffset  = 0;
                var destOffset = 0;

                foreach (var chunk in chunks)
                {
                    var boneColors           = chunk.GetNativeArray(boneColorType);
                    var boneRendererEntities = chunk.GetNativeArray(entityType);

                    for (int i = 0; i != chunk.Count; i++)
                    {
                        var matricesBuffer = EntityManager.GetBuffer <BoneRenderer.BoneWorldMatrix>(boneRendererEntities[i].Value);
                        var bufLen         = matricesBuffer.Length;

                        fixed(Matrix4x4 *matricesPtr = &m_Matrices[0])
                        {
                            fixed(Vector4 *colorsPtr = &m_Colors[0])
                            {
                                while (destOffset + bufLen > kMaxDrawMeshInstanceCount)
                                {
                                    var copyCount = kMaxDrawMeshInstanceCount - destOffset;

                                    UnsafeUtility.MemCpy(matricesPtr + destOffset,
                                                         (float4x4 *)matricesBuffer.GetUnsafePtr() + srcOffset,
                                                         copyCount * UnsafeUtility.SizeOf <float4x4>()
                                                         );

                                    UnsafeUtility.MemCpyReplicate(colorsPtr + destOffset,
                                                                  (float4 *)boneColors.GetUnsafeReadOnlyPtr() + i,
                                                                  UnsafeUtility.SizeOf <float4>(),
                                                                  copyCount
                                                                  );

                                    m_PropertyBlock.SetVectorArray(m_ColorPropertyID, m_Colors);
                                    Graphics.DrawMeshInstanced(BoneRendererUtils.GetBoneMesh(boneShape), (int)BoneRendererUtils.SubMeshType.BoneFaces, boneFaceMaterial, m_Matrices, kMaxDrawMeshInstanceCount, m_PropertyBlock);
                                    Graphics.DrawMeshInstanced(BoneRendererUtils.GetBoneMesh(boneShape), (int)BoneRendererUtils.SubMeshType.BoneWires, boneWireMaterial, m_Matrices, kMaxDrawMeshInstanceCount, m_PropertyBlock);

                                    bufLen    -= copyCount;
                                    destOffset = 0;
                                    srcOffset += copyCount;
                                }

                                UnsafeUtility.MemCpy(matricesPtr + destOffset,
                                                     (float4x4 *)matricesBuffer.GetUnsafePtr() + srcOffset,
                                                     bufLen * UnsafeUtility.SizeOf <float4x4>()
                                                     );

                                UnsafeUtility.MemCpyReplicate(colorsPtr + destOffset,
                                                              (float4 *)boneColors.GetUnsafeReadOnlyPtr() + i,
                                                              UnsafeUtility.SizeOf <float4>(),
                                                              bufLen
                                                              );

                                srcOffset   = 0;
                                destOffset += bufLen;
                            }
                        }
                    }
                }

                // Only do a draw call when there is something to draw.
                if (destOffset > 0)
                {
                    m_PropertyBlock.SetVectorArray(m_ColorPropertyID, m_Colors);
                    Graphics.DrawMeshInstanced(BoneRendererUtils.GetBoneMesh(boneShape), (int)BoneRendererUtils.SubMeshType.BoneFaces, boneFaceMaterial, m_Matrices, destOffset, m_PropertyBlock);
                    Graphics.DrawMeshInstanced(BoneRendererUtils.GetBoneMesh(boneShape), (int)BoneRendererUtils.SubMeshType.BoneWires, boneWireMaterial, m_Matrices, destOffset, m_PropertyBlock);
                }

                m_Query.ResetFilter();
                chunks.Dispose();
            }

            k_Marker.End();
        }