Class: Mittsu::PerspectiveCamera

Inherits:
Camera show all
Defined in:
lib/mittsu/cameras/perspective_camera.rb

Constant Summary

Constants inherited from Object3D

Object3D::DefaultUp

Instance Attribute Summary collapse

Attributes inherited from Camera

#matrix_world_inverse, #projection_matrix

Attributes inherited from Object3D

#active, #cast_shadow, #children, #frustum_culled, #geometry, #id, #initted, #matrix, #matrix_auto_update, #matrix_world, #matrix_world_needs_update, #model_view_matrix, #morph_target_influences, #name, #parent, #position, #quaternion, #receive_shadow, #render_order, #renderer, #rotation, #rotation_auto_update, #scale, #type, #up, #user_data, #uuid, #visible

Instance Method Summary collapse

Methods inherited from Camera

#get_world_direction, #look_at

Methods inherited from Object3D

#active?, #add, #add_opengl_object, #apply_matrix, #buffer_material, #deinit, #get_object_by_id, #get_object_by_name, #get_object_by_property, #get_world_direction, #get_world_position, #get_world_quaternion, #get_world_rotation, #get_world_scale, #init, #init_geometry, #load_uniforms_matrices, #local_to_world, #look_at, #print_tree, #project, #raycast, #remove, #rotate_on_axis, #rotate_x, #rotate_y, #rotate_z, #set_rotation_from_axis_angle, #set_rotation_from_euler, #set_rotation_from_matrix, #set_rotation_from_quaternion, #setup_matrices, #to_json, #to_s, #translate_on_axis, #translate_x, #translate_y, #translate_z, #traverse, #traverse_ancestors, #traverse_visible, #update_matrix, #update_matrix_world, #world_to_local

Methods included from EventDispatcher

#add_event_listener, #dispatch_event, #has_event_listener, #remove_event_listener

Constructor Details

#initialize(fov = 50.0, aspect = 1.0, near = 0.1, far = 2000.0) ⇒ PerspectiveCamera

Returns a new instance of PerspectiveCamera.



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/mittsu/cameras/perspective_camera.rb', line 5

def initialize(fov = 50.0, aspect = 1.0, near = 0.1, far = 2000.0)
  super()

  @type = 'PerspectiveCamera'

  @zoom = 1.0

  @fov = fov.to_f
  @aspect = aspect.to_f
  @near = near.to_f
  @far = far.to_f
  @full_width = nil

  update_projection_matrix
end

Instance Attribute Details

#aspectObject

Returns the value of attribute aspect.



3
4
5
# File 'lib/mittsu/cameras/perspective_camera.rb', line 3

def aspect
  @aspect
end

#farObject

Returns the value of attribute far.



3
4
5
# File 'lib/mittsu/cameras/perspective_camera.rb', line 3

def far
  @far
end

#fovObject

Returns the value of attribute fov.



3
4
5
# File 'lib/mittsu/cameras/perspective_camera.rb', line 3

def fov
  @fov
end

#nearObject

Returns the value of attribute near.



3
4
5
# File 'lib/mittsu/cameras/perspective_camera.rb', line 3

def near
  @near
end

#zoomObject

Returns the value of attribute zoom.



3
4
5
# File 'lib/mittsu/cameras/perspective_camera.rb', line 3

def zoom
  @zoom
end

Instance Method Details

#cloneObject



99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/mittsu/cameras/perspective_camera.rb', line 99

def clone
  camera = Mittsu::PerspectiveCamera.new
  super(camera)

  camera.zoom = zoom
  camera.fov = fov
  camera.aspect = aspect
  camera.near = near
  camera.far = far

  camera.projection_matrix.copy(projection_matrix)

  camera
end

#set_lens(focal_length, frame_height = 24.0) ⇒ Object

Uses Focal Length (in mm) to estimate and set FOV 35mm (fullframe) camera is used if frame size is not specified; Formula based on www.bobatkins.com/photography/technical/field_of_view.html



24
25
26
27
# File 'lib/mittsu/cameras/perspective_camera.rb', line 24

def set_lens(focal_length, frame_height = 24.0)
  @fov = 2.0 * Math.rad_to_deg(::Math.atan(frame_height / (focal_length * 2.0)))
  update_projection_matrix
end

#set_view_offset(full_width, full_height, x, y, width, height) ⇒ Object

Sets an offset in a larger frustum. This is useful for multi-window or multi-monitor/multi-machine setups.

For example, if you have 3x2 monitors and each monitor is 1920x1080 and the monitors are in grid like this

------ | A | B | C | ------ | D | E | F | ------

then for each monitor you would call it like this

var w = 1920; var h = 1080; var fullWidth = w * 3; var fullHeight = h * 2;

–A– camera.setOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); –B– camera.setOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); –C– camera.setOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); –D– camera.setOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); –E– camera.setOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); –F– camera.setOffset( fullWidth, fullHeight, w * 2, h * 1, w, h );

Note there is no reason monitors have to be the same size or in a grid.



63
64
65
66
67
68
69
70
71
72
# File 'lib/mittsu/cameras/perspective_camera.rb', line 63

def set_view_offset(full_width, full_height, x, y, width, height)
  @full_width = full_width
  @full_height = full_height
  @x = x
  @y = y
  @width = width
  @height = height

  update_projection_matrix
end

#update_projection_matrixObject



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/mittsu/cameras/perspective_camera.rb', line 74

def update_projection_matrix
  new_fov = Math.rad_to_deg(2.0 * ::Math.atan(::Math.tan(Math.deg_to_rad(@fov) * 0.5) / @zoom))

  if @full_width
    aspect = @full_width / @full_height
    top = ::Math.tan(Math.deg_to_rad(new_fov * 0.5)) * @near
    bottom = -top
    left = aspect * bottom
    right = aspect * top
    width = (right - left).abs
    height = (top - bottom).abs

    projection_matrix.make_frustum(
      left + @x * width / @full_width,
      left + (@x + @width) * width / @full_width,
      top - (@y + @height) * height / @full_height,
      top - @y * height / @full_height,
      @near,
      @far
    )
  else
    projection_matrix.make_perspective(new_fov, @aspect, @near, @far)
  end
end