BulletSim: add Bullet HACD library invocation. Turned off by default as not
totally debugged. Updated DLLs and SOs with more debugged HACD library code.user_profiles
parent
17fd075f39
commit
59135c9a31
|
@ -86,6 +86,7 @@ public static class BSParam
|
||||||
public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
|
public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
|
||||||
public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
|
public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
|
||||||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||||
|
public static bool ShouldUseBulletHACD { get; set; }
|
||||||
|
|
||||||
public static float TerrainImplementation { get; private set; }
|
public static float TerrainImplementation { get; private set; }
|
||||||
public static int TerrainMeshMagnification { get; private set; }
|
public static int TerrainMeshMagnification { get; private set; }
|
||||||
|
@ -149,6 +150,15 @@ public static class BSParam
|
||||||
public static float CSHullVolumeConservationThresholdPercent { get; private set; }
|
public static float CSHullVolumeConservationThresholdPercent { get; private set; }
|
||||||
public static int CSHullMaxVertices { get; private set; }
|
public static int CSHullMaxVertices { get; private set; }
|
||||||
public static float CSHullMaxSkinWidth { get; private set; }
|
public static float CSHullMaxSkinWidth { get; private set; }
|
||||||
|
public static float BHullMaxVerticesPerHull { get; private set; } // 100
|
||||||
|
public static float BHullMinClusters { get; private set; } // 2
|
||||||
|
public static float BHullCompacityWeight { get; private set; } // 0.1
|
||||||
|
public static float BHullVolumeWeight { get; private set; } // 0.0
|
||||||
|
public static float BHullConcavity { get; private set; } // 100
|
||||||
|
public static bool BHullAddExtraDistPoints { get; private set; } // false
|
||||||
|
public static bool BHullAddNeighboursDistPoints { get; private set; } // false
|
||||||
|
public static bool BHullAddFacesPoints { get; private set; } // false
|
||||||
|
public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
|
||||||
|
|
||||||
// Linkset implementation parameters
|
// Linkset implementation parameters
|
||||||
public static float LinksetImplementation { get; private set; }
|
public static float LinksetImplementation { get; private set; }
|
||||||
|
@ -325,6 +335,10 @@ public static class BSParam
|
||||||
true,
|
true,
|
||||||
(s) => { return ShouldRemoveZeroWidthTriangles; },
|
(s) => { return ShouldRemoveZeroWidthTriangles; },
|
||||||
(s,v) => { ShouldRemoveZeroWidthTriangles = v; } ),
|
(s,v) => { ShouldRemoveZeroWidthTriangles = v; } ),
|
||||||
|
new ParameterDefn<bool>("ShouldUseBulletHACD", "If true, use the Bullet version of HACD",
|
||||||
|
false,
|
||||||
|
(s) => { return ShouldUseBulletHACD; },
|
||||||
|
(s,v) => { ShouldUseBulletHACD = v; } ),
|
||||||
|
|
||||||
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
||||||
5,
|
5,
|
||||||
|
@ -663,10 +677,47 @@ public static class BSParam
|
||||||
(s) => { return CSHullMaxVertices; },
|
(s) => { return CSHullMaxVertices; },
|
||||||
(s,v) => { CSHullMaxVertices = v; } ),
|
(s,v) => { CSHullMaxVertices = v; } ),
|
||||||
new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
|
new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
|
||||||
0,
|
0f,
|
||||||
(s) => { return CSHullMaxSkinWidth; },
|
(s) => { return CSHullMaxSkinWidth; },
|
||||||
(s,v) => { CSHullMaxSkinWidth = v; } ),
|
(s,v) => { CSHullMaxSkinWidth = v; } ),
|
||||||
|
|
||||||
|
new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
|
||||||
|
100f,
|
||||||
|
(s) => { return BHullMaxVerticesPerHull; },
|
||||||
|
(s,v) => { BHullMaxVerticesPerHull = v; } ),
|
||||||
|
new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
|
||||||
|
2f,
|
||||||
|
(s) => { return BHullMinClusters; },
|
||||||
|
(s,v) => { BHullMinClusters = v; } ),
|
||||||
|
new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
|
||||||
|
2f,
|
||||||
|
(s) => { return BHullCompacityWeight; },
|
||||||
|
(s,v) => { BHullCompacityWeight = v; } ),
|
||||||
|
new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
|
||||||
|
0.1f,
|
||||||
|
(s) => { return BHullVolumeWeight; },
|
||||||
|
(s,v) => { BHullVolumeWeight = v; } ),
|
||||||
|
new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
|
||||||
|
100f,
|
||||||
|
(s) => { return BHullConcavity; },
|
||||||
|
(s,v) => { BHullConcavity = v; } ),
|
||||||
|
new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
|
||||||
|
false,
|
||||||
|
(s) => { return BHullAddExtraDistPoints; },
|
||||||
|
(s,v) => { BHullAddExtraDistPoints = v; } ),
|
||||||
|
new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
|
||||||
|
false,
|
||||||
|
(s) => { return BHullAddNeighboursDistPoints; },
|
||||||
|
(s,v) => { BHullAddNeighboursDistPoints = v; } ),
|
||||||
|
new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
|
||||||
|
false,
|
||||||
|
(s) => { return BHullAddFacesPoints; },
|
||||||
|
(s,v) => { BHullAddFacesPoints = v; } ),
|
||||||
|
new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
|
||||||
|
false,
|
||||||
|
(s) => { return BHullShouldAdjustCollisionMargin; },
|
||||||
|
(s,v) => { BHullShouldAdjustCollisionMargin = v; } ),
|
||||||
|
|
||||||
new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
||||||
(float)BSLinkset.LinksetImplementation.Compound,
|
(float)BSLinkset.LinksetImplementation.Compound,
|
||||||
(s) => { return LinksetImplementation; },
|
(s) => { return LinksetImplementation; },
|
||||||
|
|
|
@ -316,6 +316,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
break;
|
break;
|
||||||
case "bulletxna":
|
case "bulletxna":
|
||||||
ret = new BSAPIXNA(engineName, this);
|
ret = new BSAPIXNA(engineName, this);
|
||||||
|
BSParam.ShouldUseBulletHACD = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -720,7 +720,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
// Remove usage of the previous shape.
|
// Remove usage of the previous shape.
|
||||||
DereferenceShape(prim.PhysShape, shapeCallback);
|
DereferenceShape(prim.PhysShape, shapeCallback);
|
||||||
|
|
||||||
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
|
newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||||
// It might not have been created if we're waiting for an asset.
|
// It might not have been created if we're waiting for an asset.
|
||||||
newShape = VerifyMeshCreated(newShape, prim);
|
newShape = VerifyMeshCreated(newShape, prim);
|
||||||
|
|
||||||
|
@ -731,7 +731,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ConvexResult> m_hulls;
|
List<ConvexResult> m_hulls;
|
||||||
private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
private BulletShape CreatePhysicalHull(BSPhysObject prim, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||||
{
|
{
|
||||||
|
|
||||||
BulletShape newShape = new BulletShape();
|
BulletShape newShape = new BulletShape();
|
||||||
|
@ -745,115 +745,152 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Build a new hull in the physical world.
|
if (BSParam.ShouldUseBulletHACD)
|
||||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
|
||||||
IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
|
||||||
if (meshData != null)
|
|
||||||
{
|
{
|
||||||
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
||||||
int[] indices = meshData.getIndexListAsInt();
|
MeshDesc meshDesc;
|
||||||
List<OMV.Vector3> vertices = meshData.getVertexList();
|
if (!Meshes.TryGetValue(newHullKey, out meshDesc))
|
||||||
|
|
||||||
//format conversion from IMesh format to DecompDesc format
|
|
||||||
List<int> convIndices = new List<int>();
|
|
||||||
List<float3> convVertices = new List<float3>();
|
|
||||||
for (int ii = 0; ii < indices.GetLength(0); ii++)
|
|
||||||
{
|
{
|
||||||
convIndices.Add(indices[ii]);
|
// That's odd because the mesh should have been created before the hull
|
||||||
}
|
// but, since it doesn't exist, create it.
|
||||||
foreach (OMV.Vector3 vv in vertices)
|
newShape = CreatePhysicalMesh(prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||||
{
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,noMeshBuiltNew,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
|
if (newShape.HasPhysicalShape)
|
||||||
if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
|
|
||||||
{
|
|
||||||
// Simple primitive shapes we know are convex so they are better implemented with
|
|
||||||
// fewer hulls.
|
|
||||||
// Check for simple shape (prim without cuts) and reduce split parameter if so.
|
|
||||||
if (PrimHasNoCuts(pbs))
|
|
||||||
{
|
{
|
||||||
maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
|
ReferenceShape(newShape);
|
||||||
|
Meshes.TryGetValue(newHullKey, out meshDesc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (meshDesc.shape.HasPhysicalShape)
|
||||||
// setup and do convex hull conversion
|
|
||||||
m_hulls = new List<ConvexResult>();
|
|
||||||
DecompDesc dcomp = new DecompDesc();
|
|
||||||
dcomp.mIndices = convIndices;
|
|
||||||
dcomp.mVertices = convVertices;
|
|
||||||
dcomp.mDepth = maxDepthSplit;
|
|
||||||
dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
|
|
||||||
dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
|
|
||||||
dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
|
|
||||||
dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
|
|
||||||
ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
|
|
||||||
// create the hull into the _hulls variable
|
|
||||||
convexBuilder.process(dcomp);
|
|
||||||
|
|
||||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
|
|
||||||
BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
|
|
||||||
|
|
||||||
// Convert the vertices and indices for passing to unmanaged.
|
|
||||||
// The hull information is passed as a large floating point array.
|
|
||||||
// The format is:
|
|
||||||
// convHulls[0] = number of hulls
|
|
||||||
// convHulls[1] = number of vertices in first hull
|
|
||||||
// convHulls[2] = hull centroid X coordinate
|
|
||||||
// convHulls[3] = hull centroid Y coordinate
|
|
||||||
// convHulls[4] = hull centroid Z coordinate
|
|
||||||
// convHulls[5] = first hull vertex X
|
|
||||||
// convHulls[6] = first hull vertex Y
|
|
||||||
// convHulls[7] = first hull vertex Z
|
|
||||||
// convHulls[8] = second hull vertex X
|
|
||||||
// ...
|
|
||||||
// convHulls[n] = number of vertices in second hull
|
|
||||||
// convHulls[n+1] = second hull centroid X coordinate
|
|
||||||
// ...
|
|
||||||
//
|
|
||||||
// TODO: is is very inefficient. Someday change the convex hull generator to return
|
|
||||||
// data structures that do not need to be converted in order to pass to Bullet.
|
|
||||||
// And maybe put the values directly into pinned memory rather than marshaling.
|
|
||||||
int hullCount = m_hulls.Count;
|
|
||||||
int totalVertices = 1; // include one for the count of the hulls
|
|
||||||
foreach (ConvexResult cr in m_hulls)
|
|
||||||
{
|
{
|
||||||
totalVertices += 4; // add four for the vertex count and centroid
|
HACDParams parms;
|
||||||
totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
|
parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
|
||||||
}
|
parms.minClusters = BSParam.BHullMinClusters;
|
||||||
float[] convHulls = new float[totalVertices];
|
parms.compacityWeight = BSParam.BHullCompacityWeight;
|
||||||
|
parms.volumeWeight = BSParam.BHullVolumeWeight;
|
||||||
|
parms.concavity = BSParam.BHullConcavity;
|
||||||
|
parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
|
||||||
|
parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
|
||||||
|
parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
|
||||||
|
parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
|
||||||
|
|
||||||
convHulls[0] = (float)hullCount;
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
int jj = 1;
|
newShape = PhysicsScene.PE.BuildHullShapeFromMesh(PhysicsScene.World, meshDesc.shape, parms);
|
||||||
foreach (ConvexResult cr in m_hulls)
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
{
|
|
||||||
// copy vertices for index access
|
|
||||||
float3[] verts = new float3[cr.HullVertices.Count];
|
|
||||||
int kk = 0;
|
|
||||||
foreach (float3 ff in cr.HullVertices)
|
|
||||||
{
|
|
||||||
verts[kk++] = ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// add to the array one hull's worth of data
|
|
||||||
convHulls[jj++] = cr.HullIndices.Count;
|
|
||||||
convHulls[jj++] = 0f; // centroid x,y,z
|
|
||||||
convHulls[jj++] = 0f;
|
|
||||||
convHulls[jj++] = 0f;
|
|
||||||
foreach (int ind in cr.HullIndices)
|
|
||||||
{
|
|
||||||
convHulls[jj++] = verts[ind].x;
|
|
||||||
convHulls[jj++] = verts[ind].y;
|
|
||||||
convHulls[jj++] = verts[ind].z;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// create the hull data structure in Bullet
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
|
|
||||||
}
|
}
|
||||||
}
|
if (!newShape.HasPhysicalShape)
|
||||||
|
{
|
||||||
|
// Build a new hull in the physical world.
|
||||||
|
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||||
|
IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */);
|
||||||
|
if (meshData != null)
|
||||||
|
{
|
||||||
|
int[] indices = meshData.getIndexListAsInt();
|
||||||
|
List<OMV.Vector3> vertices = meshData.getVertexList();
|
||||||
|
|
||||||
newShape.shapeKey = newHullKey;
|
//format conversion from IMesh format to DecompDesc format
|
||||||
|
List<int> convIndices = new List<int>();
|
||||||
|
List<float3> convVertices = new List<float3>();
|
||||||
|
for (int ii = 0; ii < indices.GetLength(0); ii++)
|
||||||
|
{
|
||||||
|
convIndices.Add(indices[ii]);
|
||||||
|
}
|
||||||
|
foreach (OMV.Vector3 vv in vertices)
|
||||||
|
{
|
||||||
|
convVertices.Add(new float3(vv.X, vv.Y, vv.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplit;
|
||||||
|
if (BSParam.CSHullMaxDepthSplit != BSParam.CSHullMaxDepthSplitForSimpleShapes)
|
||||||
|
{
|
||||||
|
// Simple primitive shapes we know are convex so they are better implemented with
|
||||||
|
// fewer hulls.
|
||||||
|
// Check for simple shape (prim without cuts) and reduce split parameter if so.
|
||||||
|
if (PrimHasNoCuts(pbs))
|
||||||
|
{
|
||||||
|
maxDepthSplit = (uint)BSParam.CSHullMaxDepthSplitForSimpleShapes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// setup and do convex hull conversion
|
||||||
|
m_hulls = new List<ConvexResult>();
|
||||||
|
DecompDesc dcomp = new DecompDesc();
|
||||||
|
dcomp.mIndices = convIndices;
|
||||||
|
dcomp.mVertices = convVertices;
|
||||||
|
dcomp.mDepth = maxDepthSplit;
|
||||||
|
dcomp.mCpercent = BSParam.CSHullConcavityThresholdPercent;
|
||||||
|
dcomp.mPpercent = BSParam.CSHullVolumeConservationThresholdPercent;
|
||||||
|
dcomp.mMaxVertices = (uint)BSParam.CSHullMaxVertices;
|
||||||
|
dcomp.mSkinWidth = BSParam.CSHullMaxSkinWidth;
|
||||||
|
ConvexBuilder convexBuilder = new ConvexBuilder(HullReturn);
|
||||||
|
// create the hull into the _hulls variable
|
||||||
|
convexBuilder.process(dcomp);
|
||||||
|
|
||||||
|
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,key={1},inVert={2},inInd={3},split={4},hulls={5}",
|
||||||
|
BSScene.DetailLogZero, newHullKey, indices.GetLength(0), vertices.Count, maxDepthSplit, m_hulls.Count);
|
||||||
|
|
||||||
|
// Convert the vertices and indices for passing to unmanaged.
|
||||||
|
// The hull information is passed as a large floating point array.
|
||||||
|
// The format is:
|
||||||
|
// convHulls[0] = number of hulls
|
||||||
|
// convHulls[1] = number of vertices in first hull
|
||||||
|
// convHulls[2] = hull centroid X coordinate
|
||||||
|
// convHulls[3] = hull centroid Y coordinate
|
||||||
|
// convHulls[4] = hull centroid Z coordinate
|
||||||
|
// convHulls[5] = first hull vertex X
|
||||||
|
// convHulls[6] = first hull vertex Y
|
||||||
|
// convHulls[7] = first hull vertex Z
|
||||||
|
// convHulls[8] = second hull vertex X
|
||||||
|
// ...
|
||||||
|
// convHulls[n] = number of vertices in second hull
|
||||||
|
// convHulls[n+1] = second hull centroid X coordinate
|
||||||
|
// ...
|
||||||
|
//
|
||||||
|
// TODO: is is very inefficient. Someday change the convex hull generator to return
|
||||||
|
// data structures that do not need to be converted in order to pass to Bullet.
|
||||||
|
// And maybe put the values directly into pinned memory rather than marshaling.
|
||||||
|
int hullCount = m_hulls.Count;
|
||||||
|
int totalVertices = 1; // include one for the count of the hulls
|
||||||
|
foreach (ConvexResult cr in m_hulls)
|
||||||
|
{
|
||||||
|
totalVertices += 4; // add four for the vertex count and centroid
|
||||||
|
totalVertices += cr.HullIndices.Count * 3; // we pass just triangles
|
||||||
|
}
|
||||||
|
float[] convHulls = new float[totalVertices];
|
||||||
|
|
||||||
|
convHulls[0] = (float)hullCount;
|
||||||
|
int jj = 1;
|
||||||
|
foreach (ConvexResult cr in m_hulls)
|
||||||
|
{
|
||||||
|
// copy vertices for index access
|
||||||
|
float3[] verts = new float3[cr.HullVertices.Count];
|
||||||
|
int kk = 0;
|
||||||
|
foreach (float3 ff in cr.HullVertices)
|
||||||
|
{
|
||||||
|
verts[kk++] = ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add to the array one hull's worth of data
|
||||||
|
convHulls[jj++] = cr.HullIndices.Count;
|
||||||
|
convHulls[jj++] = 0f; // centroid x,y,z
|
||||||
|
convHulls[jj++] = 0f;
|
||||||
|
convHulls[jj++] = 0f;
|
||||||
|
foreach (int ind in cr.HullIndices)
|
||||||
|
{
|
||||||
|
convHulls[jj++] = verts[ind].x;
|
||||||
|
convHulls[jj++] = verts[ind].y;
|
||||||
|
convHulls[jj++] = verts[ind].z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// create the hull data structure in Bullet
|
||||||
|
newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
newShape.shapeKey = newHullKey;
|
||||||
|
}
|
||||||
|
|
||||||
return newShape;
|
return newShape;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue