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

Aktuelle Zeit: Di Jul 08, 2025 13:49

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 6 Beiträge ] 
Autor Nachricht
BeitragVerfasst: So Mär 30, 2008 22:18 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Hallo Leute!

Ich könnte ein paar Ratschläge und ein wenig Hilfe gebrauchen. Ich bastel im Moment an einer Outdoor-Engine, welche schon ganz passabel die Landschaft und statische Modelle ohne Ladepausen nachläd. Die Landschaft und die Objekte werden in Blöcken nachgeladen.

Da passt Multithreading ja ganz gut, glaub ich. Ein Thread rendert und der andere läd die neuen Blöcke nach, z.B. .
Erbe ich mir eine neue Klasse von TThread so wie im Tutorial von Lossy, wie erstelle ich dann einen Thread, der Befehle ausführt, ohne diese in Execute hineinzuschreiben? Ich würde einem Objekt meiner Klasse am Liebsten nur die Anweisungen geben, wie "Führe diese Funktion/Prozedur mit der Priorität X aus", ganz allgemein, und nicht nur beschränkt auf Prozeduren oder Funktionen mit vorgegebenen Parametern. Funktioniert das irgendwie mit Methodenzeigern o.Ä.?
Wenn ich dann unmittelbar nach dem Starten des einen Threads einen anderen starten würde, dann würden die Befehle in beiden Threads doch abwechselnd zur selben Zeit bearbeitet werden, oder? Hab ich das Prinzip da richtig verstanden?

Im Moment überlege ich mir auch gerade Methoden, wie ich eine Kollisionskontrolle am Besten implementieren könnte. Dazu wollte ich eine Klasse schreiben, die bei jedem Rendervorgang prüft, ob die Bounding-Box des Spielers eine Bounding-Box eines Objektes berührt und dann entsprechend reagiert. Das traue ich mir auch noch zu, schwieriger finde ich da die "Kollisionskontrolle" mit dem Boden. Ich generiere das Terrain aus Heightmaps in einem Editor, speichere jedoch die Vertexdaten, um evtl. noch Höhlen und Felsvorsprünge zu realisieren. Darstellbar ist das, aber ich habe keine Ahnung, wie in so einem Fall die Kollisionskontrolle aussieht. Würde ich Höhlen weglassen, könnte ich den Spieler einfach immer auf die Höhe des Terrains an einer Stelle (X,Y) setzen, wenn es nicht zu steil ist. Doch wenn an der gleichen Position (X,Y) mehrere Höhenwerte möglich sind, weil z.B. unter der Erde eine Höhle ist, so klappt das nicht mehr so einfach und sauber.

Habt ihr vielleicht ein paar Tipps, wie ich die Kollisionskontrolle für das Terrain am Besten implementieren kann? Wie läuft das in kommerziellen Programmen wie z.B. Gothic 1,2,3?


Vielen Dank fürs Lesen!


Rüdiger


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Mär 30, 2008 22:46 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Öhm, wäre vielleicht ganz gut, wenn das mal in zwei Themen aufgespalten wird, ich gebe jetzt aber trotzdem mal meinen Senf zu beidem hinzu.

1. Multithreading
Du bist bei einem Thread an die Execute gebunden. Was man aber ohne weiteres und wunderbar elegant machen kann ist, dem Thread eine Liste zu verpassen mit auszuführenden Anweisungen. Das könnte so aussehen:
Code:
  1.   TActionThread = class (TThread)
  2.   private
  3.     FQueue: TList;
  4.     FQueueMutex: <Ein Typ für einen Mutex, beispielsweise TCriticalSection>
  5.   end;

(Der Mutex ist nötig, damit sich beim Hinzufügen von Aufträgen nachher nicht die methoden in die Haare bekommen. )
Die Liste ist wie oben gezeigt vom Typ TList und hat als Einträge Instanzen einer von dir erstellten Klasse, die z.B. so aussehen könnte:
Code:
  1.   TThreadAction = class;
  2.   TFinishStatus = (fsDone, fsException);
  3.   TFinishNotify = procedure (Sender: TThreadAction; Status: TFinishStatus) of object;
  4.  
  5.   TThreadAction = class (TObject)
  6.   private
  7.     // ... Hier könnten Felder stehen, die du mit daten füllen kannst,
  8.     // die von der Run-Methode gebraucht werden.
  9.     FFinishNotifier: TFinishNotify;
  10.     FAutoFree: Boolean;
  11.   public
  12.     property AutoFree: Boolean read FAutoFree write FAutoFree;
  13.     // Hier wird der eigentliche Code ausgeführt.    
  14.     procedure Run; virtual;
  15.   end;

Was in der Run-Methode passiert, wäre dann egal. Die würde von dem Thread aufgerufen und dann könnte man FFinishNotifier (welcher vorher von der Klasse festgelegt wurde) aufrufen und der Klasse so mitteilen, dass die Aufgabe ausgeführt wurde. Dies muss dann natürlich in einem Synchronize passieren. Wenn dann FAutoFree auf True steht, wird die Klasse freigegeben.

Die Queue vom Thread sollte nach dem FIFO-Prinzip arbeiten, also First In First Out, was zuerst reinkommt, wird zuerst bearbeitet. Außerdem sollten die benutzenden Klassen die möglichkeit haben, eine Aufgabe mit priorität sofort nach ganz oben in die liste zu schieben, zum Beispiel das sofortige Nachladen eines Gegners, der gerade spontan in der Luft auftauchen soll oder solche späße.

Nun zu deinen Fragen:
Rüdiger hat geschrieben:
Wenn ich dann unmittelbar nach dem Starten des einen Threads einen anderen starten würde, dann würden die Befehle in beiden Threads doch abwechselnd zur selben Zeit bearbeitet werden, oder?

Das ist zwangsläufig so, da es eigentlich kein echtes Multithreading/-tasking gibt. Dies wird vom Betriebssystem simuliert, indem es die Anwendungen schnell hintereinander abwechselt, sodass der Benutzer es letztenendes garnicht merkt. Ausnahme sind Mehrprozessor bzw. Mehrkern-Systeme, bei denen die Anwendungen auf mehreren Prozessor(kern)en verteilt sind und wirklich nebeneinander ablaufen.


2. Kollisionserkennung
Lösen kannst du das mit per-face-collision, also indem du wirklich jede Fläche einzeln auf Kollision prüfst. Da das aber massiv an der Performance zieht, solltest du dir zusätzlich eine Optimierung anschaffen, zum beispiel einen Octtree, um nur das Gebiet zu prüfen, dass für eine Kollision in frage kommt.

Wie das Gothic X macht, weiss ich nicht. Ich habe aber bei einem Rollenspiel mal im Editor sehen können, dass sich die Welt aus einzelnen "Nodes" zusammensetzte, die man mehr oder weniger beliebig zusammensetzen kann. Da man dem Spieler dann eindeutig einer aktuell aktiven Node zuordnen kann, schränkt das das gebiet der potentiellen Kollisionserkennung schonmal deutlich ein.

Ich habe mich noch nicht eingehend mit der Kollision befasst und wie ich schon an diversen Stellen erwähnte graust es mir davor. Was du als Optimierung versuchen könntest wäre zum Beispiel, das Terrain schon im Editor in "Heightmap" und "Non-Heightmap"-Gebiete zu teilen. Wenn du es hinbekommst, dass man keinen Unterschied in der Behandlung merkt, könnte das die Performance deutlich heben, wenn dein Programm Gebiete, die als Heightmap definierbar sind von solchen die eine Per-Face-Kollision benötigen, unterscheiden kann.


So ich hoffe das war jetzt nicht zu wirr alle.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 31, 2008 07:43 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 05, 2002 10:35
Beiträge: 4234
Wohnort: Dortmund
Hab das Thema mal verschoben. Und ja. Das nächste Mal der Übersicht halber bitte 2 getrennte Themen machen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Mär 31, 2008 12:32 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Danke für die Antworten! Ich werde das nächste mal aufteilen.

Zur Kollisionserkennung: Der Spieler befindet bei mir immer nur in einem Patch/Block, den man im Editor beliebig klein einstellen kann. Vielleicht könnte ich dann nur per-face-culling anwenden, wenn es um den Boden/das Terrain geht. Das Terrain ist bei mir in einem dieser Blöcke kein sehr polygonreiches Objekt. Die statischen Modelle könnte ich dann mit Bounding Boxes machen. Ich kann ersteres ja mal versuchen...


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 01, 2008 12:58 
Offline
DGL Member

Registriert: Di Mai 24, 2005 16:43
Beiträge: 710
Raycasting wäre eine Möglichkeit, wenn du eine externe library verwenden möchtest, könntest du Newton verwenden.

mfg


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Apr 01, 2008 16:38 
Offline
DGL Member

Registriert: Mi Mär 31, 2004 15:24
Beiträge: 114
Und wie würde das mit Raycasting funktionieren?


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 » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 31 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.012s | 15 Queries | GZIP : On ]