Panda3d 介绍

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 ShowBaseclass 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 WindowPropertiesclass 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.mzph.cn/news/124387.shtml

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

相关文章

Docker Consul概述及构建

Docker Consul概述及构建 一、Consul概述1.1、什么是Consul1.2、consul 容器服务更新与发现1.3、服务注册与发现的含义1.4、consul-template概述1.5、registrator的作用 二、consul部署2.1、环境配置2.2、在主节点上部署consul2.3 、配置容器服务自动加入nginx集群2.3.1、安装G…

IDEA 使用技巧

文章目录 语言支持简化编写 有问题,可暂时跳过 个人常用快捷键插件主题插件功能插件 碰到过的问题 除了一些在Linux上用vim开发的大佬,idea算是很友好的集成开发工具了,功能全面,使用也很广泛。 记录一下我的 IDEA 使用技巧&#…

OSPF综合实验

一、实验拓扑 二、实验需求 1、R4为ISP,其上只配置IP地址;R4与其他所直连设备间均使用公有IP; 2、R3-R5、R6、R7为MGRE环境,R3为中心站点; 3、整个OSPF环境IP基于172.16.0.0/16划分;除了R12有两个环回&a…

分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测(自注意力机制)

分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测(自注意力机制) 目录 分类预测 | Matlab实现KOA-CNN-BiLSTM-selfAttention多特征分类预测(自注意力机制)分类效果基本描述程序设计参考资料 分类效果 基本描述 1…

DVWA-SQL Injection SQL注入

概念 SQL注入,是指将特殊构造的恶意SQL语句插入Web表单的输入或页面请求的查询字符串中,从而欺骗后端Web服务器以执行该恶意SQL语句。 成功的 SQL 注入漏洞可以从数据库中读取敏感数据、修改数据库数据(插入/更新/删除)、对数据…

使用Gateway解决跨域问题时配置文件不生效的情况之一

首先html文件只有一个发送ajax请求 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content&q…

21.12 Python 实现网站服务器

Web服务器本质上是一个提供Web服务的应用程序&#xff0c;运行在服务器上&#xff0c;用于处理HTTP请求和响应。它接收来自客户端&#xff08;通常是浏览器&#xff09;的HTTP请求&#xff0c;根据请求的URL、参数等信息生成HTTP响应&#xff0c;并将响应返回给客户端&#xff…

基于SpringBoot的在线笔记系统

技术介绍 &#x1f525;采用技术&#xff1a;SpringSpringMVCMyBatisJSPMaven &#x1f525;开发语言&#xff1a;Java &#x1f525;JDK版本&#xff1a;JDK1.8 &#x1f525;服务器&#xff1a;tomcat &#x1f525;数据库&#xff1a;mysql &#x1f525;数据库开发工具&…

C#开发DLL,CAPL调用(CAPL>> .NET DLL)

文章目录 展示说明新建类库工程C# 代码生成dllCAPL脚本调用dll,输出结果展示 ret为dll里函数返回的值。 说明 新建类库工程 在visual studio中建立。 C# 代码 using

合肥中科深谷嵌入式项目实战——人工智能与机械臂(三)

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 作者&#xff1a;爱吃饼干的小白鼠。Python领域优质创作者&#xff0c;2022年度博客新星top100入围&#xff0c;荣获多家平台专家称号。…

时序预测 | Matlab实现ARIMA-LSTM差分自回归移动差分自回归移动平均模型模型结合长短期记忆神经网络时间序列预测

时序预测 | Matlab实现ARIMA-LSTM差分自回归移动差分自回归移动平均模型模型结合长短期记忆神经网络时间序列预测 目录 时序预测 | Matlab实现ARIMA-LSTM差分自回归移动差分自回归移动平均模型模型结合长短期记忆神经网络时间序列预测预测效果基本介绍程序设计参考资料 预测效果…

Ansible中常用模块

目录 一、Ansible实现管理的方式 二、Ad-Hoc执行方式中如何获得帮助 三、Ansible命令运行方式及常用参数 四、Ansible的基本颜色代表信 五、Ansible中的常用模块 1、command模块 2、shell模块、script模块 3、copy模块、fetch模块 4、file模块 5、archive模块、unarc…

springboot整合postgresql

使用docker安装postgres 简单起见&#xff0c;这里用docker来安装postgresql docker pull postgresdocker run --name postgres \-e POSTGRES_PASSWORD123456 \-p 5432:5432 \-v /usr/local/docker/postgresql/data:/var/lib/postgresql/data \-d postgrespostgres客户端 pg…

ARL灯塔安装与使用

ARL灯塔安装与使用 1. 系统要求2. ARL灯塔安装2.1. docker环境安装2.1.1. 更新yum包2.1.2. 卸载老版docker2.1.3. 安装docker所需要的依赖包2.1.4. 设置yum源2.1.5. 查看仓库中docker版本2.1.6. 安装docker最新版2.1.7. docker设置2.1.8. docker其它命令 2.2. 安装docker-compo…

处理大数据的基础架构,OLTP和OLAP的区别,数据库与Hadoop、Spark、Hive和Flink大数据技术

处理大数据的基础架构&#xff0c;OLTP和OLAP的区别&#xff0c;数据库与Hadoop、Spark、Hive和Flink大数据技术 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&am…

在python中加载tensorflow-probability模块和numpy模块

目录 操作步骤&#xff1a; 注意&#xff1a; 问题&#xff1a; 解决办法&#xff1a; 操作步骤&#xff1a; 在虚拟环境的文件夹中&#xff0c;找到Scripts文件夹&#xff0c;点击进去&#xff0c;找到地址栏&#xff0c;在地址栏中输入cmd&#xff0c;进入如下界面。 输…

安防视频监控平台EasyCVR前端解码与后端解码的区别介绍

视频监控平台/视频存储/视频分析平台EasyCVR基于云边端一体化管理&#xff0c;支持多类型设备、多协议方式接入&#xff0c;具体包括&#xff1a;国标GB28181协议、RTMP、RTSP/Onvif、海康Ehome&#xff0c;以及海康SDK、大华SDK、华为SDK、宇视SDK、乐橙SDK、萤石SDK等&#x…

批量剪辑的视频怎么才能有更高的质量,更好的过审率?

在这个人人都做短视频的时代&#xff0c;批量剪辑工具就应运而生&#xff0c;成为不少短视频从业者的首选。超级编导剪辑软件是一款高质量的批量剪辑工具&#xff0c;能够一站式助力短视频团队完成脚本创作、批量剪辑、矩阵分发&#xff0c;是所有做短视频的团队不可多得的得力…

设计模式—创建型模式之工厂模式

设计模式—创建型模式之工厂模式 工厂模式&#xff08;Factory Pattern&#xff09;提供了一种创建对象的最佳方式。我们不必关心对象的创建细节&#xff0c;只需要根据不同情况获取不同产品即可。 简单工厂模式 比如我们有造车的工厂&#xff0c;来生产车&#xff0c;我们先…

NSSCTF做题第十页(1)

[GXYCTF 2019]禁止套娃 看源代码也没什么东西&#xff0c;扫一下看看 发现了git泄露 话不多说直接开整 下载下来了 flag.php 还是代码审计 <?php include "flag.php"; echo "flag在哪里呢&#xff1f;<br>"; if(isset($_GET[exp])){ if (!preg_…