Retired Document
Important: This sample code may not represent best practices for current development. The project may use deprecated symbols and illustrate technologies and techniques that are no longer recommended.
QTVRObjectAuthoring.c
// |
// This is sample code which will make QTVR object movies from Linear QuickTime movies. |
// |
// © 1991-1996 Apple Computer, Inc. All rights reserved. |
// |
#include "MakeQTVRObject.h" |
#include "extern.h" |
//================================================================================================= |
// DeleteObjectMovieData1x0 |
// -- Delete the QTVR 1.0 object movie data. |
// -- Errors returned: |
// QuickTime errors, Toolbox errors. |
//------------------------------------------------------------------------------------------------- |
pascal OSErr DeleteQTVRObjectFileFormat1x0 ( |
Movie movie, |
short movieResFref, |
short movieResID, |
FSSpec movieSFFile) |
{ |
UserData uDat; |
OSErr err; |
FInfo finderInfo; |
if (movie == nil) return (invalidMovie); |
// Remove movie user data |
uDat = GetMovieUserData (movie); |
if ((err = GetMoviesError()) != noErr) |
{ |
UserMessage("\pCould not get user data item."); |
return (err); |
} |
RemoveUserData (uDat, 'ctyp', kControllerID); // Delete special controller |
if ((err = GetMoviesError()) != noErr) |
{ |
UserMessage("\pCould not remove controller type."); |
return (err); |
} |
RemoveUserData (uDat, 'NAVG', 1); // Delete object movie data |
if ((err = GetMoviesError()) != noErr) |
{ |
UserMessage("\pCould not remove NAVG atom."); |
return (err); |
} |
// Remove the file preview |
SetMoviePreviewTime (movie, 0, 0); |
if ((err = GetMoviesError()) != noErr) |
{ |
UserMessage("\pCould not set preview time."); |
return (err); |
} |
// Change creator type back to MoviePlayer |
err = HGetFInfo (movieSFFile.vRefNum, movieSFFile.parID, movieSFFile.name, &finderInfo); |
if (err != noErr) |
{ |
UserMessage("\pCould not get creator type."); |
return (err); |
} |
finderInfo.fdCreator = kMoviePlayerCreatorType; |
err = HSetFInfo (movieSFFile.vRefNum, movieSFFile.parID, movieSFFile.name, &finderInfo); |
if (err != noErr) |
{ |
UserMessage("\pCould not set creator type."); |
return (err); |
} |
// Update the movie file itself |
err = AddFilePreview (movieResFref, 0, nil); |
if (err != noErr) |
{ |
UserMessage("\pCould add a file preview."); |
return (err); |
} |
err = UpdateMovieResource (movie, movieResFref, movieResID, 0); |
if (err != noErr) |
{ |
UserMessage("\pCould not update movie resource."); |
return (err); |
} |
UpdateResFile (movieResFref); |
if ((err = ResError()) != noErr) |
{ |
UserMessage("\pCould not update resource file."); |
return (err); |
} |
return (noErr); |
} |
//================================================================================================= |
// DoSetStartUpView |
//------------------------------------------------------------------------------------------------- |
OSErr DoSetStartUpView (MovieInstance *theInstance) |
{ |
OSErr err; |
Movie movie; |
if ( theInstance == nil) |
{ |
UserMessage("\pBad instance."); |
return (paramErr); |
} |
movie = theInstance->movie; |
if (movie == nil) |
{ |
UserMessage("\pBad movie."); |
return (paramErr); |
} |
{ |
TimeValue posterViewTime; |
QTVRObjectFileFormat1x0Record fileFormat; |
err = GetQTVRObjectFileFormat1x0 ( |
movie, |
&fileFormat); |
posterViewTime = MCGetCurrentTime (theInstance->movieController, nil); |
ConvertTimeToPanUtil (posterViewTime, |
fileFormat.frameDuration, |
fileFormat.numberOfColumns, |
fileFormat.numberOfRows, |
fileFormat.loopSize, |
fileFormat.startHPan, |
fileFormat.endHPan, |
fileFormat.startVPan, |
fileFormat.endVPan, |
&fileFormat.initialHPan, |
&fileFormat.initialVPan); |
gPrefInf.objectInfo.initialVPan = fileFormat.initialVPan; |
gPrefInf.objectInfo.initialHPan = fileFormat.initialHPan; |
err = SetQTVRObjectFileFormat1x0 ( |
movie, |
theInstance->movieResFile, |
theInstance->movieResID, |
theInstance->spec, |
posterViewTime, |
&fileFormat); |
} |
return (noErr); |
} |
//================================================================================================= |
// StuffQTVRObjectFileFormat1x0 |
// -- Error returned: |
// qtParamErr - if parameter is out of range |
//------------------------------------------------------------------------------------------------- |
OSErr StuffQTVRObjectFileFormat1x0 (short movieType, |
TimeValue frameDuration, |
short numberOfColumns, |
short numberOfRows, |
short loopSize, |
short loopTicks, |
Fixed startHPan, |
Fixed endHPan, |
Fixed startVPan, |
Fixed endVPan, |
Fixed fieldOfView, |
Fixed initialHPan, |
Fixed initialVPan, |
QTVRObjectFileFormat1x0Ptr fileFormatPtr) |
{ |
if (numberOfColumns <= 0) |
{ |
UserMessage("\pColumns must be > 0."); |
return (qtParamErr); |
} |
if (numberOfRows <= 0) |
{ |
UserMessage("\pRows must be > 0."); |
return (qtParamErr); |
} |
if (loopSize <= 0) |
{ |
UserMessage("\pLoop size must be > 0."); |
return (qtParamErr); |
} |
if (fieldOfView <= 0) |
{ |
UserMessage("\pField of view must be > 0."); |
return (qtParamErr); |
} |
if (startHPan > endHPan) |
{ |
UserMessage("\pEnding HPan must be greater than strarting HPan."); |
return (qtParamErr); |
} |
if (startVPan < endVPan) |
{ |
UserMessage("\pStarting VPan must be greater than ending VPan."); |
return (qtParamErr); |
} |
fileFormatPtr->reserved1 = 0; // For compatibility, always 0 |
fileFormatPtr->reserved2 = 0; |
fileFormatPtr->frameDuration = (short) frameDuration; |
fileFormatPtr->versionNumber = 1; |
fileFormatPtr->numberOfColumns = numberOfColumns; |
fileFormatPtr->numberOfRows = numberOfRows; |
fileFormatPtr->loopSize = loopSize; |
fileFormatPtr->loopTicks = loopTicks; |
fileFormatPtr->movieType = movieType; |
fileFormatPtr->startHPan = startHPan; |
fileFormatPtr->endHPan = endHPan; |
fileFormatPtr->startVPan = startVPan; |
fileFormatPtr->endVPan = endVPan; |
fileFormatPtr->initialHPan = initialHPan; |
fileFormatPtr->initialVPan = initialVPan; |
fileFormatPtr->fieldOfView = fieldOfView; |
return (noErr); |
} |
//================================================================================================= |
// SetQTVRObjectMovieData1x0 |
//------------------------------------------------------------------------------------------------- |
pascal OSErr SetQTVRObjectFileFormat1x0 ( |
Movie movie, |
short movieResFref, |
short movieResID, |
FSSpec movieSFFile, |
TimeValue posterViewTime, |
const QTVRObjectFileFormat1x0Ptr fileFormatPtr) |
{ |
OSType myComponentSubType = 'stna'; |
UserData uDat = GetMovieUserData (movie); |
OSErr err; |
FInfo finderInfo; |
if (movie == nil) return (invalidMovie); |
// Save navigable data |
err = SetUserDataItem (uDat, fileFormatPtr, sizeof (QTVRObjectFileFormat1x0Record), 'NAVG', 1); |
if (err != noErr) |
{ |
UserMessage("\pCould not set user data item."); |
return (err); |
} |
// Set Controller type to Nav controller |
err = SetUserDataItem (uDat, &myComponentSubType, sizeof (myComponentSubType), 'ctyp', 1); |
if (err != noErr) |
{ |
UserMessage("\pCould not set ctype."); |
return (err); |
} |
// Set current time to poster view time. |
SetMovieTimeValue (movie, posterViewTime); |
// Set the poster time to posterViewTime. For looping movie, this guarantees |
// that the QT will draw with the key frame first. |
SetMoviePosterTime (movie, posterViewTime); |
// Make a movie's preview with duration equal to the animation loop. |
SetMoviePreviewTime (movie, posterViewTime, fileFormatPtr->frameDuration * fileFormatPtr->loopSize); |
// Change creator type to QTVRPlayer |
err = HGetFInfo (movieSFFile.vRefNum, movieSFFile.parID, movieSFFile.name, &finderInfo); |
if (err != noErr) |
{ |
UserMessage("\pCould not get creator type."); |
return (err); |
} |
finderInfo.fdCreator = kQTVRPlayerCreatorType; |
err = HSetFInfo (movieSFFile.vRefNum, movieSFFile.parID, movieSFFile.name, &finderInfo); |
if (err != noErr) |
{ |
UserMessage("\pCould not set creator type."); |
return (err); |
} |
// Update the movie file itself |
err = UpdateMovieResource (movie, movieResFref, movieResID, 0); |
if (err != noErr) |
{ |
UserMessage("\pCould not update movie resource."); |
return (err); |
} |
UpdateResFile (movieResFref); |
if ((err = ResError()) != noErr) |
{ |
UserMessage("\pCould not update resource file."); |
return (err); |
} |
return (noErr); |
} |
//================================================================================================= |
// GetQTVRObjectMovieData1x0 |
// -- Caller is is responsible to make sure |
// -- Errors returned: |
// userDataItemNotFound - if QTVR Object file format data is not found |
// featureUnsupported - if file format version is not 1.0. |
//------------------------------------------------------------------------------------------------- |
pascal OSErr GetQTVRObjectFileFormat1x0 ( |
Movie movie, |
QTVRObjectFileFormat1x0Ptr fileFormatPtr) |
{ |
OSErr err; |
QTVRObjectFileFormat1x0Record tempFileFormat; |
err = GetUserDataItem (GetMovieUserData (movie), &tempFileFormat, sizeof (QTVRObjectFileFormat1x0Record), 'NAVG', 1); |
if (err != noErr) |
{ |
UserMessage("\pCould not get user data. This movie is not an Object movie."); |
return (err); |
} |
if (tempFileFormat.versionNumber != 1) |
{ |
UserMessage("\pFeature Unsupported."); |
return (featureUnsupported); |
} |
*fileFormatPtr = tempFileFormat; |
return (noErr); |
} |
//================================================================================================= |
// Convert from QuickTime time to pan parameters |
//------------------------------------------------------------------------------------------------- |
void ConvertTimeToPanUtil (TimeValue time, |
TimeValue frameDuration, |
short numColumns, |
short numRows, |
short loopSize, |
Fixed startHPan, |
Fixed endHPan, |
Fixed startVPan, |
Fixed endVPan, |
Fixed *hPan, |
Fixed *vPan) |
{ |
short row, column; |
TimeValue rc; |
Fixed panHRange; |
Fixed panVRange; |
panHRange = endHPan - startHPan; |
panVRange = startVPan - endVPan; |
time /= frameDuration; // Adjust for frameDuration |
rc = time / loopSize; |
row = rc / numColumns; |
column = rc % numColumns; |
// Note mixed Fixed and integer math. |
if (numColumns == 1) { |
*hPan = startHPan; |
} else if (panHRange == Long2Fix (360)) { |
*hPan = column * (panHRange / (numColumns )) + startHPan; |
} else { |
*hPan = column * (panHRange / (numColumns-1)) + startHPan; |
} |
if (numRows == 1) { |
*vPan = startVPan; |
} else { |
*vPan = startVPan - row * (panVRange / (numRows-1)); |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14