//---------------------------------------------------------------------------
#ifndef DxCRotationMathH
#define DxCRotationMathH
#include "SysUtils.hpp"
#include "Dialogs.hpp"
#include "Math.hpp"
#include "Math.h"
#include "gl/glew.h"
#include "gl/gl.h"
#include "DxcMath.h"
#include "Classes.hpp"
#include "string_unit.hpp"
//---------------------------------------------------------------------------
//rotation unit :) not quaterions etc just angle representation + pitch yaw roll matrix (not proper order)
struct typrNota {
public:
TStringList*s;
bool save;
//t3dpoint p;//position
t3dpoint front;
t3dpoint right;
t3dpoint up;
t3dpoint rf;
t3dpoint ru;
t3dpoint rr;
t3dpoint pos;
float * AIR_MATRIX;
float ax,ay,az,bx,by,bz,cx,cy,cz,xt,yt,zt,xp,yp,zp;
float cs,sn; // sine and cosine of the rotation angle
float rcs,rsn; //roll sine and cosine
float GetLongitude(t3dpoint cpos) //yaw
{
long double angle;
angle = n2dGetPolarCoordAngleAD(cpos.x-pos.x,cpos.z-pos.z) / 6.2731860;
angle = -360.0*angle;
angle = VALIDUJD(angle)+90.0;
angle = VALIDUJD(angle);
return float(angle);
}
float GetLatitude(t3dpoint cpos) //pitch
{
t3dpoint cpn;
cpn = vectorAB(pos,cpos);
cpn = Normalize(cpn);
long double t;
t = (long double)cpn.x*(long double)cpn.x +(long double)cpn.z*(long double)cpn.z;
t = sqrtl(t);
if (cpn.y == 0.0f) return 0.0f;
long double tanges = t / (long double)cpn.y;
long double angle;
angle = atanl(tanges);
angle = RadToDeg( angle );
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}
t3dpoint __fastcall matrix_mult2(t3dpoint adr_ptr)
{
t3dpoint p;
p.x = ax*adr_ptr.x + ay* adr_ptr.y + az* adr_ptr.z;
p.y = bx*adr_ptr.x + by* adr_ptr.y + bz* adr_ptr.z;
p.z = cx*adr_ptr.x + cy* adr_ptr.y + cz* adr_ptr.z;
return p;
}
void pitch(float cs, float sn)
{
float temp;
temp = ay*cs - az*sn;
az = ay*sn + az*cs;
ay = temp;
temp = by*cs - bz*sn;
bz = by*sn + bz*cs;
by = temp;
temp = cy*cs - cz*sn;
cz = cy*sn + cz*cs;
cy = temp;
}
void yaw(float cs, float sn)
{
float temp;
temp = az*cs - ax*sn;
ax = az*sn + ax*cs;
az = temp;
temp = bz*cs - bx*sn;
bx = bz*sn + bx*cs;
bz = temp;
temp = cz*cs - cx*sn;
cx = cz*sn + cx*cs;
cz = temp;
}
void roll(float cs, float sn)
{
float temp;
temp = ax*cs - ay*sn;
ay = ax*sn + ay*cs;
ax = temp;
temp = bx*cs - by*sn;
by = bx*sn + by*cs;
bx = temp;
temp = cx*cs - cy*sn;
cy = cx*sn + cy*cs;
cx = temp;
}
void DoRotation()
{
rf = matrix_mult2( front );
ru = matrix_mult2( up );
rr = matrix_mult2( right );
AIR_MATRIX[0] = rr.x; //right
AIR_MATRIX[1] = rr.y;
AIR_MATRIX[2] = rr.z;
AIR_MATRIX[3] = 0.0f;
AIR_MATRIX[4] = ru.x; //up
AIR_MATRIX[5] = ru.y;
AIR_MATRIX[6] = ru.z;
AIR_MATRIX[7] = 0.0f;
AIR_MATRIX[8] = -rf.x; //front
AIR_MATRIX[9] = -rf.y;
AIR_MATRIX[10] = -rf.z;
AIR_MATRIX[11] = 0.0f;
AIR_MATRIX[12] = 0.0f; //point
AIR_MATRIX[13] = 0.0f;
AIR_MATRIX[14] = 0.0f;
AIR_MATRIX[15] = 1.0f;
}
void set_init_vals(t3dpoint nfront, t3dpoint nup, t3dpoint nright, t3dpoint center)
{
pos.x = center.x;
pos.y = center.y;
pos.z = center.z;
//right.x = nright.x;
//right.y = nright.y;
//right.z = nright.z;
//
//up.x = nup.x;
//up.y = nup.y;
//up.z = nup.z;
//
//front.x = -nfront.x;
//front.y = -nfront.y;
//front.z = -nfront.z;
ax = nright.x;
ay = nright.y;
az = nright.z;
bx = nup.x;
by = nup.y;
bz = nup.z;
cx = nfront.x;
cy = nfront.y;
cz = nfront.z;
// DoRotation(); jeszcze nei sprawdzalem
}
~typrNota() {
}
typrNota() {
save=false;
//p.x = 0.0f; p.y = 0.0f; p.z = 0.0f;
right.x = 1.0f;
right.y = 0.0f;
right.z = 0.0f;
up.x = 0.0f;
up.y = 1.0f;
up.z = 0.0f;
front.x = 0.0f;
front.y = 0.0f;
front.z = -1.0f;
AIR_MATRIX = new float[16];
xt = 0.0;
yt = 0.0;
zt = 0.0;
cs = cos(3.0f*imopi);
sn = sin(3.0f*imopi);
rcs = cos(4.0f*imopi);
rsn = sin(4.0f*imopi);
ax = 1.00;
ay = 0.0;
az = 0.0;
bx = 0.0;
by = 1.00;
bz = 0.0;
cx = 0.0;
cy = 0.0;
cz = 1.00;
pos.x = 0.0f;
pos.y = 0.0f;
pos.z = 0.0f;
DoRotation();
//---
}
void perform_rotation_to_vector(t3dpoint vec, bool normalized)
{
t3dpoint v;
if (normalized == false) v = Normalize( vec ); else v = vec;
t3dpoint temp; temp = vector_multiple(v, 10000.0f);
t3dpoint temp2; temp2 = vector_multiple(rf, 10000.0f);
float act_pitch; act_pitch = GetLatitude( temp2 );
float act_yaw; act_yaw = GetLongitude( temp2 );
act_pitch = VALIDUJ( act_pitch );
act_yaw = VALIDUJ( act_yaw );
//ShowMessage("act pitch: "+FloatToStr(act_pitch));
//ShowMessage("act yaw: "+FloatToStr(act_yaw));
float new_pitch; new_pitch = GetLatitude( temp );
float new_yaw; new_yaw = GetLongitude( temp );
new_pitch = VALIDUJ( new_pitch );
new_yaw = VALIDUJ( new_yaw );
//
//ShowMessage("new pitch: "+FloatToStr(new_pitch));
//ShowMessage("new yaw: "+FloatToStr(new_yaw));
float yawsign = 1.0f; float pitchsign = 1.0f;
float mpitch;
if (act_pitch > new_pitch)
mpitch = -(act_pitch - new_pitch);
else {
mpitch = new_pitch - act_pitch;
pitchsign = -1.0f;
}
float myaw;
if (act_yaw > new_yaw)
myaw = -(act_yaw - new_yaw);
else {
myaw = new_yaw - act_yaw;
yawsign = -1.0f;
}
float mpsine; float mpcosine;
mpsine = sin( mpitch * imopi );
mpcosine = cos( mpitch * imopi );
float mysine; float mycosine;
mysine = sin( myaw * imopi );
mycosine = cos( myaw * imopi );
if (mpitch < 0) pitchsign = -1.0f;
if (myaw < 0) yawsign = -1.0f;
yaw(mycosine,yawsign*mysine);
DoRotation();
pitch(mpcosine,pitchsign*mpsine);
DoRotation();
temp2 = vector_multiple(rf, 10000.0f);
act_pitch = GetLatitude( temp2 );
act_yaw = GetLongitude( temp2 );
//ShowMessage("act pitch: "+FloatToStr(act_pitch));
//ShowMessage("act yaw: "+FloatToStr(act_yaw));
}
void perform_roll_to_vector(t3dpoint vec, bool normalized)
{
t3dpoint v;
if (normalized == false) v = Normalize( vec ); else v = vec;
t3dpoint temp; temp = vector_multiple(v, 10000.0f);
t3dpoint temp2;
temp2.x = bx;
temp2.y = by;
temp2.z = bz;
temp2 = vector_multiple(temp2, 10000.0f);
float angela = RadToDeg( AngleBetweenVectors(temp, temp2) ) + 180.0f;
float mpsine; float mpcosine;
mpsine = sin( angela * imopi );
mpcosine = cos( angela * imopi );
float yawsign = 1.0f;
roll(mpcosine,mpsine);
DoRotation();
}
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
//***************************** VECTOR PITCH YAW DETERMINATION ****************************
};
void copyNOTA(typrNota in, typrNota & d)
{
// d.p.x = in.x;
// d.p.y = in.y;
// d.p.z = in.z;
d.ax = in.ax;
d.ay = in.ax;
d.az = in.az;
d.bx = in.bx;
d.by = in.bx;
d.bz = in.bz;
d.cx = in.cx;
d.cy = in.cx;
d.cz = in.cz;
d.front.x = in.front.x;
d.front.y = in.front.y;
d.front.z = in.front.z;
d.up.x = in.up.x;
d.up.y = in.up.y;
d.up.z = in.up.z;
d.right.x = in.right.x;
d.right.y = in.right.y;
d.right.z = in.right.z;
d.pos.x = in.pos.x;
d.pos.y = in.pos.y;
d.pos.z = in.pos.z;
int i;
for (i=0;i<16;i++) d.AIR_MATRIX[i] = in.AIR_MATRIX[i]; //is result created yet no so there will be a problemo
d.DoRotation();
}
#endif
/*
// computes pB ON line B closest to line A
// computes pA ON line A closest to line B
// return: 0 if parallel; 1 if coincident; 2 if generic (i.e., skew)
int
line_line_closest_points3d (
POINT *pA, POINT *pB, // computed points
const POINT *a, const VECTOR *adir, // line A, point-normal form
const POINT *b, const VECTOR *bdir ) // line B, point-normal form
{
static VECTOR Cdir, *cdir = &Cdir;
static PLANE Ac, *ac = &Ac, Bc, *bc = &Bc;
// connecting line is perpendicular to both
vcross ( cdir, adir, bdir );
// check for near-parallel lines
if ( !vnorm( cdir ) ) {
*pA = *a; // all points are closest
*pB = *b;
return 0; // degenerate: lines parallel
}
// form plane containing line A, parallel to cdir
plane_from_two_vectors_and_point ( ac, cdir, adir, a );
// form plane containing line B, parallel to cdir
plane_from_two_vectors_and_point ( bc, cdir, bdir, b );
// closest point on A is line A ^ bc
intersect_line_plane ( pA, a, adir, bc );
// closest point on B is line B ^ ac
intersect_line_plane ( pB, b, bdir, ac );
// distinguish intersecting, skew lines
if ( edist( pA, pB ) < 1.0E-5F )
return 1; // coincident: lines intersect
else
return 2; // distinct: lines skew
}
*/
long double __fastcall n2dGetPolarCoordAngleAD(float x,float y)
{
if ( (x == 0) && (y > 0) ) { return 3.1415926535897932384626433832795/2.0; }
if ( (x == 0) && (y < 0) ) { return 3.0*3.1415926535897932384626433832795/2.0; }
if (x == 0) return - 1000.0;
long double k; k = (long double)y / (long double)x;
if ( (x > 0) && (y >= 0) ) { return ArcTan(k); }
if ( (x > 0) && (y < 0) ) { return ArcTan(k)+2.0*3.1415926535897932384626433832795; }
if (x < 0) { return ArcTan(k)+3.1415926535897932384626433832795; }
//last versions were without .0 just simple 2 division
return - 1000.0;
}
float __fastcall VALIDUJ(float angle2)
{
float angle = angle2;
int kat=(int)angle2;
kat=kat/360;
if (angle < 0 )
{
angle = angle + (float)(kat+1)*360.0f;
}
if (angle >= 360)
{
angle = angle - (float)kat*360.0f;
}
return angle;
}
float __fastcall AngleBetweenVectors(t3dpoint Vector1,t3dpoint Vector2)
{
float dotProduct = 0.0f;
float vectorsMagnitude = 0.0f;
float angle = 0.0f;
dotProduct = Dot(Vector1, Vector2);
vectorsMagnitude = magnitude(Vector1) * magnitude(Vector2) ;
angle = ArcCos( dotProduct / vectorsMagnitude );
if(IsNan(angle) == true) return 0.0f;
return angle;
}
float __fastcall magnitude(t3dpoint Vector)
{
long double k;
k = (Vector.x*Vector.x) +(Vector.y*Vector.y) +(Vector.z*Vector.z);
k = sqrtl( k );
float s = float(k);
return s;
}
float __fastcall Dot(t3dpoint vVector1,t3dpoint vVector2)
{
return ( (vVector1.x * vVector2.x) + (vVector1.y * vVector2.y) + (vVector1.z * vVector2.z) );
}
i dont call set init vals or they are set as specified in code
now the code that inserts a model onto a face:
t3dpoint normupA;
t3dpoint normupB;
t3dpoint normup;
normupA = FCOpenGL->earthp.PLANET_MODEL->VBO_V[
FCOpenGL->earthp.PLANET_MODEL->VBO_BE[
FCOpenGL->earthp.selected_face].INDEX_START];
normupB = FCOpenGL->earthp.PLANET_MODEL->VBO_V[
FCOpenGL->earthp.PLANET_MODEL->VBO_BE[
FCOpenGL->earthp.selected_face].INDEX_START + 1];
//get the pitch info - we find out how much we must rotate model to fit the face pitch)
normup = vectorAB(normupA,normupB);
lasto->MATRIX.perform_rotation_to_vector(normup,false); //rotate pitch
t3dpoint xnormal;
xnormal = FCOpenGL->earthp.PLANET_MODEL->VBO_N[
FCOpenGL->earthp.PLANET_MODEL->VBO_BE[
FCOpenGL->earthp.selected_face].INDEX_START]; //and thats the face normal
lasto->MATRIX.perform_roll_to_vector(xnormal,true); //and we roll our model
but it works when model is rotated to have z or -z front side i cant remember ;] if not you need to rotate it first;x
the video shows that it work:
https://www.youtube.com/watch?feature=player_embedded&v=nkLu1NBYgJg
ahh ofc you need to find a point on plane in order to place there a model
drawing goes like this:
through all objects in scene:
void __fastcall TEditor::draw_mission_scene()
{
if (FCOpenGL->earthp.ican == false) return;
TMissionObject * p;
p = gmiss.FIRST_MISSION_OBJECT;
glPushMatrix();
glLoadIdentity();
gluLookAt(FCOpenGL->old.x,FCOpenGL->old.y,FCOpenGL->old.z,FCOpenGL->old.x+FCOpenGL->SUPERPOINT.x,
FCOpenGL->old.y-FCOpenGL->SUPERPOINT.y,FCOpenGL->old.z-FCOpenGL->SUPERPOINT.z,
0.0,1.0,0.0);
glColor3f(1,0,0);
//Textures::CreateSphere(FCOpenGL->dq1.x,FCOpenGL->dq1.y,FCOpenGL->dq1.z,10000.0f,30);
//Textures::CreateSphere(FCOpenGL->dq2.x,FCOpenGL->dq2.y,FCOpenGL->dq2.z,10000.0f,30);
//Textures::CreateSphere(FCOpenGL->dq3.x,FCOpenGL->dq3.y,FCOpenGL->dq3.z,10000.0f,30);
//Textures::CreateSphere(FCOpenGL->dq4.x,FCOpenGL->dq4.y,FCOpenGL->dq4.z,10000.0f,30);
while (p!=NULL) {
if (p->model != NULL) if (p->blank == false)
{
if ((p->friendly == true)&& (p->neutral == false)) glColor3f(0,0,1);
if ((p->friendly == false)&& (p->neutral == true)) glColor3f(1,1,1);
if ((p->friendly == false)&& (p->neutral == false)) glColor3f(1,0,0);
if (CheckBox18->Checked == false) {
Textures::CreateSphere(p->position.x,p->position.y,p->position.z,1000.0f,30);
}
else {
glPushMatrix();
//
glTranslatef(
p->position.x,
p->position.y,
p->position.z);
glPushMatrix();
glMultMatrixf(p->MATRIX.AIR_MATRIX);
p->model->DrawSimpleModel();
glPopMatrix();
glPopMatrix();
}
}
p = p->next;
}
glPopMatrix();
glColor3f(1,1,1);
}