Tonic::Generator CloudsVisualSystemMemory::buildSynth()
{
    string strDir = GetCloudsDataPath(true) + "sound/textures/";
    ofDirectory sdir(strDir);
    string strAbsPath = ofToDataPath(strDir + "/CPUBeepsFastDrone_.aif", true);

    Tonic::SampleTable sample = Tonic::loadAudioFile(strAbsPath);
    
    Tonic::Generator sampleGen = Tonic::BufferPlayer().setBuffer(sample).trigger(1).loop(1);
    
    return sampleGen * 5;
}
string CloudsClip::getSubtitlesPath() {
	//for Higa-san, return english subtitles
	if(getLanguage() == "JAPANESE" && GetLanguage() == "JAPANESE"){
		return GetCloudsDataPath() + "language/ENGLISH/subtitles/" + getSubtitlesFilename();
	}
	return GetCloudsDataPath() + "language/" + GetLanguage() + "/subtitles/" + getSubtitlesFilename();
}
예제 #3
0
//--------------------------------------------------------------
void testApp::setup(){
    
	ofSetEscapeQuitsApp(false);
#if defined(TARGET_WIN32) && !defined(OCULUS_RIFT)
	ofSetFrameRate(60);
#endif
	ofSetVerticalSync(true);
	ofBackground(0);
    
#if defined(OCULUS_RIFT) && defined(TARGET_WIN32)
//    ofSetWindowPosition(0,0);
//    ofSetWindowShape(1920*2,1080);
#else
	#ifdef CLOUDS_RELEASE
//    ofSetWindowPosition(1920 + 1920*.5,1080*.5);
//    ofSetWindowPosition(0,0);
	#endif
//    ofSetWindowShape(1920,1080);
#endif

    
#ifdef OCULUS_RIFT
    ofToggleFullscreen();
#else
    ofSetWindowShape(1280, 720);
    ofSetWindowPosition(ofGetScreenWidth()/2 - 1280/2, ofGetScreenHeight()/2 - 720/2);

#endif
    
#ifdef CLOUDS_RELEASE
	ofHideCursor();
    
    // Log to file instead of console.
    // Note that this only works with ofLog(...), not cout.
    if (!ofDirectory::doesDirectoryExist(GetCloudsDataPath(true) + "fml")) {
        ofDirectory::createDirectory(GetCloudsDataPath(true) + "fml");
    }
    ofLogToFile(GetCloudsDataPath(true) + "fml/log_" + ofGetTimestampString() + ".log");
#endif
    
	firstFrame = true;
	playerSetup = false;
	shouldSetupPlayer = false;
    
#ifdef OCULUS_RIFT
	loader.loadImage(GetCloudsDataPath() + "AppData/CLOUDS_HD_BG_DOUBLE.png");
#else
	loader.loadImage(GetCloudsDataPath() + "AppData/SCREEN_BG.png");
#endif


}
//--------------------------------------------------------------
bool CloudsVHXAuth::setup()
{
    _keysPath = GetCloudsDataPath(true) + "vhx/client.bin";
    _tokensPath = GetCloudsDataPath(true) + "vhx/tokens.bin";
    
    // Load and decrypt the info from files on disk.
    //string path = GetCloudsDataPath() + "vhx/client.bin";
    if (CloudsCryptoLoadKeys(_clientId, _clientSecret, _packageId, _keysPath)) {
        ofLogNotice("CloudsVHXAuth::setup") << "Loaded keys successfully:\n"
        << "\tClient ID: " << _clientId << "\n"
        << "\tClient Secret: " << _clientSecret << "\n"
        << "\tPackage ID: " << _packageId;
    }
    else {
        ofLogError("CloudsVHXAuth::setup") << "Cannot open file at " << _keysPath;
    }
    
    if (CloudsCryptoLoadTokens(_accessToken, _refreshToken, _tokenExpiry, _tokensPath)) {
        ofLogNotice("CloudsVHXAuth::setup") << "Loaded tokens successfully:\n"
        << "\tAccess Token: " << _accessToken << "\n"
        << "\tRefresh Token: " << _refreshToken << "\n"
        << "\tToken Expiry: " << _tokenExpiry;
    }
    else {
        ofLogError("CloudsVHXAuth::setup") << "Cannot open file at " << _tokensPath;
        
        _tokenExpiry = 0;
    }
    
    state = INACTIVE;
    mode = WAITING;
    bNotifyComplete = false;
    ofAddListener(ofEvents().update, this, &CloudsVHXAuth::update);
    
    if (_packageId.size() && _accessToken.size()) {
        time_t nowTime = (ofGetSystemTime() / 1000.f);
        if (_tokenExpiry > nowTime) {
            // Try to verify the package immediately.
            verifyPackage();
        }
        else {
            // Refresh the token first, it's expired.
            refreshToken();
        }
        
        return true;
    }
    
    return false;
}
예제 #5
0
void CloudsHUDController::buildLayerSets(){
	
	//configure layers
	CloudsHUDLayerSet currentLayer;

	currentLayer = CLOUDS_HUD_QUESTION;
    
    CloudsHUDLayer* lowerThirdLayer = new CloudsHUDLayer();
    lowerThirdLayer->parseDirectory(GetCloudsDataPath() + "HUD/SVG/CLOUDS_HUD_LOWER_THIRD");
    layerSets[CLOUDS_HUD_LOWER_THIRD].push_back( lowerThirdLayer );
    allLayers.push_back( lowerThirdLayer );
    
    CloudsHUDLayer* questionLayer = new CloudsHUDLayer();
    questionLayer->parseDirectory(GetCloudsDataPath() + "HUD/SVG/CLOUDS_HUD_QUESTION");
    layerSets[CLOUDS_HUD_QUESTION].push_back( questionLayer );
    allLayers.push_back( questionLayer );
    
    CloudsHUDLayer* mapLayer = new CloudsHUDLayer();
    mapLayer->parseDirectory(GetCloudsDataPath() + "HUD/SVG/CLOUDS_HUD_MAP");
    layerSets[CLOUDS_HUD_MAP].push_back( mapLayer );
    allLayers.push_back( mapLayer );
    
    CloudsHUDLayer* projectExampleLayer = new CloudsHUDLayer();
    projectExampleLayer->parseDirectory(GetCloudsDataPath() + "HUD/SVG/CLOUDS_HUD_PROJECT_EXAMPLE");
    layerSets[CLOUDS_HUD_PROJECT_EXAMPLE].push_back( projectExampleLayer );
    allLayers.push_back( projectExampleLayer );
    
	//////////
	//TODO REPLACE WITH LINE WIPE SHADERS
    for( int i=0; i<allLayers.size(); i++ ){
        allLayers[i]->duration = 1.5;
        allLayers[i]->delayTime = 0;
        
        allLayers[i]->startPoint = ofVec2f(allLayers[i]->svg.getWidth(),0);
        allLayers[i]->endPoint   = ofVec2f(0,allLayers[i]->svg.getHeight());
    }
    ///////////
	
    home.bounds = lowerThirdLayer->svg.getMeshByID("HomeButtonFrame")->bounds;
    home.bounds.scaleFromCenter(1.5);
    
    svgVideoBounds = projectExampleLayer->svg.getMeshByID("ProjectExampleFrame")->bounds;
	videoBounds = svgVideoBounds;
    
    hudBounds.set( 0, 0, allLayers[0]->svg.getWidth(), allLayers[0]->svg.getHeight() );
    
//	cout << "HUD BOUNDS " << hudBounds.width << " / " << hudBounds.height << endl;
//    cout << "SCREEN " << ofGetScreenWidth() << " / " << ofGetScreenHeight() << endl;
}
void CloudsHUDLayer::draw(){
	
    if(!bIsOpen && !animatingFade){
        return;
    }
    
	if(!lineShader.isLoaded()){
		lineShader.load(GetCloudsDataPath() + "shaders/secondaryDisplay");
	}
    
	ofPushStyle();
	lineShader.begin();
    lineShader.setUniform1i("lineWork", 0);
	lineShader.setUniform1f("alphaAmt", animateOnPercentComplete);

    svg.drawFills();
    
    lineShader.setUniform1i("lineWork", 1);
	lineShader.setUniform1f("alphaAmt", hoverOnPercentComplete);

	svg.drawStrokes();

	lineShader.end();
    
	ofPopStyle();
}
예제 #7
0
void CloudsIntroSequence::updateTitle(){
	
	if(!extrudedTitleText.isLoaded() ||
	   currentFontSize != titleFontSize ||
	   currentFontExtrusion != titleFontExtrude)
	{
		currentFontSize = titleFontExtrude;
		currentFontExtrusion = titleFontExtrude;
		extrudedTitleText.loadFont(GetCloudsDataPath() + "font/materiapro_light.ttf", titleFontSize, currentFontExtrusion);
	}
	
	titleRect = ofRectangle(0,0,titleRectWidth * getSharedRenderTarget().getWidth(),
								titleRectHeight * getSharedRenderTarget().getHeight() );
	titleRect.alignTo( ofPoint(getCanvasWidth()/2, getCanvasHeight()/2) );
	hoveringTitle = titleRect.inside(GetCloudsInputX(), GetCloudsInputY());
	
	//	cout << "title rect is " << titleRect.getTopLeft() << " " << titleRect.getBottomLeft() << endl;
	//	cout << "hovering? " << (hoveringTitle ? "YES" : "NO" ) << endl;
	
	titleNoisePosition += titleNoiseSpeed;
	float hoverTitleOpacity;
	if(hoveringTitle || (startedOnclick && timeline->getIsPlaying()) ){
		hoverTitleOpacity = .9;
	}
	else{
		hoverTitleOpacity = titleTypeOpacity;
	}
	
	currentTitleOpacity += (hoverTitleOpacity-currentTitleOpacity)*.05;
}
예제 #8
0
bool CloudsRGBDVideoPlayer::loadSubtitles(string path){
    
    if (path == "") {
        return false;
    }

    if (!ofFile(path).exists()) {
        return false;
    }
    
    // need to know fps (all 24 except Higa (30))
    int fps = 24;
    if (strstr(path.data(), "Higa") != NULL) {
        fps = 30;
    }
    
    int fontSize = 36;
    if(!nextSubtitles.setup(path, GetCloudsDataPath() + "font/Blender-BOOK.ttf", fontSize/2, fps, TEXT_JUSTIFICATION_CENTER)) {
        return false;
    }
    
    // find font size based on 85% canvas width and a predefined maximum string
    float requiredWidth = (float)CloudsVisualSystem::getStaticRenderTarget().getWidth()*0.85;
    string maxStr = "If I'd have to choose from something interesting, something beautiful or something useful,";
    ofRectangle bounds = nextSubtitles.font.getStringBoundingBox(maxStr, 0, 0);
    
    // loop here until you find the right font size
    while (bounds.width > requiredWidth) {
        nextSubtitles.font.setSize(--fontSize);
        bounds = nextSubtitles.font.getStringBoundingBox(maxStr, 0, 0);
    }
//    cout << "font size is " << fontSize << endl;
    return true;
}
예제 #9
0
파일: testApp.cpp 프로젝트: cyrstem/CLOUDS
//--------------------------------------------------------------
void testApp::setup(){
	
	ofSetVerticalSync(true);
	ofSetFrameRate(60);
	ofBackground(0);
    ofEnableSmoothing();
	
	currentAct = NULL;
	rebuildAct = false;
	
	parser.loadFromFiles();
	parser.loadMediaAssets();
    
	visualSystems.loadPresets();
	
	storyEngine.parser = &parser;
	storyEngine.visualSystems = &visualSystems;
	
	storyEngine.setup();
    
    vector<CloudsClip*> clips = storyEngine.getStartingQuestions();
    random_shuffle(clips.begin(), clips.end());
    
    for(int i = 0; i < clips.size(); i++){
        
        CloudsClip* clip = clips[i];
        string topic = clip->getAllQuestionTopicPairs().begin()->first;
        CloudsRun run;
        exploreAct(clip,topic,true,run,0,10);

    }
    
    set<CloudsClip*>::iterator it;
    int clipid = 0;
    for(it = traversedClips.begin(); it != traversedClips.end(); it++){
        cout << clipid++ << "/" << traversedClips.size() << " " << (*it)->getLinkName() << endl;
    }
    
    ofBuffer shellscript;
    shellscript.append("#!/bin/bash\n");
    for(it = traversedClips.begin(); it != traversedClips.end(); it++){
        CloudsClip* clip = *it;
        if(clip->hasMediaAsset){
            string mediaFile = ofToDataPath(clip->combinedVideoPath,true);
            string xmlFile   = ofToDataPath(clip->combinedCalibrationXMLPath,true);
            string containingFolder = ofFilePath::addTrailingSlash(ofFilePath::getEnclosingDirectory( mediaFile));
            
            shellscript.append(string("echo \"copying ") + ofFilePath::getFileName(mediaFile) + "\"\n" );
            shellscript.append(string("cp \"") + mediaFile + "\" \"" + containingFolder + "__keepers/\"\n" );
            shellscript.append(string("cp \"") + xmlFile   + "\" \"" + containingFolder + "__keepers/\"\n\n"  );
        }
    }
    
    ofBufferToFile(GetCloudsDataPath()+"copyscript.sh", shellscript);
    
	//ofAddListener(storyEngine.getEvents().actCreated, this, &testApp::actCreated);
}
예제 #10
0
void CloudsHUDController::calculateFontSizes(){
    // temporary allocate
    int minFontSize = 1;
    int maxFontSize = 70;
    #ifdef OCULUS_RIFT
	string fontPath = GetCloudsDataPath() + "font/Blender-MEDIUM.ttf";
	#else
	string fontPath = GetCloudsDataPath() + "font/Blender-THIN.ttf";
	#endif

    for(int i = minFontSize; i < maxFontSize; i++){
        ofxFTGLFont *tmp = new ofxFTGLFont();
        tmp->loadFont(fontPath , i );
        tempFontList.push_back( tmp );
    }

    //BIO
    ////first name
    BylineFirstNameTextBox      = getFontForLayer("BylineFirstNameTextBox_1_", fontPath, 50);
    ////last name
    BylineLastNameTextBox       = getFontForLayer("BylineLastNameTextBox", fontPath, 50);
    ////title
    BylineTopicTextBoxBottom    = getFontForLayer("BylineTopicTextBoxBottom", fontPath, 35);
    ////location
    BylineTopicTextBoxTop       = getFontForLayer("BylineTopicTextBoxTop", fontPath, 35);
    ////description
    BylineBodyCopyTextBox       = getLayoutForLayer("BylineBodyCopyTextBox", fontPath, false);
    defaultBioBounds            = hudLabelMap["BylineBodyCopyTextBox"]->bounds;
    
    ResetButtonTextBox          = getLayoutForLayer("ResetButtonTextBox", fontPath);
    QuestionTextBox             = getLayoutForLayer("QuestionTextBox", fontPath);
    TopicTextBoxLeft            = getLayoutForLayer("TopicTextBoxLeft", fontPath);
    TopicTextBoxRight           = getLayoutForLayer("TopicTextBoxRight", fontPath);
    ProjectExampleTextboxLeft   = getLayoutForLayer("ProjectExampleTextboxLeft", fontPath);
    ProjectExampleTextboxRight  = getLayoutForLayer("ProjectExampleTextboxRight", fontPath);
    ProjectExampleTextBoxTop    = getLayoutForLayer("ProjectExampleTextBoxTop", fontPath);
    
    // cleanup!
    for( int i=0; i<tempFontList.size(); i++ ){
        delete tempFontList[i];
    }
    tempFontList.clear();
}
예제 #11
0
//--------------------------------------------------------------
void testApp::setup(){
	
	ofSetVerticalSync(true);
	ofSetFrameRate(60);
	ofBackground(0);
	ofToggleFullscreen();
    parser.loadFromFiles();
	
	if(!ofFile::doesFileExist(GetCloudsDataPath() + "CloudsMovieDirectory.txt")){
		ofSystemAlertDialog("Could not find movie file path. \
							Create a file called CloudsMovieDirectory.txt \
							that contains one line, the path to your movies folder");
	}
void CloudsVisualSystemCubeCraft::selfSetup()
{
	
	//gui
	colorMap.loadImage( GetCloudsDataPath() + "colors/defaultColorPalette.png");
	
	//cout << "Number of boxes == " << (dimX * dimY * dimZ) << endl;
	ofxObjLoader::load( getVisualSystemDataPath() + "models/box.obj", cubeMesh );
	
	loadShaders();
	
	updateAllColors();
}
Tonic::Generator CloudsVisualSystemConnectors::buildSynth()
{
    string strDir = GetCloudsDataPath(true)+"sound/textures";
    ofDirectory sdir(strDir);
    Tonic::SampleTable samples[1];
    for(int i=0; i<tonicSamples.size();i++){
        string strAbsPath = ofToDataPath(strDir + "/" + tonicSamples[i].soundFile, true);
        samples[i] = ofxAudioDecoderTonic(strAbsPath);
    }
    
    Tonic::Generator sampleGen1 = Tonic::BufferPlayer().setBuffer(samples[0]).loop(1).trigger(tonicSamples[0].soundTrigger);
    
    return sampleGen1 * volumeControl;
}
void CloudsVisualSystemBalloons::selfUpdate()
{
    cloudsCamera.lookTarget = ofVec3f(0,0,0);
    
	p0->getTextureReference().readToPixels(pospix);
	ofFloatColor poscol = pospix.getColor(0,0);
	balloon00Pos.set(poscol.r,poscol.g,poscol.b);
	
	//balloon00Pos = mix(balloon00Pos, ofVec3f(poscol.r, poscol.g, poscol.b), .1);
	balloon00Pos = mix(balloon00Pos, ofVec3f(0,0,0), balloonFrameVal);
	
	
	float t = ofGetElapsedTimef();
	progress = ofMap(t, creditStartTime, creditStartTime + creditDuration * creditDurationScale, 0, 1, true);
	balloonFrameVal = ofMap(t, balloonFramStartTime, balloonFramEndTime, 1, 0, true);

	//float creditOffset = -(creditPosition * (originalCreditPositions.back().y+dim*2) ) + dim;
	float creditOffset = -(progress * (originalCreditPositions.back().y+dim*2) ) + dim;
	
	for(int i=0; i<credits.size(); i++)
	{
		credits[i].pos.y = originalCreditPositions[i].y + creditOffset;
	}
	
	if(!font.isLoaded() || currentFontSize != fontSize)
	{
		font.loadFont(GetCloudsDataPath() + "font/Blender-BOOK.ttf", fontSize);
		currentFontSize = fontSize;
	}
	
	
	//background color
	if(bgRamp.isAllocated())
	{
		bgColor = bgRamp.getColor(0, (1. - progress) * bgRamp.getHeight());
		bgColor2 = bgRamp.getColor(1, (1. - progress) * bgRamp.getHeight());
        bgColor2.setBrightness(bgColor2.getBrightness()*.5);
	}
	
}
cloudsSequencer::cloudsSequencer(string f, vector<lukeNote>& n)
{
    string sline;
    ofFile seqfile (GetCloudsDataPath()+"sound/seqs/" + f);
    if(!seqfile.exists())
    {
        ofLogError("can't find sequence!");
    }
    ofBuffer seqbuf(seqfile);
    while(!seqbuf.isLastLine())
    {
        sline = seqbuf.getNextLine();
        vector<string> temp = ofSplitString(sline, " ");
        lukeNote foo;
        foo.starttime = ofToFloat(temp[0])/1000.;
        foo.pitch = ofToInt(temp[1]);
        foo.velo = (ofToFloat(temp[2])/128.);
        foo.dur = ofToFloat(temp[3])/1000.;
        //cout << foo.starttime << ": " << foo.pitch << " " << foo.velo << " " << foo.dur << endl;
        n.push_back(foo);
    }
}
예제 #16
0
void CloudsSpeaker::exportSpeakerXMLTemplate(){
	
	ofxXmlSettings xmltemplate;
	map<string,CloudsSpeaker>::iterator it;
	xmltemplate.addTag("clouds");
	xmltemplate.pushTag("clouds");
	int personnum = 0;
	for(it = speakers.begin(); it != speakers.end(); it++){
		xmltemplate.addTag("person");
		xmltemplate.addAttribute("person", "id", it->first, personnum);
		xmltemplate.pushTag("person", personnum);
		xmltemplate.addValue("first", it->second.firstName);
		xmltemplate.addValue("last", it->second.lastName);
		xmltemplate.addValue("twitter", "");
		xmltemplate.addValue("byline1", "");
		xmltemplate.addValue("byline2", "");
		xmltemplate.addValue("resume", "");

		xmltemplate.popTag();//person;
		personnum++;
	}

	xmltemplate.saveFile(GetCloudsDataPath() + "/SpeakerTemplate.xml");
}
// selfSetup is called when the visual system is first instantiated
// This will be called during a "loading" screen, so any big images or
// geometry should be loaded here
void CloudsVisualSystemFireworks::selfSetup()
{
	//defaults
	bAnimateCamera = true;
	minLifeSpan = .5;
	maxLifeSpan = 1.5;
	
	minExplosionTime = .75;
	maxExplosionTime = 1.25;
	
	speed = .25;
	explosionFrequencey = .1;
	emissonRate = 2;
	particleSpread = 10;
	particleSize = 10;
	spawnDistance = 250;
	
	camSpeed = .7;
	cameraMotionScl = .25;
	
	gravity.set( 0, 0, 0);
	
	minVel = .75;
	maxVel = 1.25;
	
	maxFWVel = 200;
	
	fogDistance = 800;
	fogAttenuation = 1;
	fogColor.set(0,1,0,1);
	
	bUseCircle = bUseSquare = bUseTriangle = bUseDot = true;
	
	bBurst = bOctahedron = bTetrahedron = bDodecagedron = true;
	
	startColorSaturation = endColorSaturation = fogSaturation = 1;
	
	for (int i=0; i<3; i++) {
		string key = "C" + ofToString(i) + "_birth";
		fwColors[key];
		fwSaturations[key];
		
		key = "C" + ofToString(i) + "_death";
		fwDeathColors[key];
		fwDeathSaturations[key];
	}
	
	//setupParticles
	FIREWORKS_NUM_PARTICLES = 200000;
	
	//positions = new ofVec3f[ FIREWORKS_NUM_PARTICLES ];
	//velocities = new ofVec3f[ FIREWORKS_NUM_PARTICLES ];
	//lifeData = new ofFloatColor[ FIREWORKS_NUM_PARTICLES ];
	//indices = new ofIndexType[ FIREWORKS_NUM_PARTICLES ];
	positions.resize( FIREWORKS_NUM_PARTICLES );
	velocities.resize( FIREWORKS_NUM_PARTICLES );
	lifeData.resize( FIREWORKS_NUM_PARTICLES );
	indices.resize( FIREWORKS_NUM_PARTICLES );
	
	float lifespan;
	float t = ofGetElapsedTimef();
	
	vbo.setVertexData( &positions[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW );
	vbo.setNormalData( &velocities[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW );
	vbo.setIndexData( &indices[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW );
	
	
	vbo.setColorData( &lifeData[0], FIREWORKS_NUM_PARTICLES, GL_DYNAMIC_DRAW );
	
	//TODO: mention to james that we might need a getCloudsData method
	colorSampleImage.loadImage( GetCloudsDataPath() + "colors/defaultColorPalette.png" );
	
	loadFileToGeometry( getVisualSystemDataPath() +  "animationTargets/dodecahedron.txt", dodecagedronPoints );
	loadFileToGeometry( getVisualSystemDataPath() +  "animationTargets/octahedron.txt", octahedronPoints );
	loadFileToGeometry( getVisualSystemDataPath() +  "animationTargets/tetrahedron.txt", tetrahedronPoints );
	loadFileToGeometry( getVisualSystemDataPath() + "animationTargets/icosahedron.txt", icosahedronPoints );
	
	//shader
	shader.load(getVisualSystemDataPath() + "shaders/base.vert", getVisualSystemDataPath() + "shaders/base.frag");
	
	shader.begin();
	shader.setUniform3f( "gravity", gravity.x, gravity.y, gravity.z );
	shader.end();
	startColor.set( .9, .95, 1.95, 1 );
	endColor.set( .6, 1.3, .2, 1 );
	
	spriteImage.loadImage(getVisualSystemDataPath() + "images/sphereNormal.png");
		
	//particle rendering
	bUpdateVbo = true;
	indexCount = 0;
	nextIndex = 0;
	numSprites = 0;
	
	nextFireworkExplosionTime = ofGetElapsedTimef() + 1;
	
	
	
	ofDisableArbTex();
	
	dotImage.loadImage(  getVisualSystemDataPath() + "images/sphereNormal.png" );
	triangleImage.loadImage(  getVisualSystemDataPath() + "images/triangle-sprite.png" );
	squareImage.loadImage(  getVisualSystemDataPath() + "images/square-sprite.png" );
	circleImage.loadImage(  getVisualSystemDataPath() + "images/circle-sprite.png" );
	
	ofEnableArbTex();
	
	getCameraRef().setPosition(0, 0, 0);
	camTarget.set( 0,0,spawnDistance);
	
    //MA: changed ofGetWidth() to getCanvasWidth() and ofGetHeight() to getCanvasHeight()
//	glowFbo0.allocate( getCanvasWidth(), getCanvasHeight(), GL_RGB );
//	glowFbo1.allocate( glowFbo0.getWidth()/2, glowFbo0.getHeight()/2, GL_RGB );;
//	glowFbo2.allocate( glowFbo1.getWidth()/2, glowFbo1.getHeight()/2, GL_RGB );;
//	glowFbo3.allocate( glowFbo2.getWidth()/2, glowFbo2.getHeight()/2, GL_RGB );;
//	glowFbo4.allocate( glowFbo3.getWidth()/2, glowFbo3.getHeight()/2, GL_RGB );;
//	glowFbo5.allocate( glowFbo4.getWidth()/2, glowFbo4.getHeight()/2, GL_RGB );;
//	glowFbo6.allocate( glowFbo5.getWidth()/2, glowFbo5.getHeight()/2, GL_RGB );;
	
	glowShader.load(getVisualSystemDataPath() + "shaders/post");
}
void VoxelMesh::reloadShaders(){
	pointShader.load(GetCloudsDataPath() +  "shaders/background/voxel_points");
	lineShader.load(GetCloudsDataPath() +  "shaders/background/voxel_lines");
}
예제 #19
0
void CloudsSpeaker::populateSpeakers(){
	
	speakers.clear();

	
	//parse speaker xml
	ofxXmlSettings speakerxml;
	if(!speakerxml.loadFile(GetCloudsDataPath()+"secondaryDisplay/web/xml/people.xml")){
		ofLogError("CloudsSpeaker::populateSpeakers") << "People XML failed to load";
		return;
	}
	speakerxml.pushTag("clouds");
	int numSpeakers = speakerxml.getNumTags("person");
	for(int i = 0; i < numSpeakers; i++){
		CloudsSpeaker speaker;
		speaker.fcpID = speakerxml.getAttribute("person", "id", "", i);
		if(speaker.fcpID == ""){
			ofLogError("Speaker XML") << "Error parsing entry " << i << " no FCP ID attribute";
			continue;
		}
		speakerxml.pushTag("person", i);
		
		speaker.lastName = speakerxml.getValue("last", "");
		speaker.firstName = speakerxml.getValue("first", "");
		speaker.gender = speakerxml.getValue("gender", "");
		speaker.twitterHandle = speakerxml.getValue("twitter", "");
		speaker.title = speakerxml.getValue("title", "");
		
		speaker.location1 = speakerxml.getValue("location1", "");
		speaker.location2 = speakerxml.getValue("location2", "");
		
		speaker.byline1 = speakerxml.getValue("byline1", "");
		speaker.byline2 = speakerxml.getValue("byline2", "");
		
		speakerxml.popTag();//Person
		
		speakers[speaker.fcpID] = speaker;

//		speaker.printInfo();
	}
	
	speakerxml.popTag();//clouds
	//clouds
//	<person id="Aaron">
//	<first>Aaron</first>
//	<last>Koblin</last>
//	<title>Digital Media Artist</title>
//	<twitter>@aaronkoblin</twitter>
//	<location1>Santa Monica, California</location1>
//	<location2>San Francisco, California</location2>
//	<byline1>As Creative Director of the Data Arts Team at Google, Aaron Koblin develops innovative uses of data visualization, crowdsourcing, and web-based storytelling. </byline1>
//	<byline2>He works with community generated data to reflect on cultural trends and the changing relationship between humans and the systems they create.
//	</byline2>
//	<resume> ... </resume>
//	</person>
	//all people
//	map<string,CloudsSpeaker>::iterator it;
//	for(it = speakers.begin(); it != speakers.end(); it++){
//		cout << it->second.firstName + " "  + it->second.lastName << endl;
//	}
	
	//export xml template
	
}
예제 #20
0
void CloudsIntroSequence::drawHelperType(){

	ofPushStyle();
	glDisable(GL_DEPTH_TEST);
	ofDisableLighting();
    
	if(!helperFont.isLoaded() || currentHelperFontSize != helperFontSize){
		helperFont.loadFont(GetCloudsDataPath() + "font/Blender-BOOK.ttf", helperFontSize);
		currentHelperFontSize = helperFontSize;
	}

	string helpHoverText;
	ofVec3f basePosition(0,0,0);
	float helperTextOpacity = 0.0;
	float scaleModifier = 1.0;// * ofGetMouseX() / ofGetWidth();

	
	#ifdef OCULUS_RIFT
	if(!startedOnclick){
		if(introNodeThree.hover || introNodeTwo.finished){
			helpHoverText = "< LOOK FORWARD";
			basePosition = introNodeTwo.worldPosition;
			helperTextOpacity = powf(ofMap(ofGetElapsedTimef(),
										   CalibrationNode::nodeActivatedTime,
										   CalibrationNode::nodeActivatedTime+.8,0.0,.8,true), 2.) * (1.0 - introNodeThree.percentComplete);
		}
		else if(introNodeTwo.hover || introNodeOne.finished){
			helpHoverText = "LOOK RIGHT >";
			basePosition = introNodeOne.worldPosition;
			helperTextOpacity = powf(ofMap(ofGetElapsedTimef(),
										   CalibrationNode::nodeActivatedTime,
										   CalibrationNode::nodeActivatedTime+.8,0.0,.8,true), 2.);
		}
		else {
			helpHoverText = "< LOOK LEFT";
			basePosition = introNodeThree.worldPosition;
			helperTextOpacity = (currentTitleOpacity - titleTypeOpacity) * (1.0 - introNodeOne.percentComplete);
		}
		helperFont.setTracking(helperFontTracking);
	}
	#endif
	
	if(caughtQuestion != NULL){
		basePosition = caughtQuestion->hoverPosition;
		helpHoverText = caughtQuestion->question;
		helperTextOpacity = ofMap(caughtQuestion->hoverPercentComplete, 0.0, .05, 0.0, 1.0, true);

		scaleModifier = .5;
		helperFont.setTracking(helperFontTracking*.1);
	}

    //draw the text
	if(helpHoverText != ""){
        ofPushMatrix();
		helpHoverText = ofToUpper(helpHoverText);
		
		float hoverTextWidth = helperFont.stringWidth(helpHoverText);
		float hoverTextWidth2,questionTextHeight2;
		string secondLine;
		bool twoLines = hoverTextWidth > 500;
		if(twoLines){
			vector<string> pieces = ofSplitString(helpHoverText, " ", true,true);
			vector<string> firstHalf;
			vector<string> secondHalf;
			int halfsize = pieces.size() / 2;
			firstHalf.insert(firstHalf.begin(), pieces.begin(), pieces.begin() + halfsize);
			secondHalf.insert(secondHalf.begin(), pieces.begin() + halfsize, pieces.end());
			helpHoverText = ofJoinString(firstHalf, " ");
			secondLine = ofJoinString(secondHalf, " ");
			hoverTextWidth  = helperFont.stringWidth(helpHoverText);
			hoverTextWidth2 = helperFont.stringWidth(secondLine);
		}
		float hoverTextHeight = helperFont.stringHeight(helpHoverText);

		#ifdef OCULUS_RIFT
		getOculusRift().multBillboardMatrix( basePosition );
		#else
		ofTranslate(basePosition);
		#endif
		ofRotate(180, 0, 0, 1); //flip around
		ofScale(scaleModifier*helperFontScale,
				scaleModifier*helperFontScale,
				scaleModifier*helperFontScale);
		
		ofSetColor(255,255*helperTextOpacity);
		
		int yOffsetMult = (!bUseOculusRift && caughtQuestion->tunnelQuadrantIndex == 2) ? -1 : 1;
		//helperFont.drawString(helpHoverText, -hoverTextWidth/2, yOffsetMult * (helperFontY - hoverTextHeight/2) );
       	helperFont.drawString(helpHoverText, -hoverTextWidth*.5, yOffsetMult * (helperFontY - hoverTextHeight*.5));
		if(twoLines){
			helperFont.drawString(secondLine, -hoverTextWidth2*.5, yOffsetMult * (helperFontY + hoverTextHeight*1.5) );
		} 
		ofPopMatrix();
	}
    
    if(firstQuestionStopped){
        ofPushMatrix();
        
        float questionhintAlpha = ofMap(ofGetElapsedTimef(),
                                        firstQuestionStoppedTime, firstQuestionStoppedTime+2,
                                        0.0, .2, true) * (1.0-helperTextOpacity);
        
        float hintTextWidth  = helperFont.stringWidth("SELECT A QUESTION");
		float hintTextHeight = helperFont.stringHeight("SELECT A QUESTION");
		ofVec3f basePosition = ofVec3f(0,0,warpCamera.getPosition().z + questionZStopRange.max);
#ifdef OCULUS_RIFT
		getOculusRift().multBillboardMatrix( basePosition );
#else
		ofTranslate(basePosition);
#endif
		ofRotate(180, 0, 0, 1); //flip around
		ofScale(helperFontScale*.8,
				helperFontScale*.8,
				helperFontScale*.8);
        
        ofSetColor(255, 255*questionhintAlpha);
        helperFont.drawString("SELECT A QUESTION", -hintTextWidth*.5, hintTextHeight*.5 );

        if(caughtQuestion != NULL){
            float questionHoldAlpha = ofMap(caughtQuestion->hoverPercentComplete, .2, .3, 0.0, .2, true);
            ofSetColor(255, 255*questionHoldAlpha);
            hintTextWidth = helperFont.stringWidth("HOLD TO SELECT");
            hintTextHeight = helperFont.stringWidth("HOLD TO SELECT");
            helperFont.drawString("HOLD TO SELECT", -hintTextWidth*.5, hintTextHeight*.5 );
        }
        
        ofPopMatrix();
    }

    ofEnableLighting();
	glEnable(GL_DEPTH_TEST);
	ofPopStyle();

}
//--------------------------------------------------------------
void CloudsVHXAuth::threadedFunction()
{
    completeArgs.success = false;
    completeArgs.result = "";
    
    if (mode == REQUEST_TOKEN || mode == REFRESH_TOKEN) {
        _ssl.setup();
        _ssl.setOpt(CURLOPT_CAINFO, ofToDataPath(GetCloudsDataPath(true) + "vhx/cacert.pem"));
        _ssl.setURL("https://api.vhx.tv/oauth/token");
        if (mode == REQUEST_TOKEN) {
            _ssl.addFormField("client_id", _clientId);
            _ssl.addFormField("client_secret", _clientSecret);
            _ssl.addFormField("grant_type", "client_credentials");
        }
        else {
            _ssl.addFormField("refresh_token", _refreshToken);
            _ssl.addFormField("grant_type", "refresh_token");
        }
        
        _ssl.perform();
        
        string response = _ssl.getResponseBody();
        ofLogVerbose("CloudsVHXAuth::threadedFunction") << "Response:" << endl << response;
        
        completeArgs.success = false;
        
        ofxJSONElement json;
        if (json.parse(response)) {
            if (json.isMember("access_token")) {
                _accessToken = json["access_token"].asString();
                _refreshToken = json["refresh_token"].asString();
                _tokenExpiry = (ofGetSystemTime() / 1000.f) + json["expires_in"].asFloat();
                
                // Save the tokens to disk.
                CloudsCryptoSaveTokens(_accessToken, _refreshToken, _tokenExpiry, _tokensPath);
                
                completeArgs.success = true;
                completeArgs.result = _accessToken;
            }
            else {
                ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON format:" << endl << response;
            }
        }
        else {
            ofLogError("CloudsVHXAuth::threadedFunction") << "Unable to parse JSON:" << endl << response;
        }
        
        _ssl.clear();
        
        bNotifyComplete = true;
    }
    else if (mode == REQUEST_CODE) {
        _ssl.setup();
        _ssl.setOpt(CURLOPT_CAINFO, ofToDataPath(GetCloudsDataPath(true) + "vhx/cacert.pem"));
        _ssl.setURL("https://api.vhx.tv/oauth/codes");
        _ssl.addFormField("client_id", _clientId);
        _ssl.addFormField("client_secret", _clientSecret);

        _ssl.perform();
        
        string response = _ssl.getResponseBody();
        ofLogVerbose("CloudsVHXAuth::threadedFunction") << "Response:" << endl << response;
        
        completeArgs.success = false;
        
        ofxJSONElement json;
        if (json.parse(response)) {
            if (json.isMember("code")) {
                _code = json["code"].asString();
                _codeExpiry = (ofGetSystemTime() / 1000.f) + json["expires_in"].asFloat();
                
                completeArgs.success = true;
                completeArgs.result = _code;
            }
            else {
                ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON format:" << endl << response;
            }
        }
        else {
            ofLogError("CloudsVHXAuth::threadedFunction") << "Unable to parse JSON:" << endl << response;
        }
        
        _ssl.clear();
        
        bNotifyComplete = true;
    }
    else if (mode == LINK_CODE) {
        stringstream ss;
        ss << "http://www.vhx.tv/activate/clouds";
        ss << "?client_id=" << _clientId;
        ss << "&code=" << _code;
        ofLaunchBrowser(ss.str());
        
        ss.str("");
        ss << "https://api.vhx.tv/oauth/codes/" << _code;
        ss << "?client_id=" << _clientId;
        ss << "&client_secret=" << _clientSecret;
        
        completeArgs.success = false;

        bool bWaitForLink = true;
        while (bWaitForLink && isThreadRunning()) {
            
            _ssl.setup();
            _ssl.setOpt(CURLOPT_CAINFO, ofToDataPath(GetCloudsDataPath(true) + "vhx/cacert.pem"));
            _ssl.setURL(ss.str());
            _ssl.perform();
            
            string response = _ssl.getResponseBody();
            ofLogVerbose("CloudsVHXAuth::threadedFunction") << "Response:" << endl << response;

            ofxJSONElement json;
            if (json.parse(response)) {
                if (json.isMember("access_token")) {
                    _accessToken = json["access_token"].asString();
                    _refreshToken = json["refresh_token"].asString();
                    _tokenExpiry = (ofGetSystemTime() / 1000.f) + json["expires_in"].asFloat();
                    
                    // Save the tokens to disk.
                    CloudsCryptoSaveTokens(_accessToken, _refreshToken, _tokenExpiry, _tokensPath);
                    
                    completeArgs.success = true;
                    completeArgs.result = _accessToken;

                    bWaitForLink = false;
                }
                else {
                    ofLogVerbose("CloudsVHXAuth::threadedFunction") << "Unexpected JSON result:" << endl << response;
                }
            }
            else {
                ofLogError("CloudsVHXAuth::threadedFunction") << "Unable to parse JSON:" << endl << response;
                
                bWaitForLink = false;
            }
            
            _ssl.clear();
            
            ofSleepMillis(500);
        }
        
        bNotifyComplete = true;
    }
    else if (mode == VERIFY_PACKAGE) {
        stringstream ss;
        ss << "Authorization: Bearer " << _accessToken;
        
        _ssl.setup();
        _ssl.setOpt(CURLOPT_CAINFO, ofToDataPath(GetCloudsDataPath(true) + "vhx/cacert.pem"));
        _ssl.setURL("https://api.vhx.tv/me");
        _ssl.addHeader(ss.str());
        
        _ssl.perform();
        
        string response = _ssl.getResponseBody();
        ofLogVerbose("CloudsVHXAuth::threadedFunction") << "Response:" << endl << response;
        cout << "RESPONSE " << response << endl;
        
        completeArgs.success = false;

        ofxJSONElement json;
        if (json.parse(response)) {
            if (json.isMember("_embedded")) {
                const ofxJSONElement& embedded = json["_embedded"];
                if (embedded.isMember("packages")) {
                    const ofxJSONElement& packages = embedded["packages"];
                    if(packages.size() > 0){
                        for (int i = 0; i < packages.size(); ++i) {
                            const ofxJSONElement& element = packages[i];
                            if (element.isMember("id")) {
                                string packageId = element["id"].asString();
                                if (packageId == _packageId || packageId == "8102") { //hack for rental
                                    // Found matching package, check that purchase is valid.
                                    if (element.isMember("purchase_type")) {
                                        string purchaseType = element["purchase_type"].asString();
                                        if (purchaseType == "purchase") {
                                            state = PURCHASE;
                                            completeArgs.success = true;
                                            completeArgs.result = "purchase";
                                            break;
                                        }
                                        else if (purchaseType == "rental") {
                                            if (element.isMember("expires_at")) {
                                                if (element["expires_at"].isNull()) {
                                                    // No expiry, assume we're good.
                                                    state = RENTAL;
                                                    completeArgs.success = true;
                                                    completeArgs.result = "rental";
                                                    break;
                                                }
                                                else {
                                                    // Parse the expiry date.
                                                    Poco::DateTime dt;
                                                    int tzd;
                                                    if (Poco::DateTimeParser::tryParse(element["expires_at"].asString(), dt, tzd)) {
                                                        Poco::LocalDateTime ldt(tzd, dt);
                                                        Poco::Timestamp expiryTime = ldt.timestamp();
                                                        Poco::Timestamp nowTime;
                                                        
                                                        // Make sure the rental is valid.
                                                        if (nowTime < expiryTime) {
                                                            // Expires in the future, we're good.
                                                            _packageExpiry = expiryTime.epochTime();
                                                            
                                                            state = RENTAL;
                                                            completeArgs.success = true;
                                                            completeArgs.result = "rental";
                                                            break;
                                                        }
                                                        else {
                                                            // Expired, no good.
                                                            state = EXPIRED;
                                                            completeArgs.success = true;
                                                            completeArgs.result = "expired";
                                                            continue; //check other packages
                                                        }
                                                    }
                                                    else {
                                                        // Could not parse expiry, assume no good.
                                                        state = EXPIRED;
                                                        completeArgs.success = true;
                                                        completeArgs.result = "expired";
                                                        continue; //check the other packages
                                                    }
                                                }
                                            }
                                            else {
                                                // No expiry, assume we're good.
                                                state = RENTAL;
                                                completeArgs.success = true;
                                                completeArgs.result = "rental";
                                                break;
                                            }
                                        }
                                        else {
                                            // Not a rental or purchase, assume no good.
                                            state = INACTIVE;
                                            completeArgs.success = true;
                                            completeArgs.result = "inactive";
                                            continue; //check the other packages
                                        }
                                    }
                                    else {
                                        ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON result, 'purchase_type' not found:" << endl << response;
                                    }
                                }
                                else {
                                    ofLogNotice("CloudsVHXAuth::threadedFunction") << "Skipping package " << packageId;
                                }
                            }
                            else {
                                ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON result, 'id' not found:" << endl << response;
                            }
                        }
                    }
                    else {
                        state = INACTIVE;
                        completeArgs.success = true;
                        completeArgs.result = "inactive";
                    }
                }
                else {
                    ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON result, 'packages' not found:" << endl << response;
                }
            }
            else {
                ofLogError("CloudsVHXAuth::threadedFunction") << "Unexpected JSON result, '_embedded' not found:" << endl << response;
            }
        }
        else {
            ofLogError("CloudsVHXAuth::threadedFunction") << "Unable to parse JSON:" << endl << response;
        }
        
        _ssl.clear();
        bNotifyComplete = true;
    }
    else {
        ofLogError("CloudsVHXAuth::threadedFunction") << "Mode " << mode << " is unrecongized!";
    }
}
lindenSequencer::lindenSequencer(string f)
{
    string sline;
    thestring = " ";
    ptr = 0;
    match = '*';
    
    string axiom;
    int generations;
    vector< vector<string> > rules;
    
    // load
    ofFile seqfile (GetCloudsDataPath()+"sound/lsys/" + f);
    if(!seqfile.exists())
    {
        ofLogError("can't find sequence!");
    }
    ofBuffer seqbuf(seqfile);
    // setup line
    sline = seqbuf.getNextLine();
    vector<string> sups = ofSplitString(sline, " ");
    axiom = sups[0];
    match = sups[1][0];
    generations = ofToInt(sups[2]);
    // rules
    while(!seqbuf.isLastLine())
    {
        sline = seqbuf.getNextLine();
        vector<string> temp = ofSplitString(sline, " ");
        rules.push_back(temp);
    }
    
    if(LUKEDEBUG) {
        cout << "lsys axiom: " << axiom << ", matching on: " << match << " for " << generations << " generations." << endl;
        for(int i = 0;i<rules.size();i++)
        {
            cout << "lsys: " << rules[i][0] + ": " << rules[i][1] << endl;
        }
    }
    
    // solve
    string instring, outstring;
    int i, j, k;
    int ismatching = 0;
    
    instring = axiom;
    for (int i=0;i<generations;i++) // 1 - loop through the generations
    {
        outstring = "";
        for (int j=0;j<instring.length();j++) // 2 - loop through the input string
        {
            ismatching = 0;
            for (int k=0;k<rules.size();k++) // 3 - loop through the rules
            {
                if (instring[j]==rules[k][0][0]) ismatching++;
                if (ismatching>0) {
                    outstring=outstring+rules[k][1];
                    k = rules.size();
                }
            }
            if (ismatching==0)
            {
                outstring=outstring+instring[j];
            }
        }
        instring = outstring; // we know we're doing this at the end
        if(LUKEDEBUG) cout << i << ": " << outstring << endl;
    }
    
    thestring = outstring;
}
예제 #23
0
//--------------------------------------------------------------
void testApp::setup(){
	
	ofSetVerticalSync(true);
	ofSetFrameRate(60);
	ofBackground(0);
	ofToggleFullscreen();
    parser.loadFromFiles();
	
	if(!ofFile::doesFileExist(GetCloudsDataPath() + "CloudsMovieDirectory.txt")){
		ofSystemAlertDialog("Could not find movie file path. \
							Create a file called CloudsMovieDirectory.txt \
							that contains one line, the path to your movies folder");
	}

	parser.setCombinedVideoDirectory(ofBufferFromFile(GetCloudsDataPath() + "CloudsMovieDirectory.txt").getText());
	
	//visualSystems.populateVisualSystems();
	visualSystems.loadPresets();
	
	storyEngine.parser = &parser;
	storyEngine.visualSystems = &visualSystems;
	storyEngine.printDecisions = false;
	storyEngine.combinedClipsOnly = true;
	storyEngine.setup();
	sound.setup(storyEngine);
	
	player.setup();
	player.setStoryEngine(storyEngine);
    player.setRun(run);
	player.getClusterMap().buildEntireCluster(parser);
void CloudsVisualSystemBalloons::selfSetup()
{
	//make our ballons
	setBalloonPositions();
	
	p0 = &posFbo0;
	p1 = &posFbo1;
	
	v0 = &velFbo0;
	v1 = &velFbo1;

	//baclkgrojnd ramp
	bgRamp.loadImage(getVisualSystemDataPath() + "images/backgroundRamp.png");
	
	//load balloon mesh
	ofMesh temp;
//	ofxObjLoader::load( getVisualSystemDataPath() + "models/box.obj", temp);
//	ofxObjLoader::load( getVisualSystemDataPath() + "models/balloon_low.obj", temp);
	ofxObjLoader::load( getVisualSystemDataPath() + "models/balloon_mid.obj", temp);
//	ofxObjLoader::load( getVisualSystemDataPath() + "models/balloon.obj", temp);
		
	vector<ofVec3f>& v = temp.getVertices();
	vector<ofVec3f>& n = temp.getNormals();
	
	total = v.size();

	vbo.setVertexData(&v[0], v.size(), GL_STATIC_DRAW);
	vbo.setNormalData(&n[0], n.size(), GL_STATIC_DRAW);
	
	shader.load(getVisualSystemDataPath() + "shaders/normalShader");
	posShader.load(getVisualSystemDataPath() + "shaders/posShader");
	velShader.load(getVisualSystemDataPath() + "shaders/velShader");
	quatShader.load(getVisualSystemDataPath() + "shaders/quatShader");
	
	ofxXmlSettings creditsXml;
	if(creditsXml.loadFile(GetCloudsDataPath() + "credits.xml")){
		creditsXml.pushTag("credits");
		
		int numCredits = creditsXml.getNumTags("credit");
		for(int i = 0; i < numCredits; i++){
			string justification = creditsXml.getAttribute("credit", "align", "left", i) ;
			ofVec3f pos( 0, 1000 + i * dim * 2.9, 0);
			if(justification == "left"){
				pos.x = -justificationWidth;
			}
			else if(justification == "right"){
				pos.x = justificationWidth;
			}else{} // center
			
			creditsXml.pushTag("credit", i);
			
			BalloonCredit bc;
			bc.title = (creditsXml.getValue("title", ""));
			bc.name = creditsXml.getValue("name", "");
			bc.pos = pos;
			bc.font = &font;
			bc.camera = &cloudsCamera;
			credits.push_back(bc);
			
			creditsXml.popTag(); //credit
		}
		creditsXml.popTag(); //credits
		
		for(int i=0; i<credits.size(); i++)
		{
			originalCreditPositions.push_back(credits[i].pos);
		}
	}
	else{
		ofLogError("Balloons") << "Couldn't load credits XML!";
		return;
	}
    
    creditPosition = 0;
}