1. Получи 30.000 рублей. Для получения денег необходимо принять участие в конкурсе авторов codeby. С условиями и призами можно ознакомиться на этой странице ...

    Внимание! Регистрация авторов на конкурс закрыта.

    Скрыть объявление
  2. Требуются разработчики и тестеры для проекта codebyOS. Требования для участия в проекте: Знание принципов работы ОС на базе Linux; Знание Bash; Крайне желательное знание CPP, Python, Lua; Навыки системного администрирования. Подробнее ...

    Скрыть объявление

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

Тема в разделе "С и С++", создана пользователем fromtuba, 18 мар 2010.

  1. fromtuba

    fromtuba Гость

    Репутация:
    0
    Здравствуйте Все!
    В недавнем времени понадобился 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);
    
    }
     
Загрузка...
Похожие Темы - Проблема перевода физ
  1. Apton
    Ответов:
    0
    Просмотров:
    38
  2. Anonimyc
    Ответов:
    0
    Просмотров:
    25
  3. VikTor1990
    Ответов:
    3
    Просмотров:
    80
  4. erlan1749
    Ответов:
    0
    Просмотров:
    37
  5. ivannnn
    Ответов:
    0
    Просмотров:
    56

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