Sometimes I read the manual and think "Wow, this doesn't make sense, not intuitive. Vectors are points?". But your explanation helped me fix the test case:
obj = {Cos[#/50 Pi], Sin[#/50 Pi], 0} & /@ Range[110];
viewPt = 2 {1 + Sin[#/20 Pi], 0, Cos[#/20 Pi]} & /@ Range[40];
viewVec = With[{tan = #[[3]] - #[[1]] & /@
RotateRight[Partition[viewPt, 3, 1, 1]]},
Divide[# - 2 Cross[#, {0, 1, 0}] & /@ tan, 5]];
viewNorm = Cross[#, {0, 1, 0}] & /@ viewVec;
gOBJ = {
Darker@Red, Tube[{0, 0, 1/2} + # & /@ obj, 1/10],
Darker@Blue, Tube[{0, 0, -1/2} + # & /@ obj, 1/10],
Blend[{Orange, Brown}], Sphere[{2, 0, 0}],
Blend[{Brown, Yellow}], Tube[obj, 1/2],
Black,
Sphere[#/2 + {1, 0, 0}, 1/10] & /@
viewPt[[{-7, -5, -1, 5, 13, 19, 23, 25}]]
};
Graphics3D[{
Red, MapThread[Arrow[{#1, #1 + #2}] &, {viewPt, viewVec}],
Blue, MapThread[Arrow[{#1, #1 + #2}] &, {viewPt, viewNorm}],
gOBJ}, ViewVertical -> {0, 0, 1}, Boxed -> False,
ViewPoint -> 3 {0, 1, 1}]

ListAnimate[Graphics3D[gOBJ,
ViewVector -> {viewPt[[#]], viewPt[[#]] + viewVec[[#]]},
ViewVertical -> viewNorm[[#]],
ViewAngle -> Pi/3, Boxed -> False] & /@ Range[40]]

Turns out ViewVertical needs to be set, see also this wikipedia article on Frenet-Serret perspective. This is still along way from having a meebits character walking around the surface of an elliptic curve and looking around at the scenery.