Frage zu obj loader OpenSG
-
Hallo,
habe eine obj Datei und möchte diese mit dem vorhandenen OpenSG Loader laden.
sieht so ausint main(int argc, char **argv) { osgInit(argc,argv); int winid = setupGLUT(&argc, argv); GLUTWindowPtr gwin= GLUTWindow::create(); gwin->setId(winid); gwin->init(); NodePtr scene; Time start = getSystemTime(); scene = SceneFileHandler::the().read("C:\\3001.obj"); Time end = getSystemTime(); mgr = new SimpleSceneManager; mgr->setWindow(gwin ); mgr->setRoot (scene); startFpsCounter(); mgr->showAll(); glutMainLoop(); return 0; }
Die Datei wird fehlerhaft dargestellt
evtl müsste man den Winkel und die Normalen neu berechnen.hierzu habe ich folgendes gelesen
http://opensg.vrsource.org/trac/wiki/Tutorial/OpenSG1/GeometryBox with bad vertex normals
See how bad the cube now looks. If you increase the mesh resolution the effect will reduce in size, but that is not a good solution anyway.
There is another variant of calcVertexNormals which can be given an angle. All edges between faces that have an angle larger than the one specified, will be preserved.
Replacing the old function call with
#!cpp
calcVertexNormals(geo, deg2rad(30))
would help us out with the cube.
deg2rad is a useful function that allows you to convert degree values into radians. As you might guess there is also a rad2deg function.
Calculating vertex normals is more complex than it sounds and it requires a considerably amount of time to compute. Using one of these methods on a per frame basis is not really recommended!
As OpenGL supports a lot of different geometry data formats, also new problems arise. Of course, not all of these variants are equally efficient, but luckily OpenSG also offers some methods to improve the data automatically. I mentioned createSharedIndex() before, which will look for identical elements and remove the copies, changing only the indexes.
wie wende ich die Funktion an?
habe nur den NodePtr Scene?
wie kann ich die Normalen reparieren?Gruß Matthias
-
So weit ich weiß, wird ein Geometrycore in dem NodePtr scene abelegt. Mit
GeometryPtr geo = GeometryPtr::dcast(scene->getCore());
kannst du auf den Core zugreifen und diesen der Funktion calcVertexNormals übergeben. Ich glaube aber, dass nicht die Datei fehlerdargestellt wird, sondern dass in deinem obj-File die Normalen nicht richtig abgelegt sind.
-
es lag am Format - benutze nun *.wrl und das funktioniert Prima
GeometryPtr geo = GeometryPtr::dcast(scene->getCore());
den code las ich in den tutorials auchs chon mehrmals
das Übergeben der calcNormals
geht auch soweit, nur bringt dies auch keine graphische VeränderungWie kann ich bei einem hineingeladenen Modell
die Farbe ändern bzw eine Boundingbox anzeigen lassen
und es mit der Maus bewegen?
-
matthiasas schrieb:
es lag am Format - benutze nun *.wrl und das funktioniert Prima
GeometryPtr geo = GeometryPtr::dcast(scene->getCore());
den code las ich in den tutorials auchs chon mehrmals
das Übergeben der calcNormals
geht auch soweit, nur bringt dies auch keine graphische VeränderungDie Normalen werden mit irgendeinem Algorithmus bestimmt. Dies führt nicht immer zu "schönen" Normalen. Vielleicht kannst du ja mal Screenshots zeigen, mit Ist und Soll des Modells.
Wie kann ich bei einem hineingeladenen Modell
die Farbe ändern bzw eine Boundingbox anzeigen lassen ...Das Aussehen der Geometrie kann man entweder mit dem Colorfield (keine Beleuchtungsrechnung) oder Materialien modellieren. Jeder Geometry Core hat dafür ein material-field. Schau mal in die Doku, dort ist dies zumindest gut beschrieben.
Die Bounding Box kann mit den Befehlen
node->updateVolume(); DynamicVolume * vol = node->getVolume();
bestimmen, zeichnen musst diese aber afaik selbst.
...und es mit der Maus bewegen?
Schau dir mal den SimpleSceneManager an, damit kann man schon ganz nett navigieren.
Grüße!
-
so nun klappt das oben genannte
habe nur noch eine Frage an Dich.
Es geht um das Hereinladen von mehreren Objekten in die Scene.
Ich prüfe eine Map ob das teil schon geladen ist.
Wenn nein lade ich es und lege einen NodePtr in einer Map ab.
Wenn ja hole ich mir den NodePtr und gebe diesen weiter
an meine Klasse Objekte
das funktioniert nicht?!Desweiteren, lade ich die matrix
und gebe sie der Methode settransform vom Objektda weis ich nicht ob die Methode richtig ist.
bekomme leider nur die hälte der fps wenn ich das Modell in einzelnen stücken lade - als wie im gesamtenvoid Brick::setTransformation() { beginEditCP( m_TransformPtr,OSG::Transform::MatrixFieldMask ); m_TransformPtr->setMatrix( m_Matrix ); endEditCP ( m_TransformPtr, OSG::Transform::MatrixFieldMask ); beginEditCP( m_CoreNode, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask ); m_CoreNode->setCore(m_TransformPtr); m_CoreNode->addChild(m_BaseNode); endEditCP( m_CoreNode, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask ); }
wie sieht das richtg aus?
m_Basenode ist die Node die ich mir geben lasse
da is das hereingeladene Objekt drin
Corenode ein neu erstellter member
und Transformptr auch, matrix auch ein übergebener member
-
matthiasas schrieb:
...Wenn nein lade ich es und lege einen NodePtr in einer Map ab.
Wenn ja hole ich mir den NodePtr und gebe diesen weiter
an meine Klasse Objekte
das funktioniert nicht?!hmmm... bist du dir sicher, dass du die Node im Scenegraph hizugefügt hast? Ansonsten hört sich das nicht nach einem OpenSG spezifischen Problem an ...
Desweiteren, lade ich die matrix
und gebe sie der Methode settransform vom Objektda weis ich nicht ob die Methode richtig ist.
bekomme leider nur die hälte der fps wenn ich das Modell in einzelnen stücken lade - als wie im gesamtenvoid Brick::setTransformation() { beginEditCP( m_TransformPtr,OSG::Transform::MatrixFieldMask ); m_TransformPtr->setMatrix( m_Matrix ); endEditCP ( m_TransformPtr, OSG::Transform::MatrixFieldMask ); beginEditCP( m_CoreNode, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask ); m_CoreNode->setCore(m_TransformPtr); m_CoreNode->addChild(m_BaseNode); endEditCP( m_CoreNode, OSG::Node::CoreFieldMask | OSG::Node::ChildrenFieldMask ); }
wie sieht das richtg aus?
m_Basenode ist die Node die ich mir geben lasse
da is das hereingeladene Objekt drin
Corenode ein neu erstellter member
und Transformptr auch, matrix auch ein übergebener memberDu solltest beim Laden deines Objektes die Baumstruktur manipulieren, nicht zur Laufzeit (setTransformation sieht aus, als würde es nicht nur zu Beginn aufgerufen werden).
Für eine direkte Manipulation der Transformation sollte man sich aus dem Transformationsknoten den TransformPtr irgendwo speichern und darin eine neue Matrix setzen.
-
bitte schreib mich per E-Mail an: matthias.asselborn at gmx.de
Das mit der Map passt soweit, die NodePtr werden gemappt und auch richtig
rausgeholt. Kann dir denCode gerne pr E-Mail zeigen.Der TransformPtr ist ein Member deshalb auch m_TransformPtr
Ich übergebe nun eine Matrix der Methode setTransform
und initialisiere wenn ein Objekt erstellt wird.Wie hänge ich richtig Objekte in den Scenengraph
mein geladenes Modell über eine Bibliothek von Objekten
welche dann reingeladen werden ist halb so schnell
wie wenn ich das Modell in eine wrl oder bin Datei speichere.
Sind da FieldContainer von Vorteil?hab in der Klasse Scene ne Methode addObject die ->addchild aufruft und dann
den RootPtr des Objektes übergibt
so mach ich es derzeit
geht das performanter?