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

Thursday 14 October 2010

Creating simple animations using the SunflowAPIAPI library and jruby

Here I explore the animation possibilities of the SunflowAPIAPI library (nothing on the scale of the one by amnon.owed).
It is very simple to use ruby syntax to create different views of a scene by changing the camera position, and use sunflow to render each image. Rather than modify each frame, I had the idea of using 20 incremental views, and crudely converting them to 200 frames by copying each view 10 times. I then used mencoder to stitch the frames together to produce a short movie. Here is the result:-

Changing the camera Sunflow Hair from monkstone on Vimeo.




# hair.rb NB: run this script directly with jruby

require 'library/sunflow_api/library/sunflow_api.jar'
require 'library/sunflow/library/sunflow.jar'
require 'library/sunflow/library/janino.jar'
require 'library/sunflow/library/commons-compiler.jar'

class BasicHair 

  API = Java::Com::briansteen::SunflowAPIAPI
  SMath = Java::Org::sunflow::math
  JColor = java.awt.Color  
  
  attr_reader :width, :height, :n_particles, :sunflow
        
  def initialize width = 640, height = 480, cam_x = 0
    @width = width
    @height = height
    @n_particles = 20
    # create a new API instance
    @sunflow = API.new
    # set width and height
                
    @sunflow.set_width(width)
    @sunflow.set_height(height)
    # set background color
    @sunflow.set_background(1, 1, 1)
    # set camera
    @sunflow.set_camera_position(cam_x, 7, 5)
    @sunflow.set_camera_target(2, 0.5, 0)
    @sunflow.set_thinlens_camera("thinLensCamera", 50, width/height)
    # set basic light
    @sunflow.set_point_light("myPointLight", SMath::Point3.new(0, 5, 5),
    JColor.new(255, 255, 255))
    @sunflow.set_directional_light("myDirectionalLight", SMath::Point3.new(-2, 3, 0),
    SMath::Vector3.new(0, 0, 0), 3, JColor.new(1, 1, 1))
    # @sunflow.setSphereLight("mySphereLight", SMath::Point3.new(0, 30, -5),
    # JColor.new(0, 0, 255), 32, 10)
    # draw a ground plane
    @sunflow.draw_plane("ground", SMath::Point3.new(0, 0, 0), SMath::Vector3.new(0, 1, 0))              
    # coordinates array
                
    @sunflow.draw_box("boxname", 0, 0, 0, 1)
  end
  
  def create_scene
    hair_widths = [0.025]
    # create particle coordinates
    350.times do |j|
      # particle start position
      particle_x = Math.cos(j * 0.5) * j * 0.0015
      particle_y = 0
      particle_z = Math.sin(j * 0.5) * j * 0.0015 
      
      hair_coordinates = Array.new(n_particles * 3)
      
      array_index = -1
      
      n_particles.times do |i|
        particle_x += 0.1 + Math.cos(i * 0.15 + j * 0.05) * 0.13
        particle_y -= Math.sin(particle_z * 0.01 + j * 0.05) * 0.125 +
        Math.cos(i * 0.5 + particle_y) * 0.125
        particle_z += Math.sin(i) * 0.25 + particle_y * 0.01                            
        hair_coordinates[array_index += 1] = particle_x
        hair_coordinates[array_index += 1] = particle_y
        hair_coordinates[array_index += 1] = particle_z
      end
                        
      # set ambient occlusion shader
      @sunflow.setAmbientOcclusionShader("myAmbientOcclusionShader#{j}", JColor.new(55, 55, 55),
      JColor.new(0, 0, 0), 16, 1)
      # set glass shader
      # @sunflow.setGlassShader("myGlassShader", JColor.new(1, 1, 1), 2.5, 3, JColor.new(1, 1, 1))
      # set shiny-diffuse shader
      # @sunflow.setShinyDiffuseShader("myShinyShader", JColor.new(55, 55, 55), 0.8)
                        
      # draw object
      @sunflow.draw_hair("hair#{j}", n_particles - 2, hair_coordinates.to_java(:float),
        hair_widths.to_java(:float))
    end
  end
  
  def render_scene filename = nil
    sunflow.setIrradianceCacheGIEngine(32, 0.4, 1, 15, nil)            
    # render
    sunflow.render() unless filename
    if filename
      begin # test for dodgy filename/path
        file = File.new(filename, "w")
        file.close
        sunflow.render(filename) # save as png image
      rescue
        puts "Warning #{filename} is not writable"
      end
    end
  end
          
end

20.times do |i|
  hair = BasicHair.new 640, 480, i                   # preferred render size for vimeo
  hair.create_scene
  hair.render_scene "/home/tux/ruby_sunflow/frame-#{i}.png" # default is to render in sunflow frame ie not to file
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