Created
August 5, 2014 02:51
-
-
Save drewish/23af9aa1198ba4dcb2fa to your computer and use it in GitHub Desktop.
trying to figure out cinder screenToWorld
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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