Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 13, 2008, 11:45:51 PM (15 years ago)
Author:
rgrieder
Message:

Updated to Bullet 2.73 (first part).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/branches/physics/src/bullet/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp

    r2192 r2430  
    1919
    2020
     21
     22btHeightfieldTerrainShape::btHeightfieldTerrainShape
     23(
     24int heightStickWidth, int heightStickLength, void* heightfieldData,
     25btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
     26PHY_ScalarType hdt, bool flipQuadEdges
     27)
     28{
     29        initialize(heightStickWidth, heightStickLength, heightfieldData,
     30                   heightScale, minHeight, maxHeight, upAxis, hdt,
     31                   flipQuadEdges);
     32}
     33
     34
     35
    2136btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
    22 : btConcaveShape (), m_heightStickWidth(heightStickWidth),
    23 m_heightStickLength(heightStickLength),
    24 m_maxHeight(maxHeight),
    25 m_width((btScalar)heightStickWidth-1),
    26 m_length((btScalar)heightStickLength-1),
    27 m_heightfieldDataUnknown(heightfieldData),
    28 m_useFloatData(useFloatData),
    29 m_flipQuadEdges(flipQuadEdges),
    30 m_useDiamondSubdivision(false),
    31 m_upAxis(upAxis),
    32 m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.))
    33 {
     37{
     38        // legacy constructor: support only float or unsigned char,
     39        //      and min height is zero
     40        PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
     41        btScalar minHeight = 0.0;
     42
     43        // previously, height = uchar * maxHeight / 65535.
     44        // So to preserve legacy behavior, heightScale = maxHeight / 65535
     45        btScalar heightScale = maxHeight / 65535;
     46
     47        initialize(heightStickWidth, heightStickLength, heightfieldData,
     48                   heightScale, minHeight, maxHeight, upAxis, hdt,
     49                   flipQuadEdges);
     50}
     51
     52
     53
     54void btHeightfieldTerrainShape::initialize
     55(
     56int heightStickWidth, int heightStickLength, void* heightfieldData,
     57btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
     58PHY_ScalarType hdt, bool flipQuadEdges
     59)
     60{
     61        // validation
     62        btAssert(heightStickWidth > 1 && "bad width");
     63        btAssert(heightStickLength > 1 && "bad length");
     64        btAssert(heightfieldData && "null heightfield data");
     65        // btAssert(heightScale) -- do we care?  Trust caller here
     66        btAssert(minHeight <= maxHeight && "bad min/max height");
     67        btAssert(upAxis >= 0 && upAxis < 3 &&
     68            "bad upAxis--should be in range [0,2]");
     69        btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT &&
     70            "Bad height data type enum");
     71
     72        // initialize member variables
    3473        m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
    35 
    36         btScalar        quantizationMargin = 1.f;
    37 
    38         //enlarge the AABB to avoid division by zero when initializing the quantization values
    39         btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin);
    40 
    41         btVector3       halfExtents(0,0,0);
    42 
     74        m_heightStickWidth = heightStickWidth;
     75        m_heightStickLength = heightStickLength;
     76        m_minHeight = minHeight;
     77        m_maxHeight = maxHeight;
     78        m_width = (btScalar) (heightStickWidth - 1);
     79        m_length = (btScalar) (heightStickLength - 1);
     80        m_heightScale = heightScale;
     81        m_heightfieldDataUnknown = heightfieldData;
     82        m_heightDataType = hdt;
     83        m_flipQuadEdges = flipQuadEdges;
     84        m_useDiamondSubdivision = false;
     85        m_upAxis = upAxis;
     86        m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
     87
     88        // determine min/max axis-aligned bounding box (aabb) values
    4389        switch (m_upAxis)
    4490        {
    4591        case 0:
    4692                {
    47                         halfExtents.setValue(
    48                                 btScalar(m_maxHeight),
    49                                 btScalar(m_width), //?? don't know if this should change
    50                                 btScalar(m_length));
     93                        m_localAabbMin.setValue(m_minHeight, 0, 0);
     94                        m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
    5195                        break;
    5296                }
    5397        case 1:
    5498                {
    55                         halfExtents.setValue(
    56                                 btScalar(m_width),
    57                                 btScalar(m_maxHeight),
    58                                 btScalar(m_length));
     99                        m_localAabbMin.setValue(0, m_minHeight, 0);
     100                        m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
    59101                        break;
    60102                };
    61103        case 2:
    62104                {
    63                         halfExtents.setValue(
    64                                 btScalar(m_width),
    65                                 btScalar(m_length),
    66                                 btScalar(m_maxHeight)
    67                         );
     105                        m_localAabbMin.setValue(0, 0, m_minHeight);
     106                        m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
    68107                        break;
    69108                }
     
    71110                {
    72111                        //need to get valid m_upAxis
    73                         btAssert(0);
    74                 }
    75         }
    76 
    77         halfExtents*= btScalar(0.5);
    78        
    79         m_localAabbMin = -halfExtents - clampValue;
    80         m_localAabbMax = halfExtents + clampValue;
    81         btVector3 aabbSize = m_localAabbMax - m_localAabbMin;
    82 
    83 }
     112                        btAssert(0 && "Bad m_upAxis");
     113                }
     114        }
     115
     116        // remember origin (defined as exact middle of aabb)
     117        m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
     118}
     119
    84120
    85121
     
    93129{
    94130        btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
    95         halfExtents += btVector3(getMargin(),getMargin(),getMargin());
     131
     132        btVector3 localOrigin(0, 0, 0);
     133        localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
     134        localOrigin *= m_localScaling;
    96135
    97136        btMatrix3x3 abs_b = t.getBasis().absolute(); 
    98         btPoint3 center = t.getOrigin();
     137        btVector3 center = t.getOrigin();
    99138        btVector3 extent = btVector3(abs_b[0].dot(halfExtents),
    100139                   abs_b[1].dot(halfExtents),
    101140                  abs_b[2].dot(halfExtents));
    102        
     141        extent += btVector3(getMargin(),getMargin(),getMargin());
    103142
    104143        aabbMin = center - extent;
    105144        aabbMax = center + extent;
    106 
    107 
    108145}
    109146
     
    111148{
    112149        btScalar val = 0.f;
    113         if (m_useFloatData)
     150        switch (m_heightDataType)
    114151        {
    115                 val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
    116         } else
    117         {
    118                 //assume unsigned short int
    119                 unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
    120                 val = heightFieldValue* (m_maxHeight/btScalar(65535));
    121         }
     152        case PHY_FLOAT:
     153                {
     154                        val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
     155                        break;
     156                }
     157
     158        case PHY_UCHAR:
     159                {
     160                        unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
     161                        val = heightFieldValue * m_heightScale;
     162                        break;
     163                }
     164
     165        case PHY_SHORT:
     166                {
     167                        short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
     168                        val = hfValue * m_heightScale;
     169                        break;
     170                }
     171
     172        default:
     173                {
     174                        btAssert(!"Bad m_heightDataType");
     175                }
     176        }
     177
    122178        return val;
    123179}
     
    179235
    180236
     237
     238static inline int
     239getQuantized
     240(
     241float x
     242)
     243{
     244        if (x < 0.0) {
     245                return (int) (x - 0.5);
     246        }
     247        return (int) (x + 0.5);
     248}
     249
     250
     251
     252/// given input vector, return quantized version
     253/**
     254  This routine is basically determining the gridpoint indices for a given
     255  input vector, answering the question: "which gridpoint is closest to the
     256  provided point?".
     257
     258  "with clamp" means that we restrict the point to be in the heightfield's
     259  axis-aligned bounding box.
     260 */
    181261void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
    182262{
     
    185265        clampedPoint.setMin(m_localAabbMax);
    186266
    187         btVector3 v = (clampedPoint);// - m_bvhAabbMin) * m_bvhQuantization;
    188 
    189         //TODO: optimization: check out how to removed this btFabs
     267        out[0] = getQuantized(clampedPoint.getX());
     268        out[1] = getQuantized(clampedPoint.getY());
     269        out[2] = getQuantized(clampedPoint.getZ());
    190270               
    191         out[0] = (int)(v.getX() + v.getX() / btFabs(v.getX())* btScalar(0.5) );
    192         out[1] = (int)(v.getY() + v.getY() / btFabs(v.getY())* btScalar(0.5) );
    193         out[2] = (int)(v.getZ() + v.getZ() / btFabs(v.getZ())* btScalar(0.5) );
    194        
    195 }
    196 
    197 
     271}
     272
     273
     274
     275/// process all triangles within the provided axis-aligned bounding box
     276/**
     277  basic algorithm:
     278    - convert input aabb to local coordinates (scale down and shift for local origin)
     279    - convert input aabb to a range of heightfield grid points (quantize)
     280    - iterate over all triangles in that subset of the grid
     281 */
    198282void    btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
    199283{
    200         (void)callback;
    201         (void)aabbMax;
    202         (void)aabbMin;
     284        // scale down the input aabb's so they are in local (non-scaled) coordinates
     285        btVector3       localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
     286        btVector3       localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
     287
     288        // account for local origin
     289        localAabbMin += m_localOrigin;
     290        localAabbMax += m_localOrigin;
    203291
    204292        //quantize the aabbMin and aabbMax, and adjust the start/end ranges
    205 
    206293        int     quantizedAabbMin[3];
    207294        int     quantizedAabbMax[3];
    208 
    209         btVector3       localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
    210         btVector3       localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
    211        
    212295        quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
    213296        quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
    214297       
    215        
     298        // expand the min/max quantized values
     299        // this is to catch the case where the input aabb falls between grid points!
     300        for (int i = 0; i < 3; ++i) {
     301                quantizedAabbMin[i]--;
     302                quantizedAabbMax[i]++;
     303        }       
    216304
    217305        int startX=0;
     
    224312        case 0:
    225313                {
    226                         quantizedAabbMin[1]+=m_heightStickWidth/2-1;
    227                         quantizedAabbMax[1]+=m_heightStickWidth/2+1;
    228                         quantizedAabbMin[2]+=m_heightStickLength/2-1;
    229                         quantizedAabbMax[2]+=m_heightStickLength/2+1;
    230 
    231314                        if (quantizedAabbMin[1]>startX)
    232315                                startX = quantizedAabbMin[1];
     
    241324        case 1:
    242325                {
    243                         quantizedAabbMin[0]+=m_heightStickWidth/2-1;
    244                         quantizedAabbMax[0]+=m_heightStickWidth/2+1;
    245                         quantizedAabbMin[2]+=m_heightStickLength/2-1;
    246                         quantizedAabbMax[2]+=m_heightStickLength/2+1;
    247 
    248326                        if (quantizedAabbMin[0]>startX)
    249327                                startX = quantizedAabbMin[0];
     
    258336        case 2:
    259337                {
    260                         quantizedAabbMin[0]+=m_heightStickWidth/2-1;
    261                         quantizedAabbMax[0]+=m_heightStickWidth/2+1;
    262                         quantizedAabbMin[1]+=m_heightStickLength/2-1;
    263                         quantizedAabbMax[1]+=m_heightStickLength/2+1;
    264 
    265338                        if (quantizedAabbMin[0]>startX)
    266339                                startX = quantizedAabbMin[0];
Note: See TracChangeset for help on using the changeset viewer.