예제 #1
0
void orient_editor::update_object(object *ptr)
{
	if (ptr->type != OBJ_WAYPOINT && m_point_to) {
		vec3d v, loc;
		matrix m;

		memset(&v, 0, sizeof(vec3d));
		loc.xyz.x = convert(m_location_x);
		loc.xyz.y = convert(m_location_y);
		loc.xyz.z = convert(m_location_z);
		if (((CButton *) GetDlgItem(IDC_POINT_TO_OBJECT))->GetCheck() == 1) {
			v = Objects[index[m_object_index]].pos;
			vm_vec_sub2(&v, &ptr->pos);

		} else if (((CButton *) GetDlgItem(IDC_POINT_TO_LOCATION))->GetCheck() == 1) {
			vm_vec_sub(&v, &loc, &ptr->pos);

		} else {
			Assert(0);  // neither radio button is checked.
		}

		if (!v.xyz.x && !v.xyz.y && !v.xyz.z){
			return;  // can't point to itself.
		}

		vm_vector_2_matrix(&m, &v, NULL, NULL);
		ptr->orient = m;
	}
}
예제 #2
0
// ---------------------------------------------------------------------------------------------------
// Do chase mode.
//	View current segment (Cursegp) from the previous segment.
void set_chase_matrix(segment *sp)
{
	int			v;
	vms_vector	forvec = ZERO_VECTOR, upvec;
	vms_vector	tv = ZERO_VECTOR;
	segment		*psp;

	// move back two segments, if possible, else move back one, if possible, else use current
	if (IS_CHILD(sp->children[WFRONT])) {
		psp = &Segments[sp->children[WFRONT]];
		if (IS_CHILD(psp->children[WFRONT]))
			psp = &Segments[psp->children[WFRONT]];
	} else
		psp = sp;

	for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
		vm_vec_add2(&forvec,&Vertices[sp->verts[v]]);
	vm_vec_scale(&forvec,F1_0/MAX_VERTICES_PER_SEGMENT);

	for (v=0; v<MAX_VERTICES_PER_SEGMENT; v++)
		vm_vec_add2(&tv,&Vertices[psp->verts[v]]);
	vm_vec_scale(&tv,F1_0/MAX_VERTICES_PER_SEGMENT);

	Ed_view_target = forvec;

	vm_vec_sub2(&forvec,&tv);

	extract_up_vector_from_segment(psp,&upvec);

	if (!((forvec.x == 0) && (forvec.y == 0) && (forvec.z == 0)))
		vm_vector_2_matrix(&LargeView.ev_matrix,&forvec,&upvec,NULL);
}
예제 #3
0
//find the distance between a segment and a point
static fix compute_dist(const vcsegptr_t seg,const vms_vector &pos)
{
	auto delta = compute_segment_center(seg);
	vm_vec_sub2(delta,pos);

	return vm_vec_mag(delta);

}
예제 #4
0
파일: medsel.c 프로젝트: Ringdingcoder/d1x
//find the distance between a segment and a point
fix compute_dist(segment *seg,vms_vector *pos)
{
	vms_vector delta;

	compute_segment_center(&delta,seg);
	vm_vec_sub2(&delta,pos);

	return vm_vec_mag(&delta);

}
예제 #5
0
파일: med.c 프로젝트: CDarrow/DXX-Retro
void move_player_2_segment_and_rotate(segment *seg,int side)
{
	vms_vector vp;
	vms_vector	upvec;
        static int edgenum=0;

	compute_segment_center(&ConsoleObject->pos,seg);
	compute_center_point_on_side(&vp,seg,side);
	vm_vec_sub2(&vp,&ConsoleObject->pos);

	vm_vec_sub(&upvec, &Vertices[Cursegp->verts[Side_to_verts[Curside][edgenum%4]]], &Vertices[Cursegp->verts[Side_to_verts[Curside][(edgenum+3)%4]]]);
	edgenum++;

	vm_vector_2_matrix(&ConsoleObject->orient,&vp,&upvec,NULL);
//	vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);

	obj_relink( ConsoleObject-Objects, SEG_PTR_2_NUM(seg) );
	
}
예제 #6
0
void do_object_physics( object * obj )
{
	vms_angvec rotang;
	vms_vector frame_vec;	//movement in this frame
	vms_vector new_pos,ipos;		//position after this frame
	int iseg;
	int hit;
	vms_matrix rotmat,new_pm;
	int count=0;
	short joy_x,joy_y,btns;
	int joyx_moved,joyy_moved;
	fix speed;
	vms_vector *desired_upvec;
	fixang delta_ang,roll_ang;
	vms_vector forvec = {0,0,f1_0};
	vms_matrix temp_matrix;

	//check keys

	rotang.pitch = ROT_SPEED * (key_down_time(KEY_UP) - key_down_time(KEY_DOWN));
	rotang.head  = ROT_SPEED * (key_down_time(KEY_RIGHT) - key_down_time(KEY_LEFT));
	rotang.bank = 0;

	//check for joystick movement

	joy_get_pos(&joy_x,&joy_y);
	btns=joy_get_btns();

	joyx_moved = (abs(joy_x - _old_joy_x)>JOY_NULL);
	joyy_moved = (abs(joy_y - _old_joy_y)>JOY_NULL);

	if (abs(joy_x) < JOY_NULL) joy_x = 0;
	if (abs(joy_y) < JOY_NULL) joy_y = 0;

	if (!rotang.pitch) rotang.pitch = fixmul(-joy_y * 128,FrameTime);
	if (!rotang.head) rotang.head = fixmul(joy_x * 128,FrameTime);
	
	if (joyx_moved) _old_joy_x = joy_x;
	if (joyy_moved) _old_joy_y = joy_y;

	speed = ((btns&2) || keyd_pressed[KEY_A])?SLOW_SPEED*3:(keyd_pressed[KEY_Z]?SLOW_SPEED/2:SLOW_SPEED);

	//now build matrices, do rotations, etc., etc.

	vm_angles_2_matrix(&rotmat,&rotang);
	vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat);
	obj->orient = new_pm;

	//move player

	vm_vec_copy_scale(&obj->velocity,&obj->orient.fvec,speed);
	vm_vec_copy_scale(&frame_vec,&obj->velocity,FrameTime);

	do {
		fix wall_part;
		vms_vector tvec;

		count++;

		vm_vec_add(&new_pos,&obj->pos,&frame_vec);

		hit = find_vector_intersection(&ipos,&iseg,&obj->pos,obj->seg_id,&new_pos,obj->size,-1);

		obj->seg_id = iseg;
		obj->pos = ipos;

		//-FIXJOHN-if (hit==HIT_OBJECT) ExplodeObject(hit_objnum);

		if (hit==HIT_WALL) {
			vm_vec_sub(&frame_vec,&new_pos,&obj->pos);	//part through wall
			wall_part = vm_vec_dot(wall_norm,&frame_vec);
			vm_vec_copy_scale(&tvec,wall_norm,wall_part);
			if ((wall_part == 0) || (vm_vec_mag(&tvec) < 5)) Int3();
			vm_vec_sub2(&frame_vec,&tvec);
		}

	} while (hit == HIT_WALL);

	Assert(check_point_in_seg(&obj->pos,obj->seg_id,0).centermask==0);

	//now bank player according to segment orientation

	desired_upvec = &Segments[obj->seg_id].sides[3].faces[0].normal;

	if (labs(vm_vec_dot(desired_upvec,&obj->orient.fvec)) < f1_0/2) {

		vm_vector_2_matrix(&temp_matrix,&obj->orient.fvec,desired_upvec,NULL);

		delta_ang = vm_vec_delta_ang(&obj->orient.uvec,&temp_matrix.uvec,&obj->orient.fvec);

		if (rotang.head) delta_ang += (rotang.head<0)?TURNROLL_ANG:-TURNROLL_ANG;

		if (abs(delta_ang) > DAMP_ANG) {

			roll_ang = fixmul(FrameTime,ROLL_RATE);

			if (abs(delta_ang) < roll_ang) roll_ang = delta_ang;
			else if (delta_ang<0) roll_ang = -roll_ang;

			vm_vec_ang_2_matrix(&rotmat,&forvec,roll_ang);

			vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat);
			obj->orient = new_pm;
		}
	}

}
예제 #7
0
파일: meddraw.c 프로젝트: Ringdingcoder/d1x
// -----------------------------------------------------------------------------
void draw_coordinate_axes(void)
{
	int			i;
	short			Axes_verts[16];
	vms_vector	tvec,xvec,yvec,zvec;

	for (i=0; i<16; i++)
		Axes_verts[i] = alloc_vert();

	create_coordinate_axes_from_segment(Cursegp,Axes_verts);

	vm_vec_sub(&xvec,&Vertices[Axes_verts[1]],&Vertices[Axes_verts[0]]);
	vm_vec_sub(&yvec,&Vertices[Axes_verts[2]],&Vertices[Axes_verts[0]]);
	vm_vec_sub(&zvec,&Vertices[Axes_verts[3]],&Vertices[Axes_verts[0]]);

	// Create the letter X
	tvec = xvec;
	vm_vec_add(&Vertices[Axes_verts[4]],&Vertices[Axes_verts[1]],vm_vec_scale(&tvec,F1_0/16));
	tvec = yvec;
	vm_vec_add2(&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F1_0/8));
	vm_vec_sub(&Vertices[Axes_verts[6]],&Vertices[Axes_verts[4]],vm_vec_scale(&tvec,F2_0));
	tvec = xvec;	vm_vec_scale(&tvec,F1_0/8);
	vm_vec_add(&Vertices[Axes_verts[7]],&Vertices[Axes_verts[4]],&tvec);
	vm_vec_add(&Vertices[Axes_verts[5]],&Vertices[Axes_verts[6]],&tvec);

	//	Create the letter Y
	tvec = yvec;
	vm_vec_add(&Vertices[Axes_verts[11]],&Vertices[Axes_verts[2]],vm_vec_scale(&tvec,F1_0/16));
	vm_vec_add(&Vertices[Axes_verts[8]],&Vertices[Axes_verts[11]],&tvec);
	vm_vec_add(&Vertices[Axes_verts[9]],&Vertices[Axes_verts[11]],vm_vec_scale(&tvec,F1_0*2));
	vm_vec_add(&Vertices[Axes_verts[10]],&Vertices[Axes_verts[11]],&tvec);
	tvec = xvec;	vm_vec_scale(&tvec,F1_0/16);
	vm_vec_sub2(&Vertices[Axes_verts[9]],&tvec);
	vm_vec_add2(&Vertices[Axes_verts[10]],&tvec);

	// Create the letter Z
	tvec = zvec;
	vm_vec_add(&Vertices[Axes_verts[12]],&Vertices[Axes_verts[3]],vm_vec_scale(&tvec,F1_0/16));
	tvec = yvec;
	vm_vec_add2(&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F1_0/8));
	vm_vec_sub(&Vertices[Axes_verts[14]],&Vertices[Axes_verts[12]],vm_vec_scale(&tvec,F2_0));
	tvec = zvec;	vm_vec_scale(&tvec,F1_0/8);
	vm_vec_add(&Vertices[Axes_verts[13]],&Vertices[Axes_verts[12]],&tvec);
	vm_vec_add(&Vertices[Axes_verts[15]],&Vertices[Axes_verts[14]],&tvec);

	rotate_list(16,Axes_verts);

	gr_setcolor(AXIS_COLOR);

	draw_line(Axes_verts[0],Axes_verts[1]);
	draw_line(Axes_verts[0],Axes_verts[2]);
	draw_line(Axes_verts[0],Axes_verts[3]);

	// draw the letter X
	draw_line(Axes_verts[4],Axes_verts[5]);
	draw_line(Axes_verts[6],Axes_verts[7]);

	// draw the letter Y
	draw_line(Axes_verts[8],Axes_verts[9]);
	draw_line(Axes_verts[8],Axes_verts[10]);
	draw_line(Axes_verts[8],Axes_verts[11]);

	// draw the letter Z
	draw_line(Axes_verts[12],Axes_verts[13]);
	draw_line(Axes_verts[13],Axes_verts[14]);
	draw_line(Axes_verts[14],Axes_verts[15]);

	for (i=0; i<16; i++)
		free_vert(Axes_verts[i]);
}
예제 #8
0
/**
 * nstance at specified point with specified orientation
 *
 * if matrix==NULL, don't modify matrix.  This will be like doing an offset   
 * if pos==NULL, no position change
 */
void g3_start_instance_matrix(const vec3d *pos, const matrix *orient, bool set_api)
{
	vec3d tempv;
	matrix tempm,tempm2;

	Assert( G3_count == 1 );

	Assert(instance_depth<MAX_INSTANCE_DEPTH);

	instance_stack[instance_depth].m = View_matrix;
	instance_stack[instance_depth].p = View_position;
	instance_stack[instance_depth].lm = Light_matrix;
	instance_stack[instance_depth].lb = Light_base;
	instance_stack[instance_depth].om = Object_matrix;
	instance_stack[instance_depth].op = Object_position;
	instance_depth++;

	// Make sure orient is valid
	if (!orient) {
		orient = &vmd_identity_matrix;		// Assume no change in orient
	}

	if ( pos )	{
		//step 1: subtract object position from view position
		vm_vec_sub2(&View_position,pos);

		//step 2: rotate view vector through object matrix
		vm_vec_rotate(&tempv,&View_position,orient);
		View_position = tempv;

		vm_vec_unrotate(&tempv,pos,&Object_matrix);
		vm_vec_add2(&Object_position, &tempv);
	} else {
		// No movement, leave View_position alone
	}

	//step 3: rotate object matrix through view_matrix (vm = ob * vm)
	vm_copy_transpose(&tempm2,orient);

	vm_matrix_x_matrix(&tempm,&tempm2,&View_matrix);
	View_matrix = tempm;

	vm_matrix_x_matrix(&Object_matrix,&instance_stack[instance_depth-1].om,orient);

	// Update the lighting matrix
	matrix saved_orient = Light_matrix;
	vec3d saved_base = Light_base;
	
	if ( pos )	{
		vm_vec_unrotate(&Light_base,pos,&saved_orient );
		vm_vec_add2(&Light_base, &saved_base );
	} else {
		// No movement, light_base doesn't change.
	}

	vm_matrix_x_matrix(&Light_matrix,&saved_orient, orient);

	if(!Cmdline_nohtl && set_api)
		gr_start_instance_matrix(pos, orient);

}
예제 #9
0
void objfly_move_to_new_segment( object * obj, short newseg, int first_time )
{
	segment *pseg;
	int old_object_seg = obj->segnum;

	if ( newseg != obj->segnum )
		obj_relink(obj-Objects, newseg );

	pseg = &Segments[obj->segnum];

	if ( first_time || obj->segnum != old_object_seg) {		//moved into new seg
		vms_vector curcenter,nextcenter;
		fix step_size,seg_time;
		short entry_side,exit_side;	//what sides we entry and leave through
		vms_vector dest_point;		//where we are heading (center of exit_side)
		vms_angvec dest_angles;		//where we want to be pointing

		//find new exit side

		if ( !first_time ) {

			entry_side = matt_find_connect_side(obj->segnum,old_object_seg);
			exit_side = Side_opposite[entry_side];
		}

		//if (first_time) obj->fly_info.ft_mode = FP_FORWARD;

		if (first_time || entry_side==-1 || (pseg->children[exit_side]==-1) || (obj->fly_info.ft_mode!=FP_FORWARD) ) {
			int i;
			vms_vector prefvec,segcenter,sidevec;
			fix best_val=-f2_0;
			int best_side;

			//find exit side

			if (obj->fly_info.ft_mode == FP_FORWARD) {
				if (first_time) 
					prefvec = obj->orient.fvec;
				else
					prefvec = obj->fly_info.heading;
				vm_vec_normalize(&prefvec);
			}
			else
				prefvec = obj->orient.vecs[obj->fly_info.ft_mode%3];

			if (obj->fly_info.ft_mode >= 3) {prefvec.x = -prefvec.x; prefvec.y = -prefvec.y; prefvec.z = -prefvec.z;}

			compute_segment_center(&segcenter,pseg);

			best_side=-1;
			for (i=MAX_SIDES_PER_SEGMENT;--i >= 0;) {
				fix d;

				if (pseg->children[i]!=-1) {

					compute_center_point_on_side(&sidevec,pseg,i);
					vm_vec_sub2(&sidevec,&segcenter);
					vm_vec_normalize(&sidevec);
					d = vm_vec_dotprod(&sidevec,&prefvec);

					if (labs(d) < MIN_D) d=0;

					if (d > best_val || (d==best_val && i==exit_side)) {best_val=d; best_side=i;}

				}
			}

			if (best_val > 0) obj->fly_info.ft_mode = FP_FORWARD;

			Assert(best_side!=-1);

			exit_side = best_side;
		}

		//update target point & angles

		compute_center_point_on_side(&dest_point,pseg,exit_side);

		//update target point and movement points

		vm_vec_sub(&obj->phys_info.velocity,&dest_point,&obj->pos);
		step_size = vm_vec_normalize(&obj->phys_info.velocity);
		vm_vec_scale(&obj->phys_info.velocity, obj->phys_info.speed);

		compute_segment_center(&curcenter,pseg);
		compute_segment_center(&nextcenter,&Segments[pseg->children[exit_side]]);
		vm_vec_sub(&obj->fly_info.heading,&nextcenter,&curcenter);

		angles_from_vector(&dest_angles,&obj->fly_info.heading);	//extract angles

		if (first_time) 
			angles_from_vector(&obj->phys_info.rotvel,&obj->orient.fvec);

		seg_time = fixdiv(step_size,obj->phys_info.speed);	//how long through seg

		if (seg_time) {
			obj->fly_info.angle_step.p = fixdiv(delta_ang(obj->phys_info.rotvel.p,dest_angles.p),seg_time);
			obj->fly_info.angle_step.b = fixdiv(delta_ang(obj->phys_info.rotvel.b,dest_angles.b),seg_time);
			obj->fly_info.angle_step.h = fixdiv(delta_ang(obj->phys_info.rotvel.h,dest_angles.h),seg_time);
		}
		else {
			obj->phys_info.rotvel = dest_angles;
			obj->fly_info.angle_step.p = obj->fly_info.angle_step.b = obj->fly_info.angle_step.h = 0;
		}
	}
}
예제 #10
0
//	-----------------------------------------------------------------------------------------------------------
// add rotational velocity & acceleration
void do_physics_sim_rot(object *obj)
{
	vms_angvec	tangles;
	vms_matrix	rotmat,new_orient;
	//fix		rotdrag_scale;
	physics_info *pi;

	Assert(FrameTime > 0);	//Get MATT if hit this!

	pi = &obj->mtype.phys_info;

	if (!(pi->rotvel.x || pi->rotvel.y || pi->rotvel.z || pi->rotthrust.x || pi->rotthrust.y || pi->rotthrust.z))
		return;

	if (obj->mtype.phys_info.drag) {
		int count;
		vms_vector accel;
		fix drag,r,k;

		count = FrameTime / FT;
		r = FrameTime % FT;
		k = fixdiv(r,FT);

		drag = (obj->mtype.phys_info.drag*5)/2;

		const char ORIGINAL = 0;
		const char LINEAR_INTERPOLATION = 1;
		const char GEOMETRIC_DRAG = 2; 

		const char STRATEGY = ORIGINAL; 

		if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
			vm_vec_copy_scale(&accel,&obj->mtype.phys_info.rotthrust,fixdiv(f1_0,obj->mtype.phys_info.mass));
		}

		if(STRATEGY == ORIGINAL) {
			while (count--) {
				if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
					vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel);
				}

				vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag);
			}

			//do linear scale on remaining bit of time
			if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
				vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k);
			}
			vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag));
		} else if (STRATEGY == LINEAR_INTERPOLATION) {
			vms_vector target_rotvel;
			vm_vec_copy_scale(&target_rotvel, &obj->mtype.phys_info.rotvel, F1_0); 

			// Target 21.3 FPS -- three iterations
			for(int i = 0; i < 3; i++)  {
				if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
					vm_vec_add2(&target_rotvel, &accel);
				}
				vm_vec_scale(&target_rotvel,f1_0-drag);
			}			


			fix target_frametime = F1_0 / 64 * 3; 
			fix interpolation_fraction = fixdiv(FrameTime, target_frametime); 

			vm_vec_sub2(&target_rotvel, &obj->mtype.phys_info.rotvel);
			vm_vec_scale(&target_rotvel, interpolation_fraction); 

			vm_vec_add2(&obj->mtype.phys_info.rotvel, &target_rotvel); 
		} else if(STRATEGY == GEOMETRIC_DRAG) {
			while (count--) {
				if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
					vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel);
				}

				vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag);
			}

			//do linear scale on remaining bit of time
			if (obj->mtype.phys_info.flags & PF_USES_THRUST) {
				vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k);
			}

			double target_frametime = 3.0/64.0;
			const double fix_offset = 65536.0; 
			double interpolation_fraction =  ((double)(r) / fix_offset) / target_frametime ; 

			double ddrag = (double)(drag) / fix_offset;
			double kdrag = pow((1.0 - ddrag), interpolation_fraction*3);

			fix fractional_drag = (fix)(kdrag * fix_offset); 

			vm_vec_scale(&obj->mtype.phys_info.rotvel,fractional_drag);
			//vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag));
		}

		

		/*
		fix k_drag = f1_0-fixmul(k,drag);

		if(FrameTime < F1_0/30) {
			// Pegged to 30 FPS for now
			double fix_offset = (double) F1_0; 
			double target_framerate = 20.0; 
			double ddrag = ((double) drag)/fix_offset;
			//double target_drag = (1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag*2.0/15.0); // Drag value multiplied by at 30 hz
			double target_drag = (1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag)*(1.0-ddrag*2.0/15.0); // Drag value at 20 hz

			double frame_pow = 20.0 * ((double)(FrameTime)/fix_offset); 
			double frame_drag = pow(target_drag, frame_pow);

			k_drag = (fix) (frame_drag*fix_offset); 
			
		}

		if (obj->mtype.phys_info.flags & PF_USES_THRUST) {

			vm_vec_copy_scale(&accel,&obj->mtype.phys_info.rotthrust,fixdiv(f1_0,obj->mtype.phys_info.mass));

			// CED -- fix this for frame independence! 

			while (count--) {

				vm_vec_add2(&obj->mtype.phys_info.rotvel,&accel);

				vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-drag);
			}

			//do linear scale on remaining bit of time

			vm_vec_scale_add2(&obj->mtype.phys_info.rotvel,&accel,k);
			//vm_vec_scale(&obj->mtype.phys_info.rotvel,f1_0-fixmul(k,drag));
			vm_vec_scale(&obj->mtype.phys_info.rotvel,k_drag);
		}
		else
		{
			fix total_drag=f1_0;

			while (count--)
				total_drag = fixmul(total_drag,f1_0-drag);

			//do linear scale on remaining bit of time

			//total_drag = fixmul(total_drag,f1_0-fixmul(k,drag));
			total_drag = fixmul(total_drag,k_drag);

			vm_vec_scale(&obj->mtype.phys_info.rotvel,total_drag);

		}
		*/

	}

	//now rotate object

	//unrotate object for bank caused by turn
	if (obj->mtype.phys_info.turnroll) {
		vms_matrix new_pm;

		tangles.p = tangles.h = 0;
		tangles.b = -obj->mtype.phys_info.turnroll;
		vm_angles_2_matrix(&rotmat,&tangles);
		vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat);
		obj->orient = new_pm;
	}

	tangles.p = fixmul(obj->mtype.phys_info.rotvel.x,FrameTime);
	tangles.h = fixmul(obj->mtype.phys_info.rotvel.y,FrameTime);
	tangles.b = fixmul(obj->mtype.phys_info.rotvel.z,FrameTime);

	vm_angles_2_matrix(&rotmat,&tangles);
	vm_matrix_x_matrix(&new_orient,&obj->orient,&rotmat);
	obj->orient = new_orient;

	if (obj->mtype.phys_info.flags & PF_TURNROLL)
		set_object_turnroll(obj);

	//re-rotate object for bank caused by turn
	if (obj->mtype.phys_info.turnroll) {
		vms_matrix new_pm;

		tangles.p = tangles.h = 0;
		tangles.b = obj->mtype.phys_info.turnroll;
		vm_angles_2_matrix(&rotmat,&tangles);
		vm_matrix_x_matrix(&new_pm,&obj->orient,&rotmat);
		obj->orient = new_pm;
	}

	check_and_fix_matrix(&obj->orient);
}