Example #1
0
        //*********************************************************************
        //*********************************************************************
        //********  HullLib header
        //*********************************************************************
        //*********************************************************************

        //*********************************************************************
        //*********************************************************************
        //********  HullLib implementation
        //*********************************************************************
        //*********************************************************************

        public HullError CreateConvexHull(HullDesc desc,           // describes the input request
                                        HullResult result)         // contains the resulst
        {
            HullError ret = HullError.QE_FAIL;

            PHullResult hr = new PHullResult();

            int vcount = desc.mVcount;
            if (vcount < 8)
            {
                vcount = 8;
            }

            IList<IndexedVector3> vertexSource = new List<IndexedVector3>((int)vcount);
            for (int i = 0; i < vcount; ++i)
            {
                vertexSource.Add(IndexedVector3.Zero);
            }


            IndexedVector3 scale = new IndexedVector3(1);

            int ovcount = 0;

            bool ok = CleanupVertices(desc.mVcount, desc.mVertices, desc.mVertexStride, ref ovcount, vertexSource, desc.mNormalEpsilon, ref scale); // normalize point cloud, remove duplicates!

            if (ok)
            {
                //		if ( 1 ) // scale vertices back to their original size.
                {
                    for (int i = 0; i < ovcount; i++)
                    {
                        IndexedVector3 v = vertexSource[i];
                        v.X *= scale.X;
                        v.Y *= scale.Y;
                        v.Z *= scale.Z;
                        vertexSource[i] = v;
                    }
                }

                ok = ComputeHull(ovcount, vertexSource, hr, desc.mMaxVertices);

                if (ok)
                {

                    // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table.
                    IList<IndexedVector3> vertexScratch = new ObjectArray<IndexedVector3>((int)hr.mVcount);

                    BringOutYourDead(hr.mVertices, hr.mVcount, vertexScratch, ref ovcount, hr.m_Indices, hr.mIndexCount);

                    ret = HullError.QE_OK;

                    if (desc.HasHullFlag(HullFlag.QF_TRIANGLES)) // if he wants the results as triangle!
                    {
                        result.mPolygons = false;
                        result.mNumOutputVertices = ovcount;
                        //result.m_OutputVertices.resize(ovcount);
                        result.m_OutputVertices.Clear();
                        result.mNumFaces = hr.mFaceCount;
                        result.mNumIndices = hr.mIndexCount;

                        //result.m_Indices.resize(hr.mIndexCount);
                        result.m_Indices.Clear();

                        for (int i = 0; i < ovcount; ++i)
                        {
                            result.m_OutputVertices.Add(vertexScratch[i]);
                        }
                        //memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(IndexedVector3) * ovcount);

                        if (desc.HasHullFlag(HullFlag.QF_REVERSE_ORDER))
                        {

                            IList<int> source = hr.m_Indices;
                            IList<int> dest = result.m_Indices;

                            for (int i = 0; i < hr.mFaceCount; i++)
                            {
                                int index = (i * 3);
                                //dest[index + 0] = source[index + 2];
                                //dest[index + 1] = source[index + 1];
                                //dest[index + 2] = source[index + 0];
                                dest.Add(source[index + 2]);
                                dest.Add(source[index + 1]);
                                dest.Add(source[index + 0]);
                            }
                        }
                        else
                        {
                            for (int i = 0; i < hr.mIndexCount; ++i)
                            {
                                //result.m_Indices[i] = hr.m_Indices[i];
                                result.m_Indices.Add(hr.m_Indices[i]);
                            }
                            //memcpy(&result.m_Indices[0], &hr.m_Indices[0], sizeof(int) * hr.mIndexCount);
                        }
                    }
                    else
                    {
                        result.mPolygons = true;
                        result.mNumOutputVertices = ovcount;
                        //result.m_OutputVertices.resize(ovcount);
                        result.m_OutputVertices.Clear();
                        result.mNumFaces = hr.mFaceCount;
                        result.mNumIndices = hr.mIndexCount + hr.mFaceCount;
                        //result.m_Indices.resize(result.mNumIndices);
                        result.m_Indices.Clear();

                        for (int i = 0; i < ovcount; ++i)
                        {
                            result.m_OutputVertices.Add(vertexScratch[i]);
                        }
                        //memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(IndexedVector3) * ovcount);

                        //				if ( 1 )
                        {
                            IList<int> source = hr.m_Indices;
                            IList<int> dest = result.m_Indices;

                            for (int i = 0; i < hr.mFaceCount; i++)
                            {
                                int destIndex = (i * 4);
                                int srcIndex = (i * 3);
                                dest[0] = 3;
                                if (desc.HasHullFlag(HullFlag.QF_REVERSE_ORDER))
                                {
                                    dest.Add(source[srcIndex + 2]);
                                    dest.Add(source[srcIndex + 1]);
                                    dest.Add(source[srcIndex + 0]);
                                }
                                else
                                {
                                    dest.Add(source[srcIndex + 0]);
                                    dest.Add(source[srcIndex + 1]);
                                    dest.Add(source[srcIndex + 2]);
                                }
                            }
                        }
                    }
                    ReleaseHull(hr);
                }
            }

            return ret;
        }
Example #2
0
        public bool BuildHull(float margin)
        {
	        int numSampleDirections = NUM_UNITSPHERE_POINTS;
	        {
		        int numPDA = m_shape.GetNumPreferredPenetrationDirections();
		        if (numPDA != 0)
		        {
			        for (int i=0;i<numPDA;i++)
			        {
				        IndexedVector3 norm;
				        m_shape.GetPreferredPenetrationDirection(i, out norm);
				        UnitSpherePoints[numSampleDirections] = norm;
				        numSampleDirections++;
			        }
		        }
	        }

	        IndexedVector3[] supportPoints = new IndexedVector3[NUM_UNITSPHERE_POINTS+ConvexShape.MAX_PREFERRED_PENETRATION_DIRECTIONS*2];
	        
	        for (int i = 0; i < numSampleDirections; i++)
	        {
		        supportPoints[i] = m_shape.LocalGetSupportingVertex(ref UnitSpherePoints[i]);
	        }

	        HullDesc hd = new HullDesc();
	        hd.mFlags = HullFlag.QF_TRIANGLES;
	        hd.mVcount = numSampleDirections;

            for (int i = 0; i < numSampleDirections; ++i)
            {
                hd.mVertices.Add(supportPoints[i]);
            }
            HullLibrary hl = new HullLibrary();
	        HullResult hr = new HullResult();
	        if (hl.CreateConvexHull (hd, hr) == HullError.QE_FAIL)
	        {
		        return false;
	        }


	        for (int i = 0; i < hr.mNumOutputVertices; i++)
	        {
		        m_vertices[i] = hr.m_OutputVertices[i];
	        }
            
            int numIndices = hr.mNumIndices;
	        
            for (int i = 0; i < numIndices; i++)
	        {
		        m_indices[i] = hr.m_Indices[i];
	        }

	        // free temporary hull result that we just copied
	        hl.ReleaseResult (hr);

#if DEBUG
            if (BulletGlobals.g_streamWriter != null && BulletGlobals.debugShapeHull)
			{
				BulletGlobals.g_streamWriter.WriteLine("buildHull");
				BulletGlobals.g_streamWriter.WriteLine("Vertices");
				for (int i = 0; i < m_vertices.Count; ++i)
				{
					MathUtil.PrintVector3(BulletGlobals.g_streamWriter,m_vertices[i]);
				}
				BulletGlobals.g_streamWriter.WriteLine("Indices");
				for (int i = 0; i < m_indices.Count/3; ++i)
				{
					int indexer = i*3;
					BulletGlobals.g_streamWriter.WriteLine(String.Format("{0},{1},{2}", m_indices[indexer], m_indices[indexer + 1], m_indices[indexer + 2]));
				}

			}
#endif

	        return true;

        }