⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vpmulderpicker.cpp

📁 本站以C语言和Java语言、嵌入式开发、算法实现为主
💻 CPP
字号:
// vpMulderPicker.cpp: implementation of the vpMulderPicker class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "MFC122.h"
#include "vpMulderPicker.h"
#include <vpInputMouse.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
//构造函数
vpMulderPicker::vpMulderPicker()
{
	//新建los相交矢量
	m_isector = new vpIsectorLOS();
	//着色边界类
		
    m_boundsStrategy = new vrRenderStrategyBounds();
	m_boundsStrategy->setRenderGeometryEnable(true);//是否显示相应实体
    m_boundsStrategy->setLineWidth (1);//线的宽度,缺省为1
	//线的颜色
	m_boundsStrategy->setColor (1.0,1.0,0.0,1.0);
	//线框模式
	m_boundsStrategy->setWireframeEnable(true); 
	//加入到系统中
    m_boundsStrategy->ref();
    //vsNode节点
	selectedNode=NULL;
}

vpMulderPicker::~vpMulderPicker()
{
	//删除边界类
	m_boundsStrategy->unref();
}

void vpMulderPicker::setEnable(bool e)
{
	//设置picker的开关变量
	enabled=e;
}

void vpMulderPicker::setName(char *e)
{
	//设置相交矢量的名字
	m_isector->setName(e);

}

void vpMulderPicker::setTarget(const vsNode *e)
{
	//设置相交适量的目标
	m_isector->setTarget(e);

}

void vpMulderPicker::setIsectMask(unsigned long e)
{
	//选择相交矢量的掩码
	m_isector->setIsectMask(e);	
}


void vpMulderPicker::setRenderEnable(bool e)
{
	//设置相交矢量的着色
	m_isector->setRenderEnable(e);

}

void vpMulderPicker::setTargetMode(PickerTargetModeType e)
{
	//设置目标模式
	modeType=e;

}
void vpMulderPicker::setHighlightColor(float r, float g, float b, float a )
{
	//设置边框的高亮颜色
	m_boundsStrategy->setColor(r,g,b,a);

}

void vpMulderPicker::setRenderGeometryEnable(bool e)
{
	//设置几何体是否着色
	m_boundsStrategy->setRenderGeometryEnable(e);

}

void vpMulderPicker::setWireframeEnable(bool e)
{
	//设置是否线框模式
	m_boundsStrategy->setWireframeEnable(e);

}

void vpMulderPicker::setLineWidth(float e)
{
	//设置线宽
	m_boundsStrategy->setLineWidth(e);

}

bool vpMulderPicker::performPickProcessing(vpChannel *chan)
{
	//enable的值从何而来?
	if(!enabled){
		printf("vpMulderPicker::Error! Picker isn't enabled! \n");
		return false;
	}
    //getTarget()在何处定义?
	if(m_isector->getTarget()==NULL){
		printf("vpMulderPicker::Error! Please set target node! \n");
		return false;
	}
    //判断通道存在
	if(chan==NULL){
		printf("vpMulderPicker::Error! chan is NULL !\n");
		return false;
	}
    //开始鼠标?
	vpInputMouse *mouse = *vpInputMouse::begin();
	//获得鼠标的xy值
	vpInputSourceFloat *sourceX = mouse->getSourceFloat(vpInputMouse::SOURCE_FLOAT_POSITION_X);
	vpInputSourceFloat *sourceY = mouse->getSourceFloat(vpInputMouse::SOURCE_FLOAT_POSITION_Y);
	//判断是否能获得碰撞的节点
	vsNode *node = pick(chan,sourceX->getValue(), sourceY->getValue());
    
 	if (selectedNode != NULL)
		setRenderStrategy(selectedNode, NULL);//?

 	if ((node != NULL) && (node != selectedNode)) {
		setRenderStrategy(node, m_boundsStrategy);
		selectedNode = node;
		return true;
	}else{
		selectedNode = NULL;
		return false;
	}
	
}

//DEL void vpMulderPicker::notify(vsChannel::Event, const vsChannel *,
//DEL 		vsTraversalCull *)
//DEL {
//DEL }

 

vsNode *vpMulderPicker::pick(vpChannel *channel, float mx, float my)
 {

        float n, f;
        double x, y, z, h, p, r = 0.0, range;
        const vuMatrix<double> &viewMat = channel->getViewMatrix();
        channel->getNearFar(&n, &f);

         if (channel->getProjection() == vrChannel::PROJECTION_ORTHOGRAPHIC) {

            float l, r, b, t;
            channel->getFrustum(&l, &r, &b, &t);

            x = l + ((mx + 1.0f) * 0.5f) * (r - l);
            y = b + ((my + 1.0f) * 0.5f) * (t - b);
            z = viewMat[3][2] + n;
            h = 0.0;
            p = -90.0;
            range = f - n;

        }

         else {
             vuVec3<float> mouse(mx, my, -1);
            vuVec3<float> vec;
            vuMatrix<float> projInv;
            projInv.invert(channel->getVrChannel()->getProjectionMatrix());
            projInv.transformPoint(&mouse);
            channel->getVrChannel()->getOffsetMatrixInverse(
                ).transformPoint(&mouse);
            channel->getVrChannel()->getViewMatrix().transformPoint(&mouse);

             x = viewMat[3][0];
            y = viewMat[3][1];
            z = viewMat[3][2];

            vec[0] = mouse[0] - x;
            vec[1] = mouse[1] - y;
            vec[2] = mouse[2] - z;

             h = vuRad2Deg(-vuArcTan(vec[0], vec[1]));
            p = vuRad2Deg(vuArcTan(vec[2],
                vuSqrt(vuSq(vec[0]) + vuSq(vec[1]))));

            range = 2 * f;

        }

         m_isector->setTranslate(x, y, z);
        m_isector->setRotate(h, p, 0.0);
        m_isector->setSegmentRange(range);

         vsNode *node = NULL;
        m_isector->update();

         if (m_isector->getHit()) {

            switch(modeType) {

            case MODE_OBJECT: // pick the object
                node = (vsNode*)(m_isector->getHitObject());					
                break;

            case MODE_GEOMETRY: // pick the geometry
                node = m_isector->getHitNode();				
                break;

            case MODE_DOF: // pick the dof
                node = getParent(m_isector->getHitNode(), vsDOF::getStaticClassType());
  				
                break;

            case MODE_LOD: // pick the lod
                 node = getParent(m_isector->getHitNode(), vsLOD::getStaticClassType());
                 break;

			case MODE_NAMEDPART: //pick named part
				node = getParent(m_isector->getHitNode());
				vsNode *node1 = (vsNode*)(m_isector->getHitObject());
				if(node&&node1&&(strcmp(node->getName(),node1->getName())==0)){	
					//如果与根节点相同,不选
					node=NULL;
				}
				break;
            }

			vuVec3<double> *point=new vuVec3<double>;
			if(m_isector->getHitPoint(point)==vsgu::SUCCESS){
				point->get(&x,&y,&z);
			//	printf("查询三维坐标为:%.3f,%.3f,%.3f\n",(float)x,(float)y,(float)z);
			}

        }

        return node;

    }

 vsTraversal::Result vpMulderPicker::travFuncGeometry(vsNode *node, vrRenderStrategy *strategy)
    {
        vrGeometry *geometry = static_cast<vsGeometry *>(node)->getGeometry();
        geometry->setRenderStrategy(strategy);
        return vsTraversal::RESULT_CONTINUE;
    }

      void vpMulderPicker::setRenderStrategy(vsNode *root, vrRenderStrategy *strategy)
    {
  		vsTraversalUser<vrRenderStrategy *,vsTraversalLookUpNodeId> trav(strategy);
		trav.addPreVisit(vsGeometry::getStaticNodeId(), this, &vpMulderPicker::travFuncGeometry);
		trav.visit(root);       
    }


vsNode * vpMulderPicker::getParent(vsNode *child, vuClassType *classType)
{

        if (child != NULL) {
            vsNode::const_iterator_parent it, ite = child->end_parent();
            for(it=child->begin_parent();it!=ite;++it) {
                if((*it)->isOfClassType(classType))
                    return *it;
                else return getParent(*it, classType);
            }
        }
        return NULL;
}


vsNode * vpMulderPicker::getParent(vsNode *child)
{

        if (child != NULL) {
            vsNode::const_iterator_parent it, ite = child->end_parent();
            for(it=child->begin_parent();it!=ite;++it) {
                if((*it)->getName()!=NULL)
                    return *it;
                else return getParent(*it);
            }
        }
        return NULL;
}

//获得选择的节点
vsNode* vpMulderPicker::getSelectNode()
{
	return selectedNode;
}
//获得视点和对象碰撞的交点
vuVec3<double> * vpMulderPicker::get3DPos()
{
	vuVec3<double> *point=new vuVec3<double>;
	m_isector->getHitPoint(point);
	return point;
	//if(m_isector->getHitPoint(point)==vsgu::SUCCESS){
		//point->get(&x,&y,&z);
	//	return point;
	//}else

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -