DonBruce64 / MinecraftTransportSimulator

A Minecraft mod that adds planes and automobiles with realistic physics!
Other
109 stars 60 forks source link

Allowed for more complex VM Math #1640

Closed DrprofLuigi closed 1 year ago

DrprofLuigi commented 1 year ago

This PR adds trig functions as well as square rooting and division to VM math. This also adds an 'invert' boolean field to animations (that is only used in VMs for now)

In the following expressions, 'MV' is modifiedValue or the 'running total' of the VM. V is the input variable value, [X, Y, Z] is the axis, and [x, y, z] is the centerPoint.

[Redacted Translation changes, see later comment]

The trig functions utilize the 'rotation' animationType.

The output is simply:

MV * (Xsin(V + x) Ycos(V + y) + Ztan(V + z)) (inputs in degrees)

When inverted, the trig functions are swapped to their inverses (sine becomes arcsine, etc.).

There are internal conversions in the code to keep radians in their place.

This picture shows the test values, and I tested it fairly thoroughly: 2023-05-26_23 32 00

Here are the VMs that produced the above output:


            "variable": "clock",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 1, 0]
                },
                {
                    "animationType": "inhibitor",
                    "variable": "clock",
                    "clampMin": 1,
                    "clampMax": 360
                },
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                }
            ]
        },
        {
            "variable": "clock_sin",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "rotation",
                    "variable": "clock",
                    "centerPoint": [0, 0, 0],
                    "axis": [1, 0, 0]
                }
            ]
        },
        {
            "variable": "clock_cos",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "rotation",
                    "variable": "clock",
                    "centerPoint": [0, 0, 0],
                    "axis": [0, 1, 0]
                }
            ]
        },
        {
            "variable": "clock2",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0.01, 0]
                },
                {
                    "animationType": "inhibitor",
                    "variable": "clock2",
                    "clampMin": -1,
                    "clampMax": 2
                },
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, -1]
                }
            ]
        },
        {
            "variable": "clock2_asin",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "rotation",
                    "variable": "clock2",
                    "centerPoint": [0, 0, 0],
                    "axis": [1, 0, 0],
                    "invert": true
                }
            ]
        },
        {
            "variable": "clock2_acos",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "rotation",
                    "variable": "clock2",
                    "centerPoint": [0, 0, 0],
                    "axis": [0, 1, 0],
                    "invert": true
                }
            ]
        },
        {
            "variable": "test",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 5]
                }
            ]
        },
        {
            "variable": "test2",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "translation",
                    "variable": "test",
                    "axis": [1, 0.5, 0]
                }
            ]
        },
        {
            "variable": "test3",
            "animations": [
                {
                    "animationType": "translation",
                    "variable": "unuisbest",
                    "axis": [0, 0, 1]
                },
                {
                    "animationType": "translation",
                    "variable": "test",
                    "axis": [1, 0.3333, 0]
                }
            ]
        }```
DrprofLuigi commented 1 year ago

After thinking about it for a moment, I realize the 'invert' tag for the translation animation is fairly redundant.

A cleaner way to do it is to use the following for the translation logic.

If X != 0 and Y !=0, then the output is:

MV (X V^Y)

This allows for division by setting Y to -1, and allows for simple squaring and rooting. This should also keep things backwards-compatible because iirc everyone that uses VMs to multiply uses an axis of [X, 0, 0] This would eliminate the invert tag from being used in the translation case altogether.

It is also unlikely that someone would want to do MV * (X * V^0) since that is just multiplying by a constant (which could be done easily by just multiplying by a constant-defined variable), so using Y = 0 as a backwards-compatible case shouldn't be an issue.

I would ask the MTS discord to make sure there aren't any sloppy VM multiplications that may get messed up. After talking to Laura, this seems to be the case, but it would be good to confirm.