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

如何在Python的Panda3D引擎中创建三维几何形状及建筑基元?

在Panda3D中创建几何形状方案

一、内置简单几何形状

Panda3D自带基础几何体的预制模型,直接通过loader.loadModel()加载即可,无需手动构建顶点:

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        # 加载立方体
        cube = self.loader.loadModel("models/primitives/box")
        cube.reparentTo(self.render)
        cube.setPos(0, 5, 0)
        
        # 加载金字塔
        pyramid = self.loader.loadModel("models/primitives/pyramid")
        pyramid.reparentTo(self.render)
        pyramid.setPos(-2, 5, 0)
        
        # 平行六面体:通过非均匀缩放立方体实现
        parallelepiped = self.loader.loadModel("models/primitives/box")
        parallelepiped.reparentTo(self.render)
        parallelepiped.setPos(2, 5, 0)
        parallelepiped.setScale(1.5, 0.8, 1)

app = MyApp()
app.run()

二、自定义多边形基底的建筑基元

对于基底为任意多边形、墙体垂直于基底平面的结构,需要手动构建顶点和面:

核心步骤

  1. 定义基底顶点(按顺时针/逆时针顺序排列,示例用XY平面)
  2. 生成顶面顶点(将基底顶点沿Z轴拉伸指定高度)
  3. 三角化基底和顶面(Panda3D的Geom优先支持三角形面)
  4. 生成墙体:将相邻基底顶点与对应顶面顶点组成四边形,再拆分为两个三角形
  5. 将所有面组合为Geom,通过GeomNode生成NodePath加入场景

代码示例(五边形基底建筑)

from direct.showbase.ShowBase import ShowBase
from panda3d.core import (
    GeomVertexArrayFormat, GeomVertexFormat, GeomVertexData,
    Geom, GeomTriangles, GeomNode, Vec3, DirectionalLight, LVector3
)

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        # 1. 定义基底顶点(XY平面,顺时针顺序)
        base_verts = [
            Vec3(0, 0, 0), Vec3(1, 0, 0),
            Vec3(1.5, 1, 0), Vec3(0.5, 2, 0), Vec3(-0.5, 1, 0)
        ]
        building_height = 2.0
        
        # 2. 创建顶点格式(包含位置和法线,用于光照计算)
        array_format = GeomVertexArrayFormat()
        array_format.add_column("vertex", 3, Geom.NT_float32, Geom.C_point)
        array_format.add_column("normal", 3, Geom.NT_float32, Geom.C_normal)
        vert_format = GeomVertexFormat.register_format(GeomVertexFormat().add_array(array_format))
        
        # 3. 填充顶点数据
        vdata = GeomVertexData("building_data", vert_format, Geom.UH_static)
        v_writer = GeomVertexWriter(vdata, "vertex")
        n_writer = GeomVertexWriter(vdata, "normal")
        
        # 添加底面顶点和法线
        for v in base_verts:
            v_writer.add_data3(v)
            n_writer.add_data3(0, 0, -1)  # 底面法线向下
        
        # 添加顶面顶点和法线
        top_verts = [v + Vec3(0, 0, building_height) for v in base_verts]
        for v in top_verts:
            v_writer.add_data3(v)
            n_writer.add_data3(0, 0, 1)  # 顶面法线向上
        
        # 4. 构建几何体的面
        geom = Geom(vdata)
        num_base_verts = len(base_verts)
        top_offset = num_base_verts
        
        # 三角化底面
        base_tris = GeomTriangles(Geom.UH_static)
        for i in range(1, num_base_verts - 1):
            base_tris.add_vertices(0, i, i + 1)
        geom.add_primitive(base_tris)
        
        # 三角化顶面
        top_tris = GeomTriangles(Geom.UH_static)
        for i in range(1, num_base_verts - 1):
            top_tris.add_vertices(top_offset, top_offset + i, top_offset + i + 1)
        geom.add_primitive(top_tris)
        
        # 生成墙体(每个相邻顶点对拆成两个三角形)
        wall_tris = GeomTriangles(Geom.UH_static)
        for i in range(num_base_verts):
            curr_base = i
            next_base = (i + 1) % num_base_verts
            curr_top = curr_base + top_offset
            next_top = next_base + top_offset
            
            # 第一个三角形
            wall_tris.add_vertices(curr_base, next_base, curr_top)
            # 第二个三角形
            wall_tris.add_vertices(next_base, next_top, curr_top)
            
            # 计算墙面法线(可选,提升光照效果)
            edge = base_verts[next_base] - base_verts[curr_base]
            normal = edge.cross(Vec3(0,0,1)).normalized()
            # 注:若要精细化法线,需给墙体每个顶点单独设置,此处简化处理
        geom.add_primitive(wall_tris)
        
        # 5. 添加到场景
        geom_node = GeomNode("building_node")
        geom_node.add_geom(geom)
        building_np = self.render.attach_new_node(geom_node)
        building_np.setPos(-1, 5, 0)
        
        # 添加方向光,让几何体可见
        light_node = self.render.attach_new_node(DirectionalLight("sun"))
        light_node.node().set_direction(LVector3(-5, 5, -7))
        self.render.set_light(light_node)

app = MyApp()
app.run()

三、NodePath快速理解

NodePath是操作场景对象的核心工具,可视为场景节点的操作句柄:

  • 所有可见对象必须挂载到render根节点下,用reparentTo(self.render)或attach_new_node()实现
  • 常用操作:
    • setPos(x, y, z):设置对象位置
    • setHpr(h, p, r):设置旋转(航向、俯仰、滚转)
    • setScale(sx, sy, sz):缩放对象
    • attach_new_node(node):创建并挂载新节点到当前NodePath下

内容的提问来源于stack exchange,提问作者ЧАС

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 19:24:52