/* 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: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH #include "rotation_OBSOLETE.h" #ifdef DEBUG #include "debug.h" #else #include #define PRINT(x) printf #endif /** * 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 = angleRad( 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); } /** * 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); } /** * 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; } /** * creates a nullrotation (an identity rotation) */ 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; } /** * fills the specified buffer with a 4x4 glmatrix * @param buffer: Pointer to an array of 16 floats Use this to get the rotation in a gl-compatible format */ void Rotation::glmatrix (float* buffer) { buffer[0] = m[0]; buffer[1] = m[3]; buffer[2] = m[6]; buffer[3] = m[0]; buffer[4] = m[1]; buffer[5] = m[4]; buffer[6] = m[7]; buffer[7] = m[0]; buffer[8] = m[2]; buffer[9] = m[5]; buffer[10] = m[8]; buffer[11] = m[0]; buffer[12] = m[0]; buffer[13] = m[0]; buffer[14] = m[0]; buffer[15] = m[1]; } /** * multiplies two rotational matrices * @param r: another Rotation * @return the matrix product of the Rotations Use this to rotate one rotation by another */ Rotation Rotation::operator* (const Rotation& r) { Rotation p; p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6]; p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7]; p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8]; p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6]; p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7]; p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8]; p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6]; p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7]; p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8]; return p; } /** * rotates the vector by the given rotation * @param v: a vector * @param r: a rotation * @return the rotated vector */ Vector rotateVector( 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; }