diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.cs | 263 |
1 files changed, 206 insertions, 57 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 7c3875d..aeca7df 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -36,6 +36,7 @@ using System.Timers; | |||
36 | using System.Xml; | 36 | using System.Xml; |
37 | using Nini.Config; | 37 | using Nini.Config; |
38 | using OpenMetaverse; | 38 | using OpenMetaverse; |
39 | using OpenMetaverse.Packets; | ||
39 | using OpenMetaverse.Imaging; | 40 | using OpenMetaverse.Imaging; |
40 | using OpenSim.Framework; | 41 | using OpenSim.Framework; |
41 | using OpenSim.Services.Interfaces; | 42 | using OpenSim.Services.Interfaces; |
@@ -87,8 +88,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
87 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); | 88 | protected List<RegionInfo> m_regionRestartNotifyList = new List<RegionInfo>(); |
88 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); | 89 | protected List<RegionInfo> m_neighbours = new List<RegionInfo>(); |
89 | 90 | ||
90 | public volatile bool BordersLocked = false; | 91 | private volatile int m_bordersLocked = 0; |
91 | 92 | public bool BordersLocked | |
93 | { | ||
94 | get { return m_bordersLocked == 1; } | ||
95 | set | ||
96 | { | ||
97 | if (value == true) | ||
98 | m_bordersLocked = 1; | ||
99 | else | ||
100 | m_bordersLocked = 0; | ||
101 | } | ||
102 | } | ||
92 | public List<Border> NorthBorders = new List<Border>(); | 103 | public List<Border> NorthBorders = new List<Border>(); |
93 | public List<Border> EastBorders = new List<Border>(); | 104 | public List<Border> EastBorders = new List<Border>(); |
94 | public List<Border> SouthBorders = new List<Border>(); | 105 | public List<Border> SouthBorders = new List<Border>(); |
@@ -135,6 +146,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
135 | protected SceneCommunicationService m_sceneGridService; | 146 | protected SceneCommunicationService m_sceneGridService; |
136 | public bool loginsdisabled = true; | 147 | public bool loginsdisabled = true; |
137 | 148 | ||
149 | public new float TimeDilation | ||
150 | { | ||
151 | get { return m_sceneGraph.PhysicsScene.TimeDilation; } | ||
152 | } | ||
153 | |||
138 | public SceneCommunicationService SceneGridService | 154 | public SceneCommunicationService SceneGridService |
139 | { | 155 | { |
140 | get { return m_sceneGridService; } | 156 | get { return m_sceneGridService; } |
@@ -252,7 +268,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
252 | // Central Update Loop | 268 | // Central Update Loop |
253 | 269 | ||
254 | protected int m_fps = 10; | 270 | protected int m_fps = 10; |
255 | protected int m_frame; | 271 | protected uint m_frame; |
256 | protected float m_timespan = 0.089f; | 272 | protected float m_timespan = 0.089f; |
257 | protected DateTime m_lastupdate = DateTime.UtcNow; | 273 | protected DateTime m_lastupdate = DateTime.UtcNow; |
258 | 274 | ||
@@ -269,6 +285,23 @@ namespace OpenSim.Region.Framework.Scenes | |||
269 | private int physicsMS2; | 285 | private int physicsMS2; |
270 | private int physicsMS; | 286 | private int physicsMS; |
271 | private int otherMS; | 287 | private int otherMS; |
288 | private int tempOnRezMS; | ||
289 | private int eventMS; | ||
290 | private int backupMS; | ||
291 | private int terrainMS; | ||
292 | private int landMS; | ||
293 | private int lastCompletedFrame; | ||
294 | |||
295 | public int MonitorFrameTime { get { return frameMS; } } | ||
296 | public int MonitorPhysicsUpdateTime { get { return physicsMS; } } | ||
297 | public int MonitorPhysicsSyncTime { get { return physicsMS2; } } | ||
298 | public int MonitorOtherTime { get { return otherMS; } } | ||
299 | public int MonitorTempOnRezTime { get { return tempOnRezMS; } } | ||
300 | public int MonitorEventTime { get { return eventMS; } } // This may need to be divided into each event? | ||
301 | public int MonitorBackupTime { get { return backupMS; } } | ||
302 | public int MonitorTerrainTime { get { return terrainMS; } } | ||
303 | public int MonitorLandTime { get { return landMS; } } | ||
304 | public int MonitorLastFrameTick { get { return lastCompletedFrame; } } | ||
272 | 305 | ||
273 | private bool m_physics_enabled = true; | 306 | private bool m_physics_enabled = true; |
274 | private bool m_scripts_enabled = true; | 307 | private bool m_scripts_enabled = true; |
@@ -375,6 +408,73 @@ namespace OpenSim.Region.Framework.Scenes | |||
375 | 408 | ||
376 | #endregion | 409 | #endregion |
377 | 410 | ||
411 | #region BinaryStats | ||
412 | |||
413 | public class StatLogger | ||
414 | { | ||
415 | public DateTime StartTime; | ||
416 | public string Path; | ||
417 | public System.IO.BinaryWriter Log; | ||
418 | } | ||
419 | static StatLogger m_statLog = null; | ||
420 | static TimeSpan m_statLogPeriod = TimeSpan.FromSeconds(300); | ||
421 | static string m_statsDir = String.Empty; | ||
422 | static Object m_statLockObject = new Object(); | ||
423 | private void LogSimStats(SimStats stats) | ||
424 | { | ||
425 | SimStatsPacket pack = new SimStatsPacket(); | ||
426 | pack.Region = new SimStatsPacket.RegionBlock(); | ||
427 | pack.Region.RegionX = stats.RegionX; | ||
428 | pack.Region.RegionY = stats.RegionY; | ||
429 | pack.Region.RegionFlags = stats.RegionFlags; | ||
430 | pack.Region.ObjectCapacity = stats.ObjectCapacity; | ||
431 | //pack.Region = //stats.RegionBlock; | ||
432 | pack.Stat = stats.StatsBlock; | ||
433 | pack.Header.Reliable = false; | ||
434 | |||
435 | // note that we are inside the reporter lock when called | ||
436 | DateTime now = DateTime.Now; | ||
437 | |||
438 | // hide some time information into the packet | ||
439 | pack.Header.Sequence = (uint)now.Ticks; | ||
440 | |||
441 | lock (m_statLockObject) // m_statLog is shared so make sure there is only executer here | ||
442 | { | ||
443 | try | ||
444 | { | ||
445 | if (m_statLog == null || now > m_statLog.StartTime + m_statLogPeriod) | ||
446 | { | ||
447 | // First log file or time has expired, start writing to a new log file | ||
448 | if (m_statLog != null && m_statLog.Log != null) | ||
449 | { | ||
450 | m_statLog.Log.Close(); | ||
451 | } | ||
452 | m_statLog = new StatLogger(); | ||
453 | m_statLog.StartTime = now; | ||
454 | m_statLog.Path = (m_statsDir.Length > 0 ? m_statsDir + System.IO.Path.DirectorySeparatorChar.ToString() : "") | ||
455 | + String.Format("stats-{0}.log", now.ToString("yyyyMMddHHmmss")); | ||
456 | m_statLog.Log = new BinaryWriter(File.Open(m_statLog.Path, FileMode.Append, FileAccess.Write)); | ||
457 | } | ||
458 | |||
459 | // Write the serialized data to disk | ||
460 | if (m_statLog != null && m_statLog.Log != null) | ||
461 | m_statLog.Log.Write(pack.ToBytes()); | ||
462 | } | ||
463 | catch (Exception ex) | ||
464 | { | ||
465 | m_log.Error("statistics gathering failed: " + ex.Message, ex); | ||
466 | if (m_statLog != null && m_statLog.Log != null) | ||
467 | { | ||
468 | m_statLog.Log.Close(); | ||
469 | } | ||
470 | m_statLog = null; | ||
471 | } | ||
472 | } | ||
473 | return; | ||
474 | } | ||
475 | |||
476 | #endregion | ||
477 | |||
378 | #region Constructors | 478 | #region Constructors |
379 | 479 | ||
380 | public Scene(RegionInfo regInfo, AgentCircuitManager authen, | 480 | public Scene(RegionInfo regInfo, AgentCircuitManager authen, |
@@ -560,6 +660,38 @@ namespace OpenSim.Region.Framework.Scenes | |||
560 | } | 660 | } |
561 | 661 | ||
562 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); | 662 | m_log.Info("[SCENE]: Using the " + m_update_prioritization_scheme + " prioritization scheme"); |
663 | |||
664 | #region BinaryStats | ||
665 | |||
666 | try | ||
667 | { | ||
668 | IConfig statConfig = m_config.Configs["Statistics.Binary"]; | ||
669 | if (statConfig.Contains("enabled") && statConfig.GetBoolean("enabled")) | ||
670 | { | ||
671 | if (statConfig.Contains("collect_region_stats")) | ||
672 | { | ||
673 | if (statConfig.GetBoolean("collect_region_stats")) | ||
674 | { | ||
675 | // if enabled, add us to the event. If not enabled, I won't get called | ||
676 | StatsReporter.OnSendStatsResult += LogSimStats; | ||
677 | } | ||
678 | } | ||
679 | if (statConfig.Contains("region_stats_period_seconds")) | ||
680 | { | ||
681 | m_statLogPeriod = TimeSpan.FromSeconds(statConfig.GetInt("region_stats_period_seconds")); | ||
682 | } | ||
683 | if (statConfig.Contains("stats_dir")) | ||
684 | { | ||
685 | m_statsDir = statConfig.GetString("stats_dir"); | ||
686 | } | ||
687 | } | ||
688 | } | ||
689 | catch | ||
690 | { | ||
691 | // if it doesn't work, we don't collect anything | ||
692 | } | ||
693 | |||
694 | #endregion BinaryStats | ||
563 | } | 695 | } |
564 | catch | 696 | catch |
565 | { | 697 | { |
@@ -1013,36 +1145,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
1013 | /// </summary> | 1145 | /// </summary> |
1014 | public override void Update() | 1146 | public override void Update() |
1015 | { | 1147 | { |
1016 | int maintc = 0; | 1148 | float physicsFPS; |
1149 | int maintc; | ||
1150 | |||
1017 | while (!shuttingdown) | 1151 | while (!shuttingdown) |
1018 | { | 1152 | { |
1019 | //#if DEBUG | ||
1020 | // int w = 0, io = 0; | ||
1021 | // ThreadPool.GetAvailableThreads(out w, out io); | ||
1022 | // if ((w < 10) || (io < 10)) | ||
1023 | // m_log.DebugFormat("[WARNING]: ThreadPool reaching exhaustion. workers = {0}; io = {1}", w, io); | ||
1024 | //#endif | ||
1025 | maintc = Environment.TickCount; | ||
1026 | |||
1027 | TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; | 1153 | TimeSpan SinceLastFrame = DateTime.UtcNow - m_lastupdate; |
1028 | float physicsFPS = 0; | 1154 | physicsFPS = 0f; |
1029 | 1155 | ||
1030 | frameMS = Environment.TickCount; | 1156 | maintc = otherMS = Environment.TickCount; |
1157 | int tmpFrameMS = maintc; | ||
1158 | |||
1159 | // Increment the frame counter | ||
1160 | ++m_frame; | ||
1031 | 1161 | ||
1032 | try | 1162 | try |
1033 | { | 1163 | { |
1034 | // Increment the frame counter | ||
1035 | m_frame++; | ||
1036 | |||
1037 | // Loop it | ||
1038 | if (m_frame == Int32.MaxValue) | ||
1039 | m_frame = 0; | ||
1040 | |||
1041 | otherMS = Environment.TickCount; | ||
1042 | |||
1043 | // Check if any objects have reached their targets | 1164 | // Check if any objects have reached their targets |
1044 | CheckAtTargets(); | 1165 | CheckAtTargets(); |
1045 | 1166 | ||
1046 | // Update SceneObjectGroups that have scheduled themselves for updates | 1167 | // Update SceneObjectGroups that have scheduled themselves for updates |
1047 | // Objects queue their updates onto all scene presences | 1168 | // Objects queue their updates onto all scene presences |
1048 | if (m_frame % m_update_objects == 0) | 1169 | if (m_frame % m_update_objects == 0) |
@@ -1053,62 +1174,92 @@ namespace OpenSim.Region.Framework.Scenes | |||
1053 | if (m_frame % m_update_presences == 0) | 1174 | if (m_frame % m_update_presences == 0) |
1054 | m_sceneGraph.UpdatePresences(); | 1175 | m_sceneGraph.UpdatePresences(); |
1055 | 1176 | ||
1056 | physicsMS2 = Environment.TickCount; | 1177 | int TempPhysicsMS2 = Environment.TickCount; |
1057 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) | 1178 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) |
1058 | m_sceneGraph.UpdatePreparePhysics(); | 1179 | m_sceneGraph.UpdatePreparePhysics(); |
1059 | physicsMS2 = Environment.TickCount - physicsMS2; | 1180 | TempPhysicsMS2 = Environment.TickCount - TempPhysicsMS2; |
1181 | physicsMS2 = TempPhysicsMS2; | ||
1060 | 1182 | ||
1061 | if (m_frame % m_update_entitymovement == 0) | 1183 | if (m_frame % m_update_entitymovement == 0) |
1062 | m_sceneGraph.UpdateScenePresenceMovement(); | 1184 | m_sceneGraph.UpdateScenePresenceMovement(); |
1063 | 1185 | ||
1064 | physicsMS = Environment.TickCount; | 1186 | int TempPhysicsMS = Environment.TickCount; |
1065 | if ((m_frame % m_update_physics == 0) && m_physics_enabled) | 1187 | if (m_frame % m_update_physics == 0) |
1066 | physicsFPS = m_sceneGraph.UpdatePhysics( | 1188 | { |
1067 | Math.Max(SinceLastFrame.TotalSeconds, m_timespan) | 1189 | if (m_physics_enabled) |
1068 | ); | 1190 | physicsFPS = m_sceneGraph.UpdatePhysics(Math.Max(SinceLastFrame.TotalSeconds, m_timespan)); |
1069 | if (m_frame % m_update_physics == 0 && SynchronizeScene != null) | 1191 | if (SynchronizeScene != null) |
1070 | SynchronizeScene(this); | 1192 | SynchronizeScene(this); |
1071 | 1193 | } | |
1072 | physicsMS = Environment.TickCount - physicsMS; | 1194 | TempPhysicsMS = Environment.TickCount - TempPhysicsMS; |
1073 | physicsMS += physicsMS2; | 1195 | physicsMS = TempPhysicsMS; |
1074 | 1196 | ||
1075 | // Delete temp-on-rez stuff | 1197 | // Delete temp-on-rez stuff |
1076 | if (m_frame % m_update_backup == 0) | 1198 | if (m_frame % m_update_backup == 0) |
1199 | { | ||
1200 | int tozMS = Environment.TickCount; | ||
1077 | CleanTempObjects(); | 1201 | CleanTempObjects(); |
1202 | tozMS -= Environment.TickCount; | ||
1203 | tempOnRezMS = tozMS; | ||
1204 | } | ||
1078 | 1205 | ||
1079 | if (RegionStatus != RegionStatus.SlaveScene) | 1206 | if (RegionStatus != RegionStatus.SlaveScene) |
1080 | { | 1207 | { |
1081 | if (m_frame % m_update_events == 0) | 1208 | if (m_frame % m_update_events == 0) |
1209 | { | ||
1210 | int evMS = Environment.TickCount; | ||
1082 | UpdateEvents(); | 1211 | UpdateEvents(); |
1212 | evMS -= Environment.TickCount; | ||
1213 | eventMS = evMS; | ||
1214 | } | ||
1083 | 1215 | ||
1084 | if (m_frame % m_update_backup == 0) | 1216 | if (m_frame % m_update_backup == 0) |
1217 | { | ||
1218 | int backMS = Environment.TickCount; | ||
1085 | UpdateStorageBackup(); | 1219 | UpdateStorageBackup(); |
1220 | backMS -= Environment.TickCount; | ||
1221 | backupMS = backMS; | ||
1222 | } | ||
1086 | 1223 | ||
1087 | if (m_frame % m_update_terrain == 0) | 1224 | if (m_frame % m_update_terrain == 0) |
1225 | { | ||
1226 | int terMS = Environment.TickCount; | ||
1088 | UpdateTerrain(); | 1227 | UpdateTerrain(); |
1228 | terMS -= Environment.TickCount; | ||
1229 | terrainMS = terMS; | ||
1230 | } | ||
1089 | 1231 | ||
1090 | if (m_frame % m_update_land == 0) | 1232 | if (m_frame % m_update_land == 0) |
1233 | { | ||
1234 | int ldMS = Environment.TickCount; | ||
1091 | UpdateLand(); | 1235 | UpdateLand(); |
1236 | ldMS -= Environment.TickCount; | ||
1237 | landMS = ldMS; | ||
1238 | } | ||
1239 | |||
1240 | int tickCount = Environment.TickCount; | ||
1241 | otherMS = tickCount - otherMS; | ||
1242 | tmpFrameMS -= tickCount; | ||
1243 | frameMS = tmpFrameMS; | ||
1244 | lastCompletedFrame = tickCount; | ||
1092 | 1245 | ||
1093 | otherMS = Environment.TickCount - otherMS; | ||
1094 | // if (m_frame%m_update_avatars == 0) | 1246 | // if (m_frame%m_update_avatars == 0) |
1095 | // UpdateInWorldTime(); | 1247 | // UpdateInWorldTime(); |
1096 | StatsReporter.AddPhysicsFPS(physicsFPS); | 1248 | StatsReporter.AddPhysicsFPS(physicsFPS); |
1097 | StatsReporter.AddTimeDilation(m_timedilation); | 1249 | StatsReporter.AddTimeDilation(TimeDilation); |
1098 | StatsReporter.AddFPS(1); | 1250 | StatsReporter.AddFPS(1); |
1099 | StatsReporter.AddInPackets(0); | ||
1100 | StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); | 1251 | StatsReporter.SetRootAgents(m_sceneGraph.GetRootAgentCount()); |
1101 | StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); | 1252 | StatsReporter.SetChildAgents(m_sceneGraph.GetChildAgentCount()); |
1102 | StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); | 1253 | StatsReporter.SetObjects(m_sceneGraph.GetTotalObjectsCount()); |
1103 | StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); | 1254 | StatsReporter.SetActiveObjects(m_sceneGraph.GetActiveObjectsCount()); |
1104 | frameMS = Environment.TickCount - frameMS; | ||
1105 | StatsReporter.addFrameMS(frameMS); | 1255 | StatsReporter.addFrameMS(frameMS); |
1106 | StatsReporter.addPhysicsMS(physicsMS); | 1256 | StatsReporter.addPhysicsMS(physicsMS + physicsMS2); |
1107 | StatsReporter.addOtherMS(otherMS); | 1257 | StatsReporter.addOtherMS(otherMS); |
1108 | StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); | 1258 | StatsReporter.SetActiveScripts(m_sceneGraph.GetActiveScriptsCount()); |
1109 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); | 1259 | StatsReporter.addScriptLines(m_sceneGraph.GetScriptLPS()); |
1110 | } | 1260 | } |
1111 | if (loginsdisabled && (m_frame > 20)) | 1261 | |
1262 | if (loginsdisabled && m_frame > 20) | ||
1112 | { | 1263 | { |
1113 | // In 99.9% of cases it is a bad idea to manually force garbage collection. However, | 1264 | // In 99.9% of cases it is a bad idea to manually force garbage collection. However, |
1114 | // this is a rare case where we know we have just went through a long cycle of heap | 1265 | // this is a rare case where we know we have just went through a long cycle of heap |
@@ -1141,18 +1292,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1141 | } | 1292 | } |
1142 | finally | 1293 | finally |
1143 | { | 1294 | { |
1144 | //updateLock.ReleaseMutex(); | ||
1145 | // Get actual time dilation | ||
1146 | float tmpval = (m_timespan / (float)SinceLastFrame.TotalSeconds); | ||
1147 | |||
1148 | // If actual time dilation is greater then one, we're catching up, so subtract | ||
1149 | // the amount that's greater then 1 from the time dilation | ||
1150 | if (tmpval > 1.0) | ||
1151 | { | ||
1152 | tmpval = tmpval - (tmpval - 1.0f); | ||
1153 | } | ||
1154 | m_timedilation = tmpval; | ||
1155 | |||
1156 | m_lastupdate = DateTime.UtcNow; | 1295 | m_lastupdate = DateTime.UtcNow; |
1157 | } | 1296 | } |
1158 | maintc = Environment.TickCount - maintc; | 1297 | maintc = Environment.TickCount - maintc; |
@@ -1183,9 +1322,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1183 | { | 1322 | { |
1184 | lock (m_groupsWithTargets) | 1323 | lock (m_groupsWithTargets) |
1185 | { | 1324 | { |
1186 | foreach (KeyValuePair<UUID, SceneObjectGroup> kvp in m_groupsWithTargets) | 1325 | foreach (SceneObjectGroup entry in m_groupsWithTargets.Values) |
1187 | { | 1326 | { |
1188 | kvp.Value.checkAtTargets(); | 1327 | entry.checkAtTargets(); |
1189 | } | 1328 | } |
1190 | } | 1329 | } |
1191 | } | 1330 | } |
@@ -4244,6 +4383,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
4244 | return m_sceneGraph.GetSceneObjectPart(fullID); | 4383 | return m_sceneGraph.GetSceneObjectPart(fullID); |
4245 | } | 4384 | } |
4246 | 4385 | ||
4386 | /// <summary> | ||
4387 | /// Get a scene object group that contains the prim with the given local id | ||
4388 | /// </summary> | ||
4389 | /// <param name="localID"></param> | ||
4390 | /// <returns>null if no scene object group containing that prim is found</returns> | ||
4391 | public SceneObjectGroup GetGroupByPrim(uint localID) | ||
4392 | { | ||
4393 | return m_sceneGraph.GetGroupByPrim(localID); | ||
4394 | } | ||
4395 | |||
4247 | public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) | 4396 | public bool TryGetAvatar(UUID avatarId, out ScenePresence avatar) |
4248 | { | 4397 | { |
4249 | return m_sceneGraph.TryGetAvatar(avatarId, out avatar); | 4398 | return m_sceneGraph.TryGetAvatar(avatarId, out avatar); |
@@ -4606,7 +4755,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4606 | SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup | 4755 | SceneObjectPart trackedBody = GetSceneObjectPart(joint.TrackedBodyName); // FIXME: causes a sequential lookup |
4607 | if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy. | 4756 | if (trackedBody == null) return; // the actor may have been deleted but the joint still lingers around a few frames waiting for deletion. during this time, trackedBody is NULL to prevent further motion of the joint proxy. |
4608 | jointProxyObject.Velocity = trackedBody.Velocity; | 4757 | jointProxyObject.Velocity = trackedBody.Velocity; |
4609 | jointProxyObject.RotationalVelocity = trackedBody.RotationalVelocity; | 4758 | jointProxyObject.AngularVelocity = trackedBody.AngularVelocity; |
4610 | switch (joint.Type) | 4759 | switch (joint.Type) |
4611 | { | 4760 | { |
4612 | case PhysicsJointType.Ball: | 4761 | case PhysicsJointType.Ball: |