Merge branch 'master' of /home/opensim/var/repo/opensim
commit
b1a42f4257
|
@ -323,6 +323,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
return;
|
||||
}
|
||||
|
||||
// Validate assorted conditions
|
||||
string reason = string.Empty;
|
||||
if (!ValidateGenericConditions(sp, reg, finalDestination, teleportFlags, out reason))
|
||||
{
|
||||
sp.ControllingClient.SendTeleportFailed(reason);
|
||||
return;
|
||||
}
|
||||
|
||||
//
|
||||
// This is it
|
||||
//
|
||||
|
@ -354,6 +362,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
}
|
||||
}
|
||||
|
||||
// Nothing to validate here
|
||||
protected virtual bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
|
||||
{
|
||||
reason = String.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this instance is within the max transfer distance.
|
||||
/// </summary>
|
||||
|
@ -568,7 +583,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
//sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent...");
|
||||
|
||||
if (!UpdateAgent(reg, finalDestination, agent))
|
||||
if (!UpdateAgent(reg, finalDestination, agent, sp))
|
||||
{
|
||||
// Region doesn't take it
|
||||
m_log.WarnFormat(
|
||||
|
@ -695,7 +710,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
return success;
|
||||
}
|
||||
|
||||
protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent)
|
||||
protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent, ScenePresence sp)
|
||||
{
|
||||
return Scene.SimulationService.UpdateAgent(finalDestination, agent);
|
||||
}
|
||||
|
|
|
@ -54,6 +54,60 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
|
||||
private GatekeeperServiceConnector m_GatekeeperConnector;
|
||||
|
||||
protected bool m_RestrictAppearanceAbroad;
|
||||
protected string m_AccountName;
|
||||
protected List<AvatarAppearance> m_ExportedAppearances;
|
||||
protected List<AvatarAttachment> m_Attachs;
|
||||
|
||||
protected List<AvatarAppearance> ExportedAppearance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m_ExportedAppearances != null)
|
||||
return m_ExportedAppearances;
|
||||
|
||||
m_ExportedAppearances = new List<AvatarAppearance>();
|
||||
m_Attachs = new List<AvatarAttachment>();
|
||||
|
||||
string[] names = m_AccountName.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
foreach (string name in names)
|
||||
{
|
||||
string[] parts = name.Trim().Split();
|
||||
if (parts.Length != 2)
|
||||
{
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Wrong user account name format {0}. Specify 'First Last'", name);
|
||||
return null;
|
||||
}
|
||||
UserAccount account = Scene.UserAccountService.GetUserAccount(UUID.Zero, parts[0], parts[1]);
|
||||
if (account == null)
|
||||
{
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unknown account {0}", m_AccountName);
|
||||
return null;
|
||||
}
|
||||
AvatarAppearance a = Scene.AvatarService.GetAppearance(account.PrincipalID);
|
||||
if (a != null)
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Successfully retrieved appearance for {0}", name);
|
||||
|
||||
foreach (AvatarAttachment att in a.GetAttachments())
|
||||
{
|
||||
InventoryItemBase item = new InventoryItemBase(att.ItemID, account.PrincipalID);
|
||||
item = Scene.InventoryService.GetItem(item);
|
||||
if (item != null)
|
||||
a.SetAttachment(att.AttachPoint, att.ItemID, item.AssetID);
|
||||
else
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: Unable to retrieve item {0} from inventory {1}", att.ItemID, name);
|
||||
}
|
||||
|
||||
m_ExportedAppearances.Add(a);
|
||||
m_Attachs.AddRange(a.GetAttachments());
|
||||
}
|
||||
|
||||
return m_ExportedAppearances;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#region ISharedRegionModule
|
||||
|
||||
public override string Name
|
||||
|
@ -72,8 +126,18 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
{
|
||||
IConfig transferConfig = source.Configs["EntityTransfer"];
|
||||
if (transferConfig != null)
|
||||
{
|
||||
m_levelHGTeleport = transferConfig.GetInt("LevelHGTeleport", 0);
|
||||
|
||||
m_RestrictAppearanceAbroad = transferConfig.GetBoolean("RestrictAppearanceAbroad", false);
|
||||
if (m_RestrictAppearanceAbroad)
|
||||
{
|
||||
m_AccountName = transferConfig.GetString("AccountForAppearance", string.Empty);
|
||||
if (m_AccountName == string.Empty)
|
||||
m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is on, but no account has been given for avatar appearance!");
|
||||
}
|
||||
}
|
||||
|
||||
InitialiseCommon(source);
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name);
|
||||
}
|
||||
|
@ -195,6 +259,124 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer
|
|||
return base.CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout);
|
||||
}
|
||||
|
||||
protected override bool ValidateGenericConditions(ScenePresence sp, GridRegion reg, GridRegion finalDestination, uint teleportFlags, out string reason)
|
||||
{
|
||||
reason = "Please wear your grid's allowed appearance before teleporting to another grid";
|
||||
if (!m_RestrictAppearanceAbroad)
|
||||
return true;
|
||||
|
||||
// The rest is only needed for controlling appearance
|
||||
|
||||
int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
|
||||
if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
|
||||
{
|
||||
// this user is going to another grid
|
||||
if (Scene.UserManagementModule.IsLocalGridUser(sp.UUID))
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Checking generic appearance");
|
||||
|
||||
// Check wearables
|
||||
for (int i = 0; i < AvatarWearable.MAX_WEARABLES; i++)
|
||||
{
|
||||
for (int j = 0; j < sp.Appearance.Wearables[i].Count; j++)
|
||||
{
|
||||
if (sp.Appearance.Wearables[i] == null)
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
foreach (AvatarAppearance a in ExportedAppearance)
|
||||
if (a.Wearables[i] != null)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
found = false;
|
||||
foreach (AvatarAppearance a in ExportedAppearance)
|
||||
if (sp.Appearance.Wearables[i][j].AssetID == a.Wearables[i][j].AssetID)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Wearable not allowed to go outside {0}", i);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check attachments
|
||||
foreach (AvatarAttachment att in sp.Appearance.GetAttachments())
|
||||
{
|
||||
bool found = false;
|
||||
foreach (AvatarAttachment att2 in m_Attachs)
|
||||
{
|
||||
if (att2.AssetID == att.AssetID)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Attachment not allowed to go outside {0}", att.AttachPoint);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reason = string.Empty;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agentData, ScenePresence sp)
|
||||
//{
|
||||
// int flags = Scene.GridService.GetRegionFlags(Scene.RegionInfo.ScopeID, reg.RegionID);
|
||||
// if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0)
|
||||
// {
|
||||
// // this user is going to another grid
|
||||
// if (m_RestrictAppearanceAbroad && Scene.UserManagementModule.IsLocalGridUser(agentData.AgentID))
|
||||
// {
|
||||
// // We need to strip the agent off its appearance
|
||||
// m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: RestrictAppearanceAbroad is ON. Sending generic appearance");
|
||||
|
||||
// // Delete existing npc attachments
|
||||
// Scene.AttachmentsModule.DeleteAttachmentsFromScene(sp, false);
|
||||
|
||||
// // XXX: We can't just use IAvatarFactoryModule.SetAppearance() yet since it doesn't transfer attachments
|
||||
// AvatarAppearance newAppearance = new AvatarAppearance(ExportedAppearance, true);
|
||||
// sp.Appearance = newAppearance;
|
||||
|
||||
// // Rez needed npc attachments
|
||||
// Scene.AttachmentsModule.RezAttachments(sp);
|
||||
|
||||
|
||||
// IAvatarFactoryModule module = Scene.RequestModuleInterface<IAvatarFactoryModule>();
|
||||
// //module.SendAppearance(sp.UUID);
|
||||
// module.RequestRebake(sp, false);
|
||||
|
||||
// Scene.AttachmentsModule.CopyAttachments(sp, agentData);
|
||||
// agentData.Appearance = sp.Appearance;
|
||||
// }
|
||||
// }
|
||||
|
||||
// foreach (AvatarAttachment a in agentData.Appearance.GetAttachments())
|
||||
// m_log.DebugFormat("[XXX]: {0}-{1}", a.ItemID, a.AssetID);
|
||||
|
||||
|
||||
// return base.UpdateAgent(reg, finalDestination, agentData, sp);
|
||||
//}
|
||||
|
||||
public override void TeleportHome(UUID id, IClientAPI client)
|
||||
{
|
||||
m_log.DebugFormat(
|
||||
|
|
|
@ -212,6 +212,23 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
|
|||
}
|
||||
}
|
||||
|
||||
public void RegisterScriptInvocations(IRegionModuleBase target)
|
||||
{
|
||||
foreach(MethodInfo method in target.GetType().GetMethods(
|
||||
BindingFlags.Public | BindingFlags.Instance |
|
||||
BindingFlags.Static))
|
||||
{
|
||||
if(method.GetCustomAttributes(
|
||||
typeof(ScriptInvocationAttribute), true).Any())
|
||||
{
|
||||
if(method.IsStatic)
|
||||
RegisterScriptInvocation(target.GetType(), method);
|
||||
else
|
||||
RegisterScriptInvocation(target, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Delegate[] GetScriptInvocationList()
|
||||
{
|
||||
List<Delegate> ret = new List<Delegate>();
|
||||
|
@ -313,6 +330,20 @@ namespace OpenSim.Region.OptionalModules.Scripting.ScriptModuleComms
|
|||
}
|
||||
}
|
||||
|
||||
public void RegisterConstants(IRegionModuleBase target)
|
||||
{
|
||||
foreach (FieldInfo field in target.GetType().GetFields(
|
||||
BindingFlags.Public | BindingFlags.Static |
|
||||
BindingFlags.Instance))
|
||||
{
|
||||
if (field.GetCustomAttributes(
|
||||
typeof(ScriptConstantAttribute), true).Any())
|
||||
{
|
||||
RegisterConstant(field.Name, field.GetValue(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Operation to check for a registered constant
|
||||
/// </summary>
|
|
@ -205,7 +205,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset
|
|||
{
|
||||
// m_log.DebugFormat("[LOCAL ASSET SERVICES CONNECTOR]: Requesting data for asset {0}", id);
|
||||
|
||||
AssetBase asset = m_Cache.Get(id);
|
||||
AssetBase asset = null;
|
||||
|
||||
if (m_Cache != null)
|
||||
asset = m_Cache.Get(id);
|
||||
|
||||
if (asset != null)
|
||||
return asset.Data;
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* 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.Threading;
|
||||
using log4net.Config;
|
||||
using Nini.Config;
|
||||
using NUnit.Framework;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Region.Framework.Scenes;
|
||||
using OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset;
|
||||
using OpenSim.Tests.Common;
|
||||
|
||||
namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AssetConnectorsTests : OpenSimTestCase
|
||||
{
|
||||
[Test]
|
||||
public void TestAddAsset()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
|
||||
config.AddConfig("AssetService");
|
||||
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
|
||||
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
|
||||
|
||||
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
|
||||
lasc.Initialise(config);
|
||||
|
||||
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
|
||||
lasc.Store(a1);
|
||||
|
||||
AssetBase retreivedA1 = lasc.Get(a1.ID);
|
||||
Assert.That(retreivedA1.ID, Is.EqualTo(a1.ID));
|
||||
Assert.That(retreivedA1.Metadata.ID, Is.EqualTo(a1.Metadata.ID));
|
||||
Assert.That(retreivedA1.Data.Length, Is.EqualTo(a1.Data.Length));
|
||||
|
||||
AssetMetadata retrievedA1Metadata = lasc.GetMetadata(a1.ID);
|
||||
Assert.That(retrievedA1Metadata.ID, Is.EqualTo(a1.ID));
|
||||
|
||||
byte[] retrievedA1Data = lasc.GetData(a1.ID);
|
||||
Assert.That(retrievedA1Data.Length, Is.EqualTo(a1.Data.Length));
|
||||
|
||||
// TODO: Add cache and check that this does receive a copy of the asset
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddTemporaryAsset()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
|
||||
config.AddConfig("AssetService");
|
||||
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
|
||||
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
|
||||
|
||||
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
|
||||
lasc.Initialise(config);
|
||||
|
||||
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
|
||||
a1.Temporary = true;
|
||||
|
||||
lasc.Store(a1);
|
||||
|
||||
Assert.That(lasc.Get(a1.ID), Is.Null);
|
||||
Assert.That(lasc.GetData(a1.ID), Is.Null);
|
||||
Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
|
||||
|
||||
// TODO: Add cache and check that this does receive a copy of the asset
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestAddLocalAsset()
|
||||
{
|
||||
TestHelpers.InMethod();
|
||||
// TestHelpers.EnableLogging();
|
||||
|
||||
IConfigSource config = new IniConfigSource();
|
||||
config.AddConfig("Modules");
|
||||
config.Configs["Modules"].Set("AssetServices", "LocalAssetServicesConnector");
|
||||
config.AddConfig("AssetService");
|
||||
config.Configs["AssetService"].Set("LocalServiceModule", "OpenSim.Services.AssetService.dll:AssetService");
|
||||
config.Configs["AssetService"].Set("StorageProvider", "OpenSim.Tests.Common.dll");
|
||||
|
||||
LocalAssetServicesConnector lasc = new LocalAssetServicesConnector();
|
||||
lasc.Initialise(config);
|
||||
|
||||
AssetBase a1 = AssetHelpers.CreateNotecardAsset();
|
||||
a1.Local = true;
|
||||
|
||||
lasc.Store(a1);
|
||||
|
||||
Assert.That(lasc.Get(a1.ID), Is.Null);
|
||||
Assert.That(lasc.GetData(a1.ID), Is.Null);
|
||||
Assert.That(lasc.GetMetadata(a1.ID), Is.Null);
|
||||
|
||||
// TODO: Add cache and check that this does receive a copy of the asset
|
||||
}
|
||||
}
|
||||
}
|
|
@ -74,6 +74,14 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name="methods"></param>
|
||||
void RegisterScriptInvocation(Type target, string[] methods);
|
||||
|
||||
/// <summary>
|
||||
/// Automatically register script invocations by checking for methods
|
||||
/// with <see cref="ScriptInvocationAttribute"/>. Should only check
|
||||
/// public methods.
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
void RegisterScriptInvocations(IRegionModuleBase target);
|
||||
|
||||
/// <summary>
|
||||
/// Returns an array of all registered script calls
|
||||
/// </summary>
|
||||
|
@ -96,11 +104,43 @@ namespace OpenSim.Region.Framework.Interfaces
|
|||
/// <param name="key"></param>
|
||||
void DispatchReply(UUID scriptId, int code, string text, string key);
|
||||
|
||||
/// For constants
|
||||
/// <summary>
|
||||
/// Operation to for a region module to register a constant to be used
|
||||
/// by the script engine
|
||||
/// </summary>
|
||||
/// <param name="cname">
|
||||
/// The name of the constant. LSL convention is for constant names to
|
||||
/// be uppercase.
|
||||
/// </param>
|
||||
/// <param name="value">
|
||||
/// The value of the constant. Should be of a type that can be
|
||||
/// converted to one of <see cref="OpenSim.Region.ScriptEngine.Shared.LSL_Types"/>
|
||||
/// </param>
|
||||
void RegisterConstant(string cname, object value);
|
||||
|
||||
/// <summary>
|
||||
/// Automatically register all constants on a region module by
|
||||
/// checking for fields with <see cref="ScriptConstantAttribute"/>.
|
||||
/// </summary>
|
||||
/// <param name="target"></param>
|
||||
void RegisterConstants(IRegionModuleBase target);
|
||||
|
||||
/// <summary>
|
||||
/// Operation to check for a registered constant
|
||||
/// </summary>
|
||||
/// <param name="cname">Name of constant</param>
|
||||
/// <returns>Value of constant or null if none found.</returns>
|
||||
object LookupModConstant(string cname);
|
||||
|
||||
// For use ONLY by the script API
|
||||
void RaiseEvent(UUID script, string id, string module, string command, string key);
|
||||
}
|
||||
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ScriptInvocationAttribute : Attribute
|
||||
{ }
|
||||
|
||||
[AttributeUsage(AttributeTargets.Field)]
|
||||
public class ScriptConstantAttribute : Attribute
|
||||
{ }
|
||||
}
|
||||
|
|
|
@ -5527,6 +5527,9 @@ namespace OpenSim.Region.Framework.Scenes
|
|||
|
||||
public string GetExtraSetting(string name)
|
||||
{
|
||||
if (m_extraSettings == null)
|
||||
return String.Empty;
|
||||
|
||||
string val;
|
||||
|
||||
if (!m_extraSettings.TryGetValue(name, out val))
|
||||
|
|
|
@ -130,37 +130,37 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
SendConsoleOutput(agentID, String.Format("auto_grant_attach_perms set to {0}", val));
|
||||
}
|
||||
|
||||
private void llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||
private int llAttachToAvatarTemp(UUID host, UUID script, int attachmentPoint)
|
||||
{
|
||||
SceneObjectPart hostPart = m_scene.GetSceneObjectPart(host);
|
||||
|
||||
if (hostPart == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (hostPart.ParentGroup.IsAttachment)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
IAttachmentsModule attachmentsModule = m_scene.RequestModuleInterface<IAttachmentsModule>();
|
||||
if (attachmentsModule == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
TaskInventoryItem item = hostPart.Inventory.GetInventoryItem(script);
|
||||
if (item == null)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if ((item.PermsMask & 32) == 0) // PERMISSION_ATTACH
|
||||
return;
|
||||
return 0;
|
||||
|
||||
ScenePresence target;
|
||||
if (!m_scene.TryGetScenePresence(item.PermsGranter, out target))
|
||||
return;
|
||||
return 0;
|
||||
|
||||
if (target.UUID != hostPart.ParentGroup.OwnerID)
|
||||
{
|
||||
uint effectivePerms = hostPart.ParentGroup.GetEffectivePermissions();
|
||||
|
||||
if ((effectivePerms & (uint)PermissionMask.Transfer) == 0)
|
||||
return;
|
||||
return 0;
|
||||
|
||||
hostPart.ParentGroup.SetOwnerId(target.UUID);
|
||||
hostPart.ParentGroup.SetRootPartOwner(hostPart.ParentGroup.RootPart, target.UUID, target.ControllingClient.ActiveGroupId);
|
||||
|
@ -183,7 +183,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments
|
|||
hostPart.ParentGroup.RootPart.ScheduleFullUpdate();
|
||||
}
|
||||
|
||||
attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true);
|
||||
return attachmentsModule.AttachObject(target, hostPart.ParentGroup, (uint)attachmentPoint, false, true) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -131,8 +131,6 @@ public class BSCharacter : BSPhysObject
|
|||
BulletSimAPI.SetObjectBuoyancy(Scene.WorldID, LocalID, _buoyancy);
|
||||
|
||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(Scene.World.Ptr, LocalID));
|
||||
// avatars get all collisions no matter what (makes walking on ground and such work)
|
||||
BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
|
||||
return;
|
||||
|
@ -480,11 +478,10 @@ public class BSCharacter : BSPhysObject
|
|||
// Stop collision events
|
||||
public override void UnSubscribeEvents() {
|
||||
_subscribedEventsMs = 0;
|
||||
// Avatars get all their collision events
|
||||
// Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
||||
// {
|
||||
// BulletSimAPI.RemoveFromCollisionFlags2(Body.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
// });
|
||||
Scene.TaintedObject("BSCharacter.UnSubscribeEvents", delegate()
|
||||
{
|
||||
BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
});
|
||||
}
|
||||
// Return 'true' if someone has subscribed to events
|
||||
public override bool SubscribedEvents() {
|
||||
|
@ -532,20 +529,20 @@ public class BSCharacter : BSPhysObject
|
|||
// The collision, if it should be reported to the character, is placed in a collection
|
||||
// that will later be sent to the simulator when SendCollisions() is called.
|
||||
CollisionEventUpdate collisionCollection = null;
|
||||
public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, Vector3 contactPoint, Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
bool ret = false;
|
||||
|
||||
// The following makes IsColliding() and IsCollidingGround() work
|
||||
_collidingStep = Scene.SimulationStep;
|
||||
if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
|
||||
if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
|
||||
{
|
||||
_collidingGroundStep = Scene.SimulationStep;
|
||||
}
|
||||
// DetailLog("{0},BSCharacter.Collison,call,with={1}", LocalID, collidingWith);
|
||||
|
||||
// throttle collisions to the rate specified in the subscription
|
||||
if (_subscribedEventsMs != 0) {
|
||||
if (SubscribedEvents()) {
|
||||
int nowTime = Scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||
|
@ -553,8 +550,10 @@ public class BSCharacter : BSPhysObject
|
|||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public override void SendCollisions()
|
||||
|
|
|
@ -74,6 +74,17 @@ public abstract class BSConstraint : IDisposable
|
|||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool SetSolverIterations(float cnt)
|
||||
{
|
||||
bool ret = false;
|
||||
if (m_enabled)
|
||||
{
|
||||
BulletSimAPI.SetConstraintNumSolverIterations2(m_constraint.Ptr, cnt);
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public virtual bool CalculateTransforms()
|
||||
{
|
||||
bool ret = false;
|
||||
|
@ -96,12 +107,9 @@ public abstract class BSConstraint : IDisposable
|
|||
ret = CalculateTransforms();
|
||||
if (ret)
|
||||
{
|
||||
// m_world.scene.PhysicsLogging.Write("{0},BSConstraint.RecomputeConstraintVariables,taint,enabling,A={1},B={2}",
|
||||
// BSScene.DetailLogZero, Body1.ID, Body2.ID);
|
||||
|
||||
// Setting an object's mass to zero (making it static like when it's selected)
|
||||
// automatically disables the constraints.
|
||||
// If enabled, be sure to set the constraint itself to enabled.
|
||||
// If the link is enabled, be sure to set the constraint itself to enabled.
|
||||
BulletSimAPI.SetConstraintEnable2(m_constraint.Ptr, m_world.scene.NumericBool(true));
|
||||
}
|
||||
else
|
||||
|
|
|
@ -80,7 +80,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// Linear properties
|
||||
private Vector3 m_linearMotorDirection = Vector3.Zero; // velocity requested by LSL, decayed by time
|
||||
private Vector3 m_linearMotorDirectionLASTSET = Vector3.Zero; // velocity requested by LSL
|
||||
private Vector3 m_dir = Vector3.Zero; // velocity applied to body
|
||||
private Vector3 m_newVelocity = Vector3.Zero; // velocity computed to be applied to body
|
||||
private Vector3 m_linearFrictionTimescale = Vector3.Zero;
|
||||
private float m_linearMotorDecayTimescale = 0;
|
||||
private float m_linearMotorTimescale = 0;
|
||||
|
@ -131,7 +131,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_type = Vehicle.TYPE_NONE;
|
||||
}
|
||||
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue, float timestep)
|
||||
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||
{
|
||||
VDetailLog("{0},ProcessFloatVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
|
@ -230,7 +230,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}//end ProcessFloatVehicleParam
|
||||
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue, float timestep)
|
||||
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||
{
|
||||
VDetailLog("{0},ProcessVectorVehicleParam,param={1},val={2}", m_prim.LocalID, pParam, pValue);
|
||||
switch (pParam)
|
||||
|
@ -299,7 +299,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}//end ProcessVehicleFlags
|
||||
|
||||
internal void ProcessTypeChange(Vehicle pType, float stepSize)
|
||||
internal void ProcessTypeChange(Vehicle pType)
|
||||
{
|
||||
VDetailLog("{0},ProcessTypeChange,type={1}", m_prim.LocalID, pType);
|
||||
// Set Defaults For Type
|
||||
|
@ -478,29 +478,30 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
MoveAngular(pTimestep);
|
||||
LimitRotation(pTimestep);
|
||||
|
||||
// remember the position so next step we can limit absolute movement effects
|
||||
m_lastPositionVector = m_prim.Position;
|
||||
|
||||
VDetailLog("{0},BSDynamics.Step,done,pos={1},force={2},velocity={3},angvel={4}",
|
||||
m_prim.LocalID, m_prim.Position, m_prim.Force, m_prim.Velocity, m_prim.RotationalVelocity);
|
||||
}// end Step
|
||||
|
||||
private void MoveLinear(float pTimestep)
|
||||
{
|
||||
// requested m_linearMotorDirection is significant
|
||||
// if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
if (m_linearMotorDirection.LengthSquared() > 0.0001f)
|
||||
// m_linearMotorDirection is the direction we are moving relative to the vehicle coordinates
|
||||
// m_lastLinearVelocityVector is the speed we are moving in that direction
|
||||
if (m_linearMotorDirection.LengthSquared() > 0.001f)
|
||||
{
|
||||
Vector3 origDir = m_linearMotorDirection;
|
||||
Vector3 origVel = m_lastLinearVelocityVector;
|
||||
|
||||
// add drive to body
|
||||
// Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale);
|
||||
// lastLinearVelocityVector is the current body velocity vector?
|
||||
// Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale / pTimestep);
|
||||
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/(m_linearMotorTimescale / pTimestep);
|
||||
// lastLinearVelocityVector is the current body velocity vector
|
||||
// RA: Not sure what the *10 is for. A correction for pTimestep?
|
||||
// m_lastLinearVelocityVector += (addAmount*10);
|
||||
m_lastLinearVelocityVector += addAmount;
|
||||
|
||||
// This will work temporarily, but we really need to compare speed on an axis
|
||||
// KF: Limit body velocity to applied velocity?
|
||||
// Limit the velocity vector to less than the last set linear motor direction
|
||||
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||
|
@ -509,53 +510,108 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
if (Math.Abs(m_lastLinearVelocityVector.Z) > Math.Abs(m_linearMotorDirectionLASTSET.Z))
|
||||
m_lastLinearVelocityVector.Z = m_linearMotorDirectionLASTSET.Z;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = ((Vector3.One/(m_linearMotorDecayTimescale/pTimestep)));
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||
|
||||
/*
|
||||
Vector3 addAmount = (m_linearMotorDirection - m_lastLinearVelocityVector)/m_linearMotorTimescale;
|
||||
m_lastLinearVelocityVector += addAmount;
|
||||
|
||||
float decayfraction = (1.0f - 1.0f / m_linearMotorDecayTimescale);
|
||||
m_linearMotorDirection *= decayfraction;
|
||||
|
||||
// decay applied velocity
|
||||
Vector3 decayfraction = Vector3.One/(m_linearMotorDecayTimescale / pTimestep);
|
||||
// (RA: do not know where the 0.5f comes from)
|
||||
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||
*/
|
||||
float keepfraction = 1.0f - (1.0f / (m_linearMotorDecayTimescale / pTimestep));
|
||||
m_linearMotorDirection *= keepfraction;
|
||||
|
||||
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},decay={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, origDir, origVel, addAmount, decayfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
|
||||
VDetailLog("{0},MoveLinear,nonZero,origdir={1},origvel={2},add={3},notDecay={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, origDir, origVel, addAmount, keepfraction, m_linearMotorDirection, m_lastLinearVelocityVector);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if what remains of applied is small, zero it.
|
||||
// if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||
// m_lastLinearVelocityVector = Vector3.Zero;
|
||||
// if what remains of direction is very small, zero it.
|
||||
m_linearMotorDirection = Vector3.Zero;
|
||||
m_lastLinearVelocityVector = Vector3.Zero;
|
||||
VDetailLog("{0},MoveLinear,zeroed", m_prim.LocalID);
|
||||
}
|
||||
|
||||
// convert requested object velocity to object relative vector
|
||||
Quaternion rotq = m_prim.Orientation;
|
||||
m_dir = m_lastLinearVelocityVector * rotq;
|
||||
m_newVelocity = m_lastLinearVelocityVector * rotq;
|
||||
|
||||
// Add the various forces into m_dir which will be our new direction vector (velocity)
|
||||
|
||||
// add Gravity and Buoyancy
|
||||
// KF: So far I have found no good method to combine a script-requested
|
||||
// .Z velocity and gravity. Therefore only 0g will used script-requested
|
||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||
Vector3 grav = Vector3.Zero;
|
||||
// There is some gravity, make a gravity force vector that is applied after object velocity.
|
||||
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||
grav.Z = m_prim.Scene.DefaultGravity.Z * m_prim.Mass * (1f - m_VehicleBuoyancy);
|
||||
Vector3 grav = m_prim.Scene.DefaultGravity * (m_prim.Mass * (1f - m_VehicleBuoyancy));
|
||||
|
||||
/*
|
||||
* RA: Not sure why one would do this
|
||||
// Preserve the current Z velocity
|
||||
Vector3 vel_now = m_prim.Velocity;
|
||||
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||
*/
|
||||
|
||||
Vector3 pos = m_prim.Position;
|
||||
Vector3 posChange = pos;
|
||||
// Vector3 accel = new Vector3(-(m_dir.X - m_lastLinearVelocityVector.X / 0.1f), -(m_dir.Y - m_lastLinearVelocityVector.Y / 0.1f), m_dir.Z - m_lastLinearVelocityVector.Z / 0.1f);
|
||||
double Zchange = Math.Abs(posChange.Z);
|
||||
|
||||
// If below the terrain, move us above the ground a little.
|
||||
float terrainHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
// Taking the rotated size doesn't work here because m_prim.Size is the size of the root prim and not the linkset.
|
||||
// Need to add a m_prim.LinkSet.Size similar to m_prim.LinkSet.Mass.
|
||||
// Vector3 rotatedSize = m_prim.Size * m_prim.Orientation;
|
||||
// if (rotatedSize.Z < terrainHeight)
|
||||
if (pos.Z < terrainHeight)
|
||||
{
|
||||
pos.Z = terrainHeight + 2;
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,terrainHeight={1},pos={2}", m_prim.LocalID, terrainHeight, pos);
|
||||
}
|
||||
|
||||
// Check if hovering
|
||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevelAtXYZ(pos) + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = terrainHeight + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
|
||||
{
|
||||
m_prim.Position = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if (Math.Abs(herr0) > 0.01f)
|
||||
{
|
||||
m_newVelocity.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
//KF: m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_newVelocity.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_newVelocity, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
}
|
||||
|
||||
Vector3 posChange = pos - m_lastPositionVector;
|
||||
if (m_BlockingEndPoint != Vector3.Zero)
|
||||
{
|
||||
bool changed = false;
|
||||
|
@ -592,125 +648,43 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
}
|
||||
}
|
||||
|
||||
// If below the terrain, move us above the ground a little.
|
||||
if (pos.Z < m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos))
|
||||
{
|
||||
pos.Z = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos) + 2;
|
||||
m_prim.Position = pos;
|
||||
VDetailLog("{0},MoveLinear,terrainHeight,pos={1}", m_prim.LocalID, pos);
|
||||
}
|
||||
|
||||
// Check if hovering
|
||||
if ((m_flags & (VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT)) != 0)
|
||||
{
|
||||
// We should hover, get the target height
|
||||
if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.GetWaterLevel() + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_prim.Scene.TerrainManager.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0)
|
||||
{
|
||||
m_VhoverTargetHeight = m_VhoverHeight;
|
||||
}
|
||||
|
||||
if ((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0)
|
||||
{
|
||||
// If body is aready heigher, use its height as target height
|
||||
if (pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0)
|
||||
{
|
||||
if ((pos.Z - m_VhoverTargetHeight) > .2 || (pos.Z - m_VhoverTargetHeight) < -.2)
|
||||
{
|
||||
m_prim.Position = pos;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||
// Replace Vertical speed with correction figure if significant
|
||||
if (Math.Abs(herr0) > 0.01f)
|
||||
{
|
||||
m_dir.Z = -((herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||
//KF: m_VhoverEfficiency is not yet implemented
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dir.Z = 0f;
|
||||
}
|
||||
}
|
||||
|
||||
VDetailLog("{0},MoveLinear,hover,pos={1},dir={2},height={3},target={4}", m_prim.LocalID, pos, m_dir, m_VhoverHeight, m_VhoverTargetHeight);
|
||||
|
||||
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||
// m_VhoverTimescale = 0f; // time to acheive height
|
||||
// pTimestep is time since last frame,in secs
|
||||
}
|
||||
|
||||
float Zchange = Math.Abs(posChange.Z);
|
||||
if ((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0)
|
||||
{
|
||||
//Start Experimental Values
|
||||
if (Zchange > .3)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 3);
|
||||
}
|
||||
if (Zchange > .15)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 2);
|
||||
}
|
||||
if (Zchange > .75)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.5);
|
||||
}
|
||||
if (Zchange > .05)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.25);
|
||||
}
|
||||
if (Zchange > .025)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.125);
|
||||
}
|
||||
float terraintemp = m_prim.Scene.TerrainManager.GetTerrainHeightAtXYZ(pos);
|
||||
float postemp = (pos.Z - terraintemp);
|
||||
float postemp = (pos.Z - terrainHeight);
|
||||
if (postemp > 2.5f)
|
||||
{
|
||||
grav.Z = (float)(grav.Z * 1.037125);
|
||||
}
|
||||
VDetailLog("{0},MoveLinear,limitMotorUp,grav={1}", m_prim.LocalID, grav);
|
||||
//End Experimental Values
|
||||
}
|
||||
if ((m_flags & (VehicleFlag.NO_X)) != 0)
|
||||
{
|
||||
m_dir.X = 0;
|
||||
}
|
||||
m_newVelocity.X = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Y)) != 0)
|
||||
{
|
||||
m_dir.Y = 0;
|
||||
}
|
||||
m_newVelocity.Y = 0;
|
||||
if ((m_flags & (VehicleFlag.NO_Z)) != 0)
|
||||
{
|
||||
m_dir.Z = 0;
|
||||
}
|
||||
|
||||
m_lastPositionVector = m_prim.Position;
|
||||
m_newVelocity.Z = 0;
|
||||
|
||||
// Apply velocity
|
||||
m_prim.Velocity = m_dir;
|
||||
m_prim.Velocity = m_newVelocity;
|
||||
// apply gravity force
|
||||
// Why is this set here? The physics engine already does gravity.
|
||||
// m_prim.AddForce(grav, false);
|
||||
// m_prim.Force = grav;
|
||||
|
||||
// Apply friction
|
||||
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||
Vector3 keepFraction = Vector3.One - (Vector3.One / (m_linearFrictionTimescale / pTimestep));
|
||||
m_lastLinearVelocityVector *= keepFraction;
|
||||
|
||||
VDetailLog("{0},MoveLinear,done,pos={1},vel={2},force={3},decay={4}",
|
||||
m_prim.LocalID, m_lastPositionVector, m_dir, grav, decayamount);
|
||||
VDetailLog("{0},MoveLinear,done,lmDir={1},lmVel={2},newVel={3},grav={4},1Mdecay={5}",
|
||||
m_prim.LocalID, m_linearMotorDirection, m_lastLinearVelocityVector, m_newVelocity, grav, keepFraction);
|
||||
|
||||
} // end MoveLinear()
|
||||
|
||||
|
@ -735,17 +709,18 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
// There are m_angularMotorApply steps.
|
||||
Vector3 origAngularVelocity = m_angularMotorVelocity;
|
||||
// ramp up to new value
|
||||
// current velocity += error / (time to get there / step interval)
|
||||
// current velocity += error / ( time to get there / step interval)
|
||||
// requested speed - last motor speed
|
||||
m_angularMotorVelocity.X += (m_angularMotorDirection.X - m_angularMotorVelocity.X) / (m_angularMotorTimescale / pTimestep);
|
||||
m_angularMotorVelocity.Y += (m_angularMotorDirection.Y - m_angularMotorVelocity.Y) / (m_angularMotorTimescale / pTimestep);
|
||||
m_angularMotorVelocity.Z += (m_angularMotorDirection.Z - m_angularMotorVelocity.Z) / (m_angularMotorTimescale / pTimestep);
|
||||
|
||||
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},origvel={2},dir={3},vel={4}",
|
||||
m_prim.LocalID,m_angularMotorApply,origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
|
||||
VDetailLog("{0},MoveAngular,angularMotorApply,apply={1},angTScale={2},timeStep={3},origvel={4},dir={5},vel={6}",
|
||||
m_prim.LocalID, m_angularMotorApply, m_angularMotorTimescale, pTimestep, origAngularVelocity, m_angularMotorDirection, m_angularMotorVelocity);
|
||||
|
||||
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||
// This is done so that if script request rate is less than phys frame rate the expected
|
||||
// velocity may still be acheived.
|
||||
m_angularMotorApply--;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -760,7 +735,7 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
Vector3 vertattr = Vector3.Zero;
|
||||
if (m_verticalAttractionTimescale < 300)
|
||||
{
|
||||
float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
|
||||
float VAservo = 0.2f / (m_verticalAttractionTimescale / pTimestep);
|
||||
// get present body rotation
|
||||
Quaternion rotq = m_prim.Orientation;
|
||||
// make a vector pointing up
|
||||
|
@ -863,16 +838,12 @@ namespace OpenSim.Region.Physics.BulletSPlugin
|
|||
m_rot.Y = 0;
|
||||
changed = true;
|
||||
}
|
||||
if ((m_flags & VehicleFlag.LOCK_ROTATION) != 0)
|
||||
{
|
||||
m_rot.X = 0;
|
||||
m_rot.Y = 0;
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
m_prim.Orientation = m_rot;
|
||||
VDetailLog("{0},LimitRotation,done,orig={1},new={2}", m_prim.LocalID, rotq, m_rot);
|
||||
}
|
||||
|
||||
VDetailLog("{0},LimitRotation,done,changed={1},orig={2},new={3}", m_prim.LocalID, changed, rotq, m_rot);
|
||||
}
|
||||
|
||||
// Invoke the detailed logger and output something if it's enabled.
|
||||
|
|
|
@ -202,11 +202,33 @@ public class BSLinkset
|
|||
return com;
|
||||
}
|
||||
|
||||
// The object is going dynamic (physical). Do any setup necessary
|
||||
// for a dynamic linkset.
|
||||
// Only the state of the passed object can be modified. The rest of the linkset
|
||||
// has not yet been fully constructed.
|
||||
// Return 'true' if any properties updated on the passed object.
|
||||
// Called at taint-time!
|
||||
public bool MakeDynamic(BSPhysObject child)
|
||||
{
|
||||
bool ret = false;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The object is going static (non-physical). Do any setup necessary
|
||||
// for a static linkset.
|
||||
// Return 'true' if any properties updated on the passed object.
|
||||
// Called at taint-time!
|
||||
public bool MakeStatic(BSPhysObject child)
|
||||
{
|
||||
// What is done for each object in BSPrim is what we want.
|
||||
return false;
|
||||
}
|
||||
|
||||
// When physical properties are changed the linkset needs to recalculate
|
||||
// its internal properties.
|
||||
public void Refresh(BSPhysObject requestor)
|
||||
{
|
||||
// If there are no children, there aren't any constraints to recompute
|
||||
// If there are no children, there can't be any constraints to recompute
|
||||
if (!HasAnyChildren)
|
||||
return;
|
||||
|
||||
|
@ -225,11 +247,12 @@ public class BSLinkset
|
|||
// from a linkset to make sure the constraints know about the new mass and
|
||||
// geometry.
|
||||
// Must only be called at taint time!!
|
||||
private bool RecomputeLinksetConstraintVariables()
|
||||
private void RecomputeLinksetConstraintVariables()
|
||||
{
|
||||
float linksetMass = LinksetMass;
|
||||
lock (m_linksetActivityLock)
|
||||
{
|
||||
bool somethingMissing = false;
|
||||
foreach (BSPhysObject child in m_children)
|
||||
{
|
||||
BSConstraint constrain;
|
||||
|
@ -241,16 +264,36 @@ public class BSLinkset
|
|||
}
|
||||
else
|
||||
{
|
||||
// Non-fatal error that can happen when children are being added to the linkset but
|
||||
// Non-fatal error that happens when children are being added to the linkset but
|
||||
// their constraints have not been created yet.
|
||||
// Caused by the fact that m_children is built at run time but building constraints
|
||||
// happens at taint time.
|
||||
// m_physicsScene.Logger.ErrorFormat("{0} RecomputeLinksetConstraintVariables: constraint not found for root={1}, child={2}",
|
||||
// LogHeader, m_linksetRoot.Body.ID, child.Body.ID);
|
||||
somethingMissing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If the whole linkset is not here, doesn't make sense to recompute linkset wide values
|
||||
if (!somethingMissing)
|
||||
{
|
||||
// If this is a multiple object linkset, set everybody's center of mass to the set's center of mass
|
||||
OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
|
||||
BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
|
||||
foreach (BSPhysObject child in m_children)
|
||||
{
|
||||
BulletSimAPI.SetCenterOfMassByPosRot2(child.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
|
||||
}
|
||||
return false;
|
||||
/*
|
||||
// The root prim takes on the weight of the whole linkset
|
||||
OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(LinksetRoot.BSShape.Ptr, linksetMass);
|
||||
BulletSimAPI.SetMassProps2(LinksetRoot.BSBody.Ptr, linksetMass, inertia);
|
||||
OMV.Vector3 centerOfMass = ComputeLinksetCenterOfMass();
|
||||
BulletSimAPI.SetCenterOfMassByPosRot2(LinksetRoot.BSBody.Ptr, centerOfMass, OMV.Quaternion.Identity);
|
||||
BulletSimAPI.UpdateInertiaTensor2(LinksetRoot.BSBody.Ptr);
|
||||
*/
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// I am the root of a linkset and a new child is being added
|
||||
|
@ -296,9 +339,9 @@ public class BSLinkset
|
|||
DetailLog("{0},RemoveChildFromLinkset,taint,child={1}", m_linksetRoot.LocalID, child.LocalID);
|
||||
|
||||
PhysicallyUnlinkAChildFromRoot(rootx, childx);
|
||||
RecomputeLinksetConstraintVariables();
|
||||
});
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -377,6 +420,10 @@ public class BSLinkset
|
|||
PhysicsScene.Params.linkConstraintTransMotorMaxVel,
|
||||
PhysicsScene.Params.linkConstraintTransMotorMaxForce);
|
||||
constrain.SetCFMAndERP(PhysicsScene.Params.linkConstraintCFM, PhysicsScene.Params.linkConstraintERP);
|
||||
if (PhysicsScene.Params.linkConstraintSolverIterations != 0f)
|
||||
{
|
||||
constrain.SetSolverIterations(PhysicsScene.Params.linkConstraintSolverIterations);
|
||||
}
|
||||
|
||||
RecomputeLinksetConstraintVariables();
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class BSPhysObject : PhysicsActor
|
|||
{
|
||||
public abstract BSLinkset Linkset { get; set; }
|
||||
|
||||
public abstract void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type,
|
||||
public abstract bool Collide(uint collidingWith, BSPhysObject collidee,
|
||||
OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth);
|
||||
public abstract void SendCollisions();
|
||||
|
||||
|
|
|
@ -136,11 +136,11 @@ public sealed class BSPrim : BSPhysObject
|
|||
Linkset = new BSLinkset(Scene, this); // a linkset of one
|
||||
_vehicle = new BSDynamics(Scene, this); // add vehicleness
|
||||
_mass = CalculateMass();
|
||||
// do the actual object creation at taint time
|
||||
DetailLog("{0},BSPrim.constructor,call", LocalID);
|
||||
// do the actual object creation at taint time
|
||||
_scene.TaintedObject("BSPrim.create", delegate()
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(true);
|
||||
|
||||
// Get the pointer to the physical body for this object.
|
||||
// At the moment, we're still letting BulletSim manage the creation and destruction
|
||||
|
@ -186,9 +186,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setSize", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing size changes the mass
|
||||
BulletSimAPI.SetObjectScaleMass(_scene.WorldID, _localID, _scale, (IsPhysical ? _mass : 0f), IsPhysical);
|
||||
DetailLog("{0}: BSPrim.setSize: size={1}, mass={2}, physical={3}", LocalID, _size, _mass, IsPhysical);
|
||||
RecreateGeomAndObject();
|
||||
// Since _size changed, the mesh needs to be rebuilt. If rebuilt, all the correct
|
||||
// scale and margins are set.
|
||||
CreateGeomAndObject(true);
|
||||
DetailLog("{0}: BSPrim.setSize: size={1}, scale={2}, mass={3}, physical={4}", LocalID, _size, _scale, _mass, IsPhysical);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +199,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setShape", delegate()
|
||||
{
|
||||
_mass = CalculateMass(); // changing the shape changes the mass
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(false);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -279,7 +280,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
get {
|
||||
if (!Linkset.IsRoot(this))
|
||||
// child prims move around based on their parent. Need to get the latest location
|
||||
_position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
_position = BulletSimAPI.GetPosition2(BSBody.Ptr);
|
||||
|
||||
// don't do the GetObjectPosition for root elements because this function is called a zillion times
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
|
@ -291,7 +292,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setPosition", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetPosition,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -302,7 +303,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
get
|
||||
{
|
||||
return Linkset.LinksetMass;
|
||||
// return Linkset.LinksetMass;
|
||||
return _mass;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +330,6 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setForce", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.setForce,taint,force={1}", LocalID, _force);
|
||||
// BulletSimAPI.SetObjectForce(_scene.WorldID, _localID, _force);
|
||||
BulletSimAPI.SetObjectForce2(BSBody.Ptr, _force);
|
||||
});
|
||||
}
|
||||
|
@ -345,7 +346,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// 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.
|
||||
_vehicle.ProcessTypeChange(type, Scene.LastSimulatedTimestep);
|
||||
_vehicle.ProcessTypeChange(type);
|
||||
// Tell the scene about the vehicle so it will get processing each frame.
|
||||
_scene.VehicleInSceneTypeChanged(this, type);
|
||||
});
|
||||
|
@ -355,14 +356,14 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleFloatParam", delegate()
|
||||
{
|
||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||
_vehicle.ProcessFloatVehicleParam((Vehicle)param, value);
|
||||
});
|
||||
}
|
||||
public override void VehicleVectorParam(int param, OMV.Vector3 value)
|
||||
{
|
||||
_scene.TaintedObject("BSPrim.VehicleVectorParam", delegate()
|
||||
{
|
||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value, _scene.LastSimulatedTimestep);
|
||||
_vehicle.ProcessVectorVehicleParam((Vehicle)param, value);
|
||||
});
|
||||
}
|
||||
public override void VehicleRotationParam(int param, OMV.Quaternion rotation)
|
||||
|
@ -406,7 +407,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setVelocity", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetVelocity,taint,vel={1}", LocalID, _velocity);
|
||||
BulletSimAPI.SetObjectVelocity(_scene.WorldID, LocalID, _velocity);
|
||||
BulletSimAPI.SetLinearVelocity2(BSBody.Ptr, _velocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -430,7 +431,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
if (!Linkset.IsRoot(this))
|
||||
{
|
||||
// Children move around because tied to parent. Get a fresh value.
|
||||
_orientation = BulletSimAPI.GetObjectOrientation(_scene.WorldID, LocalID);
|
||||
_orientation = BulletSimAPI.GetOrientation2(BSBody.Ptr);
|
||||
}
|
||||
return _orientation;
|
||||
}
|
||||
|
@ -441,7 +442,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// _position = BulletSimAPI.GetObjectPosition(_scene.WorldID, _localID);
|
||||
DetailLog("{0},BSPrim.setOrientation,taint,pos={1},orient={2}", LocalID, _position, _orientation);
|
||||
BulletSimAPI.SetObjectTranslation(_scene.WorldID, _localID, _position, _orientation);
|
||||
BulletSimAPI.SetTranslation2(BSBody.Ptr, _position, _orientation);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -483,31 +484,37 @@ public sealed class BSPrim : BSPhysObject
|
|||
{
|
||||
// If it's becoming dynamic, it will need hullness
|
||||
VerifyCorrectPhysicalShape();
|
||||
UpdatePhysicalParameters();
|
||||
}
|
||||
|
||||
private void UpdatePhysicalParameters()
|
||||
{
|
||||
/*
|
||||
// Bullet wants static objects to have a mass of zero
|
||||
float mass = IsStatic ? 0f : _mass;
|
||||
|
||||
BulletSimAPI.SetObjectProperties(_scene.WorldID, LocalID, IsStatic, IsSolid, SubscribedEvents(), mass);
|
||||
/*
|
||||
*/
|
||||
BulletSimAPI.RemoveObjectFromWorld2(Scene.World.Ptr, BSBody.Ptr);
|
||||
|
||||
// Set up the object physicalness (static or dynamic)
|
||||
MakeDynamic();
|
||||
// Set up the object physicalness (does gravity and collisions move this object)
|
||||
MakeDynamic(IsStatic);
|
||||
|
||||
// Make solid or not and arrange for collisions, etc
|
||||
MakeSolid();
|
||||
// Make solid or not (do things bounce off or pass through this object)
|
||||
MakeSolid(IsSolid);
|
||||
|
||||
m_currentCollisionFlags = BulletSimAPI.GetCollisionFlags2(BSBody.Ptr);
|
||||
// Arrange for collisions events if the simulator wants them
|
||||
EnableCollisions(SubscribedEvents());
|
||||
|
||||
BulletSimAPI.AddObjectToWorld2(Scene.World.Ptr, BSBody.Ptr);
|
||||
*/
|
||||
|
||||
// Recompute any linkset parameters.
|
||||
// When going from non-physical to physical, this re-enables the constraints that
|
||||
// had been automatically disabled when the mass was set to zero.
|
||||
Linkset.Refresh(this);
|
||||
|
||||
DetailLog("{0},BSPrim.SetObjectDynamic,taint,static={1},solid={2},mass={3}, cf={4}", LocalID, IsStatic, IsSolid, mass, m_currentCollisionFlags);
|
||||
DetailLog("{0},BSPrim.UpdatePhysicalParameters,taint,static={1},solid={2},mass={3}, cf={4}",
|
||||
LocalID, IsStatic, IsSolid, _mass, m_currentCollisionFlags);
|
||||
}
|
||||
|
||||
// "Making dynamic" means changing to and from static.
|
||||
|
@ -515,39 +522,84 @@ public sealed class BSPrim : BSPhysObject
|
|||
// When dynamic, the object can fall and be pushed by others.
|
||||
// This is independent of its 'solidness' which controls what passes through
|
||||
// this object and what interacts with it.
|
||||
private void MakeDynamic()
|
||||
private void MakeDynamic(bool makeStatic)
|
||||
{
|
||||
if (IsStatic)
|
||||
if (makeStatic)
|
||||
{
|
||||
// Become a Bullet 'static' object type
|
||||
BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
// Stop all movement
|
||||
BulletSimAPI.ClearAllForces2(BSBody.Ptr);
|
||||
// Center of mass is at the center of the object
|
||||
BulletSimAPI.SetCenterOfMassByPosRot2(Linkset.LinksetRoot.BSBody.Ptr, _position, _orientation);
|
||||
// Mass is zero which disables a bunch of physics stuff in Bullet
|
||||
BulletSimAPI.SetMassProps2(BSBody.Ptr, 0f, OMV.Vector3.Zero);
|
||||
// There is no inertia in a static object
|
||||
BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
|
||||
// There can be special things needed for implementing linksets
|
||||
Linkset.MakeStatic(this);
|
||||
// The activation state is 'sleeping' so Bullet will not try to act on it
|
||||
BulletSimAPI.ForceActivationState2(BSBody.Ptr, ActivationState.ISLAND_SLEEPING);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not a Bullet static object
|
||||
BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_STATIC_OBJECT);
|
||||
|
||||
// Set various physical properties so internal things will get computed correctly as they are set
|
||||
BulletSimAPI.SetFriction2(BSBody.Ptr, Scene.Params.defaultFriction);
|
||||
BulletSimAPI.SetRestitution2(BSBody.Ptr, Scene.Params.defaultRestitution);
|
||||
// per http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?t=3382
|
||||
BulletSimAPI.SetInterpolationLinearVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||
BulletSimAPI.SetInterpolationAngularVelocity2(BSBody.Ptr, OMV.Vector3.Zero);
|
||||
BulletSimAPI.SetInterpolationVelocity2(BSBody.Ptr, OMV.Vector3.Zero, OMV.Vector3.Zero);
|
||||
|
||||
// A dynamic object has mass
|
||||
BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, OMV.Vector3.Zero);
|
||||
// The shape is interesting and has mass and a center of gravity
|
||||
IntPtr collisionShapePtr = BulletSimAPI.GetCollisionShape2(BSBody.Ptr);
|
||||
BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, _mass, OMV.Vector3.Zero);
|
||||
OMV.Vector3 inertia = BulletSimAPI.CalculateLocalInertia2(collisionShapePtr, Linkset.LinksetMass);
|
||||
BulletSimAPI.SetMassProps2(BSBody.Ptr, _mass, inertia);
|
||||
// Inertia is based on our new mass
|
||||
BulletSimAPI.UpdateInertiaTensor2(BSBody.Ptr);
|
||||
|
||||
// Various values for simulation limits
|
||||
BulletSimAPI.SetDamping2(BSBody.Ptr, Scene.Params.linearDamping, Scene.Params.angularDamping);
|
||||
BulletSimAPI.SetDeactivationTime2(BSBody.Ptr, Scene.Params.deactivationTime);
|
||||
BulletSimAPI.SetSleepingThresholds2(BSBody.Ptr, Scene.Params.linearSleepingThreshold, Scene.Params.angularSleepingThreshold);
|
||||
BulletSimAPI.SetContactProcessingThreshold2(BSBody.Ptr, Scene.Params.contactProcessingThreshold);
|
||||
|
||||
// There can be special things needed for implementing linksets
|
||||
Linkset.MakeDynamic(this);
|
||||
|
||||
// Force activation of the object so Bullet will act on it.
|
||||
BulletSimAPI.Activate2(BSBody.Ptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
private void MakeSolid()
|
||||
// "Making solid" means that other object will not pass through this object.
|
||||
private void MakeSolid(bool makeSolid)
|
||||
{
|
||||
if (makeSolid)
|
||||
{
|
||||
// Easy in Bullet -- just remove the object flag that controls collision response
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.CF_NO_CONTACT_RESPONSE);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn on or off the flag controlling whether collision events are returned to the simulator.
|
||||
private void EnableCollisions(bool wantsCollisionEvents)
|
||||
{
|
||||
if (wantsCollisionEvents)
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.AddToCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_currentCollisionFlags = BulletSimAPI.RemoveFromCollisionFlags2(BSBody.Ptr, CollisionFlags.BS_SUBSCRIBE_COLLISION_EVENTS);
|
||||
}
|
||||
}
|
||||
|
||||
// prims don't fly
|
||||
|
@ -607,7 +659,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setRotationalVelocity", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetRotationalVel,taint,rotvel={1}", LocalID, _rotationalVelocity);
|
||||
BulletSimAPI.SetObjectAngularVelocity(_scene.WorldID, LocalID, _rotationalVelocity);
|
||||
BulletSimAPI.SetAngularVelocity2(BSBody.Ptr, _rotationalVelocity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -624,7 +676,10 @@ public sealed class BSPrim : BSPhysObject
|
|||
_scene.TaintedObject("BSPrim.setBuoyancy", delegate()
|
||||
{
|
||||
DetailLog("{0},BSPrim.SetBuoyancy,taint,buoy={1}", LocalID, _buoyancy);
|
||||
BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||
// Buoyancy is faked by changing the gravity applied to the object
|
||||
float grav = Scene.Params.gravity * (1f - _buoyancy);
|
||||
BulletSimAPI.SetGravity2(BSBody.Ptr, new OMV.Vector3(0f, 0f, grav));
|
||||
// BulletSimAPI.SetObjectBuoyancy(_scene.WorldID, _localID, _buoyancy);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -686,8 +741,8 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
m_accumulatedForces.Clear();
|
||||
}
|
||||
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, _force);
|
||||
// For unknown reason, "ApplyCentralForce" is really additive.
|
||||
DetailLog("{0},BSPrim.AddObjectForce,taint,force={1}", LocalID, fSum);
|
||||
// For unknown reasons, "ApplyCentralForce" adds this force to the total force on the object.
|
||||
BulletSimAPI.ApplyCentralForce2(BSBody.Ptr, fSum);
|
||||
});
|
||||
}
|
||||
|
@ -1023,22 +1078,30 @@ public sealed class BSPrim : BSPhysObject
|
|||
}// end CalculateMass
|
||||
#endregion Mass Calculation
|
||||
|
||||
// Create the geometry information in Bullet for later use
|
||||
// The objects needs a hull if it's physical otherwise a mesh is enough
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used
|
||||
// Returns 'true' if the geometry was rebuilt
|
||||
// Create the geometry information in Bullet for later use.
|
||||
// The objects needs a hull if it's physical otherwise a mesh is enough.
|
||||
// No locking here because this is done when we know physics is not simulating.
|
||||
// if 'forceRebuild' is true, the geometry is rebuilt. Otherwise a previously built version is used.
|
||||
// Returns 'true' if the geometry was rebuilt.
|
||||
// Called at taint-time!
|
||||
private bool CreateGeom(bool forceRebuild)
|
||||
{
|
||||
// the mesher thought this was too simple to mesh. Use a native Bullet collision shape.
|
||||
bool ret = false;
|
||||
if (!_scene.NeedsMeshing(_pbs))
|
||||
bool haveShape = false;
|
||||
|
||||
// If the prim attributes are simple, this could be a simple Bullet native shape
|
||||
if ((_pbs.SculptEntry && !Scene.ShouldMeshSculptedPrim)
|
||||
|| (_pbs.ProfileBegin == 0 && _pbs.ProfileEnd == 0
|
||||
&& _pbs.ProfileHollow == 0
|
||||
&& _pbs.PathTwist == 0 && _pbs.PathTwistBegin == 0
|
||||
&& _pbs.PathBegin == 0 && _pbs.PathEnd == 0
|
||||
&& _pbs.PathTaperX == 0 && _pbs.PathTaperY == 0
|
||||
&& _pbs.PathScaleX == 100 && _pbs.PathScaleY == 100
|
||||
&& _pbs.PathShearX == 0 && _pbs.PathShearY == 0) )
|
||||
{
|
||||
if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
// if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
|
||||
// {
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to sphere of size {1}", LogHeader, _size);
|
||||
haveShape = true;
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_SPHERE))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,sphere (force={1}", LocalID, forceRebuild);
|
||||
|
@ -1048,11 +1111,11 @@ public sealed class BSPrim : BSPhysObject
|
|||
// TODO: do we need to check for and destroy a mesh or hull that might have been left from before?
|
||||
ret = true;
|
||||
}
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
// m_log.DebugFormat("{0}: CreateGeom: Defaulting to box. lid={1}, type={2}, size={3}", LogHeader, LocalID, _shapeType, _size);
|
||||
haveShape = true;
|
||||
if (forceRebuild || (_shapeType != ShapeData.PhysicsShapeType.SHAPE_BOX))
|
||||
{
|
||||
DetailLog("{0},BSPrim.CreateGeom,box (force={1})", LocalID, forceRebuild);
|
||||
|
@ -1063,16 +1126,16 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
// If a simple shape isn't happening, create a mesh and possibly a hull
|
||||
if (!haveShape)
|
||||
{
|
||||
if (IsPhysical)
|
||||
{
|
||||
if (forceRebuild || _hullKey == 0)
|
||||
{
|
||||
// physical objects require a hull for interaction.
|
||||
// This will create the mesh if it doesn't already exist
|
||||
CreateGeomHull();
|
||||
ret = true;
|
||||
// This also creates the mesh if it doesn't already exist
|
||||
ret = CreateGeomHull();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1080,8 +1143,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
if (forceRebuild || _meshKey == 0)
|
||||
{
|
||||
// Static (non-physical) objects only need a mesh for bumping into
|
||||
CreateGeomMesh();
|
||||
ret = true;
|
||||
ret = CreateGeomMesh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1089,7 +1151,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
}
|
||||
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
private void CreateGeomMesh()
|
||||
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
||||
// Called at taint-time!
|
||||
private bool CreateGeomMesh()
|
||||
{
|
||||
// level of detail based on size and type of the object
|
||||
float lod = _scene.MeshLOD;
|
||||
|
@ -1103,7 +1167,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// m_log.DebugFormat("{0}: CreateGeomMesh: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _meshKey, newMeshKey);
|
||||
|
||||
// if this new shape is the same as last time, don't recreate the mesh
|
||||
if (_meshKey == newMeshKey) return;
|
||||
if (_meshKey == newMeshKey) return false;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,create,key={1}", LocalID, newMeshKey);
|
||||
// Since we're recreating new, get rid of any previously generated shape
|
||||
|
@ -1140,19 +1204,19 @@ public sealed class BSPrim : BSPhysObject
|
|||
_shapeType = ShapeData.PhysicsShapeType.SHAPE_MESH;
|
||||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomMesh,done", LocalID);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// No locking here because this is done when we know physics is not simulating
|
||||
private void CreateGeomHull()
|
||||
// Returns 'true' of a mesh was actually rebuild (we could also have one of these specs).
|
||||
private bool CreateGeomHull()
|
||||
{
|
||||
float lod = _pbs.SculptEntry ? _scene.SculptLOD : _scene.MeshLOD;
|
||||
ulong newHullKey = (ulong)_pbs.GetMeshKey(_size, lod);
|
||||
// m_log.DebugFormat("{0}: CreateGeomHull: lID={1}, oldKey={2}, newKey={3}", LogHeader, _localID, _hullKey, newHullKey);
|
||||
|
||||
// if the hull hasn't changed, don't rebuild it
|
||||
if (newHullKey == _hullKey) return;
|
||||
if (newHullKey == _hullKey) return false;
|
||||
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,create,oldKey={1},newKey={2}", LocalID, _hullKey, newHullKey);
|
||||
|
||||
|
@ -1255,7 +1319,7 @@ public sealed class BSPrim : BSPhysObject
|
|||
// meshes are already scaled by the meshmerizer
|
||||
_scale = new OMV.Vector3(1f, 1f, 1f);
|
||||
DetailLog("{0},BSPrim.CreateGeomHull,done", LocalID);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Callback from convex hull creater with a newly created hull.
|
||||
|
@ -1268,20 +1332,12 @@ public sealed class BSPrim : BSPhysObject
|
|||
|
||||
private void VerifyCorrectPhysicalShape()
|
||||
{
|
||||
if (IsStatic)
|
||||
{
|
||||
// if static, we don't need a hull so, if there is one, rebuild without it
|
||||
if (_hullKey != 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
}
|
||||
}
|
||||
else
|
||||
if (!IsStatic)
|
||||
{
|
||||
// if not static, it will need a hull to efficiently collide with things
|
||||
if (_hullKey == 0)
|
||||
{
|
||||
RecreateGeomAndObject();
|
||||
CreateGeomAndObject(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1300,8 +1356,9 @@ public sealed class BSPrim : BSPhysObject
|
|||
// m_log.DebugFormat("{0}: CreateObject: lID={1}, shape={2}", LogHeader, _localID, shape.Type);
|
||||
bool ret = BulletSimAPI.CreateObject(_scene.WorldID, shape);
|
||||
|
||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest.
|
||||
// the CreateObject() may have recreated the rigid body. Make sure we have the latest address.
|
||||
BSBody = new BulletBody(LocalID, BulletSimAPI.GetBodyHandle2(_scene.World.Ptr, LocalID));
|
||||
BSShape = new BulletShape(BulletSimAPI.GetCollisionShape2(BSBody.Ptr));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -1325,15 +1382,20 @@ public sealed class BSPrim : BSPhysObject
|
|||
shape.Static = _isPhysical ? ShapeData.numericFalse : ShapeData.numericTrue;
|
||||
}
|
||||
|
||||
|
||||
// Rebuild the geometry and object.
|
||||
// This is called when the shape changes so we need to recreate the mesh/hull.
|
||||
// No locking here because this is done when the physics engine is not simulating
|
||||
private void RecreateGeomAndObject()
|
||||
private void CreateGeomAndObject(bool forceRebuild)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: RecreateGeomAndObject. lID={1}", LogHeader, _localID);
|
||||
if (CreateGeom(true))
|
||||
// m_log.DebugFormat("{0}: CreateGeomAndObject. lID={1}, force={2}", LogHeader, _localID, forceRebuild);
|
||||
// Create the geometry that will make up the object
|
||||
if (CreateGeom(forceRebuild))
|
||||
{
|
||||
// Create the object and place it into the world
|
||||
CreateObject();
|
||||
// Make sure the properties are set on the new object
|
||||
UpdatePhysicalParameters();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1414,12 +1476,14 @@ public sealed class BSPrim : BSPhysObject
|
|||
DetailLog("{0},BSPrim.UpdateProperties,call,pos={1},orient={2},vel={3},accel={4},rotVel={5}",
|
||||
LocalID, _position, _orientation, _velocity, _acceleration, _rotationalVelocity);
|
||||
|
||||
// BulletSimAPI.DumpRigidBody2(Scene.World.Ptr, BSBody.Ptr);
|
||||
|
||||
base.RequestPhysicsterseUpdate();
|
||||
}
|
||||
/*
|
||||
else
|
||||
{
|
||||
// For debugging, we also report the movement of children
|
||||
// For debugging, we can also 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);
|
||||
|
@ -1430,15 +1494,15 @@ public sealed class BSPrim : BSPhysObject
|
|||
// I've collided with something
|
||||
// Called at taint time from within the Step() function
|
||||
CollisionEventUpdate collisionCollection;
|
||||
public override void Collide(uint collidingWith, BSPhysObject collidee, ActorTypes type, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
public override bool Collide(uint collidingWith, BSPhysObject collidee, OMV.Vector3 contactPoint, OMV.Vector3 contactNormal, float pentrationDepth)
|
||||
{
|
||||
// m_log.DebugFormat("{0}: Collide: ms={1}, id={2}, with={3}", LogHeader, _subscribedEventsMs, LocalID, collidingWith);
|
||||
bool ret = false;
|
||||
|
||||
// The following lines make IsColliding() and IsCollidingGround() work
|
||||
_collidingStep = _scene.SimulationStep;
|
||||
if (collidingWith == BSScene.TERRAIN_ID || collidingWith == BSScene.GROUNDPLANE_ID)
|
||||
_collidingStep = Scene.SimulationStep;
|
||||
if (collidingWith <= Scene.TerrainManager.HighestTerrainID)
|
||||
{
|
||||
_collidingGroundStep = _scene.SimulationStep;
|
||||
_collidingGroundStep = Scene.SimulationStep;
|
||||
}
|
||||
|
||||
// DetailLog("{0},BSPrim.Collison,call,with={1}", LocalID, collidingWith);
|
||||
|
@ -1446,21 +1510,23 @@ public sealed class BSPrim : BSPhysObject
|
|||
// prims in the same linkset cannot collide with each other
|
||||
if (collidee != null && (this.Linkset.LinksetID == collidee.Linkset.LinksetID))
|
||||
{
|
||||
return;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// if someone has subscribed for collision events....
|
||||
if (SubscribedEvents()) {
|
||||
// throttle the collisions to the number of milliseconds specified in the subscription
|
||||
int nowTime = _scene.SimulationNowTime;
|
||||
int nowTime = Scene.SimulationNowTime;
|
||||
if (nowTime >= _nextCollisionOkTime) {
|
||||
_nextCollisionOkTime = nowTime + _subscribedEventsMs;
|
||||
|
||||
if (collisionCollection == null)
|
||||
collisionCollection = new CollisionEventUpdate();
|
||||
collisionCollection.AddCollider(collidingWith, new ContactPoint(contactPoint, contactNormal, pentrationDepth));
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// The scene is telling us it's time to pass our collected collisions into the simulator
|
||||
|
|
|
@ -56,7 +56,6 @@ using OpenMetaverse;
|
|||
// Do attachments need to be handled separately? Need collision events. Do not collide with VolumeDetect
|
||||
// Implement LockAngularMotion
|
||||
// Decide if clearing forces is the right thing to do when setting position (BulletSim::SetObjectTranslation)
|
||||
// Does NeedsMeshing() really need to exclude all the different shapes?
|
||||
// Remove mesh and Hull stuff. Use mesh passed to bullet and use convexdecom from bullet.
|
||||
// Add PID movement operations. What does ScenePresence.MoveToTarget do?
|
||||
// Check terrain size. 128 or 127?
|
||||
|
@ -79,7 +78,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
private HashSet<BSPhysObject> m_objectsWithCollisions = new HashSet<BSPhysObject>();
|
||||
// Following is a kludge and can be removed when avatar animation updating is
|
||||
// moved to a better place.
|
||||
private HashSet<BSCharacter> m_avatarsWithCollisions = new HashSet<BSCharacter>();
|
||||
private HashSet<BSPhysObject> m_avatarsWithCollisions = new HashSet<BSPhysObject>();
|
||||
|
||||
// List of all the objects that have vehicle properties and should be called
|
||||
// to update each physics step.
|
||||
|
@ -111,11 +110,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
private long m_simulationStep = 0;
|
||||
public long SimulationStep { get { return m_simulationStep; } }
|
||||
|
||||
// The length of the last timestep we were asked to simulate.
|
||||
// This is used by the vehicle code. Since the vehicle code is called
|
||||
// once per simulation step, its constants need to be scaled by this.
|
||||
public float LastSimulatedTimestep { get; private set; }
|
||||
|
||||
// A value of the time now so all the collision and update routines do not have to get their own
|
||||
// Set to 'now' just before all the prims and actors are called for collisions and updates
|
||||
public int SimulationNowTime { get; private set; }
|
||||
|
@ -132,8 +126,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
private EntityProperties[] m_updateArray;
|
||||
private GCHandle m_updateArrayPinnedHandle;
|
||||
|
||||
private bool _meshSculptedPrim = true; // cause scuplted prims to get meshed
|
||||
private bool _forceSimplePrimMeshing = false; // if a cube or sphere, let Bullet do internal shapes
|
||||
public bool ShouldMeshSculptedPrim { get; private set; } // cause scuplted prims to get meshed
|
||||
public bool ShouldForceSimplePrimMeshing { get; private set; } // if a cube or sphere, let Bullet do internal shapes
|
||||
|
||||
public float PID_D { get; private set; } // derivative
|
||||
public float PID_P { get; private set; } // proportional
|
||||
|
@ -153,6 +147,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
get { return new Vector3(0f, 0f, Params.gravity); }
|
||||
}
|
||||
// Just the Z value of the gravity
|
||||
public float DefaultGravityZ
|
||||
{
|
||||
get { return Params.gravity; }
|
||||
}
|
||||
|
||||
public float MaximumObjectMass { get; private set; }
|
||||
|
||||
|
@ -171,8 +170,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
callback = c;
|
||||
}
|
||||
}
|
||||
private Object _taintLock = new Object(); // lock for using the next object
|
||||
private List<TaintCallbackEntry> _taintedObjects;
|
||||
private Object _taintLock = new Object();
|
||||
|
||||
// A pointer to an instance if this structure is passed to the C++ code
|
||||
// Used to pass basic configuration values to the unmanaged code.
|
||||
|
@ -465,12 +464,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
int collidersCount = 0;
|
||||
IntPtr collidersPtr;
|
||||
|
||||
LastSimulatedTimestep = timeStep;
|
||||
|
||||
// prevent simulation until we've been initialized
|
||||
if (!m_initialized) return 10.0f;
|
||||
|
||||
int simulateStartTime = Util.EnvironmentTickCount();
|
||||
if (!m_initialized) return 5.0f;
|
||||
|
||||
// update the prim states while we know the physics engine is not busy
|
||||
int numTaints = _taintedObjects.Count;
|
||||
|
@ -478,6 +473,7 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
// Some of the prims operate with special vehicle properties
|
||||
ProcessVehicles(timeStep);
|
||||
numTaints += _taintedObjects.Count;
|
||||
ProcessTaints(); // the vehicles might have added taints
|
||||
|
||||
// step the physical world one interval
|
||||
|
@ -506,6 +502,12 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
// Get a value for 'now' so all the collision and update routines don't have to get their own
|
||||
SimulationNowTime = Util.EnvironmentTickCount();
|
||||
|
||||
// This is a kludge to get avatar movement updates.
|
||||
// ODE sends collisions for avatars even if there are have been no collisions. This updates
|
||||
// avatar animations and stuff.
|
||||
// If you fix avatar animation updates, remove this overhead and let normal collision processing happen.
|
||||
m_objectsWithCollisions = new HashSet<BSPhysObject>(m_avatarsWithCollisions);
|
||||
|
||||
// If there were collisions, process them by sending the event to the prim.
|
||||
// Collisions must be processed before updates.
|
||||
if (collidersCount > 0)
|
||||
|
@ -527,13 +529,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
bsp.SendCollisions();
|
||||
m_objectsWithCollisions.Clear();
|
||||
|
||||
// This is a kludge to get avatar movement updated.
|
||||
// ODE sends collisions even if there are none and this is used to update
|
||||
// avatar animations and stuff.
|
||||
foreach (BSPhysObject bpo in m_avatarsWithCollisions)
|
||||
bpo.SendCollisions();
|
||||
// m_avatarsWithCollisions.Clear();
|
||||
|
||||
// If any of the objects had updated properties, tell the object it has been changed by the physics engine
|
||||
if (updatedEntityCount > 0)
|
||||
{
|
||||
|
@ -544,7 +539,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (PhysObjects.TryGetValue(entprop.ID, out pobj))
|
||||
{
|
||||
pobj.UpdateProperties(entprop);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -558,18 +552,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
}
|
||||
}
|
||||
|
||||
// this is a waste since the outside routine also calcuates the physics simulation
|
||||
// period. TODO: There should be a way of computing physics frames from simulator computation.
|
||||
// long simulateTotalTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||
// return (timeStep * (float)simulateTotalTime);
|
||||
|
||||
// TODO: FIX THIS: fps calculation possibly wrong.
|
||||
// This calculation says 1/timeStep is the ideal frame rate. Any time added to
|
||||
// that by the physics simulation gives a slower frame rate.
|
||||
long totalSimulationTime = Util.EnvironmentTickCountSubtract(simulateStartTime);
|
||||
if (totalSimulationTime >= timeStep)
|
||||
return 0;
|
||||
return 1f / (timeStep + totalSimulationTime);
|
||||
// The physics engine returns the number of milliseconds it simulated this call.
|
||||
// These are summed and normalized to one second and divided by 1000 to give the reported physics FPS.
|
||||
// Since Bullet normally does 5 or 6 substeps, this will normally sum to about 60 FPS.
|
||||
return numSubSteps * m_fixedTimeStep;
|
||||
}
|
||||
|
||||
// Something has collided
|
||||
|
@ -580,28 +566,25 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
return; // don't send collisions to the terrain
|
||||
}
|
||||
|
||||
BSPhysObject collider = PhysObjects[localID];
|
||||
// TODO: as of this code, terrain was not in the physical object list.
|
||||
// When BSTerrain is created and it will be in the list, we can remove
|
||||
// the possibility that it's not there and just fetch the collidee.
|
||||
BSPhysObject collidee = null;
|
||||
BSPhysObject collider;
|
||||
if (!PhysObjects.TryGetValue(localID, out collider))
|
||||
{
|
||||
// If the object that is colliding cannot be found, just ignore the collision.
|
||||
return;
|
||||
}
|
||||
|
||||
ActorTypes type = ActorTypes.Prim;
|
||||
if (collidingWith <= TerrainManager.HighestTerrainID)
|
||||
{
|
||||
type = ActorTypes.Ground;
|
||||
}
|
||||
else
|
||||
{
|
||||
collidee = PhysObjects[collidingWith];
|
||||
if (collidee is BSCharacter)
|
||||
type = ActorTypes.Agent;
|
||||
}
|
||||
// The terrain is not in the physical object list so 'collidee'
|
||||
// can be null when Collide() is called.
|
||||
BSPhysObject collidee = null;
|
||||
PhysObjects.TryGetValue(collidingWith, out collidee);
|
||||
|
||||
// DetailLog("{0},BSScene.SendCollision,collide,id={1},with={2}", DetailLogZero, localID, collidingWith);
|
||||
|
||||
collider.Collide(collidingWith, collidee, type, collidePoint, collideNormal, penetration);
|
||||
if (collider.Collide(collidingWith, collidee, collidePoint, collideNormal, penetration))
|
||||
{
|
||||
// If a collision was posted, remember to send it to the simulator
|
||||
m_objectsWithCollisions.Add(collider);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -619,9 +602,9 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
public override void SetWaterLevel(float baseheight)
|
||||
{
|
||||
m_waterLevel = baseheight;
|
||||
// TODO: pass to physics engine so things will float?
|
||||
}
|
||||
public float GetWaterLevel()
|
||||
// Someday....
|
||||
public float GetWaterLevelAtXYZ(Vector3 loc)
|
||||
{
|
||||
return m_waterLevel;
|
||||
}
|
||||
|
@ -659,121 +642,6 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
|
||||
public override bool IsThreaded { get { return false; } }
|
||||
|
||||
/// <summary>
|
||||
/// Routine to figure out if we need to mesh this prim with our mesher
|
||||
/// </summary>
|
||||
/// <param name="pbs"></param>
|
||||
/// <returns>true if the prim needs meshing</returns>
|
||||
public bool NeedsMeshing(PrimitiveBaseShape pbs)
|
||||
{
|
||||
// most of this is redundant now as the mesher will return null if it cant mesh a prim
|
||||
// but we still need to check for sculptie meshing being enabled so this is the most
|
||||
// convenient place to do it for now...
|
||||
|
||||
// int iPropertiesNotSupportedDefault = 0;
|
||||
|
||||
if (pbs.SculptEntry && !_meshSculptedPrim)
|
||||
{
|
||||
// Render sculpties as boxes
|
||||
return false;
|
||||
}
|
||||
|
||||
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since Bullet
|
||||
// can use an internal representation for the prim
|
||||
if (!_forceSimplePrimMeshing)
|
||||
{
|
||||
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
|
||||
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
|
||||
{
|
||||
|
||||
if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
|
||||
&& pbs.ProfileHollow == 0
|
||||
&& pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
|
||||
&& pbs.PathBegin == 0 && pbs.PathEnd == 0
|
||||
&& pbs.PathTaperX == 0 && pbs.PathTaperY == 0
|
||||
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
|
||||
&& pbs.PathShearX == 0 && pbs.PathShearY == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: verify that the mesher will now do all these shapes
|
||||
if (pbs.ProfileHollow != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
|
||||
iPropertiesNotSupportedDefault++;
|
||||
|
||||
// test for torus
|
||||
if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
|
||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
|
||||
{
|
||||
if (pbs.PathCurve == (byte)Extrusion.Straight)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
|
||||
{
|
||||
iPropertiesNotSupportedDefault++;
|
||||
}
|
||||
}
|
||||
if (iPropertiesNotSupportedDefault == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
return true;
|
||||
}
|
||||
|
||||
// Calls to the PhysicsActors can't directly call into the physics engine
|
||||
// because it might be busy. We delay changes to a known time.
|
||||
// We rely on C#'s closure to save and restore the context for the delegate.
|
||||
|
@ -782,7 +650,10 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
if (!m_initialized) return;
|
||||
|
||||
lock (_taintLock)
|
||||
{
|
||||
_taintedObjects.Add(new TaintCallbackEntry(ident, callback));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -919,14 +790,14 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
{
|
||||
new ParameterDefn("MeshSculptedPrim", "Whether to create meshes for sculpties",
|
||||
ConfigurationParameters.numericTrue,
|
||||
(s,cf,p,v) => { s._meshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s._meshSculptedPrim); },
|
||||
(s,p,l,v) => { s._meshSculptedPrim = s.BoolNumeric(v); } ),
|
||||
(s,cf,p,v) => { s.ShouldMeshSculptedPrim = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s.ShouldMeshSculptedPrim); },
|
||||
(s,p,l,v) => { s.ShouldMeshSculptedPrim = s.BoolNumeric(v); } ),
|
||||
new ParameterDefn("ForceSimplePrimMeshing", "If true, only use primitive meshes for objects",
|
||||
ConfigurationParameters.numericFalse,
|
||||
(s,cf,p,v) => { s._forceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s._forceSimplePrimMeshing); },
|
||||
(s,p,l,v) => { s._forceSimplePrimMeshing = s.BoolNumeric(v); } ),
|
||||
(s,cf,p,v) => { s.ShouldForceSimplePrimMeshing = cf.GetBoolean(p, s.BoolNumeric(v)); },
|
||||
(s) => { return s.NumericBool(s.ShouldForceSimplePrimMeshing); },
|
||||
(s,p,l,v) => { s.ShouldForceSimplePrimMeshing = s.BoolNumeric(v); } ),
|
||||
|
||||
new ParameterDefn("MeshLevelOfDetail", "Level of detail to render meshes (32, 16, 8 or 4. 32=most detailed)",
|
||||
8f,
|
||||
|
@ -1162,8 +1033,8 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
(s,cf,p,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintTransMotorMaxForce; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintTransMotorMaxForce = v; } ),
|
||||
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=none, 1=all. Default=0",
|
||||
0.0f,
|
||||
new ParameterDefn("LinkConstraintCFM", "Amount constraint can be violated. 0=no violation, 1=infinite. Default=0.1",
|
||||
0.1f,
|
||||
(s,cf,p,v) => { s.m_params[0].linkConstraintCFM = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintCFM; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintCFM = v; } ),
|
||||
|
@ -1172,6 +1043,11 @@ public class BSScene : PhysicsScene, IPhysicsParameters
|
|||
(s,cf,p,v) => { s.m_params[0].linkConstraintERP = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintERP; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintERP = v; } ),
|
||||
new ParameterDefn("LinkConstraintSolverIterations", "Number of solver iterations when computing constraint. (0 = Bullet default)",
|
||||
40,
|
||||
(s,cf,p,v) => { s.m_params[0].linkConstraintSolverIterations = cf.GetFloat(p, v); },
|
||||
(s) => { return s.m_params[0].linkConstraintSolverIterations; },
|
||||
(s,p,l,v) => { s.m_params[0].linkConstraintSolverIterations = v; } ),
|
||||
|
||||
new ParameterDefn("DetailedStats", "Frames between outputting detailed phys stats. (0 is off)",
|
||||
0f,
|
||||
|
|
|
@ -154,6 +154,9 @@ public class BSTerrainManager
|
|||
|
||||
// The simulator wants to set a new heightmap for the terrain.
|
||||
public void SetTerrain(float[] heightMap) {
|
||||
float[] localHeightMap = heightMap;
|
||||
m_physicsScene.TaintedObject("TerrainManager.SetTerrain", delegate()
|
||||
{
|
||||
if (m_worldOffset != Vector3.Zero && m_parentScene != null)
|
||||
{
|
||||
// If a child of a mega-region, we shouldn't have any terrain allocated for us
|
||||
|
@ -165,7 +168,7 @@ public class BSTerrainManager
|
|||
DetailLog("{0},SetTerrain.ToParent,offset={1},worldMax={2}",
|
||||
BSScene.DetailLogZero, m_worldOffset, m_worldMax);
|
||||
((BSScene)m_parentScene).TerrainManager.UpdateOrCreateTerrain(BSScene.CHILDTERRAIN_ID,
|
||||
heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -173,8 +176,9 @@ public class BSTerrainManager
|
|||
// If not doing the mega-prim thing, just change the terrain
|
||||
DetailLog("{0},SetTerrain.Existing", BSScene.DetailLogZero);
|
||||
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, heightMap, m_worldOffset, m_worldOffset+DefaultRegionSize, false);
|
||||
UpdateOrCreateTerrain(BSScene.TERRAIN_ID, localHeightMap, m_worldOffset, m_worldOffset + DefaultRegionSize, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// If called with no mapInfo for the terrain, this will create a new mapInfo and terrain
|
||||
|
@ -319,6 +323,8 @@ public class BSTerrainManager
|
|||
|
||||
// Make sure the new shape is processed.
|
||||
BulletSimAPI.Activate2(mapInfo.terrainBody.Ptr, true);
|
||||
|
||||
m_terrainModified = true;
|
||||
};
|
||||
|
||||
// There is the option to do the changes now (we're already in 'taint time'), or
|
||||
|
@ -357,6 +363,8 @@ public class BSTerrainManager
|
|||
m_heightMaps.Add(terrainRegionBase, mapInfo);
|
||||
// Build the terrain
|
||||
UpdateOrCreateTerrain(newTerrainID, heightMap, minCoords, maxCoords, true);
|
||||
|
||||
m_terrainModified = true;
|
||||
};
|
||||
|
||||
// If already in taint-time, just call Bullet. Otherwise queue the operations for the safe time.
|
||||
|
@ -383,7 +391,7 @@ public class BSTerrainManager
|
|||
private float lastHeightTX = 999999f;
|
||||
private float lastHeightTY = 999999f;
|
||||
private float lastHeight = HEIGHT_INITIAL_LASTHEIGHT;
|
||||
public float GetTerrainHeightAtXY(float tX, float tY)
|
||||
private float GetTerrainHeightAtXY(float tX, float tY)
|
||||
{
|
||||
// You'd be surprized at the number of times this routine is called
|
||||
// with the same parameters as last time.
|
||||
|
@ -403,11 +411,18 @@ public class BSTerrainManager
|
|||
{
|
||||
float regionX = tX - offsetX;
|
||||
float regionY = tY - offsetY;
|
||||
if (regionX >= mapInfo.sizeX || regionX < 0f) regionX = 0;
|
||||
if (regionY >= mapInfo.sizeY || regionY < 0f) regionY = 0;
|
||||
int mapIndex = (int)regionY * (int)mapInfo.sizeY + (int)regionX;
|
||||
try
|
||||
{
|
||||
ret = mapInfo.heightMap[mapIndex];
|
||||
m_terrainModified = false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Sometimes they give us wonky values of X and Y. Give a warning and return something.
|
||||
m_physicsScene.Logger.WarnFormat("{0} Bad request for terrain height. terrainBase={1}, x={2}, y={3}",
|
||||
LogHeader, terrainBaseXY, regionX, regionY);
|
||||
ret = HEIGHT_GETHEIGHT_RET;
|
||||
}
|
||||
// DetailLog("{0},BSTerrainManager.GetTerrainHeightAtXY,bX={1},baseY={2},szX={3},szY={4},regX={5},regY={6},index={7},ht={8}",
|
||||
// BSScene.DetailLogZero, offsetX, offsetY, mapInfo.sizeX, mapInfo.sizeY, regionX, regionY, mapIndex, ret);
|
||||
}
|
||||
|
@ -416,6 +431,7 @@ public class BSTerrainManager
|
|||
m_physicsScene.Logger.ErrorFormat("{0} GetTerrainHeightAtXY: terrain not found: region={1}, x={2}, y={3}",
|
||||
LogHeader, m_physicsScene.RegionName, tX, tY);
|
||||
}
|
||||
m_terrainModified = false;
|
||||
lastHeight = ret;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,7 @@ public struct ConfigurationParameters
|
|||
public float linkConstraintTransMotorMaxForce;
|
||||
public float linkConstraintERP;
|
||||
public float linkConstraintCFM;
|
||||
public float linkConstraintSolverIterations;
|
||||
|
||||
public const float numericTrue = 1f;
|
||||
public const float numericFalse = 0f;
|
||||
|
@ -395,23 +396,6 @@ public static extern bool DestroyMesh(uint worldID, System.UInt64 meshKey);
|
|||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool CreateObject(uint worldID, ShapeData shapeData);
|
||||
|
||||
/* Remove old functionality
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CreateLinkset(uint worldID, int objectCount, ShapeData[] shapeDatas);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void AddConstraint(uint worldID, uint id1, uint id2,
|
||||
Vector3 frame1, Quaternion frame1rot,
|
||||
Vector3 frame2, Quaternion frame2rot,
|
||||
Vector3 lowLinear, Vector3 hiLinear, Vector3 lowAngular, Vector3 hiAngular);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveConstraintByID(uint worldID, uint id1);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool RemoveConstraint(uint worldID, uint id1, uint id2);
|
||||
*/
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern Vector3 GetObjectPosition(uint WorldID, uint id);
|
||||
|
||||
|
@ -538,15 +522,27 @@ public static extern IntPtr BuildHullShape2(IntPtr world, IntPtr meshShape);
|
|||
public static extern IntPtr BuildNativeShape2(IntPtr world,
|
||||
float shapeType, float collisionMargin, Vector3 scale);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool IsNativeShape2(IntPtr shape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateCompoundShape2(IntPtr sim);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void AddChildToCompoundShape2(IntPtr cShape, IntPtr addShape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void RemoveChildFromCompoundShape2(IntPtr cShape, IntPtr removeShape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern bool DeleteCollisionShape2(IntPtr world, IntPtr shape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShape2(IntPtr sim, IntPtr shape, Vector3 pos, Quaternion rot);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyFromShapeAndInfo2(IntPtr sim, IntPtr shape, IntPtr constructionInfo);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateBodyWithDefaultMotionState2(IntPtr shape, Vector3 pos, Quaternion rot);
|
||||
|
||||
|
@ -561,9 +557,6 @@ public static extern void DestroyObject2(IntPtr sim, IntPtr obj);
|
|||
|
||||
// =====================================================================================
|
||||
// Terrain creation and helper routines
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void DumpMapInfo(IntPtr sim, IntPtr manInfo);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern IntPtr CreateHeightMapInfo2(IntPtr sim, uint id, Vector3 minCoords, Vector3 maxCoords,
|
||||
[MarshalAs(UnmanagedType.LPArray)] float[] heightMap, float collisionMargin);
|
||||
|
@ -1010,7 +1003,7 @@ public static extern void SetLocalScaling2(IntPtr shape, Vector3 scale);
|
|||
public static extern Vector3 GetLocalScaling2(IntPtr shape);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void CalculateLocalInertia2(IntPtr shape, float mass, Vector3 inertia);
|
||||
public static extern Vector3 CalculateLocalInertia2(IntPtr shape, float mass);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern int GetShapeType2(IntPtr shape);
|
||||
|
@ -1026,6 +1019,12 @@ public static extern void SetCollisionFilterMask(IntPtr shape, uint filter, uint
|
|||
|
||||
// =====================================================================================
|
||||
// Debugging
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void DumpRigidBody2(IntPtr sim, IntPtr collisionObject);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void DumpMapInfo2(IntPtr sim, IntPtr manInfo);
|
||||
|
||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||
public static extern void DumpPhysicsStatistics2(IntPtr sim);
|
||||
|
||||
|
|
|
@ -84,7 +84,7 @@ namespace OpenSim.Services.AssetService
|
|||
|
||||
m_Database = LoadPlugin<IAssetDataPlugin>(dllName);
|
||||
if (m_Database == null)
|
||||
throw new Exception("Could not find a storage interface in the given module");
|
||||
throw new Exception(string.Format("Could not find a storage interface in the module {0}", dllName));
|
||||
|
||||
m_Database.Initialise(connString);
|
||||
|
||||
|
@ -96,7 +96,7 @@ namespace OpenSim.Services.AssetService
|
|||
m_AssetLoader = LoadPlugin<IAssetLoader>(loaderName);
|
||||
|
||||
if (m_AssetLoader == null)
|
||||
throw new Exception("Asset loader could not be loaded");
|
||||
throw new Exception(string.Format("Asset loader could not be loaded from {0}", loaderName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -573,6 +573,7 @@ namespace OpenSim.Services.HypergridService
|
|||
private bool IsPartOfAppearance(UUID principalID, UUID itemID)
|
||||
{
|
||||
AvatarAppearance a = GetAppearance(principalID);
|
||||
|
||||
if (a == null)
|
||||
return false;
|
||||
|
||||
|
|
|
@ -153,6 +153,7 @@
|
|||
; For the InventoryServiceInConnector
|
||||
LocalServiceModule = "OpenSim.Services.HypergridService.dll:HGInventoryService"
|
||||
UserAccountsService = "OpenSim.Services.UserAccountService.dll:UserAccountService"
|
||||
AvatarService = "OpenSim.Services.AvatarService.dll:AvatarService"
|
||||
|
||||
;; The interface that local users get when they are in other grids
|
||||
;; This restricts/filters the asset operations from the outside
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -3009,6 +3009,7 @@
|
|||
<Match path="World/Media/Moap/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="World/Serialiser/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="World/Terrain/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="ServiceConnectorsOut/Asset/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="ServiceConnectorsOut/Grid/Tests" pattern="*.cs" recurse="true"/>
|
||||
<Match path="ServiceConnectorsOut/Presence/Tests" pattern="*.cs" recurse="true"/>
|
||||
</Files>
|
||||
|
|
Loading…
Reference in New Issue