diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | 1064 |
1 files changed, 504 insertions, 560 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index 58f2586..3e1439d 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -209,27 +209,89 @@ namespace OpenSim.Region.Framework.Scenes | |||
209 | return true; | 209 | return true; |
210 | return false; | 210 | return false; |
211 | } | 211 | } |
212 | 212 | ||
213 | /// <value> | 213 | /// <summary> |
214 | /// Is this scene object acting as an attachment? | 214 | /// Is this scene object acting as an attachment? |
215 | /// | 215 | /// </summary> |
216 | /// We return false if the group has already been deleted. | 216 | public bool IsAttachment { get; set; } |
217 | /// | 217 | |
218 | /// TODO: At the moment set must be done on the part itself. There may be a case for doing it here since I | 218 | /// <summary> |
219 | /// presume either all or no parts in a linkset can be part of an attachment (in which | 219 | /// The avatar to which this scene object is attached. |
220 | /// case the value would get proprogated down into all the descendent parts). | 220 | /// </summary> |
221 | /// </value> | 221 | /// <remarks> |
222 | public bool IsAttachment | 222 | /// If we're not attached to an avatar then this is UUID.Zero |
223 | /// </remarks> | ||
224 | public UUID AttachedAvatar { get; set; } | ||
225 | |||
226 | /// <summary> | ||
227 | /// Attachment point of this scene object to an avatar. | ||
228 | /// </summary> | ||
229 | /// <remarks> | ||
230 | /// 0 if we're not attached to anything | ||
231 | /// </remarks> | ||
232 | public uint AttachmentPoint | ||
223 | { | 233 | { |
224 | get | 234 | get |
225 | { | 235 | { |
226 | if (!IsDeleted) | 236 | return m_rootPart.Shape.State; |
227 | return m_rootPart.IsAttachment; | 237 | } |
228 | 238 | ||
229 | return false; | 239 | set |
240 | { | ||
241 | IsAttachment = value != 0; | ||
242 | m_rootPart.Shape.State = (byte)value; | ||
230 | } | 243 | } |
231 | } | 244 | } |
232 | 245 | ||
246 | public void ClearPartAttachmentData() | ||
247 | { | ||
248 | AttachmentPoint = 0; | ||
249 | |||
250 | // Even though we don't use child part state parameters for attachments any more, we still need to set | ||
251 | // these to zero since having them non-zero in rezzed scene objects will crash some clients. Even if | ||
252 | // we store them correctly, scene objects that we receive from elsewhere might not. | ||
253 | foreach (SceneObjectPart part in Parts) | ||
254 | part.Shape.State = 0; | ||
255 | } | ||
256 | |||
257 | /// <summary> | ||
258 | /// Is this scene object phantom? | ||
259 | /// </summary> | ||
260 | /// <remarks> | ||
261 | /// Updating must currently take place through UpdatePrimFlags() | ||
262 | /// </remarks> | ||
263 | public bool IsPhantom | ||
264 | { | ||
265 | get { return (RootPart.Flags & PrimFlags.Phantom) != 0; } | ||
266 | } | ||
267 | |||
268 | /// <summary> | ||
269 | /// Does this scene object use physics? | ||
270 | /// </summary> | ||
271 | /// <remarks> | ||
272 | /// Updating must currently take place through UpdatePrimFlags() | ||
273 | /// </remarks> | ||
274 | public bool UsesPhysics | ||
275 | { | ||
276 | get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; } | ||
277 | } | ||
278 | |||
279 | /// <summary> | ||
280 | /// Is this scene object temporary? | ||
281 | /// </summary> | ||
282 | /// <remarks> | ||
283 | /// Updating must currently take place through UpdatePrimFlags() | ||
284 | /// </remarks> | ||
285 | public bool IsTemporary | ||
286 | { | ||
287 | get { return (RootPart.Flags & PrimFlags.TemporaryOnRez) != 0; } | ||
288 | } | ||
289 | |||
290 | public bool IsVolumeDetect | ||
291 | { | ||
292 | get { return RootPart.VolumeDetectActive; } | ||
293 | } | ||
294 | |||
233 | public float scriptScore; | 295 | public float scriptScore; |
234 | 296 | ||
235 | private Vector3 lastPhysGroupPos; | 297 | private Vector3 lastPhysGroupPos; |
@@ -261,11 +323,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
261 | /// </summary> | 323 | /// </summary> |
262 | public override string Name | 324 | public override string Name |
263 | { | 325 | { |
264 | get { | 326 | get { return RootPart.Name; } |
265 | if (RootPart == null) | ||
266 | return String.Empty; | ||
267 | return RootPart.Name; | ||
268 | } | ||
269 | set { RootPart.Name = value; } | 327 | set { RootPart.Name = value; } |
270 | } | 328 | } |
271 | 329 | ||
@@ -292,10 +350,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
292 | { | 350 | { |
293 | get { return m_rotation; } | 351 | get { return m_rotation; } |
294 | set { | 352 | set { |
295 | foreach(SceneObjectPart p in m_parts.GetArray()) | ||
296 | { | ||
297 | p.StoreUndoState(UndoType.STATE_GROUP_ROTATION); | ||
298 | } | ||
299 | m_rotation = value; | 353 | m_rotation = value; |
300 | } | 354 | } |
301 | } | 355 | } |
@@ -305,6 +359,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
305 | get { return m_rootPart.RotationOffset; } | 359 | get { return m_rootPart.RotationOffset; } |
306 | } | 360 | } |
307 | 361 | ||
362 | public Vector3 GroupScale | ||
363 | { | ||
364 | get | ||
365 | { | ||
366 | Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); | ||
367 | Vector3 maxScale = Vector3.Zero; | ||
368 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | ||
369 | |||
370 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
371 | for (int i = 0; i < parts.Length; i++) | ||
372 | { | ||
373 | SceneObjectPart part = parts[i]; | ||
374 | Vector3 partscale = part.Scale; | ||
375 | Vector3 partoffset = part.OffsetPosition; | ||
376 | |||
377 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; | ||
378 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; | ||
379 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; | ||
380 | |||
381 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | ||
382 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | ||
383 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | ||
384 | } | ||
385 | |||
386 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | ||
387 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | ||
388 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | ||
389 | |||
390 | return finalScale; | ||
391 | } | ||
392 | } | ||
393 | |||
308 | public UUID GroupID | 394 | public UUID GroupID |
309 | { | 395 | { |
310 | get { return m_rootPart.GroupID; } | 396 | get { return m_rootPart.GroupID; } |
@@ -344,11 +430,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
344 | /// <summary> | 430 | /// <summary> |
345 | /// Check both the attachment property and the relevant properties of the underlying root part. | 431 | /// Check both the attachment property and the relevant properties of the underlying root part. |
346 | /// </summary> | 432 | /// </summary> |
433 | /// <remarks> | ||
347 | /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't | 434 | /// This is necessary in some cases, particularly when a scene object has just crossed into a region and doesn't |
348 | /// have the IsAttachment property yet checked. | 435 | /// have the IsAttachment property yet checked. |
349 | /// | 436 | /// |
350 | /// FIXME: However, this should be fixed so that this property | 437 | /// FIXME: However, this should be fixed so that this property |
351 | /// propertly reflects the underlying status. | 438 | /// propertly reflects the underlying status. |
439 | /// </remarks> | ||
352 | /// <returns></returns> | 440 | /// <returns></returns> |
353 | public bool IsAttachmentCheckFull() | 441 | public bool IsAttachmentCheckFull() |
354 | { | 442 | { |
@@ -395,8 +483,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
395 | SceneObjectPart[] parts = m_parts.GetArray(); | 483 | SceneObjectPart[] parts = m_parts.GetArray(); |
396 | foreach (SceneObjectPart part in parts) | 484 | foreach (SceneObjectPart part in parts) |
397 | { | 485 | { |
398 | part.IgnoreUndoUpdate = false; | ||
399 | part.StoreUndoState(UndoType.STATE_GROUP_POSITION); | ||
400 | part.GroupPosition = val; | 486 | part.GroupPosition = val; |
401 | if (!m_dupeInProgress) | 487 | if (!m_dupeInProgress) |
402 | { | 488 | { |
@@ -682,7 +768,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
682 | part.ParentID = m_rootPart.LocalId; | 768 | part.ParentID = m_rootPart.LocalId; |
683 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); | 769 | //m_log.DebugFormat("[SCENE]: Given local id {0} to part {1}, linknum {2}, parent {3} {4}", part.LocalId, part.UUID, part.LinkNum, part.ParentID, part.ParentUUID); |
684 | } | 770 | } |
685 | 771 | ||
686 | ApplyPhysics(m_scene.m_physicalPrim); | 772 | ApplyPhysics(m_scene.m_physicalPrim); |
687 | 773 | ||
688 | if (RootPart.PhysActor != null) | 774 | if (RootPart.PhysActor != null) |
@@ -693,34 +779,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
693 | //ScheduleGroupForFullUpdate(); | 779 | //ScheduleGroupForFullUpdate(); |
694 | } | 780 | } |
695 | 781 | ||
696 | public Vector3 GroupScale() | ||
697 | { | ||
698 | Vector3 minScale = new Vector3(Constants.RegionSize, Constants.RegionSize, Constants.RegionSize); | ||
699 | Vector3 maxScale = Vector3.Zero; | ||
700 | Vector3 finalScale = new Vector3(0.5f, 0.5f, 0.5f); | ||
701 | |||
702 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
703 | for (int i = 0; i < parts.Length; i++) | ||
704 | { | ||
705 | SceneObjectPart part = parts[i]; | ||
706 | Vector3 partscale = part.Scale; | ||
707 | Vector3 partoffset = part.OffsetPosition; | ||
708 | |||
709 | minScale.X = (partscale.X + partoffset.X < minScale.X) ? partscale.X + partoffset.X : minScale.X; | ||
710 | minScale.Y = (partscale.Y + partoffset.Y < minScale.Y) ? partscale.Y + partoffset.Y : minScale.Y; | ||
711 | minScale.Z = (partscale.Z + partoffset.Z < minScale.Z) ? partscale.Z + partoffset.Z : minScale.Z; | ||
712 | |||
713 | maxScale.X = (partscale.X + partoffset.X > maxScale.X) ? partscale.X + partoffset.X : maxScale.X; | ||
714 | maxScale.Y = (partscale.Y + partoffset.Y > maxScale.Y) ? partscale.Y + partoffset.Y : maxScale.Y; | ||
715 | maxScale.Z = (partscale.Z + partoffset.Z > maxScale.Z) ? partscale.Z + partoffset.Z : maxScale.Z; | ||
716 | } | ||
717 | |||
718 | finalScale.X = (minScale.X > maxScale.X) ? minScale.X : maxScale.X; | ||
719 | finalScale.Y = (minScale.Y > maxScale.Y) ? minScale.Y : maxScale.Y; | ||
720 | finalScale.Z = (minScale.Z > maxScale.Z) ? minScale.Z : maxScale.Z; | ||
721 | return finalScale; | ||
722 | |||
723 | } | ||
724 | public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) | 782 | public EntityIntersection TestIntersection(Ray hRay, bool frontFacesOnly, bool faceCenters) |
725 | { | 783 | { |
726 | // We got a request from the inner_scene to raytrace along the Ray hRay | 784 | // We got a request from the inner_scene to raytrace along the Ray hRay |
@@ -1129,45 +1187,31 @@ namespace OpenSim.Region.Framework.Scenes | |||
1129 | /// <param name="agentID"></param> | 1187 | /// <param name="agentID"></param> |
1130 | /// <param name="attachmentpoint"></param> | 1188 | /// <param name="attachmentpoint"></param> |
1131 | /// <param name="AttachOffset"></param> | 1189 | /// <param name="AttachOffset"></param> |
1132 | public void AttachToAgent(UUID agentID, uint attachmentpoint, Vector3 AttachOffset, bool silent) | 1190 | private void AttachToAgent( |
1191 | ScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) | ||
1133 | { | 1192 | { |
1134 | ScenePresence avatar = m_scene.GetScenePresence(agentID); | ||
1135 | if (avatar != null) | 1193 | if (avatar != null) |
1136 | { | 1194 | { |
1137 | // don't attach attachments to child agents | 1195 | // don't attach attachments to child agents |
1138 | if (avatar.IsChildAgent) return; | 1196 | if (avatar.IsChildAgent) return; |
1139 | 1197 | ||
1140 | // m_log.DebugFormat("[SOG]: Adding attachment {0} to avatar {1}", Name, avatar.Name); | ||
1141 | |||
1142 | DetachFromBackup(); | ||
1143 | |||
1144 | // Remove from database and parcel prim count | 1198 | // Remove from database and parcel prim count |
1145 | m_scene.DeleteFromStorage(UUID); | 1199 | m_scene.DeleteFromStorage(so.UUID); |
1146 | m_scene.EventManager.TriggerParcelPrimCountTainted(); | 1200 | m_scene.EventManager.TriggerParcelPrimCountTainted(); |
1147 | 1201 | ||
1148 | m_rootPart.AttachedAvatar = agentID; | 1202 | so.AttachedAvatar = avatar.UUID; |
1149 | |||
1150 | //Anakin Lohner bug #3839 | ||
1151 | lock (m_parts) | ||
1152 | { | ||
1153 | foreach (SceneObjectPart p in m_parts.GetArray()) | ||
1154 | { | ||
1155 | p.AttachedAvatar = agentID; | ||
1156 | } | ||
1157 | } | ||
1158 | 1203 | ||
1159 | if (m_rootPart.PhysActor != null) | 1204 | if (so.RootPart.PhysActor != null) |
1160 | { | 1205 | { |
1161 | m_scene.PhysicsScene.RemovePrim(m_rootPart.PhysActor); | 1206 | m_scene.PhysicsScene.RemovePrim(so.RootPart.PhysActor); |
1162 | m_rootPart.PhysActor = null; | 1207 | so.RootPart.PhysActor = null; |
1163 | } | 1208 | } |
1164 | 1209 | ||
1165 | AbsolutePosition = AttachOffset; | 1210 | so.AbsolutePosition = attachOffset; |
1166 | m_rootPart.AttachedPos = AttachOffset; | 1211 | so.RootPart.AttachedPos = attachOffset; |
1167 | m_rootPart.IsAttachment = true; | 1212 | so.IsAttachment = true; |
1168 | 1213 | so.RootPart.SetParentLocalId(avatar.LocalId); | |
1169 | m_rootPart.SetParentLocalId(avatar.LocalId); | 1214 | so.AttachmentPoint = attachmentpoint; |
1170 | SetAttachmentPoint(Convert.ToByte(attachmentpoint)); | ||
1171 | 1215 | ||
1172 | avatar.AddAttachment(this); | 1216 | avatar.AddAttachment(this); |
1173 | 1217 | ||
@@ -1190,7 +1234,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1190 | { | 1234 | { |
1191 | m_log.WarnFormat( | 1235 | m_log.WarnFormat( |
1192 | "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", | 1236 | "[SOG]: Tried to add attachment {0} to avatar with UUID {1} in region {2} but the avatar is not present", |
1193 | UUID, agentID, Scene.RegionInfo.RegionName); | 1237 | UUID, avatar.ControllingClient.AgentId, Scene.RegionInfo.RegionName); |
1194 | } | 1238 | } |
1195 | } | 1239 | } |
1196 | 1240 | ||
@@ -1199,14 +1243,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1199 | return m_rootPart.Shape.State; | 1243 | return m_rootPart.Shape.State; |
1200 | } | 1244 | } |
1201 | 1245 | ||
1202 | public void ClearPartAttachmentData() | ||
1203 | { | ||
1204 | SetAttachmentPoint((Byte)0); | ||
1205 | } | ||
1206 | |||
1207 | public void DetachToGround() | 1246 | public void DetachToGround() |
1208 | { | 1247 | { |
1209 | ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); | 1248 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); |
1210 | if (avatar == null) | 1249 | if (avatar == null) |
1211 | return; | 1250 | return; |
1212 | 1251 | ||
@@ -1220,14 +1259,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1220 | RootPart.FromItemID = UUID.Zero; | 1259 | RootPart.FromItemID = UUID.Zero; |
1221 | 1260 | ||
1222 | AbsolutePosition = detachedpos; | 1261 | AbsolutePosition = detachedpos; |
1223 | m_rootPart.AttachedAvatar = UUID.Zero; | 1262 | AttachedAvatar = UUID.Zero; |
1224 | 1263 | ||
1225 | SceneObjectPart[] parts = m_parts.GetArray(); | 1264 | //SceneObjectPart[] parts = m_parts.GetArray(); |
1226 | for (int i = 0; i < parts.Length; i++) | 1265 | //for (int i = 0; i < parts.Length; i++) |
1227 | parts[i].AttachedAvatar = UUID.Zero; | 1266 | // parts[i].AttachedAvatar = UUID.Zero; |
1228 | 1267 | ||
1229 | m_rootPart.SetParentLocalId(0); | 1268 | m_rootPart.SetParentLocalId(0); |
1230 | SetAttachmentPoint((byte)0); | 1269 | AttachmentPoint = (byte)0; |
1231 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim); | 1270 | m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, m_scene.m_physicalPrim); |
1232 | HasGroupChanged = true; | 1271 | HasGroupChanged = true; |
1233 | RootPart.Rezzed = DateTime.Now; | 1272 | RootPart.Rezzed = DateTime.Now; |
@@ -1240,7 +1279,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1240 | 1279 | ||
1241 | public void DetachToInventoryPrep() | 1280 | public void DetachToInventoryPrep() |
1242 | { | 1281 | { |
1243 | ScenePresence avatar = m_scene.GetScenePresence(m_rootPart.AttachedAvatar); | 1282 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); |
1244 | //Vector3 detachedpos = new Vector3(127f, 127f, 127f); | 1283 | //Vector3 detachedpos = new Vector3(127f, 127f, 127f); |
1245 | if (avatar != null) | 1284 | if (avatar != null) |
1246 | { | 1285 | { |
@@ -1248,15 +1287,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1248 | avatar.RemoveAttachment(this); | 1287 | avatar.RemoveAttachment(this); |
1249 | } | 1288 | } |
1250 | 1289 | ||
1251 | m_rootPart.AttachedAvatar = UUID.Zero; | 1290 | AttachedAvatar = UUID.Zero; |
1252 | 1291 | ||
1253 | SceneObjectPart[] parts = m_parts.GetArray(); | 1292 | /*SceneObjectPart[] parts = m_parts.GetArray(); |
1254 | for (int i = 0; i < parts.Length; i++) | 1293 | for (int i = 0; i < parts.Length; i++) |
1255 | parts[i].AttachedAvatar = UUID.Zero; | 1294 | parts[i].AttachedAvatar = UUID.Zero;*/ |
1256 | 1295 | ||
1257 | m_rootPart.SetParentLocalId(0); | 1296 | m_rootPart.SetParentLocalId(0); |
1258 | //m_rootPart.SetAttachmentPoint((byte)0); | 1297 | //m_rootPart.SetAttachmentPoint((byte)0); |
1259 | m_rootPart.IsAttachment = false; | 1298 | IsAttachment = false; |
1260 | AbsolutePosition = m_rootPart.AttachedPos; | 1299 | AbsolutePosition = m_rootPart.AttachedPos; |
1261 | //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim); | 1300 | //m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim); |
1262 | //AttachToBackup(); | 1301 | //AttachToBackup(); |
@@ -1324,7 +1363,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1324 | 1363 | ||
1325 | part.LinkNum = m_parts.Count; | 1364 | part.LinkNum = m_parts.Count; |
1326 | 1365 | ||
1327 | if (part.LinkNum == 2 && RootPart != null) | 1366 | if (part.LinkNum == 2) |
1328 | RootPart.LinkNum = 1; | 1367 | RootPart.LinkNum = 1; |
1329 | } | 1368 | } |
1330 | 1369 | ||
@@ -1407,7 +1446,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1407 | 1446 | ||
1408 | public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) | 1447 | public virtual void OnGrabPart(SceneObjectPart part, Vector3 offsetPos, IClientAPI remoteClient) |
1409 | { | 1448 | { |
1410 | part.StoreUndoState(UndoType.STATE_PRIM_ALL); | 1449 | // m_log.DebugFormat( |
1450 | // "[SCENE OBJECT GROUP]: Processing OnGrabPart for {0} on {1} {2}, offsetPos {3}", | ||
1451 | // remoteClient.Name, part.Name, part.LocalId, offsetPos); | ||
1452 | |||
1453 | part.StoreUndoState(); | ||
1411 | part.OnGrab(offsetPos, remoteClient); | 1454 | part.OnGrab(offsetPos, remoteClient); |
1412 | } | 1455 | } |
1413 | 1456 | ||
@@ -1428,7 +1471,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1428 | public void DeleteGroupFromScene(bool silent) | 1471 | public void DeleteGroupFromScene(bool silent) |
1429 | { | 1472 | { |
1430 | // We need to keep track of this state in case this group is still queued for backup. | 1473 | // We need to keep track of this state in case this group is still queued for backup. |
1431 | m_isDeleted = true; | 1474 | IsDeleted = true; |
1432 | 1475 | ||
1433 | DetachFromBackup(); | 1476 | DetachFromBackup(); |
1434 | 1477 | ||
@@ -1703,91 +1746,86 @@ namespace OpenSim.Region.Framework.Scenes | |||
1703 | /// <returns></returns> | 1746 | /// <returns></returns> |
1704 | public SceneObjectGroup Copy(bool userExposed) | 1747 | public SceneObjectGroup Copy(bool userExposed) |
1705 | { | 1748 | { |
1706 | SceneObjectGroup dupe; | 1749 | SceneObjectGroup dupe = (SceneObjectGroup)MemberwiseClone(); |
1707 | try | 1750 | dupe.m_isBackedUp = false; |
1708 | { | 1751 | dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); |
1709 | m_dupeInProgress = true; | ||
1710 | dupe = (SceneObjectGroup)MemberwiseClone(); | ||
1711 | dupe.m_isBackedUp = false; | ||
1712 | dupe.m_parts = new MapAndArray<OpenMetaverse.UUID, SceneObjectPart>(); | ||
1713 | 1752 | ||
1714 | // Warning, The following code related to previousAttachmentStatus is needed so that clones of | 1753 | // Warning, The following code related to previousAttachmentStatus is needed so that clones of |
1715 | // attachments do not bordercross while they're being duplicated. This is hacktastic! | 1754 | // attachments do not bordercross while they're being duplicated. This is hacktastic! |
1716 | // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! | 1755 | // Normally, setting AbsolutePosition will bordercross a prim if it's outside the region! |
1717 | // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state | 1756 | // unless IsAttachment is true!, so to prevent border crossing, we save it's attachment state |
1718 | // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, | 1757 | // (which should be false anyway) set it as an Attachment and then set it's Absolute Position, |
1719 | // then restore it's attachment state | 1758 | // then restore it's attachment state |
1720 | 1759 | ||
1721 | // This is only necessary when userExposed is false! | 1760 | // This is only necessary when userExposed is false! |
1722 | 1761 | ||
1723 | bool previousAttachmentStatus = dupe.RootPart.IsAttachment; | 1762 | bool previousAttachmentStatus = dupe.IsAttachment; |
1724 | 1763 | ||
1725 | if (!userExposed) | 1764 | if (!userExposed) |
1726 | dupe.RootPart.IsAttachment = true; | 1765 | dupe.IsAttachment = true; |
1727 | 1766 | ||
1728 | dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); | 1767 | dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z); |
1729 | 1768 | ||
1730 | if (!userExposed) | 1769 | if (!userExposed) |
1731 | { | 1770 | { |
1732 | dupe.RootPart.IsAttachment = previousAttachmentStatus; | 1771 | dupe.IsAttachment = previousAttachmentStatus; |
1733 | } | 1772 | } |
1734 | 1773 | ||
1735 | dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); | 1774 | dupe.CopyRootPart(m_rootPart, OwnerID, GroupID, userExposed); |
1736 | dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; | 1775 | dupe.m_rootPart.LinkNum = m_rootPart.LinkNum; |
1737 | 1776 | ||
1738 | if (userExposed) | 1777 | if (userExposed) |
1739 | dupe.m_rootPart.TrimPermissions(); | 1778 | dupe.m_rootPart.TrimPermissions(); |
1740 | 1779 | ||
1741 | List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); | 1780 | List<SceneObjectPart> partList = new List<SceneObjectPart>(m_parts.GetArray()); |
1742 | 1781 | ||
1743 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) | 1782 | partList.Sort(delegate(SceneObjectPart p1, SceneObjectPart p2) |
1744 | { | 1783 | { |
1745 | return p1.LinkNum.CompareTo(p2.LinkNum); | 1784 | return p1.LinkNum.CompareTo(p2.LinkNum); |
1746 | } | 1785 | } |
1747 | ); | 1786 | ); |
1748 | 1787 | ||
1749 | foreach (SceneObjectPart part in partList) | 1788 | foreach (SceneObjectPart part in partList) |
1789 | { | ||
1790 | SceneObjectPart newPart; | ||
1791 | if (part.UUID != m_rootPart.UUID) | ||
1750 | { | 1792 | { |
1751 | if (part.UUID != m_rootPart.UUID) | 1793 | newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); |
1752 | { | 1794 | newPart.LinkNum = part.LinkNum; |
1753 | SceneObjectPart newPart = dupe.CopyPart(part, OwnerID, GroupID, userExposed); | ||
1754 | |||
1755 | newPart.LinkNum = part.LinkNum; | ||
1756 | } | ||
1757 | |||
1758 | // Need to duplicate the physics actor as well | ||
1759 | if (part.PhysActor != null && userExposed) | ||
1760 | { | ||
1761 | PrimitiveBaseShape pbs = part.Shape; | ||
1762 | |||
1763 | part.PhysActor | ||
1764 | = m_scene.PhysicsScene.AddPrimShape( | ||
1765 | string.Format("{0}/{1}", part.Name, part.UUID), | ||
1766 | pbs, | ||
1767 | part.AbsolutePosition, | ||
1768 | part.Scale, | ||
1769 | part.RotationOffset, | ||
1770 | part.PhysActor.IsPhysical, | ||
1771 | m_localId); | ||
1772 | part.PhysActor.SetMaterial((int)part.Material); | ||
1773 | |||
1774 | part.PhysActor.LocalID = part.LocalId; | ||
1775 | part.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); | ||
1776 | } | ||
1777 | } | 1795 | } |
1778 | if (userExposed) | 1796 | else |
1779 | { | 1797 | { |
1780 | dupe.UpdateParentIDs(); | 1798 | newPart = dupe.m_rootPart; |
1781 | dupe.HasGroupChanged = true; | 1799 | } |
1782 | dupe.AttachToBackup(); | ||
1783 | 1800 | ||
1784 | ScheduleGroupForFullUpdate(); | 1801 | // Need to duplicate the physics actor as well |
1802 | if (part.PhysActor != null && userExposed) | ||
1803 | { | ||
1804 | PrimitiveBaseShape pbs = newPart.Shape; | ||
1805 | |||
1806 | newPart.PhysActor | ||
1807 | = m_scene.PhysicsScene.AddPrimShape( | ||
1808 | string.Format("{0}/{1}", newPart.Name, newPart.UUID), | ||
1809 | pbs, | ||
1810 | newPart.AbsolutePosition, | ||
1811 | newPart.Scale, | ||
1812 | newPart.RotationOffset, | ||
1813 | part.PhysActor.IsPhysical, | ||
1814 | newPart.LocalId); | ||
1815 | |||
1816 | newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true); | ||
1785 | } | 1817 | } |
1786 | } | 1818 | } |
1787 | finally | 1819 | |
1820 | if (userExposed) | ||
1788 | { | 1821 | { |
1789 | m_dupeInProgress = false; | 1822 | dupe.UpdateParentIDs(); |
1823 | dupe.HasGroupChanged = true; | ||
1824 | dupe.AttachToBackup(); | ||
1825 | |||
1826 | ScheduleGroupForFullUpdate(); | ||
1790 | } | 1827 | } |
1828 | |||
1791 | return dupe; | 1829 | return dupe; |
1792 | } | 1830 | } |
1793 | 1831 | ||
@@ -1802,36 +1840,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1802 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); | 1840 | SetRootPart(part.Copy(m_scene.AllocateLocalId(), OwnerID, GroupID, 0, userExposed)); |
1803 | } | 1841 | } |
1804 | 1842 | ||
1805 | public void ScriptSetPhysicsStatus(bool UsePhysics) | 1843 | public void ScriptSetPhysicsStatus(bool usePhysics) |
1806 | { | 1844 | { |
1807 | bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); | 1845 | UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); |
1808 | bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); | ||
1809 | bool IsVolumeDetect = RootPart.VolumeDetectActive; | ||
1810 | UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | ||
1811 | } | 1846 | } |
1812 | 1847 | ||
1813 | public void ScriptSetTemporaryStatus(bool TemporaryStatus) | 1848 | public void ScriptSetTemporaryStatus(bool makeTemporary) |
1814 | { | 1849 | { |
1815 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 1850 | UpdatePrimFlags(RootPart.LocalId, UsesPhysics, makeTemporary, IsPhantom, IsVolumeDetect); |
1816 | bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); | ||
1817 | bool IsVolumeDetect = RootPart.VolumeDetectActive; | ||
1818 | UpdatePrimFlags(RootPart.LocalId, UsePhysics, TemporaryStatus, IsPhantom, IsVolumeDetect); | ||
1819 | } | 1851 | } |
1820 | 1852 | ||
1821 | public void ScriptSetPhantomStatus(bool PhantomStatus) | 1853 | public void ScriptSetPhantomStatus(bool makePhantom) |
1822 | { | 1854 | { |
1823 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 1855 | UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, makePhantom, IsVolumeDetect); |
1824 | bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); | ||
1825 | bool IsVolumeDetect = RootPart.VolumeDetectActive; | ||
1826 | UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, PhantomStatus, IsVolumeDetect); | ||
1827 | } | 1856 | } |
1828 | 1857 | ||
1829 | public void ScriptSetVolumeDetect(bool VDStatus) | 1858 | public void ScriptSetVolumeDetect(bool makeVolumeDetect) |
1830 | { | 1859 | { |
1831 | bool UsePhysics = ((RootPart.Flags & PrimFlags.Physics) != 0); | 1860 | UpdatePrimFlags(RootPart.LocalId, UsesPhysics, IsTemporary, IsPhantom, makeVolumeDetect); |
1832 | bool IsTemporary = ((RootPart.Flags & PrimFlags.TemporaryOnRez) != 0); | ||
1833 | bool IsPhantom = ((RootPart.Flags & PrimFlags.Phantom) != 0); | ||
1834 | UpdatePrimFlags(RootPart.LocalId, UsePhysics, IsTemporary, IsPhantom, VDStatus); | ||
1835 | 1861 | ||
1836 | /* | 1862 | /* |
1837 | ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore | 1863 | ScriptSetPhantomStatus(false); // What ever it was before, now it's not phantom anymore |
@@ -1849,142 +1875,88 @@ namespace OpenSim.Region.Framework.Scenes | |||
1849 | 1875 | ||
1850 | public void applyImpulse(Vector3 impulse) | 1876 | public void applyImpulse(Vector3 impulse) |
1851 | { | 1877 | { |
1852 | // We check if rootpart is null here because scripts don't delete if you delete the host. | 1878 | if (IsAttachment) |
1853 | // This means that unfortunately, we can pass a null physics actor to Simulate! | ||
1854 | // Make sure we don't do that! | ||
1855 | SceneObjectPart rootpart = m_rootPart; | ||
1856 | if (rootpart != null) | ||
1857 | { | 1879 | { |
1858 | if (IsAttachment) | 1880 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); |
1881 | if (avatar != null) | ||
1859 | { | 1882 | { |
1860 | ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); | 1883 | avatar.PushForce(impulse); |
1861 | if (avatar != null) | ||
1862 | { | ||
1863 | avatar.PushForce(impulse); | ||
1864 | } | ||
1865 | } | 1884 | } |
1866 | else | 1885 | } |
1886 | else | ||
1887 | { | ||
1888 | if (RootPart.PhysActor != null) | ||
1867 | { | 1889 | { |
1868 | if (rootpart.PhysActor != null) | 1890 | RootPart.PhysActor.AddForce(impulse, true); |
1869 | { | 1891 | m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); |
1870 | rootpart.PhysActor.AddForce(impulse, true); | ||
1871 | m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); | ||
1872 | } | ||
1873 | } | 1892 | } |
1874 | } | 1893 | } |
1875 | } | 1894 | } |
1876 | 1895 | ||
1877 | public void applyAngularImpulse(Vector3 impulse) | 1896 | public void applyAngularImpulse(Vector3 impulse) |
1878 | { | 1897 | { |
1879 | // We check if rootpart is null here because scripts don't delete if you delete the host. | 1898 | if (RootPart.PhysActor != null) |
1880 | // This means that unfortunately, we can pass a null physics actor to Simulate! | ||
1881 | // Make sure we don't do that! | ||
1882 | SceneObjectPart rootpart = m_rootPart; | ||
1883 | if (rootpart != null) | ||
1884 | { | 1899 | { |
1885 | if (rootpart.PhysActor != null) | 1900 | if (!IsAttachment) |
1886 | { | 1901 | { |
1887 | if (!IsAttachment) | 1902 | RootPart.PhysActor.AddAngularForce(impulse, true); |
1888 | { | 1903 | m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); |
1889 | rootpart.PhysActor.AddAngularForce(impulse, true); | ||
1890 | m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); | ||
1891 | } | ||
1892 | } | 1904 | } |
1893 | } | 1905 | } |
1894 | } | 1906 | } |
1895 | 1907 | ||
1896 | public void setAngularImpulse(Vector3 impulse) | 1908 | public void setAngularImpulse(Vector3 impulse) |
1897 | { | 1909 | { |
1898 | // We check if rootpart is null here because scripts don't delete if you delete the host. | 1910 | if (RootPart.PhysActor != null) |
1899 | // This means that unfortunately, we can pass a null physics actor to Simulate! | ||
1900 | // Make sure we don't do that! | ||
1901 | SceneObjectPart rootpart = m_rootPart; | ||
1902 | if (rootpart != null) | ||
1903 | { | 1911 | { |
1904 | if (rootpart.PhysActor != null) | 1912 | if (!IsAttachment) |
1905 | { | 1913 | { |
1906 | if (!IsAttachment) | 1914 | RootPart.PhysActor.Torque = impulse; |
1907 | { | 1915 | m_scene.PhysicsScene.AddPhysicsActorTaint(RootPart.PhysActor); |
1908 | rootpart.PhysActor.Torque = impulse; | ||
1909 | m_scene.PhysicsScene.AddPhysicsActorTaint(rootpart.PhysActor); | ||
1910 | } | ||
1911 | } | 1916 | } |
1912 | } | 1917 | } |
1913 | } | 1918 | } |
1914 | 1919 | ||
1915 | public Vector3 GetTorque() | 1920 | public Vector3 GetTorque() |
1916 | { | 1921 | { |
1917 | // We check if rootpart is null here because scripts don't delete if you delete the host. | 1922 | if (RootPart.PhysActor != null) |
1918 | // This means that unfortunately, we can pass a null physics actor to Simulate! | ||
1919 | // Make sure we don't do that! | ||
1920 | SceneObjectPart rootpart = m_rootPart; | ||
1921 | if (rootpart != null) | ||
1922 | { | 1923 | { |
1923 | if (rootpart.PhysActor != null) | 1924 | if (!IsAttachment) |
1924 | { | 1925 | { |
1925 | if (!IsAttachment) | 1926 | Vector3 torque = RootPart.PhysActor.Torque; |
1926 | { | 1927 | return torque; |
1927 | Vector3 torque = rootpart.PhysActor.Torque; | ||
1928 | return torque; | ||
1929 | } | ||
1930 | } | 1928 | } |
1931 | } | 1929 | } |
1930 | |||
1932 | return Vector3.Zero; | 1931 | return Vector3.Zero; |
1933 | } | 1932 | } |
1934 | 1933 | ||
1935 | // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object | 1934 | // This is used by both Double-Click Auto-Pilot and llMoveToTarget() in an attached object |
1936 | public void moveToTarget(Vector3 target, float tau) | 1935 | public void moveToTarget(Vector3 target, float tau) |
1937 | { | 1936 | { |
1938 | SceneObjectPart rootpart = m_rootPart; | 1937 | if (IsAttachment) |
1939 | if (rootpart != null) | ||
1940 | { | 1938 | { |
1941 | if (IsAttachment) | 1939 | ScenePresence avatar = m_scene.GetScenePresence(AttachedAvatar); |
1940 | if (avatar != null) | ||
1942 | { | 1941 | { |
1943 | ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); | 1942 | avatar.MoveToTarget(target, false); |
1944 | if (avatar != null) | ||
1945 | { | ||
1946 | List<string> coords = new List<string>(); | ||
1947 | uint regionX = 0; | ||
1948 | uint regionY = 0; | ||
1949 | Utils.LongToUInts(Scene.RegionInfo.RegionHandle, out regionX, out regionY); | ||
1950 | target.X += regionX; | ||
1951 | target.Y += regionY; | ||
1952 | coords.Add(target.X.ToString()); | ||
1953 | coords.Add(target.Y.ToString()); | ||
1954 | coords.Add(target.Z.ToString()); | ||
1955 | avatar.DoMoveToPosition(avatar, "", coords); | ||
1956 | } | ||
1957 | } | 1943 | } |
1958 | else | 1944 | } |
1945 | else | ||
1946 | { | ||
1947 | if (RootPart.PhysActor != null) | ||
1959 | { | 1948 | { |
1960 | if (rootpart.PhysActor != null) | 1949 | RootPart.PhysActor.PIDTarget = target; |
1961 | { | 1950 | RootPart.PhysActor.PIDTau = tau; |
1962 | rootpart.PhysActor.PIDTarget = target; | 1951 | RootPart.PhysActor.PIDActive = true; |
1963 | rootpart.PhysActor.PIDTau = tau; | ||
1964 | rootpart.PhysActor.PIDActive = true; | ||
1965 | } | ||
1966 | } | 1952 | } |
1967 | } | 1953 | } |
1968 | } | 1954 | } |
1969 | 1955 | ||
1970 | public void stopMoveToTarget() | 1956 | public void stopMoveToTarget() |
1971 | { | 1957 | { |
1972 | SceneObjectPart rootpart = m_rootPart; | 1958 | if (RootPart.PhysActor != null) |
1973 | if (rootpart != null) | 1959 | RootPart.PhysActor.PIDActive = false; |
1974 | { | ||
1975 | if (IsAttachment) | ||
1976 | { | ||
1977 | ScenePresence avatar = m_scene.GetScenePresence(rootpart.AttachedAvatar); | ||
1978 | if (avatar != null) avatar.StopMoveToPosition(); | ||
1979 | } | ||
1980 | else | ||
1981 | { | ||
1982 | if (rootpart.PhysActor != null) | ||
1983 | { | ||
1984 | rootpart.PhysActor.PIDActive = false; | ||
1985 | } | ||
1986 | } | ||
1987 | } | ||
1988 | } | 1960 | } |
1989 | 1961 | ||
1990 | public void rotLookAt(Quaternion target, float strength, float damping) | 1962 | public void rotLookAt(Quaternion target, float strength, float damping) |
@@ -2035,22 +2007,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2035 | /// <param name="tau">Number of seconds over which to reach target</param> | 2007 | /// <param name="tau">Number of seconds over which to reach target</param> |
2036 | public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) | 2008 | public void SetHoverHeight(float height, PIDHoverType hoverType, float tau) |
2037 | { | 2009 | { |
2038 | SceneObjectPart rootpart = m_rootPart; | 2010 | if (RootPart.PhysActor != null) |
2039 | if (rootpart != null) | ||
2040 | { | 2011 | { |
2041 | if (rootpart.PhysActor != null) | 2012 | if (height != 0f) |
2042 | { | 2013 | { |
2043 | if (height != 0f) | 2014 | RootPart.PhysActor.PIDHoverHeight = height; |
2044 | { | 2015 | RootPart.PhysActor.PIDHoverType = hoverType; |
2045 | rootpart.PhysActor.PIDHoverHeight = height; | 2016 | RootPart.PhysActor.PIDTau = tau; |
2046 | rootpart.PhysActor.PIDHoverType = hoverType; | 2017 | RootPart.PhysActor.PIDHoverActive = true; |
2047 | rootpart.PhysActor.PIDTau = tau; | 2018 | } |
2048 | rootpart.PhysActor.PIDHoverActive = true; | 2019 | else |
2049 | } | 2020 | { |
2050 | else | 2021 | RootPart.PhysActor.PIDHoverActive = false; |
2051 | { | ||
2052 | rootpart.PhysActor.PIDHoverActive = false; | ||
2053 | } | ||
2054 | } | 2022 | } |
2055 | } | 2023 | } |
2056 | } | 2024 | } |
@@ -2145,7 +2113,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2145 | // an object has been deleted from a scene before update was processed. | 2113 | // an object has been deleted from a scene before update was processed. |
2146 | // A more fundamental overhaul of the update mechanism is required to eliminate all | 2114 | // A more fundamental overhaul of the update mechanism is required to eliminate all |
2147 | // the race conditions. | 2115 | // the race conditions. |
2148 | if (m_isDeleted) | 2116 | if (IsDeleted) |
2149 | return; | 2117 | return; |
2150 | 2118 | ||
2151 | // Even temporary objects take part in physics (e.g. temp-on-rez bullets) | 2119 | // Even temporary objects take part in physics (e.g. temp-on-rez bullets) |
@@ -2459,7 +2427,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2459 | } | 2427 | } |
2460 | 2428 | ||
2461 | m_scene.UnlinkSceneObject(objectGroup, true); | 2429 | m_scene.UnlinkSceneObject(objectGroup, true); |
2462 | objectGroup.m_isDeleted = true; | 2430 | objectGroup.IsDeleted = true; |
2463 | 2431 | ||
2464 | objectGroup.m_parts.Clear(); | 2432 | objectGroup.m_parts.Clear(); |
2465 | 2433 | ||
@@ -2597,8 +2565,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2597 | public virtual void DetachFromBackup() | 2565 | public virtual void DetachFromBackup() |
2598 | { | 2566 | { |
2599 | m_scene.SceneGraph.FireDetachFromBackup(this); | 2567 | m_scene.SceneGraph.FireDetachFromBackup(this); |
2600 | 2568 | if (m_isBackedUp && Scene != null) | |
2601 | if (m_isBackedUp) | ||
2602 | m_scene.EventManager.OnBackup -= ProcessBackup; | 2569 | m_scene.EventManager.OnBackup -= ProcessBackup; |
2603 | 2570 | ||
2604 | m_isBackedUp = false; | 2571 | m_isBackedUp = false; |
@@ -2858,14 +2825,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
2858 | /// Update prim flags for this group. | 2825 | /// Update prim flags for this group. |
2859 | /// </summary> | 2826 | /// </summary> |
2860 | /// <param name="localID"></param> | 2827 | /// <param name="localID"></param> |
2861 | /// <param name="type"></param> | 2828 | /// <param name="UsePhysics"></param> |
2862 | /// <param name="inUse"></param> | 2829 | /// <param name="SetTemporary"></param> |
2863 | /// <param name="data"></param> | 2830 | /// <param name="SetPhantom"></param> |
2864 | public void UpdatePrimFlags(uint localID, bool UsePhysics, bool IsTemporary, bool IsPhantom, bool IsVolumeDetect) | 2831 | /// <param name="SetVolumeDetect"></param> |
2832 | public void UpdatePrimFlags(uint localID, bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVolumeDetect) | ||
2865 | { | 2833 | { |
2866 | SceneObjectPart selectionPart = GetChildPart(localID); | 2834 | SceneObjectPart selectionPart = GetChildPart(localID); |
2867 | 2835 | ||
2868 | if (IsTemporary) | 2836 | if (SetTemporary && Scene != null) |
2869 | { | 2837 | { |
2870 | DetachFromBackup(); | 2838 | DetachFromBackup(); |
2871 | // Remove from database and parcel prim count | 2839 | // Remove from database and parcel prim count |
@@ -2877,23 +2845,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
2877 | if (selectionPart != null) | 2845 | if (selectionPart != null) |
2878 | { | 2846 | { |
2879 | SceneObjectPart[] parts = m_parts.GetArray(); | 2847 | SceneObjectPart[] parts = m_parts.GetArray(); |
2880 | for (int i = 0; i < parts.Length; i++) | 2848 | |
2849 | if (Scene != null) | ||
2881 | { | 2850 | { |
2882 | SceneObjectPart part = parts[i]; | 2851 | for (int i = 0; i < parts.Length; i++) |
2883 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || | ||
2884 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | ||
2885 | part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) | ||
2886 | { | 2852 | { |
2887 | UsePhysics = false; // Reset physics | 2853 | SceneObjectPart part = parts[i]; |
2888 | break; | 2854 | if (part.Scale.X > m_scene.RegionInfo.PhysPrimMax || |
2855 | part.Scale.Y > m_scene.RegionInfo.PhysPrimMax || | ||
2856 | part.Scale.Z > m_scene.RegionInfo.PhysPrimMax) | ||
2857 | { | ||
2858 | UsePhysics = false; // Reset physics | ||
2859 | break; | ||
2860 | } | ||
2889 | } | 2861 | } |
2890 | } | 2862 | } |
2891 | 2863 | ||
2892 | RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2864 | RootPart.UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect); |
2893 | for (int i = 0; i < parts.Length; i++) | 2865 | for (int i = 0; i < parts.Length; i++) |
2894 | { | 2866 | { |
2895 | if (parts[i] != RootPart) | 2867 | if (parts[i] != RootPart) |
2896 | parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, IsVolumeDetect); | 2868 | parts[i].UpdatePrimFlags(UsePhysics, IsTemporary, IsPhantom, SetVolumeDetect); |
2897 | } | 2869 | } |
2898 | } | 2870 | } |
2899 | } | 2871 | } |
@@ -2967,202 +2939,150 @@ namespace OpenSim.Region.Framework.Scenes | |||
2967 | #region Resize | 2939 | #region Resize |
2968 | 2940 | ||
2969 | /// <summary> | 2941 | /// <summary> |
2970 | /// Resize the given part | 2942 | /// Resize the entire group of prims. |
2971 | /// </summary> | 2943 | /// </summary> |
2972 | /// <param name="scale"></param> | 2944 | /// <param name="scale"></param> |
2973 | /// <param name="localID"></param> | 2945 | public void GroupResize(Vector3 scale) |
2974 | public void Resize(Vector3 scale, uint localID) | 2946 | { |
2975 | { | 2947 | // m_log.DebugFormat( |
2976 | if (scale.X > m_scene.m_maxNonphys) | 2948 | // "[SCENE OBJECT GROUP]: Group resizing {0} {1} from {2} to {3}", Name, LocalId, RootPart.Scale, scale); |
2977 | scale.X = m_scene.m_maxNonphys; | 2949 | RootPart.StoreUndoState(true); |
2978 | if (scale.Y > m_scene.m_maxNonphys) | ||
2979 | scale.Y = m_scene.m_maxNonphys; | ||
2980 | if (scale.Z > m_scene.m_maxNonphys) | ||
2981 | scale.Z = m_scene.m_maxNonphys; | ||
2982 | SceneObjectPart part = GetChildPart(localID); | ||
2983 | if (part != null) | ||
2984 | { | ||
2985 | if (part.PhysActor != null) | ||
2986 | { | ||
2987 | if (part.PhysActor.IsPhysical) | ||
2988 | { | ||
2989 | if (scale.X > m_scene.m_maxPhys) | ||
2990 | scale.X = m_scene.m_maxPhys; | ||
2991 | if (scale.Y > m_scene.m_maxPhys) | ||
2992 | scale.Y = m_scene.m_maxPhys; | ||
2993 | if (scale.Z > m_scene.m_maxPhys) | ||
2994 | scale.Z = m_scene.m_maxPhys; | ||
2995 | } | ||
2996 | part.PhysActor.Size = scale; | ||
2997 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | ||
2998 | } | ||
2999 | part.Resize(scale); | ||
3000 | 2950 | ||
3001 | HasGroupChanged = true; | 2951 | scale.X = Math.Min(scale.X, Scene.m_maxNonphys); |
3002 | part.TriggerScriptChangedEvent(Changed.SCALE); | 2952 | scale.Y = Math.Min(scale.Y, Scene.m_maxNonphys); |
3003 | ScheduleGroupForFullUpdate(); | 2953 | scale.Z = Math.Min(scale.Z, Scene.m_maxNonphys); |
3004 | 2954 | ||
3005 | //if (part.UUID == m_rootPart.UUID) | 2955 | if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) |
3006 | //{ | 2956 | { |
3007 | //if (m_rootPart.PhysActor != null) | 2957 | scale.X = Math.Min(scale.X, Scene.m_maxPhys); |
3008 | //{ | 2958 | scale.Y = Math.Min(scale.Y, Scene.m_maxPhys); |
3009 | //m_rootPart.PhysActor.Size = | 2959 | scale.Z = Math.Min(scale.Z, Scene.m_maxPhys); |
3010 | //new PhysicsVector(m_rootPart.Scale.X, m_rootPart.Scale.Y, m_rootPart.Scale.Z); | ||
3011 | //m_scene.PhysicsScene.AddPhysicsActorTaint(m_rootPart.PhysActor); | ||
3012 | //} | ||
3013 | //} | ||
3014 | } | 2960 | } |
3015 | } | ||
3016 | 2961 | ||
3017 | public void GroupResize(Vector3 scale, uint localID) | 2962 | float x = (scale.X / RootPart.Scale.X); |
3018 | { | 2963 | float y = (scale.Y / RootPart.Scale.Y); |
3019 | SceneObjectPart part = GetChildPart(localID); | 2964 | float z = (scale.Z / RootPart.Scale.Z); |
3020 | if (part != null) | ||
3021 | { | ||
3022 | if (scale.X > m_scene.m_maxNonphys) | ||
3023 | scale.X = m_scene.m_maxNonphys; | ||
3024 | if (scale.Y > m_scene.m_maxNonphys) | ||
3025 | scale.Y = m_scene.m_maxNonphys; | ||
3026 | if (scale.Z > m_scene.m_maxNonphys) | ||
3027 | scale.Z = m_scene.m_maxNonphys; | ||
3028 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | ||
3029 | { | ||
3030 | if (scale.X > m_scene.m_maxPhys) | ||
3031 | scale.X = m_scene.m_maxPhys; | ||
3032 | if (scale.Y > m_scene.m_maxPhys) | ||
3033 | scale.Y = m_scene.m_maxPhys; | ||
3034 | if (scale.Z > m_scene.m_maxPhys) | ||
3035 | scale.Z = m_scene.m_maxPhys; | ||
3036 | } | ||
3037 | float x = (scale.X / part.Scale.X); | ||
3038 | float y = (scale.Y / part.Scale.Y); | ||
3039 | float z = (scale.Z / part.Scale.Z); | ||
3040 | 2965 | ||
3041 | SceneObjectPart[] parts; | 2966 | SceneObjectPart[] parts; |
3042 | if (x > 1.0f || y > 1.0f || z > 1.0f) | 2967 | if (x > 1.0f || y > 1.0f || z > 1.0f) |
2968 | { | ||
2969 | parts = m_parts.GetArray(); | ||
2970 | for (int i = 0; i < parts.Length; i++) | ||
3043 | { | 2971 | { |
3044 | parts = m_parts.GetArray(); | 2972 | SceneObjectPart obPart = parts[i]; |
3045 | for (int i = 0; i < parts.Length; i++) | 2973 | if (obPart.UUID != m_rootPart.UUID) |
3046 | { | 2974 | { |
3047 | SceneObjectPart obPart = parts[i]; | 2975 | // obPart.IgnoreUndoUpdate = true; |
3048 | if (obPart.UUID != m_rootPart.UUID) | 2976 | Vector3 oldSize = new Vector3(obPart.Scale); |
2977 | |||
2978 | float f = 1.0f; | ||
2979 | float a = 1.0f; | ||
2980 | |||
2981 | if (RootPart.PhysActor != null && RootPart.PhysActor.IsPhysical) | ||
3049 | { | 2982 | { |
3050 | obPart.IgnoreUndoUpdate = true; | 2983 | if (oldSize.X * x > m_scene.m_maxPhys) |
3051 | Vector3 oldSize = new Vector3(obPart.Scale); | 2984 | { |
2985 | f = m_scene.m_maxPhys / oldSize.X; | ||
2986 | a = f / x; | ||
2987 | x *= a; | ||
2988 | y *= a; | ||
2989 | z *= a; | ||
2990 | } | ||
3052 | 2991 | ||
3053 | float f = 1.0f; | 2992 | if (oldSize.Y * y > m_scene.m_maxPhys) |
3054 | float a = 1.0f; | 2993 | { |
2994 | f = m_scene.m_maxPhys / oldSize.Y; | ||
2995 | a = f / y; | ||
2996 | x *= a; | ||
2997 | y *= a; | ||
2998 | z *= a; | ||
2999 | } | ||
3055 | 3000 | ||
3056 | if (part.PhysActor != null && part.PhysActor.IsPhysical) | 3001 | if (oldSize.Z * z > m_scene.m_maxPhys) |
3057 | { | 3002 | { |
3058 | if (oldSize.X*x > m_scene.m_maxPhys) | 3003 | f = m_scene.m_maxPhys / oldSize.Z; |
3059 | { | 3004 | a = f / z; |
3060 | f = m_scene.m_maxPhys / oldSize.X; | 3005 | x *= a; |
3061 | a = f / x; | 3006 | y *= a; |
3062 | x *= a; | 3007 | z *= a; |
3063 | y *= a; | ||
3064 | z *= a; | ||
3065 | } | ||
3066 | if (oldSize.Y*y > m_scene.m_maxPhys) | ||
3067 | { | ||
3068 | f = m_scene.m_maxPhys / oldSize.Y; | ||
3069 | a = f / y; | ||
3070 | x *= a; | ||
3071 | y *= a; | ||
3072 | z *= a; | ||
3073 | } | ||
3074 | if (oldSize.Z*z > m_scene.m_maxPhys) | ||
3075 | { | ||
3076 | f = m_scene.m_maxPhys / oldSize.Z; | ||
3077 | a = f / z; | ||
3078 | x *= a; | ||
3079 | y *= a; | ||
3080 | z *= a; | ||
3081 | } | ||
3082 | } | 3008 | } |
3083 | else | 3009 | } |
3010 | else | ||
3011 | { | ||
3012 | if (oldSize.X * x > m_scene.m_maxNonphys) | ||
3084 | { | 3013 | { |
3085 | if (oldSize.X*x > m_scene.m_maxNonphys) | 3014 | f = m_scene.m_maxNonphys / oldSize.X; |
3086 | { | 3015 | a = f / x; |
3087 | f = m_scene.m_maxNonphys / oldSize.X; | 3016 | x *= a; |
3088 | a = f / x; | 3017 | y *= a; |
3089 | x *= a; | 3018 | z *= a; |
3090 | y *= a; | 3019 | } |
3091 | z *= a; | 3020 | |
3092 | } | 3021 | if (oldSize.Y * y > m_scene.m_maxNonphys) |
3093 | if (oldSize.Y*y > m_scene.m_maxNonphys) | 3022 | { |
3094 | { | 3023 | f = m_scene.m_maxNonphys / oldSize.Y; |
3095 | f = m_scene.m_maxNonphys / oldSize.Y; | 3024 | a = f / y; |
3096 | a = f / y; | 3025 | x *= a; |
3097 | x *= a; | 3026 | y *= a; |
3098 | y *= a; | 3027 | z *= a; |
3099 | z *= a; | 3028 | } |
3100 | } | 3029 | |
3101 | if (oldSize.Z*z > m_scene.m_maxNonphys) | 3030 | if (oldSize.Z * z > m_scene.m_maxNonphys) |
3102 | { | 3031 | { |
3103 | f = m_scene.m_maxNonphys / oldSize.Z; | 3032 | f = m_scene.m_maxNonphys / oldSize.Z; |
3104 | a = f / z; | 3033 | a = f / z; |
3105 | x *= a; | 3034 | x *= a; |
3106 | y *= a; | 3035 | y *= a; |
3107 | z *= a; | 3036 | z *= a; |
3108 | } | ||
3109 | } | 3037 | } |
3110 | obPart.IgnoreUndoUpdate = false; | ||
3111 | } | 3038 | } |
3039 | |||
3040 | // obPart.IgnoreUndoUpdate = false; | ||
3112 | } | 3041 | } |
3113 | } | 3042 | } |
3043 | } | ||
3114 | 3044 | ||
3115 | Vector3 prevScale = part.Scale; | 3045 | Vector3 prevScale = RootPart.Scale; |
3116 | prevScale.X *= x; | 3046 | prevScale.X *= x; |
3117 | prevScale.Y *= y; | 3047 | prevScale.Y *= y; |
3118 | prevScale.Z *= z;; | 3048 | prevScale.Z *= z; |
3049 | // RootPart.IgnoreUndoUpdate = true; | ||
3050 | RootPart.Resize(prevScale); | ||
3051 | // RootPart.IgnoreUndoUpdate = false; | ||
3119 | 3052 | ||
3120 | part.IgnoreUndoUpdate = false; | 3053 | parts = m_parts.GetArray(); |
3121 | part.StoreUndoState(UndoType.STATE_GROUP_SCALE); | 3054 | for (int i = 0; i < parts.Length; i++) |
3122 | part.IgnoreUndoUpdate = true; | 3055 | { |
3123 | part.Resize(prevScale); | 3056 | SceneObjectPart obPart = parts[i]; |
3124 | part.IgnoreUndoUpdate = false; | ||
3125 | 3057 | ||
3126 | parts = m_parts.GetArray(); | 3058 | if (obPart.UUID != m_rootPart.UUID) |
3127 | for (int i = 0; i < parts.Length; i++) | ||
3128 | { | 3059 | { |
3129 | SceneObjectPart obPart = parts[i]; | ||
3130 | obPart.IgnoreUndoUpdate = true; | 3060 | obPart.IgnoreUndoUpdate = true; |
3131 | if (obPart.UUID != m_rootPart.UUID) | ||
3132 | { | ||
3133 | if (obPart.UUID != m_rootPart.UUID) | ||
3134 | { | ||
3135 | obPart.IgnoreUndoUpdate = false; | ||
3136 | obPart.StoreUndoState(UndoType.STATE_GROUP_SCALE); | ||
3137 | obPart.IgnoreUndoUpdate = true; | ||
3138 | |||
3139 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); | ||
3140 | currentpos.X *= x; | ||
3141 | currentpos.Y *= y; | ||
3142 | currentpos.Z *= z; | ||
3143 | Vector3 newSize = new Vector3(obPart.Scale); | ||
3144 | newSize.X *= x; | ||
3145 | newSize.Y *= y; | ||
3146 | newSize.Z *= z; | ||
3147 | obPart.Resize(newSize); | ||
3148 | obPart.UpdateOffSet(currentpos); | ||
3149 | } | ||
3150 | obPart.IgnoreUndoUpdate = false; | ||
3151 | } | ||
3152 | obPart.IgnoreUndoUpdate = false; | ||
3153 | } | ||
3154 | 3061 | ||
3155 | if (part.PhysActor != null) | 3062 | Vector3 currentpos = new Vector3(obPart.OffsetPosition); |
3156 | { | 3063 | currentpos.X *= x; |
3157 | part.PhysActor.Size = prevScale; | 3064 | currentpos.Y *= y; |
3158 | m_scene.PhysicsScene.AddPhysicsActorTaint(part.PhysActor); | 3065 | currentpos.Z *= z; |
3066 | |||
3067 | Vector3 newSize = new Vector3(obPart.Scale); | ||
3068 | newSize.X *= x; | ||
3069 | newSize.Y *= y; | ||
3070 | newSize.Z *= z; | ||
3071 | |||
3072 | obPart.Resize(newSize); | ||
3073 | obPart.UpdateOffSet(currentpos); | ||
3074 | |||
3075 | obPart.IgnoreUndoUpdate = false; | ||
3159 | } | 3076 | } |
3160 | 3077 | ||
3161 | part.IgnoreUndoUpdate = false; | 3078 | // obPart.IgnoreUndoUpdate = false; |
3162 | HasGroupChanged = true; | 3079 | HasGroupChanged = true; |
3163 | m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); | 3080 | m_rootPart.TriggerScriptChangedEvent(Changed.SCALE); |
3164 | ScheduleGroupForTerseUpdate(); | 3081 | ScheduleGroupForTerseUpdate(); |
3165 | } | 3082 | } |
3083 | |||
3084 | // m_log.DebugFormat( | ||
3085 | // "[SCENE OBJECT GROUP]: Finished group resizing {0} {1} to {2}", Name, LocalId, RootPart.Scale); | ||
3166 | } | 3086 | } |
3167 | 3087 | ||
3168 | #endregion | 3088 | #endregion |
@@ -3175,11 +3095,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
3175 | /// <param name="pos"></param> | 3095 | /// <param name="pos"></param> |
3176 | public void UpdateGroupPosition(Vector3 pos) | 3096 | public void UpdateGroupPosition(Vector3 pos) |
3177 | { | 3097 | { |
3098 | // m_log.DebugFormat("[SCENE OBJECT GROUP]: Updating group position on {0} {1} to {2}", Name, LocalId, pos); | ||
3099 | |||
3100 | RootPart.StoreUndoState(true); | ||
3101 | |||
3102 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
3103 | // for (int i = 0; i < parts.Length; i++) | ||
3104 | // parts[i].StoreUndoState(); | ||
3105 | |||
3178 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) | 3106 | if (m_scene.EventManager.TriggerGroupMove(UUID, pos)) |
3179 | { | 3107 | { |
3180 | if (IsAttachment) | 3108 | if (IsAttachment) |
3181 | { | 3109 | { |
3182 | m_rootPart.StoreUndoState(UndoType.STATE_GROUP_POSITION); | ||
3183 | m_rootPart.AttachedPos = pos; | 3110 | m_rootPart.AttachedPos = pos; |
3184 | } | 3111 | } |
3185 | if (RootPart.GetStatusSandbox()) | 3112 | if (RootPart.GetStatusSandbox()) |
@@ -3213,10 +3140,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3213 | 3140 | ||
3214 | SceneObjectPart[] parts = m_parts.GetArray(); | 3141 | SceneObjectPart[] parts = m_parts.GetArray(); |
3215 | for (int i = 0; i < parts.Length; i++) | 3142 | for (int i = 0; i < parts.Length; i++) |
3216 | parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); | 3143 | parts[i].StoreUndoState(); |
3217 | 3144 | ||
3218 | if (part != null) | 3145 | if (part != null) |
3219 | { | 3146 | { |
3147 | // m_log.DebugFormat( | ||
3148 | // "[SCENE OBJECT GROUP]: Updating single position of {0} {1} to {2}", part.Name, part.LocalId, pos); | ||
3149 | |||
3150 | part.StoreUndoState(false); | ||
3151 | part.IgnoreUndoUpdate = true; | ||
3152 | |||
3220 | if (part.UUID == m_rootPart.UUID) | 3153 | if (part.UUID == m_rootPart.UUID) |
3221 | { | 3154 | { |
3222 | UpdateRootPosition(pos); | 3155 | UpdateRootPosition(pos); |
@@ -3227,18 +3160,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
3227 | } | 3160 | } |
3228 | 3161 | ||
3229 | HasGroupChanged = true; | 3162 | HasGroupChanged = true; |
3163 | part.IgnoreUndoUpdate = false; | ||
3230 | } | 3164 | } |
3231 | } | 3165 | } |
3232 | 3166 | ||
3233 | /// <summary> | 3167 | /// <summary> |
3234 | /// | 3168 | /// Update just the root prim position in a linkset |
3235 | /// </summary> | 3169 | /// </summary> |
3236 | /// <param name="pos"></param> | 3170 | /// <param name="pos"></param> |
3237 | private void UpdateRootPosition(Vector3 pos) | 3171 | public void UpdateRootPosition(Vector3 pos) |
3238 | { | 3172 | { |
3239 | SceneObjectPart[] parts = m_parts.GetArray(); | 3173 | // m_log.DebugFormat( |
3240 | for (int i = 0; i < parts.Length; i++) | 3174 | // "[SCENE OBJECT GROUP]: Updating root position of {0} {1} to {2}", Name, LocalId, pos); |
3241 | parts[i].StoreUndoState(UndoType.STATE_PRIM_POSITION); | 3175 | |
3176 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
3177 | // for (int i = 0; i < parts.Length; i++) | ||
3178 | // parts[i].StoreUndoState(); | ||
3242 | 3179 | ||
3243 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); | 3180 | Vector3 newPos = new Vector3(pos.X, pos.Y, pos.Z); |
3244 | Vector3 oldPos = | 3181 | Vector3 oldPos = |
@@ -3251,7 +3188,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3251 | axDiff *= Quaternion.Inverse(partRotation); | 3188 | axDiff *= Quaternion.Inverse(partRotation); |
3252 | diff = axDiff; | 3189 | diff = axDiff; |
3253 | 3190 | ||
3254 | parts = m_parts.GetArray(); | 3191 | SceneObjectPart[] parts = m_parts.GetArray(); |
3255 | for (int i = 0; i < parts.Length; i++) | 3192 | for (int i = 0; i < parts.Length; i++) |
3256 | { | 3193 | { |
3257 | SceneObjectPart obPart = parts[i]; | 3194 | SceneObjectPart obPart = parts[i]; |
@@ -3297,9 +3234,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
3297 | /// <param name="rot"></param> | 3234 | /// <param name="rot"></param> |
3298 | public void UpdateGroupRotationR(Quaternion rot) | 3235 | public void UpdateGroupRotationR(Quaternion rot) |
3299 | { | 3236 | { |
3300 | SceneObjectPart[] parts = m_parts.GetArray(); | 3237 | // m_log.DebugFormat( |
3301 | for (int i = 0; i < parts.Length; i++) | 3238 | // "[SCENE OBJECT GROUP]: Updating group rotation R of {0} {1} to {2}", Name, LocalId, rot); |
3302 | parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); | 3239 | |
3240 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
3241 | // for (int i = 0; i < parts.Length; i++) | ||
3242 | // parts[i].StoreUndoState(); | ||
3243 | |||
3244 | m_rootPart.StoreUndoState(true); | ||
3303 | 3245 | ||
3304 | m_rootPart.UpdateRotation(rot); | 3246 | m_rootPart.UpdateRotation(rot); |
3305 | 3247 | ||
@@ -3321,9 +3263,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3321 | /// <param name="rot"></param> | 3263 | /// <param name="rot"></param> |
3322 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) | 3264 | public void UpdateGroupRotationPR(Vector3 pos, Quaternion rot) |
3323 | { | 3265 | { |
3324 | SceneObjectPart[] parts = m_parts.GetArray(); | 3266 | // m_log.DebugFormat( |
3325 | for (int i = 0; i < parts.Length; i++) | 3267 | // "[SCENE OBJECT GROUP]: Updating group rotation PR of {0} {1} to {2}", Name, LocalId, rot); |
3326 | parts[i].StoreUndoState(UndoType.STATE_GROUP_ROTATION); | 3268 | |
3269 | // SceneObjectPart[] parts = m_parts.GetArray(); | ||
3270 | // for (int i = 0; i < parts.Length; i++) | ||
3271 | // parts[i].StoreUndoState(); | ||
3272 | |||
3273 | RootPart.StoreUndoState(true); | ||
3274 | RootPart.IgnoreUndoUpdate = true; | ||
3327 | 3275 | ||
3328 | m_rootPart.UpdateRotation(rot); | 3276 | m_rootPart.UpdateRotation(rot); |
3329 | 3277 | ||
@@ -3338,6 +3286,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3338 | 3286 | ||
3339 | HasGroupChanged = true; | 3287 | HasGroupChanged = true; |
3340 | ScheduleGroupForTerseUpdate(); | 3288 | ScheduleGroupForTerseUpdate(); |
3289 | |||
3290 | RootPart.IgnoreUndoUpdate = false; | ||
3341 | } | 3291 | } |
3342 | 3292 | ||
3343 | /// <summary> | 3293 | /// <summary> |
@@ -3349,11 +3299,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3349 | { | 3299 | { |
3350 | SceneObjectPart part = GetChildPart(localID); | 3300 | SceneObjectPart part = GetChildPart(localID); |
3351 | SceneObjectPart[] parts = m_parts.GetArray(); | 3301 | SceneObjectPart[] parts = m_parts.GetArray(); |
3352 | for (int i = 0; i < parts.Length; i++) | ||
3353 | parts[i].StoreUndoState(UndoType.STATE_PRIM_ROTATION); | ||
3354 | 3302 | ||
3355 | if (part != null) | 3303 | if (part != null) |
3356 | { | 3304 | { |
3305 | // m_log.DebugFormat( | ||
3306 | // "[SCENE OBJECT GROUP]: Updating single rotation of {0} {1} to {2}", part.Name, part.LocalId, rot); | ||
3307 | |||
3357 | if (part.UUID == m_rootPart.UUID) | 3308 | if (part.UUID == m_rootPart.UUID) |
3358 | { | 3309 | { |
3359 | UpdateRootRotation(rot); | 3310 | UpdateRootRotation(rot); |
@@ -3375,6 +3326,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3375 | SceneObjectPart part = GetChildPart(localID); | 3326 | SceneObjectPart part = GetChildPart(localID); |
3376 | if (part != null) | 3327 | if (part != null) |
3377 | { | 3328 | { |
3329 | // m_log.DebugFormat( | ||
3330 | // "[SCENE OBJECT GROUP]: Updating single position and rotation of {0} {1} to {2}", | ||
3331 | // part.Name, part.LocalId, rot); | ||
3332 | |||
3333 | part.StoreUndoState(); | ||
3334 | part.IgnoreUndoUpdate = true; | ||
3335 | |||
3378 | if (part.UUID == m_rootPart.UUID) | 3336 | if (part.UUID == m_rootPart.UUID) |
3379 | { | 3337 | { |
3380 | UpdateRootRotation(rot); | 3338 | UpdateRootRotation(rot); |
@@ -3391,12 +3349,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
3391 | } | 3349 | } |
3392 | else | 3350 | else |
3393 | { | 3351 | { |
3394 | part.StoreUndoState(UndoType.STATE_PRIM_ROTATION); | ||
3395 | part.IgnoreUndoUpdate = true; | ||
3396 | part.UpdateRotation(rot); | 3352 | part.UpdateRotation(rot); |
3397 | part.OffsetPosition = pos; | 3353 | part.OffsetPosition = pos; |
3398 | part.IgnoreUndoUpdate = false; | ||
3399 | } | 3354 | } |
3355 | |||
3356 | part.IgnoreUndoUpdate = false; | ||
3400 | } | 3357 | } |
3401 | } | 3358 | } |
3402 | 3359 | ||
@@ -3404,18 +3361,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
3404 | /// | 3361 | /// |
3405 | /// </summary> | 3362 | /// </summary> |
3406 | /// <param name="rot"></param> | 3363 | /// <param name="rot"></param> |
3407 | private void UpdateRootRotation(Quaternion rot) | 3364 | public void UpdateRootRotation(Quaternion rot) |
3408 | { | 3365 | { |
3366 | // m_log.DebugFormat( | ||
3367 | // "[SCENE OBJECT GROUP]: Updating root rotation of {0} {1} to {2}", | ||
3368 | // Name, LocalId, rot); | ||
3369 | |||
3409 | Quaternion axRot = rot; | 3370 | Quaternion axRot = rot; |
3410 | Quaternion oldParentRot = m_rootPart.RotationOffset; | 3371 | Quaternion oldParentRot = m_rootPart.RotationOffset; |
3411 | 3372 | m_rootPart.StoreUndoState(); | |
3412 | m_rootPart.StoreUndoState(UndoType.STATE_PRIM_ROTATION); | ||
3413 | bool cancelUndo = false; | ||
3414 | if (!m_rootPart.Undoing) | ||
3415 | { | ||
3416 | m_rootPart.Undoing = true; | ||
3417 | cancelUndo = true; | ||
3418 | } | ||
3419 | 3373 | ||
3420 | //Don't use UpdateRotation because it schedules an update prematurely | 3374 | //Don't use UpdateRotation because it schedules an update prematurely |
3421 | m_rootPart.RotationOffset = rot; | 3375 | m_rootPart.RotationOffset = rot; |
@@ -3444,14 +3398,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
3444 | prim.OffsetPosition = axPos; | 3398 | prim.OffsetPosition = axPos; |
3445 | 3399 | ||
3446 | prim.IgnoreUndoUpdate = false; | 3400 | prim.IgnoreUndoUpdate = false; |
3401 | prim.IgnoreUndoUpdate = false; | ||
3447 | } | 3402 | } |
3448 | } | 3403 | } |
3449 | if (cancelUndo == true) | 3404 | |
3450 | { | 3405 | // for (int i = 0; i < parts.Length; i++) |
3451 | m_rootPart.Undoing = false; | 3406 | // { |
3452 | } | 3407 | // SceneObjectPart childpart = parts[i]; |
3408 | // if (childpart != m_rootPart) | ||
3409 | // { | ||
3410 | //// childpart.IgnoreUndoUpdate = false; | ||
3411 | //// childpart.StoreUndoState(); | ||
3412 | // } | ||
3413 | // } | ||
3453 | HasGroupChanged = true; | 3414 | HasGroupChanged = true; |
3454 | ScheduleGroupForFullUpdate(); | 3415 | ScheduleGroupForFullUpdate(); |
3416 | |||
3417 | // m_log.DebugFormat( | ||
3418 | // "[SCENE OBJECT GROUP]: Updated root rotation of {0} {1} to {2}", | ||
3419 | // Name, LocalId, rot); | ||
3455 | } | 3420 | } |
3456 | 3421 | ||
3457 | #endregion | 3422 | #endregion |
@@ -3466,28 +3431,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
3466 | int yaxis = 4; | 3431 | int yaxis = 4; |
3467 | int zaxis = 8; | 3432 | int zaxis = 8; |
3468 | 3433 | ||
3469 | if (m_rootPart != null) | 3434 | setX = ((axis & xaxis) != 0) ? true : false; |
3470 | { | 3435 | setY = ((axis & yaxis) != 0) ? true : false; |
3471 | setX = ((axis & xaxis) != 0) ? true : false; | 3436 | setZ = ((axis & zaxis) != 0) ? true : false; |
3472 | setY = ((axis & yaxis) != 0) ? true : false; | ||
3473 | setZ = ((axis & zaxis) != 0) ? true : false; | ||
3474 | |||
3475 | float setval = (rotate10 > 0) ? 1f : 0f; | ||
3476 | 3437 | ||
3477 | if (setX) | 3438 | float setval = (rotate10 > 0) ? 1f : 0f; |
3478 | m_rootPart.RotationAxis.X = setval; | ||
3479 | if (setY) | ||
3480 | m_rootPart.RotationAxis.Y = setval; | ||
3481 | if (setZ) | ||
3482 | m_rootPart.RotationAxis.Z = setval; | ||
3483 | 3439 | ||
3484 | if (setX || setY || setZ) | 3440 | if (setX) |
3485 | { | 3441 | RootPart.RotationAxis.X = setval; |
3486 | m_rootPart.SetPhysicsAxisRotation(); | 3442 | if (setY) |
3487 | } | 3443 | RootPart.RotationAxis.Y = setval; |
3444 | if (setZ) | ||
3445 | RootPart.RotationAxis.Z = setval; | ||
3488 | 3446 | ||
3489 | } | 3447 | if (setX || setY || setZ) |
3448 | RootPart.SetPhysicsAxisRotation(); | ||
3490 | } | 3449 | } |
3450 | |||
3491 | public int registerRotTargetWaypoint(Quaternion target, float tolerance) | 3451 | public int registerRotTargetWaypoint(Quaternion target, float tolerance) |
3492 | { | 3452 | { |
3493 | scriptRotTarget waypoint = new scriptRotTarget(); | 3453 | scriptRotTarget waypoint = new scriptRotTarget(); |
@@ -3615,7 +3575,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
3615 | foreach (uint idx in m_rotTargets.Keys) | 3575 | foreach (uint idx in m_rotTargets.Keys) |
3616 | { | 3576 | { |
3617 | scriptRotTarget target = m_rotTargets[idx]; | 3577 | scriptRotTarget target = m_rotTargets[idx]; |
3618 | double angle = Math.Acos(target.targetRot.X * m_rootPart.RotationOffset.X + target.targetRot.Y * m_rootPart.RotationOffset.Y + target.targetRot.Z * m_rootPart.RotationOffset.Z + target.targetRot.W * m_rootPart.RotationOffset.W) * 2; | 3578 | double angle |
3579 | = Math.Acos( | ||
3580 | target.targetRot.X * m_rootPart.RotationOffset.X | ||
3581 | + target.targetRot.Y * m_rootPart.RotationOffset.Y | ||
3582 | + target.targetRot.Z * m_rootPart.RotationOffset.Z | ||
3583 | + target.targetRot.W * m_rootPart.RotationOffset.W) | ||
3584 | * 2; | ||
3619 | if (angle < 0) angle = -angle; | 3585 | if (angle < 0) angle = -angle; |
3620 | if (angle > Math.PI) angle = (Math.PI * 2 - angle); | 3586 | if (angle > Math.PI) angle = (Math.PI * 2 - angle); |
3621 | if (angle <= target.tolerance) | 3587 | if (angle <= target.tolerance) |
@@ -3680,43 +3646,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3680 | 3646 | ||
3681 | return retmass; | 3647 | return retmass; |
3682 | } | 3648 | } |
3683 | 3649 | ||
3650 | /// <summary> | ||
3651 | /// If the object is a sculpt/mesh, retrieve the mesh data for each part and reinsert it into each shape so that | ||
3652 | /// the physics engine can use it. | ||
3653 | /// </summary> | ||
3654 | /// <remarks> | ||
3655 | /// When the physics engine has finished with it, the sculpt data is discarded to save memory. | ||
3656 | /// </remarks> | ||
3684 | public void CheckSculptAndLoad() | 3657 | public void CheckSculptAndLoad() |
3685 | { | 3658 | { |
3686 | if (IsDeleted) | 3659 | if (IsDeleted) |
3687 | return; | 3660 | return; |
3661 | |||
3688 | if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) | 3662 | if ((RootPart.GetEffectiveObjectFlags() & (uint)PrimFlags.Phantom) != 0) |
3689 | return; | 3663 | return; |
3690 | 3664 | ||
3691 | SceneObjectPart[] parts = m_parts.GetArray(); | 3665 | // m_log.Debug("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId); |
3692 | for (int i = 0; i < parts.Length; i++) | ||
3693 | { | ||
3694 | SceneObjectPart part = parts[i]; | ||
3695 | if (part.Shape.SculptEntry && part.Shape.SculptTexture != UUID.Zero) | ||
3696 | { | ||
3697 | // check if a previously decoded sculpt map has been cached | ||
3698 | if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + part.Shape.SculptTexture.ToString()))) | ||
3699 | { | ||
3700 | part.SculptTextureCallback(part.Shape.SculptTexture, null); | ||
3701 | } | ||
3702 | else | ||
3703 | { | ||
3704 | m_scene.AssetService.Get( | ||
3705 | part.Shape.SculptTexture.ToString(), part, AssetReceived); | ||
3706 | } | ||
3707 | } | ||
3708 | } | ||
3709 | } | ||
3710 | 3666 | ||
3711 | protected void AssetReceived(string id, Object sender, AssetBase asset) | 3667 | SceneObjectPart[] parts = m_parts.GetArray(); |
3712 | { | ||
3713 | SceneObjectPart sop = (SceneObjectPart)sender; | ||
3714 | 3668 | ||
3715 | if (sop != null) | 3669 | for (int i = 0; i < parts.Length; i++) |
3716 | { | 3670 | parts[i].CheckSculptAndLoad(); |
3717 | if (asset != null) | ||
3718 | sop.SculptTextureCallback(asset.FullID, asset); | ||
3719 | } | ||
3720 | } | 3671 | } |
3721 | 3672 | ||
3722 | /// <summary> | 3673 | /// <summary> |
@@ -3751,19 +3702,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
3751 | return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); | 3702 | return String.Format("{0} {1} ({2})", Name, UUID, AbsolutePosition); |
3752 | } | 3703 | } |
3753 | 3704 | ||
3754 | public void SetAttachmentPoint(byte point) | ||
3755 | { | ||
3756 | SceneObjectPart[] parts = m_parts.GetArray(); | ||
3757 | for (int i = 0; i < parts.Length; i++) | ||
3758 | parts[i].SetAttachmentPoint(point); | ||
3759 | } | ||
3760 | |||
3761 | #region ISceneObject | 3705 | #region ISceneObject |
3762 | 3706 | ||
3763 | public virtual ISceneObject CloneForNewScene() | 3707 | public virtual ISceneObject CloneForNewScene() |
3764 | { | 3708 | { |
3765 | SceneObjectGroup sog = Copy(false); | 3709 | SceneObjectGroup sog = Copy(false); |
3766 | sog.m_isDeleted = false; | 3710 | sog.IsDeleted = false; |
3767 | return sog; | 3711 | return sog; |
3768 | } | 3712 | } |
3769 | 3713 | ||