[OpenGL] Koordinaten der Oberfläche eines Zylinders
-
Hallo zusammen
Ich hab da folgendes Problem,
Ich zeichne einen Zylinder (mit gluCylinder), von der Oberfläche dieses Zylinders aus möchte ich partikel emitieren.
Nun berechne die Oberfläche des Zylinders rein mathematisch (mit sin und cos) und lasse von dort aus die Partikel emitieren, jedoch kann ich das zur zeit nur berechnen wenn der zylinder senkrecht im bild ist, wenn ich den zylinder drehe, kann ich die "partikel hülle" zwar mitdrehen aber dann bewegen sich die Partikel leider nicht mehr so wie sie sollen, da ja der Raum gedreht ist.
So nun die Frage, kann ich mir irgendwie per OpenGl die Punkte der Oberfläche meines Zylinders holen, damit ich dann von ihnen aus meine Partikel losschicken kann ?
mfg Mari2k
-
Mari2k schrieb:
kann ich die "partikel hülle" zwar mitdrehen aber dann bewegen sich die Partikel leider nicht mehr so wie sie sollen, da ja der Raum gedreht ist.
Partikel auch einfach mitdrehen
-
du berechnest einfach die punkte auf der oberfläche des zylinders mit den sin und cos funktionen in dem koordinatensystem des zylinders, und dann jagst du diese punkte durch die weltmatrix des zylinders, dann bekommst du doch die globalen koordinaten der punkte auf der oberfläche des gedrehten zylinders...
oder verstehe ich das problem falsch?
aber dann bewegen sich die Partikel leider nicht mehr so wie sie sollen
oder gibts da etwa ein problem mit der transformation von normalenvektoren?
was heisst denn "nich so wie sie sollen" ?beschreibe bitte genauer, was du für ein ergebnis haben willst
-
Hallo
Ja also es geht darum das wenn ich die PartikelOberfläche mitdrehe, dann wird die Bewegungsrichtung der Partikel mitgedreht.
Also wenn ich zB. ein "glRotatef(90,0.0f,0.0f,1.0f)" vor den Partikel zeichnen einfüge, dann werden meine Partikel zur Seite fliegen (was auch logisch ist), aber ich will das sie auch weiterhin nach oben gehn sollen.
Deswegen versuch ich sie irgendwie direkt von der Oberfläche meines Zylinders zu emitieren, damit der raum nicht gedreht ist und sie ihre normale richtung behalten können.
Als Ergebniss will ich drehbaren Zylinder haben der von einer Partikelhülle eigehüllt ist, wobei die partikel immer nach oben gehn (Feuer Effekt).
Naja wie gesagt, im moment brennt das feuer zur seite wenn ich den Zylinder drehe
du berechnest einfach die punkte auf der oberfläche des zylinders mit den sin und cos funktionen in dem koordinatensystem des zylinders, und dann jagst du diese punkte durch die weltmatrix des zylinders, dann bekommst du doch die globalen koordinaten der punkte auf der oberfläche des gedrehten zylinders...
Ja ich glaube da irgendwo liegt mein Problem, was meinst du den genau mit "jagst du diese punkte durch die weltmatrix des zylinders" ?
Im moment berechne ich die Punkte folgendermasen:
//Particle(x,y,z) Der Entstehungspunkt des Partikels mypar[loop] = new Particle(xwert,sin(winkel)*radius,cos(winkel)*radius);Wobei xwert und winkel zufallszahlen sind damit die partikel verteilt werden.
-
ah, ok, verstehe jetzt einigermaßen, was du haben willst...

ich bin zwar noch nicht soweit gekommen, mein eigenes partikelsystemchen für d3d zu implementieren, und mit ogl kenn ich mich auch nich aus, aber ich würde jetzt ma folgendes vorschlagen:erstelle einfach eine klasse "burstParticle" (wie 'feuerstoß-partickel' ) oder sowas in der art...
Jedes dieser objekte speichert seine anfangsposition (myVector3D bzw. {float, float, float} ), seinen entstehungszeitpunkt (long) und die nachOben-Geschwindigkeit (float raisingVelocity oder so...).
Dann müssen die objekte noch über ne methode wie etwa "myVector3D GetCurrentPosition(long timeMillis)" verfügen, die die aktuelle position zurückliefert, würde ich etwa so machen:myVector3D burstParticle::GetCurrentPosition(long timeMillis){ return startPosition+myVector3D(0,0,raisingVelocity)*timeMillis; }(kanns natürlich auch alles als floats ausdrücken, ansonsten musste halt ne vektorklasse haben, die du mit allen möglichen variablentypen multiplizieren kannst, geschmackssache, wie mans umsetzt...)
wie auch immer...
die startposition berechnust du ganz normal wie vorhin:
1. sin cos in relativen zylinderkoordinaten
2. die punkte transformierts du mit der weltmatrix des zylinders, bekommst dadurch die globalen koordinaten des startpunktes
3. mit dem startpunkt und der momentanen zeit erstellts du soein feuerstoß-partikel-objekt.mit der funktion bekommst du zu jedem späteren zeitpunkt die momentane position des partikels, wo der zylinder ist, ist dem partikel föllig egal (flamme folgt nicht dem zylinder, sondern fliegt einfach nach oben)
an dieser position zeichnest du deinen partikel. nach einer bestimmten zeit löschst du das ganze objekt
[ich wütrde zB 32 solcher objekte in ein array packem, und die immer wieder überschreiben...]naja, ist halt mein vorschlag...

was meinen denn die anderen dazu? :pps:
hm... wenn du schon so eine klase schreibst, mach die möglichst allgemein, dann kannst du damit später auch den langsam aufsteigenden rauch oder schnell fallende wassertropfen, oder in alle richtungen gestreute größere trümmerteile darstellen...
-
Alles klar, vielen danke für die Hilfe

2. die punkte transformierts du mit der weltmatrix des zylinders, bekommst dadurch die globalen koordinaten des startpunktes
Ich glaube daran harperts bei mir im moment.
Aber ich werd das mal so versuchen, ich denke ich muß mich auch noch etwas mehr in dem thema matrixen von opengl einlesen

mfg Mari2k
-
oops, sry, ist natrlich völliger quatsch gewesen, das mit dem "startzeitpunkt"
speichere einfach immer die aktuelle position, die geschwindigkeit, und den pointer zu dem zu zeichnenden "partikel" (bei dder daemlichen funktion übergibst du einfach elapsedTime seit dem letzten bild).

-
Hallo nochmal,
Also das mit den Partikelnn an sich klappt schon ganz gut, jedes Partikel hat seine eigene klasse, mit den koordinaten, geschwindigkeit , diversen kräften (zb. endanziehung) usw., statt der Zeit benutzt ich einen Wert für die Lebensspanne der kontinuierlich kleiner wird (dadurch wird auch das verhalten und farbe des Partikels beeinflusst), wenn diese erlischt wird dann ein neues Partikel generiert.
Könntes du mir vielleicht so eine Transformation der Zylinderpunkte mit der Weltmatrix des Zylinders anhand eines kleinen Beispiels zeigen ?
Da steig ich nämlich grade überhaupt nicht durch, die Punkte der Oberfläche kann ich mit cos/sin und der länge des Zylinders relativ berechnen, weiß jetzt nur nicht wie ich davon auf die globalen Koordinaten komme, wenn der Zylinder sich bewegt.
mfg mari2k
-
verdammt, hab zu lange eingetippt, mein beitrag wurde verschluckt, geil

-
Also wie ich das verstanden hab, muß ich eine Matrixmultiplikation durchführen und zwar meine MODELVIEW MATRIX * die Koordinaten meines Punktes , richtig?
MODELVIEW wär dann eine 4x4 Matrix :
float mat[16]; glGetFloatv( GL_MODELVIEW_MATRIX, mat );und dann das ganze mal die 1*3 Matrix meiner relativen Koordinaten.
Wär das richtig ?
-
lange rede, kurzer sinn...
-ganz am anfang mit glPushMatrix die aktuelle matrix speichern
-dann loadest du eine identitätsmatrix
-mit glRotate wandelst du die in eine rotationsmatrix um
-zeichnest deinen zylinder
-berechnest die lokalen koordinaten der partikel-startpunkte
-transformierst diese coordinaten mit deiner rotationsmatrix
-speicherst diese coordinaten und lässt die zunächst ma in ruhe
-mit glPop holst du wieder deine normale "weltmatrix" bzw GL_MODELVIEW-matrix zurück
-bewegst
-zeichnest deine partikelwichtig:
-startposition in dem ROTIERTEN koordinatensystem berechnen
-aber die partikel in den GLOBALEN kordinaten bewegen!wenn dich die mathe interessiert, lis dir dat durch (translation, skalierung rotation, der rest ist eigntl egal)...
http://www.inf.fh-dortmund.de/personen/mitarbeiter/hoffmann/skolleg/Mathematik/Matrixtransformationen.pdf
http://www.informatik.fh-nuernberg.de/Professors/Schiedermeier/SS_2002/Visualisierung/Vorlesung/Visualisierung.pdfgibt bestimmt besseres, find auf die schnelle aber nix...
HEY wo bleiben denn die ogl-profis?? ICH bin ein d3d-noob, und somit nicht gerade derjenige, der hier ratschläge geben sollte

-
Mari2k schrieb:
und dann das ganze mal die 1*3 Matrix meiner relativen Koordinaten.
hö?

ne, du musst deine rotationsmatrix (genau das GL_MODELVIEW-dingsda, mit dem du den zylinder rotierst) holen, und damit deine lokale vektoren der partikelstartpositionen in die globale koordinaten transformieren und abspeichern. danach machsts du die rotationsmatrix wieder weg, und zeichnest deine partikel in den globalen koordinaten, so wie die sind, evtl um (0,0,v) nach oben verschoben

-
zum vorletzten beitrag:
du musst:
-lokale startpositionen berechnen
-rotieren
-dann bewegenund nicht so wie vorher:
-lokale startpositionen berechnen
-bewegen
-rotieren
-
Andrey schrieb:
Mari2k schrieb:
und dann das ganze mal die 1*3 Matrix meiner relativen Koordinaten.
hö?

ne, du musst deine rotationsmatrix (genau das GL_MODELVIEW-dingsda, mit dem du den zylinder rotierst) holen, und damit deine lokale vektoren der partikelstartpositionen in die globale koordinaten transformieren und abspeichern. danach machsts du die rotationsmatrix wieder weg, und zeichnest deine partikel in den globalen koordinaten, so wie die sind, evtl um (0,0,v) nach oben verschoben

Ja ich glaube das wollte ich damit auch sagen

Also den Vektor mit den Koordinaten das Punktes(x,y,z,0) mit der MODELVIEW MATRIX (4x4) transformieren.
In etwa so:float* transform (float mat[16],float vec[4]){ float newvec[4]; newvec[0] = mat[0] * vec[0] + mat[1] * vec[1] + mat[2] * vec[2] + mat[3] * vec[3]; newvec[1] = mat[4] * vec[0] + mat[5] * vec[1] + mat[6] * vec[2] + mat[7] * vec[3]; newvec[2] = mat[8] * vec[0] + mat[9] * vec[1] + mat[10] * vec[2] + mat[11] * vec[3]; newvec[3] = mat[12] * vec[0] + mat[13] * vec[1] + mat[14] * vec[2] + mat[15] * vec[3]; return newvec; }Ich hoffe nur das wirkt sich nicht zu sehr auf die Performance aus wenn ich für jedes Partikel so eine Transformation durchführen muß.
Auf jedenfall erstmal vielen dank dir !

Edit: Alles klar, das klappt jetzt mit den Partikeln.. kann das Objekt drehen und sie gehn immer nach oben ! Danke nochmal jetzt bin ich viel schlauer

-
Edit: Alles klar, das klappt jetzt mit den Partikeln.. kann das Objekt drehen und sie gehn immer nach oben ! Danke nochmal jetzt bin ich viel schlauer
na dann issja gut, allerdings würd ich noch empfehlen, einfach ma ne eigene klasse für vektoren und matrizen zu schreiben (kostet ja nix, auch von der performance her), statt mit den ganzen arrays herumzujonglieren, der code wird dann (meiner meinung nach) einfach besser lesbar, und man kommt nicht so schnell durcheinander [ zB deine "transform" funktion könnte man auf positionsvektoren, richtungvektoren und ebenen anwenden, die haben alle jeweils vier float-komponente, allerdings macht die funktion nur bei positionsvektoren sinn]. Wenn der code noch länger wird, oder du zB ne pause fürn paar wochen machst, weist du selber nich mehr, was du da eigentlich gemacht hast... aber solangs klein und übersichtlich bleibt, ists vertretbar :p