Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
trs:room_geometry [2020/05/19 12:42] – [Room Light Structure] zdimensiontrs:room_geometry [2024/12/13 18:40] (current) – [Room Vertex Structure] stohrendorf
Line 118: Line 118:
 ''<nowiki>BoxIndex</nowiki>'' is a pointer to special [[trs:npc_behaviour#boxes|[Boxes]]] array entry, which is basically a subset of sectors with same height configuration. It is primarily used for AI pathfinding (see the [[trs:npc_behaviour|Non-player character behaviour]] chapter for more details). ''<nowiki>BoxIndex</nowiki>'' is a pointer to special [[trs:npc_behaviour#boxes|[Boxes]]] array entry, which is basically a subset of sectors with same height configuration. It is primarily used for AI pathfinding (see the [[trs:npc_behaviour|Non-player character behaviour]] chapter for more details).
  
-{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}In these games, ''<nowiki>BoxIndex</nowiki>'' field is more complicated, and actually contains //two packed values//. Bits 4..14 contain the //actual box index//, and bits 0..contain //material index//, which is used to produce specific footstep sound, when Lara is walking or running in this sector. On PlayStation game versions, this index was also used to determine if footprint textures should be applied to this particular place. Both procedures are invoked via ''FOOTPRINT_FX'' flipeffect, which is described in [[trs:miscellany#flipeffects|corresponding section]].+{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}In these games, ''<nowiki>BoxIndex</nowiki>'' field is more complicated
 + 
 +<code cpp> 
 +struct tr3_room_sector // 8 bytes 
 +
 +    uint16_t FDindex;    // Index into FloorData[] 
 +    uint16_t Material : 4// Material index, used 
 +    uint16_t Box : 11; // Actual box index 
 +    uint16_t Stopper : 1; 
 +    uint8_t  RoomBelow;  // 255 is none 
 +    int8_t   Floor;      // Absolute height of floor 
 +    uint8_t  RoomAbove;  // 255 if none 
 +    int8_t   Ceiling;    // Absolute height of ceiling 
 +}; 
 +</code> 
 + 
 +^ Hex value ^ ''%%0x8000%%'' ^ ''%%0x7FF0%%'' ^^^^^^^^^^^ ''%%0x000F%%'' ^^^^ 
 +^ Bit ^ 15 ^ 14 ^ 13 ^ 12 ^ 11 ^ 10 ^ 9 ^ 8 ^ 7 ^ 6 ^ 5 ^ 4 ^ ^ 2 ^ 1 ^ 0 ^ 
 +^ Field |  ''%%Stopper%%''  |  ''%%Box%%''  |||||||||||  ''%%Material%%''  |||| 
 + 
 +''Material'' is the //material index//, which is used to produce specific footstep sound, when Lara is walking or running in this sector. On PlayStation game versions, this index was also used to determine if footprint textures should be applied to this particular place. Both procedures are invoked via ''FOOTPRINT_FX'' flipeffect, which is described in [[trs:miscellany#flipeffects|corresponding section]].
  
 Majority of //material index// values are the same across game versions, but some of them exist only in particular game. Here is the description: Majority of //material index// values are the same across game versions, but some of them exist only in particular game. Here is the description:
  
-   * **0** — Mud+  * **0** — Mud
   * **1** — Snow (TR3 and TR5 only)   * **1** — Snow (TR3 and TR5 only)
   * **2** — Sand   * **2** — Sand
Line 138: Line 158:
 Mud, snow, sand, grass and maybe some other materials produce footprints in PlayStation version. Mud, snow, sand, grass and maybe some other materials produce footprints in PlayStation version.
  
-Furthermore, in TR3-5, //actual box index//  may contain special value 2047, which is most likely indicates that this sector is a slope on which Lara can slide (and, therefore, possibly impassable by most NPCs).+Furthermore, in TR3-5, //actual box index//  may contain special value 2047 (full 1s), which is most likely indicates that this sector is a slope on which Lara can slide (and, therefore, possibly impassable by most NPCs).
  
 ==== Room Light Structure ==== ==== Room Light Structure ====
  
-<note> TR engines always used static room lights only for processing lighting on entities (such as Lara, enemies, doors, and others). This is called //external lighting//. For room meshes, they used so-called internal, or //pre-baked//  lighting, which is done on level building stage: lights are calculated and applied to room faces via vertex colours. There is no way to change room lighting when the level is compiled — meaning, any changes in light positions, intensities and colour won’t affect room faces. </note>+<note> TR engines always used static room lights only for processing lighting on entities (such as Lara, enemies, doors, and others). This is called //external lighting//. For room meshes, they used so-called internal, or //pre-baked// lighting, which is done on level building stage: lights are calculated and applied to room faces via vertex colours. There is no way to change room lighting when the level is compiled — meaning, any changes in light positions, intensities and colour won’t affect room faces. </note>
  
 There are four different types of room light structures. First one is used in TR1-2, second is used in TR3, third is used in TR4, and fourth is used in TR5. Here is the description of each: There are four different types of room light structures. First one is used in TR1-2, second is used in TR3, third is used in TR4, and fourth is used in TR5. Here is the description of each:
Line 157: Line 177:
     uint32_t Fade1;         // Falloff value     uint32_t Fade1;         // Falloff value
 }; };
-</code> 
  
-''<nowiki>X/Y/Z</nowiki>''  are in world coordinates. ''<nowiki>Intensity1/Intensity2</nowiki>''  are almost always equal. This lighting only affects //externally-lit//  objects. Tomb Raider 1 has only the first of the paired ''<nowiki>Intensity</nowiki>''  and ''<nowiki>Fade</nowiki>''  values.+</code>
  
-''<nowiki>Intensity1</nowiki>''  ranges from ''0'' (dark) to ''0x1FFF'' (bright)However, some rooms occasionally have some lights with intensity greater than ''0x1FFF'' (for example, look at room #9, 2nd light in ''<nowiki>level1.phd</nowiki>''). ''<nowiki>Fade1</nowiki>''  is the maximum distance the light shines on, and ranges from ''0'' to ''0x7FFF''.+''<nowiki>X/Y/Z</nowiki>'' are in world coordinates. ''<nowiki>Intensity1/Intensity2</nowiki>'' are almost always equalThis lighting only affects //externally-lit// objects. Tomb Raider 1 has only the first of the paired ''<nowiki>Intensity</nowiki>'' and ''<nowiki>Fade</nowiki>'' values.
  
 +''<nowiki>Intensity1</nowiki>'' ranges from ''0'' (dark) to ''0x1FFF'' (bright). However, some rooms occasionally have some lights with intensity greater than ''0x1FFF'' (for example, look at room #9, 2nd light in ''<nowiki>level1.phd</nowiki>''). ''<nowiki>Fade1</nowiki>'' is the maximum distance the light shines on, and ranges from ''0'' to ''0x7FFF''.
 === TR2 Room Lighting === === TR2 Room Lighting ===
  
Line 178: Line 198:
     uint32_t Fade2;         // Only in TR2     uint32_t Fade2;         // Only in TR2
 }; };
 +
 </code> </code>
  
-''<nowiki>Intensity2</nowiki>''  and ''<nowiki>Fade2</nowiki>''  values are seemingly not used. ''<nowiki>Intensity1</nowiki>''  can go very well beyond ''0x1FFF'', right to ''0x7FFF'' (ultra bright light). Above ''0x7FFF'', it is always black, so the number is pseudo-signed (negative values are always treated as zero). +''<nowiki>Intensity2</nowiki>'' and ''<nowiki>Fade2</nowiki>'' values are seemingly not used. ''<nowiki>Intensity1</nowiki>'' can go very well beyond ''0x1FFF'', right to ''0x7FFF'' (ultra bright light). Above ''0x7FFF'', it is always black, so the number is pseudo-signed (negative values are always treated as zero).
 === TR3 Room Lighting === === TR3 Room Lighting ===
  
Line 194: Line 214:
       tr_colour Colour;        // Colour of the light       tr_colour Colour;        // Colour of the light
         uint8_t LightType;     // Only 2 types - sun and point lights         uint8_t LightType;     // Only 2 types - sun and point lights
-    union 
-    { 
-        tr3_room_sun; 
-        tr3_room_point; 
-    }; 
-}; 
-</code> 
  
-Depending on ''LightType'', last 2 bytes are parsed differently: +  if (LightType == 0) // Sun 
- +  
-{{anchor:tr3_room_sun}} +        int16_t nx, ny, nz; // Most likely a normal
-<code cpp> +
-struct tr3_room_sun // 8 bytes +
-+
-        int16_t nx, ny, nz; // Normal?+
         int16_t Unused;         int16_t Unused;
-}; +  
-</code> +  else if (LightType == 1) // Point 
- +  {
-''nx'', ''ny'' and ''nz'' is most likely a normal. +
- +
-{{anchor:tr3_room_sun}} +
-<code cpp> +
-struct tr3_room_point // 8 bytes +
-{+
         int32_t Intensity;         int32_t Intensity;
         int32_t Fade;          // Falloff value         int32_t Fade;          // Falloff value
 +  }
 }; };
 +
 </code> </code>
  
-''<nowiki>Intensity</nowiki>'' is the power of the light and ranges mainly from ''0'' (low power) to ''0x1FFF'' (high power). +''<nowiki>Intensity</nowiki>'' is the power of the light and ranges mainly from ''0'' (low power) to ''0x1FFF'' (high power). ''<nowiki>Fade</nowiki>'' is the distance max the light can shine on. Range is mainly from ''0'' to ''0x7FFF''.
-''<nowiki>Fade</nowiki>'' is the distance max the light can shine on. Range is mainly from ''0'' to ''0x7FFF''. +
 === TR4 Room Lighting === === TR4 Room Lighting ===
  
Line 248: Line 251:
           float dx, dy, dz;    // Direction - used only by sun and spot lights           float dx, dy, dz;    // Direction - used only by sun and spot lights
 }; };
 +
 </code> </code>
  
 ''<nowiki>LightType</nowiki>'' was extended and is now somewhat similar to D3D light type, but there are some differences. ''<nowiki>LightType</nowiki>'' was extended and is now somewhat similar to D3D light type, but there are some differences.
  
-  * **0** — Sun+   * **0** — Sun
   * **1** — Light   * **1** — Light
   * **2** — Spot   * **2** — Spot
Line 283: Line 287:
         float r, g, b;       // Colour of the light         float r, g, b;       // Colour of the light
  
-       uint32_t Separator    // Dummy value = 0xCDCDCDCD+       uint32_t shadow;    // Dummy value = 0xCDCDCDCD
  
         float In;            // Cosine of the IN value for light / size of IN value         float In;            // Cosine of the IN value for light / size of IN value
Line 299: Line 303:
       uint8_t Filler[3];     // Dummy values = 3 x 0xCD       uint8_t Filler[3];     // Dummy values = 3 x 0xCD
 }; };
 +
 +</code>
 +
 +<code cpp>
 +struct tr5_fog_bulb   // 36 bytes
 +{
 +        float x, y, z;       // Position of light, in world coordinates
 +        float rad, sqrad;
 +        float den;
 +        float r, g, b;
 +};
 +
 </code> </code>
  
Line 314: Line 330:
  
 ''<nowiki>x2</nowiki>'', ''<nowiki>y2</nowiki>'', ''<nowiki>z2</nowiki>'', ''<nowiki>dx2</nowiki>'', ''<nowiki>dy2</nowiki>''  and ''<nowiki>dz2</nowiki>''  values repeat previous corresponding information in long data types instead of floats. ''<nowiki>x2</nowiki>'', ''<nowiki>y2</nowiki>'', ''<nowiki>z2</nowiki>'', ''<nowiki>dx2</nowiki>'', ''<nowiki>dy2</nowiki>''  and ''<nowiki>dz2</nowiki>''  values repeat previous corresponding information in long data types instead of floats.
 +
  
 ==== Room Vertex Structure ==== ==== Room Vertex Structure ====
Line 347: Line 364:
        int16_t Lighting;        int16_t Lighting;
       uint16_t Attributes; // A set of flags for special rendering effects       uint16_t Attributes; // A set of flags for special rendering effects
-       int16_t Lighting2 // Almost always equal to Lighting1+       int16_t RenderedLighting; // Internal field to store the actually rendered lighting
 }; };
 </code> </code>
Line 373: Line 390:
 ''<nowiki>Lighting</nowiki>''  value is ignored by the engine, as now each vertex has its own defined 15-bit colour (see below). ''<nowiki>Lighting</nowiki>''  value is ignored by the engine, as now each vertex has its own defined 15-bit colour (see below).
  
-''<nowiki>Attributes</nowiki>''  bit flags were extended. Here is the list:+''<nowiki>Attributes</nowiki>''  bit flags were extended. Also, old bits 0..4 aren't working properly anymore, because effect lighting was broken in TR3.  Here is the list of new flags:
  
   * //Bit 13://  Water / quicksand surface “wave” movement. Brightness is also shifting, if this flag is set (but it’s not the same type as with //Bit 14//, it’s much less noticeable).   * //Bit 13://  Water / quicksand surface “wave” movement. Brightness is also shifting, if this flag is set (but it’s not the same type as with //Bit 14//, it’s much less noticeable).
   * //Bit 14://  Simulates caustics by constantly shifting vertex colour brightness. Used mainly in underwater rooms, but can be used in rooms without water. In TR2, there was a similar effect, but it was assigned for all vertices in any water room.   * //Bit 14://  Simulates caustics by constantly shifting vertex colour brightness. Used mainly in underwater rooms, but can be used in rooms without water. In TR2, there was a similar effect, but it was assigned for all vertices in any water room.
-  * //Bit 15://  Same “wave” effect as with //Bit 13//, but without light effect (?). +  * //Bit 15:// {{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Broken in these game versions. Instead, same "waveeffect is produced as with //Bit 13//, but with slightly less glow.
-<note> The amplitude of the “wave” effect depends on ''<nowiki>WaterScheme</nowiki>''  value specified in room structure. </note>+
  
 ''<nowiki>Colour</nowiki>''  value specifies vertex colour in 15-bit format (each colour occupies 5 bits). Therefore, each colour value’s maximum is //31//. You can use this code to get each colour: ''<nowiki>Colour</nowiki>''  value specifies vertex colour in 15-bit format (each colour occupies 5 bits). Therefore, each colour value’s maximum is //31//. You can use this code to get each colour:
Line 525: Line 541:
     uint16_t NumLayerVertices;   // Number of vertices in this layer (2 bytes)     uint16_t NumLayerVertices;   // Number of vertices in this layer (2 bytes)
     uint16_t NumLayerVerticesWater; // Number of underwater vertices in this layer (2 bytes)     uint16_t NumLayerVerticesWater; // Number of underwater vertices in this layer (2 bytes)
-    uint16_t UnknownL1;+    uint16_t NumLayerVerticesShore;
     uint16_t NumLayerRectangles; // Number of rectangles in this layer (2 bytes)     uint16_t NumLayerRectangles; // Number of rectangles in this layer (2 bytes)
     uint16_t NumLayerTriangles;  // Number of triangles in this layer (2 bytes)     uint16_t NumLayerTriangles;  // Number of triangles in this layer (2 bytes)
-    uint16_t UnknownL2;+    uint16_t NumLayerRectanglesWater// Number of rectangles containing water vertices 
 +    uint16_t NumLayerTrianglesWater; // Number of trianglescontaining water vertices
  
     uint16_t Filler;             // Always 0     uint16_t Filler;             // Always 0
-    uint16_t Filler2;            // Always 0 
  
     // The following 6 floats define the bounding box for the layer     // The following 6 floats define the bounding box for the layer
Line 542: Line 558:
     float    LayerBoundingBoxZ2;     float    LayerBoundingBoxZ2;
  
-    uint32_t Filler3;     // Always 0 (4 bytes)+    uint32_t Filler3;     // Always 0 (4 bytes), internal pointer
     uint32_t VerticesOffset;   // Those fields are overwritten at level loading      uint32_t VerticesOffset;   // Those fields are overwritten at level loading 
     uint32_t PolyOffset;       // by the ones present in the tr5_room struct + an offset     uint32_t PolyOffset;       // by the ones present in the tr5_room struct + an offset
-    uint32_t PolyOffset2;      // i.e. the values are not read, the fields are there for storage purposes+    uint32_t PrelightOffset;      // i.e. the values are not read, the fields are there for storage purposes
 } }
 </code> </code>
  
-''<nowiki>UnknownL2</nowiki>''  appears to be the number of double sided textures in this layer, however is sometimes 1 off (2 bytes).+''<nowiki>NumLayerVerticesShore</nowiki>''  appears to be the number of double sided textures in this layer, however is sometimes 1 off (2 bytes).
  
 ===== The Whole Room Structure ===== ===== The Whole Room Structure =====
Line 662: Line 678:
     uint16_t NumZsectors;                                  // ``Width'' of sector list     uint16_t NumZsectors;                                  // ``Width'' of sector list
     uint16_t NumXsectors;                                  // ``Height'' of sector list     uint16_t NumXsectors;                                  // ``Height'' of sector list
-    tr_room_sector SectorList[NumXsectors * NumZsectors];  // List of sectors in this room+    tr3_room_sector SectorList[NumXsectors * NumZsectors];  // List of sectors in this room
  
-    int16_t AmbientIntensity1;  // This and the next one only affect externally-lit objects +    int16_t AmbientIntensity;  // Affects externally-lit objects 
-    int16_t LightMode;  // Same as in TR2+    int16_t LightMode;  // Broken in this game version
          
     uint16_t NumLights;                 // Number of point lights in this room     uint16_t NumLights;                 // Number of point lights in this room
Line 703: Line 719:
     uint16_t NumZsectors;                                  // ``Width'' of sector list     uint16_t NumZsectors;                                  // ``Width'' of sector list
     uint16_t NumXsectors;                                  // ``Height'' of sector list     uint16_t NumXsectors;                                  // ``Height'' of sector list
-    tr_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room+    tr3_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room
  
     uint32_t RoomColour;        // In ARGB format!     uint32_t RoomColour;        // In ARGB format!
Line 729: Line 745:
 ==== TR5 Room Structure ==== ==== TR5 Room Structure ====
  
-As it was mentioned before, TR5 room structure was almost completely changed, when compared to previous versions. For example, TR5 completely throws out a concept of [[trs:room_geometry#tr_room_data|[tr_room_data]]] structure, shuffles numerous values and structures in almost chaotic manner, and introduces a bunch of completely new parameters (mostly to deal with //layers//). Also, there is vast amount of //fillers//  and //separators//, which contain no specific data.+As it was mentioned before, TR5 room structure was almost completely changed, when compared to previous versions. For example, TR5 shuffles numerous values and structures in almost chaotic manner, and introduces a bunch of completely new parameters (mostly to deal with //layers//). Also, there is vast amount of //fillers// and //separators//, which contain no specific data. 
 + 
 +<note> The one possible reason for such ridiculous structure change is an attempt to //crypt file format//, so it won’t be accessed by unofficial level editing tools, which received major development by that time. Another possible reason is whole TR5 development process was rushed, as the team developed //Tomb Raider: Angel of Darkness// at the very same time. </note>
  
-<note> The one possible reason for such ridiculous structure change is an attempt to //crypt file format//so it won’t be accessed by unofficial level editing tools, which received major development by that timeAnother possible reason is whole TR5 development process was rushed, as the team developed //Tomb Raider: Angel of Darkness//  at the very same time. </note>+<note> There are multiple pointer fields in the structure, they are relative to the **end** of the ''tr5_room'' structurei.e. to the beginning of the ''tr5_room_data'' structure.</note>
  
-{{anchor:tr5_room}}+ {{anchor:tr5_room}}
  
 <code cpp> <code cpp>
-virtual struct tr5_room // (variable length)+struct tr5_room // 216 bytes
 { {
     char XELA[4];           // So-called "XELA landmark"     char XELA[4];           // So-called "XELA landmark"
  
-    uint32_t RoomDataSize;+    uint32_t RoomDataSize; // size of following fields (208 bytes) + tr5_room_data (dynamic)
  
-    uint32_t Separator    // 0xCDCDCDCD (4 bytes)+    char* RoomData; // is filled by the game at run time. Always 0xCDCDCDCD in level files (4 bytes),
  
-    uint32_t EndSDOffset+    uint16_t* NumPortals// points to tr5_room_data.NumPortals 
-    uint32_t StartSDOffset;+    tr3_room_sector* SectorList// points to tr5_room_data.SectorList
  
-    uint32_t Separator;     // Either 0 or 0xCDCDCDCD+    tr5_room_light* Lights;     // points to tr5_room_data.Lights
  
-    uint32_t EndPortalOffset;+    tr3_room_staticmesh* StaticMeshes// points to tr5_room_data.StaticMeshes
  
     tr5_room_info info;     tr5_room_info info;
Line 763: Line 781:
     uint8_t  ReverbInfo;     uint8_t  ReverbInfo;
     uint8_t  AlternateGroup;     uint8_t  AlternateGroup;
-    uint16_t WaterScheme; 
  
-    uint32_t Filler[2];    // Both always 0x00007FFF +    int8_t MeshEffect; 
-    uint32_t Separator[2]; // Both always 0xCDCDCDCD +    int8_t bound_active; 
-    uint32_t Filler;       // Always 0xFFFFFFFF+ 
 +    int16_t left;         // always 0x7FFF 
 +    int16_t right       // always 0 
 +    int16_t top;          // always 0x7FFF 
 +    int16_t bottom;       // always 0 
 + 
 +    int16_t test_left;    // always 0xCDCD 
 +    int16_t test_right;   // always 0xCDCD 
 +    int16_t test_top;     // always 0xCDCD 
 +    int16_t test_bottom;  // always 0xCDCD 
 + 
 +    int16_t item_number;  // always 0xFFFF (-1) 
 +    int16_t fx_number;    // always 0xFFFF (-1)
  
     uint16_t AlternateRoom;     uint16_t AlternateRoom;
     uint16_t Flags;     uint16_t Flags;
  
-    uint32_t Unknown1+    uint32_t nVerts
-    uint32_t Unknown2;     // Always 0 +    uint32_t nWaterVerts;     // Always 0 
-    uint32_t Unknown3;     // Always 0+    uint32_t nShoreVerts;     // Always 0
  
-    uint32_t Separator;    // 0xCDCDCDCD+    uint32_t Separator;    // 0xCDCDCDCD, internally a pointer
  
-    uint16_t Unknown4; +    uint32_t Separator// internally a pointer to the face data
-    uint16_t Unknown5;+
  
     float RoomX;     float RoomX;
Line 785: Line 813:
     float RoomZ;     float RoomZ;
  
-    uint32_t Separator[4]; // Always 0xCDCDCDCD +    uint32_t vnormals; // internal pointer 
-    uint32_t Separator;    // 0 for normal rooms and 0xCDCDCDCD for null rooms +    uint32_t fnormals// internal pointer 
-    uint32_t Separator   // Always 0xCDCDCDCD+    uint32_t prelight; // internal pointer 
 +    uint32_t prelightwater; // internal pointer 
 +    uint32_t watercalc; // internal pointer, 0 for normal rooms and 0xCDCDCDCD for null rooms 
 +    uint32_t verts; // internal pointer
  
     uint32_t NumRoomTriangles;     uint32_t NumRoomTriangles;
     uint32_t NumRoomRectangles;     uint32_t NumRoomRectangles;
  
-    uint32_t Separator    // Always 0+    tr5_room_light* RoomLights; // points to tr5_room_data.RoomLights 
 +    tr5_fog_bulb* FogBulbs; // points to tr5_room_data.FogBulbs
  
-    uint32_t LightDataSize; 
     uint32_t NumLights2;    // Always same as NumLights     uint32_t NumLights2;    // Always same as NumLights
  
-    uint32_t Unknown6;+    uint32_t NumFogBulbs;
  
     int32_t RoomYTop;     int32_t RoomYTop;
Line 804: Line 835:
     uint32_t NumLayers;     uint32_t NumLayers;
  
-    uint32_t LayerOffset+    tr5_room_layer* Layers// points to tr5_room_data.Layers 
-    uint32_t VerticesOffset+    tr5_room_vertex* Vertices// points to tr5_room_data.Vertices 
-    uint32_t PolyOffset; +    void* PolyOffset; // points to tr5_room_data.Faces 
-    uint32_t PolyOffset2  // Same as PolyOffset+    void* PrelightOffset; // points to tr5_room_data.Faces, internal?
  
     uint32_t NumVertices;     uint32_t NumVertices;
  
-    uint32_t Separator[4];  // Always 0xCDCDCDCD +    // Always 0xCDCDCDCD 
 +    float fLeft; 
 +    float fRight; 
 +    float fTop; 
 +    float fBottom; 
 +
 +// immediately after 
 +virtual struct tr5_room_data 
 +{
     tr5_room_light Lights[NumLights];    // Data for the lights (88 bytes * NumRoomLights)     tr5_room_light Lights[NumLights];    // Data for the lights (88 bytes * NumRoomLights)
-    tr_room_sector SectorList[NumXSectors * NumZSectors]; // List of sectors in this room+    tr5_fog_bulb FogBulbs[NumFogBulbs];      // Data for the fog bulbs (36 bytes * NumFogBulbs) 
 +    tr3_room_sector SectorList[NumXSectors * NumZSectors]; // List of sectors in this room
  
     uint16_t NumPortals;                 // Number of visibility portals to other rooms     uint16_t NumPortals;                 // Number of visibility portals to other rooms
Line 829: Line 868:
     tr5_room_vertex Vertices[NumVertices];     tr5_room_vertex Vertices[NumVertices];
 } }
 +
 </code> </code>
  
-''<nowiki>XELA</nowiki>''  landmark seemingly serves as a header for room structure. It is clear that //XELA//  is a reversed //ALEX//, which is most likely the name of TR5 programmer, //Alex Davis//. It probably indicates that Alex Davis is responsible for changes in room structures.+''<nowiki>XELA</nowiki>'' landmark seemingly serves as a header for room structure. It is clear that //XELA// is a reversed //ALEX//, which is most likely the name of TR5 programmer, //Alex Davis//. It probably indicates that Alex Davis is responsible for changes in room structures.
  
-''<nowiki>RoomDataSize</nowiki>''  is a handy value determining the size of the following data. You can use this value to quickly //parse thru//  to the next room.+''<nowiki>RoomDataSize</nowiki>'' is a handy value determining the size of the following data. You can use this value to quickly //parse thru// to the next room.
  
-''<nowiki>EndSDOffset</nowiki>'': usually this number ''<nowiki>+216</nowiki>''  will give you the offset from the start of the room data to the end of the ''<nowiki>SectorData</nowiki>''  sectionHowever, it is known that this uint32_t could be equal to ''<nowiki>0xFFFFFFFF</nowiki>''so to calculate the end of ''<nowiki>SectorData</nowiki>'', it is better to use the following value $StartSDOffset + 216 + ((NumXSectors \cdot NumZSectors) \cdot 8)$, if you need to obtain this information.+''<nowiki>RoomX</nowiki>''''<nowiki>RoomY</nowiki>'' and ''<nowiki>RoomZ</nowiki>'' values are positions of room in world coordinates**NOTE:** If room is //null room//then each of these values will be ''<nowiki>0xCDCDCDCD</nowiki>''.
  
-''<nowiki>StartSDOffset</nowiki>'': This number ''<nowiki>+216</nowiki>''  will give you the offset from the start of the room to the start of the ''<nowiki>SectorData</nowiki>''  section.+''<nowiki>NumRoomTriangles</nowiki>'' and ''<nowiki>NumRoomRectangles</nowiki>'' are respectively the numbers of triangular and rectangular faces in a given room. **NOTE:** If room is //null room//, each of these values will be ''<nowiki>0xCDCDCDCD</nowiki>''.
  
-''<nowiki>EndPortalOffset</nowiki>'': this number ''<nowiki>+216</nowiki>''  will give you the offset from the start of the room to the end of the portal data.+''<nowiki>LightDataSize</nowiki>'' is the size of the light data in bytes (//not// in [[:trs:room_geometry#tr5_room_light|[tr5_room_light]]] units).
  
-''<nowiki>RoomX</nowiki>''''<nowiki>RoomY</nowiki>''  and ''<nowiki>RoomZ</nowiki>''  values are positions of room in world coordinates. **NOTE:**  If room is //null room//, then each of these values will be ''<nowiki>0xCDCDCDCD</nowiki>''.+''<nowiki>RoomYTop</nowiki>'' and ''<nowiki>RoomYBottom</nowiki>'' are equal to ''<nowiki>yTop</nowiki>'' and ''<nowiki>yBottom</nowiki>'' values in [[:trs:room_geometry#tr_room_info|[tr_room_info]]] structure. If room is //null room//, both of these values are ''<nowiki>0xCDCDCDCD</nowiki>''.
  
-''<nowiki>NumRoomTriangles</nowiki>''  and ''<nowiki>NumRoomRectangles</nowiki>''  are respectively the numbers of triangular and rectangular faces in a given room. **NOTE:**  If room is //null room//, each of these values will be ''<nowiki>0xCDCDCDCD</nowiki>''.+''<nowiki>NumLayers</nowiki>'' is a number of layers (volumes) in this room.
  
-''<nowiki>LightDataSize</nowiki>''  is the size of the light data in bytes (//not//  in [[trs:room_geometry#tr5_room_light|[tr5_room_light]]] units).+''<nowiki>VerticesSize</nowiki>'' is the size of vertex data block in bytes. Therefore, it //must// be a multiple of [[:trs:room_geometry#tr5_room_vertex|[tr5_room_vertex]]] size, else it means the block size is wrong.
  
-''<nowiki>Unknown6</nowiki>''  could probably be copy of ''<nowiki>ReverbInfo</nowiki>''  (see further), as its value usually ranges from 0 to 3. It is used for fog bulbs in TR5.+''<nowiki>Faces</nowiki>'' is sequential data array for the room polygons (both [[:trs:fundamentals#tr_face4|[tr_face4]]] and [[:trs:fundamentals#tr_face3|[tr_face3]]]),
  
-''<nowiki>RoomYTop</nowiki>''  and ''<nowiki>RoomYBottom</nowiki>''  are equal to ''<nowiki>yTop</nowiki>''  and ''<nowiki>yBottom</nowiki>''  values in [[trs:room_geometry#tr_room_info|[tr_room_info]]] structureIf room is a //null room//both of these values are ''<nowiki>0xCDCDCDCD</nowiki>''.+<note> ''<nowiki>Faces</nowiki>'' array is strictly linked with ''<nowiki>NumLayers</nowiki>'' valueThe data is sequentially structured for each layer — at first it lists first layer’s rectangles then trianglesfollowed by the second layer’s rectangles and triangles, and so on, until all layers are done. </note>
  
-''<nowiki>NumLayers</nowiki>''  is a number of layers (volumes) in this room. 
- 
-''<nowiki>LayerOffset</nowiki>'': this number ''<nowiki>+216</nowiki>''  will give you an offset from the start of the room data to the start of the layer data. 
- 
-''<nowiki>VerticesOffset</nowiki>'': this number ''<nowiki>+216</nowiki>''  will give you an offset from the start of the room data to the start of the verex data. 
- 
-''<nowiki>PolyOffset</nowiki>'': this number ''<nowiki>+216</nowiki>''  will give you an offset from the start of the room data to the start of the rectangle/triangle data. 
- 
-''<nowiki>VerticesSize</nowiki>''  is the size of vertex data block in bytes. Therefore, it //must//  be a multiple of [[trs:room_geometry#tr5_room_vertex|[tr5_room_vertex]]] size, else it means the block size is wrong. 
- 
-''<nowiki>Faces</nowiki>''  is a sequential data array for the room polygons (both [[trs:fundamentals#tr_face4|[tr_face4]]] and [[trs:fundamentals#tr_face3|[tr_face3]]]), 
- 
-<note> ''<nowiki>Faces</nowiki>''  array is strictly linked with ''<nowiki>NumLayers</nowiki>''  value. The data is sequentially structured for each layer — at first it lists first layer’s rectangles then triangles, followed by the second layer’s rectangles and triangles, and so on, until all layers are done. </note> 
  
 ==== Common Fields of a Room Structure ==== ==== Common Fields of a Room Structure ====
  
-''<nowiki>Flags</nowiki>''  is an array of various flag bits, which meaning is as follows:+''<nowiki>Flags</nowiki>'' is an array of various flag bits, which meaning is as follows:
  
-  * **Bit 0** — Room is filled with water. Sound effects played without internal flag ''SFX_WATER'' (''0x01'') will not play. +   * **Bit 0** — Room is filled with water. Sound effects played without internal flag ''SFX_WATER''  (''0x01'') will not play. 
-  * **Bit 3** — {{:icons:tr2.png?nolink&}}{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Set if the //skybox//  can be seen from this room. Used to speed things up: if no rendered room has this bit set, then the sky can never been seen, so it is not rendered. Else, if at least one visible room has this bit set, then the sky must be drawn because it is (could be) visible. +  * **Bit 3** — {{:icons:tr2.png?nolink&}}{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Set if the //skybox//  can be seen from this room. Used to speed things up: if no rendered room has this bit set, then the sky can never been seen, so it is not rendered. Else, if at least one visible room has this bit set, then the sky must be drawn because it is (could be) visible. 
-  * **Bit 5** — {{:icons:tr2.png?nolink&}}{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Lara’s ponytail gets blown by the wind. Beginning with TR3, some particle types are also be blown, if they end up in such room (particle type is specified by certain particle flag). +  * **Bit 5** — {{:icons:tr2.png?nolink&}}{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Lara’s ponytail gets blown by the wind. Beginning with TR3, some particle types are also be blown, if they end up in such room (particle type is specified by certain particle flag). 
-  * **Bit 6** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Room is inside. Used in official levels. No apparent effects. +  * **Bit 6** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Room is inside. Used in official levels. No apparent effects. 
-  * **Bit 7** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Different meaning in TR3 and TR4/5. In TR3, it means that room is filled with quicksand, while in TR4/5 it presumably blocks //global lens flare//  from appearing in that room (in TRLE, checkbox which sets this flag is named //NL//). +  * **Bit 7** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Different meaning in TR3 and TR4/5. In TR3, it means that room is filled with quicksand, while in TR4/5 it presumably blocks //global lens flare//  from appearing in that room (in TRLE, checkbox which sets this flag is named //NL//)
-  * **Bit 8** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Creates //caustics effect//  similar to that used in water rooms. TRLE sets this bit when the M option is used (in the same time, the degree of fading intensity typed by the user is put in the ''<nowiki>water_scheme</nowiki>''  byte). +  * **Bit 8** — {{:icons:tr1.png?nolink&16x16}}Skybox-like room. These must be rendered before other rooms with depth testing disabled, as these skybox rooms generally overlap each other and depth testing generall leads to z-fightig flickering
-  * **Bit 9** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} The room has some //water reflectivity//. TRLE sets this bit when the R (//reflectivity//) option is used (in the same time, the amount of reflectivity typed by the user + 5 is put in the ''<nowiki>water_scheme</nowiki>''  byte). When the flag is set for normal room and there is water room below it, game engine creates “reflection effect” above the water surface — effectively it means that all the vertices at the bottom of the room receive caustics effect described well above.+  * **Bit 8** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Creates //caustics effect//  similar to that used in water rooms. TRLE sets this bit when the M option is used (in the same time, the degree of fading intensity typed by the user is put in the ''<nowiki>water_scheme</nowiki>''  byte). 
 +  * **Bit 9** — {{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}The room has some //water reflectivity//. TRLE sets this bit when the R (//reflectivity//) option is used (in the same time, the amount of reflectivity typed by the user + 5 is put in the ''<nowiki>water_scheme</nowiki>''  byte). When the flag is set for normal room and there is water room below it, game engine creates “reflection effect” above the water surface — effectively it means that all the vertices at the bottom of the room receive caustics effect described well above.
   * **Bit 10** — unused. Was re-used in NGLE as a flag specifying //room with snow//.   * **Bit 10** — unused. Was re-used in NGLE as a flag specifying //room with snow//.
-  * **Bit 11** — {{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Not found in any original TR levels, but when the //D//  flag is set in the TRLE, this bit is set. Was re-used in NGLE as a flag specifying //room with rain//. +  * **Bit 11** — {{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Not found in any original TR levels, but when the //D//  flag is set in the TRLE, this bit is set. Was re-used in NGLE as a flag specifying //room with rain//. 
-  * **Bit 12** — {{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} Not found in any original TR levels, but when the //P//  flag is set in the TRLE, this bit is set. Was also re-used in NGLE as a flag specifying //cold room//  (a room which produce damage on Lara). +  * **Bit 12** — {{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}Not found in any original TR levels, but when the //P//  flag is set in the TRLE, this bit is set. Was also re-used in NGLE as a flag specifying //cold room//  (a room which produce damage on Lara). 
-{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} ''<nowiki>WaterScheme</nowiki>''  is used for different purposes. If room is a water room, then it specifies underwater caustics patterns. If it is set for normal room //placed above the water room//, then it controls //wave strength//  effect applied to the faces adjoining water room. Maximum value in both cases is 15.+{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}''<nowiki>WaterScheme</nowiki>''  is used for different purposes. If room is a water room, then it specifies underwater caustics patterns. If it is set for normal room //placed above the water room//, then it controls //wave strength//  effect applied to the faces adjoining water room. Maximum value in both cases is 15.
  
-{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}} ''<nowiki>ReverbInfo</nowiki>''  defines //room reverberation type//. It affects sound postprocessing, if listener position belongs to that room. This feature was present //only in PlayStation versions//  of the game, but not on PC. Nevertheless, the info is preserved in PC level files. Here are the types of reverberation:+{{:icons:tr3.png?nolink&}}{{:icons:tr4.png?nolink&}}{{:icons:tr5.png?nolink&}}''<nowiki>ReverbInfo</nowiki>''  defines //room reverberation type//. It affects sound postprocessing, if listener position belongs to that room. This feature was present //only in PlayStation versions//  of the game, but not on PC. Nevertheless, the info is preserved in PC level files. Here are the types of reverberation:
  
   * **0** — Outside. No (or barely heard) reverberation.   * **0** — Outside. No (or barely heard) reverberation.
Line 888: Line 916:
   * **3** — Large room.   * **3** — Large room.
   * **4** — Pipe. Highest reverberation level. Almost never used.   * **4** — Pipe. Highest reverberation level. Almost never used.
- 
-\\ 
  
  
trs/room_geometry.1589892137.txt.gz · Last modified: 2020/05/19 12:42 by zdimension
Back to top
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0