Jump to content

Position Vessel loaded from ProtoVessel


Recommended Posts

I'm working on a plugin in which I need to spawn a Vessel from a previously saved ProtoVessel, but with the new orbit position and rotation.

I've tired to change these parameters on a spawned vessel with no effect: position and rotation stay the same as they were in the protovessel, no matter what.

If I try to set them on the protovessel itself, position is set correctly, but rotation, when I load the protovessel, changes again in a pattern I cannot understand.

Could anyone explain to me how to correctly set the precise position-rotation-orbit of a vessel? Any help is highly appreciated!

Link to comment
Share on other sites

You shouldn't need to set the rotation directly... Have a look at Orbit and OrbitDriver...

Set the orbit and use:


vessel.orbitDriver.pos = vessel.orbit.pos.xzy;
vessel.orbitDriver.vel = vessel.orbit.vel;

Link to comment
Share on other sites

I'll do as you recommend.

But I still can't understand how the orbit describing the movement of a point object which does not have a direction, may describe directions of the axes of the 3d-object which this point represents. I mean, the vessel's head may be directed anywhere, and the orbit will stay the same. Thus you cannot derive this direction from the given orbit. Am I missing something obvious?

Link to comment
Share on other sites

But I still can't understand how the orbit describing the movement of a point object which does not have a direction, may describe directions of the axes of the 3d-object which this point represents. I mean, the vessel's head may be directed anywhere, and the orbit will stay the same. Thus you cannot derive this direction from the given orbit. Am I missing something obvious?

No, you're right: the vessel's orbit doesn't have any meaning to the vessel's actual orientation. You can use Vessel.SetRotation to orient it in a particular way. Can you show a snippet of code demonstrating what you're trying to do and describing how it's wrong?

Link to comment
Share on other sites

OK, I've kinda "figured" out the orientation part.

The thing is: vessel.vesselTransform.rotation and vessel.protoVessel.rotation are not the same; orientation of a vessel is stored in its protoVessel with respect to some other reference frame. So, in order to set a correct orientation of a vessel upon its loading from protoVessel, one needs to combine the desired rotation with the rotation between reference frames:


//these values are predefined
ConfigNode config_node;
Quaternion desired_rotation;

//get needed rotation quaternions
Quaternion vessel_rot = this.vessel.vesselTransform.rotation;
[B]//it is essential to use BackupVessel() instead of vessel.protoVessel, because in general the latter does not store the current flight state of the vessel[/B]
Quaternion proto_rot = this.vessel.BackupVessel().rotation;

//recreate a protovessel from a config node
ProtoVessel pv = new ProtoVessel(config_node, FlightDriver.FlightStateCache);

//set protovessel rotation
[B]pv.rotation = proto_rot*vessel_rot.Inverse()*desired_rotation;[/B]

//load the vessel from protovessel
pv.Load(FlightDriver.FlightStateCache.flightState);

//check the rotation
Debug.Log(string.Format("desired rotation: {0}", desired_rotation.eulerAngles));
Debug.Log(string.Format("actual rotation: {0}", pv.vesselRef.vesselTransform.rotation.eulerAngles));

I still can't position the loaded vessel correctly with respect to the given orbit though. But the reason seems the same, so I'll dig more...

xEvilReeperx, unfortunately, I can't SetPosition() or SetRotation() of the pv.refVessel until it is fully loaded with FlightGlobals.ForceSetActiveVessel(pv.refVessel). And then it could be done only with a waiting coroutine, but this fails for an unknown reason: the coroutine just hangs after the first yield.

Edited by allista
Bug fix in the code snippet =^_^=
Link to comment
Share on other sites

And the trick with positioning was to (shame on me) carefully read the API docs for Orbit class:

NOTE: All Vector3d's returned by Orbit class functions have their y and z axes flipped. You have to flip these back to get the vectors in world coordinates.

Switching the y and z components of the vector difference between the vessel.findWorldCenterOfMass() and the desired_position gave me the correct position of the spawned vessel:


Orbit this_orb = vessel.orbit;
Orbit new_orb = new Orbit();

Vector3 d_pos = desired_position-vessel.findWorldCenterOfMass();
Vector3d new_orb_pos = this_orb.pos+new Vector3d(d_pos.x, d_pos.z, d_pos.y);

new_orb.UpdateFromStateVectors(new_orb_pos, this_orb.vel, this_orb.referenceBody, Planetarium.GetUniversalTime());

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...