diff options
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 28 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 215 |
2 files changed, 191 insertions, 52 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 1976c42..bc26460 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -612,7 +612,7 @@ public sealed class BSShapeCollection : IDisposable | |||
612 | 612 | ||
613 | newShape = CreatePhysicalMesh(prim, newMeshKey, prim.BaseShape, prim.Size, lod); | 613 | newShape = CreatePhysicalMesh(prim, newMeshKey, prim.BaseShape, prim.Size, lod); |
614 | // Take evasive action if the mesh was not constructed. | 614 | // Take evasive action if the mesh was not constructed. |
615 | newShape = VerifyMeshCreated(newShape, prim); | 615 | newShape = VerifyMeshCreated(PhysicsScene, newShape, prim); |
616 | 616 | ||
617 | ReferenceShape(newShape); | 617 | ReferenceShape(newShape); |
618 | 618 | ||
@@ -719,7 +719,7 @@ public sealed class BSShapeCollection : IDisposable | |||
719 | 719 | ||
720 | newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod); | 720 | newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod); |
721 | // It might not have been created if we're waiting for an asset. | 721 | // It might not have been created if we're waiting for an asset. |
722 | newShape = VerifyMeshCreated(newShape, prim); | 722 | newShape = VerifyMeshCreated(PhysicsScene, newShape, prim); |
723 | 723 | ||
724 | ReferenceShape(newShape); | 724 | ReferenceShape(newShape); |
725 | 725 | ||
@@ -923,7 +923,7 @@ public sealed class BSShapeCollection : IDisposable | |||
923 | 923 | ||
924 | // Create a hash of all the shape parameters to be used as a key | 924 | // Create a hash of all the shape parameters to be used as a key |
925 | // for this particular shape. | 925 | // for this particular shape. |
926 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) | 926 | public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs, out float retLod) |
927 | { | 927 | { |
928 | // level of detail based on size and type of the object | 928 | // level of detail based on size and type of the object |
929 | float lod = BSParam.MeshLOD; | 929 | float lod = BSParam.MeshLOD; |
@@ -944,7 +944,7 @@ public sealed class BSShapeCollection : IDisposable | |||
944 | return pbs.GetMeshKey(size, lod); | 944 | return pbs.GetMeshKey(size, lod); |
945 | } | 945 | } |
946 | // For those who don't want the LOD | 946 | // For those who don't want the LOD |
947 | private System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) | 947 | public static System.UInt64 ComputeShapeKey(OMV.Vector3 size, PrimitiveBaseShape pbs) |
948 | { | 948 | { |
949 | float lod; | 949 | float lod; |
950 | return ComputeShapeKey(size, pbs, out lod); | 950 | return ComputeShapeKey(size, pbs, out lod); |
@@ -957,7 +957,7 @@ public sealed class BSShapeCollection : IDisposable | |||
957 | // us to not loop forever. | 957 | // us to not loop forever. |
958 | // Called after creating a physical mesh or hull. If the physical shape was created, | 958 | // Called after creating a physical mesh or hull. If the physical shape was created, |
959 | // just return. | 959 | // just return. |
960 | private BulletShape VerifyMeshCreated(BulletShape newShape, BSPhysObject prim) | 960 | public static BulletShape VerifyMeshCreated(BSScene physicsScene, BulletShape newShape, BSPhysObject prim) |
961 | { | 961 | { |
962 | // If the shape was successfully created, nothing more to do | 962 | // If the shape was successfully created, nothing more to do |
963 | if (newShape.HasPhysicalShape) | 963 | if (newShape.HasPhysicalShape) |
@@ -969,7 +969,7 @@ public sealed class BSShapeCollection : IDisposable | |||
969 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 969 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
970 | { | 970 | { |
971 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; | 971 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; |
972 | PhysicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", | 972 | physicsScene.Logger.WarnFormat("{0} Fetched asset would not mesh. {1}, texture={2}", |
973 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); | 973 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); |
974 | } | 974 | } |
975 | else | 975 | else |
@@ -981,14 +981,14 @@ public sealed class BSShapeCollection : IDisposable | |||
981 | && prim.BaseShape.SculptTexture != OMV.UUID.Zero | 981 | && prim.BaseShape.SculptTexture != OMV.UUID.Zero |
982 | ) | 982 | ) |
983 | { | 983 | { |
984 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); | 984 | physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,fetchAsset", prim.LocalID); |
985 | // Multiple requestors will know we're waiting for this asset | 985 | // Multiple requestors will know we're waiting for this asset |
986 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; | 986 | prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Waiting; |
987 | 987 | ||
988 | BSPhysObject xprim = prim; | 988 | BSPhysObject xprim = prim; |
989 | Util.FireAndForget(delegate | 989 | Util.FireAndForget(delegate |
990 | { | 990 | { |
991 | RequestAssetDelegate assetProvider = PhysicsScene.RequestAssetMethod; | 991 | RequestAssetDelegate assetProvider = physicsScene.RequestAssetMethod; |
992 | if (assetProvider != null) | 992 | if (assetProvider != null) |
993 | { | 993 | { |
994 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. | 994 | BSPhysObject yprim = xprim; // probably not necessary, but, just in case. |
@@ -1016,7 +1016,7 @@ public sealed class BSShapeCollection : IDisposable | |||
1016 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; | 1016 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Fetched; |
1017 | else | 1017 | else |
1018 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; | 1018 | yprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; |
1019 | DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", | 1019 | physicsScene.DetailLog("{0},BSShapeCollection,fetchAssetCallback,found={1},isSculpt={2},ids={3}", |
1020 | yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); | 1020 | yprim.LocalID, assetFound, yprim.BaseShape.SculptEntry, mismatchIDs ); |
1021 | 1021 | ||
1022 | }); | 1022 | }); |
@@ -1024,8 +1024,8 @@ public sealed class BSShapeCollection : IDisposable | |||
1024 | else | 1024 | else |
1025 | { | 1025 | { |
1026 | xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; | 1026 | xprim.PrimAssetState = BSPhysObject.PrimAssetCondition.Failed; |
1027 | PhysicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", | 1027 | physicsScene.Logger.ErrorFormat("{0} Physical object requires asset but no asset provider. Name={1}", |
1028 | LogHeader, PhysicsScene.Name); | 1028 | LogHeader, physicsScene.Name); |
1029 | } | 1029 | } |
1030 | }); | 1030 | }); |
1031 | } | 1031 | } |
@@ -1033,15 +1033,15 @@ public sealed class BSShapeCollection : IDisposable | |||
1033 | { | 1033 | { |
1034 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | 1034 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) |
1035 | { | 1035 | { |
1036 | PhysicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", | 1036 | physicsScene.Logger.WarnFormat("{0} Mesh failed to fetch asset. obj={1}, texture={2}", |
1037 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); | 1037 | LogHeader, prim.PhysObjectName, prim.BaseShape.SculptTexture); |
1038 | } | 1038 | } |
1039 | } | 1039 | } |
1040 | } | 1040 | } |
1041 | 1041 | ||
1042 | // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object. | 1042 | // While we wait for the mesh defining asset to be loaded, stick in a simple box for the object. |
1043 | BulletShape fillinShape = BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); | 1043 | BulletShape fillinShape = physicsScene.Shapes.BuildPhysicalNativeShape(prim, BSPhysicsShapeType.SHAPE_BOX, FixedShapeKey.KEY_BOX); |
1044 | DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID); | 1044 | physicsScene.DetailLog("{0},BSShapeCollection.VerifyMeshCreated,boxTempShape", prim.LocalID); |
1045 | 1045 | ||
1046 | return fillinShape; | 1046 | return fillinShape; |
1047 | } | 1047 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index ee18379..dd5ae1a 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -29,6 +29,9 @@ using System; | |||
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Text; | 30 | using System.Text; |
31 | 31 | ||
32 | using OpenSim.Framework; | ||
33 | using OpenSim.Region.Physics.Manager; | ||
34 | |||
32 | using OMV = OpenMetaverse; | 35 | using OMV = OpenMetaverse; |
33 | 36 | ||
34 | namespace OpenSim.Region.Physics.BulletSPlugin | 37 | namespace OpenSim.Region.Physics.BulletSPlugin |
@@ -37,11 +40,19 @@ public abstract class BSShape | |||
37 | { | 40 | { |
38 | public int referenceCount { get; set; } | 41 | public int referenceCount { get; set; } |
39 | public DateTime lastReferenced { get; set; } | 42 | public DateTime lastReferenced { get; set; } |
43 | public BulletShape physShapeInfo { get; set; } | ||
40 | 44 | ||
41 | public BSShape() | 45 | public BSShape() |
42 | { | 46 | { |
43 | referenceCount = 0; | 47 | referenceCount = 0; |
44 | lastReferenced = DateTime.Now; | 48 | lastReferenced = DateTime.Now; |
49 | physShapeInfo = new BulletShape(); | ||
50 | } | ||
51 | public BSShape(BulletShape pShape) | ||
52 | { | ||
53 | referenceCount = 0; | ||
54 | lastReferenced = DateTime.Now; | ||
55 | physShapeInfo = pShape; | ||
45 | } | 56 | } |
46 | 57 | ||
47 | // Get a reference to a physical shape. Create if it doesn't exist | 58 | // Get a reference to a physical shape. Create if it doesn't exist |
@@ -79,21 +90,30 @@ public abstract class BSShape | |||
79 | 90 | ||
80 | return ret; | 91 | return ret; |
81 | } | 92 | } |
82 | public static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 93 | private static BSShape GetShapeReferenceNonSpecial(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
83 | { | 94 | { |
95 | BSShapeMesh.GetReference(physicsScene, forceRebuild, prim); | ||
96 | BSShapeHull.GetReference(physicsScene, forceRebuild, prim); | ||
84 | return null; | 97 | return null; |
85 | } | 98 | } |
86 | public static BSShape GetShapeReferenceNonNative(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | 99 | |
100 | // Called when this shape is being used again. | ||
101 | public virtual void IncrementReference() | ||
87 | { | 102 | { |
88 | return null; | 103 | referenceCount++; |
104 | lastReferenced = DateTime.Now; | ||
105 | } | ||
106 | |||
107 | // Called when this shape is being used again. | ||
108 | public virtual void DecrementReference() | ||
109 | { | ||
110 | referenceCount--; | ||
111 | lastReferenced = DateTime.Now; | ||
89 | } | 112 | } |
90 | 113 | ||
91 | // Release the use of a physical shape. | 114 | // Release the use of a physical shape. |
92 | public abstract void Dereference(BSScene physicsScene); | 115 | public abstract void Dereference(BSScene physicsScene); |
93 | 116 | ||
94 | // All shapes have a static call to get a reference to the physical shape | ||
95 | // protected abstract static BSShape GetReference(); | ||
96 | |||
97 | // Returns a string for debugging that uniquily identifies the memory used by this instance | 117 | // Returns a string for debugging that uniquily identifies the memory used by this instance |
98 | public virtual string AddrString | 118 | public virtual string AddrString |
99 | { | 119 | { |
@@ -112,6 +132,7 @@ public abstract class BSShape | |||
112 | } | 132 | } |
113 | } | 133 | } |
114 | 134 | ||
135 | // ============================================================================================================ | ||
115 | public class BSShapeNull : BSShape | 136 | public class BSShapeNull : BSShape |
116 | { | 137 | { |
117 | public BSShapeNull() : base() | 138 | public BSShapeNull() : base() |
@@ -121,23 +142,39 @@ public class BSShapeNull : BSShape | |||
121 | public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } | 142 | public override void Dereference(BSScene physicsScene) { /* The magic of garbage collection will make this go away */ } |
122 | } | 143 | } |
123 | 144 | ||
145 | // ============================================================================================================ | ||
124 | public class BSShapeNative : BSShape | 146 | public class BSShapeNative : BSShape |
125 | { | 147 | { |
126 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; | 148 | private static string LogHeader = "[BULLETSIM SHAPE NATIVE]"; |
127 | public BSShapeNative() : base() | 149 | public BSShapeNative(BulletShape pShape) : base(pShape) |
128 | { | 150 | { |
129 | } | 151 | } |
152 | |||
130 | public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, | 153 | public static BSShape GetReference(BSScene physicsScene, BSPhysObject prim, |
131 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | 154 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) |
132 | { | 155 | { |
133 | // Native shapes are not shared and are always built anew. | 156 | // Native shapes are not shared and are always built anew. |
134 | //return new BSShapeNative(physicsScene, prim, shapeType, shapeKey); | 157 | return new BSShapeNative(CreatePhysicalNativeShape(physicsScene, prim, shapeType, shapeKey)); |
135 | return null; | ||
136 | } | 158 | } |
137 | 159 | ||
138 | private BSShapeNative(BSScene physicsScene, BSPhysObject prim, | 160 | // Make this reference to the physical shape go away since native shapes are not shared. |
139 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | 161 | public override void Dereference(BSScene physicsScene) |
162 | { | ||
163 | // Native shapes are not tracked and are released immediately | ||
164 | if (physShapeInfo.HasPhysicalShape) | ||
165 | { | ||
166 | physicsScene.DetailLog("{0},BSShapeNative.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); | ||
167 | physicsScene.PE.DeleteCollisionShape(physicsScene.World, physShapeInfo); | ||
168 | } | ||
169 | physShapeInfo.Clear(); | ||
170 | // Garbage collection will free up this instance. | ||
171 | } | ||
172 | |||
173 | private static BulletShape CreatePhysicalNativeShape(BSScene physicsScene, BSPhysObject prim, | ||
174 | BSPhysicsShapeType shapeType, FixedShapeKey shapeKey) | ||
140 | { | 175 | { |
176 | BulletShape newShape; | ||
177 | |||
141 | ShapeData nativeShapeData = new ShapeData(); | 178 | ShapeData nativeShapeData = new ShapeData(); |
142 | nativeShapeData.Type = shapeType; | 179 | nativeShapeData.Type = shapeType; |
143 | nativeShapeData.ID = prim.LocalID; | 180 | nativeShapeData.ID = prim.LocalID; |
@@ -146,63 +183,164 @@ public class BSShapeNative : BSShape | |||
146 | nativeShapeData.MeshKey = (ulong)shapeKey; | 183 | nativeShapeData.MeshKey = (ulong)shapeKey; |
147 | nativeShapeData.HullKey = (ulong)shapeKey; | 184 | nativeShapeData.HullKey = (ulong)shapeKey; |
148 | 185 | ||
149 | |||
150 | /* | ||
151 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) | 186 | if (shapeType == BSPhysicsShapeType.SHAPE_CAPSULE) |
152 | { | 187 | { |
153 | ptr = PhysicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); | 188 | newShape = physicsScene.PE.BuildCapsuleShape(physicsScene.World, 1f, 1f, prim.Scale); |
154 | physicsScene.DetailLog("{0},BSShapeCollection.BuiletPhysicalNativeShape,capsule,scale={1}", prim.LocalID, prim.Scale); | 189 | physicsScene.DetailLog("{0},BSShapeNative,capsule,scale={1}", prim.LocalID, prim.Scale); |
155 | } | 190 | } |
156 | else | 191 | else |
157 | { | 192 | { |
158 | ptr = PhysicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); | 193 | newShape = physicsScene.PE.BuildNativeShape(physicsScene.World, nativeShapeData); |
159 | } | 194 | } |
160 | if (ptr == IntPtr.Zero) | 195 | if (!newShape.HasPhysicalShape) |
161 | { | 196 | { |
162 | physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", | 197 | physicsScene.Logger.ErrorFormat("{0} BuildPhysicalNativeShape failed. ID={1}, shape={2}", |
163 | LogHeader, prim.LocalID, shapeType); | 198 | LogHeader, prim.LocalID, shapeType); |
164 | } | 199 | } |
165 | type = shapeType; | 200 | newShape.type = shapeType; |
166 | key = (UInt64)shapeKey; | 201 | newShape.isNativeShape = true; |
167 | */ | 202 | newShape.shapeKey = (UInt64)shapeKey; |
168 | } | 203 | return newShape; |
169 | // Make this reference to the physical shape go away since native shapes are not shared. | ||
170 | public override void Dereference(BSScene physicsScene) | ||
171 | { | ||
172 | /* | ||
173 | // Native shapes are not tracked and are released immediately | ||
174 | physicsScene.DetailLog("{0},BSShapeCollection.DereferenceShape,deleteNativeShape,shape={1}", BSScene.DetailLogZero, this); | ||
175 | PhysicsScene.PE.DeleteCollisionShape(physicsScene.World, this); | ||
176 | ptr = IntPtr.Zero; | ||
177 | // Garbage collection will free up this instance. | ||
178 | */ | ||
179 | } | 204 | } |
205 | |||
180 | } | 206 | } |
181 | 207 | ||
208 | // ============================================================================================================ | ||
182 | public class BSShapeMesh : BSShape | 209 | public class BSShapeMesh : BSShape |
183 | { | 210 | { |
184 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; | 211 | private static string LogHeader = "[BULLETSIM SHAPE MESH]"; |
185 | private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); | 212 | private static Dictionary<System.UInt64, BSShapeMesh> Meshes = new Dictionary<System.UInt64, BSShapeMesh>(); |
186 | 213 | ||
187 | public BSShapeMesh() : base() | 214 | public BSShapeMesh(BulletShape pShape) : base(pShape) |
188 | { | 215 | { |
189 | } | 216 | } |
190 | public static BSShape GetReference() { return new BSShapeNull(); } | 217 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) |
191 | public override void Dereference(BSScene physicsScene) { } | 218 | { |
219 | float lod; | ||
220 | System.UInt64 newMeshKey = BSShapeCollection.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
221 | |||
222 | physicsScene.DetailLog("{0},BSShapeMesh,create,oldKey={1},newKey={2},size={3},lod={4}", | ||
223 | prim.LocalID, prim.PhysShape.shapeKey.ToString("X"), newMeshKey.ToString("X"), prim.Size, lod); | ||
224 | |||
225 | BSShapeMesh retMesh; | ||
226 | lock (Meshes) | ||
227 | { | ||
228 | if (Meshes.TryGetValue(newMeshKey, out retMesh)) | ||
229 | { | ||
230 | // The mesh has already been created. Return a new reference to same. | ||
231 | retMesh.IncrementReference(); | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | // An instance of this mesh has not been created. Build and remember same. | ||
236 | BulletShape newShape = CreatePhysicalMesh(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
237 | // Take evasive action if the mesh was not constructed. | ||
238 | newShape = BSShapeCollection.VerifyMeshCreated(physicsScene, newShape, prim); | ||
239 | |||
240 | retMesh = new BSShapeMesh(newShape); | ||
241 | |||
242 | Meshes.Add(newMeshKey, retMesh); | ||
243 | } | ||
244 | } | ||
245 | return retMesh; | ||
246 | } | ||
247 | public override void Dereference(BSScene physicsScene) | ||
248 | { | ||
249 | lock (Meshes) | ||
250 | { | ||
251 | this.DecrementReference(); | ||
252 | // TODO: schedule aging and destruction of unused meshes. | ||
253 | } | ||
254 | } | ||
255 | |||
256 | private static BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
257 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
258 | { | ||
259 | BulletShape newShape = null; | ||
260 | |||
261 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | ||
262 | false, // say it is not physical so a bounding box is not built | ||
263 | false // do not cache the mesh and do not use previously built versions | ||
264 | ); | ||
265 | |||
266 | if (meshData != null) | ||
267 | { | ||
268 | |||
269 | int[] indices = meshData.getIndexListAsInt(); | ||
270 | int realIndicesIndex = indices.Length; | ||
271 | float[] verticesAsFloats = meshData.getVertexListAsFloat(); | ||
272 | |||
273 | if (BSParam.ShouldRemoveZeroWidthTriangles) | ||
274 | { | ||
275 | // Remove degenerate triangles. These are triangles with two of the vertices | ||
276 | // are the same. This is complicated by the problem that vertices are not | ||
277 | // made unique in sculpties so we have to compare the values in the vertex. | ||
278 | realIndicesIndex = 0; | ||
279 | for (int tri = 0; tri < indices.Length; tri += 3) | ||
280 | { | ||
281 | // Compute displacements into vertex array for each vertex of the triangle | ||
282 | int v1 = indices[tri + 0] * 3; | ||
283 | int v2 = indices[tri + 1] * 3; | ||
284 | int v3 = indices[tri + 2] * 3; | ||
285 | // Check to see if any two of the vertices are the same | ||
286 | if (!( ( verticesAsFloats[v1 + 0] == verticesAsFloats[v2 + 0] | ||
287 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v2 + 1] | ||
288 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v2 + 2]) | ||
289 | || ( verticesAsFloats[v2 + 0] == verticesAsFloats[v3 + 0] | ||
290 | && verticesAsFloats[v2 + 1] == verticesAsFloats[v3 + 1] | ||
291 | && verticesAsFloats[v2 + 2] == verticesAsFloats[v3 + 2]) | ||
292 | || ( verticesAsFloats[v1 + 0] == verticesAsFloats[v3 + 0] | ||
293 | && verticesAsFloats[v1 + 1] == verticesAsFloats[v3 + 1] | ||
294 | && verticesAsFloats[v1 + 2] == verticesAsFloats[v3 + 2]) ) | ||
295 | ) | ||
296 | { | ||
297 | // None of the vertices of the triangles are the same. This is a good triangle; | ||
298 | indices[realIndicesIndex + 0] = indices[tri + 0]; | ||
299 | indices[realIndicesIndex + 1] = indices[tri + 1]; | ||
300 | indices[realIndicesIndex + 2] = indices[tri + 2]; | ||
301 | realIndicesIndex += 3; | ||
302 | } | ||
303 | } | ||
304 | } | ||
305 | physicsScene.DetailLog("{0},BSShapeCollection.CreatePhysicalMesh,origTri={1},realTri={2},numVerts={3}", | ||
306 | BSScene.DetailLogZero, indices.Length / 3, realIndicesIndex / 3, verticesAsFloats.Length / 3); | ||
307 | |||
308 | if (realIndicesIndex != 0) | ||
309 | { | ||
310 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | ||
311 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
312 | } | ||
313 | else | ||
314 | { | ||
315 | physicsScene.Logger.DebugFormat("{0} All mesh triangles degenerate. Prim {1} at {2} in {3}", | ||
316 | LogHeader, prim.PhysObjectName, prim.RawPosition, physicsScene.Name); | ||
317 | } | ||
318 | } | ||
319 | newShape.shapeKey = newMeshKey; | ||
320 | |||
321 | return newShape; | ||
322 | } | ||
192 | } | 323 | } |
193 | 324 | ||
325 | // ============================================================================================================ | ||
194 | public class BSShapeHull : BSShape | 326 | public class BSShapeHull : BSShape |
195 | { | 327 | { |
196 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; | 328 | private static string LogHeader = "[BULLETSIM SHAPE HULL]"; |
197 | private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); | 329 | private static Dictionary<System.UInt64, BSShapeHull> Hulls = new Dictionary<System.UInt64, BSShapeHull>(); |
198 | 330 | ||
199 | public BSShapeHull() : base() | 331 | public BSShapeHull(BulletShape pShape) : base(pShape) |
332 | { | ||
333 | } | ||
334 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
335 | { | ||
336 | return new BSShapeNull(); | ||
337 | } | ||
338 | public override void Dereference(BSScene physicsScene) | ||
200 | { | 339 | { |
201 | } | 340 | } |
202 | public static BSShape GetReference() { return new BSShapeNull(); } | ||
203 | public override void Dereference(BSScene physicsScene) { } | ||
204 | } | 341 | } |
205 | 342 | ||
343 | // ============================================================================================================ | ||
206 | public class BSShapeCompound : BSShape | 344 | public class BSShapeCompound : BSShape |
207 | { | 345 | { |
208 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; | 346 | private static string LogHeader = "[BULLETSIM SHAPE COMPOUND]"; |
@@ -216,6 +354,7 @@ public class BSShapeCompound : BSShape | |||
216 | public override void Dereference(BSScene physicsScene) { } | 354 | public override void Dereference(BSScene physicsScene) { } |
217 | } | 355 | } |
218 | 356 | ||
357 | // ============================================================================================================ | ||
219 | public class BSShapeAvatar : BSShape | 358 | public class BSShapeAvatar : BSShape |
220 | { | 359 | { |
221 | private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; | 360 | private static string LogHeader = "[BULLETSIM SHAPE AVATAR]"; |