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(); }