opensim – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | eva | 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.Physics.Manager; |
||
35 | |||
36 | using OMV = OpenMetaverse; |
||
37 | |||
38 | namespace OpenSim.Region.Physics.BulletSPlugin |
||
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 | } |