// Persistence of Vision Ray Tracer version 3.5 Include File // File: transforms.inc // Last updated: 2001.8.9 // Description: Macros for dealing with transforms #ifndef(TRANSFORMS_INC_TEMP) #declare TRANSFORMS_INC_TEMP = version; #version 3.5; #ifdef(View_POV_Include_Stack) #debug "including transforms.inc\n" #end #include "math.inc" // -------------------- // Transformation macros: // -------------------- // Reorients and deforms object so original x axis points along A, original y along B, // and original z along C. #macro Shear_Trans(A, B, C) transform { matrix < A.x, A.y, A.z, B.x, B.y, B.z, C.x, C.y, C.z, 0, 0, 0> } #end #macro Matrix_Trans(A, B, C, D) transform { matrix < A.x, A.y, A.z, B.x, B.y, B.z, C.x, C.y, C.z, D.x, D.y, D.z> } #end // "stretch" along a specific axis #macro Axial_Scale_Trans(Axis, Amt) transform { transform {Point_At_Trans(Axis) inverse} scale <1,Amt,1> Point_At_Trans(Axis) } #end // rotate around a specific axis // Author: Rune S. Johansen #macro Axis_Rotate_Trans(Axis, Angle) #local vX = vaxis_rotate(x,Axis,Angle); #local vY = vaxis_rotate(y,Axis,Angle); #local vZ = vaxis_rotate(z,Axis,Angle); transform { matrix < vX.x,vX.y,vX.z, vY.x,vY.y,vY.z, vZ.x,vZ.y,vZ.z, 0,0,0 > } #end // Rotate around a specific point #macro Rotate_Around_Trans(Rotation, Point) transform { translate -Point rotate Rotation translate Point } #end // based on original Reorient() macro by John VanSickle #macro Reorient_Trans(Axis1, Axis2) #local vX1 = vnormalize(Axis1); #local vX2 = vnormalize(Axis2); #local Y = vcross(vX1, vX2); #if(vlength(Y) > 0) #local vY = vnormalize(Y); #local vZ1 = vnormalize(vcross(vX1, vY)); #local vZ2 = vnormalize(vcross(vX2, vY)); transform { matrix < vX1.x, vY.x,vZ1.x, vX1.y,vY.y,vZ1.y, vX1.z,vY.z, vZ1.z, 0,0,0 > matrix < vX2.x,vX2.y,vX2.z, vY.x,vY.y, vY.z, vZ2.x,vZ2.y,vZ2.z, 0,0,0 > } #else #if (vlength(vX1-vX2)=0) transform {} #else #local vZ = VPerp_To_Vector(vX2); transform { Axis_Rotate_Trans(vZ,180) } #end #end #end // Similar to Reorient_Trans(), points y axis along Axis. #macro Point_At_Trans(YAxis) #local Y = vnormalize(YAxis); #local X = VPerp_To_Vector(Y); #local Z = vcross(X, Y); Shear_Trans(X, Y, Z) #end // Calculates a transformation which will center the bounding box of Object // along specified axis Axis // Usage: // object {MyObj // Center_Trans(MyObj, x) center along x axis // You can also center along multiple axis: // Center_Trans(MyObj, x+y) center along x and y axis #macro Center_Trans(Object, Axis) #local Mn = min_extent(Object); #local Mx = max_extent(Object); transform {translate -Axis*((Mx - Mn)/2 + Mn)} #end // Calculates a transformation which will align the bounding box // of an object to a point. Negative values on Axis will align to // the sides facing the negative ends of the coordinate system, // positive values will align to the opposite sides, 0 means // not to do any alignment on that axis. // Usage: // object {MyObj // Align_Trans(MyObj, x, Pt) // Align right side of object to be coplanar with Pt // Align_Trans(MyObj, -y, Pt) // Align bottom of object to be coplanar with Pt #macro Align_Trans(Object, Axis, Pt) #local Mn = min_extent(Object); #local Mx = max_extent(Object); transform { #if(Axis.x < -0.5) translate x*(Pt - Mn.x) #else #if(Axis.x > 0.5) translate x*(Pt - Mx.x) #end #end #if(Axis.y < -0.5) translate y*(Pt - Mn.y) #else #if(Axis.y > 0.5) translate y*(Pt - Mx.y) #end #end #if(Axis.z < -0.5) translate z*(Pt - Mn.z) #else #if(Axis.z > 0.5) translate z*(Pt - Mx.z) #end #end } #end // Aligns an object to a spline for a given time value. // The Z axis of the object will point in the forward direction // of the spline and the Y axis of the object will point upwards. // // usage: object {MyObj Spline_Trans(MySpline, clock, y, 0.1, 0.5)} // // Spline: The spline that the object is aligned to. // // Time: The time value to feed to the spline, for example clock. // // Sky: The vector that is upwards in your scene, usually y. // // Foresight: How much in advance the object will turn and bank. // Values close to 0 will give precise results, while higher // values give smoother results. It will not affect parsing // speed, so just find the value that looks best. // // Banking: How much the object tilts when turning. Note that the amount // of tilting is equally much controlled by the ForeSight value. // // Author: Rune S. Johansen #macro Spline_Trans (Spline, Time, Sky, Foresight, Banking) #local Location = <0,0,0>+Spline(Time); #local LocationNext = <0,0,0>+Spline(Time+Foresight); #local LocationPrev = <0,0,0>+Spline(Time-Foresight); #local Forward = vnormalize(LocationNext-Location); #local Right = VPerp_To_Plane(Sky,Forward); #local Up = VPerp_To_Plane(Forward,Right); #local Matrix = Matrix_Trans(Right,Up,Forward,Location) #local BankingRotation = degrees(atan2( VRotation( VProject_Plane((LocationNext-Location),Sky), VProject_Plane((Location-LocationPrev),Sky), Up )*Banking ,1 )); transform { rotate BankingRotation*z transform Matrix } #end #macro vtransform(vec, trans) #local fn = function { transform { trans } } #local result = (fn(vec.x, vec.y, vec.z)); result #end #macro vinv_transform(vec, trans) #local fn = function { transform { trans inverse } } #local result = (fn(vec.x, vec.y, vec.z)); result #end #version TRANSFORMS_INC_TEMP; #end