00001 00005 /* Copyright © 2009, 2010 James Legg. 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 */ 00011 00012 #include "LineConstrainedControlPoint.h" 00013 00014 #include <GL/gl.h> 00015 #include <cmath> 00016 00017 namespace Track 00018 { 00019 00020 namespace EditAssist 00021 { 00022 00023 LineConstrainedControlPoint::LineConstrainedControlPoint() 00024 : allow_before_start(true) 00025 , allow_after_end(true) 00026 { 00027 } 00028 00029 LineConstrainedControlPoint::LineConstrainedControlPoint(bool allow_before_start, bool allow_after_end) 00030 : allow_before_start(allow_before_start) 00031 , allow_after_end(allow_after_end) 00032 { 00033 } 00034 00035 LineConstrainedControlPoint::~LineConstrainedControlPoint() 00036 { 00037 } 00038 00044 btVector3 to_plane(btVector3 v, btVector3 normal) 00045 { 00046 btScalar height = v.dot(normal); 00047 return v - height * normal; 00048 } 00049 00050 void LineConstrainedControlPoint::snap(btVector3 & position, btVector3 normal) const 00051 { 00052 // find nearest point in screenspace to line. 00053 btVector3 position_flat = to_plane(position, normal); 00054 btVector3 start_flat = to_plane(start, normal); 00055 btVector3 stop_flat = to_plane(stop, normal); 00056 // find distance along line. 00057 btVector3 line = stop_flat - start_flat; 00058 btVector3 to_start = position_flat - start_flat; 00059 btScalar line_length_squared = line.length2(); 00060 if (line_length_squared == 0) 00061 { 00062 // All points are equally close in this view. Pick any valid position. 00063 position = start; 00064 return; 00065 } 00066 btScalar u = to_start.dot(line) / line_length_squared; 00067 // is it outside the allowed range? 00068 if (u < 0.0 && !allow_before_start) 00069 { 00070 position = start; 00071 return; 00072 } 00073 else if (u > 1.0 && !allow_after_end) 00074 { 00075 position = stop; 00076 return; 00077 } 00078 else 00079 { 00080 // use u to find the position in 3D. 00081 position = start + (stop - start) * u; 00082 } 00083 } 00084 00085 void LineConstrainedControlPoint::draw() const 00086 { 00087 glBegin(GL_LINES); 00088 glVertex3f(start.x(), start.y(), start.z()); 00089 glVertex3f(position.x(), position.y(), position.z()); 00090 glEnd(); 00091 glBegin(GL_POINTS); 00092 glVertex3f(position.x(), position.y(), position.z()); 00093 glEnd(); 00094 glPushMatrix(); 00095 glTranslatef(position.x(), position.y(), position.z()); 00096 btScalar scale = position.distance(start) / 4.0; 00097 glScalef(scale, scale, scale); 00098 btVector3 difference = (position - start).normalized(); 00099 btVector3 cross = difference.cross(btVector3(0.0, 0.0, 1.0)).cross(difference).normalized(); 00100 btVector3 other = cross.cross(difference); 00101 GLfloat mat[16] = {cross.x(), cross.y(), cross.z(), 0, 00102 other.x(), other.y(), other.z(), 0, 00103 difference.x(), difference.y(), difference.z(), 0, 00104 0, 0, 0, 1}; 00105 glMultMatrixf(mat); 00106 glBegin(GL_LINE_LOOP); 00107 for (int i = 0; i < 13; i++) 00108 { 00109 float angle = (float (i)) * 0.523598776; 00110 glVertex2f(std::sin(angle), std::cos(angle)); 00111 } 00112 glEnd(); 00113 glPopMatrix(); 00114 } 00115 00116 } // namespace EditAssist 00117 00118 } // namespace Track
Generated at Mon Sep 6 00:41:11 2010 by Doxygen version 1.4.7 for Racer version svn335.