Onedayitwillmake

NYC Programmer Mario Gonzalez's blog

Using EclipseLovesCinder template

About a year ago, I created a template to use the Cinder framework within Eclipse. I still use it all the time, as I still find Eclipse a better C++ editor (although xcode is slowly catching up if you use the compile and use the latest LLVM). I recently decided to revisit it and update it to better fit the workflow I prefer, and fix issues I’ve over time found work arounds for.

With that I decided that it was time to give some new instructions so here they are. I’ll revisit this post with more details, but if pictures are a 1000 words this is a pretty big post.

(more…)

Simple Example: Using Boost Signals with Cinder

The Observer pattern is a good way of simplifying the parts that need to know about each other, and be tied together in a complex program. Here’s how a simple how to of using Boost::Signals in a Cinder project.

One thing to note, is that we have to use ‘Signals2.hpp’ not ‘Signals.hpp’, because ‘Signals.hpp’ requires it be compiled before it is used, and can lead to compilation errors for some reason in a Cinder project.

HelloEclipse.cpp

/**
 * Mario Gonzalez
 * http://onedayitwillmake
 */
#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/Vector.h"
#include "cinder/app/MouseEvent.h"
#include "cinder/Rand.h"
#include "gl.h"
 
#include "Button.h"
#include "boost/bind.hpp"
 
class HelloWorldApp : public ci::app::AppBasic {
public:
	void setup();
	void prepareSettings( ci::app::AppBasic::Settings *settings );
	void mouseDown( ci::app::MouseEvent event );
	void update();
	void draw();
 
	// An imaginary button which contains the Signal
	Button button;
 
	// This will be the callback
	void onButtonWasClicked( Button* buttonInstance );
};
 
void HelloWorldApp::prepareSettings( ci::app::AppBasic::Settings *settings ) {
	settings->setWindowSize( 800, 600 );
}
 
void HelloWorldApp::setup() {
	// Get the signal instance
	// Use boost::bind, to bind our class's function, to our (this) specific instnace
	// _1 is a typedef for boost::arg - So we're creating a spot for the first argument in the function
	button.getSignal()->connect(boost::bind(&HelloWorldApp::onButtonWasClicked, this, _1));
}
 
void HelloWorldApp::mouseDown( ci::app::MouseEvent event ) {
	// Test it out, this should fire the signal
	button.clicked();
}
 
void HelloWorldApp::onButtonWasClicked( Button* buttonInstance ) {
	// Outputs: Button instance 'Button1' was pressed!
	std::cout << "Button instance '" << buttonInstance->getId() << "' was pressed!" << std::endl;
}
 
void HelloWorldApp::update() { }
void HelloWorldApp::draw() {
	// clear out the window with black
	ci::gl::clear( ci::Color( 0, 0, 0 ) );
}
 
CINDER_APP_BASIC( HelloWorldApp, ci::app::RendererGl )

Button.h – which will dispatch the signal

#ifndef BUTTON_H_
#define BUTTON_H_
 
#include <boost/signals2.hpp>
#include <iostream>
 
class Button {
public:
	// this typedef creates a simple shorthand, so that ButtonSignal refers to boost::signals2::signal<void( Button* )>
	// If you wanted you could use the long name instead, but its easier to typo
	typedef boost::signals2::signal<void( Button* )> ButtonSignal;
 
	Button();
	virtual ~Button();
	void clicked();
 
	// ACCESSORS
	std::string getId() { return _id; };
	ButtonSignal* getSignal() { return &_signal; }; // Notice we return a pointer to the signal
private:
	std::string _id;
	ButtonSignal    _signal;
};
 
#endif /* BUTTON_H_ */

Button.cpp

#include "Button.h"
#include "boost/bind.hpp"
 
Button::Button() {
	_id = "Button1";
}
 
Button::~Button() {
}
 
 
/**
 * Dispatch the event to all listeners
 */
void Button::clicked() {
	_signal( this );
}

If you wanted no arguments passed, simply remove the _1 parameter and change your method signatures accordingly. As you can guess, you could extrapolate it to have say five arguments by using boost::bind(&HelloWorldApp::onButtonWasClicked, this, _1, _2, _3, _4, _5)

That’s about it – not too hard after you figure out the ‘Signals2.hpp’ requirement

QuadDistrust

This is a project I recently created for an installation. It uses the kinect to place the user into a world that has many particles in it – and they basically interact with the particles which are also being influenced by some perlin noise.

It was a spin off of my previous project, CinderRibbons which I never finished because it was getting a little too out of hand.
For this project my goal was simple: Quads influenced by a 3d mapped human skeleton, and perlin noise
I figured that if i scaled down my previous goal, and made it something that was actually attainable i would actually be able to finish the project.

I also decided to put the project on Github, however the code inside is rather messy because as the installation deadline got closer I had to make some, ahem sacrifices. I was actually coding and changing it up until 1 minute before the performer started her dance, while my computer was already hooked up to the projector. That part was pretty frantic.

Here are some images, they are sort of in chronological order, sort of:

Initial “get something on the screen”

Creating a floor plane:


Making quads ‘rise’ from the floor plane

Now add some beautiful perlin noise (Actually this is simplex noise technically)

 

The view from above:

 

All hail the glowing cube:

 

User controlled gravity swarms using the kinect skeleton data mapped back into 3d space:

Project Source Code

https://github.com/onedayitwillmake/QuadDistrust

Debugging Cinder Application with EclipseLovesCinder template

Working on a project at work, and at at home is a good way to re-enforce processes needed to get up and running as well as exposing cracks in your setup.

In this case it was my Eclipse Loves Cinder template
I followed my own instructions to get Eclipse up and running with Cinder C++ framework.
Then I noticed when I went to debug i was not sure what to do.

I had set it up at home, but it was very much a trial and error excercise so once it finally functioned correctly – i was not sure exactly what it was that I did that got it to work.

EclipseLovesCinder after running a build, executes a python script which creates an “Application Bundle” for your application so it looks and feels more like an OSX Application. Copying all files from ‘resources’ into the application’s resources bundle, if they have been modified since last time or did not exist.

An ApplicationBundle is actually just a collection of folders following a specific structure, this page helped me figure out how to create one http://www.eclipse.org/swt/macosx/

The second problem was getting debug to work which is probably as important as being able to create the application otherwise – good luck making anything besides HelloWorld.

Getting GDB (Debugger) to work:

  • Select the debug, bug icon and – actually select the little arrow next to it.
  • Select Debug Configurations
  • Select C/C++ Application and click the “new” icon (looks like paper)
  • Where it shows the application under "C / C++ Application" select browse, and browse to “bin/HelloEclipse.app"
  • Append Contents/MacOS/HelloEclipse at the end of that, because eclipse actually wants the binary not the psuedo-application directory

After that, you should be able to select debug, and if it worked it will stop on a break point at the launch of Main.
You can turn that off if you like, sometimes i do, by going to the “Debugger” tab in the options.

While a bit tedious – you only have to do it once so it’s not so bad.

Here’s the result of hitting a breakpoint. Callstack on the left, variables on the right.
debugger

Using Eclipse with Cinder – A better c++ editor

I was really having a hard time with Xcode lately, specifically how its C++ code-completion leaves much to be desired especially if you have a very bad memory. I find myself constantly painfully looking through the header files to find the exact name/case of a function or property.

So I decided to try and see If i could get up and running with Cinder in Eclipse instead, it wasn’t too bad either !!! Just a couple of issues getting the linking right, but that was about it.

Download / Github


Xcode is a great IDE, however it is not great at C++ editing

It provides only very barebones syntax highlighting, even more barebones code completion, and no edit-time error checking.

Cinder is a great library, but it’s very vast – Without code-completion I was very lost/ nearly all the time poking through the header files and opening the .cpp files in other editors so I could learn it more thouroughly.

(Re)-Enter EclipseIDE for C++

This project is presented as is for anyone else who would like to use a C++ editor on osx that is actually aware of your classes.
From what I’ve used it so far, it is much better – but compile times are a little slower, however the time you save while editing is well worth it imo.

Usage

  1. http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliossr2
  2. Download this project
  3. Import into eclipse workspace (select import existing project in the ‘general’ drop down)
  4. In terminal browse to the projects path and create a symbolic link named ‘CINDER_PATH_LINK’ to where cinder is located
    1. “ln -s foo/bar CINDER_PATH_LINK”
    2. Where ‘foo/bar’ is the path to Cinder such as ‘~/GIT/LIBRARY/CINDER’
  5. [Optional] – RightClick project root, select properties
    1. Select C/C++ Build
    2. Select Settings
    3. Replace ‘g++’ with ‘clang++’ and ‘gcc’ with ‘clang’ for the:
      • MacOS X C++ Linker
      • GCC C++ Compiler
      • GCC C Compiler
    • [Optional] Do the same for the discovery tab
  6. After hitting, apply/ok and closing that window select Project->Build All and project should build successfully.

Screenshots

Debugger / Hitting a breakpoint

Editor

OpenNIStarterKit Block

Editor

Better syntax highlighting, and code sense

Editor

Cinder + threaded OpenNI Skeletontracking

Here is some stuff I’ve put together that does Skeletontracking via OpenNI on a separate thread in cinder.
This is based on some code that was posted by Sector9 on the cinder forums, and which is based on the example code that comes with the Nite module.

For some reason my skeleton is offset by some seemingly random number. I’m not sure what’s causing that if someone could take a look
https://github.com/onedayitwillmake/CinderOpenNIBarebones

In order to get this to work, you’ll need to get OpenNI working on it’s own first.
I recommend following these steps, http://c4c.posterous.com/installing-openni-kinect-drivers-and-nite-on

PostADay-Round2#4 – Cinder Kinect OpenNI – Playing and seeking a .oni file

I’ve been using the Kinect for the past two weeks. It’s an amazing device, very fun to code for.
To be honest, the Kinect really provides a webcam image, and a depth map… That’s really all it adds to the mix. While that’s a lot – people (by that i mean gadget blogs, non-coder blogs) seem to think that you can just plug this thing and you will get instant Minority Report.

That’s not how it works, in fact the REAL magic of the kinect is the OpenNI drivers provided by Primesense. Primesense are the people who created the technology which microsoft has licensed. Their OpenNI drivers provide the amazing skeleton tracking / user tracking / hand tracking / gesture tracking stuff that people associate with the Kinect.

When trying to create something using the Kinect it can be somewhat annoying having to get up, calibrate it with the proper use, and then start moving around to test a variable you changed. For that reason, the OpenNI library provides a way to record, and also create files which it calls “.oni”

The easiest way to create your own .oni file, is to record one with the NIViewer sample project. However just as useful if that’s too annoying, is the skeleton.oni file provided by primesense.

These files can actually then be played by the the library, and you can even seek within them to skip around to the interesting parts you want to test.

Here’s how to play back a .oni file, it’s actually very simple. This file makes some assumptions but i’ll explain those later.

void CinderRibbons::setupWithOniFile( std::string filepath ) {
  nRetVal = skeleton->mContext.OpenFileRecording( filepath.c_str() );
		// File opened
		CHECK_RC(nRetVal, "Open File Recording", true);
 
		// Get recording 'player'
		nRetVal = skeleton->mContext.FindExistingNode(XN_NODE_TYPE_PLAYER, skeleton->mPlayer);
		CHECK_RC(nRetVal, "Find player generator", true);
}
void CinderRibbons::seekToFrame( XnUInt32 seekPosition )
{
	CinderOpenNISkeleton *skeleton = CINDERSKELETON;
	XnStatus nRetVal = XN_STATUS_OK;
 
	skeleton-&gt;debugOutputNodeTypes();
 
    // Make sure we're ready
	if(!openNIThread || !skeleton-&gt;mDepthGenerator)
		return;
 
	const XnChar*	nodeName		= skeleton-&gt;mDepthGenerator.GetName();
	XnUInt32		currentFrame	= 0;
	XnUInt32		totalFames		= 0;
 
	nRetVal = skeleton-&gt;mPlayer.TellFrame(nodeName, currentFrame);
	CHECK_RC(nRetVal, "Getting CURRENT frame", false);
 
	nRetVal = skeleton-&gt;mPlayer.GetNumFrames(nodeName, totalFames);
	CHECK_RC(nRetVal, "Getting TOTAL frames", false);
 
	// Stop the thread before trying to seek
	openNIThread-&gt;stop();
 
    // We'll be offset currentFrame and passing this value to the seek funciton which takes a relative position
    XnUInt32        seekAbsolutePos = -currentFrame + seekPosition;
 
    // Seek
	nRetVal = skeleton-&gt;mPlayer.SeekToFrame(nodeName, seekAbsolutePosition, XN_PLAYER_SEEK_CUR);
	CHECK_RC(nRetVal, "Seeking to frame", false);
 
	// Update the data now that we're at the new position
	skeleton-&gt;mDepthGenerator.GetMetaData( skeleton-&gt;mDepthMD );
	skeleton-&gt;mUserGenerator.GetUserPixels(0, skeleton-&gt;mSceneMD);
 
	// Restart the thread...
	// Thread count stays the same - but there is a race condition on a nanoscale
	// Had some problems, will have to look into later - for now we're creating a new thread.
	openNIThread = new OpenNIThreadRunner();
	openNIThread-&gt;go();
 
	// Output debug
	app::console() &lt;&lt; "Seeked to frame" &lt;&lt; currentFrame+seekPosition &lt;&lt; std::endl;
}

PostADay-Round2#2 – Cinder/C++ Boid class port

It’s weird porting something that was written into, c++ ported to AS3, back to C++. However If you’ve ever tried to find the C++ version of a boids class. They’re all too complicated for my needs, and i really like the way @soulwire ‘s version works so I started porting it into C++. Based largely on my iOS port of the same class.

https://github.com/onedayitwillmake/CinderBoid

VIDEO DEMOS

WanderSeek

BoidTrailTest from mario gonzalez on Vimeo.

Basic Usage

.cpp

Creation

 
<code>
float boidMaxSpeed = 100;
float boidMaxForce = 25;
 
// Create
_boid = new Boid( boidMaxSpeed, boidMaxForce );
_boid-&gt;setPosition( _target.x, _target.y, _target.z );
 
// Set wander properties
_boid-&gt;setWanderRadius( 75.0f );
_boid-&gt;setWanderMaxTurningSpeed( M_PI / 32 ); // 
_boid-&gt;setWanderLookAheadDistance( 300 );
 
</code>

Update



_boid->wander( 0.3f );
_boid->seek( _mousePositionXYZ, 0.8f );
_boid->update();



PostADay-Round2#1 – Calculating surface normals in C++

Given a quad, this is how you can calculate the normals for each face.
This works for triangles, as well as quad.

Loop through each face, and pass in 3 verticies. If you have a quad ABCD pass in ABD. For example for the front facing face on this cube, I would pass in, v2, v3, v0

// cube ///////////////////////////////////////////////////////////////////////
//    v6----- v5
//   /|      /|
//  v1------v0|
//  | |     | |
//  | |v7---|-|v4
//  |/      |/
//  v2------v3

This is in C++ which supports operator overloading, so keep that in mind, when you see p2-p1, its doing: (p2.x-p1.x; p2.y-p1.y; p2.z-p1.z; )

// 
Vec3f RibbonMesh::calcNormal( const Vec3f &p1, const Vec3f &p2, const Vec3f &p3 )
{
    Vec3f V1= (p2 - p1);
    Vec3f V2 = (p3 - p1);
    Vec3f surfaceNormal;
    surfaceNormal.x = (V1.y*V2.z) - (V1.z-V2.y);
    surfaceNormal.y = - ( (V2.z * V1.x) - (V2.x * V1.z) );
    surfaceNormal.z = (V1.x-V2.y) - (V1.y-V2.x);
 
 
    // Dont forget to normalize if needed
    return surfaceNormal;
}