You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
78 lines
2.6 KiB
78 lines
2.6 KiB
from panda3d.core import Vec3, NodePath
|
|
|
|
|
|
class SmoothCamera():
|
|
def __init__(self, player, city):
|
|
self.player, self.city = player, city
|
|
self.root = render.attach_new_node('camera')
|
|
self.camera = base.camera
|
|
self.camera.reparent_to(self.root)
|
|
self.target = NodePath('nothing')
|
|
self.speed = NodePath('camera speed')
|
|
self.aim = NodePath('camera aim')
|
|
self.focus_on_player()
|
|
|
|
base.accept('z', self.switch_focus)
|
|
|
|
# Skysphere stuff (should probably go elsewhere but meh)
|
|
sky = base.loader.load_model('assets/bam/skysphere.bam')
|
|
sky.reparent_to(base.camera)
|
|
sky.set_compass(render)
|
|
sky.set_scale(10)
|
|
sky.set_bin('background', 1)
|
|
sky.set_depth_write(0)
|
|
sky.set_light_off()
|
|
sky.set_fog_off()
|
|
sky.set_color_scale_off()
|
|
base.task_mgr.add(self.update)
|
|
|
|
def set_target(self, new_hook, offset=(2,0,2), distance=16):
|
|
self.target.detach_node()
|
|
self.target = new_hook.attach_new_node('camera target')
|
|
self.target.set_pos(offset)
|
|
self.max_distance = distance
|
|
|
|
def focus_on_city(self):
|
|
self.focus = 'city'
|
|
self.city.in_focus = True
|
|
self.city.active = True
|
|
self.player.in_focus = False
|
|
self.set_target(self.city.root, (3,0,3), 22)
|
|
self.root.set_pos(self.city.root, (22,-22,22))
|
|
self.look_target = self.city.root
|
|
|
|
def focus_on_player(self):
|
|
self.focus = 'player'
|
|
self.player.in_focus = True
|
|
self.city.in_focus = False
|
|
self.city.active = False
|
|
self.set_target(self.player.hook, (2,0,4), 8)
|
|
self.root.set_pos(self.player.hook, (2,-8,4))
|
|
self.look_target = self.player.hook
|
|
|
|
def switch_focus(self):
|
|
if self.focus == 'player':
|
|
self.focus_on_city()
|
|
else:
|
|
self.focus_on_player()
|
|
|
|
def update(self, task):
|
|
dt = globalClock.get_dt()
|
|
|
|
if self.focus == 'player':
|
|
if self.player.is_on_ground():
|
|
self.target.set_pos((2,0,0.5))
|
|
else:
|
|
self.target.set_pos((2,0,4))
|
|
|
|
distance = self.root.get_distance(self.target)
|
|
if distance > self.max_distance:
|
|
self.aim.set_pos(self.root.get_pos(render))
|
|
self.aim.look_at(self.target)
|
|
self.speed.set_hpr(self.aim.get_hpr(render))
|
|
self.speed.set_y(self.speed, dt*distance)
|
|
self.root.set_pos(self.root, self.speed.get_pos(render))
|
|
self.speed.clear_transform()
|
|
self.camera.look_at(self.look_target, (0,2,0))
|
|
|
|
return task.cont
|
|
|