aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDiva Canto2013-06-05 20:20:22 -0700
committerDiva Canto2013-06-05 20:20:22 -0700
commit25fa647a74194db5b20155ac6d8a34cc231996e8 (patch)
tree5dce1f838e05c2bb8562cd039e229210d99b1c5c
parentStrengthen some assumptions. (diff)
parentDatabase persistence for keyframes. Contains a Migration. (diff)
downloadopensim-SC-25fa647a74194db5b20155ac6d8a34cc231996e8.zip
opensim-SC-25fa647a74194db5b20155ac6d8a34cc231996e8.tar.gz
opensim-SC-25fa647a74194db5b20155ac6d8a34cc231996e8.tar.bz2
opensim-SC-25fa647a74194db5b20155ac6d8a34cc231996e8.tar.xz
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
-rw-r--r--OpenSim/Data/MySQL/MySQLSimulationData.cs29
-rw-r--r--OpenSim/Data/MySQL/Resources/RegionStore.migrations7
-rw-r--r--OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs3
-rw-r--r--OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs3
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.cs9
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs11
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs13
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPart.cs15
-rw-r--r--OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs16
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs140
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs1
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs13
-rw-r--r--OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs5
13 files changed, 261 insertions, 4 deletions
diff --git a/OpenSim/Data/MySQL/MySQLSimulationData.cs b/OpenSim/Data/MySQL/MySQLSimulationData.cs
index 2d20eaf..448962a 100644
--- a/OpenSim/Data/MySQL/MySQLSimulationData.cs
+++ b/OpenSim/Data/MySQL/MySQLSimulationData.cs
@@ -173,9 +173,9 @@ namespace OpenSim.Data.MySQL
173 "ParticleSystem, ClickAction, Material, " + 173 "ParticleSystem, ClickAction, Material, " +
174 "CollisionSound, CollisionSoundVolume, " + 174 "CollisionSound, CollisionSoundVolume, " +
175 "PassTouches, " + 175 "PassTouches, " +
176 "LinkNumber, MediaURL, DynAttrs, " + 176 "LinkNumber, MediaURL, KeyframeMotion, " +
177 "PhysicsShapeType, Density, GravityModifier, " + 177 "PhysicsShapeType, Density, GravityModifier, " +
178 "Friction, Restitution " + 178 "Friction, Restitution, DynAttrs " +
179 ") values (" + "?UUID, " + 179 ") values (" + "?UUID, " +
180 "?CreationDate, ?Name, ?Text, " + 180 "?CreationDate, ?Name, ?Text, " +
181 "?Description, ?SitName, ?TouchName, " + 181 "?Description, ?SitName, ?TouchName, " +
@@ -208,9 +208,9 @@ namespace OpenSim.Data.MySQL
208 "?ColorB, ?ColorA, ?ParticleSystem, " + 208 "?ColorB, ?ColorA, ?ParticleSystem, " +
209 "?ClickAction, ?Material, ?CollisionSound, " + 209 "?ClickAction, ?Material, ?CollisionSound, " +
210 "?CollisionSoundVolume, ?PassTouches, " + 210 "?CollisionSoundVolume, ?PassTouches, " +
211 "?LinkNumber, ?MediaURL, ?DynAttrs, " + 211 "?LinkNumber, ?MediaURL, ?KeyframeMotion, " +
212 "?PhysicsShapeType, ?Density, ?GravityModifier, " + 212 "?PhysicsShapeType, ?Density, ?GravityModifier, " +
213 "?Friction, ?Restitution)"; 213 "?Friction, ?Restitution, ?DynAttrs)";
214 214
215 FillPrimCommand(cmd, prim, obj.UUID, regionUUID); 215 FillPrimCommand(cmd, prim, obj.UUID, regionUUID);
216 216
@@ -455,7 +455,11 @@ namespace OpenSim.Data.MySQL
455 foreach (SceneObjectPart prim in prims.Values) 455 foreach (SceneObjectPart prim in prims.Values)
456 { 456 {
457 if (prim.ParentUUID == UUID.Zero) 457 if (prim.ParentUUID == UUID.Zero)
458 {
458 objects[prim.UUID] = new SceneObjectGroup(prim); 459 objects[prim.UUID] = new SceneObjectGroup(prim);
460 if (prim.KeyframeMotion != null)
461 prim.KeyframeMotion.UpdateSceneObject(objects[prim.UUID]);
462 }
459 } 463 }
460 464
461 // Add all of the children objects to the SOGs 465 // Add all of the children objects to the SOGs
@@ -1307,6 +1311,19 @@ namespace OpenSim.Data.MySQL
1307 else 1311 else
1308 prim.DynAttrs = new DAMap(); 1312 prim.DynAttrs = new DAMap();
1309 1313
1314 if (!(row["KeyframeMotion"] is DBNull))
1315 {
1316 Byte[] data = (byte[])row["KeyframeMotion"];
1317 if (data.Length > 0)
1318 prim.KeyframeMotion = KeyframeMotion.FromData(null, data);
1319 else
1320 prim.KeyframeMotion = null;
1321 }
1322 else
1323 {
1324 prim.KeyframeMotion = null;
1325 }
1326
1310 prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString()); 1327 prim.PhysicsShapeType = (byte)Convert.ToInt32(row["PhysicsShapeType"].ToString());
1311 prim.Density = (float)(double)row["Density"]; 1328 prim.Density = (float)(double)row["Density"];
1312 prim.GravityModifier = (float)(double)row["GravityModifier"]; 1329 prim.GravityModifier = (float)(double)row["GravityModifier"];
@@ -1659,6 +1676,10 @@ namespace OpenSim.Data.MySQL
1659 cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum); 1676 cmd.Parameters.AddWithValue("LinkNumber", prim.LinkNum);
1660 cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl); 1677 cmd.Parameters.AddWithValue("MediaURL", prim.MediaUrl);
1661 1678
1679 if (prim.KeyframeMotion != null)
1680 cmd.Parameters.AddWithValue("KeyframeMotion", prim.KeyframeMotion.Serialize());
1681 else
1682 cmd.Parameters.AddWithValue("KeyframeMotion", new Byte[0]);
1662 1683
1663 if (prim.DynAttrs.Count > 0) 1684 if (prim.DynAttrs.Count > 0)
1664 cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml()); 1685 cmd.Parameters.AddWithValue("DynAttrs", prim.DynAttrs.ToXml());
diff --git a/OpenSim/Data/MySQL/Resources/RegionStore.migrations b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
index 513c784..70b9558 100644
--- a/OpenSim/Data/MySQL/Resources/RegionStore.migrations
+++ b/OpenSim/Data/MySQL/Resources/RegionStore.migrations
@@ -923,3 +923,10 @@ ALTER TABLE prims ADD COLUMN `Restitution` double NOT NULL default '0.5';
923 923
924COMMIT; 924COMMIT;
925 925
926:VERSION 48 #---------------- Keyframes
927
928BEGIN;
929
930ALTER TABLE prims ADD COLUMN `KeyframeMotion` blob;
931
932COMMIT;
diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
index f58a24f..85d26f3 100644
--- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs
@@ -2247,6 +2247,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
2247 // move out of the region creating an infinite loop of failed attempts to cross 2247 // move out of the region creating an infinite loop of failed attempts to cross
2248 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false); 2248 grp.UpdatePrimFlags(grp.RootPart.LocalId,false,grp.IsTemporary,grp.IsPhantom,false);
2249 2249
2250 if (grp.RootPart.KeyframeMotion != null)
2251 grp.RootPart.KeyframeMotion.CrossingFailure();
2252
2250 grp.ScheduleGroupForFullUpdate(); 2253 grp.ScheduleGroupForFullUpdate();
2251 } 2254 }
2252 } 2255 }
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
index e6d6cbf..880205a 100644
--- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
+++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs
@@ -357,6 +357,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
357 357
358 foreach (SceneObjectGroup objectGroup in objlist) 358 foreach (SceneObjectGroup objectGroup in objlist)
359 { 359 {
360 if (objectGroup.RootPart.KeyframeMotion != null)
361 objectGroup.RootPart.KeyframeMotion.Stop();
362 objectGroup.RootPart.KeyframeMotion = null;
360// Vector3 inventoryStoredPosition = new Vector3 363// Vector3 inventoryStoredPosition = new Vector3
361// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) 364// (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
362// ? 250 365// ? 250
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs
index 0743ce7..a9f8a85 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.cs
@@ -2364,6 +2364,12 @@ namespace OpenSim.Region.Framework.Scenes
2364 2364
2365 foreach (SceneObjectPart part in partList) 2365 foreach (SceneObjectPart part in partList)
2366 { 2366 {
2367 if (part.KeyframeMotion != null)
2368 {
2369 part.KeyframeMotion.Delete();
2370 part.KeyframeMotion = null;
2371 }
2372
2367 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0)) 2373 if (part.IsJoint() && ((part.Flags & PrimFlags.Physics) != 0))
2368 { 2374 {
2369 PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed? 2375 PhysicsScene.RequestJointDeletion(part.Name); // FIXME: what if the name changed?
@@ -2705,6 +2711,9 @@ namespace OpenSim.Region.Framework.Scenes
2705 // before we restart the scripts, or else some functions won't work. 2711 // before we restart the scripts, or else some functions won't work.
2706 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject)); 2712 newObject.RootPart.ParentGroup.CreateScriptInstances(0, false, DefaultScriptEngine, GetStateSource(newObject));
2707 newObject.ResumeScripts(); 2713 newObject.ResumeScripts();
2714
2715 if (newObject.RootPart.KeyframeMotion != null)
2716 newObject.RootPart.KeyframeMotion.UpdateSceneObject(newObject);
2708 } 2717 }
2709 2718
2710 // Do this as late as possible so that listeners have full access to the incoming object 2719 // Do this as late as possible so that listeners have full access to the incoming object
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index a84f6d3..bb7ae7f 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -1645,6 +1645,12 @@ namespace OpenSim.Region.Framework.Scenes
1645 /// <param name="childPrims"></param> 1645 /// <param name="childPrims"></param>
1646 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children) 1646 protected internal void LinkObjects(SceneObjectPart root, List<SceneObjectPart> children)
1647 { 1647 {
1648 if (root.KeyframeMotion != null)
1649 {
1650 root.KeyframeMotion.Stop();
1651 root.KeyframeMotion = null;
1652 }
1653
1648 SceneObjectGroup parentGroup = root.ParentGroup; 1654 SceneObjectGroup parentGroup = root.ParentGroup;
1649 if (parentGroup == null) return; 1655 if (parentGroup == null) return;
1650 1656
@@ -1722,6 +1728,11 @@ namespace OpenSim.Region.Framework.Scenes
1722 { 1728 {
1723 if (part != null) 1729 if (part != null)
1724 { 1730 {
1731 if (part.KeyframeMotion != null)
1732 {
1733 part.KeyframeMotion.Stop();
1734 part.KeyframeMotion = null;
1735 }
1725 if (part.ParentGroup.PrimCount != 1) // Skip single 1736 if (part.ParentGroup.PrimCount != 1) // Skip single
1726 { 1737 {
1727 if (part.LinkNum < 2) // Root 1738 if (part.LinkNum < 2) // Root
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
index df23cc5..da80e4f 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs
@@ -455,6 +455,9 @@ namespace OpenSim.Region.Framework.Scenes
455 || Scene.TestBorderCross(val, Cardinals.S)) 455 || Scene.TestBorderCross(val, Cardinals.S))
456 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims)) 456 && !IsAttachmentCheckFull() && (!Scene.LoadingPrims))
457 { 457 {
458 if (m_rootPart.KeyframeMotion != null)
459 m_rootPart.KeyframeMotion.StartCrossingCheck();
460
458 m_scene.CrossPrimGroupIntoNewRegion(val, this, true); 461 m_scene.CrossPrimGroupIntoNewRegion(val, this, true);
459 } 462 }
460 } 463 }
@@ -578,6 +581,8 @@ namespace OpenSim.Region.Framework.Scenes
578 childPa.Selected = value; 581 childPa.Selected = value;
579 } 582 }
580 } 583 }
584 if (RootPart.KeyframeMotion != null)
585 RootPart.KeyframeMotion.Selected = value;
581 } 586 }
582 } 587 }
583 588
@@ -1551,6 +1556,8 @@ namespace OpenSim.Region.Framework.Scenes
1551 1556
1552 newPart.DoPhysicsPropertyUpdate(originalPartPa.IsPhysical, true); 1557 newPart.DoPhysicsPropertyUpdate(originalPartPa.IsPhysical, true);
1553 } 1558 }
1559 if (part.KeyframeMotion != null)
1560 newPart.KeyframeMotion = part.KeyframeMotion.Copy(dupe);
1554 } 1561 }
1555 1562
1556 if (userExposed) 1563 if (userExposed)
@@ -1578,6 +1585,12 @@ namespace OpenSim.Region.Framework.Scenes
1578 1585
1579 public void ScriptSetPhysicsStatus(bool usePhysics) 1586 public void ScriptSetPhysicsStatus(bool usePhysics)
1580 { 1587 {
1588 if (usePhysics)
1589 {
1590 if (RootPart.KeyframeMotion != null)
1591 RootPart.KeyframeMotion.Stop();
1592 RootPart.KeyframeMotion = null;
1593 }
1581 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect); 1594 UpdatePrimFlags(RootPart.LocalId, usePhysics, IsTemporary, IsPhantom, IsVolumeDetect);
1582 } 1595 }
1583 1596
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
index ea8c3c5..ff3f738 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs
@@ -354,6 +354,13 @@ namespace OpenSim.Region.Framework.Scenes
354 private UUID m_collisionSound; 354 private UUID m_collisionSound;
355 private float m_collisionSoundVolume; 355 private float m_collisionSoundVolume;
356 356
357 private KeyframeMotion m_keyframeMotion = null;
358
359 public KeyframeMotion KeyframeMotion
360 {
361 get; set;
362 }
363
357 #endregion Fields 364 #endregion Fields
358 365
359// ~SceneObjectPart() 366// ~SceneObjectPart()
@@ -1799,6 +1806,8 @@ namespace OpenSim.Region.Framework.Scenes
1799 Array.Copy(Shape.ExtraParams, extraP, extraP.Length); 1806 Array.Copy(Shape.ExtraParams, extraP, extraP.Length);
1800 dupe.Shape.ExtraParams = extraP; 1807 dupe.Shape.ExtraParams = extraP;
1801 1808
1809 // safeguard actual copy is done in sog.copy
1810 dupe.KeyframeMotion = null;
1802 dupe.PayPrice = (int[])PayPrice.Clone(); 1811 dupe.PayPrice = (int[])PayPrice.Clone();
1803 1812
1804 dupe.DynAttrs.CopyFrom(DynAttrs); 1813 dupe.DynAttrs.CopyFrom(DynAttrs);
@@ -2001,6 +2010,9 @@ namespace OpenSim.Region.Framework.Scenes
2001 { 2010 {
2002 if (UsePhysics) 2011 if (UsePhysics)
2003 { 2012 {
2013 if (ParentGroup.RootPart.KeyframeMotion != null)
2014 ParentGroup.RootPart.KeyframeMotion.Stop();
2015 ParentGroup.RootPart.KeyframeMotion = null;
2004 ParentGroup.Scene.AddPhysicalPrim(1); 2016 ParentGroup.Scene.AddPhysicalPrim(1);
2005 2017
2006 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 2018 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
@@ -4327,6 +4339,9 @@ namespace OpenSim.Region.Framework.Scenes
4327 4339
4328 if (isPhysical) 4340 if (isPhysical)
4329 { 4341 {
4342 if (ParentGroup.RootPart.KeyframeMotion != null)
4343 ParentGroup.RootPart.KeyframeMotion.Stop();
4344 ParentGroup.RootPart.KeyframeMotion = null;
4330 ParentGroup.Scene.AddPhysicalPrim(1); 4345 ParentGroup.Scene.AddPhysicalPrim(1);
4331 4346
4332 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate; 4347 pa.OnRequestTerseUpdate += PhysicsRequestingTerseUpdate;
diff --git a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
index 39420a6..3882b45 100644
--- a/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
+++ b/OpenSim/Region/Framework/Scenes/Serialization/SceneObjectSerializer.cs
@@ -262,6 +262,12 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
262 sr.Close(); 262 sr.Close();
263 } 263 }
264 264
265 XmlNodeList keymotion = doc.GetElementsByTagName("KeyframeMotion");
266 if (keymotion.Count > 0)
267 sceneObject.RootPart.KeyframeMotion = KeyframeMotion.FromData(sceneObject, Convert.FromBase64String(keymotion[0].InnerText));
268 else
269 sceneObject.RootPart.KeyframeMotion = null;
270
265 // Script state may, or may not, exist. Not having any, is NOT 271 // Script state may, or may not, exist. Not having any, is NOT
266 // ever a problem. 272 // ever a problem.
267 sceneObject.LoadScriptState(doc); 273 sceneObject.LoadScriptState(doc);
@@ -1182,6 +1188,16 @@ namespace OpenSim.Region.Framework.Scenes.Serialization
1182 }); 1188 });
1183 1189
1184 writer.WriteEndElement(); 1190 writer.WriteEndElement();
1191
1192 if (sog.RootPart.KeyframeMotion != null)
1193 {
1194 Byte[] data = sog.RootPart.KeyframeMotion.Serialize();
1195
1196 writer.WriteStartElement(String.Empty, "KeyframeMotion", String.Empty);
1197 writer.WriteBase64(data, 0, data.Length);
1198 writer.WriteEndElement();
1199 }
1200
1185 writer.WriteEndElement(); 1201 writer.WriteEndElement();
1186 } 1202 }
1187 1203
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
index 0b4b043..cd6092d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs
@@ -7296,6 +7296,146 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
7296 } 7296 }
7297 } 7297 }
7298 7298
7299 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
7300 {
7301 SceneObjectGroup group = m_host.ParentGroup;
7302
7303 if (group.RootPart.PhysActor != null && group.RootPart.PhysActor.IsPhysical)
7304 return;
7305 if (group.IsAttachment)
7306 return;
7307
7308 if (frames.Data.Length > 0) // We are getting a new motion
7309 {
7310 if (group.RootPart.KeyframeMotion != null)
7311 group.RootPart.KeyframeMotion.Delete();
7312 group.RootPart.KeyframeMotion = null;
7313
7314 int idx = 0;
7315
7316 KeyframeMotion.PlayMode mode = KeyframeMotion.PlayMode.Forward;
7317 KeyframeMotion.DataFormat data = KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation;
7318
7319 while (idx < options.Data.Length)
7320 {
7321 int option = (int)options.GetLSLIntegerItem(idx++);
7322 int remain = options.Data.Length - idx;
7323
7324 switch (option)
7325 {
7326 case ScriptBaseClass.KFM_MODE:
7327 if (remain < 1)
7328 break;
7329 int modeval = (int)options.GetLSLIntegerItem(idx++);
7330 switch(modeval)
7331 {
7332 case ScriptBaseClass.KFM_FORWARD:
7333 mode = KeyframeMotion.PlayMode.Forward;
7334 break;
7335 case ScriptBaseClass.KFM_REVERSE:
7336 mode = KeyframeMotion.PlayMode.Reverse;
7337 break;
7338 case ScriptBaseClass.KFM_LOOP:
7339 mode = KeyframeMotion.PlayMode.Loop;
7340 break;
7341 case ScriptBaseClass.KFM_PING_PONG:
7342 mode = KeyframeMotion.PlayMode.PingPong;
7343 break;
7344 }
7345 break;
7346 case ScriptBaseClass.KFM_DATA:
7347 if (remain < 1)
7348 break;
7349 int dataval = (int)options.GetLSLIntegerItem(idx++);
7350 data = (KeyframeMotion.DataFormat)dataval;
7351 break;
7352 }
7353 }
7354
7355 group.RootPart.KeyframeMotion = new KeyframeMotion(group, mode, data);
7356
7357 idx = 0;
7358
7359 int elemLength = 2;
7360 if (data == (KeyframeMotion.DataFormat.Translation | KeyframeMotion.DataFormat.Rotation))
7361 elemLength = 3;
7362
7363 List<KeyframeMotion.Keyframe> keyframes = new List<KeyframeMotion.Keyframe>();
7364 while (idx < frames.Data.Length)
7365 {
7366 int remain = frames.Data.Length - idx;
7367
7368 if (remain < elemLength)
7369 break;
7370
7371 KeyframeMotion.Keyframe frame = new KeyframeMotion.Keyframe();
7372 frame.Position = null;
7373 frame.Rotation = null;
7374
7375 if ((data & KeyframeMotion.DataFormat.Translation) != 0)
7376 {
7377 LSL_Types.Vector3 tempv = frames.GetVector3Item(idx++);
7378 frame.Position = new Vector3((float)tempv.x, (float)tempv.y, (float)tempv.z);
7379 }
7380 if ((data & KeyframeMotion.DataFormat.Rotation) != 0)
7381 {
7382 LSL_Types.Quaternion tempq = frames.GetQuaternionItem(idx++);
7383 Quaternion q = new Quaternion((float)tempq.x, (float)tempq.y, (float)tempq.z, (float)tempq.s);
7384 q.Normalize();
7385 frame.Rotation = q;
7386 }
7387
7388 float tempf = (float)frames.GetLSLFloatItem(idx++);
7389 frame.TimeMS = (int)(tempf * 1000.0f);
7390
7391 keyframes.Add(frame);
7392 }
7393
7394 group.RootPart.KeyframeMotion.SetKeyframes(keyframes.ToArray());
7395 group.RootPart.KeyframeMotion.Start();
7396 }
7397 else
7398 {
7399 if (group.RootPart.KeyframeMotion == null)
7400 return;
7401
7402 if (options.Data.Length == 0)
7403 {
7404 group.RootPart.KeyframeMotion.Stop();
7405 return;
7406 }
7407
7408 int code = (int)options.GetLSLIntegerItem(0);
7409
7410 int idx = 0;
7411
7412 while (idx < options.Data.Length)
7413 {
7414 int option = (int)options.GetLSLIntegerItem(idx++);
7415 int remain = options.Data.Length - idx;
7416
7417 switch (option)
7418 {
7419 case ScriptBaseClass.KFM_COMMAND:
7420 int cmd = (int)options.GetLSLIntegerItem(idx++);
7421 switch (cmd)
7422 {
7423 case ScriptBaseClass.KFM_CMD_PLAY:
7424 group.RootPart.KeyframeMotion.Start();
7425 break;
7426 case ScriptBaseClass.KFM_CMD_STOP:
7427 group.RootPart.KeyframeMotion.Stop();
7428 break;
7429 case ScriptBaseClass.KFM_CMD_PAUSE:
7430 group.RootPart.KeyframeMotion.Pause();
7431 break;
7432 }
7433 break;
7434 }
7435 }
7436 }
7437 }
7438
7299 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed) 7439 protected LSL_List SetPrimParams(SceneObjectPart part, LSL_List rules, string originFunc, ref uint rulesParsed)
7300 { 7440 {
7301 int idx = 0; 7441 int idx = 0;
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
index 4ac179a..a6ea88c 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Interface/ILSL_Api.cs
@@ -427,6 +427,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api.Interfaces
427 void print(string str); 427 void print(string str);
428 428
429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc); 429 void SetPrimitiveParamsEx(LSL_Key prim, LSL_List rules, string originFunc);
430 void llSetKeyframedMotion(LSL_List frames, LSL_List options);
430 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules); 431 LSL_List GetPrimitiveParamsEx(LSL_Key prim, LSL_List rules);
431 } 432 }
432} 433}
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
index dc5ef13..559068d 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Constants.cs
@@ -748,6 +748,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
748 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2; 748 public static readonly LSLInteger RCERR_SIM_PERF_LOW = -2;
749 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3; 749 public static readonly LSLInteger RCERR_CAST_TIME_EXCEEDED = 3;
750 750
751 public const int KFM_MODE = 1;
752 public const int KFM_LOOP = 1;
753 public const int KFM_REVERSE = 3;
754 public const int KFM_FORWARD = 0;
755 public const int KFM_PING_PONG = 2;
756 public const int KFM_DATA = 2;
757 public const int KFM_TRANSLATION = 2;
758 public const int KFM_ROTATION = 1;
759 public const int KFM_COMMAND = 0;
760 public const int KFM_CMD_PLAY = 0;
761 public const int KFM_CMD_STOP = 1;
762 public const int KFM_CMD_PAUSE = 2;
763
751 /// <summary> 764 /// <summary>
752 /// process name parameter as regex 765 /// process name parameter as regex
753 /// </summary> 766 /// </summary>
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
index c7a7cf6..398c125 100644
--- a/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
+++ b/OpenSim/Region/ScriptEngine/Shared/Api/Runtime/LSL_Stub.cs
@@ -554,6 +554,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.ScriptBase
554 return m_LSL_Functions.llGetLinkNumberOfSides(link); 554 return m_LSL_Functions.llGetLinkNumberOfSides(link);
555 } 555 }
556 556
557 public void llSetKeyframedMotion(LSL_List frames, LSL_List options)
558 {
559 m_LSL_Functions.llSetKeyframedMotion(frames, options);
560 }
561
557 public LSL_Integer llGetListEntryType(LSL_List src, int index) 562 public LSL_Integer llGetListEntryType(LSL_List src, int index)
558 { 563 {
559 return m_LSL_Functions.llGetListEntryType(src, index); 564 return m_LSL_Functions.llGetListEntryType(src, index);