Exemplo n.º 1
0
        // 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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
 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;
     }
 }
Exemplo n.º 5
0
        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);
        }
Exemplo n.º 6
0
        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);
        }
Exemplo n.º 7
0
        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);
            }
        }
Exemplo n.º 8
0
        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;
                    }
                }
            }
        }
Exemplo n.º 9
0
        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;
                }
            }
        }
Exemplo n.º 10
0
        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;
        }
Exemplo n.º 11
0
        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;
        }
Exemplo n.º 12
0
        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);
            }
        }
Exemplo n.º 13
0
        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;
        }
Exemplo n.º 14
0
        // 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;
        }
Exemplo n.º 15
0
        /// <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);
        }
Exemplo n.º 16
0
        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;
        }
Exemplo n.º 17
0
        // 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 ;
        }
Exemplo n.º 18
0
        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);
        }
Exemplo n.º 19
0
 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;
 }
Exemplo n.º 20
0
        // 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;
        }
Exemplo n.º 21
0
        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);
        }
Exemplo n.º 22
0
        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;
        }
Exemplo n.º 23
0
        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);
        }
Exemplo n.º 24
0
 private void Enqueue(ODEPhysRepData rep)
 {
     workQueue.Enqueue(rep);
 }