aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Client/MXP/ClientStack/MXPClientView.cs5
-rw-r--r--OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs5
-rw-r--r--OpenSim/Framework/IClientAPI.cs1
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs11
-rw-r--r--OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs5
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs73
-rw-r--r--OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs5
-rw-r--r--OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs3
-rw-r--r--OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs1
-rw-r--r--OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs2
-rw-r--r--OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs5
-rw-r--r--OpenSim/Region/Physics/Manager/PhysicsScene.cs36
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs295
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdePlugin.cs23
-rw-r--r--OpenSim/Region/Physics/POSPlugin/POSScene.cs2
-rw-r--r--OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs1
-rw-r--r--OpenSim/Tests/Common/Mock/TestClient.cs4
17 files changed, 475 insertions, 2 deletions
diff --git a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
index d8980c1..a7bcc07 100644
--- a/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
+++ b/OpenSim/Client/MXP/ClientStack/MXPClientView.cs
@@ -1240,6 +1240,11 @@ namespace OpenSim.Client.MXP.ClientStack
1240 // Need to translate to MXP somehow 1240 // Need to translate to MXP somehow
1241 } 1241 }
1242 1242
1243 public void SendCameraConstraint(Vector4 ConstraintPlane)
1244 {
1245
1246 }
1247
1243 public void SendLandParcelOverlay(byte[] data, int sequence_id) 1248 public void SendLandParcelOverlay(byte[] data, int sequence_id)
1244 { 1249 {
1245 // Need to translate to MXP somehow 1250 // Need to translate to MXP somehow
diff --git a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
index 4570395..324b5af 100644
--- a/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
+++ b/OpenSim/Client/VWoHTTP/ClientStack/VWHClientView.cs
@@ -780,6 +780,11 @@ namespace OpenSim.Client.VWoHTTP.ClientStack
780 throw new System.NotImplementedException(); 780 throw new System.NotImplementedException();
781 } 781 }
782 782
783 public void SendCameraConstraint(Vector4 ConstraintPlane)
784 {
785
786 }
787
783 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 788 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
784 { 789 {
785 throw new System.NotImplementedException(); 790 throw new System.NotImplementedException();
diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs
index fea0cea..52d9716 100644
--- a/OpenSim/Framework/IClientAPI.cs
+++ b/OpenSim/Framework/IClientAPI.cs
@@ -1007,6 +1007,7 @@ namespace OpenSim.Framework
1007 1007
1008 void SendLandAccessListData(List<UUID> avatars, uint accessFlag, int localLandID); 1008 void SendLandAccessListData(List<UUID> avatars, uint accessFlag, int localLandID);
1009 void SendForceClientSelectObjects(List<uint> objectIDs); 1009 void SendForceClientSelectObjects(List<uint> objectIDs);
1010 void SendCameraConstraint(Vector4 ConstraintPlane);
1010 void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount); 1011 void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount);
1011 void SendLandParcelOverlay(byte[] data, int sequence_id); 1012 void SendLandParcelOverlay(byte[] data, int sequence_id);
1012 1013
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index a13f6d4..3a93007 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -3779,8 +3779,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3779 } 3779 }
3780 } 3780 }
3781 3781
3782 public void SendCameraConstraint(Vector4 ConstraintPlane)
3783 {
3784 CameraConstraintPacket cpack = (CameraConstraintPacket)PacketPool.Instance.GetPacket(PacketType.CameraConstraint);
3785 cpack.CameraCollidePlane = new CameraConstraintPacket.CameraCollidePlaneBlock();
3786 cpack.CameraCollidePlane.Plane = ConstraintPlane;
3787 m_log.DebugFormat("[CLIENTVIEW]: Constraint {0}", ConstraintPlane);
3788 OutPacket(cpack, ThrottleOutPacketType.Task);
3789 }
3790
3782 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 3791 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
3783 { 3792 {
3793
3794
3784 int notifyCount = ownersAndCount.Count; 3795 int notifyCount = ownersAndCount.Count;
3785 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply); 3796 ParcelObjectOwnersReplyPacket pack = (ParcelObjectOwnersReplyPacket)PacketPool.Instance.GetPacket(PacketType.ParcelObjectOwnersReply);
3786 3797
diff --git a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
index ed38046..62779e7 100644
--- a/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
+++ b/OpenSim/Region/Examples/SimpleModule/MyNpcCharacter.cs
@@ -900,6 +900,11 @@ namespace OpenSim.Region.Examples.SimpleModule
900 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 900 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
901 { 901 {
902 } 902 }
903
904 public void SendCameraConstraint(Vector4 ConstraintPlane)
905 {
906
907 }
903 908
904 public void SendLandParcelOverlay(byte[] data, int sequence_id) 909 public void SendLandParcelOverlay(byte[] data, int sequence_id)
905 { 910 {
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 87207a0..2a8436b 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -186,6 +186,14 @@ namespace OpenSim.Region.Framework.Scenes
186 //PauPaw:Proper PID Controler for autopilot************ 186 //PauPaw:Proper PID Controler for autopilot************
187 private bool m_moveToPositionInProgress; 187 private bool m_moveToPositionInProgress;
188 private Vector3 m_moveToPositionTarget = Vector3.Zero; 188 private Vector3 m_moveToPositionTarget = Vector3.Zero;
189
190 private bool m_followCamAuto = false;
191
192 private int m_movementUpdateCount = 0;
193
194 private const int NumMovementsBetweenRayCast = 5;
195
196 private bool CameraConstraintActive = false;
189 //private int m_moveToPositionStateStatus = 0; 197 //private int m_moveToPositionStateStatus = 0;
190 //***************************************************** 198 //*****************************************************
191 199
@@ -1073,6 +1081,44 @@ namespace OpenSim.Region.Framework.Scenes
1073 } 1081 }
1074 } 1082 }
1075 1083
1084
1085 /// <summary>
1086 /// Callback for the Camera view block check. Gets called with the results of the camera view block test
1087 /// hitYN is true when there's something in the way.
1088 /// </summary>
1089 /// <param name="hitYN"></param>
1090 /// <param name="collisionPoint"></param>
1091 /// <param name="localid"></param>
1092 /// <param name="distance"></param>
1093 public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance)
1094 {
1095 if (m_followCamAuto)
1096 {
1097
1098 if (hitYN)
1099 {
1100 CameraConstraintActive = true;
1101 //m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance);
1102
1103 Vector3 normal = Vector3.Normalize(new Vector3(0,0,collisionPoint.Z) - collisionPoint);
1104 ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint)));
1105 }
1106 else
1107 {
1108 if (((Util.GetDistanceTo(lastPhysPos, AbsolutePosition) > 0.02)
1109 || (Util.GetDistanceTo(m_lastVelocity, m_velocity) > 0.02)
1110 || lastPhysRot != m_bodyRot))
1111 {
1112 if (CameraConstraintActive)
1113 {
1114 ControllingClient.SendCameraConstraint(new Vector4(0, 0.5f, 0.9f, -3000f));
1115 CameraConstraintActive = false;
1116 }
1117 }
1118 }
1119 }
1120 }
1121
1076 /// <summary> 1122 /// <summary>
1077 /// This is the event handler for client movement. If a client is moving, this event is triggering. 1123 /// This is the event handler for client movement. If a client is moving, this event is triggering.
1078 /// </summary> 1124 /// </summary>
@@ -1098,11 +1144,18 @@ namespace OpenSim.Region.Framework.Scenes
1098 // return; 1144 // return;
1099 //} 1145 //}
1100 1146
1147
1148 m_movementUpdateCount++;
1149 if (m_movementUpdateCount >= int.MaxValue)
1150 m_movementUpdateCount = 1;
1151
1152
1101 // Must check for standing up even when PhysicsActor is null, 1153 // Must check for standing up even when PhysicsActor is null,
1102 // since sitting currently removes avatar from physical scene 1154 // since sitting currently removes avatar from physical scene
1103 //m_log.Debug("agentPos:" + AbsolutePosition.ToString()); 1155 //m_log.Debug("agentPos:" + AbsolutePosition.ToString());
1104 1156
1105 // This is irritating. Really. 1157 // This is irritating. Really.
1158
1106 if (!AbsolutePosition.IsFinite()) 1159 if (!AbsolutePosition.IsFinite())
1107 { 1160 {
1108 RemoveFromPhysicalScene(); 1161 RemoveFromPhysicalScene();
@@ -1157,8 +1210,26 @@ namespace OpenSim.Region.Framework.Scenes
1157 { 1210 {
1158 StandUp(); 1211 StandUp();
1159 } 1212 }
1160
1161 1213
1214
1215
1216 // Check if Client has camera in 'follow cam' or 'build' mode.
1217 Vector3 camdif = (Vector3.One * m_bodyRot - Vector3.One * CameraRotation);
1218
1219 m_followCamAuto = ((m_CameraUpAxis.Z > 0.959f && m_CameraUpAxis.Z < 0.98f)
1220 && (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
1221
1222
1223 // Raycast from the avatar's head to the camera to see if there's anything blocking the view
1224 if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
1225 {
1226
1227 if (m_followCamAuto)
1228 {
1229 Vector3 headadjustment = new Vector3(0, 0, 0.3f);
1230 m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(m_CameraCenter - (m_pos + headadjustment)), Vector3.Distance(m_CameraCenter, (m_pos + headadjustment)) + 0.3f, RayCastCameraCallback);
1231 }
1232 }
1162 1233
1163 m_mouseLook = (flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0; 1234 m_mouseLook = (flags & (uint) AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
1164 1235
diff --git a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
index 776e972..44bd716 100644
--- a/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
+++ b/OpenSim/Region/OptionalModules/Agent/InternetRelayClientView/Server/IRCClientView.cs
@@ -1233,6 +1233,11 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
1233 1233
1234 } 1234 }
1235 1235
1236 public void SendCameraConstraint(Vector4 ConstraintPlane)
1237 {
1238
1239 }
1240
1236 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 1241 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
1237 { 1242 {
1238 1243
diff --git a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
index a1ed6ee..2102db9 100644
--- a/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
+++ b/OpenSim/Region/OptionalModules/World/NPC/NPCAvatar.cs
@@ -904,6 +904,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
904 public void SendForceClientSelectObjects(List<uint> objectIDs) 904 public void SendForceClientSelectObjects(List<uint> objectIDs)
905 { 905 {
906 } 906 }
907 public void SendCameraConstraint(Vector4 ConstraintPlane)
908 {
909 }
907 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 910 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
908 { 911 {
909 } 912 }
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index 83d7a1d..92d5771 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -210,6 +210,7 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
210 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 210 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
211 return returncolliders; 211 return returncolliders;
212 } 212 }
213
213 } 214 }
214 215
215 public class BasicActor : PhysicsActor 216 public class BasicActor : PhysicsActor
diff --git a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
index 58c2a15..e0f856a 100644
--- a/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
+++ b/OpenSim/Region/Physics/BulletDotNETPlugin/BulletDotNETScene.cs
@@ -700,6 +700,8 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
700 m_world.SetCollisionAddedCallback(m_CollisionInterface); 700 m_world.SetCollisionAddedCallback(m_CollisionInterface);
701 } 701 }
702 } 702 }
703
704
703 705
704 } 706 }
705} 707}
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 7e5e812..abed8df 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -817,9 +817,14 @@ namespace OpenSim.Region.Physics.BulletXPlugin
817 GC.Collect(); 817 GC.Collect();
818 BulletXMessage("Terrain erased!", false); 818 BulletXMessage("Terrain erased!", false);
819 } 819 }
820
821
822
820 //this._heightmap = null; 823 //this._heightmap = null;
821 } 824 }
822 825
826
827
823 internal void AddForgottenRigidBody(RigidBody forgottenRigidBody) 828 internal void AddForgottenRigidBody(RigidBody forgottenRigidBody)
824 { 829 {
825 _forgottenRigidBodies.Add(forgottenRigidBody); 830 _forgottenRigidBodies.Add(forgottenRigidBody);
diff --git a/OpenSim/Region/Physics/Manager/PhysicsScene.cs b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
index 410707b..95699fb 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsScene.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsScene.cs
@@ -36,6 +36,8 @@ namespace OpenSim.Region.Physics.Manager
36{ 36{
37 public delegate void physicsCrash(); 37 public delegate void physicsCrash();
38 38
39 public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance);
40
39 public abstract class PhysicsScene 41 public abstract class PhysicsScene
40 { 42 {
41 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 43 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
@@ -152,6 +154,39 @@ namespace OpenSim.Region.Physics.Manager
152 154
153 public abstract bool IsThreaded { get; } 155 public abstract bool IsThreaded { get; }
154 156
157 /// <summary>
158 /// True if the physics plugin supports raycasting against the physics scene
159 /// </summary>
160 public virtual bool SupportsRayCast()
161 {
162 return false;
163 }
164
165 /// <summary>
166 /// Queue a raycast against the physics scene.
167 /// The provided callback method will be called when the raycast is complete
168 ///
169 /// Many physics engines don't support collision testing at the same time as
170 /// manipulating the physics scene, so we queue the request up and callback
171 /// a custom method when the raycast is complete.
172 /// This allows physics engines that give an immediate result to callback immediately
173 /// and ones that don't, to callback when it gets a result back.
174 ///
175 /// ODE for example will not allow you to change the scene while collision testing or
176 /// it asserts, 'opteration not valid for locked space'. This includes adding a ray to the scene.
177 ///
178 /// This is named RayCastWorld to not conflict with modrex's Raycast method.
179 /// </summary>
180 /// <param name="position">Origin of the ray</param>
181 /// <param name="direction">Direction of the ray</param>
182 /// <param name="length">Length of ray in meters</param>
183 /// <param name="retMethod">Method to call when the raycast is complete</param>
184 public virtual void RaycastWorld( Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
185 {
186 if (retMethod != null)
187 retMethod(false, Vector3.Zero, 0, 999999999999f);
188 }
189
155 private class NullPhysicsScene : PhysicsScene 190 private class NullPhysicsScene : PhysicsScene
156 { 191 {
157 private static int m_workIndicator; 192 private static int m_workIndicator;
@@ -240,6 +275,7 @@ namespace OpenSim.Region.Physics.Manager
240 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 275 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
241 return returncolliders; 276 return returncolliders;
242 } 277 }
278
243 } 279 }
244 } 280 }
245 public delegate void JointMoved(PhysicsJoint joint); 281 public delegate void JointMoved(PhysicsJoint joint);
diff --git a/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
new file mode 100644
index 0000000..3a4bb02
--- /dev/null
+++ b/OpenSim/Region/Physics/OdePlugin/ODERayCastRequestManager.cs
@@ -0,0 +1,295 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Runtime.InteropServices;
32using System.Text;
33using OpenMetaverse;
34using OpenSim.Region.Physics.Manager;
35using Ode.NET;
36using log4net;
37
38namespace OpenSim.Region.Physics.OdePlugin
39{
40 /// <summary>
41 /// Processes raycast requests as ODE is in a state to be able to do them.
42 /// This ensures that it's thread safe and there will be no conflicts.
43 /// Requests get returned by a different thread then they were requested by.
44 /// </summary>
45 public class ODERayCastRequestManager
46 {
47 /// <summary>
48 /// Pending Raycast Requests
49 /// </summary>
50 protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
51
52 /// <summary>
53 /// Scene that created this object.
54 /// </summary>
55 private OdeScene m_scene;
56
57 /// <summary>
58 /// ODE contact array to be filled by the collision testing
59 /// </summary>
60 d.ContactGeom[] contacts = new d.ContactGeom[5];
61
62 /// <summary>
63 /// ODE near callback delegate
64 /// </summary>
65 private d.NearCallback nearCallback;
66 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
67 private List<ContactResult> m_contactResults = new List<ContactResult>();
68
69
70 public ODERayCastRequestManager( OdeScene pScene)
71 {
72 m_scene = pScene;
73 nearCallback = near;
74
75 }
76
77 /// <summary>
78 /// Queues a raycast
79 /// </summary>
80 /// <param name="position">Origin of Ray</param>
81 /// <param name="direction">Ray normal</param>
82 /// <param name="length">Ray length</param>
83 /// <param name="retMethod">Return method to send the results</param>
84 public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
85 {
86 lock (m_PendingRequests)
87 {
88 ODERayCastRequest req = new ODERayCastRequest();
89 req.callbackMethod = retMethod;
90 req.length = length;
91 req.Normal = direction;
92 req.Origin = position;
93
94 m_PendingRequests.Add(req);
95 }
96 }
97
98 /// <summary>
99 /// Process all queued raycast requests
100 /// </summary>
101 /// <returns>Time in MS the raycasts took to process.</returns>
102 public int ProcessQueuedRequests()
103 {
104 int time = System.Environment.TickCount;
105 lock (m_PendingRequests)
106 {
107 if (m_PendingRequests.Count > 0)
108 {
109 foreach (ODERayCastRequest req in m_PendingRequests)
110 {
111 if (req.callbackMethod != null) // quick optimization here, don't raycast
112 RayCast(req); // if there isn't anyone to send results to
113
114 }
115
116 m_PendingRequests.Clear();
117 }
118 }
119
120 lock (m_contactResults)
121 m_contactResults.Clear();
122
123 return System.Environment.TickCount - time;
124 }
125
126 /// <summary>
127 /// Method that actually initiates the raycast
128 /// </summary>
129 /// <param name="req"></param>
130 private void RayCast(ODERayCastRequest req)
131 {
132 // Create the ray
133 IntPtr ray = d.CreateRay(m_scene.space, req.length);
134 d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
135
136 // Collide test
137 d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
138
139 // Remove Ray
140 d.GeomDestroy(ray);
141
142
143 // Define default results
144 bool hitYN = false;
145 uint hitConsumerID = 0;
146 float distance = 999999999999f;
147 Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
148
149 // Find closest contact and object.
150 lock (m_contactResults)
151 {
152 foreach(ContactResult cResult in m_contactResults)
153 {
154 if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
155 {
156 closestcontact = cResult.Pos;
157 hitConsumerID = cResult.ConsumerID;
158 distance = cResult.Depth;
159 hitYN = true;
160 }
161 }
162
163 m_contactResults.Clear();
164 }
165
166 // Return results
167 if (req.callbackMethod != null)
168 req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance);
169 }
170
171 // This is the standard Near. Uses space AABBs to speed up detection.
172 private void near(IntPtr space, IntPtr g1, IntPtr g2)
173 {
174 // Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
175 if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
176 {
177 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
178 return;
179
180 // Separating static prim geometry spaces.
181 // We'll be calling near recursivly if one
182 // of them is a space to find all of the
183 // contact points in the space
184 try
185 {
186 d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
187 }
188 catch (AccessViolationException)
189 {
190 m_log.Warn("[PHYSICS]: Unable to collide test a space");
191 return;
192 }
193 //Colliding a space or a geom with a space or a geom. so drill down
194
195 //Collide all geoms in each space..
196 //if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
197 //if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
198 return;
199 }
200
201 if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
202 return;
203
204 int count = 0;
205 try
206 {
207
208 if (g1 == g2)
209 return; // Can't collide with yourself
210
211 lock (contacts)
212 {
213 count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
214 }
215 }
216 catch (SEHException)
217 {
218 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.");
219 }
220 catch (Exception e)
221 {
222 m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
223 return;
224 }
225
226 PhysicsActor p1 = null;
227 PhysicsActor p2 = null;
228
229 if (g1 != IntPtr.Zero)
230 m_scene.actor_name_map.TryGetValue(g1, out p1);
231
232 if (g2 != IntPtr.Zero)
233 m_scene.actor_name_map.TryGetValue(g1, out p2);
234
235 // Loop over contacts, build results.
236 for (int i = 0; i < count; i++)
237 {
238 if (p1 != null) {
239 if (p1 is OdePrim)
240 {
241 ContactResult collisionresult = new ContactResult();
242
243 collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
244 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
245 collisionresult.Depth = contacts[i].depth;
246
247 lock (m_contactResults)
248 m_contactResults.Add(collisionresult);
249 }
250 }
251
252 if (p2 != null)
253 {
254 if (p2 is OdePrim)
255 {
256 ContactResult collisionresult = new ContactResult();
257
258 collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
259 collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
260 collisionresult.Depth = contacts[i].depth;
261
262 lock (m_contactResults)
263 m_contactResults.Add(collisionresult);
264 }
265 }
266
267
268 }
269
270 }
271
272 /// <summary>
273 /// Dereference the creator scene so that it can be garbage collected if needed.
274 /// </summary>
275 internal void Dispose()
276 {
277 m_scene = null;
278 }
279 }
280
281 public struct ODERayCastRequest
282 {
283 public Vector3 Origin;
284 public Vector3 Normal;
285 public float length;
286 public RaycastCallback callbackMethod;
287 }
288
289 public struct ContactResult
290 {
291 public Vector3 Pos;
292 public float Depth;
293 public uint ConsumerID;
294 }
295}
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 889afb6..87357a3 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -306,6 +306,8 @@ namespace OpenSim.Region.Physics.OdePlugin
306 306
307 private volatile int m_global_contactcount = 0; 307 private volatile int m_global_contactcount = 0;
308 308
309 private ODERayCastRequestManager m_rayCastManager;
310
309 /// <summary> 311 /// <summary>
310 /// Initiailizes the scene 312 /// Initiailizes the scene
311 /// Sets many properties that ODE requires to be stable 313 /// Sets many properties that ODE requires to be stable
@@ -321,7 +323,7 @@ namespace OpenSim.Region.Physics.OdePlugin
321 nearCallback = near; 323 nearCallback = near;
322 triCallback = TriCallback; 324 triCallback = TriCallback;
323 triArrayCallback = TriArrayCallback; 325 triArrayCallback = TriArrayCallback;
324 326 m_rayCastManager = new ODERayCastRequestManager(this);
325 lock (OdeLock) 327 lock (OdeLock)
326 { 328 {
327 // Create the world and the first space 329 // Create the world and the first space
@@ -2833,6 +2835,8 @@ namespace OpenSim.Region.Physics.OdePlugin
2833 //if ((framecount % m_randomizeWater) == 0) 2835 //if ((framecount % m_randomizeWater) == 0)
2834 // randomizeWater(waterlevel); 2836 // randomizeWater(waterlevel);
2835 2837
2838 int RayCastTimeMS = m_rayCastManager.ProcessQueuedRequests();
2839
2836 collision_optimized(timeStep); 2840 collision_optimized(timeStep);
2837 2841
2838 lock (_collisionEventPrim) 2842 lock (_collisionEventPrim)
@@ -3377,6 +3381,9 @@ namespace OpenSim.Region.Physics.OdePlugin
3377 3381
3378 public override void Dispose() 3382 public override void Dispose()
3379 { 3383 {
3384 m_rayCastManager.Dispose();
3385 m_rayCastManager = null;
3386
3380 lock (OdeLock) 3387 lock (OdeLock)
3381 { 3388 {
3382 lock (_prims) 3389 lock (_prims)
@@ -3417,6 +3424,20 @@ namespace OpenSim.Region.Physics.OdePlugin
3417 } 3424 }
3418 return returncolliders; 3425 return returncolliders;
3419 } 3426 }
3427
3428 public override bool SupportsRayCast()
3429 {
3430 return true;
3431 }
3432
3433 public override void RaycastWorld(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
3434 {
3435 if (retMethod != null)
3436 {
3437 m_rayCastManager.QueueRequest(position, direction, length, retMethod);
3438 }
3439 }
3440
3420#if USE_DRAWSTUFF 3441#if USE_DRAWSTUFF
3421 // Keyboard callback 3442 // Keyboard callback
3422 public void command(int cmd) 3443 public void command(int cmd)
diff --git a/OpenSim/Region/Physics/POSPlugin/POSScene.cs b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
index 3128477..029dcce 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSScene.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSScene.cs
@@ -272,5 +272,7 @@ namespace OpenSim.Region.Physics.POSPlugin
272 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 272 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
273 return returncolliders; 273 return returncolliders;
274 } 274 }
275
276
275 } 277 }
276} 278}
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index 3082455..e7d989c 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -214,6 +214,7 @@ namespace OpenSim.Region.Physics.PhysXPlugin
214 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>(); 214 Dictionary<uint, float> returncolliders = new Dictionary<uint, float>();
215 return returncolliders; 215 return returncolliders;
216 } 216 }
217
217 } 218 }
218 219
219 public class PhysXCharacter : PhysicsActor 220 public class PhysXCharacter : PhysicsActor
diff --git a/OpenSim/Tests/Common/Mock/TestClient.cs b/OpenSim/Tests/Common/Mock/TestClient.cs
index 21541e1..4b59b50 100644
--- a/OpenSim/Tests/Common/Mock/TestClient.cs
+++ b/OpenSim/Tests/Common/Mock/TestClient.cs
@@ -942,6 +942,10 @@ namespace OpenSim.Tests.Common.Mock
942 { 942 {
943 } 943 }
944 944
945 public void SendCameraConstraint(Vector4 ConstraintPlane)
946 {
947 }
948
945 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount) 949 public void SendLandObjectOwners(LandData land, List<UUID> groups, Dictionary<UUID, int> ownersAndCount)
946 { 950 {
947 } 951 }