Lo siento si esto es una repetición, pero estoy tratando de averiguar la implementación de SoRayPickAction en Open Inventor. Estoy tratando de implementarlo para que, cuando se hace clic en el mouse, seleccione un nodo particular para que pueda traducir, rotar, etc. Tengo tres nodos: escritorio, lámpara y marco (marco de imagen). Sin embargo, no creo que mi código esté bien. También tengo varios métodos, como MouseButtonCallback (que comprobará si se hace clic en el mouse y luego usar un navegador) y MouseMoveCallback (misma idea). Así que aquí está el código que tengo, ¿pero tienes alguna sugerencia? En este momento, bueno, no hace nada.SoRayPickAction en Open Inventor?
SbViewportRegion viewport(400,300);
SoRayPickAction m(viewport);
m.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
m.apply(callback_node);
const SoPickedPoint *mpp = m.getPickedPoint();
if(mpp != NULL) {
std::cout << "test" << std::endl;
}
Podría también conocer de una acción en OpenInventor que puede "colocar" un nodo en la escena, es decir, colocar la lámpara en la parte superior de la mesa, marco en la pared, etc. Es con las rutas? Ni siquiera sé lo que estoy buscando, desafortunadamente. ¡¡Muchas gracias por su ayuda!!
Editar: ¿Cómo se ve esto? SoSeparador * escritorio2; SoSeparador * lamp2; SoSeparador * pic_frame2; SoSeparador * elegido;
void MouseButtonCallback(void* data, SoEventCallback* node)
{
SoHandleEventAction* action = node->getAction();
const SoMouseButtonEvent* event = static_cast<const SoMouseButtonEvent*>(action- >getEvent());
Navigator* nav = static_cast<Navigator*>(data);
if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
nav->OnMouseDown(event, action);
else
nav->OnMouseUp(event, action);
const SbViewportRegion & viewportRegion = action->getViewportRegion();
SoRayPickAction pickAction(viewportRegion);
SbVec2s mousePos = event->getPosition(viewportRegion);
pickAction.setPoint(mousePos);
pickAction.setPickAll(TRUE);
pickAction.setRadius(2.0F);
pickAction.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
pickAction.apply(node);
const SoPickedPoint *mpp = pickAction.getPickedPoint();
if(mpp != NULL) {
SoPath *path = mpp->getPath();
if(desk2 != NULL && path->containsNode(desk2))
{ //but this doesn't respond with cout when I try to test it :(
if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
*picked = *desk2;
}
else if(lamp2 != NULL && path->containsNode(lamp2))
{
if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
*picked = *lamp2;
}
else if(pic_frame2 != NULL && path->containsNode(pic_frame2))
{
if (SoMouseButtonEvent::isButtonPressEvent(event, event->getButton()))
*picked = *pic_frame2;
}
action->setHandled();
}
void MouseMoveCallback(void* data, SoEventCallback* node)
{
SoHandleEventAction* action = node->getAction();
const SoLocation2Event* event = static_cast<const SoLocation2Event*>(action->getEvent());
Navigator* nav = static_cast<Navigator*>(data);
nav->OnMouseMove(event, action);
const SbViewportRegion & viewportRegion = action->getViewportRegion();
SoRayPickAction pickAction(viewportRegion);
SbVec2s mousePos = event->getPosition(viewportRegion);
pickAction.setPoint(mousePos);
pickAction.setPickAll(TRUE);
pickAction.setRadius(2.0F);
pickAction.setRay(SbVec3f(0.0,0.0,0.0), SbVec3f(0.0,0.0,-1.0));
pickAction.apply(node);
const SoPickedPoint *mpp = pickAction.getPickedPoint();
if(mpp != NULL) {
SoPath *path = mpp->getPath();
if(desk2 != NULL && path->containsNode(desk2))
{
*picked = *desk2; //can't remember how to set pointers, will figure that out
}
else if(lamp2 != NULL && path->containsNode(lamp2))
{
*picked = *lamp2;
}
else if(pic_frame2 != NULL && path->containsNode(pic_frame2))
{
*picked = *pic_frame2;
}
}
action->setHandled();
}
(part of main method)
//desk
SoTransform *desk_transform = new SoTransform;
desk_transform->translation.setValue(SbVec3f(380,340,330));
SoSeparator* desk2 = new SoSeparator();
desk2->addChild(desk_transform);
desk2->addChild(desk);
root->addChild(desk2);
SoTransformerManip* picked_transform = new SoTransformerManip();
picked_transform->translation.setValue(SbVec3f(200,340,330));
SoSeparator* pick2 = new SoSeparator();
pick2->addChild(picked_transform);
pick2->addChild(picked);
root->addChild(pick2);
std::auto_ptr<btCollisionShape> picked_shape(new btBoxShape(btVector3(10.0f, 10.0f, 10.0f)));
CollisionEngine* picked_collision = new CollisionEngine(collision_world.get(), picked_shape.get());
picked_collision->translation_in.connectFrom(&picked_transform->translation);
picked_collision->rotation_in.connectFrom(&picked_transform->rotation);
picked_transform->translation.connectFrom(&picked_collision->translation_out);
Genial, wow, muchas gracias, emsr !! Tu código tiene mucho sentido ahora. Disculpe, ¿qué es "RadomeSeparador"? ¿Y este código cambia si me doy cuenta de que, desafortunadamente, el escritorio, la lámpara y el marco son separadores en lugar de nodos? ¡Otra vez, gracias por tu ayuda! – m00nbeam360
Lo siento, radomeSeparador es de mi código ;-) Yo trabajo con aviones. Olvidé cambiarlo para que parezca tu código. Obviamente, querrás usar tus propios separadores. Además, un SoSeparator es un SoNode - es decir, SoSeparator hereda de SoNode (a través de SoGroup y tal vez algo más). SoNode es el padre de un montón de cosas en Inventor para que pueda elegir SoMaterial, SoTransform o lo que sea. – emsr
Lo siento, así que estoy un poco perdido. ¡Realmente odio las variables locales! Ya tengo los métodos MouseMoveCallback y MouseButtonCallback. Sin embargo, ¿cómo crees que puedo conectar los tres a un RayPickAction? ¡Muchas gracias por tu ayuda! – m00nbeam360