Tes2Mod:ARCH3D.BSA

ARCH3D.BSA is a NumberRecord (0x0200) BSA file, containing 10251 (0x280B) records.  Each record describes a single 3D object/mesh.   

3D Object Records

The following description has been tested on all the 3D Objects contained
in Arch3D.BSA and appears to be sound.  There are two records which have 
some problems (offsets 0x008B8D58 and 0x013274C6) and don't follow the
known format of the other 10249 records.  They have a large section of
repeating bytes just after the 3D object header and their Data2 section
is not the standard.  These records could very well be corrupt or not 
used or of a special, undiscovered, format.

Each BSA record contains the information for one 3D object. Note that each
record appears to be similar to the .3D file format used in Battlespire. 
One difference is that here the .3D files are contained in one big file, 
while in Battlespire they are in individual files. Records range from 212
to 81394 bytes in size.  

A 3D Object Record normally has the following sections: 
;3D Object Header
: Always the first 64 bytes in each 3D Object Record.  
: This provides offsets to reference the other sections of the record.
;PointList
: The Point Structures which define the 3D Object Record's geometry are stored here.
;PlaneList
: The Plane Structures which define the 3D Object Record's geometry are stored here.
: Plane Structures refer to elements of the PointList.
;NormalList
: The Normals for each Plane Structure are stored here.
;PlaneDataList
: Each Plane Structure implies a 24 byte value, stored here. 
;ObjectDataList
: Each 3D Object Record refers to zero or more ObjectData Structures, stored here.

Two records contain a block of repeating bytes of unknown purpose not referenced within their 3D Object Record Header.  


3D Object Header

Each 3D Object is described by a header, which is always the first 64 bytes of the 3D Object Record.  This header reports the 3D Object's Version (necessary for interpreting the 3D Object's geometry), number and location of Point structures Plane, etc.  



PointList Section
This section is a contiguous list of PointCount Point structures.  

Point Structure
Each Point structure is an Int32 triplet:  


While the PointList Section is usually adjacent to the Object Header Section, there are two files where the PointList Section begins some distance after the Object Header Section.

PlaneList Section

The PlaneList Section contains PlaneCount Plane Structure elements describing the geometry of the 3D Object Record.  This includes the necessary points to describe the geometry, as well as the necessary texture information to display the object.  

Each Plane Structure is described by her own header, followed by three or more PlanePoint structures.  

Plane Structure elements are contiguous within the PlaneList; that is to say the second Plane Structure immediately follows the first Plane Structure.  

Plane Structure Header

Each Plane Structure is described by a header.  
From this data, one can load the Plane's geometry and texture file information.  

The 8 byte long header is described as followed: 


Texture Structure

The Texture field in the Plane Header is a bitfield containing the FileIndex and ImageIndex fields compressed into a single UInt16.  It can be interpreted as follows: 



Ex: If ImageIndex were 7, and FileIndex were 214, one would use the eighth image within TEXTURE.214 for the referring Plane Structure.

PlanePoint Structure

Immediately following the Plane Header is a set of PlanePointCount PlanePoint structures.  
Each structure contains a reference to a Point entry in the Point List Section, as well as the UV coordinates.  

The 8 byte structure is as follows: 




See UV Texture Coordinates for interpretting Daggerfall UV coordinate values.

NormalList Section

The NormalList is a PlaneCount set of Point structures, containing the Normals for each Plane structure.  Each Point structure element within the NormalList is associated by ordinal to the corresponding Plane Structure; that is to say the first Point structure in the NormalList is the normal for the first Plane structure. Normals are normalized and scaled by 256, so a normal pointing straight down the X axis would be 256 0 0.

PlaneDataList Section

For each Plane structure, there is a corresponding PlaneData structure within the 3D Object Record's PlaneDataList, by ordinal.  

The purpose of the data is currently unknown.  



ObjectDataList Section

There are ObjectDataCount elements of ObjectData Structures within the ObjectDataList.  Each ObjectData structure contains zero or more 6 byte long ObjectDataValue elements.  The ObjectData elements are contiguous; each immediately follows their predecessor.  

Each ObjectData Structure is composed of an ObjectDataHeader Structure, and zero or more ObjectDataValue structures.  The ObjectDataValue structures, if present, immediately follow the ObjectDataHeader.  

ObjectData Structure Header




ObjectDataValue
Each ObjectData Structure contains zero or more ObjectDataValue Structures.  An ObjectDataValue structure appears to be a 6 byte field of an unknown purpose.  



Special Objects

The following list of objects (by RecordId) in the ARCH3D file have special mention: 
;Object 4722 (0x8B8D58)
: This v2.6 3D object has a truncated, or different, ObjectDataList which does not conform with the known format.
;Object 7614 (0x13274C6)
: This v2.7 object has an invalid ObjectDataOffset value (it points to the middle of the PlaneDataList section).

All but 25 of the 10251 records have unique RecordId's.  It is not known if the Daggerfall engine loads the first match, or the last match when two or more records collide by RecordId values.