Merge branch 'avination' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/ScenePresence.csavinationmerge
commit
aecb32b74e
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
@ -50,6 +51,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
{
|
{
|
||||||
public class UploadBakedTextureHandler
|
public class UploadBakedTextureHandler
|
||||||
{
|
{
|
||||||
|
|
||||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
private Caps m_HostCapsObj;
|
private Caps m_HostCapsObj;
|
||||||
|
@ -81,7 +83,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
string uploaderPath = Util.RandomClass.Next(5000, 8000).ToString("0000");
|
||||||
|
|
||||||
BakedTextureUploader uploader =
|
BakedTextureUploader uploader =
|
||||||
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener);
|
new BakedTextureUploader(capsBase + uploaderPath, m_HostCapsObj.HttpListener, m_HostCapsObj.AgentID);
|
||||||
uploader.OnUpLoad += BakedTextureUploaded;
|
uploader.OnUpLoad += BakedTextureUploaded;
|
||||||
|
|
||||||
m_HostCapsObj.HttpListener.AddStreamHandler(
|
m_HostCapsObj.HttpListener.AddStreamHandler(
|
||||||
|
@ -125,6 +127,7 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
asset.Temporary = true;
|
asset.Temporary = true;
|
||||||
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
asset.Local = !m_persistBakedTextures; // Local assets aren't persisted, non-local are
|
||||||
m_assetService.Store(asset);
|
m_assetService.Store(asset);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,15 +140,19 @@ namespace OpenSim.Capabilities.Handlers
|
||||||
private string uploaderPath = String.Empty;
|
private string uploaderPath = String.Empty;
|
||||||
private UUID newAssetID;
|
private UUID newAssetID;
|
||||||
private IHttpServer httpListener;
|
private IHttpServer httpListener;
|
||||||
|
private UUID AgentId = UUID.Zero;
|
||||||
|
|
||||||
public BakedTextureUploader(string path, IHttpServer httpServer)
|
public BakedTextureUploader(string path, IHttpServer httpServer, UUID uUID)
|
||||||
{
|
{
|
||||||
newAssetID = UUID.Random();
|
newAssetID = UUID.Random();
|
||||||
uploaderPath = path;
|
uploaderPath = path;
|
||||||
httpListener = httpServer;
|
httpListener = httpServer;
|
||||||
|
AgentId = uUID;
|
||||||
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
// m_log.InfoFormat("[CAPS] baked texture upload starting for {0}",newAssetID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Handle raw uploaded baked texture data.
|
/// Handle raw uploaded baked texture data.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -66,7 +66,9 @@ 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;
|
protected WearableCacheItem[] m_cacheitems;
|
||||||
|
protected bool m_cacheItemsDirty = true;
|
||||||
|
|
||||||
public virtual int Serial
|
public virtual int Serial
|
||||||
{
|
{
|
||||||
get { return m_serial; }
|
get { return m_serial; }
|
||||||
|
@ -118,8 +120,14 @@ namespace OpenSim.Framework
|
||||||
|
|
||||||
public virtual WearableCacheItem[] WearableCacheItems
|
public virtual WearableCacheItem[] WearableCacheItems
|
||||||
{
|
{
|
||||||
get { return cacheitems; }
|
get { return m_cacheitems; }
|
||||||
set { cacheitems = value; }
|
set { m_cacheitems = value; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual bool WearableCacheItemsDirty
|
||||||
|
{
|
||||||
|
get { return m_cacheItemsDirty; }
|
||||||
|
set { m_cacheItemsDirty = value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public AvatarAppearance()
|
public AvatarAppearance()
|
||||||
|
|
|
@ -26,14 +26,132 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
using OpenMetaverse.StructuredData;
|
||||||
|
|
||||||
namespace OpenSim.Framework
|
namespace OpenSim.Framework
|
||||||
{
|
{
|
||||||
|
[Serializable]
|
||||||
public class WearableCacheItem
|
public class WearableCacheItem
|
||||||
{
|
{
|
||||||
public uint TextureIndex { get; set; }
|
public uint TextureIndex { get; set; }
|
||||||
public UUID CacheId { get; set; }
|
public UUID CacheId { get; set; }
|
||||||
public UUID TextureID { get; set; }
|
public UUID TextureID { get; set; }
|
||||||
|
public AssetBase TextureAsset { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
public static WearableCacheItem[] GetDefaultCacheItem()
|
||||||
|
{
|
||||||
|
int itemmax = 21;
|
||||||
|
WearableCacheItem[] retitems = new WearableCacheItem[itemmax];
|
||||||
|
for (uint i=0;i<itemmax;i++)
|
||||||
|
retitems[i] = new WearableCacheItem() {CacheId = UUID.Zero, TextureID = UUID.Zero, TextureIndex = i + 1};
|
||||||
|
return retitems;
|
||||||
|
}
|
||||||
|
public static WearableCacheItem[] FromOSD(OSD pInput, IImprovedAssetCache dataCache)
|
||||||
|
{
|
||||||
|
List<WearableCacheItem> ret = new List<WearableCacheItem>();
|
||||||
|
if (pInput.Type == OSDType.Array)
|
||||||
|
{
|
||||||
|
OSDArray itemarray = (OSDArray) pInput;
|
||||||
|
foreach (OSDMap item in itemarray)
|
||||||
|
{
|
||||||
|
ret.Add(new WearableCacheItem()
|
||||||
|
{
|
||||||
|
TextureIndex = item["textureindex"].AsUInteger(),
|
||||||
|
CacheId = item["cacheid"].AsUUID(),
|
||||||
|
TextureID = item["textureid"].AsUUID()
|
||||||
|
});
|
||||||
|
|
||||||
|
if (dataCache != null && item.ContainsKey("assetdata"))
|
||||||
|
{
|
||||||
|
AssetBase asset = new AssetBase(item["textureid"].AsUUID(),"BakedTexture",(sbyte)AssetType.Texture,UUID.Zero.ToString());
|
||||||
|
asset.Temporary = true;
|
||||||
|
asset.Data = item["assetdata"].AsBinary();
|
||||||
|
dataCache.Cache(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pInput.Type == OSDType.Map)
|
||||||
|
{
|
||||||
|
OSDMap item = (OSDMap) pInput;
|
||||||
|
ret.Add(new WearableCacheItem(){
|
||||||
|
TextureIndex = item["textureindex"].AsUInteger(),
|
||||||
|
CacheId = item["cacheid"].AsUUID(),
|
||||||
|
TextureID = item["textureid"].AsUUID()
|
||||||
|
});
|
||||||
|
if (dataCache != null && item.ContainsKey("assetdata"))
|
||||||
|
{
|
||||||
|
string assetCreator = item["assetcreator"].AsString();
|
||||||
|
string assetName = item["assetname"].AsString();
|
||||||
|
AssetBase asset = new AssetBase(item["textureid"].AsUUID(), assetName, (sbyte)AssetType.Texture, assetCreator);
|
||||||
|
asset.Temporary = true;
|
||||||
|
asset.Data = item["assetdata"].AsBinary();
|
||||||
|
dataCache.Cache(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return new WearableCacheItem[0];
|
||||||
|
}
|
||||||
|
return ret.ToArray();
|
||||||
|
|
||||||
|
}
|
||||||
|
public static OSD ToOSD(WearableCacheItem[] pcacheItems, IImprovedAssetCache dataCache)
|
||||||
|
{
|
||||||
|
OSDArray arr = new OSDArray();
|
||||||
|
foreach (WearableCacheItem item in pcacheItems)
|
||||||
|
{
|
||||||
|
OSDMap itemmap = new OSDMap();
|
||||||
|
itemmap.Add("textureindex", OSD.FromUInteger(item.TextureIndex));
|
||||||
|
itemmap.Add("cacheid", OSD.FromUUID(item.CacheId));
|
||||||
|
itemmap.Add("textureid", OSD.FromUUID(item.TextureID));
|
||||||
|
if (dataCache != null)
|
||||||
|
{
|
||||||
|
if (dataCache.Check(item.TextureID.ToString()))
|
||||||
|
{
|
||||||
|
AssetBase assetItem = dataCache.Get(item.TextureID.ToString());
|
||||||
|
if (assetItem != null)
|
||||||
|
{
|
||||||
|
itemmap.Add("assetdata", OSD.FromBinary(assetItem.Data));
|
||||||
|
itemmap.Add("assetcreator", OSD.FromString(assetItem.CreatorID));
|
||||||
|
itemmap.Add("assetname", OSD.FromString(assetItem.Name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr.Add(itemmap);
|
||||||
|
}
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
public static WearableCacheItem SearchTextureIndex(uint pTextureIndex,WearableCacheItem[] pcacheItems)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < pcacheItems.Length; i++)
|
||||||
|
{
|
||||||
|
if (pcacheItems[i].TextureIndex == pTextureIndex)
|
||||||
|
return pcacheItems[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static WearableCacheItem SearchTextureCacheId(UUID pCacheId, WearableCacheItem[] pcacheItems)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < pcacheItems.Length; i++)
|
||||||
|
{
|
||||||
|
if (pcacheItems[i].CacheId == pCacheId)
|
||||||
|
return pcacheItems[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static WearableCacheItem SearchTextureTextureId(UUID pTextureId, WearableCacheItem[] pcacheItems)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < pcacheItems.Length; i++)
|
||||||
|
{
|
||||||
|
if (pcacheItems[i].TextureID == pTextureId)
|
||||||
|
return pcacheItems[i];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private static readonly string m_getObjectPhysicsDataPath = "0101/";
|
private static readonly string m_getObjectPhysicsDataPath = "0101/";
|
||||||
private static readonly string m_getObjectCostPath = "0102/";
|
private static readonly string m_getObjectCostPath = "0102/";
|
||||||
private static readonly string m_ResourceCostSelectedPath = "0103/";
|
private static readonly string m_ResourceCostSelectedPath = "0103/";
|
||||||
|
private static readonly string m_UpdateAgentInformationPath = "0500/";
|
||||||
|
|
||||||
|
|
||||||
// These are callbacks which will be setup by the scene so that we can update scene data when we
|
// These are callbacks which will be setup by the scene so that we can update scene data when we
|
||||||
|
@ -287,6 +288,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
|
m_HostCapsObj.RegisterHandler("GetObjectCost", getObjectCostHandler);
|
||||||
IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
|
IRequestHandler ResourceCostSelectedHandler = new RestStreamHandler("POST", capsBase + m_ResourceCostSelectedPath, ResourceCostSelected);
|
||||||
m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
|
m_HostCapsObj.RegisterHandler("ResourceCostSelected", ResourceCostSelectedHandler);
|
||||||
|
IRequestHandler UpdateAgentInformationHandler = new RestStreamHandler("POST", capsBase + m_UpdateAgentInformationPath, UpdateAgentInformation);
|
||||||
|
m_HostCapsObj.RegisterHandler("UpdateAgentInformation", UpdateAgentInformationHandler);
|
||||||
|
|
||||||
m_HostCapsObj.RegisterHandler(
|
m_HostCapsObj.RegisterHandler(
|
||||||
"CopyInventoryFromNotecard",
|
"CopyInventoryFromNotecard",
|
||||||
|
@ -1438,6 +1441,22 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
string response = OSDParser.SerializeLLSDXmlString(resp);
|
string response = OSDParser.SerializeLLSDXmlString(resp);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string UpdateAgentInformation(string request, string path,
|
||||||
|
string param, IOSHttpRequest httpRequest,
|
||||||
|
IOSHttpResponse httpResponse)
|
||||||
|
{
|
||||||
|
OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
|
||||||
|
OSDMap resp = new OSDMap();
|
||||||
|
|
||||||
|
OSDMap accessPrefs = new OSDMap();
|
||||||
|
accessPrefs["max"] = "A";
|
||||||
|
|
||||||
|
resp["access_prefs"] = accessPrefs;
|
||||||
|
|
||||||
|
string response = OSDParser.SerializeLLSDXmlString(resp);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AssetUploader
|
public class AssetUploader
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Collections.Specialized;
|
using System.Collections.Specialized;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
|
@ -53,8 +54,8 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")]
|
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "UploadBakedTextureModule")]
|
||||||
public class UploadBakedTextureModule : INonSharedRegionModule
|
public class UploadBakedTextureModule : INonSharedRegionModule
|
||||||
{
|
{
|
||||||
// private static readonly ILog m_log =
|
private static readonly ILog m_log =
|
||||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For historical reasons this is fixed, but there
|
/// For historical reasons this is fixed, but there
|
||||||
|
@ -64,31 +65,195 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
private Scene m_scene;
|
private Scene m_scene;
|
||||||
private bool m_persistBakedTextures;
|
private bool m_persistBakedTextures;
|
||||||
|
|
||||||
|
private IBakedTextureModule m_BakedTextureModule;
|
||||||
|
|
||||||
public void Initialise(IConfigSource source)
|
public void Initialise(IConfigSource source)
|
||||||
{
|
{
|
||||||
IConfig appearanceConfig = source.Configs["Appearance"];
|
IConfig appearanceConfig = source.Configs["Appearance"];
|
||||||
if (appearanceConfig != null)
|
if (appearanceConfig != null)
|
||||||
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
m_persistBakedTextures = appearanceConfig.GetBoolean("PersistBakedTextures", m_persistBakedTextures);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddRegion(Scene s)
|
public void AddRegion(Scene s)
|
||||||
{
|
{
|
||||||
m_scene = s;
|
m_scene = s;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveRegion(Scene s)
|
public void RemoveRegion(Scene s)
|
||||||
{
|
{
|
||||||
|
s.EventManager.OnRegisterCaps -= RegisterCaps;
|
||||||
|
s.EventManager.OnNewPresence -= RegisterNewPresence;
|
||||||
|
s.EventManager.OnRemovePresence -= DeRegisterPresence;
|
||||||
|
m_BakedTextureModule = null;
|
||||||
|
m_scene = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void RegionLoaded(Scene s)
|
public void RegionLoaded(Scene s)
|
||||||
{
|
{
|
||||||
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
m_scene.EventManager.OnRegisterCaps += RegisterCaps;
|
||||||
|
m_scene.EventManager.OnNewPresence += RegisterNewPresence;
|
||||||
|
m_scene.EventManager.OnRemovePresence += DeRegisterPresence;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeRegisterPresence(UUID agentId)
|
||||||
|
{
|
||||||
|
ScenePresence presence = null;
|
||||||
|
if (m_scene.TryGetScenePresence(agentId, out presence))
|
||||||
|
{
|
||||||
|
presence.ControllingClient.OnSetAppearance -= CaptureAppearanceSettings;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterNewPresence(ScenePresence presence)
|
||||||
|
{
|
||||||
|
presence.ControllingClient.OnSetAppearance += CaptureAppearanceSettings;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CaptureAppearanceSettings(IClientAPI remoteClient, Primitive.TextureEntry textureEntry, byte[] visualParams, Vector3 avSize, WearableCacheItem[] cacheItems)
|
||||||
|
{
|
||||||
|
int maxCacheitemsLoop = cacheItems.Length;
|
||||||
|
if (maxCacheitemsLoop > AvatarWearable.MAX_WEARABLES)
|
||||||
|
{
|
||||||
|
maxCacheitemsLoop = AvatarWearable.MAX_WEARABLES;
|
||||||
|
m_log.WarnFormat("[CACHEDBAKES]: Too Many Cache items Provided {0}, the max is {1}. Truncating!", cacheItems.Length, AvatarWearable.MAX_WEARABLES);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_BakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
|
||||||
|
if (cacheItems.Length > 0)
|
||||||
|
{
|
||||||
|
m_log.Debug("[Cacheitems]: " + cacheItems.Length);
|
||||||
|
for (int iter = 0; iter < maxCacheitemsLoop; iter++)
|
||||||
|
{
|
||||||
|
m_log.Debug("[Cacheitems] {" + iter + "/" + cacheItems[iter].TextureIndex + "}: c-" + cacheItems[iter].CacheId + ", t-" +
|
||||||
|
cacheItems[iter].TextureID);
|
||||||
|
}
|
||||||
|
|
||||||
|
ScenePresence p = null;
|
||||||
|
if (m_scene.TryGetScenePresence(remoteClient.AgentId, out p))
|
||||||
|
{
|
||||||
|
|
||||||
|
WearableCacheItem[] existingitems = p.Appearance.WearableCacheItems;
|
||||||
|
if (existingitems == null)
|
||||||
|
{
|
||||||
|
if (m_BakedTextureModule != null)
|
||||||
|
{
|
||||||
|
WearableCacheItem[] savedcache = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (p.Appearance.WearableCacheItemsDirty)
|
||||||
|
{
|
||||||
|
savedcache = m_BakedTextureModule.Get(p.UUID);
|
||||||
|
p.Appearance.WearableCacheItems = savedcache;
|
||||||
|
p.Appearance.WearableCacheItemsDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* The following Catch types DO NOT WORK with m_BakedTextureModule.Get
|
||||||
|
* it jumps to the General Packet Exception Handler if you don't catch Exception!
|
||||||
|
*
|
||||||
|
catch (System.Net.Sockets.SocketException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
} */
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
// The service logs a sufficient error message.
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (savedcache != null)
|
||||||
|
existingitems = savedcache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Existing items null means it's a fully new appearance
|
||||||
|
if (existingitems == null)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < maxCacheitemsLoop; i++)
|
||||||
|
{
|
||||||
|
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
|
||||||
|
{
|
||||||
|
cacheItems[i].TextureID =
|
||||||
|
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID;
|
||||||
|
if (m_scene.AssetService != null)
|
||||||
|
cacheItems[i].TextureAsset =
|
||||||
|
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
|
||||||
|
|
||||||
|
{
|
||||||
|
// for each uploaded baked texture
|
||||||
|
for (int i = 0; i < maxCacheitemsLoop; i++)
|
||||||
|
{
|
||||||
|
if (textureEntry.FaceTextures.Length > cacheItems[i].TextureIndex)
|
||||||
|
{
|
||||||
|
cacheItems[i].TextureID =
|
||||||
|
textureEntry.FaceTextures[cacheItems[i].TextureIndex].TextureID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[CACHEDBAKES]: Invalid Texture Index Provided, Texture doesn't exist or hasn't been uploaded yet {0}, the max is {1}. Skipping!", cacheItems[i].TextureIndex, textureEntry.FaceTextures.Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < maxCacheitemsLoop; i++)
|
||||||
|
{
|
||||||
|
if (cacheItems[i].TextureAsset == null)
|
||||||
|
{
|
||||||
|
cacheItems[i].TextureAsset =
|
||||||
|
m_scene.AssetService.GetCached(cacheItems[i].TextureID.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
p.Appearance.WearableCacheItems = cacheItems;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (m_BakedTextureModule != null)
|
||||||
|
{
|
||||||
|
m_BakedTextureModule.Store(remoteClient.AgentId, cacheItems);
|
||||||
|
p.Appearance.WearableCacheItemsDirty = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PostInitialise()
|
public void PostInitialise()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void Close() { }
|
public void Close() { }
|
||||||
|
|
||||||
public string Name { get { return "UploadBakedTextureModule"; } }
|
public string Name { get { return "UploadBakedTextureModule"; } }
|
||||||
|
@ -100,15 +265,23 @@ namespace OpenSim.Region.ClientStack.Linden
|
||||||
|
|
||||||
public void RegisterCaps(UUID agentID, Caps caps)
|
public void RegisterCaps(UUID agentID, Caps caps)
|
||||||
{
|
{
|
||||||
|
UploadBakedTextureHandler avatarhandler = new UploadBakedTextureHandler(
|
||||||
|
caps, m_scene.AssetService, m_persistBakedTextures);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
caps.RegisterHandler(
|
caps.RegisterHandler(
|
||||||
"UploadBakedTexture",
|
"UploadBakedTexture",
|
||||||
new RestStreamHandler(
|
new RestStreamHandler(
|
||||||
"POST",
|
"POST",
|
||||||
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
"/CAPS/" + caps.CapsObjectPath + m_uploadBakedTexturePath,
|
||||||
new UploadBakedTextureHandler(
|
avatarhandler.UploadBakedTexture,
|
||||||
caps, m_scene.AssetService, m_persistBakedTextures).UploadBakedTexture,
|
|
||||||
"UploadBakedTexture",
|
"UploadBakedTexture",
|
||||||
agentID.ToString()));
|
agentID.ToString()));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3629,7 +3629,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.State);
|
OutPacket(avp, ThrottleOutPacketType.State);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11725,32 +11725,134 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
||||||
// var item = fac.GetBakedTextureFaces(AgentId);
|
// var item = fac.GetBakedTextureFaces(AgentId);
|
||||||
//WearableCacheItem[] items = fac.GetCachedItems(AgentId);
|
//WearableCacheItem[] items = fac.GetCachedItems(AgentId);
|
||||||
|
|
||||||
IImprovedAssetCache cache = m_scene.RequestModuleInterface<IImprovedAssetCache>();
|
IAssetService cache = m_scene.AssetService;
|
||||||
if (cache == null)
|
IBakedTextureModule bakedTextureModule = m_scene.RequestModuleInterface<IBakedTextureModule>();
|
||||||
|
//bakedTextureModule = null;
|
||||||
|
int maxWearablesLoop = cachedtex.WearableData.Length;
|
||||||
|
if (maxWearablesLoop > AvatarWearable.MAX_WEARABLES)
|
||||||
|
maxWearablesLoop = AvatarWearable.MAX_WEARABLES;
|
||||||
|
|
||||||
|
if (bakedTextureModule != null && cache != null)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cachedtex.WearableData.Length; i++)
|
// We need to make sure the asset stored in the bake is available on this server also by it's assetid before we map it to a Cacheid
|
||||||
|
|
||||||
|
WearableCacheItem[] cacheItems = null;
|
||||||
|
ScenePresence p = m_scene.GetScenePresence(AgentId);
|
||||||
|
if (p.Appearance != null)
|
||||||
|
if (p.Appearance.WearableCacheItems == null || p.Appearance.WearableCacheItemsDirty)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
cacheItems = bakedTextureModule.Get(AgentId);
|
||||||
|
p.Appearance.WearableCacheItems = cacheItems;
|
||||||
|
p.Appearance.WearableCacheItemsDirty = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following Catch types DO NOT WORK, it jumps to the General Packet Exception Handler if you don't catch Exception!
|
||||||
|
*
|
||||||
|
catch (System.Net.Sockets.SocketException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
}
|
||||||
|
catch (WebException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
}
|
||||||
|
catch (InvalidOperationException)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
} */
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
cacheItems = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (p.Appearance.WearableCacheItems != null)
|
||||||
|
{
|
||||||
|
cacheItems = p.Appearance.WearableCacheItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache != null && cacheItems != null)
|
||||||
{
|
{
|
||||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
foreach (WearableCacheItem item in cacheItems)
|
||||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
{
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero; //UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
|
||||||
cachedresp.WearableData[i].HostName = new byte[0];
|
if (cache.GetCached(item.TextureID.ToString()) == null)
|
||||||
|
{
|
||||||
|
item.TextureAsset.Temporary = true;
|
||||||
|
cache.Store(item.TextureAsset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cacheItems != null)
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < maxWearablesLoop; i++)
|
||||||
|
{
|
||||||
|
WearableCacheItem item =
|
||||||
|
WearableCacheItem.SearchTextureIndex(cachedtex.WearableData[i].TextureIndex,cacheItems);
|
||||||
|
|
||||||
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
|
cachedresp.WearableData[i].TextureIndex= cachedtex.WearableData[i].TextureIndex;
|
||||||
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
|
if (item != null && cachedtex.WearableData[i].ID == item.CacheId)
|
||||||
|
{
|
||||||
|
|
||||||
|
cachedresp.WearableData[i].TextureID = item.TextureID;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < maxWearablesLoop; i++)
|
||||||
|
{
|
||||||
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
|
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||||
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
|
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cachedtex.WearableData.Length; i++)
|
if (cache == null)
|
||||||
{
|
{
|
||||||
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
for (int i = 0; i < maxWearablesLoop; i++)
|
||||||
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
{
|
||||||
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
|
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||||
|
|
||||||
if (cache.Check(cachedtex.WearableData[i].ID.ToString()))
|
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
else
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
cachedresp.WearableData[i].TextureID = UUID.Zero; // UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
}
|
||||||
cachedresp.WearableData[i].HostName = new byte[0];
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (int i = 0; i < maxWearablesLoop; i++)
|
||||||
|
{
|
||||||
|
cachedresp.WearableData[i] = new AgentCachedTextureResponsePacket.WearableDataBlock();
|
||||||
|
cachedresp.WearableData[i].TextureIndex = cachedtex.WearableData[i].TextureIndex;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (cache.GetCached(cachedresp.WearableData[i].TextureID.ToString()) == null)
|
||||||
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
|
//UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
|
else
|
||||||
|
cachedresp.WearableData[i].TextureID = UUID.Zero;
|
||||||
|
// UUID.Parse("8334fb6e-c2f5-46ee-807d-a435f61a8d46");
|
||||||
|
cachedresp.WearableData[i].HostName = new byte[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cachedresp.Header.Zerocoded = true;
|
cachedresp.Header.Zerocoded = true;
|
||||||
|
|
|
@ -205,10 +205,7 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -284,8 +281,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
|
||||||
public WearableCacheItem[] GetCachedItems(UUID agentId)
|
public WearableCacheItem[] GetCachedItems(UUID agentId)
|
||||||
{
|
{
|
||||||
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
ScenePresence sp = m_scene.GetScenePresence(agentId);
|
||||||
Dictionary<BakeType, Primitive.TextureEntryFace> bakedTextures = GetBakedTextureFaces(sp);
|
|
||||||
|
|
||||||
WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
|
WearableCacheItem[] items = sp.Appearance.WearableCacheItems;
|
||||||
//foreach (WearableCacheItem item in items)
|
//foreach (WearableCacheItem item in items)
|
||||||
//{
|
//{
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace OpenSim.Services.Interfaces
|
||||||
{
|
{
|
||||||
public interface IBakedTextureModule
|
public interface IBakedTextureModule
|
||||||
{
|
{
|
||||||
AssetBase[] Get(UUID id);
|
WearableCacheItem[] Get(UUID id);
|
||||||
void Store(UUID id, AssetBase[] data);
|
void Store(UUID id, WearableCacheItem[] data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2982,6 +2982,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// start the scripts again (since this is done in RezAttachments()).
|
// start the scripts again (since this is done in RezAttachments()).
|
||||||
// XXX: This is convoluted.
|
// XXX: This is convoluted.
|
||||||
sp.IsChildAgent = false;
|
sp.IsChildAgent = false;
|
||||||
|
sp.IsLoggingIn = true;
|
||||||
|
|
||||||
if (AttachmentsModule != null)
|
if (AttachmentsModule != null)
|
||||||
Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
|
Util.FireAndForget(delegate(object o) { AttachmentsModule.RezAttachments(sp); });
|
||||||
|
|
|
@ -144,7 +144,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public bool IsRoot
|
public bool IsRoot
|
||||||
{
|
{
|
||||||
get { return ParentGroup.RootPart == this; }
|
get { return Object.ReferenceEquals(ParentGroup.RootPart, this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -225,8 +225,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool LandAtTarget { get; private set; }
|
public bool LandAtTarget { get; private set; }
|
||||||
|
|
||||||
private bool m_followCamAuto;
|
|
||||||
|
|
||||||
private int m_movementUpdateCount;
|
private int m_movementUpdateCount;
|
||||||
private const int NumMovementsBetweenRayCast = 5;
|
private const int NumMovementsBetweenRayCast = 5;
|
||||||
|
|
||||||
|
@ -355,6 +353,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected Vector3 m_lastCameraPosition;
|
protected Vector3 m_lastCameraPosition;
|
||||||
|
|
||||||
|
private Vector4 m_lastCameraCollisionPlane = new Vector4(0f, 0f, 0f, 1);
|
||||||
|
private bool m_doingCamRayCast = false;
|
||||||
|
|
||||||
public Vector3 CameraPosition { get; set; }
|
public Vector3 CameraPosition { get; set; }
|
||||||
|
|
||||||
public Quaternion CameraRotation
|
public Quaternion CameraRotation
|
||||||
|
@ -604,6 +605,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsChildAgent { get; set; }
|
public bool IsChildAgent { get; set; }
|
||||||
|
public bool IsLoggingIn { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
|
/// If the avatar is sitting, the local ID of the prim that it's sitting on. If not sitting then zero.
|
||||||
|
@ -740,6 +742,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
AttachmentsSyncLock = new Object();
|
AttachmentsSyncLock = new Object();
|
||||||
AllowMovement = true;
|
AllowMovement = true;
|
||||||
IsChildAgent = true;
|
IsChildAgent = true;
|
||||||
|
IsLoggingIn = false;
|
||||||
m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
|
m_sendCoarseLocationsMethod = SendCoarseLocationsDefault;
|
||||||
Animator = new ScenePresenceAnimator(this);
|
Animator = new ScenePresenceAnimator(this);
|
||||||
PresenceType = type;
|
PresenceType = type;
|
||||||
|
@ -912,6 +915,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IsChildAgent = false;
|
IsChildAgent = false;
|
||||||
|
IsLoggingIn = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1405,35 +1409,43 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="collisionPoint"></param>
|
/// <param name="collisionPoint"></param>
|
||||||
/// <param name="localid"></param>
|
/// <param name="localid"></param>
|
||||||
/// <param name="distance"></param>
|
/// <param name="distance"></param>
|
||||||
|
///
|
||||||
|
|
||||||
|
private void UpdateCameraCollisionPlane(Vector4 plane)
|
||||||
|
{
|
||||||
|
if (m_lastCameraCollisionPlane != plane)
|
||||||
|
{
|
||||||
|
m_lastCameraCollisionPlane = plane;
|
||||||
|
ControllingClient.SendCameraConstraint(plane);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
|
public void RayCastCameraCallback(bool hitYN, Vector3 collisionPoint, uint localid, float distance, Vector3 pNormal)
|
||||||
{
|
{
|
||||||
const float POSITION_TOLERANCE = 0.02f;
|
const float POSITION_TOLERANCE = 0.02f;
|
||||||
const float VELOCITY_TOLERANCE = 0.02f;
|
|
||||||
const float ROTATION_TOLERANCE = 0.02f;
|
const float ROTATION_TOLERANCE = 0.02f;
|
||||||
|
|
||||||
if (m_followCamAuto)
|
m_doingCamRayCast = false;
|
||||||
|
if (hitYN && localid != LocalId)
|
||||||
{
|
{
|
||||||
if (hitYN)
|
CameraConstraintActive = true;
|
||||||
{
|
pNormal.X = (float)Math.Round(pNormal.X, 2);
|
||||||
CameraConstraintActive = true;
|
pNormal.Y = (float)Math.Round(pNormal.Y, 2);
|
||||||
//m_log.DebugFormat("[RAYCASTRESULT]: {0}, {1}, {2}, {3}", hitYN, collisionPoint, localid, distance);
|
pNormal.Z = (float)Math.Round(pNormal.Z, 2);
|
||||||
|
pNormal.Normalize();
|
||||||
|
collisionPoint.X = (float)Math.Round(collisionPoint.X, 1);
|
||||||
|
collisionPoint.Y = (float)Math.Round(collisionPoint.Y, 1);
|
||||||
|
collisionPoint.Z = (float)Math.Round(collisionPoint.Z, 1);
|
||||||
|
|
||||||
Vector3 normal = Vector3.Normalize(new Vector3(0f, 0f, collisionPoint.Z) - collisionPoint);
|
Vector4 plane = new Vector4(pNormal.X, pNormal.Y, pNormal.Z, Vector3.Dot(collisionPoint, pNormal));
|
||||||
ControllingClient.SendCameraConstraint(new Vector4(normal.X, normal.Y, normal.Z, -1 * Vector3.Distance(new Vector3(0,0,collisionPoint.Z),collisionPoint)));
|
UpdateCameraCollisionPlane(plane);
|
||||||
}
|
}
|
||||||
else
|
else if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
|
||||||
{
|
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
|
||||||
if (!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE) ||
|
{
|
||||||
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
|
Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -9000f); // not right...
|
||||||
!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE))
|
UpdateCameraCollisionPlane(plane);
|
||||||
{
|
CameraConstraintActive = false;
|
||||||
if (CameraConstraintActive)
|
|
||||||
{
|
|
||||||
ControllingClient.SendCameraConstraint(new Vector4(0f, 0.5f, 0.9f, -3000f));
|
|
||||||
CameraConstraintActive = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1508,12 +1520,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// DrawDistance = agentData.Far;
|
// DrawDistance = agentData.Far;
|
||||||
DrawDistance = Scene.DefaultDrawDistance;
|
DrawDistance = Scene.DefaultDrawDistance;
|
||||||
|
|
||||||
// Check if Client has camera in 'follow cam' or 'build' mode.
|
|
||||||
Vector3 camdif = (Vector3.One * Rotation - Vector3.One * CameraRotation);
|
|
||||||
|
|
||||||
m_followCamAuto = ((CameraUpAxis.Z > 0.959f && CameraUpAxis.Z < 0.98f)
|
|
||||||
&& (Math.Abs(camdif.X) < 0.4f && Math.Abs(camdif.Y) < 0.4f)) ? true : false;
|
|
||||||
|
|
||||||
m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
|
m_mouseLook = (flags & AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0;
|
||||||
m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
|
m_leftButtonDown = (flags & AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0;
|
||||||
|
|
||||||
|
@ -1533,24 +1539,38 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
StandUp();
|
StandUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_log.DebugFormat("[FollowCam]: {0}", m_followCamAuto);
|
|
||||||
// Raycast from the avatar's head to the camera to see if there's anything blocking the view
|
// Raycast from the avatar's head to the camera to see if there's anything blocking the view
|
||||||
if ((m_movementUpdateCount % NumMovementsBetweenRayCast) == 0 && m_scene.PhysicsScene.SupportsRayCast())
|
// this exclude checks may not be complete
|
||||||
|
|
||||||
|
if (m_movementUpdateCount % NumMovementsBetweenRayCast == 0 && m_scene.PhysicsScene.SupportsRayCast())
|
||||||
{
|
{
|
||||||
if (m_followCamAuto)
|
if (!m_doingCamRayCast && !m_mouseLook && ParentID == 0)
|
||||||
{
|
{
|
||||||
// Vector3 posAdjusted = m_pos + HEAD_ADJUSTMENT;
|
Vector3 posAdjusted = AbsolutePosition;
|
||||||
// m_scene.PhysicsScene.RaycastWorld(m_pos, Vector3.Normalize(CameraPosition - posAdjusted), Vector3.Distance(CameraPosition, posAdjusted) + 0.3f, RayCastCameraCallback);
|
// posAdjusted.Z += 0.5f * Appearance.AvatarSize.Z - 0.5f;
|
||||||
|
posAdjusted.Z += 1.0f; // viewer current camera focus point
|
||||||
|
Vector3 tocam = CameraPosition - posAdjusted;
|
||||||
|
tocam.X = (float)Math.Round(tocam.X, 1);
|
||||||
|
tocam.Y = (float)Math.Round(tocam.Y, 1);
|
||||||
|
tocam.Z = (float)Math.Round(tocam.Z, 1);
|
||||||
|
|
||||||
Vector3 posAdjusted = AbsolutePosition + HEAD_ADJUSTMENT;
|
float distTocamlen = tocam.Length();
|
||||||
Vector3 distTocam = CameraPosition - posAdjusted;
|
if (distTocamlen > 0.3f)
|
||||||
float distTocamlen = distTocam.Length();
|
|
||||||
if (distTocamlen > 0)
|
|
||||||
{
|
{
|
||||||
distTocam *= 1.0f / distTocamlen;
|
tocam *= (1.0f / distTocamlen);
|
||||||
m_scene.PhysicsScene.RaycastWorld(posAdjusted, distTocam, distTocamlen + 0.3f, RayCastCameraCallback);
|
posAdjusted.X = (float)Math.Round(posAdjusted.X, 1);
|
||||||
}
|
posAdjusted.Y = (float)Math.Round(posAdjusted.Y, 1);
|
||||||
|
posAdjusted.Z = (float)Math.Round(posAdjusted.Z, 1);
|
||||||
|
|
||||||
|
m_doingCamRayCast = true;
|
||||||
|
m_scene.PhysicsScene.RaycastWorld(posAdjusted, tocam, distTocamlen + 1.0f, RayCastCameraCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (CameraConstraintActive && (m_mouseLook || ParentID != 0))
|
||||||
|
{
|
||||||
|
Vector4 plane = new Vector4(0.9f, 0.0f, 0.361f, -10000f); // not right...
|
||||||
|
UpdateCameraCollisionPlane(plane);
|
||||||
|
CameraConstraintActive = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2265,7 +2285,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
|
ControllingClient.SendAlertMessage(" Sit position on restricted land, try another spot");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// m_log.InfoFormat("physsit {0} {1}", offset.ToString(),Orientation.ToString());
|
|
||||||
|
|
||||||
RemoveFromPhysicalScene();
|
RemoveFromPhysicalScene();
|
||||||
|
|
||||||
|
@ -2276,7 +2295,6 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
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();
|
||||||
|
@ -2502,20 +2520,12 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
|
// NOTE: Velocity is not the same as m_velocity. Velocity will attempt to
|
||||||
// grab the latest PhysicsActor velocity, whereas m_velocity is often
|
// grab the latest PhysicsActor velocity, whereas m_velocity is often
|
||||||
// storing a requested force instead of an actual traveling velocity
|
// storing a requested force instead of an actual traveling velocity
|
||||||
if (Appearance.AvatarSize != m_lastSize)
|
if (Appearance.AvatarSize != m_lastSize && !IsLoggingIn)
|
||||||
{
|
|
||||||
m_lastSize = Appearance.AvatarSize;
|
|
||||||
SendAvatarDataToAllAgents();
|
SendAvatarDataToAllAgents();
|
||||||
}
|
|
||||||
// Throw away duplicate or insignificant updates
|
|
||||||
else if (
|
|
||||||
// If the velocity has become zero, send it no matter what.
|
|
||||||
(Velocity != m_lastVelocity && Velocity == Vector3.Zero)
|
|
||||||
// otherwise, if things have changed reasonably, send the update
|
|
||||||
|| (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE)
|
|
||||||
|| !Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE)
|
|
||||||
|| !m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE)))
|
|
||||||
|
|
||||||
|
if (!Rotation.ApproxEquals(m_lastRotation, ROTATION_TOLERANCE) ||
|
||||||
|
!Velocity.ApproxEquals(m_lastVelocity, VELOCITY_TOLERANCE) ||
|
||||||
|
!m_pos.ApproxEquals(m_lastPosition, POSITION_TOLERANCE))
|
||||||
{
|
{
|
||||||
SendTerseUpdateToAllClients();
|
SendTerseUpdateToAllClients();
|
||||||
|
|
||||||
|
@ -2704,6 +2714,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_lastSize = Appearance.AvatarSize;
|
||||||
|
|
||||||
int count = 0;
|
int count = 0;
|
||||||
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
m_scene.ForEachScenePresence(delegate(ScenePresence scenePresence)
|
||||||
{
|
{
|
||||||
|
|
|
@ -173,8 +173,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
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 Collision pair saving memory
|
// if we only want one get only one per Collision pair saving memory
|
||||||
CurrentRayFilter |= RayFilterFlags.ClosestHit;
|
CurrentRayFilter |= RayFilterFlags.ClosestHit;
|
||||||
|
d.GeomRaySetClosestHit(ray, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
d.GeomRaySetClosestHit(ray, closestHit);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
|
if ((CurrentRayFilter & RayFilterFlags.ContactsUnImportant) != 0)
|
||||||
|
@ -555,10 +560,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
ContactResult collisionresult = new ContactResult();
|
ContactResult collisionresult = new ContactResult();
|
||||||
collisionresult.ConsumerID = ID;
|
collisionresult.ConsumerID = ID;
|
||||||
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
collisionresult.Pos.X = curcontact.pos.X;
|
||||||
|
collisionresult.Pos.Y = curcontact.pos.Y;
|
||||||
|
collisionresult.Pos.Z = curcontact.pos.Z;
|
||||||
collisionresult.Depth = curcontact.depth;
|
collisionresult.Depth = curcontact.depth;
|
||||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
collisionresult.Normal.X = curcontact.normal.X;
|
||||||
curcontact.normal.Z);
|
collisionresult.Normal.Y = curcontact.normal.Y;
|
||||||
|
collisionresult.Normal.Z = curcontact.normal.Z;
|
||||||
lock (m_contactResults)
|
lock (m_contactResults)
|
||||||
{
|
{
|
||||||
m_contactResults.Add(collisionresult);
|
m_contactResults.Add(collisionresult);
|
||||||
|
@ -581,10 +589,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
if (curcontact.depth < collisionresult.Depth)
|
if (curcontact.depth < collisionresult.Depth)
|
||||||
{
|
{
|
||||||
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
collisionresult.Pos.X = curcontact.pos.X;
|
||||||
|
collisionresult.Pos.Y = curcontact.pos.Y;
|
||||||
|
collisionresult.Pos.Z = curcontact.pos.Z;
|
||||||
collisionresult.Depth = curcontact.depth;
|
collisionresult.Depth = curcontact.depth;
|
||||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
collisionresult.Normal.X = curcontact.normal.X;
|
||||||
curcontact.normal.Z);
|
collisionresult.Normal.Y = curcontact.normal.Y;
|
||||||
|
collisionresult.Normal.Z = curcontact.normal.Z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -699,10 +710,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
ContactResult collisionresult = new ContactResult();
|
ContactResult collisionresult = new ContactResult();
|
||||||
collisionresult.ConsumerID = ID;
|
collisionresult.ConsumerID = ID;
|
||||||
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
collisionresult.Pos.X = curcontact.pos.X;
|
||||||
|
collisionresult.Pos.Y = curcontact.pos.Y;
|
||||||
|
collisionresult.Pos.Z = curcontact.pos.Z;
|
||||||
collisionresult.Depth = curcontact.depth;
|
collisionresult.Depth = curcontact.depth;
|
||||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
collisionresult.Normal.X = curcontact.normal.X;
|
||||||
curcontact.normal.Z);
|
collisionresult.Normal.Y = curcontact.normal.Y;
|
||||||
|
collisionresult.Normal.Z = curcontact.normal.Z;
|
||||||
lock (m_contactResults)
|
lock (m_contactResults)
|
||||||
{
|
{
|
||||||
m_contactResults.Add(collisionresult);
|
m_contactResults.Add(collisionresult);
|
||||||
|
@ -725,10 +739,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
if (curcontact.depth < collisionresult.Depth)
|
if (curcontact.depth < collisionresult.Depth)
|
||||||
{
|
{
|
||||||
collisionresult.Pos = new Vector3(curcontact.pos.X, curcontact.pos.Y, curcontact.pos.Z);
|
collisionresult.Pos.X = curcontact.pos.X;
|
||||||
|
collisionresult.Pos.Y = curcontact.pos.Y;
|
||||||
|
collisionresult.Pos.Z = curcontact.pos.Z;
|
||||||
collisionresult.Depth = curcontact.depth;
|
collisionresult.Depth = curcontact.depth;
|
||||||
collisionresult.Normal = new Vector3(curcontact.normal.X, curcontact.normal.Y,
|
collisionresult.Normal.X = curcontact.normal.X;
|
||||||
curcontact.normal.Z);
|
collisionresult.Normal.Y = curcontact.normal.Y;
|
||||||
|
collisionresult.Normal.Z = curcontact.normal.Z;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -78,8 +78,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
IntPtr geom = ((OdePrim)actor).prim_geom;
|
IntPtr geom = ((OdePrim)actor).prim_geom;
|
||||||
|
|
||||||
Vector3 geopos = d.GeomGetPositionOMV(geom);
|
// Vector3 geopos = d.GeomGetPositionOMV(geom);
|
||||||
Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
|
// Quaternion geomOri = d.GeomGetQuaternionOMV(geom);
|
||||||
|
|
||||||
|
Vector3 geopos = actor.Position;
|
||||||
|
Quaternion geomOri = actor.Orientation;
|
||||||
|
|
||||||
Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
|
Quaternion geomInvOri = Quaternion.Conjugate(geomOri);
|
||||||
|
|
||||||
Quaternion ori = Quaternion.Identity;
|
Quaternion ori = Quaternion.Identity;
|
||||||
|
@ -116,6 +120,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
int status = 1;
|
int status = 1;
|
||||||
|
|
||||||
offset = rayResults[0].Pos - geopos;
|
offset = rayResults[0].Pos - geopos;
|
||||||
|
|
||||||
d.GeomClassID geoclass = d.GeomGetClass(geom);
|
d.GeomClassID geoclass = d.GeomGetClass(geom);
|
||||||
|
@ -191,13 +196,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (norm.Z < 0.5f)
|
if (norm.Z < 0.5f)
|
||||||
{
|
{
|
||||||
float rayDist = 4.0f;
|
float rayDist = 4.0f;
|
||||||
float curEdgeDist = 0.0f;
|
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
pivot.X -= 0.005f * norm.X;
|
pivot.X -= 0.01f * norm.X;
|
||||||
pivot.Y -= 0.005f * norm.Y;
|
pivot.Y -= 0.01f * norm.Y;
|
||||||
pivot.Z -= 0.005f * norm.Z;
|
pivot.Z -= 0.01f * norm.Z;
|
||||||
|
|
||||||
rayDir.X = -norm.X * norm.Z;
|
rayDir.X = -norm.X * norm.Z;
|
||||||
rayDir.Y = -norm.Y * norm.Z;
|
rayDir.Y = -norm.Y * norm.Z;
|
||||||
|
@ -208,8 +212,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
if (rayResults.Count == 0)
|
if (rayResults.Count == 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
curEdgeDist += rayResults[0].Depth;
|
|
||||||
|
|
||||||
if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
|
if (Math.Abs(rayResults[0].Normal.Z) < 0.7f)
|
||||||
{
|
{
|
||||||
rayDist -= rayResults[0].Depth;
|
rayDist -= rayResults[0].Depth;
|
||||||
|
@ -226,7 +228,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
foundEdge = true;
|
foundEdge = true;
|
||||||
edgeDist = curEdgeDist;
|
|
||||||
edgePos = rayResults[0].Pos;
|
edgePos = rayResults[0].Pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +255,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
pivot.Z -= 0.005f;
|
pivot.Z -= 0.01f;
|
||||||
rayDir.X = toCamX;
|
rayDir.X = toCamX;
|
||||||
rayDir.Y = toCamY;
|
rayDir.Y = toCamY;
|
||||||
rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
|
rayDir.Z = (-toCamX * norm.X - toCamY * norm.Y) / norm.Z;
|
||||||
|
|
|
@ -2586,7 +2586,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = 0;
|
req.Count = 0;
|
||||||
req.filter = RayFilterFlags.All;
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_rayCastManager.QueueRequest(req);
|
m_rayCastManager.QueueRequest(req);
|
||||||
}
|
}
|
||||||
|
@ -2603,7 +2603,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = Count;
|
req.Count = Count;
|
||||||
req.filter = RayFilterFlags.All;
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
m_rayCastManager.QueueRequest(req);
|
m_rayCastManager.QueueRequest(req);
|
||||||
}
|
}
|
||||||
|
@ -2631,7 +2631,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
req.Normal = direction;
|
req.Normal = direction;
|
||||||
req.Origin = position;
|
req.Origin = position;
|
||||||
req.Count = Count;
|
req.Count = Count;
|
||||||
req.filter = RayFilterFlags.All;
|
req.filter = RayFilterFlags.AllPrims;
|
||||||
|
|
||||||
lock (SyncObject)
|
lock (SyncObject)
|
||||||
{
|
{
|
||||||
|
|
|
@ -2359,8 +2359,14 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
|
||||||
|
// Teravus: if (m_host.ParentID == 0) is bug code because the ParentID for the Avatar will cause this to be nonzero for root prim attachments
|
||||||
|
// which is then treated like a child prim rotation and it's offset gets cumulatively multiplied against.
|
||||||
|
// to fix the scripted rotations we also have to check to see if the root part localid is the same as the host's localid.
|
||||||
|
// RootPart != null should shortcircuit
|
||||||
|
|
||||||
// try to let this work as in SL...
|
// try to let this work as in SL...
|
||||||
if (m_host.ParentID == 0)
|
if (m_host.ParentID == 0 || (m_host.ParentGroup != null && m_host == m_host.ParentGroup.RootPart))
|
||||||
{
|
{
|
||||||
// special case: If we are root, rotate complete SOG to new rotation
|
// special case: If we are root, rotate complete SOG to new rotation
|
||||||
SetRot(m_host, rot);
|
SetRot(m_host, rot);
|
||||||
|
@ -2443,6 +2449,19 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
Quaternion q = m_host.GetWorldRotation();
|
Quaternion q = m_host.GetWorldRotation();
|
||||||
|
|
||||||
|
if (m_host.ParentGroup != null && m_host.ParentGroup.AttachmentPoint != 0)
|
||||||
|
{
|
||||||
|
ScenePresence avatar = World.GetScenePresence(m_host.ParentGroup.AttachedAvatar);
|
||||||
|
if (avatar != null)
|
||||||
|
{
|
||||||
|
if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
|
||||||
|
q = avatar.CameraRotation * q; // Mouselook
|
||||||
|
else
|
||||||
|
q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2468,7 +2487,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
q = part.ParentGroup.GroupRotation; // just the group rotation
|
q = part.ParentGroup.GroupRotation; // just the group rotation
|
||||||
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
q = part.GetWorldRotation();
|
q = part.GetWorldRotation();
|
||||||
|
if (part.ParentGroup.AttachmentPoint != 0)
|
||||||
|
{
|
||||||
|
ScenePresence avatar = World.GetScenePresence(part.ParentGroup.AttachedAvatar);
|
||||||
|
if (avatar != null)
|
||||||
|
{
|
||||||
|
if ((avatar.AgentControlFlags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_MOUSELOOK) != 0)
|
||||||
|
q = avatar.CameraRotation * q; // Mouselook
|
||||||
|
else
|
||||||
|
q = avatar.Rotation * q; // Currently infrequently updated so may be inaccurate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
return new LSL_Rotation(q.X, q.Y, q.Z, q.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7909,7 +7941,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
LSL_Rotation q = rules.GetQuaternionItem(idx++);
|
LSL_Rotation q = rules.GetQuaternionItem(idx++);
|
||||||
// try to let this work as in SL...
|
// try to let this work as in SL...
|
||||||
if (part.ParentID == 0)
|
if (part.ParentID == 0 || (part.ParentGroup != null && part == part.ParentGroup.RootPart))
|
||||||
{
|
{
|
||||||
// special case: If we are root, rotate complete SOG to new rotation
|
// special case: If we are root, rotate complete SOG to new rotation
|
||||||
SetRot(part, q);
|
SetRot(part, q);
|
||||||
|
@ -8701,7 +8733,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
LSL_List remaining = GetPrimParams(m_host, rules, ref result);
|
LSL_List remaining = GetPrimParams(m_host, rules, ref result);
|
||||||
|
|
||||||
while (remaining != null && remaining.Length > 2)
|
while ((object)remaining != null && remaining.Length > 2)
|
||||||
{
|
{
|
||||||
int linknumber = remaining.GetLSLIntegerItem(0);
|
int linknumber = remaining.GetLSLIntegerItem(0);
|
||||||
rules = remaining.GetSublist(1, -1);
|
rules = remaining.GetSublist(1, -1);
|
||||||
|
@ -8742,11 +8774,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
remaining = GetPrimParams(avatar, rules, ref res);
|
remaining = GetPrimParams(avatar, rules, ref res);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (remaining != null && remaining.Length > 0)
|
if ((object)remaining != null && remaining.Length > 0)
|
||||||
{
|
{
|
||||||
linknumber = remaining.GetLSLIntegerItem(0);
|
linknumber = remaining.GetLSLIntegerItem(0);
|
||||||
rules = remaining.GetSublist(1, -1);
|
rules = remaining.GetSublist(1, -1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
|
|
Loading…
Reference in New Issue