fredag 29 februari 2008

Context free art in ruby in 3d in opengl


Since I'm a fan of contextfreeart.org and nodebox.net, I've made a small ruby program inspired by contextfreeart, using context free grammars in 3d with opengl. The only operations right now are:

  • cube - create a cube.
  • up/down/left/right/to/from(rule) - define what rule to continue with in the specified direction.
  • flip - rotate 90 degress
  • scale - scale with 0.9.

But it should be quite easy to add new primitives (and clean up the code). Here is an example of a tree. Install ruby-opengl gem, click and move mouse to rotate, q - new random seed value, w - increase rendering depth, e - decrease rendering depth.

load 'cfa3d.rb'
class Tree < CFG
rule :start do |s|
s.cube
s.up :x
end

rule :x do |s|
s.cube
s.right :x
end
rule :x do |s|
s.cube
s.flip
s.left :x
end
rule :x, 0.1 do |s|
s.cube
s.flip
s.right :x
s.flip
s.left :x
end
rule :x do |s|
s.cube
s.scale
s.up :x
end
end

render Tree

A keyhandler for svg

This is an example of a keyhandler for controlling an application in svg. It consists of three files.

class.js. This is an implementation of classes in javascript, ripped out of prototype's html guts and modified.
keyhandler.js. A class that propagates key-events between javascript objects and their corresponding svg-elements. Currently it only changes the fill color of the focused element to green.
example.svg. The demo svg with some simple svg-elements that you can switch focus between with left/right/up/down. Press enter to get the currently selected item.

A javascript object that can get key focus has the following properties:

  • It has a variable named dom that refers to a svg-element.
  • It can have the functions onFocus and onLeaveFocus that are called when it gets or leaves focus.


The api of the keyhandler.

  • setFocus(x) - give focus to object x.
  • leaveFocus(x) - leave focus from x. this will also trigger leaveFocus on any children of x.
  • addKey(x, "a", f) - add key listener function f (which is called in the scope of x) for key 'a' when x (or children of x that hasn't overloaded 'a') have focus.
  • focusStrip([a, b, c], "left", "right") - specify that you can move focus between a, b, c by using the keys left and right.