python太阳代码_日出日落,python3D编程概念:相机、节点树与键盘控制

前面4节课程,基本都是在宇宙中观察,这次让我们回到地球上,看看人间的朝朝暮暮。同时,学习更多的3d编程的概念:相机、节点树与键盘控制。

相机

在3D编程中,相机是一个基本概念。我们从屏幕上看到的画面,正是系统内三维世界对相机的一个投影。相机与聚光灯光源的设置类似,有位置、朝向属性,此外还有一个所谓的透镜属性。这个透镜决定了相机的视角有多宽。

屏幕3D不能和人眼相比的一个关键因素就在这里,屏幕视角一般以40度为适当,视角太大则画面严重失真。而人类的扫视视角则可以宽达150度。所以人类在自然的天空找太阳是非常容易的,但是在屏幕上三维世界中,只有40度的视角,想从天上找到太阳就得费点事了。

相机还有另外一个特点是:对于距离极近的事物,相机就看不到了,即使勉强展示也只不过是一片纯色。所以我们的相机不能太贴近地面,否则就看不到地面。

节点树

熊猫引擎的所有可见事物,都称作节点,节点采用树状的方式来组织管理。最基本的世界节点叫做render,我们在前面的代码中已经看过了,所有的模型必须最终关联到render才可见。

在节点树中,所有下级节点都会跟随上级节点一起运动。而下级节点的坐标也都是参照上级节点而言的。这就带来了很多便利。

cm = panda3d.core.CardMaker('') cm.setFrame(-2, 2, -2, 2) floorTex = loader.loadTexture('grass.jpg') self.earth = render.attachNewNode(panda3d.core.PandaNode("floor")) for y in range(12): for x in range(12): nn = self.earth.attachNewNode(cm.generate()) nn.setP(-90) nn.setPos((x - 6) * 4, (y - 6) * 4, 0) self.earth.setTexture(floorTex) self.camera.reparentTo(self.earth)

这次,我们的地球不再使用球体,而是一个虚拟节点。然后用CardMaker建立若干(144)片草地铺成地面。这里的CardMaker负责建立一个简单的矩形平面,在它的表面贴上素材,模拟草地。每片草地都挂接在earth节点下,同时把相机(camera)也挂接在earth节点下。

这样,当地球节点做自转运动时,所有的草地与我们的相机都会跟随转动。

地球自转:

self.angle += delta * speed angleRadians = self.angle * (pi / 180.0) self.earth.setHpr(0, self.angle, 0) 太阳和光源

一如既往的,我们把太阳和光源放在同一个位置。由于这次有了地球的自转,我们只须让太阳和光源都固定不变即可。

self.sun = loader.loadModel("sphere") sunMaterial = panda3d.core.Material() sunMaterial.setEmission((1, 1, 1, 0.2)) self.sun.setMaterial(sunMaterial) self.sun.reparentTo(render) self.sun_tex = loader.loadTexture("sun_1k_tex.jpg") self.sun.setTexture(self.sun_tex, 1) self.sun.setScale(3) self.sun.setPos(0, -10, 50) self.light.setPos(0, -10, 50)

为了避免日落后3D世界中真正的一片漆黑,这次是必须放一个背景光源了。

self.alight = render.attachNewNode(panda3d.core.AmbientLight("Ambient")) self.alight.node().setColor(panda3d.core.LVector4(0.12, 0.12, 0.12, 1)) sunlight = panda3d.core.PointLight('plight') self.light = render.attachNewNode(sunlight) render.setLight(self.light) render.setLight(self.alight) 键盘控制

为了能够更好地进行观察,我们这次加入两组键盘控制:左右键让视角左转和右转,上下键则对应着抬头和低头。左右键是360度连续运动,而上键则以抬头至90度为止,下键则以视角平视为止(低头看地板也没什么意思)。

键盘控制,通过accept函数来定义:

self.keys = {} for key in ['arrow_left', 'arrow_right', 'arrow_up', 'arrow_down']: self.keys[key] = 0 self.accept(key, self.push_key, [key, 1])

其中,self.push_key是一个函数:

def push_key(self, key, value): self.keys[key] = value

键盘只记录,而对键盘效果的处理,仍然放在定时任务中。

delta = globalClock.getDt() self.camera.setPos(self.camx, self.camy, 3) self.heading += (delta * 90 * self.keys['arrow_left'] + delta * 90 * -self.keys['arrow_right']) self.pitch += (delta * 90 * self.keys['arrow_up'] + delta * 90 * -self.keys['arrow_down']) if self.pitch>90: self.pitch= 90 elif self.pitch<0: self.pitch= 0 self.camera.setHpr(self.heading, self.pitch, 0) self.camera.setPos(self.camx, self.camy, 3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值