/// <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); }
/// <summary> /// </summary> /// <param name="assetName"></param> /// <param name="assetDescription"></param> /// <param name="assetID"></param> /// <param name="inventoryItem"></param> /// <param name="parentFolder"></param> /// <param name="data"></param> /// <param name="inventoryType"></param> /// <param name="assetType"></param> /// <param name="everyone_mask"></param> /// <param name="group_mask"></param> /// <param name="next_owner_mask"></param> public UUID UploadCompleteHandler(string assetName, string assetDescription, UUID assetID, UUID inventoryItem, UUID parentFolder, byte[] data, string inventoryType, string assetType, uint everyone_mask, uint group_mask, uint next_owner_mask) { sbyte assType = 0; sbyte inType = 0; switch (inventoryType) { case "sound": inType = 1; assType = 1; break; case "animation": inType = 19; assType = 20; break; case "snapshot": inType = 15; assType = 0; break; case "wearable": inType = 18; switch (assetType) { case "bodypart": assType = 13; break; case "clothing": assType = 5; break; } break; case "object": { inType = (sbyte) InventoryType.Object; assType = (sbyte) AssetType.Object; List<Vector3> positions = new List<Vector3>(); List<Quaternion> rotations = new List<Quaternion>(); OSDMap request = (OSDMap) OSDParser.DeserializeLLSDXml(data); OSDArray instance_list = (OSDArray) request["instance_list"]; OSDArray mesh_list = (OSDArray) request["mesh_list"]; OSDArray texture_list = (OSDArray) request["texture_list"]; SceneObjectGroup grp = null; List<UUID> textures = new List<UUID>(); foreach ( AssetBase textureAsset in texture_list.Select(t => new AssetBase(UUID.Random(), assetName, AssetType.Texture, m_agentID) { Data = t.AsBinary() })) { textureAsset.ID = m_assetService.Store(textureAsset); textures.Add(textureAsset.ID); } InventoryFolderBase meshFolder = m_inventoryService.GetFolderForType(m_agentID, InventoryType.Mesh, AssetType.Mesh); for (int i = 0; i < mesh_list.Count; i++) { PrimitiveBaseShape pbs = PrimitiveBaseShape.CreateBox(); Primitive.TextureEntry textureEntry = new Primitive.TextureEntry(Primitive.TextureEntry.WHITE_TEXTURE); OSDMap inner_instance_list = (OSDMap) instance_list[i]; OSDArray face_list = (OSDArray) inner_instance_list["face_list"]; for (uint face = 0; face < face_list.Count; face++) { OSDMap faceMap = (OSDMap) face_list[(int) face]; Primitive.TextureEntryFace f = pbs.Textures.CreateFace(face); if (faceMap.ContainsKey("fullbright")) f.Fullbright = faceMap["fullbright"].AsBoolean(); if (faceMap.ContainsKey("diffuse_color")) f.RGBA = faceMap["diffuse_color"].AsColor4(); int textureNum = faceMap["image"].AsInteger(); float imagerot = faceMap["imagerot"].AsInteger(); float offsets = (float) faceMap["offsets"].AsReal(); float offsett = (float) faceMap["offsett"].AsReal(); float scales = (float) faceMap["scales"].AsReal(); float scalet = (float) faceMap["scalet"].AsReal(); if (imagerot != 0) f.Rotation = imagerot; if (offsets != 0) f.OffsetU = offsets; if (offsett != 0) f.OffsetV = offsett; if (scales != 0) f.RepeatU = scales; if (scalet != 0) f.RepeatV = scalet; f.TextureID = textures.Count > textureNum ? textures[textureNum] : Primitive.TextureEntry.WHITE_TEXTURE; textureEntry.FaceTextures[face] = f; } pbs.TextureEntry = textureEntry.GetBytes(); AssetBase meshAsset = new AssetBase(UUID.Random(), assetName, AssetType.Mesh, m_agentID) {Data = mesh_list[i].AsBinary()}; meshAsset.ID = m_assetService.Store(meshAsset); if (meshFolder == null) { m_inventoryService.CreateUserInventory(m_agentID, false); meshFolder = m_inventoryService.GetFolderForType(m_agentID, InventoryType.Mesh, AssetType.Mesh); } InventoryItemBase itemBase = new InventoryItemBase(UUID.Random(), m_agentID) { AssetType = (sbyte) AssetType.Mesh, AssetID = meshAsset.ID, CreatorId = m_agentID.ToString(), Folder = meshFolder.ID, InvType = (int) InventoryType.Texture, Name = "(Mesh) - " + assetName, CurrentPermissions = (uint) PermissionMask.All, BasePermissions = (uint) PermissionMask.All, EveryOnePermissions = everyone_mask, GroupPermissions = group_mask, NextPermissions = next_owner_mask }; //Bad... but whatever m_inventoryService.AddItem(itemBase); pbs.SculptEntry = true; pbs.SculptTexture = meshAsset.ID; pbs.SculptType = (byte) SculptType.Mesh; pbs.SculptData = meshAsset.Data; Vector3 position = inner_instance_list["position"].AsVector3(); Vector3 scale = inner_instance_list["scale"].AsVector3(); Quaternion rotation = inner_instance_list["rotation"].AsQuaternion(); int physicsShapeType = inner_instance_list["physics_shape_type"].AsInteger(); int material = inner_instance_list["material"].AsInteger(); int mesh = inner_instance_list["mesh"].AsInteger(); SceneObjectPart prim = new SceneObjectPart(m_agentID, pbs, position, Quaternion.Identity, Vector3.Zero, assetName) {Scale = scale, AbsolutePosition = position}; rotations.Add(rotation); positions.Add(position); prim.UUID = UUID.Random(); prim.CreatorID = m_agentID; prim.OwnerID = m_agentID; prim.GroupID = UUID.Zero; prim.LastOwnerID = m_agentID; prim.CreationDate = Util.UnixTimeSinceEpoch(); prim.Name = assetName; prim.Description = ""; prim.PhysicsType = (byte) physicsShapeType; prim.BaseMask = (uint) PermissionMask.All; prim.EveryoneMask = everyone_mask; prim.NextOwnerMask = next_owner_mask; prim.GroupMask = group_mask; prim.OwnerMask = (uint) PermissionMask.All; if (grp == null) grp = new SceneObjectGroup(prim, null); else grp.AddChild(prim, i + 1); grp.RootPart.IsAttachment = false; } if (grp.ChildrenList.Count > 1) //Fix first link # grp.RootPart.LinkNum++; Vector3 rootPos = positions[0]; grp.SetAbsolutePosition(false, rootPos); for (int i = 0; i < positions.Count; i++) { Vector3 offset = positions[i] - rootPos; grp.ChildrenList[i].SetOffsetPosition(offset); } //grp.Rotation = rotations[0]; for (int i = 0; i < rotations.Count; i++) { if (i != 0) grp.ChildrenList[i].SetRotationOffset(false, rotations[i], false); } grp.UpdateGroupRotationR(rotations[0]); data = Encoding.ASCII.GetBytes(grp.ToXml2()); } break; } AssetBase asset = new AssetBase(assetID, assetName, (AssetType)assType, m_agentID) { Data = data }; asset.ID = m_assetService.Store(asset); assetID = asset.ID; InventoryItemBase item = new InventoryItemBase { Owner = m_agentID, CreatorId = m_agentID.ToString(), ID = inventoryItem, AssetID = asset.ID, Description = assetDescription, Name = assetName, AssetType = assType, InvType = inType, Folder = parentFolder, CurrentPermissions = (uint) PermissionMask.All, BasePermissions = (uint) PermissionMask.All, EveryOnePermissions = everyone_mask, NextPermissions = next_owner_mask, GroupPermissions = group_mask, CreationDate = Util.UnixTimeSinceEpoch() }; m_inventoryService.AddItem(item); return assetID; }
/// <summary> /// Constructor /// </summary> /// <param name="part"> /// A <see cref="SceneObjectPart" /> /// </param> public SceneObjectPartInventory(SceneObjectPart part) { m_part = part; }
private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation, int linkNum) { Quaternion WorldRot = oldGroupRotation*part.GetRotationOffset(); // first fix from old local to world // position Vector3 axPos = part.OffsetPosition; axPos *= oldGroupRotation; part.SetGroupPosition(oldGroupPosition + axPos); //offset part.SetRotationOffset(false, WorldRot, false); // have it in world coords lets fix other things m_scene.SceneGraph.LinkPartToSOG(this, part, linkNum); part.CreateSelected = true; // now lets move to the new parent frame Quaternion rootRotation = m_rootPart.GetRotationOffset(); Vector3 pos = part.GroupPosition - AbsolutePosition; pos *= Quaternion.Inverse(rootRotation); part.SetOffsetPosition(pos); Quaternion newRot = Quaternion.Inverse(rootRotation)*WorldRot; part.SetRotationOffset(false, newRot, false); // caller will tell the rest about this position changes.. }
/// <summary> /// Add a child to the group, set the parent id's and then set the link number /// </summary> /// <param name="child"></param> /// <param name="linkNum"></param> /// <returns></returns> public bool AddChild(ISceneChildEntity child, int linkNum) { lock (m_partsLock) { if (child is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart) child; //Root part is first if (m_partsList.Count == 0) { m_rootPart = part; } //Set the parent prim part.SetParent(this); if (m_rootPart.LocalId != 0 && !part.IsRoot) part.SetParentLocalId(m_rootPart.LocalId); else part.SetParentLocalId(0); //Fix the link num part.LinkNum = linkNum; if (!m_parts.ContainsKey(child.UUID)) { m_parts.Add(child.UUID, part); m_partsList.Add(part); m_ValidgrpOOB = false; } return true; } } return false; }
/// <summary> /// Set a part to act as the root part for this scene object /// </summary> /// <param name="part"></param> public void SetRootPart(SceneObjectPart part) { if (part == null) throw new ArgumentNullException("part"); m_rootPart = part; if (!IsAttachment) part.SetParentLocalId(0); AddChild(part, part.LinkNum); }
/// <summary> /// Fix all the vehicle params after rebuilding the representation /// </summary> /// <param name="part"></param> private void FixVehicleParams(SceneObjectPart part) { part.PhysActor.VehicleType = part.VehicleType; // OSD o = part.GetComponentState("VehicleParameters"); foreach (OSD param in part.VehicleFlags) { part.PhysActor.VehicleFlags(param.AsInteger(), false); } foreach (KeyValuePair<string, OSD> param in part.VehicleParameters) { if (param.Value.Type == OSDType.Real) part.PhysActor.VehicleFloatParam(int.Parse(param.Key), (float) param.Value.AsReal()); else if (param.Value.Type == OSDType.Array) { OSDArray a = (OSDArray) param.Value; if (a.Count == 3) part.PhysActor.VehicleVectorParam(int.Parse(param.Key), param.Value.AsVector3()); else part.PhysActor.VehicleRotationParam(int.Parse(param.Key), param.Value.AsQuaternion()); } } }
public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) { part.StoreUndoState(); part.OnGrab(offsetPos, remoteClient); }
public void SetPartOwner(SceneObjectPart part, UUID cAgentID, UUID cGroupID) { part.OwnerID = cAgentID; part.GroupID = cGroupID; }
/// <summary> /// Link the prims in a given group to this group /// </summary> /// <param name="grp">The group of prims which should be linked to this group</param> public void LinkToGroup(ISceneEntity grp) { //MainConsole.Instance.DebugFormat( // "[SCENE OBJECT GROUP]: Linking group with root part {0}, {1} to group with root part {2}, {3}", // objectGroup.RootPart.Name, objectGroup.RootPart.UUID, RootPart.Name, RootPart.UUID); if (!(grp is SceneObjectGroup)) return; SceneObjectGroup objectGroup = (SceneObjectGroup) grp; if (m_rootPart.PhysActor != null) m_rootPart.PhysActor.BlockPhysicalReconstruction = true; SceneObjectPart linkPart = objectGroup.m_rootPart; Vector3 oldGroupPosition = linkPart.GroupPosition; Quaternion oldRootRotation = linkPart.GetRotationOffset(); Quaternion parentRot = m_rootPart.GetRotationOffset(); linkPart.SetGroupPosition(AbsolutePosition); // just change it without doing anything else Vector3 axPos = oldGroupPosition - AbsolutePosition; axPos *= Quaternion.Inverse(parentRot); linkPart.SetOffsetPosition(axPos); Quaternion newRot = Quaternion.Inverse(parentRot)*oldRootRotation; linkPart.SetRotationOffset(false, newRot, false); //Fix the link number for the root if (m_rootPart.LinkNum == 0) m_rootPart.LinkNum = 1; SceneObjectPart[] objectGroupChildren = new SceneObjectPart[objectGroup.ChildrenList.Count]; objectGroup.ChildrenList.CopyTo(objectGroupChildren, 0); //Destroy the old group m_scene.SceneGraph.DeleteEntity(objectGroup); objectGroup.IsDeleted = true; objectGroup.ClearChildren(); lock (m_partsLock) { int linkNum = 2; //Add the root part to our group! m_scene.SceneGraph.LinkPartToSOG(this, linkPart, linkNum++); linkPart.CreateSelected = true; linkPart.FixOffsetPosition(linkPart.OffsetPosition, true); // nasty let all know about where this is // let physics link it if (linkPart.PhysActor != null && m_rootPart.PhysActor != null) { if (linkPart.PhysicsType != (byte) PhysicsShapeType.None) linkPart.PhysActor.link(m_rootPart.PhysActor); } //rest of parts foreach ( SceneObjectPart part in objectGroupChildren.Where(part => part.UUID != objectGroup.m_rootPart.UUID)) { LinkNonRootPart(part, oldGroupPosition, oldRootRotation, linkNum++); part.FixOffsetPosition(part.OffsetPosition, true); if (part.PhysActor != null && m_rootPart.PhysActor != null) part.PhysActor.link(m_rootPart.PhysActor); } } // Here's the deal, this is ABSOLUTELY CRITICAL so the physics scene gets the update about the // position of linkset prims. IF YOU CHANGE THIS, YOU MUST TEST colliding with just linked and // unmoved prims! m_ValidgrpOOB = false; ResetChildPrimPhysicsPositions(); if (m_rootPart.PhysActor != null) m_rootPart.PhysActor.BlockPhysicalReconstruction = false; }
/// <summary> /// Add this child to the group and set the parent ID's, /// but do NOT set the link number, /// the caller wants to deal with it if they call this /// </summary> /// <param name="child"></param> /// <returns></returns> public bool LinkChild(ISceneChildEntity child) { lock (m_partsLock) { if (child is SceneObjectPart) { SceneObjectPart part = (SceneObjectPart) child; //Root part is first if (m_partsList.Count == 0) { m_rootPart = part; } //Set the parent prim part.SetParent(this); part.SetParentLocalId(m_rootPart.LocalId); if (!m_parts.ContainsKey(child.UUID)) { m_parts.Add(child.UUID, part); m_partsList.Add(part); m_ValidgrpOOB = false; } m_partsList.Sort(m_scene.SceneGraph.LinkSetSorter); return true; } } return false; }
/// <summary> /// Constructor. This object is added to the scene later via AttachToScene() /// </summary> public SceneObjectGroup(UUID ownerID, Vector3 pos, Quaternion rot, PrimitiveBaseShape shape, string name, IScene scene) : this(scene) { SceneObjectPart part = new SceneObjectPart(ownerID, shape, pos, rot, Vector3.Zero, name); SetRootPart(part); //This has to be set, otherwise it will break things like rezzing objects in an area where crossing is disabled, but rez isn't m_lastSignificantPosition = pos; m_ValidgrpOOB = false; }
public SceneObjectGroup(SceneObjectPart part, IScene scene, bool AddToScene) : this(scene) { if (!AddToScene) m_isDeleted = true; SetRootPart(part); part.Scale = part.Shape.Scale; // temporary hack to update oobb m_ValidgrpOOB = false; }
/// <summary> /// This constructor creates a SceneObjectGroup using a pre-existing SceneObjectPart. /// The original SceneObjectPart will be used rather than a copy, preserving /// its existing localID and UUID. /// </summary> public SceneObjectGroup(SceneObjectPart part, IScene scene) : this(scene) { SetRootPart(part); part.Scale = part.Shape.Scale; // temporary hack to update oobb m_ValidgrpOOB = false; }