[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Камера от третьего лица
soosДата: Четверг, 10.11.2011, 22:40 | Сообщение # 1
Майор
Группа: Пользователи
Сообщений: 82
Награды: 1
Репутация: 0
Статус: Offline
Модуль tp_camera.py с классом реализующим управление:
Code
from direct.showbase.DirectObject import DirectObject
from panda3d.core import CompassEffect

class TPCameraDriver(DirectObject):
  def __init__(self, target, near = 5., far = 2000., dist = 30., step = 20., heading = -30., pitch = -45., ms = 0.3, slowness = 30., linear = False):
   self.target = target
   self.near = near
   self.far = far
   self.dist = dist
   self.step = step
   self.heading = heading
   self.pitch = pitch
   self.mouse_sensitivity = ms
   self.slowness = slowness
   self.linear = linear
   self.dragging = False

   base.disableMouse()
   self.accept('wheel_up', self.wheel_up)
   self.accept('wheel_down', self.wheel_down)
   self.accept('mouse3', self.start_drag)
   self.accept('mouse3-up', self.stop_drag)
   taskMgr.add(self.update, 'camera.update')
    
   self.parent = render.attachNewNode('parent')  
   self.parent.reparentTo(self.target)
   self.parent.setEffect(CompassEffect.make(render))
   base.camera.reparentTo(self.parent)  
   base.camera.lookAt(self.parent)
   base.camera.setY(-self.dist)

  def wheel_up(self):
   if self.linear:
    self.dist = self.dist - self.step
   else:
    self.dist = self.dist / 2
   if self.dist < self.near:
    self.dist = self.near
    
  def wheel_down(self):
   if self.linear:
    self.dist = self.dist + self.step
   else:
    self.dist = self.dist * 2
   if self.dist > self.far:
    self.dist = self.far

  def start_drag(self):
   self.dragging = True
   md = base.win.getPointer(0)
   self.mx = md.getX()
   self.my = md.getY()

  def stop_drag(self):
   md = base.win.getPointer(0)
   mx = (self.mx - md.getX())*self.mouse_sensitivity
   my = (self.my - md.getY())*self.mouse_sensitivity
   self.heading = self.heading + mx
   self.pitch = self.pitch + my
   self.dragging = False

  def update(self, task):
   if self.dragging:
    md = base.win.getPointer(0)
    mx = (self.mx - md.getX())*self.mouse_sensitivity
    my = (self.my - md.getY())*self.mouse_sensitivity
    self.parent.setHpr(self.heading + mx, self.pitch + my, 0)
   else:
    self.parent.setHpr(self.heading, self.pitch, 0)
   camdist = base.camera.getDistance(self.target)
   delta = self.dist - camdist
   delta = delta / self.slowness
   curdist = camdist + delta
   base.camera.setY(-curdist)

   return task.cont

Колесо мыши - приближение/отдаление.
Правая клавиша мыши - поворот вокруг цели.
Параметры:
near - ближняя граница
far - дальняя граница
dist - начальная дистанция до цели
step - шаг приближения/отдаления (учитывается только если linear == True)
heading - начальный угол по Х
pitch - начальный угол по У
ms - чувствительность мыши
slowness - медлительность камеры при приближении/отдалении
linear - линейное/параболическое приближение/отдаление
TODO: Можно ещё добавить ограничение по Pitch, чтобы камера не опускалась ниже уровня земли.
Пример использования:
Code
from pandac.PandaModules import *
from direct.task import Task
from direct.actor import Actor
from direct.interval.IntervalGlobal import *
from tp_camera import TPCameraDriver
import direct.directbase.DirectStart

environ = loader.loadModel("models/environment")
environ.reparentTo(render)
environ.setScale(0.25,0.25,0.25)
environ.setPos(-8,42,0)

pivot = render.attachNewNode('pivot')

pandaActor = Actor.Actor("models/panda-model",{"walk":"models/panda-walk4"})
pandaActor.reparentTo(pivot)
pandaActor.setScale(0.01,0.01,0.01)
pandaActor.loop("walk")

pandaPosInterval1 = pivot.posInterval(13, Point3(0,-10,0), startPos=Point3(0,10,0))
pandaPosInterval2 = pivot.posInterval(13, Point3(0,10,0), startPos=Point3(0,-10,0))
pandaHprInterval1 = pivot.hprInterval(3, Point3(180,0,0), startHpr=Point3(0,0,0))
pandaHprInterval2 = pivot.hprInterval(3, Point3(0,0,0), startHpr=Point3(180,0,0))

pandaPace = Sequence(pandaPosInterval1, pandaHprInterval1, pandaPosInterval2, pandaHprInterval2, name = "pandaPace")
pandaPace.loop()

camdriver = TPCameraDriver(pivot)

run()
 
  • Страница 1 из 1
  • 1
Поиск: