Compare commits

...

19 Commits

Author SHA1 Message Date
UbitUmarov
f168fefb79 removed outdated coments. 2012-02-11 19:14:27 +00:00
UbitUmarov
bcf59a574f remove forgotten taints code 2012-02-11 19:12:04 +00:00
UbitUmarov
09f6647aa3 scenepresence change! in standup() give avatar a physical actor after deciding the new position. This reduces a bit the odds of it being still coliding with object. 2012-02-11 17:48:49 +00:00
UbitUmarov
022ae33ed5 UbitODE: replace 'taints' by 'changes' for avatars also. This provides better time order with changes in prims. 2012-02-11 17:35:38 +00:00
UbitUmarov
d4e28ed113 vehicle changes done by simulation thread and not calling one 2012-02-11 15:18:13 +00:00
UbitUmarov
3f9c390b4d changes to vehicle banking 2012-02-11 14:29:36 +00:00
UbitUmarov
33a9f0f1c5 a bit better vertical attractor and banking 2012-02-11 04:42:45 +00:00
UbitUmarov
f415256e0b Use mesh to estimate real center of prims if avaiable. Let sculpt map textures with alpha channel work. On linux J2DecodeCache folder must be deleted to remove bad entries. Corrently this can't be cached on linux (mono/ cairo/? problem) 2012-02-11 03:25:17 +00:00
UbitUmarov
b617411b97 scale avatar push force with avatar density 2012-02-11 02:48:38 +00:00
UbitUmarov
83868c0387 revert project name to OpenSim and not Careminster 2012-02-11 01:07:57 +00:00
UbitUmarov
43a74d8481 test on git 2012-02-10 23:51:55 +00:00
UbitUmarov
e3f5fd81f1 Merge branch 'master' of ssh://3dhosting.de/var/git/careminster into ubitwork
Conflicts:
	prebuild.xml
2012-02-10 23:03:30 +00:00
UbitUmarov
7cf73cb92a Changes to vehicles code etc. Includes some debug aids to remove later. 2012-02-10 22:43:51 +00:00
UbitUmarov
6af01f6767 initial introdution of physics actor building control. 2012-02-08 23:14:53 +00:00
UbitUmarov
6cc9aa30ac first change in SOP. in AddPrimShape(..) give physics the world rotation and not local offset. Currently physics interface only knows about world frame 2012-02-08 15:45:44 +00:00
UbitUmarov
754129b903 files need to run UbitODE in linux ( untested ) 2012-02-08 15:33:51 +00:00
UbitUmarov
12c3239666 changes needed to compile UbitODE, also changes project name to "Careminter". untested on linux 2012-02-08 15:29:48 +00:00
UbitUmarov
c75fa8b8a1 changes in physics manager, needed for UbitODE 2012-02-08 15:28:13 +00:00
UbitUmarov
815f3af1d7 UbitODE plugin initial commit 2012-02-08 15:24:10 +00:00
25 changed files with 11228 additions and 49 deletions

View File

@@ -417,7 +417,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments
so.AttachedAvatar = UUID.Zero;
rootPart.SetParentLocalId(0);
so.ClearPartAttachmentData();
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive);
rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive,false);
so.HasGroupChanged = true;
rootPart.Rezzed = DateTime.Now;
rootPart.RemFlag(PrimFlags.TemporaryOnRez);

View File

@@ -4766,7 +4766,7 @@ Environment.Exit(1);
bool wasUsingPhysics = ((jointProxyObject.Flags & PrimFlags.Physics) != 0);
if (wasUsingPhysics)
{
jointProxyObject.UpdatePrimFlags(false, false, true, false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
jointProxyObject.UpdatePrimFlags(false, false, true, false,false); // FIXME: possible deadlock here; check to make sure all the scene alterations set into motion here won't deadlock
}
}

View File

@@ -1281,7 +1281,8 @@ namespace OpenSim.Region.Framework.Scenes
m_rootPart.SetParentLocalId(0);
AttachmentPoint = (byte)0;
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
// must check if buildind should be true or false here
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive,false);
HasGroupChanged = true;
RootPart.Rezzed = DateTime.Now;
RootPart.RemFlag(PrimFlags.TemporaryOnRez);
@@ -1581,21 +1582,33 @@ namespace OpenSim.Region.Framework.Scenes
public void ApplyPhysics()
{
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
// m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive);
// Apply physics to child prims
SceneObjectPart[] parts = m_parts.GetArray();
if (parts.Length > 1)
{
ResetChildPrimPhysicsPositions();
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, true);
for (int i = 0; i < parts.Length; i++)
{
SceneObjectPart part = parts[i];
if (part.LocalId != m_rootPart.LocalId)
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive);
}
// part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive);
part.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), part.VolumeDetectActive, true);
}
// Hack to get the physics scene geometries in the right spot
ResetChildPrimPhysicsPositions();
// ResetChildPrimPhysicsPositions();
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
}
else
{
// Apply physics to the root prim
m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_rootPart.VolumeDetectActive, false);
}
}
@@ -1829,13 +1842,16 @@ namespace OpenSim.Region.Framework.Scenes
pbs,
newPart.AbsolutePosition,
newPart.Scale,
newPart.RotationOffset,
//newPart.RotationOffset,
newPart.GetWorldRotation(),
part.PhysActor.IsPhysical,
newPart.LocalId);
newPart.DoPhysicsPropertyUpdate(part.PhysActor.IsPhysical, true);
}
}
if (dupe.m_rootPart.PhysActor != null && userExposed)
dupe.m_rootPart.PhysActor.Building = false; // tell physics to finish building
if (userExposed)
{
@@ -2853,12 +2869,31 @@ namespace OpenSim.Region.Framework.Scenes
}
}
/*
RootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
for (int i = 0; i < parts.Length; i++)
{
if (parts[i] != RootPart)
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect);
}
*/
if (parts.Length > 1)
{
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
for (int i = 0; i < parts.Length; i++)
{
if (parts[i].UUID != m_rootPart.UUID)
parts[i].UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, true);
}
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
}
else
m_rootPart.UpdatePrimFlags(UsePhysics, SetTemporary, SetPhantom, SetVolumeDetect, false);
}
}

View File

@@ -1503,7 +1503,8 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary>
/// <param name="rootObjectFlags"></param>
/// <param name="VolumeDetectActive"></param>
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
// public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive)
public void ApplyPhysics(uint rootObjectFlags, bool VolumeDetectActive, bool building)
{
if (!ParentGroup.Scene.CollidablePrims)
return;
@@ -1539,7 +1540,8 @@ namespace OpenSim.Region.Framework.Scenes
Shape,
AbsolutePosition,
Scale,
RotationOffset,
// RotationOffset,
GetWorldRotation(), // physics wants world rotation
RigidBody,
m_localId);
}
@@ -1556,6 +1558,8 @@ namespace OpenSim.Region.Framework.Scenes
PhysActor.SetMaterial(Material);
DoPhysicsPropertyUpdate(RigidBody, true);
PhysActor.SetVolumeDetect(VolumeDetectActive ? 1 : 0);
if (!building)
PhysActor.Building = false;
}
}
}
@@ -1791,6 +1795,10 @@ namespace OpenSim.Region.Framework.Scenes
if (!isNew)
ParentGroup.Scene.RemovePhysicalPrim(1);
Velocity = new Vector3(0, 0, 0);
Acceleration = new Vector3(0, 0, 0);
AngularVelocity = new Vector3(0, 0, 0);
PhysActor.OnRequestTerseUpdate -= PhysicsRequestingTerseUpdate;
PhysActor.OnOutOfBounds -= PhysicsOutOfBounds;
PhysActor.delink();
@@ -4267,7 +4275,8 @@ namespace OpenSim.Region.Framework.Scenes
/// <param name="SetTemporary"></param>
/// <param name="SetPhantom"></param>
/// <param name="SetVD"></param>
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
// public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD)
public void UpdatePrimFlags(bool UsePhysics, bool SetTemporary, bool SetPhantom, bool SetVD, bool building)
{
bool wasUsingPhysics = ((Flags & PrimFlags.Physics) != 0);
bool wasTemporary = ((Flags & PrimFlags.TemporaryOnRez) != 0);
@@ -4285,6 +4294,9 @@ namespace OpenSim.Region.Framework.Scenes
// that...
// ... if VD is changed, all others are not.
// ... if one of the others is changed, VD is not.
// do this first
if (building && PhysActor != null && PhysActor.Building != building)
PhysActor.Building = building;
if (SetVD) // VD is active, special logic applies
{
// State machine logic for VolumeDetect
@@ -4366,7 +4378,8 @@ namespace OpenSim.Region.Framework.Scenes
Shape,
AbsolutePosition,
Scale,
RotationOffset,
// RotationOffset,
GetWorldRotation(), //physics wants world rotation like all other functions send
UsePhysics,
m_localId);
@@ -4446,6 +4459,9 @@ namespace OpenSim.Region.Framework.Scenes
}
// m_log.Debug("Update: PHY:" + UsePhysics.ToString() + ", T:" + IsTemporary.ToString() + ", PHA:" + IsPhantom.ToString() + " S:" + CastsShadows.ToString());
// and last in case we have a new actor and not building
if (PhysActor != null && PhysActor.Building != building)
PhysActor.Building = building;
if (ParentGroup != null)
{
ParentGroup.HasGroupChanged = true;

View File

@@ -1814,8 +1814,11 @@ namespace OpenSim.Region.Framework.Scenes
// m_log.DebugFormat("[SCENE PRESENCE]: StandUp() for {0}", Name);
SitGround = false;
/* move this down so avatar gets physical in the new position and not where it is siting
if (PhysicsActor == null)
AddToPhysicalScene(false);
*/
if (ParentID != 0)
{
@@ -1850,6 +1853,10 @@ namespace OpenSim.Region.Framework.Scenes
ParentPosition = Vector3.Zero;
ParentID = 0;
if (PhysicsActor == null)
AddToPhysicalScene(false);
SendAvatarDataToAllAgents();
m_requestedSitTargetID = 0;
@@ -1857,6 +1864,9 @@ namespace OpenSim.Region.Framework.Scenes
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
}
else if (PhysicsActor == null)
AddToPhysicalScene(false);
Animator.TrySetMovementAnimation("STAND");
}

View File

@@ -65,5 +65,6 @@ namespace OpenSim.Region.Physics.Manager
void releasePinned();
void Append(IMesh newMesh);
void TransformLinear(float[,] matrix, float[] offset);
Vector3 GetCentroid();
}
}

View File

@@ -68,6 +68,17 @@ namespace OpenSim.Region.Physics.Manager
}
}
public struct ContactData
{
public float mu;
public float bounce;
public ContactData(float _mu, float _bounce)
{
mu = _mu;
bounce = _bounce;
}
}
/// <summary>
/// Used to pass collision information to OnCollisionUpdate listeners.
/// </summary>
@@ -143,6 +154,14 @@ namespace OpenSim.Region.Physics.Manager
get { return new NullPhysicsActor(); }
}
public virtual bool Building { get; set; }
public virtual ContactData ContactData
{
get { return new ContactData(0, 0); }
}
public abstract bool Stopped { get; }
public abstract Vector3 Size { get; set; }

View File

@@ -225,7 +225,7 @@ namespace OpenSim.Region.Physics.Manager
}
public virtual void Combine(PhysicsScene pScene, Vector3 offset, Vector3 extents) {}
public virtual void CombineTerrain(float[] heightMap, Vector3 pOffset) {}
public virtual void UnCombine(PhysicsScene pScene) {}
/// <summary>
@@ -263,5 +263,13 @@ namespace OpenSim.Region.Physics.Manager
{
return new List<ContactResult>();
}
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
{
return new List<ContactResult>();
}
}
}

View File

@@ -46,11 +46,36 @@ namespace OpenSim.Region.Physics.Meshing
IntPtr m_indicesPtr = IntPtr.Zero;
int m_indexCount = 0;
public float[] m_normals;
Vector3 _centroid;
int _centroidDiv;
private class vertexcomp : IEqualityComparer<Vertex>
{
public bool Equals(Vertex v1, Vertex v2)
{
if (v1.X == v2.X && v1.Y == v2.Y && v1.Z == v2.Z)
return true;
else
return false;
}
public int GetHashCode(Vertex v)
{
int a = v.X.GetHashCode();
int b = v.Y.GetHashCode();
int c = v.Z.GetHashCode();
return (a << 16) ^ (b << 8) ^ c;
}
}
public Mesh()
{
m_vertices = new Dictionary<Vertex, int>();
vertexcomp vcomp = new vertexcomp();
m_vertices = new Dictionary<Vertex, int>(vcomp);
m_triangles = new List<Triangle>();
_centroid = Vector3.Zero;
_centroidDiv = 0;
}
public Mesh Clone()
@@ -61,7 +86,8 @@ namespace OpenSim.Region.Physics.Meshing
{
result.Add(new Triangle(t.v1.Clone(), t.v2.Clone(), t.v3.Clone()));
}
result._centroid = _centroid;
result._centroidDiv = _centroidDiv;
return result;
}
@@ -71,15 +97,57 @@ namespace OpenSim.Region.Physics.Meshing
throw new NotSupportedException("Attempt to Add to a pinned Mesh");
// If a vertex of the triangle is not yet in the vertices list,
// add it and set its index to the current index count
// vertex == seems broken
// skip colapsed triangles
if ((triangle.v1.X == triangle.v2.X && triangle.v1.Y == triangle.v2.Y && triangle.v1.Z == triangle.v2.Z)
|| (triangle.v1.X == triangle.v3.X && triangle.v1.Y == triangle.v3.Y && triangle.v1.Z == triangle.v3.Z)
|| (triangle.v2.X == triangle.v3.X && triangle.v2.Y == triangle.v3.Y && triangle.v2.Z == triangle.v3.Z)
)
{
return;
}
if (m_vertices.Count == 0)
{
_centroidDiv = 0;
_centroid = Vector3.Zero;
}
if (!m_vertices.ContainsKey(triangle.v1))
{
m_vertices[triangle.v1] = m_vertices.Count;
_centroid.X += triangle.v1.X;
_centroid.Y += triangle.v1.Y;
_centroid.Z += triangle.v1.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v2))
{
m_vertices[triangle.v2] = m_vertices.Count;
_centroid.X += triangle.v2.X;
_centroid.Y += triangle.v2.Y;
_centroid.Z += triangle.v2.Z;
_centroidDiv++;
}
if (!m_vertices.ContainsKey(triangle.v3))
{
m_vertices[triangle.v3] = m_vertices.Count;
_centroid.X += triangle.v3.X;
_centroid.Y += triangle.v3.Y;
_centroid.Z += triangle.v3.Z;
_centroidDiv++;
}
m_triangles.Add(triangle);
}
public Vector3 GetCentroid()
{
if (_centroidDiv > 0)
return new Vector3(_centroid.X / _centroidDiv, _centroid.Y / _centroidDiv, _centroid.Z / _centroidDiv);
else
return Vector3.Zero;
}
public void CalcNormals()
{
int iTriangles = m_triangles.Count;

View File

@@ -74,6 +74,8 @@ namespace OpenSim.Region.Physics.Meshing
#endif
private bool cacheSculptMaps = true;
private bool cacheSculptAlphaMaps = true;
private string decodedSculptMapPath = null;
private bool useMeshiesPhysicsMesh = false;
@@ -87,7 +89,16 @@ namespace OpenSim.Region.Physics.Meshing
IConfig mesh_config = config.Configs["Mesh"];
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
cacheSculptAlphaMaps = false;
}
else
cacheSculptAlphaMaps = cacheSculptMaps;
if(mesh_config != null)
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
@@ -268,15 +279,18 @@ namespace OpenSim.Region.Physics.Meshing
{
if (!GenerateCoordsAndFacesFromPrimSculptData(primName, primShape, size, lod, out coords, out faces))
return null;
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
// don't loose it
// primShape.SculptData = Utils.EmptyBytes;
}
// primShape.SculptDataLoaded = true;
}
else
{
if (!GenerateCoordsAndFacesFromPrimShapeData(primName, primShape, size, lod, out coords, out faces))
return null;
}
// Remove the reference to any JPEG2000 sculpt data so it can be GCed
// keep compatible
primShape.SculptData = Utils.EmptyBytes;
int numCoords = coords.Count;
@@ -482,7 +496,8 @@ namespace OpenSim.Region.Physics.Meshing
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
if (cacheSculptMaps)
if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
// don't cache images with alpha channel in linux since mono can't load them correctly)
{
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }

View File

@@ -58,28 +58,24 @@ namespace PrimMesher
if (bmW == 0 || bmH == 0)
throw new Exception("SculptMap: bitmap has no data");
int numLodPixels = lod * 2 * lod * 2; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
int numLodPixels = lod * lod; // (32 * 2)^2 = 64^2 pixels for default sculpt map image
bool smallMap = bmW * bmH <= numLodPixels;
bool needsScaling = false;
bool smallMap = bmW * bmH <= lod * lod;
width = bmW;
height = bmH;
while (width * height > numLodPixels)
while (width * height > numLodPixels * 4)
{
width >>= 1;
height >>= 1;
needsScaling = true;
}
try
{
if (needsScaling)
bm = ScaleImage(bm, width, height,
System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
bm = ScaleImage(bm, width, height);
}
catch (Exception e)
@@ -87,7 +83,7 @@ namespace PrimMesher
throw new Exception("Exception in ScaleImage(): e: " + e.ToString());
}
if (width * height > lod * lod)
if (width * height > numLodPixels)
{
width >>= 1;
height >>= 1;
@@ -144,15 +140,17 @@ namespace PrimMesher
int rowNdx, colNdx;
int smNdx = 0;
for (rowNdx = 0; rowNdx < numRows; rowNdx++)
{
List<Coord> row = new List<Coord>(numCols);
for (colNdx = 0; colNdx < numCols; colNdx++)
{
if (mirror)
row.Add(new Coord(-(redBytes[smNdx] * pixScale - 0.5f), (greenBytes[smNdx] * pixScale - 0.5f), blueBytes[smNdx] * pixScale - 0.5f));
row.Add(new Coord(-((float)redBytes[smNdx] * pixScale - 0.5f), ((float)greenBytes[smNdx] * pixScale - 0.5f), (float)blueBytes[smNdx] * pixScale - 0.5f));
else
row.Add(new Coord(redBytes[smNdx] * pixScale - 0.5f, greenBytes[smNdx] * pixScale - 0.5f, blueBytes[smNdx] * pixScale - 0.5f));
row.Add(new Coord((float)redBytes[smNdx] * pixScale - 0.5f, (float)greenBytes[smNdx] * pixScale - 0.5f, (float)blueBytes[smNdx] * pixScale - 0.5f));
++smNdx;
}
@@ -161,23 +159,39 @@ namespace PrimMesher
return rows;
}
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight,
System.Drawing.Drawing2D.InterpolationMode interpMode)
private Bitmap ScaleImage(Bitmap srcImage, int destWidth, int destHeight)
{
Bitmap scaledImage = new Bitmap(srcImage, destWidth, destHeight);
scaledImage.SetResolution(96.0f, 96.0f);
Graphics grPhoto = Graphics.FromImage(scaledImage);
grPhoto.InterpolationMode = interpMode;
Bitmap scaledImage = new Bitmap(destWidth, destHeight, PixelFormat.Format24bppRgb);
Color c;
float xscale = srcImage.Width / destWidth;
float yscale = srcImage.Height / destHeight;
float sy = 0.5f;
for (int y = 0; y < destHeight; y++)
{
float sx = 0.5f;
for (int x = 0; x < destWidth; x++)
{
try
{
c = srcImage.GetPixel((int)(sx), (int)(sy));
scaledImage.SetPixel(x, y, Color.FromArgb(c.R, c.G, c.B));
}
catch (IndexOutOfRangeException)
{
}
grPhoto.DrawImage(srcImage,
new Rectangle(0, 0, destWidth, destHeight),
new Rectangle(0, 0, srcImage.Width, srcImage.Height),
GraphicsUnit.Pixel);
grPhoto.Dispose();
sx += xscale;
}
sy += yscale;
}
srcImage.Dispose();
return scaledImage;
}
}
}
}
#endif

View File

@@ -0,0 +1,58 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Reflection;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly : AssemblyTitle("OdePlugin")]
[assembly : AssemblyDescription("Ubit Variation")]
[assembly : AssemblyConfiguration("")]
[assembly : AssemblyCompany("http://opensimulator.org")]
[assembly : AssemblyProduct("OdePlugin")]
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
[assembly : AssemblyTrademark("")]
[assembly : AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly : ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly : AssemblyVersion("0.6.5.*")]

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,849 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
* ODEPrim.cs contains methods dealing with Prim editing, Prim
* characteristics and Kinetic motion.
* ODEDynamics.cs contains methods dealing with Prim Physical motion
* (dynamics) and the associated settings. Old Linear and angular
* motors for dynamic motion have been replace with MoveLinear()
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
* switch between 'VEHICLE' parameter use and general dynamics
* settings use.
*/
// Ubit 2012
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using log4net;
using OpenMetaverse;
using OdeAPI;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
namespace OpenSim.Region.Physics.OdePlugin
{
public class ODEDynamics
{
public Vehicle Type
{
get { return m_type; }
}
private OdePrim rootPrim;
private OdeScene _pParentScene;
// Vehicle properties
private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
private Quaternion m_RollreferenceFrame = Quaternion.Identity; // what hell is this ?
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
// HOVER_TERRAIN_ONLY
// HOVER_GLOBAL_HEIGHT
// NO_DEFLECTION_UP
// HOVER_WATER_ONLY
// HOVER_UP_ONLY
// LIMIT_MOTOR_UP
// LIMIT_ROLL_ONLY
private Vector3 m_BlockingEndPoint = Vector3.Zero; // not sl
// Linear properties
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
private Vector3 m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
private float m_linearMotorDecayTimescale = 120;
private float m_linearMotorTimescale = 1000;
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
private Vector3 m_linearMotorOffset = Vector3.Zero;
//Angular properties
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
private float m_angularMotorTimescale = 1000; // motor angular velocity ramp up rate
private float m_angularMotorDecayTimescale = 120; // motor angular velocity decay rate
private Vector3 m_angularFrictionTimescale = new Vector3(1000, 1000, 1000); // body angular velocity decay rate
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
//Deflection properties
private float m_angularDeflectionEfficiency = 0;
private float m_angularDeflectionTimescale = 1000;
private float m_linearDeflectionEfficiency = 0;
private float m_linearDeflectionTimescale = 1000;
//Banking properties
private float m_bankingEfficiency = 0;
private float m_bankingMix = 0;
private float m_bankingTimescale = 0;
//Hover and Buoyancy properties
private float m_VhoverHeight = 0f;
private float m_VhoverEfficiency = 0f;
private float m_VhoverTimescale = 1000f;
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
//Attractor properties
private float m_verticalAttractionEfficiency = 1.0f; // damped
private float m_verticalAttractionTimescale = 1000f; // Timescale > 300 means no vert attractor.
// auxiliar
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
private float m_lmEfect = 0; // current linear motor eficiency
private float m_amEfect = 0; // current angular motor eficiency
public ODEDynamics(OdePrim rootp)
{
rootPrim = rootp;
_pParentScene = rootPrim._parent_scene;
}
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
{
float len;
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
float timestep = _pParentScene.ODE_STEPSIZE;
switch (pParam)
{
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_angularDeflectionEfficiency = pValue;
break;
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_angularDeflectionTimescale = pValue;
break;
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
// if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_angularMotorDecayTimescale = pValue * invtimestep;
break;
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_angularMotorTimescale = pValue;
break;
case Vehicle.BANKING_EFFICIENCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
m_bankingEfficiency = pValue;
break;
case Vehicle.BANKING_MIX:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_bankingMix = pValue;
break;
case Vehicle.BANKING_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_bankingTimescale = pValue;
break;
case Vehicle.BUOYANCY:
if (pValue < -1f) pValue = -1f;
if (pValue > 1f) pValue = 1f;
m_VehicleBuoyancy = pValue;
break;
case Vehicle.HOVER_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_VhoverEfficiency = pValue;
break;
case Vehicle.HOVER_HEIGHT:
m_VhoverHeight = pValue;
break;
case Vehicle.HOVER_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_VhoverTimescale = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_linearDeflectionEfficiency = pValue;
break;
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearDeflectionTimescale = pValue;
break;
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
// if (pValue < timestep) pValue = timestep;
// try to make impulses to work a bit better
if (pValue < 0.5f) pValue = 0.5f;
else if (pValue > 120) pValue = 120;
m_linearMotorDecayTimescale = pValue * invtimestep;
break;
case Vehicle.LINEAR_MOTOR_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearMotorTimescale = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
if (pValue < 0f) pValue = 0f;
if (pValue > 1f) pValue = 1f;
m_verticalAttractionEfficiency = pValue;
break;
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_verticalAttractionTimescale = pValue;
break;
// These are vector properties but the engine lets you use a single float value to
// set all of the components to the same value
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
len = m_angularMotorDirection.Length();
if (len > 12.566f)
m_angularMotorDirection *= (12.566f / len);
m_amEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
if (pValue < timestep) pValue = timestep;
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
len = m_linearMotorDirection.Length();
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
len = m_linearMotorOffset.Length();
if (len > 100.0f)
m_linearMotorOffset *= (100.0f / len);
break;
}
}//end ProcessFloatVehicleParam
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
{
float len;
float invtimestep = 1.0f / _pParentScene.ODE_STEPSIZE;
float timestep = _pParentScene.ODE_STEPSIZE;
switch (pParam)
{
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
if (pValue.X < timestep) pValue.X = timestep;
if (pValue.Y < timestep) pValue.Y = timestep;
if (pValue.Z < timestep) pValue.Z = timestep;
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.ANGULAR_MOTOR_DIRECTION:
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
// Limit requested angular speed to 2 rps= 4 pi rads/sec
len = m_angularMotorDirection.Length();
if (len > 12.566f)
m_angularMotorDirection *= (12.566f / len);
m_amEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_FRICTION_TIMESCALE:
if (pValue.X < timestep) pValue.X = timestep;
if (pValue.Y < timestep) pValue.Y = timestep;
if (pValue.Z < timestep) pValue.Z = timestep;
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
case Vehicle.LINEAR_MOTOR_DIRECTION:
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
len = m_linearMotorDirection.Length();
if (len > 30.0f)
m_linearMotorDirection *= (30.0f / len);
m_lmEfect = 1.0f; // turn it on
break;
case Vehicle.LINEAR_MOTOR_OFFSET:
m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
len = m_linearMotorOffset.Length();
if (len > 100.0f)
m_linearMotorOffset *= (100.0f / len);
break;
case Vehicle.BLOCK_EXIT:
m_BlockingEndPoint = new Vector3(pValue.X, pValue.Y, pValue.Z);
break;
}
}//end ProcessVectorVehicleParam
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
{
switch (pParam)
{
case Vehicle.REFERENCE_FRAME:
m_referenceFrame = Quaternion.Inverse(pValue);
break;
case Vehicle.ROLL_FRAME:
m_RollreferenceFrame = pValue;
break;
}
}//end ProcessRotationVehicleParam
internal void ProcessVehicleFlags(int pParam, bool remove)
{
if (remove)
{
m_flags &= ~((VehicleFlag)pParam);
}
else
{
m_flags |= (VehicleFlag)pParam;
}
}//end ProcessVehicleFlags
internal void ProcessTypeChange(Vehicle pType)
{
float invtimestep = _pParentScene.ODE_STEPSIZE;
m_lmEfect = 0;
m_amEfect = 0;
m_linearMotorDirection = Vector3.Zero;
m_angularMotorDirection = Vector3.Zero;
m_BlockingEndPoint = Vector3.Zero;
m_RollreferenceFrame = Quaternion.Identity;
m_linearMotorOffset = Vector3.Zero;
m_referenceFrame = Quaternion.Identity;
// Set Defaults For Type
m_type = pType;
switch (pType)
{
case Vehicle.TYPE_NONE:
m_linearFrictionTimescale = new Vector3(1000, 1000, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120 * invtimestep;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 1000 * invtimestep;
m_VhoverHeight = 0;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
m_flags = (VehicleFlag)0;
break;
case Vehicle.TYPE_SLED:
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1000;
m_linearMotorDecayTimescale = 120 * invtimestep;
m_angularMotorTimescale = 1000;
m_angularMotorDecayTimescale = 120 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 1;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 0;
m_linearDeflectionEfficiency = 1;
m_linearDeflectionTimescale = 1;
m_angularDeflectionEfficiency = 0;
m_angularDeflectionTimescale = 1000;
m_bankingEfficiency = 0;
m_bankingMix = 1;
m_bankingTimescale = 10;
m_flags &=
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
break;
case Vehicle.TYPE_CAR:
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
m_linearMotorTimescale = 1;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 1;
m_angularMotorDecayTimescale = 0.8f * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
m_linearDeflectionEfficiency = 1;
m_linearDeflectionTimescale = 2;
m_angularDeflectionEfficiency = 0;
m_angularDeflectionTimescale = 10;
m_verticalAttractionEfficiency = 1f;
m_verticalAttractionTimescale = 10f;
m_bankingEfficiency = -0.2f;
m_bankingMix = 1;
m_bankingTimescale = 1;
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.LIMIT_MOTOR_UP | VehicleFlag.HOVER_UP_ONLY);
break;
case Vehicle.TYPE_BOAT:
m_linearFrictionTimescale = new Vector3(10, 3, 2);
m_angularFrictionTimescale = new Vector3(10, 10, 10);
m_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 4 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0.5f;
m_VhoverTimescale = 2;
m_VehicleBuoyancy = 1;
m_linearDeflectionEfficiency = 0.5f;
m_linearDeflectionTimescale = 3;
m_angularDeflectionEfficiency = 0.5f;
m_angularDeflectionTimescale = 5;
m_verticalAttractionEfficiency = 0.5f;
m_verticalAttractionTimescale = 5f;
m_bankingEfficiency = -0.3f;
m_bankingMix = 0.8f;
m_bankingTimescale = 1;
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.LIMIT_ROLL_ONLY);
m_flags |= (VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP |
VehicleFlag.HOVER_WATER_ONLY);
break;
case Vehicle.TYPE_AIRPLANE:
m_linearFrictionTimescale = new Vector3(200, 10, 5);
m_angularFrictionTimescale = new Vector3(20, 20, 20);
m_linearMotorTimescale = 2;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 4;
m_angularMotorDecayTimescale = 8 * invtimestep;
m_VhoverHeight = 0;
m_VhoverEfficiency = 0.5f;
m_VhoverTimescale = 1000;
m_VehicleBuoyancy = 0;
m_linearDeflectionEfficiency = 0.5f;
m_linearDeflectionTimescale = 0.5f;
m_angularDeflectionEfficiency = 1;
m_angularDeflectionTimescale = 2;
m_verticalAttractionEfficiency = 0.9f;
m_verticalAttractionTimescale = 2f;
m_bankingEfficiency = 1;
m_bankingMix = 0.7f;
m_bankingTimescale = 2;
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
break;
case Vehicle.TYPE_BALLOON:
m_linearFrictionTimescale = new Vector3(5, 5, 5);
m_angularFrictionTimescale = new Vector3(10, 10, 10);
m_linearMotorTimescale = 5;
m_linearMotorDecayTimescale = 60 * invtimestep;
m_angularMotorTimescale = 6;
m_angularMotorDecayTimescale = 10 * invtimestep;
m_VhoverHeight = 5;
m_VhoverEfficiency = 0.8f;
m_VhoverTimescale = 10;
m_VehicleBuoyancy = 1;
m_linearDeflectionEfficiency = 0;
m_linearDeflectionTimescale = 5 * invtimestep;
m_angularDeflectionEfficiency = 0;
m_angularDeflectionTimescale = 5;
m_verticalAttractionEfficiency = 0f;
m_verticalAttractionTimescale = 1000f;
m_bankingEfficiency = 0;
m_bankingMix = 0.7f;
m_bankingTimescale = 5;
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY |
VehicleFlag.HOVER_TERRAIN_ONLY |
VehicleFlag.HOVER_UP_ONLY |
VehicleFlag.NO_DEFLECTION_UP |
VehicleFlag.LIMIT_MOTOR_UP);
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY |
VehicleFlag.HOVER_GLOBAL_HEIGHT);
break;
}
}//end SetDefaultsForType
internal void Stop()
{
m_lmEfect = 0;
m_amEfect = 0;
}
public static Vector3 Xrot(Quaternion rot)
{
Vector3 vec;
rot.Normalize(); // just in case
vec.X = 2 * (rot.X * rot.X + rot.W * rot.W) - 1;
vec.Y = 2 * (rot.X * rot.Y + rot.Z * rot.W);
vec.Z = 2 * (rot.X * rot.Z - rot.Y * rot.W);
return vec;
}
public static Vector3 Zrot(Quaternion rot)
{
Vector3 vec;
rot.Normalize(); // just in case
vec.X = 2 * (rot.X * rot.Z + rot.Y * rot.W);
vec.Y = 2 * (rot.Y * rot.Z - rot.X * rot.W);
vec.Z = 2 * (rot.Z * rot.Z + rot.W * rot.W) - 1;
return vec;
}
private const float halfpi = 0.5f * (float)Math.PI;
public static Vector3 ubitRot2Euler(Quaternion rot)
{
// returns roll in X
// pitch in Y
// yaw in Z
Vector3 vec;
// assuming rot is normalised
// rot.Normalize();
float zX = rot.X * rot.Z + rot.Y * rot.W;
if (zX < -0.49999f)
{
vec.X = 0;
vec.Y = -halfpi;
vec.Z = (float)(-2d * Math.Atan(rot.X / rot.W));
}
else if (zX > 0.49999f)
{
vec.X = 0;
vec.Y = halfpi;
vec.Z = (float)(2d * Math.Atan(rot.X / rot.W));
}
else
{
vec.Y = (float)Math.Asin(2 * zX);
float sqw = rot.W * rot.W;
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
float zZ = rot.Z * rot.Z + sqw - 0.5f;
vec.X = (float)Math.Atan2(minuszY, zZ);
float yX = rot.Z * rot.W - rot.X * rot.Y; //( have negative ?)
float yY = rot.X * rot.X + sqw - 0.5f;
vec.Z = (float)Math.Atan2(yX, yY);
}
return vec;
}
public static void GetRollPitch(Quaternion rot, out float roll, out float pitch)
{
// assuming rot is normalised
// rot.Normalize();
float zX = rot.X * rot.Z + rot.Y * rot.W;
if (zX < -0.49999f)
{
roll = 0;
pitch = -halfpi;
}
else if (zX > 0.49999f)
{
roll = 0;
pitch = halfpi;
}
else
{
pitch = (float)Math.Asin(2 * zX);
float minuszY = rot.X * rot.W - rot.Y * rot.Z;
float zZ = rot.Z * rot.Z + rot.W * rot.W - 0.5f;
roll = (float)Math.Atan2(minuszY, zZ);
}
return ;
}
internal void Step()//float pTimestep)
{
IntPtr Body = rootPrim.Body;
d.Quaternion rot = d.BodyGetQuaternion(Body);
Quaternion objrotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
Quaternion rotq = objrotq; // rotq = rotation of object
rotq *= m_referenceFrame; // rotq is now rotation in vehicle reference frame
Quaternion irotq = Quaternion.Inverse(rotq);
d.Vector3 dvtmp;
Vector3 tmpV;
Vector3 curVel; // velocity in world
Vector3 curAngVel; // angular velocity in world
Vector3 force = Vector3.Zero; // actually linear aceleration until mult by mass in world frame
Vector3 torque = Vector3.Zero;// actually angular aceleration until mult by Inertia in vehicle frame
d.Vector3 dtorque = new d.Vector3();
dvtmp = d.BodyGetLinearVel(Body);
curVel.X = dvtmp.X;
curVel.Y = dvtmp.Y;
curVel.Z = dvtmp.Z;
Vector3 curLocalVel = curVel * irotq; // current velocity in local
dvtmp = d.BodyGetAngularVel(Body);
curAngVel.X = dvtmp.X;
curAngVel.Y = dvtmp.Y;
curAngVel.Z = dvtmp.Z;
Vector3 curLocalAngVel = curAngVel * irotq; // current angular velocity in local
// linear motor
if (m_lmEfect > 0.01 && m_linearMotorTimescale < 1000)
{
tmpV = m_linearMotorDirection - curLocalVel; // velocity error
tmpV *= m_lmEfect / m_linearMotorTimescale; // error to correct in this timestep
tmpV *= rotq; // to world
if ((m_flags & VehicleFlag.LIMIT_MOTOR_UP) != 0)
tmpV.Z = 0;
if (m_linearMotorOffset.X != 0 || m_linearMotorOffset.Y != 0 || m_linearMotorOffset.Z != 0)
{
// have offset, do it now
tmpV *= rootPrim.Mass;
d.BodyAddForceAtRelPos(Body, tmpV.X, tmpV.Y, tmpV.Z, m_linearMotorOffset.X, m_linearMotorOffset.Y, m_linearMotorOffset.Z);
}
else
{
force.X += tmpV.X;
force.Y += tmpV.Y;
force.Z += tmpV.Z;
}
m_lmEfect *= (1.0f - 1.0f / m_linearMotorDecayTimescale);
}
else
m_lmEfect = 0;
// friction
if (curLocalVel.X != 0 || curLocalVel.Y != 0 || curLocalVel.Z != 0)
{
tmpV.X = -curLocalVel.X / m_linearFrictionTimescale.X;
tmpV.Y = -curLocalVel.Y / m_linearFrictionTimescale.Y;
tmpV.Z = -curLocalVel.Z / m_linearFrictionTimescale.Z;
tmpV *= rotq; // to world
force.X += tmpV.X;
force.Y += tmpV.Y;
force.Z += tmpV.Z;
}
// hover
if (m_VhoverTimescale < 300)
{
d.Vector3 pos = d.BodyGetPosition(Body);
// default to global
float perr = m_VhoverHeight - pos.Z;;
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
{
perr += _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
}
else if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
{
perr += _pParentScene.GetWaterLevel();
}
else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == 0)
{
float t = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y);
float w = _pParentScene.GetWaterLevel();
if (t > w)
perr += t;
else
perr += w;
}
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) == 0 || perr > 0)
{
force.Z += (perr / m_VhoverTimescale / m_VhoverTimescale - curVel.Z * m_VhoverEfficiency) / _pParentScene.ODE_STEPSIZE;
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
}
else // no buoyancy
force.Z += _pParentScene.gravityz;
}
else
{
// default gravity and buoancy
force.Z += _pParentScene.gravityz * (1f - m_VehicleBuoyancy);
}
// linear deflection
if (m_linearDeflectionEfficiency > 0)
{
float len = curVel.Length();
Vector3 atAxis;
atAxis = Xrot(rotq); // where are we pointing to
atAxis *= len; // make it same size as world velocity vector
tmpV = -atAxis; // oposite direction
atAxis -= curVel; // error to one direction
len = atAxis.LengthSquared();
tmpV -= curVel; // error to oposite
float lens = tmpV.LengthSquared();
if (len > 0.01 || lens > 0.01) // do nothing if close enougth
{
if (len < lens)
tmpV = atAxis;
tmpV *= (m_linearDeflectionEfficiency / m_linearDeflectionTimescale); // error to correct in this timestep
force.X += tmpV.X;
force.Y += tmpV.Y;
if ((m_flags & VehicleFlag.NO_DEFLECTION_UP) == 0)
force.Z += tmpV.Z;
}
}
// angular motor
if (m_amEfect > 0.01 && m_angularMotorTimescale < 1000)
{
tmpV = m_angularMotorDirection - curLocalAngVel; // velocity error
tmpV *= m_amEfect / m_angularMotorTimescale; // error to correct in this timestep
torque.X += tmpV.X;
torque.Y += tmpV.Y;
torque.Z += tmpV.Z;
m_amEfect *= (1 - 1.0f / m_angularMotorDecayTimescale);
}
else
m_amEfect = 0;
// angular friction
if (curLocalAngVel.X != 0 || curLocalAngVel.Y != 0 || curLocalAngVel.Z != 0)
{
torque.X -= curLocalAngVel.X / m_angularFrictionTimescale.X;
torque.Y -= curLocalAngVel.Y / m_angularFrictionTimescale.Y;
torque.Z -= curLocalAngVel.Z / m_angularFrictionTimescale.Z;
}
// angular deflection
if (m_angularDeflectionEfficiency > 0)
{
Vector3 dirv;
if (curLocalVel.X > 0.01f)
dirv = curLocalVel;
else if (curLocalVel.X < -0.01f)
// use oposite
dirv = -curLocalVel;
else
{
// make it fall into small positive x case
dirv.X = 0.01f;
dirv.Y = curLocalVel.Y;
dirv.Z = curLocalVel.Z;
}
float ftmp = m_angularDeflectionEfficiency / m_angularDeflectionTimescale;
if (Math.Abs(dirv.Z) > 0.01)
{
torque.Y += - (float)Math.Atan2(dirv.Z, dirv.X) * ftmp;
}
if (Math.Abs(dirv.Y) > 0.01)
{
torque.Z += (float)Math.Atan2(dirv.Y, dirv.X) * ftmp;
}
}
// vertical atractor
if (m_verticalAttractionTimescale < 300)
{
float roll;
float pitch;
GetRollPitch(irotq, out roll, out pitch);
float ftmp = 1.0f / m_verticalAttractionTimescale / m_verticalAttractionTimescale / _pParentScene.ODE_STEPSIZE;
float ftmp2 = m_verticalAttractionEfficiency / _pParentScene.ODE_STEPSIZE;
if (Math.Abs(roll) > 0.01) // roll
{
torque.X -= -roll * ftmp + curLocalAngVel.X * ftmp2;
}
if (Math.Abs(pitch) > 0.01 && ((m_flags & VehicleFlag.LIMIT_ROLL_ONLY) == 0)) // pitch
{
torque.Y -= -pitch * ftmp + curLocalAngVel.Y * ftmp2;
}
if (m_bankingEfficiency != 0 && Math.Abs(roll) > 0.01)
{
float broll = roll * m_bankingEfficiency; ;
if (m_bankingMix != 0)
{
float vfact = Math.Abs(curLocalVel.X) / 10.0f;
if (vfact > 1.0f) vfact = 1.0f;
if (curLocalVel.X >= 0)
broll *= ((1 - m_bankingMix) + vfact);
else
broll *= -((1 - m_bankingMix) + vfact);
}
broll = (broll - curLocalAngVel.Z) / m_bankingTimescale;
// torque.Z += broll;
// make z rot be in world Z not local as seems to be in sl
tmpV.X = 0;
tmpV.Y = 0;
tmpV.Z = broll;
tmpV *= irotq;
torque.X += tmpV.X;
torque.Y += tmpV.Y;
torque.Z += tmpV.Z;
}
}
d.Mass dmass;
d.BodyGetMass(Body,out dmass);
if (force.X != 0 || force.Y != 0 || force.Z != 0)
{
force *= dmass.mass;
d.BodySetForce(Body, force.X, force.Y, force.Z);
}
if (torque.X != 0 || torque.Y != 0 || torque.Z != 0)
{
torque *= m_referenceFrame; // to object frame
dtorque.X = torque.X;
dtorque.Y = torque.Y;
dtorque.Z = torque.Z;
d.MultiplyM3V3(out dvtmp, ref dmass.I, ref dtorque);
d.BodyAddRelTorque(Body, dvtmp.X, dvtmp.Y, dvtmp.Z); // add torque in object frame
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,443 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using OpenMetaverse;
using OpenSim.Region.Physics.Manager;
using OdeAPI;
using log4net;
namespace OpenSim.Region.Physics.OdePlugin
{
/// <summary>
/// Processes raycast requests as ODE is in a state to be able to do them.
/// This ensures that it's thread safe and there will be no conflicts.
/// Requests get returned by a different thread then they were requested by.
/// </summary>
public class ODERayCastRequestManager
{
/// <summary>
/// Pending ray requests
/// </summary>
protected OpenSim.Framework.LocklessQueue<ODERayRequest> m_PendingRequests = new OpenSim.Framework.LocklessQueue<ODERayRequest>();
/// <summary>
/// Scene that created this object.
/// </summary>
private OdeScene m_scene;
IntPtr ray;
private const int ColisionContactGeomsPerTest = 5;
/// <summary>
/// ODE near callback delegate
/// </summary>
private d.NearCallback nearCallback;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private List<ContactResult> m_contactResults = new List<ContactResult>();
public ODERayCastRequestManager(OdeScene pScene)
{
m_scene = pScene;
nearCallback = near;
ray = d.CreateRay(IntPtr.Zero, 1.0f);
}
/// <summary>
/// Queues a raycast
/// </summary>
/// <param name="position">Origin of Ray</param>
/// <param name="direction">Ray normal</param>
/// <param name="length">Ray length</param>
/// <param name="retMethod">Return method to send the results</param>
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.Count = 0;
req.length = length;
req.Normal = direction;
req.Origin = position;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = 0;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.Count = 0;
req.length = length;
req.Normal = direction;
req.Origin = position;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = 0;
m_PendingRequests.Enqueue(req);
}
/// <summary>
/// Queues a raycast
/// </summary>
/// <param name="position">Origin of Ray</param>
/// <param name="direction">Ray normal</param>
/// <param name="length">Ray length</param>
/// <param name="count"></param>
/// <param name="retMethod">Return method to send the results</param>
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = IntPtr.Zero;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
{
ODERayRequest req = new ODERayRequest();
req.geom = geom;
req.callbackMethod = retMethod;
req.length = length;
req.Normal = direction;
req.Origin = position;
req.Count = count;
m_PendingRequests.Enqueue(req);
}
/// <summary>
/// Process all queued raycast requests
/// </summary>
/// <returns>Time in MS the raycasts took to process.</returns>
public int ProcessQueuedRequests()
{
int time = System.Environment.TickCount;
if (m_PendingRequests.Count <= 0)
return 0;
if (m_scene.ContactgeomsArray == IntPtr.Zero) // oops something got wrong or scene isn't ready still
{
m_PendingRequests.Clear();
return 0;
}
ODERayRequest req;
int i = 50; // arbitary limit of processed tests per frame
while(m_PendingRequests.Dequeue(out req))
{
if (req.geom == IntPtr.Zero)
doSpaceRay(req);
else
doGeomRay(req);
if(--i < 0)
break;
}
lock (m_contactResults)
m_contactResults.Clear();
return System.Environment.TickCount - time;
}
/// <summary>
/// Method that actually initiates the raycast with full top space
/// </summary>
/// <param name="req"></param>
private void doSpaceRay(ODERayRequest req)
{
// Create the ray
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
d.GeomRaySetLength(ray, req.length);
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
// Collide test
d.SpaceCollide2(m_scene.TopSpace, ray, IntPtr.Zero, nearCallback);
// Remove Ray
// d.GeomDestroy(ray);
if (req.callbackMethod == null)
return;
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
float distance = 999999999999f;
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
lock (m_contactResults)
{
foreach (ContactResult cResult in m_contactResults)
{
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
((RayCallback)req.callbackMethod)(m_contactResults);
lock (m_PendingRequests)
m_contactResults.Clear();
}
}
/// <summary>
/// Method that actually initiates the raycast with a geom
/// </summary>
/// <param name="req"></param>
private void doGeomRay(ODERayRequest req)
{
// Create the ray
// IntPtr ray = d.CreateRay(m_scene.TopSpace, req.length);
d.GeomRaySetLength(ray, req.length);
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
// Collide test
d.SpaceCollide2(req.geom, ray, IntPtr.Zero, nearCallback); // still do this to have full AABB pre test
// Remove Ray
// d.GeomDestroy(ray);
if (req.callbackMethod == null)
return;
if (req.callbackMethod is RaycastCallback)
{
// Define default results
bool hitYN = false;
uint hitConsumerID = 0;
float distance = 999999999999f;
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
Vector3 snormal = Vector3.Zero;
// Find closest contact and object.
lock (m_contactResults)
{
foreach (ContactResult cResult in m_contactResults)
{
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
{
closestcontact = cResult.Pos;
hitConsumerID = cResult.ConsumerID;
distance = cResult.Depth;
hitYN = true;
snormal = cResult.Normal;
}
}
m_contactResults.Clear();
}
((RaycastCallback)req.callbackMethod)(hitYN, closestcontact, hitConsumerID, distance, snormal);
}
else
{
((RayCallback)req.callbackMethod)(m_contactResults);
lock (m_PendingRequests)
m_contactResults.Clear();
}
}
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
{
IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest)
return false;
IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
newcontactgeom = (d.ContactGeom)Marshal.PtrToStructure(contactptr, typeof(d.ContactGeom));
return true;
}
// This is the standard Near. g2 is the ray
private void near(IntPtr space, IntPtr g1, IntPtr g2)
{
//Don't test against heightfield Geom, or you'll be sorry!
// Exclude heightfield geom
if (g1 == IntPtr.Zero || g1 == g2)
return;
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass)
return;
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
if (d.GeomIsSpace(g1))
{
try
{
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
}
return;
}
int count = 0;
try
{
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
}
catch (SEHException)
{
m_log.Error("[PHYSICS Ray]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
}
catch (Exception e)
{
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
return;
}
if (count == 0)
return;
PhysicsActor p1 = null;
if (g1 != IntPtr.Zero)
m_scene.actor_name_map.TryGetValue(g1, out p1);
d.ContactGeom curcontact = new d.ContactGeom();
// Loop over contacts, build results.
for (int i = 0; i < count; i++)
{
if (!GetCurContactGeom(i, ref curcontact))
break;
if (p1 != null) {
if (p1 is OdePrim)
{
ContactResult collisionresult = new ContactResult();
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
collisionresult.Depth = curcontact.depth;
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
curcontact.normal.Z);
lock (m_contactResults)
m_contactResults.Add(collisionresult);
}
}
}
}
/// <summary>
/// Dereference the creator scene so that it can be garbage collected if needed.
/// </summary>
internal void Dispose()
{
m_scene = null;
}
}
public struct ODERayRequest
{
public IntPtr geom;
public Vector3 Origin;
public Vector3 Normal;
public int Count;
public float length;
public object callbackMethod;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,86 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Diagnostics;
using log4net;
using Nini.Config;
using OdeAPI;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
/// <summary>
/// ODE plugin
/// </summary>
public class OdePlugin : IPhysicsPlugin
{
//private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private OdeScene m_scene;
public bool Init()
{
if (d.InitODE2(0) != 0)
{
if (d.AllocateODEDataForThread(~0U) == 0)
{
d.CloseODE();
return false;
}
return true;
}
return false;
}
public PhysicsScene GetScene(String sceneIdentifier)
{
if (m_scene == null)
{
m_scene = new OdeScene(sceneIdentifier);
}
return (m_scene);
}
public string GetName()
{
return ("UbitODE");
}
public void Dispose()
{
d.CloseODE();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,99 @@
/*
* Copyright ODE
* Ode.NET - .NET bindings for ODE
* Jason Perkins (starkos@industriousone.com)
* Licensed under the New BSD
* Part of the OpenDynamicsEngine
Open Dynamics Engine
Copyright (c) 2001-2007, Russell L. Smith.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
Neither the names of ODE's copyright owner nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*
*/
using System;
using System.Runtime.InteropServices;
using OdeAPI;
namespace ODEDrawstuff
{
/*#if dDOUBLE
using dReal = System.Double;
#else
*/
using dReal = System.Single;
//#endif
public static class ds
{
public const int VERSION = 2;
public enum Texture
{
None,
Wood
}
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void CallbackFunction(int arg);
[StructLayout(LayoutKind.Sequential)]
public struct Functions
{
public int version;
public CallbackFunction start;
public CallbackFunction step;
public CallbackFunction command;
public CallbackFunction stop;
public string path_to_textures;
}
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
public static extern void SetColor(float red, float green, float blue);
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
public static extern void SetTexture(Texture texture);
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
}
}

View File

@@ -0,0 +1,7 @@
<configuration>
<dllmap os="osx" dll="ode" target="libode.dylib" />
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="ode" target="libode-x86_64" />
<dllmap os="!windows,osx" cpu="x86" dll="ode" target="libode" />
<dllmap os="!windows,osx" cpu="ppc64" dll="ode" target="libode-ppc64" />
<dllmap os="!windows,osx" cpu="s390x" dll="ode" target="libode-s390x" />
</configuration>

Binary file not shown.

BIN
bin/Physics/libode.so Normal file

Binary file not shown.

View File

@@ -6,7 +6,7 @@
<CompilerDefines>TRACE;DEBUG</CompilerDefines>
<OptimizeCode>false</OptimizeCode>
<CheckUnderflowOverflow>false</CheckUnderflowOverflow>
<AllowUnsafe>false</AllowUnsafe>
<AllowUnsafe>true</AllowUnsafe>
<WarningLevel>4</WarningLevel>
<WarningsAsErrors>false</WarningsAsErrors>
<SuppressWarnings/>
@@ -606,6 +606,36 @@
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.UbitOdePlugin" path="OpenSim/Region/Physics/UbitOdePlugin" type="Library">
<Configuration name="Debug">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<Configuration name="Release">
<Options>
<OutputPath>../../../../bin/Physics/</OutputPath>
</Options>
</Configuration>
<ReferencePath>../../../../bin/</ReferencePath>
<Reference name="System"/>
<Reference name="System.Core"/>
<Reference name="OpenMetaverseTypes" path="../../../../bin/"/>
<Reference name="Nini" path="../../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Region.Physics.Manager"/>
<Reference name="log4net" path="../../../../bin/"/>
<Files>
<Match pattern="*.cs" recurse="true">
<Exclude name="Tests" pattern="Tests"/>
</Match>
</Files>
</Project>
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ConvexDecompositionDotNet" path="OpenSim/Region/Physics/ConvexDecompositionDotNet" type="Library">
<Configuration name="Debug">
<Options>
@@ -3316,16 +3346,12 @@
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
<Reference name="XMLRPC" path="../../../bin/"/>
<Reference name="OpenSim.Framework"/>
<Reference name="OpenSim.Framework.Communications"/>
<Reference name="OpenSim.Framework.Console"/>
<Reference name="OpenSim.Framework.Servers.HttpServer"/>
<Reference name="OpenSim.Region.CoreModules"/>
<Reference name="OpenSim.Region.Framework"/>
<Reference name="OpenSim.Region.OptionalModules"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
<Reference name="OpenSim.Region.ScriptEngine.XEngine"/>
<Reference name="OpenSim.Services.Interfaces"/>
<Reference name="OpenSim.Services.AvatarService"/>
<Reference name="OpenSim.Region.ScriptEngine.Shared"/>
<Reference name="OpenSim.Tests.Common"/>
<Files>
<Match pattern="*.cs" recurse="false"/>

View File

@@ -1,4 +1,4 @@
bin\Prebuild.exe /target nant
bin\Prebuild.exe /target vs2008
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild opensim.sln > compile.bat
echo C:\WINDOWS\Microsoft.NET\Framework\v3.5\msbuild OpenSim.sln > compile.bat