aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Framework/Scenes/KeyframeMotion.cs280
1 files changed, 165 insertions, 115 deletions
diff --git a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
index 4e6425f..5333177 100644
--- a/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
+++ b/OpenSim/Region/Framework/Scenes/KeyframeMotion.cs
@@ -53,9 +53,9 @@ namespace OpenSim.Region.Framework.Scenes
53 public Vector3 AngularVelocity; 53 public Vector3 AngularVelocity;
54 }; 54 };
55 55
56 private Vector3 m_serializedPosition;
56 private Vector3 m_basePosition; 57 private Vector3 m_basePosition;
57 private Quaternion m_baseRotation; 58 private Quaternion m_baseRotation;
58 private Vector3 m_serializedPosition;
59 59
60 private Keyframe m_currentFrame; 60 private Keyframe m_currentFrame;
61 61
@@ -78,7 +78,13 @@ namespace OpenSim.Region.Framework.Scenes
78 // skip timer events. 78 // skip timer events.
79 //timer.stop doesn't assure there aren't event threads still being fired 79 //timer.stop doesn't assure there aren't event threads still being fired
80 [NonSerialized()] 80 [NonSerialized()]
81 private bool m_skipOnTimer; 81 private bool m_timerStopped;
82
83 [NonSerialized()]
84 private bool m_crossing;
85
86 [NonSerialized()]
87 private int m_crossFailcntr;
82 88
83 // retry position for cross fail 89 // retry position for cross fail
84 [NonSerialized()] 90 [NonSerialized()]
@@ -107,6 +113,8 @@ namespace OpenSim.Region.Framework.Scenes
107 { 113 {
108 set 114 set
109 { 115 {
116 m_crossing = false;
117 m_crossFailcntr = 0;
110 if (!value) 118 if (!value)
111 { 119 {
112 // Once we're let go, recompute positions 120 // Once we're let go, recompute positions
@@ -117,39 +125,58 @@ namespace OpenSim.Region.Framework.Scenes
117 { 125 {
118 // Save selection position in case we get moved 126 // Save selection position in case we get moved
119 if (!m_selected) 127 if (!m_selected)
128 {
129 StopTimer();
120 m_serializedPosition = m_group.AbsolutePosition; 130 m_serializedPosition = m_group.AbsolutePosition;
131 }
121 } 132 }
122 m_selected = value; 133 m_selected = value;
123 } 134 }
124 } 135 }
125 136
126 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data) 137 private void StartTimer()
138 {
139 if (m_timer == null)
140 return;
141 m_timerStopped = false;
142 m_timer.Start();
143 }
144
145 private void StopTimer()
127 { 146 {
128 MemoryStream ms = new MemoryStream(data); 147 if (m_timer == null || m_timerStopped)
148 return;
149 m_timerStopped = true;
150 m_timer.Stop();
151 }
129 152
130 BinaryFormatter fmt = new BinaryFormatter(); 153 public static KeyframeMotion FromData(SceneObjectGroup grp, Byte[] data)
154 {
155 KeyframeMotion newMotion = null;
131 156
132 KeyframeMotion newMotion = (KeyframeMotion)fmt.Deserialize(ms); 157 try
158 {
159 MemoryStream ms = new MemoryStream(data);
160 BinaryFormatter fmt = new BinaryFormatter();
133 161
134/* 162 newMotion = (KeyframeMotion)fmt.Deserialize(ms);
135 * create timer in start()
136 * this was creating unneeded timers
137 163
138 // This will be started when position is updated 164 newMotion.m_group = grp;
139 165
140 newMotion.m_timer = new Timer(); 166 if (grp != null && grp.IsSelected)
141 newMotion.m_timer.Interval = (int)timerInterval; 167 newMotion.m_selected = true;
142 newMotion.m_timer.AutoReset = true;
143 newMotion.m_timer.Elapsed += newMotion.OnTimer;
144*/
145 newMotion.m_group = grp;
146 168
147 if (grp != null && grp.IsSelected) 169 newMotion.m_onTimerLock = new object();
148 newMotion.m_selected = true; 170 newMotion.m_timerStopped = false;
171 newMotion.m_inOnTimer = false;
172 newMotion.m_crossing = false;
173 newMotion.m_crossFailcntr = 0;
174 }
175 catch
176 {
177 newMotion = null;
178 }
149 179
150 newMotion.m_onTimerLock = new object();
151 newMotion.m_skipOnTimer = false;
152 newMotion.m_inOnTimer = false;
153 return newMotion; 180 return newMotion;
154 } 181 }
155 182
@@ -157,9 +184,9 @@ namespace OpenSim.Region.Framework.Scenes
157 { 184 {
158// lock (m_onTimerLock) 185// lock (m_onTimerLock)
159 { 186 {
160 m_skipOnTimer = true; 187 m_crossing = false;
161 if (m_timer != null) 188 m_crossFailcntr = 0;
162 m_timer.Stop(); 189 StopTimer();
163 190
164 m_group = grp; 191 m_group = grp;
165 Vector3 grppos = grp.AbsolutePosition; 192 Vector3 grppos = grp.AbsolutePosition;
@@ -172,14 +199,7 @@ namespace OpenSim.Region.Framework.Scenes
172 m_currentFrame.Position += offset; 199 m_currentFrame.Position += offset;
173 200
174 m_nextPosition += offset; 201 m_nextPosition += offset;
175/* 202
176 for (int i = 0; i < m_frames.Count; i++)
177 {
178 Keyframe k = m_frames[i];
179 k.Position += offset;
180 m_frames[i] = k;
181 }
182*/
183 for (int i = 0; i < m_frames.Count; i++) 203 for (int i = 0; i < m_frames.Count; i++)
184 { 204 {
185 Keyframe k = m_frames[i]; 205 Keyframe k = m_frames[i];
@@ -202,11 +222,8 @@ namespace OpenSim.Region.Framework.Scenes
202 m_group = grp; 222 m_group = grp;
203 m_basePosition = grp.AbsolutePosition; 223 m_basePosition = grp.AbsolutePosition;
204 m_baseRotation = grp.GroupRotation; 224 m_baseRotation = grp.GroupRotation;
205/* 225 m_crossing = false;
206 m_timer.Interval = (int)timerInterval; 226 m_crossFailcntr = 0;
207 m_timer.AutoReset = true;
208 m_timer.Elapsed += OnTimer;
209 */
210 } 227 }
211 228
212 public void SetKeyframes(Keyframe[] frames) 229 public void SetKeyframes(Keyframe[] frames)
@@ -216,21 +233,23 @@ namespace OpenSim.Region.Framework.Scenes
216 233
217 public void Delete() 234 public void Delete()
218 { 235 {
219 m_skipOnTimer = true; 236 m_running = false;
237 m_crossing = false;
238 m_crossFailcntr = 0;
239 StopTimer();
220 m_frames.Clear(); 240 m_frames.Clear();
221 m_keyframes = null; 241 m_keyframes = null;
222 m_running = false;
223 242
224 if (m_timer == null) 243 if (m_timer == null)
225 return; 244 return;
226
227 m_timer.Stop();
228 m_timer.Elapsed -= OnTimer; 245 m_timer.Elapsed -= OnTimer;
229 m_timer = null; 246 m_timer = null;
230 } 247 }
231 248
232 public void Start() 249 public void Start()
233 { 250 {
251 m_crossing = false;
252 m_crossFailcntr = 0;
234 if (m_keyframes.Length > 0) 253 if (m_keyframes.Length > 0)
235 { 254 {
236 if (m_timer == null) 255 if (m_timer == null)
@@ -241,19 +260,16 @@ namespace OpenSim.Region.Framework.Scenes
241 m_timer.Elapsed += OnTimer; 260 m_timer.Elapsed += OnTimer;
242 } 261 }
243 262
244 m_skipOnTimer = false;
245 m_inOnTimer = false; 263 m_inOnTimer = false;
246 264 StartTimer();
247 m_timer.Start();
248 m_running = true; 265 m_running = true;
249 } 266 }
250 else 267 else
251 { 268 {
252 m_running = false; 269 m_running = false;
253 m_skipOnTimer = true;
254 if (m_timer != null) 270 if (m_timer != null)
255 { 271 {
256 m_timer.Stop(); 272 StopTimer();
257 m_timer.Elapsed -= OnTimer; 273 m_timer.Elapsed -= OnTimer;
258 m_timer = null; 274 m_timer = null;
259 } 275 }
@@ -262,13 +278,11 @@ namespace OpenSim.Region.Framework.Scenes
262 278
263 public void Stop() 279 public void Stop()
264 { 280 {
265 m_skipOnTimer = true; 281 m_running = false;
266 282 m_crossing = false;
267 // Failed object creation 283 m_crossFailcntr = 0;
268 if (m_timer == null)
269 return;
270 284
271 m_timer.Stop(); 285 StopTimer();
272 m_timer.Elapsed -= OnTimer; 286 m_timer.Elapsed -= OnTimer;
273 m_timer = null; 287 m_timer = null;
274 288
@@ -280,19 +294,17 @@ namespace OpenSim.Region.Framework.Scenes
280 m_group.SendGroupRootTerseUpdate(); 294 m_group.SendGroupRootTerseUpdate();
281 295
282 m_frames.Clear(); 296 m_frames.Clear();
283 m_running = false;
284 } 297 }
285 298
286 public void Pause() 299 public void Pause()
287 { 300 {
288 m_skipOnTimer = true; 301 m_running = false;
302 m_crossFailcntr = 0;
303 StopTimer();
289 304
290 m_group.RootPart.Velocity = Vector3.Zero; 305 m_group.RootPart.Velocity = Vector3.Zero;
291 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero); 306 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
292 m_group.SendGroupRootTerseUpdate(); 307 m_group.SendGroupRootTerseUpdate();
293
294 m_timer.Stop();
295 m_running = false;
296 } 308 }
297 309
298 private void GetNextList() 310 private void GetNextList()
@@ -325,9 +337,16 @@ namespace OpenSim.Region.Framework.Scenes
325 Keyframe k = m_keyframes[i]; 337 Keyframe k = m_keyframes[i];
326 338
327 if (k.Position.HasValue) 339 if (k.Position.HasValue)
328 k.Position = (k.Position * direction) + pos; 340 {
341 k.Position = (k.Position * direction);
342// k.Velocity = (Vector3)k.Position / (k.TimeMS / 1000.0f);
343 k.Position += pos;
344 }
329 else 345 else
346 {
330 k.Position = pos; 347 k.Position = pos;
348// k.Velocity = Vector3.Zero;
349 }
331 350
332 k.StartRotation = rot; 351 k.StartRotation = rot;
333 if (k.Rotation.HasValue) 352 if (k.Rotation.HasValue)
@@ -341,6 +360,8 @@ namespace OpenSim.Region.Framework.Scenes
341 k.Rotation = rot; 360 k.Rotation = rot;
342 } 361 }
343 362
363/* ang vel not in use for now
364
344 float angle = 0; 365 float angle = 0;
345 366
346 float aa = k.StartRotation.X * k.StartRotation.X + k.StartRotation.Y * k.StartRotation.Y + k.StartRotation.Z * k.StartRotation.Z + k.StartRotation.W * k.StartRotation.W; 367 float aa = k.StartRotation.X * k.StartRotation.X + k.StartRotation.Y * k.StartRotation.Y + k.StartRotation.Z * k.StartRotation.Z + k.StartRotation.W * k.StartRotation.W;
@@ -370,6 +391,7 @@ namespace OpenSim.Region.Framework.Scenes
370 } 391 }
371 392
372 k.AngularVelocity = (new Vector3(0, 0, 1) * (Quaternion)k.Rotation) * (angle / (k.TimeMS / 1000)); 393 k.AngularVelocity = (new Vector3(0, 0, 1) * (Quaternion)k.Rotation) * (angle / (k.TimeMS / 1000));
394 */
373 k.TimeTotal = k.TimeMS; 395 k.TimeTotal = k.TimeMS;
374 396
375 m_frames.Add(k); 397 m_frames.Add(k);
@@ -387,20 +409,56 @@ namespace OpenSim.Region.Framework.Scenes
387 409
388 protected void OnTimer(object sender, ElapsedEventArgs e) 410 protected void OnTimer(object sender, ElapsedEventArgs e)
389 { 411 {
390 if (m_inOnTimer) 412 if (m_timerStopped) // trap events still in air even after a timer.stop
413 return;
414
415 if (m_inOnTimer) // don't let overruns to happen
391 { 416 {
392 m_log.Error("[KeyFrame]: timer overrun"); 417 m_log.Warn("[KeyFrame]: timer overrun");
393 return; 418 return;
394 } 419 }
395 420
421 if (m_group == null)
422 return;
423
396// lock (m_onTimerLock) 424// lock (m_onTimerLock)
397 { 425 {
398 if (m_skipOnTimer)
399 return;
400 426
401 m_inOnTimer = true; 427 m_inOnTimer = true;
428
429 bool update = false;
430
402 try 431 try
403 { 432 {
433 if (m_selected)
434 {
435 if (m_group.RootPart.Velocity != Vector3.Zero)
436 {
437 m_group.RootPart.Velocity = Vector3.Zero;
438 m_group.SendGroupRootTerseUpdate();
439 }
440 m_inOnTimer = false;
441 return;
442 }
443
444 if (m_crossing)
445 {
446 // if crossing and timer running then cross failed
447 // wait some time then
448 // retry to set the position that evtually caused the outbound
449 // if still outside region this will call startCrossing below
450 m_crossing = false;
451 m_group.AbsolutePosition = m_nextPosition;
452 if (!m_crossing)
453 {
454 StopTimer();
455 m_timer.Interval = timerInterval;
456 StartTimer();
457 }
458 m_inOnTimer = false;
459 return;
460 }
461
404 if (m_frames.Count == 0) 462 if (m_frames.Count == 0)
405 { 463 {
406 GetNextList(); 464 GetNextList();
@@ -413,41 +471,41 @@ namespace OpenSim.Region.Framework.Scenes
413 } 471 }
414 472
415 m_currentFrame = m_frames[0]; 473 m_currentFrame = m_frames[0];
416 } 474 m_currentFrame.TimeMS += (int)timerInterval;
417 475
418 if (m_selected) 476 //force a update on a keyframe transition
419 { 477 update = true;
420 if (m_group.RootPart.Velocity != Vector3.Zero)
421 {
422 m_group.RootPart.Velocity = Vector3.Zero;
423 m_group.SendGroupRootTerseUpdate();
424 }
425 m_inOnTimer = false;
426 return;
427 } 478 }
428 479
480 m_currentFrame.TimeMS -= (int)timerInterval;
481
429 // Do the frame processing 482 // Do the frame processing
430 double steps = (double)m_currentFrame.TimeMS / timerInterval; 483 double steps = (double)m_currentFrame.TimeMS / timerInterval;
431 float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
432 484
433 if (steps <= 1.0) 485 if (steps <= 0.0)
434 { 486 {
435 m_currentFrame.TimeMS = 0; 487 m_group.RootPart.Velocity = Vector3.Zero;
488 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
436 489
437 // m_group.AbsolutePosition = (Vector3)m_currentFrame.Position;
438 m_nextPosition = (Vector3)m_currentFrame.Position; 490 m_nextPosition = (Vector3)m_currentFrame.Position;
439 m_group.AbsolutePosition = m_nextPosition; 491 m_group.AbsolutePosition = m_nextPosition;
440 492
441 m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation); 493 m_group.UpdateGroupRotationR((Quaternion)m_currentFrame.Rotation);
494
495 m_frames.RemoveAt(0);
496 if (m_frames.Count > 0)
497 m_currentFrame = m_frames[0];
498
499 update = true;
442 } 500 }
443 else 501 else
444 { 502 {
503 float complete = ((float)m_currentFrame.TimeTotal - (float)m_currentFrame.TimeMS) / (float)m_currentFrame.TimeTotal;
504
445 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition; 505 Vector3 v = (Vector3)m_currentFrame.Position - m_group.AbsolutePosition;
446 Vector3 motionThisFrame = v / (float)steps; 506 Vector3 motionThisFrame = v / (float)steps;
447 v = v * 1000 / m_currentFrame.TimeMS; 507 v = v * 1000 / m_currentFrame.TimeMS;
448 508
449 bool update = false;
450
451 if (Vector3.Mag(motionThisFrame) >= 0.05f) 509 if (Vector3.Mag(motionThisFrame) >= 0.05f)
452 { 510 {
453 // m_group.AbsolutePosition += motionThisFrame; 511 // m_group.AbsolutePosition += motionThisFrame;
@@ -463,8 +521,8 @@ namespace OpenSim.Region.Framework.Scenes
463 Quaternion current = m_group.GroupRotation; 521 Quaternion current = m_group.GroupRotation;
464 522
465 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete); 523 Quaternion step = Quaternion.Slerp(m_currentFrame.StartRotation, (Quaternion)m_currentFrame.Rotation, complete);
466 524/* use simpler change detection
467 float angle = 0; 525 * float angle = 0;
468 526
469 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W; 527 float aa = current.X * current.X + current.Y * current.Y + current.Z * current.Z + current.W * current.W;
470 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W; 528 float bb = step.X * step.X + step.Y * step.Y + step.Z * step.Z + step.W * step.W;
@@ -493,6 +551,12 @@ namespace OpenSim.Region.Framework.Scenes
493 } 551 }
494 552
495 if (angle > 0.01f) 553 if (angle > 0.01f)
554 */
555 if(Math.Abs(step.X -current.X) > 0.001f
556 || Math.Abs(step.Y -current.Y) > 0.001f
557 || Math.Abs(step.Z -current.Z) > 0.001f)
558 // assuming w is a dependente var
559
496 { 560 {
497 m_group.UpdateGroupRotationR(step); 561 m_group.UpdateGroupRotationR(step);
498 //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2); 562 //m_group.RootPart.UpdateAngularVelocity(m_currentFrame.AngularVelocity / 2);
@@ -500,25 +564,22 @@ namespace OpenSim.Region.Framework.Scenes
500 } 564 }
501 } 565 }
502 566
503 if (update)
504 m_group.SendGroupRootTerseUpdate();
505 } 567 }
506 568
507 m_currentFrame.TimeMS -= (int)timerInterval; 569 if (update)
508
509 if (m_currentFrame.TimeMS <= 0)
510 {
511 m_group.RootPart.Velocity = Vector3.Zero;
512 m_group.RootPart.UpdateAngularVelocity(Vector3.Zero);
513 m_group.SendGroupRootTerseUpdate(); 570 m_group.SendGroupRootTerseUpdate();
514 571
515 m_frames.RemoveAt(0);
516 if (m_frames.Count > 0)
517 m_currentFrame = m_frames[0];
518 }
519 } 572 }
573 catch ( Exception ex)
574 {
575 // still happening sometimes
576 // lets try to see what
577 m_log.Warn("[KeyFrame]: timer overrun" + ex.Message);
578 }
579
520 finally 580 finally
521 { 581 {
582 // make sure we do not let this frozen
522 m_inOnTimer = false; 583 m_inOnTimer = false;
523 } 584 }
524 } 585 }
@@ -528,10 +589,7 @@ namespace OpenSim.Region.Framework.Scenes
528 { 589 {
529 MemoryStream ms = new MemoryStream(); 590 MemoryStream ms = new MemoryStream();
530 if (StopMoveTimer && m_timer != null) 591 if (StopMoveTimer && m_timer != null)
531 { 592 StopTimer();
532 m_skipOnTimer = true;
533 m_timer.Stop();
534 }
535 593
536// lock (m_onTimerLock) 594// lock (m_onTimerLock)
537 { 595 {
@@ -548,10 +606,9 @@ namespace OpenSim.Region.Framework.Scenes
548 606
549 public void StartCrossingCheck() 607 public void StartCrossingCheck()
550 { 608 {
551 m_skipOnTimer = true; 609 StopTimer();
552 if (m_timer != null) 610 m_crossing = true;
553 m_timer.Stop(); 611// to remove / retune to smoth crossings
554
555 if (m_group.RootPart.Velocity != Vector3.Zero) 612 if (m_group.RootPart.Velocity != Vector3.Zero)
556 { 613 {
557 m_group.RootPart.Velocity = Vector3.Zero; 614 m_group.RootPart.Velocity = Vector3.Zero;
@@ -561,24 +618,17 @@ namespace OpenSim.Region.Framework.Scenes
561 618
562 public void CrossingFailure() 619 public void CrossingFailure()
563 { 620 {
564 // The serialization has stopped the timer, so let's wait a moment 621 if (m_group != null)
565 // then retry the crossing. We'll get back here if it fails.
566 // if it is a open border there is no serialization
567 // so make sure timer is actually stopped
568
569 m_group.RootPart.Velocity = Vector3.Zero;
570 m_group.SendGroupRootTerseUpdate();
571
572 Util.FireAndForget(delegate (object x)
573 { 622 {
574 Thread.Sleep(60000); 623 m_group.RootPart.Velocity = Vector3.Zero;
575 if (m_running) 624 m_group.SendGroupRootTerseUpdate();
625
626 if (m_running && m_timer != null)
576 { 627 {
577 m_skipOnTimer = false; 628 m_timer.Interval = 60000;
578 m_timer.Start(); 629 StartTimer();
579 m_group.AbsolutePosition = m_nextPosition;
580 } 630 }
581 }); 631 }
582 } 632 }
583 } 633 }
584} 634}