mirror of
https://github.com/OpenMW/openmw.git
synced 2025-02-06 07:15:36 +00:00
Merge branch 'physics_heightfield' into 'master'
Replace float type for arguments to create heightfield with int See merge request OpenMW/openmw!1285
This commit is contained in:
commit
67fa8413f3
6 changed files with 38 additions and 20 deletions
|
@ -1,6 +1,8 @@
|
|||
#include "heightfield.hpp"
|
||||
#include "mtphysics.hpp"
|
||||
|
||||
#include <components/bullethelpers/heightfield.hpp>
|
||||
|
||||
#include <osg/Object>
|
||||
|
||||
#include <BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h>
|
||||
|
@ -19,17 +21,17 @@
|
|||
namespace
|
||||
{
|
||||
template <class T>
|
||||
auto makeHeights(const T* heights, float sqrtVerts)
|
||||
auto makeHeights(const T* heights, int verts)
|
||||
-> std::enable_if_t<std::is_same<btScalar, T>::value, std::vector<btScalar>>
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto makeHeights(const T* heights, float sqrtVerts)
|
||||
auto makeHeights(const T* heights, int verts)
|
||||
-> std::enable_if_t<!std::is_same<btScalar, T>::value, std::vector<btScalar>>
|
||||
{
|
||||
return std::vector<btScalar>(heights, heights + static_cast<std::ptrdiff_t>(sqrtVerts * sqrtVerts));
|
||||
return std::vector<btScalar>(heights, heights + static_cast<std::ptrdiff_t>(verts * verts));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
@ -50,16 +52,17 @@ namespace
|
|||
|
||||
namespace MWPhysics
|
||||
{
|
||||
HeightField::HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler)
|
||||
HeightField::HeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH,
|
||||
const osg::Object* holdObject, PhysicsTaskScheduler* scheduler)
|
||||
: mHoldObject(holdObject)
|
||||
#if BT_BULLET_VERSION < 310
|
||||
, mHeights(makeHeights(heights, sqrtVerts))
|
||||
, mHeights(makeHeights(heights, verts))
|
||||
#endif
|
||||
, mTaskScheduler(scheduler)
|
||||
{
|
||||
#if BT_BULLET_VERSION < 310
|
||||
mShape = std::make_unique<btHeightfieldTerrainShape>(
|
||||
sqrtVerts, sqrtVerts,
|
||||
verts, verts,
|
||||
getHeights(heights, mHeights),
|
||||
1,
|
||||
minH, maxH, 2,
|
||||
|
@ -67,10 +70,12 @@ namespace MWPhysics
|
|||
);
|
||||
#else
|
||||
mShape = std::make_unique<btHeightfieldTerrainShape>(
|
||||
sqrtVerts, sqrtVerts, heights, minH, maxH, 2, false);
|
||||
verts, verts, heights, minH, maxH, 2, false);
|
||||
#endif
|
||||
mShape->setUseDiamondSubdivision(true);
|
||||
mShape->setLocalScaling(btVector3(triSize, triSize, 1));
|
||||
|
||||
const float scaling = static_cast<float>(size) / static_cast<float>(verts - 1);
|
||||
mShape->setLocalScaling(btVector3(scaling, scaling, 1));
|
||||
|
||||
#if BT_BULLET_VERSION >= 289
|
||||
// Accelerates some collision tests.
|
||||
|
@ -81,10 +86,8 @@ namespace MWPhysics
|
|||
mShape->buildAccelerator();
|
||||
#endif
|
||||
|
||||
btTransform transform(btQuaternion::getIdentity(),
|
||||
btVector3((x+0.5f) * triSize * (sqrtVerts-1),
|
||||
(y+0.5f) * triSize * (sqrtVerts-1),
|
||||
(maxH+minH)*0.5f));
|
||||
const btTransform transform(btQuaternion::getIdentity(),
|
||||
BulletHelpers::getHeightfieldShift(x, y, size, minH, maxH));
|
||||
|
||||
mCollisionObject = std::make_unique<btCollisionObject>();
|
||||
mCollisionObject->setCollisionShape(mShape.get());
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace MWPhysics
|
|||
class HeightField
|
||||
{
|
||||
public:
|
||||
HeightField(const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject, PhysicsTaskScheduler* scheduler);
|
||||
HeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH,
|
||||
const osg::Object* holdObject, PhysicsTaskScheduler* scheduler);
|
||||
~HeightField();
|
||||
|
||||
btCollisionObject* getCollisionObject();
|
||||
|
|
|
@ -472,9 +472,9 @@ namespace MWPhysics
|
|||
return MovementSolver::traceDown(ptr, position, found->second.get(), mCollisionWorld.get(), maxHeight);
|
||||
}
|
||||
|
||||
void PhysicsSystem::addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject)
|
||||
void PhysicsSystem::addHeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, const osg::Object* holdObject)
|
||||
{
|
||||
mHeightFields[std::make_pair(x,y)] = std::make_unique<HeightField>(heights, x, y, triSize, sqrtVerts, minH, maxH, holdObject, mTaskScheduler.get());
|
||||
mHeightFields[std::make_pair(x,y)] = std::make_unique<HeightField>(heights, x, y, size, verts, minH, maxH, holdObject, mTaskScheduler.get());
|
||||
}
|
||||
|
||||
void PhysicsSystem::removeHeightField (int x, int y)
|
||||
|
|
|
@ -150,7 +150,7 @@ namespace MWPhysics
|
|||
void updateRotation (const MWWorld::Ptr& ptr, osg::Quat rotate);
|
||||
void updatePosition (const MWWorld::Ptr& ptr);
|
||||
|
||||
void addHeightField (const float* heights, int x, int y, float triSize, float sqrtVerts, float minH, float maxH, const osg::Object* holdObject);
|
||||
void addHeightField(const float* heights, int x, int y, int size, int verts, float minH, float maxH, const osg::Object* holdObject);
|
||||
|
||||
void removeHeightField (int x, int y);
|
||||
|
||||
|
|
|
@ -372,17 +372,17 @@ namespace MWWorld
|
|||
{
|
||||
osg::ref_ptr<const ESMTerrain::LandObject> land = mRendering.getLandManager()->getLand(cellX, cellY);
|
||||
const ESM::Land::LandData* data = land ? land->getData(ESM::Land::DATA_VHGT) : nullptr;
|
||||
const float verts = ESM::Land::LAND_SIZE;
|
||||
const float worldsize = ESM::Land::REAL_SIZE;
|
||||
const int verts = ESM::Land::LAND_SIZE;
|
||||
const int worldsize = ESM::Land::REAL_SIZE;
|
||||
if (data)
|
||||
{
|
||||
mPhysics->addHeightField (data->mHeights, cellX, cellY, worldsize / (verts-1), verts, data->mMinHeight, data->mMaxHeight, land.get());
|
||||
mPhysics->addHeightField(data->mHeights, cellX, cellY, worldsize, verts, data->mMinHeight, data->mMaxHeight, land.get());
|
||||
}
|
||||
else
|
||||
{
|
||||
static std::vector<float> defaultHeight;
|
||||
defaultHeight.resize(verts*verts, ESM::Land::DEFAULT_HEIGHT);
|
||||
mPhysics->addHeightField (&defaultHeight[0], cellX, cellY, worldsize / (verts-1), verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
|
||||
mPhysics->addHeightField(defaultHeight.data(), cellX, cellY, worldsize, verts, ESM::Land::DEFAULT_HEIGHT, ESM::Land::DEFAULT_HEIGHT, land.get());
|
||||
}
|
||||
if (const auto heightField = mPhysics->getHeightField(cellX, cellY))
|
||||
{
|
||||
|
|
14
components/bullethelpers/heightfield.hpp
Normal file
14
components/bullethelpers/heightfield.hpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
#ifndef OPENMW_COMPONENTS_BULLETHELPERS_HEIGHTFIELD_H
|
||||
#define OPENMW_COMPONENTS_BULLETHELPERS_HEIGHTFIELD_H
|
||||
|
||||
#include <LinearMath/btVector3.h>
|
||||
|
||||
namespace BulletHelpers
|
||||
{
|
||||
inline btVector3 getHeightfieldShift(int x, int y, int size, float minHeight, float maxHeight)
|
||||
{
|
||||
return btVector3((x + 0.5f) * size, (y + 0.5f) * size, (maxHeight + minHeight) * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue