Initial commit: Final state of the master project

This commit is contained in:
2017-09-16 09:41:37 +02:00
commit 696180d43b
832 changed files with 169717 additions and 0 deletions

View File

@@ -0,0 +1,169 @@
#pragma once
#include "Color.h"
#include "../../core/ColorHelper.h"
#include "../../inc/glm/glm.hpp"
#include "../../core/Hashers.h"
#include "../../core/Comparers.h"
#include "../../core/CollectionHelper.h"
#include "../../core/Serializer.h"
#include "../../core/BitHelper.h"
template<typename U, typename V>
class MaterialPair
{
private:
U mFirst;
V mSecond;
public:
static const unsigned8 BITS = U::BITS + V::BITS;
static const unsigned8 CHANNELSPERPIXEL = BITS % 32 == 0 ? 4 : 3;
MaterialPair() : mFirst(U()), mSecond(V()) {}
MaterialPair(U first, V second) : mFirst(first), mSecond(second) {}
MaterialPair(std::pair<U, V> pair) : mFirst(pair.first), mSecond(pair.second) {}
template<typename UC, typename VC>
MaterialPair(UC first, VC second) : MaterialPair(U(first), V(second)) {}
const U& GetFirst() const { return mFirst; }
void SetFirst(U value) { mFirst = value; }
const V& GetSecond() const { return mSecond; }
void SetSecond(V value) { mSecond = value; }
static MaterialPair Average(const std::vector<MaterialPair>& values)
{
std::vector<U> firsts(values.size());
std::vector<V> seconds(values.size());
for (size_t i = 0; i < values.size(); i++)
{
firsts[i] = values[i].GetFirst();
seconds[i] = values[i].GetSecond();
}
return MaterialPair(U::Average(first), V::Average(seconds));
}
static MaterialPair WeightedAverage(const std::vector<MaterialPair>& values, const std::vector<float>& weights)
{
std::vector<U> firsts(values.size());
std::vector<V> seconds(values.size());
for (size_t i = 0; i < values.size(); i++)
{
firsts[i] = values[i].GetFirst();
seconds[i] = values[i].GetSecond();
}
return MaterialPair(U::WeightedAverage(firsts, weights), V::WeightedAverage(seconds, weights));
}
static float Distance(const MaterialPair& a, const MaterialPair& b)
{
return (U::Distance(a.GetFirst(), a.GetSecond()) + V::Distance(a.GetSecond(), b.GetSecond())) * 0.5f;
}
std::string GetTypeSuffix() const { return GetFirst().GetTypeSuffix() + GetSecond().GetTypeSuffix(); }
std::vector<unsigned8> Serialize() const {
std::vector<unsigned8> firstSerialized = GetFirst().Serialize();
std::vector<unsigned8> secondSerialized = GetSecond().Serialize();
firstSerialized.insert(firstSerialized.end(), secondSerialized.begin(), secondSerialized.end());
return firstSerialized;
};
void Deserialize(const std::vector<unsigned8>& value)
{
mFirst.Deserialize(std::vector<unsigned8>(value.begin(), value.begin() + sizeof(mFirst)));
mSecond.Deserialize(std::vector<unsigned8>(value.begin() + sizeof(mFirst), value.end()));
}
bool operator==(const MaterialPair& v) const { return v.mFirst == mFirst && v.mSecond == mSecond; }
bool operator!=(const MaterialPair& n) const { return !(n == *this); }
//// Assignment operator, used for easy access to different kinds of materials
//ColorAndValue& operator=(const unsigned& source)
//{
// mValue = source & 0x3FF;
// glm::u8vec3 color;
// color.r = (source >> (10 + 14 - 1)) & 0xFE;
// color.g = (source >> (10 + 7 - 1)) & 0xFE;
// color.b = (source >> (10 - 1)) & 0xFE;
// mColor = Color(color);
//}
//operator unsigned() const
//{
// // Value is stored in the 10 lowest siginificant bits
// unsigned32 res = (unsigned32)mValue;
// // Colors are stored in the 21 highest significant bits (7 bits per channel, doesn't fit otherwise...)
// res |= ((unsigned32)mColor.GetR() & 0xFE) << (10 + 14 - 1);
// res |= ((unsigned32)mColor.GetG() & 0xFE) << (10 + 7 - 1);
// res |= ((unsigned32)mColor.GetB() & 0xFE) << (10 - 1);
// return res;
//}
};
template<typename U, typename V>
struct NearestFinder<MaterialPair<U, V>>
{
MaterialPair<U, V> operator()(const MaterialPair<U, V>& source, const std::vector<MaterialPair<U, V>>& values)
{
std::vector<float> distances(values.size());
// Distances are defined as the sum.
for (size_t i = 0; i < values.size(); i++)
distances[i] = U::Distance(source.GetFirst(), values[i].GetFirst()) + V::Distance(source.GetSecond(), values[i].GetSecond());
auto minIt = std::min_element(distances.begin(), distances.end());
size_t minIndex = std::distance(distances.begin(), minIt);
return values[minIndex];
}
};
template<typename U, typename V>
struct ParallelNearestFinder<MaterialPair<U, V>>
{
MaterialPair<U, V> operator()(const MaterialPair<U, V>& source, const std::vector<MaterialPair<U, V>>& values)
{
std::vector<float> distances(values.size());
// Distances are defined as the sum.
for (size_t i = 0; i < values.size(); i++)
distances[i] = U::Distance(source.GetFirst(), values[i].GetFirst()) + V::Distance(source.GetSecond(), values[i].GetSecond());
auto minIt = std::min_element(distances.begin(), distances.end());
size_t minIndex = std::distance(distances.begin(), minIt);
return values[minIndex];
}
};
namespace std {
template<typename U, typename V>
struct hash<MaterialPair<U, V>> {
size_t operator()(const MaterialPair<U, V> &value) const {
#ifdef ENVIRONMENT64
size_t cHash = std::hash<U>()(value.GetFirst());
size_t nHash = std::hash<V>()(value.GetSecond());
return cHash | BitHelper::CircularShiftLeft<size_t>(nHash, V::BITS);
#else
return (unsigned32)value;
#endif
}
};
}
template<typename U, typename UCompare, typename V, typename VCompare>
struct MaterialPairCompare
{
bool operator()(const MaterialPair<U, V>& a, const MaterialPair<U, V>& b) const
{
if (a.GetFirst() != b.GetFirst()) return UCompare()(a.GetFirst(), b.GetFirst());
return VCompare()(a.GetSecond(), b.GetSecond());
}
};
template<typename U, typename V>
struct Serializer<MaterialPair<U, V>>
{
static void Serialize(const MaterialPair<U, V>& value, std::ostream& out)
{
Serializer<U>::Serialize(value.GetFirst(), out);
Serializer<V>::Serialize(value.GetSecond(), out);
}
static void Deserialize(MaterialPair<U, V>& value, std::istream& in)
{
U first; Serializer<U>::Deserialize(first, in); value.SetFirst(first);
V second; Serializer<V>::Deserialize(second, in); value.SetSecond(second);
}
};