cleanup before reworking the scripting engine layout:

This commit is contained in:
Hartmut Seichter 2019-01-22 15:21:04 +01:00
parent 4ff557d446
commit 803af8c37a
6 changed files with 130 additions and 108 deletions

View file

@ -36,16 +36,18 @@ struct quaternion_ : vector4_<T> {
typedef vector4_<T> base_type;
using typename base_type::value_type;
using base_type::base_type;
using base_type::x;
using base_type::y;
using base_type::z;
using base_type::w;
using base_type::lerp;
using base_type::operator*;
using base_type::operator/;
// using base_type::operator*;
// using base_type::operator/;
quaternion_(const base_type& other) : base_type(other) {}
quaternion_(const base_type& other) : base_type(other) {}
inline const quaternion_ operator * (const quaternion_& rhs) const {
return quaternion_(
@ -68,6 +70,10 @@ struct quaternion_ : vector4_<T> {
return conjugate() / this->norm();
}
inline static quaternion_ identity() {
return quaternion_({0,0,0,1});
}
const matrix4x4_<T> to_matrix() const {
matrix4x4_<T> m; m.set_identity();
@ -110,10 +116,49 @@ struct quaternion_ : vector4_<T> {
wtemp);
}
static const quaternion_<T> normalized_lerp(const quaternion_<T> &a,const quaternion_<T> &b,const T &t) {
return quaternion_<T>(lerp(a,b,t).normalized());
static const quaternion_ normalized_lerp(const quaternion_ &a,const quaternion_ &b,const T &t) {
return quaternion_(lerp(a,b,t).normalized());
}
const quaternion_ slerp(const quaternion_& qa,const quaternion_& qb,const T& t)
{
using std::abs;
using std::sqrt;
using std::acos;
// quaternion to return
quaternion_ qm;
// Calculate angle between them.
T cosHalfTheta = qa.w() * qb.w() + qa.x() * qb.x() + qa.y() * qb.y() + qa.z() * qb.z();
// if qa=qb or qa=-qb then theta = 0 and we can return qa
if (abs(cosHalfTheta) >= T(1)) {
return qa;
}
// Calculate temporary values.
const T halfTheta = acos(cosHalfTheta);
const T sinHalfTheta = sqrt(1.0 - cosHalfTheta * cosHalfTheta);
// if theta = 180 degrees then result is not fully defined
// we could rotate around any axis normal to qa or qb
if (abs(sinHalfTheta) < 0.001){ // fabs is floating point absolute
qm.w() = (qa.w() * T(0.5) + qb.w() * T(0.5));
qm.x() = (qa.x() * T(0.5) + qb.x() * T(0.5));
qm.y() = (qa.y() * T(0.5) + qb.y() * T(0.5));
qm.z() = (qa.z() * T(0.5) + qb.z() * T(0.5));
return qm;
}
const T ratioA = sin((value_type(1) - t) * halfTheta) / sinHalfTheta;
const T ratioB = sin(t * halfTheta) / sinHalfTheta;
//calculate Quaternion.
qm.w() = (qa.w() * ratioA + qb.w() * ratioB);
qm.x() = (qa.x() * ratioA + qb.x() * ratioB);
qm.y() = (qa.y() * ratioA + qb.y() * ratioB);
qm.z() = (qa.z() * ratioA + qb.z() * ratioB);
return qm;
}
static const quaternion_<T> from_axisangle(const axisangle_<T> &aa) {
using std::sin;

View file

@ -15,10 +15,10 @@ int main(int argc,char **argv) {
std::cout << "qf.conjugate() = " << pw::serialize::matrix(qf.conjugate()) << std::endl;
pw::quaternionf qc = qf.conjugate();
std::cout << "qf.conjugate() (qc) = " << pw::serialize::matrix(qc) << std::endl;
std::cout << "qf.conjugate() (qc) = " << pw::serialize::matrix(qc.to_matrix()) << std::endl;
pw::quaternionf qi = qf.inverse();
std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi) << std::endl;
std::cout << "qf.inverse() (qi) = " << pw::serialize::matrix(qi.to_matrix()) << std::endl;
pw::quaternionf qmid = pw::quaternionf::normalized_lerp(qi,qf,0.5f);
// std::cout << "qmid.dot() (half between qf and qi) = " << pw::rad_to_deg(quaternionf::angle_between()) << std::endl;