Проблема перевода физ.движка с Delphi на с++

  • Автор темы fromtuba
  • Дата начала
F

fromtuba

Гость
#1
Здравствуйте Все!
В недавнем времени понадобился 2d физический движок. Нашел PhysX в примере для builder delphi (сам пишу на c++ buider).
Несколь часов перевода и некоторой модификации не дали желаемый результат.
Помогите.... в чем может быть проблема????
исходник с exe Посмотреть вложение PhysX.rar
исходный код перевода в с++ builder:
файл unit1.cpp
Код:
//---------------------------------------------------------------------------


#pragma hdrstop

#include "Unit1.h"
#include "DEF.cpp"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

float dt=0.1;

void Poly_Draw(TPoly poly)
{
int i;

Form1->Canvas->MoveTo(int (poly.v[0].x),int (poly.v[0].y));
for (i=1;i<=poly.m_v;i++)
{
int j;
if (i==poly.m_v)
j=0;
else
j=i;

Form1->Canvas->LineTo(int (poly.v[j].x),int (poly.v[j].y));

}

Form1->Canvas->TextOutA(0,0,text1);
Form1->Canvas->TextOutA(0,20,text2);
Form1->Canvas->TextOutA(0,40,text3);
Form1->Canvas->TextOutA(0,60,text4);
Form1->Canvas->TextOutA(0,70,text5);

}





//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------


void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
int i;
// отрисовка:
Canvas->Brush->Color = clWhite;
Canvas->FillRect(Canvas->ClipRect);

int Iter=10;

for (i=1;i<=Iter;i++)
{
int j;
for (j=1;j<=lObject;j++)
if (!Object[j]._static)
{
Body_Update(j,V2(0,9.8),dt/Iter);
}

//ТУТ НУЖНО ДОБАВИТЬ АВТОМАТИЗМА

if (Body_Collide(1,2))
{
text1="++++++";
}
else
text1="------";



//ВСЕГДА ++++++++++++++++++++++++++++++++ 
}




for (i=1;i<=lObject;i++)
Poly_Draw(Object[i].poly);



}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormCreate(TObject *Sender)
{
int i=1;

Object[i].Name="Пол";
Object[i]._static=true;			//подвижность/неподвижность
Object[i].possition=V2(400,400);  //центр
Object[i].velocity=V2(0,0);		//напровление ускорения
Object[i].m=0.001;						//масса
Object[i].i=0.001;					  //Момент инерции
Object[i].e=1.0;
Object[i].f=1.0;
Object[i].angle=0.00;

Object[i].poly.m_v=4;
Object[i].poly.v_base[0]=V2(-300,-20);
Object[i].poly.v_base[1]=V2(-300,20);
Object[i].poly.v_base[2]=V2(300,20);
Object[i].poly.v_base[3]=V2(300,-20);

Poly_Init(i);


i=2;
Object[i].Name="коробка";
Object[i]._static=false;			//подвижность/неподвижность
Object[i].possition=V2(430,0);  //центр
Object[i].velocity=V2(0,0);		//напровление ускорения
Object[i].m=100;						//масса
Object[i].i=1;					  //Момент инерции
Object[i].e=0.0;
Object[i].f=0.2;
Object[i].w=0.0;
// Object[i].angle=0.01;

Object[i].poly.m_v=4;
Object[i].poly.v_base[0]=V2(-30,-20);
Object[i].poly.v_base[1]=V2(-30,20);
Object[i].poly.v_base[2]=V2(30,20);
Object[i].poly.v_base[3]=V2(30,-20);

Poly_Init(i);

}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key,
TShiftState Shift)
{
if (Key==VK_ESCAPE)
Close();
}
//---------------------------------------------------------------------------
файл DEF.cpp
Код:
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "DEF.h"
#include "math.h"




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

#pragma package(smart_init)
const
c_Depth = 0.1;
//max_v  = 19;

void Poly_Update(int no);
void Poly_Init(int no);
AnsiString text1,text2,text3,text4,text5;


struct TVector2
{
double x;
double y;
};
//--------------------------------------------------------------------

//--------------------------------------------------------------------
struct TEdge
{
TVector2 n;
double d;

};
//--------------------------------------------------------------------
struct TPoly
{
TVector2 v[101];
TVector2 v_base[101];

TEdge ed[101];
TEdge ed_base[101];

int m_v;
TVector2 rot;


};
//--------------------------------------------------------------------
struct TContact
{
TVector2 p;
TVector2 n;
TVector2 r1;
TVector2 r2;
double Depth;

};
//--------------------------------------------------------------------
struct
{
AnsiString Name;
AnsiString Type;
bool Enabled;
bool _static;

TVector2 possition;
TVector2 velocity;
double m;
double w;
double i;
double f;
double e;

TPoly poly;
double angle;
//TShape *shapes[101];
int lShapes;

} Object[1001];

int lObject=2;


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

TVector2 V2( double x,double y)
{
TVector2 temp;
temp.x=x;
temp.y=y;
return temp;
}
//--------------------------------------------------------------------
TVector2 V2Add(TVector2 a,TVector2 b)
{
TVector2 temp;
temp.x=a.x+b.x;
temp.y=a.y+b.y;
return temp;
}
//--------------------------------------------------------------------
TVector2 V2Sub(TVector2 a,TVector2 b)
{
TVector2 temp;
temp.x=a.x-b.x;
temp.y=a.y-b.y;
return temp;
}
//--------------------------------------------------------------------


TVector2 V2Mul(TVector2 a, long double b)
{
TVector2 temp;
temp.x=b*a.x;
temp.y=b*a.y;
return temp;
}
//--------------------------------------------------------------------

TVector2 V2Div(TVector2 a,long double b)
{
TVector2 temp;
if (b!=0)
{
temp.x=a.x/b;
temp.y=a.y/b;
}
else
{
temp.x=0.001;
temp.y=0.001;
}
return temp;
}

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


TVector2 V2Perp(TVector2 temp)
{
return V2(-temp.x,temp.x);
}

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


long double V2Dot (TVector2 a, TVector2 b)
{
long double temp=(a.x*b.x)+(a.y*b.y);
return temp;
}
//--------------------------------------------------------------------

long double V2PerpDot(TVector2 a, TVector2 b)
{
long double temp=(a.x*b.y)-(a.y*b.x);
return temp;

}
//--------------------------------------------------------------------

TVector2 V2Negative(TVector2 a)
{
return V2(-a.x,-a.y);
}
//--------------------------------------------------------------------

TVector2 V2Normalize(TVector2 a)
{
TVector2 temp;
long double d;
if (abs(a.x)<0.0001)
if (abs(a.y)<=0.0001)
{
return V2(0,0);
}
{
d=1.0/sqrt(pow(a.x,2)+pow(a.y,2));
return V2(d*a.x,d*a.y);
}


}

//--------------------------------------------------------------------
TVector2 V2Rotate(TVector2 a,TVector2 b)
{
TVector2 temp;
temp.x=a.x*b.x-a.y*b.y;
temp.y=a.x*b.y+a.y*b.x;
return temp;
}
//--------------------------------------------------------------------
void Poly_Init(int no)
{
TVector2 a,b;
int i,j;

//подсчитываем нормаль и скаляр к ребрам
for (i=0;i<=Object[no].poly.m_v-1;i++)
{
a=Object[no].poly.v_base[i];
if (i!=Object[no].poly.m_v-1)
b=Object[no].poly.v_base[i+1];
else
b=Object[no].poly.v_base[0];

Object[no].poly.ed_base[i].n=V2Normalize(V2Perp(V2Sub(b,a)));
Object[no].poly.ed_base[i].d=V2Dot(Object[no].poly.ed_base[i].n,a);

//Нужно как то присоединить форму к телу??????????????????
}

// Object[no].lShapes++;
// Object[no].shapes[Object[no].lShapes]->Shape=
// Object[no].shapes[Object[no].lShapes]->_type=shape_poly;

Poly_Update(no);
}
//--------------------------------------------------------------------
void Poly_Update(int no)
{
int i;

Object[no].poly.rot=V2(cos(Object[no].angle),sin(Object[no].angle));

//Находим мировые координаты вершин

for (i=0;i<=Object[no].poly.m_v-1;i++)
{
Object[no].poly.v[i]=V2Add(Object[no].possition,V2Rotate(Object[no].poly.v_base[i],Object[no].poly.rot));
}
//нормаль и скаляр для ребер

for (i=0;i<=Object[no].poly.m_v-1;i++)
{
Object[no].poly.ed[i].n=V2Rotate(Object[no].poly.ed_base[i].n,Object[no].poly.rot);
Object[no].poly.ed[i].d=V2Dot(Object[no].possition,Object[no].poly.ed[i].n)+Object[no].poly.ed_base[i].d;
}

}

//----------------------------------------------------------------------------
void Body_Update(int no,TVector2 gravity,long double dt)
{
Object[no].velocity=V2Add(Object[no].velocity,V2Mul(gravity,dt)); //гравитация ууууу
Object[no].angle=Object[no].angle+Object[no].w*dt; // угол поворота
Object[no].possition=V2Add(Object[no].possition,V2Mul(Object[no].velocity,dt));// позиция тела


//обновляем

Poly_Update(no);

}

long double min(long double a,long double b)
{
if (a>b)
return b;
else
return a;
}

double Poly_EdgeDist(TPoly &poly,TVector2 &n,double &d)
{
double _m=V2Dot(n,poly.v[0]);
int i;

for (i=1;i<=poly.m_v-1;i++)
{
_m=min(_m,V2Dot(n,poly.v[i]));

}
return (_m-d); 


}

Poly_FindEdgeMinDist(TPoly &poly,TEdge ed[101],int &num,double &_m)
{
int i,_mi;
double __m,dist;

_mi=0;
__m=Poly_EdgeDist(poly,ed[0].n,ed[0].d);

if (__m>0)
{
return -1;

}

for (i=1;i<=num-1;i++)
{

dist=Poly_EdgeDist(poly,ed[i].n,ed[i].d);
if (dist>0)
return -1;
else
if (dist>__m)
__m=dist;
_mi=i;

}

_m=__m;
return _mi;
}

bool Poly_PointIn(TPoly &poly,TVector2 &p)
{
int i;
double dist;

for (i=0;i<=poly.m_v-1;i++)
{
dist=V2Dot(poly.ed[i].n,p)-poly.ed[i].d;
if (dist>0)
return false;
}
return true;
}

double max(double a,double b)
{
if (a>b)
return a;
else
return b;

}
void Body_ApplyImpulse(int no,TVector2 &j,TVector2 &r)
{

TVector2 qq=V2Div(j,Object[no].m);


Object[no].velocity=V2Add(Object[no].velocity,qq);
Object[no].w=Object[no].w+V2PerpDot(r,j)/Object[no].i;

}


void Contact_Solve(int no1,int no2,TContact &c)
{
TVector2 v1,v2,vr,t,j;
double vrn, jn, jnOld,bounce,e,u,mass_sum;
double r1cn,r2cn,vrt,nMass,jtMax,jt,jtOld;
double r1ct,r2ct,kt,tMass,jnAcc,jtAcc;
double kn;
e=Object[no1].e*Object[no2].e;
u=Object[no1].f*Object[no2].f;

jtAcc=0.0;
jnAcc=0.0;
v1=V2Add(Object[no1].velocity,V2Mul(V2Perp(c.r1),Object[no1].w));
v1=V2Add(Object[no2].velocity,V2Mul(V2Perp(c.r2),Object[no2].w));

vr=V2Sub(v2,v1);
vrn=V2Dot(vr,c.n);

bounce=V2Dot(c.n,V2Sub(v2,v1))*e;
mass_sum=1/Object[no1].m+1/Object[no2].m;

r1cn=V2PerpDot(c.r1,c.n);
r2cn=V2PerpDot(c.r2,c.n);

kn=mass_sum+r1cn*r1cn/Object[no1].i+r2cn*r2cn/Object[no2].i;

if (kn!=0)
nMass=1.0/kn;
else
nMass=0.001;
jn=-(bounce+vrn)*nMass;
jnOld=jnAcc;
jnAcc=max(jnOld+jn,0.0);
jn=jnAcc-jnOld;

t=V2Perp(c.n);
vrt=V2Dot(vr,t);
t=V2Perp(c.n);

r1ct=V2PerpDot(c.r1,t);
r2ct=V2PerpDot(c.r2,t);

kt=mass_sum+r1ct*r1ct/Object[no1].i+r2ct*r2ct/Object[no2].i;

if (kt!=0)
tMass=1.0/kt;
else
tMass=0.001;

//трение
jtMax=u*jnAcc;
jt=-vrt*tMass;
jtOld=jtAcc;
jtAcc=min(max(jtOld+jt,-jtMax),jtMax);

//накладываем импульс

Body_ApplyImpulse(no1,V2Negative(j),c.r1);
Body_ApplyImpulse(no2,j,c.r2);

}

void Poly_VertsProc(TPoly &p1,TPoly &p2,TVector2 &n,double &d,int no1,int no2)
{
int i;
TContact c;
double k;
bool b;

d=abs(d);

for (i=0;i<=p1.m_v-1;i++)
if (Poly_PointIn(p2,p1.v[i]))
{
c.p=p1.v[i];
c.n=n;
c.Depth=d*c_Depth;
c.r1=V2Sub(c.p,Object[no1].possition);
c.r2=V2Sub(c.p,Object[no2].possition);

if (Object[no1]._static)
{
k=0;
}
else
{
if (Object[no2]._static)
k=1;
else
k=0.5;
}

Object[no1].possition=V2Sub(Object[no1].possition,V2Mul(c.n,k*c.Depth));
Object[no2].possition=V2Sub(Object[no2].possition,V2Mul(c.n,(1-k)*c.Depth));

Contact_Solve(no1,no2,c);
}


for (i=0;i<=p2.m_v-1;i++)
if (Poly_PointIn(p1,p2.v[i]))
{
c.p=p2.v[i];
c.n=n;
c.Depth=d*c_Depth;
c.r1=V2Sub(c.p,Object[no1].possition);
c.r2=V2Sub(c.p,Object[no2].possition);

if (Object[no1]._static)
{
k=0;
}
else
{
if (Object[no2]._static)
k=-1;
else
k=0.5;
}
Object[no1].possition=V2Sub(Object[no1].possition,V2Mul(c.n,k*c.Depth));
Object[no2].possition=V2Sub(Object[no2].possition,V2Mul(c.n,(1-k)*c.Depth));

Contact_Solve(no1,no2,c);
}


}
bool Poly_FindCollision(TPoly &p1,TPoly &p2,int no1,int no2)//TPoly p1,TPoly p2)
{
int i,j;
TContact c;
TVector2 a1,a2,b1,b2,colp;
double k;
double min1,min2;
int min1_idx,min2_idx;
bool Boo;

min1_idx = Poly_FindEdgeMinDist(p2, p1.ed, p1.m_v, min1);
if (min1_idx == -1)
{

return false;
}
min2_idx = Poly_FindEdgeMinDist(p1, p2.ed, p2.m_v, min2);
if (min2_idx == -1)
return false;



if (min1 > min2)
Poly_VertsProc(p1,p2,p1.ed[min1_idx].n,min1,no1,no2);
else
Poly_VertsProc(p1,p2,V2Negative(p2.ed[min2_idx].n),min2,no1,no2);



return true;
}
bool Body_Collide(int no1,int no2)
{
return Poly_FindCollision(Object[no1].poly,Object[no1].poly,no1,no2);

}