I figured out a partial solution. It's not perfect, but when facing near the orbit path, it works well. anything too far off the "orbit plane" will cause a drifting effect. This is not a big issue, so for now it will do. Here is the code I am using:
void AUTOPILOT::OrbitPlanet(GAMEENGINE *GE,SHIP *Ship){
if (OrbitData.OrbitEstablished){
HUGEVECTOR3 hv=Ship->V_Location;//store this value for velocity calc later
D3DXQUATERNION rot;
D3DXMATRIX tmp;
//set up the rotation quaternion for orbit speed
D3DXQuaternionRotationYawPitchRoll(&rot, OrbitData.OrbitRate*float(GE->MyCamera.fTBF)/10.0f, 0, 0);//1000.0f
D3DXQuaternionMultiply(&OrbitData.OrbitPosition, &OrbitData.OrbitPosition, &rot);
D3DXMatrixRotationQuaternion(&tmp,&OrbitData.OrbitPosition);
tmp(3,0)=tmp(3,1)=tmp(3,2)=0;
D3DXMatrixInverse(&tmp,0,&tmp);
D3DXVECTOR3 pos(0,0,1);
D3DXVec3TransformCoord(&pos,&pos,&tmp);
Ship->V_Location=pos;
Ship->V_Location*=OrbitData.Radius;
Ship->V_Location+=OrbitData.Center;
//capture the yaw/pitch input
if (MyInput.mousestate.rgbButtons[1]>0){
D3DXMATRIX la;
HUGEVECTOR3 hv=Ship->V_Location+GE->MyCamera.m_viewDir*1000000.0f;
hv-=OrbitData.Center;
OrbitData.CameraLookAt=hv.Normalize();
OrbitData.CameraLookAt*=float(hv.Length);
OrbitData.LookAtLength=float(hv.Length);
D3DXMatrixLookAtLH(&la,&D3DXVECTOR3(0,0,0),&OrbitData.CameraLookAt,&OrbitData.Up);
D3DXQuaternionRotationMatrix(&OrbitData.LookAtQuat,&la);
D3DXQuaternionNormalize(&OrbitData.LookAtQuat,&OrbitData.LookAtQuat);
}
D3DXQuaternionMultiply(&OrbitData.LookAtQuat, &OrbitData.LookAtQuat, &rot);
D3DXMatrixRotationQuaternion(&tmp,&OrbitData.LookAtQuat);
tmp(3,0)=tmp(3,1)=tmp(3,2)=0;
D3DXMatrixInverse(&tmp,0,&tmp);
pos=D3DXVECTOR3(0,0,1);
D3DXVec3TransformCoord(&pos,&pos,&tmp);
HUGEVECTOR3 hv2=pos*OrbitData.LookAtLength;
hv2+=OrbitData.Center;
hv2-=Ship->V_Location;
GE->MyCamera.m_viewDir=hv2.Normalize();
D3DXMatrixLookAtLH(&tmp,&D3DXVECTOR3(0,0,0),&GE->MyCamera.m_viewDir,&OrbitData.CameraUp);
D3DXQuaternionRotationMatrix(&GE->MyCamera.m_orientation,&tmp);
//capture the roll input
if (abs(GE->MyCamera.RateRoll)>0.001f){
D3DXMATRIX la;
OrbitData.CameraUp=GE->MyCamera.m_yAxis;
HUGEVECTOR3 hv=Ship->V_Location+GE->MyCamera.m_viewDir*1000000.0f;
hv-=OrbitData.Center;
OrbitData.CameraLookAt=hv.Normalize();
OrbitData.CameraLookAt*=float(hv.Length);
OrbitData.LookAtLength=float(hv.Length);
D3DXMatrixLookAtLH(&la,&D3DXVECTOR3(0,0,0),&OrbitData.CameraLookAt,&OrbitData.Up);
D3DXQuaternionRotationMatrix(&OrbitData.LookAtQuat,&la);
D3DXQuaternionNormalize(&OrbitData.LookAtQuat,&OrbitData.LookAtQuat);
}
//calculate the velocity
hv-=Ship->V_Location;
D3DXVECTOR3 veldir=-hv.Normalize();
Ship->V_velocity=veldir;
Ship->V_velocity*=hv.Length *1000.0/GE->MyCamera.fTBF;
}
else{//not in orbit yet
UINT wpSize=WP.size();
if (wpSize>0){
//continue to WPs until the next to last one is reached. then delete the last 2 WPs and make wpSize=0;
}
if (wpSize==0){//at the end of the wp list. create orbit trajectory
OrbitData.OrbitEstablished=true;
//D3DXVec3Cross(&tmpv,&(Range0[i].vert[px-1][py-1].v-Range0[i].vert[px][py].v),&(Range0[i].vert[px][py-1].v-Range0[i].vert[px][py].v));
D3DXVECTOR3 ShipLoc1,ShipLoc2,Heading;
ShipLoc1=(Ship->V_Location-OrbitData.Center).Normalize();
OrbitData.Radius=float((Ship->V_Location-OrbitData.Center).GetLength());
ShipLoc1*=OrbitData.Radius;//these values are only to get the "Up" vector
Heading=Ship->V_velocity.Normalize();
OrbitData.OrbitSpeed=Ship->V_velocity.Length;
ShipLoc2=ShipLoc1+Heading*float(OrbitData.OrbitSpeed);
D3DXVec3Cross(&OrbitData.Up,&ShipLoc2,&ShipLoc1);//********** i think the direction is correct....?????
D3DXMATRIX la;
D3DXVec3Normalize(&ShipLoc1,&ShipLoc1);
D3DXVec3Normalize(&OrbitData.Up,&OrbitData.Up);
D3DXMatrixLookAtLH(&la,&D3DXVECTOR3(0,0,0),&ShipLoc1,&OrbitData.Up);
D3DXQuaternionRotationMatrix(&OrbitData.OrbitPosition,&la);
D3DXQuaternionNormalize(&OrbitData.OrbitPosition,&OrbitData.OrbitPosition);
OrbitData.OrbitRate=atan2(float(OrbitData.OrbitSpeed),OrbitData.Radius);
OrbitData.CameraUp=GE->MyCamera.m_yAxis;
HUGEVECTOR3 hv=Ship->V_Location+GE->MyCamera.m_viewDir*1000000.0f;
hv-=OrbitData.Center;
OrbitData.CameraLookAt=hv.Normalize();
OrbitData.CameraLookAt*=float(hv.Length);
OrbitData.LookAtLength=float(hv.Length);
D3DXMatrixLookAtLH(&la,&D3DXVECTOR3(0,0,0),&OrbitData.CameraLookAt,&OrbitData.Up);
D3DXQuaternionRotationMatrix(&OrbitData.LookAtQuat,&la);
D3DXQuaternionNormalize(&OrbitData.LookAtQuat,&OrbitData.LookAtQuat);
}
}
}
This is the entire function. It includes initializing the orbit and maintaining it. Even though this function says AUTOPILOT, I haven't included the auto functionality using waypoints-- that comes later.
If ANYONE has a better way, I would like to know what it is..... I've looked over and over again for example code, but I get nothing anywhere near what I am trying to do.