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 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 #ifndef  _SO_RAY_PICK_ACTION_
00052 #define  _SO_RAY_PICK_ACTION_
00053 
00054 #include <Inventor/SoLists.h>
00055 #include <Inventor/nodes/SoCamera.h>
00056 #include <Inventor/actions/SoPickAction.h>
00057 #include <Inventor/SbBox.h>
00058 #include <Inventor/lists/SoPickedPointList.h>
00059 
00060 class PickedPointListImpl;
00061 class HomTransfData;
00062 class SoDeviceContext;
00063 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00083 
00349 class  SoRayPickAction : public SoPickAction {
00350 
00351   SO_ACTION_HEADER(SoRayPickAction);
00352 
00353  public:
00354 
00361   static void setStereoMode(SoCamera::StereoMode stereoMode);
00362 
00365   static SoCamera::StereoMode getStereoMode();
00366 
00372   SoRayPickAction(const SbViewportRegion &viewportRegion);
00373 
00382   virtual void clearApplyResult();
00383 
00384   
00385 #ifndef HIDDEN_FROM_DOC
00386   virtual ~SoRayPickAction();
00387 #endif // HIDDEN_FROM_DOC
00388 
00390   
00391   
00392   
00393 
00394   enum PickingMode {
00401     DEFAULT,
00402 
00417     POINT_PICKING
00418 
00419     
00420     
00421   };
00422 
00428   void setPickingMode(PickingMode pickingMode);
00429 
00433   PickingMode getPickingMode() const;
00434 
00443   virtual void setPoint(const SbVec2s &viewportPoint);
00444 
00453   virtual void setPoint(const SbVec2f &viewportPoint);
00454 
00459   const SbVec2s&  getPoint() const       { return VPPoint; }
00460 
00466   const SbVec2f&  getPointFloat() const   { return VPPointFloat; }
00467 
00475   virtual void setNormalizedPoint(const SbVec2f &normPoint);
00476 
00486   const SbVec2f       getNormalizedPoint() const
00487     { return normVPPoint; }
00488 
00509   void                setRadius(float radius);
00510 
00514   float               getRadius() const
00515     { return VPRadius; }
00516 
00534   virtual void setRay(const SbVec3f &start, const SbVec3f &direction,
00535                       float nearDistance = -1.0,
00536                       float farDistance = -1.0);
00537 
00557   virtual void setRay(float fovy, const SbVec3f &start, const SbVec3f &direction,
00558                       float nearDistance = -1.0,
00559                       float farDistance = -1.0);
00560 
00565   void setPickAll(SbBool flag)                
00566     { pickAll = flag; }
00567 
00572   SbBool isPickAll() const            
00573     { return pickAll; }
00574 
00576   
00577   
00578   
00579 
00587   const SoPickedPointList &getPickedPointList() const;
00588   
00606   SoPickedPoint *getPickedPoint(int index = 0) const;
00607 SoDEPRECATED
00617   void clearPickedPointList();
00618 
00628   void enableRadiusForTriangles(SbBool flag);
00629  
00634   SbBool isRadiusEnableForTriangles();
00635 
00642   static void enableTriangleCulling(SbBool flag) ;
00643 
00644 
00648   static SbBool isTriangleCulling()
00649     { return s_triangleCullingEnabled; }
00650   
00656   void enableTexCoordsGeneration(const SbBool enable);
00657 
00662   void enableNormalsGeneration(const SbBool enable);
00663 
00668   SbBool isTexCoordsGenerationEnabled() const;
00669 
00674   SbBool isNormalsGenerationEnabled() const;
00675 
00689   void enableConicPickVolume(SbBool flag);
00690 
00694   inline SbBool isConicPickVolume()
00695   { return m_conicPickVolume; }
00696 
00698   virtual void apply( SoNode* node );
00699 
00701   virtual void apply( SoPath* path );
00702 
00704   virtual void apply(const SoPathList &pathList, SbBool obeysRules = FALSE) { SoAction::apply(pathList, obeysRules); }
00705 
00706 
00707  private:
00708 
00709   
00710   
00711   
00712   
00713   
00714   void computeWorldSpaceRay();
00715 
00716   
00717   
00718   SbBool hasWorldSpaceRay() const;
00719 
00720   
00721   
00722   
00723   
00724   
00725   
00726   
00727   
00728   
00729   
00730   
00731   void                setObjectSpace();
00732   void                setObjectSpace(const SbMatrix &matrix);
00733 
00734   
00735   
00736   
00737   
00738   
00739   
00740   
00741 
00742   
00743   
00744   SbBool intersect(const SbVec3f &v0,
00745                    const SbVec3f &v1,
00746                    const SbVec3f &v2,
00747                    SbVec3f &intersection, SbVec3f &barycentric,
00748                    SbBool &front) ;
00749 
00750   
00751   SbBool intersect(const SbVec3f &v0, const SbVec3f &v1,
00752                    SbVec3f &intersection) const;
00753 
00754   
00755   SbBool intersect(const SbVec3f &point) const;
00756 
00763   inline SbBool intersect(const SbBox3f &box, SbBool useFullViewVolume = TRUE)
00764   {
00765     SbXfBox3f xbox(box);
00766     return intersect(xbox, useFullViewVolume);
00767   }
00768 
00775   SbBool intersect(const SbXfBox3f &box, SbBool useFullViewVolume = TRUE);
00776 
00777 
00778   
00779   
00780   
00781   
00782   
00783   
00784   
00785   const SbViewVolume &getViewVolume() const
00786     { return objVol; }
00787 
00788   
00789   
00790   
00791   
00792   
00793   const SbLine &getLine() const
00794     { return objLine; }
00795 
00796   
00797   
00798   
00799   
00800   
00801   
00802   SbBool isBetweenPlanes(const SbVec3f &intersection) const;
00803 
00813   SoPickedPoint *addIntersection(const SbVec3f &objectSpacePoint);
00814 
00815   
00816   
00817   
00818   
00819   
00820   
00821   
00822   SoPickedPoint *addIntersection_ ( const SbVec3f &objectSpacePoint, PickedPointListImpl* ppimplptr );
00823   SoPickedPoint *addIntersection_( SoPickedPoint *pp, PickedPointListImpl* ppimplptr );
00824   SoPickedPoint *addIntersection_( SoPickedPoint *pp );
00825 
00826 
00827   
00828   
00829   
00830   SoPickedPoint *getUnsortedPickedPoint( int i ) const;
00831 
00832   
00833   
00834   int getPickedPointsListLength() const;
00835 
00836  private:
00837   
00838   virtual void beginTraversal(SoNode *node);
00839 
00840  private:
00841   static void initClass();
00842   static void exitClass();
00843 
00844   
00845   static SbBool isPickOptimSet()
00846   { return s_useAlternateIntersection; }
00847 
00848   
00849   
00850   static bool isPtCulledByClippingPlanes( const SbVec3f &worldPt, SoState *state, bool worldCoord = true );
00851 
00852   
00853   
00854   static bool isBboxCompletelyCulledByClippingPlanes( const SbBox3d& worldBBox, SoState* state, bool worldCoord = true );
00855   
00856   static bool isBboxCompletelyCulledByClippingPlanes( const SbBox3f& worldBBox, SoState* state, bool worldCoord = true );
00857   
00858   static bool arePointsCulledByAClippingPlane( const std::vector< SbVec3f>& pointVector, SoState* state, bool worldCoord = true );
00859 
00865   enum PickedProperties
00866   {
00868     NORMALS = 1 << 0,
00870     TEXCOORDS = 1 << 1,
00871     
00873     ALL = ~0
00874   };
00875 
00879   void enablePickedProperties(const enum PickedProperties pickedProperty, const SbBool enable);
00880 
00884   SbBool isPickedPropertiesEnabled(const enum PickedProperties pickedProperty) const;
00885 
00886   
00887   SbBool isEqual(const SoPickedPoint *pp0, const SoPickedPoint *pp1) const;
00888 
00889   
00890   
00891   SbBool isCloser(const SoPickedPoint *pp0, const SoPickedPoint *pp1) const;
00892   SbBool isCloser(const SbVec3f& p0, const SbVec3f& p1) const;
00893 
00894   
00895   double getDepth(const SbVec3f& p0) const;
00896 
00897   
00898   inline void resetCurrPathCache();
00899 
00900   enum PointPositionClassification
00901   {
00902     INSIDE = 0,
00903     BEHIND_FAR = 1,
00904     BEFORE_NEAR = 2,
00905     BESIDE_LEFT = 3,
00906     BESIDE_RIGHT = 4,
00907     UNDER_BOTTOM = 5,
00908     ABOVE_TOP = 6
00909   };
00910 
00911   PointPositionClassification homogeneSpaceIntersection( const SbVec3f &point, SbVec4f &pPoint ) const;
00912   SoPath *getClonedCurrPath();
00913 
00914   static bool isMTPickingActive();
00915 
00916   
00917   float getVPRadiusPixel() const ;
00918 
00919   
00920 
00921 
00922 
00923 
00924 
00925 
00926 
00927   void setPointSizeForPicking( float pointWidth, float pointHeight);
00928 
00929   
00930   void setPointSizeForPicking( const SbVec2f & pointSize)
00931   { setPointSizeForPicking(pointSize[0], pointSize[1]); }
00932 
00933   
00934   SbVec2f getPointSizeForPicking()
00935   { return SbVec2f( m_pointWidthForPicking, m_pointHeightForPicking ); }
00936 
00937   struct GPUPickInfo
00938   {
00939     bool isValid = false;
00940     SbVec3f modelPosition;
00941     uint32_t shapeId = 0;
00942     uint32_t faceId = 0;
00943     float distToPickCenter = 0.f;
00944   };
00945 
00946   bool canGPUPick() const;
00947 
00948   
00949   
00950   
00951   void renderGPUPickingScene( SoDeviceContext* ctx );
00952 
00953   
00954   
00955   
00956   std::vector<GPUPickInfo> getGPUPickInfo( SoDeviceContext* ctx ) const;
00957       
00958  private:
00959   SbBool lineWasSet;  
00960   SbBool rayWasComputed;      
00961   SbBool pickAll;     
00962   SbVec2s VPPoint;    
00963   SbVec2f VPPointFloat; 
00964   SbVec2f normVPPoint;        
00965   SbBool normPointSet;        
00966   float VPRadius;     
00967   SbMatrix objToWorld;        
00968   SbMatrix worldToObj;        
00969 
00970   
00971   
00972   
00973   SbViewVolume worldVol;
00974 
00975   
00976   
00977   
00978   
00979   SbBool clipToNear, clipToFar;
00980 
00981   
00982   
00983   SbLine  objLine;     
00984   SbLined objLineD;
00985   SbViewVolume objVol;                
00986 
00987   
00988   
00989   
00990   
00991   SbBool extraMatrixSet;
00992   SbMatrix extraMatrix;
00993 
00994   
00995   void computeMatrices();
00996 
00997   
00998   void computeObjVolAndLine();
00999 
01000   
01001   void setUpRayBBoxAndWMat( const SbVec3f ¢erPt );
01002 
01003   void evalCenterPts( SbVec3f ¢erPt, SbVec3d ¢erPtD, SbVec3d &projPtD );
01004 
01005   
01006   float getVPRadiusWorld() const ; 
01007 
01008   
01009   
01010   static float        rayDistance(const SbVec3f &start,
01011                                   const SbVec3f &direction,
01012                                   const SbVec3f &point);
01013 
01014   
01015   void setRayCommonProperties (const SbVec3f &start, const SbVec3f &direction, 
01016                                float fovy, float aspectRatio = 1.0f, float nearDistance=-1.0f, float farDistance=-1.0f);
01017 
01018   
01019   void initializeMembersAfterVPPointSet(bool normalizedPointSet);
01020 
01021 
01022 
01023   
01024   inline SbBool isInConicPickingVolume( const SbVec3f &intersection ) const;
01025 
01026   void initSetRayData ( const SbVec3f &start, const SbVec3f &direction,
01027                         float fovy, float aspectRatio = 1.0f, 
01028                         float nearDistance = -1.0f, float farDistance = -1.0f );
01029   
01030   
01031   SbBool m_canUseTriangleCulling;
01032   SbBox3f  m_rayBBox ; 
01033   
01034 
01035   
01036   
01037   SbMatrixd m_wmat;
01038   double m_wnear;
01039   double m_wfar;
01040   HomTransfData *m_htdta;
01041 
01042   
01043   SbBool canUseTriangleCulling() const
01044   { return (s_triangleCullingEnabled && m_canUseTriangleCulling); }
01045 
01046   static SbBool  s_triangleCullingEnabled ;
01047 
01048   
01049   static SbBool s_generateAllPickedProperties;
01050 
01051   
01052   static SoCamera::StereoMode s_stereoMode;
01053 
01054   
01055   static SbBool s_useAlternateIntersection;
01056 
01057   
01058   SbBool m_bEnableRadiusForTriangles;
01059 
01060   
01061   SbVec3f m_direction;
01062   SbVec3f m_start;
01063 
01064 private:
01068   template<typename SO_NODE_OR_SO_PATH> void commonApply(SO_NODE_OR_SO_PATH* nodeOrPath);
01069 
01070   float getCorrectedVPRadius() const;
01071 
01072   int m_pickedPropertiesMask;
01073   PickingMode m_pickingMode;
01074 
01075   int m_VPRadiusState;      
01076 
01077   
01078   float m_fovy;             
01079   float m_nearDistance;
01080   float m_farDistance;
01081   float m_aspectRatio;
01082 
01083   
01084   SbBool m_conicPickVolume;
01085 
01086   PickedPointListImpl *m_pickedPointListlImpl;
01087 
01088   
01089   
01090   
01091   float m_pointPickingErrorX;
01092   float m_pointPickingErrorY;
01093   
01094   float m_projSpaceWidth;
01095   float m_projSpaceHeight;
01096   
01097   float m_pointWidthForPicking;
01098   float m_pointHeightForPicking;
01099 
01100   uint64_t m_applyId;
01101   uint64_t m_lastGPUPickRenderApplyId;
01102 };
01103 
01104 inline 
01105 void SoRayPickAction::enableRadiusForTriangles(SbBool flag)
01106 {
01107   m_bEnableRadiusForTriangles = flag;  
01108 }
01109 
01110 inline
01111 SbBool SoRayPickAction::isRadiusEnableForTriangles()
01112 {
01113   return m_bEnableRadiusForTriangles;
01114 }
01115 #endif 
01116 
01117