Skip to content

Instantly share code, notes, and snippets.

@axjxwright
Created January 7, 2016 01:34
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 axjxwright/d28e3dfde355297214a4 to your computer and use it in GitHub Desktop.
Save axjxwright/d28e3dfde355297214a4 to your computer and use it in GitHub Desktop.
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Rand.h"
#include "cinder/Camera.h"
#include "cinder/CameraUi.h"
#include "cinder/ip/Checkerboard.h"
using namespace ci;
using namespace ci::app;
using namespace std;
struct Quad
{
vec3 position;
vec3 scale;
quat rotation;
mat4 transform;
mat4 inverseTransform;
vec3 normal;
vec3 a, b, c, d;
vec2 hitPosition;
Quad ( const vec3& p, const vec3& s, const quat& r )
: position(p)
, scale(s)
, rotation(r)
{
transform = glm::translate(p) * toMat4(r) * glm::scale(s);
inverseTransform = glm::inverse ( transform );
normal = glm::normalize ( vec3 ( transform * vec4 ( 0, 0, 1, 0 ) ) );
a = vec3 ( transform * vec4 ( -0.5, -0.5, 0, 1 ) );
b = vec3 ( transform * vec4 ( 0.5, -0.5, 0, 1 ) );
c = vec3 ( transform * vec4 ( 0.5, 0.5, 0, 1 ) );
d = vec3 ( transform * vec4 ( -0.5, 0.5, 0, 1 ) );
}
bool intersectsRay ( const Ray& ray, vec3& result )
{
float r = 0.0f;
if ( ray.calcTriangleIntersection ( a, b, c, &r ) )
{
result = ray.calcPosition(r);
hitPosition = vec2 ( inverseTransform * vec4 ( result, 1.0f ) );
return true;
}
if ( ray.calcTriangleIntersection ( a, d, c, &r ) )
{
result = ray.calcPosition(r);
hitPosition = vec2 ( inverseTransform * vec4 ( result, 1.0f ) );
return true;
}
return false;
}
};
class QuadsApp : public App
{
public:
static void init ( App::Settings * settings );
void setup ( ) override;
void draw ( ) override;
void rayCast ( const MouseEvent& event );
std::vector<Quad> _quads;
gl::BatchRef _quadBatch;
CameraPersp _camera;
CameraUi _camUi;
int _hitIndex{-1};
gl::TextureRef _texture;
};
void QuadsApp::init ( App::Settings * settings )
{
settings->setWindowSize ( 1280, 720 );
}
void QuadsApp::setup()
{
for ( uint32_t i = 0; i < 100; i++ )
{
vec3 pos = vec3{Rand::randFloat(-1, 1), Rand::randFloat(-1, 1), Rand::randFloat(-1, 1)} * 300.0f;
vec3 scale = vec3{Rand::randFloat(0.01, 1), Rand::randFloat(0.01, 1), Rand::randFloat(0.01, 1)} * 100.0f;
quat rot = glm::normalize(quat{Rand::randFloat(-1, 1), Rand::randFloat(-1, 1), Rand::randFloat(-1, 1), Rand::randFloat(-1, 1)});
_quads.emplace_back(pos, scale, rot);
}
getWindow()->getSignalMouseDown().connect( std::bind ( &QuadsApp::rayCast, this, std::placeholders::_1 ) );
_camera = CameraPersp ( getWindowWidth(), getWindowHeight(), 60.0f, 0.1f, 10000.0f );
_camera.lookAt(vec3(0), vec3(0, 0, 1));
_camUi = CameraUi ( &_camera, getWindow() );
_texture = gl::Texture::create ( ip::checkerboard( 128, 128 ) );
_quadBatch = gl::Batch::create( geom::Rect().rect( Rectf ( -0.5, -0.5, 0.5, 0.5 ) ), gl::getStockShader( gl::ShaderDef().color().texture() ) );
}
void QuadsApp::rayCast ( const MouseEvent& event )
{
// Should probably sort quads by distance to the camera.
vec2 uv = vec2(event.getPos()) / vec2(getWindowSize());
Ray r = _camera.generateRay(uv.x, 1.0f - uv.y, getWindowAspectRatio());
_hitIndex = -1;
int counter = 0;
for ( auto& q : _quads )
{
vec3 hit;
if ( q.intersectsRay( r, hit ) )
{
if ( _camera.worldToEye(hit).z < 0.0f ) // in front
{
_hitIndex = counter;
break;
}
}
counter++;
}
}
void QuadsApp::draw()
{
gl::clear( Color( 0, 0, 0 ) );
gl::setMatrices(_camera);
int counter = 0;
for ( auto& q : _quads )
{
bool isSelection = _hitIndex == counter;
Color c = isSelection ? Colorf(1, 0, 0) : Colorf::white();
gl::ScopedColor color(c);
gl::ScopedModelMatrix m;
gl::ScopedTextureBind tex0(_texture);
gl::setModelMatrix(q.transform);
_quadBatch->draw();
if ( isSelection )
{
gl::ScopedColor color(Colorf(0, 0, 1));
gl::drawSolidRect( Rectf ( q.hitPosition - vec2(0.03), q.hitPosition + vec2(0.03) ) );
}
counter++;
}
}
CINDER_APP( QuadsApp, RendererGl, QuadsApp::init )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment