// try and get an entity from the entity collection in this region public virtual bool TryGetEntity(EntityName entName, out IEntity foundEnt) { bool ret = false; foundEnt = null; IEntityCollection coll; if (this.TryGet<IEntityCollection>(out coll)) { IEntity ent; if (coll.TryGetEntity(entName, out ent)) { foundEnt = ent; ret = true; } } return ret; }
public override void DoTextureLoad(EntityName textureEntityName, AssetType typ, DownloadFinishedCallback finishCall) { EntityNameLL textureEnt = new EntityNameLL(textureEntityName); string worldID = textureEnt.EntityPart; OMV.UUID binID = new OMV.UUID(worldID); if (m_basePath == null) return; // do we already have the file? string textureFilename = Path.Combine(CacheDirBase, textureEnt.CacheFilename); lock (FileSystemAccessLock) { if (File.Exists(textureFilename)) { m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Texture file already exists for " + worldID); bool hasTransparancy = CheckTextureFileForTransparancy(textureFilename); // make the callback happen on a new thread so things don't get tangled (caller getting the callback) Object[] finishCallParams = { finishCall, textureEntityName.Name, hasTransparancy }; m_completionWork.DoLater(FinishCallDoLater, finishCallParams); // m_completionWork.DoLater(new FinishCallDoLater(finishCall, textureEntityName.Name, hasTransparancy)); } else { bool sendRequest = false; lock (m_waiting) { // if this is already being requested, don't waste our time if (m_waiting.ContainsKey(binID)) { m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Already waiting for " + worldID); } else { WaitingInfo wi = new WaitingInfo(binID, finishCall); wi.filename = textureFilename; wi.type = typ; m_waiting.Add(binID, wi); sendRequest = true; } } if (sendRequest) { // this is here because RequestTexture might immediately call the callback // and we should be outside the lock m_log.Log(LogLevel.DTEXTUREDETAIL, "DoTextureLoad: Requesting: " + textureEntityName); // m_texturePipe.RequestTexture(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false); // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 101300f, 0, 0, OnACDownloadFinished, false); // m_comm.GridClient.Assets.RequestImage(binID, OMV.ImageType.Normal, 50f, 0, 0, OnACDownloadFinished, false); ThrottleTextureRequests(binID); } } } return; }
/// <summary> /// </summary> /// <param name="localID"></param> /// <param name="ent"></param> /// <param name="createIt"></param> /// <returns>true if we created a new entry</returns> public bool TryGetCreateEntity(EntityName entName, out IEntity ent, RegionCreateEntityCallback createIt) { // m_log.Log(LogLevel.DWORLDDETAIL, "TryGetCreateEntity: n={0}", entName); try { lock (this) { if (!TryGetEntity(entName, out ent)) { IEntity newEntity = createIt(); AddEntity(newEntity); ent = newEntity; } } return(true); } catch (Exception e) { m_log.Log(LogLevel.DBADERROR, "TryGetCreateEntityLocalID: Failed to create entity: {0}", e.ToString()); } ent = null; return(false); }
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); }
public RegionContextBase GetRegion(EntityName name) { RegionContextBase ret = null; lock (m_regionList) { foreach (RegionContextBase rcb in m_regionList) { if (rcb.Name.Equals(name)) { ret = rcb; break; } } } return ret; }
// Each entity has a scene node and this is the conversion from the name of the // entity to the name of the scene node that contains it. public static string ConvertToOgreSceneNodeName(EntityName entName) { return "SceneNode/" + entName.Name; }
public bool TryGetEntity(EntityName entName, out IEntity ent) { return m_entityDictionary.TryGetValue(entName.Name, out ent); }
public void RequestMesh(EntityName contextEntity, string meshName) { m_log.Log(LogLevel.DRENDERDETAIL, "Request for mesh " + meshName); lock (m_requestedMeshes) { // if this mesh was requested was requested more than some time ago, request again if (m_requestedMeshes.ContainsKey(meshName)) { if (m_requestedMeshes[meshName] < Utilities.TickCount()) { m_requestedMeshes.Remove(meshName); } } if (!m_requestedMeshes.ContainsKey(meshName)) { m_requestedMeshes.Add(meshName, Utilities.TickCount() + m_meshRememberTime); Object[] meshLaterParams = { meshName, contextEntity }; m_workQueueReqMesh.DoLater(RequestMeshLater, (object)meshLaterParams); } } return; }
private void CreateMaterialParameters(OMV.Primitive.TextureEntryFace textureFace, IEntity ent, OMV.Primitive prim, int pBase, ref float[] textureParams, int faceNum, out String texName) { OMV.UUID textureID = OMV.Primitive.TextureEntry.WHITE_TEXTURE; if (textureFace != null) { textureParams[pBase + (int)Ogr.CreateMaterialParam.colorR] = textureFace.RGBA.R; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorG] = textureFace.RGBA.G; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorB] = textureFace.RGBA.B; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorA] = textureFace.RGBA.A; if (m_useRendererTextureScaling) { textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleU] = 1f / textureFace.RepeatU; textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleV] = 1f / textureFace.RepeatV; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollU] = textureFace.OffsetU; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollV] = -textureFace.OffsetV; textureParams[pBase + (int)Ogr.CreateMaterialParam.rotate] = textureFace.Rotation; } else { textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleU] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleV] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollU] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollV] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.rotate] = 0.0f; } textureParams[pBase + (int)Ogr.CreateMaterialParam.glow] = textureFace.Glow; textureParams[pBase + (int)Ogr.CreateMaterialParam.bump] = (float)textureFace.Bump; textureParams[pBase + (int)Ogr.CreateMaterialParam.shiny] = (float)textureFace.Shiny; textureParams[pBase + (int)Ogr.CreateMaterialParam.fullBright] = textureFace.Fullbright ? 1f : 0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.mappingType] = (float)textureFace.TexMapType; textureParams[pBase + (int)Ogr.CreateMaterialParam.mediaFlags] = textureFace.MediaFlags ? 1f : 0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.animationFlag] = 0f; if (prim != null && (prim.TextureAnim.Face == faceNum || (int)prim.TextureAnim.Face == 255) // && ((prim.TextureAnim.Flags & OpenMetaverse.Primitive.TextureAnimMode.ANIM_ON) != 0)) { && ((prim.TextureAnim.Flags != 0))) { m_log.Log(LogLevel.DRENDERDETAIL, "Adding animation for material texture"); textureParams[pBase + (int)Ogr.CreateMaterialParam.animationFlag] = (float)prim.TextureAnim.Flags; textureParams[pBase + (int)Ogr.CreateMaterialParam.animSizeX] = (float)prim.TextureAnim.SizeX; textureParams[pBase + (int)Ogr.CreateMaterialParam.animSizeY] = (float)prim.TextureAnim.SizeY; textureParams[pBase + (int)Ogr.CreateMaterialParam.animStart] = prim.TextureAnim.Start; textureParams[pBase + (int)Ogr.CreateMaterialParam.animRate] = prim.TextureAnim.Rate; textureParams[pBase + (int)Ogr.CreateMaterialParam.animLength] = prim.TextureAnim.Length; } else { textureParams[pBase + (int)Ogr.CreateMaterialParam.animationFlag] = 0f; } // since we can't calculate whether material is transparent or not (actually // we don't have that information at this instant), assume color transparent if (textureFace.RGBA.A == 1.0) { // The vertex color doesn't have alpha. Assume the texture that goes on here does. // We do this because we don't have the texture at the moment textureParams[pBase + (int)Ogr.CreateMaterialParam.textureHasTransparent] = 2f; } else { // Pass the overall transparancy textureParams[pBase + (int)Ogr.CreateMaterialParam.textureHasTransparent] = textureFace.RGBA.A; } textureID = textureFace.TextureID; } else { textureParams[pBase + (int)Ogr.CreateMaterialParam.colorR] = 0.4f; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorG] = 0.4f; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorB] = 0.4f; textureParams[pBase + (int)Ogr.CreateMaterialParam.colorA] = 0.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleU] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scaleV] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollU] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.scrollV] = 1.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.rotate] = 0.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.glow] = 0.0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.bump] = (float)OMV.Bumpiness.None; textureParams[pBase + (int)Ogr.CreateMaterialParam.shiny] = (float)OMV.Shininess.None; textureParams[pBase + (int)Ogr.CreateMaterialParam.fullBright] = 0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.mappingType] = 0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.mediaFlags] = 0f; textureParams[pBase + (int)Ogr.CreateMaterialParam.textureHasTransparent] = 0f; } EntityName textureEntityName = new EntityName(ent, textureID.ToString()); string textureOgreResourceName = ""; if (textureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE) { textureOgreResourceName = EntityNameOgre.ConvertToOgreNameX(textureEntityName, null); } texName = textureOgreResourceName; }
/// <summary> /// Create a mesh for the avatar. We either use the specified avatar mesh or create the /// mesh from the LAD definition file. /// </summary> public bool CreateAvatarMeshResource(float priority, IEntity ent, string meshName, EntityName contextEntity) { if (m_defaultAvatarMesh != null && m_defaultAvatarMesh.Length > 0) { return CreateAvatarMeshFromDefault(priority, ent, meshName, contextEntity); } string meshInfoDir = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.InfoDir"); string meshInfoDefn = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.Description"); string meshDescriptionDir = LookingGlassBase.Instance.AppParams.ParamString("Renderer.Avatar.Mesh.DescriptionDir"); Dictionary<string, OMVR.LindenMesh> meshTypes = new Dictionary<string, OMVR.LindenMesh>(); XmlDocument lad = new XmlDocument(); lad.Load(Path.Combine(meshInfoDir, meshInfoDefn)); XmlNodeList meshes = lad.GetElementsByTagName("mesh"); foreach (XmlNode meshNode in meshes) { string type = meshNode.Attributes.GetNamedItem("type").Value; int lod = Int32.Parse(meshNode.Attributes.GetNamedItem("lod").Value); string fileName = meshNode.Attributes.GetNamedItem("file_name").Value; //string minPixelWidth = meshNode.Attributes.GetNamedItem("min_pixel_width").Value; // for the moment, ignore the skirt if (type == "skirtMesh") continue; if (lod == 0) { // only collect the meshes with the highest resolution try { fileName = Path.Combine(meshDescriptionDir, fileName); if (!meshTypes.ContainsKey(type)) { OMVR.LindenMesh lmesh = new OMVR.LindenMesh(type); lmesh.LoadMesh(fileName); meshTypes.Add(type, lmesh); } } catch (Exception e) { m_log.Log(LogLevel.DBADERROR, "Failure reading avatar defn file {0}: {1}", fileName, e); } } } // meshTypes now contains the pieces of the avatar. string[] meshOrder = { "headMesh", "upperBodyMesh", "lowerBodyMesh", "eyeBallLeftMesh", "hairMesh", "skirtMesh", "eyelashMesh", "eyeBallRightMesh" }; // Assemble into one mesh for passing to lower system // TODO: get and pass the skeleton information if (!CreateAvatarTextures(ent, false)) { // something about the textures can't be built yet. Try again later. return false; } const int faceCountsStride = 6; const int verticesStride = 8; const int indicesStride = 3; const int vertexColorStride = 4; // calculate how many floating point numbers we're pushing over int[] faceCounts = new int[meshTypes.Count * faceCountsStride + 2]; faceCounts[0] = faceCounts.Length; faceCounts[1] = meshTypes.Count; int totalVertices = 0; try { for (int jj=0; jj < meshTypes.Count; jj++) { if (!meshTypes.ContainsKey(meshOrder[jj])) continue; OMVR.LindenMesh lmesh = meshTypes[meshOrder[jj]]; int faceBase = jj * faceCountsStride + 2; faceCounts[faceBase + 0] = totalVertices; faceCounts[faceBase + 1] = lmesh.NumVertices; faceCounts[faceBase + 2] = verticesStride; totalVertices += vertexColorStride + lmesh.NumVertices * verticesStride; faceCounts[faceBase + 3] = totalVertices; faceCounts[faceBase + 4] = lmesh.NumFaces * indicesStride; faceCounts[faceBase + 5] = indicesStride; totalVertices += lmesh.NumFaces * indicesStride; } float[] faceVertices = new float[totalVertices + 2]; faceVertices[0] = faceVertices.Length; int vertI = 1; for (int jj=0; jj < meshTypes.Count; jj++) { if (!meshTypes.ContainsKey(meshOrder[jj])) continue; OMVR.LindenMesh lmesh = meshTypes[meshOrder[jj]]; faceVertices[vertI + 0] = 0.6f; faceVertices[vertI + 1] = 0.6f; faceVertices[vertI + 2] = 0.6f; faceVertices[vertI + 3] = 0.5f; vertI += vertexColorStride; for (int k = 0; k < lmesh.NumVertices; k++) { OMVR.LindenMesh.Vertex thisVert = lmesh.Vertices[k]; // m_log.Log(LogLevel.DRENDERDETAIL, "CreateMesh: vertices: p={0}, t={1}, n={2}", // thisVert.Position.ToString(), thisVert.TexCoord.ToString(), thisVert.Normal.ToString()); faceVertices[vertI + 0] = thisVert.Coord.X; faceVertices[vertI + 1] = thisVert.Coord.Y; faceVertices[vertI + 2] = thisVert.Coord.Z; faceVertices[vertI + 3] = thisVert.TexCoord.X; faceVertices[vertI + 4] = thisVert.TexCoord.Y; faceVertices[vertI + 5] = thisVert.Normal.X; faceVertices[vertI + 6] = thisVert.Normal.Y; faceVertices[vertI + 7] = thisVert.Normal.Z; vertI += verticesStride; } for (int k = 0; k < lmesh.NumFaces; k++) { faceVertices[vertI + 0] = lmesh.Faces[k].Indices[0]; faceVertices[vertI + 1] = lmesh.Faces[k].Indices[1]; faceVertices[vertI + 2] = lmesh.Faces[k].Indices[2]; vertI += indicesStride; } } m_log.Log(LogLevel.DRENDERDETAIL, "RenderOgreLL.CreateAvatarMeshResource: {0}, fcs={1}, fs={2}, vi={3}", ent.Name, faceCounts.Length, faceVertices.Length, vertI ); // We were passed a 'context' entity. Create a scene node name to pass to // Ogre. If the scene node is not found, nothing bad happens. string contextSceneNode = EntityNameOgre.ConvertToOgreSceneNodeName(contextEntity); // Now create the mesh Ogr.CreateMeshResourceBF(priority, meshName, contextSceneNode, faceCounts, faceVertices); } catch (Exception e) { m_log.Log(LogLevel.DBADERROR, "Failure building avatar mesh: {0}", e); } return true; }
// Each entity has a scene node and this is the conversion from the name of the // entity to the name of the scene node that contains it. public static string ConvertToOgreEntityName(EntityName entName) { return "Entity/" + entName.Name; }
private void OnTextureDownloadFinished(string textureEntityName, bool hasTransparancy) { m_log.Log(LogLevel.DRENDERDETAIL, "OnTextureDownloadFinished {0}", textureEntityName); EntityName entName = new EntityName(textureEntityName); OMV.UUID id = new OMV.UUID(entName.ExtractEntityFromEntityName()); TextureInfo info; lock (Textures) { if (!Textures.TryGetValue(id, out info)) { // The id of zero will say that the mipmaps need to be generated before the texture is used m_log.Log(LogLevel.DRENDERDETAIL, "Adding TextureInfo for {0}:{1}", entName.Name, id.ToString()); info.Alpha = hasTransparancy; } } }
public bool TryGetEntity(EntityName entName, out IEntity ent) { return(m_entityDictionary.TryGetValue(entName.Name, out ent)); }
public EntityName(EntityName entName) : this(entName.Name) { }
/// <summary> /// A global call to find an entity. We ask all the regions if they have it. /// This is only here because the renderer looses the context for an entity /// when control passes into the renderer and then back. The renderer only /// has the name of the entity. /// </summary> /// <param name="entName">the name of the entity to look for</param> /// <param name="ent">place to store the reference to the found entity</param> /// <returns>'true' if entity found</returns> public bool TryGetEntity(EntityName entName, out IEntity ent) { IEntity ret = null; lock (m_regionList) { foreach (RegionContextBase rcb in m_regionList) { IEntityCollection coll; if (rcb.TryGet<IEntityCollection>(out coll)) { coll.TryGetEntity(entName, out ret); } if (ret != null) break; } } ent = ret; return (ret != null); }
// Each entity has a scene node and this is the conversion from the name of the // entity to the name of the scene node that contains it. public static EntityName ConvertToOgreMaterialName(EntityName entName) { return ConvertToOgreNameY(entName, ".material"); }
public bool CreateAvatarMeshFromDefault(float priority, IEntity ent, string meshName, EntityName contextEntity) { m_log.Log(LogLevel.DBADERROR, "CreateAvatarMeshFromDefault: NOT IMPLEMENTED!!"); return true; }
// One place to hide the crazy name that the face materials have public static string ConvertToOgreMaterialNameX(EntityName entName, int faceNum) { return ConvertToOgreNameX(entName, ".mesh-" + faceNum.ToString() + ".material"); }
/// <summary> /// Create a mesh in the renderer. /// </summary> /// <param name="sMgr">the scene manager receiving the mesh</param> /// <param name="ent">The entity the mesh is coming from</param> /// <param name="meshName">The name the mesh should take</param> public bool CreateMeshResource(float priority, IEntity ent, string meshName, EntityName contextEntity) { LLEntityBase llent; OMV.Primitive prim; try { // this will change when we are checking for avatars and other types llent = (LLEntityBase)ent; prim = llent.Prim; if (prim == null) throw new LookingGlassException("ASSERT: RenderOgreLL: prim is null"); } catch (Exception e) { m_log.Log(LogLevel.DRENDERDETAIL, "CreateMeshResource: conversion of pointers failed: " + e.ToString()); throw e; } int meshType = 0; int meshFaces = 0; // TODO: This is the start of come code to specialize the creation of standard // meshes. Since a large number of prims are cubes, they can share the face vertices // and thus reduce the total number of Ogre's vertices stored. // At the moment, CheckStandardMeshType returns false so we don't do anything special yet lock (ent) { if (CheckStandardMeshType(prim, out meshType, out meshFaces)) { m_log.Log(LogLevel.DBADERROR, "CreateMeshResource: not implemented Standard Type"); /* // while we're in the neighborhood, we can create the materials if (m_buildMaterialsAtMeshCreationTime) { for (int j = 0; j < meshFaces; j++) { CreateMaterialResource2(ent, prim, EntityNameOgre.ConvertToOgreMaterialNameX(ent.Name, j), j); } } Ogr.CreateStandardMeshResource(meshName, meshType); */ } else { OMVR.FacetedMesh mesh; try { if (prim.Sculpt != null) { // looks like it's a sculpty. Do it that way EntityNameLL textureEnt = EntityNameLL.ConvertTextureWorldIDToEntityName(ent.AssetContext, prim.Sculpt.SculptTexture); System.Drawing.Bitmap textureBitmap = ent.AssetContext.GetTexture(textureEnt); if (textureBitmap == null) { m_log.Log(LogLevel.DRENDERDETAIL, "CreateMeshResource: waiting for texture for sculpty {0}", ent.Name.Name); // Don't have the texture now so ask for the texture to be loaded. // Note that we ignore the callback and let the work queue requeing get us back here ent.AssetContext.DoTextureLoad(textureEnt, AssetContextBase.AssetType.SculptieTexture, delegate(string name, bool trans) { return; }); // This will cause the work queue to requeue the mesh creation and call us // back later to retry creating the mesh return false; } m_log.Log(LogLevel.DRENDERDETAIL, "CreateMeshResource: mesherizing scuplty {0}", ent.Name.Name); // mesh = m_meshMaker.GenerateSculptMesh(textureBitmap, prim, OMVR.DetailLevel.Highest); mesh = m_meshMaker.GenerateSculptMesh(textureBitmap, prim, OMVR.DetailLevel.Medium); // mesh = m_meshMaker.GenerateSculptMesh(textureBitmap, prim, OMVR.DetailLevel.Low); if (mesh.Faces.Count > 10) { m_log.Log(LogLevel.DBADERROR, "CreateMeshResource: mesh has {0} faces!!!!", mesh.Faces.Count); } textureBitmap.Dispose(); } else { // we really should use Low for boxes, med for most things and high for megaprim curves // OMVR.DetailLevel meshDetail = OMVR.DetailLevel.High; OMVR.DetailLevel meshDetail = OMVR.DetailLevel.Medium; if (prim.Type == OMV.PrimType.Box) { meshDetail = OMVR.DetailLevel.Low; // m_log.Log(LogLevel.DRENDERDETAIL, "CreateMeshResource: Low detail for {0}", ent.Name.Name); } mesh = m_meshMaker.GenerateFacetedMesh(prim, meshDetail); if (mesh.Faces.Count > 10) { m_log.Log(LogLevel.DBADERROR, "CreateMeshResource: mesh has {0} faces!!!!", mesh.Faces.Count); } } } catch (Exception e) { m_log.Log(LogLevel.DRENDERDETAIL, "CreateMeshResource: failed mesh generate for {0}: {1}", ent.Name.Name, e.ToString()); throw e; } // we have the face data. We package this up into a few big arrays to pass them // to the real renderer. // we pass two one-dimensional arrays of floating point numbers over to the // unmanaged code. The first array contains: // faceCounts[0] = total number of int's in this array (for alloc and freeing in Ogre) // faceCounts[1] = number of faces // faceCounts[2] = offset in second array for beginning of vertex info for face 1 // faceCounts[3] = number of vertices for face 1 // faceCounts[4] = stride for vertex info for face 1 (= 8) // faceCounts[5] = offset in second array for beginning of indices info for face 1 // faceCounts[6] = number of indices for face 1 // faceCounts[7] = stride for indices (= 3) // faceCounts[8] = offset in second array for beginning of vertex info for face 2 // faceCounts[9] = number of vertices for face 2 // faceCounts[10] = stride for vertex info for face 2 (= 8) // etc // The second array starts with the vertex color: // v.R, v.G, v.B, v.A // which is followed by the vertex info in the order: // v.X, v.Y, v.Z, u.X, u.Y, n.X, n.Y, n.Z // this is repeated for each vertex // This is followed by the list of indices listed as i.X, i.Y, i.Z const int faceCountsStride = 6; const int verticesStride = 8; const int indicesStride = 3; const int vertexColorStride = 4; // calculate how many floating point numbers we're pushing over int[] faceCounts = new int[mesh.Faces.Count * faceCountsStride + 2]; faceCounts[0] = faceCounts.Length; faceCounts[1] = mesh.Faces.Count; int totalVertices = 0; for (int j = 0; j < mesh.Faces.Count; j++) { OMVR.Face face = mesh.Faces[j]; int faceBase = j * faceCountsStride + 2; // m_log.Log(LogLevel.DRENDERDETAIL, "Mesh F" + j.ToString() + ":" // + " vcnt=" + face.Vertices.Count.ToString() // + " icnt=" + face.Indices.Count.ToString()); faceCounts[faceBase + 0] = totalVertices; faceCounts[faceBase + 1] = face.Vertices.Count; faceCounts[faceBase + 2] = verticesStride; totalVertices += vertexColorStride + face.Vertices.Count * verticesStride; faceCounts[faceBase + 3] = totalVertices; faceCounts[faceBase + 4] = face.Indices.Count; faceCounts[faceBase + 5] = indicesStride; totalVertices += face.Indices.Count; } float[] faceVertices = new float[totalVertices+2]; faceVertices[0] = faceVertices.Length; int vertI = 1; for (int j = 0; j < mesh.Faces.Count; j++) { OMVR.Face face = mesh.Faces[j]; // Texture transform for this face OMV.Primitive.TextureEntryFace teFace = face.TextureFace; try { if ((teFace != null) && !m_useRendererTextureScaling) { m_meshMaker.TransformTexCoords(face.Vertices, face.Center, teFace); } } catch { m_log.Log(LogLevel.DBADERROR, "RenderOgreLL.CreateMeshResource:" + " more faces in mesh than in prim:" + " ent=" + ent.Name + ", face=" + j.ToString() ); } // Vertices color for this face OMV.Primitive.TextureEntryFace tef = prim.Textures.GetFace((uint)j); if (tef != null) { faceVertices[vertI + 0] = tef.RGBA.R; faceVertices[vertI + 1] = tef.RGBA.G; faceVertices[vertI + 2] = tef.RGBA.B; faceVertices[vertI + 3] = tef.RGBA.A; } else { faceVertices[vertI + 0] = 1f; faceVertices[vertI + 1] = 1f; faceVertices[vertI + 2] = 1f; faceVertices[vertI + 3] = 1f; } vertI += vertexColorStride; // Vertices for this face for (int k = 0; k < face.Vertices.Count; k++) { OMVR.Vertex thisVert = face.Vertices[k]; // m_log.Log(LogLevel.DRENDERDETAIL, "CreateMesh: vertices: p={0}, t={1}, n={2}", // thisVert.Position.ToString(), thisVert.TexCoord.ToString(), thisVert.Normal.ToString()); faceVertices[vertI + 0] = thisVert.Position.X; faceVertices[vertI + 1] = thisVert.Position.Y; faceVertices[vertI + 2] = thisVert.Position.Z; faceVertices[vertI + 3] = thisVert.TexCoord.X; faceVertices[vertI + 4] = thisVert.TexCoord.Y; faceVertices[vertI + 5] = thisVert.Normal.X; faceVertices[vertI + 6] = thisVert.Normal.Y; faceVertices[vertI + 7] = thisVert.Normal.Z; vertI += verticesStride; } for (int k = 0; k < face.Indices.Count; k += 3) { faceVertices[vertI + 0] = face.Indices[k + 0]; faceVertices[vertI + 1] = face.Indices[k + 1]; faceVertices[vertI + 2] = face.Indices[k + 2]; vertI += indicesStride; } } // while we're in the neighborhood, we can create the materials if (m_buildMaterialsAtMeshCreationTime) { CreateMaterialResource7X(priority, ent, prim, mesh.Faces.Count); } // We were passed a 'context' entity. Create a scene node name to pass to // Ogre. If the scene node is not found, nothing bad happens. string contextSceneNode = EntityNameOgre.ConvertToOgreSceneNodeName(contextEntity); m_log.Log(LogLevel.DRENDERDETAIL, "RenderOgreLL: {0}, f={1}, fcs={2}, fs={3}", ent.Name, mesh.Faces.Count, faceCounts.Length, faceVertices.Length ); // Now create the mesh Ogr.CreateMeshResourceBF(priority, meshName, contextSceneNode, faceCounts, faceVertices); } } return true; }
// Each entity has a scene node and this is the conversion from the name of the // entity to the name of the scene node that contains it. public static EntityName ConvertToOgreMeshName(EntityName entName) { return ConvertToOgreNameY(entName, ".mesh"); }
// if it starts with our region name, it must be ours public override bool isTextureOwner(EntityName textureEntityName) { return textureEntityName.Name.StartsWith(m_Name + EntityName.PartSeparator); }
// ================================================ // After here are conversion routines that are sometimes needed to link between // the Ogre resource names and regular entity names. Use at your peril. // Ogre presumes that entity name will be the filename in the cache. Make the // entity name on the Ogre side have the cache filename format // Used for meshes, materials public static string ConvertToOgreNameX(EntityName entName, string extension) { string entReplace = Regex.Replace(entName.EntityPart, EntityNameMatch, CachedNameReplace); // if the replacement didn't happen entReplace == entName string newName = entName.CombineEntityName(entName.HeaderPart, entName.HostPart, entReplace); if (extension != null) newName += extension; // LogManager.Log.Log(LogLevel.DRENDERDETAIL, "ConvertToOgreName: " + entName.ToString() + " => " + newName); return newName; }
public static EntityName ConvertToOgreNameY(EntityName entName, string extension) { string entReplace = Regex.Replace(entName.EntityPart, EntityNameMatch, CachedNameReplace); // if the replacement didn't happen entReplace == entName if (extension != null) entReplace += extension; EntityName newName = new EntityNameOgre(entName.HeaderPart, entName.HostPart, entReplace); return newName; }
public EntityNameLL(EntityName ent) : base(ent.Name) { }
/// <summary> /// </summary> /// <param name="localID"></param> /// <param name="ent"></param> /// <param name="createIt"></param> /// <returns>true if we created a new entry</returns> public bool TryGetCreateEntity(EntityName entName, out IEntity ent, RegionCreateEntityCallback createIt) { // m_log.Log(LogLevel.DWORLDDETAIL, "TryGetCreateEntity: n={0}", entName); try { lock (this) { if (!TryGetEntity(entName, out ent)) { IEntity newEntity = createIt(); AddEntity(newEntity); ent = newEntity; } } return true; } catch (Exception e) { m_log.Log(LogLevel.DBADERROR, "TryGetCreateEntityLocalID: Failed to create entity: {0}", e.ToString()); } ent = null; return false; }