public void Objects_OnObjectProperties11(Simulator simulator, Primitive prim, Primitive.ObjectProperties props) { //Primitive prim = GetPrimitive(props.ObjectID, simulator); if (prim == null) { prim = GetPrimitive(props.ObjectID, simulator); } DeclareProperties(prim, props, simulator); if (prim != null) { prim.RegionHandle = simulator.Handle; SimObject updateMe = GetSimObject(prim, simulator); if (updateMe == null) { return; } if (prim.ParentID == 0 && !SimRegion.OutOfRegion(prim.Position)) { updateMe.ResetPrim(prim, client, simulator); } if (MaintainObjectProperties) { //updateMe.Properties = null; updateMe.Properties = (props); } //Debug("UpdateProperties: {0}", updateMe.DebugInfo()); describePrimToAI(prim, simulator); } }
void Objects_OnObjectProperties(Simulator simulator, Primitive.ObjectProperties properties) { lock (PrimsWaiting) { Primitive prim; if (PrimsWaiting.TryGetValue(properties.ObjectID, out prim)) { prim.Properties = properties; } PrimsWaiting.Remove(properties.ObjectID); if (PrimsWaiting.Count == 0) AllPropertiesReceived.Set(); } }
void Objects_OnNewPrim(Simulator simulator, Primitive prim, ulong regionHandle, ushort timeDilation) { if (enabled) { // Search this prim for textures for (int i = 0; i < prim.Textures.FaceTextures.Length; i++) { Primitive.TextureEntryFace face = prim.Textures.FaceTextures[i]; if (face != null) { if (!alreadyRequested.ContainsKey(face.TextureID)) { alreadyRequested[face.TextureID] = face.TextureID; Client.Assets.RequestImage(face.TextureID, ImageType.Normal); } } } } }
public SimMesh(MeshableObject simObject, Primitive prim, SimPathStore PS) : base(new Box3Fill(true), new List<Box3Fill>(), PS) { RootObject = simObject; Prim = prim; Update(RootObject); }
// Add the submesh to the passed FacetedMesh as a new face. private void AddSubMesh(OMV.Primitive prim, int faceIndex, OSD subMeshOsd, ref OMVR.FacetedMesh holdingMesh) { if (subMeshOsd is OSDMap subMesh) { // As per http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format, some Mesh Level // of Detail Blocks (maps) contain just a NoGeometry key to signal there is no // geometry for this submesh. if (subMesh.ContainsKey("NoGeometry") && ((OSDBoolean)subMesh["NoGeometry"])) { return; } Face oface = new Face { ID = faceIndex, Vertices = new List <Vertex>(), Indices = new List <ushort>(), TextureFace = prim.Textures.GetFace((uint)faceIndex) }; OSDMap subMeshMap = subMesh; oface.Vertices = CollectVertices(subMeshMap); oface.Indices = CollectIndices(subMeshMap); holdingMesh.Faces.Add(oface); } }
public Notecard(RadegastInstance instance, InventoryNotecard notecard, Primitive prim) { InitializeComponent(); Disposed += new EventHandler(Notecard_Disposed); this.instance = instance; this.notecard = notecard; this.prim = prim; Text = notecard.Name; rtbContent.DetectUrls = false; if (notecard.AssetUUID == UUID.Zero) { UpdateStatus("Blank"); } else { rtbContent.Text = " "; UpdateStatus("Loading..."); if (prim == null) { client.Assets.RequestInventoryAsset(notecard, true, Assets_OnAssetReceived); } else { client.Assets.RequestInventoryAsset(notecard.AssetUUID, notecard.UUID, prim.ID, prim.OwnerID, notecard.AssetType, true, Assets_OnAssetReceived); } } }
public PrimitiveBaseShape(Primitive prim) { ExtraParams = new byte[1]; _pathBegin = Primitive.PackBeginCut(prim.PrimData.PathBegin); _pathCurve = (byte)prim.PrimData.PathCurve; _pathEnd = Primitive.PackEndCut(prim.PrimData.PathEnd); _pathRadiusOffset = Primitive.PackPathTwist(prim.PrimData.PathRadiusOffset); _pathRevolutions = Primitive.PackPathRevolutions(prim.PrimData.PathRevolutions); _pathScaleX = Primitive.PackPathScale(prim.PrimData.PathScaleX); _pathScaleY = Primitive.PackPathScale(prim.PrimData.PathScaleY); _pathShearX = (byte)Primitive.PackPathShear(prim.PrimData.PathShearX); _pathShearY = (byte)Primitive.PackPathShear(prim.PrimData.PathShearY); _pathSkew = Primitive.PackPathTwist(prim.PrimData.PathSkew); _pathTaperX = Primitive.PackPathTaper(prim.PrimData.PathTaperX); _pathTaperY = Primitive.PackPathTaper(prim.PrimData.PathTaperY); _pathTwist = Primitive.PackPathTwist(prim.PrimData.PathTwist); _pathTwistBegin = Primitive.PackPathTwist(prim.PrimData.PathTwistBegin); _pCode = (byte)prim.PrimData.PCode; _profileBegin = Primitive.PackBeginCut(prim.PrimData.ProfileBegin); _profileEnd = Primitive.PackEndCut(prim.PrimData.ProfileEnd); _profileHollow = Primitive.PackProfileHollow(prim.PrimData.ProfileHollow); _scale = prim.Scale; _state = prim.PrimData.State; }
public AvatarAppearance(UUID avatarID, AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) { // MainConsole.Instance.WarnFormat("[AVATAR APPEARANCE] create initialized appearance for {0}",avatarID); m_serial = 1; m_owner = avatarID; if (wearables != null) m_wearables = wearables; else SetDefaultWearables(); if (textureEntry != null) m_texture = textureEntry; else SetDefaultTexture(); if (visualParams != null) m_visualparams = visualParams; else SetDefaultParams(); SetHeight(); m_attachments = new Dictionary<int, List<AvatarAttachment>>(); }
/// <summary> /// Generates a basic mesh structure from a primitive /// A 'SimpleMesh' is just the prim's overall shape with no material information. /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh or null on failure</returns> public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { LibreMetaverse.PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, false); if (newPrim == null) { return(null); } SimpleMesh mesh = new SimpleMesh { Path = new Path(), Prim = prim, Profile = new Profile(), Vertices = new List <Vertex>(newPrim.coords.Count) }; foreach (Coord c in newPrim.coords) { mesh.Vertices.Add(new Vertex { Position = new Vector3(c.X, c.Y, c.Z) }); } mesh.Indices = new List <ushort>(newPrim.faces.Count * 3); foreach (LibreMetaverse.PrimMesher.Face face in newPrim.faces) { mesh.Indices.Add((ushort)face.v1); mesh.Indices.Add((ushort)face.v2); mesh.Indices.Add((ushort)face.v3); } return(mesh); }
/// <summary> /// Generates a basic mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh or null on failure</returns> public OMVR.SimpleMesh GenerateSimpleMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, false); if (newPrim == null) { return(null); } SimpleMesh mesh = new SimpleMesh(); mesh.Path = new Path(); mesh.Prim = prim; mesh.Profile = new Profile(); mesh.Vertices = new List <Vertex>(newPrim.coords.Count); for (int i = 0; i < newPrim.coords.Count; i++) { PrimMesher.Coord c = newPrim.coords[i]; mesh.Vertices.Add(new Vertex { Position = new Vector3(c.X, c.Y, c.Z) }); } mesh.Indices = new List <ushort>(newPrim.faces.Count * 3); for (int i = 0; i < newPrim.faces.Count; i++) { PrimMesher.Face face = newPrim.faces[i]; mesh.Indices.Add((ushort)face.v1); mesh.Indices.Add((ushort)face.v2); mesh.Indices.Add((ushort)face.v3); } return(mesh); }
/// <summary> /// Check to see if the client has baked textures that belong to banned clients /// </summary> /// <param name="client"></param> /// <param name="textureEntry"></param> public void CheckForBannedViewer(IClientAPI client, Primitive.TextureEntry textureEntry) { try { //Read the website once! if (m_map == null) m_map = (OSDMap)OSDParser.Deserialize(Utilities.ReadExternalWebsite("http://auroraserver.ath.cx:8080/client_tags.xml")); //This is the givaway texture! for (int i = 0; i < textureEntry.FaceTextures.Length; i++) { if (textureEntry.FaceTextures[i] != null) { if (m_map.ContainsKey(textureEntry.FaceTextures[i].TextureID.ToString())) { OSDMap viewerMap = (OSDMap)m_map[textureEntry.FaceTextures[i].TextureID.ToString()]; //Check the names if (BannedViewers.Contains(viewerMap["name"].ToString())) { client.Kick("You cannot use " + viewerMap["name"] + " in this sim."); ((Scene)client.Scene).IncomingCloseAgent(client.AgentId); } else if (m_banEvilViewersByDefault && viewerMap.ContainsKey("evil") && (viewerMap["evil"].AsBoolean() == true)) { client.Kick("You cannot use " + viewerMap["name"] + " in this sim."); ((Scene)client.Scene).IncomingCloseAgent(client.AgentId); } } } } } catch { } }
public AttachmentsListItem(Primitive prim, GridClient client, ListBox listBox) { this.prim = prim; this.client = client; this.listBox = listBox; client.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_OnObjectProperties); }
public SimulationObject(SimulationObject obj) { Prim = new Primitive(obj.Prim); Server = obj.Server; LinkNumber = obj.LinkNumber; Frozen = obj.Frozen; // Skip everything else because it can be lazily reconstructed }
//private object AsType(Object te, Type type, MemberInfo info) //{ // if (type.IsInstanceOfType(te)) return te; // return new NullType(type); //} public override void Appearance_OnAppearanceUpdated(Primitive.TextureEntry te) { if (te!=null) { client.SendNetworkEvent("On-Appearance-Updated", te); } //client.SendNetworkEvent("On-Appearance-Updated", AsType(te, typeof(Primitive.TextureEntry))); }
public ExportCollada(RadegastInstance instance, Primitive prim) : base(instance) { InitializeComponent(); Exporter = new DAEExport(instance, prim); Exporter.Progress += new EventHandler<DAEStatutsEventArgs>(Exporter_Progress); UpdateInfo(); cbImageType.Text = "TGA"; }
public LLEntityPhysical(AssetContextBase acontext, LLRegionContext rcontext, ulong regionHandle, uint localID, OMV.Primitive prim) : base(rcontext, acontext) { this.Sim = rcontext.Simulator; this.RegionHandle = regionHandle; this.LocalID = localID; this.Prim = prim; this.Name = new EntityNameLL(acontext, m_prim.ID.ToString()); }
public DAEExport(RadegastInstance instance, Primitive requestedPrim) { Instance = instance; ImageFormat = "PNG"; ConsolidateMaterials = true; SkipTransparentFaces = true; Mesher = new MeshmerizerR(); Init(Client.Network.CurrentSim, requestedPrim); }
/// <summary> /// Create a faceted mesh from prim shape parameters. /// Generates a a series of faces, each face containing a mesh and /// material metadata. /// A prim will turn into multiple faces with each being independent /// meshes and each having different material information. /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns > public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle); PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) { return(null); } // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List <OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List <OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List <OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List <OMVR.PathPoint>(); var indexer = newPrim.GetVertexIndexer(); for (int i = 0; i < indexer.numPrimFaces; i++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List <OMVR.Vertex>(); oface.Indices = new List <ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)i); for (int j = 0; j < indexer.viewerVertices[i].Count; j++) { var vert = new OMVR.Vertex(); var m = indexer.viewerVertices[i][j]; vert.Position = new Vector3(m.v.X, m.v.Y, m.v.Z); vert.Normal = new Vector3(m.n.X, m.n.Y, m.n.Z); vert.TexCoord = new OMV.Vector2(m.uv.U, 1.0f - m.uv.V); oface.Vertices.Add(vert); } for (int j = 0; j < indexer.viewerPolygons[i].Count; j++) { var p = indexer.viewerPolygons[i][j]; // Skip "degenerate faces" where the same vertex appears twice in the same tri if (p.v1 == p.v2 || p.v1 == p.v2 || p.v2 == p.v3) { continue; } oface.Indices.Add((ushort)p.v1); oface.Indices.Add((ushort)p.v2); oface.Indices.Add((ushort)p.v3); } omvrmesh.Faces.Add(oface); } return(omvrmesh); }
public static ObjectUpdatePacket BuildFullUpdate(Primitive obj, ulong regionHandle, PrimFlags flags) { ObjectUpdatePacket update = new ObjectUpdatePacket(); update.RegionData.RegionHandle = regionHandle; update.RegionData.TimeDilation = UInt16.MaxValue; update.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; update.ObjectData[0] = BuildUpdateBlock(obj, regionHandle, flags); return update; }
public PayWindow(Primitive prim,int amount) : base(Gtk.WindowType.Toplevel) { this.Build(); is_object=true; amountpay=amount; resident_key=prim.Properties.OwnerID; object_key=prim.Properties.ObjectID; object_name=prim.Properties.Name; }
public static ObjectUpdatePacket.ObjectDataBlock BuildUpdateBlock(Primitive obj, ulong regionHandle, PrimFlags flags) { byte[] objectData = BuildObjectData(obj.Position, obj.Rotation, obj.Velocity, obj.Acceleration, obj.AngularVelocity); ObjectUpdatePacket.ObjectDataBlock update = new ObjectUpdatePacket.ObjectDataBlock(); update.ClickAction = (byte)obj.ClickAction; update.CRC = 0; update.ExtraParams = obj.GetExtraParamsBytes(); update.Flags = (byte)flags; update.FullID = obj.ID; update.Gain = obj.SoundGain; update.ID = obj.LocalID; update.JointAxisOrAnchor = obj.JointAxisOrAnchor; update.JointPivot = obj.JointPivot; update.JointType = (byte)obj.Joint; update.Material = (byte)obj.PrimData.Material; update.MediaURL = Utils.StringToBytes(obj.MediaURL); update.NameValue = Utils.StringToBytes(NameValue.NameValuesToString(obj.NameValues)); update.ObjectData = objectData; update.OwnerID = (obj.Properties != null ? obj.Properties.OwnerID : UUID.Zero); update.ParentID = obj.ParentID; update.PathBegin = Primitive.PackBeginCut(obj.PrimData.PathBegin); update.PathCurve = (byte)obj.PrimData.PathCurve; update.PathEnd = Primitive.PackEndCut(obj.PrimData.PathEnd); update.PathRadiusOffset = Primitive.PackPathTwist(obj.PrimData.PathRadiusOffset); update.PathRevolutions = Primitive.PackPathRevolutions(obj.PrimData.PathRevolutions); update.PathScaleX = Primitive.PackPathScale(obj.PrimData.PathScaleX); update.PathScaleY = Primitive.PackPathScale(obj.PrimData.PathScaleY); update.PathShearX = (byte)Primitive.PackPathShear(obj.PrimData.PathShearX); update.PathShearY = (byte)Primitive.PackPathShear(obj.PrimData.PathShearY); update.PathSkew = Primitive.PackPathTwist(obj.PrimData.PathSkew); update.PathTaperX = Primitive.PackPathTaper(obj.PrimData.PathTaperX); update.PathTaperY = Primitive.PackPathTaper(obj.PrimData.PathTaperY); update.PathTwist = Primitive.PackPathTwist(obj.PrimData.PathTwist); update.PathTwistBegin = Primitive.PackPathTwist(obj.PrimData.PathTwistBegin); update.PCode = (byte)obj.PrimData.PCode; update.ProfileBegin = Primitive.PackBeginCut(obj.PrimData.ProfileBegin); update.ProfileCurve = (byte)obj.PrimData.ProfileCurve; update.ProfileEnd = Primitive.PackEndCut(obj.PrimData.ProfileEnd); update.ProfileHollow = Primitive.PackProfileHollow(obj.PrimData.ProfileHollow); update.PSBlock = obj.ParticleSys.GetBytes(); update.TextColor = obj.TextColor.GetBytes(true); update.TextureAnim = obj.TextureAnim.GetBytes(); update.TextureEntry = obj.Textures == null ? new byte[0] : obj.Textures.ToBytes(); update.Radius = obj.SoundRadius; update.Scale = obj.Scale; update.Sound = obj.Sound; update.State = obj.PrimData.State; update.Text = Utils.StringToBytes(obj.Text); update.UpdateFlags = (uint)flags; update.Data = obj.GenericData == null ? new byte[0] : obj.GenericData; return update; }
/// <summary> /// Create and return a set of meshes/materials that make the passed SOP. /// This just deals the making a mesh from the SOP and getting the material/texture of the meshes /// into the caches. /// </summary> // Returns 'null' if the SOG/SOP could not be converted into a displayable public IPromise <Displayable> CreateMeshResource(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { var prom = new Promise <Displayable>(); try { if (prim.Sculpt != null) { if (prim.Sculpt.Type == OMV.SculptType.Mesh) { BConverterOS.LogBProgress("{0}: CreateMeshResource: creating mesh", _logHeader); ConvOAR.Globals.stats.numMeshAssets++; MeshFromPrimMeshData(sog, sop, prim, assetFetcher, lod) .Then(dispable => { prom.Resolve(new Displayable(dispable, sop)); }, e => { // prom.Reject(e); prom.Resolve(null); }); } else { BConverterOS.LogBProgress("{0}: CreateMeshResource: creating sculpty", _logHeader); ConvOAR.Globals.stats.numSculpties++; MeshFromPrimSculptData(sog, sop, prim, assetFetcher, lod) .Then(dispable => { prom.Resolve(new Displayable(dispable, sop)); }, e => { // prom.Reject(e); prom.Resolve(null); }); } } else { BConverterOS.LogBProgress("{0}: CreateMeshResource: creating primshape", _logHeader); ConvOAR.Globals.stats.numSimplePrims++; MeshFromPrimShapeData(sog, sop, prim, assetFetcher, lod) .Then(dispable => { BConverterOS.LogBProgress("{0} CreateMeshResource: prim created", _logHeader); prom.Resolve(new Displayable(dispable, sop)); }, e => { // prom.Reject(e); prom.Resolve(null); }); } } catch (Exception e) { prom.Reject(e); } return(prom); }
private static UUID GetItemID(Primitive att) { if (att.NameValues == null) return UUID.Zero; for (int i = 0; i < att.NameValues.Length; i++) { if (att.NameValues[i].Name == "AttachItemID") { return (UUID)att.NameValues[i].Value.ToString(); } } return UUID.Zero; }
/// <summary> /// Get inventory ID of a prim /// </summary> /// <param name="prim">Prim to check</param> /// <returns>Inventory ID of the object. UUID.Zero if not found</returns> public static UUID GetAttachmentItem(Primitive prim) { if (prim.NameValues == null) return UUID.Zero; for (int i = 0; i < prim.NameValues.Length; i++) { if (prim.NameValues[i].Name == "AttachItemID") { return (UUID)prim.NameValues[i].Value.ToString(); } } return UUID.Zero; }
private Promise <DisplayableRenderable> MeshFromPrimShapeData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { return(new Promise <DisplayableRenderable>((resolve, reject) => { OMVR.FacetedMesh mesh = _mesher.GenerateFacetedMesh(prim, lod); DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, mesh, prim.Textures.DefaultTexture, prim.Scale); BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); BConverterOS.LogBProgress("{0} MeshFromPrimShapeData. numGenedMeshed={1}", _logHeader, ((RenderableMeshGroup)realDR).meshes.Count); resolve(realDR); })); }
// Convert a compressed submesh buffer into a SimpleMesh. public OMVR.SimpleMesh MeshSubMeshAsSimpleMesh(OMV.Primitive prim, byte[] compressedMeshData) { OMVR.SimpleMesh ret = null; OSD meshOSD = Helpers.DecompressOSD(compressedMeshData); OSDArray meshFaces = meshOSD as OSDArray; if (meshOSD != null) { ret = new SimpleMesh(); foreach (OSD subMesh in meshFaces) { AddSubMesh(subMesh, ref ret); } } return(ret); }
private static ClickActionType GetClickType(Primitive prim) { ClickActionType clickType = ClickActionType.None; switch (prim.ClickAction) { case ClickAction.Touch: if ((prim.Flags & PrimFlags.Touch) != 0) clickType = ClickActionType.Touch; break; case OpenMetaverse.ClickAction.Sit: clickType = ClickActionType.Sit; break; } return clickType; }
public ScriptEditor(RadegastInstance instance, InventoryLSL script, Primitive prim) { InitializeComponent(); Disposed += new EventHandler(SscriptEditor_Disposed); this.instance = instance; this.script = script; this.prim = prim; rtb.SyntaxHighlightEnabled = instance.GlobalSettings["script_syntax_highlight"].AsBoolean(); lblScripStatus.Text = string.Empty; lblScripStatus.TextChanged += (object sender, EventArgs e) => instance.TabConsole.DisplayNotificationInChat(lblScripStatus.Text, ChatBufferTextStyle.Invisible); Dock = DockStyle.Fill; this.TabStop = false; if (prim == null) { cbRunning.Visible = false; } // Download script if (script != null) { scriptName = script.Name; if (prim != null) { client.Assets.RequestInventoryAsset(script.AssetUUID, script.UUID, prim.ID, prim.OwnerID, script.AssetType, true, Assets_OnAssetReceived); client.Inventory.RequestGetScriptRunning(prim.ID, script.UUID); client.Inventory.ScriptRunningReply += OnScriptRunningReplyReceived; } else { client.Assets.RequestInventoryAsset(script, true, Assets_OnAssetReceived); } rtb.Text = lblScripStatus.Text = "Loading script..."; } else { rtb.Text = " "; //bugs in control grrrr rtb.SelectionStart = 0; } Radegast.GUI.GuiHelpers.ApplyGuiFixes(this); }
public AttachmentDetail(RadegastInstance instance, Avatar av, Primitive attachment) { InitializeComponent(); Disposed += new EventHandler(AttachmentDetail_Disposed); this.instance = instance; this.av = av; this.attachment = attachment; if (!instance.advancedDebugging) { btnSave.Visible = false; boxID.Visible = false; lblAttachment.Visible = false; } // Callbacks client.Objects.ObjectProperties += new EventHandler<ObjectPropertiesEventArgs>(Objects_ObjectProperties); }
// Convert a compressed submesh buffer into a FacetedMesh. public FacetedMesh MeshSubMeshAsFacetedMesh(OMV.Primitive prim, byte[] compressedMeshData) { FacetedMesh ret = null; OSD meshOSD = Helpers.DecompressOSD(compressedMeshData); OSDArray meshFaces = meshOSD as OSDArray; if (meshFaces != null) { ret = new FacetedMesh { Faces = new List <Face>() }; for (int faceIndex = 0; faceIndex < meshFaces.Count; faceIndex++) { AddSubMesh(prim, faceIndex, meshFaces[faceIndex], ref ret); } } return(ret); }
/// <summary> /// Generates a sculpt mesh structure from a primitive /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns> public OMVR.SimpleMesh GenerateSimpleSculptMesh(OMV.Primitive prim, Bitmap bits, OMVR.DetailLevel lod) { OMVR.FacetedMesh faceted = GenerateFacetedSculptMesh(prim, bits, lod); if (faceted != null && faceted.Faces.Count == 1) { OMVR.Face face = faceted.Faces[0]; OMVR.SimpleMesh mesh = new OMVR.SimpleMesh(); mesh.Indices = face.Indices; mesh.Vertices = face.Vertices; mesh.Path = faceted.Path; mesh.Prim = prim; mesh.Profile = faceted.Profile; mesh.Vertices = face.Vertices; return(mesh); } return(null); }
/// <summary> /// Check to see if the client has baked textures that belong to banned clients /// </summary> /// <param name="avatarID"></param> /// <param name="textureEntry"></param> public void CheckForBannedViewer(UUID avatarID, Primitive.TextureEntry textureEntry) { try { //Read the website once! if (m_map == null) m_map = OSDParser.Deserialize(Utilities.ReadExternalWebsite(m_viewerTagURL)) as OSDMap; if (m_map == null) m_map = OSDParser.Deserialize(System.IO.File.ReadAllText(m_viewerTagFile)) as OSDMap; if (m_map == null) return; //Can't find it //This is the giveaway texture! for (int i = 0; i < textureEntry.FaceTextures.Length; i++) { if (textureEntry.FaceTextures[i] != null) { if (m_map.ContainsKey(textureEntry.FaceTextures[i].TextureID.ToString())) { OSDMap viewerMap = (OSDMap) m_map[textureEntry.FaceTextures[i].TextureID.ToString()]; //Check the names if (IsViewerBanned(viewerMap["name"].ToString())) { IGridWideMessageModule messageModule = m_registry.RequestModuleInterface<IGridWideMessageModule>(); if (messageModule != null) messageModule.KickUser(avatarID, "You cannot use " + viewerMap["name"] + " in this grid."); break; } break; } } } } catch { } }
private Promise <DisplayableRenderable> MeshFromPrimSculptData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { return(new Promise <DisplayableRenderable>((resolve, reject) => { // Get the asset that the sculpty is built on EntityHandleUUID texHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture); assetFetcher.FetchTexture(texHandle) .Then((bm) => { OMVR.FacetedMesh fMesh = _mesher.GenerateFacetedSculptMesh(prim, bm.Image.ExportBitmap(), lod); DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale); BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); BConverterOS.LogBProgress("{0} MeshFromPrimSculptData. numFaces={1}, numGenedMeshed={2}", _logHeader, fMesh.Faces.Count, ((RenderableMeshGroup)realDR).meshes.Count); resolve(realDR); }, (e) => { ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimSculptData: Rejected FetchTexture: {1}: {2}", _logHeader, texHandle, e); reject(null); }); })); }
private Promise <DisplayableRenderable> MeshFromPrimMeshData(SceneObjectGroup sog, SceneObjectPart sop, OMV.Primitive prim, IAssetFetcher assetFetcher, OMVR.DetailLevel lod) { EntityHandleUUID meshHandle = new EntityHandleUUID(prim.Sculpt.SculptTexture); return(new Promise <DisplayableRenderable>((resolve, reject) => { assetFetcher.FetchRawAsset(meshHandle) .Then(meshBytes => { // OMVA.AssetMesh meshAsset = new OMVA.AssetMesh(prim.ID, meshBytes); // if (OMVR.FacetedMesh.TryDecodeFromAsset(prim, meshAsset, lod, out fMesh)) { OMVR.FacetedMesh fMesh = null; try { fMesh = _mesher.GenerateFacetedMeshMesh(prim, meshBytes); } catch (Exception e) { ConvOAR.Globals.log.ErrorFormat("{0} Exception in GenerateFacetedMeshMesh: {1}", _logHeader, e); } if (fMesh != null) { DisplayableRenderable dr = ConvertFacetedMeshToDisplayable(assetFetcher, fMesh, prim.Textures.DefaultTexture, prim.Scale); // Don't know the hash of the DisplayableRenderable until after it has been created. // Now use the hash to see if this has already been done. // If this DisplayableRenderable has already been built, use the other one and throw this away. BHash drHash = dr.GetBHash(); DisplayableRenderable realDR = assetFetcher.GetRenderable(drHash, () => { return dr; }); resolve(realDR); } else { reject(new Exception("MeshFromPrimMeshData: could not decode mesh information from asset. ID=" + prim.ID.ToString())); } }, e => { ConvOAR.Globals.log.ErrorFormat("{0} MeshFromPrimMeshData: exception: {1}", _logHeader, e); reject(e); }); })); }
// A version of GenerateFacetedMeshMesh that takes LOD spec so it's similar in calling convention of // the other Generate* methods. public OMVR.FacetedMesh GenerateFacetedMeshMesh(OMV.Primitive prim, byte[] meshData, OMVR.DetailLevel lod) { OMVR.FacetedMesh ret = null; string partName = null; switch (lod) { case OMVR.DetailLevel.Highest: partName = "high_lod"; break; case OMVR.DetailLevel.High: partName = "medium_lod"; break; case OMVR.DetailLevel.Medium: partName = "low_lod"; break; case OMVR.DetailLevel.Low: partName = "lowest_lod"; break; } if (partName != null) { OSDMap meshParts = UnpackMesh(meshData); if (meshParts != null) { if (meshParts.ContainsKey(partName)) { byte[] meshBytes = meshParts[partName]; if (meshBytes != null) { ret = MeshSubMeshAsFacetedMesh(prim, meshBytes); } } } } return(ret); }
// The mesh reader code is organized so it can be used in several different ways: // // 1. Fetch the highest detail displayable mesh as a FacetedMesh: // var facetedMesh = GenerateFacetedMeshMesh(prim, meshData); // 2. Get the header, examine the submeshes available, and extract the part // desired (good if getting a different LOD of mesh): // OSDMap meshParts = UnpackMesh(meshData); // if (meshParts.ContainsKey("medium_lod")) // var facetedMesh = MeshSubMeshAsFacetedMesh(prim, meshParts["medium_lod"]): // 3. Get a simple mesh from one of the submeshes (good if just getting a physics version): // OSDMap meshParts = UnpackMesh(meshData); // OMV.Mesh flatMesh = MeshSubMeshAsSimpleMesh(prim, meshParts["physics_mesh"]); // // "physics_convex" is specially formatted so there is another routine to unpack // that section: // OSDMap meshParts = UnpackMesh(meshData); // if (meshParts.ContainsKey("physics_convex")) // OSMap hullPieces = MeshSubMeshAsConvexHulls(prim, meshParts["physics_convex"]): // // LL mesh format detailed at http://wiki.secondlife.com/wiki/Mesh/Mesh_Asset_Format /// <summary> /// Create a mesh faceted mesh from the compressed mesh data. /// This returns the highest LOD renderable version of the mesh. /// /// The actual mesh data is fetched and passed to this /// routine since all the context for finding the data is elsewhere. /// </summary> /// <returns>The faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateFacetedMeshMesh(OMV.Primitive prim, byte[] meshData) { OMVR.FacetedMesh ret = null; OSDMap meshParts = UnpackMesh(meshData); if (meshParts != null) { byte[] meshBytes = null; string[] decreasingLOD = { "high_lod", "medium_lod", "low_lod", "lowest_lod" }; foreach (string partName in decreasingLOD) { if (meshParts.ContainsKey(partName)) { meshBytes = meshParts[partName]; break; } } if (meshBytes != null) { ret = MeshSubMeshAsFacetedMesh(prim, meshBytes); } } return(ret); }
/// <summary> /// Update the textures on the part. /// </summary> /// <remarks> /// Added to handle bug in libsecondlife's TextureEntry.ToBytes() /// not handling RGBA properly. Cycles through, and "fixes" the color /// info /// </remarks> /// <param name="tex"></param> public void UpdateTexture(Primitive.TextureEntry tex) { //Color4 tmpcolor; //for (uint i = 0; i < 32; i++) //{ // if (tex.FaceTextures[i] != null) // { // tmpcolor = tex.GetFace((uint) i).RGBA; // tmpcolor.A = tmpcolor.A*255; // tmpcolor.R = tmpcolor.R*255; // tmpcolor.G = tmpcolor.G*255; // tmpcolor.B = tmpcolor.B*255; // tex.FaceTextures[i].RGBA = tmpcolor; // } //} //tmpcolor = tex.DefaultTexture.RGBA; //tmpcolor.A = tmpcolor.A*255; //tmpcolor.R = tmpcolor.R*255; //tmpcolor.G = tmpcolor.G*255; //tmpcolor.B = tmpcolor.B*255; //tex.DefaultTexture.RGBA = tmpcolor; UpdateTextureEntry(tex.GetBytes()); }
public void AddNewParticleSystem(Primitive.ParticleSystem pSystem) { m_particleSystem = pSystem.GetBytes(); }
public void AddTextureAnimation(Primitive.TextureAnimation pTexAnim) { byte[] data = new byte[16]; int pos = 0; // The flags don't like conversion from uint to byte, so we have to do // it the crappy way. See the above function :( data[pos] = ConvertScriptUintToByte((uint)pTexAnim.Flags); pos++; data[pos] = (byte)pTexAnim.Face; pos++; data[pos] = (byte)pTexAnim.SizeX; pos++; data[pos] = (byte)pTexAnim.SizeY; pos++; Utils.FloatToBytes(pTexAnim.Start).CopyTo(data, pos); Utils.FloatToBytes(pTexAnim.Length).CopyTo(data, pos + 4); Utils.FloatToBytes(pTexAnim.Rate).CopyTo(data, pos + 8); m_TextureAnimation = data; }
// Convert a SceneObjectGroup into an instance with displayables public IPromise <BInstance> ConvertSogToInstance(SceneObjectGroup sog, IAssetFetcher assetFetcher, PrimToMesh mesher) { var prom = new Promise <BInstance>(); LogBProgress("{0} ConvertSogToInstance: name={1}, id={2}, SOPs={3}", _logHeader, sog.Name, sog.UUID, sog.Parts.Length); // Create meshes for all the parts of the SOG Promise <Displayable> .All( sog.Parts.Select(sop => { LogBProgress("{0} ConvertSOGToInstance: Calling CreateMeshResource for sog={1}, sop={2}", _logHeader, sog.UUID, sop.UUID); OMV.Primitive aPrim = sop.Shape.ToOmvPrimitive(); return(mesher.CreateMeshResource(sog, sop, aPrim, assetFetcher, OMVR.DetailLevel.Highest)); }) ) .Then(renderables => { // Remove any failed SOG/SOP conversions. List <Displayable> filteredRenderables = renderables.Where(rend => rend != null).ToList(); // 'filteredRenderables' are the DisplayRenderables for all the SOPs in the SOG // Get the root prim of the SOG List <Displayable> rootDisplayableList = filteredRenderables.Where(disp => { return(disp.baseSOP.IsRoot); }).ToList(); if (rootDisplayableList.Count != 1) { // There should be only one root prim ConvOAR.Globals.log.ErrorFormat("{0} ConvertSOGToInstance: Found not one root prim in SOG. ID={1}, numRoots={2}", _logHeader, sog.UUID, rootDisplayableList.Count); prom.Reject(new Exception(String.Format("Found more than one root prim in SOG. ID={0}", sog.UUID))); return(null); } // The root of the SOG Displayable rootDisplayable = rootDisplayableList.First(); // Collect all the children prims and add them to the root Displayable rootDisplayable.children = filteredRenderables.Where(disp => { return(!disp.baseSOP.IsRoot); }).Select(disp => { return(disp); }).ToList(); return(rootDisplayable); }) .Done(rootDisplayable => { // Add the Displayable into the collection of known Displayables for instancing assetFetcher.AddUniqueDisplayable(rootDisplayable); // Package the Displayable into an instance that is position in the world BInstance inst = new BInstance(); inst.Position = sog.AbsolutePosition; inst.Rotation = sog.GroupRotation; inst.Representation = rootDisplayable; if (ConvOAR.Globals.parms.P <bool>("LogBuilding")) { DumpInstance(inst); } prom.Resolve(inst); }, e => { ConvOAR.Globals.log.ErrorFormat("{0} Failed meshing of SOG. ID={1}: {2}", _logHeader, sog.UUID, e); prom.Reject(new Exception(String.Format("failed meshing of SOG. ID={0}: {1}", sog.UUID, e))); }); return(prom); }
public void DeletePrim(Primitive thePrim) { if (thePrim is Avatar) return; SimObject O = GetSimObject(thePrim); if (O != null) { SimObjects.Remove(O); SimRootObjects.Remove(O); SimChildObjects.Remove(O); SimAttachmentObjects.Remove(O); SimAvatars.Remove(O); SendOnRemoveSimObject(O); } uint objectLocalID = thePrim.LocalID; client.Inventory.RequestDeRezToInventory(objectLocalID, DeRezDestination.AgentInventoryTake, client.Inventory.FindFolderForType(AssetType.TrashFolder), UUID.Random()); }
public static new Avatar FromOSD(OSD O) { OSDMap tex = (OSDMap)O; Avatar A = new Avatar(); Primitive P = Primitive.FromOSD(O); Type Prim = typeof(Primitive); FieldInfo[] Fields = Prim.GetFields(); for (int x = 0; x < Fields.Length; x++) { Logger.Log("Field Matched in FromOSD: " + Fields[x].Name, Helpers.LogLevel.Debug); Fields[x].SetValue(A, Fields[x].GetValue(P)); } A.Groups = new List <UUID>(); foreach (OSD U in (OSDArray)tex["groups"]) { A.Groups.Add(U.AsUUID()); } A.ProfileStatistics = Statistics.FromOSD(tex["profile_statistics"]); A.ProfileProperties = AvatarProperties.FromOSD(tex["profile_properties"]); A.ProfileInterests = Interests.FromOSD(tex["profile_interest"]); A.ControlFlags = (AgentManager.ControlFlags)tex["control_flags"].AsInteger(); OSDArray vp = (OSDArray)tex["visual_parameters"]; A.VisualParameters = new byte[vp.Count]; for (int i = 0; i < vp.Count; i++) { A.VisualParameters[i] = (byte)vp[i].AsInteger(); } // *********************From Code Above ******************************* /*if (NameValues[i].Name == "FirstName" && NameValues[i].Type == NameValue.ValueType.String) * firstName = (string)NameValues[i].Value; * else if (NameValues[i].Name == "LastName" && NameValues[i].Type == NameValue.ValueType.String) * lastName = (string)NameValues[i].Value;*/ // ******************************************************************** A.NameValues = new NameValue[3]; NameValue First = new NameValue(); First.Name = "FirstName"; First.Type = NameValue.ValueType.String; First.Value = tex["first_name"].AsString(); NameValue Last = new NameValue(); Last.Name = "LastName"; Last.Type = NameValue.ValueType.String; Last.Value = tex["last_name"].AsString(); // ***************From Code Above*************** // if (NameValues[i].Name == "Title" && NameValues[i].Type == NameValue.ValueType.String) // ********************************************* NameValue Group = new NameValue(); Group.Name = "Title"; Group.Type = NameValue.ValueType.String; Group.Value = tex["group_name"].AsString(); A.NameValues[0] = First; A.NameValues[1] = Last; A.NameValues[2] = Group; return(A); }
/// <summary> /// Creates a OpenMetaverse.Primitive and populates it with converted PrimitiveBaseShape values /// </summary> /// <param name="position"></param> /// <param name="rotation"></param> /// <returns></returns> public Primitive ToOmvPrimitive(Vector3 position, Quaternion rotation) { OpenMetaverse.Primitive prim = new OpenMetaverse.Primitive(); prim.Scale = this.Scale; prim.Position = position; prim.Rotation = rotation; if (this.SculptEntry) { prim.Sculpt = new Primitive.SculptData(); prim.Sculpt.Type = (OpenMetaverse.SculptType) this.SculptType; prim.Sculpt.SculptTexture = this.SculptTexture; } prim.PrimData.PathShearX = this.PathShearX < 128 ? (float)this.PathShearX * 0.01f : (float)(this.PathShearX - 256) * 0.01f; prim.PrimData.PathShearY = this.PathShearY < 128 ? (float)this.PathShearY * 0.01f : (float)(this.PathShearY - 256) * 0.01f; prim.PrimData.PathBegin = (float)this.PathBegin * 2.0e-5f; prim.PrimData.PathEnd = 1.0f - (float)this.PathEnd * 2.0e-5f; prim.PrimData.PathScaleX = (200 - this.PathScaleX) * 0.01f; prim.PrimData.PathScaleY = (200 - this.PathScaleY) * 0.01f; prim.PrimData.PathTaperX = this.PathTaperX * 0.01f; prim.PrimData.PathTaperY = this.PathTaperY * 0.01f; prim.PrimData.PathTwistBegin = this.PathTwistBegin * 0.01f; prim.PrimData.PathTwist = this.PathTwist * 0.01f; prim.PrimData.ProfileBegin = (float)this.ProfileBegin * 2.0e-5f; prim.PrimData.ProfileEnd = 1.0f - (float)this.ProfileEnd * 2.0e-5f; prim.PrimData.ProfileHollow = (float)this.ProfileHollow * 2.0e-5f; prim.PrimData.profileCurve = this.ProfileCurve; prim.PrimData.ProfileHole = (HoleType)this.HollowShape; prim.PrimData.PathCurve = (PathCurve)this.PathCurve; prim.PrimData.PathRadiusOffset = 0.01f * this.PathRadiusOffset; prim.PrimData.PathRevolutions = 1.0f + 0.015f * this.PathRevolutions; prim.PrimData.PathSkew = 0.01f * this.PathSkew; prim.PrimData.PCode = OpenMetaverse.PCode.Prim; prim.PrimData.State = 0; if (this.FlexiEntry) { prim.Flexible = new Primitive.FlexibleData(); prim.Flexible.Drag = this.FlexiDrag; prim.Flexible.Force = new Vector3(this.FlexiForceX, this.FlexiForceY, this.FlexiForceZ); prim.Flexible.Gravity = this.FlexiGravity; prim.Flexible.Softness = this.FlexiSoftness; prim.Flexible.Tension = this.FlexiTension; prim.Flexible.Wind = this.FlexiWind; } if (this.LightEntry) { prim.Light = new Primitive.LightData(); prim.Light.Color = new Color4(this.LightColorR, this.LightColorG, this.LightColorB, this.LightColorA); prim.Light.Cutoff = this.LightCutoff; prim.Light.Falloff = this.LightFalloff; prim.Light.Intensity = this.LightIntensity; prim.Light.Radius = this.LightRadius; } prim.Textures = this.Textures; prim.Properties = new Primitive.ObjectProperties(); prim.Properties.Name = "Object"; prim.Properties.Description = ""; prim.Properties.CreatorID = UUID.Zero; prim.Properties.GroupID = UUID.Zero; prim.Properties.OwnerID = UUID.Zero; prim.Properties.Permissions = new Permissions(); prim.Properties.SalePrice = 10; prim.Properties.SaleType = new SaleType(); return(prim); }
private OMVR.FacetedMesh GenerateIRendererMesh(int numPrimFaces, OMV.Primitive prim, List <PrimMesher.ViewerFace> viewerFaces) { // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List <OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List <OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List <OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List <OMVR.PathPoint>(); Dictionary <OMV.Vector3, int> vertexAccount = new Dictionary <OMV.Vector3, int>(); OMV.Vector3 pos; int indx; OMVR.Vertex vert; for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List <OMVR.Vertex>(); oface.Indices = new List <ushort>(); if (prim.Textures == null) { oface.TextureFace = null; } else { oface.TextureFace = prim.Textures.GetFace((uint)ii); } int faceVertices = 0; vertexAccount.Clear(); foreach (PrimMesher.ViewerFace vface in viewerFaces) { if (vface.primFaceNumber == ii) { faceVertices++; pos = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv1.U, vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); vert.Normal.Normalize(); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv2.U, vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); vert.Normal.Normalize(); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv3.U, vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); vert.Normal.Normalize(); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } } } if (faceVertices > 0) { oface.TextureFace = null; if (prim.Textures != null) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return(omvrmesh); }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <param name="scupltTexture"></param> /// <param name="prim"></param> /// <param name="lod"></param> /// <returns>the faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateSculptMesh(System.Drawing.Bitmap scupltTexture, OMV.Primitive prim, OMVR.DetailLevel lod) { try { byte sculptType = (byte)prim.Sculpt.Type; bool mirror = ((sculptType & 128) != 0); bool invert = ((sculptType & 64) != 0); // bool mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems // bool invert = false; OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07); PrimMesher.SculptMesh.SculptType smSculptType; switch (omSculptType) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert); if (ShouldScaleMesh) { newMesh.Scale(prim.Scale.X, prim.Scale.Y, prim.Scale.Z); } int numPrimFaces = 1; // a scuplty has only one face return(GenerateIRendererMesh(numPrimFaces, prim, newMesh.viewerFaces)); } catch { // don't know why we're here but tell the caller nothing was meshed return(null); } }
/// <summary> /// Generates a a series of faces, each face containing a mesh and /// metadata /// </summary> /// <param name="prim">Primitive to generate the mesh from</param> /// <param name="lod">Level of detail to generate the mesh at</param> /// <returns>The generated mesh</returns > public OMVR.FacetedMesh GenerateFacetedMesh(OMV.Primitive prim, OMVR.DetailLevel lod) { bool isSphere = ((OMV.ProfileCurve)(prim.PrimData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle); PrimMesher.PrimMesh newPrim = GeneratePrimMesh(prim, lod, true); if (newPrim == null) { return(null); } int numViewerFaces = newPrim.viewerFaces.Count; int numPrimFaces = newPrim.numPrimFaces; for (uint i = 0; i < numViewerFaces; i++) { PrimMesher.ViewerFace vf = newPrim.viewerFaces[(int)i]; if (isSphere) { vf.uv1.U = (vf.uv1.U - 0.5f) * 2.0f; vf.uv2.U = (vf.uv2.U - 0.5f) * 2.0f; vf.uv3.U = (vf.uv3.U - 0.5f) * 2.0f; } } // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List <OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List <OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List <OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List <OMVR.PathPoint>(); Dictionary <OMV.Vector3, int> vertexAccount = new Dictionary <OMV.Vector3, int>(); for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List <OMVR.Vertex>(); oface.Indices = new List <ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = 0; vertexAccount.Clear(); OMV.Vector3 pos; int indx; OMVR.Vertex vert; foreach (PrimMesher.ViewerFace vface in newPrim.viewerFaces) { if (vface.primFaceNumber == ii) { faceVertices++; pos = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); if (vertexAccount.ContainsKey(pos)) { // we aleady have this vertex in the list. Just point the index at it oface.Indices.Add((ushort)vertexAccount[pos]); } else { // the vertex is not in the list. Add it and the new index. vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } pos = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); if (vertexAccount.ContainsKey(pos)) { oface.Indices.Add((ushort)vertexAccount[pos]); } else { vert = new OMVR.Vertex(); vert.Position = pos; vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); oface.Vertices.Add(vert); indx = oface.Vertices.Count - 1; vertexAccount.Add(pos, indx); oface.Indices.Add((ushort)indx); } } } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return(omvrmesh); }
private PrimMesher.PrimMesh GeneratePrimMesh(OMV.Primitive prim, OMVR.DetailLevel lod, bool viewerMode) { OMV.Primitive.ConstructionData primData = prim.PrimData; int sides = 4; int hollowsides = 4; float profileBegin = primData.ProfileBegin; float profileEnd = primData.ProfileEnd; if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.Circle) { switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } } else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.EqualTriangle) { sides = 3; } else if ((OMV.ProfileCurve)(primData.profileCurve & 0x07) == OMV.ProfileCurve.HalfCircle) { // half circle, prim is a sphere switch (lod) { case OMVR.DetailLevel.Low: sides = 6; break; case OMVR.DetailLevel.Medium: sides = 12; break; default: sides = 24; break; } profileBegin = 0.5f * profileBegin + 0.5f; profileEnd = 0.5f * profileEnd + 0.5f; } if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Same) { hollowsides = sides; } else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Circle) { switch (lod) { case OMVR.DetailLevel.Low: hollowsides = 6; break; case OMVR.DetailLevel.Medium: hollowsides = 12; break; default: hollowsides = 24; break; } } else if ((OMV.HoleType)primData.ProfileHole == OMV.HoleType.Triangle) { hollowsides = 3; } PrimMesher.PrimMesh newPrim = new PrimMesher.PrimMesh(sides, profileBegin, profileEnd, (float)primData.ProfileHollow, hollowsides); newPrim.viewerMode = viewerMode; newPrim.holeSizeX = primData.PathScaleX; newPrim.holeSizeY = primData.PathScaleY; newPrim.pathCutBegin = primData.PathBegin; newPrim.pathCutEnd = primData.PathEnd; newPrim.topShearX = primData.PathShearX; newPrim.topShearY = primData.PathShearY; newPrim.radius = primData.PathRadiusOffset; newPrim.revolutions = primData.PathRevolutions; newPrim.skew = primData.PathSkew; switch (lod) { case OMVR.DetailLevel.Low: newPrim.stepsPerRevolution = 6; break; case OMVR.DetailLevel.Medium: newPrim.stepsPerRevolution = 12; break; default: newPrim.stepsPerRevolution = 24; break; } if ((primData.PathCurve == OMV.PathCurve.Line) || (primData.PathCurve == OMV.PathCurve.Flexible)) { newPrim.taperX = 1.0f - primData.PathScaleX; newPrim.taperY = 1.0f - primData.PathScaleY; newPrim.twistBegin = (int)(180 * primData.PathTwistBegin); newPrim.twistEnd = (int)(180 * primData.PathTwist); newPrim.ExtrudeLinear(); } else { newPrim.taperX = primData.PathTaperX; newPrim.taperY = primData.PathTaperY; newPrim.twistBegin = (int)(360 * primData.PathTwistBegin); newPrim.twistEnd = (int)(360 * primData.PathTwist); newPrim.ExtrudeCircular(); } return(newPrim); }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <returns>The faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod) { PrimMesher.SculptMesh.SculptType smSculptType; switch (prim.Sculpt.Type) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, prim.Sculpt.Mirror, prim.Sculpt.Invert); int numPrimFaces = 1; // a scuplty has only one face // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List <OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List <OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List <OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List <OMVR.PathPoint>(); Dictionary <OMVR.Vertex, int> vertexAccount = new Dictionary <OMVR.Vertex, int>(); for (int ii = 0; ii < numPrimFaces; ii++) { vertexAccount.Clear(); OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List <OMVR.Vertex>(); oface.Indices = new List <ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = newMesh.coords.Count; OMVR.Vertex vert; for (int j = 0; j < faceVertices; j++) { vert = new OMVR.Vertex(); vert.Position = new Vector3(newMesh.coords[j].X, newMesh.coords[j].Y, newMesh.coords[j].Z); vert.Normal = new Vector3(newMesh.normals[j].X, newMesh.normals[j].Y, newMesh.normals[j].Z); vert.TexCoord = new Vector2(newMesh.uvs[j].U, newMesh.uvs[j].V); oface.Vertices.Add(vert); } for (int j = 0; j < newMesh.faces.Count; j++) { oface.Indices.Add((ushort)newMesh.faces[j].v1); oface.Indices.Add((ushort)newMesh.faces[j].v2); oface.Indices.Add((ushort)newMesh.faces[j].v3); } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return(omvrmesh); }
/// <summary> /// Set up appearance textures. /// Returns boolean that indicates whether the new entries actually change the /// existing values. /// </summary> public virtual bool SetTextureEntries(Primitive.TextureEntry textureEntry, out List<UUID> ChangedTextures) { ChangedTextures = new List<UUID>(); if (textureEntry == null) return false; // There are much simpler versions of this copy that could be // made. We determine if any of the textures actually // changed to know if the appearance should be saved later bool changed = false; for (uint i = 0; i < AvatarAppearance.TEXTURE_COUNT; i++) { Primitive.TextureEntryFace newface = textureEntry.FaceTextures[i]; Primitive.TextureEntryFace oldface = m_texture.FaceTextures[i]; if (newface == null) { if (oldface == null) continue; } else { if (oldface != null && oldface.TextureID == newface.TextureID) continue; } //Ignore the 0 based one... as its always null and causes issues if (i > 0) { changed = true; if (oldface != null) if (!ChangedTextures.Contains(oldface.TextureID)) ChangedTextures.Add(oldface.TextureID); // if (newface != null) // m_log.WarnFormat("[AVATAR APPEARANCE]: index {0}, new texture id {1}",i,newface.TextureID); } } if (changed) { Serial++; m_log.Debug("[Appearance]: Incrementing Serial (Textures) to " + Serial); } m_texture = textureEntry; return changed; }
//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); }
Matrix4 GetModelviewMatrix(Primitive prim) { Vector3 pos = prim.Position; Vector3 scale = prim.Scale; Quaternion rot = prim.Rotation; if (prim.ParentID != 0) { if (mRootPrims.ContainsKey(prim.ParentID)) { Primitive parent = mRootPrims[prim.ParentID]; rot = parent.Rotation * rot; pos = parent.Position + pos * parent.Rotation; } else Logger.Log(Name + ": root prim:" + prim.ParentID.ToString() + " not found", Helpers.LogLevel.Warning); } Matrix4 mat = Matrix4.CreateScale(scale); mat *= Matrix4.CreateFromQuaternion(rot); mat *= Matrix4.CreateTranslation(pos); return mat; }
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; } }
private String PovMesh(Primitive prim) { string s; FacetedMesh renderMesh = null; if (prim.Sculpt != null && prim.Sculpt.SculptTexture != UUID.Zero) { if (prim.Sculpt.Type == SculptType.Mesh) { byte[] meshData = GetMesh(prim.Sculpt.SculptTexture); if (meshData == null) return string.Empty; AssetMesh meshAsset = new AssetMesh(prim.Sculpt.SculptTexture, meshData); FacetedMesh.TryDecodeFromAsset(prim, meshAsset, DetailLevel.Highest, out renderMesh); meshAsset = null; } else // not a mesh, must be a sculptie { Image sculpt = GetImage(Client, prim.Sculpt.SculptTexture); if (sculpt == null) return string.Empty; renderMesh = m_primMesher.GenerateFacetedSculptMesh(prim, (Bitmap)sculpt, DetailLevel.Medium); sculpt.Dispose(); } } else renderMesh = m_primMesher.GenerateFacetedMesh(prim, DetailLevel.Highest); if (renderMesh == null) return string.Empty; Matrix4 mv = GetModelviewMatrix(prim); using (StringWriter sw = new StringWriter()) { for (int i = 0; i < renderMesh.Faces.Count; i++) { var face = renderMesh.Faces[i]; Primitive.TextureEntryFace tef = null; try { tef = prim.Textures.GetFace((uint)i); } catch (Exception) { continue; } int numVerts = face.Vertices.Count; int numIndices = face.Indices.Count; if (numVerts == 0 || numIndices == 0 || tef == null) continue; sw.WriteLine("mesh2"); sw.WriteLine("{"); sw.WriteLine("vertex_vectors"); sw.WriteLine("{"); sw.WriteLine(numVerts.ToString()); for (int vi = 0; vi < numVerts; vi++) { Vector3 v = face.Vertices[vi].Position; sw.WriteLine(PovVector3((v * mv) * 0.1f)); } sw.WriteLine("}"); // vertex_vectors sw.WriteLine("face_indices"); sw.WriteLine("{"); sw.WriteLine((numIndices / 3).ToString()); for (int ti = 0; ti < numIndices; ti += 3) sw.WriteLine(string.Format("<{0},{1},{2}>", face.Indices[ti], face.Indices[ti + 1], face.Indices[ti + 2])); sw.WriteLine("}"); // face_indices // material Color4 clr = tef.RGBA; if (tef.TextureID != null && mKnownTextures.ContainsKey(tef.TextureID)) { var texInfo = mKnownTextures[tef.TextureID]; if (texInfo != null) clr *= texInfo.MeanColor; } sw.WriteLine("pigment {rgbf "); sw.WriteLine(string.Format("<{0},{1},{2},{3}>", clr.R, clr.G, clr.B, 1.0f - clr.A)); sw.WriteLine("}"); //sw.WriteLine("pigment {rgb <1, 0.6, 0.6>}"); sw.WriteLine("}"); // mesh2 } s = sw.ToString(); } return s; }
public List <List <Vector3> > MeshSubMeshAsConvexHulls(OMV.Primitive prim, byte[] compressedMeshData) { List <List <Vector3> > hulls = new List <List <Vector3> >(); try { OSD convexBlockOsd = Helpers.DecompressOSD(compressedMeshData); if (convexBlockOsd is OSDMap convexBlock) { Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); if (convexBlock.ContainsKey("Min")) { min = convexBlock["Min"].AsVector3(); } Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); if (convexBlock.ContainsKey("Max")) { max = convexBlock["Max"].AsVector3(); } if (convexBlock.ContainsKey("BoundingVerts")) { byte[] boundingVertsBytes = convexBlock["BoundingVerts"].AsBinary(); var boundingHull = new List <Vector3>(); for (int i = 0; i < boundingVertsBytes.Length;) { ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2; Vector3 pos = new Vector3( Utils.UInt16ToFloat(uX, min.X, max.X), Utils.UInt16ToFloat(uY, min.Y, max.Y), Utils.UInt16ToFloat(uZ, min.Z, max.Z) ); boundingHull.Add(pos); } List <Vector3> mBoundingHull = boundingHull; } if (convexBlock.ContainsKey("HullList")) { byte[] hullList = convexBlock["HullList"].AsBinary(); byte[] posBytes = convexBlock["Positions"].AsBinary(); int posNdx = 0; foreach (byte cnt in hullList) { int count = cnt == 0 ? 256 : cnt; List <Vector3> hull = new List <Vector3>(); for (int i = 0; i < count; i++) { ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; Vector3 pos = new Vector3( Utils.UInt16ToFloat(uX, min.X, max.X), Utils.UInt16ToFloat(uY, min.Y, max.Y), Utils.UInt16ToFloat(uZ, min.Z, max.Z) ); hull.Add(pos); } hulls.Add(hull); } } } } catch (Exception) { // Logger.Log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e); } return(hulls); }
public virtual void SetAppearance(Primitive.TextureEntry textureEntry, byte[] visualParams) { List<UUID> Changed = new List<UUID>(); SetTextureEntries(textureEntry, out Changed); SetVisualParams(visualParams); }
/// <summary> /// Create a sculpty faceted mesh. The actual scuplt texture is fetched and passed to this /// routine since all the context for finding teh texture is elsewhere. /// </summary> /// <returns>The faceted mesh or null if can't do it</returns> public OMVR.FacetedMesh GenerateFacetedSculptMesh(OMV.Primitive prim, System.Drawing.Bitmap scupltTexture, OMVR.DetailLevel lod) { byte sculptType = (byte)prim.Sculpt.Type; bool mirror = ((sculptType & 128) != 0); bool invert = ((sculptType & 64) != 0); // mirror = false; // TODO: libomv doesn't support these and letting them flop around causes problems // invert = false; OMV.SculptType omSculptType = (OMV.SculptType)(sculptType & 0x07); PrimMesher.SculptMesh.SculptType smSculptType; switch (omSculptType) { case OpenMetaverse.SculptType.Cylinder: smSculptType = PrimMesher.SculptMesh.SculptType.cylinder; break; case OpenMetaverse.SculptType.Plane: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; case OpenMetaverse.SculptType.Sphere: smSculptType = PrimMesher.SculptMesh.SculptType.sphere; break; case OpenMetaverse.SculptType.Torus: smSculptType = PrimMesher.SculptMesh.SculptType.torus; break; default: smSculptType = PrimMesher.SculptMesh.SculptType.plane; break; } // The lod for sculpties is the resolution of the texture passed. // The first guess is 1:1 then lower resolutions after that // int mesherLod = (int)Math.Sqrt(scupltTexture.Width * scupltTexture.Height); int mesherLod = 32; // number used in Idealist viewer switch (lod) { case OMVR.DetailLevel.Highest: break; case OMVR.DetailLevel.High: break; case OMVR.DetailLevel.Medium: mesherLod /= 2; break; case OMVR.DetailLevel.Low: mesherLod /= 4; break; } PrimMesher.SculptMesh newMesh = new PrimMesher.SculptMesh(scupltTexture, smSculptType, mesherLod, true, mirror, invert); int numPrimFaces = 1; // a scuplty has only one face // copy the vertex information into OMVR.IRendering structures OMVR.FacetedMesh omvrmesh = new OMVR.FacetedMesh(); omvrmesh.Faces = new List <OMVR.Face>(); omvrmesh.Prim = prim; omvrmesh.Profile = new OMVR.Profile(); omvrmesh.Profile.Faces = new List <OMVR.ProfileFace>(); omvrmesh.Profile.Positions = new List <OMV.Vector3>(); omvrmesh.Path = new OMVR.Path(); omvrmesh.Path.Points = new List <OMVR.PathPoint>(); for (int ii = 0; ii < numPrimFaces; ii++) { OMVR.Face oface = new OMVR.Face(); oface.Vertices = new List <OMVR.Vertex>(); oface.Indices = new List <ushort>(); oface.TextureFace = prim.Textures.GetFace((uint)ii); int faceVertices = 0; foreach (PrimMesher.ViewerFace vface in newMesh.viewerFaces) { OMVR.Vertex vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v1.X, vface.v1.Y, vface.v1.Z); vert.TexCoord = new OMV.Vector2(vface.uv1.U, 1.0f - vface.uv1.V); vert.Normal = new OMV.Vector3(vface.n1.X, vface.n1.Y, vface.n1.Z); oface.Vertices.Add(vert); vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v2.X, vface.v2.Y, vface.v2.Z); vert.TexCoord = new OMV.Vector2(vface.uv2.U, 1.0f - vface.uv2.V); vert.Normal = new OMV.Vector3(vface.n2.X, vface.n2.Y, vface.n2.Z); oface.Vertices.Add(vert); vert = new OMVR.Vertex(); vert.Position = new OMV.Vector3(vface.v3.X, vface.v3.Y, vface.v3.Z); vert.TexCoord = new OMV.Vector2(vface.uv3.U, 1.0f - vface.uv3.V); vert.Normal = new OMV.Vector3(vface.n3.X, vface.n3.Y, vface.n3.Z); oface.Vertices.Add(vert); oface.Indices.Add((ushort)(faceVertices * 3 + 0)); oface.Indices.Add((ushort)(faceVertices * 3 + 1)); oface.Indices.Add((ushort)(faceVertices * 3 + 2)); faceVertices++; } if (faceVertices > 0) { oface.TextureFace = prim.Textures.FaceTextures[ii]; if (oface.TextureFace == null) { oface.TextureFace = prim.Textures.DefaultTexture; } oface.ID = ii; omvrmesh.Faces.Add(oface); } } return(omvrmesh); }