Project 1 – Gauntlet
Schotter
LibCinder Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "cinder/app/AppBasic.h" | |
#include "cinder/gl/gl.h" | |
#include "cinder/Rand.h" | |
using namespace ci; | |
using namespace ci::app; | |
using namespace std; | |
const Vec3f DrawingOffset = Vec3f(50, 50, 0); | |
const Vec2f DrawingDimensions = Vec2f(12, 23); | |
const Vec3f CubeSize = Vec3f(25, 25, 0); | |
const float MaxOffsetJitter = 1; | |
const float MaxRotationJitter = 10; | |
class SchotterApp : public AppBasic { | |
public: | |
void prepareSettings( Settings *settings ); | |
void draw(); | |
void mouseDown( MouseEvent event ); | |
private: | |
int m_seed; | |
}; | |
void SchotterApp::mouseDown( MouseEvent event ) | |
{ | |
m_seed++; | |
} | |
void SchotterApp::prepareSettings( Settings *settings ) | |
{ | |
settings->setWindowSize(DrawingOffset.x * 2 + (DrawingDimensions.x - 1) * CubeSize.x, DrawingOffset.y * 2 + (DrawingDimensions.y - 1) * CubeSize.y); | |
settings->setTitle("Faux Schotter"); | |
settings->setResizable(false); | |
} | |
void SchotterApp::draw() | |
{ | |
Rand::randSeed(m_seed); | |
gl::clear( Color::white() ); | |
gl::color( Color::black() ); | |
for (int x = 0; x < DrawingDimensions.x; x++) { | |
for (int y = 0; y < DrawingDimensions.y; y++) { | |
gl::pushMatrices(); | |
int cubeNumber = y * CubeSize.y + x; | |
float jitterFactor = (float) cubeNumber / (DrawingDimensions.x + DrawingDimensions.y); | |
Vec3f center(x * CubeSize.x, y * CubeSize.y, 0 * CubeSize.z); | |
center += DrawingOffset; | |
Vec3f offsetJitter = Rand::randVec3f() * jitterFactor * MaxOffsetJitter; | |
offsetJitter.z = 0; | |
center += offsetJitter; | |
gl::translate(center); | |
float rotationJitter = (Rand::randFloat() - 0.5) * jitterFactor * MaxRotationJitter ; | |
gl::rotate(rotationJitter); | |
gl::drawStrokedCube( Vec3f::zero(), CubeSize ); | |
gl::popMatrices(); | |
} | |
} | |
} | |
CINDER_APP_BASIC( SchotterApp, RendererGl ) |
Processing/Processing.js Implementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Support Classes | |
class Vec3f { | |
float x, y, z; | |
Vec3f(float x, float y, float z) { | |
this.x = x; | |
this.y = y; | |
this.z = z; | |
} | |
void scale(float scale) { | |
this.x *= scale; | |
this.y *= scale; | |
this.z *= scale; | |
} | |
void offset(Vec3f offset) { | |
this.x += offset.x; | |
this.y += offset.y; | |
this.z += offset.z; | |
} | |
} | |
class Vec2f { | |
float x, y; | |
public Vec2f(float x, float y) { | |
this.x = x; | |
this.y = y; | |
} | |
} | |
// Constants | |
Vec3f DrawingOffset = new Vec3f(50, 50, 0); | |
Vec2f DrawingDimensions = new Vec2f(12, 23); | |
Vec3f CubeSize = new Vec3f(25, 25, 0); | |
float MaxOffsetJitter = 1; | |
float MaxRotationJitter = 10; | |
int rand_seed; | |
void setup() { | |
size((int) (DrawingOffset.x * 2 + DrawingDimensions.x * CubeSize.x), (int) (DrawingOffset.y * 2 + DrawingDimensions.y * CubeSize.y)); | |
smooth(); | |
noFill(); | |
} | |
void mouseClicked() { | |
rand_seed++; | |
} | |
void draw() { | |
randomSeed(rand_seed); | |
background(255); | |
color(0); | |
for (int x = 0; x < DrawingDimensions.x; x++) { | |
for (int y = 0; y < DrawingDimensions.y; y++) { | |
pushMatrix(); | |
int cubeNumber = (int) (y * CubeSize.y + x); | |
float jitterFactor = (float) cubeNumber / (DrawingDimensions.x + DrawingDimensions.y); | |
Vec3f center = new Vec3f(x * CubeSize.x, y * CubeSize.y, 0 * CubeSize.z); | |
center.offset(DrawingOffset); | |
Vec3f offsetJitter = new Vec3f(random(1), random(1), random(1)); | |
offsetJitter.scale(jitterFactor * MaxOffsetJitter); | |
offsetJitter.z = 0; | |
center.offset(offsetJitter); | |
translate(center.x, center.y); | |
float rotationJitter = (random(1) - 0.5) * jitterFactor * MaxRotationJitter; | |
rotate(radians(rotationJitter)); | |
rect(0, 0, CubeSize.x, CubeSize.y); | |
popMatrix(); | |
} | |
} | |
} |
Text Rain
#include "cinder/app/AppBasic.h" #include "cinder/gl/gl.h" #include "cinder/Text.h" #include "cinder/gl/GlslProg.h" #include "cinder/gl/Texture.h" #include "cinder/Rand.h" #include "cinder/Capture.h" #include "Kinect.h" using namespace ci; using namespace ci::app; using namespace std; /*************************** Messy, but -probably- works ****************************/ class Letter { public: static std::map<char, gl::Texture> textureForCharacter; static std::map<char, float> baselineOffsetForCharacter; static float fontSize; static bool texturesGenerated; Vec2f mPosition; Vec2f mVelocity; Vec2f mAcceleration; char mLetter; Letter(char letter, Vec2f position) { mAcceleration = Vec2f(0, 0.01); mPosition = position; mVelocity = Vec2f(0, 0); mLetter = letter; if (!texturesGenerated) { for(char character = 'A'; character < 'Z'; character++) { float baselineOffset = 0; std::string str(1, character); textureForCharacter[character] = gl::Texture( renderString( str, Font("Arial", fontSize), Color::white(), &baselineOffset ) ); baselineOffsetForCharacter[character] = baselineOffset; } texturesGenerated = true; } } void update() { mVelocity += mAcceleration; mPosition += mVelocity; } void draw() { float brightness = 1 - (mPosition.y / getWindowHeight()); gl::color(Color(1, brightness, brightness )); gl::draw( textureForCharacter[mLetter], mPosition - Vec2f( 0, baselineOffsetForCharacter[mLetter] ) ); } Area frame() { return Area(mPosition + Vec2f(0, baselineOffsetForCharacter[mLetter]), textureForCharacter[mLetter].getSize()); } void detectCollisions(const Surface8u &background) { const Area clippedFrame( frame().getClipBy( background.getBounds() ) ); if (clippedFrame.getWidth() <= 0 || clippedFrame.getHeight() <= 0) return; float sum = 0; // probably bad. hm. uint8_t inc = background.getPixelInc(); const uint8_t *line = background.getData( clippedFrame.getUL() ); for( int32_t y = clippedFrame.y1; y < clippedFrame.y2; ++y ) { const uint8_t *pixel = line; for( int32_t x = clippedFrame.x1; x < clippedFrame.x2; ++x ) { if(*pixel > 150) { sum++; } pixel += inc; } line += background.getRowBytes(); } if (sum > 10 && mVelocity.y > 0) { mVelocity.y = 0; } if(sum > 20) { mVelocity.y -= sum * 0.0004; } // mVelocity -= percent * 5; } }; bool Letter::texturesGenerated = false; std::map<char, float> Letter::baselineOffsetForCharacter; std::map<char, gl::Texture> Letter::textureForCharacter; float Letter::fontSize = 18; class TextRainApp : public AppBasic { public: void setup(); void mouseDown( MouseEvent event ); void update(); void draw(); private: std::vector<Letter> letters; void emitRandomLetter(); float mLastEmitTime; float mEmitInterval; float lastEmitLocation; int lastEmitCharacterIndex; Kinect mKinect; gl::Texture mColorTexture, mDepthTexture; Surface8u mDepthSurface; }; void TextRainApp::setup() { setFrameRate(30); mEmitInterval = 1; mLastEmitTime = -mEmitInterval; lastEmitCharacterIndex = 0; lastEmitLocation = 0; mKinect = Kinect( Kinect::Device() ); // the default Device implies the first Kinect connected gl::enableAdditiveBlending(); } void TextRainApp::mouseDown( MouseEvent event ) { } void TextRainApp::emitRandomLetter() { // char character = (char) Rand::randInt(97, 122); string poem = ("A ONE THAT IS NOT COLD IS SCARECLY A ONE AT ALL"); lastEmitCharacterIndex += Rand::randInt(poem.length()); char character = poem[lastEmitCharacterIndex % poem.length()]; if(character == ' ') return; float horizontalEmitLocation = ((float)(lastEmitCharacterIndex % poem.length()) / poem.length()) * getWindowWidth(); Vec2f startPosition = Vec2f(horizontalEmitLocation, -18); lastEmitLocation = horizontalEmitLocation; Letter letter(character, startPosition); letters.push_back(letter); } void TextRainApp::update() { if ((getElapsedSeconds() - mLastEmitTime) > mEmitInterval) { emitRandomLetter(); mLastEmitTime = getElapsedSeconds(); } if( mKinect.checkNewDepthFrame() ) { mDepthTexture = mKinect.getDepthImage(); mDepthSurface = Surface8u( mKinect.getDepthImage() ); } if( mKinect.checkNewColorFrame() ) mColorTexture = mKinect.getColorImage(); } void TextRainApp::draw() { // clear out the window with black gl::clear( Color( 0, 0, 0 ) ); gl::color(Color::white()); if (mColorTexture) { gl::draw(mColorTexture); } for (vector<Letter>::iterator iter = letters.begin(); iter != letters.end();) { iter->update(); iter->draw(); if (mDepthSurface) { iter->detectCollisions(mDepthSurface); } if (iter->mPosition.y > getWindowHeight() || iter->mPosition.y < -1000) { iter = letters.erase(iter); } else { iter = ++iter; } } } CINDER_APP_BASIC( TextRainApp, RendererGl ) |
Comments Off on Project 1 – Gauntlet