/* * MOC3 Format Specification, 2.1b * * Copyright (C) 2023 The OpenL2D Project Developers * * This software is free software: you can redistribute and/or modify it * under the terms of the Free Development Public License version 1.0-US * as published at <https://freedevproject.org/fdpl-1.0-us>. * * This software is provided as is, without any warranty. See the license * for more details. */ /* * This pattern has not been fully verified for correctness. Use at your * own risk. * * == Change Log == * 2.0 - Initial implementation as a pattern. * 2.0a - Support for latest MOC3 features (experimental). * 2.0b - Experimental support for verification. * 2.0c - New FIXUP attribute to support more MOC3 files. * 2.1 - Support for version 5 MOC3 features. * 2.1a - Correction to version 5 structures. * 2.1b - Correction to field order in BlendShapeKeyformBindingOffsets structure. */ #pragma MIME application/x-moc3-data // MOC3 files can contain large arrays of coordinates. // Do NOT increase pattern_limit; that's usually a sign the data structure // should be marked [[static]] instead. #ifndef MOC3_NO_SET_ARRAY_LIMIT #pragma array_limit 1048576 #endif #ifndef NO_BIG_ENDIAN_SUPPORT // Experimental big endian MOC3 support. Setting the following to // true will ensure that MOC3 files are always read as big endian, // otherwise endianness will be autodetected. bool AlwaysReadAsBigEndian in; #endif #ifdef NO_BIG_ENDIAN_SUPPORT #pragma endian little #endif // If you are interested in modifying Runtime Space fields, set the // following to true. bool ShowRuntimeSpaceFields in; using void = u8; using bool32 = u32; #ifndef NO_OFFSET_FIXUP #include <std/mem.pat> #include <std/io.pat> // Apparently some empty fields can point to EOF. // I also think this is bad design (and there's no way to support // this without weaking verification a bit), but here it is. fn fixOffset(u32 offset) { if (offset == std::mem::size()) { return -offset; } return 0; }; fn identity(auto value) { return value; }; // If you want to disable these fixups with a toggle, set the // following to true. bool DisableOffsetFixUps in; #define FIXUP pointer_base(DisableOffsetFixUps ? "identity" : "fixOffset") #endif #ifdef NO_OFFSET_FIXUP #define FIXUP dummy #endif enum Version : u8 { V3_00_00 = 1, V3_03_00 = 2, V4_00_00 = 3, V4_02_00 = 4, V5_00_00 = 5, } [[comment("MOC3 version")]]; struct Header { char magic[4] [[name("Magic"), comment("MOC3 magic string: 'MOC3'")]]; Version version [[name("Version"), comment("MOC3 version")]]; bool isBigEndian [[name("Big Endian"), comment("MOC3 endianness")]]; padding[58]; } [[static]]; bitfield CanvasFlags { reverseYCoordinate : 1; reserved : 7; }; struct CanvasInfo { float pixelsPerUnit [[name("Pixels Per Unit")]]; float originX [[name("X Origin")]]; float originY [[name("Y Origin")]]; float canvasWidth [[name("Width")]]; float canvasHeight [[name("Height")]]; CanvasFlags canvasFlags [[name("Flags")]]; padding[43]; } [[static]]; struct CountInfoTable<auto V> { if (V >= Version::V5_00_00) padding[256] [[no_unique_address]]; else padding[128] [[no_unique_address]]; u32 parts [[name("Parts")]]; u32 deformers [[name("Deformers")]]; u32 warpDeformers [[name("Warp Deformers")]]; u32 rotationDeformers [[name("Rotation Deformers")]]; u32 artMeshes [[name("Art Meshes")]]; u32 parameters [[name("Parameters")]]; u32 partKeyforms [[name("Part Keyforms")]]; u32 warpDeformerKeyforms [[name("Warp Deformer Keyforms")]]; u32 rotationDeformerKeyforms [[name("Rotation Deformer Keyforms")]]; u32 artMeshKeyforms [[name("Art Mesh Keyforms")]]; u32 keyformPositions [[name("Keyform Positions")]]; u32 parameterBindingIndices [[name("Parameter Binding Indices")]]; u32 keyformBindings [[name("Keyform Bindings")]]; u32 parameterBindings [[name("Parameter Bindings")]]; u32 keys [[name("Keys")]]; u32 uvs [[name("UVs")]]; u32 positionIndices [[name("Position Indices")]]; u32 drawableMasks [[name("Drawable Masks")]]; u32 drawOrderGroups [[name("Draw Order Groups")]]; u32 drawOrderGroupObjects [[name("Draw Order Group Objects")]]; u32 glue [[name("Glue")]]; u32 glueInfo [[name("Glue Info")]]; u32 glueKeyforms [[name("Glue Keyforms")]]; if (V >= Version::V4_02_00) { u32 keyformMultiplyColors [[name("Keyform Colors (Multiply)")]]; u32 keyformScreenColors [[hidden, name("Keyform Colors (Screen)")]]; u32 blendShapeParameterBindings [[name("Blend Shape Parameter Bindings")]]; u32 blendShapeKeyformBindings [[name("Blend Shape Keyform Bindings")]]; u32 blendShapesWarpDeformers [[name("Blend Shapes (Warp Deformers)")]]; u32 blendShapesArtMeshes [[hidden, name("Blend Shapes (Art Meshes)")]]; u32 blendShapeConstraintIndices [[name("Blend Shape Constraint Indices")]]; u32 blendShapeConstraints [[name("Blend Shape Constraints")]]; u32 blendShapeConstraintValues [[name("Blend Shape Constraint Values")]]; } if (V >= Version::V5_00_00) { u32 blendShapesParts [[name("Blend Shapes (Parts)")]]; u32 blendShapesRotationDeformers [[name("Blend Shapes (Rotation Deformers)")]]; u32 blendShapesGlue [[name("Blend Shapes (Glue)")]]; } }; union ID { padding[64]; char value[64]; } [[static]]; struct UV { float u, v; } [[static]]; struct XY { float x, y; } [[static]]; struct PartOffsets<auto N> { if (ShowRuntimeSpaceFields) u32 runtimeSpace0 [[name("Runtime Space 0 Offset")]]; else void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; ID* ids[N] : u32 [[name("IDs"), FIXUP]]; s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBeginIndices[N] : u32 [[name("Keyform Sources Begin Indices"), FIXUP]]; s32* keyformSourcesCounts[N] : u32 [[name("Keyform Sources Counts"), FIXUP]]; bool32* isVisible[N] : u32 [[name("Visible"), FIXUP]]; bool32* isEnabled[N] : u32 [[name("Enabled"), FIXUP]]; s32* parentPartIndices[N] : u32 [[name("Parent Part Indices"), FIXUP]]; }; enum DeformerType : u32 { WARP = 0, ROTATION = 1, }; struct DeformerOffsets<auto N> { if (ShowRuntimeSpaceFields) u32 runtimeSpace0 [[name("Runtime Space 0 Offset")]]; else void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; ID* ids[N] : u32 [[name("IDs"), FIXUP]]; s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; bool32* isVisible[N] : u32 [[name("Visible"), FIXUP]]; bool32* isEnabled[N] : u32 [[name("Enabled"), FIXUP]]; s32* parentPartIndices[N] : u32 [[name("Parent Part Indices"), FIXUP]]; s32* parentDeformerIndices[N] : u32 [[name("Parent Deformer Indices"), FIXUP]]; DeformerType* types[N] : u32 [[name("Types"), FIXUP]]; s32* specificSourcesIndices[N] : u32 [[name("Specific Sources Indices"), FIXUP]]; }; struct WarpDeformerOffsets<auto N> { s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBeginIndices[N] : u32 [[name("Keyform Sources Begin Indices"), FIXUP]]; s32* keyformSourcesCounts[N] : u32 [[name("Keyform Sources Counts"), FIXUP]]; s32* vertexCounts[N] : u32 [[name("Vertex Counts"), FIXUP]]; u32* rows[N] : u32 [[name("Rows"), FIXUP]]; u32* columns[N] : u32 [[name("Columns"), FIXUP]]; }; struct RotationDeformerOffsets<auto N> { s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBeginIndices[N] : u32 [[name("Keyform Sources Begin Indices"), FIXUP]]; s32* keyformSourcesCounts[N] : u32 [[name("Keyform Sources Counts"), FIXUP]]; float* baseAngles[N] : u32 [[name("Base Angles"), FIXUP]]; }; bitfield DrawableFlags { blendMode : 2; isDoubleSided : 1; isInverted : 1; padding : 4; }; struct ArtMeshOffsets<auto N> { if (ShowRuntimeSpaceFields) { u32 runtimeSpace0 [[name("Runtime Space 0 Offset")]]; u32 runtimeSpace1 [[name("Runtime Space 1 Offset")]]; u32 runtimeSpace2 [[name("Runtime Space 2 Offset")]]; u32 runtimeSpace3 [[name("Runtime Space 3 Offset")]]; } else { void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; void* runtimeSpace1[N * 8] : u32 [[name("Runtime Space 1"), hidden]]; void* runtimeSpace2[N * 8] : u32 [[name("Runtime Space 2"), hidden]]; void* runtimeSpace3[N * 8] : u32 [[name("Runtime Space 3"), hidden]]; } ID* ids[N] : u32 [[name("IDs"), FIXUP]]; s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBeginIndices[N] : u32 [[name("Keyform Sources Begin Indices"), FIXUP]]; s32* keyformSourcesCounts[N] : u32 [[name("Keyform Sources Counts"), FIXUP]]; bool32* isVisible[N] : u32 [[name("Visible"), FIXUP]]; bool32* isEnabled[N] : u32 [[name("Enabled"), FIXUP]]; s32* parentPartIndices[N] : u32 [[name("Parent Part Indices"), FIXUP]]; s32* parentDeformerIndices[N] : u32 [[name("Parent Deformer Indices"), FIXUP]]; u32* textureNos[N] : u32 [[name("Texture No."), FIXUP]]; DrawableFlags* drawableFlags[N] : u32 [[name("Drawable Flags"), FIXUP]]; s32* vertexCounts[N] : u32 [[name("Vertex Counts"), FIXUP]]; s32* uvSourcesBeginIndices[N] : u32 [[name("UV Sources Begin Indices"), FIXUP]]; s32* positionIndexSourcesBeginIndices[N] : u32 [[name("Position Index Sources Begin Indices"), FIXUP]]; s32* positionIndexSourcesCounts[N] : u32 [[name("Position Index Sources Counts"), FIXUP]]; s32* drawableMaskSourcesBeginIndices[N] : u32 [[name("Drawable Mask Sources Begin Indices"), FIXUP]]; s32* drawableMaskSourcesCounts[N] : u32 [[name("Drawable Mask Sources Counts"), FIXUP]]; }; struct ParameterOffsets<auto N> { if (ShowRuntimeSpaceFields) u32 runtimeSpace0 [[name("Runtime Space 0 Offset")]]; else void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; ID* ids[N] : u32 [[name("IDs"), FIXUP]]; float* maxValues[N] : u32 [[name("Max Values"), FIXUP]]; float* minValues[N] : u32 [[name("Min Values"), FIXUP]]; float* defaultValues[N] : u32 [[name("Default Values)"), FIXUP]]; bool32* isRepeat[N] : u32 [[name("Repeat"), FIXUP]]; u32* decimalPlaces[N] : u32 [[name("Decimal Places"), FIXUP]]; s32* parameterBindingSourcesBeginIndices[N] : u32 [[name("Parameter Binding Sources Begin Indices"), FIXUP]]; s32* parameterBindingSourcesCounts[N] : u32 [[name("Parameter Binding Sources Count"), FIXUP]]; }; struct PartKeyformOffsets<auto N> { float* drawOrders[N] : u32 [[name("Draw Orders"), FIXUP]]; }; struct WarpDeformerKeyformOffsets<auto N> { float* opacities[N] : u32 [[name("Opacities"), FIXUP]]; s32* keyformPositionSourcesBeginIndices[N] : u32 [[name("Keyform Position Sources Begin Indices"), FIXUP]]; }; struct RotationDeformerKeyformOffsets<auto N> { float* opacities[N] : u32 [[name("Opacities"), FIXUP]]; float* angles[N] : u32 [[name("Angles"), FIXUP]]; float* originX[N] : u32 [[name("X Origins"), FIXUP]]; float* originY[N] : u32 [[name("Y Origins"), FIXUP]]; float* scales[N] : u32 [[name("Scales"), FIXUP]]; bool32* isReflectX[N] : u32 [[name("Reflect on X"), FIXUP]]; bool32* isReflectY[N] : u32 [[name("Reflect on Y"), FIXUP]]; }; struct ArtMeshKeyformOffsets<auto N> { float* opacities[N] : u32 [[name("Opacities"), FIXUP]]; float* drawOrders[N] : u32 [[name("Draw Orders"), FIXUP]]; s32* keyformPositionSourcesBeginIndices[N] : u32 [[name("Keyform Position Sources Begin Indices"), FIXUP]]; }; struct KeyformPositionOffsets<auto N> { XY* xys[N / 2] : u32 [[name("Coordinates"), FIXUP]]; }; struct ParameterBindingIndicesOffsets<auto N> { s32* bindingSourcesIndices[N] : u32 [[name("Binding Sources Indices"), FIXUP]]; }; struct KeyformBindingOffsets<auto N> { s32* parameterBindingIndexSourcesBeginIndices[N] : u32 [[name("Parameter Binding Index Sources Begin Indices"), FIXUP]]; s32* parameterBindingIndexSourcesCounts[N] : u32 [[name("Parameter Binding Index Sources Counts"), FIXUP]]; }; struct ParameterBindingOffsets<auto N> { s32* keysSourcesBeginIndices[N] : u32 [[name("Keys Sources Begin Indices"), FIXUP]]; s32* keysSourcesCounts[N] : u32 [[name("Keys Sources Counts"), FIXUP]]; }; struct KeyOffsets<auto N> { float* values[N] : u32 [[name("Key Values"), FIXUP]]; }; struct UVOffsets<auto N> { UV* uvs[N / 2] : u32 [[name("UVs"), FIXUP]]; }; struct PositionIndicesOffsets<auto N> { s16* indices[N] : u32 [[name("Indices"), FIXUP]]; }; struct DrawableMaskOffsets<auto N> { s32* artMeshSourcesIndices[N] : u32 [[name("Art Mesh Sources Indices"), FIXUP]]; }; struct DrawOrderGroupOffsets<auto N> { s32* objectSourcesBeginIndices[N] : u32 [[name("Object Sources Begin Indices"), FIXUP]]; s32* objectSourcesCounts[N] : u32 [[name("Object Sources Counts"), FIXUP]]; s32* objectSourcesTotalCounts[N] : u32 [[name("Object Sources Total Counts"), FIXUP]]; u32* maximumDrawOrders[N] : u32 [[name("Maximum Draw Orders"), FIXUP]]; u32* minimumDrawOrders[N] : u32 [[name("Minimum Draw Orders"), FIXUP]]; }; enum DrawOrderGroupObjectType : u32 { ART_MESH = 0, PART = 1, }; struct DrawOrderGroupObjectOffsets<auto N> { DrawOrderGroupObjectType* types[N] : u32 [[name("Types"), FIXUP]]; s32* indices[N] : u32 [[name("Indices"), FIXUP]]; s32* selfIndices[N] : u32 [[name("Self Indices"), FIXUP]]; }; struct GlueOffsets<auto N> { if (ShowRuntimeSpaceFields) u32 runtimeSpace0 [[name("Runtime Space 0 Offset")]]; else void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; ID* IDs[N] : u32 [[name("IDs"), FIXUP]]; s32* keyformBindingSourcesIndices[N] : u32 [[name("Keyform Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBeginIndices[N] : u32 [[name("Keyform Sources Begin Indices"), FIXUP]]; s32* keyformSourcesCounts[N] : u32 [[name("Keyform Binding Sources Counts"), FIXUP]]; s32* artMeshIndicesA[N] : u32 [[name("Art Mesh Indices (A)"), FIXUP]]; s32* artMeshIndicesB[N] : u32 [[name("Art Mesh Indices (B)"), FIXUP]]; s32* glueInfoSourcesBeginIndices[N] : u32 [[name("Info Sources Begin Indices"), FIXUP]]; s32* glueInfoSourcesCounts[N] : u32 [[name("Info Sources Counts"), FIXUP]]; }; struct GlueInfoOffsets<auto N> { float* weights[N] : u32 [[name("Weights"), FIXUP]]; s16* positionIndices[N] : u32 [[name("Position Indices"), FIXUP]]; }; struct GlueKeyformOffsets<auto N> { float* intensities[N] : u32 [[name("Intensities"), FIXUP]]; }; struct WarpDeformerKeyformOffsetsV3_3<auto N> { bool32* isQuadSource[N] : u32 [[name("Quad Source"), FIXUP]]; }; struct ParameterExtensionOffsets<auto N> { if (ShowRuntimeSpaceFields) u32 runtimeSpace0 [[name("Runtime Space 0")]]; else void* runtimeSpace0[N * 8] : u32 [[name("Runtime Space 0"), hidden]]; s32* keysSourcesBeginIndices[N] : u32 [[name("Keys Sources Begin Indices"), FIXUP]]; s32* keysSourcesCounts[N] : u32 [[name("Keys Sources Counts"), FIXUP]]; }; struct WarpDeformerKeyformOffsetsV4_2<auto N> { s32* keyformColorSourcesBeginIndices[N] : u32 [[name("Keyform Color Sources Begin Indices"), FIXUP]]; }; struct RotationDeformerOffsetsV4_2<auto N> { s32* keyformColorSourcesBeginIndices[N] : u32 [[name("Keyform Color Sources Begin Indices"), FIXUP]]; }; struct ArtMeshOffsetsV4_2<auto N> { s32* keyformColorSourcesBeginIndices[N] : u32 [[name("Keyform Color Sources Begin Indices"), FIXUP]]; }; struct KeyformColorOffsets<auto N> { float* R[N] : u32 [[name("Red Values"), FIXUP]]; float* G[N] : u32 [[name("Green Values"), FIXUP]]; float* B[N] : u32 [[name("Blue Values"), FIXUP]]; }; enum ParameterType : u32 { NORMAL = 0, BLEND_SHAPE = 1, }; struct ParameterOffsetsV4_2<auto N> { ParameterType* parameterTypes[N] : u32 [[name("Types"), FIXUP]]; s32* blendShapeParameterBindingSourcesBeginIndices[N] : u32 [[name("Blend Shape Parameter Binding Sources Begin Indices"), FIXUP]]; s32* blendShapeParameterBindingSourcesCounts[N] : u32 [[name("Blend Shape Parameter Binding Sources Counts"), FIXUP]]; }; struct BlendShapeParameterBindingOffsets<auto N> { s32* keysSourcesBeginIndices[N] : u32 [[name("Keys Sources Begin Indices"), FIXUP]]; s32* keysSourcesCounts[N] : u32 [[name("Keys Sources Counts"), FIXUP]]; s32* baseKeyIndices[N] : u32 [[name("Base Key Indices"), FIXUP]]; }; struct BlendShapeKeyformBindingOffsets<auto N> { s32* parameterBindingSourcesIndices[N] : u32 [[name("Parameter Binding Sources Indices"), FIXUP]]; s32* keyformSourcesBlendShapeIndices[N] : u32 [[name("Keyform Sources Blend Shape Indices"), FIXUP]]; s32* keyformSourcesBlendShapeCounts[N] : u32 [[name("Keyform Sources Blend Shape Counts"), FIXUP]]; s32* blendShapeConstraintIndexSourcesBeginIndices[N] : u32 [[name("Blend Shape Constraint Index Sources Begin Indices"), FIXUP]]; s32* blendShapeConstraintIndexSourcesCounts[N] : u32 [[name("Blend Shape Constraint Index Sources Counts"), FIXUP]]; }; struct BlendShapeOffsets<auto N> { s32* targetIndices[N] : u32 [[name("Target Indices"), FIXUP]]; s32* blendShapeKeyformBindingSourcesBeginIndices[N] : u32 [[name("Blend Shape Keyform Binding Sources Begin Indices"), FIXUP]]; s32* blendShapeKeyformBindingSourcesCounts[N] : u32 [[name("Blend Shape Keyform Binding Sources Counts"), FIXUP]]; }; struct BlendShapeConstraintIndicesOffsets<auto N> { s32* blendShapeConstraintSourcesIndices[N] : u32 [[name("Blend Shape Constraint Sources Indices"), FIXUP]]; }; struct BlendShapeConstraintOffsets<auto N> { s32* parameterIndices[N] : u32 [[name("Parameter Indices"), FIXUP]]; s32* blendShapeConstraintValueSourcesBeginIndices[N] : u32 [[name("Blend Shape Constraint Value Sources Begin Indices"), FIXUP]]; s32* blendShapeConstraintValueSourcesCounts[N] : u32 [[name("Blend Shape Constraint Value Sources Counts"), FIXUP]]; }; struct BlendShapeConstraintValueOffsets<auto N> { float* keys[N] : u32 [[name("Keys"), FIXUP]]; float* weights[N] : u32 [[name("Weights"), FIXUP]]; }; struct WarpDeformerKeyformOffsetsV5_0<auto N> { s32* keyformMultiplyColorSourcesBeginIndices[N] : u32 [[name("Keyform Multiply Color Sources Begin Indices"), FIXUP]]; s32* keyformScreenColorSourcesBeginIndices[N] : u32 [[name("Keyform Screen Color Sources Begin Indices"), FIXUP]]; }; struct RotationDeformerKeyformOffsetsV5_0<auto N> { s32* keyformMultiplyColorSourcesBeginIndices[N] : u32 [[name("Keyform Multiply Color Sources Begin Indices"), FIXUP]]; s32* keyformScreenColorSourcesBeginIndices[N] : u32 [[name("Keyform Screen Color Sources Begin Indices"), FIXUP]]; }; struct ArtMeshKeyformOffsetsV5_0<auto N> { s32* keyformMultiplyColorSourcesBeginIndices[N] : u32 [[name("Keyform Multiply Color Sources Begin Indices"), FIXUP]]; s32* keyformScreenColorSourcesBeginIndices[N] : u32 [[name("Keyform Screen Color Sources Begin Indices"), FIXUP]]; }; struct SectionOffsetTable<auto V> { padding[0x280] [[no_unique_address]]; CountInfoTable<V>* countInfo : u32 [[name("Count Info Table")]]; CanvasInfo* canvasInfo : u32 [[name("Canvas Info")]]; PartOffsets<countInfo.parts> parts [[name("Parts")]]; DeformerOffsets<countInfo.deformers> deformers [[name("Deformers")]]; WarpDeformerOffsets<countInfo.warpDeformers> warpDeformers [[name("Warp Deformers")]]; RotationDeformerOffsets<countInfo.rotationDeformers> rotationDeformers [[name("Rotation Deformers")]]; ArtMeshOffsets<countInfo.artMeshes> artMeshes [[name("Art Meshes")]]; ParameterOffsets<countInfo.parameters> parameters [[name("Parameters")]]; PartKeyformOffsets<countInfo.partKeyforms> partKeyforms [[name("Part Keyforms")]]; WarpDeformerKeyformOffsets<countInfo.warpDeformerKeyforms> warpDeformerKeyforms [[name("Warp Deformer Keyforms")]]; RotationDeformerKeyformOffsets<countInfo.rotationDeformerKeyforms> rotationDeformerKeyforms [[name("Rotation Deformer Keyforms")]]; ArtMeshKeyformOffsets<countInfo.artMeshKeyforms> artMeshKeyforms [[name("Art Mesh Keyforms")]]; KeyformPositionOffsets<countInfo.keyformPositions> keyformPositions [[name("Keyform Positions")]]; ParameterBindingIndicesOffsets<countInfo.parameterBindingIndices> parameterBindingIndices [[name("Parameter Binding Indices")]]; KeyformBindingOffsets<countInfo.keyformBindings> keyformBindings [[name("Keyform Bindings")]]; ParameterBindingOffsets<countInfo.parameterBindings> parameterBindings [[name("Parameter Bindings")]]; KeyOffsets<countInfo.keys> keys [[name("Keys")]]; UVOffsets<countInfo.uvs> UVs [[name("UVs")]]; PositionIndicesOffsets<countInfo.positionIndices> positionIndices [[name("Position Indices")]]; DrawableMaskOffsets<countInfo.drawableMasks> drawableMasks [[name("Drawable Masks")]]; DrawOrderGroupOffsets<countInfo.drawOrderGroups> drawOrderGroups [[name("Draw Order Groups")]]; DrawOrderGroupObjectOffsets<countInfo.drawOrderGroupObjects> drawOrderGroupObjects [[name("Draw Order Group Objects")]]; GlueOffsets<countInfo.glue> glue [[name("Glue")]]; GlueInfoOffsets<countInfo.glueInfo> glueInfo [[name("Glue Info")]]; GlueKeyformOffsets<countInfo.glueKeyforms> glueKeyforms [[name("Glue Keyforms")]]; if (V >= Version::V3_03_00) { WarpDeformerKeyformOffsetsV3_3<countInfo.warpDeformers> warpDeformersV3_3 [[name("Warp Deformer Keyforms (V3_03_00+)")]]; } if (V >= Version::V4_02_00) { ParameterExtensionOffsets<countInfo.parameters> parameterExtensions [[name("Parameter Extensions")]]; WarpDeformerKeyformOffsetsV4_2<countInfo.warpDeformers> warpDeformersV4_2 [[name("Warp Deformer Keyforms (V4_02_00+)")]]; RotationDeformerOffsetsV4_2<countInfo.rotationDeformers> rotationDeformersV4_2 [[name("Rotation Deformers (V4_02_00+)")]]; ArtMeshOffsetsV4_2<countInfo.artMeshes> artMeshesV4_2 [[name("Art Meshes (V4_02_00+)")]]; KeyformColorOffsets<countInfo.keyformMultiplyColors> keyformMultiplyColors [[name("Keyform Colors (Multiply)")]]; KeyformColorOffsets<countInfo.keyformScreenColors> keyformScreenColors [[name("Keyform Colors (Screen)")]]; ParameterOffsetsV4_2<countInfo.parameters> parametersV4_2 [[name("Parameters (V4_02_00+)")]]; BlendShapeParameterBindingOffsets<countInfo.blendShapeParameterBindings> blendShapeParameterBindings [[name("Blend Shape Parameter Bindings")]]; BlendShapeKeyformBindingOffsets<countInfo.blendShapeKeyformBindings> blendShapeKeyformBindings [[name("Blend Shape Keyform Bindings")]]; BlendShapeOffsets<countInfo.blendShapesWarpDeformers> blendShapesWarpDeformers [[name("Blend Shapes (Warp Deformers)")]]; BlendShapeOffsets<countInfo.blendShapesArtMeshes> blendShapesArtMeshes [[name("Blend Shapes (Art Meshes)")]]; BlendShapeConstraintIndicesOffsets<countInfo.blendShapeConstraintIndices> blendShapeConstraintIndices [[name("Blend Shape Constraints Indices")]]; BlendShapeConstraintOffsets<countInfo.blendShapeConstraints> blendShapeConstraints [[name("Blend Shape Constraints")]]; BlendShapeConstraintValueOffsets<countInfo.blendShapeConstraintValues> blendShapeConstraintValues [[name("Blend Shape Constraint Values")]]; } if (V >= Version::V5_00_00) { WarpDeformerKeyformOffsetsV5_0<countInfo.warpDeformerKeyforms> warpDeformerKeyformsV5_0 [[name("Warp Deformer Keyforms (V5_00_00+)")]]; RotationDeformerKeyformOffsetsV5_0<countInfo.rotationDeformerKeyforms> rotationDeformerKeyformsV5_0 [[name("Rotation Deformer Keyforms (V5_00_00+)")]]; ArtMeshKeyformOffsetsV5_0<countInfo.artMeshKeyforms> artMeshKeyformsV5_0 [[name("Art Mesh Keyforms (V5_00_00+)")]]; BlendShapeOffsets<countInfo.blendShapesParts> blendShapesParts [[name("Blend Shapes (Parts)")]]; BlendShapeOffsets<countInfo.blendShapesRotationDeformers> blendShapesRotationDeformers [[name("Blend Shapes (Rotation Deformers)")]]; BlendShapeOffsets<countInfo.blendShapesGlue> blendShapesGlue [[name("Blend Shapes (Glue)")]]; } }; struct RuntimeAddressMap { void runtimeData[0x480] [[name("Runtime Data (Overwritten at Load Time)"), comment("Do not put data here.")]]; }; Header header @ 0x0 [[name("MOC3 Header")]]; #ifndef NO_BIG_ENDIAN_SUPPORT #include <std/core.pat> #include <std/mem.pat> if (AlwaysReadAsBigEndian || header.isBigEndian) { std::core::set_endian(std::mem::Endian::Big); } else { std::core::set_endian(std::mem::Endian::Little); } #endif SectionOffsetTable<header.version> sections @ 0x40 [[name("Section Offset Table")]]; RuntimeAddressMap runtimeAddressMap @ 0x2c0 [[name("Runtime Address Map")]];