private bool TryGetConvexShapeFromMesh(PrimitivePhysicsShapeType physicsShape, ObjectPart.PrimitiveShape shape, out PhysicsShapeReference physicshaperef)
        {
            PhysicsConvexShape    physicshape;
            PhysicsShapeReference physicshaperes = null;
            UUID meshId = shape.SculptMap;
            bool s      = m_Lock.AcquireReaderLock(() =>
            {
                if (m_ConvexShapesBySculptMesh.TryGetValue(GetMeshKey(meshId, physicsShape), out physicshape))
                {
                    physicshaperes = new PhysicsShapeMeshReference(meshId, physicsShape, this, physicshape);
                    return(true);
                }
                return(false);
            });

            if (s)
            {
                physicshaperef = physicshaperes;
                return(true);
            }

            if (m_DisableCache || !m_SimulationStorage.PhysicsConvexShapes.TryGetValue(meshId, physicsShape, out physicshape))
            {
                /* we may produce additional meshes sometimes but it is better not to lock while generating the mesh */
                physicshape = ConvertToMesh(physicsShape, shape);
                if (physicshape == null)
                {
                    physicshaperef = null;
                    return(false);
                }
                foreach (PhysicsConvexShape.ConvexHull hull in physicshape.Hulls)
                {
                    if (hull.Vertices.Count == 0)
                    {
                        m_Log.WarnFormat("Physics shape of mesh generated a 0 point hull: {0} / {1}", physicsShape, meshId);
                        physicshaperef = null;
                        return(false);
                    }
                }
                m_SimulationStorage.PhysicsConvexShapes[meshId, physicsShape] = physicshape;
            }

            /* we only lock out the decrement use count here */
            physicshaperef = m_Lock.AcquireReaderLock(() =>
            {
                try
                {
                    m_ConvexShapesBySculptMesh.Add(GetMeshKey(meshId, physicsShape), physicshape);
                }
                catch
                {
                    physicshape = m_ConvexShapesBySculptMesh[GetMeshKey(meshId, physicsShape)];
                }
                return(new PhysicsShapeMeshReference(meshId, physicsShape, this, physicshape));
            });

            return(true);
        }
 public void Startup(ConfigurationLoader loader)
 {
     if (m_DisableCache)
     {
         loader.KnownConfigurationIssues.Add("HACD cache is disabled");
     }
     m_AssetService           = loader.GetService <AssetServiceInterface>(m_AssetServiceName);
     m_SimulationStorage      = loader.GetService <SimulationDataStorageInterface>(m_SimulationDataStorageName);
     DefaultAvatarConvexShape = new PhysicsShapeDefaultAvatarReference(this, GenerateDefaultAvatarShape());
 }
        private bool TryGetConvexShapeFromPrim(PrimitivePhysicsShapeType physicsShape, ObjectPart.PrimitiveShape shape, out PhysicsShapeReference physicshaperef)
        {
            PhysicsConvexShape    physicshape;
            PhysicsShapeReference physicshaperes = null;
            bool s = m_Lock.AcquireReaderLock(() =>
            {
                if (m_ConvexShapesByPrimShape.TryGetValue(shape, out physicshape))
                {
                    physicshaperes = new PhysicsShapePrimShapeReference(shape, this, physicshape);
                    return(true);
                }
                return(false);
            });

            if (s)
            {
                physicshaperef = physicshaperes;
                return(true);
            }

            if (m_DisableCache || !m_SimulationStorage.PhysicsConvexShapes.TryGetValue(shape, out physicshape))
            {
                /* we may produce additional meshes sometimes but it is better not to lock while generating the mesh */
                physicshape = ConvertToMesh(physicsShape, shape);
                if (physicshape == null)
                {
                    physicshaperef = null;
                    return(false);
                }
                foreach (PhysicsConvexShape.ConvexHull hull in physicshape.Hulls)
                {
                    if (hull.Vertices.Count == 0)
                    {
                        if (shape.Type == PrimitiveShapeType.Sculpt)
                        {
                            m_Log.WarnFormat("Physics shape of sculpt generated a 0 point hull: {0} / {1}", physicsShape, shape.Serialization.ToHexString());
                        }
                        else
                        {
                            m_Log.WarnFormat("Physics shape of prim generated a 0 point hull: {0} / {1} / {2} / {3}", physicsShape, shape.PCode, shape.Type, shape.Serialization.ToHexString());
                        }
                        physicshaperef = null;
                        return(false);
                    }
                }
                m_SimulationStorage.PhysicsConvexShapes[shape] = physicshape;
            }

            /* we only lock out the decrement use count here */
            physicshaperef = m_Lock.AcquireReaderLock(() =>
            {
                try
                {
                    m_ConvexShapesByPrimShape.Add(shape, physicshape);
                }
                catch
                {
                    physicshape = m_ConvexShapesByPrimShape[shape];
                }
                return(new PhysicsShapePrimShapeReference(shape, this, physicshape));
            });

            return(true);
        }
        public bool TryGetConvexShape(PrimitivePhysicsShapeType physicsShape, ObjectPart.PrimitiveShape shape, out PhysicsShapeReference physics)
        {
            if (physicsShape == PrimitivePhysicsShapeType.None)
            {
                physics = null;
                return(false);
            }
            else if (shape.Type == PrimitiveShapeType.Sculpt)
            {
                switch (shape.SculptType)
                {
                case PrimitiveSculptType.Mesh:
                    return(TryGetConvexShapeFromMesh(physicsShape, shape, out physics));

                default:
                    /* calculate convex from sculpt */
                    return(TryGetConvexShapeFromPrim(physicsShape, shape, out physics));
                }
            }
            else
            {
                /* calculate convex from prim mesh */
                return(TryGetConvexShapeFromPrim(physicsShape, shape, out physics));
            }
        }