diff options
author | Justin Clark-Casey (justincc) | 2012-07-27 00:30:04 +0100 |
---|---|---|
committer | Justin Clark-Casey (justincc) | 2012-07-27 00:30:04 +0100 |
commit | 5f741143fd328e8b13b512d9cc611178433eaef7 (patch) | |
tree | 06f919ea81fdd26918f64fc50521b0dc0ffedd40 /OpenSim/Region | |
parent | Fix issue where RegionCombinerModule was not removing regions from its dictio... (diff) | |
parent | BulletSim: fix a recursive loop when fetching the mass of the root of a linkset. (diff) | |
download | opensim-SC_OLD-5f741143fd328e8b13b512d9cc611178433eaef7.zip opensim-SC_OLD-5f741143fd328e8b13b512d9cc611178433eaef7.tar.gz opensim-SC_OLD-5f741143fd328e8b13b512d9cc611178433eaef7.tar.bz2 opensim-SC_OLD-5f741143fd328e8b13b512d9cc611178433eaef7.tar.xz |
Merge branch 'master' of ssh://opensimulator.org/var/git/opensim
Diffstat (limited to 'OpenSim/Region')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 9 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | 308 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | 327 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 7 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | 2 | ||||
-rw-r--r-- | OpenSim/Region/Physics/OdePlugin/OdeScene.cs | 9 |
6 files changed, 427 insertions, 235 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 24f62e3..1734704 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -1222,6 +1222,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1222 | 1222 | ||
1223 | m_sceneGraph.Close(); | 1223 | m_sceneGraph.Close(); |
1224 | 1224 | ||
1225 | if (PhysicsScene != null) | ||
1226 | { | ||
1227 | PhysicsScene phys = PhysicsScene; | ||
1228 | // remove the physics engine from both Scene and SceneGraph | ||
1229 | PhysicsScene = null; | ||
1230 | phys.Dispose(); | ||
1231 | phys = null; | ||
1232 | } | ||
1233 | |||
1225 | if (!GridService.DeregisterRegion(RegionInfo.RegionID)) | 1234 | if (!GridService.DeregisterRegion(RegionInfo.RegionID)) |
1226 | m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); | 1235 | m_log.WarnFormat("[SCENE]: Deregister from grid failed for region {0}", Name); |
1227 | 1236 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs new file mode 100755 index 0000000..3bc2100 --- /dev/null +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -0,0 +1,308 @@ | |||
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 | */ | ||
27 | using System; | ||
28 | using System.Collections.Generic; | ||
29 | using System.Text; | ||
30 | |||
31 | using OMV = OpenMetaverse; | ||
32 | |||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | ||
34 | { | ||
35 | public class BSLinkset | ||
36 | { | ||
37 | private static string LogHeader = "[BULLETSIM LINKSET]"; | ||
38 | |||
39 | private BSPrim m_linksetRoot; | ||
40 | public BSPrim Root { get { return m_linksetRoot; } } | ||
41 | |||
42 | private BSScene m_scene; | ||
43 | |||
44 | private List<BSPrim> m_children; | ||
45 | |||
46 | // We lock the diddling of linkset classes to prevent any badness. | ||
47 | // This locks the modification of the instances of this class. Changes | ||
48 | // to the physical representation is done via the tainting mechenism. | ||
49 | private object m_linksetActivityLock = new Object(); | ||
50 | |||
51 | // We keep the prim's mass in the linkset structure since it could be dependent on other prims | ||
52 | private float m_mass; | ||
53 | public float LinksetMass | ||
54 | { | ||
55 | get | ||
56 | { | ||
57 | m_mass = ComputeLinksetMass(); | ||
58 | return m_mass; | ||
59 | } | ||
60 | } | ||
61 | |||
62 | public OMV.Vector3 CenterOfMass | ||
63 | { | ||
64 | get { return ComputeLinksetCenterOfMass(); } | ||
65 | } | ||
66 | |||
67 | public OMV.Vector3 GeometricCenter | ||
68 | { | ||
69 | get { return ComputeLinksetGeometricCenter(); } | ||
70 | } | ||
71 | |||
72 | public BSLinkset(BSScene scene, BSPrim parent) | ||
73 | { | ||
74 | // A simple linkset of one (no children) | ||
75 | m_scene = scene; | ||
76 | m_linksetRoot = parent; | ||
77 | m_children = new List<BSPrim>(); | ||
78 | m_mass = parent.MassRaw; | ||
79 | } | ||
80 | |||
81 | // Link to a linkset where the child knows the parent. | ||
82 | // Parent changing should not happen so do some sanity checking. | ||
83 | // We return the parent's linkset so the child can track it's membership. | ||
84 | public BSLinkset AddMeToLinkset(BSPrim child, BSPrim parent) | ||
85 | { | ||
86 | lock (m_linksetActivityLock) | ||
87 | { | ||
88 | parent.Linkset.AddChildToLinkset(child); | ||
89 | } | ||
90 | return parent.Linkset; | ||
91 | } | ||
92 | |||
93 | public BSLinkset RemoveMeFromLinkset(BSPrim child) | ||
94 | { | ||
95 | lock (m_linksetActivityLock) | ||
96 | { | ||
97 | if (IsRoot(child)) | ||
98 | { | ||
99 | // if root of linkset, take the linkset apart | ||
100 | while (m_children.Count > 0) | ||
101 | { | ||
102 | // Note that we don't do a foreach because the remove routine | ||
103 | // takes it out of the list. | ||
104 | RemoveChildFromLinkset(m_children[0]); | ||
105 | } | ||
106 | m_children.Clear(); // just to make sure | ||
107 | } | ||
108 | else | ||
109 | { | ||
110 | // Just removing a child from an existing linkset | ||
111 | RemoveChildFromLinkset(child); | ||
112 | } | ||
113 | } | ||
114 | |||
115 | // The child is down to a linkset of just itself | ||
116 | return new BSLinkset(m_scene, child); | ||
117 | } | ||
118 | |||
119 | // An existing linkset had one of its members rebuilt or something. | ||
120 | // Undo all the physical linking and rebuild the physical linkset. | ||
121 | public bool RefreshLinkset(BSPrim requestor) | ||
122 | { | ||
123 | return true; | ||
124 | } | ||
125 | |||
126 | |||
127 | // Return 'true' if the passed object is the root object of this linkset | ||
128 | public bool IsRoot(BSPrim requestor) | ||
129 | { | ||
130 | return (requestor.LocalID == m_linksetRoot.LocalID); | ||
131 | } | ||
132 | |||
133 | // Return 'true' if this linkset has any children (more than the root member) | ||
134 | public bool HasAnyChildren { get { return (m_children.Count > 0); } } | ||
135 | |||
136 | // Return 'true' if this child is in this linkset | ||
137 | public bool HasChild(BSPrim child) | ||
138 | { | ||
139 | bool ret = false; | ||
140 | foreach (BSPrim bp in m_children) | ||
141 | { | ||
142 | if (child.LocalID == bp.LocalID) | ||
143 | { | ||
144 | ret = true; | ||
145 | break; | ||
146 | } | ||
147 | } | ||
148 | return ret; | ||
149 | } | ||
150 | |||
151 | private float ComputeLinksetMass() | ||
152 | { | ||
153 | float mass = m_linksetRoot.MassRaw; | ||
154 | foreach (BSPrim bp in m_children) | ||
155 | { | ||
156 | mass += bp.MassRaw; | ||
157 | } | ||
158 | return mass; | ||
159 | } | ||
160 | |||
161 | private OMV.Vector3 ComputeLinksetCenterOfMass() | ||
162 | { | ||
163 | OMV.Vector3 com = m_linksetRoot.Position * m_linksetRoot.MassRaw; | ||
164 | float totalMass = m_linksetRoot.MassRaw; | ||
165 | |||
166 | foreach (BSPrim bp in m_children) | ||
167 | { | ||
168 | com += bp.Position * bp.MassRaw; | ||
169 | totalMass += bp.MassRaw; | ||
170 | } | ||
171 | com /= totalMass; | ||
172 | |||
173 | return com; | ||
174 | } | ||
175 | |||
176 | private OMV.Vector3 ComputeLinksetGeometricCenter() | ||
177 | { | ||
178 | OMV.Vector3 com = m_linksetRoot.Position; | ||
179 | |||
180 | foreach (BSPrim bp in m_children) | ||
181 | { | ||
182 | com += bp.Position * bp.MassRaw; | ||
183 | } | ||
184 | com /= m_children.Count + 1; | ||
185 | |||
186 | return com; | ||
187 | } | ||
188 | |||
189 | // I am the root of a linkset and a new child is being added | ||
190 | public void AddChildToLinkset(BSPrim pchild) | ||
191 | { | ||
192 | BSPrim child = pchild; | ||
193 | if (!HasChild(child)) | ||
194 | { | ||
195 | m_children.Add(child); | ||
196 | |||
197 | m_scene.TaintedObject(delegate() | ||
198 | { | ||
199 | DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, m_linksetRoot.LocalID); | ||
200 | DetailLog("{0},AddChildToLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID); | ||
201 | PhysicallyLinkAChildToRoot(pchild); // build the physical binding between me and the child | ||
202 | }); | ||
203 | } | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | // I am the root of a linkset and one of my children is being removed. | ||
208 | // Safe to call even if the child is not really in my linkset. | ||
209 | public void RemoveChildFromLinkset(BSPrim pchild) | ||
210 | { | ||
211 | BSPrim child = pchild; | ||
212 | |||
213 | if (m_children.Remove(child)) | ||
214 | { | ||
215 | m_scene.TaintedObject(delegate() | ||
216 | { | ||
217 | DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); | ||
218 | DetailLog("{0},RemoveChildFromLinkset,child={1}", m_linksetRoot.LocalID, pchild.LocalID); | ||
219 | |||
220 | if (m_children.Count == 0) | ||
221 | { | ||
222 | // if the linkset is empty, make sure all linkages have been removed | ||
223 | PhysicallyUnlinkAllChildrenFromRoot(); | ||
224 | } | ||
225 | else | ||
226 | { | ||
227 | PhysicallyUnlinkAChildFromRoot(pchild); | ||
228 | } | ||
229 | }); | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | // This will happen if we remove the root of the linkset first. Non-fatal occurance. | ||
234 | // m_scene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); | ||
235 | } | ||
236 | return; | ||
237 | } | ||
238 | |||
239 | // Create a constraint between me (root of linkset) and the passed prim (the child). | ||
240 | // Called at taint time! | ||
241 | private void PhysicallyLinkAChildToRoot(BSPrim childPrim) | ||
242 | { | ||
243 | // Zero motion for children so they don't interpolate | ||
244 | childPrim.ZeroMotion(); | ||
245 | |||
246 | // relative position normalized to the root prim | ||
247 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(m_linksetRoot.Orientation); | ||
248 | OMV.Vector3 childRelativePosition = (childPrim.Position - m_linksetRoot.Position) * invThisOrientation; | ||
249 | |||
250 | // relative rotation of the child to the parent | ||
251 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim.Orientation; | ||
252 | |||
253 | // create a constraint that allows no freedom of movement between the two objects | ||
254 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||
255 | // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); | ||
256 | DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); | ||
257 | BSConstraint constrain = m_scene.Constraints.CreateConstraint( | ||
258 | m_scene.World, m_linksetRoot.Body, childPrim.Body, | ||
259 | childRelativePosition, | ||
260 | childRelativeRotation, | ||
261 | OMV.Vector3.Zero, | ||
262 | OMV.Quaternion.Identity); | ||
263 | constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
264 | constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
265 | |||
266 | // tweek the constraint to increase stability | ||
267 | constrain.UseFrameOffset(m_scene.BoolNumeric(m_scene.Params.linkConstraintUseFrameOffset)); | ||
268 | constrain.TranslationalLimitMotor(m_scene.BoolNumeric(m_scene.Params.linkConstraintEnableTransMotor), | ||
269 | m_scene.Params.linkConstraintTransMotorMaxVel, | ||
270 | m_scene.Params.linkConstraintTransMotorMaxForce); | ||
271 | |||
272 | } | ||
273 | |||
274 | // Remove linkage between myself and a particular child | ||
275 | // Called at taint time! | ||
276 | private void PhysicallyUnlinkAChildFromRoot(BSPrim childPrim) | ||
277 | { | ||
278 | DebugLog("{0}: PhysicallyUnlinkAChildFromRoot: RemoveConstraint between root prim {1} and child prim {2}", | ||
279 | LogHeader, m_linksetRoot.LocalID, childPrim.LocalID); | ||
280 | DetailLog("{0},PhysicallyUnlinkAChildFromRoot,taint,root={1},child={2}", m_linksetRoot.LocalID, m_linksetRoot.LocalID, childPrim.LocalID); | ||
281 | // BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID); | ||
282 | m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body, childPrim.Body); | ||
283 | } | ||
284 | |||
285 | // Remove linkage between myself and any possible children I might have | ||
286 | // Called at taint time! | ||
287 | private void PhysicallyUnlinkAllChildrenFromRoot() | ||
288 | { | ||
289 | // DebugLog("{0}: PhysicallyUnlinkAllChildren:", LogHeader); | ||
290 | DetailLog("{0},PhysicallyUnlinkAllChildren,taint", m_linksetRoot.LocalID); | ||
291 | m_scene.Constraints.RemoveAndDestroyConstraint(m_linksetRoot.Body); | ||
292 | // BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID); | ||
293 | } | ||
294 | |||
295 | // Invoke the detailed logger and output something if it's enabled. | ||
296 | private void DebugLog(string msg, params Object[] args) | ||
297 | { | ||
298 | m_scene.Logger.DebugFormat(msg, args); | ||
299 | } | ||
300 | |||
301 | // Invoke the detailed logger and output something if it's enabled. | ||
302 | private void DetailLog(string msg, params Object[] args) | ||
303 | { | ||
304 | m_scene.PhysicsLogging.Write(msg, args); | ||
305 | } | ||
306 | |||
307 | } | ||
308 | } | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 3be28e3..7590d93 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -66,7 +66,7 @@ public sealed class BSPrim : PhysicsActor | |||
66 | private bool _isSelected; | 66 | private bool _isSelected; |
67 | private bool _isVolumeDetect; | 67 | private bool _isVolumeDetect; |
68 | private OMV.Vector3 _position; | 68 | private OMV.Vector3 _position; |
69 | private float _mass; | 69 | private float _mass; // the mass of this object |
70 | private float _density; | 70 | private float _density; |
71 | private OMV.Vector3 _force; | 71 | private OMV.Vector3 _force; |
72 | private OMV.Vector3 _velocity; | 72 | private OMV.Vector3 _velocity; |
@@ -89,8 +89,13 @@ public sealed class BSPrim : PhysicsActor | |||
89 | private bool _kinematic; | 89 | private bool _kinematic; |
90 | private float _buoyancy; | 90 | private float _buoyancy; |
91 | 91 | ||
92 | private BSPrim _parentPrim; | 92 | // Membership in a linkset is controlled by this class. |
93 | private List<BSPrim> _childrenPrims; | 93 | private BSLinkset _linkset; |
94 | public BSLinkset Linkset | ||
95 | { | ||
96 | get { return _linkset; } | ||
97 | set { _linkset = value; } | ||
98 | } | ||
94 | 99 | ||
95 | private int _subscribedEventsMs = 0; | 100 | private int _subscribedEventsMs = 0; |
96 | private int _nextCollisionOkTime = 0; | 101 | private int _nextCollisionOkTime = 0; |
@@ -133,9 +138,8 @@ public sealed class BSPrim : PhysicsActor | |||
133 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material | 138 | _friction = _scene.Params.defaultFriction; // TODO: compute based on object material |
134 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material | 139 | _density = _scene.Params.defaultDensity; // TODO: compute based on object material |
135 | _restitution = _scene.Params.defaultRestitution; | 140 | _restitution = _scene.Params.defaultRestitution; |
136 | _parentPrim = null; // not a child or a parent | 141 | _linkset = new BSLinkset(_scene, this); // a linkset of one |
137 | _vehicle = new BSDynamics(this); // add vehicleness | 142 | _vehicle = new BSDynamics(this); // add vehicleness |
138 | _childrenPrims = new List<BSPrim>(); | ||
139 | _mass = CalculateMass(); | 143 | _mass = CalculateMass(); |
140 | // do the actual object creation at taint time | 144 | // do the actual object creation at taint time |
141 | _scene.TaintedObject(delegate() | 145 | _scene.TaintedObject(delegate() |
@@ -161,16 +165,8 @@ public sealed class BSPrim : PhysicsActor | |||
161 | 165 | ||
162 | _scene.TaintedObject(delegate() | 166 | _scene.TaintedObject(delegate() |
163 | { | 167 | { |
164 | // undo any dependance with/on other objects | 168 | // Undo any links between me and any other object |
165 | if (_parentPrim != null) | 169 | _linkset = _linkset.RemoveMeFromLinkset(this); |
166 | { | ||
167 | // If I'm someone's child, tell them to forget about me. | ||
168 | _parentPrim.RemoveChildFromLinkset(this); | ||
169 | _parentPrim = null; | ||
170 | } | ||
171 | |||
172 | // make sure there are no other prims linked to me | ||
173 | UnlinkAllChildren(); | ||
174 | 170 | ||
175 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. | 171 | // everything in the C# world will get garbage collected. Tell the C++ world to free stuff. |
176 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); | 172 | BulletSimAPI.DestroyObject(_scene.WorldID, LocalID); |
@@ -187,7 +183,7 @@ public sealed class BSPrim : PhysicsActor | |||
187 | _scene.TaintedObject(delegate() | 183 | _scene.TaintedObject(delegate() |
188 | { | 184 | { |
189 | _mass = CalculateMass(); // changing size changes the mass | 185 | _mass = CalculateMass(); // changing size changes the mass |
190 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, Mass, IsPhysical); | 186 | BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical); |
191 | RecreateGeomAndObject(); | 187 | RecreateGeomAndObject(); |
192 | }); | 188 | }); |
193 | } | 189 | } |
@@ -226,32 +222,8 @@ public sealed class BSPrim : PhysicsActor | |||
226 | BSPrim parent = obj as BSPrim; | 222 | BSPrim parent = obj as BSPrim; |
227 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); | 223 | DebugLog("{0}: link {1}/{2} to {3}", LogHeader, _avName, _localID, obj.LocalID); |
228 | DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); | 224 | DetailLog("{0},link,parent={1}", LocalID, obj.LocalID); |
229 | // TODO: decide if this parent checking needs to happen at taint time | 225 | |
230 | if (_parentPrim == null) | 226 | _linkset = _linkset.AddMeToLinkset(this, parent); |
231 | { | ||
232 | if (parent != null) | ||
233 | { | ||
234 | // I don't have a parent so I am joining a linkset | ||
235 | parent.AddChildToLinkset(this); | ||
236 | } | ||
237 | } | ||
238 | else | ||
239 | { | ||
240 | // I already have a parent, is parenting changing? | ||
241 | if (parent != _parentPrim) | ||
242 | { | ||
243 | if (parent == null) | ||
244 | { | ||
245 | // we are being removed from a linkset | ||
246 | _parentPrim.RemoveChildFromLinkset(this); | ||
247 | } | ||
248 | else | ||
249 | { | ||
250 | // asking to reparent a prim should not happen | ||
251 | m_log.ErrorFormat("{0}: link(): Reparenting a prim. ", LogHeader); | ||
252 | } | ||
253 | } | ||
254 | } | ||
255 | return; | 227 | return; |
256 | } | 228 | } |
257 | 229 | ||
@@ -260,81 +232,18 @@ public sealed class BSPrim : PhysicsActor | |||
260 | // TODO: decide if this parent checking needs to happen at taint time | 232 | // TODO: decide if this parent checking needs to happen at taint time |
261 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen | 233 | // Race condition here: if link() and delink() in same simulation tick, the delink will not happen |
262 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, | 234 | DebugLog("{0}: delink {1}/{2}. Parent={3}", LogHeader, _avName, _localID, |
263 | (_parentPrim==null ? "NULL" : _parentPrim._avName+"/"+_parentPrim.LocalID.ToString())); | 235 | _linkset.Root._avName+"/"+_linkset.Root.LocalID.ToString()); |
264 | DetailLog("{0},delink,parent={1}", LocalID, (_parentPrim==null ? "NULL" : _parentPrim.LocalID.ToString())); | 236 | DetailLog("{0},delink,parent={1}", LocalID, _linkset.Root.LocalID.ToString()); |
265 | if (_parentPrim != null) | ||
266 | { | ||
267 | _parentPrim.RemoveChildFromLinkset(this); | ||
268 | } | ||
269 | return; | ||
270 | } | ||
271 | 237 | ||
272 | // I am the root of a linkset and a new child is being added | 238 | _linkset.RemoveMeFromLinkset(this); |
273 | public void AddChildToLinkset(BSPrim pchild) | 239 | return; |
274 | { | ||
275 | BSPrim child = pchild; | ||
276 | _scene.TaintedObject(delegate() | ||
277 | { | ||
278 | if (!_childrenPrims.Contains(child)) | ||
279 | { | ||
280 | DebugLog("{0}: AddChildToLinkset: adding child {1} to {2}", LogHeader, child.LocalID, this.LocalID); | ||
281 | DetailLog("{0},AddChildToLinkset,child={1}", LocalID, pchild.LocalID); | ||
282 | _childrenPrims.Add(child); | ||
283 | child._parentPrim = this; // the child has gained a parent | ||
284 | // RecreateGeomAndObject(); // rebuild my shape with the new child added | ||
285 | LinkAChildToMe(pchild); // build the physical binding between me and the child | ||
286 | |||
287 | _mass = CalculateMass(); | ||
288 | } | ||
289 | }); | ||
290 | return; | ||
291 | } | ||
292 | |||
293 | // I am the root of a linkset and one of my children is being removed. | ||
294 | // Safe to call even if the child is not really in my linkset. | ||
295 | public void RemoveChildFromLinkset(BSPrim pchild) | ||
296 | { | ||
297 | BSPrim child = pchild; | ||
298 | _scene.TaintedObject(delegate() | ||
299 | { | ||
300 | if (_childrenPrims.Contains(child)) | ||
301 | { | ||
302 | DebugLog("{0}: RemoveChildFromLinkset: Removing constraint to {1}", LogHeader, child.LocalID); | ||
303 | DetailLog("{0},RemoveChildFromLinkset,child={1}", LocalID, pchild.LocalID); | ||
304 | _childrenPrims.Remove(child); | ||
305 | child._parentPrim = null; // the child has lost its parent | ||
306 | if (_childrenPrims.Count == 0) | ||
307 | { | ||
308 | // if the linkset is empty, make sure all linkages have been removed | ||
309 | UnlinkAllChildren(); | ||
310 | } | ||
311 | else | ||
312 | { | ||
313 | // RecreateGeomAndObject(); // rebuild my shape with the child removed | ||
314 | UnlinkAChildFromMe(pchild); | ||
315 | } | ||
316 | |||
317 | _mass = CalculateMass(); | ||
318 | } | ||
319 | else | ||
320 | { | ||
321 | m_log.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset"); | ||
322 | } | ||
323 | }); | ||
324 | return; | ||
325 | } | ||
326 | |||
327 | // return true if we are the root of a linkset (there are children to manage) | ||
328 | public bool IsRootOfLinkset | ||
329 | { | ||
330 | get { return (_parentPrim == null && _childrenPrims.Count != 0); } | ||
331 | } | 240 | } |
332 | 241 | ||
333 | // Set motion values to zero. | 242 | // Set motion values to zero. |
334 | // Do it to the properties so the values get set in the physics engine. | 243 | // Do it to the properties so the values get set in the physics engine. |
335 | // Push the setting of the values to the viewer. | 244 | // Push the setting of the values to the viewer. |
336 | // Called at taint time! | 245 | // Called at taint time! |
337 | private void ZeroMotion() | 246 | public void ZeroMotion() |
338 | { | 247 | { |
339 | _velocity = OMV.Vector3.Zero; | 248 | _velocity = OMV.Vector3.Zero; |
340 | _acceleration = OMV.Vector3.Zero; | 249 | _acceleration = OMV.Vector3.Zero; |
@@ -355,9 +264,10 @@ public sealed class BSPrim : PhysicsActor | |||
355 | 264 | ||
356 | public override OMV.Vector3 Position { | 265 | public override OMV.Vector3 Position { |
357 | get { | 266 | get { |
358 | // child prims move around based on their parent. Need to get the latest location | 267 | if (!_linkset.IsRoot(this)) |
359 | if (_parentPrim != null) | 268 | // child prims move around based on their parent. Need to get the latest location |
360 | _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 269 | _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
270 | |||
361 | // don't do the GetObjectPosition for root elements because this function is called a zillion times | 271 | // don't do the GetObjectPosition for root elements because this function is called a zillion times |
362 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); | 272 | // _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID); |
363 | return _position; | 273 | return _position; |
@@ -373,16 +283,31 @@ public sealed class BSPrim : PhysicsActor | |||
373 | } | 283 | } |
374 | } | 284 | } |
375 | 285 | ||
376 | // Return the effective mass of the object. Non-physical objects do not have mass. | 286 | // Return the effective mass of the object. |
377 | public override float Mass { | 287 | // If there are multiple items in the linkset, add them together for the root |
378 | get { | 288 | public override float Mass |
379 | if (IsPhysical) | 289 | { |
380 | return _mass; | 290 | get |
381 | else | 291 | { |
382 | return 0f; | 292 | return _linkset.LinksetMass; |
383 | } | 293 | } |
384 | } | 294 | } |
385 | 295 | ||
296 | // used when we only want this prim's mass and not the linkset thing | ||
297 | public float MassRaw { get { return _mass; } } | ||
298 | |||
299 | // Is this used? | ||
300 | public override OMV.Vector3 CenterOfMass | ||
301 | { | ||
302 | get { return _linkset.CenterOfMass; } | ||
303 | } | ||
304 | |||
305 | // Is this used? | ||
306 | public override OMV.Vector3 GeometricCenter | ||
307 | { | ||
308 | get { return _linkset.GeometricCenter; } | ||
309 | } | ||
310 | |||
386 | public override OMV.Vector3 Force { | 311 | public override OMV.Vector3 Force { |
387 | get { return _force; } | 312 | get { return _force; } |
388 | set { | 313 | set { |
@@ -473,8 +398,6 @@ public sealed class BSPrim : PhysicsActor | |||
473 | return; | 398 | return; |
474 | } | 399 | } |
475 | 400 | ||
476 | public override OMV.Vector3 GeometricCenter { get { return OMV.Vector3.Zero; } } | ||
477 | public override OMV.Vector3 CenterOfMass { get { return OMV.Vector3.Zero; } } | ||
478 | public override OMV.Vector3 Velocity { | 401 | public override OMV.Vector3 Velocity { |
479 | get { return _velocity; } | 402 | get { return _velocity; } |
480 | set { | 403 | set { |
@@ -503,9 +426,9 @@ public sealed class BSPrim : PhysicsActor | |||
503 | } | 426 | } |
504 | public override OMV.Quaternion Orientation { | 427 | public override OMV.Quaternion Orientation { |
505 | get { | 428 | get { |
506 | if (_parentPrim != null) | 429 | if (!_linkset.IsRoot(this)) |
507 | { | 430 | { |
508 | // children move around because tied to parent. Get a fresh value. | 431 | // Children move around because tied to parent. Get a fresh value. |
509 | _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); | 432 | _orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID); |
510 | } | 433 | } |
511 | return _orientation; | 434 | return _orientation; |
@@ -555,14 +478,16 @@ public sealed class BSPrim : PhysicsActor | |||
555 | private void SetObjectDynamic() | 478 | private void SetObjectDynamic() |
556 | { | 479 | { |
557 | // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); | 480 | // m_log.DebugFormat("{0}: ID={1}, SetObjectDynamic: IsStatic={2}, IsSolid={3}", LogHeader, _localID, IsStatic, IsSolid); |
558 | // non-physical things work best with a mass of zero | 481 | |
559 | if (!IsStatic) | 482 | RecreateGeomAndObject(); |
560 | { | 483 | |
561 | _mass = CalculateMass(); | 484 | float mass = _mass; |
562 | RecreateGeomAndObject(); | 485 | // Bullet wants static objects have a mass of zero |
563 | } | 486 | if (IsStatic) |
564 | DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, Mass); | 487 | mass = 0f; |
565 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), Mass); | 488 | |
489 | DetailLog("{0},SetObjectDynamic,taint,static={1},solid={2},mass={3}", LocalID, IsStatic, IsSolid, mass); | ||
490 | BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass); | ||
566 | } | 491 | } |
567 | 492 | ||
568 | // prims don't fly | 493 | // prims don't fly |
@@ -1004,6 +929,9 @@ public sealed class BSPrim : PhysicsActor | |||
1004 | 929 | ||
1005 | returnMass = _density * volume; | 930 | returnMass = _density * volume; |
1006 | 931 | ||
932 | /* | ||
933 | * This change means each object keeps its own mass and the Mass property | ||
934 | * will return the sum if we're part of a linkset. | ||
1007 | if (IsRootOfLinkset) | 935 | if (IsRootOfLinkset) |
1008 | { | 936 | { |
1009 | foreach (BSPrim prim in _childrenPrims) | 937 | foreach (BSPrim prim in _childrenPrims) |
@@ -1011,6 +939,7 @@ public sealed class BSPrim : PhysicsActor | |||
1011 | returnMass += prim.CalculateMass(); | 939 | returnMass += prim.CalculateMass(); |
1012 | } | 940 | } |
1013 | } | 941 | } |
942 | */ | ||
1014 | 943 | ||
1015 | if (returnMass <= 0) | 944 | if (returnMass <= 0) |
1016 | returnMass = 0.0001f; | 945 | returnMass = 0.0001f; |
@@ -1026,9 +955,11 @@ public sealed class BSPrim : PhysicsActor | |||
1026 | // The objects needs a hull if it's physical otherwise a mesh is enough | 955 | // The objects needs a hull if it's physical otherwise a mesh is enough |
1027 | // No locking here because this is done when we know physics is not simulating | 956 | // No locking here because this is done when we know physics is not simulating |
1028 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used | 957 | // if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used |
1029 | private void CreateGeom(bool forceRebuild) | 958 | // Returns 'true' if the geometry was rebuilt |
959 | private bool CreateGeom(bool forceRebuild) | ||
1030 | { | 960 | { |
1031 | // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. | 961 | // the mesher thought this was too simple to mesh. Use a native Bullet collision shape. |
962 | bool ret = false; | ||
1032 | if (!_scene.NeedsMeshing(_pbs)) | 963 | if (!_scene.NeedsMeshing(_pbs)) |
1033 | { | 964 | { |
1034 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) | 965 | if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1) |
@@ -1036,18 +967,26 @@ public sealed class BSPrim : PhysicsActor | |||
1036 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) | 967 | if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z) |
1037 | { | 968 | { |
1038 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); | 969 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size); |
1039 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; | 970 | if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE) |
1040 | DetailLog("{0},CreateGeom,sphere", LocalID); | 971 | { |
1041 | // Bullet native objects are scaled by the Bullet engine so pass the size in | 972 | DetailLog("{0},CreateGeom,sphere", LocalID); |
1042 | _scale = _size; | 973 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_SPHERE; |
974 | ret = true; | ||
975 | // Bullet native objects are scaled by the Bullet engine so pass the size in | ||
976 | _scale = _size; | ||
977 | } | ||
1043 | } | 978 | } |
1044 | } | 979 | } |
1045 | else | 980 | else |
1046 | { | 981 | { |
1047 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); | 982 | // m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, size={2}", LogHeader, LocalID, _size); |
1048 | DetailLog("{0},CreateGeom,box", LocalID); | 983 | if (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX) |
1049 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; | 984 | { |
1050 | _scale = _size; | 985 | DetailLog("{0},CreateGeom,box", LocalID); |
986 | _shapeType = ShapeData.PhysicsShapeType.SHAPE_BOX; | ||
987 | ret = true; | ||
988 | _scale = _size; | ||
989 | } | ||
1051 | } | 990 | } |
1052 | } | 991 | } |
1053 | else | 992 | else |
@@ -1059,6 +998,7 @@ public sealed class BSPrim : PhysicsActor | |||
1059 | // physical objects require a hull for interaction. | 998 | // physical objects require a hull for interaction. |
1060 | // This will create the mesh if it doesn't already exist | 999 | // This will create the mesh if it doesn't already exist |
1061 | CreateGeomHull(); | 1000 | CreateGeomHull(); |
1001 | ret = true; | ||
1062 | } | 1002 | } |
1063 | } | 1003 | } |
1064 | else | 1004 | else |
@@ -1067,9 +1007,11 @@ public sealed class BSPrim : PhysicsActor | |||
1067 | { | 1007 | { |
1068 | // Static (non-physical) objects only need a mesh for bumping into | 1008 | // Static (non-physical) objects only need a mesh for bumping into |
1069 | CreateGeomMesh(); | 1009 | CreateGeomMesh(); |
1010 | ret = true; | ||
1070 | } | 1011 | } |
1071 | } | 1012 | } |
1072 | } | 1013 | } |
1014 | return ret; | ||
1073 | } | 1015 | } |
1074 | 1016 | ||
1075 | // No locking here because this is done when we know physics is not simulating | 1017 | // No locking here because this is done when we know physics is not simulating |
@@ -1254,20 +1196,18 @@ public sealed class BSPrim : PhysicsActor | |||
1254 | // No locking here because this is done when the physics engine is not simulating | 1196 | // No locking here because this is done when the physics engine is not simulating |
1255 | private void CreateObject() | 1197 | private void CreateObject() |
1256 | { | 1198 | { |
1257 | if (IsRootOfLinkset) | 1199 | // this routine is called when objects are rebuilt. |
1258 | { | 1200 | |
1259 | // Create a linkset around this object | 1201 | // the mesh or hull must have already been created in Bullet |
1260 | CreateLinkset(); | 1202 | ShapeData shape; |
1261 | } | 1203 | FillShapeInfo(out shape); |
1262 | else | 1204 | // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); |
1263 | { | 1205 | BulletSimAPI.CreateObject(_scene.WorldID, shape); |
1264 | // simple object | 1206 | // the CreateObject() may have recreated the rigid body. Make sure we have the latest. |
1265 | // the mesh or hull must have already been created in Bullet | 1207 | m_body.Ptr = BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID); |
1266 | ShapeData shape; | 1208 | |
1267 | FillShapeInfo(out shape); | 1209 | // The root object could have been recreated. Make sure everything linksety is up to date. |
1268 | // m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type); | 1210 | _linkset.RefreshLinkset(this); |
1269 | BulletSimAPI.CreateObject(_scene.WorldID, shape); | ||
1270 | } | ||
1271 | } | 1211 | } |
1272 | 1212 | ||
1273 | // Copy prim's info into the BulletSim shape description structure | 1213 | // Copy prim's info into the BulletSim shape description structure |
@@ -1279,7 +1219,7 @@ public sealed class BSPrim : PhysicsActor | |||
1279 | shape.Rotation = _orientation; | 1219 | shape.Rotation = _orientation; |
1280 | shape.Velocity = _velocity; | 1220 | shape.Velocity = _velocity; |
1281 | shape.Scale = _scale; | 1221 | shape.Scale = _scale; |
1282 | shape.Mass = Mass; | 1222 | shape.Mass = _isPhysical ? _mass : 0f; |
1283 | shape.Buoyancy = _buoyancy; | 1223 | shape.Buoyancy = _buoyancy; |
1284 | shape.HullKey = _hullKey; | 1224 | shape.HullKey = _hullKey; |
1285 | shape.MeshKey = _meshKey; | 1225 | shape.MeshKey = _meshKey; |
@@ -1289,83 +1229,6 @@ public sealed class BSPrim : PhysicsActor | |||
1289 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; | 1229 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; |
1290 | } | 1230 | } |
1291 | 1231 | ||
1292 | #region Linkset creation and destruction | ||
1293 | |||
1294 | // Create the linkset by putting constraints between the objects of the set so they cannot move | ||
1295 | // relative to each other. | ||
1296 | void CreateLinkset() | ||
1297 | { | ||
1298 | // DebugLog("{0}: CreateLinkset. Root prim={1}, prims={2}", LogHeader, LocalID, _childrenPrims.Count+1); | ||
1299 | |||
1300 | // remove any constraints that might be in place | ||
1301 | UnlinkAllChildren(); | ||
1302 | |||
1303 | // create constraints between the root prim and each of the children | ||
1304 | foreach (BSPrim prim in _childrenPrims) | ||
1305 | { | ||
1306 | LinkAChildToMe(prim); | ||
1307 | } | ||
1308 | } | ||
1309 | |||
1310 | // Create a constraint between me (root of linkset) and the passed prim (the child). | ||
1311 | // Called at taint time! | ||
1312 | private void LinkAChildToMe(BSPrim childPrim) | ||
1313 | { | ||
1314 | // Zero motion for children so they don't interpolate | ||
1315 | childPrim.ZeroMotion(); | ||
1316 | |||
1317 | // relative position normalized to the root prim | ||
1318 | OMV.Quaternion invThisOrientation = OMV.Quaternion.Inverse(this._orientation); | ||
1319 | OMV.Vector3 childRelativePosition = (childPrim._position - this._position) * invThisOrientation; | ||
1320 | |||
1321 | // relative rotation of the child to the parent | ||
1322 | OMV.Quaternion childRelativeRotation = invThisOrientation * childPrim._orientation; | ||
1323 | |||
1324 | // create a constraint that allows no freedom of movement between the two objects | ||
1325 | // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=4818 | ||
1326 | // DebugLog("{0}: CreateLinkset: Adding a constraint between root prim {1} and child prim {2}", LogHeader, LocalID, childPrim.LocalID); | ||
1327 | DetailLog("{0},LinkAChildToMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID); | ||
1328 | BSConstraint constrain = _scene.Constraints.CreateConstraint( | ||
1329 | _scene.World, this.Body, childPrim.Body, | ||
1330 | childRelativePosition, | ||
1331 | childRelativeRotation, | ||
1332 | OMV.Vector3.Zero, | ||
1333 | OMV.Quaternion.Identity); | ||
1334 | constrain.SetLinearLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
1335 | constrain.SetAngularLimits(OMV.Vector3.Zero, OMV.Vector3.Zero); | ||
1336 | |||
1337 | // tweek the constraint to increase stability | ||
1338 | constrain.UseFrameOffset(_scene.BoolNumeric(_scene.Params.linkConstraintUseFrameOffset)); | ||
1339 | if (_scene.BoolNumeric(_scene.Params.linkConstraintEnableTransMotor)) | ||
1340 | { | ||
1341 | constrain.TranslationalLimitMotor(true, | ||
1342 | _scene.Params.linkConstraintTransMotorMaxVel, | ||
1343 | _scene.Params.linkConstraintTransMotorMaxForce); | ||
1344 | } | ||
1345 | } | ||
1346 | |||
1347 | // Remove linkage between myself and a particular child | ||
1348 | // Called at taint time! | ||
1349 | private void UnlinkAChildFromMe(BSPrim childPrim) | ||
1350 | { | ||
1351 | DebugLog("{0}: UnlinkAChildFromMe: RemoveConstraint between root prim {1} and child prim {2}", | ||
1352 | LogHeader, LocalID, childPrim.LocalID); | ||
1353 | DetailLog("{0},UnlinkAChildFromMe,taint,root={1},child={2}", LocalID, LocalID, childPrim.LocalID); | ||
1354 | // BulletSimAPI.RemoveConstraint(_scene.WorldID, LocalID, childPrim.LocalID); | ||
1355 | _scene.Constraints.RemoveAndDestroyConstraint(this.Body, childPrim.Body); | ||
1356 | } | ||
1357 | |||
1358 | // Remove linkage between myself and any possible children I might have | ||
1359 | // Called at taint time! | ||
1360 | private void UnlinkAllChildren() | ||
1361 | { | ||
1362 | DebugLog("{0}: UnlinkAllChildren:", LogHeader); | ||
1363 | DetailLog("{0},UnlinkAllChildren,taint", LocalID); | ||
1364 | _scene.Constraints.RemoveAndDestroyConstraint(this.Body); | ||
1365 | // BulletSimAPI.RemoveConstraintByID(_scene.WorldID, LocalID); | ||
1366 | } | ||
1367 | |||
1368 | #endregion // Linkset creation and destruction | ||
1369 | 1232 | ||
1370 | // Rebuild the geometry and object. | 1233 | // Rebuild the geometry and object. |
1371 | // This is called when the shape changes so we need to recreate the mesh/hull. | 1234 | // This is called when the shape changes so we need to recreate the mesh/hull. |
@@ -1443,7 +1306,7 @@ public sealed class BSPrim : PhysicsActor | |||
1443 | // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. | 1306 | // Don't check for damping here -- it's done in BulletSim and SceneObjectPart. |
1444 | 1307 | ||
1445 | // Updates only for individual prims and for the root object of a linkset. | 1308 | // Updates only for individual prims and for the root object of a linkset. |
1446 | if (_parentPrim == null) | 1309 | if (_linkset.IsRoot(this)) |
1447 | { | 1310 | { |
1448 | // Assign to the local variables so the normal set action does not happen | 1311 | // Assign to the local variables so the normal set action does not happen |
1449 | _position = entprop.Position; | 1312 | _position = entprop.Position; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index a1587a8..c6d622b 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -73,7 +73,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
73 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); | 73 | private static readonly ILog m_log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); |
74 | private static readonly string LogHeader = "[BULLETS SCENE]"; | 74 | private static readonly string LogHeader = "[BULLETS SCENE]"; |
75 | 75 | ||
76 | private void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); } | 76 | public void DebugLog(string mm, params Object[] xx) { if (shouldDebugLog) m_log.DebugFormat(mm, xx); } |
77 | 77 | ||
78 | public string BulletSimVersion = "?"; | 78 | public string BulletSimVersion = "?"; |
79 | 79 | ||
@@ -87,6 +87,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
87 | private uint m_worldID; | 87 | private uint m_worldID; |
88 | public uint WorldID { get { return m_worldID; } } | 88 | public uint WorldID { get { return m_worldID; } } |
89 | 89 | ||
90 | // let my minuions use my logger | ||
91 | public ILog Logger { get { return m_log; } } | ||
92 | |||
90 | private bool m_initialized = false; | 93 | private bool m_initialized = false; |
91 | 94 | ||
92 | private int m_detailedStatsStep = 0; | 95 | private int m_detailedStatsStep = 0; |
@@ -1026,7 +1029,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters | |||
1026 | (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), | 1029 | (s,p,l,v) => { s.m_params[0].numberOfSolverIterations = v; } ), |
1027 | 1030 | ||
1028 | new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", | 1031 | new ParameterDefn("LinkConstraintUseFrameOffset", "For linksets built with constraints, enable frame offsetFor linksets built with constraints, enable frame offset.", |
1029 | ConfigurationParameters.numericTrue, | 1032 | ConfigurationParameters.numericFalse, |
1030 | (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, | 1033 | (s,cf,p,v) => { s.m_params[0].linkConstraintUseFrameOffset = s.NumericBool(cf.GetBoolean(p, s.BoolNumeric(v))); }, |
1031 | (s) => { return s.m_params[0].linkConstraintUseFrameOffset; }, | 1034 | (s) => { return s.m_params[0].linkConstraintUseFrameOffset; }, |
1032 | (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ), | 1035 | (s,p,l,v) => { s.m_params[0].linkConstraintUseFrameOffset = v; } ), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 89fd9b7..65e3145 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -239,10 +239,10 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey); | |||
239 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 239 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
240 | public static extern bool CreateObject(uint worldID, ShapeData shapeData); | 240 | public static extern bool CreateObject(uint worldID, ShapeData shapeData); |
241 | 241 | ||
242 | /* Remove old functionality | ||
242 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 243 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
243 | public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas); | 244 | public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas); |
244 | 245 | ||
245 | /* Remove old functionality | ||
246 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 246 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
247 | public static extern void AddConstraint(uint worldID, uint id1, uint id2, | 247 | public static extern void AddConstraint(uint worldID, uint id1, uint id2, |
248 | Vector3 frame1, Quaternion frame1rot, | 248 | Vector3 frame1, Quaternion frame1rot, |
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs index 32e81e2..0db936f 100644 --- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs +++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs | |||
@@ -489,6 +489,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
489 | /// </summary> | 489 | /// </summary> |
490 | internal Object OdeLock = new Object(); | 490 | internal Object OdeLock = new Object(); |
491 | 491 | ||
492 | private bool _worldInitialized = false; | ||
493 | |||
492 | public IMesher mesher; | 494 | public IMesher mesher; |
493 | 495 | ||
494 | private IConfigSource m_config; | 496 | private IConfigSource m_config; |
@@ -875,6 +877,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
875 | staticPrimspace[i, j] = IntPtr.Zero; | 877 | staticPrimspace[i, j] = IntPtr.Zero; |
876 | } | 878 | } |
877 | } | 879 | } |
880 | |||
881 | _worldInitialized = true; | ||
878 | } | 882 | } |
879 | 883 | ||
880 | // internal void waitForSpaceUnlock(IntPtr space) | 884 | // internal void waitForSpaceUnlock(IntPtr space) |
@@ -2896,6 +2900,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
2896 | /// <returns>The number of frames simulated over that period.</returns> | 2900 | /// <returns>The number of frames simulated over that period.</returns> |
2897 | public override float Simulate(float timeStep) | 2901 | public override float Simulate(float timeStep) |
2898 | { | 2902 | { |
2903 | if (!_worldInitialized) return 11f; | ||
2904 | |||
2899 | int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; | 2905 | int startFrameTick = CollectStats ? Util.EnvironmentTickCount() : 0; |
2900 | int tempTick = 0, tempTick2 = 0; | 2906 | int tempTick = 0, tempTick2 = 0; |
2901 | 2907 | ||
@@ -4017,6 +4023,8 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
4017 | 4023 | ||
4018 | public override void Dispose() | 4024 | public override void Dispose() |
4019 | { | 4025 | { |
4026 | _worldInitialized = false; | ||
4027 | |||
4020 | m_rayCastManager.Dispose(); | 4028 | m_rayCastManager.Dispose(); |
4021 | m_rayCastManager = null; | 4029 | m_rayCastManager = null; |
4022 | 4030 | ||
@@ -4037,6 +4045,7 @@ namespace OpenSim.Region.Physics.OdePlugin | |||
4037 | d.WorldDestroy(world); | 4045 | d.WorldDestroy(world); |
4038 | //d.CloseODE(); | 4046 | //d.CloseODE(); |
4039 | } | 4047 | } |
4048 | |||
4040 | } | 4049 | } |
4041 | 4050 | ||
4042 | public override Dictionary<uint, float> GetTopColliders() | 4051 | public override Dictionary<uint, float> GetTopColliders() |