Added debug lines to show ray hit position. Added highlighting the Entity hit by the ray. Incorporated user setting far clip distance.

loadfix
cc9cii 10 years ago
parent 4b53b8658b
commit fdee3fd919

@ -186,60 +186,30 @@ 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))
else
{
//std::cout << "found: " << std::endl;
}
// mouse picking
// FIXME: need to virtualise mouse buttons
// Issue: Say 800 pixels (a typical viewport size) representing 8000 units (in one cell)
// So best case resolution is 10 units per pixel.
int viewportWidth = getCamera()->getViewport()->getActualWidth();
int viewportHeight = getCamera()->getViewport()->getActualHeight();
Ogre::Root::getSingleton().renderOneFrame(); // FIXME: for testing (to show the bounding box)
float mouseX = (float) event->x()/viewportWidth;
float mouseY = (float) event->y()/viewportHeight;
getSceneManager()->destroyQuery(rayScnQuery);
getPhysics()->castRay(mouseX, mouseY, NULL, NULL, getCamera());
#if 0
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;
#endif
}
}
void CSVRender::PagedWorldspaceWidget::mouseDoubleClickEvent (QMouseEvent *event)

@ -51,6 +51,7 @@ namespace CSVRender
mCamera->setPosition (300, 0, 0);
mCamera->lookAt (0, 0, 0);
mCamera->setNearClipDistance (0.1);
//mCamera->setProjectionType(Ogre::PT_ORTHOGRAPHIC); // FIXME: debugging only
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();

@ -1,24 +1,82 @@
#include "physicssystem.hpp"
#include <iostream> // FIXME: debug only
#include <OgreRay.h>
#include <OgreCamera.h>
#include <OgreManualObject.h> // FIXME: debug cursor position
#include <OgreEntity.h> // FIXME: visual highlight, clone
#include <OgreMaterialManager.h> // FIXME: visual highlight, material
#include <OgreHardwarePixelBuffer.h> // FIXME: visual highlight, texture
#include <OgreRoot.h> // FIXME: renderOneFrame
#include <openengine/bullet/physic.hpp>
//#include <openengine/bullet/BtOgreExtras.h>
//#include <openengine/ogre/renderer.hpp>
#include <components/nifbullet/bulletnifloader.hpp>
#include "../../model/settings/usersettings.hpp"
namespace CSVWorld
{
PhysicsSystem::PhysicsSystem(Ogre::SceneManager *sceneMgr)
PhysicsSystem::PhysicsSystem(Ogre::SceneManager *sceneMgr) : mSceneMgr(sceneMgr)
{
// Create physics. shapeLoader is deleted by the physic engine
NifBullet::ManualBulletShapeLoader* shapeLoader = new NifBullet::ManualBulletShapeLoader();
mEngine = new OEngine::Physic::PhysicEngine(shapeLoader);
mEngine->setSceneManager(sceneMgr); // needed for toggleDebugRendering()
// material for visual cue
Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("DynamicTrans");
if(texture.isNull())
{
texture = Ogre::TextureManager::getSingleton().createManual(
"DynamicTrans", // name
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,
Ogre::TEX_TYPE_2D, // type
8, 8, // width & height
0, // number of mipmaps
Ogre::PF_BYTE_BGRA, // pixel format
Ogre::TU_DEFAULT); // usage; should be TU_DYNAMIC_WRITE_ONLY_DISCARDABLE for
// textures updated very often (e.g. each frame)
Ogre::HardwarePixelBufferSharedPtr pixelBuffer = texture->getBuffer();
pixelBuffer->lock(Ogre::HardwareBuffer::HBL_NORMAL);
const Ogre::PixelBox& pixelBox = pixelBuffer->getCurrentLock();
uint8_t* pDest = static_cast<uint8_t*>(pixelBox.data);
// Fill in some pixel data. This will give a semi-transparent colour,
// but this is of course dependent on the chosen pixel format.
for (size_t j = 0; j < 8; j++)
{
for(size_t i = 0; i < 8; i++)
{
*pDest++ = 255; // B
*pDest++ = 255; // G
*pDest++ = 127; // R
*pDest++ = 63; // A
}
pDest += pixelBox.getRowSkip() * Ogre::PixelUtil::getNumElemBytes(pixelBox.format);
}
pixelBuffer->unlock();
}
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().getByName(
"TransMaterial");
if(material.isNull())
{
Ogre::MaterialPtr material = Ogre::MaterialManager::getSingleton().create(
"TransMaterial",
Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true );
Ogre::Pass *pass = material->getTechnique( 0 )->getPass( 0 );
pass->setLightingEnabled( false );
pass->setDepthWriteEnabled( false );
pass->setSceneBlending( Ogre::SBT_TRANSPARENT_ALPHA );
Ogre::TextureUnitState *tex = pass->createTextureUnitState("CustomState", 0);
tex->setTextureName("DynamicTrans");
tex->setTextureFiltering( Ogre::TFO_ANISOTROPIC );
material->load();
}
}
PhysicsSystem::~PhysicsSystem()
@ -46,17 +104,17 @@ namespace CSVWorld
{
mEngine->toggleDebugRendering();
mEngine->stepSimulation(0.0167); // FIXME: DebugDrawer::step() not accessible
Ogre::Root::getSingleton().renderOneFrame(); // FIXME: temporary workaround for immediate visual feedback
Ogre::Root::getSingleton().renderOneFrame(); // FIXME: temporary workaround for immediate visual feedback
}
/*std::pair<bool, Ogre::Vector3>*/ void PhysicsSystem::castRay(float mouseX, float mouseY,
Ogre::Vector3* normal, std::string* hit, Ogre::Camera *camera)
{
Ogre::Ray ray = camera->getCameraToViewportRay(
mouseX,
mouseY);
Ogre::Ray ray = camera->getCameraToViewportRay(mouseX, mouseY);
Ogre::Vector3 from = ray.getOrigin();
Ogre::Vector3 to = ray.getPoint(200000);
CSMSettings::UserSettings &userSettings = CSMSettings::UserSettings::instance();
float farClipDist = userSettings.setting("Scene/far clip distance", QString("300000")).toFloat();
Ogre::Vector3 to = ray.getPoint(farClipDist);
//Ogre::Vector3 to = ray.getDirection();
btVector3 _from, _to;
@ -66,7 +124,8 @@ namespace CSVWorld
bool raycastingObjectOnly = true;
bool ignoreHeightMap = false;
Ogre::Vector3 norm;
std::pair<std::string, float> result = mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm);
std::pair<std::string, float> result =
mEngine->rayTest(_from, _to, raycastingObjectOnly, ignoreHeightMap, &norm);
if (result.first == "")
//return std::make_pair(false, Ogre::Vector3());
@ -74,13 +133,97 @@ namespace CSVWorld
else
{
std::cout << "hit " << result.first
+ " result " + std::to_string(result.second) << std::endl;
+ " result " + std::to_string(result.second*farClipDist) << 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;
std::cout << "hit pos "+ std::to_string(ray.getPoint(farClipDist*result.second).x)
+ ", " + std::to_string(ray.getPoint(farClipDist*result.second).y)
+ ", " + std::to_string(ray.getPoint(farClipDist*result.second).z) << std::endl;
if(mSceneMgr->hasSceneNode(result.first))
{
// FIXME: for debugging cursor position
// If using orthographic projection the cursor position is very accurate,
// but with the default perspective view the cursor position is not properly
// calculated when using getCameraToViewportRay.
// See http://www.ogre3d.org/forums/viewtopic.php?p=241933
mSceneMgr->destroyManualObject("manual" + result.first);
Ogre::ManualObject* manual = mSceneMgr->createManualObject("manual" + result.first);
manual->begin("BaseWhite", Ogre::RenderOperation::OT_LINE_LIST);
manual-> position(ray.getPoint(farClipDist*result.second).x,
ray.getPoint(farClipDist*result.second).y,
ray.getPoint(farClipDist*result.second).z);
manual-> position(ray.getPoint(farClipDist*result.second).x,
ray.getPoint(farClipDist*result.second).y,
ray.getPoint(farClipDist*result.second).z+2000);
manual-> position(ray.getPoint(farClipDist*result.second).x,
ray.getPoint(farClipDist*result.second).y,
ray.getPoint(farClipDist*result.second).z);
manual-> position(ray.getPoint(farClipDist*result.second).x,
ray.getPoint(farClipDist*result.second).y+2000,
ray.getPoint(farClipDist*result.second).z);
manual-> position(ray.getPoint(farClipDist*result.second).x,
ray.getPoint(farClipDist*result.second).y,
ray.getPoint(farClipDist*result.second).z);
manual-> position(ray.getPoint(farClipDist*result.second).x+2000,
ray.getPoint(farClipDist*result.second).y,
ray.getPoint(farClipDist*result.second).z);
manual->end();
mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(manual);
// end debugging cursor position
Ogre::SceneNode *scene = mSceneMgr->getSceneNode(result.first);
std::map<std::string, std::vector<std::string>>::iterator iter =
mSelectedEntities.find(result.first);
if(iter != mSelectedEntities.end()) // currently selected
{
//scene->showBoundingBox(false);
std::vector<std::string> deletedEntities = mSelectedEntities[result.first];
while(!deletedEntities.empty())
{
scene->detachObject(deletedEntities.back());
mSceneMgr->destroyEntity(deletedEntities.back());
deletedEntities.pop_back();
}
mSelectedEntities.erase(iter);
mSceneMgr->destroyManualObject("manual" + result.first);
}
else
{
//scene->showBoundingBox(true);
std::vector<std::string> clonedEntities;
Ogre::SceneNode::ObjectIterator iter = scene->getAttachedObjectIterator();
iter.begin();
while(iter.hasMoreElements())
{
Ogre::MovableObject * element = iter.getNext();
if(element->getMovableType() != "Entity")
continue;
Ogre::Entity * e = dynamic_cast<Ogre::Entity *>(element);
if(mSceneMgr->hasEntity(e->getName()+"cover"))
{
// FIXME: this shouldn't really happen...
scene->detachObject(e->getName()+"cover");
mSceneMgr->destroyEntity(e->getName()+"cover");
}
Ogre::Entity * clone = e->clone(e->getName()+"cover");
Ogre::MaterialPtr mat =
Ogre::MaterialManager::getSingleton().getByName("TransMaterial");
if(!mat.isNull())
{
clone->setMaterial(mat);
scene->attachObject(clone);
clonedEntities.push_back(e->getName()+"cover");
}
}
mSelectedEntities[result.first] = clonedEntities;
}
// FIXME: temporary workaround for immediate visual feedback
Ogre::Root::getSingleton().renderOneFrame();
}
}
}
}

@ -2,6 +2,7 @@
#define CSV_WORLD_PHYSICSSYSTEM_H
#include <map>
#include <vector>
namespace Ogre
{
@ -25,7 +26,8 @@ namespace CSVWorld
{
std::map<std::string, std::string> handleToMesh;
OEngine::Physic::PhysicEngine* mEngine;
//Ogre::SceneManager *mSceneMgr;
Ogre::SceneManager *mSceneMgr;
std::map<std::string, std::vector<std::string>> mSelectedEntities;
public:

Loading…
Cancel
Save