Пример #1
0
        FacetedMesh MeshPrim(Primitive prim)
        {
            FacetedMesh mesh = null;

            if (prim.Sculpt == null || prim.Sculpt.SculptTexture == UUID.Zero)
            {
                mesh = Mesher.GenerateFacetedMesh(prim, DetailLevel.Highest);
            }
            else if (prim.Sculpt.Type != SculptType.Mesh)
            {
                Image img = null;
                if (LoadTexture(prim.Sculpt.SculptTexture, ref img, true))
                {
                    mesh = Mesher.GenerateFacetedSculptMesh(prim, (Bitmap)img, DetailLevel.Highest);
                }
            }
            else
            {
                var gotMesh = new System.Threading.AutoResetEvent(false);

                Client.Assets.RequestMesh(prim.Sculpt.SculptTexture, (success, meshAsset) =>
                {
                    if (!success || !FacetedMesh.TryDecodeFromAsset(prim, meshAsset, DetailLevel.Highest, out mesh))
                    {
                        Logger.Log("Failed to fetch or decode the mesh asset", Helpers.LogLevel.Warning, Client);
                    }
                    gotMesh.Set();
                });

                gotMesh.WaitOne(20 * 1000, false);
            }
            return(mesh);
        }
Пример #2
0
    void Objects_OnObjectUpdate(object sender, PrimEventArgs e)
    {
        //leave tree out temporarily. Radegast doesn't implement tree rendering yet.
        if (e.Prim.PrimData.PCode != PCode.Prim)
        {
            Debug.Log("Receive " + e.Prim.PrimData.PCode.ToString());
            return;
        }
        FacetedMesh mesh = null;

        //FIXME : need to update prims?
        if (objects.ContainsKey(e.Prim.LocalID))
        {
            Debug.Log("receive prim with LocalID " + e.Prim.LocalID.ToString() + " again!");
            return;
        }

        if (e.Prim.Sculpt != null)
        {
            //leave sculpt prim out temporarily
        }
        else
        {
            mesh = R.GenerateFacetedMesh(e.Prim, DetailLevel.Highest);
            lock (newPrims)
            {
                newPrims[e.Prim.LocalID] = mesh;
            }
            foreach (Face face in mesh.Faces)
            {
                DownloadTexture(face.TextureFace.TextureID);
            }
        }
    }
Пример #3
0
        /// <summary>
        ///     Creates a faceted mesh from a primitive.
        /// </summary>
        /// <param name="Client">the client to use for meshing</param>
        /// <param name="primitive">the primitive to convert</param>
        /// <param name="mesher">the mesher to use</param>
        /// <param name="facetedMesh">a reference to an output facted mesh object</param>
        /// <param name="millisecondsTimeout">the services timeout</param>
        /// <returns>true if the mesh could be created successfully</returns>
        public static bool MakeFacetedMesh(GridClient Client, Primitive primitive, MeshmerizerR mesher,
                                           ref FacetedMesh facetedMesh,
                                           uint millisecondsTimeout)
        {
            if (primitive.Sculpt == null || primitive.Sculpt.SculptTexture.Equals(UUID.Zero))
            {
                facetedMesh = mesher.GenerateFacetedMesh(primitive, DetailLevel.Highest);
                return(true);
            }
            if (!primitive.Sculpt.Type.Equals(SculptType.Mesh))
            {
                byte[] assetData = null;
                switch (!Client.Assets.Cache.HasAsset(primitive.Sculpt.SculptTexture))
                {
                case true:
                    Locks.ClientInstanceAssetsLock.EnterReadLock();
                    var ImageDownloadedEvent = new ManualResetEventSlim(false);
                    Client.Assets.RequestImage(primitive.Sculpt.SculptTexture, (state, args) =>
                    {
                        if (!state.Equals(TextureRequestState.Finished))
                        {
                            return;
                        }
                        assetData = args.AssetData;
                        ImageDownloadedEvent.Set();
                    });
                    if (!ImageDownloadedEvent.Wait((int)millisecondsTimeout))
                    {
                        Locks.ClientInstanceAssetsLock.ExitReadLock();
                        return(false);
                    }
                    Locks.ClientInstanceAssetsLock.ExitReadLock();
                    break;

                default:
                    assetData = Client.Assets.Cache.GetCachedAssetBytes(primitive.Sculpt.SculptTexture);
                    break;
                }
                Image        image;
                ManagedImage managedImage;
                switch (!OpenJPEG.DecodeToImage(assetData, out managedImage))
                {
                case true:
                    return(false);

                default:
                    if ((managedImage.Channels & ManagedImage.ImageChannels.Alpha) != 0)
                    {
                        managedImage.ConvertChannels(managedImage.Channels & ~ManagedImage.ImageChannels.Alpha);
                    }
                    image = LoadTGAClass.LoadTGA(new MemoryStream(managedImage.ExportTGA()));
                    break;
                }
                facetedMesh = mesher.GenerateFacetedSculptMesh(primitive, (Bitmap)image, DetailLevel.Highest);
                return(true);
            }
            FacetedMesh localFacetedMesh    = null;
            var         MeshDownloadedEvent = new ManualResetEventSlim(false);

            Locks.ClientInstanceAssetsLock.EnterReadLock();
            Client.Assets.RequestMesh(primitive.Sculpt.SculptTexture, (success, meshAsset) =>
            {
                FacetedMesh.TryDecodeFromAsset(primitive, meshAsset, DetailLevel.Highest, out localFacetedMesh);
                MeshDownloadedEvent.Set();
            });

            if (!MeshDownloadedEvent.Wait((int)millisecondsTimeout))
            {
                Locks.ClientInstanceAssetsLock.ExitReadLock();
                return(false);
            }
            Locks.ClientInstanceAssetsLock.ExitReadLock();

            switch (localFacetedMesh != null)
            {
            case true:
                facetedMesh = localFacetedMesh;
                return(true);

            default:
                return(false);
            }
        }
Пример #4
0
        private void UpdatePrimBlocking(Primitive prim)
        {
            FacetedMesh mesh         = null;
            FacetedMesh existingMesh = null;

            lock (Prims)
            {
                if (Prims.ContainsKey(prim.LocalID))
                {
                    existingMesh = Prims[prim.LocalID];
                }
            }

            if (prim.Textures == null)
            {
                return;
            }

            try
            {
                if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero)
                {
                    if (prim.Sculpt.Type != SculptType.Mesh)
                    { // Regular sculptie
                        Image img = null;
                        if (!LoadTexture(prim.Sculpt.SculptTexture, ref img, true))
                        {
                            return;
                        }
                        mesh = renderer.GenerateFacetedSculptMesh(prim, (Bitmap)img, DetailLevel.Highest);
                    }
                    else
                    { // Mesh
                        AutoResetEvent gotMesh     = new AutoResetEvent(false);
                        bool           meshSuccess = false;

                        Client.Assets.RequestMesh(prim.Sculpt.SculptTexture, (success, meshAsset) =>
                        {
                            if (!success || !FacetedMesh.TryDecodeFromAsset(prim, meshAsset, DetailLevel.Highest, out mesh))
                            {
                                Logger.Log("Failed to fetch or decode the mesh asset", Helpers.LogLevel.Warning, Client);
                            }
                            else
                            {
                                meshSuccess = true;
                            }
                            gotMesh.Set();
                        });

                        if (!gotMesh.WaitOne(20 * 1000, false))
                        {
                            return;
                        }
                        if (!meshSuccess)
                        {
                            return;
                        }
                    }
                }
                else
                {
                    mesh = renderer.GenerateFacetedMesh(prim, DetailLevel.Highest);
                }
            }
            catch
            {
                return;
            }

            // Create a FaceData struct for each face that stores the 3D data
            // in a OpenGL friendly format
            for (int j = 0; j < mesh.Faces.Count; j++)
            {
                Face     face = mesh.Faces[j];
                FaceData data = new FaceData
                {
                    Vertices = new float[face.Vertices.Count * 3],
                    Normals  = new float[face.Vertices.Count * 3]
                };

                // Vertices for this face
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.Vertices[k * 3 + 0] = face.Vertices[k].Position.X;
                    data.Vertices[k * 3 + 1] = face.Vertices[k].Position.Y;
                    data.Vertices[k * 3 + 2] = face.Vertices[k].Position.Z;

                    data.Normals[k * 3 + 0] = face.Vertices[k].Normal.X;
                    data.Normals[k * 3 + 1] = face.Vertices[k].Normal.Y;
                    data.Normals[k * 3 + 2] = face.Vertices[k].Normal.Z;
                }

                // Indices for this face
                data.Indices = face.Indices.ToArray();

                // Texture transform for this face
                Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j);
                renderer.TransformTexCoords(face.Vertices, face.Center, teFace, prim.Scale);

                // Texcoords for this face
                data.TexCoords = new float[face.Vertices.Count * 2];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.TexCoords[k * 2 + 0] = face.Vertices[k].TexCoord.X;
                    data.TexCoords[k * 2 + 1] = face.Vertices[k].TexCoord.Y;
                }

                // Set the UserData for this face to our FaceData struct
                face.UserData = data;
                mesh.Faces[j] = face;


                if (existingMesh != null &&
                    j < existingMesh.Faces.Count &&
                    existingMesh.Faces[j].TextureFace.TextureID == teFace.TextureID &&
                    ((FaceData)existingMesh.Faces[j].UserData).TextureInfo.TexturePointer != 0
                    )
                {
                    FaceData existingData = (FaceData)existingMesh.Faces[j].UserData;
                    data.TextureInfo.TexturePointer = existingData.TextureInfo.TexturePointer;
                }
                else
                {
                    var textureItem = new TextureLoadItem()
                    {
                        Data   = data,
                        Prim   = prim,
                        TeFace = teFace
                    };

                    PendingTextures.Enqueue(textureItem);
                }
            }

            lock (Prims)
            {
                Prims[prim.LocalID] = mesh;
            }
            SafeInvalidate();
        }
        public PrimDisplayData ExtractPrimMesh(SceneObjectPart part, GroupLoader.LoaderParams parms, HashSet <UUID> fullPermTextures)
        {
            Primitive prim = part.Shape.ToOmvPrimitive(part.OffsetPosition, part.RotationOffset);

            //always generate at scale 1.0 and export the true scale for each part
            prim.Scale = new Vector3(1, 1, 1);

            FacetedMesh mesh;

            try
            {
                if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero)
                {
                    if (prim.Sculpt.Type != SculptType.Mesh)
                    { // Regular sculptie
                        Image img = null;
                        if (!LoadTexture(prim.Sculpt.SculptTexture, ref img, true))
                        {
                            return(null);
                        }

                        mesh = _renderer.GenerateFacetedSculptMesh(prim, (Bitmap)img, DetailLevel.Highest);
                        img.Dispose();
                    }
                    else
                    { // Mesh
                        var meshAsset = _stratus.RequestAssetSync(prim.Sculpt.SculptTexture);
                        if (!FacetedMesh.TryDecodeFromAsset(prim, new OpenMetaverse.Assets.AssetMesh(prim.Sculpt.SculptTexture, meshAsset.Data), DetailLevel.Highest, out mesh))
                        {
                            return(null);
                        }
                    }
                }
                else
                {
                    mesh = _renderer.GenerateFacetedMesh(prim, DetailLevel.Highest);
                }
            }
            catch
            {
                return(null);
            }

            // Create a FaceData struct for each face that stores the 3D data
            // in a OpenGL friendly format
            for (int j = 0; j < mesh.Faces.Count; j++)
            {
                Face face = mesh.Faces[j];
                PrimFace.FaceData data = new PrimFace.FaceData();

                // Vertices for this face
                data.Vertices = new float[face.Vertices.Count * 3];
                data.Normals  = new float[face.Vertices.Count * 3];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.Vertices[k * 3 + 0] = face.Vertices[k].Position.X;
                    data.Vertices[k * 3 + 1] = face.Vertices[k].Position.Y;
                    data.Vertices[k * 3 + 2] = face.Vertices[k].Position.Z;

                    data.Normals[k * 3 + 0] = face.Vertices[k].Normal.X;
                    data.Normals[k * 3 + 1] = face.Vertices[k].Normal.Y;
                    data.Normals[k * 3 + 2] = face.Vertices[k].Normal.Z;
                }

                // Indices for this face
                data.Indices = face.Indices.ToArray();

                // Texture transform for this face
                Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j);

                //not sure where this bug is coming from, but in order for sculpt textures
                //to line up, we need to flip V here
                if (prim.Sculpt != null && prim.Sculpt.Type != SculptType.None && prim.Sculpt.Type != SculptType.Mesh)
                {
                    teFace.RepeatV *= -1.0f;
                }

                _renderer.TransformTexCoords(face.Vertices, face.Center, teFace, prim.Scale);

                // Texcoords for this face
                data.TexCoords = new float[face.Vertices.Count * 2];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    data.TexCoords[k * 2 + 0] = face.Vertices[k].TexCoord.X;
                    data.TexCoords[k * 2 + 1] = face.Vertices[k].TexCoord.Y;
                }

                if (((parms.Checks & LoaderChecks.TexturesMustBeFullPerm) != 0))
                {
                    if (teFace.TextureID != UUID.Zero && !fullPermTextures.Contains(teFace.TextureID))
                    {
                        teFace.TextureID = UUID.Zero;
                    }
                }

                //store the actual texture
                data.TextureInfo = new PrimFace.TextureInfo {
                    TextureID = teFace.TextureID
                };

                // Set the UserData for this face to our FaceData struct
                face.UserData = data;
                mesh.Faces[j] = face;
            }


            var pos = part.IsRootPart() ? part.RawGroupPosition : part.OffsetPosition;

            return(new PrimDisplayData {
                Mesh = mesh, IsRootPrim = part.IsRootPart(),
                OffsetPosition = pos, OffsetRotation = part.RotationOffset,
                Scale = part.Scale,
                ShapeHash = _objectHasher.GetMeshShapeHash(part.Shape),
                MaterialHash = _objectHasher.GetMeshMaterialHash(prim),
                LinkNum = part.LinkNum
            });
        }