30 #include <Eigen/Dense> 128 #ifdef TUCANOSHADERDIR 138 key_positions.clear();
139 key_quaternions.clear();
140 key_directions.clear();
141 control_points_1.clear();
142 control_points_2.clear();
163 camerapath_shader.
load(
"beziercurve", shader_dir);
166 phong_shader.
load(
"phongshader", shader_dir);
185 control_segments =
Mesh();
187 vector < Eigen::Vector4f > control_segs;
188 for (
unsigned int i = 0; i < key_positions.size()-1; ++i)
190 control_segs.push_back(key_positions[i]);
191 control_segs.push_back(control_points_1[i]);
192 control_segs.push_back(key_positions[i+1]);
193 control_segs.push_back(control_points_2[i]);
211 Eigen::Vector4f center;
213 key_positions.push_back ( center );
214 key_intervals.push_back ( interval );
215 Eigen::Quaternionf quat (camera.
getViewMatrix().rotation() );
216 key_quaternions.push_back (quat.inverse());
219 if (key_positions.size() > 1 && interval == 0.0)
233 key_directions.push_back ( q );
247 glEnable(GL_DEPTH_TEST);
248 if (key_positions.size() > 1)
252 camerapath_shader.
bind();
259 Eigen::Vector4f color (1.0, 0.0, 0.0, 1.0);
260 camerapath_shader.
setUniform(
"modelMatrix", Eigen::Affine3f::Identity());
261 camerapath_shader.
setUniform(
"in_Color", color);
265 glDrawArrays(GL_LINE_STRIP, 0, key_positions.size());
268 camerapath_shader.
unbind();
270 if (draw_control_points)
278 color << 1.0, 1.0, 0.0, 1.0;
279 phong_shader.
setUniform(
"modelMatrix", Eigen::Affine3f::Identity());
280 phong_shader.
setUniform(
"default_color", color);
284 glDrawArrays(GL_LINES, 0, control_points_1.size()*4);
288 sphere.
setColor( Eigen::Vector4f (0.48, 1.0, 0.16, 1.0) );
290 for (
unsigned int i = 0; i < control_points_1.size(); i++)
293 Eigen::Vector3f translation = control_points_1[i].head(3);
296 sphere.
render(camera, light);
299 sphere.
setColor( Eigen::Vector4f (0.48, 0.16, 1.0, 1.0) );
301 for (
unsigned int i = 0; i < control_points_2.size(); i++)
304 Eigen::Vector3f translation = control_points_2[i].head(3);
307 sphere.
render(camera, light);
314 if (draw_quaternions)
316 for (
unsigned int i = 0; i < key_quaternions.size(); ++i)
321 axes.
render(camera, light);
325 sphere.
setColor( Eigen::Vector4f (1.0, 0.48, 0.16, 1.0) );
327 for (
unsigned int i = 0; i < key_positions.size(); i++)
331 Eigen::Vector3f translation = key_positions[i].head(3);
334 sphere.
render(camera, light);
338 glDisable(GL_DEPTH_TEST);
351 if (t < 0 || t > 1.0)
354 return int (t * (key_positions.size()-1));
364 float segment_length = 1.0 / (float)(key_positions.size()-1);
366 return (t - segment*segment_length)/segment_length;
378 pt = pow(1-t,3)*key_positions[segment] + 3.0*pow(1-t,2)*t*control_points_1[segment] + 3.0*(1-t)*pow(t,2)*control_points_2[segment] + pow(t, 3)*key_positions[segment+1];
404 Eigen::Quaternionf logq, q;
412 float angle = acos(q.w());
413 float sinangle = sin(angle);
414 if ( fabs(sinangle) >= 1e-03)
415 logq.vec() = angle * q.vec() / sinangle;
417 logq.vec() = q.vec();
433 Eigen::Quaternionf expq;
435 float angle = q.norm();
436 expq.w() = cos(angle);
437 float sinangle = sin(angle);
438 if (fabs(sinangle) >= 1e-03)
439 expq.vec() = sin(angle) * q.vec() / angle;
441 expq.vec() = q.vec();
454 Eigen::Quaternionf
squad (
int seg,
float t)
456 Eigen::Quaternionf s0 = control_quaternions[seg];
457 Eigen::Quaternionf s1 = control_quaternions[seg+1];
458 Eigen::Quaternionf q0 = key_quaternions[seg];
459 Eigen::Quaternionf q1 = key_quaternions[seg+1];
460 Eigen::Quaternionf p0, p1, res;
467 dot = q0.w()*q1.w()+q0.vec().dot(q1.vec());
472 p0 = q0.slerp(t, q1);
474 dot = s0.w()*s1.w()+s0.vec().dot(s1.vec());
479 p1 = s0.slerp(t, s1);
484 dot = p0.w()*p1.w()+p0.vec().dot(p1.vec());
489 res = p0.slerp(2.0*t*(1.0-t), p1);
502 Eigen::Affine3f m = Eigen::Affine3f::Identity();
512 Eigen::Quaternionf qt;
514 if (key_intervals[segment] > 0.0)
516 pt = key_positions[segment];
517 qt = key_quaternions[segment];
522 qt =
squad(segment, t);
527 m.translation() = pt.head(3);
538 Eigen::Quaternion<float> q = Eigen::Quaternion<float>::Identity();
547 q = key_directions[segment].slerp(t, key_directions[segment+1]);
576 if (key_positions.size() < 2)
585 float arc_length = s;
588 unsigned int segment = 0;
589 for (; segment < key_positions.size()-1; ++segment)
591 if (arc_lengths[segment+1][0] > arc_length)
596 unsigned int sub_seg = 0;
597 for (; sub_seg < arc_lengths[segment].size()-1; ++sub_seg)
599 if (arc_lengths[segment][sub_seg+1] > arc_length)
605 float alpha = (arc_length - arc_lengths[segment][sub_seg]) /
606 (arc_lengths[segment][sub_seg+1] - arc_lengths[segment][sub_seg]);
609 float t_ini = sub_seg / (float)(arc_lengths[segment].size()-1);
610 float t_end = (sub_seg+1) / (
float)(arc_lengths[segment].size()-1);
611 float t_s = t_ini + alpha * (t_end - t_ini);
614 t_s = t_s / (float)(key_positions.size()-1);
617 t_s += segment / (float)(key_positions.size()-1);
672 if (anim_time >= path_length)
754 control_quaternions.clear();
756 Eigen::Quaternionf s;
759 s = key_quaternions[0];
760 control_quaternions.push_back(s);
762 for (
unsigned int seg = 1; seg < key_quaternions.size()-1; ++seg)
764 s = -0.25*(
logQuaternion(key_quaternions[seg].inverse()*key_quaternions[seg-1]).coeffs() +
logQuaternion(key_quaternions[seg].inverse()*key_quaternions[seg+1]).coeffs());
767 control_quaternions.push_back(s);
771 control_quaternions.push_back(key_quaternions.back());
790 control_points_1.clear();
791 control_points_2.clear();
795 if (key_positions.size() == 2)
797 Eigen::Vector4f pt = 0.75*key_positions[0] + 0.25*key_positions[1];
798 control_points_1.push_back(pt);
799 control_points_1.push_back(pt);
800 pt << 0.25*key_positions[0] + 0.75*key_positions[1];
801 control_points_2.push_back(pt);
802 control_points_2.push_back(pt);
806 const int n = key_positions.size()-1;
808 control_points_1.resize(n+1);
809 control_points_2.resize(n+1);
813 vector <float> a_orig;
814 vector <float> b_orig;
815 vector <float> c_orig;
833 for (
int i = 1; i < n-1; i++)
847 for (
int coord = 0; coord < 3; ++coord)
850 d[0] = key_positions[0][coord] + 2.0 * key_positions[1][coord];
851 for (
int i = 1; i < n-1; i++)
852 d[i] = 4.0*key_positions[i][coord] + 2.0*key_positions[i+1][coord];
853 d[n-1] = 8.0*key_positions[n-1][coord] + key_positions[n][coord];
864 for (
int i = 1; i < n; ++i)
866 float m = b[i] - a[i]*c[i-1];
868 d[i] = (d[i] - a[i]*d[i-1]) / m;
872 control_points_1[n-1][coord] = d[n-1];
873 for (
int i = n-2; i >= 0; --i)
875 control_points_1[i][coord] = d[i] - c[i]*control_points_1[i+1][coord];
878 control_points_1[n][coord] = control_points_1[n-1][coord];
882 for (
int i = 0; i <= n; ++i)
884 control_points_1[i][3] = 1.0;
889 for (
int i = 0; i < n-1; ++i)
891 pt = 2.0* key_positions[i+1] - control_points_1[i+1];
892 control_points_2[i] = pt;
894 pt = (key_positions[n] + control_points_1[n-1])*0.5;
895 control_points_2[n-1] = pt;
896 control_points_2[n] = pt;
917 p0 = key_positions[0];
918 for (
unsigned int seg = 0; seg < key_positions.size()-1; ++seg)
920 vector <float> seg_lengths;
923 if (key_intervals[seg] > 0.0)
925 float l = key_intervals[seg] / divs;
927 for (
int i = 0; i < divs+1; ++i)
930 seg_lengths.push_back(dist);
932 p1 = key_positions[seg+1];
937 for (
int i = 0; i < divs; ++i)
940 dist += (p1-p0).norm();
942 seg_lengths.push_back(dist);
951 p1 = key_positions[seg+1];
952 seg_lengths.push_back( dist + (p1-p0).norm() );
954 arc_lengths.push_back (seg_lengths);
959 p1 = key_positions[key_positions.size()-1];
960 dist += (p1-p0).norm();
966 vector <float> last_seg;
967 last_seg.push_back (dist);
968 arc_lengths.push_back(last_seg);
980 Eigen::Quaternionf qt;
981 if (segment >= 0 && key_positions.size() - segment > 2)
982 qt =
squad(segment, t);
984 qt = key_quaternions[segment].slerp(t, key_quaternions[segment+1]);
986 Eigen::Affine3f m = Eigen::Affine3f::Identity();
988 m.translation() = pt.head(3);
990 cout <<
"quat : (" << qt.w() <<
" , " << qt.vec().transpose() <<
" ) " << endl;
991 cout <<
"t : " << pt.head(3).transpose() << endl;
992 cout <<
"m : " << endl << m.matrix() << endl << endl;
999 file.open (filename.c_str());
1001 file << key_positions.size() << endl;
1002 for (
unsigned int i = 0; i < key_positions.size(); ++i)
1004 file << key_positions[i].transpose() << endl;
1005 file << key_quaternions[i].w() <<
" " << key_quaternions[i].vec().transpose() << endl;
1006 file << key_directions[i].w() <<
" " << key_directions[i].vec().transpose() << endl;
1007 file << key_intervals[i] << endl;
1015 ifstream file (filename.c_str());
1023 Eigen::Quaternion<float> q;
1026 getline(file, line);
1027 istringstream iss(line);
1030 for (
int i = 0; i < num; ++i)
1033 getline(file, line);
1036 iss >> v[0] >> v[1] >> v[2] >> v[3];
1037 key_positions.push_back(v);
1040 getline(file, line);
1043 iss >> q.w() >> q.vec()[0] >> q.vec()[1] >> q.vec()[2];
1044 key_quaternions.push_back(q);
1047 getline(file, line);
1050 iss >> q.w() >> q.vec()[0] >> q.vec()[1] >> q.vec()[2];
1051 key_directions.push_back(q);
1054 getline(file, line);
1058 key_intervals.push_back(elem);
1061 if (key_positions.size() > 1)
float getNearPlane(void) const
Returns near plane value.
Definition: camera.hpp:319
bool loop_animation
Flag to loop animation.
Definition: path.hpp:65
bool draw_control_points
Flag to render control points.
Definition: path.hpp:68
Shader camerapath_shader
Path shader, used for rendering the curve.
Definition: path.hpp:114
void render(const Tucano::Camera &camera, const Tucano::Camera &light)
Renders smooth path End points for each Beziér is passed as line_strip and control points as vertex a...
Definition: path.hpp:245
void loadFromFile(const string filename)
Definition: path.hpp:1013
VertexAttribute * createAttribute(string name, vector< Eigen::Vector4f > &attrib)
Creates and loads a new mesh attribute of 4 floats.
Definition: mesh.hpp:583
void reset(void)
Resets the path.
Definition: path.hpp:136
vector< Eigen::Quaternion< float > > key_quaternions
Rotation state at each key frame.
Definition: path.hpp:92
Eigen::Affine3f * modelMatrix(void)
Returns a pointer to the model matrix.
Definition: model.hpp:112
void getViewMatrix(GLdouble *matrix)
Return the modelview matrix as a GLdouble array.
Definition: camera.hpp:126
A simple sphere shape.
Definition: sphere.hpp:83
bool isAnimating(void)
Returns if Animation is running or not.
Definition: path.hpp:660
void getProjectionMatrix(GLdouble *matrix)
Return the projection matrix as a GLdouble array.
Definition: camera.hpp:142
Definition: bufferobject.hpp:34
float getFarPlane(void) const
Returns far plane value.
Definition: camera.hpp:328
vector< Eigen::Quaternion< float > > control_quaternions
Control quaternions for SQUAD.
Definition: path.hpp:95
void resetAnimation(void)
Resets animation to first key position.
Definition: path.hpp:715
Mesh control_segments
Definition: path.hpp:105
void initialize(void)
Calls all the functions related to the shader initialization, i.e., creates, loads the shaders from t...
Definition: shader.hpp:641
float arcLengthToTime(float s)
Converts from given arc length to time parameter.
Definition: path.hpp:574
Eigen::Quaternionf squad(int seg, float t)
SQUAD - Spherical and Quadrangle quaternion interpolation.
Definition: path.hpp:454
Path class, defines control points and a cubic Bezier approximation for defining a smooth path from k...
Definition: path.hpp:51
void stopAnimation(void)
Stop animation.
Definition: path.hpp:707
void setAnimSpeed(float as)
Sets the animation speed.
Definition: path.hpp:742
A Shader object represents one GLSL program.
Definition: shader.hpp:45
void setColor(const Eigen::Vector4f &color)
Sets the default color of the model.
Definition: model.hpp:65
float path_length
Total path length.
Definition: path.hpp:89
void computeControlQuaternions(void)
Compute control points for SQUAD.
Definition: path.hpp:752
void stepBackward(void)
Move animation backward one step.
Definition: path.hpp:687
void render(const Tucano::Camera &camera, const Tucano::Camera &light)
Render camera representation.
Definition: coordinateaxes.hpp:67
void errorCheckFunc(std::string file, int line, std::string message="")
GL error check method.
Definition: misc.hpp:53
Visual representation of a 3D coordinate axes.
Definition: coordinateaxes.hpp:44
vector< vector< float > > arc_lengths
Arc-length approximation splitting each Beziér segment into linear segments.
Definition: path.hpp:86
void setLoopAnimation(bool f)
Set loop animation flag.
Definition: path.hpp:634
bool animating
Start/stop animation.
Definition: path.hpp:62
int curveSegment(float t)
returns the segment given a time t in [0,1] for the whole path
Definition: path.hpp:349
Eigen::Quaternion< float > directionAtTime(float global_t)
return a direction at a given path parameter
Definition: path.hpp:536
void initialize(string shader_dir="../effects/shaders/")
Initializes shaders.
Definition: path.hpp:161
void addKeyDirection(const Eigen::Quaternion< float > q)
Add an optial key direction Key directions are interpolated via SLERP and not SQUAD This is specially...
Definition: path.hpp:231
vector< Eigen::Vector4f > control_points_1
First control point between two key positions.
Definition: path.hpp:80
void toggleDrawControlPoints(void)
Toggle render control points.
Definition: path.hpp:642
void initOpenGLMatrices(void)
Initializes the view and projection matrices. They are all initialized as Identity matrices...
Definition: path.hpp:151
void stepForward(void)
Move animation forward one step.
Definition: path.hpp:668
vector< Eigen::Vector4f > control_points_2
Second control point between two key positions.
Definition: path.hpp:83
Mesh curve
Definition: path.hpp:102
Eigen::Quaternion< float > directionAtCurrentTime(void)
Return the direction at current animation time.
Definition: path.hpp:564
Eigen::Affine3f cameraAtCurrentTime(void)
Return the view matrix at current animation time.
Definition: path.hpp:555
void startAnimation(void)
Start animation following camera path.
Definition: path.hpp:699
float anim_speed
Movement speed, arc length increment for each animation step.
Definition: path.hpp:56
float animSpeed(void)
Return animation speed where 1 covers the whole curve in one step.
Definition: path.hpp:733
Eigen::Quaternionf logQuaternion(const Eigen::Quaternionf &qi)
Returns the log of a quaternion log(q) q in the form [cos(a), sin(a) v], log(q) = [0...
Definition: path.hpp:402
void computeInnerControlPoints(void)
Compute inner control points from key positions.
Definition: path.hpp:787
void resetModelMatrix(void)
Resets the model matrix.
Definition: model.hpp:159
void unbind(void)
Disables the shader program.
Definition: shader.hpp:1184
Eigen::Affine3f cameraAtTime(float global_t)
return a view matrix at a given path parameter
Definition: path.hpp:500
Eigen::Vector3f getCenter(void) const
Returns the center of the camera in world space.
Definition: camera.hpp:115
Eigen::Vector4f pointOnSegment(float t, int segment)
Returns a point at time t on a given Beziér segment.
Definition: path.hpp:375
void addKeyPosition(const Tucano::Camera &camera, float interval=0.0)
Add key position The camera will pause at this position for given number of steps, default is zero.
Definition: path.hpp:209
void toggleDrawQuaternions(void)
Toggle render control quaternions.
Definition: path.hpp:650
float toLocalParameter(float t)
converts global parameter t to a local t inside a segment
Definition: path.hpp:361
vector< float > key_intervals
Steps to stay paused at a given key position, usually zero.
Definition: path.hpp:77
Eigen::Quaternionf expQuaternion(const Eigen::Quaternionf &q)
Returns the exp of a quaternion exp(q) q in the form [0, a v], exp(q) = [cos(a), sin(a) v] with |v|=1...
Definition: path.hpp:431
Eigen::Vector4f pointOnPath(float global_t)
compute point on path given t in [0,1]
Definition: path.hpp:389
vector< Eigen::Vector4f > key_positions
Camera position at each Key frames.
Definition: path.hpp:74
virtual void unbindBuffers(void)
Unbinds all buffers.
Definition: mesh.hpp:702
void computeArcLength(void)
Compute an approximation of the arclength.
Definition: path.hpp:907
void writeToFile(const string filename)
Definition: path.hpp:996
void loadVertices(vector< Eigen::Vector4f > &vert)
Load vertices (x,y,z,w) and creates appropriate vertex attribute. The default attribute name is "in_P...
Definition: mesh.hpp:312
void load(string name, string shader_dir="")
Loads a shader given a directory and a name. Searches for all shader extensions in directory...
Definition: shader.hpp:436
void bind(void)
Enables the shader program for usage.
Definition: shader.hpp:1176
vector< Eigen::Quaternion< float > > key_directions
Rotation only interpolation (via Slerp) useful for accompaning light direction for example...
Definition: path.hpp:98
void render(const Tucano::Camera &camera, const Tucano::Camera &light)
Render sphere.
Definition: sphere.hpp:115
void fillVertexData(void)
Fill the vertices array.
Definition: path.hpp:173
virtual void bindBuffers(void)
Binds all buffers.
Definition: mesh.hpp:677
#define stringify(x)
Definition: misc.hpp:33
A common Mesh, usually containing triagles or points.
Definition: mesh.hpp:194
Defines an abstract camera with a projection and view matrices.
Definition: camera.hpp:37
void setAttributeLocation(Shader *shader)
Automatically sets the attribute locations for a given Shader.
Definition: mesh.hpp:541
Shapes::CoordinateAxes axes
Coordinate axes for visualizing quaternions at key positions.
Definition: path.hpp:111
Shapes::Sphere sphere
A sphere to visually represent the path's key positions.
Definition: path.hpp:108
float anim_time
Animation time.
Definition: path.hpp:59
void printDebugInfo(void)
Definition: path.hpp:972
Shader phong_shader
To render simple lines.
Definition: path.hpp:117
Path()
Default constructor.
Definition: path.hpp:124
void toggleAnimation(void)
Toggle animation.
Definition: path.hpp:625
float animTime(void)
Return current animation time.
Definition: path.hpp:724
bool draw_quaternions
Flag to render quaternions at key positions.
Definition: path.hpp:71
void setUniform(GLint location, GLint a, GLint b, GLint c, GLint d)
Sets an uniform integer 4D vector (ivec4) given a location and the vector values. ...
Definition: shader.hpp:1258