mirror of
https://github.com/OpenMW/openmw.git
synced 2025-01-29 08:15:35 +00:00
lua - fix bounding box in active grid
This commit is contained in:
parent
5f6ca2a6d1
commit
06676fd623
3 changed files with 51 additions and 7 deletions
|
@ -4,8 +4,6 @@
|
||||||
#include <components/esm3/loadnpc.hpp>
|
#include <components/esm3/loadnpc.hpp>
|
||||||
#include <components/lua/luastate.hpp>
|
#include <components/lua/luastate.hpp>
|
||||||
#include <components/lua/shapes/box.hpp>
|
#include <components/lua/shapes/box.hpp>
|
||||||
#include <components/sceneutil/cullsafeboundsvisitor.hpp>
|
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
|
||||||
|
|
||||||
#include "../mwworld/cellstore.hpp"
|
#include "../mwworld/cellstore.hpp"
|
||||||
#include "../mwworld/class.hpp"
|
#include "../mwworld/class.hpp"
|
||||||
|
@ -13,6 +11,7 @@
|
||||||
#include "../mwworld/player.hpp"
|
#include "../mwworld/player.hpp"
|
||||||
#include "../mwworld/scene.hpp"
|
#include "../mwworld/scene.hpp"
|
||||||
|
|
||||||
|
#include "../mwrender/renderingmanager.hpp"
|
||||||
#include "../mwrender/vismask.hpp"
|
#include "../mwrender/vismask.hpp"
|
||||||
|
|
||||||
#include "../mwmechanics/creaturestats.hpp"
|
#include "../mwmechanics/creaturestats.hpp"
|
||||||
|
@ -157,11 +156,9 @@ namespace MWLua
|
||||||
objectT["rotation"] = sol::readonly_property(
|
objectT["rotation"] = sol::readonly_property(
|
||||||
[](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asRotationVec3(); });
|
[](const ObjectT& o) -> osg::Vec3f { return o.ptr().getRefData().getPosition().asRotationVec3(); });
|
||||||
objectT["getBoundingBox"] = [](const ObjectT& o) {
|
objectT["getBoundingBox"] = [](const ObjectT& o) {
|
||||||
const MWWorld::Ptr& ptr = o.ptr();
|
MWRender::RenderingManager* renderingManager
|
||||||
SceneUtil::CullSafeBoundsVisitor computeBounds;
|
= MWBase::Environment::get().getWorld()->getRenderingManager();
|
||||||
computeBounds.setTraversalMask(~(MWRender::Mask_ParticleSystem | MWRender::Mask_Effect));
|
osg::BoundingBox bb = renderingManager->getCullSafeBoundingBox(o.ptr());
|
||||||
ptr.getRefData().getBaseNode()->accept(computeBounds);
|
|
||||||
osg::BoundingBox bb = computeBounds.mBoundingBox;
|
|
||||||
return LuaUtil::Box{ bb.center(), bb._max - bb.center() };
|
return LuaUtil::Box{ bb.center(), bb._max - bb.center() };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
|
|
||||||
|
#include <components/sceneutil/cullsafeboundsvisitor.hpp>
|
||||||
#include <components/sceneutil/depth.hpp>
|
#include <components/sceneutil/depth.hpp>
|
||||||
#include <components/sceneutil/lightmanager.hpp>
|
#include <components/sceneutil/lightmanager.hpp>
|
||||||
#include <components/sceneutil/positionattitudetransform.hpp>
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
||||||
|
@ -1495,6 +1496,49 @@ namespace MWRender
|
||||||
return halfExtents;
|
return halfExtents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
osg::BoundingBox RenderingManager::getCullSafeBoundingBox(const MWWorld::Ptr& ptr) const
|
||||||
|
{
|
||||||
|
const std::string model = ptr.getClass().getModel(ptr);
|
||||||
|
if (model.empty())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
osg::ref_ptr<SceneUtil::PositionAttitudeTransform> rootNode = new SceneUtil::PositionAttitudeTransform;
|
||||||
|
// Hack even used by osg internally, osg's NodeVisitor won't accept const qualified nodes
|
||||||
|
rootNode->addChild(const_cast<osg::Node*>(mResourceSystem->getSceneManager()->getTemplate(model).get()));
|
||||||
|
|
||||||
|
const SceneUtil::PositionAttitudeTransform* baseNode = ptr.getRefData().getBaseNode();
|
||||||
|
if (baseNode)
|
||||||
|
{
|
||||||
|
rootNode->setPosition(baseNode->getPosition());
|
||||||
|
rootNode->setAttitude(baseNode->getAttitude());
|
||||||
|
rootNode->setScale(baseNode->getScale());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rootNode->setPosition(ptr.getRefData().getPosition().asVec3());
|
||||||
|
osg::Vec3f rot = ptr.getRefData().getPosition().asRotationVec3();
|
||||||
|
rootNode->setAttitude(osg::Quat(rot[2], osg::Vec3f(0, 0, -1)) * osg::Quat(rot[1], osg::Vec3f(0, -1, 0))
|
||||||
|
* osg::Quat(rot[0], osg::Vec3f(-1, 0, 0)));
|
||||||
|
const float refScale = ptr.getCellRef().getScale();
|
||||||
|
rootNode->setScale({ refScale, refScale, refScale });
|
||||||
|
}
|
||||||
|
|
||||||
|
SceneUtil::CullSafeBoundsVisitor computeBounds;
|
||||||
|
computeBounds.setTraversalMask(~(MWRender::Mask_ParticleSystem | MWRender::Mask_Effect));
|
||||||
|
rootNode->accept(computeBounds);
|
||||||
|
|
||||||
|
const osg::Vec3f& scale = rootNode->getScale();
|
||||||
|
|
||||||
|
computeBounds.mBoundingBox.xMin() *= scale.x();
|
||||||
|
computeBounds.mBoundingBox.xMax() *= scale.x();
|
||||||
|
computeBounds.mBoundingBox.yMin() *= scale.y();
|
||||||
|
computeBounds.mBoundingBox.yMax() *= scale.y();
|
||||||
|
computeBounds.mBoundingBox.zMin() *= scale.z();
|
||||||
|
computeBounds.mBoundingBox.zMax() *= scale.z();
|
||||||
|
|
||||||
|
return computeBounds.mBoundingBox;
|
||||||
|
}
|
||||||
|
|
||||||
void RenderingManager::resetFieldOfView()
|
void RenderingManager::resetFieldOfView()
|
||||||
{
|
{
|
||||||
if (mFieldOfViewOverridden == true)
|
if (mFieldOfViewOverridden == true)
|
||||||
|
|
|
@ -244,6 +244,9 @@ namespace MWRender
|
||||||
|
|
||||||
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const;
|
osg::Vec3f getHalfExtents(const MWWorld::ConstPtr& object) const;
|
||||||
|
|
||||||
|
// Return local bounding box. Safe to be called in parallel with cull thread.
|
||||||
|
osg::BoundingBox getCullSafeBoundingBox(const MWWorld::Ptr& ptr) const;
|
||||||
|
|
||||||
void exportSceneGraph(
|
void exportSceneGraph(
|
||||||
const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format);
|
const MWWorld::Ptr& ptr, const std::filesystem::path& filename, const std::string& format);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue