All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.github.kosmx.bendylib.impl.IBendable Maven / Gradle / Ivy

The newest version!
package io.github.kosmx.bendylib.impl;

import net.minecraft.class_1159;
import net.minecraft.class_1160;
import net.minecraft.class_1162;
import net.minecraft.class_2350;
import net.minecraft.class_4581;
import net.minecraft.util.math.*;

/**
 * Bending methods.
 * Interface to be usable via Mixin
 */
public interface IBendable {

    /**
     * Applies the transformation to every position in posSupplier
     * @param bendAxis axis for the bend
     * @param bendValue bend value
     * @param posSupplier iterable positions
     * @return the used transformation matrix
     */
    default class_1159 applyBend(float bendAxis, float bendValue, IterableRePos posSupplier){
        class_1160 axis = new class_1160((float) Math.cos(bendAxis), 0, (float) Math.sin(bendAxis));
        class_4581 matrix3f = new class_4581(getBendDirection().method_23224());
        axis.method_23215(matrix3f);
        class_1159 transformMatrix = new class_1159();
        transformMatrix.method_22668();

        transformMatrix.method_22672(class_1159.method_24021(getBendX(), getBendY(), getBendZ()));
        transformMatrix.method_22670(axis.method_23626(bendValue));
        transformMatrix.method_22672(class_1159.method_24021(-getBendX(), -getBendY(), -getBendZ()));

        class_1160 directionUnit; //some temporarily variable;

        Plane basePlane = getBasePlane();
        Plane otherPlane = getOtherSidePlane();

        directionUnit = this.getBendDirection().method_23955();
        directionUnit.method_4951(axis);
        //parallel to the bend's axis and to the cube's bend direction
        Plane bendPlane = new Plane(directionUnit, new class_1160(this.getBendX(), this.getBendY(), this.getBendZ()));
        float halfSize = bendHeight()/2;

        boolean bl = getBendDirection() == class_2350.field_11036 || getBendDirection() == class_2350.field_11035 || getBendDirection() == class_2350.field_11034;

        posSupplier.iteratePositions(iPosWithOrigin -> {
            class_1160 newPos = iPosWithOrigin.getOriginalPos();
            float distFromBend = bl ? -bendPlane.distanceTo(newPos) : bendPlane.distanceTo(newPos);
            float distFromBase = basePlane.distanceTo(newPos);
            float distFromOther = otherPlane.distanceTo(newPos);
            double s = Math.tan(bendValue/2)*distFromBend;
            class_1160 x = getBendDirection().method_23955();
            if(Math.abs(distFromBase) < Math.abs(distFromOther)){
                x.method_4942((float) (-distFromBase/halfSize*s));
                newPos.method_23846(x);
                class_1162 reposVector = new class_1162(newPos);
                reposVector.method_22674(transformMatrix);
                newPos = new class_1160(reposVector.method_4953(), reposVector.method_4956(), reposVector.method_4957());
            }
            else {
                x.method_4942((float) (-distFromOther/halfSize*s));
                newPos.method_23846(x);
            }
            iPosWithOrigin.setPos(newPos);
        });

        return transformMatrix;
    }

    class_2350 getBendDirection();

    /**
     * center x
     * @return x
     */
    float getBendX();
    float getBendY();
    float getBendZ();
    Plane getBasePlane();
    Plane getOtherSidePlane();

    /**
     * There are more efficient ways to calculate it
     * Try to override it (If you have size)
     * @return the size of the cube
     */
    default float bendHeight(){
        return this.getBasePlane().distanceTo(this.getOtherSidePlane());
    }

    /**
     * A plane in the 3d space
     * form a vector and a position
     * for distance calculation
     */
    class Plane{
        final class_1160 normal;
        final float normDistance;

        public Plane(class_1160 normal, class_1160 position){
            this.normal = normal.method_23850();
            this.normal.method_4952();
            this.normDistance = -normal.method_4950(position);
        }

        /**
         * This will return with the SIGNED distance
         * @param pos some pos
         * @return the distance between the pos and this plane
         */
        public float distanceTo(class_1160 pos){
            return normal.method_4950(pos) + normDistance;
        }

        /**
         * This will return with the SIGNED distance
         * @param otherPlane some plane
         * @return the distance between the two planes. 0 if not parallel
         */
        public float distanceTo(Plane otherPlane){
            class_1160 tmp = this.normal.method_23850();
            tmp.method_4951(otherPlane.normal);
            //if the lines are parallel
            if(tmp.method_4950(tmp) < 0.01){
                return this.normDistance + this.normal.method_4950(otherPlane.normal) * otherPlane.normDistance; //if the normals point to the opposite direction
            }
            else {
                return 0;
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy