Hi, in my learning exercises with Ruby and OpenGL, I coded this Nav3D class to provide some basic 3D functionality to navigate in the 3D space “box”. If you are interested I can post the theory behind it. Improvements suggestion are welcome.
Regards
Marcio
The file with the Ruby class can be downloaded from:
http://pws.prserv.net/marcioab/nav3D.rb
Basic functionality:
d key = swap “on-the-fly” between Ortho and Perspective and vice-versa.
z,x keys = increase or decrease the perspective angle.
c,v keys = increase or decrease the deep of the “box”.
a key = show the box dimensions (just for curiosity).
Drag mouse around the screen with:
- Left-button down = Drag on X and Y.
- Right-button down = Rotation around X and Y, regard the center of the box.
- Right-button down and CTRL-key = Rotation around Z, regard the center of the box.
- Right-button down and Alt-key = Zoom
Optional:
- A small green point fixed in the center of the box.
- An inspection light that is always pointing from YOU to the center of the box.
To provide this functionality you need:
- include ( require ‘nav3D’ ) to call the file where is the Nav3D class.
- include a line to initiate the Nav3D class.
obs: remove any reference to glOrtho() or glFrustum() because the Nav3D class will handle that. - Replace your Reshape callback code to one that just call the Nav3D Reshape method.
- Include in your Keyboard callback code to call some Nav3D methods by keyboard.
5,6. Replace or Include the mouse callbacks (MouseFunc and MotionFunc) to allow mouse manipulations. - Include a RenderScene function (must be this name) with your render code.
More details to execute the changes:
-
require ‘nav3D_1’
-
myInit
$nav3D=Nav3D.new(4.0,5.0,0.0) # (Xm, Z, Tan) ( Tan = 0.0 = Orthogonal)
- Callback of glutReshapeFunc(Reshape)
Reshape = proc do |w, h|
$nav3D.ReShape(w,h)
end
- Callback of glutKeyboardFunc(keyboard)
keyboard = Proc.new do |key, x, y|
case (key)
when ?d # Swap Ortho to Perspective and vice-versa
$nav3D.TransformMode()
when ?z
$nav3D.TransformAlfa3(1.1)
when ?x
$nav3D.TransformAlfa3(1.0/1.1)
when ?c # Increase Z ( deep of the box)
$nav3D.TransformZ(1.1)
when ?v # Decrease Z (deep of the box)
$nav3D.TransformZ(1.0/1.1)
when ?a # key a - Show parameters
$nav3D.ShowParms()
end
end
- Callback of glutMouseFunc(mouse)
mouse = lambda do |button,state,x,y|
$nav3D.KeepPos(x,y,glutGetModifiers())
$button=button
end
- Callback of glutMotionFunc(motion)
motion = lambda do |x,y|
case($button)
when GLUT_RIGHT_BUTTON; $nav3D.Rotate(x,y)
when GLUT_LEFT_BUTTON; $nav3D.Move(x,y)
end
end
- def RenderScene()
your code here
end
Optional1: Box Central Green Point
- on RenderScene
$nav3D.PtCentral() # green point in the center of the box
Optional2: Inspection Light
- on myInit
$nav3D.SetInspectionLight(7,10.0) # (Light Number, distance) - on RenderScene
$nav3D.InspectionLight() # must be here to re-compute the “inspection” direction