The Starport
  • Categories
  • Recent
  • Users
  • Groups
  • Starport Blog
  • Knowledge Base
  • The Forge
  • Discord
  • Register
  • Login

Rot Matrix Formula

Scheduled Pinned Locked Moved Freelancer-related Programming
17 Posts 3 Posters 19.5k Views
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #5

    **That will possibly work, any chance you have the formula behind it? My asm is very rusty, it’s been over 13 years since I’ve done any assembly coding. I have to convert it both directions, ie from the matrix to rot then back to the matrix after the user adjusts the values….

    Much appreciated Adoxa! Thats half of the puzzle ;)**

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #6

    **I just found another use for it…

    In DFM files, there is a node called ‘Bone To Root’, it turns out after writing the scripter for it that it is a 3x4 matrix. It is normally an identity matrix so in this case I may be able to use the DX matrix decomposition command.

    So far I have scripters for the DFM nodes of…
    Fractions
    Tristrip_Indices
    Point_Indices
    UV0_Indices
    Points
    Point_Bone_First
    Point_Bone_Count
    Bone_ID_Chain
    Bone_Weight_Chain
    Vertex_Normals
    UV0
    Bone To Root

    If I am able to build the matrix conversion routine I will start working on creating a whole skeletal export routine that exports the entire .dfm as a single script, hopefully as a MS3D file.

    Created by my scripter…

    [Bone_To_Root]
    bone = 1.000000, 0.000000, 0.000000 ; 0
    bone = 0.000000, 1.000000, 0.000000 ; 1
    bone = 0.000000, 0.000000, 1.000000 ; 2
    bone = 0.000000, 0.000000, 0.000000 ; 3
    
    ```**
    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #7

    I tried doing it in C, but must’ve got it wrong, 'cos it didn’t work, which is why I stuck with the straight asm rip. However, I’ve just had another go and seem to have got it right, this time.

      if (dist <= 1.0f/524288.0f)
      {
        vec.x = atan2f( -z.y, y.y );
        vec.y = atan2f( -x.z, dist );
        vec.z = 0;
      }
      else
      {
        vec.x = atan2f(  y.z, z.z );
        vec.y = atan2f( -x.z, dist );
        vec.z = atan2f(  x.y, x.x );
      }
    ```There's an exported function in common.dll going the other way, can you use that?
    
    

    // ?EulerMatrix@@YA?AVMatrix@@ABVVector@@@Z
    Matrix EulerMatrix( const Vector& );

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #8

    I’ll test it out tonight after work. BTW, what is the dist comparison for? For the orientation there shouldn’t be any dist part of it since it is for the hardpoint rotation…

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #9

    **The second one worked with some adjustments. Turns out I had already figured out this formula over 15 years ago to convert rectangular to polar coordinates. I tested it with my original routine and it came up with the correct values as well. This means I already have the routine to convert it back into a matrix but just didn’t know it.

    Since the matrix uses 9 values and the routine above only uses 5 of them, I will need to work on it a bit more to include all of the values. I will dig back into my college textbooks on trig and see if it can help with the rest of the entries.

    Thanks, you taught an old dog a new trick he should have remembered :P**

    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #10

    Lancer Solurus wrote:
    I’ll test it out tonight after work. BTW, what is the dist comparison for? For the orientation there shouldn’t be any dist part of it since it is for the hardpoint rotation…

    Dist is just what I called it, since that’s what it looked like - hypot might be better. I just blindly copied what the save game routine does.

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #11

    **After doing tons of testing with the formula you provided (thanks alot btw) it appears that HardCMP is shortening the rotations to whole numbers and it’s not in the same order.

    This is the final coding I worked out based on your initial help…

    rd=180.0f/3.141592654f; // radians to degrees
    
    // set 1
    ax=rd*atan2f(yz,zz);
    ay=rd*atan2f(-xz,zz);
    az=rd*atan2f(-yx,xx);
    
    // set 2
    ax=rd*atan2f(-zy,yy);
    ay=rd*atan2f(zx,xx);
    az=rd*atan2f(xy,yy);
    
    

    Once I can get these combined properly, it will contain the entire matrix layout and it will be a simple matter of using sin and cos to rebuild the matrix.**

    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #12

    There’s also an Excel spreadsheet that converts rotation to orientation.

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #13

    It’s saying it’s password protected in both the xl viewer and MS Works…

    1 Reply Last reply
    0
  • adoxaA Offline
    adoxaA Offline
    adoxa
    wrote on global:last_edited_by,
    #14

    Find attached a version without the protection (gee, that new xml format makes it easy to remove).

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #15

    **Perfect, thanks! That will give me something to check it by…

    This is psuedo code Im using atm to work with…

    public final void rotX(double angle) { 
    double c = Math.cos(angle);    double s = Math.sin(angle);
    m00 = 1.0;    m01 = 0.0;    m02 = 0.0;
    m10 = 0.0;    m11 = c;    m12 = s;		yy,yz
    m20 = 0.0;    m21 = -s;    m22 = c;		-zy,zz
    }
    public final void rotY(double angle) {
    Double c = Math.cos(angle);    double s = Math.sin(angle);
    m00 = c;    m01 = 0.0;    m02 = -s;		xx,-xz
    m10 = 0.0;    m11 = 1;    m12 = 0.0;
    m20 = s;    m21 = 0.0;    m22 = c;		zx,zz
    }
    public final void rotZ(double angle) {
    Double c = Math.cos(angle);    double s = Math.sin(angle);
    m00 = c;    m01 = s;    m02 = 0.0;		xx,xy
    m10 = -s;    m11 = c;    m12 = 0.0;		-yx,yy
    m20 = 0.0;    m21 = 0.0;    m22 = 1.0;
    }
    
    ```**
    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #16

    I also found 4 other nodes that can use this code, the Fix, Rev, Pris and Sphere nodes stored in the Cons section. Once I get it to convert from matrix to rot and back to matrix with no loss, I will post the code for it.

    1 Reply Last reply
    0
  • L Offline
    L Offline
    LancerSolurus
    wrote on global:last_edited_by,
    #17

    **Well I finally succeeded in converting the matrix to rotation angles. I ended up scraping all of the code from before and simply did it thru matrix decomposition, which is where I started out initially.

    I have also managed to get it to show the same as it appears in Hard CMP and it’s a much higher precision. HCMP rounds off the rotation values to whole numbers.

    I am also able to convert back into the matrix format without any changes to it. The code is still buried in the orientation edit routine in the CMP Editor, I will post it in full form once it is relegated to subroutines. It does require use of DX though unless you are a math guru and can roll your own matrix conversion code. You will see what I mean once the code is posted.

    The code uses quaternions but does not require understanding of them. I used those for 2 reasons, no gimbal lock and DX supports only them for decompositions.

    A block diagram of the way it works is….
    Decompose the FL orientation matrix (3 by 3) by converting it to a 4 x 4 matrix first using D3DXMatrixDecompose.
    Convert the Quat to Euler angles. Only X and Y needed, the Z rot is either 0 or 180 degrees, if it’s 180 it requires a special case handling for each + and - states. -90 degrees X also swaps the Y and Z value, simply switching them is enough.
    Converting back to quaternions requires simply pocessing the angles in reverse order of the first conversion.
    Then simply do a D3DXMatrixTransformation back into a matrix and store it.

    Anyways, the code will show how to do it without you needing to fully understand what I did, feel free to dig into the math if you want.**

    1 Reply Last reply
    0

  • Story Mission level requirement
    C
    CommanderArgelo
    0
    11
    52

  • Crash Offsets
    J
    josbyte
    0
    231
    251.4k

  • Capital ships shield collision detection
    C
    CommanderArgelo
    0
    3
    17

  • Dropping a phantomloot cargo from an NPC
    C
    CommanderArgelo
    0
    5
    26

  • Incorrect Shield Value on HUD
    C
    CommanderArgelo
    0
    4
    19

  • @Adoxa - Wheel Scroll plugin improvements
    AingarA
    Aingar
    0
    3
    20

  • Release: Advanced Renderer v. 1.1 beta 1
    S
    SWAT_OP-R8R
    3
    50
    428

  • German Mod Tutorials? 2024 Mod Tutorial?
    S
    SWAT_OP-R8R
    0
    18
    66
  • First post
    Last post
0
  • Categories
  • Recent
  • Users
  • Groups
  • Starport Blog
  • Knowledge Base
  • The Forge
  • Discord