From Battlepedia
Jump to navigationJump to search
Type RenderWare
Object ID -
Games used Battle for Bikini Bottom
The SpongeBob SquarePants Movie
The Incredibles
Rise of the Underminer

JSP is an asset type which defines a 3D model. It's a RenderWare binary stream file. There are two types of JSP: the normal (model) has a format much similar to a DFF. They can be opened by RWAnalyze and other tools that work with RenderWare models. GTAModding has a lot of useful information regarding this format. The other format is used for visibility and collision data and is very different from a normal JSP/DFF, but still follows the layout of a RenderWare binary stream file, with three custom sections.

Format (Visibility/Collision JSP)

   int 0x00BEEF01 // section type
   int sectionSize // section size
   int 0x1400FFFF // renderware version
   char[4] CCOL
   int amount1
   int amount2
   struct unknown1 {
   int[2] unknown
   float[2] unknown
   struct unknown2 {
   short[2] unknown
   byte[2] unknown
   short unknown
   int 0x00BEEF02 // section type
   int sectionSize // section size
   int 0x1400FFFF // renderware version
   // big endian
   char[4] "JSP "
   int unknownAmount1 // usually 3
   int unknownAmount2
   int unknown1usually0
   int unknown2usually0
   int unknown3usually0
   struct unknown3{
   int[2] unknown
   int 0x00BEEF03 // section type
   int sectionSize // section size
   int 0x1400FFFF // renderware version
   int vertexCount
   float[vertexCount][3] vertices

Jason Hoerner's information on the custom JSP

JSP is actually self-named after me.  It stands for “Jason Space Partition”, a replacement for the “Binary Space Partition” supported by RenderWare.  It was based on RenderWare’s BSP format, but the key difference was that my version referenced external data also used for rendering, rather than storing a complete separate copy, saving memory.  And I wrote more efficient tool code to generate it, and runtime intersection code, but that’s more of an optimization, rather than something that directly affects how the format works.

The BSP/JSP format itself is a KD tree with overlap regions, used for spatial queries (like player collision or shadow intersection).  You can look up how a KD tree works on Wikipedia or whatever – I’ll try to explain the specifics of the overlap regions.  Here’s a diagram:

Jason space partitioning.png

The overlap region is defined by a pair of axis aligned planes (you’ll probably see two floating point numbers, kind of close to one another), which divide space into three regions, left, right, and overlap.  There is another value (probably 0,1,2 integer) that selects which axis it represents.  The blue triangles all go in the right branch of the KD tree, while the green triangles all go in the left branch.

When doing a spatial query, if your query is entirely to the right of right plane, you only need to go down the right branch of the tree.  If your query is entirely to the left of the left plane, you only go down the left branch.  If your query touches the overlap region, you need to go down both sides of the tree, because some triangles on both sides could be intersected.  If you’re doing a long thin query (like a ray or capsule), you can clip the ray or capsule to the overlap plane before recursing (which makes it smaller for the next query).

Regarding DFF, besides the JSP replacing BSP, and some post optimizations specific to PS2 command buffers, we didn’t do anything with the DFF importer, and used what RenderWare created verbatim.  So I can’t give details on the contents or import of a DFF.  But hopefully those basic details of the KD tree implementation will help some.

The editor we used for the game was called the “EvilEditor”, and I didn’t do any work on it myself.  It was named after Evil Dead, the first game Heavy Iron worked on, which was before I started working there.  I did do a lot of work on its successor, the “GoodEditor” (which was used for all of Heavy Iron’s post RenderWare games).  I can tell you all 3D geometry was built in Maya, and the EvilEditor itself was only used for object placement, setting object parameters, and scripting.

The scripting was all event based, there was no actual scripting language.  Objects could send events to other objects, and an FNV hash of the string name of each object was used as an identifier for the object to send it to.  Maybe searching for things that look like hashes (obviously not floats or integers) will make it obvious where events are present in the code.  The game included a system where updates of distant objects were turned off for performance, including a feature where you could group objects to all update together.  The “group update together” feature was used to ensure synced objects (like moving patterns of Tikis) would stay in the same pattern, and dependent objects (like teleport box pairs) would activate together.

I did the collision system.  It includes an outer sphere which does “move and de-penetrate” (let the character move and go inside triangles a bit, then try to push him back out), and an inner sphere which attempts to do continuous capsule based collision, so when moving very fast, he hopefully doesn’t go through anything, but obviously speed runners have figured out how to break that!  The outer sphere categorizes primitives as if the player is a cube, and picks the nearest collision along each face of the cube, and solves for where to place the character that’s outside of any collision.  With lots of special cases to try to make it not jitter, and hard to get stuck (if you compare to Scooby Doo, the previous game where I didn’t do the collision, that has nasty jitter).  I think Patrick has a second smaller sphere for the head, but I’m not sure…

Anyway, that’s the stuff I thought of for now, I’ll let you know if I think of anything else interesting…