00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef VRS_SG_PHYSICALNAVIGATION_H
00021 #define VRS_SG_PHYSICALNAVIGATION_H
00022
00023 #include <vrs/engine.h>
00024 #include <vrs/filtertag.h>
00025 #include <vrs/rayrequest.h>
00026
00027 #include <vrs/sg/canvas.h>
00028 #include <vrs/sg/keyevent.h>
00029 #include <vrs/sg/navigation.h>
00030 #include <vrs/sg/physicalforce.h>
00031
00032 namespace VRS {
00033
00304 class VRS_CORE_API PhysicalNavigation : public Navigation {
00305
00306 public:
00307 PhysicalNavigation(
00308 LookAt* lookAt,
00309 InputEvent::Button button = InputEvent::MouseButton1,
00310 InputEvent::Modifier must_modifier = InputEvent::NoModifier,
00311 InputEvent::Modifier must_not_modifier = InputEvent::NoModifier,
00312 double meterDefinition = 1.0,
00313 FilterTag* filterTag = NULL,
00314 Vector gravitationDir = Vector(0.0, -1.0, 0.0),
00315 PhysicalForce::ForceMode forceMode = PhysicalForce::Spring
00316 );
00343 double getMeterDefinition() const;
00350 virtual void setMeterDefinition(double);
00358 Vector getCurrentVelocity() const;
00361 float getViscosity() const;
00370 void setViscosity(float);
00379 void setSlowDownControlEnabled(bool);
00385 bool slowDownControlEnabled();
00392 virtual ~PhysicalNavigation();
00394
00395 VRS_TYPEINFO(PhysicalNavigation, Navigation);
00396 VRS_SERIALIZABLE_ABSTRACT_CLASS(PhysicalNavigation);
00397
00398 protected:
00399 virtual void translateInteractionIntoTargetPos(
00400 Vector& target, Vector& dir,
00401 float x, float y,
00402 double time_now, double time_lastCalc
00403 ) = 0;
00408 virtual bool validateTargetPosition(Vector& target, const Vector& oldTarget, const Vector& dir);
00412 virtual void updateLookAt(const Vector& pos, const Vector& dir);
00416 virtual BehaviorNode::InvalidationHint processKeyEvent(KeyEvent*);
00421 virtual void storeInitialInteractionParams(int x, int y, ButtonEvent*);
00426 virtual void storeCurrentInteractionParams(int x, int y, MotionEvent*);
00432 virtual BehaviorNode::InvalidationHint wakeUpNavigation();
00438 virtual bool keyCanWakeUpNavigation(KeyEvent*);
00441 virtual void initPhysicalNavigation(const Vector&);
00449 virtual bool detectCollisionPoint(Vector& collisionPoint, const Vector& pos, const Vector& dir);
00454 virtual bool detectGroundPoint(Vector& groundPoint, const Vector& pos);
00460 virtual bool detectHeight(float& height, const Vector& pos);
00468 float meterDefinition_;
00476 Vector position_, velocity_, acceleration_;
00478 Vector d_position_, d_velocity_, d_acceleration_;
00480
00481 Vector target_;
00483 Vector direction_;
00485
00486 enum SlowDownControlState {SDC_DEACTIVATED, SDC_TURNON, SDC_TURNOFF};
00489 VRS_SERIALIZABLE_CLASS_ENUM(SlowDownControlState);
00490
00491 SO<FilterTag> filterTag_;
00492
00493 Vector gravitationDir_;
00494
00495 Canvas* canvas_;
00497
00498
00499 private:
00500 void updatePhysicalModelData(
00501 Vector& pos, Vector& vel, Vector& acc,
00502 const Vector& d_pos, const Vector& d_vel, const Vector& d_acc
00503 );
00509 void solveMotionEquations(
00510 Vector& d_pos, Vector& d_vel, Vector& d_acc,
00511 const Vector& pos, const Vector& vel, const Vector& acc,
00512 Vector& targetPos, Vector& oldTargetPos,
00513 float timestep
00514 );
00530 virtual void interpolatePosition(Vector& pos, double now);
00535 protected:
00536 virtual BehaviorNode::InvalidationHint dragStart(int x, int y, ButtonEvent*);
00538 virtual BehaviorNode::InvalidationHint dragMotion(int x, int y, MotionEvent*);
00540 virtual BehaviorNode::InvalidationHint dragEnd(int x, int y, ButtonEvent*);
00542 virtual BehaviorNode::InvalidationHint handle(Event*);
00544
00545 PhysicalNavigation() { }
00546
00547 bool forceCalculation_;
00550 bool navigationIsSleeping_;
00557 private:
00558 float physical_inverse_mass_;
00561 float physical_viscosity_;
00565 float physical_viscosity_old_;
00569 SO<PhysicalForce> physical_force_;
00576 bool thisIsTheFirstCalculation_;
00578 double time_lastCalc_;
00580 double time_interactionStopped_;
00582 double timeout_;
00586 float time_calcInterval_;
00592 float referenceMousePos_x_, referenceMousePos_y_;
00594 float interaction_x_, interaction_y_;
00600 bool enableSlowDownControl_;
00603 SlowDownControlState slowDownControl_;
00605
00606
00607
00608 SO<Engine> engine_;
00610 SO<RayRequest> request_;
00612
00613 };
00614
00615 inline bool PhysicalNavigation::slowDownControlEnabled() {return enableSlowDownControl_;}
00616 inline double PhysicalNavigation::getMeterDefinition() const {return (double)meterDefinition_;}
00617 inline float PhysicalNavigation::getViscosity() const {return physical_viscosity_;}
00618
00619 }
00620
00621 #endif // VRS_SG_PHYSICALNAVIGATION_H