Animating text in 3D within OF?


#1

Hey there guys,

I have been thinking about this as an idea for a while but haven’t found any concrete documentation on the subject so thought I would ask. My skill level is average but I have a handle on the basics of the syntax and object orientated programming. I’m making this thread to help myself collate resources, help others looking for similar material and also hopefully get some advice from experienced members.

//-------------------------------------

I’d like to start a series of sketches using 3D animated text.

The idea is text rotating around the surface of a 3D cylinder , or a 3d cube etc while maintaining perspective and foreshortening.

I’ve used processing, P3D for some experiments but never with the level of accuracy I’d like and not really following an exact path. I thought OF might be a more robust tool to attempt this.
Using processing it was a case of initializing P3D in size, then rotating the text on the z axis which made it spin in a 3d fashion from a center point. Really Id like it if the text would almost rotate as a cylinder or box would.

Could anybody offer any initial insights into animating text in 3D within OF? Any advice or ideas, links etc would be amazing. If I can muddle it out I’ll make a guide for the community or an Example Project. In the mean time I’ll keep this post updated with relevant links and a resources that could be of use to somebody else in the future.

Potentially useful resources: All Credit to the originator of these links.
( Although I’m not fully aware of the processes to make these animations happen and whether these resources have now become obsolete with OF updates).

  1. ofxaddons website. Typography and Animation each have sub sections.

I’ll be having a good search through the existing addons to see if there is anything that encompasses text animation.

  1. https://github.com/companje/ofxArcText by Companje

  2. https://github.com/AmnonOwed/OF_GenerativeTypography by AmnonOwed

  3. OF Examples folder under Graphics there is a few font examples also but none animating text in 3d.

Many Thanks!
Josh


#2

Hi Josh, if you just want flat letters, meaning that these have no volume, like a ribbon that is in 3D space, then the easiest might be to just render the text into an fbo and the use that fbo as a texture for a cylinder or cube as you mention.
so for instance you could do:
ofApp.h

#pragma once

#include "ofMain.h"

class ofApp : public ofBaseApp{
public:
		void setup();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);

	
	
	ofTrueTypeFont font;
	ofFbo fbo;
	ofEasyCam cam;

	string text;
	
	ofCylinderPrimitive cylinder;
	
	void renderText();
	
};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

	font.load("Helvetica", 32);
	
	fbo.allocate(ofGetWidth(), ofGetHeight());

	text = "Type something in the keyboard.\nDelete with backspace.\nNew line with return";
	renderText();
	
	cylinder.set(300, 500, 100, 1, 2, false);
	cylinder.mapTexCoordsFromTexture(fbo.getTexture());
	
}
//--------------------------------------------------------------
void ofApp::draw(){

	fbo.draw(0,0);
	cam.begin();
	fbo.getTexture().bind();
	ofEnableDepthTest();
	cylinder.draw();
	ofDisableDepthTest();
	fbo.getTexture().unbind();
	cam.end();
}

//--------------------------------------------------------------
void ofApp::renderText(){
	fbo.begin();
	ofClear(0, 0, 0, 255);
	ofSetColor(255);
	font.drawString(text, 20, 50);
	fbo.end();
}

//--------------------------------------------------------------
void ofApp::keyPressed(int key){
	if(key == OF_KEY_BACKSPACE){
		if(text.size()){
			text.pop_back();
		}
	}else if(key == OF_KEY_RETURN){
		text += "\n";
	}else{
		text += key;
	}
	renderText();
}

//--------------------------------------------------------------
void ofApp::keyReleased(int key){

}

you can use any other 3d primitive instead of the cylinder, and as these inherit from ofNode it is really easy to move them around without worrying about the transformations and so.
If this is not what you want you can instead of drawing the string using font.drawString(...) you can get the ofPaths that make the string with

vector<ofPath> paths = font.getStringAsPoints(text);
for(int i = 0; i < paths.size(); i ++){
     ofMesh m = paths[i].getTessellation();
//then here modify the z value of each mesh however you might want to, but it will require some maths.
    m.draw();
}

hope this helps. cheers


#3

Hey there Roy,

Thanks so much for your reply, your code is excellent and definitely a step towards what I had envisioned.

After studying some computer vision stuff with ps3Eye, only now am I looking into 3D so I’ll check out more of the Node documentation. I also haven’t learnt a great deal about mesh either so that’s another excellent point of reference I didn’t know much about before. I’ve been trying to figure out how to make this work for a while and now I feel it’ll be able to make some good progress. I really appreciate the reply :).

As I develop my code and the project, learn a bit more about Node and Mesh, I will keep this thread updated. I hope this can become a collection of documentation and ideas to make OF animated Text more accessible to beginner users.

Thanks again!

All the best,
Josh


#4

hi Josh, no problem.
Just in case, the ofBook has some really good stuff and it covers the meshes. you should take a look at it.

https://openframeworks.cc/ofBook/chapters/openGL.html
https://openframeworks.cc/ofBook/chapters/generativemesh.html

chhers


#5

Thanks for those links! I was having a read earlier, both seem great but will require a bit of study I think.

Here is some additional code / info that Roy shared to help work towards 3D text animation. I’ll share that info in this post. All credit to him obviously!

//---------------------------------------------------

Hi there Roy,

Once again I’d like to thank you for your advice on figuring out how to figure out 3D text animation.
The FBO was a a good idea and works pretty well. From there do you think I would be able to make an array of the object and have them rotating differently?

If you have some spare time check out the work of this artist. Its something like this although more basic that I would like to achieve :

The animations are pretty advanced but I’d like to be able to reverse engineer something similar, if possible in open frameworks. Do you think this kind of work could be produced with open Frameworks?

All the best,
Josh

//------------------------------------------------------------

Hey. No problem.
It is better if you put this kind of questions in the forum,as it could be useful to others.
At least that artist is tagging with openframeworks his posts so I guess that he has used it.
Yes, you can create more objects, it should be straight forwards.
You can move the texcoords of the texture to “Slide” the texture over the shape.
put the following to the previous code I shared.

in the ofApp.h file put

std::vector<glm::vec2> texCoords;

in ofApp.cpp file
at the end of ofApp::setup():

	texCoords =  cylinder.getMesh().getTexCoords();

at the beginning of ofApp::draw()

	for(int i = 0; i < texCoords.size(); i++){
		cylinder.getMesh().setTexCoord(i, texCoords[i] + glm::vec2(ofGetMouseX(),0));
	}

Also, when using the cylinder, you can specify that it has less sections, so you can create an hexagon, for instance.
cylinder.set(300, 500, 6, 1, 2, false); the third parameter is how many faces the cylinder will have.
Check zack liebermans github he has a lot of good stuff about animation and typography.
hope this helps.
cheers

//-----------------------------------------------------------