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