Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/SceneObjectPart.cs OpenSim/Region/Physics/BulletSPlugin/BSShapes.csavinationmerge
commit
e2e839a0cd
|
@ -54,7 +54,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public new void Initialise(IConfigSource config)
|
public new void Initialise(IConfigSource config)
|
||||||
{
|
{
|
||||||
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", Name);
|
string umanmod = config.Configs["Modules"].GetString("UserManagementModule", null);
|
||||||
if (umanmod == Name)
|
if (umanmod == Name)
|
||||||
{
|
{
|
||||||
m_Enabled = true;
|
m_Enabled = true;
|
||||||
|
|
|
@ -2197,7 +2197,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (!userExposed)
|
if (!userExposed)
|
||||||
dupe.IsAttachment = true;
|
dupe.IsAttachment = true;
|
||||||
|
|
||||||
dupe.AbsolutePosition = new Vector3(AbsolutePosition.X, AbsolutePosition.Y, AbsolutePosition.Z);
|
dupe.m_sittingAvatars = new List<UUID>();
|
||||||
|
|
||||||
if (!userExposed)
|
if (!userExposed)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2159,6 +2159,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// safeguard actual copy is done in sog.copy
|
// safeguard actual copy is done in sog.copy
|
||||||
dupe.KeyframeMotion = null;
|
dupe.KeyframeMotion = null;
|
||||||
|
dupe.PayPrice = (int[])PayPrice.Clone();
|
||||||
|
|
||||||
dupe.DynAttrs.CopyFrom(DynAttrs);
|
dupe.DynAttrs.CopyFrom(DynAttrs);
|
||||||
|
|
||||||
|
|
|
@ -373,7 +373,7 @@ public static class BSParam
|
||||||
true ),
|
true ),
|
||||||
new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
|
new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
|
||||||
false ),
|
false ),
|
||||||
new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info",
|
new ParameterDefn<bool>("ShouldUseAssetHulls", "If true, use hull if specified in the mesh asset info",
|
||||||
false ),
|
false ),
|
||||||
|
|
||||||
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",
|
||||||
|
|
|
@ -441,12 +441,16 @@ public class BSShapeMesh : BSShape
|
||||||
{
|
{
|
||||||
BulletShape newShape = new BulletShape();
|
BulletShape newShape = new BulletShape();
|
||||||
|
|
||||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
IMesh meshData = null;
|
||||||
false, // say it is not physical so a bounding box is not built
|
lock (physicsScene.mesher)
|
||||||
false, // do not cache the mesh and do not use previously built versions
|
{
|
||||||
false,
|
meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod,
|
||||||
false
|
false, // say it is not physical so a bounding box is not built
|
||||||
);
|
false, // do not cache the mesh and do not use previously built versions
|
||||||
|
false,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (meshData != null)
|
if (meshData != null)
|
||||||
{
|
{
|
||||||
|
@ -578,58 +582,73 @@ public class BSShapeHull : BSShape
|
||||||
BulletShape newShape = new BulletShape();
|
BulletShape newShape = new BulletShape();
|
||||||
newShape.shapeKey = newHullKey;
|
newShape.shapeKey = newHullKey;
|
||||||
|
|
||||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
IMesh meshData = null;
|
||||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
List<List<OMV.Vector3>> allHulls = null;
|
||||||
|
lock (physicsScene.mesher)
|
||||||
// If there is hull data in the mesh asset, build the hull from that
|
|
||||||
if (meshData != null && BSParam.ShouldUseAssetHulls)
|
|
||||||
{
|
{
|
||||||
Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
|
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||||
if (realMesher != null)
|
meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
||||||
|
|
||||||
|
// If we should use the asset's hull info, fetch it out of the locked mesher
|
||||||
|
if (meshData != null && BSParam.ShouldUseAssetHulls)
|
||||||
{
|
{
|
||||||
List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size);
|
Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
|
||||||
if (allHulls != null)
|
if (realMesher != null)
|
||||||
{
|
{
|
||||||
int hullCount = allHulls.Count;
|
allHulls = realMesher.GetConvexHulls(size);
|
||||||
int totalVertices = 1; // include one for the count of the hulls
|
}
|
||||||
// Using the structure described for HACD hulls, create the memory sturcture
|
if (allHulls == null)
|
||||||
// to pass the hull data to the creater.
|
{
|
||||||
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,noAssetHull", prim.LocalID);
|
||||||
{
|
|
||||||
totalVertices += 4; // add four for the vertex count and centroid
|
|
||||||
totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
|
|
||||||
}
|
|
||||||
float[] convHulls = new float[totalVertices];
|
|
||||||
|
|
||||||
convHulls[0] = (float)hullCount;
|
|
||||||
int jj = 1;
|
|
||||||
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
|
||||||
{
|
|
||||||
convHulls[jj + 0] = hullVerts.Count;
|
|
||||||
convHulls[jj + 1] = 0f; // centroid x,y,z
|
|
||||||
convHulls[jj + 2] = 0f;
|
|
||||||
convHulls[jj + 3] = 0f;
|
|
||||||
jj += 4;
|
|
||||||
foreach (OMV.Vector3 oneVert in hullVerts)
|
|
||||||
{
|
|
||||||
convHulls[jj + 0] = oneVert.X;
|
|
||||||
convHulls[jj + 1] = oneVert.Y;
|
|
||||||
convHulls[jj + 2] = oneVert.Z;
|
|
||||||
jj += 3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the hull data structure in Bullet
|
|
||||||
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If there is hull data in the mesh asset, build the hull from that
|
||||||
|
if (allHulls != null && BSParam.ShouldUseAssetHulls)
|
||||||
|
{
|
||||||
|
int hullCount = allHulls.Count;
|
||||||
|
int totalVertices = 1; // include one for the count of the hulls
|
||||||
|
// Using the structure described for HACD hulls, create the memory sturcture
|
||||||
|
// to pass the hull data to the creater.
|
||||||
|
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||||
|
{
|
||||||
|
totalVertices += 4; // add four for the vertex count and centroid
|
||||||
|
totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
|
||||||
|
}
|
||||||
|
float[] convHulls = new float[totalVertices];
|
||||||
|
|
||||||
|
convHulls[0] = (float)hullCount;
|
||||||
|
int jj = 1;
|
||||||
|
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||||
|
{
|
||||||
|
convHulls[jj + 0] = hullVerts.Count;
|
||||||
|
convHulls[jj + 1] = 0f; // centroid x,y,z
|
||||||
|
convHulls[jj + 2] = 0f;
|
||||||
|
convHulls[jj + 3] = 0f;
|
||||||
|
jj += 4;
|
||||||
|
foreach (OMV.Vector3 oneVert in hullVerts)
|
||||||
|
{
|
||||||
|
convHulls[jj + 0] = oneVert.X;
|
||||||
|
convHulls[jj + 1] = oneVert.Y;
|
||||||
|
convHulls[jj + 2] = oneVert.Z;
|
||||||
|
jj += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the hull data structure in Bullet
|
||||||
|
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
||||||
|
|
||||||
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,assetHulls,hulls={1},totVert={2},shape={3}",
|
||||||
|
prim.LocalID, hullCount, totalVertices, newShape);
|
||||||
|
}
|
||||||
|
|
||||||
// If no hull specified in the asset and we should use Bullet's HACD approximation...
|
// If no hull specified in the asset and we should use Bullet's HACD approximation...
|
||||||
if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
|
if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
|
||||||
{
|
{
|
||||||
// Build the hull shape from an existing mesh shape.
|
// Build the hull shape from an existing mesh shape.
|
||||||
// The mesh should have already been created in Bullet.
|
// The mesh should have already been created in Bullet.
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,entry", prim.LocalID);
|
||||||
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
BSShape meshShape = BSShapeMesh.GetReference(physicsScene, true, prim);
|
||||||
|
|
||||||
if (meshShape.physShapeInfo.HasPhysicalShape)
|
if (meshShape.physShapeInfo.HasPhysicalShape)
|
||||||
|
@ -647,127 +666,123 @@ public class BSShapeHull : BSShape
|
||||||
|
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
newShape = physicsScene.PE.BuildHullShapeFromMesh(physicsScene.World, meshShape.physShapeInfo, parms);
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,hullFromMesh,shape={1}", prim.LocalID, newShape);
|
||||||
|
|
||||||
// Now done with the mesh shape.
|
// Now done with the mesh shape.
|
||||||
meshShape.Dereference(physicsScene);
|
meshShape.Dereference(physicsScene);
|
||||||
}
|
}
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,bulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
}
|
}
|
||||||
// If no hull specified, use our HACD hull approximation.
|
|
||||||
if (!newShape.HasPhysicalShape)
|
// If no other hull specifications, use our HACD hull approximation.
|
||||||
|
if (!newShape.HasPhysicalShape && meshData != null)
|
||||||
{
|
{
|
||||||
// Build a new hull in the physical world using the C# HACD algorigthm.
|
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||||
if (meshData != null)
|
|
||||||
{
|
{
|
||||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
// Release the fetched asset data once it has been used.
|
||||||
{
|
pbs.SculptData = new byte[0];
|
||||||
// Release the fetched asset data once it has been used.
|
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
||||||
pbs.SculptData = new byte[0];
|
|
||||||
prim.PrimAssetState = BSPhysObject.PrimAssetCondition.Unknown;
|
|
||||||
}
|
|
||||||
|
|
||||||
int[] indices = meshData.getIndexListAsInt();
|
|
||||||
List<OMV.Vector3> vertices = meshData.getVertexList();
|
|
||||||
|
|
||||||
//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 (BSShapeCollection.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);
|
|
||||||
|
|
||||||
physicsScene.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;
|
|
||||||
|
int[] indices = meshData.getIndexListAsInt();
|
||||||
|
List<OMV.Vector3> vertices = meshData.getVertexList();
|
||||||
|
|
||||||
|
//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 (BSShapeCollection.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);
|
||||||
|
|
||||||
|
physicsScene.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);
|
||||||
}
|
}
|
||||||
return newShape;
|
return newShape;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
public class Meshmerizer : IMesher
|
public class Meshmerizer : IMesher
|
||||||
{
|
{
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private static string LogHeader = "[MESH]";
|
||||||
|
|
||||||
// Setting baseDir to a path will enable the dumping of raw files
|
// Setting baseDir to a path will enable the dumping of raw files
|
||||||
// raw files can be imported by blender so a visual inspection of the results can be done
|
// raw files can be imported by blender so a visual inspection of the results can be done
|
||||||
|
@ -72,6 +73,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
#else
|
#else
|
||||||
private const string baseDir = null; //"rawFiles";
|
private const string baseDir = null; //"rawFiles";
|
||||||
#endif
|
#endif
|
||||||
|
// If 'true', lots of DEBUG logging of asset parsing details
|
||||||
|
private bool debugDetail = true;
|
||||||
|
|
||||||
private bool cacheSculptMaps = true;
|
private bool cacheSculptMaps = true;
|
||||||
private string decodedSculptMapPath = null;
|
private string decodedSculptMapPath = null;
|
||||||
|
@ -80,6 +83,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
||||||
|
|
||||||
private List<List<Vector3>> mConvexHulls = null;
|
private List<List<Vector3>> mConvexHulls = null;
|
||||||
|
private List<Vector3> mBoundingHull = null;
|
||||||
|
|
||||||
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
||||||
|
|
||||||
|
@ -321,6 +325,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
faces = new List<Face>();
|
faces = new List<Face>();
|
||||||
OSD meshOsd = null;
|
OSD meshOsd = null;
|
||||||
|
|
||||||
|
mConvexHulls = null;
|
||||||
|
mBoundingHull = null;
|
||||||
|
|
||||||
if (primShape.SculptData.Length <= 0)
|
if (primShape.SculptData.Length <= 0)
|
||||||
{
|
{
|
||||||
// XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
|
// XXX: At the moment we can not log here since ODEPrim, for instance, ends up triggering this
|
||||||
|
@ -357,26 +364,66 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
OSDMap physicsParms = null;
|
OSDMap physicsParms = null;
|
||||||
OSDMap map = (OSDMap)meshOsd;
|
OSDMap map = (OSDMap)meshOsd;
|
||||||
if (map.ContainsKey("physics_shape"))
|
if (map.ContainsKey("physics_shape"))
|
||||||
|
{
|
||||||
physicsParms = (OSDMap)map["physics_shape"]; // old asset format
|
physicsParms = (OSDMap)map["physics_shape"]; // old asset format
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': using 'physics_shape' mesh data", LogHeader, primName);
|
||||||
|
}
|
||||||
else if (map.ContainsKey("physics_mesh"))
|
else if (map.ContainsKey("physics_mesh"))
|
||||||
|
{
|
||||||
physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
|
physicsParms = (OSDMap)map["physics_mesh"]; // new asset format
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'physics_mesh' mesh data", LogHeader, primName);
|
||||||
|
}
|
||||||
else if (map.ContainsKey("medium_lod"))
|
else if (map.ContainsKey("medium_lod"))
|
||||||
|
{
|
||||||
physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
|
physicsParms = (OSDMap)map["medium_lod"]; // if no physics mesh, try to fall back to medium LOD display mesh
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'medium_lod' mesh data", LogHeader, primName);
|
||||||
|
}
|
||||||
else if (map.ContainsKey("high_lod"))
|
else if (map.ContainsKey("high_lod"))
|
||||||
|
{
|
||||||
physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
|
physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}':using 'high_lod' mesh data", LogHeader, primName);
|
||||||
|
}
|
||||||
|
|
||||||
if (map.ContainsKey("physics_convex"))
|
if (map.ContainsKey("physics_convex"))
|
||||||
{ // pull this out also in case physics engine can use it
|
{ // pull this out also in case physics engine can use it
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
OSDMap convexBlock = (OSDMap)map["physics_convex"];
|
OSDMap convexBlock = (OSDMap)map["physics_convex"];
|
||||||
|
|
||||||
|
Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
|
||||||
|
if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
|
||||||
|
Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
|
||||||
|
|
||||||
|
List<Vector3> boundingHull = null;
|
||||||
|
|
||||||
|
if (convexBlock.ContainsKey("BoundingVerts"))
|
||||||
|
{
|
||||||
|
// decompress and decode bounding hull points
|
||||||
|
byte[] boundingVertsBytes = DecompressOsd(convexBlock["BoundingVerts"].AsBinary()).AsBinary();
|
||||||
|
boundingHull = new List<Vector3>();
|
||||||
|
for (int i = 0; i < boundingVertsBytes.Length;)
|
||||||
|
{
|
||||||
|
ushort uX = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||||
|
ushort uY = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||||
|
ushort uZ = Utils.BytesToUInt16(boundingVertsBytes, i); i += 2;
|
||||||
|
|
||||||
|
Vector3 pos = new Vector3(
|
||||||
|
Utils.UInt16ToFloat(uX, min.X, max.X),
|
||||||
|
Utils.UInt16ToFloat(uY, min.Y, max.Y),
|
||||||
|
Utils.UInt16ToFloat(uZ, min.Z, max.Z)
|
||||||
|
);
|
||||||
|
|
||||||
|
boundingHull.Add(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
mBoundingHull = boundingHull;
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed bounding hull. nHulls={2}", LogHeader, primName, mBoundingHull.Count);
|
||||||
|
}
|
||||||
|
|
||||||
if (convexBlock.ContainsKey("HullList"))
|
if (convexBlock.ContainsKey("HullList"))
|
||||||
{
|
{
|
||||||
byte[] hullList = convexBlock["HullList"].AsBinary();
|
byte[] hullList = convexBlock["HullList"].AsBinary();
|
||||||
Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
|
|
||||||
if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
|
|
||||||
Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
|
|
||||||
if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
|
|
||||||
|
|
||||||
// decompress and decode hull points
|
// decompress and decode hull points
|
||||||
byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
|
byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
|
||||||
|
@ -408,11 +455,16 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
}
|
}
|
||||||
|
|
||||||
mConvexHulls = hulls;
|
mConvexHulls = hulls;
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}': parsed hulls. nHulls={2}", LogHeader, primName, mConvexHulls.Count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (debugDetail) m_log.DebugFormat("{0} prim='{1}' has physics_convex but no HullList", LogHeader, primName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message);
|
m_log.WarnFormat("{0} exception decoding convex block: {1}", LogHeader, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,7 +490,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[MESH]: exception decoding physical mesh: " + e.ToString());
|
m_log.ErrorFormat("{0} prim='{1}': exception decoding physical mesh: {2}", LogHeader, primName, e);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,6 +507,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
if (subMeshOsd is OSDMap)
|
if (subMeshOsd is OSDMap)
|
||||||
AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
|
AddSubMesh(subMeshOsd as OSDMap, size, coords, faces);
|
||||||
}
|
}
|
||||||
|
if (debugDetail)
|
||||||
|
m_log.DebugFormat("{0} {1}: mesh decoded. offset={2}, size={3}, nCoords={4}, nFaces={5}",
|
||||||
|
LogHeader, primName, physOffset, physSize, coords.Count, faces.Count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -772,6 +827,23 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// temporary prototype code - please do not use until the interface has been finalized!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">value to scale the hull points by</param>
|
||||||
|
/// <returns>a list of vertices in the bounding hull if it exists and has been successfully decoded, otherwise null</returns>
|
||||||
|
public List<Vector3> GetBoundingHull(Vector3 size)
|
||||||
|
{
|
||||||
|
if (mBoundingHull == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<Vector3> verts = new List<Vector3>();
|
||||||
|
foreach (var vert in mBoundingHull)
|
||||||
|
verts.Add(vert * size);
|
||||||
|
|
||||||
|
return verts;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// temporary prototype code - please do not use until the interface has been finalized!
|
/// temporary prototype code - please do not use until the interface has been finalized!
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
Loading…
Reference in New Issue