Display Block

Convertisseur BBModel → BDEngine

Ce projet est né d'un constat simple côté créateurs Minecraft : beaucoup de modèles 3D sont conçus dans Blockbench, mais restent difficiles à réutiliser en vanilla sans passer par des mods. J'ai donc développé un convertisseur qui transforme automatiquement ces modèles au format .bbmodel en structures exploitables par Block Display Engine (BDEngine), en s'appuyant uniquement sur les entités d'affichage et les têtes de joueur personnalisées.

Contexte et objectifs

Dans Minecraft, les créateurs doivent souvent choisir entre :

  • des mods puissants mais lourds à installer et dépendants d'une version du jeu
  • ou du pur vanilla, plus simple à distribuer mais très limité en 3D avancée.

L'objectif du convertisseur est de :

  • permettre de réutiliser des modèles Blockbench existants sans mods, uniquement avec des commandes et des ressources
  • générer automatiquement la structure BDEngine (têtes, matrices, textures) à partir d'un fichier .bbmodel
  • offrir deux modes : conversion rapide (stretch) et conversion qualité (smart cube).

Mon rôle

Il s'agit d'un projet personnel open-source, que j'ai entièrement conçu et développé :

  • analyse des formats Blockbench et BDEngine, définition de la stratégie de conversion
  • implémentation du pipeline complet en Python (lecture, calculs 3D, textures, écriture)
  • conception de l'algorithme de subdivision intelligente (smart cube) pour limiter la déformation des textures
  • rédaction de la documentation et publication du projet sur GitHub.

Principe général

Blockbench permet de concevoir des modèles à base de cubes en précisant leurs dimensions (from/to), leurs rotations et les coordonnées UV des différentes faces. Les modèles sont enregistrés dans un fichier JSON .bbmodel et sont essentiellement destinés à des mods ou des packs de ressources.

À l'inverse, BDEngine est un moteur open-source mis au point par illystray pour simplifier la création d'objets 3D en jeu via les entités d'affichage vanilla. Dans ce moteur, chaque cube est représenté par une « tête de joueur » dont on contrôle l'échelle, la rotation et la texture. Mon travail consiste à faire le lien entre ces deux mondes : prendre un modèle Blockbench et produire automatiquement un fichier .bdengine prêt à être utilisé dans le jeu.

Un mod est un programme additionnel que les joueurs doivent installer localement. Avec BDEngine et le convertisseur, les objets restent en pur vanilla : une simple commande ou une datapack suffit, ce qui simplifie fortement la distribution.

Différences BBModel / BDEngine (vue synthétique)

Dans un modèle Blockbench, la géométrie est composée de plusieurs éléments : parallélépipèdes définis en pixels dans un repère 3D propre au modèle. BDEngine, lui, manipule des entités d'affichage positionnées en blocs, centrées sur la face supérieure d'une tête de 8×8×8 pixels.

La conversion passe donc par :

  • un changement de repère et d'unités (pixels → blocs)
  • le calcul d'un centre de modèle pour repositionner correctement l'ensemble
  • la génération d'une matrice de transformation 4×4 pour chaque tête.

Détails techniques - positions et échelles

Pour chaque élément, on détermine :

  • la position du coin inférieur : bottom = (\min(x_f, x_t), \min(y_f, y_t), \min(z_f, z_t))
  • la taille en pixels : width = |x_t - x_f|, height = |y_t - y_f|, depth = |z_t - z_f|
  • la rotation locale (X, Y, Z) en degrés.

Le moteur place chaque tête par rapport au centre de sa face supérieure. Si l'élément mesure width × height × depth et repose sur bottom = (b_x,b_y,b_z), alors :

\begin{align*} center_x &= b_x + \frac{width}{2} \\ center_z &= b_z + \frac{depth}{2} \\ top_y &= b_y + height \end{align*}

La position en blocs s'obtient en soustrayant le centre du modèle et en divisant par 16 :

\begin{align*} pos_x &= \frac{center_x - model_center_x}{16} \\ pos_y &= \frac{top_y - model_center_y}{16} \\ pos_z &= \frac{center_z - model_center_z}{16} \end{align*}

L'échelle est déduite du ratio entre la taille de l'élément et la taille native d'une tête (8 pixels) :

\begin{align*} scale_x &= \max\left(\frac{width}{8},\ min\_scale\right) \\ scale_y &= \max\left(\frac{height}{8},\ min\_scale\right) \\ scale_z &= \max\left(\frac{depth}{8},\ min\_scale\right) \end{align*}

Détails techniques - rotations et matrices

Les rotations de Blockbench suivent l'ordre « Z → X → Y ». Pour obtenir la matrice de rotation 4×4 utilisée par BDEngine, on calcule d'abord les rotations élémentaires (en radians) autour des trois axes :

\begin{align*} Rx &= \begin{bmatrix}1 & 0 & 0 \\ 0 & \cos(rx) & -\sin(rx) \\ 0 & \sin(rx) & \cos(rx)\end{bmatrix} \\ Ry &= \begin{bmatrix}\cos(ry) & 0 & \sin(ry) \\ 0 & 1 & 0 \\ -\sin(ry) & 0 & \cos(ry)\end{bmatrix} \\ Rz &= \begin{bmatrix}\cos(rz) & -\sin(rz) & 0 \\ \sin(rz) & \cos(rz) & 0 \\ 0 & 0 & 1\end{bmatrix} \\ M &= Rz \times (Rx \times Ry) \end{align*}

Multipliée à l'échelle, cette matrice de rotation est insérée dans la matrice de transformation 4×4 :

\begin{bmatrix} M_{00} \cdot scale_x & M_{01} \cdot scale_y & M_{02} \cdot scale_z & pos_x \\ M_{10} \cdot scale_x & M_{11} \cdot scale_y & M_{12} \cdot scale_z & pos_y \\ M_{20} \cdot scale_x & M_{21} \cdot scale_y & M_{22} \cdot scale_z & pos_z \\ 0 & 0 & 0 & 1 \end{bmatrix}

Cette matrice est directement écrite dans le fichier .bdengine et interprétée en jeu par l'entité head display.

Subdivision intelligente (smart cube)

Le projet propose deux stratégies de conversion :

  • Stretch : un élément Blockbench = une seule tête étirée. Rapide, mais les textures peuvent être déformées.
  • Smart cube : chaque élément est découpé en plusieurs sous-cubes (16, 8, 4, 2 ou 1 pixels de côté) pour préserver au mieux les proportions de la texture et l'aspect des pixels.

Un algorithme analyse les dimensions de l'élément et ses coordonnées UV pour choisir la meilleure décomposition. Les faces planes sont converties en têtes très fines (épaisseur ≈ 0,011 bloc) pour simuler un panneau sans volume, ce qui réduit le nombre de têtes nécessaires tout en gardant un rendu propre.

Les têtes de joueur disposent d'un template 64×64 pixels où chaque face occupe une zone 8×8. La conversion calcule les régions UV dans la texture Blockbench, puis les projette dans les zones correspondantes du template de tête (par exemple, north sur la zone 8-16, 8-16). Une transformation affine garantit le ratio 1:1 des pixels pour éviter les déformations.

Architecture du code

Le code est structuré en plusieurs modules principaux :

  • converter.py : point d'entrée qui orchestre la lecture du .bbmodel, l'extraction des textures et l'écriture du .bdengine compressé (gzip + base64).
  • conversion_strategy.py : définit les stratégies StretchConversionStrategy et SmartCubeConversionStrategy.
  • head_factory.py : génère les structures JSON des têtes BDEngine et les matrices de transformation.
  • math_utils.py : fonctions de trigonométrie, matrices de rotation 3×3 / 4×4 et transformation de points 3D.
  • texture_manager.py et texture_subdivider.py : gestion des textures, découpe UV et subdivision des images.
  • smart_cube_optimizer.py : choix des combinaisons de cubes et optimisation du compromis nombre de têtes / qualité visuelle.

Exemples de créations BDEngine

Avant de présenter les résultats du convertisseur, voici quelques exemples de créations réalisées directement avec BDEngine. Ces modèles illustrent le potentiel du moteur en pur vanilla.

Banc en bois créé avec BDEngine
Un banc en bois composé de plusieurs têtes positionnées manuellement pour former un meuble fonctionnel.
Globe terrestre réalisé avec des cubes et rotations
Un globe terrestre assemblé à partir de cubes texturés et de rotations précises pour représenter la Terre.

Exemples de modèles convertis

Voici maintenant des exemples concrets de modèles Blockbench convertis en BDEngine :

Modèle Pikachu d'origine dans Blockbench
Modèle Pikachu dans Blockbench, composé de nombreux éléments et d'une texture 64×64 détaillée.
Pikachu après conversion en BDEngine
Le même Pikachu après conversion : les volumes sont approximés par des subdivisions et la texture des joues, oreilles et queue est préservée.
Ornithorynque dans Blockbench
Un ornithorynque dans Blockbench, avec indication des axes X, Y, Z du repère de modélisation.
Ornithorynque converti dans BDEngine
Après conversion, le modèle utilise uniquement des têtes de joueur, en conservant l'aspect du bec, des pattes et de la queue.

Ces exemples montrent que le convertisseur peut transformer des modèles complexes en structures BDEngine utilisables en vanilla, tout en respectant les rotations, échelles et textures d'origine.

Limitations et évolutions futures

Le convertisseur est encore en évolution :

  • les textures haute résolution (> 16 pixels par bloc) nécessitent des stratégies de subdivision adaptées (32×32, 64×64)
  • la transparence pourrait être mieux exploitée pour limiter le nombre de têtes générées
  • la gestion fine des groupes (outliner) peut encore être améliorée pour coller exactement au comportement de Blockbench
  • l'API BDEngine évolue régulièrement et ouvre des perspectives (animations, éclairage, textures dynamiques).

Notions utilisées

  • Python (bibliothèques standard)
  • Numpy pour les matrices et les calculs de rotation
  • Pillow pour le traitement d'images et l'encodage PNG
  • JSON et Gzip pour la sérialisation des modèles
  • Mécanismes de Block Display et de têtes de joueur dans Minecraft
  • Maths appliquées : algèbre linéaire, trigonométrie, changement de repère, optimisation.

Liens externes