<s> from math import sin , cos , pi , atan2 , asin <EOL> from . core import Scene <EOL> from . matrix import Matrix <EOL> from . util import normalize <EOL> from . import glfw <EOL> class WASD ( object ) : <EOL> def __init__ ( self , scene_or_window , <EOL> speed = <NUM_LIT:1.0> , sensitivity = <NUM_LIT> , invert = False , exclusive = True ) : <EOL> self . window = scene_or_window <EOL> if isinstance ( scene_or_window , Scene ) : <EOL> self . window = scene_or_window . window <EOL> self . speed = speed <EOL> self . sensitivity = sensitivity <EOL> self . invert = invert <EOL> self . exclusive = exclusive <EOL> self . x = <NUM_LIT:0> <EOL> self . y = <NUM_LIT:0> <EOL> self . z = <NUM_LIT:0> <EOL> self . rx = <NUM_LIT:0> <EOL> self . ry = <NUM_LIT:0> <EOL> self . mx = <NUM_LIT:0> <EOL> self . my = <NUM_LIT:0> <EOL> self . discard = True <EOL> if self . exclusive : <EOL> self . window . set_exclusive ( ) <EOL> scene_or_window . listeners . append ( self ) <EOL> @ property <EOL> def position ( self ) : <EOL> return ( self . x , self . y , self . z ) <EOL> def look_at ( self , position , target ) : <EOL> px , py , pz = position <EOL> tx , ty , tz = target <EOL> dx , dy , dz = normalize ( ( tx - px , ty - py , tz - pz ) ) <EOL> self . x = px <EOL> self . y = py <EOL> self . z = pz <EOL> self . rx = <NUM_LIT:2> * pi - ( atan2 ( dx , dz ) + pi ) <EOL> self . ry = asin ( dy ) <EOL> def enter ( self ) : <EOL> self . discard = True <EOL> def on_mouse_button ( self , button , action , mods ) : <EOL> if self . exclusive and not self . window . exclusive : <EOL> if button == glfw . MOUSE_BUTTON_1 and action == glfw . PRESS : <EOL> self . window . set_exclusive ( ) <EOL> self . discard = True <EOL> return True <EOL> def on_key ( self , key , scancode , action , mods ) : <EOL> if self . exclusive : <EOL> if key == glfw . KEY_ESCAPE : <EOL> self . window . set_exclusive ( False ) <EOL> def on_cursor_pos ( self , mx , my ) : <EOL> if self . exclusive and not self . window . exclusive : <EOL> return <EOL> if self . discard : <EOL> self . mx = mx <EOL> self . my = my <EOL> self . discard = False <EOL> return <EOL> m = self . sensitivity / <NUM_LIT> <EOL> self . rx += ( mx - self . mx ) * m <EOL> if self . invert : <EOL> self . ry += ( my - self . my ) * m <EOL> else : <EOL> self . ry -= ( my - self . my ) * m <EOL> if self . rx < <NUM_LIT:0> : <EOL> self . rx += <NUM_LIT:2> * pi <EOL> if self . rx >= <NUM_LIT:2> * pi : <EOL> self . rx -= <NUM_LIT:2> * pi <EOL> self . ry = max ( self . ry , - pi / <NUM_LIT:2> ) <EOL> self . ry = min ( self . ry , pi / <NUM_LIT:2> ) <EOL> self . mx = mx <EOL> self . my = my <EOL> def get_strafe ( self ) : <EOL> sx = sz = <NUM_LIT:0> <EOL> if glfw . get_key ( self . window . handle , ord ( '<STR_LIT>' ) ) : <EOL> sz -= <NUM_LIT:1> <EOL> if glfw . get_key ( self . window . handle , ord ( '<STR_LIT:S>' ) ) : <EOL> sz += <NUM_LIT:1> <EOL> if glfw . get_key ( self . window . handle , ord ( '<STR_LIT:A>' ) ) : <EOL> sx -= <NUM_LIT:1> <EOL> if glfw . get_key ( self . window . handle , ord ( '<STR_LIT:D>' ) ) : <EOL> sx += <NUM_LIT:1> <EOL> return ( sx , sz ) <EOL> def get_matrix ( self , matrix = None , translate = True ) : <EOL> matrix = matrix or Matrix ( ) <EOL> if translate : <EOL> matrix = matrix . translate ( ( - self . x , - self . y , - self . z ) ) <EOL> matrix = matrix . rotate ( ( cos ( self . rx ) , <NUM_LIT:0> , sin ( self . rx ) ) , self . ry ) <EOL> matrix = matrix . rotate ( ( <NUM_LIT:0> , <NUM_LIT:1> , <NUM_LIT:0> ) , - self . rx ) <EOL> return matrix <EOL> def get_sight_vector ( self ) : <EOL> m = cos ( self . ry ) <EOL> vx = cos ( self . rx - pi / <NUM_LIT:2> ) * m <EOL> vy = sin ( self . ry ) <EOL> vz = sin ( self . rx - pi / <NUM_LIT:2> ) * m <EOL> return ( vx , vy , vz ) <EOL> def get_motion_vector ( self ) : <EOL> sx , sz = self . get_strafe ( ) <EOL> if sx == <NUM_LIT:0> and sz == <NUM_LIT:0> : <EOL> return ( <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> strafe = atan2 ( sz , sx ) <EOL> m = cos ( self . ry ) <EOL> y = sin ( self . ry ) <EOL> if sx : <EOL> if not sz : <EOL> y = <NUM_LIT:0> <EOL> m = <NUM_LIT:1> <EOL> if sz > <NUM_LIT:0> : <EOL> y = - y <EOL> vx = cos ( self . rx + strafe ) * m <EOL> vy = y <EOL> vz = sin ( self . rx + strafe ) * m <EOL> return normalize ( ( vx , vy , vz ) ) <EOL> def update ( self , t , dt ) : <EOL> vx , vy , vz = self . get_motion_vector ( ) <EOL> self . x += vx * self . speed * dt <EOL> self . y += vy * self . speed * dt <EOL> self . z += vz * self . speed * dt </s>
