forked from bartvdbraak/blender
190 lines
4.8 KiB
C
190 lines
4.8 KiB
C
|
/*
|
||
|
* SOLID - Software Library for Interference Detection
|
||
|
*
|
||
|
* Copyright (C) 2001-2003 Dtecta. All rights reserved.
|
||
|
*
|
||
|
* This library may be distributed under the terms of the Q Public License
|
||
|
* (QPL) as defined by Trolltech AS of Norway and appearing in the file
|
||
|
* LICENSE.QPL included in the packaging of this file.
|
||
|
*
|
||
|
* This library may be distributed and/or modified under the terms of the
|
||
|
* GNU General Public License (GPL) version 2 as published by the Free Software
|
||
|
* Foundation and appearing in the file LICENSE.GPL included in the
|
||
|
* packaging of this file.
|
||
|
*
|
||
|
* This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||
|
* WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
*
|
||
|
* Commercial use or any other use of this library not covered by either
|
||
|
* the QPL or the GPL requires an additional license from Dtecta.
|
||
|
* Please contact info@dtecta.com for enquiries about the terms of commercial
|
||
|
* use of this library.
|
||
|
*/
|
||
|
|
||
|
#ifndef TRANSFORM_H
|
||
|
#define TRANSFORM_H
|
||
|
|
||
|
#include "Vector3.h"
|
||
|
#include "Matrix3x3.h"
|
||
|
|
||
|
namespace MT {
|
||
|
|
||
|
template <typename Scalar>
|
||
|
class Transform {
|
||
|
enum {
|
||
|
TRANSLATION = 0x01,
|
||
|
ROTATION = 0x02,
|
||
|
RIGID = TRANSLATION | ROTATION,
|
||
|
SCALING = 0x04,
|
||
|
LINEAR = ROTATION | SCALING,
|
||
|
AFFINE = TRANSLATION | LINEAR
|
||
|
};
|
||
|
|
||
|
public:
|
||
|
Transform() {}
|
||
|
|
||
|
template <typename Scalar2>
|
||
|
explicit Transform(const Scalar2 *m) { setValue(m); }
|
||
|
|
||
|
explicit Transform(const Quaternion<Scalar>& q,
|
||
|
const Vector3<Scalar>& c = Vector3<Scalar>(Scalar(0), Scalar(0), Scalar(0)))
|
||
|
: m_basis(q),
|
||
|
m_origin(c),
|
||
|
m_type(RIGID)
|
||
|
{}
|
||
|
|
||
|
explicit Transform(const Matrix3x3<Scalar>& b,
|
||
|
const Vector3<Scalar>& c = Vector3<Scalar>(Scalar(0), Scalar(0), Scalar(0)),
|
||
|
unsigned int type = AFFINE)
|
||
|
: m_basis(b),
|
||
|
m_origin(c),
|
||
|
m_type(type)
|
||
|
{}
|
||
|
|
||
|
Vector3<Scalar> operator()(const Vector3<Scalar>& x) const
|
||
|
{
|
||
|
return Vector3<Scalar>(m_basis[0].dot(x) + m_origin[0],
|
||
|
m_basis[1].dot(x) + m_origin[1],
|
||
|
m_basis[2].dot(x) + m_origin[2]);
|
||
|
}
|
||
|
|
||
|
Vector3<Scalar> operator*(const Vector3<Scalar>& x) const
|
||
|
{
|
||
|
return (*this)(x);
|
||
|
}
|
||
|
|
||
|
Matrix3x3<Scalar>& getBasis() { return m_basis; }
|
||
|
const Matrix3x3<Scalar>& getBasis() const { return m_basis; }
|
||
|
|
||
|
Vector3<Scalar>& getOrigin() { return m_origin; }
|
||
|
const Vector3<Scalar>& getOrigin() const { return m_origin; }
|
||
|
|
||
|
Quaternion<Scalar> getRotation() const { return m_basis.getRotation(); }
|
||
|
template <typename Scalar2>
|
||
|
void setValue(const Scalar2 *m)
|
||
|
{
|
||
|
m_basis.setValue(m);
|
||
|
m_origin.setValue(&m[12]);
|
||
|
m_type = AFFINE;
|
||
|
}
|
||
|
|
||
|
template <typename Scalar2>
|
||
|
void getValue(Scalar2 *m) const
|
||
|
{
|
||
|
m_basis.getValue(m);
|
||
|
m_origin.getValue(&m[12]);
|
||
|
m[15] = Scalar2(1.0);
|
||
|
}
|
||
|
|
||
|
void setOrigin(const Vector3<Scalar>& origin)
|
||
|
{
|
||
|
m_origin = origin;
|
||
|
m_type |= TRANSLATION;
|
||
|
}
|
||
|
|
||
|
void setBasis(const Matrix3x3<Scalar>& basis)
|
||
|
{
|
||
|
m_basis = basis;
|
||
|
m_type |= LINEAR;
|
||
|
}
|
||
|
|
||
|
void setRotation(const Quaternion<Scalar>& q)
|
||
|
{
|
||
|
m_basis.setRotation(q);
|
||
|
m_type = (m_type & ~LINEAR) | ROTATION;
|
||
|
}
|
||
|
|
||
|
void scale(const Vector3<Scalar>& scaling)
|
||
|
{
|
||
|
m_basis = m_basis.scaled(scaling);
|
||
|
m_type |= SCALING;
|
||
|
}
|
||
|
|
||
|
void setIdentity()
|
||
|
{
|
||
|
m_basis.setIdentity();
|
||
|
m_origin.setValue(Scalar(0.0), Scalar(0.0), Scalar(0.0));
|
||
|
m_type = 0x0;
|
||
|
}
|
||
|
|
||
|
bool isIdentity() const { return m_type == 0x0; }
|
||
|
|
||
|
Transform<Scalar>& operator*=(const Transform<Scalar>& t)
|
||
|
{
|
||
|
m_origin += m_basis * t.m_origin;
|
||
|
m_basis *= t.m_basis;
|
||
|
m_type |= t.m_type;
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
Transform<Scalar> inverse() const
|
||
|
{
|
||
|
Matrix3x3<Scalar> inv = (m_type & SCALING) ?
|
||
|
m_basis.inverse() :
|
||
|
m_basis.transpose();
|
||
|
|
||
|
return Transform<Scalar>(inv, inv * -m_origin, m_type);
|
||
|
}
|
||
|
|
||
|
Transform<Scalar> inverseTimes(const Transform<Scalar>& t) const;
|
||
|
|
||
|
Transform<Scalar> operator*(const Transform<Scalar>& t) const;
|
||
|
|
||
|
private:
|
||
|
|
||
|
Matrix3x3<Scalar> m_basis;
|
||
|
Vector3<Scalar> m_origin;
|
||
|
unsigned int m_type;
|
||
|
};
|
||
|
|
||
|
|
||
|
template <typename Scalar>
|
||
|
inline Transform<Scalar>
|
||
|
Transform<Scalar>::inverseTimes(const Transform<Scalar>& t) const
|
||
|
{
|
||
|
Vector3<Scalar> v = t.getOrigin() - m_origin;
|
||
|
if (m_type & SCALING)
|
||
|
{
|
||
|
Matrix3x3<Scalar> inv = m_basis.inverse();
|
||
|
return Transform<Scalar>(inv * t.getBasis(), inv * v,
|
||
|
m_type | t.m_type);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return Transform<Scalar>(m_basis.transposeTimes(t.m_basis),
|
||
|
v * m_basis, m_type | t.m_type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
template <typename Scalar>
|
||
|
inline Transform<Scalar>
|
||
|
Transform<Scalar>::operator*(const Transform<Scalar>& t) const
|
||
|
{
|
||
|
return Transform<Scalar>(m_basis * t.m_basis,
|
||
|
(*this)(t.m_origin),
|
||
|
m_type | t.m_type);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif
|