Class: Quake::Renderer::GLViewmodel

Inherits:
Object
  • Object
show all
Defined in:
lib/quake/renderer/gl_viewmodel.rb

Overview

Renders the first-person weapon view model. Uses the same projection as the world camera. Depth range is compressed to [0, 0.3] so the weapon always draws in front of world geometry without z-fighting (matches GLQuake's R_DrawViewModel).

Constant Summary collapse

CL_BOB =

Quake bob cvars (from view.c)

0.02
CL_BOBCYCLE =

cl_bob: amplitude multiplier

0.6
CL_BOBUP =

cl_bobcycle: seconds per full bob cycle

0.5
VIEWMODEL_Z_FUDGE =

cl_bobup: fraction of cycle spent going up

2.0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(pak, palette) ⇒ GLViewmodel

Returns a new instance of GLViewmodel.



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/quake/renderer/gl_viewmodel.rb', line 22

def initialize(pak, palette)
  @pak = pak
  @palette = palette
  @weapon_renderers = {} # model_path -> GLAliasModel
  @time = 0.0
  @bob_speed = 0.0
  @bob = 0.0
  @current_model_path = nil
  @animation_frames = []
  @animation_time = 0.0
end

Instance Attribute Details

#bobObject (readonly)

Current bob value (applied to camera Z by the game loop)



20
21
22
# File 'lib/quake/renderer/gl_viewmodel.rb', line 20

def bob
  @bob
end

Instance Method Details

#play_attack(frames) ⇒ Object



49
50
51
52
# File 'lib/quake/renderer/gl_viewmodel.rb', line 49

def play_attack(frames)
  @animation_frames = frames.to_a
  @animation_time = 0.0
end

#render(camera, aspect, visible: true, ambient_light: 200.0, shade_light: 200.0) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/quake/renderer/gl_viewmodel.rb', line 54

def render(camera, aspect, visible: true, ambient_light: 200.0, shade_light: 200.0)
  return unless visible
  return unless @current_model_path

  gl_model = @weapon_renderers[@current_model_path]
  return unless gl_model

  # Compress depth range so weapon always appears in front of world
  GL.DepthRange(0.0, 0.3)
  # Weapon origin = view origin + forward*bob*0.4 plus the default
  # scr_viewsize 100 fudge from Quake's V_CalcRefdef. The camera
  # position already carries the vertical bob, and in C the gun's
  # own +bob cancels against the camera's, so none is added here.
  # The fudge is applied along the view's up axis (not world Z as in
  # the C source): a world-Z offset swings the gun down/away as the
  # view pitches, while the reference's gun stays glued to the view.
  pos = camera.position +
        camera.forward * (@bob * 0.4) +
        camera.up * VIEWMODEL_Z_FUDGE

  GL.Enable(GL::TEXTURE_2D)

  gl_model.render(
    frame_index: current_frame,
    lerp: 0.0,
    position: pos,
    # CalcGunAngle sets viewent pitch to -viewpitch and
    # R_RotateForEntity negates it again, so the gun's world rotation
    # is +viewpitch -- it pitches with the view.
    yaw: camera.yaw,
    pitch: camera.pitch,
    roll: camera.roll,
    ambient_light: ambient_light,
    shade_light: shade_light,
    view_model: true
  )

  GL.DepthRange(0.0, 1.0)
end

#set_weapon(model_path) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/quake/renderer/gl_viewmodel.rb', line 34

def set_weapon(model_path)
  return if model_path == @current_model_path
  @current_model_path = model_path
  @animation_frames = []
  @animation_time = 0.0
  load_weapon(model_path) unless @weapon_renderers.key?(model_path)
end

#update(dt, speed) ⇒ Object



42
43
44
45
46
47
# File 'lib/quake/renderer/gl_viewmodel.rb', line 42

def update(dt, speed)
  @time += dt
  @bob_speed = speed
  @bob = calc_bob
  @animation_time += dt if @animation_frames.any?
end