It occurred to me that all I was getting from using ruby-processing in my previous post was the ruby processing interface to the libraries. So here is the straightforward jruby version....
Screen output very much as before (smaller) hence not included there. For your convenience I present an embedded gist (click on view raw to copy).
See previous post for how to setup java libraries.
Example translated from java version (by Christopher Warnow?) included in the subversion checkout of the sunflowAPIAPI.
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Thursday, 30 September 2010
Basic Hair Example SunflowAPIAPI just using jruby
Labels:
jruby,
sunflowAPIAPI
Basic Hair Example SunflowAPIAPI in ruby processing
See previous post for how to setup java libraries.
# basic_hair.rb run with 'rp5 run script.rb'
class BasicHair < Processing::App
load_libraries :sunflow_api, :sunflow
include_package 'com.briansteen'
include_package 'org.sunflow.math'
include_package 'java.awt'
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
JColor = java.awt.Color
WIDTH = 640
HEIGHT = 480
P_AMOUNT = 20
def setup
# 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(0, 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
hair_widths = [0.025]
@sunflow.draw_box("boxname", 0, 0, 0, 1)
# 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(P_AMOUNT*3)
array_index = -1
P_AMOUNT.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.drawHair("hair#{j}", P_AMOUNT - 2, hair_coordinates.to_java(:float),
hair_widths.to_java(:float))
end
@sunflow.setIrradianceCacheGIEngine(32, 0.4, 1, 15, nil)
# render
@sunflow.render() # display in sunflow window
# @sunflow.render("BasicHair.png") # save as png image
end
def draw
exit
end
end
# basic_hair.rb run with 'rp5 run script.rb'
class BasicHair < Processing::App
load_libraries :sunflow_api, :sunflow
include_package 'com.briansteen'
include_package 'org.sunflow.math'
include_package 'java.awt'
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
JColor = java.awt.Color
WIDTH = 640
HEIGHT = 480
P_AMOUNT = 20
def setup
# 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(0, 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
hair_widths = [0.025]
@sunflow.draw_box("boxname", 0, 0, 0, 1)
# 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(P_AMOUNT*3)
array_index = -1
P_AMOUNT.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.drawHair("hair#{j}", P_AMOUNT - 2, hair_coordinates.to_java(:float),
hair_widths.to_java(:float))
end
@sunflow.setIrradianceCacheGIEngine(32, 0.4, 1, 15, nil)
# render
@sunflow.render() # display in sunflow window
# @sunflow.render("BasicHair.png") # save as png image
end
def draw
exit
end
end
Labels:
ruby processing,
sunflowAPIAPI
SunflowAPIAPI in ruby processing
# sunflow_test.rb
class SunflowTest < Processing::App
load_libraries :sunflow_api, :sunflow
include_package 'com.briansteen'
include_package "org.sunflow.math"
API = Java::Com::briansteen::SunflowAPIAPI
SMath = Java::Org::sunflow::math
WIDTH = 500
HEIGHT = 500
def setup
@sunflow = API.new
@sunflow.set_width(WIDTH)
@sunflow.set_height(HEIGHT)
@sunflow.set_camera_position(0, 2.5, -5)
@sunflow.set_camera_target(0, 0, 0)
@sunflow.set_thinlens_camera("thinLensCamera", 50, WIDTH/HEIGHT)
@sunflow.draw_plane("ground", SMath::Point3.new(0,-3.5,0), SMath::Vector3.new(0, 1, 0))
@sunflow.draw_sphere_flake("mySphereFlake", 20, SMath::Vector3.new(0, 1, 0), 1)
@sunflow.setPathTracingGIEngine 6
@sunflow.render "SunflowTestRender.png"
end
def draw
exit
end
end
SunflowTest.new :title => "Sunflow Test"
This example was copied from amnon, following his recent posting on the processing discussion boards.
Checkout the sunflowapapi source (created by Christopher Warnow?) as follows:-
svn checkout http://sunflowapiapi.googlecode.com/svn/trunk/ sunflowapiapi-read-only
Get the sunflow libraries here, NB must be version 0.07.3:-
http://sunflow.sourceforge.net
Or possible here for Windows users:-
http://www.polyquark.com/opensource
The usual library setup required compile and jar the sunflowapiapi code into sunflow_api.jar nest that as follows in a folder library, in a folder sunflow_api in the library folder (in the directory where the sketch you want to run is stored). Do similar for the sunflow.jar put the janino.jar in the same folder. The janino.jar provides a fast java compiler, version is 2.~ is supplied with the sunflow download, however with a few minor modifications sunflow can be updated to use the latest version 2.6.1 (basically include the commons-compiler.jar, and remove a couple of deprecated exception types from the code and update the CompileException to the commons compiler version org.codehaus.commons.compiler.CompileException, do this in an ide unless you are crazy).
Labels:
ruby processing,
sunflow,
sunflowAPIAPI
Sunday, 26 September 2010
A Staffordshire Knot Using Ruby Processing and A Context Free Library
A Staffordshire Knot, ruby-processing 3D context-free DSL from monkstone on Vimeo.
Using a slight variation of the previous post we get something similar to the Staffordshire Knot.
segment :rz => i, :ry => Math.sin(i*Math::PI/180)*0.2, :x => Math.sin(i*Math::PI/180)*1.5
Is the main change, although to produce the video, I was saving frames and set the size to 640*480 to match vimeo preferences. Was very jumpy when I saved frames as #####.png ...
I have since uploaded an improved version, this time using the default save_frame (hence tif format). Mencoder doesn't like this format so I batch converted the tif files to png as so:-
mogrify -format png -transparent blue *.tif
See my processing blog for the video recording details.
Saturday, 25 September 2010
An Infinity Loop? With My 3D Context Free Library
# infinity.rb
# An 'infinity loop?'
load_libraries :test_free
full_screen
attr_reader :xrot, :yrot, :zrot, :wheel, :col
def setup_the_spiral
@spiral = ContextFree.define do
rule :infinity do
360.times do |i|
split do
segment :rz => i, :ry => Math.sin(i*Math::PI/180)*0.2, :x => Math.cos(i*Math::PI/180)*3
rewind
end
end
end
rule :segment do
cube :alpha => 0.8
end
rule :segment do
cube :brightness => 1.0, :saturation => 1.0
end
end
end
def setup
render_mode P3D
@wheel = JWheelListener.new(-50, -20) # initialize listener with start_z and maximum values
self.add_mouse_wheel_listener(wheel) # register the mouse listener
smooth
@xrot = 0.01
@yrot = 0
@zrot = 0
@col = 0
setup_the_spiral
end
def draw
background 0
setup_lights col
specular col, 1, 1
emissive 0.05
shininess 10
smooth_rotation(3, 3.2)
smooth_color(6.0)
@spiral.render :infinity, :start_x => 0, :start_y => 0, :start_z => wheel.zoom, :size => height/350,
:stop_size => 0.2, :color => [0, 0.7, 0.7, 0.5], :rx => xrot, :ry => yrot, :rz => zrot
end
##
# Generate a gradient value that changes smoothly over time in the range [ 0, 1 ].
# The Math.sin() function is used to map the current time in milliseconds somewhere
# in the range [ 0, 1 ]. A 'speed' factor is specified by the parameters s1.
#
def smooth_gradient(s1)
mills = millis * 0.00003
gradient = 0.5 * Math.sin(mills * s1) + 0.5
end
##
# Rotate the current coordinate system.
# Uses smooth_gradient() to smoothly animate the rotation.
#
def smooth_rotation(s1, s2)
@yrot = 2.0 * Math::PI * smooth_gradient(s1)
@zrot = 2.0 * Math::PI * smooth_gradient(s2)
end
##
# Generate a 'hue' value which smoothly changes over time.
# The speed of change is controlled by the parameter s1.
#
def smooth_color(s1)
@col = smooth_gradient(s1)
end
def setup_lights(col)
directional_light(col, 0.8, 0.8, -0.5, 0.5, -1)
point_light(col, 0.8, 0.8, -0.5, 0.5, -1)
ambient_light(col, 0.8, 0.8, 1, 1, 1)
end
Labels:
3D context free DSL,
infinity,
loop,
ruby processing
Monday, 13 September 2010
Revised 3D Context Free DSL Sketch, with Mouse Wheel Zoom Utility
I demonstrate the new feature of mouse wheel zoom in this sketch. The logic for the smooth of color and rotation I copied from lazydogs classy rotating ball. PS: if you can't see the embedded code below chances are you are not using either Firefox or Google Chrome browser (doesn't always work for me with Opera, which I also find is awkward to use when copying code).
default.rb from monkstone on Vimeo.
Labels:
context free,
mouse wheel listener,
ruby processing
Sunday, 12 September 2010
A Mouse Wheel Listener in Ruby Processing
For my 3D context free application/library, I would like to be able to zoom using the mouse wheel, I had vaguely thought about using peasycam or proscene to provide that, and other functionality. In the first instance I wanted to create it myself. After a bit of research, this the sort of implementation I would do using the java classes/interfaces in ruby:-
# mouse_listener.rb
class JWheelListener
include java.awt.event.MouseWheelListener
attr_reader :zoom
def initialize(zoom)
@zoom = zoom
end
def mouse_wheel_moved(e)
@zoom += e.get_wheel_rotation * 10
end
end
class Mouse < Processing::App
attr_reader :wheel
def setup
size(1000, 1000)
@wheel = JWheelListener.new(10)
self.add_mouse_wheel_listener(@wheel)
end
def draw
background 0
fill 255, 0, 0
ellipse(width/2, height/2, wheel.zoom, wheel.zoom)
end
end
Mouse.new :title => "Mouse Wheel Listener"
# mouse_listener.rb
class JWheelListener
include java.awt.event.MouseWheelListener
attr_reader :zoom
def initialize(zoom)
@zoom = zoom
end
def mouse_wheel_moved(e)
@zoom += e.get_wheel_rotation * 10
end
end
class Mouse < Processing::App
attr_reader :wheel
def setup
size(1000, 1000)
@wheel = JWheelListener.new(10)
self.add_mouse_wheel_listener(@wheel)
end
def draw
background 0
fill 255, 0, 0
ellipse(width/2, height/2, wheel.zoom, wheel.zoom)
end
end
Mouse.new :title => "Mouse Wheel Listener"
Labels:
mouse_wheel_listener,
ruby processing,
zoom
Subscribe to:
Posts (Atom)
Followers
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2






