LizzyFox-code / BrgContainer

The Unity BRG Container
MIT License
61 stars 6 forks source link

Some strange things happen with delete data. #13

Open wearplugins opened 2 months ago

wearplugins commented 2 months ago

Some strange things happen. I set the data to the map editor (tile id 0) and delete the data from the BatchHandle.

if (Event.current.button == 1)
                    {
                        if (region.TileView != null)
                        {
                            _regionsMap.DeleteTile(region);
                        }
                    }
public void DeleteTile(Region region)
{
    if (region == null || region.TileId == 0)
        return;

    InstanceRenderer.Remove(region.TileView);
    region.TileView = null;
    region.TileId = 0;
}
// <summary> </summary>
        /// <param name="node"></param>
        public void Remove(BatchNode node)
        {
            _containers[node.BatchIndex].Remove(node.Index);
        }
/// <summary> </summary>
/// <param name="nodeIndex"></param>
public void Remove(int nodeIndex)
{
    var dataBuffer = _batchHandle.AsInstanceDataBuffer();
    dataBuffer.Remove(nodeIndex, 1);
}

But the data is not deleted and the tile does not disappear. After that the map is saved and reloading. The tiles are back in place and there are no deleted ones.

/// <summary> </summary>
public void CreateViews()
{
    foreach (var region in Grid)
        if (region != null && region.TileId > 0)
                CreateTileView(region);
    InstanceRenderer.Populate();
}

/// <summary> </summary>
public void CreateTileView(Region region)
{
    var tileData = _coreCollection.Get<GeoscapeTileData>(region.TileId);
    if (tileData != null)
    {
        var renderer = tileData.View.GetComponent<MeshRenderer>();
        var meshFilter = tileData.View.GetComponent<MeshFilter>();
        region.TileView = InstanceRenderer.AddCached(meshFilter.sharedMesh, renderer.sharedMaterial, Color.white,
            region.Position, Quaternion.identity, Vector3.one);
    }
}
/// <summary>
/// 
/// </summary>
public void PopulateCache()
{
    if (_cacheNodes==null || _cacheNodes.Count == 0)
        return;

    var dataBuffer = _batchHandle.AsInstanceDataBuffer();

    // this number can be not a constant, but less than BatchDescription.MaxInstanceCount
    dataBuffer.SetInstanceCount(_cacheNodes.Count); 

    for (var i = 0; i < _cacheNodes.Count; i++) 
    {
        var node = _cacheNodes[i];
        dataBuffer.SetTRS(i, node.Position, node.Rotation, node.Scale);
        dataBuffer.SetColor(i, _baseColorPropertyId, new Color(0.2f, 0.2f, 0.8f, 1f));
    }

    _batchHandle.Upload();

    _cacheNodes.Clear();
    _cacheNodes = null;
}

After assembling the build, the same thing happens, all deleted tiles are displayed.

What do you think could be the problem?

LizzyFox-code commented 2 months ago

Hi! After tile removing from the batch instance data buffer you need also call the Upload method to upload CPU copy of the data to the GPU side.

wearplugins commented 2 months ago
[ExecuteInEditMode]
public class BatchRenderer : MonoBehaviour
/// <summary> </summary>
public void Update()
{
    _containers.ForEach(c => c.Update());
}
 /// <summary> </summary>
 public void Update()
 {
     if (_initialized)
         _batchHandle.Upload();
 }

As an experiment

public void Remove(int nodeIndex) { var dataBuffer = _batchHandle.AsInstanceDataBuffer(); dataBuffer.Remove(nodeIndex, 1); _batchHandle.Upload(); }

Doesn't work either.

When the map is reloaded, all containers are rebuilt. Restarting the editor and the computer does not help. It seems that the buffer is cached somewhere.

wearplugins commented 2 months ago

In the editor, the tile id is set and stored in the map file. I don't delete tiles in вuild. The map is simply loaded and tiles with ID 0 are ignored (I checked) and should not be visible. But they are.

LizzyFox-code commented 2 months ago

Hmmm, what does the Frame Debugger show? And you can try to use RenderDoc to check the instance buffer data on the GPU.

wearplugins commented 2 months ago

Ok I will try to find the reason. When I find it, I will describe it and close the issue.