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

Тема в разделе "Borland C++ Builder & Kylix", создана пользователем fromtuba, 18 мар 2010.

  1. fromtuba

    fromtuba Гость

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


    #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
    Код (Text):
    //---------------------------------------------------------------------------

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

    }
     
Загрузка...
Похожие Темы - Проблема перевода физ
  1. AgniXRudra
    Ответов:
    2
    Просмотров:
    52
  2. Zloikaktus
    Ответов:
    0
    Просмотров:
    30
  3. c0de3r
    Ответов:
    5
    Просмотров:
    153
  4. DobermannTT
    Ответов:
    10
    Просмотров:
    158
  5. SoulPaladin
    Ответов:
    4
    Просмотров:
    144

Поделиться этой страницей