Announcement

Collapse
No announcement yet.

uQuake - Load Quake 3 .bsp maps in Unity

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • uQuake - Load Quake 3 .bsp maps in Unity

    I'm working on a group of C# classes to load Quake 3 .bsps inside of the Unity game engine. It works pretty well. Geometry and non-shader textures are flawless, including bezier patches and lightmaps. I'm kind of proud of it.

    Here's the Github link if anyone is curious or wants to hack on it. Feel free to fork and have fun. https://github.com/mikezila/uQuake

    Here's a screenshot:
    http://imgur.com/KM3s836

    I'm here because I want to add support/create a sister project to do the same with Quake 1 maps, and need some guidance on rendering the level geometry from BSP29 files. I'm doing some reading on the format and it seems simple enough to get a vertex list for each face, and using dotproducts to get texture coords is a hassle but not monumentally so. What I'm really confused about is...where are the triangles? In Quake3/IBSP each face has a list of triangle indexes into its vertex array you can easily use to render that face, but BSP29 doesn't have triangles defined anywhere it seems.

    Am I missing something, or is it up to me to create some sorcery to figure out the triangles?
    Last edited by ALLCAPS; 10-14-2013, 12:49 AM.

  • #2
    I know nothing about this but, I am very interested in whatever answers you get.

    Excellent post.
    http://www.nextgenquake.com

    Comment


    • #3
      I haven't found any answers per se, but after studying the BSP29 specs a bit, it looks like all faces/polygons must be convex. If that's true it'd be pretty trivial to draw/divine triangles for a given surface by just picking a "pivot" point and then walking the other verts. Like 0-1-2, 0-2-3, 0-3-4, etc until you've made triangles for all of the verts on the face.

      Loading Quakespasm and turning on r_showtris it looks like that's what is happening.

      Comment


      • #4
        yes convex only.
        http://www.nextgenquake.com

        Comment


        • #5
          ALLCAPS,

          Func_Msgboard is the place to ask for directions, when talking about level design!

          You can actually find many of the Quake Gurus there!
          F�rum QuakeBrasil

          Lots of Quake related stuff


          Comment


          • #6
            Does this qualify as level design? He wants to parse out vectors from a bsp to be used in a non-Quake engine...
            http://www.nextgenquake.com

            Comment


            • #7
              Originally posted by vegetous View Post
              ALLCAPS,

              Func_Msgboard is the place to ask for directions, when talking about level design!

              You can actually find many of the Quake Gurus there!
              I lurk/post on func_ as well! Their coding help thread was very helpful in getting Quake 3 support working. I notice some programming wizards here as well, though, and I'll lurk anywhere there is a coding section.

              Also...

              I am hitting some issues with parsing Quake1 .bsp, though. Perhaps my understanding of variable type and size is not correct, but the file specs I linked above say that a face is thus:

              u_short plane_id;
              u_short side;
              long ledge_id;
              u_short ledge_num;
              etc...
              u_char light[2];
              long lightmap;

              Is an unsigned short int not two bytes? is a long not eight bytes, and a char one? I try to read the data out using that assumption and I get garbage. Looking at the offset where faces start It looks like either the specs are not right, or a short is one byte. I did notice the the BSP version in the file is 29 while the spec here is for version 28.

              Comment


              • #8
                In c, char, short, int, long, long long, all have relative and not exact lengths. as a result, its generally bad practise to write specs that depend upon them.

                Quake being a 32bit program, byte+char are both 1 octet, short is 2 octets, int+long are both 4 octets, long long is never encountered. any file format specs will generally follow the same rules.
                expressing things in terms of octets avoids confusion when a byte is 7 or 9 bits long...

                you'll often find 'long' used to refer to 32bit values in stuff dating from the early 32bit days because it avoids using int (which was 16bit back in the 16bit days while long was 32bit (probably emulated), and thus using long to mean 32bit avoided confusion at the time).
                nowadays however, long can mean 64bit with certain compilers, and thus should probably be avoided.

                #include <stdint.h>
                int8_t some8bitsvalue;
                int16_t some16bitsvalue;
                int32_t some32bitsvalue;
                int64_t some64bitsvalue;
                uint8_t some8bituvalue;
                uint16_t some16bituvalue;
                uint32_t some32bituvalue;
                uint64_t some64bituvalue;
                woo... bloody microsoft not supporting those typedefs for ages.
                Some Game Thing

                Comment


                • #9
                  Holy hell.

                  I was getting garbage because I was trying to read face structs from the wrong lump. In the ancient spec I was reading faces were in lump 8, in version 29 they are in lump 7. I have been staring at the wrong lump and wondering why I'm not getting the right data. Change to reading the correct lump and oh look, it's working perfectly.

                  I am a bad programmer and I should feel bad.

                  Comment


                  • #10
                    You seem like a pretty good programmer to me... Bad programmers don't figure stuff out. [[Goes back to watching "Dynamite Shaolin Heroes"]]
                    http://www.nextgenquake.com

                    Comment


                    • #11
                      I have it mostly working. Geometry is recreated, and texture coords are calculated correctly. Or at least I think they're correct, they scale and move like I expect them to playing around with them in trenchbroom.

                      Getting verts for each face was a little confusing at first with the double-lookup method it requires, but it wasn't that difficult. Same for texture coords; a little confusing at first, but simple in the end.

                      As a stress-test I loaded up Sock's Ivory Tower, and the result is a CRAZY 32k GameObjects!

                      THIRTY. TWO. THOUSAND. OBJECTS.

                      imgur: the simple image sharer

                      Marking the objects as static lets Unity batch them together, resulting in only about 2-5 draw calls at any given moment.

                      I replaced all of my Lists with arrays in the object generator, but startup performance with large maps didn't increase much. Premature optimization is the bane of many a project, though, so I think I'll focus on getting smaller maps (like my lame remake of dm_stalwart) working with textures and lightmaps before I start looking to juice performance.

                      Comment


                      • #12
                        hey, at least it all still fits in memory at once...
                        Some Game Thing

                        Comment

                        Working...
                        X