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
相关产品推荐
相关产品推荐

