Esempio n. 1
0
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim)
        {
            if ((PCode)prim.Shape.PCode != PCode.Prim)
            {
                return;
            }

            Vector3 ppos = prim.GetWorldPosition();

            if (ppos.Z < m_renderMinHeight || ppos.Z > m_renderMaxHeight)
            {
                return;
            }

            warp_Vector     primPos = ConvertVector(ppos);
            warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
            warp_Matrix     m       = warp_Matrix.quaternionMatrix(primRot);

            float screenFactor = renderer.Scene.EstimateBoxProjectedArea(primPos, ConvertVector(prim.Scale), m);

            if (screenFactor < 0)
            {
                return;
            }

            const float log2inv = -1.442695f;
            int         p2      = (int)((float)Math.Log(screenFactor) * log2inv * 0.25 - 1);

            if (p2 < 0)
            {
                p2 = 0;
            }
            else if (p2 > 3)
            {
                p2 = 3;
            }

            DetailLevel lod = (DetailLevel)(3 - p2);

            FacetedMesh renderMesh = null;
            Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);

            if (m_renderMeshes)
            {
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetchinng the asset
                    AssetBase sculptAsset = m_scene.AssetService.Get(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset.Data);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, lod, out renderMesh);
                            meshAsset = null;
                        }
                        else // It's sculptie
                        {
                            if (m_imgDecoder != null)
                            {
                                Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset.Data);
                                if (sculpt != null)
                                {
                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt, lod);
                                    sculpt.Dispose();
                                }
                            }
                        }
                    }
                    else
                    {
                        m_log.WarnFormat("[Warp3D] failed to get mesh or sculpt asset {0} of prim {1} at {2}",
                                         omvPrim.Sculpt.SculptTexture.ToString(), prim.Name, prim.GetWorldPosition().ToString());
                    }
                }
            }

            // If not a mesh or sculptie, try the regular mesher
            if (renderMesh == null)
            {
                renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, lod);
            }

            if (renderMesh == null)
            {
                return;
            }

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face   face     = renderMesh.Faces[i];
                string meshName = primID + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object();

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor = teFace.RGBA;
                if (faceColor.A == 0)
                {
                    continue;
                }

                string materialName = string.Empty;
                if (m_texturePrims)
                {
                    // if(lod > DetailLevel.Low)
                    {
                        // materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, lod == DetailLevel.Low);
                        materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID, false, prim);
                        if (String.IsNullOrEmpty(materialName))
                        {
                            continue;
                        }
                        int c = renderer.Scene.material(materialName).getColor();
                        if ((c & warp_Color.MASKALPHA) == 0)
                        {
                            continue;
                        }
                    }
                }
                else
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor);
                }

                if (renderer.Scene.material(materialName).getTexture() == null)
                {
                    // uv map details dont not matter for color;
                    for (int j = 0; j < face.Vertices.Count; j++)
                    {
                        Vertex      v    = face.Vertices[j];
                        warp_Vector pos  = ConvertVector(v.Position);
                        warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y);
                        faceObj.addVertex(vert);
                    }
                }
                else
                {
                    float tu;
                    float tv;
                    float offsetu  = teFace.OffsetU + 0.5f;
                    float offsetv  = teFace.OffsetV + 0.5f;
                    float scaleu   = teFace.RepeatU;
                    float scalev   = teFace.RepeatV;
                    float rotation = teFace.Rotation;
                    float rc       = 0;
                    float rs       = 0;
                    if (rotation != 0)
                    {
                        rc = (float)Math.Cos(rotation);
                        rs = (float)Math.Sin(rotation);
                    }

                    for (int j = 0; j < face.Vertices.Count; j++)
                    {
                        warp_Vertex vert;
                        Vertex      v   = face.Vertices[j];
                        warp_Vector pos = ConvertVector(v.Position);
                        if (teFace.TexMapType == MappingType.Planar)
                        {
                            UVPlanarMap(v, prim.Scale, out tu, out tv);
                        }
                        else
                        {
                            tu = v.TexCoord.X - 0.5f;
                            tv = 0.5f - v.TexCoord.Y;
                        }
                        if (rotation != 0)
                        {
                            float tur = tu * rc - tv * rs;
                            float tvr = tu * rs + tv * rc;
                            tur *= scaleu;
                            tur += offsetu;

                            tvr *= scalev;
                            tvr += offsetv;
                            vert = new warp_Vertex(pos, tur, tvr);
                        }
                        else
                        {
                            tu  *= scaleu;
                            tu  += offsetu;
                            tv  *= scalev;
                            tv  += offsetv;
                            vert = new warp_Vertex(pos, tu, tv);
                        }

                        faceObj.addVertex(vert);
                    }
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y);
                faceObj.transform(m);
                faceObj.setPos(primPos);

                renderer.Scene.addObject(meshName, faceObj);
                renderer.SetObjectMaterial(meshName, materialName);
            }
        }
Esempio n. 2
0
        private void CreatePrim(WarpRenderer renderer, SceneObjectPart prim,
                                bool useTextures)
        {
            const float MIN_SIZE_SQUARE = 4f;

            if ((PCode)prim.Shape.PCode != PCode.Prim)
            {
                return;
            }
            float primScaleLenSquared = prim.Scale.LengthSquared();

            if (primScaleLenSquared < MIN_SIZE_SQUARE)
            {
                return;
            }

            FacetedMesh renderMesh = null;
            Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.RotationOffset);

            if (m_renderMeshes)
            {
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetchinng the asset
                    byte[] sculptAsset = m_scene.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
                            meshAsset = null;
                        }
                        else // It's sculptie
                        {
                            IJ2KDecoder imgDecoder = m_scene.RequestModuleInterface <IJ2KDecoder>();
                            if (imgDecoder != null)
                            {
                                Image sculpt = imgDecoder.DecodeToImage(sculptAsset);
                                if (sculpt != null)
                                {
                                    renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
                                                                                        DetailLevel.Medium);
                                    sculpt.Dispose();
                                }
                            }
                        }
                    }
                }
            }

            // If not a mesh or sculptie, try the regular mesher
            if (renderMesh == null)
            {
                renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
            }

            if (renderMesh == null)
            {
                return;
            }

            string primID = prim.UUID.ToString();

            // Create the prim faces
            // TODO: Implement the useTextures flag behavior
            for (int i = 0; i < renderMesh.Faces.Count; i++)
            {
                Face   face     = renderMesh.Faces[i];
                string meshName = primID + i.ToString();

                // Avoid adding duplicate meshes to the scene
                if (renderer.Scene.objectData.ContainsKey(meshName))
                {
                    continue;
                }

                warp_Object faceObj = new warp_Object();
                for (int j = 0; j < face.Vertices.Count; j++)
                {
                    Vertex      v    = face.Vertices[j];
                    warp_Vector pos  = ConvertVector(v.Position);
                    warp_Vertex vert = new warp_Vertex(pos, v.TexCoord.X, v.TexCoord.Y);
                    faceObj.addVertex(vert);
                }

                for (int j = 0; j < face.Indices.Count; j += 3)
                {
                    faceObj.addTriangle(
                        face.Indices[j + 0],
                        face.Indices[j + 1],
                        face.Indices[j + 2]);
                }

                Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                Color4 faceColor    = GetFaceColor(teFace);
                string materialName = String.Empty;
                if (m_texturePrims && primScaleLenSquared > m_texturePrimSize * m_texturePrimSize)
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
                }
                else
                {
                    materialName = GetOrCreateMaterial(renderer, faceColor);
                }

                warp_Vector     primPos = ConvertVector(prim.GetWorldPosition());
                warp_Quaternion primRot = ConvertQuaternion(prim.GetWorldRotation());
                warp_Matrix     m       = warp_Matrix.quaternionMatrix(primRot);
                faceObj.transform(m);
                faceObj.setPos(primPos);
                faceObj.scaleSelf(prim.Scale.X, prim.Scale.Z, prim.Scale.Y);

                renderer.Scene.addObject(meshName, faceObj);
                renderer.SetObjectMaterial(meshName, materialName);
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Decodes mesh asset into FacetedMesh
        /// </summary>
        /// <param name="prim">Mesh primitive</param>
        /// <param name="meshAsset">Asset retrieved from the asset server</param>
        /// <param name="LOD">Level of detail</param>
        /// <param name="mesh">Resulting decoded FacetedMesh</param>
        /// <returns>True if mesh asset decoding was successful</returns>
        public static bool TryDecodeFromAsset(Primitive prim, AssetMesh meshAsset, DetailLevel LOD, out FacetedMesh mesh)
        {
            mesh = null;

            try
            {
                if (!meshAsset.Decode())
                {
                    return(false);
                }

                OSDMap MeshData = meshAsset.MeshData;

                mesh = new FacetedMesh();

                mesh.Faces             = new List <Face>();
                mesh.Prim              = prim;
                mesh.Profile.Faces     = new List <ProfileFace>();
                mesh.Profile.Positions = new List <Vector3>();
                mesh.Path.Points       = new List <PathPoint>();

                OSD facesOSD = null;

                switch (LOD)
                {
                default:
                case DetailLevel.Highest:
                    facesOSD = MeshData["high_lod"];
                    break;

                case DetailLevel.High:
                    facesOSD = MeshData["medium_lod"];
                    break;

                case DetailLevel.Medium:
                    facesOSD = MeshData["low_lod"];
                    break;

                case DetailLevel.Low:
                    facesOSD = MeshData["lowest_lod"];
                    break;
                }

                if (facesOSD == null || !(facesOSD is OSDArray))
                {
                    return(false);
                }

                OSDArray decodedMeshOsdArray = (OSDArray)facesOSD;

                for (int faceNr = 0; faceNr < decodedMeshOsdArray.Count; faceNr++)
                {
                    OSD subMeshOsd = decodedMeshOsdArray[faceNr];

                    // Decode each individual face
                    if (subMeshOsd is OSDMap)
                    {
                        Face oface = new Face();
                        oface.ID          = faceNr;
                        oface.Vertices    = new List <Vertex>();
                        oface.Indices     = new List <ushort>();
                        oface.TextureFace = prim.Textures.GetFace((uint)faceNr);

                        OSDMap subMeshMap = (OSDMap)subMeshOsd;

                        Vector3 posMax;
                        Vector3 posMin;

                        // If PositionDomain is not specified, the default is from -0.5 to 0.5
                        if (subMeshMap.ContainsKey("PositionDomain"))
                        {
                            posMax = ((OSDMap)subMeshMap["PositionDomain"])["Max"];
                            posMin = ((OSDMap)subMeshMap["PositionDomain"])["Min"];
                        }
                        else
                        {
                            posMax = new Vector3(0.5f, 0.5f, 0.5f);
                            posMin = new Vector3(-0.5f, -0.5f, -0.5f);
                        }

                        // Vertex positions
                        byte[] posBytes = subMeshMap["Position"];

                        // Normals
                        byte[] norBytes = null;
                        if (subMeshMap.ContainsKey("Normal"))
                        {
                            norBytes = subMeshMap["Normal"];
                        }

                        // UV texture map
                        Vector2 texPosMax = Vector2.Zero;
                        Vector2 texPosMin = Vector2.Zero;
                        byte[]  texBytes  = null;
                        if (subMeshMap.ContainsKey("TexCoord0"))
                        {
                            texBytes  = subMeshMap["TexCoord0"];
                            texPosMax = ((OSDMap)subMeshMap["TexCoord0Domain"])["Max"];
                            texPosMin = ((OSDMap)subMeshMap["TexCoord0Domain"])["Min"];
                        }

                        // Extract the vertex position data
                        // If present normals and texture coordinates too
                        for (int i = 0; i < posBytes.Length; i += 6)
                        {
                            ushort uX = Utils.BytesToUInt16(posBytes, i);
                            ushort uY = Utils.BytesToUInt16(posBytes, i + 2);
                            ushort uZ = Utils.BytesToUInt16(posBytes, i + 4);

                            Vertex vx = new Vertex();

                            vx.Position = new Vector3(
                                Utils.UInt16ToFloat(uX, posMin.X, posMax.X),
                                Utils.UInt16ToFloat(uY, posMin.Y, posMax.Y),
                                Utils.UInt16ToFloat(uZ, posMin.Z, posMax.Z));

                            if (norBytes != null && norBytes.Length >= i + 4)
                            {
                                ushort nX = Utils.BytesToUInt16(norBytes, i);
                                ushort nY = Utils.BytesToUInt16(norBytes, i + 2);
                                ushort nZ = Utils.BytesToUInt16(norBytes, i + 4);

                                vx.Normal = new Vector3(
                                    Utils.UInt16ToFloat(nX, posMin.X, posMax.X),
                                    Utils.UInt16ToFloat(nY, posMin.Y, posMax.Y),
                                    Utils.UInt16ToFloat(nZ, posMin.Z, posMax.Z));
                            }

                            var vertexIndexOffset = oface.Vertices.Count * 4;

                            if (texBytes != null && texBytes.Length >= vertexIndexOffset + 4)
                            {
                                ushort tX = Utils.BytesToUInt16(texBytes, vertexIndexOffset);
                                ushort tY = Utils.BytesToUInt16(texBytes, vertexIndexOffset + 2);

                                vx.TexCoord = new Vector2(
                                    Utils.UInt16ToFloat(tX, texPosMin.X, texPosMax.X),
                                    Utils.UInt16ToFloat(tY, texPosMin.Y, texPosMax.Y));
                            }

                            oface.Vertices.Add(vx);
                        }

                        byte[] triangleBytes = subMeshMap["TriangleList"];
                        for (int i = 0; i < triangleBytes.Length; i += 6)
                        {
                            ushort v1 = (ushort)(Utils.BytesToUInt16(triangleBytes, i));
                            oface.Indices.Add(v1);
                            ushort v2 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 2));
                            oface.Indices.Add(v2);
                            ushort v3 = (ushort)(Utils.BytesToUInt16(triangleBytes, i + 4));
                            oface.Indices.Add(v3);
                        }

                        mesh.Faces.Add(oface);
                    }
                }
            }
            catch (Exception ex)
            {
                Logger.Log("Failed to decode mesh asset: " + ex.Message, Helpers.LogLevel.Warning);
                return(false);
            }

            return(true);
        }
Esempio n. 4
0
 private void Asset_MeshCallback(bool success, AssetMesh assetMesh)
 {
     lock (Manager.AssetsReceived)
         Manager.AssetsReceived[assetMesh.AssetID] = success;
 }
        void CreatePrim(WarpRenderer renderer, ISceneChildEntity prim, bool texturePrims)
        {
            try {
                if ((PCode)prim.Shape.PCode != PCode.Prim)
                {
                    return;
                }
                if (prim.Scale.LengthSquared() < MIN_PRIM_SIZE * MIN_PRIM_SIZE)
                {
                    return;
                }

                Primitive   omvPrim    = prim.Shape.ToOmvPrimitive(prim.OffsetPosition, prim.GetRotationOffset());
                FacetedMesh renderMesh = null;

                // Are we dealing with a sculptie or mesh?
                if (omvPrim.Sculpt != null && omvPrim.Sculpt.SculptTexture != UUID.Zero)
                {
                    // Try fetching the asset
                    byte [] sculptAsset = m_scene.AssetService.GetData(omvPrim.Sculpt.SculptTexture.ToString());
                    if (sculptAsset != null)
                    {
                        // Is it a mesh?
                        if (omvPrim.Sculpt.Type == SculptType.Mesh)
                        {
                            AssetMesh meshAsset = new AssetMesh(omvPrim.Sculpt.SculptTexture, sculptAsset);
                            FacetedMesh.TryDecodeFromAsset(omvPrim, meshAsset, DetailLevel.Highest, out renderMesh);
                            meshAsset = null;
                        }
                        else   // It's sculptie
                        {
                            Image sculpt = m_imgDecoder.DecodeToImage(sculptAsset);
                            if (sculpt != null)
                            {
                                renderMesh = m_primMesher.GenerateFacetedSculptMesh(omvPrim, (Bitmap)sculpt,
                                                                                    DetailLevel.Medium);
                                sculpt.Dispose();
                            }
                        }
                        sculptAsset = null;
                    }
                    else
                    {
                        // missing sculpt data... replace with something
                        renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
                    }
                }
                else   // Prim
                {
                    renderMesh = m_primMesher.GenerateFacetedMesh(omvPrim, DetailLevel.Medium);
                }

                if (renderMesh == null)
                {
                    return;
                }

                warp_Vector     primPos = ConvertVector(prim.GetWorldPosition());
                warp_Quaternion primRot = ConvertQuaternion(prim.GetRotationOffset());

                warp_Matrix m = warp_Matrix.quaternionMatrix(primRot);

                if (prim.ParentID != 0)
                {
                    ISceneEntity group = m_scene.GetGroupByPrim(prim.LocalId);
                    if (group != null)
                    {
                        m.transform(warp_Matrix.quaternionMatrix(ConvertQuaternion(group.RootChild.GetRotationOffset())));
                    }
                }

                warp_Vector primScale = ConvertVector(prim.Scale);

                string primID = prim.UUID.ToString();

                // Create the prim faces
                for (int i = 0; i < renderMesh.Faces.Count; i++)
                {
                    Face   renderFace = renderMesh.Faces [i];
                    string meshName   = primID + "-Face-" + i;

                    warp_Object faceObj = new warp_Object(renderFace.Vertices.Count, renderFace.Indices.Count / 3);

                    foreach (Vertex v in renderFace.Vertices)
                    {
                        warp_Vector pos  = ConvertVector(v.Position);
                        warp_Vector norm = ConvertVector(v.Normal);

                        if (prim.Shape.SculptTexture == UUID.Zero)
                        {
                            norm = norm.reverse();
                        }
                        warp_Vertex vert = new warp_Vertex(pos, norm, v.TexCoord.X, v.TexCoord.Y);

                        faceObj.addVertex(vert);
                    }

                    for (int j = 0; j < renderFace.Indices.Count;)
                    {
                        faceObj.addTriangle(
                            renderFace.Indices [j++],
                            renderFace.Indices [j++],
                            renderFace.Indices [j++]);
                    }

                    Primitive.TextureEntryFace teFace = prim.Shape.Textures.GetFace((uint)i);
                    string materialName;
                    Color4 faceColor = GetFaceColor(teFace);

                    if (texturePrims && (prim.Scale.LengthSquared() > m_texturePrimSize))
                    {
                        materialName = GetOrCreateMaterial(renderer, faceColor, teFace.TextureID);
                    }
                    else
                    {
                        materialName = GetOrCreateMaterial(renderer, faceColor);
                    }

                    faceObj.transform(m);
                    faceObj.setPos(primPos);
                    faceObj.scaleSelf(primScale.x, primScale.y, primScale.z);

                    renderer.Scene.addObject(meshName, faceObj);

                    renderer.SetObjectMaterial(meshName, materialName);

                    faceObj = null;
                }
                renderMesh.Faces.Clear();
                renderMesh = null;
            } catch (Exception ex) {
                MainConsole.Instance.Warn("[WarpTile generator]: Exception creating prim, " + ex);
            }
        }