Merge branch 'master' of ssh://3dhosting.de/var/git/careminster
commit
671a97ef76
|
@ -101,6 +101,7 @@ what it is today.
|
|||
* jhurliman
|
||||
* John R Sohn (XenReborn)
|
||||
* jonc
|
||||
* Jon Cundill
|
||||
* Junta Kohime
|
||||
* Kayne
|
||||
* Kevin Cozens
|
||||
|
|
|
@ -142,7 +142,8 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[ASSETS DB]: MySql failure fetching asset " + assetID + ": " + e.Message);
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", assetID), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,10 +244,11 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASSETS DB]: " +
|
||||
"MySql failure updating access_time for asset {0} with name {1}" + Environment.NewLine + e.ToString()
|
||||
+ Environment.NewLine + "Attempting reconnection", asset.FullID, asset.Name);
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: Failure updating access_time for asset {0} with name {1}. Exception ",
|
||||
asset.FullID, asset.Name),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,8 +288,8 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.ErrorFormat(
|
||||
"[ASSETS DB]: MySql failure fetching asset {0}" + Environment.NewLine + e.ToString(), uuid);
|
||||
m_log.Error(
|
||||
string.Format("[ASSETS DB]: MySql failure fetching asset {0}. Exception ", uuid), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -346,7 +348,11 @@ namespace OpenSim.Data.MySQL
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Error("[ASSETS DB]: MySql failure fetching asset set" + Environment.NewLine + e.ToString());
|
||||
m_log.Error(
|
||||
string.Format(
|
||||
"[ASSETS DB]: MySql failure fetching asset set from {0}, count {1}. Exception ",
|
||||
start, count),
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,11 @@ namespace OpenSim.Framework.Servers
|
|||
|
||||
protected void CreatePIDFile(string path)
|
||||
{
|
||||
if (File.Exists(path))
|
||||
m_log.ErrorFormat(
|
||||
"[SERVER BASE]: Previous pid file {0} still exists on startup. Possibly previously unclean shutdown.",
|
||||
path);
|
||||
|
||||
try
|
||||
{
|
||||
string pidstring = System.Diagnostics.Process.GetCurrentProcess().Id.ToString();
|
||||
|
|
|
@ -821,7 +821,7 @@ namespace OpenSim
|
|||
|
||||
if (foundClientServer)
|
||||
{
|
||||
m_clientServers[clientServerElement].NetworkStop();
|
||||
m_clientServers[clientServerElement].Stop();
|
||||
m_clientServers.RemoveAt(clientServerElement);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,11 +38,22 @@ namespace OpenSim.Region.ClientStack
|
|||
IPAddress _listenIP, ref uint port, int proxyPortOffsetParm, bool allow_alternate_port, IConfigSource configSource,
|
||||
AgentCircuitManager authenticateClass);
|
||||
|
||||
void NetworkStop();
|
||||
bool HandlesRegion(Location x);
|
||||
void AddScene(IScene x);
|
||||
|
||||
/// <summary>
|
||||
/// Add the given scene to be handled by this IClientNetworkServer.
|
||||
/// </summary>
|
||||
/// <param name='scene'></param>
|
||||
void AddScene(IScene scene);
|
||||
|
||||
/// <summary>
|
||||
/// Start sending and receiving data.
|
||||
/// </summary>
|
||||
void Start();
|
||||
|
||||
/// <summary>
|
||||
/// Stop sending and receiving data.
|
||||
/// </summary>
|
||||
void Stop();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -823,12 +823,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
handshake.RegionInfo3.ProductName = Util.StringToBytes256(regionInfo.RegionType);
|
||||
handshake.RegionInfo3.ProductSKU = Utils.EmptyBytes;
|
||||
|
||||
handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[0];
|
||||
// OutPacket(handshake, ThrottleOutPacketType.Task);
|
||||
// use same as MoveAgentIntoRegion (both should be task )
|
||||
handshake.RegionInfo4 = new RegionHandshakePacket.RegionInfo4Block[1];
|
||||
handshake.RegionInfo4[0] = new RegionHandshakePacket.RegionInfo4Block();
|
||||
handshake.RegionInfo4[0].RegionFlagsExtended = args.regionFlags;
|
||||
handshake.RegionInfo4[0].RegionProtocols = 0; // 1 here would indicate that SSB is supported
|
||||
|
||||
OutPacket(handshake, ThrottleOutPacketType.Unknown);
|
||||
}
|
||||
|
||||
|
||||
public void MoveAgentIntoRegion(RegionInfo regInfo, Vector3 pos, Vector3 look)
|
||||
{
|
||||
AgentMovementCompletePacket mov = (AgentMovementCompletePacket)PacketPool.Instance.GetPacket(PacketType.AgentMovementComplete);
|
||||
|
|
|
@ -62,11 +62,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
|
|||
m_udpServer = new LLUDPServer(listenIP, ref port, proxyPortOffsetParm, allow_alternate_port, configSource, circuitManager);
|
||||
}
|
||||
|
||||
public void NetworkStop()
|
||||
{
|
||||
m_udpServer.Stop();
|
||||
}
|
||||
|
||||
public void AddScene(IScene scene)
|
||||
{
|
||||
m_udpServer.AddScene(scene);
|
||||
|
|
|
@ -358,7 +358,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
bool asAttachment)
|
||||
{
|
||||
CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero);
|
||||
Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
|
||||
// Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>();
|
||||
|
||||
foreach (SceneObjectGroup objectGroup in objlist)
|
||||
{
|
||||
|
@ -379,7 +379,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
objectGroup.AbsolutePosition.Z);
|
||||
|
||||
Quaternion inventoryStoredRotation = objectGroup.GroupRotation;
|
||||
originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
|
||||
//originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition;
|
||||
|
||||
// Restore attachment data after trip through the sim
|
||||
if (objectGroup.RootPart.AttachPoint > 0)
|
||||
|
@ -418,9 +418,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
else
|
||||
itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment);
|
||||
|
||||
// Restore the position of each group now that it has been stored to inventory.
|
||||
foreach (SceneObjectGroup objectGroup in objlist)
|
||||
objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
|
||||
// // Restore the position of each group now that it has been stored to inventory.
|
||||
// foreach (SceneObjectGroup objectGroup in objlist)
|
||||
// objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID];
|
||||
|
||||
InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID);
|
||||
|
||||
|
@ -866,7 +866,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
return null;
|
||||
}
|
||||
|
||||
if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment))
|
||||
if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment))
|
||||
return null;
|
||||
|
||||
for (int i = 0; i < objlist.Count; i++)
|
||||
|
@ -965,10 +965,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
/// <param name="item"></param>
|
||||
/// <param name="objlist"></param>
|
||||
/// <param name="pos"></param>
|
||||
/// <param name="veclist">
|
||||
/// List of vector position adjustments for a coalesced objects. For ordinary objects
|
||||
/// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist
|
||||
/// </param>
|
||||
/// <param name="isAttachment"></param>
|
||||
/// <returns>true if we can processed with rezzing, false if we need to abort</returns>
|
||||
private bool DoPreRezWhenFromItem(
|
||||
IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment)
|
||||
IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist,
|
||||
Vector3 pos, List<Vector3> veclist, bool isAttachment)
|
||||
{
|
||||
UUID fromUserInventoryItemId = UUID.Zero;
|
||||
|
||||
|
@ -991,12 +996,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
}
|
||||
}
|
||||
|
||||
int primcount = 0;
|
||||
foreach (SceneObjectGroup g in objlist)
|
||||
primcount += g.PrimCount;
|
||||
for (int i = 0; i < objlist.Count; i++)
|
||||
{
|
||||
SceneObjectGroup g = objlist[i];
|
||||
|
||||
if (!m_Scene.Permissions.CanRezObject(
|
||||
primcount, remoteClient.AgentId, pos)
|
||||
g.PrimCount, remoteClient.AgentId, pos + veclist[i])
|
||||
&& !isAttachment)
|
||||
{
|
||||
// The client operates in no fail mode. It will
|
||||
|
@ -1010,10 +1015,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess
|
|||
ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y);
|
||||
remoteClient.SendAlertMessage(string.Format(
|
||||
"Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.",
|
||||
item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName));
|
||||
item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name));
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < objlist.Count; i++)
|
||||
{
|
||||
|
|
|
@ -412,7 +412,6 @@ namespace OpenSim.Region.CoreModules.Scripting.HttpRequest
|
|||
//public bool HttpVerboseThrottle = true; // not implemented
|
||||
public List<string> HttpCustomHeaders = null;
|
||||
public bool HttpPragmaNoCache = true;
|
||||
private Thread httpThread;
|
||||
|
||||
// Request info
|
||||
private UUID _itemID;
|
||||
|
|
|
@ -1453,6 +1453,8 @@ namespace OpenSim.Region.CoreModules.World.Permissions
|
|||
|
||||
bool permission = false;
|
||||
|
||||
// m_log.DebugFormat("[PERMISSIONS MODULE]: Checking rez object at {0} in {1}", objectPosition, m_scene.Name);
|
||||
|
||||
ILandObject land = m_scene.LandChannel.GetLandObject(objectPosition.X, objectPosition.Y);
|
||||
if (land == null) return false;
|
||||
|
||||
|
|
|
@ -5647,12 +5647,12 @@ Environment.Exit(1);
|
|||
List<SceneObjectGroup> objects,
|
||||
out float minX, out float maxX, out float minY, out float maxY, out float minZ, out float maxZ)
|
||||
{
|
||||
minX = 256;
|
||||
maxX = -256;
|
||||
minY = 256;
|
||||
maxY = -256;
|
||||
minZ = 8192;
|
||||
maxZ = -256;
|
||||
minX = float.MaxValue;
|
||||
maxX = float.MinValue;
|
||||
minY = float.MaxValue;
|
||||
maxY = float.MinValue;
|
||||
minZ = float.MaxValue;
|
||||
maxZ = float.MinValue;
|
||||
|
||||
List<Vector3> offsets = new List<Vector3>();
|
||||
|
||||
|
|
|
@ -5005,6 +5005,14 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
oldTex.DefaultTexture = fallbackOldFace;
|
||||
}
|
||||
|
||||
// Materials capable viewers can send a ObjectImage packet
|
||||
// when nothing in TE has changed. MaterialID should be updated
|
||||
// by the RenderMaterials CAP handler, so updating it here may cause a
|
||||
// race condtion. Therefore, if no non-materials TE fields have changed,
|
||||
// we should ignore any changes and not update Shape.TextureEntry
|
||||
|
||||
bool otherFieldsChanged = false;
|
||||
|
||||
for (int i = 0 ; i < GetNumberOfSides(); i++)
|
||||
{
|
||||
|
||||
|
@ -5031,8 +5039,25 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
// Max change, skip the rest of testing
|
||||
if (changeFlags == (Changed.TEXTURE | Changed.COLOR))
|
||||
break;
|
||||
|
||||
if (!otherFieldsChanged)
|
||||
{
|
||||
if (oldFace.Bump != newFace.Bump) otherFieldsChanged = true;
|
||||
if (oldFace.Fullbright != newFace.Fullbright) otherFieldsChanged = true;
|
||||
if (oldFace.Glow != newFace.Glow) otherFieldsChanged = true;
|
||||
if (oldFace.MediaFlags != newFace.MediaFlags) otherFieldsChanged = true;
|
||||
if (oldFace.OffsetU != newFace.OffsetU) otherFieldsChanged = true;
|
||||
if (oldFace.OffsetV != newFace.OffsetV) otherFieldsChanged = true;
|
||||
if (oldFace.RepeatU != newFace.RepeatU) otherFieldsChanged = true;
|
||||
if (oldFace.RepeatV != newFace.RepeatV) otherFieldsChanged = true;
|
||||
if (oldFace.Rotation != newFace.Rotation) otherFieldsChanged = true;
|
||||
if (oldFace.Shiny != newFace.Shiny) otherFieldsChanged = true;
|
||||
if (oldFace.TexMapType != newFace.TexMapType) otherFieldsChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changeFlags != 0 || otherFieldsChanged)
|
||||
{
|
||||
m_shape.TextureEntry = newTex.GetBytes();
|
||||
if (changeFlags != 0)
|
||||
TriggerScriptChangedEvent(changeFlags);
|
||||
|
@ -5044,6 +5069,7 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
//This is sparta
|
||||
ScheduleFullUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void UpdatePhysicsSubscribedEvents()
|
||||
|
|
|
@ -0,0 +1,579 @@
|
|||
/*
|
||||
* 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 System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using System.Security.Cryptography; // for computing md5 hash
|
||||
using log4net;
|
||||
using Mono.Addins;
|
||||
using Nini.Config;
|
||||
|
||||
using OpenMetaverse;
|
||||
using OpenMetaverse.StructuredData;
|
||||
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Servers.HttpServer;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
|
||||
using Ionic.Zlib;
|
||||
|
||||
// You will need to uncomment these lines if you are adding a region module to some other assembly which does not already
|
||||
// specify its assembly. Otherwise, the region modules in the assembly will not be picked up when OpenSimulator scans
|
||||
// the available DLLs
|
||||
//[assembly: Addin("MaterialsDemoModule", "1.0")]
|
||||
//[assembly: AddinDependency("OpenSim", "0.5")]
|
||||
|
||||
namespace OpenSim.Region.OptionalModules.MaterialsDemoModule
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
// # # ## ##### # # # # # ####
|
||||
// # # # # # # ## # # ## # # #
|
||||
// # # # # # # # # # # # # # #
|
||||
// # ## # ###### ##### # # # # # # # # ###
|
||||
// ## ## # # # # # ## # # ## # #
|
||||
// # # # # # # # # # # # ####
|
||||
//
|
||||
// THIS MODULE IS FOR EXPERIMENTAL USE ONLY AND MAY CAUSE REGION OR ASSET CORRUPTION!
|
||||
//
|
||||
////////////// WARNING //////////////////////////////////////////////////////////////////
|
||||
/// This is an *Experimental* module for developing support for materials-capable viewers
|
||||
/// This module should NOT be used in a production environment! It may cause data corruption and
|
||||
/// viewer crashes. It should be only used to evaluate implementations of materials.
|
||||
///
|
||||
/// Materials are persisted via SceneObjectPart.dynattrs. This is a relatively new feature
|
||||
/// of OpenSimulator and is not field proven at the time this module was written. Persistence
|
||||
/// may fail or become corrupt and this could cause viewer crashes due to erroneous materials
|
||||
/// data being sent to viewers. Materials descriptions might survive IAR, OAR, or other means
|
||||
/// of archiving however the texture resources used by these materials probably will not as they
|
||||
/// may not be adequately referenced to ensure proper archiving.
|
||||
///
|
||||
///
|
||||
///
|
||||
/// To enable this module, add this string at the bottom of OpenSim.ini:
|
||||
/// [MaterialsDemoModule]
|
||||
///
|
||||
/// </summary>
|
||||
///
|
||||
|
||||
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MaterialsDemoModule")]
|
||||
public class MaterialsDemoModule : INonSharedRegionModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public string Name { get { return "MaterialsDemoModule"; } }
|
||||
|
||||
public Type ReplaceableInterface { get { return null; } }
|
||||
|
||||
private Scene m_scene = null;
|
||||
private bool m_enabled = false;
|
||||
|
||||
public Dictionary<UUID, OSDMap> m_knownMaterials = new Dictionary<UUID, OSDMap>();
|
||||
|
||||
public void Initialise(IConfigSource source)
|
||||
{
|
||||
m_enabled = (source.Configs["MaterialsDemoModule"] != null);
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[MaterialsDemoModule]: INITIALIZED MODULE");
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[MaterialsDemoModule]: CLOSED MODULE");
|
||||
}
|
||||
|
||||
public void AddRegion(Scene scene)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[MaterialsDemoModule]: REGION {0} ADDED", scene.RegionInfo.RegionName);
|
||||
m_scene = scene;
|
||||
m_scene.EventManager.OnRegisterCaps += new EventManager.RegisterCapsEvent(OnRegisterCaps);
|
||||
m_scene.EventManager.OnObjectAddedToScene += new Action<SceneObjectGroup>(EventManager_OnObjectAddedToScene);
|
||||
}
|
||||
|
||||
void EventManager_OnObjectAddedToScene(SceneObjectGroup obj)
|
||||
{
|
||||
foreach (var part in obj.Parts)
|
||||
if (part != null)
|
||||
GetStoredMaterialsForPart(part);
|
||||
}
|
||||
|
||||
void OnRegisterCaps(OpenMetaverse.UUID agentID, OpenSim.Framework.Capabilities.Caps caps)
|
||||
{
|
||||
string capsBase = "/CAPS/" + caps.CapsObjectPath;
|
||||
|
||||
IRequestHandler renderMaterialsPostHandler = new RestStreamHandler("POST", capsBase + "/", RenderMaterialsPostCap);
|
||||
caps.RegisterHandler("RenderMaterials", renderMaterialsPostHandler);
|
||||
|
||||
// OpenSimulator CAPs infrastructure seems to be somewhat hostile towards any CAP that requires both GET
|
||||
// and POST handlers, (at least at the time this was originally written), so we first set up a POST
|
||||
// handler normally and then add a GET handler via MainServer
|
||||
|
||||
IRequestHandler renderMaterialsGetHandler = new RestStreamHandler("GET", capsBase + "/", RenderMaterialsGetCap);
|
||||
MainServer.Instance.AddStreamHandler(renderMaterialsGetHandler);
|
||||
|
||||
// materials viewer seems to use either POST or PUT, so assign POST handler for PUT as well
|
||||
IRequestHandler renderMaterialsPutHandler = new RestStreamHandler("PUT", capsBase + "/", RenderMaterialsPostCap);
|
||||
MainServer.Instance.AddStreamHandler(renderMaterialsPutHandler);
|
||||
}
|
||||
|
||||
public void RemoveRegion(Scene scene)
|
||||
{
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
m_log.DebugFormat("[MaterialsDemoModule]: REGION {0} REMOVED", scene.RegionInfo.RegionName);
|
||||
}
|
||||
|
||||
public void RegionLoaded(Scene scene)
|
||||
{
|
||||
}
|
||||
|
||||
OSDMap GetMaterial(UUID id)
|
||||
{
|
||||
OSDMap map = null;
|
||||
if (m_knownMaterials.ContainsKey(id))
|
||||
{
|
||||
map = new OSDMap();
|
||||
map["ID"] = OSD.FromBinary(id.GetBytes());
|
||||
map["Material"] = m_knownMaterials[id];
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
void GetStoredMaterialsForPart(SceneObjectPart part)
|
||||
{
|
||||
OSDMap OSMaterials = null;
|
||||
OSDArray matsArr = null;
|
||||
|
||||
if (part.DynAttrs == null)
|
||||
{
|
||||
m_log.Warn("[MaterialsDemoModule]: NULL DYNATTRS :( ");
|
||||
}
|
||||
|
||||
lock (part.DynAttrs)
|
||||
{
|
||||
if (part.DynAttrs.ContainsKey("OS:Materials"))
|
||||
OSMaterials = part.DynAttrs["OS:Materials"];
|
||||
if (OSMaterials != null && OSMaterials.ContainsKey("Materials"))
|
||||
{
|
||||
|
||||
OSD osd = OSMaterials["Materials"];
|
||||
if (osd is OSDArray)
|
||||
matsArr = osd as OSDArray;
|
||||
}
|
||||
}
|
||||
|
||||
if (OSMaterials == null)
|
||||
return;
|
||||
|
||||
m_log.Info("[MaterialsDemoModule]: OSMaterials: " + OSDParser.SerializeJsonString(OSMaterials));
|
||||
|
||||
|
||||
if (matsArr == null)
|
||||
{
|
||||
m_log.Info("[MaterialsDemoModule]: matsArr is null :( ");
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (OSD elemOsd in matsArr)
|
||||
{
|
||||
if (elemOsd != null && elemOsd is OSDMap)
|
||||
{
|
||||
|
||||
OSDMap matMap = elemOsd as OSDMap;
|
||||
if (matMap.ContainsKey("ID") && matMap.ContainsKey("Material"))
|
||||
{
|
||||
try
|
||||
{
|
||||
m_knownMaterials[matMap["ID"].AsUUID()] = (OSDMap)matMap["Material"];
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[MaterialsDemoModule]: exception decoding persisted material: " + e.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void StoreMaterialsForPart(SceneObjectPart part)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (part == null || part.Shape == null)
|
||||
return;
|
||||
|
||||
Dictionary<UUID, OSDMap> mats = new Dictionary<UUID, OSDMap>();
|
||||
|
||||
Primitive.TextureEntry te = part.Shape.Textures;
|
||||
|
||||
if (te.DefaultTexture != null)
|
||||
{
|
||||
if (m_knownMaterials.ContainsKey(te.DefaultTexture.MaterialID))
|
||||
mats[te.DefaultTexture.MaterialID] = m_knownMaterials[te.DefaultTexture.MaterialID];
|
||||
}
|
||||
|
||||
if (te.FaceTextures != null)
|
||||
{
|
||||
foreach (var face in te.FaceTextures)
|
||||
{
|
||||
if (face != null)
|
||||
{
|
||||
if (m_knownMaterials.ContainsKey(face.MaterialID))
|
||||
mats[face.MaterialID] = m_knownMaterials[face.MaterialID];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mats.Count == 0)
|
||||
return;
|
||||
|
||||
OSDArray matsArr = new OSDArray();
|
||||
foreach (KeyValuePair<UUID, OSDMap> kvp in mats)
|
||||
{
|
||||
OSDMap matOsd = new OSDMap();
|
||||
matOsd["ID"] = OSD.FromUUID(kvp.Key);
|
||||
matOsd["Material"] = kvp.Value;
|
||||
matsArr.Add(matOsd);
|
||||
}
|
||||
|
||||
OSDMap OSMaterials = new OSDMap();
|
||||
OSMaterials["Materials"] = matsArr;
|
||||
|
||||
lock (part.DynAttrs)
|
||||
part.DynAttrs["OS:Materials"] = OSMaterials;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[MaterialsDemoModule]: exception in StoreMaterialsForPart(): " + e.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public string RenderMaterialsPostCap(string request, string path,
|
||||
string param, IOSHttpRequest httpRequest,
|
||||
IOSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.Debug("[MaterialsDemoModule]: POST cap handler");
|
||||
|
||||
OSDMap req = (OSDMap)OSDParser.DeserializeLLSDXml(request);
|
||||
OSDMap resp = new OSDMap();
|
||||
|
||||
OSDMap materialsFromViewer = null;
|
||||
|
||||
OSDArray respArr = new OSDArray();
|
||||
|
||||
if (req.ContainsKey("Zipped"))
|
||||
{
|
||||
OSD osd = null;
|
||||
|
||||
byte[] inBytes = req["Zipped"].AsBinary();
|
||||
|
||||
try
|
||||
{
|
||||
osd = ZDecompressBytesToOsd(inBytes);
|
||||
|
||||
if (osd != null)
|
||||
{
|
||||
if (osd is OSDArray) // assume array of MaterialIDs designating requested material entries
|
||||
{
|
||||
foreach (OSD elem in (OSDArray)osd)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
UUID id = new UUID(elem.AsBinary(), 0);
|
||||
|
||||
if (m_knownMaterials.ContainsKey(id))
|
||||
{
|
||||
m_log.Info("[MaterialsDemoModule]: request for known material ID: " + id.ToString());
|
||||
OSDMap matMap = new OSDMap();
|
||||
matMap["ID"] = OSD.FromBinary(id.GetBytes());
|
||||
|
||||
matMap["Material"] = m_knownMaterials[id];
|
||||
respArr.Add(matMap);
|
||||
}
|
||||
else
|
||||
m_log.Info("[MaterialsDemoModule]: request for UNKNOWN material ID: " + id.ToString());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// report something here?
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (osd is OSDMap) // reqest to assign a material
|
||||
{
|
||||
materialsFromViewer = osd as OSDMap;
|
||||
|
||||
if (materialsFromViewer.ContainsKey("FullMaterialsPerFace"))
|
||||
{
|
||||
OSD matsOsd = materialsFromViewer["FullMaterialsPerFace"];
|
||||
if (matsOsd is OSDArray)
|
||||
{
|
||||
OSDArray matsArr = matsOsd as OSDArray;
|
||||
|
||||
try
|
||||
{
|
||||
foreach (OSDMap matsMap in matsArr)
|
||||
{
|
||||
m_log.Debug("[MaterialsDemoModule]: processing matsMap: " + OSDParser.SerializeJsonString(matsMap));
|
||||
|
||||
uint matLocalID = 0;
|
||||
try { matLocalID = matsMap["ID"].AsUInteger(); }
|
||||
catch (Exception e) { m_log.Warn("[MaterialsDemoModule]: cannot decode \"ID\" from matsMap: " + e.Message); }
|
||||
m_log.Debug("[MaterialsDemoModule]: matLocalId: " + matLocalID.ToString());
|
||||
|
||||
|
||||
OSDMap mat = null;
|
||||
try { mat = matsMap["Material"] as OSDMap; }
|
||||
catch (Exception e) { m_log.Warn("[MaterialsDemoModule]: cannot decode \"Material\" from matsMap: " + e.Message); }
|
||||
m_log.Debug("[MaterialsDemoModule]: mat: " + OSDParser.SerializeJsonString(mat));
|
||||
|
||||
UUID id = HashOsd(mat);
|
||||
m_knownMaterials[id] = mat;
|
||||
|
||||
|
||||
var sop = m_scene.GetSceneObjectPart(matLocalID);
|
||||
if (sop == null)
|
||||
m_log.Debug("[MaterialsDemoModule]: null SOP for localId: " + matLocalID.ToString());
|
||||
else
|
||||
{
|
||||
//var te = sop.Shape.Textures;
|
||||
var te = new Primitive.TextureEntry(sop.Shape.TextureEntry, 0, sop.Shape.TextureEntry.Length);
|
||||
|
||||
if (te == null)
|
||||
{
|
||||
m_log.Debug("[MaterialsDemoModule]: null TextureEntry for localId: " + matLocalID.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
int face = -1;
|
||||
|
||||
if (matsMap.ContainsKey("Face"))
|
||||
{
|
||||
face = matsMap["Face"].AsInteger();
|
||||
if (te.FaceTextures == null) // && face == 0)
|
||||
{
|
||||
if (te.DefaultTexture == null)
|
||||
m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture is null");
|
||||
else
|
||||
{
|
||||
if (te.DefaultTexture.MaterialID == null)
|
||||
m_log.Debug("[MaterialsDemoModule]: te.DefaultTexture.MaterialID is null");
|
||||
else
|
||||
{
|
||||
te.DefaultTexture.MaterialID = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (te.FaceTextures.Length >= face - 1)
|
||||
{
|
||||
if (te.FaceTextures[face] == null)
|
||||
te.DefaultTexture.MaterialID = id;
|
||||
else
|
||||
te.FaceTextures[face].MaterialID = id;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (te.DefaultTexture != null)
|
||||
te.DefaultTexture.MaterialID = id;
|
||||
}
|
||||
|
||||
m_log.Debug("[MaterialsDemoModule]: setting material ID for face " + face.ToString() + " to " + id.ToString());
|
||||
|
||||
//we cant use sop.UpdateTextureEntry(te); because it filters so do it manually
|
||||
|
||||
if (sop.ParentGroup != null)
|
||||
{
|
||||
sop.Shape.TextureEntry = te.GetBytes();
|
||||
sop.TriggerScriptChangedEvent(Changed.TEXTURE);
|
||||
sop.UpdateFlag = UpdateRequired.FULL;
|
||||
sop.ParentGroup.HasGroupChanged = true;
|
||||
|
||||
sop.ScheduleFullUpdate();
|
||||
|
||||
StoreMaterialsForPart(sop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[MaterialsDemoModule]: exception processing received material: " + e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn("[MaterialsDemoModule]: exception decoding zipped CAP payload: " + e.Message);
|
||||
//return "";
|
||||
}
|
||||
m_log.Debug("[MaterialsDemoModule]: knownMaterials.Count: " + m_knownMaterials.Count.ToString());
|
||||
}
|
||||
|
||||
|
||||
resp["Zipped"] = ZCompressOSD(respArr, false);
|
||||
string response = OSDParser.SerializeLLSDXmlString(resp);
|
||||
|
||||
//m_log.Debug("[MaterialsDemoModule]: cap request: " + request);
|
||||
m_log.Debug("[MaterialsDemoModule]: cap request (zipped portion): " + ZippedOsdBytesToString(req["Zipped"].AsBinary()));
|
||||
m_log.Debug("[MaterialsDemoModule]: cap response: " + response);
|
||||
return response;
|
||||
}
|
||||
|
||||
|
||||
public string RenderMaterialsGetCap(string request, string path,
|
||||
string param, IOSHttpRequest httpRequest,
|
||||
IOSHttpResponse httpResponse)
|
||||
{
|
||||
m_log.Debug("[MaterialsDemoModule]: GET cap handler");
|
||||
|
||||
OSDMap resp = new OSDMap();
|
||||
|
||||
|
||||
int matsCount = 0;
|
||||
|
||||
OSDArray allOsd = new OSDArray();
|
||||
|
||||
foreach (KeyValuePair<UUID, OSDMap> kvp in m_knownMaterials)
|
||||
{
|
||||
OSDMap matMap = new OSDMap();
|
||||
|
||||
matMap["ID"] = OSD.FromBinary(kvp.Key.GetBytes());
|
||||
|
||||
matMap["Material"] = kvp.Value;
|
||||
allOsd.Add(matMap);
|
||||
matsCount++;
|
||||
}
|
||||
|
||||
|
||||
resp["Zipped"] = ZCompressOSD(allOsd, false);
|
||||
m_log.Debug("[MaterialsDemoModule]: matsCount: " + matsCount.ToString());
|
||||
|
||||
return OSDParser.SerializeLLSDXmlString(resp);
|
||||
}
|
||||
|
||||
static string ZippedOsdBytesToString(byte[] bytes)
|
||||
{
|
||||
try
|
||||
{
|
||||
return OSDParser.SerializeJsonString(ZDecompressBytesToOsd(bytes));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
return "ZippedOsdBytesToString caught an exception: " + e.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// computes a UUID by hashing a OSD object
|
||||
/// </summary>
|
||||
/// <param name="osd"></param>
|
||||
/// <returns></returns>
|
||||
private static UUID HashOsd(OSD osd)
|
||||
{
|
||||
using (var md5 = MD5.Create())
|
||||
using (MemoryStream ms = new MemoryStream(OSDParser.SerializeLLSDBinary(osd, false)))
|
||||
return new UUID(md5.ComputeHash(ms), 0);
|
||||
}
|
||||
|
||||
public static OSD ZCompressOSD(OSD inOsd, bool useHeader)
|
||||
{
|
||||
OSD osd = null;
|
||||
|
||||
using (MemoryStream msSinkCompressed = new MemoryStream())
|
||||
{
|
||||
using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkCompressed,
|
||||
Ionic.Zlib.CompressionMode.Compress, CompressionLevel.BestCompression, true))
|
||||
{
|
||||
CopyStream(new MemoryStream(OSDParser.SerializeLLSDBinary(inOsd, useHeader)), zOut);
|
||||
zOut.Close();
|
||||
}
|
||||
|
||||
msSinkCompressed.Seek(0L, SeekOrigin.Begin);
|
||||
osd = OSD.FromBinary( msSinkCompressed.ToArray());
|
||||
}
|
||||
|
||||
return osd;
|
||||
}
|
||||
|
||||
|
||||
public static OSD ZDecompressBytesToOsd(byte[] input)
|
||||
{
|
||||
OSD osd = null;
|
||||
|
||||
using (MemoryStream msSinkUnCompressed = new MemoryStream())
|
||||
{
|
||||
using (Ionic.Zlib.ZlibStream zOut = new Ionic.Zlib.ZlibStream(msSinkUnCompressed, CompressionMode.Decompress, true))
|
||||
{
|
||||
CopyStream(new MemoryStream(input), zOut);
|
||||
zOut.Close();
|
||||
}
|
||||
msSinkUnCompressed.Seek(0L, SeekOrigin.Begin);
|
||||
osd = OSDParser.DeserializeLLSDBinary(msSinkUnCompressed.ToArray());
|
||||
}
|
||||
|
||||
return osd;
|
||||
}
|
||||
|
||||
static void CopyStream(System.IO.Stream input, System.IO.Stream output)
|
||||
{
|
||||
byte[] buffer = new byte[2048];
|
||||
int len;
|
||||
while ((len = input.Read(buffer, 0, 2048)) > 0)
|
||||
{
|
||||
output.Write(buffer, 0, len);
|
||||
}
|
||||
|
||||
output.Flush();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,285 @@
|
|||
/*
|
||||
* 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 copyrightD
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorAvatarMove : BSActor
|
||||
{
|
||||
BSVMotor m_velocityMotor;
|
||||
|
||||
public BSActorAvatarMove(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_velocityMotor = null;
|
||||
m_physicsScene.DetailLog("{0},BSActorAvatarMove,constructor", m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorAvatarMove,refresh", m_controllingPrim.LocalID);
|
||||
|
||||
// If the object is physically active, add the hoverer prestep action
|
||||
if (isActive)
|
||||
{
|
||||
ActivateAvatarMove();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeactivateAvatarMove();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
||||
// Usually called when target velocity changes to set the current velocity and the target
|
||||
// into the movement motor.
|
||||
public void SetVelocityAndTarget(OMV.Vector3 vel, OMV.Vector3 targ, bool inTaintTime)
|
||||
{
|
||||
m_physicsScene.TaintedObject(inTaintTime, "BSActorAvatarMove.setVelocityAndTarget", delegate()
|
||||
{
|
||||
if (m_velocityMotor != null)
|
||||
{
|
||||
m_velocityMotor.Reset();
|
||||
m_velocityMotor.SetTarget(targ);
|
||||
m_velocityMotor.SetCurrent(vel);
|
||||
m_velocityMotor.Enabled = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If a hover motor has not been created, create one and start the hovering.
|
||||
private void ActivateAvatarMove()
|
||||
{
|
||||
if (m_velocityMotor == null)
|
||||
{
|
||||
// Infinite decay and timescale values so motor only changes current to target values.
|
||||
m_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||
0.2f, // time scale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
SetVelocityAndTarget(m_controllingPrim.RawVelocity, m_controllingPrim.TargetVelocity, true /* inTaintTime */);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeactivateAvatarMove()
|
||||
{
|
||||
if (m_velocityMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
m_velocityMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
private void Mover(float timeStep)
|
||||
{
|
||||
// Don't do movement while the object is selected.
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
// TODO: Decide if the step parameters should be changed depending on the avatar's
|
||||
// state (flying, colliding, ...). There is code in ODE to do this.
|
||||
|
||||
// COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
|
||||
// specified for the avatar is the one that should be used. For falling, if the avatar
|
||||
// is not flying and is not colliding then it is presumed to be falling and the Z
|
||||
// component is not fooled with (thus allowing gravity to do its thing).
|
||||
// When the avatar is standing, though, the user has specified a velocity of zero and
|
||||
// the avatar should be standing. But if the avatar is pushed by something in the world
|
||||
// (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
|
||||
// move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
|
||||
// errors can creap in and the avatar will slowly float off in some direction.
|
||||
// So, the problem is that, when an avatar is standing, we cannot tell creaping error
|
||||
// from real pushing.
|
||||
// The code below uses whether the collider is static or moving to decide whether to zero motion.
|
||||
|
||||
m_velocityMotor.Step(timeStep);
|
||||
m_controllingPrim.IsStationary = false;
|
||||
|
||||
// If we're not supposed to be moving, make sure things are zero.
|
||||
if (m_velocityMotor.ErrorIsZero() && m_velocityMotor.TargetValue == OMV.Vector3.Zero)
|
||||
{
|
||||
// The avatar shouldn't be moving
|
||||
m_velocityMotor.Zero();
|
||||
|
||||
if (m_controllingPrim.IsColliding)
|
||||
{
|
||||
// If we are colliding with a stationary object, presume we're standing and don't move around
|
||||
if (!m_controllingPrim.ColliderIsMoving)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", m_controllingPrim.LocalID);
|
||||
m_controllingPrim.IsStationary = true;
|
||||
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
|
||||
// Standing has more friction on the ground
|
||||
if (m_controllingPrim.Friction != BSParam.AvatarStandingFriction)
|
||||
{
|
||||
m_controllingPrim.Friction = BSParam.AvatarStandingFriction;
|
||||
m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_controllingPrim.Flying)
|
||||
{
|
||||
// Flying and not collising and velocity nearly zero.
|
||||
m_controllingPrim.ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
}
|
||||
|
||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}",
|
||||
m_controllingPrim.LocalID, m_velocityMotor.TargetValue, m_controllingPrim.IsColliding);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Supposed to be moving.
|
||||
OMV.Vector3 stepVelocity = m_velocityMotor.CurrentValue;
|
||||
|
||||
if (m_controllingPrim.Friction != BSParam.AvatarFriction)
|
||||
{
|
||||
// Probably starting up walking. Set friction to moving friction.
|
||||
m_controllingPrim.Friction = BSParam.AvatarFriction;
|
||||
m_physicsScene.PE.SetFriction(m_controllingPrim.PhysBody, m_controllingPrim.Friction);
|
||||
}
|
||||
|
||||
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
||||
// The check for RawVelocity.Z < 0 makes jumping work (temporary upward force).
|
||||
if (!m_controllingPrim.Flying && !m_controllingPrim.IsColliding)
|
||||
{
|
||||
if (m_controllingPrim.RawVelocity.Z < 0)
|
||||
stepVelocity.Z = m_controllingPrim.RawVelocity.Z;
|
||||
// DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
|
||||
}
|
||||
|
||||
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
|
||||
OMV.Vector3 moveForce = (stepVelocity - m_controllingPrim.RawVelocity) * m_controllingPrim.Mass;
|
||||
|
||||
// Should we check for move force being small and forcing velocity to zero?
|
||||
|
||||
// Add special movement force to allow avatars to walk up stepped surfaces.
|
||||
moveForce += WalkUpStairs();
|
||||
|
||||
m_physicsScene.DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}",
|
||||
m_controllingPrim.LocalID, stepVelocity, m_controllingPrim.RawVelocity, m_controllingPrim.Mass, moveForce);
|
||||
m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, moveForce);
|
||||
}
|
||||
}
|
||||
|
||||
// Decide if the character is colliding with a low object and compute a force to pop the
|
||||
// avatar up so it can walk up and over the low objects.
|
||||
private OMV.Vector3 WalkUpStairs()
|
||||
{
|
||||
OMV.Vector3 ret = OMV.Vector3.Zero;
|
||||
|
||||
// This test is done if moving forward, not flying and is colliding with something.
|
||||
// DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
|
||||
// LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
|
||||
if (m_controllingPrim.IsColliding && !m_controllingPrim.Flying && m_controllingPrim.TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
|
||||
{
|
||||
// The range near the character's feet where we will consider stairs
|
||||
float nearFeetHeightMin = m_controllingPrim.RawPosition.Z - (m_controllingPrim.Size.Z / 2f) + 0.05f;
|
||||
float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
|
||||
|
||||
// Look for a collision point that is near the character's feet and is oriented the same as the charactor is
|
||||
foreach (KeyValuePair<uint, ContactPoint> kvp in m_controllingPrim.CollisionsLastTick.m_objCollisionList)
|
||||
{
|
||||
// Don't care about collisions with the terrain
|
||||
if (kvp.Key > m_physicsScene.TerrainManager.HighestTerrainID)
|
||||
{
|
||||
OMV.Vector3 touchPosition = kvp.Value.Position;
|
||||
// DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
|
||||
// LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
|
||||
if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
|
||||
{
|
||||
// This contact is within the 'near the feet' range.
|
||||
// The normal should be our contact point to the object so it is pointing away
|
||||
// thus the difference between our facing orientation and the normal should be small.
|
||||
OMV.Vector3 directionFacing = OMV.Vector3.UnitX * m_controllingPrim.RawOrientation;
|
||||
OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
|
||||
float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
|
||||
if (diff < BSParam.AvatarStepApproachFactor)
|
||||
{
|
||||
// Found the stairs contact point. Push up a little to raise the character.
|
||||
float upForce = (touchPosition.Z - nearFeetHeightMin) * m_controllingPrim.Mass * BSParam.AvatarStepForceFactor;
|
||||
ret = new OMV.Vector3(0f, 0f, upForce);
|
||||
|
||||
// Also move the avatar up for the new height
|
||||
OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
|
||||
m_controllingPrim.ForcePosition = m_controllingPrim.RawPosition + displacement;
|
||||
}
|
||||
m_physicsScene.DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
|
||||
m_controllingPrim.LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,174 @@
|
|||
/*
|
||||
* 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 copyrightD
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorHover : BSActor
|
||||
{
|
||||
private BSFMotor m_hoverMotor;
|
||||
|
||||
public BSActorHover(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_hoverMotor = null;
|
||||
m_physicsScene.DetailLog("{0},BSActorHover,constructor", m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorHover,refresh", m_controllingPrim.LocalID);
|
||||
|
||||
// If not active any more, turn me off
|
||||
if (!m_controllingPrim.HoverActive)
|
||||
{
|
||||
SetEnabled(false);
|
||||
}
|
||||
|
||||
// If the object is physically active, add the hoverer prestep action
|
||||
if (isActive)
|
||||
{
|
||||
ActivateHover();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeactivateHover();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
||||
// If a hover motor has not been created, create one and start the hovering.
|
||||
private void ActivateHover()
|
||||
{
|
||||
if (m_hoverMotor == null)
|
||||
{
|
||||
// Turning the target on
|
||||
m_hoverMotor = new BSFMotor("BSActorHover",
|
||||
m_controllingPrim.HoverTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.Infinite, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
|
||||
m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
|
||||
m_hoverMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
||||
m_physicsScene.BeforeStep += Hoverer;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeactivateHover()
|
||||
{
|
||||
if (m_hoverMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Hoverer;
|
||||
m_hoverMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
private void Hoverer(float timeStep)
|
||||
{
|
||||
// Don't do hovering while the object is selected.
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
m_hoverMotor.SetCurrent(m_controllingPrim.RawPosition.Z);
|
||||
m_hoverMotor.SetTarget(ComputeCurrentHoverHeight());
|
||||
float targetHeight = m_hoverMotor.Step(timeStep);
|
||||
|
||||
// 'targetHeight' is where we'd like the Z of the prim to be at this moment.
|
||||
// Compute the amount of force to push us there.
|
||||
float moveForce = (targetHeight - m_controllingPrim.RawPosition.Z) * m_controllingPrim.RawMass;
|
||||
// Undo anything the object thinks it's doing at the moment
|
||||
moveForce = -m_controllingPrim.RawVelocity.Z * m_controllingPrim.Mass;
|
||||
|
||||
m_physicsScene.PE.ApplyCentralImpulse(m_controllingPrim.PhysBody, new OMV.Vector3(0f, 0f, moveForce));
|
||||
m_physicsScene.DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}",
|
||||
m_controllingPrim.LocalID, targetHeight, moveForce, m_controllingPrim.RawMass);
|
||||
}
|
||||
|
||||
// Based on current position, determine what we should be hovering at now.
|
||||
// Must recompute often. What if we walked offa cliff>
|
||||
private float ComputeCurrentHoverHeight()
|
||||
{
|
||||
float ret = m_controllingPrim.HoverHeight;
|
||||
float groundHeight = m_physicsScene.TerrainManager.GetTerrainHeightAtXYZ(m_controllingPrim.RawPosition);
|
||||
|
||||
switch (m_controllingPrim.HoverType)
|
||||
{
|
||||
case PIDHoverType.Ground:
|
||||
ret = groundHeight + m_controllingPrim.HoverHeight;
|
||||
break;
|
||||
case PIDHoverType.GroundAndWater:
|
||||
float waterHeight = m_physicsScene.TerrainManager.GetWaterLevelAtXYZ(m_controllingPrim.RawPosition);
|
||||
if (groundHeight > waterHeight)
|
||||
{
|
||||
ret = groundHeight + m_controllingPrim.HoverHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = waterHeight + m_controllingPrim.HoverHeight;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -36,11 +36,10 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
public class BSActorLockAxis : BSActor
|
||||
{
|
||||
bool TryExperimentalLockAxisCode = true;
|
||||
BSConstraint LockAxisConstraint = null;
|
||||
|
||||
public BSActorLockAxis(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj,actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,constructor", m_controllingPrim.LocalID);
|
||||
LockAxisConstraint = null;
|
||||
|
@ -69,17 +68,12 @@ public class BSActorLockAxis : BSActor
|
|||
// If all the axis are free, we don't need to exist
|
||||
if (m_controllingPrim.LockedAxis == m_controllingPrim.LockedAxisFree)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorLockAxis,refresh,allAxisFree,removing={1}", m_controllingPrim.LocalID, ActorName);
|
||||
m_controllingPrim.PhysicalActors.RemoveAndRelease(ActorName);
|
||||
return;
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// If the object is physically active, add the axis locking constraint
|
||||
if (Enabled
|
||||
&& m_controllingPrim.IsPhysicallyActive
|
||||
&& TryExperimentalLockAxisCode
|
||||
&& m_controllingPrim.LockedAxis != m_controllingPrim.LockedAxisFree)
|
||||
if (isActive)
|
||||
{
|
||||
if (LockAxisConstraint == null)
|
||||
AddAxisLockConstraint();
|
||||
}
|
||||
else
|
||||
|
@ -99,7 +93,7 @@ public class BSActorLockAxis : BSActor
|
|||
// If a constraint is set up, remove it from the physical scene
|
||||
RemoveAxisLockConstraint();
|
||||
// Schedule a call before the next simulation step to restore the constraint.
|
||||
m_physicsScene.PostTaintObject(m_controllingPrim.LockedAxisActorName, m_controllingPrim.LocalID, delegate()
|
||||
m_physicsScene.PostTaintObject("BSActorLockAxis:" + ActorName, m_controllingPrim.LocalID, delegate()
|
||||
{
|
||||
Refresh();
|
||||
});
|
||||
|
@ -107,6 +101,8 @@ public class BSActorLockAxis : BSActor
|
|||
}
|
||||
|
||||
private void AddAxisLockConstraint()
|
||||
{
|
||||
if (LockAxisConstraint == null)
|
||||
{
|
||||
// Lock that axis by creating a 6DOF constraint that has one end in the world and
|
||||
// the other in the object.
|
||||
|
@ -161,6 +157,7 @@ public class BSActorLockAxis : BSActor
|
|||
|
||||
axisConstrainer.RecomputeConstraintVariables(m_controllingPrim.RawMass);
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveAxisLockConstraint()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* 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 copyrightD
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorMoveToTarget : BSActor
|
||||
{
|
||||
private BSVMotor m_targetMotor;
|
||||
|
||||
public BSActorMoveToTarget(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_targetMotor = null;
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget,constructor", m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget,refresh,enabled={1},active={2},target={3},tau={4}",
|
||||
m_controllingPrim.LocalID, Enabled, m_controllingPrim.MoveToTargetActive,
|
||||
m_controllingPrim.MoveToTargetTarget, m_controllingPrim.MoveToTargetTau );
|
||||
|
||||
// If not active any more...
|
||||
if (!m_controllingPrim.MoveToTargetActive)
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
if (isActive)
|
||||
{
|
||||
ActivateMoveToTarget();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeactivateMoveToTarget();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
// Nothing to do for the moveToTarget since it is all software at pre-step action time.
|
||||
}
|
||||
|
||||
// If a hover motor has not been created, create one and start the hovering.
|
||||
private void ActivateMoveToTarget()
|
||||
{
|
||||
if (m_targetMotor == null)
|
||||
{
|
||||
// We're taking over after this.
|
||||
m_controllingPrim.ZeroMotion(true);
|
||||
|
||||
m_targetMotor = new BSVMotor("BSActorMoveToTargget.Activate",
|
||||
m_controllingPrim.MoveToTargetTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
m_targetMotor.PhysicsScene = m_physicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
m_targetMotor.SetTarget(m_controllingPrim.MoveToTargetTarget);
|
||||
m_targetMotor.SetCurrent(m_controllingPrim.RawPosition);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeactivateMoveToTarget()
|
||||
{
|
||||
if (m_targetMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
m_targetMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
private void Mover(float timeStep)
|
||||
{
|
||||
// Don't do hovering while the object is selected.
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
OMV.Vector3 origPosition = m_controllingPrim.RawPosition; // DEBUG DEBUG (for printout below)
|
||||
|
||||
// 'movePosition' is where we'd like the prim to be at this moment.
|
||||
OMV.Vector3 movePosition = m_controllingPrim.RawPosition + m_targetMotor.Step(timeStep);
|
||||
|
||||
// If we are very close to our target, turn off the movement motor.
|
||||
if (m_targetMotor.ErrorIsZero())
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover,zeroMovement,movePos={1},pos={2},mass={3}",
|
||||
m_controllingPrim.LocalID, movePosition, m_controllingPrim.RawPosition, m_controllingPrim.Mass);
|
||||
m_controllingPrim.ForcePosition = m_targetMotor.TargetValue;
|
||||
// Setting the position does not cause the physics engine to generate a property update. Force it.
|
||||
m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_controllingPrim.ForcePosition = movePosition;
|
||||
// Setting the position does not cause the physics engine to generate a property update. Force it.
|
||||
m_physicsScene.PE.PushUpdate(m_controllingPrim.PhysBody);
|
||||
}
|
||||
m_physicsScene.DetailLog("{0},BSActorMoveToTarget.Mover,move,fromPos={1},movePos={2}", m_controllingPrim.LocalID, origPosition, movePosition);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* 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 copyrightD
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorSetForce : BSActor
|
||||
{
|
||||
BSFMotor m_forceMotor;
|
||||
|
||||
public BSActorSetForce(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_forceMotor = null;
|
||||
m_physicsScene.DetailLog("{0},BSActorSetForce,constructor", m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorSetForce,refresh", m_controllingPrim.LocalID);
|
||||
|
||||
// If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
|
||||
if (m_controllingPrim.RawForce == OMV.Vector3.Zero)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorSetForce,refresh,notSetForce,removing={1}", m_controllingPrim.LocalID, ActorName);
|
||||
Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the object is physically active, add the hoverer prestep action
|
||||
if (isActive)
|
||||
{
|
||||
ActivateSetForce();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeactivateSetForce();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
||||
// If a hover motor has not been created, create one and start the hovering.
|
||||
private void ActivateSetForce()
|
||||
{
|
||||
if (m_forceMotor == null)
|
||||
{
|
||||
// A fake motor that might be used someday
|
||||
m_forceMotor = new BSFMotor("setForce", 1f, 1f, 1f, 1f);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeactivateSetForce()
|
||||
{
|
||||
if (m_forceMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
m_forceMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
private void Mover(float timeStep)
|
||||
{
|
||||
// Don't do force while the object is selected.
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
m_physicsScene.DetailLog("{0},BSActorSetForce,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawForce);
|
||||
if (m_controllingPrim.PhysBody.HasPhysicalBody)
|
||||
{
|
||||
m_physicsScene.PE.ApplyCentralForce(m_controllingPrim.PhysBody, m_controllingPrim.RawForce);
|
||||
m_controllingPrim.ActivateIfPhysical(false);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* 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 copyrightD
|
||||
* 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 System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
using OpenSim.Region.Physics.Manager;
|
||||
|
||||
using OMV = OpenMetaverse;
|
||||
|
||||
namespace OpenSim.Region.Physics.BulletSPlugin
|
||||
{
|
||||
public class BSActorSetTorque : BSActor
|
||||
{
|
||||
BSFMotor m_torqueMotor;
|
||||
|
||||
public BSActorSetTorque(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
: base(physicsScene, pObj, actorName)
|
||||
{
|
||||
m_torqueMotor = null;
|
||||
m_physicsScene.DetailLog("{0},BSActorSetTorque,constructor", m_controllingPrim.LocalID);
|
||||
}
|
||||
|
||||
// BSActor.isActive
|
||||
public override bool isActive
|
||||
{
|
||||
get { return Enabled && m_controllingPrim.IsPhysicallyActive; }
|
||||
}
|
||||
|
||||
// Release any connections and resources used by the actor.
|
||||
// BSActor.Dispose()
|
||||
public override void Dispose()
|
||||
{
|
||||
Enabled = false;
|
||||
}
|
||||
|
||||
// Called when physical parameters (properties set in Bullet) need to be re-applied.
|
||||
// Called at taint-time.
|
||||
// BSActor.Refresh()
|
||||
public override void Refresh()
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,torque={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
|
||||
|
||||
// If not active any more, get rid of me (shouldn't ever happen, but just to be safe)
|
||||
if (m_controllingPrim.RawTorque == OMV.Vector3.Zero)
|
||||
{
|
||||
m_physicsScene.DetailLog("{0},BSActorSetTorque,refresh,notSetTorque,disabling={1}", m_controllingPrim.LocalID, ActorName);
|
||||
Enabled = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// If the object is physically active, add the hoverer prestep action
|
||||
if (isActive)
|
||||
{
|
||||
ActivateSetTorque();
|
||||
}
|
||||
else
|
||||
{
|
||||
DeactivateSetTorque();
|
||||
}
|
||||
}
|
||||
|
||||
// The object's physical representation is being rebuilt so pick up any physical dependencies (constraints, ...).
|
||||
// Register a prestep action to restore physical requirements before the next simulation step.
|
||||
// Called at taint-time.
|
||||
// BSActor.RemoveBodyDependencies()
|
||||
public override void RemoveBodyDependencies()
|
||||
{
|
||||
// Nothing to do for the hoverer since it is all software at pre-step action time.
|
||||
}
|
||||
|
||||
// If a hover motor has not been created, create one and start the hovering.
|
||||
private void ActivateSetTorque()
|
||||
{
|
||||
if (m_torqueMotor == null)
|
||||
{
|
||||
// A fake motor that might be used someday
|
||||
m_torqueMotor = new BSFMotor("setTorque", 1f, 1f, 1f, 1f);
|
||||
|
||||
m_physicsScene.BeforeStep += Mover;
|
||||
}
|
||||
}
|
||||
|
||||
private void DeactivateSetTorque()
|
||||
{
|
||||
if (m_torqueMotor != null)
|
||||
{
|
||||
m_physicsScene.BeforeStep -= Mover;
|
||||
m_torqueMotor = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Called just before the simulation step. Update the vertical position for hoverness.
|
||||
private void Mover(float timeStep)
|
||||
{
|
||||
// Don't do force while the object is selected.
|
||||
if (!isActive)
|
||||
return;
|
||||
|
||||
m_physicsScene.DetailLog("{0},BSActorSetTorque,preStep,force={1}", m_controllingPrim.LocalID, m_controllingPrim.RawTorque);
|
||||
if (m_controllingPrim.PhysBody.HasPhysicalBody)
|
||||
{
|
||||
m_controllingPrim.AddAngularForce(m_controllingPrim.RawTorque, false, true);
|
||||
m_controllingPrim.ActivateIfPhysical(false);
|
||||
}
|
||||
|
||||
// TODO:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -32,45 +32,72 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
{
|
||||
public class BSActorCollection
|
||||
{
|
||||
private BSScene PhysicsScene { get; set; }
|
||||
private BSScene m_physicsScene { get; set; }
|
||||
private Dictionary<string, BSActor> m_actors;
|
||||
|
||||
public BSActorCollection(BSScene physicsScene)
|
||||
{
|
||||
PhysicsScene = physicsScene;
|
||||
m_physicsScene = physicsScene;
|
||||
m_actors = new Dictionary<string, BSActor>();
|
||||
}
|
||||
public void Add(string name, BSActor actor)
|
||||
{
|
||||
lock (m_actors)
|
||||
{
|
||||
if (!m_actors.ContainsKey(name))
|
||||
{
|
||||
m_actors[name] = actor;
|
||||
}
|
||||
}
|
||||
}
|
||||
public bool RemoveAndRelease(string name)
|
||||
{
|
||||
bool ret = false;
|
||||
lock (m_actors)
|
||||
{
|
||||
if (m_actors.ContainsKey(name))
|
||||
{
|
||||
BSActor beingRemoved = m_actors[name];
|
||||
beingRemoved.Dispose();
|
||||
m_actors.Remove(name);
|
||||
beingRemoved.Dispose();
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public void Clear()
|
||||
{
|
||||
lock (m_actors)
|
||||
{
|
||||
Release();
|
||||
m_actors.Clear();
|
||||
}
|
||||
}
|
||||
public void Dispose()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
public bool HasActor(string name)
|
||||
{
|
||||
return m_actors.ContainsKey(name);
|
||||
}
|
||||
public bool TryGetActor(string actorName, out BSActor theActor)
|
||||
{
|
||||
return m_actors.TryGetValue(actorName, out theActor);
|
||||
}
|
||||
public void ForEachActor(Action<BSActor> act)
|
||||
{
|
||||
lock (m_actors)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSActor> kvp in m_actors)
|
||||
act(kvp.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public void Enable(bool enabl)
|
||||
{
|
||||
ForEachActor(a => a.SetEnabled(enabl));
|
||||
}
|
||||
public void Release()
|
||||
{
|
||||
ForEachActor(a => a.Dispose());
|
||||
|
@ -98,7 +125,7 @@ public abstract class BSActor
|
|||
{
|
||||
protected BSScene m_physicsScene { get; private set; }
|
||||
protected BSPhysObject m_controllingPrim { get; private set; }
|
||||
protected bool Enabled { get; set; }
|
||||
public virtual bool Enabled { get; set; }
|
||||
public string ActorName { get; private set; }
|
||||
|
||||
public BSActor(BSScene physicsScene, BSPhysObject pObj, string actorName)
|
||||
|
@ -114,8 +141,10 @@ public abstract class BSActor
|
|||
{
|
||||
get { return Enabled; }
|
||||
}
|
||||
// Turn the actor on an off.
|
||||
public virtual void Enable(bool setEnabled)
|
||||
|
||||
// Turn the actor on an off. Only used by ActorCollection to set all enabled/disabled.
|
||||
// Anyone else should assign true/false to 'Enabled'.
|
||||
public void SetEnabled(bool setEnabled)
|
||||
{
|
||||
Enabled = setEnabled;
|
||||
}
|
||||
|
|
|
@ -46,9 +46,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
private OMV.Vector3 _position;
|
||||
private float _mass;
|
||||
private float _avatarVolume;
|
||||
private OMV.Vector3 _force;
|
||||
private OMV.Vector3 _velocity;
|
||||
private OMV.Vector3 _torque;
|
||||
private float _collisionScore;
|
||||
private OMV.Vector3 _acceleration;
|
||||
private OMV.Quaternion _orientation;
|
||||
|
@ -61,17 +58,13 @@ public sealed class BSCharacter : BSPhysObject
|
|||
private OMV.Vector3 _rotationalVelocity;
|
||||
private bool _kinematic;
|
||||
private float _buoyancy;
|
||||
private bool _isStationaryStanding; // true is standing on a stationary object
|
||||
|
||||
private BSVMotor _velocityMotor;
|
||||
private BSActorAvatarMove m_moveActor;
|
||||
private const string AvatarMoveActorName = "BSCharacter.AvatarMove";
|
||||
|
||||
private OMV.Vector3 _PIDTarget;
|
||||
private bool _usePID;
|
||||
private float _PIDTau;
|
||||
private bool _useHoverPID;
|
||||
private float _PIDHoverHeight;
|
||||
private PIDHoverType _PIDHoverType;
|
||||
private float _PIDHoverTao;
|
||||
|
||||
public BSCharacter(uint localID, String avName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size, bool isFlying)
|
||||
: base(parent_scene, localID, avName, "BSCharacter")
|
||||
|
@ -81,11 +74,10 @@ public sealed class BSCharacter : BSPhysObject
|
|||
|
||||
_flying = isFlying;
|
||||
_orientation = OMV.Quaternion.Identity;
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_buoyancy = ComputeBuoyancyFromFlying(isFlying);
|
||||
Friction = BSParam.AvatarStandingFriction;
|
||||
Density = BSParam.AvatarDensity / BSParam.DensityScaleFactor;
|
||||
_isStationaryStanding = false;
|
||||
|
||||
// Old versions of ScenePresence passed only the height. If width and/or depth are zero,
|
||||
// replace with the default values.
|
||||
|
@ -99,7 +91,12 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// set _avatarVolume and _mass based on capsule size, _density and Scale
|
||||
ComputeAvatarVolumeAndMass();
|
||||
|
||||
SetupMovementMotor();
|
||||
// The avatar's movement is controlled by this motor that speeds up and slows down
|
||||
// the avatar seeking to reach the motor's target speed.
|
||||
// This motor runs as a prestep action for the avatar so it will keep the avatar
|
||||
// standing as well as moving. Destruction of the avatar will destroy the pre-step action.
|
||||
m_moveActor = new BSActorAvatarMove(PhysicsScene, this, AvatarMoveActorName);
|
||||
PhysicalActors.Add(AvatarMoveActorName, m_moveActor);
|
||||
|
||||
DetailLog("{0},BSCharacter.create,call,size={1},scale={2},density={3},volume={4},mass={5}",
|
||||
LocalID, _size, Scale, Density, _avatarVolume, RawMass);
|
||||
|
@ -139,10 +136,10 @@ public sealed class BSCharacter : BSPhysObject
|
|||
ForcePosition = _position;
|
||||
|
||||
// Set the velocity
|
||||
_velocityMotor.Reset();
|
||||
_velocityMotor.SetTarget(_velocity);
|
||||
_velocityMotor.SetCurrent(_velocity);
|
||||
ForceVelocity = _velocity;
|
||||
if (m_moveActor != null)
|
||||
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, false);
|
||||
|
||||
ForceVelocity = RawVelocity;
|
||||
|
||||
// This will enable or disable the flying buoyancy of the avatar.
|
||||
// Needs to be reset especially when an avatar is recreated after crossing a region boundry.
|
||||
|
@ -163,6 +160,9 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// Make so capsule does not fall over
|
||||
PhysicsScene.PE.SetAngularFactorV(PhysBody, OMV.Vector3.Zero);
|
||||
|
||||
// The avatar mover sets some parameters.
|
||||
PhysicalActors.Refresh();
|
||||
|
||||
PhysicsScene.PE.AddToCollisionFlags(PhysBody, CollisionFlags.CF_CHARACTER_OBJECT);
|
||||
|
||||
PhysicsScene.PE.AddObjectToWorld(PhysicsScene.World, PhysBody);
|
||||
|
@ -176,162 +176,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
PhysBody.ApplyCollisionMask(PhysicsScene);
|
||||
}
|
||||
|
||||
// The avatar's movement is controlled by this motor that speeds up and slows down
|
||||
// the avatar seeking to reach the motor's target speed.
|
||||
// This motor runs as a prestep action for the avatar so it will keep the avatar
|
||||
// standing as well as moving. Destruction of the avatar will destroy the pre-step action.
|
||||
private void SetupMovementMotor()
|
||||
{
|
||||
// Infinite decay and timescale values so motor only changes current to target values.
|
||||
_velocityMotor = new BSVMotor("BSCharacter.Velocity",
|
||||
0.2f, // time scale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
// _velocityMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
||||
RegisterPreStepAction("BSCharactor.Movement", LocalID, delegate(float timeStep)
|
||||
{
|
||||
// TODO: Decide if the step parameters should be changed depending on the avatar's
|
||||
// state (flying, colliding, ...). There is code in ODE to do this.
|
||||
|
||||
// COMMENTARY: when the user is making the avatar walk, except for falling, the velocity
|
||||
// specified for the avatar is the one that should be used. For falling, if the avatar
|
||||
// is not flying and is not colliding then it is presumed to be falling and the Z
|
||||
// component is not fooled with (thus allowing gravity to do its thing).
|
||||
// When the avatar is standing, though, the user has specified a velocity of zero and
|
||||
// the avatar should be standing. But if the avatar is pushed by something in the world
|
||||
// (raising elevator platform, moving vehicle, ...) the avatar should be allowed to
|
||||
// move. Thus, the velocity cannot be forced to zero. The problem is that small velocity
|
||||
// errors can creap in and the avatar will slowly float off in some direction.
|
||||
// So, the problem is that, when an avatar is standing, we cannot tell creaping error
|
||||
// from real pushing.
|
||||
// The code below uses whether the collider is static or moving to decide whether to zero motion.
|
||||
|
||||
_velocityMotor.Step(timeStep);
|
||||
_isStationaryStanding = false;
|
||||
|
||||
// If we're not supposed to be moving, make sure things are zero.
|
||||
if (_velocityMotor.ErrorIsZero() && _velocityMotor.TargetValue == OMV.Vector3.Zero)
|
||||
{
|
||||
// The avatar shouldn't be moving
|
||||
_velocityMotor.Zero();
|
||||
|
||||
if (IsColliding)
|
||||
{
|
||||
// If we are colliding with a stationary object, presume we're standing and don't move around
|
||||
if (!ColliderIsMoving)
|
||||
{
|
||||
DetailLog("{0},BSCharacter.MoveMotor,collidingWithStationary,zeroingMotion", LocalID);
|
||||
_isStationaryStanding = true;
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
|
||||
// Standing has more friction on the ground
|
||||
if (Friction != BSParam.AvatarStandingFriction)
|
||||
{
|
||||
Friction = BSParam.AvatarStandingFriction;
|
||||
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Flying)
|
||||
{
|
||||
// Flying and not collising and velocity nearly zero.
|
||||
ZeroMotion(true /* inTaintTime */);
|
||||
}
|
||||
}
|
||||
|
||||
DetailLog("{0},BSCharacter.MoveMotor,taint,stopping,target={1},colliding={2}", LocalID, _velocityMotor.TargetValue, IsColliding);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Supposed to be moving.
|
||||
OMV.Vector3 stepVelocity = _velocityMotor.CurrentValue;
|
||||
|
||||
if (Friction != BSParam.AvatarFriction)
|
||||
{
|
||||
// Probably starting up walking. Set friction to moving friction.
|
||||
Friction = BSParam.AvatarFriction;
|
||||
PhysicsScene.PE.SetFriction(PhysBody, Friction);
|
||||
}
|
||||
|
||||
// If falling, we keep the world's downward vector no matter what the other axis specify.
|
||||
// The check for _velocity.Z < 0 makes jumping work (temporary upward force).
|
||||
if (!Flying && !IsColliding)
|
||||
{
|
||||
if (_velocity.Z < 0)
|
||||
stepVelocity.Z = _velocity.Z;
|
||||
// DetailLog("{0},BSCharacter.MoveMotor,taint,overrideStepZWithWorldZ,stepVel={1}", LocalID, stepVelocity);
|
||||
}
|
||||
|
||||
// 'stepVelocity' is now the speed we'd like the avatar to move in. Turn that into an instantanous force.
|
||||
OMV.Vector3 moveForce = (stepVelocity - _velocity) * Mass;
|
||||
|
||||
// Should we check for move force being small and forcing velocity to zero?
|
||||
|
||||
// Add special movement force to allow avatars to walk up stepped surfaces.
|
||||
moveForce += WalkUpStairs();
|
||||
|
||||
DetailLog("{0},BSCharacter.MoveMotor,move,stepVel={1},vel={2},mass={3},moveForce={4}", LocalID, stepVelocity, _velocity, Mass, moveForce);
|
||||
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, moveForce);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Decide if the character is colliding with a low object and compute a force to pop the
|
||||
// avatar up so it can walk up and over the low objects.
|
||||
private OMV.Vector3 WalkUpStairs()
|
||||
{
|
||||
OMV.Vector3 ret = OMV.Vector3.Zero;
|
||||
|
||||
// This test is done if moving forward, not flying and is colliding with something.
|
||||
// DetailLog("{0},BSCharacter.WalkUpStairs,IsColliding={1},flying={2},targSpeed={3},collisions={4}",
|
||||
// LocalID, IsColliding, Flying, TargetSpeed, CollisionsLastTick.Count);
|
||||
if (IsColliding && !Flying && TargetVelocitySpeed > 0.1f /* && ForwardSpeed < 0.1f */)
|
||||
{
|
||||
// The range near the character's feet where we will consider stairs
|
||||
float nearFeetHeightMin = RawPosition.Z - (Size.Z / 2f) + 0.05f;
|
||||
float nearFeetHeightMax = nearFeetHeightMin + BSParam.AvatarStepHeight;
|
||||
|
||||
// Look for a collision point that is near the character's feet and is oriented the same as the charactor is
|
||||
foreach (KeyValuePair<uint, ContactPoint> kvp in CollisionsLastTick.m_objCollisionList)
|
||||
{
|
||||
// Don't care about collisions with the terrain
|
||||
if (kvp.Key > PhysicsScene.TerrainManager.HighestTerrainID)
|
||||
{
|
||||
OMV.Vector3 touchPosition = kvp.Value.Position;
|
||||
// DetailLog("{0},BSCharacter.WalkUpStairs,min={1},max={2},touch={3}",
|
||||
// LocalID, nearFeetHeightMin, nearFeetHeightMax, touchPosition);
|
||||
if (touchPosition.Z >= nearFeetHeightMin && touchPosition.Z <= nearFeetHeightMax)
|
||||
{
|
||||
// This contact is within the 'near the feet' range.
|
||||
// The normal should be our contact point to the object so it is pointing away
|
||||
// thus the difference between our facing orientation and the normal should be small.
|
||||
OMV.Vector3 directionFacing = OMV.Vector3.UnitX * RawOrientation;
|
||||
OMV.Vector3 touchNormal = OMV.Vector3.Normalize(kvp.Value.SurfaceNormal);
|
||||
float diff = Math.Abs(OMV.Vector3.Distance(directionFacing, touchNormal));
|
||||
if (diff < BSParam.AvatarStepApproachFactor)
|
||||
{
|
||||
// Found the stairs contact point. Push up a little to raise the character.
|
||||
float upForce = (touchPosition.Z - nearFeetHeightMin) * Mass * BSParam.AvatarStepForceFactor;
|
||||
ret = new OMV.Vector3(0f, 0f, upForce);
|
||||
|
||||
// Also move the avatar up for the new height
|
||||
OMV.Vector3 displacement = new OMV.Vector3(0f, 0f, BSParam.AvatarStepHeight / 2f);
|
||||
ForcePosition = RawPosition + displacement;
|
||||
}
|
||||
DetailLog("{0},BSCharacter.WalkUpStairs,touchPos={1},nearFeetMin={2},faceDir={3},norm={4},diff={5},ret={6}",
|
||||
LocalID, touchPosition, nearFeetHeightMin, directionFacing, touchNormal, diff, ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override void RequestPhysicsterseUpdate()
|
||||
{
|
||||
|
@ -403,7 +247,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// Called at taint time!
|
||||
public override void ZeroMotion(bool inTaintTime)
|
||||
{
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_acceleration = OMV.Vector3.Zero;
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
|
||||
|
@ -542,15 +386,15 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
|
||||
public override OMV.Vector3 Force {
|
||||
get { return _force; }
|
||||
get { return RawForce; }
|
||||
set {
|
||||
_force = value;
|
||||
RawForce = value;
|
||||
// m_log.DebugFormat("{0}: Force = {1}", LogHeader, _force);
|
||||
PhysicsScene.TaintedObject("BSCharacter.SetForce", delegate()
|
||||
{
|
||||
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, _force);
|
||||
DetailLog("{0},BSCharacter.setForce,taint,force={1}", LocalID, RawForce);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.SetObjectForce(PhysBody, _force);
|
||||
PhysicsScene.PE.SetObjectForce(PhysBody, RawForce);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -573,7 +417,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
{
|
||||
get
|
||||
{
|
||||
return m_targetVelocity;
|
||||
return base.m_targetVelocity;
|
||||
}
|
||||
set
|
||||
{
|
||||
|
@ -583,51 +427,39 @@ public sealed class BSCharacter : BSPhysObject
|
|||
if (_setAlwaysRun)
|
||||
targetVel *= new OMV.Vector3(BSParam.AvatarAlwaysRunFactor, BSParam.AvatarAlwaysRunFactor, 0f);
|
||||
|
||||
PhysicsScene.TaintedObject("BSCharacter.setTargetVelocity", delegate()
|
||||
{
|
||||
_velocityMotor.Reset();
|
||||
_velocityMotor.SetTarget(targetVel);
|
||||
_velocityMotor.SetCurrent(_velocity);
|
||||
_velocityMotor.Enabled = true;
|
||||
});
|
||||
if (m_moveActor != null)
|
||||
m_moveActor.SetVelocityAndTarget(RawVelocity, targetVel, false /* inTaintTime */);
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 RawVelocity
|
||||
{
|
||||
get { return _velocity; }
|
||||
set { _velocity = value; }
|
||||
}
|
||||
// Directly setting velocity means this is what the user really wants now.
|
||||
public override OMV.Vector3 Velocity {
|
||||
get { return _velocity; }
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
_velocity = value;
|
||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, _velocity);
|
||||
RawVelocity = value;
|
||||
// m_log.DebugFormat("{0}: set velocity = {1}", LogHeader, RawVelocity);
|
||||
PhysicsScene.TaintedObject("BSCharacter.setVelocity", delegate()
|
||||
{
|
||||
_velocityMotor.Reset();
|
||||
_velocityMotor.SetCurrent(_velocity);
|
||||
_velocityMotor.SetTarget(_velocity);
|
||||
_velocityMotor.Enabled = false;
|
||||
if (m_moveActor != null)
|
||||
m_moveActor.SetVelocityAndTarget(RawVelocity, RawVelocity, true /* inTaintTime */);
|
||||
|
||||
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
ForceVelocity = _velocity;
|
||||
DetailLog("{0},BSCharacter.setVelocity,taint,vel={1}", LocalID, RawVelocity);
|
||||
ForceVelocity = RawVelocity;
|
||||
});
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 ForceVelocity {
|
||||
get { return _velocity; }
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
PhysicsScene.AssertInTaintTime("BSCharacter.ForceVelocity");
|
||||
|
||||
_velocity = value;
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
|
||||
RawVelocity = value;
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
PhysicsScene.PE.Activate(PhysBody, true);
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 Torque {
|
||||
get { return _torque; }
|
||||
set { _torque = value;
|
||||
get { return RawTorque; }
|
||||
set { RawTorque = value;
|
||||
}
|
||||
}
|
||||
public override float CollisionScore {
|
||||
|
@ -783,27 +615,6 @@ public sealed class BSCharacter : BSPhysObject
|
|||
set { _PIDTau = value; }
|
||||
}
|
||||
|
||||
// Used for llSetHoverHeight and maybe vehicle height
|
||||
// Hover Height will override MoveTo target's Z
|
||||
public override bool PIDHoverActive {
|
||||
set { _useHoverPID = value; }
|
||||
}
|
||||
public override float PIDHoverHeight {
|
||||
set { _PIDHoverHeight = value; }
|
||||
}
|
||||
public override PIDHoverType PIDHoverType {
|
||||
set { _PIDHoverType = value; }
|
||||
}
|
||||
public override float PIDHoverTau {
|
||||
set { _PIDHoverTao = value; }
|
||||
}
|
||||
|
||||
// For RotLookAt
|
||||
public override OMV.Quaternion APIDTarget { set { return; } }
|
||||
public override bool APIDActive { set { return; } }
|
||||
public override float APIDStrength { set { return; } }
|
||||
public override float APIDDamping { set { return; } }
|
||||
|
||||
public override void AddForce(OMV.Vector3 force, bool pushforce)
|
||||
{
|
||||
// Since this force is being applied in only one step, make this a force per second.
|
||||
|
@ -833,7 +644,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
}
|
||||
}
|
||||
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime) {
|
||||
}
|
||||
public override void SetMomentum(OMV.Vector3 momentum) {
|
||||
}
|
||||
|
@ -887,7 +698,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
public override void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
// Don't change position if standing on a stationary object.
|
||||
if (!_isStationaryStanding)
|
||||
if (!IsStationary)
|
||||
_position = entprop.Position;
|
||||
|
||||
_orientation = entprop.Rotation;
|
||||
|
@ -896,8 +707,8 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// and will send agent updates to the clients if velocity changes by more than
|
||||
// 0.001m/s. Bullet introduces a lot of jitter in the velocity which causes many
|
||||
// extra updates.
|
||||
if (!entprop.Velocity.ApproxEquals(_velocity, 0.1f))
|
||||
_velocity = entprop.Velocity;
|
||||
if (!entprop.Velocity.ApproxEquals(RawVelocity, 0.1f))
|
||||
RawVelocity = entprop.Velocity;
|
||||
|
||||
_acceleration = entprop.Acceleration;
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
|
@ -920,7 +731,7 @@ public sealed class BSCharacter : BSPhysObject
|
|||
// base.RequestPhysicsterseUpdate();
|
||||
|
||||
DetailLog("{0},BSCharacter.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||
LocalID, _position, _orientation, RawVelocity, _acceleration, _rotationalVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1358,6 +1358,35 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// If vertical attaction timescale is reasonable
|
||||
if (enableAngularVerticalAttraction && m_verticalAttractionTimescale < m_verticalAttractionCutoff)
|
||||
{
|
||||
//Another formula to try got from :
|
||||
//http://answers.unity3d.com/questions/10425/how-to-stabilize-angular-motion-alignment-of-hover.html
|
||||
|
||||
Vector3 VehicleUpAxis = Vector3.UnitZ * VehicleOrientation;
|
||||
|
||||
// Flipping what was originally a timescale into a speed variable and then multiplying it by 2
|
||||
// since only computing half the distance between the angles.
|
||||
float VerticalAttractionSpeed = (1 / m_verticalAttractionTimescale) * 2.0f;
|
||||
|
||||
// Make a prediction of where the up axis will be when this is applied rather then where it is now as
|
||||
// this makes for a smoother adjustment and less fighting between the various forces.
|
||||
Vector3 predictedUp = VehicleUpAxis * Quaternion.CreateFromAxisAngle(VehicleRotationalVelocity, 0f);
|
||||
|
||||
// This is only half the distance to the target so it will take 2 seconds to complete the turn.
|
||||
Vector3 torqueVector = Vector3.Cross(predictedUp, Vector3.UnitZ);
|
||||
|
||||
// Scale vector by our timescale since it is an acceleration it is r/s^2 or radians a timescale squared
|
||||
Vector3 vertContributionV = torqueVector * VerticalAttractionSpeed * VerticalAttractionSpeed;
|
||||
|
||||
VehicleRotationalVelocity += vertContributionV;
|
||||
|
||||
VDetailLog("{0}, MoveAngular,verticalAttraction,UpAxis={1},PredictedUp={2},torqueVector={3},contrib={4}",
|
||||
ControllingPrim.LocalID,
|
||||
VehicleUpAxis,
|
||||
predictedUp,
|
||||
torqueVector,
|
||||
vertContributionV);
|
||||
//=====================================================================
|
||||
/*
|
||||
// Possible solution derived from a discussion at:
|
||||
// http://stackoverflow.com/questions/14939657/computing-vector-from-quaternion-works-computing-quaternion-from-vector-does-no
|
||||
|
||||
|
@ -1392,6 +1421,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
differenceAngle,
|
||||
correctionRotation,
|
||||
vertContributionV);
|
||||
*/
|
||||
|
||||
// ===================================================================
|
||||
/*
|
||||
|
|
|
@ -86,6 +86,7 @@ public static class BSParam
|
|||
public static bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
|
||||
public static bool ShouldUseHullsForPhysicalObjects { get; private set; } // 'true' if should create hulls for physical objects
|
||||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||
public static bool ShouldUseBulletHACD { get; set; }
|
||||
|
||||
public static float TerrainImplementation { get; private set; }
|
||||
public static int TerrainMeshMagnification { get; private set; }
|
||||
|
@ -149,6 +150,15 @@ public static class BSParam
|
|||
public static float CSHullVolumeConservationThresholdPercent { get; private set; }
|
||||
public static int CSHullMaxVertices { get; private set; }
|
||||
public static float CSHullMaxSkinWidth { get; private set; }
|
||||
public static float BHullMaxVerticesPerHull { get; private set; } // 100
|
||||
public static float BHullMinClusters { get; private set; } // 2
|
||||
public static float BHullCompacityWeight { get; private set; } // 0.1
|
||||
public static float BHullVolumeWeight { get; private set; } // 0.0
|
||||
public static float BHullConcavity { get; private set; } // 100
|
||||
public static bool BHullAddExtraDistPoints { get; private set; } // false
|
||||
public static bool BHullAddNeighboursDistPoints { get; private set; } // false
|
||||
public static bool BHullAddFacesPoints { get; private set; } // false
|
||||
public static bool BHullShouldAdjustCollisionMargin { get; private set; } // false
|
||||
|
||||
// Linkset implementation parameters
|
||||
public static float LinksetImplementation { get; private set; }
|
||||
|
@ -325,6 +335,10 @@ public static class BSParam
|
|||
true,
|
||||
(s) => { return ShouldRemoveZeroWidthTriangles; },
|
||||
(s,v) => { ShouldRemoveZeroWidthTriangles = v; } ),
|
||||
new ParameterDefn<bool>("ShouldUseBulletHACD", "If true, use the Bullet version of HACD",
|
||||
false,
|
||||
(s) => { return ShouldUseBulletHACD; },
|
||||
(s,v) => { ShouldUseBulletHACD = v; } ),
|
||||
|
||||
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
||||
5,
|
||||
|
@ -663,10 +677,47 @@ public static class BSParam
|
|||
(s) => { return CSHullMaxVertices; },
|
||||
(s,v) => { CSHullMaxVertices = v; } ),
|
||||
new ParameterDefn<float>("CSHullMaxSkinWidth", "CS impl: skin width to apply to output hulls.",
|
||||
0,
|
||||
0f,
|
||||
(s) => { return CSHullMaxSkinWidth; },
|
||||
(s,v) => { CSHullMaxSkinWidth = v; } ),
|
||||
|
||||
new ParameterDefn<float>("BHullMaxVerticesPerHull", "Bullet impl: max number of vertices per created hull",
|
||||
100f,
|
||||
(s) => { return BHullMaxVerticesPerHull; },
|
||||
(s,v) => { BHullMaxVerticesPerHull = v; } ),
|
||||
new ParameterDefn<float>("BHullMinClusters", "Bullet impl: minimum number of hulls to create per mesh",
|
||||
2f,
|
||||
(s) => { return BHullMinClusters; },
|
||||
(s,v) => { BHullMinClusters = v; } ),
|
||||
new ParameterDefn<float>("BHullCompacityWeight", "Bullet impl: weight factor for how compact to make hulls",
|
||||
2f,
|
||||
(s) => { return BHullCompacityWeight; },
|
||||
(s,v) => { BHullCompacityWeight = v; } ),
|
||||
new ParameterDefn<float>("BHullVolumeWeight", "Bullet impl: weight factor for volume in created hull",
|
||||
0.1f,
|
||||
(s) => { return BHullVolumeWeight; },
|
||||
(s,v) => { BHullVolumeWeight = v; } ),
|
||||
new ParameterDefn<float>("BHullConcavity", "Bullet impl: weight factor for how convex a created hull can be",
|
||||
100f,
|
||||
(s) => { return BHullConcavity; },
|
||||
(s,v) => { BHullConcavity = v; } ),
|
||||
new ParameterDefn<bool>("BHullAddExtraDistPoints", "Bullet impl: whether to add extra vertices for long distance vectors",
|
||||
false,
|
||||
(s) => { return BHullAddExtraDistPoints; },
|
||||
(s,v) => { BHullAddExtraDistPoints = v; } ),
|
||||
new ParameterDefn<bool>("BHullAddNeighboursDistPoints", "Bullet impl: whether to add extra vertices between neighbor hulls",
|
||||
false,
|
||||
(s) => { return BHullAddNeighboursDistPoints; },
|
||||
(s,v) => { BHullAddNeighboursDistPoints = v; } ),
|
||||
new ParameterDefn<bool>("BHullAddFacesPoints", "Bullet impl: whether to add extra vertices to break up hull faces",
|
||||
false,
|
||||
(s) => { return BHullAddFacesPoints; },
|
||||
(s,v) => { BHullAddFacesPoints = v; } ),
|
||||
new ParameterDefn<bool>("BHullShouldAdjustCollisionMargin", "Bullet impl: whether to shrink resulting hulls to account for collision margin",
|
||||
false,
|
||||
(s) => { return BHullShouldAdjustCollisionMargin; },
|
||||
(s,v) => { BHullShouldAdjustCollisionMargin = v; } ),
|
||||
|
||||
new ParameterDefn<float>("LinksetImplementation", "Type of linkset implementation (0=Constraint, 1=Compound, 2=Manual)",
|
||||
(float)BSLinkset.LinksetImplementation.Compound,
|
||||
(s) => { return LinksetImplementation; },
|
||||
|
|
|
@ -43,7 +43,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
* VariableName: used by the simulator and performs taint operations, etc
|
||||
* RawVariableName: direct reference to the BulletSim storage for the variable value
|
||||
* ForceVariableName: direct reference (store and fetch) to the value in the physics engine.
|
||||
* The last two (and certainly the last one) should be referenced only in taint-time.
|
||||
* The last one should only be referenced in taint-time.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -84,6 +84,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// Initialize variables kept in base.
|
||||
GravModifier = 1.0f;
|
||||
Gravity = new OMV.Vector3(0f, 0f, BSParam.Gravity);
|
||||
HoverActive = false;
|
||||
|
||||
// We don't have any physical representation yet.
|
||||
PhysBody = new BulletBody(localID);
|
||||
|
@ -110,11 +111,10 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
// Tell the object to clean up.
|
||||
public virtual void Destroy()
|
||||
{
|
||||
UnRegisterAllPreStepActions();
|
||||
UnRegisterAllPostStepActions();
|
||||
PhysicalActors.Enable(false);
|
||||
PhysicsScene.TaintedObject("BSPhysObject.Destroy", delegate()
|
||||
{
|
||||
PhysicalActors.Release();
|
||||
PhysicalActors.Dispose();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -203,15 +203,48 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
public abstract OMV.Quaternion RawOrientation { get; set; }
|
||||
public abstract OMV.Quaternion ForceOrientation { get; set; }
|
||||
|
||||
public abstract OMV.Vector3 RawVelocity { get; set; }
|
||||
public OMV.Vector3 RawVelocity { get; set; }
|
||||
public abstract OMV.Vector3 ForceVelocity { get; set; }
|
||||
|
||||
public OMV.Vector3 RawForce { get; set; }
|
||||
public OMV.Vector3 RawTorque { get; set; }
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce)
|
||||
{
|
||||
AddAngularForce(force, pushforce, false);
|
||||
}
|
||||
public abstract void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime);
|
||||
|
||||
public abstract OMV.Vector3 ForceRotationalVelocity { get; set; }
|
||||
|
||||
public abstract float ForceBuoyancy { get; set; }
|
||||
|
||||
public virtual bool ForceBodyShapeRebuild(bool inTaintTime) { return false; }
|
||||
|
||||
public override bool PIDActive { set { MoveToTargetActive = value; } }
|
||||
public override OMV.Vector3 PIDTarget { set { MoveToTargetTarget = value; } }
|
||||
public override float PIDTau { set { MoveToTargetTau = value; } }
|
||||
|
||||
public bool MoveToTargetActive { get; set; }
|
||||
public OMV.Vector3 MoveToTargetTarget { get; set; }
|
||||
public float MoveToTargetTau { get; set; }
|
||||
|
||||
// Used for llSetHoverHeight and maybe vehicle height. Hover Height will override MoveTo target's Z
|
||||
public override bool PIDHoverActive { set { HoverActive = value; } }
|
||||
public override float PIDHoverHeight { set { HoverHeight = value; } }
|
||||
public override PIDHoverType PIDHoverType { set { HoverType = value; } }
|
||||
public override float PIDHoverTau { set { HoverTau = value; } }
|
||||
|
||||
public bool HoverActive { get; set; }
|
||||
public float HoverHeight { get; set; }
|
||||
public PIDHoverType HoverType { get; set; }
|
||||
public float HoverTau { get; set; }
|
||||
|
||||
// For RotLookAt
|
||||
public override OMV.Quaternion APIDTarget { set { return; } }
|
||||
public override bool APIDActive { set { return; } }
|
||||
public override float APIDStrength { set { return; } }
|
||||
public override float APIDDamping { set { return; } }
|
||||
|
||||
// The current velocity forward
|
||||
public virtual float ForwardSpeed
|
||||
{
|
||||
|
@ -237,7 +270,51 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
public OMV.Vector3 LockedAxis { get; set; } // zero means locked. one means free.
|
||||
public readonly OMV.Vector3 LockedAxisFree = new OMV.Vector3(1f, 1f, 1f); // All axis are free
|
||||
public readonly String LockedAxisActorName = "BSPrim.LockedAxis";
|
||||
|
||||
// Enable physical actions. Bullet will keep sleeping non-moving physical objects so
|
||||
// they need waking up when parameters are changed.
|
||||
// Called in taint-time!!
|
||||
public void ActivateIfPhysical(bool forceIt)
|
||||
{
|
||||
if (IsPhysical && PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.Activate(PhysBody, forceIt);
|
||||
}
|
||||
|
||||
// 'actors' act on the physical object to change or constrain its motion. These can range from
|
||||
// hovering to complex vehicle motion.
|
||||
// May be called at non-taint time as this just adds the actor to the action list and the real
|
||||
// work is done during the simulation step.
|
||||
// Note that, if the actor is already in the list and we are disabling same, the actor is just left
|
||||
// in the list disabled.
|
||||
public delegate BSActor CreateActor();
|
||||
public void EnableActor(bool enableActor, string actorName, CreateActor creator)
|
||||
{
|
||||
lock (PhysicalActors)
|
||||
{
|
||||
BSActor theActor;
|
||||
if (PhysicalActors.TryGetActor(actorName, out theActor))
|
||||
{
|
||||
// The actor already exists so just turn it on or off
|
||||
DetailLog("{0},BSPhysObject.EnableActor,enablingExistingActor,name={1},enable={2}", LocalID, actorName, enableActor);
|
||||
theActor.Enabled = enableActor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The actor does not exist. If it should, create it.
|
||||
if (enableActor)
|
||||
{
|
||||
DetailLog("{0},BSPhysObject.EnableActor,creatingActor,name={1}", LocalID, actorName);
|
||||
theActor = creator();
|
||||
PhysicalActors.Add(actorName, theActor);
|
||||
theActor.Enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DetailLog("{0},BSPhysObject.EnableActor,notCreatingActorSinceNotEnabled,name={1}", LocalID, actorName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#region Collisions
|
||||
|
||||
|
@ -255,7 +332,9 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
protected CollisionFlags CurrentCollisionFlags { get; set; }
|
||||
// On a collision, check the collider and remember if the last collider was moving
|
||||
// Used to modify the standing of avatars (avatars on stationary things stand still)
|
||||
protected bool ColliderIsMoving;
|
||||
public bool ColliderIsMoving;
|
||||
// Used by BSCharacter to manage standing (and not slipping)
|
||||
public bool IsStationary;
|
||||
|
||||
// Count of collisions for this object
|
||||
protected long CollisionAccumulation { get; set; }
|
||||
|
@ -293,7 +372,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
protected CollisionEventUpdate CollisionCollection;
|
||||
// Remember collisions from last tick for fancy collision based actions
|
||||
// (like a BSCharacter walking up stairs).
|
||||
protected CollisionEventUpdate CollisionsLastTick;
|
||||
public CollisionEventUpdate CollisionsLastTick;
|
||||
|
||||
// The simulation step is telling this object about a collision.
|
||||
// Return 'true' if a collision was processed and should be sent up.
|
||||
|
@ -424,104 +503,6 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
|
||||
public BSActorCollection PhysicalActors;
|
||||
|
||||
// There are some actions that must be performed for a physical object before each simulation step.
|
||||
// These actions are optional so, rather than scanning all the physical objects and asking them
|
||||
// if they have anything to do, a physical object registers for an event call before the step is performed.
|
||||
// This bookkeeping makes it easy to add, remove and clean up after all these registrations.
|
||||
private Dictionary<string, BSScene.PreStepAction> RegisteredPrestepActions = new Dictionary<string, BSScene.PreStepAction>();
|
||||
private Dictionary<string, BSScene.PostStepAction> RegisteredPoststepActions = new Dictionary<string, BSScene.PostStepAction>();
|
||||
protected void RegisterPreStepAction(string op, uint id, BSScene.PreStepAction actn)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPreStepAction(op, id);
|
||||
RegisteredPrestepActions[identifier] = actn;
|
||||
PhysicsScene.BeforeStep += actn;
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.RegisterPreStepAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
|
||||
// Unregister a pre step action. Safe to call if the action has not been registered.
|
||||
// Returns 'true' if an action was actually removed
|
||||
protected bool UnRegisterPreStepAction(string op, uint id)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
bool removed = false;
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
if (RegisteredPrestepActions.ContainsKey(identifier))
|
||||
{
|
||||
PhysicsScene.BeforeStep -= RegisteredPrestepActions[identifier];
|
||||
RegisteredPrestepActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPreStepAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void UnRegisterAllPreStepActions()
|
||||
{
|
||||
lock (RegisteredPrestepActions)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSScene.PreStepAction> kvp in RegisteredPrestepActions)
|
||||
{
|
||||
PhysicsScene.BeforeStep -= kvp.Value;
|
||||
}
|
||||
RegisteredPrestepActions.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPreStepActions,", LocalID);
|
||||
}
|
||||
|
||||
protected void RegisterPostStepAction(string op, uint id, BSScene.PostStepAction actn)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPostStepAction(op, id);
|
||||
RegisteredPoststepActions[identifier] = actn;
|
||||
PhysicsScene.AfterStep += actn;
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.RegisterPostStepAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
|
||||
// Unregister a pre step action. Safe to call if the action has not been registered.
|
||||
// Returns 'true' if an action was actually removed.
|
||||
protected bool UnRegisterPostStepAction(string op, uint id)
|
||||
{
|
||||
string identifier = op + "-" + id.ToString();
|
||||
bool removed = false;
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
if (RegisteredPoststepActions.ContainsKey(identifier))
|
||||
{
|
||||
PhysicsScene.AfterStep -= RegisteredPoststepActions[identifier];
|
||||
RegisteredPoststepActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPostStepAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
return removed;
|
||||
}
|
||||
|
||||
protected void UnRegisterAllPostStepActions()
|
||||
{
|
||||
lock (RegisteredPoststepActions)
|
||||
{
|
||||
foreach (KeyValuePair<string, BSScene.PostStepAction> kvp in RegisteredPoststepActions)
|
||||
{
|
||||
PhysicsScene.AfterStep -= kvp.Value;
|
||||
}
|
||||
RegisteredPoststepActions.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPostStepActions,", LocalID);
|
||||
}
|
||||
|
||||
// When an update to the physical properties happens, this event is fired to let
|
||||
// different actors to modify the update before it is passed around
|
||||
public delegate void PreUpdatePropertyAction(ref EntityProperties entprop);
|
||||
|
@ -533,46 +514,6 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
actions(ref entprop);
|
||||
}
|
||||
|
||||
private Dictionary<string, PreUpdatePropertyAction> RegisteredPreUpdatePropertyActions = new Dictionary<string, PreUpdatePropertyAction>();
|
||||
public void RegisterPreUpdatePropertyAction(string identifier, PreUpdatePropertyAction actn)
|
||||
{
|
||||
lock (RegisteredPreUpdatePropertyActions)
|
||||
{
|
||||
// Clean out any existing action
|
||||
UnRegisterPreUpdatePropertyAction(identifier);
|
||||
RegisteredPreUpdatePropertyActions[identifier] = actn;
|
||||
OnPreUpdateProperty += actn;
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.RegisterPreUpdatePropertyAction,id={1}", LocalID, identifier);
|
||||
}
|
||||
public bool UnRegisterPreUpdatePropertyAction(string identifier)
|
||||
{
|
||||
bool removed = false;
|
||||
lock (RegisteredPreUpdatePropertyActions)
|
||||
{
|
||||
if (RegisteredPreUpdatePropertyActions.ContainsKey(identifier))
|
||||
{
|
||||
OnPreUpdateProperty -= RegisteredPreUpdatePropertyActions[identifier];
|
||||
RegisteredPreUpdatePropertyActions.Remove(identifier);
|
||||
removed = true;
|
||||
}
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterPreUpdatePropertyAction,id={1},removed={2}", LocalID, identifier, removed);
|
||||
return removed;
|
||||
}
|
||||
public void UnRegisterAllPreUpdatePropertyActions()
|
||||
{
|
||||
lock (RegisteredPreUpdatePropertyActions)
|
||||
{
|
||||
foreach (KeyValuePair<string, PreUpdatePropertyAction> kvp in RegisteredPreUpdatePropertyActions)
|
||||
{
|
||||
OnPreUpdateProperty -= kvp.Value;
|
||||
}
|
||||
RegisteredPreUpdatePropertyActions.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPhysObject.UnRegisterAllPreUpdatePropertyAction,", LocalID);
|
||||
}
|
||||
|
||||
#endregion // Per Simulation Step actions
|
||||
|
||||
// High performance detailed logging routine used by the physical objects.
|
||||
|
|
|
@ -55,9 +55,6 @@ public class BSPrim : BSPhysObject
|
|||
private OMV.Vector3 _position;
|
||||
|
||||
private float _mass; // the mass of this object
|
||||
private OMV.Vector3 _force;
|
||||
private OMV.Vector3 _velocity;
|
||||
private OMV.Vector3 _torque;
|
||||
private OMV.Vector3 _acceleration;
|
||||
private OMV.Quaternion _orientation;
|
||||
private int _physicsActorType;
|
||||
|
@ -73,16 +70,13 @@ public class BSPrim : BSPhysObject
|
|||
private int CrossingFailures { get; set; }
|
||||
|
||||
public BSDynamics VehicleActor;
|
||||
public string VehicleActorName = "BasicVehicle";
|
||||
public const string VehicleActorName = "BasicVehicle";
|
||||
|
||||
private BSVMotor _targetMotor;
|
||||
private OMV.Vector3 _PIDTarget;
|
||||
private float _PIDTau;
|
||||
|
||||
private BSFMotor _hoverMotor;
|
||||
private float _PIDHoverHeight;
|
||||
private PIDHoverType _PIDHoverType;
|
||||
private float _PIDHoverTau;
|
||||
public const string HoverActorName = "HoverActor";
|
||||
public const String LockedAxisActorName = "BSPrim.LockedAxis";
|
||||
public const string MoveToTargetActorName = "MoveToTargetActor";
|
||||
public const string SetForceActorName = "SetForceActor";
|
||||
public const string SetTorqueActorName = "SetTorqueActor";
|
||||
|
||||
public BSPrim(uint localID, String primName, BSScene parent_scene, OMV.Vector3 pos, OMV.Vector3 size,
|
||||
OMV.Quaternion rotation, PrimitiveBaseShape pbs, bool pisPhysical)
|
||||
|
@ -95,12 +89,13 @@ public class BSPrim : BSPhysObject
|
|||
Scale = size; // prims are the size the user wants them to be (different for BSCharactes).
|
||||
_orientation = rotation;
|
||||
_buoyancy = 0f;
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
BaseShape = pbs;
|
||||
_isPhysical = pisPhysical;
|
||||
_isVolumeDetect = false;
|
||||
|
||||
// We keep a handle to the vehicle actor so we can set vehicle parameters later.
|
||||
VehicleActor = new BSDynamics(PhysicsScene, this, VehicleActorName);
|
||||
PhysicalActors.Add(VehicleActorName, VehicleActor);
|
||||
|
||||
|
@ -233,7 +228,7 @@ public class BSPrim : BSPhysObject
|
|||
// Called at taint time!
|
||||
public override void ZeroMotion(bool inTaintTime)
|
||||
{
|
||||
_velocity = OMV.Vector3.Zero;
|
||||
RawVelocity = OMV.Vector3.Zero;
|
||||
_acceleration = OMV.Vector3.Zero;
|
||||
_rotationalVelocity = OMV.Vector3.Zero;
|
||||
|
||||
|
@ -270,19 +265,17 @@ public class BSPrim : BSPhysObject
|
|||
if (axis.Z != 1) locking.Z = 0f;
|
||||
LockedAxis = locking;
|
||||
|
||||
if (LockedAxis != LockedAxisFree)
|
||||
EnableActor(LockedAxis != LockedAxisFree, LockedAxisActorName, delegate()
|
||||
{
|
||||
return new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName);
|
||||
});
|
||||
|
||||
// Update parameters so the new actor's Refresh() action is called at the right time.
|
||||
PhysicsScene.TaintedObject("BSPrim.LockAngularMotion", delegate()
|
||||
{
|
||||
// If there is not already an axis locker, make one
|
||||
if (!PhysicalActors.HasActor(LockedAxisActorName))
|
||||
{
|
||||
DetailLog("{0},BSPrim.LockAngularMotion,taint,registeringLockAxisActor", LocalID);
|
||||
PhysicalActors.Add(LockedAxisActorName, new BSActorLockAxis(PhysicsScene, this, LockedAxisActorName));
|
||||
}
|
||||
UpdatePhysicalParameters();
|
||||
});
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -407,9 +400,9 @@ public class BSPrim : BSPhysObject
|
|||
ZeroMotion(inTaintTime);
|
||||
ret = true;
|
||||
}
|
||||
if (_velocity.LengthSquared() > BSParam.MaxLinearVelocity)
|
||||
if (RawVelocity.LengthSquared() > BSParam.MaxLinearVelocity)
|
||||
{
|
||||
_velocity = Util.ClampV(_velocity, BSParam.MaxLinearVelocity);
|
||||
RawVelocity = Util.ClampV(RawVelocity, BSParam.MaxLinearVelocity);
|
||||
ret = true;
|
||||
}
|
||||
if (_rotationalVelocity.LengthSquared() > BSParam.MaxAngularVelocitySquared)
|
||||
|
@ -506,48 +499,25 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
public override OMV.Vector3 Force {
|
||||
get { return _force; }
|
||||
get { return RawForce; }
|
||||
set {
|
||||
_force = value;
|
||||
if (_force != OMV.Vector3.Zero)
|
||||
RawForce = value;
|
||||
EnableActor(RawForce != OMV.Vector3.Zero, SetForceActorName, delegate()
|
||||
{
|
||||
// If the force is non-zero, it must be reapplied each tick because
|
||||
// Bullet clears the forces applied last frame.
|
||||
RegisterPreStepAction("BSPrim.setForce", LocalID,
|
||||
delegate(float timeStep)
|
||||
{
|
||||
if (!IsPhysicallyActive || _force == OMV.Vector3.Zero)
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.setForce", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
DetailLog("{0},BSPrim.setForce,preStep,force={1}", LocalID, _force);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
PhysicsScene.PE.ApplyCentralForce(PhysBody, _force);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.setForce", LocalID);
|
||||
}
|
||||
return new BSActorSetForce(PhysicsScene, this, SetForceActorName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public override int VehicleType {
|
||||
get {
|
||||
return (int)VehicleActor.Type; // if we are a vehicle, return that type
|
||||
return (int)VehicleActor.Type;
|
||||
}
|
||||
set {
|
||||
Vehicle type = (Vehicle)value;
|
||||
|
||||
PhysicsScene.TaintedObject("setVehicleType", delegate()
|
||||
{
|
||||
// Done at taint time so we're sure the physics engine is not using the variables
|
||||
// Vehicle code changes the parameters for this vehicle type.
|
||||
VehicleActor.ProcessTypeChange(type);
|
||||
ActivateIfPhysical(false);
|
||||
|
@ -670,63 +640,40 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 RawVelocity
|
||||
{
|
||||
get { return _velocity; }
|
||||
set { _velocity = value; }
|
||||
}
|
||||
public override OMV.Vector3 Velocity {
|
||||
get { return _velocity; }
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
_velocity = value;
|
||||
RawVelocity = value;
|
||||
PhysicsScene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
{
|
||||
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
ForceVelocity = _velocity;
|
||||
// DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, RawVelocity);
|
||||
ForceVelocity = RawVelocity;
|
||||
});
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 ForceVelocity {
|
||||
get { return _velocity; }
|
||||
get { return RawVelocity; }
|
||||
set {
|
||||
PhysicsScene.AssertInTaintTime("BSPrim.ForceVelocity");
|
||||
|
||||
_velocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
|
||||
RawVelocity = Util.ClampV(value, BSParam.MaxLinearVelocity);
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
{
|
||||
DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, _velocity);
|
||||
DetailLog("{0},BSPrim.ForceVelocity,taint,vel={1}", LocalID, RawVelocity);
|
||||
PhysicsScene.PE.SetLinearVelocity(PhysBody, RawVelocity);
|
||||
ActivateIfPhysical(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 Torque {
|
||||
get { return _torque; }
|
||||
get { return RawTorque; }
|
||||
set {
|
||||
_torque = value;
|
||||
if (_torque != OMV.Vector3.Zero)
|
||||
RawTorque = value;
|
||||
EnableActor(RawTorque != OMV.Vector3.Zero, SetTorqueActorName, delegate()
|
||||
{
|
||||
// If the torque is non-zero, it must be reapplied each tick because
|
||||
// Bullet clears the forces applied last frame.
|
||||
RegisterPreStepAction("BSPrim.setTorque", LocalID,
|
||||
delegate(float timeStep)
|
||||
{
|
||||
if (!IsPhysicallyActive || _torque == OMV.Vector3.Zero)
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
if (PhysBody.HasPhysicalBody)
|
||||
AddAngularForce(_torque, false, true);
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.setTorque", LocalID);
|
||||
}
|
||||
// DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, _torque);
|
||||
return new BSActorSetTorque(PhysicsScene, this, SetTorqueActorName);
|
||||
});
|
||||
DetailLog("{0},BSPrim.SetTorque,call,torque={1}", LocalID, RawTorque);
|
||||
}
|
||||
}
|
||||
public override OMV.Vector3 Acceleration {
|
||||
|
@ -839,7 +786,6 @@ public class BSPrim : BSPhysObject
|
|||
MakeDynamic(IsStatic);
|
||||
|
||||
// Update vehicle specific parameters (after MakeDynamic() so can change physical parameters)
|
||||
VehicleActor.Refresh();
|
||||
PhysicalActors.Refresh();
|
||||
|
||||
// Arrange for collision events if the simulator wants them
|
||||
|
@ -909,7 +855,7 @@ public class BSPrim : BSPhysObject
|
|||
|
||||
// For good measure, make sure the transform is set through to the motion state
|
||||
ForcePosition = _position;
|
||||
ForceVelocity = _velocity;
|
||||
ForceVelocity = RawVelocity;
|
||||
ForceRotationalVelocity = _rotationalVelocity;
|
||||
|
||||
// A dynamic object has mass
|
||||
|
@ -966,15 +912,6 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
|
||||
// Enable physical actions. Bullet will keep sleeping non-moving physical objects so
|
||||
// they need waking up when parameters are changed.
|
||||
// Called in taint-time!!
|
||||
private void ActivateIfPhysical(bool forceIt)
|
||||
{
|
||||
if (IsPhysical && PhysBody.HasPhysicalBody)
|
||||
PhysicsScene.PE.Activate(PhysBody, forceIt);
|
||||
}
|
||||
|
||||
// Turn on or off the flag controlling whether collision events are returned to the simulator.
|
||||
private void EnableCollisions(bool wantsCollisionEvents)
|
||||
{
|
||||
|
@ -1096,166 +1033,27 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
|
||||
// Used for MoveTo
|
||||
public override OMV.Vector3 PIDTarget {
|
||||
set
|
||||
{
|
||||
// TODO: add a sanity check -- don't move more than a region or something like that.
|
||||
_PIDTarget = value;
|
||||
}
|
||||
}
|
||||
public override float PIDTau {
|
||||
set { _PIDTau = value; }
|
||||
}
|
||||
public override bool PIDActive {
|
||||
set {
|
||||
if (value)
|
||||
base.MoveToTargetActive = value;
|
||||
EnableActor(MoveToTargetActive, MoveToTargetActorName, delegate()
|
||||
{
|
||||
// We're taking over after this.
|
||||
ZeroMotion(true);
|
||||
|
||||
_targetMotor = new BSVMotor("BSPrim.PIDTarget",
|
||||
_PIDTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.InfiniteVector, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
_targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
_targetMotor.SetTarget(_PIDTarget);
|
||||
_targetMotor.SetCurrent(RawPosition);
|
||||
/*
|
||||
_targetMotor = new BSPIDVMotor("BSPrim.PIDTarget");
|
||||
_targetMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
||||
_targetMotor.SetTarget(_PIDTarget);
|
||||
_targetMotor.SetCurrent(RawPosition);
|
||||
_targetMotor.TimeScale = _PIDTau;
|
||||
_targetMotor.Efficiency = 1f;
|
||||
*/
|
||||
|
||||
RegisterPreStepAction("BSPrim.PIDTarget", LocalID, delegate(float timeStep)
|
||||
{
|
||||
if (!IsPhysicallyActive)
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
|
||||
return;
|
||||
}
|
||||
|
||||
OMV.Vector3 origPosition = RawPosition; // DEBUG DEBUG (for printout below)
|
||||
|
||||
// 'movePosition' is where we'd like the prim to be at this moment.
|
||||
OMV.Vector3 movePosition = RawPosition + _targetMotor.Step(timeStep);
|
||||
|
||||
// If we are very close to our target, turn off the movement motor.
|
||||
if (_targetMotor.ErrorIsZero())
|
||||
{
|
||||
DetailLog("{0},BSPrim.PIDTarget,zeroMovement,movePos={1},pos={2},mass={3}",
|
||||
LocalID, movePosition, RawPosition, Mass);
|
||||
ForcePosition = _targetMotor.TargetValue;
|
||||
_targetMotor.Enabled = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
_position = movePosition;
|
||||
PositionSanityCheck(true /* intaintTime */);
|
||||
ForcePosition = _position;
|
||||
}
|
||||
DetailLog("{0},BSPrim.PIDTarget,move,fromPos={1},movePos={2}", LocalID, origPosition, movePosition);
|
||||
return new BSActorMoveToTarget(PhysicsScene, this, MoveToTargetActorName);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
// Stop any targetting
|
||||
UnRegisterPreStepAction("BSPrim.PIDTarget", LocalID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Used for llSetHoverHeight and maybe vehicle height
|
||||
// Hover Height will override MoveTo target's Z
|
||||
public override bool PIDHoverActive {
|
||||
set {
|
||||
if (value)
|
||||
base.HoverActive = value;
|
||||
EnableActor(HoverActive, HoverActorName, delegate()
|
||||
{
|
||||
// Turning the target on
|
||||
_hoverMotor = new BSFMotor("BSPrim.Hover",
|
||||
_PIDHoverTau, // timeScale
|
||||
BSMotor.Infinite, // decay time scale
|
||||
BSMotor.Infinite, // friction timescale
|
||||
1f // efficiency
|
||||
);
|
||||
_hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
|
||||
_hoverMotor.SetCurrent(RawPosition.Z);
|
||||
_hoverMotor.PhysicsScene = PhysicsScene; // DEBUG DEBUG so motor will output detail log messages.
|
||||
|
||||
RegisterPreStepAction("BSPrim.Hover", LocalID, delegate(float timeStep)
|
||||
{
|
||||
// Don't do hovering while the object is selected.
|
||||
if (!IsPhysicallyActive)
|
||||
return;
|
||||
|
||||
_hoverMotor.SetCurrent(RawPosition.Z);
|
||||
_hoverMotor.SetTarget(ComputeCurrentPIDHoverHeight());
|
||||
float targetHeight = _hoverMotor.Step(timeStep);
|
||||
|
||||
// 'targetHeight' is where we'd like the Z of the prim to be at this moment.
|
||||
// Compute the amount of force to push us there.
|
||||
float moveForce = (targetHeight - RawPosition.Z) * Mass;
|
||||
// Undo anything the object thinks it's doing at the moment
|
||||
moveForce = -RawVelocity.Z * Mass;
|
||||
|
||||
PhysicsScene.PE.ApplyCentralImpulse(PhysBody, new OMV.Vector3(0f, 0f, moveForce));
|
||||
DetailLog("{0},BSPrim.Hover,move,targHt={1},moveForce={2},mass={3}", LocalID, targetHeight, moveForce, Mass);
|
||||
return new BSActorHover(PhysicsScene, this, HoverActorName);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
UnRegisterPreStepAction("BSPrim.Hover", LocalID);
|
||||
}
|
||||
}
|
||||
}
|
||||
public override float PIDHoverHeight {
|
||||
set { _PIDHoverHeight = value; }
|
||||
}
|
||||
public override PIDHoverType PIDHoverType {
|
||||
set { _PIDHoverType = value; }
|
||||
}
|
||||
public override float PIDHoverTau {
|
||||
set { _PIDHoverTau = value; }
|
||||
}
|
||||
// Based on current position, determine what we should be hovering at now.
|
||||
// Must recompute often. What if we walked offa cliff>
|
||||
private float ComputeCurrentPIDHoverHeight()
|
||||
{
|
||||
float ret = _PIDHoverHeight;
|
||||
float groundHeight = PhysicsScene.TerrainManager.GetTerrainHeightAtXYZ(RawPosition);
|
||||
|
||||
switch (_PIDHoverType)
|
||||
{
|
||||
case PIDHoverType.Ground:
|
||||
ret = groundHeight + _PIDHoverHeight;
|
||||
break;
|
||||
case PIDHoverType.GroundAndWater:
|
||||
float waterHeight = PhysicsScene.TerrainManager.GetWaterLevelAtXYZ(RawPosition);
|
||||
if (groundHeight > waterHeight)
|
||||
{
|
||||
ret = groundHeight + _PIDHoverHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = waterHeight + _PIDHoverHeight;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// For RotLookAt
|
||||
public override OMV.Quaternion APIDTarget { set { return; } }
|
||||
public override bool APIDActive { set { return; } }
|
||||
public override float APIDStrength { set { return; } }
|
||||
public override float APIDDamping { set { return; } }
|
||||
|
||||
public override void AddForce(OMV.Vector3 force, bool pushforce) {
|
||||
// Per documentation, max force is limited.
|
||||
|
@ -1324,10 +1122,8 @@ public class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce) {
|
||||
AddAngularForce(force, pushforce, false);
|
||||
}
|
||||
public void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
|
||||
// BSPhysObject.AddAngularForce()
|
||||
public override void AddAngularForce(OMV.Vector3 force, bool pushforce, bool inTaintTime)
|
||||
{
|
||||
if (force.IsFinite())
|
||||
{
|
||||
|
@ -1661,7 +1457,7 @@ public class BSPrim : BSPhysObject
|
|||
{
|
||||
// Create the correct physical representation for this type of object.
|
||||
// Updates base.PhysBody and base.PhysShape with the new information.
|
||||
// Ignore 'forceRebuild'. This routine makes the right choices and changes of necessary.
|
||||
// Ignore 'forceRebuild'. 'GetBodyAndShape' makes the right choices and changes of necessary.
|
||||
PhysicsScene.Shapes.GetBodyAndShape(false /*forceRebuild */, PhysicsScene.World, this, null, delegate(BulletBody dBody)
|
||||
{
|
||||
// Called if the current prim body is about to be destroyed.
|
||||
|
@ -1675,9 +1471,9 @@ public class BSPrim : BSPhysObject
|
|||
return;
|
||||
}
|
||||
|
||||
// Called at taint-time
|
||||
protected virtual void RemoveBodyDependencies()
|
||||
{
|
||||
VehicleActor.RemoveBodyDependencies();
|
||||
PhysicalActors.RemoveBodyDependencies();
|
||||
}
|
||||
|
||||
|
@ -1685,6 +1481,7 @@ public class BSPrim : BSPhysObject
|
|||
// the world that things have changed.
|
||||
public override void UpdateProperties(EntityProperties entprop)
|
||||
{
|
||||
// Let anyone (like the actors) modify the updated properties before they are pushed into the object and the simulator.
|
||||
TriggerPreUpdatePropertyAction(ref entprop);
|
||||
|
||||
// DetailLog("{0},BSPrim.UpdateProperties,entry,entprop={1}", LocalID, entprop); // DEBUG DEBUG
|
||||
|
@ -1694,8 +1491,8 @@ public class BSPrim : BSPhysObject
|
|||
_orientation = entprop.Rotation;
|
||||
// DEBUG DEBUG DEBUG -- smooth velocity changes a bit. The simulator seems to be
|
||||
// very sensitive to velocity changes.
|
||||
if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(_velocity, BSParam.UpdateVelocityChangeThreshold))
|
||||
_velocity = entprop.Velocity;
|
||||
if (entprop.Velocity == OMV.Vector3.Zero || !entprop.Velocity.ApproxEquals(RawVelocity, BSParam.UpdateVelocityChangeThreshold))
|
||||
RawVelocity = entprop.Velocity;
|
||||
_acceleration = entprop.Acceleration;
|
||||
_rotationalVelocity = entprop.RotationalVelocity;
|
||||
|
||||
|
@ -1705,7 +1502,7 @@ public class BSPrim : BSPhysObject
|
|||
if (PositionSanityCheck(true /* inTaintTime */ ))
|
||||
{
|
||||
entprop.Position = _position;
|
||||
entprop.Velocity = _velocity;
|
||||
entprop.Velocity = RawVelocity;
|
||||
entprop.RotationalVelocity = _rotationalVelocity;
|
||||
entprop.Acceleration = _acceleration;
|
||||
}
|
||||
|
@ -1717,16 +1514,8 @@ public class BSPrim : BSPhysObject
|
|||
LastEntityProperties = CurrentEntityProperties;
|
||||
CurrentEntityProperties = entprop;
|
||||
|
||||
// Note that BSPrim can be overloaded by BSPrimLinkable which controls updates from root and children prims.
|
||||
base.RequestPhysicsterseUpdate();
|
||||
/*
|
||||
else
|
||||
{
|
||||
// For debugging, report the movement of children
|
||||
DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
||||
entprop.Acceleration, entprop.RotationalVelocity);
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -163,6 +163,15 @@ public class BSPrimLinkable : BSPrimDisplaced
|
|||
// TODO: this will have to change when linksets are articulated.
|
||||
base.UpdateProperties(entprop);
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
// For debugging, report the movement of children
|
||||
DetailLog("{0},BSPrim.UpdateProperties,child,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, entprop.Position, entprop.Rotation, entprop.Velocity,
|
||||
entprop.Acceleration, entprop.RotationalVelocity);
|
||||
}
|
||||
*/
|
||||
// The linkset might like to know about changing locations
|
||||
Linkset.UpdateProperties(UpdatedProperties.EntPropUpdates, this);
|
||||
}
|
||||
|
|
|
@ -316,6 +316,7 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
|||
break;
|
||||
case "bulletxna":
|
||||
ret = new BSAPIXNA(engineName, this);
|
||||
BSParam.ShouldUseBulletHACD = false;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -722,7 +722,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
// Remove usage of the previous shape.
|
||||
DereferenceShape(prim.PhysShape, shapeCallback);
|
||||
|
||||
newShape = CreatePhysicalHull(prim.PhysObjectName, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
newShape = CreatePhysicalHull(prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
// It might not have been created if we're waiting for an asset.
|
||||
newShape = VerifyMeshCreated(newShape, prim);
|
||||
|
||||
|
@ -733,7 +733,7 @@ public sealed class BSShapeCollection : IDisposable
|
|||
}
|
||||
|
||||
List<ConvexResult> m_hulls;
|
||||
private BulletShape CreatePhysicalHull(string objName, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
private BulletShape CreatePhysicalHull(BSPhysObject prim, System.UInt64 newHullKey, PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||
{
|
||||
|
||||
BulletShape newShape = new BulletShape();
|
||||
|
@ -746,13 +746,50 @@ public sealed class BSShapeCollection : IDisposable
|
|||
newShape = hullDesc.shape.Clone();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BSParam.ShouldUseBulletHACD)
|
||||
{
|
||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,entry", prim.LocalID);
|
||||
MeshDesc meshDesc;
|
||||
if (!Meshes.TryGetValue(newHullKey, out meshDesc))
|
||||
{
|
||||
// That's odd because the mesh should have been created before the hull
|
||||
// but, since it doesn't exist, create it.
|
||||
newShape = CreatePhysicalMesh(prim, newHullKey, prim.BaseShape, prim.Size, lod);
|
||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,noMeshBuiltNew,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
|
||||
if (newShape.HasPhysicalShape)
|
||||
{
|
||||
ReferenceShape(newShape);
|
||||
Meshes.TryGetValue(newHullKey, out meshDesc);
|
||||
}
|
||||
}
|
||||
if (meshDesc.shape.HasPhysicalShape)
|
||||
{
|
||||
HACDParams parms;
|
||||
parms.maxVerticesPerHull = BSParam.BHullMaxVerticesPerHull;
|
||||
parms.minClusters = BSParam.BHullMinClusters;
|
||||
parms.compacityWeight = BSParam.BHullCompacityWeight;
|
||||
parms.volumeWeight = BSParam.BHullVolumeWeight;
|
||||
parms.concavity = BSParam.BHullConcavity;
|
||||
parms.addExtraDistPoints = BSParam.NumericBool(BSParam.BHullAddExtraDistPoints);
|
||||
parms.addNeighboursDistPoints = BSParam.NumericBool(BSParam.BHullAddNeighboursDistPoints);
|
||||
parms.addFacesPoints = BSParam.NumericBool(BSParam.BHullAddFacesPoints);
|
||||
parms.shouldAdjustCollisionMargin = BSParam.NumericBool(BSParam.BHullShouldAdjustCollisionMargin);
|
||||
|
||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,beforeCall", prim.LocalID, newShape.HasPhysicalShape);
|
||||
newShape = PhysicsScene.PE.BuildHullShapeFromMesh(PhysicsScene.World, meshDesc.shape, parms);
|
||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,hullFromMesh,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
}
|
||||
DetailLog("{0},BSShapeCollection.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||
}
|
||||
if (!newShape.HasPhysicalShape)
|
||||
{
|
||||
// Build a new hull in the physical world.
|
||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||
IMesh meshData = PhysicsScene.mesher.CreateMesh(objName, pbs, size, lod, true, false, false, false);
|
||||
IMesh meshData = PhysicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
||||
if (meshData != null)
|
||||
{
|
||||
|
||||
int[] indices = meshData.getIndexListAsInt();
|
||||
List<OMV.Vector3> vertices = meshData.getVertexList();
|
||||
|
||||
|
@ -854,8 +891,8 @@ public sealed class BSShapeCollection : IDisposable
|
|||
newShape = PhysicsScene.PE.CreateHullShape(PhysicsScene.World, hullCount, convHulls);
|
||||
}
|
||||
}
|
||||
|
||||
newShape.shapeKey = newHullKey;
|
||||
}
|
||||
|
||||
return newShape;
|
||||
}
|
||||
|
|
|
@ -213,13 +213,13 @@ public sealed class BSTerrainManager : IDisposable
|
|||
});
|
||||
}
|
||||
|
||||
// Another region is calling this region passing a terrain.
|
||||
// Another region is calling this region and passing a terrain.
|
||||
// A region that is not the mega-region root will pass its terrain to the root region so the root region
|
||||
// physics engine will have all the terrains.
|
||||
private void AddMegaRegionChildTerrain(uint id, float[] heightMap, Vector3 minCoords, Vector3 maxCoords)
|
||||
{
|
||||
// Since we are called by another region's thread, the action must be rescheduled onto our processing thread.
|
||||
PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + m_worldOffset.ToString(), 0, delegate()
|
||||
PhysicsScene.PostTaintObject("TerrainManager.AddMegaRegionChild" + minCoords.ToString(), id, delegate()
|
||||
{
|
||||
UpdateTerrain(id, heightMap, minCoords, maxCoords);
|
||||
});
|
||||
|
@ -306,7 +306,7 @@ public sealed class BSTerrainManager : IDisposable
|
|||
newTerrainID = ++m_terrainCount;
|
||||
|
||||
DetailLog("{0},BSTerrainManager.UpdateTerrain:NewTerrain,taint,newID={1},minCoord={2},maxCoord={3}",
|
||||
BSScene.DetailLogZero, newTerrainID, minCoords, minCoords);
|
||||
BSScene.DetailLogZero, newTerrainID, minCoords, maxCoords);
|
||||
BSTerrainPhys newTerrainPhys = BuildPhysicalTerrain(terrainRegionBase, id, heightMap, minCoords, maxCoords);
|
||||
m_terrains.Add(terrainRegionBase, newTerrainPhys);
|
||||
|
||||
|
|
|
@ -6,7 +6,6 @@ Enable vehicle border crossings (at least as poorly as ODE)
|
|||
Terrain skirts
|
||||
Avatar created in previous region and not new region when crossing border
|
||||
Vehicle recreated in new sim at small Z value (offset from root value?) (DONE)
|
||||
Lock axis
|
||||
Deleting a linkset while standing on the root will leave the physical shape of the root behind.
|
||||
Not sure if it is because standing on it. Done with large prim linksets.
|
||||
Linkset child rotations.
|
||||
|
@ -344,3 +343,5 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
|||
Verify that angular motion specified around Z moves in the vehicle coordinates.
|
||||
DONE 20130120: BulletSim properly applies force in vehicle relative coordinates.
|
||||
Nebadon vehicles turning funny in arena (DONE)
|
||||
Lock axis (DONE 20130401)
|
||||
|
||||
|
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Interfaces;
|
||||
|
@ -34,10 +36,10 @@ using OpenSim.Region.CoreModules.World.Land;
|
|||
|
||||
namespace OpenSim.Region.RegionCombinerModule
|
||||
{
|
||||
public class RegionCombinerLargeLandChannel : ILandChannel
|
||||
public class RegionCombinerLargeLandChannel : ILandChannel
|
||||
{
|
||||
// private static readonly ILog m_log =
|
||||
// LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private RegionData RegData;
|
||||
private ILandChannel RootRegionLandChannel;
|
||||
private readonly List<RegionData> RegionConnections;
|
||||
|
@ -75,40 +77,51 @@ public class RegionCombinerLargeLandChannel : ILandChannel
|
|||
|
||||
public ILandObject GetLandObject(int x, int y)
|
||||
{
|
||||
//m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
|
||||
return GetLandObject((float)x, (float)y);
|
||||
|
||||
if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
|
||||
{
|
||||
return RootRegionLandChannel.GetLandObject(x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
int offsetX = (x / (int)Constants.RegionSize);
|
||||
int offsetY = (y / (int)Constants.RegionSize);
|
||||
offsetX *= (int)Constants.RegionSize;
|
||||
offsetY *= (int)Constants.RegionSize;
|
||||
|
||||
foreach (RegionData regionData in RegionConnections)
|
||||
{
|
||||
if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
|
||||
{
|
||||
return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
|
||||
}
|
||||
}
|
||||
ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
|
||||
obj.LandData.Name = "NO LAND";
|
||||
return obj;
|
||||
}
|
||||
// m_log.DebugFormat("[BIGLANDTESTINT]: <{0},{1}>", x, y);
|
||||
//
|
||||
// if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
|
||||
// {
|
||||
// return RootRegionLandChannel.GetLandObject(x, y);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// int offsetX = (x / (int)Constants.RegionSize);
|
||||
// int offsetY = (y / (int)Constants.RegionSize);
|
||||
// offsetX *= (int)Constants.RegionSize;
|
||||
// offsetY *= (int)Constants.RegionSize;
|
||||
//
|
||||
// foreach (RegionData regionData in RegionConnections)
|
||||
// {
|
||||
// if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
|
||||
// {
|
||||
// m_log.DebugFormat(
|
||||
// "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}",
|
||||
// regionData.RegionScene.Name, offsetX, offsetY);
|
||||
//
|
||||
// return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
|
||||
// }
|
||||
// }
|
||||
// //ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
|
||||
// //obj.LandData.Name = "NO LAND";
|
||||
// //return obj;
|
||||
// }
|
||||
//
|
||||
// m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y);
|
||||
//
|
||||
// return null;
|
||||
}
|
||||
|
||||
public ILandObject GetLandObject(int localID)
|
||||
{
|
||||
// XXX: Possibly should be looking in every land channel, not just the root.
|
||||
return RootRegionLandChannel.GetLandObject(localID);
|
||||
}
|
||||
|
||||
public ILandObject GetLandObject(float x, float y)
|
||||
{
|
||||
//m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y);
|
||||
// m_log.DebugFormat("[BIGLANDTESTFLOAT]: <{0},{1}>", x, y);
|
||||
|
||||
if (x > 0 && x <= (int)Constants.RegionSize && y > 0 && y <= (int)Constants.RegionSize)
|
||||
{
|
||||
|
@ -125,14 +138,22 @@ public class RegionCombinerLargeLandChannel : ILandChannel
|
|||
{
|
||||
if (regionData.Offset.X == offsetX && regionData.Offset.Y == offsetY)
|
||||
{
|
||||
// m_log.DebugFormat(
|
||||
// "[REGION COMBINER LARGE LAND CHANNEL]: Found region {0} at offset {1},{2}",
|
||||
// regionData.RegionScene.Name, offsetX, offsetY);
|
||||
|
||||
return regionData.RegionScene.LandChannel.GetLandObject(x - offsetX, y - offsetY);
|
||||
}
|
||||
}
|
||||
|
||||
ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
|
||||
obj.LandData.Name = "NO LAND";
|
||||
return obj;
|
||||
// ILandObject obj = new LandObject(UUID.Zero, false, RegData.RegionScene);
|
||||
// obj.LandData.Name = "NO LAND";
|
||||
// return obj;
|
||||
}
|
||||
|
||||
// m_log.DebugFormat("[REGION COMBINER LARGE LAND CHANNEL]: No region found at {0},{1}, returning null", x, y);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool IsForcefulBansAllowed()
|
||||
|
|
|
@ -528,8 +528,13 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
|||
{
|
||||
File.Delete(savedState);
|
||||
}
|
||||
catch(Exception)
|
||||
catch (Exception e)
|
||||
{
|
||||
m_log.Warn(
|
||||
string.Format(
|
||||
"[SCRIPT INSTANCE]: Could not delete script state {0} for script {1} (id {2}) in part {3} (id {4}) in object {5} in {6}. Exception ",
|
||||
ScriptTask.Name, ScriptTask.ItemID, Part.Name, Part.UUID, Part.ParentGroup.Name, Engine.World.Name),
|
||||
e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
{ "RequestMethod", "AddSession" },
|
||||
{ "UserID", userID.ToString() }
|
||||
};
|
||||
|
||||
if (sessionID != UUID.Zero)
|
||||
{
|
||||
requestArgs["SessionID"] = sessionID.ToString();
|
||||
|
@ -158,7 +159,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public bool LogoutAgent(UUID sessionID)
|
||||
{
|
||||
// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
|
||||
// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for agent with sessionID " + sessionID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
@ -177,7 +178,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public bool LogoutRegionAgents(UUID regionID)
|
||||
{
|
||||
// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
|
||||
// m_log.InfoFormat("[SIMIAN PRESENCE CONNECTOR]: Logout requested for all agents in region " + regionID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
@ -202,49 +203,46 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public PresenceInfo GetAgent(UUID sessionID)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent with sessionID " + sessionID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
OSDMap sessionResponse = GetSessionDataFromSessionID(sessionID);
|
||||
if (sessionResponse == null)
|
||||
{
|
||||
{ "RequestMethod", "GetSession" },
|
||||
{ "SessionID", sessionID.ToString() }
|
||||
};
|
||||
|
||||
OSDMap sessionResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (sessionResponse["Success"].AsBoolean())
|
||||
{
|
||||
UUID userID = sessionResponse["UserID"].AsUUID();
|
||||
m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
|
||||
|
||||
requestArgs = new NameValueCollection
|
||||
{
|
||||
{ "RequestMethod", "GetUser" },
|
||||
{ "UserID", userID.ToString() }
|
||||
};
|
||||
|
||||
OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (userResponse["Success"].AsBoolean())
|
||||
return ResponseToPresenceInfo(sessionResponse, userResponse);
|
||||
else
|
||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session " + sessionID + ": " + sessionResponse["Message"].AsString());
|
||||
}
|
||||
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session {0}: {1}",sessionID.ToString(),sessionResponse["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
UUID userID = sessionResponse["UserID"].AsUUID();
|
||||
OSDMap userResponse = GetUserData(userID);
|
||||
if (userResponse == null)
|
||||
{
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID.ToString(),userResponse["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
return ResponseToPresenceInfo(sessionResponse);
|
||||
}
|
||||
|
||||
public PresenceInfo[] GetAgents(string[] userIDs)
|
||||
{
|
||||
List<PresenceInfo> presences = new List<PresenceInfo>(userIDs.Length);
|
||||
List<PresenceInfo> presences = new List<PresenceInfo>();
|
||||
|
||||
for (int i = 0; i < userIDs.Length; i++)
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
UUID userID;
|
||||
if (UUID.TryParse(userIDs[i], out userID) && userID != UUID.Zero)
|
||||
presences.AddRange(GetSessions(userID));
|
||||
{ "RequestMethod", "GetSessions" },
|
||||
{ "UserIDList", String.Join(",",userIDs) }
|
||||
};
|
||||
|
||||
OSDMap sessionListResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (! sessionListResponse["Success"].AsBoolean())
|
||||
{
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve sessions: {0}",sessionListResponse["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
OSDArray sessionList = sessionListResponse["Sessions"] as OSDArray;
|
||||
for (int i = 0; i < sessionList.Count; i++)
|
||||
{
|
||||
OSDMap sessionInfo = sessionList[i] as OSDMap;
|
||||
presences.Add(ResponseToPresenceInfo(sessionInfo));
|
||||
}
|
||||
|
||||
return presences.ToArray();
|
||||
|
@ -262,7 +260,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public bool LoggedOut(string userID, UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID);
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Logging out user " + userID);
|
||||
|
||||
// Remove the session to mark this user offline
|
||||
if (!LogoutAgent(sessionID))
|
||||
|
@ -287,7 +285,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public bool SetHome(string userID, UUID regionID, Vector3 position, Vector3 lookAt)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Setting home location for user " + userID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
@ -312,23 +310,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
public GridUserInfo GetGridUserInfo(string user)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting session data for agent " + user);
|
||||
|
||||
UUID userID = new UUID(user);
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
{ "RequestMethod", "GetUser" },
|
||||
{ "UserID", userID.ToString() }
|
||||
};
|
||||
|
||||
OSDMap userResponse = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (userResponse["Success"].AsBoolean())
|
||||
OSDMap userResponse = GetUserData(userID);
|
||||
if (userResponse != null)
|
||||
return ResponseToGridUserInfo(userResponse);
|
||||
else
|
||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + userResponse["Message"].AsString());
|
||||
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}: {1}",userID,userResponse["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -338,7 +327,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
|
||||
private OSDMap GetUserData(UUID userID)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting user data for " + userID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
|
@ -349,41 +338,25 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (response["Success"].AsBoolean() && response["User"] is OSDMap)
|
||||
return response;
|
||||
else
|
||||
m_log.Warn("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for " + userID + ": " + response["Message"].AsString());
|
||||
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve user data for {0}; {1}",userID.ToString(),response["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<PresenceInfo> GetSessions(UUID userID)
|
||||
private OSDMap GetSessionDataFromSessionID(UUID sessionID)
|
||||
{
|
||||
List<PresenceInfo> presences = new List<PresenceInfo>(1);
|
||||
|
||||
OSDMap userResponse = GetUserData(userID);
|
||||
if (userResponse != null)
|
||||
{
|
||||
// m_log.DebugFormat("[SIMIAN PRESENCE CONNECTOR]: Requesting sessions for " + userID);
|
||||
|
||||
NameValueCollection requestArgs = new NameValueCollection
|
||||
{
|
||||
{ "RequestMethod", "GetSession" },
|
||||
{ "UserID", userID.ToString() }
|
||||
{ "SessionID", sessionID.ToString() }
|
||||
};
|
||||
|
||||
OSDMap response = WebUtil.PostToService(m_serverUrl, requestArgs);
|
||||
if (response["Success"].AsBoolean())
|
||||
{
|
||||
PresenceInfo presence = ResponseToPresenceInfo(response, userResponse);
|
||||
if (presence != null)
|
||||
presences.Add(presence);
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// m_log.Debug("[SIMIAN PRESENCE CONNECTOR]: No session returned for " + userID + ": " + response["Message"].AsString());
|
||||
// }
|
||||
}
|
||||
return response;
|
||||
|
||||
return presences;
|
||||
m_log.WarnFormat("[SIMIAN PRESENCE CONNECTOR]: Failed to retrieve session data for {0}; {1}",sessionID.ToString(),response["Message"].AsString());
|
||||
return null;
|
||||
}
|
||||
|
||||
private bool UpdateSession(UUID sessionID, UUID regionID, Vector3 lastPosition, Vector3 lastLookAt)
|
||||
|
@ -407,7 +380,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
|
|||
return success;
|
||||
}
|
||||
|
||||
private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse, OSDMap userResponse)
|
||||
private PresenceInfo ResponseToPresenceInfo(OSDMap sessionResponse)
|
||||
{
|
||||
if (sessionResponse == null)
|
||||
return null;
|
||||
|
|
BIN
bin/CSJ2K.dll
BIN
bin/CSJ2K.dll
Binary file not shown.
|
@ -1,130 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<doc>
|
||||
<assembly>
|
||||
<name>/home/root/libomv-0.9.1-source/bin/OpenMetaverse.StructuredData</name>
|
||||
<name>OpenMetaverse.StructuredData</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDType">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Unknown">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Boolean">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Integer">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Real">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.String">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.UUID">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Date">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.URI">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Binary">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Map">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Array">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDException">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSD">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.SerializeMembers(System.Object)">
|
||||
<summary>
|
||||
Uses reflection to create an SDMap from all of the SD
|
||||
serializable types in an object
|
||||
</summary>
|
||||
<param name="obj">Class or struct containing serializable types</param>
|
||||
<returns>An SDMap holding the serialized values from the
|
||||
container object</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.DeserializeMembers(System.Object@,OpenMetaverse.StructuredData.OSDMap)">
|
||||
<summary>
|
||||
Uses reflection to deserialize member variables in an object from
|
||||
an SDMap
|
||||
</summary>
|
||||
<param name="obj">Reference to an object to fill with deserialized
|
||||
values</param>
|
||||
<param name="serialized">Serialized values to put in the target
|
||||
object</param>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBoolean">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDInteger">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDReal">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDString">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUUID">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDDate">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUri">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBinary">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDMap">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDArray">
|
||||
<summary>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDParser">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDBinary(System.Byte[])">
|
||||
|
@ -153,8 +41,7 @@
|
|||
Serializes OSD to binary format
|
||||
</summary>
|
||||
<param name="osd">OSD to serialize</param>
|
||||
<param name="prependHeader">
|
||||
</param>
|
||||
<param name="prependHeader"></param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDBinaryStream(OpenMetaverse.StructuredData.OSD)">
|
||||
|
@ -169,209 +56,294 @@
|
|||
Serializes OSD to binary format
|
||||
</summary>
|
||||
<param name="data">OSD to serialize</param>
|
||||
<param name="prependHeader">
|
||||
</param>
|
||||
<param name="prependHeader"></param>
|
||||
<returns>Serialized data</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SkipWhiteSpace(System.IO.Stream)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream">
|
||||
</param>
|
||||
<param name="stream"></param>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.FindByte(System.IO.Stream,System.Byte)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream">
|
||||
</param>
|
||||
<param name="toFind">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="stream"></param>
|
||||
<param name="toFind"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.FindString(System.IO.Stream,System.String)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream">
|
||||
</param>
|
||||
<param name="toFind">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="stream"></param>
|
||||
<param name="toFind"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ConsumeBytes(System.IO.Stream,System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="stream">
|
||||
</param>
|
||||
<param name="consumeBytes">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="stream"></param>
|
||||
<param name="consumeBytes"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.NetworkToHostInt(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="binaryNetEnd">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="binaryNetEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.NetworkToHostDouble(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="binaryNetEnd">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="binaryNetEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.HostToNetworkIntBytes(System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="intHostEnd">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<param name="delimiter">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<param name="buffer">
|
||||
</param>
|
||||
<param name="offset">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="s">
|
||||
</param>
|
||||
<param name="c">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
</summary>
|
||||
<param name="s">
|
||||
</param>
|
||||
<param name="c">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="intHostEnd"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Byte[])">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.String)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDXml(System.Xml.XmlTextReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="xmlData"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlBytes(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="data">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="data"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlString(OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="data">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="data"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.SerializeLLSDXmlElement(System.Xml.XmlTextWriter,OpenMetaverse.StructuredData.OSD)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="writer">
|
||||
</param>
|
||||
<param name="data">
|
||||
</param>
|
||||
<param name="writer"></param>
|
||||
<param name="data"></param>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.TryValidateLLSDXml(System.Xml.XmlTextReader,System.String@)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="xmlData">
|
||||
</param>
|
||||
<param name="error">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
<param name="xmlData"></param>
|
||||
<param name="error"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ParseLLSDXmlElement(System.Xml.XmlTextReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.DeserializeLLSDNotationElement(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.PeekAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.ReadAndSkipWhitespace(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetLengthInBrackets(System.IO.StringReader)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.GetStringDelimitedBy(System.IO.StringReader,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<param name="delimiter"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.BufferCharactersEqual(System.IO.StringReader,System.Char[],System.Int32)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader"></param>
|
||||
<param name="buffer"></param>
|
||||
<param name="offset"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.UnescapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="s"></param>
|
||||
<param name="c"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSDParser.EscapeCharacter(System.String,System.Char)">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="s"></param>
|
||||
<param name="c"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDType">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Unknown">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Boolean">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Integer">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Real">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.String">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.UUID">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Date">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.URI">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Binary">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Map">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="F:OpenMetaverse.StructuredData.OSDType.Array">
|
||||
<summary></summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDException">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSD">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.SerializeMembers(System.Object)">
|
||||
<summary>
|
||||
Uses reflection to create an SDMap from all of the SD
|
||||
serializable types in an object
|
||||
</summary>
|
||||
<param name="obj">Class or struct containing serializable types</param>
|
||||
<returns>An SDMap holding the serialized values from the
|
||||
container object</returns>
|
||||
</member>
|
||||
<member name="M:OpenMetaverse.StructuredData.OSD.DeserializeMembers(System.Object@,OpenMetaverse.StructuredData.OSDMap)">
|
||||
<summary>
|
||||
Uses reflection to deserialize member variables in an object from
|
||||
an SDMap
|
||||
</summary>
|
||||
<param name="obj">Reference to an object to fill with deserialized
|
||||
values</param>
|
||||
<param name="serialized">Serialized values to put in the target
|
||||
object</param>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBoolean">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDInteger">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDReal">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDString">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUUID">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDDate">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDUri">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDBinary">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDMap">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:OpenMetaverse.StructuredData.OSDArray">
|
||||
<summary>
|
||||
|
||||
</summary>
|
||||
<param name="reader">
|
||||
</param>
|
||||
<returns>
|
||||
</returns>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
|
Binary file not shown.
37991
bin/OpenMetaverse.XML
37991
bin/OpenMetaverse.XML
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -1,5 +1,7 @@
|
|||
<configuration>
|
||||
<dllmap os="osx" dll="openjpeg-dotnet.dll" target="lib64/libopenjpeg-dotnet.dylib" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="openjpeg-dotnet-x86_64.dll" target="lib64/libopenjpeg-dotnet-x86_64" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="openjpeg-dotnet.dll" target="lib32/libopenjpeg-dotnet" />
|
||||
<dllmap os="osx" dll="openjpeg-dotnet.dll" target="libopenjpeg-dotnet-2-1.5.0-dotnet-1.dylib" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="openjpeg-dotnet.dll" target="libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="openjpeg-dotnet-x86_64.dll" target="libopenjpeg-dotnet-2-1.5.0-dotnet-1-x86_64" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="openjpeg-dotnet.dll" target="libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="openjpeg-dotnet-x86_64.dll" target="libopenjpeg-dotnet-2-1.5.0-dotnet-1-i686" />
|
||||
</configuration>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
@ -43,9 +43,14 @@
|
|||
; Sets the method that OpenSim will use to fire asynchronous
|
||||
; events. Valid values are UnsafeQueueUserWorkItem,
|
||||
; QueueUserWorkItem, BeginInvoke, SmartThreadPool, and Thread.
|
||||
;
|
||||
; SmartThreadPool is reported to work well on Mono/Linux, but
|
||||
; UnsafeQueueUserWorkItem has been benchmarked with better
|
||||
; performance on .NET/Windows
|
||||
;
|
||||
; UnsafeQueueUserWorkItem refers to the fact that the code creating the event could elevate its security
|
||||
; privileges. However, as calling code is trusted anyway this is safe (if you set
|
||||
; TrustedBinaries = true in the [XEngine] section then you already have to trust that incoming code for other reasons).
|
||||
async_call_method = SmartThreadPool
|
||||
|
||||
; Max threads to allocate on the FireAndForget thread pool
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
<configuration>
|
||||
<dllmap os="windows" cpu="x86" dll="BulletSim" target="lib32/BulletSim" />
|
||||
<dllmap os="windows" cpu="x86-64,ia64" dll="BulletSim" target="lib64/BulletSim" />
|
||||
<dllmap os="osx" cpu="x86" dll="BulletSim" target="lib32/libBulletSim.dylib" />
|
||||
<dllmap os="osx" cpu="x86-64,ia64" dll="BulletSim" target="lib32/libBulletSim.dylib" />
|
||||
<dllmap os="!windows,osx" cpu="x86" dll="BulletSim" target="lib32/libBulletSim.so" />
|
||||
<dllmap os="!windows,osx" cpu="x86-64,ia64" dll="BulletSim" target="lib64/libBulletSim.so" />
|
||||
</configuration>
|
||||
|
|
|
@ -18,13 +18,13 @@
|
|||
; Set path to directory for plugin registry. Information
|
||||
; about the registered repositories and installed plugins
|
||||
; will be stored here
|
||||
; The Robust.exe process must hvae R/W access to the location
|
||||
; The Robust.exe process must have R/W access to the location
|
||||
RegistryLocation = "."
|
||||
|
||||
|
||||
; Modular configurations
|
||||
; Set path to directory for modular ini files...
|
||||
; The Robust.exe process must hvae R/W access to the location
|
||||
; The Robust.exe process must have R/W access to the location
|
||||
ConfigDirectory = "/home/opensim/etc/Configs"
|
||||
|
||||
[ServiceList]
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1760,6 +1760,7 @@
|
|||
<Reference name="System.Xml"/>
|
||||
<Reference name="System.Drawing"/>
|
||||
<Reference name="System.Web"/>
|
||||
<Reference name="Ionic.Zip" path="../../../bin/"/>
|
||||
<Reference name="NDesk.Options" path="../../../bin/"/>
|
||||
<Reference name="OpenMetaverseTypes" path="../../../bin/"/>
|
||||
<Reference name="OpenMetaverse.StructuredData" path="../../../bin/"/>
|
||||
|
|
Loading…
Reference in New Issue