- initial import
git-svn-id: http://moon:8086/svn/mips@1 a8ebac50-d88d-4704-bea3-6648445a41b3
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
#include <math.h>
|
||||
#include "ri.h"
|
||||
#include "camset.h"
|
||||
|
||||
#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));
|
||||
}
|
||||
Reference in New Issue
Block a user