mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-08-03 23:36:59 -04:00
Assume NIF controller data is already sorted (#8545)
This commit is contained in:
parent
c90ae89381
commit
93cb69b012
@ -247,16 +247,11 @@ namespace Nif
|
|||||||
|
|
||||||
void NiVisData::read(NIFStream* nif)
|
void NiVisData::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
mKeys = std::make_shared<std::map<float, bool>>();
|
mKeys = std::make_shared<std::vector<std::pair<float, bool>>>(nif->get<uint32_t>());
|
||||||
uint32_t numKeys;
|
for (auto& [time, value] : *mKeys)
|
||||||
nif->read(numKeys);
|
|
||||||
for (size_t i = 0; i < numKeys; i++)
|
|
||||||
{
|
{
|
||||||
float time;
|
|
||||||
char value;
|
|
||||||
nif->read(time);
|
nif->read(time);
|
||||||
nif->read(value);
|
value = nif->get<uint8_t>() != 0;
|
||||||
(*mKeys)[time] = (value != 0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,8 +193,8 @@ namespace Nif
|
|||||||
|
|
||||||
struct NiVisData : public Record
|
struct NiVisData : public Record
|
||||||
{
|
{
|
||||||
// TODO: investigate possible use of BoolKeyMap
|
// This is theoretically a "flat map" sorted by time
|
||||||
std::shared_ptr<std::map<float, bool>> mKeys;
|
std::shared_ptr<std::vector<std::pair<float, bool>>> mKeys;
|
||||||
|
|
||||||
void read(NIFStream* nif) override;
|
void read(NIFStream* nif) override;
|
||||||
};
|
};
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
#ifndef OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||||
#define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
#define OPENMW_COMPONENTS_NIF_NIFKEY_HPP
|
||||||
|
|
||||||
#include <map>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
@ -46,7 +46,8 @@ namespace Nif
|
|||||||
template <typename T, T (NIFStream::*getValue)()>
|
template <typename T, T (NIFStream::*getValue)()>
|
||||||
struct KeyMapT
|
struct KeyMapT
|
||||||
{
|
{
|
||||||
using MapType = std::map<float, KeyT<T>>;
|
// This is theoretically a "flat map" sorted by time
|
||||||
|
using MapType = std::vector<std::pair<float, KeyT<T>>>;
|
||||||
|
|
||||||
using ValueType = T;
|
using ValueType = T;
|
||||||
using KeyType = KeyT<T>;
|
using KeyType = KeyT<T>;
|
||||||
@ -78,9 +79,13 @@ namespace Nif
|
|||||||
uint32_t count;
|
uint32_t count;
|
||||||
nif->read(count);
|
nif->read(count);
|
||||||
|
|
||||||
if (count != 0 || morph)
|
if (count == 0 && !morph)
|
||||||
|
return;
|
||||||
|
|
||||||
nif->read(mInterpolationType);
|
nif->read(mInterpolationType);
|
||||||
|
|
||||||
|
mKeys.reserve(count);
|
||||||
|
|
||||||
KeyType key = {};
|
KeyType key = {};
|
||||||
|
|
||||||
if (mInterpolationType == InterpolationType_Linear || mInterpolationType == InterpolationType_Constant)
|
if (mInterpolationType == InterpolationType_Linear || mInterpolationType == InterpolationType_Constant)
|
||||||
@ -90,7 +95,7 @@ namespace Nif
|
|||||||
float time;
|
float time;
|
||||||
nif->read(time);
|
nif->read(time);
|
||||||
readValue(*nif, key);
|
readValue(*nif, key);
|
||||||
mKeys[time] = key;
|
mKeys.emplace_back(time, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInterpolationType == InterpolationType_Quadratic)
|
else if (mInterpolationType == InterpolationType_Quadratic)
|
||||||
@ -100,7 +105,7 @@ namespace Nif
|
|||||||
float time;
|
float time;
|
||||||
nif->read(time);
|
nif->read(time);
|
||||||
readQuadratic(*nif, key);
|
readQuadratic(*nif, key);
|
||||||
mKeys[time] = key;
|
mKeys.emplace_back(time, key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (mInterpolationType == InterpolationType_TCB)
|
else if (mInterpolationType == InterpolationType_TCB)
|
||||||
@ -115,8 +120,9 @@ namespace Nif
|
|||||||
nif->read(tcbKey.mBias);
|
nif->read(tcbKey.mBias);
|
||||||
}
|
}
|
||||||
generateTCBTangents(tcbKeys);
|
generateTCBTangents(tcbKeys);
|
||||||
for (TCBKey<T>& key : tcbKeys)
|
for (TCBKey<T>& tcbKey : tcbKeys)
|
||||||
mKeys[key.mTime] = KeyType{ std::move(key.mValue), std::move(key.mInTan), std::move(key.mOutTan) };
|
mKeys.emplace_back(std::move(tcbKey.mTime),
|
||||||
|
KeyType{ std::move(tcbKey.mValue), std::move(tcbKey.mInTan), std::move(tcbKey.mOutTan) });
|
||||||
}
|
}
|
||||||
else if (mInterpolationType == InterpolationType_XYZ)
|
else if (mInterpolationType == InterpolationType_XYZ)
|
||||||
{
|
{
|
||||||
@ -132,6 +138,8 @@ namespace Nif
|
|||||||
throw Nif::Exception("Unhandled interpolation type: " + std::to_string(mInterpolationType),
|
throw Nif::Exception("Unhandled interpolation type: " + std::to_string(mInterpolationType),
|
||||||
nif->getFile().getFilename());
|
nif->getFile().getFilename());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Note: NetImmerse does NOT sort keys or remove duplicates
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -676,12 +676,16 @@ namespace Nif
|
|||||||
|
|
||||||
void NiPSysEmitterCtlrData::read(NIFStream* nif)
|
void NiPSysEmitterCtlrData::read(NIFStream* nif)
|
||||||
{
|
{
|
||||||
|
// TODO: this is not used in the official files and needs verification
|
||||||
mFloatKeyList = std::make_shared<FloatKeyMap>();
|
mFloatKeyList = std::make_shared<FloatKeyMap>();
|
||||||
|
mFloatKeyList->read(nif);
|
||||||
mVisKeyList = std::make_shared<BoolKeyMap>();
|
mVisKeyList = std::make_shared<BoolKeyMap>();
|
||||||
uint32_t numVisKeys;
|
mVisKeyList->mKeys.resize(nif->get<uint32_t>());
|
||||||
nif->read(numVisKeys);
|
for (auto& [time, key] : mVisKeyList->mKeys)
|
||||||
for (size_t i = 0; i < numVisKeys; i++)
|
{
|
||||||
mVisKeyList->mKeys[nif->get<float>()].mValue = nif->get<uint8_t>() != 0;
|
nif->read(time);
|
||||||
|
key.mValue = nif->get<uint8_t>() != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NiPSysCollider::read(NIFStream* nif)
|
void NiPSysCollider::read(NIFStream* nif)
|
||||||
|
@ -374,7 +374,8 @@ namespace NifOsg
|
|||||||
if (mData->empty())
|
if (mData->empty())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
auto iter = mData->upper_bound(time);
|
auto iter = std::upper_bound(mData->begin(), mData->end(), time,
|
||||||
|
[](float time, const std::pair<float, bool>& key) { return time < key.first; });
|
||||||
if (iter != mData->begin())
|
if (iter != mData->begin())
|
||||||
--iter;
|
--iter;
|
||||||
return iter->second;
|
return iter->second;
|
||||||
|
@ -54,7 +54,8 @@ namespace NifOsg
|
|||||||
return mLastHighKey;
|
return mLastHighKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mKeys->mKeys.lower_bound(time);
|
return std::lower_bound(mKeys->mKeys.begin(), mKeys->mKeys.end(), time,
|
||||||
|
[](const typename MapT::MapType::value_type& key, float t) { return key.first < t; });
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -99,8 +100,8 @@ namespace NifOsg
|
|||||||
|
|
||||||
const typename MapT::MapType& keys = mKeys->mKeys;
|
const typename MapT::MapType& keys = mKeys->mKeys;
|
||||||
|
|
||||||
if (time <= keys.begin()->first)
|
if (time <= keys.front().first)
|
||||||
return keys.begin()->second.mValue;
|
return keys.front().second.mValue;
|
||||||
|
|
||||||
typename MapT::MapType::const_iterator it = retrieveKey(time);
|
typename MapT::MapType::const_iterator it = retrieveKey(time);
|
||||||
|
|
||||||
@ -116,7 +117,7 @@ namespace NifOsg
|
|||||||
return interpolate(mLastLowKey->second, mLastHighKey->second, a, mKeys->mInterpolationType);
|
return interpolate(mLastLowKey->second, mLastHighKey->second, a, mKeys->mInterpolationType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return keys.rbegin()->second.mValue;
|
return keys.back().second.mValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const { return !mKeys || mKeys->mKeys.empty(); }
|
bool empty() const { return !mKeys || mKeys->mKeys.empty(); }
|
||||||
@ -283,7 +284,7 @@ namespace NifOsg
|
|||||||
class VisController : public SceneUtil::NodeCallback<VisController>, public SceneUtil::Controller
|
class VisController : public SceneUtil::NodeCallback<VisController>, public SceneUtil::Controller
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<std::map<float, bool>> mData;
|
std::shared_ptr<std::vector<std::pair<float, bool>>> mData;
|
||||||
BoolInterpolator mInterpolator;
|
BoolInterpolator mInterpolator;
|
||||||
unsigned int mMask{ 0u };
|
unsigned int mMask{ 0u };
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user