Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Tuesday, 1 January 2013

Changes to PShape api processing-2.0b8

I'm kind of assuming the recent api changes in svn version of processing-2.0 are going to stick around to at least processing-2.0b8 (I can see some sort of logic in them at any rate). Here is my retained menger sketch that uses PShape updated in line with the api changes (note to set attributes such as ambient, and specular outside of begin/end shape you now need to use the set prefix as I have done below):-
The method signature is also different, either set_attribute(col) where col is an int or processing color or set_attribute(idx, col) where idx is an index int (which I have yet to explore).
##########################
# RetainedMenger.rb
# (processing-2.0)
# author Martin Prout
##########################

load_library 'arcball'
import "arcball"

PTS = [-1, 0, 1]
MIN_SIZE = 20
X = 0
Y = 1
Z = 2

attr_reader :arcball, :menger

def setup
  size(640, 480, P3D)
  smooth(8)
  camera
  camera(width/2.0, height/2.0, (height/2.0) / tan(PI*30.0 / 180.0), 0, 0, 0, 0, 1, 0)
  @arcball = ArcBall.new(0, 0, min(width - 20, height - 20) * 0.8)
  @menger = create_shape(GROUP)
  create_menger(0, 0, 0, height * 0.8)
end

def draw
  background(20, 20, 200)
  no_stroke
  lights
  update
  define_lights
  render
end

def render
  menger.set_ambient(50)
  menger.set_specular(30)
  shape(menger)
end

def create_menger(xx, yy, zz, sz)
  u = sz / 3.0
  if (sz < MIN_SIZE) # recursion limited by minimum cube size
    no_stroke
    menger.add_child(create_cube(xx, yy, zz, sz)) # create and add a cube  
  else
    PTS.each do |i|
      PTS.each do |j|
        PTS.each do |k|
          if ((abs(i) + abs(j) + abs(k)) > 1)
            create_menger(xx + (i * u), yy + (j * u), zz + (k * u), u)
          end
        end
      end
    end
  end
end

def create_cube(xx, yy, zz, sz)
  dim = sz / 2.0
  cube = create_shape
  cube.begin_shape(QUADS)
  # Front face
  cube.fill(255)
  cube.normal(0, 0, 1)
  cube.vertex(-dim + xx, -dim + yy, -dim + zz)
  cube.vertex(+dim + xx, -dim + yy, -dim + zz)
  cube.vertex(+dim + xx, +dim + yy, -dim + zz)
  cube.vertex(-dim + xx, +dim + yy, -dim + zz)

  # Back face

  cube.normal(0, 0, -1)
  cube.vertex(-dim + xx, -dim + yy, +dim + zz)
  cube.vertex(+dim + xx, -dim + yy, +dim + zz)
  cube.vertex(+dim + xx, +dim + yy, +dim + zz)
  cube.vertex(-dim + xx, +dim + yy, +dim + zz)

  # Left face

  cube.normal(1, 0, 0)
  cube.vertex(-dim + xx, -dim + yy, -dim + zz)
  cube.vertex(-dim + xx, -dim + yy, +dim + zz)
  cube.vertex(-dim + xx, +dim + yy, +dim + zz)
  cube.vertex(-dim + xx, +dim + yy, -dim + zz)

  # Right face

  cube.normal(-1, 0, 0)
  cube.vertex(+dim + xx, -dim + yy, -dim + zz)
  cube.vertex(+dim + xx, -dim + yy, +dim + zz)
  cube.vertex(+dim + xx, +dim + yy, +dim + zz)
  cube.vertex(+dim + xx, +dim + yy, -dim + zz)

  # Top face

  cube.normal(0, 1, 0)
  cube.vertex(-dim + xx, -dim + yy, -dim + zz)
  cube.vertex(+dim + xx, -dim + yy, -dim + zz)
  cube.vertex(+dim + xx, -dim + yy, +dim + zz)
  cube.vertex(-dim + xx, -dim + yy, +dim + zz)

  # Bottom face

  cube.normal(0, -1, 0)
  cube.vertex(-dim + xx, +dim + yy, -dim + zz)
  cube.vertex(+dim + xx, +dim + yy, -dim + zz)
  cube.vertex(+dim + xx, +dim + yy, +dim + zz)
  cube.vertex(-dim + xx, +dim + yy, +dim + zz)
  cube.end_shape
  return cube
end

def update
  theta, x, y, z = arcball.update
  rotate(theta, x, y, z)
end

def mouse_pressed
  arcball.mouse_pressed(mouse_x, mouse_y)
end

def mouse_dragged
  arcball.mouse_dragged(mouse_x, mouse_y)
end

def define_lights
  ambient(20, 20, 20)
  ambient_light(50, 50, 50)
  point_light(30, 30, 30, 200, -150, 0)
  directional_light(0, 30, 50, 1, 0, 0)
  spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, -0.5, PI / 2, 2)
end

def key_pressed
  case(key)
  when 'x'
    arcball.select_axis(X)
  when 'y'
    arcball.select_axis(Y)
  when 'z'
    arcball.select_axis(Z)
  end
end

def key_released
  arcball.select_axis(-1)
end

























  • Here is another api change was shape.texture(img)
  • now shape.set_texture(img)

# Planets, by Andres Colubri
#
# Sun and mercury textures from http://planetpixelemporium.com
# Star field picture from http://www.galacticimages.com/

attr_reader :starfield, :sun, :suntex, :planet1, :surftex1, :cloudtex, :planet2, :surftex2

def setup
  size(1024, 768, P3D)
  @starfield = load_image("starfield.jpg")
  @suntex = load_image("sun.jpg")
  @surftex1 = load_image("planet.jpg")
  @surftex2 = load_image("mercury.jpg")
  no_stroke
  fill(255)
  sphere_detail(40)
  @sun = create_shape(SPHERE, 150)
  @sun.set_texture(suntex)
  @planet1 = create_shape(SPHERE, 150)
  planet1.set_texture(surftex1)
  @planet2 = create_shape(SPHERE, 50)
  planet2.set_texture(surftex2)
end

def draw
  # Even we draw a full screen image after this, it is recommended to use
  # background to clear the screen anyways, otherwise A3D will think
  # you want to keep each drawn frame in the framebuffer, which results in 
  # slower rendering.
  background(0)
  # Disabling writing to the depth mask so the 
  # background image doesn't occludes any 3D object.
  hint(DISABLE_DEPTH_MASK)
  image(starfield, 0, 0, width, height)
  hint(ENABLE_DEPTH_MASK)
  push_matrix
  translate(width/2, height/2, -300)
  push_matrix
  rotate_y(PI * frame_count / 500)
  shape(sun)
  pop_matrix
  point_light(255,  255,  255,  0,  0,  0)
  rotate_y(PI * frame_count / 300)
  translate(0, 0, 300)
  shape(planet2)
  pop_matrix
  no_lights
  point_light(255,  255,  255,  0,  0,  -150)
  translate(0.75 * width,  0.6 * height,  50)
  shape(planet1)
end

Here is yet another api chage here need to use set_fill rather fill (further takes an int or processing color as input, there is an set_fill(index, color) variant I've yet too explore)
########################
# NB: Slow to get going 
# but, performs Ok after 
########################

BOX_SIZE = 20
MARGIN = BOX_SIZE * 2
DEPTH = 400
FINT = 3

attr_reader :box_fill, :grid, :fcount, :lastm, :frate

def setup
  size(640, 360, P3D)
  frame_rate(60)
  @fcount = 0
  @lastm = 0
  no_smooth
  no_stroke
  @grid = create_shape(GROUP)
  # Build grid using multiple translations 
  (-(DEPTH/2 + MARGIN) ... (DEPTH/2 - MARGIN)).step(BOX_SIZE) do |i|
    (-(height + MARGIN) ... (height - MARGIN)).step(BOX_SIZE) do |j|
      (-(width + MARGIN) ... (width - MARGIN)).step(BOX_SIZE) do |k|
        # Base fill color on counter values, abs function 
        # ensures values stay within legal range
        @box_fill = color(i.abs.to_i, j.abs.to_i, k.abs.to_i, 50)
        cube = create_shape(BOX, BOX_SIZE.to_f, BOX_SIZE.to_f, BOX_SIZE.to_f)
        cube.set_fill(box_fill)
        cube.translate(k, j, i)
        grid.add_child(cube)
      end
    end
  end
end

def draw
  background(255)
  hint(DISABLE_DEPTH_TEST)
  # Center and spin grid
  push_matrix()
  translate(width/2, height/2, -DEPTH)
  rotate_y(frame_count * 0.01)
  rotate_x(frame_count * 0.01)
  shape(grid)
  pop_matrix()
  hint(ENABLE_DEPTH_TEST)
  @fcount += 1
  m = millis()
  if (m - lastm > 1000 * FINT)
    @frate = fcount / FINT
    @fcount = 0
    @lastm = m
    puts("fps: #{frate}")
  end
  fill(0)
  text("fps: #{frate}", 10, 20)
end

No comments:

Post a Comment

Followers

About Me

My photo
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2