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.
Source/Process.c
/****************************/ |
/* PROCESS.C */ |
/* By Brian Greenstone */ |
/****************************/ |
/****************************/ |
/* EXTERNALS */ |
/****************************/ |
#include <QD3D.h> |
#include <QD3DGeometry.h> |
#include <QD3DGroup.h> |
#include <QD3DMath.h> |
#include "myglobals.h" |
#include "objects.h" |
#include "mymenus.h" |
#include "mywindows.h" |
#include "myevents.h" |
#include "misc.h" |
#include "process.h" |
#include "qd3d_support.h" |
#include "3dmf.h" |
extern NewObjectDefinitionType gNewObjectDefinition; |
extern float gFramesPerSecond; |
/****************************/ |
/* PROTOTYPES */ |
/****************************/ |
static void InitModelWindow(void); |
static void CalcBBox(TQ3Object theObject, TQ3BoundingBox *bbox); |
static void BuildTriMeshTest(void); |
static void BuildBBoxOutline(TQ3DisplayGroupObject group, TQ3BoundingBox *bbox); |
static void MoveCamera(void); |
static void BuildSphereTest(void); |
static void BuildTorusTest(void); |
/****************************/ |
/* CONSTANTS */ |
/****************************/ |
#define MODEL_WIND_ID 400 |
/*********************/ |
/* VARIABLES */ |
/*********************/ |
WindowPtr gModelWindow = nil; |
QD3DSetupOutputType gModelViewInfo; |
TQ3DisplayGroupObject gModelGroup[NUM_TEST] = {nil,nil,nil,nil,nil}; |
TQ3Point3D gCameraFrom = { 0,0, .1 }; |
Boolean gUseCullingGroups = kQ3True; |
Boolean gShowBBoxes = kQ3True; |
int gCurrentTest = TEST_TRIMESH; |
/******************** INIT TEST ************************/ |
void InitTest(void) |
{ |
/* INIT THE WINDOW */ |
InitModelWindow(); |
/* CREATE THE TEST MODEL */ |
BuildCurrentTest(); |
QD3D_CalcFramesPerSecond(); |
} |
/************** INIT MODEL WINDOW *******************/ |
static void InitModelWindow(void) |
{ |
QD3DSetupInputType viewDef; |
TQ3Point3D cameraTo = { 0, 0, 0 }; |
TQ3Vector3D cameraUp = { 0.0, 1.0, 0 }; |
TQ3ColorARGB clearColor = {1,0,0,0}; |
TQ3ColorRGB ambientColor = { 1.0, 1.0, 1.0 }; |
TQ3Vector3D fillDirection1 = {1, -.3, -.8 }; |
TQ3Vector3D fillDirection2 = { -1, -.1, -.2 }; |
/* CREATE THE WINDOW */ |
gModelWindow = GetNewCWindow(MODEL_WIND_ID, NIL_POINTER,MOVE_TO_FRONT); |
if (gModelWindow == nil) |
DoFatalAlert("\pWhere did the GameWindow window go?"); |
SetPort((GrafPtr)gModelWindow); |
/***********************/ |
/* SET QD3D PARAMETERS */ |
/***********************/ |
viewDef.view.displayWindow = gModelWindow; |
viewDef.view.rendererType = kQ3RendererTypeInteractive; |
viewDef.view.clearColor = clearColor; |
viewDef.view.paneClip.left = 0; |
viewDef.view.paneClip.right = 0; |
viewDef.view.paneClip.top = 0; |
viewDef.view.paneClip.bottom = 0; |
viewDef.styles.interpolation = kQ3InterpolationStyleVertex; |
viewDef.styles.backfacing = kQ3BackfacingStyleBoth; |
viewDef.styles.fill = kQ3FillStyleFilled; |
viewDef.styles.illuminationType = kQ3IlluminationTypePhong; |
viewDef.camera.from = gCameraFrom; |
viewDef.camera.to = cameraTo; |
viewDef.camera.up = cameraUp; |
viewDef.camera.hither = 5; |
viewDef.camera.yon = 1500; |
viewDef.camera.fov = .9; |
viewDef.lights.ambientBrightness = 0.3; |
viewDef.lights.ambientColor = ambientColor; |
viewDef.lights.numFillLights = 2; |
viewDef.lights.fillDirection[0] = fillDirection1; |
viewDef.lights.fillDirection[1] = fillDirection2; |
viewDef.lights.fillColor[0] = ambientColor; |
viewDef.lights.fillColor[1] = ambientColor; |
viewDef.lights.fillBrightness[0] = .8; |
viewDef.lights.fillBrightness[1] = 0.4; |
QD3D_SetupWindow(&viewDef, &gModelViewInfo); |
} |
/******************** BUILD CURRENT TEST *************************/ |
void BuildCurrentTest(void) |
{ |
ObjNode *newObj; |
float x,y,z; |
switch(gCurrentTest) |
{ |
case TEST_TRIMESH: |
BuildTriMeshTest(); |
break; |
case TEST_SPHERE: |
BuildSphereTest(); |
break; |
case TEST_TORUS: |
BuildTorusTest(); |
break; |
default: |
return; |
} |
DeleteAllObjects(); |
for (x = -1000; x < 1000; x += 300) |
for (y = -1000; y < 1000; y += 300) |
for (z = -1000; z < 1000; z += 300) |
{ |
/* CREATE OBJNODE */ |
gNewObjectDefinition.genre = DISPLAY_GROUP_GENRE; |
gNewObjectDefinition.coord.x = x; |
gNewObjectDefinition.coord.y = y; |
gNewObjectDefinition.coord.z = z; |
gNewObjectDefinition.flags = OBJ_MODE_DRAW; |
gNewObjectDefinition.slot = 100; |
gNewObjectDefinition.moveCall = nil; |
newObj = MakeNewDisplayGroupObject(&gNewObjectDefinition); |
AttachGeometryToDisplayGroupObject(newObj,gModelGroup[gCurrentTest]); |
UpdateObjectTransforms(newObj); |
} |
DrawModelWindow(); |
} |
/******************* DRAW MODEL WINDOW *********************/ |
// |
// Calls the support function QD3D_DrawScene. |
// It passes the view info and a pointer to the game draw callback. |
// |
void DrawModelWindow(void) |
{ |
QD3D_DrawScene(&gModelViewInfo,(void *)DrawObjects); |
} |
/*************** DO MODEL WINDOW NULL EVENT **********************/ |
void DoModelWindowNullEvent(void) |
{ |
QD3D_CalcFramesPerSecond(); |
MoveObjects(); |
MoveCamera(); |
DrawModelWindow(); |
} |
/****************** UPDATE MODEL WINDOW ******************/ |
// |
// Called when there is an update event from the event manager |
// |
void UpdateModelWindow(void) |
{ |
DrawModelWindow(); |
} |
/**************** MOVE CAMERA *****************/ |
static void MoveCamera(void) |
{ |
TQ3Matrix4x4 m; |
Q3Matrix4x4_SetRotate_XYZ(&m, |
1.0f/gFramesPerSecond * .1f, |
0, |
1.1f/gFramesPerSecond * -.15f); |
Q3Point3D_Transform(&gCameraFrom, &m, &gCameraFrom); |
QD3D_UpdateCameraFrom(&gModelViewInfo, &gCameraFrom); |
} |
/*********************** BUILD TRIMESH TEST **************************/ |
static void BuildTriMeshTest(void) |
{ |
TQ3Object obj; |
FSSpec spec; |
TQ3DisplayGroupState state; |
TQ3BoundingBox bbox; |
/* NUKE OLD ONE */ |
if (gModelGroup[TEST_TRIMESH]) |
Q3Object_Dispose(gModelGroup[TEST_TRIMESH]); |
/* LOAD TRIMESH FROM FILE */ |
FSMakeFSSpec(0, 0, "\p:data:tree.3dmf", &spec); |
// FSMakeFSSpec(0, 0, "\p:data:rex.3dmf", &spec); |
obj = Load3DMFModel(&spec); |
/* SEE IF OBJECT IS A GROUP ALREADY */ |
if (Q3Object_IsType(obj,kQ3ShapeTypeGroup)) |
{ |
gModelGroup[TEST_TRIMESH] = obj; |
} |
/* MAKE NEW GROUP & PUT OBJ IN IT */ |
else |
{ |
gModelGroup[TEST_TRIMESH] = Q3DisplayGroup_New(); |
Q3Group_AddObject(gModelGroup[TEST_TRIMESH],obj); |
Q3Object_Dispose(obj); |
} |
/* MAKE GROUP INLINE & ASSIGN BBOX */ |
if (gUseCullingGroups) |
{ |
Q3DisplayGroup_CalcAndUseBoundingBox(gModelGroup[TEST_TRIMESH], // calc & set group's bbox |
kQ3ComputeBoundsExact, |
gModelViewInfo.viewObject); |
Q3DisplayGroup_GetState(gModelGroup[TEST_TRIMESH],&state); // make inline |
state |= kQ3DisplayGroupStateMaskIsInline; |
Q3DisplayGroup_SetState(gModelGroup[TEST_TRIMESH],state); |
} |
if (gShowBBoxes) |
{ |
if (gUseCullingGroups) |
Q3DisplayGroup_GetBoundingBox(gModelGroup[TEST_TRIMESH], &bbox); |
else |
CalcBBox(gModelGroup[TEST_TRIMESH], &bbox); |
BuildBBoxOutline(gModelGroup[TEST_TRIMESH],&bbox); |
} |
} |
/**************** CALC BOUNDING BOX ***********************/ |
static void CalcBBox(TQ3Object theObject, TQ3BoundingBox *bbox) |
{ |
TQ3Status status; |
status = Q3View_StartBoundingBox(gModelViewInfo.viewObject, kQ3ComputeBoundsExact); |
if (status == kQ3Failure) |
DoFatalAlert("\pCalcBBox: Q3View_StartBoundingBox"); |
do |
{ |
status = Q3Object_Submit(theObject,gModelViewInfo.viewObject); |
if (status == kQ3Failure) |
DoFatalAlert("\pCalcBBox: Q3View_StartBoundingBox"); |
}while(Q3View_EndBoundingBox(gModelViewInfo.viewObject, bbox) == kQ3ViewStatusRetraverse); |
} |
/****************** BUILD BBOX OUTLINE **********************/ |
static void BuildBBoxOutline(TQ3DisplayGroupObject group, TQ3BoundingBox *bbox) |
{ |
TQ3Object line; |
TQ3PolyLineData data; |
TQ3LineData data2; |
TQ3Vertex3D verts[5]; |
data.numVertices = 5; |
data.vertices = &verts[0]; |
data.segmentAttributeSet = nil; |
data.polyLineAttributeSet = nil; |
verts[0].attributeSet = nil; |
verts[1].attributeSet = nil; |
verts[2].attributeSet = nil; |
verts[3].attributeSet = nil; |
/* BACK */ |
verts[0].point = bbox->min; // lower left far |
verts[4] = verts[0]; |
verts[1] = verts[0]; |
verts[1].point.x = bbox->max.x; // lower right far |
verts[2] = verts[1]; |
verts[2].point.y = bbox->max.y; // upper right far |
verts[3] = verts[2]; |
verts[3].point.x = bbox->min.x; // upper left far |
line = Q3PolyLine_New(&data); // make new polyline |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
/* FRONT */ |
verts[0].point = bbox->max; // upper right near |
verts[4] = verts[0]; |
verts[1] = verts[0]; |
verts[1].point.x = bbox->min.x; // upper left near |
verts[2] = verts[1]; |
verts[2].point.y = bbox->min.y; // lower left near |
verts[3] = verts[2]; |
verts[3].point.x = bbox->max.x; // lower right near |
line = Q3PolyLine_New(&data); // make new polyline |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
/* LOWER LEFT SPAR */ |
data2.lineAttributeSet = nil; |
data2.vertices[0].attributeSet = nil; |
data2.vertices[1].attributeSet = nil; |
data2.vertices[0].point = bbox->min; // lower left far |
data2.vertices[1].point = data2.vertices[0].point; |
data2.vertices[1].point.z = bbox->max.z; // lower left near |
line = Q3Line_New(&data2); |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
/* LOWER RIGHT SPAR */ |
data2.vertices[0].point.x = bbox->max.x; // lower right far |
data2.vertices[1].point.x = data2.vertices[0].point.x; // lower right near |
line = Q3Line_New(&data2); |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
/* UPPER RIGHT SPAR */ |
data2.vertices[0].point.y = bbox->max.y; // upper right far |
data2.vertices[1].point.y = data2.vertices[0].point.y; // lower right near |
line = Q3Line_New(&data2); |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
/* UPPER LEFT SPAR */ |
data2.vertices[0].point.x = bbox->min.x; // upper left far |
data2.vertices[1].point.x = data2.vertices[0].point.x; // lower left near |
line = Q3Line_New(&data2); |
Q3Group_AddObject(group,line); |
Q3Object_Dispose(line); |
} |
/*********************** BUILD SPHERE TEST **************************/ |
static void BuildSphereTest(void) |
{ |
TQ3EllipsoidData data; |
TQ3Object obj; |
TQ3DisplayGroupState state; |
TQ3BoundingBox bbox; |
/* NUKE OLD ONE */ |
if (gModelGroup[TEST_SPHERE]) |
Q3Object_Dispose(gModelGroup[TEST_SPHERE]); |
/* BUILD THE SPHERE */ |
data.ellipsoidAttributeSet = nil; |
data.interiorAttributeSet = nil; |
data.origin.x = data.origin.y = data.origin.z = 0; |
data.orientation.x = 0; |
data.orientation.y = 80; |
data.orientation.z = 0; |
data.majorRadius.x = 0; |
data.majorRadius.y = 0; |
data.majorRadius.z = 80; |
data.minorRadius.x = 80; |
data.minorRadius.y = 0; |
data.minorRadius.z = 0; |
data.uMax = data.vMax = 1.0; |
data.uMin = data.vMin = 0; |
data.caps = kQ3EndCapNone; |
obj = Q3Ellipsoid_New(&data); |
if (obj == nil) |
DoFatalAlert("\pBuildSphereTest: Q3Ellipsoid_New"); |
/* MAKE NEW GROUP & PUT OBJ IN IT */ |
gModelGroup[TEST_SPHERE] = Q3DisplayGroup_New(); |
if (gModelGroup[TEST_SPHERE] == nil) |
DoFatalAlert("\pBuildSphereTest: Q3DisplayGroup_New"); |
Q3Group_AddObject(gModelGroup[TEST_SPHERE],obj); |
Q3Object_Dispose(obj); |
/* MAKE GROUP INLINE & ASSIGN BBOX */ |
if (gUseCullingGroups) |
{ |
Q3DisplayGroup_CalcAndUseBoundingBox(gModelGroup[TEST_SPHERE], // calc & set group's bbox |
kQ3ComputeBoundsExact, |
gModelViewInfo.viewObject); |
Q3DisplayGroup_GetState(gModelGroup[TEST_SPHERE],&state); // make inline |
state |= kQ3DisplayGroupStateMaskIsInline; |
Q3DisplayGroup_SetState(gModelGroup[TEST_SPHERE],state); |
} |
if (gShowBBoxes) |
{ |
if (gUseCullingGroups) |
Q3DisplayGroup_GetBoundingBox(gModelGroup[TEST_SPHERE], &bbox); |
else |
CalcBBox(gModelGroup[TEST_SPHERE], &bbox); |
BuildBBoxOutline(gModelGroup[TEST_SPHERE],&bbox); |
} |
} |
/*********************** BUILD TORUS TEST **************************/ |
static void BuildTorusTest(void) |
{ |
TQ3TorusData data; |
TQ3Object obj; |
TQ3DisplayGroupState state; |
TQ3BoundingBox bbox; |
/* NUKE OLD ONE */ |
if (gModelGroup[TEST_TORUS]) |
Q3Object_Dispose(gModelGroup[TEST_TORUS]); |
/* BUILD THE SPHERE */ |
data.torusAttributeSet = nil; |
data.interiorAttributeSet = nil; |
data.origin.x = data.origin.y = data.origin.z = 0; |
data.orientation.x = 0; |
data.orientation.y = 50; |
data.orientation.z = 0; |
data.majorRadius.x = 0; |
data.majorRadius.y = 0; |
data.majorRadius.z = 40; |
data.minorRadius.x = 80; |
data.minorRadius.y = 0; |
data.minorRadius.z = 0; |
data.ratio = .4; |
data.uMax = data.vMax = 1.0; |
data.uMin = data.vMin = 0; |
data.caps = kQ3EndCapNone; |
obj = Q3Torus_New(&data); |
if (obj == nil) |
DoFatalAlert("\pBuildTorusTest: Q3Torus_New"); |
/* MAKE NEW GROUP & PUT OBJ IN IT */ |
gModelGroup[TEST_TORUS] = Q3DisplayGroup_New(); |
if (gModelGroup[TEST_TORUS] == nil) |
DoFatalAlert("\pBuildSphereTest: Q3DisplayGroup_New"); |
Q3Group_AddObject(gModelGroup[TEST_TORUS],obj); |
Q3Object_Dispose(obj); |
/* MAKE GROUP INLINE & ASSIGN BBOX */ |
if (gUseCullingGroups) |
{ |
Q3DisplayGroup_CalcAndUseBoundingBox(gModelGroup[TEST_TORUS], // calc & set group's bbox |
kQ3ComputeBoundsExact, |
gModelViewInfo.viewObject); |
Q3DisplayGroup_GetState(gModelGroup[TEST_TORUS],&state); // make inline |
state |= kQ3DisplayGroupStateMaskIsInline; |
Q3DisplayGroup_SetState(gModelGroup[TEST_TORUS],state); |
} |
if (gShowBBoxes) |
{ |
if (gUseCullingGroups) |
Q3DisplayGroup_GetBoundingBox(gModelGroup[TEST_TORUS], &bbox); |
else |
CalcBBox(gModelGroup[TEST_TORUS], &bbox); |
BuildBBoxOutline(gModelGroup[TEST_TORUS],&bbox); |
} |
} |
Copyright © 2003 Apple Computer, Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2003-01-14