Panda3d 介绍

news2025/1/15 7:37:47

Panda3d 介绍

文章目录

  • Panda3d 介绍
    • Panda3d 的安装
    • Panda3d 的坐标系统介绍
    • Panda3d 的运行
    • Panda3d 加载一个熊猫
      • 父节点和子节点之间的关系
    • 验证Panda3d 的坐标系统
      • X 轴的平移
      • Y 轴的平移
      • Z 轴的平移
      • X 轴的旋转
      • Y 轴的旋转
      • Z 轴的旋转

Panda3D是一个3D引擎:一个用于3D渲染和游戏开发的子程序库。该库是带有一组Python绑定的c++。使用Panda3D进行游戏开发通常需要编写一个Python或c++程序来控制Panda3D库。 Panda3D是为商业游戏开发而创建的,并且仍然用于开发商业游戏。

特点如下:

  • 提供了Python 和 C++ 两种形式的接口,底层采用C++实现的,因此在保证运行效率的前提下,使用panda3更加容易编写用户想要的界面;
  • 安装体积小,代码开源;
  • 具有良好的防崩溃机制;

Panda3d的官方网站
Panda3d的源代码
Panda3d国外的教程

Panda3d 的安装

首先通过pip指令下载:

pip3 install panda3d

Panda3d 的坐标系统介绍

Panda3d 的坐标系系统如下图所示, X 轴朝右,Y 轴朝后,Z 轴朝上。 姿态描述为 HPR,可以是欧拉角的形式,不过 H 表示的是绕着 Z 轴旋转, P 表示的是绕着 X 轴旋转, R 表示的是绕着 Y 轴旋转。
Panda3d姿态旋转图

Panda3d 的运行

任何一个3D引擎都需要一个窗口来承载其中的场景内容,那么我们的第一步就是了解Panda3d中如何打开一个窗口界面。

在Panda3d中是通过ShowBase类来创建一个游戏窗口,代码如下:

from direct.showbase.ShowBase import ShowBase

class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

app = App()
app.run()

程序解释如下:
上述程序中创建了一个ShowBase类,通过 Run 函数来显示这个窗口,运行上述代码,打开的窗口如下所示,从下图中可以看出窗口的title默认显示的是 Panda3d,默认打开的窗口大小是 800 * 600。

Pan3d 空白窗口
可以调整对应的参数让这个窗口显示的更大,一个方法就是直接点击窗口的最大化按钮。另外一种是通过代码实现,简而言之就是通过创建一个WindowProperties来实现,比如说你可以创建一个 1000 * 800 的窗口,这样如下操作:

from direct.showbase.ShowBase import ShowBase
from panda3d.core import WindowProperties

class App(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)

        properties = WindowProperties()
        properties.setSize(1000, 800)
        self.win.requestProperties(properties)

app = App()
app.run()

Panda3d 加载一个熊猫

一个游戏是需要一个背景的,因此,场景(Scenery)是需要第一个添加的元素。我们可以直接导入预设的场景模型来构建游戏背景。在添加之前,需要说明panda3d的一个基本数据结构:场景图(Scene Graph)。场景图其实是一个树形的数据结构,根节点是一个render对象,在根节点下的都是需要被渲染的元素。所以一般通过需要渲染元素的reparentTo() 方法将括号内的元素设为需要渲染元素的父节点(通过创建节点路径来实现)。比如我们获取了场景模型scene,那么我们可以通过scene.reparentTo(self.render)来将render设为场景模型的父节点(也可以理解为将场景模型挂载在render对象下),那么游戏启动时,由于render有scene这个子节点,所以scene就会被渲染在窗口上,从而让我们看到该场景。

Panda3d场景关系图

此外,给定节点的状态(例如其位置、姿态变化、模型的缩放)相对于其父节点的状态。也就是说,当我们获取一个子节点的位置的时候,如果位置参数为“零”,则表示“与其父节点位于同一位置”; 旋转姿态参数为“零”,则表示“与父节点具有相同的姿态”。因此,每个节点都会影响其子节点及其子节点,依此类推。父节点和子节点的之间的关系是父节点的移动一定会带动子节点的移动,但是子节点移动并不会带动父节点的移动。

你可以把它想象成有点像铰接小雕像的手臂:移动下臂实际上不会改变上臂。但是,移动上臂会导致下臂相应地移动。此外,如果上臂旋转为向上指向,则下臂同样指向上方,并且下臂的任何旋转都是相对于该方向的。
Panda3d场景中子父节点的关系
但是,大多数时候我们不会直接与节点进行交互。相反,我们与称为“NodePath”的进行交互。这实质上描述了从根到相关节点的场景图的路径。甚至可以为单个节点设置多个不同的 NodePath。

然而,出于实际目的,NodePath可以被认为是与节点几乎(但不完全)相同的:你可以用节点做的大部分事情,你可以用NodePath做(而且更方便)。此外,NodePaths包含对其节点的引用,因此我们也可以通过NodePaths 去操作对应的子节点。

最终我们往场景中导入一个熊猫,panda3d 模型下载

代码如下:

    self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda.reparentTo(self.render)
    self.panda.setScale(0.005,  0.005, 0.005)
    self.panda.setPos(0, 10, -1)

Panda3d导入一个熊猫

上述程序中,我们通过loader.loadModel()方法加载预设的场景模型,需要说明的是,该方法返回的是一个NodePath类,这其实是一个指向模型的指针。

上述的setScale(0.005, 0.005, 0.005)方法把载入场景模型的三个维度都缩小到原本的0.005倍再渲染。 setPos(0, 10, -1)方法将场景模型的位置设为(0, 10, -1),因为Panda3d 中默认相机的位置是在(0, 0, 0) 的位置,因此我们需要调整物体的位置来取得更好的显示效果。

当我们我们也可以保持物体的位置不变,通过修改相机的位置也是达到相同的效果, 在代码中控制相机的时候,最好是要调用disableMouse 函数。

    self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda.reparentTo(self.render)
    self.panda.setScale(0.005,  0.005, 0.005)
	self.disableMouse()
    self.camera.setPos(0, -10, 1)
    # self.panda.setPos(0, 10, -1)

Panda3d 中默认是采用鼠标进行控制相机的视角,如果我们不想采用鼠标进行控制,而是想在后续通过在代码中进行控制的话,那么也是可以禁用这种操作的,通过调用如下函数即可实现该功能。

	self.disableMouse()

这个函数的名字很容易使人误解。它只是停止了鼠标对摄影机的控制,并没有禁用鼠标。你仍可以获得鼠标的位置,以及鼠标的点击。

父节点和子节点之间的关系

下面我们通过在场景中导入两个一样的模型文件,但是修改两个模型挂载的父节点,效果和对应的代码如下:

    self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda.reparentTo(self.render)
    self.panda.setScale(0.005,  0.005, 0.005)
    self.panda.setPos(0, 10, -1)


    self.panda1 = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda1.reparentTo(self.render)
    self.panda1.setScale(0.005,  0.005, 0.005)
    self.panda1.setPos(3, 10, -1)

Panda3d导入两个熊猫

    self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda.reparentTo(self.render)
    self.panda.setScale(0.005,  0.005, 0.005)
    self.panda.setPos(0, 10, -1)


    self.panda1 = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda1.reparentTo(self.panda)
    self.panda1.setScale(1.0,  1.0, 1.0)
    self.panda1.setPos(600, 0.0, 0.0)

Panda3d导入两个熊猫父节点不同

最终上述两个代码显示的效果都是一样的,但是我们可以很明显的发现panda1的缩放比例和设置的位置是不一样的。在第一个例子中 panda1 导入的时候需要缩放 0.005 倍,但是在第一个例子中我们发现是不需要的缩放的。而对于位置而言,在第一个例子中 panda1 导入的时候设置的位置为(3, 10, -1),但是在第二个例子中我们发现设置的位置是(600, 0, 0), 通过一个简单的换算关系我们得出如下换算关系(3, 10, -1) = (0, 10, -1) + (600, 0, 0) * (0.005, 0.005, 0.005)。这个换算关系也最终验证上述所述的父节点的位置、姿态、缩放都是会影响子节点的,这个概念关系在后续的编程中是需要注意的。

    self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda.reparentTo(self.render)
    self.panda.setScale(0.001,  0.001, 0.001)
    self.panda.setPos(0, 10, -1)


    self.panda1 = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
    self.panda1.reparentTo(self.panda)
    self.panda1.setScale(1.0,  1.0, 1.0)
    self.panda1.setPos(600, 0.0, 0.0)

Panda3d导入两个熊猫父节点不同父节点缩放

在上述代码中,我们只对父节点进行缩放,在最终的显示效果中我们可以看出子节点也进行了对应的缩放。说明父节点的位置、姿态、缩放都是会影响子节点的,这个概念关系在后续的编程中是需要注意的。

验证Panda3d 的坐标系统

为了更好的说明 Panda3d 的坐标系, X 轴朝右,Y 轴朝后,Z 轴朝上。 姿态描述为 HPR,可以是欧拉角的形式,不过 H 表示的是绕着 Z 轴旋转, P 表示的是绕着 X 轴旋转, R 表示的是绕着 Y 轴旋转。我们在场景中两个不同样子的熊猫,一开始两个熊猫都在相同的位置,然后调整第二个熊猫的位置和姿态来比较不同参数的含义,姿态的旋转以逆时针方向为正, 姿态的单位是 deg, 位置的单位是 m。

      self.panda = self.loader.loadModel('./panda3d-master/models/panda-model.egg')
      self.panda.reparentTo(self.render)
      self.panda.setScale(0.003,  0.003, 0.003)
      self.panda.setPos(0, 10, -1)


      self.panda1 = self.loader.loadModel('./panda3d-master/models/panda.egg')
      self.panda1.reparentTo(self.render)
      self.panda1.setScale(0.2,  0.2, 0.2)
      self.panda1.setPos(0, 10, -1)

      self.disableMouse()
      self.camera.setPos(1.5, 0, 0)

Panda3d导入两个熊猫相同位置

X 轴的平移

    self.panda1.setPos(3, 10, -1)
    self.panda1.setHpr(0, 0, 0)

Panda3d导入两个熊猫X方向的平移

Y 轴的平移

    self.panda1.setPos(0, 20, -1)
    self.panda1.setHpr(0, 0, 0)

Panda3d导入两个熊猫Y方向的平移

Z 轴的平移

    self.panda1.setPos(0, 10, 0)
    self.panda1.setHpr(0, 0, 0)

Panda3d导入两个熊猫Z方向的平移

X 轴的旋转

    self.panda1.setPos(3, 10, -1)
    self.panda1.setHpr(0, 90, 0)

Panda3d导入两个熊猫饶X轴旋转

因为 X 轴是朝向右边的,因此沿着 X 轴旋转90度,原来头是朝上的,现在改成朝前了。

Y 轴的旋转

    self.panda1.setPos(3, 10, -1)
    self.panda1.setHpr(0, 0, 90)

Panda3d导入两个熊猫饶Y轴旋转

因为 Y 轴是朝向后边的,因此沿着 Y 轴旋转90度,原来两只手是水平放置的,现在改成垂直方向的了。

Z 轴的旋转

    self.panda1.setPos(3, 10, -1)
    self.panda1.setHpr(90, 0, 0)

Panda3d导入两个熊猫饶Z轴旋转

因为 Z 轴是朝向上的,因此沿着 Z 轴旋转90度,原来肚子是朝前的,现在改成朝右了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1151310.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++ 自引用指针this(整理)

使用例子&#xff1a; #include <iostream> #include <Windows.h> using namespace std; class A { public:A(int x1){x x1;}void disp(){cout<<"this"<<this<<" when x"<<this->x<<endl;} private:int x;…

MSQL系列(十二) Mysql实战-为什么索引要建立在被驱动表上

Mysql实战-left/right/inner join 使用详解 前面我们讲解了BTree的索引结构&#xff0c;也详细讲解下 left Join的底层驱动表 选择原理&#xff0c;那么今天我们来实战一下 left join&#xff0c;right join&#xff0c;inner join 等sql命令&#xff0c;看看到底如何用以及如…

MySQL主从复制延时

主从复制原理 MySQL主从复制是MySQL数据库中一种数据备份和数据同步的方式。它将一台MySQL服务器&#xff08;主服务器&#xff09;的数据同步到另外一台MySQL服务器&#xff08;从服务器&#xff09;。主服务器是数据的提供者&#xff0c;而从服务器是数据的接收者。主从复制…

23秋季学期期中考核(密码题)

师兄新学的Decode姿势 题目给出的 const SM4 require("gm-crypt").sm4; var payload "inu7s0XGslLFsPe0xok/nxqwtceG0cuMoh7hBbpwyNBrn3g/lMdcFYobv/KeRgWwI/TIA4qMtjqpNKOet E3TD0gWoSknGF6OhkRJ3LxrNUZ/Mi8ISz3xrDLawIY8NwbalYcQUGWtVjdC3nJL…

对象补充-原型和函数原型-创建对象

defineProperties可以定义多个属性描述符 var obj {// 私有属性&#xff08;js里面是没有严格意义的私有属性&#xff09;_age: 18,_eat: function() {} }Object.defineProperties(obj, {name: {configurable: true,enumerable: true,writable: true,value: "why"}…

软件测试面试高频30道面试题

如果哪个测试经理在看我的文章&#xff0c;希望对面试者要微笑&#xff0c;不然面试结束&#xff0c;出门之后就一万个草泥马奔腾而过&#xff0c;其实面试者并不是希望你给他们什么&#xff0c;而是一种尊重&#xff0c;平等的谈话&#xff0c;不要高高在上感觉自己超牛逼一样…

二蛋赠书六期:《Linux管理入门经典(第8版)》

前言 大家好&#xff01;我是二蛋&#xff0c;一个热爱技术、乐于分享的工程师。在过去的几年里&#xff0c;我一直通过各种渠道与大家分享技术知识和经验。我深知&#xff0c;每一位技术人员都对自己的技能提升和职业发展有着热切的期待。因此&#xff0c;我非常感激大家一直…

linux入门---线程的互斥

目录标题 什么是线程安全为什么会出现负数几个概念的介绍锁的理解锁有关函数的介绍锁的问题如何看待加锁和解锁锁的实现原理锁的封装线程安全和可重入函数死锁的概念 什么是线程安全 我们通过下面的例子来了解一下线程安全问题&#xff0c;首先我们实现一个模拟抢票的功能创建…

docker搭建halo个人博客

docker run -it -d --name halo -p 9090:8090 -v /usr/local/halo2:/root/.halo2 halohub/halo:2.10halo个人网站搭建效果 提供皮肤市场 编辑界面 自定义菜单

在win10下,使用torchviz对深度学习网络模型进行可视化

目录 1. 安装 graphviz 和 torchviz 2.安装 graphviz.exe 3.实例测试 4.如果你的电脑还是无法画图&#xff0c;并且出现了下面的报错&#xff1a; 5.参考文章&#xff1a; 1. 安装 graphviz 和 torchviz 首先打开 Anaconda prompt 进入自己的 pytorch 环境(图中 pt 是我自…

liunx练习题之在同一主机提供多个的web服务

虚拟web主机类型 一、基于端口 1.vim /etc/httpd/conf.d/vhost2.conf ---- — 改变http服务默认访问路径 <directory /testweb1>allowoverride none 表示不允许覆盖其他配置require all granted 表示允许所有请求 </directory> <virtualhost 0.0.0.0:…

【Leetcode】【简单】13. 罗马数字转整数

力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://leetcode.cn/problems/roman-to-integer/description/ …

【网络协议】聊聊套接字socket

网络编程我们知道是通过socket进行编程的&#xff0c;其实socket也是基于TCP和UDP协议进行编程的。但是在socket层面是感知不到下层的&#xff0c;所以在设置参数的时候&#xff0c;其实是端到端协议智商的网络层和传输层。TCP是数据流所以设置为SOCK_STREAM&#xff0c;而UDP是…

【配置环境】VS Code中JavaScript环境搭建

一&#xff0c;环境 Windows 11 家庭中文版&#xff0c;64 位操作系统, 基于 x64 的处理器VS Code 版本: 1.83.1 (user setup)Node.js 版本&#xff1a;20.9.0 二&#xff0c;为什么搭建JavaScript环境 因为在看《重构改善既有代码的设计第2版》的时候&#xff0c;书中的代码展…

嵌入式基础知识-RSA非对称加密基本原理

之前的文章嵌入式基础知识-信息安全与加密&#xff0c;介绍过数据加密的一些基本概念&#xff0c;对称加密的原理比较简单&#xff0c;加密和解密的密钥相同&#xff0c;而非对称加密&#xff0c;两个密钥不同&#xff0c;本篇就来具体介绍RSA这种非对称加密的密钥计算原理。 …

【PyQt学习篇 · ⑧】:QWidget - 窗口特定操作

文章目录 图标标题不透明度窗口状态最大化和最小化窗口标志案例 图标 setWindowIcon(QIcon("resource/header_icon.png"))&#xff1a;该函数用于设置QWidget的窗口图标。可以为窗口设置一个图标&#xff0c;以显示在窗口标题栏、任务栏或窗口管理器中。 windowIcon…

全面解析:oa系统是什么?有哪些好用的oa系统

oa系统是什么&#xff1f;有哪些好用的oa系统 一、什么是OA系统 OA系统全称为Office Automation&#xff0c;即办公自动化系统。它是一种专门为企业和机构的日常办公工作提供服务的综合性软件平台&#xff0c;具有信息管理、流程管理、知识管理&#xff08;档案和业务管理&am…

视频剪辑软件Corel VideoStudio Ultimate 会声会影2024中文旗舰版免费下载安装步骤

我喜欢视频剪辑软件Corel VideoStudio Ultimate 会声会影2024中文旗舰版&#xff0c;因为它使用起来很有趣。它很容易使用&#xff0c;但仍然给你很多功能和力量。VideoStudio让我与世界分享我的想法&#xff01;“这个产品的功能非常多&#xff0c;我几乎没有触及它的表面&…

分布式系统之CAP理论

1. CAP 概念 CAP 概念指的是分布式系统中的三个核心属性&#xff1a;一致性&#xff08;Consistency&#xff09;、可用性&#xff08;Availability&#xff09;、分区容错性&#xff08;Partition Tolerance&#xff09;。CAP 定理由计算机科学家 Eric Brewer 在 2000 年提出&…