promotional bannermobile promotional banner

AzureLib

Java Minecraft mod using Bedrock models to create custom models and animations for items, blocks, entities

File Details

azurelib-fabric-1.21.1-3.1.10.jar

  • R
  • Jun 17, 2026
  • 871.08 KB
  • 1.4K
  • 1.21.1
  • Fabric + 1

File Name

azurelib-fabric-1.21.1-3.1.10.jar

Supported Versions

  • 1.21.1

Curse Maven Snippet

Fabric

modImplementation "curse.maven:azurelib-817423:8267375"

Quilt

modImplementation "curse.maven:azurelib-817423:8267375"
Curse Maven does not yet support mods that have disabled 3rd party sharing

Learn more about Curse Maven

v3.1.10

Performance — Rendering Pipeline Overhaul

This release is a focused performance pass targeting the client-side rendering pipeline. The goal was to bring per-entity CPU and GC cost for complex animated models in line with vanilla mob rendering. All changes are backwards-compatible — no model files, animator classes, or existing renderer configurations require modification.

Fixes

  • Fixed registry of easing types (Credit to Collinvh for fix)
  • Fixed bedrock easing interpolation having the position incorrectly in the place of the first value. (Credit to Collinvh for fix)
  • Fixed broken matrix translation in RenderUtils.translateMatrix. The previous implementation used Matrix4f.add() to apply a translation vector, which is mathematically incorrect and produced wrong world-space matrix results for bone tracking. Now uses Matrix4f.translate() as intended.
  • Fixed triple boneTextureOverrideProvider call per bone. The provider lambda was invoked three times per bone per frame in getOrRefreshRenderBuffer. Now called once, result cached locally.
  • Replaced per-cube pushPose/popPose with save/restore in renderCubesOfBone. The pose stack entry is now captured once per bone and restored after each cube transform, eliminating N matrix stack copies per multi-cube bone.
  • Added hidden bone early-out to renderRecursively. Hidden bones now skip all matrix work (pushPose, translate, rotate, scale) entirely. Children are still iterated unless isHidingChildren() is also true, matching Bedrock's bone visibility spec.
  • Hoisted flat-cube check out of the quad loop in renderCube. fixInvertedFlatCube is only relevant for 2D plane cubes (one dimension = 0). The check is now computed once per cube before the quad loop and skipped entirely for standard 3D cubes.
  • Eliminated per-vertex redundant reads in createVerticesOfQuad. getTextureOverride(), packedOverlay(), packedLight(), and normal vector components are now all hoisted outside the vertex loop. UV scale factors for the texture override path are pre-computed as floats, replacing two integer divisions per vertex with a single multiply.
  • Fixed invertAndMultiplyMatrices allocation. Previously allocated a new Matrix4f on every call (called twice per tracked bone per frame). Now uses a static INVERT_SCRATCH buffer; one allocation per call for the returned result only.
  • Eliminated per-frame Matrix4f heap allocations in renderRecursively. The two new Matrix4f(...) calls in the bone matrix tracking path are replaced with reusable scratchPoseState and scratchLocalMatrix instance fields.
  • Fixed triple getAdjustedTick() call. Was called once before the bone loop, once inside the loop per bone, and once for the callback. Now called once; currentAdjustedTick field reused throughout.
  • Fixed severe per-frame allocation spam. The previous implementation called CubicBezierCurve.getPoints(200) on every bezier keyframe every frame, allocating an ArrayList and 201 Vector2d objects per call. Additionally findClosestPoints allocated two more Vector2d instances and a Vector2d[] return on every call, and buildBezierCurve allocated four Vector2d control points per call. For a model with multiple bezier-eased bones this produced 240+ allocations per frame contributing significantly to GC pressure.
  • Fixed AzArmorRendererPipeline using head for the leftArm scaling.
  • Fixed custom easing type lookup when easing names use mixed or lower camel case.

Changed

  • Replaced nine ArrayDeque<AzAnimationPoint> queues with a flat object pool. Nine pre-allocated AzAnimationPoint instances are reused every frame via set(). A boolean[9] presence array replaces queue state. This eliminates the dominant source of per-frame heap allocation in the animation pipeline — previously ~180 record allocations per animated bone per frame.
  • Removed LinkedList usage. Previously used for all nine queues before the ArrayDeque interim; now eliminated entirely.
  • Converted from record to mutable final class. All record accessor names preserved for API compatibility. New set(...) method enables in-place reuse by the pool in AzBoneAnimationQueue.
  • Converted from record to mutable final class. New set(T, double) method allows the single scratch instance on AzAbstractKeyframeExecutor to be truly reused end-to-end with zero allocation.
  • Replaced linear keyframe scan with binary search. getCurrentKeyframeLocation previously walked all keyframes from the start (O(n)). Now builds a cumulative end-time array and binary searches it (O(log n)). Meaningful for animations with many keyframes per bone.
  • Add overload method for per bone Texture/Render Type to support the entity as well.
  • Replaced per-frame DoubleSupplier lambda allocation for ANIM_TIME. A stable animTimeSupplier field closes over currentAdjustedTick; setMemoizedValue receives the same object reference every frame.
  • Replaced per-frame DoubleSupplier lambda allocation for ANIM_TIME, matching the fix in AzKeyframeExecutor.
  • Replaced four per-frame DoubleSupplier lambda/method-reference allocations in applyMolangQueries. LIFE_TIME, ACTOR_COUNT, TIME_OF_DAY, and MOON_PHASE now use stable supplier fields that read mutable double fields set before each call.
  • Updated to use pool-based pollRotX/Y/Z, pollPosX/Y/Z, pollSclX/Y/Z accessors from the new AzBoneAnimationQueue pool design.
  • Replaced point-scan lookup with binary search on curve parameter t. Rather than sampling the curve at 200 evenly-spaced points and scanning for the nearest two, the curve is now evaluated via binary search on t (20 iterations), exploiting the monotonically increasing x-coordinate of well-formed animation curves. Converges to the same result with zero heap allocation.
  • Added translateMatrixInPlace(Matrix4f, Vector3f). Mutates the matrix directly, for call sites that already own the matrix and don't need the original preserved.
  • Removed getPoints(int). No longer needed now that evaluateAtTime handles all call sites.

Added

  • Added hidden bone early-out matching AzModelRenderer, before pushPose and all transform calls.
  • Added scratch AzKeyframeLocation field. The single instance is reused across all getAnimationPointAtTick calls via .set(), eliminating one record allocation per axis per bone per frame.
  • Added prepareFrame() method. Clears all pool presence flags before the keyframe executor writes new values each frame, preventing stale values from partially-animated prior frames bleeding through.
  • Added boneAnimationQueueCache.prepareFrame() call before stateMachine.update() in the per-frame update order.
  • Added reusable scratch fields. Four Vector2d fields replace the per-call control point allocations in buildBezierCurve, and two scratch Vector2d fields are passed into CubicBezierCurve.evaluateAtTime for the binary search iterations.
  • Added evaluateAtTime(double, Vector2d, Vector2d). Zero-allocation curve evaluation using binary search on t, accepting caller-provided scratch vectors. Replaces the allocation-heavy getPoints(int) approach.
  • Configures bone hierarchy depth culling and animation tick-rate reduction, each with independent distance thresholds.
    • AzLodConfig.DISABLED — no LOD applied.
    • AzLodConfig.DEFAULT — automatically applied to all entity renderers unless overridden: bone LOD at 20 blocks (depth ≤ 3), animation LOD at 28 blocks (every 2 ticks).
  • Per-entity runtime manager. Walks the bone tree and calls setHidden(true) on bones exceeding the depth budget. Tracks a lodHidden flag so LOD-hidden bones can be restored when the entity returns to close range without affecting model-authored hidden bones.
  • Returns a shouldAnimate boolean to gate the full animation pipeline update, implementing tick-rate reduction for distant entities.
  • Added withLodConfig(AzLodConfig) builder method. Defaults to AzLodConfig.DEFAULT when not specified.
  • Wires AzLodManager into the render loop. LOD manager is instantiated per entity UUID and updated each frame before the pipeline runs. When shouldAnimate is false the model renders at its last computed pose, skipping all animation controller work.
  • Added lodHidden field with getLodHidden() / setLodHidden(boolean) accessors. Distinguishes LOD-driven visibility from model-authored dontRender flags. Propagated through deepCopy().