Merge branch 'master' of ssh://justincc@opensimulator.org/var/git/opensim

This commit is contained in:
Justin Clark-Casey (justincc)
2009-11-03 19:11:09 +00:00
108 changed files with 2901 additions and 4563 deletions

View File

@@ -52,6 +52,20 @@ namespace OpenSim.Region.Physics.Manager
, Absolute
}
public struct ContactPoint
{
public Vector3 Position;
public Vector3 SurfaceNormal;
public float PenetrationDepth;
public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
{
Position = position;
SurfaceNormal = surfaceNormal;
PenetrationDepth = penetrationDepth;
}
}
public class CollisionEventUpdate : EventArgs
{
// Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
@@ -59,9 +73,9 @@ namespace OpenSim.Region.Physics.Manager
public int m_colliderType;
public int m_GenericStartEnd;
//public uint m_LocalID;
public Dictionary<uint,float> m_objCollisionList = new Dictionary<uint,float>();
public Dictionary<uint, ContactPoint> m_objCollisionList = new Dictionary<uint, ContactPoint>();
public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary<uint, float> objCollisionList)
public CollisionEventUpdate(uint localID, int colliderType, int GenericStartEnd, Dictionary<uint, ContactPoint> objCollisionList)
{
m_colliderType = colliderType;
m_GenericStartEnd = GenericStartEnd;
@@ -72,8 +86,7 @@ namespace OpenSim.Region.Physics.Manager
{
m_colliderType = (int) ActorTypes.Unknown;
m_GenericStartEnd = 1;
// m_objCollisionList = null;
m_objCollisionList = new Dictionary<uint, float>();
m_objCollisionList = new Dictionary<uint, ContactPoint>();
}
public int collidertype
@@ -88,16 +101,16 @@ namespace OpenSim.Region.Physics.Manager
set { m_GenericStartEnd = value; }
}
public void addCollider(uint localID, float depth)
public void addCollider(uint localID, ContactPoint contact)
{
if (!m_objCollisionList.ContainsKey(localID))
{
m_objCollisionList.Add(localID, depth);
m_objCollisionList.Add(localID, contact);
}
else
{
if (m_objCollisionList[localID] < depth)
m_objCollisionList[localID] = depth;
if (m_objCollisionList[localID].PenetrationDepth < contact.PenetrationDepth)
m_objCollisionList[localID] = contact;
}
}
}

View File

@@ -75,6 +75,11 @@ namespace OpenSim.Region.Physics.Manager
public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
Vector3 size, Quaternion rotation, bool isPhysical);
public virtual float TimeDilation
{
get { return 1.0f; }
}
public virtual bool SupportsNINJAJoints
{
get { return false; }

View File

@@ -284,9 +284,13 @@ namespace OpenSim.Region.Physics.Meshing
try
{
idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
OpenMetaverse.Imaging.ManagedImage unusedData;
OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
unusedData = null;
if (cacheSculptMaps)
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
if (cacheSculptMaps && idata != null)
{
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
@@ -299,12 +303,12 @@ namespace OpenSim.Region.Physics.Meshing
}
catch (IndexOutOfRangeException)
{
m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
m_log.Error("[PHYSICS]: OpenJpeg was unable to decode this. Physics Proxy generation failed");
return null;
}
catch (Exception)
catch (Exception ex)
{
m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed!");
m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
return null;
}
}

View File

@@ -67,11 +67,6 @@ namespace PrimMesher
Normalize();
}
public Quat Identity()
{
return new Quat(0.0f, 0.0f, 0.0f, 1.0f);
}
public float Length()
{
return (float)Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
@@ -660,7 +655,7 @@ namespace PrimMesher
this.faceNumbers = new List<int>();
Coord center = new Coord(0.0f, 0.0f, 0.0f);
bool hasCenter = false;
//bool hasCenter = false;
List<Coord> hollowCoords = new List<Coord>();
List<Coord> hollowNormals = new List<Coord>();
@@ -727,7 +722,7 @@ namespace PrimMesher
else if (!simpleFace)
{
this.coords.Add(center);
hasCenter = true;
//hasCenter = true;
if (this.calcVertexNormals)
this.vertexNormals.Add(new Coord(0.0f, 0.0f, 1.0f));
this.us.Add(0.0f);
@@ -1541,7 +1536,7 @@ namespace PrimMesher
}
/// <summary>
/// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
/// Extrudes a profile along a path.
/// </summary>
public void Extrude(PathType pathType)
{
@@ -1557,7 +1552,6 @@ namespace PrimMesher
if (this.calcVertexNormals)
this.normals = new List<Coord>();
//int step = 0;
int steps = 1;
float length = this.pathCutEnd - this.pathCutBegin;
@@ -1579,20 +1573,6 @@ namespace PrimMesher
if (twistTotalAbs > 0.01f)
steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
//float start = -0.5f;
//float stepSize = length / (float)steps;
//float percentOfPathMultiplier = stepSize;
//float xProfileScale = 1.0f;
//float yProfileScale = 1.0f;
//float xOffset = 0.0f;
//float yOffset = 0.0f;
//float zOffset = start;
//float xOffsetStepIncrement = this.topShearX / steps;
//float yOffsetStepIncrement = this.topShearY / steps;
//float percentOfPath = this.pathCutBegin;
//zOffset += percentOfPath;
float hollow = this.hollow;
// sanity checks
@@ -1662,7 +1642,6 @@ namespace PrimMesher
cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
}
if (initialProfileRot != 0.0f)
{
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
@@ -1693,24 +1672,6 @@ namespace PrimMesher
path.stepsPerRevolution = stepsPerRevolution;
path.Create(pathType, steps);
/*
public int twistBegin = 0;
public int twistEnd = 0;
public float topShearX = 0.0f;
public float topShearY = 0.0f;
public float pathCutBegin = 0.0f;
public float pathCutEnd = 1.0f;
public float dimpleBegin = 0.0f;
public float dimpleEnd = 1.0f;
public float skew = 0.0f;
public float holeSizeX = 1.0f; // called pathScaleX in pbs
public float holeSizeY = 0.25f;
public float taperX = 0.0f;
public float taperY = 0.0f;
public float radius = 0.0f;
public float revolutions = 1.0f;
public int stepsPerRevolution = 24;
*/
bool needEndFaces = false;
if (pathType == PathType.Circular)
@@ -1796,7 +1757,6 @@ namespace PrimMesher
int numVerts = newLayer.coords.Count;
Face newFace = new Face();
//if (step > 0)
if (nodeIndex > 0)
{
int startVert = coordsLen + 1;
@@ -1812,7 +1772,6 @@ namespace PrimMesher
iNext = startVert;
int whichVert = i - startVert;
//int whichVert2 = i - lastCoordsLen;
newFace.v1 = i;
newFace.v2 = i - numVerts;
@@ -1982,809 +1941,27 @@ namespace PrimMesher
/// <summary>
/// DEPRICATED - use Extrude(PathType.Linear) instead
/// Extrudes a profile along a straight line path. Used for prim types box, cylinder, and prism.
/// </summary>
///
public void ExtrudeLinear()
{
this.coords = new List<Coord>();
this.faces = new List<Face>();
if (this.viewerMode)
{
this.viewerFaces = new List<ViewerFace>();
this.calcVertexNormals = true;
}
if (this.calcVertexNormals)
this.normals = new List<Coord>();
int step = 0;
int steps = 1;
float length = this.pathCutEnd - this.pathCutBegin;
normalsProcessed = false;
if (this.viewerMode && this.sides == 3)
{
// prisms don't taper well so add some vertical resolution
// other prims may benefit from this but just do prisms for now
if (Math.Abs(this.taperX) > 0.01 || Math.Abs(this.taperY) > 0.01)
steps = (int)(steps * 4.5 * length);
}
float twistBegin = this.twistBegin / 360.0f * twoPi;
float twistEnd = this.twistEnd / 360.0f * twoPi;
float twistTotal = twistEnd - twistBegin;
float twistTotalAbs = Math.Abs(twistTotal);
if (twistTotalAbs > 0.01f)
steps += (int)(twistTotalAbs * 3.66); // dahlia's magic number
float start = -0.5f;
float stepSize = length / (float)steps;
float percentOfPathMultiplier = stepSize;
float xProfileScale = 1.0f;
float yProfileScale = 1.0f;
float xOffset = 0.0f;
float yOffset = 0.0f;
float zOffset = start;
float xOffsetStepIncrement = this.topShearX / steps;
float yOffsetStepIncrement = this.topShearY / steps;
float percentOfPath = this.pathCutBegin;
zOffset += percentOfPath;
float hollow = this.hollow;
// sanity checks
float initialProfileRot = 0.0f;
if (this.sides == 3)
{
if (this.hollowSides == 4)
{
if (hollow > 0.7f)
hollow = 0.7f;
hollow *= 0.707f;
}
else hollow *= 0.5f;
}
else if (this.sides == 4)
{
initialProfileRot = 1.25f * (float)Math.PI;
if (this.hollowSides != 4)
hollow *= 0.707f;
}
else if (this.sides == 24 && this.hollowSides == 4)
hollow *= 1.414f;
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, true, calcVertexNormals);
this.errorMessage = profile.errorMessage;
this.numPrimFaces = profile.numPrimFaces;
int cut1Vert = -1;
int cut2Vert = -1;
if (hasProfileCut)
{
cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
}
if (initialProfileRot != 0.0f)
{
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
if (viewerMode)
profile.MakeFaceUVs();
}
Coord lastCutNormal1 = new Coord();
Coord lastCutNormal2 = new Coord();
float lastV = 1.0f;
bool done = false;
while (!done)
{
Profile newLayer = profile.Copy();
if (this.taperX == 0.0f)
xProfileScale = 1.0f;
else if (this.taperX > 0.0f)
xProfileScale = 1.0f - percentOfPath * this.taperX;
else xProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperX;
if (this.taperY == 0.0f)
yProfileScale = 1.0f;
else if (this.taperY > 0.0f)
yProfileScale = 1.0f - percentOfPath * this.taperY;
else yProfileScale = 1.0f + (1.0f - percentOfPath) * this.taperY;
if (xProfileScale != 1.0f || yProfileScale != 1.0f)
newLayer.Scale(xProfileScale, yProfileScale);
float twist = twistBegin + twistTotal * percentOfPath;
if (twist != 0.0f)
newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
newLayer.AddPos(xOffset, yOffset, zOffset);
if (step == 0)
{
newLayer.FlipNormals();
// add the top faces to the viewerFaces list here
if (this.viewerMode)
{
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace(profile.bottomFaceNumber);
int numFaces = newLayer.faces.Count;
List<Face> faces = newLayer.faces;
for (int i = 0; i < numFaces; i++)
{
Face face = faces[i];
newViewerFace.v1 = newLayer.coords[face.v1];
newViewerFace.v2 = newLayer.coords[face.v2];
newViewerFace.v3 = newLayer.coords[face.v3];
newViewerFace.coordIndex1 = face.v1;
newViewerFace.coordIndex2 = face.v2;
newViewerFace.coordIndex3 = face.v3;
newViewerFace.n1 = faceNormal;
newViewerFace.n2 = faceNormal;
newViewerFace.n3 = faceNormal;
newViewerFace.uv1 = newLayer.faceUVs[face.v1];
newViewerFace.uv2 = newLayer.faceUVs[face.v2];
newViewerFace.uv3 = newLayer.faceUVs[face.v3];
this.viewerFaces.Add(newViewerFace);
}
}
}
// append this layer
int coordsLen = this.coords.Count;
int lastCoordsLen = coordsLen;
newLayer.AddValue2FaceVertexIndices(coordsLen);
this.coords.AddRange(newLayer.coords);
if (this.calcVertexNormals)
{
newLayer.AddValue2FaceNormalIndices(this.normals.Count);
this.normals.AddRange(newLayer.vertexNormals);
}
if (percentOfPath < this.pathCutBegin + 0.01f || percentOfPath > this.pathCutEnd - 0.01f)
this.faces.AddRange(newLayer.faces);
// fill faces between layers
int numVerts = newLayer.coords.Count;
Face newFace = new Face();
if (step > 0)
{
int startVert = coordsLen + 1;
int endVert = this.coords.Count;
if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
startVert--;
for (int i = startVert; i < endVert; i++)
{
int iNext = i + 1;
if (i == endVert - 1)
iNext = startVert;
int whichVert = i - startVert;
//int whichVert2 = i - lastCoordsLen;
newFace.v1 = i;
newFace.v2 = i - numVerts;
newFace.v3 = iNext - numVerts;
this.faces.Add(newFace);
newFace.v2 = iNext - numVerts;
newFace.v3 = iNext;
this.faces.Add(newFace);
if (this.viewerMode)
{
// add the side faces to the list of viewerFaces here
//int primFaceNum = 1;
//if (whichVert >= sides)
// primFaceNum = 2;
int primFaceNum = profile.faceNumbers[whichVert];
ViewerFace newViewerFace1 = new ViewerFace(primFaceNum);
ViewerFace newViewerFace2 = new ViewerFace(primFaceNum);
float u1 = newLayer.us[whichVert];
float u2 = 1.0f;
if (whichVert < newLayer.us.Count - 1)
u2 = newLayer.us[whichVert + 1];
if (whichVert == cut1Vert || whichVert == cut2Vert)
{
u1 = 0.0f;
u2 = 1.0f;
}
else if (sides < 5)
{ // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
// to reflect the entire texture width
u1 *= sides;
u2 *= sides;
u2 -= (int)u1;
u1 -= (int)u1;
if (u2 < 0.1f)
u2 = 1.0f;
//newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1;
newViewerFace1.uv2.U = u1;
newViewerFace1.uv3.U = u2;
newViewerFace1.uv1.V = 1.0f - percentOfPath;
newViewerFace1.uv2.V = lastV;
newViewerFace1.uv3.V = lastV;
newViewerFace2.uv1.U = u1;
newViewerFace2.uv2.U = u2;
newViewerFace2.uv3.U = u2;
newViewerFace2.uv1.V = 1.0f - percentOfPath;
newViewerFace2.uv2.V = lastV;
newViewerFace2.uv3.V = 1.0f - percentOfPath;
newViewerFace1.v1 = this.coords[i];
newViewerFace1.v2 = this.coords[i - numVerts];
newViewerFace1.v3 = this.coords[iNext - numVerts];
newViewerFace2.v1 = this.coords[i];
newViewerFace2.v2 = this.coords[iNext - numVerts];
newViewerFace2.v3 = this.coords[iNext];
newViewerFace1.coordIndex1 = i;
newViewerFace1.coordIndex2 = i - numVerts;
newViewerFace1.coordIndex3 = iNext - numVerts;
newViewerFace2.coordIndex1 = i;
newViewerFace2.coordIndex2 = iNext - numVerts;
newViewerFace2.coordIndex3 = iNext;
// profile cut faces
if (whichVert == cut1Vert)
{
newViewerFace1.n1 = newLayer.cutNormal1;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
newViewerFace2.n2 = lastCutNormal1;
}
else if (whichVert == cut2Vert)
{
newViewerFace1.n1 = newLayer.cutNormal2;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
newViewerFace2.n2 = lastCutNormal2;
}
else // outer and hollow faces
{
if ((sides < 5 && whichVert < newLayer.numOuterVerts) || (hollowSides < 5 && whichVert >= newLayer.numOuterVerts))
{
newViewerFace1.CalcSurfaceNormal();
newViewerFace2.CalcSurfaceNormal();
}
else
{
newViewerFace1.n1 = this.normals[i];
newViewerFace1.n2 = this.normals[i - numVerts];
newViewerFace1.n3 = this.normals[iNext - numVerts];
newViewerFace2.n1 = this.normals[i];
newViewerFace2.n2 = this.normals[iNext - numVerts];
newViewerFace2.n3 = this.normals[iNext];
}
}
//newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = newLayer.faceNumbers[whichVert];
this.viewerFaces.Add(newViewerFace1);
this.viewerFaces.Add(newViewerFace2);
}
}
}
lastCutNormal1 = newLayer.cutNormal1;
lastCutNormal2 = newLayer.cutNormal2;
lastV = 1.0f - percentOfPath;
// calc the step for the next iteration of the loop
if (step < steps)
{
step += 1;
percentOfPath += percentOfPathMultiplier;
xOffset += xOffsetStepIncrement;
yOffset += yOffsetStepIncrement;
zOffset += stepSize;
if (percentOfPath > this.pathCutEnd)
done = true;
}
else done = true;
if (done && viewerMode)
{
// add the top faces to the viewerFaces list here
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace();
newViewerFace.primFaceNumber = 0;
int numFaces = newLayer.faces.Count;
List<Face> faces = newLayer.faces;
for (int i = 0; i < numFaces; i++)
{
Face face = faces[i];
newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
newViewerFace.coordIndex1 = face.v1 - coordsLen;
newViewerFace.coordIndex2 = face.v2 - coordsLen;
newViewerFace.coordIndex3 = face.v3 - coordsLen;
newViewerFace.n1 = faceNormal;
newViewerFace.n2 = faceNormal;
newViewerFace.n3 = faceNormal;
newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
this.viewerFaces.Add(newViewerFace);
}
}
}
this.Extrude(PathType.Linear);
}
/// <summary>
/// DEPRICATED - use Extrude(PathType.Circular) instead
/// Extrude a profile into a circular path prim mesh. Used for prim types torus, tube, and ring.
/// </summary>
///
public void ExtrudeCircular()
{
this.coords = new List<Coord>();
this.faces = new List<Face>();
if (this.viewerMode)
{
this.viewerFaces = new List<ViewerFace>();
this.calcVertexNormals = true;
}
if (this.calcVertexNormals)
this.normals = new List<Coord>();
int step = 0;
int steps = 24;
normalsProcessed = false;
float twistBegin = this.twistBegin / 360.0f * twoPi;
float twistEnd = this.twistEnd / 360.0f * twoPi;
float twistTotal = twistEnd - twistBegin;
// if the profile has a lot of twist, add more layers otherwise the layers may overlap
// and the resulting mesh may be quite inaccurate. This method is arbitrary and doesn't
// accurately match the viewer
float twistTotalAbs = Math.Abs(twistTotal);
if (twistTotalAbs > 0.01f)
{
if (twistTotalAbs > Math.PI * 1.5f)
steps *= 2;
if (twistTotalAbs > Math.PI * 3.0f)
steps *= 2;
}
float yPathScale = this.holeSizeY * 0.5f;
float pathLength = this.pathCutEnd - this.pathCutBegin;
float totalSkew = this.skew * 2.0f * pathLength;
float skewStart = this.pathCutBegin * 2.0f * this.skew - this.skew;
float xOffsetTopShearXFactor = this.topShearX * (0.25f + 0.5f * (0.5f - this.holeSizeY));
float yShearCompensation = 1.0f + Math.Abs(this.topShearY) * 0.25f;
// It's not quite clear what pushY (Y top shear) does, but subtracting it from the start and end
// angles appears to approximate it's effects on path cut. Likewise, adding it to the angle used
// to calculate the sine for generating the path radius appears to approximate it's effects there
// too, but there are some subtle differences in the radius which are noticeable as the prim size
// increases and it may affect megaprims quite a bit. The effect of the Y top shear parameter on
// the meshes generated with this technique appear nearly identical in shape to the same prims when
// displayed by the viewer.
float startAngle = (twoPi * this.pathCutBegin * this.revolutions) - this.topShearY * 0.9f;
float endAngle = (twoPi * this.pathCutEnd * this.revolutions) - this.topShearY * 0.9f;
float stepSize = twoPi / this.stepsPerRevolution;
step = (int)(startAngle / stepSize);
int firstStep = step;
float angle = startAngle;
float hollow = this.hollow;
// sanity checks
float initialProfileRot = 0.0f;
if (this.sides == 3)
{
initialProfileRot = (float)Math.PI;
if (this.hollowSides == 4)
{
if (hollow > 0.7f)
hollow = 0.7f;
hollow *= 0.707f;
}
else hollow *= 0.5f;
}
else if (this.sides == 4)
{
initialProfileRot = 0.25f * (float)Math.PI;
if (this.hollowSides != 4)
hollow *= 0.707f;
}
else if (this.sides > 4)
{
initialProfileRot = (float)Math.PI;
if (this.hollowSides == 4)
{
if (hollow > 0.7f)
hollow = 0.7f;
hollow /= 0.7f;
}
}
bool needEndFaces = false;
if (this.pathCutBegin != 0.0f || this.pathCutEnd != 1.0f)
needEndFaces = true;
else if (this.taperX != 0.0f || this.taperY != 0.0f)
needEndFaces = true;
else if (this.skew != 0.0f)
needEndFaces = true;
else if (twistTotal != 0.0f)
needEndFaces = true;
else if (this.radius != 0.0f)
needEndFaces = true;
Profile profile = new Profile(this.sides, this.profileStart, this.profileEnd, hollow, this.hollowSides, needEndFaces, calcVertexNormals);
this.errorMessage = profile.errorMessage;
this.numPrimFaces = profile.numPrimFaces;
int cut1Vert = -1;
int cut2Vert = -1;
if (hasProfileCut)
{
cut1Vert = hasHollow ? profile.coords.Count - 1 : 0;
cut2Vert = hasHollow ? profile.numOuterVerts - 1 : profile.numOuterVerts;
}
if (initialProfileRot != 0.0f)
{
profile.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), initialProfileRot));
if (viewerMode)
profile.MakeFaceUVs();
}
Coord lastCutNormal1 = new Coord();
Coord lastCutNormal2 = new Coord();
float lastV = 1.0f;
bool done = false;
while (!done) // loop through the length of the path and add the layers
{
bool isEndLayer = false;
if (angle <= startAngle + .01f || angle >= endAngle - .01f)
isEndLayer = true;
Profile newLayer = profile.Copy();
float xProfileScale = (1.0f - Math.Abs(this.skew)) * this.holeSizeX;
float yProfileScale = this.holeSizeY;
float percentOfPath = angle / (twoPi * this.revolutions);
float percentOfAngles = (angle - startAngle) / (endAngle - startAngle);
if (this.taperX > 0.01f)
xProfileScale *= 1.0f - percentOfPath * this.taperX;
else if (this.taperX < -0.01f)
xProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperX;
if (this.taperY > 0.01f)
yProfileScale *= 1.0f - percentOfPath * this.taperY;
else if (this.taperY < -0.01f)
yProfileScale *= 1.0f + (1.0f - percentOfPath) * this.taperY;
if (xProfileScale != 1.0f || yProfileScale != 1.0f)
newLayer.Scale(xProfileScale, yProfileScale);
float radiusScale = 1.0f;
if (this.radius > 0.001f)
radiusScale = 1.0f - this.radius * percentOfPath;
else if (this.radius < 0.001f)
radiusScale = 1.0f + this.radius * (1.0f - percentOfPath);
float twist = twistBegin + twistTotal * percentOfPath;
float xOffset = 0.5f * (skewStart + totalSkew * percentOfAngles);
xOffset += (float)Math.Sin(angle) * xOffsetTopShearXFactor;
float yOffset = yShearCompensation * (float)Math.Cos(angle) * (0.5f - yPathScale) * radiusScale;
float zOffset = (float)Math.Sin(angle + this.topShearY) * (0.5f - yPathScale) * radiusScale;
// next apply twist rotation to the profile layer
if (twistTotal != 0.0f || twistBegin != 0.0f)
newLayer.AddRot(new Quat(new Coord(0.0f, 0.0f, 1.0f), twist));
// now orient the rotation of the profile layer relative to it's position on the path
// adding taperY to the angle used to generate the quat appears to approximate the viewer
newLayer.AddRot(new Quat(new Coord(1.0f, 0.0f, 0.0f), angle + this.topShearY));
newLayer.AddPos(xOffset, yOffset, zOffset);
if (isEndLayer && angle <= startAngle + .01f)
{
newLayer.FlipNormals();
// add the top faces to the viewerFaces list here
if (this.viewerMode && needEndFaces)
{
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace();
newViewerFace.primFaceNumber = 0;
foreach (Face face in newLayer.faces)
{
newViewerFace.v1 = newLayer.coords[face.v1];
newViewerFace.v2 = newLayer.coords[face.v2];
newViewerFace.v3 = newLayer.coords[face.v3];
newViewerFace.coordIndex1 = face.v1;
newViewerFace.coordIndex2 = face.v2;
newViewerFace.coordIndex3 = face.v3;
newViewerFace.n1 = faceNormal;
newViewerFace.n2 = faceNormal;
newViewerFace.n3 = faceNormal;
newViewerFace.uv1 = newLayer.faceUVs[face.v1];
newViewerFace.uv2 = newLayer.faceUVs[face.v2];
newViewerFace.uv3 = newLayer.faceUVs[face.v3];
this.viewerFaces.Add(newViewerFace);
}
}
}
// append the layer and fill in the sides
int coordsLen = this.coords.Count;
newLayer.AddValue2FaceVertexIndices(coordsLen);
this.coords.AddRange(newLayer.coords);
if (this.calcVertexNormals)
{
newLayer.AddValue2FaceNormalIndices(this.normals.Count);
this.normals.AddRange(newLayer.vertexNormals);
}
if (isEndLayer)
this.faces.AddRange(newLayer.faces);
// fill faces between layers
int numVerts = newLayer.coords.Count;
Face newFace = new Face();
if (step > firstStep)
{
int startVert = coordsLen + 1;
int endVert = this.coords.Count;
if (sides < 5 || this.hasProfileCut || hollow > 0.0f)
startVert--;
for (int i = startVert; i < endVert; i++)
{
int iNext = i + 1;
if (i == endVert - 1)
iNext = startVert;
int whichVert = i - startVert;
newFace.v1 = i;
newFace.v2 = i - numVerts;
newFace.v3 = iNext - numVerts;
this.faces.Add(newFace);
newFace.v2 = iNext - numVerts;
newFace.v3 = iNext;
this.faces.Add(newFace);
if (this.viewerMode)
{
int primFaceNumber = profile.faceNumbers[whichVert];
if (!needEndFaces)
primFaceNumber -= 1;
// add the side faces to the list of viewerFaces here
ViewerFace newViewerFace1 = new ViewerFace(primFaceNumber);
ViewerFace newViewerFace2 = new ViewerFace(primFaceNumber);
float u1 = newLayer.us[whichVert];
float u2 = 1.0f;
if (whichVert < newLayer.us.Count - 1)
u2 = newLayer.us[whichVert + 1];
if (whichVert == cut1Vert || whichVert == cut2Vert)
{
u1 = 0.0f;
u2 = 1.0f;
}
else if (sides < 5)
{ // boxes and prisms have one texture face per side of the prim, so the U values have to be scaled
// to reflect the entire texture width
u1 *= sides;
u2 *= sides;
u2 -= (int)u1;
u1 -= (int)u1;
if (u2 < 0.1f)
u2 = 1.0f;
//newViewerFace2.primFaceNumber = newViewerFace1.primFaceNumber = whichVert + 1;
}
newViewerFace1.uv1.U = u1;
newViewerFace1.uv2.U = u1;
newViewerFace1.uv3.U = u2;
newViewerFace1.uv1.V = 1.0f - percentOfPath;
newViewerFace1.uv2.V = lastV;
newViewerFace1.uv3.V = lastV;
newViewerFace2.uv1.U = u1;
newViewerFace2.uv2.U = u2;
newViewerFace2.uv3.U = u2;
newViewerFace2.uv1.V = 1.0f - percentOfPath;
newViewerFace2.uv2.V = lastV;
newViewerFace2.uv3.V = 1.0f - percentOfPath;
newViewerFace1.v1 = this.coords[i];
newViewerFace1.v2 = this.coords[i - numVerts];
newViewerFace1.v3 = this.coords[iNext - numVerts];
newViewerFace2.v1 = this.coords[i];
newViewerFace2.v2 = this.coords[iNext - numVerts];
newViewerFace2.v3 = this.coords[iNext];
newViewerFace1.coordIndex1 = i;
newViewerFace1.coordIndex2 = i - numVerts;
newViewerFace1.coordIndex3 = iNext - numVerts;
newViewerFace2.coordIndex1 = i;
newViewerFace2.coordIndex2 = iNext - numVerts;
newViewerFace2.coordIndex3 = iNext;
// profile cut faces
if (whichVert == cut1Vert)
{
newViewerFace1.n1 = newLayer.cutNormal1;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal1;
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal1;
newViewerFace2.n2 = lastCutNormal1;
}
else if (whichVert == cut2Vert)
{
newViewerFace1.n1 = newLayer.cutNormal2;
newViewerFace1.n2 = newViewerFace1.n3 = lastCutNormal2;
newViewerFace2.n1 = newViewerFace2.n3 = newLayer.cutNormal2;
newViewerFace2.n2 = lastCutNormal2;
}
else // periphery faces
{
if (sides < 5 && whichVert < newLayer.numOuterVerts)
{
newViewerFace1.n1 = this.normals[i];
newViewerFace1.n2 = this.normals[i - numVerts];
newViewerFace1.n3 = this.normals[i - numVerts];
newViewerFace2.n1 = this.normals[i];
newViewerFace2.n2 = this.normals[i - numVerts];
newViewerFace2.n3 = this.normals[i];
}
else if (hollowSides < 5 && whichVert >= newLayer.numOuterVerts)
{
newViewerFace1.n1 = this.normals[iNext];
newViewerFace1.n2 = this.normals[iNext - numVerts];
newViewerFace1.n3 = this.normals[iNext - numVerts];
newViewerFace2.n1 = this.normals[iNext];
newViewerFace2.n2 = this.normals[iNext - numVerts];
newViewerFace2.n3 = this.normals[iNext];
}
else
{
newViewerFace1.n1 = this.normals[i];
newViewerFace1.n2 = this.normals[i - numVerts];
newViewerFace1.n3 = this.normals[iNext - numVerts];
newViewerFace2.n1 = this.normals[i];
newViewerFace2.n2 = this.normals[iNext - numVerts];
newViewerFace2.n3 = this.normals[iNext];
}
}
//newViewerFace1.primFaceNumber = newViewerFace2.primFaceNumber = newLayer.faceNumbers[whichVert];
this.viewerFaces.Add(newViewerFace1);
this.viewerFaces.Add(newViewerFace2);
}
}
}
lastCutNormal1 = newLayer.cutNormal1;
lastCutNormal2 = newLayer.cutNormal2;
lastV = 1.0f - percentOfPath;
// calculate terms for next iteration
// calculate the angle for the next iteration of the loop
if (angle >= endAngle - 0.01)
done = true;
else
{
step += 1;
angle = stepSize * step;
if (angle > endAngle)
angle = endAngle;
}
if (done && viewerMode && needEndFaces)
{
// add the bottom faces to the viewerFaces list here
Coord faceNormal = newLayer.faceNormal;
ViewerFace newViewerFace = new ViewerFace();
//newViewerFace.primFaceNumber = newLayer.bottomFaceNumber + 1;
newViewerFace.primFaceNumber = newLayer.bottomFaceNumber;
foreach (Face face in newLayer.faces)
{
newViewerFace.v1 = newLayer.coords[face.v1 - coordsLen];
newViewerFace.v2 = newLayer.coords[face.v2 - coordsLen];
newViewerFace.v3 = newLayer.coords[face.v3 - coordsLen];
newViewerFace.coordIndex1 = face.v1 - coordsLen;
newViewerFace.coordIndex2 = face.v2 - coordsLen;
newViewerFace.coordIndex3 = face.v3 - coordsLen;
newViewerFace.n1 = faceNormal;
newViewerFace.n2 = faceNormal;
newViewerFace.n3 = faceNormal;
newViewerFace.uv1 = newLayer.faceUVs[face.v1 - coordsLen];
newViewerFace.uv2 = newLayer.faceUVs[face.v2 - coordsLen];
newViewerFace.uv3 = newLayer.faceUVs[face.v3 - coordsLen];
this.viewerFaces.Add(newViewerFace);
}
}
}
this.Extrude(PathType.Circular);
}
private Coord SurfaceNormal(Coord c1, Coord c2, Coord c3)
{
Coord edge1 = new Coord(c2.X - c1.X, c2.Y - c1.Y, c2.Z - c1.Z);

View File

@@ -1209,11 +1209,11 @@ namespace OpenSim.Region.Physics.OdePlugin
m_requestedUpdateFrequency = 0;
m_eventsubscription = 0;
}
public void AddCollisionEvent(uint CollidedWith, float depth)
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
{
if (m_eventsubscription > 0)
{
CollisionEventsThisFrame.addCollider(CollidedWith, depth);
CollisionEventsThisFrame.addCollider(CollidedWith, contact);
}
}

View File

@@ -2958,11 +2958,11 @@ Console.WriteLine(" JointCreateFixed");
m_eventsubscription = 0;
}
public void AddCollisionEvent(uint CollidedWith, float depth)
public void AddCollisionEvent(uint CollidedWith, ContactPoint contact)
{
if (CollisionEventsThisFrame == null)
CollisionEventsThisFrame = new CollisionEventUpdate();
CollisionEventsThisFrame.addCollider(CollidedWith,depth);
CollisionEventsThisFrame.addCollider(CollidedWith, contact);
}
public void SendCollisions()

View File

@@ -159,6 +159,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private float ODE_STEPSIZE = 0.020f;
private float metersInSpace = 29.9f;
private float m_timeDilation = 1.0f;
public float gravityx = 0f;
public float gravityy = 0f;
@@ -177,8 +178,8 @@ namespace OpenSim.Region.Physics.OdePlugin
//private int m_returncollisions = 10;
private readonly IntPtr contactgroup;
internal IntPtr LandGeom;
internal IntPtr LandGeom;
internal IntPtr WaterGeom;
private float nmTerrainContactFriction = 255.0f;
@@ -250,7 +251,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_NINJA_physics_joints_enabled = false;
//private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>();
private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>();
private d.ContactGeom[] contacts = new d.ContactGeom[80];
private d.ContactGeom[] contacts;
private readonly List<PhysicsJoint> requestedJointsToBeCreated = new List<PhysicsJoint>(); // lock only briefly. accessed by external code (to request new joints) and by OdeScene.Simulate() to move those joints into pending/active
private readonly List<PhysicsJoint> pendingJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene.
private readonly List<PhysicsJoint> activeJoints = new List<PhysicsJoint>(); // can lock for longer. accessed only by OdeScene.
@@ -396,6 +397,8 @@ namespace OpenSim.Region.Physics.OdePlugin
avStandupTensor = 550000f;
}
int contactsPerCollision = 80;
if (m_config != null)
{
IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"];
@@ -438,6 +441,8 @@ namespace OpenSim.Region.Physics.OdePlugin
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", 0.37f);
avCapsuleTilted = physicsconfig.GetBoolean("av_capsule_tilted", true);
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", 80);
geomContactPointsStartthrottle = physicsconfig.GetInt("geom_contactpoints_start_throttling", 3);
geomUpdatesPerThrottledUpdate = physicsconfig.GetInt("geom_updates_before_throttled_update", 15);
geomCrossingFailuresBeforeOutofbounds = physicsconfig.GetInt("geom_crossing_failures_before_outofbounds", 5);
@@ -475,10 +480,11 @@ namespace OpenSim.Region.Physics.OdePlugin
m_NINJA_physics_joints_enabled = physicsconfig.GetBoolean("use_NINJA_physics_joints", false);
minimumGroundFlightOffset = physicsconfig.GetFloat("minimum_ground_flight_offset", 3f);
}
}
contacts = new d.ContactGeom[contactsPerCollision];
staticPrimspace = new IntPtr[(int)(300 / metersInSpace), (int)(300 / metersInSpace)];
// Centeral contact friction and bounce
@@ -771,7 +777,9 @@ namespace OpenSim.Region.Physics.OdePlugin
lock (contacts)
{
count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
if (count > contacts.Length)
m_log.Error("[PHYSICS]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
}
}
catch (SEHException)
@@ -799,7 +807,7 @@ namespace OpenSim.Region.Physics.OdePlugin
p2 = PANull;
}
float max_collision_depth = 0f;
ContactPoint maxDepthContact = new ContactPoint();
if (p1.CollisionScore + count >= float.MaxValue)
p1.CollisionScore = 0;
p1.CollisionScore += count;
@@ -810,9 +818,17 @@ namespace OpenSim.Region.Physics.OdePlugin
for (int i = 0; i < count; i++)
{
d.ContactGeom curContact = contacts[i];
if (curContact.depth > maxDepthContact.PenetrationDepth)
{
maxDepthContact = new ContactPoint(
new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
curContact.depth
);
}
max_collision_depth = (contacts[i].depth > max_collision_depth) ? contacts[i].depth : max_collision_depth;
//m_log.Warn("[CCOUNT]: " + count);
IntPtr joint;
// If we're colliding with terrain, use 'TerrainContact' instead of contact.
@@ -829,7 +845,7 @@ namespace OpenSim.Region.Physics.OdePlugin
p2.CollidingObj = true;
break;
case (int)ActorTypes.Prim:
if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true;
break;
case (int)ActorTypes.Unknown:
@@ -845,14 +861,14 @@ namespace OpenSim.Region.Physics.OdePlugin
#region InterPenetration Handling - Unintended physics explosions
# region disabled code1
if (contacts[i].depth >= 0.08f)
if (curContact.depth >= 0.08f)
{
//This is disabled at the moment only because it needs more tweaking
//It will eventually be uncommented
/*
if (contacts[i].depth >= 1.00f)
if (contact.depth >= 1.00f)
{
//m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString());
//m_log.Debug("[PHYSICS]: " + contact.depth.ToString());
}
//If you interpenetrate a prim with an agent
@@ -862,37 +878,37 @@ namespace OpenSim.Region.Physics.OdePlugin
p2.PhysicsActorType == (int) ActorTypes.Prim))
{
//contacts[i].depth = contacts[i].depth * 4.15f;
//contact.depth = contact.depth * 4.15f;
/*
if (p2.PhysicsActorType == (int) ActorTypes.Agent)
{
p2.CollidingObj = true;
contacts[i].depth = 0.003f;
contact.depth = 0.003f;
p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 2.5f);
OdeCharacter character = (OdeCharacter) p2;
character.SetPidStatus(true);
contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p1.Size.X / 2), contacts[i].pos.Y + (p1.Size.Y / 2), contacts[i].pos.Z + (p1.Size.Z / 2));
contact.pos = new d.Vector3(contact.pos.X + (p1.Size.X / 2), contact.pos.Y + (p1.Size.Y / 2), contact.pos.Z + (p1.Size.Z / 2));
}
else
{
//contacts[i].depth = 0.0000000f;
//contact.depth = 0.0000000f;
}
if (p1.PhysicsActorType == (int) ActorTypes.Agent)
{
p1.CollidingObj = true;
contacts[i].depth = 0.003f;
contact.depth = 0.003f;
p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 2.5f);
contacts[i].pos = new d.Vector3(contacts[i].pos.X + (p2.Size.X / 2), contacts[i].pos.Y + (p2.Size.Y / 2), contacts[i].pos.Z + (p2.Size.Z / 2));
contact.pos = new d.Vector3(contact.pos.X + (p2.Size.X / 2), contact.pos.Y + (p2.Size.Y / 2), contact.pos.Z + (p2.Size.Z / 2));
OdeCharacter character = (OdeCharacter)p1;
character.SetPidStatus(true);
}
else
{
//contacts[i].depth = 0.0000000f;
//contact.depth = 0.0000000f;
}
@@ -917,7 +933,7 @@ namespace OpenSim.Region.Physics.OdePlugin
//AddPhysicsActorTaint(p2);
//}
//if (contacts[i].depth >= 0.25f)
//if (contact.depth >= 0.25f)
//{
// Don't collide, one or both prim will expld.
@@ -935,21 +951,21 @@ namespace OpenSim.Region.Physics.OdePlugin
//AddPhysicsActorTaint(p2);
//}
//contacts[i].depth = contacts[i].depth / 8f;
//contacts[i].normal = new d.Vector3(0, 0, 1);
//contact.depth = contact.depth / 8f;
//contact.normal = new d.Vector3(0, 0, 1);
//}
//if (op1.m_disabled || op2.m_disabled)
//{
//Manually disabled objects stay disabled
//contacts[i].depth = 0f;
//contact.depth = 0f;
//}
#endregion
}
*/
#endregion
if (contacts[i].depth >= 1.00f)
if (curContact.depth >= 1.00f)
{
//m_log.Info("[P]: " + contacts[i].depth.ToString());
//m_log.Info("[P]: " + contact.depth.ToString());
if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
(p1.PhysicsActorType == (int) ActorTypes.Agent &&
@@ -962,12 +978,12 @@ namespace OpenSim.Region.Physics.OdePlugin
OdeCharacter character = (OdeCharacter) p2;
//p2.CollidingObj = true;
contacts[i].depth = 0.00000003f;
curContact.depth = 0.00000003f;
p2.Velocity = p2.Velocity + new Vector3(0f, 0f, 0.5f);
contacts[i].pos =
new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
contacts[i].pos.Y + (p1.Size.Y/2),
contacts[i].pos.Z + (p1.Size.Z/2));
curContact.pos =
new d.Vector3(curContact.pos.X + (p1.Size.X/2),
curContact.pos.Y + (p1.Size.Y/2),
curContact.pos.Z + (p1.Size.Z/2));
character.SetPidStatus(true);
}
}
@@ -980,12 +996,12 @@ namespace OpenSim.Region.Physics.OdePlugin
OdeCharacter character = (OdeCharacter) p1;
//p2.CollidingObj = true;
contacts[i].depth = 0.00000003f;
curContact.depth = 0.00000003f;
p1.Velocity = p1.Velocity + new Vector3(0f, 0f, 0.5f);
contacts[i].pos =
new d.Vector3(contacts[i].pos.X + (p1.Size.X/2),
contacts[i].pos.Y + (p1.Size.Y/2),
contacts[i].pos.Z + (p1.Size.Z/2));
curContact.pos =
new d.Vector3(curContact.pos.X + (p1.Size.X/2),
curContact.pos.Y + (p1.Size.Y/2),
curContact.pos.Z + (p1.Size.Z/2));
character.SetPidStatus(true);
}
}
@@ -1007,16 +1023,15 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!skipThisContact && (p2 is OdePrim) && (((OdePrim)p2).m_isVolumeDetect))
skipThisContact = true; // No collision on volume detect prims
if (!skipThisContact && contacts[i].depth < 0f)
if (!skipThisContact && curContact.depth < 0f)
skipThisContact = true;
if (!skipThisContact && checkDupe(contacts[i], p2.PhysicsActorType))
if (!skipThisContact && checkDupe(curContact, p2.PhysicsActorType))
skipThisContact = true;
int maxContactsbeforedeath = 4000;
const int maxContactsbeforedeath = 4000;
joint = IntPtr.Zero;
if (!skipThisContact)
{
// If we're colliding against terrain
@@ -1027,8 +1042,8 @@ namespace OpenSim.Region.Physics.OdePlugin
(Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{
// Use the movement terrain contact
AvatarMovementTerrainContact.geom = contacts[i];
_perloopContact.Add(contacts[i]);
AvatarMovementTerrainContact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
@@ -1040,8 +1055,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (p2.PhysicsActorType == (int)ActorTypes.Agent)
{
// Use the non moving terrain contact
TerrainContact.geom = contacts[i];
_perloopContact.Add(contacts[i]);
TerrainContact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
@@ -1066,8 +1081,8 @@ namespace OpenSim.Region.Physics.OdePlugin
material = ((OdePrim)p2).m_material;
//m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, movintYN].geom = contacts[i];
_perloopContact.Add(contacts[i]);
m_materialContacts[material, movintYN].geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
@@ -1092,8 +1107,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if (p2 is OdePrim)
material = ((OdePrim)p2).m_material;
//m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, movintYN].geom = contacts[i];
_perloopContact.Add(contacts[i]);
m_materialContacts[material, movintYN].geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
@@ -1121,20 +1136,20 @@ namespace OpenSim.Region.Physics.OdePlugin
*/
//WaterContact.surface.soft_cfm = 0.0000f;
//WaterContact.surface.soft_erp = 0.00000f;
if (contacts[i].depth > 0.1f)
if (curContact.depth > 0.1f)
{
contacts[i].depth *= 52;
//contacts[i].normal = new d.Vector3(0, 0, 1);
//contacts[i].pos = new d.Vector3(0, 0, contacts[i].pos.Z - 5f);
curContact.depth *= 52;
//contact.normal = new d.Vector3(0, 0, 1);
//contact.pos = new d.Vector3(0, 0, contact.pos.Z - 5f);
}
WaterContact.geom = contacts[i];
_perloopContact.Add(contacts[i]);
WaterContact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
joint = d.JointCreateContact(world, contactgroup, ref WaterContact);
m_global_contactcount++;
}
//m_log.Info("[PHYSICS]: Prim Water Contact" + contacts[i].depth);
//m_log.Info("[PHYSICS]: Prim Water Contact" + contact.depth);
}
else
{
@@ -1145,8 +1160,8 @@ namespace OpenSim.Region.Physics.OdePlugin
if ((Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
{
// Use the Movement prim contact
AvatarMovementprimContact.geom = contacts[i];
_perloopContact.Add(contacts[i]);
AvatarMovementprimContact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
@@ -1156,8 +1171,8 @@ namespace OpenSim.Region.Physics.OdePlugin
else
{
// Use the non movement contact
contact.geom = contacts[i];
_perloopContact.Add(contacts[i]);
contact.geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
@@ -1175,8 +1190,8 @@ namespace OpenSim.Region.Physics.OdePlugin
material = ((OdePrim)p2).m_material;
//m_log.DebugFormat("Material: {0}", material);
m_materialContacts[material, 0].geom = contacts[i];
_perloopContact.Add(contacts[i]);
m_materialContacts[material, 0].geom = curContact;
_perloopContact.Add(curContact);
if (m_global_contactcount < maxContactsbeforedeath)
{
@@ -1194,7 +1209,7 @@ namespace OpenSim.Region.Physics.OdePlugin
}
}
collision_accounting_events(p1, p2, max_collision_depth);
collision_accounting_events(p1, p2, maxDepthContact);
if (count > geomContactPointsStartthrottle)
{
// If there are more then 3 contact points, it's likely
@@ -1278,7 +1293,7 @@ namespace OpenSim.Region.Physics.OdePlugin
return result;
}
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, float collisiondepth)
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
{
// obj1LocalID = 0;
//returncollisions = false;
@@ -1299,7 +1314,7 @@ namespace OpenSim.Region.Physics.OdePlugin
case ActorTypes.Agent:
cc1 = (OdeCharacter)p1;
obj2LocalID = cc1.m_localID;
cc1.AddCollisionEvent(cc2.m_localID, collisiondepth);
cc1.AddCollisionEvent(cc2.m_localID, contact);
//ctype = (int)CollisionCategories.Character;
//if (cc1.CollidingObj)
@@ -1314,7 +1329,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
cp1 = (OdePrim) p1;
obj2LocalID = cp1.m_localID;
cp1.AddCollisionEvent(cc2.m_localID, collisiondepth);
cp1.AddCollisionEvent(cc2.m_localID, contact);
}
//ctype = (int)CollisionCategories.Geom;
@@ -1334,7 +1349,7 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
}
cc2.AddCollisionEvent(obj2LocalID, collisiondepth);
cc2.AddCollisionEvent(obj2LocalID, contact);
break;
case ActorTypes.Prim:
@@ -1350,7 +1365,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
cc1 = (OdeCharacter) p1;
obj2LocalID = cc1.m_localID;
cc1.AddCollisionEvent(cp2.m_localID, collisiondepth);
cc1.AddCollisionEvent(cp2.m_localID, contact);
//ctype = (int)CollisionCategories.Character;
//if (cc1.CollidingObj)
@@ -1366,7 +1381,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{
cp1 = (OdePrim) p1;
obj2LocalID = cp1.m_localID;
cp1.AddCollisionEvent(cp2.m_localID, collisiondepth);
cp1.AddCollisionEvent(cp2.m_localID, contact);
//ctype = (int)CollisionCategories.Geom;
//if (cp1.CollidingObj)
@@ -1387,7 +1402,7 @@ namespace OpenSim.Region.Physics.OdePlugin
break;
}
cp2.AddCollisionEvent(obj2LocalID, collisiondepth);
cp2.AddCollisionEvent(obj2LocalID, contact);
}
break;
}
@@ -1750,6 +1765,11 @@ namespace OpenSim.Region.Physics.OdePlugin
return result;
}
public override float TimeDilation
{
get { return m_timeDilation; }
}
public override bool SupportsNINJAJoints
{
get { return m_NINJA_physics_joints_enabled; }
@@ -2657,8 +2677,10 @@ namespace OpenSim.Region.Physics.OdePlugin
// Figure out the Frames Per Second we're going at.
//(step_time == 0.004f, there's 250 of those per second. Times the step time/step size
fps = (step_time/ODE_STEPSIZE) * 1000;
fps = (step_time / ODE_STEPSIZE) * 1000;
// HACK: Using a time dilation of 1.0 to debug rubberbanding issues
//m_timeDilation = Math.Min((step_time / ODE_STEPSIZE) / (0.09375f / ODE_STEPSIZE), 1.0f);
step_time = 0.09375f;