diff options
author | Robert Adams | 2012-11-01 10:23:37 -0700 |
---|---|---|
committer | Robert Adams | 2012-11-03 21:15:14 -0700 |
commit | 39c02dcc8c537d5989238ec97c876e033895a8a9 (patch) | |
tree | b23392da13d4ff36ba3258d0239ea928584a6a99 /OpenSim | |
parent | BulletSim: rename BSBody and BSShape to PhysBody and PhysShape. Add skeleton ... (diff) | |
download | opensim-SC-39c02dcc8c537d5989238ec97c876e033895a8a9.zip opensim-SC-39c02dcc8c537d5989238ec97c876e033895a8a9.tar.gz opensim-SC-39c02dcc8c537d5989238ec97c876e033895a8a9.tar.bz2 opensim-SC-39c02dcc8c537d5989238ec97c876e033895a8a9.tar.xz |
BulletSim: Remove use of shapeData in ShapeCollection and rely on the available BSPhysObject varaiables. Fix line endings in BSLinksetCompound.
Diffstat (limited to 'OpenSim')
7 files changed, 256 insertions, 266 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index 8c7061d..2a634b9 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -99,26 +99,12 @@ public sealed class BSCharacter : BSPhysObject | |||
99 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", | 99 | DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}", |
100 | LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw); | 100 | LocalID, _size, Scale, _avatarDensity, _avatarVolume, MassRaw); |
101 | 101 | ||
102 | ShapeData shapeData = new ShapeData(); | ||
103 | shapeData.ID = LocalID; | ||
104 | shapeData.Type = ShapeData.PhysicsShapeType.SHAPE_AVATAR; | ||
105 | shapeData.Position = _position; | ||
106 | shapeData.Rotation = _orientation; | ||
107 | shapeData.Velocity = _velocity; | ||
108 | shapeData.Size = Scale; // capsule is a native shape but scale is not just <1,1,1> | ||
109 | shapeData.Scale = Scale; | ||
110 | shapeData.Mass = _mass; | ||
111 | shapeData.Buoyancy = _buoyancy; | ||
112 | shapeData.Static = ShapeData.numericFalse; | ||
113 | shapeData.Friction = PhysicsScene.Params.avatarStandingFriction; | ||
114 | shapeData.Restitution = PhysicsScene.Params.avatarRestitution; | ||
115 | |||
116 | // do actual create at taint time | 102 | // do actual create at taint time |
117 | PhysicsScene.TaintedObject("BSCharacter.create", delegate() | 103 | PhysicsScene.TaintedObject("BSCharacter.create", delegate() |
118 | { | 104 | { |
119 | DetailLog("{0},BSCharacter.create,taint", LocalID); | 105 | DetailLog("{0},BSCharacter.create,taint", LocalID); |
120 | // New body and shape into BSBody and BSShape | 106 | // New body and shape into BSBody and BSShape |
121 | PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, shapeData, null, null, null); | 107 | PhysicsScene.Shapes.GetBodyAndShape(true, PhysicsScene.World, this, null, null); |
122 | 108 | ||
123 | SetPhysicalProperties(); | 109 | SetPhysicalProperties(); |
124 | }); | 110 | }); |
@@ -212,6 +198,9 @@ public sealed class BSCharacter : BSPhysObject | |||
212 | { | 198 | { |
213 | set { BaseShape = value; } | 199 | set { BaseShape = value; } |
214 | } | 200 | } |
201 | // I want the physics engine to make an avatar capsule | ||
202 | public override ShapeData.PhysicsShapeType PreferredPhysicalShape | ||
203 | { get { return ShapeData.PhysicsShapeType.SHAPE_AVATAR; } } | ||
215 | 204 | ||
216 | public override bool Grabbed { | 205 | public override bool Grabbed { |
217 | set { _grabbed = value; } | 206 | set { _grabbed = value; } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs index 525ec28..f56851f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinkset.cs | |||
@@ -68,6 +68,11 @@ public abstract class BSLinkset | |||
68 | // to the physical representation is done via the tainting mechenism. | 68 | // to the physical representation is done via the tainting mechenism. |
69 | protected object m_linksetActivityLock = new Object(); | 69 | protected object m_linksetActivityLock = new Object(); |
70 | 70 | ||
71 | // Some linksets have a preferred physical shape. | ||
72 | // Returns SHAPE_UNKNOWN if there is no preference. | ||
73 | public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape | ||
74 | { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } | ||
75 | |||
71 | // We keep the prim's mass in the linkset structure since it could be dependent on other prims | 76 | // We keep the prim's mass in the linkset structure since it could be dependent on other prims |
72 | protected float m_mass; | 77 | protected float m_mass; |
73 | public float LinksetMass | 78 | public float LinksetMass |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs index 1c569b5..638fae1 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSLinksetCompound.cs | |||
@@ -1,173 +1,176 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) Contributors, http://opensimulator.org/ | 2 | * Copyright (c) Contributors, http://opensimulator.org/ |
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | 3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. |
4 | * | 4 | * |
5 | * Redistribution and use in source and binary forms, with or without | 5 | * Redistribution and use in source and binary forms, with or without |
6 | * modification, are permitted provided that the following conditions are met: | 6 | * modification, are permitted provided that the following conditions are met: |
7 | * * Redistributions of source code must retain the above copyright | 7 | * * Redistributions of source code must retain the above copyright |
8 | * notice, this list of conditions and the following disclaimer. | 8 | * notice, this list of conditions and the following disclaimer. |
9 | * * Redistributions in binary form must reproduce the above copyrightD | 9 | * * Redistributions in binary form must reproduce the above copyrightD |
10 | * notice, this list of conditions and the following disclaimer in the | 10 | * notice, this list of conditions and the following disclaimer in the |
11 | * documentation and/or other materials provided with the distribution. | 11 | * documentation and/or other materials provided with the distribution. |
12 | * * Neither the name of the OpenSimulator Project nor the | 12 | * * Neither the name of the OpenSimulator Project nor the |
13 | * names of its contributors may be used to endorse or promote products | 13 | * names of its contributors may be used to endorse or promote products |
14 | * derived from this software without specific prior written permission. | 14 | * derived from this software without specific prior written permission. |
15 | * | 15 | * |
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | 16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY |
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | 17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | 18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | 19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY |
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | 20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | 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 | 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 | 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 | 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. | 25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 | */ | 26 | */ |
27 | using System; | 27 | using System; |
28 | using System.Collections.Generic; | 28 | using System.Collections.Generic; |
29 | using System.Text; | 29 | using System.Text; |
30 | 30 | ||
31 | using OMV = OpenMetaverse; | 31 | using OMV = OpenMetaverse; |
32 | 32 | ||
33 | namespace OpenSim.Region.Physics.BulletSPlugin | 33 | namespace OpenSim.Region.Physics.BulletSPlugin |
34 | { | 34 | { |
35 | public sealed class BSLinksetCompound : BSLinkset | 35 | public sealed class BSLinksetCompound : BSLinkset |
36 | { | 36 | { |
37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; | 37 | // private static string LogHeader = "[BULLETSIM LINKSET CONSTRAINTS]"; |
38 | 38 | ||
39 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) | 39 | public BSLinksetCompound(BSScene scene, BSPhysObject parent) |
40 | { | 40 | { |
41 | base.Initialize(scene, parent); | 41 | base.Initialize(scene, parent); |
42 | } | 42 | } |
43 | 43 | ||
44 | // When physical properties are changed the linkset needs to recalculate | 44 | // When physical properties are changed the linkset needs to recalculate |
45 | // its internal properties. | 45 | // its internal properties. |
46 | // This is queued in the 'post taint' queue so the | 46 | // This is queued in the 'post taint' queue so the |
47 | // refresh will happen once after all the other taints are applied. | 47 | // refresh will happen once after all the other taints are applied. |
48 | public override void Refresh(BSPhysObject requestor) | 48 | public override void Refresh(BSPhysObject requestor) |
49 | { | 49 | { |
50 | // Queue to happen after all the other taint processing | 50 | // Queue to happen after all the other taint processing |
51 | PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() | 51 | PhysicsScene.PostTaintObject("BSLinksetcompound.Refresh", requestor.LocalID, delegate() |
52 | { | 52 | { |
53 | if (HasAnyChildren && IsRoot(requestor)) | 53 | if (HasAnyChildren && IsRoot(requestor)) |
54 | RecomputeLinksetCompound(); | 54 | RecomputeLinksetCompound(); |
55 | }); | 55 | }); |
56 | } | 56 | } |
57 | 57 | ||
58 | // The object is going dynamic (physical). Do any setup necessary | 58 | // The object is going dynamic (physical). Do any setup necessary |
59 | // for a dynamic linkset. | 59 | // for a dynamic linkset. |
60 | // Only the state of the passed object can be modified. The rest of the linkset | 60 | // Only the state of the passed object can be modified. The rest of the linkset |
61 | // has not yet been fully constructed. | 61 | // has not yet been fully constructed. |
62 | // Return 'true' if any properties updated on the passed object. | 62 | // Return 'true' if any properties updated on the passed object. |
63 | // Called at taint-time! | 63 | // Called at taint-time! |
64 | public override bool MakeDynamic(BSPhysObject child) | 64 | public override bool MakeDynamic(BSPhysObject child) |
65 | { | 65 | { |
66 | // What is done for each object in BSPrim is what we want. | 66 | // What is done for each object in BSPrim is what we want. |
67 | return false; | 67 | return false; |
68 | } | 68 | } |
69 | 69 | ||
70 | // The object is going static (non-physical). Do any setup necessary for a static linkset. | 70 | // The object is going static (non-physical). Do any setup necessary for a static linkset. |
71 | // Return 'true' if any properties updated on the passed object. | 71 | // Return 'true' if any properties updated on the passed object. |
72 | // This doesn't normally happen -- OpenSim removes the objects from the physical | 72 | // This doesn't normally happen -- OpenSim removes the objects from the physical |
73 | // world if it is a static linkset. | 73 | // world if it is a static linkset. |
74 | // Called at taint-time! | 74 | // Called at taint-time! |
75 | public override bool MakeStatic(BSPhysObject child) | 75 | public override bool MakeStatic(BSPhysObject child) |
76 | { | 76 | { |
77 | // What is done for each object in BSPrim is what we want. | 77 | // What is done for each object in BSPrim is what we want. |
78 | return false; | 78 | return false; |
79 | } | 79 | } |
80 | 80 | ||
81 | // Called at taint-time!! | 81 | // Called at taint-time!! |
82 | public override void UpdateProperties(BSPhysObject updated) | 82 | public override void UpdateProperties(BSPhysObject updated) |
83 | { | 83 | { |
84 | // Nothing to do for constraints on property updates | 84 | // Nothing to do for constraints on property updates |
85 | } | 85 | } |
86 | 86 | ||
87 | // Routine called when rebuilding the body of some member of the linkset. | 87 | // Routine called when rebuilding the body of some member of the linkset. |
88 | // Destroy all the constraints have have been made to root and set | 88 | // Destroy all the constraints have have been made to root and set |
89 | // up to rebuild the constraints before the next simulation step. | 89 | // up to rebuild the constraints before the next simulation step. |
90 | // Returns 'true' of something was actually removed and would need restoring | 90 | // Returns 'true' of something was actually removed and would need restoring |
91 | // Called at taint-time!! | 91 | // Called at taint-time!! |
92 | public override bool RemoveBodyDependencies(BSPrim child) | 92 | public override bool RemoveBodyDependencies(BSPrim child) |
93 | { | 93 | { |
94 | bool ret = false; | 94 | bool ret = false; |
95 | 95 | ||
96 | DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", | 96 | DetailLog("{0},BSLinksetcompound.RemoveBodyDependencies,removeChildrenForRoot,rID={1},rBody={2}", |
97 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); | 97 | child.LocalID, LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X")); |
98 | 98 | ||
99 | // Cause the current shape to be freed and the new one to be built. | 99 | // Cause the current shape to be freed and the new one to be built. |
100 | Refresh(LinksetRoot); | 100 | Refresh(LinksetRoot); |
101 | 101 | ||
102 | return ret; | 102 | return ret; |
103 | } | 103 | } |
104 | 104 | ||
105 | // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', | 105 | // Companion to RemoveBodyDependencies(). If RemoveBodyDependencies() returns 'true', |
106 | // this routine will restore the removed constraints. | 106 | // this routine will restore the removed constraints. |
107 | // Called at taint-time!! | 107 | // Called at taint-time!! |
108 | public override void RestoreBodyDependencies(BSPrim child) | 108 | public override void RestoreBodyDependencies(BSPrim child) |
109 | { | 109 | { |
110 | // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. | 110 | // The Refresh operation queued by RemoveBodyDependencies() will build any missing constraints. |
111 | } | 111 | } |
112 | 112 | ||
113 | // ================================================================ | 113 | // ================================================================ |
114 | 114 | ||
115 | // Add a new child to the linkset. | 115 | // Add a new child to the linkset. |
116 | // Called while LinkActivity is locked. | 116 | // Called while LinkActivity is locked. |
117 | protected override void AddChildToLinkset(BSPhysObject child) | 117 | protected override void AddChildToLinkset(BSPhysObject child) |
118 | { | 118 | { |
119 | if (!HasChild(child)) | 119 | if (!HasChild(child)) |
120 | { | 120 | { |
121 | m_children.Add(child); | 121 | m_children.Add(child); |
122 | 122 | ||
123 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); | 123 | DetailLog("{0},BSLinksetCompound.AddChildToLinkset,call,child={1}", LinksetRoot.LocalID, child.LocalID); |
124 | 124 | ||
125 | // Cause constraints and assorted properties to be recomputed before the next simulation step. | 125 | // Cause constraints and assorted properties to be recomputed before the next simulation step. |
126 | Refresh(LinksetRoot); | 126 | Refresh(LinksetRoot); |
127 | } | 127 | } |
128 | return; | 128 | return; |
129 | } | 129 | } |
130 | 130 | ||
131 | // Remove the specified child from the linkset. | 131 | // Remove the specified child from the linkset. |
132 | // Safe to call even if the child is not really in my linkset. | 132 | // Safe to call even if the child is not really in my linkset. |
133 | protected override void RemoveChildFromLinkset(BSPhysObject child) | 133 | protected override void RemoveChildFromLinkset(BSPhysObject child) |
134 | { | 134 | { |
135 | if (m_children.Remove(child)) | 135 | if (m_children.Remove(child)) |
136 | { | 136 | { |
137 | DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", | 137 | DetailLog("{0},BSLinksetCompound.RemoveChildFromLinkset,call,rID={1},rBody={2},cID={3},cBody={4}", |
138 | child.LocalID, | 138 | child.LocalID, |
139 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), | 139 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), |
140 | child.LocalID, child.PhysBody.ptr.ToString("X")); | 140 | child.LocalID, child.PhysBody.ptr.ToString("X")); |
141 | 141 | ||
142 | // See that the linkset parameters are recomputed at the end of the taint time. | 142 | // See that the linkset parameters are recomputed at the end of the taint time. |
143 | Refresh(LinksetRoot); | 143 | Refresh(LinksetRoot); |
144 | } | 144 | } |
145 | else | 145 | else |
146 | { | 146 | { |
147 | // Non-fatal occurance. | 147 | // Non-fatal occurance. |
148 | // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); | 148 | // PhysicsScene.Logger.ErrorFormat("{0}: Asked to remove child from linkset that was not in linkset", LogHeader); |
149 | } | 149 | } |
150 | return; | 150 | return; |
151 | } | 151 | } |
152 | 152 | ||
153 | 153 | ||
154 | // Call each of the constraints that make up this linkset and recompute the | 154 | // Call each of the constraints that make up this linkset and recompute the |
155 | // various transforms and variables. Create constraints of not created yet. | 155 | // various transforms and variables. Create constraints of not created yet. |
156 | // Called before the simulation step to make sure the constraint based linkset | 156 | // Called before the simulation step to make sure the constraint based linkset |
157 | // is all initialized. | 157 | // is all initialized. |
158 | // Called at taint time!! | 158 | // Called at taint time!! |
159 | private void RecomputeLinksetCompound() | 159 | private void RecomputeLinksetCompound() |
160 | { | 160 | { |
161 | float linksetMass = LinksetMass; | 161 | // Release the existing shape |
162 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); | 162 | PhysicsScene.Shapes.DereferenceShape(LinksetRoot.PhysShape, true, null); |
163 | 163 | ||
164 | // DEBUG: see of inter-linkset collisions are causing problems | 164 | float linksetMass = LinksetMass; |
165 | // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, | 165 | LinksetRoot.UpdatePhysicalMassProperties(linksetMass); |
166 | // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); | 166 | |
167 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", | 167 | // DEBUG: see of inter-linkset collisions are causing problems |
168 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); | 168 | // BulletSimAPI.SetCollisionFilterMask2(LinksetRoot.BSBody.ptr, |
169 | 169 | // (uint)CollisionFilterGroups.LinksetFilter, (uint)CollisionFilterGroups.LinksetMask); | |
170 | 170 | DetailLog("{0},BSLinksetCompound.RecomputeLinksetCompound,set,rBody={1},linksetMass={2}", | |
171 | } | 171 | LinksetRoot.LocalID, LinksetRoot.PhysBody.ptr.ToString("X"), linksetMass); |
172 | } | 172 | |
173 | |||
174 | } | ||
175 | } | ||
173 | } \ No newline at end of file | 176 | } \ No newline at end of file |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs index 6220b21..7d91468 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPhysObject.cs | |||
@@ -78,6 +78,10 @@ public abstract class BSPhysObject : PhysicsActor | |||
78 | 78 | ||
79 | // The objects base shape information. Null if not a prim type shape. | 79 | // The objects base shape information. Null if not a prim type shape. |
80 | public PrimitiveBaseShape BaseShape { get; protected set; } | 80 | public PrimitiveBaseShape BaseShape { get; protected set; } |
81 | // Some types of objects have preferred physical representations. | ||
82 | // Returns SHAPE_UNKNOWN if there is no preference. | ||
83 | public virtual ShapeData.PhysicsShapeType PreferredPhysicalShape | ||
84 | { get { return ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; } } | ||
81 | 85 | ||
82 | // When the physical properties are updated, an EntityProperty holds the update values. | 86 | // When the physical properties are updated, an EntityProperty holds the update values. |
83 | // Keep the current and last EntityProperties to enable computation of differences | 87 | // Keep the current and last EntityProperties to enable computation of differences |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs index 8dd48ca..8ce960d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSPrim.cs | |||
@@ -171,6 +171,10 @@ public sealed class BSPrim : BSPhysObject | |||
171 | ForceBodyShapeRebuild(false); | 171 | ForceBodyShapeRebuild(false); |
172 | } | 172 | } |
173 | } | 173 | } |
174 | // Whatever the linkset wants is what I want. | ||
175 | public override ShapeData.PhysicsShapeType PreferredPhysicalShape | ||
176 | { get { return Linkset.PreferredPhysicalShape; } } | ||
177 | |||
174 | public override bool ForceBodyShapeRebuild(bool inTaintTime) | 178 | public override bool ForceBodyShapeRebuild(bool inTaintTime) |
175 | { | 179 | { |
176 | LastAssetBuildFailed = false; | 180 | LastAssetBuildFailed = false; |
@@ -1310,34 +1314,11 @@ public sealed class BSPrim : BSPhysObject | |||
1310 | }// end CalculateMass | 1314 | }// end CalculateMass |
1311 | #endregion Mass Calculation | 1315 | #endregion Mass Calculation |
1312 | 1316 | ||
1313 | // Copy prim's info into the BulletSim shape description structure | ||
1314 | public void FillShapeInfo(out ShapeData shape) | ||
1315 | { | ||
1316 | shape.ID = LocalID; | ||
1317 | shape.Type = ShapeData.PhysicsShapeType.SHAPE_UNKNOWN; | ||
1318 | shape.Position = _position; | ||
1319 | shape.Rotation = _orientation; | ||
1320 | shape.Velocity = _velocity; | ||
1321 | shape.Size = _size; | ||
1322 | shape.Scale = Scale; | ||
1323 | shape.Mass = _isPhysical ? _mass : 0f; | ||
1324 | shape.Buoyancy = _buoyancy; | ||
1325 | shape.HullKey = 0; | ||
1326 | shape.MeshKey = 0; | ||
1327 | shape.Friction = _friction; | ||
1328 | shape.Restitution = _restitution; | ||
1329 | shape.Collidable = (!IsPhantom) ? ShapeData.numericTrue : ShapeData.numericFalse; | ||
1330 | shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue; | ||
1331 | shape.Solid = IsSolid ? ShapeData.numericFalse : ShapeData.numericTrue; | ||
1332 | } | ||
1333 | // Rebuild the geometry and object. | 1317 | // Rebuild the geometry and object. |
1334 | // This is called when the shape changes so we need to recreate the mesh/hull. | 1318 | // This is called when the shape changes so we need to recreate the mesh/hull. |
1335 | // Called at taint-time!!! | 1319 | // Called at taint-time!!! |
1336 | private void CreateGeomAndObject(bool forceRebuild) | 1320 | private void CreateGeomAndObject(bool forceRebuild) |
1337 | { | 1321 | { |
1338 | ShapeData shapeData; | ||
1339 | FillShapeInfo(out shapeData); | ||
1340 | |||
1341 | // If this prim is part of a linkset, we must remove and restore the physical | 1322 | // If this prim is part of a linkset, we must remove and restore the physical |
1342 | // links if the body is rebuilt. | 1323 | // links if the body is rebuilt. |
1343 | bool needToRestoreLinkset = false; | 1324 | bool needToRestoreLinkset = false; |
@@ -1346,8 +1327,7 @@ public sealed class BSPrim : BSPhysObject | |||
1346 | // Updates BSBody and BSShape with the new information. | 1327 | // Updates BSBody and BSShape with the new information. |
1347 | // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. | 1328 | // Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary. |
1348 | // Returns 'true' if either the body or the shape was changed. | 1329 | // Returns 'true' if either the body or the shape was changed. |
1349 | PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, shapeData, BaseShape, | 1330 | PhysicsScene.Shapes.GetBodyAndShape(false, PhysicsScene.World, this, null, delegate(BulletBody dBody) |
1350 | null, delegate(BulletBody dBody) | ||
1351 | { | 1331 | { |
1352 | // Called if the current prim body is about to be destroyed. | 1332 | // Called if the current prim body is about to be destroyed. |
1353 | // Remove all the physical dependencies on the old body. | 1333 | // Remove all the physical dependencies on the old body. |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index a38e650..478924a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -90,7 +90,6 @@ public sealed class BSShapeCollection : IDisposable | |||
90 | // remove the physical constraints before the body is destroyed. | 90 | // remove the physical constraints before the body is destroyed. |
91 | // Called at taint-time!! | 91 | // Called at taint-time!! |
92 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, | 92 | public bool GetBodyAndShape(bool forceRebuild, BulletSim sim, BSPhysObject prim, |
93 | ShapeData shapeData, PrimitiveBaseShape pbs, | ||
94 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) | 93 | ShapeDestructionCallback shapeCallback, BodyDestructionCallback bodyCallback) |
95 | { | 94 | { |
96 | bool ret = false; | 95 | bool ret = false; |
@@ -101,12 +100,12 @@ public sealed class BSShapeCollection : IDisposable | |||
101 | // Do we have the correct geometry for this type of object? | 100 | // Do we have the correct geometry for this type of object? |
102 | // Updates prim.BSShape with information/pointers to shape. | 101 | // Updates prim.BSShape with information/pointers to shape. |
103 | // CreateGeom returns 'true' of BSShape as changed to a new shape. | 102 | // CreateGeom returns 'true' of BSShape as changed to a new shape. |
104 | bool newGeom = CreateGeom(forceRebuild, prim, shapeData, pbs, shapeCallback); | 103 | bool newGeom = CreateGeom(forceRebuild, prim, shapeCallback); |
105 | // If we had to select a new shape geometry for the object, | 104 | // If we had to select a new shape geometry for the object, |
106 | // rebuild the body around it. | 105 | // rebuild the body around it. |
107 | // Updates prim.BSBody with information/pointers to requested body | 106 | // Updates prim.BSBody with information/pointers to requested body |
108 | bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, | 107 | bool newBody = CreateBody((newGeom || forceRebuild), prim, PhysicsScene.World, |
109 | prim.PhysShape, shapeData, bodyCallback); | 108 | prim.PhysShape, bodyCallback); |
110 | ret = newGeom || newBody; | 109 | ret = newGeom || newBody; |
111 | } | 110 | } |
112 | DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", | 111 | DetailLog("{0},BSShapeCollection.GetBodyAndShape,taintExit,force={1},ret={2},body={3},shape={4}", |
@@ -261,6 +260,9 @@ public sealed class BSShapeCollection : IDisposable | |||
261 | case ShapeData.PhysicsShapeType.SHAPE_MESH: | 260 | case ShapeData.PhysicsShapeType.SHAPE_MESH: |
262 | DereferenceMesh(shape, shapeCallback); | 261 | DereferenceMesh(shape, shapeCallback); |
263 | break; | 262 | break; |
263 | case ShapeData.PhysicsShapeType.SHAPE_COMPOUND: | ||
264 | DereferenceCompound(shape, shapeCallback); | ||
265 | break; | ||
264 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: | 266 | case ShapeData.PhysicsShapeType.SHAPE_UNKNOWN: |
265 | break; | 267 | break; |
266 | default: | 268 | default: |
@@ -317,6 +319,13 @@ public sealed class BSShapeCollection : IDisposable | |||
317 | } | 319 | } |
318 | } | 320 | } |
319 | 321 | ||
322 | // Remove a reference to a compound shape. | ||
323 | // Called at taint-time. | ||
324 | private void DereferenceCompound(BulletShape shape, ShapeDestructionCallback shapeCallback) | ||
325 | { | ||
326 | // Compound shape is made of a bunch of meshes and natives. | ||
327 | } | ||
328 | |||
320 | // Create the geometry information in Bullet for later use. | 329 | // Create the geometry information in Bullet for later use. |
321 | // The objects needs a hull if it's physical otherwise a mesh is enough. | 330 | // The objects needs a hull if it's physical otherwise a mesh is enough. |
322 | // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, | 331 | // if 'forceRebuild' is true, the geometry is unconditionally rebuilt. For meshes and hulls, |
@@ -325,17 +334,17 @@ public sealed class BSShapeCollection : IDisposable | |||
325 | // Info in prim.BSShape is updated to the new shape. | 334 | // Info in prim.BSShape is updated to the new shape. |
326 | // Returns 'true' if the geometry was rebuilt. | 335 | // Returns 'true' if the geometry was rebuilt. |
327 | // Called at taint-time! | 336 | // Called at taint-time! |
328 | private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeData shapeData, | 337 | private bool CreateGeom(bool forceRebuild, BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
329 | PrimitiveBaseShape pbs, ShapeDestructionCallback shapeCallback) | ||
330 | { | 338 | { |
331 | bool ret = false; | 339 | bool ret = false; |
332 | bool haveShape = false; | 340 | bool haveShape = false; |
333 | bool nativeShapePossible = true; | 341 | bool nativeShapePossible = true; |
342 | PrimitiveBaseShape pbs = prim.BaseShape; | ||
334 | 343 | ||
335 | if (shapeData.Type == ShapeData.PhysicsShapeType.SHAPE_AVATAR) | 344 | if (prim.PreferredPhysicalShape == ShapeData.PhysicsShapeType.SHAPE_AVATAR) |
336 | { | 345 | { |
337 | // an avatar capsule is close to a native shape (it is not shared) | 346 | // an avatar capsule is close to a native shape (it is not shared) |
338 | ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_AVATAR, | 347 | ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_AVATAR, |
339 | ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); | 348 | ShapeData.FixedShapeKey.KEY_CAPSULE, shapeCallback); |
340 | DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); | 349 | DetailLog("{0},BSShapeCollection.CreateGeom,avatarCapsule,shape={1}", prim.LocalID, prim.PhysShape); |
341 | ret = true; | 350 | ret = true; |
@@ -359,11 +368,11 @@ public sealed class BSShapeCollection : IDisposable | |||
359 | { | 368 | { |
360 | haveShape = true; | 369 | haveShape = true; |
361 | if (forceRebuild | 370 | if (forceRebuild |
362 | || prim.Scale != shapeData.Size | 371 | || prim.Scale != prim.Size |
363 | || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE | 372 | || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_SPHERE |
364 | ) | 373 | ) |
365 | { | 374 | { |
366 | ret = GetReferenceToNativeShape(prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_SPHERE, | 375 | ret = GetReferenceToNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_SPHERE, |
367 | ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); | 376 | ShapeData.FixedShapeKey.KEY_SPHERE, shapeCallback); |
368 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", | 377 | DetailLog("{0},BSShapeCollection.CreateGeom,sphere,force={1},shape={2}", |
369 | prim.LocalID, forceRebuild, prim.PhysShape); | 378 | prim.LocalID, forceRebuild, prim.PhysShape); |
@@ -373,11 +382,11 @@ public sealed class BSShapeCollection : IDisposable | |||
373 | { | 382 | { |
374 | haveShape = true; | 383 | haveShape = true; |
375 | if (forceRebuild | 384 | if (forceRebuild |
376 | || prim.Scale != shapeData.Size | 385 | || prim.Scale != prim.Size |
377 | || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX | 386 | || prim.PhysShape.type != ShapeData.PhysicsShapeType.SHAPE_BOX |
378 | ) | 387 | ) |
379 | { | 388 | { |
380 | ret = GetReferenceToNativeShape( prim, shapeData, ShapeData.PhysicsShapeType.SHAPE_BOX, | 389 | ret = GetReferenceToNativeShape( prim, ShapeData.PhysicsShapeType.SHAPE_BOX, |
381 | ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); | 390 | ShapeData.FixedShapeKey.KEY_BOX, shapeCallback); |
382 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", | 391 | DetailLog("{0},BSShapeCollection.CreateGeom,box,force={1},shape={2}", |
383 | prim.LocalID, forceRebuild, prim.PhysShape); | 392 | prim.LocalID, forceRebuild, prim.PhysShape); |
@@ -392,15 +401,15 @@ public sealed class BSShapeCollection : IDisposable | |||
392 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) | 401 | if (prim.IsPhysical && PhysicsScene.ShouldUseHullsForPhysicalObjects) |
393 | { | 402 | { |
394 | // Update prim.BSShape to reference a hull of this shape. | 403 | // Update prim.BSShape to reference a hull of this shape. |
395 | ret = GetReferenceToHull(prim, shapeData, pbs, shapeCallback); | 404 | ret = GetReferenceToHull(prim,shapeCallback); |
396 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", | 405 | DetailLog("{0},BSShapeCollection.CreateGeom,hull,shape={1},key={2}", |
397 | shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 406 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
398 | } | 407 | } |
399 | else | 408 | else |
400 | { | 409 | { |
401 | ret = GetReferenceToMesh(prim, shapeData, pbs, shapeCallback); | 410 | ret = GetReferenceToMesh(prim, shapeCallback); |
402 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", | 411 | DetailLog("{0},BSShapeCollection.CreateGeom,mesh,shape={1},key={2}", |
403 | shapeData.ID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); | 412 | prim.LocalID, prim.PhysShape, prim.PhysShape.shapeKey.ToString("X")); |
404 | } | 413 | } |
405 | } | 414 | } |
406 | return ret; | 415 | return ret; |
@@ -408,44 +417,45 @@ public sealed class BSShapeCollection : IDisposable | |||
408 | 417 | ||
409 | // Creates a native shape and assignes it to prim.BSShape. | 418 | // Creates a native shape and assignes it to prim.BSShape. |
410 | // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). | 419 | // "Native" shapes are never shared. they are created here and destroyed in DereferenceShape(). |
411 | private bool GetReferenceToNativeShape(BSPhysObject prim, ShapeData shapeData, | 420 | private bool GetReferenceToNativeShape(BSPhysObject prim, |
412 | ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, | 421 | ShapeData.PhysicsShapeType shapeType, ShapeData.FixedShapeKey shapeKey, |
413 | ShapeDestructionCallback shapeCallback) | 422 | ShapeDestructionCallback shapeCallback) |
414 | { | 423 | { |
415 | // release any previous shape | 424 | // release any previous shape |
416 | DereferenceShape(prim.PhysShape, true, shapeCallback); | 425 | DereferenceShape(prim.PhysShape, true, shapeCallback); |
417 | 426 | ||
418 | shapeData.Type = shapeType; | ||
419 | // Bullet native objects are scaled by the Bullet engine so pass the size in | 427 | // Bullet native objects are scaled by the Bullet engine so pass the size in |
420 | prim.Scale = shapeData.Size; | 428 | prim.Scale = prim.Size; |
421 | shapeData.Scale = shapeData.Size; | ||
422 | 429 | ||
423 | BulletShape newShape = BuildPhysicalNativeShape(shapeType, shapeData, shapeKey); | 430 | BulletShape newShape = BuildPhysicalNativeShape(prim, shapeType, shapeKey); |
424 | 431 | ||
425 | // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. | 432 | // Don't need to do a 'ReferenceShape()' here because native shapes are not shared. |
426 | DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", | 433 | DetailLog("{0},BSShapeCollection.AddNativeShapeToPrim,create,newshape={1},scale={2}", |
427 | shapeData.ID, newShape, shapeData.Scale); | 434 | prim.LocalID, newShape, prim.Scale); |
428 | 435 | ||
429 | prim.PhysShape = newShape; | 436 | prim.PhysShape = newShape; |
430 | return true; | 437 | return true; |
431 | } | 438 | } |
432 | 439 | ||
433 | private BulletShape BuildPhysicalNativeShape(ShapeData.PhysicsShapeType shapeType, | 440 | private BulletShape BuildPhysicalNativeShape(BSPhysObject prim, ShapeData.PhysicsShapeType shapeType, |
434 | ShapeData shapeData, ShapeData.FixedShapeKey shapeKey) | 441 | ShapeData.FixedShapeKey shapeKey) |
435 | { | 442 | { |
436 | BulletShape newShape; | 443 | BulletShape newShape; |
437 | // Need to make sure the passed shape information is for the native type. | 444 | // Need to make sure the passed shape information is for the native type. |
438 | ShapeData nativeShapeData = shapeData; | 445 | ShapeData nativeShapeData = new ShapeData(); |
439 | nativeShapeData.Type = shapeType; | 446 | nativeShapeData.Type = shapeType; |
447 | nativeShapeData.ID = prim.LocalID; | ||
448 | nativeShapeData.Scale = prim.Scale; | ||
449 | nativeShapeData.Size = prim.Scale; | ||
440 | nativeShapeData.MeshKey = (ulong)shapeKey; | 450 | nativeShapeData.MeshKey = (ulong)shapeKey; |
441 | nativeShapeData.HullKey = (ulong)shapeKey; | 451 | nativeShapeData.HullKey = (ulong)shapeKey; |
442 | 452 | ||
443 | if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) | 453 | if (shapeType == ShapeData.PhysicsShapeType.SHAPE_AVATAR) |
444 | { | 454 | { |
445 | newShape = new BulletShape( | 455 | newShape = new BulletShape( |
446 | BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, nativeShapeData.Scale) | 456 | BulletSimAPI.BuildCapsuleShape2(PhysicsScene.World.ptr, 1f, 1f, prim.Scale) |
447 | , shapeType); | 457 | , shapeType); |
448 | DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", nativeShapeData.ID, nativeShapeData.Scale); | 458 | DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); |
449 | } | 459 | } |
450 | else | 460 | else |
451 | { | 461 | { |
@@ -454,7 +464,7 @@ public sealed class BSShapeCollection : IDisposable | |||
454 | if (newShape.ptr == IntPtr.Zero) | 464 | if (newShape.ptr == IntPtr.Zero) |
455 | { | 465 | { |
456 | PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", | 466 | PhysicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", |
457 | LogHeader, nativeShapeData.ID, nativeShapeData.Type); | 467 | LogHeader, prim.LocalID, shapeType); |
458 | } | 468 | } |
459 | newShape.shapeKey = (System.UInt64)shapeKey; | 469 | newShape.shapeKey = (System.UInt64)shapeKey; |
460 | newShape.isNativeShape = true; | 470 | newShape.isNativeShape = true; |
@@ -466,13 +476,12 @@ public sealed class BSShapeCollection : IDisposable | |||
466 | // Dereferences previous shape in BSShape and adds a reference for this new shape. | 476 | // Dereferences previous shape in BSShape and adds a reference for this new shape. |
467 | // Returns 'true' of a mesh was actually built. Otherwise . | 477 | // Returns 'true' of a mesh was actually built. Otherwise . |
468 | // Called at taint-time! | 478 | // Called at taint-time! |
469 | private bool GetReferenceToMesh(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs, | 479 | private bool GetReferenceToMesh(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
470 | ShapeDestructionCallback shapeCallback) | ||
471 | { | 480 | { |
472 | BulletShape newShape = new BulletShape(IntPtr.Zero); | 481 | BulletShape newShape = new BulletShape(IntPtr.Zero); |
473 | 482 | ||
474 | float lod; | 483 | float lod; |
475 | System.UInt64 newMeshKey = ComputeShapeKey(shapeData, pbs, out lod); | 484 | System.UInt64 newMeshKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
476 | 485 | ||
477 | // if this new shape is the same as last time, don't recreate the mesh | 486 | // if this new shape is the same as last time, don't recreate the mesh |
478 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) | 487 | if (newMeshKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_MESH) |
@@ -484,9 +493,9 @@ public sealed class BSShapeCollection : IDisposable | |||
484 | // Since we're recreating new, get rid of the reference to the previous shape | 493 | // Since we're recreating new, get rid of the reference to the previous shape |
485 | DereferenceShape(prim.PhysShape, true, shapeCallback); | 494 | DereferenceShape(prim.PhysShape, true, shapeCallback); |
486 | 495 | ||
487 | newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, pbs, shapeData.Size, lod); | 496 | newShape = CreatePhysicalMesh(prim.PhysObjectName, newMeshKey, prim.BaseShape, prim.Size, lod); |
488 | // Take evasive action if the mesh was not constructed. | 497 | // Take evasive action if the mesh was not constructed. |
489 | newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs); | 498 | newShape = VerifyMeshCreated(newShape, prim); |
490 | 499 | ||
491 | ReferenceShape(newShape); | 500 | ReferenceShape(newShape); |
492 | 501 | ||
@@ -541,13 +550,12 @@ public sealed class BSShapeCollection : IDisposable | |||
541 | 550 | ||
542 | // See that hull shape exists in the physical world and update prim.BSShape. | 551 | // See that hull shape exists in the physical world and update prim.BSShape. |
543 | // We could be creating the hull because scale changed or whatever. | 552 | // We could be creating the hull because scale changed or whatever. |
544 | private bool GetReferenceToHull(BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs, | 553 | private bool GetReferenceToHull(BSPhysObject prim, ShapeDestructionCallback shapeCallback) |
545 | ShapeDestructionCallback shapeCallback) | ||
546 | { | 554 | { |
547 | BulletShape newShape; | 555 | BulletShape newShape; |
548 | 556 | ||
549 | float lod; | 557 | float lod; |
550 | System.UInt64 newHullKey = ComputeShapeKey(shapeData, pbs, out lod); | 558 | System.UInt64 newHullKey = ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
551 | 559 | ||
552 | // if the hull hasn't changed, don't rebuild it | 560 | // if the hull hasn't changed, don't rebuild it |
553 | if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) | 561 | if (newHullKey == prim.PhysShape.shapeKey && prim.PhysShape.type == ShapeData.PhysicsShapeType.SHAPE_HULL) |
@@ -559,8 +567,8 @@ public sealed class BSShapeCollection : IDisposable | |||
559 | // Remove usage of the previous shape. | 567 | // Remove usage of the previous shape. |
560 | DereferenceShape(prim.PhysShape, true, shapeCallback); | 568 | DereferenceShape(prim.PhysShape, true, shapeCallback); |
561 | 569 | ||
562 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, pbs, shapeData.Size, lod); | 570 | newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod); |
563 | newShape = VerifyMeshCreated(newShape, prim, shapeData, pbs); | 571 | newShape = VerifyMeshCreated(newShape, prim); |
564 | 572 | ||
565 | ReferenceShape(newShape); | 573 | ReferenceShape(newShape); |
566 | 574 | ||
@@ -687,7 +695,7 @@ public sealed class BSShapeCollection : IDisposable | |||
687 | 695 | ||
688 | // Create a hash of all the shape parameters to be used as a key | 696 | // Create a hash of all the shape parameters to be used as a key |
689 | // for this particular shape. | 697 | // for this particular shape. |
690 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs, out float retLod) | 698 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) |
691 | { | 699 | { |
692 | // level of detail based on size and type of the object | 700 | // level of detail based on size and type of the object |
693 | float lod = PhysicsScene.MeshLOD; | 701 | float lod = PhysicsScene.MeshLOD; |
@@ -695,40 +703,40 @@ public sealed class BSShapeCollection : IDisposable | |||
695 | lod = PhysicsScene.SculptLOD; | 703 | lod = PhysicsScene.SculptLOD; |
696 | 704 | ||
697 | // Mega prims usually get more detail because one can interact with shape approximations at this size. | 705 | // Mega prims usually get more detail because one can interact with shape approximations at this size. |
698 | float maxAxis = Math.Max(shapeData.Size.X, Math.Max(shapeData.Size.Y, shapeData.Size.Z)); | 706 | float maxAxis = Math.Max(size.X, Math.Max(size.Y, size.Z)); |
699 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) | 707 | if (maxAxis > PhysicsScene.MeshMegaPrimThreshold) |
700 | lod = PhysicsScene.MeshMegaPrimLOD; | 708 | lod = PhysicsScene.MeshMegaPrimLOD; |
701 | 709 | ||
702 | retLod = lod; | 710 | retLod = lod; |
703 | return pbs.GetMeshKey(shapeData.Size, lod); | 711 | return pbs.GetMeshKey(size, lod); |
704 | } | 712 | } |
705 | // For those who don't want the LOD | 713 | // For those who don't want the LOD |
706 | private System.UInt64 ComputeShapeKey(ShapeData shapeData, PrimitiveBaseShape pbs) | 714 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) |
707 | { | 715 | { |
708 | float lod; | 716 | float lod; |
709 | return ComputeShapeKey(shapeData, pbs, out lod); | 717 | return ComputeShapeKey(size, pbs, out lod); |
710 | } | 718 | } |
711 | 719 | ||
712 | // The creation of a mesh or hull can fail if an underlying asset is not available. | 720 | // The creation of a mesh or hull can fail if an underlying asset is not available. |
713 | // There are two cases: 1) the asset is not in the cache and it needs to be fetched; | 721 | // There are two cases: 1) the asset is not in the cache and it needs to be fetched; |
714 | // and 2) the asset cannot be converted (like decompressing JPEG2000s). | 722 | // and 2) the asset cannot be converted (like failed decompression of JPEG2000s). |
715 | // The first case causes the asset to be fetched. The second case just requires | 723 | // The first case causes the asset to be fetched. The second case requires |
716 | // us to not loop forever. | 724 | // us to not loop forever. |
717 | // Called after creating a physical mesh or hull. If the physical shape was created, | 725 | // Called after creating a physical mesh or hull. If the physical shape was created, |
718 | // just return. | 726 | // just return. |
719 | private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim, ShapeData shapeData, PrimitiveBaseShape pbs) | 727 | private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) |
720 | { | 728 | { |
721 | // If the shape was successfully created, nothing more to do | 729 | // If the shape was successfully created, nothing more to do |
722 | if (newShape.ptr != IntPtr.Zero) | 730 | if (newShape.ptr != IntPtr.Zero) |
723 | return newShape; | 731 | return newShape; |
724 | 732 | ||
725 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset | 733 | // If this mesh has an underlying asset and we have not failed getting it before, fetch the asset |
726 | if (pbs.SculptEntry && !prim.LastAssetBuildFailed && pbs.SculptTexture != OMV.UUID.Zero) | 734 | if (prim.BaseShape.SculptEntry && !prim.LastAssetBuildFailed && prim.BaseShape.SculptTexture != OMV.UUID.Zero) |
727 | { | 735 | { |
728 | prim.LastAssetBuildFailed = true; | 736 | prim.LastAssetBuildFailed = true; |
729 | BSPhysObject xprim = prim; | 737 | BSPhysObject xprim = prim; |
730 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", | 738 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset,lID={1},lastFailed={2}", |
731 | LogHeader, shapeData.ID.ToString("X"), prim.LastAssetBuildFailed); | 739 | LogHeader, prim.LocalID, prim.LastAssetBuildFailed); |
732 | Util.FireAndForget(delegate | 740 | Util.FireAndForget(delegate |
733 | { | 741 | { |
734 | RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; | 742 | RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; |
@@ -745,7 +753,7 @@ public sealed class BSShapeCollection : IDisposable | |||
745 | yprim.BaseShape.SculptData = asset.Data; | 753 | yprim.BaseShape.SculptData = asset.Data; |
746 | // This will cause the prim to see that the filler shape is not the right | 754 | // This will cause the prim to see that the filler shape is not the right |
747 | // one and try again to build the object. | 755 | // one and try again to build the object. |
748 | // No race condition with the native sphere setting since the rebuild is at taint time. | 756 | // No race condition with the normal shape setting since the rebuild is at taint time. |
749 | yprim.ForceBodyShapeRebuild(false); | 757 | yprim.ForceBodyShapeRebuild(false); |
750 | 758 | ||
751 | }); | 759 | }); |
@@ -757,13 +765,13 @@ public sealed class BSShapeCollection : IDisposable | |||
757 | if (prim.LastAssetBuildFailed) | 765 | if (prim.LastAssetBuildFailed) |
758 | { | 766 | { |
759 | PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", | 767 | PhysicsScene.Logger.ErrorFormat("{0} Mesh failed to fetch asset. lID={1}, texture={2}", |
760 | LogHeader, shapeData.ID, pbs.SculptTexture); | 768 | LogHeader, prim.LocalID, prim.BaseShape.SculptTexture); |
761 | } | 769 | } |
762 | } | 770 | } |
763 | 771 | ||
764 | // While we figure out the real problem, stick a simple native shape on the object. | 772 | // While we figure out the real problem, stick a simple native shape on the object. |
765 | BulletShape fillinShape = | 773 | BulletShape fillinShape = |
766 | BuildPhysicalNativeShape(ShapeData.PhysicsShapeType.SHAPE_BOX, shapeData, ShapeData.FixedShapeKey.KEY_BOX); | 774 | BuildPhysicalNativeShape(prim, ShapeData.PhysicsShapeType.SHAPE_BOX, ShapeData.FixedShapeKey.KEY_BOX); |
767 | 775 | ||
768 | return fillinShape; | 776 | return fillinShape; |
769 | } | 777 | } |
@@ -773,7 +781,7 @@ public sealed class BSShapeCollection : IDisposable | |||
773 | // Returns 'true' if an object was actually created. | 781 | // Returns 'true' if an object was actually created. |
774 | // Called at taint-time. | 782 | // Called at taint-time. |
775 | private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, | 783 | private bool CreateBody(bool forceRebuild, BSPhysObject prim, BulletSim sim, BulletShape shape, |
776 | ShapeData shapeData, BodyDestructionCallback bodyCallback) | 784 | BodyDestructionCallback bodyCallback) |
777 | { | 785 | { |
778 | bool ret = false; | 786 | bool ret = false; |
779 | 787 | ||
@@ -803,16 +811,16 @@ public sealed class BSShapeCollection : IDisposable | |||
803 | if (prim.IsSolid) | 811 | if (prim.IsSolid) |
804 | { | 812 | { |
805 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, | 813 | bodyPtr = BulletSimAPI.CreateBodyFromShape2(sim.ptr, shape.ptr, |
806 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 814 | prim.LocalID, prim.ForcePosition, prim.ForceOrientation); |
807 | DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 815 | DetailLog("{0},BSShapeCollection.CreateBody,mesh,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
808 | } | 816 | } |
809 | else | 817 | else |
810 | { | 818 | { |
811 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, | 819 | bodyPtr = BulletSimAPI.CreateGhostFromShape2(sim.ptr, shape.ptr, |
812 | shapeData.ID, shapeData.Position, shapeData.Rotation); | 820 | prim.LocalID, prim.ForcePosition, prim.ForceOrientation); |
813 | DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); | 821 | DetailLog("{0},BSShapeCollection.CreateBody,ghost,ptr={1}", prim.LocalID, bodyPtr.ToString("X")); |
814 | } | 822 | } |
815 | aBody = new BulletBody(shapeData.ID, bodyPtr); | 823 | aBody = new BulletBody(prim.LocalID, bodyPtr); |
816 | 824 | ||
817 | ReferenceBody(aBody, true); | 825 | ReferenceBody(aBody, true); |
818 | 826 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs index 9b7ba03..3b6355c 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimAPI.cs | |||
@@ -194,6 +194,7 @@ public struct ShapeData | |||
194 | // following defined by BulletSim | 194 | // following defined by BulletSim |
195 | SHAPE_GROUNDPLANE = 20, | 195 | SHAPE_GROUNDPLANE = 20, |
196 | SHAPE_TERRAIN = 21, | 196 | SHAPE_TERRAIN = 21, |
197 | SHAPE_COMPOUND = 22, | ||
197 | }; | 198 | }; |
198 | public uint ID; | 199 | public uint ID; |
199 | public PhysicsShapeType Type; | 200 | public PhysicsShapeType Type; |