Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: So Jul 13, 2025 19:01

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: Schüsse berechnen
BeitragVerfasst: Fr Jun 30, 2006 19:08 
Offline
DGL Member

Registriert: Sa Okt 22, 2005 20:24
Beiträge: 291
Wohnort: Frauenfeld/CH
Moin, ich bin schon lange am herumrätseln was wohl die beste methode wäre schüsse in OGL zu berechnen. Dabei weiss ich aber noch nich so genau wie ich das denn machen soll. GluUnProject hab ich mir scho angeschaut und durchgedacht. Ich bin mir allerdings nicht sicher ob dies die Lösung für dieses Problem ist.

Ich will nämlich einen schuss, der mit einem Richtungsvektor angegeben wird testen ob er den anderen Körper schneidet. Die Schüsse können daher als Geraden vom Startpunkt aus betrachtet werden. Das Ziel ist ein Objekt wie zb ein mensch. Dieser kann unter Umständen auch durch ein Rechteck angesehen werden, um das ganze leichter zu machen. Praktisch wäre es dann aber auch noch Oberkörper, Beine und Kopf berechnen zu können. also zb hat dann der kopf eine höhe von 0.8-1 und der oberkörper startet bei 0.5-0.8.

mfg Gaukler

_________________
bester uo-shard: www.uosigena.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Fr Jun 30, 2006 20:39 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Eine der einfachsten, eher schnellen Methoden ist wohl die Tiefe des Pixels auszulesen und mit gluUnProject die 3D-Koordinate zu berechnen. Danach musst du nur noch für alle Objekte prüfen ob dieser Punkt in ihrer Nähe ist (zB Bounding Sphere). Wenn du viele Objekte hast empfiehlt sich natürlich eine Einteilung in einen Octree oder ähnliches. Bringt sogar recht gute Ergebnisse. Bei einem Weltraumshooter wo du in deiner näheren Umgebung meist eher wenig Objekte hast, könnte man das sogar fast als Pixelgenaue "Kollisions"-abfrage sehen. Das Problem bei Pixelgenauen Kollisionsabfragen ist aber natürlich, dass das etwas ungewohnt ist. Ist verflucht schwer da etwas zu treffen wenn die Objekte nicht verhältnismäßig groß sind (menschenähnliche Wesen sind hier als eher klein zu werten). Einen rechteckigen Bereich kann man hier natürlich nur mit verhältnismäßig viel Rechenleistung abdecken.

Wahrscheinlich eine der gängigsten Methoden ist eine "simple" Kollisionsabfrage zwischen einem Strahl und der Welt. Kollisionsabfragen brauchst du früher oder später ohnehin in den meisten Spielen und ein Strahl ist auch nicht gerade das schwerste was man so abfragen kann. Anfangen wirst du wahrscheinlich wieder mit einer Bounding Sphere, kannst aber natürlich beliebig detailierte Kollisions-Volumen verwenden. Wiederum empfiehlt sich natürlich eine räumliche unterteilung der Objekte. Da hier die Kollisionsvolumen komplett unabhängig von der grafischen Darstellung gesetzt werden können, kannst du da sehr viel dran rum schrauben. Im Extremfall könntest du statt einem Strahl auch einen runden, lang gezogenen Kegel verwenden um für gewisse Waffen auch einen Streueffekt zu simulieren (Schrotflinte und so).

Dann gibt es natürlich noch die Möglichkeit den kleinen Ausschnitt (oder nur das eine Pixel) nochmals zu zeichnen und über Farb-Keys, Selection Buffer oder Occlusion Querys abzufragen ob ein bestimmtes Objekt getroffen oder gestreift wurde. Dies ist wohl recht ähnlich zur ersten Methode, jedoch kannst du hier auch ohne größere Probleme einen etwas größeren Bereich abfragen.

Für ordentliche Einschusslöcher wirst du im Endeffekt aber kaum um eine Kollisionsabfrage drum rum kommen, denn der Tiefenbuffer wird ja sehr schnell ungenau (also das mit dem gluUnProject). Wenn du da 50 Meter entfernt in eine Mauer schießt hast du da bald mal ein paar Dutzend Zentimeter Abweichung. Wenn du dann näher ran kommst macht sich so etwas schon bemerkbar. Aber natürlich kannst du für die Identifizierung der relevanten Objekte wiederum Occlusion Querys oder sowas verwenden, wobei sich dann halt die Frage stellt was schneller ist, so'n Occlusion Query bzw. ReadPixel Varianten, oder wenn du in Software die Kollisionsabfrage in einer organisierten (zB Octree) Welt durchführst.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 03, 2006 09:55 
Offline
DGL Member

Registriert: Sa Okt 22, 2005 20:24
Beiträge: 291
Wohnort: Frauenfeld/CH
die frage ist für mich eigentlich mehr wie ich das mathematisch mache, wenn ich den vektor des schusses, den kugelmittelpunkt und den radius der kugel hab. Leider bin ich nich im studium sondern noch an der schule :(. Vielleicht haben wirs auch scho gehabt in der schule und ich habs wieder vergessen.

mfg

_________________
bester uo-shard: www.uosigena.de


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 03, 2006 11:34 
Offline
Fels i.d. Brandung
Benutzeravatar

Registriert: Sa Mai 04, 2002 19:48
Beiträge: 3830
Wohnort: Tespe (nahe Hamburg)
Wie bereits gesagt wurde sind übliche Kollisionsverfahren Boundbox und Boudingsphere, die man auch miteinander kombininieren und schachteln kann und damit sehr leicht eine gute Kollisionsprüfung einzubauen (reicht vermutlich nicht mehr bei polygongenauer Berechnung, aber wer schreibt schon HL2 nach?). Beispiele für solche Kollisionen sind in der neuen DGLSDK enthalten. Schaue Dir dort einmal /samples/easysdl/collision an. Dort findest Du dann auch entsprechende Funktionen um zu prüfen, ob eine Kollision statt gefunden hat.

Grob:
1. Relative Position ermitteln (Vector1-Vector2)
2. tatsächliche Distanz berechnen (rel.x^2+rel.y^2+rel.z^2);
3. Minimale Distanz berechnen (wann tritt eine Kollision ein? Wenn Beide Kugeln nebeneinander liegen => radius1+radius2).
4. Eine Kollision fand statt, wenn die tatsächliche Distanz <= minDistanz^2

_________________
"Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 03, 2006 11:46 
Offline
DGL Member

Registriert: So Sep 26, 2004 05:57
Beiträge: 190
Wohnort: Linz
Eine Möglichkeit für eine Kollisionsabfrage zwischen einer Geraden und einer Kugel ist folgende:

Der Punkt P auf einer
Strecke: S + t*D
der am nähesten zu einem Gegebenen
Punkt: P0, wobei P0 das Zentrum der Kugel ist,
liegt wird berechnet indem man den Punkt auf die Gerade projeziert und sich dadurch das t berechnet:

t = ( D * ( P0 - S ) ) / (D * D)
wobei (wie oben erwähnt):
t ... der zu berechnende Wert für die Strecken-Formel.
D ... der Richtungsvektor der Strecke, wenn der Richtungsvektor die Länge 1 besitzt, kannst du dir natürlich das dividieren durch (D*D) sparen.
P0 ... der Punkt wo wir wissen wollen welcher Punkt auf der Strecke am nächsten zu diesem liegt.
S ... der Start-Punkt der Geraden (beim schießen wahrscheinlich etwa deine Kameraposition).
Das "*" ist hier jeweils ein Skalarprodukt der beiden Vektoren.

Der näheste Punkt ist nun:
P = S + t*D
wobei wir S und D ja kennen sollten und das t haben wir uns ja gerade berechnet.

Zu beachten gilt:
Wenn t < 0, dann befindet sich der Punkt logischer weiße "hinter" unserer Strecke, also wir müssten die umgekehrte Richtung: -D einschlagen, um möglichst nahe zu dem Punkt zu kommen. Für einen Strahl (also eine Gerade mit einem Anfangspunkt S) empfiehlt sich daher die zusätzliche Abfrage:

Wenn t < 0 dann t = 0

Wenn du auch noch eine bestimmte Länge für den Strahl (also im Endeffekt eine Strecke) haben möchtest, so solltest du den Richtungsvektor D als Einheitsvektor (mit der Länge 1) dar stellen. Dann kannst du sehr einfach Abfragen:

Wenn t > Länge_des_Strahls dann t = Länge_des_Strahls

zB wenn du eine maximale Reichweite einbauen möchtest.

du kennst nun den Punkt P auf der Gerade welcher am nähesten bei P0 liegt. Nun musst du nur noch überprüfen ob der Abstand zwischen P und P0 größer oder kleiner als der Radius der Kugel ist. Also:

Wenn (P-P0)*(P-P0) < Radius*Radius dann schneidet die Gerade die Kugel.

Nochmal in kürze als Pseudo-C-ähnlichen-Code:

Code:
  1. bool Scheidet_Gerade_Kugel( Vektor KugelZentrum, float KugelRadius, Vektor StreckenAnfang, Vektor StreckenRichtung )
  2. {
  3.   float t = (StreckenRichtung * (KugelZentrum - StreckenAnfang)) / (StreckenRichtung*StreckenRichtung);
  4.  
  5.   Wenn t < 0
  6.     t = 0;
  7.  
  8.   // Ggf. hier noch
  9.   // Wenn t > StreckenLänge (brauchst natürlich einen zusätzlichen Parameter)
  10.   //   t = StreckenLänge
  11.   // Für diese Abfrage muss der Vektor StreckenRichtung ein Einheitsvektor sein!
  12.  
  13.   Vektor NaehesterPunkt = StreckenAnfang + t * StreckenRichtung;
  14.   float QuadrierterAbstand = (NaehesterPunkt - KugelZentrum) * (NaehesterPunkt - KugelZentrum)
  15.  
  16.   Wenn QuadrierterAbstand < KugelRadius * KugelRadius
  17.     return TRUE; // Strahl schneidet Kugel
  18.   Sonnst
  19.     return FALSE; // Strahl schneidet Kugel nicht.
  20. }


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jul 03, 2006 14:29 
Offline
DGL Member
Benutzeravatar

Registriert: So Jun 04, 2006 12:54
Beiträge: 263
Um einschüsse zu relaisieren geht es so am einfachsten:

Im erstem schritt wird jedes Poligon mit einer anderen Farbe gezeichnet, Die Pixelfarbe unter dem Mauszeiger wird zurückgelesen um es zu beschleunigen sollte der Sichtbereich auf ein Pixel beschränkt werden.

Im zweitem Durchgang wird das getroffene Poligon mit einer Farbverlauftextur neu gezeichtnet, aus zwei der Komponenten lässt sich wie beim erstem mal die getroffenenTexturkoordinaten ermitteln.

Dritter schritt: Unter der bedingung, das alle Texture nur einmal genutzt werden, kann der einschuss direkt draufgemalt werden, im anderem Fall wird es etwas komplizierter und man muss mit Multitexturing arbeiten.


Bei größeren Projekten sollte besser eine richtige Pysikengine verwendet werden.


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 14 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.009s | 16 Queries | GZIP : On ]