Looks like the forum is pretty dead. We found an easy solution to sort cloud puffs, now looking how to sort clouds.
CloudVolumeDepthSorter.h
#pragma once
class CloudVolumeDepthSorter
{
class vpEnvCloudVolumeHack : public vpEnvCloudVolume {friend class CloudVolumeDepthSorter;};
typedef std::pair<double, vpEnvCloudVolumeHack::Puff*> PuffDepth;
typedef std::vector<PuffDepth> SortedPuffs;
static inline bool ComparePuffDepth(PuffDepth& a, PuffDepth& b) {return (a.first > b.first);}
public:
CloudVolumeDepthSorter();
void Update();
void SortCloud(vpEnvCloudVolumeHack* cloud, const vuVec3<float>& campos);
private:
vpEnvCloudVolumeHack::Puffs m_puffs;
SortedPuffs m_sorted;
float m_sort_rate;
float m_sort_accum;
};
CloudVolumeDepthSorter.cpp
CloudVolumeDepthSorter::CloudVolumeDepthSorter()
{
m_sort_rate = 0.5f;
m_sort_accum = m_sort_rate + 1.0f;
}
//
// TODO:
// sort only visible puffs only when observer position changed
// do something with hardcoded myObserver
//
void CloudVolumeDepthSorter::Update()
{
const float dt = vpKernel::instance()->getSimulationDeltaTime();
m_sort_accum += dt;
if (m_sort_accum > m_sort_rate) {
m_sort_accum = 0.0f;
vpObserver* cam = vpObserver::find("myObserver");
double cx, cy, cz;
cam->getTranslate(&cx;, &cy;, &cz;);
vuVec3<float> campos(cx, cy, cz);
vpEnvCloudVolume::const_iterator i, iend;
for (i = vpEnvCloudVolume::begin(), iend = vpEnvCloudVolume::end(); i != iend; ++i) {
vpEnvCloudVolume* cloud = *i;
SortCloud((vpEnvCloudVolumeHack*)cloud, campos);
}
}
}
void CloudVolumeDepthSorter::SortCloud(vpEnvCloudVolumeHack* cloud, const vuVec3<float>& campos)
{
vpEnvCloudVolumeHack::Puffs& pufvec = cloud->m_puffs;
const size_t npuffs = pufvec.size();
m_puffs.clear();
m_puffs.swap(pufvec);
m_sorted.clear();
m_sorted.reserve(npuffs);
double x, y, z;
cloud->getTranslate(&x, &y, &z);
vuVec3<float> pufpos;
vpEnvCloudVolumeHack::Puffs::iterator i, iend;
for (i = m_puffs.begin(), iend = m_puffs.end(); i != iend; ++i)
{
vpEnvCloudVolumeHack::Puff& puff = *i;
pufpos = puff.m_position;
pufpos[0] += x;
pufpos[1] += y;
pufpos[2] += z;
const double distsq = campos.distanceSq(pufpos);
m_sorted.push_back(PuffDepth(distsq, &puff;));
}
std::sort(m_sorted.begin(), m_sorted.end(), ComparePuffDepth);
SortedPuffs::iterator j, jend;
for (j = m_sorted.begin(), jend = m_sorted.end(); j != jend; ++j)
{
pufvec.push_back(*(j->second));
}
}