bool BL_ModifierDeformer::Update(void)
{
	bool bShapeUpdate = BL_ShapeDeformer::Update();

	if (bShapeUpdate || m_lastModifierUpdate != m_gameobj->GetLastFrame()) {
		// static derived mesh are not updated
		if (m_dm == NULL || m_bDynamic) {
			/* execute the modifiers */
			Object* blendobj = m_gameobj->GetBlendObject();
			/* hack: the modifiers require that the mesh is attached to the object
			 * It may not be the case here because of replace mesh actuator */
			Mesh *oldmesh = (Mesh*)blendobj->data;
			blendobj->data = m_bmesh;
			/* execute the modifiers */
			DerivedMesh *dm = mesh_create_derived_no_virtual(m_scene, blendobj, m_transverts, CD_MASK_MESH);
			/* restore object data */
			blendobj->data = oldmesh;
			/* free the current derived mesh and replace, (dm should never be NULL) */
			if (m_dm != NULL) {
				// HACK! use deformedOnly as a user counter
				if (--m_dm->deformedOnly == 0) {
					m_dm->needsFree = 1;
					m_dm->release(m_dm);
				}
			}
			m_dm = dm;
			// get rid of temporary data
			m_dm->needsFree = 0;
			m_dm->release(m_dm);
			// HACK! use deformedOnly as a user counter
			m_dm->deformedOnly = 1;
			DM_update_materials(m_dm, blendobj);
			/* update the graphic controller */
			PHY_IGraphicController *ctrl = m_gameobj->GetGraphicController();
			if (ctrl) {
				float min[3], max[3];
				INIT_MINMAX(min, max);
				m_dm->getMinMax(m_dm, min, max);
				ctrl->SetLocalAabb(min, max);
			}
		}
		m_lastModifierUpdate=m_gameobj->GetLastFrame();
		bShapeUpdate = true;

		int nmat = m_pMeshObject->NumMaterials();
		for (int imat=0; imat<nmat; imat++) {
			RAS_MeshMaterial *mmat = m_pMeshObject->GetMeshMaterial(imat);
			RAS_MeshSlot **slot = mmat->m_slots[(void*)m_gameobj];
			if (!slot || !*slot)
				continue;
			(*slot)->m_pDerivedMesh = m_dm;
		}
	}
	return bShapeUpdate;
}
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;
}
Ejemplo n.º 3
0
static void createVertsTrisData(bContext *C, LinkNode* obs, int *nverts_r, float **verts_r, int *ntris_r, int **tris_r)
{
	MVert *mvert;
	int nfaces= 0, *tri, i, curnverts, basenverts, curnfaces;
	MFace *mface;
	float co[3], wco[3];
	Object *ob;
	LinkNode *oblink, *dmlink;
	DerivedMesh *dm;
	Scene* scene= CTX_data_scene(C);
	LinkNode* dms= NULL;

	int nverts, ntris, *tris;
	float *verts;

	nverts= 0;
	ntris= 0;

	/* calculate number of verts and tris */
	for(oblink= obs; oblink; oblink= oblink->next) {
		ob= (Object*) oblink->link;
		dm= mesh_create_derived_no_virtual(scene, ob, NULL, CD_MASK_MESH);
		BLI_linklist_append(&dms, (void*)dm);

		nverts+= dm->getNumVerts(dm);
		nfaces= dm->getNumFaces(dm);
		ntris+= nfaces;

		/* resolve quad faces */
		mface= dm->getFaceArray(dm);
		for(i= 0; i<nfaces; i++) {
			MFace* mf= &mface[i];
			if(mf->v4)
				ntris+=1;
		}
	}

	/* create data */
	verts= MEM_mallocN(sizeof(float)*3*nverts, "createVertsTrisData verts");
	tris= MEM_mallocN(sizeof(int)*3*ntris, "createVertsTrisData faces");

	basenverts= 0;
	tri= tris;
	for(oblink= obs, dmlink= dms; oblink && dmlink;
			oblink= oblink->next, dmlink= dmlink->next) {
		ob= (Object*) oblink->link;
		dm= (DerivedMesh*) dmlink->link;

		curnverts= dm->getNumVerts(dm);
		mvert= dm->getVertArray(dm);

		/* copy verts */
		for(i= 0; i<curnverts; i++) {
			MVert *v= &mvert[i];

			copy_v3_v3(co, v->co);
			mul_v3_m4v3(wco, ob->obmat, co);

			verts[3*(basenverts+i)+0]= wco[0];
			verts[3*(basenverts+i)+1]= wco[2];
			verts[3*(basenverts+i)+2]= wco[1];
		}

		/* create tris */
		curnfaces= dm->getNumFaces(dm);
		mface= dm->getFaceArray(dm);

		for(i= 0; i<curnfaces; i++) {
			MFace* mf= &mface[i];

			tri[0]= basenverts + mf->v1;
			tri[1]= basenverts + mf->v3;
			tri[2]= basenverts + mf->v2;
			tri += 3;

			if(mf->v4) {
				tri[0]= basenverts + mf->v1;
				tri[1]= basenverts + mf->v4;
				tri[2]= basenverts + mf->v3;
				tri += 3;
			}
		}

		basenverts+= curnverts;
	}

	/* release derived mesh */
	for(dmlink= dms; dmlink; dmlink= dmlink->next) {
		dm= (DerivedMesh*) dmlink->link;
		dm->release(dm);
	}

	BLI_linklist_free(dms, NULL);

	*nverts_r= nverts;
	*verts_r= verts;
	*ntris_r= ntris;
	*tris_r= tris;
}