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.
GTFile.c
// GTFile.c, file and metafile routines |
// system headers |
#include <Devices.h> |
#include <Dialogs.h> |
#include <DiskInit.h> |
#include <Fonts.h> |
#include <Menus.h> |
#include <PictUtils.h> |
#include <QDOffScreen.h> |
#include <QuickDraw.h> |
#include <Resources.h> |
#include <SegLoad.h> |
#include <StandardFile.h> |
#include <TextEdit.h> |
#include <ToolUtils.h> |
#include "GTSupport.h" |
#include "GTFile.h" |
#include "QD3D.h" |
#include "QD3DDrawContext.h" |
#include "QD3DRenderer.h" |
#include "QD3DShader.h" |
#include "QD3DCamera.h" |
#include "QD3DLight.h" |
#include "QD3DGeometry.h" |
#include "QD3DTransform.h" |
#include "QD3DGroup.h" |
#include "QD3DMath.h" |
#include "QD3DStorage.h" |
#include "QD3DIO.h" |
//------------------------------------------------------------------------------------------- |
// |
static void InitDocumentData( DocumentHdl theDocument ) |
{ |
TQ3Point3D myOrigin = { 0, 0, 0 } ; |
// sanity check |
if( theDocument == nil || (**theDocument).fWindow == nil ) |
return ; |
// Lock and load |
HLock( (Handle)theDocument ) ; |
// sets up the 3d data for the scene |
// Create view for QuickDraw 3D. |
(**theDocument).fView = MyNewView( (**theDocument).fWindow ); |
// the main display group: |
(**theDocument).fModel = NULL ; |
// the drawing styles: |
(**theDocument).fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ; |
(**theDocument).fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ; |
(**theDocument).fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ; |
(**theDocument).fGroupScale = 1; |
(**theDocument).fGroupCenter = myOrigin ; |
// set up an illumination shder for this document |
(**theDocument).fShader = Q3PhongIllumination_New(); |
// set the rotation matrix the identity matrix |
Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation); |
// unlock the handle |
HUnlock((Handle) theDocument ) ; |
return ; |
bail: |
// either we failed getting the model or the view |
// so we want to quit here |
ExitToShell() ; |
} |
//------------------------------------------------------------------------------------------- |
// |
static void DisposeDocumentData( DocumentHdl theDocument ) |
{ |
// Lock and load |
HLock( (Handle)theDocument ) ; |
if( (**theDocument).fView ) |
Q3Object_Dispose((**theDocument).fView) ; // the view for the scene |
if( (**theDocument).fModel ) |
Q3Object_Dispose((**theDocument).fModel) ; // object in the scene being modelled |
if( (**theDocument).fInterpolation ) |
Q3Object_Dispose((**theDocument).fInterpolation) ; // interpolation style used when rendering |
if( (**theDocument).fBackFacing ) |
Q3Object_Dispose((**theDocument).fBackFacing) ; // whether to draw shapes that face away from the camera |
if( (**theDocument).fFillStyle ) |
Q3Object_Dispose((**theDocument).fFillStyle) ; // whether drawn as solid filled object or decomposed to components |
if( (**theDocument).fShader ) |
Q3Object_Dispose((**theDocument).fShader) ; |
HUnlock((Handle) theDocument ) ; |
// And free the storage used by the document handle |
DisposHandle((Handle) theDocument); |
} |
//------------------------------------------------------------------------------------------- |
// |
void HandleCloseWindow( WindowPtr theWindow ) |
{ |
DocumentHdl theDocument ; |
if( theWindow ) { |
theDocument = (DocumentHdl) GetWRefCon( theWindow ) ; |
DisposeWindow ( theWindow ); |
if( theDocument ) |
DisposeDocumentData( theDocument ) ; |
} |
} |
//------------------------------------------------------------------------------------------- |
// Create and init a document with the 3d stuff - gets called by both open and new |
static DocumentHdl CreateDocument( void ) |
{ |
DocumentHdl theDocument; |
WindowPtr theWindow = nil ; |
OSErr theErr = noErr ; |
if(( theDocument = (DocumentHdl)NewHandleClear( sizeof(DocumentRec))) != nil ) |
{ |
theWindow = GetNewCWindow(128,nil,(WindowPtr)-1); |
if( theWindow == nil ) |
return nil ; |
SetWRefCon( theWindow, (long)theDocument ); |
(**theDocument).fWindow = theWindow ; |
// initialise our document structure |
InitDocumentData( theDocument ) ; |
} |
else // handle the error |
theErr = MemError() ; |
return theDocument ; |
} |
OSErr HandleNewCommand( void ) |
{ |
DocumentHdl theDocument ; |
OSErr theErr = noErr ; |
theDocument = CreateDocument() ; |
if(theDocument == nil ) |
{ |
theErr = MemError() ; |
if( theErr == noErr ) |
{ |
theErr = ResError() ; |
} |
} |
return theErr ; |
} |
//------------------------------------------------------------------------------------------- |
// |
static Boolean MetafileFileSpecify( FSSpec *theFile ) |
{ |
StandardFileReply theSFReply ; |
SFTypeList myTypes = { 'TEXT', '3DMF' } ; |
const short numTypes = 2 ; |
// Get the file name to open |
StandardGetFile( nil, numTypes, myTypes, &theSFReply ) ; |
if( theSFReply.sfGood ) |
*theFile = theSFReply.sfFile ; |
// did the user cancel? |
return theSFReply.sfGood ; |
} |
//----------------------------------------------------------------------------------------------- |
// |
OSErr HandleOpenCommand( void ) |
{ |
DocumentHdl theDocument ; |
OSErr theErr = noErr ; |
FSSpec theFileSpec ; |
theDocument = CreateDocument() ; |
if(theDocument == nil ) |
{ |
theErr = MemError() ; |
if( theErr == noErr ) |
{ |
theErr = ResError() ; |
} |
return theErr ; |
} |
if(MetafileFileSpecify( &theFileSpec )) { |
WindowPtr myWindow = (**theDocument).fWindow ; |
SetCursor(*(GetCursor(watchCursor))); |
HLock((Handle)theDocument) ; |
// try to read the file into the main display group |
if(((**theDocument).fModel = MyNewModelFromFile(&theFileSpec)) != NULL ) { |
AdjustCamera( theDocument, |
(myWindow->portRect.right - myWindow->portRect.left), |
(myWindow->portRect.bottom - myWindow->portRect.top) ) ; |
SetWTitle( myWindow, theFileSpec.name ); |
ShowWindow( myWindow ) ; |
SetPort( myWindow ) ; |
SetCursor(&qd.arrow) ; |
} |
HUnlock((Handle)theDocument) ; |
} |
return theErr ; |
} |
//----------------------------------------------------------------------------------------------- |
// cleaned up from IM QuickDraw 3D pp 15-5 |
static TQ3FileObject MyGetNewFile( FSSpec *myFSSpec, TQ3Boolean *isText ) |
{ |
TQ3FileObject myFileObj; |
TQ3StorageObject myStorageObj; |
OSType myFileType; |
FInfo fndrInfo ; |
// we assume the FSSpec passed in was valid, get the file information |
// we need to know the file type, this routine may get called by an appleEvent |
// handler, so we can't assume a type, we need to get it from the fsspec. |
FSpGetFInfo( myFSSpec, &fndrInfo ) ; |
// pull out the file type |
myFileType = fndrInfo.fdType ; |
// Create new storage object and new file object |
if(((myStorageObj = Q3FSSpecStorage_New( myFSSpec )) == NULL) |
|| ((myFileObj = Q3File_New()) == NULL)) |
{ |
if (myStorageObj != NULL) |
Q3Object_Dispose(myStorageObj); |
return(NULL); |
} |
// Set the storage for the file object |
Q3File_SetStorage(myFileObj, myStorageObj); |
Q3Object_Dispose(myStorageObj); |
if ((myFileType == '3DMF') || (myFileType == 'EO3D')) |
*isText = kQ3False ; |
else if (myFileType == 'TEXT') |
*isText = kQ3True ; |
return (myFileObj); |
} |
//---------------------------------------------------------------------------------- |
// read model from file object into the supplied group |
static TQ3Status MyReadModelFromFile( TQ3FileObject theFile,TQ3GroupObject myGroup) |
{ |
if(theFile != NULL) { |
TQ3Object myTempObj ; |
TQ3Boolean isEOF ; |
// read objects from the file |
do { |
myTempObj = Q3File_ReadObject( theFile ); |
if( myTempObj != NULL ) { |
// we only want the object in our main group if we can draw it |
if ( Q3Object_IsDrawable( myTempObj) ) |
Q3Group_AddObject( myGroup, myTempObj ) ; |
// we either added the object to the main group, or we don't care |
// so we can safely dispose of the object |
Q3Object_Dispose( myTempObj ) ; |
} |
// check to see if we reached the end of file yet |
isEOF = Q3File_IsEndOfFile( theFile ); |
} while (isEOF == kQ3False); |
} |
if( myGroup != NULL ) |
return kQ3Success ; |
else |
return kQ3Failure ; |
} |
//---------------------------------------------------------------------------------- |
// attach a shader to the group |
static TQ3Status MyAddShaderToGroup( TQ3GroupObject group ) |
{ |
TQ3ShaderObject illuminationShader = Q3PhongIllumination_New(); |
Q3Group_AddObject(group, illuminationShader); |
Q3Object_Dispose(illuminationShader); |
return(kQ3Success); |
} |
//---------------------------------------------------------------------------------- |
static TQ3GroupObject MyNewModelFromFile(FSSpec *theFileSpec) |
{ |
TQ3GroupObject myGroup = NULL ; |
TQ3Boolean isText = kQ3False ; |
TQ3FileMode myFileMode = 0; |
TQ3FileObject theFile; |
// Create a ordered group for the complete model. |
if ((myGroup = Q3DisplayGroup_New()) == NULL ) |
return NULL; |
MyAddShaderToGroup( myGroup ) ; |
theFile = MyGetNewFile( theFileSpec, &isText ) ; |
if( isText == kQ3True ) |
myFileMode |= kQ3FileModeText; // is it a text metafile?? |
// Open the file object |
if( Q3File_OpenRead( theFile, &myFileMode ) != kQ3Success) |
return NULL ; |
if( MyReadModelFromFile( theFile, myGroup ) == NULL) |
DebugStr("\pMetafile data read is null") ; |
Q3File_Close(theFile); // close and dispose of the file object |
Q3Object_Dispose(theFile); |
return myGroup ; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14