- Main Page
- Classes
- Files

- Search for |

# Attractor.h

Go to the documentation of this file.

    00001 /*****************************
    00002 File:      Attractor.h
    00003 Language:   C++ (header)
    00004 Project:    H3DNetworkingUtils
    00005 The contents of this file are subject to the Mozilla Public License
    00006 Version 1.1 (the "License"); you may not use this file except in
    00007 compliance with the License. You may obtain a copy of the License at
    00008 http://www.mozilla.org/MPL/
    00009
    00010 Software distributed under the License is distributed on an "AS IS"
    00011 basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
    00012 License for the specific language governing rights and limitations
    00013 under the License.
    00014
    00015 The Original Code is H3DNetworkingUtils v1.0.
    00016
    00017 The Initial Developer of the Original Code is CSIRO.
    00018 Portions created by the Initial Developer are Copyright (C) 1009 CSIRO. All Rights Reserved.
    00019 Contributor(s):
    00020     Chris Gunn  <Chris.Gunn@csiro.au> <ChrisJGunn@gmail.com>
    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    // public fields
    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    // getPoint() is provided to get the point in the
    00211    // haptics loop. The default implementation retrives a copy of the point field
    00212    // last read during the graphics loop. Overriding classes may allow the point
    00213    // to change at faster rates (see RealtimeAttractor).
    00214
    00215    // AttractForce is called by the H3D force mechanism in the haptics loop.
    00216    // It calls AttractorForceFunc then smoothes it before returning it to H3D.
    00217    class AttractForce : public HAPI::HAPIForceEffect {
    00218    public:
    00219    // Constructor
    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    // get the closest device to pos.
    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]; // index 0 is right hand, index 1 is left  hand tool.
    00307
    00308    // traverseSG data
    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