mirror of
https://github.com/Mauler125/r5sdk.git
synced 2025-02-09 19:15:03 +01:00
Model fixup (#91)
* fix header, flags, and add rest of major structs * minor type swap * bone flags because there are new ones * forgor this * Add compressed vector types. * fix bitfield sizes * Fix compilation. Co-authored-by: Marvin D <41352111+IcePixelx@users.noreply.github.com> Co-authored-by: rexx <67599507+r-ex@users.noreply.github.com>
This commit is contained in:
parent
9ec5b6aabd
commit
10c82e7e64
610
r5dev/mathlib/compressed_vector.h
Normal file
610
r5dev/mathlib/compressed_vector.h
Normal file
@ -0,0 +1,610 @@
|
||||
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
// $NoKeywords: $
|
||||
//
|
||||
//=============================================================================//
|
||||
|
||||
#ifndef COMPRESSED_VECTOR_H
|
||||
#define COMPRESSED_VECTOR_H
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
#include <float.h>
|
||||
|
||||
// For rand(). We really need a library!
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
#include "mathlib/vector.h"
|
||||
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#if defined( _X360 )
|
||||
#pragma bitfield_order( push, lsb_to_msb )
|
||||
#endif
|
||||
|
||||
FORCEINLINE float fpmax(float a, float b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// fit a 3D vector into 32 bits
|
||||
//=========================================================
|
||||
|
||||
class Vector32
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Vector32(void);
|
||||
Vector32(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
Vector32& operator=(const Vector3D &vOther);
|
||||
operator Vector3D ();
|
||||
|
||||
private:
|
||||
unsigned short x:10;
|
||||
unsigned short y:10;
|
||||
unsigned short z:10;
|
||||
unsigned short exp:2;
|
||||
};
|
||||
|
||||
inline Vector32& Vector32::operator=(const Vector3D &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
|
||||
|
||||
float fmax = MAX( fabs( vOther.x ), fabs( vOther.y ) );
|
||||
fmax = fpmax( fmax, fabs( vOther.z ) );
|
||||
|
||||
for (exp = 0; exp < 3; exp++)
|
||||
{
|
||||
if (fmax < expScale[exp])
|
||||
break;
|
||||
}
|
||||
|
||||
float fexp = 512.0f / expScale[exp];
|
||||
|
||||
x = clamp( (int)(vOther.x * fexp) + 512, 0, 1023 );
|
||||
y = clamp( (int)(vOther.y * fexp) + 512, 0, 1023 );
|
||||
z = clamp( (int)(vOther.z * fexp) + 512, 0, 1023 );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Vector32::operator Vector3D()
|
||||
{
|
||||
Vector3D tmp;
|
||||
|
||||
static float expScale[4] = { 4.0f, 16.0f, 32.f, 64.f };
|
||||
|
||||
float fexp = expScale[exp] / 512.0f;
|
||||
|
||||
tmp.x = (((int)x) - 512) * fexp;
|
||||
tmp.y = (((int)y) - 512) * fexp;
|
||||
tmp.z = (((int)z) - 512) * fexp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Fit a unit vector into 32 bits
|
||||
//=========================================================
|
||||
|
||||
class Normal32
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Normal32(void);
|
||||
Normal32(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
Normal32& operator=(const Vector3D &vOther);
|
||||
operator Vector3D ();
|
||||
|
||||
private:
|
||||
unsigned short x:15;
|
||||
unsigned short y:15;
|
||||
unsigned short zneg:1;
|
||||
};
|
||||
|
||||
|
||||
inline Normal32& Normal32::operator=(const Vector3D &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
x = clamp( (int)(vOther.x * 16384) + 16384, 0, 32767 );
|
||||
y = clamp( (int)(vOther.y * 16384) + 16384, 0, 32767 );
|
||||
zneg = (vOther.z < 0);
|
||||
//x = vOther.x;
|
||||
//y = vOther.y;
|
||||
//z = vOther.z;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Normal32::operator Vector3D ()
|
||||
{
|
||||
Vector3D tmp;
|
||||
|
||||
tmp.x = ((int)x - 16384) * (1 / 16384.0);
|
||||
tmp.y = ((int)y - 16384) * (1 / 16384.0);
|
||||
tmp.z = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y );
|
||||
if (zneg)
|
||||
tmp.z = -tmp.z;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
//=========================================================
|
||||
// 64 bit Quaternion
|
||||
//=========================================================
|
||||
|
||||
class Quaternion64
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Quaternion64(void);
|
||||
Quaternion64(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
// Quaternion& operator=(const Quaternion64 &vOther);
|
||||
Quaternion64& operator=(const Quaternion &vOther);
|
||||
operator Quaternion ();
|
||||
private:
|
||||
uint64_t x:21;
|
||||
uint64_t y:21;
|
||||
uint64_t z:21;
|
||||
uint64_t wneg:1;
|
||||
};
|
||||
|
||||
|
||||
inline Quaternion64::operator Quaternion ()
|
||||
{
|
||||
Quaternion tmp;
|
||||
|
||||
// shift to -1048576, + 1048575, then round down slightly to -1.0 < x < 1.0
|
||||
tmp.x = ((int)x - 1048576) * (1 / 1048576.5f);
|
||||
tmp.y = ((int)y - 1048576) * (1 / 1048576.5f);
|
||||
tmp.z = ((int)z - 1048576) * (1 / 1048576.5f);
|
||||
tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
|
||||
if (wneg)
|
||||
tmp.w = -tmp.w;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline Quaternion64& Quaternion64::operator=(const Quaternion &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
x = clamp( (int)(vOther.x * 1048576) + 1048576, 0, 2097151 );
|
||||
y = clamp( (int)(vOther.y * 1048576) + 1048576, 0, 2097151 );
|
||||
z = clamp( (int)(vOther.z * 1048576) + 1048576, 0, 2097151 );
|
||||
wneg = (vOther.w < 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// 48 bit Quaternion
|
||||
//=========================================================
|
||||
|
||||
class Quaternion48
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Quaternion48(void);
|
||||
Quaternion48(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
// Quaternion& operator=(const Quaternion48 &vOther);
|
||||
Quaternion48& operator=(const Quaternion &vOther);
|
||||
operator Quaternion ();
|
||||
//private:
|
||||
unsigned short x:16;
|
||||
unsigned short y:16;
|
||||
unsigned short z:15;
|
||||
unsigned short wneg:1;
|
||||
};
|
||||
|
||||
|
||||
inline Quaternion48::operator Quaternion ()
|
||||
{
|
||||
Quaternion tmp;
|
||||
|
||||
tmp.x = ((int)x - 32768) * (1 / 32768.5);
|
||||
tmp.y = ((int)y - 32768) * (1 / 32768.5);
|
||||
tmp.z = ((int)z - 16384) * (1 / 16384.5);
|
||||
tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
|
||||
if (wneg)
|
||||
tmp.w = -tmp.w;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline Quaternion48& Quaternion48::operator=(const Quaternion &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
x = clamp( (int)(vOther.x * 32768) + 32768, 0, 65535 );
|
||||
y = clamp( (int)(vOther.y * 32768) + 32768, 0, 65535 );
|
||||
z = clamp( (int)(vOther.z * 16384) + 16384, 0, 32767 );
|
||||
wneg = (vOther.w < 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// 32 bit Quaternion
|
||||
//=========================================================
|
||||
|
||||
class Quaternion32
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Quaternion32(void);
|
||||
Quaternion32(vec_t X, vec_t Y, vec_t Z);
|
||||
|
||||
// assignment
|
||||
// Quaternion& operator=(const Quaternion48 &vOther);
|
||||
Quaternion32& operator=(const Quaternion &vOther);
|
||||
operator Quaternion ();
|
||||
private:
|
||||
unsigned int x:11;
|
||||
unsigned int y:10;
|
||||
unsigned int z:10;
|
||||
unsigned int wneg:1;
|
||||
};
|
||||
|
||||
|
||||
inline Quaternion32::operator Quaternion ()
|
||||
{
|
||||
Quaternion tmp;
|
||||
|
||||
tmp.x = ((int)x - 1024) * (1 / 1024.0);
|
||||
tmp.y = ((int)y - 512) * (1 / 512.0);
|
||||
tmp.z = ((int)z - 512) * (1 / 512.0);
|
||||
tmp.w = sqrt( 1 - tmp.x * tmp.x - tmp.y * tmp.y - tmp.z * tmp.z );
|
||||
if (wneg)
|
||||
tmp.w = -tmp.w;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline Quaternion32& Quaternion32::operator=(const Quaternion &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
x = clamp( (int)(vOther.x * 1024) + 1024, 0, 2047 );
|
||||
y = clamp( (int)(vOther.y * 512) + 512, 0, 1023 );
|
||||
z = clamp( (int)(vOther.z * 512) + 512, 0, 1023 );
|
||||
wneg = (vOther.w < 0);
|
||||
return *this;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// 16 bit float
|
||||
//=========================================================
|
||||
|
||||
|
||||
const int float32bias = 127;
|
||||
const int float16bias = 15;
|
||||
|
||||
const float maxfloat16bits = 65504.0f;
|
||||
|
||||
class float16
|
||||
{
|
||||
public:
|
||||
//float16() {}
|
||||
//float16( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
|
||||
|
||||
void Init() { m_storage.rawWord = 0; }
|
||||
// float16& operator=(const float16 &other) { m_storage.rawWord = other.m_storage.rawWord; return *this; }
|
||||
// float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
|
||||
// operator unsigned short () { return m_storage.rawWord; }
|
||||
// operator float () { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
|
||||
unsigned short GetBits() const
|
||||
{
|
||||
return m_storage.rawWord;
|
||||
}
|
||||
float GetFloat() const
|
||||
{
|
||||
return Convert16bitFloatTo32bits( m_storage.rawWord );
|
||||
}
|
||||
void SetFloat( float in )
|
||||
{
|
||||
m_storage.rawWord = ConvertFloatTo16bits( in );
|
||||
}
|
||||
|
||||
bool IsInfinity() const
|
||||
{
|
||||
return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa == 0;
|
||||
}
|
||||
bool IsNaN() const
|
||||
{
|
||||
return m_storage.bits.biased_exponent == 31 && m_storage.bits.mantissa != 0;
|
||||
}
|
||||
|
||||
bool operator==(const float16 other) const { return m_storage.rawWord == other.m_storage.rawWord; }
|
||||
bool operator!=(const float16 other) const { return m_storage.rawWord != other.m_storage.rawWord; }
|
||||
|
||||
// bool operator< (const float other) const { return GetFloat() < other; }
|
||||
// bool operator> (const float other) const { return GetFloat() > other; }
|
||||
|
||||
protected:
|
||||
union float32bits
|
||||
{
|
||||
float rawFloat;
|
||||
struct
|
||||
{
|
||||
unsigned int mantissa : 23;
|
||||
unsigned int biased_exponent : 8;
|
||||
unsigned int sign : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
union float16bits
|
||||
{
|
||||
unsigned short rawWord;
|
||||
struct
|
||||
{
|
||||
unsigned short mantissa : 10;
|
||||
unsigned short biased_exponent : 5;
|
||||
unsigned short sign : 1;
|
||||
} bits;
|
||||
};
|
||||
|
||||
static bool IsNaN( float16bits in )
|
||||
{
|
||||
return in.bits.biased_exponent == 31 && in.bits.mantissa != 0;
|
||||
}
|
||||
static bool IsInfinity( float16bits in )
|
||||
{
|
||||
return in.bits.biased_exponent == 31 && in.bits.mantissa == 0;
|
||||
}
|
||||
|
||||
// 0x0001 - 0x03ff
|
||||
static unsigned short ConvertFloatTo16bits( float input )
|
||||
{
|
||||
if ( input > maxfloat16bits )
|
||||
input = maxfloat16bits;
|
||||
else if ( input < -maxfloat16bits )
|
||||
input = -maxfloat16bits;
|
||||
|
||||
float16bits output;
|
||||
float32bits inFloat;
|
||||
|
||||
inFloat.rawFloat = input;
|
||||
|
||||
output.bits.sign = inFloat.bits.sign;
|
||||
|
||||
if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa==0) )
|
||||
{
|
||||
// zero
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 0;
|
||||
}
|
||||
else if ( (inFloat.bits.biased_exponent==0) && (inFloat.bits.mantissa!=0) )
|
||||
{
|
||||
// denorm -- denorm float maps to 0 half
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 0;
|
||||
}
|
||||
else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa==0) )
|
||||
{
|
||||
#if 0
|
||||
// infinity
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 31;
|
||||
#else
|
||||
// infinity maps to maxfloat
|
||||
output.bits.mantissa = 0x3ff;
|
||||
output.bits.biased_exponent = 0x1e;
|
||||
#endif
|
||||
}
|
||||
else if ( (inFloat.bits.biased_exponent==0xff) && (inFloat.bits.mantissa!=0) )
|
||||
{
|
||||
#if 0
|
||||
// NaN
|
||||
output.bits.mantissa = 1;
|
||||
output.bits.biased_exponent = 31;
|
||||
#else
|
||||
// NaN maps to zero
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 0;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular number
|
||||
int new_exp = inFloat.bits.biased_exponent-127;
|
||||
|
||||
if (new_exp<-24)
|
||||
{
|
||||
// this maps to 0
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 0;
|
||||
}
|
||||
|
||||
if (new_exp<-14)
|
||||
{
|
||||
// this maps to a denorm
|
||||
output.bits.biased_exponent = 0;
|
||||
unsigned int exp_val = ( unsigned int )( -14 - ( inFloat.bits.biased_exponent - float32bias ) );
|
||||
if( exp_val > 0 && exp_val < 11 )
|
||||
{
|
||||
output.bits.mantissa = ( 1 << ( 10 - exp_val ) ) + ( inFloat.bits.mantissa >> ( 13 + exp_val ) );
|
||||
}
|
||||
}
|
||||
else if (new_exp>15)
|
||||
{
|
||||
#if 0
|
||||
// map this value to infinity
|
||||
output.bits.mantissa = 0;
|
||||
output.bits.biased_exponent = 31;
|
||||
#else
|
||||
// to big. . . maps to maxfloat
|
||||
output.bits.mantissa = 0x3ff;
|
||||
output.bits.biased_exponent = 0x1e;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
output.bits.biased_exponent = new_exp+15;
|
||||
output.bits.mantissa = (inFloat.bits.mantissa >> 13);
|
||||
}
|
||||
}
|
||||
return output.rawWord;
|
||||
}
|
||||
|
||||
static float Convert16bitFloatTo32bits( unsigned short input )
|
||||
{
|
||||
float32bits output;
|
||||
const float16bits &inFloat = *((float16bits *)&input);
|
||||
|
||||
if( IsInfinity( inFloat ) )
|
||||
{
|
||||
return maxfloat16bits * ( ( inFloat.bits.sign == 1 ) ? -1.0f : 1.0f );
|
||||
}
|
||||
if( IsNaN( inFloat ) )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
if( inFloat.bits.biased_exponent == 0 && inFloat.bits.mantissa != 0 )
|
||||
{
|
||||
// denorm
|
||||
const float half_denorm = (1.0f/16384.0f); // 2^-14
|
||||
float mantissa = ((float)(inFloat.bits.mantissa)) / 1024.0f;
|
||||
float sgn = (inFloat.bits.sign)? -1.0f :1.0f;
|
||||
output.rawFloat = sgn*mantissa*half_denorm;
|
||||
}
|
||||
else
|
||||
{
|
||||
// regular number
|
||||
unsigned mantissa = inFloat.bits.mantissa;
|
||||
unsigned biased_exponent = inFloat.bits.biased_exponent;
|
||||
unsigned sign = ((unsigned)inFloat.bits.sign) << 31;
|
||||
biased_exponent = ( (biased_exponent - float16bias + float32bias) * (biased_exponent != 0) ) << 23;
|
||||
mantissa <<= (23-10);
|
||||
|
||||
*((unsigned *)&output) = ( mantissa | biased_exponent | sign );
|
||||
}
|
||||
|
||||
return output.rawFloat;
|
||||
}
|
||||
|
||||
|
||||
float16bits m_storage;
|
||||
};
|
||||
|
||||
class float16_with_assign : public float16
|
||||
{
|
||||
public:
|
||||
float16_with_assign() {}
|
||||
float16_with_assign( float f ) { m_storage.rawWord = ConvertFloatTo16bits(f); }
|
||||
|
||||
float16& operator=(const float16 &other) { m_storage.rawWord = ((float16_with_assign &)other).m_storage.rawWord; return *this; }
|
||||
float16& operator=(const float &other) { m_storage.rawWord = ConvertFloatTo16bits(other); return *this; }
|
||||
// operator unsigned short () const { return m_storage.rawWord; }
|
||||
operator float () const { return Convert16bitFloatTo32bits( m_storage.rawWord ); }
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// Fit a 3D vector in 48 bits
|
||||
//=========================================================
|
||||
|
||||
class Vector48
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Vector48(void) {}
|
||||
Vector48(vec_t X, vec_t Y, vec_t Z) { x.SetFloat( X ); y.SetFloat( Y ); z.SetFloat( Z ); }
|
||||
|
||||
// assignment
|
||||
Vector48& operator=(const Vector3D &vOther);
|
||||
operator Vector3D ();
|
||||
|
||||
const float operator[]( int i ) const { return (((float16 *)this)[i]).GetFloat(); }
|
||||
|
||||
float16 x;
|
||||
float16 y;
|
||||
float16 z;
|
||||
};
|
||||
|
||||
inline Vector48& Vector48::operator=(const Vector3D &vOther)
|
||||
{
|
||||
CHECK_VALID(vOther);
|
||||
|
||||
x.SetFloat( vOther.x );
|
||||
y.SetFloat( vOther.y );
|
||||
z.SetFloat( vOther.z );
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
inline Vector48::operator Vector3D ()
|
||||
{
|
||||
Vector3D tmp;
|
||||
|
||||
tmp.x = x.GetFloat();
|
||||
tmp.y = y.GetFloat();
|
||||
tmp.z = z.GetFloat();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
// Fit a 2D vector in 32 bits
|
||||
//=========================================================
|
||||
|
||||
class Vector2d32
|
||||
{
|
||||
public:
|
||||
// Construction/destruction:
|
||||
Vector2d32(void) {}
|
||||
Vector2d32(vec_t X, vec_t Y) { x.SetFloat( X ); y.SetFloat( Y ); }
|
||||
|
||||
// assignment
|
||||
Vector2d32& operator=(const Vector3D &vOther);
|
||||
Vector2d32& operator=(const Vector2D &vOther);
|
||||
|
||||
operator Vector2D ();
|
||||
|
||||
void Init( vec_t ix = 0.f, vec_t iy = 0.f);
|
||||
|
||||
float16_with_assign x;
|
||||
float16_with_assign y;
|
||||
};
|
||||
|
||||
inline Vector2d32& Vector2d32::operator=(const Vector2D &vOther)
|
||||
{
|
||||
x.SetFloat( vOther.x );
|
||||
y.SetFloat( vOther.y );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline Vector2d32::operator Vector2D ()
|
||||
{
|
||||
Vector2D tmp;
|
||||
|
||||
tmp.x = x.GetFloat();
|
||||
tmp.y = y.GetFloat();
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline void Vector2d32::Init( vec_t ix, vec_t iy )
|
||||
{
|
||||
x.SetFloat(ix);
|
||||
y.SetFloat(iy);
|
||||
}
|
||||
|
||||
#if defined( _X360 )
|
||||
#pragma bitfield_order( pop )
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,6 +1,8 @@
|
||||
#ifndef STUDIO_H
|
||||
#define STUDIO_H
|
||||
#include "mathlib/vector.h"
|
||||
#include "mathlib/mathlib.h"
|
||||
|
||||
#define MAX_NUM_LODS 8
|
||||
|
||||
// This flag is set if no hitbox information was specified
|
||||
#define STUDIOHDR_FLAGS_AUTOGENERATED_HITBOX ( 1 << 0 )
|
||||
@ -55,8 +57,9 @@
|
||||
// only valid if STUDIOHDR_FLAGS_STATIC_PROP is also set
|
||||
#define STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT ( 1 << 13 )
|
||||
|
||||
// Flag to mark delta flexes as already converted from disk format to memory format
|
||||
#define STUDIOHDR_FLAGS_FLEXES_CONVERTED ( 1 << 14 )
|
||||
// This flag indicates that the model has complex weights, which allows it to have 3< weights per bone.
|
||||
// PREVIOUSLY USED FOR: STUDIOHDR_FLAGS_FLEXES_CONVERTED
|
||||
#define STUDIOHDR_FLAGS_COMPLEX_WEIGHTS ( 1 << 14 )
|
||||
|
||||
// Indicates the studiomdl was built in preview mode
|
||||
#define STUDIOHDR_FLAGS_BUILT_IN_PREVIEW_MODE ( 1 << 15 )
|
||||
@ -82,25 +85,14 @@
|
||||
// studiohdr_t::VertAnimFixedPointScale() to always retrieve the scale value
|
||||
#define STUDIOHDR_FLAGS_VERT_ANIM_FIXED_POINT_SCALE ( 1 << 21 )
|
||||
|
||||
// If flag is set then model data is processed for EDGE
|
||||
// the flag is set at tool time when producing PS3-format assets
|
||||
#define STUDIOHDR_FLAGS_PS3_EDGE_FORMAT ( 1 << 22 )
|
||||
// unknown purpose but definitely exists
|
||||
#define STUDIOHDR_FLAGS_RESPAWN_UNK (1 << 23) // 0x800000
|
||||
|
||||
// this is a specific case to indicate a model is over budget
|
||||
#define STUDIOHDR_FLAGS_OVER_BUDGET ( 1 << 23 )
|
||||
// If this flag is present the model has vertex color, and by extension (previously) a VVC (IDVC) file.
|
||||
#define STUDIOHDR_FLAGS_USES_VERTEX_COLOR (1 << 24) // 0x1000000
|
||||
|
||||
// this is a specific case to indicate a model is over budget
|
||||
#define STUDIOHDR_FLAGS_IGNORE_BUDGETS ( 1 << 24 )
|
||||
|
||||
// internally generated combined model
|
||||
#define STUDIOHDR_FLAGS_COMBINED ( 1 << 25 )
|
||||
|
||||
// Model has an additional set of UVs
|
||||
#define STUDIOHDR_FLAGS_EXTRA_VERTEX_DATA ( 1 << 26 )
|
||||
|
||||
// NOTE: This flag is set at loadtime, not mdl build time so that we don't have to rebuild
|
||||
// models when we change materials.
|
||||
#define STUDIOHDR_BAKED_VERTEX_LIGHTING_IS_INDIRECT_ONLY ( 1 << 27 )
|
||||
// If this flag is present the model has a secondary UV layer, and by extension (previously) a VVC (IDVC) file.
|
||||
#define STUDIOHDR_FLAGS_USES_UV2 (1 << 25) // 0x2000000
|
||||
|
||||
enum
|
||||
{
|
||||
@ -123,11 +115,11 @@ enum
|
||||
struct studiohdr_t
|
||||
{
|
||||
int id; // 'IDST'
|
||||
int version; // R5 = '6'
|
||||
int version; // R5 = '54'
|
||||
int checksum;
|
||||
int tableIndex; // Offset
|
||||
int sznameindex; // This has been moved from studiohdr2 to the front of the main header.
|
||||
|
||||
char name[0x40];
|
||||
char name[64];
|
||||
|
||||
int length; // size of data
|
||||
|
||||
@ -156,8 +148,8 @@ struct studiohdr_t
|
||||
int localseqindex;
|
||||
|
||||
int activitylistversion; // initialization flag - have the sequences been indexed ?
|
||||
int eventsindexed;
|
||||
|
||||
int materialtypesindex; // index into an array of byte sized material type enums for each material used by the model
|
||||
int numtextures;
|
||||
int textureindex;
|
||||
|
||||
@ -174,23 +166,831 @@ struct studiohdr_t
|
||||
int numlocalattachments;
|
||||
int localattachmentindex;
|
||||
|
||||
uint8_t Unknown2[0x14];
|
||||
int numlocalnodes;
|
||||
int localnodeindex;
|
||||
int localnodenameindex;
|
||||
|
||||
int submeshLodsIndex;
|
||||
int numunknodes; // ???
|
||||
int nodedataindexindex; // index into an array of int sized offsets that read into the data for each node
|
||||
|
||||
uint8_t Unknown3[0x58];
|
||||
float fadeDist;
|
||||
float gatherSize;
|
||||
uint8_t Unknown4[0x4];
|
||||
int boneRemapInfoIndex;
|
||||
int boneRemapCount;
|
||||
int meshindex; // offset to model meshes
|
||||
|
||||
// all flex related model vars and structs are stripped in respawn source
|
||||
int deprecated_numflexcontrollers;
|
||||
int deprecated_flexcontrollerindex;
|
||||
|
||||
int deprecated_numflexrules;
|
||||
int deprecated_flexruleindex;
|
||||
|
||||
int numikchains;
|
||||
int ikchainindex;
|
||||
|
||||
// mesh panels for using rui on models, primarily for weapons
|
||||
int numruimeshes;
|
||||
int ruimeshindex;
|
||||
|
||||
int numlocalposeparameters;
|
||||
int localposeparamindex;
|
||||
|
||||
int surfacepropindex;
|
||||
|
||||
int keyvalueindex;
|
||||
int keyvaluesize;
|
||||
|
||||
int numlocalikautoplaylocks;
|
||||
int localikautoplaylockindex;
|
||||
|
||||
float mass;
|
||||
int contents;
|
||||
|
||||
// unused for packed models
|
||||
// technically still functional though I am unsure why you'd want to use it
|
||||
int numincludemodels;
|
||||
int includemodelindex;
|
||||
|
||||
int virtualModel; // size placeholder
|
||||
|
||||
int bonetablebynameindex;
|
||||
|
||||
// if STUDIOHDR_FLAGS_CONSTANT_DIRECTIONAL_LIGHT_DOT is set,
|
||||
// this value is used to calculate directional components of lighting
|
||||
// on static props
|
||||
byte constdirectionallightdot;
|
||||
|
||||
// set during load of mdl data to track *desired* lod configuration (not actual)
|
||||
// the *actual* clamped root lod is found in studiohwdata
|
||||
// this is stored here as a global store to ensure the staged loading matches the rendering
|
||||
byte rootLOD;
|
||||
|
||||
// set in the mdl data to specify that lod configuration should only allow first numAllowRootLODs
|
||||
// to be set as root LOD:
|
||||
// numAllowedRootLODs = 0 means no restriction, any lod can be set as root lod.
|
||||
// numAllowedRootLODs = N means that lod0 - lod(N-1) can be set as root lod, but not lodN or lower.
|
||||
byte numAllowedRootLODs;
|
||||
|
||||
byte unused;
|
||||
|
||||
float fadeDist; // fadeDistance
|
||||
float gatherSize; // gathersize
|
||||
|
||||
int deprecated_numflexcontrollerui;
|
||||
int deprecated_flexcontrolleruiindex;
|
||||
|
||||
float flVertAnimFixedPointScale; // to be verified
|
||||
int surfacepropLookup; // saved in the file
|
||||
|
||||
int sourceFilenameOffset; // doesn't actually need to be written pretty sure, only four bytes when not present.
|
||||
|
||||
int numsrcbonetransform;
|
||||
int srcbonetransformindex;
|
||||
|
||||
int illumpositionattachmentindex;
|
||||
|
||||
int linearboneindex;
|
||||
|
||||
// unsure what this is for but it exists for jigglbones
|
||||
int numprocbones;
|
||||
int procbonetableindex;
|
||||
int linearprocboneindex;
|
||||
|
||||
// depreciated as they are removed in 12.1
|
||||
int m_nBoneFlexDriverCount;
|
||||
int m_nBoneFlexDriverIndex;
|
||||
|
||||
int m_nPerTriAABBIndex;
|
||||
int m_nPerTriAABBNodeCount;
|
||||
int m_nPerTriAABBLeafCount;
|
||||
int m_nPerTriAABBVertCount;
|
||||
|
||||
// always "" or "Titan"
|
||||
int unkstringindex;
|
||||
|
||||
// this is now used for combined files in rpak, vtx, vvd, and vvc are all combined while vphy is separate.
|
||||
// the indexes are added to the offset in the rpak mdl_ header.
|
||||
// vphy isn't vphy, looks like a heavily modified vphy.
|
||||
int vtxindex; // VTX
|
||||
int vvdindex; // VVD / IDSV
|
||||
int vvcindex; // VVC / IDCV
|
||||
int vphyindex; // VPHY / IVPS
|
||||
|
||||
int vtxsize;
|
||||
int vvdsize;
|
||||
int vvcsize;
|
||||
int vphysize; // still used in models using vg
|
||||
|
||||
// unused in apex, gets cut in 12.1
|
||||
int unkmemberindex1;
|
||||
int numunkmember1;
|
||||
|
||||
// only seen on '_animated' suffixed models so far
|
||||
int unkcount3;
|
||||
int unkindex3;
|
||||
|
||||
// BVH4 size (?)
|
||||
Vector3D mins;
|
||||
Vector3D maxs; // seem to be the same as hull size
|
||||
|
||||
int unk3_v54[3];
|
||||
|
||||
int bvh4index; // bvh4 tree
|
||||
|
||||
short unk4_v54[2]; // same as unk3_v54_v121, 2nd might be base for other offsets?
|
||||
|
||||
// new in apex vertex weight file for verts that have more than three weights
|
||||
int vvwindex; // index will come last after other vertex files
|
||||
int vvwsize;
|
||||
};
|
||||
|
||||
#define BONE_CALCULATE_MASK 0x1F
|
||||
#define BONE_PHYSICALLY_SIMULATED 0x01 // bone is physically simulated when physics are active
|
||||
#define BONE_PHYSICS_PROCEDURAL 0x02 // procedural when physics is active
|
||||
#define BONE_ALWAYS_PROCEDURAL 0x04 // bone is always procedurally animated
|
||||
#define BONE_SCREEN_ALIGN_SPHERE 0x08 // bone aligns to the screen, not constrained in motion.
|
||||
#define BONE_SCREEN_ALIGN_CYLINDER 0x10 // bone aligns to the screen, constrained by it's own axis.
|
||||
|
||||
#define BONE_USED_BY_IKCHAIN 0x20 // bone is influenced by IK chains, added in V52 (Titanfall 1)
|
||||
|
||||
#define BONE_USED_MASK 0x0007FF00
|
||||
#define BONE_USED_BY_ANYTHING 0x0007FF00
|
||||
#define BONE_USED_BY_HITBOX 0x00000100 // bone (or child) is used by a hit box
|
||||
#define BONE_USED_BY_ATTACHMENT 0x00000200 // bone (or child) is used by an attachment point
|
||||
#define BONE_USED_BY_VERTEX_MASK 0x0003FC00
|
||||
#define BONE_USED_BY_VERTEX_LOD0 0x00000400 // bone (or child) is used by the toplevel model via skinned vertex
|
||||
#define BONE_USED_BY_VERTEX_LOD1 0x00000800
|
||||
#define BONE_USED_BY_VERTEX_LOD2 0x00001000
|
||||
#define BONE_USED_BY_VERTEX_LOD3 0x00002000
|
||||
#define BONE_USED_BY_VERTEX_LOD4 0x00004000
|
||||
#define BONE_USED_BY_VERTEX_LOD5 0x00008000
|
||||
#define BONE_USED_BY_VERTEX_LOD6 0x00010000
|
||||
#define BONE_USED_BY_VERTEX_LOD7 0x00020000
|
||||
|
||||
// no longer used in apex from what I can tell
|
||||
//#define BONE_USED_BY_BONE_MERGE 0x00040000 // bone is available for bone merge to occur against it
|
||||
|
||||
#define BONE_FLAG_UNK 0x00080000 // respawn flag
|
||||
|
||||
#define BONE_USED_BY_VERTEX_AT_LOD(lod) ( BONE_USED_BY_VERTEX_LOD0 << (lod) )
|
||||
#define BONE_USED_BY_ANYTHING_AT_LOD(lod) ( ( BONE_USED_BY_ANYTHING & ~BONE_USED_BY_VERTEX_MASK ) | BONE_USED_BY_VERTEX_AT_LOD(lod) )
|
||||
|
||||
#define BONE_TYPE_MASK 0x00F00000
|
||||
#define BONE_FIXED_ALIGNMENT 0x00100000 // bone can't spin 360 degrees, all interpolation is normalized around a fixed orientation
|
||||
|
||||
#define BONE_HAS_SAVEFRAME_POS 0x00200000 // Vector48
|
||||
// v48 -> v49 : BONE_HAS_SAVEFRAME_ROT -> BONE_HAS_SAVEFRAME_ROT64
|
||||
#define BONE_HAS_SAVEFRAME_ROT64 0x00400000 // Quaternion64
|
||||
#define BONE_HAS_SAVEFRAME_ROT32 0x00800000 // Quaternion32
|
||||
|
||||
struct mstudiobone_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
int parent; // parent bone
|
||||
int bonecontroller[6]; // bone controller index, -1 == none
|
||||
|
||||
// default values
|
||||
Vector3D pos;
|
||||
Quaternion quat;
|
||||
RadianEuler rot;
|
||||
Vector3D scale; // bone scale(?)
|
||||
|
||||
matrix3x4_t poseToBone;
|
||||
Quaternion qAlignment;
|
||||
|
||||
int flags;
|
||||
int proctype;
|
||||
int procindex; // procedural rule
|
||||
int physicsbone; // index into physically simulated bone
|
||||
|
||||
int surfacepropidx; // index into string tablefor property name
|
||||
|
||||
int contents; // See BSPFlags.h for the contents flags
|
||||
|
||||
int surfacepropLookup; // written on compile in v54
|
||||
|
||||
int unk;
|
||||
|
||||
int unkid; // physics index (?)
|
||||
};
|
||||
|
||||
struct mstudiojigglebone_t
|
||||
{
|
||||
byte flags; // looks to be.
|
||||
|
||||
unsigned char bone; // id of bone, might be single byte
|
||||
|
||||
short pad; // possibly unused
|
||||
|
||||
// general params
|
||||
float length; // how far from bone base, along bone, is tip
|
||||
float tipMass;
|
||||
|
||||
float unkfloat; // v54 adds an extra value here but otherwise the same
|
||||
// observed values are between 0-1
|
||||
|
||||
// flexible params
|
||||
float yawStiffness;
|
||||
float yawDamping;
|
||||
float pitchStiffness;
|
||||
float pitchDamping;
|
||||
float alongStiffness;
|
||||
float alongDamping;
|
||||
|
||||
// angle constraint
|
||||
float angleLimit; // maximum deflection of tip in radians
|
||||
|
||||
// yaw constraint
|
||||
float minYaw; // in radians
|
||||
float maxYaw; // in radians
|
||||
float yawFriction;
|
||||
float yawBounce;
|
||||
|
||||
// pitch constraint
|
||||
float minPitch; // in radians
|
||||
float maxPitch; // in radians
|
||||
float pitchFriction;
|
||||
float pitchBounce;
|
||||
|
||||
// base spring
|
||||
float baseMass;
|
||||
float baseStiffness;
|
||||
float baseDamping;
|
||||
float baseMinLeft;
|
||||
float baseMaxLeft;
|
||||
float baseLeftFriction;
|
||||
float baseMinUp;
|
||||
float baseMaxUp;
|
||||
float baseUpFriction;
|
||||
float baseMinForward;
|
||||
float baseMaxForward;
|
||||
float baseForwardFriction;
|
||||
};
|
||||
|
||||
struct mstudioattachment_t
|
||||
{
|
||||
int sznameindex;
|
||||
int flags;
|
||||
|
||||
int localbone; // parent bone
|
||||
|
||||
matrix3x4_t localmatrix; // attachment point
|
||||
};
|
||||
|
||||
struct mstudiohitboxset_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
int numhitboxes;
|
||||
int hitboxindex;
|
||||
};
|
||||
|
||||
struct mstudiobbox_t
|
||||
{
|
||||
int bone;
|
||||
int group; // intersection group
|
||||
|
||||
Vector3D bbmin; // bounding box
|
||||
Vector3D bbmax;
|
||||
|
||||
int szhitboxnameindex; // offset to the name of the hitbox.
|
||||
|
||||
int critoverride; // overrides the group to be a crit, 0 or 1. might be group override since group 1 is head.
|
||||
|
||||
int keyvalueindex; // used for keyvalues, most for titans.
|
||||
};
|
||||
|
||||
// sequence and autolayer flags
|
||||
#define STUDIO_LOOPING 0x0001 // ending frame should be the same as the starting frame
|
||||
#define STUDIO_SNAP 0x0002 // do not interpolate between previous animation and this one
|
||||
#define STUDIO_DELTA 0x0004 // this sequence "adds" to the base sequences, not slerp blends
|
||||
#define STUDIO_AUTOPLAY 0x0008 // temporary flag that forces the sequence to always play
|
||||
#define STUDIO_POST 0x0010 //
|
||||
#define STUDIO_ALLZEROS 0x0020 // this animation/sequence has no real animation data
|
||||
#define STUDIO_CYCLEPOSE 0x0080 // cycle index is taken from a pose parameter index
|
||||
#define STUDIO_REALTIME 0x0100 // cycle index is taken from a real-time clock, not the animations cycle index
|
||||
#define STUDIO_LOCAL 0x0200 // sequence has a local context sequence
|
||||
#define STUDIO_HIDDEN 0x0400 // don't show in default selection views
|
||||
#define STUDIO_OVERRIDE 0x0800 // a forward declared sequence (empty)
|
||||
#define STUDIO_ACTIVITY 0x1000 // Has been updated at runtime to activity index
|
||||
#define STUDIO_EVENT 0x2000 // Has been updated at runtime to event index on server
|
||||
#define STUDIO_WORLD 0x4000 // sequence blends in worldspace
|
||||
#define STUDIO_NOFORCELOOP 0x8000 // do not force the animation loop
|
||||
#define STUDIO_EVENT_CLIENT 0x10000 // Has been updated at runtime to event index on client
|
||||
|
||||
// new in respawn models
|
||||
// PREVIOUSLY: STUDIO_FRAMEANIM
|
||||
#define STUDIO_ANIM_UNK3 0x0040 // used on something that is clearly not a frame anim in v54
|
||||
// animseq/humans/class/heavy/mp_pilot_heavy_core/mp_pt_crypto_base_execution_heavy_victim.rseq
|
||||
#define STUDIO_ANIM_UNK 0x20000
|
||||
#define STUDIO_ANIM_UNK1 0x40000
|
||||
#define STUDIO_ANIM_UNK2 0x80000 // cherry blossom v53, levi in v54
|
||||
|
||||
struct mstudioanimdesc_t
|
||||
{
|
||||
int baseptr;
|
||||
|
||||
int sznameindex;
|
||||
|
||||
float fps; // frames per second
|
||||
int flags; // looping/non-looping flags
|
||||
|
||||
int numframes;
|
||||
|
||||
// piecewise movement
|
||||
int nummovements;
|
||||
int movementindex;
|
||||
|
||||
int framemovementindex; // new in v52
|
||||
|
||||
int animindex; // non-zero when anim data isn't in sections
|
||||
|
||||
int numikrules;
|
||||
int ikruleindex; // non-zero when IK data is stored in the mdl
|
||||
|
||||
int sectionindex;
|
||||
int sectionframes; // number of frames used in each fast lookup section, zero if not used
|
||||
};
|
||||
|
||||
struct mstudioanimsections_t
|
||||
{
|
||||
int animindex;
|
||||
};
|
||||
|
||||
// flags for the per bone array, in 4 bit sections (two sets of flags per byte)
|
||||
#define STUDIO_ANIM_POS 0x1 // animation has pos values
|
||||
#define STUDIO_ANIM_ROT 0x2 // animation has rot values
|
||||
#define STUDIO_ANIM_SCALE 0x4 // animation has scale values
|
||||
|
||||
// the actual animation values
|
||||
union mstudioanimvalue_t
|
||||
{
|
||||
struct
|
||||
{
|
||||
byte valid; // number of valid frames, or how many frames of data this value has
|
||||
byte total; // total number of frames, aka "values"
|
||||
} num;
|
||||
short value; // actual value, value*posscale
|
||||
};
|
||||
|
||||
struct mstudioanim_valueptr_t
|
||||
{
|
||||
char packedoffsets[4]; // packing unknown
|
||||
};
|
||||
|
||||
// flags for the actually per bone animation headers
|
||||
// "mstudioanim_valueptr_t" indicates it has a set of offsets into anim tracks
|
||||
#define STUDIO_ANIM_DELTA 0x01 // unverified, animation is additive
|
||||
#define STUDIO_ANIM_ANIMSCALE 0x01 // mstudioanim_valueptr_t
|
||||
#define STUDIO_ANIM_ANIMROT 0x02 // mstudioanim_valueptr_t
|
||||
#define STUDIO_ANIM_ANIMPOS 0x04 // mstudioanim_valueptr_t
|
||||
|
||||
struct mstudio_rle_anim_t_v54
|
||||
{
|
||||
|
||||
short size : 13; // total size of all animation data, not nextoffset because even the last one has it
|
||||
|
||||
short flags : 3;
|
||||
|
||||
// if flag 'STUDIO_ANIM_ANIMPOS' then these two
|
||||
float posscale;
|
||||
mstudioanim_valueptr_t pPosV;
|
||||
// else (static value, no actual animation)
|
||||
//Vector48 pPos; // type does not exist in R5SDK
|
||||
|
||||
|
||||
// if flag 'STUDIO_ANIM_ANIMROT' then
|
||||
mstudioanim_valueptr_t pRotV;
|
||||
// else (static value, no actual animation)
|
||||
//Quaternion64 pRot; // type does not exist in R5SDK
|
||||
|
||||
// if flag 'STUDIO_ANIM_ANIMSCALE' then
|
||||
mstudioanim_valueptr_t pScaleV;
|
||||
// else (static value, no actual animation)
|
||||
//Vector48 pScale; // type does not exist in R5SDK
|
||||
};
|
||||
|
||||
// apex ikerrors do the same thing as apex framemovements
|
||||
struct mstudiocompressedikerror_t
|
||||
{
|
||||
float scale[6]; // these values are the same as what posscale (if it was used) and rotscale are.
|
||||
int sectionframes; // frames per section, may not match animdesc
|
||||
};
|
||||
|
||||
struct mstudioikrule_t
|
||||
{
|
||||
int index;
|
||||
int type;
|
||||
int chain;
|
||||
int bone; // gets it from ikchain now pretty sure
|
||||
|
||||
int slot; // iktarget slot. Usually same as chain.
|
||||
float height;
|
||||
float radius;
|
||||
float floor;
|
||||
Vector3D pos;
|
||||
Quaternion q;
|
||||
|
||||
// apex does this oddly
|
||||
mstudiocompressedikerror_t compressedikerror;
|
||||
int compressedikerrorindex;
|
||||
|
||||
int iStart;
|
||||
int ikerrorindex;
|
||||
|
||||
float start; // beginning of influence
|
||||
float peak; // start of full influence
|
||||
float tail; // end of full influence
|
||||
float end; // end of all influence
|
||||
|
||||
float contact; // frame footstep makes ground concact
|
||||
float drop; // how far down the foot should drop when reaching for IK
|
||||
float top; // top of the foot box
|
||||
|
||||
int szattachmentindex; // name of world attachment
|
||||
|
||||
float endHeight; // new in v52
|
||||
};
|
||||
|
||||
// basically compressedikerrors and frame movements will have an array of offsets that leads into the traditional 'short offset' array, allowing it to have per section (if the anim uses sections) data
|
||||
struct mstudioframemovement_t
|
||||
{
|
||||
float scale[4]; // first three values are the same as what posscale (if it was used) is, fourth is similar to unkvector1.
|
||||
int sectionframes; // frames per section, may not match animdesc
|
||||
// may have more than one, even when not section anim
|
||||
};
|
||||
|
||||
struct mstudioseqdesc_t
|
||||
{
|
||||
int baseptr;
|
||||
|
||||
int szlabelindex;
|
||||
|
||||
int szactivitynameindex;
|
||||
|
||||
int flags; // looping/non-looping flags
|
||||
|
||||
int activity; // initialized at loadtime to game DLL values
|
||||
int actweight;
|
||||
|
||||
int numevents;
|
||||
int eventindex;
|
||||
|
||||
Vector3D bbmin; // per sequence bounding box
|
||||
Vector3D bbmax;
|
||||
|
||||
int numblends;
|
||||
|
||||
// Index into array of shorts which is groupsize[0] x groupsize[1] in length
|
||||
int animindexindex;
|
||||
|
||||
int movementindex; // [blend] float array for blended movement
|
||||
int groupsize[2];
|
||||
int paramindex[2]; // X, Y, Z, XR, YR, ZR
|
||||
float paramstart[2]; // local (0..1) starting value
|
||||
float paramend[2]; // local (0..1) ending value
|
||||
int paramparent;
|
||||
|
||||
float fadeintime; // ideal cross fate in time (0.2 default)
|
||||
float fadeouttime; // ideal cross fade out time (0.2 default)
|
||||
|
||||
int localentrynode; // transition node at entry
|
||||
int localexitnode; // transition node at exit
|
||||
int nodeflags; // transition rules
|
||||
|
||||
float entryphase; // used to match entry gait
|
||||
float exitphase; // used to match exit gait
|
||||
|
||||
float lastframe; // frame that should generation EndOfSequence
|
||||
|
||||
int nextseq; // auto advancing sequences
|
||||
int pose; // index of delta animation between end and nextseq
|
||||
|
||||
int numikrules;
|
||||
|
||||
int numautolayers;
|
||||
int autolayerindex;
|
||||
|
||||
int weightlistindex;
|
||||
|
||||
int posekeyindex;
|
||||
|
||||
int numiklocks;
|
||||
int iklockindex;
|
||||
|
||||
// Key values
|
||||
int keyvalueindex;
|
||||
int keyvaluesize;
|
||||
|
||||
int cycleposeindex; // index of pose parameter to use as cycle index
|
||||
|
||||
int activitymodifierindex;
|
||||
int numactivitymodifiers;
|
||||
|
||||
int ikResetMask; // new in v52
|
||||
int unk1;
|
||||
|
||||
// offset unkindex amount into an array of unkcount 'unkseqdata_t'
|
||||
int unkindex;
|
||||
int unkcount;
|
||||
};
|
||||
|
||||
struct mstudioautolayer_t
|
||||
{
|
||||
// this needs to have a guid descriptor in rpak
|
||||
__int64 guidSequence; // hashed aseq guid asset
|
||||
|
||||
short iSequence; // only used within an rmdl I would imagine
|
||||
short iPose;
|
||||
|
||||
int flags;
|
||||
float start; // beginning of influence
|
||||
float peak; // start of full influence
|
||||
float tail; // end of full influence
|
||||
float end; // end of all influence
|
||||
};
|
||||
|
||||
#define NEW_EVENT_STYLE ( 1 << 10 )
|
||||
|
||||
struct mstudioevent_t
|
||||
{
|
||||
float cycle;
|
||||
int event;
|
||||
int type; // this will be 0 if old style
|
||||
char options[256];
|
||||
|
||||
int szeventindex;
|
||||
};
|
||||
|
||||
// will align to four, so takes up eight bytes
|
||||
struct mstudioactivitymodifier_t_v52
|
||||
{
|
||||
int sznameindex;
|
||||
bool negate; // negate all other activity modifiers when this one is active?
|
||||
};
|
||||
|
||||
struct unkseqdata_t
|
||||
{
|
||||
// generally 0-1
|
||||
float unkfloat;
|
||||
|
||||
int unk;
|
||||
|
||||
// quaternion mayhaps
|
||||
float unkfloat1;
|
||||
float unkfloat2;
|
||||
float unkfloat3;
|
||||
float unkfloat4;
|
||||
};
|
||||
|
||||
struct mstudiobodyparts_t
|
||||
{
|
||||
int sznameindex;
|
||||
int nummodels;
|
||||
int base;
|
||||
int modelindex; // index into models array
|
||||
};
|
||||
|
||||
struct mstudiomodel_t
|
||||
{
|
||||
char name[64];
|
||||
|
||||
int unkindex2; // goes to bones sometimes, string index
|
||||
|
||||
int type;
|
||||
|
||||
float boundingradius;
|
||||
|
||||
int nummeshes;
|
||||
int meshindex;
|
||||
|
||||
// cache purposes
|
||||
int numvertices; // number of unique vertices/normals/texcoords
|
||||
int vertexindex; // vertex Vector
|
||||
int tangentsindex; // tangents Vector
|
||||
|
||||
int numattachments;
|
||||
int attachmentindex;
|
||||
|
||||
int deprecated_numeyeballs;
|
||||
int deprecated_eyeballindex;
|
||||
|
||||
int pad[4];
|
||||
|
||||
int colorindex; // vertex color
|
||||
// offset by colorindex number of bytes into vvc vertex colors
|
||||
int uv2index; // vertex second uv map
|
||||
// offset by uv2index number of bytes into vvc secondary uv map
|
||||
};
|
||||
|
||||
struct mstudio_meshvertexloddata_t
|
||||
{
|
||||
int modelvertexdataUnusedPad; // likely has none of the funny stuff because unused
|
||||
|
||||
int numLODVertexes[MAX_NUM_LODS]; // depreciated starting with rmdl v14(?)
|
||||
};
|
||||
|
||||
struct mstudiomesh_t
|
||||
{
|
||||
int material;
|
||||
|
||||
int modelindex;
|
||||
|
||||
int numvertices; // number of unique vertices/normals/texcoords
|
||||
int vertexoffset; // vertex mstudiovertex_t
|
||||
|
||||
// Access thin/fat mesh vertex data (only one will return a non-NULL result)
|
||||
|
||||
int deprecated_numflexes; // vertex animation
|
||||
int deprecated_flexindex;
|
||||
|
||||
// special codes for material operations
|
||||
int deprecated_materialtype;
|
||||
int deprecated_materialparam;
|
||||
|
||||
// a unique ordinal for this mesh
|
||||
int meshid;
|
||||
|
||||
Vector3D center;
|
||||
|
||||
mstudio_meshvertexloddata_t vertexloddata;
|
||||
|
||||
char unk[8]; // these are suposed to be filled on load, however this isn't true??
|
||||
};
|
||||
|
||||
struct mstudioposeparamdesc_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
int flags; // ????
|
||||
float start; // starting value
|
||||
float end; // ending value
|
||||
float loop; // looping range, 0 for no looping, 360 for rotations, etc.
|
||||
};
|
||||
|
||||
struct mstudioikchain_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
int linktype;
|
||||
int numlinks;
|
||||
int linkindex;
|
||||
|
||||
float unk; // no clue what this does tbh, tweaking it does nothing
|
||||
// default value: 0.707f
|
||||
};
|
||||
|
||||
struct mstudioiklink_t
|
||||
{
|
||||
int bone;
|
||||
Vector3D kneeDir; // no kneeDir in apex I think
|
||||
};
|
||||
|
||||
struct mstudiotexturedir_t
|
||||
{
|
||||
int sznameindex; // file name
|
||||
};
|
||||
|
||||
struct mstudiotexture_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
__int64 guid; // guid of the material it references
|
||||
};
|
||||
|
||||
struct mstudiorruiheader_t
|
||||
{
|
||||
int unk; // unsure, it doesn't line up
|
||||
int ruimeshindex; // offset to the actual rui mesh
|
||||
};
|
||||
|
||||
// vertex map for a face
|
||||
struct mstudioruivertmap_t
|
||||
{
|
||||
// order of vertices for triangles:
|
||||
// 1st tri: 1-3-2
|
||||
// 2nd tri: 4-2-3
|
||||
|
||||
// sometimes these are for a triangle instead of a quad, if that's the case then:
|
||||
// tri: 1-4-2
|
||||
// in this case the vert map will only cover 3 verts.
|
||||
|
||||
|
||||
// in v53 the first two are an array like such:
|
||||
// 1-3
|
||||
// while the third is the fourth vert.
|
||||
short vertid[3];
|
||||
};
|
||||
|
||||
struct mstudioruivert_t
|
||||
{
|
||||
int parent; // relative to global mesh parent, assumed
|
||||
|
||||
Vector3D vertexpos; // position of vertex relative to bone
|
||||
};
|
||||
|
||||
struct mstudioruimeshface_t
|
||||
{
|
||||
// this might be the same as the RPak UIMG UV struct.
|
||||
|
||||
// these values are for the two vertices that are not shared
|
||||
// for the other do as such:
|
||||
// vertex 2: take x from vextex 1 and y from vextex 4
|
||||
// vertex 2: take x from vextex 4 and y from vextex 1
|
||||
|
||||
// normal smd uv, seems to calculate for other values
|
||||
Vector2D faceuvmin; // vertex 1
|
||||
Vector2D faceuvmax; // vertex 4
|
||||
|
||||
// these could likely be calculated by doing math with a height/width scale
|
||||
// scale of the ui element
|
||||
Vector2D facescalemin; // vertex 1
|
||||
Vector2D facescalemax; // vertex 4
|
||||
};
|
||||
|
||||
struct mstudioruimesh_t
|
||||
{
|
||||
short numparents; // apparently you can have meshes parented to more than one bone(?)
|
||||
short numvertices; // number of verts
|
||||
short numfaces; // number of faces (quads)
|
||||
|
||||
short unk; // num uvs? or this is num faces and current num faces is num uvs
|
||||
|
||||
int parentindex; // this gets padding out front of it to even off the struct
|
||||
|
||||
int vertexindex; // offset into smd style vertex data
|
||||
// not actually fourth vert wtf??
|
||||
int fourthvertmapindex; // they now fully map the vertices for each quad
|
||||
int vertmapindex; // offsets into a vertex map for each quad
|
||||
int facedataindex; // offset into uv section
|
||||
};
|
||||
|
||||
struct mstudiosrcbonetransform_t
|
||||
{
|
||||
int sznameindex;
|
||||
|
||||
matrix3x4_t pretransform;
|
||||
matrix3x4_t posttransform;
|
||||
};
|
||||
|
||||
struct mstudiolinearbone_t
|
||||
{
|
||||
// they cut pos and rot scale, understandable since posscale was never used it tf|2 and they do anims different in apex
|
||||
int numbones;
|
||||
|
||||
int flagsindex;
|
||||
|
||||
int parentindex;
|
||||
|
||||
int posindex;
|
||||
|
||||
int quatindex;
|
||||
|
||||
int rotindex;
|
||||
|
||||
int posetoboneindex;
|
||||
};
|
||||
|
||||
struct BVH4Axis_t
|
||||
{
|
||||
short minChild0;
|
||||
short maxChild0;
|
||||
|
||||
short minChild1;
|
||||
short maxChild1;
|
||||
|
||||
short minChild2;
|
||||
short maxChild2;
|
||||
|
||||
short minChild3;
|
||||
short maxChild3;
|
||||
};
|
||||
|
||||
struct BVH4Node_t
|
||||
{
|
||||
BVH4Axis_t x;
|
||||
BVH4Axis_t y;
|
||||
BVH4Axis_t z;
|
||||
|
||||
int pad : 8;
|
||||
int index0 : 24;
|
||||
|
||||
int collision_mask : 8;
|
||||
int index1 : 24;
|
||||
|
||||
int child0_type : 4;
|
||||
int child1_type : 4;
|
||||
int index2 : 24;
|
||||
|
||||
int child2_type : 4;
|
||||
int child3_type : 4;
|
||||
int index3 : 24;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
// studio model data
|
||||
struct studiomeshdata_t
|
||||
{
|
||||
int m_NumGroup;
|
||||
int m_NumGroup;
|
||||
void* m_pMeshGroup; // studiomeshgroup_t
|
||||
};
|
||||
|
||||
@ -202,10 +1002,10 @@ struct studioloddata_t
|
||||
|
||||
struct studiohwdata_t
|
||||
{
|
||||
int m_RootLOD; // calced and clamped, nonzero for lod culling
|
||||
int m_NumLODs;
|
||||
studioloddata_t* m_pLODs;
|
||||
int m_NumStudioMeshes;
|
||||
int m_RootLOD; // calced and clamped, nonzero for lod culling
|
||||
int m_NumLODs;
|
||||
studioloddata_t* m_pLODs;
|
||||
int m_NumStudioMeshes;
|
||||
// !TODO:
|
||||
};
|
||||
|
||||
|
@ -238,6 +238,7 @@
|
||||
<ClInclude Include="..\materialsystem\cmaterialglue.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialsystem.h" />
|
||||
<ClInclude Include="..\mathlib\adler32.h" />
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h" />
|
||||
<ClInclude Include="..\mathlib\fbits.h" />
|
||||
<ClInclude Include="..\mathlib\color.h" />
|
||||
<ClInclude Include="..\mathlib\crc32.h" />
|
||||
|
@ -1850,6 +1850,9 @@
|
||||
<ClInclude Include="..\public\ipackedstore.h">
|
||||
<Filter>sdk\public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\codecs\bink\bink_impl.h">
|
||||
<Filter>sdk\codecs\bink</Filter>
|
||||
</ClInclude>
|
||||
|
@ -186,6 +186,7 @@
|
||||
<ClInclude Include="..\launcher\prx.h" />
|
||||
<ClInclude Include="..\materialsystem\cmaterialsystem.h" />
|
||||
<ClInclude Include="..\mathlib\adler32.h" />
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h" />
|
||||
<ClInclude Include="..\mathlib\fbits.h" />
|
||||
<ClInclude Include="..\mathlib\color.h" />
|
||||
<ClInclude Include="..\mathlib\crc32.h" />
|
||||
|
@ -1269,6 +1269,9 @@
|
||||
<ClInclude Include="..\public\ipackedstore.h">
|
||||
<Filter>sdk\public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\public\dt_send.h">
|
||||
<Filter>sdk\public</Filter>
|
||||
</ClInclude>
|
||||
|
@ -263,6 +263,7 @@
|
||||
<ClInclude Include="..\materialsystem\cshaderglue.h" />
|
||||
<ClInclude Include="..\mathlib\adler32.h" />
|
||||
<ClInclude Include="..\mathlib\almostequal.cpp" />
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h" />
|
||||
<ClInclude Include="..\mathlib\fbits.h" />
|
||||
<ClInclude Include="..\mathlib\color.h" />
|
||||
<ClInclude Include="..\mathlib\crc32.h" />
|
||||
|
@ -1946,6 +1946,9 @@
|
||||
<ClInclude Include="..\public\ipackedstore.h">
|
||||
<Filter>sdk\public</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\mathlib\compressed_vector.h">
|
||||
<Filter>sdk\mathlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\codecs\bink\bink_impl.h">
|
||||
<Filter>sdk\codecs\bink</Filter>
|
||||
</ClInclude>
|
||||
|
Loading…
x
Reference in New Issue
Block a user