private void TryEndTouchObject() { if (m_currentlyTouchingObject != null) Client.Self.DeGrab(m_currentlyTouchingObject.Prim.LocalID); m_currentlyTouchingObject = null; }
private void UpdatePrimBlocking(Primitive prim) { if (!RenderingEnabled) return; if (RenderSettings.AvatarRenderingEnabled && prim.PrimData.PCode == PCode.Avatar) { AddAvatarToScene(Client.Network.CurrentSim.ObjectsAvatars[prim.LocalID]); return; } // Skip foliage if (prim.PrimData.PCode != PCode.Prim) return; if (!RenderSettings.PrimitiveRenderingEnabled) return; if (prim.Textures == null) return; RenderPrimitive rPrim = null; if (Prims.TryGetValue(prim.LocalID, out rPrim)) { rPrim.AttachedStateKnown = false; } else { rPrim = new RenderPrimitive(); rPrim.Meshed = false; rPrim.BoundingVolume = new BoundingVolume(); rPrim.BoundingVolume.FromScale(prim.Scale); } rPrim.BasePrim = prim; lock (Prims) Prims[prim.LocalID] = rPrim; }
private void TryTouchObject(RenderPrimitive LeftclickedObject) { if ((LeftclickedObject.Prim.Flags & PrimFlags.Touch) != 0) { if (m_currentlyTouchingObject != null) { if (m_currentlyTouchingObject.Prim.LocalID != LeftclickedObject.Prim.LocalID) { //Changed what we are touching... stop touching the old one TryEndTouchObject(); //Then set the new one and touch it for the first time m_currentlyTouchingObject = LeftclickedObject; Client.Self.Grab(LeftclickedObject.Prim.LocalID, Vector3.Zero, Vector3.Zero, Vector3.Zero, RightclickedFaceID, Vector3.Zero, Vector3.Zero, Vector3.Zero); Client.Self.GrabUpdate(LeftclickedObject.Prim.ID, Vector3.Zero); } else Client.Self.GrabUpdate(LeftclickedObject.Prim.ID, Vector3.Zero); } else { m_currentlyTouchingObject = LeftclickedObject; Client.Self.Grab(LeftclickedObject.Prim.LocalID, Vector3.Zero, Vector3.Zero, Vector3.Zero, RightclickedFaceID, Vector3.Zero, Vector3.Zero, Vector3.Zero); Client.Self.GrabUpdate(LeftclickedObject.Prim.ID, Vector3.Zero); } } }
private GenericTask GenerateSculptOrMeshPrim(RenderPrimitive rprim, Primitive prim) { return new GenericTask(() => { FacetedMesh mesh = null; try { if (prim.Sculpt.Type != SculptType.Mesh) { // Regular sculptie Image img = null; lock (sculptCache) { if (sculptCache.ContainsKey(prim.Sculpt.SculptTexture)) { img = sculptCache[prim.Sculpt.SculptTexture]; } } if (img == null) { if (LoadTexture(prim.Sculpt.SculptTexture, ref img, true)) { sculptCache[prim.Sculpt.SculptTexture] = (Bitmap)img; } else { return; } } mesh = renderer.GenerateFacetedSculptMesh(prim, (Bitmap)img, RenderSettings.SculptRenderDetail); } else { // Mesh AutoResetEvent gotMesh = new AutoResetEvent(false); Client.Assets.RequestMesh(prim.Sculpt.SculptTexture, (success, meshAsset) => { if (!success || !FacetedMesh.TryDecodeFromAsset(prim, meshAsset, RenderSettings.MeshRenderDetail, out mesh)) { Logger.Log("Failed to fetch or decode the mesh asset", Helpers.LogLevel.Warning, Client); } gotMesh.Set(); }); gotMesh.WaitOne(20 * 1000, false); } } catch { } if (mesh != null) { rprim.Faces = mesh.Faces; CalculateBoundingBox(rprim); rprim.Meshing = false; rprim.Meshed = true; } else { lock (Prims) { Prims.Remove(rprim.BasePrim.LocalID); } } }); }
private void MeshPrim(RenderPrimitive rprim) { if (rprim.Meshing) return; rprim.Meshing = true; Primitive prim = rprim.BasePrim; // Regular prim if (prim.Sculpt == null || prim.Sculpt.SculptTexture == UUID.Zero) { DetailLevel detailLevel = RenderSettings.PrimRenderDetail; if (RenderSettings.AllowQuickAndDirtyMeshing) { if (prim.Flexible == null && prim.Type == PrimType.Box && prim.PrimData.ProfileHollow == 0 && prim.PrimData.PathTwist == 0 && prim.PrimData.PathTaperX == 0 && prim.PrimData.PathTaperY == 0 && prim.PrimData.PathSkew == 0 && prim.PrimData.PathShearX == 0 && prim.PrimData.PathShearY == 0 && prim.PrimData.PathRevolutions == 1 && prim.PrimData.PathRadiusOffset == 0) detailLevel = DetailLevel.Low;//Its a box or something else that can use lower meshing } FacetedMesh mesh = renderer.GenerateFacetedMesh(prim, detailLevel); rprim.Faces = mesh.Faces; CalculateBoundingBox(rprim); rprim.Meshing = false; rprim.Meshed = true; } else { PendingTasks.Enqueue(GenerateSculptOrMeshPrim(rprim, prim)); return; } }
private void CalculateBoundingBox(RenderPrimitive rprim) { Primitive prim = rprim.BasePrim; // Calculate bounding volumes for each prim and adjust textures rprim.BoundingVolume = new BoundingVolume(); for (int j = 0; j < rprim.Faces.Count; j++) { Primitive.TextureEntryFace teFace = prim.Textures.GetFace((uint)j); if (teFace == null) continue; Face face = rprim.Faces[j]; FaceData data = new FaceData(); data.BoundingVolume.CreateBoundingVolume(face, prim.Scale); rprim.BoundingVolume.AddVolume(data.BoundingVolume, prim.Scale); // With linear texture animation in effect, texture repeats and offset are ignored if ((prim.TextureAnim.Flags & Primitive.TextureAnimMode.ANIM_ON) != 0 && (prim.TextureAnim.Flags & Primitive.TextureAnimMode.ROTATE) == 0 && (prim.TextureAnim.Face == 255 || prim.TextureAnim.Face == j)) { teFace.RepeatU = 1; teFace.RepeatV = 1; teFace.OffsetU = 0; teFace.OffsetV = 0; } // Need to adjust UV for spheres as they are sort of half-prim if (prim.PrimData.ProfileCurve == ProfileCurve.HalfCircle) { teFace = (Primitive.TextureEntryFace)teFace.Clone(); teFace.RepeatV *= 2; teFace.OffsetV += 0.5f; } // Sculpt UV vertically flipped compared to prims. Flip back if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero && prim.Sculpt.Type != SculptType.Mesh) { teFace = (Primitive.TextureEntryFace)teFace.Clone(); teFace.RepeatV *= -1; } // Texture transform for this face renderer.TransformTexCoords(face.Vertices, face.Center, teFace, prim.Scale); // Set the UserData for this face to our FaceData struct face.UserData = data; rprim.Faces[j] = face; } }
private void TryEndTouchObject() { if (m_currentlyTouchingObject != null) Client.Self.DeGrab(m_currentlyTouchingObject.Prim.LocalID, Vector3.Zero, Vector3.Zero, LeftclickedFaceID, Vector3.Zero, Vector3.Zero, Vector3.Zero); m_currentlyTouchingObject = null; }
void RenderPrim(RenderPrimitive mesh, RenderPass pass, int primNr) { if (!AvatarRenderingEnabled && mesh.Attached) return; Primitive prim = mesh.Prim; // Individual prim matrix GL.PushMatrix(); // Prim roation and position and scale GL.MultMatrix(Math3D.CreateSRTMatrix(prim.Scale, mesh.RenderRotation, mesh.RenderPosition)); // Do we have animated texture on this face bool animatedTexture = false; // Initialise flags tracking what type of faces this prim has if (pass == RenderPass.Simple) { mesh.HasSimpleFaces = false; } else if (pass == RenderPass.Alpha) { mesh.HasAlphaFaces = false; } // Draw the prim faces for (int j = 0; j < mesh.Faces.Count; j++) { Primitive.TextureEntryFace teFace = mesh.Prim.Textures.GetFace((uint)j); Face face = mesh.Faces[j]; FaceData data = (FaceData)mesh.Faces[j].UserData; if (data == null) continue; if (teFace == null) continue; // Don't render transparent faces if (data.TextureInfo.FullAlpha || teFace.RGBA.A <= 0.01f) continue; bool switchedLightsOff = false; if (pass != RenderPass.Picking) { bool belongToAlphaPass = (teFace.RGBA.A < 0.99f) || (data.TextureInfo.HasAlpha && !data.TextureInfo.IsMask); if (belongToAlphaPass && pass != RenderPass.Alpha) continue; if (!belongToAlphaPass && pass == RenderPass.Alpha) continue; if (pass == RenderPass.Simple) { mesh.HasSimpleFaces = true; } else if (pass == RenderPass.Alpha) { mesh.HasAlphaFaces = true; } if (teFace.Fullbright) { GL.Disable(EnableCap.Lighting); switchedLightsOff = true; } switch (teFace.Shiny) { case Shininess.High: GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.94f); break; case Shininess.Medium: GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.64f); break; case Shininess.Low: GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0.24f); break; case Shininess.None: default: GL.Material(MaterialFace.Front, MaterialParameter.Shininess, 0f); break; } var faceColor = new float[] { teFace.RGBA.R, teFace.RGBA.G, teFace.RGBA.B, teFace.RGBA.A }; GL.Color4(faceColor); GL.Material(MaterialFace.Front, MaterialParameter.Specular, new float[] { 0.5f, 0.5f, 0.5f, 1f }); if (data.TextureInfo.TexturePointer == 0 && TexturesPtrMap.ContainsKey(teFace.TextureID)) { data.TextureInfo = TexturesPtrMap[teFace.TextureID]; } if (data.TextureInfo.TexturePointer == 0) { GL.Disable(EnableCap.Texture2D); if (texturesRequestedThisFrame < 2 && !data.TextureInfo.FetchFailed) { texturesRequestedThisFrame++; DownloadTexture(new TextureLoadItem() { Prim = prim, TeFace = teFace, Data = data }); } } else { // Is this face using texture animation if ((prim.TextureAnim.Flags & Primitive.TextureAnimMode.ANIM_ON) != 0 && (prim.TextureAnim.Face == j || prim.TextureAnim.Face == 255)) { if (data.AnimInfo == null) { data.AnimInfo = new TextureAnimationInfo(); } data.AnimInfo.PrimAnimInfo = prim.TextureAnim; data.AnimInfo.Step(lastFrameTime); animatedTexture = true; } else if (data.AnimInfo != null) // Face texture not animated. Do we have previous anim setting? { data.AnimInfo = null; } GL.Enable(EnableCap.Texture2D); GL.BindTexture(TextureTarget.Texture2D, data.TextureInfo.TexturePointer); } } else { data.PickingID = primNr; var primNrBytes = Utils.UInt16ToBytes((ushort)primNr); var faceColor = new byte[] { primNrBytes[0], primNrBytes[1], (byte)j, 255 }; GL.Color4(faceColor); } if (!RenderSettings.UseVBO) { Vertex[] verts = face.Vertices.ToArray(); ushort[] indices = face.Indices.ToArray(); unsafe { fixed (float* normalPtr = &verts[0].Normal.X) fixed (float* texPtr = &verts[0].TexCoord.X) { GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)normalPtr); GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)texPtr); GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, verts); GL.DrawElements(BeginMode.Triangles, indices.Length, DrawElementsType.UnsignedShort, indices); } } } else { data.CheckVBO(face); GL.BindBuffer(BufferTarget.ArrayBuffer, data.VertexVBO); GL.BindBuffer(BufferTarget.ElementArrayBuffer, data.IndexVBO); GL.NormalPointer(NormalPointerType.Float, FaceData.VertexSize, (IntPtr)12); GL.TexCoordPointer(2, TexCoordPointerType.Float, FaceData.VertexSize, (IntPtr)(24)); GL.VertexPointer(3, VertexPointerType.Float, FaceData.VertexSize, (IntPtr)(0)); GL.DrawElements(BeginMode.Triangles, face.Indices.Count, DrawElementsType.UnsignedShort, IntPtr.Zero); GL.BindBuffer(BufferTarget.ArrayBuffer, 0); GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0); } if (switchedLightsOff) { GL.Enable(EnableCap.Lighting); switchedLightsOff = false; } } GL.BindTexture(TextureTarget.Texture2D, 0); ResetMaterial(); // Reset texture coordinates if we modified them in texture animation if (animatedTexture) { GL.MatrixMode(MatrixMode.Texture); GL.LoadIdentity(); GL.MatrixMode(MatrixMode.Modelview); } // Pop the prim matrix GL.PopMatrix(); }