3O Format (Chasm: The Rift)

From ModdingWiki
Jump to navigation Jump to search
3O Format (Chasm: The Rift)
Format type3D Model
Model typePolygon
Maximum number of polygons400
Maximum number of vertices938
Games

The 3O Format is used by Chasm: The Rift to store most of the game's 3D objects, such as scenery and collectible items. Monsters and the player use the more complicated CAR Format instead.

! Figure out flags and animation. Animations seem to require a separate .ANI file to be associated with the object.

There aren't any headers, footers or "magic number" in this format. There are, however, some values sandwiched between the vertex and skin data that one might expect to appear in a header instead.

The data in the 3O is divided into three distinct sections, which appear at fixed positions in the file, and only the skin data is allowed to vary in length. Unused entries in the polygon and vertex arrays are generally filled with junk data.

Based on the amount of space alloted to the arrays, the upper limit of the format ought to be 938 vertices and 400 polygons.

Skins are always 64 pixels wide.

Vertex definition

Each vertex in the array uses 6 bytes. The first two coordinates position the vertex on the horizontal axes, while the third is the vertical position.

Relative position Type Description
0x00 INT16LE X coordinate (signed)
0x02 INT16LE Y coordinate (signed)
0x04 INT16LE Z coordinate (signed)

Polygon definition

This format uses quads, rather than triangles. Each polygon uses 32 bytes.

Relative position Type Description
0x00 UINT16LE Index of first vertex
0x02 UINT16LE Index of second vertex
0x04 UINT16LE Index of third vertex
0x06 UINT16LE Index of fourth vertex
0x08 UINT16LE U coordinate of first vertex
0x0A UINT16LE V coordinate of first vertex
0x0C UINT16LE U coordinate of second vertex
0x0E UINT16LE V coordinate of second vertex
0x10 UINT16LE U coordinate of third vertex
0x12 UINT16LE V coordinate of third vertex
0x14 UINT16LE U coordinate of fourth vertex
0x16 UINT16LE V coordinate of fourth vertex
0x18 UINT16LE Next
0x1A UINT16LE Distant
0x1C UINT8 Group ID (monster/body parts) initialized with (((Flags >> 4) == 0) ? 0 : uint8_t(1 << ((Flags >> 4)-1)))
0x1D UINT8 Flags
  • bit 0: TwoSided (normally the back of the poly is invisible)
  • bit 1: AlphaTested
  • bit 2: Translucent poly
  • bit 3: Translucent poly (More visible than bit 2 version. Setting both seems to result in neither.)
  • bit 4: ? ! Seems like it might be set on objects that can block/be stood on, but toggling the bit doesn't affect them functioning as such.
  • bit 5: Invisible poly?
  • bit 6: Invisible poly?
  • bit 7: Invisible poly?

! What do the other bits do? What's the deal with the high bits making the poly invisible?

0x1E INT16LE SpriteOffset (Initialize with SpriteOffset*=(SkinWidth=64)) Appears to be a UV mapping offset, value added to the V coordinates.

Header definition

Header for 3O Format 3D Model prepended by optional CAR Format adding 0x66 to all the offsets

Offset Type Description
0x0000 Array Polygon array.
0x3200 Array Vertex array.
0x4800 UINT16LE Number of valid vertex entries.
0x4802 UINT16LE Number of valid polygon entries.
0x4804 UINT16LE Skin height
0x4806 64 × skin height array of UINT8 Skin image, each byte defines a pixel by palette index
enum BodyPartsMask : uint8_t
{
        LeftHand           = 1 << 0,
        LeftHandSeparated  = 1 << 1,
        RightHand          = 1 << 2,
        RightHandSeparated = 1 << 3,
        Head               = 1 << 4,
        HeadSeparated      = 1 << 5,
        Body               = 1 << 6,
        WeaponFire         = 1 << 7,
};

enum BodyPartSubModelId : uint8_t
{
        RightHand = 0,
        LeftHand  = 1,
        Head      = 2,
};

uint8_t FlagsToGroupId(const uint8_t flags) 
{
        const uint8_t b = flags >> 4;
        return (0 == b) ? 0 : uint8_t(1 << (b - 1));
}

uint8_t GroupIdToGroupsMask(const uint8_t group_id)
{
        return (group_id == 0) ? 64 : group_id;
}

unsigned char MonsterBase::GetBodyPartsMask() const
{
        if( fragmented_ ) // Hide all body, if fragmented.
                return 0u;
 
        unsigned char mask= BodyPartsMask::Body;
        mask|= have_left_hand_  ? BodyPartsMask::LeftHand  : BodyPartsMask::LeftHandSeparated ;
        mask|= have_right_hand_ ? BodyPartsMask::RightHand : BodyPartsMask::RightHandSeparated;
        mask|= have_head_ ? BodyPartsMask::Head : BodyPartsMask::HeadSeparated;
 
        if( int(current_animation_) == GetAnimation( AnimationId::RemoteAttack ) )
        {
                PC_ASSERT( monster_id_ < game_resources_->monsters_models.size() );
                PC_ASSERT( current_animation_ < game_resources_->monsters_models[ monster_id_ ].animations.size() );
 
                const unsigned int frame_count= game_resources_->monsters_models[ monster_id_ ].animations[ current_animation_ ].frame_count;
                const unsigned int middle_frame= frame_count / 2u;
 
                // Draw weapon fire at middle of attack animation.
                if( std::abs( int(current_animation_frame_) - int(middle_frame) ) <= 2 )
                        mask|= BodyPartsMask::WeaponFire;
        }
 
        return mask;
}


Early version

The Chasm Demo Test v1.02 (Entering Shadow Zone) uses an earlier version of the format. It is almost identical, but there are two important differences:

  • The polygon array reserves space for 300 polys (100 fewer than the full version). Vertex array therefore begins at 0x2580.
  • While not related to the 3O format per se, this version has a slightly different palette.

Therefore, it is possible to get a bare-bones readable conversion between the two formats by adding/truncating entries in the file's polygon array, but a GOOD conversion will also require fixing the skin graphic to account for the palette differences.

Software

Chasm Modding Toolkit Package is a comprehensive Windows package for customizing and modding game assets for both DOS and REMAKE version of Chasm the Rift. It supports CAR, OBJ, CEL and SPR formats for models, sprites, textures, animations and many more. You can extract, replace and preview textures, edit palettes, import/export audio, generate skyboxes and cube maps, and view assets with dedicated GUI or CLI tools.

Animator Pro (A.K.A. Autodesk Animator Pro, Ani Pro, V Paint, PJ Paint, or simply PJ) is a 256 color paint and animation package for MSDOS. It was popular in the early to mid 1990's for game art, online animation, business presentations and occasional TV productions.

Noesis is a free tool created by 'Rich Whitehouse'. Noesis provides the ability to view 3O files and even export them as different file types. Unfortunately, however, it does not yet allow the option of converting other formats to the 3O type. It is a useful tool for quickly checking model files and deciding which ones you wish to include in your project's RESOURCE.xx file.

full-featured 3D computer graphics application now owned and developed by Daz 3D.

P3DO Organizer is a software for viewing and managing 3D Objects, & Digital Pictures with a simple Explorer-ish look and feel.

OpenChasm Pascal reverse engineered source code.

Chasm-Reverse C++ open source port

AwesomeChasm list of useful Chasm resources.