• Create Account

We're offering banner ads on our site from just \$5!

### #Actual___

Posted 21 June 2013 - 01:33 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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:

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();

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);
}


### #8___

Posted 21 June 2013 - 01:28 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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:

ahh ofc you need to find a point on plane in order to place there a model

### #7___

Posted 21 June 2013 - 01:28 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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:

ahh ofc you need to find a point on plane in order to lace there a model

### #6___

Posted 21 June 2013 - 01:21 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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:

### #5___

Posted 21 June 2013 - 01:19 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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;
}



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:

### #4___

Posted 21 June 2013 - 01:17 AM



//---------------------------------------------------------------------------

#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 = -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);
if (angle < 0) angle = -1.0*(90.0 + angle); else
angle = 90.0 - angle;
return float(angle);
}

{
t3dpoint p;
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;

}


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:

PARTNERS