diff options
Diffstat (limited to 'intern/audaspace/intern')
-rw-r--r-- | intern/audaspace/intern/AUD_AnimateableProperty.cpp | 88 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_AnimateableProperty.h | 14 |
2 files changed, 98 insertions, 4 deletions
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp index 0b333e687ff..61adae4b34b 100644 --- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp +++ b/intern/audaspace/intern/AUD_AnimateableProperty.cpp @@ -47,6 +47,15 @@ AUD_AnimateableProperty::AUD_AnimateableProperty(int count) : pthread_mutexattr_destroy(&attr); } +void AUD_AnimateableProperty::updateUnknownCache(int start, int end) +{ + float* buf = getBuffer(); + + for(int i = start; i <= end; i++) + // TODO: maybe first instead of zero order interpolation? + memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float)); +} + AUD_AnimateableProperty::~AUD_AnimateableProperty() { pthread_mutex_destroy(&m_mutex); @@ -67,6 +76,7 @@ void AUD_AnimateableProperty::write(const float* data) AUD_MutexLock lock(*this); m_isAnimated = false; + m_unknown.clear(); memcpy(getBuffer(), data, m_count * sizeof(float)); } @@ -74,18 +84,88 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count) { AUD_MutexLock lock(*this); - m_isAnimated = true; - int pos = getSize() / (sizeof(float) * m_count); + if(!m_isAnimated) + pos = 0; + + m_isAnimated = true; + assureSize((count + position) * m_count * sizeof(float), true); float* buf = getBuffer(); memcpy(buf + position * m_count, data, count * m_count * sizeof(float)); - for(int i = pos; i < position; i++) - memcpy(buf + i * m_count, buf + (pos - 1) * m_count, m_count * sizeof(float)); + // have to fill up space between? + if(pos < position) + { + m_unknown.push_back(Unknown(pos, position - 1)); + + if(pos == 0) + { + memset(buf, 0, position * m_count * sizeof(float)); + } + else + updateUnknownCache(pos, position - 1); + } + // otherwise it's not at the end, let's check if some unknown part got filled + else + { + bool erased = false; + + for(std::list<Unknown>::iterator it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++) + { + erased = false; + + // unknown area before position + if(it->end < position) + continue; + + // we're after the new area, let's stop + if(it->start >= position + count) + break; + + // we have an intersection, now 4 cases: + // the start is included + if(position <= it->start) + { + // the end is included + if(position + count > it->end) + { + // simply delete + it = m_unknown.erase(it); + erased = true; + } + // the end is excluded, a second part remains + else + { + // update second part + it->start = position + count; + updateUnknownCache(it->start, it->end); + break; + } + } + // start is excluded, a first part remains + else + { + // the end is included + if(position + count > it->end) + { + // update first part + it->end = position - 1; + } + // the end is excluded, a second part remains + else + { + // add another item and update both parts + m_unknown.insert(it, Unknown(it->start, position - 1)); + it->start = position + count; + updateUnknownCache(it->start, it->end); + } + } + } + } } void AUD_AnimateableProperty::read(float position, float* out) diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h index 322748ad571..37eb8f84550 100644 --- a/intern/audaspace/intern/AUD_AnimateableProperty.h +++ b/intern/audaspace/intern/AUD_AnimateableProperty.h @@ -34,6 +34,7 @@ #include "AUD_ILockable.h" #include <pthread.h> +#include <list> /** * This class saves animation data for float properties. @@ -41,6 +42,14 @@ class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable { private: + struct Unknown { + int start; + int end; + + Unknown(int start, int end) : + start(start), end(end) {} + }; + /// The count of floats for a single property. const int m_count; @@ -50,10 +59,15 @@ private: /// The mutex for locking. pthread_mutex_t m_mutex; + /// The list of unknown buffer areas. + std::list<Unknown> m_unknown; + // hide copy constructor and operator= AUD_AnimateableProperty(const AUD_AnimateableProperty&); AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&); + void updateUnknownCache(int start, int end); + public: /** * Creates a new animateable property. |