Merge branch 'master' of ssh://TOR/var/git/careminster
commit
c54e0953d0
|
@ -46,7 +46,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
public delegate UUID UpdateItem(UUID itemID, byte[] data);
|
public delegate UUID UpdateItem(UUID itemID, byte[] data);
|
||||||
|
|
||||||
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data);
|
public delegate void UpdateTaskScript(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors);
|
||||||
|
|
||||||
public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
|
public delegate void NewInventoryItem(UUID userID, InventoryItemBase item);
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ namespace OpenSim.Framework.Capabilities
|
||||||
|
|
||||||
public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
|
public delegate UUID ItemUpdatedCallback(UUID userID, UUID itemID, byte[] data);
|
||||||
|
|
||||||
public delegate void TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
|
public delegate ArrayList TaskScriptUpdatedCallback(UUID userID, UUID itemID, UUID primID,
|
||||||
bool isScriptRunning, byte[] data);
|
bool isScriptRunning, byte[] data);
|
||||||
|
|
||||||
public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
public delegate InventoryCollection FetchInventoryDescendentsCAPS(UUID agentID, UUID folderID, UUID ownerID,
|
||||||
|
@ -940,11 +940,13 @@ namespace OpenSim.Framework.Capabilities
|
||||||
/// <param name="primID">Prim containing item to update</param>
|
/// <param name="primID">Prim containing item to update</param>
|
||||||
/// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
|
/// <param name="isScriptRunning">Signals whether the script to update is currently running</param>
|
||||||
/// <param name="data">New asset data</param>
|
/// <param name="data">New asset data</param>
|
||||||
public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data)
|
public void TaskScriptUpdated(UUID itemID, UUID primID, bool isScriptRunning, byte[] data, ref ArrayList errors)
|
||||||
{
|
{
|
||||||
if (TaskScriptUpdatedCall != null)
|
if (TaskScriptUpdatedCall != null)
|
||||||
{
|
{
|
||||||
TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
|
ArrayList e = TaskScriptUpdatedCall(m_agentID, itemID, primID, isScriptRunning, data);
|
||||||
|
foreach (Object item in e)
|
||||||
|
errors.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1174,17 +1176,20 @@ namespace OpenSim.Framework.Capabilities
|
||||||
// data, path, param));
|
// data, path, param));
|
||||||
|
|
||||||
string res = String.Empty;
|
string res = String.Empty;
|
||||||
LLSDTaskInventoryUploadComplete uploadComplete = new LLSDTaskInventoryUploadComplete();
|
LLSDTaskScriptUploadComplete uploadComplete = new LLSDTaskScriptUploadComplete();
|
||||||
|
|
||||||
|
ArrayList errors = new ArrayList();
|
||||||
handlerUpdateTaskScript = OnUpLoad;
|
handlerUpdateTaskScript = OnUpLoad;
|
||||||
if (handlerUpdateTaskScript != null)
|
if (handlerUpdateTaskScript != null)
|
||||||
{
|
{
|
||||||
handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data);
|
handlerUpdateTaskScript(inventoryItemID, primID, isScriptRunning, data, ref errors);
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadComplete.item_id = inventoryItemID;
|
uploadComplete.new_asset = inventoryItemID;
|
||||||
uploadComplete.task_id = primID;
|
uploadComplete.compiled = errors.Count > 0 ? false : true;
|
||||||
uploadComplete.state = "complete";
|
uploadComplete.state = "complete";
|
||||||
|
uploadComplete.errors = new OSDArray();
|
||||||
|
uploadComplete.errors.Array = errors;
|
||||||
|
|
||||||
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
res = LLSDHelpers.SerialiseLLSDReply(uploadComplete);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* 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 OpenMetaverse;
|
||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace OpenSim.Framework.Capabilities
|
||||||
|
{
|
||||||
|
[OSDMap]
|
||||||
|
public class LLSDTaskScriptUploadComplete
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The task inventory item that was updated
|
||||||
|
/// </summary>
|
||||||
|
public UUID new_asset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Was it compiled?
|
||||||
|
/// </summary>
|
||||||
|
public bool compiled;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// State of the upload. So far have only even seen this set to "complete"
|
||||||
|
/// </summary>
|
||||||
|
public string state;
|
||||||
|
|
||||||
|
public OSDArray errors;
|
||||||
|
}
|
||||||
|
}
|
|
@ -171,6 +171,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
item.NextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF);
|
item.NextPermissions = (uint)config.GetLong("nextPermissions", 0x7FFFFFFF);
|
||||||
item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF);
|
item.EveryOnePermissions = (uint)config.GetLong("everyonePermissions", 0x7FFFFFFF);
|
||||||
item.BasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF);
|
item.BasePermissions = (uint)config.GetLong("basePermissions", 0x7FFFFFFF);
|
||||||
|
item.Flags = (uint)config.GetInt("flags", 0);
|
||||||
|
|
||||||
if (libraryFolders.ContainsKey(item.Folder))
|
if (libraryFolders.ContainsKey(item.Folder))
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,6 +142,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
|
|
||||||
if (userProfile != null)
|
if (userProfile != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((userProfile.UserAssetURI == null || userProfile.UserAssetURI == "") && m_commsManager.NetworkServersInfo != null)
|
if ((userProfile.UserAssetURI == null || userProfile.UserAssetURI == "") && m_commsManager.NetworkServersInfo != null)
|
||||||
userProfile.UserAssetURI = m_commsManager.NetworkServersInfo.AssetURL;
|
userProfile.UserAssetURI = m_commsManager.NetworkServersInfo.AssetURL;
|
||||||
if ((userProfile.UserInventoryURI == null || userProfile.UserInventoryURI == "") && m_commsManager.NetworkServersInfo != null)
|
if ((userProfile.UserInventoryURI == null || userProfile.UserInventoryURI == "") && m_commsManager.NetworkServersInfo != null)
|
||||||
|
@ -177,6 +178,7 @@ namespace OpenSim.Framework.Communications.Cache
|
||||||
UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID);
|
UserProfileData userProfile = m_commsManager.UserService.GetUserProfile(userID);
|
||||||
if (userProfile != null)
|
if (userProfile != null)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((userProfile.UserAssetURI == null || userProfile.UserAssetURI == "") && m_commsManager.NetworkServersInfo != null)
|
if ((userProfile.UserAssetURI == null || userProfile.UserAssetURI == "") && m_commsManager.NetworkServersInfo != null)
|
||||||
userProfile.UserAssetURI = m_commsManager.NetworkServersInfo.AssetURL;
|
userProfile.UserAssetURI = m_commsManager.NetworkServersInfo.AssetURL;
|
||||||
if ((userProfile.UserInventoryURI == null || userProfile.UserInventoryURI == "") && m_commsManager.NetworkServersInfo != null)
|
if ((userProfile.UserInventoryURI == null || userProfile.UserInventoryURI == "") && m_commsManager.NetworkServersInfo != null)
|
||||||
|
|
|
@ -56,6 +56,17 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
private ISessionAuthInventoryService m_HGService;
|
private ISessionAuthInventoryService m_HGService;
|
||||||
|
|
||||||
private string m_LocalGridInventoryURI = string.Empty;
|
private string m_LocalGridInventoryURI = string.Empty;
|
||||||
|
|
||||||
|
private string LocalGridInventory
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (m_LocalGridInventoryURI == null || m_LocalGridInventoryURI == "")
|
||||||
|
m_LocalGridInventoryURI = m_Scene.CommsManager.NetworkServersInfo.InventoryURL;
|
||||||
|
return m_LocalGridInventoryURI;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Type ReplaceableInterface
|
public Type ReplaceableInterface
|
||||||
{
|
{
|
||||||
get { return null; }
|
get { return null; }
|
||||||
|
@ -533,7 +544,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
|
|
||||||
string userInventoryServerURI = Util.ServerURI(uinfo.UserProfile.UserInventoryURI);
|
string userInventoryServerURI = Util.ServerURI(uinfo.UserProfile.UserInventoryURI);
|
||||||
|
|
||||||
string uri = m_LocalGridInventoryURI.TrimEnd('/');
|
string uri = LocalGridInventory.TrimEnd('/');
|
||||||
|
|
||||||
if ((userInventoryServerURI == uri) || (userInventoryServerURI == ""))
|
if ((userInventoryServerURI == uri) || (userInventoryServerURI == ""))
|
||||||
{
|
{
|
||||||
|
@ -545,7 +556,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory
|
||||||
|
|
||||||
private string GetUserInventoryURI(UUID userID)
|
private string GetUserInventoryURI(UUID userID)
|
||||||
{
|
{
|
||||||
string invURI = m_LocalGridInventoryURI;
|
string invURI = LocalGridInventory;
|
||||||
|
|
||||||
CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID);
|
CachedUserInfo uinfo = m_UserProfileService.GetUserDetails(userID);
|
||||||
if ((uinfo == null) || (uinfo.UserProfile == null))
|
if ((uinfo == null) || (uinfo.UserProfile == null))
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
|
|
||||||
|
@ -71,6 +72,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// Start all the scripts contained in this entity's inventory
|
/// Start all the scripts contained in this entity's inventory
|
||||||
/// </summary>
|
/// </summary>
|
||||||
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource);
|
||||||
|
ArrayList GetScriptErrors(UUID itemID);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop all the scripts in this entity.
|
/// Stop all the scripts in this entity.
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Framework.Interfaces
|
namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
@ -39,5 +40,7 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
|
|
||||||
bool PostScriptEvent(UUID itemID, string name, Object[] args);
|
bool PostScriptEvent(UUID itemID, string name, Object[] args);
|
||||||
bool PostObjectEvent(UUID itemID, string name, Object[] args);
|
bool PostObjectEvent(UUID itemID, string name, Object[] args);
|
||||||
|
|
||||||
|
ArrayList GetScriptErrors(UUID itemID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Timers;
|
using System.Timers;
|
||||||
|
@ -215,13 +216,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="primID">The prim which contains the item to update</param>
|
/// <param name="primID">The prim which contains the item to update</param>
|
||||||
/// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
|
/// <param name="isScriptRunning">Indicates whether the script to update is currently running</param>
|
||||||
/// <param name="data"></param>
|
/// <param name="data"></param>
|
||||||
public void CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
|
public ArrayList CapsUpdateTaskInventoryScriptAsset(IClientAPI remoteClient, UUID itemId,
|
||||||
UUID primId, bool isScriptRunning, byte[] data)
|
UUID primId, bool isScriptRunning, byte[] data)
|
||||||
{
|
{
|
||||||
if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
|
if (!Permissions.CanEditScript(itemId, primId, remoteClient.AgentId))
|
||||||
{
|
{
|
||||||
remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
|
remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
|
||||||
return;
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve group
|
// Retrieve group
|
||||||
|
@ -234,7 +235,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
"Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
|
"Prim inventory update requested for item ID {0} in prim ID {1} but this prim does not exist",
|
||||||
itemId, primId);
|
itemId, primId);
|
||||||
|
|
||||||
return;
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve item
|
// Retrieve item
|
||||||
|
@ -247,7 +248,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
+ " but the item does not exist in this inventory",
|
+ " but the item does not exist in this inventory",
|
||||||
itemId, part.Name, part.UUID);
|
itemId, part.Name, part.UUID);
|
||||||
|
|
||||||
return;
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data);
|
AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data);
|
||||||
|
@ -264,29 +265,33 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
part.GetProperties(remoteClient);
|
part.GetProperties(remoteClient);
|
||||||
|
|
||||||
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
// Trigger rerunning of script (use TriggerRezScript event, see RezScript)
|
||||||
|
ArrayList errors = new ArrayList();
|
||||||
|
|
||||||
if (isScriptRunning)
|
if (isScriptRunning)
|
||||||
{
|
{
|
||||||
// Needs to determine which engine was running it and use that
|
// Needs to determine which engine was running it and use that
|
||||||
//
|
//
|
||||||
part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
|
part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0);
|
||||||
|
errors = part.Inventory.GetScriptErrors(item.ItemID);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
remoteClient.SendAgentAlertMessage("Script saved", false);
|
remoteClient.SendAgentAlertMessage("Script saved", false);
|
||||||
}
|
}
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
|
/// <see>CapsUpdateTaskInventoryScriptAsset(IClientAPI, UUID, UUID, bool, byte[])</see>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
|
public ArrayList CapsUpdateTaskInventoryScriptAsset(UUID avatarId, UUID itemId,
|
||||||
UUID primId, bool isScriptRunning, byte[] data)
|
UUID primId, bool isScriptRunning, byte[] data)
|
||||||
{
|
{
|
||||||
ScenePresence avatar;
|
ScenePresence avatar;
|
||||||
|
|
||||||
if (TryGetAvatar(avatarId, out avatar))
|
if (TryGetAvatar(avatarId, out avatar))
|
||||||
{
|
{
|
||||||
CapsUpdateTaskInventoryScriptAsset(
|
return CapsUpdateTaskInventoryScriptAsset(
|
||||||
avatar.ControllingClient, itemId, primId, isScriptRunning, data);
|
avatar.ControllingClient, itemId, primId, isScriptRunning, data);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -295,6 +300,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
"[PRIM INVENTORY]: " +
|
"[PRIM INVENTORY]: " +
|
||||||
"Avatar {0} cannot be found to update its prim item asset",
|
"Avatar {0} cannot be found to update its prim item asset",
|
||||||
avatarId);
|
avatarId);
|
||||||
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -542,6 +542,18 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
if (group.GetFromItemID() == itemID)
|
if (group.GetFromItemID() == itemID)
|
||||||
{
|
{
|
||||||
m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
|
m_parentScene.SendAttachEvent(group.LocalId, itemID, UUID.Zero);
|
||||||
|
bool hasScripts = false;
|
||||||
|
foreach (SceneObjectPart part in group.Children.Values)
|
||||||
|
{
|
||||||
|
if (part.Inventory.ContainsScripts())
|
||||||
|
{
|
||||||
|
hasScripts = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasScripts) // Allow the object to execute the attach(NULL_KEY) event
|
||||||
|
System.Threading.Thread.Sleep(100);
|
||||||
group.DetachToInventoryPrep();
|
group.DetachToInventoryPrep();
|
||||||
m_log.Debug("[DETACH]: Saving attachpoint: " +
|
m_log.Debug("[DETACH]: Saving attachpoint: " +
|
||||||
((uint)group.GetAttachmentPoint()).ToString());
|
((uint)group.GetAttachmentPoint()).ToString());
|
||||||
|
|
|
@ -1880,6 +1880,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopLookAt()
|
public void stopLookAt()
|
||||||
{
|
{
|
||||||
SceneObjectPart rootpart = m_rootPart;
|
SceneObjectPart rootpart = m_rootPart;
|
||||||
|
|
|
@ -29,6 +29,7 @@ using System;
|
||||||
using System.Xml;
|
using System.Xml;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using OpenMetaverse;
|
using OpenMetaverse;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
@ -210,6 +211,27 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList GetScriptErrors(UUID itemID)
|
||||||
|
{
|
||||||
|
ArrayList ret = new ArrayList();
|
||||||
|
|
||||||
|
IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
|
||||||
|
if (engines == null) // No engine at all
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
foreach (IScriptModule e in engines)
|
||||||
|
{
|
||||||
|
if (e != null)
|
||||||
|
{
|
||||||
|
ArrayList errors = e.GetScriptErrors(itemID);
|
||||||
|
foreach (Object line in errors)
|
||||||
|
ret.Add(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stop all the scripts in this prim.
|
/// Stop all the scripts in this prim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -345,6 +367,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_part.ParentGroup.m_savedScriptState.Remove(oldID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,26 +258,50 @@ namespace OpenSim.Region.OptionalModules.Scripting.Minimodule
|
||||||
|
|
||||||
public Vector3 SitTarget
|
public Vector3 SitTarget
|
||||||
{
|
{
|
||||||
get { throw new System.NotImplementedException(); }
|
get { return GetSOP().SitTargetPosition; }
|
||||||
set { throw new System.NotImplementedException(); }
|
set
|
||||||
|
{
|
||||||
|
if (CanEdit())
|
||||||
|
{
|
||||||
|
GetSOP().SitTargetPosition = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string SitTargetText
|
public string SitTargetText
|
||||||
{
|
{
|
||||||
get { throw new System.NotImplementedException(); }
|
get { return GetSOP().SitName; }
|
||||||
set { throw new System.NotImplementedException(); }
|
set
|
||||||
|
{
|
||||||
|
if (CanEdit())
|
||||||
|
{
|
||||||
|
GetSOP().SitName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string TouchText
|
public string TouchText
|
||||||
{
|
{
|
||||||
get { throw new System.NotImplementedException(); }
|
get { return GetSOP().TouchName; }
|
||||||
set { throw new System.NotImplementedException(); }
|
set
|
||||||
|
{
|
||||||
|
if (CanEdit())
|
||||||
|
{
|
||||||
|
GetSOP().TouchName = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
get { throw new System.NotImplementedException(); }
|
get { return GetSOP().Text; }
|
||||||
set { throw new System.NotImplementedException(); }
|
set
|
||||||
|
{
|
||||||
|
if (CanEdit())
|
||||||
|
{
|
||||||
|
GetSOP().SetText(value,new Vector3(1.0f,1.0f,1.0f),1.0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsRotationLockedX
|
public bool IsRotationLockedX
|
||||||
|
|
|
@ -620,11 +620,25 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
||||||
set { return; }
|
set { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Quaternion APIDTarget { set { return; } }
|
public override Quaternion APIDTarget
|
||||||
public override bool APIDActive { set { return; } }
|
{
|
||||||
public override float APIDStrength { set { return; } }
|
set { return; }
|
||||||
public override float APIDDamping { set { return; } }
|
}
|
||||||
|
|
||||||
|
public override bool APIDActive
|
||||||
|
{
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float APIDStrength
|
||||||
|
{
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override float APIDDamping
|
||||||
|
{
|
||||||
|
set { return; }
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adds the force supplied to the Target Velocity
|
/// Adds the force supplied to the Target Velocity
|
||||||
|
|
|
@ -570,7 +570,6 @@ namespace OpenSim.Region.Physics.BulletDotNETPlugin
|
||||||
public override float APIDStrength { set { return; } }
|
public override float APIDStrength { set { return; } }
|
||||||
public override float APIDDamping { set { return; } }
|
public override float APIDDamping { set { return; } }
|
||||||
|
|
||||||
|
|
||||||
public override void AddForce(Vector3 force, bool pushforce)
|
public override void AddForce(Vector3 force, bool pushforce)
|
||||||
{
|
{
|
||||||
m_forcelist.Add(force);
|
m_forcelist.Add(force);
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
/*
|
||||||
|
* 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.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// Information about this assembly is defined by the following
|
||||||
|
// attributes.
|
||||||
|
//
|
||||||
|
// change them to the information which is associated with the assembly
|
||||||
|
// you compile.
|
||||||
|
|
||||||
|
[assembly : AssemblyTitle("OdePlugin")]
|
||||||
|
[assembly : AssemblyDescription("")]
|
||||||
|
[assembly : AssemblyConfiguration("")]
|
||||||
|
[assembly : AssemblyCompany("http://opensimulator.org")]
|
||||||
|
[assembly : AssemblyProduct("OdePlugin")]
|
||||||
|
[assembly : AssemblyCopyright("Copyright (c) OpenSimulator.org Developers 2007-2009")]
|
||||||
|
[assembly : AssemblyTrademark("")]
|
||||||
|
[assembly : AssemblyCulture("")]
|
||||||
|
|
||||||
|
// This sets the default COM visibility of types in the assembly to invisible.
|
||||||
|
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
|
||||||
|
|
||||||
|
[assembly : ComVisible(false)]
|
||||||
|
|
||||||
|
// The assembly version has following format :
|
||||||
|
//
|
||||||
|
// Major.Minor.Build.Revision
|
||||||
|
//
|
||||||
|
// You can specify all values by your own or you can build default build and revision
|
||||||
|
// numbers with the '*' character (the default):
|
||||||
|
|
||||||
|
[assembly : AssemblyVersion("0.6.5.*")]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,630 @@
|
||||||
|
/*
|
||||||
|
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*
|
||||||
|
* 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.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
public class ODEDynamics
|
||||||
|
{
|
||||||
|
public Vehicle Type
|
||||||
|
{
|
||||||
|
get { return m_type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Body
|
||||||
|
{
|
||||||
|
get { return m_body; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int frcount = 0; // Used to limit dynamics debug output to
|
||||||
|
// every 100th frame
|
||||||
|
|
||||||
|
// private OdeScene m_parentScene = null;
|
||||||
|
private IntPtr m_body = IntPtr.Zero;
|
||||||
|
private IntPtr m_jointGroup = IntPtr.Zero;
|
||||||
|
private IntPtr m_aMotor = IntPtr.Zero;
|
||||||
|
|
||||||
|
|
||||||
|
// Vehicle properties
|
||||||
|
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||||
|
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||||
|
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||||
|
// HOVER_TERRAIN_ONLY
|
||||||
|
// HOVER_GLOBAL_HEIGHT
|
||||||
|
// NO_DEFLECTION_UP
|
||||||
|
// HOVER_WATER_ONLY
|
||||||
|
// HOVER_UP_ONLY
|
||||||
|
// LIMIT_MOTOR_UP
|
||||||
|
// LIMIT_ROLL_ONLY
|
||||||
|
|
||||||
|
// 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_linearFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_linearMotorDecayTimescale = 0;
|
||||||
|
private float m_linearMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
// private bool m_LinearMotorSetLastFrame = false;
|
||||||
|
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||||
|
|
||||||
|
//Angular properties
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero;
|
||||||
|
private Vector3 m_angularMotorDirectionLASTSET = Vector3.Zero;
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_angularMotorDecayTimescale = 0;
|
||||||
|
private float m_angularMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastAngularVelocityVector = Vector3.Zero;
|
||||||
|
|
||||||
|
//Deflection properties
|
||||||
|
// private float m_angularDeflectionEfficiency = 0;
|
||||||
|
// private float m_angularDeflectionTimescale = 0;
|
||||||
|
// private float m_linearDeflectionEfficiency = 0;
|
||||||
|
// private float m_linearDeflectionTimescale = 0;
|
||||||
|
|
||||||
|
//Banking properties
|
||||||
|
// private float m_bankingEfficiency = 0;
|
||||||
|
// private float m_bankingMix = 0;
|
||||||
|
// private float m_bankingTimescale = 0;
|
||||||
|
|
||||||
|
//Hover and Buoyancy properties
|
||||||
|
private float m_VhoverHeight = 0f;
|
||||||
|
private float m_VhoverEfficiency = 0f;
|
||||||
|
private float m_VhoverTimescale = 0f;
|
||||||
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
|
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||||
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
|
||||||
|
//Attractor properties
|
||||||
|
private float m_verticalAttractionEfficiency = 0;
|
||||||
|
private float m_verticalAttractionTimescale = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_MIX:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingMix = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BUOYANCY:
|
||||||
|
if (pValue < -1f) pValue = -1f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VehicleBuoyancy = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_EFFICIENCY:
|
||||||
|
if (pValue < 0f) pValue = 0f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VhoverEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_HEIGHT:
|
||||||
|
m_VhoverHeight = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_VhoverTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.0f) pValue = 0.0f;
|
||||||
|
if (pValue > 1.0f) pValue = 1.0f;
|
||||||
|
m_verticalAttractionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_verticalAttractionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These are vector properties but the engine lets you use a single float value to
|
||||||
|
// set all of the components to the same value
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_angularMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessFloatVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessVectorVehicleParam(Vehicle pParam, PhysicsVector pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_angularMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessVectorVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.REFERENCE_FRAME:
|
||||||
|
// m_referenceFrame = pValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessRotationVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessTypeChange(Vehicle pType)
|
||||||
|
{
|
||||||
|
Console.WriteLine("ProcessTypeChange to " + pType);
|
||||||
|
|
||||||
|
// Set Defaults For Type
|
||||||
|
m_type = pType;
|
||||||
|
switch (pType)
|
||||||
|
{
|
||||||
|
case Vehicle.TYPE_SLED:
|
||||||
|
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1000;
|
||||||
|
m_linearMotorDecayTimescale = 120;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1000;
|
||||||
|
m_angularMotorDecayTimescale = 120;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 1;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 1;
|
||||||
|
// m_linearDeflectionTimescale = 1;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 10;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &=
|
||||||
|
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_CAR:
|
||||||
|
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1;
|
||||||
|
m_angularMotorDecayTimescale = 0.8f;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// // m_linearDeflectionEfficiency = 1;
|
||||||
|
// // m_linearDeflectionTimescale = 2;
|
||||||
|
// // m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 10;
|
||||||
|
m_verticalAttractionEfficiency = 1;
|
||||||
|
m_verticalAttractionTimescale = 10;
|
||||||
|
// m_bankingEfficiency = -0.2f;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BOAT:
|
||||||
|
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 2;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 0.5f;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 0.5f;
|
||||||
|
m_verticalAttractionTimescale = 5;
|
||||||
|
// m_bankingEfficiency = -0.3f;
|
||||||
|
// m_bankingMix = 0.8f;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_AIRPLANE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 2;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 2;
|
||||||
|
m_verticalAttractionEfficiency = 0.9f;
|
||||||
|
m_verticalAttractionTimescale = 2;
|
||||||
|
// m_bankingEfficiency = 1;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 2;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BALLOON:
|
||||||
|
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 6;
|
||||||
|
m_angularMotorDecayTimescale = 10;
|
||||||
|
m_VhoverHeight = 5;
|
||||||
|
m_VhoverEfficiency = 0.8f;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0;
|
||||||
|
// m_linearDeflectionTimescale = 5;
|
||||||
|
// m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 1;
|
||||||
|
m_verticalAttractionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 5;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}//end SetDefaultsForType
|
||||||
|
|
||||||
|
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
//Console.WriteLine("Enable m_type=" + m_type + " m_VehicleBuoyancy=" + m_VehicleBuoyancy);
|
||||||
|
if (m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_body = pBody;
|
||||||
|
//KF: This used to set up the linear and angular joints
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
frcount++; // used to limit debug comment output
|
||||||
|
if (frcount > 100)
|
||||||
|
frcount = 0;
|
||||||
|
|
||||||
|
MoveLinear(pTimestep, pParentScene);
|
||||||
|
MoveAngular(pTimestep);
|
||||||
|
}// end Step
|
||||||
|
|
||||||
|
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||||
|
{
|
||||||
|
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
|
||||||
|
// add drive to body
|
||||||
|
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||||
|
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||||
|
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
// KF: Limit body velocity to applied velocity?
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||||
|
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||||
|
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||||
|
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)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_linearMotorDirection -= m_linearMotorDirection * decayfraction;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // requested is not significant
|
||||||
|
// if what remains of applied is small, zero it.
|
||||||
|
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convert requested object velocity to world-referenced vector
|
||||||
|
m_dir = m_lastLinearVelocityVector;
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
|
// add Gravity andBuoyancy
|
||||||
|
// 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;
|
||||||
|
if(m_VehicleBuoyancy < 1.0f)
|
||||||
|
{
|
||||||
|
// There is some gravity, make a gravity force vector
|
||||||
|
// that is applied after object velocity.
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
|
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||||
|
// Preserve the current Z velocity
|
||||||
|
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||||
|
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||||
|
} // else its 1.0, no gravity.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||||
|
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = m_VhoverHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||||
|
{
|
||||||
|
// If body is aready heigher, use its height as target height
|
||||||
|
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||||
|
// m_VhoverTimescale = 0f; // time to acheive height
|
||||||
|
// pTimestep is time since last frame,in secs
|
||||||
|
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||||
|
//if(frcount == 0) Console.WriteLine("herr0=" + herr0);
|
||||||
|
// Replace Vertical speed with correction figure if significant
|
||||||
|
if(Math.Abs(herr0) > 0.01f )
|
||||||
|
{
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||||
|
// m_VhoverEfficiency is not yet implemented
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_dir.Z = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply velocity
|
||||||
|
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||||
|
//if(frcount == 0) Console.WriteLine("Move " + Body + ":"+ m_dir.X + " " + m_dir.Y + " " + m_dir.Z);
|
||||||
|
// apply gravity force
|
||||||
|
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||||
|
//if(frcount == 0) Console.WriteLine("Force " + Body + ":" + grav.X + " " + grav.Y + " " + grav.Z);
|
||||||
|
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||||
|
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||||
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
private void MoveAngular(float pTimestep)
|
||||||
|
{
|
||||||
|
|
||||||
|
// m_angularMotorDirection is the latest value from the script, and is decayed here
|
||||||
|
// m_angularMotorDirectionLASTSET is the latest value from the script
|
||||||
|
// m_lastAngularVelocityVector is what is being applied to the Body, varied up and down here
|
||||||
|
|
||||||
|
if (!m_angularMotorDirection.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
// ramp up to new value
|
||||||
|
Vector3 addAmount = m_angularMotorDirection / (m_angularMotorTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocityVector += (addAmount * 10f);
|
||||||
|
//if(frcount == 0) Console.WriteLine("add: " + addAmount);
|
||||||
|
|
||||||
|
// limit applied value to what was set by script
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.X) > Math.Abs(m_angularMotorDirectionLASTSET.X))
|
||||||
|
m_lastAngularVelocityVector.X = m_angularMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.Y) > Math.Abs(m_angularMotorDirectionLASTSET.Y))
|
||||||
|
m_lastAngularVelocityVector.Y = m_angularMotorDirectionLASTSET.Y;
|
||||||
|
if (Math.Abs(m_lastAngularVelocityVector.Z) > Math.Abs(m_angularMotorDirectionLASTSET.Z))
|
||||||
|
m_lastAngularVelocityVector.Z = m_angularMotorDirectionLASTSET.Z;
|
||||||
|
|
||||||
|
// decay the requested value
|
||||||
|
Vector3 decayfraction = ((Vector3.One / (m_angularMotorDecayTimescale / pTimestep)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_angularMotorDirection -= m_angularMotorDirection * decayfraction;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
// KF: m_lastAngularVelocityVector is rotational speed in rad/sec ?
|
||||||
|
|
||||||
|
// Vertical attractor section
|
||||||
|
|
||||||
|
// d.Mass objMass;
|
||||||
|
// d.BodyGetMass(Body, out objMass);
|
||||||
|
// float servo = 100f * objMass.mass * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
float servo = 0.1f * m_verticalAttractionEfficiency / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
// get present body rotation
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
|
// make a vector pointing up
|
||||||
|
Vector3 verterr = Vector3.Zero;
|
||||||
|
verterr.Z = 1.0f;
|
||||||
|
// rotate it to Body Angle
|
||||||
|
verterr = verterr * rotq;
|
||||||
|
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||||
|
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||||
|
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||||
|
if (verterr.Z < 0.0f)
|
||||||
|
{
|
||||||
|
verterr.X = 2.0f - verterr.X;
|
||||||
|
verterr.Y = 2.0f - verterr.Y;
|
||||||
|
}
|
||||||
|
// Error is 0 (no error) to +/- 2 (max error)
|
||||||
|
// scale it by servo
|
||||||
|
verterr = verterr * servo;
|
||||||
|
|
||||||
|
// rotate to object frame
|
||||||
|
// verterr = verterr * rotq;
|
||||||
|
|
||||||
|
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||||
|
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||||
|
m_lastAngularVelocityVector.X += verterr.Y;
|
||||||
|
m_lastAngularVelocityVector.Y -= verterr.X;
|
||||||
|
/*
|
||||||
|
if(frcount == 0)
|
||||||
|
{
|
||||||
|
// Console.WriteLine("AngleMotor " + m_lastAngularVelocityVector);
|
||||||
|
Console.WriteLine(String.Format("VA Body:{0} servo:{1} err:<{2},{3},{4}> VAE:{5}",
|
||||||
|
Body, servo, verterr.X, verterr.Y, verterr.Z, m_verticalAttractionEfficiency));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
d.BodySetAngularVel (Body, m_lastAngularVelocityVector.X, m_lastAngularVelocityVector.Y, m_lastAngularVelocityVector.Z);
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocityVector -= m_lastAngularVelocityVector * decayamount;
|
||||||
|
|
||||||
|
} //end MoveAngular
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,673 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
||||||
|
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
||||||
|
* characteristics and Kinetic motion.
|
||||||
|
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
||||||
|
* (dynamics) and the associated settings. Old Linear and angular
|
||||||
|
* motors for dynamic motion have been replace with MoveLinear()
|
||||||
|
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
||||||
|
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
||||||
|
* switch between 'VEHICLE' parameter use and general dynamics
|
||||||
|
* settings use.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using log4net;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
public class ODEDynamics
|
||||||
|
{
|
||||||
|
public Vehicle Type
|
||||||
|
{
|
||||||
|
get { return m_type; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntPtr Body
|
||||||
|
{
|
||||||
|
get { return m_body; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private int frcount = 0; // Used to limit dynamics debug output to
|
||||||
|
// every 100th frame
|
||||||
|
|
||||||
|
// private OdeScene m_parentScene = null;
|
||||||
|
private IntPtr m_body = IntPtr.Zero;
|
||||||
|
// private IntPtr m_jointGroup = IntPtr.Zero;
|
||||||
|
// private IntPtr m_aMotor = IntPtr.Zero;
|
||||||
|
|
||||||
|
|
||||||
|
// Vehicle properties
|
||||||
|
private Vehicle m_type = Vehicle.TYPE_NONE; // If a 'VEHICLE', and what kind
|
||||||
|
// private Quaternion m_referenceFrame = Quaternion.Identity; // Axis modifier
|
||||||
|
private VehicleFlag m_flags = (VehicleFlag) 0; // Boolean settings:
|
||||||
|
// HOVER_TERRAIN_ONLY
|
||||||
|
// HOVER_GLOBAL_HEIGHT
|
||||||
|
// NO_DEFLECTION_UP
|
||||||
|
// HOVER_WATER_ONLY
|
||||||
|
// HOVER_UP_ONLY
|
||||||
|
// LIMIT_MOTOR_UP
|
||||||
|
// LIMIT_ROLL_ONLY
|
||||||
|
|
||||||
|
// 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_linearFrictionTimescale = Vector3.Zero;
|
||||||
|
private float m_linearMotorDecayTimescale = 0;
|
||||||
|
private float m_linearMotorTimescale = 0;
|
||||||
|
private Vector3 m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
// private bool m_LinearMotorSetLastFrame = false;
|
||||||
|
// private Vector3 m_linearMotorOffset = Vector3.Zero;
|
||||||
|
|
||||||
|
//Angular properties
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||||
|
private int m_angularMotorApply = 0; // application frame counter
|
||||||
|
private Vector3 m_angularMotorVelocity = Vector3.Zero; // current angular motor velocity
|
||||||
|
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||||
|
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
|
// private Vector3 m_lastVertAttractor = Vector3.Zero; // what VA was last applied to body
|
||||||
|
|
||||||
|
//Deflection properties
|
||||||
|
// private float m_angularDeflectionEfficiency = 0;
|
||||||
|
// private float m_angularDeflectionTimescale = 0;
|
||||||
|
// private float m_linearDeflectionEfficiency = 0;
|
||||||
|
// private float m_linearDeflectionTimescale = 0;
|
||||||
|
|
||||||
|
//Banking properties
|
||||||
|
// private float m_bankingEfficiency = 0;
|
||||||
|
// private float m_bankingMix = 0;
|
||||||
|
// private float m_bankingTimescale = 0;
|
||||||
|
|
||||||
|
//Hover and Buoyancy properties
|
||||||
|
private float m_VhoverHeight = 0f;
|
||||||
|
// private float m_VhoverEfficiency = 0f;
|
||||||
|
private float m_VhoverTimescale = 0f;
|
||||||
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
|
private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
|
||||||
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
|
||||||
|
//Attractor properties
|
||||||
|
private float m_verticalAttractionEfficiency = 1.0f; // damped
|
||||||
|
private float m_verticalAttractionTimescale = 500f; // Timescale > 300 means no vert attractor.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
internal void ProcessFloatVehicleParam(Vehicle pParam, float pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_angularDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_angularMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_MIX:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingMix = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BANKING_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_bankingTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.BUOYANCY:
|
||||||
|
if (pValue < -1f) pValue = -1f;
|
||||||
|
if (pValue > 1f) pValue = 1f;
|
||||||
|
m_VehicleBuoyancy = pValue;
|
||||||
|
break;
|
||||||
|
// case Vehicle.HOVER_EFFICIENCY:
|
||||||
|
// if (pValue < 0f) pValue = 0f;
|
||||||
|
// if (pValue > 1f) pValue = 1f;
|
||||||
|
// m_VhoverEfficiency = pValue;
|
||||||
|
// break;
|
||||||
|
case Vehicle.HOVER_HEIGHT:
|
||||||
|
m_VhoverHeight = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.HOVER_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_VhoverTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_DEFLECTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
// m_linearDeflectionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DECAY_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorDecayTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_linearMotorTimescale = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_EFFICIENCY:
|
||||||
|
if (pValue < 0.1f) pValue = 0.1f; // Less goes unstable
|
||||||
|
if (pValue > 1.0f) pValue = 1.0f;
|
||||||
|
m_verticalAttractionEfficiency = pValue;
|
||||||
|
break;
|
||||||
|
case Vehicle.VERTICAL_ATTRACTION_TIMESCALE:
|
||||||
|
if (pValue < 0.01f) pValue = 0.01f;
|
||||||
|
m_verticalAttractionTimescale = pValue;
|
||||||
|
break;
|
||||||
|
|
||||||
|
// These are vector properties but the engine lets you use a single float value to
|
||||||
|
// set all of the components to the same value
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_angularMotorApply = 10;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue, pValue, pValue);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue, pValue, pValue);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessFloatVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessVectorVehicleParam(Vehicle pParam, Vector3 pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.ANGULAR_FRICTION_TIMESCALE:
|
||||||
|
m_angularFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.ANGULAR_MOTOR_DIRECTION:
|
||||||
|
m_angularMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
// Limit requested angular speed to 2 rps= 4 pi rads/sec
|
||||||
|
if(m_angularMotorDirection.X > 12.56f) m_angularMotorDirection.X = 12.56f;
|
||||||
|
if(m_angularMotorDirection.X < - 12.56f) m_angularMotorDirection.X = - 12.56f;
|
||||||
|
if(m_angularMotorDirection.Y > 12.56f) m_angularMotorDirection.Y = 12.56f;
|
||||||
|
if(m_angularMotorDirection.Y < - 12.56f) m_angularMotorDirection.Y = - 12.56f;
|
||||||
|
if(m_angularMotorDirection.Z > 12.56f) m_angularMotorDirection.Z = 12.56f;
|
||||||
|
if(m_angularMotorDirection.Z < - 12.56f) m_angularMotorDirection.Z = - 12.56f;
|
||||||
|
m_angularMotorApply = 10;
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_FRICTION_TIMESCALE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_DIRECTION:
|
||||||
|
m_linearMotorDirection = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
m_linearMotorDirectionLASTSET = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
case Vehicle.LINEAR_MOTOR_OFFSET:
|
||||||
|
// m_linearMotorOffset = new Vector3(pValue.X, pValue.Y, pValue.Z);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessVectorVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessRotationVehicleParam(Vehicle pParam, Quaternion pValue)
|
||||||
|
{
|
||||||
|
switch (pParam)
|
||||||
|
{
|
||||||
|
case Vehicle.REFERENCE_FRAME:
|
||||||
|
// m_referenceFrame = pValue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}//end ProcessRotationVehicleParam
|
||||||
|
|
||||||
|
internal void ProcessTypeChange(Vehicle pType)
|
||||||
|
{
|
||||||
|
// Set Defaults For Type
|
||||||
|
m_type = pType;
|
||||||
|
switch (pType)
|
||||||
|
{
|
||||||
|
case Vehicle.TYPE_SLED:
|
||||||
|
m_linearFrictionTimescale = new Vector3(30, 1, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1000;
|
||||||
|
m_linearMotorDecayTimescale = 120;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1000;
|
||||||
|
m_angularMotorDecayTimescale = 120;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 1;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 1;
|
||||||
|
// m_linearDeflectionTimescale = 1;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 1000;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 10;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &=
|
||||||
|
~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_CAR:
|
||||||
|
m_linearFrictionTimescale = new Vector3(100, 2, 1000);
|
||||||
|
m_angularFrictionTimescale = new Vector3(1000, 1000, 1000);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 1;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 1;
|
||||||
|
m_angularMotorDecayTimescale = 0.8f;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// // m_linearDeflectionEfficiency = 1;
|
||||||
|
// // m_linearDeflectionTimescale = 2;
|
||||||
|
// // m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 10;
|
||||||
|
m_verticalAttractionEfficiency = 1f;
|
||||||
|
m_verticalAttractionTimescale = 10f;
|
||||||
|
// m_bankingEfficiency = -0.2f;
|
||||||
|
// m_bankingMix = 1;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_UP_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BOAT:
|
||||||
|
m_linearFrictionTimescale = new Vector3(10, 3, 2);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10,10,10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 2;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 0.5f;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 0.5f;
|
||||||
|
m_verticalAttractionTimescale = 5f;
|
||||||
|
// m_bankingEfficiency = -0.3f;
|
||||||
|
// m_bankingMix = 0.8f;
|
||||||
|
// m_bankingTimescale = 1;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.HOVER_TERRAIN_ONLY | VehicleFlag.LIMIT_ROLL_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY);
|
||||||
|
m_flags |= (VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY |
|
||||||
|
VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_AIRPLANE:
|
||||||
|
m_linearFrictionTimescale = new Vector3(200, 10, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(20, 20, 20);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 2;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 4;
|
||||||
|
m_angularMotorDecayTimescale = 4;
|
||||||
|
m_VhoverHeight = 0;
|
||||||
|
// m_VhoverEfficiency = 0.5f;
|
||||||
|
m_VhoverTimescale = 1000;
|
||||||
|
m_VehicleBuoyancy = 0;
|
||||||
|
// m_linearDeflectionEfficiency = 0.5f;
|
||||||
|
// m_linearDeflectionTimescale = 3;
|
||||||
|
// m_angularDeflectionEfficiency = 1;
|
||||||
|
// m_angularDeflectionTimescale = 2;
|
||||||
|
m_verticalAttractionEfficiency = 0.9f;
|
||||||
|
m_verticalAttractionTimescale = 2f;
|
||||||
|
// m_bankingEfficiency = 1;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 2;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_GLOBAL_HEIGHT | VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY);
|
||||||
|
break;
|
||||||
|
case Vehicle.TYPE_BALLOON:
|
||||||
|
m_linearFrictionTimescale = new Vector3(5, 5, 5);
|
||||||
|
m_angularFrictionTimescale = new Vector3(10, 10, 10);
|
||||||
|
m_linearMotorDirection = Vector3.Zero;
|
||||||
|
m_linearMotorTimescale = 5;
|
||||||
|
m_linearMotorDecayTimescale = 60;
|
||||||
|
m_angularMotorDirection = Vector3.Zero;
|
||||||
|
m_angularMotorTimescale = 6;
|
||||||
|
m_angularMotorDecayTimescale = 10;
|
||||||
|
m_VhoverHeight = 5;
|
||||||
|
// m_VhoverEfficiency = 0.8f;
|
||||||
|
m_VhoverTimescale = 10;
|
||||||
|
m_VehicleBuoyancy = 1;
|
||||||
|
// m_linearDeflectionEfficiency = 0;
|
||||||
|
// m_linearDeflectionTimescale = 5;
|
||||||
|
// m_angularDeflectionEfficiency = 0;
|
||||||
|
// m_angularDeflectionTimescale = 5;
|
||||||
|
m_verticalAttractionEfficiency = 1f;
|
||||||
|
m_verticalAttractionTimescale = 100f;
|
||||||
|
// m_bankingEfficiency = 0;
|
||||||
|
// m_bankingMix = 0.7f;
|
||||||
|
// m_bankingTimescale = 5;
|
||||||
|
// m_referenceFrame = Quaternion.Identity;
|
||||||
|
m_flags &= ~(VehicleFlag.NO_DEFLECTION_UP | VehicleFlag.HOVER_WATER_ONLY | VehicleFlag.HOVER_TERRAIN_ONLY |
|
||||||
|
VehicleFlag.HOVER_UP_ONLY | VehicleFlag.LIMIT_MOTOR_UP);
|
||||||
|
m_flags |= (VehicleFlag.LIMIT_ROLL_ONLY | VehicleFlag.HOVER_GLOBAL_HEIGHT);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}//end SetDefaultsForType
|
||||||
|
|
||||||
|
internal void Enable(IntPtr pBody, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_body = pBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void Step(float pTimestep, OdeScene pParentScene)
|
||||||
|
{
|
||||||
|
if (m_body == IntPtr.Zero || m_type == Vehicle.TYPE_NONE)
|
||||||
|
return;
|
||||||
|
frcount++; // used to limit debug comment output
|
||||||
|
if (frcount > 100)
|
||||||
|
frcount = 0;
|
||||||
|
|
||||||
|
MoveLinear(pTimestep, pParentScene);
|
||||||
|
MoveAngular(pTimestep);
|
||||||
|
}// end Step
|
||||||
|
|
||||||
|
private void MoveLinear(float pTimestep, OdeScene _pParentScene)
|
||||||
|
{
|
||||||
|
if (!m_linearMotorDirection.ApproxEquals(Vector3.Zero, 0.01f)) // requested m_linearMotorDirection is significant
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
|
||||||
|
// add drive to body
|
||||||
|
Vector3 addAmount = m_linearMotorDirection/(m_linearMotorTimescale/pTimestep);
|
||||||
|
m_lastLinearVelocityVector += (addAmount*10); // lastLinearVelocityVector is the current body velocity vector?
|
||||||
|
|
||||||
|
// This will work temporarily, but we really need to compare speed on an axis
|
||||||
|
// KF: Limit body velocity to applied velocity?
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.X) > Math.Abs(m_linearMotorDirectionLASTSET.X))
|
||||||
|
m_lastLinearVelocityVector.X = m_linearMotorDirectionLASTSET.X;
|
||||||
|
if (Math.Abs(m_lastLinearVelocityVector.Y) > Math.Abs(m_linearMotorDirectionLASTSET.Y))
|
||||||
|
m_lastLinearVelocityVector.Y = m_linearMotorDirectionLASTSET.Y;
|
||||||
|
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)));
|
||||||
|
//Console.WriteLine("decay: " + decayfraction);
|
||||||
|
m_linearMotorDirection -= m_linearMotorDirection * decayfraction * 0.5f;
|
||||||
|
//Console.WriteLine("actual: " + m_linearMotorDirection);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // requested is not significant
|
||||||
|
// if what remains of applied is small, zero it.
|
||||||
|
if (m_lastLinearVelocityVector.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
m_lastLinearVelocityVector = Vector3.Zero;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// convert requested object velocity to world-referenced vector
|
||||||
|
m_dir = m_lastLinearVelocityVector;
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
if(m_VehicleBuoyancy < 1.0f)
|
||||||
|
{
|
||||||
|
// There is some gravity, make a gravity force vector
|
||||||
|
// that is applied after object velocity.
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
// m_VehicleBuoyancy: -1=2g; 0=1g; 1=0g;
|
||||||
|
grav.Z = _pParentScene.gravityz * objMass.mass * (1f - m_VehicleBuoyancy);
|
||||||
|
// Preserve the current Z velocity
|
||||||
|
d.Vector3 vel_now = d.BodyGetLinearVel(Body);
|
||||||
|
m_dir.Z = vel_now.Z; // Preserve the accumulated falling velocity
|
||||||
|
} // else its 1.0, no gravity.
|
||||||
|
|
||||||
|
// 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
|
||||||
|
d.Vector3 pos = d.BodyGetPosition(Body);
|
||||||
|
if((m_flags & VehicleFlag.HOVER_WATER_ONLY) == VehicleFlag.HOVER_WATER_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetWaterLevel() + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) == VehicleFlag.HOVER_TERRAIN_ONLY)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight;
|
||||||
|
}
|
||||||
|
else if((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) == VehicleFlag.HOVER_GLOBAL_HEIGHT)
|
||||||
|
{
|
||||||
|
m_VhoverTargetHeight = m_VhoverHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((m_flags & VehicleFlag.HOVER_UP_ONLY) == VehicleFlag.HOVER_UP_ONLY)
|
||||||
|
{
|
||||||
|
// If body is aready heigher, use its height as target height
|
||||||
|
if(pos.Z > m_VhoverTargetHeight) m_VhoverTargetHeight = pos.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// m_VhoverEfficiency = 0f; // 0=boucy, 1=Crit.damped
|
||||||
|
// m_VhoverTimescale = 0f; // time to acheive height
|
||||||
|
// pTimestep is time since last frame,in secs
|
||||||
|
float herr0 = pos.Z - m_VhoverTargetHeight;
|
||||||
|
// Replace Vertical speed with correction figure if significant
|
||||||
|
if(Math.Abs(herr0) > 0.01f )
|
||||||
|
{
|
||||||
|
d.Mass objMass;
|
||||||
|
d.BodyGetMass(Body, out objMass);
|
||||||
|
m_dir.Z = - ( (herr0 * pTimestep * 50.0f) / m_VhoverTimescale);
|
||||||
|
//KF: m_VhoverEfficiency is not yet implemented
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_dir.Z = 0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply velocity
|
||||||
|
d.BodySetLinearVel(Body, m_dir.X, m_dir.Y, m_dir.Z);
|
||||||
|
// apply gravity force
|
||||||
|
d.BodyAddForce(Body, grav.X, grav.Y, grav.Z);
|
||||||
|
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_linearFrictionTimescale / pTimestep);
|
||||||
|
m_lastLinearVelocityVector -= m_lastLinearVelocityVector * decayamount;
|
||||||
|
} // end MoveLinear()
|
||||||
|
|
||||||
|
private void MoveAngular(float pTimestep)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
private Vector3 m_angularMotorDirection = Vector3.Zero; // angular velocity requested by LSL motor
|
||||||
|
private int m_angularMotorApply = 0; // application frame counter
|
||||||
|
private float m_angularMotorVelocity = 0; // current angular motor velocity (ramps up and down)
|
||||||
|
private float m_angularMotorTimescale = 0; // motor angular velocity ramp up rate
|
||||||
|
private float m_angularMotorDecayTimescale = 0; // motor angular velocity decay rate
|
||||||
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
|
*/
|
||||||
|
//if(frcount == 0) Console.WriteLine("MoveAngular ");
|
||||||
|
|
||||||
|
// Get what the body is doing, this includes 'external' influences
|
||||||
|
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
||||||
|
// Vector3 angularVelocity = Vector3.Zero;
|
||||||
|
|
||||||
|
if (m_angularMotorApply > 0)
|
||||||
|
{
|
||||||
|
// ramp up to new value
|
||||||
|
// 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);
|
||||||
|
|
||||||
|
m_angularMotorApply--; // This is done so that if script request rate is less than phys frame rate the expected
|
||||||
|
// velocity may still be acheived.
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no motor recently applied, keep the body velocity
|
||||||
|
/* m_angularMotorVelocity.X = angularVelocity.X;
|
||||||
|
m_angularMotorVelocity.Y = angularVelocity.Y;
|
||||||
|
m_angularMotorVelocity.Z = angularVelocity.Z; */
|
||||||
|
|
||||||
|
// and decay the velocity
|
||||||
|
m_angularMotorVelocity -= m_angularMotorVelocity / (m_angularMotorDecayTimescale / pTimestep);
|
||||||
|
} // end motor section
|
||||||
|
|
||||||
|
|
||||||
|
// Vertical attractor section
|
||||||
|
Vector3 vertattr = Vector3.Zero;
|
||||||
|
|
||||||
|
if(m_verticalAttractionTimescale < 300)
|
||||||
|
{
|
||||||
|
float VAservo = 0.2f / (m_verticalAttractionTimescale * pTimestep);
|
||||||
|
// get present body rotation
|
||||||
|
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
||||||
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
||||||
|
// make a vector pointing up
|
||||||
|
Vector3 verterr = Vector3.Zero;
|
||||||
|
verterr.Z = 1.0f;
|
||||||
|
// rotate it to Body Angle
|
||||||
|
verterr = verterr * rotq;
|
||||||
|
// verterr.X and .Y are the World error ammounts. They are 0 when there is no error (Vehicle Body is 'vertical'), and .Z will be 1.
|
||||||
|
// As the body leans to its side |.X| will increase to 1 and .Z fall to 0. As body inverts |.X| will fall and .Z will go
|
||||||
|
// negative. Similar for tilt and |.Y|. .X and .Y must be modulated to prevent a stable inverted body.
|
||||||
|
if (verterr.Z < 0.0f)
|
||||||
|
{
|
||||||
|
verterr.X = 2.0f - verterr.X;
|
||||||
|
verterr.Y = 2.0f - verterr.Y;
|
||||||
|
}
|
||||||
|
// Error is 0 (no error) to +/- 2 (max error)
|
||||||
|
// scale it by VAservo
|
||||||
|
verterr = verterr * VAservo;
|
||||||
|
//if(frcount == 0) Console.WriteLine("VAerr=" + verterr);
|
||||||
|
|
||||||
|
// As the body rotates around the X axis, then verterr.Y increases; Rotated around Y then .X increases, so
|
||||||
|
// Change Body angular velocity X based on Y, and Y based on X. Z is not changed.
|
||||||
|
vertattr.X = verterr.Y;
|
||||||
|
vertattr.Y = - verterr.X;
|
||||||
|
vertattr.Z = 0f;
|
||||||
|
|
||||||
|
// scaling appears better usingsquare-law
|
||||||
|
float bounce = 1.0f - (m_verticalAttractionEfficiency * m_verticalAttractionEfficiency);
|
||||||
|
vertattr.X += bounce * angularVelocity.X;
|
||||||
|
vertattr.Y += bounce * angularVelocity.Y;
|
||||||
|
|
||||||
|
} // else vertical attractor is off
|
||||||
|
|
||||||
|
// m_lastVertAttractor = vertattr;
|
||||||
|
|
||||||
|
// Bank section tba
|
||||||
|
// Deflection section tba
|
||||||
|
|
||||||
|
// Sum velocities
|
||||||
|
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
|
||||||
|
|
||||||
|
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
|
{
|
||||||
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_lastAngularVelocity = Vector3.Zero; // Reduce small value to zero.
|
||||||
|
}
|
||||||
|
|
||||||
|
// apply friction
|
||||||
|
Vector3 decayamount = Vector3.One / (m_angularFrictionTimescale / pTimestep);
|
||||||
|
m_lastAngularVelocity -= m_lastAngularVelocity * decayamount;
|
||||||
|
|
||||||
|
// Apply to the body
|
||||||
|
d.BodySetAngularVel (Body, m_lastAngularVelocity.X, m_lastAngularVelocity.Y, m_lastAngularVelocity.Z);
|
||||||
|
|
||||||
|
} //end MoveAngular
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,375 @@
|
||||||
|
/*
|
||||||
|
* 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.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using Ode.NET;
|
||||||
|
using log4net;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Processes raycast requests as ODE is in a state to be able to do them.
|
||||||
|
/// This ensures that it's thread safe and there will be no conflicts.
|
||||||
|
/// Requests get returned by a different thread then they were requested by.
|
||||||
|
/// </summary>
|
||||||
|
public class ODERayCastRequestManager
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Pending Raycast Requests
|
||||||
|
/// </summary>
|
||||||
|
protected List<ODERayCastRequest> m_PendingRequests = new List<ODERayCastRequest>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Scene that created this object.
|
||||||
|
/// </summary>
|
||||||
|
private OdeScene m_scene;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ODE contact array to be filled by the collision testing
|
||||||
|
/// </summary>
|
||||||
|
d.ContactGeom[] contacts = new d.ContactGeom[5];
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// ODE near callback delegate
|
||||||
|
/// </summary>
|
||||||
|
private d.NearCallback nearCallback;
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
private List<ContactResult> m_contactResults = new List<ContactResult>();
|
||||||
|
|
||||||
|
|
||||||
|
public ODERayCastRequestManager(OdeScene pScene)
|
||||||
|
{
|
||||||
|
m_scene = pScene;
|
||||||
|
nearCallback = near;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Queues a raycast
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="position">Origin of Ray</param>
|
||||||
|
/// <param name="direction">Ray normal</param>
|
||||||
|
/// <param name="length">Ray length</param>
|
||||||
|
/// <param name="retMethod">Return method to send the results</param>
|
||||||
|
public void QueueRequest(Vector3 position, Vector3 direction, float length, RaycastCallback retMethod)
|
||||||
|
{
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
ODERayCastRequest req = new ODERayCastRequest();
|
||||||
|
req.callbackMethod = retMethod;
|
||||||
|
req.length = length;
|
||||||
|
req.Normal = direction;
|
||||||
|
req.Origin = position;
|
||||||
|
|
||||||
|
m_PendingRequests.Add(req);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Process all queued raycast requests
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>Time in MS the raycasts took to process.</returns>
|
||||||
|
public int ProcessQueuedRequests()
|
||||||
|
{
|
||||||
|
int time = System.Environment.TickCount;
|
||||||
|
lock (m_PendingRequests)
|
||||||
|
{
|
||||||
|
if (m_PendingRequests.Count > 0)
|
||||||
|
{
|
||||||
|
ODERayCastRequest[] reqs = m_PendingRequests.ToArray();
|
||||||
|
for (int i = 0; i < reqs.Length; i++)
|
||||||
|
{
|
||||||
|
if (reqs[i].callbackMethod != null) // quick optimization here, don't raycast
|
||||||
|
RayCast(reqs[i]); // if there isn't anyone to send results
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
foreach (ODERayCastRequest req in m_PendingRequests)
|
||||||
|
{
|
||||||
|
if (req.callbackMethod != null) // quick optimization here, don't raycast
|
||||||
|
RayCast(req); // if there isn't anyone to send results to
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
m_PendingRequests.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Clear();
|
||||||
|
|
||||||
|
return System.Environment.TickCount - time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method that actually initiates the raycast
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="req"></param>
|
||||||
|
private void RayCast(ODERayCastRequest req)
|
||||||
|
{
|
||||||
|
// Create the ray
|
||||||
|
IntPtr ray = d.CreateRay(m_scene.space, req.length);
|
||||||
|
d.GeomRaySet(ray, req.Origin.X, req.Origin.Y, req.Origin.Z, req.Normal.X, req.Normal.Y, req.Normal.Z);
|
||||||
|
|
||||||
|
// Collide test
|
||||||
|
d.SpaceCollide2(m_scene.space, ray, IntPtr.Zero, nearCallback);
|
||||||
|
|
||||||
|
// Remove Ray
|
||||||
|
d.GeomDestroy(ray);
|
||||||
|
|
||||||
|
|
||||||
|
// Define default results
|
||||||
|
bool hitYN = false;
|
||||||
|
uint hitConsumerID = 0;
|
||||||
|
float distance = 999999999999f;
|
||||||
|
Vector3 closestcontact = new Vector3(99999f, 99999f, 99999f);
|
||||||
|
Vector3 snormal = Vector3.Zero;
|
||||||
|
|
||||||
|
// Find closest contact and object.
|
||||||
|
lock (m_contactResults)
|
||||||
|
{
|
||||||
|
foreach (ContactResult cResult in m_contactResults)
|
||||||
|
{
|
||||||
|
if (Vector3.Distance(req.Origin, cResult.Pos) < Vector3.Distance(req.Origin, closestcontact))
|
||||||
|
{
|
||||||
|
closestcontact = cResult.Pos;
|
||||||
|
hitConsumerID = cResult.ConsumerID;
|
||||||
|
distance = cResult.Depth;
|
||||||
|
hitYN = true;
|
||||||
|
snormal = cResult.Normal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_contactResults.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return results
|
||||||
|
if (req.callbackMethod != null)
|
||||||
|
req.callbackMethod(hitYN, closestcontact, hitConsumerID, distance, snormal);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is the standard Near. Uses space AABBs to speed up detection.
|
||||||
|
private void near(IntPtr space, IntPtr g1, IntPtr g2)
|
||||||
|
{
|
||||||
|
|
||||||
|
//Don't test against heightfield Geom, or you'll be sorry!
|
||||||
|
|
||||||
|
/*
|
||||||
|
terminate called after throwing an instance of 'std::bad_alloc'
|
||||||
|
what(): std::bad_alloc
|
||||||
|
Stacktrace:
|
||||||
|
|
||||||
|
at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0x00004>
|
||||||
|
at (wrapper managed-to-native) Ode.NET.d.Collide (intptr,intptr,int,Ode.NET.d/ContactGeom[],int) <0xffffffff>
|
||||||
|
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0x00280>
|
||||||
|
at (wrapper native-to-managed) OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.near (intptr,intptr,intptr) <0xfff
|
||||||
|
fffff>
|
||||||
|
at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0x00004>
|
||||||
|
at (wrapper managed-to-native) Ode.NET.d.SpaceCollide2 (intptr,intptr,intptr,Ode.NET.d/NearCallback) <0xffffffff>
|
||||||
|
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.RayCast (OpenSim.Region.Physics.OdePlugin.ODERayCastRequest) <
|
||||||
|
0x00114>
|
||||||
|
at OpenSim.Region.Physics.OdePlugin.ODERayCastRequestManager.ProcessQueuedRequests () <0x000eb>
|
||||||
|
at OpenSim.Region.Physics.OdePlugin.OdeScene.Simulate (single) <0x017e6>
|
||||||
|
at OpenSim.Region.Framework.Scenes.SceneGraph.UpdatePhysics (double) <0x00042>
|
||||||
|
at OpenSim.Region.Framework.Scenes.Scene.Update () <0x0039e>
|
||||||
|
at OpenSim.Region.Framework.Scenes.Scene.Heartbeat (object) <0x00019>
|
||||||
|
at (wrapper runtime-invoke) object.runtime_invoke_void__this___object (object,intptr,intptr,intptr) <0xffffffff>
|
||||||
|
|
||||||
|
Native stacktrace:
|
||||||
|
|
||||||
|
mono [0x80d2a42]
|
||||||
|
[0xb7f5840c]
|
||||||
|
/lib/i686/cmov/libc.so.6(abort+0x188) [0xb7d1a018]
|
||||||
|
/usr/lib/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x158) [0xb45fc988]
|
||||||
|
/usr/lib/libstdc++.so.6 [0xb45fa865]
|
||||||
|
/usr/lib/libstdc++.so.6 [0xb45fa8a2]
|
||||||
|
/usr/lib/libstdc++.so.6 [0xb45fa9da]
|
||||||
|
/usr/lib/libstdc++.so.6(_Znwj+0x83) [0xb45fb033]
|
||||||
|
/usr/lib/libstdc++.so.6(_Znaj+0x1d) [0xb45fb11d]
|
||||||
|
libode.so(_ZN13dxHeightfield23dCollideHeightfieldZoneEiiiiP6dxGeomiiP12dContactGeomi+0xd04) [0xb46678e4]
|
||||||
|
libode.so(_Z19dCollideHeightfieldP6dxGeomS0_iP12dContactGeomi+0x54b) [0xb466832b]
|
||||||
|
libode.so(dCollide+0x102) [0xb46571b2]
|
||||||
|
[0x95cfdec9]
|
||||||
|
[0x8ea07fe1]
|
||||||
|
[0xab260146]
|
||||||
|
libode.so [0xb465a5c4]
|
||||||
|
libode.so(_ZN11dxHashSpace8collide2EPvP6dxGeomPFvS0_S2_S2_E+0x75) [0xb465bcf5]
|
||||||
|
libode.so(dSpaceCollide2+0x177) [0xb465ac67]
|
||||||
|
[0x95cf978e]
|
||||||
|
[0x8ea07945]
|
||||||
|
[0x95cf2bbc]
|
||||||
|
[0xab2787e7]
|
||||||
|
[0xab419fb3]
|
||||||
|
[0xab416657]
|
||||||
|
[0xab415bda]
|
||||||
|
[0xb609b08e]
|
||||||
|
mono(mono_runtime_delegate_invoke+0x34) [0x8192534]
|
||||||
|
mono [0x81a2f0f]
|
||||||
|
mono [0x81d28b6]
|
||||||
|
mono [0x81ea2c6]
|
||||||
|
/lib/i686/cmov/libpthread.so.0 [0xb7e744c0]
|
||||||
|
/lib/i686/cmov/libc.so.6(clone+0x5e) [0xb7dcd6de]
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Exclude heightfield geom
|
||||||
|
|
||||||
|
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
if (d.GeomGetClass(g1) == d.GeomClassID.HeightfieldClass || d.GeomGetClass(g2) == d.GeomClassID.HeightfieldClass)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Raytest against AABBs of spaces first, then dig into the spaces it hits for actual geoms.
|
||||||
|
if (d.GeomIsSpace(g1) || d.GeomIsSpace(g2))
|
||||||
|
{
|
||||||
|
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Separating static prim geometry spaces.
|
||||||
|
// We'll be calling near recursivly if one
|
||||||
|
// of them is a space to find all of the
|
||||||
|
// contact points in the space
|
||||||
|
try
|
||||||
|
{
|
||||||
|
d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
|
||||||
|
}
|
||||||
|
catch (AccessViolationException)
|
||||||
|
{
|
||||||
|
m_log.Warn("[PHYSICS]: Unable to collide test a space");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//Colliding a space or a geom with a space or a geom. so drill down
|
||||||
|
|
||||||
|
//Collide all geoms in each space..
|
||||||
|
//if (d.GeomIsSpace(g1)) d.SpaceCollide(g1, IntPtr.Zero, nearCallback);
|
||||||
|
//if (d.GeomIsSpace(g2)) d.SpaceCollide(g2, IntPtr.Zero, nearCallback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g1 == IntPtr.Zero || g2 == IntPtr.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int count = 0;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
|
||||||
|
if (g1 == g2)
|
||||||
|
return; // Can't collide with yourself
|
||||||
|
|
||||||
|
lock (contacts)
|
||||||
|
{
|
||||||
|
count = d.Collide(g1, g2, contacts.GetLength(0), contacts, d.ContactGeom.SizeOf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (SEHException)
|
||||||
|
{
|
||||||
|
m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory. This could be a result of really irregular terrain. If this repeats continuously, restart using Basic Physics and terrain fill your terrain. Restarting the sim.");
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[PHYSICS]: Unable to collide test an object: {0}", e.Message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PhysicsActor p1 = null;
|
||||||
|
PhysicsActor p2 = null;
|
||||||
|
|
||||||
|
if (g1 != IntPtr.Zero)
|
||||||
|
m_scene.actor_name_map.TryGetValue(g1, out p1);
|
||||||
|
|
||||||
|
if (g2 != IntPtr.Zero)
|
||||||
|
m_scene.actor_name_map.TryGetValue(g1, out p2);
|
||||||
|
|
||||||
|
// Loop over contacts, build results.
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (p1 != null) {
|
||||||
|
if (p1 is OdePrim)
|
||||||
|
{
|
||||||
|
ContactResult collisionresult = new ContactResult();
|
||||||
|
|
||||||
|
collisionresult.ConsumerID = ((OdePrim)p1).m_localID;
|
||||||
|
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
|
||||||
|
collisionresult.Depth = contacts[i].depth;
|
||||||
|
collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
|
||||||
|
contacts[i].normal.Z);
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Add(collisionresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p2 != null)
|
||||||
|
{
|
||||||
|
if (p2 is OdePrim)
|
||||||
|
{
|
||||||
|
ContactResult collisionresult = new ContactResult();
|
||||||
|
|
||||||
|
collisionresult.ConsumerID = ((OdePrim)p2).m_localID;
|
||||||
|
collisionresult.Pos = new Vector3(contacts[i].pos.X, contacts[i].pos.Y, contacts[i].pos.Z);
|
||||||
|
collisionresult.Depth = contacts[i].depth;
|
||||||
|
collisionresult.Normal = new Vector3(contacts[i].normal.X, contacts[i].normal.Y,
|
||||||
|
contacts[i].normal.Z);
|
||||||
|
|
||||||
|
lock (m_contactResults)
|
||||||
|
m_contactResults.Add(collisionresult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dereference the creator scene so that it can be garbage collected if needed.
|
||||||
|
/// </summary>
|
||||||
|
internal void Dispose()
|
||||||
|
{
|
||||||
|
m_scene = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ODERayCastRequest
|
||||||
|
{
|
||||||
|
public Vector3 Origin;
|
||||||
|
public Vector3 Normal;
|
||||||
|
public float length;
|
||||||
|
public RaycastCallback callbackMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct ContactResult
|
||||||
|
{
|
||||||
|
public Vector3 Pos;
|
||||||
|
public float Depth;
|
||||||
|
public uint ConsumerID;
|
||||||
|
public Vector3 Normal;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) Contributors, http://opensimulator.org/
|
||||||
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* * Neither the name of the OpenSimulator Project nor the
|
||||||
|
* names of its contributors may be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
||||||
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
||||||
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using Ode.NET;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using OpenSim.Region.Physics.OdePlugin;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
class OdePhysicsJoint : PhysicsJoint
|
||||||
|
{
|
||||||
|
public override bool IsInPhysicsEngine
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return (jointID != IntPtr.Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public IntPtr jointID;
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,122 @@
|
||||||
|
/*
|
||||||
|
* 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 Nini.Config;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using OpenMetaverse;
|
||||||
|
using OpenSim.Framework;
|
||||||
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using log4net;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class ODETestClass
|
||||||
|
{
|
||||||
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||||
|
|
||||||
|
private OdePlugin cbt;
|
||||||
|
private PhysicsScene ps;
|
||||||
|
private IMeshingPlugin imp;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
// Loading ODEPlugin
|
||||||
|
cbt = new OdePlugin();
|
||||||
|
// Loading Zero Mesher
|
||||||
|
imp = new ZeroMesherPlugin();
|
||||||
|
// Getting Physics Scene
|
||||||
|
ps = cbt.GetScene("test");
|
||||||
|
// Initializing Physics Scene.
|
||||||
|
ps.Initialise(imp.GetMesher(),null);
|
||||||
|
float[] _heightmap = new float[(int)Constants.RegionSize * (int)Constants.RegionSize];
|
||||||
|
for (int i = 0; i < ((int)Constants.RegionSize * (int)Constants.RegionSize); i++)
|
||||||
|
{
|
||||||
|
_heightmap[i] = 21f;
|
||||||
|
}
|
||||||
|
ps.SetTerrain(_heightmap);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TearDown]
|
||||||
|
public void Terminate()
|
||||||
|
{
|
||||||
|
ps.DeleteTerrain();
|
||||||
|
ps.Dispose();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void CreateAndDropPhysicalCube()
|
||||||
|
{
|
||||||
|
PrimitiveBaseShape newcube = PrimitiveBaseShape.CreateBox();
|
||||||
|
Vector3 position = new Vector3(((float)Constants.RegionSize * 0.5f), ((float)Constants.RegionSize * 0.5f), 128f);
|
||||||
|
Vector3 size = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
Quaternion rot = Quaternion.Identity;
|
||||||
|
PhysicsActor prim = ps.AddPrimShape("CoolShape", newcube, position, size, rot, true);
|
||||||
|
OdePrim oprim = (OdePrim)prim;
|
||||||
|
OdeScene pscene = (OdeScene) ps;
|
||||||
|
|
||||||
|
Assert.That(oprim.m_taintadd);
|
||||||
|
|
||||||
|
prim.LocalID = 5;
|
||||||
|
|
||||||
|
for (int i = 0; i < 58; i++)
|
||||||
|
{
|
||||||
|
ps.Simulate(0.133f);
|
||||||
|
|
||||||
|
Assert.That(oprim.prim_geom != (IntPtr)0);
|
||||||
|
|
||||||
|
Assert.That(oprim.m_targetSpace != (IntPtr)0);
|
||||||
|
|
||||||
|
//Assert.That(oprim.m_targetSpace == pscene.space);
|
||||||
|
m_log.Info("TargetSpace: " + oprim.m_targetSpace + " - SceneMainSpace: " + pscene.space);
|
||||||
|
|
||||||
|
Assert.That(!oprim.m_taintadd);
|
||||||
|
m_log.Info("Prim Position (" + oprim.m_localID + "): " + prim.Position.ToString());
|
||||||
|
|
||||||
|
// Make sure we're above the ground
|
||||||
|
//Assert.That(prim.Position.Z > 20f);
|
||||||
|
//m_log.Info("PrimCollisionScore (" + oprim.m_localID + "): " + oprim.m_collisionscore);
|
||||||
|
|
||||||
|
// Make sure we've got a Body
|
||||||
|
Assert.That(oprim.Body != (IntPtr)0);
|
||||||
|
//m_log.Info(
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we're not somewhere above the ground
|
||||||
|
Assert.That(prim.Position.Z < 21.5f);
|
||||||
|
|
||||||
|
ps.RemovePrim(prim);
|
||||||
|
Assert.That(oprim.m_taintremove);
|
||||||
|
ps.Simulate(0.133f);
|
||||||
|
Assert.That(oprim.Body == (IntPtr)0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
/*
|
||||||
|
* Copyright ODE
|
||||||
|
* Ode.NET - .NET bindings for ODE
|
||||||
|
* Jason Perkins (starkos@industriousone.com)
|
||||||
|
* Licensed under the New BSD
|
||||||
|
* Part of the OpenDynamicsEngine
|
||||||
|
Open Dynamics Engine
|
||||||
|
Copyright (c) 2001-2007, Russell L. Smith.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
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 names of ODE's copyright owner 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"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 COPYRIGHT
|
||||||
|
OWNER OR 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.Runtime.InteropServices;
|
||||||
|
using Ode.NET;
|
||||||
|
|
||||||
|
namespace Drawstuff.NET
|
||||||
|
{
|
||||||
|
#if dDOUBLE
|
||||||
|
using dReal = System.Double;
|
||||||
|
#else
|
||||||
|
using dReal = System.Single;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public static class ds
|
||||||
|
{
|
||||||
|
public const int VERSION = 2;
|
||||||
|
|
||||||
|
public enum Texture
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Wood
|
||||||
|
}
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
|
||||||
|
public delegate void CallbackFunction(int arg);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
public struct Functions
|
||||||
|
{
|
||||||
|
public int version;
|
||||||
|
public CallbackFunction start;
|
||||||
|
public CallbackFunction step;
|
||||||
|
public CallbackFunction command;
|
||||||
|
public CallbackFunction stop;
|
||||||
|
public string path_to_textures;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawBox")]
|
||||||
|
public static extern void DrawBox(ref d.Vector3 pos, ref d.Matrix3 R, ref d.Vector3 sides);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawCapsule")]
|
||||||
|
public static extern void DrawCapsule(ref d.Vector3 pos, ref d.Matrix3 R, dReal length, dReal radius);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsDrawConvex")]
|
||||||
|
public static extern void DrawConvex(ref d.Vector3 pos, ref d.Matrix3 R, dReal[] planes, int planeCount, dReal[] points, int pointCount, int[] polygons);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetColor")]
|
||||||
|
public static extern void SetColor(float red, float green, float blue);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetTexture")]
|
||||||
|
public static extern void SetTexture(Texture texture);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSetViewpoint")]
|
||||||
|
public static extern void SetViewpoint(ref d.Vector3 xyz, ref d.Vector3 hpr);
|
||||||
|
|
||||||
|
[DllImport("drawstuff", EntryPoint = "dsSimulationLoop")]
|
||||||
|
public static extern void SimulationLoop(int argc, string[] argv, int window_width, int window_height, ref Functions fn);
|
||||||
|
}
|
||||||
|
}
|
|
@ -487,7 +487,6 @@ namespace OpenSim.Region.Physics.Manager
|
||||||
public override float APIDStrength { set { return; } }
|
public override float APIDStrength { set { return; } }
|
||||||
public override float APIDDamping { set { return; } }
|
public override float APIDDamping { set { return; } }
|
||||||
|
|
||||||
|
|
||||||
public override void SetMomentum(Vector3 momentum)
|
public override void SetMomentum(Vector3 momentum)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1197,27 +1197,13 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public override PIDHoverType PIDHoverType { set { return; } }
|
public override PIDHoverType PIDHoverType { set { return; } }
|
||||||
public override float PIDHoverTau { set { return; } }
|
public override float PIDHoverTau { set { return; } }
|
||||||
|
|
||||||
public override Quaternion APIDTarget
|
public override Quaternion APIDTarget{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool APIDActive
|
public override bool APIDActive{ set { return; } }
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float APIDStrength
|
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override float APIDDamping
|
|
||||||
{
|
|
||||||
set { return; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public override float APIDStrength{ set { return; } }
|
||||||
|
|
||||||
|
public override float APIDDamping{ set { return; } }
|
||||||
|
|
||||||
public override void SubscribeEvents(int ms)
|
public override void SubscribeEvents(int ms)
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,19 +23,6 @@
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
|
||||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
|
||||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
|
||||||
* characteristics and Kinetic motion.
|
|
||||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
|
||||||
* (dynamics) and the associated settings. Old Linear and angular
|
|
||||||
* motors for dynamic motion have been replace with MoveLinear()
|
|
||||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
|
||||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
|
||||||
* switch between 'VEHICLE' parameter use and general dynamics
|
|
||||||
* settings use.
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
/* Revised Aug, Sept 2009 by Kitto Flora. ODEDynamics.cs replaces
|
||||||
|
@ -133,7 +120,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// private float m_VhoverEfficiency = 0f;
|
// private float m_VhoverEfficiency = 0f;
|
||||||
private float m_VhoverTimescale = 0f;
|
private float m_VhoverTimescale = 0f;
|
||||||
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
private float m_VhoverTargetHeight = -1.0f; // if <0 then no hover, else its the current target height
|
||||||
private float m_VehicleBuoyancy = 0f; // Set by VEHICLE_BUOYANCY, for a vehicle.
|
private float m_VehicleBuoyancy = 0f; //KF: m_VehicleBuoyancy is set by VEHICLE_BUOYANCY for a vehicle.
|
||||||
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
// Modifies gravity. Slider between -1 (double-gravity) and 1 (full anti-gravity)
|
||||||
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
// KF: So far I have found no good method to combine a script-requested .Z velocity and gravity.
|
||||||
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
// Therefore only m_VehicleBuoyancy=1 (0g) will use the script-requested .Z velocity.
|
||||||
|
@ -492,7 +479,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W); // rotq = rotation of object
|
||||||
m_dir *= rotq; // apply obj rotation to velocity vector
|
m_dir *= rotq; // apply obj rotation to velocity vector
|
||||||
|
|
||||||
// add Gravity and Buoyancy
|
// add Gravity andBuoyancy
|
||||||
// KF: So far I have found no good method to combine a script-requested
|
// 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 and gravity. Therefore only 0g will used script-requested
|
||||||
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
// .Z velocity. >0g (m_VehicleBuoyancy < 1) will used modified gravity only.
|
||||||
|
@ -574,7 +561,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
private Vector3 m_angularFrictionTimescale = Vector3.Zero; // body angular velocity decay rate
|
||||||
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
private Vector3 m_lastAngularVelocity = Vector3.Zero; // what was last applied to body
|
||||||
*/
|
*/
|
||||||
//if(frcount == 0) Console.WriteLine("MoveAngular ");
|
|
||||||
|
|
||||||
// Get what the body is doing, this includes 'external' influences
|
// Get what the body is doing, this includes 'external' influences
|
||||||
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
d.Vector3 angularVelocity = d.BodyGetAngularVel(Body);
|
||||||
|
@ -650,7 +636,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// Deflection section tba
|
// Deflection section tba
|
||||||
|
|
||||||
// Sum velocities
|
// Sum velocities
|
||||||
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // tba: + bank + deflection
|
m_lastAngularVelocity = m_angularMotorVelocity + vertattr; // + bank + deflection
|
||||||
|
|
||||||
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
if (!m_lastAngularVelocity.ApproxEquals(Vector3.Zero, 0.01f))
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,18 +21,6 @@
|
||||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
* 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
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
*
|
|
||||||
* Revised August 26 2009 by Kitto Flora. ODEDynamics.cs replaces
|
|
||||||
* ODEVehicleSettings.cs. It and ODEPrim.cs are re-organised:
|
|
||||||
* ODEPrim.cs contains methods dealing with Prim editing, Prim
|
|
||||||
* characteristics and Kinetic motion.
|
|
||||||
* ODEDynamics.cs contains methods dealing with Prim Physical motion
|
|
||||||
* (dynamics) and the associated settings. Old Linear and angular
|
|
||||||
* motors for dynamic motion have been replace with MoveLinear()
|
|
||||||
* and MoveAngular(); 'Physical' is used only to switch ODE dynamic
|
|
||||||
* simualtion on/off; VEHICAL_TYPE_NONE/VEHICAL_TYPE_<other> is to
|
|
||||||
* switch between 'VEHICLE' parameter use and general dynamics
|
|
||||||
* settings use.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -93,12 +81,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private float m_PIDTau;
|
private float m_PIDTau;
|
||||||
private float PID_D = 35f;
|
private float PID_D = 35f;
|
||||||
private float PID_G = 25f;
|
private float PID_G = 25f;
|
||||||
private bool m_usePID = false;
|
private bool m_usePID;
|
||||||
|
|
||||||
private Quaternion m_APIDTarget = new Quaternion();
|
|
||||||
private float m_APIDStrength = 0.5f;
|
|
||||||
private float m_APIDDamping = 0.5f;
|
|
||||||
private bool m_useAPID = false;
|
|
||||||
|
|
||||||
// KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
|
// KF: These next 7 params apply to llSetHoverHeight(float height, integer water, float tau),
|
||||||
// and are for non-VEHICLES only.
|
// and are for non-VEHICLES only.
|
||||||
|
@ -200,9 +183,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
internal int m_material = (int)Material.Wood;
|
internal int m_material = (int)Material.Wood;
|
||||||
|
|
||||||
private int frcount = 0; // Used to limit dynamics debug output to
|
|
||||||
|
|
||||||
|
|
||||||
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
|
public OdePrim(String primName, OdeScene parent_scene, Vector3 pos, Vector3 size,
|
||||||
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
|
Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
|
||||||
{
|
{
|
||||||
|
@ -1581,14 +1561,9 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
float fy = 0;
|
float fy = 0;
|
||||||
float fz = 0;
|
float fz = 0;
|
||||||
|
|
||||||
frcount++; // used to limit debug comment output
|
|
||||||
if (frcount > 100)
|
|
||||||
frcount = 0;
|
|
||||||
|
|
||||||
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
if (IsPhysical && (Body != IntPtr.Zero) && !m_isSelected && !childPrim) // KF: Only move root prims.
|
||||||
{
|
{
|
||||||
//if(frcount == 0) Console.WriteLine("Move " + m_primName + " VTyp " + m_vehicle.Type +
|
|
||||||
// " usePID=" + m_usePID + " seHover=" + m_useHoverPID + " useAPID=" + m_useAPID);
|
|
||||||
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
if (m_vehicle.Type != Vehicle.TYPE_NONE)
|
||||||
{
|
{
|
||||||
// 'VEHICLES' are dealt with in ODEDynamics.cs
|
// 'VEHICLES' are dealt with in ODEDynamics.cs
|
||||||
|
@ -1596,6 +1571,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
//Console.WriteLine("Move " + m_primName);
|
||||||
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
|
if(!d.BodyIsEnabled (Body)) d.BodyEnable (Body); // KF add 161009
|
||||||
// NON-'VEHICLES' are dealt with here
|
// NON-'VEHICLES' are dealt with here
|
||||||
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
|
if (d.BodyIsEnabled(Body) && !m_angularlock.ApproxEquals(Vector3.Zero, 0.003f))
|
||||||
|
@ -1617,18 +1593,21 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
//m_log.Info(m_collisionFlags.ToString());
|
//m_log.Info(m_collisionFlags.ToString());
|
||||||
|
|
||||||
|
|
||||||
//KF: m_buoyancy is set by llSetBuoyancy() and is for non-vehicle.
|
//KF: m_buoyancy should be set by llSetBuoyancy() for non-vehicle.
|
||||||
|
// would come from SceneObjectPart.cs, public void SetBuoyancy(float fvalue) , PhysActor.Buoyancy = fvalue; ??
|
||||||
// m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
|
// m_buoyancy: (unlimited value) <0=Falls fast; 0=1g; 1=0g; >1 = floats up
|
||||||
// NB Prims in ODE are no subject to global gravity
|
// gravityz multiplier = 1 - m_buoyancy
|
||||||
fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass; // force = acceleration * mass
|
fz = _parent_scene.gravityz * (1.0f - m_buoyancy) * m_mass;
|
||||||
|
|
||||||
if (m_usePID)
|
if (m_usePID)
|
||||||
{
|
{
|
||||||
//if(frcount == 0) Console.WriteLine("PID " + m_primName);
|
//Console.WriteLine("PID " + m_primName);
|
||||||
// KF - this is for object MoveToTarget.
|
// KF - this is for object move? eg. llSetPos() ?
|
||||||
|
|
||||||
//if (!d.BodyIsEnabled(Body))
|
//if (!d.BodyIsEnabled(Body))
|
||||||
//d.BodySetForce(Body, 0f, 0f, 0f);
|
//d.BodySetForce(Body, 0f, 0f, 0f);
|
||||||
|
// If we're using the PID controller, then we have no gravity
|
||||||
|
//fz = (-1 * _parent_scene.gravityz) * m_mass; //KF: ?? Prims have no global gravity,so simply...
|
||||||
|
fz = 0f;
|
||||||
|
|
||||||
// no lock; for now it's only called from within Simulate()
|
// no lock; for now it's only called from within Simulate()
|
||||||
|
|
||||||
|
@ -1763,7 +1742,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
|
d.BodySetPosition(Body, pos.X, pos.Y, m_targetHoverHeight);
|
||||||
d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
|
d.BodySetLinearVel(Body, vel.X, vel.Y, 0);
|
||||||
d.BodyAddForce(Body, 0, 0, fz);
|
d.BodyAddForce(Body, 0, 0, fz);
|
||||||
//KF this prevents furthur motions return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -1772,45 +1751,7 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
// We're flying and colliding with something
|
// We're flying and colliding with something
|
||||||
fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
|
fz = fz + ((_target_velocity.Z - vel.Z) * (PID_D) * m_mass);
|
||||||
}
|
}
|
||||||
} // end m_useHoverPID && !m_usePID
|
}
|
||||||
|
|
||||||
if (m_useAPID)
|
|
||||||
{
|
|
||||||
// RotLookAt, apparently overrides all other rotation sources. Inputs:
|
|
||||||
// Quaternion m_APIDTarget
|
|
||||||
// float m_APIDStrength // From SL experiments, this is the time to get there
|
|
||||||
// float m_APIDDamping // From SL experiments, this is damping, 1.0 = damped, 0.1 = wobbly
|
|
||||||
// Also in SL the mass of the object has no effect on time to get there.
|
|
||||||
// Factors:
|
|
||||||
//if(frcount == 0) Console.WriteLine("APID ");
|
|
||||||
// get present body rotation
|
|
||||||
float limit = 1.0f;
|
|
||||||
float scaler = 50f; // adjusts damping time
|
|
||||||
float RLAservo = 0f;
|
|
||||||
|
|
||||||
d.Quaternion rot = d.BodyGetQuaternion(Body);
|
|
||||||
Quaternion rotq = new Quaternion(rot.X, rot.Y, rot.Z, rot.W);
|
|
||||||
Quaternion rot_diff = Quaternion.Inverse(rotq) * m_APIDTarget;
|
|
||||||
float diff_angle;
|
|
||||||
Vector3 diff_axis;
|
|
||||||
rot_diff.GetAxisAngle(out diff_axis, out diff_angle);
|
|
||||||
diff_axis.Normalize();
|
|
||||||
if(diff_angle > 0.01f) // diff_angle is always +ve
|
|
||||||
{
|
|
||||||
// PhysicsVector rotforce = new PhysicsVector(diff_axis.X, diff_axis.Y, diff_axis.Z);
|
|
||||||
Vector3 rotforce = new Vector3(diff_axis.X, diff_axis.Y, diff_axis.Z);
|
|
||||||
rotforce = rotforce * rotq;
|
|
||||||
if(diff_angle > limit) diff_angle = limit; // cap the rotate rate
|
|
||||||
// RLAservo = timestep / m_APIDStrength * m_mass * scaler;
|
|
||||||
// rotforce = rotforce * RLAservo * diff_angle ;
|
|
||||||
// d.BodyAddRelTorque(Body, rotforce.X, rotforce.Y, rotforce.Z);
|
|
||||||
RLAservo = timestep / m_APIDStrength * scaler;
|
|
||||||
rotforce = rotforce * RLAservo * diff_angle ;
|
|
||||||
d.BodySetAngularVel (Body, rotforce.X, rotforce.Y, rotforce.Z);
|
|
||||||
//Console.WriteLine("axis= " + diff_axis + " angle= " + diff_angle + "servo= " + RLAservo);
|
|
||||||
}
|
|
||||||
//if(frcount == 0) Console.WriteLine("mass= " + m_mass + " servo= " + RLAservo + " angle= " + diff_angle);
|
|
||||||
} // end m_useAPID
|
|
||||||
|
|
||||||
fx *= m_mass;
|
fx *= m_mass;
|
||||||
fy *= m_mass;
|
fy *= m_mass;
|
||||||
|
@ -2682,10 +2623,6 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
l_orientation.Z = ori.Z;
|
l_orientation.Z = ori.Z;
|
||||||
l_orientation.W = ori.W;
|
l_orientation.W = ori.W;
|
||||||
|
|
||||||
// if(l_position.Y != m_lastposition.Y){
|
|
||||||
// Console.WriteLine("UP&V {0} {1}", m_primName, l_position);
|
|
||||||
// }
|
|
||||||
|
|
||||||
if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
|
if (l_position.X > ((int)_parent_scene.WorldExtents.X - 0.05f) || l_position.X < 0f || l_position.Y > ((int)_parent_scene.WorldExtents.Y - 0.05f) || l_position.Y < 0f)
|
||||||
{
|
{
|
||||||
//base.RaiseOutOfBounds(l_position);
|
//base.RaiseOutOfBounds(l_position);
|
||||||
|
@ -2886,17 +2823,20 @@ Console.WriteLine(" JointCreateFixed");
|
||||||
public override bool PIDActive { set { m_usePID = value; } }
|
public override bool PIDActive { set { m_usePID = value; } }
|
||||||
public override float PIDTau { set { m_PIDTau = value; } }
|
public override float PIDTau { set { m_PIDTau = value; } }
|
||||||
|
|
||||||
// For RotLookAt
|
|
||||||
public override Quaternion APIDTarget { set { m_APIDTarget = value; } }
|
|
||||||
public override bool APIDActive { set { m_useAPID = value; } }
|
|
||||||
public override float APIDStrength { set { m_APIDStrength = value; } }
|
|
||||||
public override float APIDDamping { set { m_APIDDamping = value; } }
|
|
||||||
|
|
||||||
public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
|
public override float PIDHoverHeight { set { m_PIDHoverHeight = value; ; } }
|
||||||
public override bool PIDHoverActive { set { m_useHoverPID = value; } }
|
public override bool PIDHoverActive { set { m_useHoverPID = value; } }
|
||||||
public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
|
public override PIDHoverType PIDHoverType { set { m_PIDHoverType = value; } }
|
||||||
public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
|
public override float PIDHoverTau { set { m_PIDHoverTau = value; } }
|
||||||
|
|
||||||
|
public override Quaternion APIDTarget{ set { return; } }
|
||||||
|
|
||||||
|
public override bool APIDActive{ set { return; } }
|
||||||
|
|
||||||
|
public override float APIDStrength{ set { return; } }
|
||||||
|
|
||||||
|
public override float APIDDamping{ set { return; } }
|
||||||
|
|
||||||
|
|
||||||
private void createAMotor(Vector3 axis)
|
private void createAMotor(Vector3 axis)
|
||||||
{
|
{
|
||||||
if (Body == IntPtr.Zero)
|
if (Body == IntPtr.Zero)
|
||||||
|
|
|
@ -299,6 +299,7 @@ namespace OpenSim.Region.Physics.POSPlugin
|
||||||
{
|
{
|
||||||
set { return; }
|
set { return; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Quaternion APIDTarget
|
public override Quaternion APIDTarget
|
||||||
{
|
{
|
||||||
set { return; }
|
set { return; }
|
||||||
|
|
|
@ -2781,7 +2781,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void llStopLookAt()
|
public void llStopLookAt()
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
@ -7523,9 +7522,17 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_POSITION:
|
case (int)ScriptBaseClass.PRIM_POSITION:
|
||||||
res.Add(new LSL_Vector(part.AbsolutePosition.X,
|
LSL_Vector v = new LSL_Vector(part.AbsolutePosition.X,
|
||||||
part.AbsolutePosition.Y,
|
part.AbsolutePosition.Y,
|
||||||
part.AbsolutePosition.Z));
|
part.AbsolutePosition.Z);
|
||||||
|
// For some reason, the part.AbsolutePosition.* values do not change if the
|
||||||
|
// linkset is rotated; they always reflect the child prim's world position
|
||||||
|
// as though the linkset is unrotated. This is incompatible behavior with SL's
|
||||||
|
// implementation, so will break scripts imported from there (not to mention it
|
||||||
|
// makes it more difficult to determine a child prim's actual inworld position).
|
||||||
|
if (part.ParentID != 0)
|
||||||
|
v = ((v - llGetRootPosition()) * llGetRootRotation()) + llGetRootPosition();
|
||||||
|
res.Add( v );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case (int)ScriptBaseClass.PRIM_SIZE:
|
case (int)ScriptBaseClass.PRIM_SIZE:
|
||||||
|
@ -7543,6 +7550,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
PrimitiveBaseShape Shape = part.Shape;
|
PrimitiveBaseShape Shape = part.Shape;
|
||||||
int primType = getScriptPrimType(part.Shape);
|
int primType = getScriptPrimType(part.Shape);
|
||||||
res.Add(new LSL_Integer(primType));
|
res.Add(new LSL_Integer(primType));
|
||||||
|
double topshearx = (double)(sbyte)Shape.PathShearX / 100.0; // Fix negative values for PathShearX
|
||||||
|
double topsheary = (double)(sbyte)Shape.PathShearY / 100.0; // and PathShearY.
|
||||||
switch (primType)
|
switch (primType)
|
||||||
{
|
{
|
||||||
case ScriptBaseClass.PRIM_TYPE_BOX:
|
case ScriptBaseClass.PRIM_TYPE_BOX:
|
||||||
|
@ -7553,7 +7562,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
|
res.Add(new LSL_Float(Shape.ProfileHollow / 50000.0));
|
||||||
res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
|
res.Add(new LSL_Vector(Shape.PathTwistBegin / 100.0, Shape.PathTwist / 100.0, 0));
|
||||||
res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
|
res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
|
||||||
res.Add(new LSL_Vector(Shape.PathShearX / 100.0, Shape.PathShearY / 100.0, 0));
|
res.Add(new LSL_Vector(topshearx, topsheary, 0));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ScriptBaseClass.PRIM_TYPE_SPHERE:
|
case ScriptBaseClass.PRIM_TYPE_SPHERE:
|
||||||
|
@ -7588,7 +7597,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
|
res.Add(new LSL_Vector(1 - (Shape.PathScaleX / 100.0 - 1), 1 - (Shape.PathScaleY / 100.0 - 1), 0));
|
||||||
|
|
||||||
// vector topshear
|
// vector topshear
|
||||||
res.Add(new LSL_Vector(Shape.PathShearX / 100.0, Shape.PathShearY / 100.0, 0));
|
res.Add(new LSL_Vector(topshearx, topsheary, 0));
|
||||||
|
|
||||||
// vector profilecut
|
// vector profilecut
|
||||||
res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
|
res.Add(new LSL_Vector(Shape.ProfileBegin / 50000.0, 1 - Shape.ProfileEnd / 50000.0, 0));
|
||||||
|
@ -7597,7 +7606,10 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
|
res.Add(new LSL_Vector(Shape.PathTaperX / 100.0, Shape.PathTaperY / 100.0, 0));
|
||||||
|
|
||||||
// float revolutions
|
// float revolutions
|
||||||
res.Add(new LSL_Float(Shape.PathRevolutions / 50.0)); // needs fixing :(
|
res.Add(new LSL_Float((Shape.PathRevolutions * 0.015) + 1.0)); // Slightly inaccurate, because an unsigned
|
||||||
|
// byte is being used to represent the entire
|
||||||
|
// range of floating-point values from 1.0
|
||||||
|
// through 4.0 (which is how SL does it).
|
||||||
|
|
||||||
// float radiusoffset
|
// float radiusoffset
|
||||||
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
|
res.Add(new LSL_Float(Shape.PathRadiusOffset / 100.0));
|
||||||
|
|
|
@ -111,7 +111,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
||||||
if (emessage.StartsWith(slinfo+": "))
|
if (emessage.StartsWith(slinfo+": "))
|
||||||
emessage = emessage.Substring(slinfo.Length+2);
|
emessage = emessage.Substring(slinfo.Length+2);
|
||||||
|
|
||||||
message = String.Format("Line ({0},{1}) {2}",
|
message = String.Format("({0},{1}) {2}",
|
||||||
e.slInfo.lineNumber - 2,
|
e.slInfo.lineNumber - 2,
|
||||||
e.slInfo.charPosition - 1, emessage);
|
e.slInfo.charPosition - 1, emessage);
|
||||||
|
|
||||||
|
|
|
@ -623,7 +623,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.CodeTools
|
||||||
|
|
||||||
// The Second Life viewer's script editor begins
|
// The Second Life viewer's script editor begins
|
||||||
// countingn lines and columns at 0, so we subtract 1.
|
// countingn lines and columns at 0, so we subtract 1.
|
||||||
errtext += String.Format("Line ({0},{1}): {4} {2}: {3}\n",
|
errtext += String.Format("({0},{1}): {4} {2}: {3}\n",
|
||||||
lslPos.Key - 1, lslPos.Value - 1,
|
lslPos.Key - 1, lslPos.Value - 1,
|
||||||
CompErr.ErrorNumber, text, severity);
|
CompErr.ErrorNumber, text, severity);
|
||||||
hadErrors = true;
|
hadErrors = true;
|
||||||
|
|
|
@ -1673,7 +1673,7 @@ default
|
||||||
{
|
{
|
||||||
// The syntax error is on line 6, char 5 (expected ';', found
|
// The syntax error is on line 6, char 5 (expected ';', found
|
||||||
// '}').
|
// '}').
|
||||||
Assert.AreEqual("Line (4,4) syntax error", e.Message);
|
Assert.AreEqual("(4,4) syntax error", e.Message);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1698,7 +1698,7 @@ default
|
||||||
catch (System.Exception e)
|
catch (System.Exception e)
|
||||||
{
|
{
|
||||||
// The syntax error is on line 5, char 14 (Syntax error)
|
// The syntax error is on line 5, char 14 (Syntax error)
|
||||||
Assert.AreEqual("Line (3,13) syntax error", e.Message);
|
Assert.AreEqual("(3,13) syntax error", e.Message);
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -974,7 +974,7 @@ namespace OpenSim.Region.ScriptEngine.Shared.Instance
|
||||||
if (col == 0)
|
if (col == 0)
|
||||||
col++;
|
col++;
|
||||||
message = string.Format("Runtime error:\n" +
|
message = string.Format("Runtime error:\n" +
|
||||||
"Line ({0}): {1}", scriptLine - 1,
|
"({0}): {1}", scriptLine - 1,
|
||||||
e.InnerException.Message);
|
e.InnerException.Message);
|
||||||
|
|
||||||
System.Console.WriteLine(e.ToString()+"\n");
|
System.Console.WriteLine(e.ToString()+"\n");
|
||||||
|
|
|
@ -78,6 +78,8 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
private string m_ScriptErrorMessage;
|
private string m_ScriptErrorMessage;
|
||||||
private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>();
|
private Dictionary<string, string> m_uniqueScripts = new Dictionary<string, string>();
|
||||||
private bool m_AppDomainLoading;
|
private bool m_AppDomainLoading;
|
||||||
|
private Dictionary<UUID,ArrayList> m_ScriptErrors =
|
||||||
|
new Dictionary<UUID,ArrayList>();
|
||||||
|
|
||||||
// disable warning: need to keep a reference to XEngine.EventManager
|
// disable warning: need to keep a reference to XEngine.EventManager
|
||||||
// alive to avoid it being garbage collected
|
// alive to avoid it being garbage collected
|
||||||
|
@ -657,87 +659,97 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
|
Dictionary<KeyValuePair<int, int>, KeyValuePair<int, int>> linemap;
|
||||||
|
|
||||||
try
|
lock(m_ScriptErrors)
|
||||||
{
|
|
||||||
lock (m_AddingAssemblies)
|
|
||||||
{
|
|
||||||
m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
|
|
||||||
if (!m_AddingAssemblies.ContainsKey(assembly)) {
|
|
||||||
m_AddingAssemblies[assembly] = 1;
|
|
||||||
} else {
|
|
||||||
m_AddingAssemblies[assembly]++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string[] warnings = m_Compiler.GetWarnings();
|
|
||||||
|
|
||||||
if (warnings != null && warnings.Length != 0)
|
|
||||||
{
|
|
||||||
foreach (string warning in warnings)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// DISPLAY WARNING INWORLD
|
|
||||||
string text = "Warning:\n" + warning;
|
|
||||||
if (text.Length > 1000)
|
|
||||||
text = text.Substring(0, 1000);
|
|
||||||
if (!ShowScriptSaveResponse(item.OwnerID,
|
|
||||||
assetID, text, true))
|
|
||||||
{
|
|
||||||
if (presence != null && (!postOnRez))
|
|
||||||
presence.ControllingClient.SendAgentAlertMessage("Script saved with warnings, check debug window!", false);
|
|
||||||
|
|
||||||
World.SimChat(Utils.StringToBytes(text),
|
|
||||||
ChatTypeEnum.DebugChannel, 2147483647,
|
|
||||||
part.AbsolutePosition,
|
|
||||||
part.Name, part.UUID, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e2) // LEGIT: User Scripting
|
|
||||||
{
|
|
||||||
m_log.Error("[XEngine]: " +
|
|
||||||
"Error displaying warning in-world: " +
|
|
||||||
e2.ToString());
|
|
||||||
m_log.Error("[XEngine]: " +
|
|
||||||
"Warning:\r\n" +
|
|
||||||
warning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// DISPLAY ERROR INWORLD
|
lock (m_AddingAssemblies)
|
||||||
m_ScriptErrorMessage += "Failed to compile script in object: '" + part.ParentGroup.RootPart.Name + "' Script name: '" + item.Name + "' Error message: " + e.Message.ToString();
|
|
||||||
|
|
||||||
m_ScriptFailCount++;
|
|
||||||
string text = "Error compiling script '" + item.Name + "':\n" + e.Message.ToString();
|
|
||||||
if (text.Length > 1000)
|
|
||||||
text = text.Substring(0, 1000);
|
|
||||||
if (!ShowScriptSaveResponse(item.OwnerID,
|
|
||||||
assetID, text, false))
|
|
||||||
{
|
{
|
||||||
if (presence != null && (!postOnRez))
|
m_Compiler.PerformScriptCompile(script, assetID.ToString(), item.OwnerID, out assembly, out linemap);
|
||||||
presence.ControllingClient.SendAgentAlertMessage("Script saved with errors, check debug window!", false);
|
if (!m_AddingAssemblies.ContainsKey(assembly)) {
|
||||||
World.SimChat(Utils.StringToBytes(text),
|
m_AddingAssemblies[assembly] = 1;
|
||||||
ChatTypeEnum.DebugChannel, 2147483647,
|
} else {
|
||||||
part.AbsolutePosition,
|
m_AddingAssemblies[assembly]++;
|
||||||
part.Name, part.UUID, false);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string[] warnings = m_Compiler.GetWarnings();
|
||||||
|
|
||||||
|
if (warnings != null && warnings.Length != 0)
|
||||||
|
{
|
||||||
|
foreach (string warning in warnings)
|
||||||
|
{
|
||||||
|
if (!m_ScriptErrors.ContainsKey(itemID))
|
||||||
|
m_ScriptErrors[itemID] = new ArrayList();
|
||||||
|
|
||||||
|
m_ScriptErrors[itemID].Add(warning);
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // DISPLAY WARNING INWORLD
|
||||||
|
// string text = "Warning:\n" + warning;
|
||||||
|
// if (text.Length > 1000)
|
||||||
|
// text = text.Substring(0, 1000);
|
||||||
|
// if (!ShowScriptSaveResponse(item.OwnerID,
|
||||||
|
// assetID, text, true))
|
||||||
|
// {
|
||||||
|
// if (presence != null && (!postOnRez))
|
||||||
|
// presence.ControllingClient.SendAgentAlertMessage("Script saved with warnings, check debug window!", false);
|
||||||
|
//
|
||||||
|
// World.SimChat(Utils.StringToBytes(text),
|
||||||
|
// ChatTypeEnum.DebugChannel, 2147483647,
|
||||||
|
// part.AbsolutePosition,
|
||||||
|
// part.Name, part.UUID, false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception e2) // LEGIT: User Scripting
|
||||||
|
// {
|
||||||
|
// m_log.Error("[XEngine]: " +
|
||||||
|
// "Error displaying warning in-world: " +
|
||||||
|
// e2.ToString());
|
||||||
|
// m_log.Error("[XEngine]: " +
|
||||||
|
// "Warning:\r\n" +
|
||||||
|
// warning);
|
||||||
|
// }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (Exception e2) // LEGIT: User Scripting
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
m_log.Error("[XEngine]: "+
|
// try
|
||||||
"Error displaying error in-world: " +
|
// {
|
||||||
e2.ToString());
|
if (!m_ScriptErrors.ContainsKey(itemID))
|
||||||
m_log.Error("[XEngine]: " +
|
m_ScriptErrors[itemID] = new ArrayList();
|
||||||
"Errormessage: Error compiling script:\r\n" +
|
// DISPLAY ERROR INWORLD
|
||||||
e.Message.ToString());
|
// m_ScriptErrorMessage += "Failed to compile script in object: '" + part.ParentGroup.RootPart.Name + "' Script name: '" + item.Name + "' Error message: " + e.Message.ToString();
|
||||||
}
|
//
|
||||||
|
m_ScriptFailCount++;
|
||||||
|
m_ScriptErrors[itemID].Add(e.Message.ToString());
|
||||||
|
// string text = "Error compiling script '" + item.Name + "':\n" + e.Message.ToString();
|
||||||
|
// if (text.Length > 1000)
|
||||||
|
// text = text.Substring(0, 1000);
|
||||||
|
// if (!ShowScriptSaveResponse(item.OwnerID,
|
||||||
|
// assetID, text, false))
|
||||||
|
// {
|
||||||
|
// if (presence != null && (!postOnRez))
|
||||||
|
// presence.ControllingClient.SendAgentAlertMessage("Script saved with errors, check debug window!", false);
|
||||||
|
// World.SimChat(Utils.StringToBytes(text),
|
||||||
|
// ChatTypeEnum.DebugChannel, 2147483647,
|
||||||
|
// part.AbsolutePosition,
|
||||||
|
// part.Name, part.UUID, false);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception e2) // LEGIT: User Scripting
|
||||||
|
// {
|
||||||
|
// m_log.Error("[XEngine]: "+
|
||||||
|
// "Error displaying error in-world: " +
|
||||||
|
// e2.ToString());
|
||||||
|
// m_log.Error("[XEngine]: " +
|
||||||
|
// "Errormessage: Error compiling script:\r\n" +
|
||||||
|
// e.Message.ToString());
|
||||||
|
// }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1252,7 +1264,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
return UUID.Zero;
|
return UUID.Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
[DebuggerNonUserCode]
|
|
||||||
public void SetState(UUID itemID, string newState)
|
public void SetState(UUID itemID, string newState)
|
||||||
{
|
{
|
||||||
IScriptInstance instance = GetInstance(itemID);
|
IScriptInstance instance = GetInstance(itemID);
|
||||||
|
@ -1260,13 +1271,6 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
return;
|
return;
|
||||||
instance.SetState(newState);
|
instance.SetState(newState);
|
||||||
}
|
}
|
||||||
public string GetState(UUID itemID)
|
|
||||||
{
|
|
||||||
IScriptInstance instance = GetInstance(itemID);
|
|
||||||
if (instance == null)
|
|
||||||
return "default";
|
|
||||||
return instance.State;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetStartParameter(UUID itemID)
|
public int GetStartParameter(UUID itemID)
|
||||||
{
|
{
|
||||||
|
@ -1552,5 +1556,21 @@ namespace OpenSim.Region.ScriptEngine.XEngine
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ArrayList GetScriptErrors(UUID itemID)
|
||||||
|
{
|
||||||
|
System.Threading.Thread.Sleep(1000);
|
||||||
|
|
||||||
|
lock (m_ScriptErrors)
|
||||||
|
{
|
||||||
|
if (m_ScriptErrors.ContainsKey(itemID))
|
||||||
|
{
|
||||||
|
ArrayList ret = m_ScriptErrors[itemID];
|
||||||
|
m_ScriptErrors.Remove(itemID);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
return new ArrayList();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -151,6 +151,9 @@ namespace OpenSim.Services.Connectors.Grid
|
||||||
|
|
||||||
m_AssetService.Store(ass);
|
m_AssetService.Store(ass);
|
||||||
|
|
||||||
|
// finally
|
||||||
|
info.TerrainImage = ass.FullID;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
|
catch // LEGIT: Catching problems caused by OpenJPEG p/invoke
|
||||||
{
|
{
|
||||||
|
|
30
prebuild.xml
30
prebuild.xml
|
@ -543,6 +543,36 @@
|
||||||
</Files>
|
</Files>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.ChOdePlugin" path="OpenSim/Region/Physics/ChOdePlugin" type="Library">
|
||||||
|
<Configuration name="Debug">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration name="Release">
|
||||||
|
<Options>
|
||||||
|
<OutputPath>../../../../bin/Physics/</OutputPath>
|
||||||
|
</Options>
|
||||||
|
</Configuration>
|
||||||
|
|
||||||
|
<ReferencePath>../../../../bin/</ReferencePath>
|
||||||
|
<Reference name="System"/>
|
||||||
|
<Reference name="System.Core"/>
|
||||||
|
<Reference name="OpenMetaverseTypes.dll"/>
|
||||||
|
<Reference name="Nini.dll" />
|
||||||
|
<Reference name="OpenSim.Framework"/>
|
||||||
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
|
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||||
|
<Reference name="Ode.NET.dll" />
|
||||||
|
<Reference name="log4net.dll"/>
|
||||||
|
|
||||||
|
<Files>
|
||||||
|
<Match pattern="*.cs" recurse="true">
|
||||||
|
<Exclude name="Tests" pattern="Tests"/>
|
||||||
|
</Match>
|
||||||
|
</Files>
|
||||||
|
</Project>
|
||||||
|
|
||||||
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
<Project frameworkVersion="v3_5" name="OpenSim.Region.Physics.BulletXPlugin" path="OpenSim/Region/Physics/BulletXPlugin" type="Library">
|
||||||
<Configuration name="Debug">
|
<Configuration name="Debug">
|
||||||
<Options>
|
<Options>
|
||||||
|
|
Loading…
Reference in New Issue