Probably the most convenient way to explore glsl shader sketches from ruby is to use NetBeans with jruby-plugin, jruby_art gem (and optionally c/c++ plugin). Made possible by Andrés Colubri processing opengl work, tutorial here:-
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Showing posts with label glsl. Show all posts
Showing posts with label glsl. Show all posts
Monday, 6 October 2014
Wednesday, 11 September 2013
Gravitational Attraction (3D) Planetarium Sketch (avoiding reflection with some alternative logic)
Yet another example using Andrés Colubri's planetarium library, hardest to convert so far.
Andrés Colubri is concerned that in his sketch some logic would be called too often in the draw loop, this is why he uses the pre and post (methods, only available using reflection, but only recognised if they are part of a java class, this is Catch 22 territory for ruby-processing). I think I've come up with a decent solution (certainly seems to run OK) that avoids reflection, which can only be good thing. In this case I have placed a "guard" in the pre and post methods (ruby methods to be clear). Can't get border to work "too complicated", I reckon I have mad sketch more efficient by replacing PVector with a custom vector (starts at 8 fps, but quickly moves to 60 fps).
The sketch:-
The solar system library
The sketch:-
# # Gravitational Attraction (3D) # by Daniel Shiffman. # # Adapted for dome projection by Andres Colubri # # Simulating gravitational attraction # G ---> universal gravitational constant # m1 --> mass of object #1 # m2 --> mass of object #2 # d ---> distance between objects # F = (G*m1*m2)/(d*d) # # For the basics of working with PVector, see # http://processing.org/learning/pvector/ # as well as examples in Topics/Vectors/ # # load_libraries :planetarium, :solar_system include_package 'codeanticode.planetarium' PLANETS = 10 attr_reader :angle, :planets, :sun, :count, :do_rotate java_alias :background_int, :background, [Java::int] # precast for efficiency def setup size(800, 800, Dome::RENDERER) @angle = 0 # Some random planets @planets = [] @count = 10 # warm up time @do_rotate = false (0 ... PLANETS).each do planets << Planet.new(rand(0.1 .. 2), rand(-width/2 .. width/2), rand(-height/2 .. height/2), rand(-100 .. 100)) end # A single sun @sun = Sun.new end def pre if count == frame_count # only enter once per frame planets.each do |planet| # Sun attracts Planets force = sun.attract(planet) planet.apply_force(force) # Update and draw Planets planet.update end @count = frame_count + 1 frame.set_title("Solar System FPS: #{frame_rate.to_i}") @do_rotate = true end end def draw pre background_int 0 # Setup the scene lights translate(width/2, height/2, 300) rotate_y(angle) # Display the Sun sun.display # All the Planets planets.each do |planet| planet.display end post end # Called after rendering all the faces, but before the dome sphere, # so it can be used to draw stuff on the corners of the screen. #def border # perspective # camera # background(255) # fill(0) # text("FPS: #{frame_rate}", 20, 20) #end def post # Rotate around the scene if do_rotate @angle += 0.003 @do_rotate = false end end
The solar system library
# Gravitational Attraction (3D) # Daniel Shiffman <http://www.shiffman.net> # A class for an attractive body in our world class Sun include Processing::Proxy G = 0.4 # Universal gravitational constant (arbitrary value) attr_reader :sphere, :location, :mass def initialize @location = Vect.new(0,0) @mass = 20 @sphere = create_shape(SPHERE, mass * 2, 20) sphere.set_fill(false) sphere.set_stroke(color(255)) end def constrain val, lo, hi # override processing overloaded method result = (val > hi)? hi : (val < lo)? lo : val end def attract(m) force = Vect.sub(location,m.location) # Calculate direction of force d = constrain(force.mag, 5.0, 25.0) # Limiting the distance to eliminate "extreme" results for very close or very far objects strength = (G * mass * m.mass) / (d * d) # Calculate gravitional force magnitude force.set_mag(strength) # Get force vector --> magnitude * direction return force end # Draw Sun def display push_matrix translate(location.x,location.y,location.z) shape(sphere) pop_matrix end end # Gravitational Attraction (3D) # Daniel Shiffman <http://www.shiffman.net> # A class for an orbiting Planet class Planet include Processing::Proxy # Basic physics model (location, velocity, acceleration, mass) attr_reader :location, :velocity, :acceleration, :mass, :sphere def initialize(m, x, y, z) @mass = m @location = Vect.new(x,y,z) @velocity = Vect.new(1,0) # Arbitrary starting velocity @acceleration = Vect.new(0,0) @sphere = create_shape(SPHERE, mass * 8, 20) sphere.set_stroke(false) sphere.set_fill(color(255)) end # Newton's 2nd Law (F = M*A) applied def apply_force(force) f = Vect.div(force,mass) acceleration.add(f) end # Our motion algorithm (aka Euler Integration) def update velocity.add(acceleration) # Velocity changes according to acceleration location.add(velocity) # Location changes according to velocity acceleration.zero end # Draw the Planet def display push_matrix translate(location.x,location.y,location.z) shape(sphere) pop_matrix end end class Vect attr_reader :x, :y, :z def initialize(x, y, z = 0) @x, @y, @z = x, y, z end def normalize @x, @y, @z = x / mag, y / mag, z / mag if (mag != 0 && mag != 1) end def mult a @x, @y, @z = x * a, y * a, z * a end def self.sub(v0, v1) Vect.new(v0.x - v1.x, v0.y - v1.y, v0.z - v1.z) end def add(v) @x, @y, @z = x + v.x, y + v.y, z + v.z end def self.div(v, a) Vect.new(v.x / a, v.y / a, v.z / a) end def mag Math.sqrt(x*x + y*y + z*z) end def set_mag m normalize @x, @y, @z = x * m, y * m, z * m end def zero @x, @y, @z = 0, 0, 0 end end
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

