/** Find the closest point on target_ray to mouse_ray. * @returns false if rays are effectively parallel, true otherwise. */ bool InteractiveMarkerControl::findClosestPoint( const Ogre::Ray& target_ray, const Ogre::Ray& mouse_ray, Ogre::Vector3& closest_point ) { // Find the closest point on target_ray to any point on mouse_ray. // // Math taken from http://paulbourke.net/geometry/lineline3d/ // line P1->P2 is target_ray // line P3->P4 is mouse_ray Ogre::Vector3 v13 = target_ray.getOrigin() - mouse_ray.getOrigin(); Ogre::Vector3 v43 = mouse_ray.getDirection(); Ogre::Vector3 v21 = target_ray.getDirection(); double d1343 = v13.dotProduct( v43 ); double d4321 = v43.dotProduct( v21 ); double d1321 = v13.dotProduct( v21 ); double d4343 = v43.dotProduct( v43 ); double d2121 = v21.dotProduct( v21 ); double denom = d2121 * d4343 - d4321 * d4321; if( fabs( denom ) <= Ogre::Matrix3::EPSILON ) { return false; } double numer = d1343 * d4321 - d1321 * d4343; double mua = numer / denom; closest_point = target_ray.getPoint( mua ); return true; }
bool gkRayTest::collides(const Ogre::Ray& ray) { gkVector3 from = ray.getOrigin(); gkVector3 to = ray.getOrigin() + ray.getDirection(); gkRayTestFilter test; return gkRayTest::collides(from, to,test); }
VOID CEngineInterface::Camera_GetWindowToViewportRay(INT nX, INT nY, fRay& fRay) { Ogre::Ray ray = m_pFairySystem->getWindowToViewportRay(nX, nY); fVector3 fGFX = fVector3(ray.getOrigin().x, ray.getOrigin().y, ray.getOrigin().z); Axis_Trans(AX_GFX, fGFX, AX_GAME, fRay.mOrigin); fRay.mDirection = fVector3(ray.getDirection().x, ray.getDirection().y, ray.getDirection().z); }
void Selection3DDisplayCustom::raycastRequest(bool, int x, int y) { float win_width = render_panel_->width(); float win_height = render_panel_->height(); //then send a raycast straight out from the camera at the mouse's position Ogre::Ray mouseRay = this->render_panel_->getCamera()->getCameraToViewportRay((float)x/win_width, (float)y/win_height); // send ray data to other instances of OCS publishOCSRayRequest(RAYCAST_SELECTION, mouseRay.getOrigin(), mouseRay.getDirection()); // send ray data to onboard publishRayRequest(mouseRay.getOrigin(), mouseRay.getDirection()); }
void SelectionBox::performSelection(std::list<AgentId> &selection, Ogre::Camera *mCamera) { if((mRight - mLeft) * (mBottom - mTop) < 0.0001) return; float left = (mLeft + 1.f) / 2.f; float right = (mRight + 1.f) / 2.f; float top = (1.f - mBottom) / 2.f; float bottom = (1.f - mTop) / 2.f; Ogre::Ray topLeft = mCamera->getCameraToViewportRay(left, top); Ogre::Ray topRight = mCamera->getCameraToViewportRay(right, top); Ogre::Ray bottomLeft = mCamera->getCameraToViewportRay(left, bottom); Ogre::Ray bottomRight = mCamera->getCameraToViewportRay(right, bottom); // These planes have now defined an "open box" which extends to infinity in front of the camera. You can think of // the rectangle we drew with the mouse as being the termination point of the box just in front of the camera. Ogre::PlaneBoundedVolume vol; const Ogre::Real min = .1, max = 500; vol.planes.push_back(Ogre::Plane(topLeft.getPoint(min), topRight.getPoint(min), bottomRight.getPoint(min))); // front plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(max), topRight.getPoint(max))); // top plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(max), topLeft.getPoint(max))); // left plane vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(max), bottomLeft.getPoint(max))); // bottom plane vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(max), bottomRight.getPoint(max))); // right plane Ogre::PlaneBoundedVolumeList volList; volList.push_back(vol); mVolQuery->setVolumes(volList); Ogre::SceneQueryResult result = mVolQuery->execute(); // Finally we need to handle the results of the query. First we will deselect all previously selected objects, // then we will select all objects which were found by the query. std::list<Ogre::SceneNode *> nodes; Ogre::SceneQueryResultMovableList::iterator iter; for(iter = result.movables.begin(); iter != result.movables.end(); ++iter) { Ogre::MovableObject *movable = *iter; if(movable->getMovableType().compare("Entity") == 0) { Ogre::Entity *pentity = static_cast<Ogre::Entity *>(movable); nodes.push_back(pentity->getParentSceneNode()); } } mEngine->level()->getAgentsIdsFromSceneNodes(nodes, selection); }
gkCam2ViewportRay::gkCam2ViewportRay(gkScalar x, gkScalar y, gkScalar rayLength) { gkScene* pScene = gkEngine::getSingleton().getActiveScene(); GK_ASSERT(pScene); gkCamera* pCamera = pScene->getMainCamera(); GK_ASSERT(pCamera); gkVector2 pos(x, y); gkWindow* pWindow = pScene->getDisplayWindow(); if (pWindow == 0) pWindow = gkWindowSystem::getSingleton().getMainWindow(); GK_ASSERT(pWindow); gkScalar width = pWindow->getWidth(); gkScalar height = pWindow->getHeight(); GK_ASSERT(width && height); Ogre::Ray ray = pCamera->getCamera()->getCameraToViewportRay(pos.x / width, pos.y / height); gkVector3 p0 = ray.getOrigin(); gkVector3 p1 = p0 + ray.getDirection() * rayLength; setOrigin(p0); setDirection(p1 - p0); }
// ------------------------------------------------------------------------- void OgreBulletListener::button1Pressed() { // small unique impulse under cursor. Ogre::Vector3 pickPos; Ogre::Ray rayTo; OgreBulletDynamics::RigidBody * body = getBodyUnderCursorUsingBullet(pickPos, rayTo); //getBodyUnderCursorUsingOgre(pickPos, rayTo); if (body) { if (!(body->isStaticObject() || body->isKinematicObject() )) { body->enableActiveState (); const Ogre::Vector3 relPos (pickPos - body->getCenterOfMassPosition()); const Ogre::Vector3 impulse (rayTo.getDirection ()); body->applyImpulse (impulse * mImpulseForce, relPos); } getDebugLines(); mDebugRayLine->addLine (rayTo.getOrigin(), pickPos); mDebugRayLine->draw(); } }
//---------------------------------------------------------------------------------------- bool ObjectsViewWidget::OnDragMove(Ogre::Viewport *vp, unsigned int modifier, Ogre::Vector2& position) { if(mDragData.ObjectType == "") return false; if(!mDragData.Object) return true; Ogre::Ray mouseRay; mouseRay = vp->getCamera()->getCameraToViewportRay(position.x, position.y); Ogre::Vector3 vPos; mDragData.Object->getProperties()->getValue("position", vPos); bool hitfound = false; if(modifier & Ogitors::DragDropShiftModifier) { hitfound = OgitorsRoot::getSingletonPtr()->GetViewport()->GetHitPosition(mouseRay, vPos, mDragData.Object->getName()); } if(!hitfound) { if(vPos.x == 999999 && vPos.y == 999999 && vPos.z == 999999) vPos = mouseRay.getOrigin() + (mouseRay.getDirection() * 40.0f); else vPos = OgitorsRoot::getSingletonPtr()->GetGizmoIntersectCameraPlane(mDragData.Object, mouseRay); } mDragData.Object->getProperties()->setValue("position", vPos); return true; }
void ProjectManager::onSelectActorAtClickpoint(float mouseX, float mouseY) { assert(QThread::currentThread() == thread()); QOCamera* cameraNode = getCameraWithName("cam1"); if(!cameraNode) { qWarning("ProjectManager.onSelectActorAtClickpoint: Can't determine an actor to select " "without a corresponding CameraNode."); return; } Ogre::Camera* camera = cameraNode->camera(); if(!camera) { qWarning("ProjectManager.onSelectActorAtClickpoint: Can't determine an actor to select " "without a corresponding ogre camera."); return; } Ogre::Ray mouseRay = camera->getCameraToViewportRay(mouseX, mouseY); Scene* current = mScenarioManager.getCurrentScene(); QSharedPointer<Actor> hitActor = current->raycast(mouseRay.getOrigin(), mouseRay.getDirection()).actor.toStrongRef(); if(hitActor) { onActorChangeSelected(hitActor->getName(), !hitActor->getSceneNode()->getShowBoundingBox()); } }
void InputListener::shootingMouvements(const Ogre::FrameEvent& evt) { if (this->_Game->getGun(this->_Game->getNextTeam()->getChoseGun()).getAfterEffect() == true) { if (this->_Game->getGun(this->_Game->getNextTeam()->getChoseGun()).afterEffect(evt.timeSinceLastFrame) == true) { this->changeTurn(); } else { this->_Game->doDamageToWorms(this->_Game-> getGun(this->_Game->getNextTeam()->getChoseGun()).getExplosion(), this->_Game-> getGun(this->_Game->getNextTeam()->getChoseGun()).getScale() / 20); } } else if (!this->_WormsApp->getSceneManager()->getScene("PlayScene")->getGame() ->getGun(this->_Game->getNextTeam()->getChoseGun()).getIsFree()) this->_Game->getGun(this->_Game->getNextTeam()->getChoseGun()).move(evt.timeSinceLastFrame, this->_CollisionMgr, this->_Game->getTeam()); if (this->_Mouse->getMouseState().buttonDown(OIS::MB_Left)) { if (this->_Game->getTeleportActivated()) { Ogre::Vector2 pos = this->_WormsApp->getUIManager()->teleportPressed(); pos.x = pos.x / this->_currentScene->getViewPort()->getActualWidth(); pos.y = pos.y / this->_currentScene->getViewPort()->getActualHeight(); Ogre::Ray ray = this->_currentScene->getCamera()->getCameraToViewportRay(pos.x, pos.y); Ogre::Vector3 newRay= ray.getOrigin() + (ray.getDirection() * 3); newRay.z = 0; _current->getNode()->setPosition(newRay); } } }
std::pair<bool, Real> doPicking(const Ogre::Ray& localRay, const CollisionModel& collisionModel, CullingMode cullingMode) { // Convert our ray to Opcode ray IceMaths::Ray world_ray( IceMaths::Point(localRay.getOrigin().x, localRay.getOrigin().y, localRay.getOrigin().z), IceMaths::Point(localRay.getDirection().x, localRay.getDirection().y, localRay.getDirection().z)); // Be aware we store triangle as ccw in collision mode, and Opcode treat it as cw, // so need to inverse cull mode here. Opcode::CullMode cullMode; switch (cullingMode) { default: case CULL_NONE: cullMode = Opcode::CULLMODE_NONE; break; case CULL_CLOCKWISE: cullMode = Opcode::CULLMODE_CCW; break; case CULL_ANTICLOCKWISE: cullMode = Opcode::CULLMODE_CW; break; } // Cull mode callback for Opcode struct Local { static Opcode::CullMode cullModeCallback(udword triangle_index, void* user_data) { return (Opcode::CullMode) (int) user_data; } }; std::pair<bool, Real> ret; // Do picking Opcode::CollisionFace picked_face; ret.first = Opcode::Picking(picked_face, world_ray, collisionModel.getOpcodeModel(), 0, 0, FLT_MAX, world_ray.mOrig, &Local::cullModeCallback, (void*) (int) cullMode); ret.second = ret.first ? picked_face.mDistance : 0; return ret; }
Ogre::Ray OgreMesh::transformRay(Ogre::Node *node, const Ogre::Ray &ray) { return ray; const Ogre::Vector3 &position = node->_getDerivedPosition(); const Ogre::Quaternion &orient = node->_getDerivedOrientation(); const Ogre::Vector3 &scale = node->_getDerivedScale(); Ogre::Vector3 newStart = (orient.Inverse() * (ray.getOrigin() - position)) / scale; Ogre::Vector3 newDirection = orient.Inverse() * ray.getDirection(); return Ogre::Ray(newStart, newDirection); }
bool Panel::injectMouseMoved(const Ogre::Ray& ray) { Ogre::Matrix4 transform; transform.makeTransform(mNode->getPosition(), mNode->getScale(), mNode->getOrientation()); Ogre::AxisAlignedBox aabb = mScreenRenderable->getBoundingBox(); aabb.transform(transform); pair<bool, Ogre::Real> result = Ogre::Math::intersects(ray, aabb); if (result.first == false) { unOverAllElements(); return false; } Ogre::Vector3 a,b,c,d; Ogre::Vector2 halfSize = (mSize/100) * 0.5f; a = transform * Ogre::Vector3(-halfSize.x,-halfSize.y,0); b = transform * Ogre::Vector3( halfSize.x,-halfSize.y,0); c = transform * Ogre::Vector3(-halfSize.x, halfSize.y,0); d = transform * Ogre::Vector3( halfSize.x, halfSize.y,0); result = Ogre::Math::intersects(ray, c, b, a); if (result.first == false) result = Ogre::Math::intersects(ray, c, d, b); if (result.first == false) { unOverAllElements(); return false; } if (result.second > mDistanceFromPanelToInteractWith) { unOverAllElements(); return false; } Ogre::Vector3 hitPos = (ray.getOrigin() + (ray.getDirection() * result.second)); Ogre::Vector3 localPos = transform.inverse() * hitPos; localPos.x += halfSize.x; localPos.y -= halfSize.y; localPos.x *= 100; localPos.y *= 100; // Cursor clip localPos.x = Ogre::Math::Clamp<Ogre::Real>(localPos.x, 0, mSize.x - 10); localPos.y = Ogre::Math::Clamp<Ogre::Real>(-localPos.y, 0, mSize.y - 18); mInternalMousePos = Ogre::Vector2(localPos.x, localPos.y); mMousePointer->position(mInternalMousePos); // Let's actualize the "over" for each elements for (size_t i=0; i < mPanelElements.size(); i++) mPanelElements[i]->isOver(mInternalMousePos); return true; }
std::vector<Unite *> RTSState::getUnitesInRectangleUnderCamera(const Rectangle<float> &rectangle) const { Ogre::PlaneBoundedVolume vol; Ogre::Camera *camera = m_gameEngine->cameraManager()->camera(); Ogre::Ray topLeft = camera->getCameraToViewportRay(rectangle.left, rectangle.top); Ogre::Ray topRight = camera->getCameraToViewportRay(rectangle.left + rectangle.width, rectangle.top); Ogre::Ray bottomLeft = camera->getCameraToViewportRay(rectangle.left, rectangle.top + rectangle.height); Ogre::Ray bottomRight = camera->getCameraToViewportRay(rectangle.left + rectangle.width, rectangle.top + rectangle.height); vol.planes.push_back(Ogre::Plane(topLeft.getPoint(1), topRight.getPoint(1), bottomRight.getPoint(1))); // front plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), topLeft.getPoint(100), topRight.getPoint(100))); // top plane vol.planes.push_back(Ogre::Plane(topLeft.getOrigin(), bottomLeft.getPoint(100), topLeft.getPoint(100))); // left plane vol.planes.push_back(Ogre::Plane(bottomLeft.getOrigin(), bottomRight.getPoint(100), bottomLeft.getPoint(100))); // bottom plane vol.planes.push_back(Ogre::Plane(topRight.getOrigin(), topRight.getPoint(100), bottomRight.getPoint(100))); // right plane Ogre::PlaneBoundedVolumeList volList; volList.push_back(vol); EngineManager *mng = m_gameEngine->getManager(); Ogre::PlaneBoundedVolumeListSceneQuery *query = mng->getGraphic()->getSceneManager()->createPlaneBoundedVolumeQuery(volList); Ogre::SceneQueryResult result = query->execute(); std::vector<Unite *> foundUnits; std::for_each(result.movables.begin(), result.movables.end(), [&foundUnits](Ogre::MovableObject * obj) { try { WorldObject *worldObj = Ogre::any_cast<WorldObject *>(obj->getUserObjectBindings().getUserAny()); Unite *unite = dynamic_cast<Unite *>(worldObj); foundUnits.push_back(unite); } catch (...) { } }); return foundUnits; }
bool NxOgreSample_SoftBodyApp::mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id) { if (arg.state.buttonDown(OIS::MB_Left)) { if (mSelectedVertex != -1) { mSoftBody->getPhysXSoftBody()->freeVertex(mSelectedVertex); mSelectedVertex = -1; } Ogre::Vector2 point(arg.state.X.abs,arg.state.Y.abs); Ogre::Ray ogreRay = mCameraMan->getCamera()->getCameraToViewportRay(point.x/arg.state.width,point.y/arg.state.height); NxRay nxRay(NxVec3(ogreRay.getOrigin().x,ogreRay.getOrigin().y,ogreRay.getOrigin().z),NxVec3(ogreRay.getDirection().x,ogreRay.getDirection().y,ogreRay.getDirection().z)); NxVec3 hit; if (!mSoftBody->getPhysXSoftBody()->raycast(nxRay,hit,mSelectedVertex)) mSelectedVertex = -1; } return true; }
void CameraDragMove::_onDrag(const Point& pt) { if (!mTerrainHitInfo.hitted) return; Ogre::Ray ray = getSceneManipulator()->getWindowToViewportRay(pt); if (!ray.getDirection().y) return; Ogre::Vector3 newPosition; // 对正交投影和透视投影分开处理 if (getSceneManipulator()->getCamera()->getProjectionType() == Ogre::PT_ORTHOGRAPHIC) { Real offsetx = mRay.getOrigin().x - ray.getOrigin().x; Real offsetz = mRay.getOrigin().z - ray.getOrigin().z; newPosition.x = getSceneManipulator()->getCamera()->getRealPosition().x + offsetx; newPosition.y = getSceneManipulator()->getCamera()->getRealPosition().y; newPosition.z = getSceneManipulator()->getCamera()->getRealPosition().z + offsetz; } else { Real length = (mTerrainHitInfo.position.y - mTerrainHitInfo.hitPosition.y) / ray.getDirection().y; newPosition = mTerrainHitInfo.hitPosition + ray.getDirection() * length; if (getSceneManipulator()->getCameraHeightLocked()) { newPosition.y += getTerrainData()->getHeightAt(newPosition.x, newPosition.z) - getTerrainData()->getHeightAt(mTerrainHitInfo.position.x, mTerrainHitInfo.position.z); } } getSceneManipulator()->setCameraPosition(newPosition); }
// ------------------------------------------------------------------------- void OgreBulletListener::button0Pressed() { // pick a body and try to drag it. Ogre::Vector3 pickPos; Ogre::Ray rayTo; OgreBulletDynamics::RigidBody * body = getBodyUnderCursorUsingBullet(pickPos, rayTo); //getBodyUnderCursorUsingOgre(pickPos, rayTo); if (body) { //other exclusions? if (!(body->isStaticObject() //|| body->isKinematicObject() )) { mPickedBody = body; mPickedBody->disableDeactivation(); const Ogre::Vector3 localPivot (body->getCenterOfMassPivot(pickPos)); OgreBulletDynamics::PointToPointConstraint *p2p = new OgreBulletDynamics::PointToPointConstraint(body, localPivot); mWorld->addConstraint(p2p); //save mouse position for dragging mOldPickingPos = pickPos; const Ogre::Vector3 eyePos(mCamera->getDerivedPosition()); mOldPickingDist = (pickPos - eyePos).length(); //very weak constraint for picking p2p->setTau (0.1f); mPickConstraint = p2p; } getDebugLines(); mDebugRayLine->addLine (rayTo.getOrigin(), pickPos); mDebugRayLine->draw(); } if (mGuiListener->getGui()->injectMouse(mInputListener->getAbsMouseX ()*mWindow->getWidth(), mInputListener->getAbsMouseY ()*mWindow->getHeight(), true)) { mGuiListener->hideMouse(); } else { mGuiListener->showMouse (); } }
bool GenericMousePicker::cast( const OIS::MouseEvent &e, const CEGUI::Point& mousePos, const Ogre::Camera *mCamera, Ogre::MovableObject **out, Ogre::uint32 mask) { Ogre::Ray mouseRay = mCamera->getCameraToViewportRay( mousePos.d_x/float(e.state.width), mousePos.d_y/float(e.state.height) ); return cast(mouseRay.getOrigin(), mouseRay.getDirection(), out, mask); }
bool XYOrbitViewController::intersectGroundPlane( Ogre::Ray mouse_ray, Ogre::Vector3 &intersection_3d ) { //convert rays into reference frame mouse_ray.setOrigin( target_scene_node_->convertWorldToLocalPosition( mouse_ray.getOrigin() ) ); mouse_ray.setDirection( target_scene_node_->convertWorldToLocalOrientation( Ogre::Quaternion::IDENTITY ) * mouse_ray.getDirection() ); Ogre::Plane ground_plane( Ogre::Vector3::UNIT_Z, 0 ); std::pair<bool, Ogre::Real> intersection = mouse_ray.intersects(ground_plane); if (!intersection.first) { return false; } intersection_3d = mouse_ray.getPoint(intersection.second); return true; }
void AIRayPathFinderStrategy::CalcLines(Ogre::Ray &line) { Vector3 start; Vector3 direction = line.getDirection(); Ogre::Quaternion quat; for (int i=0;i<LinesNumber-1;++i) { start = LineOrigins[i]; quat = start.getRotationTo(direction); start = quat*start; //matr.rotateVect(lines[i].start); Lines[i].setOrigin(start+line.getOrigin()); //lines[i].start += line.start; Lines[i].setDirection(start+direction); //lines[i].end = lines[i].start+v; } Lines[LinesNumber-1] = line; }
void NxOgreSample_SoftBodyApp::frameRenderingQueued(const Ogre::FrameEvent &evt) { mWorld->advance(evt.timeSinceLastFrame); if (mSelectedVertex != -1) { Ogre::Vector2 point(CEGUI::MouseCursor::getSingleton().getPosition().d_x/mWindow->getWidth(),CEGUI::MouseCursor::getSingleton().getPosition().d_y/mWindow->getHeight()); Ogre::Ray ogreRay = mCameraMan->getCamera()->getCameraToViewportRay(point.x,point.y); NxOgre::Ray nxRay; nxRay.mDirection.from(ogreRay.getDirection()); nxRay.mOrigin.from(ogreRay.getOrigin()); NxVec3 vec3 = (nxRay.mOrigin + 45 * nxRay.mDirection).as<NxVec3>(); mSoftBody->getPhysXSoftBody()->attachVertexToGlobalPosition(mSelectedVertex,vec3); } }
//-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ Math::Ray Camera::getViewportRay(int _x, int _y) { // Convert the values to Real Ogre::Real x((Ogre::Real)_x); Ogre::Real y((Ogre::Real)_y); // Normalise them based on the size of the screen. x = x / m_canvas.getWidth(); y = y / m_canvas.getHeight(); const Ogre::Ray ray = m_camera.getCameraToViewportRay(x, y); return Math::Ray( Math::Point3(ray.getOrigin().ptr()), Math::Vector3(ray.getDirection().ptr()) ); }
void SkyStar::followMouseRay(const Ogre::Ray& mouseRay) { std::pair<bool, Real> intersectPlane = Math::intersects(mouseRay, *_waterPlane); if (!intersectPlane.first) { std::pair<bool, Real> intersectR = Math::intersects(mouseRay, *_skyPlane); Vector3 pos = mouseRay.getOrigin() + mouseRay.getDirection() * intersectR.second; if (pos.x < -50) pos.x = -50; if (pos.x > 50) pos.x = 50; if (pos.z > 50) pos.z = 50; if (pos.z < -50) pos.z = - 50; _node->_setDerivedPosition(pos); } }
std::pair<bool, Ogre::Vector3> PhysicsSystem::castRay(float mouseX, float mouseY) { Ogre::Ray ray = mRender.getCamera()->getCameraToViewportRay( mouseX, mouseY); Ogre::Vector3 from = ray.getOrigin(); Ogre::Vector3 to = ray.getPoint(200); /// \todo make this distance (ray length) configurable btVector3 _from, _to; // OGRE to MW coordinates _from = btVector3(from.x, -from.z, from.y); _to = btVector3(to.x, -to.z, to.y); std::pair<std::string, float> result = mEngine->rayTest(_from, _to); if (result.first == "") return std::make_pair(false, Ogre::Vector3()); else { return std::make_pair(true, ray.getPoint(200*result.second)); /// \todo make this distance (ray length) configurable } }
void gkPickNode::CreatePick() { ReleasePick(); Ogre::Ray ray = GetRay(); gkRayTest rayTest; if (rayTest.collides(ray)) { const btCollisionObject* pCol = rayTest.getCollisionObject(); gkPhysicsController* pObj = static_cast<gkPhysicsController*>(pCol->getUserPointer()); m_pickedBody = dynamic_cast<gkRigidBody*>(pObj); if (m_pickedBody && !(pCol->isStaticObject() || pCol->isKinematicObject())) { btRigidBody* body = m_pickedBody->getBody(); m_angularFactor = gkVector3(body->getAngularFactor()); if (GET_SOCKET_VALUE(DISABLE_ROTATION)) { body->setAngularFactor(0); } m_activationState = body->getActivationState(); body->setActivationState(DISABLE_DEACTIVATION); const gkVector3& hitPointWorld = rayTest.getHitPoint(); btVector3 hitPos(hitPointWorld.x, hitPointWorld.y, hitPointWorld.z); btVector3 localPivot = body->getCenterOfMassTransform().inverse() * hitPos; m_constraint = new btPoint2PointConstraint(*body, localPivot); static btScalar mousePickClamping = 30.f; m_constraint->m_setting.m_impulseClamp = mousePickClamping; btDynamicsWorld* pWorld = m_scene->getDynamicsWorld()->getBulletWorld(); GK_ASSERT(pWorld); pWorld->addConstraint(m_constraint, false); Vector3 from = ray.getOrigin(); Vector3 to = ray.getOrigin() + ray.getDirection(); btVector3 rayFrom(from.x, from.y, from.z); btVector3 rayTo(to.x, to.y, to.z); //save mouse position for dragging m_oldPickingPos = rayTo; m_oldPickingDist = (hitPos - rayFrom).length(); //very weak constraint for picking m_constraint->m_setting.m_tau = 0.1f; SET_SOCKET_VALUE(PICKED_OBJ, m_pickedBody->getObject()); SET_SOCKET_VALUE(CAUGHT_TRUE, true); SET_SOCKET_VALUE(CAUGHT_FALSE, false); } else { m_pickedBody = 0; } } }
ray::ray(const Ogre::Ray &vec) : mOrigin(vec.getOrigin()) , mDirection(vec.getDirection()) { ; }
bool OgreNewtonFrameListener::frameStarted(const FrameEvent &evt) { mKeyboard->capture(); mMouse->capture(); // ---------------------------------------- // CAMERA CONTROLS // ---------------------------------------- if ((mKeyboard->isKeyDown(OIS::KC_LSHIFT)) || (mKeyboard->isKeyDown(OIS::KC_RSHIFT))) { Vector3 trans, strafe, vec; Quaternion quat; quat = mCamera->getOrientation(); vec = Vector3(0.0,0.0,-0.5); trans = quat * vec; vec = Vector3(0.5,0.0,0.0); strafe = quat * vec; mCamera->pitch( Degree(mMouse->getMouseState().Y.rel * -0.5) ); mCamera->setFixedYawAxis(true); mCamera->yaw( Degree(mMouse->getMouseState().X.rel * -0.5) ); if (mKeyboard->isKeyDown(OIS::KC_UP)) mCamera->moveRelative(trans); if (mKeyboard->isKeyDown(OIS::KC_DOWN)) mCamera->moveRelative(trans * -1.0); if (mKeyboard->isKeyDown(OIS::KC_LEFT)) mCamera->moveRelative(strafe * -1.0); if (mKeyboard->isKeyDown(OIS::KC_RIGHT)) mCamera->moveRelative(strafe); } // ---------------------------------------- // DRAGGING! // ---------------------------------------- if (!dragging) { //user pressing the left mouse button? if (mMouse->getMouseState().buttonDown(OIS::MB_Left)) { // perform a raycast! // start at the camera, and go for 100 units in the Z direction. Ogre::Vector3 start, end; CEGUI::Point mouse = CEGUI::MouseCursor::getSingleton().getPosition(); CEGUI::Renderer* rend = CEGUI::System::getSingleton().getRenderer(); Ogre::Real mx,my; mx = mouse.d_x / rend->getWidth(); my = mouse.d_y / rend->getHeight(); Ogre::Ray camray = mCamera->getCameraToViewportRay(mx,my); start = camray.getOrigin(); end = camray.getPoint( 100.0 ); OgreNewt::BasicRaycast* ray = new OgreNewt::BasicRaycast( m_World, start, end, true ); OgreNewt::BasicRaycast::BasicRaycastInfo info = ray->getFirstHit(); if (info.mBody) { // a body was found. first let's find the point we clicked, in local coordinates of the body. // while dragging, make sure the body can't fall asleep. info.mBody->unFreeze(); //info.mBody->setAutoFreeze(0); Ogre::Vector3 bodpos; Ogre::Quaternion bodorient; info.mBody->getPositionOrientation( bodpos, bodorient ); // info.mDistance is in the range [0,1]. Ogre::Vector3 globalpt = camray.getPoint( 100.0 * info.mDistance ); Ogre::Vector3 localpt = bodorient.Inverse() * (globalpt - bodpos); // now we need to save this point to apply the spring force, I'm using the userData of the bodies in this example. // (where is it used? probably not needed here...) #ifndef OGRENEWT_NO_OGRE_ANY info.mBody->setUserData( Ogre::Any(this) ); #else info.mBody->setUserData( this ); #endif // now change the force callback from the standard one to the one that applies the spring (drag) force. // this is an example of binding a callback to a member of a specific class. in previous versions of OgreNewt you were // required to use a static member function fr all callbacks... but now through the fantastic FastDelegate library, you can // now use callbacks that are members of specific classes. to do this, use the syntax shown below. the "this" is a pointer // to the specific class, and the 2nd parameter is a pointer to the function you want to use. you can do this for all // body callbacks (ForceAndTorque, Transform, addBuoyancyPlane). info.mBody->setCustomForceAndTorqueCallback<OgreNewtonFrameListener>( &OgreNewtonFrameListener::dragCallback, this ); // save the relevant drag information. dragBody = info.mBody; dragDist = (100.0 * info.mDistance); dragPoint = localpt; dragging = true; } delete ray; } if (mDragLine) remove3DLine(); } else { // currently dragging! if (!mMouse->getMouseState().buttonDown(OIS::MB_Left)) { // no longer holding mouse button, so stop dragging! // remove the special callback, and put it back to standard gravity. dragBody->setStandardForceCallback(); //dragBody->setAutoFreeze(1); dragBody = NULL; dragPoint = Ogre::Vector3::ZERO; dragDist = 0.0; dragging = false; } } OgreNewt::Debugger& debug(m_World->getDebugger()); if (mKeyboard->isKeyDown(OIS::KC_F3)) { debug.showDebugInformation(); debug.startRaycastRecording(); debug.clearRaycastsRecorded(); } else { debug.hideDebugInformation(); debug.clearRaycastsRecorded(); debug.stopRaycastRecording(); } if (mKeyboard->isKeyDown(OIS::KC_T)) m_World->setThreadCount( m_World->getThreadCount() % 2 + 1); if (mKeyboard->isKeyDown(OIS::KC_ESCAPE)) return false; return true; }
bool AxisRenderable::collideAxis(Ogre::Ray& ray) { Ogre::Vector3 dir = getWorldPosition() - ray.getOrigin(); Ogre::Real mAxisGizmoProjLen = mLength / mViewport->getActualWidth() * dir.length() * Ogre::Math::Tan(mCamera->getFOVy()); dir.normalise(); mAxisGizmoSelAxis = -1; // find axis to use... for(unsigned int i = 0; i < 3; i++) { Ogre::Vector3 up, normal; up = dir.crossProduct(mAxisGizmoVector[i]); normal = up.crossProduct(mAxisGizmoVector[i]); if(normal.isZeroLength()) break; Ogre::Plane plane(normal,getWorldPosition()); // width of the axis poly is 1/10 the run Ogre::Vector3 a = up * mAxisGizmoProjLen / 10; Ogre::Vector3 b = mAxisGizmoVector[i] * mAxisGizmoProjLen; Ogre::Vector3 poly [] = { Ogre::Vector3(getWorldPosition() + a), Ogre::Vector3(getWorldPosition() + a + b), Ogre::Vector3(getWorldPosition() - a + b), Ogre::Vector3(getWorldPosition() - a) }; Ogre::Vector3 end = ray.getPoint(mProjectDistance); Ogre::Real t = intersect(&plane,ray.getOrigin(), end); if(t >= 0 && t <= 1) { Ogre::Vector3 pos = interpolate(ray.getOrigin(), end, t); // check if inside our 'poly' of this axis vector... bool inside = true; for(unsigned int j = 0; inside && (j < 4); j++) { unsigned int k = (j+1) % 4; Ogre::Vector3 vec1 = poly[k] - poly[j]; Ogre::Vector3 vec2 = pos - poly[k]; if(vec1.dotProduct(vec2) >0.f) inside = false; } // if(inside) { mAxisGizmoSelAxis = i; return(true); } } } return(false); }
std::pair<bool, Real> rayCollide(const Ogre::Ray& ray, Ogre::MovableObject* movable, bool accurate, CullingMode cullingMode, bool allowAnimable) { // Get local space axis aligned bounding box const Ogre::AxisAlignedBox& aabb = movable->getBoundingBox(); // Matrix4 to transform local space to world space const Ogre::Matrix4& localToWorld = movable->_getParentNodeFullTransform(); // Matrix4 to transform world space to local space Ogre::Matrix4 worldToLocal = localToWorld.inverse(); // Matrix3 to transform world space normal to local space Ogre::Matrix3 worldToLocalN; worldToLocal.extract3x3Matrix(worldToLocalN); // Convert world space ray to local space ray // Note: // By preserving the scale between world space and local space of the // direction, we don't need to recalculate the distance later. Ogre::Ray localRay; localRay.setOrigin(worldToLocal * ray.getOrigin()); localRay.setDirection(worldToLocalN * ray.getDirection()); // Intersect with axis aligned bounding box, but because we transformed // ray to local space of the bounding box, so this test just like test // with oriented bounding box. std::pair<bool, Real> ret = localRay.intersects(aabb); // Do accurate test if hitted bounding box and user required. if (ret.first && accurate) { if (movable->getMovableType() == Ogre::EntityFactory::FACTORY_TYPE_NAME || allowAnimable && movable->getMovableType() == Ogre::AutoAnimationEntityFactory::FACTORY_TYPE_NAME) { Ogre::Entity* entity = static_cast<Ogre::Entity*>(movable); if (!entity->_isAnimated()) { // Static entity // Get the entity mesh const Ogre::MeshPtr& mesh = entity->getMesh(); // Get the collision mode CollisionModelPtr collisionModel = CollisionModelManager::getSingleton().getCollisionModel(mesh); ret = doPicking(localRay, *collisionModel, cullingMode); } else if (allowAnimable) { // Animation entity bool addedSoftwareAnimation = false; if (entity->getSoftwareAnimationRequests() <= 0) { entity->addSoftwareAnimationRequest(false); entity->_updateAnimation(); addedSoftwareAnimation = true; } CollisionModel collisionModel; collisionModel.addEntity(entity); collisionModel.build(true); ret = doPicking(localRay, collisionModel, cullingMode); if (addedSoftwareAnimation) { entity->removeSoftwareAnimationRequest(false); } } } } return ret; }
void EntityWorldPickListener::processPickResult(bool& continuePicking, Ogre::RaySceneQueryResultEntry& entry, Ogre::Ray& cameraRay, const MousePickerArgs& mousePickerArgs) { if (!mContinuePickingThisContext) { return; } if (entry.worldFragment) { //this is terrain //a position of -1, -1, -1 is not valid terrain Ogre::SceneQuery::WorldFragment* wf = entry.worldFragment; static const Ogre::Vector3 invalidPos(-1, -1, -1); if (wf->singleIntersection != invalidPos) { if (mFurthestPickingDistance == 0 || mResult.empty()) { EntityPickResult result; result.entity = findTerrainEntity(); result.position = wf->singleIntersection; result.distance = entry.distance; result.isTransparent = false; mResult.push_back(result); mContinuePickingThisContext = false; } else { if (entry.distance < mResult[mResult.size() - 1].distance) { //If the last result is transparent, add another result, but if it's not replace it. if (mResult.size() && !mResult[mResult.size() - 1].isTransparent) { mResult.pop_back(); } EntityPickResult result; result.entity = findTerrainEntity(); result.position = wf->singleIntersection; result.distance = entry.distance; result.isTransparent = false; mResult.push_back(result); mContinuePickingThisContext = false; } } } /* std::stringstream ss; ss << wf->singleIntersection; S_LOG_VERBOSE("Picked in terrain: " << ss.str() << " distance: " << mResult.distance);*/ } else if (entry.movable) { Ogre::MovableObject* pickedMovable = entry.movable; if (pickedMovable->isVisible() && pickedMovable->getUserObjectBindings().getUserAny().getType() == typeid(EmberEntityUserObject::SharedPtr)) { EmberEntityUserObject* anUserObject = Ogre::any_cast<EmberEntityUserObject::SharedPtr>(pickedMovable->getUserObjectBindings().getUserAny()).get(); //refit the opcode mesh to adjust for changes in the mesh (for example animations) anUserObject->refit(); ICollisionDetector* collisionDetector = anUserObject->getCollisionDetector(); if (collisionDetector) { CollisionResult collisionResult; collisionResult.collided = false; collisionResult.isTransparent = false; collisionDetector->testCollision(cameraRay, collisionResult); if (collisionResult.collided) { if (mFurthestPickingDistance == 0) { //If the current collision is transparent, also check for entities which are further away. if (!collisionResult.isTransparent) { //test all objects that fall into this distance mFurthestPickingDistance = (pickedMovable->getParentNode()->_getDerivedPosition() - cameraRay.getOrigin()).length() + pickedMovable->getBoundingRadius(); } } else { if (collisionResult.distance > mFurthestPickingDistance) { mContinuePickingThisContext = false; return; } else { if (!mResult.empty() && mResult[mResult.size() - 1].distance > collisionResult.distance) { //If the last result is transparent, add another result, but if it's not replace it. if (!mResult[mResult.size() - 1].isTransparent) { mResult.pop_back(); } } else { return; } } } EmberEntity& pickedEntity = anUserObject->getEmberEntity(); std::list<EmberEntity*> entities; entities.push_front(&pickedEntity); EmberEntity* entity = pickedEntity.getEmberLocation(); while (entity) { if (entity->getCompositionMode() == EmberEntity::CM_COMPOSITION) { entities.push_front(entity); } else if (entity->getCompositionMode() == EmberEntity::CM_COMPOSITION_EXCLUSIVE) { entities.clear(); entities.push_front(entity); } entity = entity->getEmberLocation(); } for (std::list<EmberEntity*>::const_iterator I = entities.begin(); I != entities.end(); ++I) { EntityPickResult result; result.entity = *I; result.position = collisionResult.position; result.distance = collisionResult.distance; result.isTransparent = collisionResult.isTransparent; mResult.push_back(result); } } } } } }