Merge branch 'avination' of careminster:/var/git/careminster into teravuswork

avinationmerge
teravus 2012-12-19 11:53:26 -05:00
commit c648325d7c
27 changed files with 1311 additions and 710 deletions

View File

@ -2028,7 +2028,7 @@ namespace OpenSim.Data.MySQL
using (MySqlCommand cmd = dbcon.CreateCommand()) using (MySqlCommand cmd = dbcon.CreateCommand())
{ {
cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID"; cmd.CommandText = "select UUID from prims where RegionUUID = ?RegionUUID and SceneGroupID = UUID";
cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString()); cmd.Parameters.AddWithValue("RegionUUID", regionID.ToString());
using (IDataReader reader = ExecuteReader(cmd)) using (IDataReader reader = ExecuteReader(cmd))

View File

@ -40,6 +40,13 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public class AvatarAppearance public class AvatarAppearance
{ {
// SL box diferent to size
const float AVBOXAJUST = 0.2f;
// constrains for ubitode physics
const float AVBOXMINX = 0.2f;
const float AVBOXMINY = 0.3f;
const float AVBOXMINZ = 1.2f;
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
// this is viewer capabilities and weared things dependent // this is viewer capabilities and weared things dependent
@ -55,6 +62,10 @@ namespace OpenSim.Framework
protected AvatarWearable[] m_wearables; protected AvatarWearable[] m_wearables;
protected Dictionary<int, List<AvatarAttachment>> m_attachments; protected Dictionary<int, List<AvatarAttachment>> m_attachments;
protected float m_avatarHeight = 0; protected float m_avatarHeight = 0;
protected Vector3 m_avatarSize = new Vector3(0.45f, 0.6f, 1.9f); // sl Z cloud value
protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
protected float m_avatarFeetOffset = 0;
protected float m_avatarAnimOffset = 0;
public virtual int Serial public virtual int Serial
{ {
@ -68,6 +79,21 @@ namespace OpenSim.Framework
set { m_visualparams = value; } set { m_visualparams = value; }
} }
public virtual Vector3 AvatarSize
{
get { return m_avatarSize; }
}
public virtual Vector3 AvatarBoxSize
{
get { return m_avatarBoxSize; }
}
public virtual float AvatarFeetOffset
{
get { return m_avatarFeetOffset + m_avatarAnimOffset; }
}
public virtual Primitive.TextureEntry Texture public virtual Primitive.TextureEntry Texture
{ {
get { return m_texture; } get { return m_texture; }
@ -98,7 +124,8 @@ namespace OpenSim.Framework
SetDefaultWearables(); SetDefaultWearables();
SetDefaultTexture(); SetDefaultTexture();
SetDefaultParams(); SetDefaultParams();
SetHeight(); // SetHeight();
SetSize(new Vector3(0.45f,0.6f,1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
} }
@ -107,7 +134,7 @@ namespace OpenSim.Framework
// m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap"); // m_log.WarnFormat("[AVATAR APPEARANCE]: create appearance from OSDMap");
Unpack(map); Unpack(map);
SetHeight(); // SetHeight(); done in Unpack
} }
public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams) public AvatarAppearance(AvatarWearable[] wearables, Primitive.TextureEntry textureEntry, byte[] visualParams)
@ -131,7 +158,9 @@ namespace OpenSim.Framework
else else
SetDefaultParams(); SetDefaultParams();
SetHeight(); // SetHeight();
if(m_avatarHeight == 0)
SetSize(new Vector3(0.45f,0.6f,1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
} }
@ -150,7 +179,8 @@ namespace OpenSim.Framework
SetDefaultWearables(); SetDefaultWearables();
SetDefaultTexture(); SetDefaultTexture();
SetDefaultParams(); SetDefaultParams();
SetHeight(); // SetHeight();
SetSize(new Vector3(0.45f, 0.6f, 1.9f));
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
return; return;
@ -179,7 +209,8 @@ namespace OpenSim.Framework
if (appearance.VisualParams != null) if (appearance.VisualParams != null)
m_visualparams = (byte[])appearance.VisualParams.Clone(); m_visualparams = (byte[])appearance.VisualParams.Clone();
m_avatarHeight = appearance.m_avatarHeight; // m_avatarHeight = appearance.m_avatarHeight;
SetSize(appearance.AvatarSize);
// Copy the attachment, force append mode since that ensures consistency // Copy the attachment, force append mode since that ensures consistency
m_attachments = new Dictionary<int, List<AvatarAttachment>>(); m_attachments = new Dictionary<int, List<AvatarAttachment>>();
@ -346,8 +377,8 @@ namespace OpenSim.Framework
} }
} }
// Reset the height if the visual parameters actually changed // Reset the height if the visual parameters actually changed
if (changed) // if (changed)
SetHeight(); // SetHeight();
return changed; return changed;
} }
@ -363,6 +394,7 @@ namespace OpenSim.Framework
/// </summary> /// </summary>
public virtual void SetHeight() public virtual void SetHeight()
{ {
/*
// Start with shortest possible female avatar height // Start with shortest possible female avatar height
m_avatarHeight = 1.14597f; m_avatarHeight = 1.14597f;
// Add offset for male avatars // Add offset for male avatars
@ -375,6 +407,35 @@ namespace OpenSim.Framework
+ 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f + 0.07f * (float)m_visualparams[(int)VPElement.SHOES_PLATFORM_HEIGHT] / 255.0f
+ 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f + 0.08f * (float)m_visualparams[(int)VPElement.SHOES_HEEL_HEIGHT] / 255.0f
+ 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f; + 0.076f * (float)m_visualparams[(int)VPElement.SHAPE_NECK_LENGTH] / 255.0f;
*/
}
public void SetSize(Vector3 avSize)
{
if (avSize.X > 32f)
avSize.X = 32f;
else if (avSize.X < 0.1f)
avSize.X = 0.1f;
if (avSize.Y > 32f)
avSize.Y = 32f;
else if (avSize.Y < 0.1f)
avSize.Y = 0.1f;
if (avSize.Z > 32f)
avSize.Z = 32f;
else if (avSize.Z < 0.1f)
avSize.Z = 0.1f;
m_avatarSize = avSize;
m_avatarBoxSize = avSize;
m_avatarBoxSize.Z += AVBOXAJUST;
if (m_avatarBoxSize.X < AVBOXMINX)
m_avatarBoxSize.X = AVBOXMINX;
if (m_avatarBoxSize.Y < AVBOXMINY)
m_avatarBoxSize.Y = AVBOXMINY;
if (m_avatarBoxSize.Z < AVBOXMINZ)
m_avatarBoxSize.Z = AVBOXMINZ;
m_avatarHeight = m_avatarSize.Z;
} }
public virtual void SetWearable(int wearableId, AvatarWearable wearable) public virtual void SetWearable(int wearableId, AvatarWearable wearable)
@ -649,7 +710,8 @@ namespace OpenSim.Framework
if ((data != null) && (data["serial"] != null)) if ((data != null) && (data["serial"] != null))
m_serial = data["serial"].AsInteger(); m_serial = data["serial"].AsInteger();
if ((data != null) && (data["height"] != null)) if ((data != null) && (data["height"] != null))
m_avatarHeight = (float)data["height"].AsReal(); // m_avatarHeight = (float)data["height"].AsReal();
SetSize(new Vector3(0.45f,0.6f, (float)data["height"].AsReal()));
try try
{ {

View File

@ -64,7 +64,7 @@ namespace OpenSim.Framework
public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes); public delegate void NetworkStats(int inPackets, int outPackets, int unAckedBytes);
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams); public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize);
public delegate void StartAnim(IClientAPI remoteClient, UUID animID); public delegate void StartAnim(IClientAPI remoteClient, UUID animID);

View File

@ -33,6 +33,7 @@ namespace OpenSim.Framework
{ {
void Cache(AssetBase asset); void Cache(AssetBase asset);
AssetBase Get(string id); AssetBase Get(string id);
bool Check(string id);
void Expire(string id); void Expire(string id);
void Clear(); void Clear();
} }

View File

@ -377,7 +377,7 @@ namespace OpenSim.Region.ClientStack.Linden
protocol = "https"; protocol = "https";
} }
caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); caps.RegisterHandler("GetMesh", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
m_pollservices.Add(agentID, args); m_pollservices[agentID] = args;
m_capsDict[agentID] = capUrl; m_capsDict[agentID] = capUrl;

View File

@ -333,7 +333,7 @@ namespace OpenSim.Region.ClientStack.Linden
protocol = "https"; protocol = "https";
} }
caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl)); caps.RegisterHandler("GetTexture", String.Format("{0}://{1}:{2}{3}", protocol, hostName, port, capUrl));
m_pollservices.Add(agentID, args); m_pollservices[agentID] = args;
m_capsDict[agentID] = capUrl; m_capsDict[agentID] = capUrl;
} }

View File

@ -331,6 +331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private Prioritizer m_prioritizer; private Prioritizer m_prioritizer;
private bool m_disableFacelights = false; private bool m_disableFacelights = false;
private bool m_VelocityInterpolate = false;
private const uint MaxTransferBytesPerPacket = 600; private const uint MaxTransferBytesPerPacket = 600;
@ -5137,7 +5138,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
update.PCode = (byte)PCode.Avatar; update.PCode = (byte)PCode.Avatar;
update.ProfileCurve = 1; update.ProfileCurve = 1;
update.PSBlock = Utils.EmptyBytes; update.PSBlock = Utils.EmptyBytes;
update.Scale = new Vector3(0.45f, 0.6f, 1.9f); update.Scale = data.Appearance.AvatarSize;
// update.Scale.Z -= 0.2f;
update.Text = Utils.EmptyBytes; update.Text = Utils.EmptyBytes;
update.TextColor = new byte[4]; update.TextColor = new byte[4];
@ -5327,6 +5330,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false); AddLocalPacketHandler(PacketType.AgentUpdate, HandleAgentUpdate, false);
AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false); AddLocalPacketHandler(PacketType.ViewerEffect, HandleViewerEffect, false);
AddLocalPacketHandler(PacketType.VelocityInterpolateOff, HandleVelocityInterpolateOff, false);
AddLocalPacketHandler(PacketType.VelocityInterpolateOn, HandleVelocityInterpolateOn, false);
AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false); AddLocalPacketHandler(PacketType.AgentCachedTexture, HandleAgentTextureCached, false);
AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false); AddLocalPacketHandler(PacketType.MultipleObjectUpdate, HandleMultipleObjUpdate, false);
AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false); AddLocalPacketHandler(PacketType.MoneyTransferRequest, HandleMoneyTransferRequest, false);
@ -5844,6 +5849,29 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return true; return true;
} }
private bool HandleVelocityInterpolateOff(IClientAPI sender, Packet Pack)
{
VelocityInterpolateOffPacket p = (VelocityInterpolateOffPacket)Pack;
if (p.AgentData.SessionID != SessionId ||
p.AgentData.AgentID != AgentId)
return true;
m_VelocityInterpolate = false;
return true;
}
private bool HandleVelocityInterpolateOn(IClientAPI sender, Packet Pack)
{
VelocityInterpolateOnPacket p = (VelocityInterpolateOnPacket)Pack;
if (p.AgentData.SessionID != SessionId ||
p.AgentData.AgentID != AgentId)
return true;
m_VelocityInterpolate = true;
return true;
}
private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack) private bool HandleAvatarPropertiesRequest(IClientAPI sender, Packet Pack)
{ {
AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack; AvatarPropertiesRequestPacket avatarProperties = (AvatarPropertiesRequestPacket)Pack;
@ -6264,6 +6292,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Temporarily protect ourselves from the mantis #951 failure. // Temporarily protect ourselves from the mantis #951 failure.
// However, we could do this for several other handlers where a failure isn't terminal // However, we could do this for several other handlers where a failure isn't terminal
// for the client session anyway, in order to protect ourselves against bad code in plugins // for the client session anyway, in order to protect ourselves against bad code in plugins
Vector3 avSize = appear.AgentData.Size;
try try
{ {
byte[] visualparams = new byte[appear.VisualParam.Length]; byte[] visualparams = new byte[appear.VisualParam.Length];
@ -6274,7 +6303,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (appear.ObjectData.TextureEntry.Length > 1) if (appear.ObjectData.TextureEntry.Length > 1)
te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length); te = new Primitive.TextureEntry(appear.ObjectData.TextureEntry, 0, appear.ObjectData.TextureEntry.Length);
handlerSetAppearance(sender, te, visualparams); handlerSetAppearance(sender, te, visualparams,avSize);
} }
catch (Exception e) catch (Exception e)
{ {
@ -11684,6 +11713,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
cachedresp.WearableData = cachedresp.WearableData =
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length]; new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
if (cache == null)
{
for (int i = 0; i < cachedtex.WearableData.Length; i++) for (int i = 0; i < cachedtex.WearableData.Length; i++)
{ {
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock(); cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
@ -11691,7 +11723,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
cachedresp.WearableData[i].TextureID = UUID.Zero; cachedresp.WearableData[i].TextureID = UUID.Zero;
cachedresp.WearableData[i].HostName = new byte[0]; cachedresp.WearableData[i].HostName = new byte[0];
} }
}
else
{
for (int i = 0; i < cachedtex.WearableData.Length; i++)
{
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
if(cache.Check(cachedtex.WearableData[i].ID.ToString()))
cachedresp.WearableData[i].TextureID = UUID.Zero;
else
cachedresp.WearableData[i].TextureID = UUID.Zero;
cachedresp.WearableData[i].HostName = new byte[0];
}
}
cachedresp.Header.Zerocoded = true; cachedresp.Header.Zerocoded = true;
OutPacket(cachedresp, ThrottleOutPacketType.Task); OutPacket(cachedresp, ThrottleOutPacketType.Task);

View File

@ -194,6 +194,12 @@ namespace OpenSim.Region.CoreModules.Asset
#region IImprovedAssetCache Members #region IImprovedAssetCache Members
public bool Check(string id)
{
return false;
}
/// <summary> /// <summary>
/// Cache asset. /// Cache asset.
/// </summary> /// </summary>

View File

@ -112,6 +112,10 @@ namespace OpenSim.Region.CoreModules.Asset
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// IImprovedAssetCache // IImprovedAssetCache
// //
public bool Check(string id)
{
return false;
}
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
{ {

View File

@ -348,6 +348,17 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
private bool CheckFromMemoryCache(string id)
{
AssetBase asset = null;
if (m_MemoryCache.TryGetValue(id, out asset))
return true;
return false;
}
/// <summary> /// <summary>
/// Try to get an asset from the file cache. /// Try to get an asset from the file cache.
/// </summary> /// </summary>
@ -420,6 +431,50 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
private bool CheckFromFileCache(string id)
{
bool found = false;
string filename = GetFileName(id);
if (File.Exists(filename))
{
// actually check if we can open it, and so update expire
FileStream stream = null;
try
{
stream = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read);
if (stream != null)
{
found = true;
stream.Close();
}
}
catch (System.Runtime.Serialization.SerializationException e)
{
found = false;
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace);
// If there was a problem deserializing the asset, the asset may
// either be corrupted OR was serialized under an old format
// {different version of AssetBase} -- we should attempt to
// delete it and re-cache
File.Delete(filename);
}
catch (Exception e)
{
found = false;
m_log.ErrorFormat(
"[FLOTSAM ASSET CACHE]: Failed to check file {0} for asset {1}. Exception {2} {3}",
filename, id, e.Message, e.StackTrace);
}
}
return found;
}
public AssetBase Get(string id) public AssetBase Get(string id)
{ {
m_Requests++; m_Requests++;
@ -456,11 +511,26 @@ namespace OpenSim.Region.CoreModules.Asset
return asset; return asset;
} }
public bool Check(string id)
{
if (m_MemoryCacheEnabled && CheckFromMemoryCache(id))
return true;
if (m_FileCacheEnabled && CheckFromFileCache(id))
return true;
return false;
}
public AssetBase GetCached(string id) public AssetBase GetCached(string id)
{ {
return Get(id); return Get(id);
} }
public AssetBase CheckCached(string id)
{
return Get(id);
}
public void Expire(string id) public void Expire(string id)
{ {
if (m_LogLevel >= 2) if (m_LogLevel >= 2)
@ -941,6 +1011,11 @@ namespace OpenSim.Region.CoreModules.Asset
return asset.Data; return asset.Data;
} }
public bool CheckData(string id)
{
return Check(id); ;
}
public bool Get(string id, object sender, AssetRetrieved handler) public bool Get(string id, object sender, AssetRetrieved handler)
{ {
AssetBase asset = Get(id); AssetBase asset = Get(id);

View File

@ -115,6 +115,11 @@ namespace OpenSim.Region.CoreModules.Asset
// IImprovedAssetCache // IImprovedAssetCache
// //
public bool Check(string id)
{
return false;
}
public void Cache(AssetBase asset) public void Cache(AssetBase asset)
{ {
if (asset != null) if (asset != null)

View File

@ -145,6 +145,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
SetAppearance(sp, appearance.Texture, appearance.VisualParams); SetAppearance(sp, appearance.Texture, appearance.VisualParams);
} }
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize)
{
float oldoff = sp.Appearance.AvatarFeetOffset;
Vector3 oldbox = sp.Appearance.AvatarBoxSize;
SetAppearance(sp, textureEntry, visualParams);
sp.Appearance.SetSize(avSize);
float off = sp.Appearance.AvatarFeetOffset;
Vector3 box = sp.Appearance.AvatarBoxSize;
if (oldoff != off || oldbox != box)
((ScenePresence)sp).SetSize(box, off);
}
/// <summary> /// <summary>
/// Set appearance data (texture asset IDs and slider settings) /// Set appearance data (texture asset IDs and slider settings)
/// </summary> /// </summary>
@ -174,12 +189,21 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
// m_log.DebugFormat( // m_log.DebugFormat(
// "[AVFACTORY]: Setting visual params for {0} to {1}", // "[AVFACTORY]: Setting visual params for {0} to {1}",
// client.Name, string.Join(", ", visualParamsStrings)); // client.Name, string.Join(", ", visualParamsStrings));
/*
float oldHeight = sp.Appearance.AvatarHeight; float oldHeight = sp.Appearance.AvatarHeight;
changed = sp.Appearance.SetVisualParams(visualParams); changed = sp.Appearance.SetVisualParams(visualParams);
if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0)
((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight); ((ScenePresence)sp).SetHeight(sp.Appearance.AvatarHeight);
*/
// float oldoff = sp.Appearance.AvatarFeetOffset;
// Vector3 oldbox = sp.Appearance.AvatarBoxSize;
changed = sp.Appearance.SetVisualParams(visualParams);
// float off = sp.Appearance.AvatarFeetOffset;
// Vector3 box = sp.Appearance.AvatarBoxSize;
// if(oldoff != off || oldbox != box)
// ((ScenePresence)sp).SetSize(box,off);
} }
// Process the baked texture array // Process the baked texture array
@ -337,6 +361,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public bool ValidateBakedTextureCache(IScenePresence sp) public bool ValidateBakedTextureCache(IScenePresence sp)
{ {
bool defonly = true; // are we only using default textures bool defonly = true; // are we only using default textures
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
// Process the texture entry // Process the texture entry
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
@ -361,9 +386,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
defonly = false; // found a non-default texture reference defonly = false; // found a non-default texture reference
if (cache != null)
{
if (!cache.Check(face.TextureID.ToString()))
return false;
}
else
{
if (m_scene.AssetService.Get(face.TextureID.ToString()) == null) if (m_scene.AssetService.Get(face.TextureID.ToString()) == null)
return false; return false;
} }
}
// m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID); // m_log.DebugFormat("[AVFACTORY]: Completed texture check for {0} {1}", sp.Name, sp.UUID);
@ -374,6 +407,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
public int RequestRebake(IScenePresence sp, bool missingTexturesOnly) public int RequestRebake(IScenePresence sp, bool missingTexturesOnly)
{ {
int texturesRebaked = 0; int texturesRebaked = 0;
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++) for (int i = 0; i < AvatarAppearance.BAKE_INDICES.Length; i++)
{ {
@ -396,11 +430,25 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
continue; continue;
if (missingTexturesOnly) if (missingTexturesOnly)
{
if (cache != null)
{
if (cache.Check(face.TextureID.ToString()))
continue;
else
{
m_log.DebugFormat(
"[AVFACTORY]: Missing baked texture {0} ({1}) for {2}, requesting rebake.",
face.TextureID, idx, sp.Name);
}
}
else
{ {
if (m_scene.AssetService.Get(face.TextureID.ToString()) != null) if (m_scene.AssetService.Get(face.TextureID.ToString()) != null)
{ {
continue; continue;
} }
else else
{ {
// On inter-simulator teleports, this occurs if baked textures are not being stored by the // On inter-simulator teleports, this occurs if baked textures are not being stored by the
@ -414,6 +462,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
face.TextureID, idx, sp.Name); face.TextureID, idx, sp.Name);
} }
} }
}
else else
{ {
m_log.DebugFormat( m_log.DebugFormat(
@ -611,12 +660,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
/// <param name="client"></param> /// <param name="client"></param>
/// <param name="texture"></param> /// <param name="texture"></param>
/// <param name="visualParam"></param> /// <param name="visualParam"></param>
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams) private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize)
{ {
// m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId); // m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance called for {0} ({1})", client.Name, client.AgentId);
ScenePresence sp = m_scene.GetScenePresence(client.AgentId); ScenePresence sp = m_scene.GetScenePresence(client.AgentId);
if (sp != null) if (sp != null)
SetAppearance(sp, textureEntry, visualParams); SetAppearance(sp, textureEntry, visualParams,avSize);
else else
m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId); m_log.WarnFormat("[AVFACTORY]: Client_OnSetAppearance unable to find presence for {0}", client.AgentId);
} }

View File

@ -0,0 +1,19 @@
////////////////////////////////////////////////////////////////
//
// (c) 2009, 2010 Careminster Limited and Melanie Thielker
//
// All rights reserved
//
using System;
using Nini.Config;
using OpenSim.Framework;
using OpenMetaverse;
namespace OpenSim.Services.Interfaces
{
public interface IBakedTextureModule
{
AssetBase[] Get(UUID id);
void Store(UUID id, AssetBase[] data);
}
}

View File

@ -3449,7 +3449,9 @@ namespace OpenSim.Region.Framework.Scenes
part.ClonePermissions(RootPart); part.ClonePermissions(RootPart);
}); });
RootPart.OwnerMask = newOwnerMask | foldedPerms; uint lockMask = ~(uint)PermissionMask.Move;
uint lockBit = RootPart.OwnerMask & (uint)PermissionMask.Move;
RootPart.OwnerMask = (RootPart.OwnerMask & lockBit) | ((newOwnerMask | foldedPerms) & lockMask);
RootPart.ScheduleFullUpdate(); RootPart.ScheduleFullUpdate();
} }

View File

@ -140,6 +140,8 @@ namespace OpenSim.Region.Framework.Scenes
private Vector3 m_lastPosition; private Vector3 m_lastPosition;
private Quaternion m_lastRotation; private Quaternion m_lastRotation;
private Vector3 m_lastVelocity; private Vector3 m_lastVelocity;
private Vector3 m_lastSize = new Vector3(0.45f,0.6f,1.9f);
private Vector3? m_forceToApply; private Vector3? m_forceToApply;
private int m_userFlags; private int m_userFlags;
@ -562,7 +564,24 @@ namespace OpenSim.Region.Framework.Scenes
// Scene.RegionInfo.RegionName, Name, m_velocity); // Scene.RegionInfo.RegionName, Name, m_velocity);
} }
} }
/*
public override Vector3 AngularVelocity
{
get
{
if (PhysicsActor != null)
{
m_rotationalvelocity = PhysicsActor.RotationalVelocity;
// m_log.DebugFormat(
// "[SCENE PRESENCE]: Set velocity {0} for {1} in {2} via getting Velocity!",
// m_velocity, Name, Scene.RegionInfo.RegionName);
}
return m_rotationalvelocity;
}
}
*/
private Quaternion m_bodyRot = Quaternion.Identity; private Quaternion m_bodyRot = Quaternion.Identity;
public Quaternion Rotation public Quaternion Rotation
@ -1260,6 +1279,13 @@ namespace OpenSim.Region.Framework.Scenes
PhysicsActor.Size = new Vector3(0.45f, 0.6f, height); PhysicsActor.Size = new Vector3(0.45f, 0.6f, height);
} }
public void SetSize(Vector3 size, float feetoffset)
{
if (PhysicsActor != null && !IsChildAgent)
PhysicsActor.setAvatarSize(size, feetoffset);
}
/// <summary> /// <summary>
/// Complete Avatar's movement into the region. /// Complete Avatar's movement into the region.
/// </summary> /// </summary>
@ -2077,12 +2103,29 @@ namespace OpenSim.Region.Framework.Scenes
} }
else else
{ {
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) // if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
{ // {
// m_log.DebugFormat( // m_log.DebugFormat(
// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
// Name, part.Name, part.LocalId); // Name, part.Name, part.LocalId);
if (m_scene.PhysicsScene != null &&
part.PhysActor != null &&
Util.GetDistanceTo(AbsolutePosition, pos) <= 30)
{
Vector3 camdif = CameraPosition - part.AbsolutePosition;
camdif.Normalize();
// m_log.InfoFormat("sit {0} {1}", offset.ToString(), camdif.ToString());
if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
return;
}
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
{
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
canSit = true; canSit = true;
} }
@ -2170,197 +2213,54 @@ namespace OpenSim.Region.Framework.Scenes
SendSitResponse(targetID, offset, Quaternion.Identity); SendSitResponse(targetID, offset, Quaternion.Identity);
} }
/* public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
public void SitRayCastAvatarPosition(SceneObjectPart part)
{ {
Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
Vector3 StartRayCastPosition = AbsolutePosition;
Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionResponse);
}
public void SitRayCastAvatarPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal) if (status < 0)
{
SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
if (part != null)
{
if (hitYN)
{
if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
{
SitRaycastFindEdge(collisionPoint, normal);
m_log.DebugFormat("[SIT]: Raycast Avatar Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
}
else
{
SitRayCastAvatarPositionCameraZ(part);
}
}
else
{
SitRayCastAvatarPositionCameraZ(part);
}
}
else
{ {
ControllingClient.SendAlertMessage("Sit position no longer exists"); ControllingClient.SendAlertMessage("Sit position no longer exists");
m_requestedSitTargetUUID = UUID.Zero; return;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
} }
if (status == 0)
return;
SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
if (part == null || part.ParentGroup.IsAttachment)
{
return;
} }
public void SitRayCastAvatarPositionCameraZ(SceneObjectPart part) // m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
{
// Next, try to raycast from the camera Z position part.AddSittingAvatar(UUID);
Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
Vector3 StartRayCastPosition = AbsolutePosition; StartRayCastPosition.Z = CameraPosition.Z; Vector3 cameraAtOffset = part.GetCameraAtOffset();
Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition); Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition); bool forceMouselook = part.GetForceMouselook();
m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastAvatarPositionCameraZResponse);
ControllingClient.SendSitResponse(
part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
// assuming no autopilot in use
Velocity = Vector3.Zero;
RemoveFromPhysicalScene();
Rotation = Orientation;
m_pos = offset;
m_requestedSitTargetID = 0; // invalidate the viewer sit comand for now
part.ParentGroup.AddAvatar(UUID);
ParentPart = part;
ParentID = part.LocalId;
Animator.TrySetMovementAnimation("SIT");
SendAvatarDataToAllAgents();
} }
public void SitRayCastAvatarPositionCameraZResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
{
SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
if (part != null)
{
if (hitYN)
{
if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
{
SitRaycastFindEdge(collisionPoint, normal);
m_log.DebugFormat("[SIT]: Raycast Avatar Position + CameraZ succeeded at point: {0}, normal:{1}", collisionPoint, normal);
}
else
{
SitRayCastCameraPosition(part);
}
}
else
{
SitRayCastCameraPosition(part);
}
}
else
{
ControllingClient.SendAlertMessage("Sit position no longer exists");
m_requestedSitTargetUUID = UUID.Zero;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
}
}
public void SitRayCastCameraPosition(SceneObjectPart part)
{
// Next, try to raycast from the camera position
Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
Vector3 StartRayCastPosition = CameraPosition;
Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastCameraPositionResponse);
}
public void SitRayCastCameraPositionResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
{
SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
if (part != null)
{
if (hitYN)
{
if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
{
SitRaycastFindEdge(collisionPoint, normal);
m_log.DebugFormat("[SIT]: Raycast Camera Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
}
else
{
SitRayHorizontal(part);
}
}
else
{
SitRayHorizontal(part);
}
}
else
{
ControllingClient.SendAlertMessage("Sit position no longer exists");
m_requestedSitTargetUUID = UUID.Zero;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
}
}
public void SitRayHorizontal(SceneObjectPart part)
{
// Next, try to raycast from the avatar position to fwd
Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
Vector3 StartRayCastPosition = CameraPosition;
Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastHorizontalResponse);
}
public void SitRayCastHorizontalResponse(bool hitYN, Vector3 collisionPoint, uint localid, float pdistance, Vector3 normal)
{
SceneObjectPart part = FindNextAvailableSitTarget(m_requestedSitTargetUUID);
if (part != null)
{
if (hitYN)
{
if (collisionPoint.ApproxEquals(m_requestedSitOffset + part.AbsolutePosition, 0.2f))
{
SitRaycastFindEdge(collisionPoint, normal);
m_log.DebugFormat("[SIT]: Raycast Horizontal Position succeeded at point: {0}, normal:{1}", collisionPoint, normal);
// Next, try to raycast from the camera position
Vector3 EndRayCastPosition = part.AbsolutePosition + m_requestedSitOffset;
Vector3 StartRayCastPosition = CameraPosition;
Vector3 direction = Vector3.Normalize(EndRayCastPosition - StartRayCastPosition);
float distance = Vector3.Distance(EndRayCastPosition, StartRayCastPosition);
//m_scene.PhysicsScene.RaycastWorld(StartRayCastPosition, direction, distance, SitRayCastResponseAvatarPosition);
}
else
{
ControllingClient.SendAlertMessage("Sit position not accessable.");
m_requestedSitTargetUUID = UUID.Zero;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
}
}
else
{
ControllingClient.SendAlertMessage("Sit position not accessable.");
m_requestedSitTargetUUID = UUID.Zero;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
}
}
else
{
ControllingClient.SendAlertMessage("Sit position no longer exists");
m_requestedSitTargetUUID = UUID.Zero;
m_requestedSitTargetID = 0;
m_requestedSitOffset = Vector3.Zero;
}
}
private void SitRaycastFindEdge(Vector3 collisionPoint, Vector3 collisionNormal)
{
int i = 0;
//throw new NotImplementedException();
//m_requestedSitTargetUUID = UUID.Zero;
//m_requestedSitTargetID = 0;
//m_requestedSitOffset = Vector3.Zero;
SendSitResponse(ControllingClient, m_requestedSitTargetUUID, collisionPoint - m_requestedSitOffset, Quaternion.Identity);
}
*/
public void HandleAgentSit(IClientAPI remoteClient, UUID agentID) public void HandleAgentSit(IClientAPI remoteClient, UUID agentID)
{ {
@ -2566,9 +2466,13 @@ namespace OpenSim.Region.Framework.Scenes
// NOTE: Velocity is not the same as m_velocity. Velocity will attempt to // NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
// grab the latest PhysicsActor velocity, whereas m_velocity is often // grab the latest PhysicsActor velocity, whereas m_velocity is often
// storing a requested force instead of an actual traveling velocity // storing a requested force instead of an actual traveling velocity
if (Appearance.AvatarSize != m_lastSize)
{
m_lastSize = Appearance.AvatarSize;
SendAvatarDataToAllAgents();
}
// Throw away duplicate or insignificant updates else if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) || !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)) !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
{ {
@ -2866,6 +2770,8 @@ namespace OpenSim.Region.Framework.Scenes
avatar.ControllingClient.SendAppearance( avatar.ControllingClient.SendAppearance(
UUID, Appearance.VisualParams, Appearance.Texture.GetBytes()); UUID, Appearance.VisualParams, Appearance.Texture.GetBytes());
} }
#endregion #endregion
@ -3438,15 +3344,22 @@ namespace OpenSim.Region.Framework.Scenes
} }
if (Appearance.AvatarHeight == 0) if (Appearance.AvatarHeight == 0)
Appearance.SetHeight(); // Appearance.SetHeight();
Appearance.SetSize(new Vector3(0.45f,0.6f,1.9f));
PhysicsScene scene = m_scene.PhysicsScene; PhysicsScene scene = m_scene.PhysicsScene;
Vector3 pVec = AbsolutePosition; Vector3 pVec = AbsolutePosition;
/*
PhysicsActor = scene.AddAvatar( PhysicsActor = scene.AddAvatar(
LocalId, Firstname + "." + Lastname, pVec, LocalId, Firstname + "." + Lastname, pVec,
new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying); new Vector3(0.45f, 0.6f, Appearance.AvatarHeight), isFlying);
*/
PhysicsActor = scene.AddAvatar(
LocalId, Firstname + "." + Lastname, pVec,
Appearance.AvatarBoxSize,Appearance.AvatarFeetOffset, isFlying);
//PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients; //PhysicsActor.OnRequestTerseUpdate += SendTerseUpdateToAllClients;
PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate; PhysicsActor.OnCollisionUpdate += PhysicsCollisionUpdate;
@ -3465,6 +3378,7 @@ namespace OpenSim.Region.Framework.Scenes
ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true); ControllingClient.SendAgentAlertMessage("Physics is having a problem with your avatar. You may not be able to move until you relog.", true);
} }
/// <summary> /// <summary>
/// Event called by the physics plugin to tell the avatar about a collision. /// Event called by the physics plugin to tell the avatar about a collision.
/// </summary> /// </summary>
@ -3494,7 +3408,6 @@ namespace OpenSim.Region.Framework.Scenes
CollisionEventUpdate collisionData = (CollisionEventUpdate)e; CollisionEventUpdate collisionData = (CollisionEventUpdate)e;
Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList; Dictionary<uint, ContactPoint> coldata = collisionData.m_objCollisionList;
CollisionPlane = Vector4.UnitW;
// // No collisions at all means we may be flying. Update always // // No collisions at all means we may be flying. Update always
// // to make falling work // // to make falling work
@ -3506,6 +3419,7 @@ namespace OpenSim.Region.Framework.Scenes
if (coldata.Count != 0) if (coldata.Count != 0)
{ {
/*
switch (Animator.CurrentMovementAnimation) switch (Animator.CurrentMovementAnimation)
{ {
case "STAND": case "STAND":
@ -3514,24 +3428,36 @@ namespace OpenSim.Region.Framework.Scenes
case "CROUCH": case "CROUCH":
case "CROUCHWALK": case "CROUCHWALK":
{ {
*/
ContactPoint lowest; ContactPoint lowest;
lowest.SurfaceNormal = Vector3.Zero; lowest.SurfaceNormal = Vector3.Zero;
lowest.Position = Vector3.Zero; lowest.Position = Vector3.Zero;
lowest.Position.Z = Single.NaN; lowest.Position.Z = float.MaxValue;
foreach (ContactPoint contact in coldata.Values) foreach (ContactPoint contact in coldata.Values)
{ {
if (Single.IsNaN(lowest.Position.Z) || contact.Position.Z < lowest.Position.Z)
if (contact.CharacterFeet && contact.Position.Z < lowest.Position.Z)
{ {
lowest = contact; lowest = contact;
} }
} }
CollisionPlane = new Vector4(-lowest.SurfaceNormal, -Vector3.Dot(lowest.Position, lowest.SurfaceNormal)); if (lowest.Position.Z != float.MaxValue)
{
lowest.SurfaceNormal = -lowest.SurfaceNormal;
CollisionPlane = new Vector4(lowest.SurfaceNormal, Vector3.Dot(lowest.Position, lowest.SurfaceNormal));
}
else
CollisionPlane = Vector4.UnitW;
/*
} }
break; break;
} }
*/
} }
else
CollisionPlane = Vector4.UnitW;
RaiseCollisionScriptEvents(coldata); RaiseCollisionScriptEvents(coldata);

View File

@ -911,7 +911,7 @@ namespace OpenSim.Region.OptionalModules.Agent.InternetRelayClientView.Server
// Mimicking LLClientView which gets always set appearance from client. // Mimicking LLClientView which gets always set appearance from client.
AvatarAppearance appearance; AvatarAppearance appearance;
m_scene.GetAvatarAppearance(this, out appearance); m_scene.GetAvatarAppearance(this, out appearance);
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone()); OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize);
} }
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args) public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)

View File

@ -61,6 +61,7 @@ namespace OpenSim.Region.Physics.Manager
public Vector3 SurfaceNormal; public Vector3 SurfaceNormal;
public float PenetrationDepth; public float PenetrationDepth;
public float RelativeSpeed; public float RelativeSpeed;
public bool CharacterFeet;
public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth) public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth)
{ {
@ -68,6 +69,16 @@ namespace OpenSim.Region.Physics.Manager
SurfaceNormal = surfaceNormal; SurfaceNormal = surfaceNormal;
PenetrationDepth = penetrationDepth; PenetrationDepth = penetrationDepth;
RelativeSpeed = 0f; // for now let this one be set explicity RelativeSpeed = 0f; // for now let this one be set explicity
CharacterFeet = true; // keep other plugins work as before
}
public ContactPoint(Vector3 position, Vector3 surfaceNormal, float penetrationDepth, bool feet)
{
Position = position;
SurfaceNormal = surfaceNormal;
PenetrationDepth = penetrationDepth;
RelativeSpeed = 0f; // for now let this one be set explicity
CharacterFeet = feet; // keep other plugins work as before
} }
} }
@ -173,6 +184,11 @@ namespace OpenSim.Region.Physics.Manager
public abstract Vector3 Size { get; set; } public abstract Vector3 Size { get; set; }
public virtual void setAvatarSize(Vector3 size, float feetOffset)
{
Size = size;
}
public virtual bool Phantom { get; set; } public virtual bool Phantom { get; set; }
public virtual bool IsVolumeDtc public virtual bool IsVolumeDtc
@ -395,6 +411,7 @@ namespace OpenSim.Region.Physics.Manager
// Warning in a parent part it returns itself, not null // Warning in a parent part it returns itself, not null
public virtual PhysicsActor ParentActor { get { return this; } } public virtual PhysicsActor ParentActor { get { return this; } }
} }
public class NullPhysicsActor : PhysicsActor public class NullPhysicsActor : PhysicsActor

View File

@ -38,6 +38,7 @@ namespace OpenSim.Region.Physics.Manager
public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal); public delegate void RaycastCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 normal);
public delegate void RayCallback(List<ContactResult> list); public delegate void RayCallback(List<ContactResult> list);
public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
public delegate void JointMoved(PhysicsJoint joint); public delegate void JointMoved(PhysicsJoint joint);
public delegate void JointDeactivated(PhysicsJoint joint); public delegate void JointDeactivated(PhysicsJoint joint);
@ -127,8 +128,10 @@ namespace OpenSim.Region.Physics.Manager
/// <param name="size"></param> /// <param name="size"></param>
/// <param name="isFlying"></param> /// <param name="isFlying"></param>
/// <returns></returns> /// <returns></returns>
public abstract PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying); public virtual PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying)
{
return null;
}
/// <summary> /// <summary>
/// Add an avatar /// Add an avatar
/// </summary> /// </summary>
@ -145,6 +148,12 @@ namespace OpenSim.Region.Physics.Manager
return ret; return ret;
} }
public virtual PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
{
PhysicsActor ret = AddAvatar(localID, avName, position, size, isFlying);
return ret;
}
/// <summary> /// <summary>
/// Remove an avatar. /// Remove an avatar.
/// </summary> /// </summary>
@ -349,5 +358,9 @@ namespace OpenSim.Region.Physics.Manager
return new List<ContactResult>(); return new List<ContactResult>();
} }
public virtual int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
{
return 0;
}
} }
} }

View File

@ -74,31 +74,31 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 _position; private Vector3 _position;
private Vector3 _zeroPosition; private Vector3 _zeroPosition;
private bool _zeroFlag = false;
private Vector3 _velocity; private Vector3 _velocity;
private Vector3 _target_velocity; private Vector3 _target_velocity;
private Vector3 _acceleration; private Vector3 _acceleration;
private Vector3 m_rotationalVelocity; private Vector3 m_rotationalVelocity;
private Vector3 m_size; private Vector3 m_size;
private Quaternion m_orientation; private Quaternion m_orientation;
private Quaternion m_orientation2D;
private float m_mass = 80f; private float m_mass = 80f;
public float m_density = 60f; public float m_density = 60f;
private bool m_pidControllerActive = true; private bool m_pidControllerActive = true;
public float PID_D = 800.0f;
public float PID_P = 900.0f;
//private static float POSTURE_SERVO = 10000.0f;
const float basePID_D = 0.55f; // scaled for unit mass unit time (2200 /(50*80))
const float basePID_P = 0.225f; // scaled for unit mass unit time (900 /(50*80))
public float PID_D;
public float PID_P;
private float m_invElipSizeX; private float timeStep;
private float m_invElipSizeY; private float invtimeStep;
private float m_feetOffset = 0;
private float feetOff = 0; private float feetOff = 0;
private float feetSZ = 0.5f; private float feetSZ = 0.5f;
const float feetScale = 0.9f; const float feetScale = 0.8f;
const float invFeetScale = 1.0f / 0.9f;
const float sizeZAdjust = 0.15f;
private float boneOff = 0; private float boneOff = 0;
private float m_lastVelocitySqr = 0;
public float walkDivisor = 1.3f; public float walkDivisor = 1.3f;
public float runDivisor = 0.8f; public float runDivisor = 0.8f;
@ -107,6 +107,9 @@ namespace OpenSim.Region.Physics.OdePlugin
private bool m_iscollidingGround = false; private bool m_iscollidingGround = false;
private bool m_iscollidingObj = false; private bool m_iscollidingObj = false;
private bool m_alwaysRun = false; private bool m_alwaysRun = false;
private bool _zeroFlag = false;
private int m_requestedUpdateFrequency = 0; private int m_requestedUpdateFrequency = 0;
private uint m_localID = 0; private uint m_localID = 0;
public bool m_returnCollisions = false; public bool m_returnCollisions = false;
@ -124,6 +127,7 @@ namespace OpenSim.Region.Physics.OdePlugin
int m_colliderfilter = 0; int m_colliderfilter = 0;
int m_colliderGroundfilter = 0; int m_colliderGroundfilter = 0;
int m_colliderObjectfilter = 0; int m_colliderObjectfilter = 0;
bool m_collisionException = false;
// Default we're a Character // Default we're a Character
private CollisionCategories m_collisionCategories = (CollisionCategories.Character); private CollisionCategories m_collisionCategories = (CollisionCategories.Character);
@ -136,10 +140,11 @@ namespace OpenSim.Region.Physics.OdePlugin
// we do land collisions not ode | CollisionCategories.Land); // we do land collisions not ode | CollisionCategories.Land);
public IntPtr Body = IntPtr.Zero; public IntPtr Body = IntPtr.Zero;
private OdeScene _parent_scene; private OdeScene _parent_scene;
public IntPtr topbox = IntPtr.Zero; private IntPtr topbox = IntPtr.Zero;
public IntPtr midbox = IntPtr.Zero; private IntPtr midbox = IntPtr.Zero;
public IntPtr feetbox = IntPtr.Zero; private IntPtr feetbox = IntPtr.Zero;
public IntPtr bonebox = IntPtr.Zero; private IntPtr bbox = IntPtr.Zero;
public IntPtr collider = IntPtr.Zero;
public IntPtr Amotor = IntPtr.Zero; public IntPtr Amotor = IntPtr.Zero;
@ -147,6 +152,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public int m_eventsubscription = 0; public int m_eventsubscription = 0;
private int m_cureventsubscription = 0; private int m_cureventsubscription = 0;
private CollisionEventUpdate CollisionEventsThisFrame = null; private CollisionEventUpdate CollisionEventsThisFrame = null;
@ -160,9 +166,13 @@ namespace OpenSim.Region.Physics.OdePlugin
public OdeCharacter(String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pid_d, float pid_p, float density, float walk_divisor, float rundivisor) public OdeCharacter(uint localID, String avName, OdeScene parent_scene, Vector3 pos, Vector3 pSize, float pfeetOffset, float density, float walk_divisor, float rundivisor)
{ {
m_uuid = UUID.Random(); m_uuid = UUID.Random();
m_localID = localID;
timeStep = parent_scene.ODE_STEPSIZE;
invtimeStep = 1 / timeStep;
if (pos.IsFinite()) if (pos.IsFinite())
{ {
@ -184,8 +194,6 @@ namespace OpenSim.Region.Physics.OdePlugin
_parent_scene = parent_scene; _parent_scene = parent_scene;
PID_D = pid_d;
PID_P = pid_p;
m_size.X = pSize.X; m_size.X = pSize.X;
m_size.Y = pSize.Y; m_size.Y = pSize.Y;
@ -198,12 +206,16 @@ namespace OpenSim.Region.Physics.OdePlugin
if(m_size.Z <0.01f) if(m_size.Z <0.01f)
m_size.Z = 0.01f; m_size.Z = 0.01f;
m_feetOffset = pfeetOffset;
m_orientation = Quaternion.Identity; m_orientation = Quaternion.Identity;
m_orientation2D = Quaternion.Identity;
m_density = density; m_density = density;
// force lower density for testing // force lower density for testing
m_density = 3.0f; m_density = 3.0f;
m_density *= 1.4f; // scale to have mass similar to capsule
mu = parent_scene.AvatarFriction; mu = parent_scene.AvatarFriction;
walkDivisor = walk_divisor; walkDivisor = walk_divisor;
@ -211,6 +223,9 @@ namespace OpenSim.Region.Physics.OdePlugin
m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default m_mass = m_density * m_size.X * m_size.Y * m_size.Z; ; // sure we have a default
PID_D = basePID_D * m_mass * invtimeStep;
PID_P = basePID_P * m_mass * invtimeStep;
m_isPhysical = false; // current status: no ODE information exists m_isPhysical = false; // current status: no ODE information exists
Name = avName; Name = avName;
@ -475,6 +490,28 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
public override void setAvatarSize(Vector3 size, float feetOffset)
{
if (size.IsFinite())
{
if (size.X < 0.01f)
size.X = 0.01f;
if (size.Y < 0.01f)
size.Y = 0.01f;
if (size.Z < 0.01f)
size.Z = 0.01f;
strAvatarSize st = new strAvatarSize();
st.size = size;
st.offset = feetOffset;
AddChange(changes.AvatarSize, st);
}
else
{
m_log.Warn("[PHYSICS]: Got a NaN AvatarSize from Scene on a Character");
}
}
/// <summary> /// <summary>
/// This creates the Avatar's physical Surrogate at the position supplied /// This creates the Avatar's physical Surrogate at the position supplied
/// </summary> /// </summary>
@ -491,7 +528,7 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
get get
{ {
return m_density * m_size.X * m_size.Y * m_size.Z; return m_mass;
} }
} }
public override void link(PhysicsActor obj) public override void link(PhysicsActor obj)
@ -614,7 +651,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
// fakeori = value; // fakeori = value;
// givefakeori++; // givefakeori++;
value.Normalize(); value.Normalize();
AddChange(changes.Orientation, value); AddChange(changes.Orientation, value);
} }
@ -668,33 +704,72 @@ namespace OpenSim.Region.Physics.OdePlugin
AddChange(changes.Momentum, momentum); AddChange(changes.Momentum, momentum);
} }
private void ajustCollider()
{
float vq = _velocity.LengthSquared();
if (m_lastVelocitySqr != vq)
{
m_lastVelocitySqr = vq;
if (vq > 100.0f)
{
Vector3 off = _velocity;
float t = 0.5f * timeStep;
off = off * t;
d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
off.X = 2.0f * (m_size.X + Math.Abs(off.X));
off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
d.GeomBoxSetLengths(bbox, off.X, off.Y, off.Z);
d.GeomSetCategoryBits(bbox, (uint)m_collisionCategories);
d.GeomSetCollideBits(bbox, (uint)m_collisionFlags);
d.GeomSetCategoryBits(topbox, 0);
d.GeomSetCollideBits(topbox, 0);
d.GeomSetCategoryBits(midbox, 0);
d.GeomSetCollideBits(midbox, 0);
d.GeomSetCategoryBits(feetbox, 0);
d.GeomSetCollideBits(feetbox, 0);
}
else
{
d.GeomSetCategoryBits(bbox, 0);
d.GeomSetCollideBits(bbox, 0);
d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories);
d.GeomSetCollideBits(midbox, (uint)m_collisionFlags);
d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
}
}
}
private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ) private void AvatarGeomAndBodyCreation(float npositionX, float npositionY, float npositionZ)
{ {
// sizes one day should came from visual parameters // sizes one day should came from visual parameters
float sz = m_size.Z + sizeZAdjust; float sx = m_size.X;
float sy = m_size.Y;
float sz = m_size.Z;
m_invElipSizeX = 1.0f / m_size.X; float topsx = sx * 0.9f;
m_invElipSizeY = 1.0f / m_size.Y; float midsx = sx;
float feetsx = sx * feetScale;
float bonesx = sx * 0.2f;
float topsx = m_size.X; float topsy = sy * 0.4f;
float midsx = m_size.X; float midsy = sy;
float feetsx = m_size.X * feetScale; float feetsy = sy * feetScale * 0.8f;
float bonesx = feetsx * 0.2f;
float topsy = m_size.Y * 0.5f;
float midsy = m_size.Y;
float feetsy = m_size.Y * feetScale;
float bonesy = feetsy * 0.2f; float bonesy = feetsy * 0.2f;
float topsz = sz * 0.15f; float topsz = sz * 0.15f;
float feetsz = sz * 0.3f; float feetsz = sz * 0.45f;
if (feetsz > 0.6f) if (feetsz > 0.6f)
feetsz = 0.6f; feetsz = 0.6f;
float midsz = sz - topsz - feetsz; float midsz = sz - topsz - feetsz;
float bonesz = sz; float bonesz = sz;
float bot = -sz * 0.5f; float bot = -sz * 0.5f + m_feetOffset;
boneOff = bot + 0.3f; boneOff = bot + 0.3f;
@ -708,47 +783,37 @@ namespace OpenSim.Region.Physics.OdePlugin
bot += midsz; bot += midsz;
float topz = bot + topsz * 0.5f; float topz = bot + topsz * 0.5f;
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); _parent_scene.waitForSpaceUnlock(_parent_scene.CharsSpace);
feetbox = d.CreateBox(_parent_scene.ActiveSpace, feetsx, feetsy, feetsz); collider = d.HashSpaceCreate(_parent_scene.CharsSpace);
d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories); d.HashSpaceSetLevels(collider, -4, 3);
d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags); d.SpaceSetSublevel(collider, 3);
d.SpaceSetCleanup(collider, false);
d.GeomSetCategoryBits(collider, (uint)m_collisionCategories);
d.GeomSetCollideBits(collider, (uint)m_collisionFlags);
midbox = d.CreateBox(_parent_scene.ActiveSpace, midsx, midsy, midsz); feetbox = d.CreateBox(collider, feetsx, feetsy, feetsz);
d.GeomSetCategoryBits(midbox, (uint)m_collisionCategories); midbox = d.CreateBox(collider, midsx, midsy, midsz);
d.GeomSetCollideBits(midbox, (uint)m_collisionFlags); topbox = d.CreateBox(collider, topsx, topsy, topsz);
bbox = d.CreateBox(collider, m_size.X, m_size.Y, m_size.Z);
topbox = d.CreateBox(_parent_scene.ActiveSpace, topsx, topsy, topsz); m_mass = m_density * m_size.X * m_size.Y * m_size.Z; // update mass
d.GeomSetCategoryBits(topbox, (uint)m_collisionCategories);
d.GeomSetCollideBits(topbox, (uint)m_collisionFlags);
bonebox = d.CreateBox(_parent_scene.ActiveSpace, bonesx, bonesy, bonesz); d.MassSetBoxTotal(out ShellMass, m_mass, m_size.X, m_size.Y, m_size.Z);
d.GeomSetCategoryBits(bonebox, (uint)m_collisionCategories);
d.GeomSetCollideBits(bonebox, (uint)m_collisionFlags);
d.MassSetBox(out ShellMass, m_density, m_size.X , m_size.Y, m_size.Z); PID_D = basePID_D * m_mass / _parent_scene.ODE_STEPSIZE;
PID_P = basePID_P * m_mass / _parent_scene.ODE_STEPSIZE;
m_mass = ShellMass.mass; // update mass
// rescale PID parameters
PID_D = _parent_scene.avPIDD;
PID_P = _parent_scene.avPIDP;
// rescale PID parameters so that this aren't affected by mass
// and so don't get unstable for some masses
// also scale by ode time step so you don't need to refix them
PID_D /= 50 * 80; //scale to original mass of around 80 and 50 ODE fps
PID_D *= m_mass / _parent_scene.ODE_STEPSIZE;
PID_P /= 50 * 80;
PID_P *= m_mass / _parent_scene.ODE_STEPSIZE;
Body = d.BodyCreate(_parent_scene.world); Body = d.BodyCreate(_parent_scene.world);
_zeroFlag = false; _zeroFlag = false;
m_collisionException = false;
m_pidControllerActive = true; m_pidControllerActive = true;
m_freemove = false; m_freemove = false;
_velocity = Vector3.Zero;
m_lastVelocitySqr = 0;
d.BodySetAutoDisableFlag(Body, false); d.BodySetAutoDisableFlag(Body, false);
d.BodySetPosition(Body, npositionX, npositionY, npositionZ); d.BodySetPosition(Body, npositionX, npositionY, npositionZ);
@ -760,12 +825,15 @@ namespace OpenSim.Region.Physics.OdePlugin
d.GeomSetBody(feetbox, Body); d.GeomSetBody(feetbox, Body);
d.GeomSetBody(midbox, Body); d.GeomSetBody(midbox, Body);
d.GeomSetBody(topbox, Body); d.GeomSetBody(topbox, Body);
d.GeomSetBody(bonebox, Body); d.GeomSetBody(bbox, Body);
d.GeomSetOffsetPosition(feetbox, 0, 0, feetz); d.GeomSetOffsetPosition(feetbox, 0, 0, feetz);
d.GeomSetOffsetPosition(midbox, 0, 0, midz); d.GeomSetOffsetPosition(midbox, 0, 0, midz);
d.GeomSetOffsetPosition(topbox, 0, 0, topz); d.GeomSetOffsetPosition(topbox, 0, 0, topz);
ajustCollider();
// The purpose of the AMotor here is to keep the avatar's physical // The purpose of the AMotor here is to keep the avatar's physical
// surrogate from rotating while moving // surrogate from rotating while moving
Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero); Amotor = d.JointCreateAMotor(_parent_scene.world, IntPtr.Zero);
@ -828,141 +896,211 @@ namespace OpenSim.Region.Physics.OdePlugin
if (topbox != IntPtr.Zero) if (topbox != IntPtr.Zero)
{ {
_parent_scene.actor_name_map.Remove(topbox); _parent_scene.actor_name_map.Remove(topbox);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); _parent_scene.waitForSpaceUnlock(collider);
d.GeomDestroy(topbox); d.GeomDestroy(topbox);
topbox = IntPtr.Zero; topbox = IntPtr.Zero;
} }
if (midbox != IntPtr.Zero) if (midbox != IntPtr.Zero)
{ {
_parent_scene.actor_name_map.Remove(midbox); _parent_scene.actor_name_map.Remove(midbox);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); _parent_scene.waitForSpaceUnlock(collider);
d.GeomDestroy(midbox); d.GeomDestroy(midbox);
midbox = IntPtr.Zero; midbox = IntPtr.Zero;
} }
if (feetbox != IntPtr.Zero) if (feetbox != IntPtr.Zero)
{ {
_parent_scene.actor_name_map.Remove(feetbox); _parent_scene.actor_name_map.Remove(feetbox);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); _parent_scene.waitForSpaceUnlock(collider);
d.GeomDestroy(feetbox); d.GeomDestroy(feetbox);
feetbox = IntPtr.Zero; feetbox = IntPtr.Zero;
} }
if (bonebox != IntPtr.Zero) if (bbox != IntPtr.Zero)
{ {
_parent_scene.actor_name_map.Remove(bonebox); _parent_scene.actor_name_map.Remove(bbox);
_parent_scene.waitForSpaceUnlock(_parent_scene.ActiveSpace); _parent_scene.waitForSpaceUnlock(collider);
d.GeomDestroy(bonebox); d.GeomDestroy(bbox);
bonebox = IntPtr.Zero; bbox = IntPtr.Zero;
}
if (collider != IntPtr.Zero)
{
d.SpaceDestroy(collider);
collider = IntPtr.Zero;
} }
} }
public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact) //in place 2D rotation around Z assuming rot is normalised and is a rotation around Z
public void RotateXYonZ(ref float x, ref float y, ref Quaternion rot)
{ {
float sin = 2.0f * rot.Z * rot.W;
float cos = rot.W * rot.W - rot.Z * rot.Z;
float tx = x;
if (me == bonebox) // inner bone x = tx * cos - y * sin;
y = tx * sin + y * cos;
}
public void RotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
{ {
if (contact.pos.Z - _position.Z < boneOff) float tx = x;
IsColliding = true; x = tx * cos - y * sin;
return true; y = tx * sin + y * cos;
}
public void invRotateXYonZ(ref float x, ref float y, ref float sin, ref float cos)
{
float tx = x;
x = tx * cos + y * sin;
y = -tx * sin + y * cos;
} }
if (me == topbox) // keep a box head public void invRotateXYonZ(ref float x, ref float y, ref Quaternion rot)
return true;
// rotate elipsoide assuming only rotation around Z
float ca = m_orientation.W * m_orientation.W - m_orientation.Z * m_orientation.Z;
float sa = 2 * m_orientation.W * m_orientation.Z;
float isx;
float isy;
if (me == feetbox) // feet have narrow bounds
{ {
float sin = - 2.0f * rot.Z * rot.W;
float cos = rot.W * rot.W - rot.Z * rot.Z;
float tx = x;
isx = m_invElipSizeX * invFeetScale; x = tx * cos - y * sin;
isy = m_invElipSizeY * invFeetScale; y = tx * sin + y * cos;
}
else
{
isx = m_invElipSizeX;
isy = m_invElipSizeY;
} }
float a = isx * ca - isy * sa;
float b = isx * sa + isy * ca;
float offx = contact.pos.X - _position.X; public bool Collide(IntPtr me, bool reverse, ref d.ContactGeom contact, ref bool feetcollision)
float er = offx * a;
er *= er;
float offy = contact.pos.Y - _position.Y;
float ty = offy * b;
er += ty * ty;
if (me == midbox)
{ {
if (er > 4.0f) // no collision feetcollision = false;
if (m_collisionException)
return false; return false;
if (er < 0.2f)
return true;
float t = offx * offx + offy * offy; Vector3 offset;
t = (float)Math.Sqrt(t);
t = 1 / t; if (me == bbox) // if moving fast
offx *= t; {
offy *= t; // force a full inelastic collision
m_collisionException = true;
offset = m_size * m_orientation2D;
offset.X = (float)Math.Abs(offset.X) * 0.5f + contact.depth;
offset.Y = (float)Math.Abs(offset.Y) * 0.5f + contact.depth;
offset.Z = (float)Math.Abs(offset.Z) * 0.5f + contact.depth;
if (reverse) if (reverse)
{ {
contact.normal.X = offx; offset.X *= -contact.normal.X;
contact.normal.Y = offy; offset.Y *= -contact.normal.Y;
offset.Z *= -contact.normal.Z;
} }
else else
{ {
contact.normal.X = -offx; offset.X *= contact.normal.X;
contact.normal.Y = -offy; offset.Y *= contact.normal.Y;
offset.Z *= contact.normal.Z;
}
offset.X += contact.pos.X;
offset.Y += contact.pos.Y;
offset.Z += contact.pos.Z;
_position = offset;
return false;
}
offset.X = contact.pos.X - _position.X;
offset.Y = contact.pos.Y - _position.Y;
if (me == topbox)
{
offset.Z = contact.pos.Z - _position.Z;
offset.Normalize();
if (reverse)
{
contact.normal.X = offset.X;
contact.normal.Y = offset.Y;
contact.normal.Z = offset.Z;
}
else
{
contact.normal.X = -offset.X;
contact.normal.Y = -offset.Y;
contact.normal.Z = -offset.Z;
}
return true;
}
if (me == midbox)
{
if (Math.Abs(contact.normal.Z) > 0.95f)
offset.Z = contact.pos.Z - _position.Z;
else
offset.Z = contact.normal.Z;
offset.Normalize();
if (reverse)
{
contact.normal.X = offset.X;
contact.normal.Y = offset.Y;
contact.normal.Z = offset.Z;
}
else
{
contact.normal.X = -offset.X;
contact.normal.Y = -offset.Y;
contact.normal.Z = -offset.Z;
} }
contact.normal.Z = 0;
return true; return true;
} }
else if (me == feetbox) else if (me == feetbox)
{ {
float c = feetSZ * 2;
float h = contact.pos.Z - _position.Z; float h = contact.pos.Z - _position.Z;
float offz = h - feetOff; // distance from top of feetbox
float tz = offz / c; if (Math.Abs(contact.normal.Z) > 0.95f)
er += tz * tz; {
if (contact.normal.Z > 0)
contact.normal.Z = 1.0f;
else
contact.normal.Z = -1.0f;
contact.normal.X = 0.0f;
contact.normal.Y = 0.0f;
feetcollision = true;
if (h < boneOff)
IsColliding = true;
return true;
}
if (er > 4.0f) // no collision offset.Z = h - feetOff; // distance from top of feetbox
if (offset.Z > 0)
return false; return false;
if (er > 0.2f) if (offset.Z > -0.01)
{ {
float t = offx * offx + offy * offy + offz * offz; offset.X = 0;
t = (float)Math.Sqrt(t); offset.Y = 0;
t = 1 / t; offset.Z = -1.0f;
offx *= t;
offy *= t;
offz *= t;
if (reverse)
{
contact.normal.X = offx;
contact.normal.Y = offy;
contact.normal.Z = offz;
} }
else else
{ {
contact.normal.X = -offx; offset.Normalize();
contact.normal.Y = -offy;
contact.normal.Z = -offz;
}
} }
if (reverse)
{
contact.normal.X = offset.X;
contact.normal.Y = offset.Y;
contact.normal.Z = offset.Z;
}
else
{
contact.normal.X = -offset.X;
contact.normal.Y = -offset.Y;
contact.normal.Z = -offset.Z;
}
feetcollision = true;
if (h < boneOff) if (h < boneOff)
IsColliding = true; IsColliding = true;
} }
@ -977,11 +1115,28 @@ namespace OpenSim.Region.Physics.OdePlugin
/// This is the avatar's movement control + PID Controller /// This is the avatar's movement control + PID Controller
/// </summary> /// </summary>
/// <param name="timeStep"></param> /// <param name="timeStep"></param>
public void Move(float timeStep, List<OdeCharacter> defects) public void Move(List<OdeCharacter> defects)
{ {
if (Body == IntPtr.Zero) if (Body == IntPtr.Zero)
return; return;
if (m_collisionException)
{
d.BodySetPosition(Body,_position.X, _position.Y, _position.Z);
d.BodySetLinearVel(Body, 0, 0, 0);
float v = _velocity.Length();
if (v != 0)
{
v = 5.0f / v;
_velocity = _velocity * v;
d.BodySetLinearVel(Body, _velocity.X, _velocity.Y, _velocity.Z);
}
ajustCollider();
m_collisionException = false;
return;
}
d.Vector3 dtmp = d.BodyGetPosition(Body); d.Vector3 dtmp = d.BodyGetPosition(Body);
Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z); Vector3 localpos = new Vector3(dtmp.X, dtmp.Y, dtmp.Z);
@ -989,10 +1144,10 @@ namespace OpenSim.Region.Physics.OdePlugin
// so force it back to identity // so force it back to identity
d.Quaternion qtmp; d.Quaternion qtmp;
qtmp.W = m_orientation.W; qtmp.W = m_orientation2D.W;
qtmp.X = m_orientation.X; qtmp.X = m_orientation2D.X;
qtmp.Y = m_orientation.Y; qtmp.Y = m_orientation2D.Y;
qtmp.Z = m_orientation.Z; qtmp.Z = m_orientation2D.Z;
d.BodySetQuaternion(Body, ref qtmp); d.BodySetQuaternion(Body, ref qtmp);
if (m_pidControllerActive == false) if (m_pidControllerActive == false)
@ -1055,9 +1210,10 @@ namespace OpenSim.Region.Physics.OdePlugin
//****************************************** //******************************************
// colide with land // colide with land
d.AABB aabb; d.AABB aabb;
d.GeomGetAABB(feetbox, out aabb); d.GeomGetAABB(feetbox, out aabb);
float chrminZ = aabb.MinZ - 0.04f; // move up a bit float chrminZ = aabb.MinZ; ; // move up a bit
Vector3 posch = localpos; Vector3 posch = localpos;
float ftmp; float ftmp;
@ -1100,11 +1256,12 @@ namespace OpenSim.Region.Physics.OdePlugin
contact.PenetrationDepth = depth; contact.PenetrationDepth = depth;
contact.Position.X = localpos.X; contact.Position.X = localpos.X;
contact.Position.Y = localpos.Y; contact.Position.Y = localpos.Y;
contact.Position.Z = chrminZ; contact.Position.Z = terrainheight;
contact.SurfaceNormal.X = 0f; contact.SurfaceNormal.X = 0.0f;
contact.SurfaceNormal.Y = 0f; contact.SurfaceNormal.Y = 0.0f;
contact.SurfaceNormal.Z = -1f; contact.SurfaceNormal.Z = -1f;
contact.RelativeSpeed = -vel.Z; contact.RelativeSpeed = -vel.Z;
contact.CharacterFeet = true;
AddCollisionEvent(0, contact); AddCollisionEvent(0, contact);
vec.Z *= 0.5f; vec.Z *= 0.5f;
@ -1123,6 +1280,7 @@ namespace OpenSim.Region.Physics.OdePlugin
m_iscollidingGround = false; m_iscollidingGround = false;
} }
//****************************************** //******************************************
bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f); bool tviszero = (_target_velocity.X == 0.0f && _target_velocity.Y == 0.0f && _target_velocity.Z == 0.0f);
@ -1258,21 +1416,58 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
// update our local ideia of position velocity and aceleration // update our local ideia of position velocity and aceleration
// _position = localpos;
_position = localpos; _position = localpos;
if (_zeroFlag) if (_zeroFlag)
{ {
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
_acceleration = Vector3.Zero; _acceleration = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero;
} }
else else
{ {
_acceleration = _velocity; // previus velocity Vector3 a =_velocity; // previus velocity
_velocity = vel; SetSmooth(ref _velocity, ref vel, 2);
_acceleration = (vel - _acceleration) / timeStep; a = (_velocity - a) * invtimeStep;
SetSmooth(ref _acceleration, ref a, 2);
dtmp = d.BodyGetAngularVel(Body);
m_rotationalVelocity.X = 0f;
m_rotationalVelocity.Y = 0f;
m_rotationalVelocity.Z = dtmp.Z;
Math.Round(m_rotationalVelocity.Z,3);
}
ajustCollider();
} }
public void round(ref Vector3 v, int digits)
{
v.X = (float)Math.Round(v.X, digits);
v.Y = (float)Math.Round(v.Y, digits);
v.Z = (float)Math.Round(v.Z, digits);
} }
public void SetSmooth(ref Vector3 dst, ref Vector3 value)
{
dst.X = 0.1f * dst.X + 0.9f * value.X;
dst.Y = 0.1f * dst.Y + 0.9f * value.Y;
dst.Z = 0.1f * dst.Z + 0.9f * value.Z;
}
public void SetSmooth(ref Vector3 dst, ref Vector3 value, int rounddigits)
{
dst.X = 0.4f * dst.X + 0.6f * value.X;
dst.X = (float)Math.Round(dst.X, rounddigits);
dst.Y = 0.4f * dst.Y + 0.6f * value.Y;
dst.Y = (float)Math.Round(dst.Y, rounddigits);
dst.Z = 0.4f * dst.Z + 0.6f * value.Z;
dst.Z = (float)Math.Round(dst.Z, rounddigits);
}
/// <summary> /// <summary>
/// Updates the reported position and velocity. /// Updates the reported position and velocity.
/// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording /// Used to copy variables from unmanaged space at heartbeat rate and also trigger scene updates acording
@ -1399,10 +1594,11 @@ namespace OpenSim.Region.Physics.OdePlugin
AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z); AvatarGeomAndBodyCreation(_position.X, _position.Y, _position.Z);
_parent_scene.actor_name_map[topbox] = (PhysicsActor)this; _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
_parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
_parent_scene.AddCharacter(this); _parent_scene.AddCharacter(this);
} }
else else
@ -1431,6 +1627,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
} }
private void changeAvatarSize(strAvatarSize st)
{
m_feetOffset = st.offset;
changeSize(st.size);
}
private void changeSize(Vector3 pSize) private void changeSize(Vector3 pSize)
{ {
if (pSize.IsFinite()) if (pSize.IsFinite())
@ -1450,12 +1652,15 @@ namespace OpenSim.Region.Physics.OdePlugin
Velocity = Vector3.Zero; Velocity = Vector3.Zero;
_parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[midbox] = (PhysicsActor)this; _parent_scene.actor_name_map[collider] = (PhysicsActor)this;
_parent_scene.actor_name_map[feetbox] = (PhysicsActor)this; _parent_scene.actor_name_map[feetbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[bonebox] = (PhysicsActor)this; _parent_scene.actor_name_map[midbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[topbox] = (PhysicsActor)this;
_parent_scene.actor_name_map[bbox] = (PhysicsActor)this;
} }
m_freemove = false; m_freemove = false;
m_collisionException = false;
m_pidControllerActive = true; m_pidControllerActive = true;
} }
else else
@ -1475,14 +1680,36 @@ namespace OpenSim.Region.Physics.OdePlugin
private void changeOrientation(Quaternion newOri) private void changeOrientation(Quaternion newOri)
{ {
if (m_orientation != newOri)
{
m_orientation = newOri; // keep a copy for core use
// but only use rotations around Z
m_orientation2D.W = newOri.W;
m_orientation2D.Z = newOri.Z;
float t = m_orientation2D.W * m_orientation2D.W + m_orientation2D.Z * m_orientation2D.Z;
if (t > 0)
{
t = 1.0f / (float)Math.Sqrt(t);
m_orientation2D.W *= t;
m_orientation2D.Z *= t;
}
else
{
m_orientation2D.W = 1.0f;
m_orientation2D.Z = 0f;
}
m_orientation2D.Y = 0f;
m_orientation2D.X = 0f;
d.Quaternion myrot = new d.Quaternion(); d.Quaternion myrot = new d.Quaternion();
myrot.X = newOri.X; myrot.X = m_orientation2D.X;
myrot.Y = newOri.Y; myrot.Y = m_orientation2D.Y;
myrot.Z = newOri.Z; myrot.Z = m_orientation2D.Z;
myrot.W = newOri.W; myrot.W = m_orientation2D.W;
float t = d.JointGetAMotorAngle(Amotor, 2);
d.BodySetQuaternion(Body, ref myrot); d.BodySetQuaternion(Body, ref myrot);
m_orientation = newOri; }
} }
private void changeVelocity(Vector3 newVel) private void changeVelocity(Vector3 newVel)
@ -1564,6 +1791,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (Body != IntPtr.Zero) if (Body != IntPtr.Zero)
d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z); d.BodySetLinearVel(Body, newmomentum.X, newmomentum.Y, newmomentum.Z);
ajustCollider();
} }
private void donullchange() private void donullchange()
@ -1572,7 +1800,7 @@ namespace OpenSim.Region.Physics.OdePlugin
public bool DoAChange(changes what, object arg) public bool DoAChange(changes what, object arg)
{ {
if (topbox == IntPtr.Zero && what != changes.Add && what != changes.Remove) if (collider == IntPtr.Zero && what != changes.Add && what != changes.Remove)
{ {
return false; return false;
} }
@ -1638,6 +1866,10 @@ namespace OpenSim.Region.Physics.OdePlugin
changeSize((Vector3)arg); changeSize((Vector3)arg);
break; break;
case changes.AvatarSize:
changeAvatarSize((strAvatarSize)arg);
break;
case changes.Momentum: case changes.Momentum:
changeMomentum((Vector3)arg); changeMomentum((Vector3)arg);
break; break;
@ -1685,5 +1917,12 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_parent_scene.AddChange((PhysicsActor)this, what, arg); _parent_scene.AddChange((PhysicsActor)this, what, arg);
} }
private struct strAvatarSize
{
public Vector3 size;
public float offset;
}
} }
} }

View File

@ -84,7 +84,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private Vector3 _position; private Vector3 _position;
private Vector3 _velocity; private Vector3 _velocity;
private Vector3 _torque; private Vector3 m_torque;
private Vector3 m_lastVelocity; private Vector3 m_lastVelocity;
private Vector3 m_lastposition; private Vector3 m_lastposition;
private Vector3 m_rotationalVelocity; private Vector3 m_rotationalVelocity;
@ -597,7 +597,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (!IsPhysical || Body == IntPtr.Zero) if (!IsPhysical || Body == IntPtr.Zero)
return Vector3.Zero; return Vector3.Zero;
return _torque; return m_torque;
} }
set set
@ -2425,10 +2425,10 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (!childPrim) if (!childPrim)
{ {
m_force = Vector3.Zero; // m_force = Vector3.Zero;
m_forceacc = Vector3.Zero; m_forceacc = Vector3.Zero;
m_angularForceacc = Vector3.Zero; m_angularForceacc = Vector3.Zero;
_torque = Vector3.Zero; // m_torque = Vector3.Zero;
_velocity = Vector3.Zero; _velocity = Vector3.Zero;
_acceleration = Vector3.Zero; _acceleration = Vector3.Zero;
m_rotationalVelocity = Vector3.Zero; m_rotationalVelocity = Vector3.Zero;
@ -2521,7 +2521,7 @@ namespace OpenSim.Region.Physics.OdePlugin
prm.m_collisionCategories = m_collisionCategories; prm.m_collisionCategories = m_collisionCategories;
prm.m_collisionFlags = m_collisionFlags; prm.m_collisionFlags = m_collisionFlags;
if (prm.prim_geom != null) if (prm.prim_geom != IntPtr.Zero)
{ {
if (prm.m_NoColide) if (prm.m_NoColide)
@ -2542,7 +2542,7 @@ namespace OpenSim.Region.Physics.OdePlugin
// ((OdePrim)_parent).ChildSelectedChange(true); // ((OdePrim)_parent).ChildSelectedChange(true);
if (prim_geom != null) if (prim_geom != IntPtr.Zero)
{ {
if (m_NoColide) if (m_NoColide)
{ {
@ -2968,7 +2968,7 @@ namespace OpenSim.Region.Physics.OdePlugin
d.BodyEnable(Body); d.BodyEnable(Body);
} }
_torque = newtorque; m_torque = newtorque;
} }
} }
@ -3364,7 +3364,7 @@ namespace OpenSim.Region.Physics.OdePlugin
Vector3 trq; Vector3 trq;
trq = _torque; trq = m_torque;
trq += m_angularForceacc; trq += m_angularForceacc;
m_angularForceacc = Vector3.Zero; m_angularForceacc = Vector3.Zero;
if (trq.X != 0 || trq.Y != 0 || trq.Z != 0) if (trq.X != 0 || trq.Y != 0 || trq.Z != 0)

View File

@ -324,7 +324,10 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
// Collide tests // Collide tests
if ((CurrentRayFilter & FilterActiveSpace) != 0) if ((CurrentRayFilter & FilterActiveSpace) != 0)
{
d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback); d.SpaceCollide2(ray, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
d.SpaceCollide2(ray, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
}
if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount)) if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback); d.SpaceCollide2(ray, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount)) if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
@ -552,7 +555,6 @@ namespace OpenSim.Region.Physics.OdePlugin
break; break;
default: default:
return;
break; break;
} }
} }

View File

@ -0,0 +1,183 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSimulator Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// Ubit 2012
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OdeAPI;
using log4net;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
/// <summary>
/// </summary>
public class ODESitAvatar
{
private OdeScene m_scene;
private ODERayCastRequestManager m_raymanager;
public ODESitAvatar(OdeScene pScene, ODERayCastRequestManager raymanager)
{
m_scene = pScene;
m_raymanager = raymanager;
}
private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
{
if (!m_scene.haveActor(actor) || !(actor is OdePrim) || ((OdePrim)actor).prim_geom == IntPtr.Zero)
{
PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
return;
}
IntPtr geom = ((OdePrim)actor).prim_geom;
d.Vector3 dtmp = d.GeomGetPosition(geom);
Vector3 geopos;
geopos.X = dtmp.X;
geopos.Y = dtmp.Y;
geopos.Z = dtmp.Z;
d.AABB aabb;
Quaternion ori;
d.Quaternion qtmp;
d.GeomCopyQuaternion(geom, out qtmp);
Quaternion geomOri;
geomOri.X = qtmp.X;
geomOri.Y = qtmp.Y;
geomOri.Z = qtmp.Z;
geomOri.W = qtmp.W;
Quaternion geomInvOri;
geomInvOri.X = -qtmp.X;
geomInvOri.Y = -qtmp.Y;
geomInvOri.Z = -qtmp.Z;
geomInvOri.W = qtmp.W;
Vector3 target = geopos + offset;
Vector3 rayDir = target - avCameraPosition;
float raylen = rayDir.Length();
float t = 1 / raylen;
rayDir.X *= t;
rayDir.Y *= t;
rayDir.Z *= t;
raylen += 0.5f;
List<ContactResult> rayResults;
rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1);
if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID)
{
d.GeomGetAABB(geom,out aabb);
offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
ori = geomInvOri;
offset *= geomInvOri;
PhysicsSitResponse(1, actor.LocalID, offset, ori);
return;
}
offset = rayResults[0].Pos - geopos;
double ang;
float s;
float c;
d.GeomClassID geoclass = d.GeomGetClass(geom);
if (geoclass == d.GeomClassID.SphereClass)
{
float r = d.GeomSphereGetRadius(geom);
offset.Normalize();
offset *= r;
ang = Math.Atan2(offset.Y, offset.X);
ang *= 0.5d;
s = (float)Math.Sin(ang);
c = (float)Math.Cos(ang);
ori = new Quaternion(0, 0, s, c);
if (r < 0.4f)
{
offset = new Vector3(0, 0, r);
}
else if (offset.Z < 0.4f)
{
t = offset.Z;
float rsq = r * r;
t = 1.0f / (rsq - t * t);
offset.X *= t;
offset.Y *= t;
offset.Z = 0.4f;
t = rsq - 0.16f;
offset.X *= t;
offset.Y *= t;
}
offset += avOffset * ori;
ori = geomInvOri * ori;
offset *= geomInvOri;
PhysicsSitResponse(1, actor.LocalID, offset, ori);
return;
}
Vector3 norm = rayResults[0].Normal;
if (norm.Z < 0)
{
PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
return;
}
ang = Math.Atan2(-rayDir.Y, -rayDir.X);
ang *= 0.5d;
s = (float)Math.Sin(ang);
c = (float)Math.Cos(ang);
ori = new Quaternion(0, 0, s, c);
offset += avOffset * ori;
ori = geomInvOri * ori;
offset *= geomInvOri;
PhysicsSitResponse(1, actor.LocalID, offset, ori);
return;
}
}
}

View File

@ -147,6 +147,7 @@ namespace OpenSim.Region.Physics.OdePlugin
PIDHoverActive, PIDHoverActive,
Size, Size,
AvatarSize,
Shape, Shape,
PhysRepData, PhysRepData,
AddPhysRep, AddPhysRep,
@ -178,6 +179,8 @@ namespace OpenSim.Region.Physics.OdePlugin
public Object arg; public Object arg;
} }
public class OdeScene : PhysicsScene public class OdeScene : PhysicsScene
{ {
private readonly ILog m_log; private readonly ILog m_log;
@ -224,9 +227,6 @@ namespace OpenSim.Region.Physics.OdePlugin
// private IntPtr WaterHeightmapData = IntPtr.Zero; // private IntPtr WaterHeightmapData = IntPtr.Zero;
// private GCHandle WaterMapHandler = new GCHandle(); // private GCHandle WaterMapHandler = new GCHandle();
public float avPIDD = 2200f; // make it visible
public float avPIDP = 900f; // make it visible
private float avCapRadius = 0.37f;
private float avDensity = 3f; private float avDensity = 3f;
private float avMovementDivisorWalk = 1.3f; private float avMovementDivisorWalk = 1.3f;
private float avMovementDivisorRun = 0.8f; private float avMovementDivisorRun = 0.8f;
@ -299,9 +299,12 @@ namespace OpenSim.Region.Physics.OdePlugin
public IntPtr TopSpace; // the global space public IntPtr TopSpace; // the global space
public IntPtr ActiveSpace; // space for active prims public IntPtr ActiveSpace; // space for active prims
public IntPtr CharsSpace; // space for active prims
public IntPtr StaticSpace; // space for the static things around public IntPtr StaticSpace; // space for the static things around
public IntPtr GroundSpace; // space for ground public IntPtr GroundSpace; // space for ground
public IntPtr SharedRay;
// some speedup variables // some speedup variables
private int spaceGridMaxX; private int spaceGridMaxX;
private int spaceGridMaxY; private int spaceGridMaxY;
@ -361,7 +364,6 @@ namespace OpenSim.Region.Physics.OdePlugin
m_rayCastManager = new ODERayCastRequestManager(this); m_rayCastManager = new ODERayCastRequestManager(this);
lock (OdeLock) lock (OdeLock)
{ {
// Create the world and the first space // Create the world and the first space
@ -372,21 +374,25 @@ namespace OpenSim.Region.Physics.OdePlugin
// now the major subspaces // now the major subspaces
ActiveSpace = d.HashSpaceCreate(TopSpace); ActiveSpace = d.HashSpaceCreate(TopSpace);
CharsSpace = d.HashSpaceCreate(TopSpace);
StaticSpace = d.HashSpaceCreate(TopSpace); StaticSpace = d.HashSpaceCreate(TopSpace);
GroundSpace = d.HashSpaceCreate(TopSpace); GroundSpace = d.HashSpaceCreate(TopSpace);
} }
catch catch
{ {
// i must RtC#FM // i must RtC#FM
// i did!
} }
d.HashSpaceSetLevels(TopSpace, -2, 8); d.HashSpaceSetLevels(TopSpace, -2, 8);
d.HashSpaceSetLevels(ActiveSpace, -2, 8); d.HashSpaceSetLevels(ActiveSpace, -2, 8);
d.HashSpaceSetLevels(CharsSpace, -4, 3);
d.HashSpaceSetLevels(StaticSpace, -2, 8); d.HashSpaceSetLevels(StaticSpace, -2, 8);
d.HashSpaceSetLevels(GroundSpace, 0, 8); d.HashSpaceSetLevels(GroundSpace, 0, 8);
// demote to second level // demote to second level
d.SpaceSetSublevel(ActiveSpace, 1); d.SpaceSetSublevel(ActiveSpace, 1);
d.SpaceSetSublevel(CharsSpace, 1);
d.SpaceSetSublevel(StaticSpace, 1); d.SpaceSetSublevel(StaticSpace, 1);
d.SpaceSetSublevel(GroundSpace, 1); d.SpaceSetSublevel(GroundSpace, 1);
@ -396,11 +402,24 @@ namespace OpenSim.Region.Physics.OdePlugin
CollisionCategories.Phantom | CollisionCategories.Phantom |
CollisionCategories.VolumeDtc CollisionCategories.VolumeDtc
)); ));
d.GeomSetCollideBits(ActiveSpace, 0); d.GeomSetCollideBits(ActiveSpace, (uint)(CollisionCategories.Space |
CollisionCategories.Geom |
CollisionCategories.Character |
CollisionCategories.Phantom |
CollisionCategories.VolumeDtc
));
d.GeomSetCategoryBits(CharsSpace, (uint)(CollisionCategories.Space |
CollisionCategories.Geom |
CollisionCategories.Character |
CollisionCategories.Phantom |
CollisionCategories.VolumeDtc
));
d.GeomSetCollideBits(CharsSpace, 0);
d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space | d.GeomSetCategoryBits(StaticSpace, (uint)(CollisionCategories.Space |
CollisionCategories.Geom | CollisionCategories.Geom |
CollisionCategories.Land | // CollisionCategories.Land |
CollisionCategories.Water | // CollisionCategories.Water |
CollisionCategories.Phantom | CollisionCategories.Phantom |
CollisionCategories.VolumeDtc CollisionCategories.VolumeDtc
)); ));
@ -412,6 +431,8 @@ namespace OpenSim.Region.Physics.OdePlugin
contactgroup = d.JointGroupCreate(0); contactgroup = d.JointGroupCreate(0);
//contactgroup //contactgroup
SharedRay = d.CreateRay(TopSpace, 1.0f);
d.WorldSetAutoDisableFlag(world, false); d.WorldSetAutoDisableFlag(world, false);
} }
} }
@ -468,7 +489,6 @@ namespace OpenSim.Region.Physics.OdePlugin
avDensity = physicsconfig.GetFloat("av_density", avDensity); avDensity = physicsconfig.GetFloat("av_density", avDensity);
avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk); avMovementDivisorWalk = physicsconfig.GetFloat("av_movement_divisor_walk", avMovementDivisorWalk);
avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun); avMovementDivisorRun = physicsconfig.GetFloat("av_movement_divisor_run", avMovementDivisorRun);
avCapRadius = physicsconfig.GetFloat("av_capsule_radius", avCapRadius);
contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision); contactsPerCollision = physicsconfig.GetInt("contacts_per_collision", contactsPerCollision);
@ -494,7 +514,7 @@ namespace OpenSim.Region.Physics.OdePlugin
odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf);
GlobalContactsArray = GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf); GlobalContactsArray = Marshal.AllocHGlobal(maxContactsbeforedeath * d.Contact.unmanagedSizeOf);
m_materialContactsData[(int)Material.Stone].mu = 0.8f; m_materialContactsData[(int)Material.Stone].mu = 0.8f;
m_materialContactsData[(int)Material.Stone].bounce = 0.4f; m_materialContactsData[(int)Material.Stone].bounce = 0.4f;
@ -746,7 +766,7 @@ namespace OpenSim.Region.Physics.OdePlugin
if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc || if (d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc ||
d.GeomGetCategoryBits(g1) == (uint)CollisionCategories.VolumeDtc) d.GeomGetCategoryBits(g2) == (uint)CollisionCategories.VolumeDtc)
{ {
int cflags; int cflags;
unchecked unchecked
@ -801,26 +821,25 @@ namespace OpenSim.Region.Physics.OdePlugin
// get first contact // get first contact
d.ContactGeom curContact = new d.ContactGeom(); d.ContactGeom curContact = new d.ContactGeom();
if (!GetCurContactGeom(0, ref curContact)) if (!GetCurContactGeom(0, ref curContact))
return; return;
// for now it's the one with max depth
// do volume detection case
if ((p1.IsVolumeDtc || p2.IsVolumeDtc))
{
ContactPoint maxDepthContact = new ContactPoint( ContactPoint maxDepthContact = new ContactPoint(
new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z), new Vector3(curContact.pos.X, curContact.pos.Y, curContact.pos.Z),
new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z), new Vector3(curContact.normal.X, curContact.normal.Y, curContact.normal.Z),
curContact.depth curContact.depth, false
); );
// do volume detection case
if (
(p1.IsVolumeDtc || p2.IsVolumeDtc))
{
collision_accounting_events(p1, p2, maxDepthContact); collision_accounting_events(p1, p2, maxDepthContact);
return; return;
} }
// big messy collision analises // big messy collision analises
Vector3 normoverride = Vector3.Zero; //damm c#
float mu = 0; float mu = 0;
float bounce = 0; float bounce = 0;
float cfm = 0.0001f; float cfm = 0.0001f;
@ -831,36 +850,15 @@ namespace OpenSim.Region.Physics.OdePlugin
ContactData contactdata1 = new ContactData(0, 0, false); ContactData contactdata1 = new ContactData(0, 0, false);
ContactData contactdata2 = new ContactData(0, 0, false); ContactData contactdata2 = new ContactData(0, 0, false);
bool dop1foot = false; bool dop1ava = false;
bool dop2foot = false; bool dop2ava = false;
bool ignore = false; bool ignore = false;
bool AvanormOverride = false;
switch (p1.PhysicsActorType) switch (p1.PhysicsActorType)
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
{ {
dop1foot = true; dop1ava = true;
AvanormOverride = true;
Vector3 tmp = p2.Position - p1.Position;
normoverride = p2.Velocity - p1.Velocity;
mu = normoverride.LengthSquared();
if (mu > 1e-6)
{
mu = 1.0f / (float)Math.Sqrt(mu);
normoverride *= mu;
mu = Vector3.Dot(tmp, normoverride);
if (mu > 0)
normoverride *= -1;
}
else
{
tmp.Normalize();
normoverride = -tmp;
}
switch (p2.PhysicsActorType) switch (p2.PhysicsActorType)
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
@ -871,7 +869,6 @@ namespace OpenSim.Region.Physics.OdePlugin
case (int)ActorTypes.Prim: case (int)ActorTypes.Prim:
if (p2.Velocity.LengthSquared() > 0.0f) if (p2.Velocity.LengthSquared() > 0.0f)
p2.CollidingObj = true; p2.CollidingObj = true;
dop1foot = true;
break; break;
default: default:
@ -886,33 +883,8 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
case (int)ActorTypes.Agent: case (int)ActorTypes.Agent:
dop2ava = true;
dop2foot = true;
AvanormOverride = true;
Vector3 tmp = p2.Position - p1.Position;
normoverride = p2.Velocity - p1.Velocity;
mu = normoverride.LengthSquared();
if (mu > 1e-6)
{
mu = 1.0f / (float)Math.Sqrt(mu);
normoverride *= mu;
mu = Vector3.Dot(tmp, normoverride);
if (mu > 0)
normoverride *= -1;
}
else
{
tmp.Normalize();
normoverride = -tmp;
}
bounce = 0;
mu = 0;
cfm = 0.0001f;
dop2foot = true;
if (p1.Velocity.LengthSquared() > 0.0f) if (p1.Velocity.LengthSquared() > 0.0f)
p1.CollidingObj = true; p1.CollidingObj = true;
break; break;
@ -1017,166 +989,78 @@ namespace OpenSim.Region.Physics.OdePlugin
default: default:
break; break;
} }
if (ignore) if (ignore)
return; return;
d.ContactGeom maxContact = curContact;
// if (IgnoreNegSides && curContact.side1 < 0)
// maxContact.depth = float.MinValue;
d.ContactGeom minContact = curContact;
// if (IgnoreNegSides && curContact.side1 < 0)
// minContact.depth = float.MaxValue;
IntPtr Joint; IntPtr Joint;
bool FeetCollision = false;
int ncontacts = 0;
int i = 0; int i = 0;
int ncontacts = 0;
while (true) while (true)
{ {
if (m_global_contactcount >= maxContactsbeforedeath)
if (IgnoreNegSides && curContact.side1 < 0)
{
if (++i >= count)
break; break;
if (!GetCurContactGeom(i, ref curContact)) // if (!(IgnoreNegSides && curContact.side1 < 0))
break; {
} bool noskip = true;
else if (dop1ava)
{
if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact, ref FeetCollision)))
{ noskip = false;
if(dop1foot)
{
if (!(((OdeCharacter)p1).Collide(g1,false, ref curContact)))
{
if (++i >= count)
break;
else
continue;
} }
} else if (dop2ava)
else if(dop2foot)
{ {
if(!(((OdeCharacter) p2).Collide(g2,true,ref curContact))) if (!(((OdeCharacter)p2).Collide(g2,true, ref curContact, ref FeetCollision)))
{ noskip = false;
if (++i >= count)
break;
else
continue;
}
} }
/* if (noskip)
if (AvanormOverride)
{ {
if (curContact.depth > 0.3f) m_global_contactcount++;
{
if (dop1foot && (p1.Position.Z - curContact.pos.Z) > (p1.Size.Z - avCapRadius) * 0.5f)
p1.IsColliding = true;
if (dop2foot && (p2.Position.Z - curContact.pos.Z) > (p2.Size.Z - avCapRadius) * 0.5f)
p2.IsColliding = true;
curContact.normal.X = normoverride.X;
curContact.normal.Y = normoverride.Y;
curContact.normal.Z = normoverride.Z;
}
else
{
if (dop1foot)
{
float sz = p1.Size.Z;
Vector3 vtmp = p1.Position;
float ppos = curContact.pos.Z - vtmp.Z + (sz - avCapRadius) * 0.5f;
if (ppos > 0f)
{
if (!p1.Flying)
{
d.AABB aabb;
d.GeomGetAABB(g2, out aabb);
float tmp = vtmp.Z - sz * .18f;
if (aabb.MaxZ < tmp)
{
vtmp.X = curContact.pos.X - vtmp.X;
vtmp.Y = curContact.pos.Y - vtmp.Y;
vtmp.Z = -0.2f;
vtmp.Normalize();
curContact.normal.X = vtmp.X;
curContact.normal.Y = vtmp.Y;
curContact.normal.Z = vtmp.Z;
}
}
}
else
p1.IsColliding = true;
}
if (dop2foot)
{
float sz = p2.Size.Z;
Vector3 vtmp = p2.Position;
vtmp.Z -= sz * 0.5f;
vtmp.Z += 0.5f;
float ppos = vtmp.Z - curContact.pos.Z;
if (ppos > 0f)
{
if (!p2.Flying)
{
float tmp = vtmp.Z - sz * .18f;
vtmp.X = curContact.pos.X - vtmp.X;
vtmp.Y = curContact.pos.Y - vtmp.Y;
vtmp.Z = curContact.pos.Z - vtmp.Z;
vtmp.Normalize();
curContact.normal.X = vtmp.X;
curContact.normal.Y = vtmp.Y;
curContact.normal.Z = vtmp.Z;
}
}
// else
p2.IsColliding = true;
}
}
}
*/
ncontacts++; ncontacts++;
Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale); Joint = CreateContacJoint(ref curContact, mu, bounce, cfm, erpscale, dscale);
d.JointAttach(Joint, b1, b2); d.JointAttach(Joint, b1, b2);
if (++m_global_contactcount >= maxContactsbeforedeath) if (curContact.depth > maxContact.depth)
break; maxContact = curContact;
if (curContact.depth < minContact.depth)
minContact = curContact;
}
}
if (++i >= count) if (++i >= count)
break; break;
if (!GetCurContactGeom(i, ref curContact)) if (!GetCurContactGeom(i, ref curContact))
break; break;
if (curContact.depth > maxDepthContact.PenetrationDepth)
{
maxDepthContact.Position.X = curContact.pos.X;
maxDepthContact.Position.Y = curContact.pos.Y;
maxDepthContact.Position.Z = curContact.pos.Z;
maxDepthContact.SurfaceNormal.X = curContact.normal.X;
maxDepthContact.SurfaceNormal.Y = curContact.normal.Y;
maxDepthContact.SurfaceNormal.Z = curContact.normal.Z;
maxDepthContact.PenetrationDepth = curContact.depth;
}
}
} }
if (ncontacts > 0) if (ncontacts > 0)
collision_accounting_events(p1, p2, maxDepthContact);
/*
if (notskipedcount > geomContactPointsStartthrottle)
{ {
// If there are more then 3 contact points, it's likely ContactPoint maxDepthContact = new ContactPoint(
// that we've got a pile of objects, so ... new Vector3(maxContact.pos.X, maxContact.pos.Y, maxContact.pos.Z),
// We don't want to send out hundreds of terse updates over and over again new Vector3(minContact.normal.X, minContact.normal.Y, minContact.normal.Z),
// so lets throttle them and send them again after it's somewhat sorted out. maxContact.depth, FeetCollision
this needs checking so out for now );
if (b1 != IntPtr.Zero) collision_accounting_events(p1, p2, maxDepthContact);
p1.ThrottleUpdates = true;
if (b2 != IntPtr.Zero)
p2.ThrottleUpdates = true;
} }
*/
} }
private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact) private void collision_accounting_events(PhysicsActor p1, PhysicsActor p2, ContactPoint contact)
@ -1267,10 +1151,10 @@ namespace OpenSim.Region.Physics.OdePlugin
// chr.CollidingGround = false; not done here // chr.CollidingGround = false; not done here
chr.CollidingObj = false; chr.CollidingObj = false;
// do colisions with static space // do colisions with static space
d.SpaceCollide2(StaticSpace, chr.topbox, IntPtr.Zero, nearCallback); d.SpaceCollide2(chr.collider, StaticSpace, IntPtr.Zero, nearCallback);
d.SpaceCollide2(StaticSpace, chr.midbox, IntPtr.Zero, nearCallback);
d.SpaceCollide2(StaticSpace, chr.feetbox, IntPtr.Zero, nearCallback); // chars with chars
d.SpaceCollide2(StaticSpace, chr.bonebox, IntPtr.Zero, nearCallback); d.SpaceCollide(CharsSpace, IntPtr.Zero, nearCallback);
// no coll with gnd // no coll with gnd
} }
} }
@ -1312,12 +1196,21 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space"); m_log.Warn("[PHYSICS]: Unable to collide Active prim to static space");
} }
} }
// finally colide active things amoung them // colide active amoung them
try try
{ {
d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback); d.SpaceCollide(ActiveSpace, IntPtr.Zero, nearCallback);
} }
catch (AccessViolationException) catch (AccessViolationException)
{
m_log.Warn("[PHYSICS]: Unable to collide Active with Characters space");
}
// and with chars
try
{
d.SpaceCollide2(CharsSpace,ActiveSpace, IntPtr.Zero, nearCallback);
}
catch (AccessViolationException)
{ {
m_log.Warn("[PHYSICS]: Unable to collide in Active space"); m_log.Warn("[PHYSICS]: Unable to collide in Active space");
} }
@ -1357,13 +1250,13 @@ namespace OpenSim.Region.Physics.OdePlugin
#region Add/Remove Entities #region Add/Remove Entities
public override PhysicsActor AddAvatar(string avName, Vector3 position, Vector3 size, bool isFlying) public override PhysicsActor AddAvatar(uint localID, string avName, Vector3 position, Vector3 size, float feetOffset, bool isFlying)
{ {
Vector3 pos; Vector3 pos;
pos.X = position.X; pos.X = position.X;
pos.Y = position.Y; pos.Y = position.Y;
pos.Z = position.Z; pos.Z = position.Z;
OdeCharacter newAv = new OdeCharacter(avName, this, pos, size, avPIDD, avPIDP, avDensity, avMovementDivisorWalk, avMovementDivisorRun); OdeCharacter newAv = new OdeCharacter(localID,avName, this, pos, size, feetOffset, avDensity, avMovementDivisorWalk, avMovementDivisorRun);
newAv.Flying = isFlying; newAv.Flying = isFlying;
newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset; newAv.MinimumGroundFlightOffset = minimumGroundFlightOffset;
@ -1806,7 +1699,7 @@ namespace OpenSim.Region.Physics.OdePlugin
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor != null) if (actor != null)
actor.Move(ODE_STEPSIZE, defects); actor.Move(defects);
} }
if (defects.Count != 0) if (defects.Count != 0)
{ {
@ -2817,5 +2710,17 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
return new List<ContactResult>(); return new List<ContactResult>();
} }
public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
{
Util.FireAndForget( delegate
{
ODESitAvatar sitAvatar = new ODESitAvatar(this, m_rayCastManager);
if(sitAvatar != null)
sitAvatar.Sit(actor, AbsolutePosition, CameraPosition, offset, AvatarSize, PhysicsSitResponse);
});
return 1;
}
} }
} }

View File

@ -317,8 +317,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
comms.DeleteListener(itemID); comms.DeleteListener(itemID);
IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>(); IXMLRPC xmlrpc = engine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
xmlrpc.DeleteChannels(itemID); xmlrpc.DeleteChannels(itemID);
xmlrpc.CancelSRDRequests(itemID); xmlrpc.CancelSRDRequests(itemID);
}
// Remove Sensors // Remove Sensors
m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID); m_SensorRepeat[engine].UnSetSenseRepeaterEvents(localID, itemID);

View File

@ -6384,7 +6384,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
else else
{ {
agentSize = new LSL_Vector(0.45, 0.6, avatar.Appearance.AvatarHeight); // agentSize = new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight);
Vector3 s = avatar.Appearance.AvatarSize;
agentSize = new LSL_Vector(s.X, s.Y, s.Z);
} }
return agentSize; return agentSize;
} }
@ -8591,8 +8593,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// and standing avatar since server 1.36 // and standing avatar since server 1.36
LSL_Vector lower; LSL_Vector lower;
LSL_Vector upper; LSL_Vector upper;
Vector3 box = presence.Appearance.AvatarBoxSize * 0.5f;
if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID if (presence.Animator.Animations.ImplicitDefaultAnimation.AnimID
== DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"]) == DefaultAvatarAnimations.AnimsUUID["SIT_GROUND_CONSTRAINED"])
/*
{ {
// This is for ground sitting avatars // This is for ground sitting avatars
float height = presence.Appearance.AvatarHeight / 2.66666667f; float height = presence.Appearance.AvatarHeight / 2.66666667f;
@ -8610,6 +8616,18 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
// Adjust to the documented error offsets (see LSL Wiki) // Adjust to the documented error offsets (see LSL Wiki)
lower += new LSL_Vector(0.05f, 0.05f, 0.05f); lower += new LSL_Vector(0.05f, 0.05f, 0.05f);
upper -= new LSL_Vector(0.05f, 0.05f, 0.05f); upper -= new LSL_Vector(0.05f, 0.05f, 0.05f);
*/
{
// This is for ground sitting avatars TODO!
lower = new LSL_Vector(-box.X - 0.1125, -box.Y, box.Z * -1.0f);
upper = new LSL_Vector(box.X + 0.1125, box.Y, box.Z * -1.0f);
}
else
{
// This is for standing/flying avatars
lower = new LSL_Vector(-box.X, -box.Y, -box.Z);
upper = new LSL_Vector(box.X, box.Y, box.Z);
}
if (lower.x > upper.x) if (lower.x > upper.x)
lower.x = upper.x; lower.x = upper.x;
@ -12529,7 +12547,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
} }
bool result = money.ObjectGiveMoney( bool result = money.ObjectGiveMoney(
m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount, txn); m_host.ParentGroup.RootPart.UUID, m_host.ParentGroup.RootPart.OwnerID, toID, amount,UUID.Zero);
if (result) if (result)
{ {
@ -12931,7 +12949,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
case (int)ScriptBaseClass.PRIM_SIZE: case (int)ScriptBaseClass.PRIM_SIZE:
// as in llGetAgentSize above // as in llGetAgentSize above
res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight)); // res.Add(new LSL_Vector(0.45f, 0.6f, avatar.Appearance.AvatarHeight));
Vector3 s = avatar.Appearance.AvatarSize;
res.Add(new LSL_Vector(s.X, s.Y, s.Z));
break; break;
case (int)ScriptBaseClass.PRIM_ROTATION: case (int)ScriptBaseClass.PRIM_ROTATION:

View File

@ -201,7 +201,13 @@ namespace OpenSim.Services.Interfaces
appearance.Serial = Int32.Parse(Data["Serial"]); appearance.Serial = Int32.Parse(Data["Serial"]);
if (Data.ContainsKey("AvatarHeight")) if (Data.ContainsKey("AvatarHeight"))
appearance.AvatarHeight = float.Parse(Data["AvatarHeight"]); {
float h = float.Parse(Data["AvatarHeight"]);
if( h == 0f)
h = 1.9f;
appearance.SetSize(new Vector3(0.45f, 0.6f, h ));
// appearance.AvatarHeight = float.Parse(Data["AvatarHeight"]);
}
// Legacy Wearables // Legacy Wearables
if (Data.ContainsKey("BodyItem")) if (Data.ContainsKey("BodyItem"))
@ -339,6 +345,7 @@ namespace OpenSim.Services.Interfaces
appearance.Wearables[AvatarWearable.EYES].Wear( appearance.Wearables[AvatarWearable.EYES].Wear(
AvatarWearable.DefaultWearables[ AvatarWearable.DefaultWearables[
AvatarWearable.EYES][0]); AvatarWearable.EYES][0]);
} }
catch catch
{ {

View File

@ -0,0 +1,17 @@
////////////////////////////////////////////////////////////////
//
// (c) 2009, 2010 Careminster Limited and Melanie Thielker
//
// All rights reserved
//
using System;
using Nini.Config;
namespace OpenSim.Services.Interfaces
{
public interface IBakedTextureService
{
string Get(string id);
void Store(string id, string data);
}
}