aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
diff options
context:
space:
mode:
authorDiva Canto2015-09-01 09:20:20 -0700
committerDiva Canto2015-09-01 09:20:20 -0700
commit0235e58fff47d3794777392a987feb4de8a5f99a (patch)
treee17292d912f98f1095601b6a858f409d6f5f997d /OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
parentDeleted physics plugin classes. (diff)
downloadopensim-SC-0235e58fff47d3794777392a987feb4de8a5f99a.zip
opensim-SC-0235e58fff47d3794777392a987feb4de8a5f99a.tar.gz
opensim-SC-0235e58fff47d3794777392a987feb4de8a5f99a.tar.bz2
opensim-SC-0235e58fff47d3794777392a987feb4de8a5f99a.tar.xz
Moved ExtendedPhysics from OptionalModules to Bullet project, because it's very much an optional Bullet feature. This way, Bullet doesn't need to depend on the OptionalModules dll. No changes in configs or behavior.
Diffstat (limited to 'OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs')
-rwxr-xr-xOpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs622
1 files changed, 622 insertions, 0 deletions
diff --git a/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
new file mode 100755
index 0000000..2ba3c5a
--- /dev/null
+++ b/OpenSim/Region/PhysicsModules/BulletS/ExtendedPhysics.cs
@@ -0,0 +1,622 @@
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 copyrightD
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 */
27using System;
28using System.Collections.Generic;
29using System.Linq;
30using System.Reflection;
31using System.Text;
32using System.Threading;
33
34using OpenSim.Framework;
35using OpenSim.Region.Framework;
36using OpenSim.Region.Framework.Interfaces;
37using OpenSim.Region.Framework.Scenes;
38using OpenSim.Region.PhysicsModules.SharedBase;
39
40using Mono.Addins;
41using Nini.Config;
42using log4net;
43using OpenMetaverse;
44
45namespace OpenSim.Region.PhysicsModule.BulletS
46{
47 [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")]
48 public class ExtendedPhysics : INonSharedRegionModule
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51 private static string LogHeader = "[EXTENDED PHYSICS]";
52
53 // =============================================================
54 // Since BulletSim is a plugin, this these values aren't defined easily in one place.
55 // This table must correspond to an identical table in BSScene.
56
57 // Per scene functions. See BSScene.
58
59 // Per avatar functions. See BSCharacter.
60
61 // Per prim functions. See BSPrim.
62 public const string PhysFunctGetLinksetType = "BulletSim.GetLinksetType";
63 public const string PhysFunctSetLinksetType = "BulletSim.SetLinksetType";
64 public const string PhysFunctChangeLinkFixed = "BulletSim.ChangeLinkFixed";
65 public const string PhysFunctChangeLinkType = "BulletSim.ChangeLinkType";
66 public const string PhysFunctGetLinkType = "BulletSim.GetLinkType";
67 public const string PhysFunctChangeLinkParams = "BulletSim.ChangeLinkParams";
68 public const string PhysFunctAxisLockLimits = "BulletSim.AxisLockLimits";
69
70 // =============================================================
71
72 private IConfig Configuration { get; set; }
73 private bool Enabled { get; set; }
74 private Scene BaseScene { get; set; }
75 private IScriptModuleComms Comms { get; set; }
76
77 #region INonSharedRegionModule
78
79 public string Name { get { return this.GetType().Name; } }
80
81 public void Initialise(IConfigSource config)
82 {
83 BaseScene = null;
84 Enabled = false;
85 Configuration = null;
86 Comms = null;
87
88 try
89 {
90 if ((Configuration = config.Configs["ExtendedPhysics"]) != null)
91 {
92 Enabled = Configuration.GetBoolean("Enabled", Enabled);
93 }
94 }
95 catch (Exception e)
96 {
97 m_log.ErrorFormat("{0} Initialization error: {0}", LogHeader, e);
98 }
99
100 m_log.InfoFormat("{0} module {1} enabled", LogHeader, (Enabled ? "is" : "is not"));
101 }
102
103 public void Close()
104 {
105 if (BaseScene != null)
106 {
107 BaseScene.EventManager.OnObjectAddedToScene -= EventManager_OnObjectAddedToScene;
108 BaseScene.EventManager.OnSceneObjectPartUpdated -= EventManager_OnSceneObjectPartUpdated;
109 BaseScene = null;
110 }
111 }
112
113 public void AddRegion(Scene scene)
114 {
115 }
116
117 public void RemoveRegion(Scene scene)
118 {
119 if (BaseScene != null && BaseScene == scene)
120 {
121 Close();
122 }
123 }
124
125 public void RegionLoaded(Scene scene)
126 {
127 if (!Enabled) return;
128
129 BaseScene = scene;
130
131 Comms = BaseScene.RequestModuleInterface<IScriptModuleComms>();
132 if (Comms == null)
133 {
134 m_log.WarnFormat("{0} ScriptModuleComms interface not defined", LogHeader);
135 Enabled = false;
136
137 return;
138 }
139
140 // Register as LSL functions all the [ScriptInvocation] marked methods.
141 Comms.RegisterScriptInvocations(this);
142 Comms.RegisterConstants(this);
143
144 // When an object is modified, we might need to update its extended physics parameters
145 BaseScene.EventManager.OnObjectAddedToScene += EventManager_OnObjectAddedToScene;
146 BaseScene.EventManager.OnSceneObjectPartUpdated += EventManager_OnSceneObjectPartUpdated;
147
148 }
149
150 public Type ReplaceableInterface { get { return null; } }
151
152 #endregion // INonSharedRegionModule
153
154 private void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
155 {
156 }
157
158 // Event generated when some property of a prim changes.
159 private void EventManager_OnSceneObjectPartUpdated(SceneObjectPart sop, bool isFullUpdate)
160 {
161 }
162
163 [ScriptConstant]
164 public const int PHYS_CENTER_OF_MASS = 1 << 0;
165
166 [ScriptInvocation]
167 public string physGetEngineType(UUID hostID, UUID scriptID)
168 {
169 string ret = string.Empty;
170
171 if (BaseScene.PhysicsScene != null)
172 {
173 ret = BaseScene.PhysicsScene.EngineType;
174 }
175
176 return ret;
177 }
178
179 // Code for specifying params.
180 // The choice if 14700 is arbitrary and only serves to catch parameter code misuse.
181 [ScriptConstant]
182 public const int PHYS_AXIS_LOCK_LINEAR = 14700;
183 [ScriptConstant]
184 public const int PHYS_AXIS_LOCK_LINEAR_X = 14701;
185 [ScriptConstant]
186 public const int PHYS_AXIS_LIMIT_LINEAR_X = 14702;
187 [ScriptConstant]
188 public const int PHYS_AXIS_LOCK_LINEAR_Y = 14703;
189 [ScriptConstant]
190 public const int PHYS_AXIS_LIMIT_LINEAR_Y = 14704;
191 [ScriptConstant]
192 public const int PHYS_AXIS_LOCK_LINEAR_Z = 14705;
193 [ScriptConstant]
194 public const int PHYS_AXIS_LIMIT_LINEAR_Z = 14706;
195 [ScriptConstant]
196 public const int PHYS_AXIS_LOCK_ANGULAR = 14707;
197 [ScriptConstant]
198 public const int PHYS_AXIS_LOCK_ANGULAR_X = 14708;
199 [ScriptConstant]
200 public const int PHYS_AXIS_LIMIT_ANGULAR_X = 14709;
201 [ScriptConstant]
202 public const int PHYS_AXIS_LOCK_ANGULAR_Y = 14710;
203 [ScriptConstant]
204 public const int PHYS_AXIS_LIMIT_ANGULAR_Y = 14711;
205 [ScriptConstant]
206 public const int PHYS_AXIS_LOCK_ANGULAR_Z = 14712;
207 [ScriptConstant]
208 public const int PHYS_AXIS_LIMIT_ANGULAR_Z = 14713;
209 [ScriptConstant]
210 public const int PHYS_AXIS_UNLOCK_LINEAR = 14714;
211 [ScriptConstant]
212 public const int PHYS_AXIS_UNLOCK_LINEAR_X = 14715;
213 [ScriptConstant]
214 public const int PHYS_AXIS_UNLOCK_LINEAR_Y = 14716;
215 [ScriptConstant]
216 public const int PHYS_AXIS_UNLOCK_LINEAR_Z = 14717;
217 [ScriptConstant]
218 public const int PHYS_AXIS_UNLOCK_ANGULAR = 14718;
219 [ScriptConstant]
220 public const int PHYS_AXIS_UNLOCK_ANGULAR_X = 14719;
221 [ScriptConstant]
222 public const int PHYS_AXIS_UNLOCK_ANGULAR_Y = 14720;
223 [ScriptConstant]
224 public const int PHYS_AXIS_UNLOCK_ANGULAR_Z = 14721;
225 [ScriptConstant]
226 public const int PHYS_AXIS_UNLOCK = 14722;
227 // physAxisLockLimits()
228 [ScriptInvocation]
229 public int physAxisLock(UUID hostID, UUID scriptID, object[] parms)
230 {
231 int ret = -1;
232 if (!Enabled) return ret;
233
234 PhysicsActor rootPhysActor;
235 if (GetRootPhysActor(hostID, out rootPhysActor))
236 {
237 object[] parms2 = AddToBeginningOfArray(rootPhysActor, null, parms);
238 ret = MakeIntError(rootPhysActor.Extension(PhysFunctAxisLockLimits, parms2));
239 }
240
241 return ret;
242 }
243
244 [ScriptConstant]
245 public const int PHYS_LINKSET_TYPE_CONSTRAINT = 0;
246 [ScriptConstant]
247 public const int PHYS_LINKSET_TYPE_COMPOUND = 1;
248 [ScriptConstant]
249 public const int PHYS_LINKSET_TYPE_MANUAL = 2;
250
251 [ScriptInvocation]
252 public int physSetLinksetType(UUID hostID, UUID scriptID, int linksetType)
253 {
254 int ret = -1;
255 if (!Enabled) return ret;
256
257 // The part that is requesting the change.
258 SceneObjectPart requestingPart = BaseScene.GetSceneObjectPart(hostID);
259
260 if (requestingPart != null)
261 {
262 // The change is always made to the root of a linkset.
263 SceneObjectGroup containingGroup = requestingPart.ParentGroup;
264 SceneObjectPart rootPart = containingGroup.RootPart;
265
266 if (rootPart != null)
267 {
268 PhysicsActor rootPhysActor = rootPart.PhysActor;
269 if (rootPhysActor != null)
270 {
271 if (rootPhysActor.IsPhysical)
272 {
273 // Change a physical linkset by making non-physical, waiting for one heartbeat so all
274 // the prim and linkset state is updated, changing the type and making the
275 // linkset physical again.
276 containingGroup.ScriptSetPhysicsStatus(false);
277 Thread.Sleep(150); // longer than one heartbeat tick
278
279 // A kludge for the moment.
280 // Since compound linksets move the children but don't generate position updates to the
281 // simulator, it is possible for compound linkset children to have out-of-sync simulator
282 // and physical positions. The following causes the simulator to push the real child positions
283 // down into the physics engine to get everything synced.
284 containingGroup.UpdateGroupPosition(containingGroup.AbsolutePosition);
285 containingGroup.UpdateGroupRotationR(containingGroup.GroupRotation);
286
287 object[] parms2 = { rootPhysActor, null, linksetType };
288 ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
289 Thread.Sleep(150); // longer than one heartbeat tick
290
291 containingGroup.ScriptSetPhysicsStatus(true);
292 }
293 else
294 {
295 // Non-physical linksets don't have a physical instantiation so there is no state to
296 // worry about being updated.
297 object[] parms2 = { rootPhysActor, null, linksetType };
298 ret = MakeIntError(rootPhysActor.Extension(PhysFunctSetLinksetType, parms2));
299 }
300 }
301 else
302 {
303 m_log.WarnFormat("{0} physSetLinksetType: root part does not have a physics actor. rootName={1}, hostID={2}",
304 LogHeader, rootPart.Name, hostID);
305 }
306 }
307 else
308 {
309 m_log.WarnFormat("{0} physSetLinksetType: root part does not exist. RequestingPartName={1}, hostID={2}",
310 LogHeader, requestingPart.Name, hostID);
311 }
312 }
313 else
314 {
315 m_log.WarnFormat("{0} physSetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
316 }
317 return ret;
318 }
319
320 [ScriptInvocation]
321 public int physGetLinksetType(UUID hostID, UUID scriptID)
322 {
323 int ret = -1;
324 if (!Enabled) return ret;
325
326 PhysicsActor rootPhysActor;
327 if (GetRootPhysActor(hostID, out rootPhysActor))
328 {
329 object[] parms2 = { rootPhysActor, null };
330 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinksetType, parms2));
331 }
332 else
333 {
334 m_log.WarnFormat("{0} physGetLinsetType: cannot find script object in scene. hostID={1}", LogHeader, hostID);
335 }
336 return ret;
337 }
338
339 [ScriptConstant]
340 public const int PHYS_LINK_TYPE_FIXED = 1234;
341 [ScriptConstant]
342 public const int PHYS_LINK_TYPE_HINGE = 4;
343 [ScriptConstant]
344 public const int PHYS_LINK_TYPE_SPRING = 9;
345 [ScriptConstant]
346 public const int PHYS_LINK_TYPE_6DOF = 6;
347 [ScriptConstant]
348 public const int PHYS_LINK_TYPE_SLIDER = 7;
349
350 // physChangeLinkType(integer linkNum, integer typeCode)
351 [ScriptInvocation]
352 public int physChangeLinkType(UUID hostID, UUID scriptID, int linkNum, int typeCode)
353 {
354 int ret = -1;
355 if (!Enabled) return ret;
356
357 PhysicsActor rootPhysActor;
358 PhysicsActor childPhysActor;
359
360 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
361 {
362 object[] parms2 = { rootPhysActor, childPhysActor, typeCode };
363 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
364 }
365
366 return ret;
367 }
368
369 // physGetLinkType(integer linkNum)
370 [ScriptInvocation]
371 public int physGetLinkType(UUID hostID, UUID scriptID, int linkNum)
372 {
373 int ret = -1;
374 if (!Enabled) return ret;
375
376 PhysicsActor rootPhysActor;
377 PhysicsActor childPhysActor;
378
379 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
380 {
381 object[] parms2 = { rootPhysActor, childPhysActor };
382 ret = MakeIntError(rootPhysActor.Extension(PhysFunctGetLinkType, parms2));
383 }
384
385 return ret;
386 }
387
388 // physChangeLinkFixed(integer linkNum)
389 // Change the link between the root and the linkNum into a fixed, static physical connection.
390 [ScriptInvocation]
391 public int physChangeLinkFixed(UUID hostID, UUID scriptID, int linkNum)
392 {
393 int ret = -1;
394 if (!Enabled) return ret;
395
396 PhysicsActor rootPhysActor;
397 PhysicsActor childPhysActor;
398
399 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
400 {
401 object[] parms2 = { rootPhysActor, childPhysActor , PHYS_LINK_TYPE_FIXED };
402 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkType, parms2));
403 }
404
405 return ret;
406 }
407
408 // Code for specifying params.
409 // The choice if 14400 is arbitrary and only serves to catch parameter code misuse.
410 public const int PHYS_PARAM_MIN = 14401;
411
412 [ScriptConstant]
413 public const int PHYS_PARAM_FRAMEINA_LOC = 14401;
414 [ScriptConstant]
415 public const int PHYS_PARAM_FRAMEINA_ROT = 14402;
416 [ScriptConstant]
417 public const int PHYS_PARAM_FRAMEINB_LOC = 14403;
418 [ScriptConstant]
419 public const int PHYS_PARAM_FRAMEINB_ROT = 14404;
420 [ScriptConstant]
421 public const int PHYS_PARAM_LINEAR_LIMIT_LOW = 14405;
422 [ScriptConstant]
423 public const int PHYS_PARAM_LINEAR_LIMIT_HIGH = 14406;
424 [ScriptConstant]
425 public const int PHYS_PARAM_ANGULAR_LIMIT_LOW = 14407;
426 [ScriptConstant]
427 public const int PHYS_PARAM_ANGULAR_LIMIT_HIGH = 14408;
428 [ScriptConstant]
429 public const int PHYS_PARAM_USE_FRAME_OFFSET = 14409;
430 [ScriptConstant]
431 public const int PHYS_PARAM_ENABLE_TRANSMOTOR = 14410;
432 [ScriptConstant]
433 public const int PHYS_PARAM_TRANSMOTOR_MAXVEL = 14411;
434 [ScriptConstant]
435 public const int PHYS_PARAM_TRANSMOTOR_MAXFORCE = 14412;
436 [ScriptConstant]
437 public const int PHYS_PARAM_CFM = 14413;
438 [ScriptConstant]
439 public const int PHYS_PARAM_ERP = 14414;
440 [ScriptConstant]
441 public const int PHYS_PARAM_SOLVER_ITERATIONS = 14415;
442 [ScriptConstant]
443 public const int PHYS_PARAM_SPRING_AXIS_ENABLE = 14416;
444 [ScriptConstant]
445 public const int PHYS_PARAM_SPRING_DAMPING = 14417;
446 [ScriptConstant]
447 public const int PHYS_PARAM_SPRING_STIFFNESS = 14418;
448 [ScriptConstant]
449 public const int PHYS_PARAM_LINK_TYPE = 14419;
450 [ScriptConstant]
451 public const int PHYS_PARAM_USE_LINEAR_FRAMEA = 14420;
452 [ScriptConstant]
453 public const int PHYS_PARAM_SPRING_EQUILIBRIUM_POINT = 14421;
454
455 public const int PHYS_PARAM_MAX = 14421;
456
457 // Used when specifying a parameter that has settings for the three linear and three angular axis
458 [ScriptConstant]
459 public const int PHYS_AXIS_ALL = -1;
460 [ScriptConstant]
461 public const int PHYS_AXIS_LINEAR_ALL = -2;
462 [ScriptConstant]
463 public const int PHYS_AXIS_ANGULAR_ALL = -3;
464 [ScriptConstant]
465 public const int PHYS_AXIS_LINEAR_X = 0;
466 [ScriptConstant]
467 public const int PHYS_AXIS_LINEAR_Y = 1;
468 [ScriptConstant]
469 public const int PHYS_AXIS_LINEAR_Z = 2;
470 [ScriptConstant]
471 public const int PHYS_AXIS_ANGULAR_X = 3;
472 [ScriptConstant]
473 public const int PHYS_AXIS_ANGULAR_Y = 4;
474 [ScriptConstant]
475 public const int PHYS_AXIS_ANGULAR_Z = 5;
476
477 // physChangeLinkParams(integer linkNum, [ PHYS_PARAM_*, value, PHYS_PARAM_*, value, ...])
478 [ScriptInvocation]
479 public int physChangeLinkParams(UUID hostID, UUID scriptID, int linkNum, object[] parms)
480 {
481 int ret = -1;
482 if (!Enabled) return ret;
483
484 PhysicsActor rootPhysActor;
485 PhysicsActor childPhysActor;
486
487 if (GetRootAndChildPhysActors(hostID, linkNum, out rootPhysActor, out childPhysActor))
488 {
489 object[] parms2 = AddToBeginningOfArray(rootPhysActor, childPhysActor, parms);
490 ret = MakeIntError(rootPhysActor.Extension(PhysFunctChangeLinkParams, parms2));
491 }
492
493 return ret;
494 }
495
496 private bool GetRootPhysActor(UUID hostID, out PhysicsActor rootPhysActor)
497 {
498 SceneObjectGroup containingGroup;
499 SceneObjectPart rootPart;
500 return GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor);
501 }
502
503 private bool GetRootPhysActor(UUID hostID, out SceneObjectGroup containingGroup, out SceneObjectPart rootPart, out PhysicsActor rootPhysActor)
504 {
505 bool ret = false;
506 rootPhysActor = null;
507 containingGroup = null;
508 rootPart = null;
509
510 SceneObjectPart requestingPart;
511
512 requestingPart = BaseScene.GetSceneObjectPart(hostID);
513 if (requestingPart != null)
514 {
515 // The type is is always on the root of a linkset.
516 containingGroup = requestingPart.ParentGroup;
517 if (containingGroup != null && !containingGroup.IsDeleted)
518 {
519 rootPart = containingGroup.RootPart;
520 if (rootPart != null)
521 {
522 rootPhysActor = rootPart.PhysActor;
523 if (rootPhysActor != null)
524 {
525 ret = true;
526 }
527 else
528 {
529 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
530 LogHeader, rootPart.Name, hostID);
531 }
532 }
533 else
534 {
535 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not exist. RequestingPartName={1}, hostID={2}",
536 LogHeader, requestingPart.Name, hostID);
537 }
538 }
539 else
540 {
541 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Containing group missing or deleted. hostID={1}", LogHeader, hostID);
542 }
543 }
544 else
545 {
546 m_log.WarnFormat("{0} GetRootAndChildPhysActors: cannot find script object in scene. hostID={1}", LogHeader, hostID);
547 }
548
549 return ret;
550 }
551
552 // Find the root and child PhysActors based on the linkNum.
553 // Return 'true' if both are found and returned.
554 private bool GetRootAndChildPhysActors(UUID hostID, int linkNum, out PhysicsActor rootPhysActor, out PhysicsActor childPhysActor)
555 {
556 bool ret = false;
557 rootPhysActor = null;
558 childPhysActor = null;
559
560 SceneObjectGroup containingGroup;
561 SceneObjectPart rootPart;
562
563 if (GetRootPhysActor(hostID, out containingGroup, out rootPart, out rootPhysActor))
564 {
565 SceneObjectPart linkPart = containingGroup.GetLinkNumPart(linkNum);
566 if (linkPart != null)
567 {
568 childPhysActor = linkPart.PhysActor;
569 if (childPhysActor != null)
570 {
571 ret = true;
572 }
573 else
574 {
575 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Link part has no physical actor. rootName={1}, hostID={2}, linknum={3}",
576 LogHeader, rootPart.Name, hostID, linkNum);
577 }
578 }
579 else
580 {
581 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Could not find linknum part. rootName={1}, hostID={2}, linknum={3}",
582 LogHeader, rootPart.Name, hostID, linkNum);
583 }
584 }
585 else
586 {
587 m_log.WarnFormat("{0} GetRootAndChildPhysActors: Root part does not have a physics actor. rootName={1}, hostID={2}",
588 LogHeader, rootPart.Name, hostID);
589 }
590
591 return ret;
592 }
593
594 // Return an array of objects with the passed object as the first object of a new array
595 private object[] AddToBeginningOfArray(object firstOne, object secondOne, object[] prevArray)
596 {
597 object[] newArray = new object[2 + prevArray.Length];
598 newArray[0] = firstOne;
599 newArray[1] = secondOne;
600 prevArray.CopyTo(newArray, 2);
601 return newArray;
602 }
603
604 // Extension() returns an object. Convert that object into the integer error we expect to return.
605 private int MakeIntError(object extensionRet)
606 {
607 int ret = -1;
608 if (extensionRet != null)
609 {
610 try
611 {
612 ret = (int)extensionRet;
613 }
614 catch
615 {
616 ret = -1;
617 }
618 }
619 return ret;
620 }
621 }
622}