// Create the initial instance of terrain and the underlying ground plane. // The objects are allocated in the unmanaged space and the pointers are tracked // by the managed code. // The terrains and the groundPlane are not added to the list of PhysObjects. // This is called from the initialization routine so we presume it is // safe to call Bullet in real time. We hope no one is moving prims around yet. public void CreateInitialGroundPlaneAndTerrain() { // The ground plane is here to catch things that are trying to drop to negative infinity BulletShape groundPlaneShape = new BulletShape( BulletSimAPI.CreateGroundPlaneShape2(BSScene.GROUNDPLANE_ID, 1f, TERRAIN_COLLISION_MARGIN), ShapeData.PhysicsShapeType.SHAPE_GROUNDPLANE); m_groundPlane = new BulletBody(BSScene.GROUNDPLANE_ID, BulletSimAPI.CreateBodyWithDefaultMotionState2(groundPlaneShape.ptr, BSScene.GROUNDPLANE_ID, Vector3.Zero, Quaternion.Identity)); BulletSimAPI.AddObjectToWorld2(PhysicsScene.World.ptr, m_groundPlane.ptr); // Everything collides with the ground plane. BulletSimAPI.SetCollisionFilterMask2(m_groundPlane.ptr, (uint)CollisionFilterGroups.GroundPlaneFilter, (uint)CollisionFilterGroups.GroundPlaneMask); Vector3 minTerrainCoords = new Vector3(0f, 0f, HEIGHT_INITIALIZATION - HEIGHT_EQUAL_FUDGE); Vector3 maxTerrainCoords = new Vector3(DefaultRegionSize.X, DefaultRegionSize.Y, HEIGHT_INITIALIZATION); int totalHeights = (int)maxTerrainCoords.X * (int)maxTerrainCoords.Y; float[] initialMap = new float[totalHeights]; for (int ii = 0; ii < totalHeights; ii++) { initialMap[ii] = HEIGHT_INITIALIZATION; } UpdateOrCreateTerrain(BSScene.TERRAIN_ID, initialMap, minTerrainCoords, maxTerrainCoords, true); }