Skip to content

Instantly share code, notes, and snippets.

@drewish
Created August 5, 2014 02:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drewish/23af9aa1198ba4dcb2fa to your computer and use it in GitHub Desktop.
Save drewish/23af9aa1198ba4dcb2fa to your computer and use it in GitHub Desktop.
trying to figure out cinder screenToWorld
#include "cinder/app/AppNative.h"
#include "cinder/gl/gl.h"
#include "cinder/Camera.h"
#include "cinder/params/Params.h"
using namespace ci;
using namespace ci::app;
using namespace std;
#define SQRT_3_2 0.8660254037844386
class TrianglePaintApp : public AppNative {
public:
void setup();
void resize();
void mouseDown( MouseEvent event );
void update();
void draw();
void drawGrid( float size, float unit = 50 );
Vec2f convert( int r, int g, int b, float unit = 50 );
Vec2f worldFromScreen( Vec2i xy );
cinder::CameraPersp mCam;
int mR = 1;
int mG = 0;
int mB = -1;
Vec2f touched = Vec2f::zero();
params::InterfaceGl mParams;
};
void TrianglePaintApp::setup()
{
mParams = params::InterfaceGl( "Parameters", Vec2i( 220, 170 ) );
mParams.addParam( "R", &mR, "keyIncr=R keyDecr=r" );
mParams.addParam( "G", &mG, "keyIncr=G keyDecr=g" );
mParams.addParam( "B", &mB, "keyIncr=B keyDecr=b" );
mParams.addParam( "X", &touched.x, true );
mParams.addParam( "Y", &touched.y, true );
}
// Replicate most of the defaultResize so we get a reference to the camera
// for converting screen to world.
void TrianglePaintApp::resize()
{
Vec2i size = getWindowSize();
mCam = cinder::CameraPersp( size.x, size.y, 60.0f );
mCam.lookAt( Vec3f( 0.0f, 0.0f, 400.0f ), Vec3f::zero(), Vec3f::yAxis() );
gl::setMatrices( mCam );
// Invert Y axis so increasing Y goes down.
glScalef( 1.0f, -1.0f, 1.0f );
}
void TrianglePaintApp::mouseDown( MouseEvent event )
{
touched = worldFromScreen(Vec2i(event.getX(), event.getY()));
console() << touched << endl;
}
void TrianglePaintApp::update()
{
mB = - (mR + mG);
}
void TrianglePaintApp::draw()
{
int step = 50;
gl::pushModelView();
gl::clear( Color::white() );
drawGrid( 500, step);
// Origin
gl::color( Colorf(1.0f, 0.0f, 0.0f) );
gl::drawSolidCircle(Vec2f::zero(), 10);
// Mover
gl::color( Colorf(0.0f, 0.0f, 0.0f) );
gl::drawSolidCircle(convert(mR, mG, mB, step), 10);
gl::popModelView();
mParams.draw();
}
void TrianglePaintApp::drawGrid( float size, float unit )
{
gl::pushModelView();
float step = unit * SQRT_3_2;
gl::rotate(30);
gl::color( ColorAf(0.7, 0, 0, 0.3f) );
for ( float i = -size * step; i <= size * step; i += step ) {
gl::drawLine( Vec2f(-size, i), Vec2f(size, i) );
}
gl::drawSolidTriangle(Vec2f(unit, 0), Vec2f(unit * 0.8, unit * -0.2), Vec2f(unit * 0.8, unit * 0.2));
gl::rotate(120);
gl::color( ColorAf(0, 0.7, 0, 0.3f) );
for ( float i = -size * step; i <= size * step; i += step ) {
gl::drawLine( Vec2f(-size, i), Vec2f(size, i) );
}
gl::drawSolidTriangle(Vec2f(unit, 0), Vec2f(unit * 0.8, unit * -0.2), Vec2f(unit * 0.8, unit * 0.2));
gl::rotate(120);
gl::color( ColorAf(0, 0, 0.7, 0.3f) );
for ( float i = -size * step; i <= size * step; i += step ) {
gl::drawLine( Vec2f(-size, i), Vec2f(size, i) );
}
gl::drawSolidTriangle(Vec2f(unit, 0), Vec2f(unit * 0.8, unit * -0.2), Vec2f(unit * 0.8, unit * 0.2));
gl::rotate(120);
gl::popModelView();
}
// RGB to XY
Vec2f TrianglePaintApp::convert( int r, int g, int b, float unit )
{
// Should throw or something?
if ( r + g + b != 0 ) return Vec2f::zero();
// FLAT TOP
// The slope of of the Green axis to X and inverted Y axis:
// 120 degree is -1/2, sqrt(3)/2,
// Vec2f vr = Vec2f(r, 0);
// Vec2f vg = Vec2f(-0.5f * g, SQRT_3_2 * g);
// POINTY TOP
// Red is 330 degrees
Vec2f vr = Vec2f(SQRT_3_2 * r, 0.5f * r);
// Green is 210 degrees
Vec2f vg = Vec2f(-SQRT_3_2 * g, 0.5f * g);
// Blue is 90 degrees (up)
//Vec2f vb = Vec2f(0, -b * 1.0f);
return unit * (vr + vg);
}
Vec2f TrianglePaintApp::worldFromScreen( Vec2i pos )
{
// generate a ray from the camera into our world
float u = pos.x / (float) getWindowWidth();
float v = pos.y / (float) getWindowHeight();
// because OpenGL and Cinder use a coordinate system
// where (0, 0) is in the LOWERleft corner, we have to flip the v-coordinate
Ray ray = mCam.generateRay(u , 1.0f - v, mCam.getAspectRatio() );
float result = 0.0f;
Vec3f planePos = mCam.getCenterOfInterestPoint();
Vec3f normal = mCam.getViewDirection();
if ( ray.calcPlaneIntersection( planePos, normal, &result ) ) {
return ray.calcPosition( result ).xy();
}
return Vec2f::zero();
}
CINDER_APP_NATIVE( TrianglePaintApp, RendererGl )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment