home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- *
- * File : object.c
- *
- * Abstract : Generic object handler. This module handles the depth
- * sorting and general control flow for the objects in
- * the street.
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1995 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
-
- /*--- Include files ---*/
-
- #include "global.h" /* Application general includes */
-
- /*--- Structure Definitions ---*/
-
- /* All Objects: A single global variable of this type is declared and used
- * to hold the data for all of the objects currently defined
- */
-
- typedef struct
- {
- Object **oppObjects;
- int nEndObject;
- int nAmoObjects;
- RwV3d vDeletePos;
- int nFirst; /* 0-2 : 0 x 1 y 2 z */
- int nSecond;
- int nThird;
- int (*fpCompare)(const void *,const void *);
- } AllObjects;
-
- AllObjects aoGAll;
-
- /*--- Macor and Magic Number definitions */
-
- #define MAX_NUM 20 /* The maximum depth for an object in cyberstreet
- any objects that are further away from the camera
- than this will automatically be deleted */
-
-
- /* Patch for floating point */
-
- #ifdef RWFLOAT
- #define RETURNINT(A) ((int)((A)*65536.0))
- #else
- #define RETURNINT(A) (A)
- #endif
-
- #define INITIAL_OBJECTS 20 /* Initial number of objects */
- #define OBJ_INCREASE 5 /* Allocate space for this many objects
- at a time */
-
- /************************************************************************
- *
- * Function: DefaultRender()
- *
- * Description: The default object render function. This function
- * will be used to render all objects that don't
- * explicitly define their own render function
- *
- * Parameters: opObj - the object to render
- *
- * Return Value: None
- *
- ************************************************************************/
- static void DefaultRender(Object *opObj)
- {
- if (opObj->cpClump)
- {
- /* The default render action is just to translate the clump to
- its final position and render it */
-
- RwTranslateMatrix(RwScratchMatrix(),
- opObj->vPos.x,
- opObj->vPos.y,
- opObj->vPos.z, rwREPLACE);
-
- RwTransformClump(opObj->cpClump, RwScratchMatrix(), rwREPLACE);
- RwRenderClump(opObj->cpClump);
- }
- }
-
- /************************************************************************
- *
- * Function: DefaultUpdate()
- *
- * Description: The default object update function. This function
- * will be used to update all objects that don't
- * explicitly define their own update function
- *
- * Parameters: opObj - the object to update
- *
- * Return Value: None
- *
- ************************************************************************/
- static void
- DefaultUpdate(Object *opObj)
- {
- /* Don't do anything for the default object */
- opObj = opObj;
- }
-
- /************************************************************************
- *
- * Function: DefaultDestroy()
- *
- * Description: The default object destroy function. This function
- * will be used to destroy all objects that don't
- * explicitly define their own destroy function
- *
- * Parameters: opObj - the object to destroy
- *
- * Return Value: None
- *
- ************************************************************************/
- static void
- DefaultDestroy(Object *opObj)
- {
- /* Destroy the RenderWare clump */
- RwDestroyClump(opObj->cpClump);
-
- /* free up the object data */
- free(opObj);
- }
-
- /************************************************************************
- * Object Depth Sorting:
- * We make the following assumptions about the objects in the cyberstreet scene.
- * 1. If 2 objects occupy the same space then they will be drawn in an
- * arbitrary order. We don't want to Z buffer them.
- * 2. The objects are small and self contained, therefore a simple depth sort
- * using the objects origins is sufficient.
- * For these reasons we choose to implement our own scene sorting which because
- * of its specific nature will be quicker than the more general RenderWare
- * scene sorting which will always try to render an accurate result.
- *
- * The algorithm that is used is a simple depth sort, where objects are sorted
- * such that those furthest from the camera are drawn first. We use the standard
- * C library function 'qsort' to perform the sorting.
- *
- * There are 2 mechanisms that are used to determine how best to sort the scene.
- * the implementation of these mechanism varies with camera position.
- * 1. We sort the scene by the most significant axis first down to least
- * least significant. ie if the camera is looking along the X axis, then
- * the x component of an objects position is more important than the y
- * component in determining correct ordering. The order of sorting is
- * assigned as first, second, third
- *
- * 2. Depending on the direction of the camera's at vector, the comparison
- * mechanism varies. ie A camera looking along the positive X axis would
- * sort from maximum X (furthest) to minimum Z (nearest). If the camera
- * was looking along the negative X axis then the sort order would be from
- * minimum X (furthest) to maximum X (nearest). Given this, we need 8
- * comparison functions for qsort which implement all combinations of
- * camera orientation in the 3 axis X, Y, and Z
- *
- *************************************************************************/
-
- /************************************************************************
- *
- * Function: FMaxSMaxTMax()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMaxSMaxTMax(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMinSMaxTMax()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMinSMaxTMax(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMinSMinTMax()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int FMinSMinTMax(const Object **oppF,const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMaxSMinTMax()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMaxSMinTMax(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMaxSMinTMin()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- int FMaxSMinTMin(const Object **oppF,const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
-
- /************************************************************************
- *
- * Function: FMinSMinTMin()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMinSMinTMin(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMinSMaxTMin()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMinSMaxTMin(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
- /************************************************************************
- *
- * Function: FMaxSMaxTMin()
- *
- * Description: qsort comparison function.
- *
- * Parameters: oppF - first object
- * oppS - second object
- *
- * Return Value: -ve if 2nd object is further away than the first
- * 0 if they occupy the same location
- * +ve if the 2nd object is nearer that the first
- *
- ************************************************************************/
- static int
- FMaxSMaxTMin(const Object **oppF, const Object **oppS)
- {
- RwReal nVal;
-
- /* Compare the position of the 2 objects in the Most Significant Axis */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
- {
- return RETURNINT(nVal);
- }
-
- /* Most significant Axis comarison was zero so try the next one */
-
- if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
- {
- return RETURNINT(nVal);
- }
-
- /* Try the least significant axis */
-
- nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
- ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
-
- return RETURNINT(nVal);
- }
-
-
- /************************************************************************
- *
- * Function: ObjectDelete()
- *
- * Description: Delete and object from the cyberstreet scene. Rather
- * than remove it from it current place in the scene and
- * have to shuffle the list about, we just move it to a
- * distant point and then delete all of the objects at
- * this point once the list has been reordered on the
- * next render.
- *
- * Parameters: opObj - object to delete
- *
- * Return Value: None
- *
- ************************************************************************/
- void ObjectDelete(Object *opObj)
- {
- opObj->vPos = aoGAll.vDeletePos;
- }
-
- /************************************************************************
- *
- * Function: ObjectSetup()
- *
- * Description: Initialise an objects data structure.
- *
- * Parameters: opObj - object to set up
- * x, y, z - Initial position for the object
- * cpClump - The RenderWare clump data for the object
- *
- * Return Value: None
- *
- ************************************************************************/
- void
- ObjectSetup(Object *opObj, RwReal x, RwReal y, RwReal z, RwClump *cpClump)
- {
- /* define the functions that will be used to render, update and
- * destroy the object. Not these functions may be overloaded with
- * an object specific routine
- */
- opObj->fpRender = DefaultRender;
- opObj->fpUpdate = DefaultUpdate;
- opObj->fpDestroy = DefaultDestroy;
-
- /* Initialise the objects position
- */
- opObj->vPos.x = x;
- opObj->vPos.y = y;
- opObj->vPos.z = z;
-
- /* The object has no extra information initially. This value may
- * be overloaded later
- */
- opObj->pExtra = NULL;
-
- /* Define the objects clump
- */
- opObj->cpClump = cpClump;
- }
-
- /************************************************************************
- *
- * Function: AllObjectsUpdate()
- *
- * Description: Update the position of all of the objects
- *
- * Parameters: None
- *
- * Return Value: None
- *
- ************************************************************************/
- void
- AllObjectsUpdate(void)
- {
- int nCount; /* Temporary loop control variable */
- Object **oppObj; /* Object pointer used in loop iteration */
- RwV3d vAt; /* The camera look at vector */
- RwV3d vSize; /* The absolute x, y, and z for the camera look at
- vector */
-
- /* Get the camera's look at vector */
-
- RwGetCameraLookAt(cpGCamera,&vAt);
-
- /* based on the camera's look at vector, determine the position that
- * will be used as the 'delete position' for this frame. Any objects
- * that are moved to this position will be deleted after the scene
- * has been sorted.
- */
-
- if (vAt.x < CREAL(0.0))
- {
- aoGAll.vDeletePos.x = CREAL(+MAX_NUM);
- vSize.x = -vAt.x;
- }
- else
- {
- aoGAll.vDeletePos.x = CREAL(-MAX_NUM);
- vSize.x = +vAt.x;
- }
-
- if (vAt.y < CREAL(0.0))
- {
- aoGAll.vDeletePos.y = CREAL(+MAX_NUM);
- vSize.y = -vAt.y;
- }
- else
- {
- aoGAll.vDeletePos.y = CREAL(-MAX_NUM);
- vSize.y = +vAt.y;
- }
-
- if (vAt.z < CREAL(0.0))
- {
- aoGAll.vDeletePos.z = CREAL(+MAX_NUM);
- vSize.z = -vAt.z;
- }
- else
- {
- aoGAll.vDeletePos.z = CREAL(-MAX_NUM);
- vSize.z = +vAt.z;
- }
-
- /* Determine the order that the axis will be compared in when performing
- * the depth sort.
- */
-
- if (vSize.x > vSize.y)
- {
- if (vSize.y > vSize.z)
- {
- /* x > y > z */
- aoGAll.nFirst = 0;
- aoGAll.nSecond = 1;
- aoGAll.nThird = 2;
- }
- else
- {
- /* y smallest */
- aoGAll.nThird = 1;
- if (vSize.x > vSize.z)
- {
- /* x > z > y */
- aoGAll.nFirst = 0;
- aoGAll.nSecond = 2;
- }
- else
- {
- /* z > x > y */
- aoGAll.nFirst = 2;
- aoGAll.nSecond = 0;
- }
- }
- }
- else
- {
- /* y > x */
- if (vSize.y > vSize.z)
- {
- /* y largest */
- aoGAll.nFirst = 1;
- if (vSize.x > vSize.z)
- {
- /* y > x > z */
- aoGAll.nSecond = 0;
- aoGAll.nThird = 2;
- }
- else
- {
- /* y > z > x */
- aoGAll.nSecond = 2;
- aoGAll.nThird = 0;
- }
- }
- else
- {
- /* z > y > x */
- aoGAll.nFirst = 2;
- aoGAll.nSecond = 1;
- aoGAll.nThird = 0;
- }
- }
-
- /* Determine the sort function that we will use based on the cameras
- * at vector
- */
-
- if (((RwReal *)&vAt)[aoGAll.nFirst] > CREAL(0.0))
- {
- /* Max1 */
- if (((RwReal *)&vAt)[aoGAll.nSecond]>CREAL(0.0))
- {
- /* Max2 */
- if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0))
- {
- /* Max 3*/
- aoGAll.fpCompare = FMaxSMaxTMax;
- }
- else
- {
- /* Min 3 */
- aoGAll.fpCompare = FMaxSMaxTMin;
- }
- }
- else
- {
- /* Min2 */
- if (((RwReal *)&vAt)[aoGAll.nThird] > CREAL(0.0))
- {
- /* Max 3*/
- aoGAll.fpCompare = FMaxSMinTMax;
- }
- else
- {
- /* Min 3 */
- aoGAll.fpCompare = FMaxSMinTMin;
- }
- }
- }
- else
- {
- /* Min 1 */
- if (((RwReal *)&vAt)[aoGAll.nSecond]>CREAL(0.0))
- {
- /* Max2 */
- if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0))
- {
- /* Max 3*/
- aoGAll.fpCompare = FMinSMaxTMax;
- }
- else
- {
- /* Min 3 */
- aoGAll.fpCompare = FMinSMaxTMin;
- }
- }
- else
- {
- /* Min2 */
- if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0))
- {
- /* Max 3*/
- aoGAll.fpCompare = FMinSMinTMax;
- }
- else
- {
- /* Min 3 */
- aoGAll.fpCompare = FMinSMinTMin;
- }
- }
- }
-
- /* Call the object update function for all of the objects in the street */
-
- oppObj = aoGAll.oppObjects;
-
- for (nCount=0; nCount < aoGAll.nEndObject; nCount++, oppObj++)
- {
- (*oppObj)->fpUpdate(*oppObj);
- }
- }
-
-
- /************************************************************************
- *
- * Function: AllObjectsSetup()
- *
- * Description: Initialise the global object data structure
- *
- * Parameters: None
- *
- * Return Value: None
- *
- ************************************************************************/
- int AllObjectsSetup(void)
- {
- aoGAll.oppObjects = (Object **) malloc(sizeof(Object *)*INITIAL_OBJECTS);
- aoGAll.nAmoObjects = INITIAL_OBJECTS;
- aoGAll.nEndObject = 0;
-
- return TRUE;
- }
-
- /************************************************************************
- *
- * Function: AllObjectsAddObject()
- *
- * Description: Add an object to the list of global objects
- *
- * Parameters: opObj - the object to add to the global list
- *
- * Return Value: None
- *
- ************************************************************************/
- void AllObjectsAddObject(Object *opObj)
- {
- if (aoGAll.nEndObject == aoGAll.nAmoObjects)
- {
- /* The object list is full. Grow it a bit */
- aoGAll.oppObjects = realloc(aoGAll.oppObjects,
- sizeof(Object *) * (aoGAll.nAmoObjects + OBJ_INCREASE));
- aoGAll.nAmoObjects += OBJ_INCREASE;
- }
-
- /* Add the object to the list */
- aoGAll.oppObjects[aoGAll.nEndObject++] = opObj;
- }
-
- /************************************************************************
- *
- * Function: AllObjectsDestroy()
- *
- * Description: Destroy the global object data structure
- *
- * Parameters: None
- *
- * Return Value: None
- *
- ************************************************************************/
- void
- AllObjectsDestroy(void)
- {
- int nCount;
- Object **oppObj;
-
- /* Destroy all of the objects first */
-
- oppObj = aoGAll.oppObjects;
-
- for (nCount=0; nCount < aoGAll.nEndObject; nCount++, oppObj++)
- {
- (*oppObj)->fpDestroy(*oppObj);
- }
-
- /* Destroy the All Object structure */
-
- free(aoGAll.oppObjects);
- }
-
- /************************************************************************
- *
- * Function: AllObjectsRender()
- *
- * Description: Sort the objects in the scene and then render them
- * from furthest to nearest
- *
- * Parameters: None
- *
- * Return Value: None
- *
- ************************************************************************/
- void
- AllObjectsRender(void)
- {
- int nCount; /* temporary loop control variable */
- int nNewEnd; /* the last object that was rendered */
- Object **oppObj;
-
- /* Order all of the objects */
-
- qsort(aoGAll.oppObjects, aoGAll.nEndObject, sizeof(Object *),
- aoGAll.fpCompare);
-
- /* Render each object using its own render function. We don't
- * attempt to render objects that are at the delete position
- */
-
- nCount = 0;
- oppObj = aoGAll.oppObjects;
-
- while ((nCount < aoGAll.nEndObject) &&
- ((*oppObj)->vPos.x != CREAL(MAX_NUM)) &&
- ((*oppObj)->vPos.x != CREAL(-MAX_NUM)) )
- {
- (*oppObj)->fpRender(*oppObj);
-
- oppObj++;
- nCount++;
- }
-
- /* Delete all the unwanted objects */
-
- nNewEnd = nCount;
-
- while (nCount < aoGAll.nEndObject)
- {
- (*oppObj)->fpDestroy(*oppObj);
-
- oppObj++;
- nCount++;
- }
-
- /* This is the last object now */
- aoGAll.nEndObject = nNewEnd;
- }
-
- /************************************************************************
- *
- * Function: AddStaticObject()
- *
- * Description: Read a clump and position it at a fixed location
- * in the scene
- *
- * Parameters: x, y, z - fixed position for the object
- * name - the RenderWare script file name
- *
- * Return Value: None
- *
- ************************************************************************/
- int
- AddStaticObject(RwReal x, RwReal y, RwReal z, char *name)
- {
- Object *opObj;
- RwClump *cpClump;
-
- if (!(cpClump = DoRwReadShape(name)))
- {
- return FALSE;
- }
-
- /* Create the object data structure */
- opObj = malloc(sizeof(Object));
-
- /* Setup the object and add it to the list of global objects */
-
- ObjectSetup(opObj, x, y, z, cpClump);
- AllObjectsAddObject(opObj);
-
- return TRUE;
- }
-
-