Merge branch 'master' into httptests

httptests
UbitUmarov 2016-10-08 01:27:02 +01:00
commit 9843e3776e
28 changed files with 669 additions and 493 deletions

View File

@ -221,7 +221,8 @@ namespace OpenSim.Data.MySQL
cmd.Parameters.AddWithValue("?id", meta.ID); cmd.Parameters.AddWithValue("?id", meta.ID);
cmd.Parameters.AddWithValue("?name", meta.Name); cmd.Parameters.AddWithValue("?name", meta.Name);
cmd.Parameters.AddWithValue("?description", meta.Description); cmd.Parameters.AddWithValue("?description", meta.Description);
cmd.Parameters.AddWithValue("?type", meta.Type.ToString()); // cmd.Parameters.AddWithValue("?type", meta.Type.ToString());
cmd.Parameters.AddWithValue("?type", meta.Type);
cmd.Parameters.AddWithValue("?hash", hash); cmd.Parameters.AddWithValue("?hash", hash);
cmd.Parameters.AddWithValue("?asset_flags", meta.Flags); cmd.Parameters.AddWithValue("?asset_flags", meta.Flags);
@ -239,7 +240,12 @@ namespace OpenSim.Data.MySQL
//ExecuteNonQuery(cmd); //ExecuteNonQuery(cmd);
} }
return false;
// return false;
// if the asset already exits
// assume it was already correctly stored
// or regions will keep retry.
return true;
} }
catch(Exception e) catch(Exception e)
{ {

View File

@ -1142,8 +1142,8 @@ namespace OpenSim.Framework
void SendLayerData(float[] map); void SendLayerData(float[] map);
void SendLayerData(int px, int py, float[] map); void SendLayerData(int px, int py, float[] map);
void SendWindData(Vector2[] windSpeeds); void SendWindData(int version, Vector2[] windSpeeds);
void SendCloudData(float[] cloudCover); void SendCloudData(int version, float[] cloudCover);
/// <summary> /// <summary>
/// Sent when an agent completes its movement into a region. /// Sent when an agent completes its movement into a region.

View File

@ -55,6 +55,9 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
bool IsChildAgent { get; } bool IsChildAgent { get; }
bool IsInTransit { get; }
bool isNPC { get;}
bool Invulnerable { get; set; } bool Invulnerable { get; set; }
/// <summary> /// <summary>
/// Avatar appearance data. /// Avatar appearance data.

View File

@ -909,7 +909,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
{ {
m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue; m_thisAgentUpdateArgs.CameraAtAxis.X = float.MinValue;
m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue; // m_thisAgentUpdateArgs.ControlFlags = uint.MaxValue;
m_thisAgentUpdateArgs.ControlFlags = 0;
AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete); AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
mov.SimData.ChannelVersion = m_channelVersion; mov.SimData.ChannelVersion = m_channelVersion;
@ -1375,73 +1376,125 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
} }
// wind caching
private static Dictionary<ulong,int> lastWindVersion = new Dictionary<ulong,int>();
private static Dictionary<ulong,List<LayerDataPacket>> lastWindPackets =
new Dictionary<ulong,List<LayerDataPacket>>();
/// <summary> /// <summary>
/// Send the wind matrix to the client /// Send the wind matrix to the client
/// </summary> /// </summary>
/// <param name="windSpeeds">16x16 array of wind speeds</param> /// <param name="windSpeeds">16x16 array of wind speeds</param>
public virtual void SendWindData(Vector2[] windSpeeds) public virtual void SendWindData(int version, Vector2[] windSpeeds)
{ {
Util.FireAndForget(DoSendWindData, windSpeeds, "LLClientView.SendWindData"); // Vector2[] windSpeeds = (Vector2[])o;
ulong handle = this.Scene.RegionInfo.RegionHandle;
bool isNewData;
lock(lastWindPackets)
{
if(!lastWindVersion.ContainsKey(handle) ||
!lastWindPackets.ContainsKey(handle))
{
lastWindVersion[handle] = 0;
lastWindPackets[handle] = new List<LayerDataPacket>();
isNewData = true;
}
else
isNewData = lastWindVersion[handle] != version;
}
if(isNewData)
{
TerrainPatch[] patches = new TerrainPatch[2];
patches[0] = new TerrainPatch { Data = new float[16 * 16] };
patches[1] = new TerrainPatch { Data = new float[16 * 16] };
for (int x = 0; x < 16 * 16; x++)
{
patches[0].Data[x] = windSpeeds[x].X;
patches[1].Data[x] = windSpeeds[x].Y;
}
// neither we or viewers have extended wind
byte layerType = (byte)TerrainPatch.LayerType.Wind;
LayerDataPacket layerpack =
OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(
patches, layerType);
layerpack.Header.Zerocoded = true;
lock(lastWindPackets)
{
lastWindPackets[handle].Clear();
lastWindPackets[handle].Add(layerpack);
lastWindVersion[handle] = version;
}
}
lock(lastWindPackets)
foreach(LayerDataPacket pkt in lastWindPackets[handle])
OutPacket(pkt, ThrottleOutPacketType.Wind);
} }
// cloud caching
private static Dictionary<ulong,int> lastCloudVersion = new Dictionary<ulong,int>();
private static Dictionary<ulong,List<LayerDataPacket>> lastCloudPackets =
new Dictionary<ulong,List<LayerDataPacket>>();
/// <summary> /// <summary>
/// Send the cloud matrix to the client /// Send the cloud matrix to the client
/// </summary> /// </summary>
/// <param name="windSpeeds">16x16 array of cloud densities</param> /// <param name="windSpeeds">16x16 array of cloud densities</param>
public virtual void SendCloudData(float[] cloudDensity) public virtual void SendCloudData(int version, float[] cloudDensity)
{ {
Util.FireAndForget(DoSendCloudData, cloudDensity, "LLClientView.SendCloudData"); ulong handle = this.Scene.RegionInfo.RegionHandle;
} bool isNewData;
lock(lastWindPackets)
/// <summary>
/// Send wind layer information to the client.
/// </summary>
/// <param name="o"></param>
private void DoSendWindData(object o)
{
Vector2[] windSpeeds = (Vector2[])o;
TerrainPatch[] patches = new TerrainPatch[2];
patches[0] = new TerrainPatch { Data = new float[16 * 16] };
patches[1] = new TerrainPatch { Data = new float[16 * 16] };
for (int x = 0; x < 16 * 16; x++)
{ {
patches[0].Data[x] = windSpeeds[x].X; if(!lastCloudVersion.ContainsKey(handle) ||
patches[1].Data[x] = windSpeeds[x].Y; !lastCloudPackets.ContainsKey(handle))
{
lastCloudVersion[handle] = 0;
lastCloudPackets[handle] = new List<LayerDataPacket>();
isNewData = true;
}
else
isNewData = lastCloudVersion[handle] != version;
} }
// neither we or viewers have extended wind if(isNewData)
byte layerType = (byte)TerrainPatch.LayerType.Wind;
LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(patches, layerType);
layerpack.Header.Zerocoded = true;
OutPacket(layerpack, ThrottleOutPacketType.Wind);
}
/// <summary>
/// Send cloud layer information to the client.
/// </summary>
/// <param name="o"></param>
private void DoSendCloudData(object o)
{
float[] cloudCover = (float[])o;
TerrainPatch[] patches = new TerrainPatch[1];
patches[0] = new TerrainPatch();
patches[0].Data = new float[16 * 16];
for (int y = 0; y < 16; y++)
{ {
for (int x = 0; x < 16; x++) TerrainPatch[] patches = new TerrainPatch[1];
patches[0] = new TerrainPatch();
patches[0].Data = new float[16 * 16];
for (int y = 0; y < 16; y++)
{ {
patches[0].Data[y * 16 + x] = cloudCover[y * 16 + x]; for (int x = 0; x < 16; x++)
{
patches[0].Data[y * 16 + x] = cloudDensity[y * 16 + x];
}
}
// neither we or viewers have extended clouds
byte layerType = (byte)TerrainPatch.LayerType.Cloud;
LayerDataPacket layerpack =
OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(
patches, layerType);
layerpack.Header.Zerocoded = true;
lock(lastCloudPackets)
{
lastCloudPackets[handle].Clear();
lastCloudPackets[handle].Add(layerpack);
lastCloudVersion[handle] = version;
} }
} }
// neither we or viewers have extended clouds
byte layerType = (byte)TerrainPatch.LayerType.Cloud;
LayerDataPacket layerpack = OpenSimTerrainCompressor.CreateLayerDataPacketStandardSize(patches, layerType); lock(lastCloudPackets)
layerpack.Header.Zerocoded = true; foreach(LayerDataPacket pkt in lastCloudPackets[handle])
OutPacket(layerpack, ThrottleOutPacketType.Cloud); OutPacket(pkt, ThrottleOutPacketType.Cloud);
} }
/// <summary> /// <summary>
@ -6144,27 +6197,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param> /// <param name='x'></param>
private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) private bool CheckAgentMovementUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{ {
float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation)); if(
//qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation));
bool movementSignificant =
(x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed (x.ControlFlags != m_thisAgentUpdateArgs.ControlFlags) // significant if control flags changed
|| (x.ControlFlags != (byte)AgentManager.ControlFlags.NONE) // significant if user supplying any movement update commands || ((x.ControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0 &&
(x.ControlFlags & 0x3f8dfff) != 0) // we need to rotate the av on fly
|| (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed || (x.Flags != m_thisAgentUpdateArgs.Flags) // significant if Flags changed
|| (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed || (x.State != m_thisAgentUpdateArgs.State) // significant if Stats changed
|| (qdelta1 < QDELTABody) // significant if body rotation above(below cos) threshold
// Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
// || (qdelta2 < QDELTAHead) // significant if head rotation above(below cos) threshold
|| (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed || (Math.Abs(x.Far - m_thisAgentUpdateArgs.Far) >= 32) // significant if far distance changed
; )
//if (movementSignificant) return true;
//{
//m_log.DebugFormat("[LLCLIENTVIEW]: Bod {0} {1}", float qdelta1 = Math.Abs(Quaternion.Dot(x.BodyRotation, m_thisAgentUpdateArgs.BodyRotation));
// qdelta1, qdelta2); //qdelta2 = Math.Abs(Quaternion.Dot(x.HeadRotation, m_thisAgentUpdateArgs.HeadRotation));
//m_log.DebugFormat("[LLCLIENTVIEW]: St {0} {1} {2} {3}",
// x.ControlFlags, x.Flags, x.Far, x.State); if(
//} qdelta1 < QDELTABody // significant if body rotation above(below cos) threshold
return movementSignificant; // Ignoring head rotation altogether, because it's not being used for anything interesting up the stack
// || qdelta2 < QDELTAHead // significant if head rotation above(below cos) threshold
)
return true;
return false;
} }
/// <summary> /// <summary>
@ -6175,33 +6228,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// <param name='x'></param> /// <param name='x'></param>
private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x) private bool CheckAgentCameraUpdateSignificance(AgentUpdatePacket.AgentDataBlock x)
{ {
float vdelta1 = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis); float vdelta = Vector3.Distance(x.CameraAtAxis, m_thisAgentUpdateArgs.CameraAtAxis);
float vdelta2 = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter); if((vdelta > VDELTA))
float vdelta3 = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis); return true;
float vdelta4 = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
bool cameraSignificant = vdelta = Vector3.Distance(x.CameraCenter, m_thisAgentUpdateArgs.CameraCenter);
(vdelta1 > VDELTA) || if((vdelta > VDELTA))
(vdelta2 > VDELTA) || return true;
(vdelta3 > VDELTA) ||
(vdelta4 > VDELTA)
;
//if (cameraSignificant) vdelta = Vector3.Distance(x.CameraLeftAxis, m_thisAgentUpdateArgs.CameraLeftAxis);
//{ if((vdelta > VDELTA))
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam1 {0} {1}", return true;
// x.CameraAtAxis, x.CameraCenter);
//m_log.DebugFormat("[LLCLIENTVIEW]: Cam2 {0} {1}",
// x.CameraLeftAxis, x.CameraUpAxis);
//}
return cameraSignificant; vdelta = Vector3.Distance(x.CameraUpAxis, m_thisAgentUpdateArgs.CameraUpAxis);
if((vdelta > VDELTA))
return true;
return false;
} }
private bool HandleAgentUpdate(IClientAPI sender, Packet packet) private bool HandleAgentUpdate(IClientAPI sender, Packet packet)
{ {
// We got here, which means that something in agent update was significant
AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet; AgentUpdatePacket agentUpdate = (AgentUpdatePacket)packet;
AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData; AgentUpdatePacket.AgentDataBlock x = agentUpdate.AgentData;
@ -6212,10 +6259,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
} }
TotalAgentUpdates++; TotalAgentUpdates++;
// dont let ignored updates pollute this throttles
if(SceneAgent == null || SceneAgent.IsChildAgent || SceneAgent.IsInTransit)
{
// throttle reset is done at MoveAgentIntoRegion()
// called by scenepresence on completemovement
PacketPool.Instance.ReturnPacket(packet);
return true;
}
bool movement = CheckAgentMovementUpdateSignificance(x); bool movement = CheckAgentMovementUpdateSignificance(x);
bool camera = CheckAgentCameraUpdateSignificance(x); bool camera = CheckAgentCameraUpdateSignificance(x);
// Was there a significant movement/state change? // Was there a significant movement/state change?
if (movement) if (movement)
{ {
@ -6224,7 +6279,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
m_thisAgentUpdateArgs.Far = x.Far; m_thisAgentUpdateArgs.Far = x.Far;
m_thisAgentUpdateArgs.Flags = x.Flags; m_thisAgentUpdateArgs.Flags = x.Flags;
m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation; m_thisAgentUpdateArgs.HeadRotation = x.HeadRotation;
// m_thisAgentUpdateArgs.SessionID = x.SessionID;
m_thisAgentUpdateArgs.State = x.State; m_thisAgentUpdateArgs.State = x.State;
UpdateAgent handlerAgentUpdate = OnAgentUpdate; UpdateAgent handlerAgentUpdate = OnAgentUpdate;
@ -6235,9 +6289,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (handlerAgentUpdate != null) if (handlerAgentUpdate != null)
OnAgentUpdate(this, m_thisAgentUpdateArgs); OnAgentUpdate(this, m_thisAgentUpdateArgs);
handlerAgentUpdate = null;
handlerPreAgentUpdate = null;
} }
// Was there a significant camera(s) change? // Was there a significant camera(s) change?
@ -6253,7 +6305,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (handlerAgentCameraUpdate != null) if (handlerAgentCameraUpdate != null)
handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs); handlerAgentCameraUpdate(this, m_thisAgentUpdateArgs);
handlerAgentCameraUpdate = null;
} }
PacketPool.Instance.ReturnPacket(packet); PacketPool.Instance.ReturnPacket(packet);

View File

@ -374,9 +374,11 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
if (channel == DEBUG_CHANNEL) if (channel == DEBUG_CHANNEL)
return; return;
// Is id an avatar? if(target == UUID.Zero)
ScenePresence sp = m_scene.GetScenePresence(target); return;
// Is target an avatar?
ScenePresence sp = m_scene.GetScenePresence(target);
if (sp != null) if (sp != null)
{ {
// Send message to avatar // Send message to avatar
@ -401,19 +403,22 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
foreach (SceneObjectGroup sog in attachments) foreach (SceneObjectGroup sog in attachments)
{ {
if (!sog.IsDeleted) if (!sog.IsDeleted)
targets.Add(sog.UUID); {
SceneObjectPart[] parts = sog.Parts;
foreach(SceneObjectPart p in parts)
targets.Add(p.UUID);
}
} }
// Need to check each attachment
foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
{ {
if (li.GetHostID().Equals(id)) UUID liHostID = li.GetHostID();
if (liHostID.Equals(id))
continue; continue;
if (m_scene.GetSceneObjectPart(liHostID) == null)
if (m_scene.GetSceneObjectPart(li.GetHostID()) == null)
continue; continue;
if (targets.Contains(li.GetHostID())) if (targets.Contains(liHostID))
QueueMessage(new ListenerInfo(li, name, id, msg)); QueueMessage(new ListenerInfo(li, name, id, msg));
} }
@ -426,16 +431,15 @@ namespace OpenSim.Region.CoreModules.Scripting.WorldComm
foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg)) foreach (ListenerInfo li in m_listenerManager.GetListeners(UUID.Zero, channel, name, id, msg))
{ {
UUID liHostID = li.GetHostID();
// Dont process if this message is from yourself! // Dont process if this message is from yourself!
if (li.GetHostID().Equals(id)) if (liHostID.Equals(id))
continue; continue;
SceneObjectPart sPart = m_scene.GetSceneObjectPart( if (m_scene.GetSceneObjectPart(liHostID) == null)
li.GetHostID());
if (sPart == null)
continue; continue;
if (li.GetHostID().Equals(target)) if (liHostID.Equals(target))
{ {
QueueMessage(new ListenerInfo(li, name, id, msg)); QueueMessage(new ListenerInfo(li, name, id, msg));
break; break;

View File

@ -227,8 +227,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (boOption != m_boundingOrigin) if (boOption != m_boundingOrigin)
{ {
m_boundingOrigin = boOption; m_boundingOrigin = boOption;
m_boundingBox = true;
} }
m_boundingBox = true;
} }
if (options.ContainsKey("bounding-size")) if (options.ContainsKey("bounding-size"))
@ -936,14 +936,24 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (m_assetService.GetMetadata(uuid) != null) if (m_assetService.GetMetadata(uuid) != null)
{ {
sbyte asype = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
if(asype == -2)
{
}
// m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid); // m_log.DebugFormat("[ARCHIVER]: found existing asset {0}",uuid);
return true; return true;
} }
if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension)) if (ArchiveConstants.EXTENSION_TO_ASSET_TYPE.ContainsKey(extension))
{ {
sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension]; sbyte assetType = ArchiveConstants.EXTENSION_TO_ASSET_TYPE[extension];
if(assetType == -2)
{
}
if (assetType == (sbyte)AssetType.Unknown) if (assetType == (sbyte)AssetType.Unknown)
{ {
m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid); m_log.WarnFormat("[ARCHIVER]: Importing {0} byte asset {1} with unknown type", data.Length, uuid);

View File

@ -285,10 +285,15 @@ namespace OpenSim.Region.CoreModules.World.Archiver
if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired) if (m_foundAssetUuids.Count + m_notFoundAssetUuids.Count >= m_repliesRequired)
{ {
m_requestState = RequestState.Completed; m_requestState = RequestState.Completed;
if(m_notFoundAssetUuids.Count == 0)
m_log.DebugFormat( m_log.DebugFormat(
"[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)", "[ARCHIVER]: Successfully added {0} assets",
m_foundAssetUuids.Count);
else
m_log.DebugFormat(
"[ARCHIVER]: Successfully added {0} assets ({1} assets not found but these may be expected invalid references)",
m_foundAssetUuids.Count, m_notFoundAssetUuids.Count); m_foundAssetUuids.Count, m_notFoundAssetUuids.Count);
// We want to stop using the asset cache thread asap // We want to stop using the asset cache thread asap
// as we now need to do the work of producing the rest of the archive // as we now need to do the work of producing the rest of the archive

View File

@ -27,6 +27,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading;
using Mono.Addins; using Mono.Addins;
using Nini.Config; using Nini.Config;
using OpenMetaverse; using OpenMetaverse;
@ -43,12 +44,16 @@ namespace OpenSim.Region.CoreModules.World
// = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); // = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private uint m_frame = 0; private uint m_frame = 0;
private int m_frameUpdateRate = 1000; private int m_frameUpdateRate = 1000;
private Random m_rndnums = new Random(Environment.TickCount); private Random m_rndnums;
private Scene m_scene = null; private Scene m_scene = null;
private bool m_ready = false; private bool m_ready = false;
private bool m_enabled = false; private bool m_enabled = false;
private float m_cloudDensity = 1.0F; private float m_cloudDensity = 1.0F;
private float[] cloudCover = new float[16 * 16]; private float[] cloudCover = new float[16 * 16];
private int m_dataVersion;
private bool m_busy;
private object cloudlock = new object();
public void Initialise(IConfigSource config) public void Initialise(IConfigSource config)
{ {
@ -70,11 +75,17 @@ namespace OpenSim.Region.CoreModules.World
m_scene = scene; m_scene = scene;
scene.EventManager.OnNewClient += CloudsToClient;
scene.RegisterModuleInterface<ICloudModule>(this); scene.RegisterModuleInterface<ICloudModule>(this);
scene.EventManager.OnFrame += CloudUpdate; int seed = Environment.TickCount;
seed += (int)(scene.RegionInfo.RegionLocX << 16);
seed += (int)(scene.RegionInfo.RegionLocY);
m_rndnums = new Random(seed);
GenerateCloudCover(); GenerateCloudCover();
m_dataVersion = (int)m_scene.AllocateLocalId();
scene.EventManager.OnNewClient += CloudsToClient;
scene.EventManager.OnFrame += CloudUpdate;
m_ready = true; m_ready = true;
} }
@ -89,7 +100,6 @@ namespace OpenSim.Region.CoreModules.World
m_scene.EventManager.OnNewClient -= CloudsToClient; m_scene.EventManager.OnNewClient -= CloudsToClient;
m_scene.EventManager.OnFrame -= CloudUpdate; m_scene.EventManager.OnFrame -= CloudUpdate;
m_scene.UnregisterModuleInterface<ICloudModule>(this); m_scene.UnregisterModuleInterface<ICloudModule>(this);
m_scene = null; m_scene = null;
} }
@ -127,7 +137,8 @@ namespace OpenSim.Region.CoreModules.World
if (cloudCover != null) if (cloudCover != null)
{ {
cover = cloudCover[y * 16 + x]; lock(cloudlock)
cover = cloudCover[y * 16 + x];
} }
return cover; return cover;
@ -188,22 +199,47 @@ namespace OpenSim.Region.CoreModules.World
} }
} }
Array.Copy(newCover, cloudCover, 16 * 16); Array.Copy(newCover, cloudCover, 16 * 16);
m_dataVersion++;
} }
private void CloudUpdate() private void CloudUpdate()
{ {
if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready || (m_cloudDensity == 0)) if ((!m_ready || m_busy || m_cloudDensity == 0 ||
{ (m_frame++ % m_frameUpdateRate) != 0))
return; return;
}
UpdateCloudCover(); if(Monitor.TryEnter(cloudlock))
{
m_busy = true;
Util.FireAndForget(delegate
{
try
{
lock(cloudlock)
{
UpdateCloudCover();
m_scene.ForEachClient(delegate(IClientAPI client)
{
client.SendCloudData(m_dataVersion, cloudCover);
});
}
}
finally
{
m_busy = false;
}
},
null, "CloudModuleUpdate");
Monitor.Exit(cloudlock);
}
} }
public void CloudsToClient(IClientAPI client) public void CloudsToClient(IClientAPI client)
{ {
if (m_ready) if (m_ready)
{ {
client.SendCloudData(cloudCover); lock(cloudlock)
client.SendCloudData(m_dataVersion, cloudCover);
} }
} }

View File

@ -1360,7 +1360,8 @@ namespace OpenSim.Region.CoreModules.World.Estate
public void sendRegionInfoPacketToAll() public void sendRegionInfoPacketToAll()
{ {
Scene.ForEachRootClient(delegate(IClientAPI client) // Scene.ForEachRootClient(delegate(IClientAPI client)
Scene.ForEachClient(delegate(IClientAPI client)
{ {
HandleRegionInfoRequest(client); HandleRegionInfoRequest(client);
}); });

View File

@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.World.Estate
sr.Close(); sr.Close();
body = body.Trim(); body = body.Trim();
m_log.DebugFormat("[XESTATE HANDLER]: query String: {0}", body); // m_log.DebugFormat("[XESTATE HANDLER]: query String: {0}", body);
try try
{ {

View File

@ -212,7 +212,6 @@ namespace OpenSim.Region.CoreModules.World.Land
client.OnParcelReclaim += ClientOnParcelReclaim; client.OnParcelReclaim += ClientOnParcelReclaim;
client.OnParcelInfoRequest += ClientOnParcelInfoRequest; client.OnParcelInfoRequest += ClientOnParcelInfoRequest;
client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup; client.OnParcelDeedToGroup += ClientOnParcelDeedToGroup;
client.OnPreAgentUpdate += ClientOnPreAgentUpdate;
client.OnParcelEjectUser += ClientOnParcelEjectUser; client.OnParcelEjectUser += ClientOnParcelEjectUser;
client.OnParcelFreezeUser += ClientOnParcelFreezeUser; client.OnParcelFreezeUser += ClientOnParcelFreezeUser;
client.OnSetStartLocationRequest += ClientOnSetHome; client.OnSetStartLocationRequest += ClientOnSetHome;
@ -223,10 +222,6 @@ namespace OpenSim.Region.CoreModules.World.Land
avatar.currentParcelUUID = UUID.Zero; avatar.currentParcelUUID = UUID.Zero;
} }
void ClientOnPreAgentUpdate(IClientAPI remoteClient, AgentUpdateArgs agentData)
{
}
public void Close() public void Close()
{ {
} }

View File

@ -103,7 +103,7 @@ namespace OpenSim.Region.CoreModules.World.Wind.Plugins
} }
} }
public void WindUpdate(uint frame) public bool WindUpdate(uint frame)
{ {
double avgAng = m_avgDirection * (Math.PI/180.0f); double avgAng = m_avgDirection * (Math.PI/180.0f);
double varDir = m_varDirection * (Math.PI/180.0f); double varDir = m_varDirection * (Math.PI/180.0f);
@ -125,10 +125,8 @@ namespace OpenSim.Region.CoreModules.World.Wind.Plugins
offset = Math.Sin(theta) * Math.Sin(theta*4) + (Math.Sin(theta*13) / 3); offset = Math.Sin(theta) * Math.Sin(theta*4) + (Math.Sin(theta*13) / 3);
double windSpeed = m_avgStrength + (m_varStrength * offset); double windSpeed = m_avgStrength + (m_varStrength * offset);
if (windSpeed<0) if (windSpeed < 0)
windSpeed=0; windSpeed = -windSpeed;
m_curPredominateWind.X = (float)Math.Cos(windDir); m_curPredominateWind.X = (float)Math.Cos(windDir);
m_curPredominateWind.Y = (float)Math.Sin(windDir); m_curPredominateWind.Y = (float)Math.Sin(windDir);
@ -144,6 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Wind.Plugins
m_windSpeeds[y * 16 + x] = m_curPredominateWind; m_windSpeeds[y * 16 + x] = m_curPredominateWind;
} }
} }
return true;
} }
public Vector3 WindSpeed(float fX, float fY, float fZ) public Vector3 WindSpeed(float fX, float fY, float fZ)

View File

@ -82,22 +82,23 @@ namespace OpenSim.Region.CoreModules.World.Wind.Plugins
} }
} }
public void WindUpdate(uint frame) public bool WindUpdate(uint frame)
{ {
//Make sure our object is valid (we haven't been disposed of yet) //Make sure our object is valid (we haven't been disposed of yet)
if (m_windSpeeds != null) if (m_windSpeeds == null)
return false;
for (int y = 0; y < 16; y++)
{ {
for (int y = 0; y < 16; y++) for (int x = 0; x < 16; x++)
{ {
for (int x = 0; x < 16; x++) m_windSpeeds[y * 16 + x].X = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1
{ m_windSpeeds[y * 16 + x].Y = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1
m_windSpeeds[y * 16 + x].X = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1 m_windSpeeds[y * 16 + x].X *= m_strength;
m_windSpeeds[y * 16 + x].Y = (float)(m_rndnums.NextDouble() * 2d - 1d); // -1 to 1 m_windSpeeds[y * 16 + x].Y *= m_strength;
m_windSpeeds[y * 16 + x].X *= m_strength;
m_windSpeeds[y * 16 + x].Y *= m_strength;
}
} }
} }
return true;
} }
public Vector3 WindSpeed(float fX, float fY, float fZ) public Vector3 WindSpeed(float fX, float fY, float fZ)

View File

@ -46,11 +46,13 @@ namespace OpenSim.Region.CoreModules
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private uint m_frame = 0; private uint m_frame = 0;
private uint m_frameLastUpdateClientArray = 0; private int m_dataVersion = 0;
private int m_regionID = 0;
private int m_frameUpdateRate = 150; private int m_frameUpdateRate = 150;
//private Random m_rndnums = new Random(Environment.TickCount); //private Random m_rndnums = new Random(Environment.TickCount);
private Scene m_scene = null; private Scene m_scene = null;
private bool m_ready = false; private bool m_ready = false;
private bool m_inUpdate = false;
private bool m_enabled = false; private bool m_enabled = false;
private IConfig m_windConfig; private IConfig m_windConfig;
@ -96,7 +98,6 @@ namespace OpenSim.Region.CoreModules
m_scene = scene; m_scene = scene;
m_frame = 0; m_frame = 0;
// Register all the Wind Model Plug-ins // Register all the Wind Model Plug-ins
foreach (IWindModelPlugin windPlugin in AddinManager.GetExtensionObjects("/OpenSim/WindModule", false)) foreach (IWindModelPlugin windPlugin in AddinManager.GetExtensionObjects("/OpenSim/WindModule", false))
{ {
@ -118,7 +119,6 @@ namespace OpenSim.Region.CoreModules
} }
} }
// if the plug-in wasn't found, default to no wind. // if the plug-in wasn't found, default to no wind.
if (m_activeWindPlugin == null) if (m_activeWindPlugin == null)
{ {
@ -154,14 +154,14 @@ namespace OpenSim.Region.CoreModules
// Register event handlers for when Avatars enter the region, and frame ticks // Register event handlers for when Avatars enter the region, and frame ticks
m_scene.EventManager.OnFrame += WindUpdate; m_scene.EventManager.OnFrame += WindUpdate;
m_scene.EventManager.OnMakeRootAgent += OnAgentEnteredRegion;
// Register the wind module // Register the wind module
m_scene.RegisterModuleInterface<IWindModule>(this); m_scene.RegisterModuleInterface<IWindModule>(this);
// Generate initial wind values // Generate initial wind values
GenWindPos(); GenWind();
// hopefully this will not be the same for all regions on same instance
m_dataVersion = (int)m_scene.AllocateLocalId();
// Mark Module Ready for duty // Mark Module Ready for duty
m_ready = true; m_ready = true;
} }
@ -184,7 +184,7 @@ namespace OpenSim.Region.CoreModules
// Remove our hooks // Remove our hooks
m_scene.EventManager.OnFrame -= WindUpdate; m_scene.EventManager.OnFrame -= WindUpdate;
m_scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion; // m_scene.EventManager.OnMakeRootAgent -= OnAgentEnteredRegion;
} }
@ -416,67 +416,43 @@ namespace OpenSim.Region.CoreModules
/// </summary> /// </summary>
public void WindUpdate() public void WindUpdate()
{ {
if (((m_frame++ % m_frameUpdateRate) != 0) || !m_ready) if ((!m_ready || m_inUpdate || (m_frame++ % m_frameUpdateRate) != 0))
{
return; return;
}
GenWindPos(); m_inUpdate = true;
Util.FireAndForget(delegate
SendWindAllClients();
}
public void OnAgentEnteredRegion(ScenePresence avatar)
{
if (m_ready)
{ {
if (m_activeWindPlugin != null) try
{ {
// Ask wind plugin to generate a LL wind array to be cached locally GenWind();
// Try not to update this too often, as it may involve array copies m_scene.ForEachClient(delegate(IClientAPI client)
if (m_frame >= (m_frameLastUpdateClientArray + m_frameUpdateRate))
{ {
windSpeeds = m_activeWindPlugin.WindLLClientArray(); client.SendWindData(m_dataVersion, windSpeeds);
m_frameLastUpdateClientArray = m_frame;
}
}
avatar.ControllingClient.SendWindData(windSpeeds);
}
}
private void SendWindAllClients()
{
if (m_ready)
{
if (m_scene.GetRootAgentCount() > 0)
{
// Ask wind plugin to generate a LL wind array to be cached locally
// Try not to update this too often, as it may involve array copies
if (m_frame >= (m_frameLastUpdateClientArray + m_frameUpdateRate))
{
windSpeeds = m_activeWindPlugin.WindLLClientArray();
m_frameLastUpdateClientArray = m_frame;
}
m_scene.ForEachRootClient(delegate(IClientAPI client)
{
client.SendWindData(windSpeeds);
}); });
} }
} finally
{
m_inUpdate = false;
}
},
null, "WindModuleUpdate");
} }
/// <summary> /// <summary>
/// Calculate the sun's orbital position and its velocity. /// Calculate new wind
/// returns false if no change
/// </summary> /// </summary>
private void GenWindPos() private bool GenWind()
{ {
if (m_activeWindPlugin != null) if (m_activeWindPlugin != null && m_activeWindPlugin.WindUpdate(m_frame))
{ {
// Tell Wind Plugin to update it's wind data windSpeeds = m_activeWindPlugin.WindLLClientArray();
m_activeWindPlugin.WindUpdate(m_frame); m_dataVersion++;
return true;
} }
return false;
} }
} }
} }

View File

@ -53,7 +53,7 @@ namespace OpenSim.Region.Framework.Interfaces
/// <summary> /// <summary>
/// Update wind. /// Update wind.
/// </summary> /// </summary>
void WindUpdate(uint frame); bool WindUpdate(uint frame);
/// <summary> /// <summary>
/// Returns the wind vector at the given local region coordinates. /// Returns the wind vector at the given local region coordinates.

View File

@ -274,50 +274,46 @@ namespace OpenSim.Region.Framework.Scenes
private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity) private uint GetPriorityByAngularDistance(IClientAPI client, ISceneEntity entity)
{ {
uint pqueue = 2; // keep compiler happy
ScenePresence presence = m_scene.GetScenePresence(client.AgentId); ScenePresence presence = m_scene.GetScenePresence(client.AgentId);
if (presence == null) if (presence == null)
return PriorityQueue.NumberOfQueues - 1; return PriorityQueue.NumberOfQueues - 1;
// All avatars other than our own go into pqueue 1 uint pqueue = ComputeAngleDistancePriority(presence, entity);
if (entity is ScenePresence)
return 1;
if (entity is SceneObjectPart)
{
// Attachments are high priority,
if (((SceneObjectPart)entity).ParentGroup.IsAttachment)
return 2;
pqueue = ComputeAngleDistancePriority(presence, entity);
// Non physical prims are lower priority than physical prims
PhysicsActor physActor = ((SceneObjectPart)entity).ParentGroup.RootPart.PhysActor;
if (physActor == null || !physActor.IsPhysical)
pqueue++;
}
return pqueue; return pqueue;
} }
private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity) private uint ComputeAngleDistancePriority(ScenePresence presence, ISceneEntity entity)
{ {
double distance;
Vector3 presencePos = presence.AbsolutePosition;
SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
float bradius = group.GetBoundsRadius();
Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter();
distance = Vector3.Distance(presencePos, grppos);
distance -= bradius;
distance *= group.getAreaFactor();
// And convert the distance to a priority queue, this computation gives queues // And convert the distance to a priority queue, this computation gives queues
// at 10, 20, 40, 80, 160, 320, 640, and 1280m // at 10, 20, 40, 80, 160, 320, 640, and 1280m
uint pqueue = PriorityQueue.NumberOfImmediateQueues + 1; // reserve attachments queue // uint minpqueue = PriorityQueue.NumberOfImmediateQueues;
uint queues = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues; uint maxqueue = PriorityQueue.NumberOfQueues - PriorityQueue.NumberOfImmediateQueues -1;
// uint pqueue = minpqueue;
uint pqueue = PriorityQueue.NumberOfImmediateQueues;
float distance;
Vector3 presencePos = presence.AbsolutePosition;
if(entity is ScenePresence)
{
ScenePresence sp = entity as ScenePresence;
distance = Vector3.Distance(presencePos, sp.AbsolutePosition);
distance *= 0.5f;
}
else
{
SceneObjectGroup group = (entity as SceneObjectPart).ParentGroup;
float bradius = group.GetBoundsRadius();
Vector3 grppos = group.AbsolutePosition + group.getBoundsCenter();
distance = Vector3.Distance(presencePos, grppos);
distance -= bradius;
distance *= group.getAreaFactor();
if(group.IsAttachment)
distance *= 0.5f;
else if(group.UsesPhysics)
distance *= 0.6f;
else if(group.GetSittingAvatarsCount() > 0)
distance *= 0.5f;
}
if (distance > 10f) if (distance > 10f)
{ {
@ -328,8 +324,8 @@ namespace OpenSim.Region.Framework.Scenes
// 2st constant makes it be log2(distance/10) // 2st constant makes it be log2(distance/10)
pqueue += (uint)tmp; pqueue += (uint)tmp;
if (pqueue > queues - 1) if (pqueue > maxqueue)
pqueue = queues - 1; pqueue = maxqueue;
} }
return pqueue; return pqueue;

View File

@ -1865,7 +1865,8 @@ namespace OpenSim.Region.Framework.Scenes
// this is here so physics gets updated! // this is here so physics gets updated!
// Don't remove! Bad juju! Stay away! or fix physics! // Don't remove! Bad juju! Stay away! or fix physics!
child.AbsolutePosition = child.AbsolutePosition; // already done in LinkToGroup
// child.AbsolutePosition = child.AbsolutePosition;
} }
} }
@ -1912,31 +1913,36 @@ namespace OpenSim.Region.Framework.Scenes
// //
foreach (SceneObjectPart part in prims) foreach (SceneObjectPart part in prims)
{ {
if (part != null) if(part == null)
{ continue;
if (part.KeyframeMotion != null) SceneObjectGroup parentSOG = part.ParentGroup;
{ if(parentSOG == null ||
part.KeyframeMotion.Stop(); parentSOG.IsDeleted ||
part.KeyframeMotion = null; parentSOG.inTransit ||
} parentSOG.PrimCount == 1)
if (part.ParentGroup.PrimCount != 1) // Skip single continue;
{
if (part.LinkNum < 2) // Root
{
rootParts.Add(part);
}
else
{
part.LastOwnerID = part.ParentGroup.RootPart.LastOwnerID;
childParts.Add(part);
}
SceneObjectGroup group = part.ParentGroup; if (!affectedGroups.Contains(parentSOG))
if (!affectedGroups.Contains(group)) {
{ affectedGroups.Add(parentSOG);
affectedGroups.Add(group); if(parentSOG.RootPart.PhysActor != null)
} parentSOG.RootPart.PhysActor.Building = true;
} }
if (part.KeyframeMotion != null)
{
part.KeyframeMotion.Stop();
part.KeyframeMotion = null;
}
if (part.LinkNum < 2) // Root
{
rootParts.Add(part);
}
else
{
part.LastOwnerID = part.ParentGroup.RootPart.LastOwnerID;
childParts.Add(part);
} }
} }
@ -1945,8 +1951,8 @@ namespace OpenSim.Region.Framework.Scenes
foreach (SceneObjectPart child in childParts) foreach (SceneObjectPart child in childParts)
{ {
// Unlink all child parts from their groups // Unlink all child parts from their groups
//
child.ParentGroup.DelinkFromGroup(child, true); child.ParentGroup.DelinkFromGroup(child, true);
//child.ParentGroup is now other
child.ParentGroup.HasGroupChanged = true; child.ParentGroup.HasGroupChanged = true;
child.ParentGroup.ScheduleGroupForFullUpdate(); child.ParentGroup.ScheduleGroupForFullUpdate();
} }
@ -1959,74 +1965,51 @@ namespace OpenSim.Region.Framework.Scenes
// However, editing linked parts and unlinking may be different // However, editing linked parts and unlinking may be different
// //
SceneObjectGroup group = root.ParentGroup; SceneObjectGroup group = root.ParentGroup;
List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts); List<SceneObjectPart> newSet = new List<SceneObjectPart>(group.Parts);
int numChildren = newSet.Count;
if (numChildren == 1) newSet.Remove(root);
int numChildren = newSet.Count;
if(numChildren == 0)
break; break;
// If there are prims left in a link set, but the root is
// slated for unlink, we need to do this
// Unlink the remaining set
//
bool sendEventsToRemainder = false;
if (numChildren == 2) // only one child prim no re-link needed
sendEventsToRemainder = true;
foreach (SceneObjectPart p in newSet) foreach (SceneObjectPart p in newSet)
{ group.DelinkFromGroup(p, false);
if (p != group.RootPart)
{
group.DelinkFromGroup(p, sendEventsToRemainder);
if (sendEventsToRemainder) // finish single child prim now
{
p.ParentGroup.HasGroupChanged = true;
p.ParentGroup.ScheduleGroupForFullUpdate();
}
}
}
SceneObjectPart newRoot = newSet[0];
// If there is more than one prim remaining, we // If there is more than one prim remaining, we
// need to re-link // need to re-link
// //
if (numChildren > 2) if (numChildren > 1)
{ {
// Remove old root
//
if (newSet.Contains(root))
newSet.Remove(root);
// Preserve link ordering
//
newSet.Sort(delegate (SceneObjectPart a, SceneObjectPart b)
{
return a.LinkNum.CompareTo(b.LinkNum);
});
// Determine new root // Determine new root
// //
SceneObjectPart newRoot = newSet[0];
newSet.RemoveAt(0); newSet.RemoveAt(0);
foreach (SceneObjectPart newChild in newSet)
foreach (SceneObjectPart newChild in newSet) newChild.ClearUpdateSchedule();
newChild.ClearUpdateSchedule();
LinkObjects(newRoot, newSet); LinkObjects(newRoot, newSet);
// if (!affectedGroups.Contains(newRoot.ParentGroup)) }
// affectedGroups.Add(newRoot.ParentGroup); else
{
newRoot.TriggerScriptChangedEvent(Changed.LINK);
newRoot.ParentGroup.HasGroupChanged = true;
newRoot.ParentGroup.ScheduleGroupForFullUpdate();
} }
} }
// Finally, trigger events in the roots // trigger events in the roots
// //
foreach (SceneObjectGroup g in affectedGroups) foreach (SceneObjectGroup g in affectedGroups)
{ {
if(g.RootPart.PhysActor != null)
g.RootPart.PhysActor.Building = false;
g.AdjustChildPrimPermissions(false);
// Child prims that have been unlinked and deleted will // Child prims that have been unlinked and deleted will
// return unless the root is deleted. This will remove them // return unless the root is deleted. This will remove them
// from the database. They will be rewritten immediately, // from the database. They will be rewritten immediately,
// minus the rows for the unlinked child prims. // minus the rows for the unlinked child prims.
g.AdjustChildPrimPermissions(false);
m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID); m_parentScene.SimulationDataService.RemoveObject(g.UUID, m_parentScene.RegionInfo.RegionID);
g.TriggerScriptChangedEvent(Changed.LINK); g.TriggerScriptChangedEvent(Changed.LINK);
g.HasGroupChanged = true; // Persist g.HasGroupChanged = true; // Persist

View File

@ -3168,10 +3168,11 @@ namespace OpenSim.Region.Framework.Scenes
if (insert) if (insert)
{ {
linkNum = 2; linkNum = 2;
int insertSize = objectGroup.PrimCount;
foreach (SceneObjectPart part in Parts) foreach (SceneObjectPart part in Parts)
{ {
if (part.LinkNum > 1) if (part.LinkNum > 1)
part.LinkNum++; part.LinkNum += insertSize;
} }
} }
else else
@ -3200,14 +3201,14 @@ namespace OpenSim.Region.Framework.Scenes
linkPart.LinkNum = linkNum++; linkPart.LinkNum = linkNum++;
linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false); linkPart.UpdatePrimFlags(UsesPhysics, IsTemporary, IsPhantom, IsVolumeDetect, false);
// Get a list of the SOP's in the old group in order of their linknum's. // Get a list of the SOP's in the source group in order of their linknum's.
SceneObjectPart[] ogParts = objectGroup.Parts; SceneObjectPart[] ogParts = objectGroup.Parts;
Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b) Array.Sort(ogParts, delegate(SceneObjectPart a, SceneObjectPart b)
{ {
return a.LinkNum - b.LinkNum; return a.LinkNum - b.LinkNum;
}); });
// Add each of the SOP's from the old linkset to our linkset // Add each of the SOP's from the source linkset to our linkset
for (int i = 0; i < ogParts.Length; i++) for (int i = 0; i < ogParts.Length; i++)
{ {
SceneObjectPart part = ogParts[i]; SceneObjectPart part = ogParts[i];
@ -3415,6 +3416,110 @@ namespace OpenSim.Region.Framework.Scenes
return objectGroup; return objectGroup;
} }
/* working on it
public void DelinkFromGroup(List<SceneObjectPart> linkParts, bool sendEvents)
{
// m_log.DebugFormat(
// "[SCENE OBJECT GROUP]: Delinking part {0}, {1} from group with root part {2}, {3}",
// linkPart.Name, linkPart.UUID, RootPart.Name, RootPart.UUID);
if(PrimCount == 1)
return;
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = true;
bool unlinkroot = false;
foreach(SceneObjectPart linkPart in linkParts)
{
// first we only remove child parts
if(linkPart.LocalId == m_rootPart.LocalId)
{
unlinkroot = true;
continue;
}
lock (m_parts.SyncRoot)
if(!m_parts.Remove(linkPart.UUID))
continue;
linkPart.ClearUndoState();
Vector3 worldPos = linkPart.GetWorldPosition();
Quaternion worldRot = linkPart.GetWorldRotation();
linkPart.ParentID = 0;
linkPart.LinkNum = 0;
PhysicsActor linkPartPa = linkPart.PhysActor;
// Remove the SOP from the physical scene.
// If the new SOG is physical, it is re-created later.
// (There is a problem here in that we have not yet told the physics
// engine about the delink. Someday, linksets should be made first
// class objects in the physics engine interface).
if (linkPartPa != null)
{
m_scene.PhysicsScene.RemovePrim(linkPartPa);
linkPart.PhysActor = null;
}
linkPart.setGroupPosition(worldPos);
linkPart.setOffsetPosition(Vector3.Zero);
linkPart.setRotationOffset(worldRot);
// Create a new SOG to go around this unlinked and unattached SOP
SceneObjectGroup objectGroup = new SceneObjectGroup(linkPart);
m_scene.AddNewSceneObject(objectGroup, true);
linkPart.Rezzed = RootPart.Rezzed;
// this is as it seems to be in sl now
if(linkPart.PhysicsShapeType == (byte)PhysShapeType.none)
linkPart.PhysicsShapeType = linkPart.DefaultPhysicsShapeType(); // root prims can't have type none for now
objectGroup.HasGroupChangedDueToDelink = true;
if (sendEvents)
linkPart.TriggerScriptChangedEvent(Changed.LINK);
}
if(unlinkroot)
{
//TODO
}
lock (m_parts.SyncRoot)
{
SceneObjectPart[] parts = m_parts.GetArray();
if (parts.Length == 1)
{
// Single prim left
m_rootPart.LinkNum = 0;
}
else
{
m_rootPart.LinkNum = 1;
int linknum = 2;
for (int i = 1; i < parts.Length; i++)
parts[i].LinkNum = linknum++;
}
}
InvalidBoundsRadius();
if (m_rootPart.PhysActor != null)
m_rootPart.PhysActor.Building = false;
// When we delete a group, we currently have to force persist to the database if the object id has changed
// (since delete works by deleting all rows which have a given object id)
Scene.SimulationDataService.RemoveObject(UUID, Scene.RegionInfo.RegionID);
HasGroupChangedDueToDelink = true;
TriggerScriptChangedEvent(Changed.LINK);
return;
}
*/
/// <summary> /// <summary>
/// Stop this object from being persisted over server restarts. /// Stop this object from being persisted over server restarts.
/// </summary> /// </summary>

View File

@ -281,7 +281,9 @@ namespace OpenSim.Region.Framework.Scenes
private bool m_followCamAuto = false; private bool m_followCamAuto = false;
private Vector3? m_forceToApply; // private object m_forceToApplyLock = new object();
// private bool m_forceToApplyValid;
// private Vector3 m_forceToApply;
private int m_userFlags; private int m_userFlags;
public int UserFlags public int UserFlags
{ {
@ -582,11 +584,11 @@ namespace OpenSim.Region.Framework.Scenes
{ {
get get
{ {
return m_drawDistance; return m_drawDistance;
} }
set set
{ {
m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance); m_drawDistance = Util.Clamp(value, 32f, m_scene.MaxDrawDistance);
} }
} }
@ -594,7 +596,7 @@ namespace OpenSim.Region.Framework.Scenes
{ {
get get
{ {
return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance); return Util.Clamp(m_drawDistance, 32f, m_scene.MaxRegionViewDistance);
} }
} }
@ -2120,6 +2122,7 @@ namespace OpenSim.Region.Framework.Scenes
if (haveAnims) if (haveAnims)
SendAnimPackToAgent(this, animIDs, animseqs, animsobjs); SendAnimPackToAgent(this, animIDs, animseqs, animsobjs);
// we should be able to receive updates, etc // we should be able to receive updates, etc
// so release them // so release them
m_inTransit = false; m_inTransit = false;
@ -2238,6 +2241,9 @@ namespace OpenSim.Region.Framework.Scenes
} }
finally finally
{ {
haveGroupInformation = false;
gotCrossUpdate = false;
crossingFlags = 0;
m_inTransit = false; m_inTransit = false;
} }
// if hide force a check // if hide force a check
@ -2247,9 +2253,6 @@ namespace OpenSim.Region.Framework.Scenes
// m_currentParcelHide = newhide; // m_currentParcelHide = newhide;
// } // }
haveGroupInformation = false;
gotCrossUpdate = false;
crossingFlags = 0;
m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd; m_scene.EventManager.OnRegionHeartbeatEnd += RegionHeartbeatEnd;
@ -3006,7 +3009,8 @@ namespace OpenSim.Region.Framework.Scenes
MovingToTarget = false; MovingToTarget = false;
// MoveToPositionTarget = Vector3.Zero; // MoveToPositionTarget = Vector3.Zero;
m_forceToApply = null; // cancel possible last action // lock(m_forceToApplyLock)
// m_forceToApplyValid = false; // cancel possible last action
// We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct // We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
// resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag. // resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
@ -3638,8 +3642,14 @@ namespace OpenSim.Region.Framework.Scenes
} }
// m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name); // m_log.DebugFormat("[SCENE PRESENCE]: Setting force to apply to {0} for {1}", direc, Name);
/*
m_forceToApply = direc; lock(m_forceToApplyLock)
{
m_forceToApply = direc;
m_forceToApplyValid = true;
}
*/
Velocity = direc;
Animator.UpdateMovementAnimations(); Animator.UpdateMovementAnimations();
} }
@ -4734,17 +4744,21 @@ namespace OpenSim.Region.Framework.Scenes
/// </summary> /// </summary>
public void UpdateMovement() public void UpdateMovement()
{ {
/*
if (IsInTransit) if (IsInTransit)
return; return;
if (m_forceToApply.HasValue)
lock(m_forceToApplyLock)
{ {
Vector3 force = m_forceToApply.Value; if (m_forceToApplyValid)
{
Velocity = m_forceToApply;
Velocity = force; m_forceToApplyValid = false;
TriggerScenePresenceUpdated();
m_forceToApply = null; }
TriggerScenePresenceUpdated();
} }
*/
} }
/// <summary> /// <summary>
@ -4767,6 +4781,9 @@ namespace OpenSim.Region.Framework.Scenes
// Appearance.SetHeight(); // Appearance.SetHeight();
Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f)); Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
// lock(m_forceToApplyLock)
// m_forceToApplyValid = false;
PhysicsScene scene = m_scene.PhysicsScene; PhysicsScene scene = m_scene.PhysicsScene;
Vector3 pVec = AbsolutePosition; Vector3 pVec = AbsolutePosition;

View File

@ -178,8 +178,10 @@ namespace OpenSim.Region.Framework.Scenes
if (part.Shape.ProjectionTextureUUID != UUID.Zero) if (part.Shape.ProjectionTextureUUID != UUID.Zero)
GatheredUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture; GatheredUuids[part.Shape.ProjectionTextureUUID] = (sbyte)AssetType.Texture;
if (part.CollisionSound != UUID.Zero) UUID collisionSound = part.CollisionSound;
GatheredUuids[part.CollisionSound] = (sbyte)AssetType.Sound; if ( collisionSound != UUID.Zero &&
collisionSound != part.invalidCollisionSoundUUID)
GatheredUuids[collisionSound] = (sbyte)AssetType.Sound;
if (part.ParticleSystem.Length > 0) if (part.ParticleSystem.Length > 0)
{ {

View File

@ -1023,12 +1023,12 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
} }
public void SendWindData(Vector2[] windSpeeds) public void SendWindData(int version, Vector2[] windSpeeds)
{ {
} }
public void SendCloudData(float[] cloudCover) public void SendCloudData(int version, float[] cloudCover)
{ {
} }

View File

@ -724,9 +724,9 @@ namespace OpenSim.Region.OptionalModules.World.NPC
{ {
} }
public virtual void SendWindData(Vector2[] windSpeeds) { } public virtual void SendWindData(int version, Vector2[] windSpeeds) { }
public virtual void SendCloudData(float[] cloudCover) { } public virtual void SendCloudData(int version, float[] cloudCover) { }
public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
{ {

View File

@ -52,7 +52,6 @@ public sealed class BSCharacter : BSPhysObject
private bool _setAlwaysRun; private bool _setAlwaysRun;
private bool _throttleUpdates; private bool _throttleUpdates;
private bool _floatOnWater; private bool _floatOnWater;
private OMV.Vector3 _rotationalVelocity;
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
@ -291,7 +290,7 @@ public sealed class BSCharacter : BSPhysObject
{ {
RawVelocity = OMV.Vector3.Zero; RawVelocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; RawRotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties directly into the physics engine // Zero some other properties directly into the physics engine
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
@ -303,7 +302,7 @@ public sealed class BSCharacter : BSPhysObject
public override void ZeroAngularMotion(bool inTaintTime) public override void ZeroAngularMotion(bool inTaintTime)
{ {
_rotationalVelocity = OMV.Vector3.Zero; RawRotationalVelocity = OMV.Vector3.Zero;
PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate() PhysScene.TaintedObject(inTaintTime, LocalID, "BSCharacter.ZeroMotion", delegate()
{ {
@ -351,7 +350,6 @@ public sealed class BSCharacter : BSPhysObject
} }
} }
// Check that the current position is sane and, if not, modify the position to make it so. // Check that the current position is sane and, if not, modify the position to make it so.
// Check for being below terrain or on water. // Check for being below terrain or on water.
// Returns 'true' of the position was made sane by some action. // Returns 'true' of the position was made sane by some action.
@ -503,6 +501,17 @@ public sealed class BSCharacter : BSPhysObject
} }
} }
// SetMomentum just sets the velocity without a target. We need to stop the movement actor if a character.
public override void SetMomentum(OMV.Vector3 momentum)
{
if (m_moveActor != null)
{
m_moveActor.SetVelocityAndTarget(OMV.Vector3.Zero, OMV.Vector3.Zero, false /* inTaintTime */);
}
base.SetMomentum(momentum);
}
public override OMV.Vector3 Torque { public override OMV.Vector3 Torque {
get { return RawTorque; } get { return RawTorque; }
set { RawTorque = value; set { RawTorque = value;
@ -618,14 +627,6 @@ public sealed class BSCharacter : BSPhysObject
}); });
} }
} }
public override OMV.Vector3 RotationalVelocity {
get { return _rotationalVelocity; }
set { _rotationalVelocity = value; }
}
public override OMV.Vector3 ForceRotationalVelocity {
get { return _rotationalVelocity; }
set { _rotationalVelocity = value; }
}
public override bool Kinematic { public override bool Kinematic {
get { return _kinematic; } get { return _kinematic; }
set { _kinematic = value; } set { _kinematic = value; }
@ -716,8 +717,6 @@ public sealed class BSCharacter : BSPhysObject
public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force) { public override void AddAngularForce(bool inTaintTime, OMV.Vector3 force) {
} }
public override void SetMomentum(OMV.Vector3 momentum) {
}
// The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets // The avatar's physical shape (whether capsule or cube) is unit sized. BulletSim sets
// the scale of that unit shape to create the avatars full size. // the scale of that unit shape to create the avatars full size.
@ -841,7 +840,7 @@ public sealed class BSCharacter : BSPhysObject
RawVelocity = entprop.Velocity; RawVelocity = entprop.Velocity;
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity; RawRotationalVelocity = entprop.RotationalVelocity;
// Do some sanity checking for the avatar. Make sure it's above ground and inbounds. // Do some sanity checking for the avatar. Make sure it's above ground and inbounds.
if (PositionSanityCheck(true)) if (PositionSanityCheck(true))
@ -861,7 +860,7 @@ public sealed class BSCharacter : BSPhysObject
// PhysScene.PostUpdate(this); // PhysScene.PostUpdate(this);
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}", DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, _rotationalVelocity); LocalID, RawPosition, RawOrientation, RawVelocity, _acceleration, RawRotationalVelocity);
} }
} }
} }

View File

@ -239,6 +239,8 @@ public abstract class BSPhysObject : PhysicsActor
public virtual OMV.Vector3 RawVelocity { get; set; } public virtual OMV.Vector3 RawVelocity { get; set; }
public abstract OMV.Vector3 ForceVelocity { get; set; } public abstract OMV.Vector3 ForceVelocity { get; set; }
public OMV.Vector3 RawRotationalVelocity { get; set; }
// RawForce is a constant force applied to object (see Force { set; } ) // RawForce is a constant force applied to object (see Force { set; } )
public OMV.Vector3 RawForce { get; set; } public OMV.Vector3 RawForce { get; set; }
public OMV.Vector3 RawTorque { get; set; } public OMV.Vector3 RawTorque { get; set; }
@ -250,7 +252,48 @@ public abstract class BSPhysObject : PhysicsActor
public abstract void AddAngularForce(bool inTaintTime, OMV.Vector3 force); public abstract void AddAngularForce(bool inTaintTime, OMV.Vector3 force);
public abstract void AddForce(bool inTaintTime, OMV.Vector3 force); public abstract void AddForce(bool inTaintTime, OMV.Vector3 force);
public abstract OMV.Vector3 ForceRotationalVelocity { get; set; } // PhysicsActor.SetMomentum
// All the physics engined use this as a way of forcing the velocity to something.
public override void SetMomentum(OMV.Vector3 momentum)
{
// This doesn't just set Velocity=momentum because velocity is ramped up to (see MoveActor)
RawVelocity = momentum;
PhysScene.TaintedObject(LocalID, TypeName + ".SetMomentum", delegate()
{
// DetailLog("{0},BSPrim.SetMomentum,taint,vel={1}", LocalID, RawVelocity);
ForceVelocity = RawVelocity;
});
}
public override OMV.Vector3 RotationalVelocity {
get {
return RawRotationalVelocity;
}
set {
RawRotationalVelocity = value;
Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
PhysScene.TaintedObject(LocalID, TypeName + ".setRotationalVelocity", delegate()
{
ForceRotationalVelocity = RawRotationalVelocity;
});
}
}
public OMV.Vector3 ForceRotationalVelocity {
get {
return RawRotationalVelocity;
}
set {
RawRotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
if (PhysBody.HasPhysicalBody)
{
DetailLog("{0},{1}.ForceRotationalVel,taint,rotvel={2}", LocalID, TypeName, RawRotationalVelocity);
PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
// PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
ActivateIfPhysical(false);
}
}
}
public abstract float ForceBuoyancy { get; set; } public abstract float ForceBuoyancy { get; set; }
@ -582,7 +625,7 @@ public abstract class BSPhysObject : PhysicsActor
{ {
CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS); CurrentCollisionFlags = PhysScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}", DetailLog("{0},{1}.SubscribeEvents,setting collision. ms={2}, collisionFlags={3:x}",
LocalID, TypeName, ms, CurrentCollisionFlags); LocalID, TypeName, SubscribedEventsMs, CurrentCollisionFlags);
} }
}); });
} }

View File

@ -59,7 +59,6 @@ public class BSPrim : BSPhysObject
private bool _setAlwaysRun; private bool _setAlwaysRun;
private bool _throttleUpdates; private bool _throttleUpdates;
private bool _floatOnWater; private bool _floatOnWater;
private OMV.Vector3 _rotationalVelocity;
private bool _kinematic; private bool _kinematic;
private float _buoyancy; private float _buoyancy;
@ -90,7 +89,7 @@ public class BSPrim : BSPhysObject
RawOrientation = rotation; RawOrientation = rotation;
_buoyancy = 0f; _buoyancy = 0f;
RawVelocity = OMV.Vector3.Zero; RawVelocity = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; RawRotationalVelocity = OMV.Vector3.Zero;
BaseShape = pbs; BaseShape = pbs;
_isPhysical = pisPhysical; _isPhysical = pisPhysical;
_isVolumeDetect = false; _isVolumeDetect = false;
@ -256,7 +255,7 @@ public class BSPrim : BSPhysObject
{ {
RawVelocity = OMV.Vector3.Zero; RawVelocity = OMV.Vector3.Zero;
_acceleration = OMV.Vector3.Zero; _acceleration = OMV.Vector3.Zero;
_rotationalVelocity = OMV.Vector3.Zero; RawRotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties in the physics engine // Zero some other properties in the physics engine
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
@ -267,15 +266,15 @@ public class BSPrim : BSPhysObject
} }
public override void ZeroAngularMotion(bool inTaintTime) public override void ZeroAngularMotion(bool inTaintTime)
{ {
_rotationalVelocity = OMV.Vector3.Zero; RawRotationalVelocity = OMV.Vector3.Zero;
// Zero some other properties in the physics engine // Zero some other properties in the physics engine
PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate() PhysScene.TaintedObject(inTaintTime, LocalID, "BSPrim.ZeroMotion", delegate()
{ {
// DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity); // DetailLog("{0},BSPrim.ZeroAngularMotion,call,rotVel={1}", LocalID, _rotationalVelocity);
if (PhysBody.HasPhysicalBody) if (PhysBody.HasPhysicalBody)
{ {
PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity); PhysScene.PE.SetInterpolationAngularVelocity(PhysBody, RawRotationalVelocity);
PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity); PhysScene.PE.SetAngularVelocity(PhysBody, RawRotationalVelocity);
} }
}); });
} }
@ -426,9 +425,9 @@ public class BSPrim : BSPhysObject
RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity); RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
ret = true; ret = true;
} }
if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared) if (RawRotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
{ {
_rotationalVelocity = Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity); RawRotationalVelocity = Util.ClampV(RawRotationalVelocity, BSParam.MaxAngularVelocity);
ret = true; ret = true;
} }
@ -1008,7 +1007,7 @@ public class BSPrim : BSPhysObject
// For good measure, make sure the transform is set through to the motion state // For good measure, make sure the transform is set through to the motion state
ForcePosition = RawPosition; ForcePosition = RawPosition;
ForceVelocity = RawVelocity; ForceVelocity = RawVelocity;
ForceRotationalVelocity = _rotationalVelocity; ForceRotationalVelocity = RawRotationalVelocity;
// A dynamic object has mass // A dynamic object has mass
UpdatePhysicalMassProperties(RawMass, false); UpdatePhysicalMassProperties(RawMass, false);
@ -1128,35 +1127,6 @@ public class BSPrim : BSPhysObject
}); });
} }
} }
public override OMV.Vector3 RotationalVelocity {
get {
return _rotationalVelocity;
}
set {
_rotationalVelocity = value;
Util.ClampV(_rotationalVelocity, BSParam.MaxAngularVelocity);
// m_log.DebugFormat("{0}: RotationalVelocity={1}", LogHeader, _rotationalVelocity);
PhysScene.TaintedObject(LocalID, "BSPrim.setRotationalVelocity", delegate()
{
ForceRotationalVelocity = _rotationalVelocity;
});
}
}
public override OMV.Vector3 ForceRotationalVelocity {
get {
return _rotationalVelocity;
}
set {
_rotationalVelocity = Util.ClampV(value, BSParam.MaxAngularVelocity);
if (PhysBody.HasPhysicalBody)
{
DetailLog("{0},BSPrim.ForceRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
PhysScene.PE.SetAngularVelocity(PhysBody, _rotationalVelocity);
// PhysicsScene.PE.SetInterpolationAngularVelocity(PhysBody, _rotationalVelocity);
ActivateIfPhysical(false);
}
}
}
public override bool Kinematic { public override bool Kinematic {
get { return _kinematic; } get { return _kinematic; }
set { _kinematic = value; set { _kinematic = value;
@ -1358,9 +1328,6 @@ public class BSPrim : BSPhysObject
}); });
} }
public override void SetMomentum(OMV.Vector3 momentum) {
// DetailLog("{0},BSPrim.SetMomentum,call,mom={1}", LocalID, momentum);
}
#region Mass Calculation #region Mass Calculation
private float CalculateMass() private float CalculateMass()
@ -1930,7 +1897,7 @@ public class BSPrim : BSPhysObject
if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold)) if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
RawVelocity = entprop.Velocity; RawVelocity = entprop.Velocity;
_acceleration = entprop.Acceleration; _acceleration = entprop.Acceleration;
_rotationalVelocity = entprop.RotationalVelocity; RawRotationalVelocity = entprop.RotationalVelocity;
// DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG // DetailLog("{0},BSPrim.UpdateProperties,afterAssign,entprop={1}", LocalID, entprop); // DEBUG DEBUG
@ -1939,7 +1906,7 @@ public class BSPrim : BSPhysObject
{ {
entprop.Position = RawPosition; entprop.Position = RawPosition;
entprop.Velocity = RawVelocity; entprop.Velocity = RawVelocity;
entprop.RotationalVelocity = _rotationalVelocity; entprop.RotationalVelocity = RawRotationalVelocity;
entprop.Acceleration = _acceleration; entprop.Acceleration = _acceleration;
} }

View File

@ -2664,13 +2664,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
private LSL_Key NpcCreate( private LSL_Key NpcCreate(
string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent, bool hostGroupID) string firstname, string lastname, LSL_Vector position, string notecard, bool owned, bool senseAsAgent, bool hostGroupID)
{ {
if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z))) if (!World.Permissions.CanRezObject(1, m_host.OwnerID, new Vector3((float)position.x, (float)position.y, (float)position.z)))
{
OSSLError("no permission to rez NPC at requested location");
return new LSL_Key(UUID.Zero.ToString()); return new LSL_Key(UUID.Zero.ToString());
}
INPCModule module = World.RequestModuleInterface<INPCModule>(); INPCModule module = World.RequestModuleInterface<INPCModule>();
if(module == null) if(module == null)
new LSL_Key(UUID.Zero.ToString()); {
OSSLError("NPC module not enabled");
return new LSL_Key(UUID.Zero.ToString());
}
string groupTitle = String.Empty; string groupTitle = String.Empty;
UUID groupID = UUID.Zero; UUID groupID = UUID.Zero;
@ -3878,11 +3883,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
m_host.AddScriptLPS(1); m_host.AddScriptLPS(1);
UUID targetUUID; UUID targetUUID;
if(!UUID.TryParse(avatar.ToString(), out targetUUID))
return;
if(targetUUID == UUID.Zero)
return;
ScenePresence target; ScenePresence target;
if(!World.TryGetScenePresence(targetUUID, out target))
return;
if (attachmentPoints.Length >= 1 && UUID.TryParse(avatar.ToString(), out targetUUID) && World.TryGetScenePresence(targetUUID, out target)) if(target.IsDeleted || target.IsInTransit)
return;
List<int> aps = new List<int>();
if(attachmentPoints.Length != 0)
{ {
List<int> aps = new List<int>();
foreach (object point in attachmentPoints.Data) foreach (object point in attachmentPoints.Data)
{ {
int ipoint; int ipoint;
@ -3891,115 +3907,76 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
aps.Add(ipoint); aps.Add(ipoint);
} }
} }
// parsing failed
List<SceneObjectGroup> attachments = new List<SceneObjectGroup>(); if(aps.Count != attachmentPoints.Length)
bool msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
if (msgAll && invertPoints)
{
return; return;
} }
else if (msgAll || invertPoints)
{
attachments = target.GetAttachments();
}
else
{
foreach (int point in aps)
{
if (point > 0)
{
attachments.AddRange(target.GetAttachments((uint)point));
}
}
}
// if we have no attachments at this point, exit now List<SceneObjectGroup> attachments = new List<SceneObjectGroup>();
if (attachments.Count == 0)
{ bool msgAll;
bool invertPoints = (options & ScriptBaseClass.OS_ATTACH_MSG_INVERT_POINTS) != 0;
if(aps.Count == 0)
{
if(!invertPoints)
return; return;
} msgAll = true;
invertPoints = false;
}
else
msgAll = aps.Contains(ScriptBaseClass.OS_ATTACH_MSG_ALL);
List<SceneObjectGroup> ignoreThese = new List<SceneObjectGroup>(); if (msgAll && invertPoints)
return;
if (invertPoints) if (msgAll || invertPoints)
{
attachments = target.GetAttachments();
}
else
{
foreach (int point in aps)
{ {
foreach (SceneObjectGroup attachment in attachments) if (point > 0)
{ {
if (aps.Contains((int)attachment.AttachmentPoint)) attachments.AddRange(target.GetAttachments((uint)point));
{
ignoreThese.Add(attachment);
}
} }
} }
}
foreach (SceneObjectGroup attachment in ignoreThese) // if we have no attachments at this point, exit now
{ if (attachments.Count == 0)
attachments.Remove(attachment); {
} return;
ignoreThese.Clear(); }
// if inverting removed all attachments to check, exit now bool optionObjCreator = (options &
if (attachments.Count < 1) ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0;
{ bool optionScriptCreator = (options &
return; ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0;
}
if ((options & ScriptBaseClass.OS_ATTACH_MSG_OBJECT_CREATOR) != 0) UUID hostCreatorID = m_host.CreatorID;
{ UUID itemCreatorID = m_item.CreatorID;
foreach (SceneObjectGroup attachment in attachments)
{
if (attachment.RootPart.CreatorID != m_host.CreatorID)
{
ignoreThese.Add(attachment);
}
}
foreach (SceneObjectGroup attachment in ignoreThese) foreach (SceneObjectGroup sog in attachments)
{ {
attachments.Remove(attachment); if(sog.IsDeleted || sog.inTransit)
} continue;
ignoreThese.Clear();
// if filtering by same object creator removed all if (invertPoints && aps.Contains((int)sog.AttachmentPoint))
// attachments to check, exit now continue;
if (attachments.Count == 0)
{
return;
}
}
if ((options & ScriptBaseClass.OS_ATTACH_MSG_SCRIPT_CREATOR) != 0) UUID CreatorID = sog.RootPart.CreatorID;
{ if (optionObjCreator && CreatorID != hostCreatorID)
foreach (SceneObjectGroup attachment in attachments) continue;
{
if (attachment.RootPart.CreatorID != m_item.CreatorID)
{
ignoreThese.Add(attachment);
}
}
foreach (SceneObjectGroup attachment in ignoreThese) if (optionScriptCreator && CreatorID != itemCreatorID)
{ continue;
attachments.Remove(attachment);
}
ignoreThese.Clear();
// if filtering by object creator must match originating SceneObjectPart[] parts = sog.Parts;
// script creator removed all attachments to check, foreach(SceneObjectPart p in parts)
// exit now MessageObject(p.UUID, message);
if (attachments.Count == 0)
{
return;
}
}
foreach (SceneObjectGroup attachment in attachments)
{
MessageObject(attachment.RootPart.UUID, message);
}
} }
} }

View File

@ -659,9 +659,9 @@ namespace OpenSim.Tests.Common
{ {
} }
public virtual void SendWindData(Vector2[] windSpeeds) { } public virtual void SendWindData(int version, Vector2[] windSpeeds) { }
public virtual void SendCloudData(float[] cloudCover) { } public virtual void SendCloudData(int version, float[] cloudCover) { }
public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look) public virtual void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
{ {

View File

@ -293,7 +293,7 @@
;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before. ;; OpenDynamicsEngine was the previous default physics engine in OpenSimulator 0.7.6.1 and before.
;; It continues to provide a workable physics implementation. It does not currently support varregions. ;; It continues to provide a workable physics implementation. It does not currently support varregions.
;; basicphysics effectively does not model physics at all, making all objects phantom. ;; basicphysics effectively does not model physics at all, making all objects phantom.
;; Default is OpenDynamicsEngine ;; Default is BulletSim
physics = BulletSim physics = BulletSim
;physics = modified_BulletX ;physics = modified_BulletX
;physics = OpenDynamicsEngine ;physics = OpenDynamicsEngine