aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Animation
diff options
context:
space:
mode:
authorMelanie2009-11-18 06:20:21 +0000
committerMelanie2009-11-18 06:20:21 +0000
commit5d0778014df68b48abb08c8f63204cf7e077af7f (patch)
tree5f6ef28958950412130f68fa3bbe1491a456eef7 /OpenSim/Region/Framework/Scenes/Animation
parentMerge branch 'master' into careminster (diff)
parentChange PresenceData to PresenceInfo to remove a naming conflict in the (diff)
downloadopensim-SC-5d0778014df68b48abb08c8f63204cf7e077af7f.zip
opensim-SC-5d0778014df68b48abb08c8f63204cf7e077af7f.tar.gz
opensim-SC-5d0778014df68b48abb08c8f63204cf7e077af7f.tar.bz2
opensim-SC-5d0778014df68b48abb08c8f63204cf7e077af7f.tar.xz
Merge branch 'master' into careminster
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Animation')
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs185
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs63
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/BinBVHAnimation.cs643
-rw-r--r--OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs448
4 files changed, 1339 insertions, 0 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
new file mode 100644
index 0000000..9176d3d
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/AnimationSet.cs
@@ -0,0 +1,185 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenSim.Framework;
31using OpenMetaverse;
32
33using Animation = OpenSim.Framework.Animation;
34
35namespace OpenSim.Region.Framework.Scenes.Animation
36{
37 [Serializable]
38 public class AnimationSet
39 {
40 public static AvatarAnimations Animations = new AvatarAnimations();
41
42 private OpenSim.Framework.Animation m_defaultAnimation = new OpenSim.Framework.Animation();
43 private List<OpenSim.Framework.Animation> m_animations = new List<OpenSim.Framework.Animation>();
44
45 public OpenSim.Framework.Animation DefaultAnimation
46 {
47 get { return m_defaultAnimation; }
48 }
49
50 public AnimationSet()
51 {
52 ResetDefaultAnimation();
53 }
54
55 public bool HasAnimation(UUID animID)
56 {
57 if (m_defaultAnimation.AnimID == animID)
58 return true;
59
60 for (int i = 0; i < m_animations.Count; ++i)
61 {
62 if (m_animations[i].AnimID == animID)
63 return true;
64 }
65
66 return false;
67 }
68
69 public bool Add(UUID animID, int sequenceNum, UUID objectID)
70 {
71 lock (m_animations)
72 {
73 if (!HasAnimation(animID))
74 {
75 m_animations.Add(new OpenSim.Framework.Animation(animID, sequenceNum, objectID));
76 return true;
77 }
78 }
79 return false;
80 }
81
82 public bool Remove(UUID animID)
83 {
84 lock (m_animations)
85 {
86 if (m_defaultAnimation.AnimID == animID)
87 {
88 ResetDefaultAnimation();
89 }
90 else if (HasAnimation(animID))
91 {
92 for (int i = 0; i < m_animations.Count; i++)
93 {
94 if (m_animations[i].AnimID == animID)
95 {
96 m_animations.RemoveAt(i);
97 return true;
98 }
99 }
100 }
101 }
102 return false;
103 }
104
105 public void Clear()
106 {
107 ResetDefaultAnimation();
108 m_animations.Clear();
109 }
110
111 /// <summary>
112 /// The default animation is reserved for "main" animations
113 /// that are mutually exclusive, e.g. flying and sitting.
114 /// </summary>
115 public bool SetDefaultAnimation(UUID animID, int sequenceNum, UUID objectID)
116 {
117 if (m_defaultAnimation.AnimID != animID)
118 {
119 m_defaultAnimation = new OpenSim.Framework.Animation(animID, sequenceNum, objectID);
120 return true;
121 }
122 return false;
123 }
124
125 protected bool ResetDefaultAnimation()
126 {
127 return TrySetDefaultAnimation("STAND", 1, UUID.Zero);
128 }
129
130 /// <summary>
131 /// Set the animation as the default animation if it's known
132 /// </summary>
133 public bool TrySetDefaultAnimation(string anim, int sequenceNum, UUID objectID)
134 {
135 if (Animations.AnimsUUID.ContainsKey(anim))
136 {
137 return SetDefaultAnimation(Animations.AnimsUUID[anim], sequenceNum, objectID);
138 }
139 return false;
140 }
141
142 public void GetArrays(out UUID[] animIDs, out int[] sequenceNums, out UUID[] objectIDs)
143 {
144 lock (m_animations)
145 {
146 animIDs = new UUID[m_animations.Count + 1];
147 sequenceNums = new int[m_animations.Count + 1];
148 objectIDs = new UUID[m_animations.Count + 1];
149
150 animIDs[0] = m_defaultAnimation.AnimID;
151 sequenceNums[0] = m_defaultAnimation.SequenceNum;
152 objectIDs[0] = m_defaultAnimation.ObjectID;
153
154 for (int i = 0; i < m_animations.Count; ++i)
155 {
156 animIDs[i + 1] = m_animations[i].AnimID;
157 sequenceNums[i + 1] = m_animations[i].SequenceNum;
158 objectIDs[i + 1] = m_animations[i].ObjectID;
159 }
160 }
161 }
162
163 public OpenSim.Framework.Animation[] ToArray()
164 {
165 OpenSim.Framework.Animation[] theArray = new OpenSim.Framework.Animation[m_animations.Count];
166 uint i = 0;
167 try
168 {
169 foreach (OpenSim.Framework.Animation anim in m_animations)
170 theArray[i++] = anim;
171 }
172 catch
173 {
174 /* S%^t happens. Ignore. */
175 }
176 return theArray;
177 }
178
179 public void FromArray(OpenSim.Framework.Animation[] theArray)
180 {
181 foreach (OpenSim.Framework.Animation anim in theArray)
182 m_animations.Add(anim);
183 }
184 }
185}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs b/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs
new file mode 100644
index 0000000..659c3a5
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/AvatarAnimations.cs
@@ -0,0 +1,63 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System.Collections.Generic;
29using System.Xml;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Framework.Scenes.Animation
33{
34 public class AvatarAnimations
35 {
36 public Dictionary<string, UUID> AnimsUUID = new Dictionary<string, UUID>();
37 public Dictionary<UUID, string> AnimsNames = new Dictionary<UUID, string>();
38 public Dictionary<UUID, string> AnimStateNames = new Dictionary<UUID, string>();
39
40 public AvatarAnimations()
41 {
42 using (XmlTextReader reader = new XmlTextReader("data/avataranimations.xml"))
43 {
44 XmlDocument doc = new XmlDocument();
45 doc.Load(reader);
46 foreach (XmlNode nod in doc.DocumentElement.ChildNodes)
47 {
48 if (nod.Attributes["name"] != null)
49 {
50 string name = (string)nod.Attributes["name"].Value;
51 UUID id = (UUID)nod.InnerText;
52 string animState = (string)nod.Attributes["state"].Value;
53
54 AnimsUUID.Add(name, id);
55 AnimsNames.Add(id, name);
56 if (animState != "")
57 AnimStateNames.Add(id, animState);
58 }
59 }
60 }
61 }
62 }
63}
diff --git a/OpenSim/Region/Framework/Scenes/Animation/BinBVHAnimation.cs b/OpenSim/Region/Framework/Scenes/Animation/BinBVHAnimation.cs
new file mode 100644
index 0000000..3afc87f
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/BinBVHAnimation.cs
@@ -0,0 +1,643 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.IO;
30using OpenMetaverse;
31
32namespace OpenSim.Region.Framework.Scenes.Animation
33{
34 /// <summary>
35 /// Written to decode and encode a binary animation asset.
36 /// The SecondLife Client reads in a BVH file and converts
37 /// it to the format described here. This isn't
38 /// </summary>
39 public class BinBVHAnimation
40 {
41 /// <summary>
42 /// Rotation Keyframe count (used internally)
43 /// Don't use this, use the rotationkeys.Length on each joint
44 /// </summary>
45 private int rotationkeys;
46
47 /// <summary>
48 /// Position Keyframe count (used internally)
49 /// Don't use this, use the positionkeys.Length on each joint
50 /// </summary>
51 private int positionkeys;
52
53 public UInt16 unknown0; // Always 1
54 public UInt16 unknown1; // Always 0
55
56 /// <summary>
57 /// Animation Priority
58 /// </summary>
59 public int Priority;
60
61 /// <summary>
62 /// The animation length in seconds.
63 /// </summary>
64 public Single Length;
65
66 /// <summary>
67 /// Expression set in the client. Null if [None] is selected
68 /// </summary>
69 public string ExpressionName; // "" (null)
70
71 /// <summary>
72 /// The time in seconds to start the animation
73 /// </summary>
74 public Single InPoint;
75
76 /// <summary>
77 /// The time in seconds to end the animation
78 /// </summary>
79 public Single OutPoint;
80
81 /// <summary>
82 /// Loop the animation
83 /// </summary>
84 public bool Loop;
85
86 /// <summary>
87 /// Meta data. Ease in Seconds.
88 /// </summary>
89 public Single EaseInTime;
90
91 /// <summary>
92 /// Meta data. Ease out seconds.
93 /// </summary>
94 public Single EaseOutTime;
95
96 /// <summary>
97 /// Meta Data for the Hand Pose
98 /// </summary>
99 public uint HandPose;
100
101 /// <summary>
102 /// Number of joints defined in the animation
103 /// Don't use this.. use joints.Length
104 /// </summary>
105 private uint m_jointCount;
106
107
108 /// <summary>
109 /// Contains an array of joints
110 /// </summary>
111 public binBVHJoint[] Joints;
112
113
114 public byte[] ToBytes()
115 {
116 byte[] outputbytes = new byte[0];
117
118 BinaryWriter iostream = new BinaryWriter(new MemoryStream());
119 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown0)));
120 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(unknown1)));
121 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority)));
122 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(Length)));
123 iostream.Write(BinBVHUtil.WriteNullTerminatedString(ExpressionName));
124 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(InPoint)));
125 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(OutPoint)));
126 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Loop ? 1 : 0)));
127 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(EaseInTime)));
128 iostream.Write(BinBVHUtil.ES(Utils.FloatToBytes(EaseOutTime)));
129 iostream.Write(BinBVHUtil.ES(Utils.UIntToBytes(HandPose)));
130 iostream.Write(BinBVHUtil.ES(Utils.UIntToBytes((uint)(Joints.Length))));
131
132 for (int i = 0; i < Joints.Length; i++)
133 {
134 Joints[i].WriteBytesToStream(iostream, InPoint, OutPoint);
135 }
136 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(0)));
137 MemoryStream ms = (MemoryStream)iostream.BaseStream;
138 outputbytes = ms.ToArray();
139 ms.Close();
140 iostream.Close();
141 return outputbytes;
142 }
143
144 public BinBVHAnimation()
145 {
146 rotationkeys = 0;
147 positionkeys = 0;
148 unknown0 = 1;
149 unknown1 = 0;
150 Priority = 1;
151 Length = 0;
152 ExpressionName = string.Empty;
153 InPoint = 0;
154 OutPoint = 0;
155 Loop = false;
156 EaseInTime = 0;
157 EaseOutTime = 0;
158 HandPose = 1;
159 m_jointCount = 0;
160
161 Joints = new binBVHJoint[1];
162 Joints[0] = new binBVHJoint();
163 Joints[0].Name = "mPelvis";
164 Joints[0].Priority = 7;
165 Joints[0].positionkeys = new binBVHJointKey[1];
166 Joints[0].rotationkeys = new binBVHJointKey[1];
167 Random rnd = new Random();
168
169 Joints[0].rotationkeys[0] = new binBVHJointKey();
170 Joints[0].rotationkeys[0].time = (0f);
171 Joints[0].rotationkeys[0].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
172 Joints[0].rotationkeys[0].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
173 Joints[0].rotationkeys[0].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
174
175 Joints[0].positionkeys[0] = new binBVHJointKey();
176 Joints[0].positionkeys[0].time = (0f);
177 Joints[0].positionkeys[0].key_element.X = ((float)rnd.NextDouble() * 2 - 1);
178 Joints[0].positionkeys[0].key_element.Y = ((float)rnd.NextDouble() * 2 - 1);
179 Joints[0].positionkeys[0].key_element.Z = ((float)rnd.NextDouble() * 2 - 1);
180
181
182 }
183
184 public BinBVHAnimation(byte[] animationdata)
185 {
186 int i = 0;
187 if (!BitConverter.IsLittleEndian)
188 {
189 unknown0 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata,i,2)); i += 2; // Always 1
190 unknown1 = Utils.BytesToUInt16(BinBVHUtil.EndianSwap(animationdata, i, 2)); i += 2; // Always 0
191 Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4;
192 Length = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
193 }
194 else
195 {
196 unknown0 = Utils.BytesToUInt16(animationdata, i); i += 2; // Always 1
197 unknown1 = Utils.BytesToUInt16(animationdata, i); i += 2; // Always 0
198 Priority = Utils.BytesToInt(animationdata, i); i += 4;
199 Length = Utils.BytesToFloat(animationdata, i); i += 4;
200 }
201 ExpressionName = ReadBytesUntilNull(animationdata, ref i);
202 if (!BitConverter.IsLittleEndian)
203 {
204 InPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
205 OutPoint = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
206 Loop = (Utils.BytesToInt(BinBVHUtil.EndianSwap(animationdata, i, 4)) != 0); i += 4;
207 EaseInTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
208 EaseOutTime = Utils.BytesToFloat(BinBVHUtil.EndianSwap(animationdata, i, 4), 0); i += 4;
209 HandPose = Utils.BytesToUInt(BinBVHUtil.EndianSwap(animationdata, i, 4)); i += 4; // Handpose?
210
211 m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; // Get Joint count
212 }
213 else
214 {
215 InPoint = Utils.BytesToFloat(animationdata, i); i += 4;
216 OutPoint = Utils.BytesToFloat(animationdata, i); i += 4;
217 Loop = (Utils.BytesToInt(animationdata, i) != 0); i += 4;
218 EaseInTime = Utils.BytesToFloat(animationdata, i); i += 4;
219 EaseOutTime = Utils.BytesToFloat(animationdata, i); i += 4;
220 HandPose = Utils.BytesToUInt(animationdata, i); i += 4; // Handpose?
221
222 m_jointCount = Utils.BytesToUInt(animationdata, i); i += 4; // Get Joint count
223 }
224 Joints = new binBVHJoint[m_jointCount];
225
226 // deserialize the number of joints in the animation.
227 // Joints are variable length blocks of binary data consisting of joint data and keyframes
228 for (int iter = 0; iter < m_jointCount; iter++)
229 {
230 binBVHJoint joint = readJoint(animationdata, ref i);
231 Joints[iter] = joint;
232 }
233 }
234
235
236 /// <summary>
237 /// Variable length strings seem to be null terminated in the animation asset.. but..
238 /// use with caution, home grown.
239 /// advances the index.
240 /// </summary>
241 /// <param name="data">The animation asset byte array</param>
242 /// <param name="i">The offset to start reading</param>
243 /// <returns>a string</returns>
244 private static string ReadBytesUntilNull(byte[] data, ref int i)
245 {
246 char nterm = '\0'; // Null terminator
247 int endpos = i;
248 int startpos = i;
249
250 // Find the null character
251 for (int j = i; j < data.Length; j++)
252 {
253 char spot = Convert.ToChar(data[j]);
254 if (spot == nterm)
255 {
256 endpos = j;
257 break;
258 }
259 }
260
261 // if we got to the end, then it's a zero length string
262 if (i == endpos)
263 {
264 // advance the 1 null character
265 i++;
266 return string.Empty;
267 }
268 else
269 {
270 // We found the end of the string
271 // append the bytes from the beginning of the string to the end of the string
272 // advance i
273 byte[] interm = new byte[endpos-i];
274 for (; i<endpos; i++)
275 {
276 interm[i-startpos] = data[i];
277 }
278 i++; // advance past the null character
279
280 return Utils.BytesToString(interm);
281 }
282 }
283
284 /// <summary>
285 /// Read in a Joint from an animation asset byte array
286 /// Variable length Joint fields, yay!
287 /// Advances the index
288 /// </summary>
289 /// <param name="data">animation asset byte array</param>
290 /// <param name="i">Byte Offset of the start of the joint</param>
291 /// <returns>The Joint data serialized into the binBVHJoint structure</returns>
292 private binBVHJoint readJoint(byte[] data, ref int i)
293 {
294
295 binBVHJointKey[] positions;
296 binBVHJointKey[] rotations;
297
298 binBVHJoint pJoint = new binBVHJoint();
299
300 /*
301 109
302 84
303 111
304 114
305 114
306 111
307 0 <--- Null terminator
308 */
309
310 pJoint.Name = ReadBytesUntilNull(data, ref i); // Joint name
311
312 /*
313 2 <- Priority Revisited
314 0
315 0
316 0
317 */
318
319 /*
320 5 <-- 5 keyframes
321 0
322 0
323 0
324 ... 5 Keyframe data blocks
325 */
326
327 /*
328 2 <-- 2 keyframes
329 0
330 0
331 0
332 .. 2 Keyframe data blocks
333 */
334 if (!BitConverter.IsLittleEndian)
335 {
336 pJoint.Priority = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // Joint Priority override?
337 rotationkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // How many rotation keyframes
338 }
339 else
340 {
341 pJoint.Priority = Utils.BytesToInt(data, i); i += 4; // Joint Priority override?
342 rotationkeys = Utils.BytesToInt(data, i); i += 4; // How many rotation keyframes
343 }
344
345 // argh! floats into two bytes!.. bad bad bad bad
346 // After fighting with it for a while.. -1, to 1 seems to give the best results
347 rotations = readKeys(data, ref i, rotationkeys, -1f, 1f);
348 for (int iter = 0; iter < rotations.Length; iter++)
349 {
350 rotations[iter].W = 1f -
351 (rotations[iter].key_element.X + rotations[iter].key_element.Y +
352 rotations[iter].key_element.Z);
353 }
354
355
356 if (!BitConverter.IsLittleEndian)
357 {
358 positionkeys = Utils.BytesToInt(BinBVHUtil.EndianSwap(data, i, 4)); i += 4; // How many position keyframes
359 }
360 else
361 {
362 positionkeys = Utils.BytesToInt(data, i); i += 4; // How many position keyframes
363 }
364
365 // Read in position keyframes
366 // argh! more floats into two bytes!.. *head desk*
367 // After fighting with it for a while.. -5, to 5 seems to give the best results
368 positions = readKeys(data, ref i, positionkeys, -5f, 5f);
369
370 pJoint.rotationkeys = rotations;
371 pJoint.positionkeys = positions;
372
373 return pJoint;
374 }
375
376 /// <summary>
377 /// Read Keyframes of a certain type
378 /// advance i
379 /// </summary>
380 /// <param name="data">Animation Byte array</param>
381 /// <param name="i">Offset in the Byte Array. Will be advanced</param>
382 /// <param name="keycount">Number of Keyframes</param>
383 /// <param name="min">Scaling Min to pass to the Uint16ToFloat method</param>
384 /// <param name="max">Scaling Max to pass to the Uint16ToFloat method</param>
385 /// <returns></returns>
386 private binBVHJointKey[] readKeys(byte[] data, ref int i, int keycount, float min, float max)
387 {
388 float x;
389 float y;
390 float z;
391
392 /*
393 0.o, Float values in Two bytes.. this is just wrong >:(
394 17 255 <-- Time Code
395 17 255 <-- Time Code
396 255 255 <-- X
397 127 127 <-- X
398 255 255 <-- Y
399 127 127 <-- Y
400 213 213 <-- Z
401 142 142 <---Z
402
403 */
404
405 binBVHJointKey[] m_keys = new binBVHJointKey[keycount];
406 for (int j = 0; j < keycount; j++)
407 {
408 binBVHJointKey pJKey = new binBVHJointKey();
409 if (!BitConverter.IsLittleEndian)
410 {
411 pJKey.time = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, InPoint, OutPoint); i += 2;
412 x = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
413 y = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
414 z = Utils.UInt16ToFloat(BinBVHUtil.EndianSwap(data, i, 2), 0, min, max); i += 2;
415 }
416 else
417 {
418 pJKey.time = Utils.UInt16ToFloat(data, i, InPoint, OutPoint); i += 2;
419 x = Utils.UInt16ToFloat(data, i, min, max); i += 2;
420 y = Utils.UInt16ToFloat(data, i, min, max); i += 2;
421 z = Utils.UInt16ToFloat(data, i, min, max); i += 2;
422 }
423 pJKey.key_element = new Vector3(x, y, z);
424 m_keys[j] = pJKey;
425 }
426 return m_keys;
427 }
428
429
430
431 }
432 /// <summary>
433 /// A Joint and it's associated meta data and keyframes
434 /// </summary>
435 public struct binBVHJoint
436 {
437 /// <summary>
438 /// Name of the Joint. Matches the avatar_skeleton.xml in client distros
439 /// </summary>
440 public string Name;
441
442 /// <summary>
443 /// Joint Animation Override? Was the same as the Priority in testing..
444 /// </summary>
445 public int Priority;
446
447 /// <summary>
448 /// Array of Rotation Keyframes in order from earliest to latest
449 /// </summary>
450 public binBVHJointKey[] rotationkeys;
451
452 /// <summary>
453 /// Array of Position Keyframes in order from earliest to latest
454 /// This seems to only be for the Pelvis?
455 /// </summary>
456 public binBVHJointKey[] positionkeys;
457
458
459
460 public void WriteBytesToStream(BinaryWriter iostream, float InPoint, float OutPoint)
461 {
462 iostream.Write(BinBVHUtil.WriteNullTerminatedString(Name));
463 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(Priority)));
464 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes(rotationkeys.Length)));
465 for (int i=0;i<rotationkeys.Length;i++)
466 {
467 rotationkeys[i].WriteBytesToStream(iostream, InPoint, OutPoint, -1f, 1f);
468 }
469 iostream.Write(BinBVHUtil.ES(Utils.IntToBytes((positionkeys.Length))));
470 for (int i = 0; i < positionkeys.Length; i++)
471 {
472 positionkeys[i].WriteBytesToStream(iostream, InPoint, OutPoint, -256f, 256f);
473 }
474 }
475 }
476
477 /// <summary>
478 /// A Joint Keyframe. This is either a position or a rotation.
479 /// </summary>
480 public struct binBVHJointKey
481 {
482 // Time in seconds for this keyframe.
483 public float time;
484
485 /// <summary>
486 /// Either a Vector3 position or a Vector3 Euler rotation
487 /// </summary>
488 public Vector3 key_element;
489
490 public float W;
491
492 public void WriteBytesToStream(BinaryWriter iostream, float InPoint, float OutPoint, float min, float max)
493 {
494 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(time, InPoint, OutPoint))));
495 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.X, min, max))));
496 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.Y, min, max))));
497 iostream.Write(BinBVHUtil.ES(Utils.UInt16ToBytes(BinBVHUtil.FloatToUInt16(key_element.Z, min, max))));
498 }
499 }
500
501 /// <summary>
502 /// Poses set in the animation metadata for the hands.
503 /// </summary>
504 public enum HandPose : uint
505 {
506 Spread = 0,
507 Relaxed = 1,
508 Point_Both = 2,
509 Fist = 3,
510 Relaxed_Left = 4,
511 Point_Left = 5,
512 Fist_Left = 6,
513 Relaxed_Right = 7,
514 Point_Right = 8,
515 Fist_Right = 9,
516 Salute_Right = 10,
517 Typing = 11,
518 Peace_Right = 12
519 }
520 public static class BinBVHUtil
521 {
522 public const float ONE_OVER_U16_MAX = 1.0f / UInt16.MaxValue;
523
524 public static UInt16 FloatToUInt16(float val, float lower, float upper)
525 {
526 UInt16 uival = 0;
527 //m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue
528 //0-1
529
530// float difference = upper - lower;
531 // we're trying to get a zero lower and modify all values equally so we get a percentage position
532 if (lower > 0)
533 {
534 upper -= lower;
535 val = val - lower;
536
537 // start with 500 upper and 200 lower.. subtract 200 from the upper and the value
538 }
539 else //if (lower < 0 && upper > 0)
540 {
541 // double negative, 0 minus negative 5 is 5.
542 upper += 0 - lower;
543 lower += 0 - lower;
544 val += 0 - lower;
545 }
546
547 if (upper == 0)
548 val = 0;
549 else
550 {
551 val /= upper;
552 }
553
554 uival = (UInt16)(val * UInt16.MaxValue);
555
556 return uival;
557 }
558
559
560 /// <summary>
561 /// Endian Swap
562 /// Swaps endianness if necessary
563 /// </summary>
564 /// <param name="arr">Input array</param>
565 /// <returns></returns>
566 public static byte[] ES(byte[] arr)
567 {
568 if (!BitConverter.IsLittleEndian)
569 Array.Reverse(arr);
570 return arr;
571 }
572 public static byte[] EndianSwap(byte[] arr, int offset, int len)
573 {
574 byte[] bendian = new byte[offset + len];
575 Buffer.BlockCopy(arr, offset, bendian, 0, len);
576 Array.Reverse(bendian);
577 return bendian;
578 }
579
580 public static byte[] WriteNullTerminatedString(string str)
581 {
582 byte[] output = new byte[str.Length + 1];
583 Char[] chr = str.ToCharArray();
584 int i = 0;
585 for (i = 0; i < chr.Length; i++)
586 {
587 output[i] = Convert.ToByte(chr[i]);
588
589 }
590
591 output[i] = Convert.ToByte('\0');
592 return output;
593 }
594
595 }
596}
597/*
598switch (jointname)
599 {
600 case "mPelvis":
601 case "mTorso":
602 case "mNeck":
603 case "mHead":
604 case "mChest":
605 case "mHipLeft":
606 case "mHipRight":
607 case "mKneeLeft":
608 case "mKneeRight":
609 // XYZ->ZXY
610 t = x;
611 x = y;
612 y = t;
613 break;
614 case "mCollarLeft":
615 case "mCollarRight":
616 case "mElbowLeft":
617 case "mElbowRight":
618 // YZX ->ZXY
619 t = z;
620 z = x;
621 x = y;
622 y = t;
623 break;
624 case "mWristLeft":
625 case "mWristRight":
626 case "mShoulderLeft":
627 case "mShoulderRight":
628 // ZYX->ZXY
629 t = y;
630 y = z;
631 z = t;
632
633 break;
634 case "mAnkleLeft":
635 case "mAnkleRight":
636 // XYZ ->ZXY
637 t = x;
638 x = z;
639 z = y;
640 y = t;
641 break;
642 }
643*/ \ No newline at end of file
diff --git a/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
new file mode 100644
index 0000000..cbe4118
--- /dev/null
+++ b/OpenSim/Region/Framework/Scenes/Animation/ScenePresenceAnimator.cs
@@ -0,0 +1,448 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using OpenMetaverse;
31using OpenSim.Framework;
32using OpenSim.Region.Framework.Interfaces;
33using OpenSim.Region.Framework.Scenes;
34using OpenSim.Region.Physics.Manager;
35
36namespace OpenSim.Region.Framework.Scenes.Animation
37{
38 /// <summary>
39 /// Handle all animation duties for a scene presence
40 /// </summary>
41 public class ScenePresenceAnimator
42 {
43 public AnimationSet Animations
44 {
45 get { return m_animations; }
46 }
47 protected AnimationSet m_animations = new AnimationSet();
48
49 /// <value>
50 /// The current movement animation
51 /// </value>
52 public string CurrentMovementAnimation
53 {
54 get { return m_movementAnimation; }
55 }
56 protected string m_movementAnimation = "DEFAULT";
57
58 private int m_animTickFall;
59 private int m_animTickJump;
60
61 /// <value>
62 /// The scene presence that this animator applies to
63 /// </value>
64 protected ScenePresence m_scenePresence;
65
66 public ScenePresenceAnimator(ScenePresence sp)
67 {
68 m_scenePresence = sp;
69 }
70
71 public void AddAnimation(UUID animID, UUID objectID)
72 {
73 if (m_scenePresence.IsChildAgent)
74 return;
75
76 if (m_animations.Add(animID, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, objectID))
77 SendAnimPack();
78 }
79
80 // Called from scripts
81 public void AddAnimation(string name, UUID objectID)
82 {
83 if (m_scenePresence.IsChildAgent)
84 return;
85
86 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name);
87 if (animID == UUID.Zero)
88 return;
89
90 AddAnimation(animID, objectID);
91 }
92
93 public void RemoveAnimation(UUID animID)
94 {
95 if (m_scenePresence.IsChildAgent)
96 return;
97
98 if (m_animations.Remove(animID))
99 SendAnimPack();
100 }
101
102 // Called from scripts
103 public void RemoveAnimation(string name)
104 {
105 if (m_scenePresence.IsChildAgent)
106 return;
107
108 UUID animID = m_scenePresence.ControllingClient.GetDefaultAnimation(name);
109 if (animID == UUID.Zero)
110 return;
111
112 RemoveAnimation(animID);
113 }
114
115 public void ResetAnimations()
116 {
117 m_animations.Clear();
118 }
119
120 /// <summary>
121 /// The movement animation is reserved for "main" animations
122 /// that are mutually exclusive, e.g. flying and sitting.
123 /// </summary>
124 public void TrySetMovementAnimation(string anim)
125 {
126 //m_log.DebugFormat("Updating movement animation to {0}", anim);
127
128 if (!m_scenePresence.IsChildAgent)
129 {
130 if (m_animations.TrySetDefaultAnimation(
131 anim, m_scenePresence.ControllingClient.NextAnimationSequenceNumber, UUID.Zero))
132 {
133 // 16384 is CHANGED_ANIMATION
134 m_scenePresence.SendScriptEventToAttachments("changed", new Object[] { 16384 });
135 SendAnimPack();
136 }
137 }
138 }
139
140 /// <summary>
141 /// This method determines the proper movement related animation
142 /// </summary>
143 public string GetMovementAnimation()
144 {
145 const float FALL_DELAY = 0.33f;
146 const float PREJUMP_DELAY = 0.25f;
147
148 #region Inputs
149
150 AgentManager.ControlFlags controlFlags = (AgentManager.ControlFlags)m_scenePresence.AgentControlFlags;
151 PhysicsActor actor = m_scenePresence.PhysicsActor;
152
153 // Create forward and left vectors from the current avatar rotation
154 Matrix4 rotMatrix = Matrix4.CreateFromQuaternion(m_scenePresence.Rotation);
155 Vector3 fwd = Vector3.Transform(Vector3.UnitX, rotMatrix);
156 Vector3 left = Vector3.Transform(Vector3.UnitY, rotMatrix);
157
158 // Check control flags
159 bool heldForward = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_AT_POS;
160 bool heldBack = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG;
161 bool heldLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS;
162 bool heldRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG;
163 //bool heldTurnLeft = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_LEFT;
164 //bool heldTurnRight = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT) == AgentManager.ControlFlags.AGENT_CONTROL_TURN_RIGHT;
165 bool heldUp = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) == AgentManager.ControlFlags.AGENT_CONTROL_UP_POS;
166 bool heldDown = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) == AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG;
167 //bool flying = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) == AgentManager.ControlFlags.AGENT_CONTROL_FLY;
168 //bool mouselook = (controlFlags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) == AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK;
169
170 // Direction in which the avatar is trying to move
171 Vector3 move = Vector3.Zero;
172 if (heldForward) { move.X += fwd.X; move.Y += fwd.Y; }
173 if (heldBack) { move.X -= fwd.X; move.Y -= fwd.Y; }
174 if (heldLeft) { move.X += left.X; move.Y += left.Y; }
175 if (heldRight) { move.X -= left.X; move.Y -= left.Y; }
176 if (heldUp) { move.Z += 1; }
177 if (heldDown) { move.Z -= 1; }
178
179 // Is the avatar trying to move?
180// bool moving = (move != Vector3.Zero);
181 bool jumping = m_animTickJump != 0;
182
183 #endregion Inputs
184
185 #region Flying
186
187 if (actor != null && actor.Flying)
188 {
189 m_animTickFall = 0;
190 m_animTickJump = 0;
191
192 if (move.X != 0f || move.Y != 0f)
193 {
194 return (m_scenePresence.Scene.m_useFlySlow ? "FLYSLOW" : "FLY");
195 }
196 else if (move.Z > 0f)
197 {
198 return "HOVER_UP";
199 }
200 else if (move.Z < 0f)
201 {
202 if (actor != null && actor.IsColliding)
203 return "LAND";
204 else
205 return "HOVER_DOWN";
206 }
207 else
208 {
209 return "HOVER";
210 }
211 }
212
213 #endregion Flying
214
215 #region Falling/Floating/Landing
216
217 if (actor == null || !actor.IsColliding)
218 {
219 float fallElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
220 float fallVelocity = (actor != null) ? actor.Velocity.Z : 0.0f;
221
222 if (m_animTickFall == 0 || (fallElapsed > FALL_DELAY && fallVelocity >= 0.0f))
223 {
224 // Just started falling
225 m_animTickFall = Environment.TickCount;
226 }
227 else if (!jumping && fallElapsed > FALL_DELAY)
228 {
229 // Falling long enough to trigger the animation
230 return "FALLDOWN";
231 }
232
233 return m_movementAnimation;
234 }
235
236 #endregion Falling/Floating/Landing
237
238 #region Ground Movement
239
240 if (m_movementAnimation == "FALLDOWN")
241 {
242 m_animTickFall = Environment.TickCount;
243
244 // TODO: SOFT_LAND support
245 return "LAND";
246 }
247 else if (m_movementAnimation == "LAND")
248 {
249 float landElapsed = (float)(Environment.TickCount - m_animTickFall) / 1000f;
250
251 if (landElapsed <= FALL_DELAY)
252 return "LAND";
253 }
254
255 m_animTickFall = 0;
256
257 if (move.Z > 0f)
258 {
259 // Jumping
260 if (!jumping)
261 {
262 // Begin prejump
263 m_animTickJump = Environment.TickCount;
264 return "PREJUMP";
265 }
266 else if (Environment.TickCount - m_animTickJump > PREJUMP_DELAY * 1000.0f)
267 {
268 // Start actual jump
269 if (m_animTickJump == -1)
270 {
271 // Already jumping! End the current jump
272 m_animTickJump = 0;
273 return "JUMP";
274 }
275
276 m_animTickJump = -1;
277 return "JUMP";
278 }
279 }
280 else
281 {
282 // Not jumping
283 m_animTickJump = 0;
284
285 if (move.X != 0f || move.Y != 0f)
286 {
287 // Walking / crouchwalking / running
288 if (move.Z < 0f)
289 return "CROUCHWALK";
290 else if (m_scenePresence.SetAlwaysRun)
291 return "RUN";
292 else
293 return "WALK";
294 }
295 else
296 {
297 // Not walking
298 if (move.Z < 0f)
299 return "CROUCH";
300 else
301 return "STAND";
302 }
303 }
304
305 #endregion Ground Movement
306
307 return m_movementAnimation;
308 }
309
310 /// <summary>
311 /// Update the movement animation of this avatar according to its current state
312 /// </summary>
313 public void UpdateMovementAnimations()
314 {
315 m_movementAnimation = GetMovementAnimation();
316
317 if (m_movementAnimation == "PREJUMP" && !m_scenePresence.Scene.m_usePreJump)
318 {
319 // This was the previous behavior before PREJUMP
320 TrySetMovementAnimation("JUMP");
321 }
322 else
323 {
324 TrySetMovementAnimation(m_movementAnimation);
325 }
326 }
327
328 public UUID[] GetAnimationArray()
329 {
330 UUID[] animIDs;
331 int[] sequenceNums;
332 UUID[] objectIDs;
333 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
334 return animIDs;
335 }
336
337 public BinBVHAnimation GenerateRandomAnimation()
338 {
339 int rnditerations = 3;
340 BinBVHAnimation anim = new BinBVHAnimation();
341 List<string> parts = new List<string>();
342 parts.Add("mPelvis");parts.Add("mHead");parts.Add("mTorso");
343 parts.Add("mHipLeft");parts.Add("mHipRight");parts.Add("mHipLeft");parts.Add("mKneeLeft");
344 parts.Add("mKneeRight");parts.Add("mCollarLeft");parts.Add("mCollarRight");parts.Add("mNeck");
345 parts.Add("mElbowLeft");parts.Add("mElbowRight");parts.Add("mWristLeft");parts.Add("mWristRight");
346 parts.Add("mShoulderLeft");parts.Add("mShoulderRight");parts.Add("mAnkleLeft");parts.Add("mAnkleRight");
347 parts.Add("mEyeRight");parts.Add("mChest");parts.Add("mToeLeft");parts.Add("mToeRight");
348 parts.Add("mFootLeft");parts.Add("mFootRight");parts.Add("mEyeLeft");
349 anim.HandPose = 1;
350 anim.InPoint = 0;
351 anim.OutPoint = (rnditerations * .10f);
352 anim.Priority = 7;
353 anim.Loop = false;
354 anim.Length = (rnditerations * .10f);
355 anim.ExpressionName = "afraid";
356 anim.EaseInTime = 0;
357 anim.EaseOutTime = 0;
358
359 string[] strjoints = parts.ToArray();
360 anim.Joints = new binBVHJoint[strjoints.Length];
361 for (int j = 0; j < strjoints.Length; j++)
362 {
363 anim.Joints[j] = new binBVHJoint();
364 anim.Joints[j].Name = strjoints[j];
365 anim.Joints[j].Priority = 7;
366 anim.Joints[j].positionkeys = new binBVHJointKey[rnditerations];
367 anim.Joints[j].rotationkeys = new binBVHJointKey[rnditerations];
368 Random rnd = new Random();
369 for (int i = 0; i < rnditerations; i++)
370 {
371 anim.Joints[j].rotationkeys[i] = new binBVHJointKey();
372 anim.Joints[j].rotationkeys[i].time = (i*.10f);
373 anim.Joints[j].rotationkeys[i].key_element.X = ((float) rnd.NextDouble()*2 - 1);
374 anim.Joints[j].rotationkeys[i].key_element.Y = ((float) rnd.NextDouble()*2 - 1);
375 anim.Joints[j].rotationkeys[i].key_element.Z = ((float) rnd.NextDouble()*2 - 1);
376 anim.Joints[j].positionkeys[i] = new binBVHJointKey();
377 anim.Joints[j].positionkeys[i].time = (i*.10f);
378 anim.Joints[j].positionkeys[i].key_element.X = 0;
379 anim.Joints[j].positionkeys[i].key_element.Y = 0;
380 anim.Joints[j].positionkeys[i].key_element.Z = 0;
381 }
382 }
383
384 AssetBase Animasset = new AssetBase(UUID.Random(), "Random Animation", (sbyte)AssetType.Animation);
385 Animasset.Data = anim.ToBytes();
386 Animasset.Temporary = true;
387 Animasset.Local = true;
388 Animasset.Description = "dance";
389 //BinBVHAnimation bbvhanim = new BinBVHAnimation(Animasset.Data);
390
391 m_scenePresence.Scene.AssetService.Store(Animasset);
392 AddAnimation(Animasset.FullID, m_scenePresence.UUID);
393 return anim;
394 }
395
396 /// <summary>
397 ///
398 /// </summary>
399 /// <param name="animations"></param>
400 /// <param name="seqs"></param>
401 /// <param name="objectIDs"></param>
402 public void SendAnimPack(UUID[] animations, int[] seqs, UUID[] objectIDs)
403 {
404 if (m_scenePresence.IsChildAgent)
405 return;
406
407 m_scenePresence.Scene.ForEachClient(
408 delegate(IClientAPI client)
409 {
410 client.SendAnimations(animations, seqs, m_scenePresence.ControllingClient.AgentId, objectIDs);
411 });
412 }
413
414 public void SendAnimPackToClient(IClientAPI client)
415 {
416 if (m_scenePresence.IsChildAgent)
417 return;
418
419 UUID[] animIDs;
420 int[] sequenceNums;
421 UUID[] objectIDs;
422
423 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
424
425 m_scenePresence.ControllingClient.SendAnimations(
426 animIDs, sequenceNums, m_scenePresence.ControllingClient.AgentId, objectIDs);
427 }
428
429 /// <summary>
430 /// Send animation information about this avatar to all clients.
431 /// </summary>
432 public void SendAnimPack()
433 {
434 //m_log.Debug("Sending animation pack to all");
435
436 if (m_scenePresence.IsChildAgent)
437 return;
438
439 UUID[] animIDs;
440 int[] sequenceNums;
441 UUID[] objectIDs;
442
443 m_animations.GetArrays(out animIDs, out sequenceNums, out objectIDs);
444
445 SendAnimPack(animIDs, sequenceNums, objectIDs);
446 }
447 }
448} \ No newline at end of file