Skip to content

Instantly share code, notes, and snippets.

@paulhoux
Last active December 22, 2015 08:09
Show Gist options
  • Save paulhoux/6443497 to your computer and use it in GitHub Desktop.
Save paulhoux/6443497 to your computer and use it in GitHub Desktop.
Example of how to place objects at the surface of a sphere with the correct axes. Created in response to https://forum.libcinder.org/#Topic/23286000001779023 .
#include "cinder/app/AppNative.h"
#include "cinder/gl/gl.h"
#include "cinder/Camera.h"
#include "cinder/MayaCamUI.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class PointOnSphereApp : public AppNative {
public:
void setup();
void update();
void draw();
void resize();
void mouseDown( MouseEvent event );
void mouseDrag( MouseEvent event );
private:
CameraPersp mCamera;
MayaCamUI mMayaCam;
};
void PointOnSphereApp::setup()
{
// initialize our camera
mCamera.setEyePoint( Vec3f(0.f, 0.f, -400.f) );
mCamera.setCenterOfInterestPoint( Vec3f(0.f, 0.f, 0.f) );
}
void PointOnSphereApp::update()
{
// nothing to update
}
void PointOnSphereApp::draw()
{
// clear the window
gl::clear();
// enable depth buffer and setup camera
gl::enableDepthRead();
gl::enableDepthWrite();
gl::setMatrices( mCamera );
// draw our 'shapes'
gl::color( Color::white() );
float radius = 100.0f;
for(int longitude=-180; longitude<180; longitude+=20)
{
for(int latitude=-80; latitude<=80; latitude+=20)
{
Matrix44f transform;
// turn according to position on Earth
transform.rotate( Vec3f(0.0f, toRadians((float)longitude), 0.0f) );
transform.rotate( Vec3f(toRadians((float)-latitude), 0.0f, 0.0f) );
// place on surface of Earth
transform.translate( Vec3f(0.0f, 0.0f, radius) );
// now that we have constructed our transform matrix,
// multiply the current modelView matrix with it
gl::pushModelView();
gl::multModelView( transform );
// now we can simply draw something at the origin,
// as if we haven't rotated at all
gl::drawCoordinateFrame(10.f, 1.f, 1.f);
// restore the modelView matrix to undo the transformation,
// so it doesn't interfere with the next shape
gl::popModelView();
}
}
// draw a translucent black sphere to make the shapes at the back appear darker
gl::color( ColorA(0, 0, 0, 0.8f) );
gl::enableAlphaBlending();
gl::enable( GL_CULL_FACE );
gl::drawSphere( Vec3f::zero(), radius, 60 );
gl::disable( GL_CULL_FACE );
gl::disableAlphaBlending();
// disable depth buffer
gl::disableDepthRead();
gl::disableDepthWrite();
}
void PointOnSphereApp::resize()
{
// adjust the camera's aspect ratio if the window resizes
mCamera.setAspectRatio( getWindowAspectRatio() );
}
void PointOnSphereApp::mouseDown( MouseEvent event )
{
// use the maya camera helper to control our camera
mMayaCam.setCurrentCam( mCamera );
mMayaCam.mouseDown( event.getPos() );
}
void PointOnSphereApp::mouseDrag( MouseEvent event )
{
// use the maya camera helper to control our camera
mMayaCam.mouseDrag( event.getPos(), event.isLeftDown(), event.isMiddleDown(), event.isRightDown() );
mCamera = mMayaCam.getCamera();
}
CINDER_APP_NATIVE( PointOnSphereApp, RendererGl )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment