public override int CompareTo(BHash other) { int ret = 1; if (other != null) { BHash bh = other as BHashBytes; if (bh != null) { byte[] otherb = bh.ToBytes(); if (_hash.Length != otherb.Length) { ret = _hash.Length.CompareTo(otherb.Length); } else { ret = 0; // start off assuming they are equal for (int ii = 0; ii < _hash.Length; ii++) { ret = _hash[ii].CompareTo(otherb[ii]); if (ret != 0) { break; } } } } } return(ret); }
public MeshInfo GetMeshInfo(BHash hash, MeshInfoBuilder builder) { MeshInfo meshInfo = null; lock (Meshes) { if (!Meshes.TryGetValue(hash, out meshInfo)) { if (builder != null) { meshInfo = builder(); Meshes.Add(hash, meshInfo.handle, meshInfo); // Assert the hash we're indexing it under is the one in meshInfo if (!hash.Equals(meshInfo.GetBHash())) { ConvOAR.Globals.log.ErrorFormat( "AssetFetcher.GetMeshInfo: adding mesh with different hash!"); ConvOAR.Globals.log.ErrorFormat( "AssetFetcher.GetMeshInfo: meshInfo.handle={0}, passed hash={1}, meshInfo.hash={2}", meshInfo.handle, hash.ToString(), meshInfo.GetBHash().ToString()); } } else { meshInfo = null; } } } return(meshInfo); }
public BHash GetBHash(bool force) { if (force) { _hash = null; } if (_hash == null) { BHasher hasher = new BHasherMdjb2(); vertexs.ForEach(vert => { MeshInfo.VertexBHash(vert, hasher); }); indices.ForEach(ind => { hasher.Add(ind); }); hasher.Add(faceCenter.X); hasher.Add(faceCenter.Y); hasher.Add(faceCenter.Z); hasher.Add(scale.X); hasher.Add(scale.Y); hasher.Add(scale.Z); _hash = hasher.Finish(); } return(_hash); }
public DisplayableRenderable GetRenderable(BHash hash, RenderableBuilder builder) { DisplayableRenderable renderable = null; lock (Renderables) { if (!Renderables.TryGetValue(hash, out renderable)) { try { if (builder != null) { renderable = builder(); } else { renderable = null; } } catch (Exception e) { ConvOAR.Globals.log.ErrorFormat("{0} GetRenderable: builder exception: {1}", _logHeader, e); } Renderables.Add(hash, renderable); } } return(renderable); }
// Create one or more Instances from this list of meshes. // There might be more than 2^15 vertices so, to keep the indices a ushort, might need // to break of the meshes. private List <BInstance> CreateInstancesFromSharedMaterialMeshes(BHash materialHash, List <InvertedMesh> meshes) { List <BInstance> ret = new List <BInstance>(); List <InvertedMesh> partial = new List <InvertedMesh>(); int totalVertices = 0; foreach (InvertedMesh imesh in meshes) { if (totalVertices + imesh.renderableMesh.mesh.vertexs.Count > 50000) { // if adding this mesh will push us over the max, create instances and start again ret.Add(CreateOneInstanceFromMeshes(materialHash, partial)); partial.Clear(); totalVertices = 0; } totalVertices += imesh.renderableMesh.mesh.vertexs.Count; partial.Add(imesh); } if (partial.Count > 0) { ret.Add(CreateOneInstanceFromMeshes(materialHash, partial)); } return(ret); }
// Find all the meshes in passed Displayable and add them to the lists indexed by their material // mesh hashes. private void MapMaterialsAndMeshes(BScene pBs, BInstance pInst, Displayable disp) { RenderableMeshGroup rmg = disp.renderable as RenderableMeshGroup; if (rmg != null) { foreach (RenderableMesh rMesh in rmg.meshes) { InvertedMesh imesh = new InvertedMesh(pBs, pInst, disp, rmg, rMesh); BHash meshHash = rMesh.mesh.GetBHash(); if (!sharedMeshes.ContainsKey(meshHash)) { sharedMeshes.Add(meshHash, new List <InvertedMesh>()); } sharedMeshes[meshHash].Add(imesh); BHash materialHash = rMesh.material.GetBHash(); if (!meshByMaterial.ContainsKey(materialHash)) { meshByMaterial.Add(materialHash, new List <InvertedMesh>()); } meshByMaterial[materialHash].Add(imesh); } } foreach (Displayable child in disp.children) { MapMaterialsAndMeshes(pBs, pInst, child); } }
public BHash GetBHash(bool force) { if (force) { _hash = null; } if (_hash == null) { BHasher hasher = new BHasherMdjb2(); hasher.Add(RGBA.R); // Not using RGBA.GetHashCode() as it always returns the same value hasher.Add(RGBA.G); hasher.Add(RGBA.B); hasher.Add(RGBA.A); hasher.Add((int)bump); hasher.Add(glow); hasher.Add((int)shiny); if (textureID.HasValue) { hasher.Add(textureID.Value.GetHashCode()); } _hash = hasher.Finish(); // ConvOAR.Globals.log.DebugFormat("MaterialInfo.GetBHash: rgba={0},bump={1},glow={2},shiny={3},tex={4},hash={5}", // RGBA, bump, glow, shiny, textureID.HasValue ? textureID.Value.ToString() : "none", _hash.ToString()); } return(_hash); }
// Given a list of meshes, combine them into one mesh and return a containing BInstance. private BInstance CreateOneInstanceFromMeshes(BHash materialHash, List <InvertedMesh> meshes) { // Pick one of the meshes to be the 'root' mesh. // Someday may need to find the most center mesh to work from. InvertedMesh rootIMesh = meshes.First(); // The new instance will be at the location of the root mesh with no rotation BInstance inst = new BInstance(); inst.Position = rootIMesh.containingInstance.Position; inst.Rotation = OMV.Quaternion.Identity; inst.coordAxis = rootIMesh.containingInstance.coordAxis; try { // The mesh we're going to build MeshInfo meshInfo = new MeshInfo(); foreach (InvertedMesh imesh in meshes) { int indicesBase = meshInfo.vertexs.Count; // Go through the mesh, map all vertices to global coordinates then convert relative to root meshInfo.vertexs.AddRange(imesh.renderableMesh.mesh.vertexs.Select(vert => { OMVR.Vertex newVert = new OMVR.Vertex(); OMV.Vector3 worldPos = vert.Position; worldPos = worldPos * imesh.containingDisplayable.offsetRotation + imesh.containingDisplayable.offsetPosition; worldPos = worldPos * imesh.containingInstance.Rotation + imesh.containingInstance.Position; // Make new vert relative to the BInstance it's being added to newVert.Position = worldPos - inst.Position; newVert.Normal = vert.Normal * imesh.containingDisplayable.offsetRotation * imesh.containingInstance.Rotation; newVert.TexCoord = vert.TexCoord; return(newVert); })); meshInfo.indices.AddRange(imesh.renderableMesh.mesh.indices.Select(ind => ind + indicesBase)); } RenderableMesh newMesh = new RenderableMesh(); newMesh.num = 0; newMesh.material = rootIMesh.renderableMesh.material; // The material we share newMesh.mesh = meshInfo; RenderableMeshGroup meshGroup = new RenderableMeshGroup(); meshGroup.meshes.Add(newMesh); Displayable displayable = new Displayable(meshGroup); displayable.name = "combinedMaterialMeshes-" + materialHash.ToString(); inst.Representation = displayable; } catch (Exception e) { ConvOAR.Globals.log.ErrorFormat("{0} CreateInstanceFromSharedMaterialMeshes: exception: {1}", _logHeader, e); } return(inst); }
public override int CompareTo(BHash other) { int ret = 1; if (other != null) { if (other is BHashULong bh) { ret = _hash.CompareTo(bh.ToULong()); } } return(ret); }
private Promise <DisplayableRenderable> MeshFromPrimShapeData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { return(new Promise <DisplayableRenderable>((resolve, reject) => { OMVR.FacetedMesh mesh = _mesher.GenerateFacetedMesh(prim, lod); DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, mesh, prim.Textures.DefaultTexture, prim.Scale); BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); BConverterOS.LogBProgress("{0} MeshFromPrimShapeData. numGenedMeshed={1}", _logHeader, ((RenderableMeshGroup)realDR).meshes.Count); resolve(realDR); })); }
public void RemoveMeshesFromShared(List <InvertedMesh> meshList) { // Remove these meshes from the ones that are shared by material foreach (InvertedMesh imesh in meshList) { BHash shapeHash = imesh.renderableMesh.mesh.GetBHash(); if (!sharedMeshes[shapeHash].Remove(imesh)) { ConvOAR.Globals.log.DebugFormat("{0} RemoveMeshesFromShared: couldn't remove imesh. shapeHash={1}", _logHeader, shapeHash); } } }
// Adds this Displayable if it's not already in the list. // Return 'true' if the Displayable was added to the list. public bool AddUniqueDisplayable(Displayable disp) { bool ret = false; Displayable maybeDisp; BHash dispHash = disp.GetBHash(); lock (Displayables) { if (!Displayables.TryGetValue(dispHash, out maybeDisp)) { Displayables.Add(dispHash, disp); } } return(ret); }
public override bool Equals(BHash other) { bool ret = false; if (other != null) { BHash bh = other as BHashBytes; if (bh != null) { ret = _hash.Equals(bh.ToBytes()); } } return(ret); }
public ImageInfo GetImageInfo(BHash hash, ImageInfoBuilder builder) { ImageInfo imageInfo = null; lock (Images) { if (!Images.TryGetValue(hash, out imageInfo)) { if (builder != null) { imageInfo = builder(); Images.Add(hash, imageInfo.handle, imageInfo); } else { imageInfo = null; } } } return(imageInfo); }
public MaterialInfo GetMaterialInfo(BHash hash, MaterialInfoBuilder builder) { MaterialInfo matInfo = null; lock (Materials) { if (!Materials.TryGetValue(hash, out matInfo)) { if (builder != null) { matInfo = builder(); Materials.Add(hash, matInfo.handle, matInfo); } else { matInfo = null; } } } return(matInfo); }
private Promise <DisplayableRenderable> MeshFromPrimSculptData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { return(new Promise <DisplayableRenderable>((resolve, reject) => { // Get the asset that the sculpty is built on EntityHandleUUID texHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture); assetFetcher.FetchTexture(texHandle) .Then((bm) => { OMVR.FacetedMesh fMesh = _mesher.GenerateFacetedSculptMesh(prim, bm.Image.ExportBitmap(), lod); DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale); BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); BConverterOS.LogBProgress("{0} MeshFromPrimSculptData. numFaces={1}, numGenedMeshed={2}", _logHeader, fMesh.Faces.Count, ((RenderableMeshGroup)realDR).meshes.Count); resolve(realDR); }, (e) => { ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimSculptData: Rejected FetchTexture: {1}: {2}", _logHeader, texHandle, e); reject(null); }); })); }
private Promise <DisplayableRenderable> MeshFromPrimMeshData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { EntityHandleUUID meshHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture); return(new Promise <DisplayableRenderable>((resolve, reject) => { assetFetcher.FetchRawAsset(meshHandle) .Then(meshBytes => { // OMVA.AssetMesh meshAsset = new OMVA.AssetMesh(prim.ID, meshBytes); // if (OMVR.FacetedMesh.TryDecodeFromAsset(prim, meshAsset, lod, out fMesh)) { OMVR.FacetedMesh fMesh = null; try { fMesh = _mesher.GenerateFacetedMeshMesh(prim, meshBytes); } catch (Exception e) { ConvOAR.Globals.log.ErrorFormat("{0} Exception in GenerateFacetedMeshMesh: {1}", _logHeader, e); } if (fMesh != null) { DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale); // Don't know the hash of the DisplayableRenderable until after it has been created. // Now use the hash to see if this has already been done. // If this DisplayableRenderable has already been built, use the other one and throw this away. BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); resolve(realDR); } else { reject(new Exception("MeshFromPrimMeshData: could not decode mesh information from asset. ID=" + prim.ID.ToString())); } }, e => { ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimMeshData: exception: {1}", _logHeader, e); reject(e); }); })); }
public bool GetDisplayable(BHash hash, out Displayable disp) { return(Displayables.TryGetValue(hash, out disp)); }
// Short form that just returns 'null' if not found. public ImageInfo GetImageInfo(BHash hash) { return(GetImageInfo(hash, null)); }
// Short form that just returns 'null' if not found. public MaterialInfo GetMaterialInfo(BHash hash) { return(GetMaterialInfo(hash, null)); }
// Short form that just returns 'null' if not found. public MeshInfo GetMeshInfo(BHash hash) { return(GetMeshInfo(hash, null)); }
// Short form that just returns 'null' if not found. public DisplayableRenderable GetRenderable(BHash hash) { return(GetRenderable(hash, null)); }
public abstract void Add(BHash c);
public override void Add(BHash c) { byte[] bytes = c.ToBytes(); AddBytes(bytes, 0, bytes.Length); }