Example #1
0
        // I had a lot of trouble with problems with equality and GetHashCode of OMVR.Vertex
        //    so this implementation creates a proper hash for a Vertex so it can be used
        //    in a dictionary.
        public static BHash VertexBHash(OMVR.Vertex vert)
        {
            BHasher hasher = new BHasherMdjb2();

            MeshInfo.VertexBHash(vert, hasher);
            return(hasher.Finish());
        }
Example #2
0
        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);
        }
Example #3
0
        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);
        }
Example #4
0
 public static void OnAllVertex(MeshInfo mi, OperateOnVertex vertOp)
 {
     for (int jj = 0; jj < mi.vertexs.Count; jj++)
     {
         OMVR.Vertex aVert = mi.vertexs[jj];
         vertOp(ref aVert);
         mi.vertexs[jj] = aVert;
     }
 }
Example #5
0
        // 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);
        }
Example #6
0
 // Add the passed MeshInfo the to list if it is not already in the list
 public void AddUniqueMeshInfo(MeshInfo meshInfo)
 {
     lock (Meshes) {
         MeshInfo existingMeshInfo = null;
         if (!Meshes.TryGetValue(meshInfo.GetBHash(), out existingMeshInfo))
         {
             // If not already in the list, add this MeshInfo
             Meshes.Add(meshInfo.GetBHash(), meshInfo.handle, meshInfo);
         }
     }
 }
Example #7
0
 // Create a new MeshInfo with a copy of what is in another MeshInfo.
 // Note that we need to do a deep'ish copy since the values of the
 //     vertices may be modified in the copy.
 // OMVR.Vertex and OMV.Vextor3 are structs so they are copied.
 public MeshInfo(MeshInfo other)
 {
     handle  = new EntityHandleUUID();
     vertexs = other.vertexs.ConvertAll(v => {
         OMVR.Vertex newV = new OMVR.Vertex();
         newV.Position    = v.Position;
         newV.Normal      = v.Normal;
         newV.TexCoord    = v.TexCoord;
         return(newV);
     });
     // vertexs = new List<OMVR.Vertex>(other.vertexs);
     indices    = new List <int>(other.indices);
     scale      = new OMV.Vector3(other.scale);
     faceCenter = new OMV.Vector3(other.faceCenter);
 }
Example #8
0
        // Walk through all the vertices and scale the included meshes
        // Returns 'true' of the mesh was changed.
        public static bool ScaleMeshes(MeshInfo meshInfo, OMV.Vector3 scale)
        {
            bool ret = false;

            if (scale.X != 1.0 || scale.Y != 1.0 || scale.Z != 1.0)
            {
                ret = true;
                for (int ii = 0; ii < meshInfo.vertexs.Count; ii++)
                {
                    OMVR.Vertex aVert = meshInfo.vertexs[ii];
                    aVert.Position      *= scale;
                    meshInfo.vertexs[ii] = aVert;
                }
            }
            return(ret);
        }
Example #9
0
        private RenderableMesh ConvertFaceToRenderableMesh(OMVR.Face face, IAssetFetcher assetFetcher,
                                                           OMV.Primitive.TextureEntryFace defaultTexture, OMV.Vector3 primScale)
        {
            RenderableMesh rmesh = new RenderableMesh();

            rmesh.num = face.ID;

            // Copy one face's mesh imformation from the FacetedMesh into a MeshInfo
            MeshInfo meshInfo = new MeshInfo {
                vertexs    = new List <OMVR.Vertex>(face.Vertices),
                indices    = face.Indices.ConvertAll(ii => (int)ii),
                faceCenter = face.Center,
                scale      = primScale
            };

            BConverterOS.LogBProgress("{0} ConvertFaceToRenderableMesh: faceId={1}, numVert={2}, numInd={3}",
                                      _logHeader, face.ID, meshInfo.vertexs.Count, meshInfo.indices.Count);

            if (!ConvOAR.Globals.parms.P <bool>("DisplayTimeScaling"))
            {
                if (ScaleMeshes(meshInfo, primScale))
                {
                    BConverterOS.LogBProgress("{0} ConvertFaceToRenderableMesh: scaled mesh to {1}",
                                              _logHeader, primScale);
                }
                meshInfo.scale = OMV.Vector3.One;
            }

            // Find or create the MaterialInfo for this face.
            MaterialInfo matInfo = new MaterialInfo(face, defaultTexture);

            if (matInfo.textureID != null &&
                matInfo.textureID != OMV.UUID.Zero &&
                matInfo.textureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE)
            {
                // Textures/images use the UUID from OpenSim and the hash is just the hash of the UUID
                EntityHandleUUID textureHandle   = new EntityHandleUUID((OMV.UUID)matInfo.textureID);
                BHash            textureHash     = new BHashULong(textureHandle.GetUUID().GetHashCode());
                ImageInfo        lookupImageInfo = assetFetcher.GetImageInfo(textureHash, () => {
                    // The image is not in the cache yet so create an ImageInfo entry for it
                    // Note that image gets the same UUID as the OpenSim texture
                    ImageInfo imageInfo = new ImageInfo(textureHandle);
                    assetFetcher.FetchTextureAsImage(textureHandle)
                    .Then(img => {
                        imageInfo.SetImage(img);
                    })
                    .Catch(e => {
                        // Failure getting the image
                        ConvOAR.Globals.log.ErrorFormat("{0} Failure fetching texture. id={1}. {2}",
                                                        _logHeader, matInfo.textureID, e);
                        // Create a simple, single color image to fill in for the missing image
                        var fillInImage = new Bitmap(32, 32, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                        Color theColor  = Color.FromArgb(128, 202, 213, 170);       // 0x80CAB5AA
                        for (int xx = 0; xx < 32; xx++)
                        {
                            for (int yy = 0; yy < 32; yy++)
                            {
                                fillInImage.SetPixel(xx, yy, theColor);
                            }
                        }
                        imageInfo.SetImage(fillInImage);
                    });
                    imageInfo.imageIdentifier = (OMV.UUID)matInfo.textureID;
                    BConverterOS.LogBProgress("{0} ConvertFaceToRenderableMesh: create ImageInfo. hash={1}, id={2}",
                                              _logHeader, textureHash, imageInfo.handle);
                    return(imageInfo);
                });
                matInfo.image = lookupImageInfo;

                // Update the UV information for the texture mapping
                BConverterOS.LogBProgress("{0} ConvertFaceToRenderableMesh: Converting tex coords using {1} texture",
                                          _logHeader, face.TextureFace == null ? "default" : "face");
                _mesher.TransformTexCoords(meshInfo.vertexs, meshInfo.faceCenter,
                                           face.TextureFace == null ? defaultTexture : face.TextureFace, primScale);
            }

            // See that the material is in the cache
            MaterialInfo lookupMatInfo = assetFetcher.GetMaterialInfo(matInfo.GetBHash(), () => { return(matInfo); });

            rmesh.material = lookupMatInfo;

            // See that the mesh is in the cache
            MeshInfo lookupMeshInfo = assetFetcher.GetMeshInfo(meshInfo.GetBHash(true), () => { return(meshInfo); });

            rmesh.mesh = lookupMeshInfo;
            if (lookupMeshInfo.indices.Count == 0)      // DEBUG DEBUG
            {
                ConvOAR.Globals.log.ErrorFormat("{0} indices count of zero. rmesh={1}", _logHeader, rmesh.ToString());
            }   // DEBUG DEBUG

            BConverterOS.LogBProgress("{0} ConvertFaceToRenderableMesh: rmesh.mesh={1}, rmesh.material={2}",
                                      _logHeader, rmesh.mesh, rmesh.material);

            return(rmesh);
        }