OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
BSPrimDisplaced.cs
Go to the documentation of this file.
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 
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Runtime.InteropServices;
32 using OpenMetaverse;
33 using OpenSim.Framework;
34 using OpenSim.Region.PhysicsModules.SharedBase;
35 
36 using OMV = OpenMetaverse;
37 
38 namespace OpenSim.Region.PhysicsModule.BulletS
39 {
40 public class BSPrimDisplaced : BSPrim
41 {
42  // The purpose of this subclass is to do any mapping between what the simulator thinks
43  // the prim position and orientation is and what the physical position/orientation.
44  // This difference happens because Bullet assumes the center-of-mass is the <0,0,0>
45  // of the prim/linkset. The simulator, on the other hand, tracks the location of
46  // the prim/linkset by the location of the root prim. So, if center-of-mass is anywhere
47  // but the origin of the root prim, the physical origin is displaced from the simulator origin.
48  //
49  // This routine works by capturing ForcePosition and
50  // adjusting the simulator values (being set) into the physical values.
51  // The conversion is also done in the opposite direction (physical origin -> simulator origin).
52  //
53  // The updateParameter call is also captured and the values from the physics engine
54  // are converted into simulator origin values before being passed to the base
55  // class.
56 
57  // PositionDisplacement is the vehicle relative distance from the root prim position to the center-of-mass.
58  public virtual OMV.Vector3 PositionDisplacement { get; set; }
59 
60  public BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
61  OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
62  : base(localID, primName, parent_scene, pos, size, rotation, pbs, pisPhysical)
63  {
64  ClearDisplacement();
65  }
66 
67  // Clears any center-of-mass displacement introduced by linksets, etc.
68  // Does not clear the displacement set by the user.
69  public void ClearDisplacement()
70  {
71  if (UserSetCenterOfMassDisplacement.HasValue)
72  PositionDisplacement = (OMV.Vector3)UserSetCenterOfMassDisplacement;
73  else
74  PositionDisplacement = OMV.Vector3.Zero;
75  }
76 
77  // Set this sets and computes the displacement from the passed prim to the center-of-mass.
78  // A user set value for center-of-mass overrides whatever might be passed in here.
79  // The displacement is in local coordinates (relative to root prim in linkset oriented coordinates).
80  // Returns the relative offset from the root position to the center-of-mass.
81  // Called at taint time.
82  public virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
83  {
84  PhysScene.AssertInTaintTime("BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement");
85  Vector3 comDisp;
86  if (UserSetCenterOfMassDisplacement.HasValue)
87  comDisp = (OMV.Vector3)UserSetCenterOfMassDisplacement;
88  else
89  comDisp = centerOfMassDisplacement;
90 
91  // Eliminate any jitter caused be very slight differences in masses and positions
92  if (comDisp.ApproxEquals(Vector3.Zero, 0.01f) )
93  comDisp = Vector3.Zero;
94 
95  DetailLog("{0},BSPrimDisplaced.SetEffectiveCenterOfMassDisplacement,userSet={1},comDisp={2}",
96  LocalID, UserSetCenterOfMassDisplacement.HasValue, comDisp);
97  if ( !comDisp.ApproxEquals(PositionDisplacement, 0.01f) )
98  {
99  // Displacement setting is changing.
100  // The relationship between the physical object and simulated object must be aligned.
101  PositionDisplacement = comDisp;
102  this.ForcePosition = RawPosition;
103  }
104 
105  return PositionDisplacement;
106  }
107 
108  // 'ForcePosition' is the one way to set the physical position of the body in the physics engine.
109  // Displace the simulator idea of position (center of root prim) to the physical position.
110  public override Vector3 ForcePosition
111  {
112  get {
113  OMV.Vector3 physPosition = PhysScene.PE.GetPosition(PhysBody);
114  if (PositionDisplacement != OMV.Vector3.Zero)
115  {
116  // If there is some displacement, return the physical position (center-of-mass)
117  // location minus the displacement to give the center of the root prim.
118  OMV.Vector3 displacement = PositionDisplacement * ForceOrientation;
119  DetailLog("{0},BSPrimDisplaced.ForcePosition,get,physPos={1},disp={2},simPos={3}",
120  LocalID, physPosition, displacement, physPosition - displacement);
121  physPosition -= displacement;
122  }
123  RawPosition = physPosition;
124  return physPosition;
125  }
126  set
127  {
128  if (PositionDisplacement != OMV.Vector3.Zero)
129  {
130  // This value is the simulator's idea of where the prim is: the center of the root prim
131  RawPosition = value;
132 
133  // Move the passed root prim postion to the center-of-mass position and set in the physics engine.
134  OMV.Vector3 displacement = PositionDisplacement * RawOrientation;
135  OMV.Vector3 displacedPos = RawPosition + displacement;
136  DetailLog("{0},BSPrimDisplaced.ForcePosition,set,simPos={1},disp={2},physPos={3}",
137  LocalID, RawPosition, displacement, displacedPos);
138  if (PhysBody.HasPhysicalBody)
139  {
140  PhysScene.PE.SetTranslation(PhysBody, displacedPos, RawOrientation);
141  ActivateIfPhysical(false);
142  }
143  }
144  else
145  {
146  base.ForcePosition = value;
147  }
148  }
149  }
150 
151  // These are also overridden by BSPrimLinkable if the prim can be part of a linkset
152  public override OMV.Vector3 CenterOfMass
153  {
154  get { return RawPosition; }
155  }
156 
157  public override OMV.Vector3 GeometricCenter
158  {
159  get { return RawPosition; }
160  }
161 
162  public override void UpdateProperties(EntityProperties entprop)
163  {
164  // Undo any center-of-mass displacement that might have been done.
165  if (PositionDisplacement != OMV.Vector3.Zero)
166  {
167  // The origional shape was offset from 'zero' by PositionDisplacement.
168  // These physical location must be back converted to be centered around the displaced
169  // root shape.
170 
171  // Move the returned center-of-mass location to the root prim location.
172  OMV.Vector3 displacement = PositionDisplacement * entprop.Rotation;
173  OMV.Vector3 displacedPos = entprop.Position - displacement;
174  DetailLog("{0},BSPrimDisplaced.UpdateProperties,physPos={1},disp={2},simPos={3}",
175  LocalID, entprop.Position, displacement, displacedPos);
176  entprop.Position = displacedPos;
177  }
178 
179  base.UpdateProperties(entprop);
180  }
181 }
182 }
OpenMetaverse OMV
virtual Vector3 SetEffectiveCenterOfMassDisplacement(Vector3 centerOfMassDisplacement)
OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion rotation
Definition: ICM_Api.cs:32
BSPrimDisplaced(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
override void UpdateProperties(EntityProperties entprop)