bool Hud::OnEvent(const SEvent& event) { if (!_showMinimap) return false; ISceneManager* scene; IVideoDriver* video; switch (Game::ToGameEvent(event)) { case EGE_ADDITIONAL_RENDER_STARTING: scene = _game->getDevice()->getSceneManager(); video = _game->getDevice()->getVideoDriver(); _previousCamera = scene->getActiveCamera(); scene->setActiveCamera(_minimapCamera); video->setRenderTarget(_minimapTexture); show(false); break; case EGE_ADDITIONAL_RENDER_FINISHED: scene = _game->getDevice()->getSceneManager(); video = _game->getDevice()->getVideoDriver(); scene->setActiveCamera(_previousCamera); video->setRenderTarget(NULL); show(true); break; } return false; }
// selectObject // detect list objs at rect void CDocument::selectObject( int x, int y, int w, int h, bool isControlHold ) { IView *pView = getIView(); ISceneManager *smgr = pView->getSceneMgr(); ICameraSceneNode *camera = smgr->getActiveCamera(); // if no camera if ( camera == NULL ) return; const SViewFrustum* viewFrustum = camera->getViewFrustum(); ISceneCollisionManager *collMan = smgr->getSceneCollisionManager(); int screenX = -1, screenY = -1; ArrayZoneIter iZone = m_zones.begin(), iEnd = m_zones.end(); while ( iZone != iEnd ) { ArrayGameObject* listObj = (*iZone)->getChilds(); ArrayGameObjectIter iObj = listObj->begin(), objEnd = listObj->end(); ISceneNode *pNode = NULL; while ( iObj != objEnd ) { CGameObject *pGameObj = (CGameObject*)(*iObj); pNode = pGameObj->getSceneNode(); if ( pNode != NULL && pGameObj->isVisible() ) { core::vector3df center = pGameObj->getPosition(); // check object is in frustum if ( viewFrustum->getBoundingBox().isPointInside( center ) ) { if ( pView->getScreenCoordinatesFrom3DPosition( center, &screenX, &screenY ) ) { if ( x <= screenX && screenX <= x + w && y <= screenY && screenY <= y + h ) { if ( isControlHold == false || pGameObj->getObjectState() == CGameObject::Normal ) m_selectObjects.push_back( pGameObj ); } // inselect } // getScreenCoordinatesFrom3DPosition } // frustum } iObj++; } iZone++; } }
bool isActive() { ISceneManager* smgr = irrDevice->getSceneManager(); if (smgr->getActiveCamera() == m_camNode) { return true; } return false; }
CGameCamera::CGameCamera() { m_targetObject = NULL; m_objectType = CGameObject::CameraObject; #ifdef GSEDITOR m_cameraMesh = NULL; #endif ISceneManager *smgr = getIView()->getSceneMgr(); // save old camera ICameraSceneNode *oldCam = smgr->getActiveCamera(); // create new camera m_camera = smgr->addCameraSceneNode(); m_camera->setFOV( core::degToRad(60.0f) ); m_camera->setFarValue( 8000.0f ); m_camera->grab(); core::vector3df pos(0,0,0); setPosition( pos ); core::vector3df target(1,0,0); setTarget( target ); #ifdef GSEDITOR CColladaMeshComponent *comp = new CColladaMeshComponent( this ); comp->loadFromFile( getIView()->getPath("data/editor/camera.dae") ); addComponent( comp ); setLighting( false ); m_cameraMesh = m_node; m_cameraMesh->setVisible( true ); ITriangleSelector *selector = smgr->createTriangleSelectorFromBoundingBox( m_cameraMesh ); m_cameraMesh->setTriangleSelector(selector); selector->drop(); #endif // set camera node m_node = m_camera; // restore camera smgr->setActiveCamera( oldCam ); m_animator = NULL; #ifndef GSGAMEPLAY setEditorCamera(); #else setFreeCamera(); #endif }
CGameCamera::~CGameCamera() { #ifdef GSEDITOR m_cameraMesh->drop(); #endif if ( getIView()->getActiveCamera() == this ) getIView()->setActiveCamera(NULL); ISceneManager *smgr = getIView()->getSceneMgr(); // set null camera on scenenode if ( smgr->getActiveCamera() == m_node ) smgr->setActiveCamera( NULL ); }
void CDR::update(NBEditor* editor, bool drag, rect<s32> offset) { if (!editor->state->project) { return; } if (!editor->state->settings->getBool("always_show_position_handle") && (editor->state->keys[KEY_LSHIFT] == EKS_UP) == (type == CDR_XY || type == CDR_XZ || type == CDR_ZY)) { return; } Node* node = editor->state->project->GetCurrentNode(); if (!node) { return; } NodeBox *box = node->GetCurrentNodeBox(); if (!box) { return; } ISceneManager * smgr = editor->state->device->getSceneManager(); if (drag) { // get mouse position position2di target = editor->state->mouse_position; target -= offset.UpperLeftCorner; // Get the ray line3d<irr::f32> ray = smgr->getSceneCollisionManager() ->getRayFromScreenCoordinates(target, smgr->getActiveCamera()); // Contains the output values vector3df wpos = vector3df(0, 0, 0); // The collision position // Not used, but required for function #if IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8 const ISceneNode* tmpNode; #else ISceneNode* tmpNode; #endif triangle3df tmpTri; // Execute ray smgr->getSceneCollisionManager()->getCollisionPoint(ray, editor->state->plane_tri, wpos, tmpTri, tmpNode); // Snapping wpos -= vector3df(node->position.X, node->position.Y, node->position.Z); if (window == VIEW_XZ) wpos.Z -= 0.1; if (editor->state->settings->getBool("snapping")) { wpos.X = floor((wpos.X + 0.5) * 16 + 0.5) / 16 - 0.5; wpos.Y = floor((wpos.Y + 0.5) * 16 + 0.5) / 16 - 0.5; wpos.Z = floor((wpos.Z + 0.5) * 16 + 0.5) / 16 - 0.5; } // Do node limiting if (editor->state->settings->getBool("limiting")) { // X Axis if (wpos.X < -0.5) { wpos.X = -0.5; } else if (wpos.X > 0.5) { wpos.X = 0.5; } // Y Axis if (wpos.Y < -0.5) { wpos.Y = -0.5; } else if (wpos.Y > 0.5) { wpos.Y = 0.5; } // Z Axis if (wpos.Z < -0.5) { wpos.Z = -0.5; } else if (wpos.Z > 0.5) { wpos.Z = 0.5; } } // Call required function if (type < CDR_XZ) { box->resizeNodeBoxFace(editor->state, type, wpos, editor->state->keys[KEY_LCONTROL] == EKS_DOWN); } else { box->moveNodeBox(editor->state, type, wpos); } node->remesh(); editor->triggerCDRmoved(); } vector3df pos = box->GetCenter(); switch (type) { case CDR_X_P: pos.X = box->two.X; break; case CDR_X_N: pos.X = box->one.X; break; case CDR_Y_P: pos.Y = box->two.Y; break; case CDR_Y_N: pos.Y = box->one.Y; break; case CDR_Z_P: pos.Z = box->two.Z; break; case CDR_Z_N: pos.Z = box->one.Z; break; default: break; } pos.X += node->position.X; pos.Y += node->position.Y; pos.Z += node->position.Z; vector2d<irr::s32> cpos = smgr->getSceneCollisionManager() ->getScreenCoordinatesFrom3DPosition( pos, smgr->getActiveCamera() #if !(IRRLICHT_VERSION_MAJOR == 1 && IRRLICHT_VERSION_MINOR < 8) , true #endif ); position = cpos + offset.UpperLeftCorner; visible = true; }
//получение объекта сцены, который выбра пользователем void CNrpMainScene::GetNodeAndIntersectionFromCursor_( scene::ISceneNode*& node, core::vector3df& point, bool &doubleClick ) { ISceneManager* smgr = _nrpEngine.GetSceneManager(); //координаты курсора на экране core::position2di pos = _nrpEngine.GetDevice()->getCursorControl()->getPosition(); //получаем луч для расчетов core::line3df line = smgr->getSceneCollisionManager()->getRayFromScreenCoordinates( pos, smgr->getActiveCamera() ); //здесь будет выбранный треугольник core::triangle3df tri; //получаем выбранный объект node = smgr->getSceneCollisionManager()->getSceneNodeAndCollisionPointFromRay( line, point, tri ); //устанавливаем флаг двойного нажатия мышкой doubleClick = ( selectedNode_ == node ) && ( GetTickCount() - lastTimeNodeSelect_ < 200 ); lastTimeNodeSelect_ = GetTickCount(); }
// selectObject // detect list objs at mouse xy void CDocument::selectObject( int mouseX, int mouseY, bool isControlHold ) { ISceneManager *smgr = getIView()->getSceneMgr(); ICameraSceneNode *camera = smgr->getActiveCamera(); // if no camera if ( camera == NULL ) return; ISceneCollisionManager *collMan = smgr->getSceneCollisionManager(); // get select ray core::line3df selectRay = getIView()->getSelectRay(); // check hit test core::vector3df intersection; core::triangle3df hitTriangle; // check select ISceneNode *selectedSceneNode = collMan->getSceneNodeAndCollisionPointFromRay ( selectRay, intersection, hitTriangle ); if ( selectedSceneNode ) { CGameObject *pObj = searchObject( selectedSceneNode->getID() ); // try find parent while ( pObj == NULL ) { selectedSceneNode = selectedSceneNode->getParent(); if ( selectedSceneNode == NULL ) break; pObj = searchObject( selectedSceneNode->getID() ); } // add to select list if ( pObj && pObj->isVisible() ) { if ( isControlHold == false || pObj->getObjectState() == CGameObject::Normal ) m_selectObjects.push_back( pObj ); else { pObj->setObjectState( CGameObject::Normal ); ArrayGameObjectIter i = m_selectObjects.begin(), iEnd = m_selectObjects.end(); while ( i != iEnd ) { if ( (*i) == pObj ) { m_selectObjects.erase( i ); break; } i++; } } } } }
int main() { // create device EventHandler receiver; Init(); Output(); ISceneNode* objects [MAX_OBJECTS]; IrrlichtDevice *device = createDevice(EDT_OPENGL, dimension2d<u32>(ResX, ResY), 32, fullscreen, false, vsync, &receiver); receiver.device = device; if (!device) return 1; IVideoDriver* driver = device->getVideoDriver(); ISceneManager* smgr = device->getSceneManager(); IGUIEnvironment* guienv = device->getGUIEnvironment(); HMDDescriptor HMD; // Parameters from the Oculus Rift DK1 HMD.hResolution = ResX; HMD.vResolution = ResY; HMD.hScreenSize = 0.14976; HMD.vScreenSize = 0.0936; HMD.interpupillaryDistance = 0.064; HMD.lensSeparationDistance = 0.064; HMD.eyeToScreenDistance = 0.041; HMD.distortionK[0] = 1.0; HMD.distortionK[1] = 0.22; HMD.distortionK[2] = 0.24; HMD.distortionK[3] = 0.0; HMDStereoRender renderer(device, HMD, 10); #ifdef OCCULUS ICameraSceneNode* camera = smgr->addCameraSceneNode(); camera->bindTargetAndRotation(false); camera->setTarget(vector3df(1,0,0)); #else ICameraSceneNode* camera = smgr->addCameraSceneNodeFPS(); #endif device->getCursorControl()->setVisible(false); // load a faerie IAnimatedMesh* faerie = smgr->getMesh("media/faerie.md2"); IAnimatedMeshSceneNode* faerieNode = smgr->addAnimatedMeshSceneNode(faerie); faerieNode->setMaterialTexture(0, driver->getTexture("media/faerie2.bmp")); faerieNode->setMaterialFlag(EMF_LIGHTING, false); faerieNode->setPosition(vector3df(40,190,-1030)); faerieNode->setRotation(vector3df(0,-90,0)); faerieNode->setMD2Animation(EMAT_SALUTE); // load a dwarf IAnimatedMesh* dwarf = smgr->getMesh("media/dwarf.x"); IAnimatedMeshSceneNode* dwarfNode = smgr->addAnimatedMeshSceneNode(dwarf); dwarfNode->setPosition(vector3df(40,-25,20)); Level currentLevel(device); currentLevel.makeLevel(0); smgr->setAmbientLight(video::SColorf(0.1,0.1,0.1,1)); ILightSceneNode* light1 = smgr->addLightSceneNode( camera , vector3df(0,0,0), video::SColorf(0.3f,0.4f,0.4f), 80.0f, 1 ); vector3df pos = vector3df(0,0,0); //naplníme tunel pøekážkama srand (time(NULL)); /* generate secret number between 1 and 10: */ for(int i = 0; i < MAX_OBJECTS; i++){ objects[i] = smgr->addCubeSceneNode(2); objects[i]->setMaterialFlag(EMF_LIGHTING, false); objects[i]->setPosition( vector3df( (rand() % 30) - 5, (rand() % 30) - 5, rand() % 80) ); } //device->setInputReceivingSceneManager(smgr); //použivane pro vector3df tempRot; irr::core::quaternion tempQ; irr::core::matrix4 tempM; float round = 0; while(device->run()) { round += 0.01; driver->beginScene(true, true, SColor(255,100,101,140)); for(int i = 0; i < MAX_OBJECTS; i++){ vector3df tmpPos = objects[i]->getPosition(); if(tmpPos.Z > pos.Z) continue; objects[i]->setPosition( vector3df( (rand() % 30) - 15, (rand() % 30) - 15, rand() % 80 + pos.Z) ); } #ifndef OCCULUS tempM.setRotationDegrees(vector3df(sin(round*0.5)*360-180, sin(round)*360-180, cos(round*0.8)*360-180)); // transform forward vector of camera irr::core::vector3df frv = irr::core::vector3df (0.0f, 0.0f, 1.0f); tempM.transformVect(frv); // transform upvector of camera irr::core::vector3df upv = irr::core::vector3df (0.0f, 1.0f, 0.0f); tempM.transformVect(upv); camera->setUpVector(upv); //set up vector of camera camera->setTarget(frv); //set target of camera (look at point) (thx Zeuss for correcting it) #endif if(pSensor){ Quatf quaternion = FusionResult.GetOrientation(); ICameraSceneNode* camera = smgr->getActiveCamera(); tempQ.set(-quaternion.z,quaternion.y,-quaternion.x, quaternion.w); tempQ.normalize(); tempQ.toEuler(tempRot); tempM.setRotationDegrees(tempRot); // transform forward vector of camera irr::core::vector3df frv = irr::core::vector3df (0.0f, 0.0f, 1.0f); tempM.transformVect(frv); // transform upvector of camera irr::core::vector3df upv = irr::core::vector3df (0.0f, 1.0f, 0.0f); tempM.transformVect(upv); camera->setUpVector(upv); //set up vector of camera camera->setTarget(frv); //set target of camera (look at point) (thx Zeuss for correcting it) // update absolute position camera->updateAbsolutePosition(); float yaw, pitch, roll; quaternion.GetEulerAngles<Axis_Y, Axis_X, Axis_Z>(&yaw, &pitch, &roll); camera->getParent()->setRotation( vector3df(RadToDegree(pitch),RadToDegree(yaw),RadToDegree(roll))); //camera->setRotation( vector3df(RadToDegree(-pitch),RadToDegree(-yaw),RadToDegree(roll))); //camera->setProjectionMatrix(ToMatrix(quaternion)); cout << " Yaw: " << RadToDegree(yaw) << ", Pitch: " << RadToDegree(pitch) << ", Roll: " << RadToDegree(roll) << endl; if (_kbhit()) exit(0); } #ifdef OCCULUS renderer.drawAll(smgr); #else smgr->drawAll(); #endif guienv->drawAll(); driver->endScene(); } device->drop(); Clear(); return 0; }
void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, UINT32 timeMs) { if (!node || node->getType() != ESNT_CAMERA) return; ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); if (firstUpdate) { camera->updateAbsolutePosition(); if (CursorControl) { CursorControl->setPosition(0.5f, 0.5f); CursorPos = CenterCursor = CursorControl->getRelativePosition(); } LastAnimationTime = timeMs; firstUpdate = false; } // If the camera isn't the active camera, and receiving input, then don't process it. if (!camera->isInputReceiverEnabled()) { firstInput = true; return; } if (firstInput) { allKeysUp(); firstInput = false; } ISceneManager * smgr = camera->getSceneManager(); if (smgr && smgr->getActiveCamera() != camera) return; // get time FLOAT32 timeDiff = (FLOAT32)(timeMs - LastAnimationTime); LastAnimationTime = timeMs; // update position Vector3 pos = camera->getPosition(); // Update rotation Vector3 target = (camera->getTarget() - camera->getAbsolutePosition()); Vector3 relativeRotation = target.getHorizontalAngle(); if (CursorControl) { if (CursorPos != CenterCursor) { relativeRotation.y -= (0.5f - CursorPos.x) * RotateSpeed; relativeRotation.x -= (0.5f - CursorPos.y) * RotateSpeed * MouseYDirection; // X < MaxVerticalAngle or X > 360-MaxVerticalAngle if (relativeRotation.x > MaxVerticalAngle * 2 && relativeRotation.x < 360.0f - MaxVerticalAngle) { relativeRotation.x = 360.0f - MaxVerticalAngle; } else if (relativeRotation.x > MaxVerticalAngle && relativeRotation.x < 360.0f - MaxVerticalAngle) { relativeRotation.x = MaxVerticalAngle; } // Do the fix as normal, special case below // reset cursor position to the centre of the window. CursorControl->setPosition(0.5f, 0.5f); CenterCursor = CursorControl->getRelativePosition(); // needed to avoid problems when the event receiver is disabled CursorPos = CenterCursor; } // Special case, mouse is whipped outside of window before it can update. IVideoDriver* driver = smgr->getVideoDriver(); Vector2 mousepos(UINT32(CursorControl->getPosition().x), UINT32(CursorControl->getPosition().y)); rect<UINT32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); // Only if we are moving outside quickly. bool reset = !screenRect.isPointInside(mousepos); if (reset) { // Force a reset. CursorControl->setPosition(0.5f, 0.5f); CenterCursor = CursorControl->getRelativePosition(); CursorPos = CenterCursor; } } // set target target.set(0, 0, Math::_max<Real>(1.f, pos.length())); Vector3 movedir = target; Matrix4 mat; mat.setRotationDegrees(Vector3(relativeRotation.x, relativeRotation.y, 0)); //mat.transformVect(target); target = mat.transformAffine(target); if (NoVerticalMovement) { mat.setRotationDegrees(Vector3(0, relativeRotation.y, 0)); //mat.transformVect(movedir); target = mat.transformAffine(target); } else { movedir = target; } movedir.normalise(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; if (CursorKeys[EKA_MOVE_BACKWARD]) pos -= movedir * timeDiff * MoveSpeed; // strafing Vector3 strafevect = target; strafevect = strafevect.crossProduct(camera->getUpVector()); if (NoVerticalMovement) strafevect.y = 0.0f; strafevect.normalise(); if (CursorKeys[EKA_STRAFE_LEFT]) pos += strafevect * timeDiff * MoveSpeed; if (CursorKeys[EKA_STRAFE_RIGHT]) pos -= strafevect * timeDiff * MoveSpeed; // For jumping, we find the collision response animator attached to our camera // and if it's not falling, we tell it to jump. if (CursorKeys[EKA_JUMP_UP]) { const ISceneNodeAnimatorList& animators = camera->getAnimators(); ISceneNodeAnimatorList::const_iterator it = animators.begin(); while (it != animators.end()) { if (ESNAT_COLLISION_RESPONSE == (*it)->getType()) { ISceneNodeAnimatorCollisionResponse * collisionResponse = static_cast<ISceneNodeAnimatorCollisionResponse *>(*it); if (!collisionResponse->isFalling()) collisionResponse->jump(JumpSpeed); } it++; } } // write translation camera->setPosition(pos); // write right target target += pos; camera->setTarget(target); }