protected override unsafe void OnUpdate()
    {
        EntityQuery          query   = GetEntityQuery(ComponentType.ReadWrite <TrailBufferElement>());
        NativeArray <Entity> entitis = query.ToEntityArray(Allocator.Persistent);
        int segmentCount             = entitis.Length;
        int trailElementCount        = 0;
        BufferFromEntity <TrailBufferElement> buffers = GetBufferFromEntity <TrailBufferElement>();

        for (int i = 0; i < entitis.Length; ++i)
        {
            trailElementCount += buffers[entitis[i]].Length;
        }

        if (!m_TrailElements.IsCreated || m_TrailElements.Length < trailElementCount)
        {
            if (m_TrailElements.IsCreated)
            {
                m_TrailElements.Dispose();
            }
            m_TrailElements = new NativeArray <float3>(CalcWrappingArraySize(trailElementCount), Allocator.Persistent);

            m_TrailElementBufferInShader?.Dispose();
            m_TrailElementBufferInShader = new ComputeBuffer(m_TrailElements.Length, sizeof(TrailBufferElement));
        }

        if (!m_Segments.IsCreated || m_Segments.Length < segmentCount)
        {
            if (m_Segments.IsCreated)
            {
                m_Segments.Dispose();
            }
            m_Segments = new NativeArray <int3>(CalcWrappingArraySize(segmentCount), Allocator.Persistent);

            m_SegmentBufferInShader?.Dispose();
            m_SegmentBufferInShader = new ComputeBuffer(m_Segments.Length, sizeof(TrailBufferElement));
        }

        int     offset           = 0;
        float3 *trailElementsPtr = (float3 *)m_TrailElements.GetUnsafePtr();
        int3 *  segmentsPtr      = (int3 *)m_Segments.GetUnsafePtr();

        for (int i = 0; i < segmentCount; ++i)
        {
            DynamicBuffer <float3> trailbuffer = buffers[entitis[i]].Reinterpret <float3>();
            Entity entity = entitis[i];

            int bufferlength = trailbuffer.Length;

            UnsafeUtility.MemCpy(trailElementsPtr, trailbuffer.GetUnsafePtr(), sizeof(float3) * bufferlength);
            *segmentsPtr = new int3(offset, bufferlength, entity.Index);

            offset += bufferlength;

            segmentsPtr++;
            trailElementsPtr += bufferlength;

            for (int j = 0; j < trailbuffer.Length; ++j)
            {
                if (trailbuffer[j].x == 0.0f && trailbuffer[j].y == 0.0f && trailbuffer[j].z == 0.0f)
                {
                    Debug.Log(entity.Index);
                }
            }
        }

        m_TrailElementBufferInShader.SetData(m_TrailElements);
        m_SegmentBufferInShader.SetData(m_Segments);

        m_MaterialPropertyBlock.SetBuffer("_Positions", m_TrailElementBufferInShader);
        m_MaterialPropertyBlock.SetBuffer("_Segments", m_SegmentBufferInShader);

        m_MeshInstancedArgs.SetData(m_TrailMesh, (uint)segmentCount);

        Graphics.DrawMeshInstancedIndirect(
            m_TrailMesh, 0, m_Material,
            new Bounds(Vector3.zero, Vector3.one * 1000),
            m_MeshInstancedArgs.m_Buffer, 0, m_MaterialPropertyBlock
            );

        entitis.Dispose();
    }
示例#2
0
    protected override unsafe void OnUpdate()
    {
        // Segmentの個数を計算
        var segmentCount = componentGroup.CalculateLength();

        // TrailElementの個数を計算
        var trailBufferArray  = componentGroup.GetBufferArray <TrailBufferElement>();
        var trailElementCount = 0;

        for (var i = 0; i < segmentCount; ++i)
        {
            trailElementCount += trailBufferArray[i].Length;
        }

        // 配列のサイズが足りなかったら新しく作り直す
        if (!trailElements.IsCreated || trailElements.Length < trailElementCount)
        {
            if (trailElements.IsCreated)
            {
                trailElements.Dispose();
            }
            trailElements = new NativeArray <float3>(CalcWrappingArraySize(trailElementCount), Allocator.Persistent);

            trailElementBuffer?.Dispose();
            trailElementBuffer = new ComputeBuffer(trailElements.Length, sizeof(TrailBufferElement));
        }

        if (!segments.IsCreated || segments.Length < segmentCount)
        {
            if (segments.IsCreated)
            {
                segments.Dispose();
            }
            segments = new NativeArray <int3>(CalcWrappingArraySize(segmentCount), Allocator.Persistent);

            segmentBuffer?.Dispose();
            segmentBuffer = new ComputeBuffer(segments.Length, sizeof(TrailBufferElement));
        }

        // UnsafePtrを取得する
        var offset           = 0;
        var trailElementsPtr = (float3 *)trailElements.GetUnsafePtr();
        var segmentsPtr      = (int3 *)segments.GetUnsafePtr();

        var entityArray = componentGroup.GetEntityArray();

        // あらかじめ計算してあったSegmentの数(=パーティクルの数)だけループを回す
        for (var i = 0; i < segmentCount; ++i)
        {
            var trailBuffer = trailBufferArray[i];
            var entity      = entityArray[i];

            var bufferLength = trailBuffer.Length;

            // TrailBufferの値をNativeArrayに複製していく
            UnsafeUtility.MemCpy(trailElementsPtr, trailBuffer.GetBasePointer(), sizeof(float3) * bufferLength);
            *segmentsPtr = new int3(offset, bufferLength, entity.Index); // Segmentにヘッダ情報を書き込む

            // ヘッダ用のオフセットを再計算しておく
            offset += bufferLength;

            // ポインタを進める
            segmentsPtr++;
            trailElementsPtr += bufferLength;
        }

        // ComputeBufferにNativeArrayの情報を渡す
        trailElementBuffer.SetData(trailElements);
        segmentBuffer.SetData(segments);

        // MaterialPropertyBlockに生成したBufferを渡す
        materialPropertyBlock.SetBuffer("_Positions", trailElementBuffer);
        materialPropertyBlock.SetBuffer("_Segments", segmentBuffer);

        // Segmentの数を渡しておく
        meshInstancedArgs.SetData(trailMesh, (uint)segmentCount);

        // Meshを描画する
        Graphics.DrawMeshInstancedIndirect(
            trailMesh, 0, Material,
            new Bounds(Vector3.zero, Vector3.one * 1000),
            meshInstancedArgs.Buffer, 0, materialPropertyBlock
            );
    }