Project 1 – Gauntlet

by Max Hawkins @ 2:42 am 12 January 2011

Schotter

LibCinder Implementation

#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 )
view raw schotter.cpp hosted with ❤ by GitHub

Processing/Processing.js Implementation

// 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();
}
}
}
view raw schotter.pde hosted with ❤ by GitHub

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 )

This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2023 Interactive Art & Computational Design / Spring 2011 | powered by WordPress with Barecity
AAAAAAAA