introduce a ODEMeshWorker class, should be pure cosmetic changes for now

avinationmerge
UbitUmarov 2012-10-03 19:33:28 +01:00
parent f433ee317b
commit 7137b234b4
7 changed files with 262 additions and 163 deletions

View File

@ -37,7 +37,8 @@ namespace OpenSim.Region.Physics.Manager
{ {
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod);
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical);
IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical,bool convex); IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex);
IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex);
void ReleaseMesh(IMesh mesh); void ReleaseMesh(IMesh mesh);
void ExpireReleaseMeshs(); void ExpireReleaseMeshs();
} }

View File

@ -79,6 +79,12 @@ namespace OpenSim.Region.Physics.Manager
return null; return null;
} }
public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
{
return null;
}
public void ReleaseMesh(IMesh mesh) { } public void ReleaseMesh(IMesh mesh) { }
public void ExpireReleaseMeshs() { } public void ExpireReleaseMeshs() { }
} }

View File

@ -763,6 +763,11 @@ namespace OpenSim.Region.Physics.Meshing
return mesh; return mesh;
} }
public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
{
return null;
}
public void ReleaseMesh(IMesh imesh) { } public void ReleaseMesh(IMesh imesh) { }
public void ExpireReleaseMeshs() { } public void ExpireReleaseMeshs() { }
} }

View File

@ -1061,6 +1061,42 @@ namespace OpenSim.Region.Physics.Meshing
private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f); private static Vector3 m_MeshUnitSize = new Vector3(0.5f, 0.5f, 0.5f);
public IMesh GetMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
{
Mesh mesh = null;
if (size.X < 0.01f) size.X = 0.01f;
if (size.Y < 0.01f) size.Y = 0.01f;
if (size.Z < 0.01f) size.Z = 0.01f;
AMeshKey key = GetMeshUniqueKey(primShape, size, (byte)lod, convex);
lock (m_uniqueMeshes)
{
m_uniqueMeshes.TryGetValue(key, out mesh);
if (mesh != null)
{
mesh.RefCount++;
return mesh;
}
}
// try to find a identical mesh on meshs recently released
lock (m_uniqueReleasedMeshes)
{
m_uniqueReleasedMeshes.TryGetValue(key, out mesh);
if (mesh != null)
{
m_uniqueReleasedMeshes.Remove(key);
lock (m_uniqueMeshes)
m_uniqueMeshes.Add(key, mesh);
mesh.RefCount = 1;
return mesh;
}
}
return null;
}
public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex) public IMesh CreateMesh(String primName, PrimitiveBaseShape primShape, Vector3 size, float lod, bool isPhysical, bool convex)
{ {
#if SPAM #if SPAM
@ -1068,15 +1104,13 @@ namespace OpenSim.Region.Physics.Meshing
#endif #endif
Mesh mesh = null; Mesh mesh = null;
// ulong key = 0;
if (size.X < 0.01f) size.X = 0.01f; if (size.X < 0.01f) size.X = 0.01f;
if (size.Y < 0.01f) size.Y = 0.01f; if (size.Y < 0.01f) size.Y = 0.01f;
if (size.Z < 0.01f) size.Z = 0.01f; if (size.Z < 0.01f) size.Z = 0.01f;
// try to find a identical mesh on meshs in use // try to find a identical mesh on meshs in use
// key = primShape.GetMeshKey(size, lod, convex);
AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex); AMeshKey key = GetMeshUniqueKey(primShape,size,(byte)lod, convex);
lock (m_uniqueMeshes) lock (m_uniqueMeshes)

View File

@ -0,0 +1,199 @@
/*
* AJLDuarte 2012
*/
using System;
using System.Threading;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using OpenSim.Framework;
using OpenSim.Region.Physics.Manager;
using OdeAPI;
using log4net;
using Nini.Config;
using OpenMetaverse;
namespace OpenSim.Region.Physics.OdePlugin
{
public class ODEMeshWorker
{
private ILog m_log;
private OdeScene m_scene;
private IMesher m_mesher;
public bool meshSculptedPrim = true;
public bool forceSimplePrimMeshing = false;
public float meshSculptLOD = 32;
public float MeshSculptphysicalLOD = 32;
public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
{
m_scene = pScene;
m_log = pLog;
m_mesher = pMesher;
if (pConfig != null)
{
forceSimplePrimMeshing = pConfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
meshSculptedPrim = pConfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
}
}
/// <summary>
/// Routine to figure out if we need to mesh this prim with our mesher
/// </summary>
/// <param name="pbs"></param>
/// <returns></returns>
public bool needsMeshing(PrimitiveBaseShape pbs)
{
// check sculpts or meshs
if (pbs.SculptEntry)
{
if (meshSculptedPrim)
return true;
if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
return true;
return false;
}
if (forceSimplePrimMeshing)
return true;
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
{
if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
&& pbs.ProfileHollow == 0
&& pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
&& pbs.PathBegin == 0 && pbs.PathEnd == 0
&& pbs.PathTaperX == 0 && pbs.PathTaperY == 0
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
&& pbs.PathShearX == 0 && pbs.PathShearY == 0)
{
return false;
}
}
// following code doesn't give meshs to boxes and spheres ever
// and it's odd.. so for now just return true if asked to force meshs
// hopefully mesher will fail if doesn't suport so things still get basic boxes
int iPropertiesNotSupportedDefault = 0;
if (pbs.ProfileHollow != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
iPropertiesNotSupportedDefault++;
if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
iPropertiesNotSupportedDefault++;
if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
iPropertiesNotSupportedDefault++;
// test for torus
if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
{
if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
{
if (pbs.PathCurve == (byte)Extrusion.Straight)
{
iPropertiesNotSupportedDefault++;
}
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
{
if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
{
if (pbs.PathCurve == (byte)Extrusion.Straight)
{
iPropertiesNotSupportedDefault++;
}
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
if (iPropertiesNotSupportedDefault == 0)
{
return false;
}
return true;
}
public IMesh getMesh(PhysicsActor actor, PrimitiveBaseShape ppbs, Vector3 psize, byte pshapetype)
{
if (!(actor is OdePrim))
return null;
IMesh mesh = null;
PrimitiveBaseShape pbs = ppbs;
Vector3 size = psize;
byte shapetype = pshapetype;
if (needsMeshing(pbs) && (pbs.SculptData.Length > 0))
{
bool convex;
int clod = (int)LevelOfDetail.High;
if (shapetype == 0)
convex = false;
else
{
convex = true;
if (pbs.SculptType != (byte)SculptType.Mesh)
clod = (int)LevelOfDetail.Low;
}
mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
if(mesh == null)
mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
}
return mesh;
}
}
}

View File

@ -1080,7 +1080,7 @@ namespace OpenSim.Region.Physics.OdePlugin
bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce; bounce = parent_scene.m_materialContactsData[(int)Material.Wood].bounce;
CalcPrimBodyData(); CalcPrimBodyData();
/*
m_mesh = null; m_mesh = null;
if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0)) if (_parent_scene.needsMeshing(pbs) && (pbs.SculptData.Length > 0))
{ {
@ -1096,6 +1096,8 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex); m_mesh = _parent_scene.mesher.CreateMesh(Name, _pbs, _size, clod, true, convex);
} }
*/
m_mesh = _parent_scene.m_meshWorker.getMesh(this, pbs, _size, m_shapetype);
m_building = true; // control must set this to false when done m_building = true; // control must set this to false when done
@ -1476,7 +1478,7 @@ namespace OpenSim.Region.Physics.OdePlugin
hasOOBoffsetFromMesh = false; hasOOBoffsetFromMesh = false;
m_NoColide = false; m_NoColide = false;
if (_parent_scene.needsMeshing(_pbs)) if (_parent_scene.m_meshWorker.needsMeshing(_pbs))
{ {
haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims haveMesh = setMesh(_parent_scene); // this will give a mesh to non trivial known prims
if (!haveMesh) if (!haveMesh)

View File

@ -230,11 +230,6 @@ namespace OpenSim.Region.Physics.OdePlugin
private float minimumGroundFlightOffset = 3f; private float minimumGroundFlightOffset = 3f;
public float maximumMassObject = 10000.01f; public float maximumMassObject = 10000.01f;
public bool meshSculptedPrim = true;
public bool forceSimplePrimMeshing = false;
public float meshSculptLOD = 32;
public float MeshSculptphysicalLOD = 32;
public float geomDefaultDensity = 10.000006836f; public float geomDefaultDensity = 10.000006836f;
@ -328,7 +323,7 @@ namespace OpenSim.Region.Physics.OdePlugin
private PhysicsScene m_parentScene = null; private PhysicsScene m_parentScene = null;
private ODERayCastRequestManager m_rayCastManager; private ODERayCastRequestManager m_rayCastManager;
public ODEMeshWorker m_meshWorker;
/* maybe needed if ode uses tls /* maybe needed if ode uses tls
private void checkThread() private void checkThread()
@ -361,6 +356,8 @@ namespace OpenSim.Region.Physics.OdePlugin
nearCallback = near; nearCallback = near;
m_rayCastManager = new ODERayCastRequestManager(this); m_rayCastManager = new ODERayCastRequestManager(this);
lock (OdeLock) lock (OdeLock)
{ {
// Create the world and the first space // Create the world and the first space
@ -440,9 +437,11 @@ namespace OpenSim.Region.Physics.OdePlugin
int contactsPerCollision = 80; int contactsPerCollision = 80;
IConfig physicsconfig = null;
if (m_config != null) if (m_config != null)
{ {
IConfig physicsconfig = m_config.Configs["ODEPhysicsSettings"]; physicsconfig = m_config.Configs["ODEPhysicsSettings"];
if (physicsconfig != null) if (physicsconfig != null)
{ {
gravityx = physicsconfig.GetFloat("world_gravityx", gravityx); gravityx = physicsconfig.GetFloat("world_gravityx", gravityx);
@ -469,27 +468,7 @@ namespace OpenSim.Region.Physics.OdePlugin
geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity); geomDefaultDensity = physicsconfig.GetFloat("geometry_default_density", geomDefaultDensity);
bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable); bodyFramesAutoDisable = physicsconfig.GetInt("body_frames_auto_disable", bodyFramesAutoDisable);
/*
bodyPIDD = physicsconfig.GetFloat("body_pid_derivative", bodyPIDD);
bodyPIDG = physicsconfig.GetFloat("body_pid_gain", bodyPIDG);
*/
forceSimplePrimMeshing = physicsconfig.GetBoolean("force_simple_prim_meshing", forceSimplePrimMeshing);
meshSculptedPrim = physicsconfig.GetBoolean("mesh_sculpted_prim", meshSculptedPrim);
meshSculptLOD = physicsconfig.GetFloat("mesh_lod", meshSculptLOD);
MeshSculptphysicalLOD = physicsconfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
/*
if (Environment.OSVersion.Platform == PlatformID.Unix)
{
avPIDD = physicsconfig.GetFloat("av_pid_derivative_linux", avPIDD);
avPIDP = physicsconfig.GetFloat("av_pid_proportional_linux", avPIDP);
}
else
{
avPIDD = physicsconfig.GetFloat("av_pid_derivative_win", avPIDD);
avPIDP = physicsconfig.GetFloat("av_pid_proportional_win", avPIDP);
}
*/
physics_logging = physicsconfig.GetBoolean("physics_logging", false); physics_logging = physicsconfig.GetBoolean("physics_logging", false);
physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0); physics_logging_interval = physicsconfig.GetInt("physics_logging_interval", 0);
physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false); physics_logging_append_existing_logfile = physicsconfig.GetBoolean("physics_logging_append_existing_logfile", false);
@ -499,6 +478,8 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
} }
m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, physicsconfig);
HalfOdeStep = ODE_STEPSIZE * 0.5f; HalfOdeStep = ODE_STEPSIZE * 0.5f;
odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f); odetimestepMS = (int)(1000.0f * ODE_STEPSIZE +0.5f);
@ -1615,135 +1596,6 @@ namespace OpenSim.Region.Physics.OdePlugin
#endregion #endregion
/// <summary>
/// Routine to figure out if we need to mesh this prim with our mesher
/// </summary>
/// <param name="pbs"></param>
/// <returns></returns>
public bool needsMeshing(PrimitiveBaseShape pbs)
{
// check sculpts or meshs
if (pbs.SculptEntry)
{
if (meshSculptedPrim)
return true;
if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs
return true;
return false;
}
if (forceSimplePrimMeshing)
return true;
// if it's a standard box or sphere with no cuts, hollows, twist or top shear, return false since ODE can use an internal representation for the prim
if ((pbs.ProfileShape == ProfileShape.Square && pbs.PathCurve == (byte)Extrusion.Straight)
|| (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
&& pbs.Scale.X == pbs.Scale.Y && pbs.Scale.Y == pbs.Scale.Z))
{
if (pbs.ProfileBegin == 0 && pbs.ProfileEnd == 0
&& pbs.ProfileHollow == 0
&& pbs.PathTwist == 0 && pbs.PathTwistBegin == 0
&& pbs.PathBegin == 0 && pbs.PathEnd == 0
&& pbs.PathTaperX == 0 && pbs.PathTaperY == 0
&& pbs.PathScaleX == 100 && pbs.PathScaleY == 100
&& pbs.PathShearX == 0 && pbs.PathShearY == 0)
{
#if SPAM
m_log.Warn("NonMesh");
#endif
return false;
}
}
// following code doesn't give meshs to boxes and spheres ever
// and it's odd.. so for now just return true if asked to force meshs
// hopefully mesher will fail if doesn't suport so things still get basic boxes
int iPropertiesNotSupportedDefault = 0;
if (pbs.ProfileHollow != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathBegin != 0) || pbs.PathEnd != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathTwistBegin != 0) || (pbs.PathTwist != 0))
iPropertiesNotSupportedDefault++;
if ((pbs.ProfileBegin != 0) || pbs.ProfileEnd != 0)
iPropertiesNotSupportedDefault++;
if ((pbs.PathScaleX != 100) || (pbs.PathScaleY != 100))
iPropertiesNotSupportedDefault++;
if ((pbs.PathShearX != 0) || (pbs.PathShearY != 0))
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1 && (pbs.Scale.X != pbs.Scale.Y || pbs.Scale.Y != pbs.Scale.Z || pbs.Scale.Z != pbs.Scale.X))
iPropertiesNotSupportedDefault++;
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte) Extrusion.Curve1)
iPropertiesNotSupportedDefault++;
// test for torus
if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Square)
{
if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.Circle)
{
if (pbs.PathCurve == (byte)Extrusion.Straight)
{
iPropertiesNotSupportedDefault++;
}
// ProfileCurve seems to combine hole shape and profile curve so we need to only compare against the lower 3 bits
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.HalfCircle)
{
if (pbs.PathCurve == (byte)Extrusion.Curve1 || pbs.PathCurve == (byte)Extrusion.Curve2)
{
iPropertiesNotSupportedDefault++;
}
}
else if ((pbs.ProfileCurve & 0x07) == (byte)ProfileShape.EquilateralTriangle)
{
if (pbs.PathCurve == (byte)Extrusion.Straight)
{
iPropertiesNotSupportedDefault++;
}
else if (pbs.PathCurve == (byte)Extrusion.Curve1)
{
iPropertiesNotSupportedDefault++;
}
}
if (iPropertiesNotSupportedDefault == 0)
{
#if SPAM
m_log.Warn("NonMesh");
#endif
return false;
}
#if SPAM
m_log.Debug("Mesh");
#endif
return true;
}
/// <summary> /// <summary>
/// Called to queue a change to a actor /// Called to queue a change to a actor