forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			410 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			410 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								Bullet Continuous Collision Detection and Physics Library
							 | 
						||
| 
								 | 
							
								Copyright (c) 2003-2009 Erwin Coumans  http://bulletphysics.org
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								This software is provided 'as-is', without any express or implied warranty.
							 | 
						||
| 
								 | 
							
								In no event will the authors be held liable for any damages arising from the use of this software.
							 | 
						||
| 
								 | 
							
								Permission is granted to anyone to use this software for any purpose, 
							 | 
						||
| 
								 | 
							
								including commercial applications, and to alter it and redistribute it freely, 
							 | 
						||
| 
								 | 
							
								subject to the following restrictions:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
							 | 
						||
| 
								 | 
							
								2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
							 | 
						||
| 
								 | 
							
								3. This notice may not be removed or altered from any source distribution.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "btHeightfieldTerrainShape.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "LinearMath/btTransformUtil.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btHeightfieldTerrainShape::btHeightfieldTerrainShape
							 | 
						||
| 
								 | 
							
								(
							 | 
						||
| 
								 | 
							
								int heightStickWidth, int heightStickLength, const void* heightfieldData,
							 | 
						||
| 
								 | 
							
								btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis,
							 | 
						||
| 
								 | 
							
								PHY_ScalarType hdt, bool flipQuadEdges
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									initialize(heightStickWidth, heightStickLength, heightfieldData,
							 | 
						||
| 
								 | 
							
									           heightScale, minHeight, maxHeight, upAxis, hdt,
							 | 
						||
| 
								 | 
							
									           flipQuadEdges);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,const void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									// legacy constructor: support only float or unsigned char,
							 | 
						||
| 
								 | 
							
									// 	and min height is zero
							 | 
						||
| 
								 | 
							
									PHY_ScalarType hdt = (useFloatData) ? PHY_FLOAT : PHY_UCHAR;
							 | 
						||
| 
								 | 
							
									btScalar minHeight = 0.0f;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// previously, height = uchar * maxHeight / 65535.
							 | 
						||
| 
								 | 
							
									// So to preserve legacy behavior, heightScale = maxHeight / 65535
							 | 
						||
| 
								 | 
							
									btScalar heightScale = maxHeight / 65535;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									initialize(heightStickWidth, heightStickLength, heightfieldData,
							 | 
						||
| 
								 | 
							
									           heightScale, minHeight, maxHeight, upAxis, hdt,
							 | 
						||
| 
								 | 
							
									           flipQuadEdges);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btHeightfieldTerrainShape::initialize
							 | 
						||
| 
								 | 
							
								(
							 | 
						||
| 
								 | 
							
								int heightStickWidth, int heightStickLength, const void* heightfieldData,
							 | 
						||
| 
								 | 
							
								btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis,
							 | 
						||
| 
								 | 
							
								PHY_ScalarType hdt, bool flipQuadEdges
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									// validation
							 | 
						||
| 
								 | 
							
									btAssert(heightStickWidth > 1);// && "bad width");
							 | 
						||
| 
								 | 
							
									btAssert(heightStickLength > 1);// && "bad length");
							 | 
						||
| 
								 | 
							
									btAssert(heightfieldData);// && "null heightfield data");
							 | 
						||
| 
								 | 
							
									// btAssert(heightScale) -- do we care?  Trust caller here
							 | 
						||
| 
								 | 
							
									btAssert(minHeight <= maxHeight);// && "bad min/max height");
							 | 
						||
| 
								 | 
							
									btAssert(upAxis >= 0 && upAxis < 3);// && "bad upAxis--should be in range [0,2]");
							 | 
						||
| 
								 | 
							
									btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT);// && "Bad height data type enum");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// initialize member variables
							 | 
						||
| 
								 | 
							
									m_shapeType = TERRAIN_SHAPE_PROXYTYPE;
							 | 
						||
| 
								 | 
							
									m_heightStickWidth = heightStickWidth;
							 | 
						||
| 
								 | 
							
									m_heightStickLength = heightStickLength;
							 | 
						||
| 
								 | 
							
									m_minHeight = minHeight;
							 | 
						||
| 
								 | 
							
									m_maxHeight = maxHeight;
							 | 
						||
| 
								 | 
							
									m_width = (btScalar) (heightStickWidth - 1);
							 | 
						||
| 
								 | 
							
									m_length = (btScalar) (heightStickLength - 1);
							 | 
						||
| 
								 | 
							
									m_heightScale = heightScale;
							 | 
						||
| 
								 | 
							
									m_heightfieldDataUnknown = heightfieldData;
							 | 
						||
| 
								 | 
							
									m_heightDataType = hdt;
							 | 
						||
| 
								 | 
							
									m_flipQuadEdges = flipQuadEdges;
							 | 
						||
| 
								 | 
							
									m_useDiamondSubdivision = false;
							 | 
						||
| 
								 | 
							
									m_useZigzagSubdivision = false;
							 | 
						||
| 
								 | 
							
									m_upAxis = upAxis;
							 | 
						||
| 
								 | 
							
									m_localScaling.setValue(btScalar(1.), btScalar(1.), btScalar(1.));
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// determine min/max axis-aligned bounding box (aabb) values
							 | 
						||
| 
								 | 
							
									switch (m_upAxis)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_localAabbMin.setValue(m_minHeight, 0, 0);
							 | 
						||
| 
								 | 
							
											m_localAabbMax.setValue(m_maxHeight, m_width, m_length);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_localAabbMin.setValue(0, m_minHeight, 0);
							 | 
						||
| 
								 | 
							
											m_localAabbMax.setValue(m_width, m_maxHeight, m_length);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									case 2:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											m_localAabbMin.setValue(0, 0, m_minHeight);
							 | 
						||
| 
								 | 
							
											m_localAabbMax.setValue(m_width, m_length, m_maxHeight);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//need to get valid m_upAxis
							 | 
						||
| 
								 | 
							
											btAssert(0);// && "Bad m_upAxis");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// remember origin (defined as exact middle of aabb)
							 | 
						||
| 
								 | 
							
									m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								btHeightfieldTerrainShape::~btHeightfieldTerrainShape()
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btVector3 localOrigin(0, 0, 0);
							 | 
						||
| 
								 | 
							
									localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5);
							 | 
						||
| 
								 | 
							
									localOrigin *= m_localScaling;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btMatrix3x3 abs_b = t.getBasis().absolute();  
							 | 
						||
| 
								 | 
							
									btVector3 center = t.getOrigin();
							 | 
						||
| 
								 | 
							
								    btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]);
							 | 
						||
| 
								 | 
							
									extent += btVector3(getMargin(),getMargin(),getMargin());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									aabbMin = center - extent;
							 | 
						||
| 
								 | 
							
									aabbMax = center + extent;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// This returns the "raw" (user's initial) height, not the actual height.
							 | 
						||
| 
								 | 
							
								/// The actual height needs to be adjusted to be relative to the center
							 | 
						||
| 
								 | 
							
								///   of the heightfield's AABB.
							 | 
						||
| 
								 | 
							
								btScalar
							 | 
						||
| 
								 | 
							
								btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btScalar val = 0.f;
							 | 
						||
| 
								 | 
							
									switch (m_heightDataType)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									case PHY_FLOAT:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x];
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									case PHY_UCHAR:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x];
							 | 
						||
| 
								 | 
							
											val = heightFieldValue * m_heightScale;
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									case PHY_SHORT:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x];
							 | 
						||
| 
								 | 
							
											val = hfValue * m_heightScale;
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btAssert(!"Bad m_heightDataType");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									return val;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// this returns the vertex in bullet-local coordinates
							 | 
						||
| 
								 | 
							
								void	btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btAssert(x>=0);
							 | 
						||
| 
								 | 
							
									btAssert(y>=0);
							 | 
						||
| 
								 | 
							
									btAssert(x<m_heightStickWidth);
							 | 
						||
| 
								 | 
							
									btAssert(y<m_heightStickLength);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									btScalar	height = getRawHeightFieldValue(x,y);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									switch (m_upAxis)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
										vertex.setValue(
							 | 
						||
| 
								 | 
							
											height - m_localOrigin.getX(),
							 | 
						||
| 
								 | 
							
											(-m_width/btScalar(2.0)) + x,
							 | 
						||
| 
								 | 
							
											(-m_length/btScalar(2.0) ) + y
							 | 
						||
| 
								 | 
							
											);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vertex.setValue(
							 | 
						||
| 
								 | 
							
											(-m_width/btScalar(2.0)) + x,
							 | 
						||
| 
								 | 
							
											height - m_localOrigin.getY(),
							 | 
						||
| 
								 | 
							
											(-m_length/btScalar(2.0)) + y
							 | 
						||
| 
								 | 
							
											);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									case 2:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											vertex.setValue(
							 | 
						||
| 
								 | 
							
											(-m_width/btScalar(2.0)) + x,
							 | 
						||
| 
								 | 
							
											(-m_length/btScalar(2.0)) + y,
							 | 
						||
| 
								 | 
							
											height - m_localOrigin.getZ()
							 | 
						||
| 
								 | 
							
											);
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//need to get valid m_upAxis
							 | 
						||
| 
								 | 
							
											btAssert(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									vertex*=m_localScaling;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								static inline int
							 | 
						||
| 
								 | 
							
								getQuantized
							 | 
						||
| 
								 | 
							
								(
							 | 
						||
| 
								 | 
							
								btScalar x
							 | 
						||
| 
								 | 
							
								)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									if (x < 0.0) {
							 | 
						||
| 
								 | 
							
										return (int) (x - 0.5);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									return (int) (x + 0.5);
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// given input vector, return quantized version
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								  This routine is basically determining the gridpoint indices for a given
							 | 
						||
| 
								 | 
							
								  input vector, answering the question: "which gridpoint is closest to the
							 | 
						||
| 
								 | 
							
								  provided point?".
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								  "with clamp" means that we restrict the point to be in the heightfield's
							 | 
						||
| 
								 | 
							
								  axis-aligned bounding box.
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									btVector3 clampedPoint(point);
							 | 
						||
| 
								 | 
							
									clampedPoint.setMax(m_localAabbMin);
							 | 
						||
| 
								 | 
							
									clampedPoint.setMin(m_localAabbMax);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									out[0] = getQuantized(clampedPoint.getX());
							 | 
						||
| 
								 | 
							
									out[1] = getQuantized(clampedPoint.getY());
							 | 
						||
| 
								 | 
							
									out[2] = getQuantized(clampedPoint.getZ());
							 | 
						||
| 
								 | 
							
										
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/// process all triangles within the provided axis-aligned bounding box
							 | 
						||
| 
								 | 
							
								/**
							 | 
						||
| 
								 | 
							
								  basic algorithm:
							 | 
						||
| 
								 | 
							
								    - convert input aabb to local coordinates (scale down and shift for local origin)
							 | 
						||
| 
								 | 
							
								    - convert input aabb to a range of heightfield grid points (quantize)
							 | 
						||
| 
								 | 
							
								    - iterate over all triangles in that subset of the grid
							 | 
						||
| 
								 | 
							
								 */
							 | 
						||
| 
								 | 
							
								void	btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									// scale down the input aabb's so they are in local (non-scaled) coordinates
							 | 
						||
| 
								 | 
							
									btVector3	localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
							 | 
						||
| 
								 | 
							
									btVector3	localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									// account for local origin
							 | 
						||
| 
								 | 
							
									localAabbMin += m_localOrigin;
							 | 
						||
| 
								 | 
							
									localAabbMax += m_localOrigin;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									//quantize the aabbMin and aabbMax, and adjust the start/end ranges
							 | 
						||
| 
								 | 
							
									int	quantizedAabbMin[3];
							 | 
						||
| 
								 | 
							
									int	quantizedAabbMax[3];
							 | 
						||
| 
								 | 
							
									quantizeWithClamp(quantizedAabbMin, localAabbMin,0);
							 | 
						||
| 
								 | 
							
									quantizeWithClamp(quantizedAabbMax, localAabbMax,1);
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									// expand the min/max quantized values
							 | 
						||
| 
								 | 
							
									// this is to catch the case where the input aabb falls between grid points!
							 | 
						||
| 
								 | 
							
									for (int i = 0; i < 3; ++i) {
							 | 
						||
| 
								 | 
							
										quantizedAabbMin[i]--;
							 | 
						||
| 
								 | 
							
										quantizedAabbMax[i]++;
							 | 
						||
| 
								 | 
							
									}	
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									int startX=0;
							 | 
						||
| 
								 | 
							
									int endX=m_heightStickWidth-1;
							 | 
						||
| 
								 | 
							
									int startJ=0;
							 | 
						||
| 
								 | 
							
									int endJ=m_heightStickLength-1;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									switch (m_upAxis)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
									case 0:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[1]>startX)
							 | 
						||
| 
								 | 
							
												startX = quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[1]<endX)
							 | 
						||
| 
								 | 
							
												endX = quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[2]>startJ)
							 | 
						||
| 
								 | 
							
												startJ = quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[2]<endJ)
							 | 
						||
| 
								 | 
							
												endJ = quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									case 1:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[0]>startX)
							 | 
						||
| 
								 | 
							
												startX = quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[0]<endX)
							 | 
						||
| 
								 | 
							
												endX = quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[2]>startJ)
							 | 
						||
| 
								 | 
							
												startJ = quantizedAabbMin[2];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[2]<endJ)
							 | 
						||
| 
								 | 
							
												endJ = quantizedAabbMax[2];
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										};
							 | 
						||
| 
								 | 
							
									case 2:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[0]>startX)
							 | 
						||
| 
								 | 
							
												startX = quantizedAabbMin[0];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[0]<endX)
							 | 
						||
| 
								 | 
							
												endX = quantizedAabbMax[0];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMin[1]>startJ)
							 | 
						||
| 
								 | 
							
												startJ = quantizedAabbMin[1];
							 | 
						||
| 
								 | 
							
											if (quantizedAabbMax[1]<endJ)
							 | 
						||
| 
								 | 
							
												endJ = quantizedAabbMax[1];
							 | 
						||
| 
								 | 
							
											break;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									default:
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											//need to get valid m_upAxis
							 | 
						||
| 
								 | 
							
											btAssert(0);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								  
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									for(int j=startJ; j<endJ; j++)
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										for(int x=startX; x<endX; x++)
							 | 
						||
| 
								 | 
							
										{
							 | 
						||
| 
								 | 
							
											btVector3 vertices[3];
							 | 
						||
| 
								 | 
							
											if (m_flipQuadEdges || (m_useDiamondSubdivision && !((j+x) & 1))|| (m_useZigzagSubdivision  && !(j & 1)))
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
								        //first triangle
							 | 
						||
| 
								 | 
							
								        getVertex(x,j,vertices[0]);
							 | 
						||
| 
								 | 
							
										getVertex(x, j + 1, vertices[1]);
							 | 
						||
| 
								 | 
							
										getVertex(x + 1, j + 1, vertices[2]);
							 | 
						||
| 
								 | 
							
								        callback->processTriangle(vertices,x,j);
							 | 
						||
| 
								 | 
							
								        //second triangle
							 | 
						||
| 
								 | 
							
								      //  getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman
							 | 
						||
| 
								 | 
							
								        getVertex(x+1,j+1,vertices[1]);
							 | 
						||
| 
								 | 
							
										getVertex(x + 1, j, vertices[2]);
							 | 
						||
| 
								 | 
							
										callback->processTriangle(vertices, x, j);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											} else
							 | 
						||
| 
								 | 
							
											{
							 | 
						||
| 
								 | 
							
								        //first triangle
							 | 
						||
| 
								 | 
							
								        getVertex(x,j,vertices[0]);
							 | 
						||
| 
								 | 
							
								        getVertex(x,j+1,vertices[1]);
							 | 
						||
| 
								 | 
							
								        getVertex(x+1,j,vertices[2]);
							 | 
						||
| 
								 | 
							
								        callback->processTriangle(vertices,x,j);
							 | 
						||
| 
								 | 
							
								        //second triangle
							 | 
						||
| 
								 | 
							
								        getVertex(x+1,j,vertices[0]);
							 | 
						||
| 
								 | 
							
								        //getVertex(x,j+1,vertices[1]);
							 | 
						||
| 
								 | 
							
								        getVertex(x+1,j+1,vertices[2]);
							 | 
						||
| 
								 | 
							
								        callback->processTriangle(vertices,x,j);
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									//moving concave objects not supported
							 | 
						||
| 
								 | 
							
									
							 | 
						||
| 
								 | 
							
									inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.));
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								void	btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling)
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									m_localScaling = scaling;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								const btVector3& btHeightfieldTerrainShape::getLocalScaling() const
							 | 
						||
| 
								 | 
							
								{
							 | 
						||
| 
								 | 
							
									return m_localScaling;
							 | 
						||
| 
								 | 
							
								}
							 |