TF

Multipoint Builder Technical Specs

(The how, what and why of camera specifications for multinode.)


Main Page

Multipoint Page

Sample Code
Basics:
In order to correctly place and position a QTVR node, Multipoint Builder needs to know several things:
  • The node position
  • The direction the center of the panorama is pointing
  • The vertical field of view
  • (optional) The left and right pan range

By simply adding a resource to your output PICT or MooV, you enable Multipoint Builder to automatically position your output and create a multi-node movie.

Preparing the Data:

For multipoint builder to position multiple movies together in a scene, and design links between them it needs three things:

The node position in space. This is the center point of the camera as it rendered the panorama. The camera coordinates are expected in a right handed coordinate system, where positive X cross positive Y = positive Z, not negative. If you are using left handed coordinates internally, you will need to negate Z or the appropriate coordinate when filling in the resource.

The core orientation of the camera. This is a coordinate the center of the panoramic movie is facing. This is used to calculate the shift applied to hotspots linking to other movies. If your camera has a look at point, this will do, or a direction vector added to your camera position. (It is also good to scale the direction vector up if your camera coordinates are large. Using the average distance between camera sites for a scaling factor should prevent any floating point precision errors.)

The camera's vertical field of view, from top to bottom in degrees. This is the visual "height" of the panorama. And is used for coding PICTs as QTVR nodes, and for setting the QTVR records in the final movie.

The next three fields define how the panorama "pans". First, there is the panStart and panStop fields. This determines the angle range through which the QTVR movie will pan. For full panoramas, you can set this to 0 and 360, or -180 and +180 degrees. For partial panoramas, you can set this to be the range seen by the panorama. The next field, panCenter is the angle measure of the center of the output panorama. For instance, if you render the image so that the left edge is -180 degrees and the right edge is +180, then the panCenter value is 0. If you render the image so that the left edge is 0 and the right edge is 360, the panCenter value is 180. This field is necessary to align the camera view with the panorama cylinder.

The final option is so that Multipoint Builder can tell which application created the node both for display to the user, and so MPB can resolve any differences between nodes created in different applications.


Sample Code:

This sample code provides an example call to store the necessary camera information with your file. Once the structure VRCameraInfo_Rec has been populated, calling AddQTVRInfo will complete the operation and the node will contain everything Multipoint Builder needs to position it with others.

ftp: AddQTVRInfo.c

typedef struct Point3D
{
    float x,y,z;
} Point3D;
typedef struct VRCameraInfo_Rec
    Point3D	FromPt;		// location of camera
    Point3D 	ToPt;		// center of object movie
    float 	FOV;		// field of view "height" of movie.
    float 	panStart,panStop; // pan range
    float 	panCenter;	// center is 180 or 0
    OSType	AppSig;		// creator type of application
} VRCameraInfo_Rec;
void AddQTVRInfo(VRCameraInfo_Rec *camera, FSSpec *file)
{
	short fref,oref;
	Handle h;
	FInfo finfo;
	oref=CurResFile();
	fref=FSpOpenResFile(file,fsRdWrPerm);
	if (fref == -1) // we have to add a resource map to the file
	{
		if (FSpGetFInfo(file, &finfo)) return;
		FSpCreateResFile(file, finfo.fdCreator,finfo.fdType, smSystemScript);
		fref= FSpOpenResFile(file,fsRdWrPerm);
	}
	if (fref != -1)
	{
		UseResFile(fref);
		h= Get1Resource('VCam', 128);
		if (h)
			RemoveResource(h);
		h= NewHandle(sizeof(VRCameraInfo_Rec));
		if (h)
		{
			BlockMoveData(camera, *h, sizeof(VRCameraInfo_Rec));
			AddResource(h, 'VCam', 128, "\pVR camera info");
			ReleaseResource(h);
			UpdateResFile(fref);
		}
		CloseResFile(fref);
		UseResFile(oref); 
	}
}
ÿ