.[ ČeskéHry.cz ].
pohyb objektu a jeho natoceni po trajektorii

 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Lazaroz



Založen: 06. 09. 2007
Příspěvky: 11

PříspěvekZaslal: 6. září 2007, 15:25:03    Předmět: pohyb objektu a jeho natoceni po trajektorii Odpovědět s citátem

zdravim chci se optat jak vyresit problem s natáčením objektu po určité trajektorii objekt natáčím pomocí translate v opengl .Jde mě oto,že objektu nastavím waypointy kam se má pohybovat ,to mě funguje,ale horší je to už s tím,jak objekt natočím pomocí translací ve směru waypointu .Každy waypoint má souřadnice a vektor takže jsem zkusil vypočítat úhel mezi dvěma vektory ale to je blbost protože nezjistím jestli je ten úhel kladný nebo záporný,takže se mi otáčí objekt sice o spravnou velikost uhlu ale ne už ve správném směru čili když se třebas objekt pohybuje dopředu tak má čumák dozadu atd jeslti mě chápete .díky za každou radu
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lando



Založen: 29. 07. 2007
Příspěvky: 33
Bydliště: Cestice

PříspěvekZaslal: 6. září 2007, 15:50:35    Předmět: Odpovědět s citátem

Zkusil bych to asi tak, ze bych vzal vektor kterym se ten objekt pohybuje. Potom vytvoril pravy vektor operaci cross s nejakym docasnym up vektorem (0,1,0 nebo 0,0,1, podle toho "kde je nahore") Dalsi cross praveho vektoru a vektoru pohybu potom da posledni vektor. Tyto tri navzajem pravouhle vektory potom naskladane (po sloupcich?) do matice daji rotacni matici.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lazaroz



Založen: 06. 09. 2007
Příspěvky: 11

PříspěvekZaslal: 6. září 2007, 16:15:56    Předmět: Odpovědět s citátem

Lando napsal:
Zkusil bych to asi tak, ze bych vzal vektor kterym se ten objekt pohybuje. Potom vytvoril pravy vektor operaci cross s nejakym docasnym up vektorem (0,1,0 nebo 0,0,1, podle toho "kde je nahore") Dalsi cross praveho vektoru a vektoru pohybu potom da posledni vektor. Tyto tri navzajem pravouhle vektory potom naskladane (po sloupcich?) do matice daji rotacni matici.

asi to chapu cece dikec lando zkusim to a snad to pujde pokud nekdo ma jeste jiny zpusob tak sem snim cim vic jich bude tim lip
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
ladik-BigBoss



Založen: 28. 07. 2007
Příspěvky: 162

PříspěvekZaslal: 8. září 2007, 00:53:22    Předmět: Odpovědět s citátem

ja bych ty uhly mezi sebou linearne interpoloval;
asi nejlepsi by bylo uzit quaterniony, ale tem nerozumim
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
pcmaster



Založen: 28. 07. 2007
Příspěvky: 1824

PříspěvekZaslal: 8. září 2007, 01:13:59    Předmět: Odpovědět s citátem

ak to chces kvaternionmi, musis si nastudovat nieco o nich a potom o SLERP (Spherical Linear intERPolation). A mozno aj nie Smile
Slerp funguje tak, ze do nej narves kvaternion1 (rotaciu1) a kvaternion2 (rotaciu2) a parameter t z intervalu <0,1>. A vypluje to na teba vysledny kvaternion.
V skratke: kvaternion je normalny 4D vektor (v nasom pripade jednotkovy). Reprezentuje rotaciu. Vsetky taketo jednotkove kvaterniony tvoria povrch jednotkovej hyper-gule (dokonca 2x, ale to je nepodstatne). SLERP robi to, ze vyberie bod na obluku na tejto 4D guli, na obluku, ktory zacina v bode kvaternion1 (parameter t=0) a konci v bode kvaternion2 (t=1). Viz literatura. V podstate to pri rovnomernej zmene t od 0 do 1 a naslednej aplikacii vysledneho kvaternionu napr. na nejaky vektore, tento vektor otaca pekne rovnomerne po najkratsej krivke.

Pre teba je dolezite vyrobit kvaternion1 a kvaternion2. Pozri do literatury, ale v skratke:
Kvaternion je stvorica (w,x,y,z), pripadne dvojica (w, V). Potom:
citace:
Kvaternion(os3D, uhol) = (cos(uhol/2), os3D*sin(uhol/2))


Tiez ho mozes vyrobit z rotacnej matice alebo z eulerovych uhlov.

Viac sa mi vysvetlovat nechce, po statniciach tu zverejnim moju bakalarsku pracu, kde uvadzam mimo ineho dost odkazov na literaturu a tieto velmi zname postupy aj strucne polopaticky opisujem (aby som mal dost stran Very Happy).

(Odpuste mnohe matematicke nezrovnalosti, mam plnu hlavu superskalarnych architektur a inych kokotin na statnice a myslim, ze to na informacnej hodnote neuskodi.)
_________________
Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Peta



Založen: 28. 07. 2007
Příspěvky: 154
Bydliště: V prvnim patre hned vedle koupelny.

PříspěvekZaslal: 8. září 2007, 09:54:50    Předmět: Odpovědět s citátem

Jestli to dobře chápu, tak jediné co potřebuješ je, aby se model "díval" směrem kterým jede. Imho to řešit nějakýmy kvaterniony je trochu moc drsný. Já jsem to v jedné své hře vyřešil jednoduše:

Protože pohyb se koná víceméně po rovine, počítal jsem si vždy jen úhly na rovine XZ - prostě z dvou bodu (modelX,modelY) a (cilX,cilY) jsem vypocital vektor, ze ktereho mi vyplynul uhel (napriklad pokud je cil primo pred modelem tak je uhel 0, pokud je za nim tak 180 atd). Z toho jsem mel cilovy uhel natoceni modelu. Aktualni uhel modelu na rovine XZ je "uhelH" (jako "horizontalni uhel", pak ma jeste uhelV, tedy vertikalni uhel). Nasledne staci proste menit uhelH v kazdem framu dokud nebude roven "cilovemu uhlu" - vsimneme si ze pokud model jede, cilovy uhel se porad meni, ale to je osetreno tim ze se cilovy uhel neustale prepocitava.

Kód pro výpočet jakým směrem se má koukat model:

(uhel)
kód:

double Enemy::GetDirToTarget(double pX, double pZ, double tX, double tZ)
{

   double result, protilehla, prepona;

   if ((pX - tX) > 0 && (pZ - tZ) > 0)
   {
      // 1. kvadrant, + 0, X protilehla
      protilehla = pX - tX;
      prepona = sqrt((pX - tX)*(pX - tX) + (pZ - tZ)*(pZ - tZ));
      result = asin(protilehla / prepona) * (180/PI);
   }
   else if ((pX - tX) > 0 && (pZ - tZ) < 0)
   {
      // 2. kvadrant, + 90, Z protilehla
      protilehla = tZ - pZ;
      prepona = sqrt((pX - tX)*(pX - tX) + (pZ - tZ)*(pZ - tZ));
      result = asin(protilehla / prepona) * (180/PI) + 90;
   }
   else if ((pX - tX) < 0 && (pZ - tZ) < 0)
   {
      // 3. kvadrant, + 180, X protilehla
      protilehla = tX - pX;
      prepona = sqrt((pX - tX)*(pX - tX) + (pZ - tZ)*(pZ - tZ));
      result = asin(protilehla / prepona) * (180/PI) + 180;
   }
   else
   {
      // 4. kvadrant, + 270, Z protilehla
      protilehla = pZ - tZ;
      prepona = sqrt((pX - tX)*(pX - tX) + (pZ - tZ)*(pZ - tZ));
      result = asin(protilehla / prepona) * (180/PI) + 270;
   }
   
   //result = result % 360;

   return result;

   return 0.0;
}


uhel k cili a jeho zmena:

kód:

bool Enemy::RotateToTarget(int who, double targetX, double targetZ)
{
   double uhelCil = GetDirToTarget(targetX, targetZ, enemInfo[who].x, enemInfo[who].z);

   if (abs(uhelCil - enemInfo[who].angleH) > 3)
   {
      if (uhelCil > enemInfo[who].angleH)
      {
         if (abs(uhelCil - enemInfo[who].angleH) > 180)
         {
            enemInfo[who].angleH -= 40 * Hra->delay;
         }
         else
         {
            enemInfo[who].angleH += 40 * Hra->delay;
         }
      }
      else
      {
         if (abs(uhelCil - enemInfo[who].angleH) > 180)
         {
            enemInfo[who].angleH += 40 * Hra->delay;
         }
         else
         {
            enemInfo[who].angleH -= 40 * Hra->delay;
         }
      }

      if (enemInfo[who].angleH > 360)
      enemInfo[who].angleH -= 360;

      if (enemInfo[who].angleH < 0)
         enemInfo[who].angleH += 360;

   }
   
   if (abs(uhelCil - enemInfo[who].angleH) < 25)
      return true;
   else
      return false;
}


A samotné vykreslení:

kód:

void Enemy::Draw(int who)
{
   int k;

   k = enemInfo[who].modelType;
   
   glPushMatrix();

      glEnable(GL_ALPHA_TEST);
      glAlphaFunc(GL_GREATER, 0.1f);

      glBindTexture(GL_TEXTURE_2D, enemTex[k].texID);

      glTranslated(enemInfo[who].x, enemInfo[who].y + enemInfo[who].elevation, enemInfo[who].z);
      glRotated(enemInfo[who].angleH, 0.0, 1.0, 0.0);
      glmDraw(enemUniq[k], GLM_FLAT | GLM_TEXTURE);

      glDisable(GL_ALPHA_TEST);

   glPopMatrix();
}


Snad to trochu pomůže a snad je to aspoň k tématu.

To že je kód prasárna vím a je mi to jedno Smile[/code]
_________________
Když je Ti smutno, otoč se tváří ke slunci a všechny stíny padnou za Tebe.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
pcmaster



Založen: 28. 07. 2007
Příspěvky: 1824

PříspěvekZaslal: 8. září 2007, 13:33:56    Předmět: Odpovědět s citátem

Ale hej, preco by to tak nemohlo fungovat Smile Ja som len reagoval na ladika.
S kvaternionmi to vobec nie je zlozite. Ak mas predpripravene struktury pre kvaterniony a hotovu funkciu SLERP (3rd-party), tak peknu kameru a podobne mas implementovanu za 10 minut a nemusis sa srat so sinusmi a kosinusmi Smile
_________________
Off-topic flame-war addict since the very beginning. Registered since Oct. 2003!
Interproductum fimi omne est.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Marek



Založen: 28. 07. 2007
Příspěvky: 1782
Bydliště: Velká Morava

PříspěvekZaslal: 8. září 2007, 14:28:05    Předmět: Odpovědět s citátem

Quaterniony jsou tady asi nejvhodnejsi. Ono kdyz si z toho odstranite ten SLERP, tak to ma stejne vlastnosti jako 3x3 matice bez scale + je tu vyhoda, ze nasobek quaternionu nemeni rotaci (takze nemusi byt jednotkovy). Ten SLERP je na animace fakt nejlepsi, protoze pri interpolaci eulerovych uhlu tam mate gimbal lock (prvni uhel orotuje hlavni osy pred aplikaci druheho uhlu). Implementaci quaternionu se na netu vali hafo, takze neni problem jednu vzit a pouzit.
_________________
AMD Open Source Graphics Driver Developer
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Peta



Založen: 28. 07. 2007
Příspěvky: 154
Bydliště: V prvnim patre hned vedle koupelny.

PříspěvekZaslal: 8. září 2007, 15:49:10    Předmět: Odpovědět s citátem

To jo no - kazdopadne ja jsem prezentoval reseni vhodne pro trochu specialni pripad, tj pohyb vicemene po rovine, jestli to potrebuje pro obecnejsi pripad (tj uplny pohyb v prostoru) tak asi bude lepsi pouzit ty quaterniony.
_________________
Když je Ti smutno, otoč se tváří ke slunci a všechny stíny padnou za Tebe.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lazaroz



Založen: 06. 09. 2007
Příspěvky: 11

PříspěvekZaslal: 8. září 2007, 22:23:44    Předmět: Odpovědět s citátem

quateriony nebo co to je jsem zatim nak nestudoval pac me to prijde slozity na cloveka co nema vysku ale zkusil jsem tu prvni radu a poskladal jsem tu rotační matici ale pracuje to nak divne mrknete jestli sem to udelal spravne
kód:

RotateMatrix.m[0]=directionV.vx;
         RotateMatrix.m[4]=directionV.vy;
         RotateMatrix.m[8]=directionV.vz;
            C_VECTOR UP;
         C_VECTOR result;
         C_VECTOR result2;
         UP.Set(0,1,0);
            result=UP*directionV;
         RotateMatrix.m[1]=result.vx;
         RotateMatrix.m[5]=result.vy;
          RotateMatrix.m[9]=result.vz;
            result2=result*directionV;
         RotateMatrix.m[2]=result2.vx;
         RotateMatrix.m[6]=result2.vy;
         RotateMatrix.m[10]=result2.vz;
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lazaroz



Založen: 06. 09. 2007
Příspěvky: 11

PříspěvekZaslal: 17. září 2007, 12:55:26    Předmět: Odpovědět s citátem

tak metoda s naskladanim cross uhlu a nasledne sestaveni matice me nefunguje resp objekt se otáčí ale ne tak jak má asi jsem to blbě poskládal ,byl bych moc rad,kdyby tu někdo uveřejnil kus kodu třeba jak to udělat pomocí toho Quaternionu nebo jen pomocí matic díky moc
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Lazaroz



Založen: 06. 09. 2007
Příspěvky: 11

PříspěvekZaslal: 18. září 2007, 08:53:02    Předmět: Odpovědět s citátem

tak jsem konečně našel funkční kod ktery jsem si ttrošku upravil ale funguje!
kód:

C_VECTOR x_dir(0.0,0.0,1.0),y_dir;
C_VECTOR dir=directionV;
__int64 d=dir.vz;

if(d>-0.999999999 && d<0.999999999){ // to avoid problems with normalize in special cases
      x_dir=x_dir-dir*d;
      x_dir.Normalize();
      y_dir=dir.Cross(x_dir);
}else{
      x_dir=C_VECTOR(dir.vz,0,-dir.vx);
      y_dir=C_VECTOR(0,1,0);
};


// x_dir and y_dir is orthogonal to dir and to eachother.
// so, you can make matrix from x_dir, y_dir, and dir in whatever way you prefer.
// What to do depends to what API you use and where arrow model is pointing.
// this is matrix i use which may give starting point.
// this is for arrow that points in z direction (for arrow that points in x direction you may try swapping dir and x_dir)
   

   RotateMatrix.m[0]=x_dir.vx;
   RotateMatrix.m[1]=x_dir.vy;
   RotateMatrix.m[2]=x_dir.vz;
   RotateMatrix.m[3]=0.0;
   
   RotateMatrix.m[4]=y_dir.vx;
   RotateMatrix.m[5]=y_dir.vy;
   RotateMatrix.m[6]=y_dir.vz;
   RotateMatrix.m[7]=0.0;

    RotateMatrix.m[8]=dir.vx;
   RotateMatrix.m[9]=dir.vy;
   RotateMatrix.m[10]=dir.vz;
   RotateMatrix.m[11]=0.0;   

   RotateMatrix.m[12]=0;
   RotateMatrix.m[13]=0;
   RotateMatrix.m[14]=0;
   RotateMatrix.m[15]=1.0;
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Obecné Časy uváděny v GMT + 1 hodina
Strana 1 z 1

 
Přejdi na:  
Nemůžete odesílat nové téma do tohoto fóra
Nemůžete odpovídat na témata v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete hlasovat v tomto fóru


Powered by phpBB © 2001, 2005 phpBB Group


Vzhled udelal powermac
Styl "vykraden" z phpBB stylu MonkiDream - upraveno by rezna