initial commit, 4.5 stable
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
Some checks failed
🔗 GHA / 📊 Static checks (push) Has been cancelled
🔗 GHA / 🤖 Android (push) Has been cancelled
🔗 GHA / 🍏 iOS (push) Has been cancelled
🔗 GHA / 🐧 Linux (push) Has been cancelled
🔗 GHA / 🍎 macOS (push) Has been cancelled
🔗 GHA / 🏁 Windows (push) Has been cancelled
🔗 GHA / 🌐 Web (push) Has been cancelled
This commit is contained in:
153
thirdparty/cvtt/ConvectionKernels_EndpointSelector.h
vendored
Normal file
153
thirdparty/cvtt/ConvectionKernels_EndpointSelector.h
vendored
Normal file
@@ -0,0 +1,153 @@
|
||||
#pragma once
|
||||
#ifndef __CVTT_ENDPOINTSELECTOR_H__
|
||||
#define __CVTT_ENDPOINTSELECTOR_H__
|
||||
|
||||
#include "ConvectionKernels_ParallelMath.h"
|
||||
#include "ConvectionKernels_UnfinishedEndpoints.h"
|
||||
#include "ConvectionKernels_PackedCovarianceMatrix.h"
|
||||
|
||||
namespace cvtt
|
||||
{
|
||||
namespace Internal
|
||||
{
|
||||
static const int NumEndpointSelectorPasses = 3;
|
||||
|
||||
template<int TVectorSize, int TIterationCount>
|
||||
class EndpointSelector
|
||||
{
|
||||
public:
|
||||
typedef ParallelMath::Float MFloat;
|
||||
|
||||
EndpointSelector()
|
||||
{
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
{
|
||||
m_centroid[ch] = ParallelMath::MakeFloatZero();
|
||||
m_direction[ch] = ParallelMath::MakeFloatZero();
|
||||
}
|
||||
m_weightTotal = ParallelMath::MakeFloatZero();
|
||||
m_minDist = ParallelMath::MakeFloat(FLT_MAX);
|
||||
m_maxDist = ParallelMath::MakeFloat(-FLT_MAX);
|
||||
}
|
||||
|
||||
void ContributePass(const MFloat *value, int pass, const MFloat &weight)
|
||||
{
|
||||
if (pass == 0)
|
||||
ContributeCentroid(value, weight);
|
||||
else if (pass == 1)
|
||||
ContributeDirection(value, weight);
|
||||
else if (pass == 2)
|
||||
ContributeMinMax(value);
|
||||
}
|
||||
|
||||
void FinishPass(int pass)
|
||||
{
|
||||
if (pass == 0)
|
||||
FinishCentroid();
|
||||
else if (pass == 1)
|
||||
FinishDirection();
|
||||
}
|
||||
|
||||
UnfinishedEndpoints<TVectorSize> GetEndpoints(const float channelWeights[TVectorSize]) const
|
||||
{
|
||||
MFloat unweightedBase[TVectorSize];
|
||||
MFloat unweightedOffset[TVectorSize];
|
||||
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
{
|
||||
MFloat min = m_centroid[ch] + m_direction[ch] * m_minDist;
|
||||
MFloat max = m_centroid[ch] + m_direction[ch] * m_maxDist;
|
||||
|
||||
float safeWeight = channelWeights[ch];
|
||||
if (safeWeight == 0.f)
|
||||
safeWeight = 1.0f;
|
||||
|
||||
unweightedBase[ch] = min / channelWeights[ch];
|
||||
unweightedOffset[ch] = (max - min) / channelWeights[ch];
|
||||
}
|
||||
|
||||
return UnfinishedEndpoints<TVectorSize>(unweightedBase, unweightedOffset);
|
||||
}
|
||||
|
||||
private:
|
||||
void ContributeCentroid(const MFloat *value, const MFloat &weight)
|
||||
{
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
m_centroid[ch] = m_centroid[ch] + value[ch] * weight;
|
||||
m_weightTotal = m_weightTotal + weight;
|
||||
}
|
||||
|
||||
void FinishCentroid()
|
||||
{
|
||||
MFloat denom = m_weightTotal;
|
||||
ParallelMath::MakeSafeDenominator(denom);
|
||||
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
m_centroid[ch] = m_centroid[ch] / denom;
|
||||
}
|
||||
|
||||
void ContributeDirection(const MFloat *value, const MFloat &weight)
|
||||
{
|
||||
MFloat diff[TVectorSize];
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
diff[ch] = value[ch] - m_centroid[ch];
|
||||
|
||||
m_covarianceMatrix.Add(diff, weight);
|
||||
}
|
||||
|
||||
void FinishDirection()
|
||||
{
|
||||
MFloat approx[TVectorSize];
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
approx[ch] = ParallelMath::MakeFloat(1.0f);
|
||||
|
||||
for (int i = 0; i < TIterationCount; i++)
|
||||
{
|
||||
MFloat product[TVectorSize];
|
||||
m_covarianceMatrix.Product(product, approx);
|
||||
|
||||
MFloat largestComponent = product[0];
|
||||
for (int ch = 1; ch < TVectorSize; ch++)
|
||||
largestComponent = ParallelMath::Max(largestComponent, product[ch]);
|
||||
|
||||
// product = largestComponent*newApprox
|
||||
ParallelMath::MakeSafeDenominator(largestComponent);
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
approx[ch] = product[ch] / largestComponent;
|
||||
}
|
||||
|
||||
// Normalize
|
||||
MFloat approxLen = ParallelMath::MakeFloatZero();
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
approxLen = approxLen + approx[ch] * approx[ch];
|
||||
|
||||
approxLen = ParallelMath::Sqrt(approxLen);
|
||||
|
||||
ParallelMath::MakeSafeDenominator(approxLen);
|
||||
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
m_direction[ch] = approx[ch] / approxLen;
|
||||
}
|
||||
|
||||
void ContributeMinMax(const MFloat *value)
|
||||
{
|
||||
MFloat dist = ParallelMath::MakeFloatZero();
|
||||
for (int ch = 0; ch < TVectorSize; ch++)
|
||||
dist = dist + m_direction[ch] * (value[ch] - m_centroid[ch]);
|
||||
|
||||
m_minDist = ParallelMath::Min(m_minDist, dist);
|
||||
m_maxDist = ParallelMath::Max(m_maxDist, dist);
|
||||
}
|
||||
|
||||
ParallelMath::Float m_centroid[TVectorSize];
|
||||
ParallelMath::Float m_direction[TVectorSize];
|
||||
PackedCovarianceMatrix<TVectorSize> m_covarianceMatrix;
|
||||
ParallelMath::Float m_weightTotal;
|
||||
|
||||
ParallelMath::Float m_minDist;
|
||||
ParallelMath::Float m_maxDist;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
Reference in New Issue
Block a user