Japanese
Leave Your Message

De structuur van het FBX-modelbestand uitgelegd

Het FBX-formaat wordt door vrijwel alle 3D-engines ondersteund en is een eigen formaat voor 3D-modellen, ontwikkeld door Autodesk. Het ondersteunt hoekpunten, indexen, normalenvlakken, UV-coördinaten, materialen en animaties.
Autodesk levert officieel de FBX SDK, waarmee FBX-bestanden of andere bibliotheken met hetzelfde doel kunnen worden geïmporteerd en geëxporteerd. De SDK biedt twee interfaces, een in C++ en een in Python.
Je kunt ook zelf FBX-parsers schrijven om afhankelijkheid van andere bibliotheken te voorkomen.
In dit artikel wordt de structuur van een FBX-bestand beschreven. Door deze structuur te begrijpen, kunnen we een aangepaste, lichtgewicht FBX-parser schrijven. Voor voorbeelden van aangepaste FBX-parsers kunt u de FBX Importer/Exporter-plugin van Blender raadplegen.
Het FBX-formaat is beschikbaar in ASCII (tekstbestand, leesbaar voor mensen) of binair.

    1. FBX-bestandsstructuur

    Dit is een voorbeeld van een FBX-bestand.
    Het eerste wat opvalt, is dat sommige regels met een puntkomma beginnen: dit zijn commentaarregels en moeten worden genegeerd bij het lezen van het bestand.
    Na de eerste opmerking wordt de identifier FBXHeaderExtension gevonden. Dit is het eerste hoofdknooppunt van de bestandsstructuur. Het FBX-bestandsformaat is inderdaad een boomstructuur die het volgende schema volgt:
    FBX-modelbestandsstructuur uitgelegd (1)
    Elk knooppunt of subknooppunt kan zijn eigen specifieke kenmerken hebben. Kenmerken kunnen ook buiten het hoofdknooppunt worden gevonden, maar kunnen meestal worden genegeerd. Over het algemeen is de basisstructuur van een knooppunt als volgt:
    knooppuntnaam: eventual_properties {
    Knooppunt_Eigenschap_1: waarde
    Knooppunt_Eigenschap_2: waarde
    Subnode1 : {
    Subnode_Property_1: waarde
    […]
    }
    Knooppunt_Eigenschap_3: waarde
    […]
    }
    Dit is een knooppunt (het eerste) dat in het voorbeeldbestand is gevonden:
    FBXHeaderExtension: {
    FBXHeaderVersion: 1003
    FBX-versie: 6100
    Aanmaaktijdstempel: {
    Versie: 1000
    Jaar: 2014
    Maand: 3
    Dag: 20
    Uur: 17
    Minuut: 38
    Tweede: 29
    Milliseconde: 0
    }
    Maker: "FBX SDK/FBX Plugins build 20070228"
    OtherFlags: {
    FlagPLE: 0
    }
    }
    Inzicht in de structuur is de basis voor het schrijven van een efficiënte parser.
    In het eerste knooppunt vinden we twee attributen (FBXHeaderVersion en FBXVersion) waarvan de waarden de formaatversies zijn. In dit geval is dat versie 6.1. De overige informatie kan worden genegeerd, tenzij men ook de aanmaakdatum (CreationTimeStamp) wil lezen.

    2. FBX-objectknooppunten

    Het belangrijkste knooppunt is zonder twijfel het objectknooppunt.
    Het objectknooppunt bevat de hoekpunten, indexen, normalenvlakken, UV-coördinaten en materialen van het model. De structuur ervan is als volgt:
    Objecten: {
    Model: 'modelnaam', 'Mesh' {
    [...]
    Hoekpunten: [...]
    PolygonVertexIndex: [...]
    LayerElementNormal: { }
    LayerElementUV: { }
    }
    Materiaal: 'materiaalnaam', '' { }
    [...]
    }

    3. FBX-vertex

    Zoals we hebben gezien, zijn de hoekpunten te vinden in de eigenschap 'Vertex' van de kindknooppunten van het model.
    De syntaxis is als volgt:
    Hoekpunten: v1_x, v1_y, v1_z, v2_x, v2_y, v2_z, [...]
    Elk hoekpunt heeft drie ruimtelijke coördinaten (x, y, z), gescheiden door komma's (die ook de hoekpunten van elkaar scheiden). De coördinaten worden uiteraard in decimale vorm weergegeven met punten.
    Een voorbeeld hiervan is het volgende:
    Hoekpunten: 0.000000,0.104800,39.291698,0.000000,0.043400,-44.424301,0.000000,38.654301,-41.818802,-0.000000,39.455002,44.424400
    De hoekpunten waaruit het model is opgebouwd, zijn:
    v1(0,000000,0,104800,39,291698)
    v2(00.000000,0.043400,-44.424301)
    v3(0,000000,38,654301,-41,818802)
    v4(0,000000,39,455002,44,424400)

    4. Vertexindex van FBX-polygoon

    De index is te vinden onder de eigenschap PolygonVertexIndex.
    FBX-bestanden kunnen driehoekige polygonen (driehoeken) of meer exporteren. De meeste bestanden exporteren vierhoekige polygonen (quads). De syntaxis is vergelijkbaar met die van hoekpunten, maar er is één ding om op te merken:
    PolygonVertexIndex: i1, i2,-i3, i4, i5,-i6,[...]
    PolygonVertexIndex: i1, i2, i3, -i4, i5, i6, i7, -i8, [...]
    De indexen waaruit een veelhoek bestaat, staan ​​in volgorde. Een negatieve index betekent dat het de laatste index van de veelhoek is. De index moet worden ingesteld op een positief getal, en vervolgens moet je er 1 van aftrekken!
    [Mocht je je afvragen waarom, dat komt omdat de oorspronkelijke index een alles-of-niets-principe hanteert met -1. Index 3 wordt bijvoorbeeld -4.]
    Het voorbeeld is als volgt:
    PolygonVertexIndex: 8,7,3,-7,4,8,7,-3,0,5,8,-5
    De polygonen waaruit het model is opgebouwd, zijn:
    p1(8,7,3,6)
    p2(4,8,7,2)
    p3(0,5,8,4)
    Merk op dat de index die het einde van de veelhoek aangeeft, is ingesteld op een positief getal, en trek daar vervolgens 1 van af.
    Let op: grafische kaarten hebben moeite met vierhoeken, dus elke veelhoek met vier zijden moet in twee driehoeken worden verdeeld voordat het model wordt weergegeven.

    5. FBX-normalen

    Normalen zijn te vinden onder het subknooppunt LayerElementNormal van de eigenschap Normals (dat op zijn beurt een subknooppunt is van Model). De syntax is hetzelfde als voor een van de hoekpunten, namelijk een reeks (x,y,z) coördinaten.
    Normalen: n1_x, n1_y, n1_z, n2_x, n2_y, n2_z, [...]
    Je moet letten op de eigenschap MappingInformationType, die de volgende waarden kan hebben:
    ▪ ByPolygon: per polygoon, wat betekent dat elke polygoon van het model een normaalvector heeft.
    ▪ ByPolygonVertex: verwerkt per polygoonpunt, wat betekent dat elk hoekpunt van elke polygoon in het model een normaalvector heeft. Als het model bijvoorbeeld 8 hoekpunten heeft die vier vierhoeken vormen, zijn er 16 normaalvectoren (1 normaalvector * 4 polygonen * 4 polygoonpunten). Houd er rekening mee dat game-engines meestal slechts één normaalvector per hoekpunt nodig hebben. Als je dus een hoekpunt met meer dan één normaalvector vindt, kun je de normaalvectoren na de eerste negeren of het gemiddelde van alle normaalvectoren berekenen (normal smoothing).
    ▪ ByVertex: verwerking per vertex, wat betekent dat elke vertex van het model een normaalvector heeft. Soms ook wel ByVertice genoemd, zoals in de Blender-exporteerfunctie staat. Ik denk dat de auteur Spaans is.
    ▪ ByEdge: verwerkt per rand, dit betekent dat elke rand van het model een normale (zeldzame) waarde heeft.
    ▪ AllSame: dit betekent dat elk hoekpunt van het model dezelfde normaalvector heeft, wat zeldzaam of onmogelijk is voor de meeste modellen.
    Een andere belangrijke eigenschap is de eigenschap ReferenceInformationType, die de volgende waarden kan hebben:
    ▪ Direct: geeft aan dat de normalen geordend zijn.
    ▪ IndexToDirect (of index in oudere versies van het FBX-formaat): geeft aan dat de volgorde van de normalvectoren wordt bepaald door de eigenschap NormalsIndex.
    Hieronder staat een grafisch voorbeeld dat wellicht duidelijker is dan de tekst. Het voorbeeldmodel is een vlak op de X- en Y-assen (dus alle hoekpunten hebben een Z-coördinaat van 0), bestaande uit 9 hoekpunten en 4 polygonen (vierhoeken). De afbeelding toont het vlak van bovenaf.
    FBX-modelbestandsstructuur uitgelegd (2)

    6. FBX UV-coördinaten

    De UV-coördinaten zijn te vinden in de UV-eigenschap onder het kindknooppunt LayerElementUV (dat op zijn beurt een kindknooppunt is van Model). De syntax is vergelijkbaar met die van vertices en normalenvlakken, maar er zullen uiteraard twee coördinaten zijn in plaats van drie.
    UV: u1, v1, u2, v2, [...]
    Je moet nog steeds letten op de eigenschappen MappingInformationType en ReferenceInformationType! Deze twee eigenschappen kunnen dezelfde waarden hebben als de normalen, dus dezelfde regels zijn van toepassing. De indexeigenschap (indien aanwezig, d.w.z. IndexToDirect is gedefinieerd) is UVIndex.