public CreateFace ( uint index ) : TextureEntryFace | ||
index | uint | The index number of the face to create or /// retrieve |
return | TextureEntryFace |
public void TestCreate() { TestHelper.InMethod(); // log4net.Config.XmlConfigurator.Configure(); IConfigSource config = new IniConfigSource(); config.AddConfig("NPC"); config.Configs["NPC"].Set("Enabled", "true"); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = SceneSetupHelpers.SetupScene(); SceneSetupHelpers.SetupSceneModules(scene, config, afm, new NPCModule()); TestClient originalClient = SceneSetupHelpers.AddClient(scene, TestHelper.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance UUID originalFace8TextureId = TestHelper.ParseTail(0x10); Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); originalTef.TextureID = originalFace8TextureId; // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateAsset(originalFace8TextureId)); afm.SetAppearance(originalClient, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, originalClient.AgentId); ScenePresence npc = scene.GetScenePresence(npcId); Assert.That(npc, Is.Not.Null); Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); }
public void TestSetAppearance() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); UUID bakedTextureID = TestHelpers.ParseTail(0x2); // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly // to the AssetService, which will then store temporary and local assets permanently CoreAssetCache assetCache = new CoreAssetCache(); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = new SceneHelpers(assetCache).SetupScene(); SceneHelpers.SetupSceneModules(scene, afm); ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules AssetBase bakedTextureAsset; bakedTextureAsset = new AssetBase( bakedTextureID, "Test Baked Texture", (sbyte)AssetType.Texture, userId.ToString()); bakedTextureAsset.Data = new byte[] { 2 }; // Not necessary to have a genuine JPEG2000 asset here yet bakedTextureAsset.Temporary = true; bakedTextureAsset.Local = true; scene.AssetService.Store(bakedTextureAsset); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)); uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes); Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); int rebakeRequestsReceived = 0; ((TestClient)sp.ControllingClient).OnReceivedSendRebakeAvatarTextures += id => rebakeRequestsReceived++; // This is the alpha texture eyesFace.TextureID = bakedTextureID; afm.SetAppearance(sp, bakedTextureEntry, visualParams, null); Assert.That(rebakeRequestsReceived, Is.EqualTo(0)); AssetBase eyesBake = scene.AssetService.Get(bakedTextureID.ToString()); Assert.That(eyesBake, Is.Not.Null); Assert.That(eyesBake.Temporary, Is.True); Assert.That(eyesBake.Local, Is.True); }
public string RenderMaterialsPostCap(string request, UUID agentID) { OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request); OSDMap resp = new OSDMap(); OSDMap materialsFromViewer = null; OSDArray respArr = new OSDArray(); if (req.ContainsKey("Zipped")) { OSD osd = null; byte[] inBytes = req["Zipped"].AsBinary(); try { osd = ZDecompressBytesToOsd(inBytes); if (osd != null) { if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries { foreach (OSD elem in (OSDArray)osd) { try { UUID id = new UUID(elem.AsBinary(), 0); lock (m_regionMaterials) { if (m_regionMaterials.ContainsKey(id)) { OSDMap matMap = new OSDMap(); matMap["ID"] = OSD.FromBinary(id.GetBytes()); matMap["Material"] = m_regionMaterials[id]; respArr.Add(matMap); } else { m_log.Warn("[Materials]: request for unknown material ID: " + id.ToString()); // Theoretically we could try to load the material from the assets service, // but that shouldn't be necessary because the viewer should only request // materials that exist in a prim on the region, and all of these materials // are already stored in m_regionMaterials. } } } catch (Exception e) { m_log.Error("Error getting materials in response to viewer request", e); continue; } } } else if (osd is OSDMap) // request to assign a material { materialsFromViewer = osd as OSDMap; if (materialsFromViewer.ContainsKey("FullMaterialsPerFace")) { OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"]; if (matsOsd is OSDArray) { OSDArray matsArr = matsOsd as OSDArray; try { foreach (OSDMap matsMap in matsArr) { uint primLocalID = 0; try { primLocalID = matsMap["ID"].AsUInteger(); } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"ID\" from matsMap: " + e.Message); continue; } OSDMap mat = null; try { mat = matsMap["Material"] as OSDMap; } catch (Exception e) { m_log.Warn("[Materials]: cannot decode \"Material\" from matsMap: " + e.Message); continue; } SceneObjectPart sop = m_scene.GetSceneObjectPart(primLocalID); if (sop == null) { m_log.WarnFormat("[Materials]: SOP not found for localId: {0}", primLocalID.ToString()); continue; } if (!m_scene.Permissions.CanEditObject(sop.UUID, agentID)) { m_log.WarnFormat("User {0} can't edit object {1} {2}", agentID, sop.Name, sop.UUID); continue; } Primitive.TextureEntry te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.WarnFormat("[Materials]: Error in TextureEntry for SOP {0} {1}", sop.Name, sop.UUID); continue; } UUID id; if (mat == null) { // This happens then the user removes a material from a prim id = UUID.Zero; } else { id = StoreMaterialAsAsset(agentID, mat, sop); } int face = -1; if (matsMap.ContainsKey("Face")) { face = matsMap["Face"].AsInteger(); Primitive.TextureEntryFace faceEntry = te.CreateFace((uint)face); faceEntry.MaterialID = id; } else { if (te.DefaultTexture == null) m_log.WarnFormat("[Materials]: TextureEntry.DefaultTexture is null in {0} {1}", sop.Name, sop.UUID); else te.DefaultTexture.MaterialID = id; } //m_log.DebugFormat("[Materials]: in \"{0}\" {1}, setting material ID for face {2} to {3}", sop.Name, sop.UUID, face, id); // We can't use sop.UpdateTextureEntry(te) because it filters, so do it manually sop.Shape.TextureEntry = te.GetBytes(); if (sop.ParentGroup != null) { sop.TriggerScriptChangedEvent(Changed.TEXTURE); sop.UpdateFlag = UpdateRequired.FULL; sop.ParentGroup.HasGroupChanged = true; sop.ScheduleFullUpdate(); } } } catch (Exception e) { m_log.Warn("[Materials]: exception processing received material ", e); } } } } } } catch (Exception e) { m_log.Warn("[Materials]: exception decoding zipped CAP payload ", e); //return ""; } } resp["Zipped"] = ZCompressOSD(respArr, false); string response = OSDParser.SerializeLLSDXmlString(resp); //m_log.Debug("[Materials]: cap request: " + request); //m_log.Debug("[Materials]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary())); //m_log.Debug("[Materials]: cap response: " + response); return response; }
/// <summary> /// Parses add request /// </summary> /// <param name="request"></param> /// <param name="AgentId"></param> /// <param name="cap"></param> /// <returns></returns> public Hashtable ProcessAdd(Hashtable request, UUID AgentId, Caps cap) { Hashtable responsedata = new Hashtable(); responsedata["int_response_code"] = 400; //501; //410; //404; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "Request wasn't what was expected"; ScenePresence avatar; if (!m_scene.TryGetScenePresence(AgentId, out avatar)) return responsedata; OSDMap r = (OSDMap)OSDParser.Deserialize((string)request["requestbody"]); UploadObjectAssetMessage message = new UploadObjectAssetMessage(); try { message.Deserialize(r); } catch (Exception ex) { m_log.Error("[UPLOAD OBJECT ASSET MODULE]: Error deserializing message " + ex.ToString()); message = null; } if (message == null) { responsedata["int_response_code"] = 400; //501; //410; //404; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>"; return responsedata; } Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX * avatar.Rotation); Quaternion rot = Quaternion.Identity; Vector3 rootpos = Vector3.Zero; // Quaternion rootrot = Quaternion.Identity; SceneObjectGroup rootGroup = null; SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length]; for (int i = 0; i < message.Objects.Length; i++) { UploadObjectAssetMessage.Object obj = message.Objects[i]; PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); if (i == 0) { rootpos = obj.Position; // rootrot = obj.Rotation; } // Combine the extraparams data into it's ugly blob again.... //int bytelength = 0; //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) //{ // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length; //} //byte[] extraparams = new byte[bytelength]; //int position = 0; //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) //{ // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position, // obj.ExtraParams[extparams].ExtraParamData.Length); // // position += obj.ExtraParams[extparams].ExtraParamData.Length; // } //pbs.ExtraParams = extraparams; for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) { UploadObjectAssetMessage.Object.ExtraParam extraParam = obj.ExtraParams[extparams]; switch ((ushort)extraParam.Type) { case (ushort)ExtraParamType.Sculpt: Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0); pbs.SculptEntry = true; pbs.SculptTexture = obj.SculptID; pbs.SculptType = (byte)sculpt.Type; break; case (ushort)ExtraParamType.Flexible: Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0); pbs.FlexiEntry = true; pbs.FlexiDrag = flex.Drag; pbs.FlexiForceX = flex.Force.X; pbs.FlexiForceY = flex.Force.Y; pbs.FlexiForceZ = flex.Force.Z; pbs.FlexiGravity = flex.Gravity; pbs.FlexiSoftness = flex.Softness; pbs.FlexiTension = flex.Tension; pbs.FlexiWind = flex.Wind; break; case (ushort)ExtraParamType.Light: Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0); pbs.LightColorA = light.Color.A; pbs.LightColorB = light.Color.B; pbs.LightColorG = light.Color.G; pbs.LightColorR = light.Color.R; pbs.LightCutoff = light.Cutoff; pbs.LightEntry = true; pbs.LightFalloff = light.Falloff; pbs.LightIntensity = light.Intensity; pbs.LightRadius = light.Radius; break; case 0x40: pbs.ReadProjectionData(extraParam.ExtraParamData, 0); break; } } pbs.PathBegin = (ushort) obj.PathBegin; pbs.PathCurve = (byte) obj.PathCurve; pbs.PathEnd = (ushort) obj.PathEnd; pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset; pbs.PathRevolutions = (byte) obj.Revolutions; pbs.PathScaleX = (byte) obj.ScaleX; pbs.PathScaleY = (byte) obj.ScaleY; pbs.PathShearX = (byte) obj.ShearX; pbs.PathShearY = (byte) obj.ShearY; pbs.PathSkew = (sbyte) obj.Skew; pbs.PathTaperX = (sbyte) obj.TaperX; pbs.PathTaperY = (sbyte) obj.TaperY; pbs.PathTwist = (sbyte) obj.Twist; pbs.PathTwistBegin = (sbyte) obj.TwistBegin; pbs.HollowShape = (HollowShape) obj.ProfileHollow; pbs.PCode = (byte) PCode.Prim; pbs.ProfileBegin = (ushort) obj.ProfileBegin; pbs.ProfileCurve = (byte) obj.ProfileCurve; pbs.ProfileEnd = (ushort) obj.ProfileEnd; pbs.Scale = obj.Scale; pbs.State = (byte) 0; pbs.LastAttachPoint = (byte) 0; SceneObjectPart prim = new SceneObjectPart(); prim.UUID = UUID.Random(); prim.CreatorID = AgentId; prim.OwnerID = AgentId; prim.GroupID = obj.GroupID; prim.LastOwnerID = prim.OwnerID; prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.Name = obj.Name; prim.Description = ""; prim.PayPrice[0] = -2; prim.PayPrice[1] = -2; prim.PayPrice[2] = -2; prim.PayPrice[3] = -2; prim.PayPrice[4] = -2; Primitive.TextureEntry tmp = new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f")); for (int j = 0; j < obj.Faces.Length; j++) { UploadObjectAssetMessage.Object.Face face = obj.Faces[j]; Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j); primFace.Bump = face.Bump; primFace.RGBA = face.Color; primFace.Fullbright = face.Fullbright; primFace.Glow = face.Glow; primFace.TextureID = face.ImageID; primFace.Rotation = face.ImageRot; primFace.MediaFlags = ((face.MediaFlags & 1) != 0); primFace.OffsetU = face.OffsetS; primFace.OffsetV = face.OffsetT; primFace.RepeatU = face.ScaleS; primFace.RepeatV = face.ScaleT; primFace.TexMapType = (MappingType) (face.MediaFlags & 6); } pbs.TextureEntry = tmp.GetBytes(); prim.Shape = pbs; prim.Scale = obj.Scale; SceneObjectGroup grp = new SceneObjectGroup(); grp.SetRootPart(prim); prim.ParentID = 0; if (i == 0) { rootGroup = grp; } grp.AttachToScene(m_scene); grp.AbsolutePosition = obj.Position; prim.RotationOffset = obj.Rotation; // Required for linking grp.RootPart.ClearUpdateSchedule(); if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos)) { m_scene.AddSceneObject(grp); grp.AbsolutePosition = obj.Position; } allparts[i] = grp; } for (int j = 1; j < allparts.Length; j++) { // Required for linking rootGroup.RootPart.ClearUpdateSchedule(); allparts[j].RootPart.ClearUpdateSchedule(); rootGroup.LinkToGroup(allparts[j]); } rootGroup.ScheduleGroupForFullUpdate(); pos = m_scene.GetNewRezLocation( Vector3.Zero, rootpos, UUID.Zero, rot, (byte)1, 1, true, allparts[0].GroupScale, false); responsedata["int_response_code"] = 200; //501; //410; //404; responsedata["content_type"] = "text/plain"; responsedata["keepalive"] = false; responsedata["str_response_string"] = String.Format("<llsd><map><key>local_id</key>{0}</map></llsd>", ConvertUintToBytes(allparts[0].LocalId)); return responsedata; }
public void TestCreate() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); originalTef.TextureID = originalFace8TextureId; // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); afm.SetAppearance(sp, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); UUID npcId = npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), scene, sp.Appearance); ScenePresence npc = scene.GetScenePresence(npcId); Assert.That(npc, Is.Not.Null); Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); Assert.That(umm.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname))); }
private void TestAddRemoveNPCs(int numberOfNpcs) { ScenePresence sp = SceneHelpers.AddScenePresence(scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); originalTef.TextureID = originalFace8TextureId; // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell // ScenePresence.SendInitialData() to reset our entire appearance. scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); afm.SetAppearance(sp, originalTe, null); INPCModule npcModule = scene.RequestModuleInterface<INPCModule>(); List<UUID> npcs = new List<UUID>(); long startGcMemory = GC.GetTotalMemory(true); Stopwatch sw = new Stopwatch(); sw.Start(); for (int i = 0; i < numberOfNpcs; i++) { npcs.Add( npcModule.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, scene, sp.Appearance)); } for (int i = 0; i < numberOfNpcs; i++) { Assert.That(npcs[i], Is.Not.Null); ScenePresence npc = scene.GetScenePresence(npcs[i]); Assert.That(npc, Is.Not.Null); } for (int i = 0; i < numberOfNpcs; i++) { Assert.That(npcModule.DeleteNPC(npcs[i], scene), Is.True); ScenePresence npc = scene.GetScenePresence(npcs[i]); Assert.That(npc, Is.Null); } sw.Stop(); long endGcMemory = GC.GetTotalMemory(true); Console.WriteLine("Took {0} ms", sw.ElapsedMilliseconds); Console.WriteLine( "End {0} MB, Start {1} MB, Diff {2} MB", endGcMemory / 1024 / 1024, startGcMemory / 1024 / 1024, (endGcMemory - startGcMemory) / 1024 / 1024); }
public void TextureEntry() { Primitive.TextureEntry te = new Primitive.TextureEntry(UUID.Random()); Primitive.TextureEntryFace face = te.CreateFace(0); face.Bump = Bumpiness.Concrete; face.Fullbright = true; face.MediaFlags = true; face.OffsetU = 0.5f; face.OffsetV = -0.5f; face.RepeatU = 3.0f; face.RepeatV = 4.0f; face.RGBA = new Color4(0f, 0.25f, 0.75f, 1f); face.Rotation = 1.5f; face.Shiny = Shininess.Medium; face.TexMapType = MappingType.Planar; face.TextureID = UUID.Random(); byte[] teBytes = te.GetBytes(); Primitive.TextureEntry te2 = new Primitive.TextureEntry(teBytes, 0, teBytes.Length); byte[] teBytes2 = te2.GetBytes(); Assert.IsTrue(teBytes.Length == teBytes2.Length); for (int i = 0; i < teBytes.Length; i++) { Assert.IsTrue(teBytes[i] == teBytes2[i], "Byte " + i + " is not equal"); } }
/// <summary> /// Assign a single material value. Based on the values passed we'll either set (or clear) the materials for a SOP. /// </summary> /// <param name="sop">The SOP being affected.</param> /// <param name="face">The face to assign, or -1 if the default texture is being set.</param> /// <param name="id">The ID assigned to this material. Setting a Zero UUID clears it.</param> /// <param name="material">If not null, the material to set. Otherwise we are clearing.</param> private void AssignSingleMaterial(SceneObjectPart sop, int face, OSDMap matData) { UUID id = UUID.Zero; // If there is a material being set, see if we've seen it before. // If not we'll add it to the Shape RenderMaterials and the region cache if (matData != null) { RenderMaterial material = RenderMaterial.FromOSD(matData); id = sop.Shape.RenderMaterials.AddMaterial(material); m_scene.EventManager.TriggerRenderMaterialAddedToPrim(sop, id, material); m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Adding RenderMaterial {2}", sop.LocalId, face, material.ToString()); } // If the new material is replacing one lets record it so we can clean up UUID oldMaterialID = UUID.Zero; /// Get a copy of the texture entry so we can make changes. var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); // Set the Material ID in the TextureEntry. If face is ALL_SIDES then // set the default entry, otherwise fetch the face and set it there. if (face < 0) { oldMaterialID = te.DefaultTexture.MaterialID; te.DefaultTexture.MaterialID = id; } else { var faceEntry = te.CreateFace((uint)face); oldMaterialID = faceEntry.MaterialID; faceEntry.MaterialID = id; } // Update the texture entry which will force an update to connected clients sop.UpdateTexture(te); // If the material has changed and it wasn't previously Zero // Deallocate the old value if its not in use and signal the change if ((oldMaterialID != id) && (oldMaterialID != UUID.Zero)) { var currentMaterialIDs = sop.Shape.GetMaterialIDs(); if (currentMaterialIDs.Contains(oldMaterialID) == false) { if (sop.Shape.RenderMaterials.ContainsMaterial(oldMaterialID) == true) sop.Shape.RenderMaterials.RemoveMaterial(oldMaterialID); m_scene.EventManager.TriggerRenderMaterialRemovedFromPrim(sop, oldMaterialID); } } }
/// <summary> /// Parses ad request /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <param name="AgentId"></param> /// <returns></returns> public byte[] ProcessAdd(Stream request, OSHttpResponse response, UUID AgentId) { IScenePresence avatar; if (!m_scene.TryGetScenePresence(AgentId, out avatar)) return MainServer.BlankResponse; OSDMap r = (OSDMap) OSDParser.Deserialize(HttpServerHandlerHelpers.ReadFully(request)); UploadObjectAssetMessage message = new UploadObjectAssetMessage(); try { message.Deserialize(r); } catch (Exception ex) { MainConsole.Instance.Error("[UploadObjectAssetModule]: Error deserializing message " + ex); message = null; } if (message == null) { response.StatusCode = 400; //501; //410; //404; return Encoding.UTF8.GetBytes( "<llsd><map><key>error</key><string>Error parsing Object</string></map></llsd>"); } Vector3 pos = avatar.AbsolutePosition + (Vector3.UnitX*avatar.Rotation); Quaternion rot = Quaternion.Identity; Vector3 rootpos = Vector3.Zero; SceneObjectGroup rootGroup = null; SceneObjectGroup[] allparts = new SceneObjectGroup[message.Objects.Length]; for (int i = 0; i < message.Objects.Length; i++) { UploadObjectAssetMessage.Object obj = message.Objects[i]; PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); if (i == 0) { rootpos = obj.Position; } // Combine the extraparams data into it's ugly blob again.... //int bytelength = 0; //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) //{ // bytelength += obj.ExtraParams[extparams].ExtraParamData.Length; //} //byte[] extraparams = new byte[bytelength]; //int position = 0; //for (int extparams = 0; extparams < obj.ExtraParams.Length; extparams++) //{ // Buffer.BlockCopy(obj.ExtraParams[extparams].ExtraParamData, 0, extraparams, position, // obj.ExtraParams[extparams].ExtraParamData.Length); // // position += obj.ExtraParams[extparams].ExtraParamData.Length; // } //pbs.ExtraParams = extraparams; foreach (UploadObjectAssetMessage.Object.ExtraParam extraParam in obj.ExtraParams) { switch ((ushort) extraParam.Type) { case (ushort) ExtraParamType.Sculpt: Primitive.SculptData sculpt = new Primitive.SculptData(extraParam.ExtraParamData, 0); pbs.SculptEntry = true; pbs.SculptTexture = obj.SculptID; pbs.SculptType = (byte) sculpt.Type; break; case (ushort) ExtraParamType.Flexible: Primitive.FlexibleData flex = new Primitive.FlexibleData(extraParam.ExtraParamData, 0); pbs.FlexiEntry = true; pbs.FlexiDrag = flex.Drag; pbs.FlexiForceX = flex.Force.X; pbs.FlexiForceY = flex.Force.Y; pbs.FlexiForceZ = flex.Force.Z; pbs.FlexiGravity = flex.Gravity; pbs.FlexiSoftness = flex.Softness; pbs.FlexiTension = flex.Tension; pbs.FlexiWind = flex.Wind; break; case (ushort) ExtraParamType.Light: Primitive.LightData light = new Primitive.LightData(extraParam.ExtraParamData, 0); pbs.LightColorA = light.Color.A; pbs.LightColorB = light.Color.B; pbs.LightColorG = light.Color.G; pbs.LightColorR = light.Color.R; pbs.LightCutoff = light.Cutoff; pbs.LightEntry = true; pbs.LightFalloff = light.Falloff; pbs.LightIntensity = light.Intensity; pbs.LightRadius = light.Radius; break; case 0x40: pbs.ReadProjectionData(extraParam.ExtraParamData, 0); break; } } pbs.PathBegin = (ushort) obj.PathBegin; pbs.PathCurve = (byte) obj.PathCurve; pbs.PathEnd = (ushort) obj.PathEnd; pbs.PathRadiusOffset = (sbyte) obj.RadiusOffset; pbs.PathRevolutions = (byte) obj.Revolutions; pbs.PathScaleX = (byte) obj.ScaleX; pbs.PathScaleY = (byte) obj.ScaleY; pbs.PathShearX = (byte) obj.ShearX; pbs.PathShearY = (byte) obj.ShearY; pbs.PathSkew = (sbyte) obj.Skew; pbs.PathTaperX = (sbyte) obj.TaperX; pbs.PathTaperY = (sbyte) obj.TaperY; pbs.PathTwist = (sbyte) obj.Twist; pbs.PathTwistBegin = (sbyte) obj.TwistBegin; pbs.HollowShape = (HollowShape) obj.ProfileHollow; pbs.PCode = (byte) PCode.Prim; pbs.ProfileBegin = (ushort) obj.ProfileBegin; pbs.ProfileCurve = (byte) obj.ProfileCurve; pbs.ProfileEnd = (ushort) obj.ProfileEnd; pbs.Scale = obj.Scale; pbs.State = 0; SceneObjectPart prim = new SceneObjectPart(AgentId, pbs, obj.Position, obj.Rotation, Vector3.Zero, obj.Name) { UUID = UUID.Random(), CreatorID = AgentId, OwnerID = AgentId, GroupID = obj.GroupID }; prim.LastOwnerID = prim.OwnerID; prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.Name = obj.Name; prim.Description = ""; prim.PayPrice[0] = -2; prim.PayPrice[1] = -2; prim.PayPrice[2] = -2; prim.PayPrice[3] = -2; prim.PayPrice[4] = -2; Primitive.TextureEntry tmp = new Primitive.TextureEntry(UUID.Parse("89556747-24cb-43ed-920b-47caed15465f")); for (int j = 0; j < obj.Faces.Length; j++) { UploadObjectAssetMessage.Object.Face face = obj.Faces[j]; Primitive.TextureEntryFace primFace = tmp.CreateFace((uint) j); primFace.Bump = face.Bump; primFace.RGBA = face.Color; primFace.Fullbright = face.Fullbright; primFace.Glow = face.Glow; primFace.TextureID = face.ImageID; primFace.Rotation = face.ImageRot; primFace.MediaFlags = ((face.MediaFlags & 1) != 0); primFace.OffsetU = face.OffsetS; primFace.OffsetV = face.OffsetT; primFace.RepeatU = face.ScaleS; primFace.RepeatV = face.ScaleT; primFace.TexMapType = (MappingType) (face.MediaFlags & 6); } pbs.TextureEntry = tmp.GetBytes(); prim.Shape = pbs; prim.Scale = obj.Scale; SceneObjectGroup grp = new SceneObjectGroup(prim, m_scene); prim.ParentID = 0; if (i == 0) rootGroup = grp; grp.AbsolutePosition = obj.Position; prim.SetRotationOffset(true, obj.Rotation, true); grp.RootPart.IsAttachment = false; string reason; if (m_scene.Permissions.CanRezObject(1, avatar.UUID, pos, out reason)) { m_scene.SceneGraph.AddPrimToScene(grp); grp.AbsolutePosition = obj.Position; } else { //Stop now then avatar.ControllingClient.SendAlertMessage("You do not have permission to rez objects here: " + reason); return MainServer.BlankResponse; } allparts[i] = grp; } for (int j = 1; j < allparts.Length; j++) { rootGroup.LinkToGroup(allparts[j]); } rootGroup.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); pos = m_scene.SceneGraph.GetNewRezLocation(Vector3.Zero, rootpos, UUID.Zero, rot, 1, 1, true, allparts[0].GroupScale(), false); OSDMap map = new OSDMap(); map["local_id"] = allparts[0].LocalId; return OSDParser.SerializeLLSDXmlBytes(map); }
public void TestCreate() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); ScenePresence sp = SceneHelpers.AddScenePresence(m_scene, TestHelpers.ParseTail(0x1)); // ScenePresence originalAvatar = scene.GetScenePresence(originalClient.AgentId); // 8 is the index of the first baked texture in AvatarAppearance UUID originalFace8TextureId = TestHelpers.ParseTail(0x10); Primitive.TextureEntry originalTe = new Primitive.TextureEntry(UUID.Zero); Primitive.TextureEntryFace originalTef = originalTe.CreateFace(8); originalTef.TextureID = originalFace8TextureId; // We also need to add the texture to the asset service, otherwise the AvatarFactoryModule will tell // ScenePresence.SendInitialData() to reset our entire appearance. m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId)); m_afMod.SetAppearance(sp, originalTe, null, null); UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance); ScenePresence npc = m_scene.GetScenePresence(npcId); Assert.That(npc, Is.Not.Null); Assert.That(npc.Appearance.Texture.FaceTextures[8].TextureID, Is.EqualTo(originalFace8TextureId)); Assert.That(m_umMod.GetUserName(npc.UUID), Is.EqualTo(string.Format("{0} {1}", npc.Firstname, npc.Lastname))); IClientAPI client; Assert.That(m_scene.TryGetClient(npcId, out client), Is.True); // Have to account for both SP and NPC. Assert.That(m_scene.AuthenticateHandler.GetAgentCircuits().Count, Is.EqualTo(2)); }
/// <summary> /// Set the color of prim faces /// </summary> /// <param name="color"></param> /// <param name="face"></param> public void SetFaceColor(Vector3 color, int face) { // The only way to get a deep copy/ If we don't do this, we can // mever detect color changes further down. Byte[] buf = Shape.Textures.GetBytes(); Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); Color4 texcolor; if (face >= 0 && face < GetNumberOfSides()) { texcolor = tex.CreateFace((uint)face).RGBA; texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); tex.FaceTextures[face].RGBA = texcolor; UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ALL_SIDES) { for (uint i = 0; i < GetNumberOfSides(); i++) { if (tex.FaceTextures[i] != null) { texcolor = tex.FaceTextures[i].RGBA; texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); tex.FaceTextures[i].RGBA = texcolor; } texcolor = tex.DefaultTexture.RGBA; texcolor.R = Util.Clip((float)color.X, 0.0f, 1.0f); texcolor.G = Util.Clip((float)color.Y, 0.0f, 1.0f); texcolor.B = Util.Clip((float)color.Z, 0.0f, 1.0f); tex.DefaultTexture.RGBA = texcolor; } UpdateTextureEntry(tex.GetBytes()); return; } }
public static Primitive.TextureEntry GetDefaultTexture() { Primitive.TextureEntry textu = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); textu.CreateFace(0).TextureID = new UUID("00000000-0000-1111-9999-000000000012"); textu.CreateFace(1).TextureID = Util.BLANK_TEXTURE_UUID; textu.CreateFace(2).TextureID = Util.BLANK_TEXTURE_UUID; textu.CreateFace(3).TextureID = new UUID("6522E74D-1660-4E7F-B601-6F48C1659A77"); textu.CreateFace(4).TextureID = new UUID("7CA39B4C-BD19-4699-AFF7-F93FD03D3E7B"); textu.CreateFace(5).TextureID = new UUID("00000000-0000-1111-9999-000000000010"); textu.CreateFace(6).TextureID = new UUID("00000000-0000-1111-9999-000000000011"); return textu; }
public void TestSetAppearanceAlphaBakedTextures() { TestHelpers.InMethod(); // TestHelpers.EnableLogging(); UUID userId = TestHelpers.ParseTail(0x1); UUID alphaTextureID = new UUID("3a367d1c-bef1-6d43-7595-e88c1e3aadb3"); // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly // to the AssetService, which will then store temporary and local assets permanently CoreAssetCache assetCache = new CoreAssetCache(); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = new SceneHelpers(assetCache).SetupScene(); SceneHelpers.SetupSceneModules(scene, afm); ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); AssetBase libraryAsset; libraryAsset = new AssetBase( alphaTextureID, "Default Alpha Layer Texture", (sbyte)AssetType.Texture, userId.ToString()); libraryAsset.Data = new byte[] { 2 }; // Not necessary to have a genuine JPEG2000 asset here yet libraryAsset.Temporary = false; libraryAsset.Local = false; scene.AssetService.Store(libraryAsset); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)); uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes); Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); int rebakeRequestsReceived = 0; ((TestClient)sp.ControllingClient).OnReceivedSendRebakeAvatarTextures += id => rebakeRequestsReceived++; // This is the alpha texture eyesFace.TextureID = alphaTextureID; afm.SetAppearance(sp, bakedTextureEntry, visualParams, null); Assert.That(rebakeRequestsReceived, Is.EqualTo(0)); }
/// <summary> /// Assign a single material value. Based on the values passed we'll either set (or clear) the materials for a SOP. /// </summary> /// <param name="sop">The SOP being affected.</param> /// <param name="face">The face to assign, or -1 if the default texture is being set.</param> /// <param name="id">The ID assigned to this material. Setting a Zero UUID clears it.</param> /// <param name="material">If not null, the material to set. Otherwise we are clearing.</param> private void AssignSingleMaterial(SceneObjectPart sop, int face, OSDMap matData) { /// Get a copy of the texture entry so we can make changes. var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length); if (te == null) { m_log.Warn("[RenderMaterials]: null TextureEntry for localId: " + sop.LocalId.ToString()); return; } lock (m_knownMaterials) { UUID id = UUID.Zero; // Record what we currently have var currentMaterialIDs = getMaterialIDsFromTextureEntry(te); // If there is a material being set see if we've seen it before. // If not we'll add it to the region cache if (matData != null) { RenderMaterial material = RenderMaterial.FromOSD(matData); id = sop.Shape.RenderMaterials.AddMaterial(material); if (m_knownMaterials.ContainsKey(id)) { material = m_knownMaterials[id].material; var entry = m_knownMaterials[id]; if (entry.partIds.Contains(sop.LocalId) == false) entry.partIds.Add(sop.LocalId); } else { m_knownMaterials[id] = new RenderMaterialEntry(material, sop.LocalId); } m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Adding RenderMaterial {2}", sop.LocalId, face, material.ToString()); } // Set the Material ID in the sop texture entry. If there's a face defined // use that else use the Default entry. ID can either be a material ID // we set from the lookup above or Zero when we are clearing a material. if (face < 0) { te.DefaultTexture.MaterialID = id; } else { var faceEntry = te.CreateFace((uint)face); faceEntry.MaterialID = id; } // Get the updated list of Materials from the TextureEntry. We will // Use that to rebuild the RenderMaterials for the part. We'll also get a list // of entries that have been removed based on what we fetched initially so we // can clean that up in our cache. var newMaterialIDs = getMaterialIDsFromTextureEntry(te); // If there was an update and the material id has changed, clean up the old value. // Have to be careful here. It might still be in use in another slot. So we build // a list of keys and walk the texture entries subtracting keys in use. Whatever // is left are candidates to clean up. foreach (var entry in newMaterialIDs) { if (currentMaterialIDs.Contains(entry)) { currentMaterialIDs.Remove(entry); } if (sop.Shape.RenderMaterials.ContainsMaterial(entry) == false) { m_log.WarnFormat("[RenderMaterials]: SOP {0}, Face {1}, RenderMaterials {2} should be present but isn't!", sop.LocalId, face, entry.ToString()); } } // currentMaterialsIDs contains orphans if any. Remove them from the sop.Shape and the cache (if needed) foreach (var entry in currentMaterialIDs) { if (sop.Shape.RenderMaterials.ContainsMaterial(entry) == true) { m_log.DebugFormat("[RenderMaterials]: SOP {0}, Face {1}, Removing unused RenderMaterials {2} from shape.", sop.LocalId, face, entry.ToString()); sop.Shape.RenderMaterials.RemoveMaterial(entry); } else { m_log.WarnFormat("[RenderMaterials]: SOP {0}, Face {1}, ORPHANED RenderMaterials {2} should be present but isn't!", sop.LocalId, face, entry.ToString()); } if (m_knownMaterials.ContainsKey(entry)) { m_knownMaterials[entry].partIds.Remove(sop.LocalId); if (m_knownMaterials[entry].partIds.Count <= 0) { m_log.DebugFormat("[RenderMaterials]: Removing unused RenderMaterials {0} from region cache.", entry.ToString()); m_knownMaterials.Remove(entry); } } } } // Update the texture entry which will force an update to connected clients sop.UpdateTextureEntry(te.GetBytes()); }
public AgentSetAppearancePacket MakeAppearancePacket() { AgentSetAppearancePacket set = new AgentSetAppearancePacket(); set.AgentData.AgentID = Client.Self.AgentID; set.AgentData.SessionID = Client.Self.SessionID; set.AgentData.SerialNum = (uint)Interlocked.Increment(ref SetAppearanceSerialNum); // Visual params used in the agent height calculation float agentSizeVPHeight = 0.0f; float agentSizeVPHeelHeight = 0.0f; float agentSizeVPPlatformHeight = 0.0f; float agentSizeVPHeadSize = 0.5f; float agentSizeVPLegLength = 0.0f; float agentSizeVPNeckLength = 0.0f; float agentSizeVPHipLength = 0.0f; lock (Wearables) { #region VisualParam int vpIndex = 0; int nrParams; bool wearingPhysics = false; foreach (WearableData wearable in Wearables.Values) { if (wearable.WearableType == WearableType.Physics) { wearingPhysics = true; break; } } if (wearingPhysics) { nrParams = 251; } else { nrParams = 218; } set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[nrParams]; foreach (KeyValuePair<int, VisualParam> kvp in VisualParams.Params) { VisualParam vp = kvp.Value; float paramValue = 0f; bool found = false; // Try and find this value in our collection of downloaded wearables foreach (WearableData data in Wearables.Values) { if (data.Asset != null && data.Asset.Params.TryGetValue(vp.ParamID, out paramValue)) { found = true; break; } } // Use a default value if we don't have one set for it if (!found) paramValue = vp.DefaultValue; // Only Group-0 parameters are sent in AgentSetAppearance packets if (kvp.Value.Group == 0) { set.VisualParam[vpIndex] = new AgentSetAppearancePacket.VisualParamBlock(); set.VisualParam[vpIndex].ParamValue = Utils.FloatToByte(paramValue, vp.MinValue, vp.MaxValue); ++vpIndex; } // Check if this is one of the visual params used in the agent height calculation switch (vp.ParamID) { case 33: agentSizeVPHeight = paramValue; break; case 198: agentSizeVPHeelHeight = paramValue; break; case 503: agentSizeVPPlatformHeight = paramValue; break; case 682: agentSizeVPHeadSize = paramValue; break; case 692: agentSizeVPLegLength = paramValue; break; case 756: agentSizeVPNeckLength = paramValue; break; case 842: agentSizeVPHipLength = paramValue; break; } if (vpIndex == nrParams) break; } MyVisualParameters = new byte[set.VisualParam.Length]; for (int i = 0; i < set.VisualParam.Length; i++) { MyVisualParameters[i] = set.VisualParam[i].ParamValue; } #endregion VisualParam #region TextureEntry Primitive.TextureEntry te = new Primitive.TextureEntry(DEFAULT_AVATAR_TEXTURE); for (uint i = 0; i < Textures.Length; i++) { if ((i == 0 || i == 5 || i == 6) && Client.Settings.CLIENT_IDENTIFICATION_TAG != UUID.Zero) { Primitive.TextureEntryFace face = te.CreateFace(i); face.TextureID = Client.Settings.CLIENT_IDENTIFICATION_TAG; Logger.DebugLog("Sending client identification tag: " + Client.Settings.CLIENT_IDENTIFICATION_TAG, Client); } else if (Textures[i].TextureID != UUID.Zero) { Primitive.TextureEntryFace face = te.CreateFace(i); face.TextureID = Textures[i].TextureID; Logger.DebugLog("Sending texture entry for " + (AvatarTextureIndex)i + " to " + Textures[i].TextureID, Client); } } set.ObjectData.TextureEntry = te.GetBytes(); MyTextures = te; #endregion TextureEntry #region WearableData set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[BAKED_TEXTURE_COUNT]; // Build hashes for each of the bake layers from the individual components for (int bakedIndex = 0; bakedIndex < BAKED_TEXTURE_COUNT; bakedIndex++) { UUID hash = UUID.Zero; for (int wearableIndex = 0; wearableIndex < WEARABLES_PER_LAYER; wearableIndex++) { WearableType type = WEARABLE_BAKE_MAP[bakedIndex][wearableIndex]; WearableData wearable; if (type != WearableType.Invalid && Wearables.TryGetValue(type, out wearable)) hash ^= wearable.AssetID; } if (hash != UUID.Zero) { // Hash with our magic value for this baked layer hash ^= BAKED_TEXTURE_HASH[bakedIndex]; } // Tell the server what cached texture assetID to use for each bake layer set.WearableData[bakedIndex] = new AgentSetAppearancePacket.WearableDataBlock(); set.WearableData[bakedIndex].TextureIndex = BakeIndexToTextureIndex[bakedIndex]; set.WearableData[bakedIndex].CacheID = hash; Logger.DebugLog("Sending TextureIndex " + (BakeType)bakedIndex + " with CacheID " + hash, Client); } #endregion WearableData #region Agent Size // Takes into account the Shoe Heel/Platform offsets but not the HeadSize offset. Seems to work. double agentSizeBase = 1.706; // The calculation for the HeadSize scalar may be incorrect, but it seems to work double agentHeight = agentSizeBase + (agentSizeVPLegLength * .1918) + (agentSizeVPHipLength * .0375) + (agentSizeVPHeight * .12022) + (agentSizeVPHeadSize * .01117) + (agentSizeVPNeckLength * .038) + (agentSizeVPHeelHeight * .08) + (agentSizeVPPlatformHeight * .07); set.AgentData.Size = new Vector3(0.45f, 0.6f, (float)agentHeight); #endregion Agent Size if (Client.Settings.AVATAR_TRACKING) { Avatar me; if (Client.Network.CurrentSim.ObjectsAvatars.TryGetValue(Client.Self.LocalID, out me)) { me.Textures = MyTextures; me.VisualParameters = MyVisualParameters; } } } return set; }
/// <summary> /// Set the color & alpha of prim faces /// </summary> /// <param name="face"></param> /// <param name="color"></param> /// <param name="alpha"></param> public void SetFaceColorAlpha(int face, Vector3 color, double ?alpha) { Vector3 clippedColor = Util.Clip(color, 0.0f, 1.0f); float clippedAlpha = alpha.HasValue ? Util.Clip((float)alpha.Value, 0.0f, 1.0f) : 0; // The only way to get a deep copy/ If we don't do this, we can // never detect color changes further down. Byte[] buf = Shape.Textures.GetBytes(); Primitive.TextureEntry tex = new Primitive.TextureEntry(buf, 0, buf.Length); Color4 texcolor; if (face >= 0 && face < GetNumberOfSides()) { texcolor = tex.CreateFace((uint)face).RGBA; texcolor.R = clippedColor.X; texcolor.G = clippedColor.Y; texcolor.B = clippedColor.Z; if (alpha.HasValue) { texcolor.A = clippedAlpha; } tex.FaceTextures[face].RGBA = texcolor; UpdateTextureEntry(tex.GetBytes()); return; } else if (face == ALL_SIDES) { for (uint i = 0; i < GetNumberOfSides(); i++) { if (tex.FaceTextures[i] != null) { texcolor = tex.FaceTextures[i].RGBA; texcolor.R = clippedColor.X; texcolor.G = clippedColor.Y; texcolor.B = clippedColor.Z; if (alpha.HasValue) { texcolor.A = clippedAlpha; } tex.FaceTextures[i].RGBA = texcolor; } texcolor = tex.DefaultTexture.RGBA; texcolor.R = clippedColor.X; texcolor.G = clippedColor.Y; texcolor.B = clippedColor.Z; if (alpha.HasValue) { texcolor.A = clippedAlpha; } tex.DefaultTexture.RGBA = texcolor; } UpdateTextureEntry(tex.GetBytes()); return; } }
private void SendAgentSetAppearance() { AgentSetAppearancePacket set = new AgentSetAppearancePacket(); set.AgentData.AgentID = Network.AgentID; set.AgentData.SessionID = Network.SessionID; set.AgentData.SerialNum = SetAppearanceSerialNum++; set.VisualParam = new AgentSetAppearancePacket.VisualParamBlock[218]; float AgentSizeVPHeight = 0.0f; float AgentSizeVPHeelHeight = 0.0f; float AgentSizeVPPlatformHeight = 0.0f; float AgentSizeVPHeadSize = 0.5f; float AgentSizeVPLegLength = 0.0f; float AgentSizeVPNeckLength = 0.0f; float AgentSizeVPHipLength = 0.0f; lock (Wearables.Dictionary) { // Only for debugging output int count = 0, vpIndex = 0; // Build the visual param array foreach (KeyValuePair<int, VisualParam> kvp in VisualParams.Params) { VisualParam vp = kvp.Value; // Only Group-0 parameters are sent in AgentSetAppearance packets if (vp.Group == 0) { set.VisualParam[vpIndex] = new AgentSetAppearancePacket.VisualParamBlock(); // Try and find this value in our collection of downloaded wearables foreach (WearableData data in Wearables.Dictionary.Values) { if (data.Asset != null && data.Asset.Params.ContainsKey(vp.ParamID)) { set.VisualParam[vpIndex].ParamValue = Utils.FloatToByte(data.Asset.Params[vp.ParamID], vp.MinValue, vp.MaxValue); count++; switch (vp.ParamID) { case 33: AgentSizeVPHeight = data.Asset.Params[vp.ParamID]; break; case 198: AgentSizeVPHeelHeight = data.Asset.Params[vp.ParamID]; break; case 503: AgentSizeVPPlatformHeight = data.Asset.Params[vp.ParamID]; break; case 682: AgentSizeVPHeadSize = data.Asset.Params[vp.ParamID]; break; case 692: AgentSizeVPLegLength = data.Asset.Params[vp.ParamID]; break; case 756: AgentSizeVPNeckLength = data.Asset.Params[vp.ParamID]; break; case 842: AgentSizeVPHipLength = data.Asset.Params[vp.ParamID]; break; } break; } } ++vpIndex; } } // Build the texture entry for our agent Primitive.TextureEntry te = new Primitive.TextureEntry(DEFAULT_AVATAR_TEXTURE); // Put our AgentTextures array in to TextureEntry lock (AgentTextures) { for (uint i = 0; i < AgentTextures.Length; i++) { if (AgentTextures[i] != UUID.Zero) { Primitive.TextureEntryFace face = te.CreateFace(i); face.TextureID = AgentTextures[i]; } } } foreach (WearableData data in Wearables.Dictionary.Values) { if (data.Asset != null) { foreach (KeyValuePair<TextureIndex, UUID> texture in data.Asset.Textures) { Primitive.TextureEntryFace face = te.CreateFace((uint)texture.Key); face.TextureID = texture.Value; Log.DebugLog("Setting agent texture " + ((TextureIndex)texture.Key).ToString() + " to " + texture.Value.ToString()); } } } // Set the packet TextureEntry set.ObjectData.TextureEntry = te.GetBytes(); } // FIXME: Our hackish algorithm is making squished avatars. See // http://www.OpenMetaverse.org/wiki/Agent_Size for discussion of the correct algorithm //float height = Utils.ByteToFloat(set.VisualParam[33].ParamValue, VisualParams.Params[33].MinValue, // VisualParams.Params[33].MaxValue); // Takes into account the Shoe Heel/Platform offsets but not the Head Size Offset. But seems to work. double AgentSizeBase = 1.706; // The calculation for the Head Size scalar may be incorrect. But seems to work. double AgentHeight = AgentSizeBase + (AgentSizeVPLegLength * .1918) + (AgentSizeVPHipLength * .0375) + (AgentSizeVPHeight * .12022) + (AgentSizeVPHeadSize * .01117) + (AgentSizeVPNeckLength * .038) + (AgentSizeVPHeelHeight * .08) + (AgentSizeVPPlatformHeight * .07); set.AgentData.Size = new Vector3(0.45f, 0.6f, (float)AgentHeight); // TODO: Account for not having all the textures baked yet set.WearableData = new AgentSetAppearancePacket.WearableDataBlock[BAKED_TEXTURE_COUNT]; // Build hashes for each of the bake layers from the individual components for (int bakedIndex = 0; bakedIndex < BAKED_TEXTURE_COUNT; bakedIndex++) { UUID hash = new UUID(); for (int wearableIndex = 0; wearableIndex < WEARABLES_PER_LAYER; wearableIndex++) { WearableType type = WEARABLE_BAKE_MAP[bakedIndex][wearableIndex]; UUID assetID = GetWearableAsset(type); // Build a hash of all the texture asset IDs in this baking layer if (assetID != UUID.Zero) hash ^= assetID; } if (hash != UUID.Zero) { // Hash with our secret value for this baked layer hash ^= BAKED_TEXTURE_HASH[bakedIndex]; } // Tell the server what cached texture assetID to use for each bake layer set.WearableData[bakedIndex] = new AgentSetAppearancePacket.WearableDataBlock(); set.WearableData[bakedIndex].TextureIndex = (byte)bakedIndex; set.WearableData[bakedIndex].CacheID = hash; Log.DebugLog("Setting baked agent texture hash " + ((BakeType)bakedIndex).ToString() + " to " + hash); } // Finally, send the packet Network.SendPacket(set); }
protected virtual void SetDefaultTexture() { m_texture = new Primitive.TextureEntry(new UUID("C228D1CF-4B5D-4BA8-84F4-899A0796AA97")); for (uint i = 0; i < TEXTURE_COUNT; i++) m_texture.CreateFace(i).TextureID = new UUID(AppearanceManager.DEFAULT_AVATAR_TEXTURE); }
public void TestSaveBakedTextures() { TestHelpers.InMethod(); // log4net.Config.XmlConfigurator.Configure(); UUID userId = TestHelpers.ParseTail(0x1); UUID eyesTextureId = TestHelpers.ParseTail(0x2); // We need an asset cache because otherwise the LocalAssetServiceConnector will short-circuit directly // to the AssetService, which will then store temporary and local assets permanently CoreAssetCache assetCache = new CoreAssetCache(); AvatarFactoryModule afm = new AvatarFactoryModule(); TestScene scene = new SceneHelpers(assetCache).SetupScene(); SceneHelpers.SetupSceneModules(scene, afm); ScenePresence sp = SceneHelpers.AddScenePresence(scene, userId); // TODO: Use the actual BunchOfCaps functionality once we slot in the CapabilitiesModules AssetBase uploadedAsset; uploadedAsset = new AssetBase(eyesTextureId, "Baked Texture", (sbyte)AssetType.Texture, userId.ToString()); uploadedAsset.Data = new byte[] { 2 }; uploadedAsset.Temporary = true; uploadedAsset.Local = true; // Local assets aren't persisted, non-local are scene.AssetService.Store(uploadedAsset); byte[] visualParams = new byte[AvatarAppearance.VISUALPARAM_COUNT]; for (byte i = 0; i < visualParams.Length; i++) visualParams[i] = i; Primitive.TextureEntry bakedTextureEntry = new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)); uint eyesFaceIndex = (uint)AppearanceManager.BakeTypeToAgentTextureIndex(BakeType.Eyes); Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex); eyesFace.TextureID = eyesTextureId; afm.SetAppearance(sp, bakedTextureEntry, visualParams); afm.SaveBakedTextures(userId); // Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId); // We should also inpsect the asset data store layer directly, but this is difficult to get at right now. assetCache.Clear(); AssetBase eyesBake = scene.AssetService.Get(eyesTextureId.ToString()); Assert.That(eyesBake, Is.Not.Null); Assert.That(eyesBake.Temporary, Is.False); Assert.That(eyesBake.Local, Is.False); }