sources/BoxMooV_document.c

/*  BoxPaint_document.c                                                                         
 
    This contains all the document-specific code.
                                                                                    
    Rick Evans  - September 9, 1996 derived from BoxPaint_document.c
    Michael Bishop - August 21 1996                                                 
    Nick Thompson
    Robert Dierkes                                                                              
    (c)1994-96 Apple computer Inc., All Rights Reserved                             
 
*/
 
 
/* --------------------------------------------------------------------
** Includes
*/
#include    "BoxMooV_document.h"
#include    "BoxPaint_Support.h"
#include    "BoxMooV_window.h"
#include    "BoxMooV_texture.h"
 
/* QuickDraw 3D stuff */
#include "QD3DMath.h"
#include "QD3DTransform.h"
#include "QD3DGroup.h"
#include "QD3DShader.h"
#include "QD3DStorage.h"
#include "QD3DIO.h"
 
/* --------------------------------------------------------------------
** Local Functions
*/
void        Document_Init( DocumentHdl theDocument) ;
 
 
/* -------------------------------------------------------------------------------------------
** Document_Init
** Sets All Variables and objects common to all documents
*/
 
void Document_Init( 
        DocumentHdl theDocument) 
{
    TQ3Point3D      myOrigin = { 0, 0, 0 } ;
    
    if(theDocument == NULL) goto bail;
    
    (**theDocument).fGroupScale = 1;                
    (**theDocument).fGroupCenter = myOrigin ;           
    
    /*  Get a window for it */
    if(((**theDocument).fWindow = Window_New()) == NULL) {
        DisposeHandle( (Handle)theDocument ) ;
    }
    else 
    {           
        
        /*  sets up the 3d data for the scene */
        /*  Create view for QuickDraw 3D. */
        (**theDocument).fView = MyNewView( (**theDocument).fWindow ) ;
 
        /*  the main display group: */
        (**theDocument).fModel = MyNewModel() ;
    
        /*  the drawing styles: */
        (**theDocument).fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
        (**theDocument).fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleRemove ) ;
        (**theDocument).fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
 
        /*  set the rotation matrix the identity matrix */
        Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation);    
            
        /* store a reference to the document record in the window's refcon */
        SetWRefCon ((**theDocument).fWindow, (long)theDocument ) ;
    }
bail:
;
}
 
/* -------------------------------------------------------------------------------------------
** Document_GetFromWindow
** Gets the document associated with a window
*/
 
DocumentHdl Document_GetFromWindow( 
        WindowPtr theWindow)
{
    if (theWindow != NULL)
        return  (DocumentHdl) GetWRefCon ( theWindow );
    else return NULL;
}
 
 
/* -------------------------------------------------------------------------------------------
** Document_Delete
** Destroys and deletes all the data in a document
*/
 
void Document_Delete(
        DocumentHdl theDocument)
{
    if (theDocument != NULL) {
    
        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 */
        
        Texture_Delete((**theDocument).fTexture);
        
        Window_Delete ( (**theDocument).fWindow ) ;             /*  get rid of the window   */
 
        /*  Do this last    */
        DisposeHandle( (Handle)theDocument ) ;
    }
}
 
 
/* -------------------------------------------------------------------------------------------
**  Document_Draw
**  Draws the document in the current DrawContext
*/
 
TQ3Status Document_Draw( DocumentPtr theDocument )
{   
    TQ3Status       status = kQ3Failure;
    
    if(theDocument == NULL) goto bail;
    
    if ((status = Q3View_StartRendering(theDocument->fView)) != kQ3Failure)
    do {
        Document_SubmitScene( theDocument ) ;
    } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
    
bail:
    
    return status ;
 
}
 
/* -------------------------------------------------------------------------------------------
**  Document_New
**  Loads a new Document with a blank (white) canvas for a texture
*/
 
DocumentHdl Document_New(
        void)
{
    DocumentHdl theDocument = (DocumentHdl)NewHandle( sizeof(DocumentRec)) ;
    
    if( theDocument != NULL )
    {
 
        HLock( (Handle)theDocument ) ;
            
        /* init the field to some reasonable values */
 
        Document_Init( theDocument) ;
 
        /*  By passing NULL as the first parameter, we tell the function to
            make a blank offscreen  */
        (**theDocument).fTexture = Texture_New();
 
        /*  Add it to the model */
        Texture_AddToGroup((**theDocument).fTexture, (**theDocument).fModel) ;
 
        AdjustCamera(*theDocument) ;
 
        HUnlock( (Handle)theDocument ) ;
 
    }
 
    return theDocument ;
}
 
/* -------------------------------------------------------------------------------------------
**  Document_Open
**  Loads a new Document with a Pict for a texture
*/
 
DocumentHdl Document_Open(
        void)
{
    DocumentHdl theDocument;
    
    if ( (theDocument = (DocumentHdl)NewHandle( sizeof(DocumentRec))) != NULL )
    {
            
        /* lock the handle and init the field to some reasonable values */
 
        Document_Init(theDocument) ;
 
        (**theDocument).fTexture = Texture_New();
 
        Texture_AddToGroup( (**theDocument).fTexture, (**theDocument).fModel ) ;
 
        HLock( (Handle)theDocument ) ;
 
        AdjustCamera(*theDocument) ;
                
        HUnlock( (Handle)theDocument ) ;
        
    }   
    
    return theDocument ;
    
}
    
/* -------------------------------------------------------------------------------------------
**  Document_SubmitScene
**  if you make a function like this, you can easily use it inside a
**  Rendering or Picking or BoundingSphere/Box loop
**  (See Document_Draw)
*/
 
TQ3Status Document_SubmitScene( 
        DocumentPtr theDocument ) 
{       
    TQ3Vector3D             globalScale;
    TQ3Vector3D             globalTranslate;
    
    globalScale.x = globalScale.y = globalScale.z = theDocument->fGroupScale;
    globalTranslate = *(TQ3Vector3D *)&theDocument->fGroupCenter;
    Q3Vector3D_Scale(&globalTranslate, -1, &globalTranslate);
    Q3Style_Submit(theDocument->fInterpolation, theDocument->fView);
    Q3Style_Submit(theDocument->fBackFacing , theDocument->fView);
    Q3Style_Submit(theDocument->fFillStyle, theDocument->fView);
        
    Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView);
        
    Q3ScaleTransform_Submit(&globalScale, theDocument->fView);
    Q3TranslateTransform_Submit(&globalTranslate, theDocument->fView);
    Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView);
    
    return kQ3Success ;
}
 
 
            
/* -------------------------------------------------------------------------------------------
**  Document_Animate
**  Advance the movie one frame
**  Rotate the box a little
*/
 
void Document_Animate(
        DocumentHdl theDocument)
{
    TQ3Matrix4x4        tmp;
    
    Texture_NextFrame((**theDocument).fTexture);
    
    Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.025, 0.03, 0.02);
    Q3Matrix4x4_Multiply(&(**theDocument).fRotation, &tmp,
                            &(**theDocument).fRotation);
 
}