[DANGER UNTESTED] ODE mesh assets. Other plugins will not do meshs/sculpts
nowavinationmerge
parent
5254c0de8f
commit
78ce7a0a04
|
@ -4299,8 +4299,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
SceneObjectPart[] parts = m_parts.GetArray();
|
SceneObjectPart[] parts = m_parts.GetArray();
|
||||||
|
|
||||||
for (int i = 0; i < parts.Length; i++)
|
// for (int i = 0; i < parts.Length; i++)
|
||||||
parts[i].CheckSculptAndLoad();
|
// parts[i].CheckSculptAndLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -1095,9 +1095,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
{
|
{
|
||||||
actor.Size = m_shape.Scale;
|
actor.Size = m_shape.Scale;
|
||||||
|
|
||||||
if (Shape.SculptEntry)
|
// if (Shape.SculptEntry)
|
||||||
CheckSculptAndLoad();
|
// CheckSculptAndLoad();
|
||||||
else
|
// else
|
||||||
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(actor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1654,8 +1654,8 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PhysActor.PhysicsShapeType = m_physicsShapeType;
|
PhysActor.PhysicsShapeType = m_physicsShapeType;
|
||||||
if (Shape.SculptEntry)
|
// if (Shape.SculptEntry)
|
||||||
CheckSculptAndLoad();
|
// CheckSculptAndLoad();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ParentGroup != null)
|
if (ParentGroup != null)
|
||||||
|
@ -2115,12 +2115,13 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
if (userExposed)
|
if (userExposed)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
|
if (dupe.m_shape.SculptEntry && dupe.m_shape.SculptTexture != UUID.Zero)
|
||||||
{
|
{
|
||||||
ParentGroup.Scene.AssetService.Get(
|
ParentGroup.Scene.AssetService.Get(
|
||||||
dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
|
dupe.m_shape.SculptTexture.ToString(), dupe, dupe.AssetReceived);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
|
bool UsePhysics = ((dupe.Flags & PrimFlags.Physics) != 0);
|
||||||
dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
|
dupe.DoPhysicsPropertyUpdate(UsePhysics, true);
|
||||||
// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
|
// dupe.UpdatePhysicsSubscribedEvents(); // not sure...
|
||||||
|
@ -2142,6 +2143,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <param name="id">ID of asset received</param>
|
/// <param name="id">ID of asset received</param>
|
||||||
/// <param name="sender">Register</param>
|
/// <param name="sender">Register</param>
|
||||||
/// <param name="asset"></param>
|
/// <param name="asset"></param>
|
||||||
|
/*
|
||||||
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
protected void AssetReceived(string id, Object sender, AssetBase asset)
|
||||||
{
|
{
|
||||||
if (asset != null)
|
if (asset != null)
|
||||||
|
@ -2151,7 +2153,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
|
// "[SCENE OBJECT PART]: Part {0} {1} requested mesh/sculpt data for asset id {2} from asset service but received no data",
|
||||||
// Name, UUID, id);
|
// Name, UUID, id);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Do a physics property update for a NINJA joint.
|
/// Do a physics property update for a NINJA joint.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -2341,9 +2343,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
|
|
||||||
// If this part is a sculpt then delay the physics update until we've asynchronously loaded the
|
// If this part is a sculpt then delay the physics update until we've asynchronously loaded the
|
||||||
// mesh data.
|
// mesh data.
|
||||||
if (Shape.SculptEntry)
|
// if (Shape.SculptEntry)
|
||||||
CheckSculptAndLoad();
|
// CheckSculptAndLoad();
|
||||||
else
|
// else
|
||||||
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
|
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3125,6 +3127,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// Set sculpt and mesh data, and tell the physics engine to process the change.
|
/// Set sculpt and mesh data, and tell the physics engine to process the change.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="texture">The mesh itself.</param>
|
/// <param name="texture">The mesh itself.</param>
|
||||||
|
/*
|
||||||
public void SculptTextureCallback(AssetBase texture)
|
public void SculptTextureCallback(AssetBase texture)
|
||||||
{
|
{
|
||||||
if (m_shape.SculptEntry)
|
if (m_shape.SculptEntry)
|
||||||
|
@ -3152,7 +3155,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Send a full update to the client for the given part
|
/// Send a full update to the client for the given part
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -4377,7 +4380,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
|
public void UpdateExtraParam(ushort type, bool inUse, byte[] data)
|
||||||
{
|
{
|
||||||
m_shape.ReadInUpdateExtraParam(type, inUse, data);
|
m_shape.ReadInUpdateExtraParam(type, inUse, data);
|
||||||
|
/*
|
||||||
if (type == 0x30)
|
if (type == 0x30)
|
||||||
{
|
{
|
||||||
if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
|
if (m_shape.SculptEntry && m_shape.SculptTexture != UUID.Zero)
|
||||||
|
@ -4385,7 +4388,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived);
|
ParentGroup.Scene.AssetService.Get(m_shape.SculptTexture.ToString(), this, AssetReceived);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
if (ParentGroup != null)
|
if (ParentGroup != null)
|
||||||
{
|
{
|
||||||
ParentGroup.HasGroupChanged = true;
|
ParentGroup.HasGroupChanged = true;
|
||||||
|
@ -4793,9 +4796,9 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Shape.SculptEntry)
|
// if (Shape.SculptEntry)
|
||||||
CheckSculptAndLoad();
|
// CheckSculptAndLoad();
|
||||||
else
|
// else
|
||||||
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
|
ParentGroup.Scene.PhysicsScene.AddPhysicsActorTaint(pa);
|
||||||
|
|
||||||
if (!building)
|
if (!building)
|
||||||
|
@ -4898,6 +4901,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
/// <remarks>
|
/// <remarks>
|
||||||
/// When the physics engine has finished with it, the sculpt data is discarded to save memory.
|
/// When the physics engine has finished with it, the sculpt data is discarded to save memory.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
/*
|
||||||
public void CheckSculptAndLoad()
|
public void CheckSculptAndLoad()
|
||||||
{
|
{
|
||||||
// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
|
// m_log.DebugFormat("Processing CheckSculptAndLoad for {0} {1}", Name, LocalId);
|
||||||
|
@ -4925,7 +4929,7 @@ namespace OpenSim.Region.Framework.Scenes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Update the texture entry for this part.
|
/// Update the texture entry for this part.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -74,10 +74,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
private const string baseDir = null; //"rawFiles";
|
private const string baseDir = null; //"rawFiles";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private bool cacheSculptMaps = true;
|
|
||||||
private bool cacheSculptAlphaMaps = true;
|
|
||||||
|
|
||||||
private string decodedSculptMapPath = null;
|
|
||||||
private bool useMeshiesPhysicsMesh = false;
|
private bool useMeshiesPhysicsMesh = false;
|
||||||
|
|
||||||
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
|
||||||
|
@ -92,29 +88,9 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
IConfig start_config = config.Configs["Startup"];
|
IConfig start_config = config.Configs["Startup"];
|
||||||
IConfig mesh_config = config.Configs["Mesh"];
|
IConfig mesh_config = config.Configs["Mesh"];
|
||||||
|
|
||||||
decodedSculptMapPath = start_config.GetString("DecodedSculptMapPath","j2kDecodeCache");
|
|
||||||
|
|
||||||
cacheSculptMaps = start_config.GetBoolean("CacheSculptMaps", cacheSculptMaps);
|
|
||||||
|
|
||||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
|
||||||
{
|
|
||||||
cacheSculptAlphaMaps = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
cacheSculptAlphaMaps = cacheSculptMaps;
|
|
||||||
|
|
||||||
if(mesh_config != null)
|
if(mesh_config != null)
|
||||||
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
useMeshiesPhysicsMesh = mesh_config.GetBoolean("UseMeshiesPhysicsMesh", useMeshiesPhysicsMesh);
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Directory.Exists(decodedSculptMapPath))
|
|
||||||
Directory.CreateDirectory(decodedSculptMapPath);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[SCULPT]: Unable to create {0} directory: ", decodedSculptMapPath, e.Message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -444,7 +420,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
// physics_shape is an array of OSDMaps, one for each submesh
|
// physics_shape is an array of OSDMaps, one for each submesh
|
||||||
if (decodedMeshOsd is OSDArray)
|
if (decodedMeshOsd is OSDArray)
|
||||||
{
|
{
|
||||||
// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
|
// Console.WriteLine("decodedMeshOsd for {0} - {1}", primName, Util.GetFormattedXml(decodedMeshOsd));
|
||||||
|
|
||||||
decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
|
decodedMeshOsdArray = (OSDArray)decodedMeshOsd;
|
||||||
foreach (OSD subMeshOsd in decodedMeshOsdArray)
|
foreach (OSD subMeshOsd in decodedMeshOsdArray)
|
||||||
|
@ -717,29 +693,7 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
faces = new List<Face>();
|
faces = new List<Face>();
|
||||||
PrimMesher.SculptMesh sculptMesh;
|
PrimMesher.SculptMesh sculptMesh;
|
||||||
Image idata = null;
|
Image idata = null;
|
||||||
string decodedSculptFileName = "";
|
|
||||||
|
|
||||||
if (cacheSculptMaps && primShape.SculptTexture != UUID.Zero)
|
|
||||||
{
|
|
||||||
decodedSculptFileName = System.IO.Path.Combine(decodedSculptMapPath, "smap_" + primShape.SculptTexture.ToString());
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (File.Exists(decodedSculptFileName))
|
|
||||||
{
|
|
||||||
idata = Image.FromFile(decodedSculptFileName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Error("[SCULPT]: unable to load cached sculpt map " + decodedSculptFileName + " " + e.Message);
|
|
||||||
|
|
||||||
}
|
|
||||||
//if (idata != null)
|
|
||||||
// m_log.Debug("[SCULPT]: loaded cached map asset for map ID: " + primShape.SculptTexture.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (idata == null)
|
|
||||||
{
|
|
||||||
if (primShape.SculptData == null || primShape.SculptData.Length == 0)
|
if (primShape.SculptData == null || primShape.SculptData.Length == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -748,25 +702,15 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
OpenMetaverse.Imaging.ManagedImage unusedData;
|
OpenMetaverse.Imaging.ManagedImage unusedData;
|
||||||
OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
|
OpenMetaverse.Imaging.OpenJPEG.DecodeToImage(primShape.SculptData, out unusedData, out idata);
|
||||||
|
|
||||||
|
unusedData = null;
|
||||||
|
|
||||||
if (idata == null)
|
if (idata == null)
|
||||||
{
|
{
|
||||||
// In some cases it seems that the decode can return a null bitmap without throwing
|
// In some cases it seems that the decode can return a null bitmap without throwing
|
||||||
// an exception
|
// an exception
|
||||||
m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
|
m_log.WarnFormat("[PHYSICS]: OpenJPEG decoded sculpt data for {0} to a null bitmap. Ignoring.", primName);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
unusedData = null;
|
|
||||||
|
|
||||||
//idata = CSJ2K.J2kImage.FromBytes(primShape.SculptData);
|
|
||||||
|
|
||||||
if (cacheSculptMaps && (cacheSculptAlphaMaps || (((ImageFlags)(idata.Flags) & ImageFlags.HasAlpha) ==0)))
|
|
||||||
// don't cache images with alpha channel in linux since mono can't load them correctly)
|
|
||||||
{
|
|
||||||
try { idata.Save(decodedSculptFileName, ImageFormat.MemoryBmp); }
|
|
||||||
catch (Exception e) { m_log.Error("[SCULPT]: unable to cache sculpt map " + decodedSculptFileName + " " + e.Message); }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (DllNotFoundException)
|
catch (DllNotFoundException)
|
||||||
{
|
{
|
||||||
|
@ -783,7 +727,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
|
m_log.Error("[PHYSICS]: Unable to generate a Sculpty physics proxy. Sculpty texture decode failed: " + ex.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
PrimMesher.SculptMesh.SculptType sculptType;
|
PrimMesher.SculptMesh.SculptType sculptType;
|
||||||
// remove mirror and invert bits
|
// remove mirror and invert bits
|
||||||
|
@ -1048,7 +991,6 @@ namespace OpenSim.Region.Physics.Meshing
|
||||||
return ((hash << 5) + hash) + (ulong)(c >> 8);
|
return ((hash << 5) + hash) + (ulong)(c >> 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
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,false);
|
return CreateMesh(primName, primShape, size, lod, false,false);
|
||||||
|
|
|
@ -172,7 +172,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// force lower density for testing
|
// force lower density for testing
|
||||||
m_density = 3.0f;
|
m_density = 3.0f;
|
||||||
|
|
||||||
|
|
||||||
mu = parent_scene.AvatarFriction;
|
mu = parent_scene.AvatarFriction;
|
||||||
|
|
||||||
walkDivisor = walk_divisor;
|
walkDivisor = walk_divisor;
|
||||||
|
|
|
@ -18,26 +18,63 @@ using OpenMetaverse;
|
||||||
|
|
||||||
namespace OpenSim.Region.Physics.OdePlugin
|
namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
|
public enum meshWorkerCmnds : byte
|
||||||
|
{
|
||||||
|
nop = 0,
|
||||||
|
addnew,
|
||||||
|
changefull,
|
||||||
|
changesize,
|
||||||
|
changeshapetype,
|
||||||
|
getmesh,
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ODEPhysRepData
|
||||||
|
{
|
||||||
|
public PhysicsActor actor;
|
||||||
|
public PrimitiveBaseShape pbs;
|
||||||
|
public IMesh mesh;
|
||||||
|
|
||||||
|
public Vector3 size;
|
||||||
|
public Vector3 OBB;
|
||||||
|
public Vector3 OBBOffset;
|
||||||
|
|
||||||
|
public float volume;
|
||||||
|
|
||||||
|
public float physCost;
|
||||||
|
public float streamCost;
|
||||||
|
public byte shapetype;
|
||||||
|
public bool hasOBB;
|
||||||
|
public bool hasMeshVolume;
|
||||||
|
public AssetState assetState;
|
||||||
|
public UUID? assetID;
|
||||||
|
public meshWorkerCmnds comand;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class ODEMeshWorker
|
public class ODEMeshWorker
|
||||||
{
|
{
|
||||||
|
|
||||||
private ILog m_log;
|
private ILog m_log;
|
||||||
private OdeScene m_scene;
|
private OdeScene m_scene;
|
||||||
private IMesher m_mesher;
|
private IMesher m_mesher;
|
||||||
|
|
||||||
|
|
||||||
public bool meshSculptedPrim = true;
|
public bool meshSculptedPrim = true;
|
||||||
public bool forceSimplePrimMeshing = false;
|
public bool forceSimplePrimMeshing = false;
|
||||||
public float meshSculptLOD = 32;
|
public float meshSculptLOD = 32;
|
||||||
public float MeshSculptphysicalLOD = 32;
|
public float MeshSculptphysicalLOD = 32;
|
||||||
|
|
||||||
private IntPtr m_workODEspace = IntPtr.Zero;
|
|
||||||
|
|
||||||
public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IntPtr pWorkSpace, IConfig pConfig)
|
private OpenSim.Framework.BlockingQueue<ODEPhysRepData> createqueue = new OpenSim.Framework.BlockingQueue<ODEPhysRepData>();
|
||||||
|
private bool m_running;
|
||||||
|
|
||||||
|
private Thread m_thread;
|
||||||
|
|
||||||
|
public ODEMeshWorker(OdeScene pScene, ILog pLog, IMesher pMesher, IConfig pConfig)
|
||||||
{
|
{
|
||||||
m_scene = pScene;
|
m_scene = pScene;
|
||||||
m_log = pLog;
|
m_log = pLog;
|
||||||
m_mesher = pMesher;
|
m_mesher = pMesher;
|
||||||
m_workODEspace = pWorkSpace;
|
|
||||||
|
|
||||||
if (pConfig != null)
|
if (pConfig != null)
|
||||||
{
|
{
|
||||||
|
@ -46,8 +83,177 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
|
meshSculptLOD = pConfig.GetFloat("mesh_lod", meshSculptLOD);
|
||||||
MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
|
MeshSculptphysicalLOD = pConfig.GetFloat("mesh_physical_lod", MeshSculptphysicalLOD);
|
||||||
}
|
}
|
||||||
|
m_running = true;
|
||||||
|
m_thread = new Thread(DoWork);
|
||||||
|
m_thread.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DoWork()
|
||||||
|
{
|
||||||
|
while(m_running)
|
||||||
|
{
|
||||||
|
ODEPhysRepData nextRep = createqueue.Dequeue();
|
||||||
|
if(!m_running)
|
||||||
|
return;
|
||||||
|
if (nextRep == null)
|
||||||
|
continue;
|
||||||
|
if (m_scene.haveActor(nextRep.actor))
|
||||||
|
{
|
||||||
|
switch (nextRep.comand)
|
||||||
|
{
|
||||||
|
case meshWorkerCmnds.changefull:
|
||||||
|
case meshWorkerCmnds.changeshapetype:
|
||||||
|
case meshWorkerCmnds.changesize:
|
||||||
|
if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor))
|
||||||
|
m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep);
|
||||||
|
break;
|
||||||
|
case meshWorkerCmnds.addnew:
|
||||||
|
if (CreateActorPhysRep(nextRep))
|
||||||
|
m_scene.AddChange(nextRep.actor, changes.AddPhysRep, nextRep);
|
||||||
|
break;
|
||||||
|
case meshWorkerCmnds.getmesh:
|
||||||
|
DoRepDataGetMesh(nextRep);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop()
|
||||||
|
{
|
||||||
|
m_running = false;
|
||||||
|
m_thread.Abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
|
||||||
|
Vector3 size, byte shapetype)
|
||||||
|
{
|
||||||
|
ODEPhysRepData repData = new ODEPhysRepData();
|
||||||
|
repData.actor = actor;
|
||||||
|
repData.pbs = pbs;
|
||||||
|
repData.size = size;
|
||||||
|
repData.shapetype = shapetype;
|
||||||
|
|
||||||
|
// if (CheckMeshDone(repData))
|
||||||
|
{
|
||||||
|
CheckMeshDone(repData);
|
||||||
|
CalcVolumeData(repData);
|
||||||
|
m_scene.AddChange(actor, changes.PhysRepData, repData);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// repData.comand = meshWorkerCmnds.changefull;
|
||||||
|
// createqueue.Enqueue(repData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NewActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
|
||||||
|
Vector3 size, byte shapetype)
|
||||||
|
{
|
||||||
|
ODEPhysRepData repData = new ODEPhysRepData();
|
||||||
|
repData.actor = actor;
|
||||||
|
repData.pbs = pbs;
|
||||||
|
repData.size = size;
|
||||||
|
repData.shapetype = shapetype;
|
||||||
|
|
||||||
|
// bool done = CheckMeshDone(repData);
|
||||||
|
|
||||||
|
CheckMeshDone(repData);
|
||||||
|
CalcVolumeData(repData);
|
||||||
|
m_scene.AddChange(actor, changes.AddPhysRep, repData);
|
||||||
|
// if (done)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// repData.comand = meshWorkerCmnds.addnew;
|
||||||
|
// createqueue.Enqueue(repData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RequestMeshAsset(ODEPhysRepData repData)
|
||||||
|
{
|
||||||
|
if (repData.assetState != AssetState.needAsset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (repData.assetID == null || repData.assetID == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
repData.mesh = null;
|
||||||
|
|
||||||
|
repData.assetState = AssetState.loadingAsset;
|
||||||
|
|
||||||
|
repData.comand = meshWorkerCmnds.getmesh;
|
||||||
|
createqueue.Enqueue(repData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CreateActorPhysRep(ODEPhysRepData repData)
|
||||||
|
{
|
||||||
|
getMesh(repData);
|
||||||
|
IMesh mesh = repData.mesh;
|
||||||
|
|
||||||
|
if (mesh != null)
|
||||||
|
{
|
||||||
|
IntPtr vertices, indices;
|
||||||
|
int vertexCount, indexCount;
|
||||||
|
int vertexStride, triStride;
|
||||||
|
|
||||||
|
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount);
|
||||||
|
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount);
|
||||||
|
|
||||||
|
if (vertexCount == 0 || indexCount == 0)
|
||||||
|
{
|
||||||
|
m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
|
||||||
|
repData.actor.Name, repData.pbs.SculptTexture.ToString());
|
||||||
|
repData.assetState = AssetState.AssetFailed;
|
||||||
|
repData.hasOBB = false;
|
||||||
|
repData.mesh = null;
|
||||||
|
m_scene.mesher.ReleaseMesh(mesh);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
repData.OBBOffset = mesh.GetCentroid();
|
||||||
|
repData.OBB = mesh.GetOBB();
|
||||||
|
repData.hasOBB = true;
|
||||||
|
repData.physCost = 0.0013f * (float)indexCount;
|
||||||
|
// todo
|
||||||
|
repData.streamCost = 1.0f;
|
||||||
|
mesh.releaseSourceMeshData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CalcVolumeData(repData);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AssetLoaded(ODEPhysRepData repData)
|
||||||
|
{
|
||||||
|
if (m_scene.haveActor(repData.actor))
|
||||||
|
{
|
||||||
|
if (needsMeshing(repData.pbs)) // no need for pbs now?
|
||||||
|
{
|
||||||
|
repData.comand = meshWorkerCmnds.changefull;
|
||||||
|
createqueue.Enqueue(repData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void DoRepDataGetMesh(ODEPhysRepData repData)
|
||||||
|
{
|
||||||
|
if (!repData.pbs.SculptEntry)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (repData.assetState != AssetState.loadingAsset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (repData.assetID == null || repData.assetID == UUID.Zero)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (repData.assetID != repData.pbs.SculptTexture)
|
||||||
|
return;
|
||||||
|
|
||||||
|
RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
|
||||||
|
if (assetProvider == null)
|
||||||
|
return;
|
||||||
|
ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Routine to figure out if we need to mesh this prim with our mesher
|
/// Routine to figure out if we need to mesh this prim with our mesher
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -169,194 +375,151 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IMesh getMesh(PhysicsActor actor, PrimitiveBaseShape ppbs, Vector3 psize, byte pshapetype)
|
public bool CheckMeshDone(ODEPhysRepData repData)
|
||||||
{
|
{
|
||||||
if (!(actor is OdePrim))
|
PhysicsActor actor = repData.actor;
|
||||||
return null;
|
PrimitiveBaseShape pbs = repData.pbs;
|
||||||
|
|
||||||
|
repData.mesh = null;
|
||||||
|
repData.hasOBB = false;
|
||||||
|
|
||||||
|
if (!needsMeshing(pbs))
|
||||||
|
{
|
||||||
|
repData.assetState = AssetState.noNeedAsset;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pbs.SculptEntry)
|
||||||
|
{
|
||||||
|
if (repData.assetState == AssetState.AssetFailed)
|
||||||
|
{
|
||||||
|
if (pbs.SculptTexture == repData.assetID)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
repData.assetState = AssetState.noNeedAsset;
|
||||||
|
repData.assetID = null;
|
||||||
|
}
|
||||||
|
|
||||||
IMesh mesh = null;
|
IMesh mesh = null;
|
||||||
PrimitiveBaseShape pbs = ppbs;
|
|
||||||
Vector3 size = psize;
|
|
||||||
byte shapetype = pshapetype;
|
|
||||||
|
|
||||||
if (needsMeshing(pbs))
|
Vector3 size = repData.size;
|
||||||
|
byte shapetype = repData.shapetype;
|
||||||
|
|
||||||
|
bool convex;
|
||||||
|
|
||||||
|
int clod = (int)LevelOfDetail.High;
|
||||||
|
if (shapetype == 0)
|
||||||
|
convex = false;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
bool convex;
|
convex = true;
|
||||||
int clod = (int)LevelOfDetail.High;
|
if (pbs.SculptType != (byte)SculptType.Mesh)
|
||||||
if (shapetype == 0)
|
clod = (int)LevelOfDetail.Low;
|
||||||
convex = false;
|
}
|
||||||
else
|
mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
|
||||||
|
if (mesh == null)
|
||||||
|
{
|
||||||
|
if (pbs.SculptEntry)
|
||||||
{
|
{
|
||||||
convex = true;
|
if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero)
|
||||||
if (pbs.SculptType != (byte)SculptType.Mesh)
|
{
|
||||||
clod = (int)LevelOfDetail.Low;
|
repData.assetID = pbs.SculptTexture;
|
||||||
}
|
repData.assetState = AssetState.needAsset;
|
||||||
mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
|
|
||||||
if (mesh == null)
|
|
||||||
{
|
|
||||||
if (!pbs.SculptEntry)
|
|
||||||
return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
|
|
||||||
|
|
||||||
if (pbs.SculptTexture == UUID.Zero)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
if (pbs.SculptType != (byte)SculptType.Mesh)
|
|
||||||
{ // check for sculpt decoded image on cache)
|
|
||||||
if (File.Exists(System.IO.Path.Combine("j2kDecodeCache", "smap_" + pbs.SculptTexture.ToString())))
|
|
||||||
return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (pbs.SculptData != null && pbs.SculptData.Length > 0)
|
repData.assetState = AssetState.AssetFailed;
|
||||||
return m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
|
|
||||||
|
|
||||||
ODEAssetRequest asr;
|
|
||||||
RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod;
|
|
||||||
if (assetProvider != null)
|
|
||||||
asr = new ODEAssetRequest(this, assetProvider, actor, pbs, m_log);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return mesh;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool GetTriMeshGeo(ODEPhysRepData repData)
|
|
||||||
{
|
|
||||||
IntPtr vertices, indices;
|
|
||||||
IntPtr triMeshData = IntPtr.Zero;
|
|
||||||
IntPtr geo = IntPtr.Zero;
|
|
||||||
int vertexCount, indexCount;
|
|
||||||
int vertexStride, triStride;
|
|
||||||
|
|
||||||
PhysicsActor actor = repData.actor;
|
|
||||||
|
|
||||||
IMesh mesh = repData.mesh;
|
|
||||||
|
|
||||||
if (mesh == null)
|
|
||||||
{
|
|
||||||
mesh = getMesh(repData.actor, repData.pbs, repData.size, repData.shapetype);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh == null)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
mesh.getVertexListAsPtrToFloatArray(out vertices, out vertexStride, out vertexCount); // Note, that vertices are fixed in unmanaged heap
|
|
||||||
mesh.getIndexListAsPtrToIntArray(out indices, out triStride, out indexCount); // Also fixed, needs release after usage
|
|
||||||
|
|
||||||
if (vertexCount == 0 || indexCount == 0)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[PHYSICS]: Invalid mesh data on prim {0} mesh UUID {1}",
|
|
||||||
actor.Name, repData.pbs.SculptTexture.ToString());
|
|
||||||
mesh.releaseSourceMeshData();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
repData.OBBOffset = mesh.GetCentroid();
|
repData.mesh = mesh;
|
||||||
repData.OBB = mesh.GetOBB();
|
if (pbs.SculptEntry)
|
||||||
repData.hasOBB = true;
|
|
||||||
repData.physCost = 0.0013f * (float)indexCount;
|
|
||||||
|
|
||||||
mesh.releaseSourceMeshData();
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
{
|
||||||
triMeshData = d.GeomTriMeshDataCreate();
|
repData.assetState = AssetState.AssetOK;
|
||||||
|
repData.assetID = pbs.SculptTexture;
|
||||||
d.GeomTriMeshDataBuildSimple(triMeshData, vertices, vertexStride, vertexCount, indices, indexCount, triStride);
|
pbs.SculptData = Utils.EmptyBytes;
|
||||||
d.GeomTriMeshDataPreprocess(triMeshData);
|
|
||||||
|
|
||||||
m_scene.waitForSpaceUnlock(m_workODEspace);
|
|
||||||
geo = d.CreateTriMesh(m_workODEspace, triMeshData, null, null, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.ErrorFormat("[PHYSICS]: SetGeom Mesh failed for {0} exception: {1}", actor.Name, e);
|
|
||||||
if (triMeshData != IntPtr.Zero)
|
|
||||||
{
|
|
||||||
d.GeomTriMeshDataDestroy(triMeshData);
|
|
||||||
repData.triMeshData = IntPtr.Zero;
|
|
||||||
}
|
|
||||||
repData.geo = IntPtr.Zero;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
repData.geo = geo;
|
|
||||||
repData.triMeshData = triMeshData;
|
|
||||||
repData.curSpace = m_workODEspace;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ODEPhysRepData CreateActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs, IMesh pMesh, Vector3 size, byte shapetype)
|
|
||||||
|
public bool getMesh(ODEPhysRepData repData)
|
||||||
{
|
{
|
||||||
ODEPhysRepData repData = new ODEPhysRepData();
|
PhysicsActor actor = repData.actor;
|
||||||
|
|
||||||
repData.actor = actor;
|
PrimitiveBaseShape pbs = repData.pbs;
|
||||||
repData.pbs = pbs;
|
|
||||||
repData.mesh = pMesh;
|
|
||||||
repData.size = size;
|
|
||||||
repData.shapetype = shapetype;
|
|
||||||
|
|
||||||
IntPtr geo = IntPtr.Zero;
|
repData.mesh = null;
|
||||||
bool hasMesh = false;
|
repData.hasOBB = false;
|
||||||
if (needsMeshing(pbs))
|
|
||||||
|
if (!needsMeshing(pbs))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (pbs.SculptEntry)
|
||||||
{
|
{
|
||||||
if (GetTriMeshGeo(repData))
|
if (repData.assetState == AssetState.AssetFailed)
|
||||||
hasMesh = true;
|
{
|
||||||
else
|
if (pbs.SculptTexture == repData.assetID)
|
||||||
repData.NoColide = true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hasMesh)
|
repData.assetState = AssetState.noNeedAsset;
|
||||||
|
|
||||||
|
IMesh mesh = null;
|
||||||
|
Vector3 size = repData.size;
|
||||||
|
byte shapetype = repData.shapetype;
|
||||||
|
|
||||||
|
bool convex;
|
||||||
|
int clod = (int)LevelOfDetail.High;
|
||||||
|
if (shapetype == 0)
|
||||||
|
convex = false;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1
|
convex = true;
|
||||||
&& size.X == size.Y && size.Y == size.Z)
|
if (pbs.SculptType != (byte)SculptType.Mesh)
|
||||||
{ // it's a sphere
|
clod = (int)LevelOfDetail.Low;
|
||||||
m_scene.waitForSpaceUnlock(m_workODEspace);
|
}
|
||||||
try
|
mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex);
|
||||||
|
if (mesh == null)
|
||||||
|
{
|
||||||
|
if (pbs.SculptEntry)
|
||||||
|
{
|
||||||
|
if (pbs.SculptTexture == UUID.Zero)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
repData.assetID = pbs.SculptTexture;
|
||||||
|
repData.assetState = AssetState.AssetOK;
|
||||||
|
|
||||||
|
if (pbs.SculptData == null || pbs.SculptData.Length == 0)
|
||||||
{
|
{
|
||||||
geo = d.CreateSphere(m_workODEspace, size.X * 0.5f);
|
repData.assetState = AssetState.needAsset;
|
||||||
}
|
return false;
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.WarnFormat("[PHYSICS]: Create sphere failed: {0}", e);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{// do it as a box
|
|
||||||
m_scene.waitForSpaceUnlock(m_workODEspace);
|
|
||||||
try
|
|
||||||
{
|
|
||||||
//Console.WriteLine(" CreateGeom 4");
|
|
||||||
geo = d.CreateBox(m_workODEspace, size.X, size.Y, size.Z);
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
m_log.Warn("[PHYSICS]: Create box failed: {0}", e);
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repData.physCost = 0.1f;
|
mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex);
|
||||||
repData.streamCost = 1.0f;
|
|
||||||
repData.geo = geo;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repData.curSpace = m_workODEspace;
|
|
||||||
|
|
||||||
CalcVolumeData(repData);
|
repData.mesh = mesh;
|
||||||
|
repData.pbs.SculptData = Utils.EmptyBytes;
|
||||||
|
|
||||||
return repData;
|
if (mesh == null)
|
||||||
}
|
{
|
||||||
|
if (pbs.SculptEntry)
|
||||||
|
repData.assetState = AssetState.AssetFailed;
|
||||||
|
|
||||||
public void ChangeActorPhysRep(PhysicsActor actor, PrimitiveBaseShape pbs,
|
return false;
|
||||||
Vector3 size, byte shapetype, MeshWorkerChange what)
|
}
|
||||||
{
|
|
||||||
ODEPhysRepData repData = CreateActorPhysRep(actor, pbs, null, size, shapetype);
|
if (pbs.SculptEntry)
|
||||||
repData.changed |= what;
|
repData.assetState = AssetState.AssetOK;
|
||||||
if (repData != null && actor != null)
|
|
||||||
((OdePrim)actor).AddChange(changes.PhysRepData, repData);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalculateBasicPrimVolume(ODEPhysRepData repData)
|
private void CalculateBasicPrimVolume(ODEPhysRepData repData)
|
||||||
|
@ -662,46 +825,12 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
private void CalcVolumeData(ODEPhysRepData repData)
|
private void CalcVolumeData(ODEPhysRepData repData)
|
||||||
{
|
{
|
||||||
float volume;
|
|
||||||
Vector3 OBB = repData.size;
|
|
||||||
Vector3 OBBoffset;
|
|
||||||
IntPtr geo = repData.geo;
|
|
||||||
|
|
||||||
if (geo == IntPtr.Zero || repData.triMeshData == IntPtr.Zero)
|
|
||||||
{
|
|
||||||
OBB.X *= 0.5f;
|
|
||||||
OBB.Y *= 0.5f;
|
|
||||||
OBB.Z *= 0.5f;
|
|
||||||
|
|
||||||
repData.OBB = OBB;
|
|
||||||
repData.OBBOffset = Vector3.Zero;
|
|
||||||
}
|
|
||||||
else if (!repData.hasOBB) // should this happen?
|
|
||||||
{
|
|
||||||
d.AABB AABB;
|
|
||||||
d.GeomGetAABB(geo, out AABB); // get the AABB from engine geom
|
|
||||||
|
|
||||||
OBB.X = (AABB.MaxX - AABB.MinX) * 0.5f;
|
|
||||||
OBB.Y = (AABB.MaxY - AABB.MinY) * 0.5f;
|
|
||||||
OBB.Z = (AABB.MaxZ - AABB.MinZ) * 0.5f;
|
|
||||||
repData.OBB = OBB;
|
|
||||||
OBBoffset.X = (AABB.MaxX + AABB.MinX) * 0.5f;
|
|
||||||
OBBoffset.Y = (AABB.MaxY + AABB.MinY) * 0.5f;
|
|
||||||
OBBoffset.Z = (AABB.MaxZ + AABB.MinZ) * 0.5f;
|
|
||||||
repData.OBBOffset = Vector3.Zero;
|
|
||||||
}
|
|
||||||
|
|
||||||
// also its own inertia and mass
|
|
||||||
// keep using basic shape mass for now
|
|
||||||
CalculateBasicPrimVolume(repData);
|
|
||||||
|
|
||||||
if (repData.hasOBB)
|
if (repData.hasOBB)
|
||||||
{
|
{
|
||||||
OBB = repData.OBB;
|
Vector3 OBB = repData.OBB;
|
||||||
float pc = repData.physCost;
|
float pc = repData.physCost;
|
||||||
float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
|
float psf = OBB.X * (OBB.Y + OBB.Z) + OBB.Y * OBB.Z;
|
||||||
psf *= 1.33f * .2f;
|
psf *= 1.33f * .2f;
|
||||||
|
|
||||||
pc *= psf;
|
pc *= psf;
|
||||||
if (pc < 0.1f)
|
if (pc < 0.1f)
|
||||||
pc = 0.1f;
|
pc = 0.1f;
|
||||||
|
@ -709,54 +838,79 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
repData.physCost = pc;
|
repData.physCost = pc;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
Vector3 OBB = repData.size;
|
||||||
|
OBB.X *= 0.5f;
|
||||||
|
OBB.Y *= 0.5f;
|
||||||
|
OBB.Z *= 0.5f;
|
||||||
|
|
||||||
|
repData.OBB = OBB;
|
||||||
|
repData.OBBOffset = Vector3.Zero;
|
||||||
|
|
||||||
repData.physCost = 0.1f;
|
repData.physCost = 0.1f;
|
||||||
|
repData.streamCost = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
CalculateBasicPrimVolume(repData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ODEAssetRequest
|
public class ODEAssetRequest
|
||||||
{
|
{
|
||||||
PhysicsActor m_actor;
|
|
||||||
ODEMeshWorker m_worker;
|
ODEMeshWorker m_worker;
|
||||||
PrimitiveBaseShape m_pbs;
|
|
||||||
private ILog m_log;
|
private ILog m_log;
|
||||||
|
ODEPhysRepData repData;
|
||||||
|
|
||||||
public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
|
public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider,
|
||||||
PhysicsActor pActor, PrimitiveBaseShape ppbs, ILog plog)
|
ODEPhysRepData pRepData, ILog plog)
|
||||||
{
|
{
|
||||||
m_actor = pActor;
|
|
||||||
m_worker = pWorker;
|
m_worker = pWorker;
|
||||||
m_pbs = ppbs;
|
|
||||||
m_log = plog;
|
m_log = plog;
|
||||||
|
repData = pRepData;
|
||||||
|
|
||||||
|
repData.assetState = AssetState.AssetFailed;
|
||||||
if (provider == null)
|
if (provider == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
UUID assetID = m_pbs.SculptTexture;
|
if (repData.assetID == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
UUID assetID = (UUID) repData.assetID;
|
||||||
if (assetID == UUID.Zero)
|
if (assetID == UUID.Zero)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
repData.assetState = AssetState.loadingAsset;
|
||||||
provider(assetID, ODEassetReceived);
|
provider(assetID, ODEassetReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ODEassetReceived(AssetBase asset)
|
void ODEassetReceived(AssetBase asset)
|
||||||
{
|
{
|
||||||
if (m_actor != null && m_pbs != null)
|
repData.assetState = AssetState.AssetFailed;
|
||||||
|
if (asset != null)
|
||||||
{
|
{
|
||||||
if (asset != null)
|
if (asset.Data != null && asset.Data.Length > 0)
|
||||||
{
|
{
|
||||||
if (asset.Data != null && asset.Data.Length > 0)
|
if (!repData.pbs.SculptEntry)
|
||||||
{
|
return;
|
||||||
m_pbs.SculptData = asset.Data;
|
if (repData.pbs.SculptTexture != repData.assetID)
|
||||||
m_actor.Shape = m_pbs;
|
return;
|
||||||
}
|
|
||||||
else
|
// asset get may return a pointer to the same asset data
|
||||||
m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
|
// for similar prims and we destroy with it
|
||||||
m_actor.Name, asset.ID.ToString());
|
// so waste a lot of time stressing gc and hoping it clears things
|
||||||
|
// TODO avoid this
|
||||||
|
repData.pbs.SculptData = new byte[asset.Data.Length];
|
||||||
|
asset.Data.CopyTo(repData.pbs.SculptData,0);
|
||||||
|
repData.assetState = AssetState.AssetOK;
|
||||||
|
m_worker.AssetLoaded(repData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
|
m_log.WarnFormat("[PHYSICS]: asset provider returned invalid mesh data for prim {0} asset UUID {1}.",
|
||||||
m_actor.Name);
|
repData.actor.Name, asset.ID.ToString());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
m_log.WarnFormat("[PHYSICS]: asset provider returned null asset fo mesh of prim {0}.",
|
||||||
|
repData.actor.Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -60,29 +60,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public int lastframe;
|
public int lastframe;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ODEPhysRepData
|
|
||||||
{
|
|
||||||
public PhysicsActor actor;
|
|
||||||
public IntPtr geo = IntPtr.Zero;
|
|
||||||
public IntPtr triMeshData = IntPtr.Zero;
|
|
||||||
public IMesh mesh;
|
|
||||||
public IntPtr curSpace = IntPtr.Zero;
|
|
||||||
public PrimitiveBaseShape pbs;
|
|
||||||
|
|
||||||
public Vector3 size = Vector3.Zero;
|
|
||||||
public Vector3 OBB = Vector3.Zero;
|
|
||||||
public Vector3 OBBOffset = Vector3.Zero;
|
|
||||||
|
|
||||||
public float volume;
|
|
||||||
|
|
||||||
public float physCost = 0.0f;
|
|
||||||
public float streamCost = 0;
|
|
||||||
public MeshWorkerChange changed;
|
|
||||||
public byte shapetype = 0;
|
|
||||||
public bool NoColide = false;
|
|
||||||
public bool hasOBB = false;
|
|
||||||
public bool hasMeshVolume = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// colision flags of things others can colide with
|
// colision flags of things others can colide with
|
||||||
// rays, sensors, probes removed since can't be colided with
|
// rays, sensors, probes removed since can't be colided with
|
||||||
|
@ -133,13 +110,16 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
|
|
||||||
light = 7 // compatibility with old viewers
|
light = 7 // compatibility with old viewers
|
||||||
}
|
}
|
||||||
[Flags]
|
|
||||||
public enum MeshWorkerChange : uint
|
public enum AssetState : byte
|
||||||
{
|
{
|
||||||
none = 0,
|
noNeedAsset = 0,
|
||||||
size = 1,
|
needAsset = 1,
|
||||||
shape = 2,
|
loadingAsset = 2,
|
||||||
shapetype = 3,
|
procAsset = 3,
|
||||||
|
AssetOK = 4,
|
||||||
|
|
||||||
|
AssetFailed = 0xff
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum changes : int
|
public enum changes : int
|
||||||
|
@ -180,6 +160,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
Size,
|
Size,
|
||||||
Shape,
|
Shape,
|
||||||
PhysRepData,
|
PhysRepData,
|
||||||
|
AddPhysRep,
|
||||||
|
|
||||||
CollidesWater,
|
CollidesWater,
|
||||||
VolumeDtc,
|
VolumeDtc,
|
||||||
|
@ -330,7 +311,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
public IntPtr TopSpace; // the global space
|
public IntPtr TopSpace; // the global space
|
||||||
public IntPtr ActiveSpace; // space for active prims
|
public IntPtr ActiveSpace; // space for active prims
|
||||||
public IntPtr StaticSpace; // space for the static things around
|
public IntPtr StaticSpace; // space for the static things around
|
||||||
public IntPtr WorkSpace; // no collisions work space
|
|
||||||
|
|
||||||
// some speedup variables
|
// some speedup variables
|
||||||
private int spaceGridMaxX;
|
private int spaceGridMaxX;
|
||||||
|
@ -342,7 +322,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
private IntPtr[] staticPrimspaceOffRegion;
|
private IntPtr[] staticPrimspaceOffRegion;
|
||||||
|
|
||||||
public Object OdeLock;
|
public Object OdeLock;
|
||||||
private static Object SimulationLock;
|
public static Object SimulationLock;
|
||||||
|
|
||||||
public IMesher mesher;
|
public IMesher mesher;
|
||||||
|
|
||||||
|
@ -403,7 +383,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
// now the major subspaces
|
// now the major subspaces
|
||||||
ActiveSpace = d.HashSpaceCreate(TopSpace);
|
ActiveSpace = d.HashSpaceCreate(TopSpace);
|
||||||
StaticSpace = d.HashSpaceCreate(TopSpace);
|
StaticSpace = d.HashSpaceCreate(TopSpace);
|
||||||
WorkSpace = d.HashSpaceCreate(TopSpace);
|
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
|
@ -413,12 +392,10 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
d.HashSpaceSetLevels(TopSpace, -2, 8);
|
d.HashSpaceSetLevels(TopSpace, -2, 8);
|
||||||
d.HashSpaceSetLevels(ActiveSpace, -2, 8);
|
d.HashSpaceSetLevels(ActiveSpace, -2, 8);
|
||||||
d.HashSpaceSetLevels(StaticSpace, -2, 8);
|
d.HashSpaceSetLevels(StaticSpace, -2, 8);
|
||||||
d.HashSpaceSetLevels(WorkSpace, -2, 8);
|
|
||||||
|
|
||||||
// demote to second level
|
// demote to second level
|
||||||
d.SpaceSetSublevel(ActiveSpace, 1);
|
d.SpaceSetSublevel(ActiveSpace, 1);
|
||||||
d.SpaceSetSublevel(StaticSpace, 1);
|
d.SpaceSetSublevel(StaticSpace, 1);
|
||||||
d.SpaceSetSublevel(WorkSpace, 1);
|
|
||||||
|
|
||||||
d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
|
d.GeomSetCategoryBits(ActiveSpace, (uint)(CollisionCategories.Space |
|
||||||
CollisionCategories.Geom |
|
CollisionCategories.Geom |
|
||||||
|
@ -436,8 +413,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
));
|
));
|
||||||
d.GeomSetCollideBits(StaticSpace, 0);
|
d.GeomSetCollideBits(StaticSpace, 0);
|
||||||
|
|
||||||
d.GeomSetCategoryBits(WorkSpace, 0);
|
|
||||||
d.GeomSetCollideBits(WorkSpace, 0);
|
|
||||||
|
|
||||||
contactgroup = d.JointGroupCreate(0);
|
contactgroup = d.JointGroupCreate(0);
|
||||||
//contactgroup
|
//contactgroup
|
||||||
|
@ -518,7 +493,7 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_meshWorker = new ODEMeshWorker(this, m_log, meshmerizer, WorkSpace, physicsconfig);
|
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);
|
||||||
|
@ -1316,6 +1291,15 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
_collisionEventPrimRemove.Add(obj);
|
_collisionEventPrimRemove.Add(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override float TimeDilation
|
||||||
|
{
|
||||||
|
get { return m_timeDilation; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool SupportsNINJAJoints
|
||||||
|
{
|
||||||
|
get { return false; }
|
||||||
|
}
|
||||||
|
|
||||||
#region Add/Remove Entities
|
#region Add/Remove Entities
|
||||||
|
|
||||||
|
@ -1371,59 +1355,6 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
((OdeCharacter) actor).Destroy();
|
((OdeCharacter) actor).Destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
|
|
||||||
PrimitiveBaseShape pbs, bool isphysical, uint localID)
|
|
||||||
{
|
|
||||||
Vector3 pos = position;
|
|
||||||
Vector3 siz = size;
|
|
||||||
Quaternion rot = rotation;
|
|
||||||
|
|
||||||
OdePrim newPrim;
|
|
||||||
lock (OdeLock)
|
|
||||||
{
|
|
||||||
newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical,false,0,localID);
|
|
||||||
|
|
||||||
lock (_prims)
|
|
||||||
_prims.Add(newPrim);
|
|
||||||
}
|
|
||||||
return newPrim;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
|
|
||||||
PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, uint localID)
|
|
||||||
{
|
|
||||||
Vector3 pos = position;
|
|
||||||
Vector3 siz = size;
|
|
||||||
Quaternion rot = rotation;
|
|
||||||
|
|
||||||
OdePrim newPrim;
|
|
||||||
lock (OdeLock)
|
|
||||||
{
|
|
||||||
newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, 0, localID);
|
|
||||||
|
|
||||||
lock (_prims)
|
|
||||||
_prims.Add(newPrim);
|
|
||||||
}
|
|
||||||
return newPrim;
|
|
||||||
}
|
|
||||||
|
|
||||||
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
|
|
||||||
PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
|
|
||||||
{
|
|
||||||
Vector3 pos = position;
|
|
||||||
Vector3 siz = size;
|
|
||||||
Quaternion rot = rotation;
|
|
||||||
|
|
||||||
OdePrim newPrim;
|
|
||||||
lock (OdeLock)
|
|
||||||
{
|
|
||||||
newPrim = new OdePrim(name, this, pos, siz, rot, pbs, isphysical, isPhantom, shapeType, localID);
|
|
||||||
|
|
||||||
lock (_prims)
|
|
||||||
_prims.Add(newPrim);
|
|
||||||
}
|
|
||||||
return newPrim;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addActivePrim(OdePrim activatePrim)
|
public void addActivePrim(OdePrim activatePrim)
|
||||||
{
|
{
|
||||||
|
@ -1444,44 +1375,39 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
|
||||||
|
PrimitiveBaseShape pbs, bool isphysical, bool isPhantom, byte shapeType, uint localID)
|
||||||
|
{
|
||||||
|
OdePrim newPrim;
|
||||||
|
lock (OdeLock)
|
||||||
|
{
|
||||||
|
newPrim = new OdePrim(name, this, position, size, rotation, pbs, isphysical, isPhantom, shapeType, localID);
|
||||||
|
lock (_prims)
|
||||||
|
_prims.Add(newPrim);
|
||||||
|
}
|
||||||
|
return newPrim;
|
||||||
|
}
|
||||||
|
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
|
Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, uint localid)
|
||||||
{
|
{
|
||||||
return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, localid);
|
return AddPrim(primName, position, size, rotation, pbs, isPhysical, isPhantom, 0 , localid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
|
Vector3 size, Quaternion rotation, bool isPhysical, uint localid)
|
||||||
{
|
{
|
||||||
#if SPAM
|
return AddPrim(primName, position, size, rotation, pbs, isPhysical,false, 0, localid);
|
||||||
m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return AddPrim(primName, position, size, rotation, pbs, isPhysical, localid);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
public override PhysicsActor AddPrimShape(string primName, PrimitiveBaseShape pbs, Vector3 position,
|
||||||
Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
|
Vector3 size, Quaternion rotation, bool isPhysical, bool isPhantom, byte shapeType, uint localid)
|
||||||
{
|
{
|
||||||
#if SPAM
|
|
||||||
m_log.DebugFormat("[PHYSICS]: Adding physics actor to {0}", primName);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
|
return AddPrim(primName, position, size, rotation, pbs, isPhysical,isPhantom, shapeType, localid);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override float TimeDilation
|
|
||||||
{
|
|
||||||
get { return m_timeDilation; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool SupportsNINJAJoints
|
|
||||||
{
|
|
||||||
get { return false; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void remActivePrim(OdePrim deactivatePrim)
|
public void remActivePrim(OdePrim deactivatePrim)
|
||||||
{
|
{
|
||||||
lock (_activeprims)
|
lock (_activeprims)
|
||||||
|
@ -1534,6 +1460,28 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool havePrim(OdePrim prm)
|
||||||
|
{
|
||||||
|
lock (_prims)
|
||||||
|
return _prims.Contains(prm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool haveActor(PhysicsActor actor)
|
||||||
|
{
|
||||||
|
if (actor is OdePrim)
|
||||||
|
{
|
||||||
|
lock (_prims)
|
||||||
|
return _prims.Contains((OdePrim)actor);
|
||||||
|
}
|
||||||
|
else if (actor is OdeCharacter)
|
||||||
|
{
|
||||||
|
lock (_characters)
|
||||||
|
return _characters.Contains((OdeCharacter)actor);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Space Separation Calculation
|
#region Space Separation Calculation
|
||||||
|
@ -1706,20 +1654,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
{
|
{
|
||||||
if (world == IntPtr.Zero)
|
if (world == IntPtr.Zero)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
d.WorldSetQuickStepNumIterations(world, curphysiteractions);
|
||||||
|
|
||||||
// adjust number of iterations per step
|
|
||||||
|
|
||||||
// try
|
|
||||||
// {
|
|
||||||
d.WorldSetQuickStepNumIterations(world, curphysiteractions);
|
|
||||||
/* }
|
|
||||||
catch (StackOverflowException)
|
|
||||||
{
|
|
||||||
m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation. Restarting the sim.");
|
|
||||||
// ode.drelease(world);
|
|
||||||
base.TriggerPhysicsBasedRestart();
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
|
while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -1747,8 +1684,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
{
|
{
|
||||||
m_log.Warn("[PHYSICS]: doChange failed for a actor");
|
m_log.WarnFormat("[PHYSICS]: doChange failed for a actor {0} {1}",
|
||||||
};
|
item.actor.Name, item.what.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
|
ttmp = Util.EnvironmentTickCountSubtract(ttmpstart);
|
||||||
if (ttmp > 20)
|
if (ttmp > 20)
|
||||||
|
@ -2491,6 +2429,9 @@ namespace OpenSim.Region.Physics.OdePlugin
|
||||||
*/
|
*/
|
||||||
public override void Dispose()
|
public override void Dispose()
|
||||||
{
|
{
|
||||||
|
if (m_meshWorker != null)
|
||||||
|
m_meshWorker.Stop();
|
||||||
|
|
||||||
lock (OdeLock)
|
lock (OdeLock)
|
||||||
{
|
{
|
||||||
m_rayCastManager.Dispose();
|
m_rayCastManager.Dispose();
|
||||||
|
|
Loading…
Reference in New Issue