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.
sources/PickOne_document.c
/* PickOne_document.c |
This contains all the document-specific code. |
Michael Bishop - August 21 1996 |
Nick Thompson |
Robert Dierkes |
Scott Kuechle - March 1997 |
(c)1994-97 Apple computer Inc., All Rights Reserved |
*/ |
/* -------------------------------------------------------------------- |
** Includes |
*/ |
#include <Quickdraw.h> /* For Show/HideCursor routines */ |
#include <assert.h> |
#include "PickOne_document.h" |
#include "PickOne_documentStructure.h" |
#include "PickOne_Support.h" |
#include "PickOne_window.h" |
#include "PickOne_utility.h" |
#include "PictRead.h" |
/* QuickDraw 3D stuff */ |
#include "QD3DMath.h" |
#include "QD3DCamera.h" |
#include "QD3DTransform.h" |
#include "QD3DGroup.h" |
#include "QD3DShader.h" |
#include "QD3DStorage.h" |
#include "QD3DIO.h" |
#include "QD3DPick.h" |
#include "QD3DRenderer.h" |
#include "QD3DAcceleration.h" |
/* -------------------------------------------------------------------- |
** Local Functions |
*/ |
static void Document_Init( DocumentHdl theDocument) ; |
static unsigned long Document_DoPick( DocumentPtr theDocument, TQ3PickObject pickObject); |
static TQ3PickObject Document_NewPick(TQ3WindowPointPickData *pWPPData); |
/* ------------------------------------------------------------------------------------------- |
** 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 ) |
{ |
Document_Init(theDocument); |
/* Get a window for it */ |
(**theDocument).fWindow = Window_New(); |
if ((**theDocument).fWindow == NULL) goto bail; |
/* store a reference to the document record in the window's refcon */ |
Window_SetDocument((**theDocument).fWindow, theDocument ) ; |
/* sets up the 3d data for the scene */ |
/* Create view for QuickDraw 3D. */ |
(**theDocument).fView = MyNewView( (**theDocument).fWindow ) ; |
if ((**theDocument).fView == NULL) { BP_DebugString("View could not be created!"); |
goto bail; } |
/* the main display group: */ |
(**theDocument).fModel = MyNewModel(theDocument) ; |
if ((**theDocument).fModel == NULL) goto bail; |
/* the drawing styles: */ |
(**theDocument).fInterpolation = |
Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ; |
if ((**theDocument).fInterpolation == NULL) goto bail; |
(**theDocument).fBackFacing = |
Q3BackfacingStyle_New(kQ3BackfacingStyleRemove ) ; |
if ((**theDocument).fBackFacing == NULL) goto bail; |
(**theDocument).fFillStyle = |
Q3FillStyle_New(kQ3FillStyleFilled ) ; |
if ((**theDocument).fFillStyle == NULL) goto bail; |
} |
return theDocument ; |
bail: |
Document_Dispose(theDocument); |
theDocument = NULL; |
return theDocument; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Dispose |
** Destroys and deletes all the data in a document |
*/ |
void Document_Dispose( DocumentHdl theDocument) |
{ |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
if ((**theDocument).fView != NULL) |
Q3Object_Dispose((**theDocument).fView) ; |
if ((**theDocument).fModel != NULL) |
Q3Object_Dispose((**theDocument).fModel) ; |
if ((**theDocument).fInterpolation != NULL) |
Q3Object_Dispose((**theDocument).fInterpolation) ; |
if ((**theDocument).fBackFacing != NULL) |
Q3Object_Dispose((**theDocument).fBackFacing) ; |
if ((**theDocument).fFillStyle != NULL) |
Q3Object_Dispose((**theDocument).fFillStyle) ; |
if ((**theDocument).fWindow != NULL) |
Window_Dispose ( (**theDocument).fWindow ) ; |
/* Do this last */ |
DisposeHandle( (Handle)theDocument ) ; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_GetCamera |
** Returns the Camera associated with the document |
*/ |
TQ3CameraObject Document_GetCamera(DocumentHdl theDocument) |
{ |
TQ3CameraObject theCamera; |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
Q3View_GetCamera((**theDocument).fView, &theCamera); |
return theCamera; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_GetRendererPreferences |
** Returns the Renderer Preferences associated with the document |
*/ |
TQ3Status Document_GetRendererPreferences(DocumentHdl theDocument, |
long *theVendorID, |
long *theEngineID) |
{ |
TQ3RendererObject theRenderer; |
TQ3Status theStatus = kQ3Success; |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
if (Q3View_GetRenderer((**theDocument).fView, &theRenderer) != kQ3Failure) |
{ |
if (Q3Renderer_GetType(theRenderer) == kQ3RendererTypeInteractive) |
Q3InteractiveRenderer_GetPreferences(theRenderer, theVendorID, theEngineID); |
else theStatus = kQ3Failure; |
Q3Object_Dispose(theRenderer); |
} else theStatus = kQ3Failure; |
return theStatus; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_SetRendererPreferences |
** Sets the Renderer Preferences |
*/ |
TQ3Status Document_SetRendererPreferences(DocumentHdl theDocument, |
long theVendorID, |
long theEngineID) |
{ |
TQ3RendererObject theRenderer; |
TQ3Status theStatus = kQ3Success; |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
if (Q3View_GetRenderer((**theDocument).fView, &theRenderer) != kQ3Failure) |
{ |
if (Q3Renderer_GetType(theRenderer) == kQ3RendererTypeInteractive) |
{ |
Q3InteractiveRenderer_SetPreferences(theRenderer, theVendorID, theEngineID); |
Q3View_SetRenderer((**theDocument).fView, theRenderer); |
} |
else theStatus = kQ3Failure; |
Q3Object_Dispose(theRenderer); |
} else theStatus = kQ3Failure; |
return theStatus; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Open |
** Loads a new Document with a Pict for a texture |
*/ |
TQ3Status Document_Open(DocumentHdl theDocument) |
{ |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
return kQ3Failure; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Save |
** Saves the *Model* |
*/ |
TQ3Status Document_Save(DocumentHdl theDocument) |
{ |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
/* If you can figure out how to save the model, |
This is a good place to put in that code */ |
theDocument; /* in the meantime, no op */ |
return kQ3Failure; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Draw |
** Draws the document in the current DrawContext |
*/ |
TQ3Status Document_Draw( DocumentPtr theDocument ) |
{ |
TQ3Status status = kQ3Failure; |
assert(theDocument != NULL); |
if ((status = Q3View_StartRendering(theDocument->fView)) != kQ3Failure) |
do { |
Document_SubmitScene( theDocument ) ; |
} while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse ); |
bail: |
return status ; |
} |
/* ------------------------------------------------------------------------------------------- |
** 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 ) |
{ |
TQ3Status theStatus = kQ3Success; |
assert(theDocument != NULL); |
/* |
* Interpolation |
*/ |
if (Q3Style_Submit( theDocument->fInterpolation, |
theDocument->fView) == kQ3Failure) |
theStatus = kQ3Failure; |
/* |
* BackFacing |
*/ |
if (Q3Style_Submit( theDocument->fBackFacing , |
theDocument->fView) == kQ3Failure) |
theStatus = kQ3Failure; |
/* |
* FillStyle |
*/ |
if (Q3Style_Submit( theDocument->fFillStyle, |
theDocument->fView) == kQ3Failure) |
theStatus = kQ3Failure; |
/* |
* Model |
*/ |
if (Q3DisplayGroup_Submit( theDocument->fModel, |
theDocument->fView) == kQ3Failure) |
theStatus = kQ3Failure; |
bail: |
return kQ3Success ; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Idle |
** Does the Idle Action |
*/ |
void Document_Idle(DocumentHdl theDocument) |
{ |
TQ3Matrix4x4 tmp; |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
/* For now, this just rotates the model */ |
Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.025, 0.03, 0.02); |
Q3Matrix4x4_Multiply(&(**theDocument).fRotation, &tmp, &(**theDocument).fRotation); |
HLock( (Handle)theDocument ) ; |
Document_Draw(*theDocument); |
HUnlock( (Handle)theDocument ) ; |
} |
/* ------------------------------------------------------------------------------------------- |
** Document_Init |
** Sets All Variables and objects common to all documents |
*/ |
void Document_Init( DocumentHdl theDocument) |
{ |
assert(theDocument != NULL); |
assert(*theDocument != NULL); |
/* NULL out all of the parameters */ |
/* Check out the header file for the parameter comments */ |
(**theDocument).fWindow = NULL ; |
(**theDocument).fView = NULL; |
(**theDocument).fModel = NULL ; |
(**theDocument).fInterpolation = NULL ; |
(**theDocument).fBackFacing = NULL ; |
(**theDocument).fFillStyle = NULL ; |
Q3Matrix4x4_SetIdentity(&(**theDocument).fRotation); |
} |
/* |
* Document_DoPick |
* |
* Submits objects for picking and returns the number of objects hit. |
* |
* This should be identical to DrawDocumentData. |
*/ |
static |
unsigned long Document_DoPick( |
DocumentPtr pDocument, |
TQ3PickObject pickObject) |
{ |
TQ3ViewObject aView; |
TQ3ViewStatus viewStatus; |
unsigned long numHits; |
assert(pDocument != NULL); |
aView = pDocument->fView; |
numHits = 0; |
if (Q3View_StartPicking(aView, pickObject) == kQ3Success) { |
do { |
Document_SubmitScene( pDocument ) ; |
viewStatus = Q3View_EndPicking(aView); |
} while (viewStatus == kQ3ViewStatusRetraverse); |
if (viewStatus == kQ3ViewStatusDone) { |
Q3Pick_GetNumHits(pickObject, &numHits); |
} |
else { |
BP_DebugString("Document_DoPick: Q3View_EndPicking failed."); |
} |
} |
else { |
BP_DebugString("Document_DoPick: Q3View_StartPicking failed."); |
} |
return numHits; |
} |
/* -------------------------------------------------------------------- |
** Document_NewPick |
** Creates a new pick object. pWPPData->point is assumed to be initialized. |
*/ |
static |
TQ3PickObject Document_NewPick( |
TQ3WindowPointPickData *pWPPData) |
{ |
if (pWPPData == NULL) { |
return NULL; |
} |
/* Create the window point pick */ |
pWPPData->data.sort = kQ3PickSortNearToFar; |
pWPPData->data.numHitsToReturn = kQ3ReturnAllHits; |
/* We want all this info */ |
pWPPData->data.mask = kQ3PickDetailMaskObject | |
kQ3PickDetailMaskPath; |
pWPPData->vertexTolerance = |
pWPPData->edgeTolerance = 3.0; |
return (Q3WindowPointPick_New(pWPPData)); |
} |
/*----------------------------------------------------------------------*/ |
/*----------------------------------------------------------------------*/ |
void Document_DoPickAndRotate( DocumentHdl pDocument) |
{ |
TQ3WindowPointPickData wppData; |
TQ3PickObject pickObject; |
TQ3Status status = kQ3Failure; |
TQ3GroupObject theHitGroupObject; /* What we hit: it's the group |
holding the hit object */ |
TQ3HitPath theHitPath; /* the group hierarchy */ |
TQ3PickDetail testDetail; /* Used to check if this mask is valid */ |
assert(pDocument != NULL); |
HLock((Handle)pDocument); |
Utility_MyGetMouse(&wppData.point); |
/* Create a pick */ |
if((pickObject = Document_NewPick(&wppData)) == NULL) { |
BP_DebugString("Document_DrawOnTexture: pickObject == NULL."); |
goto bail; |
} |
if (Q3WindowPointPick_SetPoint(pickObject, &wppData.point) == kQ3Failure) { |
goto bail; |
} |
if (Document_DoPick(*pDocument, pickObject) != 0) { |
/* HERE'S WHERE ALL THE PICKING TAKES PLACE */ |
/* Get the hit path */ |
if ( Q3Pick_GetPickDetailValidMask( pickObject, 0, &testDetail) == kQ3Success) { |
if ( testDetail & kQ3PickDetailMaskPath) { |
if ( Q3Pick_GetPickDetailData(pickObject, 0, kQ3PickDetailMaskPath, &theHitPath) == kQ3Success) { |
/* Get the group that holds the hit object */ |
theHitGroupObject = Utility_GetEnclosingGroup((const TQ3HitPath *)&theHitPath); |
Document_Rotate(pDocument, theHitGroupObject); |
Q3HitPath_EmptyData(&theHitPath); /* Empty the hit path */ |
Q3Object_Dispose(theHitGroupObject); |
} |
} |
} |
Q3Pick_EmptyHitList(pickObject); /* Empty the list */ |
} |
bail: |
if (pickObject != NULL) { |
Q3Object_Dispose(pickObject); |
pickObject = NULL; |
} |
HUnlock((Handle)pDocument); |
} |
/* ------------------------------------------------------------------------------------------- |
** |
** |
*/ |
void Document_Rotate(DocumentHdl theDocumentHdl, |
TQ3GroupObject theGroup) |
{ |
TQ3Point2D newMouse; |
TQ3Point2D oldPoint; |
float dx, dy; |
float width, height; |
float xRot, yRot; |
DocumentPtr theDocument; |
TQ3TransformObject transform; |
TQ3Matrix4x4 matrix, newMatrix; |
TQ3BoundingBox viewBBox; |
TQ3Point3D center; |
TQ3Status status; |
assert(theDocumentHdl != NULL); |
HideCursor(); |
HLock((Handle)theDocumentHdl); |
theDocument = *theDocumentHdl; |
Utility_MyGetMouse(&oldPoint); /* get the mouse in local co-ordinates, */ |
/* local to the current GrafPort */ |
width = theDocument->fWindow->portRect.left - theDocument->fWindow->portRect.right; |
height = theDocument->fWindow->portRect.bottom - theDocument->fWindow->portRect.top; |
while (Utility_MyStillDown()) { |
Utility_MyGetMouse(&newMouse); /* get the mouse in local co-ordinates, */ |
/* local to the current GrafPort */ |
dx = oldPoint.y - newMouse.y; |
dy = newMouse.x - oldPoint.x; |
if ((dx != 0) || (dy != 0)) { |
TQ3Matrix4x4 tempMatrix; |
xRot = ((float) dx * kQ3Pi) / width; |
yRot = ((float) dy * kQ3Pi) / height; |
if ((xRot != 0.0) || (yRot != 0.0)) { |
/* Get the group's transform */ |
transform = Document_GetGroupTransform(theGroup); |
if (transform != NULL) { |
/* Change the transform's matrix with the translation */ |
Q3Transform_GetMatrix(transform, &matrix); |
status = GetDocumentGroupBoundingBox( theDocument->fView, |
theGroup, |
&viewBBox); |
status = ComputeCenterOfBoundingBox(&viewBBox, |
¢er); |
Q3Matrix4x4_SetRotateAboutPoint(&tempMatrix, ¢er, xRot, yRot, 0.0); |
Q3Matrix4x4_Multiply(&matrix, &tempMatrix, &newMatrix); |
Q3MatrixTransform_Set(transform, &newMatrix); |
Document_Draw(theDocument); |
Q3Object_Dispose(transform); |
} |
} |
} |
oldPoint.x = newMouse.x; oldPoint.y = newMouse.y; |
} |
ShowCursor(); |
HUnlock((Handle)theDocumentHdl); |
} |
TQ3TransformObject Document_GetGroupTransform(TQ3GroupObject theGroup) |
{ |
TQ3TransformObject transform; |
TQ3GroupPosition transformPos; |
TQ3Status status; |
/* Get transform's position in this group */ |
transformPos = NULL; |
status = Q3Group_GetFirstPositionOfType(theGroup, |
kQ3ShapeTypeTransform, |
&transformPos); |
if ((status == kQ3Success) && (transformPos != NULL)) { |
/* Get transform's object reference */ |
transform = NULL; |
status = Q3Group_GetPositionObject(theGroup, |
transformPos, |
&transform); |
if ((status == kQ3Success) && (transform != NULL)) { |
return transform; |
} |
} |
return NULL; |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14