diff options
Diffstat (limited to 'OpenSim/Region/Physics')
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | 15 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | 11 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | 5 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | 11 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | 6 | ||||
-rw-r--r-- | OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | 8 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | 15 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | 185 | ||||
-rwxr-xr-x | OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | 14 | ||||
-rw-r--r-- | OpenSim/Region/Physics/Meshing/Meshmerizer.cs | 131 |
10 files changed, 352 insertions, 49 deletions
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs index 231f0f8..12a0c17 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIUnman.cs | |||
@@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world, | |||
251 | BSPhysicsShapeType.SHAPE_MESH); | 251 | BSPhysicsShapeType.SHAPE_MESH); |
252 | } | 252 | } |
253 | 253 | ||
254 | public override BulletShape CreateGImpactShape(BulletWorld world, | ||
255 | int indicesCount, int[] indices, | ||
256 | int verticesCount, float[] vertices) | ||
257 | { | ||
258 | BulletWorldUnman worldu = world as BulletWorldUnman; | ||
259 | return new BulletShapeUnman( | ||
260 | BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices), | ||
261 | BSPhysicsShapeType.SHAPE_GIMPACT); | ||
262 | } | ||
263 | |||
254 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) | 264 | public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls) |
255 | { | 265 | { |
256 | BulletWorldUnman worldu = world as BulletWorldUnman; | 266 | BulletWorldUnman worldu = world as BulletWorldUnman; |
@@ -1426,6 +1436,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world, | |||
1426 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | 1436 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); |
1427 | 1437 | ||
1428 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | 1438 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] |
1439 | public static extern IntPtr CreateGImpactShape2(IntPtr world, | ||
1440 | int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices, | ||
1441 | int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices ); | ||
1442 | |||
1443 | [DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity] | ||
1429 | public static extern IntPtr CreateHullShape2(IntPtr world, | 1444 | public static extern IntPtr CreateHullShape2(IntPtr world, |
1430 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); | 1445 | int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls); |
1431 | 1446 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs index 59780ae..6db5f5e 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSAPIXNA.cs | |||
@@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1475 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; |
1476 | break; | 1476 | break; |
1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: | 1477 | case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE: |
1478 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1478 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1479 | break; | 1479 | break; |
1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: | 1480 | case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE: |
1481 | ret = BSPhysicsShapeType.SHAPE_HULL; | 1481 | ret = BSPhysicsShapeType.SHAPE_HULL; |
@@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1503 | ret = BSPhysicsShapeType.SHAPE_CONE; | 1503 | ret = BSPhysicsShapeType.SHAPE_CONE; |
1504 | break; | 1504 | break; |
1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: | 1505 | case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE: |
1506 | ret = BSPhysicsShapeType.SHAPE_UNKNOWN; | 1506 | ret = BSPhysicsShapeType.SHAPE_CONVEXHULL; |
1507 | break; | 1507 | break; |
1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: | 1508 | case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE: |
1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; | 1509 | ret = BSPhysicsShapeType.SHAPE_CYLINDER; |
@@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1547 | break; | 1547 | break; |
1548 | ///Used for GIMPACT Trimesh integration | 1548 | ///Used for GIMPACT Trimesh integration |
1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: | 1549 | case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE: |
1550 | ret = BSPhysicsShapeType.SHAPE_MESH; | 1550 | ret = BSPhysicsShapeType.SHAPE_GIMPACT; |
1551 | break; | 1551 | break; |
1552 | ///Multimaterial mesh | 1552 | ///Multimaterial mesh |
1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: | 1553 | case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE: |
@@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint | |||
1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); | 1820 | return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH); |
1821 | 1821 | ||
1822 | } | 1822 | } |
1823 | public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats) | ||
1824 | { | ||
1825 | // TODO: | ||
1826 | return null; | ||
1827 | } | ||
1823 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) | 1828 | public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount ) |
1824 | { | 1829 | { |
1825 | 1830 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs index 3378c93..6cdc112 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSApiTemplate.cs | |||
@@ -71,6 +71,7 @@ public enum BSPhysicsShapeType | |||
71 | SHAPE_HEIGHTMAP = 23, | 71 | SHAPE_HEIGHTMAP = 23, |
72 | SHAPE_AVATAR = 24, | 72 | SHAPE_AVATAR = 24, |
73 | SHAPE_CONVEXHULL= 25, | 73 | SHAPE_CONVEXHULL= 25, |
74 | SHAPE_GIMPACT = 26, | ||
74 | }; | 75 | }; |
75 | 76 | ||
76 | // The native shapes have predefined shape hash keys | 77 | // The native shapes have predefined shape hash keys |
@@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world, | |||
321 | int indicesCount, int[] indices, | 322 | int indicesCount, int[] indices, |
322 | int verticesCount, float[] vertices ); | 323 | int verticesCount, float[] vertices ); |
323 | 324 | ||
325 | public abstract BulletShape CreateGImpactShape(BulletWorld world, | ||
326 | int indicesCount, int[] indices, | ||
327 | int verticesCount, float[] vertices ); | ||
328 | |||
324 | public abstract BulletShape CreateHullShape(BulletWorld world, | 329 | public abstract BulletShape CreateHullShape(BulletWorld world, |
325 | int hullCount, float[] hulls); | 330 | int hullCount, float[] hulls); |
326 | 331 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs index ff5b6ab..48f842e 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSCharacter.cs | |||
@@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject | |||
483 | { | 483 | { |
484 | // Bullet assumes we know what we are doing when forcing orientation | 484 | // Bullet assumes we know what we are doing when forcing orientation |
485 | // so it lets us go against all the rules and just compensates for them later. | 485 | // so it lets us go against all the rules and just compensates for them later. |
486 | // This keeps us from flipping the capsule over which the veiwer does not understand. | 486 | // This forces rotation to be only around the Z axis and doesn't change any of the other axis. |
487 | ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0); | 487 | // This keeps us from flipping the capsule over which the veiwer does not understand. |
488 | float oRoll, oPitch, oYaw; | ||
489 | _orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw); | ||
490 | OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw); | ||
491 | // DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}", | ||
492 | // LocalID, _orientation, OMV.Vector3.UnitX * _orientation, | ||
493 | // trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation); | ||
494 | ForceOrientation = trimmedOrientation; | ||
488 | }); | 495 | }); |
489 | } | 496 | } |
490 | } | 497 | } |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs index d33292f..5cff668 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSParam.cs | |||
@@ -89,6 +89,8 @@ public static class BSParam | |||
89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } | 89 | public static bool ShouldRemoveZeroWidthTriangles { get; private set; } |
90 | public static bool ShouldUseBulletHACD { get; set; } | 90 | public static bool ShouldUseBulletHACD { get; set; } |
91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } | 91 | public static bool ShouldUseSingleConvexHullForPrims { get; set; } |
92 | public static bool ShouldUseGImpactShapeForPrims { get; set; } | ||
93 | public static bool ShouldUseAssetHulls { get; set; } | ||
92 | 94 | ||
93 | public static float TerrainImplementation { get; set; } | 95 | public static float TerrainImplementation { get; set; } |
94 | public static int TerrainMeshMagnification { get; private set; } | 96 | public static int TerrainMeshMagnification { get; private set; } |
@@ -369,6 +371,10 @@ public static class BSParam | |||
369 | false ), | 371 | false ), |
370 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", | 372 | new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims", |
371 | true ), | 373 | true ), |
374 | new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists", | ||
375 | false ), | ||
376 | new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info", | ||
377 | false ), | ||
372 | 378 | ||
373 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", | 379 | new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions", |
374 | 5 ), | 380 | 5 ), |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs index 3f407ce..39f5b0a 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSScene.cs | |||
@@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
268 | // Do any replacements in the parameters | 268 | // Do any replacements in the parameters |
269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); | 269 | m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName); |
270 | } | 270 | } |
271 | else | ||
272 | { | ||
273 | BulletEngineName = "BulletUnmanaged"; | ||
274 | m_physicsLoggingEnabled = false; | ||
275 | VehicleLoggingEnabled = false; | ||
276 | } | ||
271 | 277 | ||
272 | // The material characteristics. | 278 | // The material characteristics. |
273 | BSMaterials.InitializeFromDefaults(Params); | 279 | BSMaterials.InitializeFromDefaults(Params); |
@@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters | |||
322 | BSParam.ShouldUseBulletHACD = false; | 328 | BSParam.ShouldUseBulletHACD = false; |
323 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); | 329 | m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader); |
324 | BSParam.ShouldUseSingleConvexHullForPrims = false; | 330 | BSParam.ShouldUseSingleConvexHullForPrims = false; |
331 | m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader); | ||
332 | BSParam.ShouldUseGImpactShapeForPrims = false; | ||
325 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); | 333 | m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader); |
326 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; | 334 | BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap; |
327 | break; | 335 | break; |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs index 64aaa15..32bbc8f 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapeCollection.cs | |||
@@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable | |||
230 | BSShape potentialHull = null; | 230 | BSShape potentialHull = null; |
231 | 231 | ||
232 | PrimitiveBaseShape pbs = prim.BaseShape; | 232 | PrimitiveBaseShape pbs = prim.BaseShape; |
233 | // Use a simple, one section convex shape for prims that are probably convex (no cuts or twists) | ||
233 | if (BSParam.ShouldUseSingleConvexHullForPrims | 234 | if (BSParam.ShouldUseSingleConvexHullForPrims |
234 | && pbs != null | 235 | && pbs != null |
235 | && !pbs.SculptEntry | 236 | && !pbs.SculptEntry |
@@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable | |||
238 | { | 239 | { |
239 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); | 240 | potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim); |
240 | } | 241 | } |
241 | else | 242 | // Use the GImpact shape if it is a prim that has some concaveness |
243 | if (potentialHull == null | ||
244 | && BSParam.ShouldUseGImpactShapeForPrims | ||
245 | && pbs != null | ||
246 | && !pbs.SculptEntry | ||
247 | ) | ||
248 | { | ||
249 | potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim); | ||
250 | } | ||
251 | // If not any of the simple cases, just make a hull | ||
252 | if (potentialHull == null) | ||
242 | { | 253 | { |
243 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 254 | potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
244 | } | 255 | } |
@@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable | |||
261 | } | 272 | } |
262 | else | 273 | else |
263 | { | 274 | { |
264 | // Update prim.BSShape to reference a mesh of this shape. | 275 | // Non-physical objects should be just meshes. |
265 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); | 276 | BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim); |
266 | // If the current shape is not what is on the prim at the moment, time to change. | 277 | // If the current shape is not what is on the prim at the moment, time to change. |
267 | if (!prim.PhysShape.HasPhysicalShape | 278 | if (!prim.PhysShape.HasPhysicalShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs index 6b09468..fca4258 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs | |||
@@ -31,6 +31,7 @@ using System.Text; | |||
31 | 31 | ||
32 | using OpenSim.Framework; | 32 | using OpenSim.Framework; |
33 | using OpenSim.Region.Physics.Manager; | 33 | using OpenSim.Region.Physics.Manager; |
34 | using OpenSim.Region.Physics.Meshing; | ||
34 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; | 35 | using OpenSim.Region.Physics.ConvexDecompositionDotNet; |
35 | 36 | ||
36 | using OMV = OpenMetaverse; | 37 | using OMV = OpenMetaverse; |
@@ -422,9 +423,22 @@ public class BSShapeMesh : BSShape | |||
422 | outMesh = foundDesc; | 423 | outMesh = foundDesc; |
423 | return ret; | 424 | return ret; |
424 | } | 425 | } |
426 | |||
427 | public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices ); | ||
425 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | 428 | private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, |
426 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 429 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
427 | { | 430 | { |
431 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
432 | (w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) ); | ||
433 | } | ||
434 | |||
435 | // Code that uses the mesher to create the index/vertices info for a trimesh shape. | ||
436 | // This is used by the passed 'makeShape' call to create the Bullet mesh shape. | ||
437 | // The actual build call is passed so this logic can be used by several of the shapes that use a | ||
438 | // simple mesh as their base shape. | ||
439 | public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
440 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape) | ||
441 | { | ||
428 | BulletShape newShape = new BulletShape(); | 442 | BulletShape newShape = new BulletShape(); |
429 | 443 | ||
430 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, | 444 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, |
@@ -484,8 +498,7 @@ public class BSShapeMesh : BSShape | |||
484 | 498 | ||
485 | if (realIndicesIndex != 0) | 499 | if (realIndicesIndex != 0) |
486 | { | 500 | { |
487 | newShape = physicsScene.PE.CreateMeshShape(physicsScene.World, | 501 | newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); |
488 | realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats); | ||
489 | } | 502 | } |
490 | else | 503 | else |
491 | { | 504 | { |
@@ -563,9 +576,56 @@ public class BSShapeHull : BSShape | |||
563 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | 576 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) |
564 | { | 577 | { |
565 | BulletShape newShape = new BulletShape(); | 578 | BulletShape newShape = new BulletShape(); |
566 | IntPtr hullPtr = IntPtr.Zero; | 579 | newShape.shapeKey = newHullKey; |
580 | |||
581 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
582 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
567 | 583 | ||
568 | if (BSParam.ShouldUseBulletHACD) | 584 | // If there is hull data in the mesh asset, build the hull from that |
585 | if (meshData != null && BSParam.ShouldUseAssetHulls) | ||
586 | { | ||
587 | Meshmerizer realMesher = physicsScene.mesher as Meshmerizer; | ||
588 | if (realMesher != null) | ||
589 | { | ||
590 | List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size); | ||
591 | if (allHulls != null) | ||
592 | { | ||
593 | int hullCount = allHulls.Count; | ||
594 | int totalVertices = 1; // include one for the count of the hulls | ||
595 | // Using the structure described for HACD hulls, create the memory sturcture | ||
596 | // to pass the hull data to the creater. | ||
597 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
598 | { | ||
599 | totalVertices += 4; // add four for the vertex count and centroid | ||
600 | totalVertices += hullVerts.Count * 3; // one vertex is three dimensions | ||
601 | } | ||
602 | float[] convHulls = new float[totalVertices]; | ||
603 | |||
604 | convHulls[0] = (float)hullCount; | ||
605 | int jj = 1; | ||
606 | foreach (List<OMV.Vector3> hullVerts in allHulls) | ||
607 | { | ||
608 | convHulls[jj + 0] = hullVerts.Count; | ||
609 | convHulls[jj + 1] = 0f; // centroid x,y,z | ||
610 | convHulls[jj + 2] = 0f; | ||
611 | convHulls[jj + 3] = 0f; | ||
612 | jj += 4; | ||
613 | foreach (OMV.Vector3 oneVert in hullVerts) | ||
614 | { | ||
615 | convHulls[jj + 0] = oneVert.X; | ||
616 | convHulls[jj + 1] = oneVert.Y; | ||
617 | convHulls[jj + 2] = oneVert.Z; | ||
618 | jj += 3; | ||
619 | } | ||
620 | } | ||
621 | |||
622 | // create the hull data structure in Bullet | ||
623 | newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls); | ||
624 | } | ||
625 | } | ||
626 | } | ||
627 | // If no hull specified in the asset and we should use Bullet's HACD approximation... | ||
628 | if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD) | ||
569 | { | 629 | { |
570 | // Build the hull shape from an existing mesh shape. | 630 | // Build the hull shape from an existing mesh shape. |
571 | // The mesh should have already been created in Bullet. | 631 | // The mesh should have already been created in Bullet. |
@@ -594,11 +654,10 @@ public class BSShapeHull : BSShape | |||
594 | } | 654 | } |
595 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); | 655 | physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape); |
596 | } | 656 | } |
657 | // If no hull specified, use our HACD hull approximation. | ||
597 | if (!newShape.HasPhysicalShape) | 658 | if (!newShape.HasPhysicalShape) |
598 | { | 659 | { |
599 | // Build a new hull in the physical world using the C# HACD algorigthm. | 660 | // Build a new hull in the physical world using the C# HACD algorigthm. |
600 | // Pass true for physicalness as this prevents the creation of bounding box which is not needed | ||
601 | IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false); | ||
602 | if (meshData != null) | 661 | if (meshData != null) |
603 | { | 662 | { |
604 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) | 663 | if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched) |
@@ -805,6 +864,7 @@ public class BSShapeCompound : BSShape | |||
805 | // Called at taint-time. | 864 | // Called at taint-time. |
806 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) | 865 | private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape) |
807 | { | 866 | { |
867 | // TODO: figure a better way to go through all the shape types and find a possible instance. | ||
808 | BSShapeMesh meshDesc; | 868 | BSShapeMesh meshDesc; |
809 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) | 869 | if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc)) |
810 | { | 870 | { |
@@ -826,17 +886,25 @@ public class BSShapeCompound : BSShape | |||
826 | } | 886 | } |
827 | else | 887 | else |
828 | { | 888 | { |
829 | if (physicsScene.PE.IsCompound(pShape)) | 889 | BSShapeGImpact gImpactDesc; |
890 | if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc)) | ||
830 | { | 891 | { |
831 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); | 892 | gImpactDesc.Dereference(physicsScene); |
832 | recursiveCompound.Dereference(physicsScene); | ||
833 | } | 893 | } |
834 | else | 894 | else |
835 | { | 895 | { |
836 | if (physicsScene.PE.IsNativeShape(pShape)) | 896 | if (physicsScene.PE.IsCompound(pShape)) |
837 | { | 897 | { |
838 | BSShapeNative nativeShape = new BSShapeNative(pShape); | 898 | BSShapeCompound recursiveCompound = new BSShapeCompound(pShape); |
839 | nativeShape.Dereference(physicsScene); | 899 | recursiveCompound.Dereference(physicsScene); |
900 | } | ||
901 | else | ||
902 | { | ||
903 | if (physicsScene.PE.IsNativeShape(pShape)) | ||
904 | { | ||
905 | BSShapeNative nativeShape = new BSShapeNative(pShape); | ||
906 | nativeShape.Dereference(physicsScene); | ||
907 | } | ||
840 | } | 908 | } |
841 | } | 909 | } |
842 | } | 910 | } |
@@ -859,7 +927,7 @@ public class BSShapeConvexHull : BSShape | |||
859 | float lod; | 927 | float lod; |
860 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | 928 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); |
861 | 929 | ||
862 | physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}", | 930 | physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}", |
863 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | 931 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); |
864 | 932 | ||
865 | BSShapeConvexHull retConvexHull = null; | 933 | BSShapeConvexHull retConvexHull = null; |
@@ -939,6 +1007,97 @@ public class BSShapeConvexHull : BSShape | |||
939 | return ret; | 1007 | return ret; |
940 | } | 1008 | } |
941 | } | 1009 | } |
1010 | // ============================================================================================================ | ||
1011 | public class BSShapeGImpact : BSShape | ||
1012 | { | ||
1013 | private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]"; | ||
1014 | public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>(); | ||
1015 | |||
1016 | public BSShapeGImpact(BulletShape pShape) : base(pShape) | ||
1017 | { | ||
1018 | } | ||
1019 | public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim) | ||
1020 | { | ||
1021 | float lod; | ||
1022 | System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod); | ||
1023 | |||
1024 | physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}", | ||
1025 | prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod); | ||
1026 | |||
1027 | BSShapeGImpact retGImpact = null; | ||
1028 | lock (GImpacts) | ||
1029 | { | ||
1030 | if (GImpacts.TryGetValue(newMeshKey, out retGImpact)) | ||
1031 | { | ||
1032 | // The mesh has already been created. Return a new reference to same. | ||
1033 | retGImpact.IncrementReference(); | ||
1034 | } | ||
1035 | else | ||
1036 | { | ||
1037 | retGImpact = new BSShapeGImpact(new BulletShape()); | ||
1038 | BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod); | ||
1039 | |||
1040 | // Check to see if mesh was created (might require an asset). | ||
1041 | newShape = VerifyMeshCreated(physicsScene, newShape, prim); | ||
1042 | if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed) | ||
1043 | { | ||
1044 | // If a mesh was what was created, remember the built shape for later sharing. | ||
1045 | // Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh. | ||
1046 | GImpacts.Add(newMeshKey, retGImpact); | ||
1047 | } | ||
1048 | |||
1049 | retGImpact.physShapeInfo = newShape; | ||
1050 | } | ||
1051 | } | ||
1052 | return retGImpact; | ||
1053 | } | ||
1054 | |||
1055 | private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey, | ||
1056 | PrimitiveBaseShape pbs, OMV.Vector3 size, float lod) | ||
1057 | { | ||
1058 | return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod, | ||
1059 | (w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) ); | ||
1060 | } | ||
1061 | |||
1062 | public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim) | ||
1063 | { | ||
1064 | // Calling this reference means we want another handle to an existing shape | ||
1065 | // (usually linksets) so return this copy. | ||
1066 | IncrementReference(); | ||
1067 | return this; | ||
1068 | } | ||
1069 | // Dereferencing a compound shape releases the hold on all the child shapes. | ||
1070 | public override void Dereference(BSScene physicsScene) | ||
1071 | { | ||
1072 | lock (GImpacts) | ||
1073 | { | ||
1074 | this.DecrementReference(); | ||
1075 | physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this); | ||
1076 | // TODO: schedule aging and destruction of unused meshes. | ||
1077 | } | ||
1078 | } | ||
1079 | // Loop through all the known hulls and return the description based on the physical address. | ||
1080 | public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull) | ||
1081 | { | ||
1082 | bool ret = false; | ||
1083 | BSShapeGImpact foundDesc = null; | ||
1084 | lock (GImpacts) | ||
1085 | { | ||
1086 | foreach (BSShapeGImpact sh in GImpacts.Values) | ||
1087 | { | ||
1088 | if (sh.physShapeInfo.ReferenceSame(pShape)) | ||
1089 | { | ||
1090 | foundDesc = sh; | ||
1091 | ret = true; | ||
1092 | break; | ||
1093 | } | ||
1094 | |||
1095 | } | ||
1096 | } | ||
1097 | outHull = foundDesc; | ||
1098 | return ret; | ||
1099 | } | ||
1100 | } | ||
942 | 1101 | ||
943 | // ============================================================================================================ | 1102 | // ============================================================================================================ |
944 | public class BSShapeAvatar : BSShape | 1103 | public class BSShapeAvatar : BSShape |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt index 5792ae6..df1da63 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt +++ b/OpenSim/Region/Physics/BulletSPlugin/BulletSimTODO.txt | |||
@@ -1,16 +1,12 @@ | |||
1 | PROBLEMS TO LOOK INTO | 1 | CURRENT PROBLEMS TO FIX AND/OR LOOK AT |
2 | ================================================= | 2 | ================================================= |
3 | Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly. | 3 | Script changing rotation of child prim while vehicle moving (eg turning wheel) causes |
4 | the wheel to appear to jump back. Looks like sending position from previous update. | ||
5 | Vehicle ride, get up, ride again. Second time vehicle does not act correctly. | ||
4 | Have to rez new vehicle and delete the old to fix situation. | 6 | Have to rez new vehicle and delete the old to fix situation. |
5 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd | 7 | Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd |
6 | position state where it will not settle onto ground properly, etc | 8 | position state where it will not settle onto ground properly, etc |
7 | Two of Nebadon vehicles in a sim max the CPU. This is new. | 9 | Two of Nebadon vehicles in a sim max the CPU. This is new. |
8 | A sitting, active vehicle bobs up and down a small amount. | ||
9 | |||
10 | CURRENT PRIORITIES | ||
11 | ================================================= | ||
12 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
13 | Speed up hullifying large meshes. | ||
14 | Enable vehicle border crossings (at least as poorly as ODE) | 10 | Enable vehicle border crossings (at least as poorly as ODE) |
15 | Terrain skirts | 11 | Terrain skirts |
16 | Avatar created in previous region and not new region when crossing border | 12 | Avatar created in previous region and not new region when crossing border |
@@ -361,4 +357,6 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE. | |||
361 | Nebadon vehicles turning funny in arena (DONE) | 357 | Nebadon vehicles turning funny in arena (DONE) |
362 | Lock axis (DONE 20130401) | 358 | Lock axis (DONE 20130401) |
363 | Terrain detail: double terrain mesh detail (DONE) | 359 | Terrain detail: double terrain mesh detail (DONE) |
360 | Use the HACD convex hull routine in Bullet rather than the C# version. | ||
361 | Speed up hullifying large meshes. (DONE) | ||
364 | 362 | ||
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs index 42929ec..db5d962 100644 --- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs +++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs | |||
@@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Meshing | |||
79 | 79 | ||
80 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh | 80 | private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh |
81 | 81 | ||
82 | private List<List<Vector3>> mConvexHulls = null; | ||
83 | |||
82 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); | 84 | private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>(); |
83 | 85 | ||
84 | public Meshmerizer(IConfigSource config) | 86 | public Meshmerizer(IConfigSource config) |
@@ -363,6 +365,57 @@ namespace OpenSim.Region.Physics.Meshing | |||
363 | else if (map.ContainsKey("high_lod")) | 365 | else if (map.ContainsKey("high_lod")) |
364 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) | 366 | physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :) |
365 | 367 | ||
368 | if (map.ContainsKey("physics_convex")) | ||
369 | { // pull this out also in case physics engine can use it | ||
370 | try | ||
371 | { | ||
372 | OSDMap convexBlock = (OSDMap)map["physics_convex"]; | ||
373 | if (convexBlock.ContainsKey("HullList")) | ||
374 | { | ||
375 | byte[] hullList = convexBlock["HullList"].AsBinary(); | ||
376 | Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f); | ||
377 | if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3(); | ||
378 | Vector3 max = new Vector3(0.5f, 0.5f, 0.5f); | ||
379 | if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3(); | ||
380 | |||
381 | // decompress and decode hull points | ||
382 | byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary(); | ||
383 | |||
384 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
385 | int posNdx = 0; | ||
386 | |||
387 | foreach (byte cnt in hullList) | ||
388 | { | ||
389 | int count = cnt == 0 ? 256 : cnt; | ||
390 | List<Vector3> hull = new List<Vector3>(); | ||
391 | |||
392 | for (int i = 0; i < count; i++) | ||
393 | { | ||
394 | ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
395 | ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
396 | ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2; | ||
397 | |||
398 | Vector3 pos = new Vector3( | ||
399 | Utils.UInt16ToFloat(uX, min.X, max.X), | ||
400 | Utils.UInt16ToFloat(uY, min.Y, max.Y), | ||
401 | Utils.UInt16ToFloat(uZ, min.Z, max.Z) | ||
402 | ); | ||
403 | |||
404 | hull.Add(pos); | ||
405 | } | ||
406 | |||
407 | hulls.Add(hull); | ||
408 | } | ||
409 | |||
410 | mConvexHulls = hulls; | ||
411 | } | ||
412 | } | ||
413 | catch (Exception e) | ||
414 | { | ||
415 | m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message); | ||
416 | } | ||
417 | } | ||
418 | |||
366 | if (physicsParms == null) | 419 | if (physicsParms == null) |
367 | { | 420 | { |
368 | m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); | 421 | m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName); |
@@ -381,27 +434,7 @@ namespace OpenSim.Region.Physics.Meshing | |||
381 | // byte[] decompressed = new byte[physSize * 5]; | 434 | // byte[] decompressed = new byte[physSize * 5]; |
382 | try | 435 | try |
383 | { | 436 | { |
384 | using (MemoryStream inMs = new MemoryStream(meshBytes)) | 437 | decodedMeshOsd = DecompressOsd(meshBytes); |
385 | { | ||
386 | using (MemoryStream outMs = new MemoryStream()) | ||
387 | { | ||
388 | using (ZOutputStream zOut = new ZOutputStream(outMs)) | ||
389 | { | ||
390 | byte[] readBuffer = new byte[2048]; | ||
391 | int readLen = 0; | ||
392 | while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) | ||
393 | { | ||
394 | zOut.Write(readBuffer, 0, readLen); | ||
395 | } | ||
396 | zOut.Flush(); | ||
397 | outMs.Seek(0, SeekOrigin.Begin); | ||
398 | |||
399 | byte[] decompressedBuf = outMs.GetBuffer(); | ||
400 | |||
401 | decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); | ||
402 | } | ||
403 | } | ||
404 | } | ||
405 | } | 438 | } |
406 | catch (Exception e) | 439 | catch (Exception e) |
407 | { | 440 | { |
@@ -428,6 +461,41 @@ namespace OpenSim.Region.Physics.Meshing | |||
428 | return true; | 461 | return true; |
429 | } | 462 | } |
430 | 463 | ||
464 | |||
465 | /// <summary> | ||
466 | /// decompresses a gzipped OSD object | ||
467 | /// </summary> | ||
468 | /// <param name="decodedOsd"></param> the OSD object | ||
469 | /// <param name="meshBytes"></param> | ||
470 | /// <returns></returns> | ||
471 | private static OSD DecompressOsd(byte[] meshBytes) | ||
472 | { | ||
473 | OSD decodedOsd = null; | ||
474 | |||
475 | using (MemoryStream inMs = new MemoryStream(meshBytes)) | ||
476 | { | ||
477 | using (MemoryStream outMs = new MemoryStream()) | ||
478 | { | ||
479 | using (ZOutputStream zOut = new ZOutputStream(outMs)) | ||
480 | { | ||
481 | byte[] readBuffer = new byte[2048]; | ||
482 | int readLen = 0; | ||
483 | while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0) | ||
484 | { | ||
485 | zOut.Write(readBuffer, 0, readLen); | ||
486 | } | ||
487 | zOut.Flush(); | ||
488 | outMs.Seek(0, SeekOrigin.Begin); | ||
489 | |||
490 | byte[] decompressedBuf = outMs.GetBuffer(); | ||
491 | |||
492 | decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf); | ||
493 | } | ||
494 | } | ||
495 | } | ||
496 | return decodedOsd; | ||
497 | } | ||
498 | |||
431 | /// <summary> | 499 | /// <summary> |
432 | /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. | 500 | /// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim. |
433 | /// </summary> | 501 | /// </summary> |
@@ -704,6 +772,27 @@ namespace OpenSim.Region.Physics.Meshing | |||
704 | return true; | 772 | return true; |
705 | } | 773 | } |
706 | 774 | ||
775 | /// <summary> | ||
776 | /// temporary prototype code - please do not use until the interface has been finalized! | ||
777 | /// </summary> | ||
778 | /// <param name="size">value to scale the hull points by</param> | ||
779 | /// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns> | ||
780 | public List<List<Vector3>> GetConvexHulls(Vector3 size) | ||
781 | { | ||
782 | if (mConvexHulls == null) | ||
783 | return null; | ||
784 | |||
785 | List<List<Vector3>> hulls = new List<List<Vector3>>(); | ||
786 | foreach (var hull in mConvexHulls) | ||
787 | { | ||
788 | List<Vector3> verts = new List<Vector3>(); | ||
789 | foreach (var vert in hull) | ||
790 | verts.Add(vert * size); | ||
791 | } | ||
792 | |||
793 | return hulls; | ||
794 | } | ||
795 | |||
707 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) | 796 | public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod) |
708 | { | 797 | { |
709 | return CreateMesh(primName, primShape, size, lod, false, true); | 798 | return CreateMesh(primName, primShape, size, lod, false, true); |