home *** CD-ROM | disk | FTP | other *** search
- /*********************************/
- /* OBJECT MANAGER */
- /* By Brian Greenstone */
- /*********************************/
-
-
- /***************/
- /* EXTERNALS */
- /***************/
- #include <QD3D.h>
- #include <QD3DGeometry.h>
- #include <QD3DGroup.h>
- #include <QD3DMath.h>
- #include <QD3DTransform.h>
-
- #include "myglobals.h"
- #include "objects.h"
- #include "misc.h"
- #include "qd3d_support.h"
-
- /****************************/
- /* CONSTANTS */
- /****************************/
-
- #define INVALID_NODE_FLAG 0xffffffffL // put into CType when node is deleted
-
-
- /**********************/
- /* VARIABLES */
- /**********************/
-
- // OBJECT LIST
- ObjNode *gFirstNodePtr;
-
- ObjNode *gCurrentNode,*gMostRecentlyAddedNode;
-
- NewObjectDefinitionType gNewObjectDefinition;
-
- TQ3Point3D gCoord;
-
-
- /************************ INIT OBJECT MANAGER **********************/
-
- void InitObjectManager(void)
- {
- gCurrentNode = nil;
- gFirstNodePtr = nil; // no node yet
-
- }
-
-
- /*********************** MAKE NEW OBJECT ******************/
- //
- // MAKE NEW OBJECT & RETURN PTR TO IT
- //
- // The linked list is sorted from LARGEST z to smallest!
- //
-
- ObjNode *MakeNewObject(NewObjectDefinitionType *newObjDef)
- {
- ObjNode *newNodePtr,*scanNodePtr,*reNodePtr;
- long slot;
-
- slot = newObjDef->slot;
-
- /* INITIALIZE NEW NODE */
-
- newNodePtr = (ObjNode *)AllocPtr(sizeof(ObjNode));
- if (newNodePtr == nil)
- DoFatalAlert("\pMakeNewObject: Alloc Ptr failed!");
-
- newNodePtr->SortSlot = slot;
-
- newNodePtr->Type = newObjDef->type;
- newNodePtr->MoveCall = newObjDef->moveCall; // save move routine
- newNodePtr->Genre = newObjDef->genre;
- newNodePtr->Coord = newObjDef->coord;
- newNodePtr->ModeFlags = newObjDef->flags|OBJ_MODE_MOVE;
- newNodePtr->RotX =
- newNodePtr->RotY =
- newNodePtr->RotZ = 0;
- newNodePtr->ScaleX =
- newNodePtr->ScaleY =
- newNodePtr->ScaleZ = 1.0;
-
- newNodePtr->BaseGroup = nil;
-
-
-
- /* FIND INSERTION PLACE FOR NODE */
-
- if (gFirstNodePtr == nil) // special case only entry
- {
- gFirstNodePtr = newNodePtr;
- newNodePtr->PrevNode = nil;
- newNodePtr->NextNode = nil;
- }
- else
- if (slot < gFirstNodePtr->SortSlot) // INSERT AS FIRST NODE
- {
- newNodePtr->PrevNode = nil; // no prev
- newNodePtr->NextNode = gFirstNodePtr; // next pts to old 1st
- gFirstNodePtr->PrevNode = newNodePtr; // old pts to new 1st
- gFirstNodePtr = newNodePtr;
- }
- else
- {
- reNodePtr = gFirstNodePtr;
- scanNodePtr = gFirstNodePtr;
-
- while (scanNodePtr != nil)
- {
- if (slot < scanNodePtr->SortSlot) // INSERT IN MIDDLE HERE
- {
- newNodePtr->NextNode = scanNodePtr;
- newNodePtr->PrevNode = reNodePtr;
- reNodePtr->NextNode = newNodePtr;
- scanNodePtr->PrevNode = newNodePtr;
- goto out;
- }
- reNodePtr = scanNodePtr;
- scanNodePtr=(ObjNode *)scanNodePtr->NextNode; // try next node
- }
-
- newNodePtr->NextNode = nil; // TAG TO END
- newNodePtr->PrevNode = reNodePtr;
- reNodePtr->NextNode = newNodePtr;
- }
-
- out:
- gMostRecentlyAddedNode = newNodePtr; // remember this
- return(newNodePtr);
- }
-
-
- /******************************* MOVE OBJECTS **************************/
-
- void MoveObjects(void)
- {
- ObjNode *thisNodePtr;
-
-
- if (gFirstNodePtr == nil) // see if there are any objects
- return;
-
- thisNodePtr = gFirstNodePtr;
-
- do
- {
- /* NEXT TRY TO MOVE IT */
-
- if ((thisNodePtr->ModeFlags & OBJ_MODE_MOVE) && (thisNodePtr->MoveCall != nil))
- {
- gCurrentNode = thisNodePtr; // set current object node
- thisNodePtr->MoveCall(); // call object's move routine
- }
-
- thisNodePtr = (ObjNode *)thisNodePtr->NextNode; // next node
- }
- while (thisNodePtr != nil);
-
- }
-
- /**************************** DRAW OBJECTS ***************************/
-
- void DrawObjects(QD3DSetupOutputType *viewInfo)
- {
- ObjNode *theNode;
- TQ3Status myStatus;
-
- if (gFirstNodePtr == nil) // see if there are any objects
- return;
-
- theNode = gFirstNodePtr;
-
-
- /* MAIN NODE TASK LOOP */
-
- do
- {
- if (theNode->BaseGroup) // see if group exists
- {
- myStatus = Q3Object_Submit(theNode->BaseGroup,viewInfo->viewObject);
- if ( myStatus == kQ3Failure )
- DoFatalAlert("\p Drawing Q3Object_Submit Failed!");
- }
- theNode = (ObjNode *)theNode->NextNode;
- }while (theNode != nil);
- }
-
-
- /******************** DELETE ALL OBJECTS ********************/
-
- void DeleteAllObjects(void)
- {
- while (gFirstNodePtr != nil)
- DeleteObject(gFirstNodePtr);
- }
-
-
- /************************ DELETE OBJECT ****************/
-
- void DeleteObject(ObjNode *theNode)
- {
- ObjNode *tempNode;
-
- if (theNode == nil) // see if passed a bogus node
- return;
-
- /* PURGE SPECIAL DATA */
-
- if(theNode->BaseGroup)
- {
- Q3Object_Dispose(theNode->BaseGroup);
- theNode->BaseGroup = nil;
- }
-
- /* DO NODE SWITCHING */
-
- if (theNode->PrevNode == nil) // special case 1st node
- {
- gFirstNodePtr = (ObjNode *)theNode->NextNode;
- tempNode = (ObjNode *)theNode->NextNode;
- tempNode->PrevNode = nil;
- }
- else if (theNode->NextNode == nil) // special case last node
- {
- tempNode = (ObjNode *)theNode->PrevNode;
- tempNode->NextNode = nil;
- }
- else // generic middle deletion
- {
- tempNode = (ObjNode *)theNode->PrevNode;
- tempNode->NextNode = theNode->NextNode;
- tempNode = (ObjNode *)theNode->NextNode;
- tempNode->PrevNode = theNode->PrevNode;
- }
-
- DisposePtr((Ptr)theNode);
- }
-
-
- /********************** GET OBJECT INFO *********************/
-
- void GetObjectInfo(ObjNode *theNode)
- {
- gCoord = theNode->Coord;
- }
-
- /********************** UPDATE OBJECT *********************/
-
- void UpdateObject(ObjNode *theNode)
- {
- theNode->Coord = gCoord;
- }
-
-
- /************* MAKE NEW DISPLAY GROUP OBJECT *************/
-
- ObjNode *MakeNewDisplayGroupObject(NewObjectDefinitionType *newObjDef)
- {
- ObjNode *newObj;
-
- newObjDef->genre = DISPLAY_GROUP_GENRE;
-
- newObj = MakeNewObject(newObjDef);
- if (newObj == nil)
- return(nil);
-
- CreateBaseGroup(newObj);
- return(newObj);
- }
-
-
- /************************* ADD GEOMETRY TO DISPLAY GROUP OBJECT ***********************/
- //
- // Attaches a geometry object to the BaseGroup object. MakeNewDisplayGroupObject must have already been
- // called which made the group & transforms.
- //
-
- void AttachGeometryToDisplayGroupObject(ObjNode *theNode, TQ3GeometryObject geometry)
- {
- TQ3GroupPosition groupPosition;
-
- groupPosition = Q3Group_AddObject(theNode->BaseGroup,geometry);
- if (groupPosition == nil)
- DoFatalAlert("\pError: AttachGeometryToDisplayGroupObject");
- }
-
-
- /***************** CREATE BASE GROUP **********************/
- //
- // the base group contains the base translation/rotation transforms
- // plus the link to the heirarchial chain of joint objects if its a skeleton object.
- //
- // NOTE: this is not only used for skeleton objects, but also for display group objects!!!
- //
-
- void CreateBaseGroup(ObjNode *theNode)
- {
- TQ3GroupPosition myGroupPosition;
- TQ3Matrix4x4 transMatrix,scaleMatrix;
- TQ3TransformObject transObject;
-
-
- if (theNode->BaseGroup) // nuke old one
- Q3Object_Dispose(theNode->BaseGroup);
-
-
- /* CREATE THE GROUP OBJECT */
-
- theNode->BaseGroup = Q3DisplayGroup_New();
- if (theNode->BaseGroup == nil)
- DoFatalAlert("\p Couldnt allocate BaseGroup!");
-
-
- /* SETUP BASE MATRIX */
-
- Q3Matrix4x4_SetRotate_XYZ(&theNode->BaseTransformMatrix, // init rotation matrix
- theNode->RotX, theNode->RotY,
- theNode->RotZ);
-
- Q3Matrix4x4_SetTranslate(&transMatrix, theNode->Coord.x, theNode->Coord.y, // make translate matrix
- theNode->Coord.z);
-
- Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix, // mult rot & trans matrices
- &transMatrix,
- &theNode->BaseTransformMatrix);
-
- Q3Matrix4x4_SetScale(&scaleMatrix, theNode->ScaleX,
- theNode->ScaleY,
- theNode->ScaleZ);
-
- Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix, // mult rot & trans matrices
- &scaleMatrix,
- &theNode->BaseTransformMatrix);
-
-
- /* CREATE A MATRIX XFORM */
-
- transObject = Q3MatrixTransform_New(&theNode->BaseTransformMatrix);
- myGroupPosition = Q3Group_AddObject(theNode->BaseGroup, transObject); // add to base group
- if (myGroupPosition == 0)
- DoFatalAlert("\pQ3Group_AddObject Failed!");
- theNode->BaseTransformObject = transObject; // keep illegal ref
- Q3Object_Dispose(transObject);
-
-
- }
-
- /****************** UPDATE OBJECT TRANSFORMS *****************/
- //
- // This updates the skeleton object's base translate & rotate transforms
- //
-
- void UpdateObjectTransforms(ObjNode *theNode)
- {
- TQ3Matrix4x4 scaleMatrix;
-
-
- /* RESET BASE MATRIX */
-
- Q3Matrix4x4_SetRotate_XYZ(&theNode->BaseTransformMatrix, // init rotation matrix
- theNode->RotX, theNode->RotY,
- theNode->RotZ);
-
- TranslateObjectBaseMatrixByXYZ(theNode);
-
-
- Q3Matrix4x4_SetScale(&scaleMatrix, theNode->ScaleX, // do scale
- theNode->ScaleY,
- theNode->ScaleZ);
- TransformObjectBaseMatrix(theNode,&scaleMatrix);
-
- SetObjectTransformMatrix(theNode);
- }
-
-
- /***************** SET OBJECT TRANSFORM MATRIX *******************/
- //
- // This call simply resets the base transform object so that it uses the latest
- // base transform matrix
- //
-
- void SetObjectTransformMatrix(ObjNode *theNode)
- {
- TQ3Status error;
-
- error = Q3MatrixTransform_Set(theNode->BaseTransformObject,&theNode->BaseTransformMatrix);
- if (error != kQ3Success)
- DoFatalAlert("\pQ3MatrixTransform_Set Failed!");
- }
-
-
- /******************** TRANSLATE OBJECT BASE MATRIX BY X/Y/Z *******************/
-
- void TranslateObjectBaseMatrixByXYZ(ObjNode *theNode)
- {
- TQ3Matrix4x4 transMatrix;
-
- Q3Matrix4x4_SetTranslate(&transMatrix, theNode->Coord.x, theNode->Coord.y, // make translate matrix
- theNode->Coord.z);
-
- TransformObjectBaseMatrix(theNode,&transMatrix);
- }
-
-
-
- /***************** TRANSFORM OBJECT BASE MATRIX ******************/
- //
- // This multiplies the current BaseTransformMatrix by the input transform matrix.
- //
-
- void TransformObjectBaseMatrix(ObjNode *theNode, TQ3Matrix4x4 *inMatrix)
- {
- Q3Matrix4x4_Multiply(&theNode->BaseTransformMatrix,
- inMatrix,
- &theNode->BaseTransformMatrix);
- }
-
-
-
-
-
-
-