int polyIsConvex(const unsigned short *p, const int vertsPerPoly, const float *verts)
{
	int j, nv = polyNumVerts(p, vertsPerPoly);
	if (nv < 3)
		return 0;
	for (j = 0; j < nv; j++) {
		const float *v = &verts[3 * p[j]];
		const float *v_next = &verts[3 * p[(j + 1) % nv]];
		const float *v_prev = &verts[3 * p[(nv + j - 1) % nv]];
		if (!left(v_prev, v, v_next))
			return 0;

	}
	return 1;
}
bool KX_NavMeshObject::BuildVertIndArrays(float *&vertices, int& nverts,
									   unsigned short* &polys, int& npolys, unsigned short *&dmeshes,
									   float *&dvertices, int &ndvertsuniq, unsigned short *&dtris, 
									   int& ndtris, int &vertsPerPoly)
{
    DerivedMesh* dm = mesh_create_derived_no_virtual(GetScene()->GetBlenderScene(), GetBlenderObject(),
													NULL, CD_MASK_MESH);
	CustomData *pdata = dm->getPolyDataLayout(dm);
	int* recastData = (int*) CustomData_get_layer(pdata, CD_RECAST);
	if (recastData)
	{
		int *dtrisToPolysMap=NULL, *dtrisToTrisMap=NULL, *trisToFacesMap=NULL;
		int nAllVerts = 0;
		float *allVerts = NULL;
		buildNavMeshDataByDerivedMesh(dm, &vertsPerPoly, &nAllVerts, &allVerts, &ndtris, &dtris,
		                              &npolys, &dmeshes, &polys, &dtrisToPolysMap, &dtrisToTrisMap, &trisToFacesMap);

		MEM_SAFE_FREE(dtrisToPolysMap);
		MEM_SAFE_FREE(dtrisToTrisMap);
		MEM_SAFE_FREE(trisToFacesMap);

		unsigned short *verticesMap = (unsigned short *)MEM_mallocN(sizeof(*verticesMap) * nAllVerts, __func__);
		memset(verticesMap, 0xff, sizeof(*verticesMap) * nAllVerts);
		int curIdx = 0;
		//vertices - mesh verts
		//iterate over all polys and create map for their vertices first...
		for (int polyidx=0; polyidx<npolys; polyidx++)
		{
			unsigned short* poly = &polys[polyidx*vertsPerPoly*2];
			for (int i=0; i<vertsPerPoly; i++)
			{
				unsigned short idx = poly[i];
				if (idx==0xffff)
					break;
				if (verticesMap[idx]==0xffff)
				{
					verticesMap[idx] = curIdx++;
				}
				poly[i] = verticesMap[idx];
			}
		}
		nverts = curIdx;
		//...then iterate over detailed meshes
		//transform indices to local ones (for each navigation polygon)
		for (int polyidx=0; polyidx<npolys; polyidx++)
		{
			unsigned short *poly = &polys[polyidx*vertsPerPoly*2];
			int nv = polyNumVerts(poly, vertsPerPoly);
			unsigned short *dmesh = &dmeshes[4*polyidx];
			unsigned short tribase = dmesh[2];
			unsigned short trinum = dmesh[3];
			unsigned short vbase = curIdx;
			for (int j=0; j<trinum; j++)
			{
				unsigned short* dtri = &dtris[(tribase+j)*3*2];
				for (int k=0; k<3; k++)
				{
					int newVertexIdx = verticesMap[dtri[k]];
					if (newVertexIdx==0xffff)
					{
						newVertexIdx = curIdx++;
						verticesMap[dtri[k]] = newVertexIdx;
					}

					if (newVertexIdx<nverts)
					{
						//it's polygon vertex ("shared")
						int idxInPoly = polyFindVertex(poly, vertsPerPoly, newVertexIdx);
						if (idxInPoly==-1)
						{
							printf("Building NavMeshObject: Error! Can't find vertex in polygon\n");
							return false;
						}
						dtri[k] = idxInPoly;
					}
					else
					{
						dtri[k] = newVertexIdx - vbase + nv;
					}
				}
			}
			dmesh[0] = vbase-nverts; //verts base
			dmesh[1] = curIdx-vbase; //verts num
		}

		vertices = new float[nverts*3];
		ndvertsuniq = curIdx - nverts;
		if (ndvertsuniq>0)
		{
			dvertices = new float[ndvertsuniq*3];
		}
		for (int vi=0; vi<nAllVerts; vi++)
		{
			int newIdx = verticesMap[vi];
			if (newIdx!=0xffff)
			{
				if (newIdx<nverts)
				{
					//navigation mesh vertex
					memcpy(vertices+3*newIdx, allVerts+3*vi, 3*sizeof(float));
				}
				else
				{
					//detailed mesh vertex
					memcpy(dvertices+3*(newIdx-nverts), allVerts+3*vi, 3*sizeof(float));
				}
			}
		}

		MEM_SAFE_FREE(allVerts);

		MEM_freeN(verticesMap);
	}
	else
	{
		//create from RAS_MeshObject (detailed mesh is fake)
		RAS_MeshObject* meshobj = GetMesh(0);
		vertsPerPoly = 3;
		nverts = meshobj->m_sharedvertex_map.size();
		if (nverts >= 0xffff)
			return false;
		//calculate count of tris
		int nmeshpolys = meshobj->NumPolygons();
		npolys = nmeshpolys;
		for (int p=0; p<nmeshpolys; p++)
		{
			int vertcount = meshobj->GetPolygon(p)->VertexCount();
			npolys+=vertcount-3;
		}

		//create verts
		vertices = new float[nverts*3];
		float* vert = vertices;
		for (int vi=0; vi<nverts; vi++)
		{
			const float* pos = !meshobj->m_sharedvertex_map[vi].empty() ? meshobj->GetVertexLocation(vi) : NULL;
			if (pos)
				copy_v3_v3(vert, pos);
			else
			{
				memset(vert, 0, 3*sizeof(float)); //vertex isn't in any poly, set dummy zero coordinates
			}
			vert+=3;
		}

		//create tris
		polys = (unsigned short *)MEM_callocN(sizeof(unsigned short)*3*2*npolys, "BuildVertIndArrays polys");
		memset(polys, 0xff, sizeof(unsigned short)*3*2*npolys);
		unsigned short *poly = polys;
		RAS_Polygon* raspoly;
		for (int p=0; p<nmeshpolys; p++)
		{
			raspoly = meshobj->GetPolygon(p);
			for (int v=0; v<raspoly->VertexCount()-2; v++)
			{
				poly[0] = raspoly->GetVertex(0)->getOrigIndex();
				for (size_t i=1; i<3; i++)
				{
					poly[i] = raspoly->GetVertex(v+i)->getOrigIndex();
				}
				poly += 6;
			}
		}
		dmeshes = NULL;
		dvertices = NULL;
		ndvertsuniq = 0;
		dtris = NULL;
		ndtris = npolys;
	}
	dm->release(dm);
	
	return true;
}