From: Phlip Date: 2001-12-03T02:00:17+09:00 Subject: [ruby-talk:27283] Is there a geometer in the house? (OpenGL Translate vs POVray Translate) Jean-Marc van Leerdam wrote: > Keep in mind that the OpenGL origin 'moves with the translations' > whereas the POV origin is fixed. Therein lies the rub. Compare: // POVray cylinder {<0,0,0>,<0,59.0625,0>, 3.32227 pigment{col_2} finish {ambient 0.3 diffuse 0.7 phong 1} rotate < 0, 0, -32.8296> rotate < 0, -99.4838, 0> translate < 0, 175, 0>} //OpenGL GL::Rotate(@whyRotation, 0, 0, 1) GL::Rotate(@zeeRotation, 0, 1, 0) GL::Translate ( @exxTranslation, @whyTranslation, 0 # @zeeTranslation, ) GLU::Cylinder(quad, @radius, @radius, @height, SLICES_NUMBER, STACKS_NUMBER) The POVray script builds the object at the origin, then rolls it around Z, then rolls it around Y, then moves it out to its final location. The OpenGL code creates a matrix that rolls around Y (formerly Z), rolls around Z (formerly Y), then translates. (Swapping Y and Z is a pain, but it works on Cylinders with several other rotations and translations besides this one. So regardless of how OpenGL rotates after a translation, we are using POVray in an OpenGL-compatible way, by rotating first and then translating. Below my sig is source closer to the actual problem. I took the Translate call out and let glshapes.rb handle it internally. The V is now on top of the I, with only a small break between them. -- Phlip #!/usr/bin/env ruby require 'fox' require 'opengl' require 'fox/glshapes' include Fox class GLViewWindow < FXMainWindow ID_GLVIEWER = enum(FXMainWindow::ID_LAST, 1)[0] def initialize(app) super(app, "Bad Thing Test", nil, nil, DECOR_ALL, 0, 0, 800, 600) @mdiclient = FXMDIClient.new(self, LAYOUT_FILL_X|LAYOUT_FILL_Y) mdichild = FXMDIChild.new(@mdiclient, "FOX GL Viewer", @mdiicon, nil, MDI_MAXIMIZED, 30, 30, 300, 200) @glvisual = FXGLVisual.new(getApp(), VISUAL_DOUBLEBUFFER) @mdiclient.setActiveChild(mdichild) viewer = FXGLViewer.new(mdichild, @glvisual, self, ID_GLVIEWER, LAYOUT_FILL_X|LAYOUT_FILL_Y|LAYOUT_TOP|LAYOUT_LEFT) @scene = FXGLGroup.new gp2 = FXGLGroup.new @scene.append(gp2) addCylinder gp2, 59.0625, 3.322265625, 2, -32.82964323, -99.48376736, [0.0, 0.0, 175.0], [-5.319876145, 30.17051687, 222.1752194] addCylinder gp2, 44.296875, 1.868774414, 2, -65.65928646, -99.48376736, [-5.319876145, 30.17051687, 222.1752194], [-12.01231147, 68.12520364, 239.3344216] addCylinder gp2, 44.296875, 1.868774414, 2, -32.82964323, -99.48376736, [-5.319876145, 30.17051687, 222.1752194], [-9.309783254, 52.79840451, 257.556634] viewer.setScene(@scene) end def addCylinder gp, length,thickness,pigment,zeeRotation,whyRotation, xyzTranslation, xyzEnd exxTranslation, whyTranslation, zeeTranslation = xyzTranslation cyl = Cylinder.new ( exxTranslation, whyTranslation, zeeTranslation, length, thickness ) cyl.zeeRotation = zeeRotation cyl.whyRotation = whyRotation gp.append(cyl) end def create super show(PLACEMENT_SCREEN) end end def run application = FXApp.new("GLViewer", "FoxTest") application.disableThreads application.init(ARGV) GLViewWindow.new(application) application.create application.run end class Cylinder < FXGLCylinder def initialize(*args) super(*args) @zeeRotation = 0 @whyRotation = 0 end attr_writer :zeeRotation, :whyRotation def drawshape(viewer) quad = GLU::NewQuadric() GLU::QuadricDrawStyle(quad, GLU::FILL) GL::PushMatrix() GL::Rotate(@whyRotation, 0, 0, 1) GL::Rotate(@zeeRotation, 0, 1, 0) GLU::Cylinder(quad, @radius, @radius, @height, SLICES_NUMBER, STACKS_NUMBER) GLU::QuadricOrientation(quad, GLU::INSIDE) GLU::Disk(quad, 0, @radius, SLICES_NUMBER, LOOPS) GLU::QuadricOrientation(quad, GLU::OUTSIDE) GLU::Disk(quad, 0, @radius, SLICES_NUMBER, LOOPS) GL::PopMatrix() GLU::DeleteQuadric(quad) end end run