【计算机图形学】三维美术馆漫游

中国农业大学计算机图形学 2022课程设计 三维美术馆漫游

写在前面:这玩意还是蛮有趣的哈哈哈

第一部分:加载场景,让人物动起来

import sys	    #加载库文件
import viz
import vizact
import vizinfo
import vizshape
import vizact
import math
import datetime

speed = 2.0		#设置移动速度
view = viz.MainView		#设置视角,get the main viewpoint object

viz.setMultiSample(18)
viz.go()
viz.mouse.setVisible(viz.OFF) 		#关闭鼠标图案

avatar = viz.addAvatar('vcc_male.cfg', pos=(0,0,0), euler=(0,0,0))		#加入人物,模型是自带男性,位置坐标,欧拉角
gallery = viz.add('gallery.osgb')		#载入美术馆模型
car = viz.addChild('mini.osg', pos=(0,0,6), euler=(-90,0,0))		#加入一辆minicooper

运行该片段,用鼠标进行移动,可以观察该场景和各模型

第二部分:让这个人走起来

我们现在需要让这个痴呆小人没病走两步,下面来实现一些基础代码

在移动的时候,先不考虑转圈和视角移动,在上一个代码段后插入该段代码

核心思路,人动,视角追,人转,视角变换之后转

其中坐标计算的有关数学知识部分见周学长的讲解:http://t.csdn.cn/Lzc6E

def UpdateView():
	m = viz.Matrix.euler(0,0,0)		#定义人物模型移动的坐标矩阵
	camera = viz.Matrix.euler(0,0,0)	#定义相机移动的坐标矩阵
	dm = viz.getFrameElapsed() * speed		#定义一个dm,记录获取自上一帧以来经过的时间*速度的结果
	temp=avatar.getEuler()[0]*math.pi/180		#获取人物当前的欧拉矩阵,并用temp记录其在x方向上的夹角
	if viz.key.isDown('w'):		#如果按下‘W’键,则对人物模型和相机的坐标矩阵根据欧拉角进行改变,并播放移动动作
		m.preTrans([dm*math.sin(temp),0,dm*math.cos(temp)])		#人物
		camera.preTrans([dm*math.sin(temp),0,dm*math.cos(temp)])		#相机
		avatar.state(2)		#播放移动动作
	elif viz.key.isDown('s'):		#同理
		m.preTrans([-dm*math.sin(temp),0,-dm*math.cos(temp)])
		camera.preTrans([-dm*math.sin(temp),0,-dm*math.cos(temp)])
		avatar.state(2)
	elif viz.key.isDown('a'):
		m.preTrans([-dm*0.3*math.cos(temp),0,dm*0.3*math.sin(temp)])
		camera.preTrans([-dm*0.3*math.cos(temp),0,dm*0.3*math.sin(temp)])
		avatar.state(12)
	elif viz.key.isDown('d'):
		m.preTrans([dm*0.3*math.cos(temp),0,-dm*0.3*math.sin(temp)])
		camera.preTrans([dm*0.3*math.cos(temp),0,-dm*0.3*math.sin(temp)])
		avatar.state(13)
	else :
		avatar.state(1)	#如果站着不动蛤起,也要播一个动作
	avatar.setPosition(m.getPosition(), viz.REL_PARENT)		#setPosition(x,y,z,参数),其中viz.REL_PARENT代表根据其现在的位置重新构筑的相对坐标系,前面的m.getPosition()即是在相对坐标系下进行修改
	view.setPosition(camera.getPosition(), viz.REL_PARENT)
	
vizact.ontimer(0,UpdateView)	#让其重复执行该函数

第三部分:让这个人转起来

这一部分,原理见帮助文档视角窗变换章节

#【函数】鼠标控制第三人称摄像机跟随人物旋转
def onMouseMove(e):
	p1 = avatar.getPosition()          #摄像机位置坐标
	p2 = view.getPosition()				#摄像机位置坐标
	e1 = avatar.getEuler()             #旋转前人  物的朝向欧拉角
	e2 = view.getEuler()                  #旋转前摄像机的朝向欧拉角
	
	e1[0] = e1[0]+e.dx/10                 #鼠标横向偏移,将鼠标偏移量除以10控制鼠标灵敏度,人  物旋转,偏航角e1[0]改变
	avatar.setEuler(e1)                #旋转后人  物的朝向欧拉角

	p2[1] = p1[1]+2                                       #摄像机在y轴的相对高度比人物高,即在y轴方向摄像机以人物高2个单位
	p2[0] = p1[0]-3*math.sin(math.pi*(e1[0]/180))          #摄像机在x轴的相对距离在人物后,即摄像机在x轴方向偏移了3sin(θ)个单位
	p2[2] = p1[2]-3*math.cos(math.pi*(e1[0]/180))          #摄像机在z轴的相对距离在人物后,即摄像机在z轴方向偏移了3cos(θ)个单位

	e2[0]=e1[0]
	e2[2]=e1[2]
	e2[1] = e2[1]-e.dy/10                 #鼠标纵向偏移,将鼠标偏移量除以20控制鼠标灵敏度,摄像机旋转,俯仰角e2[1]改变
	e2[1] = viz.clamp(e2[1],-85.0,85.0)	  #控制俯仰角
	view.setEuler(e2) 
	view.setPosition(p2)                  #设置旋转后摄像机的位置坐标

viz.callback(viz.MOUSE_MOVE_EVENT,onMouseMove)    #回调函数检测鼠标偏移量

其中利用clamp函数控制摄像机在y轴的夹角,避免小人晕头转向!!

第四部分:加入关键要素,时钟

此部分讲解学长讲得非常详细http://t.csdn.cn/Lzc6E

这里我就只粘贴代码了,四个模型建好放在resources文件夹下,运行即可

biaopan=viz.add('Biaopan.obj')	#加入表盘模型
shizhen=viz.add('Shizhen.obj')	#加入时针模型
fenzhen=viz.add('fenzhen.obj')	#加入分针模型
miaozhen=viz.add('miaozhen.obj')	#加入秒针模型

#调整时钟模型大小
biaopan.setScale([0.25,0.25,0.25])            #调整模型大小
shizhen.setScale([0.25,0.25,0.25])            #调整模型大小
fenzhen.setScale([0.25,0.25,0.25])            #调整模型大小
miaozhen.setScale([0.25,0.25,0.25])           #调整模型大小

#设置时钟初始位置
biaopan.setPosition(0,4,9.98)                   #表盘坐标位置
shizhen.setPosition(0,4,9.97)                   #时针坐标位置
fenzhen.setPosition(0,4,9.97)                   #分针坐标位置
miaozhen.setPosition(0,4,9.97)                  #秒针坐标位置

#设置时钟初始朝向
biaopan.setEuler(0,-90,0)                     #表盘初始朝向
shizhen.setEuler(-90,180,0)                   #时针初始朝向
fenzhen.setEuler(-90,180,0)                   #分针初始朝向
miaozhen.setEuler(-90,180,0)                  #秒针初始朝向

#【函数】时钟渲染
def Clock():
   t = datetime.datetime.now()                #获取系统时间(系统时间是实时变化的,必须将其值赋值给其他变量才可以处理)
   hour=t.hour                                #将系统的小时值赋值给hour
   minute=t.minute                            #将系统的分钟值赋值给minute
   second=t.second                            #将系统的秒数值赋值给second
   hour=hour%12                               #时钟一圈只有12小时,对于12:00~24:00的情况需要对hour进行模12除法的处理
   second_angle=second/60.0*360               #计算一秒钟秒针的旋转角度
   minute_angle=minute/60.0*360+second/60.0*6 #计算一秒钟分针的旋转角度
   hour_angle=hour/12.0*360+minute/60.0*30    #计算一秒钟时针的旋转角度
   miaozhen.setEuler(-90,270-second_angle,0)  #设置一秒钟后的秒针角度
   fenzhen.setEuler(-90,270-minute_angle,0)   #设置一秒钟后的分针角度
   shizhen.setEuler(-90,270-hour_angle,0)     #设置一秒钟后的时针角度
vizact.ontimer(1,Clock)                       #每隔一秒刷新一次,实现时钟功能

第五部分:小人讲话和鸽子

此处详情见帮助文档Tutorial: Adding Avatars

#小人讲话
def PersonTalk():
	female = viz.addAvatar('vcc_female.cfg', pos=(1,0,8), euler=(-90,0,0))
	male = viz.addAvatar('vcc_male2.cfg', pos=(0,0,8), euler=(90,0,0))
	female.state(14)
	male.state(4)
	
#鸽子走路	
pigeon = viz.addAvatar('pigeon.cfg',pos=(2,0,5))
random_walk = vizact.walkTo(pos=[vizact.randfloat(1.5,2.5),0,vizact.randfloat(4.5,5.5)])
random_animation = vizact.method.state(vizact.choice([1,3],vizact.RANDOM))
random_wait = vizact.waittime(vizact.randfloat(2.0,8.0))
pigeon_idle = vizact.sequence( random_walk, random_animation, random_wait, viz.FOREVER)
pigeon.runAction(pigeon_idle)

PersonTalk();

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值