Both sides previous revisionPrevious revisionNext revision | Previous revision |
trs:room_geometry [2021/04/29 21:30] – [TR5 Room Structure] zdimension | trs:room_geometry [2024/12/13 18:40] (current) – [Room Vertex Structure] stohrendorf |
---|
==== 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: |
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 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. |
| |
| ''<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 === |
| |
uint32_t Fade2; // Only in TR2 | uint32_t Fade2; // Only in TR2 |
}; | }; |
</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). | </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). |
=== TR3 Room Lighting === | === TR3 Room Lighting === |
| |
} | } |
}; | }; |
</code> | |
| |
''<nowiki>Intensity</nowiki>'' is the power of the light and ranges mainly from ''0'' (low power) to ''0x1FFF'' (high power). | </code> |
''<nowiki>Fade</nowiki>'' is the distance max the light can shine on. Range is mainly from ''0'' to ''0x7FFF''. | |
| |
| ''<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''. |
=== TR4 Room Lighting === | === TR4 Room Lighting === |
| |
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 |
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 |
uint8_t Filler[3]; // Dummy values = 3 x 0xCD | uint8_t Filler[3]; // Dummy values = 3 x 0xCD |
}; | }; |
| |
</code> | </code> |
| |
{ | { |
float x, y, z; // Position of light, in world coordinates | float x, y, z; // Position of light, in world coordinates |
float r, g, b; // Colour of the light | float rad, sqrad; |
| float den; |
| float r, g, b; |
| }; |
| |
uint32_t Separator // Dummy value = 0xCDCDCDCD | |
| |
float In; // Cosine of the IN value for light / size of IN value | |
float Out; // Cosine of the OUT value for light / size of OUT value | |
}; | |
</code> | </code> |
| |
**TODO**: investigate exact meaning of ''tr5_fog_bulb'' fields. | |
| |
''<nowiki>x,y,z</nowiki>'' values shouldn’t be used by sun type light, but sun seems to have a large ''<nowiki>x</nowiki>'' value (9 million, give or take), a zero ''<nowiki>y</nowiki>'' value, and a small ''<nowiki>z</nowiki>'' value (4..20) in the original TR5 levels. | ''<nowiki>x,y,z</nowiki>'' values shouldn’t be used by sun type light, but sun seems to have a large ''<nowiki>x</nowiki>'' value (9 million, give or take), a zero ''<nowiki>y</nowiki>'' value, and a small ''<nowiki>z</nowiki>'' value (4..20) in the original TR5 levels. |
| |
''<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 ==== |
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> |
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 |
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 ===== |