Merge branch 'avination' into careminster
commit
083ac92b34
|
@ -117,7 +117,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
private void BakedTextureUploaded(UUID assetID, byte[] data)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
|
m_log.DebugFormat("[UPLOAD BAKED TEXTURE HANDLER]: Received baked texture {0}", assetID.ToString());
|
||||||
|
|
||||||
AssetBase asset;
|
AssetBase asset;
|
||||||
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
asset = new AssetBase(assetID, "Baked Texture", (sbyte)AssetType.Texture, m_HostCapsObj.AgentID.ToString());
|
||||||
|
|
|
@ -66,7 +66,7 @@ namespace OpenSim.Framework
|
||||||
protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
|
protected Vector3 m_avatarBoxSize = new Vector3(0.45f, 0.6f, 1.9f);
|
||||||
protected float m_avatarFeetOffset = 0;
|
protected float m_avatarFeetOffset = 0;
|
||||||
protected float m_avatarAnimOffset = 0;
|
protected float m_avatarAnimOffset = 0;
|
||||||
|
protected WearableCacheItem[] cacheitems;
|
||||||
public virtual int Serial
|
public virtual int Serial
|
||||||
{
|
{
|
||||||
get { return m_serial; }
|
get { return m_serial; }
|
||||||
|
@ -116,6 +116,12 @@ namespace OpenSim.Framework
|
||||||
set { m_avatarHeight = value; }
|
set { m_avatarHeight = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public virtual WearableCacheItem[] WearableCacheItems
|
||||||
|
{
|
||||||
|
get { return cacheitems; }
|
||||||
|
set { cacheitems = value; }
|
||||||
|
}
|
||||||
|
|
||||||
public AvatarAppearance()
|
public AvatarAppearance()
|
||||||
{
|
{
|
||||||
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
|
// m_log.WarnFormat("[AVATAR APPEARANCE]: create empty appearance");
|
||||||
|
|
|
@ -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, Vector3 AvSize);
|
public delegate void SetAppearance(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 AvSize, WearableCacheItem[] CacheItems);
|
||||||
|
|
||||||
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
public delegate void StartAnim(IClientAPI remoteClient, UUID animID);
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,7 @@ namespace OpenSim.Framework
|
||||||
void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
|
void UpdateLandProperties(LandUpdateArgs args, IClientAPI remote_client);
|
||||||
bool IsEitherBannedOrRestricted(UUID avatar);
|
bool IsEitherBannedOrRestricted(UUID avatar);
|
||||||
bool IsBannedFromLand(UUID avatar);
|
bool IsBannedFromLand(UUID avatar);
|
||||||
|
bool CanBeOnThisLand(UUID avatar, float posHeight);
|
||||||
bool IsRestrictedFromLand(UUID avatar);
|
bool IsRestrictedFromLand(UUID avatar);
|
||||||
bool IsInLandAccessList(UUID avatar);
|
bool IsInLandAccessList(UUID avatar);
|
||||||
void SendLandUpdateToClient(IClientAPI remote_client);
|
void SendLandUpdateToClient(IClientAPI remote_client);
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework
|
||||||
|
{
|
||||||
|
public class WearableCacheItem
|
||||||
|
{
|
||||||
|
public uint TextureIndex { get; set; }
|
||||||
|
public UUID CacheId { get; set; }
|
||||||
|
public UUID TextureID { get; set; }
|
||||||
|
}
|
||||||
|
}
|
|
@ -461,6 +461,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
|
|
||||||
public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
|
public bool SendLogoutPacketWhenClosing { set { m_SendLogoutPacketWhenClosing = value; } }
|
||||||
|
|
||||||
|
|
||||||
#endregion Properties
|
#endregion Properties
|
||||||
|
|
||||||
// ~LLClientView()
|
// ~LLClientView()
|
||||||
|
@ -585,6 +586,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// Disable UDP handling for this client
|
// Disable UDP handling for this client
|
||||||
m_udpClient.Shutdown();
|
m_udpClient.Shutdown();
|
||||||
|
|
||||||
|
|
||||||
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
|
//m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
|
||||||
//GC.Collect();
|
//GC.Collect();
|
||||||
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
|
//m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
|
||||||
|
@ -2750,8 +2752,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
|
req.AssetInf.ID, req.AssetInf.Metadata.ContentType);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
int WearableOut = 0;
|
||||||
|
bool isWearable = false;
|
||||||
|
|
||||||
|
if (req.AssetInf != null)
|
||||||
|
isWearable =
|
||||||
|
((AssetType) req.AssetInf.Type ==
|
||||||
|
AssetType.Bodypart || (AssetType) req.AssetInf.Type == AssetType.Clothing);
|
||||||
|
|
||||||
|
|
||||||
|
//m_log.Debug("sending asset " + req.RequestAssetID + ", iswearable: " + isWearable);
|
||||||
|
|
||||||
|
|
||||||
|
//if (isWearable)
|
||||||
|
// m_log.Debug((AssetType)req.AssetInf.Type);
|
||||||
|
|
||||||
//m_log.Debug("sending asset " + req.RequestAssetID);
|
|
||||||
TransferInfoPacket Transfer = new TransferInfoPacket();
|
TransferInfoPacket Transfer = new TransferInfoPacket();
|
||||||
Transfer.TransferInfo.ChannelType = 2;
|
Transfer.TransferInfo.ChannelType = 2;
|
||||||
Transfer.TransferInfo.Status = 0;
|
Transfer.TransferInfo.Status = 0;
|
||||||
|
@ -2773,7 +2788,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
|
Transfer.TransferInfo.Size = req.AssetInf.Data.Length;
|
||||||
Transfer.TransferInfo.TransferID = req.TransferRequestID;
|
Transfer.TransferInfo.TransferID = req.TransferRequestID;
|
||||||
Transfer.Header.Zerocoded = true;
|
Transfer.Header.Zerocoded = true;
|
||||||
OutPacket(Transfer, ThrottleOutPacketType.Asset);
|
OutPacket(Transfer, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
|
||||||
|
|
||||||
if (req.NumPackets == 1)
|
if (req.NumPackets == 1)
|
||||||
{
|
{
|
||||||
|
@ -2784,7 +2799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
TransferPacket.TransferData.Data = req.AssetInf.Data;
|
TransferPacket.TransferData.Data = req.AssetInf.Data;
|
||||||
TransferPacket.TransferData.Status = 1;
|
TransferPacket.TransferData.Status = 1;
|
||||||
TransferPacket.Header.Zerocoded = true;
|
TransferPacket.Header.Zerocoded = true;
|
||||||
OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
|
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2817,7 +2832,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
TransferPacket.TransferData.Status = 1;
|
TransferPacket.TransferData.Status = 1;
|
||||||
}
|
}
|
||||||
TransferPacket.Header.Zerocoded = true;
|
TransferPacket.Header.Zerocoded = true;
|
||||||
OutPacket(TransferPacket, ThrottleOutPacketType.Asset);
|
OutPacket(TransferPacket, isWearable ? ThrottleOutPacketType.State : ThrottleOutPacketType.Asset);
|
||||||
|
|
||||||
processedLength += chunkSize;
|
processedLength += chunkSize;
|
||||||
packetNumber++;
|
packetNumber++;
|
||||||
|
@ -3572,24 +3587,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
|
aw.WearableData = new AgentWearablesUpdatePacket.WearableDataBlock[count];
|
||||||
AgentWearablesUpdatePacket.WearableDataBlock awb;
|
AgentWearablesUpdatePacket.WearableDataBlock awb;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
|
|
||||||
for (int i = 0; i < wearables.Length; i++)
|
for (int i = 0; i < wearables.Length; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < wearables[i].Count; j++)
|
for (int j = 0; j < wearables[i].Count; j++)
|
||||||
{
|
{
|
||||||
awb = new AgentWearablesUpdatePacket.WearableDataBlock();
|
awb = new AgentWearablesUpdatePacket.WearableDataBlock();
|
||||||
awb.WearableType = (byte)i;
|
awb.WearableType = (byte) i;
|
||||||
awb.AssetID = wearables[i][j].AssetID;
|
awb.AssetID = wearables[i][j].AssetID;
|
||||||
awb.ItemID = wearables[i][j].ItemID;
|
awb.ItemID = wearables[i][j].ItemID;
|
||||||
aw.WearableData[idx] = awb;
|
aw.WearableData[idx] = awb;
|
||||||
idx++;
|
idx++;
|
||||||
|
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
|
// "[APPEARANCE]: Sending wearable item/asset {0} {1} (index {2}) for {3}",
|
||||||
// awb.ItemID, awb.AssetID, i, Name);
|
// awb.ItemID, awb.AssetID, i, Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OutPacket(aw, ThrottleOutPacketType.Task);
|
OutPacket(aw, ThrottleOutPacketType.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
|
public void SendAppearance(UUID agentID, byte[] visualParams, byte[] textureEntry)
|
||||||
|
@ -3614,7 +3630,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
avp.Sender.IsTrial = false;
|
avp.Sender.IsTrial = false;
|
||||||
avp.Sender.ID = agentID;
|
avp.Sender.ID = agentID;
|
||||||
//m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
|
//m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString());
|
||||||
OutPacket(avp, ThrottleOutPacketType.Task);
|
OutPacket(avp, ThrottleOutPacketType.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
|
public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs)
|
||||||
|
@ -6282,12 +6298,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
byte[] visualparams = new byte[appear.VisualParam.Length];
|
byte[] visualparams = new byte[appear.VisualParam.Length];
|
||||||
for (int i = 0; i < appear.VisualParam.Length; i++)
|
for (int i = 0; i < appear.VisualParam.Length; i++)
|
||||||
visualparams[i] = appear.VisualParam[i].ParamValue;
|
visualparams[i] = appear.VisualParam[i].ParamValue;
|
||||||
|
//var b = appear.WearableData[0];
|
||||||
|
|
||||||
Primitive.TextureEntry te = null;
|
Primitive.TextureEntry te = null;
|
||||||
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,avSize);
|
WearableCacheItem[] cacheitems = new WearableCacheItem[appear.WearableData.Length];
|
||||||
|
for (int i=0; i<appear.WearableData.Length;i++)
|
||||||
|
cacheitems[i] = new WearableCacheItem(){CacheId = appear.WearableData[i].CacheID,TextureIndex=Convert.ToUInt32(appear.WearableData[i].TextureIndex)};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
handlerSetAppearance(sender, te, visualparams,avSize, cacheitems);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -7798,6 +7821,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// surrounding scene
|
// surrounding scene
|
||||||
if ((ImageType)block.Type == ImageType.Baked)
|
if ((ImageType)block.Type == ImageType.Baked)
|
||||||
args.Priority *= 2.0f;
|
args.Priority *= 2.0f;
|
||||||
|
int wearableout = 0;
|
||||||
|
|
||||||
ImageManager.EnqueueReq(args);
|
ImageManager.EnqueueReq(args);
|
||||||
}
|
}
|
||||||
|
@ -11688,6 +11712,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
if (cachedtex.AgentData.SessionID != SessionId)
|
if (cachedtex.AgentData.SessionID != SessionId)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
// TODO: don't create new blocks if recycling an old packet
|
// TODO: don't create new blocks if recycling an old packet
|
||||||
cachedresp.AgentData.AgentID = AgentId;
|
cachedresp.AgentData.AgentID = AgentId;
|
||||||
cachedresp.AgentData.SessionID = m_sessionId;
|
cachedresp.AgentData.SessionID = m_sessionId;
|
||||||
|
@ -11696,6 +11721,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
cachedresp.WearableData =
|
cachedresp.WearableData =
|
||||||
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
|
new AgentCachedTextureResponsePacket.WearableDataBlock[cachedtex.WearableData.Length];
|
||||||
|
|
||||||
|
//IAvatarFactoryModule fac = m_scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||||
|
// var item = fac.GetBakedTextureFaces(AgentId);
|
||||||
|
//WearableCacheItem[] items = fac.GetCachedItems(AgentId);
|
||||||
|
|
||||||
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
|
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
|
||||||
if (cache == null)
|
if (cache == null)
|
||||||
{
|
{
|
||||||
|
@ -11703,7 +11732,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
cachedresp.WearableData[i].HostName = new byte[0];
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11713,10 +11742,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
{
|
{
|
||||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||||
if(cache.Check(cachedtex.WearableData[i].ID.ToString()))
|
|
||||||
|
|
||||||
|
|
||||||
|
if (cache.Check(cachedtex.WearableData[i].ID.ToString()))
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
|
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
else
|
else
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
cachedresp.WearableData[i].HostName = new byte[0];
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,18 +140,18 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="sp"></param>
|
/// <param name="sp"></param>
|
||||||
/// <param name="texture"></param>
|
/// <param name="texture"></param>
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance)
|
public void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems)
|
||||||
{
|
{
|
||||||
SetAppearance(sp, appearance.Texture, appearance.VisualParams);
|
SetAppearance(sp, appearance.Texture, appearance.VisualParams, cacheItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize)
|
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
|
||||||
{
|
{
|
||||||
float oldoff = sp.Appearance.AvatarFeetOffset;
|
float oldoff = sp.Appearance.AvatarFeetOffset;
|
||||||
Vector3 oldbox = sp.Appearance.AvatarBoxSize;
|
Vector3 oldbox = sp.Appearance.AvatarBoxSize;
|
||||||
|
|
||||||
SetAppearance(sp, textureEntry, visualParams);
|
SetAppearance(sp, textureEntry, visualParams, cacheItems);
|
||||||
sp.Appearance.SetSize(avSize);
|
sp.Appearance.SetSize(avSize);
|
||||||
|
|
||||||
float off = sp.Appearance.AvatarFeetOffset;
|
float off = sp.Appearance.AvatarFeetOffset;
|
||||||
|
@ -166,7 +166,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
/// <param name="sp"></param>
|
/// <param name="sp"></param>
|
||||||
/// <param name="texture"></param>
|
/// <param name="texture"></param>
|
||||||
/// <param name="visualParam"></param>
|
/// <param name="visualParam"></param>
|
||||||
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams)
|
public void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat(
|
// m_log.DebugFormat(
|
||||||
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
// "[AVFACTORY]: start SetAppearance for {0}, te {1}, visualParams {2}",
|
||||||
|
@ -205,11 +205,14 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
// ((ScenePresence)sp).SetSize(box,off);
|
// ((ScenePresence)sp).SetSize(box,off);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
//if (cacheItems.Length > 0)
|
||||||
|
//{
|
||||||
|
sp.Appearance.WearableCacheItems = cacheItems;
|
||||||
|
//}
|
||||||
// Process the baked texture array
|
// Process the baked texture array
|
||||||
if (textureEntry != null)
|
if (textureEntry != null)
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
m_log.DebugFormat("[AVFACTORY]: Received texture update for {0} {1}", sp.Name, sp.UUID);
|
||||||
|
|
||||||
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
// WriteBakedTexturesReport(sp, m_log.DebugFormat);
|
||||||
|
|
||||||
|
@ -278,6 +281,19 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
return GetBakedTextureFaces(sp);
|
return GetBakedTextureFaces(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public WearableCacheItem[] GetCachedItems(UUID agentId)
|
||||||
|
{
|
||||||
|
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||||
|
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
|
||||||
|
|
||||||
|
WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
|
||||||
|
//foreach (WearableCacheItem item in items)
|
||||||
|
//{
|
||||||
|
|
||||||
|
//}
|
||||||
|
return items;
|
||||||
|
}
|
||||||
|
|
||||||
public bool SaveBakedTextures(UUID agentId)
|
public bool SaveBakedTextures(UUID agentId)
|
||||||
{
|
{
|
||||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||||
|
@ -660,12 +676,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, Vector3 avSize)
|
private void Client_OnSetAppearance(IClientAPI client, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
|
||||||
{
|
{
|
||||||
// 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,avSize);
|
SetAppearance(sp, textureEntry, visualParams,avSize, cacheItems);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
for (byte i = 0; i < visualParams.Length; i++)
|
for (byte i = 0; i < visualParams.Length; i++)
|
||||||
visualParams[i] = i;
|
visualParams[i] = i;
|
||||||
|
|
||||||
afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams);
|
afm.SetAppearance(sp, new Primitive.TextureEntry(TestHelpers.ParseTail(0x10)), visualParams, new WearableCacheItem[0]);
|
||||||
|
|
||||||
// TODO: Check baked texture
|
// TODO: Check baked texture
|
||||||
Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
|
Assert.AreEqual(visualParams, sp.Appearance.VisualParams);
|
||||||
|
@ -102,7 +102,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
|
Primitive.TextureEntryFace eyesFace = bakedTextureEntry.CreateFace(eyesFaceIndex);
|
||||||
eyesFace.TextureID = eyesTextureId;
|
eyesFace.TextureID = eyesTextureId;
|
||||||
|
|
||||||
afm.SetAppearance(sp, bakedTextureEntry, visualParams);
|
afm.SetAppearance(sp, bakedTextureEntry, visualParams, new WearableCacheItem[0]);
|
||||||
afm.SaveBakedTextures(userId);
|
afm.SaveBakedTextures(userId);
|
||||||
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
|
// Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = afm.GetBakedTextureFaces(userId);
|
||||||
|
|
||||||
|
|
|
@ -442,6 +442,19 @@ namespace OpenSim.Region.CoreModules.World.Land
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool CanBeOnThisLand(UUID avatar, float posHeight)
|
||||||
|
{
|
||||||
|
if (posHeight < LandChannel.BAN_LINE_SAFETY_HIEGHT && IsBannedFromLand(avatar))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (IsRestrictedFromLand(avatar))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool HasGroupAccess(UUID avatar)
|
public bool HasGroupAccess(UUID avatar)
|
||||||
{
|
{
|
||||||
if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
|
if (LandData.GroupID != UUID.Zero && (LandData.Flags & (uint)ParcelFlags.UseAccessGroup) == (uint)ParcelFlags.UseAccessGroup)
|
||||||
|
|
|
@ -35,8 +35,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
|
||||||
public interface IAvatarFactoryModule
|
public interface IAvatarFactoryModule
|
||||||
{
|
{
|
||||||
void SetAppearance(IScenePresence sp, AvatarAppearance appearance);
|
void SetAppearance(IScenePresence sp, AvatarAppearance appearance, WearableCacheItem[] cacheItems);
|
||||||
void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams);
|
void SetAppearance(IScenePresence sp, Primitive.TextureEntry textureEntry, byte[] visualParams, WearableCacheItem[] cacheItems);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send the appearance of an avatar to others in the scene.
|
/// Send the appearance of an avatar to others in the scene.
|
||||||
|
@ -52,6 +52,8 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
|
/// <returns>An empty list if this agent has no baked textures (e.g. because it's a child agent)</returns>
|
||||||
Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
|
Dictionary<BakeType, Primitive.TextureEntryFace> GetBakedTextureFaces(UUID agentId);
|
||||||
|
|
||||||
|
|
||||||
|
WearableCacheItem[] GetCachedItems(UUID agentId);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Save the baked textures for the given agent permanently in the asset database.
|
/// Save the baked textures for the given agent permanently in the asset database.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -923,6 +923,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
|
m_scene.EventManager.TriggerSetRootAgentScene(m_uuid, m_scene);
|
||||||
|
|
||||||
|
UUID groupUUID = UUID.Zero;
|
||||||
|
string GroupName = string.Empty;
|
||||||
|
ulong groupPowers = 0;
|
||||||
|
|
||||||
|
// ----------------------------------
|
||||||
|
// Previous Agent Difference - AGNI sends an unsolicited AgentDataUpdate upon root agent status
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (gm != null)
|
||||||
|
{
|
||||||
|
groupUUID = ControllingClient.ActiveGroupId;
|
||||||
|
GroupRecord record = gm.GetGroupRecord(groupUUID);
|
||||||
|
if (record != null)
|
||||||
|
GroupName = record.GroupName;
|
||||||
|
GroupMembershipData groupMembershipData = gm.GetMembershipData(groupUUID, m_uuid);
|
||||||
|
if (groupMembershipData != null)
|
||||||
|
groupPowers = groupMembershipData.GroupPowers;
|
||||||
|
}
|
||||||
|
ControllingClient.SendAgentDataUpdate(m_uuid, groupUUID, Firstname, Lastname, groupPowers, GroupName,
|
||||||
|
Grouptitle);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.Debug("[AGENTUPDATE]: " + e.ToString());
|
||||||
|
}
|
||||||
|
// ------------------------------------
|
||||||
|
|
||||||
if (ParentID == 0)
|
if (ParentID == 0)
|
||||||
{
|
{
|
||||||
// Moved this from SendInitialData to ensure that Appearance is initialized
|
// Moved this from SendInitialData to ensure that Appearance is initialized
|
||||||
|
@ -1961,7 +1988,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
|
// m_log.DebugFormat("[SCENE PRESENCE]: Resetting move to target for {0}", Name);
|
||||||
|
|
||||||
MovingToTarget = false;
|
MovingToTarget = false;
|
||||||
MoveToPositionTarget = Vector3.Zero;
|
// MoveToPositionTarget = Vector3.Zero;
|
||||||
|
m_forceToApply = null; // cancel possible last action
|
||||||
|
|
||||||
// We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
|
// We need to reset the control flag as the ScenePresenceAnimator uses this to determine the correct
|
||||||
// resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
|
// resting animation (e.g. hover or stand). NPCs don't have a client that will quickly reset this flag.
|
||||||
|
@ -2080,9 +2108,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (part == null)
|
if (part == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// TODO: determine position to sit at based on scene geometry; don't trust offset from client
|
|
||||||
// see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
|
|
||||||
|
|
||||||
if (PhysicsActor != null)
|
if (PhysicsActor != null)
|
||||||
m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
|
m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
|
||||||
|
|
||||||
|
@ -2101,25 +2126,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
|
if (PhysicsSit(part,offset)) // physics engine
|
||||||
// {
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
|
|
||||||
// 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;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
|
if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
|
||||||
{
|
{
|
||||||
|
@ -2127,22 +2135,22 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
|
AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
|
||||||
canSit = true;
|
canSit = true;
|
||||||
}
|
}
|
||||||
// else
|
|
||||||
// {
|
|
||||||
// m_log.DebugFormat(
|
|
||||||
// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
|
|
||||||
// Name, part.Name, part.LocalId);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canSit)
|
if (canSit)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (PhysicsActor != null)
|
if (PhysicsActor != null)
|
||||||
{
|
{
|
||||||
// We can remove the physicsActor until they stand up.
|
// We can remove the physicsActor until they stand up.
|
||||||
RemoveFromPhysicalScene();
|
RemoveFromPhysicalScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MovingToTarget)
|
||||||
|
ResetMoveToTarget();
|
||||||
|
|
||||||
|
Velocity = Vector3.Zero;
|
||||||
|
|
||||||
part.AddSittingAvatar(UUID);
|
part.AddSittingAvatar(UUID);
|
||||||
|
|
||||||
cameraAtOffset = part.GetCameraAtOffset();
|
cameraAtOffset = part.GetCameraAtOffset();
|
||||||
|
@ -2179,14 +2187,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
m_requestedSitTargetID = part.LocalId;
|
m_requestedSitTargetID = part.LocalId;
|
||||||
m_requestedSitTargetUUID = targetID;
|
m_requestedSitTargetUUID = targetID;
|
||||||
|
|
||||||
// m_log.DebugFormat("[SIT]: Client requested Sit Position: {0}", offset);
|
|
||||||
|
|
||||||
if (m_scene.PhysicsScene.SupportsRayCast())
|
|
||||||
{
|
|
||||||
//m_scene.PhysicsScene.RaycastWorld(Vector3.Zero,Vector3.Zero, 0.01f,new RaycastCallback());
|
|
||||||
//SitRayCastAvatarPosition(part);
|
|
||||||
//return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -2196,28 +2196,87 @@ 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)
|
// returns false if does not suport so older sit can be tried
|
||||||
|
public bool PhysicsSit(SceneObjectPart part, Vector3 offset)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (status < 0)
|
|
||||||
{
|
|
||||||
ControllingClient.SendAlertMessage("Sit position no longer exists");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
|
|
||||||
if (part == null || part.ParentGroup.IsAttachment)
|
if (part == null || part.ParentGroup.IsAttachment)
|
||||||
{
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_scene.PhysicsScene == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (part.PhysActor == null)
|
||||||
|
{
|
||||||
|
// none physcis shape
|
||||||
|
if (part.PhysicsShapeType == (byte)PhysicsShapeType.None)
|
||||||
|
ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
|
||||||
|
else
|
||||||
|
{ // non physical phantom TODO
|
||||||
|
ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// not doing autopilot
|
||||||
|
m_requestedSitTargetID = 0;
|
||||||
|
|
||||||
|
if (m_scene.PhysicsScene.SitAvatar(part.PhysActor, AbsolutePosition, CameraPosition, offset, new Vector3(0.35f, 0, 0.65f), PhysicsSitResponse) != 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private bool CanEnterLandPosition(Vector3 testPos)
|
||||||
|
{
|
||||||
|
ILandObject land = m_scene.LandChannel.GetLandObject(testPos.X, testPos.Y);
|
||||||
|
|
||||||
|
if (land == null || land.LandData.Name == "NO_LAND")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return land.CanBeOnThisLand(UUID,testPos.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// status
|
||||||
|
// < 0 ignore
|
||||||
|
// 0 bad sit spot
|
||||||
|
public void PhysicsSitResponse(int status, uint partID, Vector3 offset, Quaternion Orientation)
|
||||||
|
{
|
||||||
|
if (status < 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (status == 0)
|
||||||
|
{
|
||||||
|
ControllingClient.SendAlertMessage(" There is no suitable surface to sit on, try another spot.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SceneObjectPart part = m_scene.GetSceneObjectPart(partID);
|
||||||
|
if (part == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Vector3 targetPos = part.GetWorldPosition() + offset * part.GetWorldRotation();
|
||||||
|
if(!CanEnterLandPosition(targetPos))
|
||||||
|
{
|
||||||
|
ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
|
||||||
|
return;
|
||||||
|
}
|
||||||
// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
|
// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
|
||||||
|
|
||||||
|
RemoveFromPhysicalScene();
|
||||||
|
|
||||||
|
if (MovingToTarget)
|
||||||
|
ResetMoveToTarget();
|
||||||
|
|
||||||
|
Velocity = Vector3.Zero;
|
||||||
|
|
||||||
part.AddSittingAvatar(UUID);
|
part.AddSittingAvatar(UUID);
|
||||||
|
|
||||||
|
|
||||||
Vector3 cameraAtOffset = part.GetCameraAtOffset();
|
Vector3 cameraAtOffset = part.GetCameraAtOffset();
|
||||||
Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
|
Vector3 cameraEyeOffset = part.GetCameraEyeOffset();
|
||||||
bool forceMouselook = part.GetForceMouselook();
|
bool forceMouselook = part.GetForceMouselook();
|
||||||
|
@ -2225,23 +2284,23 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ControllingClient.SendSitResponse(
|
ControllingClient.SendSitResponse(
|
||||||
part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
|
part.UUID, offset, Orientation, false, cameraAtOffset, cameraEyeOffset, forceMouselook);
|
||||||
|
|
||||||
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
// not using autopilot
|
||||||
|
|
||||||
// assuming no autopilot in use
|
|
||||||
Velocity = Vector3.Zero;
|
|
||||||
RemoveFromPhysicalScene();
|
|
||||||
|
|
||||||
Rotation = Orientation;
|
Rotation = Orientation;
|
||||||
m_pos = offset;
|
m_pos = offset;
|
||||||
|
|
||||||
m_requestedSitTargetID = 0; // invalidate the viewer sit comand for now
|
m_requestedSitTargetID = 0;
|
||||||
part.ParentGroup.AddAvatar(UUID);
|
part.ParentGroup.AddAvatar(UUID);
|
||||||
|
|
||||||
ParentPart = part;
|
ParentPart = part;
|
||||||
ParentID = part.LocalId;
|
ParentID = part.LocalId;
|
||||||
|
if(status == 3)
|
||||||
|
Animator.TrySetMovementAnimation("SIT_GROUND");
|
||||||
|
else
|
||||||
Animator.TrySetMovementAnimation("SIT");
|
Animator.TrySetMovementAnimation("SIT");
|
||||||
SendAvatarDataToAllAgents();
|
SendAvatarDataToAllAgents();
|
||||||
|
|
||||||
|
part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2260,6 +2319,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (part.SitTargetAvatar == UUID)
|
if (part.SitTargetAvatar == UUID)
|
||||||
{
|
{
|
||||||
Vector3 sitTargetPos = part.SitTargetPosition;
|
Vector3 sitTargetPos = part.SitTargetPosition;
|
||||||
|
|
|
@ -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(),appearance.AvatarSize);
|
OnSetAppearance(this, appearance.Texture, (byte[])appearance.VisualParams.Clone(),appearance.AvatarSize, new WearableCacheItem[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
|
public void SendRegionHandshake(RegionInfo regionInfo, RegionHandshakeArgs args)
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace OpenSim.Region.OptionalModules.World.NPC.Tests
|
||||||
// ScenePresence.SendInitialData() to reset our entire appearance.
|
// ScenePresence.SendInitialData() to reset our entire appearance.
|
||||||
m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
|
m_scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
|
||||||
|
|
||||||
m_afMod.SetAppearance(sp, originalTe, null);
|
m_afMod.SetAppearance(sp, originalTe, null, new WearableCacheItem[0] );
|
||||||
|
|
||||||
UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
|
UUID npcId = m_npcMod.CreateNPC("John", "Smith", new Vector3(128, 128, 30), UUID.Zero, true, m_scene, sp.Appearance);
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,9 @@ 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 ProbeBoxCallback(List<ContactResult> list);
|
||||||
|
public delegate void ProbeSphereCallback(List<ContactResult> list);
|
||||||
|
public delegate void ProbePlaneCallback(List<ContactResult> list);
|
||||||
public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
|
public delegate void SitAvatarCallback(int status, uint partID, Vector3 offset, Quaternion Orientation);
|
||||||
|
|
||||||
public delegate void JointMoved(PhysicsJoint joint);
|
public delegate void JointMoved(PhysicsJoint joint);
|
||||||
|
@ -56,6 +59,7 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
volumedtc = 0x40,
|
volumedtc = 0x40,
|
||||||
|
|
||||||
// ray cast colision control (may only work for meshs)
|
// ray cast colision control (may only work for meshs)
|
||||||
|
ContactsUnImportant = 0x2000,
|
||||||
BackFaceCull = 0x4000,
|
BackFaceCull = 0x4000,
|
||||||
ClosestHit = 0x8000,
|
ClosestHit = 0x8000,
|
||||||
|
|
||||||
|
@ -351,9 +355,22 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod){}
|
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
|
||||||
public virtual void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod) { }
|
{
|
||||||
public virtual List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
|
||||||
|
{
|
||||||
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
|
||||||
|
{
|
||||||
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
|
||||||
{
|
{
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -715,7 +715,17 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
Vector3 off = _velocity;
|
Vector3 off = _velocity;
|
||||||
float t = 0.5f * timeStep;
|
float t = 0.5f * timeStep;
|
||||||
off = off * t;
|
off = off * t;
|
||||||
|
d.Quaternion qtmp;
|
||||||
|
d.GeomCopyQuaternion(bbox, out qtmp);
|
||||||
|
Quaternion q;
|
||||||
|
q.X = qtmp.X;
|
||||||
|
q.Y = qtmp.Y;
|
||||||
|
q.Z = qtmp.Z;
|
||||||
|
q.W = qtmp.W;
|
||||||
|
off *= Quaternion.Conjugate(q);
|
||||||
|
|
||||||
d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
|
d.GeomSetOffsetPosition(bbox, off.X, off.Y, off.Z);
|
||||||
|
|
||||||
off.X = 2.0f * (m_size.X + Math.Abs(off.X));
|
off.X = 2.0f * (m_size.X + Math.Abs(off.X));
|
||||||
off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
|
off.Y = 2.0f * (m_size.Y + Math.Abs(off.Y));
|
||||||
off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
|
off.Z = m_size.Z + 2.0f * Math.Abs(off.Z);
|
||||||
|
@ -741,6 +751,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
|
d.GeomSetCategoryBits(feetbox, (uint)m_collisionCategories);
|
||||||
d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
|
d.GeomSetCollideBits(feetbox, (uint)m_collisionFlags);
|
||||||
}
|
}
|
||||||
|
uint cat1 = d.GeomGetCategoryBits(bbox);
|
||||||
|
uint col1 = d.GeomGetCollideBits(bbox);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1526,10 +1539,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public override void UnSubscribeEvents()
|
public override void UnSubscribeEvents()
|
||||||
{
|
{
|
||||||
if (CollisionEventsThisFrame != null)
|
if (CollisionEventsThisFrame != null)
|
||||||
|
{
|
||||||
|
lock (CollisionEventsThisFrame)
|
||||||
{
|
{
|
||||||
CollisionEventsThisFrame.Clear();
|
CollisionEventsThisFrame.Clear();
|
||||||
CollisionEventsThisFrame = null;
|
CollisionEventsThisFrame = null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
m_eventsubscription = 0;
|
m_eventsubscription = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1537,15 +1553,20 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (CollisionEventsThisFrame == null)
|
if (CollisionEventsThisFrame == null)
|
||||||
CollisionEventsThisFrame = new CollisionEventUpdate();
|
CollisionEventsThisFrame = new CollisionEventUpdate();
|
||||||
|
lock (CollisionEventsThisFrame)
|
||||||
|
{
|
||||||
CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
|
CollisionEventsThisFrame.AddCollider(CollidedWith, contact);
|
||||||
_parent_scene.AddCollisionEventReporting(this);
|
_parent_scene.AddCollisionEventReporting(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SendCollisions()
|
public void SendCollisions()
|
||||||
{
|
{
|
||||||
if (CollisionEventsThisFrame == null)
|
if (CollisionEventsThisFrame == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
lock (CollisionEventsThisFrame)
|
||||||
|
{
|
||||||
if (m_cureventsubscription < m_eventsubscription)
|
if (m_cureventsubscription < m_eventsubscription)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -1569,6 +1590,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal void AddCollisionFrameTime(int t)
|
internal void AddCollisionFrameTime(int t)
|
||||||
{
|
{
|
||||||
|
|
|
@ -56,8 +56,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private OdeScene m_scene;
|
private OdeScene m_scene;
|
||||||
|
|
||||||
IntPtr ray; // the ray. we only need one for our lifetime
|
IntPtr ray; // the ray. we only need one for our lifetime
|
||||||
|
IntPtr Sphere;
|
||||||
|
IntPtr Box;
|
||||||
|
IntPtr Plane;
|
||||||
|
|
||||||
private const int ColisionContactGeomsPerTest = 5;
|
private int CollisionContactGeomsPerTest = 25;
|
||||||
private const int DefaultMaxCount = 25;
|
private const int DefaultMaxCount = 25;
|
||||||
private const int MaxTimePerCallMS = 30;
|
private const int MaxTimePerCallMS = 30;
|
||||||
|
|
||||||
|
@ -65,6 +68,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
/// ODE near callback delegate
|
/// ODE near callback delegate
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private d.NearCallback nearCallback;
|
private d.NearCallback nearCallback;
|
||||||
|
private d.NearCallback nearProbeCallback;
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
||||||
private RayFilterFlags CurrentRayFilter;
|
private RayFilterFlags CurrentRayFilter;
|
||||||
|
@ -74,155 +78,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
m_scene = pScene;
|
m_scene = pScene;
|
||||||
nearCallback = near;
|
nearCallback = near;
|
||||||
|
nearProbeCallback = nearProbe;
|
||||||
ray = d.CreateRay(IntPtr.Zero, 1.0f);
|
ray = d.CreateRay(IntPtr.Zero, 1.0f);
|
||||||
d.GeomSetCategoryBits(ray,0);
|
d.GeomSetCategoryBits(ray, 0);
|
||||||
|
Box = d.CreateBox(IntPtr.Zero, 1.0f, 1.0f, 1.0f);
|
||||||
|
d.GeomSetCategoryBits(Box, 0);
|
||||||
|
Sphere = d.CreateSphere(IntPtr.Zero,1.0f);
|
||||||
|
d.GeomSetCategoryBits(Sphere, 0);
|
||||||
|
Plane = d.CreatePlane(IntPtr.Zero, 0f,0f,1f,1f);
|
||||||
|
d.GeomSetCategoryBits(Sphere, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
public void QueueRequest(ODERayRequest req)
|
||||||
/// Queues request for a raycast to all world
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="position">Origin of Ray</param>
|
|
||||||
/// <param name="direction">Ray direction</param>
|
|
||||||
/// <param name="length">Ray length</param>
|
|
||||||
/// <param name="retMethod">Return method to send the results</param>
|
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
|
||||||
{
|
{
|
||||||
ODERayRequest req = new ODERayRequest();
|
if (req.Count == 0)
|
||||||
req.geom = IntPtr.Zero;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.Count = DefaultMaxCount;
|
req.Count = DefaultMaxCount;
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queues request for a raycast to particular part
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="position">Origin of Ray</param>
|
|
||||||
/// <param name="direction">Ray direction</param>
|
|
||||||
/// <param name="length">Ray length</param>
|
|
||||||
/// <param name="retMethod">Return method to send the results</param>
|
|
||||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RayCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = geom;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = DefaultMaxCount;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = IntPtr.Zero;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.Count = DefaultMaxCount;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.filter = RayFilterFlags.AllPrims | RayFilterFlags.land;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = geom;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = DefaultMaxCount;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Queues a raycast
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="position">Origin of Ray</param>
|
|
||||||
/// <param name="direction">Ray normal</param>
|
|
||||||
/// <param name="length">Ray length</param>
|
|
||||||
/// <param name="count"></param>
|
|
||||||
/// <param name="retMethod">Return method to send the results</param>
|
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = IntPtr.Zero;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = count;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count,RayFilterFlags filter , RayCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = IntPtr.Zero;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = count;
|
|
||||||
req.filter = filter;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RayCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = geom;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = count;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueRequest(Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = IntPtr.Zero;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = count;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void QueueRequest(IntPtr geom, Vector3 position, Vector3 direction, float length, int count, RaycastCallback retMethod)
|
|
||||||
{
|
|
||||||
ODERayRequest req = new ODERayRequest();
|
|
||||||
req.geom = geom;
|
|
||||||
req.callbackMethod = retMethod;
|
|
||||||
req.length = length;
|
|
||||||
req.Normal = direction;
|
|
||||||
req.Origin = position;
|
|
||||||
req.Count = count;
|
|
||||||
req.filter = RayFilterFlags.AllPrims;
|
|
||||||
|
|
||||||
m_PendingRequests.Enqueue(req);
|
m_PendingRequests.Enqueue(req);
|
||||||
}
|
}
|
||||||
|
@ -258,21 +128,64 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
CurrentRayFilter = req.filter;
|
CurrentRayFilter = req.filter;
|
||||||
CurrentMaxCount = req.Count;
|
CurrentMaxCount = req.Count;
|
||||||
|
|
||||||
|
CollisionContactGeomsPerTest = req.Count & 0xffff;
|
||||||
|
|
||||||
closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
|
closestHit = ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0 ? 0 : 1);
|
||||||
backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
|
backfacecull = ((CurrentRayFilter & RayFilterFlags.BackFaceCull) == 0 ? 0 : 1);
|
||||||
|
|
||||||
|
if (req.callbackMethod is ProbeBoxCallback)
|
||||||
|
{
|
||||||
|
if (CollisionContactGeomsPerTest > 80)
|
||||||
|
CollisionContactGeomsPerTest = 80;
|
||||||
|
d.GeomBoxSetLengths(Box, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
||||||
|
d.GeomSetPosition(Box, req.Origin.X, req.Origin.Y, req.Origin.Z);
|
||||||
|
d.Quaternion qtmp;
|
||||||
|
qtmp.X = req.orientation.X;
|
||||||
|
qtmp.Y = req.orientation.Y;
|
||||||
|
qtmp.Z = req.orientation.Z;
|
||||||
|
qtmp.W = req.orientation.W;
|
||||||
|
d.GeomSetQuaternion(Box, ref qtmp);
|
||||||
|
}
|
||||||
|
else if (req.callbackMethod is ProbeSphereCallback)
|
||||||
|
{
|
||||||
|
if (CollisionContactGeomsPerTest > 80)
|
||||||
|
CollisionContactGeomsPerTest = 80;
|
||||||
|
|
||||||
|
d.GeomSphereSetRadius(Sphere, req.length);
|
||||||
|
d.GeomSetPosition(Sphere, req.Origin.X, req.Origin.Y, req.Origin.Z);
|
||||||
|
}
|
||||||
|
else if (req.callbackMethod is ProbePlaneCallback)
|
||||||
|
{
|
||||||
|
if (CollisionContactGeomsPerTest > 80)
|
||||||
|
CollisionContactGeomsPerTest = 80;
|
||||||
|
|
||||||
|
d.GeomPlaneSetParams(Plane, req.Normal.X, req.Normal.Y, req.Normal.Z, req.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (CollisionContactGeomsPerTest > 25)
|
||||||
|
CollisionContactGeomsPerTest = 25;
|
||||||
|
|
||||||
d.GeomRaySetLength(ray, req.length);
|
d.GeomRaySetLength(ray, req.length);
|
||||||
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
||||||
d.GeomRaySetParams(ray, 0, backfacecull);
|
d.GeomRaySetParams(ray, 0, backfacecull);
|
||||||
d.GeomRaySetClosestHit(ray, closestHit);
|
d.GeomRaySetClosestHit(ray, closestHit);
|
||||||
|
|
||||||
if (req.callbackMethod is RaycastCallback)
|
if (req.callbackMethod is RaycastCallback)
|
||||||
// if we only want one get only one per colision pair saving memory
|
// if we only want one get only one per Collision pair saving memory
|
||||||
CurrentRayFilter |= RayFilterFlags.ClosestHit;
|
CurrentRayFilter |= RayFilterFlags.ClosestHit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
CollisionContactGeomsPerTest |= (int)d.CONTACTS_UNIMPORTANT;
|
||||||
|
}
|
||||||
|
|
||||||
if (req.geom == IntPtr.Zero)
|
if (req.geom == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
// translate ray filter to colision flags
|
// translate ray filter to Collision flags
|
||||||
catflags = 0;
|
catflags = 0;
|
||||||
if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
|
if ((CurrentRayFilter & RayFilterFlags.volumedtc) != 0)
|
||||||
catflags |= CollisionCategories.VolumeDtc;
|
catflags |= CollisionCategories.VolumeDtc;
|
||||||
|
@ -288,18 +201,51 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
catflags |= CollisionCategories.Water;
|
catflags |= CollisionCategories.Water;
|
||||||
|
|
||||||
if (catflags != 0)
|
if (catflags != 0)
|
||||||
|
{
|
||||||
|
if (req.callbackMethod is ProbeBoxCallback)
|
||||||
|
{
|
||||||
|
catflags |= CollisionCategories.Space;
|
||||||
|
d.GeomSetCollideBits(Box, (uint)catflags);
|
||||||
|
d.GeomSetCategoryBits(Box, (uint)catflags);
|
||||||
|
doProbe(req, Box);
|
||||||
|
}
|
||||||
|
else if (req.callbackMethod is ProbeSphereCallback)
|
||||||
|
{
|
||||||
|
catflags |= CollisionCategories.Space;
|
||||||
|
d.GeomSetCollideBits(Sphere, (uint)catflags);
|
||||||
|
d.GeomSetCategoryBits(Sphere, (uint)catflags);
|
||||||
|
doProbe(req, Sphere);
|
||||||
|
}
|
||||||
|
else if (req.callbackMethod is ProbePlaneCallback)
|
||||||
|
{
|
||||||
|
catflags |= CollisionCategories.Space;
|
||||||
|
d.GeomSetCollideBits(Plane, (uint)catflags);
|
||||||
|
d.GeomSetCategoryBits(Plane, (uint)catflags);
|
||||||
|
doPlane(req);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
d.GeomSetCollideBits(ray, (uint)catflags);
|
d.GeomSetCollideBits(ray, (uint)catflags);
|
||||||
doSpaceRay(req);
|
doSpaceRay(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// if we select a geom don't use filters
|
// if we select a geom don't use filters
|
||||||
|
|
||||||
|
if (req.callbackMethod is ProbePlaneCallback)
|
||||||
|
{
|
||||||
|
d.GeomSetCollideBits(Plane, (uint)CollisionCategories.All);
|
||||||
|
doPlane(req);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
|
d.GeomSetCollideBits(ray, (uint)CollisionCategories.All);
|
||||||
doGeomRay(req);
|
doGeomRay(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
|
if (Util.EnvironmentTickCountSubtract(time) > MaxTimePerCallMS)
|
||||||
break;
|
break;
|
||||||
|
@ -382,6 +328,61 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void doProbe(ODERayRequest req, IntPtr probe)
|
||||||
|
{
|
||||||
|
// Collide tests
|
||||||
|
if ((CurrentRayFilter & FilterActiveSpace) != 0)
|
||||||
|
{
|
||||||
|
d.SpaceCollide2(probe, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
|
||||||
|
d.SpaceCollide2(probe, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
|
||||||
|
}
|
||||||
|
if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
|
||||||
|
d.SpaceCollide2(probe, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
|
||||||
|
d.SpaceCollide2(probe, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
|
||||||
|
|
||||||
|
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
cresult.AddRange(m_contactResults);
|
||||||
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
if (req.callbackMethod is ProbeBoxCallback)
|
||||||
|
((ProbeBoxCallback)req.callbackMethod)(cresult);
|
||||||
|
else if (req.callbackMethod is ProbeSphereCallback)
|
||||||
|
((ProbeSphereCallback)req.callbackMethod)(cresult);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void doPlane(ODERayRequest req)
|
||||||
|
{
|
||||||
|
// Collide tests
|
||||||
|
if (req.geom == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
if ((CurrentRayFilter & FilterActiveSpace) != 0)
|
||||||
|
{
|
||||||
|
d.SpaceCollide2(Plane, m_scene.ActiveSpace, IntPtr.Zero, nearCallback);
|
||||||
|
d.SpaceCollide2(Plane, m_scene.CharsSpace, IntPtr.Zero, nearCallback);
|
||||||
|
}
|
||||||
|
if ((CurrentRayFilter & FilterStaticSpace) != 0 && (m_contactResults.Count < CurrentMaxCount))
|
||||||
|
d.SpaceCollide2(Plane, m_scene.StaticSpace, IntPtr.Zero, nearCallback);
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.land) != 0 && (m_contactResults.Count < CurrentMaxCount))
|
||||||
|
d.SpaceCollide2(Plane, m_scene.GroundSpace, IntPtr.Zero, nearCallback);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
d.SpaceCollide2(Plane, req.geom, IntPtr.Zero, nearCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ContactResult> cresult = new List<ContactResult>(m_contactResults.Count);
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
cresult.AddRange(m_contactResults);
|
||||||
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
((ProbePlaneCallback)req.callbackMethod)(cresult);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Method that actually initiates the raycast with a geom
|
/// Method that actually initiates the raycast with a geom
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -436,7 +437,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
|
private bool GetCurContactGeom(int index, ref d.ContactGeom newcontactgeom)
|
||||||
{
|
{
|
||||||
IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
|
IntPtr ContactgeomsArray = m_scene.ContactgeomsArray;
|
||||||
if (ContactgeomsArray == IntPtr.Zero || index >= ColisionContactGeomsPerTest)
|
if (ContactgeomsArray == IntPtr.Zero || index >= CollisionContactGeomsPerTest)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
|
IntPtr contactptr = new IntPtr(ContactgeomsArray.ToInt64() + (Int64)(index * d.ContactGeom.unmanagedSizeOf));
|
||||||
|
@ -469,7 +470,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
int count = 0;
|
int count = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
count = d.CollidePtr(g1, g2, ColisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
|
count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -479,6 +480,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
/*
|
||||||
|
uint cat1 = d.GeomGetCategoryBits(g1);
|
||||||
|
uint cat2 = d.GeomGetCategoryBits(g2);
|
||||||
|
uint col1 = d.GeomGetCollideBits(g1);
|
||||||
|
uint col2 = d.GeomGetCollideBits(g2);
|
||||||
|
*/
|
||||||
|
|
||||||
uint ID = 0;
|
uint ID = 0;
|
||||||
PhysicsActor p2 = null;
|
PhysicsActor p2 = null;
|
||||||
|
@ -486,31 +493,8 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
m_scene.actor_name_map.TryGetValue(g2, out p2);
|
m_scene.actor_name_map.TryGetValue(g2, out p2);
|
||||||
|
|
||||||
if (p2 == null)
|
if (p2 == null)
|
||||||
{
|
|
||||||
/*
|
|
||||||
string name;
|
|
||||||
|
|
||||||
if (!m_scene.geom_name_map.TryGetValue(g2, out name))
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (name == "Terrain")
|
|
||||||
{
|
|
||||||
// land colision
|
|
||||||
if ((CurrentRayFilter & RayFilterFlags.land) == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (name == "Water")
|
|
||||||
{
|
|
||||||
if ((CurrentRayFilter & RayFilterFlags.water) == 0)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
*/
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (p2.PhysicsActorType)
|
switch (p2.PhysicsActorType)
|
||||||
{
|
{
|
||||||
case (int)ActorTypes.Prim:
|
case (int)ActorTypes.Prim:
|
||||||
|
@ -557,6 +541,149 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d.ContactGeom curcontact = new d.ContactGeom();
|
||||||
|
|
||||||
|
// closestHit for now only works for meshs, so must do it for others
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.ClosestHit) == 0)
|
||||||
|
{
|
||||||
|
// Loop all contacts, build results.
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (!GetCurContactGeom(i, ref curcontact))
|
||||||
|
break;
|
||||||
|
|
||||||
|
ContactResult collisionresult = new ContactResult();
|
||||||
|
collisionresult.ConsumerID = ID;
|
||||||
|
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
||||||
|
collisionresult.Depth = curcontact.depth;
|
||||||
|
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
||||||
|
curcontact.normal.Z);
|
||||||
|
lock (m_contactResults)
|
||||||
|
{
|
||||||
|
m_contactResults.Add(collisionresult);
|
||||||
|
if (m_contactResults.Count >= CurrentMaxCount)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// keep only closest contact
|
||||||
|
ContactResult collisionresult = new ContactResult();
|
||||||
|
collisionresult.ConsumerID = ID;
|
||||||
|
collisionresult.Depth = float.MaxValue;
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (!GetCurContactGeom(i, ref curcontact))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (curcontact.depth < collisionresult.Depth)
|
||||||
|
{
|
||||||
|
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
||||||
|
collisionresult.Depth = curcontact.depth;
|
||||||
|
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
||||||
|
curcontact.normal.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (collisionresult.Depth != float.MaxValue)
|
||||||
|
{
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Add(collisionresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nearProbe(IntPtr space, IntPtr g1, IntPtr g2)
|
||||||
|
{
|
||||||
|
if (g1 == IntPtr.Zero || g1 == g2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_contactResults.Count >= CurrentMaxCount)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (d.GeomIsSpace(g1))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearProbeCallback);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[PHYSICS Ray]: Unable to Space collide test an object: {0}", e.Message);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
count = d.CollidePtr(g1, g2, CollisionContactGeomsPerTest, m_scene.ContactgeomsArray, d.ContactGeom.unmanagedSizeOf);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[PHYSICS Ray]: Unable to collide test an object: {0}", e.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
uint ID = 0;
|
||||||
|
PhysicsActor p1 = null;
|
||||||
|
|
||||||
|
m_scene.actor_name_map.TryGetValue(g1, out p1);
|
||||||
|
|
||||||
|
if (p1 == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (p1.PhysicsActorType)
|
||||||
|
{
|
||||||
|
case (int)ActorTypes.Prim:
|
||||||
|
|
||||||
|
RayFilterFlags thisFlags;
|
||||||
|
|
||||||
|
if (p1.IsPhysical)
|
||||||
|
thisFlags = RayFilterFlags.physical;
|
||||||
|
else
|
||||||
|
thisFlags = RayFilterFlags.nonphysical;
|
||||||
|
|
||||||
|
if (p1.Phantom)
|
||||||
|
thisFlags |= RayFilterFlags.phantom;
|
||||||
|
|
||||||
|
if (p1.IsVolumeDtc)
|
||||||
|
thisFlags |= RayFilterFlags.volumedtc;
|
||||||
|
|
||||||
|
if ((thisFlags & CurrentRayFilter) == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ID = ((OdePrim)p1).LocalID;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (int)ActorTypes.Agent:
|
||||||
|
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.agent) == 0)
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
ID = ((OdeCharacter)p1).LocalID;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (int)ActorTypes.Ground:
|
||||||
|
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.land) == 0)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case (int)ActorTypes.Water:
|
||||||
|
|
||||||
|
if ((CurrentRayFilter & RayFilterFlags.water) == 0)
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
d.ContactGeom curcontact = new d.ContactGeom();
|
d.ContactGeom curcontact = new d.ContactGeom();
|
||||||
|
@ -624,6 +751,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.GeomDestroy(ray);
|
d.GeomDestroy(ray);
|
||||||
ray = IntPtr.Zero;
|
ray = IntPtr.Zero;
|
||||||
}
|
}
|
||||||
|
if (Box != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
d.GeomDestroy(Box);
|
||||||
|
Box = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
if (Sphere != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
d.GeomDestroy(Sphere);
|
||||||
|
Sphere = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
if (Plane != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
d.GeomDestroy(Plane);
|
||||||
|
Plane = IntPtr.Zero;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,5 +778,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public float length;
|
public float length;
|
||||||
public object callbackMethod;
|
public object callbackMethod;
|
||||||
public RayFilterFlags filter;
|
public RayFilterFlags filter;
|
||||||
|
public Quaternion orientation;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -52,6 +52,21 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
|
private static Vector3 SitAjust = new Vector3(0, 0, 0.4f);
|
||||||
|
private const RayFilterFlags RaySitFlags = RayFilterFlags.AllPrims | RayFilterFlags.ClosestHit;
|
||||||
|
|
||||||
|
private void RotAroundZ(float x, float y, ref Quaternion ori)
|
||||||
|
{
|
||||||
|
double ang = Math.Atan2(y, x);
|
||||||
|
ang *= 0.5d;
|
||||||
|
float s = (float)Math.Sin(ang);
|
||||||
|
float c = (float)Math.Cos(ang);
|
||||||
|
|
||||||
|
ori.X = 0;
|
||||||
|
ori.Y = 0;
|
||||||
|
ori.Z = s;
|
||||||
|
ori.W = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
|
public void Sit(PhysicsActor actor, Vector3 avPos, Vector3 avCameraPosition, Vector3 offset, Vector3 avOffset, SitAvatarCallback PhysicsSitResponse)
|
||||||
{
|
{
|
||||||
|
@ -63,55 +78,45 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
IntPtr geom = ((OdePrim)actor).prim_geom;
|
IntPtr geom = ((OdePrim)actor).prim_geom;
|
||||||
|
|
||||||
d.Vector3 dtmp = d.GeomGetPosition(geom);
|
Vector3 geopos = d.GeomGetPositionOMV(geom);
|
||||||
Vector3 geopos;
|
Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
|
||||||
geopos.X = dtmp.X;
|
Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
|
||||||
geopos.Y = dtmp.Y;
|
|
||||||
geopos.Z = dtmp.Z;
|
|
||||||
|
|
||||||
|
Quaternion ori = Quaternion.Identity;
|
||||||
|
|
||||||
d.AABB aabb;
|
Vector3 rayDir = geopos + offset - avCameraPosition;
|
||||||
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 raylen = rayDir.Length();
|
||||||
|
if (raylen < 0.001f)
|
||||||
|
{
|
||||||
|
PhysicsSitResponse(-1, actor.LocalID, offset, Quaternion.Identity);
|
||||||
|
return;
|
||||||
|
}
|
||||||
float t = 1 / raylen;
|
float t = 1 / raylen;
|
||||||
rayDir.X *= t;
|
rayDir.X *= t;
|
||||||
rayDir.Y *= t;
|
rayDir.Y *= t;
|
||||||
rayDir.Z *= t;
|
rayDir.Z *= t;
|
||||||
|
|
||||||
raylen += 0.5f;
|
raylen += 30f; // focal point may be far
|
||||||
List<ContactResult> rayResults;
|
List<ContactResult> rayResults;
|
||||||
|
|
||||||
rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir , raylen, 1);
|
rayResults = m_scene.RaycastActor(actor, avCameraPosition, rayDir, raylen, 1, RaySitFlags);
|
||||||
if (rayResults.Count == 0 || rayResults[0].ConsumerID != actor.LocalID)
|
if (rayResults.Count == 0)
|
||||||
{
|
{
|
||||||
d.GeomGetAABB(geom,out aabb);
|
/* if this fundamental ray failed, then just fail so user can try another spot and not be sitted far on a big prim
|
||||||
|
d.AABB aabb;
|
||||||
|
d.GeomGetAABB(geom, out aabb);
|
||||||
offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
|
offset = new Vector3(avOffset.X, 0, aabb.MaxZ + avOffset.Z - geopos.Z);
|
||||||
ori = geomInvOri;
|
ori = geomInvOri;
|
||||||
offset *= geomInvOri;
|
offset *= geomInvOri;
|
||||||
|
|
||||||
PhysicsSitResponse(1, actor.LocalID, offset, ori);
|
PhysicsSitResponse(1, actor.LocalID, offset, ori);
|
||||||
|
*/
|
||||||
|
PhysicsSitResponse(0, actor.LocalID, offset, ori);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int status = 1;
|
||||||
offset = rayResults[0].Pos - geopos;
|
offset = rayResults[0].Pos - geopos;
|
||||||
double ang;
|
|
||||||
float s;
|
|
||||||
float c;
|
|
||||||
|
|
||||||
d.GeomClassID geoclass = d.GeomGetClass(geom);
|
d.GeomClassID geoclass = d.GeomGetClass(geom);
|
||||||
|
|
||||||
|
@ -122,18 +127,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
offset.Normalize();
|
offset.Normalize();
|
||||||
offset *= r;
|
offset *= r;
|
||||||
|
|
||||||
ang = Math.Atan2(offset.Y, offset.X);
|
RotAroundZ(offset.X, offset.Y, ref ori);
|
||||||
ang *= 0.5d;
|
|
||||||
s = (float)Math.Sin(ang);
|
|
||||||
c = (float)Math.Cos(ang);
|
|
||||||
|
|
||||||
ori = new Quaternion(0, 0, s, c);
|
|
||||||
|
|
||||||
if (r < 0.4f)
|
if (r < 0.4f)
|
||||||
{
|
{
|
||||||
offset = new Vector3(0, 0, r);
|
offset = new Vector3(0, 0, r);
|
||||||
}
|
}
|
||||||
else if (offset.Z < 0.4f)
|
else
|
||||||
|
{
|
||||||
|
if (offset.Z < 0.4f)
|
||||||
{
|
{
|
||||||
t = offset.Z;
|
t = offset.Z;
|
||||||
float rsq = r * r;
|
float rsq = r * r;
|
||||||
|
@ -146,36 +148,206 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
offset.X *= t;
|
offset.X *= t;
|
||||||
offset.Y *= t;
|
offset.Y *= t;
|
||||||
}
|
}
|
||||||
|
else if (r > 0.8f && offset.Z > 0.8f * r)
|
||||||
|
{
|
||||||
|
status = 3;
|
||||||
|
avOffset.X = -avOffset.X;
|
||||||
|
avOffset.Z *= 1.6f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
offset += avOffset * ori;
|
offset += avOffset * ori;
|
||||||
|
|
||||||
ori = geomInvOri * ori;
|
ori = geomInvOri * ori;
|
||||||
offset *= geomInvOri;
|
offset *= geomInvOri;
|
||||||
|
|
||||||
PhysicsSitResponse(1, actor.LocalID, offset, ori);
|
PhysicsSitResponse(status, actor.LocalID, offset, ori);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 norm = rayResults[0].Normal;
|
Vector3 norm = rayResults[0].Normal;
|
||||||
|
|
||||||
if (norm.Z < 0)
|
if (norm.Z < -0.4f)
|
||||||
{
|
{
|
||||||
PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
|
PhysicsSitResponse(0, actor.LocalID, offset, Quaternion.Identity);
|
||||||
return;
|
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);
|
float SitNormX = -rayDir.X;
|
||||||
|
float SitNormY = -rayDir.Y;
|
||||||
|
|
||||||
|
Vector3 pivot = geopos + offset;
|
||||||
|
|
||||||
|
float edgeNormalX = norm.X;
|
||||||
|
float edgeNormalY = norm.Y;
|
||||||
|
float edgeDirX = -rayDir.X;
|
||||||
|
float edgeDirY = -rayDir.Y;
|
||||||
|
Vector3 edgePos = rayResults[0].Pos;
|
||||||
|
float edgeDist = float.MaxValue;
|
||||||
|
|
||||||
|
bool foundEdge = false;
|
||||||
|
|
||||||
|
if (norm.Z < 0.5f)
|
||||||
|
{
|
||||||
|
float rayDist = 4.0f;
|
||||||
|
float curEdgeDist = 0.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
pivot.X -= 0.005f * norm.X;
|
||||||
|
pivot.Y -= 0.005f * norm.Y;
|
||||||
|
pivot.Z -= 0.005f * norm.Z;
|
||||||
|
|
||||||
|
rayDir.X = -norm.X * norm.Z;
|
||||||
|
rayDir.Y = -norm.Y * norm.Z;
|
||||||
|
rayDir.Z = 1.0f - norm.Z * norm.Z;
|
||||||
|
rayDir.Normalize();
|
||||||
|
|
||||||
|
rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
|
||||||
|
if (rayResults.Count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
curEdgeDist += rayResults[0].Depth;
|
||||||
|
|
||||||
|
if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
|
||||||
|
{
|
||||||
|
rayDist -= rayResults[0].Depth;
|
||||||
|
if (rayDist < 0f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pivot = rayResults[0].Pos;
|
||||||
|
norm = rayResults[0].Normal;
|
||||||
|
edgeNormalX = norm.X;
|
||||||
|
edgeNormalY = norm.Y;
|
||||||
|
edgeDirX = -rayDir.X;
|
||||||
|
edgeDirY = -rayDir.Y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foundEdge = true;
|
||||||
|
edgeDist = curEdgeDist;
|
||||||
|
edgePos = rayResults[0].Pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundEdge)
|
||||||
|
{
|
||||||
|
PhysicsSitResponse(0, actor.LocalID, offset, ori);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
avOffset.X *= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (norm.Z > 0.866f)
|
||||||
|
{
|
||||||
|
float toCamBaseX = avCameraPosition.X - pivot.X;
|
||||||
|
float toCamBaseY = avCameraPosition.Y - pivot.Y;
|
||||||
|
float toCamX = toCamBaseX;
|
||||||
|
float toCamY = toCamBaseY;
|
||||||
|
|
||||||
|
for (int j = 0; j < 4; j++)
|
||||||
|
{
|
||||||
|
float rayDist = 1.0f;
|
||||||
|
float curEdgeDist = 0.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
pivot.Z -= 0.005f;
|
||||||
|
rayDir.X = toCamX;
|
||||||
|
rayDir.Y = toCamY;
|
||||||
|
rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
|
||||||
|
rayDir.Normalize();
|
||||||
|
|
||||||
|
rayResults = m_scene.RaycastActor(actor, pivot, rayDir, rayDist, 1, RayFilterFlags.AllPrims);
|
||||||
|
if (rayResults.Count == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
curEdgeDist += rayResults[0].Depth;
|
||||||
|
|
||||||
|
if (rayResults[0].Normal.Z > 0.5f)
|
||||||
|
{
|
||||||
|
rayDist -= rayResults[0].Depth;
|
||||||
|
if (rayDist < 0f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pivot = rayResults[0].Pos;
|
||||||
|
norm = rayResults[0].Normal;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foundEdge = true;
|
||||||
|
if (curEdgeDist < edgeDist)
|
||||||
|
{
|
||||||
|
edgeDist = curEdgeDist;
|
||||||
|
edgeNormalX = rayResults[0].Normal.X;
|
||||||
|
edgeNormalY = rayResults[0].Normal.Y;
|
||||||
|
edgeDirX = rayDir.X;
|
||||||
|
edgeDirY = rayDir.Y;
|
||||||
|
edgePos = rayResults[0].Pos;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (foundEdge && edgeDist < 0.2f)
|
||||||
|
break;
|
||||||
|
|
||||||
|
pivot = geopos + offset;
|
||||||
|
|
||||||
|
switch (j)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
toCamX = -toCamBaseY;
|
||||||
|
toCamY = toCamBaseX;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
toCamX = toCamBaseY;
|
||||||
|
toCamY = -toCamBaseX;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
toCamX = -toCamBaseX;
|
||||||
|
toCamY = -toCamBaseY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!foundEdge)
|
||||||
|
{
|
||||||
|
avOffset.X = -avOffset.X;
|
||||||
|
avOffset.Z *= 1.6f;
|
||||||
|
|
||||||
|
RotAroundZ(SitNormX, SitNormY, ref ori);
|
||||||
|
|
||||||
offset += avOffset * ori;
|
offset += avOffset * ori;
|
||||||
|
|
||||||
ori = geomInvOri * ori;
|
ori = geomInvOri * ori;
|
||||||
offset *= geomInvOri;
|
offset *= geomInvOri;
|
||||||
|
|
||||||
|
PhysicsSitResponse(3, actor.LocalID, offset, ori);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
avOffset.X *= 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
SitNormX = edgeNormalX;
|
||||||
|
SitNormY = edgeNormalY;
|
||||||
|
if (edgeDirX * SitNormX + edgeDirY * SitNormY < 0)
|
||||||
|
{
|
||||||
|
SitNormX = -SitNormX;
|
||||||
|
SitNormY = -SitNormY;
|
||||||
|
}
|
||||||
|
|
||||||
|
RotAroundZ(SitNormX, SitNormY, ref ori);
|
||||||
|
|
||||||
|
offset = edgePos + avOffset * ori;
|
||||||
|
offset -= geopos;
|
||||||
|
|
||||||
|
ori = geomInvOri * ori;
|
||||||
|
offset *= geomInvOri;
|
||||||
|
|
||||||
PhysicsSitResponse(1, actor.LocalID, offset, ori);
|
PhysicsSitResponse(1, actor.LocalID, offset, ori);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using System.Security;
|
using System.Security;
|
||||||
|
using OMV = OpenMetaverse;
|
||||||
namespace OdeAPI
|
namespace OdeAPI
|
||||||
{
|
{
|
||||||
//#if dDOUBLE
|
//#if dDOUBLE
|
||||||
|
@ -925,9 +925,20 @@ namespace OdeAPI
|
||||||
{
|
{
|
||||||
unsafe { return *(GeomGetPositionUnsafe(geom)); }
|
unsafe { return *(GeomGetPositionUnsafe(geom)); }
|
||||||
}
|
}
|
||||||
|
public static OMV.Vector3 GeomGetPositionOMV(IntPtr geom)
|
||||||
|
{
|
||||||
|
Vector3 vtmp = GeomGetPosition(geom);
|
||||||
|
return new OMV.Vector3(vtmp.X, vtmp.Y, vtmp.Z);
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
|
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q);
|
public static extern void GeomCopyQuaternion(IntPtr geom, out Quaternion q);
|
||||||
|
public static OMV.Quaternion GeomGetQuaternionOMV(IntPtr geom)
|
||||||
|
{
|
||||||
|
Quaternion qtmp;
|
||||||
|
GeomCopyQuaternion(geom, out qtmp);
|
||||||
|
return new OMV.Quaternion(qtmp.X, qtmp.Y, qtmp.Z, qtmp.W);
|
||||||
|
}
|
||||||
|
|
||||||
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
|
[DllImport("ode", CallingConvention = CallingConvention.Cdecl, EntryPoint = "dGeomGetQuaternion"), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X);
|
public static extern void GeomCopyQuaternion(IntPtr geom, out dReal X);
|
||||||
|
|
|
@ -2579,7 +2579,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (retMethod != null)
|
if (retMethod != null)
|
||||||
{
|
{
|
||||||
m_rayCastManager.QueueRequest(position, direction, length, retMethod);
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = 0;
|
||||||
|
req.filter = RayFilterFlags.All;
|
||||||
|
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2587,29 +2596,51 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (retMethod != null)
|
if (retMethod != null)
|
||||||
{
|
{
|
||||||
m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = RayFilterFlags.All;
|
||||||
|
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't like this
|
|
||||||
public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
|
public override List<ContactResult> RaycastWorld(Vector3 position, Vector3 direction, float length, int Count)
|
||||||
{
|
{
|
||||||
ContactResult[] ourResults = null;
|
List<ContactResult> ourresults = new List<ContactResult>();
|
||||||
|
object SyncObject = new object();
|
||||||
|
|
||||||
RayCallback retMethod = delegate(List<ContactResult> results)
|
RayCallback retMethod = delegate(List<ContactResult> results)
|
||||||
{
|
{
|
||||||
ourResults = new ContactResult[results.Count];
|
lock (SyncObject)
|
||||||
results.CopyTo(ourResults, 0);
|
|
||||||
};
|
|
||||||
int waitTime = 0;
|
|
||||||
m_rayCastManager.QueueRequest(position, direction, length, Count, retMethod);
|
|
||||||
while (ourResults == null && waitTime < 1000)
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(1);
|
ourresults = results;
|
||||||
waitTime++;
|
Monitor.PulseAll(SyncObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = RayFilterFlags.All;
|
||||||
|
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
|
return null;
|
||||||
|
else
|
||||||
|
return ourresults;
|
||||||
}
|
}
|
||||||
if (ourResults == null)
|
|
||||||
return new List<ContactResult>();
|
|
||||||
return new List<ContactResult>(ourResults);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool SuportsRaycastWorldFiltered()
|
public override bool SuportsRaycastWorldFiltered()
|
||||||
|
@ -2631,9 +2662,18 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = filter;
|
||||||
|
|
||||||
lock (SyncObject)
|
lock (SyncObject)
|
||||||
{
|
{
|
||||||
m_rayCastManager.QueueRequest(position, direction, length, Count,filter, retMethod);
|
m_rayCastManager.QueueRequest(req);
|
||||||
if (!Monitor.Wait(SyncObject, 500))
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
return null;
|
return null;
|
||||||
else
|
else
|
||||||
|
@ -2641,46 +2681,11 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayFilterFlags flags)
|
||||||
{
|
{
|
||||||
if (retMethod != null && actor !=null)
|
if (actor == null)
|
||||||
{
|
return new List<ContactResult>();
|
||||||
IntPtr geom;
|
|
||||||
if (actor is OdePrim)
|
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
|
||||||
else if (actor is OdeCharacter)
|
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
if (geom == IntPtr.Zero)
|
|
||||||
return;
|
|
||||||
m_rayCastManager.QueueRequest(geom, position, direction, length, retMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count, RayCallback retMethod)
|
|
||||||
{
|
|
||||||
if (retMethod != null && actor != null)
|
|
||||||
{
|
|
||||||
IntPtr geom;
|
|
||||||
if (actor is OdePrim)
|
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
|
||||||
else if (actor is OdeCharacter)
|
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
if (geom == IntPtr.Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// don't like this
|
|
||||||
public override List<ContactResult> RaycastActor(PhysicsActor actor, Vector3 position, Vector3 direction, float length, int Count)
|
|
||||||
{
|
|
||||||
if (actor != null)
|
|
||||||
{
|
|
||||||
IntPtr geom;
|
IntPtr geom;
|
||||||
if (actor is OdePrim)
|
if (actor is OdePrim)
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
geom = ((OdePrim)actor).prim_geom;
|
||||||
|
@ -2688,29 +2693,153 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
geom = ((OdePrim)actor).prim_geom;
|
geom = ((OdePrim)actor).prim_geom;
|
||||||
else
|
else
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
|
|
||||||
if (geom == IntPtr.Zero)
|
if (geom == IntPtr.Zero)
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
|
|
||||||
ContactResult[] ourResults = null;
|
List<ContactResult> ourResults = null;
|
||||||
|
object SyncObject = new object();
|
||||||
|
|
||||||
RayCallback retMethod = delegate(List<ContactResult> results)
|
RayCallback retMethod = delegate(List<ContactResult> results)
|
||||||
{
|
{
|
||||||
ourResults = new ContactResult[results.Count];
|
lock (SyncObject)
|
||||||
results.CopyTo(ourResults, 0);
|
|
||||||
};
|
|
||||||
int waitTime = 0;
|
|
||||||
m_rayCastManager.QueueRequest(geom,position, direction, length, Count, retMethod);
|
|
||||||
while (ourResults == null && waitTime < 1000)
|
|
||||||
{
|
{
|
||||||
Thread.Sleep(1);
|
ourResults = results;
|
||||||
waitTime++;
|
Monitor.PulseAll(SyncObject);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = geom;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = flags;
|
||||||
|
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
if (ourResults == null)
|
if (ourResults == null)
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
return new List<ContactResult>(ourResults);
|
return ourResults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override List<ContactResult> BoxProbe(Vector3 position, Vector3 size, Quaternion orientation, int Count, RayFilterFlags flags)
|
||||||
|
{
|
||||||
|
List<ContactResult> ourResults = null;
|
||||||
|
object SyncObject = new object();
|
||||||
|
|
||||||
|
ProbeBoxCallback retMethod = delegate(List<ContactResult> results)
|
||||||
|
{
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
ourResults = results;
|
||||||
|
Monitor.PulseAll(SyncObject);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.Normal = size;
|
||||||
|
req.Origin = position;
|
||||||
|
req.orientation = orientation;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = flags;
|
||||||
|
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
return new List<ContactResult>();
|
return new List<ContactResult>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ourResults == null)
|
||||||
|
return new List<ContactResult>();
|
||||||
|
return ourResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<ContactResult> SphereProbe(Vector3 position, float radius, int Count, RayFilterFlags flags)
|
||||||
|
{
|
||||||
|
List<ContactResult> ourResults = null;
|
||||||
|
object SyncObject = new object();
|
||||||
|
|
||||||
|
ProbeSphereCallback retMethod = delegate(List<ContactResult> results)
|
||||||
|
{
|
||||||
|
ourResults = results;
|
||||||
|
Monitor.PulseAll(SyncObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = IntPtr.Zero;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = radius;
|
||||||
|
req.Origin = position;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = flags;
|
||||||
|
|
||||||
|
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ourResults == null)
|
||||||
|
return new List<ContactResult>();
|
||||||
|
return ourResults;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override List<ContactResult> PlaneProbe(PhysicsActor actor, Vector4 plane, int Count, RayFilterFlags flags)
|
||||||
|
{
|
||||||
|
IntPtr geom = IntPtr.Zero;;
|
||||||
|
|
||||||
|
if (actor != null)
|
||||||
|
{
|
||||||
|
if (actor is OdePrim)
|
||||||
|
geom = ((OdePrim)actor).prim_geom;
|
||||||
|
else if (actor is OdeCharacter)
|
||||||
|
geom = ((OdePrim)actor).prim_geom;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ContactResult> ourResults = null;
|
||||||
|
object SyncObject = new object();
|
||||||
|
|
||||||
|
ProbePlaneCallback retMethod = delegate(List<ContactResult> results)
|
||||||
|
{
|
||||||
|
ourResults = results;
|
||||||
|
Monitor.PulseAll(SyncObject);
|
||||||
|
};
|
||||||
|
|
||||||
|
ODERayRequest req = new ODERayRequest();
|
||||||
|
req.geom = geom;
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = plane.W;
|
||||||
|
req.Normal.X = plane.X;
|
||||||
|
req.Normal.Y = plane.Y;
|
||||||
|
req.Normal.Z = plane.Z;
|
||||||
|
req.Count = Count;
|
||||||
|
req.filter = flags;
|
||||||
|
|
||||||
|
lock (SyncObject)
|
||||||
|
{
|
||||||
|
m_rayCastManager.QueueRequest(req);
|
||||||
|
if (!Monitor.Wait(SyncObject, 500))
|
||||||
|
return new List<ContactResult>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ourResults == null)
|
||||||
|
return new List<ContactResult>();
|
||||||
|
return ourResults;
|
||||||
|
}
|
||||||
|
|
||||||
public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
|
public override int SitAvatar(PhysicsActor actor, Vector3 AbsolutePosition, Vector3 CameraPosition, Vector3 offset, Vector3 AvatarSize, SitAvatarCallback PhysicsSitResponse)
|
||||||
{
|
{
|
||||||
Util.FireAndForget( delegate
|
Util.FireAndForget( delegate
|
||||||
|
|
|
@ -144,7 +144,7 @@ namespace OpenSim.Tests.Performance
|
||||||
// ScenePresence.SendInitialData() to reset our entire appearance.
|
// ScenePresence.SendInitialData() to reset our entire appearance.
|
||||||
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
|
scene.AssetService.Store(AssetHelpers.CreateNotecardAsset(originalFace8TextureId));
|
||||||
|
|
||||||
afm.SetAppearance(sp, originalTe, null);
|
afm.SetAppearance(sp, originalTe, null, new WearableCacheItem[0]);
|
||||||
|
|
||||||
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
|
INPCModule npcModule = scene.RequestModuleInterface<INPCModule>();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue