vengi icon indicating copy to clipboard operation
vengi copied to clipboard

VOXELFORMAT: VXL animations broken

Open mgerhardy opened this issue 1 year ago • 3 comments

from the c&c mod haven discord:


i see in code you have matrix[col][row], Westwood's Matrix3D is Vector4 Row[3];, so row col

it's z up, x forward, y left (3dsmax coord system)


//------------------------------------------------
//--- 010 Editor v12.0.1 Binary Template
//
//      File: VXL.bt
//   Purpose: Parses Westwood Voxel files.
// File Mask: *.vxl
//------------------------------------------------
struct Vector4
{
    float X;
    float Y;
    float Z;
    float W;
};

struct Vector3
{
    float X;
    float Y;
    float Z;
};

struct Matrix3D
{
    Vector4 Row[3];
};

struct VoxelHeader
{
    unsigned char Name[16];
    int PaletteCount;
    int LayerCount;
    int LayerInfoCount;
    int DataSize;
};

struct VoxelLayerHeader
{
    char Name[16];
    int InfoIndex;
    int field_14;
    unsigned char field_18;
    unsigned char pad[3];
};

struct VoxelLayerInfo
{
    int StartOffset;
    int EndOffset;
    int DataOffset;
    float Scale;
    Matrix3D Transform;
    Vector3 MinBounds;
    Vector3 MaxBounds;
    unsigned char SizeX;
    unsigned char SizeY;
    unsigned char SizeZ;
    unsigned char NormalType;
};

struct VoxelCubeStruct
{
    unsigned char ColorIndex;
    unsigned char NormalIndex;
};

struct VoxelPalette {
    char startPaletteRemap;
    char endPaletteRemap;
    char palette[256*3]; 
};

when the game draws a voxel it does this scaling for hva matrixes

void __thiscall MotionLibraryClass::Scale(MotionLibraryClass *this, float scale)
{
    unsigned int f; // esi
    unsigned int l; // eax
    unsigned int j; // edx
    int v5; // eax
    int v6; // eax

    f = 0;
    if ( this->FrameCount )
    {
        do
        {
            l = this->LayerCount;
            j = 0;
            if ( l )
            {
                do
                {
                    this->Matrixes[j + f * l].Row[0].W = scale * this->Matrixes[j + f * l].Row[0].W;
                    v5 = j + this->LayerCount * f;
                    this->Matrixes[v5].Row[1].W = scale * this->Matrixes[v5].Row[1].W;
                    v6 = j++ + this->LayerCount * f;
                    this->Matrixes[v6].Row[2].W = scale * this->Matrixes[v6].Row[2].W;
                    l = this->LayerCount;
                }
                while ( j < l );
            }
            ++f;
        }
        while ( f < this->FrameCount );
    }
}

not that min max stuff you had, scale is always Scale from layer info


also in case you would want to display ingame preview: https://github.com/secsome/CncVxlRenderText

this is YR VXL code

mgerhardy avatar Sep 19 '22 16:09 mgerhardy

https://github.com/hathlife/voxel_section_editor

mgerhardy avatar Sep 21 '22 10:09 mgerhardy

found in voxel_section_editor HVA.pas


// This function converts the Westwood coordinates into OpenGL's
// (x,y,z) becomes (y,z,x)
procedure THVA.WestwoodToOpenGLCoordinates;
var
   i : integer;
   Temp: single;
begin
   for i := Low(TransformMatrices) to High(TransformMatrices) do
   begin
      Temp := TransformMatrices[i][1][1];
      TransformMatrices[i][1][1] := TransformMatrices[i][2][2];
      TransformMatrices[i][2][2] := TransformMatrices[i][3][3];
      TransformMatrices[i][3][3] := Temp;
      Temp := TransformMatrices[i][1][2];
      TransformMatrices[i][1][2] := TransformMatrices[i][2][3];
      TransformMatrices[i][2][3] := TransformMatrices[i][3][1];
      TransformMatrices[i][3][1] := Temp;
      Temp := TransformMatrices[i][1][3];
      TransformMatrices[i][1][3] := TransformMatrices[i][2][1];
      TransformMatrices[i][2][1] := TransformMatrices[i][3][2];
      TransformMatrices[i][3][2] := Temp;
      Temp := TransformMatrices[i][1][4];
      TransformMatrices[i][1][4] := TransformMatrices[i][2][4];
      TransformMatrices[i][2][4] := TransformMatrices[i][3][4];
      TransformMatrices[i][3][4] := Temp;
   end;
end;

// This function converts the OpenGL coordinates into Westwood's
// (x,y,z) becomes (z,x,y)
procedure THVA.OpenGLToWestwoodCoordinates;
var
   i : integer;
   Temp: single;
begin
   for i := Low(TransformMatrices) to High(TransformMatrices) do
   begin
      Temp := TransformMatrices[i][1][1];
      TransformMatrices[i][1][1] := TransformMatrices[i][3][3];
      TransformMatrices[i][3][3] := TransformMatrices[i][2][2];
      TransformMatrices[i][2][2] := Temp;
      Temp := TransformMatrices[i][1][2];
      TransformMatrices[i][1][2] := TransformMatrices[i][3][1];
      TransformMatrices[i][3][1] := TransformMatrices[i][2][3];
      TransformMatrices[i][2][3] := Temp;
      Temp := TransformMatrices[i][1][3];
      TransformMatrices[i][1][3] := TransformMatrices[i][3][2];
      TransformMatrices[i][3][2] := TransformMatrices[i][2][1];
      TransformMatrices[i][2][1] := Temp;
      Temp := TransformMatrices[i][1][4];
      TransformMatrices[i][1][4] := TransformMatrices[i][3][4];
      TransformMatrices[i][3][4] := TransformMatrices[i][2][4];
      TransformMatrices[i][2][4] := Temp;
   end;
end;

mgerhardy avatar Sep 22 '22 17:09 mgerhardy

TVoxelSection.WestwoodToOpenGLCoordinates

mgerhardy avatar Sep 22 '22 17:09 mgerhardy

file: hva.hexpat

struct vec4_s {
    float x [[color("FF0000")]];
    float y [[color("00FF00")]];
    float z [[color("0000FF")]];
    float w [[color("FFFF00")]];
};

struct mat3x4_s {
    vec4_s row[3];
};

struct name_s {
	char buffer[16] [[color("EECCCC")]];
};

struct hva_s {
	name_s name;
	u32 numFrames;
	u32 numNodes;
	name_s nodeNames[numNodes];
};

struct frame_s {
	mat3x4_s mat[hva.numNodes];
};

hva_s hva @0x00;
frame_s frames[hva.numFrames] @sizeof(hva);

imhex hva pattern.

mgerhardy avatar Oct 04 '22 08:10 mgerhardy

https://www.gamedev.net/forums/topic/209830-converting-coordinate-systems-3ds-max-gtopengl/

mgerhardy avatar Oct 04 '22 11:10 mgerhardy

https://youtu.be/Hp3RJ1ZlxPs

mgerhardy avatar Oct 06 '22 21:10 mgerhardy