http://mm2kiwi.apan.is-a-geek.com/api.php?action=feedcontributions&user=Fre-Ber&feedformat=atomMm2kiwi - User contributions [en-gb]2024-03-28T21:22:02ZUser contributionsMediaWiki 1.27.1http://mm2kiwi.apan.is-a-geek.com/index.php?title=User:Fre-Ber&diff=1343User:Fre-Ber2011-04-24T12:14:58Z<p>Fre-Ber: Test of LaTeX</p>
<hr />
<div>==Math==<br />
<math>\frac{a+b}{\sqrt{b}}</math><br />
<br />
==Folder tree==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">js<br />
<ul><br />
<li class="FolderTree-Open">real<br />
<ul><br />
<li class="FolderTree-Open">code<br />
<ul><br />
<li class="FolderTree-File-JS">r3vsl.js<br />
<div class="FolderTree-Content"><br />
===SETATTRIBUTESHOWSTATEBYOBJ - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that two parameters are required, in fact this <br />
method takes three paramters. In addition to this, the automatic header file generator <br />
that Realsoft used has a funny way of truncating method names. In r3vsl.js it causes <br />
two methods to have the same name. The effective result of this is that only the <br />
method that is last declared in the JS class will function. To remedy this, apply the <br />
following diff to your file:<br />
</p><br />
<pre> // attr tag is unknown.<br />
// p2: Integer, attribute tag<br />
// p3: Integer, show state (TRUE == show, FALSE == hide)<br />
<br />
-R3VSLM_SETATTRIBUTESHOWSTATE = 53020;<br />
+R3VSLM_SETATTRIBUTESHOWSTATEBYOBJ = 53020;<br />
<br />
-function mR3VSLM_SETATTRIBUTESHOWSTATE(p2, p3) {<br />
- return DoA3(this.r3obj, R3VSLM_SETATTRIBUTESHOWSTATE, 0, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_INTEGER, 0);<br />
+function mR3VSLM_SETATTRIBUTESHOWSTATEBYOBJ(p1, p2, p3) {<br />
+ return DoA3(this.r3obj, R3VSLM_SETATTRIBUTESHOWSTATE, p1, R3TID_OBJECT, 0, p2, R3TID_INTEGER, 0, p3, R3TID_INTEGER, 0);<br />
}<br />
</pre><br />
<p>And further down:</p><br />
<pre> this.ISOFPHASELEVEL=mR3VSLM_ISOFPHASELEVEL;<br />
- this.SETATTRIBUTESHOWSTATE=mR3VSLM_SETATTRIBUTESHOWSTATE;<br />
+ this.SETATTRIBUTESHOWSTATEBYOBJ=mR3VSLM_SETATTRIBUTESHOWSTATEBYOBJ;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td> 4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
<br />
===SETATTRIBUTENAMEBYOBJ - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that two parameters are required, in fact this <br />
method takes three paramters.<br />
</p><br />
<pre> R3VSLM_SETATTRIBUTENAMEBYOBJ = 53021;<br />
<br />
-function mR3VSLM_SETATTRIBUTENAMEBYOBJ(p2, p3) {<br />
+function mR3VSLM_SETATTRIBUTENAMEBYOBJ(p1, p2, p3) {<br />
- return DoA3(this.r3obj, R3VSLM_SETATTRIBUTENAMEBYOBJ, 0, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_STRING, 0);<br />
+ return DoA3(this.r3obj, R3VSLM_SETATTRIBUTENAMEBYOBJ, p1, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_STRING, 0);<br />
}<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td> 4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">objects<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div> <ul><br />
<li class="FolderTree-File-JS">r3prim.h<br />
<div class="FolderTree-Content"><br />
===ENUMSELECTHANDLES - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that no parameters are required, in fact this <br />
method takes a tag list as a paramter.<br />
</p><br />
<pre> R3PRIMM_ENUMSELECTHANDLES = 140156;<br />
<br />
-function mR3PRIMM_ENUMSELECTHANDLES() {<br />
- DoA(this.r3obj, R3PRIMM_ENUMSELECTHANDLES, 0, R3TID_INTEGER, 0);<br />
+function mR3PRIMM_ENUMSELECTHANDLES(p3) {<br />
+ return Do(this.r3obj, R3PRIMM_ENUMSELECTHANDLES, p3, R3TID_TAG, R3TNF_ARRAY);<br />
}<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">r3subdiv.js<br />
<div class="FolderTree-Content"><br />
===SELECTEDFACESTOTRI - Truncated method name===<br />
<p><br />
The automatic header file generator that Realsoft used has a funny way of truncating <br />
method names. This may be a requirement of the JS engine, but it causes some <br />
problems. In r3subdiv.js it causes two methods to have the same name. The effective <br />
result of this is that only the method that is last declared in the JS class will function. To <br />
remedy this, apply the following diff to your file:<br />
</p><br />
<pre> R3SUBDIVM_GETMAXEDGESPERVERT = 1235126;<br />
function mR3SUBDIVM_GETMAXEDGESPERVERT() {<br />
return DoA(this.r3obj, 1235126, 0, R3TID_INTEGER, 0);<br />
<br />
-R3SUBDIVM_SELECTEDFACESTOTRI = 1235127;<br />
+R3SUBDIVM_SELECTEDFACESTOTRIS = 1235127;<br />
-function mR3SUBDIVM_SELECTEDFACESTOTRI(p1, p3) {<br />
+function mR3SUBDIVM_SELECTEDFACESTOTRIS(p1, p3) {<br />
if(arguments.length &lt; 2) {<br />
- error(&quot;SELECTEDFACESTOTRI() needs 2 parameters&quot;);<br />
+ error(&quot;SELECTEDFACESTOTRIS() needs 2 parameters&quot;);<br />
}<br />
return DoA2(this.r3obj, 1235127, p1, R3TID_BOOLEAN, 0, p3, R3TID_BOOLEAN, 0);<br />
<br />
</pre><br />
<p>Then, further down:</p><br />
<pre> this.GETMAXEDGESPERVERT=mR3SUBDIVM_GETMAXEDGESPERVERT;<br />
- this.SELECTEDFACESTOTRI=mR3SUBDIVM_SELECTEDFACESTOTRI;<br />
+ this.SELECTEDFACESTOTRIS=mR3SUBDIVM_SELECTEDFACESTOTRIS;<br />
this.WELD=mR3SUBDIVM_WELD;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td /><br />
</tr><br />
<tr><br />
<td>5.1.56 linux</td><br />
<td /><br />
</tr><br />
</table><br />
<br />
===EXTRUDE - Several tags omitted===<br />
<p><br />
Some special tgas may be used with the EXTRUDE method, unfortunately, r3subdiv.js <br />
does not define symbols for these tags. In order to use these tags without having to <br />
remember their number, apply the following diff to your file:<br />
</p><br />
<pre>function GetR3SUBDIVA_Quality() {<br />
return R3Get(this.r3obj, R3SUBDIVA_Quality, R3TID_INTEGER, 0);<br />
}<br />
<br />
+R3SUBDIVA_ExtrudeRegionOpt = 1235512;<br />
+R3SUBDIVA_ExtrudeNormalOpt = 1235513;<br />
+R3SUBDIVA_ExtrudeLeaveFloor = 1235514;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td>5.1.57 linux</td><br />
</tr><br />
<tr><br />
<td>5.1.56 linux</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=MediaWiki:Sidebar&diff=1342MediaWiki:Sidebar2011-04-24T11:35:59Z<p>Fre-Ber: </p>
<hr />
<div>* navigation<br />
** mainpage|mainpage-description<br />
** File_tree|File tree<br />
** Format_Reference|Format Reference<br />
** portal-url|portal<br />
** currentevents-url|currentevents<br />
** recentchanges-url|recentchanges<br />
** randompage-url|randompage<br />
** helppage|help<br />
* SEARCH<br />
* TOOLBOX<br />
* LANGUAGES</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=MediaWiki:Sidebar&diff=1341MediaWiki:Sidebar2011-04-24T11:34:41Z<p>Fre-Ber: Created page with "* navigation ** mainpage|mainpage-description ** Format_Reference|Format Reference ** portal-url|portal ** currentevents-url|currentevents ** recentchanges-url|recentchanges ** r..."</p>
<hr />
<div>* navigation<br />
** mainpage|mainpage-description<br />
** Format_Reference|Format Reference<br />
** portal-url|portal<br />
** currentevents-url|currentevents<br />
** recentchanges-url|recentchanges<br />
** randompage-url|randompage<br />
** helppage|help<br />
* SEARCH<br />
* TOOLBOX<br />
* LANGUAGES</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=INST&diff=1340INST2011-04-24T11:03:00Z<p>Fre-Ber: Reverted edits by 109.230.217.91 (talk) to last revision by Fre-Ber</p>
<hr />
<div>Each city can have one INST file, the INST file describes where to place monuments and other objects modeled in a PKG model file. Each placement allows a selection of paint job, scale and orientation as well as location of a PKG.<br />
<br />
==Format description==<br />
The format is simply a list of components placing one PKG object each. There are two types of components:<br />
;Coordinate component: Gives you complete freedom in placing the object - the component includes a complete coordinate system definition that allows for arbitrary rotation and scaling of the object.<br />
;Simple component: A shorter component that offers limited options for scaling and rotating the placed object.<br />
<br />
===Structure===<br />
<br />
INST<br />
{<br />
INSTComponent[] components;<br />
}<br />
<br />
INSTComponentHeader<br />
{<br />
unsigned short blockIndex; // Index +1 of the block this <br />
// package is placed on<br />
unsigned short modifiers; // Modifies the appearance of <br />
// the object, see below<br />
unsigned char type; // Highest bit indicates <br />
// component type, the rest is<br />
// length of "packageName"<br />
unsigned char[type & 0x7f] packageName; // Zero-terminated name-part of<br />
// the PKG filename<br />
}<br />
<br />
INSTCoordinateComponent<br />
{<br />
INSTComponentHeader header; // The type field has the top bit cleared<br />
Vector xAxis;<br />
Vector yAxis;<br />
Vector zAxis;<br />
Vector origo;<br />
}<br />
<br />
INSTSimpleComponent<br />
{<br />
INSTComponentHeader header; // The type field has the top bit set<br />
// (type >= 0x80)<br />
float scale;<br />
float angle;<br />
Vector location;<br />
}<br />
<br />
Vector<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
The ''modifiers'' define what ''paint job'' should be used for the object, among other things. The least significant bits of this field, currently I use the lowest eight bits, but I have a feeling that 256 paint jobs are not possible. Maybe this should be the least four bits instead. Other bits are still unknown. It seems as if bit 8, 0x100, is set for most monuments that are visible from every direction. Monuments doesn't appear to have more than one paint job, but facades generally do.<br />
<br />
''INSTCoordinateComponents'' define a complete coordinate system used by MM2 to convert each vertex in the PKG to city-coordinates. This is done by defining the locations for (1, 0, 0), (0, 1, 0), (0, 0, 1) and (0, 0, 0) of PKG coordinates in city coordinates.<br />
<br />
INSTSimpleComponents use a more compact, less flexible method of placing geometry. The vector named ''location'' is the coordinate for (0, 0, 0) of PKG coordinates in city-coordinates. The float ''scale'' defines a scaling factor in the ''x-z'' plane only - objects can't be stretched along the vertical axis! The float ''angle'' defines the angle to rotate the geometry around the ''y''-axis. No other rotation is possible with this component.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=1297Block attributes2007-01-06T14:25:43Z<p>Fre-Ber: /* Introduction */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|[[#Crosswalk rectangles|0x04]]||4||Crosswalk rectangle<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Crosswalk rectangles===<br />
A rectangular surface representing a cross-walk.<br />
{{Clr}}<br />
struct CrosswalkRectangle<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x04;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 2<br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=150Block attributes2007-01-06T14:25:04Z<p>Fre-Ber: /* Intersections: Added cross-walk rectangle */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|[[#Crosswalk rectangle|0x04]]||4||Crosswalk rectangle<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Crosswalk rectangles===<br />
A rectangular surface representing a cross-walk.<br />
{{Clr}}<br />
struct CrosswalkRectangle<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x04;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 2<br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=149Block attributes2007-01-06T14:22:17Z<p>Fre-Ber: /* Introduction */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|[[#Crosswalk rectangle|0x04]]||4||Crosswalk rectangle<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 2<br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=148Block attributes2007-01-06T14:21:42Z<p>Fre-Ber: /* Introduction: Added the crosswalk rectangle attribute */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|[[#Crosswalk rectangle|0x04]]||0x04||Crosswalk rectangle<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 2<br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=147Block attributes2006-12-26T16:55:53Z<p>Fre-Ber: /* Road triangle fans */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 2<br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=146Block attributes2006-12-26T16:47:03Z<p>Fre-Ber: // Added facade</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|[[#Facades|0x0b]]||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Facades===<br />
A regular facade is modelled as a rectangle that has a texture map repeated a number of times over its surface. The facade rectangle is always aligned with the world Y axis.<br />
{{Clr}}<br />
struct Facade<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0b;<br />
bit[3] subtype = 0x06;<br />
bit[8] padding = 0x00;<br />
ushort bottom; // Index in the height list<br />
ushort top; // Index in the height list<br />
ushort uRepeat; // Number of times to repeat the texture along its u-axis<br />
ushort vRepeat; // Number of times to repeat the texture along its v-axis<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=145Block attributes2006-12-26T16:18:07Z<p>Fre-Ber: // Divider type and value was wrong</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
bit[5] flags;<br />
bit[3] dividerType;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort value; // Usage depends on the divider type<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=144Block attributes2006-12-26T16:07:00Z<p>Fre-Ber: // Bah, reverted incorrect modification of cross section count on road attributes</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross sections<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=143Block attributes2006-12-26T15:58:11Z<p>Fre-Ber: // Added road triangle fan</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|[[#Road triangle fans|0x05]]||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Road triangle fans===<br />
A road triangle fan is encoded the same way as a regular triangle fan.<br />
{{Clr}}<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoadTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x05;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=142Block attributes2006-12-26T15:48:54Z<p>Fre-Ber: /* Roof triangle fans */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans. These fans differ from the regular triangle fan in that the vertex count is indicated differently. Another difference is that they include a reference to a height value that will replace the y-component of each of the referenced points.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; // Number of vertices - 1<br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=141Block attributes2006-12-26T15:37:24Z<p>Fre-Ber: /* Roof triangle fans */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices - 1; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=140Block attributes2006-12-26T15:37:06Z<p>Fre-Ber: /* Sidewalk strip */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; // Number of cross-sections<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype > 0x01;<br />
bit[8] padding = 0x00;<br />
ushort[subType * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices - 1; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=139Block attributes2006-12-26T15:32:49Z<p>Fre-Ber: /* Roof triangle fans */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices - 1; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 1] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=138Block attributes2006-12-26T15:25:53Z<p>Fre-Ber: /* Triangle fans */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=137Block attributes2006-12-26T15:22:50Z<p>Fre-Ber: /* Slivers */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the two bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=136Block attributes2006-12-26T15:10:44Z<p>Fre-Ber: Heading level of slivers</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
===Slivers===<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the thwo bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=135Block attributes2006-12-26T15:10:03Z<p>Fre-Ber: // Added slivers</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|[[#Slivers|0x03]]||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}<br />
<br />
==Slivers==<br />
The ground floor of a building is often partially below street level. To simulate this, there is an attribute that accepts different y-components on the thwo bottom vertices. This means that the bottom edge of the facade can be slanted so that it follows the street outside the building. The top edge of the sliver is always horisontal, though.<br />
{{Clr}}<br />
struct Sliver<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x03;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort top; // Index in the height list<br />
ushort textureScale; // Value for uniformly scaling the texture<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=134Block attributes2006-12-26T14:49:38Z<p>Fre-Ber: // Added sidewalk strip.</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|[[#Sidewalk strips|0x01]]||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Intersections==<br />
Where roads meet, some additional attributes are needed to make up the geometry.<br />
<br />
===Sidewalk strip===<br />
[[Image:Roadcrossing Sidewalk.jpg|thumbnail|350px|Sidewalk strip attribute]]<br />
A sidewalk strip defines a piece of a sidewalk. The sidewalk is defined by a set of inner and outer vertex indices, repeating a vertex index can be used to ''bend'' a sidewalk around a point as shown in the image. The actual geometry will have an additional point 15 centimetres above the inner vertex of each cross section.<br />
{{Clr}}<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct SidewalkStrip<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x01;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections; <br />
ushort[(subType + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File:Roadcrossing_Sidewalk.jpg&diff=1336File:Roadcrossing Sidewalk.jpg2006-12-26T14:39:22Z<p>Fre-Ber: Shows the construction of a sidewalk strip in a corner of an intersection.</p>
<hr />
<div>Shows the construction of a sidewalk strip in a corner of an intersection.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=133Block attributes2006-12-26T14:31:26Z<p>Fre-Ber: /* Roads without sidewalks: Bah, wrond vertex count */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=132Block attributes2006-12-26T14:14:24Z<p>Fre-Ber: /* Roads with sidewalks: Whoops, wrong vertex counts */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[(nSections + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[(subtype + 1) * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=131Block attributes2006-12-26T13:21:47Z<p>Fre-Ber: /* Facade bounds */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle<br />
// between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=130Block attributes2006-12-26T13:21:00Z<p>Fre-Ber: // Added facade bound</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|[[#Facade bounds|0x07]]||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
===Facade bounds===<br />
To simplify collision detection, each facade has a single quad bound surface. When facades are divided into several sections with different texture maps, it is not necessary to check for collisions against every subdivision since they are all covered by a single quad. Checking against this quad is sufficient. The quad is constructed by taking the two given vertices as the bottom side of the quad and then substituting the y-component in these vertices to construct the corresponding vertices at the top of the quad. This means that the top of a facade bound is always perfectly horizontal, but this is also the case for the facades and the roofs. The bottom edge of the facade bound can, however, be slanted. This acommodates the possibility of a sliver on the facade.<br />
{{Clr}}<br />
struct FacadeBound<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x07;<br />
bit[3] subtype = 0x04;<br />
bit[8] padding = 0x00;<br />
ushort angle; // Angle between 0-255 determines the angle between the facade and the sunlight <br />
ushort top; // Index in the height list<br />
ushort left; // Index in the vertex list<br />
ushort right; // Index in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=129Block attributes2006-12-26T12:40:20Z<p>Fre-Ber: // Added roof triangle fan</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|0x07||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|[[#Roof triangle fans|0x0c]]||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Buildings==<br />
Most of the buildings in a city is constructed using PSDL attributes. These are well suited for low detailed buildings. For higher detail levels, add INST-placed PKGs as parts of or complete buildings.<br />
<br />
===Roof triangle fans===<br />
The roof of a building is made up of triangle fans, these are encoded in the same way as regular triangle fans witrh the difference of an added height reference. The y-component of each of the points making up the fan is replaced by the height this reference indicates.<br />
{{Clr}}<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort heightRef; // Index in the height list<br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct RoofTriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0c;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort heightRef; // Index in the height list<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=PKG&diff=1318PKG2006-10-03T22:27:22Z<p>Fre-Ber: /* Geometry file: The "flags" field of the geometry file is, in fact a DirectX FVF value */</p>
<hr />
<div>==Introduction==<br />
<br />
Many aspects of MM2 requires geometric objects. These range from lampposts and waste bins, through monuments and complex facades to vehicles hudmaps and dashboards. A PKG file defines the geometric properties of a single object as well as the visual material properties of the surfaces.<br />
<br />
The PKG format used in the game Midnight Club differs slightly from this format. A description of the differences can be found [[PKGMC|here]].<br />
<br />
==Format description==<br />
===Files===<br />
The PKG file format is built up by several chunks of data, these chunks are called ''files''. There are a number of different types of files, each of these contain different types of data that make up the complete 3D model of the object.<br />
<br />
Each file has a name. This name determines the type of the file.<br />
; *VL, *L, *M, *H (Geometry file): Files whose name ends with one of "VL", "L", "M", "H" define geometry primitives. The name suffixes define the LOD, the level of detail, of the particular part of the object. A PKG-file can have any number of separate parts, some have special significance, especially for vehicle models. The suffixes themself stand for Very Low, Low, Medium and High respectively. Look [[PKG_Groups|here]] for a description of the special geometry groups.<br />
;shaders: A PKG-file always have one ''shader'' file. It defines the visual material properties to use for the surfaces defined in the geometry files. Shaders can be defined in one of two ways, either using floating point colour values or integer colour values. Each shader defines ambient, diffuse, specular and emissive colours. The floating point shader also specifies the shininess used to calculate highlights. Each shader can also specify one texture map. The shaders are organized in groups called ''paint jobs''. When an object is placed in game, a certain paint job is requested, either by the INST, PATHSET or PSDL for monuments and props or by user interaction for player vehicle models. Each paint job holds the same number of shaders, even if a particular shader is identical in several paint jobs. Each group of geometry primitives referens an index in to a single paint-job of the shader list. <br />
;offset: Unknown, probably provides a way to offset every point of this model with a fixed vector. A PKG-file can only contain one offset file.<br />
;xref: Reference to another PKG. Some objects are constructed by attaching several smaller objects to itself. Often these parts are ''breakable''. This means that they can be broken off from the main object. Examples are awnings on facades or pieces of driveable vehicles that can break off as a result of careless driving.<br />
<br />
===Structure===<br />
MM2 can read two types of PKG files, PKG2 and PKG3, these differ slightly in the structure. The following C-style format description describes this using a ''union'' type.<br />
struct PKG<br />
{<br />
char[4] header = "PKG3" | "PKG2";<br />
PKGFile[] files;<br />
}<br />
<br />
union PKGFile<br />
{<br />
PKG2File pkg2file; // If header == "PKG2"<br />
PKG3File pkg3file; // If header == "PKG3"<br />
}<br />
<br />
struct PKG2File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct PKG3File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
long length; // Length of this PKGFile in bytes<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct String<br />
{<br />
unsigned byte length; // Number of bytes in this string including<br />
// the string terminator.<br />
char[length - 1] characters; // ASCII characters<br />
char terminator = '\0';<br />
}<br />
<br />
====Geometry file====<br />
struct PKGFileData<br />
{<br />
long nSections; // Number of sections making up this LOD<br />
long nVerticesTot; // Total number of vertices in this LOD<br />
long nIndiciesTot; // Total number of indicies in this LOD<br />
long nSections2; // Repetition of the number of sections?<br />
// Highly unlikely, but I have no better suggestion at<br />
// this time<br />
long fvf; // Flags defining what components are provided with<br />
// each vertex, see below<br />
PKGSection[nSections] sections;<br />
}<br />
<br />
struct PKGSection<br />
{<br />
ushort nStrips; // Number of geometry strips in this section<br />
ushort flags; // Unknown flags (Always 0 in MM2 PKGs)<br />
<br />
long shaderOffset; // Offset into the shader list of the requested<br />
// paintjob<br />
PKGStrip[nStrips] strips;<br />
}<br />
<br />
struct PKGStrip<br />
{<br />
long primType; // Determines the primitive type<br />
long nVertices; // Number of vertices in this strip<br />
PKGVertex[nVertices] vertices;<br />
long nIndices; // Number of indices making up the geometry strip<br />
ushort[nIndices] indices;<br />
}<br />
<br />
struct PKGVertex<br />
{<br />
Vertex3D coordinate; // If flags indicate coordinates<br />
Vector3D normal; // If flags indicate normals<br />
Vertex2D textureCoordinate; // If flags indicate texture coordinates<br />
}<br />
<br />
struct Vertex3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vector3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vertex2D<br />
{<br />
float x;<br />
float y;<br />
}<br />
<br />
The bits of the PKGFILEData.fvf field are defined by the DirectX flexible vertex format enumerated type. Some of the bits are as follows:<br />
<br />
<ol start="0"><br />
<li>D3DFVF_RESERVED0</li><br />
<li>D3DFVF_XYZ - Coordinate</li><br />
<li>D3DFVF_XYZRHW - Pre-transformed coordinate</li><br />
<li>Unknown</li><br />
<li>D3DFVF_NORMAL - Normal vector</li><br />
<li>D3DFVF_RESERVED1</li><br />
<li>D3DFVF_DIFFUSE - Vertex colour 0 (diffuse)</li><br />
<li>D3DFVF_SPECULAR - Vertex colour 1 (specular)</li><br />
<li>D3DFVF_TEX1 - One 2D texture coordinate</li><br />
</ol><br />
Other bits can be checked in the DirectX documentation or header file d3dtypes.h.<br />
<br />
The only known value for primType is PRIMTYPE_TRIANGLES (=3) that means that the indices make up lists of complete, separate triangles.<br />
<br />
====Shaders====<br />
PKGFileData<br />
{<br />
long shaderType; // Bit 7: Shader type<br />
// Bit 0-6: Number of paint jobs<br />
long shadersPerPaintJob;<br />
PKGShader[Number of paint jobs * shadersPerPaintJob] shaders;<br />
}<br />
<br />
union PKGShader<br />
{<br />
FloatPKGShader floatShader; // If type is 0<br />
IntPKGShader intShader; // If type is 1<br />
}<br />
<br />
FloatPKGShader<br />
{<br />
String textureName;<br />
Color4f ambient;<br />
Color4f diffuse;<br />
Color4f specular;<br />
Color4f reflective;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
IntPKGShader<br />
{<br />
String textureName;<br />
Color4d ambient;<br />
Color4d diffuse;<br />
Color4d specular;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
Color4f<br />
{<br />
float red;<br />
float green;<br />
float blue;<br />
float alpha;<br />
}<br />
<br />
Color4d<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
unsigned char alpha;<br />
}<br />
<br />
====Offset====<br />
PKGFileData<br />
{<br />
Vector3D offset; // Have not tested, but could be an offset added to all<br />
// vertices in the object<br />
}<br />
<br />
====XRef====<br />
PKGFileData<br />
{<br />
long nReferences;<br />
PKGXRef[nReferences] references;<br />
}<br />
<br />
PKGXRef<br />
{<br />
Vector3D xAxis;<br />
Vector3D yAxis;<br />
Vector3D zAxis;<br />
Vector3D origin;<br />
char[32] name;<br />
}<br />
<br />
==MTX - Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. Look [[MTX|here]] for more information.<br />
<br />
==Boundary files==<br />
MM2 use three file types for collision detection and material properties on regular PKG objects:<br />
<br />
* [[BND]] - Simple bound mesh in a plain ASCII format.<br />
* [[BBND]] - Binary version of .bnd<br />
* [[TER]] - Unknown, but the MM2 engine does read these files<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File_tree&diff=1326File tree2006-08-08T18:30:01Z<p>Fre-Ber: /* Removed TOC */</p>
<hr />
<div>__NOTOC__<br />
The AR files of MM2 make up a common file tree, the files are extracted to a, shared, virtual file system when needed. The structure of this file system is as follows:<br />
==Structure==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">root<br />
<ul><br />
<li class="FolderTree-Open">anim<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.anim<br />
<div class="FolderTree-Content"><br />
====Animation sequence====<br />
<p><br />
Each [[Pedestrian animations|animation sequence]], <br />
associated with a state, is made up by a number of key <br />
frames. Each key frame has several parameters that should be <br />
applied to each bone in the skeleton. By moving the <br />
skeleton, the entire model will move.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.csv<br />
<div class="FolderTree-Content"><br />
====Animation state model====<br />
<p><br />
The animation of a pedestrian is based on a <br />
[[Pedestrian state models|state model]]. A pedestrian is <br />
always in a specific state and each state is connected to an <br />
animation sequence. For example, if the pedestrian is in the <br />
state "WALK", the animation named pedanim_womwalk.anim is <br />
looping over and over again. When something happens, the <br />
pedestrian might make a transition from one state to another.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.rays<br />
<div class="FolderTree-Content"><br />
<br />
====Unknown: rays====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.shaders<br />
<div class="FolderTree-Content"><br />
====Shader definitions====<br />
<p><br />
The [[PKG#Shaders|shaders]] are defined in exactly the same <br />
way as for PKG objects. The pedmodel_*.shaders files follow <br />
the specification of the PKGFileData in the [[PKG]] file <br />
format.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.skel<br />
<div class="FolderTree-Content"><br />
====Skeleton====<br />
<p><br />
All the parts of a pedestrian model are bound to a <br />
[[Pedestrian skeleton|skeleton]]. <br />
A skeleton is constructed by a number of bones that are <br />
attached with joints. In MM2 the skeletons are defined using <br />
a tree structure. <br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.mod<br />
<div class="FolderTree-Content"><br />
====Geometry model====<br />
<p><br />
The [[Pedestrian model|pedmodel_*.mod]] files define the <br />
actual 3D model of a pedestrian. It defines vertices, some <br />
material attributes and the surfaces of the model.<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">aud<br />
<div class="FolderTree-Content"><br />
<br />
===Audio files===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">bound<br />
<div class="FolderTree-Content"><br />
<br />
===Object boundaries===<br />
<p><br />
MM2 use three file types for collision detection and material properties on regular PKG objects, [[BND]], [[BBND]] and [[TER]].<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.bnd<br />
<div class="FolderTree-Content"><br />
====ASCII bound====<br />
<p><br />
Simple, ASCII-based file format defined [[BND|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.bbnd<br />
<div class="FolderTree-Content"><br />
====Binary bound====<br />
<p><br />
Binary version of the ASCII-based format, defined [[BBND|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.ter<br />
<div class="FolderTree-Content"><br />
====Terrain bound====<br />
<p><br />
Unknown format, defined [[TER|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">city<br />
<div class="FolderTree-Content"><br />
<br />
===City definitions===<br />
<p><br />
Each MM2 city has a number of files defining the actual city, its geometry, monuments, traffic flows and so on. Many of the files that controls these things are stored in the ''city'' folder.<br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-Open">audio_pathsets<br />
<ul><br />
<li class="FolderTree-File-JS">*.pathset<br />
<div class="FolderTree-Content"><br />
====Local city sound placement====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">decals.pathset<br />
<div class="FolderTree-Content"><br />
====Decal placements====<br />
<p><br />
Decals are flat images that can be placed on the ground <br />
and on facades to increase the visual detail level. Decals <br />
are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">props.pathset<br />
<div class="FolderTree-Content"><br />
====Prop placements====<br />
<p><br />
Props are, typically, small 3D objects like road cones, <br />
park benches and similar that can be placed around the <br />
city. Props are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">propdefs.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop definitions====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
repetiton controls for certain props. The proprules file <br />
controls which of these props are to be placed next in <br />
line.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">proprules.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop rules====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
the sequencing of the prop definitions defined in the <br />
propdefs file. The [[PSDL]] file selects a proprule index <br />
from this file for each road. <br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
This file controls what ambients are present in this city.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.bai<br />
<div class="FolderTree-Content"><br />
====Ambient path file====<br />
<p><br />
This file defines where and how the ambients may move in the <br />
city. See [[BAI]] for details.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cpvs<br />
<div class="FolderTree-Content"><br />
====Potentially visible set definition====<br />
<p><br />
MM2 uses a PVS, or potentially visible set, algorithm to <br />
speed up rendering of each game frame. These files contain <br />
the pre-calculated PVS tree. See [[CPVS]] for details.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.inst<br />
<div class="FolderTree-Content"><br />
====Stationary objects====<br />
<p><br />
For stationary objects that require more detail than the <br />
[[PSDL]] file can provide, the [[INST]] file can be used to <br />
place [[PKG]] objects throughout the city. These objects <br />
will not move for anything.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.ldef<br />
<div class="FolderTree-Content"><br />
====LDEF====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lmap<br />
<div class="FolderTree-Content"><br />
====Light map definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lt*<br />
<div class="FolderTree-Content"><br />
====LT====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">materials.csv<br />
<div class="FolderTree-Content"><br />
====Material mappings====<br />
<p><br />
This file simply lists what material should be used together <br />
with which image map.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">materials.mtl<br />
<div class="FolderTree-Content"><br />
====Material definitions====<br />
<p><br />
Defines material properties such as friction and possible <br />
particle effecs that apply to a particular type of surface.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.psdl<br />
<div class="FolderTree-Content"><br />
====City geometry====<br />
<p><br />
The [[PSDL]] file defines the major geometry of the city. <br />
All roads and most buildings are defined with this file.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.sky<br />
<div class="FolderTree-Content"><br />
====Sky dome definition====<br />
<p><br />
Defines the name of the sky dome object and to position of <br />
the center of this dome relative to the [[PSDL]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.water<br />
<div class="FolderTree-Content"><br />
====Water of death definition====<br />
<p><br />
Defines the heghit of deadly water - if a vehicle goes below <br />
this height it sleeps with the fishes. Possibly a list of <br />
[[PSDL]] block ids can be listed for blocks that define <br />
deadly water at any height. <br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">geometry<br />
<div class="FolderTree-Content"><br />
<br />
===Object definitions===<br />
<p><br />
The geometry of generic 3D objects are defined by PKG files. These are used for many things, from player vehicles to statues and complex facades.<br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">*.pkg<br />
<div class="FolderTree-Content"><br />
====Object geometry====<br />
<p><br />
Actual geometry is defined in these files, definition can be found [[PKG|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.mtx<br />
<div class="FolderTree-Content"><br />
====Object matrix====<br />
<p><br />
Defines a transformation matrix for ''local'' parts of a [[PKG]]. Format is defined [[MTX|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">jpg<br />
<div class="FolderTree-Content"><br />
<br />
===Game interface graphics===<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-Open">texture<br />
<div class="FolderTree-Content"><br />
===Game image maps===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">*.tex<br />
<div class="FolderTree-Content"><br />
====Custom image map file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.tga<br />
<div class="FolderTree-Content"><br />
====Targa image map file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">race<br />
<div class="FolderTree-Content"><br />
===Race definitions===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-File-JS">*.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.aimap_p<br />
<div class="FolderTree-Content"><br />
====Ambient control file?====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>waypoints.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>data.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><eventname>.csv<br />
<div class="FolderTree-Content"><br />
====Event definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">mm[blitz|circuit|crash|race]data.csv<br />
<div class="FolderTree-Content"><br />
====Race progression definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">multicopwaypoints.csv<br />
<div class="FolderTree-Content"><br />
====Cops and robbers locations====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>_rewards.csv<br />
<div class="FolderTree-Content"><br />
====Race reward definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>-[a|p]-<n>.opp<br />
<div class="FolderTree-Content"><br />
====Opponent definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>.pathset<br />
<div class="FolderTree-Content"><br />
====Race props====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">scene<br />
<div class="FolderTree-Content"><br />
===Scene?===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">modtypes.ini<br />
<div class="FolderTree-Content"><br />
====Mod types?====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">tune<br />
<div class="FolderTree-Content"><br />
===Tuning information===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open">banger<br />
<ul><br />
<li class="FolderTree-File-JS"><objectname>.dgBangerData<br />
<div class="FolderTree-Content"><br />
====Object collision properties====<br />
<p><br />
Defines properties controlling [[PKG]] objects that has<br />
collided with something. The format is described [[dgBangerData|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">camera<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>[_dash].camPovCS<br />
<div class="FolderTree-Content"><br />
<br />
====Camera definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_[NEAR|FAR].camTrackCS<br />
<div class="FolderTree-Content"><br />
====Camera tracking definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">effects<br />
<ul><br />
<li class="FolderTree-File-JS"><effectname>.asBirthRule<br />
<div class="FolderTree-Content"><br />
====Particle effect definition====<br />
<p><br />
Particle effects are used in weather, vehicle effects and collisions. The format is described [[asBirthRule|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">vehicle<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>.aiVehicleData<br />
<div class="FolderTree-Content"><br />
<br />
====Ambient vehicle data====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====??====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehCarDamage<br />
<div class="FolderTree-Content"><br />
====Vehicle damage control====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>[_opp].vehCarSim<br />
<div class="FolderTree-Content"><br />
====Vehicle tuning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehGyro<br />
<div class="FolderTree-Content"><br />
====Vehicle stability====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehStuck<br />
<div class="FolderTree-Content"><br />
====Vehicle instability====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">[rain|snow].asBirthRule<br />
<div class="FolderTree-Content"><br />
====Weather particle effect====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle control settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_dash.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle dashboard settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cinfo<br />
<div class="FolderTree-Content"><br />
====City definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.info<br />
<div class="FolderTree-Content"><br />
====Vehicle information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">menu.csv<br />
<div class="FolderTree-Content"><br />
====Game interface menu options====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">widget.csv<br />
<div class="FolderTree-Content"><br />
====Game interface widgets====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.mmHudMap<br />
<div class="FolderTree-Content"><br />
====Hudmap definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.mmMirror<br />
<div class="FolderTree-Content"><br />
====Vehicle rear view mirror definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><texturenamestem>.movie<br />
<div class="FolderTree-Content"><br />
====Animated image sequence definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=128Block attributes2006-08-08T18:26:08Z<p>Fre-Ber: /* Introduction */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|Reserved (=0)||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|0x07||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|0x0c||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=125Block attributes2006-08-08T18:23:33Z<p>Fre-Ber: /* Introduction - added links to table*/</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|RFU||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|[[#Roads with sidewalks|0x00]]||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|[[#Roads without sidewalks|0x02]]||n||Road without sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|[[#Triangle fans|0x06]]||n||Triangle fan<br />
|-<br />
|0x07||4||Facade bound<br />
|-<br />
|[[#Divided roads|0x08]]||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|0x0c||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=124Block attributes2006-08-08T18:20:32Z<p>Fre-Ber: /* Introduction - tested a link */</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|RFU||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|0x00||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|0x02||n||Road with no sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|0x06||n||Triangle fan<br />
|-<br />
|0x07||4||Facade bound<br />
|-<br />
|0x08||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|[[#Texture references|0x0a]]||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|0x0c||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Help:Editing&diff=1334Help:Editing2006-08-08T18:17:50Z<p>Fre-Ber: </p>
<hr />
<div>http://meta.wikimedia.org/wiki/Help:Contents</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=Block_attributes&diff=123Block attributes2006-08-08T18:13:12Z<p>Fre-Ber: Added more precise description of the attribute type and a quick-reference list.</p>
<hr />
<div>==Introduction==<br />
Most block attributes are built in a similar way, all share a bit indicating that the attribute is the last one in the block, all have a four bit type indicator and all have a three bit sub type indicator. These parameters form the first byte of the first ''ushort'' of the attribute data. The second byte is always zero.<br />
{|class="wikitable"<br />
|+Attribute type field<br />
!Bit!!15!!14!!13!!12!!11!!10!!9!!8!!7!!6!!5!!4!!3!!2!!1!!0<br />
|-<br />
!<br />
|colspan="8"|RFU||Last||colspan="4"|Type||colspan="3"|Subtype<br />
|}<br />
<br />
Typically, the subtype indicates the number of something for the attribute, for example, the number of points in a triangle fan, the number of cross-sections in a road and so on. The subtype zero usually means that the counter is instead stored in the following uword in the attribute data.<br />
{|class="wikitable"<br />
|+Attribute types<br />
!Type!!Subtype!!Description<br />
|-<br />
|0x00||n||Road with sidewalks<br />
|-<br />
|0x01||n||Sidewalk strip<br />
|-<br />
|0x02||n||Road with no sidewalks<br />
|-<br />
|0x03||4||Sliver<br />
|-<br />
|0x04||?||?<br />
|-<br />
|0x05||n||Road triangle fan<br />
|-<br />
|0x06||n||Triangle fan<br />
|-<br />
|0x07||4||Facade bound<br />
|-<br />
|0x08||n||Divided road<br />
|-<br />
|0x09||0||Junction tunnel/railing<br />
|-<br />
|0x09||3||Road tunnel/railing<br />
|-<br />
|0x0a||n||Texture reference<br />
|-<br />
|0x0b||6||Facade<br />
|-<br />
|0x0c||n||Roof triangle fan<br />
|-<br />
|0x0d||?||?<br />
|-<br />
|0x0e||?||?<br />
|-<br />
|0x0f||?||?<br />
|}<br />
<br />
==Common attributes==<br />
<br />
Most attributes of the PSDL-file are specialized, created for a specific purpose. Some, however, are general attributes with several uses. This section describes them. <br />
<br />
===Texture references===<br />
<br />
Most geometry primitives use texture mappings. The textures are identified by attributes of type ''0xa''. The data is just one byte and a padding zero byte. The byte is an eight bit index in the list of materials. In order to be able to use more than 256 textures, the subtype indicates a value to add to the byte to get the real index. This formula can be used to compute the real index, ''n'': ''n'' = ''data'' + (256 * ''subtype'') - 1. The data value 0 in subtype 0 is special, it is used in both SF and London, but the effect is unknown.<br />
<br />
Several block attributes use more than one texture. In most cases the texture attribute references the first texture in a list. This texture index is referenced to as texture ''n'' and block attributes sometimes uses texture index ''n'', ''n + 1'', ''n + 2'', ''n + 3'' and so on.<br />
<br />
In a pseudo-C style structure, the texture attributes look like this:<br />
struct TextureReference<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x0a;<br />
bit[3] subtype;<br />
bit[8] padding = 0x00;<br />
ushort data;<br />
}<br />
<br />
===Triangle fans===<br />
[[Image:0x30-0x37 Triangle fan.jpg|thumbnail|350px|Triangle fan attribute]]<br />
To create ground surfaces triangle fans are usually used. These are constructed by a list of vertices surrounding a pivot vertex in a counter-clockwise order. Often the triangle fan is degenerated to a convex polygon. This means that the pivot vertex is located on the perimeter of the attribute. <br />
<br />
Triangle fan attributes have type ''0x06'' and the sub type indicates the number of triangles present in the triangle fan. Sub type zero is special and means that the total number of ''vertices'' are stored in the following uword. Of course, there are no actual coordinates listed in the attribute, instead each uword in the data is an index in the vertex list of the PSDL file.<br />
{{Clr}}<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nVertices; <br />
ushort[nVertices] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct TriangleFan<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x06;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype + 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
==Roads==<br />
In a racing game, the roads are one of the most important features. There are several geometric primitives for defining roads, this section describes them.<br />
<br />
===Roads without sidewalks===<br />
[[Image:0x10-0x17 Rectangle strip.jpg|thumb|350px]]<br />
For walkways and narrow alleys without sidewalks the attributes with id 0x02 is used. The data in the attribute defines the road by pairs of vertices - cross sections of the road. The sub type defines the number of cross sections the road consists of. If the sub type is zero, the following ushort gives the number of cross sections.<br />
{{clr}}<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Walkway<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x02;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 2] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Roads with sidewalks===<br />
[[Image:0x00-0x07 Road strip.jpg|thumb|350px]]<br />
The most common roads in an MM2 city are the ones with sidewalks on both sides. These are easily defined using cross-sections of the road. Attribute 0x00 defines cross sections of the particular road segment.<br />
<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
This type of roads use three textures. The texture attribute points out texture ''n'', this texture is used to render the road surface. This texture is mirrored along the center line of the road. The sidewalks are rendered using texture ''n'' + 1 and texture ''n'' + 2 is the texture used across the entire road in the lowest ''LOD'', or level of detail, of the road segment. <br />
{{clr}}<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ushort[nSections * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct Road<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x00;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ushort[subtype * 4] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
===Divided roads===<br />
[[Image:0x08 Divided road.jpg|thumb|350px]]<br />
The vertices in each cross section are organized like this: First comes the vertex defining the position of the outer edge of the left sidewalk, then follows the outer edge of the left road surface, the inner edge of the left road surface, the inner edge of the right road surface, the outer edge of the right road surface and finally the outer edge of the right sidewalk. MM2 automatically renders the vertical sides of the sidewalks and the road surface vertices are expected to be located 15 cm below the sidewalk vertices.<br />
<br />
The road surface and sidewalks are rendered in the same way as the road with sidewalk attributes.<br />
{{clr}}<br />
<br />
====Divider type====<br />
Several types of dividers can be created by using various parameters to the divided road strip attributes. First we have a flags parameter, the flags paramter is divided into two parts, it is currently not 100% clear how many bits belong to which part, but the examined road attributes in SF and London indicates that at least the two lowest bits of the flags parameter is a divider type.<br />
<br />
In addition to the flags parameter there is also an extra texture reference and a value parameter. These are used differently depending on the divider type. <br />
<br />
;0 - Invisible:No divider is rendered, but the bound is there.<br />
;1 - Flat:[[Image:DividerFlatGFX.jpg|none]] A flat divider is in the same height as the road surfaces, the ''value'' parameter defines how many times the texture is repeated across the divider.<br />
;2 - Elevated:[[Image:DividerElevatedGFX.jpg|none]] The ''value'' parameter specifies the height of the divider and the width of the side strips.<br />
;3 - Wedged:[[Image:DividerWedgeGFX.jpg|none]] A wedged divider is always one metre high. The top of the sloping sides are always 0.5 metres towards the center of the road from the given divider vertices. The remaining width between the two divider vertices are filled by a flat top strip.<br />
<br />
====Flags====<br />
Only two flags are known, besides the two type bits, those control the closing of the short-ends of the divider. Bit seven closes the divider at the start and bit eight closes the divider at the end. The first section of a divided road should close it's start, the last section should close it's end. Intermediary sections shouldn't close anything.<br />
<br />
====Textures====<br />
All dividers in these examples use the same textures as indicated in this image:<br />
<br />
[[Image:DividerTextures.png|none]]<br />
<br />
The texture index, ''n'', in this case ''n'' = 5, points to the texture used for the sides of an elevated divider. ''n'' + 1 is used for a flat divider, the sidestrips of an elevated divider and the sloping sides of a wedge divider. Texture ''n'' + 2 is used for the center strip of an elevated or wedge divider. Finally, texture ''n'' + 3 is used to close the dividers.<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype = 0x00;<br />
bit[8] padding = 0x00;<br />
ushort nSections;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[nSections * 6] vertexRefs; // Indices in the vertex list<br />
}<br />
<br />
struct DividedRoad<br />
{<br />
bit lastAttribute;<br />
bit[4] type = 0x08;<br />
bit[3] subtype != 0x00;<br />
bit[8] padding = 0x00;<br />
ubyte flags;<br />
ubyte texture; // Index in the texture list + 1 for the divider<br />
ushort[subtype * 6] vertexRefs; // Indices in the vertex list<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=AsBirthRule&diff=1332AsBirthRule2006-08-06T21:46:11Z<p>Fre-Ber: /* Headings */</p>
<hr />
<div>The asBirthRule files define a particle effect. A particle effect is an effect where many, small objects are spewed out from a point at certain occasions. For weather effects, the particles can be rain drops, for colliding with a parking meter, the particles may be coins.<br />
<br />
The format is ASCII-based and consist of a block enclosed by ''{'' and ''}''.<br />
<br />
The files start with a definition of the type of banger data given. None of the MM2 files use anything but type ''a'', like this:<br />
type: a<br />
<br />
Next comes the main asBirthRule block:<br />
asBirthRule {<br />
...<br />
}<br />
<br />
This block can contain several tag-value parameters:<br />
{| class="wikitable"<br />
|+ Tags of the asBirthRule block<br />
!Tag!!Format!!Description<br />
|-<br />
|Position||float float float||Position where particles originate <br />
|-<br />
|PositionVar||float float float||Variance in position, the origin <br />
is randomly modified within this range<br />
|-<br />
|Velocity||float float float||Velocity and direction of the particles when created <br />
|-<br />
|VelocityVar||float float float||Variance in velocity, the velocity is randomly modified within this range<br />
|-<br />
|Life||float||Life-time of the particles <br />
|-<br />
|LifeVar||float||Variance in life-time<br />
|-<br />
|Mass||float||Mass of a particle<br />
|-<br />
|MassVar||float||Variance in particle mass<br />
|-<br />
|Radius||float||Size of the invisible sphere containing all particles<br />
|-<br />
|RadiusVar||float||Variance in containing sphere<br />
|-<br />
|Drag||float||Unknown<br />
|-<br />
|DragVar||float||Variance in drag<br />
|-<br />
|Damp||float||Unknown<br />
|-<br />
|DampVar||float||Variance in damp <br />
|-<br />
|DRadius||float||Size of the particles<br />
|-<br />
|DRadiusVar||float||Variance in particle size<br />
|-<br />
|DAlpha||float||Transparency of the particle<br />
|-<br />
|DAlphaVar||float||Variance in particle transparency<br />
|-<br />
|DRotation||float||Particle rotation speed, about what axis?<br />
|-<br />
|DRotationVar||float||Variance in particle rotation<br />
|-<br />
|InitialBlast||int||Number of particles created immediately on activation<br />
|-<br />
|SpewRate||float||Number of new particles per second? <br />
|-<br />
|SpewTimeLimit||float||Maximum time, in seconds, for particle creation<br />
|-<br />
|Gravity||float||Gravitational factor for particles, for Earth conditions enter -9.8 or thereabaouts<br />
|-<br />
|TexFrameStart||int||Index of the first frame of particle animation in the image, see below<br />
|-<br />
|TexFrameEnd||int||Index of the last frame of particle animation in the image , see below<br />
|-<br />
|BirthFlags||int||Unknown<br />
|-<br />
|Height||float||Unknown<br />
|-<br />
|Intensity||float||Unknown<br />
|-<br />
|Color||int||Controls colour of the particles in some mysterious way that only Stereo understands<br />
|}<br />
<br />
Some of the global particle effects use the texture image named "TODO: I could have sworn that I saw an image where the indices matched all of the default vehicular particle effect, now I can't find it". This image, and all particle texture images, are divided into rectangular frames used for animation. All frames are equal in size and they are numbered for easy access in the asBirthRule. Animation sequences must be made up of consequtive frames in the image, but the image may contain other frames for different particle effects.<br />
<br />
Oject collision particle effects may use other images, see ''TexNumber'' in [[dgBangerData]], but these are structured in the same way, with frames and indices to the frames.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=DgBangerData&diff=1331DgBangerData2006-08-06T21:45:40Z<p>Fre-Ber: /* Specification - headings */</p>
<hr />
<div>The ''dgBangerData'' files are used to define collision properties for [[PKG]] objects. These properties define how an object behaves when something collides with it. <br />
<br />
The file names are derived from the name of the [[PKG]] and the names of the internal parts of it. The syntax is like this for the banger data of the entire object:<br />
/tune/banger/<pkgname>.dgBangerData<br />
<br />
and like this for the breakable parts:<br />
/tune/banger/<pkgname>_<partname>.dgBangerData<br />
<br />
For example, the banger data for the wooden barricade, ''/geometry/sp_barricadewood_f.pkg'', of SF and London is defined in the following files:<br />
/tune/banger/sp_barricadewood_f.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK01.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK02.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK03.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK04.dgBangerData<br />
<br />
==Specification==<br />
The format is ASCII-based and made up of tag-value rows grouped in ''blocks'' between ''{'' and ''}'' symbols.<br />
<br />
The files start with a definition of the type of banger data given. None of the MM2 files use anything but ''type a'', like this:<br />
type: a<br />
<br />
Next comes the main ''dgBangerData'' block:<br />
dgBangerData {<br />
<tags><br />
}<br />
<br />
''<tags>'' is replaced by a list of tags from the following table. The order of the tags is significant, but some tags may be omitted from the file, in that case the values from ''default.dgBangerData'' is used.<br />
{| class="wikitable"<br />
|+ Tags of the dgBangerData block<br />
!Tag!!Format!!Description<br />
|-<br />
|AudioId||int||Index in a list of sound effects the object makes all the time?<br />
|-<br />
|Size||float float float||Width, height and depth of the bounding box around the object<br />
|-<br />
|CG||float float float||Center of gravity, rotation takes place around this point<br />
|-<br />
|NumGlows||int||Number of image light glow effects listed below using the GlowOffset tag. These effects are only active at night<br />
|-<br />
|GlowOffset||float float float||Position of a ''billboarded'' glow effect image<br />
|-<br />
|Mass||float||Mass of the object in kilograms, closely related to the objects weight<br />
|-<br />
|Elasticity||float||Controls the ''bounciness'' of the object<br />
|-<br />
|Friction||float||friction coefficient, determines how much force is required to slide along the surface of the object<br />
|-<br />
|ImpulseLimit2||float||Force required to move the object<br />
|-<br />
|SpinAxis||int||Unknown, always set to 0 in MM2 files<br />
|-<br />
|Flash||int||Unknown<br />
|-<br />
|NumParts||int||Number of breakable parts in the object<br />
|-<br />
|BirthRule||block||Particle effect for collision, see below<br />
|-<br />
|TexNumber||int||Number of the particle texture map, see below<br />
|-<br />
|BillFlags||int||Flags controlling ''billboarding'', 0, 64, 128 and 512 are used in MM2 files for unknown effects<br />
|-<br />
|YRadius||float||Bounding cylinder/sphere radius<br />
|-<br />
|ColliderId||int||Index in a list of sound effects the object makes when collided with. The list is defined in the file [[default_impacts.csv|/aud/cardata/player/default_impacts.csv]].<br />
|-<br />
|CollisionPrim||int||Defines the type of object used for collision detection, 0=boundary file, 1=bounding box, 2=cylinder with circular base, height is Y-component of ''Size'' and 3=sphere<br />
|-<br />
|CollisionType||int||Unknown, values 4, 16 and 48 are used in MM2 files<br />
|}<br />
<br />
The ''BirthRule'' block is the same as used in the [[asBirthRule]] files used to define particle effects caused by player vehicles.<br />
<br />
The image files for particle effects are named ''fxptn.tex'' where ''n'' is an integer. MM2 has files from index one to index 16, excluding index 15. It is uncertain if more files can be added, but, at least 15 might be re-instated for new particle textures. See [[asBirthRule]] for more details.<br />
<br />
''Billboarding'' an object or an image means that it is always rotated so that it faces the camera regardless of the actual orientation of the object. The flags may apply restrictions to this, such as only allowing rotation around the Y-axis, etc.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=DgBangerData&diff=120DgBangerData2006-08-06T21:43:49Z<p>Fre-Ber: /* File naming rules */</p>
<hr />
<div>The ''dgBangerData'' files are used to define collision properties for [[PKG]] objects. These properties define how an object behaves when something collides with it. <br />
<br />
The file names are derived from the name of the [[PKG]] and the names of the internal parts of it. The syntax is like this for the banger data of the entire object:<br />
/tune/banger/<pkgname>.dgBangerData<br />
<br />
and like this for the breakable parts:<br />
/tune/banger/<pkgname>_<partname>.dgBangerData<br />
<br />
For example, the banger data for the wooden barricade, ''/geometry/sp_barricadewood_f.pkg'', of SF and London is defined in the following files:<br />
/tune/banger/sp_barricadewood_f.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK01.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK02.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK03.dgBangerData<br />
/tune/banger/sp_barricadewood_f_BREAK04.dgBangerData<br />
<br />
==Specification==<br />
The format is ASCII-based and made up of tag-value rows grouped in ''blocks'' between ''{'' and ''}'' symbols.<br />
<br />
The files start with a definition of the type of banger data given. None of the MM2 files use anything but ''type a'', like this:<br />
type: a<br />
<br />
Next comes the main ''dgBangerData'' block:<br />
dgBangerData {<br />
<tags><br />
}<br />
<br />
''<tags>'' is replaced by a list of tags from the following table. The order of the tags is significant, but some tags may be omitted from the file, in that case the values from ''default.dgBangerData'' is used.<br />
{| class="wikitable"<br />
|+ Tags of the dgBangerData block<br />
!tag!!format!!Description<br />
|-<br />
|AudioId||int||Index in a list of sound effects the object makes all the time?<br />
|-<br />
|Size||float float float||Width, height and depth of the bounding box around the object<br />
|-<br />
|CG||float float float||Center of gravity, rotation takes place around this point<br />
|-<br />
|NumGlows||int||Number of image light glow effects listed below using the GlowOffset tag. These effects are only active at night<br />
|-<br />
|GlowOffset||float float float||Position of a ''billboarded'' glow effect image<br />
|-<br />
|Mass||float||Mass of the object in kilograms, closely related to the objects weight<br />
|-<br />
|Elasticity||float||Controls the ''bounciness'' of the object<br />
|-<br />
|Friction||float||friction coefficient, determines how much force is required to slide along the surface of the object<br />
|-<br />
|ImpulseLimit2||float||Force required to move the object<br />
|-<br />
|SpinAxis||int||Unknown, always set to 0 in MM2 files<br />
|-<br />
|Flash||int||Unknown<br />
|-<br />
|NumParts||int||Number of breakable parts in the object<br />
|-<br />
|BirthRule||block||Particle effect for collision, see below<br />
|-<br />
|TexNumber||int||Number of the particle texture map, see below<br />
|-<br />
|BillFlags||int||Flags controlling ''billboarding'', 0, 64, 128 and 512 are used in MM2 files for unknown effects<br />
|-<br />
|YRadius||float||Bounding cylinder/sphere radius<br />
|-<br />
|ColliderId||int||Index in a list of sound effects the object makes when collided with. The list is defined in the file [[default_impacts.csv|/aud/cardata/player/default_impacts.csv]].<br />
|-<br />
|CollisionPrim||int||Defines the type of object used for collision detection, 0=boundary file, 1=bounding box, 2=cylinder with circular base, height is Y-component of ''Size'' and 3=sphere<br />
|-<br />
|CollisionType||int||Unknown, values 4, 16 and 48 are used in MM2 files<br />
|}<br />
<br />
The ''BirthRule'' block is the same as used in the [[asBirthRule]] files used to define particle effects caused by player vehicles.<br />
<br />
The image files for particle effects are named ''fxptn.tex'' where ''n'' is an integer. MM2 has files from index one to index 16, excluding index 15. It is uncertain if more files can be added, but, at least 15 might be re-instated for new particle textures. See [[asBirthRule]] for more details.<br />
<br />
''Billboarding'' an object or an image means that it is always rotated so that it faces the camera regardless of the actual orientation of the object. The flags may apply restrictions to this, such as only allowing rotation around the Y-axis, etc.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File_tree&diff=126File tree2006-08-06T21:27:20Z<p>Fre-Ber: /* Why does an empty table after the Content divs remove tha gap? */</p>
<hr />
<div>The AR files of MM2 make up a common file tree, the files are extracted to a, shared, virtual file system when needed. The structure of this file system is as follows:<br />
==Structure==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">root<br />
<ul><br />
<li class="FolderTree-Open">anim<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.anim<br />
<div class="FolderTree-Content"><br />
====Animation sequence====<br />
<p><br />
Each [[Pedestrian animations|animation sequence]], <br />
associated with a state, is made up by a number of key <br />
frames. Each key frame has several parameters that should be <br />
applied to each bone in the skeleton. By moving the <br />
skeleton, the entire model will move.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.csv<br />
<div class="FolderTree-Content"><br />
====Animation state model====<br />
<p><br />
The animation of a pedestrian is based on a <br />
[[Pedestrian state models|state model]]. A pedestrian is <br />
always in a specific state and each state is connected to an <br />
animation sequence. For example, if the pedestrian is in the <br />
state "WALK", the animation named pedanim_womwalk.anim is <br />
looping over and over again. When something happens, the <br />
pedestrian might make a transition from one state to another.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.rays<br />
<div class="FolderTree-Content"><br />
<br />
====Unknown: rays====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.shaders<br />
<div class="FolderTree-Content"><br />
====Shader definitions====<br />
<p><br />
The [[PKG#Shaders|shaders]] are defined in exactly the same <br />
way as for PKG objects. The pedmodel_*.shaders files follow <br />
the specification of the PKGFileData in the [[PKG]] file <br />
format.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.skel<br />
<div class="FolderTree-Content"><br />
====Skeleton====<br />
<p><br />
All the parts of a pedestrian model are bound to a <br />
[[Pedestrian skeleton|skeleton]]. <br />
A skeleton is constructed by a number of bones that are <br />
attached with joints. In MM2 the skeletons are defined using <br />
a tree structure. <br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.mod<br />
<div class="FolderTree-Content"><br />
====Geometry model====<br />
<p><br />
The [[Pedestrian model|pedmodel_*.mod]] files define the <br />
actual 3D model of a pedestrian. It defines vertices, some <br />
material attributes and the surfaces of the model.<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">aud<br />
<div class="FolderTree-Content"><br />
<br />
===Audio files===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">bound<br />
<div class="FolderTree-Content"><br />
<br />
===Object boundaries===<br />
<p><br />
MM2 use three file types for collision detection and material properties on regular PKG objects, [[BND]], [[BBND]] and [[TER]].<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.bnd<br />
<div class="FolderTree-Content"><br />
====ASCII bound====<br />
<p><br />
Simple, ASCII-based file format defined [[BND|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.bbnd<br />
<div class="FolderTree-Content"><br />
====Binary bound====<br />
<p><br />
Binary version of the ASCII-based format, defined [[BBND|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.ter<br />
<div class="FolderTree-Content"><br />
====Terrain bound====<br />
<p><br />
Unknown format, defined [[TER|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">city<br />
<div class="FolderTree-Content"><br />
<br />
===City definitions===<br />
<p><br />
Each MM2 city has a number of files defining the actual city, its geometry, monuments, traffic flows and so on. Many of the files that controls these things are stored in the ''city'' folder.<br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-Open">audio_pathsets<br />
<ul><br />
<li class="FolderTree-File-JS">*.pathset<br />
<div class="FolderTree-Content"><br />
====Local city sound placement====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">decals.pathset<br />
<div class="FolderTree-Content"><br />
====Decal placements====<br />
<p><br />
Decals are flat images that can be placed on the ground <br />
and on facades to increase the visual detail level. Decals <br />
are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">props.pathset<br />
<div class="FolderTree-Content"><br />
====Prop placements====<br />
<p><br />
Props are, typically, small 3D objects like road cones, <br />
park benches and similar that can be placed around the <br />
city. Props are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">propdefs.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop definitions====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
repetiton controls for certain props. The proprules file <br />
controls which of these props are to be placed next in <br />
line.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">proprules.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop rules====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
the sequencing of the prop definitions defined in the <br />
propdefs file. The [[PSDL]] file selects a proprule index <br />
from this file for each road. <br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
This file controls what ambients are present in this city.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.bai<br />
<div class="FolderTree-Content"><br />
====Ambient path file====<br />
<p><br />
This file defines where and how the ambients may move in the <br />
city. See [[BAI]] for details.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cpvs<br />
<div class="FolderTree-Content"><br />
====Potentially visible set definition====<br />
<p><br />
MM2 uses a PVS, or potentially visible set, algorithm to <br />
speed up rendering of each game frame. These files contain <br />
the pre-calculated PVS tree. See [[CPVS]] for details.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.inst<br />
<div class="FolderTree-Content"><br />
====Stationary objects====<br />
<p><br />
For stationary objects that require more detail than the <br />
[[PSDL]] file can provide, the [[INST]] file can be used to <br />
place [[PKG]] objects throughout the city. These objects <br />
will not move for anything.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.ldef<br />
<div class="FolderTree-Content"><br />
====LDEF====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lmap<br />
<div class="FolderTree-Content"><br />
====Light map definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lt*<br />
<div class="FolderTree-Content"><br />
====LT====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">materials.csv<br />
<div class="FolderTree-Content"><br />
====Material mappings====<br />
<p><br />
This file simply lists what material should be used together <br />
with which image map.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">materials.mtl<br />
<div class="FolderTree-Content"><br />
====Material definitions====<br />
<p><br />
Defines material properties such as friction and possible <br />
particle effecs that apply to a particular type of surface.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.psdl<br />
<div class="FolderTree-Content"><br />
====City geometry====<br />
<p><br />
The [[PSDL]] file defines the major geometry of the city. <br />
All roads and most buildings are defined with this file.<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.sky<br />
<div class="FolderTree-Content"><br />
====Sky dome definition====<br />
<p><br />
Defines the name of the sky dome object and to position of <br />
the center of this dome relative to the [[PSDL]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.water<br />
<div class="FolderTree-Content"><br />
====Water of death definition====<br />
<p><br />
Defines the heghit of deadly water - if a vehicle goes below <br />
this height it sleeps with the fishes. Possibly a list of <br />
[[PSDL]] block ids can be listed for blocks that define <br />
deadly water at any height. <br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">geometry<br />
<div class="FolderTree-Content"><br />
<br />
===Object definitions===<br />
<p><br />
The geometry of generic 3D objects are defined by PKG files. These are used for many things, from player vehicles to statues and complex facades.<br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">*.pkg<br />
<div class="FolderTree-Content"><br />
====Object geometry====<br />
<p><br />
Actual geometry is defined in these files, definition can be found [[PKG|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.mtx<br />
<div class="FolderTree-Content"><br />
====Object matrix====<br />
<p><br />
Defines a transformation matrix for ''local'' parts of a [[PKG]]. Format is defined [[MTX|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">jpg<br />
<div class="FolderTree-Content"><br />
<br />
===Game interface graphics===<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-Open">texture<br />
<div class="FolderTree-Content"><br />
===Game image maps===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">*.tex<br />
<div class="FolderTree-Content"><br />
====Custom image map file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.tga<br />
<div class="FolderTree-Content"><br />
====Targa image map file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">race<br />
<div class="FolderTree-Content"><br />
===Race definitions===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-File-JS">*.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">*.aimap_p<br />
<div class="FolderTree-Content"><br />
====Ambient control file?====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>waypoints.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>data.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><eventname>.csv<br />
<div class="FolderTree-Content"><br />
====Event definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">mm[blitz|circuit|crash|race]data.csv<br />
<div class="FolderTree-Content"><br />
====Race progression definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">multicopwaypoints.csv<br />
<div class="FolderTree-Content"><br />
====Cops and robbers locations====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>_rewards.csv<br />
<div class="FolderTree-Content"><br />
====Race reward definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>-[a|p]-<n>.opp<br />
<div class="FolderTree-Content"><br />
====Opponent definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><racename>.pathset<br />
<div class="FolderTree-Content"><br />
====Race props====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">scene<br />
<div class="FolderTree-Content"><br />
===Scene?===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-File-JS">modtypes.ini<br />
<div class="FolderTree-Content"><br />
====Mod types?====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">tune<br />
<div class="FolderTree-Content"><br />
===Tuning information===<br />
<p><br />
</p><br />
</div><table></table><br />
<ul><br />
<li class="FolderTree-Open">banger<br />
<ul><br />
<li class="FolderTree-File-JS"><objectname>.dgBangerData<br />
<div class="FolderTree-Content"><br />
====Object collision properties====<br />
<p><br />
Defines properties controlling [[PKG]] objects that has<br />
collided with something. The format is described [[dgBangerData|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">camera<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>[_dash].camPovCS<br />
<div class="FolderTree-Content"><br />
<br />
====Camera definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_[NEAR|FAR].camTrackCS<br />
<div class="FolderTree-Content"><br />
====Camera tracking definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">effects<br />
<ul><br />
<li class="FolderTree-File-JS"><effectname>.asBirthRule<br />
<div class="FolderTree-Content"><br />
====Particle effect definition====<br />
<p><br />
Particle effects are used in weather, vehicle effects and collisions. The format is described [[asBirthRule|here]].<br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">vehicle<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>.aiVehicleData<br />
<div class="FolderTree-Content"><br />
<br />
====Ambient vehicle data====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====??====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehCarDamage<br />
<div class="FolderTree-Content"><br />
====Vehicle damage control====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>[_opp].vehCarSim<br />
<div class="FolderTree-Content"><br />
====Vehicle tuning====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehGyro<br />
<div class="FolderTree-Content"><br />
====Vehicle stability====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehStuck<br />
<div class="FolderTree-Content"><br />
====Vehicle instability====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">[rain|snow].asBirthRule<br />
<div class="FolderTree-Content"><br />
====Weather particle effect====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle control settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_dash.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle dashboard settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cinfo<br />
<div class="FolderTree-Content"><br />
====City definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint settings====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.info<br />
<div class="FolderTree-Content"><br />
====Vehicle information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">menu.csv<br />
<div class="FolderTree-Content"><br />
====Game interface menu options====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS">widget.csv<br />
<div class="FolderTree-Content"><br />
====Game interface widgets====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.mmHudMap<br />
<div class="FolderTree-Content"><br />
====Hudmap definitions====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.mmMirror<br />
<div class="FolderTree-Content"><br />
====Vehicle rear view mirror definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><texturenamestem>.movie<br />
<div class="FolderTree-Content"><br />
====Animated image sequence definition====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><table></table><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=User:Fre-Ber&diff=1301User:Fre-Ber2006-08-06T21:10:30Z<p>Fre-Ber: /* Folder tree - tested a comment for the objects folder */</p>
<hr />
<div>==Math==<br />
<math>\frac{a}{\sqrt{b}}</math><br />
<br />
==Folder tree==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">js<br />
<ul><br />
<li class="FolderTree-Open">real<br />
<ul><br />
<li class="FolderTree-Open">code<br />
<ul><br />
<li class="FolderTree-File-JS">r3vsl.js<br />
<div class="FolderTree-Content"><br />
===SETATTRIBUTESHOWSTATEBYOBJ - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that two parameters are required, in fact this <br />
method takes three paramters. In addition to this, the automatic header file generator <br />
that Realsoft used has a funny way of truncating method names. In r3vsl.js it causes <br />
two methods to have the same name. The effective result of this is that only the <br />
method that is last declared in the JS class will function. To remedy this, apply the <br />
following diff to your file:<br />
</p><br />
<pre> // attr tag is unknown.<br />
// p2: Integer, attribute tag<br />
// p3: Integer, show state (TRUE == show, FALSE == hide)<br />
<br />
-R3VSLM_SETATTRIBUTESHOWSTATE = 53020;<br />
+R3VSLM_SETATTRIBUTESHOWSTATEBYOBJ = 53020;<br />
<br />
-function mR3VSLM_SETATTRIBUTESHOWSTATE(p2, p3) {<br />
- return DoA3(this.r3obj, R3VSLM_SETATTRIBUTESHOWSTATE, 0, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_INTEGER, 0);<br />
+function mR3VSLM_SETATTRIBUTESHOWSTATEBYOBJ(p1, p2, p3) {<br />
+ return DoA3(this.r3obj, R3VSLM_SETATTRIBUTESHOWSTATE, p1, R3TID_OBJECT, 0, p2, R3TID_INTEGER, 0, p3, R3TID_INTEGER, 0);<br />
}<br />
</pre><br />
<p>And further down:</p><br />
<pre> this.ISOFPHASELEVEL=mR3VSLM_ISOFPHASELEVEL;<br />
- this.SETATTRIBUTESHOWSTATE=mR3VSLM_SETATTRIBUTESHOWSTATE;<br />
+ this.SETATTRIBUTESHOWSTATEBYOBJ=mR3VSLM_SETATTRIBUTESHOWSTATEBYOBJ;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td> 4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
<br />
===SETATTRIBUTENAMEBYOBJ - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that two parameters are required, in fact this <br />
method takes three paramters.<br />
</p><br />
<pre> R3VSLM_SETATTRIBUTENAMEBYOBJ = 53021;<br />
<br />
-function mR3VSLM_SETATTRIBUTENAMEBYOBJ(p2, p3) {<br />
+function mR3VSLM_SETATTRIBUTENAMEBYOBJ(p1, p2, p3) {<br />
- return DoA3(this.r3obj, R3VSLM_SETATTRIBUTENAMEBYOBJ, 0, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_STRING, 0);<br />
+ return DoA3(this.r3obj, R3VSLM_SETATTRIBUTENAMEBYOBJ, p1, R3TID_INTEGER, 0, p2, R3TID_INTEGER, 0, p3, R3TID_STRING, 0);<br />
}<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td> 4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">objects<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div> <ul><br />
<li class="FolderTree-File-JS">r3prim.h<br />
<div class="FolderTree-Content"><br />
===ENUMSELECTHANDLES - Wrong number of parameters===<br />
<p><br />
The declaration of this method states that no parameters are required, in fact this <br />
method takes a tag list as a paramter.<br />
</p><br />
<pre> R3PRIMM_ENUMSELECTHANDLES = 140156;<br />
<br />
-function mR3PRIMM_ENUMSELECTHANDLES() {<br />
- DoA(this.r3obj, R3PRIMM_ENUMSELECTHANDLES, 0, R3TID_INTEGER, 0);<br />
+function mR3PRIMM_ENUMSELECTHANDLES(p3) {<br />
+ return Do(this.r3obj, R3PRIMM_ENUMSELECTHANDLES, p3, R3TID_TAG, R3TNF_ARRAY);<br />
}<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">r3subdiv.js<br />
<div class="FolderTree-Content"><br />
===SELECTEDFACESTOTRI - Truncated method name===<br />
<p><br />
The automatic header file generator that Realsoft used has a funny way of truncating <br />
method names. This may be a requirement of the JS engine, but it causes some <br />
problems. In r3subdiv.js it causes two methods to have the same name. The effective <br />
result of this is that only the method that is last declared in the JS class will function. To <br />
remedy this, apply the following diff to your file:<br />
</p><br />
<pre> R3SUBDIVM_GETMAXEDGESPERVERT = 1235126;<br />
function mR3SUBDIVM_GETMAXEDGESPERVERT() {<br />
return DoA(this.r3obj, 1235126, 0, R3TID_INTEGER, 0);<br />
<br />
-R3SUBDIVM_SELECTEDFACESTOTRI = 1235127;<br />
+R3SUBDIVM_SELECTEDFACESTOTRIS = 1235127;<br />
-function mR3SUBDIVM_SELECTEDFACESTOTRI(p1, p3) {<br />
+function mR3SUBDIVM_SELECTEDFACESTOTRIS(p1, p3) {<br />
if(arguments.length &lt; 2) {<br />
- error(&quot;SELECTEDFACESTOTRI() needs 2 parameters&quot;);<br />
+ error(&quot;SELECTEDFACESTOTRIS() needs 2 parameters&quot;);<br />
}<br />
return DoA2(this.r3obj, 1235127, p1, R3TID_BOOLEAN, 0, p3, R3TID_BOOLEAN, 0);<br />
<br />
</pre><br />
<p>Then, further down:</p><br />
<pre> this.GETMAXEDGESPERVERT=mR3SUBDIVM_GETMAXEDGESPERVERT;<br />
- this.SELECTEDFACESTOTRI=mR3SUBDIVM_SELECTEDFACESTOTRI;<br />
+ this.SELECTEDFACESTOTRIS=mR3SUBDIVM_SELECTEDFACESTOTRIS;<br />
this.WELD=mR3SUBDIVM_WELD;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td /><br />
</tr><br />
<tr><br />
<td>5.1.56 linux</td><br />
<td /><br />
</tr><br />
</table><br />
<br />
===EXTRUDE - Several tags omitted===<br />
<p><br />
Some special tgas may be used with the EXTRUDE method, unfortunately, r3subdiv.js <br />
does not define symbols for these tags. In order to use these tags without having to <br />
remember their number, apply the following diff to your file:<br />
</p><br />
<pre>function GetR3SUBDIVA_Quality() {<br />
return R3Get(this.r3obj, R3SUBDIVA_Quality, R3TID_INTEGER, 0);<br />
}<br />
<br />
+R3SUBDIVA_ExtrudeRegionOpt = 1235512;<br />
+R3SUBDIVA_ExtrudeNormalOpt = 1235513;<br />
+R3SUBDIVA_ExtrudeLeaveFloor = 1235514;<br />
</pre><br />
<table border="1" cellpadding="5" cellspacing="0"><br />
<tr><br />
<th>Error spotted in </th><br />
<th>Error fixed in</th><br />
</tr><br />
<tr><br />
<td>4.26.40 win</td><br />
<td>5.1.57 linux</td><br />
</tr><br />
<tr><br />
<td>5.1.56 linux</td><br />
<td /><br />
</tr><br />
</table><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=BBND&diff=1333BBND2006-08-06T20:48:51Z<p>Fre-Ber: </p>
<hr />
<div>BND is a binary version of the [[BND|ASCII-based]] format used to define the boundary of [[PKG]] objects.<br />
<br />
struct BBND<br />
{<br />
char version; // == 1<br />
long nVertices;<br />
long nMaterials;<br />
long nPolys;<br />
BBNDVertex vertices[nVertices];<br />
BBNDMaterial materials[nMaterials];<br />
BBNDPolygon polys[nPolys];<br />
};<br />
<br />
struct BBNDVertex<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
};<br />
<br />
struct BBNDMaterial<br />
{<br />
char[32] name;<br />
float elasticity;<br />
float friction;<br />
char[32] effect;<br />
char[32] sound;<br />
};<br />
<br />
struct BBNDPolygon<br />
{<br />
short indicies[4];<br />
short material;<br />
};<br />
<br />
Bound polygons can be quads and triangles. If a polygon is a triangle, the last index is 0. Therefore a future exporter must never put the vertex index 0 last in a quad polygon. All strings are fixed 32 byte arrays with terminator byte 0x00.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File_tree&diff=118File tree2006-08-06T20:47:28Z<p>Fre-Ber: /* Object boundaries */</p>
<hr />
<div>The AR files of MM2 make up a common file tree, the files are extracted to a, shared, virtual file system when needed. The structure of this file system is as follows:<br />
==Structure==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">root<br />
<ul><br />
<li class="FolderTree-Open">anim<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.anim<br />
<div class="FolderTree-Content"><br />
====Animation sequence====<br />
<p><br />
Each [[Pedestrian animations|animation sequence]], <br />
associated with a state, is made up by a number of key <br />
frames. Each key frame has several parameters that should be <br />
applied to each bone in the skeleton. By moving the <br />
skeleton, the entire model will move.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.csv<br />
<div class="FolderTree-Content"><br />
====Animation state model====<br />
<p><br />
The animation of a pedestrian is based on a <br />
[[Pedestrian state models|state model]]. A pedestrian is <br />
always in a specific state and each state is connected to an <br />
animation sequence. For example, if the pedestrian is in the <br />
state "WALK", the animation named pedanim_womwalk.anim is <br />
looping over and over again. When something happens, the <br />
pedestrian might make a transition from one state to another.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.rays<br />
<div class="FolderTree-Content"><br />
<br />
====Unknown: rays====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.shaders<br />
<div class="FolderTree-Content"><br />
====Shader definitions====<br />
<p><br />
The [[PKG#Shaders|shaders]] are defined in exactly the same <br />
way as for PKG objects. The pedmodel_*.shaders files follow <br />
the specification of the PKGFileData in the [[PKG]] file <br />
format.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.skel<br />
<div class="FolderTree-Content"><br />
====Skeleton====<br />
<p><br />
All the parts of a pedestrian model are bound to a <br />
[[Pedestrian skeleton|skeleton]]. <br />
A skeleton is constructed by a number of bones that are <br />
attached with joints. In MM2 the skeletons are defined using <br />
a tree structure. <br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.mod<br />
<div class="FolderTree-Content"><br />
====Geometry model====<br />
<p><br />
The [[Pedestrian model|pedmodel_*.mod]] files define the <br />
actual 3D model of a pedestrian. It defines vertices, some <br />
material attributes and the surfaces of the model.<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">aud<br />
<div class="FolderTree-Content"><br />
<br />
===Audio files===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">bound<br />
<div class="FolderTree-Content"><br />
<br />
===Object boundaries===<br />
<p><br />
MM2 use three file types for collision detection and material properties on regular PKG objects, [[BND]], [[BBND]] and [[TER]].<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.bnd<br />
<div class="FolderTree-Content"><br />
====ASCII bound====<br />
<p><br />
Simple, ASCII-based file format defined [[BND|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.bbnd<br />
<div class="FolderTree-Content"><br />
====Binary bound====<br />
<p><br />
Binary version of the ASCII-based format, defined [[BBND|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ter<br />
<div class="FolderTree-Content"><br />
====Terrain bound====<br />
<p><br />
Unknown format, defined [[TER|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">city<br />
<div class="FolderTree-Content"><br />
<br />
===City definitions===<br />
<p><br />
Each MM2 city has a number of files defining the actual city, its geometry, monuments, traffic flows and so on. Many of the files that controls these things are stored in the ''city'' folder.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-Open">audio_pathsets<br />
<ul><br />
<li class="FolderTree-File-JS">*.pathset<br />
<div class="FolderTree-Content"><br />
====Local city sound placement====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">decals.pathset<br />
<div class="FolderTree-Content"><br />
====Decal placements====<br />
<p><br />
Decals are flat images that can be placed on the ground <br />
and on facades to increase the visual detail level. Decals <br />
are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">props.pathset<br />
<div class="FolderTree-Content"><br />
====Prop placements====<br />
<p><br />
Props are, typically, small 3D objects like road cones, <br />
park benches and similar that can be placed around the <br />
city. Props are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">propdefs.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop definitions====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
repetiton controls for certain props. The proprules file <br />
controls which of these props are to be placed next in <br />
line.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">proprules.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop rules====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
the sequencing of the prop definitions defined in the <br />
propdefs file. The [[PSDL]] file selects a proprule index <br />
from this file for each road. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
This file controls what ambients are present in this city.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.bai<br />
<div class="FolderTree-Content"><br />
====Ambient path file====<br />
<p><br />
This file defines where and how the ambients may move in the <br />
city. See [[BAI]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cpvs<br />
<div class="FolderTree-Content"><br />
====Potentially visible set definition====<br />
<p><br />
MM2 uses a PVS, or potentially visible set, algorithm to <br />
speed up rendering of each game frame. These files contain <br />
the pre-calculated PVS tree. See [[CPVS]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.inst<br />
<div class="FolderTree-Content"><br />
====Stationary objects====<br />
<p><br />
For stationary objects that require more detail than the <br />
[[PSDL]] file can provide, the [[INST]] file can be used to <br />
place [[PKG]] objects throughout the city. These objects <br />
will not move for anything.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ldef<br />
<div class="FolderTree-Content"><br />
====LDEF====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lmap<br />
<div class="FolderTree-Content"><br />
====Light map definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lt*<br />
<div class="FolderTree-Content"><br />
====LT====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.csv<br />
<div class="FolderTree-Content"><br />
====Material mappings====<br />
<p><br />
This file simply lists what material should be used together <br />
with which image map.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.mtl<br />
<div class="FolderTree-Content"><br />
====Material definitions====<br />
<p><br />
Defines material properties such as friction and possible <br />
particle effecs that apply to a particular type of surface.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.psdl<br />
<div class="FolderTree-Content"><br />
====City geometry====<br />
<p><br />
The [[PSDL]] file defines the major geometry of the city. <br />
All roads and most buildings are defined with this file.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.sky<br />
<div class="FolderTree-Content"><br />
====Sky dome definition====<br />
<p><br />
Defines the name of the sky dome object and to position of <br />
the center of this dome relative to the [[PSDL]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.water<br />
<div class="FolderTree-Content"><br />
====Water of death definition====<br />
<p><br />
Defines the heghit of deadly water - if a vehicle goes below <br />
this height it sleeps with the fishes. Possibly a list of <br />
[[PSDL]] block ids can be listed for blocks that define <br />
deadly water at any height. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">geometry<br />
<div class="FolderTree-Content"><br />
<br />
===Object definitions===<br />
<p><br />
The geometry of generic 3D objects are defined by PKG files. These are used for many things, from player vehicles to statues and complex facades.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.pkg<br />
<div class="FolderTree-Content"><br />
====Object geometry====<br />
<p><br />
Actual geometry is defined in these files, definition can be found [[PKG|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.mtx<br />
<div class="FolderTree-Content"><br />
====Object matrix====<br />
<p><br />
Defines a transformation matrix for ''local'' parts of a [[PKG]]. Format is defined [[MTX|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">jpg<br />
<div class="FolderTree-Content"><br />
<br />
===Game interface graphics===<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-Open">texture<br />
<div class="FolderTree-Content"><br />
===Game image maps===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.tex<br />
<div class="FolderTree-Content"><br />
====Custom image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.tga<br />
<div class="FolderTree-Content"><br />
====Targa image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">race<br />
<div class="FolderTree-Content"><br />
===Race definitions===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-File-JS">*.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.aimap_p<br />
<div class="FolderTree-Content"><br />
====Ambient control file?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>waypoints.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>data.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><eventname>.csv<br />
<div class="FolderTree-Content"><br />
====Event definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">mm[blitz|circuit|crash|race]data.csv<br />
<div class="FolderTree-Content"><br />
====Race progression definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">multicopwaypoints.csv<br />
<div class="FolderTree-Content"><br />
====Cops and robbers locations====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>_rewards.csv<br />
<div class="FolderTree-Content"><br />
====Race reward definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>-[a|p]-<n>.opp<br />
<div class="FolderTree-Content"><br />
====Opponent definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>.pathset<br />
<div class="FolderTree-Content"><br />
====Race props====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">scene<br />
<div class="FolderTree-Content"><br />
===Scene?===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">modtypes.ini<br />
<div class="FolderTree-Content"><br />
====Mod types?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">tune<br />
<div class="FolderTree-Content"><br />
===Tuning information===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open">banger<br />
<ul><br />
<li class="FolderTree-File-JS"><objectname>.dgBangerData<br />
<div class="FolderTree-Content"><br />
====Object collision properties====<br />
<p><br />
Defines properties controlling [[PKG]] objects that has<br />
collided with something. The format is described [[dgBangerData|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">camera<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>[_dash].camPovCS<br />
<div class="FolderTree-Content"><br />
<br />
====Camera definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_[NEAR|FAR].camTrackCS<br />
<div class="FolderTree-Content"><br />
====Camera tracking definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">effects<br />
<ul><br />
<li class="FolderTree-File-JS"><effectname>.asBirthRule<br />
<div class="FolderTree-Content"><br />
====Particle effect definition====<br />
<p><br />
Particle effects are used in weather, vehicle effects and collisions. The format is described [[asBirthRule|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">vehicle<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>.aiVehicleData<br />
<div class="FolderTree-Content"><br />
<br />
====Ambient vehicle data====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====??====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehCarDamage<br />
<div class="FolderTree-Content"><br />
====Vehicle damage control====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>[_opp].vehCarSim<br />
<div class="FolderTree-Content"><br />
====Vehicle tuning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehGyro<br />
<div class="FolderTree-Content"><br />
====Vehicle stability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehStuck<br />
<div class="FolderTree-Content"><br />
====Vehicle instability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">[rain|snow].asBirthRule<br />
<div class="FolderTree-Content"><br />
====Weather particle effect====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle control settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_dash.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle dashboard settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cinfo<br />
<div class="FolderTree-Content"><br />
====City definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.info<br />
<div class="FolderTree-Content"><br />
====Vehicle information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">menu.csv<br />
<div class="FolderTree-Content"><br />
====Game interface menu options====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">widget.csv<br />
<div class="FolderTree-Content"><br />
====Game interface widgets====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.mmHudMap<br />
<div class="FolderTree-Content"><br />
====Hudmap definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.mmMirror<br />
<div class="FolderTree-Content"><br />
====Vehicle rear view mirror definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><texturenamestem>.movie<br />
<div class="FolderTree-Content"><br />
====Animated image sequence definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=PKG&diff=127PKG2006-08-06T20:46:28Z<p>Fre-Ber: /* Boundary files */</p>
<hr />
<div>==Introduction==<br />
<br />
Many aspects of MM2 requires geometric objects. These range from lampposts and waste bins, through monuments and complex facades to vehicles hudmaps and dashboards. A PKG file defines the geometric properties of a single object as well as the visual material properties of the surfaces.<br />
<br />
The PKG format used in the game Midnight Club differs slightly from this format. A description of the differences can be found [[PKGMC|here]].<br />
<br />
==Format description==<br />
===Files===<br />
The PKG file format is built up by several chunks of data, these chunks are called ''files''. There are a number of different types of files, each of these contain different types of data that make up the complete 3D model of the object.<br />
<br />
Each file has a name. This name determines the type of the file.<br />
; *VL, *L, *M, *H (Geometry file): Files whose name ends with one of "VL", "L", "M", "H" define geometry primitives. The name suffixes define the LOD, the level of detail, of the particular part of the object. A PKG-file can have any number of separate parts, some have special significance, especially for vehicle models. The suffixes themself stand for Very Low, Low, Medium and High respectively. Look [[PKG_Groups|here]] for a description of the special geometry groups.<br />
;shaders: A PKG-file always have one ''shader'' file. It defines the visual material properties to use for the surfaces defined in the geometry files. Shaders can be defined in one of two ways, either using floating point colour values or integer colour values. Each shader defines ambient, diffuse, specular and emissive colours. The floating point shader also specifies the shininess used to calculate highlights. Each shader can also specify one texture map. The shaders are organized in groups called ''paint jobs''. When an object is placed in game, a certain paint job is requested, either by the INST, PATHSET or PSDL for monuments and props or by user interaction for player vehicle models. Each paint job holds the same number of shaders, even if a particular shader is identical in several paint jobs. Each group of geometry primitives referens an index in to a single paint-job of the shader list. <br />
;offset: Unknown, probably provides a way to offset every point of this model with a fixed vector. A PKG-file can only contain one offset file.<br />
;xref: Reference to another PKG. Some objects are constructed by attaching several smaller objects to itself. Often these parts are ''breakable''. This means that they can be broken off from the main object. Examples are awnings on facades or pieces of driveable vehicles that can break off as a result of careless driving.<br />
<br />
===Structure===<br />
MM2 can read two types of PKG files, PKG2 and PKG3, these differ slightly in the structure. The following C-style format description describes this using a ''union'' type.<br />
struct PKG<br />
{<br />
char[4] header = "PKG3" | "PKG2";<br />
PKGFile[] files;<br />
}<br />
<br />
union PKGFile<br />
{<br />
PKG2File pkg2file; // If header == "PKG2"<br />
PKG3File pkg3file; // If header == "PKG3"<br />
}<br />
<br />
struct PKG2File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct PKG3File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
long length; // Length of this PKGFile in bytes<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct String<br />
{<br />
unsigned byte length; // Number of bytes in this string including<br />
// the string terminator.<br />
char[length - 1] characters; // ASCII characters<br />
char terminator = '\0';<br />
}<br />
<br />
====Geometry file====<br />
struct PKGFileData<br />
{<br />
long nSections; // Number of sections making up this LOD<br />
long nVerticesTot; // Total number of vertices in this LOD<br />
long nIndiciesTot; // Total number of indicies in this LOD<br />
long nSections2; // Repetition of the number of sections?<br />
// Highly unlikely, but I have no better suggestion at<br />
// this time<br />
long flags; // Flags defining what components are provided with<br />
// each vertex, see below<br />
PKGSection[nSections] sections;<br />
}<br />
<br />
struct PKGSection<br />
{<br />
ushort nStrips; // Number of geometry strips in this section<br />
ushort flags; // Unknown flags (Always 0 in MM2 PKGs)<br />
<br />
long shaderOffset; // Offset into the shader list of the requested<br />
// paintjob<br />
PKGStrip[nStrips] strips;<br />
}<br />
<br />
struct PKGStrip<br />
{<br />
long primType; // Determines the primitive type<br />
long nVertices; // Number of vertices in this strip<br />
PKGVertex[nVertices] vertices;<br />
long nIndices; // Number of indices making up the geometry strip<br />
ushort[nIndices] indices;<br />
}<br />
<br />
struct PKGVertex<br />
{<br />
Vertex3D coordinate; // If flags indicate coordinates<br />
Vector3D normal; // If flags indicate normals<br />
Vertex2D textureCoordinate; // If flags indicate texture coordinates<br />
}<br />
<br />
struct Vertex3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vector3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vertex2D<br />
{<br />
float x;<br />
float y;<br />
}<br />
<br />
The bits of the PKGFILEData.flags field are defined as follows:<br />
<br />
<ol start="0"><br />
<li>Unknown</li><br />
<li>Texture coordinates or coordinates</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Normal vectors</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Coordinates or texture coordinates</li><br />
</ol><br />
All other bits are unknown at this time.<br />
<br />
The only known value for primType is PRIMTYPE_TRIANGLES (=3) that means that the indices make up lists of complete, separate triangles.<br />
<br />
====Shaders====<br />
PKGFileData<br />
{<br />
long shaderType; // Bit 7: Shader type<br />
// Bit 0-6: Number of paint jobs<br />
long shadersPerPaintJob;<br />
PKGShader[Number of paint jobs * shadersPerPaintJob] shaders;<br />
}<br />
<br />
union PKGShader<br />
{<br />
FloatPKGShader floatShader; // If type is 0<br />
IntPKGShader intShader; // If type is 1<br />
}<br />
<br />
FloatPKGShader<br />
{<br />
String textureName;<br />
Color4f ambient;<br />
Color4f diffuse;<br />
Color4f specular;<br />
Color4f reflective;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
IntPKGShader<br />
{<br />
String textureName;<br />
Color4d ambient;<br />
Color4d diffuse;<br />
Color4d specular;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
Color4f<br />
{<br />
float red;<br />
float green;<br />
float blue;<br />
float alpha;<br />
}<br />
<br />
Color4d<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
unsigned char alpha;<br />
}<br />
<br />
====Offset====<br />
PKGFileData<br />
{<br />
Vector3D offset; // Have not tested, but could be an offset added to all<br />
// vertices in the object<br />
}<br />
<br />
====XRef====<br />
PKGFileData<br />
{<br />
long nReferences;<br />
PKGXRef[nReferences] references;<br />
}<br />
<br />
PKGXRef<br />
{<br />
Vector3D xAxis;<br />
Vector3D yAxis;<br />
Vector3D zAxis;<br />
Vector3D origin;<br />
char[32] name;<br />
}<br />
<br />
==MTX - Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. Look [[MTX|here]] for more information.<br />
<br />
==Boundary files==<br />
MM2 use three file types for collision detection and material properties on regular PKG objects:<br />
<br />
* [[BND]] - Simple bound mesh in a plain ASCII format.<br />
* [[BBND]] - Binary version of .bnd<br />
* [[TER]] - Unknown, but the MM2 engine does read these files<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=PKG&diff=114PKG2006-08-06T20:45:25Z<p>Fre-Ber: /* MTX - Local objects */</p>
<hr />
<div>==Introduction==<br />
<br />
Many aspects of MM2 requires geometric objects. These range from lampposts and waste bins, through monuments and complex facades to vehicles hudmaps and dashboards. A PKG file defines the geometric properties of a single object as well as the visual material properties of the surfaces.<br />
<br />
The PKG format used in the game Midnight Club differs slightly from this format. A description of the differences can be found [[PKGMC|here]].<br />
<br />
==Format description==<br />
===Files===<br />
The PKG file format is built up by several chunks of data, these chunks are called ''files''. There are a number of different types of files, each of these contain different types of data that make up the complete 3D model of the object.<br />
<br />
Each file has a name. This name determines the type of the file.<br />
; *VL, *L, *M, *H (Geometry file): Files whose name ends with one of "VL", "L", "M", "H" define geometry primitives. The name suffixes define the LOD, the level of detail, of the particular part of the object. A PKG-file can have any number of separate parts, some have special significance, especially for vehicle models. The suffixes themself stand for Very Low, Low, Medium and High respectively. Look [[PKG_Groups|here]] for a description of the special geometry groups.<br />
;shaders: A PKG-file always have one ''shader'' file. It defines the visual material properties to use for the surfaces defined in the geometry files. Shaders can be defined in one of two ways, either using floating point colour values or integer colour values. Each shader defines ambient, diffuse, specular and emissive colours. The floating point shader also specifies the shininess used to calculate highlights. Each shader can also specify one texture map. The shaders are organized in groups called ''paint jobs''. When an object is placed in game, a certain paint job is requested, either by the INST, PATHSET or PSDL for monuments and props or by user interaction for player vehicle models. Each paint job holds the same number of shaders, even if a particular shader is identical in several paint jobs. Each group of geometry primitives referens an index in to a single paint-job of the shader list. <br />
;offset: Unknown, probably provides a way to offset every point of this model with a fixed vector. A PKG-file can only contain one offset file.<br />
;xref: Reference to another PKG. Some objects are constructed by attaching several smaller objects to itself. Often these parts are ''breakable''. This means that they can be broken off from the main object. Examples are awnings on facades or pieces of driveable vehicles that can break off as a result of careless driving.<br />
<br />
===Structure===<br />
MM2 can read two types of PKG files, PKG2 and PKG3, these differ slightly in the structure. The following C-style format description describes this using a ''union'' type.<br />
struct PKG<br />
{<br />
char[4] header = "PKG3" | "PKG2";<br />
PKGFile[] files;<br />
}<br />
<br />
union PKGFile<br />
{<br />
PKG2File pkg2file; // If header == "PKG2"<br />
PKG3File pkg3file; // If header == "PKG3"<br />
}<br />
<br />
struct PKG2File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct PKG3File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
long length; // Length of this PKGFile in bytes<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct String<br />
{<br />
unsigned byte length; // Number of bytes in this string including<br />
// the string terminator.<br />
char[length - 1] characters; // ASCII characters<br />
char terminator = '\0';<br />
}<br />
<br />
====Geometry file====<br />
struct PKGFileData<br />
{<br />
long nSections; // Number of sections making up this LOD<br />
long nVerticesTot; // Total number of vertices in this LOD<br />
long nIndiciesTot; // Total number of indicies in this LOD<br />
long nSections2; // Repetition of the number of sections?<br />
// Highly unlikely, but I have no better suggestion at<br />
// this time<br />
long flags; // Flags defining what components are provided with<br />
// each vertex, see below<br />
PKGSection[nSections] sections;<br />
}<br />
<br />
struct PKGSection<br />
{<br />
ushort nStrips; // Number of geometry strips in this section<br />
ushort flags; // Unknown flags (Always 0 in MM2 PKGs)<br />
<br />
long shaderOffset; // Offset into the shader list of the requested<br />
// paintjob<br />
PKGStrip[nStrips] strips;<br />
}<br />
<br />
struct PKGStrip<br />
{<br />
long primType; // Determines the primitive type<br />
long nVertices; // Number of vertices in this strip<br />
PKGVertex[nVertices] vertices;<br />
long nIndices; // Number of indices making up the geometry strip<br />
ushort[nIndices] indices;<br />
}<br />
<br />
struct PKGVertex<br />
{<br />
Vertex3D coordinate; // If flags indicate coordinates<br />
Vector3D normal; // If flags indicate normals<br />
Vertex2D textureCoordinate; // If flags indicate texture coordinates<br />
}<br />
<br />
struct Vertex3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vector3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vertex2D<br />
{<br />
float x;<br />
float y;<br />
}<br />
<br />
The bits of the PKGFILEData.flags field are defined as follows:<br />
<br />
<ol start="0"><br />
<li>Unknown</li><br />
<li>Texture coordinates or coordinates</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Normal vectors</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Coordinates or texture coordinates</li><br />
</ol><br />
All other bits are unknown at this time.<br />
<br />
The only known value for primType is PRIMTYPE_TRIANGLES (=3) that means that the indices make up lists of complete, separate triangles.<br />
<br />
====Shaders====<br />
PKGFileData<br />
{<br />
long shaderType; // Bit 7: Shader type<br />
// Bit 0-6: Number of paint jobs<br />
long shadersPerPaintJob;<br />
PKGShader[Number of paint jobs * shadersPerPaintJob] shaders;<br />
}<br />
<br />
union PKGShader<br />
{<br />
FloatPKGShader floatShader; // If type is 0<br />
IntPKGShader intShader; // If type is 1<br />
}<br />
<br />
FloatPKGShader<br />
{<br />
String textureName;<br />
Color4f ambient;<br />
Color4f diffuse;<br />
Color4f specular;<br />
Color4f reflective;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
IntPKGShader<br />
{<br />
String textureName;<br />
Color4d ambient;<br />
Color4d diffuse;<br />
Color4d specular;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
Color4f<br />
{<br />
float red;<br />
float green;<br />
float blue;<br />
float alpha;<br />
}<br />
<br />
Color4d<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
unsigned char alpha;<br />
}<br />
<br />
====Offset====<br />
PKGFileData<br />
{<br />
Vector3D offset; // Have not tested, but could be an offset added to all<br />
// vertices in the object<br />
}<br />
<br />
====XRef====<br />
PKGFileData<br />
{<br />
long nReferences;<br />
PKGXRef[nReferences] references;<br />
}<br />
<br />
PKGXRef<br />
{<br />
Vector3D xAxis;<br />
Vector3D yAxis;<br />
Vector3D zAxis;<br />
Vector3D origin;<br />
char[32] name;<br />
}<br />
<br />
==MTX - Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. Look [[MTX|here]] for more information.<br />
<br />
==Boundary files==<br />
MM2 use three file types for collision detection and material properties on regular PKG objects:<br />
<br />
* [[bnd]] - Simple bound mesh in a plain ASCII format.<br />
* [[bbnd]] - Binary version of .bnd<br />
* [[ter]] - Unknown, but the MM2 engine does read these files<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File_tree&diff=115File tree2006-08-06T20:43:34Z<p>Fre-Ber: /* Object definitions */</p>
<hr />
<div>The AR files of MM2 make up a common file tree, the files are extracted to a, shared, virtual file system when needed. The structure of this file system is as follows:<br />
==Structure==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">root<br />
<ul><br />
<li class="FolderTree-Open">anim<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.anim<br />
<div class="FolderTree-Content"><br />
====Animation sequence====<br />
<p><br />
Each [[Pedestrian animations|animation sequence]], <br />
associated with a state, is made up by a number of key <br />
frames. Each key frame has several parameters that should be <br />
applied to each bone in the skeleton. By moving the <br />
skeleton, the entire model will move.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.csv<br />
<div class="FolderTree-Content"><br />
====Animation state model====<br />
<p><br />
The animation of a pedestrian is based on a <br />
[[Pedestrian state models|state model]]. A pedestrian is <br />
always in a specific state and each state is connected to an <br />
animation sequence. For example, if the pedestrian is in the <br />
state "WALK", the animation named pedanim_womwalk.anim is <br />
looping over and over again. When something happens, the <br />
pedestrian might make a transition from one state to another.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.rays<br />
<div class="FolderTree-Content"><br />
<br />
====Unknown: rays====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.shaders<br />
<div class="FolderTree-Content"><br />
====Shader definitions====<br />
<p><br />
The [[PKG#Shaders|shaders]] are defined in exactly the same <br />
way as for PKG objects. The pedmodel_*.shaders files follow <br />
the specification of the PKGFileData in the [[PKG]] file <br />
format.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.skel<br />
<div class="FolderTree-Content"><br />
====Skeleton====<br />
<p><br />
All the parts of a pedestrian model are bound to a <br />
[[Pedestrian skeleton|skeleton]]. <br />
A skeleton is constructed by a number of bones that are <br />
attached with joints. In MM2 the skeletons are defined using <br />
a tree structure. <br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.mod<br />
<div class="FolderTree-Content"><br />
====Geometry model====<br />
<p><br />
The [[Pedestrian model|pedmodel_*.mod]] files define the <br />
actual 3D model of a pedestrian. It defines vertices, some <br />
material attributes and the surfaces of the model.<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">aud<br />
<div class="FolderTree-Content"><br />
<br />
===Audio files===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">bound<br />
<div class="FolderTree-Content"><br />
<br />
===Object boundaries===<br />
<p><br />
MM2 use three file types for collision detection and material properties on regular PKG objects, [[bnd]], [[bbnd]] and [[ter]].<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.bnd<br />
<div class="FolderTree-Content"><br />
====ASCII bound====<br />
<p><br />
Simple, ASCII-based file format defined [[bnd|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.bbnd<br />
<div class="FolderTree-Content"><br />
====Binary bound====<br />
<p><br />
Binary version of the ASCII-based format, defined [[bbnd|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ter<br />
<div class="FolderTree-Content"><br />
====Terrain bound====<br />
<p><br />
Unknown format, defined [[ter|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">city<br />
<div class="FolderTree-Content"><br />
<br />
===City definitions===<br />
<p><br />
Each MM2 city has a number of files defining the actual city, its geometry, monuments, traffic flows and so on. Many of the files that controls these things are stored in the ''city'' folder.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-Open">audio_pathsets<br />
<ul><br />
<li class="FolderTree-File-JS">*.pathset<br />
<div class="FolderTree-Content"><br />
====Local city sound placement====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">decals.pathset<br />
<div class="FolderTree-Content"><br />
====Decal placements====<br />
<p><br />
Decals are flat images that can be placed on the ground <br />
and on facades to increase the visual detail level. Decals <br />
are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">props.pathset<br />
<div class="FolderTree-Content"><br />
====Prop placements====<br />
<p><br />
Props are, typically, small 3D objects like road cones, <br />
park benches and similar that can be placed around the <br />
city. Props are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">propdefs.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop definitions====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
repetiton controls for certain props. The proprules file <br />
controls which of these props are to be placed next in <br />
line.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">proprules.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop rules====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
the sequencing of the prop definitions defined in the <br />
propdefs file. The [[PSDL]] file selects a proprule index <br />
from this file for each road. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
This file controls what ambients are present in this city.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.bai<br />
<div class="FolderTree-Content"><br />
====Ambient path file====<br />
<p><br />
This file defines where and how the ambients may move in the <br />
city. See [[BAI]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cpvs<br />
<div class="FolderTree-Content"><br />
====Potentially visible set definition====<br />
<p><br />
MM2 uses a PVS, or potentially visible set, algorithm to <br />
speed up rendering of each game frame. These files contain <br />
the pre-calculated PVS tree. See [[CPVS]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.inst<br />
<div class="FolderTree-Content"><br />
====Stationary objects====<br />
<p><br />
For stationary objects that require more detail than the <br />
[[PSDL]] file can provide, the [[INST]] file can be used to <br />
place [[PKG]] objects throughout the city. These objects <br />
will not move for anything.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ldef<br />
<div class="FolderTree-Content"><br />
====LDEF====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lmap<br />
<div class="FolderTree-Content"><br />
====Light map definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lt*<br />
<div class="FolderTree-Content"><br />
====LT====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.csv<br />
<div class="FolderTree-Content"><br />
====Material mappings====<br />
<p><br />
This file simply lists what material should be used together <br />
with which image map.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.mtl<br />
<div class="FolderTree-Content"><br />
====Material definitions====<br />
<p><br />
Defines material properties such as friction and possible <br />
particle effecs that apply to a particular type of surface.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.psdl<br />
<div class="FolderTree-Content"><br />
====City geometry====<br />
<p><br />
The [[PSDL]] file defines the major geometry of the city. <br />
All roads and most buildings are defined with this file.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.sky<br />
<div class="FolderTree-Content"><br />
====Sky dome definition====<br />
<p><br />
Defines the name of the sky dome object and to position of <br />
the center of this dome relative to the [[PSDL]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.water<br />
<div class="FolderTree-Content"><br />
====Water of death definition====<br />
<p><br />
Defines the heghit of deadly water - if a vehicle goes below <br />
this height it sleeps with the fishes. Possibly a list of <br />
[[PSDL]] block ids can be listed for blocks that define <br />
deadly water at any height. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">geometry<br />
<div class="FolderTree-Content"><br />
<br />
===Object definitions===<br />
<p><br />
The geometry of generic 3D objects are defined by PKG files. These are used for many things, from player vehicles to statues and complex facades.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.pkg<br />
<div class="FolderTree-Content"><br />
====Object geometry====<br />
<p><br />
Actual geometry is defined in these files, definition can be found [[PKG|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.mtx<br />
<div class="FolderTree-Content"><br />
====Object matrix====<br />
<p><br />
Defines a transformation matrix for ''local'' parts of a [[PKG]]. Format is defined [[MTX|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">jpg<br />
<div class="FolderTree-Content"><br />
<br />
===Game interface graphics===<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-Open">texture<br />
<div class="FolderTree-Content"><br />
===Game image maps===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.tex<br />
<div class="FolderTree-Content"><br />
====Custom image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.tga<br />
<div class="FolderTree-Content"><br />
====Targa image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">race<br />
<div class="FolderTree-Content"><br />
===Race definitions===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-File-JS">*.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.aimap_p<br />
<div class="FolderTree-Content"><br />
====Ambient control file?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>waypoints.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>data.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><eventname>.csv<br />
<div class="FolderTree-Content"><br />
====Event definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">mm[blitz|circuit|crash|race]data.csv<br />
<div class="FolderTree-Content"><br />
====Race progression definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">multicopwaypoints.csv<br />
<div class="FolderTree-Content"><br />
====Cops and robbers locations====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>_rewards.csv<br />
<div class="FolderTree-Content"><br />
====Race reward definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>-[a|p]-<n>.opp<br />
<div class="FolderTree-Content"><br />
====Opponent definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>.pathset<br />
<div class="FolderTree-Content"><br />
====Race props====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">scene<br />
<div class="FolderTree-Content"><br />
===Scene?===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">modtypes.ini<br />
<div class="FolderTree-Content"><br />
====Mod types?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">tune<br />
<div class="FolderTree-Content"><br />
===Tuning information===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open">banger<br />
<ul><br />
<li class="FolderTree-File-JS"><objectname>.dgBangerData<br />
<div class="FolderTree-Content"><br />
====Object collision properties====<br />
<p><br />
Defines properties controlling [[PKG]] objects that has<br />
collided with something. The format is described [[dgBangerData|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">camera<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>[_dash].camPovCS<br />
<div class="FolderTree-Content"><br />
<br />
====Camera definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_[NEAR|FAR].camTrackCS<br />
<div class="FolderTree-Content"><br />
====Camera tracking definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">effects<br />
<ul><br />
<li class="FolderTree-File-JS"><effectname>.asBirthRule<br />
<div class="FolderTree-Content"><br />
====Particle effect definition====<br />
<p><br />
Particle effects are used in weather, vehicle effects and collisions. The format is described [[asBirthRule|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">vehicle<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>.aiVehicleData<br />
<div class="FolderTree-Content"><br />
<br />
====Ambient vehicle data====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====??====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehCarDamage<br />
<div class="FolderTree-Content"><br />
====Vehicle damage control====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>[_opp].vehCarSim<br />
<div class="FolderTree-Content"><br />
====Vehicle tuning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehGyro<br />
<div class="FolderTree-Content"><br />
====Vehicle stability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehStuck<br />
<div class="FolderTree-Content"><br />
====Vehicle instability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">[rain|snow].asBirthRule<br />
<div class="FolderTree-Content"><br />
====Weather particle effect====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle control settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_dash.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle dashboard settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cinfo<br />
<div class="FolderTree-Content"><br />
====City definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.info<br />
<div class="FolderTree-Content"><br />
====Vehicle information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">menu.csv<br />
<div class="FolderTree-Content"><br />
====Game interface menu options====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">widget.csv<br />
<div class="FolderTree-Content"><br />
====Game interface widgets====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.mmHudMap<br />
<div class="FolderTree-Content"><br />
====Hudmap definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.mmMirror<br />
<div class="FolderTree-Content"><br />
====Vehicle rear view mirror definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><texturenamestem>.movie<br />
<div class="FolderTree-Content"><br />
====Animated image sequence definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=File_tree&diff=112File tree2006-08-06T20:39:13Z<p>Fre-Ber: /* Object boundaries */</p>
<hr />
<div>The AR files of MM2 make up a common file tree, the files are extracted to a, shared, virtual file system when needed. The structure of this file system is as follows:<br />
==Structure==<br />
<div class="FolderTree"><br />
<ul><br />
<li class="FolderTree-Open">root<br />
<ul><br />
<li class="FolderTree-Open">anim<br />
<div class="FolderTree-Content"><br />
===Animated objects===<br />
<p><br />
The ''anim'' folder holds definitions of the animated objects <br />
of MM2. These are the pedestrians.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.anim<br />
<div class="FolderTree-Content"><br />
====Animation sequence====<br />
<p><br />
Each [[Pedestrian animations|animation sequence]], <br />
associated with a state, is made up by a number of key <br />
frames. Each key frame has several parameters that should be <br />
applied to each bone in the skeleton. By moving the <br />
skeleton, the entire model will move.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.csv<br />
<div class="FolderTree-Content"><br />
====Animation state model====<br />
<p><br />
The animation of a pedestrian is based on a <br />
[[Pedestrian state models|state model]]. A pedestrian is <br />
always in a specific state and each state is connected to an <br />
animation sequence. For example, if the pedestrian is in the <br />
state "WALK", the animation named pedanim_womwalk.anim is <br />
looping over and over again. When something happens, the <br />
pedestrian might make a transition from one state to another.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.rays<br />
<div class="FolderTree-Content"><br />
<br />
====Unknown: rays====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.shaders<br />
<div class="FolderTree-Content"><br />
====Shader definitions====<br />
<p><br />
The [[PKG#Shaders|shaders]] are defined in exactly the same <br />
way as for PKG objects. The pedmodel_*.shaders files follow <br />
the specification of the PKGFileData in the [[PKG]] file <br />
format.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.skel<br />
<div class="FolderTree-Content"><br />
====Skeleton====<br />
<p><br />
All the parts of a pedestrian model are bound to a <br />
[[Pedestrian skeleton|skeleton]]. <br />
A skeleton is constructed by a number of bones that are <br />
attached with joints. In MM2 the skeletons are defined using <br />
a tree structure. <br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.mod<br />
<div class="FolderTree-Content"><br />
====Geometry model====<br />
<p><br />
The [[Pedestrian model|pedmodel_*.mod]] files define the <br />
actual 3D model of a pedestrian. It defines vertices, some <br />
material attributes and the surfaces of the model.<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">aud<br />
<div class="FolderTree-Content"><br />
<br />
===Audio files===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">bound<br />
<div class="FolderTree-Content"><br />
<br />
===Object boundaries===<br />
<p><br />
MM2 use three file types for collision detection and material properties on regular PKG objects, [[bnd]], [[bbnd]] and [[ter]].<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.bnd<br />
<div class="FolderTree-Content"><br />
====ASCII bound====<br />
<p><br />
Simple, ASCII-based file format defined [[bnd|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.bbnd<br />
<div class="FolderTree-Content"><br />
====Binary bound====<br />
<p><br />
Binary version of the ASCII-based format, defined [[bbnd|here]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ter<br />
<div class="FolderTree-Content"><br />
====Terrain bound====<br />
<p><br />
Unknown format, defined [[ter|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">city<br />
<div class="FolderTree-Content"><br />
<br />
===City definitions===<br />
<p><br />
Each MM2 city has a number of files defining the actual city, its geometry, monuments, traffic flows and so on. Many of the files that controls these things are stored in the ''city'' folder.<br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-Open">audio_pathsets<br />
<ul><br />
<li class="FolderTree-File-JS">*.pathset<br />
<div class="FolderTree-Content"><br />
====Local city sound placement====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">decals.pathset<br />
<div class="FolderTree-Content"><br />
====Decal placements====<br />
<p><br />
Decals are flat images that can be placed on the ground <br />
and on facades to increase the visual detail level. Decals <br />
are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">props.pathset<br />
<div class="FolderTree-Content"><br />
====Prop placements====<br />
<p><br />
Props are, typically, small 3D objects like road cones, <br />
park benches and similar that can be placed around the <br />
city. Props are placed using [[Pathset|pathset]] files.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">propdefs.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop definitions====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
repetiton controls for certain props. The proprules file <br />
controls which of these props are to be placed next in <br />
line.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">proprules.csv<br />
<div class="FolderTree-Content"><br />
====Roadside prop rules====<br />
<p><br />
The roads defined by the [[PSDL]] file can be <br />
automatically be filled with props. This file defines <br />
the sequencing of the prop definitions defined in the <br />
propdefs file. The [[PSDL]] file selects a proprule index <br />
from this file for each road. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
This file controls what ambients are present in this city.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.bai<br />
<div class="FolderTree-Content"><br />
====Ambient path file====<br />
<p><br />
This file defines where and how the ambients may move in the <br />
city. See [[BAI]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cpvs<br />
<div class="FolderTree-Content"><br />
====Potentially visible set definition====<br />
<p><br />
MM2 uses a PVS, or potentially visible set, algorithm to <br />
speed up rendering of each game frame. These files contain <br />
the pre-calculated PVS tree. See [[CPVS]] for details.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.inst<br />
<div class="FolderTree-Content"><br />
====Stationary objects====<br />
<p><br />
For stationary objects that require more detail than the <br />
[[PSDL]] file can provide, the [[INST]] file can be used to <br />
place [[PKG]] objects throughout the city. These objects <br />
will not move for anything.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.ldef<br />
<div class="FolderTree-Content"><br />
====LDEF====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lmap<br />
<div class="FolderTree-Content"><br />
====Light map definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.lt*<br />
<div class="FolderTree-Content"><br />
====LT====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.csv<br />
<div class="FolderTree-Content"><br />
====Material mappings====<br />
<p><br />
This file simply lists what material should be used together <br />
with which image map.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">materials.mtl<br />
<div class="FolderTree-Content"><br />
====Material definitions====<br />
<p><br />
Defines material properties such as friction and possible <br />
particle effecs that apply to a particular type of surface.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.psdl<br />
<div class="FolderTree-Content"><br />
====City geometry====<br />
<p><br />
The [[PSDL]] file defines the major geometry of the city. <br />
All roads and most buildings are defined with this file.<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.sky<br />
<div class="FolderTree-Content"><br />
====Sky dome definition====<br />
<p><br />
Defines the name of the sky dome object and to position of <br />
the center of this dome relative to the [[PSDL]].<br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.water<br />
<div class="FolderTree-Content"><br />
====Water of death definition====<br />
<p><br />
Defines the heghit of deadly water - if a vehicle goes below <br />
this height it sleeps with the fishes. Possibly a list of <br />
[[PSDL]] block ids can be listed for blocks that define <br />
deadly water at any height. <br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">geometry<br />
<div class="FolderTree-Content"><br />
<br />
===Object definitions===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.mtx<br />
<div class="FolderTree-Content"><br />
====Object matrix====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.pkg<br />
<div class="FolderTree-Content"><br />
====Object geometry====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">jpg<br />
<div class="FolderTree-Content"><br />
===Game interface graphics===<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-Open">texture<br />
<div class="FolderTree-Content"><br />
===Game image maps===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">*.tex<br />
<div class="FolderTree-Content"><br />
====Custom image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.tga<br />
<div class="FolderTree-Content"><br />
====Targa image map file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">race<br />
<div class="FolderTree-Content"><br />
===Race definitions===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open"><cityname><br />
<ul><br />
<li class="FolderTree-File-JS">*.aimap<br />
<div class="FolderTree-Content"><br />
====Ambient control file====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">*.aimap_p<br />
<div class="FolderTree-Content"><br />
====Ambient control file?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>waypoints.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>data.csv<br />
<div class="FolderTree-Content"><br />
====Race waypoint positioning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><eventname>.csv<br />
<div class="FolderTree-Content"><br />
====Event definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">mm[blitz|circuit|crash|race]data.csv<br />
<div class="FolderTree-Content"><br />
====Race progression definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">multicopwaypoints.csv<br />
<div class="FolderTree-Content"><br />
====Cops and robbers locations====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>_rewards.csv<br />
<div class="FolderTree-Content"><br />
====Race reward definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>-[a|p]-<n>.opp<br />
<div class="FolderTree-Content"><br />
====Opponent definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><racename>.pathset<br />
<div class="FolderTree-Content"><br />
====Race props====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">scene<br />
<div class="FolderTree-Content"><br />
===Scene?===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-File-JS">modtypes.ini<br />
<div class="FolderTree-Content"><br />
====Mod types?====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">tune<br />
<div class="FolderTree-Content"><br />
===Tuning information===<br />
<p><br />
</p><br />
</div><br />
<ul><br />
<li class="FolderTree-Open">banger<br />
<ul><br />
<li class="FolderTree-File-JS"><objectname>.dgBangerData<br />
<div class="FolderTree-Content"><br />
====Object collision properties====<br />
<p><br />
Defines properties controlling [[PKG]] objects that has<br />
collided with something. The format is described [[dgBangerData|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">camera<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>[_dash].camPovCS<br />
<div class="FolderTree-Content"><br />
<br />
====Camera definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_[NEAR|FAR].camTrackCS<br />
<div class="FolderTree-Content"><br />
====Camera tracking definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">effects<br />
<ul><br />
<li class="FolderTree-File-JS"><effectname>.asBirthRule<br />
<div class="FolderTree-Content"><br />
====Particle effect definition====<br />
<p><br />
Particle effects are used in weather, vehicle effects and collisions. The format is described [[asBirthRule|here]].<br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-Open">vehicle<br />
<ul><br />
<li class="FolderTree-File-JS"><vehiclename>.aiVehicleData<br />
<div class="FolderTree-Content"><br />
<br />
====Ambient vehicle data====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====??====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehCarDamage<br />
<div class="FolderTree-Content"><br />
====Vehicle damage control====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>[_opp].vehCarSim<br />
<div class="FolderTree-Content"><br />
====Vehicle tuning====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehGyro<br />
<div class="FolderTree-Content"><br />
====Vehicle stability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehStuck<br />
<div class="FolderTree-Content"><br />
====Vehicle instability====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
<li class="FolderTree-File-JS">[rain|snow].asBirthRule<br />
<div class="FolderTree-Content"><br />
====Weather particle effect====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle control settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>_dash.asNode<br />
<div class="FolderTree-Content"><br />
====Vehicle dashboard settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.cinfo<br />
<div class="FolderTree-Content"><br />
====City definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.dgTrailerJoint<br />
<div class="FolderTree-Content"><br />
====Trailer joint settings====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.info<br />
<div class="FolderTree-Content"><br />
====Vehicle information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">menu.csv<br />
<div class="FolderTree-Content"><br />
====Game interface menu options====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS">widget.csv<br />
<div class="FolderTree-Content"><br />
====Game interface widgets====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><cityname>.mmHudMap<br />
<div class="FolderTree-Content"><br />
====Hudmap definitions====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.mmMirror<br />
<div class="FolderTree-Content"><br />
====Vehicle rear view mirror definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><texturenamestem>.movie<br />
<div class="FolderTree-Content"><br />
====Animated image sequence definition====<br />
<p><br />
</p><br />
</div><br />
</li><br />
<li class="FolderTree-File-JS"><vehiclename>.vehTrailer<br />
<div class="FolderTree-Content"><br />
====Vehicle trailer information====<br />
<p><br />
</p><br />
</div><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</li><br />
</ul><br />
</div></div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=MTX&diff=1330MTX2006-08-06T20:36:28Z<p>Fre-Ber: </p>
<hr />
<div>==Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. The name of this file is ''<pkgname>_<geometryname>.mtx'' where ''pkgname'' is the filename of the ''PKG'', without the ''.pkg'' extension and ''geometryname'' is the name of the internal geometry file excluding the trailing underscore and LOD name. For example, the ''PKG'' named ''vpauditt.pkg'' has a locally defined geometry file named ''WHL0_H''. The ''MTX'' file for this is named ''vpauditt_whl0.mtx''. If the ''geometryname'' only contains a LOD name, the ''geometryname'' is replaced by ''(null)''.<br />
<br />
What the ''MTX'' file does is to define the location and extent of the geometry file in question. MM2 can manipulate the piece of geometry based on this information in order to animate the parts of the ''PKG'' object. For example, turning the wheels depending on current velocity and steering, while maintaining quick and accurate collision detection.<br />
<br />
===MTX Structure===<br />
The file contains four vectors. The first three define a bounding box and a center of gravity while the fourth defines an offset for the coordinate system.<br />
<br />
struct MTX<br />
{<br />
Vector3D min; // Minimum x, y and z<br />
Vector3D max; // Maximum x, y and z<br />
Vector3D cog; // Center of gravity, object is rotated around this point<br />
Vector3D origin; // Origin of the local coordinate system<br />
}</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=PKG&diff=113PKG2006-08-06T20:35:46Z<p>Fre-Ber: /* MTX - Local objects - Moved description to separate page */</p>
<hr />
<div>==Introduction==<br />
<br />
Many aspects of MM2 requires geometric objects. These range from lampposts and waste bins, through monuments and complex facades to vehicles hudmaps and dashboards. A PKG file defines the geometric properties of a single object as well as the visual material properties of the surfaces.<br />
<br />
The PKG format used in the game Midnight Club differs slightly from this format. A description of the differences can be found [[PKGMC|here]].<br />
<br />
==Format description==<br />
===Files===<br />
The PKG file format is built up by several chunks of data, these chunks are called ''files''. There are a number of different types of files, each of these contain different types of data that make up the complete 3D model of the object.<br />
<br />
Each file has a name. This name determines the type of the file.<br />
; *VL, *L, *M, *H (Geometry file): Files whose name ends with one of "VL", "L", "M", "H" define geometry primitives. The name suffixes define the LOD, the level of detail, of the particular part of the object. A PKG-file can have any number of separate parts, some have special significance, especially for vehicle models. The suffixes themself stand for Very Low, Low, Medium and High respectively. Look [[PKG_Groups|here]] for a description of the special geometry groups.<br />
;shaders: A PKG-file always have one ''shader'' file. It defines the visual material properties to use for the surfaces defined in the geometry files. Shaders can be defined in one of two ways, either using floating point colour values or integer colour values. Each shader defines ambient, diffuse, specular and emissive colours. The floating point shader also specifies the shininess used to calculate highlights. Each shader can also specify one texture map. The shaders are organized in groups called ''paint jobs''. When an object is placed in game, a certain paint job is requested, either by the INST, PATHSET or PSDL for monuments and props or by user interaction for player vehicle models. Each paint job holds the same number of shaders, even if a particular shader is identical in several paint jobs. Each group of geometry primitives referens an index in to a single paint-job of the shader list. <br />
;offset: Unknown, probably provides a way to offset every point of this model with a fixed vector. A PKG-file can only contain one offset file.<br />
;xref: Reference to another PKG. Some objects are constructed by attaching several smaller objects to itself. Often these parts are ''breakable''. This means that they can be broken off from the main object. Examples are awnings on facades or pieces of driveable vehicles that can break off as a result of careless driving.<br />
<br />
===Structure===<br />
MM2 can read two types of PKG files, PKG2 and PKG3, these differ slightly in the structure. The following C-style format description describes this using a ''union'' type.<br />
struct PKG<br />
{<br />
char[4] header = "PKG3" | "PKG2";<br />
PKGFile[] files;<br />
}<br />
<br />
union PKGFile<br />
{<br />
PKG2File pkg2file; // If header == "PKG2"<br />
PKG3File pkg3file; // If header == "PKG3"<br />
}<br />
<br />
struct PKG2File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct PKG3File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
long length; // Length of this PKGFile in bytes<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct String<br />
{<br />
unsigned byte length; // Number of bytes in this string including<br />
// the string terminator.<br />
char[length - 1] characters; // ASCII characters<br />
char terminator = '\0';<br />
}<br />
<br />
====Geometry file====<br />
struct PKGFileData<br />
{<br />
long nSections; // Number of sections making up this LOD<br />
long nVerticesTot; // Total number of vertices in this LOD<br />
long nIndiciesTot; // Total number of indicies in this LOD<br />
long nSections2; // Repetition of the number of sections?<br />
// Highly unlikely, but I have no better suggestion at<br />
// this time<br />
long flags; // Flags defining what components are provided with<br />
// each vertex, see below<br />
PKGSection[nSections] sections;<br />
}<br />
<br />
struct PKGSection<br />
{<br />
ushort nStrips; // Number of geometry strips in this section<br />
ushort flags; // Unknown flags (Always 0 in MM2 PKGs)<br />
<br />
long shaderOffset; // Offset into the shader list of the requested<br />
// paintjob<br />
PKGStrip[nStrips] strips;<br />
}<br />
<br />
struct PKGStrip<br />
{<br />
long primType; // Determines the primitive type<br />
long nVertices; // Number of vertices in this strip<br />
PKGVertex[nVertices] vertices;<br />
long nIndices; // Number of indices making up the geometry strip<br />
ushort[nIndices] indices;<br />
}<br />
<br />
struct PKGVertex<br />
{<br />
Vertex3D coordinate; // If flags indicate coordinates<br />
Vector3D normal; // If flags indicate normals<br />
Vertex2D textureCoordinate; // If flags indicate texture coordinates<br />
}<br />
<br />
struct Vertex3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vector3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vertex2D<br />
{<br />
float x;<br />
float y;<br />
}<br />
<br />
The bits of the PKGFILEData.flags field are defined as follows:<br />
<br />
<ol start="0"><br />
<li>Unknown</li><br />
<li>Texture coordinates or coordinates</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Normal vectors</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Coordinates or texture coordinates</li><br />
</ol><br />
All other bits are unknown at this time.<br />
<br />
The only known value for primType is PRIMTYPE_TRIANGLES (=3) that means that the indices make up lists of complete, separate triangles.<br />
<br />
====Shaders====<br />
PKGFileData<br />
{<br />
long shaderType; // Bit 7: Shader type<br />
// Bit 0-6: Number of paint jobs<br />
long shadersPerPaintJob;<br />
PKGShader[Number of paint jobs * shadersPerPaintJob] shaders;<br />
}<br />
<br />
union PKGShader<br />
{<br />
FloatPKGShader floatShader; // If type is 0<br />
IntPKGShader intShader; // If type is 1<br />
}<br />
<br />
FloatPKGShader<br />
{<br />
String textureName;<br />
Color4f ambient;<br />
Color4f diffuse;<br />
Color4f specular;<br />
Color4f reflective;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
IntPKGShader<br />
{<br />
String textureName;<br />
Color4d ambient;<br />
Color4d diffuse;<br />
Color4d specular;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
Color4f<br />
{<br />
float red;<br />
float green;<br />
float blue;<br />
float alpha;<br />
}<br />
<br />
Color4d<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
unsigned char alpha;<br />
}<br />
<br />
====Offset====<br />
PKGFileData<br />
{<br />
Vector3D offset; // Have not tested, but could be an offset added to all<br />
// vertices in the object<br />
}<br />
<br />
====XRef====<br />
PKGFileData<br />
{<br />
long nReferences;<br />
PKGXRef[nReferences] references;<br />
}<br />
<br />
PKGXRef<br />
{<br />
Vector3D xAxis;<br />
Vector3D yAxis;<br />
Vector3D zAxis;<br />
Vector3D origin;<br />
char[32] name;<br />
}<br />
<br />
==MTX - Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. Look [[Mtx|here]] for more information.<br />
<br />
==Boundary files==<br />
MM2 use three file types for collision detection and material properties on regular PKG objects:<br />
<br />
* [[bnd]] - Simple bound mesh in a plain ASCII format.<br />
* [[bbnd]] - Binary version of .bnd<br />
* [[ter]] - Unknown, but the MM2 engine does read these files<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=PKG&diff=110PKG2006-08-06T20:33:25Z<p>Fre-Ber: /* Boundary files - moved descriptions to separate pages*/</p>
<hr />
<div>==Introduction==<br />
<br />
Many aspects of MM2 requires geometric objects. These range from lampposts and waste bins, through monuments and complex facades to vehicles hudmaps and dashboards. A PKG file defines the geometric properties of a single object as well as the visual material properties of the surfaces.<br />
<br />
The PKG format used in the game Midnight Club differs slightly from this format. A description of the differences can be found [[PKGMC|here]].<br />
<br />
==Format description==<br />
===Files===<br />
The PKG file format is built up by several chunks of data, these chunks are called ''files''. There are a number of different types of files, each of these contain different types of data that make up the complete 3D model of the object.<br />
<br />
Each file has a name. This name determines the type of the file.<br />
; *VL, *L, *M, *H (Geometry file): Files whose name ends with one of "VL", "L", "M", "H" define geometry primitives. The name suffixes define the LOD, the level of detail, of the particular part of the object. A PKG-file can have any number of separate parts, some have special significance, especially for vehicle models. The suffixes themself stand for Very Low, Low, Medium and High respectively. Look [[PKG_Groups|here]] for a description of the special geometry groups.<br />
;shaders: A PKG-file always have one ''shader'' file. It defines the visual material properties to use for the surfaces defined in the geometry files. Shaders can be defined in one of two ways, either using floating point colour values or integer colour values. Each shader defines ambient, diffuse, specular and emissive colours. The floating point shader also specifies the shininess used to calculate highlights. Each shader can also specify one texture map. The shaders are organized in groups called ''paint jobs''. When an object is placed in game, a certain paint job is requested, either by the INST, PATHSET or PSDL for monuments and props or by user interaction for player vehicle models. Each paint job holds the same number of shaders, even if a particular shader is identical in several paint jobs. Each group of geometry primitives referens an index in to a single paint-job of the shader list. <br />
;offset: Unknown, probably provides a way to offset every point of this model with a fixed vector. A PKG-file can only contain one offset file.<br />
;xref: Reference to another PKG. Some objects are constructed by attaching several smaller objects to itself. Often these parts are ''breakable''. This means that they can be broken off from the main object. Examples are awnings on facades or pieces of driveable vehicles that can break off as a result of careless driving.<br />
<br />
===Structure===<br />
MM2 can read two types of PKG files, PKG2 and PKG3, these differ slightly in the structure. The following C-style format description describes this using a ''union'' type.<br />
struct PKG<br />
{<br />
char[4] header = "PKG3" | "PKG2";<br />
PKGFile[] files;<br />
}<br />
<br />
union PKGFile<br />
{<br />
PKG2File pkg2file; // If header == "PKG2"<br />
PKG3File pkg3file; // If header == "PKG3"<br />
}<br />
<br />
struct PKG2File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct PKG3File<br />
{<br />
char[4] header = "FILE";<br />
String name; // Name of this section<br />
long length; // Length of this PKGFile in bytes<br />
PKGFileData data; // Format depends of name, see below<br />
}<br />
<br />
struct String<br />
{<br />
unsigned byte length; // Number of bytes in this string including<br />
// the string terminator.<br />
char[length - 1] characters; // ASCII characters<br />
char terminator = '\0';<br />
}<br />
<br />
====Geometry file====<br />
struct PKGFileData<br />
{<br />
long nSections; // Number of sections making up this LOD<br />
long nVerticesTot; // Total number of vertices in this LOD<br />
long nIndiciesTot; // Total number of indicies in this LOD<br />
long nSections2; // Repetition of the number of sections?<br />
// Highly unlikely, but I have no better suggestion at<br />
// this time<br />
long flags; // Flags defining what components are provided with<br />
// each vertex, see below<br />
PKGSection[nSections] sections;<br />
}<br />
<br />
struct PKGSection<br />
{<br />
ushort nStrips; // Number of geometry strips in this section<br />
ushort flags; // Unknown flags (Always 0 in MM2 PKGs)<br />
<br />
long shaderOffset; // Offset into the shader list of the requested<br />
// paintjob<br />
PKGStrip[nStrips] strips;<br />
}<br />
<br />
struct PKGStrip<br />
{<br />
long primType; // Determines the primitive type<br />
long nVertices; // Number of vertices in this strip<br />
PKGVertex[nVertices] vertices;<br />
long nIndices; // Number of indices making up the geometry strip<br />
ushort[nIndices] indices;<br />
}<br />
<br />
struct PKGVertex<br />
{<br />
Vertex3D coordinate; // If flags indicate coordinates<br />
Vector3D normal; // If flags indicate normals<br />
Vertex2D textureCoordinate; // If flags indicate texture coordinates<br />
}<br />
<br />
struct Vertex3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vector3D<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
}<br />
<br />
struct Vertex2D<br />
{<br />
float x;<br />
float y;<br />
}<br />
<br />
The bits of the PKGFILEData.flags field are defined as follows:<br />
<br />
<ol start="0"><br />
<li>Unknown</li><br />
<li>Texture coordinates or coordinates</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Normal vectors</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Unknown</li><br />
<li>Coordinates or texture coordinates</li><br />
</ol><br />
All other bits are unknown at this time.<br />
<br />
The only known value for primType is PRIMTYPE_TRIANGLES (=3) that means that the indices make up lists of complete, separate triangles.<br />
<br />
====Shaders====<br />
PKGFileData<br />
{<br />
long shaderType; // Bit 7: Shader type<br />
// Bit 0-6: Number of paint jobs<br />
long shadersPerPaintJob;<br />
PKGShader[Number of paint jobs * shadersPerPaintJob] shaders;<br />
}<br />
<br />
union PKGShader<br />
{<br />
FloatPKGShader floatShader; // If type is 0<br />
IntPKGShader intShader; // If type is 1<br />
}<br />
<br />
FloatPKGShader<br />
{<br />
String textureName;<br />
Color4f ambient;<br />
Color4f diffuse;<br />
Color4f specular;<br />
Color4f reflective;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
IntPKGShader<br />
{<br />
String textureName;<br />
Color4d ambient;<br />
Color4d diffuse;<br />
Color4d specular;<br />
float shininess; // Intensity of specular highlights<br />
}<br />
<br />
Color4f<br />
{<br />
float red;<br />
float green;<br />
float blue;<br />
float alpha;<br />
}<br />
<br />
Color4d<br />
{<br />
unsigned char red;<br />
unsigned char green;<br />
unsigned char blue;<br />
unsigned char alpha;<br />
}<br />
<br />
====Offset====<br />
PKGFileData<br />
{<br />
Vector3D offset; // Have not tested, but could be an offset added to all<br />
// vertices in the object<br />
}<br />
<br />
====XRef====<br />
PKGFileData<br />
{<br />
long nReferences;<br />
PKGXRef[nReferences] references;<br />
}<br />
<br />
PKGXRef<br />
{<br />
Vector3D xAxis;<br />
Vector3D yAxis;<br />
Vector3D zAxis;<br />
Vector3D origin;<br />
char[32] name;<br />
}<br />
<br />
==MTX - Local objects==<br />
Some PKGs have several geometry files that are defined in a local coordinate system. These are recognised by the fact that they have an additional, external file in the filesystem. The name of this file is ''<pkgname>_<geometryname>.mtx'' where ''pkgname'' is the filename of the ''PKG'', without the ''.pkg'' extension and ''geometryname'' is the name of the internal geometry file excluding the trailing underscore and LOD name. For example, the ''PKG'' named ''vpauditt.pkg'' has a locally defined geometry file named ''WHL0_H''. The ''MTX'' file for this is named ''vpauditt_whl0.mtx''. If the ''geometryname'' only contains a LOD name, the ''geometryname'' is replaced by ''(null)''.<br />
<br />
What the ''MTX'' file does is to define the location and extent of the geometry file in question. MM2 can manipulate the piece of geometry based on this information in order to animate the parts of the ''PKG'' object. For example, turning the wheels depending on current velocity and steering, while maintaining quick and accurate collision detection.<br />
<br />
===MTX Structure===<br />
The file contains four vectors. The first three define a bounding box and a center of gravity while the fourth defines an offset for the coordinate system.<br />
<br />
struct MTX<br />
{<br />
Vector3D min; // Minimum x, y and z<br />
Vector3D max; // Maximum x, y and z<br />
Vector3D cog; // Center of gravity, object is rotated around this point<br />
Vector3D origin; // Origin of the local coordinate system<br />
}<br />
<br />
==Boundary files==<br />
MM2 use three file types for collision detection and material properties on regular PKG objects:<br />
<br />
* [[bnd]] - Simple bound mesh in a plain ASCII format.<br />
* [[bbnd]] - Binary version of .bnd<br />
* [[ter]] - Unknown, but the MM2 engine does read these files<br />
<br />
It is not clear when to pick .bbnd/.ter over .bnd, but some indications imply that objects placed with INST typically uses the binary formats.</div>Fre-Berhttp://mm2kiwi.apan.is-a-geek.com/index.php?title=BBND&diff=116BBND2006-08-06T20:32:08Z<p>Fre-Ber: </p>
<hr />
<div>Defines the boundary of a [[PKG]] object.<br />
<br />
struct BBND<br />
{<br />
char version; // == 1<br />
long nVertices;<br />
long nMaterials;<br />
long nPolys;<br />
BBNDVertex vertices[nVertices];<br />
BBNDMaterial materials[nMaterials];<br />
BBNDPolygon polys[nPolys];<br />
};<br />
<br />
struct BBNDVertex<br />
{<br />
float x;<br />
float y;<br />
float z;<br />
};<br />
<br />
struct BBNDMaterial<br />
{<br />
char[32] name;<br />
float elasticity;<br />
float friction;<br />
char[32] effect;<br />
char[32] sound;<br />
};<br />
<br />
struct BBNDPolygon<br />
{<br />
short indicies[4];<br />
short material;<br />
};<br />
<br />
Bound polygons can be quads and triangles. If a polygon is a triangle, the last index is 0. Therefore a future exporter must never put the vertex index 0 last in a quad polygon. All strings are fixed 32 byte arrays with terminator byte 0x00.</div>Fre-Ber