Irrlicht Scene speichern und laden

Fragen zu Grafik- & Soundproblemen und zur Spieleprogrammierung haben hier ihren Platz.
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Irrlicht Scene speichern und laden

Beitrag von Darie »

Hi Leute !!!

Hab ein bisschen mit Irrlicht herumgespielt und weiss nicht weiter...

Und zwar hab ich aus Cubes und Plane-Meshes als Boden und Decke ein Dungeon erstellt. Dann hab ich das ganze als Irr-Szene abgespeichert und versucht die Szene mit "LoadIrrScene" wieder zu laden. Die Cubes werden alle richtig angezeigt nur die Boden und Decken "Planes" werden nicht angezeigt und ich weiss nicht warum. Eigentlich wollte ich so, anhand einer Textdatei ein einfaches Dungeon erstellen,dass aus cubes und planes besteht, dieses dann wieder als Irr-Scene laden, da je nach Größe die Generieung des Dungeons lange dauert.
Welche Infos werden denn genau bei "SaveIrrScene" gespeichert und geladen?
Eigentlich wollte ich nach dem Laden der Szene die Cube Nodes zu einer Collisiongroup hinzufügen, damit ich ne Kollisionsabfrage machen kann.
Irgendwie ist mir nicht so ganz klar, was also LoadIrrScene und SaveScene bringt solange ich auch nicht irgendwie meinen Objektbaum danach nutzen kann.
(Wollte halt weg vom BSP-Format und mit ner Textdatei meine Dungeons basteln, hat wer ne Idee wie man das am besten handelt?????)

Gruss
Darie
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

Womit hast du die .irr datei erstellt ?

Lad diese mal in IrrEdit. Und schau was die anzeigt. Zum debuggen kompilier deine Applikation als Konsolenapplikation und schau was der motzt ( meist sinds irgendwelche falschen Pfade im .irr file ).

im IrrEdit kannst du ebenfalls lightmapping rechnen lassen und die Gruppen zusammenfassen.

Cheers, Thalius
"...smoking hash-tables until until you run out of memory." :P
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Beitrag von Darie »

Die Irr-Datei hab ich mit nach dem generieren und positionieren der Cubes und Planes mit dem "SaveIrrScene" gespeichert. Wenn ich die Scene in IrrEdit lade, hab ich die Cubes und die Planes werden dann als animated Mesh geladen, aber auch nicht richtig gezeigt (bin aber nicht sicher, weil die texturen fehlen). Hab mal als Console kompiliert.
Hab mal als Konsole kompiliert und gesehen dass die Meldung "Could not load Mesh" kommt. Vielleicht muss ich die Planes als Mesh speichern, damits klappt......

hier sind mal beide codes

Code: Alles auswählen

XIncludeFile #PB_Compiler_Home + "Includes\IrrlichtWrapper_Include.pbi"

global cubesize.f=10
global mapsize.w = 20
global dim map.s(mapsize,mapsize)

 
file=ReadFile(#pb_any, "dungeon.map")

for y=1 to mapsize
 for x=1 to mapsize
  map(x,y)=chr(readcharacter(file))
 next x
   readcharacter(file):readcharacter(file)
next y
closefile(file)


IrrStartEx(#IRR_EDT_DIRECT3D9 , 1680, 1050, #True,#True,#True,32,#True,#True,#True,0)
IrrSetWindowCaption( "Dungeon" ) : IrrHideMouse() : *cam = IrrAddFPSCamera(#True,80,40) : *CamNode = *cam


Dim *textures.irr_texture(2) 
*textures(0) = IrrGetTexture("wall.jpg")
*textures(1) = IrrGetTexture("ground.jpg")
*textures(2) = IrrGetTexture("ceiling.jpg")


newlist *cube.irr_node()
newlist *floor.irr_node()
newlist *ceiling.irr_node()



for z = 1 to mapsize : for x = 1 to mapsize
 
   if map(x,z)="#"
          
         addelement(*cube()) 
         *cube() = IrrAddCubeSceneNode(cubesize)
         IrrSetNodeScale(*cube(), 1, 2.5, 1)
         IrrSetNodeMaterialTexture(*cube(), *textures(0), 0 )
         IrrSetNodeMaterialFlag(*cube(), #IRR_EMF_LIGHTING, #IRR_OFF )
         IrrSetNodePosition(*cube(), cubesize*x,0,z*cubesize)
        
          
   endif
   
   if map(x,z)="."
          
         addelement(*floor()) : addelement(*ceiling()) 
         *floor()   = IrrAddPlaneSceneNode("f"+str(CountList(*floor())),cubesize, cubesize, 1, 1, 1, 1)
         *ceiling() = IrrAddPlaneSceneNode("c"+str(CountList(*ceiling())),cubesize, cubesize, 1, 1, 1, 1)
          IrrSetNodeMaterialTexture(*floor(),   *textures(1), 0)
          IrrSetNodeMaterialTexture(*ceiling(), *textures(2), 0)
          IrrSetNodeMaterialFlag(*floor(),   #IRR_EMF_LIGHTING, #IRR_OFF )
          IrrSetNodeMaterialFlag(*ceiling(), #IRR_EMF_LIGHTING, #IRR_OFF )
          IrrSetNodeRotation(*ceiling(), 180, 0, 0)
          IrrSetNodePosition(*floor(), cubesize*x,cubesize*(-1),cubesize*z)
          IrrSetNodePosition(*ceiling(), cubesize*x,cubesize,cubesize*z)
          
   endif
   
 next x : next z

IrrSaveScene("dungeon.irr")


While IrrRunning()


      IrrBeginScene(0,0,0) : IrrDrawScene() : IrrEndScene()

Wend 



IrrStop()

Code: Alles auswählen

XIncludeFile #PB_Compiler_Home + "Includes\IrrlichtWrapper_Include.pbi"

global cubesize.f=10
global mapsize.w = 20
global dim map.s(mapsize,mapsize)


IrrStartEx(#IRR_EDT_DIRECT3D9 , 1680, 1050, #True,#True,#True,32,#True,#True,#True,0) : *Scene=IrrLoadScene("dungeon.irr")
IrrSetWindowCaption( "Dungeon" ) : IrrHideMouse() : ;*cam = IrrAddFPSCamera(#True,80,40) : *CamNode = *cam


While IrrRunning()


      IrrBeginScene(0,0,0) : IrrDrawScene() : IrrEndScene()

Wend 

IrrStop()
Zuletzt geändert von Darie am 16.09.2008 18:16, insgesamt 1-mal geändert.
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

Nene, höchstwarscheinlich nur ein pfad problem.

Als was lädst du denn die meshes in die szene ? Respektive für was werden die nachher gebraucht - gibt da verschiedene typen meshes in 3D - von static über dynamic und animated. Wenn man die falschen Typen wählt geht entweder die performance flöten oder man bekommt nicht was man will.

öffne doch mal das irr file in einem editor (ist ein XML) und passe die modelpfade manuell an. Je nachdem wie du diese abgelegt hast ob absolut oder relativ müssen diese zur debuggten respektive kompilierten version natürlich am richtigen Ort liegen.
Dasselbe gilt für alle Ressourcen die du verwendest.

Wenns rein um static geometry geht ( also gebäude / indoor etc ) verwende octrees bei grossen szenen oder statics bei einzel-objekten - diese kannst du dann zur jeweiligen collison group hinzufügen um einen einfachen selektor zu haben.

Alles was bewegt werden sollte oder animiert kannst du als animated mesh hinzuladen.

die szene komplett mit irredit zu erstellen ist im prinzip kein prob. Wenn du interchangen willst zwischen irredit und einem irrlicht generierten IRR file solltest du auf die typen und pfade achten ( am besten relativieren dann hast keine probs damit ).

Die Planes: hast du da die standard typen verwendet ?
Als mesh geht natürlich auch.

Cheers,
Thalius
"...smoking hash-tables until until you run out of memory." :P
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Beitrag von Darie »

hab die "modelle" ja mit den Befehlen "AddCubeSceneNode" und "IrrAddPlaneSceneNode" generiert und dann mit IrrSaveScene gespeichert. Komischerweise klappt es bei den würfeln aber nicht mit den planes....
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

ich gugg das morgen mal an ... 22.00 und ich bin noch im büro .. bah!
"...smoking hash-tables until until you run out of memory." :P
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Beitrag von Darie »

Thanx!! :oops:
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

Post mal noch schnell das .map file.

Paar Anmerkungen:

Code: Alles auswählen

*CamNode = *cam ; wird früher oder später crashen - je nachdem was du machst
Damit sowas funktioniert - empfehle Enableexplicit hier.

Musst du die beiden Pointer vorher initialisieren.

Code: Alles auswählen

define *cam.IRR_CAMERA, *CameraNode.IRR_NODE
Zur Listenverwaltung empfehle ich dir eine Structure zu verwenden und wenn du einen direkten verweis auf das objekt brauchst dann nimm lieber ein array da du ansonsten jedesmal durch die gesamte liste durchiterieren musst was natürlich CPU zeit kostet.

zur structure in etwa sowas:

Code: Alles auswählen

Structure my_mapObject
  type.i
  Position.IRR_VECTOR
  Dimension.IRR_VECTOR
  *mesh.irr_mesh
  *node.irr_node
  *tex.irr_tex
  *custom.my_gameobject
EndStructure

; Sieht doch zb so übersichtlicher aus .. :)

Scene\type         = #MyObj_Cube
Scene\Position\x = 

Scene\Custom\name = "Würfel Mensch!"
Scene\Custom\hitpoints = 20

...

ist natürlich nur ein Beispiel aber so hast du alle argumente und parameter eines jeden objekts inklusive infos wie zb HP usw unter einem hut. Für Sachen wie Mapsize wenn dus öfters brauchst verwende den neuen Typ .i ( integer ) welcher in den jeweils nativen long werd umgewandelt wird -> schneller als word aber braucht n paar bytes mehr im ram. Wobei du in 3D generell überall optimieren willst/solltest da die meisten Leute auf ziemlich schlechten Gfx Karten hocken.

Was Maps betrifft ist immernoch das effektivste diese zu einem mesh zu combinen , im Irredit das licht zu berechnen und als ein octree einzubinden. Es sei denn du willst dich selbst um die FOV Verwaltung kümmern ( geht natürlich, aber wird ne ziemliche Arbeit ). So dynamische Maps mit tausenden von dynamischen Nodes zwingt so gut wie jede Kiste in die Knie. Der Unterschied zwischen static und dynamic ist im prinzip dass bei zb Kollisionen jedes vertex eines dynamics relativ zu siener position mit jedem anderen dynamic vertex (dreieck) verglichen wird - wohingegen statics, speziell als octree in bereiche unterteilt werden welche jeweils nur gegen ein dynamic und da nicht mit dynamischer position mit fixen werten überprüft werden kann - was wiederum natürlich einiges schneller ist! Dies ist nichtnur in irrlicht so, sondern auch in anderen 3D Engines.

Je nachdem wie gross deine Maps werden sollen und wie weit der Betrachter sehen soll - solltest du also etwas Vorplanung machen. :)

Was die Plane Node betrifft kann ich dir mehr sagen sobald ich das .map file zum testen habe.
Auch zu beachten ist dass so wie du das jetzt aufgestellt hast alle ressourcen im gleichen ordner wie dein exe gesucht werden.

Cheers, Thalius
"...smoking hash-tables until until you run out of memory." :P
Benutzeravatar
Darie
Beiträge: 204
Registriert: 14.09.2004 21:51

Beitrag von Darie »

Ok, hier ist das Mapfile (ist einfach nur ne textdatei mit rauten und punkten, grösse 20x20)

Code: Alles auswählen

####################
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
#..................#
####################
Ressourcen sind alle im gleichen ordner, keine ahnung warum die qubes gerendert werden, die planes aber nicht.

Aber wie komme ich nach laden des Irrfile wieder an die ganzen nodes pointer? Ich weiss, dass es besser ist große Meshes zu haben als viele kleine Nodes, aber dann kann ich auch wieder das BSP Format nehmen, muss dann allerdings meine levels wieder mit dem Radiant bauen.
Gibts ne Möglichkeit beim Irrfile generieren die Qubes und die Planes zu einem Mesh zu verbinden, sodass ich nicht mehr so viele Nodes hab?
Benutzeravatar
Thalius
Beiträge: 476
Registriert: 17.02.2005 16:17
Wohnort: Basel / Schweiz

Beitrag von Thalius »

irr file deklariert lediglich die Szene und nicht ein Mesh. Eine Szene enthält Nodes und diese verweisen auf meshes.

So können auch mehrere nodes dasselbe mesh verwenden was sehr viel speicher spart.
Kombinieren kannst du das nur indem du manuell das Mesh mit Vertexinformationen füllst und dieses static lädst ( somit befindet es sich auch im GPU speicher und nicht im langsameren shared ).
Bei diesem Prozess solltest du sinnvollerweise die sich überschneidenden Polygone weglassen ( Cubeboden zu bodenfläche etc. ), damit sich die Grafikkarte nicht auch noch darum kümmern muss was wiederum in tonnenweise "Overdraw" speziell wenn transparenz ins spiel kommt resultiert.

Möglichkeit 1. In nem Modeller erstellen und die dynamischen bereiche nachladen ( wenn als octree geladen teilt irrlicht ein komplexeres poly model automatisch in octrees - wie BSP, nur on the fly ;) ).

Möglichkeit 2: Bau die Basis wie ground und grobe Struktur im Modeller und dann lädst du deine dungeon 3d Tilesets und machst jeweils die sichtbar welche in der Sichtweite des Spielers liegen -> #IRR_VISIBLE
Klar kannst du auch alles zeigen aber dann wird die Performance wieder in den Keller gehen - je nachdem wieviele dynamische objekte du verwendest. Was den Kollisionscheck angeht kannst du hier alle dynamics mit den statics in eine Collisiongroup nehmen - welche zumindest fuer collisionscheck dir die arbeit der unterteilung abnimmt und das ganze fuer kollision quasi als ein grosses mesh handhabt - wobei du hierbei Octree dann wieder mit vorsicht geniessen solltest da das dann zu polygon fehlern führen kann ( je nach übelkeit des grafiktreibers .... Z- Test etc. )

Am sichersten wie gesagt basis als mesh kreieren. Dann zusammenwürfeln , dynamics ohne octree behandeln und col-gruppieren und je nach grösse und Detaillevel für gewünschte minimalframerate dann ausblenden was ausserhalb der sinnvollen sichtweite liegt.

Oder halt ja ... Traditionell mit vertex zusammenbauen ( was dir die volle Kontrolle gäbe ) - Comtois hatte da mal ein Beispiel fuer das alte ogre gebaut - im prinzip sind die 3d vertex daten die selben.

Was den Plane node betrifft ist dieser tatsächlich noch als animated mesh deklariert ( du verwendest 1.05 ) :) - sprich nimm den cube ( former testcenenode ) oder ein custommodel um mehr zu machen (falls du das irr file nachher im irredit noch bearbeiten willst ) - primitives und ein paar sachen haben wir erweitert welche im irredit version zt. nicht drin sind.

.. und schau nochmals ins irr file wegen der pfade ;) - kein gesetzter pfad nimmt den standardpfadeintrag. ;)

Cheers, Thalius
"...smoking hash-tables until until you run out of memory." :P
Antworten