PHYS: Difference between revisions

From wowdev
Jump to navigation Jump to search
mNo edit summary
Line 13: Line 13:
*** 1 capsule
*** 1 capsule
*** 1 sphere
*** 1 sphere
*** 1 polytope (version 3+)
*** 1 (tree mesh [*])
*** 1 (tree mesh [*])
*** 1 (height field [*])
*** 1 (height field [*])
Line 19: Line 20:
** 1 spherical
** 1 spherical
** 1 shoulder
** 1 shoulder
** 1 (mouse [*])
** 1 distance (version 2+)
** 1 distance (version 2+)
** 1 revolute (version 2+)
** 1 revolute (version 2+)
** 1 prismatic (version 2+)
** 1 prismatic (version 2+)
** 1 (mouse [*])
[*] supported by domino, but not available in wow
[*] supported by domino, but not available in wow


Line 38: Line 39:


Loading is partially backwards compatible and fills up with default values if loading older versions. Since version 2* it no longer reuses chunk identifiers but has separate identifiers for versions (BDY2, SHP2, WLJ2). It still is able to parse old ones, and fills up with defaults.
Loading is partially backwards compatible and fills up with default values if loading older versions. Since version 2* it no longer reuses chunk identifiers but has separate identifiers for versions (BDY2, SHP2, WLJ2). It still is able to parse old ones, and fills up with defaults.
=PHYV (version 1+)=
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20773}}
struct
{
  float _unk[0x6];
} phyv[];
=PHYT (version 1+)=
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20773}}
uint32_t phyt; // default: 0


=BODY, BDY2, BDY3, BDY4=
=BODY, BDY2, BDY3, BDY4=
Line 88: Line 100:
  } shapes[];
  } shapes[];


=BOXS=
=shapes=
==BOXS==
  struct BOXSEntry
  struct BOXSEntry
  {
  {
Line 95: Line 108:
  } boxShapes[];
  } boxShapes[];


=CAPS=
==CAPS==
  struct CAPSEntry
  struct CAPSEntry
  {
  {
Line 103: Line 116:
  } capsuleShapes[];
  } capsuleShapes[];


=SPHS=
==SPHS==
  struct SPHSEntry
  struct SPHSEntry
  {
  {
Line 110: Line 123:
  } sphereShapes[];
  } sphereShapes[];


=JOIN=
==PLYT (version 3+)==
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.3.21287}}
This chunk does being an array of entries on it's own. Because why not.
struct {
/*0x00*/  uint32_t count;
   
  struct {
  /*0x00*/  uint32_t unk_00; // Default 8
  /*0x04*/  char unk_04[0xC];
  /*0x10*/  uint32_t unk_10; // Default 6
  /*0x14*/  char unk_14[0x14];
  /*0x28*/  uint32_t unk_28; // Default 24
  /*0x2c*/  char unk_2C[0xC];
  /*0x38*/  float unk_38[6];
  } entries[count];
 
  struct {
  /*0x00*/  char unk_00[0x126];
  } entries2[count];
} polytopeShapes;
 
=joints=
==JOIN==
  struct JOINEntry
  struct JOINEntry
  {
  {
Line 131: Line 166:
  } joints[];
  } joints[];


=WELJ, WLJ2=
==WELJ, WLJ2==
  struct
  struct
  {
  {
Line 144: Line 179:
  } weldJoints[];
  } weldJoints[];


=SPHJ=
==SPHJ==
  struct SPHJEntry
  struct SPHJEntry
  {
  {
Line 152: Line 187:
  } sphericalJointEntries[];
  } sphericalJointEntries[];


=SHOJ=
==SHOJ==
Note that even though this chunk is handled differently since version 2, it does not have a version 2* chunk name.
Note that even though this chunk is handled differently since version 2, it does not have a version 2* chunk name.
  struct SHOJEntry
  struct SHOJEntry
Line 166: Line 201:
  } shoulderJoints[];
  } shoulderJoints[];


=PHYV (version 1+)=
==PRSJ (version 2+)==
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20773}}
struct
{
  float _unk[0x6];
} phyv[];
 
=PHYT (version 1+)=
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20773}}
uint32_t phyt; // default: 0
 
=PRSJ (version 2+)=
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
  struct
  struct
Line 184: Line 208:
  } prismaticJoints[];
  } prismaticJoints[];


=REVJ (version 2+)=
==REVJ (version 2+)==
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
  struct
  struct
Line 191: Line 215:
  } revoluteJoints[];
  } revoluteJoints[];


=DSTJ (version 2+)=
==DSTJ (version 2+)==
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.1.20979}}
  struct
  struct
Line 197: Line 221:
   char _unk[0x1c];
   char _unk[0x1c];
  } distanceJoints[];
  } distanceJoints[];
=PLYT (version 3+)=
{{Template:SectionBox/VersionRange|min_expansionlevel=7|min_build=7.0.3.21287}}
This chunk does being an array of entries on it's own. Because why not.
struct {
/*0x00*/  uint32_t count;
   
  struct {
  /*0x00*/  uint32_t unk_00; // Default 8
  /*0x04*/  char unk_04[0xC];
  /*0x10*/  uint32_t unk_10; // Default 6
  /*0x14*/  char unk_14[0x14];
  /*0x28*/  uint32_t unk_28; // Default 24
  /*0x2c*/  char unk_2C[0xC];
  /*0x38*/  float unk_38[6];
  } entries[count];
 
  struct {
  /*0x00*/  char unk_00[0x126];
  } entries2[count];
} polytopes;


[[Category:Format]]
[[Category:Format]]

Revision as of 03:31, 2 September 2017

This section only applies to versions ≥ Mists.

.phys files are chunked. The files are used by Blizzard's Domino physics engine which got added to WoW in the fourth expansion (MoP). In build Mists (5.0.1.15464), there is one .phys file "item/objectcomponents/waist/buckle_panstart_a_01.phys". .phys files are an extension to M2s. The M2 requests a .phys file to be loaded by having GlobalModelFlags & 0x20 set.

The main PHYS chunk is followed by an unordered sequence of unique chunks of the other types.

// vec*: * floats
// mat*x*: * times * floats.
  • 1 phys
  • n body
    • n shapes
      • 1 box
      • 1 capsule
      • 1 sphere
      • 1 polytope (version 3+)
      • 1 (tree mesh [*])
      • 1 (height field [*])
  • n joints
    • 1 weld
    • 1 spherical
    • 1 shoulder
    • 1 distance (version 2+)
    • 1 revolute (version 2+)
    • 1 prismatic (version 2+)
    • 1 (mouse [*])

[*] supported by domino, but not available in wow

One body is connected to one bone. Bodies are connected via joints. A joint is of type weld, spherical or shoulder. A body is constructed out of shapes. A shape is a box, capsule or sphere.

PHYS

 short version;
 // since Mists (5.0.1.15???): 0
 // since Legion (7.0.1.20773): 1
 // since Legion (7.0.1.20979): 2
 // since Legion (7.0.1.21063): 2* -- not a different version in file or client parsing, but changed semantics and chunk names
 // since Legion (7.0.3.21287): 3
 // since Legion (7.0.3.21846): 4
 // since Legion (7.3.0.24500): 5 -- this version does not change anything in parsing. it likely handles some existing field differently

Loading is partially backwards compatible and fills up with default values if loading older versions. Since version 2* it no longer reuses chunk identifiers but has separate identifiers for versions (BDY2, SHP2, WLJ2). It still is able to parse old ones, and fills up with defaults.

PHYV (version 1+)

This section only applies to versions ≥ Legion (7.0.1.20773).
struct
{
  float _unk[0x6];
} phyv[];

PHYT (version 1+)

This section only applies to versions ≥ Legion (7.0.1.20773).
uint32_t phyt; // default: 0

BODY, BDY2, BDY3, BDY4

struct
{
/*0x00*/  unsigned short type; // maps to dmBodyDef type enum. 0 -> 1, 1 -> 0 = dm_dynamicBody, * -> 2. Only one should be of type 0 (root). possibly only 0 and 1.
/*0x02*/  char PADDING_a[2];
/*0x04*/  vec3 position;
/*0x10*/  unsigned short modelBoneIndex;
/*0x12*/  char PADDING_b[2];
/*0x14*/  int shapes_base; // starting at shapes[shapes_base]
/*0x18*/  int shapes_count; // shapes_count shapes are in this body.
#if version >= 2 // BDY2
/*0x1c*/  float _x1c; // default 1.0
#endif
#if version >= 3 // BDY3
/*0x20*/  char _x20[4]; // default 0x00000000
/*0x24*/  char _x24[4]; // default 0x00000000
/*0x28*/  float _x28; // default 0.89999998
#endif
#if version >= 4 // BDY4
/*0x2c*/  char _x2c[0x04]; // default 0x00000000
#endif
} bodies[];

SHAP, SHP2

struct
{
/*0x00*/  short shapeType;
  enum
  {
    box = 0,      // BOXS
    capsule = 1,  // CAPS
    sphere = 2,   // SPHS
#if version >= 3
    polytope = 3, // PLYT
#endif
  };
/*0x02*/  short shapeIndex; // into the corresponding chunk
/*0x04*/  char unk[4];
/*0x08*/  float friction;
/*0x0c*/  float restitution;
/*0x10*/  float density;
#if version >= 2 // SHP2
/*0x14*/  uint32_t _x14; // default 0
/*0x18*/  float _x18; // default 1.0
/*0x1c*/  uint16_t _x1c; // default 0
/*0x1e*/  uint16_t _x1e; // no default, padding?
#endif
} shapes[];

shapes

BOXS

struct BOXSEntry
{
/*0x00*/  mat3x4 a;
/*0x30*/  vec3 c;
} boxShapes[];

CAPS

struct CAPSEntry
{
  vec3 localPosition1;
  vec3 localPosition2;
  float radius;
} capsuleShapes[];

SPHS

struct SPHSEntry
{
  vec3 localPosition;
  float radius;
} sphereShapes[];

PLYT (version 3+)

This section only applies to versions ≥ Legion (7.0.3.21287).

This chunk does being an array of entries on it's own. Because why not.

struct {
/*0x00*/  uint32_t count;
    
  struct {
  /*0x00*/  uint32_t unk_00; // Default 8
  /*0x04*/  char unk_04[0xC];
  /*0x10*/  uint32_t unk_10; // Default 6
  /*0x14*/  char unk_14[0x14];
  /*0x28*/  uint32_t unk_28; // Default 24
  /*0x2c*/  char unk_2C[0xC];
  /*0x38*/  float unk_38[6];
  } entries[count];
  
  struct {
  /*0x00*/  char unk_00[0x126];
  } entries2[count];
} polytopeShapes;

joints

JOIN

struct JOINEntry
{
  unsigned int bodyAIdx;
  unsigned int bodyBIdx;
  char unk[4];
  enum
  {
    sphericalJoint = 0,
    shoulderJoint = 1,
    weldJoint = 2,
#if version >= 2
    revoluteJoint = 3,
    prismaticJoint = 4,
    distanceJoint = 5,
#endif
  };
  short jointType;
  short jointId; // reference into the corresponding chunk entries.
} joints[];

WELJ, WLJ2

struct
{
/*0x00*/  mat3x4 frameA;
/*0x30*/  mat3x4 frameB;
/*0x60*/  float frequency;
/*0x64*/  float dampingRatio;
#if version >= 2 // WLJ2
/*0x68*/  uint32_t _x68; // default 0
/*0x6c*/  uint32_t _x6c; // default 0
#endif
} weldJoints[];

SPHJ

struct SPHJEntry
{
  vec3 anchorA;
  vec3 anchorB;
  float frictionTorque;
} sphericalJointEntries[];

SHOJ

Note that even though this chunk is handled differently since version 2, it does not have a version 2* chunk name.

struct SHOJEntry
{
  mat3x4 frameA;
  mat3x4 frameB;
  float lowerTwistAngle;
  float upperTwistAngle;
  float coneAngle;
#if version >= 2
  char _x6c[8]; // NO BACKWARDS COMPATIBILITY as of Legion (7.0.1.20979) and Legion (7.3.0.24931)! client always assumes new size!
#endif
} shoulderJoints[];

PRSJ (version 2+)

This section only applies to versions ≥ Legion (7.0.1.20979).
struct
{
  char _unk[0x78];
} prismaticJoints[];

REVJ (version 2+)

This section only applies to versions ≥ Legion (7.0.1.20979).
struct
{
  char _unk[0x70];
} revoluteJoints[];

DSTJ (version 2+)

This section only applies to versions ≥ Legion (7.0.1.20979).
struct
{
  char _unk[0x1c];
} distanceJoints[];