/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Christian Meyer co-programmer: ... */ #include "rotation.h" using namespace std; /** \brief create a rotation from a vector \param v: a vector */ Rotation::Rotation (const Vector& v) { Vector x = Vector( 1, 0, 0); Vector axis = x.cross( v); axis.normalize(); float angle = angle_rad( x, v); float ca = cos(angle); float sa = sin(angle); m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f); m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y; m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z; m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y; m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f); m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z; m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z; m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z; m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f); } /** \brief creates a rotation from an axis and an angle (radians!) \param axis: the rotational axis \param angle: the angle in radians */ Rotation::Rotation (const Vector& axis, float angle) { float ca, sa; ca = cos(angle); sa = sin(angle); m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f); m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y; m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z; m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y; m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f); m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z; m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z; m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z; m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f); } /** \brief creates a rotation from euler angles (pitch/yaw/roll) \param pitch: rotation around z (in radians) \param yaw: rotation around y (in radians) \param roll: rotation around x (in radians) */ Rotation::Rotation ( float pitch, float yaw, float roll) { float cy, sy, cr, sr, cp, sp; cy = cos(yaw); sy = sin(yaw); cr = cos(roll); sr = sin(roll); cp = cos(pitch); sp = sin(pitch); m[0] = cy*cr; m[1] = -cy*sr; m[2] = sy; m[3] = cp*sr+sp*sy*cr; m[4] = cp*cr-sp*sr*sy; m[5] = -sp*cy; m[6] = sp*sr-cp*sy*cr; m[7] = sp*cr+cp*sy*sr; m[8] = cp*cy; } /** \brief creates a nullrotation */ Rotation::Rotation () { m[0] = 1.0f; m[1] = 0.0f; m[2] = 0.0f; m[3] = 0.0f; m[4] = 1.0f; m[5] = 0.0f; m[6] = 0.0f; m[7] = 0.0f; m[8] = 1.0f; } /** \brief rotates the vector by the given rotation \param v: a vector \param r: a rotation */ Vector rotate_vector( const Vector& v, const Rotation& r) { Vector t; t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2]; t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5]; t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8]; return t; }