.[ ČeskéHry.cz ].
Ray - Sphere kolize
Jdi na stránku 1, 2  Další
 
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Fyzikální modely
Zobrazit předchozí téma :: Zobrazit následující téma  
Autor Zpráva
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 23. duben 2011, 18:09:15    Předmět: Ray - Sphere kolize Odpovědět s citátem

Hare,
přejdu rovnou ke kodu, funkce kodu je takova ze nefunguje Very Happy, myslim ze tam posilam blby vstupy jenom nemuzu furt dojit na to co mi to dela :X

tady chyba nebude, myslim
kód:
bool IntersectsRaySphere(vec3 p, vec3 d, vec3 cntr, float r, vec3 & intersect)
{
   vec3 m = p - cntr;   
   float b = Dot(m, d);
   float c = Dot(m, m) - r * r;

   if(c > 0.0f && b > 0.0f) return false;
   float discr = b * b - c;
   if(discr < 0.0f) return false;
   
   float t = -b - sqrt(discr);
   if(t < 0.0f) t = 0.0;
   intersect = p + t * d;
   return true;
}


Vytvorim paprsek, start - startovni pozice paprsku -> end startovni pozice + direkce kamery * 10000 - paprsek o nejakejch 10000.0f daleko od kamery

kód:
void Bullet::Fire()
{
    if(iCurrBullet>= 60) iCurrBullet= 0; else iCurrBullet++;
    bullet[iCurrBullet].start = camera.GetPosition();
    bullet[iCurrBullet].end = camera.GetPosition() + camera.GetCameraDirection() * 10000.0;
}


a ve finale to profrcim cyklem a ocekuju vsechny paprsky na prusecik s kouli pomoci IntersectsRaySphere, jenze problem je ten, ze se mi stava ze mam kolizi uplne vsude ..


kód:
   
for(int index = 0; index < 60; i++)
{
if(IntersectsRaySphere(bullet[index].start, bullet[index].end, center, radius, intersect))
    {
         bullet[index].collided = true;
         bullet[index].collPoints[0] = bullet[index].start;
         bullet[index].collPoints[1] = intersect;
    }   
}



Predem rikam ze mi tuhle matiku moc hlava nebere a mozna sem nepochopil princip Very Happy
Nic, konec.

Dikec ;D
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Peto



Založen: 01. 08. 2007
Příspěvky: 206
Bydliště: Košice

PříspěvekZaslal: 23. duben 2011, 18:19:41    Předmět: Odpovědět s citátem

Hoj..

Nepozeral som detialne na algorytmus tej kolizie.. ale vyzera to tak ze vstupom je nie ray zadany zaciatocnym a koncovym bodom.. ale bodom a smerovym vektorom.. Wink.. aspon podla nazvov argumentov funkcie

p - position
d - direction

takze bullet.end by asi mal byt skor.. bullet.dir = camera.GetCameraDirection() ... za pokus to stoji Smile
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 23. duben 2011, 18:28:34    Předmět: Odpovědět s citátem

jsem zmaten, dneska sem se dal do rewrite protoze puvodne jsem mel ray.positon - prvni pozice paprsku a ray.direction - cista direkce kamery tak jak pises ty WATAFA? Kazdopadne ani tak to nefungovalo ..
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 23. duben 2011, 18:58:44    Předmět: Odpovědět s citátem

Možná, že je to to samé, na to jsem nekoukal. Takhle to mám udělané já a funguje to. Jen mám za to, že vektor d musí být jednotkový...

kód:
bool IntersectsRaySphere(vec3 p, vec3 d, vec3 cntr, float r, vec3 & intersect)
 {
    vec3 diff = cntr - p;
    float sqrDist = Dot(diff, diff);
    float vDot = Dot(diff, d);

    if (vDot >= 0.0f)
    {
          float dP = r*r - sqrDist + vDot*vDot;
          if (dP < 0.0f) { return false; }
          float t = vDot - sqrt(dP);
          intersect = p + d*t;
          return true;
     }
     return false;
 }

_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 23. duben 2011, 19:03:10    Předmět: Odpovědět s citátem

je to dost mozny, funkce je z googlebooku , kazdopadne ten druhej parametr nemam jendotkovej, omrknu
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 23. duben 2011, 21:02:00    Předmět: Odpovědět s citátem

Takže podle mých výpočtů musí být směr paprsku jednotkový vektor. Musím si to napsat do dokumentačních komentářů... Wink
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 23. duben 2011, 22:30:46    Předmět: Odpovědět s citátem

Mno, sec... podívám se do mojí obří ray-tracing knihovny...

máš to napsané celkem hrozivým způsobem (tolik parameterů ti to dost zpomalí, navíc mi přijde ten kód divný.

Já používám toto (pro mono-tracing, asi nejoptimálnější co můžeš dostat pro mono-tracing, v packet-tracingu to zemře na větvích, tam musíš maskovat):
kód:

IntersectResult Sphere::Intersect(const Ray &r)
{
  IntersectResult ret_val = IntersectResult();

  Vector rayToSphere = this->center - r.origin;
  float rayToSphereLength = Dot(rayToSphere, rayToSphere);
  float intersectPoint = Dot(rayToSphere, r.direction);
       
  if(intersectPoint < 0.0f)
    return ret_val;
       
  float squaredPoint = (this->radius * this->radius) - rayToSphereLength + (intersectPoint * intersectPoint);
       
  if(squaredPoint < 0.0f)
    return ret_val;
       
  ret_val.distance = intersectPoint - sqrtf(squaredPoint);
  return ret_val;
}


Pozn! Vždy vracej vzdálenost a nikdy ne celou pozici, ušetří ti to spousty operací. Jo, možná ti přijde, že tam neukládám zda strefil - je tam trošku bitové magie (pouze kladná vzdálenost trefi) - alignment 8-byte structu IntersectResult (obsahuje vzdálenost a ID objektu - nastavený v traversalu) je pro cache mnohem lepší než 9-byte.

Pro packet tracing používám branch-less proceduru (je trošku těžší pro procesor, ale celkový výkon je pro KOHERENTNÍ Exclamation polopřímky vyšší, v praxi u path-tracingu nejsou koherentní nikdy, u ray tracingu pouze primární a výjimečně sekundární).

Nicméně tvůj ray-cast traversal je taky špatný. Ty hledáš nejbližší hitpoint, nikoliv každý (pokud nechceš prostřelovat). Zpravidla ray-cast algoritmus pro střely ve hře vypadá takto (za předpokladu že vše máme v bounding spheres):
kód:

IntersectResult FindHit()
{
  IntersectResult ret_val = IntersectResult(INFINITY);
  IntersectResult temp_val = IntersectResult();

  for(int i = 0; i < Rays_num; i++)
  {
    for(int j = 0; j < Spheres_num; j++)
    {
      temp_val = Sphere[j].Intersect(Ray[i]);

      if(temp_val.Hit() && temp_val.distance < ret_val.distance)
      {
          ret_val = temp_val;
          ret_val.id = j;
      }
    }
  }

  return ret_val.distance == INFINITY ? IntersectResult() : ret_val;
}


Snad to vypadá srozumitelně, jestli ne - ptej se.

EDIT: Ve skutečnosti by se ten traversal dal optimalizovat - např. přístup Sphere[j].Intersect(Ray[i]) je docela dost náročný...
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 24. duben 2011, 09:28:11    Předmět: Odpovědět s citátem

Vilem Otte: Kdyz sem uvidel ten tvuj koment, tak mi spadla brada Very Happy

kazdopadne, doprepsal jsem to + jsem pouzil tvuj kod ale furt to nefunguje jak ma, obcas mi to hitne i jinde nez kde je koule. -> http://nopaste.ceske-hry.cz/223305 , doufam ze jsem si to prepsal spravne podle tvych komentu - distanc si nikam neposilam protoze me zatim zajima jenom to jestli sem zasahl nebo ne.

Hlavni problem bude ve vypoctu myho direkcniho vektoru, jelikoz at googlim jak googlim lepsi variantu sem zatim nenasel ale ->


kód:
vec3 Camera::GetCameraDirection()
{
    vec3 dir;
    dir.x = -sin(DegreesToRadians(camAngle.y));
    dir.y = -tan(DegreesToRadians(-camAngle.x)); // - pri debugu dostavam hodnoty pri uhlu > +-60 vetsi nez 1.0 jakmile je uhel okolo 80 tak je tam nejakych 57.0 z cehoz usuzuju ze tady bude problem, kdyz direkce ma bejt jednotkova
    dir.z =  cos(DegreesToRadians(camAngle.y));     
    return dir;
}


jiny gon. fce jsem zkousel ale vzdycky to nefungovalo tak jako s tim -tg(), uz se zacinam dostavat do slepe ulicky.
Nejaky napad?
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Poky



Založen: 29. 06. 2009
Příspěvky: 184
Bydliště: Písek / Plzeň

PříspěvekZaslal: 24. duben 2011, 10:40:43    Předmět: Odpovědět s citátem

Pro kameru bych doporučil používat [url=http://cs.wikipedia.org/wiki/Sférická_soustava_souřadnic]sférické souřadnice[/url]
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 24. duben 2011, 11:01:39    Předmět: Odpovědět s citátem

Pokud máš jednotkovou kouli a znáš tam úhly alpha a beta (viz. obrázek) můžeš "pohledový" vektor spočítat takhle:

kód:
x = cos(alpha) * cos(beta);
y = sin(alpha) * cos(beta);
z = sin(beta);


Obrázek (snad je to pochopitelné):

_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 24. duben 2011, 12:03:55    Předmět: Odpovědět s citátem

Diky, uz sem to vycucnul z modelview matice, ale problem to neporesilo. WTF? ňákej magickej kod toto.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 24. duben 2011, 12:27:44    Předmět: Odpovědět s citátem

Nevím jak máš psanou cameru, ale pokud máś lookat pozici a camera origin pozici, tak jako ray-origin dosadíš camera origin a direkční vektor střely bude Normalize(camera_lookat - camera_origin).

Nicméně další možnost (možná lepší) je vygenerovat základní direkční vektor (0, 0, 1) a rotovat jej přes matici.
Vytvoříš rotační matici pro Y a rotační matici pro X, vynásobíš Y * X a výsledkem transformuješ základní direkční vektor. Toto je mimochodem jedna z metod pro kameru v ray-traceru (výpočet směrů primárních polopřímek).
Půjde to i bez matic, ale nebude to tak jednoduchý kód (navíc odladěný bude cca stejně rychlý).
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
VODA



Založen: 29. 07. 2007
Příspěvky: 1721
Bydliště: Plzeň

PříspěvekZaslal: 24. duben 2011, 13:03:07    Předmět: Odpovědět s citátem

Koukal jsem ještě na ten Tvůj kód na začátku a napadá mě, resetuješ také vůbec atribut collided (tj. nastavit na false). Kdyby ne, tak by to pak vše vysvětlovalo...ale nechci Tě podceňovat... Wink
_________________
Opravdovost se pojí s trýzní...
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Játro.m



Založen: 01. 02. 2010
Příspěvky: 230

PříspěvekZaslal: 24. duben 2011, 13:16:20    Předmět: Odpovědět s citátem

Vilem: kameru mam rotovanou klasicky pres uhly pomoci glRotatef + glTranslatef na pohyb, zadny gluLookat. Spis si myslim ze ta bota musi byt nekde v tom koliznim kodu, kdyz si to zrekapituluju co tam dosazuju tak:

ray origin -> aktualni pozice kamery
ray direction -> jednotkovej vektor kamery
center ->klasicka pozice koule
radius tj snad jasny

a jelikoz na kolizi pouzivam tu tvoji funkci ktera by mela byt overena tak uz nevidim problem proc to nefunguje jak ma. Kdyz jsem jeste zkousel kde se ta kolizni funkce ukonci tak je to vetsinou ze je squaredPoint < 0.0, nikdy se nepodari dojit az ke konci ikdyz vim ze strilim primo do koule..

Voda: ta booleanka je zezacatku nastavena na false jakmile koliduju tak na true a podle toho si jenom vykleslim linku kde byl prunik abych videl jak to funguje a takhle furt dokola, takze tady by problem byt nemel.
BTW toto je aktualnejsi kod nez to nahore
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu
Vilem Otte



Založen: 18. 09. 2007
Příspěvky: 462
Bydliště: Znojmo - Sedlesovice, Kravi Hora

PříspěvekZaslal: 24. duben 2011, 14:02:05    Předmět: Odpovědět s citátem

citace:
a jelikoz na kolizi pouzivam tu tvoji funkci ktera by mela byt overena tak uz nevidim problem proc to nefunguje jak ma. Kdyz jsem jeste zkousel kde se ta kolizni funkce ukonci tak je to vetsinou ze je squaredPoint < 0.0, nikdy se nepodari dojit az ke konci ikdyz vim ze strilim primo do koule..

To mi pripada jako bys mel obraceny nejaky smer, v ray direction... jinak co píšeš (popisky, ty jsou správně).

Kód, který jsem posílal určitě špatně není, používám ho už dlouhou dobu (a teď třeba zrovna s ním pracuju) a funguje správně.
_________________
Should array indices start at 0 or 1? My compromise of 0.5 was rejected without, I thought, proper consideration.
Návrat nahoru
Zobrazit informace o autorovi Odeslat soukromou zprávu Odeslat e-mail Zobrazit autorovi WWW stránky
Zobrazit příspěvky z předchozích:   
odeslat nové téma   Odpovědět na téma    Obsah fóra České-Hry.cz -> Fyzikální modely Časy uváděny v GMT + 1 hodina
Jdi na stránku 1, 2  Další
Strana 1 z 2

 
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