#include #include #include #define min(a,b) ((a)<(b)?(a):(b)) #define PI 3.1415926535897932384626433832795 /* PlaceCamera(): establish a viewpoint, viewing direction and orientation * for a scene. This routine must be called before RiWorldBegin(). * position: a point giving the camera position * direction: a point giving the camera direction relative to position * roll: an optional rotation of the camera about its direction axis */ void PlaceCamera(RtPoint position, RtPoint direction, float roll) { RiIdentity(); /* Initialize the camera transformation */ if (roll != 0.0) RiRotate(-roll, 0.0, 0.0, 1.0); AimZ(direction); RiTranslate(-position[0], -position[1], -position[2]); } void AimZ(RtPoint direction) { double xzlen, yzlen, yrot, xrot; if (direction[0]==0 && direction[1]==0 && direction[2]==0) return; /* * The initial rotation about the y axis is given by the projection of * the direction vector onto the x,z plane: the x and z components * of the direction. */ xzlen = sqrt(direction[0]*direction[0]+direction[2]*direction[2]); if (xzlen == 0) yrot = (direction[1] < 0) ? 180 : 0; else yrot = 180*acos(direction[2]/xzlen)/PI; /* * The second rotation, about the x axis, is given by the projection on * the y,z plane of the y-rotated direction vector: the original y * component, and the rotated x,z vector from above. */ yzlen = sqrt(direction[1]*direction[1]+xzlen*xzlen); xrot = 180*acos(xzlen/yzlen)/PI; /* yzlen should never be 0 */ if (xrot != 0.0) { if (direction[1] > 0) RiRotate(xrot, 1.0, 0.0, 0.0); else RiRotate(-xrot, 1.0, 0.0, 0.0); } /* The last rotation declared gets performed first */ if (yrot != 0.0) { if (direction[0] > 0) RiRotate(-yrot, 0.0, 1.0, 0.0); else RiRotate(yrot, 0.0, 1.0, 0.0); } } /* FrameCamera(): give physical parameters for a camera. Parameters: focallength: the "camera's" focal length. framewidth: the width of the film frame frameheight: the height of the film frame */ void FrameCamera(float focallength, float framewidth, float frameheight) { RtFloat normwidth, normheight; /* Focal length of 0 is taken to be an orthographic projection */ if (focallength != 0.0) { RiProjection("perspective", RI_NULL); normwidth = (framewidth*.5)/focallength; normheight = (frameheight*.5)/focallength; } else { RiProjection("orthographic", RI_NULL); normwidth = framewidth*.5; normheight = frameheight*.5; } RiScreenWindow(-normwidth, normwidth, -normheight, normheight); } /* FrameCamera2(): give physical parameters for a camera. * Parameters: * focallength: controls the width of the camera's field of view. * framewidth: the width of the film image * frameheight: the height of the film image*/ void FrameCamera2(float focallength, float framewidth, float frameheight) { RtFloat fov; /* A nonzero focal length is taken to be a "normal" lens */ if(focallength != 0.0) { fov = 2 * atan((min(framewidth,frameheight)*.5)/focallength) * 180.0/3.14159; RiProjection("perspective", RI_FOV, (RtPointer)&fov, RI_NULL); } else { RiProjection("orthographic", RI_NULL); } RiFrameAspectRatio((RtFloat)(framewidth/frameheight)); }