Parts

File location

/assets/minecraft/optifine/cem/**/*.jpm

CEM part files contain the definition of one model part to be referenced in a CEM model file.

Keys

invertAxis

Values: String: permutation of "xyz"
Optional

Axes to invert: "xyz" inverts the X, Y, Z axes. An empty string inverts none of them and is equal the key being absent.

translate

Values: Array of 3 integers
Optional

Translate (move) the texture by the 3 integers x, y, and z.

rotate

Values: Array of 3 integers
Optional

Rotation (spin) the texture by the 3 integers angle_x, angle_y, and angle_z.

mirrorTexture

Values: String permutation of "uv"
Optional

Texture axis to mirror. "uv" will mirror both the U and V axis. An empty string mirrors along no axis and is equal the key being absent.

boxes

Values: Array of objects
Optional

Array of part model boxes.

textureOffset

Values: Array of 2 integers
Required

Texture offset for the box format; [x, y].

uv<FACE>

Values: Array of 4 strings
Required

<FACE> is one of Down, Up, North, South, West, or East.

UV for face. Ordered as [u1, v1, u2, v2].

coordinates

Values: Array of 6 integers
Required

Box position and dimensions. Ordered as [x, y, z, width, height, depth].

sizeAdd

Values: Integer
Optional

Size increment added to all dimensions; can be used for asymmetric scaling.

sprites

Values: Array of objects
Optional

List of 3D sprite models; depth 1.

textureOffset

Values: Array of 2 integers
Required

Texture offset; [x, y].

coordinates

Values: Array of 6 integers
Required

Box position and dimensions. Ordered as [x, y, z, width, height, depth].

sizeAdd

Values: Integer
Optional

Size increment added to all dimensions; can be used for asymmetric scaling.

submodel

Values: Self, CEM part object
Optional

A sub-model part; attached to the parent, moving and rotating with it.

submodels

Values: List of CEM part objects
Optional

A list of sub-model parts; attached to the parent, moving and rotating with it.

Texture UV

Warning

Texture UV cannot have both specifications, either "textureOffset" or uv<face>, not both.

Texture UV can be specified in box format with:

  • "textureOffset", or

  • "uvDown", "uvUp", "uvNorth", "uvSouth", "uvWest", and "uvEast".

_images/model_box.webp

The box format UV mapping.

Attachment points

Entities can have items/blocks attached to them. The attachments system allows you to render these items/blocks attached to model parts of your choice.

Attachment name

Supported models

left_handheld_item

allay, armor_stand, drowned, evoker, giant, husk, illusioner, piglin, piglin_brute, pillager, skeleton, stray, vex, vindicator, wither_skeleton, zombie, zombie_villager, zombified_piglin

right_handheld_item

allay, armor_stand, drowned, evoker, giant, husk, illusioner, piglin, piglin_brute, pillager, skeleton, stray, vex, vindicator, wither_skeleton, zombie, zombie_villager, zombified_piglin

JSON schema

{
    "$schema": "http://json-schema.org/draft/2020-12/schema",
    "$id": "https://gitlab.com/whoatemybutter/optifinedocs/-/blob/master/schemas/cem_part.schema.json",
    "title": "Custom Entity Models Part",
    "description": "CEM parts contains definition of one model part for a whole CEM model.",
    "type": "object",
    "properties": {
        "texture": {
            "type": "string",
            "description": "Texture used by entity model.",
            "$ref": "common.schema.json#/$defs/resource"
        },
        "textureSize": {
            "type": "array",
            "items": {
                "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Texture size (width, height) in pixels."
        },
        "invertAxis": {
            "type": "string",
            "maxLength": 3,
            "pattern": "^([xyz])?((?!\\1)[xyz])?((?!\\1)(?!\\2)[xyz])?((?!\\1)(?!\\2)(?!\\3))?$",
            "description": "Axes to invert; \"xyz\" inverts the X, Y, and Z axes, \"\" inverts none of them."
        },
        "translate": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
                "type": "number"
            },
            "description": "Translate texture by [0], [1], [2]."
        },
        "rotate": {
            "type": "array",
            "minItems": 3,
            "maxItems": 3,
            "items": {
                "type": "number"
            },
            "description": "Rotate texture by [0], [1], [2]."
        },
        "mirrorTexture": {
            "type": "string",
            "minLength": 2,
            "maxLength": 2,
            "pattern": "^([uv])?((?!\\1)[uv])?((?!\\1)(?!\\2)[uv])?$"
        },
        "attachments": {
            "type": "object",
            "description": "Attachment points for vanilla rendering",
            "patternProperties": {
                "^(left|right)_handheld_item$": {
                    "type": "array",
                    "minItems": 3,
                    "maxItems": 3,
                    "description": "Render an attachment with translation (tx, ty, tz). See attachment section for details.",
                    "items": {
                        "type": "number"
                    }
                }
            }
        },
        "boxes": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "textureOffset": {
                        "$ref": "#/$defs/textureOffset"
                    },
                    "coordinates": {
                        "$ref": "#/$defs/coordinates"
                    },
                    "sizeAdd": {
                        "$ref": "#/$defs/sizeAdd"
                    }
                },
                "patternProperties": {
                    "^uv(Down|Up|North|South|West|East)$": {
                        "type": "array",
                        "minItems": 4,
                        "maxItems": 4,
                        "items": {
                            "type": "string"
                        },
                        "description": "UV for face."
                    }
                }
            },
            "description": "List of part model boxes."
        },
        "sprites": {
            "type": "array",
            "items": {
                "type": "object",
                "properties": {
                    "textureOffset": {
                        "$ref": "#/$defs/textureOffset"
                    },
                    "coordinates": {
                        "$ref": "#/$defs/coordinates"
                    },
                    "sizeAdd": {
                        "$ref": "#/$defs/sizeAdd"
                    }
                }
            }
        },
        "submodel": {
            "type": "object",
            "$ref": "#",
            "description": "Submodel; attached to the parent, moving and rotating with it."
        },
        "submodels": {
            "type": "array",
            "items": {
                "type": "object",
                "$ref": "#"
            },
            "description": "List of submodels; attached to the parent, moving and rotating with it."
        }
    },
    "allOf": [
        {
            "anyOf": [
                {
                    "required": [
                        "textureOffset"
                    ]
                },
                {
                    "required": [],
                    "patternProperties": {
                        "^(?!(uv(Down|Up|North|South|West|East))$).*$": {}
                    }
                }
            ]
        },
        {
            "required": [
                "coordinates"
            ]
        }
    ],
    "$defs": {
        "textureOffset": {
            "type": "array",
            "items": {
                "type": "integer"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Texture offset for the box format."
        },
        "coordinates": {
            "type": "array",
            "minItems": 6,
            "maxItems": 6,
            "items": {
                "type": "integer"
            },
            "description": "Box position and dimensions. x, y, z, width, height, depth."
        },
        "sizeAdd": {
            "type": "number",
            "minimum": 0,
            "maximum": 65535,
            "description": "Size increment added to all dimensions; can be used for asymmetric scaling."
        }
    },
    "additionalProperties": false
}

Assumes the latest OptiFine version.
Updated to commit 15ef3106.

Last update: 2024 April 30