Skip to main content

Overview

The model rendering system in Minecraft Community Edition provides classes for rendering 3D entity models with animations. This includes the base Model class, specialized models like HumanoidModel, entity renderers, and model parts.

Model Class

Header: Minecraft.Client/Model.h

Class Definition

class Model
Base class for all entity models.

Members

float attackTime;                             // Attack animation progress (0-1)
bool riding;                                  // Whether entity is riding
vector<ModelPart*> cubes;                     // Model parts/cubes
bool young;                                   // Whether entity is a baby
unordered_map<wstring, TexOffs*> mappedTexOffs;  // Texture offset mapping
int texWidth;                                 // Texture width
int texHeight;                                // Texture height

Core Methods

render

virtual void render(shared_ptr<Entity> entity, float time, float r, 
                   float bob, float yRot, float xRot, 
                   float scale, bool usecompiled);
Renders the model. Parameters:
  • entity - Entity being rendered
  • time - Animation time/walk position
  • r - Walk animation speed
  • bob - Vertical bob amount
  • yRot - Head yaw rotation (relative to body)
  • xRot - Head pitch rotation
  • scale - Render scale (typically 1/16)
  • usecompiled - Use compiled display lists (optimization)

setupAnim

virtual void setupAnim(float time, float r, float bob, 
                      float yRot, float xRot, float scale,
                      unsigned int uiBitmaskOverrideAnim = 0);
Sets up model animations before rendering. Parameters:
  • time - Animation time
  • r - Animation speed
  • bob - Bob amount
  • yRot - Y rotation
  • xRot - X rotation
  • scale - Scale factor
  • uiBitmaskOverrideAnim - Animation override flags

prepareMobModel

virtual void prepareMobModel(shared_ptr<Mob> mob, float time, float r, float a);
Prepares model-specific state before rendering (e.g., spider climbing animation).

Texture Mapping

void setMapTex(wstring id, int x, int y);
TexOffs* getMapTex(wstring id);
Manage texture coordinate mappings for model parts.

HumanoidModel Class

Header: Minecraft.Client/HumanoidModel.h

Class Definition

class HumanoidModel : public Model
Model for humanoid entities (players, zombies, skeletons, etc.).

Model Parts

ModelPart *head;      // Head
ModelPart *hair;      // Hair/helmet overlay
ModelPart *body;      // Torso
ModelPart *arm0;      // Right arm
ModelPart *arm1;      // Left arm
ModelPart *leg0;      // Right leg
ModelPart *leg1;      // Left leg
ModelPart *ear;       // Ear (for some mobs)
ModelPart *cloak;     // Cape/cloak

Animation State

int holdingLeftHand;      // 0=nothing, 1=item, 2=block
int holdingRightHand;     // 0=nothing, 1=item, 2=block
bool idle;                // Idle animation enabled
bool sneaking;            // Sneaking pose
bool bowAndArrow;         // Aiming bow
bool eating;              // Eating animation
float eating_t;           // Eating animation time
float eating_swing;       // Eating swing amount

Animation Override Flags

enum animbits {
    eAnim_ArmsDown = 0,           // Arms at sides
    eAnim_ArmsOutFront,           // Arms out front (zombie)
    eAnim_NoLegAnim,              // Disable leg animation
    eAnim_HasIdle,                // Enable idle animation
    eAnim_ForceAnim,              // Force custom animation
    eAnim_SingleLegs,             // Both legs move together
    eAnim_SingleArms,             // Both arms move together
    eAnim_StatueOfLiberty,        // Static pose (Weeping Angels)
    eAnim_DontRenderArmour,       // Don't render armor
    eAnim_NoBobbing,              // Disable bobbing
    eAnim_DisableRenderHead,      // Hide head
    eAnim_DisableRenderArm0,      // Hide right arm
    eAnim_DisableRenderArm1,      // Hide left arm
    eAnim_DisableRenderTorso,     // Hide torso
    eAnim_DisableRenderLeg0,      // Hide right leg
    eAnim_DisableRenderLeg1,      // Hide left leg
    eAnim_DisableRenderHair       // Hide hair overlay
};

Constructors

HumanoidModel();
HumanoidModel(float g);
HumanoidModel(float g, float yOffset, int texWidth, int texHeight);
Parameters:
  • g - Model scale/padding
  • yOffset - Vertical offset
  • texWidth - Texture width (64 for standard skins)
  • texHeight - Texture height (64 for standard, 32 for legacy)
Example:
// Standard player model (64x64 skin)
HumanoidModel* playerModel = new HumanoidModel(0.0f, 0.0f, 64, 64);

// Zombie model (slightly larger)
HumanoidModel* zombieModel = new HumanoidModel(0.5f);

Rendering Methods

void render(shared_ptr<Entity> entity, float time, float r, 
           float bob, float yRot, float xRot, 
           float scale, bool usecompiled) override;

void renderHair(float scale, bool usecompiled);
void renderEars(float scale, bool usecompiled);
void renderCloak(float scale, bool usecompiled);
Example:
// Render player with cape
playerModel->render(player, walkPos, walkSpeed, bob, 
                   headYaw, headPitch, 1.0f/16.0f, true);
playerModel->renderCloak(1.0f/16.0f, true);

ModelPart Class

Header: Minecraft.Client/ModelPart.h

Class Definition

class ModelPart
Represents an individual part of a model (head, arm, leg, etc.).

Transform Properties

float x, y, z;           // Position offset
float xRot, yRot, zRot;  // Rotation in radians
bool visible;            // Whether to render
bool neverRender;        // Permanently hidden
bool bMirror;            // Mirror texture coordinates

Constructors

ModelPart();
ModelPart(Model *model, const wstring &id);
ModelPart(Model *model);
ModelPart(Model *model, int xTexOffs, int yTexOffs);

Building Methods

ModelPart* texOffs(int xTexOffs, int yTexOffs);
ModelPart* addBox(float x0, float y0, float z0, int w, int h, int d);
ModelPart* addBox(float x0, float y0, float z0, int w, int h, int d, float g);
void addHumanoidBox(float x0, float y0, float z0, int w, int h, int d, float g);
ModelPart* mirror();
Example:
// Create a head model part
ModelPart* head = new ModelPart(model, 0, 0);
head->addBox(-4, -8, -4, 8, 8, 8, 0.0f);  // Head cube
head->setPos(0, 0, 0);

// Create arm with mirrored texture
ModelPart* leftArm = new ModelPart(model, 40, 16);
leftArm->mirror();  // Mirror for left side
leftArm->addBox(-1, -2, -2, 4, 12, 4, 0.0f);
leftArm->setPos(5, 2, 0);

Rendering

void render(float scale, bool usecompiled, bool bHideParentBodyPart = false);
void renderRollable(float scale, bool usecompiled);
Example:
// Render model part
glPushMatrix();
glTranslatef(x, y, z);
glRotatef(xRot * RAD_TO_DEG, 1, 0, 0);
head->render(1.0f/16.0f, true);
glPopMatrix();

Entity Renderers

EntityRenderer Base Class

Header: Minecraft.Client/EntityRenderer.h
class EntityRenderer
Base class for all entity renderers.

Key Methods

virtual void render(shared_ptr<Entity> entity, 
                   double x, double y, double z, 
                   float rot, float a) = 0;

virtual void postRender(shared_ptr<Entity> entity,
                       double x, double y, double z,
                       float rot, float a, bool bRenderPlayerShadow);

MobRenderer Class

Header: Minecraft.Client/MobRenderer.h
class MobRenderer : public EntityRenderer
Renderer for mob entities with models.

Constructor

MobRenderer(Model *model, float shadow);
Parameters:
  • model - The model to render
  • shadow - Shadow radius
Example:
// Zombie renderer
ZombieModel* zombieModel = new ZombieModel();
MobRenderer* zombieRenderer = new MobRenderer(zombieModel, 0.5f);

Core Methods

void render(shared_ptr<Entity> mob, double x, double y, double z,
           float rot, float a) override;

virtual void renderModel(shared_ptr<Entity> mob, float wp, float ws,
                        float bob, float headRotMinusBodyRot, 
                        float headRotx, float scale);

virtual void setupPosition(shared_ptr<Mob> mob, double x, double y, double z);
virtual void setupRotations(shared_ptr<Mob> mob, float bob, float bodyRot, float a);
virtual void scale(shared_ptr<Mob> mob, float a);

Armor Rendering

virtual void setArmor(Model *armor);
virtual int prepareArmor(shared_ptr<Mob> mob, int layer, float a);
Example:
// Setup armor model
HumanoidModel* armorModel = new HumanoidModel(1.0f);
mobRenderer->setArmor(armorModel);

Complete Usage Example

// 1. Create a custom mob model
class MyCustomModel : public HumanoidModel {
public:
    ModelPart* customPart;
    
    MyCustomModel() : HumanoidModel(0.0f, 0.0f, 64, 64) {
        // Add custom model part
        customPart = new ModelPart(this, 0, 32);
        customPart->addBox(-4, 0, -4, 8, 8, 8);
        customPart->setPos(0, -8, 0);
    }
    
    void setupAnim(float time, float r, float bob,
                  float yRot, float xRot, float scale,
                  unsigned int override = 0) override {
        // Call parent animation
        HumanoidModel::setupAnim(time, r, bob, yRot, xRot, scale, override);
        
        // Custom animation
        customPart->yRot = sinf(time * 0.1f) * 0.2f;
    }
    
    void render(shared_ptr<Entity> entity, float time, float r,
               float bob, float yRot, float xRot,
               float scale, bool usecompiled) override {
        // Setup animation
        setupAnim(time, r, bob, yRot, xRot, scale);
        
        // Render base humanoid model
        HumanoidModel::render(entity, time, r, bob, yRot, xRot, scale, usecompiled);
        
        // Render custom part
        customPart->render(scale, usecompiled);
    }
};

// 2. Create a custom renderer
class MyCustomRenderer : public MobRenderer {
public:
    MyCustomRenderer() : MobRenderer(new MyCustomModel(), 0.5f) {}
    
    void render(shared_ptr<Entity> entity, double x, double y, double z,
               float rot, float a) override {
        // Bind custom texture
        bindTexture(L"textures/entity/mycustom.png");
        
        // Call parent render
        MobRenderer::render(entity, x, y, z, rot, a);
    }
    
    void scale(shared_ptr<Mob> mob, float a) override {
        // Make entity larger
        glScalef(1.5f, 1.5f, 1.5f);
    }
};

// 3. Register and use
EntityRenderDispatcher* dispatcher = /* ... */;
dispatcher->register(MyCustomEntity::TYPE_ID, new MyCustomRenderer());

// Entities will now be rendered with custom model and animation

Animation Example

// Walking animation for humanoid
void HumanoidModel::setupAnim(float time, float r, float bob,
                             float yRot, float xRot, float scale,
                             unsigned int override) {
    // Head rotation
    head->yRot = yRot / RAD_TO_DEG;
    head->xRot = xRot / RAD_TO_DEG;
    
    // Arm swing
    arm0->xRot = cosf(time * 0.6662f) * 2.0f * r;
    arm1->xRot = cosf(time * 0.6662f + PI) * 2.0f * r;
    
    // Leg swing
    leg0->xRot = cosf(time * 0.6662f) * 1.4f * r;
    leg1->xRot = cosf(time * 0.6662f + PI) * 1.4f * r;
    
    // Sneaking pose
    if (sneaking) {
        body->y = 5.0f;
        head->y = 1.0f;
        leg0->y = 12.0f;
        leg1->y = 12.0f;
    } else {
        body->y = 0.0f;
        head->y = 0.0f;
        leg0->y = 12.0f;
        leg1->y = 12.0f;
    }
    
    // Bow aiming
    if (bowAndArrow) {
        arm0->xRot = -0.9f;
        arm1->xRot = -0.9f;
    }
}

Performance Tips

Display Lists: Set usecompiled to true to use OpenGL display lists for static model parts. This significantly improves performance by caching geometry.
Model Complexity: Keep model part counts reasonable. Each ModelPart adds overhead. Typical humanoid models have 8-12 parts.
  • GameRenderer - Main rendering coordinator
  • LevelRenderer - Level rendering
  • EntityRenderDispatcher - Entity renderer registry
  • Tesselator - Vertex batching
  • Entity - Base entity class
  • Mob - Mobile entity class

Build docs developers (and LLMs) love