// The segments in the group are indicated (by segment number) in group_seglist. There are group_size segments.
// The point about which the groups is rotated is the center of first_seg:first_side.
// delta_flag:
// 0 absolute rotation, destination specified in terms of base_seg:base_side, used in moving or copying a group
// 1 relative rotation, destination specified relative to current orientation of first_seg:first_side
// Note: The group must exist in the mine, consisting of actual points in the world. If any points in the
// segments in the group are shared by segments not in the group, those points will get rotated and the
// segments not in the group will have their shapes modified.
// Return value:
// 0 group rotated
// 1 unable to rotate group
void med_create_group_rotation_matrix(vms_matrix *result_mat, int delta_flag, segment *first_seg, int first_side, segment *base_seg, int base_side, vms_matrix *orient_matrix, int orientation)
{
vms_matrix rotmat2,rotmat,rotmat3,rotmat4;
vms_angvec pbh = {0,0,0};
// Determine whether this rotation is a delta rotation, meaning to just rotate in place, or an absolute rotation,
// which means that the destination rotation is specified, not as a delta, but as an absolute
if (delta_flag) {
// Create rotation matrix describing rotation.
med_extract_matrix_from_segment(first_seg, &rotmat4); // get rotation matrix describing current orientation of first seg
set_matrix_based_on_side(&rotmat4, first_side);
rotmat3 = *orient_matrix;
vm_transpose_matrix(&rotmat3);
vm_matrix_x_matrix(&rotmat,&rotmat4,&rotmat3); // this is the desired orientation of the new segment
vm_transpose_matrix(&rotmat4);
vm_matrix_x_matrix(&rotmat2,&rotmat,&rotmat4); // this is the desired orientation of the new segment
} else {
// Create rotation matrix describing rotation.
med_extract_matrix_from_segment(base_seg, &rotmat); // get rotation matrix describing desired orientation
set_matrix_based_on_side(&rotmat, base_side); // modify rotation matrix for desired side
// If the new segment is to be attached without rotation, then its orientation is the same as the base_segment
vm_matrix_x_matrix(&rotmat4,&rotmat,orient_matrix); // this is the desired orientation of the new segment
pbh.b = orientation*16384;
vm_angles_2_matrix(&rotmat3,&pbh);
vm_matrix_x_matrix(&rotmat, &rotmat4, &rotmat3);
rotmat4 = rotmat;
rotmat = rotmat4;
med_extract_matrix_from_segment(first_seg, &rotmat3); // get rotation matrix describing current orientation of first seg
// It is curious that the following statement has no analogue in the med_attach_segment_rotated code.
// Perhaps it is because segments are always attached at their front side. If the back side is the side
// passed to the function, then the matrix is not modified, which might suggest that what you need to do below
// is use Side_opposite[first_side].
set_matrix_based_on_side(&rotmat3, Side_opposite[first_side]); // modify rotation matrix for desired side
vm_transpose_matrix(&rotmat3); // get the inverse of the current orientation matrix
vm_matrix_x_matrix(&rotmat2,&rotmat,&rotmat3); // now rotmat2 takes the current segment to the desired orientation
for (i=0; i<GroupList[Current_group].num_segments; i++)
if (GroupList[Current_group].segments[i] == attach_seg)
break;
if (i != GroupList[Current_group].num_segments) {
editor_status("Error -- Cannot copy group, attach side has a child (segment %i) attached.", Groupsegp[Current_group]->children[Groupside[Current_group]]);
return 1;
}
}
med_compress_mine();
if (!med_copy_group(0, Cursegp, Curside, Groupsegp[Current_group], Groupside[Current_group], &vmd_identity_matrix)) {