00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef __SGL_SEGMENT_HPP
00026 #define __SGL_SEGMENT_HPP
00027
00028 #include <sgl.h>
00029 #include <GL/gl.h>
00030 #include <sglVec3.hpp>
00031 #include <sglVec4.hpp>
00032 #include <sglMat4.hpp>
00033
00034
00035
00036
00037
00038 template <class T> class sglSegment;
00039
00040 typedef sglSegment<float> sglSegmentf;
00041 typedef sglSegment<double> sglSegmentd;
00042
00043
00044
00045 template <class T>
00046 class sglSegment
00047 {
00048 public:
00049 sglSegment() {};
00050
00051
00052 sglSegment(const sglVec3<T> &pos, const sglVec3<T> &dir, T len)
00053 : m_pos(pos), m_dir(dir), m_len(len) {};
00054
00055
00056 sglSegment(const sglVec3<T> &p1, const sglVec3<T> &p2)
00057 : m_pos(p1)
00058 {
00059 m_dir = p2;
00060 m_dir -= p1;
00061 m_len = m_dir.normalize();
00062 }
00063
00064
00065 sglSegment(const sglSegment<T> &seg)
00066 : m_pos(seg.getPos()),
00067 m_dir(seg.getDir()),
00068 m_len(seg.getLen())
00069
00070 {
00071 }
00072
00073 ~sglSegment() {};
00074
00075 inline sglSegment &operator=(const sglSegment<T> seg)
00076 {
00077 if (this != &seg)
00078 {
00079 m_pos = seg.getPos();
00080 m_dir = seg.getDir();
00081 m_len = seg.getLen();
00082 }
00083 return *this;
00084 }
00085
00086
00087 void setPos(const sglVec3<T> &pos) { m_pos = pos; }
00088 void setDir(const sglVec3<T> &dir) { m_dir = dir; }
00089 void setLen(T len) { m_len = len; }
00090
00091 const sglVec3<T>& getPos() const { return m_pos; }
00092 const sglVec3<T>& getDir() const { return m_dir; }
00093 T getLen() const { return m_len; }
00094
00095 sglVec3<T> getEndPoint() const
00096 {
00097 return (sglVec3<T>(m_pos[0] + m_len*m_dir[0],
00098 m_pos[1] + m_len*m_dir[1],
00099 m_pos[2] + m_len*m_dir[2]));
00100 }
00101
00102 void clip(const sglSegment<T>& seg, T d1, T d2)
00103 {
00104 if (d2 < d1)
00105 {
00106 m_dir = seg.getDir();
00107 m_dir *= -1;
00108
00109 m_pos = m_dir;
00110 m_pos *= d1;
00111 m_pos = seg.getPos();
00112
00113 m_len = d1 - d2;
00114 }
00115 else
00116 {
00117 m_dir = seg.getDir();
00118
00119 m_pos = m_dir;
00120 m_pos *= d1;
00121 m_pos += seg.getPos();
00122
00123 m_len = d2 - d1;
00124 }
00125 }
00126
00127 void makePts(const sglVec3<T> &p1, const sglVec3<T> &p2)
00128 {
00129 m_pos = p1;
00130 m_dir = p2;
00131 m_dir -= p1;
00132 m_len = m_dir.normalize();
00133 }
00134
00135
00136 void makePolar(const sglVec3<T> &pos, double heading, double pitch, T len)
00137 {
00138 m_pos = pos;
00139 m_len = len;
00140 m_dir.set(-sin(heading)*cos(pitch),
00141 cos(heading)*cos(pitch),
00142 sin(pitch));
00143 }
00144
00145
00146
00147 template <class S>
00148 void mul(const sglMat4<S> &mat)
00149 {
00150 sglVec4<T> pos, dir;
00151 ::mul(m_pos, (T)1.0, mat, pos);
00152 ::mul(m_dir, (T)0.0, mat, dir);
00153 m_pos.set(pos[0], pos[1], pos[2]);
00154 m_dir.set(dir[0], dir[1], dir[2]);
00155 }
00156
00157 template <class S>
00158 void translate(S x, S y, S z)
00159 {
00160 m_pos[0] += x;
00161 m_pos[1] += y;
00162 m_pos[2] += z;
00163 }
00164
00165 template <class S>
00166 void scale(S scale)
00167 {
00168 m_pos[0] *= scale;
00169 m_pos[1] *= scale;
00170 m_pos[2] *= scale;
00171 m_len *= scale;
00172 }
00173
00174
00175
00176 void drawImmediate() const;
00177
00178 #if defined(TEMPLATE_OSTREAM_HACK)
00179 template <class S>
00180 friend ostream &operator<<(ostream &ostrm, const sglSegment<S> &segment);
00181 #else
00182 friend ostream &operator<<(ostream &ostrm, const sglSegment<T> &segment)
00183 {
00184 return (ostrm << "segment [ origin = " << segment.m_pos
00185 << ", dir = " << segment.m_dir
00186 << ", length = " << segment.m_len << "]");
00187 }
00188 #endif
00189
00190 protected:
00191 sglVec3<T> m_pos;
00192 sglVec3<T> m_dir;
00193 T m_len;
00194 };
00195
00196
00197 #if defined(TEMPLATE_OSTREAM_HACK)
00198 template <class T>
00199 inline ostream &operator<<(ostream &ostrm, const sglSegment<T> &segment)
00200 {
00201 return (ostrm << "segment [ origin = " << segment.m_pos
00202 << ", dir = " << segment.m_dir
00203 << ", length = " << segment.m_len << "]");
00204 }
00205 #endif
00206
00207
00208 template <class T>
00209 inline void sglSegment<T>::drawImmediate() const
00210 {
00211 glBegin(GL_LINES);
00212 glVertex3f(m_pos[0], m_pos[1], m_pos[2]);
00213 glVertex3f(m_pos[0] + m_len*m_dir[0],
00214 m_pos[1] + m_len*m_dir[1],
00215 m_pos[2] + m_len*m_dir[2]);
00216 glEnd();
00217 }
00218
00219 #endif