00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00025
00026 #ifndef Attractor_H
00027 #define Attractor_H
00028
00029
00030
00031
00032
00033
00034 #include "H3DNetworkingUtils/Config.h"
00035 #include <H3D/X3DChildNode.h>
00036 #include <H3DUtil/AutoRef.h>
00037 #include <HAPI/HAPIForceEffect.h>
00038 #include <H3D/SFString.h>
00039 #include <H3D/SFInt32.h>
00040 #include <H3D/SFVec3f.h>
00041 #include <H3D/SFFloat.h>
00042 #include <H3D/SFBool.h>
00043 #include <H3D/TraverseInfo.h>
00044 #include <H3D/ThreadSafeFields.h>
00045 #include <H3DUtil/AutoRef.h>
00046
00047 namespace H3D {
00048 H3D_VALUE_EXCEPTION( const char *, invalidAttractorMode );
00049 }
00050
00051 namespace H3DNetworkingUtils{
00052
00071
00072 class H3D_NETWORKING_UTILS_DLL_SPEC Attractor : public H3D::X3DChildNode {
00073 public:
00074 #define NEAREST_TOOL -1
00075 #define NONE -2
00076
00077 struct BoolOr : public H3D::SFBool {
00078 virtual void update() {
00079 for (u_int i = 0; i < routes_in.size(); i++) {
00080 if (static_cast<H3D::SFBool*>(routes_in[i])->getValue()) {
00081 value = true;
00082 return;
00083 }
00084 }
00085 value = false;
00086 }
00087 };
00088 Attractor( H3D::Inst<H3D::ThreadSafeSField<H3D::SFVec3f> > point = 0,
00089 H3D::Inst<H3D::SFBool> withOffset = 0,
00090 H3D::Inst<H3D::SFFloat> radius = 0,
00091 H3D::Inst<H3D::SFFloat> strength = 0,
00092 H3D::Inst<BoolOr > enabled = 0,
00093 H3D::Inst<H3D::SFInt32> deviceIndex = 0,
00094 H3D::Inst<H3D::SFFloat> maxForce = 0,
00095 H3D::Inst<H3D::SFFloat> maxDeltaForce = 0,
00096 H3D::Inst<H3D::SFVec3f> offset = 0,
00097 H3D::Inst<H3D::SFBool> repel = 0,
00098 H3D::Inst<H3D::SFInt32> activeDevice = 0,
00099 H3D::Inst<H3D::SFBool> activeOnlyOnClick = 0,
00100 H3D::Inst<H3D::SFFloat> rampUpTime = 0,
00101 H3D::Inst<H3D::SFFloat> rampDownTime = 0);
00102
00103 virtual void traverseSG(H3D::TraverseInfo & ti);
00104
00105 static H3D::H3DNodeDatabase database;
00106
00107
00108
00113 auto_ptr<H3D::ThreadSafeSField<H3D::SFVec3f> > point;
00114
00120 auto_ptr<H3D::SFBool> withOffset;
00121
00126 auto_ptr<H3D::SFFloat> radius;
00127
00132 auto_ptr<H3D::SFFloat> strength;
00133
00141 auto_ptr<H3D::SFBool> enabled;
00142
00152 auto_ptr<H3D::SFInt32> deviceIndex;
00153
00158 auto_ptr<H3D::SFFloat> maxForce;
00159
00164 auto_ptr<H3D::SFFloat> maxDeltaForce;
00165
00170 auto_ptr<H3D::SFVec3f> offset;
00171
00176 auto_ptr<H3D::SFBool> repel;
00177
00182 auto_ptr<H3D::SFInt32> activeDevice;
00183
00190 auto_ptr<H3D::SFBool> activeOnlyOnClick;
00191
00196 auto_ptr<H3D::SFFloat> rampUpTime;
00197
00202 auto_ptr<H3D::SFFloat> rampDownTime;
00203
00204
00205 protected:
00206
00207 virtual void setOffset(H3D::Vec3f const & offs) { offset->setValue(offs, id); }
00208
00209 virtual H3D::Vec3f getPoint() {return point->getValue();}
00210
00211
00212
00213
00214
00215
00216
00217 class AttractForce : public HAPI::HAPIForceEffect {
00218 public:
00219
00220 AttractForce( H3D::H3DTime t,
00221 H3D::Vec3f const & _point,
00222 bool _repel,
00223 H3D::H3DFloat maxForce,
00224 H3D::H3DFloat maxDeltaForce,
00225 H3D::H3DFloat _radius,
00226 H3D::H3DFloat _scale,
00227 H3D::Vec3f const & offset,
00228 Attractor * attrP);
00229
00230 AttractForce(AttractForce & that);
00231
00232 virtual H3D::Vec3f getLatestAttractionPoint() {return attraction_point;}
00233
00234 HAPI::HAPIForceEffect::EffectOutput virtual calculateForces( const HAPI::HAPIForceEffect::EffectInput &input );
00235
00236 H3D::H3DFloat strength;
00237
00238 protected:
00239 H3D::Vec3f smooth(H3D::Vec3f const & raw_force, H3D::TimeStamp const & deltaT);
00240
00241 H3D::AutoRef<Attractor> attrP;
00242 private:
00243 H3D::H3DFloat maxForce;
00244 H3D::H3DFloat maxDeltaForce;
00245 H3D::H3DTime traverse_time;
00246 H3D::Vec3f attraction_point;
00247 H3D::H3DFloat radius;
00248 int currently_attracted_device;
00249 H3D::H3DFloat scale;
00250 H3D::Vec3f offset;
00251 bool repel;
00252 H3D::Vec3f prev_force;
00253 };
00254
00255 virtual AttractForce * createAttractForce(H3D::H3DTime t,
00256 H3D::Vec3f const & _point,
00257 bool _repel,
00258 H3D::H3DFloat maxForce,
00259 H3D::H3DFloat maxDeltaForce,
00260 H3D::H3DFloat _radius,
00261 H3D::H3DFloat _scale,
00262 H3D::Vec3f const & offset);
00263
00264 virtual H3D::H3DFloat getForce(H3D::TraverseInfo & ti,
00265 bool & inside,
00266 H3D::H3DTime now,
00267 H3D::Vec3f & tool_pos,
00268 H3D::Vec3f const & current_attr_pt);
00269
00270 int getNearestDevice(H3D::TraverseInfo & ti,
00271 H3D::Vec3f & pos,
00272 H3D::Vec3f const & current_attr_pt);
00273
00274
00275 virtual H3D::H3DFloat calcDistSquared(H3D::Vec3f const & pt1, H3D::Vec3f const & pt2) {
00276 H3D::Vec3f x = pt1 - pt2; return x * x;
00277 }
00278
00279 virtual H3D::H3DFloat calcForceStrength(H3D::Vec3f const & pos,
00280 bool & now_inside,
00281 H3D::Vec3f const & current_attr_pt);
00282
00283 enum Ramping {RAMP_UP, RAMP_DOWN, RAMP_NONE};
00284
00285 struct RampIncrPerSec : public H3D::TypedField<H3D::SFFloat, H3D::Types<H3D::SFFloat, H3D::SFFloat> > {
00286 virtual void update() {
00287 float ramp_time = static_cast<H3D::SFFloat*>(routes_in[0])->getValue();
00288 float str = static_cast<H3D::SFFloat*>(routes_in[1])->getValue();
00289 if (ramp_time > 0.0f) {
00290 value = str / ramp_time;
00291 } else {
00292 value = str;
00293 }
00294 }
00295 };
00296
00297 H3DUtil::MutexLock point_lock;
00298 H3D::Vec3f attract_pt;
00299
00300 private:
00301 struct TraverseData {
00302 H3D::H3DTime traverse_time;
00303 H3D::Vec3f last_force;
00304 };
00305 H3D::H3DFloat scale;
00306 TraverseData tool_data[4];
00307
00308
00309 int selected_device;
00310 bool just_enabled;
00311 bool inside;
00312 H3D::H3DTime ramp_time;
00313 bool ramping_up;
00314 bool ramping_down;
00315 H3D::H3DFloat force_strength;
00316 H3D::H3DFloat prev_force_strength;
00317 auto_ptr<RampIncrPerSec> ramp_up_incr_per_sec;
00318 auto_ptr<RampIncrPerSec> ramp_down_incr_per_sec;
00319 bool was_inside;
00320 bool was_enabled;
00321 H3D::H3DTime ramp_start_time;
00322 Ramping ramping;
00323 H3D::H3DFloat ramp_start_strength;
00324
00325 };
00326
00327 }
00328
00329 #endif
00330