00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef GEE_PATH_H
00021 #define GEE_PATH_H
00022
00023 #include <gee_geometry.h>
00024 #include <gee_param_writer.h>
00025
00026 #include <vee_bounding_box.h>
00027 #include <vee_math.h>
00028 #include <vee_matrix3.h>
00029 #include <vee_vector3.h>
00030
00031 #include <map>
00032 #include <strings.h>
00033
00034
00035 class GEE_PathVertex3D
00036 {
00037 public:
00038 GEE_PathVertex3D(const VEE_Vector3 &loc = VEE_Vector3ZERO,
00039 const VEE_Matrix3 &rot = VEE_Matrix3IDENTITY,
00040 float time = 0.0f)
00041 : m_location(loc), m_rotation(rot), m_time(time)
00042 {
00043 bzero(m_tips, sizeof(m_tips));
00044 }
00045
00046 void clear() { m_location.clear(); m_rotation.identity(); }
00047
00049 float edgesLength() const
00050 {
00051 return (m_tips[2] - m_tips[1]).length() +
00052 (m_tips[1] - m_tips[0]).length() +
00053 (m_tips[2] - m_tips[0]).length();
00054 }
00055
00058 float calculateToolRadius(float radiusBase,
00059 float radiusNorm,
00060 float exaggerate) const
00061 {
00062 float r = edgesLength();
00063 float rel = r / radiusNorm;
00064 float boost = pow(rel, exaggerate);
00065 return boost * r * radiusBase;
00066 }
00067
00068 VEE_Vector3 calculateLinearMix(const VEE_Vector3 & inValue,
00069 float mixRatio,
00070 const VEE_Vector3 & origin,
00071 float minSpan,
00072 float maxSpan) const
00073 {
00074 VEE_Vector3 res;
00075
00076 float amplitude = maxSpan - minSpan;
00077
00078 for(int i = 0; i <3; i++) {
00079 float d = ((origin - m_tips[i]).length() - minSpan) / amplitude;
00080
00081 d = VEE_clamp(d, 0.0f, 1.0f) - 0.5f;
00082
00083 res[i] = VEE_clamp(inValue[i] + d * mixRatio, 0.0f, 1.0f);
00084 }
00085
00086 return res;
00087 }
00088
00089 VEE_Vector3 tipAverage() const
00090 { return (m_tips[0] + m_tips[1] + m_tips[2]) * 0.333333333333333333f; }
00091
00092 VEE_Vector3 calculateToolCenter() const
00093 { return m_location + m_rotation * tipAverage(); }
00094
00095 bool operator == (const GEE_PathVertex3D &that) const
00096 {
00097 return m_location == that.m_location && m_rotation == that.m_rotation;
00098 }
00099
00100 bool read(GEE_Io *);
00101 bool write(GEE_Io *);
00102
00103 VEE_Vector3 & tip(int index) { return m_tips[index]; }
00104
00105 VEE_Vector3 m_location;
00106 VEE_Matrix3 m_rotation;
00107 float m_time;
00108
00110 VEE_Vector3 m_tips[3];
00111 };
00112
00115
00123 class GEE_Path3D : public GEE_Geometry
00124 {
00125 public:
00126
00127 typedef std::map<int, GEE_PathVertex3D> container;
00128 typedef container::iterator iterator;
00129 typedef container::const_iterator const_iterator;
00130
00131 GEE_Path3D();
00132 virtual ~GEE_Path3D();
00133
00134 static GEE_Geometry * create();
00135 virtual GEE_Geometry * clone() const;
00136 virtual bool intersects(GEE_Containment *);
00137
00138 virtual bool getBoundingBox(VEE_BoundingBox *);
00139 virtual void render(GEE_Renderer *);
00140
00141 virtual bool read(const char *);
00142 virtual bool write(const char *);
00143 virtual bool read(GEE_Io *);
00144 virtual bool write(GEE_Io *);
00145
00146 void addVertex(const GEE_PathVertex3D &v);
00147
00148 void addVertex(int index, const GEE_PathVertex3D &v)
00149 {
00150 m_vertices[index++] = v;
00151 m_bbox.expand(v.m_location);
00152 if(m_counter < index) m_counter = index;
00153 }
00154
00155 void addVertex(float time,
00156 const VEE_Vector3 &loc,
00157 const VEE_Matrix3 &rot)
00158 {
00159 m_vertices[m_counter++] = GEE_PathVertex3D(loc, rot, time);
00160 m_bbox.expand(loc);
00161 }
00162
00163 void addVertex(const VEE_Vector3 &loc,
00164 const VEE_Matrix3 &rot)
00165 {
00166 float t = endTime() + 1.0f;
00167 m_vertices[m_counter++] = GEE_PathVertex3D(loc, rot, t);
00168 m_bbox.expand(loc);
00169 }
00170
00171 iterator begin() { return m_vertices.begin(); }
00172 iterator end() { return m_vertices.end(); }
00173 iterator lower_bound(int index) { return m_vertices.lower_bound(index); }
00174
00175 const_iterator begin() const { return m_vertices.begin(); }
00176 const_iterator end() const { return m_vertices.end(); }
00177
00178 uint vertexCount() const { return m_vertices.size(); }
00179 int counter() const { return m_counter; }
00180
00181 bool activeNapra() const { return m_activeNapra; }
00182 void setActiveNapra(bool isActive) { m_activeNapra = isActive; }
00183
00184 void clear() { m_vertices.clear(); }
00185
00186 static int getIndex(iterator & it)
00187 { return (*it).first; }
00188 static float getTime(iterator & it)
00189 { return (*it).second.m_time; }
00190 static GEE_PathVertex3D & getVertex(iterator & it)
00191 { return (*it).second; }
00192 static VEE_Vector3 & getVertexLocation(iterator & it)
00193 { return (*it).second.m_location; }
00194 static VEE_Matrix3 & getVertexRotation(iterator & it)
00195 { return (*it).second.m_rotation; }
00196
00197 float beginTime()
00198 {
00199 if(!m_vertices.size())
00200 return 0.0f;
00201 return (*m_vertices.begin()).second.m_time;
00202 }
00203
00204 float endTime()
00205 {
00206 if(!m_vertices.size())
00207 return 0.0f;
00208 return (*(--m_vertices.end())).second.m_time;
00209 }
00210
00211 void create3DSpiral(int rounds = 3,
00212 int segmentsPerRound = 6,
00213 float secondsPerRound = 2.0,
00214 float initialRadius = 2.0,
00215 float depth = 2.0);
00216
00217 bool operator == (const GEE_Path3D &that) const;
00218
00219 protected:
00220 container m_vertices;
00221 int m_counter;
00222
00223 bool m_activeNapra;
00224 GEE_ParamWriter m_writer;
00225
00226 VEE_BoundingBox m_bbox;
00227 };
00228
00229 #endif