Doris

hierarchy.lua

This is an example of using the OpenGL matrix stack to render a linked hierarchy of objects. When the rotators are manipulated the boxes, and their children spin. All of the boxes can be moved arond using the translator as well.

Screenshot

hierarchy.lua screenshot

Source Code


-- Simple hierarchy example
-- $Id: hierarchy.lua,v 1.5 2002/06/24 07:06:31 trout Exp $

-- Create a hierarchy node. A table is passed containing information
-- about the position, size and children of the node.
function makeNode(t)
   t.pos = Matrix:new() -- positioning matrix
   local p = t.vpos
   t.pos:makeTranslate(p[1],p[2],p[3])
   t.rot = Matrix:new() -- rotation matrix
   return t
end

-- Create some nodes to draw and manipulate.
n4 = makeNode{vpos={0.5,0.5,0.5}, size=0.5}
n3 = makeNode{vpos={1,1,1}, kids={n4}, size=1}
n2 = makeNode{vpos={2,2,2}, kids={n3}, size=2}
n1 = makeNode{vpos={-2,-2,-2}, size=1}
n0 = makeNode{vpos={0,0,0}, kids={n1,n2}, size=4}

-- Put the nodes in a list for ease of use
nodes = {n0,n1,n2,n3,n4}

-- Render a given node and then its children
function RenderNode(n)
   glPushMatrix() -- jump into new frame
     glMultMatrix(n.pos) -- position ourselves
     glMultMatrix(n.rot) -- rotate ourselves
     --glutWireCube(n.size)
     glutSolidCube(n.size)
     for _,k in (n.kids or {}) do
       RenderNode(k)
     end
   glPopMatrix()
end

-- The scene render callback function.
function RenderScene()

   if not first then
     first = 1
     glEnable(GL_LIGHTING)
     glEnable(GL_LIGHT0)
     glLight(GL_LIGHT0, GL_POSITION, {10,10,10})
     glLight(GL_LIGHT0, GL_AMBIENT, {.3,.3,.3})
     glLight(GL_LIGHT0, GL_DIFFUSE, {.7,.2,0})
     glClearColor(.9,.9,.9,1.0)
   end
  
   glClear(GL_DEPTH_BUFFER_BIT + GL_COLOR_BUFFER_BIT)
   gluLookAt(0,0,15, 0,0,0, 0,1,0)
   glMatrixMode(GL_MODELVIEW)
   glLoadIdentity()
   RenderNode(n0) -- start rendering our nodes from the root
end

-- Create the main window
wmain = Window:create{
     title="Doris: Simple hierarchy example",
     render=RenderScene
}

-- Add a window at the bottom
sw=SubWindow{ parent=wmain, side="bottom" }

-- Create a rotator for each node which will rotate it
for i=1,getn(nodes) do
     local n = nodes[i]
     Rotator{ parent=sw, text="Rotate node "..i,
             value=n.rot, -- matrix to manipulate
             line="|", -- draw line seperator
             spin=.97 -- allow it to spin with a little damping
     }
end

-- Create translator for left and right movement (in xy)
Translator{ parent=sw, type="xy", text="Move cubes", space="v",
     update = function(p)
       local v = n0.vpos
       v[1],v[2] = p[1]*.1, p[2]*.1
       n0.pos:makeTranslate(v[1],v[2],v[3])
     end
}

-- Move back and forth (in z)
Translator{ parent=sw, type="z", line="v", text="Move cubes",
     update = function(p)
       local v = n0.vpos
       v[3] = p*.1
       n0.pos:makeTranslate(v[1],v[2],v[3])
     end
}


Back