Index: code/camera/camera.cpp
===================================================================
--- code/camera/camera.cpp	(revision 9426)
+++ code/camera/camera.cpp	(working copy)
@@ -11,6 +11,7 @@
 #include "ship/ship.h" //compute_slew_matrix
 #include "graphics/font.h"
 #include "mod_table/mod_table.h"
+#include "globalincs/linklist.h"
 
 //*************************IMPORTANT GLOBALS*************************
 float VIEWER_ZOOM_DEFAULT = 0.75f;			//	Default viewer zoom, 0.625 as per multi-lateral agreement on 3/24/97
@@ -110,6 +111,22 @@
 
 	object_host = object_h(objp);
 	object_host_submodel = n_object_host_submodel;
+	set_custom_position_function(NULL);
+	set_custom_orientation_function(NULL);
+	if(n_object_host_submodel > 0) {
+		if(objp->type == OBJ_SHIP) {
+			ship_subsys* ssp = GET_FIRST(&Ships[objp->instance].subsys_list);
+			while ( ssp != END_OF_LIST( &Ships[objp->instance].subsys_list ) ) {
+				if(ssp->system_info->subobj_num == n_object_host_submodel) {
+					if(ssp->system_info->type == SUBSYSTEM_TURRET) {
+						set_custom_position_function(get_turret_cam_pos);
+						set_custom_orientation_function(get_turret_cam_orient);
+					}
+				}
+				ssp = GET_NEXT( ssp );
+			}
+		}
+	}
 }
 
 void camera::set_object_target(object *objp, int n_object_target_submodel)
@@ -119,6 +136,7 @@
 
 	object_target = object_h(objp);
 	object_target_submodel = n_object_target_submodel;
+
 }
 
 /**
@@ -290,7 +308,9 @@
 		pos_x.get(&pt.xyz.x, NULL);
 		pos_y.get(&pt.xyz.y, NULL);
 		pos_z.get(&pt.xyz.z, NULL);
-
+		
+		eye* eyep = NULL;
+		
 		if(object_host.IsValid())
 		{
 			object *objp = object_host.objp;
@@ -309,7 +329,30 @@
 			}
 			else
 			{
-				model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos );
+				if(pm->n_view_positions > 0) {
+					for(int i = 0; i < pm->n_view_positions; ++i) {
+						if(pm->view_positions[i].parent == object_host_submodel) {
+							eyep = &pm->view_positions[i];
+							break;
+						}
+						int sm = pm->submodel[object_host_submodel].first_child;
+						while(sm > 0) { //look for eyepoints attached to children, important for turret arms
+							if(pm->view_positions[i].parent == sm) {
+								eyep = &pm->view_positions[i];
+								break;
+							}
+							sm = pm->submodel[sm].next_sibling;
+						}
+					}
+				}
+				if(eyep) {
+					vec3d dummy, c_pos_in;
+					find_submodel_instance_point_normal( &c_pos_in, &dummy, objp, object_host_submodel+1, &eyep->pnt, &dummy);
+					vm_vec_unrotate(&c_pos, &c_pos_in, &objp->orient);
+					vm_vec_add2(&c_pos, &objp->pos);
+				} else {
+					model_find_world_point( &c_pos, &pt, pm->id, object_host_submodel, &objp->orient, &objp->pos );
+				}
 			}
 		}
 		else
@@ -317,10 +360,14 @@
 			c_pos = pt;
 		}
 
+		vec3d custom_pos;
 		//Do custom position stuff, if needed
 		if(func_custom_position != NULL)
 		{
-			func_custom_position(this, &c_pos);
+			func_custom_position(this, &custom_pos);
+			if(!eyep) {
+				c_pos = custom_pos;
+			}
 		}
 	}
 
@@ -983,3 +1030,29 @@
 			sub->do_frame(frametime);
 	}
 }
+
+vec3d normal_cache;
+
+void get_turret_cam_pos(camera *cam, vec3d *pos)
+{
+	object_h obj(cam->get_object_host());
+	if(!obj.IsValid())
+		return;
+	ship* shipp = &Ships[cam->get_object_host()->instance];
+	ship_subsys* ssp = GET_FIRST(&shipp->subsys_list);
+	while ( ssp != END_OF_LIST( &shipp->subsys_list ) ) {
+		if(ssp->system_info->subobj_num == cam->get_object_host_submodel()) {
+			ship_get_global_turret_gun_info(cam->get_object_host(), ssp, pos, &normal_cache, 1, NULL);
+			break;
+		}
+		ssp = GET_NEXT( ssp );
+	}
+}
+
+void get_turret_cam_orient(camera *cam, matrix *ori)
+{
+	object_h obj(cam->get_object_host());
+	if(!obj.IsValid())
+		return;
+	vm_vector_2_matrix(ori, &normal_cache, vm_vec_same(&normal_cache, &cam->get_object_host()->orient.vec.uvec)?NULL:&cam->get_object_host()->orient.vec.uvec, NULL);
+}
\ No newline at end of file
Index: code/camera/camera.h
===================================================================
--- code/camera/camera.h	(revision 9426)
+++ code/camera/camera.h	(working copy)
@@ -168,6 +168,9 @@
 camid cam_get_current();
 uint cam_get_num();
 
+void get_turret_cam_pos(camera *cam, vec3d *pos);
+void get_turret_cam_orient(camera *cam, matrix *ori);
+
 void subtitles_close();
 void subtitles_do_frame(float frametime);
 void subtitles_do_frame_post_shaded(float frametime);
