// creates and prepares a mesh to use and calls parameters estimation public bool CreateActorPhysRep(ODEPhysRepData 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.meshState = MeshState.MeshFailed; repData.hasOBB = false; repData.mesh = null; m_scene.mesher.ReleaseMesh(mesh); } else { repData.OBBOffset = mesh.GetCentroid(); repData.OBB = mesh.GetOBB(); repData.hasOBB = true; mesh.releaseSourceMeshData(); } } CalcVolumeData(repData); return(true); }
public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, ODEPhysRepData pRepData, ILog plog) { m_worker = pWorker; m_log = plog; repData = pRepData; repData.meshState = MeshState.AssetFailed; if (provider == null) { return; } if (repData.assetID == null) { return; } UUID assetID = (UUID)repData.assetID; if (assetID == UUID.Zero) { return; } repData.meshState = MeshState.loadingAsset; provider(assetID, ODEassetReceived); }
public ODEPhysRepData 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; CheckMesh(repData); CalcVolumeData(repData); m_scene.AddChange(actor, changes.AddPhysRep, repData); return(repData); }
public void AssetLoaded(ODEPhysRepData repData) { if (m_scene.haveActor(repData.actor)) { if (needsMeshing(repData)) // no need for pbs now? { repData.comand = meshWorkerCmnds.changefull; workQueue.Enqueue(repData); } } else { repData.pbs.SculptData = Utils.EmptyBytes; } }
private void CalcVolumeData(ODEPhysRepData repData) { if (repData.hasOBB) { Vector3 OBB = repData.OBB; } else { Vector3 OBB = repData.size; OBB.X *= 0.5f; OBB.Y *= 0.5f; OBB.Z *= 0.5f; repData.OBB = OBB; repData.OBBOffset = Vector3.Zero; } CalculateBasicPrimVolume(repData); }
public void DoRepDataGetMesh(ODEPhysRepData repData) { if (!repData.pbs.SculptEntry) { return; } if (repData.meshState != MeshState.loadingAsset) { return; } if (repData.assetID == null || repData.assetID == UUID.Zero) { return; } if (repData.assetID != repData.pbs.SculptTexture) { return; } // check if it is in cache GetMesh(repData); if (repData.meshState != MeshState.needAsset) { CreateActorPhysRep(repData); m_scene.AddChange(repData.actor, changes.PhysRepData, repData); return; } RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod; if (assetProvider == null) { return; } ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log); }
public void RequestMesh(ODEPhysRepData repData) { repData.mesh = null; if (repData.meshState == MeshState.needAsset) { PrimitiveBaseShape pbs = repData.pbs; // check if we got outdated if (!pbs.SculptEntry || pbs.SculptTexture == UUID.Zero) { repData.meshState = MeshState.noNeed; return; } repData.assetID = pbs.SculptTexture; repData.meshState = MeshState.loadingAsset; repData.comand = meshWorkerCmnds.getmesh; workQueue.Enqueue(repData); } }
private void DoWork() { m_mesher.ExpireFileCache(); while (m_running) { ODEPhysRepData nextRep = workQueue.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: GetMesh(nextRep); if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor)) { m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep); } break; case meshWorkerCmnds.getmesh: DoRepDataGetMesh(nextRep); break; } } } }
private void DoWork(object rep) { ODEPhysRepData nextRep = rep as ODEPhysRepData; if (m_running && nextRep != null && m_scene.haveActor(nextRep.actor)) { switch (nextRep.comand) { case meshWorkerCmnds.changefull: case meshWorkerCmnds.changeshapetype: case meshWorkerCmnds.changesize: GetMesh(nextRep); if (CreateActorPhysRep(nextRep) && m_scene.haveActor(nextRep.actor)) { m_scene.AddChange(nextRep.actor, changes.PhysRepData, nextRep); } break; case meshWorkerCmnds.getmesh: DoRepDataGetMesh(nextRep); break; } } }
private void CalculateBasicPrimVolume(ODEPhysRepData repData) { PrimitiveBaseShape _pbs = repData.pbs; Vector3 _size = repData.size; float volume = _size.X * _size.Y * _size.Z; // default float tmp; float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; float hollowVolume = hollowAmount * hollowAmount; switch (_pbs.ProfileShape) { case ProfileShape.Square: // default box if (_pbs.PathCurve == (byte)Extrusion.Straight) { if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f; break; case HollowShape.Triangle: hollowVolume *= (0.5f * .5f); break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { //a tube volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY); volume -= volume * tmp * tmp; if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f; break; case HollowShape.Triangle: hollowVolume *= 0.5f * 0.5f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.Circle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.78539816339f; // elipse base if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.5236f; if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Circle: case HollowShape.Triangle: // diference in sl is minor and odd case HollowShape.Same: break; case HollowShape.Square: hollowVolume *= 0.909f; break; // case HollowShape.Triangle: // hollowVolume *= .827f; // break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.EquilateralTriangle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.32475953f; if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: // Hollow shape is a perfect cyllinder in respect to the cube's scale // Cyllinder hollow volume calculation hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.32475953f; volume *= 0.01f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; default: break; } float taperX1; float taperY1; float taperX; float taperY; float pathBegin; float pathEnd; float profileBegin; float profileEnd; if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) { taperX1 = _pbs.PathScaleX * 0.01f; if (taperX1 > 1.0f) taperX1 = 2.0f - taperX1; taperX = 1.0f - taperX1; taperY1 = _pbs.PathScaleY * 0.01f; if (taperY1 > 1.0f) taperY1 = 2.0f - taperY1; taperY = 1.0f - taperY1; } else { taperX = _pbs.PathTaperX * 0.01f; if (taperX < 0.0f) taperX = -taperX; taperX1 = 1.0f - taperX; taperY = _pbs.PathTaperY * 0.01f; if (taperY < 0.0f) taperY = -taperY; taperY1 = 1.0f - taperY; } volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); pathBegin = (float)_pbs.PathBegin * 2.0e-5f; pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; volume *= (pathEnd - pathBegin); // this is crude aproximation profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; volume *= (profileEnd - profileBegin); repData.volume = volume; }
public ODEPhysRepData 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; CheckMesh(repData); CalcVolumeData(repData); m_scene.AddChange(actor, changes.AddPhysRep, repData); return repData; }
public void RequestMesh(ODEPhysRepData repData) { repData.mesh = null; if (repData.meshState == MeshState.needAsset) { PrimitiveBaseShape pbs = repData.pbs; // check if we got outdated if (!pbs.SculptEntry || pbs.SculptTexture == UUID.Zero) { repData.meshState = MeshState.noNeed; return; } repData.assetID = pbs.SculptTexture; repData.meshState = MeshState.loadingAsset; repData.comand = meshWorkerCmnds.getmesh; createqueue.Enqueue(repData); } }
public void GetMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; repData.mesh = null; repData.hasOBB = false; if (!needsMeshing(repData)) { repData.meshState = MeshState.noNeed; return; } if (repData.meshState == MeshState.MeshFailed) { return; } if (pbs.SculptEntry) { if (repData.meshState == MeshState.AssetFailed) { if (pbs.SculptTexture == repData.assetID) { return; } } } repData.meshState = MeshState.noNeed; IMesh mesh = null; Vector3 size = repData.size; byte shapetype = repData.shapetype; 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, true); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture == UUID.Zero) { return; } repData.assetID = pbs.SculptTexture; if (pbs.SculptData == null || pbs.SculptData.Length == 0) { repData.meshState = MeshState.needAsset; return; } } } repData.mesh = mesh; repData.pbs.SculptData = Utils.EmptyBytes; if (mesh == null) { if (pbs.SculptEntry) { repData.meshState = MeshState.AssetFailed; } else { repData.meshState = MeshState.MeshFailed; } return; } repData.meshState = MeshState.AssetOK; return; }
// creates and prepares a mesh to use and calls parameters estimation public bool CreateActorPhysRep(ODEPhysRepData 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.meshState = MeshState.MeshFailed; repData.hasOBB = false; repData.mesh = null; m_scene.mesher.ReleaseMesh(mesh); } else { repData.OBBOffset = mesh.GetCentroid(); repData.OBB = mesh.GetOBB(); repData.hasOBB = true; mesh.releaseSourceMeshData(); } } CalcVolumeData(repData); return true; }
/// <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(ODEPhysRepData repData) { PrimitiveBaseShape pbs = repData.pbs; // check sculpts or meshs Vector3 scale = pbs.Scale; if (scale.X <= MinSizeToMeshmerize && scale.Y <= MinSizeToMeshmerize && scale.Z <= MinSizeToMeshmerize) { repData.isTooSmall = true; return(false); } if (pbs.SculptEntry) { if (meshSculptedPrim) { return(true); } if (pbs.SculptType == (byte)SculptType.Mesh) // always do meshs { return(true); } return(false); } // convex shapes have no holes ushort profilehollow = pbs.ProfileHollow; if (repData.shapetype == 2) { profilehollow = 0; } // 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 && 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 (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 void GetMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; repData.mesh = null; repData.hasOBB = false; if (!needsMeshing(pbs)) { repData.meshState = MeshState.noNeed; return; } if (repData.meshState == MeshState.MeshFailed) return; if (pbs.SculptEntry) { if (repData.meshState == MeshState.AssetFailed) { if (pbs.SculptTexture == repData.assetID) return; } } repData.meshState = MeshState.noNeed; IMesh mesh = null; Vector3 size = repData.size; byte shapetype = repData.shapetype; 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, true); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture == UUID.Zero) return; repData.assetID = pbs.SculptTexture; if (pbs.SculptData == null || pbs.SculptData.Length == 0) { repData.meshState = MeshState.needAsset; return; } } } repData.mesh = mesh; repData.pbs.SculptData = Utils.EmptyBytes; if (mesh == null) { if (pbs.SculptEntry) repData.meshState = MeshState.AssetFailed; else repData.meshState = MeshState.MeshFailed; return; } repData.meshState = MeshState.AssetOK; return; }
// see if we need a mesh and if so if we have a cached one // called with a new repData public void CheckMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; if (!needsMeshing(pbs)) { repData.meshState = MeshState.noNeed; repData.hasOBB = false; return; } IMesh mesh = null; Vector3 size = repData.size; byte shapetype = repData.shapetype; 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.GetMesh(actor.Name, pbs, size, clod, true, convex); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero) { repData.assetID = pbs.SculptTexture; repData.meshState = MeshState.needAsset; } else repData.meshState = MeshState.MeshFailed; return; } else { repData.meshState = MeshState.needMesh; mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { repData.meshState = MeshState.MeshFailed; return; } } } repData.meshState = MeshState.AssetOK; repData.mesh = mesh; repData.OBB = mesh.GetOBB(); repData.OBBOffset = mesh.GetCentroid(); repData.hasOBB = true; if (pbs.SculptEntry) { repData.assetID = pbs.SculptTexture; } pbs.SculptData = Utils.EmptyBytes; return ; }
public void DoRepDataGetMesh(ODEPhysRepData repData) { if (!repData.pbs.SculptEntry) return; if (repData.meshState != MeshState.loadingAsset) return; if (repData.assetID == null || repData.assetID == UUID.Zero) return; if (repData.assetID != repData.pbs.SculptTexture) return; // check if it is in cache GetMesh(repData); if (repData.meshState != MeshState.needAsset) { CreateActorPhysRep(repData); m_scene.AddChange(repData.actor, changes.PhysRepData, repData); return; } RequestAssetDelegate assetProvider = m_scene.RequestAssetMethod; if (assetProvider == null) return; ODEAssetRequest asr = new ODEAssetRequest(this, assetProvider, repData, m_log); }
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); } } else repData.pbs.SculptData = Utils.EmptyBytes; }
// see if we need a mesh and if so if we have a cached one // called with a new repData public void CheckMesh(ODEPhysRepData repData) { PhysicsActor actor = repData.actor; PrimitiveBaseShape pbs = repData.pbs; if (!needsMeshing(repData)) { repData.meshState = MeshState.noNeed; repData.hasOBB = false; return; } IMesh mesh = null; Vector3 size = repData.size; int clod = (int)LevelOfDetail.High; byte shapetype = repData.shapetype; bool convex = shapetype == 2; mesh = m_mesher.GetMesh(actor.Name, pbs, size, clod, true, convex); if (mesh == null) { if (pbs.SculptEntry) { if (pbs.SculptTexture != null && pbs.SculptTexture != UUID.Zero) { repData.assetID = pbs.SculptTexture; repData.meshState = MeshState.needAsset; } else { repData.meshState = MeshState.MeshFailed; } return; } else { repData.meshState = MeshState.needMesh; mesh = m_mesher.CreateMesh(actor.Name, pbs, size, clod, true, convex, true); if (mesh == null) { repData.meshState = MeshState.MeshFailed; return; } } } repData.meshState = MeshState.AssetOK; repData.mesh = mesh; repData.OBB = mesh.GetOBB(); repData.OBBOffset = mesh.GetCentroid(); repData.hasOBB = true; if (pbs.SculptEntry) { repData.assetID = pbs.SculptTexture; } pbs.SculptData = Utils.EmptyBytes; return; }
private void CalculateBasicPrimVolume(ODEPhysRepData repData) { Vector3 _size = repData.size; float volume = _size.X * _size.Y * _size.Z; // default if (repData.isTooSmall) { repData.volume = volume; return; } PrimitiveBaseShape _pbs = repData.pbs; float tmp; float hollowAmount = (float)_pbs.ProfileHollow * 2.0e-5f; float hollowVolume = hollowAmount * hollowAmount; switch (_pbs.ProfileShape) { case ProfileShape.Square: // default box if (_pbs.PathCurve == (byte)Extrusion.Straight) { if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f; break; case HollowShape.Triangle: hollowVolume *= (0.5f * .5f); break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { //a tube volume *= 0.78539816339e-2f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - 2.0e-2f * (float)(200 - _pbs.PathScaleY); volume -= volume * tmp * tmp; if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Square: case HollowShape.Same: break; case HollowShape.Circle: hollowVolume *= 0.78539816339f; break; case HollowShape.Triangle: hollowVolume *= 0.5f * 0.5f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.Circle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.78539816339f; // elipse base if (hollowAmount > 0.0) { switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.61685027506808491367715568749226e-2f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Circle: break; case HollowShape.Square: hollowVolume *= 0.5f * 2.5984480504799f; break; case HollowShape.Triangle: hollowVolume *= .5f * 1.27323954473516f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.HalfCircle: if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.5236f; if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Circle: case HollowShape.Triangle: // diference in sl is minor and odd case HollowShape.Same: break; case HollowShape.Square: hollowVolume *= 0.909f; break; // case HollowShape.Triangle: // hollowVolume *= .827f; // break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; case ProfileShape.EquilateralTriangle: if (_pbs.PathCurve == (byte)Extrusion.Straight) { volume *= 0.32475953f; if (hollowAmount > 0.0) { // calculate the hollow volume by it's shape compared to the prim shape switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: // Hollow shape is a perfect cyllinder in respect to the cube's scale // Cyllinder hollow volume calculation hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } else if (_pbs.PathCurve == (byte)Extrusion.Curve1) { volume *= 0.32475953f; volume *= 0.01f * (float)(200 - _pbs.PathScaleX); tmp = 1.0f - .02f * (float)(200 - _pbs.PathScaleY); volume *= (1.0f - tmp * tmp); if (hollowAmount > 0.0) { hollowVolume *= hollowAmount; switch (_pbs.HollowShape) { case HollowShape.Same: case HollowShape.Triangle: hollowVolume *= .25f; break; case HollowShape.Square: hollowVolume *= 0.499849f * 3.07920140172638f; break; case HollowShape.Circle: hollowVolume *= 0.1963495f * 3.07920140172638f; break; default: hollowVolume = 0; break; } volume *= (1.0f - hollowVolume); } } break; default: break; } float taperX1; float taperY1; float taperX; float taperY; float pathBegin; float pathEnd; float profileBegin; float profileEnd; if (_pbs.PathCurve == (byte)Extrusion.Straight || _pbs.PathCurve == (byte)Extrusion.Flexible) { taperX1 = _pbs.PathScaleX * 0.01f; if (taperX1 > 1.0f) { taperX1 = 2.0f - taperX1; } taperX = 1.0f - taperX1; taperY1 = _pbs.PathScaleY * 0.01f; if (taperY1 > 1.0f) { taperY1 = 2.0f - taperY1; } taperY = 1.0f - taperY1; } else { taperX = _pbs.PathTaperX * 0.01f; if (taperX < 0.0f) { taperX = -taperX; } taperX1 = 1.0f - taperX; taperY = _pbs.PathTaperY * 0.01f; if (taperY < 0.0f) { taperY = -taperY; } taperY1 = 1.0f - taperY; } volume *= (taperX1 * taperY1 + 0.5f * (taperX1 * taperY + taperX * taperY1) + 0.3333333333f * taperX * taperY); pathBegin = (float)_pbs.PathBegin * 2.0e-5f; pathEnd = 1.0f - (float)_pbs.PathEnd * 2.0e-5f; volume *= (pathEnd - pathBegin); // this is crude aproximation profileBegin = (float)_pbs.ProfileBegin * 2.0e-5f; profileEnd = 1.0f - (float)_pbs.ProfileEnd * 2.0e-5f; volume *= (profileEnd - profileBegin); repData.volume = volume; }
public ODEAssetRequest(ODEMeshWorker pWorker, RequestAssetDelegate provider, ODEPhysRepData pRepData, ILog plog) { m_worker = pWorker; m_log = plog; repData = pRepData; repData.meshState = MeshState.AssetFailed; if (provider == null) return; if (repData.assetID == null) return; UUID assetID = (UUID) repData.assetID; if (assetID == UUID.Zero) return; repData.meshState = MeshState.loadingAsset; provider(assetID, ODEassetReceived); }
private void Enqueue(ODEPhysRepData rep) { workQueue.Enqueue(rep); }