So i just worked on this for the last i dunno 2 or 3 days and figured id post it as it is a bit different to a simplified orbit camera method.

The below camera code takes a Target Game Objects Matrix… one typically created with the Matrix.CreateWorld method as its target to orbit around.

It takes a distance from the target and a height above the target as well as a angle of rotation.

The target can however be in any orientation and the camera will stay aligned with its forward plane.

Basically if you have a rotated world matrix you can hover over it and move up or down or orbit around its center as if your just orbiting over a flat area that is still.

Basically its a cylindrical style to target camera.

You can alternately do things like flyby’s at a specific height over a target that is moving and rotating in 3d space. *Shown in the below gif. The red green blue grid is actually still, its just a static grid aligned to the x y z world space system coordinates. While the surface is being tumbled around.*

```
Matrix OrbitAtHeightAroundTargetForward(Matrix target, float ForwardOrbitallRotation, float DistanceFromTarget, float zHeightAboveTarget)
{
float flip = -1; // quick fix think my model is upside down
var targetAxisHeightOffset = target.Forward * zHeightAboveTarget;
var targetPos = target.Translation; // yes this is intentional, see position.
Matrix axisTransformation = target * Matrix.CreateFromAxisAngle(target.Forward, ForwardOrbitallRotation);
// i don't think this can happen anymore now so its probably redundant.
float proximityToGimblePointRight = Math.Abs(Vector3.Dot(axisTransformation.Right, target.Forward));
var positionalDistanceOffset = Vector3.Lerp(axisTransformation.Right, axisTransformation.Up, proximityToGimblePointRight) * DistanceFromTarget;
var position = targetPos + positionalDistanceOffset + targetAxisHeightOffset;
var gimbleSmothingLookAtOffset = Vector3.Zero;
if (DistanceFromTarget < .5f)
gimbleSmothingLookAtOffset = (1f * flip * target.Forward + 2f * target.Left + 1f * target.Up) * .1f * (.5f - DistanceFromTarget);
var toTarget = (targetPos + gimbleSmothingLookAtOffset) - position;
var lookUp = flip * target.Forward;
return Matrix.CreateWorld(position, toTarget, lookUp);
}
```

I also made this one that just orbits the target it also stays with the target rotation.

It can offset the orbit so it can orbit over it in the full 360, but the height variable doesn’t make much sense to use with this so i yanked it out.

```
Matrix OrbitAroundTarget(Matrix target, float ForwardOrbitallRotation, float UpAxisRotation, float DistanceFromTarget)
{
float flip = -1; // quick fix
var Target = target * Matrix.CreateFromAxisAngle(target.Up, UpAxisRotation); // order matters its not commutative.
var targetPos = Target.Translation; // yes this is intentional, see position.
Matrix axisTransformation = Target * Matrix.CreateFromAxisAngle(Target.Forward, ForwardOrbitallRotation);
float proximityToGimblePointRight = Math.Abs(Vector3.Dot(axisTransformation.Right, Target.Forward));
var positionalDistanceOffset = Vector3.Lerp(axisTransformation.Right, axisTransformation.Up, proximityToGimblePointRight) * DistanceFromTarget;
var position = targetPos + positionalDistanceOffset;
var gimbleSmothingLookAtOffset = Vector3.Zero;
if (DistanceFromTarget < .5f)
gimbleSmothingLookAtOffset = (1f * flip * Target.Forward + 2f * Target.Left + 1f * Target.Up) * .1f * (.5f - DistanceFromTarget);
var toTarget = (targetPos + gimbleSmothingLookAtOffset) - position;
var lookUp = flip * Target.Forward;
return Matrix.CreateWorld(position, toTarget, lookUp);
}
```