Jump to content

QuaternionD.LookRotation MissingMethodException


Recommended Posts

I'm getting a weird thing where the *compiler* claims a method exists that at *runtime* it throws an exception on and says it does not exist.

It's this:

System.MissingMethodException: Cannot find the requested method.

  at (wrapper managed-to-native) UnityEngine.QuaternionD:INTERNAL_CALL_LookRotation (Vector3d&,Vector3d&)
  at UnityEngine.QuaternionD.LookRotation (Vector3d forward, Vector3d upwards) [0x00000] in <filename unknown>:0 
  at kOS.Function.FunctionHeading.Execute (kOS.SharedObjects shared) [0x00000] in <filename unknown>:0 
  at kOS.Function.FunctionBase.Execute (kOS.Safe.SafeSharedObjects shared) [0x00000] in <filename unknown>:0 
  at kOS.Safe.Function.FunctionManager.CallFunction (System.String functionName) [0x00000] in <filename unknown>:0 
  at kOS.Safe.Execution.CPU.CallBuiltinFunction (System.String functionName) [0x00000] in <filename unknown>:0 
  at kOS.Safe.Compilation.OpcodeCall.StaticExecute (ICpu cpu, Boolean direct, System.Object destination, Boolean calledFromKOSDelegateCall) [0x00000] in <filename unknown>:0 
  at kOS.Safe.Compilation.OpcodeCall.Execute (ICpu cpu) [0x00000] in <filename unknown>:0 
  at kOS.Safe.Execution.CPU.ExecuteInstruction (IProgramContext context, Boolean doProfiling) [0x00000] in <filename unknown>:0 

According to the compiler, UnityEngine.QuaternionD.LookRotation emphatically does exist, with those exact arguments.  But at runtime it does not.  I'm not sure what "INTERNAL_CALL" means, but I'm guessing it means "this isn't implemented in the normal C# way" or something like that.  (i.e. maybe it's dropping down into some other language for that part, or doing something implemented in raw machine language instead of in the MSIL's opcodes?)

This came about because I was trying to replace all our Quaternion usages with QuaternionD's because when working with large vectors (i.e. the distance from Kerbin to Duna, for example), the 32-bit precision of Quaternion's was beginning to multiply into rather big errors after several operations of using them to rotate those big vectors.  But it looks like not everything that was implemented for Quaternion got re-implemented for QuaterionD''s.

Am I going to have to resort to running my own matrix multiplications to perform rotations or is there some other solution to this?

 

Link to comment
Share on other sites

26 minutes ago, Steven Mading said:

Am I going to have to resort to running my own matrix multiplications to perform rotations or is there some other solution to this?

Normalizing before rotating (and then denormalizing) may solve precision issues for float quat. Exception text indeed means, that method is lacking implementation in some native library.

Link to comment
Share on other sites

6 hours ago, Boris-Barboris said:

Normalizing before rotating (and then denormalizing) may solve precision issues for float quat. Exception text indeed means, that method is lacking implementation in some native library.

Well, I was hoping I didn't have to do that (normalize, rotate, then un-normalize) but it looks like it's the only good way.  I really don't want to re-implement Quaternions because....ugh....Complex Numbers.

Link to comment
Share on other sites

I'm finding a suspiciously large number of these missing extern methods in QuaternionD.  I've been trying to build our own replacements for them, but each time I implement one, that just makes me find another one is missing the next time I run.

 

So far, all the following are ones I've had this problem with and I had to re-implement them myself:

QuaternionD.LookRotation()

QuaternionD.FromToRotation()

QuaternionD.eulerAngles

 

I'm starting to wonder if the real problem might be one of the following possibilities:

1 - QuaternionD is part of some refactor that never got completed and I shouldn't really be using it at all.

2 - QuaternionD depends on an additional DLL I'm meant to be compiling with that I'm neglecting to add to the build or runtime environment.

3 - QuaternionD is designed for KSP-only and modders aren't supposed to be using it.

4- QuaternionD is only used by KSP in just a few places here and there, and only the parts that were needed by SQUAD got implemented, with everything else left as an extern method because it was meant as a "TODO" for later if need-be.

If it's any of the above, then I probably shouldn't be trying to implement my own versions of these missing methods.  If it's 1, 3, or 4, then I shouldn't be using QuaternionD at all and I should just find ways to get by without it.  If it's 2, then I should be trying to figure out what I'm missing from my build or runtime environment.

(Note, despite being in the UnityEngine namespace, QuaternionD seems to actually be part of the KSPUtils DLL file, not the UnityEngine DLL file.)

 

Link to comment
Share on other sites

4 minutes ago, Steven Mading said:

If it's any of the above, then I probably shouldn't be trying to implement my own versions of these missing methods

I'd bet on 4.
Also, I think float quaternion's precision is enough, and you're probably doing something bizarre or wrong if you run into problems.

Edited by Boris-Barboris
Link to comment
Share on other sites

11 minutes ago, Boris-Barboris said:

I'd bet on 4.
Also, I think float quaternion's precision is enough, and you're probably doing something bizarre or wrong if you run into problems.

I've done tests where using a Quaternion to rotate a vector produces enormous errors if the vector has a large magnitude, but works fine if you try to rotate the unit-vector version of the vector instead, and then multiply the magnitude of the vector back to full size again afterward.  When I found QuaternionD I was sort of hoping it would avoid me having to perform those extra steps but it really looks like QuaternionD is sort of half "not there" so this technique won't work well.  It looks like I will have to resort to the normalize, rotate, denormalize technique.  It's not impossible, but it's a big edit because of how many places we perform vector rotations that I will have to replace with calls to some wrapper method instead that does those steps.

 

 

Edited by Steven Mading
Link to comment
Share on other sites

27 minutes ago, Steven Mading said:

not

You can always just explicitly state in docs that user should normalize large vectors. Norm denorm every time blindly is indeed quite ugly, I think it's better to offload the decision to someone, who knows the context - end user.

Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...