📄 vpmulderpicker.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 + -