Merge branch 'master' into careminster
Conflicts: OpenSim/Region/Framework/Scenes/SceneObjectPart.cs OpenSim/Region/Physics/BulletSPlugin/BSShapes.cs OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.csavinationmerge
commit
09c2cd0d76
|
@ -2148,7 +2148,7 @@ namespace OpenSim.Framework
|
||||||
/// <param name="secret">the secret part</param>
|
/// <param name="secret">the secret part</param>
|
||||||
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
public static bool ParseUniversalUserIdentifier(string value, out UUID uuid, out string url, out string firstname, out string lastname, out string secret)
|
||||||
{
|
{
|
||||||
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "User"; secret = string.Empty;
|
uuid = UUID.Zero; url = string.Empty; firstname = "Unknown"; lastname = "UserUPUUI"; secret = string.Empty;
|
||||||
|
|
||||||
string[] parts = value.Split(';');
|
string[] parts = value.Split(';');
|
||||||
if (parts.Length >= 1)
|
if (parts.Length >= 1)
|
||||||
|
|
|
@ -371,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
foreach (string fid in outstanding)
|
foreach (string fid in outstanding)
|
||||||
{
|
{
|
||||||
UUID fromAgentID;
|
UUID fromAgentID;
|
||||||
string firstname = "Unknown", lastname = "User";
|
string firstname = "Unknown", lastname = "UserFMSFOIN";
|
||||||
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
if (!GetAgentInfo(client.Scene.RegionInfo.ScopeID, fid, out fromAgentID, out firstname, out lastname))
|
||||||
{
|
{
|
||||||
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
m_log.DebugFormat("[FRIENDS MODULE]: skipping malformed friend {0}", fid);
|
||||||
|
@ -397,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
protected virtual bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
{
|
{
|
||||||
first = "Unknown"; last = "User";
|
first = "Unknown"; last = "UserFMGAI";
|
||||||
if (!UUID.TryParse(fid, out agentID))
|
if (!UUID.TryParse(fid, out agentID))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
|
@ -293,7 +293,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
|
||||||
|
|
||||||
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
|
||||||
{
|
{
|
||||||
first = "Unknown"; last = "User";
|
first = "Unknown"; last = "UserHGGAI";
|
||||||
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
if (base.GetAgentInfo(scopeID, fid, out agentID, out first, out last))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
|
@ -157,13 +157,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
string[] names = GetUserNames(uuid);
|
string[] names;
|
||||||
|
bool foundRealName = TryGetUserNames(uuid, out names);
|
||||||
|
|
||||||
if (names.Length == 2)
|
if (names.Length == 2)
|
||||||
{
|
{
|
||||||
//m_log.DebugFormat("[XXX] HandleUUIDNameRequest {0} is {1} {2}", uuid, names[0], names[1]);
|
if (!foundRealName)
|
||||||
|
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Sending {0} {1} for {2} to {3} since no bound name found", names[0], names[1], uuid, remote_client.Name);
|
||||||
|
|
||||||
remote_client.SendNameReply(uuid, names[0], names[1]);
|
remote_client.SendNameReply(uuid, names[0], names[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,10 +249,15 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
}
|
}
|
||||||
|
|
||||||
// search the local cache
|
// search the local cache
|
||||||
foreach (UserData data in m_UserCache.Values)
|
lock (m_UserCache)
|
||||||
if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
|
{
|
||||||
(data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
|
foreach (UserData data in m_UserCache.Values)
|
||||||
users.Add(data);
|
{
|
||||||
|
if (users.Find(delegate(UserData d) { return d.Id == data.Id; }) == null &&
|
||||||
|
(data.FirstName.ToLower().StartsWith(query.ToLower()) || data.LastName.ToLower().StartsWith(query.ToLower())))
|
||||||
|
users.Add(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
AddAdditionalUsers(query, users);
|
AddAdditionalUsers(query, users);
|
||||||
|
|
||||||
|
@ -272,17 +280,24 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string[] GetUserNames(UUID uuid)
|
/// <summary>
|
||||||
|
/// Try to get the names bound to the given uuid.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if the name was found, false if not.</returns>
|
||||||
|
/// <param name='uuid'></param>
|
||||||
|
/// <param name='names'>The array of names if found. If not found, then names[0] = "Unknown" and names[1] = "User"</param>
|
||||||
|
private bool TryGetUserNames(UUID uuid, out string[] names)
|
||||||
{
|
{
|
||||||
string[] returnstring = new string[2];
|
names = new string[2];
|
||||||
|
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
{
|
{
|
||||||
if (m_UserCache.ContainsKey(uuid))
|
if (m_UserCache.ContainsKey(uuid))
|
||||||
{
|
{
|
||||||
returnstring[0] = m_UserCache[uuid].FirstName;
|
names[0] = m_UserCache[uuid].FirstName;
|
||||||
returnstring[1] = m_UserCache[uuid].LastName;
|
names[1] = m_UserCache[uuid].LastName;
|
||||||
return returnstring;
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,8 +305,8 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
if (account != null)
|
if (account != null)
|
||||||
{
|
{
|
||||||
returnstring[0] = account.FirstName;
|
names[0] = account.FirstName;
|
||||||
returnstring[1] = account.LastName;
|
names[1] = account.LastName;
|
||||||
|
|
||||||
UserData user = new UserData();
|
UserData user = new UserData();
|
||||||
user.FirstName = account.FirstName;
|
user.FirstName = account.FirstName;
|
||||||
|
@ -299,14 +314,16 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
lock (m_UserCache)
|
lock (m_UserCache)
|
||||||
m_UserCache[uuid] = user;
|
m_UserCache[uuid] = user;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
returnstring[0] = "Unknown";
|
names[0] = "Unknown";
|
||||||
returnstring[1] = "User";
|
names[1] = "UserUMMTGUN";
|
||||||
}
|
|
||||||
|
|
||||||
return returnstring;
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#region IUserManagement
|
#region IUserManagement
|
||||||
|
@ -342,15 +359,17 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
public string GetUserName(UUID uuid)
|
public string GetUserName(UUID uuid)
|
||||||
{
|
{
|
||||||
string[] names = GetUserNames(uuid);
|
string[] names;
|
||||||
|
TryGetUserNames(uuid, out names);
|
||||||
|
|
||||||
if (names.Length == 2)
|
if (names.Length == 2)
|
||||||
{
|
{
|
||||||
string firstname = names[0];
|
string firstname = names[0];
|
||||||
string lastname = names[1];
|
string lastname = names[1];
|
||||||
|
|
||||||
return firstname + " " + lastname;
|
return firstname + " " + lastname;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return "(hippos)";
|
return "(hippos)";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -466,12 +485,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
//ignore updates without creator data
|
//ignore updates without creator data
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//try update unknown users
|
//try update unknown users
|
||||||
//and creator's home URL's
|
//and creator's home URL's
|
||||||
if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL)))
|
if ((oldUser.FirstName == "Unknown" && !creatorData.Contains ("Unknown")) || (oldUser.HomeURL != null && !creatorData.StartsWith (oldUser.HomeURL)))
|
||||||
{
|
{
|
||||||
m_UserCache.Remove (id);
|
m_UserCache.Remove (id);
|
||||||
// m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData,oldUser.HomeURL);
|
m_log.DebugFormat("[USER MANAGEMENT MODULE]: Re-adding user with id {0}, creatorData [{1}] and old HomeURL {2}", id, creatorData, oldUser.HomeURL);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -516,7 +536,7 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
user.FirstName = "Unknown";
|
user.FirstName = "Unknown";
|
||||||
user.LastName = "User";
|
user.LastName = "UserUMMAU";
|
||||||
}
|
}
|
||||||
|
|
||||||
AddUserInternal (user);
|
AddUserInternal (user);
|
||||||
|
@ -547,6 +567,13 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
|
|
||||||
protected void RegisterConsoleCmds()
|
protected void RegisterConsoleCmds()
|
||||||
{
|
{
|
||||||
|
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||||
|
"show name",
|
||||||
|
"show name <uuid>",
|
||||||
|
"Show the bindings between a single user UUID and a user name",
|
||||||
|
String.Empty,
|
||||||
|
HandleShowUser);
|
||||||
|
|
||||||
MainConsole.Instance.Commands.AddCommand("Users", true,
|
MainConsole.Instance.Commands.AddCommand("Users", true,
|
||||||
"show names",
|
"show names",
|
||||||
"show names",
|
"show names",
|
||||||
|
@ -555,26 +582,54 @@ namespace OpenSim.Region.CoreModules.Framework.UserManagement
|
||||||
HandleShowUsers);
|
HandleShowUsers);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HandleShowUsers(string module, string[] cmd)
|
private void HandleShowUser(string module, string[] cmd)
|
||||||
{
|
{
|
||||||
lock (m_UserCache)
|
if (cmd.Length < 3)
|
||||||
{
|
{
|
||||||
if (m_UserCache.Count == 0)
|
MainConsole.Instance.OutputFormat("Usage: show name <uuid>");
|
||||||
{
|
|
||||||
MainConsole.Instance.Output("No users found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MainConsole.Instance.Output("UUID User Name");
|
|
||||||
MainConsole.Instance.Output("-----------------------------------------------------------------------------");
|
|
||||||
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
|
|
||||||
{
|
|
||||||
MainConsole.Instance.Output(String.Format("{0} {1} {2} ({3})",
|
|
||||||
kvp.Key, kvp.Value.FirstName, kvp.Value.LastName, kvp.Value.HomeURL));
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UUID userId;
|
||||||
|
if (!ConsoleUtil.TryParseConsoleUuid(MainConsole.Instance, cmd[2], out userId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
string[] names;
|
||||||
|
|
||||||
|
UserData ud;
|
||||||
|
|
||||||
|
lock (m_UserCache)
|
||||||
|
{
|
||||||
|
if (!m_UserCache.TryGetValue(userId, out ud))
|
||||||
|
{
|
||||||
|
MainConsole.Instance.OutputFormat("No name known for user with id {0}", userId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("UUID", 36);
|
||||||
|
cdt.AddColumn("Name", 30);
|
||||||
|
cdt.AddColumn("HomeURL", 40);
|
||||||
|
cdt.AddRow(userId, string.Format("{0} {1}", ud.FirstName, ud.LastName), ud.HomeURL);
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleShowUsers(string module, string[] cmd)
|
||||||
|
{
|
||||||
|
ConsoleDisplayTable cdt = new ConsoleDisplayTable();
|
||||||
|
cdt.AddColumn("UUID", 36);
|
||||||
|
cdt.AddColumn("Name", 30);
|
||||||
|
cdt.AddColumn("HomeURL", 40);
|
||||||
|
|
||||||
|
lock (m_UserCache)
|
||||||
|
{
|
||||||
|
foreach (KeyValuePair<UUID, UserData> kvp in m_UserCache)
|
||||||
|
cdt.AddRow(kvp.Key, string.Format("{0} {1}", kvp.Value.FirstName, kvp.Value.LastName), kvp.Value.HomeURL);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainConsole.Instance.Output(cdt.ToString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -369,6 +369,15 @@ namespace OpenSim.Region.CoreModules.World.Sound
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetSoundQueueing(UUID objectID, bool shouldQueue)
|
||||||
|
{
|
||||||
|
SceneObjectPart part;
|
||||||
|
if (!m_scene.TryGetSceneObjectPart(objectID, out part))
|
||||||
|
return;
|
||||||
|
|
||||||
|
part.SoundQueueing = shouldQueue;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,6 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="sound">Sound asset ID</param>
|
/// <param name="sound">Sound asset ID</param>
|
||||||
/// <param name="volume">Sound volume</param>
|
/// <param name="volume">Sound volume</param>
|
||||||
/// <param name="triggered">Triggered or not.</param>
|
/// <param name="triggered">Triggered or not.</param>
|
||||||
/// <param name="flags"></param>
|
|
||||||
/// <param name="radius">Sound radius</param>
|
/// <param name="radius">Sound radius</param>
|
||||||
/// <param name="useMaster">Play using sound master</param>
|
/// <param name="useMaster">Play using sound master</param>
|
||||||
/// <param name="isMaster">Play as sound master</param>
|
/// <param name="isMaster">Play as sound master</param>
|
||||||
|
@ -123,5 +122,12 @@ namespace OpenSim.Region.Framework.Interfaces
|
||||||
/// <param name="max">AABB top north-east corner</param>
|
/// <param name="max">AABB top north-east corner</param>
|
||||||
void TriggerSoundLimited(UUID objectID, UUID sound, double volume,
|
void TriggerSoundLimited(UUID objectID, UUID sound, double volume,
|
||||||
Vector3 min, Vector3 max);
|
Vector3 min, Vector3 max);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Set whether sounds on the given prim should be queued.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name='objectID'></param>
|
||||||
|
/// <param name='shouldQueue'></param>
|
||||||
|
void SetSoundQueueing(UUID objectID, bool shouldQueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -231,6 +231,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
public double SoundRadius;
|
public double SoundRadius;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Should sounds played from this prim be queued?
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This should only be changed by sound modules. It is up to sound modules as to how they interpret this setting.
|
||||||
|
/// </remarks>
|
||||||
|
public bool SoundQueueing { get; set; }
|
||||||
|
|
||||||
public uint TimeStampFull;
|
public uint TimeStampFull;
|
||||||
|
|
||||||
|
|
|
@ -251,6 +251,16 @@ public override BulletShape CreateMeshShape(BulletWorld world,
|
||||||
BSPhysicsShapeType.SHAPE_MESH);
|
BSPhysicsShapeType.SHAPE_MESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override BulletShape CreateGImpactShape(BulletWorld world,
|
||||||
|
int indicesCount, int[] indices,
|
||||||
|
int verticesCount, float[] vertices)
|
||||||
|
{
|
||||||
|
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||||
|
return new BulletShapeUnman(
|
||||||
|
BSAPICPP.CreateGImpactShape2(worldu.ptr, indicesCount, indices, verticesCount, vertices),
|
||||||
|
BSPhysicsShapeType.SHAPE_GIMPACT);
|
||||||
|
}
|
||||||
|
|
||||||
public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls)
|
public override BulletShape CreateHullShape(BulletWorld world, int hullCount, float[] hulls)
|
||||||
{
|
{
|
||||||
BulletWorldUnman worldu = world as BulletWorldUnman;
|
BulletWorldUnman worldu = world as BulletWorldUnman;
|
||||||
|
@ -1425,6 +1435,11 @@ public static extern IntPtr CreateMeshShape2(IntPtr world,
|
||||||
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
||||||
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
||||||
|
|
||||||
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
|
public static extern IntPtr CreateGImpactShape2(IntPtr world,
|
||||||
|
int indicesCount, [MarshalAs(UnmanagedType.LPArray)] int[] indices,
|
||||||
|
int verticesCount, [MarshalAs(UnmanagedType.LPArray)] float[] vertices );
|
||||||
|
|
||||||
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
[DllImport("BulletSim", CallingConvention = CallingConvention.Cdecl), SuppressUnmanagedCodeSecurity]
|
||||||
public static extern IntPtr CreateHullShape2(IntPtr world,
|
public static extern IntPtr CreateHullShape2(IntPtr world,
|
||||||
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
|
int hullCount, [MarshalAs(UnmanagedType.LPArray)] float[] hulls);
|
||||||
|
|
|
@ -1475,7 +1475,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
||||||
ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
||||||
break;
|
break;
|
||||||
case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
|
case BroadphaseNativeTypes.CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE:
|
||||||
ret = BSPhysicsShapeType.SHAPE_MESH;
|
ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
|
||||||
break;
|
break;
|
||||||
case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
|
case BroadphaseNativeTypes.CONVEX_HULL_SHAPE_PROXYTYPE:
|
||||||
ret = BSPhysicsShapeType.SHAPE_HULL;
|
ret = BSPhysicsShapeType.SHAPE_HULL;
|
||||||
|
@ -1503,7 +1503,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
||||||
ret = BSPhysicsShapeType.SHAPE_CONE;
|
ret = BSPhysicsShapeType.SHAPE_CONE;
|
||||||
break;
|
break;
|
||||||
case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
|
case BroadphaseNativeTypes.CONVEX_SHAPE_PROXYTYPE:
|
||||||
ret = BSPhysicsShapeType.SHAPE_UNKNOWN;
|
ret = BSPhysicsShapeType.SHAPE_CONVEXHULL;
|
||||||
break;
|
break;
|
||||||
case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
|
case BroadphaseNativeTypes.CYLINDER_SHAPE_PROXYTYPE:
|
||||||
ret = BSPhysicsShapeType.SHAPE_CYLINDER;
|
ret = BSPhysicsShapeType.SHAPE_CYLINDER;
|
||||||
|
@ -1547,7 +1547,7 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
||||||
break;
|
break;
|
||||||
///Used for GIMPACT Trimesh integration
|
///Used for GIMPACT Trimesh integration
|
||||||
case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
|
case BroadphaseNativeTypes.GIMPACT_SHAPE_PROXYTYPE:
|
||||||
ret = BSPhysicsShapeType.SHAPE_MESH;
|
ret = BSPhysicsShapeType.SHAPE_GIMPACT;
|
||||||
break;
|
break;
|
||||||
///Multimaterial mesh
|
///Multimaterial mesh
|
||||||
case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
|
case BroadphaseNativeTypes.MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE:
|
||||||
|
@ -1820,6 +1820,11 @@ private sealed class BulletConstraintXNA : BulletConstraint
|
||||||
return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH);
|
return new BulletShapeXNA(meshShape, BSPhysicsShapeType.SHAPE_MESH);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
public override BulletShape CreateGImpactShape(BulletWorld pWorld, int pIndicesCount, int[] indices, int pVerticesCount, float[] verticesAsFloats)
|
||||||
|
{
|
||||||
|
// TODO:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
|
public static void DumpRaw(ObjectArray<int>indices, ObjectArray<float> vertices, int pIndicesCount,int pVerticesCount )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,7 @@ public enum BSPhysicsShapeType
|
||||||
SHAPE_HEIGHTMAP = 23,
|
SHAPE_HEIGHTMAP = 23,
|
||||||
SHAPE_AVATAR = 24,
|
SHAPE_AVATAR = 24,
|
||||||
SHAPE_CONVEXHULL= 25,
|
SHAPE_CONVEXHULL= 25,
|
||||||
|
SHAPE_GIMPACT = 26,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The native shapes have predefined shape hash keys
|
// The native shapes have predefined shape hash keys
|
||||||
|
@ -321,6 +322,10 @@ public abstract BulletShape CreateMeshShape(BulletWorld world,
|
||||||
int indicesCount, int[] indices,
|
int indicesCount, int[] indices,
|
||||||
int verticesCount, float[] vertices );
|
int verticesCount, float[] vertices );
|
||||||
|
|
||||||
|
public abstract BulletShape CreateGImpactShape(BulletWorld world,
|
||||||
|
int indicesCount, int[] indices,
|
||||||
|
int verticesCount, float[] vertices );
|
||||||
|
|
||||||
public abstract BulletShape CreateHullShape(BulletWorld world,
|
public abstract BulletShape CreateHullShape(BulletWorld world,
|
||||||
int hullCount, float[] hulls);
|
int hullCount, float[] hulls);
|
||||||
|
|
||||||
|
|
|
@ -483,8 +483,15 @@ public sealed class BSCharacter : BSPhysObject
|
||||||
{
|
{
|
||||||
// Bullet assumes we know what we are doing when forcing orientation
|
// Bullet assumes we know what we are doing when forcing orientation
|
||||||
// so it lets us go against all the rules and just compensates for them later.
|
// so it lets us go against all the rules and just compensates for them later.
|
||||||
// This keeps us from flipping the capsule over which the veiwer does not understand.
|
// This forces rotation to be only around the Z axis and doesn't change any of the other axis.
|
||||||
ForceOrientation = new OMV.Quaternion(0, 0, _orientation.Z,0);
|
// This keeps us from flipping the capsule over which the veiwer does not understand.
|
||||||
|
float oRoll, oPitch, oYaw;
|
||||||
|
_orientation.GetEulerAngles(out oRoll, out oPitch, out oYaw);
|
||||||
|
OMV.Quaternion trimmedOrientation = OMV.Quaternion.CreateFromEulers(0f, 0f, oYaw);
|
||||||
|
// DetailLog("{0},BSCharacter.setOrientation,taint,val={1},valDir={2},conv={3},convDir={4}",
|
||||||
|
// LocalID, _orientation, OMV.Vector3.UnitX * _orientation,
|
||||||
|
// trimmedOrientation, OMV.Vector3.UnitX * trimmedOrientation);
|
||||||
|
ForceOrientation = trimmedOrientation;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,8 @@ public static class BSParam
|
||||||
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
public static bool ShouldRemoveZeroWidthTriangles { get; private set; }
|
||||||
public static bool ShouldUseBulletHACD { get; set; }
|
public static bool ShouldUseBulletHACD { get; set; }
|
||||||
public static bool ShouldUseSingleConvexHullForPrims { get; set; }
|
public static bool ShouldUseSingleConvexHullForPrims { get; set; }
|
||||||
|
public static bool ShouldUseGImpactShapeForPrims { get; set; }
|
||||||
|
public static bool ShouldUseAssetHulls { get; set; }
|
||||||
|
|
||||||
public static float TerrainImplementation { get; set; }
|
public static float TerrainImplementation { get; set; }
|
||||||
public static int TerrainMeshMagnification { get; private set; }
|
public static int TerrainMeshMagnification { get; private set; }
|
||||||
|
@ -369,6 +371,10 @@ public static class BSParam
|
||||||
false ),
|
false ),
|
||||||
new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
|
new ParameterDefn<bool>("ShouldUseSingleConvexHullForPrims", "If true, use a single convex hull shape for physical prims",
|
||||||
true ),
|
true ),
|
||||||
|
new ParameterDefn<bool>("ShouldUseGImpactShapeForPrims", "If true, use a GImpact shape for prims with cuts and twists",
|
||||||
|
false ),
|
||||||
|
new ParameterDefn<bool>("UseAssetHulls", "If true, use hull if specified in the mesh asset info",
|
||||||
|
false ),
|
||||||
|
|
||||||
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
new ParameterDefn<int>("CrossingFailuresBeforeOutOfBounds", "How forgiving we are about getting into adjactent regions",
|
||||||
5 ),
|
5 ),
|
||||||
|
|
|
@ -268,6 +268,12 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
// Do any replacements in the parameters
|
// Do any replacements in the parameters
|
||||||
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
m_physicsLoggingPrefix = m_physicsLoggingPrefix.Replace("%REGIONNAME%", RegionName);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BulletEngineName = "BulletUnmanaged";
|
||||||
|
m_physicsLoggingEnabled = false;
|
||||||
|
VehicleLoggingEnabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
// The material characteristics.
|
// The material characteristics.
|
||||||
BSMaterials.InitializeFromDefaults(Params);
|
BSMaterials.InitializeFromDefaults(Params);
|
||||||
|
@ -322,6 +328,8 @@ public sealed class BSScene : PhysicsScene, IPhysicsParameters
|
||||||
BSParam.ShouldUseBulletHACD = false;
|
BSParam.ShouldUseBulletHACD = false;
|
||||||
m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
|
m_log.InfoFormat("{0} Disabling ShouldUseSingleConvexHullForPrims", LogHeader);
|
||||||
BSParam.ShouldUseSingleConvexHullForPrims = false;
|
BSParam.ShouldUseSingleConvexHullForPrims = false;
|
||||||
|
m_log.InfoFormat("{0} Disabling ShouldUseGImpactShapeForPrims", LogHeader);
|
||||||
|
BSParam.ShouldUseGImpactShapeForPrims = false;
|
||||||
m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader);
|
m_log.InfoFormat("{0} Setting terrain implimentation to Heightmap", LogHeader);
|
||||||
BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
|
BSParam.TerrainImplementation = (float)BSTerrainPhys.TerrainImplementation.Heightmap;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -230,6 +230,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
BSShape potentialHull = null;
|
BSShape potentialHull = null;
|
||||||
|
|
||||||
PrimitiveBaseShape pbs = prim.BaseShape;
|
PrimitiveBaseShape pbs = prim.BaseShape;
|
||||||
|
// Use a simple, one section convex shape for prims that are probably convex (no cuts or twists)
|
||||||
if (BSParam.ShouldUseSingleConvexHullForPrims
|
if (BSParam.ShouldUseSingleConvexHullForPrims
|
||||||
&& pbs != null
|
&& pbs != null
|
||||||
&& !pbs.SculptEntry
|
&& !pbs.SculptEntry
|
||||||
|
@ -238,7 +239,17 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
{
|
{
|
||||||
potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim);
|
potentialHull = BSShapeConvexHull.GetReference(m_physicsScene, false /* forceRebuild */, prim);
|
||||||
}
|
}
|
||||||
else
|
// Use the GImpact shape if it is a prim that has some concaveness
|
||||||
|
if (potentialHull == null
|
||||||
|
&& BSParam.ShouldUseGImpactShapeForPrims
|
||||||
|
&& pbs != null
|
||||||
|
&& !pbs.SculptEntry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
potentialHull = BSShapeGImpact.GetReference(m_physicsScene, false /* forceRebuild */, prim);
|
||||||
|
}
|
||||||
|
// If not any of the simple cases, just make a hull
|
||||||
|
if (potentialHull == null)
|
||||||
{
|
{
|
||||||
potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
potentialHull = BSShapeHull.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||||
}
|
}
|
||||||
|
@ -261,7 +272,7 @@ public sealed class BSShapeCollection : IDisposable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Update prim.BSShape to reference a mesh of this shape.
|
// Non-physical objects should be just meshes.
|
||||||
BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
BSShape potentialMesh = BSShapeMesh.GetReference(m_physicsScene, false /*forceRebuild*/, prim);
|
||||||
// If the current shape is not what is on the prim at the moment, time to change.
|
// If the current shape is not what is on the prim at the moment, time to change.
|
||||||
if (!prim.PhysShape.HasPhysicalShape
|
if (!prim.PhysShape.HasPhysicalShape
|
||||||
|
|
|
@ -31,6 +31,7 @@ using System.Text;
|
||||||
|
|
||||||
using OpenSim.Framework;
|
using OpenSim.Framework;
|
||||||
using OpenSim.Region.Physics.Manager;
|
using OpenSim.Region.Physics.Manager;
|
||||||
|
using OpenSim.Region.Physics.Meshing;
|
||||||
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
using OpenSim.Region.Physics.ConvexDecompositionDotNet;
|
||||||
|
|
||||||
using OMV = OpenMetaverse;
|
using OMV = OpenMetaverse;
|
||||||
|
@ -422,8 +423,21 @@ public class BSShapeMesh : BSShape
|
||||||
outMesh = foundDesc;
|
outMesh = foundDesc;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate BulletShape CreateShapeCall(BulletWorld world, int indicesCount, int[] indices, int verticesCount, float[] vertices );
|
||||||
private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
private BulletShape CreatePhysicalMesh(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||||
|
{
|
||||||
|
return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
|
||||||
|
(w, iC, i, vC, v) => physicsScene.PE.CreateMeshShape(w, iC, i, vC, v) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Code that uses the mesher to create the index/vertices info for a trimesh shape.
|
||||||
|
// This is used by the passed 'makeShape' call to create the Bullet mesh shape.
|
||||||
|
// The actual build call is passed so this logic can be used by several of the shapes that use a
|
||||||
|
// simple mesh as their base shape.
|
||||||
|
public static BulletShape CreatePhysicalMeshShape(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||||
|
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod, CreateShapeCall makeShape)
|
||||||
{
|
{
|
||||||
BulletShape newShape = new BulletShape();
|
BulletShape newShape = new BulletShape();
|
||||||
|
|
||||||
|
@ -484,8 +498,7 @@ public class BSShapeMesh : BSShape
|
||||||
|
|
||||||
if (realIndicesIndex != 0)
|
if (realIndicesIndex != 0)
|
||||||
{
|
{
|
||||||
newShape = physicsScene.PE.CreateMeshShape(physicsScene.World,
|
newShape = makeShape(physicsScene.World, realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
|
||||||
realIndicesIndex, indices, verticesAsFloats.Length / 3, verticesAsFloats);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -563,9 +576,56 @@ public class BSShapeHull : BSShape
|
||||||
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||||
{
|
{
|
||||||
BulletShape newShape = new BulletShape();
|
BulletShape newShape = new BulletShape();
|
||||||
IntPtr hullPtr = IntPtr.Zero;
|
newShape.shapeKey = newHullKey;
|
||||||
|
|
||||||
if (BSParam.ShouldUseBulletHACD)
|
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
||||||
|
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
||||||
|
|
||||||
|
// If there is hull data in the mesh asset, build the hull from that
|
||||||
|
if (meshData != null && BSParam.ShouldUseAssetHulls)
|
||||||
|
{
|
||||||
|
Meshmerizer realMesher = physicsScene.mesher as Meshmerizer;
|
||||||
|
if (realMesher != null)
|
||||||
|
{
|
||||||
|
List<List<OMV.Vector3>> allHulls = realMesher.GetConvexHulls(size);
|
||||||
|
if (allHulls != null)
|
||||||
|
{
|
||||||
|
int hullCount = allHulls.Count;
|
||||||
|
int totalVertices = 1; // include one for the count of the hulls
|
||||||
|
// Using the structure described for HACD hulls, create the memory sturcture
|
||||||
|
// to pass the hull data to the creater.
|
||||||
|
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||||
|
{
|
||||||
|
totalVertices += 4; // add four for the vertex count and centroid
|
||||||
|
totalVertices += hullVerts.Count * 3; // one vertex is three dimensions
|
||||||
|
}
|
||||||
|
float[] convHulls = new float[totalVertices];
|
||||||
|
|
||||||
|
convHulls[0] = (float)hullCount;
|
||||||
|
int jj = 1;
|
||||||
|
foreach (List<OMV.Vector3> hullVerts in allHulls)
|
||||||
|
{
|
||||||
|
convHulls[jj + 0] = hullVerts.Count;
|
||||||
|
convHulls[jj + 1] = 0f; // centroid x,y,z
|
||||||
|
convHulls[jj + 2] = 0f;
|
||||||
|
convHulls[jj + 3] = 0f;
|
||||||
|
jj += 4;
|
||||||
|
foreach (OMV.Vector3 oneVert in hullVerts)
|
||||||
|
{
|
||||||
|
convHulls[jj + 0] = oneVert.X;
|
||||||
|
convHulls[jj + 1] = oneVert.Y;
|
||||||
|
convHulls[jj + 2] = oneVert.Z;
|
||||||
|
jj += 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the hull data structure in Bullet
|
||||||
|
newShape = physicsScene.PE.CreateHullShape(physicsScene.World, hullCount, convHulls);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If no hull specified in the asset and we should use Bullet's HACD approximation...
|
||||||
|
if (!newShape.HasPhysicalShape && BSParam.ShouldUseBulletHACD)
|
||||||
{
|
{
|
||||||
// Build the hull shape from an existing mesh shape.
|
// Build the hull shape from an existing mesh shape.
|
||||||
// The mesh should have already been created in Bullet.
|
// The mesh should have already been created in Bullet.
|
||||||
|
@ -594,11 +654,10 @@ public class BSShapeHull : BSShape
|
||||||
}
|
}
|
||||||
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
physicsScene.DetailLog("{0},BSShapeHull.CreatePhysicalHull,shouldUseBulletHACD,exit,hasBody={1}", prim.LocalID, newShape.HasPhysicalShape);
|
||||||
}
|
}
|
||||||
|
// If no hull specified, use our HACD hull approximation.
|
||||||
if (!newShape.HasPhysicalShape)
|
if (!newShape.HasPhysicalShape)
|
||||||
{
|
{
|
||||||
// Build a new hull in the physical world using the C# HACD algorigthm.
|
// Build a new hull in the physical world using the C# HACD algorigthm.
|
||||||
// Pass true for physicalness as this prevents the creation of bounding box which is not needed
|
|
||||||
IMesh meshData = physicsScene.mesher.CreateMesh(prim.PhysObjectName, pbs, size, lod, true /* isPhysical */, false /* shouldCache */, false, false);
|
|
||||||
if (meshData != null)
|
if (meshData != null)
|
||||||
{
|
{
|
||||||
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
if (prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Fetched)
|
||||||
|
@ -805,6 +864,7 @@ public class BSShapeCompound : BSShape
|
||||||
// Called at taint-time.
|
// Called at taint-time.
|
||||||
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
|
private void DereferenceAnonCollisionShape(BSScene physicsScene, BulletShape pShape)
|
||||||
{
|
{
|
||||||
|
// TODO: figure a better way to go through all the shape types and find a possible instance.
|
||||||
BSShapeMesh meshDesc;
|
BSShapeMesh meshDesc;
|
||||||
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
|
if (BSShapeMesh.TryGetMeshByPtr(pShape, out meshDesc))
|
||||||
{
|
{
|
||||||
|
@ -826,17 +886,25 @@ public class BSShapeCompound : BSShape
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (physicsScene.PE.IsCompound(pShape))
|
BSShapeGImpact gImpactDesc;
|
||||||
|
if (BSShapeGImpact.TryGetGImpactByPtr(pShape, out gImpactDesc))
|
||||||
{
|
{
|
||||||
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
|
gImpactDesc.Dereference(physicsScene);
|
||||||
recursiveCompound.Dereference(physicsScene);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (physicsScene.PE.IsNativeShape(pShape))
|
if (physicsScene.PE.IsCompound(pShape))
|
||||||
{
|
{
|
||||||
BSShapeNative nativeShape = new BSShapeNative(pShape);
|
BSShapeCompound recursiveCompound = new BSShapeCompound(pShape);
|
||||||
nativeShape.Dereference(physicsScene);
|
recursiveCompound.Dereference(physicsScene);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (physicsScene.PE.IsNativeShape(pShape))
|
||||||
|
{
|
||||||
|
BSShapeNative nativeShape = new BSShapeNative(pShape);
|
||||||
|
nativeShape.Dereference(physicsScene);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -859,7 +927,7 @@ public class BSShapeConvexHull : BSShape
|
||||||
float lod;
|
float lod;
|
||||||
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
physicsScene.DetailLog("{0},BSShapeMesh,getReference,newKey={1},size={2},lod={3}",
|
physicsScene.DetailLog("{0},BSShapeConvexHull,getReference,newKey={1},size={2},lod={3}",
|
||||||
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||||
|
|
||||||
BSShapeConvexHull retConvexHull = null;
|
BSShapeConvexHull retConvexHull = null;
|
||||||
|
@ -939,6 +1007,97 @@ public class BSShapeConvexHull : BSShape
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// ============================================================================================================
|
||||||
|
public class BSShapeGImpact : BSShape
|
||||||
|
{
|
||||||
|
private static string LogHeader = "[BULLETSIM SHAPE GIMPACT]";
|
||||||
|
public static Dictionary<System.UInt64, BSShapeGImpact> GImpacts = new Dictionary<System.UInt64, BSShapeGImpact>();
|
||||||
|
|
||||||
|
public BSShapeGImpact(BulletShape pShape) : base(pShape)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
public static BSShape GetReference(BSScene physicsScene, bool forceRebuild, BSPhysObject prim)
|
||||||
|
{
|
||||||
|
float lod;
|
||||||
|
System.UInt64 newMeshKey = BSShape.ComputeShapeKey(prim.Size, prim.BaseShape, out lod);
|
||||||
|
|
||||||
|
physicsScene.DetailLog("{0},BSShapeGImpact,getReference,newKey={1},size={2},lod={3}",
|
||||||
|
prim.LocalID, newMeshKey.ToString("X"), prim.Size, lod);
|
||||||
|
|
||||||
|
BSShapeGImpact retGImpact = null;
|
||||||
|
lock (GImpacts)
|
||||||
|
{
|
||||||
|
if (GImpacts.TryGetValue(newMeshKey, out retGImpact))
|
||||||
|
{
|
||||||
|
// The mesh has already been created. Return a new reference to same.
|
||||||
|
retGImpact.IncrementReference();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
retGImpact = new BSShapeGImpact(new BulletShape());
|
||||||
|
BulletShape newShape = retGImpact.CreatePhysicalGImpact(physicsScene, prim, newMeshKey, prim.BaseShape, prim.Size, lod);
|
||||||
|
|
||||||
|
// Check to see if mesh was created (might require an asset).
|
||||||
|
newShape = VerifyMeshCreated(physicsScene, newShape, prim);
|
||||||
|
if (!newShape.isNativeShape || prim.PrimAssetState == BSPhysObject.PrimAssetCondition.Failed)
|
||||||
|
{
|
||||||
|
// If a mesh was what was created, remember the built shape for later sharing.
|
||||||
|
// Also note that if meshing failed we put it in the mesh list as there is nothing else to do about the mesh.
|
||||||
|
GImpacts.Add(newMeshKey, retGImpact);
|
||||||
|
}
|
||||||
|
|
||||||
|
retGImpact.physShapeInfo = newShape;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retGImpact;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BulletShape CreatePhysicalGImpact(BSScene physicsScene, BSPhysObject prim, System.UInt64 newMeshKey,
|
||||||
|
PrimitiveBaseShape pbs, OMV.Vector3 size, float lod)
|
||||||
|
{
|
||||||
|
return BSShapeMesh.CreatePhysicalMeshShape(physicsScene, prim, newMeshKey, pbs, size, lod,
|
||||||
|
(w, iC, i, vC, v) => physicsScene.PE.CreateGImpactShape(w, iC, i, vC, v) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public override BSShape GetReference(BSScene physicsScene, BSPhysObject prim)
|
||||||
|
{
|
||||||
|
// Calling this reference means we want another handle to an existing shape
|
||||||
|
// (usually linksets) so return this copy.
|
||||||
|
IncrementReference();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
// Dereferencing a compound shape releases the hold on all the child shapes.
|
||||||
|
public override void Dereference(BSScene physicsScene)
|
||||||
|
{
|
||||||
|
lock (GImpacts)
|
||||||
|
{
|
||||||
|
this.DecrementReference();
|
||||||
|
physicsScene.DetailLog("{0},BSShapeGImpact.Dereference,shape={1}", BSScene.DetailLogZero, this);
|
||||||
|
// TODO: schedule aging and destruction of unused meshes.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Loop through all the known hulls and return the description based on the physical address.
|
||||||
|
public static bool TryGetGImpactByPtr(BulletShape pShape, out BSShapeGImpact outHull)
|
||||||
|
{
|
||||||
|
bool ret = false;
|
||||||
|
BSShapeGImpact foundDesc = null;
|
||||||
|
lock (GImpacts)
|
||||||
|
{
|
||||||
|
foreach (BSShapeGImpact sh in GImpacts.Values)
|
||||||
|
{
|
||||||
|
if (sh.physShapeInfo.ReferenceSame(pShape))
|
||||||
|
{
|
||||||
|
foundDesc = sh;
|
||||||
|
ret = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outHull = foundDesc;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ============================================================================================================
|
// ============================================================================================================
|
||||||
public class BSShapeAvatar : BSShape
|
public class BSShapeAvatar : BSShape
|
||||||
|
|
|
@ -1,16 +1,12 @@
|
||||||
PROBLEMS TO LOOK INTO
|
CURRENT PROBLEMS TO FIX AND/OR LOOK AT
|
||||||
=================================================
|
=================================================
|
||||||
Nebadon vehicle ride, get up, ride again. Second time vehicle does not act correctly.
|
Script changing rotation of child prim while vehicle moving (eg turning wheel) causes
|
||||||
|
the wheel to appear to jump back. Looks like sending position from previous update.
|
||||||
|
Vehicle ride, get up, ride again. Second time vehicle does not act correctly.
|
||||||
Have to rez new vehicle and delete the old to fix situation.
|
Have to rez new vehicle and delete the old to fix situation.
|
||||||
Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd
|
Hitting RESET on Nebadon's vehicle while riding causes vehicle to get into odd
|
||||||
position state where it will not settle onto ground properly, etc
|
position state where it will not settle onto ground properly, etc
|
||||||
Two of Nebadon vehicles in a sim max the CPU. This is new.
|
Two of Nebadon vehicles in a sim max the CPU. This is new.
|
||||||
A sitting, active vehicle bobs up and down a small amount.
|
|
||||||
|
|
||||||
CURRENT PRIORITIES
|
|
||||||
=================================================
|
|
||||||
Use the HACD convex hull routine in Bullet rather than the C# version.
|
|
||||||
Speed up hullifying large meshes.
|
|
||||||
Enable vehicle border crossings (at least as poorly as ODE)
|
Enable vehicle border crossings (at least as poorly as ODE)
|
||||||
Terrain skirts
|
Terrain skirts
|
||||||
Avatar created in previous region and not new region when crossing border
|
Avatar created in previous region and not new region when crossing border
|
||||||
|
@ -361,4 +357,6 @@ Angular motion around Z moves the vehicle in world Z and not vehicle Z in ODE.
|
||||||
Nebadon vehicles turning funny in arena (DONE)
|
Nebadon vehicles turning funny in arena (DONE)
|
||||||
Lock axis (DONE 20130401)
|
Lock axis (DONE 20130401)
|
||||||
Terrain detail: double terrain mesh detail (DONE)
|
Terrain detail: double terrain mesh detail (DONE)
|
||||||
|
Use the HACD convex hull routine in Bullet rather than the C# version.
|
||||||
|
Speed up hullifying large meshes. (DONE)
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,8 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
|
|
||||||
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
private float minSizeForComplexMesh = 0.2f; // prims with all dimensions smaller than this will have a bounding box mesh
|
||||||
|
|
||||||
|
private List<List<Vector3>> mConvexHulls = null;
|
||||||
|
|
||||||
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
private Dictionary<ulong, Mesh> m_uniqueMeshes = new Dictionary<ulong, Mesh>();
|
||||||
|
|
||||||
public Meshmerizer(IConfigSource config)
|
public Meshmerizer(IConfigSource config)
|
||||||
|
@ -363,6 +365,57 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
else if (map.ContainsKey("high_lod"))
|
else if (map.ContainsKey("high_lod"))
|
||||||
physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
|
physicsParms = (OSDMap)map["high_lod"]; // if all else fails, use highest LOD display mesh and hope it works :)
|
||||||
|
|
||||||
|
if (map.ContainsKey("physics_convex"))
|
||||||
|
{ // pull this out also in case physics engine can use it
|
||||||
|
try
|
||||||
|
{
|
||||||
|
OSDMap convexBlock = (OSDMap)map["physics_convex"];
|
||||||
|
if (convexBlock.ContainsKey("HullList"))
|
||||||
|
{
|
||||||
|
byte[] hullList = convexBlock["HullList"].AsBinary();
|
||||||
|
Vector3 min = new Vector3(-0.5f, -0.5f, -0.5f);
|
||||||
|
if (convexBlock.ContainsKey("Min")) min = convexBlock["Min"].AsVector3();
|
||||||
|
Vector3 max = new Vector3(0.5f, 0.5f, 0.5f);
|
||||||
|
if (convexBlock.ContainsKey("Max")) max = convexBlock["Max"].AsVector3();
|
||||||
|
|
||||||
|
// decompress and decode hull points
|
||||||
|
byte[] posBytes = DecompressOsd(convexBlock["Positions"].AsBinary()).AsBinary();
|
||||||
|
|
||||||
|
List<List<Vector3>> hulls = new List<List<Vector3>>();
|
||||||
|
int posNdx = 0;
|
||||||
|
|
||||||
|
foreach (byte cnt in hullList)
|
||||||
|
{
|
||||||
|
int count = cnt == 0 ? 256 : cnt;
|
||||||
|
List<Vector3> hull = new List<Vector3>();
|
||||||
|
|
||||||
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
ushort uX = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
|
||||||
|
ushort uY = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
|
||||||
|
ushort uZ = Utils.BytesToUInt16(posBytes, posNdx); posNdx += 2;
|
||||||
|
|
||||||
|
Vector3 pos = new Vector3(
|
||||||
|
Utils.UInt16ToFloat(uX, min.X, max.X),
|
||||||
|
Utils.UInt16ToFloat(uY, min.Y, max.Y),
|
||||||
|
Utils.UInt16ToFloat(uZ, min.Z, max.Z)
|
||||||
|
);
|
||||||
|
|
||||||
|
hull.Add(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
hulls.Add(hull);
|
||||||
|
}
|
||||||
|
|
||||||
|
mConvexHulls = hulls;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[MESH]: exception decoding convex block: {0}", e.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (physicsParms == null)
|
if (physicsParms == null)
|
||||||
{
|
{
|
||||||
m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
|
m_log.WarnFormat("[MESH]: No recognized physics mesh found in mesh asset for {0}", primName);
|
||||||
|
@ -381,27 +434,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
// byte[] decompressed = new byte[physSize * 5];
|
// byte[] decompressed = new byte[physSize * 5];
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using (MemoryStream inMs = new MemoryStream(meshBytes))
|
decodedMeshOsd = DecompressOsd(meshBytes);
|
||||||
{
|
|
||||||
using (MemoryStream outMs = new MemoryStream())
|
|
||||||
{
|
|
||||||
using (ZOutputStream zOut = new ZOutputStream(outMs))
|
|
||||||
{
|
|
||||||
byte[] readBuffer = new byte[2048];
|
|
||||||
int readLen = 0;
|
|
||||||
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
|
|
||||||
{
|
|
||||||
zOut.Write(readBuffer, 0, readLen);
|
|
||||||
}
|
|
||||||
zOut.Flush();
|
|
||||||
outMs.Seek(0, SeekOrigin.Begin);
|
|
||||||
|
|
||||||
byte[] decompressedBuf = outMs.GetBuffer();
|
|
||||||
|
|
||||||
decodedMeshOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -428,6 +461,41 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// decompresses a gzipped OSD object
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="decodedOsd"></param> the OSD object
|
||||||
|
/// <param name="meshBytes"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
private static OSD DecompressOsd(byte[] meshBytes)
|
||||||
|
{
|
||||||
|
OSD decodedOsd = null;
|
||||||
|
|
||||||
|
using (MemoryStream inMs = new MemoryStream(meshBytes))
|
||||||
|
{
|
||||||
|
using (MemoryStream outMs = new MemoryStream())
|
||||||
|
{
|
||||||
|
using (ZOutputStream zOut = new ZOutputStream(outMs))
|
||||||
|
{
|
||||||
|
byte[] readBuffer = new byte[2048];
|
||||||
|
int readLen = 0;
|
||||||
|
while ((readLen = inMs.Read(readBuffer, 0, readBuffer.Length)) > 0)
|
||||||
|
{
|
||||||
|
zOut.Write(readBuffer, 0, readLen);
|
||||||
|
}
|
||||||
|
zOut.Flush();
|
||||||
|
outMs.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
|
byte[] decompressedBuf = outMs.GetBuffer();
|
||||||
|
|
||||||
|
decodedOsd = OSDParser.DeserializeLLSDBinary(decompressedBuf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return decodedOsd;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
|
/// Generate the co-ords and faces necessary to construct a mesh from the sculpt data the accompanies a prim.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -704,6 +772,27 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// temporary prototype code - please do not use until the interface has been finalized!
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="size">value to scale the hull points by</param>
|
||||||
|
/// <returns>a list of hulls if they exist and have been successfully decoded, otherwise null</returns>
|
||||||
|
public List<List<Vector3>> GetConvexHulls(Vector3 size)
|
||||||
|
{
|
||||||
|
if (mConvexHulls == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
List<List<Vector3>> hulls = new List<List<Vector3>>();
|
||||||
|
foreach (var hull in mConvexHulls)
|
||||||
|
{
|
||||||
|
List<Vector3> verts = new List<Vector3>();
|
||||||
|
foreach (var vert in hull)
|
||||||
|
verts.Add(vert * size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hulls;
|
||||||
|
}
|
||||||
|
|
||||||
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
|
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod)
|
||||||
{
|
{
|
||||||
return CreateMesh(primName, primShape, size, lod, false, true);
|
return CreateMesh(primName, primShape, size, lod, false, true);
|
||||||
|
|
|
@ -2772,9 +2772,11 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
// send the sound, once, to all clients in range
|
// send the sound, once, to all clients in range
|
||||||
if (m_SoundModule != null)
|
if (m_SoundModule != null)
|
||||||
{
|
{
|
||||||
m_SoundModule.SendSound(m_host.UUID,
|
m_SoundModule.SendSound(
|
||||||
ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound), volume, false, 0,
|
m_host.UUID,
|
||||||
0, false, false);
|
ScriptUtils.GetAssetIdFromKeyOrItemName(m_host, sound, AssetType.Sound),
|
||||||
|
volume, false, m_host.SoundQueueing ? (byte)SoundFlags.Queue : (byte)SoundFlags.None,
|
||||||
|
0, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12644,6 +12646,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api
|
||||||
public void llSetSoundQueueing(int queue)
|
public void llSetSoundQueueing(int queue)
|
||||||
{
|
{
|
||||||
m_host.AddScriptLPS(1);
|
m_host.AddScriptLPS(1);
|
||||||
|
|
||||||
|
if (m_SoundModule != null)
|
||||||
|
m_SoundModule.SetSoundQueueing(m_host.UUID, queue == ScriptBaseClass.TRUE.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llCollisionSprite(string impact_sprite)
|
public void llCollisionSprite(string impact_sprite)
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1878,6 +1878,7 @@
|
||||||
<Reference name="OpenSim.Region.CoreModules"/>
|
<Reference name="OpenSim.Region.CoreModules"/>
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||||
|
<Reference name="OpenSim.Region.Physics.Meshing" path="../../../../bin/Physics/"/>
|
||||||
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
|
<Reference name="OpenSim.Region.Physics.ConvexDecompositionDotNet"/>
|
||||||
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
|
<Reference name="BulletXNA.dll" path="../../../../bin/"/>
|
||||||
<Reference name="log4net.dll" path="../../../../bin/"/>
|
<Reference name="log4net.dll" path="../../../../bin/"/>
|
||||||
|
|
Loading…
Reference in New Issue