/// <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 DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) { m_autopilotMoving = true; m_autoPilotTarget = Pos; m_sitAtAutoTarget = false; PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; //proxy.PCode = (byte)PCode.ParticleSystem; proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy, "", m_scene); proxyObjectGroup.AttachToScene(m_scene); // Commented out this code since it could never have executed, but might still be informative. // if (proxyObjectGroup != null) // { proxyObjectGroup.ScheduleGroupUpdate(PrimUpdateFlags.ForcedFullUpdate); remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); IBackupModule backup = m_scene.RequestModuleInterface<IBackupModule>(); if (backup != null) backup.DeleteSceneObjects(new[] { proxyObjectGroup }, true, true); // } // else // { // m_autopilotMoving = false; // m_autoPilotTarget = Vector3.Zero; // ControllingClient.SendAlertMessage("Autopilot cancelled"); // } }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; bool alreadyExisted = false; if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in sceneObject.Children.Values) { Vector3 scale = part.Shape.Scale; if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; if (scale.Y > m_parentScene.m_maxNonphys) scale.Y = m_parentScene.m_maxNonphys; if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; part.Shape.Scale = scale; } } sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); lock (sceneObject) { if (!Entities.ContainsKey(sceneObject.UUID)) { Entities.Add(sceneObject); m_numPrim += sceneObject.Children.Count; if (attachToBackup) sceneObject.AttachToBackup(); if (OnObjectCreate != null) OnObjectCreate(sceneObject); lock (m_dictionary_lock) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values) { SceneObjectGroupsByFullID[part.UUID] = sceneObject; SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } } } else { alreadyExisted = true; } } return alreadyExisted; }
public void DoAutoPilot(uint not_used, Vector3 Pos, IClientAPI remote_client) { if (IsChildAgent || IsInTransit) { m_log.Info("[SCENE PRESENCE]: DoAutoPilot: Request from child agent ignored - " + this.UUID.ToString()); return; } //m_log.Debug("[SCENE PRESENCE]: DoAutoPilot: Auto-move " + this.UUID.ToString() + " to " + Pos.ToString()); m_autopilotMoving = true; m_autoPilotTarget = Pos; m_sitAtAutoTarget = false; PrimitiveBaseShape proxy = PrimitiveBaseShape.Default; //proxy.PCode = (byte)PCode.ParticleSystem; proxyObjectGroup = new SceneObjectGroup(UUID, Pos, Rotation, proxy, false); proxyObjectGroup.AttachToScene(m_scene, false); // Commented out this code since it could never have executed, but might still be informative. // if (proxyObjectGroup != null) // { proxyObjectGroup.SendGroupFullUpdate(PrimUpdateFlags.ForcedFullUpdate); remote_client.SendSitResponse(proxyObjectGroup.UUID, Vector3.Zero, Quaternion.Identity, true, Vector3.Zero, Vector3.Zero, false); m_scene.DeleteSceneObject(proxyObjectGroup, false); // } // else // { // m_autopilotMoving = false; // m_autoPilotTarget = Vector3.Zero; // ControllingClient.SendAlertMessage("Autopilot cancelled"); // } }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <remarks> /// The object's stored position, rotation and velocity are used. /// </remarks> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null) { m_log.ErrorFormat("[SCENEGRAPH]: Tried to add null scene object"); return false; } if (sceneObject.UUID == UUID.Zero) { m_log.ErrorFormat( "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}", sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero); return false; } if (Entities.ContainsKey(sceneObject.UUID)) { m_log.DebugFormat( "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", m_parentScene.RegionInfo.RegionName, sceneObject.UUID); return false; } // m_log.DebugFormat( // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); SceneObjectPart[] parts = sceneObject.Parts; // Clamp the sizes (scales) of the child prims and add the child prims to the count of all primitives // (meshes and geometric primitives) in the scene; add child prims to m_numTotalPrim count if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in parts) { Vector3 scale = part.Shape.Scale; scale.X = Util.Clamp(scale.X, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); scale.Y = Util.Clamp(scale.Y, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); scale.Z = Util.Clamp(scale.Z, m_parentScene.m_minNonphys, m_parentScene.m_maxNonphys); part.Shape.Scale = scale; } } m_numTotalPrim += parts.Length; // Go through all parts (geometric primitives and meshes) of this Scene Object foreach (SceneObjectPart part in parts) { // Keep track of the total number of meshes or geometric primitives now in the scene; // determine which object this is based on its primitive type: sculpted (sculpt) prim refers to // a mesh and all other prims (i.e. box, sphere, etc) are geometric primitives if (part.GetPrimType() == PrimType.SCULPT) m_numMesh++; else m_numPrim++; } sceneObject.AttachToScene(m_parentScene); Entities.Add(sceneObject); lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; foreach (SceneObjectPart part in parts) { lock (SceneObjectGroupsByFullPartID) SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; lock (SceneObjectGroupsByLocalPartID) SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; } if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); if (attachToBackup) sceneObject.AttachToBackup(); return true; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <remarks> /// The object's stored position, rotation and velocity are used. /// </remarks> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject.UUID == UUID.Zero) { m_log.ErrorFormat( "[SCENEGRAPH]: Tried to add scene object {0} to {1} with illegal UUID of {2}", sceneObject.Name, m_parentScene.RegionInfo.RegionName, UUID.Zero); return false; } if (Entities.ContainsKey(sceneObject.UUID)) { m_log.DebugFormat( "[SCENEGRAPH]: Scene graph for {0} already contains object {1} in AddSceneObject()", m_parentScene.RegionInfo.RegionName, sceneObject.UUID); return false; } // m_log.DebugFormat( // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); SceneObjectPart[] parts = sceneObject.Parts; // Clamp child prim sizes and add child prims to the m_numPrim count if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in parts) { Vector3 scale = part.Shape.Scale; scale.X = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.X)); scale.Y = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Y)); scale.Z = Math.Max(m_parentScene.m_minNonphys, Math.Min(m_parentScene.m_maxNonphys, scale.Z)); part.Shape.Scale = scale; } } m_numPrim += parts.Length; sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); Entities.Add(sceneObject); if (attachToBackup) sceneObject.AttachToBackup(); lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; lock (SceneObjectGroupsByFullPartID) { foreach (SceneObjectPart part in parts) SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; } lock (SceneObjectGroupsByLocalPartID) { // m_log.DebugFormat( // "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}", // sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName); foreach (SceneObjectPart part in parts) SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; } return true; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <remarks> /// The object's stored position, rotation and velocity are used. /// </remarks> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart.UUID == UUID.Zero) return false; if (Entities.ContainsKey(sceneObject.UUID)) return false; // m_log.DebugFormat( // "[SCENEGRAPH]: Adding scene object {0} {1}, with {2} parts on {3}", // sceneObject.Name, sceneObject.UUID, sceneObject.Parts.Length, m_parentScene.RegionInfo.RegionName); SceneObjectPart[] parts = sceneObject.Parts; // Clamp child prim sizes and add child prims to the m_numPrim count if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in parts) { Vector3 scale = part.Shape.Scale; if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; if (scale.Y > m_parentScene.m_maxNonphys) scale.Y = m_parentScene.m_maxNonphys; if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; part.Shape.Scale = scale; } } m_numPrim += parts.Length; sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); Entities.Add(sceneObject); if (attachToBackup) sceneObject.AttachToBackup(); if (OnObjectCreate != null) OnObjectCreate(sceneObject); lock (SceneObjectGroupsByFullID) SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; lock (SceneObjectGroupsByFullPartID) { foreach (SceneObjectPart part in parts) SceneObjectGroupsByFullPartID[part.UUID] = sceneObject; } lock (SceneObjectGroupsByLocalPartID) { // m_log.DebugFormat( // "[SCENE GRAPH]: Adding scene object {0} {1} {2} to SceneObjectGroupsByLocalPartID in {3}", // sceneObject.Name, sceneObject.UUID, sceneObject.LocalId, m_parentScene.RegionInfo.RegionName); foreach (SceneObjectPart part in parts) SceneObjectGroupsByLocalPartID[part.LocalId] = sceneObject; } return true; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <returns>true if the object was added, false if an object with the same uuid was already in the scene /// </returns> public bool AddGroupToSceneGraph(SceneObjectGroup sceneObject, bool attachToBackup, bool alreadyPersisted, bool fromStorage, bool fromCrossing) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) { m_log.ErrorFormat("[SceneGraph]: {0} AddGroupToSceneGraph failed, invalid or null object.", m_parentScene.RegionInfo.RegionName); return false; } foreach (SceneObjectPart part in sceneObject.Children.Values) { Vector3 scale = part.Shape.Scale; if (scale.X < SceneObjectPart.MIN_PART_SCALE) { scale.X = SceneObjectPart.MIN_PART_SCALE; sceneObject.HasGroupChanged = true; } if (scale.Y < SceneObjectPart.MIN_PART_SCALE) { scale.Y = SceneObjectPart.MIN_PART_SCALE; sceneObject.HasGroupChanged = true; } if (scale.Z < SceneObjectPart.MIN_PART_SCALE) { scale.Z = SceneObjectPart.MIN_PART_SCALE; sceneObject.HasGroupChanged = true; } if (m_parentScene.m_clampPrimSize) { if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; if (scale.Y > m_parentScene.m_maxNonphys) scale.Y = m_parentScene.m_maxNonphys; if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; } part.Shape.Scale = scale; } // if physical, make sure we're above the ground by at least 10 cm if ((sceneObject.RootPart.Flags & PrimFlags.Physics) != 0) { OpenSim.Framework.Geom.Box bbox = sceneObject.BoundingBox(); float groundHeight = m_parentScene.Heightmap.CalculateHeightAt(sceneObject.AbsolutePosition.X, sceneObject.AbsolutePosition.Y); if (sceneObject.AbsolutePosition.Z + bbox.Size.Z <= groundHeight) { Vector3 newPos = sceneObject.AbsolutePosition; newPos.Z = (bbox.Size.Z / 2.0f) + groundHeight + 0.1f; sceneObject.RootPart.SetGroupPositionDirect(newPos); } AddPhysicalObject(); } // rationalize the group: fix any inconsistency in locked bits, and // clear the default touch action of BUY for any objects not actually for sale, etc sceneObject.Rationalize(sceneObject.OwnerID, fromCrossing); sceneObject.AttachToScene(m_parentScene, fromStorage); // allocates the localIds for the prims if (!alreadyPersisted) { sceneObject.HasGroupChanged = true; } sceneObject.IsPersisted = alreadyPersisted; lock (sceneObject) { bool entityAdded = false; lock (m_dictionary_lock) { if (!Entities.ContainsKey(sceneObject.LocalId)) { Entities.Add(sceneObject); foreach (SceneObjectPart part in sceneObject.Children.Values) { SceneObjectPartsByFullID[part.UUID] = part; SceneObjectPartsByLocalID[part.LocalId] = part; } entityAdded = true; } } if (entityAdded) { m_numPrim += sceneObject.Children.Count; m_parentScene.EventManager.TriggerParcelPrimCountTainted(); if (attachToBackup) { sceneObject.AttachToBackup(); //this gets the new object on the taint list if (!alreadyPersisted) { sceneObject.HasGroupChanged = true; } m_parentScene.InspectForAutoReturn(sceneObject); } //This property doesn't work on rezzing, only on crossings or restarts if ((fromStorage || fromCrossing) && sceneObject.RootPart.KeyframeAnimation != null) { if (sceneObject.RootPart.KeyframeAnimation.CurrentCommand == KeyframeAnimation.Commands.Play) { if (!fromStorage) { //Offset the initial position so that it is in the new region's coordinates // (only if we are actually crossing from a different region) Vector3 regionOffset = sceneObject.AbsolutePosition - sceneObject.OriginalEnteringScenePosition; sceneObject.RootPart.KeyframeAnimation.InitialPosition += regionOffset; } sceneObject.AddKeyframedMotion(null, KeyframeAnimation.Commands.Play); } } if (OnObjectCreate != null) OnObjectCreate(sceneObject); return true; } } return false; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; if (Entities.ContainsKey(sceneObject.UUID)) return false; SceneObjectPart[] children = sceneObject.Parts; // Clamp child prim sizes and add child prims to the m_numPrim count if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in children) { Vector3 scale = part.Shape.Scale; if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; if (scale.Y > m_parentScene.m_maxNonphys) scale.Y = m_parentScene.m_maxNonphys; if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; part.Shape.Scale = scale; } } m_numPrim += children.Length; sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); Entities.Add(sceneObject); if (attachToBackup) sceneObject.AttachToBackup(); if (OnObjectCreate != null) OnObjectCreate(sceneObject); lock (SceneObjectGroupsByFullID) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; foreach (SceneObjectPart part in children) SceneObjectGroupsByFullID[part.UUID] = sceneObject; } lock (SceneObjectGroupsByLocalID) { SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in children) SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } return true; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; lock (sceneObject) { if (Entities.ContainsKey(sceneObject.UUID)) { // m_log.WarnFormat( // "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); return false; } // m_log.DebugFormat( // "[SCENE GRAPH]: Adding object {0} {1} to region {2}", // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); if (m_parentScene.m_clampPrimSize) { foreach (SceneObjectPart part in sceneObject.Children.Values) { Vector3 scale = part.Shape.Scale; if (scale.X > m_parentScene.m_maxNonphys) scale.X = m_parentScene.m_maxNonphys; if (scale.Y > m_parentScene.m_maxNonphys) scale.Y = m_parentScene.m_maxNonphys; if (scale.Z > m_parentScene.m_maxNonphys) scale.Z = m_parentScene.m_maxNonphys; part.Shape.Scale = scale; } } sceneObject.AttachToScene(m_parentScene); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(); Entities.Add(sceneObject); m_numPrim += sceneObject.Children.Count; if (attachToBackup) sceneObject.AttachToBackup(); if (OnObjectCreate != null) OnObjectCreate(sceneObject); lock (m_dictionary_lock) { SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; foreach (SceneObjectPart part in sceneObject.Children.Values) { SceneObjectGroupsByFullID[part.UUID] = sceneObject; SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; } } } return true; }
/// <summary> /// Add an object to the scene. This will both update the scene, and send information about the /// new object to all clients interested in the scene. /// </summary> /// <param name="sceneObject"></param> /// <param name="attachToBackup"> /// If true, the object is made persistent into the scene. /// If false, the object will not persist over server restarts /// </param> /// <param name="sendClientUpdates"> /// If true, updates for the new scene object are sent to all viewers in range. /// If false, it is left to the caller to schedule the update /// </param> /// <returns> /// true if the object was added, false if an object with the same uuid was already in the scene /// </returns> protected bool AddSceneObject(SceneObjectGroup sceneObject, bool attachToBackup, bool sendClientUpdates) { if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) return false; //if (Entities.ContainsKey(sceneObject.UUID)) //{ // m_log.WarnFormat( // "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", // sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); // return false; //} IOpenRegionSettingsModule WSModule = sceneObject.Scene.RequestModuleInterface<IOpenRegionSettingsModule>(); if (WSModule != null) { foreach (SceneObjectPart part in sceneObject.ChildrenList) { if (part.Shape == null) continue; Vector3 scale = part.Shape.Scale; if (WSModule.MinimumPrimScale != -1) { if (scale.X < WSModule.MinimumPrimScale) scale.X = WSModule.MinimumPrimScale; if (scale.Y < WSModule.MinimumPrimScale) scale.Y = WSModule.MinimumPrimScale; if (scale.Z < WSModule.MinimumPrimScale) scale.Z = WSModule.MinimumPrimScale; } if (part.ParentGroup.RootPart.PhysActor != null && part.ParentGroup.RootPart.PhysActor.IsPhysical && WSModule.MaximumPhysPrimScale != -1) { if (scale.X > WSModule.MaximumPhysPrimScale) scale.X = WSModule.MaximumPhysPrimScale; if (scale.Y > WSModule.MaximumPhysPrimScale) scale.Y = WSModule.MaximumPhysPrimScale; if (scale.Z > WSModule.MaximumPhysPrimScale) scale.Z = WSModule.MaximumPhysPrimScale; } if (WSModule.MaximumPrimScale != -1) { if (scale.X > WSModule.MaximumPrimScale) scale.X = WSModule.MaximumPrimScale; if (scale.Y > WSModule.MaximumPrimScale) scale.Y = WSModule.MaximumPrimScale; if (scale.Z > WSModule.MaximumPrimScale) scale.Z = WSModule.MaximumPrimScale; } part.Shape.Scale = scale; } } sceneObject.AttachToScene(m_parentScene); Entities.Add(sceneObject); if (sendClientUpdates) sceneObject.ScheduleGroupForFullUpdate(PrimUpdateFlags.FullUpdate); m_numPrim += sceneObject.ChildrenList.Count; return true; }