public LLRegionContext(RegionContextBase rcontext, AssetContextBase acontext,
                               LLTerrainInfo tinfo, OMV.Simulator sim)
            : base(rcontext, acontext)
        {
            m_terrainInfo = tinfo;

            // until we have a better protocol, we know the sims are a fixed size
            m_size = new OMV.Vector3(256f, 256f, 8000f);

            // believe it or not the world coordinates of a sim are hidden in the handle
            uint x, y;

            OMV.Utils.LongToUInts(sim.Handle, out x, out y);
            m_worldBase = new OMV.Vector3d((double)x, (double)y, 0d);

            m_simulator = sim;

            // this should be more general as "GRID/SIM"
            m_name = new EntityName(sim.Name);

            // a cache of requested localIDs so we don't ask too often
            m_recentLocalIDRequests = new Dictionary <uint, int>();

            this.RegisterInterface <LLRegionContext>(this);
        }
        private void RenderAvatars(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            OMV.Vector3 avatarColor        = ModuleParams.ParamVector3(m_renderer.m_moduleName + ".OGL.Avatar.Color");
            float       avatarTransparancy = ModuleParams.ParamFloat(m_renderer.m_moduleName + ".OGL.Avatar.Transparancy");

            float[] m_avatarMaterialColor = { avatarColor.X, avatarColor.Y, avatarColor.Z, avatarTransparancy };

            lock (rri.renderAvatarList) {
                foreach (RenderableAvatar rav in rri.renderAvatarList.Values)
                {
                    GL.PushMatrix();
                    GL.Translate(rav.avatar.RegionPosition.X,
                                 rav.avatar.RegionPosition.Y,
                                 rav.avatar.RegionPosition.Z);

                    GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, m_avatarMaterialColor);
                    GL.Disable(EnableCap.Texture2D);
                    Glu.GLUquadric quad = Glu.gluNewQuadric();
                    Glu.gluSphere(quad, 0.5d, 10, 10);
                    Glu.gluDeleteQuadric(quad);

                    GL.PopMatrix();
                }
            }
        }
        private void RenderTerrain(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            GL.PushMatrix();

            // if the terrain has changed,
            if (rri.refreshTerrain)
            {
                rri.refreshTerrain = false;
                UpdateRegionTerrainMesh(rcontext, rri);
            }

            // apply region offset
            GL.MultMatrix(Math3D.CreateTranslationMatrix(CalcRegionOffset(rcontext)));

            // everything built. Display the terrain
            GL.EnableClientState(ArrayCap.VertexArray);
            GL.EnableClientState(ArrayCap.TextureCoordArray);
            GL.EnableClientState(ArrayCap.NormalArray);

            GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, rri.terrainTexCoord);
            GL.VertexPointer(3, VertexPointerType.Float, 0, rri.terrainVertices);
            GL.NormalPointer(NormalPointerType.Float, 0, rri.terrainNormal);
            GL.DrawElements(BeginMode.Quads, rri.terrainIndices.Length, DrawElementsType.UnsignedShort, rri.terrainIndices);

            GL.PopMatrix();
        }
Beispiel #4
0
        // something about the terrain has changed, do some updating
        public void UpdateTerrain(RegionContextBase rcontext)
        {
            RegionRenderInfo rri = GetRegionRenderInfo(rcontext);

            // making this true will case the low level renderer to rebuild the terrain
            rri.refreshTerrain = true;
            return;
        }
 public LLEntityBase(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     this.Prim         = null;
     this.Sim          = null;
     this.RegionHandle = LLEntityBase.NOREGION;
     this.LocalID      = LLEntityBase.NOLOCALID;
 }
 public LLEntityBase(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     this.Prim = null;
     this.Sim = null;
     this.RegionHandle = LLEntityBase.NOREGION;
     this.LocalID = LLEntityBase.NOLOCALID;
 }
        private void RenderOcean(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            GL.PushMatrix();

            // apply region offset
            GL.MultMatrix(Math3D.CreateTranslationMatrix(CalcRegionOffset(rcontext)));

            GL.PopMatrix();
            return;
        }
Beispiel #8
0
        // rendering specific information for placing in  the view
        public void MapRegionIntoView(RegionContextBase rcontext)
        {
            if (!m_trackedRegions.Contains(rcontext))
            {
                m_trackedRegions.Add(rcontext);
            }
            // get the render info block to create it if it doesn't exist
            RegionRenderInfo rri = GetRegionRenderInfo(rcontext);

            return;
        }
Beispiel #9
0
        // create and initialize the renderinfoblock
        private RegionRenderInfo GetRegionRenderInfo(RegionContextBase rcontext)
        {
            RegionRenderInfo ret = null;

            if (!rcontext.TryGet <RegionRenderInfo>(out ret))
            {
                ret = new RegionRenderInfo();
                rcontext.RegisterInterface <RegionRenderInfo>(ret);
                ret.oceanHeight = rcontext.TerrainInfo.WaterHeight;
            }
            return(ret);
        }
 /// <summary>
 /// When multiple regions are displayed, there is a focus region (the one the main avatar
 /// is in) and other regions that are offset from that focus region. Here we come up with
 /// that offset.
 /// </summary>
 /// <param name="rcontext"></param>
 /// <returns></returns>
 private OMV.Vector3 CalcRegionOffset(RegionContextBase rcontext)
 {
     if (rcontext == m_renderer.m_focusRegion)
     {
         return(OMV.Vector3.Zero);
     }
     OMV.Vector3 ret = new OMV.Vector3();
     ret.X = (float)(m_renderer.m_focusRegion.GlobalPosition.X - rcontext.GlobalPosition.X);
     ret.Y = (float)(m_renderer.m_focusRegion.GlobalPosition.Y - rcontext.GlobalPosition.Y);
     ret.Z = (float)(m_renderer.m_focusRegion.GlobalPosition.Z - rcontext.GlobalPosition.Z);
     return(ret);
 }
 private void ComputeVisibility(RegionContextBase rcontext, RegionRenderInfo rri)
 {
     m_renderer.Camera.ComputeFrustum();
     lock (rri.renderPrimList) {
         foreach (uint ind in rri.renderPrimList.Keys)
         {
             RenderablePrim rp = rri.renderPrimList[ind];
             rp.isVisible = m_renderer.Camera.isVisible(rp.Position.X, rp.Position.Y, rp.Position.Z, 10f);
         }
     }
     return;
 }
Beispiel #12
0
 private void World_OnRegionUpdated(RegionContextBase rcontext, UpdateCodes what)
 {
     m_log.Log(LogLevel.DVIEWDETAIL, "OnRegionUpdated: ");
     if ((what & UpdateCodes.Terrain) != 0)
     {
         // This is first attempt at terrain. The description of the land comes in
         // as a heightmap defined by OMV. The renderer will have to deal with that.
         // How to generalize this so it works for any world representation?
         // What about a cylindrical spaceship world?
         Renderer.UpdateTerrain(rcontext);
     }
     // TODO: other things to test?
     return;
 }
 void World_OnWorldRegionNew(RegionContextBase rcontext)
 {
     /*
      * // we have a new region. Set the focus region to be where the main agent points
      * if (World.World.Instance.Agent != null) {
      *  if (World.World.Instance.Agent.AssociatedAvatar != null) {
      *      if (World.World.Instance.Agent.AssociatedAvatar.RegionContext != null) {
      *          if (m_renderer != null) {
      *              LogManager.Log.Log(LogLevel.DWORLDDETAIL, "RegionTracker: setting focus region {0}",
      *                  World.World.Instance.Agent.AssociatedAvatar.RegionContext.Name);
      *              m_renderer.SetFocusRegion(World.World.Instance.Agent.AssociatedAvatar.RegionContext);
      *          }
      *      }
      *  }
      * }
      */
     // for the moment, any close by region is good enough for focus
     if (m_renderer != null)
     {
         LogManager.Log.Log(LogLevel.DWORLDDETAIL, "RegionTracker: setting focus region {0}", rcontext.Name);
         m_renderer.SetFocusRegion(rcontext);
     }
 }
        //int[] CubeMapDefines = new int[]
        //{
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
        //};

        private void RenderPrims(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Texture2D);

            lock (rri.renderPrimList) {
                bool firstPass = true;
                // GL.Disable(EnableCap.Blend);
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                GL.Enable(EnableCap.DepthTest);

                GL.Enable(EnableCap.Normalize);

                GL.EnableClientState(ArrayCap.TextureCoordArray);
                GL.EnableClientState(ArrayCap.VertexArray);
                GL.EnableClientState(ArrayCap.NormalArray);


StartRender:

                List <RenderablePrim> rpList = new List <RenderablePrim>(rri.renderPrimList.Values);
                // sort back to front
                rpList.Sort(delegate(RenderablePrim rp1, RenderablePrim rp2) {
                    return((int)(((OMV.Vector3.Distance(m_renderer.Camera.Position, rp1.Prim.Position)) -
                                  (OMV.Vector3.Distance(m_renderer.Camera.Position, rp2.Prim.Position))) * 100f));
                });
                foreach (RenderablePrim rp in rpList)
                {
                    // if this prim is not visible, just loop
                    if (!rp.isVisible)
                    {
                        continue;
                    }

                    RenderablePrim prp  = RenderablePrim.Empty;
                    OMV.Primitive  prim = rp.Prim;

                    if (prim.ParentID != 0)
                    {
                        // Get the parent reference
                        if (!rri.renderPrimList.TryGetValue(prim.ParentID, out prp))
                        {
                            // Can't render a child with no parent prim, skip it
                            continue;
                        }
                    }

                    GL.PushName(prim.LocalID);
                    GL.PushMatrix();

                    if (prim.ParentID != 0)
                    {
                        // Apply parent translation and rotation
                        GL.MultMatrix(Math3D.CreateTranslationMatrix(prp.Position));
                        GL.MultMatrix(Math3D.CreateRotationMatrix(prp.Rotation));
                    }

                    // Apply prim translation and rotation
                    GL.MultMatrix(Math3D.CreateTranslationMatrix(rp.Position));
                    // apply region offset for multiple regions
                    GL.MultMatrix(Math3D.CreateTranslationMatrix(CalcRegionOffset(rp.rcontext)));
                    GL.MultMatrix(Math3D.CreateRotationMatrix(rp.Rotation));

                    // Scale the prim
                    GL.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z);

                    // Draw the prim faces
                    for (int j = 0; j < rp.Mesh.Faces.Count; j++)
                    {
                        OMVR.Face  face      = rp.Mesh.Faces[j];
                        FaceData   data      = (FaceData)face.UserData;
                        OMV.Color4 color     = face.TextureFace.RGBA;
                        bool       alpha     = false;
                        int        textureID = 0;

                        if (color.A < 1.0f)
                        {
                            alpha = true;
                        }

                        TextureInfo info;
                        if (face.TextureFace.TextureID != OMV.UUID.Zero &&
                            face.TextureFace.TextureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE &&
                            m_renderer.Textures.TryGetValue(face.TextureFace.TextureID, out info))
                        {
                            if (info.Alpha)
                            {
                                alpha = true;
                            }

                            textureID = info.ID;
                            // if textureID has not been set, need to generate the mipmaps
                            if (textureID == 0)
                            {
                                GenerateMipMaps(rp.acontext, face.TextureFace.TextureID, out textureID);
                                info.ID = textureID;
                            }

                            // Enable texturing for this face
                            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                        }
                        else
                        {
                            if (face.TextureFace.TextureID == OMV.Primitive.TextureEntry.WHITE_TEXTURE ||
                                face.TextureFace.TextureID == OMV.UUID.Zero)
                            {
                                GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill);
                            }
                            else
                            {
                                GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
                            }
                        }

                        // if (firstPass && !alpha || !firstPass && alpha) {
                        // GL.Color4(color.R, color.G, color.B, color.A);
                        float[] matDiffuse = { color.R, color.G, color.B, color.A };
                        GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, matDiffuse);

                        // Bind the texture
                        if (textureID != 0)
                        {
                            GL.Enable(EnableCap.Texture2D);
                            GL.BindTexture(TextureTarget.Texture2D, textureID);
                        }
                        else
                        {
                            GL.Disable(EnableCap.Texture2D);
                        }

                        GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, data.TexCoords);
                        GL.VertexPointer(3, VertexPointerType.Float, 0, data.Vertices);
                        GL.NormalPointer(NormalPointerType.Float, 0, data.Normals);
                        GL.DrawElements(BeginMode.Triangles, data.Indices.Length, DrawElementsType.UnsignedShort, data.Indices);
                        // }
                    }

                    GL.PopMatrix();
                    GL.PopName();
                }

                /*
                 * if (firstPass) {
                 *  firstPass = false;
                 *  GL.Enable(EnableCap.Blend);
                 *  GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                 *  // GL.Disable(EnableCap.DepthTest);
                 *
                 *  goto StartRender;
                 * }
                 */
            }

            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.Texture2D);
        }
 void World_OnWorldRegionUpdated(RegionContextBase rcontext, UpdateCodes what)
 {
 }
        private void UpdateRegionTerrainMesh(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            TerrainInfoBase ti = rcontext.TerrainInfo;

            rri.terrainVertices = new float[3 * ti.HeightMapLength * ti.HeightMapWidth];
            rri.terrainTexCoord = new float[2 * ti.HeightMapLength * ti.HeightMapWidth];
            rri.terrainNormal   = new float[3 * ti.HeightMapLength * ti.HeightMapWidth];
            int nextVert = 0;
            int nextTex  = 0;
            int nextNorm = 0;

            for (int xx = 0; xx < ti.HeightMapLength; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth; yy++)
                {
                    rri.terrainVertices[nextVert + 0] = (float)xx / ti.HeightMapLength * rcontext.Size.X;
                    rri.terrainVertices[nextVert + 1] = (float)yy / ti.HeightMapWidth * rcontext.Size.Y;
                    rri.terrainVertices[nextVert + 2] = ti.HeightMap[xx, yy];
                    nextVert += 3;
                    rri.terrainTexCoord[nextTex + 0] = xx / ti.HeightMapLength;
                    rri.terrainTexCoord[nextTex + 1] = yy / ti.HeightMapWidth;
                    nextTex += 2;
                    rri.terrainNormal[nextNorm + 0] = 0f; // simple normal pointing up
                    rri.terrainNormal[nextNorm + 1] = 1f;
                    rri.terrainNormal[nextNorm + 2] = 0f;
                    nextNorm += 3;
                }
            }
            // Create the quads which make up the terrain
            rri.terrainIndices = new UInt16[4 * ti.HeightMapLength * ti.HeightMapWidth];
            int nextInd = 0;

            for (int xx = 0; xx < ti.HeightMapLength - 1; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth - 1; yy++)
                {
                    rri.terrainIndices[nextInd + 0] = (UInt16)((yy + 0) + (xx + 0) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 1] = (UInt16)((yy + 1) + (xx + 0) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 2] = (UInt16)((yy + 1) + (xx + 1) * ti.HeightMapLength);
                    rri.terrainIndices[nextInd + 3] = (UInt16)((yy + 0) + (xx + 1) * ti.HeightMapLength);
                    nextInd += 4;
                }
            }
            rri.terrainWidth  = ti.HeightMapWidth;
            rri.terrainLength = ti.HeightMapLength;

            // Calculate normals
            // Take three corners of each quad and calculate the normal for the vector
            //   a--b--e--...
            //   |  |  |
            //   d--c--h--...
            // The triangle a-b-d calculates the normal for a, etc
            int nextQuad = 0;
            int nextNrm  = 0;

            for (int xx = 0; xx < ti.HeightMapLength - 1; xx++)
            {
                for (int yy = 0; yy < ti.HeightMapWidth - 1; yy++)
                {
                    OMV.Vector3 aa, bb, cc;
                    int         offset = rri.terrainIndices[nextQuad + 0] * 3;
                    aa.X   = rri.terrainVertices[offset + 0];
                    aa.Y   = rri.terrainVertices[offset + 1];
                    aa.Z   = rri.terrainVertices[offset + 2];
                    offset = rri.terrainIndices[nextQuad + 1] * 3;
                    bb.X   = rri.terrainVertices[offset + 0];
                    bb.Y   = rri.terrainVertices[offset + 1];
                    bb.Z   = rri.terrainVertices[offset + 2];
                    offset = rri.terrainIndices[nextQuad + 3] * 3;
                    cc.X   = rri.terrainVertices[offset + 0];
                    cc.Y   = rri.terrainVertices[offset + 1];
                    cc.Z   = rri.terrainVertices[offset + 2];
                    OMV.Vector3 mm        = aa - bb;
                    OMV.Vector3 nn        = aa - cc;
                    OMV.Vector3 theNormal = -OMV.Vector3.Cross(mm, nn);
                    theNormal.Normalize();
                    rri.terrainNormal[nextNrm + 0] = theNormal.X; // simple normal pointing up
                    rri.terrainNormal[nextNrm + 1] = theNormal.Y;
                    rri.terrainNormal[nextNrm + 2] = theNormal.Z;
                    nextNrm  += 3;
                    nextQuad += 4;
                }
                rri.terrainNormal[nextNrm + 0] = 1.0f;
                rri.terrainNormal[nextNrm + 1] = 0.0f;
                rri.terrainNormal[nextNrm + 2] = 0.0f;
                nextNrm += 3;
            }
        }
Beispiel #17
0
 // When a region is connected, one job is to map it into the view.
 // Chat with the renderer to enhance the rcontext with mapping info
 private void World_OnRegionNew(RegionContextBase rcontext)
 {
     m_log.Log(LogLevel.DVIEWDETAIL, "OnRegionNew: ");
     Renderer.MapRegionIntoView(rcontext);
     return;
 }
 public override void UpdatePatch(RegionContextBase reg, int x, int y, float[] data)
 {
     // even though I am passed the data, I rely on Comm.Client to save it for me
     UpdateHeightMap(reg);
     return;
 }
 void World_OnWorldRegionRemoved(RegionContextBase rcontext)
 {
 }
 public override void UpdatePatch(RegionContextBase reg, int x, int y, float[] data)
 {
     // even though I am passed the data, I rely on Comm.Client to save it for me
     UpdateHeightMap(reg);
     return;
 }
Beispiel #21
0
 // When a region is connected, one job is to map it into the view.
 // Chat with the renderer to enhance the rcontext with mapping info
 private void World_OnRegionRemoved(RegionContextBase rcontext)
 {
     m_log.Log(LogLevel.DVIEWDETAIL, "OnRegionRemoved: ");
     // TODO: when we have proper region management
     return;
 }
Beispiel #22
0
 // Set one region as the focus of display
 public void SetFocusRegion(RegionContextBase rcontext)
 {
     m_focusRegion = rcontext;
     return;
 }
 public LLTerrainInfo(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     init();
 }
 // rendering specific information for placing in  the view
 public void MapRegionIntoView(RegionContextBase rcontext)
 {
     return;
 }
        private void UpdateHeightMap(RegionContextBase reg)
        {
            int stride  = TerrainPatchStride;
            int stride2 = stride * TerrainPatchWidth;

            lock (this) {
                float[,] newHM = new float[TerrainPatchWidth, TerrainPatchLength];
                float minHeight = 999999f;
                float maxHeight = 0f;

                if ((reg == null) || !(reg is LLRegionContext))
                {
                    // things are not set up so create a default, flat heightmap
                    LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                       "LLTerrainInfo: Building default zero terrain");
                    CreateZeroHeight(ref newHM);
                    minHeight = maxHeight = 0f;
                }
                else
                {
                    try {
                        LLRegionContext llreg = (LLRegionContext)reg;
                        OMV.Simulator   sim   = llreg.Simulator;

                        int nullPatchCount = 0;
                        for (int px = 0; px < stride; px++)
                        {
                            for (int py = 0; py < stride; py++)
                            {
                                OMV.TerrainPatch pat = sim.Terrain[px + py * stride];
                                if (pat == null)
                                {
                                    // if no patch, it's all zeros
                                    if (0.0f < minHeight)
                                    {
                                        minHeight = 0.0f;
                                    }
                                    if (0.0f > maxHeight)
                                    {
                                        maxHeight = 0.0f;
                                    }
                                    for (int xx = 0; xx < stride; xx++)
                                    {
                                        for (int yy = 0; yy < stride; yy++)
                                        {
                                            // newHM[(py * stride + yy), (px * stride + xx)] = 0.0f;
                                            newHM[(px * stride + xx), (py * stride + yy)] = 0.0f;
                                        }
                                    }
                                    nullPatchCount++;
                                }
                                else
                                {
                                    for (int xx = 0; xx < stride; xx++)
                                    {
                                        for (int yy = 0; yy < stride; yy++)
                                        {
                                            float height = pat.Data[xx + yy * stride];
                                            // newHM[(py * stride + yy), (px * stride + xx)] = height;
                                            newHM[(px * stride + xx), (py * stride + yy)] = height;
                                            if (height < minHeight)
                                            {
                                                minHeight = height;
                                            }
                                            if (height > maxHeight)
                                            {
                                                maxHeight = height;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        // LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                        //         "LLTerrainInfo: UpdateHeightMap: {0} null patches = {1}", sim.Name, nullPatchCount);
                    }
                    catch {
                        // this usually happens when first starting a region
                        LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                           "LLTerrainInfo: Exception building terrain. Defaulting to zero.");
                        CreateZeroHeight(ref newHM);
                        minHeight = maxHeight = 0f;
                    }
                }
                m_heightMap       = newHM;
                m_heightMapWidth  = TerrainPatchWidth; // X
                m_heightMapLength = TerrainPatchLength;
                m_minimumHeight   = minHeight;
                m_maximumHeight   = maxHeight;
                LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                                   "LLTerrainInfo: New terrain:"
                                   + " min=" + m_minimumHeight.ToString()
                                   + " max=" + m_maximumHeight.ToString()
                                   );
            }
        }
 // Set one region as the focus of display
 public void SetFocusRegion(RegionContextBase rcontext)
 {
     return;
 }
 public LLTerrainInfo(RegionContextBase rcontext, AssetContextBase acontext)
     : base(rcontext, acontext)
 {
     init();
 }
 // something about the terrain has changed, do some updating
 public void UpdateTerrain(RegionContextBase wcontext)
 {
     return;
 }
        private void UpdateHeightMap(RegionContextBase reg)
        {
            int stride = TerrainPatchStride;
            int stride2 = stride * TerrainPatchWidth;

            lock (this) {
            float[,] newHM = new float[TerrainPatchWidth, TerrainPatchLength];
            float minHeight = 999999f;
            float maxHeight = 0f;

            if ((reg == null) || !(reg is LLRegionContext)) {
                // things are not set up so create a default, flat heightmap
                LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                        "LLTerrainInfo: Building default zero terrain");
                CreateZeroHeight(ref newHM);
                minHeight = maxHeight = 0f;
            }
            else {
                try {
                    LLRegionContext llreg = (LLRegionContext)reg;
                    OMV.Simulator sim = llreg.Simulator;

                    int nullPatchCount = 0;
                    for (int px = 0; px < stride; px++) {
                        for (int py = 0; py < stride; py++) {
                            OMV.TerrainPatch pat = sim.Terrain[px + py * stride];
                            if (pat == null) {
                                // if no patch, it's all zeros
                                if (0.0f < minHeight) minHeight = 0.0f;
                                if (0.0f > maxHeight) maxHeight = 0.0f;
                                for (int xx = 0; xx < stride; xx++) {
                                    for (int yy = 0; yy < stride; yy++) {
                                        // newHM[(py * stride + yy), (px * stride + xx)] = 0.0f;
                                        newHM[(px * stride + xx), (py * stride + yy)] = 0.0f;
                                    }
                                }
                                nullPatchCount++;
                            }
                            else {
                                for (int xx = 0; xx < stride; xx++) {
                                    for (int yy = 0; yy < stride; yy++) {
                                        float height = pat.Data[xx + yy * stride];
                                        // newHM[(py * stride + yy), (px * stride + xx)] = height;
                                        newHM[(px * stride + xx), (py * stride + yy)] = height;
                                        if (height < minHeight) minHeight = height;
                                        if (height > maxHeight) maxHeight = height;
                                    }
                                }
                            }
                        }
                    }
                    // LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                    //         "LLTerrainInfo: UpdateHeightMap: {0} null patches = {1}", sim.Name, nullPatchCount);
                }
                catch {
                    // this usually happens when first starting a region
                    LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                            "LLTerrainInfo: Exception building terrain. Defaulting to zero.");
                    CreateZeroHeight(ref newHM);
                    minHeight = maxHeight = 0f;
                }
            }
            m_heightMap = newHM;
            m_heightMapWidth = TerrainPatchWidth;   // X
            m_heightMapLength = TerrainPatchLength;
            m_minimumHeight = minHeight;
            m_maximumHeight = maxHeight;
            LogManager.Log.Log(LogLevel.DWORLDDETAIL,
                    "LLTerrainInfo: New terrain:"
                    + " min=" + m_minimumHeight.ToString()
                    + " max=" + m_maximumHeight.ToString()
                );
            }
        }
 private void RenderAnimations(float timeSinceLastFrame, RegionContextBase rcontext, RegionRenderInfo rri)
 {
     AnimatBase.ProcessAnimations(timeSinceLastFrame, rri);
 }