MerlinofMines / EasyCommands

Github Repository for Ingame Scripts built by MerlinofMines. Uses MDK to Deploy to SpaceEngineerse
GNU General Public License v3.0
8 stars 3 forks source link

Add WorldMatrix property and Matrix operations #158

Closed jgersti closed 2 years ago

jgersti commented 2 years ago

The only major stumpling block to replicate most simple standalone scripts is the ability to transform coordinates and directions into usable information via the world transformation (in reference to a control block) encode in the world matrices.

The most notable example is controlling gyroscopes in reference to the controller orientation (instead of its own).

Since the proper world matrix to use is usually the one obtained from the cockpit/remote these transformation cannot really performed on the block which is manipulated.

As a first step into that direction I would propose to add a way to access and use world matrices. Support for arbitrary matrices can be added further down the line.


Since the matrices are 4x4 but vector has 3 components there is no difference between position vectors (4th component would be 1 or a scaling factor) and directional vectors (4th component would be 0), there are 2 different matrix multiplications (these are left multiplications by row vectors ?!?). Transform is for position vectors and TransformNormal is for directional vectors. Apart from the normal operations (+, -, *[matrix-matrix, scalar-matrix, matrix-scalar], / [matrix-scalar only]), the Transpose, Invert and Rescale (this is not the same a multiplying with a number!) operations are also important. These matrices also have apart from the usual access by element, the six cardinal direction and the Translation properties to access the (truncated) rows.


All in all this is a rather comprehensive feature request that would allow the (advanced) user to replace many simple script. For documentation the we should ask Whiplash141 if we can use Vector Transformation with World Matrices or just reference there for an explanation when to use what.

MerlinofMines commented 2 years ago

Can you describe specifically what you would expect to write as a script if you had this functionality? Like an example script of what you could do vs what you have to do right now?

jgersti commented 2 years ago

Right now we can do nothing of the sort since the information is simply not available.

I would like to replace simple scripts for gyro/subGrid/steering control

The simplest example is controling gyros relative to a cockpit/remote.

var rotationVec = new Vector3D(pitchSpeed, yawSpeed, rollSpeed);
// transform desired rotation speeds into world coordinates
var relativeRotationVec = Vector3D.TransformNormal(rotationVec, referenceWorldMatrix);

foreach (var g in gyroList)
{
    // transform rotation speeds from world to gyro coordinate system
    var transformedRotationVec = Vector3D.TransformNormal(relativeRotationVec, Matrix.Transpose(g.WorldMatrix));

  g.Pitch = (float)transformedRotationVec.X;
  g.Yaw = (float)transformedRotationVec.Y;
  g.Roll = (float)transformedRotationVec.Z;
  g.GyroOverride = true;
  g.GyroPower = power * 0.01f
}

For this example the world matrices and its transpose and TransformNormal would be needed. I imagine something like (where § is a placeholder for TransformNormal)

set myRot to ...
set refWM to "reference" block worldmatrix

set worldRot to myRot § refWM

for g in my gyros names
    set gyroWM to $g block worldmatrix
    set gyroRot to gyroWM § worldRot
    # set gyroRot to worldRot § transpose of gyroWM

    set $g gyro rotation to gyroRot
    set $g gyro power to 0.01f * gyroPower

Other examples are bit more involved.

MerlinofMines commented 2 years ago

Let's think about this one carefully, it could easily take up a lot of characters and would likely only be used by advanced users.

I think we would need to create a new primitive type for "matrix". We can then identify the appropriate uni and bi operand parameters. Not sure yet about syntax for creating matrix directly, but we can use a multi-dimensional collection and convert that to matrix (and vice versa).

Since scripts are parsed back to front, i'm not sure if that will cause issues for matrix multiplication. Will need to think through this.

Note that the gyro rotation can already be set to a vector, and that vector can be constructed based on the relative directional input (left/right/up/down) of the cockpit. A workaround for much of the desired behavior does exist, but perhaps it is more verbose than necessary.

Again, let's just make sure we have our ducks in a row before we try implementing this one, so we're happy & sure of it's scope and syntax before we get too far.

Thoughts?

jgersti commented 2 years ago

While experimenting a bit i found that the block orientations that are calculated in a rather convolited way are just the directions on the world matrix.

MerlinofMines commented 2 years ago

Ya I stole the actual code but it's returning directional vectors relative to the given block's orientation in works coordinates so you don't need to do the world matrix transformation yourself. We are missing the actual directional vector representing orientation in the Direction property, that sound be added. And there are likely still use cases that benefit from using the world matrix directly.

jgersti commented 2 years ago

with #169 this has a much lower priority now. If i find some time i will write some examples how the world transforms can be achieved with current means.

MerlinofMines commented 2 years ago

Perhaps we mark this is issue as "won't fix" for now and mark as resolved? Can be re-opened later if we decide it is merited?