diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
index 4cd587cb71..2405d4a6bf 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
-[assembly : AssemblyVersion("1.0.*")]
\ No newline at end of file
+[assembly : AssemblyVersion("1.0.*")]
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index d7d91bebcd..64118870de 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -1,336 +1,365 @@
-/*
-* 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 OpenSim 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.Collections.Generic;
-using Axiom.Math;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.BasicPhysicsPlugin
-{
- ///
- /// Will be the PhysX plugin but for now will be a very basic physics engine
- ///
- public class BasicPhysicsPlugin : IPhysicsPlugin
- {
- public BasicPhysicsPlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene()
- {
- return new BasicScene();
- }
-
- public string GetName()
- {
- return ("basicphysics");
- }
-
- public void Dispose()
- {
- }
- }
-
- public class BasicScene : PhysicsScene
- {
- private List _actors = new List();
- private float[] _heightMap;
-
- public BasicScene()
- {
- }
-
- public override void Initialise(IMesher meshmerizer)
- {
- // Does nothing right now
- }
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
- {
- BasicActor act = new BasicActor();
- act.Position = position;
- _actors.Add(act);
- return act;
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- BasicActor act = (BasicActor) actor;
- if (_actors.Contains(act))
- {
- _actors.Remove(act);
- }
- }
-
-/*
- public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
- {
- return null;
- }
-*/
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint LocalID)
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false, LocalID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, modified
- {
- return null;
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- }
-
- public override float Simulate(float timeStep)
- {
- float fps = 0;
- for (int i = 0; i < _actors.Count; ++i)
- {
- BasicActor actor = _actors[i];
-
- actor.Position.X += actor.Velocity.X*timeStep;
- actor.Position.Y += actor.Velocity.Y*timeStep;
-
- if (actor.Position.Y < 0)
- {
- actor.Position.Y = 0.1F;
- }
- else if (actor.Position.Y >= 256)
- {
- actor.Position.Y = 255.9F;
- }
-
- if (actor.Position.X < 0)
- {
- actor.Position.X = 0.1F;
- }
- else if (actor.Position.X >= 256)
- {
- actor.Position.X = 255.9F;
- }
-
- float height = _heightMap[(int) actor.Position.Y*256 + (int) actor.Position.X] + 1.0f;
- if (actor.Flying)
- {
- if (actor.Position.Z + (actor.Velocity.Z*timeStep) <
- _heightMap[(int) actor.Position.Y*256 + (int) actor.Position.X] + 2)
- {
- actor.Position.Z = height;
- actor.Velocity.Z = 0;
- }
- else
- {
- actor.Position.Z += actor.Velocity.Z*timeStep;
- }
- }
- else
- {
- actor.Position.Z = height;
- actor.Velocity.Z = 0;
- }
- }
- return fps;
- }
-
- public override void GetResults()
- {
- }
-
- public override bool IsThreaded
- {
- get { return (false); // for now we won't be multithreaded
- }
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- _heightMap = heightMap;
- }
-
- public override void DeleteTerrain()
- {
- }
- }
-
- public class BasicActor : PhysicsActor
- {
- private PhysicsVector _position;
- private PhysicsVector _velocity;
- private PhysicsVector _acceleration;
- private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
- private bool flying;
- private bool iscolliding;
-
- public BasicActor()
- {
- _velocity = new PhysicsVector();
- _position = new PhysicsVector();
- _acceleration = new PhysicsVector();
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Agent; }
- set { return; }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool Flying
- {
- get { return flying; }
- set { flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set { _position = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return PhysicsVector.Zero; }
- set { }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
-
- public override Quaternion Orientation
- {
- get { return Quaternion.Identity; }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public override bool Kinematic
- {
- get { return true; }
- set { }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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.Collections.Generic;
+using Axiom.Math;
+using OpenSim.Framework;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.BasicPhysicsPlugin
+{
+ ///
+ /// Will be the PhysX plugin but for now will be a very basic physics engine
+ ///
+ public class BasicPhysicsPlugin : IPhysicsPlugin
+ {
+ public BasicPhysicsPlugin()
+ {
+ }
+
+ public bool Init()
+ {
+ return true;
+ }
+
+ public PhysicsScene GetScene()
+ {
+ return new BasicScene();
+ }
+
+ public string GetName()
+ {
+ return ("basicphysics");
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ public class BasicScene : PhysicsScene
+ {
+ private List _actors = new List();
+ private float[] _heightMap;
+
+ public BasicScene()
+ {
+ }
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
+ {
+
+ }
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ BasicActor act = new BasicActor();
+ act.Position = position;
+ _actors.Add(act);
+ return act;
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ }
+
+ public override void RemoveAvatar(PhysicsActor actor)
+ {
+ BasicActor act = (BasicActor) actor;
+ if (_actors.Contains(act))
+ {
+ _actors.Remove(act);
+ }
+ }
+
+/*
+ public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
+ {
+ return null;
+ }
+*/
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint LocalID)
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false, LocalID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, modified
+ {
+ return null;
+ }
+
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ public override float Simulate(float timeStep)
+ {
+ float fps = 0;
+ for (int i = 0; i < _actors.Count; ++i)
+ {
+ BasicActor actor = _actors[i];
+
+ actor.Position.X += actor.Velocity.X*timeStep;
+ actor.Position.Y += actor.Velocity.Y*timeStep;
+
+ if (actor.Position.Y < 0)
+ {
+ actor.Position.Y = 0.1F;
+ }
+ else if (actor.Position.Y >= Constants.RegionSize)
+ {
+ actor.Position.Y = 255.9F;
+ }
+
+ if (actor.Position.X < 0)
+ {
+ actor.Position.X = 0.1F;
+ }
+ else if (actor.Position.X >= Constants.RegionSize)
+ {
+ actor.Position.X = 255.9F;
+ }
+
+ float height = _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 1.0f;
+ if (actor.Flying)
+ {
+ if (actor.Position.Z + (actor.Velocity.Z*timeStep) <
+ _heightMap[(int)actor.Position.Y * Constants.RegionSize + (int)actor.Position.X] + 2)
+ {
+ actor.Position.Z = height;
+ actor.Velocity.Z = 0;
+ }
+ else
+ {
+ actor.Position.Z += actor.Velocity.Z*timeStep;
+ }
+ }
+ else
+ {
+ actor.Position.Z = height;
+ actor.Velocity.Z = 0;
+ }
+ }
+ return fps;
+ }
+
+ public override void GetResults()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ get { return (false); // for now we won't be multithreaded
+ }
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ _heightMap = heightMap;
+ }
+
+ public override void DeleteTerrain()
+ {
+ }
+ }
+
+ public class BasicActor : PhysicsActor
+ {
+ private PhysicsVector _position;
+ private PhysicsVector _velocity;
+ private PhysicsVector _acceleration;
+ private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
+ private bool flying;
+ private bool iscolliding;
+
+ public BasicActor()
+ {
+ _velocity = new PhysicsVector();
+ _position = new PhysicsVector();
+ _acceleration = new PhysicsVector();
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Agent; }
+ set { return; }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Flying
+ {
+ get { return flying; }
+ set { flying = value; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set { _position = value; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return PhysicsVector.Zero; }
+ set { }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set { _velocity = value; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return Quaternion.Identity; }
+ set { }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return true; }
+ set { }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index f6d0f6a9da..7d5d6d0023 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -1,1531 +1,1558 @@
-/*
-* 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 OpenSim 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.
-*
-*/
-
-#region Copyright
-
-/*
-* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.
-*
-*/
-
-#endregion
-
-#region References
-
-using System;
-using System.Collections.Generic;
-using MonoXnaCompactMaths;
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-using XnaDevRu.BulletX;
-using XnaDevRu.BulletX.Dynamics;
-using AxiomQuaternion = Axiom.Math.Quaternion;
-using BoxShape=XnaDevRu.BulletX.BoxShape;
-
-#endregion
-
-namespace OpenSim.Region.Physics.BulletXPlugin
-{
- ///
- /// BulletXConversions are called now BulletXMaths
- /// This Class converts objects and types for BulletX and give some operations
- ///
- public class BulletXMaths
- {
- //Vector3
- public static Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector)
- {
- return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z);
- }
-
- public static PhysicsVector XnaVector3ToPhysicsVector(Vector3 xnaVector3)
- {
- return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z);
- }
-
- //Quaternion
- public static Quaternion AxiomQuaternionToXnaQuaternion(AxiomQuaternion axiomQuaternion)
- {
- return new Quaternion(axiomQuaternion.x, axiomQuaternion.y, axiomQuaternion.z, axiomQuaternion.w);
- }
-
- public static AxiomQuaternion XnaQuaternionToAxiomQuaternion(Quaternion xnaQuaternion)
- {
- return new AxiomQuaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z);
- }
-
- //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license):
- //- SetRotation (class MatrixOperations)
- //- GetRotation (class MatrixOperations)
- //- GetElement (class MathHelper)
- //- SetElement (class MathHelper)
- internal static void SetRotation(ref Matrix m, Quaternion q)
- {
- float d = q.LengthSquared();
- float s = 2f/d;
- float xs = q.X*s, ys = q.Y*s, zs = q.Z*s;
- float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs;
- float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs;
- float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs;
- m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
- xy + wz, 1 - (xx + zz), yz - wx, 0,
- xz - wy, yz + wx, 1 - (xx + yy), 0,
- m.M41, m.M42, m.M43, 1);
- }
-
- internal static Quaternion GetRotation(Matrix m)
- {
- Quaternion q = new Quaternion();
-
- float trace = m.M11 + m.M22 + m.M33;
-
- if (trace > 0)
- {
- float s = (float) Math.Sqrt(trace + 1);
- q.W = s*0.5f;
- s = 0.5f/s;
-
- q.X = (m.M32 - m.M23)*s;
- q.Y = (m.M13 - m.M31)*s;
- q.Z = (m.M21 - m.M12)*s;
- }
- else
- {
- int i = m.M11 < m.M22
- ?
- (m.M22 < m.M33 ? 2 : 1)
- :
- (m.M11 < m.M33 ? 2 : 0);
- int j = (i + 1)%3;
- int k = (i + 2)%3;
-
- float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1);
- SetElement(ref q, i, s*0.5f);
- s = 0.5f/s;
-
- q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s;
- SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s);
- SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s);
- }
-
- return q;
- }
-
- internal static float SetElement(ref Quaternion q, int index, float value)
- {
- switch (index)
- {
- case 0:
- q.X = value;
- break;
- case 1:
- q.Y = value;
- break;
- case 2:
- q.Z = value;
- break;
- case 3:
- q.W = value;
- break;
- }
-
- return 0;
- }
-
- internal static float GetElement(Matrix mat, int row, int col)
- {
- switch (row)
- {
- case 0:
- switch (col)
- {
- case 0:
- return mat.M11;
- case 1:
- return mat.M12;
- case 2:
- return mat.M13;
- }
- break;
- case 1:
- switch (col)
- {
- case 0:
- return mat.M21;
- case 1:
- return mat.M22;
- case 2:
- return mat.M23;
- }
- break;
- case 2:
- switch (col)
- {
- case 0:
- return mat.M31;
- case 1:
- return mat.M32;
- case 2:
- return mat.M33;
- }
- break;
- }
-
- return 0;
- }
- }
-
- ///
- /// PhysicsPlugin Class for BulletX
- ///
- public class BulletXPlugin : IPhysicsPlugin
- {
- private BulletXScene _mScene;
-
- public BulletXPlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene()
- {
- if (_mScene == null)
- {
- _mScene = new BulletXScene();
- }
- return (_mScene);
- }
-
- public string GetName()
- {
- return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX"
- }
-
- public void Dispose()
- {
- }
- }
-
-
- // Class to detect and debug collisions
- // Mainly used for debugging purposes
- internal class CollisionDispatcherLocal : CollisionDispatcher
- {
- private BulletXScene relatedScene;
-
- public CollisionDispatcherLocal(BulletXScene s)
- : base()
- {
- relatedScene = s;
- }
-
- public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
- {
- RigidBody rb;
- BulletXCharacter bxcA = null;
- BulletXPrim bxpA = null;
- Type t = bodyA.GetType();
- if (t == typeof (RigidBody))
- {
- rb = (RigidBody) bodyA;
- relatedScene._characters.TryGetValue(rb, out bxcA);
- relatedScene._prims.TryGetValue(rb, out bxpA);
- }
- String nameA;
- if (bxcA != null)
- nameA = bxcA._name;
- else if (bxpA != null)
- nameA = bxpA._name;
- else
- nameA = "null";
-
- BulletXCharacter bxcB = null;
- BulletXPrim bxpB = null;
- t = bodyB.GetType();
- if (t == typeof (RigidBody))
- {
- rb = (RigidBody) bodyB;
- relatedScene._characters.TryGetValue(rb, out bxcB);
- relatedScene._prims.TryGetValue(rb, out bxpB);
- }
- String nameB;
- if (bxcB != null)
- nameB = bxcB._name;
- else if (bxpB != null)
- nameB = bxpB._name;
- else
- nameB = "null";
-
- bool needsCollision = base.NeedsCollision(bodyA, bodyB);
-
- MainLog.Instance.Debug("BulletX", "A collision was detected between {0} and {1} --> {2}", nameA, nameB,
- needsCollision);
-
-
- return needsCollision;
- }
- }
-
- ///
- /// PhysicsScene Class for BulletX
- ///
- public class BulletXScene : PhysicsScene
- {
- #region BulletXScene Fields
-
- public DiscreteDynamicsWorld ddWorld;
- private CollisionDispatcher cDispatcher;
- private OverlappingPairCache opCache;
- private SequentialImpulseConstraintSolver sicSolver;
- public static Object BulletXLock = new Object();
-
- private const int minXY = 0;
- private const int minZ = 0;
- private const int maxXY = 256;
- private const int maxZ = 4096;
- private const int maxHandles = 32766; //Why? I don't know
- private const float gravity = 9.8f;
- private const float heightLevel0 = 77.0f;
- private const float heightLevel1 = 200.0f;
- private const float lowGravityFactor = 0.2f;
- //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
- private const int simulationSubSteps = 10;
- //private float[] _heightmap;
- private BulletXPlanet _simFlatPlanet;
- internal Dictionary _characters = new Dictionary();
- internal Dictionary _prims = new Dictionary();
-
- public IMesher mesher;
-
-
- public static float Gravity
- {
- get { return gravity; }
- }
-
- public static float HeightLevel0
- {
- get { return heightLevel0; }
- }
-
- public static float HeightLevel1
- {
- get { return heightLevel1; }
- }
-
- public static float LowGravityFactor
- {
- get { return lowGravityFactor; }
- }
-
- public static int MaxXY
- {
- get { return maxXY; }
- }
-
- public static int MaxZ
- {
- get { return maxZ; }
- }
-
- private List _forgottenRigidBodies = new List();
- internal string is_ex_message = "Can't remove rigidBody!: ";
-
- #endregion
-
- public BulletXScene()
- {
- cDispatcher = new CollisionDispatcherLocal(this);
- Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
- Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
- opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
- sicSolver = new SequentialImpulseConstraintSolver();
-
- lock (BulletXLock)
- {
- ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
- ddWorld.Gravity = new Vector3(0, 0, -gravity);
- }
- //this._heightmap = new float[65536];
- }
-
- public override void Initialise(IMesher meshmerizer)
- {
- mesher = meshmerizer;
- }
-
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
- {
- PhysicsVector pos = new PhysicsVector();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z + 20;
- BulletXCharacter newAv = null;
- lock (BulletXLock)
- {
- newAv = new BulletXCharacter(avName, this, pos);
- _characters.Add(newAv.RigidBody, newAv);
- }
- return newAv;
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- if (actor is BulletXCharacter)
- {
- lock (BulletXLock)
- {
- try
- {
- ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
- }
- catch (Exception ex)
- {
- BulletXMessage(is_ex_message + ex.Message, true);
- ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
- AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
- }
- _characters.Remove(((BulletXCharacter) actor).RigidBody);
- }
- GC.Collect();
- }
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, AxiomQuaternion rotation, uint localID)
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, AxiomQuaternion rotation, bool isPhysical, uint LocalID)
- {
- PhysicsActor result;
-
- switch (pbs.ProfileShape)
- {
- case ProfileShape.Square:
- /// support simple box & hollow box now; later, more shapes
- if (pbs.ProfileHollow == 0)
- {
- result = AddPrim(primName, position, size, rotation, null, null, isPhysical, LocalID);
- }
- else
- {
- IMesh mesh = mesher.CreateMesh(primName, pbs, size);
- result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, LocalID);
- }
- break;
-
- default:
- result = AddPrim(primName, position, size, rotation, null, null, isPhysical, LocalID);
- break;
- }
-
- return result;
- }
-
- public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation,
- IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical, uint localID)
- {
- BulletXPrim newPrim = null;
- lock (BulletXLock)
- {
- newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
- _prims.Add(newPrim.RigidBody, newPrim);
- }
- return newPrim;
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- if (prim is BulletXPrim)
- {
- lock (BulletXLock)
- {
- try
- {
- ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
- }
- catch (Exception ex)
- {
- BulletXMessage(is_ex_message + ex.Message, true);
- ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
- AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
- }
- _prims.Remove(((BulletXPrim) prim).RigidBody);
- }
- GC.Collect();
- }
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- }
-
- public override float Simulate(float timeStep)
- {
- float fps = 0;
- lock (BulletXLock)
- {
- //Try to remove garbage
- RemoveForgottenRigidBodies();
- //End of remove
- MoveAllObjects(timeStep);
-
-
- fps = (timeStep*simulationSubSteps);
-
- ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
- //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
- ValidateHeightForAll();
- //End heightmap validation.
- UpdateKineticsForAll();
- }
- return fps;
- }
-
- private void MoveAllObjects(float timeStep)
- {
- foreach (BulletXCharacter actor in _characters.Values)
- {
- actor.Move(timeStep);
- }
- foreach (BulletXPrim prim in _prims.Values)
- {
- }
- }
-
- private void ValidateHeightForAll()
- {
- float _height;
- foreach (BulletXCharacter actor in _characters.Values)
- {
- //_height = HeightValue(actor.RigidBodyPosition);
- _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
- actor.ValidateHeight(_height);
- //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
- }
- foreach (BulletXPrim prim in _prims.Values)
- {
- //_height = HeightValue(prim.RigidBodyPosition);
- _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
- prim.ValidateHeight(_height);
- //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
- }
- //foreach (BulletXCharacter actor in _characters)
- //{
- // actor.ValidateHeight(0);
- //}
- //foreach (BulletXPrim prim in _prims)
- //{
- // prim.ValidateHeight(0);
- //}
- }
-
- private void UpdateKineticsForAll()
- {
- //UpdatePosition > UpdateKinetics.
- //Not only position will be updated, also velocity cause acceleration.
- foreach (BulletXCharacter actor in _characters.Values)
- {
- actor.UpdateKinetics();
- }
- foreach (BulletXPrim prim in _prims.Values)
- {
- prim.UpdateKinetics();
- }
- //if(this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
- }
-
- public override void GetResults()
- {
- }
-
- public override bool IsThreaded
- {
- get { return (false); // for now we won't be multithreaded
- }
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
- //for (int i = 0; i < 65536; i++)
- //{
- // // this._heightmap[i] = (double)heightMap[i];
- // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
- // int x = i & 0xff;
- // int y = i >> 8;
- // this._heightmap[i] = heightMap[x * 256 + y];
- //}
-
- //float[] swappedHeightMap = new float[65536];
- ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
- //for (int i = 0; i < 65536; i++)
- //{
- // // this._heightmap[i] = (double)heightMap[i];
- // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
- // int x = i & 0xff;
- // int y = i >> 8;
- // swappedHeightMap[i] = heightMap[x * 256 + y];
- //}
- DeleteTerrain();
- //There is a BulletXLock inside the constructor of BulletXPlanet
- //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
- _simFlatPlanet = new BulletXPlanet(this, heightMap);
- //this._heightmap = heightMap;
- }
-
- public override void DeleteTerrain()
- {
- if (_simFlatPlanet != null)
- {
- lock (BulletXLock)
- {
- try
- {
- ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody);
- }
- catch (Exception ex)
- {
- BulletXMessage(is_ex_message + ex.Message, true);
- _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
- AddForgottenRigidBody(_simFlatPlanet.RigidBody);
- }
- }
- _simFlatPlanet = null;
- GC.Collect();
- BulletXMessage("Terrain erased!", false);
- }
- //this._heightmap = null;
- }
-
- internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
- {
- _forgottenRigidBodies.Add(forgottenRigidBody);
- }
-
- private void RemoveForgottenRigidBodies()
- {
- RigidBody forgottenRigidBody;
- int nRigidBodies = _forgottenRigidBodies.Count;
- for (int i = nRigidBodies - 1; i >= 0; i--)
- {
- forgottenRigidBody = _forgottenRigidBodies[i];
- try
- {
- ddWorld.RemoveRigidBody(forgottenRigidBody);
- _forgottenRigidBodies.Remove(forgottenRigidBody);
- BulletXMessage("Forgotten Rigid Body Removed", false);
- }
- catch (Exception ex)
- {
- BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
- }
- }
- GC.Collect();
- }
-
- internal void BulletXMessage(string message, bool isWarning)
- {
- PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
- }
-
- //temp
- //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
- //{
- // int li_x, li_y;
- // float height;
- // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
- // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
-
- // height = this._heightmap[li_y * 256 + li_x];
- // if (height < 0) height = 0;
- // else if (height > maxZ) height = maxZ;
-
- // return height;
- //}
- }
-
- ///
- /// Generic Physics Actor for BulletX inherit from PhysicActor
- ///
- public class BulletXActor : PhysicsActor
- {
- protected bool flying = false;
- protected bool _physical = false;
- protected PhysicsVector _position;
- protected PhysicsVector _velocity;
- protected PhysicsVector _size;
- protected PhysicsVector _acceleration;
- protected AxiomQuaternion _orientation;
- protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
- protected RigidBody rigidBody;
- protected int m_PhysicsActorType;
- private Boolean iscolliding = false;
- internal string _name;
-
- public BulletXActor(String name)
- {
- _name = name;
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set
- {
- lock (BulletXScene.BulletXLock)
- {
- _position = value;
- Translate();
- }
- }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set
- {
- lock (BulletXScene.BulletXLock)
- {
- //Static objects don' have linear velocity
- if (_physical)
- {
- _velocity = value;
- Speed();
- }
- else
- {
- _velocity = new PhysicsVector();
- }
- }
- }
- }
-
- public override PhysicsVector Size
- {
- get { return _size; }
- set
- {
- lock (BulletXScene.BulletXLock)
- {
- _size = value;
- }
- }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public override AxiomQuaternion Orientation
- {
- get { return _orientation; }
- set
- {
- lock (BulletXScene.BulletXLock)
- {
- _orientation = value;
- ReOrient();
- }
- }
- }
-
- public override float Mass
- {
- get { return ActorMass; }
- }
-
- public virtual float ActorMass
- {
- get { return 0; }
- }
-
- public override int PhysicsActorType
- {
- get { return (int) m_PhysicsActorType; }
- set { m_PhysicsActorType = value; }
- }
-
- public RigidBody RigidBody
- {
- get { return rigidBody; }
- }
-
- public Vector3 RigidBodyPosition
- {
- get { return rigidBody.CenterOfMassPosition; }
- }
-
- public override bool IsPhysical
- {
- get { return _physical; }
- set { _physical = value; }
- }
-
- public override bool Flying
- {
- get { return flying; }
- set { flying = value; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public virtual void SetAcceleration(PhysicsVector accel)
- {
- lock (BulletXScene.BulletXLock)
- {
- _acceleration = accel;
- }
- }
-
- public override bool Kinematic
- {
- get { return false; }
- set { }
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
- internal virtual void ValidateHeight(float heighmapPositionValue)
- {
- }
-
- internal virtual void UpdateKinetics()
- {
- }
-
- #region Methods for updating values of RigidBody
-
- protected internal void Translate()
- {
- Translate(_position);
- }
-
- protected internal void Translate(PhysicsVector _newPos)
- {
- Vector3 _translation;
- _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition;
- rigidBody.Translate(_translation);
- }
-
- protected internal void Speed()
- {
- Speed(_velocity);
- }
-
- protected internal void Speed(PhysicsVector _newSpeed)
- {
- Vector3 _speed;
- _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed);
- rigidBody.LinearVelocity = _speed;
- }
-
- protected internal void ReOrient()
- {
- ReOrient(_orientation);
- }
-
- protected internal void ReOrient(AxiomQuaternion _newOrient)
- {
- Quaternion _newOrientation;
- _newOrientation = BulletXMaths.AxiomQuaternionToXnaQuaternion(_newOrient);
- Matrix _comTransform = rigidBody.CenterOfMassTransform;
- BulletXMaths.SetRotation(ref _comTransform, _newOrientation);
- rigidBody.CenterOfMassTransform = _comTransform;
- }
-
- protected internal void ReSize()
- {
- ReSize(_size);
- }
-
- protected internal virtual void ReSize(PhysicsVector _newSize)
- {
- }
-
- public virtual void ScheduleTerseUpdate()
- {
- base.RequestPhysicsterseUpdate();
- }
-
- #endregion
- }
-
- ///
- /// PhysicsActor Character Class for BulletX
- ///
- public class BulletXCharacter : BulletXActor
- {
- public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos)
- : this("", parent_scene, pos)
- {
- }
-
- public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos)
- : this(avName, parent_scene, pos, new PhysicsVector(), new PhysicsVector(), new PhysicsVector(),
- AxiomQuaternion.Identity)
- {
- }
-
- public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
- PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
- : base(avName)
- {
- //This fields will be removed. They're temporal
- float _sizeX = 0.5f;
- float _sizeY = 0.5f;
- float _sizeZ = 1.6f;
- //.
- _position = pos;
- _velocity = velocity;
- _size = size;
- //---
- _size.X = _sizeX;
- _size.Y = _sizeY;
- _size.Z = _sizeZ;
- //.
- _acceleration = acceleration;
- _orientation = orientation;
- _physical = true;
-
- float _mass = 50.0f; //This depends of avatar's dimensions
- //For RigidBody Constructor. The next values might change
- float _linearDamping = 0.0f;
- float _angularDamping = 0.0f;
- float _friction = 0.5f;
- float _restitution = 0.0f;
- Matrix _startTransform = Matrix.Identity;
- Matrix _centerOfMassOffset = Matrix.Identity;
- lock (BulletXScene.BulletXLock)
- {
- _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
- //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f));
- //For now, like ODE, collisionShape = sphere of radious = 1.0
- CollisionShape _collisionShape = new SphereShape(1.0f);
- DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
- Vector3 _localInertia = new Vector3();
- _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
- rigidBody =
- new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
- _friction, _restitution);
- //rigidBody.ActivationState = ActivationState.DisableDeactivation;
- //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
- Vector3 _vDebugTranslation;
- _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
- rigidBody.Translate(_vDebugTranslation);
- parent_scene.ddWorld.AddRigidBody(rigidBody);
- }
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Agent; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get { return base.Position; }
- set { base.Position = value; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return base.Velocity; }
- set { base.Velocity = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return base.Size; }
- set { base.Size = value; }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return base.Acceleration; }
- }
-
- public override AxiomQuaternion Orientation
- {
- get { return base.Orientation; }
- set { base.Orientation = value; }
- }
-
- public override bool Flying
- {
- get { return base.Flying; }
- set { base.Flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return base.IsColliding; }
- set { base.IsColliding = value; }
- }
-
- public override bool Kinematic
- {
- get { return base.Kinematic; }
- set { base.Kinematic = value; }
- }
-
- public override void SetAcceleration(PhysicsVector accel)
- {
- base.SetAcceleration(accel);
- }
-
- public override void AddForce(PhysicsVector force)
- {
- base.AddForce(force);
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- base.SetMomentum(momentum);
- }
-
- internal void Move(float timeStep)
- {
- Vector3 vec = new Vector3();
- //At this point it's supossed that:
- //_velocity == rigidBody.LinearVelocity
- vec.X = _velocity.X;
- vec.Y = _velocity.Y;
- vec.Z = _velocity.Z;
- if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
- if (flying)
- {
- //Antigravity with movement
- if (_position.Z <= BulletXScene.HeightLevel0)
- {
- vec.Z += BulletXScene.Gravity*timeStep;
- }
- //Lowgravity with movement
- else if ((_position.Z > BulletXScene.HeightLevel0)
- && (_position.Z <= BulletXScene.HeightLevel1))
- {
- vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
- }
- //Lowgravity with...
- else if (_position.Z > BulletXScene.HeightLevel1)
- {
- if (vec.Z > 0) //no movement
- vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
- else
- vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
- }
- }
- rigidBody.LinearVelocity = vec;
- }
-
- //This validation is very basic
- internal override void ValidateHeight(float heighmapPositionValue)
- {
- if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
- {
- Matrix m = rigidBody.WorldTransform;
- Vector3 v3 = m.Translation;
- v3.Z = heighmapPositionValue + _size.Z/2.0f;
- m.Translation = v3;
- rigidBody.WorldTransform = m;
- //When an Avie touch the ground it's vertical velocity it's reduced to ZERO
- Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
- }
- }
-
- internal override void UpdateKinetics()
- {
- _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
- _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
- //Orientation it seems that it will be the default.
- ReOrient();
- }
- }
-
- ///
- /// PhysicsActor Prim Class for BulletX
- ///
- public class BulletXPrim : BulletXActor
- {
- //Density it will depends of material.
- //For now all prims have the same density, all prims are made of water. Be water my friend! :D
- private const float _density = 1000.0f;
- private BulletXScene _parent_scene;
- private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
- private bool m_lastUpdateSent = false;
-
- public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
- AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
- : this(
- primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs,
- isPhysical)
- {
- }
-
- public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
- PhysicsVector size,
- PhysicsVector acceleration, AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
- bool isPhysical)
- : base(primName)
- {
- if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
- if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
-
- _position = pos;
- _physical = isPhysical;
- _velocity = _physical ? velocity : new PhysicsVector();
- _size = size;
- _acceleration = acceleration;
- _orientation = rotation;
-
- _parent_scene = parent_scene;
-
- CreateRigidBody(parent_scene, mesh, pos, size);
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Prim; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get { return base.Position; }
- set { base.Position = value; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return base.Velocity; }
- set { base.Velocity = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return _size; }
- set
- {
- lock (BulletXScene.BulletXLock)
- {
- _size = value;
- ReSize();
- }
- }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return base.Acceleration; }
- }
-
- public override AxiomQuaternion Orientation
- {
- get { return base.Orientation; }
- set { base.Orientation = value; }
- }
-
- public override float ActorMass
- {
- get
- {
- //For now all prims are boxes
- return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z;
- }
- }
-
- public override bool IsPhysical
- {
- get { return base.IsPhysical; }
- set
- {
- base.IsPhysical = value;
- if (value)
- {
- //---
- PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true);
- //---
- ReCreateRigidBody(_size);
- }
- else
- {
- //---
- PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true);
- //---
- rigidBody.SetMassProps(Mass, new Vector3());
- }
- }
- }
-
- public override bool Flying
- {
- get { return base.Flying; }
- set { base.Flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return base.IsColliding; }
- set { base.IsColliding = value; }
- }
-
- public override bool Kinematic
- {
- get { return base.Kinematic; }
- set { base.Kinematic = value; }
- }
-
- public override void SetAcceleration(PhysicsVector accel)
- {
- lock (BulletXScene.BulletXLock)
- {
- _acceleration = accel;
- }
- }
-
- public override void AddForce(PhysicsVector force)
- {
- base.AddForce(force);
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- base.SetMomentum(momentum);
- }
-
- internal override void ValidateHeight(float heighmapPositionValue)
- {
- if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
- {
- Matrix m = rigidBody.WorldTransform;
- Vector3 v3 = m.Translation;
- v3.Z = heighmapPositionValue + _size.Z/2.0f;
- m.Translation = v3;
- rigidBody.WorldTransform = m;
- //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
- //Static objects don't have linear velocity
- if (_physical)
- Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
- }
- }
-
- internal override void UpdateKinetics()
- {
- if (_physical) //Updates properties. Prim updates its properties physically
- {
- _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
-
- _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
- _orientation = BulletXMaths.XnaQuaternionToAxiomQuaternion(rigidBody.Orientation);
-
- if ((Math.Abs(m_prev_position.X - _position.X) < 0.03)
- && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03)
- && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03))
- {
- if (!m_lastUpdateSent)
- {
- _velocity = new PhysicsVector(0, 0, 0);
- base.ScheduleTerseUpdate();
- m_lastUpdateSent = true;
- }
- }
- else
- {
- m_lastUpdateSent = false;
- base.ScheduleTerseUpdate();
- }
- m_prev_position = _position;
- }
- else //Doesn't updates properties. That's a cancel
- {
- Translate();
- //Speed(); //<- Static objects don't have linear velocity
- ReOrient();
- }
- }
-
- #region Methods for updating values of RigidBody
-
- protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, PhysicsVector pos,
- PhysicsVector size)
- {
- //For RigidBody Constructor. The next values might change
- float _linearDamping = 0.0f;
- float _angularDamping = 0.0f;
- float _friction = 1.0f;
- float _restitution = 0.0f;
- Matrix _startTransform = Matrix.Identity;
- Matrix _centerOfMassOffset = Matrix.Identity;
- lock (BulletXScene.BulletXLock)
- {
- _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
- //For now all prims are boxes
- CollisionShape _collisionShape;
- if (mesh == null)
- {
- _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f);
- }
- else
- {
- int iVertexCount = mesh.getVertexList().Count;
- int[] indices = mesh.getIndexListAsInt();
- Vector3[] v3Vertices = new Vector3[iVertexCount];
- for (int i = 0; i < iVertexCount; i++)
- {
- PhysicsVector v = mesh.getVertexList()[i];
- if (v != null) // Note, null has special meaning. See meshing code for details
- v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
- else
- v3Vertices[i] = Vector3.Zero;
- }
- TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
-
- _collisionShape = new TriangleMeshShape(triMesh);
- }
- DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
- Vector3 _localInertia = new Vector3();
- if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
- rigidBody =
- new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
- _friction, _restitution);
- //rigidBody.ActivationState = ActivationState.DisableDeactivation;
- //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
- Vector3 _vDebugTranslation;
- _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
- rigidBody.Translate(_vDebugTranslation);
- //---
- parent_scene.ddWorld.AddRigidBody(rigidBody);
- }
- }
-
- protected internal void ReCreateRigidBody(PhysicsVector size)
- {
- //There is a bug when trying to remove a rigidBody that is colliding with something..
- try
- {
- _parent_scene.ddWorld.RemoveRigidBody(rigidBody);
- }
- catch (Exception ex)
- {
- _parent_scene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true);
- rigidBody.ActivationState = ActivationState.DisableSimulation;
- _parent_scene.AddForgottenRigidBody(rigidBody);
- }
- CreateRigidBody(_parent_scene, null, _position, size);
- // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
- if (_physical) Speed(); //Static objects don't have linear velocity
- ReOrient();
- GC.Collect();
- }
-
- protected internal override void ReSize(PhysicsVector _newSize)
- {
- //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
- //so i have to do it manually. That's recreating rigidbody
- ReCreateRigidBody(_newSize);
- }
-
- #endregion
- }
-
- ///
- /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
- ///
- internal class BulletXPlanet
- {
- private PhysicsVector _staticPosition;
- private PhysicsVector _staticVelocity;
- private AxiomQuaternion _staticOrientation;
- private float _mass;
- private BulletXScene _parentscene;
- internal float[] _heightField;
- private RigidBody _flatPlanet;
-
- internal RigidBody RigidBody
- {
- get { return _flatPlanet; }
- }
-
- internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
- {
- _staticPosition = new PhysicsVector(BulletXScene.MaxXY/2, BulletXScene.MaxXY/2, 0);
- _staticVelocity = new PhysicsVector();
- _staticOrientation = AxiomQuaternion.Identity;
- _mass = 0; //No active
- _parentscene = parent_scene;
- _heightField = heightField;
-
- float _linearDamping = 0.0f;
- float _angularDamping = 0.0f;
- float _friction = 0.5f;
- float _restitution = 0.0f;
- Matrix _startTransform = Matrix.Identity;
- Matrix _centerOfMassOffset = Matrix.Identity;
-
- lock (BulletXScene.BulletXLock)
- {
- try
- {
- _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
- CollisionShape _collisionShape =
- new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField,
- (float) BulletXScene.MaxZ, 2, true, false);
- DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
- Vector3 _localInertia = new Vector3();
- //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
- _flatPlanet =
- new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping,
- _angularDamping, _friction, _restitution);
- //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
- Vector3 _vDebugTranslation;
- _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
- _flatPlanet.Translate(_vDebugTranslation);
- parent_scene.ddWorld.AddRigidBody(_flatPlanet);
- }
- catch (Exception ex)
- {
- _parentscene.BulletXMessage(ex.Message, true);
- }
- }
- _parentscene.BulletXMessage("BulletXPlanet created.", false);
- }
-
- internal float HeightValue(Vector3 position)
- {
- int li_x, li_y;
- float height;
- li_x = (int) Math.Round(position.X);
- if (li_x < 0) li_x = 0;
- if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
- li_y = (int) Math.Round(position.Y);
- if (li_y < 0) li_y = 0;
- if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
-
- height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
- if (height < 0) height = 0;
- else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
-
- return height;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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.
+*
+*/
+
+#region Copyright
+
+/*
+* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim 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.
+*
+*/
+
+#endregion
+
+#region References
+
+using System;
+using System.Collections.Generic;
+using MonoXnaCompactMaths;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+using XnaDevRu.BulletX;
+using XnaDevRu.BulletX.Dynamics;
+using AxiomQuaternion = Axiom.Math.Quaternion;
+using BoxShape=XnaDevRu.BulletX.BoxShape;
+
+#endregion
+
+namespace OpenSim.Region.Physics.BulletXPlugin
+{
+ ///
+ /// BulletXConversions are called now BulletXMaths
+ /// This Class converts objects and types for BulletX and give some operations
+ ///
+ public class BulletXMaths
+ {
+ //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ //Vector3
+ public static Vector3 PhysicsVectorToXnaVector3(PhysicsVector physicsVector)
+ {
+ return new Vector3(physicsVector.X, physicsVector.Y, physicsVector.Z);
+ }
+
+ public static PhysicsVector XnaVector3ToPhysicsVector(Vector3 xnaVector3)
+ {
+ return new PhysicsVector(xnaVector3.X, xnaVector3.Y, xnaVector3.Z);
+ }
+
+ //Quaternion
+ public static Quaternion AxiomQuaternionToXnaQuaternion(AxiomQuaternion axiomQuaternion)
+ {
+ return new Quaternion(axiomQuaternion.x, axiomQuaternion.y, axiomQuaternion.z, axiomQuaternion.w);
+ }
+
+ public static AxiomQuaternion XnaQuaternionToAxiomQuaternion(Quaternion xnaQuaternion)
+ {
+ return new AxiomQuaternion(xnaQuaternion.W, xnaQuaternion.X, xnaQuaternion.Y, xnaQuaternion.Z);
+ }
+
+ //Next methods are extracted from XnaDevRu.BulletX(See 3rd party license):
+ //- SetRotation (class MatrixOperations)
+ //- GetRotation (class MatrixOperations)
+ //- GetElement (class MathHelper)
+ //- SetElement (class MathHelper)
+ internal static void SetRotation(ref Matrix m, Quaternion q)
+ {
+ float d = q.LengthSquared();
+ float s = 2f/d;
+ float xs = q.X*s, ys = q.Y*s, zs = q.Z*s;
+ float wx = q.W*xs, wy = q.W*ys, wz = q.W*zs;
+ float xx = q.X*xs, xy = q.X*ys, xz = q.X*zs;
+ float yy = q.Y*ys, yz = q.Y*zs, zz = q.Z*zs;
+ m = new Matrix(1 - (yy + zz), xy - wz, xz + wy, 0,
+ xy + wz, 1 - (xx + zz), yz - wx, 0,
+ xz - wy, yz + wx, 1 - (xx + yy), 0,
+ m.M41, m.M42, m.M43, 1);
+ }
+
+ internal static Quaternion GetRotation(Matrix m)
+ {
+ Quaternion q = new Quaternion();
+
+ float trace = m.M11 + m.M22 + m.M33;
+
+ if (trace > 0)
+ {
+ float s = (float) Math.Sqrt(trace + 1);
+ q.W = s*0.5f;
+ s = 0.5f/s;
+
+ q.X = (m.M32 - m.M23)*s;
+ q.Y = (m.M13 - m.M31)*s;
+ q.Z = (m.M21 - m.M12)*s;
+ }
+ else
+ {
+ int i = m.M11 < m.M22
+ ?
+ (m.M22 < m.M33 ? 2 : 1)
+ :
+ (m.M11 < m.M33 ? 2 : 0);
+ int j = (i + 1)%3;
+ int k = (i + 2)%3;
+
+ float s = (float) Math.Sqrt(GetElement(m, i, i) - GetElement(m, j, j) - GetElement(m, k, k) + 1);
+ SetElement(ref q, i, s*0.5f);
+ s = 0.5f/s;
+
+ q.W = (GetElement(m, k, j) - GetElement(m, j, k))*s;
+ SetElement(ref q, j, (GetElement(m, j, i) + GetElement(m, i, j))*s);
+ SetElement(ref q, k, (GetElement(m, k, i) + GetElement(m, i, k))*s);
+ }
+
+ return q;
+ }
+
+ internal static float SetElement(ref Quaternion q, int index, float value)
+ {
+ switch (index)
+ {
+ case 0:
+ q.X = value;
+ break;
+ case 1:
+ q.Y = value;
+ break;
+ case 2:
+ q.Z = value;
+ break;
+ case 3:
+ q.W = value;
+ break;
+ }
+
+ return 0;
+ }
+
+ internal static float GetElement(Matrix mat, int row, int col)
+ {
+ switch (row)
+ {
+ case 0:
+ switch (col)
+ {
+ case 0:
+ return mat.M11;
+ case 1:
+ return mat.M12;
+ case 2:
+ return mat.M13;
+ }
+ break;
+ case 1:
+ switch (col)
+ {
+ case 0:
+ return mat.M21;
+ case 1:
+ return mat.M22;
+ case 2:
+ return mat.M23;
+ }
+ break;
+ case 2:
+ switch (col)
+ {
+ case 0:
+ return mat.M31;
+ case 1:
+ return mat.M32;
+ case 2:
+ return mat.M33;
+ }
+ break;
+ }
+
+ return 0;
+ }
+ }
+
+ ///
+ /// PhysicsPlugin Class for BulletX
+ ///
+ public class BulletXPlugin : IPhysicsPlugin
+ {
+ private BulletXScene _mScene;
+
+ public BulletXPlugin()
+ {
+ }
+
+ public bool Init()
+ {
+ return true;
+ }
+
+ public PhysicsScene GetScene()
+ {
+ if (_mScene == null)
+ {
+ _mScene = new BulletXScene();
+ }
+ return (_mScene);
+ }
+
+ public string GetName()
+ {
+ return ("modified_BulletX"); //Changed!! "BulletXEngine" To "modified_BulletX"
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+
+ // Class to detect and debug collisions
+ // Mainly used for debugging purposes
+ internal class CollisionDispatcherLocal : CollisionDispatcher
+ {
+ private BulletXScene relatedScene;
+
+ public CollisionDispatcherLocal(BulletXScene s)
+ : base()
+ {
+ relatedScene = s;
+ }
+
+ public override bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
+ {
+ RigidBody rb;
+ BulletXCharacter bxcA = null;
+ BulletXPrim bxpA = null;
+ Type t = bodyA.GetType();
+ if (t == typeof (RigidBody))
+ {
+ rb = (RigidBody) bodyA;
+ relatedScene._characters.TryGetValue(rb, out bxcA);
+ relatedScene._prims.TryGetValue(rb, out bxpA);
+ }
+ String nameA;
+ if (bxcA != null)
+ nameA = bxcA._name;
+ else if (bxpA != null)
+ nameA = bxpA._name;
+ else
+ nameA = "null";
+
+ BulletXCharacter bxcB = null;
+ BulletXPrim bxpB = null;
+ t = bodyB.GetType();
+ if (t == typeof (RigidBody))
+ {
+ rb = (RigidBody) bodyB;
+ relatedScene._characters.TryGetValue(rb, out bxcB);
+ relatedScene._prims.TryGetValue(rb, out bxpB);
+ }
+ String nameB;
+ if (bxcB != null)
+ nameB = bxcB._name;
+ else if (bxpB != null)
+ nameB = bxpB._name;
+ else
+ nameB = "null";
+
+ bool needsCollision = base.NeedsCollision(bodyA, bodyB);
+
+ //m_log.DebugFormat("[BulletX]: A collision was detected between {0} and {1} --> {2}", nameA, nameB,
+ //needsCollision);
+
+ return needsCollision;
+ }
+ }
+
+ ///
+ /// PhysicsScene Class for BulletX
+ ///
+ public class BulletXScene : PhysicsScene
+ {
+ #region BulletXScene Fields
+
+ public DiscreteDynamicsWorld ddWorld;
+ private CollisionDispatcher cDispatcher;
+ private OverlappingPairCache opCache;
+ private SequentialImpulseConstraintSolver sicSolver;
+ public static Object BulletXLock = new Object();
+
+ private const int minXY = 0;
+ private const int minZ = 0;
+ private const int maxXY = (int)Constants.RegionSize;
+ private const int maxZ = 4096;
+ private const int maxHandles = 32766; //Why? I don't know
+ private const float gravity = 9.8f;
+ private const float heightLevel0 = 77.0f;
+ private const float heightLevel1 = 200.0f;
+ private const float lowGravityFactor = 0.2f;
+ //OpenSim calls Simulate 10 times per seconds. So FPS = "Simulate Calls" * simulationSubSteps = 100 FPS
+ private const int simulationSubSteps = 10;
+ //private float[] _heightmap;
+ private BulletXPlanet _simFlatPlanet;
+ internal Dictionary _characters = new Dictionary();
+ internal Dictionary _prims = new Dictionary();
+
+ public IMesher mesher;
+
+
+ public static float Gravity
+ {
+ get { return gravity; }
+ }
+
+ public static float HeightLevel0
+ {
+ get { return heightLevel0; }
+ }
+
+ public static float HeightLevel1
+ {
+ get { return heightLevel1; }
+ }
+
+ public static float LowGravityFactor
+ {
+ get { return lowGravityFactor; }
+ }
+
+ public static int MaxXY
+ {
+ get { return maxXY; }
+ }
+
+ public static int MaxZ
+ {
+ get { return maxZ; }
+ }
+
+ private List _forgottenRigidBodies = new List();
+ internal string is_ex_message = "Can't remove rigidBody!: ";
+
+ #endregion
+
+ public BulletXScene()
+ {
+ cDispatcher = new CollisionDispatcherLocal(this);
+ Vector3 worldMinDim = new Vector3((float) minXY, (float) minXY, (float) minZ);
+ Vector3 worldMaxDim = new Vector3((float) maxXY, (float) maxXY, (float) maxZ);
+ opCache = new AxisSweep3(worldMinDim, worldMaxDim, maxHandles);
+ sicSolver = new SequentialImpulseConstraintSolver();
+
+ lock (BulletXLock)
+ {
+ ddWorld = new DiscreteDynamicsWorld(cDispatcher, opCache, sicSolver);
+ ddWorld.Gravity = new Vector3(0, 0, -gravity);
+ }
+ //this._heightmap = new float[65536];
+ }
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ mesher = meshmerizer;
+ }
+
+ public override void Dispose()
+ {
+
+ }
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ PhysicsVector pos = new PhysicsVector();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z + 20;
+ BulletXCharacter newAv = null;
+ lock (BulletXLock)
+ {
+ newAv = new BulletXCharacter(avName, this, pos);
+ _characters.Add(newAv.RigidBody, newAv);
+ }
+ return newAv;
+ }
+
+ public override void RemoveAvatar(PhysicsActor actor)
+ {
+ if (actor is BulletXCharacter)
+ {
+ lock (BulletXLock)
+ {
+ try
+ {
+ ddWorld.RemoveRigidBody(((BulletXCharacter) actor).RigidBody);
+ }
+ catch (Exception ex)
+ {
+ BulletXMessage(is_ex_message + ex.Message, true);
+ ((BulletXCharacter) actor).RigidBody.ActivationState = ActivationState.DisableSimulation;
+ AddForgottenRigidBody(((BulletXCharacter) actor).RigidBody);
+ }
+ _characters.Remove(((BulletXCharacter) actor).RigidBody);
+ }
+ GC.Collect();
+ }
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, AxiomQuaternion rotation, uint localID)
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, AxiomQuaternion rotation, bool isPhysical, uint LocalID)
+ {
+ PhysicsActor result;
+
+ switch (pbs.ProfileShape)
+ {
+ case ProfileShape.Square:
+ /// support simple box & hollow box now; later, more shapes
+ if (pbs.ProfileHollow == 0)
+ {
+ result = AddPrim(primName, position, size, rotation, null, null, isPhysical, LocalID);
+ }
+ else
+ {
+ IMesh mesh = mesher.CreateMesh(primName, pbs, size);
+ result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, LocalID);
+ }
+ break;
+
+ default:
+ result = AddPrim(primName, position, size, rotation, null, null, isPhysical, LocalID);
+ break;
+ }
+
+ return result;
+ }
+
+ public PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, AxiomQuaternion rotation,
+ IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical, uint localID)
+ {
+ BulletXPrim newPrim = null;
+ lock (BulletXLock)
+ {
+ newPrim = new BulletXPrim(name, this, position, size, rotation, mesh, pbs, isPhysical);
+ _prims.Add(newPrim.RigidBody, newPrim);
+ }
+ return newPrim;
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ if (prim is BulletXPrim)
+ {
+ lock (BulletXLock)
+ {
+ try
+ {
+ ddWorld.RemoveRigidBody(((BulletXPrim) prim).RigidBody);
+ }
+ catch (Exception ex)
+ {
+ BulletXMessage(is_ex_message + ex.Message, true);
+ ((BulletXPrim) prim).RigidBody.ActivationState = ActivationState.DisableSimulation;
+ AddForgottenRigidBody(((BulletXPrim) prim).RigidBody);
+ }
+ _prims.Remove(((BulletXPrim) prim).RigidBody);
+ }
+ GC.Collect();
+ }
+ }
+
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ public override float Simulate(float timeStep)
+ {
+ float fps = 0;
+ lock (BulletXLock)
+ {
+ //Try to remove garbage
+ RemoveForgottenRigidBodies();
+ //End of remove
+ MoveAllObjects(timeStep);
+
+
+ fps = (timeStep*simulationSubSteps);
+
+ ddWorld.StepSimulation(timeStep, simulationSubSteps, timeStep);
+ //Extra Heightmap Validation: BulletX's HeightFieldTerrain somestimes doesn't work so fine.
+ ValidateHeightForAll();
+ //End heightmap validation.
+ UpdateKineticsForAll();
+ }
+ return fps;
+ }
+
+ private void MoveAllObjects(float timeStep)
+ {
+ foreach (BulletXCharacter actor in _characters.Values)
+ {
+ actor.Move(timeStep);
+ }
+ foreach (BulletXPrim prim in _prims.Values)
+ {
+ }
+ }
+
+ private void ValidateHeightForAll()
+ {
+ float _height;
+ foreach (BulletXCharacter actor in _characters.Values)
+ {
+ //_height = HeightValue(actor.RigidBodyPosition);
+ _height = _simFlatPlanet.HeightValue(actor.RigidBodyPosition);
+ actor.ValidateHeight(_height);
+ //if (_simFlatPlanet.heightIsNotValid(actor.RigidBodyPosition, out _height)) actor.ValidateHeight(_height);
+ }
+ foreach (BulletXPrim prim in _prims.Values)
+ {
+ //_height = HeightValue(prim.RigidBodyPosition);
+ _height = _simFlatPlanet.HeightValue(prim.RigidBodyPosition);
+ prim.ValidateHeight(_height);
+ //if (_simFlatPlanet.heightIsNotValid(prim.RigidBodyPosition, out _height)) prim.ValidateHeight(_height);
+ }
+ //foreach (BulletXCharacter actor in _characters)
+ //{
+ // actor.ValidateHeight(0);
+ //}
+ //foreach (BulletXPrim prim in _prims)
+ //{
+ // prim.ValidateHeight(0);
+ //}
+ }
+
+ private void UpdateKineticsForAll()
+ {
+ //UpdatePosition > UpdateKinetics.
+ //Not only position will be updated, also velocity cause acceleration.
+ foreach (BulletXCharacter actor in _characters.Values)
+ {
+ actor.UpdateKinetics();
+ }
+ foreach (BulletXPrim prim in _prims.Values)
+ {
+ prim.UpdateKinetics();
+ }
+ //if(this._simFlatPlanet!=null) this._simFlatPlanet.Restore();
+ }
+
+ public override void GetResults()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ get { return (false); // for now we won't be multithreaded
+ }
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
+ //for (int i = 0; i < 65536; i++)
+ //{
+ // // this._heightmap[i] = (double)heightMap[i];
+ // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
+ // int x = i & 0xff;
+ // int y = i >> 8;
+ // this._heightmap[i] = heightMap[x * 256 + y];
+ //}
+
+ //float[] swappedHeightMap = new float[65536];
+ ////As the same as ODE, heightmap (x,y) must be swapped for BulletX
+ //for (int i = 0; i < 65536; i++)
+ //{
+ // // this._heightmap[i] = (double)heightMap[i];
+ // // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
+ // int x = i & 0xff;
+ // int y = i >> 8;
+ // swappedHeightMap[i] = heightMap[x * 256 + y];
+ //}
+ DeleteTerrain();
+ //There is a BulletXLock inside the constructor of BulletXPlanet
+ //this._simFlatPlanet = new BulletXPlanet(this, swappedHeightMap);
+ _simFlatPlanet = new BulletXPlanet(this, heightMap);
+ //this._heightmap = heightMap;
+ }
+
+ public override void DeleteTerrain()
+ {
+ if (_simFlatPlanet != null)
+ {
+ lock (BulletXLock)
+ {
+ try
+ {
+ ddWorld.RemoveRigidBody(_simFlatPlanet.RigidBody);
+ }
+ catch (Exception ex)
+ {
+ BulletXMessage(is_ex_message + ex.Message, true);
+ _simFlatPlanet.RigidBody.ActivationState = ActivationState.DisableSimulation;
+ AddForgottenRigidBody(_simFlatPlanet.RigidBody);
+ }
+ }
+ _simFlatPlanet = null;
+ GC.Collect();
+ BulletXMessage("Terrain erased!", false);
+ }
+ //this._heightmap = null;
+ }
+
+ internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
+ {
+ _forgottenRigidBodies.Add(forgottenRigidBody);
+ }
+
+ private void RemoveForgottenRigidBodies()
+ {
+ RigidBody forgottenRigidBody;
+ int nRigidBodies = _forgottenRigidBodies.Count;
+ for (int i = nRigidBodies - 1; i >= 0; i--)
+ {
+ forgottenRigidBody = _forgottenRigidBodies[i];
+ try
+ {
+ ddWorld.RemoveRigidBody(forgottenRigidBody);
+ _forgottenRigidBodies.Remove(forgottenRigidBody);
+ BulletXMessage("Forgotten Rigid Body Removed", false);
+ }
+ catch (Exception ex)
+ {
+ BulletXMessage("Can't remove forgottenRigidBody!: " + ex.Message, false);
+ }
+ }
+ GC.Collect();
+ }
+
+ internal void BulletXMessage(string message, bool isWarning)
+ {
+ PhysicsPluginManager.PhysicsPluginMessage("[Modified BulletX]:\t" + message, isWarning);
+ }
+
+ //temp
+ //private float HeightValue(MonoXnaCompactMaths.Vector3 position)
+ //{
+ // int li_x, li_y;
+ // float height;
+ // li_x = (int)Math.Round(position.X); if (li_x < 0) li_x = 0;
+ // li_y = (int)Math.Round(position.Y); if (li_y < 0) li_y = 0;
+
+ // height = this._heightmap[li_y * 256 + li_x];
+ // if (height < 0) height = 0;
+ // else if (height > maxZ) height = maxZ;
+
+ // return height;
+ //}
+ }
+
+ ///
+ /// Generic Physics Actor for BulletX inherit from PhysicActor
+ ///
+ public class BulletXActor : PhysicsActor
+ {
+ protected bool flying = false;
+ protected bool _physical = false;
+ protected PhysicsVector _position;
+ protected PhysicsVector _velocity;
+ protected PhysicsVector _size;
+ protected PhysicsVector _acceleration;
+ protected AxiomQuaternion _orientation;
+ protected PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
+ protected RigidBody rigidBody;
+ protected int m_PhysicsActorType;
+ private Boolean iscolliding = false;
+ internal string _name;
+
+ public BulletXActor(String name)
+ {
+ _name = name;
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _position = value;
+ Translate();
+ }
+ }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ //Static objects don' have linear velocity
+ if (_physical)
+ {
+ _velocity = value;
+ Speed();
+ }
+ else
+ {
+ _velocity = new PhysicsVector();
+ }
+ }
+ }
+ }
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+ public override PhysicsVector Size
+ {
+ get { return _size; }
+ set
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _size = value;
+ }
+ }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public override AxiomQuaternion Orientation
+ {
+ get { return _orientation; }
+ set
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _orientation = value;
+ ReOrient();
+ }
+ }
+ }
+
+ public override float Mass
+ {
+ get { return ActorMass; }
+ }
+
+ public virtual float ActorMass
+ {
+ get { return 0; }
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) m_PhysicsActorType; }
+ set { m_PhysicsActorType = value; }
+ }
+
+ public RigidBody RigidBody
+ {
+ get { return rigidBody; }
+ }
+
+ public Vector3 RigidBodyPosition
+ {
+ get { return rigidBody.CenterOfMassPosition; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return _physical; }
+ set { _physical = value; }
+ }
+
+ public override bool Flying
+ {
+ get { return flying; }
+ set { flying = value; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public virtual void SetAcceleration(PhysicsVector accel)
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _acceleration = accel;
+ }
+ }
+
+ public override bool Kinematic
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+ internal virtual void ValidateHeight(float heighmapPositionValue)
+ {
+ }
+
+ internal virtual void UpdateKinetics()
+ {
+ }
+
+ #region Methods for updating values of RigidBody
+
+ protected internal void Translate()
+ {
+ Translate(_position);
+ }
+
+ protected internal void Translate(PhysicsVector _newPos)
+ {
+ Vector3 _translation;
+ _translation = BulletXMaths.PhysicsVectorToXnaVector3(_newPos) - rigidBody.CenterOfMassPosition;
+ rigidBody.Translate(_translation);
+ }
+
+ protected internal void Speed()
+ {
+ Speed(_velocity);
+ }
+
+ protected internal void Speed(PhysicsVector _newSpeed)
+ {
+ Vector3 _speed;
+ _speed = BulletXMaths.PhysicsVectorToXnaVector3(_newSpeed);
+ rigidBody.LinearVelocity = _speed;
+ }
+
+ protected internal void ReOrient()
+ {
+ ReOrient(_orientation);
+ }
+
+ protected internal void ReOrient(AxiomQuaternion _newOrient)
+ {
+ Quaternion _newOrientation;
+ _newOrientation = BulletXMaths.AxiomQuaternionToXnaQuaternion(_newOrient);
+ Matrix _comTransform = rigidBody.CenterOfMassTransform;
+ BulletXMaths.SetRotation(ref _comTransform, _newOrientation);
+ rigidBody.CenterOfMassTransform = _comTransform;
+ }
+
+ protected internal void ReSize()
+ {
+ ReSize(_size);
+ }
+
+ protected internal virtual void ReSize(PhysicsVector _newSize)
+ {
+ }
+
+ public virtual void ScheduleTerseUpdate()
+ {
+ base.RequestPhysicsterseUpdate();
+ }
+
+ #endregion
+
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+
+ ///
+ /// PhysicsActor Character Class for BulletX
+ ///
+ public class BulletXCharacter : BulletXActor
+ {
+ public BulletXCharacter(BulletXScene parent_scene, PhysicsVector pos)
+ : this(String.Empty, parent_scene, pos)
+ {
+ }
+
+ public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos)
+ : this(avName, parent_scene, pos, new PhysicsVector(), new PhysicsVector(), new PhysicsVector(),
+ AxiomQuaternion.Identity)
+ {
+ }
+
+ public BulletXCharacter(String avName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
+ PhysicsVector size, PhysicsVector acceleration, AxiomQuaternion orientation)
+ : base(avName)
+ {
+ //This fields will be removed. They're temporal
+ float _sizeX = 0.5f;
+ float _sizeY = 0.5f;
+ float _sizeZ = 1.6f;
+ //.
+ _position = pos;
+ _velocity = velocity;
+ _size = size;
+ //---
+ _size.X = _sizeX;
+ _size.Y = _sizeY;
+ _size.Z = _sizeZ;
+ //.
+ _acceleration = acceleration;
+ _orientation = orientation;
+ _physical = true;
+
+ float _mass = 50.0f; //This depends of avatar's dimensions
+ //For RigidBody Constructor. The next values might change
+ float _linearDamping = 0.0f;
+ float _angularDamping = 0.0f;
+ float _friction = 0.5f;
+ float _restitution = 0.0f;
+ Matrix _startTransform = Matrix.Identity;
+ Matrix _centerOfMassOffset = Matrix.Identity;
+ lock (BulletXScene.BulletXLock)
+ {
+ _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
+ //CollisionShape _collisionShape = new BoxShape(new MonoXnaCompactMaths.Vector3(1.0f, 1.0f, 1.60f));
+ //For now, like ODE, collisionShape = sphere of radious = 1.0
+ CollisionShape _collisionShape = new SphereShape(1.0f);
+ DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
+ Vector3 _localInertia = new Vector3();
+ _collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
+ rigidBody =
+ new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
+ _friction, _restitution);
+ //rigidBody.ActivationState = ActivationState.DisableDeactivation;
+ //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
+ Vector3 _vDebugTranslation;
+ _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
+ rigidBody.Translate(_vDebugTranslation);
+ parent_scene.ddWorld.AddRigidBody(rigidBody);
+ }
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Agent; }
+ set { return; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return base.Position; }
+ set { base.Position = value; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return base.Velocity; }
+ set { base.Velocity = value; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return base.Size; }
+ set { base.Size = value; }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return base.Acceleration; }
+ }
+
+ public override AxiomQuaternion Orientation
+ {
+ get { return base.Orientation; }
+ set { base.Orientation = value; }
+ }
+
+ public override bool Flying
+ {
+ get { return base.Flying; }
+ set { base.Flying = value; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return base.IsColliding; }
+ set { base.IsColliding = value; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return base.Kinematic; }
+ set { base.Kinematic = value; }
+ }
+
+ public override void SetAcceleration(PhysicsVector accel)
+ {
+ base.SetAcceleration(accel);
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ base.AddForce(force);
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ base.SetMomentum(momentum);
+ }
+
+ internal void Move(float timeStep)
+ {
+ Vector3 vec = new Vector3();
+ //At this point it's supossed that:
+ //_velocity == rigidBody.LinearVelocity
+ vec.X = _velocity.X;
+ vec.Y = _velocity.Y;
+ vec.Z = _velocity.Z;
+ if ((vec.X != 0.0f) || (vec.Y != 0.0f) || (vec.Z != 0.0f)) rigidBody.Activate();
+ if (flying)
+ {
+ //Antigravity with movement
+ if (_position.Z <= BulletXScene.HeightLevel0)
+ {
+ vec.Z += BulletXScene.Gravity*timeStep;
+ }
+ //Lowgravity with movement
+ else if ((_position.Z > BulletXScene.HeightLevel0)
+ && (_position.Z <= BulletXScene.HeightLevel1))
+ {
+ vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
+ }
+ //Lowgravity with...
+ else if (_position.Z > BulletXScene.HeightLevel1)
+ {
+ if (vec.Z > 0) //no movement
+ vec.Z = BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
+ else
+ vec.Z += BulletXScene.Gravity*timeStep*(1.0f - BulletXScene.LowGravityFactor);
+ }
+ }
+ rigidBody.LinearVelocity = vec;
+ }
+
+ //This validation is very basic
+ internal override void ValidateHeight(float heighmapPositionValue)
+ {
+ if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
+ {
+ Matrix m = rigidBody.WorldTransform;
+ Vector3 v3 = m.Translation;
+ v3.Z = heighmapPositionValue + _size.Z/2.0f;
+ m.Translation = v3;
+ rigidBody.WorldTransform = m;
+ //When an Avie touch the ground it's vertical velocity it's reduced to ZERO
+ Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
+ }
+ }
+
+ internal override void UpdateKinetics()
+ {
+ _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
+ _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
+ //Orientation it seems that it will be the default.
+ ReOrient();
+ }
+ }
+
+ ///
+ /// PhysicsActor Prim Class for BulletX
+ ///
+ public class BulletXPrim : BulletXActor
+ {
+ //Density it will depends of material.
+ //For now all prims have the same density, all prims are made of water. Be water my friend! :D
+ private const float _density = 1000.0f;
+ private BulletXScene _parent_scene;
+ private PhysicsVector m_prev_position = new PhysicsVector(0, 0, 0);
+ private bool m_lastUpdateSent = false;
+
+ public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector size,
+ AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool isPhysical)
+ : this(
+ primName, parent_scene, pos, new PhysicsVector(), size, new PhysicsVector(), rotation, mesh, pbs,
+ isPhysical)
+ {
+ }
+
+ public BulletXPrim(String primName, BulletXScene parent_scene, PhysicsVector pos, PhysicsVector velocity,
+ PhysicsVector size,
+ PhysicsVector acceleration, AxiomQuaternion rotation, IMesh mesh, PrimitiveBaseShape pbs,
+ bool isPhysical)
+ : base(primName)
+ {
+ if ((size.X == 0) || (size.Y == 0) || (size.Z == 0)) throw new Exception("Size 0");
+ if (rotation.Norm == 0f) rotation = AxiomQuaternion.Identity;
+
+ _position = pos;
+ _physical = isPhysical;
+ _velocity = _physical ? velocity : new PhysicsVector();
+ _size = size;
+ _acceleration = acceleration;
+ _orientation = rotation;
+
+ _parent_scene = parent_scene;
+
+ CreateRigidBody(parent_scene, mesh, pos, size);
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Prim; }
+ set { return; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return base.Position; }
+ set { base.Position = value; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return base.Velocity; }
+ set { base.Velocity = value; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return _size; }
+ set
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _size = value;
+ ReSize();
+ }
+ }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return base.Acceleration; }
+ }
+
+ public override AxiomQuaternion Orientation
+ {
+ get { return base.Orientation; }
+ set { base.Orientation = value; }
+ }
+
+ public override float ActorMass
+ {
+ get
+ {
+ //For now all prims are boxes
+ return (_physical ? 1 : 0)*_density*_size.X*_size.Y*_size.Z;
+ }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return base.IsPhysical; }
+ set
+ {
+ base.IsPhysical = value;
+ if (value)
+ {
+ //---
+ PhysicsPluginManager.PhysicsPluginMessage("Physical - Recreate", true);
+ //---
+ ReCreateRigidBody(_size);
+ }
+ else
+ {
+ //---
+ PhysicsPluginManager.PhysicsPluginMessage("Physical - SetMassProps", true);
+ //---
+ rigidBody.SetMassProps(Mass, new Vector3());
+ }
+ }
+ }
+
+ public override bool Flying
+ {
+ get { return base.Flying; }
+ set { base.Flying = value; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return base.IsColliding; }
+ set { base.IsColliding = value; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return base.Kinematic; }
+ set { base.Kinematic = value; }
+ }
+
+ public override void SetAcceleration(PhysicsVector accel)
+ {
+ lock (BulletXScene.BulletXLock)
+ {
+ _acceleration = accel;
+ }
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ base.AddForce(force);
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ base.SetMomentum(momentum);
+ }
+
+ internal override void ValidateHeight(float heighmapPositionValue)
+ {
+ if (rigidBody.CenterOfMassPosition.Z < heighmapPositionValue + _size.Z/2.0f)
+ {
+ Matrix m = rigidBody.WorldTransform;
+ Vector3 v3 = m.Translation;
+ v3.Z = heighmapPositionValue + _size.Z/2.0f;
+ m.Translation = v3;
+ rigidBody.WorldTransform = m;
+ //When a Prim touch the ground it's vertical velocity it's reduced to ZERO
+ //Static objects don't have linear velocity
+ if (_physical)
+ Speed(new PhysicsVector(rigidBody.LinearVelocity.X, rigidBody.LinearVelocity.Y, 0.0f));
+ }
+ }
+
+ internal override void UpdateKinetics()
+ {
+ if (_physical) //Updates properties. Prim updates its properties physically
+ {
+ _position = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.CenterOfMassPosition);
+
+ _velocity = BulletXMaths.XnaVector3ToPhysicsVector(rigidBody.LinearVelocity);
+ _orientation = BulletXMaths.XnaQuaternionToAxiomQuaternion(rigidBody.Orientation);
+
+ if ((Math.Abs(m_prev_position.X - _position.X) < 0.03)
+ && (Math.Abs(m_prev_position.Y - _position.Y) < 0.03)
+ && (Math.Abs(m_prev_position.Z - _position.Z) < 0.03))
+ {
+ if (!m_lastUpdateSent)
+ {
+ _velocity = new PhysicsVector(0, 0, 0);
+ base.ScheduleTerseUpdate();
+ m_lastUpdateSent = true;
+ }
+ }
+ else
+ {
+ m_lastUpdateSent = false;
+ base.ScheduleTerseUpdate();
+ }
+ m_prev_position = _position;
+ }
+ else //Doesn't updates properties. That's a cancel
+ {
+ Translate();
+ //Speed(); //<- Static objects don't have linear velocity
+ ReOrient();
+ }
+ }
+
+ #region Methods for updating values of RigidBody
+
+ protected internal void CreateRigidBody(BulletXScene parent_scene, IMesh mesh, PhysicsVector pos,
+ PhysicsVector size)
+ {
+ //For RigidBody Constructor. The next values might change
+ float _linearDamping = 0.0f;
+ float _angularDamping = 0.0f;
+ float _friction = 1.0f;
+ float _restitution = 0.0f;
+ Matrix _startTransform = Matrix.Identity;
+ Matrix _centerOfMassOffset = Matrix.Identity;
+ lock (BulletXScene.BulletXLock)
+ {
+ _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(pos);
+ //For now all prims are boxes
+ CollisionShape _collisionShape;
+ if (mesh == null)
+ {
+ _collisionShape = new BoxShape(BulletXMaths.PhysicsVectorToXnaVector3(size)/2.0f);
+ }
+ else
+ {
+ int iVertexCount = mesh.getVertexList().Count;
+ int[] indices = mesh.getIndexListAsInt();
+ Vector3[] v3Vertices = new Vector3[iVertexCount];
+ for (int i = 0; i < iVertexCount; i++)
+ {
+ PhysicsVector v = mesh.getVertexList()[i];
+ if (v != null) // Note, null has special meaning. See meshing code for details
+ v3Vertices[i] = BulletXMaths.PhysicsVectorToXnaVector3(v);
+ else
+ v3Vertices[i] = Vector3.Zero;
+ }
+ TriangleIndexVertexArray triMesh = new TriangleIndexVertexArray(indices, v3Vertices);
+
+ _collisionShape = new TriangleMeshShape(triMesh);
+ }
+ DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
+ Vector3 _localInertia = new Vector3();
+ if (_physical) _collisionShape.CalculateLocalInertia(Mass, out _localInertia); //Always when mass > 0
+ rigidBody =
+ new RigidBody(Mass, _motionState, _collisionShape, _localInertia, _linearDamping, _angularDamping,
+ _friction, _restitution);
+ //rigidBody.ActivationState = ActivationState.DisableDeactivation;
+ //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
+ Vector3 _vDebugTranslation;
+ _vDebugTranslation = _startTransform.Translation - rigidBody.CenterOfMassPosition;
+ rigidBody.Translate(_vDebugTranslation);
+ //---
+ parent_scene.ddWorld.AddRigidBody(rigidBody);
+ }
+ }
+
+ protected internal void ReCreateRigidBody(PhysicsVector size)
+ {
+ //There is a bug when trying to remove a rigidBody that is colliding with something..
+ try
+ {
+ _parent_scene.ddWorld.RemoveRigidBody(rigidBody);
+ }
+ catch (Exception ex)
+ {
+ _parent_scene.BulletXMessage(_parent_scene.is_ex_message + ex.Message, true);
+ rigidBody.ActivationState = ActivationState.DisableSimulation;
+ _parent_scene.AddForgottenRigidBody(rigidBody);
+ }
+ CreateRigidBody(_parent_scene, null, _position, size);
+ // Note, null for the meshing definitely is wrong. It's here for the moment to apease the compiler
+ if (_physical) Speed(); //Static objects don't have linear velocity
+ ReOrient();
+ GC.Collect();
+ }
+
+ protected internal override void ReSize(PhysicsVector _newSize)
+ {
+ //I wonder to know how to resize with a simple instruction in BulletX. It seems that for now there isn't
+ //so i have to do it manually. That's recreating rigidbody
+ ReCreateRigidBody(_newSize);
+ }
+
+ #endregion
+ }
+
+ ///
+ /// This Class manage a HeighField as a RigidBody. This is for to be added in the BulletXScene
+ ///
+ internal class BulletXPlanet
+ {
+ private PhysicsVector _staticPosition;
+ private PhysicsVector _staticVelocity;
+ private AxiomQuaternion _staticOrientation;
+ private float _mass;
+ private BulletXScene _parentscene;
+ internal float[] _heightField;
+ private RigidBody _flatPlanet;
+
+ internal RigidBody RigidBody
+ {
+ get { return _flatPlanet; }
+ }
+
+ internal BulletXPlanet(BulletXScene parent_scene, float[] heightField)
+ {
+ _staticPosition = new PhysicsVector(BulletXScene.MaxXY/2, BulletXScene.MaxXY/2, 0);
+ _staticVelocity = new PhysicsVector();
+ _staticOrientation = AxiomQuaternion.Identity;
+ _mass = 0; //No active
+ _parentscene = parent_scene;
+ _heightField = heightField;
+
+ float _linearDamping = 0.0f;
+ float _angularDamping = 0.0f;
+ float _friction = 0.5f;
+ float _restitution = 0.0f;
+ Matrix _startTransform = Matrix.Identity;
+ Matrix _centerOfMassOffset = Matrix.Identity;
+
+ lock (BulletXScene.BulletXLock)
+ {
+ try
+ {
+ _startTransform.Translation = BulletXMaths.PhysicsVectorToXnaVector3(_staticPosition);
+ CollisionShape _collisionShape =
+ new HeightfieldTerrainShape(BulletXScene.MaxXY, BulletXScene.MaxXY, _heightField,
+ (float) BulletXScene.MaxZ, 2, true, false);
+ DefaultMotionState _motionState = new DefaultMotionState(_startTransform, _centerOfMassOffset);
+ Vector3 _localInertia = new Vector3();
+ //_collisionShape.CalculateLocalInertia(_mass, out _localInertia); //Always when mass > 0
+ _flatPlanet =
+ new RigidBody(_mass, _motionState, _collisionShape, _localInertia, _linearDamping,
+ _angularDamping, _friction, _restitution);
+ //It's seems that there are a bug with rigidBody constructor and its CenterOfMassPosition
+ Vector3 _vDebugTranslation;
+ _vDebugTranslation = _startTransform.Translation - _flatPlanet.CenterOfMassPosition;
+ _flatPlanet.Translate(_vDebugTranslation);
+ parent_scene.ddWorld.AddRigidBody(_flatPlanet);
+ }
+ catch (Exception ex)
+ {
+ _parentscene.BulletXMessage(ex.Message, true);
+ }
+ }
+ _parentscene.BulletXMessage("BulletXPlanet created.", false);
+ }
+
+ internal float HeightValue(Vector3 position)
+ {
+ int li_x, li_y;
+ float height;
+ li_x = (int) Math.Round(position.X);
+ if (li_x < 0) li_x = 0;
+ if (li_x >= BulletXScene.MaxXY) li_x = BulletXScene.MaxXY - 1;
+ li_y = (int) Math.Round(position.Y);
+ if (li_y < 0) li_y = 0;
+ if (li_y >= BulletXScene.MaxXY) li_y = BulletXScene.MaxXY - 1;
+
+ height = ((HeightfieldTerrainShape) _flatPlanet.CollisionShape).getHeightFieldValue(li_x, li_y);
+ if (height < 0) height = 0;
+ else if (height > BulletXScene.MaxZ) height = BulletXScene.MaxZ;
+
+ return height;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/CollisionLocker.cs b/OpenSim/Region/Physics/Manager/CollisionLocker.cs
new file mode 100644
index 0000000000..98e9736a93
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/CollisionLocker.cs
@@ -0,0 +1,74 @@
+/*
+* 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 OpenSim 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.Text;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public class CollisionLocker
+ {
+
+
+ private List worldlock = new List();
+ public CollisionLocker()
+ {
+
+ }
+ public void dlock(IntPtr world)
+ {
+ lock (worldlock)
+ {
+ worldlock.Add(world);
+ }
+
+ }
+ public void dunlock(IntPtr world)
+ {
+ lock (worldlock)
+ {
+ worldlock.Remove(world);
+ }
+ }
+ public bool lockquery()
+ {
+ return (worldlock.Count > 0);
+ }
+ public void drelease(IntPtr world)
+ {
+ lock (worldlock)
+ {
+ if (worldlock.Contains(world))
+ worldlock.Remove(world);
+ }
+ }
+
+ }
+
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 9f058dd6c3..c3dd880b96 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -1,324 +1,368 @@
-/*
-* 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 OpenSim 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 Axiom.Math;
-using OpenSim.Framework;
-
-namespace OpenSim.Region.Physics.Manager
-{
- public delegate void PositionUpdate(PhysicsVector position);
-
- public delegate void VelocityUpdate(PhysicsVector velocity);
-
- public delegate void OrientationUpdate(Quaternion orientation);
-
- public enum ActorTypes : int
- {
- Unknown = 0,
- Agent = 1,
- Prim = 2,
- Ground = 3,
- PrimVolume = 4 // rex
- }
-
- public class CollisionEventUpdate : EventArgs
- {
- // Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
- public int m_colliderType;
- public bool m_startOrEnd;
- public uint m_LocalID; // rex
- public List m_objCollisionList;
-
- public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List objCollisionList)
- {
- m_LocalID = localID; // rex
- m_colliderType = colliderType;
- m_startOrEnd = startOrEnd;
- m_objCollisionList = objCollisionList;
- }
-
- public CollisionEventUpdate(bool startOrEnd)
- {
- m_colliderType = (int) ActorTypes.Unknown;
- m_startOrEnd = startOrEnd;
- m_objCollisionList = null;
- }
-
- public CollisionEventUpdate()
- {
- m_colliderType = (int) ActorTypes.Unknown;
- m_startOrEnd = false;
- m_objCollisionList = null;
- }
-
- public int collidertype
- {
- get { return m_colliderType; }
- set { m_colliderType = value; }
- }
-
- public bool startOrEnd
- {
- get { return m_startOrEnd; }
- set { m_startOrEnd = value; }
- }
-
- public void addCollider(uint localID)
- {
- m_objCollisionList.Add(localID);
- }
- }
-
-
- public abstract class PhysicsActor
- {
- public delegate void RequestTerseUpdate();
-
- public delegate void CollisionUpdate(EventArgs e);
-
- public delegate void OutOfBounds(PhysicsVector pos);
-
-#pragma warning disable 67
- public event PositionUpdate OnPositionUpdate;
- public event VelocityUpdate OnVelocityUpdate;
- public event OrientationUpdate OnOrientationUpdate;
- public event RequestTerseUpdate OnRequestTerseUpdate;
- public event CollisionUpdate OnCollisionUpdate;
- public event OutOfBounds OnOutOfBounds;
-#pragma warning restore 67
-
- public static PhysicsActor Null
- {
- get { return new NullPhysicsActor(); }
- }
-
- public abstract PhysicsVector Size { get; set; }
-
- public abstract PrimitiveBaseShape Shape { set; }
-
- public virtual void RequestPhysicsterseUpdate()
- {
- // Make a temporary copy of the event to avoid possibility of
- // a race condition if the last subscriber unsubscribes
- // immediately after the null check and before the event is raised.
- RequestTerseUpdate handler = OnRequestTerseUpdate;
- if (handler != null)
- {
- OnRequestTerseUpdate();
- }
- }
-
- public virtual void RaiseOutOfBounds(PhysicsVector pos)
- {
- // Make a temporary copy of the event to avoid possibility of
- // a race condition if the last subscriber unsubscribes
- // immediately after the null check and before the event is raised.
- OutOfBounds handler = OnOutOfBounds;
- if (handler != null)
- {
- OnOutOfBounds(pos);
- }
- }
-
- public virtual void SendCollisionUpdate(EventArgs e)
- {
- // CollisionUpdate handler = OnCollisionUpdate;
- if (OnCollisionUpdate != null)
- OnCollisionUpdate(e);
- }
-
-
- public abstract PhysicsVector Position { get; set; }
-
- public abstract float Mass { get; }
-
- public abstract PhysicsVector Force { get; }
-
- public abstract PhysicsVector GeometricCenter { get; }
-
- public abstract PhysicsVector CenterOfMass { get; }
-
- public abstract PhysicsVector Velocity { get; set; }
-
- public abstract PhysicsVector Acceleration { get; }
-
- public abstract Quaternion Orientation { get; set; }
- public abstract int PhysicsActorType { get; set; }
-
- public abstract bool IsPhysical { get; set; }
-
- public abstract bool Flying { get; set; }
- public abstract bool SetAlwaysRun { get; set; }
- public abstract bool ThrottleUpdates { get; set; }
-
- public abstract bool IsColliding { get; set; }
- public abstract bool CollidingGround { get; set; }
- public abstract bool CollidingObj { get; set; }
-
- public abstract PhysicsVector RotationalVelocity { get; set; }
-
- public abstract bool Kinematic { get; set; }
-
- public abstract void AddForce(PhysicsVector force);
-
- public abstract void SetMomentum(PhysicsVector momentum);
-
- public virtual void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh) { } // rex
- public virtual void SetBoundsScaling(bool vbScaleMesh) { } // rex
- public int NextPrimVolumeTime = 0; // rex
- public uint m_localID; // rex
- }
-
- public class NullPhysicsActor : PhysicsActor
- {
- public override PhysicsVector Position
- {
- get { return PhysicsVector.Zero; }
- set { return; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Size
- {
- get { return PhysicsVector.Zero; }
- set { return; }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return PhysicsVector.Zero; }
- set { return; }
- }
-
- public override Quaternion Orientation
- {
- get { return Quaternion.Identity; }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool Flying
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsColliding
- {
- get { return false; }
- set { return; }
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Unknown; }
- set { return; }
- }
-
- public override bool Kinematic
- {
- get { return true; }
- set { return; }
- }
-
- public override void AddForce(PhysicsVector force)
- {
- return;
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return PhysicsVector.Zero; }
- set { return; }
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- return;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 Axiom.Math;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public delegate void PositionUpdate(PhysicsVector position);
+
+ public delegate void VelocityUpdate(PhysicsVector velocity);
+
+ public delegate void OrientationUpdate(Quaternion orientation);
+
+ public enum ActorTypes : int
+ {
+ Unknown = 0,
+ Agent = 1,
+ Prim = 2,
+ Ground = 3,
+ PrimVolume = 4 // rex
+ }
+
+ public class CollisionEventUpdate : EventArgs
+ {
+ // Raising the event on the object, so don't need to provide location.. further up the tree knows that info.
+ public int m_colliderType;
+ public bool m_startOrEnd;
+ public uint m_LocalID; // rex
+ public List m_objCollisionList;
+
+ public CollisionEventUpdate(uint localID, int colliderType, bool startOrEnd, List objCollisionList)
+ {
+ m_LocalID = localID; // rex
+ m_colliderType = colliderType;
+ m_startOrEnd = startOrEnd;
+ m_objCollisionList = objCollisionList;
+ }
+
+ public CollisionEventUpdate(bool startOrEnd)
+ {
+ m_colliderType = (int) ActorTypes.Unknown;
+ m_startOrEnd = startOrEnd;
+ m_objCollisionList = null;
+ }
+
+ public CollisionEventUpdate()
+ {
+ m_colliderType = (int) ActorTypes.Unknown;
+ m_startOrEnd = false;
+ m_objCollisionList = null;
+ }
+
+ public int collidertype
+ {
+ get { return m_colliderType; }
+ set { m_colliderType = value; }
+ }
+
+ public bool startOrEnd
+ {
+ get { return m_startOrEnd; }
+ set { m_startOrEnd = value; }
+ }
+
+ public void addCollider(uint localID)
+ {
+ m_objCollisionList.Add(localID);
+ }
+ }
+
+
+ public abstract class PhysicsActor
+ {
+ public delegate void RequestTerseUpdate();
+
+ public delegate void CollisionUpdate(EventArgs e);
+
+ public delegate void OutOfBounds(PhysicsVector pos);
+
+#pragma warning disable 67
+ public event PositionUpdate OnPositionUpdate;
+ public event VelocityUpdate OnVelocityUpdate;
+ public event OrientationUpdate OnOrientationUpdate;
+ public event RequestTerseUpdate OnRequestTerseUpdate;
+ public event CollisionUpdate OnCollisionUpdate;
+ public event OutOfBounds OnOutOfBounds;
+#pragma warning restore 67
+
+ public static PhysicsActor Null
+ {
+ get { return new NullPhysicsActor(); }
+ }
+
+ public abstract bool Stopped { get; }
+
+ public abstract PhysicsVector Size { get; set; }
+
+ public abstract PrimitiveBaseShape Shape { set; }
+
+ public abstract bool Grabbed { set; }
+
+ public abstract bool Selected { set; }
+
+ public abstract void CrossingFailure();
+
+ public virtual void RequestPhysicsterseUpdate()
+ {
+ // Make a temporary copy of the event to avoid possibility of
+ // a race condition if the last subscriber unsubscribes
+ // immediately after the null check and before the event is raised.
+ RequestTerseUpdate handler = OnRequestTerseUpdate;
+
+ if (handler != null)
+ {
+
+ handler();
+
+ }
+ }
+
+ public virtual void RaiseOutOfBounds(PhysicsVector pos)
+ {
+ // Make a temporary copy of the event to avoid possibility of
+ // a race condition if the last subscriber unsubscribes
+ // immediately after the null check and before the event is raised.
+ OutOfBounds handler = OnOutOfBounds;
+ if (handler != null)
+ {
+ handler(pos);
+ }
+ }
+
+ public virtual void SendCollisionUpdate(EventArgs e)
+ {
+ CollisionUpdate handler = OnCollisionUpdate;
+
+ if (handler != null)
+ {
+ handler(e);
+ }
+
+ }
+
+
+ public abstract PhysicsVector Position { get; set; }
+
+ public abstract float Mass { get; }
+
+ public abstract PhysicsVector Force { get; }
+
+ public abstract PhysicsVector GeometricCenter { get; }
+
+ public abstract PhysicsVector CenterOfMass { get; }
+
+ public abstract PhysicsVector Velocity { get; set; }
+
+ public abstract float CollisionScore { get;}
+
+ public abstract PhysicsVector Acceleration { get; }
+
+ public abstract Quaternion Orientation { get; set; }
+ public abstract int PhysicsActorType { get; set; }
+
+ public abstract bool IsPhysical { get; set; }
+
+ public abstract bool Flying { get; set; }
+ public abstract bool SetAlwaysRun { get; set; }
+ public abstract bool ThrottleUpdates { get; set; }
+
+ public abstract bool IsColliding { get; set; }
+ public abstract bool CollidingGround { get; set; }
+ public abstract bool CollidingObj { get; set; }
+
+ public abstract PhysicsVector RotationalVelocity { get; set; }
+
+ public abstract bool Kinematic { get; set; }
+
+ public abstract void AddForce(PhysicsVector force);
+
+ public abstract void SetMomentum(PhysicsVector momentum);
+
+ public virtual void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh) { } // rex
+ public virtual void SetBoundsScaling(bool vbScaleMesh) { } // rex
+ public int NextPrimVolumeTime = 0; // rex
+ public uint m_localID; // rex
+ }
+
+ public class NullPhysicsActor : PhysicsActor
+ {
+ public override bool Stopped
+ {
+ get{ return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return PhysicsVector.Zero; }
+ set { return; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return PhysicsVector.Zero; }
+ set { return; }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return PhysicsVector.Zero; }
+ set { return; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override void CrossingFailure()
+ {
+
+ }
+
+
+ public override Quaternion Orientation
+ {
+ get { return Quaternion.Identity; }
+ set { }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Flying
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Unknown; }
+ set { return; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return true; }
+ set { return; }
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ return;
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return PhysicsVector.Zero; }
+ set { return; }
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ return;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
index 4d98a8a673..08f04b5c34 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsPluginManager.cs
@@ -1,181 +1,188 @@
-/*
-* 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 OpenSim 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.IO;
-using System.Reflection;
-using OpenSim.Framework.Console;
-
-namespace OpenSim.Region.Physics.Manager
-{
- ///
- /// Description of MyClass.
- ///
- public class PhysicsPluginManager
- {
- private Dictionary _PhysPlugins = new Dictionary();
- private Dictionary _MeshPlugins = new Dictionary();
-
- public PhysicsPluginManager()
- {
- }
-
- public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
- {
- if (String.IsNullOrEmpty(physEngineName))
- {
- return PhysicsScene.Null;
- }
-
- if (String.IsNullOrEmpty(meshEngineName))
- {
- return PhysicsScene.Null;
- }
-
- IMesher meshEngine = null;
- if (_MeshPlugins.ContainsKey(meshEngineName))
- {
- MainLog.Instance.Verbose("PHYSICS", "creating meshing engine " + meshEngineName);
- meshEngine = _MeshPlugins[meshEngineName].GetMesher();
- }
- else
- {
- MainLog.Instance.Warn("PHYSICS", "couldn't find meshingEngine: {0}", meshEngineName);
- throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
- }
-
- if (_PhysPlugins.ContainsKey(physEngineName))
- {
- MainLog.Instance.Verbose("PHYSICS", "creating " + physEngineName);
- PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
- result.Initialise(meshEngine);
- return result;
- }
- else
- {
- MainLog.Instance.Warn("PHYSICS", "couldn't find physicsEngine: {0}", physEngineName);
- throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
- }
- }
-
- public void LoadPlugins()
- {
- // Load "plugins", that are hard coded and not existing in form of an external lib
- IMeshingPlugin plugHard;
- plugHard = new ZeroMesherPlugin();
- _MeshPlugins.Add(plugHard.GetName(), plugHard);
- MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plugHard.GetName());
-
- // And now walk all assemblies (DLLs effectively) and see if they are home
- // of a plugin that is of interest for us
- string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Physics");
- string[] pluginFiles = Directory.GetFiles(path, "*.dll");
-
- for (int i = 0; i < pluginFiles.Length; i++)
- {
- AddPlugin(pluginFiles[i]);
- }
- }
-
- private void AddPlugin(string FileName)
+/*
+* 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 OpenSim 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.IO;
+using System.Reflection;
+using OpenSim.Framework.Console;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ ///
+ /// Description of MyClass.
+ ///
+ public class PhysicsPluginManager
+ {
+ private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ private Dictionary _PhysPlugins = new Dictionary();
+ private Dictionary _MeshPlugins = new Dictionary();
+
+ public PhysicsPluginManager()
{
- try
- {
- Assembly pluginAssembly = Assembly.LoadFrom(FileName);
-
- foreach (Type pluginType in pluginAssembly.GetTypes())
- {
- if (pluginType.IsPublic)
- {
- if (!pluginType.IsAbstract)
- {
- Type physTypeInterface = pluginType.GetInterface("IPhysicsPlugin", true);
-
- if (physTypeInterface != null)
- {
- IPhysicsPlugin plug =
- (IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
- plug.Init();
- _PhysPlugins.Add(plug.GetName(), plug);
- MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
- }
-
- Type meshTypeInterface = pluginType.GetInterface("IMeshingPlugin", true);
-
- if (meshTypeInterface != null)
- {
- IMeshingPlugin plug =
- (IMeshingPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
- _MeshPlugins.Add(plug.GetName(), plug);
- MainLog.Instance.Verbose("PHYSICS", "Added meshing engine: " + plug.GetName());
- }
-
- physTypeInterface = null;
- meshTypeInterface = null;
- }
- }
- }
-
+ }
+
+ public PhysicsScene GetPhysicsScene(string physEngineName, string meshEngineName)
+ {
+ if (String.IsNullOrEmpty(physEngineName))
+ {
+ return PhysicsScene.Null;
+ }
+
+ if (String.IsNullOrEmpty(meshEngineName))
+ {
+ return PhysicsScene.Null;
+ }
+
+ IMesher meshEngine = null;
+ if (_MeshPlugins.ContainsKey(meshEngineName))
+ {
+ m_log.Info("[PHYSICS]: creating meshing engine " + meshEngineName);
+ meshEngine = _MeshPlugins[meshEngineName].GetMesher();
+ }
+ else
+ {
+ m_log.WarnFormat("[PHYSICS]: couldn't find meshingEngine: {0}", meshEngineName);
+ throw new ArgumentException(String.Format("couldn't find meshingEngine: {0}", meshEngineName));
+ }
+
+ if (_PhysPlugins.ContainsKey(physEngineName))
+ {
+ m_log.Info("[PHYSICS]: creating " + physEngineName);
+ PhysicsScene result = _PhysPlugins[physEngineName].GetScene();
+ result.Initialise(meshEngine);
+ return result;
+ }
+ else
+ {
+ m_log.WarnFormat("[PHYSICS]: couldn't find physicsEngine: {0}", physEngineName);
+ throw new ArgumentException(String.Format("couldn't find physicsEngine: {0}", physEngineName));
+ }
+ }
+
+ public void LoadPlugins()
+ {
+ // Load "plugins", that are hard coded and not existing in form of an external lib
+ IMeshingPlugin plugHard;
+ plugHard = new ZeroMesherPlugin();
+ _MeshPlugins.Add(plugHard.GetName(), plugHard);
+ m_log.Info("[PHYSICS]: Added meshing engine: " + plugHard.GetName());
+
+ // And now walk all assemblies (DLLs effectively) and see if they are home
+ // of a plugin that is of interest for us
+ string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Physics");
+ string[] pluginFiles = Directory.GetFiles(path, "*.dll");
+
+ for (int i = 0; i < pluginFiles.Length; i++)
+ {
+ AddPlugin(pluginFiles[i]);
+ }
+ }
+
+ private void AddPlugin(string FileName)
+ {
+ // TODO / NOTE
+ // The assembly named 'OpenSim.Region.Physics.BasicPhysicsPlugin' was loaded from
+ // 'file:///C:/OpenSim/trunk2/bin/Physics/OpenSim.Region.Physics.BasicPhysicsPlugin.dll'
+ // using the LoadFrom context. The use of this context can result in unexpected behavior
+ // for serialization, casting and dependency resolution. In almost all cases, it is recommended
+ // that the LoadFrom context be avoided. This can be done by installing assemblies in the
+ // Global Assembly Cache or in the ApplicationBase directory and using Assembly.
+ // Load when explicitly loading assemblies.
+ Assembly pluginAssembly = Assembly.LoadFrom(FileName);
+
+ foreach (Type pluginType in pluginAssembly.GetTypes())
+ {
+ if (pluginType.IsPublic)
+ {
+ if (!pluginType.IsAbstract)
+ {
+ IPhysicsPlugin plug =
+ (IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
+ plug.Init();
+ _PhysPlugins.Add(plug.GetName(), plug);
+ m_log.Info("[PHYSICS]: Added physics engine: " + plug.GetName());
+ }
+
+ if (physTypeInterface != null)
+ {
+ IPhysicsPlugin plug =
+ (IPhysicsPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
+ plug.Init();
+ _PhysPlugins.Add(plug.GetName(), plug);
+ MainLog.Instance.Verbose("PHYSICS", "Added physics engine: " + plug.GetName());
+ }
+
+ if (meshTypeInterface != null)
+ {
+ IMeshingPlugin plug =
+ (IMeshingPlugin) Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
+ _MeshPlugins.Add(plug.GetName(), plug);
+ m_log.Info("[PHYSICS]: Added meshing engine: " + plug.GetName());
+ }
+ }
+ }
+
pluginAssembly = null;
}
catch(Exception e)
{
MainLog.Instance.Warn("PHYSICS", "Error loading plugin " + FileName + ": " + e.Message);
- }
- }
-
- //---
- public static void PhysicsPluginMessage(string message, bool isWarning)
- {
- if (isWarning)
- {
- MainLog.Instance.Warn("PHYSICS", message);
- }
- else
- {
- MainLog.Instance.Verbose("PHYSICS", message);
- }
- }
-
- //---
- }
-
- public interface IPhysicsPlugin
- {
- bool Init();
- PhysicsScene GetScene();
- string GetName();
- void Dispose();
- }
-
- public interface IMeshingPlugin
- {
- string GetName();
- IMesher GetMesher();
- }
-}
\ No newline at end of file
+ }
+ }
+
+ //---
+ public static void PhysicsPluginMessage(string message, bool isWarning)
+ {
+ if (isWarning)
+ {
+ m_log.Warn("[PHYSICS]: " + message);
+ }
+ else
+ {
+ m_log.Info("[PHYSICS]: " + message);
+ }
+ }
+
+ //---
+ }
+
+ public interface IPhysicsPlugin
+ {
+ bool Init();
+ PhysicsScene GetScene();
+ string GetName();
+ void Dispose();
+ }
+
+ public interface IMeshingPlugin
+ {
+ string GetName();
+ IMesher GetMesher();
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 3c21542c66..67b3f77f64 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -1,160 +1,168 @@
-/*
-* 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 OpenSim 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 Axiom.Math;
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-
-namespace OpenSim.Region.Physics.Manager
-{
- public delegate void physicsCrash();
-
- public abstract class PhysicsScene
- {
- // The only thing that should register for this event is the InnerScene
- // Anything else could cause problems.
-
- public event physicsCrash OnPhysicsCrash;
-
- public static PhysicsScene Null
- {
- get { return new NullPhysicsScene(); }
- }
-
- public virtual void TriggerPhysicsBasedRestart()
- {
- physicsCrash handler = OnPhysicsCrash;
- if (handler != null)
- {
- OnPhysicsCrash();
- }
- }
-
-
- public abstract void Initialise(IMesher meshmerizer);
-
- public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID); // rex, localID added
-
- public abstract void RemoveAvatar(PhysicsActor actor);
-
- public abstract void RemovePrim(PhysicsActor prim);
-
- public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint localID); //To be removed, rex, localID added
- public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID); // rex, localID added
-
- public abstract void AddPhysicsActorTaint(PhysicsActor prim);
-
- public abstract float Simulate(float timeStep);
-
- public abstract void GetResults();
-
- public abstract void SetTerrain(float[] heightMap);
-
- public abstract void DeleteTerrain();
-
- public abstract bool IsThreaded { get; }
-
- private class NullPhysicsScene : PhysicsScene
- {
- private static int m_workIndicator;
-
-
- public override void Initialise(IMesher meshmerizer)
- {
- // Does nothing right now
- }
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
- {
- MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : AddAvatar({0})", position);
- return PhysicsActor.Null;
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- }
-
-/*
- public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
- {
- MainLog.Instance.Verbose("NullPhysicsScene : AddPrim({0},{1})", position, size);
- return PhysicsActor.Null;
- }
-*/
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint localID) //To be removed
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false, localID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
- {
- MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : AddPrim({0},{1})", position, size);
- return PhysicsActor.Null;
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- }
-
- public override float Simulate(float timeStep)
- {
- m_workIndicator = (m_workIndicator + 1)%10;
-
- //MainLog.Instance.SetStatus(m_workIndicator.ToString());
- return 0f;
- }
-
- public override void GetResults()
- {
- MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : GetResults()");
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- MainLog.Instance.Verbose("PHYSICS", "NullPhysicsScene : SetTerrain({0} items)", heightMap.Length);
- }
-
- public override void DeleteTerrain()
- {
- }
-
- public override bool IsThreaded
- {
- get { return false; }
- }
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 Axiom.Math;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public delegate void physicsCrash();
+
+ public abstract class PhysicsScene
+ {
+ private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ // The only thing that should register for this event is the InnerScene
+ // Anything else could cause problems.
+
+ public event physicsCrash OnPhysicsCrash;
+
+ public static PhysicsScene Null
+ {
+ get { return new NullPhysicsScene(); }
+ }
+
+ public virtual void TriggerPhysicsBasedRestart()
+ {
+ physicsCrash handler = OnPhysicsCrash;
+ if (handler != null)
+ {
+ OnPhysicsCrash();
+ }
+ }
+
+
+ public abstract void Initialise(IMesher meshmerizer);
+
+ public abstract PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size);
+
+ public abstract void RemoveAvatar(PhysicsActor actor);
+
+ public abstract void RemovePrim(PhysicsActor prim);
+
+ public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint localID); //To be removed, rex, localID added
+ public abstract PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID); // rex, localID added
+
+ public abstract void AddPhysicsActorTaint(PhysicsActor prim);
+
+ public abstract float Simulate(float timeStep);
+
+ public abstract void GetResults();
+
+ public abstract void SetTerrain(float[] heightMap);
+
+ public abstract void DeleteTerrain();
+
+ public abstract void Dispose();
+
+ public abstract bool IsThreaded { get; }
+
+ private class NullPhysicsScene : PhysicsScene
+ {
+ private static int m_workIndicator;
+
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddAvatar({0})", position);
+ return PhysicsActor.Null;
+ }
+
+ public override void RemoveAvatar(PhysicsActor actor)
+ {
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ }
+
+/*
+ public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
+ {
+ m_log.InfoFormat("NullPhysicsScene : AddPrim({0},{1})", position, size);
+ return PhysicsActor.Null;
+ }
+*/
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint localID) //To be removed
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false, localID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
+ {
+ m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : AddPrim({0},{1})", position, size);
+ return PhysicsActor.Null;
+ }
+
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ public override float Simulate(float timeStep)
+ {
+ m_workIndicator = (m_workIndicator + 1) % 10;
+
+ return 0f;
+ }
+
+ public override void GetResults()
+ {
+ m_log.Info("[PHYSICS]: NullPhysicsScene : GetResults()");
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ m_log.InfoFormat("[PHYSICS]: NullPhysicsScene : SetTerrain({0} items)", heightMap.Length);
+ }
+
+ public override void DeleteTerrain()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ get { return false; }
+ }
+ public override void Dispose()
+ {
+
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsSensor.cs b/OpenSim/Region/Physics/Manager/PhysicsSensor.cs
new file mode 100644
index 0000000000..b85c5b31cb
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/PhysicsSensor.cs
@@ -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 OpenSim 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.Timers;
+using Axiom.Math;
+using OpenSim.Framework;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ [Flags]
+ public enum SenseType : uint
+ {
+ NONE = 0,
+ AGENT = 1,
+ ACTIVE = 2,
+ PASSIVE = 3,
+ SCRIPTED = 4
+
+ }
+ public abstract class PhysicsSensor
+ {
+
+ public static PhysicsSensor Null
+ {
+ get { return new NullPhysicsSensor(); }
+ }
+ public abstract PhysicsVector Position {get; set;}
+ public abstract void TimerCallback (object obj, ElapsedEventArgs eea);
+ public abstract float radianarc {get; set;}
+ public abstract string targetname {get; set;}
+ public abstract Guid targetKey{get;set;}
+ public abstract SenseType sensetype { get;set;}
+ public abstract float range { get;set;}
+ public abstract float rateSeconds { get;set;}
+
+
+
+ }
+
+ public class NullPhysicsSensor : PhysicsSensor
+ {
+
+ public override PhysicsVector Position
+ {
+ get { return PhysicsVector.Zero; }
+ set { return; }
+ }
+ public override void TimerCallback(object obj, ElapsedEventArgs eea)
+ {
+ // don't do squat
+ }
+ public override float radianarc { get { return 0f; } set { } }
+ public override string targetname { get { return ""; } set { } }
+ public override Guid targetKey { get { return Guid.Empty; } set { } }
+ public override SenseType sensetype { get { return SenseType.NONE; } set { } }
+ public override float range { get { return 0; } set { } }
+ public override float rateSeconds { get { return 0; } set { } }
+
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsVector.cs b/OpenSim/Region/Physics/Manager/PhysicsVector.cs
index 6194da0b76..d81115b0d3 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsVector.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsVector.cs
@@ -1,103 +1,158 @@
-/*
-* 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 OpenSim 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;
-
-namespace OpenSim.Region.Physics.Manager
-{
- public class PhysicsVector
- {
- public float X;
- public float Y;
- public float Z;
-
- public PhysicsVector()
- {
- }
-
- public PhysicsVector(float x, float y, float z)
- {
- X = x;
- Y = y;
- Z = z;
- }
-
- public static readonly PhysicsVector Zero = new PhysicsVector(0f, 0f, 0f);
-
- public override string ToString()
- {
- return "<" + X + "," + Y + "," + Z + ">";
- }
-
- // Operations
- public static PhysicsVector operator +(PhysicsVector a, PhysicsVector b)
- {
- return new PhysicsVector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
- }
-
- public static PhysicsVector operator -(PhysicsVector a, PhysicsVector b)
- {
- return new PhysicsVector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
- }
-
- public static PhysicsVector cross(PhysicsVector a, PhysicsVector b)
- {
- return new PhysicsVector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z, a.X*b.Y - a.Y*b.X);
- }
-
- public float length()
- {
- return (float) Math.Sqrt(X*X + Y*Y + Z*Z);
- }
-
- public static PhysicsVector operator /(PhysicsVector v, float f)
- {
- return new PhysicsVector(v.X/f, v.Y/f, v.Z/f);
- }
-
- public static PhysicsVector operator *(PhysicsVector v, float f)
- {
- return new PhysicsVector(v.X*f, v.Y*f, v.Z*f);
- }
-
- public static PhysicsVector operator *(float f, PhysicsVector v)
- {
- return v*f;
- }
-
- public virtual bool IsIdentical(PhysicsVector v, float tolerance)
- {
- PhysicsVector diff = this - v;
- float d = diff.length();
- if (d < tolerance)
- return true;
-
- return false;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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;
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public class PhysicsVector
+ {
+ public float X;
+ public float Y;
+ public float Z;
+
+ public PhysicsVector()
+ {
+ }
+
+ public PhysicsVector(float x, float y, float z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+ public void setValues(float x, float y, float z)
+ {
+ X = x;
+ Y = y;
+ Z = z;
+ }
+ public static readonly PhysicsVector Zero = new PhysicsVector(0f, 0f, 0f);
+
+ public override string ToString()
+ {
+ return "<" + X + "," + Y + "," + Z + ">";
+ }
+
+ ///
+ /// These routines are the easiest way to store XYZ values in an LLVector3 without requiring 3 calls.
+ ///
+ ///
+ public byte[] GetBytes()
+ {
+ byte[] byteArray = new byte[12];
+
+ Buffer.BlockCopy(BitConverter.GetBytes(X), 0, byteArray, 0, 4);
+ Buffer.BlockCopy(BitConverter.GetBytes(Y), 0, byteArray, 4, 4);
+ Buffer.BlockCopy(BitConverter.GetBytes(Z), 0, byteArray, 8, 4);
+
+ if (!BitConverter.IsLittleEndian)
+ {
+ Array.Reverse(byteArray, 0, 4);
+ Array.Reverse(byteArray, 4, 4);
+ Array.Reverse(byteArray, 8, 4);
+ }
+
+ return byteArray;
+ }
+
+ public void FromBytes(byte[] byteArray, int pos)
+ {
+ byte[] conversionBuffer = null;
+ if (!BitConverter.IsLittleEndian)
+ {
+ // Big endian architecture
+ if (conversionBuffer == null)
+ conversionBuffer = new byte[12];
+
+ Buffer.BlockCopy(byteArray, pos, conversionBuffer, 0, 12);
+
+ Array.Reverse(conversionBuffer, 0, 4);
+ Array.Reverse(conversionBuffer, 4, 4);
+ Array.Reverse(conversionBuffer, 8, 4);
+
+ X = BitConverter.ToSingle(conversionBuffer, 0);
+ Y = BitConverter.ToSingle(conversionBuffer, 4);
+ Z = BitConverter.ToSingle(conversionBuffer, 8);
+ }
+ else
+ {
+ // Little endian architecture
+ X = BitConverter.ToSingle(byteArray, pos);
+ Y = BitConverter.ToSingle(byteArray, pos + 4);
+ Z = BitConverter.ToSingle(byteArray, pos + 8);
+ }
+ }
+
+ // Operations
+ public static PhysicsVector operator +(PhysicsVector a, PhysicsVector b)
+ {
+ return new PhysicsVector(a.X + b.X, a.Y + b.Y, a.Z + b.Z);
+ }
+
+ public static PhysicsVector operator -(PhysicsVector a, PhysicsVector b)
+ {
+ return new PhysicsVector(a.X - b.X, a.Y - b.Y, a.Z - b.Z);
+ }
+
+ public static PhysicsVector cross(PhysicsVector a, PhysicsVector b)
+ {
+ return new PhysicsVector(a.Y*b.Z - a.Z*b.Y, a.Z*b.X - a.X*b.Z, a.X*b.Y - a.Y*b.X);
+ }
+
+ public float length()
+ {
+ return (float) Math.Sqrt(X*X + Y*Y + Z*Z);
+ }
+
+ public static PhysicsVector operator /(PhysicsVector v, float f)
+ {
+ return new PhysicsVector(v.X/f, v.Y/f, v.Z/f);
+ }
+
+ public static PhysicsVector operator *(PhysicsVector v, float f)
+ {
+ return new PhysicsVector(v.X*f, v.Y*f, v.Z*f);
+ }
+
+ public static PhysicsVector operator *(float f, PhysicsVector v)
+ {
+ return v*f;
+ }
+
+ public virtual bool IsIdentical(PhysicsVector v, float tolerance)
+ {
+ PhysicsVector diff = this - v;
+ float d = diff.length();
+ if (d < tolerance)
+ return true;
+
+ return false;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Manager/ZeroMesher.cs b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
index 63aab34fd7..da19b95247 100644
--- a/OpenSim/Region/Physics/Manager/ZeroMesher.cs
+++ b/OpenSim/Region/Physics/Manager/ZeroMesher.cs
@@ -1,69 +1,69 @@
-/*
-* 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 OpenSim 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 OpenSim.Framework;
-
-/*
- * This is the zero mesher.
- * Whatever you want him to mesh, he can't, telling you that by responding with a null pointer.
- * Effectivly this is for switching off meshing and for testing as each physics machine should deal
- * with the null pointer situation.
- * But it's also a convenience thing, as physics machines can rely on having a mesher in any situation, even
- * if it's a dump one like this.
- * Note, that this mesher is *not* living in a module but in the manager itself, so
- * it's always availabe and thus the default in case of configuration errors
-*/
-
-namespace OpenSim.Region.Physics.Manager
-{
- public class ZeroMesherPlugin : IMeshingPlugin
- {
- public ZeroMesherPlugin()
- {
- }
-
- public string GetName()
- {
- return "ZeroMesher";
- }
-
- public IMesher GetMesher()
- {
- return new ZeroMesher();
- }
- }
-
- public class ZeroMesher : IMesher
- {
- public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- {
- return null;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 OpenSim.Framework;
+
+/*
+ * This is the zero mesher.
+ * Whatever you want him to mesh, he can't, telling you that by responding with a null pointer.
+ * Effectivly this is for switching off meshing and for testing as each physics machine should deal
+ * with the null pointer situation.
+ * But it's also a convenience thing, as physics machines can rely on having a mesher in any situation, even
+ * if it's a dump one like this.
+ * Note, that this mesher is *not* living in a module but in the manager itself, so
+ * it's always availabe and thus the default in case of configuration errors
+*/
+
+namespace OpenSim.Region.Physics.Manager
+{
+ public class ZeroMesherPlugin : IMeshingPlugin
+ {
+ public ZeroMesherPlugin()
+ {
+ }
+
+ public string GetName()
+ {
+ return "ZeroMesher";
+ }
+
+ public IMesher GetMesher()
+ {
+ return new ZeroMesher();
+ }
+ }
+
+ public class ZeroMesher : IMesher
+ {
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ {
+ return null;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Meshing/Extruder.cs b/OpenSim/Region/Physics/Meshing/Extruder.cs
index ab065d15ba..7fe6bd69ef 100644
--- a/OpenSim/Region/Physics/Meshing/Extruder.cs
+++ b/OpenSim/Region/Physics/Meshing/Extruder.cs
@@ -1,110 +1,125 @@
-/*
-* 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 OpenSim 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 OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- internal class Extruder
- {
- public float startParameter;
- public float stopParameter;
- public PhysicsVector size;
-
- public Mesh Extrude(Mesh m)
- {
- // Currently only works for iSteps=1;
- Mesh result = new Mesh();
-
- Mesh workingPlus = m.Clone();
- Mesh workingMinus = m.Clone();
-
- foreach (Vertex v in workingPlus.vertices)
- {
- if (v == null)
- continue;
-
- v.Z = +.5f;
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
-
- foreach (Vertex v in workingMinus.vertices)
- {
- if (v == null)
- continue;
-
- v.Z = -.5f;
- v.X *= size.X;
- v.Y *= size.Y;
- v.Z *= size.Z;
- }
-
- foreach (Triangle t in workingMinus.triangles)
- {
- t.invertNormal();
- }
-
- result.Append(workingMinus);
- result.Append(workingPlus);
-
- int iLastNull = 0;
- for (int i = 0; i < workingPlus.vertices.Count; i++)
- {
- int iNext = (i + 1);
-
- if (workingPlus.vertices[i] == null) // Can't make a simplex here
- {
- iLastNull = i + 1;
- continue;
- }
-
- if (i == workingPlus.vertices.Count - 1) // End of list
- {
- iNext = iLastNull;
- }
-
- if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
- {
- iNext = iLastNull;
- }
-
- Triangle tSide;
- tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
- result.Add(tSide);
-
- tSide =
- new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
- result.Add(tSide);
- }
-
- return result;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ internal class Extruder
+ {
+ public float startParameter;
+ public float stopParameter;
+ public PhysicsVector size;
+
+ public float taperTopFactorX = 1f;
+ public float taperTopFactorY = 1f;
+ public float taperBotFactorX = 1f;
+ public float taperBotFactorY = 1f;
+ public float pushX = 0f;
+ public float pushY = 0f;
+
+ public Mesh Extrude(Mesh m)
+ {
+ // Currently only works for iSteps=1;
+ Mesh result = new Mesh();
+
+ Mesh workingPlus = m.Clone();
+ Mesh workingMinus = m.Clone();
+
+ foreach (Vertex v in workingPlus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ // This is the top
+ // Set the Z + .5 to match the rest of the scale of the mesh
+ // Scale it by Size, and Taper the scaling
+ v.Z = +.5f;
+ v.X *= (size.X * taperTopFactorX);
+ v.Y *= (size.Y * taperTopFactorY);
+ v.Z *= size.Z;
+
+ //Push the top of the object over by the Top Shear amount
+ v.X += pushX * size.X;
+ v.Y += pushY * size.X;
+ }
+
+ foreach (Vertex v in workingMinus.vertices)
+ {
+ if (v == null)
+ continue;
+
+ // This is the bottom
+ v.Z = -.5f;
+ v.X *= (size.X * taperBotFactorX);
+ v.Y *= (size.Y * taperBotFactorY);
+ v.Z *= size.Z;
+ }
+
+ foreach (Triangle t in workingMinus.triangles)
+ {
+ t.invertNormal();
+ }
+
+ result.Append(workingMinus);
+ result.Append(workingPlus);
+
+ int iLastNull = 0;
+ for (int i = 0; i < workingPlus.vertices.Count; i++)
+ {
+ int iNext = (i + 1);
+
+ if (workingPlus.vertices[i] == null) // Can't make a simplex here
+ {
+ iLastNull = i + 1;
+ continue;
+ }
+
+ if (i == workingPlus.vertices.Count - 1) // End of list
+ {
+ iNext = iLastNull;
+ }
+
+ if (workingPlus.vertices[iNext] == null) // Null means wrap to begin of last segment
+ {
+ iNext = iLastNull;
+ }
+
+ Triangle tSide;
+ tSide = new Triangle(workingPlus.vertices[i], workingMinus.vertices[i], workingPlus.vertices[iNext]);
+ result.Add(tSide);
+
+ tSide =
+ new Triangle(workingPlus.vertices[iNext], workingMinus.vertices[i], workingMinus.vertices[iNext]);
+ result.Add(tSide);
+ }
+
+ return result;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Meshing/HelperTypes.cs b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
index a5988ae85d..6aebaad3b6 100644
--- a/OpenSim/Region/Physics/Meshing/HelperTypes.cs
+++ b/OpenSim/Region/Physics/Meshing/HelperTypes.cs
@@ -1,304 +1,304 @@
-/*
-* 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 OpenSim 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.Diagnostics;
-using System.Globalization;
-using OpenSim.Region.Physics.Manager;
-using OpenSim.Region.Physics.Meshing;
-
-public class Vertex : PhysicsVector, IComparable
-{
- public Vertex(float x, float y, float z)
- : base(x, y, z)
- {
- }
-
- public Vertex(PhysicsVector v)
- : base(v.X, v.Y, v.Z)
- {
- }
-
- public Vertex Clone()
- {
- return new Vertex(X, Y, Z);
- }
-
- public static Vertex FromAngle(double angle)
- {
- return new Vertex((float) Math.Cos(angle), (float) Math.Sin(angle), 0.0f);
- }
-
-
- public virtual bool Equals(Vertex v, float tolerance)
- {
- PhysicsVector diff = this - v;
- float d = diff.length();
- if (d < tolerance)
- return true;
-
- return false;
- }
-
-
- public int CompareTo(Vertex other)
- {
- if (X < other.X)
- return -1;
-
- if (X > other.X)
- return 1;
-
- if (Y < other.Y)
- return -1;
-
- if (Y > other.Y)
- return 1;
-
- if (Z < other.Z)
- return -1;
-
- if (Z > other.Z)
- return 1;
-
- return 0;
- }
-
- public static bool operator >(Vertex me, Vertex other)
- {
- return me.CompareTo(other) > 0;
- }
-
- public static bool operator <(Vertex me, Vertex other)
- {
- return me.CompareTo(other) < 0;
- }
-
- public String ToRaw()
- {
- // Why this stuff with the number formatter?
- // Well, the raw format uses the english/US notation of numbers
- // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
- // The german notation uses these characters exactly vice versa!
- // The Float.ToString() routine is a localized one, giving different results depending on the country
- // settings your machine works with. Unusable for a machine readable file format :-(
- NumberFormatInfo nfi = new NumberFormatInfo();
- nfi.NumberDecimalSeparator = ".";
- nfi.NumberDecimalDigits = 3;
-
- String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
-
- return s1;
- }
-}
-
-public class Triangle
-{
- public Vertex v1;
- public Vertex v2;
- public Vertex v3;
-
- private float radius_square;
- private float cx;
- private float cy;
-
- public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
- {
- v1 = _v1;
- v2 = _v2;
- v3 = _v3;
-
- CalcCircle();
- }
-
- public bool isInCircle(float x, float y)
- {
- float dx, dy;
- float dd;
-
- dx = x - cx;
- dy = y - cy;
-
- dd = dx*dx + dy*dy;
- if (dd < radius_square)
- return true;
- else
- return false;
- }
-
- public bool isDegraded()
- {
- // This means, the vertices of this triangle are somewhat strange.
- // They either line up or at least two of them are identical
- return (radius_square == 0.0);
- }
-
- private void CalcCircle()
- {
- // Calculate the center and the radius of a circle given by three points p1, p2, p3
- // It is assumed, that the triangles vertices are already set correctly
- double p1x, p2x, p1y, p2y, p3x, p3y;
-
- // Deviation of this routine:
- // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
- // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
- // putting respectively two equations together gives two equations
- // f(p1)=f(p2) and f(p1)=f(p3)
- // bringing all constant terms to one side brings them to the form
- // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
- // and c1, c2 are scalars (Naming conventions like the variables below)
- // Now using the equations that are formed by the components of the vectors
- // and isolate Mx lets you make one equation that only holds My
- // The rest is straight forward and eaasy :-)
- //
-
- /* helping variables for temporary results */
- double c1, c2;
- double v1x, v1y, v2x, v2y;
-
- double z, n;
-
- double rx, ry;
-
- // Readout the three points, the triangle consists of
- p1x = v1.X;
- p1y = v1.Y;
-
- p2x = v2.X;
- p2y = v2.Y;
-
- p3x = v3.X;
- p3y = v3.Y;
-
- /* calc helping values first */
- c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
- c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
-
- v1x = p1x - p2x;
- v1y = p1y - p2y;
-
- v2x = p1x - p3x;
- v2y = p1y - p3y;
-
- z = (c1*v2x - c2*v1x);
- n = (v1y*v2x - v2y*v1x);
-
- if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
- {
- radius_square = 0.0f;
- return;
- }
-
- cy = (float) (z/n);
-
- if (v2x != 0.0)
- {
- cx = (float) ((c2 - v2y*cy)/v2x);
- }
- else if (v1x != 0.0)
- {
- cx = (float) ((c1 - v1y*cy)/v1x);
- }
- else
- {
- Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
- }
-
- rx = (p1x - cx);
- ry = (p1y - cy);
-
- radius_square = (float) (rx*rx + ry*ry);
- }
-
- public List GetSimplices()
- {
- List result = new List();
- Simplex s1 = new Simplex(v1, v2);
- Simplex s2 = new Simplex(v2, v3);
- Simplex s3 = new Simplex(v3, v1);
-
- result.Add(s1);
- result.Add(s2);
- result.Add(s3);
-
- return result;
- }
-
- public override String ToString()
- {
- NumberFormatInfo nfi = new NumberFormatInfo();
- nfi.CurrencyDecimalDigits = 2;
- nfi.CurrencyDecimalSeparator = ".";
-
- String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
- String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
- String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
-
- return s1 + ";" + s2 + ";" + s3;
- }
-
- public PhysicsVector getNormal()
- {
- // Vertices
-
- // Vectors for edges
- PhysicsVector e1;
- PhysicsVector e2;
-
- e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
- e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
-
- // Cross product for normal
- PhysicsVector n = PhysicsVector.cross(e1, e2);
-
- // Length
- float l = n.length();
-
- // Normalized "normal"
- n = n/l;
-
- return n;
- }
-
- public void invertNormal()
- {
- Vertex vt;
- vt = v1;
- v1 = v2;
- v2 = vt;
- }
-
- // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
- // debugging purposes
- public String ToStringRaw()
- {
- String output = v1.ToRaw() + " " + v2.ToRaw() + " " + v3.ToRaw();
- return output;
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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.Diagnostics;
+using System.Globalization;
+using OpenSim.Region.Physics.Manager;
+using OpenSim.Region.Physics.Meshing;
+
+public class Vertex : PhysicsVector, IComparable
+{
+ public Vertex(float x, float y, float z)
+ : base(x, y, z)
+ {
+ }
+
+ public Vertex(PhysicsVector v)
+ : base(v.X, v.Y, v.Z)
+ {
+ }
+
+ public Vertex Clone()
+ {
+ return new Vertex(X, Y, Z);
+ }
+
+ public static Vertex FromAngle(double angle)
+ {
+ return new Vertex((float) Math.Cos(angle), (float) Math.Sin(angle), 0.0f);
+ }
+
+
+ public virtual bool Equals(Vertex v, float tolerance)
+ {
+ PhysicsVector diff = this - v;
+ float d = diff.length();
+ if (d < tolerance)
+ return true;
+
+ return false;
+ }
+
+
+ public int CompareTo(Vertex other)
+ {
+ if (X < other.X)
+ return -1;
+
+ if (X > other.X)
+ return 1;
+
+ if (Y < other.Y)
+ return -1;
+
+ if (Y > other.Y)
+ return 1;
+
+ if (Z < other.Z)
+ return -1;
+
+ if (Z > other.Z)
+ return 1;
+
+ return 0;
+ }
+
+ public static bool operator >(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) > 0;
+ }
+
+ public static bool operator <(Vertex me, Vertex other)
+ {
+ return me.CompareTo(other) < 0;
+ }
+
+ public String ToRaw()
+ {
+ // Why this stuff with the number formatter?
+ // Well, the raw format uses the english/US notation of numbers
+ // where the "," separates groups of 1000 while the "." marks the border between 1 and 10E-1.
+ // The german notation uses these characters exactly vice versa!
+ // The Float.ToString() routine is a localized one, giving different results depending on the country
+ // settings your machine works with. Unusable for a machine readable file format :-(
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.NumberDecimalSeparator = ".";
+ nfi.NumberDecimalDigits = 3;
+
+ String s1 = X.ToString("N2", nfi) + " " + Y.ToString("N2", nfi) + " " + Z.ToString("N2", nfi);
+
+ return s1;
+ }
+}
+
+public class Triangle
+{
+ public Vertex v1;
+ public Vertex v2;
+ public Vertex v3;
+
+ private float radius_square;
+ private float cx;
+ private float cy;
+
+ public Triangle(Vertex _v1, Vertex _v2, Vertex _v3)
+ {
+ v1 = _v1;
+ v2 = _v2;
+ v3 = _v3;
+
+ CalcCircle();
+ }
+
+ public bool isInCircle(float x, float y)
+ {
+ float dx, dy;
+ float dd;
+
+ dx = x - cx;
+ dy = y - cy;
+
+ dd = dx*dx + dy*dy;
+ if (dd < radius_square)
+ return true;
+ else
+ return false;
+ }
+
+ public bool isDegraded()
+ {
+ // This means, the vertices of this triangle are somewhat strange.
+ // They either line up or at least two of them are identical
+ return (radius_square == 0.0);
+ }
+
+ private void CalcCircle()
+ {
+ // Calculate the center and the radius of a circle given by three points p1, p2, p3
+ // It is assumed, that the triangles vertices are already set correctly
+ double p1x, p2x, p1y, p2y, p3x, p3y;
+
+ // Deviation of this routine:
+ // A circle has the general equation (M-p)^2=r^2, where M and p are vectors
+ // this gives us three equations f(p)=r^2, each for one point p1, p2, p3
+ // putting respectively two equations together gives two equations
+ // f(p1)=f(p2) and f(p1)=f(p3)
+ // bringing all constant terms to one side brings them to the form
+ // M*v1=c1 resp.M*v2=c2 where v1=(p1-p2) and v2=(p1-p3) (still vectors)
+ // and c1, c2 are scalars (Naming conventions like the variables below)
+ // Now using the equations that are formed by the components of the vectors
+ // and isolate Mx lets you make one equation that only holds My
+ // The rest is straight forward and eaasy :-)
+ //
+
+ /* helping variables for temporary results */
+ double c1, c2;
+ double v1x, v1y, v2x, v2y;
+
+ double z, n;
+
+ double rx, ry;
+
+ // Readout the three points, the triangle consists of
+ p1x = v1.X;
+ p1y = v1.Y;
+
+ p2x = v2.X;
+ p2y = v2.Y;
+
+ p3x = v3.X;
+ p3y = v3.Y;
+
+ /* calc helping values first */
+ c1 = (p1x*p1x + p1y*p1y - p2x*p2x - p2y*p2y)/2;
+ c2 = (p1x*p1x + p1y*p1y - p3x*p3x - p3y*p3y)/2;
+
+ v1x = p1x - p2x;
+ v1y = p1y - p2y;
+
+ v2x = p1x - p3x;
+ v2y = p1y - p3y;
+
+ z = (c1*v2x - c2*v1x);
+ n = (v1y*v2x - v2y*v1x);
+
+ if (n == 0.0) // This is no triangle, i.e there are (at least) two points at the same location
+ {
+ radius_square = 0.0f;
+ return;
+ }
+
+ cy = (float) (z/n);
+
+ if (v2x != 0.0)
+ {
+ cx = (float) ((c2 - v2y*cy)/v2x);
+ }
+ else if (v1x != 0.0)
+ {
+ cx = (float) ((c1 - v1y*cy)/v1x);
+ }
+ else
+ {
+ Debug.Assert(false, "Malformed triangle"); /* Both terms zero means nothing good */
+ }
+
+ rx = (p1x - cx);
+ ry = (p1y - cy);
+
+ radius_square = (float) (rx*rx + ry*ry);
+ }
+
+ public List GetSimplices()
+ {
+ List result = new List();
+ Simplex s1 = new Simplex(v1, v2);
+ Simplex s2 = new Simplex(v2, v3);
+ Simplex s3 = new Simplex(v3, v1);
+
+ result.Add(s1);
+ result.Add(s2);
+ result.Add(s3);
+
+ return result;
+ }
+
+ public override String ToString()
+ {
+ NumberFormatInfo nfi = new NumberFormatInfo();
+ nfi.CurrencyDecimalDigits = 2;
+ nfi.CurrencyDecimalSeparator = ".";
+
+ String s1 = "<" + v1.X.ToString(nfi) + "," + v1.Y.ToString(nfi) + "," + v1.Z.ToString(nfi) + ">";
+ String s2 = "<" + v2.X.ToString(nfi) + "," + v2.Y.ToString(nfi) + "," + v2.Z.ToString(nfi) + ">";
+ String s3 = "<" + v3.X.ToString(nfi) + "," + v3.Y.ToString(nfi) + "," + v3.Z.ToString(nfi) + ">";
+
+ return s1 + ";" + s2 + ";" + s3;
+ }
+
+ public PhysicsVector getNormal()
+ {
+ // Vertices
+
+ // Vectors for edges
+ PhysicsVector e1;
+ PhysicsVector e2;
+
+ e1 = new PhysicsVector(v1.X - v2.X, v1.Y - v2.Y, v1.Z - v2.Z);
+ e2 = new PhysicsVector(v1.X - v3.X, v1.Y - v3.Y, v1.Z - v3.Z);
+
+ // Cross product for normal
+ PhysicsVector n = PhysicsVector.cross(e1, e2);
+
+ // Length
+ float l = n.length();
+
+ // Normalized "normal"
+ n = n/l;
+
+ return n;
+ }
+
+ public void invertNormal()
+ {
+ Vertex vt;
+ vt = v1;
+ v1 = v2;
+ v2 = vt;
+ }
+
+ // Dumps a triangle in the "raw faces" format, blender can import. This is for visualisation and
+ // debugging purposes
+ public String ToStringRaw()
+ {
+ String output = v1.ToRaw() + " " + v2.ToRaw() + " " + v3.ToRaw();
+ return output;
+ }
+}
diff --git a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
index cd013ea2c6..30fab39976 100644
--- a/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
+++ b/OpenSim/Region/Physics/Meshing/Meshmerizer.cs
@@ -1,389 +1,1081 @@
-/*
-* 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 OpenSim 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 OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- public class MeshmerizerPlugin : IMeshingPlugin
- {
- public MeshmerizerPlugin()
- {
- }
-
- public string GetName()
- {
- return "Meshmerizer";
- }
-
- public IMesher GetMesher()
- {
- return new Meshmerizer();
- }
- }
-
- public class Meshmerizer : IMesher
- {
- // Setting baseDir to a path will enable the dumping of raw files
- // raw files can be imported by blender so a visual inspection of the results can be done
- // const string baseDir = "rawFiles";
- private const string baseDir = null;
-
- private static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2,
- PhysicsVector r2, ref float lambda, ref float mu)
- {
- // p1, p2, points on the straight
- // r1, r2, directional vectors of the straight. Not necessarily of length 1!
- // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
- // thus allowing to decide whether an intersection is between two points
-
- float r1x = r1.X;
- float r1y = r1.Y;
- float r2x = r2.X;
- float r2y = r2.Y;
-
- float denom = r1y*r2x - r1x*r2y;
-
- if (denom == 0.0)
- {
- lambda = Single.NaN;
- mu = Single.NaN;
- return;
- }
-
- float p1x = p1.X;
- float p1y = p1.Y;
- float p2x = p2.X;
- float p2y = p2.Y;
- lambda = (-p2x*r2y + p1x*r2y + (p2y - p1y)*r2x)/denom;
- mu = (-p2x*r1y + p1x*r1y + (p2y - p1y)*r1x)/denom;
- }
-
- private static List FindInfluencedTriangles(List triangles, Vertex v)
- {
- List influenced = new List();
- foreach (Triangle t in triangles)
- {
- if (t.isInCircle(v.X, v.Y))
- {
- influenced.Add(t);
- }
- }
- return influenced;
- }
-
-
- private static void InsertVertices(List vertices, int usedForSeed, List triangles)
- {
- // This is a variant of the delaunay algorithm
- // each time a new vertex is inserted, all triangles that are influenced by it are deleted
- // and replaced by new ones including the new vertex
- // It is not very time efficient but easy to implement.
-
- int iCurrentVertex;
- int iMaxVertex = vertices.Count;
- for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
- {
- // Background: A triangle mesh fulfills the delaunay condition if (iff!)
- // each circumlocutory circle (i.e. the circle that touches all three corners)
- // of each triangle is empty of other vertices.
- // Obviously a single (seeding) triangle fulfills this condition.
- // If we now add one vertex, we need to reconstruct all triangles, that
- // do not fulfill this condition with respect to the new triangle
-
- // Find the triangles that are influenced by the new vertex
- Vertex v = vertices[iCurrentVertex];
- if (v == null)
- continue; // Null is polygon stop marker. Ignore it
- List influencedTriangles = FindInfluencedTriangles(triangles, v);
-
- List simplices = new List();
-
- // Reconstruction phase. First step, dissolve each triangle into it's simplices,
- // i.e. it's "border lines"
- // Goal is to find "inner" borders and delete them, while the hull gets conserved.
- // Inner borders are special in the way that they always come twice, which is how we detect them
- foreach (Triangle t in influencedTriangles)
- {
- List newSimplices = t.GetSimplices();
- simplices.AddRange(newSimplices);
- triangles.Remove(t);
- }
- // Now sort the simplices. That will make identical ones reside side by side in the list
- simplices.Sort();
-
- // Look for duplicate simplices here.
- // Remember, they are directly side by side in the list right now,
- // So we only check directly neighbours
- int iSimplex;
- List innerSimplices = new List();
- for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
- {
- if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
- {
- innerSimplices.Add(simplices[iSimplex - 1]);
- innerSimplices.Add(simplices[iSimplex]);
- }
- }
-
- foreach (Simplex s in innerSimplices)
- {
- simplices.Remove(s);
- }
-
- // each simplex still in the list belongs to the hull of the region in question
- // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
- // with each of these simplices. Build the new triangles and add them to the list
- foreach (Simplex s in simplices)
- {
- Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
- if (!t.isDegraded())
- {
- triangles.Add(t);
- }
- }
- }
- }
-
-
- private static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- // Builds the z (+ and -) surfaces of a box shaped prim
- {
- UInt16 hollowFactor = primShape.ProfileHollow;
- UInt16 profileBegin = primShape.ProfileBegin;
- UInt16 profileEnd = primShape.ProfileEnd;
-
- // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
- // of a block are basically the same
- // They may be warped differently but the shape is identical
- // So we only create one surface as a model and derive both plus and minus surface of the block from it
- // This is done in a model space where the block spans from -.5 to +.5 in X and Y
- // The mapping to Scene space is done later during the "extrusion" phase
-
- // Base
- Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
- Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
- Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
- Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
-
- SimpleHull outerHull = new SimpleHull();
- outerHull.AddVertex(MM);
- outerHull.AddVertex(PM);
- outerHull.AddVertex(PP);
- outerHull.AddVertex(MP);
-
- // Deal with cuts now
- if ((profileBegin != 0) || (profileEnd != 0))
- {
- double fProfileBeginAngle = profileBegin/50000.0*360.0;
- // In degree, for easier debugging and understanding
- fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
- double fProfileEndAngle = 360.0 - profileEnd/50000.0*360.0; // Pathend comes as complement to 1.0
- fProfileEndAngle -= (90.0 + 45.0);
- if (fProfileBeginAngle < fProfileEndAngle)
- fProfileEndAngle -= 360.0;
-
- // Note, that we don't want to cut out a triangle, even if this is a
- // good approximation for small cuts. Indeed we want to cut out an arc
- // and we approximate this arc by a polygon chain
- // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
- // So it can easily be subtracted from the outer hull
- int iSteps = (int) (((fProfileBeginAngle - fProfileEndAngle)/45.0) + .5);
- // how many steps do we need with approximately 45 degree
- double dStepWidth = (fProfileBeginAngle - fProfileEndAngle)/iSteps;
-
- Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
-
- // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
- SimpleHull cutHull = new SimpleHull();
- cutHull.AddVertex(origin);
- for (int i = 0; i < iSteps; i++)
- {
- double angle = fProfileBeginAngle - i*dStepWidth; // we count against the angle orientation!!!!
- Vertex v = Vertex.FromAngle(angle*Math.PI/180.0);
- cutHull.AddVertex(v);
- }
- Vertex legEnd = Vertex.FromAngle(fProfileEndAngle*Math.PI/180.0);
- // Calculated separately to avoid errors
- cutHull.AddVertex(legEnd);
-
- MainLog.Instance.Debug("Starting cutting of the hollow shape from the prim {1}", 0, primName);
- SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
-
- outerHull = cuttedHull;
- }
-
- // Deal with the hole here
- if (hollowFactor > 0)
- {
- float hollowFactorF = (float) hollowFactor/(float) 50000;
- Vertex IMM = new Vertex(-0.5f*hollowFactorF, -0.5f*hollowFactorF, 0.0f);
- Vertex IPM = new Vertex(+0.5f*hollowFactorF, -0.5f*hollowFactorF, 0.0f);
- Vertex IMP = new Vertex(-0.5f*hollowFactorF, +0.5f*hollowFactorF, 0.0f);
- Vertex IPP = new Vertex(+0.5f*hollowFactorF, +0.5f*hollowFactorF, 0.0f);
-
- SimpleHull holeHull = new SimpleHull();
-
- holeHull.AddVertex(IMM);
- holeHull.AddVertex(IMP);
- holeHull.AddVertex(IPP);
- holeHull.AddVertex(IPM);
-
- SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
-
- outerHull = hollowedHull;
- }
-
- Mesh m = new Mesh();
-
- Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
- Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
- Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
-
- m.Add(Seed1);
- m.Add(Seed2);
- m.Add(Seed3);
-
- m.Add(new Triangle(Seed1, Seed2, Seed3));
- m.Add(outerHull.getVertices());
-
- InsertVertices(m.vertices, 3, m.triangles);
- m.DumpRaw(baseDir, primName, "Proto first Mesh");
-
- m.Remove(Seed1);
- m.Remove(Seed2);
- m.Remove(Seed3);
- m.DumpRaw(baseDir, primName, "Proto seeds removed");
-
- m.RemoveTrianglesOutside(outerHull);
- m.DumpRaw(baseDir, primName, "Proto outsides removed");
-
- foreach (Triangle t in m.triangles)
- {
- PhysicsVector n = t.getNormal();
- if (n.Z < 0.0)
- t.invertNormal();
- }
-
- Extruder extr = new Extruder();
-
- extr.size = size;
-
- Mesh result = extr.Extrude(m);
- result.DumpRaw(baseDir, primName, "Z extruded");
- return result;
- }
-
- public static void CalcNormals(Mesh mesh)
- {
- int iTriangles = mesh.triangles.Count;
-
- mesh.normals = new float[iTriangles*3];
-
- int i = 0;
- foreach (Triangle t in mesh.triangles)
- {
- float ux, uy, uz;
- float vx, vy, vz;
- float wx, wy, wz;
-
- ux = t.v1.X;
- uy = t.v1.Y;
- uz = t.v1.Z;
-
- vx = t.v2.X;
- vy = t.v2.Y;
- vz = t.v2.Z;
-
- wx = t.v3.X;
- wy = t.v3.Y;
- wz = t.v3.Z;
-
-
- // Vectors for edges
- float e1x, e1y, e1z;
- float e2x, e2y, e2z;
-
- e1x = ux - vx;
- e1y = uy - vy;
- e1z = uz - vz;
-
- e2x = ux - wx;
- e2y = uy - wy;
- e2z = uz - wz;
-
-
- // Cross product for normal
- float nx, ny, nz;
- nx = e1y*e2z - e1z*e2y;
- ny = e1z*e2x - e1x*e2z;
- nz = e1x*e2y - e1y*e2x;
-
- // Length
- float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
-
- // Normalized "normal"
- nx /= l;
- ny /= l;
- nz /= l;
-
- mesh.normals[i] = nx;
- mesh.normals[i + 1] = ny;
- mesh.normals[i + 2] = nz;
-
- i += 3;
- }
- }
-
- public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
- {
- Mesh mesh = null;
-
- switch (primShape.ProfileShape)
- {
- case ProfileShape.Square:
- mesh = CreateBoxMesh(primName, primShape, size);
- CalcNormals(mesh);
- break;
- default:
- mesh = CreateBoxMesh(primName, primShape, size);
- CalcNormals(mesh);
- //Set default mesh to cube otherwise it'll return
- // null and crash on the 'setMesh' method in the physics plugins.
- //mesh = null;
- break;
- }
-
- return mesh;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ public class MeshmerizerPlugin : IMeshingPlugin
+ {
+ public MeshmerizerPlugin()
+ {
+ }
+
+ public string GetName()
+ {
+ return "Meshmerizer";
+ }
+
+ public IMesher GetMesher()
+ {
+ return new Meshmerizer();
+ }
+ }
+
+ public class Meshmerizer : IMesher
+ {
+ //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ // Setting baseDir to a path will enable the dumping of raw files
+ // raw files can be imported by blender so a visual inspection of the results can be done
+ // const string baseDir = "rawFiles";
+ private const string baseDir = null; //"rawFiles";
+
+ private static void IntersectionParameterPD(PhysicsVector p1, PhysicsVector r1, PhysicsVector p2,
+ PhysicsVector r2, ref float lambda, ref float mu)
+ {
+ // p1, p2, points on the straight
+ // r1, r2, directional vectors of the straight. Not necessarily of length 1!
+ // note, that l, m can be scaled such, that the range 0..1 is mapped to the area between two points,
+ // thus allowing to decide whether an intersection is between two points
+
+ float r1x = r1.X;
+ float r1y = r1.Y;
+ float r2x = r2.X;
+ float r2y = r2.Y;
+
+ float denom = r1y*r2x - r1x*r2y;
+
+ if (denom == 0.0)
+ {
+ lambda = Single.NaN;
+ mu = Single.NaN;
+ return;
+ }
+
+ float p1x = p1.X;
+ float p1y = p1.Y;
+ float p2x = p2.X;
+ float p2y = p2.Y;
+ lambda = (-p2x*r2y + p1x*r2y + (p2y - p1y)*r2x)/denom;
+ mu = (-p2x*r1y + p1x*r1y + (p2y - p1y)*r1x)/denom;
+ }
+
+ private static List FindInfluencedTriangles(List triangles, Vertex v)
+ {
+ List influenced = new List();
+ foreach (Triangle t in triangles)
+ {
+ if (t.isInCircle(v.X, v.Y))
+ {
+ influenced.Add(t);
+ }
+ }
+ return influenced;
+ }
+
+ private static void InsertVertices(List vertices, int usedForSeed, List triangles)
+ {
+ // This is a variant of the delaunay algorithm
+ // each time a new vertex is inserted, all triangles that are influenced by it are deleted
+ // and replaced by new ones including the new vertex
+ // It is not very time efficient but easy to implement.
+
+ int iCurrentVertex;
+ int iMaxVertex = vertices.Count;
+ for (iCurrentVertex = usedForSeed; iCurrentVertex < iMaxVertex; iCurrentVertex++)
+ {
+ // Background: A triangle mesh fulfills the delaunay condition if (iff!)
+ // each circumlocutory circle (i.e. the circle that touches all three corners)
+ // of each triangle is empty of other vertices.
+ // Obviously a single (seeding) triangle fulfills this condition.
+ // If we now add one vertex, we need to reconstruct all triangles, that
+ // do not fulfill this condition with respect to the new triangle
+
+ // Find the triangles that are influenced by the new vertex
+ Vertex v = vertices[iCurrentVertex];
+ if (v == null)
+ continue; // Null is polygon stop marker. Ignore it
+ List influencedTriangles = FindInfluencedTriangles(triangles, v);
+
+ List simplices = new List();
+
+ // Reconstruction phase. First step, dissolve each triangle into it's simplices,
+ // i.e. it's "border lines"
+ // Goal is to find "inner" borders and delete them, while the hull gets conserved.
+ // Inner borders are special in the way that they always come twice, which is how we detect them
+ foreach (Triangle t in influencedTriangles)
+ {
+ List newSimplices = t.GetSimplices();
+ simplices.AddRange(newSimplices);
+ triangles.Remove(t);
+ }
+ // Now sort the simplices. That will make identical ones reside side by side in the list
+ simplices.Sort();
+
+ // Look for duplicate simplices here.
+ // Remember, they are directly side by side in the list right now,
+ // So we only check directly neighbours
+ int iSimplex;
+ List innerSimplices = new List();
+ for (iSimplex = 1; iSimplex < simplices.Count; iSimplex++) // Startindex=1, so we can refer backwards
+ {
+ if (simplices[iSimplex - 1].CompareTo(simplices[iSimplex]) == 0)
+ {
+ innerSimplices.Add(simplices[iSimplex - 1]);
+ innerSimplices.Add(simplices[iSimplex]);
+ }
+ }
+
+ foreach (Simplex s in innerSimplices)
+ {
+ simplices.Remove(s);
+ }
+
+ // each simplex still in the list belongs to the hull of the region in question
+ // The new vertex (yes, we still deal with verices here :-) ) forms a triangle
+ // with each of these simplices. Build the new triangles and add them to the list
+ foreach (Simplex s in simplices)
+ {
+ Triangle t = new Triangle(s.v1, s.v2, vertices[iCurrentVertex]);
+ if (!t.isDegraded())
+ {
+ triangles.Add(t);
+ }
+ }
+ }
+ }
+
+ private static SimpleHull BuildHoleHull(PrimitiveBaseShape pbs, ProfileShape pshape, HollowShape hshape, UInt16 hollowFactor)
+ {
+ // Tackle HollowShape.Same
+ float fhollowFactor = (float)hollowFactor;
+
+ switch (pshape)
+ {
+ case ProfileShape.Square:
+ if (hshape == HollowShape.Same)
+ hshape= HollowShape.Square;
+ break;
+ case ProfileShape.EquilateralTriangle:
+ fhollowFactor = ((float)hollowFactor / 1.9f);
+ if (hshape == HollowShape.Same)
+ {
+ hshape = HollowShape.Triangle;
+ }
+
+ break;
+
+ case ProfileShape.Circle:
+ if (pbs.PathCurve == (byte)Extrusion.Straight)
+ {
+ if (hshape == HollowShape.Same)
+ {
+ hshape = HollowShape.Circle;
+ }
+ }
+ break;
+ default:
+ if (hshape == HollowShape.Same)
+ hshape= HollowShape.Square;
+ break;
+ }
+
+
+ SimpleHull holeHull = null;
+
+ if (hshape == HollowShape.Square)
+ {
+ float hollowFactorF = (float)fhollowFactor / (float)50000;
+ Vertex IMM = new Vertex(-0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IPM = new Vertex(+0.5f * hollowFactorF, -0.5f * hollowFactorF, 0.0f);
+ Vertex IPP = new Vertex(+0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+ Vertex IMP = new Vertex(-0.5f * hollowFactorF, +0.5f * hollowFactorF, 0.0f);
+
+
+ holeHull = new SimpleHull();
+
+ holeHull.AddVertex(IMM);
+ holeHull.AddVertex(IMP);
+ holeHull.AddVertex(IPP);
+ holeHull.AddVertex(IPM);
+ }
+ if (hshape == HollowShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
+ {
+ float hollowFactorF = (float)fhollowFactor / (float)50000;
+
+ Vertex IQ1Q15 = new Vertex(-0.35f * hollowFactorF, -0.35f * hollowFactorF, 0.0f);
+ Vertex IQ1Q16 = new Vertex(-0.30f * hollowFactorF, -0.40f * hollowFactorF, 0.0f);
+ Vertex IQ1Q17 = new Vertex(-0.24f * hollowFactorF, -0.43f * hollowFactorF, 0.0f);
+ Vertex IQ1Q18 = new Vertex(-0.18f * hollowFactorF, -0.46f * hollowFactorF, 0.0f);
+ Vertex IQ1Q19 = new Vertex(-0.11f * hollowFactorF, -0.48f * hollowFactorF, 0.0f);
+
+ Vertex IQ2Q10 = new Vertex(+0.0f * hollowFactorF, -0.50f * hollowFactorF, 0.0f);
+ Vertex IQ2Q11 = new Vertex(+0.11f * hollowFactorF, -0.48f * hollowFactorF, 0.0f);
+ Vertex IQ2Q12 = new Vertex(+0.18f * hollowFactorF, -0.46f * hollowFactorF, 0.0f);
+ Vertex IQ2Q13 = new Vertex(+0.24f * hollowFactorF, -0.43f * hollowFactorF, 0.0f);
+ Vertex IQ2Q14 = new Vertex(+0.30f * hollowFactorF, -0.40f * hollowFactorF, 0.0f);
+ Vertex IQ2Q15 = new Vertex(+0.35f * hollowFactorF, -0.35f * hollowFactorF, 0.0f);
+ Vertex IQ2Q16 = new Vertex(+0.40f * hollowFactorF, -0.30f * hollowFactorF, 0.0f);
+ Vertex IQ2Q17 = new Vertex(+0.43f * hollowFactorF, -0.24f * hollowFactorF, 0.0f);
+ Vertex IQ2Q18 = new Vertex(+0.46f * hollowFactorF, -0.18f * hollowFactorF, 0.0f);
+ Vertex IQ2Q19 = new Vertex(+0.48f * hollowFactorF, -0.11f * hollowFactorF, 0.0f);
+
+ Vertex IQ2Q20 = new Vertex(+0.50f * hollowFactorF, +0.0f * hollowFactorF, 0.0f);
+ Vertex IQ2Q21 = new Vertex(+0.48f * hollowFactorF, +0.11f * hollowFactorF, 0.0f);
+ Vertex IQ2Q22 = new Vertex(+0.46f * hollowFactorF, +0.18f * hollowFactorF, 0.0f);
+ Vertex IQ2Q23 = new Vertex(+0.43f * hollowFactorF, +0.24f * hollowFactorF, 0.0f);
+ Vertex IQ2Q24 = new Vertex(+0.40f * hollowFactorF, +0.30f * hollowFactorF, 0.0f);
+ Vertex IQ2Q25 = new Vertex(+0.35f * hollowFactorF, +0.35f * hollowFactorF, 0.0f);
+ Vertex IQ2Q26 = new Vertex(+0.30f * hollowFactorF, +0.40f * hollowFactorF, 0.0f);
+ Vertex IQ2Q27 = new Vertex(+0.24f * hollowFactorF, +0.43f * hollowFactorF, 0.0f);
+ Vertex IQ2Q28 = new Vertex(+0.18f * hollowFactorF, +0.46f * hollowFactorF, 0.0f);
+ Vertex IQ2Q29 = new Vertex(+0.11f * hollowFactorF, +0.48f * hollowFactorF, 0.0f);
+
+ Vertex IQ1Q20 = new Vertex(+0.0f * hollowFactorF, +0.50f * hollowFactorF, 0.0f);
+ Vertex IQ1Q21 = new Vertex(-0.11f * hollowFactorF, +0.48f * hollowFactorF, 0.0f);
+ Vertex IQ1Q22 = new Vertex(-0.18f * hollowFactorF, +0.46f * hollowFactorF, 0.0f);
+ Vertex IQ1Q23 = new Vertex(-0.24f * hollowFactorF, +0.43f * hollowFactorF, 0.0f);
+ Vertex IQ1Q24 = new Vertex(-0.30f * hollowFactorF, +0.40f * hollowFactorF, 0.0f);
+ Vertex IQ1Q25 = new Vertex(-0.35f * hollowFactorF, +0.35f * hollowFactorF, 0.0f);
+ Vertex IQ1Q26 = new Vertex(-0.40f * hollowFactorF, +0.30f * hollowFactorF, 0.0f);
+ Vertex IQ1Q27 = new Vertex(-0.43f * hollowFactorF, +0.24f * hollowFactorF, 0.0f);
+ Vertex IQ1Q28 = new Vertex(-0.46f * hollowFactorF, +0.18f * hollowFactorF, 0.0f);
+ Vertex IQ1Q29 = new Vertex(-0.48f * hollowFactorF, +0.11f * hollowFactorF, 0.0f);
+
+ Vertex IQ1Q10 = new Vertex(-0.50f * hollowFactorF, +0.0f * hollowFactorF, 0.0f);
+ Vertex IQ1Q11 = new Vertex(-0.48f * hollowFactorF, -0.11f * hollowFactorF, 0.0f);
+ Vertex IQ1Q12 = new Vertex(-0.46f * hollowFactorF, -0.18f * hollowFactorF, 0.0f);
+ Vertex IQ1Q13 = new Vertex(-0.43f * hollowFactorF, -0.24f * hollowFactorF, 0.0f);
+ Vertex IQ1Q14 = new Vertex(-0.40f * hollowFactorF, -0.30f * hollowFactorF, 0.0f);
+
+ //Counter clockwise around the quadrants
+ holeHull = new SimpleHull();
+ holeHull.AddVertex(IQ1Q15);
+ holeHull.AddVertex(IQ1Q14);
+ holeHull.AddVertex(IQ1Q13);
+ holeHull.AddVertex(IQ1Q12);
+ holeHull.AddVertex(IQ1Q11);
+ holeHull.AddVertex(IQ1Q10);
+
+ holeHull.AddVertex(IQ1Q29);
+ holeHull.AddVertex(IQ1Q28);
+ holeHull.AddVertex(IQ1Q27);
+ holeHull.AddVertex(IQ1Q26);
+ holeHull.AddVertex(IQ1Q25);
+ holeHull.AddVertex(IQ1Q24);
+ holeHull.AddVertex(IQ1Q23);
+ holeHull.AddVertex(IQ1Q22);
+ holeHull.AddVertex(IQ1Q21);
+ holeHull.AddVertex(IQ1Q20);
+
+ holeHull.AddVertex(IQ2Q29);
+ holeHull.AddVertex(IQ2Q28);
+ holeHull.AddVertex(IQ2Q27);
+ holeHull.AddVertex(IQ2Q26);
+ holeHull.AddVertex(IQ2Q25);
+ holeHull.AddVertex(IQ2Q24);
+ holeHull.AddVertex(IQ2Q23);
+ holeHull.AddVertex(IQ2Q22);
+ holeHull.AddVertex(IQ2Q21);
+ holeHull.AddVertex(IQ2Q20);
+
+ holeHull.AddVertex(IQ2Q19);
+ holeHull.AddVertex(IQ2Q18);
+ holeHull.AddVertex(IQ2Q17);
+ holeHull.AddVertex(IQ2Q16);
+ holeHull.AddVertex(IQ2Q15);
+ holeHull.AddVertex(IQ2Q14);
+ holeHull.AddVertex(IQ2Q13);
+ holeHull.AddVertex(IQ2Q12);
+ holeHull.AddVertex(IQ2Q11);
+ holeHull.AddVertex(IQ2Q10);
+
+ holeHull.AddVertex(IQ1Q19);
+ holeHull.AddVertex(IQ1Q18);
+ holeHull.AddVertex(IQ1Q17);
+ holeHull.AddVertex(IQ1Q16);
+ }
+ if (hshape == HollowShape.Triangle)
+ {
+ float hollowFactorF = (float)fhollowFactor / (float)50000;
+ Vertex IMM = new Vertex(-0.25f * hollowFactorF, -0.45f * hollowFactorF, 0.0f);
+ Vertex IPM = new Vertex(+0.5f * hollowFactorF, +0f * hollowFactorF, 0.0f);
+ Vertex IPP = new Vertex(-0.25f * hollowFactorF, +0.45f * hollowFactorF, 0.0f);
+
+
+
+ holeHull = new SimpleHull();
+
+ holeHull.AddVertex(IMM);
+ holeHull.AddVertex(IPP);
+ holeHull.AddVertex(IPM);
+
+ }
+
+ return holeHull;
+
+
+ }
+
+ private static Mesh CreateBoxMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ // Builds the z (+ and -) surfaces of a box shaped prim
+ {
+ UInt16 hollowFactor = primShape.ProfileHollow;
+ UInt16 profileBegin = primShape.ProfileBegin;
+ UInt16 profileEnd = primShape.ProfileEnd;
+ UInt16 taperX = primShape.PathScaleX;
+ UInt16 taperY = primShape.PathScaleY;
+ UInt16 pathShearX = primShape.PathShearX;
+ UInt16 pathShearY = primShape.PathShearY;
+
+
+ //m_log.Error("pathShear:" + primShape.PathShearX.ToString() + "," + primShape.PathShearY.ToString());
+ //m_log.Error("pathTaper:" + primShape.PathTaperX.ToString() + "," + primShape.PathTaperY.ToString());
+ //m_log.Error("ProfileBegin:" + primShape.ProfileBegin.ToString() + "," + primShape.ProfileBegin.ToString());
+ //m_log.Error("PathScale:" + primShape.PathScaleX.ToString() + "," + primShape.PathScaleY.ToString());
+
+ // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
+ // of a block are basically the same
+ // They may be warped differently but the shape is identical
+ // So we only create one surface as a model and derive both plus and minus surface of the block from it
+ // This is done in a model space where the block spans from -.5 to +.5 in X and Y
+ // The mapping to Scene space is done later during the "extrusion" phase
+
+ // Base
+ Vertex MM = new Vertex(-0.5f, -0.5f, 0.0f);
+ Vertex PM = new Vertex(+0.5f, -0.5f, 0.0f);
+ Vertex PP = new Vertex(+0.5f, +0.5f, 0.0f);
+ Vertex MP = new Vertex(-0.5f, +0.5f, 0.0f);
+
+ SimpleHull outerHull = new SimpleHull();
+ outerHull.AddVertex(MM);
+ outerHull.AddVertex(PM);
+ outerHull.AddVertex(PP);
+ outerHull.AddVertex(MP);
+
+ // Deal with cuts now
+ if ((profileBegin != 0) || (profileEnd != 0))
+ {
+ double fProfileBeginAngle = profileBegin/50000.0*360.0;
+ // In degree, for easier debugging and understanding
+ fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
+ double fProfileEndAngle = 360.0 - profileEnd/50000.0*360.0; // Pathend comes as complement to 1.0
+ fProfileEndAngle -= (90.0 + 45.0);
+ if (fProfileBeginAngle < fProfileEndAngle)
+ fProfileEndAngle -= 360.0;
+
+ // Note, that we don't want to cut out a triangle, even if this is a
+ // good approximation for small cuts. Indeed we want to cut out an arc
+ // and we approximate this arc by a polygon chain
+ // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
+ // So it can easily be subtracted from the outer hull
+ int iSteps = (int) (((fProfileBeginAngle - fProfileEndAngle)/45.0) + .5);
+ // how many steps do we need with approximately 45 degree
+ double dStepWidth = (fProfileBeginAngle - fProfileEndAngle)/iSteps;
+
+ Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
+
+ // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
+ SimpleHull cutHull = new SimpleHull();
+ cutHull.AddVertex(origin);
+ for (int i = 0; i < iSteps; i++)
+ {
+ double angle = fProfileBeginAngle - i*dStepWidth; // we count against the angle orientation!!!!
+ Vertex v = Vertex.FromAngle(angle*Math.PI/180.0);
+ cutHull.AddVertex(v);
+ }
+ Vertex legEnd = Vertex.FromAngle(fProfileEndAngle*Math.PI/180.0);
+ // Calculated separately to avoid errors
+ cutHull.AddVertex(legEnd);
+
+ //m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
+ SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
+
+ outerHull = cuttedHull;
+ }
+
+ // Deal with the hole here
+ if (hollowFactor > 0)
+ {
+
+ SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
+ if (holeHull != null)
+ {
+ SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
+
+ outerHull = hollowedHull;
+ }
+ }
+
+ Mesh m = new Mesh();
+
+ Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
+ Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
+ Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
+
+ m.Add(Seed1);
+ m.Add(Seed2);
+ m.Add(Seed3);
+
+ m.Add(new Triangle(Seed1, Seed2, Seed3));
+ m.Add(outerHull.getVertices());
+
+ InsertVertices(m.vertices, 3, m.triangles);
+ m.DumpRaw(baseDir, primName, "Proto first Mesh");
+
+ m.Remove(Seed1);
+ m.Remove(Seed2);
+ m.Remove(Seed3);
+ m.DumpRaw(baseDir, primName, "Proto seeds removed");
+
+ m.RemoveTrianglesOutside(outerHull);
+ m.DumpRaw(baseDir, primName, "Proto outsides removed");
+
+ foreach (Triangle t in m.triangles)
+ {
+ PhysicsVector n = t.getNormal();
+ if (n.Z < 0.0)
+ t.invertNormal();
+ }
+
+ Extruder extr = new Extruder();
+
+ extr.size = size;
+
+ if (taperX != 100)
+ {
+ if (taperX > 100)
+ {
+ extr.taperTopFactorX = 1.0f - ((float)taperX / 200);
+ //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
+ //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
+ }
+
+ }
+
+ if (taperY != 100)
+ {
+ if (taperY > 100)
+ {
+ extr.taperTopFactorY = 1.0f - ((float)taperY / 200);
+ //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
+ //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
+ }
+ }
+
+
+ if (pathShearX != 0)
+ {
+ if (pathShearX > 50) {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
+ // m_log.Warn("pushX: " + extr.pushX);
+ }
+ else
+ {
+ extr.pushX = (float)pathShearX / 100;
+ // m_log.Warn("pushX: " + extr.pushX);
+ }
+ }
+
+ if (pathShearY != 0)
+ {
+ if (pathShearY > 50) {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ else
+ {
+ extr.pushY = (float)pathShearY / 100;
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ }
+
+ Mesh result = extr.Extrude(m);
+ result.DumpRaw(baseDir, primName, "Z extruded");
+ return result;
+ }
+
+ private static Mesh CreateCyllinderMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ // Builds the z (+ and -) surfaces of a box shaped prim
+ {
+ UInt16 hollowFactor = primShape.ProfileHollow;
+ UInt16 profileBegin = primShape.ProfileBegin;
+ UInt16 profileEnd = primShape.ProfileEnd;
+ UInt16 taperX = primShape.PathScaleX;
+ UInt16 taperY = primShape.PathScaleY;
+ UInt16 pathShearX = primShape.PathShearX;
+ UInt16 pathShearY = primShape.PathShearY;
+
+ // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
+ // of a block are basically the same
+ // They may be warped differently but the shape is identical
+ // So we only create one surface as a model and derive both plus and minus surface of the block from it
+ // This is done in a model space where the block spans from -.5 to +.5 in X and Y
+ // The mapping to Scene space is done later during the "extrusion" phase
+
+ // Base
+ // Q1Q15 = Quadrant 1, Quadrant1, Vertex 5
+ Vertex Q1Q15 = new Vertex(-0.35f, -0.35f, 0.0f);
+ Vertex Q1Q16 = new Vertex(-0.30f, -0.40f, 0.0f);
+ Vertex Q1Q17 = new Vertex(-0.24f, -0.43f, 0.0f);
+ Vertex Q1Q18 = new Vertex(-0.18f, -0.46f, 0.0f);
+ Vertex Q1Q19 = new Vertex(-0.11f, -0.48f, 0.0f);
+
+ Vertex Q2Q10 = new Vertex(+0.0f, -0.50f, 0.0f);
+ Vertex Q2Q11 = new Vertex(+0.11f, -0.48f, 0.0f);
+ Vertex Q2Q12 = new Vertex(+0.18f, -0.46f, 0.0f);
+ Vertex Q2Q13 = new Vertex(+0.24f, -0.43f, 0.0f);
+ Vertex Q2Q14 = new Vertex(+0.30f, -0.40f, 0.0f);
+ Vertex Q2Q15 = new Vertex(+0.35f, -0.35f, 0.0f);
+ Vertex Q2Q16 = new Vertex(+0.40f, -0.30f, 0.0f);
+ Vertex Q2Q17 = new Vertex(+0.43f, -0.24f, 0.0f);
+ Vertex Q2Q18 = new Vertex(+0.46f, -0.18f, 0.0f);
+ Vertex Q2Q19 = new Vertex(+0.48f, -0.11f, 0.0f);
+
+ Vertex Q2Q20 = new Vertex(+0.50f, +0.0f, 0.0f);
+ Vertex Q2Q21 = new Vertex(+0.48f, +0.11f, 0.0f);
+ Vertex Q2Q22 = new Vertex(+0.46f, +0.18f, 0.0f);
+ Vertex Q2Q23 = new Vertex(+0.43f, +0.24f, 0.0f);
+ Vertex Q2Q24 = new Vertex(+0.40f, +0.30f, 0.0f);
+ Vertex Q2Q25 = new Vertex(+0.35f, +0.35f, 0.0f);
+ Vertex Q2Q26 = new Vertex(+0.30f, +0.40f, 0.0f);
+ Vertex Q2Q27 = new Vertex(+0.24f, +0.43f, 0.0f);
+ Vertex Q2Q28 = new Vertex(+0.18f, +0.46f, 0.0f);
+ Vertex Q2Q29 = new Vertex(+0.11f, +0.48f, 0.0f);
+
+ Vertex Q1Q20 = new Vertex(+0.0f, +0.50f, 0.0f);
+ Vertex Q1Q21 = new Vertex(-0.11f, +0.48f, 0.0f);
+ Vertex Q1Q22 = new Vertex(-0.18f, +0.46f, 0.0f);
+ Vertex Q1Q23 = new Vertex(-0.24f, +0.43f, 0.0f);
+ Vertex Q1Q24 = new Vertex(-0.30f, +0.40f, 0.0f);
+ Vertex Q1Q25 = new Vertex(-0.35f, +0.35f, 0.0f);
+ Vertex Q1Q26 = new Vertex(-0.40f, +0.30f, 0.0f);
+ Vertex Q1Q27 = new Vertex(-0.43f, +0.24f, 0.0f);
+ Vertex Q1Q28 = new Vertex(-0.46f, +0.18f, 0.0f);
+ Vertex Q1Q29 = new Vertex(-0.48f, +0.11f, 0.0f);
+
+ Vertex Q1Q10 = new Vertex(-0.50f, +0.0f, 0.0f);
+ Vertex Q1Q11 = new Vertex(-0.48f, -0.11f, 0.0f);
+ Vertex Q1Q12 = new Vertex(-0.46f, -0.18f, 0.0f);
+ Vertex Q1Q13 = new Vertex(-0.43f, -0.24f, 0.0f);
+ Vertex Q1Q14 = new Vertex(-0.40f, -0.30f, 0.0f);
+
+ SimpleHull outerHull = new SimpleHull();
+ //Clockwise around the quadrants
+ outerHull.AddVertex(Q1Q15);
+ outerHull.AddVertex(Q1Q16);
+ outerHull.AddVertex(Q1Q17);
+ outerHull.AddVertex(Q1Q18);
+ outerHull.AddVertex(Q1Q19);
+
+ outerHull.AddVertex(Q2Q10);
+ outerHull.AddVertex(Q2Q11);
+ outerHull.AddVertex(Q2Q12);
+ outerHull.AddVertex(Q2Q13);
+ outerHull.AddVertex(Q2Q14);
+ outerHull.AddVertex(Q2Q15);
+ outerHull.AddVertex(Q2Q16);
+ outerHull.AddVertex(Q2Q17);
+ outerHull.AddVertex(Q2Q18);
+ outerHull.AddVertex(Q2Q19);
+
+ outerHull.AddVertex(Q2Q20);
+ outerHull.AddVertex(Q2Q21);
+ outerHull.AddVertex(Q2Q22);
+ outerHull.AddVertex(Q2Q23);
+ outerHull.AddVertex(Q2Q24);
+ outerHull.AddVertex(Q2Q25);
+ outerHull.AddVertex(Q2Q26);
+ outerHull.AddVertex(Q2Q27);
+ outerHull.AddVertex(Q2Q28);
+ outerHull.AddVertex(Q2Q29);
+
+ outerHull.AddVertex(Q1Q20);
+ outerHull.AddVertex(Q1Q21);
+ outerHull.AddVertex(Q1Q22);
+ outerHull.AddVertex(Q1Q23);
+ outerHull.AddVertex(Q1Q24);
+ outerHull.AddVertex(Q1Q25);
+ outerHull.AddVertex(Q1Q26);
+ outerHull.AddVertex(Q1Q27);
+ outerHull.AddVertex(Q1Q28);
+ outerHull.AddVertex(Q1Q29);
+
+ outerHull.AddVertex(Q1Q10);
+ outerHull.AddVertex(Q1Q11);
+ outerHull.AddVertex(Q1Q12);
+ outerHull.AddVertex(Q1Q13);
+ outerHull.AddVertex(Q1Q14);
+
+ // Deal with cuts now
+ if ((profileBegin != 0) || (profileEnd != 0))
+ {
+ double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
+ // In degree, for easier debugging and understanding
+ //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
+ double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
+ //fProfileEndAngle -= (90.0 + 45.0);
+ if (fProfileBeginAngle < fProfileEndAngle)
+ fProfileEndAngle -= 360.0;
+
+ // Note, that we don't want to cut out a triangle, even if this is a
+ // good approximation for small cuts. Indeed we want to cut out an arc
+ // and we approximate this arc by a polygon chain
+ // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
+ // So it can easily be subtracted from the outer hull
+ int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
+ // how many steps do we need with approximately 45 degree
+ double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
+
+ Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
+
+ // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
+ SimpleHull cutHull = new SimpleHull();
+ cutHull.AddVertex(origin);
+ for (int i = 0; i < iSteps; i++)
+ {
+ double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
+ Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
+ cutHull.AddVertex(v);
+ }
+ Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
+ // Calculated separately to avoid errors
+ cutHull.AddVertex(legEnd);
+
+ // m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
+ SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
+
+ outerHull = cuttedHull;
+ }
+
+ // Deal with the hole here
+ if (hollowFactor > 0)
+ {
+ SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
+ if (holeHull != null)
+ {
+ SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
+
+ outerHull = hollowedHull;
+ }
+ }
+
+ Mesh m = new Mesh();
+
+ Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
+ Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
+ Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
+
+ m.Add(Seed1);
+ m.Add(Seed2);
+ m.Add(Seed3);
+
+ m.Add(new Triangle(Seed1, Seed2, Seed3));
+ m.Add(outerHull.getVertices());
+
+ InsertVertices(m.vertices, 3, m.triangles);
+ m.DumpRaw(baseDir, primName, "Proto first Mesh");
+
+ m.Remove(Seed1);
+ m.Remove(Seed2);
+ m.Remove(Seed3);
+ m.DumpRaw(baseDir, primName, "Proto seeds removed");
+
+ m.RemoveTrianglesOutside(outerHull);
+ m.DumpRaw(baseDir, primName, "Proto outsides removed");
+
+ foreach (Triangle t in m.triangles)
+ {
+ PhysicsVector n = t.getNormal();
+ if (n.Z < 0.0)
+ t.invertNormal();
+ }
+
+ Extruder extr = new Extruder();
+
+ extr.size = size;
+ if (taperX != 100)
+ {
+ if (taperX > 100)
+ {
+ extr.taperTopFactorX = 1.0f - ((float)taperX / 200);
+ //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
+ //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
+ }
+
+ }
+
+ if (taperY != 100)
+ {
+ if (taperY > 100)
+ {
+ extr.taperTopFactorY = 1.0f - ((float)taperY / 200);
+ //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
+ //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
+ }
+ }
+
+ if (pathShearX != 0)
+ {
+ if (pathShearX > 50)
+ {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
+ //m_log.Warn("pushX: " + extr.pushX);
+ }
+ else
+ {
+ extr.pushX = (float)pathShearX / 100;
+ //m_log.Warn("pushX: " + extr.pushX);
+ }
+ }
+
+ if (pathShearY != 0)
+ {
+ if (pathShearY > 50)
+ {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ else
+ {
+ extr.pushY = (float)pathShearY / 100;
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ }
+
+ Mesh result = extr.Extrude(m);
+ result.DumpRaw(baseDir, primName, "Z extruded");
+ return result;
+ }
+
+ private static Mesh CreatePrismMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ // Builds the z (+ and -) surfaces of a box shaped prim
+ {
+ UInt16 hollowFactor = primShape.ProfileHollow;
+ UInt16 profileBegin = primShape.ProfileBegin;
+ UInt16 profileEnd = primShape.ProfileEnd;
+ UInt16 taperX = primShape.PathScaleX;
+ UInt16 taperY = primShape.PathScaleY;
+ UInt16 pathShearX = primShape.PathShearX;
+ UInt16 pathShearY = primShape.PathShearY;
+
+ //m_log.Error("pathShear:" + primShape.PathShearX.ToString() + "," + primShape.PathShearY.ToString());
+ //m_log.Error("pathTaper:" + primShape.PathTaperX.ToString() + "," + primShape.PathTaperY.ToString());
+ //m_log.Error("ProfileBegin:" + primShape.ProfileBegin.ToString() + "," + primShape.ProfileBegin.ToString());
+ //m_log.Error("PathScale:" + primShape.PathScaleX.ToString() + "," + primShape.PathScaleY.ToString());
+
+ // Procedure: This is based on the fact that the upper (plus) and lower (minus) Z-surface
+ // of a block are basically the same
+ // They may be warped differently but the shape is identical
+ // So we only create one surface as a model and derive both plus and minus surface of the block from it
+ // This is done in a model space where the block spans from -.5 to +.5 in X and Y
+ // The mapping to Scene space is done later during the "extrusion" phase
+
+ // Base
+ Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
+ Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
+ Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
+
+
+ SimpleHull outerHull = new SimpleHull();
+ outerHull.AddVertex(MM);
+ outerHull.AddVertex(PM);
+ outerHull.AddVertex(PP);
+
+ // Deal with cuts now
+ if ((profileBegin != 0) || (profileEnd != 0))
+ {
+ double fProfileBeginAngle = profileBegin / 50000.0 * 360.0;
+ // In degree, for easier debugging and understanding
+ //fProfileBeginAngle -= (90.0 + 45.0); // for some reasons, the SL client counts from the corner -X/-Y
+ double fProfileEndAngle = 360.0 - profileEnd / 50000.0 * 360.0; // Pathend comes as complement to 1.0
+ //fProfileEndAngle -= (90.0 + 45.0);
+ if (fProfileBeginAngle < fProfileEndAngle)
+ fProfileEndAngle -= 360.0;
+
+ // Note, that we don't want to cut out a triangle, even if this is a
+ // good approximation for small cuts. Indeed we want to cut out an arc
+ // and we approximate this arc by a polygon chain
+ // Also note, that these vectors are of length 1.0 and thus their endpoints lay outside the model space
+ // So it can easily be subtracted from the outer hull
+ int iSteps = (int)(((fProfileBeginAngle - fProfileEndAngle) / 45.0) + .5);
+ // how many steps do we need with approximately 45 degree
+ double dStepWidth = (fProfileBeginAngle - fProfileEndAngle) / iSteps;
+
+ Vertex origin = new Vertex(0.0f, 0.0f, 0.0f);
+
+ // Note the sequence of vertices here. It's important to have the other rotational sense than in outerHull
+ SimpleHull cutHull = new SimpleHull();
+ cutHull.AddVertex(origin);
+ for (int i = 0; i < iSteps; i++)
+ {
+ double angle = fProfileBeginAngle - i * dStepWidth; // we count against the angle orientation!!!!
+ Vertex v = Vertex.FromAngle(angle * Math.PI / 180.0);
+ cutHull.AddVertex(v);
+ }
+ Vertex legEnd = Vertex.FromAngle(fProfileEndAngle * Math.PI / 180.0);
+ // Calculated separately to avoid errors
+ cutHull.AddVertex(legEnd);
+
+ //m_log.DebugFormat("Starting cutting of the hollow shape from the prim {1}", 0, primName);
+ SimpleHull cuttedHull = SimpleHull.SubtractHull(outerHull, cutHull);
+
+ outerHull = cuttedHull;
+ }
+
+ // Deal with the hole here
+ if (hollowFactor > 0)
+ {
+ SimpleHull holeHull = BuildHoleHull(primShape, primShape.ProfileShape, primShape.HollowShape, hollowFactor);
+ if (holeHull != null)
+ {
+ SimpleHull hollowedHull = SimpleHull.SubtractHull(outerHull, holeHull);
+
+ outerHull = hollowedHull;
+ }
+ }
+
+ Mesh m = new Mesh();
+
+ Vertex Seed1 = new Vertex(0.0f, -10.0f, 0.0f);
+ Vertex Seed2 = new Vertex(-10.0f, 10.0f, 0.0f);
+ Vertex Seed3 = new Vertex(10.0f, 10.0f, 0.0f);
+
+ m.Add(Seed1);
+ m.Add(Seed2);
+ m.Add(Seed3);
+
+ m.Add(new Triangle(Seed1, Seed2, Seed3));
+ m.Add(outerHull.getVertices());
+
+ InsertVertices(m.vertices, 3, m.triangles);
+ m.DumpRaw(baseDir, primName, "Proto first Mesh");
+
+ m.Remove(Seed1);
+ m.Remove(Seed2);
+ m.Remove(Seed3);
+ m.DumpRaw(baseDir, primName, "Proto seeds removed");
+
+ m.RemoveTrianglesOutside(outerHull);
+ m.DumpRaw(baseDir, primName, "Proto outsides removed");
+
+ foreach (Triangle t in m.triangles)
+ {
+ PhysicsVector n = t.getNormal();
+ if (n.Z < 0.0)
+ t.invertNormal();
+ }
+
+ Extruder extr = new Extruder();
+
+ extr.size = size;
+
+ if (taperX != 100)
+ {
+ if (taperX > 100)
+ {
+ extr.taperTopFactorX = 1.0f - ((float)taperX / 200);
+ //m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorX = 1.0f - ((100 - (float)taperX) / 100);
+ //m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
+ }
+ }
+
+ if (taperY != 100)
+ {
+ if (taperY > 100)
+ {
+ extr.taperTopFactorY = 1.0f - ((float)taperY / 200);
+ //m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
+ }
+ else
+ {
+ extr.taperBotFactorY = 1.0f - ((100 - (float)taperY) / 100);
+ //m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
+ }
+ }
+
+ if (pathShearX != 0)
+ {
+ if (pathShearX > 50)
+ {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushX = (((float)(256 - pathShearX) / 100) * -1f);
+ // m_log.Warn("pushX: " + extr.pushX);
+ }
+ else
+ {
+ extr.pushX = (float)pathShearX / 100;
+ // m_log.Warn("pushX: " + extr.pushX);
+ }
+ }
+
+ if (pathShearY != 0)
+ {
+ if (pathShearY > 50)
+ {
+ // Complimentary byte. Negative values wrap around the byte. Positive values go up to 50
+ extr.pushY = (((float)(256 - pathShearY) / 100) * -1f);
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ else
+ {
+ extr.pushY = (float)pathShearY / 100;
+ //m_log.Warn("pushY: " + extr.pushY);
+ }
+ }
+
+ Mesh result = extr.Extrude(m);
+ result.DumpRaw(baseDir, primName, "Z extruded");
+ return result;
+ }
+
+ public static void CalcNormals(Mesh mesh)
+ {
+ int iTriangles = mesh.triangles.Count;
+
+ mesh.normals = new float[iTriangles*3];
+
+ int i = 0;
+ foreach (Triangle t in mesh.triangles)
+ {
+ float ux, uy, uz;
+ float vx, vy, vz;
+ float wx, wy, wz;
+
+ ux = t.v1.X;
+ uy = t.v1.Y;
+ uz = t.v1.Z;
+
+ vx = t.v2.X;
+ vy = t.v2.Y;
+ vz = t.v2.Z;
+
+ wx = t.v3.X;
+ wy = t.v3.Y;
+ wz = t.v3.Z;
+
+
+ // Vectors for edges
+ float e1x, e1y, e1z;
+ float e2x, e2y, e2z;
+
+ e1x = ux - vx;
+ e1y = uy - vy;
+ e1z = uz - vz;
+
+ e2x = ux - wx;
+ e2y = uy - wy;
+ e2z = uz - wz;
+
+
+ // Cross product for normal
+ float nx, ny, nz;
+ nx = e1y*e2z - e1z*e2y;
+ ny = e1z*e2x - e1x*e2z;
+ nz = e1x*e2y - e1y*e2x;
+
+ // Length
+ float l = (float) Math.Sqrt(nx*nx + ny*ny + nz*nz);
+
+ // Normalized "normal"
+ nx /= l;
+ ny /= l;
+ nz /= l;
+
+ mesh.normals[i] = nx;
+ mesh.normals[i + 1] = ny;
+ mesh.normals[i + 2] = nz;
+
+ i += 3;
+ }
+ }
+
+ public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, PhysicsVector size)
+ {
+ Mesh mesh = null;
+
+ switch (primShape.ProfileShape)
+ {
+ case ProfileShape.Square:
+ mesh = CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ break;
+ case ProfileShape.Circle:
+ if (primShape.PathCurve == (byte)Extrusion.Straight)
+ {
+ mesh = CreateCyllinderMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ }
+ break;
+ case ProfileShape.EquilateralTriangle:
+ mesh = CreatePrismMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ break;
+
+ default:
+ mesh = CreateBoxMesh(primName, primShape, size);
+ CalcNormals(mesh);
+ //Set default mesh to cube otherwise it'll return
+ // null and crash on the 'setMesh' method in the physics plugins.
+ //mesh = null;
+ break;
+ }
+
+ return mesh;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/Meshing/SimpleHull.cs b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
index 1461376ef2..58b9a0e5a6 100644
--- a/OpenSim/Region/Physics/Meshing/SimpleHull.cs
+++ b/OpenSim/Region/Physics/Meshing/SimpleHull.cs
@@ -1,395 +1,395 @@
-/*
-* 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 OpenSim 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 OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.Meshing
-{
- // A simple hull is a set of vertices building up to simplices that border a region
- // The word simple referes to the fact, that this class assumes, that all simplices
- // do not intersect
- // Simple hulls can be added and subtracted.
- // Vertices can be checked to lie inside a hull
- // Also note, that the sequence of the vertices is important and defines if the region that
- // is defined by the hull lies inside or outside the simplex chain
- public class SimpleHull
- {
- private List vertices = new List();
- private List holeVertices = new List(); // Only used, when the hull is hollow
-
- // Adds a vertex to the end of the list
- public void AddVertex(Vertex v)
- {
- vertices.Add(v);
- }
-
- public override String ToString()
- {
- String result = "";
- foreach (Vertex v in vertices)
- {
- result += "b:" + v.ToString() + "\n";
- }
-
- return result;
- }
-
-
- public List getVertices()
- {
- List newVertices = new List();
-
- newVertices.AddRange(vertices);
- newVertices.Add(null);
- newVertices.AddRange(holeVertices);
-
- return newVertices;
- }
-
- public SimpleHull Clone()
- {
- SimpleHull result = new SimpleHull();
- foreach (Vertex v in vertices)
- {
- result.AddVertex(v.Clone());
- }
-
- foreach (Vertex v in holeVertices)
- {
- result.holeVertices.Add(v.Clone());
- }
-
- return result;
- }
-
- public bool IsPointIn(Vertex v1)
- {
- int iCounter = 0;
- List simplices = buildSimplexList();
- foreach (Simplex s in simplices)
- {
- // Send a ray along the positive X-Direction
- // Note, that this direction must correlate with the "below" interpretation
- // of handling for the special cases below
- PhysicsVector intersection = s.RayIntersect(v1, new PhysicsVector(1.0f, 0.0f, 0.0f), true);
-
- if (intersection == null)
- continue; // No intersection. Done. More tests to follow otherwise
-
- // Did we hit the end of a simplex?
- // Then this can be one of two special cases:
- // 1. we go through a border exactly at a joint
- // 2. we have just marginally touched a corner
- // 3. we can slide along a border
- // Solution: If the other vertex is "below" the ray, we don't count it
- // Thus corners pointing down are counted twice, corners pointing up are not counted
- // borders are counted once
- if (intersection.IsIdentical(s.v1, 0.001f))
- {
- if (s.v2.Y < v1.Y)
- continue;
- }
- // Do this for the other vertex two
- if (intersection.IsIdentical(s.v2, 0.001f))
- {
- if (s.v1.Y < v1.Y)
- continue;
- }
- iCounter++;
- }
-
- return iCounter%2 == 1; // Point is inside if the number of intersections is odd
- }
-
- public bool containsPointsFrom(SimpleHull otherHull)
- {
- foreach (Vertex v in otherHull.vertices)
- {
- if (IsPointIn(v))
- return true;
- }
-
- return false;
- }
-
-
- private List buildSimplexList()
- {
- List result = new List();
-
- // Not asserted but assumed: at least three vertices
- for (int i = 0; i < vertices.Count - 1; i++)
- {
- Simplex s = new Simplex(vertices[i], vertices[i + 1]);
- result.Add(s);
- }
- Simplex s1 = new Simplex(vertices[vertices.Count - 1], vertices[0]);
- result.Add(s1);
-
- if (holeVertices.Count == 0)
- return result;
-
- // Same here. At least three vertices in hole assumed
- for (int i = 0; i < holeVertices.Count - 1; i++)
- {
- Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
- result.Add(s);
- }
-
- s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
- result.Add(s1);
- return result;
- }
-
- private bool InsertVertex(Vertex v, int iAfter)
- {
- vertices.Insert(iAfter + 1, v);
- return true;
- }
-
- private Vertex getNextVertex(Vertex currentVertex)
- {
- int iCurrentIndex;
- iCurrentIndex = vertices.IndexOf(currentVertex);
-
- // Error handling for iCurrentIndex==-1 should go here (and probably never will)
-
- iCurrentIndex++;
- if (iCurrentIndex == vertices.Count)
- iCurrentIndex = 0;
-
- return vertices[iCurrentIndex];
- }
-
- public Vertex FindVertex(Vertex vBase, float tolerance)
- {
- foreach (Vertex v in vertices)
- {
- if (v.IsIdentical(vBase, tolerance))
- return v;
- }
-
- return null;
- }
-
- public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
- {
- Vertex bestIntersection = null;
- float distToV1 = Single.PositiveInfinity;
- Simplex bestIntersectingSimplex = null;
-
- List simple = buildSimplexList();
- foreach (Simplex sTest in simple)
- {
- PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
-
- Vertex vTemp = null;
- if (vvTemp != null)
- vTemp = new Vertex(vvTemp);
-
- if (vTemp != null)
- {
- PhysicsVector diff = (s.v1 - vTemp);
- float distTemp = diff.length();
-
- if (bestIntersection == null || distTemp < distToV1)
- {
- bestIntersection = vTemp;
- distToV1 = distTemp;
- bestIntersectingSimplex = sTest;
- }
- } // end if vTemp
- } // end foreach
-
- Intersection = bestIntersection;
- if (bestIntersectingSimplex != null)
- nextVertex = bestIntersectingSimplex.v2;
- else
- nextVertex = null;
- }
-
-
- public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
- {
- SimpleHull baseHullClone = baseHull.Clone();
- SimpleHull otherHullClone = otherHull.Clone();
- bool intersects = false;
-
- MainLog.Instance.Debug("State before intersection detection");
- MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
- MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
-
- {
- int iBase, iOther;
-
- // Insert into baseHull
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
-
- for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
- {
- int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
- Simplex sOther =
- new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
-
- PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
- if (intersect != null)
- {
- Vertex vIntersect = new Vertex(intersect);
- baseHullClone.vertices.Insert(iBase + 1, vIntersect);
- sBase.v2 = vIntersect;
- intersects = true;
- }
- }
- }
- }
-
- MainLog.Instance.Debug("State after intersection detection for the base hull");
- MainLog.Instance.Debug("The baseHull is:\n{1}", 0, baseHullClone.ToString());
-
- {
- int iOther, iBase;
-
- // Insert into otherHull
- for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
- {
- int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
- Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
-
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
-
- PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
- if (intersect != null)
- {
- Vertex vIntersect = new Vertex(intersect);
- otherHullClone.vertices.Insert(iOther + 1, vIntersect);
- sOther.v2 = vIntersect;
- intersects = true;
- }
- }
- }
- }
-
- MainLog.Instance.Debug("State after intersection detection for the base hull");
- MainLog.Instance.Debug("The otherHull is:\n{1}", 0, otherHullClone.ToString());
-
-
- bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
- if (!intersects && otherIsInBase)
- {
- // We have a hole here
- baseHullClone.holeVertices = otherHullClone.vertices;
- return baseHullClone;
- }
-
-
- SimpleHull result = new SimpleHull();
-
- // Find a good starting Simplex from baseHull
- // A good starting simplex is one that is outside otherHull
- // Such a simplex must exist, otherwise the result will be empty
- Vertex baseStartVertex = null;
- {
- int iBase;
- for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
- {
- int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
- Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext])/2.0f);
- bool isOutside = !otherHullClone.IsPointIn(center);
- if (isOutside)
- {
- baseStartVertex = baseHullClone.vertices[iBaseNext];
- break;
- }
- }
- }
-
-
- if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
- // In otherwords, subtractHull completely embraces baseHull
- {
- return result;
- }
-
- // The simplex that *starts* with baseStartVertex is outside the cutting hull,
- // so we can start our walk with the next vertex without loosing a branch
- Vertex V1 = baseStartVertex;
- bool onBase = true;
-
- // And here is how we do the magic :-)
- // Start on the base hull.
- // Walk the vertices in the positive direction
- // For each vertex check, whether it is a vertex shared with the other hull
- // if this is the case, switch over to walking the other vertex list.
- // Note: The other hull *must* go backwards to our starting point (via several orther vertices)
- // Thus it is important that the cutting hull has the inverse directional sense than the
- // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
-
- bool done = false;
- while (!done)
- {
- result.AddVertex(V1);
- Vertex nextVertex = null;
- if (onBase)
- {
- nextVertex = otherHullClone.FindVertex(V1, 0.001f);
- }
- else
- {
- nextVertex = baseHullClone.FindVertex(V1, 0.001f);
- }
-
- if (nextVertex != null) // A node that represents an intersection
- {
- V1 = nextVertex; // Needed to find the next vertex on the other hull
- onBase = !onBase;
- }
-
- if (onBase)
- V1 = baseHullClone.getNextVertex(V1);
- else
- V1 = otherHullClone.getNextVertex(V1);
-
- if (V1 == baseStartVertex)
- done = true;
- }
-
- MainLog.Instance.Debug("The resulting Hull is:\n{1}", 0, result.ToString());
-
- return result;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.Meshing
+{
+ // A simple hull is a set of vertices building up to simplices that border a region
+ // The word simple referes to the fact, that this class assumes, that all simplices
+ // do not intersect
+ // Simple hulls can be added and subtracted.
+ // Vertices can be checked to lie inside a hull
+ // Also note, that the sequence of the vertices is important and defines if the region that
+ // is defined by the hull lies inside or outside the simplex chain
+ public class SimpleHull
+ {
+ //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ private List vertices = new List();
+ private List holeVertices = new List(); // Only used, when the hull is hollow
+
+ // Adds a vertex to the end of the list
+ public void AddVertex(Vertex v)
+ {
+ vertices.Add(v);
+ }
+
+ public override String ToString()
+ {
+ String result = String.Empty;
+ foreach (Vertex v in vertices)
+ {
+ result += "b:" + v.ToString() + "\n";
+ }
+
+ return result;
+ }
+
+
+ public List getVertices()
+ {
+ List newVertices = new List();
+
+ newVertices.AddRange(vertices);
+ newVertices.Add(null);
+ newVertices.AddRange(holeVertices);
+
+ return newVertices;
+ }
+
+ public SimpleHull Clone()
+ {
+ SimpleHull result = new SimpleHull();
+ foreach (Vertex v in vertices)
+ {
+ result.AddVertex(v.Clone());
+ }
+
+ foreach (Vertex v in holeVertices)
+ {
+ result.holeVertices.Add(v.Clone());
+ }
+
+ return result;
+ }
+
+ public bool IsPointIn(Vertex v1)
+ {
+ int iCounter = 0;
+ List simplices = buildSimplexList();
+ foreach (Simplex s in simplices)
+ {
+ // Send a ray along the positive X-Direction
+ // Note, that this direction must correlate with the "below" interpretation
+ // of handling for the special cases below
+ PhysicsVector intersection = s.RayIntersect(v1, new PhysicsVector(1.0f, 0.0f, 0.0f), true);
+
+ if (intersection == null)
+ continue; // No intersection. Done. More tests to follow otherwise
+
+ // Did we hit the end of a simplex?
+ // Then this can be one of two special cases:
+ // 1. we go through a border exactly at a joint
+ // 2. we have just marginally touched a corner
+ // 3. we can slide along a border
+ // Solution: If the other vertex is "below" the ray, we don't count it
+ // Thus corners pointing down are counted twice, corners pointing up are not counted
+ // borders are counted once
+ if (intersection.IsIdentical(s.v1, 0.001f))
+ {
+ if (s.v2.Y < v1.Y)
+ continue;
+ }
+ // Do this for the other vertex two
+ if (intersection.IsIdentical(s.v2, 0.001f))
+ {
+ if (s.v1.Y < v1.Y)
+ continue;
+ }
+ iCounter++;
+ }
+
+ return iCounter%2 == 1; // Point is inside if the number of intersections is odd
+ }
+
+ public bool containsPointsFrom(SimpleHull otherHull)
+ {
+ foreach (Vertex v in otherHull.vertices)
+ {
+ if (IsPointIn(v))
+ return true;
+ }
+
+ return false;
+ }
+
+
+ private List buildSimplexList()
+ {
+ List result = new List();
+
+ // Not asserted but assumed: at least three vertices
+ for (int i = 0; i < vertices.Count - 1; i++)
+ {
+ Simplex s = new Simplex(vertices[i], vertices[i + 1]);
+ result.Add(s);
+ }
+ Simplex s1 = new Simplex(vertices[vertices.Count - 1], vertices[0]);
+ result.Add(s1);
+
+ if (holeVertices.Count == 0)
+ return result;
+
+ // Same here. At least three vertices in hole assumed
+ for (int i = 0; i < holeVertices.Count - 1; i++)
+ {
+ Simplex s = new Simplex(holeVertices[i], holeVertices[i + 1]);
+ result.Add(s);
+ }
+
+ s1 = new Simplex(holeVertices[holeVertices.Count - 1], holeVertices[0]);
+ result.Add(s1);
+ return result;
+ }
+
+ private bool InsertVertex(Vertex v, int iAfter)
+ {
+ vertices.Insert(iAfter + 1, v);
+ return true;
+ }
+
+ private Vertex getNextVertex(Vertex currentVertex)
+ {
+ int iCurrentIndex;
+ iCurrentIndex = vertices.IndexOf(currentVertex);
+
+ // Error handling for iCurrentIndex==-1 should go here (and probably never will)
+
+ iCurrentIndex++;
+ if (iCurrentIndex == vertices.Count)
+ iCurrentIndex = 0;
+
+ return vertices[iCurrentIndex];
+ }
+
+ public Vertex FindVertex(Vertex vBase, float tolerance)
+ {
+ foreach (Vertex v in vertices)
+ {
+ if (v.IsIdentical(vBase, tolerance))
+ return v;
+ }
+
+ return null;
+ }
+
+ public void FindIntersection(Simplex s, ref Vertex Intersection, ref Vertex nextVertex)
+ {
+ Vertex bestIntersection = null;
+ float distToV1 = Single.PositiveInfinity;
+ Simplex bestIntersectingSimplex = null;
+
+ List simple = buildSimplexList();
+ foreach (Simplex sTest in simple)
+ {
+ PhysicsVector vvTemp = Simplex.Intersect(sTest, s, -.001f, -.001f, 0.999f, .999f);
+
+ Vertex vTemp = null;
+ if (vvTemp != null)
+ vTemp = new Vertex(vvTemp);
+
+ if (vTemp != null)
+ {
+ PhysicsVector diff = (s.v1 - vTemp);
+ float distTemp = diff.length();
+
+ if (bestIntersection == null || distTemp < distToV1)
+ {
+ bestIntersection = vTemp;
+ distToV1 = distTemp;
+ bestIntersectingSimplex = sTest;
+ }
+ }
+ }
+
+ Intersection = bestIntersection;
+ if (bestIntersectingSimplex != null)
+ nextVertex = bestIntersectingSimplex.v2;
+ else
+ nextVertex = null;
+ }
+
+
+ public static SimpleHull SubtractHull(SimpleHull baseHull, SimpleHull otherHull)
+ {
+ SimpleHull baseHullClone = baseHull.Clone();
+ SimpleHull otherHullClone = otherHull.Clone();
+ bool intersects = false;
+
+ //m_log.Debug("State before intersection detection");
+ //m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
+ //m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
+
+ {
+ int iBase, iOther;
+
+ // Insert into baseHull
+ for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
+ {
+ int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
+ Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
+
+ for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
+ {
+ int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
+ Simplex sOther =
+ new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
+
+ PhysicsVector intersect = Simplex.Intersect(sBase, sOther, 0.001f, -.001f, 0.999f, 1.001f);
+ if (intersect != null)
+ {
+ Vertex vIntersect = new Vertex(intersect);
+ baseHullClone.vertices.Insert(iBase + 1, vIntersect);
+ sBase.v2 = vIntersect;
+ intersects = true;
+ }
+ }
+ }
+ }
+
+ //m_log.Debug("State after intersection detection for the base hull");
+ //m_log.DebugFormat("The baseHull is:\n{1}", 0, baseHullClone.ToString());
+
+ {
+ int iOther, iBase;
+
+ // Insert into otherHull
+ for (iOther = 0; iOther < otherHullClone.vertices.Count; iOther++)
+ {
+ int iOtherNext = (iOther + 1)%otherHullClone.vertices.Count;
+ Simplex sOther = new Simplex(otherHullClone.vertices[iOther], otherHullClone.vertices[iOtherNext]);
+
+ for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
+ {
+ int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
+ Simplex sBase = new Simplex(baseHullClone.vertices[iBase], baseHullClone.vertices[iBaseNext]);
+
+ PhysicsVector intersect = Simplex.Intersect(sBase, sOther, -.001f, 0.001f, 1.001f, 0.999f);
+ if (intersect != null)
+ {
+ Vertex vIntersect = new Vertex(intersect);
+ otherHullClone.vertices.Insert(iOther + 1, vIntersect);
+ sOther.v2 = vIntersect;
+ intersects = true;
+ }
+ }
+ }
+ }
+
+ //m_log.Debug("State after intersection detection for the base hull");
+ //m_log.DebugFormat("The otherHull is:\n{1}", 0, otherHullClone.ToString());
+
+ bool otherIsInBase = baseHullClone.containsPointsFrom(otherHullClone);
+ if (!intersects && otherIsInBase)
+ {
+ // We have a hole here
+ baseHullClone.holeVertices = otherHullClone.vertices;
+ return baseHullClone;
+ }
+
+ SimpleHull result = new SimpleHull();
+
+ // Find a good starting Simplex from baseHull
+ // A good starting simplex is one that is outside otherHull
+ // Such a simplex must exist, otherwise the result will be empty
+ Vertex baseStartVertex = null;
+ {
+ int iBase;
+ for (iBase = 0; iBase < baseHullClone.vertices.Count; iBase++)
+ {
+ int iBaseNext = (iBase + 1)%baseHullClone.vertices.Count;
+ Vertex center = new Vertex((baseHullClone.vertices[iBase] + baseHullClone.vertices[iBaseNext])/2.0f);
+ bool isOutside = !otherHullClone.IsPointIn(center);
+ if (isOutside)
+ {
+ baseStartVertex = baseHullClone.vertices[iBaseNext];
+ break;
+ }
+ }
+ }
+
+
+ if (baseStartVertex == null) // i.e. no simplex fulfilled the "outside" condition.
+ // In otherwords, subtractHull completely embraces baseHull
+ {
+ return result;
+ }
+
+ // The simplex that *starts* with baseStartVertex is outside the cutting hull,
+ // so we can start our walk with the next vertex without loosing a branch
+ Vertex V1 = baseStartVertex;
+ bool onBase = true;
+
+ // And here is how we do the magic :-)
+ // Start on the base hull.
+ // Walk the vertices in the positive direction
+ // For each vertex check, whether it is a vertex shared with the other hull
+ // if this is the case, switch over to walking the other vertex list.
+ // Note: The other hull *must* go backwards to our starting point (via several orther vertices)
+ // Thus it is important that the cutting hull has the inverse directional sense than the
+ // base hull!!!!!!!!! (means if base goes CW around it's center cutting hull must go CCW)
+
+ bool done = false;
+ while (!done)
+ {
+ result.AddVertex(V1);
+ Vertex nextVertex = null;
+ if (onBase)
+ {
+ nextVertex = otherHullClone.FindVertex(V1, 0.001f);
+ }
+ else
+ {
+ nextVertex = baseHullClone.FindVertex(V1, 0.001f);
+ }
+
+ if (nextVertex != null) // A node that represents an intersection
+ {
+ V1 = nextVertex; // Needed to find the next vertex on the other hull
+ onBase = !onBase;
+ }
+
+ if (onBase)
+ V1 = baseHullClone.getNextVertex(V1);
+ else
+ V1 = otherHullClone.getNextVertex(V1);
+
+ if (V1 == baseStartVertex)
+ done = true;
+ }
+
+ //m_log.DebugFormat("The resulting Hull is:\n{1}", 0, result.ToString());
+
+ return result;
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 3ad226c86b..433f3c152f 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1,609 +1,871 @@
-/*
-* 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 OpenSim 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 Axiom.Math;
-using Ode.NET;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-using System.Runtime.InteropServices; // rex
-
-namespace OpenSim.Region.Physics.OdePlugin
-{
- public class OdeCharacter : PhysicsActor
- {
- private PhysicsVector _position;
- private d.Vector3 _zeroPosition;
- private d.Matrix3 m_StandUpRotation;
- private bool _zeroFlag = false;
- private bool m_lastUpdateSent = false;
- private PhysicsVector _velocity;
- private PhysicsVector _target_velocity;
- private PhysicsVector _acceleration;
- private PhysicsVector m_rotationalVelocity;
- private float m_density = 50f;
- private bool m_pidControllerActive = true;
- private static float PID_D = 3020.0f;
- private static float PID_P = 7000.0f;
- private static float POSTURE_SERVO = 10000.0f;
- public static float CAPSULE_RADIUS = 0.5f;
- public float CAPSULE_LENGTH = 0.79f;
- private bool flying = false;
- private bool m_iscolliding = false;
- private bool m_iscollidingGround = false;
- private bool m_wascolliding = false;
- private bool m_wascollidingGround = false;
- private bool m_iscollidingObj = false;
- private bool m_wascollidingObj = false;
- private bool m_alwaysRun = false;
- private bool m_hackSentFall = false;
- private bool m_hackSentFly = false;
- private string m_name = "";
-
- private bool[] m_colliderarr = new bool[11];
- private bool[] m_colliderGroundarr = new bool[11];
-
-
- private bool jumping = false;
- //private float gravityAccel;
- public IntPtr Body;
- private GCHandle gchBody; // rex
-
- private OdeScene _parent_scene;
- public IntPtr Shell;
- private GCHandle gchShell; // rex
-
- public IntPtr Amotor;
- public d.Mass ShellMass;
- public bool collidelock = false;
-
- public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, uint localID) // rex, localID added
- {
- m_localID = localID; // rex
- _velocity = new PhysicsVector();
- _target_velocity = new PhysicsVector();
- _position = pos;
- _acceleration = new PhysicsVector();
- _parent_scene = parent_scene;
-
- m_StandUpRotation =
- new d.Matrix3(0.8184158f, -0.5744568f, -0.0139677f, 0.5744615f, 0.8185215f, -0.004074608f, 0.01377355f,
- -0.004689182f, 0.9998941f);
-
- for (int i = 0; i < 11; i++)
- {
- m_colliderarr[i] = false;
- }
-
- lock (OdeScene.OdeLock)
- {
- int dAMotorEuler = 1;
- Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
- gchShell = GCHandle.Alloc(Shell, GCHandleType.Pinned); // rex
-
- d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
- Body = d.BodyCreate(parent_scene.world);
- gchBody = GCHandle.Alloc(Body, GCHandleType.Pinned); // rex
-
- d.BodySetMass(Body, ref ShellMass);
- d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
- d.GeomSetBody(Shell, Body);
-
-
- d.BodySetRotation(Body, ref m_StandUpRotation);
-
-
- //Amotor = d.JointCreateAMotor(parent_scene.world, IntPtr.Zero);
- //d.JointAttach(Amotor, Body, IntPtr.Zero);
- //d.JointSetAMotorMode(Amotor, dAMotorEuler);
- //d.JointSetAMotorNumAxes(Amotor, 3);
- //d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
- //d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
- ///d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
- //d.JointSetAMotorAngle(Amotor, 0, 0);
- //d.JointSetAMotorAngle(Amotor, 1, 0);
- //d.JointSetAMotorAngle(Amotor, 2, 0);
- //d.JointSetAMotorParam(Amotor, 0, -0);
- //d.JointSetAMotorParam(Amotor, 0x200, -0);
- //d.JointSetAMotorParam(Amotor, 0x100, -0);
- // d.JointSetAMotorParam(Amotor, 0, 0);
- // d.JointSetAMotorParam(Amotor, 3, 0);
- // d.JointSetAMotorParam(Amotor, 2, 0);
- }
- m_name = avName;
- parent_scene.geom_name_map[Shell] = avName;
- parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Agent; }
- set { return; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return m_alwaysRun; }
- set { m_alwaysRun = value; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool Flying
- {
- get { return flying; }
- set { flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return m_iscolliding; }
- set
- {
- int i;
- int truecount = 0;
- int falsecount = 0;
-
- if (m_colliderarr.Length >= 10)
- {
- for (i = 0; i < 10; i++)
- {
- m_colliderarr[i] = m_colliderarr[i + 1];
- }
- }
- m_colliderarr[10] = value;
-
- for (i = 0; i < 11; i++)
- {
- if (m_colliderarr[i])
- {
- truecount++;
- }
- else
- {
- falsecount++;
- }
- }
-
- // Equal truecounts and false counts means we're colliding with something.
-
- if (falsecount > 1.2*truecount)
- {
- m_iscolliding = false;
- }
- else
- {
- m_iscolliding = true;
- }
- if (m_wascolliding != m_iscolliding)
- {
- //base.SendCollisionUpdate(new CollisionEventUpdate());
- }
- m_wascolliding = m_iscolliding;
- }
- }
-
- public override bool CollidingGround
- {
- get { return m_iscollidingGround; }
- set
- {
- int i;
- int truecount = 0;
- int falsecount = 0;
-
- if (m_colliderGroundarr.Length >= 10)
- {
- for (i = 0; i < 10; i++)
- {
- m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
- }
- }
- m_colliderGroundarr[10] = value;
-
- for (i = 0; i < 11; i++)
- {
- if (m_colliderGroundarr[i])
- {
- truecount++;
- }
- else
- {
- falsecount++;
- }
- }
-
- // Equal truecounts and false counts means we're colliding with something.
-
- if (falsecount > 1.2*truecount)
- {
- m_iscollidingGround = false;
- }
- else
- {
- m_iscollidingGround = true;
- }
- if (m_wascollidingGround != m_iscollidingGround)
- {
- //base.SendCollisionUpdate(new CollisionEventUpdate());
- }
- m_wascollidingGround = m_iscollidingGround;
- }
- }
-
- public override bool CollidingObj
- {
- get { return m_iscollidingObj; }
- set
- {
- m_iscollidingObj = value;
- if (value)
- m_pidControllerActive = false;
- else
- m_pidControllerActive = true;
- }
- }
-
- public void SetPidStatus(bool status)
- {
- m_pidControllerActive = status;
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set
- {
- lock (OdeScene.OdeLock)
- {
- d.BodySetPosition(Body, value.X, value.Y, value.Z);
- _position = value;
- }
- }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); }
- set
- {
- m_pidControllerActive = true;
- lock (OdeScene.OdeLock)
- {
- PhysicsVector SetSize = value;
- float prevCapsule = CAPSULE_LENGTH;
- float capsuleradius = CAPSULE_RADIUS;
- capsuleradius = 0.2f;
-
- CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z*0.43f))); // subtract 43% of the size
- d.BodyDestroy(Body);
- gchBody.Free(); // rex
- d.GeomDestroy(Shell);
- gchShell.Free(); // rex
- //MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH));
- Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH);
- gchShell = GCHandle.Alloc(Shell, GCHandleType.Pinned); // rex
- d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
- Body = d.BodyCreate(_parent_scene.world);
- gchBody = GCHandle.Alloc(Body, GCHandleType.Pinned); // rex
- d.BodySetMass(Body, ref ShellMass);
- d.BodySetPosition(Body, _position.X, _position.Y,
- _position.Z + Math.Abs(CAPSULE_LENGTH - prevCapsule));
- d.GeomSetBody(Shell, Body);
- }
- _parent_scene.geom_name_map[Shell] = m_name;
- _parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
- }
- }
-
- public override float Mass
- {
- get
- {
- float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH);
- return m_density*AVvolume;
- }
- }
-
- public override PhysicsVector Force
- {
- get { return new PhysicsVector(_target_velocity.X, _target_velocity.Y, _target_velocity.Z); }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set
- {
- m_pidControllerActive = true;
- _target_velocity = value;
- }
- }
-
- public override bool Kinematic
- {
- get { return false; }
- set { }
- }
-
- public override Quaternion Orientation
- {
- get { return Quaternion.Identity; }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- m_pidControllerActive = true;
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- m_pidControllerActive = true;
- _target_velocity.X += force.X;
- _target_velocity.Y += force.Y;
- _target_velocity.Z += force.Z;
-
- //m_lastUpdateSent = false;
- }
-
- public void doForce(PhysicsVector force)
- {
- if (!collidelock)
- {
- d.BodyAddForce(Body, force.X, force.Y, force.Z);
-
- // ok -- let's stand up straight!
- //d.Matrix3 StandUpRotationalMatrix = new d.Matrix3(0.8184158f, -0.5744568f, -0.0139677f, 0.5744615f, 0.8185215f, -0.004074608f, 0.01377355f, -0.004689182f, 0.9998941f);
- //d.BodySetRotation(Body, ref StandUpRotationalMatrix);
- //d.BodySetRotation(Body, ref m_StandUpRotation);
- // The above matrix was generated with the amazing standup routine below by danX0r *cheer*
- d.Vector3 feet;
- d.Vector3 head;
- d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet);
- d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head);
- float posture = head.Z - feet.Z;
-
- // restoring force proportional to lack of posture:
- float servo = (2.5f - posture) * POSTURE_SERVO;
- d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
- d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
-
- //m_lastUpdateSent = false;
- }
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
- public void Move(float timeStep)
- {
- // no lock; for now it's only called from within Simulate()
- if (m_pidControllerActive == false)
- {
- _zeroPosition = d.BodyGetPosition(Body);
- }
- //PidStatus = true;
-
- PhysicsVector vec = new PhysicsVector();
- d.Vector3 vel = d.BodyGetLinearVel(Body);
- float movementdivisor = 1f;
-
- if (!m_alwaysRun)
- {
- movementdivisor = 1.3f;
- }
- else
- {
- movementdivisor = 0.8f;
- }
-
- // if velocity is zero, use position control; otherwise, velocity control
- if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
- {
- // keep track of where we stopped. No more slippin' & slidin'
- if (!_zeroFlag)
- {
- _zeroFlag = true;
- _zeroPosition = d.BodyGetPosition(Body);
- }
- if (m_pidControllerActive)
- {
- d.Vector3 pos = d.BodyGetPosition(Body);
- vec.X = (_target_velocity.X - vel.X)*PID_D + (_zeroPosition.X - pos.X)*PID_P;
- vec.Y = (_target_velocity.Y - vel.Y)*PID_D + (_zeroPosition.Y - pos.Y)*PID_P;
- if (flying)
- {
- vec.Z = (_target_velocity.Z - vel.Z)*(PID_D + 5100) + (_zeroPosition.Z - pos.Z)*PID_P;
- }
- }
- //PidStatus = true;
- }
- else
- {
- m_pidControllerActive = true;
- _zeroFlag = false;
- if (m_iscolliding || flying)
- {
- vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*PID_D;
- vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*PID_D;
- }
- if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
- {
- d.Vector3 pos = d.BodyGetPosition(Body);
- vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P;
- if (_target_velocity.X > 0)
- {
- vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
- }
- if (_target_velocity.Y > 0)
- {
- vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
- }
- }
- else if (!m_iscolliding && !flying)
- {
- d.Vector3 pos = d.BodyGetPosition(Body);
- if (_target_velocity.X > 0)
- {
- vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
- }
- if (_target_velocity.Y > 0)
- {
- vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
- }
- }
-
-
- if (flying)
- {
- vec.Z = (_target_velocity.Z - vel.Z)*(PID_D + 5100);
- }
- }
- if (flying)
- {
- vec.Z += 10.0f;
- }
-
-
- doForce(vec);
- }
-
- public void UpdatePositionAndVelocity()
- {
- // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
- d.Vector3 vec = d.BodyGetPosition(Body);
-
- // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
- if (vec.X < 0.0f) vec.X = 0.0f;
- if (vec.Y < 0.0f) vec.Y = 0.0f;
- if (vec.X > 255.95f) vec.X = 255.95f;
- if (vec.Y > 255.95f) vec.Y = 255.95f;
-
- _position.X = vec.X;
- _position.Y = vec.Y;
- _position.Z = vec.Z;
-
- if (_zeroFlag)
- {
- _velocity.X = 0.0f;
- _velocity.Y = 0.0f;
- _velocity.Z = 0.0f;
- if (!m_lastUpdateSent)
- {
- m_lastUpdateSent = true;
- base.RequestPhysicsterseUpdate();
- //string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
- //int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
- //if (primScenAvatarIn == "0")
- //{
- //MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in space with no prim. Arr:':" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
- //}
- //else
- //{
- // MainLog.Instance.Verbose("Physics", "Avatar " + m_name + " in Prim space':" + primScenAvatarIn + ". Arr:" + arrayitem[0].ToString() + "," + arrayitem[1].ToString());
- //}
- }
- }
- else
- {
- m_lastUpdateSent = false;
- vec = d.BodyGetLinearVel(Body);
- _velocity.X = (vec.X);
- _velocity.Y = (vec.Y);
-
- _velocity.Z = (vec.Z);
- if (_velocity.Z < -6 && !m_hackSentFall)
- {
- m_hackSentFall = true;
- //base.SendCollisionUpdate(new CollisionEventUpdate());
- m_pidControllerActive = false;
- }
- else if (flying && !m_hackSentFly)
- {
- //m_hackSentFly = true;
- //base.SendCollisionUpdate(new CollisionEventUpdate());
- }
- else
- {
- m_hackSentFly = false;
- m_hackSentFall = false;
- }
- }
- }
-
- public void Destroy()
- {
- lock (OdeScene.OdeLock)
- {
- // d.JointDestroy(Amotor);
- d.GeomDestroy(Shell);
- _parent_scene.geom_name_map.Remove(Shell);
- d.BodyDestroy(Body);
- }
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 Axiom.Math;
+using Ode.NET;
+using OpenSim.Framework;
+using OpenSim.Region.Physics.Manager;
+using System.Runtime.InteropServices; // rex
+
+namespace OpenSim.Region.Physics.OdePlugin
+{
+ ///
+ /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
+ ///
+
+ public enum dParam : int
+ {
+ LowStop = 0,
+ HiStop = 1,
+ Vel = 2,
+ FMax = 3,
+ FudgeFactor = 4,
+ Bounce = 5,
+ CFM = 6,
+ ERP = 7,
+ StopCFM = 8,
+ LoStop2 = 256,
+ HiStop2 = 257,
+ LoStop3 = 512,
+ HiStop3 = 513
+ }
+ public class OdeCharacter : PhysicsActor
+ {
+ //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ private PhysicsVector _position;
+ private d.Vector3 _zeroPosition;
+ private d.Matrix3 m_StandUpRotation;
+ private bool _zeroFlag = false;
+ private bool m_lastUpdateSent = false;
+ private PhysicsVector _velocity;
+ private PhysicsVector _target_velocity;
+ private PhysicsVector _acceleration;
+ private PhysicsVector m_rotationalVelocity;
+ private float m_mass = 80f;
+ private float m_density = 60f;
+ private bool m_pidControllerActive = true;
+ private float PID_D = 800.0f;
+ private float PID_P = 900.0f;
+ private static float POSTURE_SERVO = 10000.0f;
+ public static float CAPSULE_RADIUS = 0.37f;
+ public float CAPSULE_LENGTH = 2.140599f;
+ private float m_tensor = 3800000f;
+ private bool flying = false;
+ private bool m_iscolliding = false;
+ private bool m_iscollidingGround = false;
+ private bool m_wascolliding = false;
+ private bool m_wascollidingGround = false;
+ private bool m_iscollidingObj = false;
+ private bool m_wascollidingObj = false;
+ private bool m_alwaysRun = false;
+ private bool m_hackSentFall = false;
+ private bool m_hackSentFly = false;
+ private bool m_foundDebian = false;
+ private CollisionLocker ode;
+
+ private string m_name = String.Empty;
+
+ private bool[] m_colliderarr = new bool[11];
+ private bool[] m_colliderGroundarr = new bool[11];
+
+
+ private bool jumping = false;
+ //private float gravityAccel;
+ public IntPtr Body;
+ private GCHandle gchBody; // rex
+
+ private OdeScene _parent_scene;
+ public IntPtr Shell;
+ private GCHandle gchShell; // rex
+
+ public IntPtr Amotor;
+ public d.Mass ShellMass;
+ public bool collidelock = false;
+
+ public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode, PhysicsVector size)
+ {
+ ode = dode;
+ _velocity = new PhysicsVector();
+ _target_velocity = new PhysicsVector();
+ _position = pos;
+ _acceleration = new PhysicsVector();
+ _parent_scene = parent_scene;
+
+ if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+ {
+ m_foundDebian = true;
+ m_tensor = 2000000f;
+ }
+ else
+ {
+ m_tensor = 1300000f;
+ }
+
+ m_StandUpRotation =
+ new d.Matrix3(0.5f, 0.7071068f, 0.5f, -0.7071068f, 0f, 0.7071068f, 0.5f, -0.7071068f,
+ 0.5f);
+
+ for (int i = 0; i < 11; i++)
+ {
+ m_colliderarr[i] = false;
+ }
+ CAPSULE_LENGTH = (size.Z - ((size.Z * 0.52f)));
+
+ lock (OdeScene.OdeLock)
+ {
+ AvatarGeomAndBodyCreation(pos.X, pos.Y, pos.Z, m_tensor);
+ int dAMotorEuler = 1;
+ Shell = d.CreateCapsule(parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
+ gchShell = GCHandle.Alloc(Shell, GCHandleType.Pinned); // rex
+
+ d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
+ Body = d.BodyCreate(parent_scene.world);
+ gchBody = GCHandle.Alloc(Body, GCHandleType.Pinned); // rex
+
+ d.BodySetMass(Body, ref ShellMass);
+ d.BodySetPosition(Body, pos.X, pos.Y, pos.Z);
+ d.GeomSetBody(Shell, Body);
+
+
+ d.BodySetRotation(Body, ref m_StandUpRotation);
+
+
+ //Amotor = d.JointCreateAMotor(parent_scene.world, IntPtr.Zero);
+ //d.JointAttach(Amotor, Body, IntPtr.Zero);
+ //d.JointSetAMotorMode(Amotor, dAMotorEuler);
+ //d.JointSetAMotorNumAxes(Amotor, 3);
+ //d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
+ //d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
+ ///d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
+ //d.JointSetAMotorAngle(Amotor, 0, 0);
+ //d.JointSetAMotorAngle(Amotor, 1, 0);
+ //d.JointSetAMotorAngle(Amotor, 2, 0);
+ //d.JointSetAMotorParam(Amotor, 0, -0);
+ //d.JointSetAMotorParam(Amotor, 0x200, -0);
+ //d.JointSetAMotorParam(Amotor, 0x100, -0);
+ // d.JointSetAMotorParam(Amotor, 0, 0);
+ // d.JointSetAMotorParam(Amotor, 3, 0);
+ // d.JointSetAMotorParam(Amotor, 2, 0);
+ }
+ m_name = avName;
+ parent_scene.geom_name_map[Shell] = avName;
+ parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Agent; }
+ set { return; }
+ }
+
+ ///
+ /// If this is set, the avatar will move faster
+ ///
+ public override bool SetAlwaysRun
+ {
+ get { return m_alwaysRun; }
+ set { m_alwaysRun = value; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Flying
+ {
+ get { return flying; }
+ set { flying = value; }
+ }
+
+ ///
+ /// Returns if the avatar is colliding in general.
+ /// This includes the ground and objects and avatar.
+ ///
+ public override bool IsColliding
+ {
+ get { return m_iscolliding; }
+ set
+ {
+ int i;
+ int truecount = 0;
+ int falsecount = 0;
+
+ if (m_colliderarr.Length >= 10)
+ {
+ for (i = 0; i < 10; i++)
+ {
+ m_colliderarr[i] = m_colliderarr[i + 1];
+ }
+ }
+ m_colliderarr[10] = value;
+
+ for (i = 0; i < 11; i++)
+ {
+ if (m_colliderarr[i])
+ {
+ truecount++;
+ }
+ else
+ {
+ falsecount++;
+ }
+ }
+
+ // Equal truecounts and false counts means we're colliding with something.
+
+ if (falsecount > 1.2*truecount)
+ {
+ m_iscolliding = false;
+ }
+ else
+ {
+ m_iscolliding = true;
+ }
+ if (m_wascolliding != m_iscolliding)
+ {
+ //base.SendCollisionUpdate(new CollisionEventUpdate());
+ }
+ m_wascolliding = m_iscolliding;
+ }
+ }
+
+ ///
+ /// Returns if an avatar is colliding with the ground
+ ///
+ public override bool CollidingGround
+ {
+ get { return m_iscollidingGround; }
+ set
+ {
+ // Collisions against the ground are not really reliable
+ // So, to get a consistant value we have to average the current result over time
+ // Currently we use 1 second = 10 calls to this.
+ int i;
+ int truecount = 0;
+ int falsecount = 0;
+
+ if (m_colliderGroundarr.Length >= 10)
+ {
+ for (i = 0; i < 10; i++)
+ {
+ m_colliderGroundarr[i] = m_colliderGroundarr[i + 1];
+ }
+ }
+ m_colliderGroundarr[10] = value;
+
+ for (i = 0; i < 11; i++)
+ {
+ if (m_colliderGroundarr[i])
+ {
+ truecount++;
+ }
+ else
+ {
+ falsecount++;
+ }
+ }
+
+ // Equal truecounts and false counts means we're colliding with something.
+
+ if (falsecount > 1.2*truecount)
+ {
+ m_iscollidingGround = false;
+ }
+ else
+ {
+ m_iscollidingGround = true;
+ }
+ if (m_wascollidingGround != m_iscollidingGround)
+ {
+ //base.SendCollisionUpdate(new CollisionEventUpdate());
+ }
+ m_wascollidingGround = m_iscollidingGround;
+ }
+ }
+
+ ///
+ /// Returns if the avatar is colliding with an object
+ ///
+ public override bool CollidingObj
+ {
+ get { return m_iscollidingObj; }
+ set
+ {
+ m_iscollidingObj = value;
+ if (value)
+ m_pidControllerActive = false;
+ else
+ m_pidControllerActive = true;
+ }
+ }
+
+ ///
+ /// turn the PID controller on or off.
+ /// The PID Controller will turn on all by itself in many situations
+ ///
+ ///
+ public void SetPidStatus(bool status)
+ {
+ m_pidControllerActive = status;
+ }
+
+ public override bool Stopped
+ {
+ get { return _zeroFlag; }
+ }
+
+ ///
+ /// This 'puts' an avatar somewhere in the physics space.
+ /// Not really a good choice unless you 'know' it's a good
+ /// spot otherwise you're likely to orbit the avatar.
+ ///
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set
+ {
+ lock (OdeScene.OdeLock)
+ {
+ d.BodySetPosition(Body, value.X, value.Y, value.Z);
+ _position = value;
+ }
+ }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ ///
+ /// This property sets the height of the avatar only. We use the height to make sure the avatar stands up straight
+ /// and use it to offset landings properly
+ ///
+ public override PhysicsVector Size
+ {
+ get { return new PhysicsVector(CAPSULE_RADIUS*2, CAPSULE_RADIUS*2, CAPSULE_LENGTH); }
+ set
+ {
+ m_pidControllerActive = true;
+ lock (OdeScene.OdeLock)
+ {
+ d.JointDestroy(Amotor);
+
+ PhysicsVector SetSize = value;
+ float prevCapsule = CAPSULE_LENGTH;
+ float capsuleradius = CAPSULE_RADIUS;
+ //capsuleradius = 0.2f;
+
+ CAPSULE_LENGTH = (SetSize.Z - ((SetSize.Z*0.52f))); // subtract 43% of the size
+ //m_log.Info("[SIZE]: " + CAPSULE_LENGTH.ToString());
+ d.BodyDestroy(Body);
+ gchBody.Free(); // rex
+ _parent_scene.waitForSpaceUnlock(_parent_scene.space);
+
+ d.GeomDestroy(Shell);
+ AvatarGeomAndBodyCreation(_position.X, _position.Y,
+ _position.Z + (Math.Abs(CAPSULE_LENGTH - prevCapsule) * 2), m_tensor);
+ Velocity = new PhysicsVector(0f, 0f, 0f);
+
+ gchShell.Free(); // rex
+ //MainLog.Instance.Verbose("PHYSICS", "Set Avatar Height To: " + (CAPSULE_RADIUS + CAPSULE_LENGTH));
+ Shell = d.CreateCapsule(_parent_scene.space, capsuleradius, CAPSULE_LENGTH);
+ gchShell = GCHandle.Alloc(Shell, GCHandleType.Pinned); // rex
+ d.MassSetCapsule(out ShellMass, m_density, 3, CAPSULE_RADIUS, CAPSULE_LENGTH);
+ Body = d.BodyCreate(_parent_scene.world);
+ gchBody = GCHandle.Alloc(Body, GCHandleType.Pinned); // rex
+ d.BodySetMass(Body, ref ShellMass);
+ d.BodySetPosition(Body, _position.X, _position.Y,
+ _position.Z + Math.Abs(CAPSULE_LENGTH - prevCapsule));
+ d.GeomSetBody(Shell, Body);
+ }
+ _parent_scene.geom_name_map[Shell] = m_name;
+ _parent_scene.actor_name_map[Shell] = (PhysicsActor) this;
+ }
+ }
+ ///
+ /// This creates the Avatar's physical Surrogate at the position supplied
+ ///
+ ///
+ ///
+ ///
+ private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ, float tensor)
+ {
+
+ if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+ {
+ m_foundDebian = true;
+ m_tensor = 2000000f;
+ }
+ else
+ {
+ m_tensor = 550000f;
+ }
+
+ int dAMotorEuler = 1;
+ _parent_scene.waitForSpaceUnlock(_parent_scene.space);
+ Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
+ d.MassSetCapsuleTotal(out ShellMass, m_mass, 2, CAPSULE_RADIUS, CAPSULE_LENGTH);
+ Body = d.BodyCreate(_parent_scene.world);
+ d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
+
+ d.BodySetMass(Body, ref ShellMass);
+ d.Matrix3 m_caprot;
+ // 90 Stand up on the cap of the capped cyllinder
+ d.RFromAxisAndAngle(out m_caprot, 1, 0, 1, (float)(Math.PI / 2));
+
+
+ d.GeomSetRotation(Shell, ref m_caprot);
+ d.BodySetRotation(Body, ref m_caprot);
+
+ d.GeomSetBody(Shell, Body);
+
+
+ // The purpose of the AMotor here is to keep the avatar's physical
+ // surrogate from rotating while moving
+ Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
+ d.JointAttach(Amotor, Body, IntPtr.Zero);
+ d.JointSetAMotorMode(Amotor, dAMotorEuler);
+ d.JointSetAMotorNumAxes(Amotor, 3);
+ d.JointSetAMotorAxis(Amotor, 0, 0, 1, 0, 0);
+ d.JointSetAMotorAxis(Amotor, 1, 0, 0, 1, 0);
+ d.JointSetAMotorAxis(Amotor, 2, 0, 0, 0, 1);
+ d.JointSetAMotorAngle(Amotor, 0, 0);
+ d.JointSetAMotorAngle(Amotor, 1, 0);
+ d.JointSetAMotorAngle(Amotor, 2, 0);
+
+ // These lowstops and high stops are effectively (no wiggle room)
+ d.JointSetAMotorParam(Amotor, (int)dParam.LowStop, -0.000000000001f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.LoStop3, -0.000000000001f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.LoStop2, -0.000000000001f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.HiStop, 0.000000000001f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.HiStop3, 0.000000000001f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.HiStop2, 0.000000000001f);
+
+ // Fudge factor is 1f by default, we're setting it to 0. We don't want it to Fudge or the
+ // capped cyllinder will fall over
+ d.JointSetAMotorParam(Amotor, (int)dParam.FudgeFactor, 0f);
+ d.JointSetAMotorParam(Amotor, (int)dParam.FMax, tensor);
+
+ //d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
+ //d.QfromR(
+ //d.Matrix3 checkrotation = new d.Matrix3(0.7071068,0.5, -0.7071068,
+ //
+ //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
+ //standupStraight();
+
+
+
+ }
+
+ //
+ ///
+ /// Uses the capped cyllinder volume formula to calculate the avatar's mass.
+ /// This may be used in calculations in the scene/scenepresence
+ ///
+ public override float Mass
+ {
+ get
+ {
+ float AVvolume = (float) (Math.PI*Math.Pow(CAPSULE_RADIUS, 2)*CAPSULE_LENGTH);
+ return m_density*AVvolume;
+ }
+ }
+
+ private void standupStraight()
+ {
+
+ // The purpose of this routine here is to quickly stabilize the Body while it's popped up in the air.
+ // The amotor needs a few seconds to stabilize so without it, the avatar shoots up sky high when you
+ // change appearance and when you enter the simulator
+ // After this routine is done, the amotor stabilizes much quicker
+ d.Vector3 feet;
+ d.Vector3 head;
+ d.BodyGetRelPointPos(Body, 0.0f, 0.0f, -1.0f, out feet);
+ d.BodyGetRelPointPos(Body, 0.0f, 0.0f, 1.0f, out head);
+ float posture = head.Z - feet.Z;
+
+ // restoring force proportional to lack of posture:
+ float servo = (2.5f - posture) * POSTURE_SERVO;
+ d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, servo, 0.0f, 0.0f, 1.0f);
+ d.BodyAddForceAtRelPos(Body, 0.0f, 0.0f, -servo, 0.0f, 0.0f, -1.0f);
+ //d.Matrix3 bodyrotation = d.BodyGetRotation(Body);
+ //m_log.Info("[PHYSICSAV]: Rotation: " + bodyrotation.M00 + " : " + bodyrotation.M01 + " : " + bodyrotation.M02 + " : " + bodyrotation.M10 + " : " + bodyrotation.M11 + " : " + bodyrotation.M12 + " : " + bodyrotation.M20 + " : " + bodyrotation.M21 + " : " + bodyrotation.M22);
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return new PhysicsVector(_target_velocity.X, _target_velocity.Y, _target_velocity.Z); }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get {
+ // There's a problem with PhysicsVector.Zero! Don't Use it Here!
+ if (_zeroFlag)
+ return new PhysicsVector(0f, 0f, 0f);
+ m_lastUpdateSent = false;
+ return _velocity;
+ }
+ set
+ {
+ m_pidControllerActive = true;
+ _target_velocity = value;
+ }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return Quaternion.Identity; }
+ set {
+ //Matrix3 or = Orientation.ToRotationMatrix();
+ //d.Matrix3 ord = new d.Matrix3(or.m00, or.m10, or.m20, or.m01, or.m11, or.m21, or.m02, or.m12, or.m22);
+ //d.BodySetRotation(Body, ref ord);
+
+ }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ m_pidControllerActive = true;
+ _acceleration = accel;
+ }
+
+ ///
+ /// Adds the force supplied to the Target Velocity
+ /// The PID controller takes this target velocity and tries to make it a reality
+ ///
+ ///
+ public override void AddForce(PhysicsVector force)
+ {
+ m_pidControllerActive = true;
+ _target_velocity.X += force.X;
+ _target_velocity.Y += force.Y;
+ _target_velocity.Z += force.Z;
+
+ //m_lastUpdateSent = false;
+ }
+
+ ///
+ /// After all of the forces add up with 'add force' we apply them with doForce
+ ///
+ ///
+ public void doForce(PhysicsVector force)
+ {
+ if (!collidelock)
+ {
+ d.BodyAddForce(Body, force.X, force.Y, force.Z);
+ //d.BodySetRotation(Body, ref m_StandUpRotation);
+ //standupStraight();
+
+ }
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+
+ ///
+ /// Called from Simulate
+ /// This is the avatar's movement control + PID Controller
+ ///
+ ///
+ public void Move(float timeStep)
+ {
+ // no lock; for now it's only called from within Simulate()
+
+ // If the PID Controller isn't active then we set our force
+ // calculating base velocity to the current position
+ if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+ {
+ PID_D = 3200.0f;
+ PID_P = 1400.0f;
+ }
+ else
+ {
+ PID_D = 2200.0f;
+ PID_P = 900.0f;
+ }
+
+
+ if (m_pidControllerActive == false)
+ {
+ _zeroPosition = d.BodyGetPosition(Body);
+ }
+ //PidStatus = true;
+
+ PhysicsVector vec = new PhysicsVector();
+ d.Vector3 vel = d.BodyGetLinearVel(Body);
+ float movementdivisor = 1f;
+
+ if (!m_alwaysRun)
+ {
+ movementdivisor = 1.3f;
+ }
+ else
+ {
+ movementdivisor = 0.8f;
+ }
+
+ // if velocity is zero, use position control; otherwise, velocity control
+ if (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f && m_iscolliding)
+ {
+ // keep track of where we stopped. No more slippin' & slidin'
+ if (!_zeroFlag)
+ {
+ _zeroFlag = true;
+ _zeroPosition = d.BodyGetPosition(Body);
+ }
+ if (m_pidControllerActive)
+ {
+ // We only want to deactivate the PID Controller if we think we want to have our surrogate
+ // react to the physics scene by moving it's position.
+ // Avatar to Avatar collisions
+ // Prim to avatar collisions
+
+ d.Vector3 pos = d.BodyGetPosition(Body);
+ vec.X = (_target_velocity.X - vel.X) * (PID_D) + (_zeroPosition.X - pos.X) * (PID_P * 2);
+ vec.Y = (_target_velocity.Y - vel.Y)*(PID_D) + (_zeroPosition.Y - pos.Y)* (PID_P * 2);
+ if (flying)
+ {
+ vec.Z = (_target_velocity.Z - vel.Z) * (PID_D) + (_zeroPosition.Z - pos.Z) * PID_P;
+ }
+ }
+ //PidStatus = true;
+ }
+ else
+ {
+ m_pidControllerActive = true;
+ _zeroFlag = false;
+ if (m_iscolliding && !flying)
+ {
+ // We're flying and colliding with something
+ vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D);
+ vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D);
+ }
+ else if (m_iscolliding && flying)
+ {
+ // We're flying and colliding with something
+ vec.X = ((_target_velocity.X/movementdivisor) - vel.X)*(PID_D / 16);
+ vec.Y = ((_target_velocity.Y/movementdivisor) - vel.Y)*(PID_D / 16);
+ }
+ else if (!m_iscolliding && flying)
+ {
+ // We're flying and colliding with something
+ vec.X = ((_target_velocity.X / movementdivisor) - vel.X) * (PID_D/6);
+ vec.Y = ((_target_velocity.Y / movementdivisor) - vel.Y) * (PID_D/6);
+ }
+
+ if (m_iscolliding && !flying && _target_velocity.Z > 0.0f)
+ {
+ // We're colliding with something and we're not flying but we're moving
+ // This means we're walking or running.
+ d.Vector3 pos = d.BodyGetPosition(Body);
+ vec.Z = (_target_velocity.Z - vel.Z)*PID_D + (_zeroPosition.Z - pos.Z)*PID_P;
+ if (_target_velocity.X > 0)
+ {
+ vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
+ }
+ if (_target_velocity.Y > 0)
+ {
+ vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
+ }
+ }
+ else if (!m_iscolliding && !flying)
+ {
+ // we're not colliding and we're not flying so that means we're falling!
+ // m_iscolliding includes collisions with the ground.
+ d.Vector3 pos = d.BodyGetPosition(Body);
+ if (_target_velocity.X > 0)
+ {
+ vec.X = ((_target_velocity.X - vel.X)/1.2f)*PID_D;
+ }
+ if (_target_velocity.Y > 0)
+ {
+ vec.Y = ((_target_velocity.Y - vel.Y)/1.2f)*PID_D;
+ }
+ }
+
+
+ if (flying)
+ {
+ vec.Z = (_target_velocity.Z - vel.Z) * (PID_D);
+ }
+ }
+ if (flying)
+ {
+ vec.Z += (9.8f*m_mass);
+ }
+
+
+ doForce(vec);
+ }
+
+ ///
+ /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
+ ///
+ public void UpdatePositionAndVelocity()
+ {
+ // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
+ d.Vector3 vec = d.BodyGetPosition(Body);
+
+ // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
+ if (vec.X < 0.0f) vec.X = 0.0f;
+ if (vec.Y < 0.0f) vec.Y = 0.0f;
+ if (vec.X > 255.95f) vec.X = 255.95f;
+ if (vec.Y > 255.95f) vec.Y = 255.95f;
+
+ _position.X = vec.X;
+ _position.Y = vec.Y;
+ _position.Z = vec.Z;
+
+ // Did we move last? = zeroflag
+ // This helps keep us from sliding all over
+
+ if (_zeroFlag)
+ {
+ _velocity.X = 0.0f;
+ _velocity.Y = 0.0f;
+ _velocity.Z = 0.0f;
+
+ // Did we send out the 'stopped' message?
+ if (!m_lastUpdateSent)
+ {
+ m_lastUpdateSent = true;
+ //base.RequestPhysicsterseUpdate();
+
+ }
+ }
+ else
+ {
+ m_lastUpdateSent = false;
+ vec = d.BodyGetLinearVel(Body);
+ _velocity.X = (vec.X);
+ _velocity.Y = (vec.Y);
+
+ _velocity.Z = (vec.Z);
+ if (_velocity.Z < -6 && !m_hackSentFall)
+ {
+ // Collisionupdates will be used in the future, right now the're not being used.
+ m_hackSentFall = true;
+ //base.SendCollisionUpdate(new CollisionEventUpdate());
+ m_pidControllerActive = false;
+ }
+ else if (flying && !m_hackSentFly)
+ {
+ //m_hackSentFly = true;
+ //base.SendCollisionUpdate(new CollisionEventUpdate());
+ }
+ else
+ {
+ m_hackSentFly = false;
+ m_hackSentFall = false;
+ }
+ }
+ }
+
+ ///
+ /// Cleanup the things we use in the scene.
+ ///
+ public void Destroy()
+ {
+ lock (OdeScene.OdeLock)
+ {
+ // Kill the Amotor
+ d.JointDestroy(Amotor);
+
+ //kill the Geometry
+ _parent_scene.waitForSpaceUnlock(_parent_scene.space);
+
+ d.GeomDestroy(Shell);
+ _parent_scene.geom_name_map.Remove(Shell);
+
+ //kill the body
+ d.BodyDestroy(Body);
+ }
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 35021ec6da..012e7d94dd 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -1,1167 +1,1790 @@
-/*
-* 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 OpenSim 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 Axiom.Math;
-using Ode.NET;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-
-using System.Collections.Generic; // rex
-using System.Runtime.InteropServices; // rex
-using RexDotMeshLoader; // rex
-using OpenSim.Framework.Console; // rex
-using libsecondlife; // rex
-
-namespace OpenSim.Region.Physics.OdePlugin
-{
-
- // rex, new class
- public class OdeCollisionMesh : IMesh
- {
- public float[] vertexListOrig;
- public int[] indexListOrig;
-
- public float[] vertexList;
- public int[] indexList;
- public GCHandle gchVertexList;
- public GCHandle gchIndexList;
-
- public LLVector3 BoundsMin = new LLVector3();
- public LLVector3 BoundsMax = new LLVector3();
- public bool m_BoundsScaling;
-
- public OdeCollisionMesh(int vVertexCount, int vIndexCount)
- {
- vertexList = new float[vVertexCount];
- gchVertexList = GCHandle.Alloc(vertexList, GCHandleType.Pinned);
- vertexListOrig = new float[vVertexCount];
-
- indexList = new int[vIndexCount];
- gchIndexList = GCHandle.Alloc(indexList, GCHandleType.Pinned);
- indexListOrig = new int[vIndexCount];
- }
-
- public void FreeLists()
- {
- gchVertexList.Free();
- gchIndexList.Free();
- }
-
- public List getVertexList()
- {
- return null;
- }
- public int[] getIndexListAsInt()
- {
- return indexList;
- }
- public int[] getIndexListAsIntLocked()
- {
- return indexList;
- }
- public float[] getVertexListAsFloatLocked()
- {
- return vertexList;
- }
- }
-
-
- public class OdePrim : PhysicsActor
- {
- public PhysicsVector _position;
- private PhysicsVector _velocity;
- private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f);
- private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
- private PhysicsVector m_rotationalVelocity;
- private PhysicsVector _size;
- private PhysicsVector _acceleration;
- private Quaternion _orientation;
- private PhysicsVector m_taintposition;
- private PhysicsVector m_taintsize;
- private Quaternion m_taintrot;
- private bool m_taintshape = false;
- private bool m_taintPhysics = false;
- public bool m_taintremove = false;
-
- private IMesh _mesh;
- private PrimitiveBaseShape _pbs;
- private OdeScene _parent_scene;
- public IntPtr m_targetSpace = (IntPtr) 0;
- public IntPtr prim_geom;
- public IntPtr _triMeshData;
- private bool iscolliding = false;
- private bool m_isphysical = false;
- private bool m_throttleUpdates = false;
- private int throttleCounter = 0;
- public bool outofBounds = false;
- private float m_density = 10.000006836f; // Aluminum g/cm3;
-
-
- public bool _zeroFlag = false;
- private bool m_lastUpdateSent = false;
-
- public IntPtr Body = (IntPtr) 0;
- private String m_primName;
- private PhysicsVector _target_velocity;
- public d.Mass pMass;
-
- private int debugcounter = 0;
- private bool m_DotMeshCollision = false; // rex
- public bool m_BoundsScalingUpdate = false; // rex
- private bool m_PrimVolume = false; // rex
-
- public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size,
- Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, uint localID)
- {
- m_localID = localID; // rex
- _velocity = new PhysicsVector();
- _position = pos;
- m_taintposition = pos;
- if (_position.X > 257)
- {
- _position.X = 257;
- }
- if (_position.X < 0)
- {
- _position.X = 0;
- }
- if (_position.Y > 257)
- {
- _position.Y = 257;
- }
- if (_position.Y < 0)
- {
- _position.Y = 0;
- }
-
- _size = size;
- m_taintsize = _size;
- _acceleration = new PhysicsVector();
- m_rotationalVelocity = PhysicsVector.Zero;
- _orientation = rotation;
- m_taintrot = _orientation;
- _mesh = mesh;
- _pbs = pbs;
-
- _parent_scene = parent_scene;
- m_targetSpace = targetSpace;
-
- if (pos.Z < 0)
- m_isphysical = false;
- else
- {
- m_isphysical = pisPhysical;
- // If we're physical, we need to be in the master space for now.
- // linksets *should* be in a space together.. but are not currently
- if (m_isphysical)
- m_targetSpace = _parent_scene.space;
- }
- m_primName = primName;
-
- lock (OdeScene.OdeLock)
- {
- if (mesh != null)
- {
- setMesh(parent_scene, mesh);
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- }
-
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = rotation.w;
- myrot.X = rotation.x;
- myrot.Y = rotation.y;
- myrot.Z = rotation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
-
-
- if (m_isphysical && Body == (IntPtr) 0)
- {
- enableBody();
- }
- parent_scene.geom_name_map[prim_geom] = primName;
- parent_scene.actor_name_map[prim_geom] = (PhysicsActor) this;
- // don't do .add() here; old geoms get recycled with the same hash
- }
- }
-
- // rex, modified function, m_PrimVolume added
- public override int PhysicsActorType
- {
- get
- {
- if (m_PrimVolume)
- return (int)ActorTypes.PrimVolume;
- else
- return (int)ActorTypes.Prim;
- }
- set
- {
- if (value == (int)ActorTypes.PrimVolume)
- m_PrimVolume = true;
- else
- m_PrimVolume = false;
- }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public void enableBody()
- {
- // Sets the geom to a body
- Body = d.BodyCreate(_parent_scene.world);
-
- setMass();
- d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.BodySetQuaternion(Body, ref myrot);
- d.GeomSetBody(prim_geom, Body);
- d.BodySetAutoDisableFlag(Body, true);
- d.BodySetAutoDisableSteps(Body, 20);
-
- _parent_scene.addActivePrim(this);
- }
-
- private float CalculateMass()
- {
- float volume = 0;
-
- // No material is passed to the physics engines yet.. soo..
- // we're using the m_density constant in the class definition
-
-
- float returnMass = 0;
-
- switch (_pbs.ProfileShape)
- {
- case ProfileShape.Square:
- // Profile Volume
-
- volume = _size.X*_size.Y*_size.Z;
-
- // If the user has 'hollowed out'
- // ProfileHollow is one of those 0 to 50000 values :P
- // we like percentages better.. so turning into a percentage
-
- if (((float) _pbs.ProfileHollow/50000f) > 0.0)
- {
- float hollowAmount = (float) _pbs.ProfileHollow/50000f;
-
- // calculate the hollow volume by it's shape compared to the prim shape
- float hollowVolume = 0;
- switch (_pbs.HollowShape)
- {
- case HollowShape.Square:
- case HollowShape.Same:
- // Cube Hollow volume calculation
- float hollowsizex = _size.X*hollowAmount;
- float hollowsizey = _size.Y*hollowAmount;
- float hollowsizez = _size.Z*hollowAmount;
- hollowVolume = hollowsizex*hollowsizey*hollowsizez;
- break;
-
- case HollowShape.Circle:
- // Hollow shape is a perfect cyllinder in respect to the cube's scale
- // Cyllinder hollow volume calculation
- float hRadius = _size.X/2;
- float hLength = _size.Z;
-
- // pi * r2 * h
- hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount);
- break;
-
- case HollowShape.Triangle:
- // Equilateral Triangular Prism volume hollow calculation
- // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
-
- float aLength = _size.Y;
- // 1/2 abh
- hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount);
- break;
-
- default:
- hollowVolume = 0;
- break;
- }
- volume = volume - hollowVolume;
- }
-
- break;
-
- default:
- // we don't have all of the volume formulas yet so
- // use the common volume formula for all
- volume = _size.X*_size.Y*_size.Z;
- break;
- }
-
- // Calculate Path cut effect on volume
- // Not exact, in the triangle hollow example
- // They should never be zero or less then zero..
- // we'll ignore it if it's less then zero
-
- // ProfileEnd and ProfileBegin are values
- // from 0 to 50000
-
- // Turning them back into percentages so that I can cut that percentage off the volume
-
- float PathCutEndAmount = _pbs.ProfileEnd;
- float PathCutStartAmount = _pbs.ProfileBegin;
- if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
- {
- float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
-
- // Check the return amount for sanity
- if (pathCutAmount >= 0.99f)
- pathCutAmount = 0.99f;
-
- volume = volume - (volume*pathCutAmount);
- }
-
- // Mass = density * volume
-
- returnMass = m_density*volume;
-
- return returnMass;
- }
-
- public void setMass()
- {
- if (Body != (IntPtr) 0)
- {
- d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z);
- d.BodySetMass(Body, ref pMass);
- }
- }
-
-
- public void disableBody()
- {
- //this kills the body so things like 'mesh' can re-create it.
- if (Body != (IntPtr) 0)
- {
- _parent_scene.remActivePrim(this);
- d.BodyDestroy(Body);
- Body = (IntPtr) 0;
- }
- }
-
- public void setMesh(OdeScene parent_scene, IMesh mesh)
- {
- //Kill Body so that mesh can re-make the geom
- if (IsPhysical && Body != (IntPtr) 0)
- {
- disableBody();
- }
- float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
- int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
- int VertexCount = vertexList.GetLength(0)/3;
- int IndexCount = indexList.GetLength(0);
-
- // rex, del old trimeshdata
- if (_triMeshData != (IntPtr)0)
- d.GeomTriMeshDataDestroy(_triMeshData);
- _mesh = mesh; // rex, end
-
- _triMeshData = d.GeomTriMeshDataCreate();
-
- d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
- 3*sizeof (int));
- d.GeomTriMeshDataPreprocess(_triMeshData);
-
- prim_geom = d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null);
-
- if (IsPhysical && Body == (IntPtr) 0)
- {
- // Recreate the body
- enableBody();
- }
- }
-
- public void ProcessTaints(float timestep)
- {
- if (m_taintposition != _position)
- Move(timestep);
-
- if (m_taintrot != _orientation)
- rotate(timestep);
- //
-
- if (m_taintPhysics != m_isphysical)
- changePhysicsStatus(timestep);
- //
-
- if (m_taintsize != _size)
- changesize(timestep);
-
- if (m_BoundsScalingUpdate) // rex
- changesize(timestep);
- //
-
- if (m_taintshape)
- changeshape(timestep);
- //
- }
-
- public void Move(float timestep)
- {
- if (m_isphysical)
- {
- // This is a fallback.. May no longer be necessary.
- if (Body == (IntPtr) 0)
- enableBody();
- //Prim auto disable after 20 frames,
- ///if you move it, re-enable the prim manually.
- d.BodyEnable(Body);
- d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
- }
- else
- {
- string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
- int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
- m_targetSpace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.SpaceAdd(m_targetSpace, prim_geom);
- }
-
- m_taintposition = _position;
- }
-
- // rex, function changed
- public void rotate(float timestep)
- {
- d.Quaternion myrot = new d.Quaternion();
-
- if (m_DotMeshCollision && _mesh != null) // rex, setting rot for collision 3d model
- {
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
-
- Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
- Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
- Quaternion mytemprot = _orientation * meshRotA * meshRotB;
-
- myrot.W = mytemprot.w;
- myrot.X = mytemprot.x;
- myrot.Y = mytemprot.y;
- myrot.Z = mytemprot.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
- }
- else
- {
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
- }
-
- if (m_isphysical && Body != (IntPtr) 0)
- {
- d.BodySetQuaternion(Body, ref myrot);
- }
-
- m_taintrot = _orientation;
- }
-
- public void changePhysicsStatus(float timestap)
- {
- if (m_isphysical == true)
- {
- if (Body == (IntPtr) 0)
- {
- enableBody();
- }
- }
- else
- {
- if (Body != (IntPtr) 0)
- {
- disableBody();
- }
- }
-
-
- m_taintPhysics = m_isphysical;
- }
-
- // rex, function changed
- public void changesize(float timestamp)
- {
- string oldname = _parent_scene.geom_name_map[prim_geom];
-
- // Cleanup of old prim geometry
- if (_mesh != null)
- {
- // Cleanup meshing here
- }
- //kill body to rebuild
- if (IsPhysical && Body != (IntPtr) 0)
- {
- disableBody();
- }
- if (d.SpaceQuery(m_targetSpace, prim_geom))
- {
- d.SpaceRemove(m_targetSpace, prim_geom);
- }
- d.GeomDestroy(prim_geom);
-
- // we don't need to do space calculation because the client sends a position update also.
-
- if (m_DotMeshCollision && _mesh != null) // rex, scaling dotmesh models
- {
- float[] scalefactor = new float[3];
- int vertindex = 0;
- OdeCollisionMesh mesh = _mesh as OdeCollisionMesh;
-
- LLVector3 scalingvector = new LLVector3(_size.X, _size.Y, _size.Z);
- if (mesh.m_BoundsScaling)
- {
- LLVector3 boundssize = mesh.BoundsMax - mesh.BoundsMin;
- if (boundssize.X != 0)
- scalingvector.X /= boundssize.X;
- if (boundssize.Y != 0)
- scalingvector.Z /= boundssize.Y;
- if (boundssize.Z != 0)
- scalingvector.Y /= boundssize.Z;
- }
- scalefactor[0] = scalingvector.X;
- scalefactor[1] = scalingvector.Z;
- scalefactor[2] = scalingvector.Y;
-
- for (int i = 0; i < mesh.vertexList.GetLength(0); i++)
- {
- mesh.vertexList[i] = mesh.vertexListOrig[i] * scalefactor[vertindex];
- vertindex++;
- if (vertindex > 2)
- vertindex = 0;
- }
-
- for (int i = 0; i < mesh.indexList.GetLength(0); i++)
- mesh.indexList[i] = mesh.indexListOrig[i];
-
- setMesh(_parent_scene, mesh);
-
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
-
- Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
- Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
- Quaternion mytemprot = _orientation * meshRotA * meshRotB;
-
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = mytemprot.w;
- myrot.X = mytemprot.x;
- myrot.Y = mytemprot.y;
- myrot.Z = mytemprot.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
-
- if (IsPhysical && Body == (IntPtr)0)
- {
- // Re creates body on size.
- // EnableBody also does setMass()
- enableBody();
- d.BodyEnable(Body);
- }
- } // rex, end scaling
- // Construction of new prim
- else if (_parent_scene.needsMeshing(_pbs))
- {
- // Don't need to re-enable body.. it's done in SetMesh
- IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
- // createmesh returns null when it's a shape that isn't a cube.
- if (mesh != null)
- {
- setMesh(_parent_scene, mesh);
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
- }
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
-
-
- //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
- if (IsPhysical && Body == (IntPtr) 0)
- {
- // Re creates body on size.
- // EnableBody also does setMass()
- enableBody();
- d.BodyEnable(Body);
- }
- }
-
- _parent_scene.geom_name_map[prim_geom] = oldname;
-
- m_taintsize = _size;
- m_BoundsScalingUpdate = false; // rex
- }
-
- public void changeshape(float timestamp)
- {
- string oldname = _parent_scene.geom_name_map[prim_geom];
-
- // Cleanup of old prim geometry and Bodies
- if (IsPhysical && Body != (IntPtr) 0)
- {
- disableBody();
- }
- d.GeomDestroy(prim_geom);
- if (_mesh != null)
- {
- d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
- }
-
- // Construction of new prim
- if (_parent_scene.needsMeshing(_pbs))
- {
- IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
- if (mesh != null)
- {
- setMesh(_parent_scene, mesh);
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- }
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- }
- if (IsPhysical && Body == (IntPtr) 0)
- {
- //re-create new body
- enableBody();
- }
- else
- {
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
- }
- _parent_scene.geom_name_map[prim_geom] = oldname;
-
- m_taintshape = false;
- }
-
- public override bool IsPhysical
- {
- get { return m_isphysical; }
- set { m_isphysical = value; }
- }
-
- public void setPrimForRemoval()
- {
- m_taintremove = true;
- }
-
- public override bool Flying
- {
- get { return false; //no flying prims for you
- }
- set { }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return m_throttleUpdates; }
- set { m_throttleUpdates = value; }
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
-
- set { _position = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return _size; }
- set { _size = value; }
- }
-
- public override float Mass
- {
- get { return CalculateMass(); }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { _pbs = value; }
- }
-
- public override PhysicsVector Velocity
- {
- get
- {
- // Averate previous velocity with the new one so
- // client object interpolation works a 'little' better
- PhysicsVector returnVelocity = new PhysicsVector();
- returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2;
- returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2;
- returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
- return returnVelocity;
- }
- set { _velocity = value; }
- }
-
- public override bool Kinematic
- {
- get { return false; }
- set { }
- }
-
- public override Quaternion Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public void UpdatePositionAndVelocity()
- {
- // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
-
- if (Body != (IntPtr) 0)
- {
- d.Vector3 vec = d.BodyGetPosition(Body);
- d.Quaternion ori = d.BodyGetQuaternion(Body);
- d.Vector3 vel = d.BodyGetLinearVel(Body);
- d.Vector3 rotvel = d.BodyGetAngularVel(Body);
-
- PhysicsVector l_position = new PhysicsVector();
- // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
- if (vec.X < 0.0f) vec.X = 0.0f;
- if (vec.Y < 0.0f) vec.Y = 0.0f;
- if (vec.X > 255.95f) vec.X = 255.95f;
- if (vec.Y > 255.95f) vec.Y = 255.95f;
- m_lastposition = _position;
-
- l_position.X = vec.X;
- l_position.Y = vec.Y;
- l_position.Z = vec.Z;
- if (l_position.Z < 0)
- {
- // This is so prim that get lost underground don't fall forever and suck up
- //
- // Sim resources and memory.
- // Disables the prim's movement physics....
- // It's a hack and will generate a console message if it fails.
-
-
- //IsPhysical = false;
- base.RaiseOutOfBounds(_position);
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- base.RequestPhysicsterseUpdate();
- m_throttleUpdates = false;
- throttleCounter = 0;
- _zeroFlag = true;
- //outofBounds = true;
- }
-
- if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
- && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
- && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02))
- {
- _zeroFlag = true;
- }
- else
- {
- //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
- _zeroFlag = false;
- }
-
-
- if (_zeroFlag)
- {
- // Supposedly this is supposed to tell SceneObjectGroup that
- // no more updates need to be sent..
- // but it seems broken.
- _velocity.X = 0.0f;
- _velocity.Y = 0.0f;
- _velocity.Z = 0.0f;
- //_orientation.w = 0f;
- //_orientation.x = 0f;
- //_orientation.y = 0f;
- //_orientation.z = 0f;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- if (!m_lastUpdateSent)
- {
- m_throttleUpdates = false;
- throttleCounter = 0;
- base.RequestPhysicsterseUpdate();
- m_lastUpdateSent = true;
- }
- }
- else
- {
- m_lastVelocity = _velocity;
-
- _position = l_position;
-
- _velocity.X = vel.X;
- _velocity.Y = vel.Y;
- _velocity.Z = vel.Z;
-
- m_rotationalVelocity.X = rotvel.X;
- m_rotationalVelocity.Y = rotvel.Y;
- m_rotationalVelocity.Z = rotvel.Z;
- //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
- _orientation.w = ori.W;
- _orientation.x = ori.X;
- _orientation.y = ori.Y;
- _orientation.z = ori.Z;
- m_lastUpdateSent = false;
- if (!m_throttleUpdates || throttleCounter > 15)
- {
- base.RequestPhysicsterseUpdate();
- }
- else
- {
- throttleCounter++;
- }
- }
- m_lastposition = l_position;
- }
- else
- {
- // Not a body.. so Make sure the client isn't interpolating
- _velocity.X = 0;
- _velocity.Y = 0;
- _velocity.Z = 0;
- m_rotationalVelocity.X = 0;
- m_rotationalVelocity.Y = 0;
- m_rotationalVelocity.Z = 0;
- _zeroFlag = true;
- }
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
-
- // rex, new function.
- // This function should be called only outside of simulation loop -> OdeLock used.
- public override void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh)
- {
- float[] tempVertexList;
- float[] tempBounds;
- int[] tempIndexList;
- string errorMessage;
- float[] scalefactor = new float[3];
- int vertindex = 0;
-
- lock (OdeScene.OdeLock)
- {
- // 1. Get rid of old mesh
- m_DotMeshCollision = false;
- if (_mesh != null)
- {
- if ((OdeCollisionMesh)_mesh != null)
- (_mesh as OdeCollisionMesh).FreeLists();
-
- _mesh = null;
- }
-
- // 2. Try to load new colmesh
- OdeCollisionMesh mesh = null;
- if (vData != null)
- {
- DotMeshLoader.ReadDotMeshModel(vData, out tempVertexList, out tempIndexList, out tempBounds, out errorMessage);
-
- if (tempVertexList != null && tempIndexList != null)
- {
- mesh = new OdeCollisionMesh(tempVertexList.GetLength(0), tempIndexList.GetLength(0));
- mesh.m_BoundsScaling = vbScaleMesh;
- mesh.BoundsMin.X = tempBounds[0];
- mesh.BoundsMin.Y = tempBounds[1];
- mesh.BoundsMin.Z = tempBounds[2];
- mesh.BoundsMax.X = tempBounds[3];
- mesh.BoundsMax.Y = tempBounds[4];
- mesh.BoundsMax.Z = tempBounds[5];
-
- LLVector3 scalingvector = new LLVector3(_size.X, _size.Y, _size.Z);
- if (vbScaleMesh)
- {
- LLVector3 boundssize = mesh.BoundsMax - mesh.BoundsMin;
- if (boundssize.X != 0)
- scalingvector.X /= boundssize.X;
- if (boundssize.Y != 0)
- scalingvector.Z /= boundssize.Y;
- if (boundssize.Z != 0)
- scalingvector.Y /= boundssize.Z;
- }
-
- scalefactor[0] = scalingvector.X;
- scalefactor[1] = scalingvector.Z;
- scalefactor[2] = scalingvector.Y;
- for (int i = 0; i < tempVertexList.GetLength(0); i++)
- {
- mesh.vertexListOrig[i] = tempVertexList[i];
- mesh.vertexList[i] = tempVertexList[i] * scalefactor[vertindex];
-
- vertindex++;
- if (vertindex > 2)
- vertindex = 0;
- }
-
- for (int i = 0; i < tempIndexList.GetLength(0); i++)
- {
- mesh.indexListOrig[i] = tempIndexList[i];
- mesh.indexList[i] = tempIndexList[i];
- }
-
-
- }
- else
- MainLog.Instance.Error("PHYSICS", "Error importing mesh:" + MeshName + ", " + errorMessage);
- }
-
- // 3. If mesh is null, must create the default collisionbox
- if (mesh == null)
- {
- CreateDefaultCollision();
- return;
- }
-
- // 4. If mesh loaded, use it
- string oldname = _parent_scene.geom_name_map[prim_geom];
- m_DotMeshCollision = true;
-
- if (IsPhysical && Body != (IntPtr)0)
- disableBody();
-
- if (prim_geom != (IntPtr)0)
- {
- if (d.SpaceQuery(m_targetSpace, prim_geom))
- {
- d.SpaceRemove(m_targetSpace, prim_geom);
- }
- d.GeomDestroy(prim_geom);
- }
-
- setMesh(_parent_scene, mesh);
-
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
-
- Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
- Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
- Quaternion mytemprot = _orientation * meshRotA * meshRotB;
-
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = mytemprot.w;
- myrot.X = mytemprot.x;
- myrot.Y = mytemprot.y;
- myrot.Z = mytemprot.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
-
- _parent_scene.geom_name_map[prim_geom] = oldname;
- }
- }
-
-
-
-
-
- // rex, function added
- private void CreateDefaultCollision()
- {
- string oldname = _parent_scene.geom_name_map[prim_geom];
-
- // Cleanup of old prim geometry
- if (_mesh != null)
- {
- // Cleanup meshing here
- }
- //kill body to rebuild
- if (IsPhysical && Body != (IntPtr)0)
- {
- disableBody();
- }
- if (d.SpaceQuery(m_targetSpace, prim_geom))
- {
- d.SpaceRemove(m_targetSpace, prim_geom);
- }
- d.GeomDestroy(prim_geom);
-
- // we don't need to do space calculation because the client sends a position update also.
- // Construction of new prim
- if (_parent_scene.needsMeshing(_pbs))
- {
- // Don't need to re-enable body.. it's done in SetMesh
- IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
- // createmesh returns null when it's a shape that isn't a cube.
- if (mesh != null)
- {
- setMesh(_parent_scene, mesh);
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
- }
- }
- else
- {
- prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
- d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
- d.Quaternion myrot = new d.Quaternion();
- myrot.W = _orientation.w;
- myrot.X = _orientation.x;
- myrot.Y = _orientation.y;
- myrot.Z = _orientation.z;
- d.GeomSetQuaternion(prim_geom, ref myrot);
-
-
- //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
- if (IsPhysical && Body == (IntPtr)0)
- {
- // Re creates body on size.
- // EnableBody also does setMass()
- enableBody();
- d.BodyEnable(Body);
- }
- }
- _parent_scene.geom_name_map[prim_geom] = oldname;
- }
-
- // rex, new function
- public override void SetBoundsScaling(bool vbScaleMesh)
- {
- if (m_DotMeshCollision && _mesh != null)
- {
- (_mesh as OdeCollisionMesh).m_BoundsScaling = vbScaleMesh;
- m_BoundsScalingUpdate = true;
- }
- }
-
-
-
-
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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.Runtime.InteropServices;
+using Axiom.Math;
+using Ode.NET;
+using OpenSim.Framework;
+using OpenSim.Region.Physics.Manager;
+
+using System.Collections.Generic; // rex
+using System.Runtime.InteropServices; // rex
+using RexDotMeshLoader; // rex
+using OpenSim.Framework.Console; // rex
+using libsecondlife; // rex
+
+namespace OpenSim.Region.Physics.OdePlugin
+{
+
+ // rex, new class
+ public class OdeCollisionMesh : IMesh
+ {
+ public float[] vertexListOrig;
+ public int[] indexListOrig;
+
+ public float[] vertexList;
+ public int[] indexList;
+ public GCHandle gchVertexList;
+ public GCHandle gchIndexList;
+
+ public LLVector3 BoundsMin = new LLVector3();
+ public LLVector3 BoundsMax = new LLVector3();
+ public bool m_BoundsScaling;
+
+ public OdeCollisionMesh(int vVertexCount, int vIndexCount)
+ {
+ vertexList = new float[vVertexCount];
+ gchVertexList = GCHandle.Alloc(vertexList, GCHandleType.Pinned);
+ vertexListOrig = new float[vVertexCount];
+
+ indexList = new int[vIndexCount];
+ gchIndexList = GCHandle.Alloc(indexList, GCHandleType.Pinned);
+ indexListOrig = new int[vIndexCount];
+ }
+
+ public void FreeLists()
+ {
+ gchVertexList.Free();
+ gchIndexList.Free();
+ }
+
+ public List getVertexList()
+ {
+ return null;
+ }
+ public int[] getIndexListAsInt()
+ {
+ return indexList;
+ }
+ public int[] getIndexListAsIntLocked()
+ {
+ return indexList;
+ }
+ public float[] getVertexListAsFloatLocked()
+ {
+ return vertexList;
+ }
+ }
+
+
+ public class OdePrim : PhysicsActor
+ {
+ private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ public PhysicsVector _position;
+ private PhysicsVector _velocity;
+ private PhysicsVector m_lastVelocity = new PhysicsVector(0.0f, 0.0f, 0.0f);
+ private PhysicsVector m_lastposition = new PhysicsVector(0.0f, 0.0f, 0.0f);
+ private PhysicsVector m_rotationalVelocity;
+ private PhysicsVector _size;
+ private PhysicsVector _acceleration;
+ private Quaternion _orientation;
+ private PhysicsVector m_taintposition;
+ private PhysicsVector m_taintsize;
+ private PhysicsVector m_taintVelocity = PhysicsVector.Zero;
+ private Quaternion m_taintrot;
+ private bool m_taintshape = false;
+ private bool m_taintPhysics = false;
+ public bool m_taintremove = false;
+ public bool m_taintdisable = false;
+ public bool m_disabled = false;
+ public bool m_taintadd = false;
+ public GCHandle gc;
+ private CollisionLocker ode;
+
+ private bool m_taintforce = false;
+ private List m_forcelist = new List();
+
+ private IMesh _mesh;
+ private PrimitiveBaseShape _pbs;
+ private OdeScene _parent_scene;
+ public IntPtr m_targetSpace = (IntPtr) 0;
+ public IntPtr prim_geom;
+ public IntPtr prev_geom;
+ public IntPtr _triMeshData;
+
+ private bool iscolliding = false;
+ private bool m_isphysical = false;
+ private bool m_throttleUpdates = false;
+ private int throttleCounter = 0;
+ public int m_interpenetrationcount = 0;
+ public int m_collisionscore = 0;
+ public int m_roundsUnderMotionThreshold = 0;
+ private int m_crossingfailures = 0;
+
+ public bool outofBounds = false;
+ private float m_density = 10.000006836f; // Aluminum g/cm3;
+
+
+ public bool _zeroFlag = false;
+ private bool m_lastUpdateSent = false;
+
+ public IntPtr Body = (IntPtr) 0;
+ private String m_primName;
+ private PhysicsVector _target_velocity;
+ public d.Mass pMass;
+
+ private int debugcounter = 0;
+ private bool m_DotMeshCollision = false; // rex
+ public bool m_BoundsScalingUpdate = false; // rex
+ private bool m_PrimVolume = false; // rex
+
+ public OdePrim(String primName, OdeScene parent_scene, PhysicsVector pos, PhysicsVector size,
+ Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
+ {
+ m_localID = localID; // rex
+
+
+ gc = GCHandle.Alloc(prim_geom, GCHandleType.Pinned);
+ ode = dode;
+ _velocity = new PhysicsVector();
+ _position = pos;
+ m_taintposition = pos;
+ if (_position.X > 257)
+ {
+ _position.X = 257;
+ }
+ if (_position.X < 0)
+ {
+ _position.X = 0;
+ }
+ if (_position.Y > 257)
+ {
+ _position.Y = 257;
+ }
+ if (_position.Y < 0)
+ {
+ _position.Y = 0;
+ }
+
+ prim_geom = (IntPtr)0;
+ prev_geom = (IntPtr)0;
+
+ _size = size;
+ m_taintsize = _size;
+ _acceleration = new PhysicsVector();
+ m_rotationalVelocity = PhysicsVector.Zero;
+ _orientation = rotation;
+ m_taintrot = _orientation;
+ _mesh = mesh;
+ _pbs = pbs;
+
+ _parent_scene = parent_scene;
+ m_targetSpace = (IntPtr)0;
+
+ if (pos.Z < 0)
+ m_isphysical = false;
+ else
+ {
+ m_isphysical = pisPhysical;
+ // If we're physical, we need to be in the master space for now.
+ // linksets *should* be in a space together.. but are not currently
+ if (m_isphysical)
+ m_targetSpace = _parent_scene.space;
+ }
+ m_primName = primName;
+ m_taintadd = true;
+ _parent_scene.AddPhysicsActorTaint(this);
+ // don't do .add() here; old geoms get recycled with the same hash
+
+ }
+
+ ///
+ /// Nasty, however without this you get
+ /// 'invalid operation for locked space' when things are really loaded down
+ ///
+ ///
+
+ public override int PhysicsActorType
+ {
+ get
+ {
+ if (m_PrimVolume)
+ return (int)ActorTypes.PrimVolume;
+ else
+ return (int)ActorTypes.Prim;
+ }
+ set
+ {
+ if (value == (int)ActorTypes.PrimVolume)
+ m_PrimVolume = true;
+ else
+ m_PrimVolume = false;
+ }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public void SetGeom(IntPtr geom)
+ {
+ prev_geom = prim_geom;
+ prim_geom = geom;
+ //m_log.Warn("Setting Geom to: " + prim_geom);
+
+ }
+
+ public void enableBody()
+ {
+ // Sets the geom to a body
+ Body = d.BodyCreate(_parent_scene.world);
+
+ setMass();
+ d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.BodySetQuaternion(Body, ref myrot);
+ d.GeomSetBody(prim_geom, Body);
+ d.BodySetAutoDisableFlag(Body, true);
+ d.BodySetAutoDisableSteps(Body, 20);
+
+ m_interpenetrationcount = 0;
+ m_collisionscore = 0;
+ m_disabled = false;
+
+ _parent_scene.addActivePrim(this);
+ }
+
+ private float CalculateMass()
+ {
+ float volume = 0;
+
+ // No material is passed to the physics engines yet.. soo..
+ // we're using the m_density constant in the class definition
+
+
+ float returnMass = 0;
+
+ switch (_pbs.ProfileShape)
+ {
+ case ProfileShape.Square:
+ // Profile Volume
+
+ volume = _size.X*_size.Y*_size.Z;
+
+ // If the user has 'hollowed out'
+ // ProfileHollow is one of those 0 to 50000 values :P
+ // we like percentages better.. so turning into a percentage
+
+ if (((float) _pbs.ProfileHollow/50000f) > 0.0)
+ {
+ float hollowAmount = (float) _pbs.ProfileHollow/50000f;
+
+ // calculate the hollow volume by it's shape compared to the prim shape
+ float hollowVolume = 0;
+ switch (_pbs.HollowShape)
+ {
+ case HollowShape.Square:
+ case HollowShape.Same:
+ // Cube Hollow volume calculation
+ float hollowsizex = _size.X*hollowAmount;
+ float hollowsizey = _size.Y*hollowAmount;
+ float hollowsizez = _size.Z*hollowAmount;
+ hollowVolume = hollowsizex*hollowsizey*hollowsizez;
+ break;
+
+ case HollowShape.Circle:
+ // Hollow shape is a perfect cyllinder in respect to the cube's scale
+ // Cyllinder hollow volume calculation
+ float hRadius = _size.X/2;
+ float hLength = _size.Z;
+
+ // pi * r2 * h
+ hollowVolume = ((float) (Math.PI*Math.Pow(hRadius, 2)*hLength)*hollowAmount);
+ break;
+
+ case HollowShape.Triangle:
+ // Equilateral Triangular Prism volume hollow calculation
+ // Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
+
+ float aLength = _size.Y;
+ // 1/2 abh
+ hollowVolume = (float) ((0.5*aLength*_size.X*_size.Z)*hollowAmount);
+ break;
+
+ default:
+ hollowVolume = 0;
+ break;
+ }
+ volume = volume - hollowVolume;
+ }
+
+ break;
+
+ default:
+ // we don't have all of the volume formulas yet so
+ // use the common volume formula for all
+ volume = _size.X*_size.Y*_size.Z;
+ break;
+ }
+
+ // Calculate Path cut effect on volume
+ // Not exact, in the triangle hollow example
+ // They should never be zero or less then zero..
+ // we'll ignore it if it's less then zero
+
+ // ProfileEnd and ProfileBegin are values
+ // from 0 to 50000
+
+ // Turning them back into percentages so that I can cut that percentage off the volume
+
+ float PathCutEndAmount = _pbs.ProfileEnd;
+ float PathCutStartAmount = _pbs.ProfileBegin;
+ if (((PathCutStartAmount + PathCutEndAmount)/50000f) > 0.0f)
+ {
+ float pathCutAmount = ((PathCutStartAmount + PathCutEndAmount)/50000f);
+
+ // Check the return amount for sanity
+ if (pathCutAmount >= 0.99f)
+ pathCutAmount = 0.99f;
+
+ volume = volume - (volume*pathCutAmount);
+ }
+
+ // Mass = density * volume
+
+ returnMass = m_density*volume;
+
+ return returnMass;
+ }
+
+ public void setMass()
+ {
+ if (Body != (IntPtr) 0)
+ {
+ d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z);
+ d.BodySetMass(Body, ref pMass);
+ }
+ }
+
+
+ public void disableBody()
+ {
+ //this kills the body so things like 'mesh' can re-create it.
+ if (Body != (IntPtr) 0)
+ {
+ _parent_scene.remActivePrim(this);
+ d.BodyDestroy(Body);
+ Body = (IntPtr) 0;
+ }
+ m_disabled = true;
+ m_collisionscore = 0;
+ }
+
+ public void setMesh(OdeScene parent_scene, IMesh mesh)
+ {
+ // This sleeper is there to moderate how long it takes between
+ // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
+
+ System.Threading.Thread.Sleep(10);
+
+ //Kill Body so that mesh can re-make the geom
+ if (IsPhysical && Body != (IntPtr) 0)
+ {
+ disableBody();
+ }
+
+ float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
+ int[] indexList = mesh.getIndexListAsIntLocked(); // Also pinned, needs release after usage
+ int VertexCount = vertexList.GetLength(0)/3;
+ int IndexCount = indexList.GetLength(0);
+
+ // rex, del old trimeshdata
+ if (_triMeshData != (IntPtr)0)
+ d.GeomTriMeshDataDestroy(_triMeshData);
+ _mesh = mesh; // rex, end
+
+ _triMeshData = d.GeomTriMeshDataCreate();
+
+ d.GeomTriMeshDataBuildSimple(_triMeshData, vertexList, 3*sizeof (float), VertexCount, indexList, IndexCount,
+ 3*sizeof (int));
+ d.GeomTriMeshDataPreprocess(_triMeshData);
+
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+
+ try
+ {
+ if (prim_geom == (IntPtr)0)
+ {
+ SetGeom(d.CreateTriMesh(m_targetSpace, _triMeshData, parent_scene.triCallback, null, null));
+ }
+ }
+ catch (System.AccessViolationException)
+ {
+
+ m_log.Error("[PHYSICS]: MESH LOCKED");
+ return;
+ }
+ if (IsPhysical && Body == (IntPtr) 0)
+ {
+ // Recreate the body
+ m_interpenetrationcount = 0;
+ m_collisionscore = 0;
+
+ enableBody();
+
+ }
+ }
+
+ public void ProcessTaints(float timestep)
+ {
+
+
+ if (m_taintadd)
+ {
+ changeadd(timestep);
+ }
+
+ if (m_taintposition != _position)
+ Move(timestep);
+
+ if (m_taintrot != _orientation)
+ rotate(timestep);
+ //
+
+ if (m_taintPhysics != m_isphysical)
+ changePhysicsStatus(timestep);
+ //
+
+ if (m_taintsize != _size)
+ changesize(timestep);
+
+ if (m_BoundsScalingUpdate) // rex
+ changesize(timestep);
+ //
+
+ if (m_taintshape)
+ changeshape(timestep);
+ //
+
+ if (m_taintforce)
+ changeAddForce(timestep);
+
+ if (m_taintdisable)
+ changedisable(timestep);
+
+ if (m_taintVelocity != PhysicsVector.Zero)
+ changevelocity(timestep);
+ }
+
+ public void ResetTaints()
+ {
+
+ m_taintposition = _position;
+
+ m_taintrot = _orientation;
+
+ m_taintPhysics = m_isphysical;
+
+ m_taintsize = _size;
+
+
+ m_taintshape = false;
+
+ m_taintforce = false;
+
+ m_taintdisable = false;
+
+ m_taintVelocity = PhysicsVector.Zero;
+ }
+ public void changeadd(float timestep)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+ int[] iprimspaceArrItem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
+ IntPtr targetspace = _parent_scene.calculateSpaceForGeom(_position);
+
+ if (targetspace == IntPtr.Zero)
+ targetspace = _parent_scene.createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
+
+ m_targetSpace = targetspace;
+
+
+
+ if (_mesh != null)
+ {
+ }
+ else
+ {
+ if (_parent_scene.needsMeshing(_pbs))
+ {
+ // Don't need to re-enable body.. it's done in SetMesh
+ _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size);
+ // createmesh returns null when it's a shape that isn't a cube.
+ }
+ }
+
+ lock (OdeScene.OdeLock)
+ {
+ if (_mesh != null)
+ {
+ setMesh(_parent_scene, _mesh);
+ }
+ else
+ {
+ if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+ {
+ if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+ {
+ if (((_size.X / 2f) > 0f))
+ {
+
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ try
+ {
+ SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+ ode.dunlock(_parent_scene.world);
+ return;
+ }
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ try
+ {
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+ ode.dunlock(_parent_scene.world);
+ return;
+ }
+ }
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ try
+ {
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+ ode.dunlock(_parent_scene.world);
+ return;
+ }
+ }
+ }
+ //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
+ //{
+ //Cyllinder
+ //if (_size.X == _size.Y)
+ //{
+ //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+ //}
+ //else
+ //{
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ //}
+ //}
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ try
+ {
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+ ode.dunlock(_parent_scene.world);
+ return;
+ }
+ }
+ }
+ if (prim_geom != (IntPtr) 0)
+ {
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+
+
+ if (m_isphysical && Body == (IntPtr)0)
+ {
+ enableBody();
+ }
+
+
+ }
+ ode.dunlock(_parent_scene.world);
+ _parent_scene.geom_name_map[prim_geom] = this.m_primName;
+ _parent_scene.actor_name_map[prim_geom] = (PhysicsActor)this;
+ m_taintadd = false;
+
+
+ }
+ public void Move(float timestep)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+
+ if (m_isphysical)
+ {
+ // This is a fallback.. May no longer be necessary.
+ if (Body == (IntPtr) 0)
+ enableBody();
+ //Prim auto disable after 20 frames,
+ //if you move it, re-enable the prim manually.
+
+ d.BodySetPosition(Body, _position.X, _position.Y, _position.Z);
+ d.BodyEnable(Body);
+
+ }
+ else
+ {
+ string primScenAvatarIn = _parent_scene.whichspaceamIin(_position);
+ int[] arrayitem = _parent_scene.calculateSpaceArrayItemFromPos(_position);
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+
+ IntPtr tempspace = _parent_scene.recalculateSpaceForGeom(prim_geom, _position, m_targetSpace);
+ m_targetSpace = tempspace;
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ if (prim_geom != (IntPtr) 0)
+ {
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ d.SpaceAdd(m_targetSpace, prim_geom);
+ }
+ }
+ ode.dunlock(_parent_scene.world);
+
+ resetCollisionAccounting();
+ m_taintposition = _position;
+ }
+
+ // rex, function changed
+ public void rotate(float timestep)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+ d.Quaternion myrot = new d.Quaternion();
+
+ if (m_DotMeshCollision && _mesh != null) // rex, setting rot for collision 3d model
+ {
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+
+ Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
+ Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
+ Quaternion mytemprot = _orientation * meshRotA * meshRotB;
+
+ myrot.W = mytemprot.w;
+ myrot.X = mytemprot.x;
+ myrot.Y = mytemprot.y;
+ myrot.Z = mytemprot.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+ else
+ {
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+
+ if (m_isphysical && Body != (IntPtr) 0)
+ {
+ d.BodySetQuaternion(Body, ref myrot);
+ }
+
+ ode.dunlock(_parent_scene.world);
+
+ resetCollisionAccounting();
+ m_taintrot = _orientation;
+ }
+
+ private void resetCollisionAccounting()
+ {
+ m_collisionscore = 0;
+ m_interpenetrationcount = 0;
+ m_disabled = false;
+ }
+
+ public void changedisable(float timestep)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+ m_disabled = true;
+ if (Body != (IntPtr)0)
+ {
+ d.BodyDisable(Body);
+ Body = (IntPtr)0;
+ }
+ ode.dunlock(_parent_scene.world);
+
+ m_taintdisable = false;
+ }
+
+ public void changePhysicsStatus(float timestap)
+ {
+ lock (ode)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+ if (m_isphysical == true)
+ {
+ if (Body == (IntPtr)0)
+ {
+ enableBody();
+ }
+ }
+ else
+ {
+ if (Body != (IntPtr)0)
+ {
+ disableBody();
+ }
+ }
+
+ ode.dunlock(_parent_scene.world);
+ }
+
+ resetCollisionAccounting();
+ m_taintPhysics = m_isphysical;
+ }
+
+ // rex, function changed
+ public void changesize(float timestamp)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+ //if (!_parent_scene.geom_name_map.ContainsKey(prim_geom))
+ //{
+ // m_taintsize = _size;
+ //return;
+ //}
+ string oldname = _parent_scene.geom_name_map[prim_geom];
+
+
+ // Cleanup of old prim geometry
+ if (_mesh != null)
+ {
+ // Cleanup meshing here
+ }
+ //kill body to rebuild
+ if (IsPhysical && Body != (IntPtr) 0)
+ {
+ disableBody();
+ }
+ if (d.SpaceQuery(m_targetSpace, prim_geom))
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ d.SpaceRemove(m_targetSpace, prim_geom);
+ }
+ d.GeomDestroy(prim_geom);
+ prim_geom = (IntPtr)0;
+ // we don't need to do space calculation because the client sends a position update also.
+
+ if (m_DotMeshCollision && _mesh != null) // rex, scaling dotmesh models
+ {
+ float[] scalefactor = new float[3];
+ int vertindex = 0;
+ OdeCollisionMesh mesh = _mesh as OdeCollisionMesh;
+
+ LLVector3 scalingvector = new LLVector3(_size.X, _size.Y, _size.Z);
+ if (mesh.m_BoundsScaling)
+ {
+ LLVector3 boundssize = mesh.BoundsMax - mesh.BoundsMin;
+ if (boundssize.X != 0)
+ scalingvector.X /= boundssize.X;
+ if (boundssize.Y != 0)
+ scalingvector.Z /= boundssize.Y;
+ if (boundssize.Z != 0)
+ scalingvector.Y /= boundssize.Z;
+ }
+ scalefactor[0] = scalingvector.X;
+ scalefactor[1] = scalingvector.Z;
+ scalefactor[2] = scalingvector.Y;
+
+ for (int i = 0; i < mesh.vertexList.GetLength(0); i++)
+ {
+ mesh.vertexList[i] = mesh.vertexListOrig[i] * scalefactor[vertindex];
+ vertindex++;
+ if (vertindex > 2)
+ vertindex = 0;
+ }
+
+ for (int i = 0; i < mesh.indexList.GetLength(0); i++)
+ mesh.indexList[i] = mesh.indexListOrig[i];
+
+ setMesh(_parent_scene, mesh);
+
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+
+ Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
+ Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
+ Quaternion mytemprot = _orientation * meshRotA * meshRotB;
+
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = mytemprot.w;
+ myrot.X = mytemprot.x;
+ myrot.Y = mytemprot.y;
+ myrot.Z = mytemprot.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+ if (IsPhysical && Body == (IntPtr)0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ } // rex, end scaling
+ // Construction of new prim
+ else if (_parent_scene.needsMeshing(_pbs))
+ {
+ // Don't need to re-enable body.. it's done in SetMesh
+ IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
+ // createmesh returns null when it's a shape that isn't a cube.
+ if (mesh != null)
+ {
+ setMesh(_parent_scene, mesh);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+ //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
+ if (IsPhysical && Body == (IntPtr)0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ }
+ else
+ {
+ if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+ {
+ if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+ {
+ if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ }
+ else
+ {
+ m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ }
+ //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
+ //{
+ //Cyllinder
+ //if (_size.X == _size.Y)
+ //{
+ // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+ //}
+ //else
+ //{
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ //}
+ //}
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+ }
+ else
+ {
+ if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+ {
+ if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ }
+ //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
+ //{
+ //Cyllinder
+ //if (_size.X == _size.Y)
+ //{
+ //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+ //}
+ //else
+ //{
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ //}
+ //}
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+ //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
+ if (IsPhysical && Body == (IntPtr) 0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ }
+
+ _parent_scene.geom_name_map[prim_geom] = oldname;
+
+ ode.dunlock(_parent_scene.world);
+
+ resetCollisionAccounting();
+ m_taintsize = _size;
+ m_BoundsScalingUpdate = false; // rex
+ }
+
+ public void changeshape(float timestamp)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+
+ string oldname = _parent_scene.geom_name_map[prim_geom];
+
+ // Cleanup of old prim geometry and Bodies
+ if (IsPhysical && Body != (IntPtr) 0)
+ {
+ disableBody();
+ }
+ d.GeomDestroy(prim_geom);
+ prim_geom = (IntPtr) 0;
+ // we don't need to do space calculation because the client sends a position update also.
+
+ // Construction of new prim
+ if (_parent_scene.needsMeshing(_pbs))
+ {
+ // Don't need to re-enable body.. it's done in SetMesh
+ IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
+ // createmesh returns null when it's a shape that isn't a cube.
+ if (mesh != null)
+ {
+ setMesh(_parent_scene, mesh);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+ //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
+ if (IsPhysical && Body == (IntPtr)0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ }
+ else
+ {
+ if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+ {
+ if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+ {
+ if (((_size.X / 2f) > 0f) && ((_size.X / 2f) < 1000))
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ }
+ else
+ {
+ m_log.Info("[PHYSICS]: Failed to load a sphere bad size");
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ }
+ //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
+ //{
+ //Cyllinder
+ //if (_size.X == _size.Y)
+ //{
+ // prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+ //}
+ //else
+ //{
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ //}
+ //}
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+ }
+ else
+ {
+ if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+ {
+ if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateSphere(m_targetSpace, _size.X / 2));
+ }
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ }
+ //else if (_pbs.ProfileShape == ProfileShape.Circle && _pbs.PathCurve == (byte)Extrusion.Straight)
+ //{
+ //Cyllinder
+ //if (_size.X == _size.Y)
+ //{
+ //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+ //}
+ //else
+ //{
+ //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ //}
+ //}
+ else
+ {
+ _parent_scene.waitForSpaceUnlock(m_targetSpace);
+ SetGeom(d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z));
+ }
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+ //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
+ if (IsPhysical && Body == (IntPtr)0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ }
+ _parent_scene.geom_name_map[prim_geom] = oldname;
+
+ ode.dunlock(_parent_scene.world);
+
+ resetCollisionAccounting();
+ m_taintshape = false;
+ }
+
+ public void changeAddForce(float timestamp)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+
+ lock (m_forcelist)
+ {
+ //m_log.Info("[PHYSICS]: dequeing forcelist");
+ if (IsPhysical)
+ {
+ PhysicsVector iforce = new PhysicsVector();
+ for (int i = 0; i < m_forcelist.Count; i++)
+ {
+ iforce = iforce + (m_forcelist[i]*100);
+ }
+ d.BodyEnable(Body);
+ d.BodyAddForce(Body, iforce.X, iforce.Y, iforce.Z);
+ }
+ m_forcelist.Clear();
+ }
+
+ ode.dunlock(_parent_scene.world);
+
+ m_collisionscore = 0;
+ m_interpenetrationcount = 0;
+ m_taintforce = false;
+
+ }
+ private void changevelocity(float timestep)
+ {
+ lock (ode)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(_parent_scene.world);
+
+ System.Threading.Thread.Sleep(20);
+ if (IsPhysical)
+ {
+ if (Body != (IntPtr)0)
+ {
+ d.BodySetLinearVel(Body, m_taintVelocity.X, m_taintVelocity.Y, m_taintVelocity.Z);
+ }
+ }
+
+ ode.dunlock(_parent_scene.world);
+ }
+ //resetCollisionAccounting();
+ m_taintVelocity = PhysicsVector.Zero;
+ }
+ public override bool IsPhysical
+ {
+ get { return m_isphysical; }
+ set { m_isphysical = value; }
+ }
+
+ public void setPrimForRemoval()
+ {
+ m_taintremove = true;
+ }
+
+ public override bool Flying
+ {
+ get { return false; //no flying prims for you
+ }
+ set { }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return m_throttleUpdates; }
+ set { m_throttleUpdates = value; }
+ }
+
+ public override bool Stopped
+ {
+ get { return _zeroFlag; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+
+ set { _position = value;
+ //m_log.Info("[PHYSICS]: " + _position.ToString());
+ }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ public override float Mass
+ {
+ get { return CalculateMass(); }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set {
+
+ _pbs = value;
+ m_taintshape = true;
+ }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get
+ {
+ // Averate previous velocity with the new one so
+ // client object interpolation works a 'little' better
+ PhysicsVector returnVelocity = new PhysicsVector();
+ returnVelocity.X = (m_lastVelocity.X + _velocity.X)/2;
+ returnVelocity.Y = (m_lastVelocity.Y + _velocity.Y)/2;
+ returnVelocity.Z = (m_lastVelocity.Z + _velocity.Z)/2;
+ return returnVelocity;
+ }
+ set {
+ _velocity = value;
+
+ m_taintVelocity = value;
+ _parent_scene.AddPhysicsActorTaint(this);
+
+
+ }
+ }
+
+ public override float CollisionScore
+ {
+ get { return m_collisionscore; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return _orientation; }
+ set { _orientation = value; }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ m_forcelist.Add(force);
+ m_taintforce = true;
+ //m_log.Info("[PHYSICS]: Added Force:" + force.ToString() + " to prim at " + Position.ToString());
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get {
+ PhysicsVector pv = new PhysicsVector(0, 0, 0);
+ if (_zeroFlag)
+ return pv;
+ m_lastUpdateSent = false;
+
+ if (m_rotationalVelocity.IsIdentical(pv, 0.2f))
+ return pv;
+
+ return m_rotationalVelocity;
+ }
+ set { m_rotationalVelocity = value; }
+ }
+ public override void CrossingFailure()
+ {
+ m_crossingfailures++;
+ if (m_crossingfailures > 5)
+ {
+ base.RaiseOutOfBounds(_position);
+ return;
+
+ }
+ else if (m_crossingfailures == 5)
+ {
+ m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
+ }
+ }
+ public void UpdatePositionAndVelocity()
+ {
+ // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
+ PhysicsVector pv = new PhysicsVector(0, 0, 0);
+ if (Body != (IntPtr) 0)
+ {
+ d.Vector3 vec = d.BodyGetPosition(Body);
+ d.Quaternion ori = d.BodyGetQuaternion(Body);
+ d.Vector3 vel = d.BodyGetLinearVel(Body);
+ d.Vector3 rotvel = d.BodyGetAngularVel(Body);
+
+ PhysicsVector l_position = new PhysicsVector();
+
+
+ // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
+ //if (vec.X < 0.0f) { vec.X = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
+ //if (vec.Y < 0.0f) { vec.Y = 0.0f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
+ //if (vec.X > 255.95f) { vec.X = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
+ //if (vec.Y > 255.95f) { vec.Y = 255.95f; if (Body != (IntPtr)0) d.BodySetAngularVel(Body, 0, 0, 0); }
+
+ m_lastposition = _position;
+
+ l_position.X = vec.X;
+ l_position.Y = vec.Y;
+ l_position.Z = vec.Z;
+
+ if (l_position.X > 255.95f || l_position.X < 0f || l_position.Y > 255.95f || l_position.Y < 0f)
+ {
+ base.RaiseOutOfBounds(_position);
+ }
+ //if (m_crossingfailures < 5)
+ //{
+ //base.RequestPhysicsterseUpdate();
+ //}
+ //}
+
+ if (l_position.Z < 0)
+ {
+ // This is so prim that get lost underground don't fall forever and suck up
+ //
+ // Sim resources and memory.
+ // Disables the prim's movement physics....
+ // It's a hack and will generate a console message if it fails.
+
+
+ //IsPhysical = false;
+ base.RaiseOutOfBounds(_position);
+ _velocity.X = 0;
+ _velocity.Y = 0;
+ _velocity.Z = 0;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
+ base.RequestPhysicsterseUpdate();
+ m_throttleUpdates = false;
+ throttleCounter = 0;
+ _zeroFlag = true;
+ //outofBounds = true;
+ }
+
+ if ((Math.Abs(m_lastposition.X - l_position.X) < 0.02)
+ && (Math.Abs(m_lastposition.Y - l_position.Y) < 0.02)
+ && (Math.Abs(m_lastposition.Z - l_position.Z) < 0.02))
+ {
+ _zeroFlag = true;
+ m_throttleUpdates = false;
+ }
+ else
+ {
+ //System.Console.WriteLine(Math.Abs(m_lastposition.X - l_position.X).ToString());
+ _zeroFlag = false;
+ }
+
+
+ if (_zeroFlag)
+ {
+ // Supposedly this is supposed to tell SceneObjectGroup that
+ // no more updates need to be sent..
+ // but it seems broken.
+ _velocity.X = 0.0f;
+ _velocity.Y = 0.0f;
+ _velocity.Z = 0.0f;
+ //_orientation.w = 0f;
+ //_orientation.x = 0f;
+ //_orientation.y = 0f;
+ //_orientation.z = 0f;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
+ if (!m_lastUpdateSent)
+ {
+ m_throttleUpdates = false;
+ throttleCounter = 0;
+ m_rotationalVelocity = pv;
+ base.RequestPhysicsterseUpdate();
+ m_lastUpdateSent = true;
+ }
+ }
+ else
+ {
+ m_lastVelocity = _velocity;
+
+ _position = l_position;
+
+ _velocity.X = vel.X;
+ _velocity.Y = vel.Y;
+ _velocity.Z = vel.Z;
+ if (_velocity.IsIdentical(pv, 0.5f))
+ {
+ m_rotationalVelocity = pv;
+ }
+ else
+ {
+ m_rotationalVelocity.setValues(rotvel.X, rotvel.Y, rotvel.Z);
+ }
+
+ //System.Console.WriteLine("ODE: " + m_rotationalVelocity.ToString());
+ _orientation.w = ori.W;
+ _orientation.x = ori.X;
+ _orientation.y = ori.Y;
+ _orientation.z = ori.Z;
+ m_lastUpdateSent = false;
+ if (!m_throttleUpdates || throttleCounter > 15)
+ {
+
+ base.RequestPhysicsterseUpdate();
+ }
+ else
+ {
+ throttleCounter++;
+ }
+ }
+ m_lastposition = l_position;
+ }
+ else
+ {
+ // Not a body.. so Make sure the client isn't interpolating
+ _velocity.X = 0;
+ _velocity.Y = 0;
+ _velocity.Z = 0;
+ m_rotationalVelocity.X = 0;
+ m_rotationalVelocity.Y = 0;
+ m_rotationalVelocity.Z = 0;
+ _zeroFlag = true;
+ }
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+
+ // rex, new function.
+ // This function should be called only outside of simulation loop -> OdeLock used.
+ public override void SetCollisionMesh(byte[] vData, string MeshName, bool vbScaleMesh)
+ {
+ float[] tempVertexList;
+ float[] tempBounds;
+ int[] tempIndexList;
+ string errorMessage;
+ float[] scalefactor = new float[3];
+ int vertindex = 0;
+
+ lock (OdeScene.OdeLock)
+ {
+ // 1. Get rid of old mesh
+ m_DotMeshCollision = false;
+ if (_mesh != null)
+ {
+ if ((OdeCollisionMesh)_mesh != null)
+ (_mesh as OdeCollisionMesh).FreeLists();
+
+ _mesh = null;
+ }
+
+ // 2. Try to load new colmesh
+ OdeCollisionMesh mesh = null;
+ if (vData != null)
+ {
+ DotMeshLoader.ReadDotMeshModel(vData, out tempVertexList, out tempIndexList, out tempBounds, out errorMessage);
+
+ if (tempVertexList != null && tempIndexList != null)
+ {
+ mesh = new OdeCollisionMesh(tempVertexList.GetLength(0), tempIndexList.GetLength(0));
+ mesh.m_BoundsScaling = vbScaleMesh;
+ mesh.BoundsMin.X = tempBounds[0];
+ mesh.BoundsMin.Y = tempBounds[1];
+ mesh.BoundsMin.Z = tempBounds[2];
+ mesh.BoundsMax.X = tempBounds[3];
+ mesh.BoundsMax.Y = tempBounds[4];
+ mesh.BoundsMax.Z = tempBounds[5];
+
+ LLVector3 scalingvector = new LLVector3(_size.X, _size.Y, _size.Z);
+ if (vbScaleMesh)
+ {
+ LLVector3 boundssize = mesh.BoundsMax - mesh.BoundsMin;
+ if (boundssize.X != 0)
+ scalingvector.X /= boundssize.X;
+ if (boundssize.Y != 0)
+ scalingvector.Z /= boundssize.Y;
+ if (boundssize.Z != 0)
+ scalingvector.Y /= boundssize.Z;
+ }
+
+ scalefactor[0] = scalingvector.X;
+ scalefactor[1] = scalingvector.Z;
+ scalefactor[2] = scalingvector.Y;
+ for (int i = 0; i < tempVertexList.GetLength(0); i++)
+ {
+ mesh.vertexListOrig[i] = tempVertexList[i];
+ mesh.vertexList[i] = tempVertexList[i] * scalefactor[vertindex];
+
+ vertindex++;
+ if (vertindex > 2)
+ vertindex = 0;
+ }
+
+ for (int i = 0; i < tempIndexList.GetLength(0); i++)
+ {
+ mesh.indexListOrig[i] = tempIndexList[i];
+ mesh.indexList[i] = tempIndexList[i];
+ }
+
+
+ }
+ else
+ MainLog.Instance.Error("PHYSICS", "Error importing mesh:" + MeshName + ", " + errorMessage);
+ }
+
+ // 3. If mesh is null, must create the default collisionbox
+ if (mesh == null)
+ {
+ CreateDefaultCollision();
+ return;
+ }
+
+ // 4. If mesh loaded, use it
+ string oldname = _parent_scene.geom_name_map[prim_geom];
+ m_DotMeshCollision = true;
+
+ if (IsPhysical && Body != (IntPtr)0)
+ disableBody();
+
+ if (prim_geom != (IntPtr)0)
+ {
+ if (d.SpaceQuery(m_targetSpace, prim_geom))
+ {
+ d.SpaceRemove(m_targetSpace, prim_geom);
+ }
+ d.GeomDestroy(prim_geom);
+ }
+
+ setMesh(_parent_scene, mesh);
+
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+
+ Quaternion meshRotA = Quaternion.FromAngleAxis((float)(Math.PI * 0.5), new Vector3(1, 0, 0));
+ Quaternion meshRotB = Quaternion.FromAngleAxis((float)(Math.PI), new Vector3(0, 1, 0));
+ Quaternion mytemprot = _orientation * meshRotA * meshRotB;
+
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = mytemprot.w;
+ myrot.X = mytemprot.x;
+ myrot.Y = mytemprot.y;
+ myrot.Z = mytemprot.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+ _parent_scene.geom_name_map[prim_geom] = oldname;
+ }
+ }
+
+
+
+
+
+ // rex, function added
+ private void CreateDefaultCollision()
+ {
+ string oldname = _parent_scene.geom_name_map[prim_geom];
+
+ // Cleanup of old prim geometry
+ if (_mesh != null)
+ {
+ // Cleanup meshing here
+ }
+ //kill body to rebuild
+ if (IsPhysical && Body != (IntPtr)0)
+ {
+ disableBody();
+ }
+ if (d.SpaceQuery(m_targetSpace, prim_geom))
+ {
+ d.SpaceRemove(m_targetSpace, prim_geom);
+ }
+ d.GeomDestroy(prim_geom);
+
+ // we don't need to do space calculation because the client sends a position update also.
+ // Construction of new prim
+ if (_parent_scene.needsMeshing(_pbs))
+ {
+ // Don't need to re-enable body.. it's done in SetMesh
+ IMesh mesh = _parent_scene.mesher.CreateMesh(oldname, _pbs, _size);
+ // createmesh returns null when it's a shape that isn't a cube.
+ if (mesh != null)
+ {
+ setMesh(_parent_scene, mesh);
+ }
+ else
+ {
+ prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+ }
+ }
+ else
+ {
+ prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+ d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+ d.Quaternion myrot = new d.Quaternion();
+ myrot.W = _orientation.w;
+ myrot.X = _orientation.x;
+ myrot.Y = _orientation.y;
+ myrot.Z = _orientation.z;
+ d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+ //d.GeomBoxSetLengths(prim_geom, _size.X, _size.Y, _size.Z);
+ if (IsPhysical && Body == (IntPtr)0)
+ {
+ // Re creates body on size.
+ // EnableBody also does setMass()
+ enableBody();
+ d.BodyEnable(Body);
+ }
+ }
+ _parent_scene.geom_name_map[prim_geom] = oldname;
+ }
+
+ // rex, new function
+ public override void SetBoundsScaling(bool vbScaleMesh)
+ {
+ if (m_DotMeshCollision && _mesh != null)
+ {
+ (_mesh as OdeCollisionMesh).m_BoundsScaling = vbScaleMesh;
+ m_BoundsScalingUpdate = true;
+ }
+ }
+
+
+
+
+ }
+}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index f173a2a143..4e8945047c 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -1,1224 +1,1712 @@
-/*
-* 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 OpenSim 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.Runtime.InteropServices;
-using Axiom.Math;
-using Ode.NET;
-using OpenSim.Framework;
-using OpenSim.Framework.Console;
-using OpenSim.Region.Physics.Manager;
-
-//using OpenSim.Region.Physics.OdePlugin.Meshing;
-
-namespace OpenSim.Region.Physics.OdePlugin
-{
- ///
- /// ODE plugin
- ///
- public class OdePlugin : IPhysicsPlugin
- {
- private OdeScene _mScene;
-
- public OdePlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene()
- {
- if (_mScene == null)
- {
- _mScene = new OdeScene();
- }
- return (_mScene);
- }
-
- public string GetName()
- {
- return ("OpenDynamicsEngine");
- }
-
- public void Dispose()
- {
- }
- }
-
- public class OdeScene : PhysicsScene
- {
- // TODO: this should be hard-coded in some common place
- private const uint m_regionWidth = 256;
- private const uint m_regionHeight = 256;
-
- private static float ODE_STEPSIZE = 0.004f;
- private static bool RENDER_FLAG = false;
- private static float metersInSpace = 29.9f;
- private IntPtr contactgroup;
- private IntPtr LandGeom = (IntPtr) 0;
- private double[] _heightmap;
- private GCHandle gchHeightMap; // rex
- private d.NearCallback nearCallback;
- public d.TriCallback triCallback;
- public d.TriArrayCallback triArrayCallback;
- private List _characters = new List();
- private List _prims = new List();
- private List _activeprims = new List();
- private List _taintedPrim = new List();
- public Dictionary geom_name_map = new Dictionary();
- public Dictionary actor_name_map = new Dictionary();
- private d.ContactGeom[] contacts = new d.ContactGeom[30];
- private d.Contact contact;
- private d.Contact TerrainContact;
- private d.Contact AvatarMovementprimContact;
- private d.Contact AvatarMovementTerrainContact;
-
- private int m_physicsiterations = 10;
- private float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
- private PhysicsActor PANull = new NullPhysicsActor();
- private float step_time = 0.0f;
- public IntPtr world;
-
- public IntPtr space;
- // split static geometry collision handling into spaces of 30 meters
- public IntPtr[,] staticPrimspace = new IntPtr[(int) (300/metersInSpace),(int) (300/metersInSpace)];
-
- public static Object OdeLock = new Object();
-
- public IMesher mesher;
-
- public OdeScene()
- {
- nearCallback = near;
- triCallback = TriCallback;
- triArrayCallback = TriArrayCallback;
- /*
- contact.surface.mode |= d.ContactFlags.Approx1 | d.ContactFlags.SoftCFM | d.ContactFlags.SoftERP;
- contact.surface.mu = 10.0f;
- contact.surface.bounce = 0.9f;
- contact.surface.soft_erp = 0.005f;
- contact.surface.soft_cfm = 0.00003f;
- */
-
- contact.surface.mu = 250.0f;
- contact.surface.bounce = 0.2f;
-
- TerrainContact.surface.mode |= d.ContactFlags.SoftERP;
- TerrainContact.surface.mu = 550.0f;
- TerrainContact.surface.bounce = 0.1f;
- TerrainContact.surface.soft_erp = 0.1025f;
-
- AvatarMovementprimContact.surface.mu = 150.0f;
- AvatarMovementprimContact.surface.bounce = 0.1f;
-
- AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP;
- AvatarMovementTerrainContact.surface.mu = 150.0f;
- AvatarMovementTerrainContact.surface.bounce = 0.1f;
- AvatarMovementTerrainContact.surface.soft_erp = 0.1025f;
-
- lock (OdeLock)
- {
- world = d.WorldCreate();
- space = d.HashSpaceCreate(IntPtr.Zero);
- d.HashSpaceSetLevels(space, -4, 128);
- contactgroup = d.JointGroupCreate(0);
- //contactgroup
-
-
- d.WorldSetGravity(world, 0.0f, 0.0f, -10.0f);
- d.WorldSetAutoDisableFlag(world, false);
- d.WorldSetContactSurfaceLayer(world, 0.001f);
- d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
- d.WorldSetContactMaxCorrectingVel(world, 1000.0f);
- }
-
- _heightmap = new double[514*514];
- gchHeightMap = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); // rex
-
- for (int i = 0; i < staticPrimspace.GetLength(0); i++)
- {
- for (int j = 0; j < staticPrimspace.GetLength(1); j++)
- {
- staticPrimspace[i, j] = IntPtr.Zero;
- }
- }
- }
-
- public override void Initialise(IMesher meshmerizer)
- {
- mesher = meshmerizer;
- }
-
- public string whichspaceamIin(PhysicsVector pos)
- {
- return calculateSpaceForGeom(pos).ToString();
- }
-
- private void near(IntPtr space, IntPtr g1, IntPtr g2)
- {
- // no lock here! It's invoked from within Simulate(), which is thread-locked
- if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
- {
- // Separating static prim geometry spaces.
- // We'll be calling near recursivly if one
- // of them is a space to find all of the
- // contact points in the space
-
- d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
- //Colliding a space or a geom with a space or a geom.
-
- //Collide all geoms in each space..
- //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
- //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
- }
- else
- {
- // Colliding Geom To Geom
- // This portion of the function 'was' blatantly ripped off from BoxStack.cs
-
- IntPtr b1 = d.GeomGetBody(g1);
- IntPtr b2 = d.GeomGetBody(g2);
-
- if (g1 == g2)
- return; // Can't collide with yourself
-
- if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
- return;
-
- d.GeomClassID id = d.GeomGetClass(g1);
-
- String name1 = null;
- String name2 = null;
-
- if (!geom_name_map.TryGetValue(g1, out name1))
- {
- name1 = "null";
- }
- if (!geom_name_map.TryGetValue(g2, out name2))
- {
- name2 = "null";
- }
-
- if (id == d.GeomClassID.TriMeshClass)
- {
- // MainLog.Instance.Verbose("near: A collision was detected between {1} and {2}", 0, name1, name2);
- //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
- }
-
- int count = 0;
- try
- {
- count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
- }
- catch (SEHException)
- {
- MainLog.Instance.Error("PHYSICS",
- "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.");
- base.TriggerPhysicsBasedRestart();
- }
-
- for (int i = 0; i < count; i++)
- {
- IntPtr joint;
- // If we're colliding with terrain, use 'TerrainContact' instead of contact.
- // allows us to have different settings
- PhysicsActor p1;
- PhysicsActor p2;
-
- if (!actor_name_map.TryGetValue(g1, out p1))
- {
- p1 = PANull;
- }
- if (!actor_name_map.TryGetValue(g2, out p2))
- {
- p2 = PANull;
- }
-
- // We only need to test p2 for 'jump crouch purposes'
- p2.IsColliding = true;
-
-
- switch (p1.PhysicsActorType)
- {
- case (int) ActorTypes.Agent:
- p2.CollidingObj = true;
- break;
- case (int) ActorTypes.Prim:
- if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
- p2.CollidingObj = true;
- break;
- case (int) ActorTypes.Unknown:
- p2.CollidingGround = true;
- break;
- case (int)ActorTypes.PrimVolume: // rex, added primvolume
- if (Util.UnixTimeSinceEpoch() > p2.NextPrimVolumeTime)
- {
- p2.NextPrimVolumeTime = Util.UnixTimeSinceEpoch() + 1;
- p1.SendCollisionUpdate(new CollisionEventUpdate(p2.m_localID,0,true,null));
- }
- return;
- default:
- p2.CollidingGround = true;
- break;
- }
- // we don't want prim or avatar to explode
-
- #region InterPenetration Handling - Unintended physics explosions
-
- if (contacts[i].depth >= 0.08f)
- {
- if (contacts[i].depth >= 1.00f)
- {
- //MainLog.Instance.Debug("PHYSICS",contacts[i].depth.ToString());
- }
- // If you interpenetrate a prim with an agent
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
- p1.PhysicsActorType == (int) ActorTypes.Prim) ||
- (p1.PhysicsActorType == (int) ActorTypes.Agent &&
- p2.PhysicsActorType == (int) ActorTypes.Prim))
- {
- if (p2.PhysicsActorType == (int) ActorTypes.Agent)
- {
- //p2.CollidingObj = true;
- //contacts[i].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));
-
- }
- else
- {
-
- //contacts[i].depth = 0.0000000f;
- }
- if (p1.PhysicsActorType == (int) ActorTypes.Agent)
- {
-
- //p1.CollidingObj = true;
- //contacts[i].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));
- //OdeCharacter character = (OdeCharacter)p1;
- //character.SetPidStatus(true);
- }
- else
- {
-
- //contacts[i].depth = 0.0000000f;
- }
- }
- // If you interpenetrate a prim with another prim
- if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
- {
- // Don't collide, one or both prim will explode.
- contacts[i].depth = 0f;
- }
- if (contacts[i].depth >= 1.00f)
- {
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
- p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
- (p1.PhysicsActorType == (int) ActorTypes.Agent &&
- p2.PhysicsActorType == (int) ActorTypes.Unknown))
- {
- if (p2.PhysicsActorType == (int) ActorTypes.Agent)
- {
- OdeCharacter character = (OdeCharacter) p2;
-
- //p2.CollidingObj = true;
- contacts[i].depth = 0.003f;
- p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 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));
- character.SetPidStatus(true);
- }
- else
- {
- }
- if (p1.PhysicsActorType == (int) ActorTypes.Agent)
- {
- OdeCharacter character = (OdeCharacter)p1;
-
- //p2.CollidingObj = true;
- contacts[i].depth = 0.003f;
- p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 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));
- character.SetPidStatus(true);
- }
- else
- {
- //contacts[i].depth = 0.0000000f;
- }
- }
- }
- }
-
- #endregion
-
- if (contacts[i].depth >= 0f)
- {
- if (name1 == "Terrain" || name2 == "Terrain")
- {
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
- (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
- {
- AvatarMovementTerrainContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
- }
- else
- {
- TerrainContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
- }
- }
- else
- {
- if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
- (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
- {
- AvatarMovementprimContact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
- }
- else
- {
- contact.geom = contacts[i];
- joint = d.JointCreateContact(world, contactgroup, ref contact);
- }
- }
- d.JointAttach(joint, b1, b2);
- }
-
- if (count > 3)
- {
- p2.ThrottleUpdates = true;
- }
- //System.Console.WriteLine(count.ToString());
- //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
- }
- }
- }
-
- private void collision_optimized(float timeStep)
- {
- foreach (OdeCharacter chr in _characters)
- {
- chr.IsColliding = false;
- chr.CollidingGround = false;
- chr.CollidingObj = false;
- d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
- }
- // If the sim is running slow this frame,
- // don't process collision for prim!
- if (timeStep < (m_SkipFramesAtms/3))
- {
- foreach (OdePrim chr in _activeprims)
- {
- // This if may not need to be there.. it might be skipped anyway.
- if (d.BodyIsEnabled(chr.Body))
- {
- d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback);
- //foreach (OdePrim ch2 in _prims)
- /// should be a separate space -- lots of avatars will be N**2 slow
- //{
- //if (ch2.IsPhysical && d.BodyIsEnabled(ch2.Body))
- //{
- // Only test prim that are 0.03 meters away in one direction.
- // This should be Optimized!
-
- //if ((Math.Abs(ch2.Position.X - chr.Position.X) < 0.03) || (Math.Abs(ch2.Position.Y - chr.Position.Y) < 0.03) || (Math.Abs(ch2.Position.X - chr.Position.X) < 0.03))
- //{
- //d.SpaceCollide2(chr.prim_geom, ch2.prim_geom, IntPtr.Zero, nearCallback);
- //}
- //}
- //}
- }
- }
- }
- else
- {
- // Everything is going slow, so we're skipping object to object collisions
- // At least collide test against the ground.
- foreach (OdePrim chr in _activeprims)
- {
- // This if may not need to be there.. it might be skipped anyway.
- if (d.BodyIsEnabled(chr.Body))
- {
- d.SpaceCollide2(LandGeom, chr.prim_geom, IntPtr.Zero, nearCallback);
- }
- }
- }
- }
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID) // rex, localid
- {
- PhysicsVector pos = new PhysicsVector();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z;
- OdeCharacter newAv = new OdeCharacter(avName, this, pos, localID); // rex, localid
- _characters.Add(newAv);
-
- return newAv;
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- lock (OdeLock)
- {
- ((OdeCharacter) actor).Destroy();
- _characters.Remove((OdeCharacter) actor);
- }
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- if (prim is OdePrim)
- {
- lock (OdeLock)
- {
- OdePrim p = (OdePrim) prim;
-
- p.setPrimForRemoval();
- AddPhysicsActorTaint(prim);
- }
- }
- }
-
- public void RemovePrimThreadLocked(OdePrim prim)
- {
- lock (OdeLock)
- {
- if (prim.IsPhysical)
- {
- prim.disableBody();
- }
- // we don't want to remove the main space
- if (prim.m_targetSpace != space && prim.IsPhysical == false)
- {
- // If the geometry is in the targetspace, remove it from the target space
- if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
- {
- if (!(prim.m_targetSpace.Equals(null)))
- {
- if (d.GeomIsSpace(prim.m_targetSpace))
- {
- d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'removeprim from scene':" +
- ((OdePrim) prim).m_targetSpace.ToString());
- }
- }
- }
-
-
- //If there are no more geometries in the sub-space, we don't need it in the main space anymore
- if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
- {
- if (!(prim.m_targetSpace.Equals(null)))
- {
- if (d.GeomIsSpace(prim.m_targetSpace))
- {
- d.SpaceRemove(space, prim.m_targetSpace);
- // free up memory used by the space.
- d.SpaceDestroy(prim.m_targetSpace);
- int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
- resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'removeprim from scene':" +
- ((OdePrim) prim).m_targetSpace.ToString());
- }
- }
- }
- }
-
- d.GeomDestroy(prim.prim_geom);
-
- _prims.Remove(prim);
- }
- }
-
- public void resetSpaceArrayItemToZero(IntPtr space)
- {
- for (int x = 0; x < staticPrimspace.GetLength(0); x++)
- {
- for (int y = 0; y < staticPrimspace.GetLength(1); y++)
- {
- if (staticPrimspace[x, y] == space)
- staticPrimspace[x, y] = IntPtr.Zero;
- }
- }
- }
-
- public void resetSpaceArrayItemToZero(int arrayitemX, int arrayitemY)
- {
- staticPrimspace[arrayitemX, arrayitemY] = IntPtr.Zero;
- }
-
- public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos, IntPtr currentspace)
- {
- //Todo recalculate space the prim is in.
- // Called from setting the Position and Size of an ODEPrim so
- // it's already in locked space.
-
- // we don't want to remove the main space
- // we don't need to test physical here because this function should
- // never be called if the prim is physical(active)
- if (currentspace != space)
- {
- if (d.SpaceQuery(currentspace, geom) && currentspace != (IntPtr) 0)
- {
- if (d.GeomIsSpace(currentspace))
- {
- d.SpaceRemove(currentspace, geom);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'recalculatespace':" + currentspace.ToString() +
- " Geom:" + geom.ToString());
- }
- }
- else
- {
- IntPtr sGeomIsIn = d.GeomGetSpace(geom);
- if (!(sGeomIsIn.Equals(null)))
- {
- if (sGeomIsIn != (IntPtr) 0)
- {
- if (d.GeomIsSpace(currentspace))
- {
- d.SpaceRemove(sGeomIsIn, geom);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'recalculatespace':" +
- sGeomIsIn.ToString() + " Geom:" + geom.ToString());
- }
- }
- }
- }
-
-
- //If there are no more geometries in the sub-space, we don't need it in the main space anymore
- if (d.SpaceGetNumGeoms(currentspace) == 0)
- {
- if (currentspace != (IntPtr) 0)
- {
- if (d.GeomIsSpace(currentspace))
- {
- d.SpaceRemove(space, currentspace);
- // free up memory used by the space.
- d.SpaceDestroy(currentspace);
- resetSpaceArrayItemToZero(currentspace);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'recalculatespace':" +
- currentspace.ToString() + " Geom:" + geom.ToString());
- }
- }
- }
- }
- else
- {
- // this is a physical object that got disabled. ;.;
- if (d.SpaceQuery(currentspace, geom))
- {
- if (currentspace != (IntPtr) 0)
- if (d.GeomIsSpace(currentspace))
- {
- d.SpaceRemove(currentspace, geom);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'recalculatespace':" +
- currentspace.ToString() + " Geom:" + geom.ToString());
- }
- }
- else
- {
- IntPtr sGeomIsIn = d.GeomGetSpace(geom);
- if (!(sGeomIsIn.Equals(null)))
- {
- if (sGeomIsIn != (IntPtr) 0)
- {
- if (d.GeomIsSpace(sGeomIsIn))
- {
- d.SpaceRemove(sGeomIsIn, geom);
- }
- else
- {
- MainLog.Instance.Verbose("Physics",
- "Invalid Scene passed to 'recalculatespace':" +
- sGeomIsIn.ToString() + " Geom:" + geom.ToString());
- }
- }
- }
- }
- }
-
-
- // The routines in the Position and Size sections do the 'inserting' into the space,
- // so all we have to do is make sure that the space that we're putting the prim into
- // is in the 'main' space.
- int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
- IntPtr newspace = calculateSpaceForGeom(pos);
-
- if (newspace == IntPtr.Zero)
- {
- newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
- d.HashSpaceSetLevels(newspace, -4, 66);
- }
-
- return newspace;
- }
-
- public IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY)
- {
- // creating a new space for prim and inserting it into main space.
- staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero);
- d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]);
- return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY];
- }
-
- public IntPtr calculateSpaceForGeom(PhysicsVector pos)
- {
- int[] xyspace = calculateSpaceArrayItemFromPos(pos);
- //MainLog.Instance.Verbose("Physics", "Attempting to use arrayItem: " + xyspace[0].ToString() + "," + xyspace[1].ToString());
- IntPtr locationbasedspace = staticPrimspace[xyspace[0], xyspace[1]];
-
- //locationbasedspace = space;
- return locationbasedspace;
- }
-
- public int[] calculateSpaceArrayItemFromPos(PhysicsVector pos)
- {
- int[] returnint = new int[2];
-
- returnint[0] = (int) (pos.X/metersInSpace);
-
- if (returnint[0] > ((int) (259f/metersInSpace)))
- returnint[0] = ((int) (259f/metersInSpace));
- if (returnint[0] < 0)
- returnint[0] = 0;
-
- returnint[1] = (int) (pos.Y/metersInSpace);
- if (returnint[0] > ((int) (259f/metersInSpace)))
- returnint[0] = ((int) (259f/metersInSpace));
- if (returnint[0] < 0)
- returnint[0] = 0;
-
- return returnint;
- }
-
- private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
- IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) // rex, localid
- {
- PhysicsVector pos = new PhysicsVector();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z;
- PhysicsVector siz = new PhysicsVector();
- siz.X = size.X;
- siz.Y = size.Y;
- siz.Z = size.Z;
- Quaternion rot = new Quaternion();
- rot.w = rotation.w;
- rot.x = rotation.x;
- rot.y = rotation.y;
- rot.z = rotation.z;
-
-
- int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
- IntPtr targetspace = calculateSpaceForGeom(pos);
-
- if (targetspace == IntPtr.Zero)
- targetspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
-
- OdePrim newPrim;
- lock (OdeLock)
- {
- newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical, localID); // rex, localid
-
- _prims.Add(newPrim);
- }
-
- return newPrim;
- }
-
- public void addActivePrim(OdePrim activatePrim)
- {
- // adds active prim.. (ones that should be iterated over in collisions_optimized
-
- _activeprims.Add(activatePrim);
- }
-
- public void remActivePrim(OdePrim deactivatePrim)
- {
- _activeprims.Remove(deactivatePrim);
- }
-
- public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
- {
-/* String name1 = null;
- String name2 = null;
-
- if (!geom_name_map.TryGetValue(trimesh, out name1))
- {
- name1 = "null";
- }
- if (!geom_name_map.TryGetValue(refObject, out name2))
- {
- name2 = "null";
- }
-
- MainLog.Instance.Verbose("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2);
-*/
- return 1;
- }
-
- public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
- {
- String name1 = null;
- String name2 = null;
-
- if (!geom_name_map.TryGetValue(trimesh, out name1))
- {
- name1 = "null";
- }
- if (!geom_name_map.TryGetValue(refObject, out name2))
- {
- name2 = "null";
- }
-
-// MainLog.Instance.Verbose("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
-
- d.Vector3 v0 = new d.Vector3();
- d.Vector3 v1 = new d.Vector3();
- d.Vector3 v2 = new d.Vector3();
-
- d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
-// MainLog.Instance.Debug("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
-
- return 1;
- }
-
-
- public bool needsMeshing(PrimitiveBaseShape pbs)
- {
- if (pbs.ProfileHollow != 0)
- return true;
-
- if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
- return true;
-
- return false;
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint localID) //To be removed rex, localid
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, localid
- {
- PhysicsActor result;
- IMesh mesh = null;
-
- switch (pbs.ProfileShape)
- {
- case ProfileShape.Square:
- /// support simple box & hollow box now; later, more shapes
- if (needsMeshing(pbs))
- {
- mesh = mesher.CreateMesh(primName, pbs, size);
- }
-
- break;
- }
-
- result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localID); // rex, localid
-
-
- return result;
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- if (prim is OdePrim)
- {
- OdePrim taintedprim = ((OdePrim) prim);
- if (!(_taintedPrim.Contains(taintedprim)))
- _taintedPrim.Add(taintedprim);
- }
- }
-
- public override float Simulate(float timeStep)
- {
- float fps = 0;
-
- step_time += timeStep;
-
-
- // If We're loaded down by something else,
- // or debugging with the Visual Studio project on pause
- // skip a few frames to catch up gracefully.
- // without shooting the physicsactors all over the place
-
-
- if (step_time >= m_SkipFramesAtms)
- {
- // Instead of trying to catch up, it'll do one physics frame only
- step_time = ODE_STEPSIZE;
- m_physicsiterations = 5;
- }
- else
- {
- m_physicsiterations = 10;
- }
- lock (OdeLock)
- {
- // Process 10 frames if the sim is running normal..
- // process 5 frames if the sim is running slow
- try
- {
- d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
- }
- catch (StackOverflowException)
- {
- MainLog.Instance.Error("PHYSICS",
- "The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
- base.TriggerPhysicsBasedRestart();
- }
-
- int i = 0;
-
-
- // Figure out the Frames Per Second we're going at.
-
- fps = (((step_time/ODE_STEPSIZE*m_physicsiterations)*2)*10);
-
-
- while (step_time > 0.0f)
- {
- foreach (OdeCharacter actor in _characters)
- {
- actor.Move(timeStep);
- actor.collidelock = true;
- }
-
-
- collision_optimized(timeStep);
- d.WorldQuickStep(world, ODE_STEPSIZE);
- d.JointGroupEmpty(contactgroup);
- foreach (OdeCharacter actor in _characters)
- {
- actor.collidelock = false;
- }
-
- step_time -= ODE_STEPSIZE;
- i++;
- }
-
- foreach (OdeCharacter actor in _characters)
- {
- actor.UpdatePositionAndVelocity();
- }
- bool processedtaints = false;
- foreach (OdePrim prim in _taintedPrim)
- {
- prim.ProcessTaints(timeStep);
- if (prim.m_taintremove)
- {
- RemovePrimThreadLocked(prim);
- }
- processedtaints = true;
- }
- if (processedtaints)
- _taintedPrim = new List();
-
- if (timeStep < 0.2f)
- {
- foreach (OdePrim actor in _activeprims)
- {
- if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag))
- {
- actor.UpdatePositionAndVelocity();
- }
- }
- }
- }
- return fps;
- }
-
- public override void GetResults()
- {
- }
-
- public override bool IsThreaded
- {
- get { return (false); // for now we won't be multithreaded
- }
- }
-
- public float[] ResizeTerrain512(float[] heightMap)
- {
- float[] returnarr = new float[262144];
- float[,] resultarr = new float[m_regionWidth,m_regionHeight];
-
- // Filling out the array into it's multi-dimentional components
- for (int y = 0; y < m_regionHeight; y++)
- {
- for (int x = 0; x < m_regionWidth; x++)
- {
- resultarr[y, x] = heightMap[y*m_regionWidth + x];
- }
- }
-
- // Resize using interpolation
-
- // This particular way is quick but it only works on a multiple of the original
-
- // The idea behind this method can be described with the following diagrams
- // second pass and third pass happen in the same loop really.. just separated
- // them to show what this does.
-
- // First Pass
- // ResultArr:
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
- // 1,1,1,1,1,1
-
- // Second Pass
- // ResultArr2:
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
- // ,,,,,,,,,,
- // 1,,1,,1,,1,,1,,1,
-
- // Third pass fills in the blanks
- // ResultArr2:
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
- // 1,1,1,1,1,1,1,1,1,1,1,1
-
- // X,Y = .
- // X+1,y = ^
- // X,Y+1 = *
- // X+1,Y+1 = #
-
- // Filling in like this;
- // .*
- // ^#
- // 1st .
- // 2nd *
- // 3rd ^
- // 4th #
- // on single loop.
-
- float[,] resultarr2 = new float[512,512];
- for (int y = 0; y < m_regionHeight; y++)
- {
- for (int x = 0; x < m_regionWidth; x++)
- {
- resultarr2[y*2, x*2] = resultarr[y, x];
-
- if (y < m_regionHeight)
- {
- if (y + 1 < m_regionHeight)
- {
- if (x + 1 < m_regionWidth)
- {
- resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
- }
- }
- else
- {
- resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
- }
- }
- if (x < m_regionWidth)
- {
- if (x + 1 < m_regionWidth)
- {
- if (y + 1 < m_regionHeight)
- {
- resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
- }
- }
- else
- {
- resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
- }
- }
- if (x < m_regionWidth && y < m_regionHeight)
- {
- if ((x + 1 < m_regionWidth) && (y + 1 < m_regionHeight))
- {
- resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
- resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
- }
- else
- {
- resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
- }
- }
- }
- }
- //Flatten out the array
- int i = 0;
- for (int y = 0; y < 512; y++)
- {
- for (int x = 0; x < 512; x++)
- {
- if (resultarr2[y, x] <= 0)
- returnarr[i] = 0.0000001f;
- else
- returnarr[i] = resultarr2[y, x];
-
- i++;
- }
- }
-
- return returnarr;
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- // this._heightmap[i] = (double)heightMap[i];
- // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
- // also, creating a buffer zone of one extra sample all around
-
- const uint heightmapWidth = m_regionWidth + 2;
- const uint heightmapHeight = m_regionHeight + 2;
- const uint heightmapWidthSamples = 2*m_regionWidth + 2;
- const uint heightmapHeightSamples = 2*m_regionHeight + 2;
- const float scale = 1.0f;
- const float offset = 0.0f;
- const float thickness = 2.0f;
- const int wrap = 0;
-
- //Double resolution
- heightMap = ResizeTerrain512(heightMap);
- for (int x = 0; x < heightmapWidthSamples; x++)
- {
- for (int y = 0; y < heightmapHeightSamples; y++)
- {
- int xx = Util.Clip(x - 1, 0, 511);
- int yy = Util.Clip(y - 1, 0, 511);
-
- double val = (double) heightMap[yy*512 + xx];
- _heightmap[x*heightmapHeightSamples + y] = val;
- }
- }
-
- lock (OdeLock)
- {
- if (!(LandGeom == (IntPtr) 0))
- {
- d.SpaceRemove(space, LandGeom);
- }
- IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
- d.GeomHeightfieldDataBuildDouble(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
- (int) heightmapWidthSamples, (int) heightmapHeightSamples, scale,
- offset, thickness, wrap);
- d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
- LandGeom = d.CreateHeightfield(space, HeightmapData, 1);
- geom_name_map[LandGeom] = "Terrain";
-
- d.Matrix3 R = new d.Matrix3();
-
- Quaternion q1 = Quaternion.FromAngleAxis(1.5707f, new Vector3(1, 0, 0));
- Quaternion q2 = Quaternion.FromAngleAxis(1.5707f, new Vector3(0, 1, 0));
- //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
-
- q1 = q1*q2;
- //q1 = q1 * q3;
- Vector3 v3 = new Vector3();
- float angle = 0;
- q1.ToAngleAxis(ref angle, ref v3);
-
- d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle);
- d.GeomSetRotation(LandGeom, ref R);
- d.GeomSetPosition(LandGeom, 128, 128, 0);
- }
- }
-
- public override void DeleteTerrain()
- {
- }
- }
-}
+/*
+* 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 OpenSim 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.Runtime.InteropServices;
+using Axiom.Math;
+using Ode.NET;
+using OpenSim.Framework;
+using OpenSim.Framework.Console;
+using OpenSim.Region.Physics.Manager;
+
+//using OpenSim.Region.Physics.OdePlugin.Meshing;
+
+namespace OpenSim.Region.Physics.OdePlugin
+{
+ ///
+ /// ODE plugin
+ ///
+ public class OdePlugin : IPhysicsPlugin
+ {
+ //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ private CollisionLocker ode;
+ private OdeScene _mScene;
+
+ public OdePlugin()
+ {
+ ode = new CollisionLocker();
+ }
+
+ public bool Init()
+ {
+ return true;
+ }
+
+ public PhysicsScene GetScene()
+ {
+ if (_mScene == null)
+ {
+ _mScene = new OdeScene(ode);
+ }
+ return (_mScene);
+ }
+
+ public string GetName()
+ {
+ return ("OpenDynamicsEngine");
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ public class OdeScene : PhysicsScene
+ {
+ private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+
+ CollisionLocker ode;
+
+ private const uint m_regionWidth = Constants.RegionSize;
+ private const uint m_regionHeight = Constants.RegionSize;
+
+ private static float ODE_STEPSIZE = 0.020f;
+ private static bool RENDER_FLAG = false;
+ private static float metersInSpace = 29.9f;
+
+ private int interpenetrations_before_disable = 35;
+
+ private IntPtr contactgroup;
+ private IntPtr LandGeom = (IntPtr) 0;
+ private float[] _heightmap;
+ private float[] _origheightmap;
+
+ private GCHandle gchHeightMap; // rex
+ private d.NearCallback nearCallback;
+ public d.TriCallback triCallback;
+ public d.TriArrayCallback triArrayCallback;
+ private List _characters = new List();
+ private List _prims = new List();
+ private List _activeprims = new List();
+ private List _taintedPrim = new List();
+ public Dictionary geom_name_map = new Dictionary();
+ public Dictionary actor_name_map = new Dictionary();
+ private d.ContactGeom[] contacts = new d.ContactGeom[30];
+ private d.Contact contact;
+ private d.Contact TerrainContact;
+ private d.Contact AvatarMovementprimContact;
+ private d.Contact AvatarMovementTerrainContact;
+
+
+
+ private int m_physicsiterations = 10;
+ private float m_SkipFramesAtms = 0.40f; // Drop frames gracefully at a 400 ms lag
+ private PhysicsActor PANull = new NullPhysicsActor();
+ private float step_time = 0.0f;
+ private int ms = 0;
+ public IntPtr world;
+
+ public IntPtr space;
+
+ private IntPtr tmpSpace;
+ // split static geometry collision handling into spaces of 30 meters
+ public IntPtr[,] staticPrimspace = new IntPtr[(int) (300/metersInSpace),(int) (300/metersInSpace)];
+
+ public static Object OdeLock = new Object();
+
+ public IMesher mesher;
+
+
+ ///
+ /// Initiailizes the scene
+ /// Sets many properties that ODE requires to be stable
+ /// These settings need to be tweaked 'exactly' right or weird stuff happens.
+ ///
+ public OdeScene(CollisionLocker dode)
+ {
+ ode = dode;
+ nearCallback = near;
+ triCallback = TriCallback;
+ triArrayCallback = TriArrayCallback;
+ /*
+ contact.surface.mode |= d.ContactFlags.Approx1 | d.ContactFlags.SoftCFM | d.ContactFlags.SoftERP;
+ contact.surface.mu = 10.0f;
+ contact.surface.bounce = 0.9f;
+ contact.surface.soft_erp = 0.005f;
+ contact.surface.soft_cfm = 0.00003f;
+ */
+
+ // Centeral contact friction and bounce
+ contact.surface.mu = 250.0f;
+ contact.surface.bounce = 0.2f;
+
+ // Terrain contact friction and Bounce
+ // This is the *non* moving version. Use this when an avatar
+ // isn't moving to keep it in place better
+ TerrainContact.surface.mode |= d.ContactFlags.SoftERP;
+ TerrainContact.surface.mu = 255.0f;
+ TerrainContact.surface.bounce = 0.1f;
+ TerrainContact.surface.soft_erp = 0.1025f;
+
+ // Prim contact friction and bounce
+ // THis is the *non* moving version of friction and bounce
+ // Use this when an avatar comes in contact with a prim
+ // and is moving
+ AvatarMovementprimContact.surface.mu = 75.0f;
+ AvatarMovementprimContact.surface.bounce = 0.1f;
+
+ // Terrain contact friction bounce and various error correcting calculations
+ // Use this when an avatar is in contact with the terrain and moving.
+ AvatarMovementTerrainContact.surface.mode |= d.ContactFlags.SoftERP;
+ AvatarMovementTerrainContact.surface.mu = 75.0f;
+ AvatarMovementTerrainContact.surface.bounce = 0.1f;
+ AvatarMovementTerrainContact.surface.soft_erp = 0.1025f;
+
+ lock (OdeLock)
+ {
+
+ // Creat the world and the first space
+ world = d.WorldCreate();
+ space = d.HashSpaceCreate(IntPtr.Zero);
+ d.HashSpaceSetLevels(space, -4, 128);
+ contactgroup = d.JointGroupCreate(0);
+ //contactgroup
+
+
+ // Set the gravity,, don't disable things automatically (we set it explicitly on some things)
+
+ d.WorldSetGravity(world, 0.0f, 0.0f, -9.8f);
+ d.WorldSetAutoDisableFlag(world, false);
+ d.WorldSetContactSurfaceLayer(world, 0.001f);
+
+ // Set how many steps we go without running collision testing
+ // This is in addition to the step size.
+ // Essentially Steps * m_physicsiterations
+ d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
+ ///d.WorldSetContactMaxCorrectingVel(world, 1000.0f);
+ }
+
+ // zero out a heightmap array float array (single dimention [flattened]))
+ _heightmap = new float[514*514];
+ gchHeightMap = GCHandle.Alloc(_heightmap, GCHandleType.Pinned); // rex
+
+
+ // Zero out the prim spaces array (we split our space into smaller spaces so
+ // we can hit test less.
+ for (int i = 0; i < staticPrimspace.GetLength(0); i++)
+ {
+ for (int j = 0; j < staticPrimspace.GetLength(1); j++)
+ {
+ staticPrimspace[i, j] = IntPtr.Zero;
+ }
+ }
+ }
+
+ public void starttiming()
+ {
+ ms = Environment.TickCount;
+ }
+ public int stoptiming()
+ {
+ return Environment.TickCount - ms;
+ }
+ // Initialize the mesh plugin
+ public override void Initialise(IMesher meshmerizer)
+ {
+ mesher = meshmerizer;
+ }
+
+ internal void waitForSpaceUnlock(IntPtr space)
+ {
+
+ while (d.SpaceLockQuery(space))
+ {
+
+ }
+
+
+
+ }
+ ///
+ /// Debug space message for printing the space that a prim/avatar is in.
+ ///
+ ///
+ /// Returns which split up space the given position is in.
+ public string whichspaceamIin(PhysicsVector pos)
+ {
+ return calculateSpaceForGeom(pos).ToString();
+ }
+
+ ///
+ /// This is our near callback. A geometry is near a body
+ ///
+ /// The space that contains the geoms. Remember, spaces are also geoms
+ /// a geometry or space
+ /// another geometry or space
+ private void near(IntPtr space, IntPtr g1, IntPtr g2)
+ {
+ // no lock here! It's invoked from within Simulate(), which is thread-locked
+
+ // Test if we're collidng a geom with a space.
+ // If so we have to drill down into the space recursively
+
+ if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
+ {
+ if (g1 == (IntPtr)0 || g2 == (IntPtr)0)
+ return;
+ // Separating static prim geometry spaces.
+ // We'll be calling near recursivly if one
+ // of them is a space to find all of the
+ // contact points in the space
+ try
+ {
+ d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to collide test a space");
+ return;
+ }
+ //Colliding a space or a geom with a space or a geom. so drill down
+
+ //Collide all geoms in each space..
+ //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
+ //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
+ }
+ else
+ {
+ // Colliding Geom To Geom
+ // This portion of the function 'was' blatantly ripped off from BoxStack.cs
+ if (g1 == (IntPtr)0 || g2 == (IntPtr)0)
+ return;
+
+ IntPtr b1 = d.GeomGetBody(g1);
+ IntPtr b2 = d.GeomGetBody(g2);
+
+ if (g1 == g2)
+ return; // Can't collide with yourself
+
+ if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
+ return;
+
+
+
+ d.GeomClassID id = d.GeomGetClass(g1);
+
+ String name1 = null;
+ String name2 = null;
+
+ if (!geom_name_map.TryGetValue(g1, out name1))
+ {
+ name1 = "null";
+ }
+ if (!geom_name_map.TryGetValue(g2, out name2))
+ {
+ name2 = "null";
+ }
+
+ //if (id == d.GeomClassId.TriMeshClass)
+ //{
+ // m_log.InfoFormat("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ //}
+
+ // Figure out how many contact points we have
+ int count = 0;
+ try
+ {
+ //m_log.Warn(g1.ToString() + "|" + g2.ToString());
+ count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
+ }
+ catch (SEHException)
+ {
+ m_log.Error("[PHYSICS]: 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.");
+ ode.drelease(world);
+ base.TriggerPhysicsBasedRestart();
+ }
+ catch (System.AccessViolationException)
+ {
+
+ m_log.Warn("[PHYSICS]: Unable to collide test an object");
+ return;
+ }
+
+ PhysicsActor p1;
+ PhysicsActor p2;
+
+ for (int i = 0; i < count; i++)
+ {
+ //m_log.Warn("[CCOUNT]: " + count);
+ IntPtr joint;
+ // If we're colliding with terrain, use 'TerrainContact' instead of contact.
+ // allows us to have different settings
+
+ if (!actor_name_map.TryGetValue(g1, out p1))
+ {
+ p1 = PANull;
+ }
+ if (!actor_name_map.TryGetValue(g2, out p2))
+ {
+ p2 = PANull;
+ }
+
+ // We only need to test p2 for 'jump crouch purposes'
+ p2.IsColliding = true;
+
+
+ switch (p1.PhysicsActorType)
+ {
+ case (int)ActorTypes.Agent:
+ p2.CollidingObj = true;
+ break;
+ case (int)ActorTypes.Prim:
+ if (p2.Velocity.X > 0 || p2.Velocity.Y > 0 || p2.Velocity.Z > 0)
+ p2.CollidingObj = true;
+ break;
+ case (int)ActorTypes.Unknown:
+ p2.CollidingGround = true;
+ break;
+ case (int)ActorTypes.PrimVolume: // rex, added primvolume
+ if (Util.UnixTimeSinceEpoch() > p2.NextPrimVolumeTime)
+ {
+ p2.NextPrimVolumeTime = Util.UnixTimeSinceEpoch() + 1;
+ p1.SendCollisionUpdate(new CollisionEventUpdate(p2.m_localID,0,true,null));
+ }
+ return;
+ default:
+ p2.CollidingGround = true;
+ break;
+ }
+ // we don't want prim or avatar to explode
+
+ #region InterPenetration Handling - Unintended physics explosions
+
+ if (contacts[i].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)
+ {
+ //m_log.Debug("[PHYSICS]: " + contacts[i].depth.ToString());
+ }
+
+ //If you interpenetrate a prim with an agent
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
+ p1.PhysicsActorType == (int) ActorTypes.Prim) ||
+ (p1.PhysicsActorType == (int) ActorTypes.Agent &&
+ p2.PhysicsActorType == (int) ActorTypes.Prim))
+ {
+ //contacts[i].depth = contacts[i].depth * 4.15f;
+ /*
+ if (p2.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+ p2.CollidingObj = true;
+ contacts[i].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));
+
+ }
+ else
+ {
+
+ //contacts[i].depth = 0.0000000f;
+ }
+ if (p1.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+
+ p1.CollidingObj = true;
+ contacts[i].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));
+ OdeCharacter character = (OdeCharacter)p1;
+ character.SetPidStatus(true);
+ }
+ else
+ {
+
+ //contacts[i].depth = 0.0000000f;
+ }
+ */
+ }
+
+
+ // If you interpenetrate a prim with another prim
+ if (p1.PhysicsActorType == (int) ActorTypes.Prim && p2.PhysicsActorType == (int) ActorTypes.Prim)
+ {
+ //OdePrim op1 = (OdePrim)p1;
+ //OdePrim op2 = (OdePrim)p2;
+ //op1.m_collisionscore++;
+ //op2.m_collisionscore++;
+
+
+ //if (op1.m_collisionscore > 8000 || op2.m_collisionscore > 8000)
+ //{
+ //op1.m_taintdisable = true;
+ //AddPhysicsActorTaint(p1);
+ //op2.m_taintdisable = true;
+ //AddPhysicsActorTaint(p2);
+ //}
+
+ //if (contacts[i].depth >= 0.25f)
+ //{
+ // Don't collide, one or both prim will expld.
+
+
+ //op1.m_interpenetrationcount++;
+ //op2.m_interpenetrationcount++;
+ //interpenetrations_before_disable = 200;
+ //if (op1.m_interpenetrationcount >= interpenetrations_before_disable)
+ //{
+ //op1.m_taintdisable = true;
+ //AddPhysicsActorTaint(p1);
+ //}
+ //if (op2.m_interpenetrationcount >= interpenetrations_before_disable)
+ //{
+ // op2.m_taintdisable = true;
+ //AddPhysicsActorTaint(p2);
+ //}
+
+
+ //contacts[i].depth = contacts[i].depth / 8f;
+ //contacts[i].normal = new d.Vector3(0, 0, 1);
+ //}
+ //if (op1.m_disabled || op2.m_disabled)
+ //{
+ //Manually disabled objects stay disabled
+ //contacts[i].depth = 0f;
+ //}
+ }
+ if (contacts[i].depth >= 1.00f)
+ {
+ //m_log.Info("[P]: " + contacts[i].depth.ToString());
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent &&
+ p1.PhysicsActorType == (int) ActorTypes.Unknown) ||
+ (p1.PhysicsActorType == (int) ActorTypes.Agent &&
+ p2.PhysicsActorType == (int) ActorTypes.Unknown))
+ {
+ if (p2.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+ OdeCharacter character = (OdeCharacter) p2;
+
+ //p2.CollidingObj = true;
+ contacts[i].depth = 0.00000003f;
+ p2.Velocity = p2.Velocity + new PhysicsVector(0, 0, 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));
+ character.SetPidStatus(true);
+ }
+ else
+ {
+ }
+ if (p1.PhysicsActorType == (int) ActorTypes.Agent)
+ {
+ OdeCharacter character = (OdeCharacter)p1;
+
+ //p2.CollidingObj = true;
+ contacts[i].depth = 0.00000003f;
+ p1.Velocity = p1.Velocity + new PhysicsVector(0, 0, 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));
+ character.SetPidStatus(true);
+ }
+ else
+ {
+ //contacts[i].depth = 0.0000000f;
+ }
+ }
+ }
+ }
+
+ #endregion
+
+ if (contacts[i].depth >= 0f)
+ {
+ // If we're collidng against terrain
+ if (name1 == "Terrain" || name2 == "Terrain")
+ {
+ // If we're moving
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
+ (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
+ {
+ // Use the movement terrain contact
+ AvatarMovementTerrainContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementTerrainContact);
+ }
+ else
+ {
+ // Use the non moving terrain contact
+ TerrainContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref TerrainContact);
+ }
+ }
+ else
+ {
+ // we're colliding with prim or avatar
+
+ // check if we're moving
+ if ((p2.PhysicsActorType == (int) ActorTypes.Agent) &&
+ (Math.Abs(p2.Velocity.X) > 0.01f || Math.Abs(p2.Velocity.Y) > 0.01f))
+ {
+ // Use the Movement prim contact
+ AvatarMovementprimContact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref AvatarMovementprimContact);
+ }
+ else
+ {
+ // Use the non movement contact
+ contact.geom = contacts[i];
+ joint = d.JointCreateContact(world, contactgroup, ref contact);
+ }
+ }
+ d.JointAttach(joint, b1, b2);
+ }
+
+ if (count > 3)
+ {
+ // If there are more then 3 contact points, it's likely
+ // that we've got a pile of objects
+ //
+ // We don't want to send out hundreds of terse updates over and over again
+ // so lets throttle them and send them again after it's somewhat sorted out.
+ p2.ThrottleUpdates = true;
+ }
+ //System.Console.WriteLine(count.ToString());
+ //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
+ }
+ }
+ }
+ private float GetTerrainHeightAtXY(float x, float y)
+ {
+ return (float)_origheightmap[(int)y * Constants.RegionSize + (int)x];
+
+
+ }
+
+ ///
+ /// This is our collision testing routine in ODE
+ ///
+ ///
+ private void collision_optimized(float timeStep)
+ {
+
+ foreach (OdeCharacter chr in _characters)
+ {
+ // Reset the collision values to false
+ // since we don't know if we're colliding yet
+
+ chr.IsColliding = false;
+ chr.CollidingGround = false;
+ chr.CollidingObj = false;
+
+ // test the avatar's geometry for collision with the space
+ // This will return near and the space that they are the closest to
+ // And we'll run this again against the avatar and the space segment
+ // This will return with a bunch of possible objects in the space segment
+ // and we'll run it again on all of them.
+ try
+ {
+ d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
+ }
+ catch (AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to space collide");
+ }
+ //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
+ //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
+ //{
+ //chr.Position.Z = terrainheight + 10.0f;
+ //forcedZ = true;
+ //}
+ }
+
+
+ // If the sim is running slow this frame,
+ // don't process collision for prim!
+ if (timeStep < (m_SkipFramesAtms/3))
+ {
+ foreach (OdePrim chr in _activeprims)
+ {
+ // This if may not need to be there.. it might be skipped anyway.
+ if (d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
+ {
+ try
+ {
+ d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback);
+ }
+ catch (AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to space collide");
+ }
+ //calculateSpaceForGeom(chr.Position)
+ //foreach (OdePrim ch2 in _prims)
+ /// should be a separate space -- lots of avatars will be N**2 slow
+ //{
+ //if (ch2.IsPhysical && d.BodyIsEnabled(ch2.Body))
+ //{
+ // Only test prim that are 0.03 meters away in one direction.
+ // This should be Optimized!
+
+ //if ((Math.Abs(ch2.Position.X - chr.Position.X) < 0.03) || (Math.Abs(ch2.Position.Y - chr.Position.Y) < 0.03) || (Math.Abs(ch2.Position.X - chr.Position.X) < 0.03))
+ //{
+ //d.SpaceCollide2(chr.prim_geom, ch2.prim_geom, IntPtr.Zero, nearCallback);
+ //}
+ //}
+ //}
+ }
+ try
+ {
+ d.SpaceCollide2(LandGeom, chr.prim_geom, IntPtr.Zero, nearCallback);
+ }
+ catch (AccessViolationException)
+ {
+ m_log.Warn("[PHYSICS]: Unable to space collide");
+ }
+ }
+ }
+ else
+ {
+ // Everything is going slow, so we're skipping object to object collisions
+ // At least collide test against the ground.
+ foreach (OdePrim chr in _activeprims)
+ {
+ // This if may not need to be there.. it might be skipped anyway.
+ if (d.BodyIsEnabled(chr.Body))
+ {
+ // Collide test the prims with the terrain.. since if you don't do this,
+ // next frame, all of the physical prim in the scene will awaken and explode upwards
+ tmpSpace = calculateSpaceForGeom(chr.Position);
+ if (tmpSpace != (IntPtr) 0 && d.GeomIsSpace(tmpSpace))
+ d.SpaceCollide2(calculateSpaceForGeom(chr.Position), chr.prim_geom, IntPtr.Zero, nearCallback);
+ d.SpaceCollide2(LandGeom, chr.prim_geom, IntPtr.Zero, nearCallback);
+ }
+ }
+ }
+ }
+
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ PhysicsVector pos = new PhysicsVector();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z;
+ OdeCharacter newAv = new OdeCharacter(avName, this, pos, ode, size);
+ _characters.Add(newAv);
+
+ return newAv;
+ }
+
+ public override void RemoveAvatar(PhysicsActor actor)
+ {
+ lock (OdeLock)
+ {
+ ((OdeCharacter) actor).Destroy();
+ _characters.Remove((OdeCharacter) actor);
+ }
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ if (prim is OdePrim)
+ {
+ lock (OdeLock)
+ {
+ OdePrim p = (OdePrim) prim;
+
+ p.setPrimForRemoval();
+ AddPhysicsActorTaint(prim);
+ //RemovePrimThreadLocked(p);
+ }
+ }
+ }
+
+ ///
+ /// This is called from within simulate but outside the locked portion
+ /// We need to do our own locking here
+ /// Essentially, we need to remove the prim from our space segment, whatever segment it's in.
+ ///
+ /// If there are no more prim in the segment, we need to empty (spacedestroy)the segment and reclaim memory
+ /// that the space was using.
+ ///
+ ///
+ public void RemovePrimThreadLocked(OdePrim prim)
+ {
+ lock (ode)
+ {
+ if (prim.prim_geom != (IntPtr)0)
+ {
+ while (ode.lockquery())
+ {
+ }
+ ode.dlock(world);
+ //System.Threading.Thread.Sleep(20);
+ prim.ResetTaints();
+
+
+ if (prim.IsPhysical)
+ {
+ prim.disableBody();
+ }
+ // we don't want to remove the main space
+
+ // If the geometry is in the targetspace, remove it from the target space
+ //m_log.Warn(prim.m_targetSpace);
+
+ //if (prim.m_targetSpace != (IntPtr)0)
+ //{
+ if (d.SpaceQuery(prim.m_targetSpace, prim.prim_geom))
+ {
+
+ if (d.GeomIsSpace(prim.m_targetSpace))
+ {
+ waitForSpaceUnlock(prim.m_targetSpace);
+ d.SpaceRemove(prim.m_targetSpace, prim.prim_geom);
+ prim.m_targetSpace = (IntPtr) 0;
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
+ ((OdePrim)prim).m_targetSpace.ToString());
+ }
+
+ }
+ //}
+ //m_log.Warn(prim.prim_geom);
+ try
+ {
+ if (prim.prim_geom != (IntPtr)0)
+ {
+ d.GeomDestroy(prim.prim_geom);
+ prim.prim_geom = (IntPtr)0;
+ }
+ else
+ {
+ m_log.Warn("[PHYSICS]: Unable to remove prim from physics scene");
+ }
+
+ }
+ catch (System.AccessViolationException)
+ {
+ m_log.Info("[PHYSICS]: Couldn't remove prim from physics scene, it was already be removed.");
+ }
+ _prims.Remove(prim);
+
+ //If there are no more geometries in the sub-space, we don't need it in the main space anymore
+ //if (d.SpaceGetNumGeoms(prim.m_targetSpace) == 0)
+ //{
+ //if (!(prim.m_targetSpace.Equals(null)))
+ //{
+ //if (d.GeomIsSpace(prim.m_targetSpace))
+ //{
+ //waitForSpaceUnlock(prim.m_targetSpace);
+ //d.SpaceRemove(space, prim.m_targetSpace);
+ // free up memory used by the space.
+ //d.SpaceDestroy(prim.m_targetSpace);
+ //int[] xyspace = calculateSpaceArrayItemFromPos(prim.Position);
+ //resetSpaceArrayItemToZero(xyspace[0], xyspace[1]);
+ //}
+ //else
+ //{
+ //m_log.Info("[Physics]: Invalid Scene passed to 'removeprim from scene':" +
+ //((OdePrim) prim).m_targetSpace.ToString());
+ //}
+ //}
+ //}
+ }
+
+ ode.dunlock(world);
+ }
+ }
+
+ ///
+ /// Takes a space pointer and zeros out the array we're using to hold the spaces
+ ///
+ ///
+ public void resetSpaceArrayItemToZero(IntPtr space)
+ {
+ for (int x = 0; x < staticPrimspace.GetLength(0); x++)
+ {
+ for (int y = 0; y < staticPrimspace.GetLength(1); y++)
+ {
+ if (staticPrimspace[x, y] == space)
+ staticPrimspace[x, y] = IntPtr.Zero;
+ }
+ }
+ }
+
+ public void resetSpaceArrayItemToZero(int arrayitemX, int arrayitemY)
+ {
+ staticPrimspace[arrayitemX, arrayitemY] = IntPtr.Zero;
+ }
+
+ ///
+ /// Called when a static prim moves. Allocates a space for the prim based on it's position
+ ///
+ /// the pointer to the geom that moved
+ /// the position that the geom moved to
+ /// a pointer to the space it was in before it was moved.
+ /// a pointer to the new space it's in
+ public IntPtr recalculateSpaceForGeom(IntPtr geom, PhysicsVector pos, IntPtr currentspace)
+ {
+
+ // Called from setting the Position and Size of an ODEPrim so
+ // it's already in locked space.
+
+ // we don't want to remove the main space
+ // we don't need to test physical here because this function should
+ // never be called if the prim is physical(active)
+
+ // All physical prim end up in the root space
+ System.Threading.Thread.Sleep(20);
+ if (currentspace != space)
+ {
+ if (d.SpaceQuery(currentspace, geom) && currentspace != (IntPtr) 0)
+ {
+ if (d.GeomIsSpace(currentspace))
+ {
+ waitForSpaceUnlock(currentspace);
+ d.SpaceRemove(currentspace, geom);
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" + currentspace.ToString() +
+ " Geom:" + geom.ToString());
+ }
+ }
+ else
+ {
+ IntPtr sGeomIsIn = d.GeomGetSpace(geom);
+ if (!(sGeomIsIn.Equals(null)))
+ {
+ if (sGeomIsIn != (IntPtr) 0)
+ {
+ if (d.GeomIsSpace(currentspace))
+ {
+ waitForSpaceUnlock(sGeomIsIn);
+ d.SpaceRemove(sGeomIsIn, geom);
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" +
+ sGeomIsIn.ToString() + " Geom:" + geom.ToString());
+ }
+ }
+ }
+ }
+
+ //If there are no more geometries in the sub-space, we don't need it in the main space anymore
+ if (d.SpaceGetNumGeoms(currentspace) == 0)
+ {
+ if (currentspace != (IntPtr) 0)
+ {
+ if (d.GeomIsSpace(currentspace))
+ {
+ waitForSpaceUnlock(currentspace);
+ waitForSpaceUnlock(space);
+ d.SpaceRemove(space, currentspace);
+ // free up memory used by the space.
+
+ d.SpaceDestroy(currentspace);
+ resetSpaceArrayItemToZero(currentspace);
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" +
+ currentspace.ToString() + " Geom:" + geom.ToString());
+ }
+ }
+ }
+ }
+ else
+ {
+ // this is a physical object that got disabled. ;.;
+ if (currentspace != (IntPtr)0 && geom != (IntPtr)0)
+ {
+ if (d.SpaceQuery(currentspace, geom))
+ {
+
+ if (d.GeomIsSpace(currentspace))
+ {
+ waitForSpaceUnlock(currentspace);
+ d.SpaceRemove(currentspace, geom);
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" +
+ currentspace.ToString() + " Geom:" + geom.ToString());
+ }
+ }
+ else
+ {
+ IntPtr sGeomIsIn = d.GeomGetSpace(geom);
+ if (!(sGeomIsIn.Equals(null)))
+ {
+ if (sGeomIsIn != (IntPtr)0)
+ {
+ if (d.GeomIsSpace(sGeomIsIn))
+ {
+ waitForSpaceUnlock(sGeomIsIn);
+ d.SpaceRemove(sGeomIsIn, geom);
+ }
+ else
+ {
+ m_log.Info("[Physics]: Invalid Scene passed to 'recalculatespace':" +
+ sGeomIsIn.ToString() + " Geom:" + geom.ToString());
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // The routines in the Position and Size sections do the 'inserting' into the space,
+ // so all we have to do is make sure that the space that we're putting the prim into
+ // is in the 'main' space.
+ int[] iprimspaceArrItem = calculateSpaceArrayItemFromPos(pos);
+ IntPtr newspace = calculateSpaceForGeom(pos);
+
+ if (newspace == IntPtr.Zero)
+ {
+ newspace = createprimspace(iprimspaceArrItem[0], iprimspaceArrItem[1]);
+ d.HashSpaceSetLevels(newspace, -4, 66);
+ }
+
+ return newspace;
+ }
+
+ ///
+ /// Creates a new space at X Y
+ ///
+ ///
+ ///
+ /// A pointer to the created space
+ public IntPtr createprimspace(int iprimspaceArrItemX, int iprimspaceArrItemY)
+ {
+ // creating a new space for prim and inserting it into main space.
+ staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY] = d.HashSpaceCreate(IntPtr.Zero);
+ waitForSpaceUnlock(space);
+ d.SpaceAdd(space, staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY]);
+ return staticPrimspace[iprimspaceArrItemX, iprimspaceArrItemY];
+ }
+
+ ///
+ /// Calculates the space the prim should be in by it's position
+ ///
+ ///
+ /// a pointer to the space. This could be a new space or reused space.
+ public IntPtr calculateSpaceForGeom(PhysicsVector pos)
+ {
+ IntPtr locationbasedspace =IntPtr.Zero;
+
+ int[] xyspace = calculateSpaceArrayItemFromPos(pos);
+ //m_log.Info("[Physics]: Attempting to use arrayItem: " + xyspace[0].ToString() + "," + xyspace[1].ToString());
+ locationbasedspace = staticPrimspace[xyspace[0], xyspace[1]];
+
+ //locationbasedspace = space;
+ return locationbasedspace;
+ }
+
+ ///
+ /// Holds the space allocation logic
+ ///
+ ///
+ /// an array item based on the position
+ public int[] calculateSpaceArrayItemFromPos(PhysicsVector pos)
+ {
+ int[] returnint = new int[2];
+
+ returnint[0] = (int) (pos.X/metersInSpace);
+
+ if (returnint[0] > ((int) (259f/metersInSpace)))
+ returnint[0] = ((int) (259f/metersInSpace));
+ if (returnint[0] < 0)
+ returnint[0] = 0;
+
+ returnint[1] = (int) (pos.Y/metersInSpace);
+ if (returnint[1] > ((int) (259f/metersInSpace)))
+ returnint[1] = ((int) (259f/metersInSpace));
+ if (returnint[1] < 0)
+ returnint[1] = 0;
+
+
+ return returnint;
+ }
+
+ private PhysicsActor AddPrim(String name, PhysicsVector position, PhysicsVector size, Quaternion rotation,
+ IMesh mesh, PrimitiveBaseShape pbs, bool isphysical, uint localID) // rex, localid
+ {
+ PhysicsVector pos = new PhysicsVector();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z;
+ PhysicsVector siz = new PhysicsVector();
+ siz.X = size.X;
+ siz.Y = size.Y;
+ siz.Z = size.Z;
+ Quaternion rot = new Quaternion();
+ rot.w = rotation.w;
+ rot.x = rotation.x;
+ rot.y = rotation.y;
+ rot.z = rotation.z;
+
+
+
+ OdePrim newPrim;
+ lock (OdeLock)
+ {
+ newPrim = new OdePrim(name, this, pos, siz, rot, mesh, pbs, isphysical, ode);
+
+ _prims.Add(newPrim);
+ }
+
+
+ return newPrim;
+ }
+
+ public void addActivePrim(OdePrim activatePrim)
+ {
+ // adds active prim.. (ones that should be iterated over in collisions_optimized
+
+ _activeprims.Add(activatePrim);
+ }
+
+ public void remActivePrim(OdePrim deactivatePrim)
+ {
+ _activeprims.Remove(deactivatePrim);
+ }
+
+ public int TriArrayCallback(IntPtr trimesh, IntPtr refObject, int[] triangleIndex, int triCount)
+ {
+/* String name1 = null;
+ String name2 = null;
+
+ if (!geom_name_map.TryGetValue(trimesh, out name1))
+ {
+ name1 = "null";
+ }
+ if (!geom_name_map.TryGetValue(refObject, out name2))
+ {
+ name2 = "null";
+ }
+
+ m_log.InfoFormat("TriArrayCallback: A collision was detected between {1} and {2}", 0, name1, name2);
+*/
+ return 1;
+ }
+
+ public int TriCallback(IntPtr trimesh, IntPtr refObject, int triangleIndex)
+ {
+ String name1 = null;
+ String name2 = null;
+
+ if (!geom_name_map.TryGetValue(trimesh, out name1))
+ {
+ name1 = "null";
+ }
+
+ if (!geom_name_map.TryGetValue(refObject, out name2))
+ {
+ name2 = "null";
+ }
+
+// m_log.InfoFormat("TriCallback: A collision was detected between {1} and {2}. Index was {3}", 0, name1, name2, triangleIndex);
+
+ d.Vector3 v0 = new d.Vector3();
+ d.Vector3 v1 = new d.Vector3();
+ d.Vector3 v2 = new d.Vector3();
+
+ d.GeomTriMeshGetTriangle(trimesh, 0, ref v0, ref v1, ref v2);
+// m_log.DebugFormat("Triangle {0} is <{1},{2},{3}>, <{4},{5},{6}>, <{7},{8},{9}>", triangleIndex, v0.X, v0.Y, v0.Z, v1.X, v1.Y, v1.Z, v2.X, v2.Y, v2.Z);
+
+ return 1;
+ }
+
+ ///
+ /// Routine to figure out if we need to mesh this prim with our mesher
+ ///
+ ///
+ ///
+ public bool needsMeshing(PrimitiveBaseShape pbs)
+ {
+ if (pbs.ProfileHollow != 0)
+ return true;
+
+ if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
+ return true;
+
+ if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
+ return true;
+
+ if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
+ return true;
+
+ if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
+ return true;
+
+ if (pbs.ProfileShape == ProfileShape.EquilateralTriangle)
+ return true;
+
+ return false;
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint localID) //To be removed rex, localid
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID) // rex, localid
+ {
+ PhysicsActor result;
+ IMesh mesh = null;
+
+ switch (pbs.ProfileShape)
+ {
+ case ProfileShape.Square:
+ /// support simple box & hollow box now; later, more shapes
+ if (needsMeshing(pbs))
+ {
+ mesh = mesher.CreateMesh(primName, pbs, size);
+ }
+
+ break;
+ }
+
+ result = AddPrim(primName, position, size, rotation, mesh, pbs, isPhysical, localID); // rex, localid
+
+
+ return result;
+ }
+
+ ///
+ /// Called after our prim properties are set Scale, position etc.
+ /// We use this event queue like method to keep changes to the physical scene occuring in the threadlocked mutex
+ /// This assures us that we have no race conditions
+ ///
+ ///
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ if (prim is OdePrim)
+ {
+ OdePrim taintedprim = ((OdePrim) prim);
+ if (!(_taintedPrim.Contains(taintedprim)))
+ _taintedPrim.Add(taintedprim);
+ }
+ }
+
+ ///
+ /// This is our main simulate loop
+ /// It's thread locked by a Mutex in the scene.
+ /// It holds Collisions, it instructs ODE to step through the physical reactions
+ /// It moves the objects around in memory
+ /// It calls the methods that report back to the object owners.. (scenepresence, SceneObjectGroup)
+ ///
+ ///
+ ///
+ public override float Simulate(float timeStep)
+ {
+ float fps = 0;
+
+ step_time += timeStep;
+
+
+ // If We're loaded down by something else,
+ // or debugging with the Visual Studio project on pause
+ // skip a few frames to catch up gracefully.
+ // without shooting the physicsactors all over the place
+
+
+ if (step_time >= m_SkipFramesAtms)
+ {
+ // Instead of trying to catch up, it'll do 5 physics frames only
+ step_time = ODE_STEPSIZE;
+ m_physicsiterations = 5;
+ }
+ else
+ {
+ m_physicsiterations = 10;
+ }
+ lock (OdeLock)
+ {
+ // Process 10 frames if the sim is running normal..
+ // process 5 frames if the sim is running slow
+ try
+ {
+ d.WorldSetQuickStepNumIterations(world, m_physicsiterations);
+ }
+ catch (StackOverflowException)
+ {
+ m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
+ ode.drelease(world);
+ base.TriggerPhysicsBasedRestart();
+ }
+
+ int i = 0;
+
+ // 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;
+
+ while (step_time > 0.0f)
+ {
+ lock (ode)
+ {
+ if (!ode.lockquery())
+ {
+ ode.dlock(world);
+ try
+ {
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.Move(timeStep);
+ }
+
+ collision_optimized(timeStep);
+
+ d.WorldQuickStep(world, ODE_STEPSIZE);
+
+ d.JointGroupEmpty(contactgroup);
+ ode.dunlock(world);
+ }
+ catch (Exception e)
+ {
+ m_log.Error("[PHYSICS]: " + e.Message.ToString() + e.TargetSite.ToString());
+ ode.dunlock(world);
+ }
+
+ step_time -= ODE_STEPSIZE;
+ i++;
+ }
+ else
+ {
+ fps = 0;
+ }
+ }
+ }
+
+ foreach (OdeCharacter actor in _characters)
+ {
+ if (actor != null)
+ actor.UpdatePositionAndVelocity();
+ }
+
+ if (!ode.lockquery())
+ {
+ bool processedtaints = false;
+ foreach (OdePrim prim in _taintedPrim)
+ {
+ if (prim.m_taintremove)
+ {
+ RemovePrimThreadLocked(prim);
+ }
+
+ prim.ProcessTaints(timeStep);
+
+ processedtaints = true;
+ prim.m_collisionscore = 0;
+ }
+ if (processedtaints)
+ _taintedPrim = new List();
+ }
+ foreach (OdePrim prim in _activeprims)
+ {
+ prim.m_collisionscore = 0;
+ }
+
+
+
+ if (timeStep < 0.2f)
+ {
+ foreach (OdePrim actor in _activeprims)
+ {
+ if (actor.IsPhysical && (d.BodyIsEnabled(actor.Body) || !actor._zeroFlag))
+ {
+ actor.UpdatePositionAndVelocity();
+ }
+ }
+ }
+ }
+ return fps;
+ }
+
+ public override void GetResults()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ // for now we won't be multithreaded
+ get { return (false); }
+ }
+ public float[] ResizeTerrain512NearestNeighbour(float[] heightMap)
+ {
+ float[] returnarr = new float[262144];
+ float[,] resultarr = new float[m_regionWidth, m_regionHeight];
+
+ // Filling out the array into it's multi-dimentional components
+ for (int y = 0; y < m_regionHeight; y++)
+ {
+ for (int x = 0; x < m_regionWidth; x++)
+ {
+ resultarr[y, x] = heightMap[y * m_regionWidth + x];
+ }
+ }
+
+ // Resize using Nearest Neighbour
+
+ // This particular way is quick but it only works on a multiple of the original
+
+ // The idea behind this method can be described with the following diagrams
+ // second pass and third pass happen in the same loop really.. just separated
+ // them to show what this does.
+
+ // First Pass
+ // ResultArr:
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+
+ // Second Pass
+ // ResultArr2:
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+
+ // Third pass fills in the blanks
+ // ResultArr2:
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+
+ // X,Y = .
+ // X+1,y = ^
+ // X,Y+1 = *
+ // X+1,Y+1 = #
+
+ // Filling in like this;
+ // .*
+ // ^#
+ // 1st .
+ // 2nd *
+ // 3rd ^
+ // 4th #
+ // on single loop.
+
+ float[,] resultarr2 = new float[512, 512];
+ for (int y = 0; y < m_regionHeight; y++)
+ {
+ for (int x = 0; x < m_regionWidth; x++)
+ {
+ resultarr2[y * 2, x * 2] = resultarr[y, x];
+
+ if (y < m_regionHeight)
+ {
+ resultarr2[(y * 2) + 1, x * 2] = resultarr[y, x];
+ }
+ if (x < m_regionWidth)
+ {
+ resultarr2[y * 2, (x * 2) + 1] = resultarr[y, x];
+ }
+ if (x < m_regionWidth && y < m_regionHeight)
+ {
+ resultarr2[(y * 2) + 1, (x * 2) + 1] = resultarr[y, x];
+ }
+ }
+ }
+
+ //Flatten out the array
+ int i = 0;
+ for (int y = 0; y < 512; y++)
+ {
+ for (int x = 0; x < 512; x++)
+ {
+ if (resultarr2[y, x] <= 0)
+ returnarr[i] = 0.0000001f;
+ else
+ returnarr[i] = resultarr2[y, x];
+
+ i++;
+ }
+ }
+
+ return returnarr;
+ }
+ public float[] ResizeTerrain512Interpolation(float[] heightMap)
+ {
+ float[] returnarr = new float[262144];
+ float[,] resultarr = new float[m_regionWidth,m_regionHeight];
+
+ // Filling out the array into it's multi-dimentional components
+ for (int y = 0; y < m_regionHeight; y++)
+ {
+ for (int x = 0; x < m_regionWidth; x++)
+ {
+ resultarr[y, x] = heightMap[y*m_regionWidth + x];
+ }
+ }
+
+ // Resize using interpolation
+
+ // This particular way is quick but it only works on a multiple of the original
+
+ // The idea behind this method can be described with the following diagrams
+ // second pass and third pass happen in the same loop really.. just separated
+ // them to show what this does.
+
+ // First Pass
+ // ResultArr:
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+ // 1,1,1,1,1,1
+
+ // Second Pass
+ // ResultArr2:
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+ // ,,,,,,,,,,
+ // 1,,1,,1,,1,,1,,1,
+
+ // Third pass fills in the blanks
+ // ResultArr2:
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+ // 1,1,1,1,1,1,1,1,1,1,1,1
+
+ // X,Y = .
+ // X+1,y = ^
+ // X,Y+1 = *
+ // X+1,Y+1 = #
+
+ // Filling in like this;
+ // .*
+ // ^#
+ // 1st .
+ // 2nd *
+ // 3rd ^
+ // 4th #
+ // on single loop.
+
+ float[,] resultarr2 = new float[512,512];
+ for (int y = 0; y < m_regionHeight; y++)
+ {
+ for (int x = 0; x < m_regionWidth; x++)
+ {
+ resultarr2[y*2, x*2] = resultarr[y, x];
+
+ if (y < m_regionHeight)
+ {
+ if (y + 1 < m_regionHeight)
+ {
+ if (x + 1 < m_regionWidth)
+ {
+ resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x] +
+ resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
+ }
+ else
+ {
+ resultarr2[(y*2) + 1, x*2] = ((resultarr[y, x] + resultarr[y + 1, x])/2);
+ }
+ }
+ else
+ {
+ resultarr2[(y*2) + 1, x*2] = resultarr[y, x];
+ }
+ }
+ if (x < m_regionWidth)
+ {
+ if (x + 1 < m_regionWidth)
+ {
+ if (y + 1 < m_regionHeight)
+ {
+ resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
+ resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
+ }
+ else
+ {
+ resultarr2[y*2, (x*2) + 1] = ((resultarr[y, x] + resultarr[y, x + 1])/2);
+ }
+ }
+ else
+ {
+ resultarr2[y*2, (x*2) + 1] = resultarr[y, x];
+ }
+ }
+ if (x < m_regionWidth && y < m_regionHeight)
+ {
+ if ((x + 1 < m_regionWidth) && (y + 1 < m_regionHeight))
+ {
+ resultarr2[(y*2) + 1, (x*2) + 1] = ((resultarr[y, x] + resultarr[y + 1, x] +
+ resultarr[y, x + 1] + resultarr[y + 1, x + 1])/4);
+ }
+ else
+ {
+ resultarr2[(y*2) + 1, (x*2) + 1] = resultarr[y, x];
+ }
+ }
+ }
+ }
+ //Flatten out the array
+ int i = 0;
+ for (int y = 0; y < 512; y++)
+ {
+ for (int x = 0; x < 512; x++)
+ {
+ if (resultarr2[y, x] <= 0)
+ returnarr[i] = 0.0000001f;
+ else
+ returnarr[i] = resultarr2[y, x];
+
+ i++;
+ }
+ }
+
+ return returnarr;
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ // this._heightmap[i] = (double)heightMap[i];
+ // dbm (danx0r) -- heightmap x,y must be swapped for Ode (should fix ODE, but for now...)
+ // also, creating a buffer zone of one extra sample all around
+ _origheightmap = heightMap;
+ const uint heightmapWidth = m_regionWidth + 2;
+ const uint heightmapHeight = m_regionHeight + 2;
+ const uint heightmapWidthSamples = 2*m_regionWidth + 2;
+ const uint heightmapHeightSamples = 2*m_regionHeight + 2;
+ const float scale = 1.0f;
+ const float offset = 0.0f;
+ const float thickness = 0.2f;
+ const int wrap = 0;
+
+ //Double resolution
+ heightMap = ResizeTerrain512Interpolation(heightMap);
+ for (int x = 0; x < heightmapWidthSamples; x++)
+ {
+ for (int y = 0; y < heightmapHeightSamples; y++)
+ {
+ int xx = Util.Clip(x - 1, 0, 511);
+ int yy = Util.Clip(y - 1, 0, 511);
+
+ float val = heightMap[yy*512 + xx];
+ _heightmap[x*heightmapHeightSamples + y] = val;
+ }
+ }
+
+ lock (OdeLock)
+ {
+ if (!(LandGeom == (IntPtr) 0))
+ {
+ d.SpaceRemove(space, LandGeom);
+ }
+ IntPtr HeightmapData = d.GeomHeightfieldDataCreate();
+ d.GeomHeightfieldDataBuildSingle(HeightmapData, _heightmap, 0, heightmapWidth, heightmapHeight,
+ (int) heightmapWidthSamples, (int) heightmapHeightSamples, scale,
+ offset, thickness, wrap);
+ d.GeomHeightfieldDataSetBounds(HeightmapData, m_regionWidth, m_regionHeight);
+ LandGeom = d.CreateHeightfield(space, HeightmapData, 1);
+ geom_name_map[LandGeom] = "Terrain";
+
+ d.Matrix3 R = new d.Matrix3();
+
+ Quaternion q1 = Quaternion.FromAngleAxis(1.5707f, new Vector3(1, 0, 0));
+ Quaternion q2 = Quaternion.FromAngleAxis(1.5707f, new Vector3(0, 1, 0));
+ //Axiom.Math.Quaternion q3 = Axiom.Math.Quaternion.FromAngleAxis(3.14f, new Axiom.Math.Vector3(0, 0, 1));
+
+ q1 = q1*q2;
+ //q1 = q1 * q3;
+ Vector3 v3 = new Vector3();
+ float angle = 0;
+ q1.ToAngleAxis(ref angle, ref v3);
+
+ d.RFromAxisAndAngle(out R, v3.x, v3.y, v3.z, angle);
+ d.GeomSetRotation(LandGeom, ref R);
+ d.GeomSetPosition(LandGeom, 128, 128, 0);
+ }
+ }
+
+ public override void DeleteTerrain()
+ {
+ }
+
+ public override void Dispose()
+ {
+ lock (OdeLock)
+ {
+
+ foreach (OdePrim prm in _prims)
+ {
+ RemovePrim(prm);
+ }
+
+ foreach (OdeCharacter act in _characters)
+ {
+ RemoveAvatar(act);
+ }
+ d.WorldDestroy(world);
+ //d.CloseODE();
+ }
+ }
+ }
+}
diff --git a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
index ec84473134..f521cf9980 100644
--- a/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/POSPlugin/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
-[assembly : AssemblyVersion("1.0.*")]
\ No newline at end of file
+[assembly : AssemblyVersion("1.0.*")]
diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
index d772f8dbbd..d38ded6f7c 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
@@ -1,604 +1,663 @@
-/*
-* 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 OpenSim 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 Axiom.Math;
-using OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-
-namespace OpenSim.Region.Physics.POSPlugin
-{
- ///
- /// for now will be a very POS physics engine
- ///
- public class POSPlugin : IPhysicsPlugin
- {
- public POSPlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene()
- {
- return new POSScene();
- }
-
- public string GetName()
- {
- return ("POS");
- }
-
- public void Dispose()
- {
- }
- }
-
- public class POSScene : PhysicsScene
- {
- private List _characters = new List();
- private List _prims = new List();
- private float[] _heightMap;
- private const float gravity = -9.8f;
-
- public POSScene()
- {
- }
-
- public override void Initialise(IMesher meshmerizer)
- {
- // Does nothing right now
- }
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
- {
- POSCharacter act = new POSCharacter();
- act.Position = position;
- _characters.Add(act);
- return act;
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- POSPrim p = (POSPrim) prim;
- if (_prims.Contains(p))
- {
- _prims.Remove(p);
- }
- }
-
- public override void RemoveAvatar(PhysicsActor character)
- {
- POSCharacter act = (POSCharacter) character;
- if (_characters.Contains(act))
- {
- _characters.Remove(act);
- }
- }
-
-/*
- public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
- {
- return null;
- }
-*/
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint localID)
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
- {
- POSPrim prim = new POSPrim();
- prim.Position = position;
- prim.Orientation = rotation;
- prim.Size = size;
- _prims.Add(prim);
- return prim;
- }
-
- private bool check_collision(POSCharacter c, POSPrim p)
- {
- /*
- Console.WriteLine("checking whether " + c + " collides with " + p +
- " absX: " + Math.Abs(p.Position.X - c.Position.X) +
- " sizeX: " + p.Size.X * 0.5 + 0.5);
- */
-
- Vector3 rotatedPos = p.Orientation.Inverse()*
- new Vector3(c.Position.X - p.Position.X, c.Position.Y - p.Position.Y,
- c.Position.Z - p.Position.Z);
- Vector3 avatarSize = p.Orientation.Inverse()*new Vector3(c.Size.X, c.Size.Y, c.Size.Z);
-
- if (Math.Abs(rotatedPos.x) >= (p.Size.X*0.5 + Math.Abs(avatarSize.x)))
- {
- return false;
- }
- if (Math.Abs(rotatedPos.y) >= (p.Size.Y*0.5 + Math.Abs(avatarSize.y)))
- {
- return false;
- }
- if (Math.Abs(rotatedPos.z) >= (p.Size.Z*0.5 + Math.Abs(avatarSize.z)))
- {
- return false;
- }
- return true;
- }
-
- private bool check_all_prims(POSCharacter c)
- {
- for (int i = 0; i < _prims.Count; ++i)
- {
- if (check_collision(c, _prims[i]))
- return true;
- }
- return false;
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- }
-
- public override float Simulate(float timeStep)
- {
- float fps = 0;
- for (int i = 0; i < _characters.Count; ++i)
- {
- fps++;
- POSCharacter character = _characters[i];
-
- float oldposX = character.Position.X;
- float oldposY = character.Position.Y;
- float oldposZ = character.Position.Z;
-
- if (!character.Flying)
- {
- character._target_velocity.Z += gravity*timeStep;
- }
-
- bool forcedZ = false;
- character.Position.X += character._target_velocity.X*timeStep;
- character.Position.Y += character._target_velocity.Y*timeStep;
-
- if (character.Position.Y < 0)
- {
- character.Position.Y = 0.1F;
- }
- else if (character.Position.Y >= 256)
- {
- character.Position.Y = 255.9F;
- }
-
- if (character.Position.X < 0)
- {
- character.Position.X = 0.1F;
- }
- else if (character.Position.X >= 256)
- {
- character.Position.X = 255.9F;
- }
-
- float terrainheight = _heightMap[(int) character.Position.Y*256 + (int) character.Position.X];
- if (character.Position.Z + (character._target_velocity.Z*timeStep) < terrainheight + 2)
- {
- character.Position.Z = terrainheight + 1.0f;
- forcedZ = true;
- }
- else
- {
- character.Position.Z += character._target_velocity.Z*timeStep;
- }
-
- /// this is it -- the magic you've all been waiting for! Ladies and gentlemen --
- /// Completely Bogus Collision Detection!!!
- /// better known as the CBCD algorithm
-
- if (check_all_prims(character))
- {
- character.Position.Z = oldposZ; // first try Z axis
- if (check_all_prims(character))
- {
- character.Position.Z = oldposZ + 0.4f; // try harder
- if (check_all_prims(character))
- {
- character.Position.X = oldposX;
- character.Position.Y = oldposY;
- character.Position.Z = oldposZ;
- character.Position.X = character.Position.X + (character._target_velocity.X*timeStep);
- if (check_all_prims(character))
- {
- character.Position.X = oldposX;
- }
- character.Position.Y = character.Position.Y + (character._target_velocity.Y*timeStep);
- if (check_all_prims(character))
- {
- character.Position.Y = oldposY;
- }
- }
- else
- {
- forcedZ = true;
- }
- }
- else
- {
- forcedZ = true;
- }
- }
-
- if (character.Position.Y < 0)
- {
- character.Position.Y = 0.1F;
- }
- else if (character.Position.Y >= 256)
- {
- character.Position.Y = 255.9F;
- }
-
- if (character.Position.X < 0)
- {
- character.Position.X = 0.1F;
- }
- else if (character.Position.X >= 256)
- {
- character.Position.X = 255.9F;
- }
-
- character._velocity.X = (character.Position.X - oldposX)/timeStep;
- character._velocity.Y = (character.Position.Y - oldposY)/timeStep;
-
- if (forcedZ)
- {
- character._velocity.Z = 0;
- character._target_velocity.Z = 0;
- character.RequestPhysicsterseUpdate();
- }
- else
- {
- character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
- }
- }
- return fps;
- }
-
- public override void GetResults()
- {
- }
-
- public override bool IsThreaded
- {
- get { return (false); // for now we won't be multithreaded
- }
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- _heightMap = heightMap;
- }
-
- public override void DeleteTerrain()
- {
- }
- }
-
- public class POSCharacter : PhysicsActor
- {
- private PhysicsVector _position;
- public PhysicsVector _velocity;
- public PhysicsVector _target_velocity = PhysicsVector.Zero;
- private PhysicsVector _acceleration;
- private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
- private bool flying;
- private bool iscolliding;
-
- public POSCharacter()
- {
- _velocity = new PhysicsVector();
- _position = new PhysicsVector();
- _acceleration = new PhysicsVector();
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Agent; }
- set { return; }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool Flying
- {
- get { return flying; }
- set { flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set { _position = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return new PhysicsVector(0.5f, 0.5f, 1.0f); }
- set { }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set { _target_velocity = value; }
- }
-
- public override Quaternion Orientation
- {
- get { return Quaternion.Identity; }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public override bool Kinematic
- {
- get { return true; }
- set { }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
- }
-
- public class POSPrim : PhysicsActor
- {
- private PhysicsVector _position;
- private PhysicsVector _velocity;
- private PhysicsVector _acceleration;
- private PhysicsVector _size;
- private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
- private Quaternion _orientation;
- private bool iscolliding;
-
- public POSPrim()
- {
- _velocity = new PhysicsVector();
- _position = new PhysicsVector();
- _acceleration = new PhysicsVector();
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Prim; }
- set { return; }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set { _position = value; }
- }
-
- public override PhysicsVector Size
- {
- get { return _size; }
- set { _size = value; }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
-
- public override Quaternion Orientation
- {
- get { return _orientation; }
- set { _orientation = value; }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public override bool Kinematic
- {
- get { return true; }
- set { }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
- public override bool Flying
- {
- get { return false; }
- set { }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 Axiom.Math;
+using OpenSim.Framework;
+using OpenSim.Region.Physics.Manager;
+
+namespace OpenSim.Region.Physics.POSPlugin
+{
+ ///
+ /// for now will be a very POS physics engine
+ ///
+ public class POSPlugin : IPhysicsPlugin
+ {
+ public POSPlugin()
+ {
+ }
+
+ public bool Init()
+ {
+ return true;
+ }
+
+ public PhysicsScene GetScene()
+ {
+ return new POSScene();
+ }
+
+ public string GetName()
+ {
+ return ("POS");
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ public class POSScene : PhysicsScene
+ {
+ private List _characters = new List();
+ private List _prims = new List();
+ private float[] _heightMap;
+ private const float gravity = -9.8f;
+
+ public POSScene()
+ {
+ }
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+ public override void Dispose()
+ {
+
+ }
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ POSCharacter act = new POSCharacter();
+ act.Position = position;
+ _characters.Add(act);
+ return act;
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ POSPrim p = (POSPrim) prim;
+ if (_prims.Contains(p))
+ {
+ _prims.Remove(p);
+ }
+ }
+
+ public override void RemoveAvatar(PhysicsActor character)
+ {
+ POSCharacter act = (POSCharacter) character;
+ if (_characters.Contains(act))
+ {
+ _characters.Remove(act);
+ }
+ }
+
+/*
+ public override PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation)
+ {
+ return null;
+ }
+*/
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint localID)
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
+ {
+ POSPrim prim = new POSPrim();
+ prim.Position = position;
+ prim.Orientation = rotation;
+ prim.Size = size;
+ _prims.Add(prim);
+ return prim;
+ }
+
+ private bool check_collision(POSCharacter c, POSPrim p)
+ {
+ /*
+ Console.WriteLine("checking whether " + c + " collides with " + p +
+ " absX: " + Math.Abs(p.Position.X - c.Position.X) +
+ " sizeX: " + p.Size.X * 0.5 + 0.5);
+ */
+
+ Vector3 rotatedPos = p.Orientation.Inverse()*
+ new Vector3(c.Position.X - p.Position.X, c.Position.Y - p.Position.Y,
+ c.Position.Z - p.Position.Z);
+ Vector3 avatarSize = p.Orientation.Inverse()*new Vector3(c.Size.X, c.Size.Y, c.Size.Z);
+
+ if (Math.Abs(rotatedPos.x) >= (p.Size.X*0.5 + Math.Abs(avatarSize.x)))
+ {
+ return false;
+ }
+ if (Math.Abs(rotatedPos.y) >= (p.Size.Y*0.5 + Math.Abs(avatarSize.y)))
+ {
+ return false;
+ }
+ if (Math.Abs(rotatedPos.z) >= (p.Size.Z*0.5 + Math.Abs(avatarSize.z)))
+ {
+ return false;
+ }
+ return true;
+ }
+
+ private bool check_all_prims(POSCharacter c)
+ {
+ for (int i = 0; i < _prims.Count; ++i)
+ {
+ if (check_collision(c, _prims[i]))
+ {
+
+ return true;
+ }
+
+ }
+
+ return false;
+ }
+
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ public override float Simulate(float timeStep)
+ {
+ float fps = 0;
+ for (int i = 0; i < _characters.Count; ++i)
+ {
+ fps++;
+ POSCharacter character = _characters[i];
+
+ float oldposX = character.Position.X;
+ float oldposY = character.Position.Y;
+ float oldposZ = character.Position.Z;
+
+ if (!character.Flying)
+ {
+ character._target_velocity.Z += gravity*timeStep;
+ }
+
+ bool forcedZ = false;
+ character.Position.X += character._target_velocity.X*timeStep;
+ character.Position.Y += character._target_velocity.Y*timeStep;
+
+ if (character.Position.Y < 0)
+ {
+ character.Position.Y = 0.1F;
+ }
+ else if (character.Position.Y >= Constants.RegionSize)
+ {
+ character.Position.Y = Constants.RegionSize - 0.1f;
+ }
+
+ if (character.Position.X < 0)
+ {
+ character.Position.X = 0.1F;
+ }
+ else if (character.Position.X >= Constants.RegionSize)
+ {
+ character.Position.X = Constants.RegionSize - 0.1f;
+ }
+
+ float terrainheight = _heightMap[(int)character.Position.Y * Constants.RegionSize + (int)character.Position.X];
+ if (character.Position.Z + (character._target_velocity.Z*timeStep) < terrainheight + 2)
+ {
+ character.Position.Z = terrainheight + 1.0f;
+ forcedZ = true;
+ }
+ else
+ {
+ character.Position.Z += character._target_velocity.Z*timeStep;
+ }
+
+ /// this is it -- the magic you've all been waiting for! Ladies and gentlemen --
+ /// Completely Bogus Collision Detection!!!
+ /// better known as the CBCD algorithm
+
+ if (check_all_prims(character))
+ {
+ character.Position.Z = oldposZ; // first try Z axis
+ if (check_all_prims(character))
+ {
+ character.Position.Z = oldposZ + 0.4f; // try harder
+ if (check_all_prims(character))
+ {
+ character.Position.X = oldposX;
+ character.Position.Y = oldposY;
+ character.Position.Z = oldposZ;
+ character.Position.X = character.Position.X + (character._target_velocity.X*timeStep);
+ if (check_all_prims(character))
+ {
+ character.Position.X = oldposX;
+ }
+ character.Position.Y = character.Position.Y + (character._target_velocity.Y*timeStep);
+ if (check_all_prims(character))
+ {
+ character.Position.Y = oldposY;
+ }
+ }
+ else
+ {
+ forcedZ = true;
+ }
+ }
+ else
+ {
+ forcedZ = true;
+ }
+ }
+
+ if (character.Position.Y < 0)
+ {
+ character.Position.Y = 0.1F;
+ }
+ else if (character.Position.Y >= Constants.RegionSize)
+ {
+ character.Position.Y = Constants.RegionSize - 0.1f;
+ }
+
+ if (character.Position.X < 0)
+ {
+ character.Position.X = 0.1F;
+ }
+ else if (character.Position.X >= Constants.RegionSize)
+ {
+ character.Position.X = Constants.RegionSize - 0.1f;
+ }
+
+ character._velocity.X = (character.Position.X - oldposX)/timeStep;
+ character._velocity.Y = (character.Position.Y - oldposY)/timeStep;
+
+ if (forcedZ)
+ {
+ character._velocity.Z = 0;
+ character._target_velocity.Z = 0;
+ ((PhysicsActor)character).IsColliding = true;
+ character.RequestPhysicsterseUpdate();
+ }
+ else
+ {
+ ((PhysicsActor)character).IsColliding = false;
+ character._velocity.Z = (character.Position.Z - oldposZ)/timeStep;
+ }
+ }
+ return fps;
+ }
+
+ public override void GetResults()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ get { return (false); // for now we won't be multithreaded
+ }
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ _heightMap = heightMap;
+ }
+
+ public override void DeleteTerrain()
+ {
+ }
+ }
+
+ public class POSCharacter : PhysicsActor
+ {
+ private PhysicsVector _position;
+ public PhysicsVector _velocity;
+ public PhysicsVector _target_velocity = PhysicsVector.Zero;
+ private PhysicsVector _acceleration;
+ private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
+ private bool flying;
+ private bool iscolliding;
+
+ public POSCharacter()
+ {
+ _velocity = new PhysicsVector();
+ _position = new PhysicsVector();
+ _acceleration = new PhysicsVector();
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Agent; }
+ set { return; }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Flying
+ {
+ get { return flying; }
+ set { flying = value; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set { _position = value; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return new PhysicsVector(0.5f, 0.5f, 1.0f); }
+ set { }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set { _target_velocity = value; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return Quaternion.Identity; }
+ set { }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return true; }
+ set { }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+
+ public class POSPrim : PhysicsActor
+ {
+ private PhysicsVector _position;
+ private PhysicsVector _velocity;
+ private PhysicsVector _acceleration;
+ private PhysicsVector _size;
+ private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
+ private Quaternion _orientation;
+ private bool iscolliding;
+
+ public POSPrim()
+ {
+ _velocity = new PhysicsVector();
+ _position = new PhysicsVector();
+ _acceleration = new PhysicsVector();
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Prim; }
+ set { return; }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set { _position = value; }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return _size; }
+ set { _size = value; }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set { _velocity = value; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return _orientation; }
+ set { _orientation = value; }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return true; }
+ set { }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+ public override bool Flying
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+
+ }
+}
diff --git a/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs b/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs
index dc4427061b..7ae94c1e9f 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/AssemblyInfo.cs
@@ -55,4 +55,4 @@ using System.Runtime.InteropServices;
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
-[assembly : AssemblyVersion("1.0.*")]
\ No newline at end of file
+[assembly : AssemblyVersion("1.0.*")]
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index dbb3281f14..8853d0da3f 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -1,548 +1,599 @@
-/*/*
-* 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 OpenSim 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 OpenSim.Framework;
-using OpenSim.Region.Physics.Manager;
-using PhysXWrapper;
-using Quaternion=Axiom.Math.Quaternion;
-
-namespace OpenSim.Region.Physics.PhysXPlugin
-{
- ///
- /// Will be the PhysX plugin but for now will be a very basic physics engine
- ///
- public class PhysXPlugin : IPhysicsPlugin
- {
- private PhysXScene _mScene;
-
- public PhysXPlugin()
- {
- }
-
- public bool Init()
- {
- return true;
- }
-
- public PhysicsScene GetScene()
- {
- if (_mScene == null)
- {
- _mScene = new PhysXScene();
- }
- return (_mScene);
- }
-
- public string GetName()
- {
- return ("RealPhysX");
- }
-
- public void Dispose()
- {
- }
- }
-
- public class PhysXScene : PhysicsScene
- {
- private List _characters = new List();
- private List _prims = new List();
- private float[] _heightMap = null;
- private NxPhysicsSDK mySdk;
- private NxScene scene;
-
- public PhysXScene()
- {
- mySdk = NxPhysicsSDK.CreateSDK();
- Console.WriteLine("Sdk created - now creating scene");
- scene = mySdk.CreateScene();
- }
-
- public override void Initialise(IMesher meshmerizer)
- {
- // Does nothing right now
- }
-
-
- public override PhysicsActor AddAvatar(string avName, PhysicsVector position, uint localID)
- {
- Vec3 pos = new Vec3();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z;
- PhysXCharacter act = new PhysXCharacter(scene.AddCharacter(pos));
- act.Position = position;
- _characters.Add(act);
- return act;
- }
-
- public override void RemovePrim(PhysicsActor prim)
- {
- }
-
- public override void RemoveAvatar(PhysicsActor actor)
- {
- }
-
- private PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation, uint localID)
- {
- Vec3 pos = new Vec3();
- pos.X = position.X;
- pos.Y = position.Y;
- pos.Z = position.Z;
- Vec3 siz = new Vec3();
- siz.X = size.X;
- siz.Y = size.Y;
- siz.Z = size.Z;
- PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz));
- _prims.Add(act);
- return act;
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, uint localID) //To be removed
- {
- return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
- }
-
- public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
- PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
- {
- return AddPrim(position, size, rotation,localID);
- }
-
- public override void AddPhysicsActorTaint(PhysicsActor prim)
- {
- }
-
- public override float Simulate(float timeStep)
- {
- float fps = 0f;
- try
- {
- foreach (PhysXCharacter actor in _characters)
- {
- actor.Move(timeStep);
- }
- scene.Simulate(timeStep);
- scene.FetchResults();
- scene.UpdateControllers();
-
- foreach (PhysXCharacter actor in _characters)
- {
- actor.UpdatePosition();
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e.Message);
- }
- return fps;
- }
-
- public override void GetResults()
- {
- }
-
- public override bool IsThreaded
- {
- get { return (false); // for now we won't be multithreaded
- }
- }
-
- public override void SetTerrain(float[] heightMap)
- {
- if (_heightMap != null)
- {
- Console.WriteLine("PhysX - deleting old terrain");
- scene.DeleteTerrain();
- }
- _heightMap = heightMap;
- scene.AddTerrain(heightMap);
- }
-
- public override void DeleteTerrain()
- {
- scene.DeleteTerrain();
- }
- }
-
- public class PhysXCharacter : PhysicsActor
- {
- private PhysicsVector _position;
- private PhysicsVector _velocity;
- private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
- private PhysicsVector _acceleration;
- private NxCharacter _character;
- private bool flying;
- private bool iscolliding = false;
- private float gravityAccel;
-
- public PhysXCharacter(NxCharacter character)
- {
- _velocity = new PhysicsVector();
- _position = new PhysicsVector();
- _acceleration = new PhysicsVector();
- _character = character;
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Agent; }
- set { return; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override bool Flying
- {
- get { return flying; }
- set { flying = value; }
- }
-
- public override bool IsColliding
- {
- get { return iscolliding; }
- set { iscolliding = value; }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override PhysicsVector Position
- {
- get { return _position; }
- set
- {
- _position = value;
- Vec3 ps = new Vec3();
- ps.X = value.X;
- ps.Y = value.Y;
- ps.Z = value.Z;
- _character.Position = ps;
- }
- }
-
- public override PhysicsVector Size
- {
- get { return PhysicsVector.Zero; }
- set { }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
-
- public override bool Kinematic
- {
- get { return false; }
- set { }
- }
-
- public override Quaternion Orientation
- {
- get { return Quaternion.Identity; }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
- public void Move(float timeStep)
- {
- Vec3 vec = new Vec3();
- vec.X = _velocity.X*timeStep;
- vec.Y = _velocity.Y*timeStep;
- if (flying)
- {
- vec.Z = (_velocity.Z)*timeStep;
- }
- else
- {
- gravityAccel += -9.8f;
- vec.Z = (gravityAccel + _velocity.Z)*timeStep;
- }
- int res = _character.Move(vec);
- if (res == 1)
- {
- gravityAccel = 0;
- }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public void UpdatePosition()
- {
- Vec3 vec = _character.Position;
- _position.X = vec.X;
- _position.Y = vec.Y;
- _position.Z = vec.Z;
- }
- }
-
-
- public class PhysXPrim : PhysicsActor
- {
- private PhysicsVector _velocity;
- private PhysicsVector _acceleration;
- private PhysicsVector m_rotationalVelocity;
- private NxActor _prim;
-
- public PhysXPrim(NxActor prim)
- {
- _velocity = new PhysicsVector();
- _acceleration = new PhysicsVector();
- _prim = prim;
- }
-
- public override int PhysicsActorType
- {
- get { return (int) ActorTypes.Prim; }
- set { return; }
- }
-
- public override bool IsPhysical
- {
- get { return false; }
- set { return; }
- }
-
- public override bool SetAlwaysRun
- {
- get { return false; }
- set { return; }
- }
-
- public override bool ThrottleUpdates
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector RotationalVelocity
- {
- get { return m_rotationalVelocity; }
- set { m_rotationalVelocity = value; }
- }
-
- public override bool Flying
- {
- get { return false; //no flying prims for you
- }
- set { }
- }
-
- public override bool IsColliding
- {
- get { return false; }
- set { }
- }
-
- public override bool CollidingGround
- {
- get { return false; }
- set { return; }
- }
-
- public override bool CollidingObj
- {
- get { return false; }
- set { return; }
- }
-
- public override PhysicsVector Position
- {
- get
- {
- PhysicsVector pos = new PhysicsVector();
- Vec3 vec = _prim.Position;
- pos.X = vec.X;
- pos.Y = vec.Y;
- pos.Z = vec.Z;
- return pos;
- }
- set
- {
- PhysicsVector vec = value;
- Vec3 pos = new Vec3();
- pos.X = vec.X;
- pos.Y = vec.Y;
- pos.Z = vec.Z;
- _prim.Position = pos;
- }
- }
-
- public override PrimitiveBaseShape Shape
- {
- set { return; }
- }
-
- public override PhysicsVector Velocity
- {
- get { return _velocity; }
- set { _velocity = value; }
- }
-
- public override bool Kinematic
- {
- get { return _prim.Kinematic; }
- set { _prim.Kinematic = value; }
- }
-
- public override Quaternion Orientation
- {
- get
- {
- Quaternion res = new Quaternion();
- PhysXWrapper.Quaternion quat = _prim.GetOrientation();
- res.w = quat.W;
- res.x = quat.X;
- res.y = quat.Y;
- res.z = quat.Z;
- return res;
- }
- set { }
- }
-
- public override PhysicsVector Acceleration
- {
- get { return _acceleration; }
- }
-
- public void SetAcceleration(PhysicsVector accel)
- {
- _acceleration = accel;
- }
-
- public override void AddForce(PhysicsVector force)
- {
- }
-
- public override void SetMomentum(PhysicsVector momentum)
- {
- }
-
- public override PhysicsVector Size
- {
- get { return PhysicsVector.Zero; }
- set { }
- }
-
- public override float Mass
- {
- get { return 0f; }
- }
-
- public override PhysicsVector Force
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector CenterOfMass
- {
- get { return PhysicsVector.Zero; }
- }
-
- public override PhysicsVector GeometricCenter
- {
- get { return PhysicsVector.Zero; }
- }
- }
-}
\ No newline at end of file
+/*/*
+* 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 OpenSim 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 OpenSim.Framework;
+using OpenSim.Region.Physics.Manager;
+using PhysXWrapper;
+using Quaternion=Axiom.Math.Quaternion;
+
+namespace OpenSim.Region.Physics.PhysXPlugin
+{
+ ///
+ /// Will be the PhysX plugin but for now will be a very basic physics engine
+ ///
+ public class PhysXPlugin : IPhysicsPlugin
+ {
+ private PhysXScene _mScene;
+
+ public PhysXPlugin()
+ {
+ }
+
+ public bool Init()
+ {
+ return true;
+ }
+
+ public PhysicsScene GetScene()
+ {
+ if (_mScene == null)
+ {
+ _mScene = new PhysXScene();
+ }
+ return (_mScene);
+ }
+
+ public string GetName()
+ {
+ return ("RealPhysX");
+ }
+
+ public void Dispose()
+ {
+ }
+ }
+
+ public class PhysXScene : PhysicsScene
+ {
+ private List _characters = new List();
+ private List _prims = new List();
+ private float[] _heightMap = null;
+ private NxPhysicsSDK mySdk;
+ private NxScene scene;
+
+ public PhysXScene()
+ {
+ mySdk = NxPhysicsSDK.CreateSDK();
+ Console.WriteLine("Sdk created - now creating scene");
+ scene = mySdk.CreateScene();
+ }
+
+ public override void Initialise(IMesher meshmerizer)
+ {
+ // Does nothing right now
+ }
+ public override void Dispose()
+ {
+
+ }
+
+ public override PhysicsActor AddAvatar(string avName, PhysicsVector position, PhysicsVector size)
+ {
+ Vec3 pos = new Vec3();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z;
+ PhysXCharacter act = new PhysXCharacter(scene.AddCharacter(pos));
+ act.Position = position;
+ _characters.Add(act);
+ return act;
+ }
+
+ public override void RemovePrim(PhysicsActor prim)
+ {
+ }
+
+ public override void RemoveAvatar(PhysicsActor actor)
+ {
+ }
+
+ private PhysicsActor AddPrim(PhysicsVector position, PhysicsVector size, Quaternion rotation, uint localID)
+ {
+ Vec3 pos = new Vec3();
+ pos.X = position.X;
+ pos.Y = position.Y;
+ pos.Z = position.Z;
+ Vec3 siz = new Vec3();
+ siz.X = size.X;
+ siz.Y = size.Y;
+ siz.Z = size.Z;
+ PhysXPrim act = new PhysXPrim(scene.AddNewBox(pos, siz));
+ _prims.Add(act);
+ return act;
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, uint localID) //To be removed
+ {
+ return AddPrimShape(primName, pbs, position, size, rotation, false,localID);
+ }
+
+ public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, PhysicsVector position,
+ PhysicsVector size, Quaternion rotation, bool isPhysical, uint localID)
+ {
+ return AddPrim(position, size, rotation,localID);
+ }
+
+ public override void AddPhysicsActorTaint(PhysicsActor prim)
+ {
+ }
+
+ public override float Simulate(float timeStep)
+ {
+ float fps = 0f;
+ try
+ {
+ foreach (PhysXCharacter actor in _characters)
+ {
+ actor.Move(timeStep);
+ }
+ scene.Simulate(timeStep);
+ scene.FetchResults();
+ scene.UpdateControllers();
+
+ foreach (PhysXCharacter actor in _characters)
+ {
+ actor.UpdatePosition();
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine(e.Message);
+ }
+ return fps;
+ }
+
+ public override void GetResults()
+ {
+ }
+
+ public override bool IsThreaded
+ {
+ get { return (false); // for now we won't be multithreaded
+ }
+ }
+
+ public override void SetTerrain(float[] heightMap)
+ {
+ if (_heightMap != null)
+ {
+ Console.WriteLine("PhysX - deleting old terrain");
+ scene.DeleteTerrain();
+ }
+ _heightMap = heightMap;
+ scene.AddTerrain(heightMap);
+ }
+
+ public override void DeleteTerrain()
+ {
+ scene.DeleteTerrain();
+ }
+ }
+
+ public class PhysXCharacter : PhysicsActor
+ {
+ private PhysicsVector _position;
+ private PhysicsVector _velocity;
+ private PhysicsVector m_rotationalVelocity = PhysicsVector.Zero;
+ private PhysicsVector _acceleration;
+ private NxCharacter _character;
+ private bool flying;
+ private bool iscolliding = false;
+ private float gravityAccel;
+
+ public PhysXCharacter(NxCharacter character)
+ {
+ _velocity = new PhysicsVector();
+ _position = new PhysicsVector();
+ _acceleration = new PhysicsVector();
+ _character = character;
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Agent; }
+ set { return; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Flying
+ {
+ get { return flying; }
+ set { flying = value; }
+ }
+
+ public override bool IsColliding
+ {
+ get { return iscolliding; }
+ set { iscolliding = value; }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get { return _position; }
+ set
+ {
+ _position = value;
+ Vec3 ps = new Vec3();
+ ps.X = value.X;
+ ps.Y = value.Y;
+ ps.Z = value.Z;
+ _character.Position = ps;
+ }
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return PhysicsVector.Zero; }
+ set { }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set { _velocity = value; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override Quaternion Orientation
+ {
+ get { return Quaternion.Identity; }
+ set { }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+ public void Move(float timeStep)
+ {
+ Vec3 vec = new Vec3();
+ vec.X = _velocity.X*timeStep;
+ vec.Y = _velocity.Y*timeStep;
+ if (flying)
+ {
+ vec.Z = (_velocity.Z)*timeStep;
+ }
+ else
+ {
+ gravityAccel += -9.8f;
+ vec.Z = (gravityAccel + _velocity.Z)*timeStep;
+ }
+ int res = _character.Move(vec);
+ if (res == 1)
+ {
+ gravityAccel = 0;
+ }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public void UpdatePosition()
+ {
+ Vec3 vec = _character.Position;
+ _position.X = vec.X;
+ _position.Y = vec.Y;
+ _position.Z = vec.Z;
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+
+
+ public class PhysXPrim : PhysicsActor
+ {
+ private PhysicsVector _velocity;
+ private PhysicsVector _acceleration;
+ private PhysicsVector m_rotationalVelocity;
+ private NxActor _prim;
+
+ public PhysXPrim(NxActor prim)
+ {
+ _velocity = new PhysicsVector();
+ _acceleration = new PhysicsVector();
+ _prim = prim;
+ }
+
+ public override int PhysicsActorType
+ {
+ get { return (int) ActorTypes.Prim; }
+ set { return; }
+ }
+
+ public override bool IsPhysical
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool SetAlwaysRun
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Grabbed
+ {
+ set { return; }
+ }
+
+ public override bool Selected
+ {
+ set { return; }
+ }
+
+ public override bool ThrottleUpdates
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override PhysicsVector RotationalVelocity
+ {
+ get { return m_rotationalVelocity; }
+ set { m_rotationalVelocity = value; }
+ }
+
+ public override bool Flying
+ {
+ get { return false; //no flying prims for you
+ }
+ set { }
+ }
+
+ public override bool IsColliding
+ {
+ get { return false; }
+ set { }
+ }
+
+ public override bool CollidingGround
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool CollidingObj
+ {
+ get { return false; }
+ set { return; }
+ }
+
+ public override bool Stopped
+ {
+ get { return false; }
+ }
+
+ public override PhysicsVector Position
+ {
+ get
+ {
+ PhysicsVector pos = new PhysicsVector();
+ Vec3 vec = _prim.Position;
+ pos.X = vec.X;
+ pos.Y = vec.Y;
+ pos.Z = vec.Z;
+ return pos;
+ }
+ set
+ {
+ PhysicsVector vec = value;
+ Vec3 pos = new Vec3();
+ pos.X = vec.X;
+ pos.Y = vec.Y;
+ pos.Z = vec.Z;
+ _prim.Position = pos;
+ }
+ }
+
+ public override PrimitiveBaseShape Shape
+ {
+ set { return; }
+ }
+
+ public override PhysicsVector Velocity
+ {
+ get { return _velocity; }
+ set { _velocity = value; }
+ }
+
+ public override float CollisionScore
+ {
+ get { return 0f; }
+ }
+
+ public override bool Kinematic
+ {
+ get { return _prim.Kinematic; }
+ set { _prim.Kinematic = value; }
+ }
+
+ public override Quaternion Orientation
+ {
+ get
+ {
+ Quaternion res = new Quaternion();
+ PhysXWrapper.Quaternion quat = _prim.GetOrientation();
+ res.w = quat.W;
+ res.x = quat.X;
+ res.y = quat.Y;
+ res.z = quat.Z;
+ return res;
+ }
+ set { }
+ }
+
+ public override PhysicsVector Acceleration
+ {
+ get { return _acceleration; }
+ }
+
+ public void SetAcceleration(PhysicsVector accel)
+ {
+ _acceleration = accel;
+ }
+
+ public override void AddForce(PhysicsVector force)
+ {
+ }
+
+ public override void SetMomentum(PhysicsVector momentum)
+ {
+ }
+
+ public override PhysicsVector Size
+ {
+ get { return PhysicsVector.Zero; }
+ set { }
+ }
+
+ public override float Mass
+ {
+ get { return 0f; }
+ }
+
+ public override PhysicsVector Force
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector CenterOfMass
+ {
+ get { return PhysicsVector.Zero; }
+ }
+
+ public override PhysicsVector GeometricCenter
+ {
+ get { return PhysicsVector.Zero; }
+ }
+ public override void CrossingFailure()
+ {
+
+ }
+ }
+}
diff --git a/OpenSim/Region/ScriptEngine/Common/Executor.cs b/OpenSim/Region/ScriptEngine/Common/Executor.cs
index 6f6c3930ff..0f610f804e 100644
--- a/OpenSim/Region/ScriptEngine/Common/Executor.cs
+++ b/OpenSim/Region/ScriptEngine/Common/Executor.cs
@@ -1,146 +1,92 @@
-/*
-* 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 OpenSim 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.Remoting.Lifetime;
-
-namespace OpenSim.Region.ScriptEngine.Common
-{
- public class Executor : MarshalByRefObject
- {
- // Private instance for each script
-
- private IScript m_Script;
- private Dictionary Events = new Dictionary();
- private bool m_Running = true;
- //private List Scripts = new List();
-
- public Executor(IScript Script)
- {
- m_Script = Script;
- }
-
- // Object never expires
- public override Object InitializeLifetimeService()
- {
- //Console.WriteLine("Executor: InitializeLifetimeService()");
- // return null;
- ILease lease = (ILease) base.InitializeLifetimeService();
-
- if (lease.CurrentState == LeaseState.Initial)
- {
- lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
-// lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
-// lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
- }
- return lease;
- }
-
- public AppDomain GetAppDomain()
- {
- return AppDomain.CurrentDomain;
- }
-
- public void ExecuteEvent(string FunctionName, object[] args)
- {
- // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
- // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
- //try
- //{
- if (m_Running == false)
- {
- // Script is inactive, do not execute!
- return;
- }
-
- string EventName = m_Script.State() + "_event_" + FunctionName;
-
-#if DEBUG
- Console.WriteLine("ScriptEngine: Script event function name: " + EventName);
-#endif
-
- //type.InvokeMember(EventName, BindingFlags.InvokeMethod, null, m_Script, args);
-
- //Console.WriteLine("ScriptEngine Executor.ExecuteEvent: \"" + EventName + "\"");
-
- if (Events.ContainsKey(EventName) == false)
- {
- // Not found, create
- Type type = m_Script.GetType();
- try
- {
- MethodInfo mi = type.GetMethod(EventName);
- Events.Add(EventName, mi);
- }
- catch
- {
- // Event name not found, cache it as not found
- Events.Add(EventName, null);
- }
- }
-
- // Get event
- MethodInfo ev = null;
- Events.TryGetValue(EventName, out ev);
-
- if (ev == null) // No event by that name!
- {
- //Console.WriteLine("ScriptEngine Can not find any event named: \"" + EventName + "\"");
- return;
- }
-
-#if DEBUG
- Console.WriteLine("ScriptEngine: Executing function name: " + EventName);
-#endif
- // Found
- //try
- //{
- // Invoke it
- ev.Invoke(m_Script, args);
-
- //}
- //catch (Exception e)
- //{
- // // TODO: Send to correct place
- // Console.WriteLine("ScriptEngine Exception attempting to executing script function: " + e.ToString());
- //}
-
-
- //}
- //catch { }
- }
-
-
- public void StopScript()
- {
- m_Running = false;
- }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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.Remoting.Lifetime;
+
+namespace OpenSim.Region.ScriptEngine.Common
+{
+ public class Executor : ExecutorBase
+ {
+ // Cache functions by keeping a reference to them in a dictionary
+ private Dictionary Events = new Dictionary();
+
+ public Executor(IScript script) : base(script)
+ {
+ }
+
+ protected override void DoExecuteEvent(string FunctionName, object[] args)
+ {
+ // IMPORTANT: Types and MemberInfo-derived objects require a LOT of memory.
+ // Instead use RuntimeTypeHandle, RuntimeFieldHandle and RunTimeHandle (IntPtr) instead!
+
+ string EventName = m_Script.State + "_event_" + FunctionName;
+
+//#if DEBUG
+// Console.WriteLine("ScriptEngine: Script event function name: " + EventName);
+//#endif
+
+ if (Events.ContainsKey(EventName) == false)
+ {
+ // Not found, create
+ Type type = m_Script.GetType();
+ try
+ {
+ MethodInfo mi = type.GetMethod(EventName);
+ Events.Add(EventName, mi);
+ }
+ catch
+ {
+ // Event name not found, cache it as not found
+ Events.Add(EventName, null);
+ }
+ }
+
+ // Get event
+ MethodInfo ev = null;
+ Events.TryGetValue(EventName, out ev);
+
+ if (ev == null) // No event by that name!
+ {
+ //Console.WriteLine("ScriptEngine Can not find any event named: \String.Empty + EventName + "\String.Empty);
+ return;
+ }
+
+//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
+#if DEBUG
+ Console.WriteLine("ScriptEngine: Executing function name: " + EventName);
+#endif
+ // Found
+ ev.Invoke(m_Script, args);
+
+ }
+
+ }
+}
diff --git a/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
new file mode 100644
index 0000000000..4fe4b71ced
--- /dev/null
+++ b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
@@ -0,0 +1,108 @@
+/*
+* 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 OpenSim 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.Runtime.Remoting.Lifetime;
+using System.Text;
+
+namespace OpenSim.Region.ScriptEngine.Common
+{
+ public abstract class ExecutorBase : MarshalByRefObject
+ {
+ ///
+ /// Contains the script to execute functions in.
+ ///
+ protected IScript m_Script;
+ ///
+ /// If set to False events will not be executed.
+ ///
+ protected bool m_Running = true;
+
+ ///
+ /// Create a new instance of ExecutorBase
+ ///
+ ///
+ public ExecutorBase(IScript Script)
+ {
+ m_Script = Script;
+ }
+
+ ///
+ /// Make sure our object does not timeout when in AppDomain. (Called by ILease base class)
+ ///
+ ///
+ public override Object InitializeLifetimeService()
+ {
+ //Console.WriteLine("Executor: InitializeLifetimeService()");
+ // return null;
+ ILease lease = (ILease)base.InitializeLifetimeService();
+
+ if (lease.CurrentState == LeaseState.Initial)
+ {
+ lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
+ // lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
+ // lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
+ }
+ return lease;
+ }
+
+ ///
+ /// Get current AppDomain
+ ///
+ /// Current AppDomain
+ public AppDomain GetAppDomain()
+ {
+ return AppDomain.CurrentDomain;
+ }
+
+ ///
+ /// Execute a specific function/event in script.
+ ///
+ /// Name of function to execute
+ /// Arguments to pass to function
+ public void ExecuteEvent(string FunctionName, object[] args)
+ {
+ if (m_Running == false)
+ {
+ // Script is inactive, do not execute!
+ return;
+ }
+ DoExecuteEvent(FunctionName, args);
+ }
+ protected abstract void DoExecuteEvent(string FunctionName, object[] args);
+
+ ///
+ /// Stop script from running. Event execution will be ignored.
+ ///
+ public void StopScript()
+ {
+ m_Running = false;
+ }
+
+ }
+}
diff --git a/OpenSim/Region/ScriptEngine/Common/IScript.cs b/OpenSim/Region/ScriptEngine/Common/IScript.cs
index 30f318f896..0e2a95e9fc 100644
--- a/OpenSim/Region/ScriptEngine/Common/IScript.cs
+++ b/OpenSim/Region/ScriptEngine/Common/IScript.cs
@@ -1,36 +1,41 @@
-/*
-* 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 OpenSim 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.
-*
-*/
-
-namespace OpenSim.Region.ScriptEngine.Common
-{
- public interface IScript
- {
- string State();
- Executor Exec { get; }
- }
-}
\ No newline at end of file
+/*
+* 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 OpenSim 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 OpenSim.Region.ScriptEngine.Common.ScriptEngineBase;
+
+namespace OpenSim.Region.ScriptEngine.Common
+{
+ public interface IScript
+ {
+ string State { get; set; }
+ ExecutorBase Exec { get; }
+ string Source { get; set; }
+ void Start(LSL_BuiltIn_Commands_Interface BuiltIn_Commands);
+ EventQueueManager.Queue_llDetectParams_Struct llDetectParams { get; set; }
+ }
+}
diff --git a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
similarity index 94%
rename from OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs
rename to OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
index 438cdd9633..870884c705 100644
--- a/OpenSim/Region/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BaseClass.cs
@@ -1,2133 +1,2212 @@
-/*
-* 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 OpenSim 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.Runtime.Remoting.Lifetime;
-using System.Threading;
-using OpenSim.Region.ScriptEngine.Common;
-using integer = System.Int32;
-using key = System.String;
-using vector = OpenSim.Region.ScriptEngine.Common.LSL_Types.Vector3;
-using rotation = OpenSim.Region.ScriptEngine.Common.LSL_Types.Quaternion;
-
-namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler.LSL
-{
- //[Serializable]
- public class LSL_BaseClass : MarshalByRefObject, LSL_BuiltIn_Commands_Interface, IScript
- {
-
- //
- // Included as base for any LSL-script that is compiled.
- // Any function added here will be accessible to the LSL script. But it must also be added to "LSL_BuiltIn_Commands_Interface" in "OpenSim.Region.ScriptEngine.Common" class.
- //
- // Security note: This script will be running inside an restricted AppDomain. Currently AppDomain is not very restricted.zxs
- //
-
- // Object never expires
- public override Object InitializeLifetimeService()
- {
- //Console.WriteLine("LSL_BaseClass: InitializeLifetimeService()");
- // return null;
- ILease lease = (ILease) base.InitializeLifetimeService();
-
- if (lease.CurrentState == LeaseState.Initial)
- {
- lease.InitialLeaseTime = TimeSpan.Zero; // TimeSpan.FromMinutes(1);
- //lease.SponsorshipTimeout = TimeSpan.FromMinutes(2);
- //lease.RenewOnCallTime = TimeSpan.FromSeconds(2);
- }
- return lease;
- }
-
-
- private Executor m_Exec;
-
- public Executor Exec
- {
- get
- {
- if (m_Exec == null)
- m_Exec = new Executor(this);
- return m_Exec;
- }
- }
-
- public LSL_BuiltIn_Commands_Interface m_LSL_Functions;
- public string SourceCode = "";
-
- public LSL_BaseClass()
- {
- }
-
- public string State()
- {
- return m_LSL_Functions.State();
- }
-
-
- public void Start(LSL_BuiltIn_Commands_Interface LSL_Functions)
- {
- m_LSL_Functions = LSL_Functions;
-
- //MainLog.Instance.Notice("ScriptEngine", "LSL_BaseClass.Start() called.");
-
- // Get this AppDomain's settings and display some of them.
- AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation;
- Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}",
- ads.ApplicationName,
- ads.ApplicationBase,
- ads.ConfigurationFile
- );
-
- // Display the name of the calling AppDomain and the name
- // of the second domain.
- // NOTE: The application's thread has transitioned between
- // AppDomains.
- Console.WriteLine("Calling to '{0}'.",
- Thread.GetDomain().FriendlyName
- );
-
- return;
- }
-
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- // They are only forwarders to LSL_BuiltIn_Commands.cs
- //
- public double llSin(double f)
- {
- return m_LSL_Functions.llSin(f);
- }
-
- public double llCos(double f)
- {
- return m_LSL_Functions.llCos(f);
- }
-
- public double llTan(double f)
- {
- return m_LSL_Functions.llTan(f);
- }
-
- public double llAtan2(double x, double y)
- {
- return m_LSL_Functions.llAtan2(x, y);
- }
-
- public double llSqrt(double f)
- {
- return m_LSL_Functions.llSqrt(f);
- }
-
- public double llPow(double fbase, double fexponent)
- {
- return m_LSL_Functions.llPow(fbase, fexponent);
- }
-
- public int llAbs(int i)
- {
- return m_LSL_Functions.llAbs(i);
- }
-
- public double llFabs(double f)
- {
- return m_LSL_Functions.llFabs(f);
- }
-
- public double llFrand(double mag)
- {
- return m_LSL_Functions.llFrand(mag);
- }
-
- public int llFloor(double f)
- {
- return m_LSL_Functions.llFloor(f);
- }
-
- public int llCeil(double f)
- {
- return m_LSL_Functions.llCeil(f);
- }
-
- public int llRound(double f)
- {
- return m_LSL_Functions.llRound(f);
- }
-
- public double llVecMag(vector v)
- {
- return m_LSL_Functions.llVecMag(v);
- }
-
- public vector llVecNorm(vector v)
- {
- return m_LSL_Functions.llVecNorm(v);
- }
-
- public double llVecDist(vector a, vector b)
- {
- return m_LSL_Functions.llVecDist(a, b);
- }
-
- public vector llRot2Euler(rotation r)
- {
- return m_LSL_Functions.llRot2Euler(r);
- }
-
- public rotation llEuler2Rot(vector v)
- {
- return m_LSL_Functions.llEuler2Rot(v);
- }
-
- public rotation llAxes2Rot(vector fwd, vector left, vector up)
- {
- return m_LSL_Functions.llAxes2Rot(fwd, left, up);
- }
-
- public vector llRot2Fwd(rotation r)
- {
- return m_LSL_Functions.llRot2Fwd(r);
- }
-
- public vector llRot2Left(rotation r)
- {
- return m_LSL_Functions.llRot2Left(r);
- }
-
- public vector llRot2Up(rotation r)
- {
- return m_LSL_Functions.llRot2Up(r);
- }
-
- public rotation llRotBetween(vector start, vector end)
- {
- return m_LSL_Functions.llRotBetween(start, end);
- }
-
- public void llWhisper(int channelID, string text)
- {
- m_LSL_Functions.llWhisper(channelID, text);
- }
-
- public void llSay(int channelID, string text)
- {
- m_LSL_Functions.llSay(channelID, text);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llShout(int channelID, string text)
- {
- m_LSL_Functions.llShout(channelID, text);
- }
-
- public int llListen(int channelID, string name, string ID, string msg)
- {
- return m_LSL_Functions.llListen(channelID, name, ID, msg);
- }
-
- public void llListenControl(int number, int active)
- {
- m_LSL_Functions.llListenControl(number, active);
- }
-
- public void llListenRemove(int number)
- {
- m_LSL_Functions.llListenRemove(number);
- }
-
- public void llSensor(string name, string id, int type, double range, double arc)
- {
- m_LSL_Functions.llSensor(name, id, type, range, arc);
- }
-
- public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate)
- {
- m_LSL_Functions.llSensorRepeat(name, id, type, range, arc, rate);
- }
-
- public void llSensorRemove()
- {
- m_LSL_Functions.llSensorRemove();
- }
-
- public string llDetectedName(int number)
- {
- return m_LSL_Functions.llDetectedName(number);
- }
-
- public string llDetectedKey(int number)
- {
- return m_LSL_Functions.llDetectedKey(number);
- }
-
- public string llDetectedOwner(int number)
- {
- return m_LSL_Functions.llDetectedOwner(number);
- }
-
- public int llDetectedType(int number)
- {
- return m_LSL_Functions.llDetectedType(number);
- }
-
- public vector llDetectedPos(int number)
- {
- return m_LSL_Functions.llDetectedPos(number);
- }
-
- public vector llDetectedVel(int number)
- {
- return m_LSL_Functions.llDetectedVel(number);
- }
-
- public vector llDetectedGrab(int number)
- {
- return m_LSL_Functions.llDetectedGrab(number);
- }
-
- public rotation llDetectedRot(int number)
- {
- return m_LSL_Functions.llDetectedRot(number);
- }
-
- public int llDetectedGroup(int number)
- {
- return m_LSL_Functions.llDetectedGroup(number);
- }
-
- public int llDetectedLinkNumber(int number)
- {
- return m_LSL_Functions.llDetectedLinkNumber(number);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llDie()
- {
- m_LSL_Functions.llDie();
- }
-
- public double llGround(vector offset)
- {
- return m_LSL_Functions.llGround(offset);
- }
-
- public double llCloud(vector offset)
- {
- return m_LSL_Functions.llCloud(offset);
- }
-
- public vector llWind(vector offset)
- {
- return m_LSL_Functions.llWind(offset);
- }
-
- public void llSetStatus(int status, int value)
- {
- m_LSL_Functions.llSetStatus(status, value);
- }
-
- public int llGetStatus(int status)
- {
- return m_LSL_Functions.llGetStatus(status);
- }
-
- public void llSetScale(vector scale)
- {
- m_LSL_Functions.llSetScale(scale);
- }
-
- public vector llGetScale()
- {
- return m_LSL_Functions.llGetScale();
- }
-
- public void llSetColor(vector color, int face)
- {
- m_LSL_Functions.llSetColor(color, face);
- }
-
- public double llGetAlpha(int face)
- {
- return m_LSL_Functions.llGetAlpha(face);
- }
-
- public void llSetAlpha(double alpha, int face)
- {
- m_LSL_Functions.llSetAlpha(alpha, face);
- }
-
- public vector llGetColor(int face)
- {
- return m_LSL_Functions.llGetColor(face);
- }
-
- public void llSetTexture(string texture, int face)
- {
- m_LSL_Functions.llSetTexture(texture, face);
- }
-
- public void llScaleTexture(double u, double v, int face)
- {
- m_LSL_Functions.llScaleTexture(u, v, face);
- }
-
- public void llOffsetTexture(double u, double v, int face)
- {
- m_LSL_Functions.llOffsetTexture(u, v, face);
- }
-
- public void llRotateTexture(double rotation, int face)
- {
- m_LSL_Functions.llRotateTexture(rotation, face);
- }
-
- public string llGetTexture(int face)
- {
- return m_LSL_Functions.llGetTexture(face);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llSetPos(vector pos)
- {
- m_LSL_Functions.llSetPos(pos);
- }
-
- public vector llGetPos()
- {
- return m_LSL_Functions.llGetPos();
- }
-
- public vector llGetLocalPos()
- {
- return m_LSL_Functions.llGetLocalPos();
- }
-
- public void llSetRot(rotation rot)
- {
- m_LSL_Functions.llSetRot(rot);
- }
-
- public rotation llGetRot()
- {
- return m_LSL_Functions.llGetRot();
- }
-
- public rotation llGetLocalRot()
- {
- return m_LSL_Functions.llGetLocalRot();
- }
-
- public void llSetForce(vector force, int local)
- {
- m_LSL_Functions.llSetForce(force, local);
- }
-
- public vector llGetForce()
- {
- return m_LSL_Functions.llGetForce();
- }
-
- public int llTarget(vector position, double range)
- {
- return m_LSL_Functions.llTarget(position, range);
- }
-
- public void llTargetRemove(int number)
- {
- m_LSL_Functions.llTargetRemove(number);
- }
-
- public int llRotTarget(rotation rot, double error)
- {
- return m_LSL_Functions.llRotTarget(rot, error);
- }
-
- public void llRotTargetRemove(int number)
- {
- m_LSL_Functions.llRotTargetRemove(number);
- }
-
- public void llMoveToTarget(vector target, double tau)
- {
- m_LSL_Functions.llMoveToTarget(target, tau);
- }
-
- public void llStopMoveToTarget()
- {
- m_LSL_Functions.llStopMoveToTarget();
- }
-
- public void llApplyImpulse(vector force, int local)
- {
- m_LSL_Functions.llApplyImpulse(force, local);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llApplyRotationalImpulse(vector force, int local)
- {
- m_LSL_Functions.llApplyRotationalImpulse(force, local);
- }
-
- public void llSetTorque(vector torque, int local)
- {
- m_LSL_Functions.llSetTorque(torque, local);
- }
-
- public vector llGetTorque()
- {
- return m_LSL_Functions.llGetTorque();
- }
-
- public void llSetForceAndTorque(vector force, vector torque, int local)
- {
- m_LSL_Functions.llSetForceAndTorque(force, torque, local);
- }
-
- public vector llGetVel()
- {
- return m_LSL_Functions.llGetVel();
- }
-
- public vector llGetAccel()
- {
- return m_LSL_Functions.llGetAccel();
- }
-
- public vector llGetOmega()
- {
- return m_LSL_Functions.llGetOmega();
- }
-
- public double llGetTimeOfDay()
- {
- return m_LSL_Functions.llGetTimeOfDay();
- }
-
- public double llGetWallclock()
- {
- return m_LSL_Functions.llGetWallclock();
- }
-
- public double llGetTime()
- {
- return m_LSL_Functions.llGetTime();
- }
-
- public void llResetTime()
- {
- m_LSL_Functions.llResetTime();
- }
-
- public double llGetAndResetTime()
- {
- return m_LSL_Functions.llGetAndResetTime();
- }
-
- public void llSound()
- {
- m_LSL_Functions.llSound();
- }
-
- public void llPlaySound(string sound, double volume)
- {
- m_LSL_Functions.llPlaySound(sound, volume);
- }
-
- public void llLoopSound(string sound, double volume)
- {
- m_LSL_Functions.llLoopSound(sound, volume);
- }
-
- public void llLoopSoundMaster(string sound, double volume)
- {
- m_LSL_Functions.llLoopSoundMaster(sound, volume);
- }
-
- public void llLoopSoundSlave(string sound, double volume)
- {
- m_LSL_Functions.llLoopSoundSlave(sound, volume);
- }
-
- public void llPlaySoundSlave(string sound, double volume)
- {
- m_LSL_Functions.llPlaySoundSlave(sound, volume);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llTriggerSound(string sound, double volume)
- {
- m_LSL_Functions.llTriggerSound(sound, volume);
- }
-
- public void llStopSound()
- {
- m_LSL_Functions.llStopSound();
- }
-
- public void llPreloadSound(string sound)
- {
- m_LSL_Functions.llPreloadSound(sound);
- }
-
- public string llGetSubString(string src, int start, int end)
- {
- return m_LSL_Functions.llGetSubString(src, start, end);
- }
-
- public string llDeleteSubString(string src, int start, int end)
- {
- return m_LSL_Functions.llDeleteSubString(src, start, end);
- }
-
- public string llInsertString(string dst, int position, string src)
- {
- return m_LSL_Functions.llInsertString(dst, position, src);
- }
-
- public string llToUpper(string source)
- {
- return m_LSL_Functions.llToUpper(source);
- }
-
- public string llToLower(string source)
- {
- return m_LSL_Functions.llToLower(source);
- }
-
- public int llGiveMoney(string destination, int amount)
- {
- return m_LSL_Functions.llGiveMoney(destination, amount);
- }
-
- public void llMakeExplosion()
- {
- m_LSL_Functions.llMakeExplosion();
- }
-
- public void llMakeFountain()
- {
- m_LSL_Functions.llMakeFountain();
- }
-
- public void llMakeSmoke()
- {
- m_LSL_Functions.llMakeSmoke();
- }
-
- public void llMakeFire()
- {
- m_LSL_Functions.llMakeFire();
- }
-
- public void llRezObject(string inventory, vector pos, rotation rot, int param)
- {
- m_LSL_Functions.llRezObject(inventory, pos, rot, param);
- }
-
- public void llLookAt(vector target, double strength, double damping)
- {
- m_LSL_Functions.llLookAt(target, strength, damping);
- }
-
- public void llStopLookAt()
- {
- m_LSL_Functions.llStopLookAt();
- }
-
- public void llSetTimerEvent(double sec)
- {
- m_LSL_Functions.llSetTimerEvent(sec);
- }
-
- public void llSleep(double sec)
- {
- m_LSL_Functions.llSleep(sec);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public double llGetMass()
- {
- return m_LSL_Functions.llGetMass();
- }
-
- public void llCollisionFilter(string name, string id, int accept)
- {
- m_LSL_Functions.llCollisionFilter(name, id, accept);
- }
-
- public void llTakeControls(int controls, int accept, int pass_on)
- {
- m_LSL_Functions.llTakeControls(controls, accept, pass_on);
- }
-
- public void llReleaseControls()
- {
- m_LSL_Functions.llReleaseControls();
- }
-
- public void llAttachToAvatar(int attachment)
- {
- m_LSL_Functions.llAttachToAvatar(attachment);
- }
-
- public void llDetachFromAvatar()
- {
- m_LSL_Functions.llDetachFromAvatar();
- }
-
- public void llTakeCamera()
- {
- m_LSL_Functions.llTakeCamera();
- }
-
- public void llReleaseCamera()
- {
- m_LSL_Functions.llReleaseCamera();
- }
-
- public string llGetOwner()
- {
- return m_LSL_Functions.llGetOwner();
- }
-
- public void llInstantMessage(string user, string message)
- {
- m_LSL_Functions.llInstantMessage(user, message);
- }
-
- public void llEmail(string address, string subject, string message)
- {
- m_LSL_Functions.llEmail(address, subject, message);
- }
-
- public void llGetNextEmail(string address, string subject)
- {
- m_LSL_Functions.llGetNextEmail(address, subject);
- }
-
- public string llGetKey()
- {
- return m_LSL_Functions.llGetKey();
- }
-
- public void llSetBuoyancy(double buoyancy)
- {
- m_LSL_Functions.llSetBuoyancy(buoyancy);
- }
-
- public void llSetHoverHeight(double height, int water, double tau)
- {
- m_LSL_Functions.llSetHoverHeight(height, water, tau);
- }
-
- public void llStopHover()
- {
- m_LSL_Functions.llStopHover();
- }
-
- public void llMinEventDelay(double delay)
- {
- m_LSL_Functions.llMinEventDelay(delay);
- }
-
- public void llSoundPreload()
- {
- m_LSL_Functions.llSoundPreload();
- }
-
- public void llRotLookAt(rotation target, double strength, double damping)
- {
- m_LSL_Functions.llRotLookAt(target, strength, damping);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public int llStringLength(string str)
- {
- return m_LSL_Functions.llStringLength(str);
- }
-
- public void llStartAnimation(string anim)
- {
- m_LSL_Functions.llStartAnimation(anim);
- }
-
- public void llStopAnimation(string anim)
- {
- m_LSL_Functions.llStopAnimation(anim);
- }
-
- public void llPointAt()
- {
- m_LSL_Functions.llPointAt();
- }
-
- public void llStopPointAt()
- {
- m_LSL_Functions.llStopPointAt();
- }
-
- public void llTargetOmega(vector axis, double spinrate, double gain)
- {
- m_LSL_Functions.llTargetOmega(axis, spinrate, gain);
- }
-
- public int llGetStartParameter()
- {
- return m_LSL_Functions.llGetStartParameter();
- }
-
- public void llGodLikeRezObject(string inventory, vector pos)
- {
- m_LSL_Functions.llGodLikeRezObject(inventory, pos);
- }
-
- public void llRequestPermissions(string agent, int perm)
- {
- m_LSL_Functions.llRequestPermissions(agent, perm);
- }
-
- public string llGetPermissionsKey()
- {
- return m_LSL_Functions.llGetPermissionsKey();
- }
-
- public int llGetPermissions()
- {
- return m_LSL_Functions.llGetPermissions();
- }
-
- public int llGetLinkNumber()
- {
- return m_LSL_Functions.llGetLinkNumber();
- }
-
- public void llSetLinkColor(int linknumber, vector color, int face)
- {
- m_LSL_Functions.llSetLinkColor(linknumber, color, face);
- }
-
- public void llCreateLink(string target, int parent)
- {
- m_LSL_Functions.llCreateLink(target, parent);
- }
-
- public void llBreakLink(int linknum)
- {
- m_LSL_Functions.llBreakLink(linknum);
- }
-
- public void llBreakAllLinks()
- {
- m_LSL_Functions.llBreakAllLinks();
- }
-
- public string llGetLinkKey(int linknum)
- {
- return m_LSL_Functions.llGetLinkKey(linknum);
- }
-
- public string llGetLinkName(int linknum)
- {
- return m_LSL_Functions.llGetLinkName(linknum);
- }
-
- public int llGetInventoryNumber(int type)
- {
- return m_LSL_Functions.llGetInventoryNumber(type);
- }
-
- public string llGetInventoryName(int type, int number)
- {
- return m_LSL_Functions.llGetInventoryName(type, number);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llSetScriptState(string name, int run)
- {
- m_LSL_Functions.llSetScriptState(name, run);
- }
-
- public double llGetEnergy()
- {
- return m_LSL_Functions.llGetEnergy();
- }
-
- public void llGiveInventory(string destination, string inventory)
- {
- m_LSL_Functions.llGiveInventory(destination, inventory);
- }
-
- public void llRemoveInventory(string item)
- {
- m_LSL_Functions.llRemoveInventory(item);
- }
-
- public void llSetText(string text, vector color, double alpha)
- {
- m_LSL_Functions.llSetText(text, color, alpha);
- }
-
- public double llWater(vector offset)
- {
- return m_LSL_Functions.llWater(offset);
- }
-
- public void llPassTouches(int pass)
- {
- m_LSL_Functions.llPassTouches(pass);
- }
-
- public string llRequestAgentData(string id, int data)
- {
- return m_LSL_Functions.llRequestAgentData(id, data);
- }
-
- public string llRequestInventoryData(string name)
- {
- return m_LSL_Functions.llRequestInventoryData(name);
- }
-
- public void llSetDamage(double damage)
- {
- m_LSL_Functions.llSetDamage(damage);
- }
-
- public void llTeleportAgentHome(string agent)
- {
- m_LSL_Functions.llTeleportAgentHome(agent);
- }
-
- public void llModifyLand(int action, int brush)
- {
- m_LSL_Functions.llModifyLand(action, brush);
- }
-
- public void llCollisionSound(string impact_sound, double impact_volume)
- {
- m_LSL_Functions.llCollisionSound(impact_sound, impact_volume);
- }
-
- public void llCollisionSprite(string impact_sprite)
- {
- m_LSL_Functions.llCollisionSprite(impact_sprite);
- }
-
- public string llGetAnimation(string id)
- {
- return m_LSL_Functions.llGetAnimation(id);
- }
-
- public void llResetScript()
- {
- m_LSL_Functions.llResetScript();
- }
-
- public void llMessageLinked(int linknum, int num, string str, string id)
- {
- m_LSL_Functions.llMessageLinked(linknum, num, str, id);
- }
-
- public void llPushObject(string target, vector impulse, vector ang_impulse, int local)
- {
- m_LSL_Functions.llPushObject(target, impulse, ang_impulse, local);
- }
-
- public void llPassCollisions(int pass)
- {
- m_LSL_Functions.llPassCollisions(pass);
- }
-
- public string llGetScriptName()
- {
- return m_LSL_Functions.llGetScriptName();
- }
-
- public int llGetNumberOfSides()
- {
- return m_LSL_Functions.llGetNumberOfSides();
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public rotation llAxisAngle2Rot(vector axis, double angle)
- {
- return m_LSL_Functions.llAxisAngle2Rot(axis, angle);
- }
-
- public vector llRot2Axis(rotation rot)
- {
- return m_LSL_Functions.llRot2Axis(rot);
- }
-
- public void llRot2Angle()
- {
- m_LSL_Functions.llRot2Angle();
- }
-
- public double llAcos(double val)
- {
- return m_LSL_Functions.llAcos(val);
- }
-
- public double llAsin(double val)
- {
- return m_LSL_Functions.llAsin(val);
- }
-
- public double llAngleBetween(rotation a, rotation b)
- {
- return m_LSL_Functions.llAngleBetween(a, b);
- }
-
- public string llGetInventoryKey(string name)
- {
- return m_LSL_Functions.llGetInventoryKey(name);
- }
-
- public void llAllowInventoryDrop(int add)
- {
- m_LSL_Functions.llAllowInventoryDrop(add);
- }
-
- public vector llGetSunDirection()
- {
- return m_LSL_Functions.llGetSunDirection();
- }
-
- public vector llGetTextureOffset(int face)
- {
- return m_LSL_Functions.llGetTextureOffset(face);
- }
-
- public vector llGetTextureScale(int side)
- {
- return m_LSL_Functions.llGetTextureScale(side);
- }
-
- public double llGetTextureRot(int side)
- {
- return m_LSL_Functions.llGetTextureRot(side);
- }
-
- public int llSubStringIndex(string source, string pattern)
- {
- return m_LSL_Functions.llSubStringIndex(source, pattern);
- }
-
- public string llGetOwnerKey(string id)
- {
- return m_LSL_Functions.llGetOwnerKey(id);
- }
-
- public vector llGetCenterOfMass()
- {
- return m_LSL_Functions.llGetCenterOfMass();
- }
-
- public LSL_Types.list llListSort(LSL_Types.list src, int stride, int ascending)
- {
- return m_LSL_Functions.llListSort(src, stride, ascending);
- }
-
- public int llGetListLength(LSL_Types.list src)
- {
- return m_LSL_Functions.llGetListLength(src);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public int llList2Integer(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llList2Integer(src, index);
- }
-
- public double osList2Double(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.osList2Double(src, index);
- }
-
- public string llList2String(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llList2String(src, index);
- }
-
- public string llList2Key(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llList2Key(src, index);
- }
-
- public vector llList2Vector(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llList2Vector(src, index);
- }
-
- public rotation llList2Rot(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llList2Rot(src, index);
- }
-
- public LSL_Types.list llList2List(LSL_Types.list src, int start, int end)
- {
- return m_LSL_Functions.llList2List(src, start, end);
- }
-
- public LSL_Types.list llDeleteSubList(LSL_Types.list src, int start, int end)
- {
- return m_LSL_Functions.llDeleteSubList(src, start, end);
- }
-
- public int llGetListEntryType(LSL_Types.list src, int index)
- {
- return m_LSL_Functions.llGetListEntryType(src, index);
- }
-
- public string llList2CSV(LSL_Types.list src)
- {
- return m_LSL_Functions.llList2CSV(src);
- }
-
- public LSL_Types.list llCSV2List(string src)
- {
- return m_LSL_Functions.llCSV2List(src);
- }
-
- public LSL_Types.list llListRandomize(LSL_Types.list src, int stride)
- {
- return m_LSL_Functions.llListRandomize(src, stride);
- }
-
- public LSL_Types.list llList2ListStrided(LSL_Types.list src, int start, int end, int stride)
- {
- return m_LSL_Functions.llList2ListStrided(src, start, end, stride);
- }
-
- public vector llGetRegionCorner()
- {
- return m_LSL_Functions.llGetRegionCorner();
- }
-
- public LSL_Types.list llListInsertList(LSL_Types.list dest, LSL_Types.list src, int start)
- {
- return m_LSL_Functions.llListInsertList(dest, src, start);
- }
-
- public int llListFindList(LSL_Types.list src, LSL_Types.list test)
- {
- return m_LSL_Functions.llListFindList(src, test);
- }
-
- public string llGetObjectName()
- {
- return m_LSL_Functions.llGetObjectName();
- }
-
- public void llSetObjectName(string name)
- {
- m_LSL_Functions.llSetObjectName(name);
- }
-
- public string llGetDate()
- {
- return m_LSL_Functions.llGetDate();
- }
-
- public int llEdgeOfWorld(vector pos, vector dir)
- {
- return m_LSL_Functions.llEdgeOfWorld(pos, dir);
- }
-
- public int llGetAgentInfo(string id)
- {
- return m_LSL_Functions.llGetAgentInfo(id);
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llAdjustSoundVolume(double volume)
- {
- m_LSL_Functions.llAdjustSoundVolume(volume);
- }
-
- public void llSetSoundQueueing(int queue)
- {
- m_LSL_Functions.llSetSoundQueueing(queue);
- }
-
- public void llSetSoundRadius(double radius)
- {
- m_LSL_Functions.llSetSoundRadius(radius);
- }
-
- public string llKey2Name(string id)
- {
- return m_LSL_Functions.llKey2Name(id);
- }
-
- public void llSetTextureAnim(int mode, int face, int sizex, int sizey, double start, double length, double rate)
- {
- m_LSL_Functions.llSetTextureAnim(mode, face, sizex, sizey, start, length, rate);
- }
-
- public void llTriggerSoundLimited(string sound, double volume, vector top_north_east, vector bottom_south_west)
- {
- m_LSL_Functions.llTriggerSoundLimited(sound, volume, top_north_east, bottom_south_west);
- }
-
- public void llEjectFromLand(string pest)
- {
- m_LSL_Functions.llEjectFromLand(pest);
- }
-
- public void llParseString2List()
- {
- m_LSL_Functions.llParseString2List();
- }
-
- public int llOverMyLand(string id)
- {
- return m_LSL_Functions.llOverMyLand(id);
- }
-
- public string llGetLandOwnerAt(vector pos)
- {
- return m_LSL_Functions.llGetLandOwnerAt(pos);
- }
-
- public string llGetNotecardLine(string name, int line)
- {
- return m_LSL_Functions.llGetNotecardLine(name, line);
- }
-
- public vector llGetAgentSize(string id)
- {
- return m_LSL_Functions.llGetAgentSize(id);
- }
-
- public int llSameGroup(string agent)
- {
- return m_LSL_Functions.llSameGroup(agent);
- }
-
- public void llUnSit(string id)
- {
- m_LSL_Functions.llUnSit(id);
- }
-
- public vector llGroundSlope(vector offset)
- {
- return m_LSL_Functions.llGroundSlope(offset);
- }
-
- public vector llGroundNormal(vector offset)
- {
- return m_LSL_Functions.llGroundNormal(offset);
- }
-
- public vector llGroundContour(vector offset)
- {
- return m_LSL_Functions.llGroundContour(offset);
- }
-
- public int llGetAttached()
- {
- return m_LSL_Functions.llGetAttached();
- }
-
- public int llGetFreeMemory()
- {
- return m_LSL_Functions.llGetFreeMemory();
- }
-
- public string llGetRegionName()
- {
- return m_LSL_Functions.llGetRegionName();
- }
-
- public double llGetRegionTimeDilation()
- {
- return m_LSL_Functions.llGetRegionTimeDilation();
- }
-
- public double llGetRegionFPS()
- {
- return m_LSL_Functions.llGetRegionFPS();
- }
-
- //
- // DO NOT MODIFY HERE: MODIFY IN LSL_BuiltIn_Commands.cs
- //
- public void llParticleSystem(List