/// <summary>
        /// Create the animation. The passed animation block is expected
        /// to contain a defintion of a fixed rotation. If not, bad things will happen.
        /// </summary>
        /// <param name="anim">The IAnimation block with the info.</param>
        /// <param name="id">localID to lookup the prim in the RegionRenderInfo.renderPrimList</param>
        public AnimatPosition(OMV.Vector3 newPos, float durationSeconds, RegionRenderInfo rri, uint id)
            : base(AnimatBase.AnimatTypePosition)
        {
            m_infoID = id;
            RenderablePrim rp = rri.renderPrimList[id];

            m_origionalPosition = rp.Position;
            m_targetPosition    = newPos;
            m_durationSeconds   = durationSeconds;
            m_distanceVector    = m_targetPosition - m_origionalPosition;
            m_progress          = 0f;
        }
 private void ComputeVisibility(RegionContextBase rcontext, RegionRenderInfo rri)
 {
     m_renderer.Camera.ComputeFrustum();
     lock (rri.renderPrimList) {
         foreach (uint ind in rri.renderPrimList.Keys)
         {
             RenderablePrim rp = rri.renderPrimList[ind];
             rp.isVisible = m_renderer.Camera.isVisible(rp.Position.X, rp.Position.Y, rp.Position.Z, 10f);
         }
     }
     return;
 }
        /// <summary>
        /// Called for each frame. Advance the position.
        /// </summary>
        /// <param name="timeSinceLastFrame">seconds since last frame display</param>
        /// <param name="rri">RegionRenderInfo for region the animation is in</param>
        /// <returns>true to say we never exit</returns>
        public override bool Process(float timeSinceLastFrame, RegionRenderInfo rri)
        {
            bool  ret          = true;
            float thisProgress = timeSinceLastFrame / m_durationSeconds;

            m_progress += thisProgress;
            RenderablePrim rp = rri.renderPrimList[m_infoID];

            if (m_progress >= 1f)
            {
                // if progressed all the way, we're at the destination
                rp.Position = m_targetPosition;
                ret         = false; // we're done animating
            }
            else
            {
                // only part way there
                rp.Position = m_origionalPosition + m_distanceVector * m_progress;
            }
            return(ret);
        }
        /// <summary>
        /// Called for each frame. Advance the rotation.
        /// </summary>
        /// <param name="timeSinceLastFrame">seconds since last frame display</param>
        /// <param name="rri">RegionRenderInfo for region the animation is in</param>
        /// <returns>true to say we never exit</returns>
        public override bool Process(float timeSinceLastFrame, RegionRenderInfo rri)
        {
            float nextStep      = m_rotationsPerSecond * timeSinceLastFrame;
            float nextIncrement = Constants.TWOPI * nextStep;

            while (nextIncrement > Constants.TWOPI)
            {
                nextIncrement -= Constants.TWOPI;
            }
            OMV.Quaternion newRotation = OMV.Quaternion.CreateFromAxisAngle(m_rotationAxis, nextIncrement);
            lock (rri) {
                try {
                    RenderablePrim rp = rri.renderPrimList[m_infoID];
                    rp.Rotation = newRotation * rp.Rotation;
                }
                catch (Exception e) {
                    LogManager.Log.Log(LogLevel.DBADERROR, "Did not find prim for FixedRotation: {0}", e);
                }
            }
            return(true);        // we never exit
        }
        //int[] CubeMapDefines = new int[]
        //{
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
        //    Gl.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB
        //};

        private void RenderPrims(RegionContextBase rcontext, RegionRenderInfo rri)
        {
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Texture2D);

            lock (rri.renderPrimList) {
                bool firstPass = true;
                // GL.Disable(EnableCap.Blend);
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                GL.Enable(EnableCap.DepthTest);

                GL.Enable(EnableCap.Normalize);

                GL.EnableClientState(ArrayCap.TextureCoordArray);
                GL.EnableClientState(ArrayCap.VertexArray);
                GL.EnableClientState(ArrayCap.NormalArray);


StartRender:

                List <RenderablePrim> rpList = new List <RenderablePrim>(rri.renderPrimList.Values);
                // sort back to front
                rpList.Sort(delegate(RenderablePrim rp1, RenderablePrim rp2) {
                    return((int)(((OMV.Vector3.Distance(m_renderer.Camera.Position, rp1.Prim.Position)) -
                                  (OMV.Vector3.Distance(m_renderer.Camera.Position, rp2.Prim.Position))) * 100f));
                });
                foreach (RenderablePrim rp in rpList)
                {
                    // if this prim is not visible, just loop
                    if (!rp.isVisible)
                    {
                        continue;
                    }

                    RenderablePrim prp  = RenderablePrim.Empty;
                    OMV.Primitive  prim = rp.Prim;

                    if (prim.ParentID != 0)
                    {
                        // Get the parent reference
                        if (!rri.renderPrimList.TryGetValue(prim.ParentID, out prp))
                        {
                            // Can't render a child with no parent prim, skip it
                            continue;
                        }
                    }

                    GL.PushName(prim.LocalID);
                    GL.PushMatrix();

                    if (prim.ParentID != 0)
                    {
                        // Apply parent translation and rotation
                        GL.MultMatrix(Math3D.CreateTranslationMatrix(prp.Position));
                        GL.MultMatrix(Math3D.CreateRotationMatrix(prp.Rotation));
                    }

                    // Apply prim translation and rotation
                    GL.MultMatrix(Math3D.CreateTranslationMatrix(rp.Position));
                    // apply region offset for multiple regions
                    GL.MultMatrix(Math3D.CreateTranslationMatrix(CalcRegionOffset(rp.rcontext)));
                    GL.MultMatrix(Math3D.CreateRotationMatrix(rp.Rotation));

                    // Scale the prim
                    GL.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z);

                    // Draw the prim faces
                    for (int j = 0; j < rp.Mesh.Faces.Count; j++)
                    {
                        OMVR.Face  face      = rp.Mesh.Faces[j];
                        FaceData   data      = (FaceData)face.UserData;
                        OMV.Color4 color     = face.TextureFace.RGBA;
                        bool       alpha     = false;
                        int        textureID = 0;

                        if (color.A < 1.0f)
                        {
                            alpha = true;
                        }

                        TextureInfo info;
                        if (face.TextureFace.TextureID != OMV.UUID.Zero &&
                            face.TextureFace.TextureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE &&
                            m_renderer.Textures.TryGetValue(face.TextureFace.TextureID, out info))
                        {
                            if (info.Alpha)
                            {
                                alpha = true;
                            }

                            textureID = info.ID;
                            // if textureID has not been set, need to generate the mipmaps
                            if (textureID == 0)
                            {
                                GenerateMipMaps(rp.acontext, face.TextureFace.TextureID, out textureID);
                                info.ID = textureID;
                            }

                            // Enable texturing for this face
                            GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                        }
                        else
                        {
                            if (face.TextureFace.TextureID == OMV.Primitive.TextureEntry.WHITE_TEXTURE ||
                                face.TextureFace.TextureID == OMV.UUID.Zero)
                            {
                                GL.PolygonMode(MaterialFace.Front, PolygonMode.Fill);
                            }
                            else
                            {
                                GL.PolygonMode(MaterialFace.Front, PolygonMode.Line);
                            }
                        }

                        // if (firstPass && !alpha || !firstPass && alpha) {
                        // GL.Color4(color.R, color.G, color.B, color.A);
                        float[] matDiffuse = { color.R, color.G, color.B, color.A };
                        GL.Material(MaterialFace.FrontAndBack, MaterialParameter.Diffuse, matDiffuse);

                        // Bind the texture
                        if (textureID != 0)
                        {
                            GL.Enable(EnableCap.Texture2D);
                            GL.BindTexture(TextureTarget.Texture2D, textureID);
                        }
                        else
                        {
                            GL.Disable(EnableCap.Texture2D);
                        }

                        GL.TexCoordPointer(2, TexCoordPointerType.Float, 0, data.TexCoords);
                        GL.VertexPointer(3, VertexPointerType.Float, 0, data.Vertices);
                        GL.NormalPointer(NormalPointerType.Float, 0, data.Normals);
                        GL.DrawElements(BeginMode.Triangles, data.Indices.Length, DrawElementsType.UnsignedShort, data.Indices);
                        // }
                    }

                    GL.PopMatrix();
                    GL.PopName();
                }

                /*
                 * if (firstPass) {
                 *  firstPass = false;
                 *  GL.Enable(EnableCap.Blend);
                 *  GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                 *  // GL.Disable(EnableCap.DepthTest);
                 *
                 *  goto StartRender;
                 * }
                 */
            }

            GL.Enable(EnableCap.DepthTest);
            GL.Disable(EnableCap.Texture2D);
        }
Example #6
0
        public void RenderUpdate(IEntity ent, UpdateCodes what)
        {
            m_log.Log(LogLevel.DRENDERDETAIL, "RenderUpdate: {0} for {1}", ent.Name.Name, what);
            bool fullUpdate = false;

            lock (ent) {
                if (ent is LLEntityBase && ((what & UpdateCodes.New) != 0))
                {
                    CreateNewPrim((LLEntityBase)ent);
                    fullUpdate = true;
                }
                if ((what & UpdateCodes.Animation) != 0)
                {
                    // the prim has changed its rotation animation
                    IAnimation anim;
                    if (ent.TryGet <IAnimation>(out anim))
                    {
                        m_log.Log(LogLevel.DRENDERDETAIL, "RenderUpdate: animation ");
                        RegionRenderInfo rri;
                        if (ent.RegionContext.TryGet <RegionRenderInfo>(out rri))
                        {
                            lock (rri) {
                                rri.animations.Add(AnimatBase.CreateAnimation(anim, ((LLEntityBase)ent).Prim.LocalID));
                            }
                        }
                    }
                }
                if ((what & UpdateCodes.Text) != 0)
                {
                    // text associated with the prim changed
                    m_log.Log(LogLevel.DRENDERDETAIL, "RenderUpdate: text changed");
                }
                if ((what & UpdateCodes.Particles) != 0)
                {
                    // particles associated with the prim changed
                    m_log.Log(LogLevel.DRENDERDETAIL, "RenderUpdate: particles changed");
                }
                if (!fullUpdate && (what & (UpdateCodes.Scale | UpdateCodes.Position | UpdateCodes.Rotation)) != 0)
                {
                    // world position has changed. Tell Ogre they have changed
                    try {
                        m_log.Log(LogLevel.DRENDERDETAIL, "RenderUpdate: Updating position/rotation for {0}", ent.Name.Name);
                        RegionRenderInfo rri;
                        if (ent.RegionContext.TryGet <RegionRenderInfo>(out rri))
                        {
                            lock (rri.renderPrimList) {
                                // exception if the casting does not work
                                if (((LLEntityBase)ent).Prim != null)
                                {
                                    uint localID = ((LLEntityBase)ent).Prim.LocalID;
                                    if (rri.renderPrimList.ContainsKey(localID))
                                    {
                                        RenderablePrim rp = rri.renderPrimList[localID];
                                        rp.Position = new OMV.Vector3(ent.RegionPosition.X, ent.RegionPosition.Y, ent.RegionPosition.Z);
                                        rp.Rotation = new OMV.Quaternion(ent.Heading.X, ent.Heading.Y, ent.Heading.Z, ent.Heading.W);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception e) {
                        m_log.Log(LogLevel.DBADERROR, "RenderUpdate: FAIL updating pos/rot: {0}", e);
                    }
                }
            }
            return;
        }
Example #7
0
        private void CreateNewPrim(LLEntityBase ent)
        {
            m_log.Log(LogLevel.DRENDERDETAIL, "Create new prim {0}", ent.Name.Name);
            // entity render info is kept per region. Get the region prim structure
            RegionRenderInfo rri = GetRegionRenderInfo(ent.RegionContext);
            IEntityAvatar    av;

            if (ent.TryGet <IEntityAvatar>(out av))
            {
                // if this entity is an avatar, just put it on the display list
                lock (rri.renderAvatarList) {
                    if (!rri.renderAvatarList.ContainsKey(av.LGID))
                    {
                        RenderableAvatar ravv = new RenderableAvatar();
                        ravv.avatar = av;
                        rri.renderAvatarList.Add(av.LGID, ravv);
                    }
                }
                return;
            }
            OMV.Primitive prim = ent.Prim;

            /* don't do foliage yet
             * if (prim.PrimData.PCode == OMV.PCode.Grass
             || prim.PrimData.PCode == OMV.PCode.Tree
             || prim.PrimData.PCode == OMV.PCode.NewTree) {
             || lock (renderFoliageList)
             ||     renderFoliageList[prim.LocalID] = prim;
             || return;
             ||}
             */

            RenderablePrim render = new RenderablePrim();

            render.Prim      = prim;
            render.acontext  = ent.AssetContext;
            render.rcontext  = ent.RegionContext;
            render.Position  = prim.Position;
            render.Rotation  = prim.Rotation;
            render.isVisible = true; // initially assume visible

            if (m_meshMaker == null)
            {
                m_meshMaker = new Renderer.Mesher.MeshmerizerR();
                m_meshMaker.ShouldScaleMesh = false;
            }

            if (prim.Sculpt != null)
            {
                EntityNameLL          textureEnt    = EntityNameLL.ConvertTextureWorldIDToEntityName(ent.AssetContext, prim.Sculpt.SculptTexture);
                System.Drawing.Bitmap textureBitmap = ent.AssetContext.GetTexture(textureEnt);
                if (textureBitmap == null)
                {
                    // the texture is not available. Request it.
                    // Note that we just call this routine again when it is available. Hope it's not recursive
                    ent.AssetContext.DoTextureLoad(textureEnt, AssetContextBase.AssetType.SculptieTexture,
                                                   delegate(string name, bool trans) {
                        CreateNewPrim(ent);
                        return;
                    }
                                                   );
                    return;
                }
                render.Mesh = m_meshMaker.GenerateSculptMesh(textureBitmap, prim, OMVR.DetailLevel.Medium);
                textureBitmap.Dispose();
            }
            else
            {
                render.Mesh = m_meshMaker.GenerateFacetedMesh(prim, OMVR.DetailLevel.High);
            }

            if (render.Mesh == null)
            {
                // mesh generation failed
                m_log.Log(LogLevel.DBADERROR, "FAILED MESH GENERATION: not generating new prim {0}", ent.Name.Name);
                return;
            }

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

                // Vertices for this face
                data.Vertices = 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;
                }

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

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

                // 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;
                }

                data.Normals = new float[face.Vertices.Count * 3];
                for (int k = 0; k < face.Vertices.Count; k++)
                {
                    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;
                }


                // m_log.Log(LogLevel.DRENDERDETAIL, "CreateNewPrim: v={0}, i={1}, t={2}",
                //     data.Vertices.GetLength(0), data.Indices.GetLength(0), data.TexCoords.GetLength(0));

                // Texture for this face
                if (teFace.TextureID != OMV.UUID.Zero &&
                    teFace.TextureID != OMV.Primitive.TextureEntry.WHITE_TEXTURE)
                {
                    lock (Textures) {
                        if (!Textures.ContainsKey(teFace.TextureID))
                        {
                            // temporarily add the entry to the table so we don't request it multiple times
                            Textures.Add(teFace.TextureID, new TextureInfo(0, true));
                            // We haven't constructed this image in OpenGL yet, get ahold of it
                            AssetContextBase.RequestTextureLoad(
                                EntityNameLL.ConvertTextureWorldIDToEntityName(ent.AssetContext, teFace.TextureID),
                                AssetContextBase.AssetType.Texture,
                                OnTextureDownloadFinished);
                        }
                    }
                }

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

            lock (rri.renderPrimList) {
                rri.renderPrimList[prim.LocalID] = render;
            }
        }