Models

Current development progress
Appearance files store 3d data in the game. They contain information on a specific set item, including all the different ways it can look (the character models for example contain all the different possible transformations of a given class, like the character select version or the Wizard's arkhon version), bone structure, vertices, triangles, material references, hardpoints, vertex blend information, some sort of collision information, ragdoll constraints and possibly more.

Animations are stored in .ani files, these are collected into .ans animation sets and the models and their animations are paired in .acr actor files.

Structural analysis of the format seems to be mostly complete, now the data contained in the different sections needs to be interpreted properly.

While the format is being researched this page will be updated with a 010 editor binary template that can be used to parse the files to our best knowledge and can act as a template for any parser/exporter tools.

//--   //--- 010 Editor v3.2.1 Binary Template //   // File: Diablo 3 .app // Purpose: Parsing Diablo 3 appearance files //--   struct SerializeData {       int Offset ; int Size; };   int goto(SerializeData &d) {       if (!d.Size) return 0; local int x=FTell; FSeek(d.Offset+16); return x;   } struct SNOName {       int SNOGroup; int SNOHandle; };   struct Vector3D {       float x,y,z; };   struct Quaternion {       float w;        Vector3D p;    }; struct Sphere {       Vector3D Position; float Radius; };   struct PRSTransform {       Quaternion q;        Vector3D v;        float s;    }; struct PRTransform {       Quaternion q;        Vector3D v;    }; struct AABB {       Vector3D v0,v1; };   struct IVector2D {       int Field0; int Field1; };   struct RGBAColor {       unsigned char r,g,b,a; };   struct RGBAColorValue {       float r,g,b,a; };   struct Matrix4x4 {       float m[16]; };   struct snoHeader {       int DEADBEEF; int snoType; int unk1 ,unk2 ; int snoID; //0 int unk3 ,unk4 ; };                                              struct LookAtData {       int f0; char Name[64]; float Angles[4]; float AngularVelocity; float f1; };   struct dmPlane {       Vector3D v0; float f0; };   struct dmSubEdge {       char b0,b1,b2,b3; };   struct PolytopeData {       local int x;        int pad0[8] ; Vector3D v0; int nVertices ; int nPlanes ; int nSubEdges ; float f0,f1; SerializeData serVertices ; if (x=goto(serVertices)) {           struct {               Vector3D Vertex[nVertices] ; } Vertices; FSeek(x); }       SerializeData serPlanes ; if (x=goto(serPlanes)) {           struct {               dmPlane Plane[nPlanes] ; } Planes; FSeek(x); }       SerializeData serSubEdges ; if (x=goto(serSubEdges)) {           struct {               dmSubEdge SubEdge[nSubEdges] ; } SubEdges; FSeek(x); }       SerializeData serFaceSubEdges ; if (x=goto(serFaceSubEdges)) {           unsigned char FaceSubEdges[serFaceSubEdges.Size] ; FSeek(x); }   };    struct CollisionShape {       local int x;        int i0,i1,i2,i3; float f0,f1,f2; SerializeData serPolytope ; if (x=goto(serPolytope)) {           PolytopeData Polytope[serPolytope.Size/96] ; FSeek(x); }       int pad0 ; Vector3D v0,v1; float f3; };   struct ConstraintParameters {       char str0[64]; int i0,i1,i2,i3; PRTransform p0; Vector3D v0; PRTransform p1,p2; float f0,f1,f2,f3,f4,f5,f6,f7,f8; char str1[64]; };   struct BoneStructure {       local int x;        char Name[64]; int ParentID; AABB aabb; Sphere wsBounds; PRSTransform t1,t2,t3; int nCollShapeCount ; SerializeData serShapes ; if (x=goto(serShapes)) {              CollisionShape CollShape[nCollShapeCount] ; FSeek(x); }       int pad0 ; SerializeData serConstraints ; if (x=goto(serConstraints)) {           ConstraintParameters Constraint[serConstraints.Size/276] ; FSeek(x); }       int pad1 ; int snoParticleSystem; };   struct BonePulseData {       char Name[64]; float f0,f1; float Angle; };   struct FatVertex {       Vector3D Position; RGBAColor c0; RGBAColor c1[2]; RGBAColor c2[2]; RGBAColor c3; RGBAColor c4; unsigned short w0; unsigned short pad0 ; };   struct Influence {       int BoneId; float Strength; };   struct VertInfluences {       Influence Influences[3]; };   struct ClothVertex {       Vector3D v0,v1,v2,v3; float f0; int i0,i1,i2,i3; Vector3D v4; int i4; };   struct ClothFace {       Vector3D v0; float f0; int i0,i1,i2; };   struct ClothStaple {       int i0; int a0[3]; float a1[3]; };   struct ClothConstraint {       int i0,i1; float f0,f1,f2,f3; };   struct ClothStructure {   local int x;        int nVertexCount ; SerializeData serVertices ; int pad0 ; if (x=goto(serVertices)) {           struct {               ClothVertex Vertex[nVertexCount] ; } ClothVertices; FSeek(x); }       int nFaceCount ; SerializeData serFaces ; int pad1 ; if (x=goto(serFaces)) {           struct {               ClothFace Face[nFaceCount] ; } ClothFaces; FSeek(x); }       int nStapleCount ; SerializeData serStaples ; int pad2 ; if (x=goto(serStaples)) {           struct {               ClothStaple Staple[nStapleCount] ; } ClothStaples; FSeek(x); }       int nDistanceConstraints ; SerializeData serDistanceConstraints ; int pad3 ; if (x=goto(serDistanceConstraints)) {           struct {               ClothConstraint Constraint[nDistanceConstraints] ; } DistanceConstraints; FSeek(x); }       int nBendingConstraints ; SerializeData serBendingConstraints ; int pad4 ; if (x=goto(serBendingConstraints)) {           struct {               ClothConstraint Constraint[nBendingConstraints] ; } BendingConstraints; FSeek(x); }       int i5; float f0; };   struct SubObject {       local int x;        int i0; int nVertCount ; SerializeData serVertList ; if (x=goto(serVertList)) {           FatVertex Vertex[nVertCount] ; FSeek(x); }       int pad0 ; SerializeData serInfluenceList ; if (x=goto(serInfluenceList)) {           VertInfluences Influences[nVertCount] ; FSeek(x); }           int pad1 ; int nIndexCount ; SerializeData serIndexList ; if (x=goto(serIndexList)) {           unsigned short Indices[nIndexCount] ; FSeek(x); }       int pad2 ; SerializeData serClothStructure ; if (x=goto(serClothStructure)) {           ClothStructure ClothStruct[serClothStructure.Size/88] ; FSeek(x); }       int pad3 ; int snoSurface; int i1; float f0; char c0[128]; char c1[128]; AABB aabbBounds; int nShapeCount; SerializeData serShapes; if (x=goto(serShapes)) {           CollisionShape CollShape[nSHapeCount] ; FSeek(x); }       int pad4[2] ; };   struct GeoSet {       local int x;        int nSubObjectCount ; SerializeData serSubObjects ; if (x=goto(serSubObjects)) {           SubObject SubObj[nSubObjectCount] ; FSeek(x); }       int pad0[3] ; };   struct HardPoint {       char Name[64]; int ParentBone; PRTransform p;   }; struct CollisionCapsule {       float f0,f1; HardPoint h;   }; struct OctreeCube {       Vector3D v0; float f0; };   struct OctreeNode {       OctreeCube c0; int a0[8]; };   struct OctreeLeaf {       OctreeCube c0; int i0,i1; };   struct OctreePrimitive {       int i0,i1; };   struct Octree {       local int x;        int nMaxNodes; int nMaxLeaves; int nMaxPrimitives; int nNodeCount ; int nLeafCount ; int nPrimitiveCount ; SerializeData serNodes ; if (x=goto(serNodes)) {           struct {               OctreeNode Node[nNodeCount] ; } Nodes; FSeek(x); }       int pad0[2] ; SerializeData serLeaves ; if (x=goto(serLeaves)) {           struct {               OctreeLeaf Node[nLeafCount] ; } Leaves; FSeek(x); }       int pad1[2] ; SerializeData serPrimitives ; if (x=goto(serPrimitives)) {           struct {               OctreePrimitive Node[nPrimitiveCount] ; } Primitives; FSeek(x); }       int pad2[2] ; };   struct Material {       RGBAColorValue v0,v1,v2,v3; float f0; int i0; };   struct FrameAnim {       int i0; float v0,v1; int i1,i2; };   struct TexAnimParams {       int i0; Matrix4x4 m0; float f0; float v0,f1; float v1; float a0; float av0; float a1; float f2; float v2,f3; float v3; float a2; float av1; float a3,a4; float av3,av4; int i0,i1,i2,i3; FrameAnim fa0; int i4; };   struct MaterialTexture {       int snoTex; TexAnimParams tap; };   struct MaterialTextureEntry {       int i0; MaterialTexture mt; };   struct UberMaterial {       local int x;        int snoShaderMap; Material Mat; SerializeData serMatTexList ; if (x=goto(serMatTexList)) {           MaterialTextureEntry Tex[serMatTexList.Size/184] ; FSeek(x); }       int pad0[5] ; };   struct SubObjectAppearance {       local int x;        int i0; int snoCloth; SerializeData TagMap; if (x=goto(TagMap)) {           char tagmap[TagMap.Size] ; FSeek(x); }       int pad0[2] ; UberMaterial Mat; int snoMaterial; int pad1[29] ; };   struct AppearanceMaterial {       local int x;        char Name[128]; SerializeData serSOAs ; if (x=goto(serSOAs)) {           SubObjectAppearance SOA[serSOAs.Size/248] ; FSeek(x); }       int pad0 ; };   struct AppearanceLook {       char Name[64]; };   struct StaticLight {       int fCastsShadows; int eType; Vector3D wp,wv; float wdRadius; int eAttenType; float a[3]; float flAttenNearStart; float flAttenNearEnd; float flAttenFarStart; float flAttenFarEnd; int aHotspot; int aFalloff; RGBAColorValue rgbaValDiffuse; };   struct {       local int x;        snoHeader Header; unsigned int i0; unsigned int dwFlags ; int nBoneCount ; SerializeData serBoneStructure ; if (x=goto(serBoneStructure)) {           struct {               BoneStructure Bone[nBoneCount]; } Bones; FSeek(x); }       int pad0[2] ; LookAtData ldLookAtData; int nBonePulseCount ; int pad1[2] ; SerializeData serBonePulses ; if (x=goto(serBonePulses)) {           struct {               BonePulseData BonePulse[nBonePulseCount] ; } BonePulses; FSeek(x); }       GeoSet GeoSets[2]; Sphere s0; int nCollisionCapsuleCount ; SerializeData serCollisionCapsules ; if (x=goto(serCollisionCapsules)) {           struct {               CollisionCapsule CollCaps[nCollisionCapsuleCount] ; } CollisionCapsules; FSeek(x); }       int pad3[3] ; int nHardPointCount ; SerializeData serHardPoints ; if (x=goto(serHardPoints)) {           struct {               HardPoint HP[nHardPointCount] ; } HardPoints; FSeek(x); }       int pad4[3] ; Vector3D v0; unsigned int pad5 ; Octree tOctreeVisualMesh; AABB aabbBounds; int nLoopConstraintCount ; SerializeData serLoopConstraints ; if (x=goto(serLoopConstraints)) {           struct {               ConstraintParameters Constraint[nLoopConstraintCount] ; } LoopConstraints; FSeek(x); }       unsigned int pad6[3] ; int uRagdollDegrade; unsigned int pad7[3] ;; char c0[256] ; char c1[256] ; char c2[256] ; char c3[256] ; int i2; float f0; int i3; int pad8 ; int nLooks ,nMaterials ; SerializeData serAppearanceMaterials ; if (x=goto(serAppearanceMaterials)) {           AppearanceMaterial Materials[nMaterials]; FSeek(x); }       int pad9[2] ; SerializeData serAppearanceLooks ; if (x=goto(serAppearanceLooks)) {           AppearanceLook Looks[nLooks] ; FSeek(x); }       int pad10[2] ; int nStaticLightCount ; SerializeData serStaticLights ; if (x=goto(serStaticLights)) {           StaticLight Lights[nStaticLightCount] ; FSeek(x); }       int pad11[3] ; int i6; int times[5]; int i7; float f1; int i8,i9; int64 i10; int i11; int pad12 ; } snoAPPEARANCE ;