aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs222
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs183
-rw-r--r--OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs15
3 files changed, 244 insertions, 176 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index e026ffd..7ff163b 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -2103,12 +2103,29 @@ namespace OpenSim.Region.Framework.Scenes
2103 } 2103 }
2104 else 2104 else
2105 { 2105 {
2106 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2106// if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2107 { 2107// {
2108// m_log.DebugFormat( 2108// m_log.DebugFormat(
2109// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", 2109// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2110// Name, part.Name, part.LocalId); 2110// Name, part.Name, part.LocalId);
2111 2111
2112 if (m_scene.PhysicsScene != null &&
2113 part.PhysActor != null &&
2114 Util.GetDistanceTo(AbsolutePosition, pos) <= 30)
2115 {
2116
2117 Vector3 camdif = CameraPosition - part.AbsolutePosition;
2118 camdif.Normalize();
2119
2120// m_log.InfoFormat("sit {0} {1}", offset.ToString(), camdif.ToString());
2121
2122 if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
2123 return;
2124 }
2125
2126 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2127 {
2128
2112 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2129 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2113 canSit = true; 2130 canSit = true;
2114 } 2131 }
@@ -2196,197 +2213,54 @@ namespace OpenSim.Region.Framework.Scenes
2196 SendSitResponse(targetID, offset, Quaternion.Identity); 2213 SendSitResponse(targetID, offset, Quaternion.Identity);
2197 } 2214 }
2198 2215
2199 /* 2216 public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
2200 public void SitRayCastAvatarPosition(SceneObjectPart part)
2201 { 2217 {
2202 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2203 Vector3 StartRayCastPosition = AbsolutePosition;
2204 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2205 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2206 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
2207 }
2208 2218
2209 public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2219 if (status < 0)
2210 {
2211 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2212 if (part != null)
2213 {
2214 if (hitYN)
2215 {
2216 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2217 {
2218 SitRaycastFindEdge(collisionPoint, normal);
2219 m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2220 }
2221 else
2222 {
2223 SitRayCastAvatarPositionCameraZ(part);
2224 }
2225 }
2226 else
2227 {
2228 SitRayCastAvatarPositionCameraZ(part);
2229 }
2230 }
2231 else
2232 { 2220 {
2233 ControllingClient.SendAlertMessage("Sit position no longer exists"); 2221 ControllingClient.SendAlertMessage("Sit position no longer exists");
2234 m_requestedSitTargetUUID = UUID.Zero; 2222 return;
2235 m_requestedSitTargetID = 0;
2236 m_requestedSitOffset = Vector3.Zero;
2237 } 2223 }
2238 2224
2239 } 2225 if (status == 0)
2240 2226 return;
2241 public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part)
2242 {
2243 // Next, try to raycast from the camera Z position
2244 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2245 Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z;
2246 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2247 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2248 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
2249 }
2250 2227
2251 public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2228 SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
2252 { 2229 if (part == null || part.ParentGroup.IsAttachment)
2253 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
2254 if (part != null)
2255 { 2230 {
2256 if (hitYN) 2231 return;
2257 {
2258 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2259 {
2260 SitRaycastFindEdge(collisionPoint, normal);
2261 m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2262 }
2263 else
2264 {
2265 SitRayCastCameraPosition(part);
2266 }
2267 }
2268 else
2269 {
2270 SitRayCastCameraPosition(part);
2271 }
2272 }
2273 else
2274 {
2275 ControllingClient.SendAlertMessage("Sit position no longer exists");
2276 m_requestedSitTargetUUID = UUID.Zero;
2277 m_requestedSitTargetID = 0;
2278 m_requestedSitOffset = Vector3.Zero;
2279 } 2232 }
2280 2233
2281 } 2234// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
2282 2235
2283 public void SitRayCastCameraPosition(SceneObjectPart part) 2236 part.AddSittingAvatar(UUID);
2284 {
2285 // Next, try to raycast from the camera position
2286 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2287 Vector3 StartRayCastPosition = CameraPosition;
2288 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2289 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2290 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
2291 }
2292 2237
2293 public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2238 Vector3 cameraAtOffset = part.GetCameraAtOffset();
2294 { 2239 Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
2295 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2240 bool forceMouselook = part.GetForceMouselook();
2296 if (part != null)
2297 {
2298 if (hitYN)
2299 {
2300 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2301 {
2302 SitRaycastFindEdge(collisionPoint, normal);
2303 m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2304 }
2305 else
2306 {
2307 SitRayHorizontal(part);
2308 }
2309 }
2310 else
2311 {
2312 SitRayHorizontal(part);
2313 }
2314 }
2315 else
2316 {
2317 ControllingClient.SendAlertMessage("Sit position no longer exists");
2318 m_requestedSitTargetUUID = UUID.Zero;
2319 m_requestedSitTargetID = 0;
2320 m_requestedSitOffset = Vector3.Zero;
2321 }
2322 2241
2323 } 2242 ControllingClient.SendSitResponse(
2243 part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
2324 2244
2325 public void SitRayHorizontal(SceneObjectPart part) 2245 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
2326 {
2327 // Next, try to raycast from the avatar position to fwd
2328 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2329 Vector3 StartRayCastPosition = CameraPosition;
2330 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2331 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2332 m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse);
2333 }
2334 2246
2335 public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) 2247 // assuming no autopilot in use
2336 { 2248 Velocity = Vector3.Zero;
2337 SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID); 2249 RemoveFromPhysicalScene();
2338 if (part != null)
2339 {
2340 if (hitYN)
2341 {
2342 if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
2343 {
2344 SitRaycastFindEdge(collisionPoint, normal);
2345 m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
2346 // Next, try to raycast from the camera position
2347 Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
2348 Vector3 StartRayCastPosition = CameraPosition;
2349 Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
2350 float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
2351 //m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
2352 }
2353 else
2354 {
2355 ControllingClient.SendAlertMessage("Sit position not accessable.");
2356 m_requestedSitTargetUUID = UUID.Zero;
2357 m_requestedSitTargetID = 0;
2358 m_requestedSitOffset = Vector3.Zero;
2359 }
2360 }
2361 else
2362 {
2363 ControllingClient.SendAlertMessage("Sit position not accessable.");
2364 m_requestedSitTargetUUID = UUID.Zero;
2365 m_requestedSitTargetID = 0;
2366 m_requestedSitOffset = Vector3.Zero;
2367 }
2368 }
2369 else
2370 {
2371 ControllingClient.SendAlertMessage("Sit position no longer exists");
2372 m_requestedSitTargetUUID = UUID.Zero;
2373 m_requestedSitTargetID = 0;
2374 m_requestedSitOffset = Vector3.Zero;
2375 }
2376 2250
2377 } 2251 Rotation = Orientation;
2252 m_pos = offset;
2378 2253
2379 private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal) 2254 m_requestedSitTargetID = 0; // invalidate the viewer sit comand for now
2380 { 2255 part.ParentGroup.AddAvatar(UUID);
2381 int i = 0;
2382 //throw new NotImplementedException();
2383 //m_requestedSitTargetUUID = UUID.Zero;
2384 //m_requestedSitTargetID = 0;
2385 //m_requestedSitOffset = Vector3.Zero;
2386 2256
2387 SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity); 2257 ParentPart = part;
2258 ParentID = part.LocalId;
2259
2260 Animator.TrySetMovementAnimation("SIT");
2261 SendAvatarDataToAllAgents();
2388 } 2262 }
2389 */ 2263
2390 2264
2391 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) 2265 public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
2392 { 2266 {
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
new file mode 100644
index 0000000..225bff8
--- /dev/null
+++ b/OpenSim/Region/Physics/UbitOdePlugin/ODESitAvatar.cs
@@ -0,0 +1,183 @@
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// Ubit 2012
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Runtime.InteropServices;
32using System.Text;
33using OpenSim.Framework;
34using OpenSim.Region.Physics.Manager;
35using OdeAPI;
36using log4net;
37using OpenMetaverse;
38
39namespace OpenSim.Region.Physics.OdePlugin
40{
41 /// <summary>
42 /// </summary>
43 public class ODESitAvatar
44 {
45 private OdeScene m_scene;
46 private ODERayCastRequestManager m_raymanager;
47
48 public ODESitAvatar(OdeScene pScene, ODERayCastRequestManager raymanager)
49 {
50 m_scene = pScene;
51 m_raymanager = raymanager;
52 }
53
54 private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
55
56 public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
57 {
58 if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
59 {
60 PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
61 return;
62 }
63
64 IntPtr geom = ((OdePrim)actor).prim_geom;
65
66 d.Vector3 dtmp = d.GeomGetPosition(geom);
67 Vector3 geopos;
68 geopos.X = dtmp.X;
69 geopos.Y = dtmp.Y;
70 geopos.Z = dtmp.Z;
71
72
73 d.AABB aabb;
74 Quaternion ori;
75 d.Quaternion qtmp;
76 d.GeomCopyQuaternion(geom, out qtmp);
77 Quaternion geomOri;
78 geomOri.X = qtmp.X;
79 geomOri.Y = qtmp.Y;
80 geomOri.Z = qtmp.Z;
81 geomOri.W = qtmp.W;
82 Quaternion geomInvOri;
83 geomInvOri.X = -qtmp.X;
84 geomInvOri.Y = -qtmp.Y;
85 geomInvOri.Z = -qtmp.Z;
86 geomInvOri.W = qtmp.W;
87
88 Vector3 target = geopos + offset;
89 Vector3 rayDir = target - avCameraPosition;
90 float raylen = rayDir.Length();
91 float t = 1 / raylen;
92 rayDir.X *= t;
93 rayDir.Y *= t;
94 rayDir.Z *= t;
95
96 raylen += 0.5f;
97 List<ContactResult> rayResults;
98
99 rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1);
100 if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID)
101 {
102 d.GeomGetAABB(geom,out aabb);
103 offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
104 ori = geomInvOri;
105 offset *= geomInvOri;
106
107 PhysicsSitResponse(1, actor.LocalID, offset, ori);
108 return;
109 }
110
111 offset = rayResults[0].Pos - geopos;
112 double ang;
113 float s;
114 float c;
115
116 d.GeomClassID geoclass = d.GeomGetClass(geom);
117
118 if (geoclass == d.GeomClassID.SphereClass)
119 {
120 float r = d.GeomSphereGetRadius(geom);
121
122 offset.Normalize();
123 offset *= r;
124
125 ang = Math.Atan2(offset.Y, offset.X);
126 ang *= 0.5d;
127 s = (float)Math.Sin(ang);
128 c = (float)Math.Cos(ang);
129
130 ori = new Quaternion(0, 0, s, c);
131
132 if (r < 0.4f)
133 {
134 offset = new Vector3(0, 0, r);
135 }
136 else if (offset.Z < 0.4f)
137 {
138 t = offset.Z;
139 float rsq = r * r;
140
141 t = 1.0f / (rsq - t * t);
142 offset.X *= t;
143 offset.Y *= t;
144 offset.Z = 0.4f;
145 t = rsq - 0.16f;
146 offset.X *= t;
147 offset.Y *= t;
148 }
149
150 offset += avOffset * ori;
151
152 ori = geomInvOri * ori;
153 offset *= geomInvOri;
154
155 PhysicsSitResponse(1, actor.LocalID, offset, ori);
156 return;
157 }
158
159 Vector3 norm = rayResults[0].Normal;
160
161 if (norm.Z < 0)
162 {
163 PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
164 return;
165 }
166
167 ang = Math.Atan2(-rayDir.Y, -rayDir.X);
168 ang *= 0.5d;
169 s = (float)Math.Sin(ang);
170 c = (float)Math.Cos(ang);
171
172 ori = new Quaternion(0, 0, s, c);
173
174 offset += avOffset * ori;
175
176 ori = geomInvOri * ori;
177 offset *= geomInvOri;
178
179 PhysicsSitResponse(1, actor.LocalID, offset, ori);
180 return;
181 }
182 }
183} \ No newline at end of file
diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 15eb01f..fbf2f0d 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -362,8 +362,7 @@ namespace OpenSim.Region.Physics.OdePlugin
362 362
363 nearCallback = near; 363 nearCallback = near;
364 364
365 m_rayCastManager = new ODERayCastRequestManager(this); 365 m_rayCastManager = new ODERayCastRequestManager(this);
366
367 366
368 lock (OdeLock) 367 lock (OdeLock)
369 { 368 {
@@ -2711,5 +2710,17 @@ namespace OpenSim.Region.Physics.OdePlugin
2711 } 2710 }
2712 return new List<ContactResult>(); 2711 return new List<ContactResult>();
2713 } 2712 }
2713
2714 public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
2715 {
2716 Util.FireAndForget( delegate
2717 {
2718 ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager);
2719 if(sitAvatar != null)
2720 sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse);
2721 });
2722 return 1;
2723 }
2724
2714 } 2725 }
2715} 2726}