| 1 |
/////////////////////////////////////////////////////////// |
|---|
| 2 |
// MobSurgeon // |
|---|
| 3 |
// Ðåäàêòîð mob-îâ äëÿ Ïðîêëÿòûõ Çåìåëü // |
|---|
| 4 |
// Copyright (C) 2005-2007 Gipat Group // |
|---|
| 5 |
// Ðàñïðîñòðàíÿåòñÿ íà óñëîâèÿõ // |
|---|
| 6 |
// Gipat Group's opened EI-editor-utility license // |
|---|
| 7 |
// âåðñèè 1.0 // |
|---|
| 8 |
// // |
|---|
| 9 |
// www.gipatgroup.org // |
|---|
| 10 |
/////////////////////////////////////////////////////////// |
|---|
| 11 |
|
|---|
| 12 |
//Ê ðàáîòå íàä äàííûì ôàéëîì ïðèëîæèëè ðóêè, íîãè.... êîðî÷å àôôòàðû: |
|---|
| 13 |
// 1) Sagrer (sagrer@yandex.ru) |
|---|
| 14 |
|
|---|
| 15 |
//////////////////////////////////////////////////////////////////////// |
|---|
| 16 |
|
|---|
| 17 |
//--------------------------------------------------------------------------- |
|---|
| 18 |
|
|---|
| 19 |
|
|---|
| 20 |
#pragma hdrstop |
|---|
| 21 |
|
|---|
| 22 |
#include "glQuaternions.h" |
|---|
| 23 |
#include <limits> |
|---|
| 24 |
|
|---|
| 25 |
//Íó, òèïî, ðåàëèçàöèÿ... |
|---|
| 26 |
//--------------------------------------------------------------------------- |
|---|
| 27 |
|
|---|
| 28 |
TQuaternion::~TQuaternion() |
|---|
| 29 |
//äåñòðóêòîð |
|---|
| 30 |
{ |
|---|
| 31 |
//Àí íèôèãà, ïóñòî. Íî ïî èäåå ñþäà ìîæíî âïèñàòü òî ÷òî äåëàåòñÿ ïðè óáèâñòâå |
|---|
| 32 |
//(delete) îáúåêòà ýòîãî êëàññà. |
|---|
| 33 |
}; |
|---|
| 34 |
//--------------------------------------------------------------------------- |
|---|
| 35 |
|
|---|
| 36 |
TQuaternion::TQuaternion() |
|---|
| 37 |
//Äåôîëòíûé êîíñòðóêòîð |
|---|
| 38 |
{ |
|---|
| 39 |
//Èíèöèàëèçèðóåì äåôîëòíûå çíà÷åíèÿ ïåðåìåííûõ... |
|---|
| 40 |
this->ident(); |
|---|
| 41 |
}; |
|---|
| 42 |
//--------------------------------------------------------------------------- |
|---|
| 43 |
|
|---|
| 44 |
TQuaternion::TQuaternion(float &w, float &x, float &y, float &z) |
|---|
| 45 |
//Êîíñòðóêòîð íà ïðîèçâîëüíûé êâàòåðíèîí |
|---|
| 46 |
{ |
|---|
| 47 |
//Èíèöèàëèçèðóåì óêàçàííûå çíà÷åíèÿ ïåðåìåííûõ... |
|---|
| 48 |
QuatW = w; |
|---|
| 49 |
QuatX = x; |
|---|
| 50 |
QuatY = y; |
|---|
| 51 |
QuatZ = z; |
|---|
| 52 |
}; |
|---|
| 53 |
//--------------------------------------------------------------------------- |
|---|
| 54 |
|
|---|
| 55 |
TQuaternion::TQuaternion(float w, float x, float y, float z) |
|---|
| 56 |
//Êîíñòðóêòîð íà ïðîèçâîëüíûé êâàòåðíèîí |
|---|
| 57 |
{ |
|---|
| 58 |
//Èíèöèàëèçèðóåì óêàçàííûå çíà÷åíèÿ ïåðåìåííûõ... |
|---|
| 59 |
QuatW = w; |
|---|
| 60 |
QuatX = x; |
|---|
| 61 |
QuatY = y; |
|---|
| 62 |
QuatZ = z; |
|---|
| 63 |
}; |
|---|
| 64 |
//--------------------------------------------------------------------------- |
|---|
| 65 |
|
|---|
| 66 |
void TQuaternion::ident() |
|---|
| 67 |
//Ïîñòàâèòü êâàòåðíèîíó ïóñòîå çíà÷åíèå. |
|---|
| 68 |
{ |
|---|
| 69 |
QuatW = 1; |
|---|
| 70 |
QuatX = 0; |
|---|
| 71 |
QuatY = 0; |
|---|
| 72 |
QuatZ = 0; |
|---|
| 73 |
}; |
|---|
| 74 |
//--------------------------------------------------------------------------- |
|---|
| 75 |
|
|---|
| 76 |
void TQuaternion::scale(float s) |
|---|
| 77 |
//Òèïî ìàñøòàáèðîâàòü. Â ïðèíöèïå - óìíîæåíèå íà ñêàëÿð. |
|---|
| 78 |
{ |
|---|
| 79 |
QuatW *= s; |
|---|
| 80 |
QuatX *= s; |
|---|
| 81 |
QuatY *= s; |
|---|
| 82 |
QuatZ *= s; |
|---|
| 83 |
}; |
|---|
| 84 |
//--------------------------------------------------------------------------- |
|---|
| 85 |
|
|---|
| 86 |
float TQuaternion::norm() |
|---|
| 87 |
//Íîðìà. |
|---|
| 88 |
{ |
|---|
| 89 |
//Ïåðåìåííûå |
|---|
| 90 |
float Result; |
|---|
| 91 |
/*double Arr[] = {QuatX,QuatY,QuatZ,QuatW}; |
|---|
| 92 |
|
|---|
| 93 |
//Ñ÷èòàåì... |
|---|
| 94 |
Result = SumOfSquares(&Arr[0],3);*/ |
|---|
| 95 |
|
|---|
| 96 |
//Ñ÷èòàåì... |
|---|
| 97 |
Result = QuatX*QuatX + QuatY*QuatY + QuatZ*QuatZ + QuatW*QuatW; |
|---|
| 98 |
|
|---|
| 99 |
//Âåðíóòü ðåçóëüòàò... |
|---|
| 100 |
return Result; |
|---|
| 101 |
}; |
|---|
| 102 |
|
|---|
| 103 |
//--------------------------------------------------------------------------- |
|---|
| 104 |
|
|---|
| 105 |
float TQuaternion::magnitude() |
|---|
| 106 |
//Ìîäóëü. |
|---|
| 107 |
{ |
|---|
| 108 |
//Ïåðåìåííûå |
|---|
| 109 |
float Result; |
|---|
| 110 |
|
|---|
| 111 |
//Ñ÷èòàåì... |
|---|
| 112 |
Result = (float)sqrt(norm()); |
|---|
| 113 |
|
|---|
| 114 |
//Âåðíóòü ðåçóëüòàò... |
|---|
| 115 |
return Result; |
|---|
| 116 |
}; |
|---|
| 117 |
//--------------------------------------------------------------------------- |
|---|
| 118 |
|
|---|
| 119 |
void TQuaternion::StabilizeLength() |
|---|
| 120 |
//Òèïî ñòàáèëèçèðîâàòü äëèíó êâàòåðíèîíà - ýòî âûïîëíÿåòñÿ áûñòðåå íîðìàëèçàöèè. |
|---|
| 121 |
{ |
|---|
| 122 |
float cs = (float)(fabs(QuatW) + fabs(QuatX) + fabs(QuatY) + fabs(QuatZ)); |
|---|
| 123 |
|
|---|
| 124 |
if (cs > 0.0f) |
|---|
| 125 |
{ |
|---|
| 126 |
QuatW /= cs; |
|---|
| 127 |
QuatX /= cs; |
|---|
| 128 |
QuatY /= cs; |
|---|
| 129 |
QuatZ /= cs; |
|---|
| 130 |
} |
|---|
| 131 |
else |
|---|
| 132 |
{ |
|---|
| 133 |
this->ident(); |
|---|
| 134 |
}; |
|---|
| 135 |
}; |
|---|
| 136 |
//--------------------------------------------------------------------------- |
|---|
| 137 |
|
|---|
| 138 |
void TQuaternion::normalize() |
|---|
| 139 |
//Íîðìàëèçîâàòü. Ìåäëåííåå ñòàáèëèçàöèè, íî â ðåçóëüòàòå åäèíè÷íûé êâàòåðíèîí. |
|---|
| 140 |
{ |
|---|
| 141 |
float m = magnitude(); |
|---|
| 142 |
if( m < std::numeric_limits<float>::epsilon() ) |
|---|
| 143 |
{ |
|---|
| 144 |
StabilizeLength(); |
|---|
| 145 |
m = magnitude(); |
|---|
| 146 |
} |
|---|
| 147 |
scale( 1.0f/m ); |
|---|
| 148 |
}; |
|---|
| 149 |
//--------------------------------------------------------------------------- |
|---|
| 150 |
|
|---|
| 151 |
void TQuaternion::GetGLMatrix(GLfloat *matrix) |
|---|
| 152 |
//Ïîëó÷èòü OpenGL-øíóþ ìàòðèöó ïîâîðîòà èç êâàòåðíèîíà. |
|---|
| 153 |
{ |
|---|
| 154 |
//Åäèíè÷íàÿ ìàòðèöà... |
|---|
| 155 |
//Çàêîììåíòèðîâàíî ãäå - òàì îïòèìèçàöèÿ - âñåðàâíî ýòè çíà÷åíèÿ áóäóò ïåðåçàïèñàíû. |
|---|
| 156 |
/*matrix[0] = 1; matrix[1] = 0; matrix[2] = 0; */matrix[3] = 0; |
|---|
| 157 |
/*matrix[4] = 0; matrix[5] = 1; matrix[6] = 0; */matrix[7] = 0; |
|---|
| 158 |
/*matrix[8] = 0; matrix[9] = 0; matrix[10] = 1; */matrix[11] = 0; |
|---|
| 159 |
matrix[12] = 0; matrix[13] = 0; matrix[14] = 0; matrix[15] = 1; |
|---|
| 160 |
|
|---|
| 161 |
//À òåïåðü ïðèíöèïå òóò âñå ñîäðàíî ñ ó÷åáíèêà... |
|---|
| 162 |
float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2; |
|---|
| 163 |
float s = 2.0f/norm(); // 4 mul 3 add 1 div |
|---|
| 164 |
|
|---|
| 165 |
x2 = QuatX * s; y2 = QuatY * s; z2 = QuatZ * s; |
|---|
| 166 |
xx = QuatX * x2; xy = QuatX * y2; xz = QuatX * z2; |
|---|
| 167 |
yy = QuatY * y2; yz = QuatY * z2; zz = QuatZ * z2; |
|---|
| 168 |
wx = QuatW * x2; wy = QuatW * y2; wz = QuatW * z2; |
|---|
| 169 |
|
|---|
| 170 |
matrix[0] = 1.0f - (yy + zz); |
|---|
| 171 |
matrix[4] = xy - wz; |
|---|
| 172 |
matrix[8] = xz + wy; |
|---|
| 173 |
|
|---|
| 174 |
matrix[1] = xy + wz; |
|---|
| 175 |
matrix[5] = 1.0f - (xx + zz); |
|---|
| 176 |
matrix[9] = yz - wx; |
|---|
| 177 |
|
|---|
| 178 |
matrix[2] = xz - wy; |
|---|
| 179 |
matrix[6] = yz + wx; |
|---|
| 180 |
matrix[10] = 1.0f - (xx + yy); |
|---|
| 181 |
}; |
|---|
| 182 |
//--------------------------------------------------------------------------- |
|---|
| 183 |
|
|---|
| 184 |
void TQuaternion::Mult(float W, float X, float Y, float Z) |
|---|
| 185 |
//Òèïî óìíîæèòü íà äðóãîé êâàòåðíèîí... |
|---|
| 186 |
{ |
|---|
| 187 |
this->QuatX = (this->QuatW * X) + (this->QuatX * W) + (this->QuatY * Z) - (this->QuatZ * Y); |
|---|
| 188 |
this->QuatY = (this->QuatW * Y) + (this->QuatY * W) + (this->QuatZ * X) - (this->QuatX * Z); |
|---|
| 189 |
this->QuatZ = (this->QuatW * Z) + (this->QuatZ * W) + (this->QuatX * Y) - (this->QuatY * X); |
|---|
| 190 |
this->QuatW = (this->QuatW * W) - (this->QuatX * X) - (this->QuatY * Y) - (this->QuatZ * Z); |
|---|
| 191 |
}; |
|---|
| 192 |
//--------------------------------------------------------------------------- |
|---|
| 193 |
|
|---|
| 194 |
void TQuaternion::SetAxisAngle(float VecX, float VecY, float VecZ, float angle) |
|---|
| 195 |
//Òèïî âûñòàâèòü êâàòåðíèîíó óãîë èç Axis-Angle ïðåäñòàâëåíèÿ. |
|---|
| 196 |
{ |
|---|
| 197 |
vec3 AxisVec(VecX, VecY, VecZ); //Îñü ïîâîðîòà. |
|---|
| 198 |
float tmp = AxisVec.normalize(); //Íîðìàëèçóåì âåêòîð. |
|---|
| 199 |
float HalfAngle = angle*0.5f; //Âûñ÷èòûâàåì ïîëîâèííûé óãîë. |
|---|
| 200 |
float AngleSin = (float)sin(HalfAngle); //Âûñ÷èòûâàåì ñèíóñ ïîëóóãëà... |
|---|
| 201 |
|
|---|
| 202 |
//Âûñòàâëÿåì íîâûå çíà÷åíèÿ êâàòåðíèîíà... |
|---|
| 203 |
this->QuatW = (float)cos(HalfAngle); //Ñêàëÿð - êîñèíóñ ïîëóóãëà ïîâîðîòà. |
|---|
| 204 |
this->QuatX = AxisVec.x * AngleSin; //Êîîðäèíàòû âåêòîðíîé ÷àñòè çàâèñÿò îò ñèíóñà ïîëóóãëà ïîâîðîòà... |
|---|
| 205 |
this->QuatY = AxisVec.y * AngleSin; // --""-- |
|---|
| 206 |
this->QuatZ = AxisVec.z * AngleSin; // --""-- |
|---|
| 207 |
}; |
|---|
| 208 |
//--------------------------------------------------------------------------- |
|---|
| 209 |
|
|---|
| 210 |
void TQuaternion::RotateByAxisAngle(float VecX, float VecY, float VecZ, float angle) |
|---|
| 211 |
//Ñäåëàòü óêàçàííûé ïîâîðîò âîêðóã óêàçàííîé îñè (â äîáàâêó ê èìåþùåéñÿ îðèåíòàöèè). |
|---|
| 212 |
{ |
|---|
| 213 |
vec3 AxisVec(VecX, VecY, VecZ); //Îñü ïîâîðîòà. |
|---|
| 214 |
float tmp = AxisVec.normalize(); //Íîðìàëèçóåì âåêòîð. |
|---|
| 215 |
float HalfAngle = angle*0.5f; //Âûñ÷èòûâàåì ïîëîâèííûé óãîë. |
|---|
| 216 |
float AngleSin = (float)sin(HalfAngle); //Âûñ÷èòûâàåì ñèíóñ ïîëóóãëà... |
|---|
| 217 |
|
|---|
| 218 |
//óìíîæàåì "íîâûé" ïîëó÷åííûé êâàòåðíèîí íà òî ÷òî åñòü... |
|---|
| 219 |
this->Mult((float)cos(HalfAngle),(float)(AxisVec.x * AngleSin),(float)(AxisVec.y * AngleSin),(float)(AxisVec.z * AngleSin)); |
|---|
| 220 |
}; |
|---|
| 221 |
//--------------------------------------------------------------------------- |
|---|
| 222 |
|
|---|
| 223 |
#pragma package(smart_init) |
|---|