public EntityCamera(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { m_yawFixed = true; m_globalPosition = new OMV.Vector3d(40f, 40f, 30f); m_heading = new OMV.Quaternion(0f, 1f, 0f); }
public EntityCamera(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { m_yawFixed = true; m_globalPosition = new OMV.Vector3d(40f, 40f, 30f); m_heading = new OMV.Quaternion(0f, 1f, 0f); }
public RegionContextBase(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { m_regionState = new RegionState(); m_regionStateChangedCallback = new RegionStateChangedCallback(State_OnChange); State.OnStateChanged += m_regionStateChangedCallback; m_entityCollection = new EntityCollection(this.Name.Name); this.RegisterInterface<IEntityCollection>(m_entityCollection); this.RegisterInterface<IRegionContext>(this); }
public EntityBase(RegionContextBase rcontext, AssetContextBase acontext) { Additions = new Object[EntityBase.ADDITIONCLASSES]; for (int ii = 0; ii < EntityBase.ADDITIONCLASSES; ii++) { Additions[ii] = null; } m_LGID = NextLGID(); m_worldContext = World.Instance; m_regionContext = rcontext; m_assetContext = acontext; }
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 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; }
// Set one region as the focus of display public void SetFocusRegion(RegionContextBase rcontext) { m_focusRegion = rcontext; return; }
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(); }
// 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 EntityLight(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
// ========================================================================== public void SetFocusRegion(RegionContextBase rcontext) { m_log.Log(LogLevel.DRENDERDETAIL, "SetFocusRegion: setting focus region {0}", rcontext.Name); Ogr.SetFocusRegionBF(EntityNameOgre.ConvertToOgreSceneNodeName(rcontext.Name)); }
public void AddRegion(RegionContextBase rcontext) { m_log.Log(LogLevel.DWORLD, "Simulator connected " + rcontext.Name); RegionContextBase foundRegion = null; lock (m_regionList) { foundRegion = GetRegion(rcontext.Name); if (foundRegion == null) { // we don't know about this region. Add it and connect to events m_regionList.Add(rcontext); IEntityCollection coll; if (rcontext.TryGet<IEntityCollection>(out coll)) { if (Region_OnNewEntityCallback == null) { Region_OnNewEntityCallback = new EntityNewCallback(Region_OnNewEntity); } coll.OnEntityNew += Region_OnNewEntityCallback; if (Region_OnUpdateEntityCallback == null) { Region_OnUpdateEntityCallback = new EntityUpdateCallback(Region_OnUpdateEntity); } coll.OnEntityUpdate += Region_OnUpdateEntityCallback; if (Region_OnRemovedEntityCallback == null) { Region_OnRemovedEntityCallback = new EntityRemovedCallback(Region_OnRemovedEntity); } coll.OnEntityRemoved += Region_OnRemovedEntityCallback; } if (Region_OnRegionUpdatedCallback == null) { Region_OnRegionUpdatedCallback = new RegionRegionUpdatedCallback(Region_OnRegionUpdated); } rcontext.OnRegionUpdated += Region_OnRegionUpdatedCallback; } } // tell the world there is a new region (do it outside the lock) if (foundRegion == null) { if (OnWorldRegionNew != null) OnWorldRegionNew(rcontext); } }
private void Region_OnRegionUpdated(RegionContextBase rcontext, UpdateCodes what) { if (OnWorldRegionUpdated != null) OnWorldRegionUpdated(rcontext, what); return; }
public EntityLight(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
// 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; }
public TerrainInfoBase(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
// the patch is presumed to be Stride width and length public virtual void UpdatePatch(RegionContextBase reg, int x, int y, float[] data) { return; }
public EntityAvatarBase(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
// the patch is presumed to be Stride width and length public virtual void UpdatePatch(RegionContextBase reg, int x, int y, float[] data) { return; }
public void RemoveRegion(RegionContextBase rcontext) { RegionContextBase foundRegion = null; lock (m_regionList) { foundRegion = GetRegion(rcontext.Name); if (foundRegion != null) { // we know about this region so remove it and disconnect from events m_regionList.Remove(foundRegion); m_log.Log(LogLevel.DWORLD, "Removing region " + foundRegion.Name); IEntityCollection coll; if (rcontext.TryGet<IEntityCollection>(out coll)) { if (Region_OnNewEntityCallback != null) { coll.OnEntityNew -= Region_OnNewEntityCallback; } if (Region_OnUpdateEntityCallback != null) { coll.OnEntityUpdate -= Region_OnUpdateEntityCallback; } if (Region_OnRemovedEntityCallback != null) { coll.OnEntityRemoved -= Region_OnRemovedEntityCallback; } } if (Region_OnRegionUpdatedCallback != null) { rcontext.OnRegionUpdated -= Region_OnRegionUpdatedCallback; } if (OnWorldRegionRemoved != null) OnWorldRegionRemoved(rcontext); } else { m_log.Log(LogLevel.DBADERROR, "RemoveRegion: asked to remove region we don't have. Name={0}", rcontext.Name); } } }
public TerrainInfoBase(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
/// <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; }
// ========================================================================== public void MapRegionIntoView(RegionContextBase rcontext) { Ogr.AddRegionBF(0f, EntityNameOgre.ConvertToOgreSceneNodeName(rcontext.Name), // rcontext.GlobalPosition.X, rcontext.GlobalPosition.Z, -rcontext.GlobalPosition.Y, rcontext.GlobalPosition.X, (double)0, -rcontext.GlobalPosition.Y, rcontext.Size.X, rcontext.Size.Y, rcontext.TerrainInfo.WaterHeight); return; }
private void RenderAnimations(float timeSinceLastFrame, RegionContextBase rcontext, RegionRenderInfo rri) { AnimatBase.ProcessAnimations(timeSinceLastFrame, rri); }
// ========================================================================== public void UpdateTerrain(RegionContextBase rcontext) { m_log.Log(LogLevel.DRENDERDETAIL, "RenderOgre: UpdateTerrain: for region {0}", rcontext.Name.Name); try { float[,] hm = rcontext.TerrainInfo.HeightMap; int hmWidth = rcontext.TerrainInfo.HeightMapWidth; int hmLength = rcontext.TerrainInfo.HeightMapLength; int loc = 0; float[] passingHM = new float[hmWidth * hmLength]; for (int xx = 0; xx < hmWidth; xx++) { for (int yy = 0; yy < hmLength; yy++) { passingHM[loc++] = hm[xx, yy]; } } Ogr.UpdateTerrainBF(0, EntityNameOgre.ConvertToOgreSceneNodeName(rcontext.Name), hmWidth, hmLength, passingHM); } catch (Exception e) { m_log.Log(LogLevel.DBADERROR, "UpdateTerrainLater: mesh creation failure: " + e.ToString()); } return; }
private void RenderOcean(RegionContextBase rcontext, RegionRenderInfo rri) { GL.PushMatrix(); // apply region offset GL.MultMatrix(Math3D.CreateTranslationMatrix(CalcRegionOffset(rcontext))); GL.PopMatrix(); return; }
// rendering specific information for placing in the view public void MapRegionIntoView(RegionContextBase rcontext) { return; }
public EntityAvatarBase(RegionContextBase rcontext, AssetContextBase acontext) : base(rcontext, acontext) { }
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; }
// Set one region as the focus of display public void SetFocusRegion(RegionContextBase rcontext) { return; }
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(); } } }
// something about the terrain has changed, do some updating public void UpdateTerrain(RegionContextBase wcontext) { return; }
//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); }
// 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; }
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; } }
// 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; }