You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Octree系统实现报错求助:方法调用参数不匹配问题

Octree实现中的参数不匹配错误修复

错误原因分析

你遇到的两个错误核心是方法定义与调用签名完全不匹配:

  • CalculateAverageColor:你在Center类里试图以接收(OctreeNode, Color)委托的方式调用,但Octree类中该方法的实际定义是public Color CalculateAverageColor(Bounds bounds, Texture3D texture),需要传入边界和纹理两个参数,而非委托。
  • Traverse:Center类调用时传入了带两个参数的委托,但Octree类的Traverse方法定义是public void Traverse(OctreeNode node, System.Action<OctreeNode> action),其中action仅接受单个OctreeNode参数。

此外代码还存在其他隐性问题:

  • Octree类中接收Vector3Int position, Vector3Int dimensions的构造函数未实现,直接抛出异常,导致初始化失败。
  • OctreeNode的Bounds属性未初始化,后续计算平均颜色时会触发空引用错误。
  • Center类中调用CalculateAverageColor时,Texture尚未创建,会导致空引用。

分步修复方案

1. 补全Octree类构造函数并初始化节点Bounds

实现未完成的构造函数,同时为根节点初始化Bounds属性:

public Octree(Vector3Int position, Vector3Int dimensions)
{
    rootNode = new OctreeNode(position, dimensions);
    // 初始化根节点边界:中心坐标+尺寸
    rootNode.Bounds = new Bounds(
        new Vector3(position.x + dimensions.x/2f, position.y + dimensions.y/2f, position.z + dimensions.z/2f),
        new Vector3(dimensions.x, dimensions.y, dimensions.z)
    );
}

2. 调整CalculateAverageColor调用逻辑

删除Center类SetData方法中错误的_colorOctree.CalculateAverageColor(...)调用,改为在CreateTexture方法中创建纹理后,调用OctreeNode的CalculateAverageColor方法:

// Center类SetData方法中移除原错误调用,改为在CreateTexture中处理

在CreateTexture方法中,先填充纹理数据,再关联纹理到Octree节点并计算平均颜色:

private void CreateTexture()
{
    const TextureFormat format = TextureFormat.RGB24;
    
    // 创建Texture
    Texture = new Texture3D(_data.Size["width"], _data.Size["height"], _data.Size["depth"], format, false);
    // 先填充纹理原始数据
    _data.SetPixelTexture(Texture, nbChannel, _nbChannelGlobal, listChannel, lut);
    Texture.Apply(false, true);

    // 关联纹理到Octree根节点并计算所有节点平均颜色
    _colorOctree.rootNode.Texture = Texture;
    _colorOctree.rootNode.CalculateAverageColor(Texture);

3. 修正Traverse方法调用

Traverse方法的action仅接受OctreeNode参数,直接利用节点的AverageColor属性设置纹理即可:

// 修正CreateTexture中的Traverse调用
_colorOctree.Traverse(node =>
{
    Color color = node.AverageColor;
    for (int z = node.position.z; z < node.position.z + node.dimensions.z; z++)
    {
        for (int y = node.position.y; y < node.position.y + node.dimensions.y; y++)
        {
            for (int x = node.position.x; x < node.position.x + node.dimensions.x; x++)
            {
                Texture.SetPixel(x, y, z, color);
            }
        }
    }
});
Texture.Apply(false, true);

4. 为Octree类添加公共遍历入口

将rootNode设为public,或添加无需传入根节点的遍历方法:

// 在Octree类中添加公共遍历入口
public void Traverse(System.Action<OctreeNode> action)
{
    Traverse(rootNode, action);
}

修正后的关键代码片段

Center类核心修正

public void SetData(Data data, float divisionResolution=1, int nbChannelsGlobal=1)
{
    nbChannel = data._matriceImages[0].channels();
    sizeChannel = data._matriceImages[0].depth();
    _data = data;
    _nbChannelGlobal = nbChannelsGlobal;

    transform.localScale = new Vector3(
        (float)_data.Size["width"]/_data.Size.Values.Max(), 
        (float)_data.Size["height"]/_data.Size.Values.Max(),
        (float)_data.Size["depth"]/_data.Size.Values.Max()
    );

    // 创建Octree
    Vector3Int dimensions = new Vector3Int(_data.Size["width"], _data.Size["height"], _data.Size["depth"]);
    Vector3Int position = Vector3Int.zero;
    _colorOctree = new Octree(position, dimensions);
}

private void CreateTexture()
{
    const TextureFormat format = TextureFormat.RGB24;
    
    // 创建Texture
    Texture = new Texture3D(_data.Size["width"], _data.Size["height"], _data.Size["depth"], format, false);
    // 先填充纹理原始数据
    _data.SetPixelTexture(Texture, nbChannel, _nbChannelGlobal, listChannel, lut);
    Texture.Apply(false, true);

    // 关联纹理并计算平均颜色
    _colorOctree.rootNode.Texture = Texture;
    _colorOctree.rootNode.CalculateAverageColor(Texture);

    // 设置Texture数据
    _colorOctree.Traverse(node =>
    {
        Color color = node.AverageColor;
        for (int z = node.position.z; z < node.position.z + node.dimensions.z; z++)
        {
            for (int y = node.position.y; y < node.position.y + node.dimensions.y; y++)
            {
                for (int x = node.position.x; x < node.position.x + node.dimensions.x; x++)
                {
                    Texture.SetPixel(x, y, z, color);
                }
            }
        }
    });
    Texture.Apply(false, true);

    GetComponent<Renderer>().material.SetTexture("_Volume", Texture);
}

Octree类核心修正

public class Octree
{
    public OctreeNode rootNode; // 改为public方便访问

    public Octree(Texture3D texture)
    {
        Vector3Int dimensions = new Vector3Int(texture.width, texture.height, texture.depth);
        rootNode = new OctreeNode(Vector3Int.zero, dimensions);
        rootNode.Bounds = new Bounds(
            new Vector3(dimensions.x/2f, dimensions.y/2f, dimensions.z/2f),
            new Vector3(dimensions.x, dimensions.y, dimensions.z)
        );
        rootNode.Texture = texture;
        CalculateAverageColors(rootNode, texture);
    }

    public Octree(Vector3Int position, Vector3Int dimensions)
    {
        rootNode = new OctreeNode(position, dimensions);
        rootNode.Bounds = new Bounds(
            new Vector3(position.x + dimensions.x/2f, position.y + dimensions.y/2f, position.z + dimensions.z/2f),
            new Vector3(dimensions.x, dimensions.y, dimensions.z)
        );
    }

    // 公共遍历入口
    public void Traverse(System.Action<OctreeNode> action)
    {
        Traverse(rootNode, action);
    }

    // 其余方法保持不变
}

OctreeNode类核心修正(初始化Bounds)

public OctreeNode(Vector3Int position, Vector3Int dimensions)
{
    this.position = position;
    this.dimensions = dimensions;
    this.children = new List<OctreeNode>();
    
    _children = Enumerable.Repeat<OctreeNode>(null, 8).ToList();
    
    // 初始化节点边界
    Bounds = new Bounds(
        new Vector3(position.x + dimensions.x/2f, position.y + dimensions.y/2f, position.z + dimensions.z/2f),
        new Vector3(dimensions.x, dimensions.y, dimensions.z)
    );

    if (!IsLeaf())
    {
        Subdivide();
    }
}

内容的提问来源于stack exchange,提问作者Lvs17

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 09:14:54