| 143 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
| 144 | |
| 145 | bool Gu::HeightField::modifySamples(PxI32 startCol, PxI32 startRow, const PxHeightFieldDesc& desc, bool shrinkBounds) |
| 146 | { |
| 147 | const PxU32 nbCols = getNbColumns(); |
| 148 | const PxU32 nbRows = getNbRows(); |
| 149 | PX_CHECK_AND_RETURN_NULL(desc.format == mData.format, "Gu::HeightField::modifySamples: desc.format mismatch"); |
| 150 | //PX_CHECK_AND_RETURN_NULL(startCol + desc.nbColumns <= nbCols, |
| 151 | // "Gu::HeightField::modifySamples: startCol + nbColumns out of range"); |
| 152 | //PX_CHECK_AND_RETURN_NULL(startRow + desc.nbRows <= nbRows, |
| 153 | // "Gu::HeightField::modifySamples: startRow + nbRows out of range"); |
| 154 | //PX_CHECK_AND_RETURN_NULL(desc.samples.stride == mSampleStride, "Gu::HeightField::modifySamples: desc.samples.stride mismatch"); |
| 155 | |
| 156 | // by default bounds don't shrink since the whole point of this function is to avoid modifying the whole HF |
| 157 | // unless shrinkBounds is specified. then the bounds will be fully recomputed later |
| 158 | PxReal minHeight = mMinHeight; |
| 159 | PxReal maxHeight = mMaxHeight; |
| 160 | PxU32 hiRow = PxMin(PxU32(PxMax(0, startRow + PxI32(desc.nbRows))), nbRows); |
| 161 | PxU32 hiCol = PxMin(PxU32(PxMax(0, startCol + PxI32(desc.nbColumns))), nbCols); |
| 162 | for (PxU32 row = PxU32(PxMax(startRow, 0)); row < hiRow; row++) |
| 163 | { |
| 164 | for (PxU32 col = PxU32(PxMax(startCol, 0)); col < hiCol; col++) |
| 165 | { |
| 166 | const PxU32 vertexIndex = col + row*nbCols; |
| 167 | PxHeightFieldSample* targetSample = &mData.samples[vertexIndex]; |
| 168 | |
| 169 | // update target sample from source sample |
| 170 | const PxHeightFieldSample& sourceSample = |
| 171 | (reinterpret_cast<const PxHeightFieldSample*>(desc.samples.data))[col - startCol + (row - startRow) * desc.nbColumns]; |
| 172 | *targetSample = sourceSample; |
| 173 | |
| 174 | if(isCollisionVertexPreca(vertexIndex, row, col, PxHeightFieldMaterial::eHOLE)) |
| 175 | targetSample->materialIndex1.setBit(); |
| 176 | else |
| 177 | targetSample->materialIndex1.clearBit(); |
| 178 | |
| 179 | // grow (but not shrink) the height extents |
| 180 | const PxReal h = getHeight(vertexIndex); |
| 181 | minHeight = physx::intrinsics::selectMin(h, minHeight); |
| 182 | maxHeight = physx::intrinsics::selectMax(h, maxHeight); |
| 183 | } |
| 184 | } |
| 185 | |
| 186 | if (shrinkBounds) |
| 187 | { |
| 188 | // do a full recompute on vertical bounds to allow shrinking |
| 189 | minHeight = PX_MAX_REAL; |
| 190 | maxHeight = -PX_MAX_REAL; |
| 191 | // have to recompute the min&max from scratch... |
| 192 | for (PxU32 vertexIndex = 0; vertexIndex < nbRows * nbCols; vertexIndex ++) |
| 193 | { |
| 194 | // update height extents |
| 195 | const PxReal h = getHeight(vertexIndex); |
| 196 | minHeight = physx::intrinsics::selectMin(h, minHeight); |
| 197 | maxHeight = physx::intrinsics::selectMax(h, maxHeight); |
| 198 | } |
| 199 | } |
| 200 | mMinHeight = minHeight; |
| 201 | mMaxHeight = maxHeight; |
| 202 | |