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
|
Zaslal: 23. duben 2011, 18:09:15 Předmět: Ray - Sphere kolize |
|
|
Hare,
přejdu rovnou ke kodu, funkce kodu je takova ze nefunguje , 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
Nic, konec.
Dikec ;D |
|
Návrat nahoru |
|
 |
Peto

Založen: 01. 08. 2007 Příspěvky: 206 Bydliště: Košice
|
Zaslal: 23. duben 2011, 18:19:41 Předmět: |
|
|
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.. .. 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  |
|
Návrat nahoru |
|
 |
Játro.m
Založen: 01. 02. 2010 Příspěvky: 230
|
Zaslal: 23. duben 2011, 18:28:34 Předmět: |
|
|
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 |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 23. duben 2011, 18:58:44 Předmět: |
|
|
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 |
|
 |
Játro.m
Založen: 01. 02. 2010 Příspěvky: 230
|
Zaslal: 23. duben 2011, 19:03:10 Předmět: |
|
|
je to dost mozny, funkce je z googlebooku , kazdopadne ten druhej parametr nemam jendotkovej, omrknu |
|
Návrat nahoru |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 23. duben 2011, 21:02:00 Předmět: |
|
|
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ářů...  _________________ Opravdovost se pojí s trýzní... |
|
Návrat nahoru |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 23. duben 2011, 22:30:46 Předmět: |
|
|
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Í 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 |
|
 |
Játro.m
Založen: 01. 02. 2010 Příspěvky: 230
|
Zaslal: 24. duben 2011, 09:28:11 Předmět: |
|
|
Vilem Otte: Kdyz sem uvidel ten tvuj koment, tak mi spadla brada
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 |
|
 |
Poky

Založen: 29. 06. 2009 Příspěvky: 184 Bydliště: Písek / Plzeň
|
Zaslal: 24. duben 2011, 10:40:43 Předmět: |
|
|
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 |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 24. duben 2011, 11:01:39 Předmět: |
|
|
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 |
|
 |
Játro.m
Založen: 01. 02. 2010 Příspěvky: 230
|
Zaslal: 24. duben 2011, 12:03:55 Předmět: |
|
|
Diky, uz sem to vycucnul z modelview matice, ale problem to neporesilo. WTF? ňákej magickej kod toto. |
|
Návrat nahoru |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 24. duben 2011, 12:27:44 Předmět: |
|
|
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 |
|
 |
VODA

Založen: 29. 07. 2007 Příspěvky: 1721 Bydliště: Plzeň
|
Zaslal: 24. duben 2011, 13:03:07 Předmět: |
|
|
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...  _________________ Opravdovost se pojí s trýzní... |
|
Návrat nahoru |
|
 |
Játro.m
Založen: 01. 02. 2010 Příspěvky: 230
|
Zaslal: 24. duben 2011, 13:16:20 Předmět: |
|
|
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 |
|
 |
Vilem Otte

Založen: 18. 09. 2007 Příspěvky: 462 Bydliště: Znojmo - Sedlesovice, Kravi Hora
|
Zaslal: 24. duben 2011, 14:02:05 Předmět: |
|
|
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 |
|
 |
|