// // Created by Chris Bartlett January 2006 // This SDL is supplied without warranty of any sort. // Permission is hereby granted for it to be reused in original or modified form for commercial or non-commercial purposes. // // This file has been created for POV-Ray 3.6 and illustrates the invocation of the ppConvertRotationAxes macro described below. // // This macro is designed to be used in conjunction with external converters to enable a set of joint rotations based on an alternative // orientation system to be used with a POV-Person figure. It is also able to output a set of joint rotations based on a range of // different systems of orientation. This converter requires the 3 input axes to be perpendicular to each other and the 3 output axes // to be perpendicular to each other. In all cases the sequence and relative directions of the axes are parameter controlled and need // to be specified using the standard POV-Ray coordinate space vector notation. // // Alternative Orientation Systems // ------------------------------- // BVH - the rotations are applied relative to the new position of the object being rotated as each successive rotation is applied // POV-Ray - the rotations are applied relative to axes that remain fixed relative to the POV-Ray axes. // POV-Person - the first axis is expected to align with the main axis of the object and the rotation is applied relative to the POV-Ray // coordinate space. The rotation around the second axis is also applied relative to the POV-Ray coordinate space. The // third rotation is applied around the 3rd axis once it has been adjusted to take account of the second axial rotation. // // Parameters: // ----------- // ppRotationIn - The rotation settings that need to be converted // ppAxisIn1 - The first axis of rotation to be used with ppRotationIn // ppAxisIn2 - The second axis of rotation to be used with ppRotationIn // ppAxisIn3 - The third axis of rotation to be used with ppRotationIn // ppAxisOut1 - The first axis in POV-Person format that will be used for the calculated rotation vector // ppAxisOut2 - The second axis in POV-Person format that will be used for the calculated rotation vector // ppAxisOut3 - The third axis in POV-Person format that will be used for the calculated rotation vector // ppAxesConvertFrom - The type of rotation to convert from i.e. 'BVH', 'POV-Person' or 'POV-Ray' // ppAxesConvertTo - The type of rotation to convert to i.e. 'POV-Person' or 'POV-Ray' // #include "transforms.inc" #macro ppConvertRotationAxes (ppRotationIn, ppAxisIn1, ppAxisIn2, ppAxisIn3, ppAxisOut1, ppAxisOut2, ppAxisOut3, ppAxesConvertFrom, ppAxesConvertTo) // Rotate x and y vectors by the 3 rotations specified in ppRotation around the 3 inbound Axes. // Note: When we use x, y and z with the Rotations it is to access the first second and third elements of the // vector and is not related to the x, y and z axes. #if (strcmp(ppAxesConvertFrom,"BVH") = 0) // The inbound axes move with the object, so we first need to work out where the second and 3rd axes are relative // to the POV-Ray coordinate space. #local ppAxis1 = ppAxisIn1; #local ppAxis2 = vaxis_rotate(ppAxisIn2,ppAxis1,ppRotationIn.x); #local ppAxis3 = vaxis_rotate(vaxis_rotate(ppAxisIn3,ppAxis1,ppRotationIn.x),ppAxis2,ppRotationIn.y); #end #if (strcmp(ppAxesConvertFrom,"POV-Ray") = 0) // The inbound axes don't move with the object, they are aligned to the POV-Ray axes (though they may be transposed), // so we just use the axes provided. #local ppAxis1 = ppAxisIn1; #local ppAxis2 = ppAxisIn2; #local ppAxis3 = ppAxisIn3; #end #if (strcmp(ppAxesConvertFrom,"POV-Person") = 0) // The first 2 axes are fixed relative to the POV-Ray axes. The third axis is rotated about the second axis by the amount // specified in the second element of the inbound rotation vector. #local ppAxis1 = ppAxisIn1; #local ppAxis2 = ppAxisIn2; #local ppAxis3 = vaxis_rotate(ppAxisIn3,ppAxis2,ppRotationIn.y); #end // Take a Unit length vector aligned to the first output axis and apply the 3 input rotations around the 3 input axes #local ppV1Start = vnormalize(ppAxisOut1); #local ppV1 = ppV1Start; #local ppV1 = vaxis_rotate(ppV1,ppAxis1,ppRotationIn.x); #local ppV1 = vaxis_rotate(ppV1,ppAxis2,ppRotationIn.y); #local ppV1 = vaxis_rotate(ppV1,ppAxis3,ppRotationIn.z); // Take a Unit length vector aligned to the second output axis and apply the 3 input rotations around the 3 input axes #local ppV2Start = vnormalize(ppAxisOut2); #local ppV2 = ppV2Start; #local ppV2 = vaxis_rotate(ppV2,ppAxis1,ppRotationIn.x); #local ppV2 = vaxis_rotate(ppV2,ppAxis2,ppRotationIn.y); #local ppV2 = vaxis_rotate(ppV2,ppAxis3,ppRotationIn.z); // Take a Unit length vector aligned to the third output axis and apply the 3 input rotations around the 3 input axes // This is only used when converting to BVH format #local ppV3Start = vnormalize(ppAxisOut3); #local ppV3 = ppV3Start; #local ppV3 = vaxis_rotate(ppV3,ppAxis1,ppRotationIn.x); #local ppV3 = vaxis_rotate(ppV3,ppAxis2,ppRotationIn.y); #local ppV3 = vaxis_rotate(ppV3,ppAxis3,ppRotationIn.z); #if (strcmp(ppAxesConvertTo,"POV-Person") = 0) // Work out an equivalent set of rotations about the second set of 3 axes (the POV-Person format Axes). // Project the ppV1 point back onto the plane defined by the second output axis to derive the second rotation // First deal with the special condition where ppV1 ends up aligned with (i.e. parallel to) ppAxisOut2 #if (vlength(ppV1+ppAxisOut2)<0.001|vlength(ppV1-ppAxisOut2)<0.001) #local ppRotationOut2 = 0; #else #local ppRotationOut2 = VRotationD(ppV1Start,VProject_Plane(ppV1, ppAxisOut2),ppAxisOut2); #end // Work out the direction of Axis 3 once it's been adjusted by the second rotation #local ppAxis3Adjusted = vaxis_rotate(ppAxisOut3,ppAxisOut2,ppRotationOut2); // Take the angle between the start position of V1 with the second rotation applied and the final position of V1 // Note. The first rotation doesn't effect V1 as V1 lies on the first axis of rotation #local ppRotationOut3 = VRotationD(vaxis_rotate(ppV1Start,ppAxisOut2,ppRotationOut2),ppV1,ppAxis3Adjusted); // Subtract both rotations from ppV2 #local ppV2 = vaxis_rotate(ppV2,ppAxis3Adjusted,-ppRotationOut3); #local ppV2 = vaxis_rotate(ppV2,ppAxis2,-ppRotationOut2); #local ppRotationOut1 = VRotationD(ppV2Start,ppV2,ppAxisOut1); #local ppRotationOut = ; #end #if (strcmp(ppAxesConvertTo,"POV-Ray") = 0) // Work out an equivalent set of rotations about the second set of 3 axes // Project the ppV1 point back onto the plane defined by the third output axis to derive the third rotation // First deal with the special condition where ppV1 ends up aligned with (i.e. parallel to) ppAxisOut3 #if (vlength(ppV1+ppAxisOut3)<0.001|vlength(ppV1-ppAxisOut3)<0.001) #local ppRotationOut3 = 0; #else #local ppRotationOut3 = VRotationD(ppV1Start,VProject_Plane(ppV1, ppAxisOut3),ppAxisOut3); #end // Subtract this rotation from ppV1 #local ppV1 = vaxis_rotate(ppV1,ppAxisOut3,-ppRotationOut3); #local ppRotationOut2 = VRotationD(ppV1Start,ppV1,ppAxisOut2); // Subtract both rotations from ppV2 #local ppV2 = vaxis_rotate(ppV2,ppAxisOut3,-ppRotationOut3); #local ppV2 = vaxis_rotate(ppV2,ppAxisOut2,-ppRotationOut2); #local ppRotationOut1 = VRotationD(ppV2Start,ppV2,ppAxisOut1); #local ppRotationOut = ; #end #if (strcmp(ppAxesConvertTo,"BVH") = 0) // Find the angle needed to rotate V2 back around V3 until it's on the plane perpendicular to V1 // First deal with the special condition where ppV3 ends up aligned with (i.e. parallel to) ppAxisOut1 #if (vlength(ppV3+ppAxisOut1)<0.001|vlength(ppV3-ppAxisOut1)<0.001) #local ppRotationOut3 = VRotationD(ppV2Start,ppV2,ppV3); #else #local ppRotationOut3 = VRotationD(VPerp_To_Plane(ppV3,ppAxisOut1),ppV2,ppV3); #end #local ppV1 = vaxis_rotate(ppV1,ppV3,-ppRotationOut3); #local ppV2 = vaxis_rotate(ppV2,ppV3,-ppRotationOut3); // Find the angle needed to rotate V1 around Axis 2 till V1 returns to it's start position #local ppRotationOut2 = VRotationD(ppV1Start,ppV1,ppV2); // Find the angle needed to rotate V2 back around Axis 1 till V2 returns to it's start position #local ppRotationOut1 = VRotationD(ppV2Start,ppV2,ppAxisOut1); #local ppRotationOut = ; #end ppRotationOut #end #local RotationIn = <-17.035578, -5.684984, 13.266925>; #debug concat("Rotation In: <",vstr(3,RotationIn,",",0,4),"> \n") #local Type = array [3]; #local Type[0] = "BVH"; #local Type[1] = "POV-Person"; #local Type[2] = "POV-Ray"; #local I= 0; #while (I<3) #local J = 0; #while (J<3) #local RotationOut = ppConvertRotationAxes (RotationIn, x, y, z, x, y, z, Type[I], Type[J]); #debug concat("Rotation Out: <",vstr(3,RotationOut,",",0,4),"> Converted from ",Type[I]," to ",Type[J]," \n") #local J = J + 1; #end #local I = I + 1; #end