OSG自定义拖拽器
来源:互联网 发布:盈建科三维软件停止 编辑:程序博客网 时间:2024/05/29 14:16
#ifndef _OSG_TRACKBALL_AND_TRANSLATEAXIS_DRAGGER_#define _OSG_TRACKBALL_AND_TRANSLATEAXIS_DRAGGER_#include <osgManipulator/TrackballDragger>#include <osgManipulator/TranslateAxisDragger>#include <osgManipulator/TranslatePlaneDragger>#include <osgManipulator/RotateCylinderDragger>#include <osgManipulator/Dragger>/**@class TranslatePlaneDraggerXY [TranslatePlaneDraggerXY.h] *@brief 平面拖拽器XY * */class TranslatePlaneDraggerXY : public osgManipulator::TranslatePlaneDragger{public: // 修改平面操作器的方向 void setupDefaultGeometryXY();};/**@class RotateCylinderDraggerZ [RotateCylinderDraggerZ.h] *@brief 圆柱z拖拽器 * */class RotateCylinderDraggerZ : public osgManipulator::RotateCylinderDragger{public: // 修改圆柱体操作器的形状,使之壁薄,高度减小,上颜色 void setupDefaultGeometryZ(); osg::Geometry* createDiskGeometry(float radius, float offset, float z, unsigned int numSegments);protected: virtual bool handle(const osgManipulator::PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa) override;private: osg::ShapeDrawable* m_ptrCylinderDrawableOutter; osg::ShapeDrawable* m_ptrCylinderDrawableIntter;};/**@class TrackballAndTranslateAxisDragger[TrackballAndTranslateAxisDragger.h]*@brief 圆柱z拖拽和平面拖拽XY的合集//球形拖拽器和XYZ轴拖拽器的合集**/class CustomDragger : public osgManipulator::CompositeDragger{public: CustomDragger(); void setupDefaultGeometry();protected: virtual ~CustomDragger(); osg::ref_ptr<TranslatePlaneDraggerXY> m_translateAxisDraggerXY; osg::ref_ptr<RotateCylinderDraggerZ> m_rotateCylinderDragger; };#endif // _OSG_TRACKBALL_AND_TRANSLATEAXIS_DRAGGER_
#include "CustomDragger.h"void TranslatePlaneDraggerXY::setupDefaultGeometryXY(){ osg::Quat rotation; rotation.makeRotate(osg::Vec3(0.0f, 0.0f, 1.0f), osg::Vec3(0.0f, 1.0f, 0.0f)); _translate2DDragger->setMatrix(osg::Matrix(rotation)*osg::Matrix::translate(osg::Vec3(0.0, 0.0, 0.0)));}///////////////////////////////////////////////////////////////////////////////////////////////////////////////osg::Geometry* RotateCylinderDraggerZ::createDiskGeometry(float radius, float offset, float z, unsigned int numSegments){ osg::ref_ptr<osg::Vec4Array> boundaryColors = new osg::Vec4Array; //boundaryColors->push_back(osg::Vec4(0, 0, 0, 1.0)); const float angleDelta = 2.0f*osg::PI / float(numSegments); const unsigned int numPoints = (numSegments + 1) * 2; float angle = 0.0f; osg::Vec3Array* vertexArray = new osg::Vec3Array(numPoints); osg::Vec3Array* normalArray = new osg::Vec3Array(numPoints); unsigned int p = 0; for (unsigned int i = 0; i < numSegments; ++i, angle += angleDelta) { float c = cosf(angle); float s = sinf(angle); // Outer point (*vertexArray)[p].set(radius*c, radius*s, z); (*normalArray)[p].set(0.0, 0.0, -1.0); ++p; // Inner point (*vertexArray)[p].set((radius - offset)*c, (radius - offset)*s, z); (*normalArray)[p].set(0.0, 0.0, -1.0); ++p; } // do last points by hand to ensure no round off errors. (*vertexArray)[p] = (*vertexArray)[0]; (*normalArray)[p] = (*normalArray)[0]; ++p; (*vertexArray)[p] = (*vertexArray)[1]; (*normalArray)[p] = (*normalArray)[1]; osg::Geometry* geometry = new osg::Geometry; geometry->setVertexArray(vertexArray); geometry->setNormalArray(normalArray, osg::Array::BIND_PER_VERTEX); geometry->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, 0, vertexArray->size())); //geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX); // 填充圆柱的上下表面 //geometry->setColorArray(boundaryColors.get(), osg::Array::BIND_OVERALL); return geometry;}void RotateCylinderDraggerZ::setupDefaultGeometryZ(){ osg::Geode* geode = new osg::Geode; { osg::TessellationHints* hints = new osg::TessellationHints; hints->setCreateTop(false); hints->setCreateBottom(false); hints->setCreateBackFace(false); float radius = 1.0f; float height = 0.05f; float thickness = 0.02f; // outer cylinder osg::Cylinder* cylinder = new osg::Cylinder; cylinder->setHeight(height); cylinder->setRadius(radius); m_ptrCylinderDrawableOutter = new osg::ShapeDrawable(cylinder, hints); m_ptrCylinderDrawableOutter->setColor(osg::Vec4(1.0, 0, 0, 1.0)); geode->addDrawable(m_ptrCylinderDrawableOutter); // inner cylinder osg::Cylinder* cylinder1 = const_cast<osg::Cylinder*>(_projector->getCylinder()); cylinder1->setHeight(height); cylinder1->setRadius(radius - thickness); m_ptrCylinderDrawableIntter = new osg::ShapeDrawable(cylinder1, hints); m_ptrCylinderDrawableIntter->setColor(osg::Vec4(1.0, 0, 0, 1.0)); geode->addDrawable(m_ptrCylinderDrawableIntter); // top geode->addDrawable(createDiskGeometry(radius, thickness, height / 2, 100)); // bottom geode->addDrawable(createDiskGeometry(radius, thickness, - height / 2, 100)); } addChild(geode);}bool RotateCylinderDraggerZ::handle(const osgManipulator::PointerInfo& pointer, const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){ // Check if the dragger node is in the nodepath. if (!pointer.contains(this)) return false; switch (ea.getEventType()) { // Pick start. case (osgGA::GUIEventAdapter::PUSH): { // Get the LocalToWorld matrix for this node and set it for the projector. osg::NodePath nodePathToRoot; computeNodePathToRoot(*this, nodePathToRoot); osg::Matrix localToWorld = osg::computeLocalToWorld(nodePathToRoot); _projector->setLocalToWorld(localToWorld); _startLocalToWorld = _projector->getLocalToWorld(); _startWorldToLocal = _projector->getWorldToLocal(); if (_projector->isPointInFront(pointer, _startLocalToWorld)) _projector->setFront(true); else _projector->setFront(false); osg::Vec3d projectedPoint; if (_projector->project(pointer, projectedPoint)) { // Generate the motion command. osg::ref_ptr<osgManipulator::Rotate3DCommand> cmd = new osgManipulator::Rotate3DCommand(); cmd->setStage(osgManipulator::MotionCommand::START); cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld, _startWorldToLocal); // Dispatch command. dispatch(*cmd); // Set color to pick color. setMaterialColor(_pickColor, *this); m_ptrCylinderDrawableOutter->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); m_ptrCylinderDrawableIntter->setColor(osg::Vec4(1.0, 1.0, 0.0, 1.0)); _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld(); _prevRotation = osg::Quat(); aa.requestRedraw(); } return true; } // Pick move. case (osgGA::GUIEventAdapter::DRAG): { // Get the LocalToWorld matrix for this node and set it for the projector. osg::Matrix localToWorld = osg::Matrix(_prevRotation) * _startLocalToWorld; _projector->setLocalToWorld(localToWorld); osg::Vec3d projectedPoint; if (_projector->project(pointer, projectedPoint)) { osg::Vec3d prevProjectedPoint = _prevWorldProjPt * _projector->getWorldToLocal(); osg::Quat deltaRotation = _projector->getRotation(prevProjectedPoint, projectedPoint); osg::Quat rotation = deltaRotation * _prevRotation; // Generate the motion command. osg::ref_ptr<osgManipulator::Rotate3DCommand> cmd = new osgManipulator::Rotate3DCommand(); cmd->setStage(osgManipulator::MotionCommand::MOVE); cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld, _startWorldToLocal); cmd->setRotation(rotation); // Dispatch command. dispatch(*cmd); _prevWorldProjPt = projectedPoint * _projector->getLocalToWorld(); _prevRotation = rotation; aa.requestRedraw(); } return true; } // Pick finish. case (osgGA::GUIEventAdapter::RELEASE): { osg::ref_ptr<osgManipulator::Rotate3DCommand> cmd = new osgManipulator::Rotate3DCommand(); cmd->setStage(osgManipulator::MotionCommand::FINISH); cmd->setLocalToWorldAndWorldToLocal(_startLocalToWorld, _startWorldToLocal); // Dispatch command. dispatch(*cmd); // Reset color. setMaterialColor(_color, *this); m_ptrCylinderDrawableOutter->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); m_ptrCylinderDrawableIntter->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); aa.requestRedraw(); return true; } default: return false; }}///////////////////////////////////////////////////////////////////////////////////////////////////////////////CustomDragger::CustomDragger(){ m_translateAxisDraggerXY = new TranslatePlaneDraggerXY(); m_translateAxisDraggerXY->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); addChild(m_translateAxisDraggerXY.get()); addDragger(m_translateAxisDraggerXY.get()); m_rotateCylinderDragger = new RotateCylinderDraggerZ(); addChild(m_rotateCylinderDragger.get()); addDragger(m_rotateCylinderDragger.get()); setParentDragger(getParentDragger());}CustomDragger::~CustomDragger(){}void CustomDragger::setupDefaultGeometry(){ m_translateAxisDraggerXY->setupDefaultGeometry(); m_translateAxisDraggerXY->setupDefaultGeometryXY(); m_rotateCylinderDragger->setupDefaultGeometryZ();}
简述:为了实现仅允许在osg的XY平面进行平移和旋转的功能,这里创建了2个自定义拖拽器
1 osgManipulator::CompositeDragger提供给了用户自定义组合想要的拖拽器,你可以将任意简单的Dragger进行组合添加到CompositeDragger中
2 osgManipulator::TranslatePlaneDragger的默认拖拽器是平行于Z轴的,所以需要将_translate2DDragger进行矩阵变换;
osgManipulator::RotateCylinderDragger的圆柱体拖拽面积和颜色是可以进行自定义的
阅读全文
0 0
- OSG自定义拖拽器
- OSG 自定义数据类型 关键帧动画
- osg自定义操作器实现视图缩放
- 自定义OSG窗口大小(设置Osgiewer)
- osg中添加自定义事件UserEvent
- OSG
- osg
- OSG
- osg-
- OSG
- osg
- OSG
- OSG拖拽器简介与示例
- osg自定义场景物体和设置状态集
- 自定义回调控制OSG模型进行移动操作
- OSG 多视图 实现导航拖拽器
- OSG 单视图 hudCamera 实现导航拖拽器
- [osg]OSG的分格化
- 第26讲项目6-定期存款利息计算器
- Android开发艺术探索_View的工作原理(四)
- matlab练习程序(LBP,局部二值模型)
- PostgreSQL Daily Maintenance
- SDIO驱动总结
- OSG自定义拖拽器
- Java方法中通过传递参数改变变量的值
- 操作系统常见面试题目
- JAVA性能优化
- 素数
- 新网站如何快速被搜索引擎收录
- java利用qrcode生成带有logo的二维码(logo位置及大小自己调)
- thinkphp5.0中让某些记录优先展示
- GLIB编译