Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@eamonnbell
Last active November 14, 2015 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eamonnbell/b6d327915c464b1eef64 to your computer and use it in GitHub Desktop.
Save eamonnbell/b6d327915c464b1eef64 to your computer and use it in GitHub Desktop.
VR experiments with Processing
import org.jsfml.audio.*;
import org.jsfml.window.event.*;
import org.jsfml.window.*;
import org.jsfml.system.*;
import org.jsfml.internal.*;
import org.jsfml.graphics.*;
import java.util.*;
import java.text.*;
import java.nio.file.*;
import peasy.*;
BlobComplex blob_complex;
PeasyCam cam;
VRListener vr_listener;
class Blob {
PVector location;
PVector velocity;
PVector target_location;
Date date;
int size;
String filename;
Music sound;
Blob(PVector location_, int size_, Date date_, String filename_) {
// Blobs represent sound sources and have location, size and velocity
location = location_;
target_location = location_;
size = size_;
date = date_;
velocity = new PVector(0, 0, 0);
filename = filename_;
// Create a new JSFML music object for each Blob
sound = new Music();
Path p = Paths.get(sketchPath(filename));
try {
sound.openFromFile(p);
}
catch (Exception e) {
println("Unable to open music file.");
println(e);
}
// Make sure the Music object takes absolution positions
sound.setRelativeToListener(false);
// MinDistance is the maximum distance at which a sound is heard at its maximum volume
sound.setMinDistance(250);
}
void play() {
// Wraps the play function of the sound
sound.play();
}
void update() {
// Increment location by velocity on every update
location.add(velocity);
// If Blob is in motion to a new target and gets close enough, set
// velocity to zero and snap to target_location
if (PVector.sub(target_location, location).mag() < 2) {
location = target_location;
velocity = new PVector(0, 0, 0);
}
PVector l = location.get();
l.add(new PVector(width/2, height/2, 0));
sound.setPosition(l.x, l.y, l.z);
}
void move_to(PVector target) {
target_location = target;
velocity = PVector.sub(target_location, location);
velocity.normalize();
velocity.mult(3);
}
void display() {
pushMatrix();
PVector l = location.get();
l.add(new PVector(width/2, height/2, 0));
translate(l.x, l.y, l.z);
sphere(size);
popMatrix();
}
}
class BlobComplex {
Table table = loadTable("data.csv", "header");
int blobcount = table.getRowCount();
Blob[] blobs = new Blob[blobcount];
BlobComplex() {
Table table = loadTable("data.csv", "header");
for (int i = 0; i < table.getRowCount (); i++) {
TableRow row = table.getRow(i);
PVector rand_loc = PVector.random3D();
rand_loc.mult(100);
Date blobDate = null;
SimpleDateFormat isoSDF = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
try {
blobDate = isoSDF.parse(row.getString("time"));
}
catch (Exception e) {
println("Unable to parse date stamp.");
}
blobs[i] = new Blob(rand_loc, row.getInt("size"), blobDate, row.getString("filename"));
}
}
void update() {
// Update every Blob in the BlobComplex
for (int i = 0; i < blobs.length; i++) {
blobs[i].update();
}
}
void display() {
// Update every Blob in the BlobComplex
for (int i = 0; i < blobs.length; i++) {
blobs[i].display();
}
}
}
class VRListener {
PVector location;
PVector direction;
VRListener(PVector location_, PVector direction_) {
// VRListener is just a thin wrap around the Listener object
// which allows us to render a representation of it.
location = location_;
direction = direction_;
// Listener represents the location and direction of the listener in 3D space
// It doesn't require instantiation and has only static methods.
Listener.setPosition(location.x, location.y, location.z);
Listener.setDirection(direction.x, direction.y, direction.z);
}
void display() {
pushMatrix();
// Draw a red sphere representing the location of the listener
PVector l = location.get();
l.add(new PVector(width/2, height/2, 0));
translate(l.x, l.y, l.z);
fill(200, 15, 15);
sphere(20);
fill(255);
// Draw a green line representing the orientation of the listener
strokeWeight(3);
stroke(0, 255, 0);
PVector d = direction.get();
d.mult(35);
line(0, 0, 0, d.x, d.y, d.z);
noStroke();
popMatrix();
}
void update() {
// Set the position and location of the listener to that of the VRListener
Listener.setPosition(location.x, location.y, location.z);
Listener.setDirection(direction.x, direction.y, direction.z);
}
}
void setup() {
size(640, 640, P3D);
// Create and setup
cam = new PeasyCam(this, width/2, height/2, 0, 100);
cam.setMinimumDistance(50);
cam.setMaximumDistance(500);
// Create blob complex
blob_complex = new BlobComplex();
// Create VR listener with (position, direction)
vr_listener = new VRListener(new PVector(0, 0, 0), new PVector(1, 0, 1));
}
void draw() {
background(0);
noStroke();
lights();
vr_listener.display();
vr_listener.update();
blob_complex.update();
blob_complex.display();
}
void keyPressed() {
// Move a random blob to a random location on the sphere of size 250
// and trigger associated sound.
PVector rand_loc = PVector.random3D();
rand_loc.mult(int(random(250)));
int index = int(random(blob_complex.blobcount));
blob_complex.blobs[index].move_to(rand_loc);
blob_complex.blobs[index].play();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment