void showIndicator( bool show ) { assert(mIndicatorSceneNode); assert( mCurrentLightEntity && mDirectionalLightEntity ); // 如果是方向光 if ( mCurrentLightEntity == mDirectionalLightEntity ) { mIndicatorSceneNode->setVisible(show); mIndicatorSceneNode->showBoundingBox(false); // 获取到摄像机与地形的交点 Ogre::Vector3 pos; Ogre::Ray cameraRay( mSceneManipulator->getCamera()->getPosition(), mSceneManipulator->getCamera()->getDirection() ); bool hit = mSceneManipulator->getTerrainIntersects(cameraRay, pos); if (hit) { // 在地形上的一米处出现光源指示器 float height = mSceneManipulator->getTerrainData()->getHeightAt(pos.x, pos.z) + 100.0f; mIndicatorSceneNode->setPosition(pos.x, height, pos.z); } } else { mIndicatorSceneNode->showBoundingBox(show); } }
//------------------------------------------------------------------------------------- bool App::frameRenderingQueued(const Ogre::FrameEvent& evt) { if(mWindow->isClosed()) return false; if(mShutDown) return false; //Need to capture/update each device mKeyboard->capture(); mMouse->capture(); //Need to inject timestamps to CEGUI System. CEGUI::System::getSingleton().injectTimePulse(evt.timeSinceLastFrame); //---- handle terrain collisions //raycast to the ground from the camera Ogre::Vector3 camPos = mCamera->getPosition(); Ogre::Ray cameraRay(Ogre::Vector3(camPos.x, 5000.0f, camPos.z), Ogre::Vector3::NEGATIVE_UNIT_Y); mRaySceneQuery->setRay(cameraRay); Ogre::RaySceneQueryResult &result = mRaySceneQuery->execute(); Ogre::RaySceneQueryResult::iterator itr = result.begin(); //tell the player about the ground height if (itr != result.end() && itr->worldFragment) { m_pPlayerEntity->SetGroundHeight(itr->worldFragment->singleIntersection.y); } // return true; }
Ray Camera::GenerateRay(vec2 sample) { vec3 w = normalize(eyeinit - center); vec3 u = cross(upinit, w); u = normalize(u); vec3 v = cross(w, u); float alpha, beta; beta = tan(fovy / 2) * (Height / 2 - sample.y) / (Height / 2); alpha = tan(fovy / 2) * (sample.x - (Width / 2)) / (Width / 2) * Width / Height; Ray cameraRay(eyeinit, normalize(alpha * u - beta * v - w)); return cameraRay; }
void StandardModelIndicator::_setHitPoint(Real x, Real y) { Ogre::Vector3 position; Ogre::Ray cameraRay( getCamera()->getPosition(), getCamera()->getDirection() ); bool hit = getSceneManipulator()->getTerrainIntersects(cameraRay, position); mIntersectNode->setVisible(hit); if (hit) { mIntersectNode->setPosition(position); } }
bool AvatarTerrainCursor::getTerrainCursorPosition(const Ogre::Vector3** position) { bool shouldRecalculate = false; bool updated = false; //first check if the mouse has moved even one pixel, and if so force an update const MousePosition& mousePosition(Input::getSingleton().getMousePosition()); if (mousePosition.xPixelPosition != mLastMouseX || mousePosition.yPixelPosition != mLastMouseY) { shouldRecalculate = true; } else { //the mouse hasn't moved, perhaps the camera has? if (mLastCameraPosition != mCamera.getDerivedPosition() || mLastCameraOrientation != mCamera.getDerivedOrientation()) { //ok, the camera has moved, but has enough time elapsed since our last update to warrant a new update? long long now = Time::currentTimeMillis(); long long delta = now - mLastUpdated; // if enough time has lapsed, we'll update, otherwise we return the last known position if( delta > mUpdatePositionThreshold ) { shouldRecalculate = true; } } } if(shouldRecalculate) { // mark update time mLastUpdated = Time::currentTimeMillis(); mLastMouseX = mousePosition.xPixelPosition; mLastMouseY = mousePosition.yPixelPosition; mLastCameraPosition = mCamera.getDerivedPosition(); mLastCameraOrientation = mCamera.getDerivedOrientation(); // Check if camera ray intersects terrain Ogre::Ray cameraRay(mCamera.getCameraToViewportRay(mousePosition.xRelativePosition, mousePosition.yRelativePosition)); std::pair<bool, Ogre::Vector3> intersectResult = mTerrainAdapter.rayIntersects(cameraRay); if (intersectResult.first) { mLastTerrainPosition = intersectResult.second; updated = true; } // S_LOG_VERBOSE("getTerrainCursorPosition : Update ("<< mLastMouseX << "," << mLastMouseY << ")->" << Ogre::StringConverter::toString(mLastTerrainPosition)); } *position = &mLastTerrainPosition; // S_LOG_VERBOSE("getTerrainCursorPosition : return"); return updated; }
void CharacterGame::fixCamera(long elapsedTime) { static float cameraOffset = 0.0f; #define RAY_STEP_SIZE 0.1f Node* node = _scene->getActiveCamera()->getNode(); Vector3 cameraForward = node->getForwardVectorWorld(); cameraForward.normalize(); Vector3 cameraPosition = node->getTranslationWorld(); Vector3 focalPoint = cameraPosition + (cameraForward * CAMERA_FOCUS_RANGE); Ray cameraRay(cameraPosition, cameraPosition - focalPoint); float d = cameraRay.getOrigin().distanceSquared(focalPoint); Vector3 collisionPoint; PhysicsCollisionObject* cameraOcclusion = Game::getInstance()->getPhysicsController()->rayTest(cameraRay, CAMERA_FOCUS_RANGE, &collisionPoint); bool cameraCollision = false; if (cameraOcclusion) { Vector3 rayStep = cameraRay.getDirection() * RAY_STEP_SIZE; do { float d2 = cameraRay.getOrigin().distanceSquared(collisionPoint); if (d2 > d) break; // collision point is past the character (not obstructing the view) cameraCollision = true; // Step along the camera ray closer to the character cameraRay.setOrigin(cameraRay.getOrigin() - rayStep); // Prevent camera from moving past character if (cameraRay.getOrigin().distanceSquared(focalPoint) < (RAY_STEP_SIZE*RAY_STEP_SIZE)) break; } while ((cameraOcclusion = Game::getInstance()->getPhysicsController()->rayTest(cameraRay, CAMERA_FOCUS_RANGE, &collisionPoint))); } if (cameraCollision) { // Move camera float moveDistance = cameraPosition.distance(cameraRay.getOrigin()); //node->setTranslation(0, 0, 0); node->translateForward(moveDistance); cameraOffset += moveDistance; } else { // Reset camera if (cameraOffset != 0.0f) { node->translateForward(-cameraOffset); cameraOffset = 0.0f; // Call updateCamera again to ensure that moving back didn't cause a different // object to obstruct the view. fixCamera(elapsedTime); } } }