Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
trs:room_geometry [2017/06/04 19:07] zdimension [Room Static Mesh Structure] |
trs:room_geometry [2019/05/21 22:41] (current) zdimension [TR5 Room Structure] |
||
---|---|---|---|
Line 1: | Line 1: | ||
+ | {{indexmenu_n>2}} | ||
+ | |||
====== Room Geometry ====== | ====== Room Geometry ====== | ||
Line 83: | Line 85: | ||
==== Room Sector Structure ==== | ==== Room Sector Structure ==== | ||
+ | |||
+ | //**Core: **''FLOOR_INFO''// | ||
All the geometry specified here is //collisional geometry//. | All the geometry specified here is //collisional geometry//. | ||
Line 276: | Line 280: | ||
''<nowiki>dx</nowiki>'', ''<nowiki>dy</nowiki>'' and ''<nowiki>dz</nowiki>'' values are used only by the //sun// and //spot// type lights. They describe the directional vector of the light. This can be obtained by: | ''<nowiki>dx</nowiki>'', ''<nowiki>dy</nowiki>'' and ''<nowiki>dz</nowiki>'' values are used only by the //sun// and //spot// type lights. They describe the directional vector of the light. This can be obtained by: | ||
- | * if both ''<nowiki>x</nowiki>'' and ''<nowiki>y</nowiki>'' $\text{LightDirectionVectorX} = \cos(X) \times \sin(Y)$ | + | * if both ''<nowiki>x</nowiki>'' and ''<nowiki>y</nowiki>'' $\text{LightDirectionVectorX} = \cos(X) \cdot \sin(Y)$ |
* $\text{LightDirectionVectorY} = \sin(X)$ | * $\text{LightDirectionVectorY} = \sin(X)$ | ||
- | * $\text{LightDirectionVectorZ} = \cos(X) \times \cos(Y)$ | + | * $\text{LightDirectionVectorZ} = \cos(X) \cdot \cos(Y)$ |
''<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. | ||
Line 302: | Line 306: | ||
''<nowiki>Vertex</nowiki>'' is the coordinates of the vertex, relative to [[trs:room_geometry#tr_room_info|[tr_room_info]]] ''<nowiki>x</nowiki>'' and ''<nowiki>z</nowiki>'' values. | ''<nowiki>Vertex</nowiki>'' is the coordinates of the vertex, relative to [[trs:room_geometry#tr_room_info|[tr_room_info]]] ''<nowiki>x</nowiki>'' and ''<nowiki>z</nowiki>'' values. | ||
- | ''<nowiki>Lighting</nowiki>'' ranges from 0 (bright) to 0x1FFF (dark). This value is ignored by TR2, and ''<nowiki>Lighting2</nowiki>'' is used instead with the same brightness range. | + | ''<nowiki>Lighting</nowiki>'' ranges from ''0'' (bright) to ''0x1FFF'' (dark). This value is ignored by TR2, and ''<nowiki>Lighting2</nowiki>'' is used instead with the same brightness range. |
TR2 uses an extended version of the structure: | TR2 uses an extended version of the structure: | ||
Line 349: | Line 353: | ||
''<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: | ||
- | * //Red://''<nowiki>((Colour & 0x7C00) >> 10)</nowiki>'' | + | * Red: ''<nowiki>((Colour & 0x7C00) >> 10)</nowiki>'' |
- | * //Green://''<nowiki>((Colour & 0x03E0) >> 5)</nowiki>'' | + | * Green: ''<nowiki>((Colour & 0x03E0) >> 5)</nowiki>'' |
- | * //Blue://''<nowiki>(Colour & 0x001F)</nowiki>'' | + | * Blue: ''<nowiki>(Colour & 0x001F)</nowiki>'' |
=== TR5 Room Vertex Structure === | === TR5 Room Vertex Structure === | ||
Line 434: | Line 438: | ||
In ''<nowiki>Rotation</nowiki>'' field, high two bits (''<nowiki>0xC000</nowiki>'') indicate steps of 90 degrees (e.g. ''%%(Rotation >> 14) * 90%%''). However, when parsing this value, no extra bitshifting is needed, as you can simply interpret it using this formula: | In ''<nowiki>Rotation</nowiki>'' field, high two bits (''<nowiki>0xC000</nowiki>'') indicate steps of 90 degrees (e.g. ''%%(Rotation >> 14) * 90%%''). However, when parsing this value, no extra bitshifting is needed, as you can simply interpret it using this formula: | ||
- | $RealRotation = Rotation \div 16384 \times -90$ | + | $RealRotation = \frac{Rotation}{16384} \cdot -90$ |
=== TR2 Room Static Mesh Structure === | === TR2 Room Static Mesh Structure === | ||
Line 507: | Line 511: | ||
uint32_t Filler3; // Always 0 (4 bytes) | uint32_t Filler3; // Always 0 (4 bytes) | ||
- | uint32_t UnknownL6; // Unknown | + | uint32_t VerticesOffset; // Those fields are overwritten at level loading |
- | uint32_t UnknownL7; // Unknown | + | uint32_t PolyOffset; // by the ones present in the tr5_room struct + an offset |
- | uint32_t UnknownL8; // Always the same throughout the level. | + | uint32_t PolyOffset2; // i.e. the values are not read, the fields are there for storage purposes |
} | } | ||
</code> | </code> | ||
Line 543: | Line 547: | ||
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 | tr_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room | ||
Line 559: | Line 563: | ||
</code> | </code> | ||
- | ''<nowiki>AmbientIntensity</nowiki>'' is a brightness value which affects only //externally-lit// objects. It ranges from 0 (bright) to 0x1FFF (dark). | + | ''<nowiki>AmbientIntensity</nowiki>'' is a brightness value which affects only //externally-lit// objects. It ranges from ''0'' (bright) to ''0x1FFF'' (dark). |
''<nowiki>AlternateRoom</nowiki>'' (or, as it is called in TRLE terms, //flipped room//) is the number of the room that this room can //flip// with. In the terms of the gameplay, //flipped// room is a state change of the same room — for example, empty or flooded with water, filled with sand or debris. Alternate room usually has the same boundaries as original room, but altered geometry and/or texturing. Detailed description of //alternate rooms// will be provided in a separate section. | ''<nowiki>AlternateRoom</nowiki>'' (or, as it is called in TRLE terms, //flipped room//) is the number of the room that this room can //flip// with. In the terms of the gameplay, //flipped// room is a state change of the same room — for example, empty or flooded with water, filled with sand or debris. Alternate room usually has the same boundaries as original room, but altered geometry and/or texturing. Detailed description of //alternate rooms// will be provided in a separate section. | ||
Line 580: | Line 584: | ||
tr_room_portal Portals[NumPortals]; // List of visibility portals | tr_room_portal Portals[NumPortals]; // List of visibility portals | ||
- | 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 | tr_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room | ||
Line 624: | Line 628: | ||
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 | tr_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room | ||
Line 664: | Line 668: | ||
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 | tr_room_sector SectorList[NumXsectors * NumZsectors]; // List of sectors in this room | ||
Line 687: | Line 691: | ||
''<nowiki>RoomColour</nowiki>'' replaces ''<nowiki>AmbientIntensity</nowiki>'' and ''<nowiki>AmbientIntensity2</nowiki>'' values from [[trs:room_geometry#tr2_room|[tr2_room]]] structure. Note it’s //not in [[trs:fundamentals#tr_colour4|[tr_colour4]]] format//, because colour order is reversed. It should be treated as ARGB, where A is unused. | ''<nowiki>RoomColour</nowiki>'' replaces ''<nowiki>AmbientIntensity</nowiki>'' and ''<nowiki>AmbientIntensity2</nowiki>'' values from [[trs:room_geometry#tr2_room|[tr2_room]]] structure. Note it’s //not in [[trs:fundamentals#tr_colour4|[tr_colour4]]] format//, because colour order is reversed. It should be treated as ARGB, where A is unused. | ||
- | ''<nowiki>AlternateGroup</nowiki>'' was introduced in TR4 to solve long-existing engine limitation, which flipped //all alternate rooms at once// (see [[trs:floordata#trigfunc_0x03|//flipmap// trigger action]] description in [[trs:floordata#trigger_actions|Trigger actions]] section). Since TR4, engine only flips rooms which have similar index in room’s ''<nowiki>AlternateGroup</nowiki>'' field and trigger operand. | + | ''<nowiki>AlternateGroup</nowiki>'' was introduced in TR4 to solve long-existing engine limitation, which flipped //all alternate rooms at once// (see [[trs:floordata#trigfunc_0x03|flipmap trigger action]] description in [[trs:floordata#trigger_actions|Trigger actions]] section). Since TR4, engine only flips rooms which have similar index in room’s ''<nowiki>AlternateGroup</nowiki>'' field and trigger operand. |
==== TR5 Room Structure ==== | ==== TR5 Room Structure ==== | ||
Line 797: | Line 801: | ||
''<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>'' section. However, 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 ''<nowiki>StartSDOffset + 216 + ((NumXSectors * NumZSectors)*8)</nowiki>'', if you need to obtain this information. | + | ''<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>'' section. However, 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>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>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. | ||
Line 809: | Line 813: | ||
''<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>LightDataSize</nowiki>'' is the size of the light data in bytes (//not// in [[trs:room_geometry#tr5_room_light|[tr5_room_light]]] units). | ||
- | ''<nowiki>Unknown6</nowiki>'' could probably be a copy of ''<nowiki>ReverbInfo</nowiki>'' (see further), as its value usually ranges from 0 to 3. | + | ''<nowiki>Unknown6</nowiki>'' could probably be a 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>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 a //null room//, both of these values are ''<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 a //null room//, both of these values are ''<nowiki>0xCDCDCDCD</nowiki>''. |