v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
68
attic/unneeded/StarCoordSys.hpp
Normal file
68
attic/unneeded/StarCoordSys.hpp
Normal file
|
@ -0,0 +1,68 @@
|
|||
#ifndef STAR_COORD_SYS_H
|
||||
#define STAR_COORD_SYS_H
|
||||
|
||||
#include "StarMathCommon.hpp"
|
||||
#include "StarVector3.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
class CoordinateSystem3 {
|
||||
public:
|
||||
static inline CoordinateSystem3 opengl() {
|
||||
return CoordinateSystem3(-3, 1, -2);
|
||||
}
|
||||
static inline CoordinateSystem3 northEastDown() {
|
||||
return CoordinateSystem3(1, 2, 3);
|
||||
}
|
||||
static inline CoordinateSystem3 eastNorthUp() {
|
||||
return CoordinateSystem3(2, 1, -3);
|
||||
}
|
||||
|
||||
static inline Vec3D getDirection(int v) {
|
||||
Vec3D dir(0, 0, 0);
|
||||
if(v < 0)
|
||||
dir[-v - 1] = -1.0f;
|
||||
else
|
||||
dir[v - 1] = 1.0f;
|
||||
return dir;
|
||||
}
|
||||
|
||||
inline CoordinateSystem3(int forward, int right, int down) {
|
||||
if((forward < -3 || forward > 3 || forward == 0) ||
|
||||
(right < -3 || right > 3 || right == 0) ||
|
||||
(down < -3 || down > 3 || down == 0)) {
|
||||
throw MathException("Value out of range [-3, -1], [1, -3] on "
|
||||
"CoordinateSystem3 constructor");
|
||||
}
|
||||
m_forward = forward;
|
||||
m_right = right;
|
||||
m_down = down;
|
||||
}
|
||||
|
||||
inline Vec3D getForward() const { return getDirection(m_forward); }
|
||||
inline Vec3D getRight() const { return getDirection(m_right); }
|
||||
inline Vec3D getDown() const { return getDirection(m_down); }
|
||||
|
||||
size_t getForwardIndex() const { return abs(m_forward) - 1; }
|
||||
size_t getRightIndex() const { return abs(m_right) - 1; }
|
||||
size_t getDownIndex() const { return abs(m_down) - 1; }
|
||||
|
||||
int getForwardSign() const { return m_forward / abs(m_forward); }
|
||||
int getRightSign() const { return m_right / abs(m_right); }
|
||||
int getDownSign() const { return m_down / abs(m_down); }
|
||||
|
||||
bool operator==(CoordinateSystem3 const& ref) const {
|
||||
return m_forward == ref.m_forward &&
|
||||
m_right == ref.m_right &&
|
||||
m_down == ref.m_down;
|
||||
}
|
||||
|
||||
private:
|
||||
int m_forward;
|
||||
int m_right;
|
||||
int m_down;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
173
attic/unneeded/StarFFT.hpp
Normal file
173
attic/unneeded/StarFFT.hpp
Normal file
|
@ -0,0 +1,173 @@
|
|||
#ifndef STAR_FFT_HPP
|
||||
#define STAR_FFT_HPP
|
||||
|
||||
#include "StarMathCommon.hpp"
|
||||
|
||||
#include <complex>
|
||||
#include <vector>
|
||||
|
||||
namespace Star {
|
||||
|
||||
template<typename Float>
|
||||
class FFT {
|
||||
public:
|
||||
typedef std::complex<Float> Complex;
|
||||
typedef std::vector<Complex> Vector;
|
||||
|
||||
static Float intensity(Complex c);
|
||||
static Float phase(Complex c);
|
||||
|
||||
FFT(int n);
|
||||
FFT();
|
||||
|
||||
// Initializes FFT, n will be rounded up to the nearest power of 2.
|
||||
void init(int n);
|
||||
|
||||
int size() const;
|
||||
|
||||
Float freq(int i, Float sampleRate = 1.0f) const;
|
||||
|
||||
// Computes DFT, buffer will be resized to current size.
|
||||
void transform(Vector& data) const;
|
||||
|
||||
// Computes inverse DFT, buffer will be resized to current size.
|
||||
void itransform(Vector& data) const;
|
||||
|
||||
// Make vector complex conjugate symmetric so that the output of a (forward)
|
||||
// transform will be real.
|
||||
void makeSymmetric(Vector& data) const;
|
||||
|
||||
private:
|
||||
int m_n, m_lgN;
|
||||
Vector m_omega;
|
||||
Vector m_iomega;
|
||||
|
||||
void bitReverse(Vector& dest) const;
|
||||
};
|
||||
|
||||
template<typename Float>
|
||||
Float FFT<Float>::intensity(Complex c) {
|
||||
return std::abs(c);
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
Float FFT<Float>::phase(Complex c) {
|
||||
return std::arg(c);
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
FFT<Float>::FFT() : m_n(0), m_lgN(0) {}
|
||||
|
||||
template<typename Float>
|
||||
FFT<Float>::FFT(int n) {
|
||||
init(n);
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
void FFT<Float>::init(int n) {
|
||||
if (m_n == n)
|
||||
return;
|
||||
|
||||
m_n = ceilPowerOf2(n);
|
||||
m_lgN = 0;
|
||||
|
||||
for (int i = m_n; i > 1; i /= 2)
|
||||
++m_lgN;
|
||||
|
||||
m_omega.resize(m_lgN);
|
||||
int m = 1;
|
||||
for (int s = 0; s < m_lgN; ++s) {
|
||||
m *= 2;
|
||||
m_omega[s] = std::exp(Complex(0, -2.0 * Constants::pi / m));
|
||||
}
|
||||
|
||||
m_iomega.resize(m_lgN);
|
||||
m = 1;
|
||||
for (int s = 0; s < m_lgN; ++s) {
|
||||
m *= 2;
|
||||
m_iomega[s] = std::exp(Complex(0, 2.0 * Constants::pi / m));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
int FFT<Float>::size() const {
|
||||
return m_n;
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
Float FFT<Float>::freq(int i, Float sampleRate) const {
|
||||
return sampleRate * i / m_n;
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
void FFT<Float>::transform(Vector& data) const {
|
||||
data.resize(m_n);
|
||||
bitReverse(data);
|
||||
int m = 1;
|
||||
for (int s = 0; s < m_lgN; ++s) {
|
||||
m *= 2;
|
||||
for (int k = 0; k < m_n; k += m) {
|
||||
Complex current_omega = 1;
|
||||
for (int j = 0; j < (m / 2); ++j) {
|
||||
Complex t = current_omega * data[k + j + (m / 2)];
|
||||
Complex u = data[k + j];
|
||||
data[k + j] = u + t;
|
||||
data[k + j + (m / 2)] = u - t;
|
||||
current_omega *= m_omega[s];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < m_n; ++i)
|
||||
data[i] /= m_n;
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
void FFT<Float>::itransform(Vector& data) const {
|
||||
data.resize(m_n);
|
||||
bitReverse(data);
|
||||
int m = 1;
|
||||
for (int s = 0; s < m_lgN; ++s) {
|
||||
m *= 2;
|
||||
for (int k = 0; k < m_n; k += m) {
|
||||
Complex current_omega = 1;
|
||||
for (int j = 0; j < (m / 2); ++j) {
|
||||
Complex t = current_omega * data[k + j + (m / 2)];
|
||||
Complex u = data[k + j];
|
||||
data[k + j] = u + t;
|
||||
data[k + j + (m / 2)] = u - t;
|
||||
current_omega *= m_iomega[s];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
void FFT<Float>::makeSymmetric(Vector& data) const {
|
||||
data.resize(m_n);
|
||||
for (int i = 0; i <= m_n / 2; ++i) {
|
||||
if (i == 0 || i == m_n / 2)
|
||||
data[i] = data[i].real();
|
||||
else
|
||||
data[m_n - i] = std::conj(data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Float>
|
||||
void FFT<Float>::bitReverse(Vector& data) const {
|
||||
for (int i = 0; i < m_n; ++i) {
|
||||
int index = i, rev = 0;
|
||||
for (int j = 0; j < m_lgN; ++j) {
|
||||
rev = (rev << 1) | (index & 1);
|
||||
index >>= 1;
|
||||
}
|
||||
if (i < rev)
|
||||
std::swap(data[i], data[rev]);
|
||||
}
|
||||
}
|
||||
|
||||
typedef FFT<float> FFTF;
|
||||
typedef FFT<double> FFTD;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
139
attic/unneeded/StarFifo.cpp
Normal file
139
attic/unneeded/StarFifo.cpp
Normal file
|
@ -0,0 +1,139 @@
|
|||
#include "StarFifo.hpp"
|
||||
#include "StarFormat.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
pair<FifoPtr, FifoPtr> Fifo::makePair(bool blocking, size_t bufferSize) {
|
||||
auto left = make_shared<Fifo>(blocking, bufferSize);
|
||||
auto right = make_shared<Fifo>(blocking, bufferSize);
|
||||
|
||||
left->m_isPaired = true;
|
||||
left->m_pairedFifo = right;
|
||||
right->m_isPaired = true;
|
||||
right->m_pairedFifo = left;
|
||||
|
||||
return {left, right};
|
||||
}
|
||||
|
||||
Fifo::Fifo(bool blocking, size_t bufferSize) {
|
||||
m_buffer.resize(bufferSize, 0);
|
||||
m_blocking = blocking;
|
||||
m_readPos = 0;
|
||||
m_writePos = 0;
|
||||
m_writeFull = false;
|
||||
m_readEmpty = true;
|
||||
m_isPaired = false;
|
||||
setMode(ReadWrite);
|
||||
}
|
||||
|
||||
void Fifo::close() {
|
||||
setMode(Closed);
|
||||
disconnect();
|
||||
}
|
||||
|
||||
size_t Fifo::read(char* data, size_t len) {
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
MutexLocker locker(m_mutex);
|
||||
|
||||
size_t ramt = 0;
|
||||
while (isOpen()) {
|
||||
while (!m_readEmpty && ramt < len) {
|
||||
*data = m_buffer[m_readPos];
|
||||
++data;
|
||||
++ramt;
|
||||
m_readPos = (m_readPos + 1) % m_buffer.size();
|
||||
|
||||
m_writeFull = false;
|
||||
if (m_readPos == m_writePos)
|
||||
m_readEmpty = true;
|
||||
}
|
||||
|
||||
// Signal any waiting writes.
|
||||
m_condition.signal();
|
||||
|
||||
// If we are blocking, and haven't read all we need, wait for writers.
|
||||
if (m_blocking && ramt < len) {
|
||||
// Make sure to check that we're not disconnected if we're out of data to
|
||||
// read, and need to subsequently close.
|
||||
if (m_isPaired && m_pairedFifo.expired()) {
|
||||
close();
|
||||
throw FifoClosedException("Fifo::read called on closed Fifo");
|
||||
} else {
|
||||
m_condition.wait(m_mutex);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isOpen() && ramt == 0)
|
||||
throw FifoClosedException("Fifo::read called on closed Fifo");
|
||||
|
||||
return ramt;
|
||||
}
|
||||
|
||||
size_t Fifo::write(char const* data, size_t len) {
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
if (m_isPaired) {
|
||||
if (auto paired = m_pairedFifo.lock()) {
|
||||
return paired->doWrite(data, len);
|
||||
} else {
|
||||
close();
|
||||
throw FifoClosedException("Fifo::write called on closed Fifo");
|
||||
}
|
||||
} else {
|
||||
return doWrite(data, len);
|
||||
}
|
||||
}
|
||||
|
||||
String Fifo::deviceName() const {
|
||||
return strf("Fifo <%s>", this);
|
||||
}
|
||||
|
||||
size_t Fifo::doWrite(char const* data, size_t len) {
|
||||
MutexLocker locker(m_mutex);
|
||||
|
||||
size_t wamt = 0;
|
||||
while (isOpen()) {
|
||||
while (!m_writeFull && wamt < len) {
|
||||
m_buffer[m_writePos] = *data;
|
||||
++data;
|
||||
++wamt;
|
||||
m_writePos = (m_writePos + 1) % m_buffer.size();
|
||||
|
||||
m_readEmpty = false;
|
||||
if (m_writePos == m_readPos)
|
||||
m_writeFull = true;
|
||||
}
|
||||
|
||||
// Signal any waiting reads.
|
||||
m_condition.signal();
|
||||
|
||||
// If we are blocking, and haven't written all we need, wait for readers.
|
||||
if (m_blocking && wamt < len)
|
||||
m_condition.wait(m_mutex);
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (!isOpen() && wamt == 0)
|
||||
throw FifoClosedException("Fifo::write called on closed Fifo");
|
||||
|
||||
return wamt;
|
||||
}
|
||||
|
||||
void Fifo::disconnect() {
|
||||
if (auto paired = m_pairedFifo.lock()) {
|
||||
MutexLocker locker(m_mutex);
|
||||
m_pairedFifo.reset();
|
||||
paired->disconnect();
|
||||
// Wake up all readers / writers so they can fail.
|
||||
m_condition.signal();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
60
attic/unneeded/StarFifo.hpp
Normal file
60
attic/unneeded/StarFifo.hpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#ifndef STAR_FIFO_HPP
|
||||
#define STAR_FIFO_HPP
|
||||
|
||||
#include "StarIODevice.hpp"
|
||||
#include "StarThread.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
STAR_EXCEPTION(FifoClosedException, DeviceClosedException);
|
||||
|
||||
STAR_CLASS(Fifo);
|
||||
|
||||
// First in first out IODevice. Bytes written to the device can be read from
|
||||
// it first byte in, first byte out. If it set to blocking, then reads that
|
||||
// read past the end of the available bytes -- or writes that go over the
|
||||
// available buffer size -- will block until write is called, or the device is
|
||||
// closed.
|
||||
//
|
||||
// A paired set of Fifos work just like a single Fifo, except each Fifo writes
|
||||
// to the other and reads from the other.
|
||||
class Fifo : public IODevice {
|
||||
public:
|
||||
// If either one of the paired Fifo objects is destroyed, the other one will
|
||||
// immediately be marked as closed.
|
||||
static pair<FifoPtr, FifoPtr> makePair(bool blocking = false, size_t bufferSize = 1024);
|
||||
|
||||
Fifo(bool blocking = false, size_t bufferSize = 1024);
|
||||
|
||||
// If this is a paired fifo, then this will close both sides.
|
||||
void close() override;
|
||||
|
||||
size_t read(char* data, size_t len) override;
|
||||
size_t write(char const* data, size_t len) override;
|
||||
|
||||
String deviceName() const override;
|
||||
|
||||
private:
|
||||
size_t doWrite(char const* data, size_t len);
|
||||
|
||||
// Disconnects the other side of a paired fifo.
|
||||
void disconnect();
|
||||
|
||||
Mutex m_mutex;
|
||||
ConditionVariable m_condition;
|
||||
|
||||
ByteArray m_buffer;
|
||||
bool m_blocking;
|
||||
size_t m_readPos;
|
||||
size_t m_writePos;
|
||||
|
||||
bool m_writeFull;
|
||||
bool m_readEmpty;
|
||||
|
||||
bool m_isPaired;
|
||||
weak_ptr<Fifo> m_pairedFifo;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
356
attic/unneeded/StarGuardedPtr.hpp
Normal file
356
attic/unneeded/StarGuardedPtr.hpp
Normal file
|
@ -0,0 +1,356 @@
|
|||
#ifndef STAR_GUARDED_PTR_HPP
|
||||
#define STAR_GUARDED_PTR_HPP
|
||||
|
||||
#include "StarException.hpp"
|
||||
#include "StarCasting.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
STAR_EXCEPTION(GuardedPtrInvalidAccess, StarException);
|
||||
STAR_EXCEPTION(BadGuardedPtrCast, StarException);
|
||||
|
||||
// Simple guarded pointer class that, when the object that it points to is
|
||||
// destructed, automatically sets itself to invalid. Similar to
|
||||
// enable_shared_from_this, with the benefit of not requiring that the class be
|
||||
// managed by a shared_ptr. Accessing the guarded pointer is thread safe, with
|
||||
// one huge caveat: Because this model of guarded pointers relies on putting
|
||||
// no restrictions on object destruction, there is no thread safe way of
|
||||
// *locking* the pointer from destruction. The pattern of if (guardedPtr) {
|
||||
// guardedPtr->doThings(); } is inherently unsafe in a context where the
|
||||
// original object that guardedPtr points to could be deconstructed at any
|
||||
// time. If you need thread safety from destruction, then the only viable way
|
||||
// to do this is enable_shared_from_this and weak_ptr.
|
||||
template<typename T>
|
||||
class GuardedPtr {
|
||||
public:
|
||||
typedef typename std::decay<T>::type Type;
|
||||
typedef Type* PtrType;
|
||||
typedef Type& RefType;
|
||||
|
||||
GuardedPtr();
|
||||
GuardedPtr(PtrType ptr, shared_ptr<atomic<bool>> sharedValid);
|
||||
|
||||
template<typename Other>
|
||||
GuardedPtr(GuardedPtr<Other> const& other);
|
||||
template<typename Other>
|
||||
GuardedPtr(GuardedPtr<Other>&& other);
|
||||
|
||||
template<typename Other>
|
||||
GuardedPtr& operator=(GuardedPtr<Other> const& other);
|
||||
template<typename Other>
|
||||
GuardedPtr& operator=(GuardedPtr<Other>&& other);
|
||||
|
||||
bool valid() const;
|
||||
explicit operator bool() const;
|
||||
|
||||
PtrType get() const;
|
||||
|
||||
template<typename T2>
|
||||
GuardedPtr<T2> as() const;
|
||||
|
||||
template<typename T2>
|
||||
GuardedPtr<T2> convert() const;
|
||||
|
||||
void reset();
|
||||
|
||||
PtrType operator->() const;
|
||||
RefType operator*() const;
|
||||
|
||||
bool operator==(GuardedPtr const& ptr) const;
|
||||
bool operator!=(GuardedPtr const& ptr) const;
|
||||
|
||||
bool operator==(PtrType ptr) const;
|
||||
bool operator!=(PtrType ptr) const;
|
||||
|
||||
private:
|
||||
template<typename Other>
|
||||
friend class GuardedPtr;
|
||||
|
||||
PtrType m_ptr;
|
||||
shared_ptr<atomic<bool>> m_sharedValid;
|
||||
};
|
||||
|
||||
// Holds a pointer and enables construction of GuardedPtr versions of that
|
||||
// pointer. If constructed with autoDelete, then the pointer will be
|
||||
// automatically deleted on destruction.
|
||||
template<typename T>
|
||||
class GuardedHolder {
|
||||
public:
|
||||
typedef typename std::decay<T>::type Type;
|
||||
typedef Type* PtrType;
|
||||
|
||||
GuardedHolder();
|
||||
GuardedHolder(PtrType ptr, bool autoDelete);
|
||||
~GuardedHolder();
|
||||
|
||||
GuardedHolder(GuardedHolder const& rhs) = delete;
|
||||
GuardedHolder& operator=(GuardedHolder const& rhs) = delete;
|
||||
|
||||
GuardedHolder(GuardedHolder&& guardedHolder);
|
||||
GuardedHolder& operator=(GuardedHolder&& guardedHolder);
|
||||
|
||||
PtrType pointer() const;
|
||||
GuardedPtr<Type> guardedPtr() const;
|
||||
|
||||
// Clears the held pointer and invalidates any GuardedPtrs that reference it.
|
||||
void clear();
|
||||
// Clears the held pointer and invalidates any GuardedPtrs that reference it,
|
||||
// then updates the pointer value to a new value.
|
||||
void reset(PtrType ptr, bool autoDelete);
|
||||
|
||||
private:
|
||||
bool m_autoDelete;
|
||||
PtrType m_ptr;
|
||||
shared_ptr<atomic<bool>> m_sharedValid;
|
||||
};
|
||||
|
||||
// Easy way to automatically support guardedPtrs to this.
|
||||
class GuardedHolderBase {
|
||||
public:
|
||||
GuardedHolderBase();
|
||||
virtual ~GuardedHolderBase();
|
||||
|
||||
// Invalidates all existing GuardedPtrs to this, and resets the this holder
|
||||
// to 'this' again.
|
||||
void invalidateExistingGuardedPointers();
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T> guardedPtr(T& t);
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T const> guardedPtr(T const& t);
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T> guardedPtr(T* t);
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T const> guardedPtr(T const* t);
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T> guardedPtr(shared_ptr<T> t);
|
||||
|
||||
template<typename T>
|
||||
friend GuardedPtr<T const> guardedPtr(shared_ptr<T const> t);
|
||||
|
||||
private:
|
||||
GuardedHolder<GuardedHolderBase> m_thisHolder;
|
||||
};
|
||||
|
||||
template<typename T1, typename T2>
|
||||
GuardedPtr<T1> as(GuardedPtr<T2> const& t);
|
||||
|
||||
template<typename T1, typename T2>
|
||||
GuardedPtr<T1 const> as(GuardedPtr<T2 const> const& t);
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T>::GuardedPtr()
|
||||
: m_ptr(nullptr) {}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T>::GuardedPtr(PtrType ptr, shared_ptr<atomic<bool>> sharedValid)
|
||||
: m_ptr(move(ptr)), m_sharedValid(move(sharedValid)) {}
|
||||
|
||||
template<typename T>
|
||||
template<typename Other>
|
||||
GuardedPtr<T>::GuardedPtr(GuardedPtr<Other> const& other) {
|
||||
m_ptr = other.m_ptr;
|
||||
m_sharedValid = other.m_sharedValid;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Other>
|
||||
GuardedPtr<T>::GuardedPtr(GuardedPtr<Other>&& other) {
|
||||
m_ptr = other.m_ptr;
|
||||
m_sharedValid = move(other.m_sharedValid);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Other>
|
||||
GuardedPtr<T>& GuardedPtr<T>::operator=(GuardedPtr<Other> const& other) {
|
||||
m_ptr = other.m_ptr;
|
||||
m_sharedValid = other.m_sharedValid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename Other>
|
||||
GuardedPtr<T>& GuardedPtr<T>::operator=(GuardedPtr<Other>&& other) {
|
||||
m_ptr = other.m_ptr;
|
||||
m_sharedValid = move(other.m_sharedValid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GuardedPtr<T>::valid() const {
|
||||
return m_sharedValid && *m_sharedValid;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T>::operator bool() const {
|
||||
return valid();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GuardedPtr<T>::get() const -> PtrType {
|
||||
if (valid())
|
||||
return m_ptr;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
GuardedPtr<T2> GuardedPtr<T>::convert() const {
|
||||
if (auto p = as<T2>())
|
||||
return p;
|
||||
|
||||
throw BadGuardedPtrCast();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T2>
|
||||
GuardedPtr<T2> GuardedPtr<T>::as() const {
|
||||
if (valid()) {
|
||||
if (auto p = Star::as<T2>(m_ptr))
|
||||
return GuardedPtr<T2>(p, m_sharedValid);
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void GuardedPtr<T>::reset() {
|
||||
m_sharedValid.reset();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GuardedPtr<T>::operator->() const -> PtrType {
|
||||
if (auto p = get())
|
||||
return p;
|
||||
else
|
||||
throw GuardedPtrInvalidAccess("Invalid access to invalid GuardedPtr");
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GuardedPtr<T>::operator*() const -> RefType {
|
||||
return *operator->();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GuardedPtr<T>::operator==(GuardedPtr const& ptr) const {
|
||||
return get() == ptr.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GuardedPtr<T>::operator!=(GuardedPtr const& ptr) const {
|
||||
return get() != ptr.get();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GuardedPtr<T>::operator==(PtrType ptr) const {
|
||||
return get() == ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool GuardedPtr<T>::operator!=(PtrType ptr) const {
|
||||
return get() != ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedHolder<T>::GuardedHolder(PtrType ptr, bool autoDelete)
|
||||
: m_autoDelete(false), m_ptr(nullptr) {
|
||||
reset(ptr, autoDelete);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedHolder<T>::~GuardedHolder() {
|
||||
clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedHolder<T>::GuardedHolder(GuardedHolder&& guardedHolder) {
|
||||
operator=(move(guardedHolder));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedHolder<T>& GuardedHolder<T>::operator=(GuardedHolder&& guardedHolder) {
|
||||
clear();
|
||||
m_autoDelete = move(guardedHolder.m_autoDelete);
|
||||
m_ptr = move(guardedHolder.m_ptr);
|
||||
m_sharedValid = move(guardedHolder.m_sharedValid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GuardedHolder<T>::pointer() const -> PtrType {
|
||||
return m_ptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
auto GuardedHolder<T>::guardedPtr() const -> GuardedPtr<Type> {
|
||||
return GuardedPtr<T>(m_ptr, m_sharedValid);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void GuardedHolder<T>::clear() {
|
||||
reset(nullptr, false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void GuardedHolder<T>::reset(PtrType ptr, bool autoDelete) {
|
||||
if (m_autoDelete && m_ptr)
|
||||
delete m_ptr;
|
||||
|
||||
if (m_sharedValid) {
|
||||
*m_sharedValid = false;
|
||||
m_sharedValid.reset();
|
||||
}
|
||||
|
||||
m_autoDelete = autoDelete;
|
||||
m_ptr = ptr;
|
||||
if (m_ptr)
|
||||
m_sharedValid = make_shared<atomic<bool>>(true);
|
||||
}
|
||||
|
||||
inline GuardedHolderBase::GuardedHolderBase()
|
||||
: m_thisHolder(this, false) {}
|
||||
|
||||
inline GuardedHolderBase::~GuardedHolderBase() {}
|
||||
|
||||
inline void GuardedHolderBase::invalidateExistingGuardedPointers() {
|
||||
m_thisHolder.reset(this, false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T> guardedPtr(T& t) {
|
||||
return t.m_thisHolder.guardedPtr().template convert<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T const> guardedPtr(T const& t) {
|
||||
return t.m_thisHolder.guardedPtr().template convert<T const>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T> guardedPtr(T* t) {
|
||||
return t->m_thisHolder.guardedPtr().template convert<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T const> guardedPtr(T const* t) {
|
||||
return t->m_thisHolder.guardedPtr().template convert<T const>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T> guardedPtr(shared_ptr<T> t) {
|
||||
return t->m_thisHolder.guardedPtr().template convert<T>();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
GuardedPtr<T const> guardedPtr(shared_ptr<T const> t) {
|
||||
return t->m_thisHolder.guardedPtr().template convert<T const>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
338
attic/unneeded/StarMatrix4.hpp
Normal file
338
attic/unneeded/StarMatrix4.hpp
Normal file
|
@ -0,0 +1,338 @@
|
|||
#ifndef STAR_MATRIX4_HPP
|
||||
#define STAR_MATRIX4_HPP
|
||||
|
||||
#include "StarMatrix3.hpp"
|
||||
#include "StarVector4.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
template<typename T1> class Matrix4 {
|
||||
public:
|
||||
static Matrix4<T1> identity();
|
||||
|
||||
static Matrix4<T1> rotAroundPoint(Matrix3<T1> rot, Vector3<T1> point);
|
||||
static Matrix4<T1> frustrum(T1 l, T1 r, T1 b, T1 t, T1 n, T1 f);
|
||||
static Matrix4<T1> frustrumInv(T1 l, T1 r, T1 b, T1 t, T1 n, T1 f);
|
||||
|
||||
public:
|
||||
typedef Vector4<T1> RowT;
|
||||
RowT r1, r2, r3, r4;
|
||||
|
||||
Matrix4();
|
||||
Matrix4(T1 r1c1, T1 r1c2, T1 r1c3, T1 r1c4,
|
||||
T1 r2c1, T1 r2c2, T1 r2c3, T1 r2c4,
|
||||
T1 r3c1, T1 r3c2, T1 r3c3, T1 r3c4,
|
||||
T1 r4c1, T1 r4c2, T1 r4c3, T1 r4c4 );
|
||||
Matrix4(RowT const& r1, RowT const& r2,
|
||||
RowT const& r3, RowT const& r4);
|
||||
|
||||
template<typename T2> Matrix4(Matrix4<T2> const& m);
|
||||
template<typename T2> explicit Matrix4(Matrix3<T2> const& m);
|
||||
|
||||
Matrix3<T1> mat3() const;
|
||||
|
||||
T1* ptr();
|
||||
T1 const* ptr() const;
|
||||
|
||||
// Copy to an existing array
|
||||
void copy(T1 *loc) const;
|
||||
|
||||
Vector4<T1>& operator[](size_t const i);
|
||||
Vector4<T1> const& operator[](size_t const i) const;
|
||||
|
||||
Vector4<T1> const& row(size_t r) const;
|
||||
template<typename T2>
|
||||
void setRow(unsigned int i, Vector4<T2> const& v);
|
||||
|
||||
Vector4<T1> col(size_t c) const;
|
||||
template<typename T2>
|
||||
void setCol(unsigned int i, Vector4<T2> const& v);
|
||||
|
||||
template<typename T2> Matrix4& operator+=(Matrix4<T2> const& m);
|
||||
template<typename T2> Matrix4& operator-=(Matrix4<T2> const& m);
|
||||
|
||||
T1 det();
|
||||
Matrix4& transpose();
|
||||
Matrix4& opengl();
|
||||
Matrix4& inverse();
|
||||
Vector4<T1> trace() const;
|
||||
|
||||
Matrix4& operator*=(T1 const& s);
|
||||
Matrix4& operator/=(T1 const& s);
|
||||
Matrix4 operator*(T1 const& s);
|
||||
Matrix4 operator/(T1 const& s);
|
||||
|
||||
template<typename T2>
|
||||
Matrix4 operator+(Matrix4<T2> const& m2) const;
|
||||
template<typename T2>
|
||||
Matrix4 operator-(Matrix4<T2> const& m2) const;
|
||||
template<typename T2>
|
||||
Matrix4 operator*(Matrix4<T2> const& m2) const;
|
||||
|
||||
template<typename T2>
|
||||
Vector4<T1> operator*(Vector4<T2> const& v) const;
|
||||
};
|
||||
|
||||
typedef Matrix4<float> Mat4F;
|
||||
typedef Matrix4<double> Mat4D;
|
||||
|
||||
template<typename T>
|
||||
std::ostream& operator<<(std::ostream &os, Matrix4<T> mat) {
|
||||
os << mat[0] << std::endl;
|
||||
os << mat[1] << std::endl;
|
||||
os << mat[2] << std::endl;
|
||||
os << mat[3];
|
||||
return os;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Matrix4<T1> Matrix4<T1>::identity() {
|
||||
return Matrix4(1, 0, 0, 0,
|
||||
0, 1, 0, 0,
|
||||
0, 0, 1, 0,
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Vector4<T1> Matrix4<T1>::trace() const {
|
||||
return Vector4<T1>(r1[0], r2[1], r3[2], r4[3]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline Matrix4<T>::Matrix4() {}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>::Matrix4(
|
||||
T r1c1, T r1c2, T r1c3, T r1c4,
|
||||
T r2c1, T r2c2, T r2c3, T r2c4,
|
||||
T r3c1, T r3c2, T r3c3, T r3c4,
|
||||
T r4c1, T r4c2, T r4c3, T r4c4 ) {
|
||||
r1 = Vector4<T>(r1c1, r1c2, r1c3, r1c4);
|
||||
r2 = Vector4<T>(r2c1, r2c2, r2c3, r2c4);
|
||||
r3 = Vector4<T>(r3c1, r3c2, r3c3, r3c4);
|
||||
r4 = Vector4<T>(r4c1, r4c2, r4c3, r4c4);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>::Matrix4(const RowT& pr1, const RowT& pr2,
|
||||
const RowT& pr3, const RowT& pr4) {
|
||||
r1 = pr1;
|
||||
r2 = pr2;
|
||||
r3 = pr3;
|
||||
r4 = pr4;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Vector4<T1>& Matrix4<T1>::operator[](const size_t i) {
|
||||
return *(&r1 + i);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
const Vector4<T1>& Matrix4<T1>::operator[](const size_t i) const {
|
||||
return *(&r1 + i);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
T1* Matrix4<T1>::ptr() {
|
||||
return &r1[0];
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
const T1* Matrix4<T1>::ptr() const {
|
||||
return &r1[0];
|
||||
}
|
||||
|
||||
|
||||
template<typename T1>
|
||||
void Matrix4<T1>::copy(T1* loc) const {
|
||||
r1.copy(loc);
|
||||
r2.copy(loc + 4);
|
||||
r3.copy(loc + 8);
|
||||
r4.copy(loc + 12);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
template<typename T2> Matrix4<T1>::Matrix4(const Matrix3<T2> &m) {
|
||||
r1 = Vector4<T1>(m[0], 0);
|
||||
r2 = Vector4<T1>(m[1], 0);
|
||||
r3 = Vector4<T1>(m[2], 0);
|
||||
r4 = Vector4<T1>(T1(0), T1(0), T1(0), T1(1));
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Matrix3<T1> Matrix4<T1>::mat3() const {
|
||||
return Matrix3<T1>(r1, r2, r3);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
const Vector4<T1>& Matrix4<T1>::row(size_t i) const {
|
||||
return operator[](i);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Vector4<T1> Matrix4<T1>::col(size_t c) const {
|
||||
return Vector4<T1>(r1[c], r2[c], r3[c], r4[c]);
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
void Matrix4<T1>::setRow(unsigned int c, const Vector4<T2> &r) {
|
||||
operator[](c) = r;
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
void Matrix4<T1>::setCol(unsigned int c, const Vector4<T2> &v) {
|
||||
r1[c] = v[0];
|
||||
r2[c] = v[1];
|
||||
r3[c] = v[2];
|
||||
r4[c] = v[3];
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Matrix4<T1>::Matrix4(const Matrix4<T2> &m) {
|
||||
r1 = m[0];
|
||||
r2 = m[1];
|
||||
r3 = m[2];
|
||||
r4 = m[3];
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Matrix4<T1>& Matrix4<T1>::operator+=(const Matrix4<T2> &m) {
|
||||
r1 += m[0];
|
||||
r2 += m[1];
|
||||
r3 += m[2];
|
||||
r4 += m[3];
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Matrix4<T1>& Matrix4<T1>::operator-=(const Matrix4<T2> &m) {
|
||||
r1 -= m[0];
|
||||
r2 -= m[1];
|
||||
r3 -= m[2];
|
||||
r4 -= m[3];
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>& Matrix4<T>::transpose() {
|
||||
return operator=(Matrix4( r1[0], r2[0], r3[0], r4[0],
|
||||
r1[1], r2[1], r3[1], r4[1],
|
||||
r1[2], r2[2], r3[2], r4[2],
|
||||
r1[3], r2[3], r3[3], r4[3]));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>& Matrix4<T>::opengl() {
|
||||
return transpose();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>& Matrix4<T>::operator*=(const T &s) {
|
||||
r1 *= s;
|
||||
r2 *= s;
|
||||
r3 *= s;
|
||||
r4 *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T>& Matrix4<T>::operator/=(const T &s) {
|
||||
r1 /= s;
|
||||
r2 /= s;
|
||||
r3 /= s;
|
||||
r4 /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <typename T1> template<typename T2>
|
||||
Matrix4<T1> Matrix4<T1>::operator+(const Matrix4<T2> &m2) const {
|
||||
return Matrix4<T1>( r1 + m2[0],
|
||||
r2 + m2[1],
|
||||
r3 + m2[2],
|
||||
r4 + m2[3]);
|
||||
}
|
||||
|
||||
template <typename T1> template<typename T2>
|
||||
Matrix4<T1> Matrix4<T1>::operator-(const Matrix4<T2> &m2) const {
|
||||
return Matrix4<T1>( r1 - m2[0],
|
||||
r2 - m2[1],
|
||||
r3 - m2[2],
|
||||
r4 - m2[3]);
|
||||
}
|
||||
|
||||
|
||||
template <typename T1> template<typename T2>
|
||||
Matrix4<T1> Matrix4<T1>::operator*(const Matrix4<T2> &m2) const {
|
||||
return Matrix4<T1>(
|
||||
row(0)*m2.col(0), row(0)*m2.col(1),
|
||||
row(0)*m2.col(2), row(0)*m2.col(3),
|
||||
row(1)*m2.col(0), row(1)*m2.col(1),
|
||||
row(1)*m2.col(2), row(1)*m2.col(3),
|
||||
row(2)*m2.col(0), row(2)*m2.col(1),
|
||||
row(2)*m2.col(2), row(2)*m2.col(3),
|
||||
row(3)*m2.col(0), row(3)*m2.col(1),
|
||||
row(3)*m2.col(2), row(3)*m2.col(3));
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Matrix4<T1> Matrix4<T1>::operator*(const T1 &s) {
|
||||
return Matrix4(r1*s, r2*s, r3*s, r4*s);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Matrix4<T1> Matrix4<T1>::operator/(const T1 &s) {
|
||||
return Matrix4<T1>(r1/s, r2/s, r3/s, r4/s);
|
||||
}
|
||||
|
||||
template <typename T1> template<typename T2>
|
||||
Vector4<T1> Matrix4<T1>::operator*(const Vector4<T2>& v) const {
|
||||
return Vector4<T1>(r1*v, r2*v, r3*v, r4*v);
|
||||
}
|
||||
|
||||
template <typename T1>
|
||||
Matrix4<T1> Matrix4<T1>::rotAroundPoint(Matrix3<T1> rot,
|
||||
Vector3<T1> point) {
|
||||
Matrix4<T1> final(rot);
|
||||
final[0][3] =
|
||||
rot[0][0]*point[0] + rot[0][1]*point[1] + rot[0][0]*point[2]-point[0];
|
||||
final[1][3] =
|
||||
rot[1][0]*point[0] + rot[1][1]*point[1] + rot[1][2]*point[2]-point[1];
|
||||
final[2][3] =
|
||||
rot[2][0]*point[0] + rot[2][1]*point[1] + rot[2][2]*point[2]-point[2];
|
||||
return final;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T> Matrix4<T>::frustrumInv(T l, T r, T b, T t, T n, T f) {
|
||||
return Matrix4<T>(
|
||||
(r-l)/(2*n), 0, 0, (r+l)/(2*n),
|
||||
0, (t-b)/(2*n), 0, (t+b)/(2*n),
|
||||
0, 0, 0, -1,
|
||||
0, 0, -(f-n)/(2*f*n), (f+n)/(2*f*n));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T> Matrix4<T>::frustrum(T l, T r, T b, T t, T n, T f) {
|
||||
return Matrix4<T>(
|
||||
2*n/(r-l), 0, 0, (r+l)/(r-l),
|
||||
0, 2/(t-b), 0, (t+b)/(t-b),
|
||||
0, 0, -2/(f-n), (f+n)/(f-n),
|
||||
0, 0, 0, 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T> transpose(Matrix4<T> m) {
|
||||
return m.transpose();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T> opengl(Matrix4<T> m) {
|
||||
return m.opengl();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix4<T> operator*(const T &s, const Matrix4<T> &m) {
|
||||
return m * s;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
1054
attic/unneeded/StarMultiArrayInterpolator.hpp
Normal file
1054
attic/unneeded/StarMultiArrayInterpolator.hpp
Normal file
File diff suppressed because it is too large
Load diff
216
attic/unneeded/StarNoiseField.hpp
Normal file
216
attic/unneeded/StarNoiseField.hpp
Normal file
|
@ -0,0 +1,216 @@
|
|||
#ifndef STAR_NOISE_FIELD_HPP
|
||||
#define STAR_NOISE_FIELD_HPP
|
||||
|
||||
#include "StarMultiArrayInterpolator.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
// Noise field with configurable number of layers of randomness. Each layer of
|
||||
// randomness is <alpha> times as dense as the last layer, as well as 1.0 /
|
||||
// <beta> the magnitude of the last layer. If <alpha> and <beta> are 2.0
|
||||
// (typical), and there are 4 layers, the perlin field would be constructed as
|
||||
// follows:
|
||||
// - The bottom layer would be 1x1, with magnitude 1 / 8
|
||||
// - Next layer is 2x2 with magnitude 1 / 4
|
||||
// - Next layer 4x4 with magnitude 1 / 2
|
||||
// - Top layer 8x8 with magnitude 1.
|
||||
//
|
||||
// Note: Cubic interpolation mode *can* produce values just outside the range [0.0, 1.0] when normalized.
|
||||
template<typename DataT, typename IndexT, typename ScaleT, size_t RankT, typename NoiseSource>
|
||||
class NoiseField {
|
||||
public:
|
||||
typedef DataT Data;
|
||||
static size_t const Rank = RankT;
|
||||
|
||||
typedef IndexT IndexType;
|
||||
typedef Array<IndexType, Rank> Index;
|
||||
|
||||
typedef ScaleT ScaleType;
|
||||
typedef Array<ScaleType, Rank> Scale;
|
||||
|
||||
typedef Star::MultiArray<Data, Rank> MultiArray;
|
||||
typedef typename MultiArray::SizeList Size;
|
||||
|
||||
enum InterpolationMode {
|
||||
Linear,
|
||||
Smooth,
|
||||
Cubic
|
||||
};
|
||||
|
||||
NoiseField(InterpolationMode interpolation, size_t minLayer, size_t layers,
|
||||
ScaleType alpha = 2.0, ScaleType beta = 2.0, NoiseSource const& noise = NoiseSource())
|
||||
|
||||
: m_minLayer(minLayer), m_noiseSource(noise), m_interpolation(interpolation),
|
||||
m_normalize(true), m_max(ScaleType()) {
|
||||
|
||||
m_layers.resize(layers);
|
||||
for (size_t i = 0; i < layers; ++i) {
|
||||
m_layers[i].indexScale = 1 / pow(alpha, i);
|
||||
m_layers[i].valueScale = 1 / pow(beta, layers - i - 1);
|
||||
m_max += m_layers[i].valueScale;
|
||||
}
|
||||
}
|
||||
|
||||
// The maximum scale for any point in the field is sum(1 / s^x, x, 0, n),
|
||||
// where s is the layer scale and n is the number of layers.
|
||||
// This scale is the maximum amount that a generated value will be relative
|
||||
// to the values generated by the noise source.
|
||||
//
|
||||
// If normalized is set to true, then all values genrated will be divided by
|
||||
// this scale, so the range of values generated by this field will always be
|
||||
// the same as the range generated by the noise source.
|
||||
ScaleType maxScale() const {
|
||||
return m_max;
|
||||
}
|
||||
|
||||
InterpolationMode interpolationMode() const {
|
||||
return m_interpolation;
|
||||
}
|
||||
|
||||
void setInterpolationMode(InterpolationMode interpolation) const {
|
||||
m_interpolation = interpolation;
|
||||
}
|
||||
|
||||
bool isNormalized() const {
|
||||
return m_normalize;
|
||||
}
|
||||
|
||||
void setNormalize(bool normalize) {
|
||||
m_normalize = normalize;
|
||||
}
|
||||
|
||||
MultiArray generate(Index const& min, Size const& size) {
|
||||
MultiArray array(size);
|
||||
generate(min, array);
|
||||
return array;
|
||||
}
|
||||
|
||||
void generate(Index const& min, MultiArray& array) {
|
||||
Size size = array.size();
|
||||
|
||||
for (size_t i = m_minLayer; i < m_layers.size(); ++i) {
|
||||
ScaleType indexScale = m_layers[i].indexScale;
|
||||
ScaleType valueScale = m_layers[i].valueScale;
|
||||
|
||||
if (m_normalize)
|
||||
valueScale = valueScale / m_max;
|
||||
|
||||
// Bottom layer is always 1x1, so we can skip the resampling step.
|
||||
if (i == 0) {
|
||||
array.eval(NoiseGenerator(m_noiseSource, i, valueScale, min));
|
||||
} else {
|
||||
// This layer's min and max index in field space, and the total size of
|
||||
// this layer.
|
||||
Index layerMinIndex;
|
||||
Index layerMaxIndex;
|
||||
Size layerSize;
|
||||
|
||||
// Sampling offset of layerMin / layerMax
|
||||
Scale sampleMin;
|
||||
Scale sampleMax;
|
||||
|
||||
for (size_t j = 0; j < Rank; ++j) {
|
||||
ScaleType lmin = min[j] * indexScale;
|
||||
ScaleType lmax = (min[j] + size[j] - 1) * indexScale;
|
||||
|
||||
if (m_interpolation == Cubic) {
|
||||
layerMinIndex[j] = IndexType(floor(lmin) - 1);
|
||||
layerMaxIndex[j] = IndexType(ceil(lmax) + 1);
|
||||
} else {
|
||||
layerMinIndex[j] = IndexType(floor(lmin));
|
||||
layerMaxIndex[j] = IndexType(ceil(lmax));
|
||||
}
|
||||
|
||||
layerSize[j] = size_t(layerMaxIndex[j] - layerMinIndex[j]) + 1;
|
||||
sampleMin[j] = lmin - layerMinIndex[j];
|
||||
sampleMax[j] = lmax - layerMinIndex[j];
|
||||
}
|
||||
|
||||
MultiArray layer(layerSize);
|
||||
layer.eval(NoiseGenerator(m_noiseSource, i, valueScale, layerMinIndex));
|
||||
|
||||
//TODO: this code isn't even compiled, is it.
|
||||
starAssert(m_interpolation != Smooth);
|
||||
if (m_interpolation == Cubic) {
|
||||
auto interpolator = MultiArrayInterpolator4<MultiArray, ScaleType>(CubicWeightOperator<ScaleType>());
|
||||
interpolator.sample(layer, array, sampleMin, sampleMax);
|
||||
// } else if (m_interpolation == Smooth) {
|
||||
// auto interpolator = MultiArrayInterpolator2<MultiArray, ScaleType>(SmoothWeightOperator<ScaleType>());
|
||||
// interpolator.sample(layer, array, sampleMin, sampleMax);
|
||||
} else {
|
||||
auto interpolator = MultiArrayInterpolator2<MultiArray, ScaleType>(LinearWeightOperator<ScaleType>());
|
||||
interpolator.sample(layer, array, sampleMin, sampleMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
struct NoiseGenerator {
|
||||
NoiseGenerator(NoiseSource& ns, size_t l, ScaleType sc, Index const& mn)
|
||||
: noiseSource(ns), layer(l), scale(sc), min(mn) {}
|
||||
|
||||
inline Data operator()(typename MultiArray::IndexList& index) {
|
||||
Index loc = min;
|
||||
std::transform(min.begin(), min.end(), index.begin(), loc.begin(), std::plus<IndexType>());
|
||||
return scale * noiseSource(layer, loc);
|
||||
}
|
||||
|
||||
NoiseSource noiseSource;
|
||||
size_t layer;
|
||||
ScaleType scale;
|
||||
Index min;
|
||||
};
|
||||
|
||||
struct Layer {
|
||||
ScaleType indexScale;
|
||||
ScaleType valueScale;
|
||||
};
|
||||
|
||||
std::vector<Layer> m_layers;
|
||||
size_t m_minLayer;
|
||||
NoiseSource m_noiseSource;
|
||||
InterpolationMode m_interpolation;
|
||||
bool m_normalize;
|
||||
Data m_max;
|
||||
};
|
||||
|
||||
// Generates values in range [0.0, 1.0]
|
||||
struct DoubleNoiseFieldSource {
|
||||
DoubleNoiseFieldSource(int64_t s) : seed(s) {}
|
||||
|
||||
template<typename Index>
|
||||
inline double operator()(size_t layer, Index const& index) const {
|
||||
int64_t x = layer;
|
||||
for (size_t i = 0; i < Index::Size; ++i)
|
||||
x = x * 38577907 + index[i];
|
||||
|
||||
x = (x<<27) ^ x;
|
||||
x *= seed;
|
||||
return ((x * (x * x * 5736215731 + 23453458789221) + 1997293021376312589) & 0x7fffffffffffffff) / 9223372036854775808.0;
|
||||
}
|
||||
|
||||
int64_t seed;
|
||||
};
|
||||
|
||||
// Generates values in range [0.0, 1.0]
|
||||
struct FloatNoiseFieldSource {
|
||||
FloatNoiseFieldSource(int64_t s) : seed(s) {}
|
||||
|
||||
template<typename Index>
|
||||
inline float operator()(size_t layer, Index const& index) const {
|
||||
int64_t x = layer;
|
||||
for (size_t i = 0; i < Index::Size; ++i)
|
||||
x = x * 38577907 + index[i];
|
||||
|
||||
x = (x<<13) ^ x;
|
||||
x *= seed;
|
||||
return ((x * (x * x * 15731 + 789221) + 1376312589) & 0x7fffffff) / 2147483648.0;
|
||||
}
|
||||
|
||||
int64_t seed;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
120
attic/unneeded/StarPromise.hpp
Normal file
120
attic/unneeded/StarPromise.hpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#ifndef STAR_PROMISE_HPP
|
||||
#define STAR_PROMISE_HPP
|
||||
|
||||
#include "StarAtomicSharedPtr.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
STAR_EXCEPTION(PromiseException, StarException);
|
||||
|
||||
// Wraps a ThreadInvoker, and can hold the value for consumption by more than
|
||||
// one thread, and is sharable. The return value is not taken on get(), and
|
||||
// access to the value via get() by multiple threads is safe.
|
||||
template<typename Result>
|
||||
class Promise {
|
||||
public:
|
||||
Promise();
|
||||
Promise(ThreadInvoker<Result> invoker);
|
||||
Promise(Result result);
|
||||
|
||||
bool valid() const;
|
||||
operator bool() const;
|
||||
|
||||
bool fulfilled() const;
|
||||
|
||||
Maybe<Result const&> maybe() const;
|
||||
Maybe<Result&> maybe();
|
||||
|
||||
Result const& get() const;
|
||||
Result& get();
|
||||
|
||||
private:
|
||||
void checkValid();
|
||||
|
||||
struct Data {
|
||||
mutable Mutex mutex;
|
||||
Maybe<ThreadInvoker<Result>> invoker;
|
||||
Maybe<Result> result;
|
||||
};
|
||||
|
||||
AtomicSharedPtr<Data> m_data;
|
||||
};
|
||||
|
||||
template<typename Result>
|
||||
Promise<Result>::Promise() {}
|
||||
|
||||
template<typename Result>
|
||||
Promise<Result>::Promise(ThreadInvoker<Result> invoker) {
|
||||
m_data = make_shared<Data>(Data{{}, move(invoker), {}});
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Promise<Result>::Promise(Result result) {
|
||||
m_data = make_shared<Data>(Data{{}, {}, move(result)});
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
bool Promise<Result>::valid() const {
|
||||
return m_data.valid();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Promise<Result>::operator bool() const {
|
||||
return (bool)m_data;
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
bool Promise<Result>::fulfilled() const {
|
||||
if (!m_data)
|
||||
return false;
|
||||
MutexLocker locker(m_data->mutex);
|
||||
return m_data->result.isValid();
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Maybe<Result const&> Promise<Result>::maybe() const {
|
||||
if (!m_data)
|
||||
return {};
|
||||
MutexLocker locker(m_data->mutex);
|
||||
return *m_data->result;
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Maybe<Result&> Promise<Result>::maybe() {
|
||||
if (!m_data)
|
||||
return {};
|
||||
MutexLocker locker(m_data->mutex);
|
||||
return *m_data->result;
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result const& Promise<Result>::get() const {
|
||||
checkValid();
|
||||
MutexLocker locker(m_data->mutex);
|
||||
if (m_data->invoker) {
|
||||
m_data->result = m_data->invoker->finish();
|
||||
m_data->invoker.reset();
|
||||
}
|
||||
return *m_data->result;
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
Result& Promise<Result>::get() {
|
||||
checkValid();
|
||||
MutexLocker locker(m_data->mutex);
|
||||
if (m_data->invoker) {
|
||||
m_data->result = m_data->invoker->finish();
|
||||
m_data->invoker.reset();
|
||||
}
|
||||
return *m_data->result;
|
||||
}
|
||||
|
||||
template<typename Result>
|
||||
void Promise<Result>::checkValid() {
|
||||
if (!m_data)
|
||||
throw PromiseException("Unset Promise was accessed");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
448
attic/unneeded/StarQuaternion.hpp
Normal file
448
attic/unneeded/StarQuaternion.hpp
Normal file
|
@ -0,0 +1,448 @@
|
|||
#ifndef STAR_QUATERNION_HPP
|
||||
#define STAR_QUATERNION_HPP
|
||||
|
||||
#include "StarVector3.hpp"
|
||||
#include "StarMatrix3.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
template <typename T1>
|
||||
class Quaternion {
|
||||
public:
|
||||
// Default tolerance is 100 times type epsilon
|
||||
static T1 const Tolerance;
|
||||
|
||||
static Quaternion slerp(Quaternion q, Quaternion r, T1 a);
|
||||
static T1 dot(Quaternion q1, Quaternion q2);
|
||||
|
||||
static Quaternion fromRotMat(Matrix3<T1> mat);
|
||||
static Quaternion fromAxisAngle(Vector3<T1> axis, T1 angle);
|
||||
static Quaternion fromAngVel(Vector3<T1> omega);
|
||||
|
||||
T1 n;
|
||||
Vector3<T1> v;
|
||||
|
||||
Quaternion();
|
||||
Quaternion(T1 w, T1 x, T1 y, T1 z);
|
||||
Quaternion(Vector3<T1> axis, T1 angle);
|
||||
|
||||
T1* ptr();
|
||||
T1 const* ptr() const;
|
||||
|
||||
template<typename T2> Quaternion(Quaternion<T2> const& q);
|
||||
template<typename T2> Quaternion& operator=(Quaternion<T2> const& q);
|
||||
|
||||
template<typename T2>
|
||||
Quaternion& operator+=(Quaternion<T2> q);
|
||||
template<typename T2>
|
||||
Quaternion& operator-=(Quaternion<T2> q);
|
||||
|
||||
Quaternion& operator*=(T1 s);
|
||||
Quaternion& operator/=(T1 s);
|
||||
|
||||
template<typename T2>
|
||||
Quaternion operator+(Quaternion<T2> const& q) const;
|
||||
template<typename T2>
|
||||
Quaternion operator-(Quaternion<T2> const& q) const;
|
||||
|
||||
template<typename T2>
|
||||
Quaternion operator*(Quaternion<T2> const& q) const;
|
||||
template<typename T2>
|
||||
Quaternion operator*(Vector3<T2> const& q) const;
|
||||
|
||||
Quaternion operator*(T1 const s) const;
|
||||
Quaternion operator/(T1 const s) const;
|
||||
|
||||
Quaternion operator~() const;
|
||||
Quaternion operator-() const;
|
||||
T1 magnitude() const;
|
||||
|
||||
Quaternion& normalize();
|
||||
|
||||
Vector3<T1> axis() const;
|
||||
T1 angle() const;
|
||||
|
||||
Matrix3<T1> toRotMat() const;
|
||||
|
||||
Quaternion rotate(Quaternion q2) const;
|
||||
Vector3<T1> rotate(Vector3<T1> v) const;
|
||||
};
|
||||
|
||||
typedef Quaternion<double> QuatD;
|
||||
typedef Quaternion<float> QuatF;
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion() {
|
||||
n = 1;
|
||||
v[0] = 0;
|
||||
v[1] = 0;
|
||||
v[2] = 0;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>::Quaternion(T w, T x, T y, T z) {
|
||||
n = w;
|
||||
v[0] = x;
|
||||
v[1] = y;
|
||||
v[2] = z;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1>::Quaternion(Vector3<T1> axis, T1 angle) {
|
||||
T1 d = axis.magnitude();
|
||||
if (d != 0) {
|
||||
T1 s = sin(0.5*angle) / d;
|
||||
v[0] = (T1) axis[0] * s;
|
||||
v[1] = (T1) axis[1] * s;
|
||||
v[2] = (T1) axis[2] * s;
|
||||
n = cos(0.5*angle);
|
||||
}
|
||||
else {
|
||||
v[0] = v[1] = v[2] = 0;
|
||||
n = 1;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1>::Quaternion(Quaternion<T2> const& q) {
|
||||
n = q.n;
|
||||
v = q.v;
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1>& Quaternion<T1>::operator=(Quaternion<T2> const& q) {
|
||||
n = q.n;
|
||||
v = q.v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Quaternion<T>::magnitude() const {
|
||||
return (T) sqrt(n*n + v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
|
||||
}
|
||||
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1>& Quaternion<T1>::operator+=(Quaternion<T2> q) {
|
||||
n += q.n;
|
||||
v[0] += q.v[0];
|
||||
v[1] += q.v[1];
|
||||
v[2] += q.v[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1>& Quaternion<T1>::operator-=(Quaternion<T2> q) {
|
||||
n -= q.n;
|
||||
v[0] -= q.v[0];
|
||||
v[1] -= q.v[1];
|
||||
v[2] -= q.v[2];
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1>& Quaternion<T1>::operator*=(T1 s) {
|
||||
n *= s;
|
||||
v[0] *= s;
|
||||
v[1] *= s;
|
||||
v[2] *= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> Quaternion<T1>::operator/(T1 s) const {
|
||||
return Quaternion<T1>(n/s, v[0]/s, v[1]/s, v[2]/s);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1>& Quaternion<T1>::operator/=(T1 s) {
|
||||
n /= s;
|
||||
v /= s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> Quaternion<T1>::operator~() const {
|
||||
return Quaternion(n, -v[0], -v[1], -v[2]);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> Quaternion<T1>::operator-() const {
|
||||
return Quaternion(-n, -v[0], -v[1], -v[2]);
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1> Quaternion<T1>::operator+(
|
||||
Quaternion<T2> const& q2) const {
|
||||
return Quaternion<T1>( n + q2.n,
|
||||
v[0] + q2.v[0],
|
||||
v[1] + q2.v[1],
|
||||
v[2] + q2.v[2]);
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1> Quaternion<T1>::operator-(
|
||||
Quaternion<T2> const& q2) const {
|
||||
return Quaternion<T1>( n - q2.n,
|
||||
v[0] - q2.v[0],
|
||||
v[1] - q2.v[1],
|
||||
v[2] - q2.v[2]);
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1> Quaternion<T1>::operator*(
|
||||
Quaternion<T2> const& q2) const {
|
||||
return Quaternion<T1>(
|
||||
n*q2.n - v[0]*q2.v[0] - v[1]*q2.v[1] - v[2]*q2.v[2],
|
||||
n*q2.v[0] + v[0]*q2.n + v[1]*q2.v[2] - v[2]*q2.v[1],
|
||||
n*q2.v[1] + v[1]*q2.n + v[2]*q2.v[0] - v[0]*q2.v[2],
|
||||
n*q2.v[2] + v[2]*q2.n + v[0]*q2.v[1] - v[1]*q2.v[0]);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> Quaternion<T1>::operator*(T1 s) const {
|
||||
return Quaternion<T1>( n * s, v[0] * s,
|
||||
v[1] * s, v[2] * s );
|
||||
}
|
||||
|
||||
template<typename T1> template<typename T2>
|
||||
Quaternion<T1> Quaternion<T1>::operator*(Vector3<T2> const& v2) const {
|
||||
return Quaternion<T1>( -(v[0]*v2[0] + v[1]*v2[1] + v[2]*v2[2]),
|
||||
n*v2[0] + v[1]*v2[2] - v[2]*v2[1],
|
||||
n*v2[1] + v[2]*v2[0] - v[0]*v2[2],
|
||||
n*v2[2] + v[0]*v2[1] - v[1]*v2[0]);
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
T1 Quaternion<T1>::angle() const {
|
||||
return T1(2*acos(n));
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Vector3<T1> Quaternion<T1>::axis() const {
|
||||
T1 m = v.magnitude();
|
||||
|
||||
if (m <= Tolerance)
|
||||
return Vector3<T1();
|
||||
else
|
||||
return v/m;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> Quaternion<T1>::rotate(Quaternion q2) const {
|
||||
return (*this)*q2*(~(*this));
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Vector3<T1> Quaternion<T1>::rotate(Vector3<T1> v) const {
|
||||
Quaternion<T1> t;
|
||||
t = (*this)*v*(~(*this));
|
||||
|
||||
return t.v;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::slerp(Quaternion<T> q, Quaternion<T> r, T a) {
|
||||
q.normalize();
|
||||
r.normalize();
|
||||
T u, v, angle, s;
|
||||
T dot = qdot(q, r);
|
||||
if(dot < 0.0f) {
|
||||
q = -q;
|
||||
dot = qdot(q, r);
|
||||
}
|
||||
|
||||
// acos gives NaN for dot slightly out of range
|
||||
if(dot > -(1.0 - Tolerance)) {
|
||||
if(dot < (1.0 - Tolerance)) {
|
||||
angle = acos(dot);
|
||||
s = sin(angle);
|
||||
} else {
|
||||
angle = 0;
|
||||
s = 0;
|
||||
}
|
||||
} else {
|
||||
angle = T(Constants::pi);
|
||||
s = 0;
|
||||
}
|
||||
if(s == 0)
|
||||
return angle<Constants::pi/2 ? q : r;
|
||||
|
||||
u = sin((1-a)*angle)/s;
|
||||
v = sin(a*angle)/s;
|
||||
return norm(u*q + v*r);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::fromRotMat(Matrix3<T> mat) {
|
||||
// quicker, but still wrong in one case
|
||||
/*
|
||||
Quaternion<T> q(1.0f, 0.0f, 0.0f, 0.0f);
|
||||
T t;
|
||||
if((t=0.25f*(1.0f + mat.r1[0] + mat.r2[1] + mat.r3[2])) > Tolerance) {
|
||||
q.n = sqrt(t);
|
||||
t = 4.0f*q.n;
|
||||
q.v[0] = (mat.r2[2]-mat.r3[1]) / t;
|
||||
q.v[1] = (mat.r3[0]-mat.r1[2]) / t;
|
||||
q.v[2] = (mat.r1[1]-mat.r2[0]) / t;
|
||||
} else if((t=-0.5f*(mat.r2[1]+mat.r3[2])) > Tolerance) {
|
||||
q.v[0] = sqrt(t);
|
||||
t=2.0f*q.v[0];
|
||||
q.v[1] = mat.r1[1]/t;
|
||||
q.v[2] = mat.r1[2]/t;
|
||||
} else if((t=0.5f*(1-mat.r3[2])) > Tolerance) {
|
||||
q.v[1]=sqrt(t);
|
||||
q.v[2]=mat.r2[2]/(2.0f*q.v[1]);
|
||||
}
|
||||
return norm(q);
|
||||
*/
|
||||
|
||||
Quaternion<T> quat;
|
||||
T s;
|
||||
T tr = mat[0][0] + mat[1][1] + mat[2][2];
|
||||
if(tr >= 0.0f) {
|
||||
s = sqrt(tr + 1.0f);
|
||||
quat.n = s * 0.5f;
|
||||
s = T(0.5) / s;
|
||||
quat.v[0] = (mat.r3[1] - mat.r2[2]) * s;
|
||||
quat.v[1] = (mat.r1[2] - mat.r3[0]) * s;
|
||||
quat.v[2] = (mat.r2[0] - mat.r1[1]) * s;
|
||||
}
|
||||
else {
|
||||
int i = 0;
|
||||
if(mat.r2[1] > mat.r1[0]) i = 1;
|
||||
if(mat.r3[2] > mat[i][i]) i = 2;
|
||||
switch(i) {
|
||||
case 0:
|
||||
s = sqrt(1.0f + mat.r1[0] - mat.r2[1] - mat.r3[2]);
|
||||
|
||||
quat.v[0] = s*0.5f;
|
||||
s = 0.5f / s;
|
||||
quat.v[1] = (mat.r2[0] + mat.r1[1]) * s;
|
||||
quat.v[2] = (mat.r1[2] + mat.r3[0]) * s;
|
||||
quat.n = (mat.r3[1] - mat.r2[2]) * s;
|
||||
break;
|
||||
case 1:
|
||||
s = sqrt(1.0f + mat.r2[1] - mat.r1[0] - mat.r3[2]);
|
||||
|
||||
quat.v[1] = s*0.5f;
|
||||
s = 0.5f / s;
|
||||
quat.v[2] = (mat.r3[1] + mat.r2[2]) * s;
|
||||
quat.v[0] = (mat.r2[0] + mat.r1[1]) * s;
|
||||
quat.n = (mat.r1[2] - mat.r3[0]) * s;
|
||||
break;
|
||||
case 2:
|
||||
s = sqrt(1.0f + mat.r3[2] - mat.r1[0] - mat.r2[1]);
|
||||
|
||||
quat.v[2] = s*0.5f;
|
||||
s = 0.5f / s;
|
||||
quat.v[0] = (mat.r1[2] + mat.r3[0]) * s;
|
||||
quat.v[1] = (mat.r3[1] + mat.r2[2]) * s;
|
||||
quat.n = (mat.r2[0] - mat.r1[1]) * s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return norm(quat);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Matrix3<T> Quaternion<T>::toRotMat() const {
|
||||
Matrix3<T> mat;
|
||||
|
||||
T twx = 2*n*v[0];
|
||||
T twy = 2*n*v[1];
|
||||
T twz = 2*n*v[2];
|
||||
T txy = 2*v[0]*v[1];
|
||||
T txz = 2*v[0]*v[2];
|
||||
T tyz = 2*v[1]*v[2];
|
||||
|
||||
T tx2 = 2*v[0]*v[0];
|
||||
T ty2 = 2*v[1]*v[1];
|
||||
T tz2 = 2*v[2]*v[2];
|
||||
|
||||
|
||||
mat.r1[0] = 1 - ty2 - tz2;
|
||||
mat.r2[0] = txy + twz;
|
||||
mat.r3[0] = txz - twy;
|
||||
mat.r1[1] = txy - twz;
|
||||
mat.r2[1] = 1 - tx2 - tz2;
|
||||
mat.r3[1] = tyz + twx;
|
||||
mat.r1[2] = txz + twy;
|
||||
mat.r2[2] = tyz - twx;
|
||||
mat.r3[2] = 1 - tx2 - ty2;
|
||||
return mat;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::fromAxisAngle(Vector3<T> axis, T angle) {
|
||||
Quaternion<T> ret;
|
||||
ret.n = cos(angle / 2);
|
||||
ret.v = norm(axis) * sin(angle / 2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> Quaternion<T>::fromAngVel(Vector3<T> axis) {
|
||||
T mag = mag(axis);
|
||||
return fromAxisAngle(axis/mag, mag);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T Quaternion<T>::dot(Quaternion<T> q, Quaternion<T> r) {
|
||||
return q.n*r.n + (q.v * r.v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T>& Quaternion<T>::normalize() {
|
||||
operator/=(magnitude());
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T qdot(Quaternion<T> const& q, Quaternion<T> const& r) {
|
||||
return Quaternion<T>::dot(q, r);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T mag(Quaternion<T> const& q) {
|
||||
return q.magnitude();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> norm(Quaternion<T> q) {
|
||||
return q.normalize();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Vector3<T> qv_rotate(Quaternion<T> q, Vector3<T> v) {
|
||||
return q.rotate(v);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Quaternion<T> q_rotate(Quaternion<T> q1, Quaternion<T> q2) {
|
||||
return q1.rotate(q2);
|
||||
}
|
||||
|
||||
template<typename T1, typename T2>
|
||||
Quaternion<T1> operator*(Vector3<T1> const& v, Quaternion<T2> const& q) {
|
||||
return q * v;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
Quaternion<T1> operator*(T1 s, Quaternion<T1> const& q) {
|
||||
return q * s;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
T1 const* Quaternion<T1>::ptr() const {
|
||||
return &n;
|
||||
}
|
||||
|
||||
template<typename T1>
|
||||
T1* Quaternion<T1>::ptr() {
|
||||
return &n;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
105
attic/unneeded/StarRUTable.hpp
Normal file
105
attic/unneeded/StarRUTable.hpp
Normal file
|
@ -0,0 +1,105 @@
|
|||
#ifndef STAR_RUTABLE_HPP
|
||||
#define STAR_RUTABLE_HPP
|
||||
|
||||
#include "StarInterpolation.hpp"
|
||||
#include "StarArray.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Star {
|
||||
|
||||
template<typename Element, typename Position, size_t Rank, size_t StorageRank>
|
||||
struct Storage;
|
||||
|
||||
template<typename Element, typename Position, size_t Rank>
|
||||
struct Storage<Element, Position, Rank, 1> {
|
||||
std::vector<Position> positions;
|
||||
std::vector<Element> elements;
|
||||
|
||||
template<typename IndexList>
|
||||
void pushDim(Position const& position, size_t dim, IndexList const& index) {
|
||||
starAssert(false);
|
||||
}
|
||||
|
||||
template<typename IndexList>
|
||||
void pushElement(Position const& position, Element const& element, IndexList const& index) {
|
||||
positions.push_back(position);
|
||||
elements.push_back(element);
|
||||
}
|
||||
|
||||
template<typename IndexList>
|
||||
Element const& get(IndexList const& index) const {
|
||||
return elements[index[Rank - 1]];
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Element, typename Position, size_t Rank, size_t StorageRank>
|
||||
struct Storage {
|
||||
typedef Storage<Element, Position, Rank, StorageRank - 1> Stored;
|
||||
|
||||
template<typename IndexList>
|
||||
void pushDim(Position const& position, size_t dim, IndexList const& index) {
|
||||
if (dim == Rank - StorageRank) {
|
||||
positions.push_back(position);
|
||||
elements.push_back(Stored());
|
||||
} else {
|
||||
elements[index[Rank - StorageRank]].pushDim(position, dim, index);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename IndexList>
|
||||
void pushElement(Position const& position, Element const& element, IndexList const& index) {
|
||||
elements[index[Rank - StorageRank]].pushElement(position, element, index);
|
||||
}
|
||||
|
||||
template<typename IndexList>
|
||||
Element const& get(IndexList const& index) const {
|
||||
return elements[index[Rank - StorageRank]].get(index);
|
||||
}
|
||||
|
||||
std::vector<Position> positions;
|
||||
std::vector<Stored> elements;
|
||||
};
|
||||
|
||||
template<typename ElementT, typename PositionT, size_t RankN>
|
||||
class RUTable {
|
||||
public:
|
||||
typedef ElementT Element;
|
||||
typedef PositionT Position;
|
||||
static size_t const Rank = RankN;
|
||||
|
||||
typedef Array<Position, Rank> PositionList;
|
||||
typedef Array<size_t, Rank> IndexList;
|
||||
typedef Array<size_t, Rank> SizeList;
|
||||
|
||||
RUTable() : m_curDim(0), m_curIndex(IndexList::filled(0)) {}
|
||||
|
||||
void pushDim(Position const& position) {
|
||||
m_storage.pushDim(position, m_curDim, m_curIndex);
|
||||
++m_curDim;
|
||||
}
|
||||
|
||||
void pushElement(Position const& position, Element const& element) {
|
||||
m_storage.pushElement(position, element, m_curIndex);
|
||||
++m_curIndex[Rank - 1];
|
||||
}
|
||||
|
||||
void popDim() {
|
||||
m_curIndex[m_curDim] = 0;
|
||||
--m_curDim;
|
||||
++m_curIndex[m_curDim];
|
||||
}
|
||||
|
||||
Element const& get(IndexList const& index) const {
|
||||
return m_storage.get(index);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t m_curDim;
|
||||
IndexList m_curIndex;
|
||||
Storage<Element, Position, Rank, Rank> m_storage;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
420
attic/unneeded/StarSparseArray.hpp
Normal file
420
attic/unneeded/StarSparseArray.hpp
Normal file
|
@ -0,0 +1,420 @@
|
|||
#ifndef STAR_SPARSE_ARRAY_HPP
|
||||
#define STAR_SPARSE_ARRAY_HPP
|
||||
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
|
||||
namespace Star {
|
||||
|
||||
// Sparse "infinite" (mapped to every possible value of IndexT) 1d array.
|
||||
// Run-length compressed. Every element is always "set" -- starts out with
|
||||
// default constructed value of DataT. Stays run-length compressed as elements
|
||||
// are added or removed. CompareT should compare equality of two DataT,
|
||||
// defaults to operator==. IndexT must be an integer-like type.
|
||||
template<typename DataT, typename IndexT, typename CompareT = std::equal_to<DataT>,
|
||||
typename IndexLimitsT = std::numeric_limits<IndexT> >
|
||||
class SparseArray {
|
||||
public:
|
||||
typedef DataT Data;
|
||||
typedef IndexT Index;
|
||||
typedef CompareT Compare;
|
||||
typedef IndexLimitsT IndexLimits;
|
||||
|
||||
static Index minIndex() {
|
||||
return IndexLimits::min();
|
||||
}
|
||||
|
||||
static Index maxIndex() {
|
||||
return IndexLimits::max();
|
||||
}
|
||||
|
||||
struct Element {
|
||||
Element(Index const& i, Data const& v) : index(i), value(v) {}
|
||||
Index index;
|
||||
Data value;
|
||||
|
||||
bool operator<(Element const& e) const {
|
||||
return index < e.index;
|
||||
}
|
||||
|
||||
bool operator<(Index const& i) const {
|
||||
return index < i;
|
||||
}
|
||||
};
|
||||
|
||||
struct ElementCompare {
|
||||
ElementCompare(Compare const& r) : compare(r) {}
|
||||
bool operator()(Element const& e1, Element const& e2) const {
|
||||
return e1.index == e2.index && compare(e1.value, e2.value);
|
||||
}
|
||||
Compare const& compare;
|
||||
};
|
||||
|
||||
typedef std::vector<Element> ElementList;
|
||||
typedef typename ElementList::const_iterator ConstElementIterator;
|
||||
typedef typename ElementList::iterator ElementIterator;
|
||||
|
||||
ElementIterator rangeForIndex(Index const& i) {
|
||||
ElementIterator it = std::lower_bound(m_elements.begin(), m_elements.end(), i);
|
||||
|
||||
if (it != m_elements.end()) {
|
||||
if (it->index != i)
|
||||
--it;
|
||||
} else {
|
||||
--it;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
ConstElementIterator rangeForIndex(Index const& i) const {
|
||||
return const_cast<SparseArray*>(this)->rangeForIndex(i);
|
||||
}
|
||||
|
||||
ElementList const& elements() const {
|
||||
return m_elements;
|
||||
}
|
||||
|
||||
SparseArray(Compare const& c = Compare()) : m_compare(c) {
|
||||
m_elements.insert(m_elements.begin(), Element(minIndex(), Data()));
|
||||
}
|
||||
|
||||
SparseArray(Data const& d, Compare const& c = Compare()) : m_compare(c) {
|
||||
m_elements.insert(m_elements.begin(), Element(minIndex(), d));
|
||||
}
|
||||
|
||||
Data const& get(Index const& i) const {
|
||||
return rangeForIndex(i)->value;
|
||||
}
|
||||
|
||||
void set(Index const& i, Data const& d) {
|
||||
fill(i, i, d);
|
||||
}
|
||||
|
||||
void fill(Data const& d) {
|
||||
fill(minIndex(), maxIndex(), d);
|
||||
}
|
||||
|
||||
// Find the ranges in the array that include begin and end, brange, and erange, as well as the length of erange.
|
||||
// Delete every range in between, but not including brange and erange.
|
||||
// Find the distance between begin index and brange start, and end index and erange end (bdiff, ediff)
|
||||
// Store value of erange.
|
||||
// If erange is not the same range as brange, delete erange.
|
||||
// If brange value is equal to inserted value, then don't need to change brange.
|
||||
// Else, if bdiff is 0, then check the range previous to brange. If values are equal, erase brange, else replace brange,
|
||||
// Else, insert (begin, value) after brange.
|
||||
// Now, if ediff is 0, then check if next range value is equal to this value, if so, erase.
|
||||
// Else, insert (end+1, erange.value) after previously inserted range.
|
||||
// Sets *inclusive* range.
|
||||
void fill(Index const& begin, Index const& end, Data const& d) {
|
||||
ElementIterator brangeIt = rangeForIndex(begin);
|
||||
ElementIterator erangeIt = rangeForIndex(end);
|
||||
|
||||
if (brangeIt != erangeIt) {
|
||||
++brangeIt;
|
||||
if (brangeIt != erangeIt) {
|
||||
erangeIt = m_elements.erase(brangeIt, erangeIt);
|
||||
brangeIt = erangeIt;
|
||||
}
|
||||
--brangeIt;
|
||||
}
|
||||
|
||||
Index erangeEnd;
|
||||
ElementIterator pastIt(erangeIt);
|
||||
++pastIt;
|
||||
if (pastIt == m_elements.end())
|
||||
erangeEnd = maxIndex();
|
||||
else
|
||||
erangeEnd = pastIt->index - 1;
|
||||
|
||||
bool bdiff = begin != brangeIt->index;
|
||||
bool ediff = erangeEnd != end;
|
||||
|
||||
Data erangeVal = erangeIt->value;
|
||||
if (brangeIt != erangeIt) {
|
||||
erangeIt = m_elements.erase(erangeIt);
|
||||
brangeIt = erangeIt;
|
||||
--brangeIt;
|
||||
}
|
||||
|
||||
// insertIt should point to range after erange after this.
|
||||
ElementIterator insertIt = brangeIt;
|
||||
if (!m_compare(insertIt->value, d)) {
|
||||
if (!bdiff) {
|
||||
if (insertIt != m_elements.begin()) {
|
||||
ElementIterator prevIt = insertIt;
|
||||
--prevIt;
|
||||
if (m_compare(prevIt->value, d)) {
|
||||
insertIt = m_elements.erase(insertIt);
|
||||
} else {
|
||||
insertIt->value = d;
|
||||
++insertIt;
|
||||
}
|
||||
} else {
|
||||
insertIt->value = d;
|
||||
++insertIt;
|
||||
}
|
||||
} else {
|
||||
++insertIt;
|
||||
insertIt = m_elements.insert(insertIt, Element(begin, d));
|
||||
++insertIt;
|
||||
}
|
||||
} else {
|
||||
++insertIt;
|
||||
}
|
||||
|
||||
if (!ediff) {
|
||||
if (insertIt != m_elements.end()) {
|
||||
if (m_compare(insertIt->value, d))
|
||||
m_elements.erase(insertIt);
|
||||
}
|
||||
} else {
|
||||
ElementIterator prevIt = insertIt;
|
||||
--prevIt;
|
||||
if (!m_compare(prevIt->value, erangeVal))
|
||||
m_elements.insert(insertIt, Element(end+1, erangeVal));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
void transform(Index const& begin, Index const& end, Func f) {
|
||||
ElementIterator brangeIt = rangeForIndex(begin);
|
||||
ElementIterator erangeIt = rangeForIndex(end);
|
||||
Data erangeVal = erangeIt->value;
|
||||
|
||||
Index erangeEnd;
|
||||
ElementIterator pastIt(erangeIt);
|
||||
++pastIt;
|
||||
if (pastIt == m_elements.end())
|
||||
erangeEnd = maxIndex();
|
||||
else
|
||||
erangeEnd = pastIt->index - 1;
|
||||
|
||||
bool bdiff = begin != brangeIt->index;
|
||||
bool ediff = erangeEnd != end;
|
||||
|
||||
if (bdiff) {
|
||||
Data d = f(brangeIt->value);
|
||||
if (!m_compare(d, brangeIt->value)) {
|
||||
brangeIt = m_elements.insert(++brangeIt, Element(begin, d));
|
||||
}
|
||||
} else {
|
||||
brangeIt->value = f(brangeIt->value);
|
||||
}
|
||||
|
||||
ElementIterator last = brangeIt;
|
||||
ElementIterator cur = brangeIt;
|
||||
++cur;
|
||||
while(true) {
|
||||
if (cur == m_elements.end())
|
||||
break;
|
||||
if (cur->index > erangeEnd)
|
||||
break;
|
||||
|
||||
cur->value = f(cur->value);
|
||||
if (m_compare(cur->value, last->value)) {
|
||||
cur = m_elements.erase(cur);
|
||||
last = cur;
|
||||
--last;
|
||||
} else {
|
||||
last = cur++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ediff) {
|
||||
return;
|
||||
} else {
|
||||
if (!m_compare(last->value, erangeVal))
|
||||
m_elements.insert(cur, Element(end+1, erangeVal));
|
||||
}
|
||||
}
|
||||
|
||||
class Proxy {
|
||||
public:
|
||||
Proxy(SparseArray& s, Index const& i) : ref(s), index(i) {}
|
||||
operator Data const& () { return ref.get(index); }
|
||||
Proxy& operator=(Data const& d) {
|
||||
ref.set(index, d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
SparseArray& ref;
|
||||
Index const& index;
|
||||
};
|
||||
|
||||
Data const& operator()(Index const& i) const {
|
||||
return get(i);
|
||||
}
|
||||
|
||||
Proxy operator()(Index const& i) {
|
||||
return Proxy(*this, i);
|
||||
}
|
||||
|
||||
bool operator==(SparseArray const& sa) const {
|
||||
if (m_elements.size() != sa.m_elements.size())
|
||||
return false;
|
||||
return std::equal(m_elements.begin(), m_elements.end(), sa.m_elements.begin(), ElementCompare(m_compare));
|
||||
}
|
||||
|
||||
// Force compression (useful if m_compare is changed.)
|
||||
void compress() {
|
||||
for (ElementIterator i = m_elements.begin(); i != m_elements.end(); ++i) {
|
||||
if (i != m_elements.begin()) {
|
||||
ElementIterator p = i;
|
||||
--p;
|
||||
if (m_compare(p->value, i->value)) {
|
||||
i = m_elements.erase(i);
|
||||
--i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void setCompare(Compare c) {
|
||||
m_compare = c;
|
||||
}
|
||||
|
||||
Compare const& compare() const {
|
||||
return m_compare;
|
||||
}
|
||||
|
||||
private:
|
||||
ElementList m_elements;
|
||||
Compare m_compare;
|
||||
};
|
||||
|
||||
// 2 dimensional SparseArray
|
||||
template<typename DataT, typename IndexT, typename CompareT = std::equal_to<DataT>,
|
||||
typename IndexLimitsT = std::numeric_limits<IndexT> >
|
||||
class SparseGrid {
|
||||
public:
|
||||
typedef DataT Data;
|
||||
typedef IndexT Index;
|
||||
typedef CompareT Compare;
|
||||
typedef IndexLimitsT IndexLimits;
|
||||
typedef SparseArray<Data, Index, Compare, IndexLimitsT> ArrayElement;
|
||||
|
||||
// Compare rows, ignoring rows with complexity greater than 'limit'
|
||||
struct RowCompare {
|
||||
RowCompare(size_t cl = std::numeric_limits<size_t>::max()) : limit(cl) {}
|
||||
|
||||
bool operator()(ArrayElement const& a, ArrayElement const& b) const {
|
||||
if (a.elements().size() > limit || b.elements().size() > limit)
|
||||
return false;
|
||||
else
|
||||
return a == b;
|
||||
}
|
||||
|
||||
size_t limit;
|
||||
};
|
||||
|
||||
typedef SparseArray<ArrayElement, Index, RowCompare, IndexLimits> RowArray;
|
||||
|
||||
static Index minIndex() {
|
||||
return IndexLimits::min();
|
||||
}
|
||||
|
||||
static Index maxIndex() {
|
||||
return IndexLimits::max();
|
||||
}
|
||||
|
||||
SparseGrid(size_t compareLimit = 1) : m_rows(Data(), RowCompare(compareLimit)) {}
|
||||
|
||||
size_t compareLimit() const {
|
||||
return m_rows.compare().limit;
|
||||
}
|
||||
|
||||
void setCompareLimit(size_t cl) {
|
||||
m_rows.setCompare(RowCompare(cl));
|
||||
}
|
||||
|
||||
Data const& get(Index const& i, Index const& j) const {
|
||||
return m_rows.get(i).get(j);
|
||||
}
|
||||
|
||||
void set(Index const& i, Index const& j, Data const& d) {
|
||||
ArrayElement e = m_rows.get(i);
|
||||
e(j) = d;
|
||||
m_rows.set(i, e);
|
||||
}
|
||||
|
||||
Data const& operator()(Index const& i, Index const& j) const {
|
||||
return m_rows.get(i)(j);
|
||||
}
|
||||
|
||||
friend class Proxy;
|
||||
class Proxy {
|
||||
public:
|
||||
Proxy(SparseGrid& s, Index const& i, Index const& j) : ref(s), index_i(i), index_j(j) {}
|
||||
operator Data const&() const { return ref.get(index_i, index_j); }
|
||||
|
||||
Proxy& operator=(Data const& d) {
|
||||
ref.set(index_i, index_j, d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
SparseGrid& ref;
|
||||
Index const& index_i;
|
||||
Index const& index_j;
|
||||
};
|
||||
|
||||
Proxy operator()(Index const& i, Index const& j) {
|
||||
return Proxy(*this, i, j);
|
||||
}
|
||||
|
||||
class FillTransform {
|
||||
public:
|
||||
FillTransform(Index const& min, Index const& max, Data const& d) : m_min(min), m_max(max), m_val(d) {}
|
||||
|
||||
ArrayElement operator()(ArrayElement const& e) const {
|
||||
ArrayElement ne(e);
|
||||
ne.fill(m_min, m_max, m_val);
|
||||
return ne;
|
||||
}
|
||||
|
||||
private:
|
||||
Index const& m_min;
|
||||
Index const& m_max;
|
||||
Data const& m_val;
|
||||
};
|
||||
|
||||
void fill(Data const& d) {
|
||||
fill(minIndex(), maxIndex(), ArrayElement(d));
|
||||
}
|
||||
|
||||
void fill(Index const& rmin, Index const& rmax, ArrayElement const& row) {
|
||||
m_rows.fill(rmin, rmax, row);
|
||||
}
|
||||
|
||||
void fill(Index const& rmin, Index const& cmin, Index const& rmax, Index const& cmax, Data const& d) {
|
||||
m_rows.transform(rmin, rmax, FillTransform(cmin, cmax, d));
|
||||
}
|
||||
|
||||
// Full compression, turns off RowCompare limit temporarily.
|
||||
void compress() {
|
||||
size_t oldCompareLimit = compareLimit();
|
||||
setCompareLimit(std::numeric_limits<size_t>::max());
|
||||
m_rows.compress();
|
||||
setCompareLimit(oldCompareLimit);
|
||||
}
|
||||
|
||||
RowArray const& rows() const {
|
||||
return m_rows;
|
||||
}
|
||||
|
||||
size_t elementCount() const {
|
||||
size_t count = 0;
|
||||
for (typename RowArray::ConstElementIterator i = m_rows.begin(); i != m_rows.end(); ++i)
|
||||
count += m_rows.elements.count();
|
||||
return count;
|
||||
}
|
||||
|
||||
private:
|
||||
RowArray m_rows;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
185
attic/unneeded/StarTable.hpp
Normal file
185
attic/unneeded/StarTable.hpp
Normal file
|
@ -0,0 +1,185 @@
|
|||
#ifndef STAR_TABLE_HPP
|
||||
#define STAR_TABLE_HPP
|
||||
|
||||
#include "StarMultiArrayInterpolator.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
// Provides a method for storing, retrieving, and interpolating even n-variate
|
||||
// data. Access time is O(n), where n is the GridRank of the Table
|
||||
// Interpolation time for piecewise is O(n), O(2^n) for linear,
|
||||
// O(4^n) for cubic.
|
||||
template<typename ElementT, typename PositionT, size_t RankN>
|
||||
class Table {
|
||||
public:
|
||||
typedef ElementT Element;
|
||||
typedef PositionT Position;
|
||||
static size_t const Rank = RankN;
|
||||
|
||||
typedef Star::MultiArray<ElementT, RankN> MultiArray;
|
||||
|
||||
typedef Star::MultiArrayInterpolator2<MultiArray, Position> Interpolator2;
|
||||
typedef Star::MultiArrayInterpolator4<MultiArray, Position> Interpolator4;
|
||||
typedef Star::MultiArrayPiecewiseInterpolator<MultiArray, Position> PiecewiseInterpolator;
|
||||
|
||||
typedef Array<Position, Rank> PositionList;
|
||||
typedef Array<Position, 2> WeightList2;
|
||||
typedef Array<Position, 4> WeightList4;
|
||||
typedef typename MultiArray::SizeList SizeList;
|
||||
typedef typename MultiArray::IndexList IndexList;
|
||||
|
||||
typedef std::function<WeightList2(Position)> WeightFunction2;
|
||||
typedef std::function<WeightList4(Position)> WeightFunction4;
|
||||
typedef std::function<Element(PositionList const&)> InterpolateFunction;
|
||||
|
||||
struct TableRange {
|
||||
Position min;
|
||||
Position max;
|
||||
};
|
||||
|
||||
Table() {}
|
||||
|
||||
Table(SizeList const& size, PositionList const& min, PositionList const& max) {
|
||||
setDimensions(size, min, max);
|
||||
}
|
||||
|
||||
MultiArray const& array() const {
|
||||
return m_array;
|
||||
}
|
||||
|
||||
MultiArray& array() {
|
||||
return m_array;
|
||||
}
|
||||
|
||||
void setRanges(PositionList const& min, PositionList const& max) {
|
||||
for (size_t i = 0; i < Rank; ++i) {
|
||||
m_ranges[i].min = min[i];
|
||||
m_ranges[i].max = max[i];
|
||||
}
|
||||
}
|
||||
|
||||
void setRange(size_t dim, Position min, Position max) {
|
||||
m_ranges[dim].min = min;
|
||||
m_ranges[dim].max = max;
|
||||
}
|
||||
|
||||
TableRange const& range(size_t dim) const {
|
||||
return m_ranges[dim];
|
||||
}
|
||||
|
||||
TableRange& range(size_t dim) {
|
||||
return m_ranges[dim];
|
||||
}
|
||||
|
||||
void setDimension(size_t dim, size_t size, Position min, Position max) {
|
||||
SizeList sizes = m_array.sizes();
|
||||
sizes[dim] = size;
|
||||
m_array.resize(sizes);
|
||||
setRange(dim, min, max);
|
||||
}
|
||||
|
||||
void setDimensions(SizeList const& sizes, PositionList const& min, PositionList const& max) {
|
||||
m_array.resize(sizes);
|
||||
setRanges(min, max);
|
||||
}
|
||||
|
||||
void set(IndexList const& index, Element const& element) {
|
||||
m_array.set(index, element);
|
||||
}
|
||||
|
||||
Element const& get(IndexList const& index) const {
|
||||
return m_array(index);
|
||||
}
|
||||
|
||||
void set2TermInterpolation(WeightFunction2 const& weightFunction, BoundMode boundMode) {
|
||||
Interpolator2 interpolator2(weightFunction, boundMode);
|
||||
m_interpolateFunction = [=](PositionList const& position) {
|
||||
return interpolator2.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
};
|
||||
}
|
||||
|
||||
void set4TermInterpolation(WeightFunction4 const& weightFunction, BoundMode boundMode) {
|
||||
Interpolator4 interpolator4(weightFunction, boundMode);
|
||||
m_interpolateFunction = [=](PositionList const& position) {
|
||||
return interpolator4.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
};
|
||||
}
|
||||
|
||||
void setPiecewiseInterpolation(WeightFunction2 const& weightFunction, BoundMode boundMode) {
|
||||
PiecewiseInterpolator piecewiseInterpolator(weightFunction, boundMode);
|
||||
m_interpolateFunction = [=](PositionList const& position) {
|
||||
return piecewiseInterpolator.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
};
|
||||
}
|
||||
|
||||
Element interpolate(PositionList const& coord) const {
|
||||
return m_interpolateFunction(coord);
|
||||
}
|
||||
|
||||
Element operator()(PositionList const& coord) const {
|
||||
return interpolate(coord);
|
||||
}
|
||||
|
||||
// op should take a PositionList parameter and return an element.
|
||||
template<typename OpType>
|
||||
void eval(OpType op) {
|
||||
m_array.eval(EvalWrapper<OpType>(op, *this));
|
||||
}
|
||||
|
||||
protected:
|
||||
PositionList toIndexSpace(PositionList const& coord) const {
|
||||
PositionList indexCoord;
|
||||
for (size_t i = 0; i < Rank; ++i)
|
||||
indexCoord[i] = (coord[i] - m_ranges[i].min) / delta(i);
|
||||
return indexCoord;
|
||||
}
|
||||
|
||||
Position toTableSpace(Position pos, size_t dim) const {
|
||||
return m_ranges[dim].min + pos * delta(dim);
|
||||
}
|
||||
|
||||
Position delta(size_t dim) const {
|
||||
return (m_ranges[dim].max - m_ranges[dim].min) / (m_array.size(dim) - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
enum InterpolateMode {
|
||||
Interpolate2Mode,
|
||||
Interpolate4Mode,
|
||||
PiecewiseInterpolateMode
|
||||
};
|
||||
|
||||
template<typename OpType>
|
||||
struct EvalWrapper {
|
||||
EvalWrapper(OpType &o, Table const& t) : op(o), table(t) {}
|
||||
|
||||
template<typename IndexList>
|
||||
Element operator()(IndexList const& indexList) {
|
||||
PositionList rangeList;
|
||||
for (size_t i = 0; i < Rank; ++i)
|
||||
rangeList[i] = table.toTableSpace(indexList[i], i);
|
||||
|
||||
return op(rangeList);
|
||||
}
|
||||
|
||||
OpType& op;
|
||||
Table const& table;
|
||||
};
|
||||
|
||||
InterpolateFunction m_interpolateFunction;
|
||||
Array<TableRange, Rank> m_ranges;
|
||||
MultiArray m_array;
|
||||
};
|
||||
|
||||
typedef Table<float, float, 2> Table2F;
|
||||
typedef Table<double, double, 2> Table2D;
|
||||
|
||||
typedef Table<float, float, 3> Table3F;
|
||||
typedef Table<double, double, 3> Table3D;
|
||||
|
||||
typedef Table<float, float, 4> Table4F;
|
||||
typedef Table<double, double, 4> Table4D;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
202
attic/unneeded/StarUTable.hpp
Normal file
202
attic/unneeded/StarUTable.hpp
Normal file
|
@ -0,0 +1,202 @@
|
|||
#ifndef STAR_UTABLE_HPP
|
||||
#define STAR_UTABLE_HPP
|
||||
|
||||
#include "StarTable.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
// Provides a method for storing, retrieving, and interpolating uneven
|
||||
// n-variate data. Access times involve a binary search over the domain of
|
||||
// each dimension, so is O(log(n)*m) where n is the size of the largest
|
||||
// dimension, and m is the table_rank.
|
||||
//
|
||||
// BoundMode Wrap makes little mathematical sense for UTable.
|
||||
template<typename ElementT, typename PositionT, size_t RankN>
|
||||
class UTable {
|
||||
public:
|
||||
typedef ElementT Element;
|
||||
typedef PositionT Position;
|
||||
static size_t const Rank = RankN;
|
||||
|
||||
typedef Star::MultiArray<ElementT, RankN> MultiArray;
|
||||
|
||||
typedef Star::MultiArrayInterpolator2<MultiArray, Position> Interpolator2;
|
||||
typedef Star::MultiArrayPiecewiseInterpolator<MultiArray, Position> PiecewiseInterpolator;
|
||||
|
||||
typedef Array<Position, Rank> PositionList;
|
||||
typedef Array<Position, 2> WeightList2;
|
||||
typedef Array<Position, 4> WeightList4;
|
||||
typedef typename MultiArray::SizeList SizeList;
|
||||
typedef typename MultiArray::IndexList IndexList;
|
||||
typedef std::vector<Position> Range;
|
||||
typedef Vector<Range, Rank> RangeList;
|
||||
|
||||
typedef std::function<WeightList2(Position)> WeightFunction2;
|
||||
|
||||
// Evenly spaced table that UTable can be resampled into.
|
||||
typedef Table<Element, Position, Rank> ResampledTable;
|
||||
|
||||
// Set input ranges on a particular dimension. Will resize underlying storage to fit range.
|
||||
void setRange(std::size_t dim, Range const& range) {
|
||||
SizeList sizes = m_array.sizes();
|
||||
sizes[dim] = range.size();
|
||||
m_array.resize(sizes);
|
||||
|
||||
m_ranges[dim] = range;
|
||||
}
|
||||
|
||||
template<typename... Rest>
|
||||
void setRanges(RangeList const& ranges) {
|
||||
SizeList arraySize;
|
||||
|
||||
for (size_t dim = 0; dim < Rank; ++dim) {
|
||||
arraySize[dim] = ranges[dim].size();
|
||||
m_ranges[dim] = ranges[dim];
|
||||
}
|
||||
|
||||
m_array.resize(arraySize);
|
||||
}
|
||||
|
||||
template<typename... T>
|
||||
void setRanges(Range const& range, T const&... rest) {
|
||||
setRanges(RangeList{range, rest...});
|
||||
}
|
||||
|
||||
// Set array element based on index.
|
||||
void set(IndexList const& index, Element const& element) {
|
||||
m_array.set(index, element);
|
||||
}
|
||||
|
||||
// Get array element based on index.
|
||||
Element const& get(IndexList const& index) const {
|
||||
return m_array(index);
|
||||
}
|
||||
|
||||
MultiArray const& array() const {
|
||||
return m_array;
|
||||
}
|
||||
|
||||
MultiArray& array() {
|
||||
return m_array;
|
||||
}
|
||||
|
||||
void set2TermInterpolation(WeightFunction2 const& weightFunction, BoundMode boundMode) {
|
||||
Interpolator2 interpolator2(weightFunction, boundMode);
|
||||
m_interpolateFunction = [=](PositionList const& position) {
|
||||
return interpolator2.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
};
|
||||
|
||||
m_resampleFunction = [=](SizeList const& size) {
|
||||
ResampledTable resampledTable;
|
||||
resampledTable.reshape(size);
|
||||
|
||||
for (size_t i = 0; i < Rank; ++i)
|
||||
resampledTable.setRange(i, *this->m_ranges[i].begin(), *--this->m_ranges[i].end());
|
||||
|
||||
interpolator2.sample(this->m_array, resampledTable.array(), ResampleCoordinateOp(*this, resampledTable));
|
||||
return resampledTable;
|
||||
};
|
||||
}
|
||||
|
||||
void setPiecewiseInterpolation(WeightFunction2 const& weightFunction, BoundMode boundMode) {
|
||||
PiecewiseInterpolator piecewiseInterpolator(weightFunction, boundMode);
|
||||
m_interpolateFunction = [=](PositionList const& position) {
|
||||
return piecewiseInterpolator.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
};
|
||||
|
||||
m_resampleFunction = [=](SizeList const& size) {
|
||||
ResampledTable resampledTable;
|
||||
resampledTable.reshape(size);
|
||||
|
||||
resampledTable.eval([=](typename ResampledTable::PositionList const& position) {
|
||||
piecewiseInterpolator.interpolate(this->m_array, this->toIndexSpace(position));
|
||||
});
|
||||
|
||||
return resampledTable;
|
||||
};
|
||||
}
|
||||
|
||||
Element interpolate(PositionList const& coord) const {
|
||||
return m_interpolateFunction(coord);
|
||||
}
|
||||
|
||||
Element operator()(PositionList const& coord) const {
|
||||
return interpolate(coord);
|
||||
}
|
||||
|
||||
ResampledTable resample(SizeList const& size) const {
|
||||
return m_resampleFunction(size);
|
||||
}
|
||||
|
||||
// op should take a PositionList parameter and return an element.
|
||||
template<typename OpType>
|
||||
void eval(OpType op) {
|
||||
m_array.eval(EvalWrapper<OpType>(op, *this));
|
||||
}
|
||||
|
||||
private:
|
||||
struct ResampleCoordinateOp {
|
||||
typedef Position Scalar;
|
||||
|
||||
ResampleCoordinateOp(UTable const& u, ResampledTable const& t) :
|
||||
utable(u), table(t) {}
|
||||
|
||||
Scalar operator()(size_t dim, size_t pos) {
|
||||
return inverseLinearInterpolate(utable.m_ranges[dim], table.toTableSpace(pos, dim));
|
||||
}
|
||||
|
||||
PositionList operator()(size_t dim, int i) {
|
||||
return inverseLinearInterpolate(utable.getRange(dim),
|
||||
table.getTransformedCoord(i, dim));
|
||||
}
|
||||
|
||||
UTable const& utable;
|
||||
ResampledTable const& table;
|
||||
};
|
||||
|
||||
template<typename Coordinate>
|
||||
inline PositionList toIndexSpace(Coordinate const& coord) const {
|
||||
PositionList indexCoord;
|
||||
for (size_t i = 0; i < Rank; ++i)
|
||||
indexCoord[i] = inverseLinearInterpolate(m_ranges[i], coord[i]);
|
||||
return indexCoord;
|
||||
}
|
||||
|
||||
template<typename OpType>
|
||||
struct EvalWrapper {
|
||||
EvalWrapper(OpType &o, UTable const& t) : op(o), table(t) {}
|
||||
|
||||
template<typename IndexList>
|
||||
Element operator()(IndexList const& indexList) {
|
||||
PositionList rangeList;
|
||||
for (size_t i = 0; i < Rank; ++i)
|
||||
rangeList[i] = table.m_ranges[i][indexList[i]];
|
||||
|
||||
return op(rangeList);
|
||||
}
|
||||
|
||||
OpType& op;
|
||||
UTable const& table;
|
||||
};
|
||||
|
||||
typedef std::function<Element(PositionList const&)> InterpolateFunction;
|
||||
typedef std::function<ResampledTable(SizeList const&)> ResampleFunction;
|
||||
|
||||
RangeList m_ranges;
|
||||
InterpolateFunction m_interpolateFunction;
|
||||
ResampleFunction m_resampleFunction;
|
||||
MultiArray m_array;
|
||||
};
|
||||
|
||||
typedef UTable<float, float, 2> UTable2F;
|
||||
typedef UTable<double, double, 2> UTable2D;
|
||||
|
||||
typedef UTable<float, float, 3> UTable3F;
|
||||
typedef UTable<double, double, 3> UTable3D;
|
||||
|
||||
typedef UTable<float, float, 4> UTable4F;
|
||||
typedef UTable<double, double, 4> UTable4D;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
24
attic/unneeded/guarded_ptr_test.cpp
Normal file
24
attic/unneeded/guarded_ptr_test.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "StarGuardedPtr.hpp"
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
using namespace Star;
|
||||
|
||||
TEST(GuardedPtr, All) {
|
||||
GuardedPtr<int> ptr1;
|
||||
{
|
||||
GuardedPtr<int> ptr2;
|
||||
|
||||
GuardedHolder<int> holder(new int (5), true);
|
||||
|
||||
ptr1 = ptr2 = holder.guardedPtr();
|
||||
|
||||
EXPECT_TRUE((bool)ptr1);
|
||||
EXPECT_TRUE((bool)ptr2);
|
||||
|
||||
EXPECT_EQ(*ptr1, 5);
|
||||
EXPECT_EQ(*ptr2, 5);
|
||||
}
|
||||
|
||||
EXPECT_FALSE((bool)ptr1);
|
||||
}
|
229
attic/unneeded/liquid_test.cpp
Normal file
229
attic/unneeded/liquid_test.cpp
Normal file
|
@ -0,0 +1,229 @@
|
|||
#include "StarCellularLiquid.hpp"
|
||||
#include "StarRandom.hpp"
|
||||
#include "StarRenderer.hpp"
|
||||
#include "StarRootLoader.hpp"
|
||||
#include "StarLiquidsDatabase.hpp"
|
||||
#include "StarAssets.hpp"
|
||||
#include "StarTextPainter.hpp"
|
||||
#include "StarMainApplication.hpp"
|
||||
|
||||
using namespace Star;
|
||||
|
||||
constexpr int LiquidArrayWidth = 60;
|
||||
constexpr int LiquidArrayHeight = 60;
|
||||
constexpr int LiquidArraySlowBorder = 0;
|
||||
constexpr int LiquidArraySlowTickLimit = 200;
|
||||
constexpr float LiquidBottomDrainPercentage = 0.5f;
|
||||
|
||||
class LiquidTest : public Application {
|
||||
protected:
|
||||
struct LiquidStore {
|
||||
bool collision;
|
||||
bool endless;
|
||||
Maybe<size_t> liquid;
|
||||
float level;
|
||||
float pressure;
|
||||
};
|
||||
|
||||
void startup(StringList const& cmdLineArgs) override {
|
||||
RootLoader rootLoader({{}, {}, {}, LogLevel::Info, false, {}});
|
||||
m_root = rootLoader.initOrDie(cmdLineArgs).first;
|
||||
|
||||
m_liquidArray.resize(Array2S(LiquidArrayWidth, LiquidArrayHeight), LiquidStore());
|
||||
m_paused = false;
|
||||
m_step = false;
|
||||
m_update = 0;
|
||||
|
||||
struct CellWorld : CellularLiquidWorld<size_t> {
|
||||
LiquidTest& parent;
|
||||
|
||||
CellWorld(LiquidTest& parent) : parent(parent) {}
|
||||
|
||||
float drainLevel(Vec2I const& location) const override {
|
||||
return location[1] == 0 ? LiquidBottomDrainPercentage : 0.0f;
|
||||
}
|
||||
|
||||
CellularLiquidCell<size_t> cell(Vec2I const& location) const override {
|
||||
if (location[0] < 0 || location[1] < 0 || location[0] >= (int)parent.m_liquidArray.size(0) || location[1] >= (int)parent.m_liquidArray.size(1))
|
||||
return {};
|
||||
|
||||
auto const& store = parent.m_liquidArray(location[0], location[1]);
|
||||
if (store.collision)
|
||||
return CellularLiquidCollisionCell();
|
||||
|
||||
if (store.endless)
|
||||
return CellularLiquidSourceCell<size_t>{*store.liquid, store.pressure};
|
||||
else
|
||||
return CellularLiquidFlowCell<size_t>{store.liquid, store.level, store.pressure};
|
||||
}
|
||||
|
||||
void setFlow(Vec2I const& location, CellularLiquidFlowCell<size_t> const& flow) override {
|
||||
if (location[0] < 0 || location[1] < 0 || location[0] >= (int)parent.m_liquidArray.size(0) || location[1] >= (int)parent.m_liquidArray.size(1))
|
||||
return;
|
||||
|
||||
auto& store = parent.m_liquidArray(location[0], location[1]);
|
||||
if (!store.endless && !store.collision) {
|
||||
store.liquid = flow.liquid;
|
||||
store.level = flow.level;
|
||||
store.pressure = flow.pressure;
|
||||
}
|
||||
}
|
||||
|
||||
void liquidInteraction(Vec2I const& a, size_t aLiquid, Vec2I const& b, size_t bLiquid) override {
|
||||
if (a[0] < 0 || a[1] < 0 || a[0] >= (int)parent.m_liquidArray.size(0) || a[1] >= (int)parent.m_liquidArray.size(1))
|
||||
return;
|
||||
|
||||
if (b[0] < 0 || b[1] < 0 || b[0] >= (int)parent.m_liquidArray.size(0) || b[1] >= (int)parent.m_liquidArray.size(1))
|
||||
return;
|
||||
|
||||
auto& aCell = parent.m_liquidArray(a[0], a[1]);
|
||||
auto& bCell = parent.m_liquidArray(b[0], b[1]);
|
||||
|
||||
if (aLiquid == 0 && bLiquid == 2 && !aCell.endless)
|
||||
bCell = LiquidStore{true, false, {}, 0.0f, 0.0f};
|
||||
if (aLiquid == 2 && bLiquid == 0 && !bCell.endless)
|
||||
aCell = LiquidStore{true, false, {}, 0.0f, 0.0f};
|
||||
if (aLiquid == 0 && bLiquid == 1 && !aCell.endless)
|
||||
aCell.liquid = 1;
|
||||
if (aLiquid == 1 && bLiquid == 0 && !bCell.endless)
|
||||
bCell.liquid = 1;
|
||||
}
|
||||
};
|
||||
|
||||
m_liquidEngine = make_shared<LiquidCellEngine<size_t>>(
|
||||
Root::singleton().liquidsDatabase()->liquidEngineParameters(), make_shared<CellWorld>(*this));
|
||||
|
||||
auto assets = Root::singleton().assets();
|
||||
|
||||
m_liquids = {{0, 0, 255, 255}, {0, 255, 0, 255}, {255, 0, 0, 255}};
|
||||
m_currentLiquid = 0;
|
||||
|
||||
m_liquidEngine->setLiquidTickDelta(0, 2);
|
||||
m_liquidEngine->setLiquidTickDelta(1, 3);
|
||||
m_liquidEngine->setLiquidTickDelta(2, 5);
|
||||
|
||||
m_liquidEngine->setProcessingLimit(LiquidArraySlowTickLimit);
|
||||
m_liquidEngine->setNoProcessingLimitRegions({RectI(0, 0, LiquidArrayWidth, LiquidArrayHeight).trimmed(LiquidArraySlowBorder)});
|
||||
}
|
||||
|
||||
void renderInit(RendererPtr renderer) override {
|
||||
Application::renderInit(renderer);
|
||||
m_textPainter = make_shared<TextPainter>(m_root->assets()->font("/hobo.ttf")->clone(), renderer);
|
||||
m_textPainter->setFontSize(16);
|
||||
}
|
||||
|
||||
void update() override {
|
||||
if (m_mouseButtonHeld) {
|
||||
Vec2I cell = screenToCell(m_mousePos);
|
||||
auto& mouseCell = m_liquidArray(cell[0], cell[1]);
|
||||
|
||||
if (*m_mouseButtonHeld == MouseButton::Left) {
|
||||
mouseCell = LiquidStore{true, false, {}, 0.0f, 0.0f};
|
||||
} else if (*m_mouseButtonHeld == MouseButton::Middle) {
|
||||
mouseCell = LiquidStore{false, true, m_currentLiquid, 1.0f, 5.0f};
|
||||
} else if (*m_mouseButtonHeld == MouseButton::Right) {
|
||||
mouseCell = LiquidStore{false, false, {}, 0.0f, 0.0f};
|
||||
}
|
||||
|
||||
m_liquidEngine->visitLocation(cell);
|
||||
}
|
||||
|
||||
if (!m_paused || m_step) {
|
||||
m_liquidEngine->update();
|
||||
++m_update;
|
||||
}
|
||||
|
||||
m_step = false;
|
||||
}
|
||||
|
||||
void render() override {
|
||||
for (int x = 0; x < LiquidArrayWidth; ++x) {
|
||||
for (int y = 0; y < LiquidArrayHeight; ++y) {
|
||||
auto const& cell = m_liquidArray(x, y);
|
||||
RectF screenRect = cellScreenRect({x, y});
|
||||
Vec4B color;
|
||||
if (cell.collision)
|
||||
color = {255, 255, 255, 255};
|
||||
if (cell.endless)
|
||||
color = {255, 0, 255, 255};
|
||||
else if (cell.liquid)
|
||||
color = liquidColor(*cell.liquid, cell.level);
|
||||
|
||||
renderer()->render(renderFlatRect(screenRect, color));
|
||||
}
|
||||
}
|
||||
|
||||
Vec2I mouseCellPos = screenToCell(m_mousePos);
|
||||
auto const& mouseCell = m_liquidArray(mouseCellPos[0], mouseCellPos[1]);
|
||||
|
||||
String hoverText = strf(
|
||||
"fps: %s\nactive water cells: %s\nactive acid cells: %s\nactive lava cells: %s\ncell: %s\npaused: %s\ncurrent "
|
||||
"liquid: %d\ncell collision: %s\ncell liquid: %d\ncell level: %s\ncell pressure: %s\n",
|
||||
appController()->renderFps(), m_liquidEngine->activeCells(0), m_liquidEngine->activeCells(1), m_liquidEngine->activeCells(2),
|
||||
mouseCellPos, m_paused, m_currentLiquid, mouseCell.collision, mouseCell.liquid, mouseCell.level, mouseCell.pressure);
|
||||
|
||||
m_textPainter->renderText(hoverText, TextPositioning(Vec2F(0, renderer()->screenSize()[1]), HorizontalAnchor::LeftAnchor, VerticalAnchor::TopAnchor));
|
||||
}
|
||||
|
||||
void processInput(InputEvent const& event) override {
|
||||
if (auto keyDown = event.ptr<KeyDownEvent>()) {
|
||||
if (keyDown->key == Key::P)
|
||||
m_paused = !m_paused;
|
||||
if (keyDown->key == Key::S)
|
||||
m_step = true;
|
||||
} else if (auto mouseDown = event.ptr<MouseButtonDownEvent>()) {
|
||||
m_mouseButtonHeld = mouseDown->mouseButton;
|
||||
} else if (auto mouseWheel = event.ptr<MouseWheelEvent>()) {
|
||||
if (mouseWheel->mouseWheel == MouseWheel::Up)
|
||||
m_currentLiquid = pmod<int>((int)m_currentLiquid + 1, m_liquids.size());
|
||||
else
|
||||
m_currentLiquid = pmod<int>((int)m_currentLiquid - 1, m_liquids.size());
|
||||
|
||||
} else if (event.is<MouseButtonUpEvent>()) {
|
||||
m_mouseButtonHeld.reset();
|
||||
} else if (auto mme = event.ptr<MouseMoveEvent>()) {
|
||||
m_mousePos = mme->mousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
typedef MultiArray<LiquidStore, 2> LiquidArray;
|
||||
|
||||
Vec2F cellScreenDimensions() const {
|
||||
Vec2F windowSize(renderer()->screenSize());
|
||||
return {windowSize[0] / LiquidArrayWidth, windowSize[1] / LiquidArrayHeight};
|
||||
}
|
||||
|
||||
RectF cellScreenRect(Vec2I const& c) const {
|
||||
Vec2F cdim = cellScreenDimensions();
|
||||
Vec2F ll = Vec2F(cdim[0] * c[0], cdim[1] * c[1]);
|
||||
return RectF::withSize(ll, cdim);
|
||||
}
|
||||
|
||||
Vec2I screenToCell(Vec2I const& screen) const {
|
||||
Vec2F cdim = cellScreenDimensions();
|
||||
Vec2I cpos = Vec2I::floor(Vec2F(screen[0] / cdim[0], screen[1] / cdim[1]));
|
||||
return Vec2I(clamp(cpos[0], 0, LiquidArrayWidth - 1), clamp(cpos[1], 0, LiquidArrayHeight - 1));
|
||||
}
|
||||
|
||||
Vec4B liquidColor(size_t liquid, float level) {
|
||||
Vec4B color = m_liquids.at(liquid);
|
||||
return Color::v4fToByte(Color::v4bToFloat(color) * level);
|
||||
}
|
||||
|
||||
RootUPtr m_root;
|
||||
LiquidArray m_liquidArray;
|
||||
shared_ptr<LiquidCellEngine<size_t>> m_liquidEngine;
|
||||
List<Vec4B> m_liquids;
|
||||
bool m_paused;
|
||||
bool m_step;
|
||||
uint64_t m_update;
|
||||
Vec2I m_mousePos;
|
||||
|
||||
RendererPtr m_renderer;
|
||||
TextPainterPtr m_textPainter;
|
||||
Maybe<MouseButton> m_mouseButtonHeld;
|
||||
size_t m_currentLiquid;
|
||||
};
|
||||
|
||||
STAR_MAIN_APPLICATION(LiquidTest);
|
147
attic/unneeded/renderer_test.cpp
Normal file
147
attic/unneeded/renderer_test.cpp
Normal file
|
@ -0,0 +1,147 @@
|
|||
#include "StarMainApplication.hpp"
|
||||
|
||||
using namespace Star;
|
||||
|
||||
class MainApplication : public Application {
|
||||
protected:
|
||||
void renderInit(RendererPtr renderer) override {
|
||||
Application::renderInit(renderer);
|
||||
|
||||
if (renderer->rendererId() == "OpenGL20") {
|
||||
renderer->setEffectConfig(Json::parseJson(R"JSON(
|
||||
{
|
||||
"effectParameters" : {
|
||||
"lightMapEnabled" : {
|
||||
"type" : "bool",
|
||||
"default" : false,
|
||||
"uniform" : "lightMapEnabled"
|
||||
},
|
||||
"lightMapScale" : {
|
||||
"type" : "vec2",
|
||||
"default" : [1, 1],
|
||||
"uniform" : "lightMapScale"
|
||||
},
|
||||
"lightMapMultiplier" : {
|
||||
"type" : "float",
|
||||
"default" : 1.0,
|
||||
"uniform" : "lightMapMultiplier"
|
||||
}
|
||||
},
|
||||
|
||||
"effectTextures" : {
|
||||
"lightMap" : {
|
||||
"textureUniform" : "lightMap",
|
||||
"textureSizeUniform" : "lightMapSize",
|
||||
"textureAddressing" : "clamp",
|
||||
"textureFiltering" : "linear"
|
||||
}
|
||||
},
|
||||
|
||||
"vertexShader" : "
|
||||
#version 110
|
||||
|
||||
uniform vec2 textureSize;
|
||||
uniform vec2 screenSize;
|
||||
uniform mat3 vertexTransform;
|
||||
uniform vec2 lightMapSize;
|
||||
uniform vec2 lightMapScale;
|
||||
|
||||
attribute vec2 vertexPosition;
|
||||
attribute vec2 vertexTextureCoordinate;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
varying vec2 fragmentTextureCoordinate;
|
||||
varying vec4 fragmentColor;
|
||||
varying vec2 fragmentLightMapCoordinate;
|
||||
|
||||
void main() {
|
||||
vec2 screenPosition = (vertexTransform * vec3(vertexPosition, 1.0)).xy;
|
||||
|
||||
gl_Position = vec4(screenPosition / screenSize * 2.0 - 1.0, 0.0, 1.0);
|
||||
|
||||
fragmentLightMapCoordinate = (screenPosition / lightMapScale) / lightMapSize;
|
||||
fragmentTextureCoordinate = vertexTextureCoordinate / textureSize;
|
||||
fragmentColor = vertexColor;
|
||||
}
|
||||
",
|
||||
|
||||
"fragmentShader" : "
|
||||
#version 110
|
||||
|
||||
uniform sampler2D texture;
|
||||
uniform bool lightMapEnabled;
|
||||
uniform sampler2D lightMap;
|
||||
uniform float lightMapMultiplier;
|
||||
|
||||
varying vec2 fragmentTextureCoordinate;
|
||||
varying vec4 fragmentColor;
|
||||
varying vec2 fragmentLightMapCoordinate;
|
||||
|
||||
void main() {
|
||||
vec4 finalColor = texture2D(texture, fragmentTextureCoordinate) * fragmentColor;
|
||||
if (lightMapEnabled)
|
||||
finalColor *= texture2D(lightMap, fragmentLightMapCoordinate) * lightMapMultiplier;
|
||||
gl_FragColor = finalColor;
|
||||
}
|
||||
"
|
||||
}
|
||||
)JSON"));
|
||||
}
|
||||
|
||||
Image texture1Image(10, 10, PixelFormat::RGBA32);
|
||||
for (unsigned y = 0; y < 10; ++y) {
|
||||
for (unsigned x = 0; x < 10; ++x) {
|
||||
if (x < 3 || x > 7)
|
||||
texture1Image.set(x, y, Vec3B(0, 0, 0));
|
||||
else
|
||||
texture1Image.set(x, y, Vec3B(255, 255, 255));
|
||||
}
|
||||
}
|
||||
auto texture1 = renderer->createTexture(texture1Image, TextureAddressing::Clamp, TextureFiltering::Linear);
|
||||
|
||||
Image texture2Image(10, 10, PixelFormat::RGBA32);
|
||||
for (unsigned y = 0; y < 10; ++y) {
|
||||
for (unsigned x = 0; x < 10; ++x) {
|
||||
if (y < 3 || y > 7)
|
||||
texture2Image.set(x, y, Vec3B(0, 0, 0));
|
||||
else
|
||||
texture2Image.set(x, y, Vec3B(255, 255, 255));
|
||||
}
|
||||
}
|
||||
auto texture2 = renderer->createTexture(texture2Image, TextureAddressing::Clamp, TextureFiltering::Linear);
|
||||
|
||||
List<RenderPrimitive> primitives;
|
||||
for (size_t y = 0; y < 100; ++y) {
|
||||
for (size_t x = 0; x < 100; ++x) {
|
||||
primitives.append(RenderQuad{(y % 2 == 0) ? texture1 : texture2,
|
||||
RenderVertex{Vec2F(x, y), Vec2F(0, 0), Vec4B(255, 255, 255, 255)},
|
||||
RenderVertex{Vec2F(x + 1, y), Vec2F(10, 0), Vec4B(255, 255, 255, 255)},
|
||||
RenderVertex{Vec2F(x + 1, y + 1), Vec2F(10, 10), Vec4B(255, 255, 255, 255)},
|
||||
RenderVertex{Vec2F(x, y + 1), Vec2F(0, 10), Vec4B(255, 255, 255, 255)}});
|
||||
}
|
||||
}
|
||||
m_renderBuffer = renderer->createRenderBuffer();
|
||||
m_renderBuffer->set(primitives);
|
||||
|
||||
Image lightMapImage(50, 50, PixelFormat::RGBA32);
|
||||
for (unsigned y = 0; y < 50; ++y) {
|
||||
for (unsigned x = 0; x < 50; ++x)
|
||||
lightMapImage.set(x, y, Vec3B((x + 1) * 5.2 - 5, (y + 1) * 5.2 - 5, 255));
|
||||
}
|
||||
|
||||
renderer->setEffectParameter("lightMapEnabled", true);
|
||||
renderer->setEffectTexture("lightMap", lightMapImage);
|
||||
}
|
||||
|
||||
void render() override {
|
||||
Vec2U screenSize = renderer()->screenSize();
|
||||
renderer()->setEffectParameter("lightMapScale", Vec2F(screenSize[0] / 50.0f, screenSize[1] / 50.0f));
|
||||
renderer()->setScissorRect(RectI(20, 20, screenSize[0] - 20, screenSize[1] - 20));
|
||||
renderer()->renderBuffer(m_renderBuffer, Mat3F::scaling(Vec2F(screenSize[0] / 100.0f, screenSize[1] / 100.0f)));
|
||||
}
|
||||
|
||||
private:
|
||||
RenderBufferPtr m_renderBuffer;
|
||||
};
|
||||
|
||||
STAR_MAIN_APPLICATION(MainApplication);
|
Loading…
Add table
Add a link
Reference in a new issue