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

Ursina开发Minecraft删除Mesh顶点调用Mesh.generate()报错求助

问题

用Ursina开发Minecraft,手动通过添加顶点构建Chunk的Mesh,但删除顶点后调用Mesh.generate()触发错误。以下是测试代码及报错信息:

测试代码

from ursina import *
from ursina.shaders import basic_lighting_shader, lit_with_shadows_shader
from ursina.prefabs.first_person_controller import FirstPersonController

app = Ursina()

bte = Entity(model='block.obj',color=color.rgba(1,1,0,0.4),visible=False)
bte.scale=1.1
bte.origin_y+=0.05

sun = DirectionalLight(rotation=Vec3(45, 45, 45))

vertices = [# 底面
            [0, 0, 0], #0
            [0, 0, 1], #1
            [1, 0, 1], #2
            [1, 0, 1], #3
            [1, 0, 0], #4
            [0, 0, 0], #5

            # 顶面
            [0, 1, 0], #0
            [1, 1, 0], #1
            [1, 1, 1], #2
            [1, 1, 1], #3
            [0, 1, 1], #4
            [0, 1, 0], #5
            
            # 左面
            [0, 0, 0], #0
            [0, 1, 0], #1
            [0, 1, 1], #2
            [0, 1, 1], #3
            [0, 0, 1], #4
            [0, 0, 0], #5

            # 右面
            [1, 0, 0], #0
            [1, 0, 1], #1
            [1, 1, 1], #2
            [1, 1, 1], #3
            [1, 1, 0], #4
            [1, 0, 0], #5

            # 前面
            [0, 0, 0], #0
            [1, 0, 0], #1
            [1, 1, 0], #2
            [1, 1, 0], #3
            [0, 1, 0], #4
            [0, 0, 0], #5

            # 后面
            [0, 0, 1], #0
            [0, 1, 1], #1
            [1, 1, 1], #2
            [1, 1, 1], #3
            [1, 0, 1], #4
            [0, 0, 1], #5
            ]
normals = [[-1 if number == 0 else number for number in sublist] for sublist in vertices]
amesh = Mesh()

amesh.normals.extend(normals)
amesh.uvs.extend([[0,0], [0,1], [1,1], [1,1], [1,0], [0,0], # 底面
                  [0,0], [1,0], [1,1], [1,1], [0,1], [0,0], # 顶面
                  [0,0], [0,1], [1,1], [1,1], [1,0], [0,0], # 左面
                  [0,0], [1,0], [1,1], [1,1], [0,1], [0,0], # 右面
                  [0,0], [1,0], [1,1], [1,1], [0,1], [0,0], # 前面
                  [0,0], [0,1], [1,1], [1,1], [1,0], [0,0], # 后面
                  ])
amesh.vertices.extend(vertices)
amesh.vertices.remove([0, 0, 0])
amesh.generate()

报错信息(翻译后)

:prc(警告): 配置变量win-size的整数值无效: 864.0
:prc(警告): 配置变量win-size的整数值无效: 1536.0
已知管道类型: wglGraphicsPipe (3个辅助显示模块尚未加载。)
设置窗口位置: Vec2(192, 108)
:prc(警告): 将配置变量paste-emit-keystrokes的默认值从'1'改为'0'。
:pnmimage:png(警告): iCCP: 已知不正确的sRGB配置文件
package_folder: D:\MiniConda\Lib\site-packages\ursina
asset_folder: d:\Downloads\myCode\Python\小游戏\Minecraft-Ursina-2.0
读取obj文件路径: d:\Downloads\myCode\Python\小游戏\Minecraft-Ursina-2.0\assets\block.obj
保存.bam文件到: d:\Downloads\myCode\Python\小游戏\Minecraft-Ursina-2.0\models_compressed\block.bam
断言失败: (num_vertices + num_unused_vertices_per_primitive) % (num_vertices_per_primitive + num_unused_vertices_per_primitive) == 0
位于c:\buildslave\sdk-windows-amd64\build\panda\src\gobj\geomPrimitive.cxx第388行
回溯(最近的调用最后):
  文件 "d:\Downloads\myCode\Python\小游戏\Minecraft-Ursina-2.0\test.py", 第75行, in <module>
    amesh.generate()
  文件 "D:\MiniConda\Lib\site-packages\ursina\mesh.py", 第139行, in generate
    prim.close_primitive()
AssertionError: (num_vertices + num_unused_vertices_per_primitive) % (num_vertices_per_primitive + num_unused_vertices_per_primitive) == 0
位于c:\buildslave\sdk-windows-amd64\build\panda\src\gobj\geomPrimitive.cxx第388行

解决方案

错误原因

  1. 数据不匹配:Mesh的vertices、normals、uvs三个列表是严格一一对应的,每个顶点必须对应一个法线和UV坐标。你只删除了vertices中的一个元素,却没有同步删除normals和uvs中对应的元素,导致三者长度不一致。
  2. 顶点数不符合要求:Ursina默认用三角形绘制Mesh,顶点总数必须是3的倍数(每个三角形3个顶点)。你删除1个顶点后,总数不再是3的倍数,触发了底层Panda3D的断言检查。
  3. 删除操作不彻底:list.remove([0,0,0])只会删除列表中第一个匹配的元素,而你的原始顶点列表中有多个[0,0,0],这种删除方式逻辑混乱,无法精准控制要移除的面或顶点。

修复步骤

  1. 同步修改所有关联数据:如果要删除顶点,必须同时从vertices、normals、uvs中删除对应位置的元素,保证三者长度一致。
  2. 保证顶点数为3的倍数:每次修改后检查顶点总数,确保能被3整除(因为每个三角形需要3个顶点)。
  3. 提前构建正确的顶点列表:更高效的方式是在构建原始vertices、normals、uvs时,就只保留需要的面/顶点,而不是先添加全部再删除。

示例修改

比如要移除底面的所有顶点,直接在原始列表中删除底面对应的6个顶点,同时同步删除法线和UV的对应部分:

# 移除底面的顶点、法线、UV
del vertices[:6]
del normals[:6]
del amesh.uvs[:6]

# 再将处理后的列表添加到Mesh
amesh.vertices.extend(vertices)
amesh.normals.extend(normals)
amesh.uvs.extend(uvs)
amesh.generate()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:14:54