diff options
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 409 |
1 files changed, 106 insertions, 303 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index bd94902..64b2ddb 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1942,7 +1942,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1942 | Velocity = Vector3.Zero; | 1942 | Velocity = Vector3.Zero; |
1943 | SendAvatarDataToAllAgents(); | 1943 | SendAvatarDataToAllAgents(); |
1944 | 1944 | ||
1945 | HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); //KF ?? | 1945 | //HandleAgentSit(ControllingClient, m_requestedSitTargetUUID); |
1946 | } | 1946 | } |
1947 | //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); | 1947 | //ControllingClient.SendSitResponse(m_requestedSitTargetID, m_requestedSitOffset, Quaternion.Identity, false, Vector3.Zero, Vector3.Zero, false); |
1948 | m_requestedSitTargetUUID = UUID.Zero; | 1948 | m_requestedSitTargetUUID = UUID.Zero; |
@@ -1979,22 +1979,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1979 | 1979 | ||
1980 | if (ParentID != 0) | 1980 | if (ParentID != 0) |
1981 | { | 1981 | { |
1982 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 1982 | m_log.Debug("StandupCode Executed"); |
1983 | SceneObjectPart part = m_scene.GetSceneObjectPart(ParentID); | ||
1983 | if (part != null) | 1984 | if (part != null) |
1984 | { | 1985 | { |
1985 | part.TaskInventory.LockItemsForRead(true); | ||
1986 | TaskInventoryDictionary taskIDict = part.TaskInventory; | 1986 | TaskInventoryDictionary taskIDict = part.TaskInventory; |
1987 | if (taskIDict != null) | 1987 | if (taskIDict != null) |
1988 | { | 1988 | { |
1989 | foreach (UUID taskID in taskIDict.Keys) | 1989 | lock (taskIDict) |
1990 | { | 1990 | { |
1991 | UnRegisterControlEventsToScript(LocalId, taskID); | 1991 | foreach (UUID taskID in taskIDict.Keys) |
1992 | taskIDict[taskID].PermsMask &= ~( | 1992 | { |
1993 | 2048 | //PERMISSION_CONTROL_CAMERA | 1993 | UnRegisterControlEventsToScript(LocalId, taskID); |
1994 | 4); // PERMISSION_TAKE_CONTROLS | 1994 | taskIDict[taskID].PermsMask &= ~( |
1995 | 2048 | //PERMISSION_CONTROL_CAMERA | ||
1996 | 4); // PERMISSION_TAKE_CONTROLS | ||
1997 | } | ||
1995 | } | 1998 | } |
1996 | } | 1999 | } |
1997 | part.TaskInventory.LockItemsForRead(false); | ||
1998 | 2000 | ||
1999 | // Reset sit target. | 2001 | // Reset sit target. |
2000 | if (part.SitTargetAvatar == UUID) | 2002 | if (part.SitTargetAvatar == UUID) |
@@ -2003,54 +2005,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2003 | ParentPosition = part.GetWorldPosition(); | 2005 | ParentPosition = part.GetWorldPosition(); |
2004 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); | 2006 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); |
2005 | } | 2007 | } |
2006 | // part.GetWorldRotation() is the rotation of the object being sat on | ||
2007 | // Rotation is the sittiing Av's rotation | ||
2008 | |||
2009 | Quaternion partRot; | ||
2010 | // if (part.LinkNum == 1) | ||
2011 | // { // Root prim of linkset | ||
2012 | // partRot = part.ParentGroup.RootPart.RotationOffset; | ||
2013 | // } | ||
2014 | // else | ||
2015 | // { // single or child prim | ||
2016 | |||
2017 | // } | ||
2018 | if (part == null) //CW: Part may be gone. llDie() for example. | ||
2019 | { | ||
2020 | partRot = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | ||
2021 | } | ||
2022 | else | ||
2023 | { | ||
2024 | partRot = part.GetWorldRotation(); | ||
2025 | } | ||
2026 | |||
2027 | Quaternion partIRot = Quaternion.Inverse(partRot); | ||
2028 | |||
2029 | Quaternion avatarRot = Quaternion.Inverse(Quaternion.Inverse(Rotation) * partIRot); // world or. of the av | ||
2030 | Vector3 avStandUp = new Vector3(0.3f, 0f, 0f) * avatarRot; // 0.3M infront of av | ||
2031 | 2008 | ||
2032 | 2009 | if (PhysicsActor == null) | |
2033 | if (m_physicsActor == null) | ||
2034 | { | 2010 | { |
2035 | AddToPhysicalScene(false); | 2011 | AddToPhysicalScene(false); |
2036 | } | 2012 | } |
2037 | //CW: If the part isn't null then we can set the current position | 2013 | |
2038 | if (part != null) | 2014 | m_pos += ParentPosition + new Vector3(0.0f, 0.0f, 2.0f * m_sitAvatarHeight); |
2039 | { | 2015 | ParentPosition = Vector3.Zero; |
2040 | Vector3 avWorldStandUp = avStandUp + part.GetWorldPosition() + ((m_pos - part.OffsetPosition) * partRot); // + av sit offset! | 2016 | |
2041 | AbsolutePosition = avWorldStandUp; //KF: Fix stand up. | 2017 | ParentID = 0; |
2042 | part.IsOccupied = false; | ||
2043 | part.ParentGroup.DeleteAvatar(ControllingClient.AgentId); | ||
2044 | } | ||
2045 | else | ||
2046 | { | ||
2047 | //CW: Since the part doesn't exist, a coarse standup position isn't an issue | ||
2048 | AbsolutePosition = m_lastWorldPosition; | ||
2049 | } | ||
2050 | |||
2051 | m_parentPosition = Vector3.Zero; | ||
2052 | m_parentID = 0; | ||
2053 | m_offsetRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); | ||
2054 | SendAvatarDataToAllAgents(); | 2018 | SendAvatarDataToAllAgents(); |
2055 | m_requestedSitTargetID = 0; | 2019 | m_requestedSitTargetID = 0; |
2056 | 2020 | ||
@@ -2058,7 +2022,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2058 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | 2022 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); |
2059 | } | 2023 | } |
2060 | 2024 | ||
2061 | Animator.UpdateMovementAnimations(); | 2025 | Animator.TrySetMovementAnimation("STAND"); |
2062 | } | 2026 | } |
2063 | 2027 | ||
2064 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) | 2028 | private SceneObjectPart FindNextAvailableSitTarget(UUID targetID) |
@@ -2089,8 +2053,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2089 | Quaternion avSitOrientation = part.SitTargetOrientation; | 2053 | Quaternion avSitOrientation = part.SitTargetOrientation; |
2090 | UUID avOnTargetAlready = part.SitTargetAvatar; | 2054 | UUID avOnTargetAlready = part.SitTargetAvatar; |
2091 | 2055 | ||
2092 | bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); | 2056 | bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero; |
2093 | bool SitTargetisSet = (Vector3.Zero != avSitOffset); //NB Latest SL Spec shows Sit Rotation setting is ignored. | 2057 | bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity; |
2094 | 2058 | ||
2095 | if (SitTargetisSet && SitTargetUnOccupied) | 2059 | if (SitTargetisSet && SitTargetUnOccupied) |
2096 | { | 2060 | { |
@@ -2106,167 +2070,87 @@ namespace OpenSim.Region.Framework.Scenes | |||
2106 | private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) | 2070 | private void SendSitResponse(IClientAPI remoteClient, UUID targetID, Vector3 offset, Quaternion pSitOrientation) |
2107 | { | 2071 | { |
2108 | bool autopilot = true; | 2072 | bool autopilot = true; |
2109 | Vector3 autopilotTarget = new Vector3(); | ||
2110 | Quaternion sitOrientation = Quaternion.Identity; | ||
2111 | Vector3 pos = new Vector3(); | 2073 | Vector3 pos = new Vector3(); |
2074 | Quaternion sitOrientation = pSitOrientation; | ||
2112 | Vector3 cameraEyeOffset = Vector3.Zero; | 2075 | Vector3 cameraEyeOffset = Vector3.Zero; |
2113 | Vector3 cameraAtOffset = Vector3.Zero; | 2076 | Vector3 cameraAtOffset = Vector3.Zero; |
2114 | bool forceMouselook = false; | 2077 | bool forceMouselook = false; |
2115 | 2078 | ||
2116 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); | 2079 | SceneObjectPart part = FindNextAvailableSitTarget(targetID); |
2117 | if (part == null) return; | 2080 | if (part != null) |
2118 | 2081 | { | |
2119 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client | 2082 | // TODO: determine position to sit at based on scene geometry; don't trust offset from client |
2120 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it | 2083 | // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it |
2121 | 2084 | ||
2122 | // part is the prim to sit on | 2085 | // Is a sit target available? |
2123 | // offset is the world-ref vector distance from that prim center to the click-spot | 2086 | Vector3 avSitOffSet = part.SitTargetPosition; |
2124 | // UUID is the UUID of the Avatar doing the clicking | 2087 | Quaternion avSitOrientation = part.SitTargetOrientation; |
2125 | 2088 | UUID avOnTargetAlready = part.SitTargetAvatar; | |
2126 | m_avInitialPos = AbsolutePosition; // saved to calculate unscripted sit rotation | 2089 | |
2127 | 2090 | bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero)); | |
2128 | // Is a sit target available? | 2091 | bool SitTargetisSet = |
2129 | Vector3 avSitOffSet = part.SitTargetPosition; | 2092 | (!(avSitOffSet == Vector3.Zero && |
2130 | Quaternion avSitOrientation = part.SitTargetOrientation; | 2093 | ( |
2131 | 2094 | avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion | |
2132 | bool SitTargetisSet = (Vector3.Zero != avSitOffSet); //NB Latest SL Spec shows Sit Rotation setting is ignored. | 2095 | || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point |
2133 | // Quaternion partIRot = Quaternion.Inverse(part.GetWorldRotation()); | 2096 | || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion |
2134 | Quaternion partRot; | 2097 | ) |
2135 | // if (part.LinkNum == 1) | 2098 | )); |
2136 | // { // Root prim of linkset | 2099 | |
2137 | // partRot = part.ParentGroup.RootPart.RotationOffset; | 2100 | // m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied); |
2138 | // } | 2101 | |
2139 | // else | 2102 | if (SitTargetisSet && SitTargetUnOccupied) |
2140 | // { // single or child prim | 2103 | { |
2141 | partRot = part.GetWorldRotation(); | 2104 | part.SitTargetAvatar = UUID; |
2142 | // } | 2105 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); |
2143 | Quaternion partIRot = Quaternion.Inverse(partRot); | 2106 | sitOrientation = avSitOrientation; |
2144 | //Console.WriteLine("SendSitResponse offset=" + offset + " Occup=" + part.IsOccupied + " TargSet=" + SitTargetisSet); | 2107 | autopilot = false; |
2145 | // Sit analysis rewritten by KF 091125 | 2108 | } |
2146 | if (SitTargetisSet) // scipted sit | 2109 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); |
2147 | { | 2110 | |
2148 | if (!part.IsOccupied) | 2111 | pos = part.AbsolutePosition + offset; |
2149 | { | 2112 | //if (Math.Abs(part.AbsolutePosition.Z - AbsolutePosition.Z) > 1) |
2150 | //Console.WriteLine("Scripted, unoccupied"); | 2113 | //{ |
2151 | part.SitTargetAvatar = UUID; // set that Av will be on it | 2114 | // offset = pos; |
2152 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); // change ofset to the scripted one | 2115 | //autopilot = false; |
2116 | //} | ||
2117 | if (PhysicsActor != null) | ||
2118 | { | ||
2119 | // If we're not using the client autopilot, we're immediately warping the avatar to the location | ||
2120 | // We can remove the physicsActor until they stand up. | ||
2121 | m_sitAvatarHeight = PhysicsActor.Size.Z; | ||
2153 | 2122 | ||
2154 | Quaternion nrot = avSitOrientation; | 2123 | if (autopilot) |
2155 | if (!part.IsRoot) | ||
2156 | { | 2124 | { |
2157 | nrot = part.RotationOffset * avSitOrientation; | 2125 | if (Util.GetDistanceTo(AbsolutePosition, pos) < 4.5) |
2126 | { | ||
2127 | autopilot = false; | ||
2128 | |||
2129 | RemoveFromPhysicalScene(); | ||
2130 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); | ||
2131 | } | ||
2158 | } | 2132 | } |
2159 | sitOrientation = nrot; // Change rotatione to the scripted one | 2133 | else |
2160 | OffsetRotation = nrot; | ||
2161 | autopilot = false; // Jump direct to scripted llSitPos() | ||
2162 | } | ||
2163 | else | ||
2164 | { | ||
2165 | //Console.WriteLine("Scripted, occupied"); | ||
2166 | return; | ||
2167 | } | ||
2168 | } | ||
2169 | else // Not Scripted | ||
2170 | { | ||
2171 | if ( (Math.Abs(offset.X) > 0.1f) || (Math.Abs(offset.Y) > 0.1f) ) // Changed 0.5M to 0.1M as they want to be able to sit close together | ||
2172 | { | ||
2173 | // large prim & offset, ignore if other Avs sitting | ||
2174 | // offset.Z -= 0.05f; | ||
2175 | m_avUnscriptedSitPos = offset * partIRot; // (non-zero) sit where clicked | ||
2176 | autopilotTarget = part.AbsolutePosition + offset; // World location of clicked point | ||
2177 | |||
2178 | //Console.WriteLine(" offset ={0}", offset); | ||
2179 | //Console.WriteLine(" UnscriptedSitPos={0}", m_avUnscriptedSitPos); | ||
2180 | //Console.WriteLine(" autopilotTarget={0}", autopilotTarget); | ||
2181 | |||
2182 | } | ||
2183 | else // small offset | ||
2184 | { | ||
2185 | //Console.WriteLine("Small offset"); | ||
2186 | if (!part.IsOccupied) | ||
2187 | { | ||
2188 | m_avUnscriptedSitPos = Vector3.Zero; // Zero = Sit on prim center | ||
2189 | autopilotTarget = part.AbsolutePosition; | ||
2190 | //Console.WriteLine("UsSmall autopilotTarget={0}", autopilotTarget); | ||
2191 | } | ||
2192 | else return; // occupied small | ||
2193 | } // end large/small | ||
2194 | } // end Scripted/not | ||
2195 | |||
2196 | part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); | ||
2197 | |||
2198 | cameraAtOffset = part.GetCameraAtOffset(); | ||
2199 | cameraEyeOffset = part.GetCameraEyeOffset(); | ||
2200 | forceMouselook = part.GetForceMouselook(); | ||
2201 | if(cameraAtOffset == Vector3.Zero) cameraAtOffset = new Vector3(0f, 0f, 0.1f); // | ||
2202 | if(cameraEyeOffset == Vector3.Zero) cameraEyeOffset = new Vector3(0f, 0f, 0.1f); // | ||
2203 | |||
2204 | if (m_physicsActor != null) | ||
2205 | { | ||
2206 | // If we're not using the client autopilot, we're immediately warping the avatar to the location | ||
2207 | // We can remove the physicsActor until they stand up. | ||
2208 | m_sitAvatarHeight = m_physicsActor.Size.Z; | ||
2209 | if (autopilot) | ||
2210 | { // its not a scripted sit | ||
2211 | // if (Util.GetDistanceTo(AbsolutePosition, autopilotTarget) < 4.5) | ||
2212 | if( (Math.Abs(AbsolutePosition.X - autopilotTarget.X) < 256.0f) && (Math.Abs(AbsolutePosition.Y - autopilotTarget.Y) < 256.0f) ) | ||
2213 | { | 2134 | { |
2214 | autopilot = false; // close enough | ||
2215 | m_lastWorldPosition = m_pos; /* CW - This give us a position to return the avatar to if the part is killed before standup. | ||
2216 | Not using the part's position because returning the AV to the last known standing | ||
2217 | position is likely to be more friendly, isn't it? */ | ||
2218 | RemoveFromPhysicalScene(); | 2135 | RemoveFromPhysicalScene(); |
2219 | Velocity = Vector3.Zero; | 2136 | } |
2220 | AbsolutePosition = autopilotTarget + new Vector3(0.0f, 0.0f, (m_sitAvatarHeight / 2.0f)); // Warp av to over sit target | ||
2221 | } // else the autopilot will get us close | ||
2222 | } | ||
2223 | else | ||
2224 | { // its a scripted sit | ||
2225 | m_lastWorldPosition = part.AbsolutePosition; /* CW - This give us a position to return the avatar to if the part is killed before standup. | ||
2226 | I *am* using the part's position this time because we have no real idea how far away | ||
2227 | the avatar is from the sit target. */ | ||
2228 | RemoveFromPhysicalScene(); | ||
2229 | Velocity = Vector3.Zero; | ||
2230 | } | 2137 | } |
2138 | |||
2139 | cameraAtOffset = part.GetCameraAtOffset(); | ||
2140 | cameraEyeOffset = part.GetCameraEyeOffset(); | ||
2141 | forceMouselook = part.GetForceMouselook(); | ||
2231 | } | 2142 | } |
2232 | else return; // physactor is null! | ||
2233 | 2143 | ||
2234 | Vector3 offsetr; // = offset * partIRot; | 2144 | ControllingClient.SendSitResponse(targetID, offset, sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); |
2235 | // KF: In a linkset, offsetr needs to be relative to the group root! 091208 | 2145 | m_requestedSitTargetUUID = targetID; |
2236 | // offsetr = (part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + (offset * partIRot); | 2146 | |
2237 | // if (part.LinkNum < 2) 091216 All this was necessary because of the GetWorldRotation error. | ||
2238 | // { // Single, or Root prim of linkset, target is ClickOffset * RootRot | ||
2239 | //offsetr = offset * partIRot; | ||
2240 | // | ||
2241 | // } | ||
2242 | // else | ||
2243 | // { // Child prim, offset is (ChildOffset * RootRot) + (ClickOffset * ChildRot) | ||
2244 | // offsetr = //(part.OffsetPosition * Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset)) + | ||
2245 | // (offset * partRot); | ||
2246 | // } | ||
2247 | |||
2248 | //Console.WriteLine(" "); | ||
2249 | //Console.WriteLine("link number ={0}", part.LinkNum); | ||
2250 | //Console.WriteLine("Prim offset ={0}", part.OffsetPosition ); | ||
2251 | //Console.WriteLine("Root Rotate ={0}", part.ParentGroup.RootPart.RotationOffset); | ||
2252 | //Console.WriteLine("Click offst ={0}", offset); | ||
2253 | //Console.WriteLine("Prim Rotate ={0}", part.GetWorldRotation()); | ||
2254 | //Console.WriteLine("offsetr ={0}", offsetr); | ||
2255 | //Console.WriteLine("Camera At ={0}", cameraAtOffset); | ||
2256 | //Console.WriteLine("Camera Eye ={0}", cameraEyeOffset); | ||
2257 | |||
2258 | //NOTE: SendSitResponse should be relative to the GROUP *NOT* THE PRIM if we're sitting on a child | ||
2259 | ControllingClient.SendSitResponse(part.ParentGroup.UUID, ((offset * part.RotationOffset) + part.OffsetPosition), sitOrientation, autopilot, cameraAtOffset, cameraEyeOffset, forceMouselook); | ||
2260 | |||
2261 | m_requestedSitTargetUUID = part.UUID; //KF: Correct autopilot target | ||
2262 | // This calls HandleAgentSit twice, once from here, and the client calls | 2147 | // This calls HandleAgentSit twice, once from here, and the client calls |
2263 | // HandleAgentSit itself after it gets to the location | 2148 | // HandleAgentSit itself after it gets to the location |
2264 | // It doesn't get to the location until we've moved them there though | 2149 | // It doesn't get to the location until we've moved them there though |
2265 | // which happens in HandleAgentSit :P | 2150 | // which happens in HandleAgentSit :P |
2266 | m_autopilotMoving = autopilot; | 2151 | m_autopilotMoving = autopilot; |
2267 | m_autoPilotTarget = autopilotTarget; | 2152 | m_autoPilotTarget = pos; |
2268 | m_sitAtAutoTarget = autopilot; | 2153 | m_sitAtAutoTarget = autopilot; |
2269 | m_initialSitTarget = autopilotTarget; | ||
2270 | if (!autopilot) | 2154 | if (!autopilot) |
2271 | HandleAgentSit(remoteClient, UUID); | 2155 | HandleAgentSit(remoteClient, UUID); |
2272 | } | 2156 | } |
@@ -2300,9 +2184,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2300 | m_requestedSitTargetID = part.LocalId; | 2184 | m_requestedSitTargetID = part.LocalId; |
2301 | //m_requestedSitOffset = offset; | 2185 | //m_requestedSitOffset = offset; |
2302 | m_requestedSitTargetUUID = targetID; | 2186 | m_requestedSitTargetUUID = targetID; |
2303 | 2187 | ||
2304 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); | 2188 | m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset); |
2305 | 2189 | ||
2306 | if (m_scene.PhysicsScene.SupportsRayCast()) | 2190 | if (m_scene.PhysicsScene.SupportsRayCast()) |
2307 | { | 2191 | { |
2308 | //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); | 2192 | //m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback()); |
@@ -2521,7 +2405,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2521 | HandleAgentSit(remoteClient, agentID, "SIT"); | 2405 | HandleAgentSit(remoteClient, agentID, "SIT"); |
2522 | } | 2406 | } |
2523 | } | 2407 | } |
2524 | 2408 | ||
2525 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) | 2409 | public void HandleAgentSit(IClientAPI remoteClient, UUID agentID, string sitAnimation) |
2526 | { | 2410 | { |
2527 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); | 2411 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_requestedSitTargetID); |
@@ -2532,68 +2416,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
2532 | { | 2416 | { |
2533 | if (part.SitTargetAvatar == UUID) | 2417 | if (part.SitTargetAvatar == UUID) |
2534 | { | 2418 | { |
2535 | //Console.WriteLine("Scripted Sit"); | ||
2536 | // Scripted sit | ||
2537 | Vector3 sitTargetPos = part.SitTargetPosition; | 2419 | Vector3 sitTargetPos = part.SitTargetPosition; |
2538 | Quaternion sitTargetOrient = part.SitTargetOrientation; | 2420 | Quaternion sitTargetOrient = part.SitTargetOrientation; |
2539 | m_pos = new Vector3(sitTargetPos.X, sitTargetPos.Y, sitTargetPos.Z); | 2421 | |
2540 | m_pos += SIT_TARGET_ADJUSTMENT; | 2422 | // m_log.DebugFormat( |
2541 | if (!part.IsRoot) | 2423 | // "[SCENE PRESENCE]: Sitting {0} at sit target {1}, {2} on {3} {4}", |
2542 | { | 2424 | // Name, sitTargetPos, sitTargetOrient, part.Name, part.LocalId); |
2543 | m_pos *= part.RotationOffset; | 2425 | |
2544 | } | 2426 | //Quaternion vq = new Quaternion(sitTargetPos.X, sitTargetPos.Y+0.2f, sitTargetPos.Z+0.2f, 0); |
2545 | m_bodyRot = sitTargetOrient; | 2427 | //Quaternion nq = new Quaternion(-sitTargetOrient.X, -sitTargetOrient.Y, -sitTargetOrient.Z, sitTargetOrient.w); |
2546 | m_parentPosition = part.AbsolutePosition; | 2428 | |
2547 | part.IsOccupied = true; | 2429 | //Quaternion result = (sitTargetOrient * vq) * nq; |
2548 | part.ParentGroup.AddAvatar(agentID); | 2430 | |
2431 | m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; | ||
2432 | Rotation = sitTargetOrient; | ||
2433 | ParentPosition = part.AbsolutePosition; | ||
2549 | } | 2434 | } |
2550 | else | 2435 | else |
2551 | { | 2436 | { |
2552 | // if m_avUnscriptedSitPos is zero then Av sits above center | 2437 | m_pos -= part.AbsolutePosition; |
2553 | // Else Av sits at m_avUnscriptedSitPos | 2438 | ParentPosition = part.AbsolutePosition; |
2554 | 2439 | ||
2555 | // Non-scripted sit by Kitto Flora 21Nov09 | 2440 | // m_log.DebugFormat( |
2556 | // Calculate angle of line from prim to Av | 2441 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", |
2557 | Quaternion partIRot; | 2442 | // Name, part.AbsolutePosition, m_pos, ParentPosition, part.Name, part.LocalId); |
2558 | // if (part.LinkNum == 1) | 2443 | } |
2559 | // { // Root prim of linkset | ||
2560 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); | ||
2561 | // } | ||
2562 | // else | ||
2563 | // { // single or child prim | ||
2564 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); | ||
2565 | // } | ||
2566 | Vector3 sitTargetPos= part.AbsolutePosition + m_avUnscriptedSitPos; | ||
2567 | float y_diff = (m_avInitialPos.Y - sitTargetPos.Y); | ||
2568 | float x_diff = ( m_avInitialPos.X - sitTargetPos.X); | ||
2569 | if(Math.Abs(x_diff) < 0.001f) x_diff = 0.001f; // avoid div by 0 | ||
2570 | if(Math.Abs(y_diff) < 0.001f) y_diff = 0.001f; // avoid pol flip at 0 | ||
2571 | float sit_angle = (float)Math.Atan2( (double)y_diff, (double)x_diff); | ||
2572 | // NOTE: when sitting m_ pos and m_bodyRot are *relative* to the prim location/rotation, not 'World'. | ||
2573 | // Av sits at world euler <0,0, z>, translated by part rotation | ||
2574 | m_bodyRot = partIRot * Quaternion.CreateFromEulers(0f, 0f, sit_angle); // sit at 0,0,inv-click | ||
2575 | |||
2576 | m_parentPosition = part.AbsolutePosition; | ||
2577 | part.IsOccupied = true; | ||
2578 | part.ParentGroup.AddAvatar(agentID); | ||
2579 | m_pos = new Vector3(0f, 0f, 0.05f) + // corrections to get Sit Animation | ||
2580 | (new Vector3(0.0f, 0f, 0.61f) * partIRot) + // located on center | ||
2581 | (new Vector3(0.34f, 0f, 0.0f) * m_bodyRot) + | ||
2582 | m_avUnscriptedSitPos; // adds click offset, if any | ||
2583 | //Set up raytrace to find top surface of prim | ||
2584 | Vector3 size = part.Scale; | ||
2585 | float mag = 2.0f; // 0.1f + (float)Math.Sqrt((size.X * size.X) + (size.Y * size.Y) + (size.Z * size.Z)); | ||
2586 | Vector3 start = part.AbsolutePosition + new Vector3(0f, 0f, mag); | ||
2587 | Vector3 down = new Vector3(0f, 0f, -1f); | ||
2588 | //Console.WriteLine("st={0} do={1} ma={2}", start, down, mag); | ||
2589 | m_scene.PhysicsScene.RaycastWorld( | ||
2590 | start, // Vector3 position, | ||
2591 | down, // Vector3 direction, | ||
2592 | mag, // float length, | ||
2593 | SitAltitudeCallback); // retMethod | ||
2594 | } // end scripted/not | ||
2595 | } | 2444 | } |
2596 | else // no Av | 2445 | else |
2597 | { | 2446 | { |
2598 | return; | 2447 | return; |
2599 | } | 2448 | } |
@@ -2601,58 +2450,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
2601 | 2450 | ||
2602 | ParentID = m_requestedSitTargetID; | 2451 | ParentID = m_requestedSitTargetID; |
2603 | 2452 | ||
2604 | //We want our offsets to reference the root prim, not the child we may have sat on | ||
2605 | if (!part.IsRoot) | ||
2606 | { | ||
2607 | m_parentID = part.ParentGroup.RootPart.LocalId; | ||
2608 | m_pos += part.OffsetPosition; | ||
2609 | } | ||
2610 | else | ||
2611 | { | ||
2612 | m_parentID = m_requestedSitTargetID; | ||
2613 | } | ||
2614 | |||
2615 | if (part.SitTargetAvatar != UUID) | ||
2616 | { | ||
2617 | m_offsetRotation = m_offsetRotation / part.RotationOffset; | ||
2618 | } | ||
2619 | Velocity = Vector3.Zero; | 2453 | Velocity = Vector3.Zero; |
2620 | RemoveFromPhysicalScene(); | 2454 | RemoveFromPhysicalScene(); |
2455 | |||
2621 | Animator.TrySetMovementAnimation(sitAnimation); | 2456 | Animator.TrySetMovementAnimation(sitAnimation); |
2622 | SendAvatarDataToAllAgents(); | 2457 | SendAvatarDataToAllAgents(); |
2623 | } | 2458 | } |
2624 | |||
2625 | public void SitAltitudeCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal) | ||
2626 | { | ||
2627 | // KF: 091202 There appears to be a bug in Prim Edit Size - the process sometimes make a prim that RayTrace no longer | ||
2628 | // sees. Take/re-rez, or sim restart corrects the condition. Result of bug is incorrect sit height. | ||
2629 | if(hitYN) | ||
2630 | { | ||
2631 | // m_pos = Av offset from prim center to make look like on center | ||
2632 | // m_parentPosition = Actual center pos of prim | ||
2633 | // collisionPoint = spot on prim where we want to sit | ||
2634 | // collisionPoint.Z = global sit surface height | ||
2635 | SceneObjectPart part = m_scene.GetSceneObjectPart(localid); | ||
2636 | Quaternion partIRot; | ||
2637 | // if (part.LinkNum == 1) | ||
2638 | /// { // Root prim of linkset | ||
2639 | // partIRot = Quaternion.Inverse(part.ParentGroup.RootPart.RotationOffset); | ||
2640 | // } | ||
2641 | // else | ||
2642 | // { // single or child prim | ||
2643 | partIRot = Quaternion.Inverse(part.GetWorldRotation()); | ||
2644 | // } | ||
2645 | if (m_initialSitTarget != null) | ||
2646 | { | ||
2647 | float offZ = collisionPoint.Z - m_initialSitTarget.Z; | ||
2648 | Vector3 offset = new Vector3(0.0f, 0.0f, offZ) * partIRot; // Altitude correction | ||
2649 | //Console.WriteLine("sitPoint={0}, offset={1}", sitPoint, offset); | ||
2650 | m_pos += offset; | ||
2651 | // ControllingClient.SendClearFollowCamProperties(part.UUID); | ||
2652 | } | ||
2653 | |||
2654 | } | ||
2655 | } // End SitAltitudeCallback KF. | ||
2656 | 2459 | ||
2657 | /// <summary> | 2460 | /// <summary> |
2658 | /// Event handler for the 'Always run' setting on the client | 2461 | /// Event handler for the 'Always run' setting on the client |