home *** CD-ROM | disk | FTP | other *** search
/ Learn 3D Graphics Programming on the PC / Learn_3D_Graphics_Programming_on_the_PC_Ferraro.iso / rwwin / object.c_ / object.bin
Text File  |  1995-11-14  |  30KB  |  948 lines

  1. /**********************************************************************
  2.  *
  3.  * File :     object.c
  4.  *
  5.  * Abstract : Generic object handler. This module handles the depth
  6.  *            sorting and general control flow for the objects in 
  7.  *            the street.
  8.  *
  9.  **********************************************************************
  10.  *
  11.  * This file is a product of Criterion Software Ltd.
  12.  *
  13.  * This file is provided as is with no warranties of any kind and is
  14.  * provided without any obligation on Criterion Software Ltd. or
  15.  * Canon Inc. to assist in its use or modification.
  16.  *
  17.  * Criterion Software Ltd. will not, under any
  18.  * circumstances, be liable for any lost revenue or other damages arising
  19.  * from the use of this file.
  20.  *
  21.  * Copyright (c) 1995 Criterion Software Ltd.
  22.  * All Rights Reserved.
  23.  *
  24.  * RenderWare is a trademark of Canon Inc.
  25.  *
  26.  ************************************************************************/
  27.  
  28. /*--- Include files ---*/
  29.  
  30. #include "global.h"     /* Application general includes */
  31.  
  32. /*--- Structure Definitions ---*/
  33.  
  34. /* All Objects: A single global variable of this type is declared and used
  35.  *  to hold the data for all of the objects currently defined 
  36.  */
  37.  
  38. typedef struct
  39. {
  40.     Object **oppObjects;
  41.     int nEndObject;
  42.     int nAmoObjects;
  43.     RwV3d vDeletePos;
  44.     int nFirst;             /* 0-2 : 0 x 1 y 2 z */
  45.     int nSecond;
  46.     int nThird;
  47.     int (*fpCompare)(const void *,const void *);
  48. } AllObjects;
  49.  
  50. AllObjects aoGAll;
  51.  
  52. /*--- Macor and Magic Number definitions */
  53.  
  54. #define MAX_NUM     20   /* The maximum depth for an object in cyberstreet
  55.                             any objects that are further away from the camera
  56.                             than this will automatically be deleted */
  57.  
  58.  
  59. /* RETURNINT: This macro is used to return a value to the qsort function.
  60.  * we convert the floating point value into an equivalent integer comparison 
  61.  */
  62. #define RETURNINT(A) (((A) < CREAL(0.0)) ? -1 : (((A) > CREAL(0.0)) ? 1 : 0))
  63.  
  64. #define INITIAL_OBJECTS  20  /* Initial number of objects */
  65. #define OBJ_INCREASE 5       /* Allocate space for this many objects 
  66.                                 at a time */
  67.  
  68. /************************************************************************
  69.  *
  70.  *      Function:       DefaultRender()
  71.  *                      
  72.  *      Description:    The default object render function. This function
  73.  *                      will be used to render all objects that don't 
  74.  *                      explicitly define their own render function
  75.  *
  76.  *      Parameters:     opObj - the object to render
  77.  *
  78.  *      Return Value:   None
  79.  *
  80.  ************************************************************************/
  81. static void DefaultRender(Object *opObj)
  82. {
  83.     if (opObj->cpClump) 
  84.     {
  85.         /* The default render action is just to translate the clump to 
  86.            its final position and render it */
  87.  
  88.         RwTranslateMatrix(RwScratchMatrix(),
  89.                           opObj->vPos.x,
  90.                           opObj->vPos.y,
  91.                           opObj->vPos.z, rwREPLACE);
  92.  
  93.         RwTransformClump(opObj->cpClump, RwScratchMatrix(), rwREPLACE);
  94.         RwRenderClump(opObj->cpClump);
  95.     }
  96. }
  97.  
  98. /************************************************************************
  99.  *
  100.  *      Function:       DefaultUpdate()
  101.  *                      
  102.  *      Description:    The default object update function. This function
  103.  *                      will be used to update all objects that don't 
  104.  *                      explicitly define their own update function
  105.  *
  106.  *      Parameters:     opObj - the object to update
  107.  *
  108.  *      Return Value:   None
  109.  *
  110.  ************************************************************************/
  111. static void 
  112. DefaultUpdate(Object *opObj)
  113. {
  114.     /* Don't do anything for the default object */
  115. }
  116.  
  117. /************************************************************************
  118.  *
  119.  *      Function:       DefaultDestroy()
  120.  *                      
  121.  *      Description:    The default object destroy function. This function
  122.  *                      will be used to destroy all objects that don't 
  123.  *                      explicitly define their own destroy function
  124.  *
  125.  *      Parameters:     opObj - the object to destroy
  126.  *
  127.  *      Return Value:   None
  128.  *
  129.  ************************************************************************/
  130. static void 
  131. DefaultDestroy(Object *opObj)
  132. {
  133.     /* Destroy the RenderWare clump */
  134.     RwDestroyClump(opObj->cpClump);
  135.  
  136.     /* free up the object data */
  137.     free(opObj); 
  138. }
  139.  
  140. /************************************************************************
  141.  * Object Depth Sorting:
  142.  * We make the following assumptions about the objects in the cyberstreet scene.
  143.  * 1. If 2 objects occupy the same space then they will be drawn in an
  144.  *    arbitrary order. We don't want to Z buffer them.
  145.  * 2. The objects are small and self contained, therefore a simple depth sort
  146.  *    using the objects origins is sufficient.
  147.  * For these reasons we choose to implement our own scene sorting which because
  148.  * of its specific nature will be quicker than the more general RenderWare 
  149.  * scene sorting which will always try to render an accurate result.
  150.  *
  151.  * The algorithm that is used is a simple depth sort, where objects are sorted
  152.  * such that those furthest from the camera are drawn first. We use the standard
  153.  * C library function 'qsort' to perform the sorting.
  154.  *
  155.  * There are 2 mechanisms that are used to determine how best to sort the scene.
  156.  * the implementation of these mechanism varies with camera position.
  157.  * 1. We sort the scene by the most significant axis first down to least 
  158.  *    least significant. ie if the camera is looking along the X axis, then 
  159.  *    the x component of an objects position is more important than the y 
  160.  *    component in determining correct ordering. The order of sorting is
  161.  *    assigned as first, second, third
  162.  *
  163.  * 2. Depending on the direction of the camera's at vector, the comparison
  164.  *    mechanism varies. ie A camera looking along the positive X axis would 
  165.  *    sort from maximum X (furthest) to minimum Z (nearest). If the camera
  166.  *    was looking along the negative X axis then the sort order would be from
  167.  *    minimum X (furthest) to maximum X (nearest). Given this, we need 8
  168.  *    comparison functions for qsort which implement all combinations of
  169.  *    camera orientation in the 3 axis X, Y, and Z
  170.  *
  171.  *************************************************************************/
  172.  
  173. /************************************************************************
  174.  *
  175.  *      Function:       FMaxSMaxTMax()
  176.  *                      
  177.  *      Description:    qsort comparison function. 
  178.  *
  179.  *      Parameters:     oppF - first object
  180.  *                      oppS - second object
  181.  *
  182.  *      Return Value:   -ve if 2nd object is further away than the first
  183.  *                      0 if they occupy the same location
  184.  *                      +ve if the 2nd object is nearer that the first
  185.  *
  186.  ************************************************************************/
  187. static int 
  188. FMaxSMaxTMax(const Object **oppF, const Object **oppS)
  189. {
  190.     RwReal nVal;
  191.  
  192.     /* Compare the position of the 2 objects in the Most Significant Axis */
  193.   
  194.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
  195.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] ) 
  196.     {
  197.         return RETURNINT(nVal);
  198.     }
  199.  
  200.     /* Most significant Axis comarison was zero so try the next one */
  201.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
  202.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  203.     {
  204.         return RETURNINT(nVal);
  205.     }
  206.  
  207.     /* Try the least significant axis */
  208.  
  209.     nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
  210.             ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  211.  
  212.     return RETURNINT(nVal);
  213. }
  214.  
  215. /************************************************************************
  216.  *
  217.  *      Function:       FMinSMaxTMax()
  218.  *                      
  219.  *      Description:    qsort comparison function. 
  220.  *
  221.  *      Parameters:     oppF - first object
  222.  *                      oppS - second object
  223.  *
  224.  *      Return Value:   -ve if 2nd object is further away than the first
  225.  *                      0 if they occupy the same location
  226.  *                      +ve if the 2nd object is nearer that the first
  227.  *
  228.  ************************************************************************/
  229. static int 
  230. FMinSMaxTMax(const Object **oppF, const Object **oppS)
  231. {
  232.     RwReal nVal;
  233.  
  234.     /* Compare the position of the 2 objects in the Most Significant Axis */
  235.  
  236.     if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
  237.                ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  238.     {
  239.         return RETURNINT(nVal);
  240.     }
  241.  
  242.     /* Most significant Axis comarison was zero so try the next one */
  243.  
  244.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
  245.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  246.     {
  247.         return RETURNINT(nVal);
  248.     }
  249.  
  250.     /* Try the least significant axis */
  251.  
  252.     nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
  253.             ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  254.     
  255.     return RETURNINT(nVal);
  256. }
  257.  
  258. /************************************************************************
  259.  *
  260.  *      Function:       FMinSMinTMax()
  261.  *                      
  262.  *      Description:    qsort comparison function. 
  263.  *
  264.  *      Parameters:     oppF - first object
  265.  *                      oppS - second object
  266.  *
  267.  *      Return Value:   -ve if 2nd object is further away than the first
  268.  *                      0 if they occupy the same location
  269.  *                      +ve if the 2nd object is nearer that the first
  270.  *
  271.  ************************************************************************/
  272. static int FMinSMinTMax(const Object **oppF,const Object **oppS)
  273. {
  274.     RwReal nVal;
  275.  
  276.     /* Compare the position of the 2 objects in the Most Significant Axis */
  277.  
  278.     if (nVal =  ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
  279.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  280.     {
  281.         return RETURNINT(nVal);
  282.     }
  283.  
  284.     /* Most significant Axis comarison was zero so try the next one */
  285.  
  286.     if (nVal =  ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
  287.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] ) 
  288.     {
  289.         return RETURNINT(nVal);
  290.     }
  291.  
  292.     /* Try the least significant axis */
  293.  
  294.      nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
  295.              ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  296.     
  297.     return RETURNINT(nVal);
  298. }
  299.  
  300. /************************************************************************
  301.  *
  302.  *      Function:       FMaxSMinTMax()
  303.  *                      
  304.  *      Description:    qsort comparison function. 
  305.  *
  306.  *      Parameters:     oppF - first object
  307.  *                      oppS - second object
  308.  *
  309.  *      Return Value:   -ve if 2nd object is further away than the first
  310.  *                      0 if they occupy the same location
  311.  *                      +ve if the 2nd object is nearer that the first
  312.  *
  313.  ************************************************************************/
  314. static int 
  315. FMaxSMinTMax(const Object **oppF, const Object **oppS)
  316. {
  317.     RwReal nVal;
  318.  
  319.     /* Compare the position of the 2 objects in the Most Significant Axis */
  320.  
  321.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
  322.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  323.     {
  324.         return RETURNINT(nVal);
  325.     }
  326.  
  327.     /* Most significant Axis comarison was zero so try the next one */
  328.  
  329.     if (nVal =  ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
  330.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  331.     {
  332.         return RETURNINT(nVal);
  333.     }
  334.  
  335.     /* Try the least significant axis */
  336.  
  337.     nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] +
  338.             ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  339.   
  340.     return RETURNINT(nVal);
  341. }
  342.  
  343. /************************************************************************
  344.  *
  345.  *      Function:       FMaxSMinTMin()
  346.  *                      
  347.  *      Description:    qsort comparison function. 
  348.  *
  349.  *      Parameters:     oppF - first object
  350.  *                      oppS - second object
  351.  *
  352.  *      Return Value:   -ve if 2nd object is further away than the first
  353.  *                      0 if they occupy the same location
  354.  *                      +ve if the 2nd object is nearer that the first
  355.  *
  356.  ************************************************************************/
  357. int FMaxSMinTMin(const Object **oppF,const Object **oppS)
  358. {
  359.     RwReal nVal;
  360.  
  361.     /* Compare the position of the 2 objects in the Most Significant Axis */
  362.  
  363.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
  364.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  365.     {
  366.         return RETURNINT(nVal);
  367.     }
  368.  
  369.     /* Most significant Axis comarison was zero so try the next one */
  370.  
  371.     if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
  372.                ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  373.     {
  374.         return RETURNINT(nVal);
  375.     }
  376.  
  377.     /* Try the least significant axis */
  378.  
  379.     nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
  380.            ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  381.     
  382.     return RETURNINT(nVal);
  383. }
  384.  
  385.  
  386. /************************************************************************
  387.  *
  388.  *      Function:       FMinSMinTMin()
  389.  *                      
  390.  *      Description:    qsort comparison function. 
  391.  *
  392.  *      Parameters:     oppF - first object
  393.  *                      oppS - second object
  394.  *
  395.  *      Return Value:   -ve if 2nd object is further away than the first
  396.  *                      0 if they occupy the same location
  397.  *                      +ve if the 2nd object is nearer that the first
  398.  *
  399.  ************************************************************************/
  400. static int 
  401. FMinSMinTMin(const Object **oppF, const Object **oppS)
  402. {
  403.     RwReal nVal;
  404.  
  405.     /* Compare the position of the 2 objects in the Most Significant Axis */
  406.  
  407.     if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
  408.                ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  409.     {
  410.         return RETURNINT(nVal);
  411.     }
  412.  
  413.     /* Most significant Axis comarison was zero so try the next one */
  414.  
  415.     if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] -
  416.                ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] ) 
  417.     {
  418.         return RETURNINT(nVal);
  419.     }
  420.  
  421.     /* Try the least significant axis */
  422.  
  423.     nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
  424.            ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  425.   
  426.     return RETURNINT(nVal);
  427. }
  428.  
  429. /************************************************************************
  430.  *
  431.  *      Function:       FMinSMaxTMin()
  432.  *                      
  433.  *      Description:    qsort comparison function. 
  434.  *
  435.  *      Parameters:     oppF - first object
  436.  *                      oppS - second object
  437.  *
  438.  *      Return Value:   -ve if 2nd object is further away than the first
  439.  *                      0 if they occupy the same location
  440.  *                      +ve if the 2nd object is nearer that the first
  441.  *
  442.  ************************************************************************/
  443. static int 
  444. FMinSMaxTMin(const Object **oppF, const Object **oppS)
  445. {
  446.     RwReal nVal;
  447.  
  448.     /* Compare the position of the 2 objects in the Most Significant Axis */
  449.  
  450.     if (nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] -
  451.                ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] ) 
  452.     {
  453.         return RETURNINT(nVal);
  454.     }
  455.  
  456.     /* Most significant Axis comarison was zero so try the next one */
  457.  
  458.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
  459.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  460.     {
  461.         return RETURNINT(nVal);
  462.     }
  463.  
  464.     /* Try the least significant axis */
  465.  
  466.     nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
  467.            ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  468.     
  469.     return RETURNINT(nVal);
  470. }
  471.  
  472. /************************************************************************
  473.  *
  474.  *      Function:       FMaxSMaxTMin()
  475.  *                      
  476.  *      Description:    qsort comparison function. 
  477.  *
  478.  *      Parameters:     oppF - first object
  479.  *                      oppS - second object
  480.  *
  481.  *      Return Value:   -ve if 2nd object is further away than the first
  482.  *                      0 if they occupy the same location
  483.  *                      +ve if the 2nd object is nearer that the first
  484.  *
  485.  ************************************************************************/
  486. static int 
  487. FMaxSMaxTMin(const Object **oppF, const Object **oppS)
  488. {
  489.     RwReal nVal;
  490.  
  491.     /* Compare the position of the 2 objects in the Most Significant Axis */
  492.  
  493.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nFirst] +
  494.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nFirst] )
  495.     {
  496.         return RETURNINT(nVal);
  497.     }
  498.  
  499.     /* Most significant Axis comarison was zero so try the next one */
  500.  
  501.     if (nVal = -((RwReal *)(&((*oppF)->vPos)))[aoGAll.nSecond] +
  502.                 ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nSecond] )
  503.     {
  504.         return RETURNINT(nVal);
  505.     }
  506.  
  507.     /* Try the least significant axis */
  508.  
  509.     nVal = ((RwReal *)(&((*oppF)->vPos)))[aoGAll.nThird] -
  510.            ((RwReal *)(&((*oppS)->vPos)))[aoGAll.nThird];
  511.   
  512.     return RETURNINT(nVal);
  513. }
  514.  
  515.  
  516. /************************************************************************
  517.  *
  518.  *      Function:       ObjectDelete()
  519.  *                      
  520.  *      Description:    Delete and object from the cyberstreet scene. Rather
  521.  *                      than remove it from it current place in the scene and 
  522.  *                      have to shuffle the list about, we just move it to a
  523.  *                      distant point and then delete all of the objects at 
  524.  *                      this point once the list has been reordered on the 
  525.  *                      next render. 
  526.  *
  527.  *      Parameters:     opObj - object to delete
  528.  *
  529.  *      Return Value:   None
  530.  *
  531.  ************************************************************************/
  532. void ObjectDelete(Object *opObj)
  533. {
  534.     opObj->vPos = aoGAll.vDeletePos;
  535. }
  536.  
  537. /************************************************************************
  538.  *
  539.  *      Function:       ObjectSetup()
  540.  *                      
  541.  *      Description:    Initialise an objects data structure. 
  542.  *
  543.  *      Parameters:     opObj - object to set up
  544.  *                      x, y, z - Initial position for the object
  545.  *                      cpClump - The RenderWare clump data for the object
  546.  *
  547.  *      Return Value:   None
  548.  *
  549.  ************************************************************************/
  550. void 
  551. ObjectSetup(Object *opObj, RwReal x, RwReal y, RwReal z, RwClump *cpClump)
  552. {
  553.     /* define the functions that will be used to render, update and
  554.      * destroy the object. Not these functions may be overloaded with
  555.      * an object specific routine
  556.      */
  557.     opObj->fpRender = DefaultRender;
  558.     opObj->fpUpdate = DefaultUpdate;
  559.     opObj->fpDestroy = DefaultDestroy;
  560.  
  561.     /* Initialise the objects position
  562.      */
  563.     opObj->vPos.x = x;
  564.     opObj->vPos.y = y;
  565.     opObj->vPos.z = z;
  566.  
  567.     /* The object has no extra information initially. This value may
  568.      * be overloaded later
  569.      */
  570.     opObj->pExtra = NULL;
  571.  
  572.     /* Define the objects clump
  573.      */
  574.     opObj->cpClump = cpClump;
  575. }
  576.  
  577. /************************************************************************
  578.  *
  579.  *      Function:       AllObjectsUpdate()
  580.  *                      
  581.  *      Description:    Update the position of all of the objects
  582.  *
  583.  *      Parameters:     None
  584.  *
  585.  *      Return Value:   None
  586.  *
  587.  ************************************************************************/
  588. void 
  589. AllObjectsUpdate(void)
  590. {
  591.     int nCount;         /* Temporary loop control variable */
  592.     Object **oppObj;    /* Object pointer used in loop iteration */
  593.     RwV3d vAt;          /* The camera look at vector */
  594.     RwV3d vSize;        /* The absolute x, y, and z for the camera look at 
  595.                            vector */
  596.  
  597.     /* Get the camera's look at vector */
  598.  
  599.     RwGetCameraLookAt(cpGCamera,&vAt);
  600.  
  601.     /* based on the camera's look at vector, determine the position that 
  602.      * will be used as the 'delete position' for this frame. Any objects
  603.      * that are moved to this position will be deleted after the scene
  604.      * has been sorted.
  605.      */
  606.  
  607.     if (vAt.x < CREAL(0.0)) 
  608.     {
  609.         aoGAll.vDeletePos.x = CREAL(+MAX_NUM);
  610.         vSize.x = -vAt.x;
  611.     } 
  612.     else 
  613.     {
  614.         aoGAll.vDeletePos.x = CREAL(-MAX_NUM);
  615.         vSize.x = +vAt.x;
  616.     }
  617.  
  618.     if (vAt.y < CREAL(0.0)) 
  619.     {
  620.         aoGAll.vDeletePos.y = CREAL(+MAX_NUM);
  621.         vSize.y = -vAt.y;
  622.     } 
  623.     else 
  624.     {
  625.         aoGAll.vDeletePos.y = CREAL(-MAX_NUM);
  626.         vSize.y = +vAt.y;
  627.     }
  628.  
  629.     if (vAt.z < CREAL(0.0)) 
  630.     {
  631.         aoGAll.vDeletePos.z = CREAL(+MAX_NUM);
  632.         vSize.z = -vAt.z;
  633.     }
  634.     else 
  635.     {
  636.         aoGAll.vDeletePos.z = CREAL(-MAX_NUM);
  637.         vSize.z = +vAt.z;
  638.     }
  639.  
  640.     /* Determine the order that the axis will be compared in when performing
  641.      * the depth sort. 
  642.      */
  643.  
  644.     if (vSize.x > vSize.y) 
  645.     {
  646.         if (vSize.y > vSize.z) 
  647.         {
  648.             /* x > y > z */
  649.             aoGAll.nFirst = 0;
  650.             aoGAll.nSecond = 1;
  651.             aoGAll.nThird = 2;
  652.         } 
  653.         else 
  654.         {
  655.             /* y smallest */
  656.             aoGAll.nThird = 1;
  657.             if (vSize.x > vSize.z) 
  658.             {
  659.                 /* x > z > y */
  660.                 aoGAll.nFirst = 0;
  661.                 aoGAll.nSecond = 2;
  662.             } 
  663.             else 
  664.             {
  665.                 /* z > x > y */
  666.                 aoGAll.nFirst = 2;
  667.                 aoGAll.nSecond = 0;
  668.             }
  669.         }
  670.     }
  671.     else 
  672.     {
  673.         /* y > x */
  674.         if (vSize.y > vSize.z) 
  675.         {
  676.             /* y largest */
  677.             aoGAll.nFirst = 1;
  678.             if (vSize.x > vSize.z) 
  679.             {
  680.                 /* y > x > z */
  681.                 aoGAll.nSecond = 0;
  682.                 aoGAll.nThird = 2;
  683.             }
  684.             else 
  685.             {
  686.                 /* y > z > x */
  687.                 aoGAll.nSecond = 2;
  688.                 aoGAll.nThird = 0;
  689.             }
  690.         } 
  691.         else 
  692.         {
  693.             /* z > y > x */
  694.             aoGAll.nFirst = 2;
  695.             aoGAll.nSecond = 1;
  696.             aoGAll.nThird = 0;
  697.         }
  698.     }
  699.  
  700.     /* Determine the sort function that we will use based on the cameras
  701.      * at vector
  702.      */
  703.  
  704.     if (((RwReal *)&vAt)[aoGAll.nFirst] > CREAL(0.0)) 
  705.     {
  706.         /* Max1 */
  707.         if (((RwReal *)&vAt)[aoGAll.nSecond]>CREAL(0.0)) 
  708.         {
  709.             /* Max2 */
  710.             if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0)) 
  711.             {
  712.                 /* Max 3*/
  713.                 aoGAll.fpCompare = FMaxSMaxTMax;
  714.             } 
  715.             else 
  716.             {
  717.                 /* Min 3 */
  718.                 aoGAll.fpCompare = FMaxSMaxTMin;
  719.             }
  720.         } 
  721.         else 
  722.         {
  723.             /* Min2 */
  724.             if (((RwReal *)&vAt)[aoGAll.nThird] > CREAL(0.0)) 
  725.             {
  726.                 /* Max 3*/
  727.                 aoGAll.fpCompare = FMaxSMinTMax;
  728.             } 
  729.             else 
  730.             {
  731.                 /* Min 3 */
  732.                 aoGAll.fpCompare = FMaxSMinTMin;
  733.             }
  734.         }
  735.     } 
  736.     else 
  737.     {
  738.         /* Min 1 */
  739.         if (((RwReal *)&vAt)[aoGAll.nSecond]>CREAL(0.0)) 
  740.         {
  741.             /* Max2 */
  742.             if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0)) 
  743.             {
  744.                 /* Max 3*/
  745.                 aoGAll.fpCompare = FMinSMaxTMax;
  746.             } 
  747.             else 
  748.             {
  749.                 /* Min 3 */
  750.                 aoGAll.fpCompare = FMinSMaxTMin;
  751.             }
  752.         } 
  753.         else 
  754.         {
  755.             /* Min2 */
  756.             if (((RwReal *)&vAt)[aoGAll.nThird]>CREAL(0.0)) 
  757.             {
  758.                 /* Max 3*/
  759.                 aoGAll.fpCompare = FMinSMinTMax;
  760.             } 
  761.             else 
  762.             {
  763.                 /* Min 3 */
  764.                 aoGAll.fpCompare = FMinSMinTMin;
  765.             }
  766.         }
  767.     }
  768.  
  769.     /* Call the object update function for all of the objects in the street */
  770.  
  771.     oppObj = aoGAll.oppObjects;
  772.  
  773.     for (nCount=0; nCount < aoGAll.nEndObject; nCount++, oppObj++)
  774.     {
  775.         (*oppObj)->fpUpdate(*oppObj);
  776.     }
  777. }
  778.  
  779.  
  780. /************************************************************************
  781.  *
  782.  *      Function:       AllObjectsSetup()
  783.  *                      
  784.  *      Description:    Initialise the global object data structure
  785.  *
  786.  *      Parameters:     None
  787.  *
  788.  *      Return Value:   None
  789.  *
  790.  ************************************************************************/
  791. int AllObjectsSetup(void)
  792. {
  793.     aoGAll.oppObjects = (Object **) malloc(sizeof(Object *)*INITIAL_OBJECTS);
  794.     aoGAll.nAmoObjects = INITIAL_OBJECTS;
  795.     aoGAll.nEndObject = 0;
  796.  
  797.   return TRUE;
  798. }
  799.  
  800. /************************************************************************
  801.  *
  802.  *      Function:       AllObjectsAddObject()
  803.  *                      
  804.  *      Description:    Add an object to the list of global objects
  805.  *
  806.  *      Parameters:     opObj - the object to add to the global list
  807.  *
  808.  *      Return Value:   None
  809.  *
  810.  ************************************************************************/
  811. void AllObjectsAddObject(Object *opObj)
  812. {
  813.     if (aoGAll.nEndObject == aoGAll.nAmoObjects) 
  814.     {
  815.         /* The object list is full. Grow it a bit */
  816.         aoGAll.oppObjects = realloc(aoGAll.oppObjects,
  817.                                     sizeof(Object *) * (aoGAll.nAmoObjects + OBJ_INCREASE));
  818.         aoGAll.nAmoObjects += OBJ_INCREASE;
  819.     }
  820.  
  821.     /* Add the object to the list */
  822.     aoGAll.oppObjects[aoGAll.nEndObject++] = opObj;
  823. }
  824.  
  825. /************************************************************************
  826.  *
  827.  *      Function:       AllObjectsDestroy()
  828.  *                      
  829.  *      Description:    Destroy the global object data structure
  830.  *
  831.  *      Parameters:     None
  832.  *
  833.  *      Return Value:   None
  834.  *
  835.  ************************************************************************/
  836. void 
  837. AllObjectsDestroy(void)
  838. {
  839.     int nCount;
  840.     Object **oppObj;
  841.  
  842.     /* Destroy all of the objects first */
  843.  
  844.     oppObj = aoGAll.oppObjects;
  845.  
  846.     for (nCount=0; nCount < aoGAll.nEndObject; nCount++, oppObj++)
  847.     {
  848.         (*oppObj)->fpDestroy(*oppObj);
  849.     }
  850.  
  851.     /* Destroy the All Object structure */
  852.  
  853.     free(aoGAll.oppObjects);
  854. }
  855.  
  856. /************************************************************************
  857.  *
  858.  *      Function:       AllObjectsRender()
  859.  *                      
  860.  *      Description:    Sort the objects in the scene and then render them
  861.  *                      from furthest to nearest
  862.  *
  863.  *      Parameters:     None
  864.  *
  865.  *      Return Value:   None
  866.  *
  867.  ************************************************************************/
  868. void 
  869. AllObjectsRender(void)
  870. {
  871.     int nCount;     /* temporary loop control variable */
  872.     int nNewEnd;    /* the last object that was rendered */
  873.     Object **oppObj;
  874.  
  875.     /* Order all of the objects */
  876.  
  877.     qsort(aoGAll.oppObjects, aoGAll.nEndObject, sizeof(Object *),
  878.          aoGAll.fpCompare);
  879.  
  880.     /* Render each object using its own render function. We don't 
  881.      * attempt to render objects that are at the delete position
  882.      */
  883.  
  884.     nCount = 0;
  885.     oppObj = aoGAll.oppObjects;
  886.  
  887.     while ((nCount < aoGAll.nEndObject) &&
  888.            ((*oppObj)->vPos.x != CREAL(MAX_NUM)) &&
  889.            ((*oppObj)->vPos.x != CREAL(-MAX_NUM)) )
  890.     {
  891.         (*oppObj)->fpRender(*oppObj);
  892.  
  893.         oppObj++;
  894.         nCount++;
  895.     }
  896.  
  897.     /* Delete all the unwanted objects */
  898.  
  899.     nNewEnd = nCount;
  900.  
  901.     while (nCount < aoGAll.nEndObject)
  902.     {
  903.         (*oppObj)->fpDestroy(*oppObj);
  904.  
  905.         oppObj++;
  906.         nCount++;
  907.     }
  908.  
  909.     /* This is the last object now */
  910.     aoGAll.nEndObject = nNewEnd;
  911. }
  912.  
  913. /************************************************************************
  914.  *
  915.  *      Function:       AddStaticObject()
  916.  *                      
  917.  *      Description:    Read a clump and position it at a fixed location
  918.  *                      in the scene
  919.  *
  920.  *      Parameters:     x, y, z - fixed position for the object
  921.  *                      name - the RenderWare script file name
  922.  *
  923.  *      Return Value:   None
  924.  *
  925.  ************************************************************************/
  926. int 
  927. AddStaticObject(RwReal x, RwReal y, RwReal z, char *name)
  928. {
  929.     Object *opObj;
  930.     RwClump *cpClump;
  931.  
  932.     if (!(cpClump = DoRwReadShape(name))) 
  933.     {
  934.         return FALSE;
  935.     }
  936.     
  937.     /* Create the object data structure */
  938.     opObj = malloc(sizeof(Object));
  939.  
  940.     /* Setup the object and add it to the list of global objects */
  941.  
  942.     ObjectSetup(opObj, x, y, z, cpClump);
  943.     AllObjectsAddObject(opObj);
  944.  
  945.     return TRUE;
  946. }
  947.  
  948.