diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index fcdfc05e1..c33131423 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -36,6 +36,8 @@ void CSVRender::Object::clear() mObject.setNull(); clearSceneNode (mBase); + + // FIXME: also clear bullet objects } void CSVRender::Object::update() @@ -76,47 +78,21 @@ void CSVRender::Object::update() mObject = NifOgre::Loader::createObjects (mBase, "Meshes\\" + model); mObject->setVisibilityFlags (Element_Reference); - // mwrender/objects.cpp: insertBegin() - // - // creates a ChildSceneNode from root if one doesn't exist for that cell (CellStore*) - // creates a ChildSceneNode for that cell scene node - // set the position & scale of the new node (for the object) - // set the orientation of the new node - // set the new node as the basenode (for the object) - // - // render/cell.cpp: Cell() - // - // creates a ChildSceneNode from root - // set the position to origin <---- each object adjusts its position later - // pass the node when creating an Object - // - // render/object.cpp: Object() - // creates a ChildSceneNode from the cell scene node - // if (!mReferenceId.empty()) { const CSMWorld::CellRef& reference = getReference(); + + // position + Ogre::Vector3 position; + if (!mForceBaseToZero) + position = Ogre::Vector3(reference.mPos.pos[0], reference.mPos.pos[1], reference.mPos.pos[2]); + + // orientation Ogre::Quaternion xr (Ogre::Radian (-reference.mPos.rot[0]), Ogre::Vector3::UNIT_X); Ogre::Quaternion yr (Ogre::Radian (-reference.mPos.rot[1]), Ogre::Vector3::UNIT_Y); Ogre::Quaternion zr (Ogre::Radian (-reference.mPos.rot[2]), Ogre::Vector3::UNIT_Z); - bool placeable = false; // FIXME - mPhysics->addObject("meshes\\" + model, - mBase->getName(), - reference.mScale, - Ogre::Vector3(reference.mPos.pos[0], - reference.mPos.pos[1], - reference.mPos.pos[2]), - xr*yr*zr, - 0, 0, false, placeable); - mPhysics->addObject("meshes\\" + model, - mBase->getName(), - reference.mScale, - Ogre::Vector3(reference.mPos.pos[0], - reference.mPos.pos[1], - reference.mPos.pos[2]), - xr*yr*zr, - 0, 0, true, placeable); // FIXME: why again with raycasting? + mPhysics->addObject("meshes\\" + model, mBase->getName(), reference.mScale, position, xr*yr*zr); } } } @@ -173,10 +149,6 @@ CSVRender::Object::Object (const CSMWorld::Data& data, Ogre::SceneNode *cellNode update(); adjust(); - std::cout << "obj pos" + std::to_string(mBase->getPosition().x) - + ", " + std::to_string(mBase->getPosition().y) - + ", " + std::to_string(mBase->getPosition().z) << std::endl; - } CSVRender::Object::~Object() diff --git a/apps/opencs/view/render/pagedworldspacewidget.cpp b/apps/opencs/view/render/pagedworldspacewidget.cpp index c7d866360..c9991b58e 100644 --- a/apps/opencs/view/render/pagedworldspacewidget.cpp +++ b/apps/opencs/view/render/pagedworldspacewidget.cpp @@ -147,11 +147,7 @@ bool CSVRender::PagedWorldspaceWidget::adjustCells() ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2, height+200)); getSceneManager()->getRootSceneNode()->createChildSceneNode()->attachObject(manual); - manual->setVisible(true); - - std::cout << "cell pos" + std::to_string(ESM::Land::REAL_SIZE * iter->getX() + ESM::Land::REAL_SIZE/2) - + ", " + std::to_string(ESM::Land::REAL_SIZE * iter->getY() + ESM::Land::REAL_SIZE/2) - + ", " + std::to_string(height) << std::endl; + manual->setVisible(false); CSVRender::TextOverlay *textDisp = new CSVRender::TextOverlay(manual, getCamera(), iter->getId(mWorldspace)); @@ -190,6 +186,60 @@ void CSVRender::PagedWorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) } } } + + // mouse picking + // FIXME: need to virtualise mouse buttons + int viewportWidth = getCamera()->getViewport()->getActualWidth(); + int viewportHeight = getCamera()->getViewport()->getActualHeight(); + + float mouseX = (float) event->x()/viewportWidth; + float mouseY = (float) event->y()/viewportHeight; + + getPhysics()->castRay(mouseX, mouseY, NULL, NULL, getCamera()); + //Ogre::Ray mouseRay = getCamera()->getCameraToViewportRay(mouseX, mouseY); + + // Issue: Say 800 pixels (a typical viewport size) representing 8000 units (in one cell) + // So best case resolution is 10 units per pixel. + +#if 0 + Ogre::RaySceneQuery *rayScnQuery = getSceneManager()->createRayQuery(Ogre::Ray()); + rayScnQuery->setRay(mouseRay); + rayScnQuery->setSortByDistance(true); + // kinda works, but bounding box tests aren't accurate + Ogre::RaySceneQueryResult result = rayScnQuery->execute(); + + std::cout << "geometry: " + std::to_string(width()) + ", " + std::to_string(height()) << std::endl; + std::cout << "event: " + std::to_string(event->x()) + ", " + std::to_string(event->y()) << std::endl; + std::cout << "viewport: " + std::to_string(viewportWidth) + ", " + std::to_string(viewportHeight) << std::endl; + std::cout << "mouse: " + std::to_string(mouseX) + ", " + std::to_string(mouseY) << std::endl; + + std::cout << "camera: " + std::to_string(getCamera()->getPosition().x) + + ", " + std::to_string(getCamera()->getPosition().y) + + ", " + std::to_string(getCamera()->getPosition().z) + << std::endl; + std::cout << "ray origin: " + std::to_string(mouseRay.getOrigin().x) + + ", " + std::to_string(mouseRay.getOrigin().y) + + ", " + std::to_string(mouseRay.getOrigin().z) + << std::endl; + std::cout << "ray direction: " + std::to_string(mouseRay.getDirection().x) + + ", " + std::to_string(mouseRay.getDirection().y) + + ", " + std::to_string(mouseRay.getDirection().z) + << std::endl; + //std::cout << "fov" + std::to_string(getCamera()->getFOVy().valueDegrees()) << std::endl; + + Ogre::Vector3 res; + Ogre::Vector3 direction = mouseRay.getDirection(); + OgreRay ray(getSceneManager()); + //if(!clicked && ray.RaycastFromPoint(getCamera()->getPosition(), direction, res)) + if(!clicked && ray.RaycastFromPoint(mouseRay.getOrigin(), direction, res)) + { + //std::cout << "found: " << std::endl; + } + + Ogre::Root::getSingleton().renderOneFrame(); // FIXME: for testing (to show the bounding box) + + getSceneManager()->destroyQuery(rayScnQuery); +#endif } void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event) @@ -197,7 +247,6 @@ void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event if(event->button() == Qt::RightButton) { std::cout << "double clicked" << std::endl; - //getSceneManager()->setVisibilityMask (4294967295); getPhysics()->toggleDebugRendering(); } diff --git a/apps/opencs/view/world/physicssystem.cpp b/apps/opencs/view/world/physicssystem.cpp index 620b92980..5db37f068 100644 --- a/apps/opencs/view/world/physicssystem.cpp +++ b/apps/opencs/view/world/physicssystem.cpp @@ -1,5 +1,9 @@ #include "physicssystem.hpp" +#include +#include +#include // FIXME: renderOneFrame + #include //#include //#include @@ -27,19 +31,56 @@ namespace CSVWorld float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, - Ogre::Vector3* scaledBoxTranslation, - Ogre::Quaternion* boxRotation, - bool raycasting, + //Ogre::Vector3* scaledBoxTranslation, + //Ogre::Quaternion* boxRotation, + //bool raycasting, bool placeable) { //handleToMesh[node->getName()] = mesh; + mEngine->createAndAdjustRigidBody(mesh, name, scale, position, rotation, - scaledBoxTranslation, boxRotation, raycasting, placeable); + 0, 0, true, placeable); } void PhysicsSystem::toggleDebugRendering() { mEngine->toggleDebugRendering(); - //mEngine->setDebugRenderingMode(1); + mEngine->stepSimulation(0.0167); // FIXME: DebugDrawer::step() not accessible + Ogre::Root::getSingleton().renderOneFrame(); // FIXME: temporary workaround for immediate visual feedback + } + + /*std::pair*/ void PhysicsSystem::castRay(float mouseX, float mouseY, + Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera) + { + Ogre::Ray ray = camera->getCameraToViewportRay( + mouseX, + mouseY); + Ogre::Vector3 from = ray.getOrigin(); + Ogre::Vector3 to = ray.getPoint(200000); + //Ogre::Vector3 to = ray.getDirection(); + + btVector3 _from, _to; + _from = btVector3(from.x, from.y, from.z); + _to = btVector3(to.x, to.y, to.z); + + bool raycastingObjectOnly = true; + bool ignoreHeightMap = false; + Ogre::Vector3 norm; + std::pair result = mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm); + + if (result.first == "") + //return std::make_pair(false, Ogre::Vector3()); + std::cout << "no hit" << std::endl; + else + { + std::cout << "hit " << result.first + + " result " + std::to_string(result.second) << std::endl; + std::cout << "normal " + std::to_string(norm.x) + + ", " + std::to_string(norm.y) + + ", " + std::to_string(norm.z) << std::endl; + std::cout << "hit pos" + std::to_string(ray.getPoint(200000*result.second).x) + + ", " + std::to_string(ray.getPoint(200000*result.second).y) + + ", " + std::to_string(ray.getPoint(200000*result.second).z) << std::endl; + } } } diff --git a/apps/opencs/view/world/physicssystem.hpp b/apps/opencs/view/world/physicssystem.hpp index f96724e1d..0aeffc9b2 100644 --- a/apps/opencs/view/world/physicssystem.hpp +++ b/apps/opencs/view/world/physicssystem.hpp @@ -8,6 +8,7 @@ namespace Ogre class Vector3; class Quaternion; class SceneManager; + class Camera; } namespace OEngine @@ -36,12 +37,15 @@ namespace CSVWorld float scale, const Ogre::Vector3 &position, const Ogre::Quaternion &rotation, - Ogre::Vector3* scaledBoxTranslation = 0, - Ogre::Quaternion* boxRotation = 0, - bool raycasting=false, + //Ogre::Vector3* scaledBoxTranslation = 0, + //Ogre::Quaternion* boxRotation = 0, + //bool raycasting=false, bool placeable=false); void toggleDebugRendering(); + + /*std::pair*/ void castRay(float mouseX, float mouseY, + Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera); }; }