snake-biscuits / bsp_tool

Python library for analysing .bsp files
GNU General Public License v3.0
102 stars 7 forks source link

DisplacementInfo Neighbours aren’t mapped yet #75

Open snake-biscuits opened 1 year ago

snake-biscuits commented 1 year ago

Displacement Neighbour sub-structs aren't mapped yet They're also nasty to pack / unpack, as they don't match the byte alignment of their parent

Look at #74 & #73 for then arguments in favour of using inheritance to simplify this nightmare (valve.source.DisplacementInfo can do the black magic and the others can copy)

Test Maps

Enjoy the pain

snake-biscuits commented 1 year ago

The Source Engine definitions for ddispinfo_t mess with how C/C++ packs structs to create some oddly aligned structures

Just kidding, everything is padded automatically

/* chaos_bsp.c */
typedef struct { float x, y, z; }  Vector;

struct DispSubNeighbor_t {
    unsigned int   neighbor;
    unsigned char  neighborOrient;
    unsigned char  span;
    unsigned char  neighborSpan;
};

struct DispNeighbor_t {
    struct DispSubNeighbor_t  neighbors[2];
};

struct DispCornerNeighbors_t {
    unsigned int   neighbors[4];
    unsigned char  neighborCount;
};

#define ALLOWEDVERTS_SIZE  10
struct ddispinfo_t {
    Vector                        startPosition;
    int                           m_iDispVertStart;
    int                           m_iDispTriStart;
    int                           power;
    int                           minTess;
    float                         smoothingAngle;
    int                           contents;
    unsigned int                  m_iMapFace;
    int                           m_iLightmapAlphaStart;
    int                           m_iLightmapSamplePositionStart;
    struct DispNeighbor_t         m_EdgeNeighbors[4];
    struct DispCornerNeighbors_t  m_CornerNeighbors[4];
    unsigned int                  m_AllowedVerts[ALLOWEDVERTS_SIZE];
};

int main(int argc, char *argv[]) {
    #define SHOW_SIZE(s)  printf("%32s | %lu\n", #s, sizeof(s))
    SHOW_SIZE(struct DispSubNeighbor_t);
    SHOW_SIZE(struct DispNeighbor_t);
    SHOW_SIZE(struct DispCornerNeighbors_t);
    SHOW_SIZE(struct ddispinfo_t);
    #undef SHOW_SIZE
    return 0;
}
$ ./chaos_bsp.exe
        struct DispSubNeighbor_t | 8
           struct DispNeighbor_t | 16
    struct DispCornerNeighbors_t | 20
              struct ddispinfo_t | 232

So, we only have to add padding members to each child struct & hook up classes No .from_bytes() & .as_bytes() overrides required!

snake-biscuits commented 1 year ago

Though I would like to make sure the LumpClasses use inheritance & add num_displacement_vertices & _triangles properties. If .bsp files can be thought of as SQL tables, I don't see why LumpClasses can't be VIEWs, rather than just TABLEs

snake-biscuits commented 1 year ago

valve.source.DisplacementInfo neighbours get read with bad alignment, getting garbage values in enums & padding

snake-biscuits commented 1 year ago

We need more robust testing on how displacements are parsed, especially neighbours This might require new displacement related methods in valve.source Just testing for valid start positions & displacement face connections would be a start

valid enum & padding == 0 checks are also relatively simple

snake-biscuits commented 1 year ago

The __repr__ is also really bad, a prettyprint __repr__ for the big displacement neighbours chunk would be really nice respawn.apex_legends.BVHNode.__repr__ already has a custom __repr__, should make for a good reference

We could even mimic the nice code comment diagrams from the Source SDK