Esempio n. 1
0
        // TODO: redo terrain implementation selection to allow other base types than heightMap.
        private BSTerrainPhys BuildPhysicalTerrain(Vector3 terrainRegionBase, uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
        {
            PhysicsScene.Logger.DebugFormat("{0} Terrain for {1}/{2} created with {3}",
                                            LogHeader, PhysicsScene.RegionName, terrainRegionBase,
                                            (BSTerrainPhys.TerrainImplementation)BSParam.TerrainImplementation);
            BSTerrainPhys newTerrainPhys = null;

            switch ((int)BSParam.TerrainImplementation)
            {
            case (int)BSTerrainPhys.TerrainImplementation.Heightmap:
                newTerrainPhys = new BSTerrainHeightmap(PhysicsScene, terrainRegionBase, id,
                                                        heightMap, minCoords, maxCoords);
                break;

            case (int)BSTerrainPhys.TerrainImplementation.Mesh:
                newTerrainPhys = new BSTerrainMesh(PhysicsScene, terrainRegionBase, id,
                                                   heightMap, minCoords, maxCoords);
                break;

            default:
                PhysicsScene.Logger.ErrorFormat("{0} Bad terrain implementation specified. Type={1}/{2},Region={3}/{4}",
                                                LogHeader,
                                                (int)BSParam.TerrainImplementation,
                                                BSParam.TerrainImplementation,
                                                PhysicsScene.RegionName, terrainRegionBase);
                break;
            }
            return(newTerrainPhys);
        }
Esempio n. 2
0
        // Given an address, return 'true' of there is a description of that terrain and output
        //    the descriptor class and the 'base' fo the addresses therein.
        private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
        {
            int     offsetX        = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
            int     offsetY        = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
            Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);

            BSTerrainPhys physTerrain = null;

            lock (m_terrains)
            {
                m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
            }
            outTerrainBase = terrainBaseXYZ;
            outPhysTerrain = physTerrain;
            return(physTerrain != null);
        }
Esempio n. 3
0
        // If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
        //     based on the passed information. The 'id' should be either the terrain id or
        //     BSScene.CHILDTERRAIN_ID. If the latter, a new child terrain ID will be allocated and used.
        //     The latter feature is for creating child terrains for mega-regions.
        // If called with a mapInfo in m_heightMaps and there is an existing terrain body, a new
        //     terrain shape is created and added to the body.
        //     This call is most often used to update the heightMap and parameters of the terrain.
        // (The above does suggest that some simplification/refactoring is in order.)
        // Called during taint-time.
        private void UpdateTerrain(uint id, float[] heightMap,
                                   Vector3 minCoords, Vector3 maxCoords, bool inTaintTime)
        {
            DetailLog("{0},BSTerrainManager.UpdateTerrain,call,minC={1},maxC={2},inTaintTime={3}",
                      BSScene.DetailLogZero, minCoords, maxCoords, inTaintTime);

            // Find high and low points of passed heightmap.
            // The min and max passed in is usually the area objects can be in (maximum
            //     object height, for instance). The terrain wants the bounding box for the
            //     terrain so replace passed min and max Z with the actual terrain min/max Z.
            float minZ = float.MaxValue;
            float maxZ = float.MinValue;

            foreach (float height in heightMap)
            {
                if (height < minZ)
                {
                    minZ = height;
                }
                if (height > maxZ)
                {
                    maxZ = height;
                }
            }
            if (minZ == maxZ)
            {
                // If min and max are the same, reduce min a little bit so a good bounding box is created.
                minZ -= BSTerrainManager.HEIGHT_EQUAL_FUDGE;
            }
            minCoords.Z = minZ;
            maxCoords.Z = maxZ;

            Vector3 terrainRegionBase = new Vector3(minCoords.X, minCoords.Y, 0f);

            lock (m_terrains)
            {
                BSTerrainPhys terrainPhys;
                if (m_terrains.TryGetValue(terrainRegionBase, out terrainPhys))
                {
                    // There is already a terrain in this spot. Free the old and build the new.
                    DetailLog("{0},UpdateTerrain:UpdateExisting,call,id={1},base={2},minC={3},maxC={4}",
                              BSScene.DetailLogZero, id, terrainRegionBase, minCoords, minCoords);

                    // Remove old terrain from the collection
                    m_terrains.Remove(terrainRegionBase);
                    // Release any physical memory it may be using.
                    terrainPhys.Dispose();

                    if (MegaRegionParentPhysicsScene == null)
                    {
                        BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
                        m_terrains.Add(terrainRegionBase, newTerrainPhys);

                        m_terrainModified = true;
                    }
                    else
                    {
                        // It's possible that Combine() was called after this code was queued.
                        // If we are a child of combined regions, we don't create any terrain for us.
                        DetailLog("{0},BSTerrainManager.UpdateTerrain:AmACombineChild,taint", BSScene.DetailLogZero);

                        // Get rid of any terrain that may have been allocated for us.
                        ReleaseGroundPlaneAndTerrain();

                        // I hate doing this, but just bail
                        return;
                    }
                }
                else
                {
                    // We don't know about this terrain so either we are creating a new terrain or
                    //    our mega-prim child is giving us a new terrain to add to the phys world

                    // if this is a child terrain, calculate a unique terrain id
                    uint newTerrainID = id;
                    if (newTerrainID >= BSScene.CHILDTERRAIN_ID)
                    {
                        newTerrainID = ++m_terrainCount;
                    }

                    DetailLog("{0},UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
                              BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
                    BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
                    m_terrains.Add(terrainRegionBase, newTerrainPhys);

                    m_terrainModified = true;
                }
            }
        }
    // Given an address, return 'true' of there is a description of that terrain and output
    //    the descriptor class and the 'base' fo the addresses therein.
    private bool GetTerrainPhysicalAtXYZ(Vector3 pos, out BSTerrainPhys outPhysTerrain, out Vector3 outTerrainBase)
    {
        int offsetX = ((int)(pos.X / (int)DefaultRegionSize.X)) * (int)DefaultRegionSize.X;
        int offsetY = ((int)(pos.Y / (int)DefaultRegionSize.Y)) * (int)DefaultRegionSize.Y;
        Vector3 terrainBaseXYZ = new Vector3(offsetX, offsetY, 0f);

        BSTerrainPhys physTerrain = null;
        lock (m_terrains)
        {
            m_terrains.TryGetValue(terrainBaseXYZ, out physTerrain);
        }
        outTerrainBase = terrainBaseXYZ;
        outPhysTerrain = physTerrain;
        return (physTerrain != null);
    }