mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-02-21 09:39:41 +00:00
Restore various raycasting
This commit is contained in:
parent
8e0a988289
commit
ccd95419e5
9 changed files with 157 additions and 111 deletions
|
@ -838,14 +838,12 @@ void CharacterController::updatePtr(const MWWorld::Ptr &ptr)
|
||||||
void CharacterController::updateIdleStormState()
|
void CharacterController::updateIdleStormState()
|
||||||
{
|
{
|
||||||
bool inStormDirection = false;
|
bool inStormDirection = false;
|
||||||
/*
|
|
||||||
if (MWBase::Environment::get().getWorld()->isInStorm())
|
if (MWBase::Environment::get().getWorld()->isInStorm())
|
||||||
{
|
{
|
||||||
Ogre::Vector3 stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
|
osg::Vec3f stormDirection = MWBase::Environment::get().getWorld()->getStormDirection();
|
||||||
Ogre::Vector3 characterDirection = mPtr.getRefData().getBaseNode()->getOrientation().yAxis();
|
osg::Vec3f characterDirection = mPtr.getRefData().getBaseNode()->getAttitude() * osg::Vec3f(0,1,0);
|
||||||
inStormDirection = stormDirection.angleBetween(characterDirection) > Ogre::Degree(120);
|
inStormDirection = std::acos(stormDirection * characterDirection) > osg::DegreesToRadians(120.f);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
if (inStormDirection && mUpperBodyState == UpperCharState_Nothing && mAnimation->hasAnimation("idlestorm"))
|
if (inStormDirection && mUpperBodyState == UpperCharState_Nothing && mAnimation->hasAnimation("idlestorm"))
|
||||||
{
|
{
|
||||||
float complete = 0;
|
float complete = 0;
|
||||||
|
|
|
@ -728,35 +728,74 @@ namespace MWPhysics
|
||||||
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
return std::make_pair(MWWorld::Ptr(), osg::Vec3f());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback
|
||||||
bool PhysicsSystem::castRay(const Ogre::Vector3& from, const Ogre::Vector3& to, bool ignoreHeightMap)
|
|
||||||
{
|
{
|
||||||
return false;
|
public:
|
||||||
/*
|
ClosestNotMeRayResultCallback(const btCollisionObject* me, const btVector3& from, const btVector3& to)
|
||||||
btVector3 _from, _to;
|
: btCollisionWorld::ClosestRayResultCallback(from, to)
|
||||||
_from = btVector3(from.x, from.y, from.z);
|
, mMe(me)
|
||||||
_to = btVector3(to.x, to.y, to.z);
|
{
|
||||||
|
}
|
||||||
|
|
||||||
std::pair<std::string, float> result = mEngine->rayTest(_from, _to,ignoreHeightMap);
|
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace)
|
||||||
return !(result.first == "");
|
{
|
||||||
*/
|
if (rayResult.m_collisionObject == mMe)
|
||||||
}
|
return 1.f;
|
||||||
|
return btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
const btCollisionObject* mMe;
|
||||||
|
};
|
||||||
|
|
||||||
std::pair<bool, osg::Vec3f> PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to)
|
PhysicsSystem::RayResult PhysicsSystem::castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore, int mask)
|
||||||
{
|
{
|
||||||
btVector3 btFrom = toBullet(from);
|
btVector3 btFrom = toBullet(from);
|
||||||
btVector3 btTo = toBullet(to);
|
btVector3 btTo = toBullet(to);
|
||||||
|
|
||||||
btCollisionWorld::ClosestRayResultCallback resultCallback(btFrom, btTo);
|
const btCollisionObject* me = NULL;
|
||||||
|
if (!ignore.isEmpty())
|
||||||
|
{
|
||||||
|
Actor* actor = getActor(ignore);
|
||||||
|
if (actor)
|
||||||
|
me = actor->getCollisionObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClosestNotMeRayResultCallback resultCallback(me, btFrom, btTo);
|
||||||
resultCallback.m_collisionFilterGroup = 0xff;
|
resultCallback.m_collisionFilterGroup = 0xff;
|
||||||
resultCallback.m_collisionFilterMask = CollisionType_World | CollisionType_HeightMap;
|
resultCallback.m_collisionFilterMask = mask;
|
||||||
|
|
||||||
mCollisionWorld->rayTest(btFrom, btTo, resultCallback);
|
mCollisionWorld->rayTest(btFrom, btTo, resultCallback);
|
||||||
|
|
||||||
|
RayResult result;
|
||||||
|
result.mHit = resultCallback.hasHit();
|
||||||
if (resultCallback.hasHit())
|
if (resultCallback.hasHit())
|
||||||
{
|
{
|
||||||
return std::make_pair(true, toOsg(resultCallback.m_hitPointWorld));
|
result.mHitPos = toOsg(resultCallback.m_hitPointWorld);
|
||||||
|
result.mHitNormal = toOsg(resultCallback.m_hitNormalWorld);
|
||||||
|
if (PtrHolder* ptrHolder = static_cast<PtrHolder*>(resultCallback.m_collisionObject->getUserPointer()))
|
||||||
|
result.mHitObject = ptrHolder->getPtr();
|
||||||
}
|
}
|
||||||
return std::make_pair(false, osg::Vec3f());
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PhysicsSystem::getLineOfSight(const MWWorld::Ptr &actor1, const MWWorld::Ptr &actor2)
|
||||||
|
{
|
||||||
|
Actor* physactor1 = getActor(actor1);
|
||||||
|
Actor* physactor2 = getActor(actor2);
|
||||||
|
|
||||||
|
if (!physactor1 || !physactor2)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
osg::Vec3f halfExt1 = physactor1->getHalfExtents();
|
||||||
|
osg::Vec3f pos1 (actor1.getRefData().getPosition().asVec3());
|
||||||
|
pos1.z() += halfExt1.z()*2*0.9f; // eye level
|
||||||
|
osg::Vec3f halfExt2 = physactor2->getHalfExtents();
|
||||||
|
osg::Vec3f pos2 (actor2.getRefData().getPosition().asVec3());
|
||||||
|
pos2.z() += halfExt2.z()*2*0.9f;
|
||||||
|
|
||||||
|
RayResult result = castRay(pos1, pos2, MWWorld::Ptr(), CollisionType_World|CollisionType_HeightMap);
|
||||||
|
|
||||||
|
return !result.mHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
class ContactTestResultCallback : public btCollisionWorld::ContactResultCallback
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
#include <osg/Quat>
|
#include <osg/Quat>
|
||||||
|
|
||||||
|
#include "collisiontype.hpp"
|
||||||
|
|
||||||
namespace osg
|
namespace osg
|
||||||
{
|
{
|
||||||
class Group;
|
class Group;
|
||||||
|
@ -87,11 +89,20 @@ namespace MWPhysics
|
||||||
const osg::Quat &orientation,
|
const osg::Quat &orientation,
|
||||||
float queryDistance);
|
float queryDistance);
|
||||||
|
|
||||||
// cast ray, return true if it hit something.
|
struct RayResult
|
||||||
bool castRay(const Ogre::Vector3& from, const Ogre::Vector3& to,bool ignoreHeightMap = false);
|
{
|
||||||
|
bool mHit;
|
||||||
|
osg::Vec3f mHitPos;
|
||||||
|
osg::Vec3f mHitNormal;
|
||||||
|
MWWorld::Ptr mHitObject;
|
||||||
|
};
|
||||||
|
|
||||||
/// @return <bool hit, world hit position>
|
/// @param me Optional, a Ptr to ignore in the list of results
|
||||||
std::pair<bool, osg::Vec3f> castRay(const osg::Vec3f &from, const osg::Vec3f &to);
|
RayResult castRay(const osg::Vec3f &from, const osg::Vec3f &to, MWWorld::Ptr ignore = MWWorld::Ptr(), int mask =
|
||||||
|
CollisionType_World|CollisionType_HeightMap|CollisionType_Actor);
|
||||||
|
|
||||||
|
/// Return true if actor1 can see actor2.
|
||||||
|
bool getLineOfSight(const MWWorld::Ptr& actor1, const MWWorld::Ptr& actor2);
|
||||||
|
|
||||||
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
|
/// Queues velocity movement for a Ptr. If a Ptr is already queued, its velocity will
|
||||||
/// be overwritten. Valid until the next call to applyQueuedMovement.
|
/// be overwritten. Valid until the next call to applyQueuedMovement.
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#include <components/vfs/manager.hpp>
|
#include <components/vfs/manager.hpp>
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
|
||||||
|
|
||||||
#include <components/sceneutil/statesetupdater.hpp>
|
#include <components/sceneutil/statesetupdater.hpp>
|
||||||
#include <components/sceneutil/visitor.hpp>
|
#include <components/sceneutil/visitor.hpp>
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
|
|
||||||
#include <osg/PositionAttitudeTransform>
|
#include <osg/PositionAttitudeTransform>
|
||||||
|
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
|
||||||
|
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
#include <components/resource/scenemanager.hpp>
|
#include <components/resource/scenemanager.hpp>
|
||||||
|
|
||||||
|
|
|
@ -298,6 +298,21 @@ namespace MWRender
|
||||||
mObjects->removeObject(ptr);
|
mObjects->removeObject(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderingManager::getCameraToViewportRay(float nX, float nY, osg::Vec3f &origin, osg::Vec3f &dest)
|
||||||
|
{
|
||||||
|
osg::Matrix viewProj = mViewer->getCamera()->getViewMatrix() * mViewer->getCamera()->getProjectionMatrix();
|
||||||
|
osg::Matrix invViewProj = viewProj.inverse(viewProj);
|
||||||
|
|
||||||
|
nX = nX * 2 - 1;
|
||||||
|
nY = nY * -2 + 1;
|
||||||
|
|
||||||
|
osg::Vec3f start (nX, nY, -1.f);
|
||||||
|
osg::Vec3f end (nX, nY, 1.f);
|
||||||
|
|
||||||
|
origin = invViewProj.preMult(start);
|
||||||
|
dest = invViewProj.preMult(end);
|
||||||
|
}
|
||||||
|
|
||||||
osg::Vec4f RenderingManager::getScreenBounds(const MWWorld::Ptr& ptr)
|
osg::Vec4f RenderingManager::getScreenBounds(const MWWorld::Ptr& ptr)
|
||||||
{
|
{
|
||||||
if (!ptr.getRefData().getBaseNode())
|
if (!ptr.getRefData().getBaseNode())
|
||||||
|
|
|
@ -80,6 +80,9 @@ namespace MWRender
|
||||||
/// Get the bounding box of the given object in screen coordinates as (minX, minY, maxX, maxY), with (0,0) being the top left corner.
|
/// Get the bounding box of the given object in screen coordinates as (minX, minY, maxX, maxY), with (0,0) being the top left corner.
|
||||||
osg::Vec4f getScreenBounds(const MWWorld::Ptr& ptr);
|
osg::Vec4f getScreenBounds(const MWWorld::Ptr& ptr);
|
||||||
|
|
||||||
|
/// Get a camera to viewport ray for normalized screen coordinates nX and nY, with the top left corner being at (0,0)
|
||||||
|
void getCameraToViewportRay(float nX, float nY, osg::Vec3f& origin, osg::Vec3f& dest);
|
||||||
|
|
||||||
void setSkyEnabled(bool enabled);
|
void setSkyEnabled(bool enabled);
|
||||||
|
|
||||||
bool toggleRenderMode(RenderMode mode);
|
bool toggleRenderMode(RenderMode mode);
|
||||||
|
|
|
@ -419,6 +419,7 @@ void WeatherManager::update(float duration, bool paused)
|
||||||
|
|
||||||
mStormDirection = (playerPos - redMountainPos);
|
mStormDirection = (playerPos - redMountainPos);
|
||||||
mStormDirection.z() = 0;
|
mStormDirection.z() = 0;
|
||||||
|
mStormDirection.normalize();
|
||||||
mRendering->getSkyManager()->setStormDirection(mStormDirection);
|
mRendering->getSkyManager()->setStormDirection(mStormDirection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
#else
|
#else
|
||||||
#include <tr1/unordered_map>
|
#include <tr1/unordered_map>
|
||||||
#endif
|
#endif
|
||||||
#include <OgreSceneNode.h>
|
|
||||||
|
|
||||||
#include <osg/Group>
|
#include <osg/Group>
|
||||||
#include <osg/ComputeBoundsVisitor>
|
#include <osg/ComputeBoundsVisitor>
|
||||||
|
@ -21,8 +20,6 @@
|
||||||
#include <components/misc/resourcehelpers.hpp>
|
#include <components/misc/resourcehelpers.hpp>
|
||||||
#include <components/resource/resourcesystem.hpp>
|
#include <components/resource/resourcesystem.hpp>
|
||||||
|
|
||||||
#include <boost/math/special_functions/sign.hpp>
|
|
||||||
|
|
||||||
#include "../mwbase/environment.hpp"
|
#include "../mwbase/environment.hpp"
|
||||||
#include "../mwbase/soundmanager.hpp"
|
#include "../mwbase/soundmanager.hpp"
|
||||||
#include "../mwbase/mechanicsmanager.hpp"
|
#include "../mwbase/mechanicsmanager.hpp"
|
||||||
|
@ -1411,9 +1408,10 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
bool World::castRay (float x1, float y1, float z1, float x2, float y2, float z2)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 a(x1,y1,z1);
|
osg::Vec3f a(x1,y1,z1);
|
||||||
Ogre::Vector3 b(x2,y2,z2);
|
osg::Vec3f b(x2,y2,z2);
|
||||||
return 0;//mPhysics->castRay(a,b,false,true);
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(a, b, MWWorld::Ptr(), MWPhysics::CollisionType_World);
|
||||||
|
return result.mHit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::processDoors(float duration)
|
void World::processDoors(float duration)
|
||||||
|
@ -1793,17 +1791,26 @@ namespace MWWorld
|
||||||
|
|
||||||
MWWorld::Ptr World::placeObject (const MWWorld::Ptr& object, float cursorX, float cursorY, int amount)
|
MWWorld::Ptr World::placeObject (const MWWorld::Ptr& object, float cursorX, float cursorY, int amount)
|
||||||
{
|
{
|
||||||
std::pair<bool, Ogre::Vector3> result;// = mPhysics->castRay(cursorX, cursorY);
|
osg::Vec3f origin, dest;
|
||||||
|
mRendering->getCameraToViewportRay(cursorX, cursorY, origin, dest);
|
||||||
|
|
||||||
if (!result.first)
|
const float maxDist = 200.f;
|
||||||
return MWWorld::Ptr();
|
osg::Vec3f dir = (dest - origin);
|
||||||
|
dir.normalize();
|
||||||
|
dest = origin + dir * maxDist;
|
||||||
|
|
||||||
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(origin, dest, MWWorld::Ptr(),
|
||||||
|
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
||||||
|
|
||||||
CellStore* cell = getPlayerPtr().getCell();
|
CellStore* cell = getPlayerPtr().getCell();
|
||||||
|
|
||||||
ESM::Position pos = getPlayerPtr().getRefData().getPosition();
|
ESM::Position pos = getPlayerPtr().getRefData().getPosition();
|
||||||
pos.pos[0] = result.second[0];
|
if (result.mHit)
|
||||||
pos.pos[1] = result.second[1];
|
{
|
||||||
pos.pos[2] = result.second[2];
|
pos.pos[0] = result.mHitPos.x();
|
||||||
|
pos.pos[1] = result.mHitPos.y();
|
||||||
|
pos.pos[2] = result.mHitPos.z();
|
||||||
|
}
|
||||||
// We want only the Z part of the player's rotation
|
// We want only the Z part of the player's rotation
|
||||||
pos.rot[0] = 0;
|
pos.rot[0] = 0;
|
||||||
pos.rot[1] = 0;
|
pos.rot[1] = 0;
|
||||||
|
@ -1822,21 +1829,23 @@ namespace MWWorld
|
||||||
|
|
||||||
bool World::canPlaceObject(float cursorX, float cursorY)
|
bool World::canPlaceObject(float cursorX, float cursorY)
|
||||||
{
|
{
|
||||||
Ogre::Vector3 normal(0,0,0);
|
osg::Vec3f origin, dest;
|
||||||
std::string handle;
|
mRendering->getCameraToViewportRay(cursorX, cursorY, origin, dest);
|
||||||
std::pair<bool, Ogre::Vector3> result;// = mPhysics->castRay(cursorX, cursorY, &normal, &handle);
|
|
||||||
|
|
||||||
if (result.first)
|
const float maxDist = 200.f;
|
||||||
|
osg::Vec3f dir = (dest - origin);
|
||||||
|
dir.normalize();
|
||||||
|
dest = origin + dir * maxDist;
|
||||||
|
|
||||||
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(origin, dest, MWWorld::Ptr(),
|
||||||
|
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
||||||
|
|
||||||
|
if (result.mHit)
|
||||||
{
|
{
|
||||||
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
// check if the wanted position is on a flat surface, and not e.g. against a vertical wall
|
||||||
if (normal.angleBetween(Ogre::Vector3(0.f,0.f,1.f)).valueDegrees() >= 30)
|
if (std::acos(result.mHitNormal * osg::Vec3f(0,0,1)) >= osg::DegreesToRadians(30.f))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
|
||||||
MWWorld::Ptr hitObject = searchPtrViaHandle(handle);
|
|
||||||
if (!hitObject.isEmpty() && hitObject.getClass().isActor())
|
|
||||||
return false;
|
|
||||||
*/
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1917,9 +1926,10 @@ namespace MWWorld
|
||||||
|
|
||||||
float len = 100.0;
|
float len = 100.0;
|
||||||
|
|
||||||
std::pair<bool, osg::Vec3f> hit = mPhysics->castRay(orig, dir*len);
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(orig, orig+dir*len, MWWorld::Ptr(),
|
||||||
if (hit.first)
|
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
||||||
pos.pos[2] = hit.second.z();
|
if (result.mHit)
|
||||||
|
pos.pos[2] = result.mHitPos.z();
|
||||||
|
|
||||||
// copy the object and set its count
|
// copy the object and set its count
|
||||||
int origCount = object.getRefData().getCount();
|
int origCount = object.getRefData().getCount();
|
||||||
|
@ -2346,50 +2356,30 @@ namespace MWWorld
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool World::getLOS(const MWWorld::Ptr& actor,const MWWorld::Ptr& targetActor)
|
bool World::getLOS(const MWWorld::Ptr& actor, const MWWorld::Ptr& targetActor)
|
||||||
{
|
{
|
||||||
if (!targetActor.getRefData().isEnabled() || !actor.getRefData().isEnabled())
|
if (!targetActor.getRefData().isEnabled() || !actor.getRefData().isEnabled())
|
||||||
return false; // cannot get LOS unless both NPC's are enabled
|
return false; // cannot get LOS unless both NPC's are enabled
|
||||||
if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
|
if (!targetActor.getRefData().getBaseNode() || !targetActor.getRefData().getBaseNode())
|
||||||
return false; // not in active cell
|
return false; // not in active cell
|
||||||
|
|
||||||
// TODO: move to PhysicsSystem
|
return mPhysics->getLineOfSight(actor, targetActor);
|
||||||
/*
|
|
||||||
OEngine::Physic::PhysicActor* actor1 = mPhysEngine->getCharacter(actor.getRefData().getHandle());
|
|
||||||
OEngine::Physic::PhysicActor* actor2 = mPhysEngine->getCharacter(targetActor.getRefData().getHandle());
|
|
||||||
|
|
||||||
if (!actor1 || !actor2)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Ogre::Vector3 halfExt1 = actor1->getHalfExtents();
|
|
||||||
const float* pos1 = actor.getRefData().getPosition().pos;
|
|
||||||
Ogre::Vector3 halfExt2 = actor2->getHalfExtents();
|
|
||||||
const float* pos2 = targetActor.getRefData().getPosition().pos;
|
|
||||||
|
|
||||||
btVector3 from(pos1[0],pos1[1],pos1[2]+halfExt1.z*2*0.9f); // eye level
|
|
||||||
btVector3 to(pos2[0],pos2[1],pos2[2]+halfExt2.z*2*0.9f);
|
|
||||||
|
|
||||||
std::pair<std::string, float> result = mPhysEngine->rayTest(from, to,false);
|
|
||||||
if(result.first == "") return true;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float World::getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist)
|
float World::getDistToNearestRayHit(const Ogre::Vector3& from, const Ogre::Vector3& dir, float maxDist)
|
||||||
{
|
{
|
||||||
return 0;
|
osg::Vec3f from_ (from.x, from.y, from.z);
|
||||||
/*
|
osg::Vec3f to_ (dir.x, dir.y, dir.z);
|
||||||
btVector3 btFrom(from.x, from.y, from.z);
|
to_.normalize();
|
||||||
btVector3 btTo = btVector3(dir.x, dir.y, dir.z);
|
to_ = from_ + (to_ * maxDist);
|
||||||
btTo.normalize();
|
|
||||||
btTo = btFrom + btTo * maxDist;
|
|
||||||
|
|
||||||
std::pair<std::string, float> result = mPhysEngine->rayTest(btFrom, btTo, false);
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(from_, to_, MWWorld::Ptr(),
|
||||||
|
MWPhysics::CollisionType_World|MWPhysics::CollisionType_HeightMap);
|
||||||
|
|
||||||
if(result.second == -1) return maxDist;
|
if (!result.mHit)
|
||||||
else return result.second*(btTo-btFrom).length();
|
return maxDist;
|
||||||
*/
|
else
|
||||||
|
return (result.mHitPos - from_).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable)
|
void World::enableActorCollision(const MWWorld::Ptr& actor, bool enable)
|
||||||
|
@ -2697,37 +2687,30 @@ namespace MWWorld
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// For NPCs use facing direction from Head node
|
// For NPCs use facing direction from Head node
|
||||||
Ogre::Vector3 origin(actor.getRefData().getPosition().pos);
|
osg::Vec3f origin(actor.getRefData().getPosition().asVec3());
|
||||||
#if 0
|
|
||||||
MWRender::Animation *anim = mRendering->getAnimation(actor);
|
MWRender::Animation* anim = mRendering->getAnimation(actor);
|
||||||
if(anim != NULL)
|
if (anim != NULL)
|
||||||
{
|
{
|
||||||
Ogre::Node *node = anim->getNode("Head");
|
const osg::Node* node = anim->getNode("Head");
|
||||||
if (node == NULL)
|
if (node == NULL)
|
||||||
node = anim->getNode("Bip01 Head");
|
node = anim->getNode("Bip01 Head");
|
||||||
if(node != NULL)
|
if (node != NULL)
|
||||||
origin += node->_getDerivedPosition();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
|
|
||||||
Ogre::Quaternion orient;
|
|
||||||
orient = Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) *
|
|
||||||
Ogre::Quaternion(Ogre::Radian(actor.getRefData().getPosition().rot[0]), Ogre::Vector3::NEGATIVE_UNIT_X);
|
|
||||||
Ogre::Vector3 direction = orient.yAxis();
|
|
||||||
Ogre::Vector3 dest = origin + direction * distance;
|
|
||||||
|
|
||||||
std::vector<std::pair<float, std::string> > collisions = mPhysEngine->rayTest2(btVector3(origin.x, origin.y, origin.z), btVector3(dest.x, dest.y, dest.z));
|
|
||||||
for (std::vector<std::pair<float, std::string> >::iterator cIt = collisions.begin(); cIt != collisions.end(); ++cIt)
|
|
||||||
{
|
|
||||||
MWWorld::Ptr collided = getPtrViaHandle(cIt->second);
|
|
||||||
if (collided != actor)
|
|
||||||
{
|
{
|
||||||
target = collided;
|
osg::MatrixList mats = node->getWorldMatrices();
|
||||||
break;
|
if (mats.size())
|
||||||
|
origin = mats[0].getTrans();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
osg::Quat orient = osg::Quat(actor.getRefData().getPosition().rot[0], osg::Vec3f(-1,0,0))
|
||||||
|
* osg::Quat(actor.getRefData().getPosition().rot[2], osg::Vec3f(0,0,-1));
|
||||||
|
|
||||||
|
osg::Vec3f direction = orient * osg::Vec3f(0,1,0);
|
||||||
|
osg::Vec3f dest = origin + direction * distance;
|
||||||
|
|
||||||
|
MWPhysics::PhysicsSystem::RayResult result = mPhysics->castRay(origin, dest, actor);
|
||||||
|
target = result.mHitObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
std::string selectedSpell = stats.getSpells().getSelectedSpell();
|
||||||
|
|
Loading…
Reference in a new issue