Python Panda3D【 3D 游戏引擎和框架】 全面讲解

Panda3D 是一个开源的、免费的 3D 游戏引擎和框架,由迪士尼互动工作室开发并维护,后来开源。它使用 Python 和 C++ 编写,主要面向游戏开发、模拟、可视化和其他 3D 应用。

1. Panda3D 基础

1.1 安装 Panda3D

pip install panda3d

或者从官网下载安装包:www.panda3d.org

1.2 基本结构

一个最简单的 Panda3D 程序:

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        
        # 加载一个模型
        self.scene = self.loader.loadModel("models/environment")
        # 将模型附加到渲染场景中
        self.scene.reparentTo(self.render)
        # 设置模型的缩放和位置
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)

app = MyApp()
app.run()

2. 核心概念

2.1 场景图 (Scene Graph)

Panda3D 使用场景图来组织3D对象,主要节点类型包括:

  • Render: 根节点,所有可见对象都应附加到此节点
  • NodePath: 场景图中的路径,用于操作节点
  • GeomNode: 包含几何数据的节点
  • Camera: 相机节点

2.2 坐标系

Panda3D 使用右手坐标系:

  • X轴:向右
  • Y轴:向前
  • Z轴:向上

2.3 模型加载

# 加载模型
model = self.loader.loadModel("path/to/model")
model.reparentTo(self.render)

# 设置位置、旋转、缩放
model.setPos(x, y, z)
model.setHpr(h, p, r)  # 航向、俯仰、横滚
model.setScale(sx, sy, sz)

3. 渲染与光照

3.1 基本渲染设置

# 设置背景色
self.setBackgroundColor(0.1, 0.1, 0.1, 1)

# 启用阴影
self.render.setShaderAuto()

3.2 光照

# 创建平行光
dlight = DirectionalLight('dlight')
dlight.setColor((0.8, 0.8, 0.5, 1))
dlight_np = self.render.attachNewNode(dlight)
dlight_np.setHpr(45, -45, 0)
self.render.setLight(dlight_np)

# 创建点光源
plight = PointLight('plight')
plight.setColor((1, 0.5, 0.5, 1))
plight_np = self.render.attachNewNode(plight)
plight_np.setPos(10, 0, 0)
self.render.setLight(plight_np)

4. 相机控制

# 设置相机位置
self.camera.setPos(0, -20, 5)
self.camera.lookAt(0, 0, 0)

# 第一人称相机控制
self.disableMouse()  # 禁用默认鼠标控制
self.cameraControl = FirstPersonController(self)

# 轨道相机
self.trackball = Trackball(self)
self.trackball.setPos(0, -20, 0)

5. 动画与交互

5.1 键盘输入

from direct.showbase.DirectObject import DirectObject

class InputHandler(DirectObject):
    def __init__(self):
        self.accept("escape", sys.exit)  # ESC键退出
        self.accept("w", self.moveForward)
        
    def moveForward(self):
        print("Moving forward!")

handler = InputHandler()

5.2 鼠标输入

self.accept("mouse1", self.onClick)  # 左键点击

def onClick(self):
    if self.mouseWatcherNode.hasMouse():
        mpos = self.mouseWatcherNode.getMouse()
        print(f"Clicked at: {mpos}")

5.3 动画系统

Panda3D 支持两种动画系统:

  1. 基于 Actor 的骨骼动画
  2. 基于 Intervals 的变换动画
# 加载角色和动画
actor = Actor("models/character", {"walk": "models/character-walk"})
actor.reparentTo(self.render)
actor.loop("walk")  # 循环播放行走动画

# 使用Interval制作动画
from direct.interval.IntervalGlobal import *
Sequence(
    actor.posInterval(3, (5, 0, 0)),  # 3秒移动到x=5
    actor.hprInterval(2, (180, 0, 0))  # 然后2秒旋转180度
).start()

6. 物理引擎

Panda3D 支持多种物理引擎集成,如 Bullet 和 ODE。

6.1 Bullet 物理示例

from panda3d.bullet import BulletWorld, BulletPlaneShape, BulletBoxShape, BulletRigidBodyNode

# 创建物理世界
self.world = BulletWorld()
self.world.setGravity((0, 0, -9.81))

# 创建地面
shape = BulletPlaneShape((0, 0, 1), 0)
node = BulletRigidBodyNode('Ground')
node.addShape(shape)
ground = self.render.attachNewNode(node)
self.world.attachRigidBody(node)

# 创建盒子
box_shape = BulletBoxShape((0.5, 0.5, 0.5))
box_node = BulletRigidBodyNode('Box')
box_node.setMass(1.0)
box_node.addShape(box_shape)
box = self.render.attachNewNode(box_node)
box.setPos(0, 0, 5)
self.world.attachRigidBody(box_node)

# 更新物理世界
self.taskMgr.add(self.updatePhysics, 'updatePhysics')

def updatePhysics(self, task):
    dt = globalClock.getDt()
    self.world.doPhysics(dt)
    return task.cont

7. 高级特性

7.1 着色器编程

# 加载GLSL着色器
shader = Shader.load(Shader.SL_GLSL, 
                    "vertex.glsl", 
                    "fragment.glsl")
self.render.setShader(shader)

7.2 粒子系统

from panda3d.core import ParticleSystem, PointParticleFactory

# 创建粒子系统
system = ParticleSystem()
system.setPoolSize(100)
factory = PointParticleFactory()
system.addFactory(factory)

# 将粒子系统添加到场景中
renderer = ParticleSystemManager.getGlobalPtr().createRenderer("point")
system.addRenderer(renderer)
node = self.render.attachNewNode(system)
node.setPos(0, 0, 5)

7.3 音频系统

# 加载和播放音效
sound = loader.loadSfx("sound/effect.ogg")
sound.play()

# 播放背景音乐
music = loader.loadMusic("sound/music.ogg")
music.setLoop(True)
music.play()

8. 性能优化

  1. 模型优化:使用低多边形模型,合理使用LOD
  2. 纹理优化:使用压缩纹理,合理设置mipmap
  3. 批处理:对静态物体使用flattenStrong()
  4. 剔除:合理使用setBin()setDepthTest()
  5. 多线程:利用Panda3D的多线程渲染

9. 发布应用

# 打包为独立可执行文件
from panda3d.core import VirtualFileSystem
vfs = VirtualFileSystem.getGlobalPtr()
vfs.mount("models", "/path/to/models", 0)

可以使用PyInstaller或cx_Freeze将Python脚本打包为可执行文件。

10. 学习资源

  1. 官方文档:https://docs.panda3d.org/
  2. 官方示例:安装目录下的sample文件夹
  3. 社区论坛:https://discourse.panda3d.org/
  4. GitHub仓库:https://github.com/panda3d/panda3d

Panda3D 是一个功能强大但学习曲线适中的引擎,特别适合Python开发者进入3D游戏和图形编程领域。通过结合Python的易用性和Panda3D的强大功能,可以快速开发出高质量的3D应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老胖闲聊

创作不易,您的打赏是最大的鼓励

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值