3D WFC多层实现异常:GetRotatedEdgeID函数上下方向处理矛盾
修复3D WFC的GetRotatedEdgeID函数问题
首先明确核心问题:
- 保留上下方向判断时触发矛盾,本质是水平旋转的边缘索引计算错误,导致水平方向约束无法满足,进而引发整体矛盾。
- 注释上下判断后,上下方向被错误归入水平旋转逻辑,导致上下层边缘无约束,生成独立的2D结果。
修复步骤:
- 明确水平方向映射规则
确保ConvertDirectionToCompassIndex函数的映射与绕Y轴(从上往下看)的水平旋转逻辑一致,标准映射如下:
private int ConvertDirectionToCompassIndex(Vector3Int direction) { if (direction == Vector3Int.forward) return 0; // Z+ 朝前 if (direction == Vector3Int.right) return 1; // X+ 朝右 if (direction == Vector3Int.back) return 2; // Z- 朝后 if (direction == Vector3Int.left) return 3; // X- 朝左 throw new ArgumentException("方向必须是水平方向(X/Z轴)"); }
- 修正水平旋转的索引计算
根据rotationIndex代表的旋转方向调整计算逻辑:
- 若
rotationIndex是顺时针旋转次数(每次90度),优化取模逻辑避免负数:int rotatedIndex = (compassIndex - rotationIndex + 4) % 4; - 若
rotationIndex是逆时针旋转次数,改为加法取模:int rotatedIndex = (compassIndex + rotationIndex) % 4;
- 保留上下方向的正确处理
上下方向(Y轴)不受水平旋转影响,直接返回对应边缘的逻辑是正确的,需确保:- 单元格数据中
Yp(顶部边缘)和Yn(底部边缘)的定义与约束规则匹配。 - 约束规则中,上层单元格的
Yn必须与下层单元格的Yp兼容。
- 单元格数据中
修复后的完整函数:
private EdgeID GetRotatedEdgeID(WFCCell3D data, int rotationIndex, Vector3Int direction) { // 上下方向不受水平旋转影响,直接返回对应边缘 if (direction == Vector3Int.up) return data.Yp; if (direction == Vector3Int.down) return data.Yn; // 转换水平方向为罗盘索引 int compassIndex = ConvertDirectionToCompassIndex(direction); // 计算旋转后的索引(假设rotationIndex为顺时针旋转次数,+4确保非负) int rotatedIndex = (compassIndex - rotationIndex + 4) % 4; // 返回对应边缘ID return rotatedIndex switch { 0 => data.Zp, 1 => data.Xp, 2 => data.Zn, 3 => data.Xn, _ => throw new InvalidOperationException("无效的旋转索引") }; }
额外排查点:
- 验证
rotationIndex的取值范围(0-3,对应0/90/180/270度旋转)。 - 检查约束数据:确保水平方向边缘的兼容性与旋转逻辑匹配,上下边缘的兼容性正确关联
Yp和Yn。
内容的提问来源于stack exchange,提问作者Warre Geerts
相关产品推荐
相关产品推荐

