MarkerPickShell.c

// MarkerPickShell.c - QuickDraw 3d routines
//
// This is MarkerPick, an adaptation of box, the QuickDraw 3D starter program,
// written by Nick Thompson.
//
// Julian G—mez - May 31, 1995
// 
// ©1994-95 Apple computer Inc., All Rights Reserved
//
 
// system headers
#include <Dialogs.h>
#include <DiskInit.h>
#include <Fonts.h>
#include <Menus.h>
#include <PictUtils.h>
#include <QDOffScreen.h>
#include <QuickDraw.h>
#include <SegLoad.h>
#include <StandardFile.h>
#include <TextEdit.h>
 
// for QuickDraw 3D
#include "QD3D.h"
#include "QD3DMath.h"
#include "QD3DDrawContext.h"
#include "QD3DShader.h"
#include "QD3DTransform.h"
#include "QD3DGroup.h"
#include "QD3DPick.h"
 
 
#include "MarkerPickShell.h"
#include "MarkerPickSupport.h"
 
//-------------------------------------------------------------------------------------------
 
struct _documentRecord {
    TQ3ViewObject   fView ;                 // the view for the scene
    TQ3GroupObject  fModel ;                // object in the scene being modelled
    TQ3StyleObject  fInterpolation ;        // interpolation style used when rendering
    TQ3StyleObject  fBackFacing ;           // whether to draw shapes that face away from the camera
    TQ3StyleObject  fFillStyle ;            // whether drawn as solid filled object or decomposed to components
    TQ3Matrix4x4        fRotation;              // the transform for the model
};
 
typedef struct _documentRecord DocumentRec, *DocumentPtr, **DocumentHdl ;
 
 
//-------------------------------------------------------------------------------------------
// function prototypes
 
static void         InitToolbox( void ) ;
static void         MainEventLoop( void ) ;
static void         HandleKeyPress(EventRecord *event) ;
static void         HandleOSEvent(EventRecord *event) ;
void InitDocumentData( DocumentPtr theDocument ) ;
TQ3Status DocumentDraw3DData( DocumentPtr theDocument ) ;
void DisposeDocumentData( DocumentPtr theDocument) ;
 
void DoPick(Point, DocumentPtr);
 
 
//-------------------------------------------------------------------------------------------
//
 
Boolean         gQuitFlag       = false ;
WindowPtr       gMainWindow     = nil ;
DocumentRec     gDocument ;
 
//-------------------------------------------------------------------------------------------
// main()
// entry point for the application, initialize the toolbox, initialize QuickDraw 3D
// and enter the main event loop.  On exit from the main event loop, we want to call
// the QuickDraw 3D exit function to clean up QuickDraw 3d.
 
void main(void)
{
    TQ3Status   myStatus;
    Rect        rBounds = { 50, 50, 450, 450 } ;
    Str255      title = "\pMarker Pick" ;
 
    InitToolbox() ;
    
    //  Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
    myStatus = Q3Initialize();
 
    if ( myStatus == kQ3Failure )
        DebugStr("\pErInitialize returned failure.");           
 
    // set up our globals
    gQuitFlag = false ;
    gMainWindow = NewCWindow(nil,&rBounds,title,true,noGrowDocProc,(WindowPtr)-1,true,0) ;
 
    InitDocumentData( &gDocument ) ;
    
    MainEventLoop();
    
    DisposeDocumentData( &gDocument ) ;
    
    //  Close our connection to the QuickDraw 3D library
    myStatus = Q3Exit();
    if ( myStatus == kQ3Failure )
        DebugStr("\pErExit returned failure.");
    
}
 
//-------------------------------------------------------------------------------------------
//
 
void InitDocumentData( DocumentPtr theDocument ) 
{
    // sets up the 3d data for the scene
    // Create view for QuickDraw 3D.
    theDocument->fView = MyNewView( (WindowPtr)gMainWindow ) ;
 
    // the main display group:
    theDocument->fModel = MyNewModel() ;
 
    // the drawing styles:
    theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
    theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
    theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
 
    // set the rotation matrix the identity matrix
    Q3Matrix4x4_SetIdentity(&theDocument->fRotation);       
}
 
void DisposeDocumentData( DocumentPtr theDocument)
{
    Q3Object_Dispose(theDocument->fView) ;              // the view for the scene
    Q3Object_Dispose(theDocument->fModel) ;             // object in the scene being modelled
    Q3Object_Dispose(theDocument->fInterpolation) ;     // interpolation style used when rendering
    Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
    Q3Object_Dispose(theDocument->fFillStyle) ;         // whether drawn as solid filled object or decomposed to components
 
}
//-----------------------------------------------------------------------------
// 
 
TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
{   
    Q3View_StartRendering(theDocument->fView );
    do {
        Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );
        Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );
        Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );
        Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView );
        Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );
    } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
    return kQ3Success ;
}
 
 
//----------------------------------------------------------------------------------
 
//-------------------------------------------------------------------------------------------
//
 
short HiWrd(long aLong)
{
    return  (((aLong) >> 16) & 0xFFFF) ;
}
 
//-------------------------------------------------------------------------------------------
//
 
short LoWrd(long aLong)
{
    return  ((aLong) & 0xFFFF) ;
 
}
 
//-------------------------------------------------------------------------------------------
//
 
void InitToolbox()
{
    Handle      menuBar = nil;
 
    MaxApplZone() ;
    MoreMasters() ; MoreMasters() ; MoreMasters() ; 
    
    InitGraf( &qd.thePort );
    InitFonts();
    InitWindows();
    InitCursor();
 
    FlushEvents( everyEvent, 0 ) ;
    // initialize application globals
    
    gQuitFlag = false;
    
}
 
 
//-------------------------------------------------------------------------------------------
//
void MainEventLoop()
{
    EventRecord     event;
    WindowPtr       window;
    short           thePart;
    Rect            screenRect, updateRect;
    Point           aPoint = {100, 100};
    Point           clickPoint;
    CGrafPtr        savedPort ;
    
 
    while( !gQuitFlag )
    {
        if (WaitNextEvent( everyEvent, &event, 0, nil ))
        {
 
            switch (event.what) {
                case mouseDown:
                
                    thePart = FindWindow( event.where, &window );
                    
                    switch( thePart ) {
                        case inMenuBar: 
                            break;
                        
                        case inDrag:
                    
                            screenRect = (**GetGrayRgn()).rgnBBox;
                            DragWindow( window, event.where, &screenRect );
                            break ;
                    
                        case inContent:
                    
                            if (window != FrontWindow())
                                SelectWindow( window );
                            else {
                                GetPort((GrafPtr*)&savedPort);
                                SetPort(window);
                                clickPoint = event.where;
                                GlobalToLocal(&clickPoint);
                                SetPort((GrafPtr)savedPort);
                                DoPick(clickPoint, &gDocument);
                            }
                            break ;
                    
                        case inGoAway:
                            if (TrackGoAway( window, event.where )) {
                                DisposeWindow ( window );
                                gQuitFlag = true;
 
                            }
                            break ;
                            
                        default:
                            break ;
                    }
                    break ;
                            
                        
                case updateEvt:
                
                    window = (WindowPtr)event.message;
                    updateRect = (**(window->visRgn)).rgnBBox;
                    SetPort( window ) ;
                    BeginUpdate( window );
                    DocumentDraw3DData( &gDocument ) ;
                    EndUpdate( window );
                    break ;
                    
                case keyDown:
                case autoKey:
                    HandleKeyPress(&event);
                    break;
                    
                case diskEvt:
                    if ( HiWrd(event.message) != noErr ) 
                        (void) DIBadMount(aPoint, event.message);
                    break;
                    
                case osEvt:
                case activateEvt:
                    break;
 
 
            }
        }
    }
}
 
 
//-------------------------------------------------------------------------------------------
//
void HandleKeyPress(EventRecord *event)
{}
 
//-------------------------------------------------------------------------------------------
//
 
 
 
void DoPick(Point where, DocumentPtr theDocument)
    {
    TQ3WindowPointPickData  data;
    unsigned long           i;
    unsigned long           numHits;
    TQ3PickObject           pick;
    
    data.data.sort = kQ3PickSortNone;
    data.data.mask = 0;
    data.data.numHitsToReturn = kQ3ReturnAllHits;
    
    data.point.x = where.h;
    data.point.y = where.v;
    data.vertexTolerance = 1;
    data.edgeTolerance = 1;
    
    if ((pick = Q3WindowPointPick_New(&data)) == NULL)
        return;
        
    Q3View_StartPicking(theDocument->fView, pick);
    do {
        Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );
    } while (Q3View_EndPicking(theDocument->fView) == kQ3ViewStatusRetraverse );
    
    if (Q3Pick_GetNumHits(pick, &numHits) == kQ3Success)
        for (i=0; i<numHits; i++)
            SysBeep(5);
            
    Q3Object_Dispose(pick);
    }