public override BulletShape CreateTerrainShape(uint id, Vector3 size, float minHeight, float maxHeight, float[] heightMap, float scaleFactor, float collisionMargin) { const int upAxis = 2; HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)size.X, (int)size.Y, heightMap, scaleFactor, minHeight, maxHeight, upAxis, false); terrainShape.SetMargin(collisionMargin); terrainShape.SetUseDiamondSubdivision(true); terrainShape.SetUserPointer(id); return new BulletShapeXNA(terrainShape, BSPhysicsShapeType.SHAPE_TERRAIN); }
//////////////////////////////////////////////////////////////////////////////// // // TerrainDemo -- private helper methods // //////////////////////////////////////////////////////////////////////////////// /// called whenever key terrain attribute is changed public override void ClientResetScene() { base.ClientResetScene(); // remove old heightfield m_rawHeightfieldData = null; // reset gravity to point in appropriate direction //m_dynamicsWorld.setGravity(getUpVector(m_upAxis, 0.0f, -s_gravity)); m_dynamicsWorld.SetGravity(ref m_defaultGravity); // get new heightfield of appropriate type m_rawHeightfieldData = GetRawHeightfieldData(m_model, m_type, ref m_minHeight, ref m_maxHeight); Debug.Assert(m_rawHeightfieldData != null , "failed to create raw heightfield"); if (m_terrainRigidBody != null) { m_dynamicsWorld.RemoveCollisionObject(m_terrainRigidBody); m_terrainRigidBody = null; m_terrainShape = null; m_collisionShapes.Remove(m_terrainShape); } bool flipQuadEdges = false; m_terrainShape = new HeightfieldTerrainShape(s_gridSize, s_gridSize, m_rawHeightfieldData, s_gridHeightScale, m_minHeight, m_maxHeight, m_upAxis, m_type, flipQuadEdges); Debug.Assert(m_terrainShape != null, "null heightfield"); // scale the shape IndexedVector3 localScaling = GetUpVector(m_upAxis, s_gridSpacing, 1.0f); m_terrainShape.SetLocalScaling(ref localScaling); // stash this shape away m_collisionShapes.Add(m_terrainShape); // set origin to middle of heightfield IndexedMatrix tr = IndexedMatrix.CreateTranslation(new IndexedVector3(0,-20,0)); // create ground object float mass = 0.0f; m_terrainRigidBody = LocalCreateRigidBody(mass, ref tr, m_terrainShape); CollisionShape sphere = new SphereShape(0.5f); tr = IndexedMatrix.CreateTranslation(new IndexedVector3(0, 0, 0)); LocalCreateRigidBody(1f,ref tr,sphere); }
internal static object CreateTerrainShape2(object pMapInfo) { BulletHeightMapInfo mapinfo = pMapInfo as BulletHeightMapInfo; const int upAxis = 2; const float scaleFactor = 1.0f; HeightfieldTerrainShape terrainShape = new HeightfieldTerrainShape((int)mapinfo.sizeX, (int)mapinfo.sizeY, mapinfo.heightMap, scaleFactor, mapinfo.minZ, mapinfo.maxZ, upAxis, false); terrainShape.SetMargin(mapinfo.collisionMargin + 0.5f); terrainShape.SetUseDiamondSubdivision(true); terrainShape.SetUserPointer(mapinfo.ID); return terrainShape; }
public virtual void LoadHeightField(float[,] heights, float heightRange, uint vertsX, uint vertsZ, Vector3 loc, int metersPerSample) { //if (worldLoaded == false || metersPerSample > 2) // return; loc = loc / scaleFactor; //heightRange = heightRange * 1000; //loc.X += heightFieldOffset; //loc.z += heightFieldOffset; // these axes are out by about 1m? if (heightFields.ContainsKey(loc)) { int oldMetersPerSample = heightFields[loc]; if (oldMetersPerSample == metersPerSample) { return; // no need to update } else { // we need to delete the old one to rebuild this one foreach (CollisionObject a in m_dynamicsWorld.GetCollisionObjectArray()) { if (a.GetCollisionShape() != null && a.GetCollisionShape().GetShapeType() == BroadphaseNativeTypes.TERRAIN_SHAPE_PROXYTYPE) { string terrainName = (string)a.GetUserPointer(); if (terrainName == "TestHeightField_" + loc) { a.Cleanup(); heightFields.Remove(loc); System.Console.WriteLine("Removed heightmap at position '{0}' with metersPerSample: '{1}' and old: '{2}'", loc, metersPerSample, oldMetersPerSample); break; } } } } } byte[] terr = new byte[vertsX * vertsZ * 4]; MemoryStream file = new MemoryStream(terr); BinaryWriter writer = new BinaryWriter(file); for (int i = 0; i < vertsX; i++) { for (int j = 0; j < vertsZ; j++) { writer.Write((float)((heightRange / 2) + 4 * Math.Sin(j * 0.5f) * Math.Cos(i))); //writer.Write(0f); } } writer.Flush(); file.Position = 0; float heightScale = heightRange / 32767f / scaleFactor; int upAxis = 1; CollisionShape terrainShape = new HeightfieldTerrainShape((int)vertsX, (int)vertsZ, terr, heightScale, 0, heightRange, upAxis, PHY_ScalarType.PHY_FLOAT, true); IndexedMatrix worldTransform = IndexedMatrix.CreateTranslation(loc); DefaultMotionState objectMotionState = new DefaultMotionState(worldTransform, IndexedMatrix.Identity); //terrainShape = new StaticPlaneShape(Vector3.Up, 0f); //IndexedVector3 halfExtents = new IndexedVector3(50, 50, 50); //terrainShape = new BoxShape(ref halfExtents); RigidBodyConstructionInfo rbInfo = new RigidBodyConstructionInfo(0, objectMotionState, terrainShape); RigidBody terrain = new RigidBody(rbInfo); //IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -50, 0)); IndexedMatrix groundTransform = IndexedMatrix.CreateTranslation(new IndexedVector3(0, -5, 0)); LocalCreateRigidBody(0f, groundTransform, terrainShape); terrain.SetUserPointer("TestHeightField_" + loc.ToString()); //terrain.SetCollisionFlags(CollisionFlags.CF_KINEMATIC_OBJECT); ////m_dynamicsWorld.AddCollisionObject(terrain, CollisionFilterGroups.DefaultFilter, CollisionFilterGroups.AllFilter); //m_dynamicsWorld.AddCollisionObject(terrain); System.Console.WriteLine("Added heightmap at position: '{0}' with metersPerSample: '{1}'", loc, metersPerSample); heightFields.Add(loc, metersPerSample); }
public void AdjustHeightValues(int xAxis,int yAxis,int zAxis,ref float min,ref float max,HeightfieldTerrainShape shape) { if (children == null) { min = vmin[yAxis]; max = vmax[yAxis]; int[] clampedMin = new int[3]; int[] clampedMax = new int[3]; shape.QuantizeWithClamp(clampedMin, ref vmin, 0); shape.QuantizeWithClamp(clampedMax, ref vmax, 1); shape.InspectVertexHeights(clampedMin[xAxis], clampedMax[xAxis], clampedMin[zAxis], clampedMax[zAxis], yAxis, ref min, ref max); vmin[yAxis] = min; vmax[yAxis] = max; } else { float newMin = min; float newMax = max; children[0].AdjustHeightValues(xAxis,yAxis, zAxis,ref newMin, ref newMax,shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[1].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[2].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[3].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } vmin[yAxis] = min; vmax[yAxis] = max; } }
public void AdjustHeightValues(int xAxis, int yAxis, int zAxis, ref float min, ref float max, HeightfieldTerrainShape shape) { if (children == null) { min = vmin[yAxis]; max = vmax[yAxis]; int[] clampedMin = new int[3]; int[] clampedMax = new int[3]; shape.QuantizeWithClamp(clampedMin, ref vmin, 0); shape.QuantizeWithClamp(clampedMax, ref vmax, 1); shape.InspectVertexHeights(clampedMin[xAxis], clampedMax[xAxis], clampedMin[zAxis], clampedMax[zAxis], yAxis, ref min, ref max); vmin[yAxis] = min; vmax[yAxis] = max; } else { float newMin = min; float newMax = max; children[0].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[1].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[2].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } children[3].AdjustHeightValues(xAxis, yAxis, zAxis, ref newMin, ref newMax, shape); if (newMin < min) { min = newMin; } if (newMax > max) { max = newMax; } vmin[yAxis] = min; vmax[yAxis] = max; } }