Seite 1 von 1

[Assimp] Modell kopieren

Verfasst: 17.09.2009, 15:31
von chewbo
Hallo,
ich probiere zur Zeit Assimp aus und stehe vor folgendem Problem:

Ich möchte eine Klasse schreiben in der ich die benötigten OpenGL Routinen zum Zeichnen des Modells aufrufe. Mein Problem ist folgendes:
Im Konstruktor leses ich das Modell ein und setze einen Pointer drauf. Jetzt ist es logisch, dass beim verlassen des Konstruktor der Destruktor des eingelesenen Modells sich einschaltet und alles war umsonst.
Setze ich keinen Zeiger drauf, sondern kopiere ich es, werden die Zeiger die innerhalb der Klasse sind mitkopiert. Logisch ist, dass die Daten somit wiederum futsch sind, wenn sich der Konstruktor meiner Klasse beendet, da beide Zeiger auf den gleichen Speicher zeigen. Ich bräuchte also eine Tiefenkopie. Sowas liefert aber die Klasse nicht mit und selbst schreiben und alle Daten somit kopieren ist aufwendig und nicht umbedingt meine erste Wahl.

Hier mein Code um besser zu verstehen was ich meine:

Code: Alles auswählen

Model::Model(const std::string& pFile)
{
	 
	  Assimp::Importer importer;

		m_pAIScene=importer.ReadFile( pFile, 
        aiProcess_CalcTangentSpace       | 
        aiProcess_Triangulate            |
        aiProcess_JoinIdenticalVertices  |
        aiProcess_SortByPType);
		
		
}
Und die Klasse

Code: Alles auswählen

class Model
{
private:
	const aiScene* m_pAIScene;
	

public:
	Model(const std::string& File);
	~Model(void);
};
Die Frage ist also, wie ihr das Problem lösen würdet oder löst. Ladet ihr alle Modelle global? Oder ladet ihr die immer vorm Zeichnen neu ein? Beide Sachen kann ich mir kaum vorstellen.

Gruß
chewbo

Re: [Assimp] Modell kopieren

Verfasst: 17.09.2009, 16:05
von Schrompf
Das Assimp-Szenenformat ist eigentlich nicht direkt zum Rendern gedacht, sondern nur ein temporäres Format, aus dem man sich die benötigten Daten rausziehen kann. Bei uns läuft Assimp also einmalig im Editor, wenn ein neues Modell von den Grafikern reinkommt. Die Funktion sieht dann so aus:

Code: Alles auswählen

void Lesen()
{
  Assimp::Importer importer;
  importer.ReadFile(...);

  ErstelleEngineDatenAusAssimp( importer.GetScene());
}
So sinngemäß. Was ich damit sagen will: die Assimp-Szene war nicht dazu gedacht, längerfristig behalten zu werden.

Wenn Du das jetzt erreichen willst, kannst Du ja erstmal pro Modell eine Importer-Instanz per new erzeugen. Die und damit auch die damit gelesene Szene hat dann Bestand, solange Deine Model-Instanz besteht.

Code: Alles auswählen

class Model
{
protected:
  Assimp::Importer* mStoff;
};

Model::Model( const std::string& pFile)
{
  mStoff = new Assimp::Importer;
  mStoff->ReadFile( pFile, ...);
}

Model::~Model()
{
  delete mStoff;
}
So könnte es erstmal klappen. Im Normalfall lädt man aber die Assimp-Daten in die Strukturen der jeweiligen Engine um und die Engine kümmert sich dann um die Verwaltung. Die Assimp-Szene ist nur ein temporäres Zwischenformat.

Re: [Assimp] Modell kopieren

Verfasst: 17.09.2009, 16:12
von Krishty
Sry für die potenziell dumme Frage, aber – warum per new und nicht einfach als Member? new birgt schließlich so einige Fallstricke im Verbund mit RAII.

Weiterhin: könnte man nicht einen Importer als statisches Member anlegen, so dass er für alle Modelle nur einmal erzeugt wird?

Gruß, Ky

Re: [Assimp] Modell kopieren

Verfasst: 17.09.2009, 16:40
von Aramis
Weiterhin: könnte man nicht einen Importer als statisches Member anlegen, so dass er für alle Modelle nur einmal erzeugt wird?
Ja, das ist möglich sofern eine Assimp::Importer-Instanz von nur einem Thread gleichzeitig benutzt wird.

Re: [Assimp] Modell kopieren

Verfasst: 17.09.2009, 17:45
von Schrompf
Stimmt, als schlichte Membervar und mit dem Member-Constructor-Syntax geht das auch.

Eine einzelne Instanz für alle geht auch. Allerdings wird bei jedem Aufruf von ReadFile() dann (hoffentlich, habs grad nicht im Kopf) die vorherige Szene zerstört. Wenn ein Außenstehender die Lebensdauer der vom Importer erzeugten Resourcen bestimmen könnte, knallt es wegen der verschiedenen Heaps von DLL und Hauptprogramm bei der Freigabe.