/// <summary> /// If we've got the texture, return it and true. If not, then return false /// </summary> /// <param name="assetID">the Asset ID of the texture</param> /// <param name="tex">The texture</param> /// <returns>If we have the texture or not</returns> public bool tryGetTexture(UUID assetID, out TextureExtended tex) { tex = null; lock (memoryTextures) { if (memoryTextures.ContainsKey(assetID)) { tex = memoryTextures[assetID]; } } if (tex != null) { return true; } string texturefolderpath = imagefolder; bool alreadyRequesting = false; lock (outstandingRequests) { if (outstandingRequests.ContainsKey(assetID)) { alreadyRequesting = true; } } // Check if we've got this texture on the file system. if (!alreadyRequesting && File.Exists(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga"))) { Texture texTnorm = Reference.VideoDriver.GetTexture(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga")); tex = new TextureExtended(texTnorm.Raw, ".tga"); if (tex != null) { lock (memoryTextures) { if (!memoryTextures.ContainsKey(assetID)) { memoryTextures.Add(assetID, tex); } } return true; } } return false; }
private bool IsAlphaImage(TextureExtended tex) { bool alphaimage = false; // Check if we've already run this through our image alpha checker if (tex.Userdata == null) { // Check if this image has an alpha channel in use // All textures are 32 Bit and alpha capable, so we have to scan it for an // alpha pixel Color[,] imgcolors; try { imgcolors = tex.Retrieve(); for (int i = 0; i < imgcolors.GetUpperBound(0); i++) { for (int j = 0; j < imgcolors.GetUpperBound(1); j++) { if (imgcolors[i, j].A != 255) { alphaimage = true; break; } } if (alphaimage) break; } } catch (OutOfMemoryException) { alphaimage = false; } // Save result tex.Userdata = (object)alphaimage; } else { // Use cached result alphaimage = (bool)tex.Userdata; } return alphaimage; }
public override void Initialize() { base.Initialize(); downloadTextureQueue = new BlockingQueue<TextureDownloadRequest>(); timeout = Reference.Viewer.Config.Source.Configs["Startup"].GetInt("asset_timeout", 60000); textureFetchThread = new Thread(new ThreadStart(TextureFetchHandler)); textureFetchThread.Start(); defaultTexture = new TextureExtended(Reference.VideoDriver.GetTexture(Util.ApplicationDataDirectory + @"/media/textures/dummy_white.tga").Raw, ".tga"); }
/// <summary> /// Requests an image for an object. /// </summary> /// <param name="assetID"></param> /// <param name="requestor"></param> public void RequestImage(UUID assetID, VObject requestor) { TextureExtended tex = null; lock (memoryTextures) { if (memoryTextures.ContainsKey(assetID)) { tex = memoryTextures[assetID]; } } if (tex != null) { // We already have the texture, jump to applyTexture applyTexture(tex, requestor, assetID); // Apply the texture to all objects that are already waiting for this texture lock (outstandingRequests) { if (outstandingRequests.ContainsKey(assetID)) { m_log.Warn("[TEXTURE]: Applying texture from memory to outstanding requestors."); foreach (VObject vObj in outstandingRequests[assetID]) { applyTexture(tex, vObj, assetID); } outstandingRequests.Remove(assetID); } } return; } // Check to see if we've got the texture on disk string texturefolderpath = imagefolder; bool alreadyRequesting = false; lock (outstandingRequests) { if (outstandingRequests.ContainsKey(assetID)) { alreadyRequesting = true; } } if (!alreadyRequesting && File.Exists(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga"))) { Texture texTnorm = Reference.VideoDriver.GetTexture(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga")); if (texTnorm != null) tex = new TextureExtended(texTnorm.Raw, ".tga"); if (tex != null) { lock (memoryTextures) { if (!memoryTextures.ContainsKey(assetID)) { // Add it to the texture cache. memoryTextures.Add(assetID, tex); } } // apply texture applyTexture(tex, requestor, assetID); // Apply the texture to all objects that are already waiting for this texture lock (outstandingRequests) { if (outstandingRequests.ContainsKey(assetID)) { m_log.Warn("[TEXTURE]: Applying texture from memory to outstanding requestors."); foreach (VObject vObj in outstandingRequests[assetID]) { applyTexture(tex, vObj, assetID); } outstandingRequests.Remove(assetID); } } return; } } // Check if we've already got an outstanding request for this texture lock (outstandingRequests) { if (outstandingRequests.ContainsKey(assetID)) { // Add it to the objects to be notified when this texture download is complete. outstandingRequests[assetID].Add(requestor); return; } else { // Create a new outstanding request entry List<VObject> requestors = new List<VObject>(); requestors.Add(requestor); outstandingRequests.Add(assetID,requestors); } } if (string.IsNullOrEmpty(Reference.Viewer.ProtocolManager.AvatarConnection.m_user.Network.AssetServerUri)) { this.texDownloadStyle = TextureDownloadStyle.TEX_DOWNLOAD_LIBOMV; } TextureDownloadRequest req = new TextureDownloadRequest(); req.uuid = assetID; downloadTextureQueue.Enqueue(req); // no need to lock b/c it's a BlockingQueue which needs no synchronization m_log.Info("[TEXTURE]: Added to DownloadTextureQueue current count " + downloadTextureQueue.Count); /* if (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_LIBOMV) { // Request texture from LibOMV m_user.RequestTexture(assetID); } else { // request texture directly from assetserver via our own background thread TextureDownloadRequest req = new TextureDownloadRequest(); req.uuid = assetID; downloadTextureQueue.Enqueue(req); // no need to lock b/c it's a BlockingQueue which needs no synchronization } */ }
// LibOMV callback for completed image texture. public void imageReceivedCallback(AssetTexture asset) { if (asset == null) { m_log.Debug("[TEXTURE]: GotLIBOMV callback but asset was null"); return; } m_log.Debug("[TEXTURE]: GotLIBOMV callback for asset" + asset.AssetID); lock (downloadQueue) { if (downloadQueue.ContainsKey(asset.AssetID)) downloadQueue.Remove(asset.AssetID); } bool result = false; bool bNonJp2000 = true; string extension = string.Empty; try { AssetType type = asset.AssetType; if (asset is OpenViewer.Primitives.ExtendedAssetTexture) { type = (AssetType)((OpenViewer.Primitives.ExtendedAssetTexture)asset).ExtAssetType; //Paupaw:Get the AssetType switch (type) { case AssetType.ImageJPEG: result = true; extension = ".jpg"; break; case AssetType.ImageTGA: result = true; extension = ".tga"; break; case AssetType.Texture: //JP2000 bNonJp2000 = false; result = asset.Decode(); extension = ".tga"; break; } } else if (asset is AssetTexture) { bNonJp2000 = false; result = asset.Decode(); extension = ".tga"; } else { result = true; extension = ".jpg"; } } catch (Exception e) { //m_log.Debug("[TEXTURE]: Failed to decode asset " + asset.AssetID); if (!bNonJp2000) { bNonJp2000 = true; result = true; extension = ".jpg"; } } if (result) { byte[] imgdata = null; if (bNonJp2000) imgdata = asset.AssetData; else imgdata = asset.Image.ExportTGA(); string texturefolderpath = imagefolder; string texturepath = System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension); FileStream fs = (File.Open(texturepath, FileMode.Create)); BinaryWriter bw = new BinaryWriter(fs); bw.Write(imgdata); bw.Flush(); bw.Close(); // Immediately load it to memory if (File.Exists(System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension))) { Texture texTnorm = Reference.VideoDriver.GetTexture(System.IO.Path.Combine(texturefolderpath, asset.AssetID.ToString() + extension)); TextureExtended tex = new TextureExtended(texTnorm.Raw, extension); if (tex != null) { lock (memoryTextures) { if (!memoryTextures.ContainsKey(asset.AssetID)) { memoryTextures.Add(asset.AssetID, tex); } } } } // Update nodes that the texture is downloaded. List<VObject> nodesToUpdate = null; lock (outstandingRequests) { if (outstandingRequests.ContainsKey(asset.AssetID)) { nodesToUpdate = outstandingRequests[asset.AssetID]; outstandingRequests.Remove(asset.AssetID); } } if (nodesToUpdate == null) return; lock (nodesToUpdate) { for (int i = 0; i < nodesToUpdate.Count; i++) { VObject vObj = nodesToUpdate[i]; if (vObj == null || OnTextureLoaded == null) continue; OnTextureLoaded(asset.AssetID.ToString(), extension, vObj, asset.AssetID); Reference.Viewer.Adapter.CallReceiveImage(asset.AssetID.ToString()); } } } }
public override void Cleanup() { if (defaultTexture != null) { defaultTexture = null; } if (textureFetchThread != null) { textureFetchThread.Abort(); textureFetchThread = null; } lock (memoryTextures) { memoryTextures.Clear(); } lock (outstandingRequests) { outstandingRequests.Clear(); } base.Cleanup(); }
/// <summary> /// Bread and butter of the texture system. /// This is the start point for the texture-> graphics pipeline /// </summary> /// <param name="tex"></param> /// <param name="vObj"></param> /// <param name="AssetID"></param> public void applyTexture(TextureExtended tex, VObject vObj, UUID AssetID) { try { // works if (vObj.Mesh == null) return; // Check if we have a sculptie and its sculpting texture // If yes, don't apply the texture if (vObj.Prim.Sculpt != null && vObj.Prim.Sculpt.SculptTexture == AssetID) { m_log.Debug("[TEXTURE]: Skipping applyTexture for sculpt " + AssetID); return; } bool alphaimage = IsAlphaImage(tex); // MeshPrim if (vObj._3DiIrrfileUUID != UUID.Zero && vObj.IrrData != null) { for (int iTex = 0; iTex < vObj.IrrData.Materials.Count; iTex++) { if (Path.GetFileNameWithoutExtension(vObj.IrrData.Materials[iTex].Texture1) == AssetID.ToString()) { Texture loadedTex = Reference.VideoDriver.GetTexture(AssetID.ToString() + tex.extension); if (vObj.Node.Children.Length > 0) { vObj.Node.Children[0].GetMaterial(iTex).Texture1 = loadedTex; } break; } } if (alphaimage) { vObj.Node.Children[0].SetMaterialType(MaterialType.TransparentAlphaChannel); Reference.SceneManager.RegisterNodeForRendering(vObj.Node.Children[0], SceneNodeRenderPass.Transparent); } } // Normal prim else { // Apply the Texture based on the TextureEntry if (vObj.Prim.Textures != null) { Reference.SceneManager.MeshCache.RemoveMesh(vObj.Mesh); // TODO: Apply texture per face (including DefaultTexture if a FaceTexture was not specified) for (int i = 0; i < vObj.Mesh.MeshBufferCount; i++) { float shinyval = 0; // Check if there is a facetexture for this MB Primitive.TextureEntryFace applyTexture = null; if (i < vObj.Prim.Textures.FaceTextures.Length && vObj.Prim.Textures.FaceTextures[i] != null) { // Apply FaceTexture applyTexture = vObj.Prim.Textures.FaceTextures[i]; } else if (vObj.Prim.Textures.DefaultTexture != null) { // Apply DefaultTexture applyTexture = vObj.Prim.Textures.DefaultTexture; } if (applyTexture != null) { Color4 coldata = applyTexture.RGBA; switch (applyTexture.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } if (applyTexture.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, applyTexture, tex, i, shinyval, coldata); } else { // Apply color settings ApplyFaceSettings(vObj, alphaimage, applyTexture, null, i, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(i).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(i).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(i).Material.BackfaceCulling = (texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } } if (vObj.Node is MeshSceneNode) { MeshSceneNode msn = (MeshSceneNode) vObj.Node; msn.SetMesh(vObj.Mesh); /* if (vObj.Prim.Textures != null) { // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; IrrlichtNETCP.Color objColor = new Color( Util.Clamp<int>((int) (coldata.A*255), 0, 255), Util.Clamp<int>((int) (coldata.R*255), 0, 255), Util.Clamp<int>((int) (coldata.G*255), 0, 255), Util.Clamp<int>((int) (coldata.B*255), 0, 255) ); // Set material color. for (int i = 0; i < msn.MaterialCount; i++) { msn.GetMaterial(i).AmbientColor = objColor; msn.GetMaterial(i).DiffuseColor = objColor; msn.GetMaterial(i).SpecularColor = Color.Black; msn.GetMaterial(i).EmissiveColor = Color.Black; msn.GetMaterial(i).Shininess = 0; } } } */ Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < msn.GetMesh().MeshBufferCount; i++) { msn.GetMesh().GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(msn.GetMesh().GetMeshBuffer(i).BoundingBox); } msn.GetMesh().BoundingBox = box; } else { // Swap out the visible untextured object with a textured one. // SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, ParentNode, -1); // ZAKI: Change TextureManager Parent to actual parent node SceneNode sn = Reference.SceneManager.AddMeshSceneNode(vObj.Mesh, vObj.Node.Parent, -1); sn.Position = vObj.Node.Position; sn.Rotation = vObj.Node.Rotation; sn.Scale = vObj.Node.Scale; sn.DebugDataVisible = DebugSceneType.Off; // If it's translucent, register it for the Transparent phase of rendering if (vObj.Prim.Textures.DefaultTexture != null) { if (vObj.Prim.Textures.DefaultTexture.RGBA.A != 1) { Reference.SceneManager.RegisterNodeForRendering(sn, SceneNodeRenderPass.Transparent); } } // Add the new triangle selector sn.TriangleSelector = Reference.SceneManager.CreateTriangleSelector(vObj.Mesh, sn); sn.TriangleSelector.Drop(); Reference.Viewer.EntityManager.AddTriangleSelector(sn.TriangleSelector, sn); // Delete the old node. SceneNode oldnode = vObj.Node; Reference.Viewer.EntityManager.DeleteNode(oldnode); // Assign new node vObj.Node = sn; } } } // prim texture is not null } catch (AccessViolationException) { VUtil.LogConsole(this.ToString() + "[ACCESSVIOLATION]", " TextureManager::ApplyTexture"); m_log.Error("[TEXTURE]: Failed to load texture."); } catch (NullReferenceException) { m_log.Error("unable to update texture"); } }
/// <summary> /// Bread and butter of the texture system. /// This is the start point for the texture-> graphics pipeline /// </summary> /// <param name="tex"></param> /// <param name="vObj"></param> /// <param name="AssetID"></param> public void applyTexture(TextureExtended tex, VObject vObj, UUID AssetID) { //return; try { // works if (vObj.Mesh == null) return; // Check if we have a sculptie and its sculpting texture // If yes, don't apply the texture if (vObj.Prim.Sculpt != null && vObj.Prim.Sculpt.SculptTexture == AssetID) { m_log.Debug("[TEXTURE]: Skipping applyTexture for sculpt " + AssetID); return; } bool alphaimage = false; #if YK_ADD_DEFAULT_TEXTURE if (tex == null) tex = defaultTexture; #endif // Check if we've already run this through our image alpha checker if (tex.Userdata == null) { // Check if this image has an alpha channel in use // All textures are 32 Bit and alpha capable, so we have to scan it for an // alpha pixel Color[,] imgcolors; //tex.Lock(); try { imgcolors = tex.Retrieve(); //tex.Unlock(); for (int i = 0; i < imgcolors.GetUpperBound(0); i++) { for (int j = 0; j < imgcolors.GetUpperBound(1); j++) { if (imgcolors[i, j].A != 255) { alphaimage = true; break; } } if (alphaimage) break; } } catch (OutOfMemoryException) { alphaimage = false; } // Save result tex.Userdata = (object)alphaimage; } else { // Use cached result alphaimage = (bool)tex.Userdata; } //#if NOTYET if (vObj._3DiIrrfileUUID != UUID.Zero && vObj.IrrData != null) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: 3Di mesh applyTexture for tex " + AssetID + " for irrfile " + vObj._3DiIrrfileUUID); #endif for (int iTex = 0; iTex < vObj.IrrData.Materials.Count; iTex++) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: This mesh references a texture num " + iTex + ": " + vObj.IrrData.Materials[iTex].Texture1); #endif if (System.IO.Path.GetFileNameWithoutExtension(vObj.IrrData.Materials[iTex].Texture1) == AssetID.ToString()) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Found the texture reference inside the mesh; loading texture and re-assigning the reference."); #endif Texture loadedTex = device.VideoDriver.GetTexture(AssetID.ToString() + tex.extension); if (vObj.Node.Children.Length > 0) { vObj.Node.Children[0].GetMaterial(iTex).Texture1 = loadedTex; } else { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Could not assign texture; mesh child not found"); #endif } } } #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Finished all materials in this mesh."); #endif if (alphaimage) { vObj.Node.Children[0].SetMaterialType(MaterialType.TransparentAlphaChannel); device.SceneManager.RegisterNodeForRendering(vObj.Node.Children[0], SceneNodeRenderPass.Transparent); } } else //#endif // Apply the Texture based on the TextureEntry if(vObj.Prim.Textures != null) { device.SceneManager.MeshCache.RemoveMesh(vObj.Mesh); // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; float shinyval = 0; switch (vObj.Prim.Textures.DefaultTexture.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } // The mesh buffers correspond to the faces defined in the textureentry int mbcount = vObj.Mesh.MeshBufferCount; for (int j = 0; j < mbcount; j++) { // Only apply default texture if there isn't one already! // we don't want to overwrite a face specific texture with the default if (vObj.Prim.Textures.DefaultTexture.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, vObj.Prim.Textures.DefaultTexture, tex, j, shinyval, coldata); } else { // Apply color settings ApplyFaceSettings(vObj, alphaimage, vObj.Prim.Textures.DefaultTexture, null, j, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(j).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(j).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(j).Material.BackfaceCulling = (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } } // default taken care of.. now on to the individual face settings. for (int i = 0; i < vObj.Prim.Textures.FaceTextures.Length; i++) { if (vObj.Prim.Textures.FaceTextures[i] != null) { Primitive.TextureEntryFace teface = vObj.Prim.Textures.FaceTextures[i]; if (vObj.Mesh.MeshBufferCount > i) { //if (tex. Color4 coldata = teface.RGBA; float shinyval = 0; switch (teface.Shiny) { case Shininess.Low: shinyval = 0.8f; coldata.R *= 0.8f; coldata.B *= 0.8f; coldata.G *= 0.8f; break; case Shininess.Medium: shinyval = 0.7f; coldata.R *= 0.6f; coldata.B *= 0.6f; coldata.G *= 0.6f; break; case Shininess.High: shinyval = 0.6f; coldata.R *= 0.3f; coldata.B *= 0.3f; coldata.G *= 0.3f; break; } // Apply texture only if this face has it linked if (teface.TextureID == AssetID) { ApplyFaceSettings(vObj, alphaimage, teface, tex, i, shinyval, coldata); } else { // Only apply the color settings.. ApplyFaceSettings(vObj, alphaimage, teface, null, i, shinyval, coldata); } vObj.Mesh.GetMeshBuffer(i).Material.NormalizeNormals = true; vObj.Mesh.GetMeshBuffer(i).Material.GouraudShading = true; vObj.Mesh.GetMeshBuffer(i).Material.BackfaceCulling = (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_ASSETSERVER); } else { m_log.Warn("[TEXTUREDEF]: Unable to apply Texture to face because mesh buffer doesn't have definition for face"); } }// end check if textureentry face is null } // end loop over textureentry faces array if (vObj.Node is MeshSceneNode) { MeshSceneNode msn = (MeshSceneNode)vObj.Node; msn.SetMesh(vObj.Mesh); if (vObj.Prim.Textures != null) { // Check the default texture to ensure that it's not null (why would it be null?) if (vObj.Prim.Textures.DefaultTexture != null) { Color4 coldata = vObj.Prim.Textures.DefaultTexture.RGBA; IrrlichtNETCP.Color objColor = new Color( Util.Clamp<int>((int)(coldata.A * 255), 0, 255), Util.Clamp<int>((int)(coldata.R * 255), 0, 255), Util.Clamp<int>((int)(coldata.G * 255), 0, 255), Util.Clamp<int>((int)(coldata.B * 255), 0, 255) ); // Set material color. for (int i = 0; i < msn.MaterialCount; i++) { #if MATERIAL_DEBUG lock(NativeElement.Elements) {System.Diagnostics.Debug.WriteLine("Element count before get:" + NativeElement.Elements.Count);} #endif msn.GetMaterial(i).AmbientColor = objColor; #if MATERIAL_DEBUG lock (NativeElement.Elements) { System.Diagnostics.Debug.WriteLine("Element count after get:" + NativeElement.Elements.Count); } #endif msn.GetMaterial(i).DiffuseColor = objColor; msn.GetMaterial(i).SpecularColor = Color.Black; msn.GetMaterial(i).EmissiveColor = Color.Black; msn.GetMaterial(i).Shininess = 0; } } } #if RECALC_BOUNDINGBOX Box3D box = new Box3D(0, 0, 0, 0, 0, 0); for (int i = 0; i < msn.GetMesh().MeshBufferCount; i++) { msn.GetMesh().GetMeshBuffer(i).RecalculateBoundingBox(); box.AddInternalBox(msn.GetMesh().GetMeshBuffer(i).BoundingBox); } msn.GetMesh().BoundingBox = box; #endif } else { // Swap out the visible untextured object with a textured one. // SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, ParentNode, -1); // ZAKI: Change TextureManager Parent to actual parent node SceneNode sn = device.SceneManager.AddMeshSceneNode(vObj.Mesh, vObj.Node.Parent, -1); sn.Position = vObj.Node.Position; sn.Rotation = vObj.Node.Rotation; sn.Scale = vObj.Node.Scale; sn.DebugDataVisible = DebugSceneType.Off; // If it's translucent, register it for the Transparent phase of rendering if (vObj.Prim.Textures.DefaultTexture.RGBA.A != 1) { device.SceneManager.RegisterNodeForRendering(sn, SceneNodeRenderPass.Transparent); } // Add the new triangle selector sn.TriangleSelector = device.SceneManager.CreateTriangleSelector(vObj.Mesh, sn); sn.TriangleSelector.Drop(); Reference.Viewer.EntityManager.AddTriangleSelector(sn.TriangleSelector, sn); // Delete the old node. SceneNode oldnode = vObj.Node; Reference.Viewer.EntityManager.DeleteNode(oldnode); // Assign new node vObj.Node = sn; } } // prim texture is not null } catch (AccessViolationException) { VUtil.LogConsole(this.ToString() + "[ACCESSVIOLATION]", " TextureManager::ApplyTexture"); m_log.Error("[TEXTURE]: Failed to load texture."); } catch (NullReferenceException) { m_log.Error("unable to update texture"); } }
/// <summary> /// Requests an image for an object. /// </summary> /// <param name="assetID"></param> /// <param name="requestor"></param> public void RequestImage(UUID assetID, VObject requestor) { TextureExtended tex = null; lock (memoryTextures) { if (memoryTextures.ContainsKey(assetID)) { tex = memoryTextures[assetID]; } } if (tex != null) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Already have texture in memory: " + assetID); #endif #if DebugTexturePipeline m_log.Debug("RequestImage 1 calling applyTexture"); #endif // We already have the texture, jump to applyTexture applyTexture(tex, requestor, assetID); // Apply the texture to all objects that are already waiting for this texture lock (ouststandingRequests) { if (ouststandingRequests.ContainsKey(assetID)) { m_log.Warn("[TEXTURE]: Applying texture from memory to outstanding requestors."); foreach (VObject vObj in ouststandingRequests[assetID]) { applyTexture(tex, vObj, assetID); } ouststandingRequests.Remove(assetID); } } return; } // Check to see if we've got the texture on disk string texturefolderpath = imagefolder; if (File.Exists(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga"))) { Texture texTnorm = driver.GetTexture(System.IO.Path.Combine(texturefolderpath, assetID.ToString() + ".tga")); if (texTnorm != null) tex = new TextureExtended(texTnorm.Raw, ".tga"); if (tex != null) { #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Already have texture locally on disk: " + assetID); #endif lock (memoryTextures) { if (!memoryTextures.ContainsKey(assetID)) { // Add it to the texture cache. memoryTextures.Add(assetID, tex); } } #if DebugTexturePipeline m_log.Debug("RequestImage 2 calling applyTexture"); #endif // apply texture applyTexture(tex, requestor, assetID); // Apply the texture to all objects that are already waiting for this texture lock (ouststandingRequests) { if (ouststandingRequests.ContainsKey(assetID)) { m_log.Warn("[TEXTURE]: Applying texture from memory to outstanding requestors."); foreach (VObject vObj in ouststandingRequests[assetID]) { applyTexture(tex, vObj, assetID); } ouststandingRequests.Remove(assetID); } } return; } } // Check if we've already got an outstanding request for this texture lock (ouststandingRequests) { if (ouststandingRequests.ContainsKey(assetID)) { // Add it to the objects to be notified when this texture download is complete. ouststandingRequests[assetID].Add(requestor); #if YK_ADD_DEFAULT_TEXTURE applyTexture(null, requestor, assetID); #endif return; } else { // Create a new outstanding request entry List<VObject> requestors = new List<VObject>(); requestors.Add(requestor); ouststandingRequests.Add(assetID,requestors); } } #if DebugTexturePipeline m_log.Debug("[3Di Mesh]: Requesting from libomv the following texture: " + assetID); #endif if (string.IsNullOrEmpty(m_user.m_user.Network.AssetServerUri)) { this.texDownloadStyle = TextureDownloadStyle.TEX_DOWNLOAD_LIBOMV; } TextureDownloadRequest req = new TextureDownloadRequest(); req.uuid = assetID; downloadTextureQueue.Enqueue(req); // no need to lock b/c it's a BlockingQueue which needs no synchronization m_log.Info("[TEXTURE]: Added to DownloadTextureQueue current count " + downloadTextureQueue.Count); /* if (this.texDownloadStyle == TextureDownloadStyle.TEX_DOWNLOAD_LIBOMV) { // Request texture from LibOMV m_user.RequestTexture(assetID); } else { // request texture directly from assetserver via our own background thread TextureDownloadRequest req = new TextureDownloadRequest(); req.uuid = assetID; downloadTextureQueue.Enqueue(req); // no need to lock b/c it's a BlockingQueue which needs no synchronization } */ }