Cinder  0.8.6
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
Arcball.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2010, The Barbarian Group
3  All rights reserved.
4 
5  Redistribution and use in source and binary forms, with or without modification, are permitted provided that
6  the following conditions are met:
7 
8  * Redistributions of source code must retain the above copyright notice, this list of conditions and
9  the following disclaimer.
10  * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
11  the following disclaimer in the documentation and/or other materials provided with the distribution.
12 
13  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
15  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
16  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
17  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
18  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
19  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20  POSSIBILITY OF SUCH DAMAGE.
21 */
22 
23 #pragma once
24 
25 #include "cinder/Quaternion.h"
26 #include "cinder/Vector.h"
27 
28 namespace cinder {
29 
30 class Arcball {
31  public:
33  {
35  mCurrentQuat = mInitialQuat = Quatf::identity();
36  }
37  Arcball( const Vec2i &aScreenSize )
38  : mWindowSize( aScreenSize )
39  {
40  setCenter( Vec2f( mWindowSize.x / 2.0f, mWindowSize.y / 2.0f ) );
41  mRadius = std::min( (float)mWindowSize.x / 2, (float)mWindowSize.y / 2 );
43  mCurrentQuat = mInitialQuat = Quatf::identity();
44  }
45 
46  void mouseDown( const Vec2i &mousePos )
47  {
48  mInitialMousePos = mousePos;
49  mInitialQuat = mCurrentQuat;
50  }
51 
52  void mouseDrag( const Vec2i &mousePos )
53  {
54  Vec3f from = mouseOnSphere( mInitialMousePos );
55  Vec3f to = mouseOnSphere( mousePos );
56  if( mUseConstraint ) {
57  from = constrainToAxis( from, mConstraintAxis );
58  to = constrainToAxis( to, mConstraintAxis );
59  }
60 
61  Vec3f axis = from.cross( to );
62  mCurrentQuat = mInitialQuat * Quatf( from.dot( to ), axis.x, axis.y, axis.z );
63  mCurrentQuat.normalize();
64  }
65 
66  void resetQuat() { mCurrentQuat = mInitialQuat = Quatf::identity(); }
67  Quatf getQuat() { return mCurrentQuat; }
68  void setQuat( const Quatf &quat ) { mCurrentQuat = quat; }
69 
70  void setWindowSize( const Vec2i &aWindowSize ) { mWindowSize = aWindowSize; }
71  void setCenter( const Vec2f &aCenter ) { mCenter = aCenter; }
72  Vec2f getCenter() const { return mCenter; }
73  void setRadius( float aRadius ) { mRadius = aRadius; }
74  float getRadius() const { return mRadius; }
75  void setConstraintAxis( const Vec3f &aConstraintAxis ) { mConstraintAxis = aConstraintAxis; mUseConstraint = true; }
76  void setNoConstraintAxis() { mUseConstraint = false; }
77  bool isUsingConstraint() const { return mUseConstraint; }
78  Vec3f getConstraintAxis() const { return mConstraintAxis; }
79 
80  Vec3f mouseOnSphere( const Vec2i &point ) {
81  Vec3f result;
82 
83  result.x = ( point.x - mCenter.x ) / ( mRadius * 2 );
84  result.y = ( point.y - mCenter.y ) / ( mRadius * 2 );
85  result.z = 0.0f;
86 
87  float mag = result.lengthSquared();
88  if( mag > 1.0f ) {
89  result.normalize();
90  }
91  else {
92  result.z = math<float>::sqrt( 1.0f - mag );
93  result.normalize();
94  }
95 
96  return result;
97  }
98 
99  private:
100  // Force sphere point to be perpendicular to axis
101  Vec3f constrainToAxis( const Vec3f &loose, const Vec3f &axis )
102  {
103  float norm;
104  Vec3f onPlane = loose - axis * axis.dot( loose );
105  norm = onPlane.lengthSquared();
106  if( norm > 0.0f ) {
107  if( onPlane.z < 0.0f )
108  onPlane = -onPlane;
109  return ( onPlane * ( 1.0f / math<float>::sqrt( norm ) ) );
110  }
111 
112  if( axis.dot( Vec3f::zAxis() ) < 0.0001f ) {
113  onPlane = Vec3f::xAxis();
114  }
115  else {
116  onPlane = Vec3f( -axis.y, axis.x, 0.0f ).normalized();
117  }
118 
119  return onPlane;
120  }
121 
122  Vec2i mWindowSize;
123  Vec2i mInitialMousePos;
124  Vec2f mCenter;
125  Quatf mCurrentQuat, mInitialQuat;
126  float mRadius;
127  Vec3f mConstraintAxis;
128  bool mUseConstraint;
129 };
130 
131 } // namespace cinder
void setQuat(const Quatf &quat)
Definition: Arcball.h:68
static T sqrt(T x)
Definition: CinderMath.h:63
Quatf getQuat()
Definition: Arcball.h:67
void resetQuat()
Definition: Arcball.h:66
T lengthSquared() const
Definition: Vector.h:443
Definition: CinderMath.h:40
void setConstraintAxis(const Vec3f &aConstraintAxis)
Definition: Arcball.h:75
Vec3f mouseOnSphere(const Vec2i &point)
Definition: Arcball.h:80
T dot(const Vec3< T > &rhs) const
Definition: Vector.h:418
void normalize()
Definition: Vector.h:484
Vec2< float > Vec2f
Definition: Vector.h:1314
T z
Definition: Vector.h:321
T x
Definition: Vector.h:321
static Quaternion< float > identity()
Definition: Quaternion.h:733
T x
Definition: Vector.h:71
T y
Definition: Vector.h:321
bool isUsingConstraint() const
Definition: Arcball.h:77
void setCenter(const Vec2f &aCenter)
Definition: Arcball.h:71
#define min(a, b)
Definition: AppImplMsw.cpp:36
Vec3< float > Vec3f
Definition: Vector.h:1317
void mouseDrag(const Vec2i &mousePos)
Definition: Arcball.h:52
void setWindowSize(const Vec2i &aWindowSize)
Definition: Arcball.h:70
Quaternion< float > Quatf
Definition: Quaternion.h:774
float getRadius() const
Definition: Arcball.h:74
Vec2f getCenter() const
Definition: Arcball.h:72
void normalize()
Definition: Quaternion.h:125
void setNoConstraintAxis()
Definition: Arcball.h:76
Definition: Arcball.h:30
T y
Definition: Vector.h:71
Vec3< T > cross(const Vec3< T > &rhs) const
Definition: Vector.h:423
static Vec3< float > xAxis()
Definition: Vector.h:683
Vec3f getConstraintAxis() const
Definition: Arcball.h:78
void mouseDown(const Vec2i &mousePos)
Definition: Arcball.h:46
Arcball()
Definition: Arcball.h:32
Arcball(const Vec2i &aScreenSize)
Definition: Arcball.h:37
GLclampf f
Definition: GLee.h:15307
void setRadius(float aRadius)
Definition: Arcball.h:73
Vec2< int > Vec2i
Definition: Vector.h:1313
Vec3< T > normalized() const
Definition: Vector.h:492
static Vec3< float > zAxis()
Definition: Vector.h:685