/// <summary> /// Create the collision height map. /// </summary> /// <param name="heightData">Height map data (should be defined as byte[size.X * size.Y * 4]).</param> /// <param name="size">Tilemap size (Y is actually Z axis).</param> /// <param name="scale">Scale tiles width and depth.</param> /// <param name="minHeight">Min height value.</param> /// <param name="maxHeight">Max height value.</param> /// <param name="heightScale">Optional height scale.</param> /// <param name="upIndex">Up index.</param> /// <param name="useDiamondSubdivision">Divide the tiles into diamond shapes for more accurare results.</param> private void Build(float[] heightData, Point size, Vector2 scale, float minHeight = 0f, float maxHeight = 100f, float heightScale = 1f, int upIndex = 1, bool useDiamondSubdivision = false) { // get int ptr for data bytes _rawDataHandle = System.Runtime.InteropServices.GCHandle.Alloc(heightData, System.Runtime.InteropServices.GCHandleType.Pinned); var address = _rawDataHandle.AddrOfPinnedObject(); // create heightmap var heightmap = new BulletSharp.HeightfieldTerrainShape(size.X, size.Y, address, heightScale, minHeight, maxHeight, upIndex, BulletSharp.PhyScalarType.Single, false); // set transform and diamond subdivision heightmap.SetUseDiamondSubdivision(useDiamondSubdivision); heightmap.LocalScaling = ToBullet.Vector(new Vector3(scale.X, 1, scale.Y)); // set shape _shape = heightmap; }
internal HeightfieldColliderShape ( int heightStickWidth, int heightStickLength, HeightfieldTypes heightType, object dynamicFieldData, float heightScale, float minHeight, float maxHeight, bool flipQuadEdges ) { Type = ColliderShapeTypes.Heightfield; Is2D = false; HeightStickWidth = heightStickWidth; HeightStickLength = heightStickLength; HeightType = heightType; HeightScale = heightScale; MinHeight = minHeight; MaxHeight = maxHeight; cachedScaling = Vector3.One; switch (HeightType) { case HeightfieldTypes.Short: ShortArray = dynamicFieldData as UnmanagedArray <short>; InternalShape = new BulletSharp.HeightfieldTerrainShape(HeightStickWidth, HeightStickLength, ShortArray.Pointer, HeightScale, MinHeight, MaxHeight, 1, BulletSharp.PhyScalarType.Int16, flipQuadEdges) { LocalScaling = cachedScaling, }; break; case HeightfieldTypes.Byte: ByteArray = dynamicFieldData as UnmanagedArray <byte>; InternalShape = new BulletSharp.HeightfieldTerrainShape(HeightStickWidth, HeightStickLength, ByteArray.Pointer, HeightScale, MinHeight, MaxHeight, 1, BulletSharp.PhyScalarType.Byte, flipQuadEdges) { LocalScaling = cachedScaling, }; break; case HeightfieldTypes.Float: FloatArray = dynamicFieldData as UnmanagedArray <float>; InternalShape = new BulletSharp.HeightfieldTerrainShape(HeightStickWidth, HeightStickLength, FloatArray.Pointer, HeightScale, MinHeight, MaxHeight, 1, BulletSharp.PhyScalarType.Single, flipQuadEdges) { LocalScaling = cachedScaling, }; break; } var halfRange = (MaxHeight - MinHeight) * 0.5f; var offset = -(MinHeight + halfRange); DebugPrimitiveMatrix = Matrix.Translation(new Vector3(0, offset, 0)) * Matrix.Scaling(Vector3.One * DebugScaling); }