* ODEPlugin

** Added more realistic calculations of mass for the rest of the supported prim shapes+holes+cuts+tapers.  Previously they were the generic height * width * length. Spheres roll (Angular velocity) more realistically, etc.
0.6.0-stable
Teravus Ovares 2008-02-29 05:46:24 +00:00
parent de1024adf7
commit e333eaf4b6
3 changed files with 227 additions and 16 deletions

View File

@ -45,8 +45,8 @@ namespace OpenSim.Region.Environment.Modules
private List<Scene> m_scene = new List<Scene>(); private List<Scene> m_scene = new List<Scene>();
Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>(); Dictionary<LLUUID, ulong> m_rootAgents = new Dictionary<LLUUID, ulong>();
Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>(); Dictionary<LLUUID, LLUUID> m_pendingFriendRequests = new Dictionary<LLUUID, LLUUID>();
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
@ -66,9 +66,6 @@ namespace OpenSim.Region.Environment.Modules
scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
scene.EventManager.OnMakeChildAgent += MakeChildAgent; scene.EventManager.OnMakeChildAgent += MakeChildAgent;
scene.EventManager.OnClientClosed += ClientLoggedOut; scene.EventManager.OnClientClosed += ClientLoggedOut;
} }
public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req) public XmlRpcResponse processPresenceUpdate(XmlRpcRequest req)
{ {
@ -90,10 +87,6 @@ namespace OpenSim.Region.Environment.Modules
client.OnDenyFriendRequest += OnDenyFriendRequest; client.OnDenyFriendRequest += OnDenyFriendRequest;
client.OnTerminateFriendship += OnTerminateFriendship; client.OnTerminateFriendship += OnTerminateFriendship;
} }
private void ClientLoggedOut(LLUUID AgentId) private void ClientLoggedOut(LLUUID AgentId)
@ -146,7 +139,7 @@ namespace OpenSim.Region.Environment.Modules
} }
} }
#region FriendRequestHandling
private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID, private void OnInstantMessage(IClientAPI client,LLUUID fromAgentID,
LLUUID fromAgentSession, LLUUID toAgentID, LLUUID fromAgentSession, LLUUID toAgentID,
LLUUID imSessionID, uint timestamp, string fromAgentName, LLUUID imSessionID, uint timestamp, string fromAgentName,
@ -293,7 +286,7 @@ namespace OpenSim.Region.Environment.Modules
new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID), new LLVector3(msg.Position.x, msg.Position.y, msg.Position.z), new LLUUID(msg.RegionID),
msg.binaryBucket); msg.binaryBucket);
} }
#endregion
private ScenePresence GetPresenceFromAgentID(LLUUID AgentID) private ScenePresence GetPresenceFromAgentID(LLUUID AgentID)
{ {
ScenePresence returnAgent = null; ScenePresence returnAgent = null;

View File

@ -26,27 +26,39 @@
* *
*/ */
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using libsecondlife; using libsecondlife;
using Nini.Config; using Nini.Config;
using Nwc.XmlRpc;
using OpenSim.Framework; using OpenSim.Framework;
using OpenSim.Framework.Console; using OpenSim.Framework.Console;
using OpenSim.Region.Environment.Interfaces; using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Scenes; using OpenSim.Region.Environment.Scenes;
namespace OpenSim.Region.Environment.Modules namespace OpenSim.Region.Environment.Modules
{ {
public class InstantMessageModule : IRegionModule public class InstantMessageModule : IRegionModule
{ {
private List<Scene> m_scenes = new List<Scene>(); private List<Scene> m_scenes = new List<Scene>();
private Hashtable m_RegionInfoCache = new Hashtable();
public void Initialise(Scene scene, IConfigSource config) public void Initialise(Scene scene, IConfigSource config)
{ {
if (!m_scenes.Contains(scene)) lock (m_scenes)
{ {
m_scenes.Add(scene); if (m_scenes.Count == 0)
scene.EventManager.OnNewClient += OnNewClient; {
scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage; //scene.AddXmlRPCHandler("avatar_location_update", processPresenceUpdate);
}
if (!m_scenes.Contains(scene))
{
m_scenes.Add(scene);
scene.EventManager.OnNewClient += OnNewClient;
scene.EventManager.OnGridInstantMessageToIMModule += OnGridInstantMessage;
}
} }
} }

View File

@ -353,6 +353,176 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
break; break;
case ProfileShape.Circle:
if (_pbs.PathCurve == (byte)Extrusion.Straight)
{
// Cylinder
float volume1 = (float)(Math.PI * Math.Pow(_size.X, 2) * _size.Z);
float volume2 = (float)(Math.PI * Math.Pow(_size.Y, 2) * _size.Z);
// Approximating the cylinder's irregularity.
if (volume1 > volume2)
{
volume = (float)volume1 - (volume1 - volume2);
}
else if (volume2 > volume1)
{
volume = (float)volume2 - (volume2 - volume1);
}
else
{
// Regular cylinder
volume = volume1;
}
}
else
{
// We don't know what the shape is yet, so use default
volume = _size.X * _size.Y * _size.Z;
}
// If the user has 'hollowed out'
// ProfileHollow is one of those 0 to 50000 values :P
// we like percentages better.. so turning into a percentage
if (((float)_pbs.ProfileHollow / 50000f) > 0.0)
{
float hollowAmount = (float)_pbs.ProfileHollow / 50000f;
// calculate the hollow volume by it's shape compared to the prim shape
float hollowVolume = 0;
switch (_pbs.HollowShape)
{
case HollowShape.Same:
case HollowShape.Circle:
// Hollow shape is a perfect cyllinder in respect to the cube's scale
// Cyllinder hollow volume calculation
float hRadius = _size.X / 2;
float hLength = _size.Z;
// pi * r2 * h
hollowVolume = ((float)(Math.PI * Math.Pow(hRadius, 2) * hLength) * hollowAmount);
break;
case HollowShape.Square:
// Cube Hollow volume calculation
float hollowsizex = _size.X * hollowAmount;
float hollowsizey = _size.Y * hollowAmount;
float hollowsizez = _size.Z * hollowAmount;
hollowVolume = hollowsizex * hollowsizey * hollowsizez;
break;
case HollowShape.Triangle:
// Equilateral Triangular Prism volume hollow calculation
// Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
float aLength = _size.Y;
// 1/2 abh
hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
break;
default:
hollowVolume = 0;
break;
}
volume = volume - hollowVolume;
}
break;
case ProfileShape.HalfCircle:
if (_pbs.PathCurve == (byte)Extrusion.Curve1)
{
if (_size.X == _size.Z && _size.Z == _size.X)
{
// regular sphere
// v = 4/3 * pi * r^3
float sradius3 = (float)Math.Pow((_size.X / 2), 3);
volume = (float)((4 / 3) * Math.PI * sradius3);
}
else
{
// we treat this as a box currently
volume = _size.X * _size.Y * _size.Z;
}
}
else
{
// We don't know what the shape is yet, so use default
volume = _size.X * _size.Y * _size.Z;
}
break;
case ProfileShape.EquilateralTriangle:
/*
v = (abs((xB*yA-xA*yB)+(xC*yB-xB*yC)+(xA*yC-xC*yA))/2) * h
// seed mesh
Vertex MM = new Vertex(-0.25f, -0.45f, 0.0f);
Vertex PM = new Vertex(+0.5f, 0f, 0.0f);
Vertex PP = new Vertex(-0.25f, +0.45f, 0.0f);
*/
float xA = -0.25f * _size.X;
float yA = -0.45f * _size.Y;
float xB = 0.5f * _size.X;
float yB = 0;
float xC = -0.25f * _size.X;
float yC = 0.45f * _size.Y;
volume = (float)((Math.Abs((xB * yA - xA * yB) + (xC * yB - xB * yC) + (xA * yC - xC * yA)) / 2) * _size.Z);
// If the user has 'hollowed out'
// ProfileHollow is one of those 0 to 50000 values :P
// we like percentages better.. so turning into a percentage
float fhollowFactor = ((float)_pbs.ProfileHollow / 1.9f);
if (((float)fhollowFactor / 50000f) > 0.0)
{
float hollowAmount = (float)fhollowFactor / 50000f;
// calculate the hollow volume by it's shape compared to the prim shape
float hollowVolume = 0;
switch (_pbs.HollowShape)
{
case HollowShape.Same:
case HollowShape.Triangle:
// Equilateral Triangular Prism volume hollow calculation
// Triangle is an Equilateral Triangular Prism with aLength = to _size.Y
float aLength = _size.Y;
// 1/2 abh
hollowVolume = (float)((0.5 * aLength * _size.X * _size.Z) * hollowAmount);
break;
case HollowShape.Square:
// Cube Hollow volume calculation
float hollowsizex = _size.X * hollowAmount;
float hollowsizey = _size.Y * hollowAmount;
float hollowsizez = _size.Z * hollowAmount;
hollowVolume = hollowsizex * hollowsizey * hollowsizez;
break;
case HollowShape.Circle:
// Hollow shape is a perfect cyllinder in respect to the cube's scale
// Cyllinder hollow volume calculation
float hRadius = _size.X / 2;
float hLength = _size.Z;
// pi * r2 * h
hollowVolume = ((float)((Math.PI * Math.Pow(hRadius, 2) * hLength)/2) * hollowAmount);
break;
default:
hollowVolume = 0;
break;
}
volume = volume - hollowVolume;
}
break;
default: default:
// we don't have all of the volume formulas yet so // we don't have all of the volume formulas yet so
@ -383,9 +553,41 @@ namespace OpenSim.Region.Physics.OdePlugin
volume = volume - (volume*pathCutAmount); volume = volume - (volume*pathCutAmount);
} }
UInt16 taperX = _pbs.PathScaleX;
UInt16 taperY = _pbs.PathScaleY;
float taperFactorX = 0;
float taperFactorY = 0;
// Mass = density * volume // Mass = density * volume
if (taperX != 100)
{
if (taperX > 100)
{
taperFactorX = 1.0f - ((float)taperX / 200);
//m_log.Warn("taperTopFactorX: " + extr.taperTopFactorX.ToString());
}
else
{
taperFactorX = 1.0f - ((100 - (float)taperX) / 100);
//m_log.Warn("taperBotFactorX: " + extr.taperBotFactorX.ToString());
}
volume = (float)volume * ((taperFactorX / 3f) + 0.001f);
}
if (taperY != 100)
{
if (taperY > 100)
{
taperFactorY = 1.0f - ((float)taperY / 200);
//m_log.Warn("taperTopFactorY: " + extr.taperTopFactorY.ToString());
}
else
{
taperFactorY = 1.0f - ((100 - (float)taperY) / 100);
//m_log.Warn("taperBotFactorY: " + extr.taperBotFactorY.ToString());
}
volume = (float)volume * ((taperFactorY / 3f) + 0.001f);
}
returnMass = m_density*volume; returnMass = m_density*volume;
return returnMass; return returnMass;
@ -395,7 +597,11 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
if (Body != (IntPtr) 0) if (Body != (IntPtr) 0)
{ {
d.MassSetBoxTotal(out pMass, CalculateMass(), _size.X, _size.Y, _size.Z); float newmass = CalculateMass();
m_log.Info("[PHYSICS]: New Mass: " + newmass.ToString());
if (newmass <= 0) newmass = 0.0001f;
d.MassSetBoxTotal(out pMass, newmass, _size.X, _size.Y, _size.Z);
d.BodySetMass(Body, ref pMass); d.BodySetMass(Body, ref pMass);
} }
} }