use a raycast to determine where to place object, if distance is too far

drop it on the ground
actorid
scrawl 13 years ago
parent 7fbee0d488
commit b18ee198b4

@ -244,7 +244,7 @@ void ContainerBase::Update()
if(mDragAndDrop->mIsOnDragAndDrop)
{
if(mDragAndDrop->mDraggedWidget)
mDragAndDrop->mDraggedWidget->setPosition(MyGUI::InputManager::getInstance().getMousePosition() - MyGUI::IntPoint(21, 21));
mDragAndDrop->mDraggedWidget->setPosition(MyGUI::InputManager::getInstance().getMousePosition());
else mDragAndDrop->mIsOnDragAndDrop = false; //If this happens, there is a bug.
}
}

@ -91,6 +91,7 @@ HUD::HUD(int width, int height, int fpsLevel, DragAndDrop* dragAndDrop)
LocalMapBase::init(minimap, this);
mMainWidget->eventMouseButtonClick += MyGUI::newDelegate(this, &HUD::onWorldClicked);
mMainWidget->eventMouseMove += MyGUI::newDelegate(this, &HUD::onWorldMouseOver);
}
void HUD::setFpsLevel(int level)
@ -261,16 +262,19 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
// drop item into the gameworld
MWWorld::Ptr object = *mDragAndDrop->mStore.begin();
float* playerPos;
playerPos = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getRefData().getPosition().pos;
MWWorld::Ptr::CellStore* cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell(); /// \todo this might be a different cell
MWWorld::World* world = MWBase::Environment::get().getWorld();
ESM::Position& pos = object.getRefData().getPosition();
pos.pos[0] = playerPos[0];
pos.pos[1] = playerPos[1];
pos.pos[2] = playerPos[2];
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
MWBase::Environment::get().getWorld()->insertObject(object, cell);
if (world->canPlaceObject(mouseX, mouseY))
world->placeObject(object, mouseX, mouseY);
else
world->dropObjectOnGround(object);
MyGUI::PointerManager::getInstance().setPointer("arrow");
std::string sound = MWWorld::Class::get(object).getDownSoundId(object);
MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0);
@ -284,3 +288,30 @@ void HUD::onWorldClicked(MyGUI::Widget* _sender)
}
}
void HUD::onWorldMouseOver(MyGUI::Widget* _sender, int x, int y)
{
if (mDragAndDrop->mIsOnDragAndDrop)
{
MyGUI::IntSize viewSize = MyGUI::RenderManager::getInstance().getViewSize();
MyGUI::IntPoint cursorPosition = MyGUI::InputManager::getInstance().getMousePosition();
float mouseX = cursorPosition.left / float(viewSize.width);
float mouseY = cursorPosition.top / float(viewSize.height);
MWWorld::World* world = MWBase::Environment::get().getWorld();
// if we can't drop the object at the wanted position, show the "drop on ground" cursor.
bool canDrop = world->canPlaceObject(mouseX, mouseY);
if (!canDrop)
MyGUI::PointerManager::getInstance().setPointer("drop_ground");
else
MyGUI::PointerManager::getInstance().setPointer("arrow");
}
else
{
MyGUI::PointerManager::getInstance().setPointer("arrow");
/// \todo make it possible to pick up objects with the mouse, if inventory or container window is open
}
}

@ -52,5 +52,6 @@ namespace MWGui
DragAndDrop* mDragAndDrop;
void onWorldClicked(MyGUI::Widget* _sender);
void onWorldMouseOver(MyGUI::Widget* _sender, int x, int y);
};
}

@ -576,5 +576,4 @@ void WindowManager::setDragDrop(bool dragDrop)
{
mToolTips->setEnabled(!dragDrop);
MWBase::Environment::get().getInputManager()->setDragDrop(dragDrop);
setMouseVisible(!dragDrop);
}

@ -80,7 +80,7 @@ namespace MWWorld
Ray centerRay = mRender.getCamera()->getCameraToViewportRay(
mRender.getViewport()->getWidth()/2,
mRender.getViewport()->getHeight()/2);
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y);
btVector3 result(centerRay.getPoint(500*extent).x,-centerRay.getPoint(500*extent).z,centerRay.getPoint(500*extent).y); /// \todo make this distance (ray length) configurable
return result;
}
@ -95,6 +95,29 @@ namespace MWWorld
return !(result.first == "");
}
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 PhysicsSystem::doPhysics(float dt, const std::vector<std::pair<std::string, Ogre::Vector3> >& actors)
{
//set the DebugRenderingMode. To disable it,set it to 0

@ -53,6 +53,9 @@ namespace MWWorld
// cast ray, return true if it hit something
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to);
std::pair<bool, Ogre::Vector3> castRay(float mouseX, float mouseY);
///< cast ray from the mouse, return true if it hit something and the first result (in OGRE coordinates)
void insertObjectPhysics(const MWWorld::Ptr& ptr, std::string model);
void insertActorPhysics(const MWWorld::Ptr&, std::string model);

@ -965,9 +965,57 @@ namespace MWWorld
mRendering->toggleWater();
}
void World::insertObject(MWWorld::Ptr ptr, Ptr::CellStore* cell)
bool World::placeObject(MWWorld::Ptr object, float cursorX, float cursorY)
{
mWorldScene->insertObject(ptr, cell);
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
if (!result.first)
return false;
MWWorld::Ptr::CellStore* cell;
if (isCellExterior())
{
int cellX, cellY;
positionToIndex(result.second[0], -result.second[2], cellX, cellY);
cell = mCells.getExterior(cellX, cellY);
}
else
cell = getPlayer().getPlayer().getCell();
ESM::Position& pos = object.getRefData().getPosition();
pos.pos[0] = result.second[0];
pos.pos[1] = -result.second[2];
pos.pos[2] = result.second[1];
mWorldScene->insertObject(object, cell);
/// \todo retrieve the bounds of the object and translate it accordingly
return true;
}
bool World::canPlaceObject(float cursorX, float cursorY)
{
std::pair<bool, Ogre::Vector3> result = mPhysics->castRay(cursorX, cursorY);
/// \todo also check if the wanted position is on a flat surface, and not e.g. against a vertical wall!
if (!result.first)
return false;
return true;
}
void World::dropObjectOnGround(MWWorld::Ptr object)
{
MWWorld::Ptr::CellStore* cell = getPlayer().getPlayer().getCell();
float* playerPos = getPlayer().getPlayer().getRefData().getPosition().pos;
ESM::Position& pos = object.getRefData().getPosition();
pos.pos[0] = playerPos[0];
pos.pos[1] = playerPos[1];
pos.pos[2] = playerPos[2];
mWorldScene->insertObject(object, cell);
}
}

@ -263,9 +263,17 @@ namespace MWWorld
void update (float duration);
void insertObject (MWWorld::Ptr ptr, Ptr::CellStore* cell);
///< insert object in a given cell
/// \note this method is only meant for dropping items into the gameworld from a container
bool placeObject(MWWorld::Ptr object, float cursorX, float cursorY);
///< place an object into the gameworld at the specified cursor position
/// @param object
/// @param cursor X (relative 0-1)
/// @param cursor Y (relative 0-1)
/// @return true if the object was placed, or false if it was rejected because the position is too far away
void dropObjectOnGround(MWWorld::Ptr object);
bool canPlaceObject(float cursorX, float cursorY);
///< @return true if it is possible to place on object at specified cursor location
};
}

@ -26,4 +26,9 @@
<Property key="Size" value="32 32"/>
<Property key="Resource" value="DResize2PointerImage"/>
</Resource>
<Resource type="ResourceImageSetPointer" name="drop_ground">
<Property key="Point" value="0 24"/>
<Property key="Size" value="32 32"/>
<Property key="Resource" value="DropGroundPointerImage"/>
</Resource>
</MyGUI>

@ -8,7 +8,6 @@
<Layer name="MainMenu" overlapped="false" peek="false"/>
<Layer name="Console" overlapped="false" peek="true"/>
<Layer name="Popup" overlapped="true" peek="true"/>
<Layer name="DragAndDrop" overlapped="false" peek="true"/>
<Layer name="Pointer" overlapped="false" peek="false"/>
<Layer name="Statistic" overlapped="false" peek="false"/>
<Layer name="DragAndDrop" overlapped="false" peek="true"/>
</MyGUI>

@ -36,6 +36,13 @@
</Index>
</Group>
</Resource>
<Resource type="ResourceImageSet" name="DropGroundPointerImage">
<Group name="Pointer" texture="textures\cursor_drop_ground.dds" size="32 32">
<Index name="Pointer" >
<Frame point="0 0"/>
</Index>
</Group>
</Resource>
<Resource type="ResourceImageSet" name="MenuBook_Close">
<Group name="States" texture="mwgui1" size="96 24">

Loading…
Cancel
Save