mirror of https://github.com/OpenMW/openmw.git
Expose game object's bounding box in lua api
parent
54a79cfc39
commit
a7b7f99d72
@ -0,0 +1,45 @@
|
||||
#include "box.hpp"
|
||||
|
||||
namespace LuaUtil
|
||||
{
|
||||
Box::Box(const osg::Vec3f& center, const osg::Vec3f& halfSize, const osg::Quat& rotation)
|
||||
: mCenter(center)
|
||||
, mHalfSize(halfSize)
|
||||
, mRotation(rotation)
|
||||
{
|
||||
}
|
||||
|
||||
Box::Box(const osg::Matrix& transform)
|
||||
{
|
||||
osg::Quat _;
|
||||
transform.decompose(mCenter, mRotation, mHalfSize, _);
|
||||
}
|
||||
|
||||
std::array<osg::Vec3f, 8> Box::vertices() const
|
||||
{
|
||||
return {
|
||||
mCenter + mRotation * osg::Vec3f(-mHalfSize.x(), -mHalfSize.y(), -mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(mHalfSize.x(), -mHalfSize.y(), -mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(mHalfSize.x(), mHalfSize.y(), -mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(-mHalfSize.x(), mHalfSize.y(), -mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(-mHalfSize.x(), -mHalfSize.y(), mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(mHalfSize.x(), -mHalfSize.y(), mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(mHalfSize.x(), mHalfSize.y(), mHalfSize.z()),
|
||||
mCenter + mRotation * osg::Vec3f(-mHalfSize.x(), mHalfSize.y(), mHalfSize.z()),
|
||||
};
|
||||
}
|
||||
|
||||
osg::Matrix Box::asTransform() const
|
||||
{
|
||||
osg::Matrix transform;
|
||||
transform.preMultTranslate(mCenter);
|
||||
transform.preMultRotate(mRotation);
|
||||
transform.preMultScale(mHalfSize);
|
||||
return transform;
|
||||
}
|
||||
|
||||
bool Box::operator==(const Box& other) const
|
||||
{
|
||||
return mCenter == other.mCenter && mHalfSize == other.mHalfSize && mRotation == other.mRotation;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
#ifndef COMPONENTS_LUA_SHAPES_BOX_H
|
||||
#define COMPONENTS_LUA_SHAPES_BOX_H
|
||||
|
||||
#include <array>
|
||||
|
||||
#include <osg/Matrix>
|
||||
#include <osg/Quat>
|
||||
#include <osg/Vec3f>
|
||||
|
||||
namespace LuaUtil
|
||||
{
|
||||
class Box
|
||||
{
|
||||
public:
|
||||
Box(const osg::Vec3f& center, const osg::Vec3f& halfSize, const osg::Quat& rotation = osg::Quat());
|
||||
Box(const osg::Matrix& transform);
|
||||
|
||||
std::array<osg::Vec3f, 8> vertices() const;
|
||||
|
||||
osg::Matrix asTransform() const;
|
||||
|
||||
// TODO: Add `contains` and `intersects` methods
|
||||
|
||||
bool operator==(const Box& other) const;
|
||||
|
||||
osg::Vec3f mCenter;
|
||||
osg::Vec3f mHalfSize;
|
||||
osg::Quat mRotation;
|
||||
};
|
||||
}
|
||||
#endif // COMPONENTS_LUA_SHAPES_BOX_H
|
@ -0,0 +1,64 @@
|
||||
#ifndef OPENMW_COMPONENTS_SCENEUTIL_CULLSAFEBOUNDSVISITOR_H
|
||||
#define OPENMW_COMPONENTS_SCENEUTIL_CULLSAFEBOUNDSVISITOR_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <osg/BoundingBox>
|
||||
#include <osg/Matrix>
|
||||
#include <osg/NodeVisitor>
|
||||
|
||||
#include <osg/Drawable>
|
||||
#include <osg/Transform>
|
||||
|
||||
namespace SceneUtil
|
||||
{
|
||||
// Computes local bounding box of a node without dirtying itself or any of its children
|
||||
struct CullSafeBoundsVisitor : osg::NodeVisitor
|
||||
{
|
||||
CullSafeBoundsVisitor(osg::NodeVisitor::TraversalMode traversalMode = TRAVERSE_ALL_CHILDREN)
|
||||
: osg::NodeVisitor(traversalMode)
|
||||
{
|
||||
}
|
||||
|
||||
void reset() override
|
||||
{
|
||||
mMatrixStack.clear();
|
||||
mBoundingBox.init();
|
||||
}
|
||||
|
||||
void apply(osg::Drawable& drawable)
|
||||
{
|
||||
osg::BoundingBox bbox = drawable.getInitialBound();
|
||||
bbox.expandBy(drawable.computeBoundingBox());
|
||||
applyBoundingBox(bbox);
|
||||
}
|
||||
|
||||
void apply(osg::Transform& transform)
|
||||
{
|
||||
osg::Matrix matrix;
|
||||
if (!mMatrixStack.empty())
|
||||
matrix = mMatrixStack.back();
|
||||
|
||||
mMatrixStack.push_back(matrix);
|
||||
traverse(transform);
|
||||
mMatrixStack.pop_back();
|
||||
}
|
||||
|
||||
void applyBoundingBox(const osg::BoundingBox& bbox)
|
||||
{
|
||||
if (mMatrixStack.empty())
|
||||
{
|
||||
mBoundingBox.expandBy(bbox);
|
||||
}
|
||||
else if (bbox.valid())
|
||||
{
|
||||
for (int i = 0; i < 8; ++i)
|
||||
mBoundingBox.expandBy(bbox.corner(i) * mMatrixStack.back());
|
||||
}
|
||||
}
|
||||
|
||||
osg::BoundingBox mBoundingBox;
|
||||
std::vector<osg::Matrix> mMatrixStack;
|
||||
};
|
||||
}
|
||||
#endif // OPENMW_COMPONENTS_SCENEUTIL_CULLSAFEBOUNDSVISITOR_H
|
Loading…
Reference in New Issue