Class: Cosmos::GlViewer

Inherits:
Qt::GLWidget
  • Object
show all
Defined in:
lib/cosmos/gui/opengl/gl_viewer.rb

Constant Summary collapse

MAX_PICKBUF =
1024
MAX_SELPATH =
64
EPS =
1.0e-2
PICK_TOL =
3
DTOR =
0.0174532925199432957692369077
RTOD =
57.295779513082320876798154814

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent) ⇒ GlViewer

Returns a new instance of GlViewer.



52
53
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
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 52

def initialize(parent)
  super(parent)

  @defaultCursor = nil
  @dragCursor = nil
  @projection = :PERSPECTIVE
  @zoom = 1.0
  @fov = 30.0
  @wvt = GlViewport.new
  @diameter = 2.0;
  @distance = 7.464116;
  @orientation = Quaternion.new([0.0, 0.0, 0.0, 1.0])
  @center = [0.0, 0.0, 0.0]
  @scale = [1.0, 1.0, 1.0]
  updateProjection()
  updateTransform()
  @maxhits = 512;
  @top_background = [0.5, 0.5, 1.0, 1.0]
  @bottom_background = [1.0, 1.0, 1.0, 1.0]
  @ambient = [0.2, 0.2, 0.2, 1.0]
  @light = GlLight.new
  @material = GlMaterial.new
  @dial = [0, 0, 0]
  @dropped = nil
  @selection = nil
  @scene = nil
  @mode = :HOVERING
  @draw_axis = nil
  @options = []

  @selection_callback = nil
end

Instance Attribute Details

#ambientObject (readonly)

Returns the value of attribute ambient.



41
42
43
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 41

def ambient
  @ambient
end

#bottom_backgroundObject (readonly)

Returns the value of attribute bottom_background.



40
41
42
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 40

def bottom_background
  @bottom_background
end

#centerObject

Returns the value of attribute center.



34
35
36
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 34

def center
  @center
end

#diameterObject (readonly)

Returns the value of attribute diameter.



31
32
33
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 31

def diameter
  @diameter
end

#distanceObject

Returns the value of attribute distance.



32
33
34
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 32

def distance
  @distance
end

#draw_axisObject

Returns the value of attribute draw_axis.



51
52
53
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 51

def draw_axis
  @draw_axis
end

#droppedObject (readonly)

Returns the value of attribute dropped.



44
45
46
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 44

def dropped
  @dropped
end

#fovObject

Returns the value of attribute fov.



29
30
31
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 29

def fov
  @fov
end

#itransformObject (readonly)

Returns the value of attribute itransform.



37
38
39
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 37

def itransform
  @itransform
end

#lightObject (readonly)

Returns the value of attribute light.



42
43
44
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 42

def light
  @light
end

#materialObject (readonly)

Returns the value of attribute material.



43
44
45
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 43

def material
  @material
end

#maxhitsObject (readonly)

Returns the value of attribute maxhits.



38
39
40
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 38

def maxhits
  @maxhits
end

#optionsObject (readonly)

Returns the value of attribute options.



48
49
50
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 48

def options
  @options
end

#orientationObject

Returns the value of attribute orientation.



33
34
35
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 33

def orientation
  @orientation
end

#projectionObject

:PARALLEL or :PERSPECTIVE



27
28
29
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 27

def projection
  @projection
end

#scaleObject

Returns the value of attribute scale.



35
36
37
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 35

def scale
  @scale
end

#sceneObject

Returns the value of attribute scene.



46
47
48
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 46

def scene
  @scene
end

#selectionObject

Returns the value of attribute selection.



45
46
47
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 45

def selection
  @selection
end

#selection_callbackObject

Returns the value of attribute selection_callback.



50
51
52
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 50

def selection_callback
  @selection_callback
end

#smodeObject (readonly)

Returns the value of attribute smode.



47
48
49
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 47

def smode
  @smode
end

#top_backgroundObject (readonly)

Returns the value of attribute top_background.



39
40
41
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 39

def top_background
  @top_background
end

#transformObject (readonly)

Returns the value of attribute transform.



36
37
38
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 36

def transform
  @transform
end

#wvtObject (readonly)

Returns the value of attribute wvt.



30
31
32
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 30

def wvt
  @wvt
end

#zoomObject

Returns the value of attribute zoom.



28
29
30
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 28

def zoom
  @zoom
end

Instance Method Details

#bounds=(bounds) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 159

def bounds= (bounds)
  # Model center
  @center = bounds.center

  # Model size
  @diameter = bounds.longest

  # Fix zero size model
  @diameter = 1.0 if @diameter < 1.0e-30

  # Set equal scaling initially
  @scale = [1.0, 1.0, 1.0]

  # Reset distance (and thus field of view)
  self.distance = 1.1 * @diameter
end

#calc_prime(v) ⇒ Object



523
524
525
526
527
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 523

def calc_prime(v)
  [v[0]*@itransform[0][0] + v[1]*@itransform[1][0] + v[2]*@itransform[2][0] + @itransform[3][0],
   v[0]*@itransform[0][1] + v[1]*@itransform[1][1] + v[2]*@itransform[2][1] + @itransform[3][1],
   v[0]*@itransform[0][2] + v[1]*@itransform[1][2] + v[2]*@itransform[2][2] + @itransform[3][2]]
end

#clear_solid_backgroundObject



408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 408

def clear_solid_background
  GL.ClearDepth(1.0)
  GL.ClearColor(@top_background[0], @top_background[1], @top_background[2], @top_background[3])
  if @top_background == @bottom_background
    begin
      GL.Clear(GL::COLOR_BUFFER_BIT | GL::DEPTH_BUFFER_BIT)
    rescue
      # Raises false error on Mac
    end
  else # Clear to gradient background
    begin
      GL.Clear(GL::DEPTH_BUFFER_BIT)
    rescue
      # Raises false error on Mac
    end
    GL.Disable(GL::DEPTH_TEST)
    GL.DepthMask(GL::FALSE)
    GL.Begin(GL::TRIANGLE_STRIP)
    GL.Color(@bottom_background); GL.Vertex3f(-1.0, -1.0, 0.0); GL.Vertex3f(1.0, -1.0, 0.0)
    GL.Color(@top_background); GL.Vertex3f(-1.0, 1.0, 0.0); GL.Vertex3f(1.0, 1.0, 0.0)
    begin
      GL.End
    rescue
      # Raises false error on Mac
    end
  end
end

#enable_light(light) ⇒ Object



469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 469

def enable_light(light)
  GL.Enable(GL::LIGHT0)
  GL.Light(GL::LIGHT0, GL::AMBIENT, light.ambient)
  GL.Light(GL::LIGHT0, GL::DIFFUSE, light.diffuse)
  GL.Light(GL::LIGHT0, GL::SPECULAR, light.specular)
  GL.Light(GL::LIGHT0, GL::POSITION, light.position)
  GL.Light(GL::LIGHT0, GL::SPOT_DIRECTION, light.direction)
  GL.Lightf(GL::LIGHT0, GL::SPOT_EXPONENT, light.exponent)
  GL.Lightf(GL::LIGHT0, GL::SPOT_CUTOFF, light.cutoff)
  GL.Lightf(GL::LIGHT0, GL::CONSTANT_ATTENUATION, light.c_attn)
  GL.Lightf(GL::LIGHT0, GL::LINEAR_ATTENUATION, light.l_attn)
  GL.Lightf(GL::LIGHT0, GL::QUADRATIC_ATTENUATION, light.q_attn)
end

#enable_material(material) ⇒ Object



483
484
485
486
487
488
489
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 483

def enable_material(material)
  GL.Material(GL::FRONT_AND_BACK, GL::AMBIENT, material.ambient)
  GL.Material(GL::FRONT_AND_BACK, GL::DIFFUSE, material.diffuse)
  GL.Material(GL::FRONT_AND_BACK, GL::SPECULAR, material.specular)
  GL.Material(GL::FRONT_AND_BACK, GL::EMISSION, material.emission)
  GL.Materialf(GL::FRONT_AND_BACK, GL::SHININESS, material.shininess)
end

#eyeToWorld(e) ⇒ Object



519
520
521
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 519

def eyeToWorld(e)
  calc_prime(e)
end

#initializeGLObject



273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 273

def initializeGL
  GL.GetError()

  # Initialize GL context
  GL.RenderMode(GL::RENDER)

  # Fast hints
  GL.Hint(GL::POLYGON_SMOOTH_HINT, GL::FASTEST)
  GL.Hint(GL::PERSPECTIVE_CORRECTION_HINT, GL::FASTEST)
  GL.Hint(GL::FOG_HINT, GL::FASTEST)
  GL.Hint(GL::LINE_SMOOTH_HINT, GL::FASTEST)
  GL.Hint(GL::POINT_SMOOTH_HINT, GL::FASTEST)

  # Z-buffer test on
  GL.Enable(GL::DEPTH_TEST)
  GL.DepthFunc(GL::LESS)
  GL.DepthRange(0.0, 1.0)
  GL.ClearDepth(1.0)
  GL.ClearColor(@top_background[0], @top_background[1], @top_background[2], @top_background[3])

  # No face culling
  GL.Disable(GL::CULL_FACE)
  GL.CullFace(GL::BACK)
  GL.FrontFace(GL::CCW)

  # Two sided lighting
  GL.LightModeli(GL::LIGHT_MODEL_TWO_SIDE, 1)
  GL.LightModel(GL::LIGHT_MODEL_AMBIENT, @ambient)

  # Preferred blend over background
  GL.BlendFunc(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA)

  enable_light(@light)
  # Viewer is close
  GL.LightModeli(GL::LIGHT_MODEL_LOCAL_VIEWER, 1)

  enable_material(@material)
  # Vertex colors change both diffuse and ambient
  GL.ColorMaterial(GL::FRONT_AND_BACK, GL::AMBIENT_AND_DIFFUSE)
  GL.Disable(GL::COLOR_MATERIAL)

  # Simplest and fastest drawing is default
  GL.ShadeModel(GL::FLAT)
  GL.Disable(GL::BLEND)
  GL.Disable(GL::LINE_SMOOTH)
  GL.Disable(GL::POINT_SMOOTH)
  GL.Disable(GL::COLOR_MATERIAL)

  # Lighting
  GL.Disable(GL::LIGHTING)

  # No normalization of normals (it's broken on some machines anyway)
  GL.Disable(GL::NORMALIZE)

  # Dithering if needed
  GL.Disable(GL::DITHER)
end

#minimumSizeHintObject



85
86
87
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 85

def minimumSizeHint
  return Qt::Size.new(100, 100)
end

#mode=(mode) ⇒ Object



569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 569

def mode=(mode)
  @mode = mode
  case @mode
  when :ZOOMING
    Qt::Application.setOverrideCursor(Cosmos.getCursor(Qt::SizeVerCursor))
  when :DRAGGING
    Qt::Application.setOverrideCursor(Cosmos.getCursor(Qt::ClosedHandCursor))
  when :ROTATING
    Qt::Application.setOverrideCursor(Cosmos.getCursor(Qt::CrossCursor))
  when :TRANSLATING
    Qt::Application.setOverrideCursor(Cosmos.getCursor(Qt::SizeAllCursor))
  else
    Qt::Application.restoreOverrideCursor
  end
end

#mouseMoveEvent(event) ⇒ Object



623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 623

def mouseMoveEvent(event)
  dx = event.x - @lastPos.x
  dy = event.y - @lastPos.y

  case @mode
  when :PICKING, :POSTING
    if dx.abs > 0 or dy.abs > 0
      if @mode == :PICKING
        self.mode = :ROTATING
      else
        self.mode = :TRANSLATING
      end
    end
  when :TRANSLATING
    vector = worldVector(@lastPos.x, @lastPos.y, event.x, event.y)
    translate([-vector[0], -vector[1], -vector[2]])
  when :DRAGGING
    if @selection and @selection.drag(self, @lastPos.x, @lastPos.y, event.x, event.y)
      updateGL()
    end
  when :ROTATING
    self.orientation = turn(@lastPos.x, @lastPos.y, event.x, event.y) * @orientation
  when :ZOOMING
    delta = 0.005 * dy
    self.zoom = @zoom * (2.0 ** delta)
  end

  @lastPos = event.pos
end

#mousePressEvent(event) ⇒ Object



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 585

def mousePressEvent(event)
  case event.button
  when Qt::LeftButton
    self.mode = :PICKING
    if (event.buttons & Qt::RightButton.to_i) != 0
      self.mode = :ZOOMING
    elsif (@selection and @selection.dragable and @selection == pick(event.x, event.y))
      self.mode = :DRAGGING
    end
  when Qt::RightButton
    if (event.buttons & Qt::LeftButton.to_i) != 0
      self.mode = :ZOOMING
    else
      self.mode = :POSTING
    end
  when Qt::MidButton
    self.mode = :ZOOMING
  end
  @lastPos = event.pos
end

#mouseReleaseEvent(event) ⇒ Object



606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 606

def mouseReleaseEvent(event)
  case @mode
  when :PICKING
    self.selection = pick(event.x, event.y)
  end

  if (((event.buttons & Qt::RightButton.to_i) != 0) and ((event.buttons & Qt::LeftButton.to_i) != 0)) or ((event.buttons & Qt::MidButton.to_i) != 0)
    self.mode = :ZOOMING
  elsif (event.buttons & Qt::LeftButton.to_i) != 0
    self.mode = :ROTATING
  elsif (event.buttons & Qt::RightButton.to_i) != 0
    self.mode = :TRANSLATING
  else
    self.mode = :HOVERING
  end
end

#paintGLObject



331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 331

def paintGL
  # Set viewport
  GL.Viewport(0, 0, @wvt.w, @wvt.h)
  reset_gl_state()
  clear_solid_background()

  # Depth test on by default
  GL.DepthMask(GL::TRUE)
  GL.Enable(GL::DEPTH_TEST)

  # Switch to projection matrix
  GL.MatrixMode(GL::PROJECTION)
  GL.LoadIdentity
  case @projection
  when :PARALLEL
    GL.Ortho(@wvt.left, @wvt.right, @wvt.bottom, @wvt.top, @wvt.hither, @wvt.yon)
  when :PERSPECTIVE
    GL.Frustum(@wvt.left, @wvt.right, @wvt.bottom, @wvt.top, @wvt.hither, @wvt.yon)
  end

  # Switch to model matrix
  GL.MatrixMode(GL::MODELVIEW)
  GL.LoadIdentity

  enable_light(@light)
  enable_material(@material)

  # Color commands change both
  GL.ColorMaterial(GL::FRONT_AND_BACK, GL::AMBIENT_AND_DIFFUSE)
  # Global ambient light
  GL.LightModel(GL::LIGHT_MODEL_AMBIENT, @ambient)

  # Enable fog
  if @options.include?(:VIEWER_FOG)
    GL.Enable(GL::FOG)
    GL.Fog(GL::FOG_COLOR, @top_background) # Disappear into the background
    GL.Fogf(GL::FOG_START, (@distance - @diameter).to_f) # Range tight around model position
    GL.Fogf(GL::FOG_END, (@distance + @diameter).to_f) # Far place same as clip plane:- clipped stuff is in the mist!
    GL.Fogi(GL::FOG_MODE, GL::LINEAR) # Simple linear depth cueing
  end

  # Dithering
  GL.Enable(GL::DITHER) if @options.include?(:VIEWER_DITHER)
  # Enable lighting
  GL.Enable(GL::LIGHTING) if @options.include?(:VIEWER_LIGHTING)

  # Set model matrix
  GL.LoadMatrixf(@transform)

  draw_axis() if (@draw_axis and @draw_axis > 0)

  # Draw what's visible
  @scene.draw(self) if @scene
end

#pick(x, y) ⇒ Object



264
265
266
267
268
269
270
271
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 264

def pick(x, y)
  obj = nil
  if @scene and @maxhits
    pickbuffer, nhits = selectHits(x-PICK_TOL, y-PICK_TOL, PICK_TOL*2, PICK_TOL*2)
    obj = processHits(pickbuffer, nhits) if nhits > 0
  end
  return obj;
end

#processHits(pickbuffer, nhits) ⇒ Object



242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 242

def processHits(pickbuffer, nhits)
  if nhits > 0
    zmin = 4294967295
    zmax = 4294967295
    i = 0
    while nhits > 0
      n = pickbuffer[i]
      d1 = pickbuffer[1+i]
      d2 = pickbuffer[2+i]
      if ((d1 < zmin) || ((d1 == zmin) && (d2<=zmax)))
        zmin = d1
        zmax = d2
        sel = i
      end
      i += n + 3
      nhits -= 1
    end
    return @scene.identify(pickbuffer[4 + sel])
  end
  return nil
end

#reset_gl_stateObject



386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 386

def reset_gl_state
  GL.ShadeModel(GL::SMOOTH)
  GL.PolygonMode(GL::FRONT_AND_BACK, GL::FILL)
  GL.Disable(GL::LIGHTING)
  GL.Disable(GL::ALPHA_TEST)
  GL.Disable(GL::BLEND)
  GL.Disable(GL::DITHER)
  GL.Disable(GL::FOG)
  GL.Disable(GL::LOGIC_OP)
  GL.Disable(GL::POLYGON_SMOOTH)
  GL.Disable(GL::POLYGON_STIPPLE)
  GL.Disable(GL::STENCIL_TEST)
  GL.Disable(GL::CULL_FACE)
  GL.Disable(GL::COLOR_MATERIAL)

  # Reset matrices
  GL.MatrixMode(GL::PROJECTION)
  GL.LoadIdentity
  GL.MatrixMode(GL::MODELVIEW)
  GL.LoadIdentity
end

#resizeGL(width, height) ⇒ Object



491
492
493
494
495
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 491

def resizeGL(width, height)
  @wvt.w = width;
  @wvt.h = height;
  updateProjection()
end

#screenToEye(sx, sy, eyez) ⇒ Object



497
498
499
500
501
502
503
504
505
506
507
508
509
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 497

def screenToEye(sx, sy, eyez)
  e = [0.0, 0.0, 0.0]
  xp = (@worldpx*sx + @ax).to_f
  yp = (@ay - @worldpx*sy).to_f
  if @projection == :PERSPECTIVE
    if @distance != 0.0
      e.x = [((-eyez*xp) / @distance).to_f, ((-eyez*yp) / @distance).to_f, eyez]
    end
  else
    e = [xp, yp, eyez]
  end
  return e;
end

#screenToTarget(sx, sy) ⇒ Object



511
512
513
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 511

def screenToTarget(sx, sy)
  [@worldpx*sx.to_f + @ax, @ay - @worldpx*sy.to_f, -@distance.to_f]
end

#selectHits(x, y, w, h) ⇒ Object



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 198

def selectHits(x, y, w, h)
  mh = @maxhits
  nhits = 0
  makeCurrent()

  # Where to pick
  pickx = (@wvt.w - 2.0*x - w) / w.to_f
  picky = (2.0*y + h - @wvt.h) / h.to_f
  pickw = @wvt.w / w.to_f
  pickh = @wvt.h / h.to_f

  # Set pick projection matrix
  GL.MatrixMode(GL::PROJECTION);
  GL.LoadIdentity()
  GL.Translatef(pickx, picky, 0.0)
  GL.Scalef(pickw, pickh, 1.0)
  case projection
  when :PARALLEL
    GL.Ortho(@wvt.left, @wvt.right, @wvt.bottom, @wvt.top, @wvt.hither, @wvt.yon)
  when :PERSPECTIVE
    GL.Frustum(@wvt.left, @wvt.right, @wvt.bottom, @wvt.top, @wvt.hither, @wvt.yon)
  end

  # Model matrix
  GL.MatrixMode(GL::MODELVIEW);
  GL.LoadMatrixf(@transform)

  # Loop until room enough to fit
  while true
    nhits = 0
    buffer = GL.SelectBuffer(mh)
    GL.RenderMode(GL::SELECT);
    GL.InitNames()
    GL.PushName(0)
    @scene.hit(self) if @scene
    GL.PopName()
    nhits = GL.RenderMode(GL::RENDER)
    mh <<= 1
    break if nhits >= 0
  end
  doneCurrent()
  return buffer.unpack("L*"), nhits
end

#sizeHintObject



89
90
91
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 89

def sizeHint
  return Qt::Size.new(400, 400)
end

#spherePoint(x, y) ⇒ Object



535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 535

def spherePoint(x, y)
  if @wvt.w > @wvt.h
    screenmin = wvt.h.to_f
  else
    screenmin = wvt.w.to_f
  end
  v = []
  v[0] = 2.0 * (x - 0.5*@wvt.w) / screenmin
  v[1] = 2.0 * (0.5 * @wvt.h - y) / screenmin
  d = v[0]*v[0] + v[1]*v[1]

  if d < 0.75
    v[2] = sqrt(1.0-d)
  elsif d < 3.0
    d = 1.7320508008 - sqrt(d)
    t = 1.0 - d*d
    t = 0.0 if t < 0.0
    v[2] = 1.0 - sqrt(t)
  else
    v[2] = 0.0
  end

  length = sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2])
  if length > 0.0
    return [v[0] / length, v[1] / length, v[2] / length]
  else
    return [0.0, 0.0, 0.0]
  end
end

#translate(vector) ⇒ Object



190
191
192
193
194
195
196
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 190

def translate(vector)
  @center[0] += vector[0]
  @center[1] += vector[1]
  @center[2] += vector[2]
  updateTransform()
  updateGL()
end

#turn(fx, fy, tx, ty) ⇒ Object



565
566
567
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 565

def turn(fx, fy, tx, ty)
  return Quaternion.arc(spherePoint(fx,fy), spherePoint(tx,ty))
end

#wheelEvent(event) ⇒ Object



653
654
655
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 653

def wheelEvent(event)
  self.zoom = @zoom * (2.0 ** (-0.1 * event.delta / 120.0))
end

#worldToEyeZ(w) ⇒ Object



515
516
517
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 515

def worldToEyeZ(w)
  w[0]*@transform[0][2] + w[1]*@transform[1][2] + w[2]*@transform[2][2] + @transform[3][2]
end

#worldVector(fx, fy, tx, ty) ⇒ Object



529
530
531
532
533
# File 'lib/cosmos/gui/opengl/gl_viewer.rb', line 529

def worldVector(fx, fy, tx, ty)
  wfm_prime = calc_prime(screenToTarget(fx, fy))
  wto_prime = calc_prime(screenToTarget(tx, ty))
  return [wto_prime[0] - wfm_prime[0], wto_prime[1] - wfm_prime[1], wto_prime[2] - wfm_prime[2]]
end