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