From a25c7f647e3050239d0c0ea35db37a3e48f84e4c Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 27 Sep 2011 09:09:43 +0000 Subject: navmesh: convert object_navmesh.cpp to plain c. --- source/blender/editors/object/CMakeLists.txt | 4 +- source/blender/editors/object/SConscript | 4 +- source/blender/editors/object/object_navmesh.c | 684 +++++++++++++++++++++++ source/blender/editors/object/object_navmesh.cpp | 628 --------------------- 4 files changed, 688 insertions(+), 632 deletions(-) create mode 100644 source/blender/editors/object/object_navmesh.c delete mode 100644 source/blender/editors/object/object_navmesh.cpp (limited to 'source/blender/editors/object') diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index b9b8ddc6305..b0b4f9dc0eb 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -60,11 +60,11 @@ set(SRC if(WITH_GAMEENGINE) list(APPEND INC - ../../../../extern/recastnavigation/Recast/Include + ../../../../extern/recastnavigation ) list(APPEND SRC - object_navmesh.cpp + object_navmesh.c ) endif() diff --git a/source/blender/editors/object/SConscript b/source/blender/editors/object/SConscript index cdda16582ef..d4739236ba1 100644 --- a/source/blender/editors/object/SConscript +++ b/source/blender/editors/object/SConscript @@ -1,13 +1,13 @@ #!/usr/bin/python Import ('env') -sources = env.Glob('*.c') + env.Glob('*.cpp') +sources = env.Glob('*.c') incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc ../../blenloader' incs += ' ../../makesrna ../../python ../../ikplugin' incs += ' ../../render/extern/include ../../gpu' # for object_bake.c -incs += ' #extern/recastnavigation/Recast/Include' +incs += ' #extern/recastnavigation' defs = [] diff --git a/source/blender/editors/object/object_navmesh.c b/source/blender/editors/object/object_navmesh.c new file mode 100644 index 00000000000..413d8757be2 --- /dev/null +++ b/source/blender/editors/object/object_navmesh.c @@ -0,0 +1,684 @@ +/** +* $Id$ +* +* ***** BEGIN GPL LICENSE BLOCK ***** +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software Foundation, +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +* +* The Original Code is Copyright (C) 2004 by Blender Foundation +* All rights reserved. +* +* The Original Code is: all of this file. +* +* Contributor(s): none yet. +* +* ***** END GPL LICENSE BLOCK ***** +*/ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" +#include "DNA_object_types.h" +#include "DNA_meshdata_types.h" +#include "DNA_modifier_types.h" +#include "DNA_ID.h" + +#include "BKE_library.h" +#include "BKE_depsgraph.h" +#include "BKE_context.h" +#include "BKE_main.h" +#include "BKE_mesh.h" +#include "BKE_modifier.h" +#include "BKE_scene.h" +#include "BKE_DerivedMesh.h" +#include "BKE_cdderivedmesh.h" + +#include "BLI_editVert.h" +#include "BLI_listbase.h" +#include "BLI_utildefines.h" +#include "BLI_math_vector.h" + +#include "ED_object.h" +#include "ED_mesh.h" + +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "recast-capi.h" + +/*mesh/mesh_intern.h */ +extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); +extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); +extern void free_vertlist(EditMesh *em, ListBase *edve); +extern void free_edgelist(EditMesh *em, ListBase *lb); +extern void free_facelist(EditMesh *em, ListBase *lb); + +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; iv4) + ntris+=1; + } + } + + //create data + verts = MEM_mallocN(sizeof(float)*3*nverts, "verts"); + tris = MEM_mallocN(sizeof(int)*3*ntris, "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; ico); + 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; iv1; 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; +} + +static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris, + struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh) +{ + float bmin[3], bmax[3]; + struct recast_heightfield *solid; + unsigned char *triflags; + struct recast_compactHeightfield* chf; + struct recast_contourSet *cset; + int width, height, walkableHeight, walkableClimb, walkableRadius; + int minRegionSize, mergeRegionSize, maxEdgeLen; + float detailSampleDist, detailSampleMaxError; + + recast_calcBounds(verts, nverts, bmin, bmax); + + // + // Step 1. Initialize build config. + // + { +/* + float cellsize = 0.3f; + float cellheight = 0.2f; + float agentmaxslope = M_PI/4; + float agentmaxclimb = 0.9f; + float agentheight = 2.0f; + float agentradius = 0.6f; + float edgemaxlen = 12.0f; + float edgemaxerror = 1.3f; + float regionminsize = 50.f; + float regionmergesize = 20.f; + int vertsperpoly = 6; + float detailsampledist = 6.0f; + float detailsamplemaxerror = 1.0f; + cfg.cs = cellsize; + cfg.ch = cellheight; + cfg.walkableSlopeAngle = agentmaxslope/M_PI*180.f; + cfg.walkableHeight = (int)ceilf(agentheight/ cfg.ch); + cfg.walkableClimb = (int)floorf(agentmaxclimb / cfg.ch); + cfg.walkableRadius = (int)ceilf(agentradius / cfg.cs); + cfg.maxEdgeLen = (int)(edgemaxlen/cellsize); + cfg.maxSimplificationError = edgemaxerror; + cfg.minRegionSize = (int)rcSqr(regionminsize); + cfg.mergeRegionSize = (int)rcSqr(regionmergesize); + cfg.maxVertsPerPoly = vertsperpoly; + cfg.detailSampleDist = detailsampledist< 0.9f ? 0 : cellsize * detailsampledist; + cfg.detailSampleMaxError = cellheight * detailsamplemaxerror; +*/ +#if 0 + cfg.cs = recastParams.cellsize; + cfg.ch = recastParams.cellheight; + cfg.walkableSlopeAngle = recastParams.agentmaxslope/((float)M_PI)*180.f; + cfg.walkableHeight = (int)ceilf(recastParams.agentheight/ cfg.ch); + cfg.walkableClimb = (int)floorf(recastParams.agentmaxclimb / cfg.ch); + cfg.walkableRadius = (int)ceilf(recastParams.agentradius / cfg.cs); + cfg.maxEdgeLen = (int)(recastParams.edgemaxlen/recastParams.cellsize); + cfg.maxSimplificationError = recastParams.edgemaxerror; + cfg.minRegionSize = (int)rcSqr(recastParams.regionminsize); + cfg.mergeRegionSize = (int)rcSqr(recastParams.regionmergesize); + cfg.maxVertsPerPoly = recastParams.vertsperpoly; + cfg.detailSampleDist = recastParams.detailsampledist< 0.9f ? 0 : + recastParams.cellsize * recastParams.detailsampledist; + cfg.detailSampleMaxError = recastParams.cellheight * recastParams.detailsamplemaxerror; +#endif + } + + walkableHeight = (int)ceilf(recastParams->agentheight/ recastParams->cellheight); + walkableClimb = (int)floorf(recastParams->agentmaxclimb / recastParams->cellheight); + walkableRadius = (int)ceilf(recastParams->agentradius / recastParams->cellsize); + minRegionSize = (int)(recastParams->regionminsize * recastParams->regionminsize); + mergeRegionSize = (int)(recastParams->regionmergesize * recastParams->regionmergesize); + maxEdgeLen = (int)(recastParams->edgemaxlen/recastParams->cellsize); + detailSampleDist = recastParams->detailsampledist< 0.9f ? 0 : + recastParams->cellsize * recastParams->detailsampledist; + detailSampleMaxError = recastParams->cellheight * recastParams->detailsamplemaxerror; + + // Set the area where the navigation will be build. + recast_calcGridSize(bmin, bmax, recastParams->cellsize, &width, &height); + + // + // Step 2. Rasterize input polygon soup. + // + // Allocate voxel heightfield where we rasterize our input data to. + solid = recast_newHeightfield(); + + if (!recast_createHeightfield(solid, width, height, bmin, bmax, recastParams->cellsize, recastParams->cellheight)) { + recast_destroyHeightfield(solid); + + return 0; + } + + // Allocate array that can hold triangle flags. + triflags = MEM_callocN(sizeof(unsigned char)*ntris, "triflags"); + + // Find triangles which are walkable based on their slope and rasterize them. + recast_markWalkableTriangles(RAD2DEG(recastParams->agentmaxslope), verts, nverts, tris, ntris, triflags); + recast_rasterizeTriangles(verts, nverts, tris, triflags, ntris, solid); + MEM_freeN(triflags); + + // + // Step 3. Filter walkables surfaces. + // + recast_filterLedgeSpans(walkableHeight, walkableClimb, solid); + recast_filterWalkableLowHeightSpans(walkableHeight, solid); + + // + // Step 4. Partition walkable surface to simple regions. + // + + chf = recast_newCompactHeightfield(); + if (!recast_buildCompactHeightfield(walkableHeight, walkableClimb, RECAST_WALKABLE, solid, chf)) { + recast_destroyHeightfield(solid); + recast_destroyCompactHeightfield(chf); + + return 0; + } + + recast_destroyHeightfield(solid); + + // Prepare for region partitioning, by calculating distance field along the walkable surface. + if (!recast_buildDistanceField(chf)) { + recast_destroyCompactHeightfield(chf); + + return 0; + } + + // Partition the walkable surface into simple regions without holes. + if (!recast_buildRegions(chf, walkableRadius, 0, minRegionSize, mergeRegionSize)) { + recast_destroyCompactHeightfield(chf); + + return 0; + } + + // + // Step 5. Trace and simplify region contours. + // + // Create contours. + cset = recast_newContourSet(); + + if (!recast_buildContours(chf, recastParams->edgemaxerror, maxEdgeLen, cset)) { + recast_destroyCompactHeightfield(chf); + recast_destroyContourSet(cset); + + return 0; + } + + // + // Step 6. Build polygons mesh from contours. + // + *pmesh = recast_newPolyMesh(); + if (!recast_buildPolyMesh(cset, recastParams->vertsperpoly, *pmesh)) { + recast_destroyCompactHeightfield(chf); + recast_destroyContourSet(cset); + recast_destroyPolyMesh(*pmesh); + + return 0; + } + + + // + // Step 7. Create detail mesh which allows to access approximate height on each polygon. + // + + *dmesh = recast_newPolyMeshDetail(); + if (!recast_buildPolyMeshDetail(*pmesh, chf, detailSampleDist, detailSampleMaxError, *dmesh)) { + recast_destroyCompactHeightfield(chf); + recast_destroyContourSet(cset); + recast_destroyPolyMesh(*pmesh); + recast_destroyPolyMeshDetail(*dmesh); + + return 0; + } + + recast_destroyCompactHeightfield(chf); + recast_destroyContourSet(cset); + + return 1; +} + +static Object* createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base* base) +{ + float co[3], rot[3]; + EditMesh *em; + int i,j, k; + unsigned short* v; + int face[3]; + Main *bmain = CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Object* obedit; + int createob = base==NULL; + int nverts, nmeshes, nvp; + unsigned short *verts, *meshes, *polys; + float bmin[3], cs, ch, *dverts; + unsigned char *tris; + ModifierData *md; + + zero_v3(co); + zero_v3(rot); + + if (createob) + { + //create new object + obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); + } + else + { + obedit = base->object; + scene_select_base(scene, base); + copy_v3_v3(obedit->loc, co); + copy_v3_v3(obedit->rot, rot); + } + + ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); + em = BKE_mesh_get_editmesh(((Mesh *)obedit->data)); + + if (!createob) + { + //clear + if(em->verts.first) free_vertlist(em, &em->verts); + if(em->edges.first) free_edgelist(em, &em->edges); + if(em->faces.first) free_facelist(em, &em->faces); + if(em->selected.first) BLI_freelistN(&(em->selected)); + } + + //create verts for polygon mesh + verts = recast_polyMeshGetVerts(pmesh, &nverts); + recast_polyMeshGetBoundbox(pmesh, bmin, NULL); + recast_polyMeshGetCell(pmesh, &cs, &ch); + + for(i = 0; i < nverts; i++) { + v = &verts[3*i]; + co[0] = bmin[0] + v[0]*cs; + co[1] = bmin[1] + v[1]*ch; + co[2] = bmin[2] + v[2]*cs; + SWAP(float, co[1], co[2]); + addvertlist(em, co, NULL); + } + + //create custom data layer to save polygon idx + CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "recastData"); + + //create verts and faces for detailed mesh + meshes = recast_polyMeshDetailGetMeshes(dmesh, &nmeshes); + polys = recast_polyMeshGetPolys(pmesh, NULL, &nvp); + dverts = recast_polyMeshDetailGetVerts(dmesh, NULL); + tris = recast_polyMeshDetailGetTris(dmesh, NULL); + + for (i=0; itotvert; + unsigned short vbase = meshes[4*i+0]; + unsigned short ndv = meshes[4*i+1]; + unsigned short tribase = meshes[4*i+2]; + unsigned short trinum = meshes[4*i+3]; + const unsigned short* p = &polys[i*nvp*2]; + int nv = 0; + for (j = 0; j < nvp; ++j) + { + if (p[j] == 0xffff) break; + nv++; + } + //create unique verts + for (j=nv; jfdata, newFace->data, CD_RECAST); + *polygonIdx = i+1; //add 1 to avoid zero idx + } + + EM_free_index_arrays(); + } + + recast_destroyPolyMesh(pmesh); + recast_destroyPolyMeshDetail(dmesh); + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + + ED_object_exit_editmode(C, EM_FREEDATA); + WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); + + if (createob) + { + obedit->gameflag &= ~OB_COLLISION; + obedit->gameflag |= OB_NAVMESH; + obedit->body_type = OB_BODY_TYPE_NAVMESH; + rename_id((ID *)obedit, "Navmesh"); + } + + md= modifiers_findByType(obedit, eModifierType_NavMesh); + if (!md) + { + ED_object_modifier_add(NULL, bmain, scene, obedit, NULL, eModifierType_NavMesh); + } + + return obedit; +} + +static int create_navmesh_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Scene* scene = CTX_data_scene(C); + int nverts, ntris; + float* verts; + int* tris; + struct recast_polyMesh *pmesh; + struct recast_polyMeshDetail *dmesh; + LinkNode* obs = NULL; + Base* navmeshBase = NULL; + + //CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) //expand macros to avoid error in convertion from void* + { + ListBase ctx_data_list; + CollectionPointerLink *ctx_link; + CTX_data_selected_editable_bases(C, &ctx_data_list); + for(ctx_link = (CollectionPointerLink *)ctx_data_list.first; + ctx_link; ctx_link = (CollectionPointerLink *)ctx_link->next) { + Base* base= (Base*)ctx_link->ptr.data; + { + if (base->object->body_type==OB_BODY_TYPE_NAVMESH) + { + if (!navmeshBase || base==CTX_data_active_base(C)) + navmeshBase = base; + } + else + BLI_linklist_append(&obs, (void*)base->object); + } + CTX_DATA_END; + createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris); + BLI_linklist_free(obs, NULL); + buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh); + createRepresentation(C, pmesh, dmesh, navmeshBase); + + return OPERATOR_FINISHED; +} + +void OBJECT_OT_create_navmesh(wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Create navigation mesh"; + ot->description= "Create navigation mesh for selected objects"; + ot->idname= "OBJECT_OT_create_navmesh"; + + /* api callbacks */ + ot->exec= create_navmesh_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int assign_navpolygon_poll(bContext *C) +{ + Object *ob= (Object *)CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + if (!ob || !ob->data) + return 0; + return (((Mesh*)ob->data)->edit_mesh != NULL); +} + +static int assign_navpolygon_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + + //do work here + int targetPolyIdx = -1; + EditFace *ef, *efa; + efa = EM_get_actFace(em, 0); + if (efa) + { + if (CustomData_has_layer(&em->fdata, CD_RECAST)) + { + targetPolyIdx = *(int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST); + targetPolyIdx = targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx; + if (targetPolyIdx>0) + { + //set target poly idx to other selected faces + ef = (EditFace*)em->faces.last; + while(ef) + { + if((ef->f & SELECT )&& ef!=efa) + { + int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + *recastDataBlock = targetPolyIdx; + } + ef = ef->prev; + } + } + } + } + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Assign polygon index"; + ot->description= "Assign polygon index to face by active face"; + ot->idname= "OBJECT_OT_assign_navpolygon"; + + /* api callbacks */ + ot->poll = assign_navpolygon_poll; + ot->exec= assign_navpolygon_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} + +static int compare(const void * a, const void * b){ + return ( *(int*)a - *(int*)b ); +} + +static int findFreeNavPolyIndex(EditMesh* em) +{ + //construct vector of indices + int numfaces = em->totface; + int* indices = MEM_callocN(sizeof(int)*numfaces, "findFreeNavPolyIndex(indices)"); + EditFace* ef = (EditFace*)em->faces.last; + int i, idx = 0, freeIdx = 1; + + while(ef) + { + int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + indices[idx] = polyIdx; + idx++; + ef = ef->prev; + } + + qsort(indices, numfaces, sizeof(int), compare); + + //search first free index + freeIdx = 1; + for (i=0; ifreeIdx) + break; + } + + MEM_freeN(indices); + + return freeIdx; +} + +static int assign_new_navpolygon_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit= CTX_data_edit_object(C); + EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); + + EditFace *ef; + if (CustomData_has_layer(&em->fdata, CD_RECAST)) + { + int targetPolyIdx = findFreeNavPolyIndex(em); + if (targetPolyIdx>0) + { + //set target poly idx to selected faces + ef = (EditFace*)em->faces.last; + while(ef) + { + if(ef->f & SELECT ) + { + int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); + *recastDataBlock = targetPolyIdx; + } + ef = ef->prev; + } + } + } + + DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); + + BKE_mesh_end_editmesh((Mesh*)obedit->data, em); + return OPERATOR_FINISHED; +} + +void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name= "Assign new polygon index"; + ot->description= "Assign new polygon index to face"; + ot->idname= "OBJECT_OT_assign_new_navpolygon"; + + /* api callbacks */ + ot->poll = assign_navpolygon_poll; + ot->exec= assign_new_navpolygon_exec; + + /* flags */ + ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; +} diff --git a/source/blender/editors/object/object_navmesh.cpp b/source/blender/editors/object/object_navmesh.cpp deleted file mode 100644 index ae97b40eb49..00000000000 --- a/source/blender/editors/object/object_navmesh.cpp +++ /dev/null @@ -1,628 +0,0 @@ -/** -* $Id$ -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) 2004 by Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL LICENSE BLOCK ***** -*/ - -#include -#include "Recast.h" - -extern "C" -{ -#include "MEM_guardedalloc.h" - -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_ID.h" - -#include "BKE_library.h" -#include "BKE_depsgraph.h" -#include "BKE_context.h" -#include "BKE_mesh.h" -#include "BKE_modifier.h" -#include "BKE_scene.h" -#include "BKE_DerivedMesh.h" -#include "BKE_cdderivedmesh.h" -#include "BLI_editVert.h" -#include "BLI_listbase.h" -#include "BLI_utildefines.h" -#include "ED_object.h" -#include "BLI_math_vector.h" - -#include "RNA_access.h" - -#include "ED_mesh.h" - -/*mesh/mesh_intern.h */ -extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); -extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); -extern void free_vertlist(EditMesh *em, ListBase *edve); -extern void free_edgelist(EditMesh *em, ListBase *lb); -extern void free_facelist(EditMesh *em, ListBase *lb); - -#include "WM_api.h" -#include "WM_types.h" - -static void createVertsTrisData(bContext *C, LinkNode* obs, int& nverts, float*& verts, int &ntris, int*& tris) -{ - 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; - - nverts = 0; - ntris = 0; - //calculate number of verts and tris - for (oblink = obs; oblink; oblink = oblink->next) - { - ob = (Object*) oblink->link; - DerivedMesh *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; iv4) - ntris+=1; - } - } - - //create data - verts = (float*) MEM_mallocN(sizeof(float)*3*nverts, "verts"); - tris = (int*) MEM_mallocN(sizeof(int)*3*ntris, "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; ico); - 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; iv1; 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); -} - -static bool buildNavMesh(const RecastData& recastParams, int nverts, float* verts, int ntris, int* tris, - rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh) -{ - float bmin[3], bmax[3]; - rcHeightfield* solid; - unsigned char *triflags; - rcCompactHeightfield* chf; - rcContourSet *cset; - - rcCalcBounds(verts, nverts, bmin, bmax); - - // - // Step 1. Initialize build config. - // - rcConfig cfg; - memset(&cfg, 0, sizeof(cfg)); - { -/* - float cellsize = 0.3f; - float cellheight = 0.2f; - float agentmaxslope = M_PI/4; - float agentmaxclimb = 0.9f; - float agentheight = 2.0f; - float agentradius = 0.6f; - float edgemaxlen = 12.0f; - float edgemaxerror = 1.3f; - float regionminsize = 50.f; - float regionmergesize = 20.f; - int vertsperpoly = 6; - float detailsampledist = 6.0f; - float detailsamplemaxerror = 1.0f; - cfg.cs = cellsize; - cfg.ch = cellheight; - cfg.walkableSlopeAngle = agentmaxslope/M_PI*180.f; - cfg.walkableHeight = (int)ceilf(agentheight/ cfg.ch); - cfg.walkableClimb = (int)floorf(agentmaxclimb / cfg.ch); - cfg.walkableRadius = (int)ceilf(agentradius / cfg.cs); - cfg.maxEdgeLen = (int)(edgemaxlen/cellsize); - cfg.maxSimplificationError = edgemaxerror; - cfg.minRegionSize = (int)rcSqr(regionminsize); - cfg.mergeRegionSize = (int)rcSqr(regionmergesize); - cfg.maxVertsPerPoly = vertsperpoly; - cfg.detailSampleDist = detailsampledist< 0.9f ? 0 : cellsize * detailsampledist; - cfg.detailSampleMaxError = cellheight * detailsamplemaxerror; -*/ - cfg.cs = recastParams.cellsize; - cfg.ch = recastParams.cellheight; - cfg.walkableSlopeAngle = recastParams.agentmaxslope/((float)M_PI)*180.f; - cfg.walkableHeight = (int)ceilf(recastParams.agentheight/ cfg.ch); - cfg.walkableClimb = (int)floorf(recastParams.agentmaxclimb / cfg.ch); - cfg.walkableRadius = (int)ceilf(recastParams.agentradius / cfg.cs); - cfg.maxEdgeLen = (int)(recastParams.edgemaxlen/recastParams.cellsize); - cfg.maxSimplificationError = recastParams.edgemaxerror; - cfg.minRegionSize = (int)rcSqr(recastParams.regionminsize); - cfg.mergeRegionSize = (int)rcSqr(recastParams.regionmergesize); - cfg.maxVertsPerPoly = recastParams.vertsperpoly; - cfg.detailSampleDist = recastParams.detailsampledist< 0.9f ? 0 : - recastParams.cellsize * recastParams.detailsampledist; - cfg.detailSampleMaxError = recastParams.cellheight * recastParams.detailsamplemaxerror; - - } - - // Set the area where the navigation will be build. - vcopy(cfg.bmin, bmin); - vcopy(cfg.bmax, bmax); - rcCalcGridSize(cfg.bmin, cfg.bmax, cfg.cs, &cfg.width, &cfg.height); - - // - // Step 2. Rasterize input polygon soup. - // - // Allocate voxel heightfield where we rasterize our input data to. - solid = new rcHeightfield; - if (!solid) - return false; - - if (!rcCreateHeightfield(*solid, cfg.width, cfg.height, cfg.bmin, cfg.bmax, cfg.cs, cfg.ch)) - return false; - - // Allocate array that can hold triangle flags. - triflags = (unsigned char*) MEM_mallocN(sizeof(unsigned char)*ntris, "triflags"); - if (!triflags) - return false; - // Find triangles which are walkable based on their slope and rasterize them. - memset(triflags, 0, ntris*sizeof(unsigned char)); - rcMarkWalkableTriangles(cfg.walkableSlopeAngle, verts, nverts, tris, ntris, triflags); - rcRasterizeTriangles(verts, nverts, tris, triflags, ntris, *solid); - MEM_freeN(triflags); - MEM_freeN(verts); - MEM_freeN(tris); - - // - // Step 3. Filter walkables surfaces. - // - rcFilterLedgeSpans(cfg.walkableHeight, cfg.walkableClimb, *solid); - rcFilterWalkableLowHeightSpans(cfg.walkableHeight, *solid); - - // - // Step 4. Partition walkable surface to simple regions. - // - - chf = new rcCompactHeightfield; - if (!chf) - return false; - if (!rcBuildCompactHeightfield(cfg.walkableHeight, cfg.walkableClimb, RC_WALKABLE, *solid, *chf)) - return false; - - delete solid; - - // Prepare for region partitioning, by calculating distance field along the walkable surface. - if (!rcBuildDistanceField(*chf)) - return false; - - // Partition the walkable surface into simple regions without holes. - if (!rcBuildRegions(*chf, cfg.walkableRadius, cfg.borderSize, cfg.minRegionSize, cfg.mergeRegionSize)) - return false; - - // - // Step 5. Trace and simplify region contours. - // - // Create contours. - cset = new rcContourSet; - if (!cset) - return false; - - if (!rcBuildContours(*chf, cfg.maxSimplificationError, cfg.maxEdgeLen, *cset)) - return false; - - // - // Step 6. Build polygons mesh from contours. - // - pmesh = new rcPolyMesh; - if (!pmesh) - return false; - if (!rcBuildPolyMesh(*cset, cfg.maxVertsPerPoly, *pmesh)) - return false; - - - // - // Step 7. Create detail mesh which allows to access approximate height on each polygon. - // - - dmesh = new rcPolyMeshDetail; - if (!dmesh) - return false; - - if (!rcBuildPolyMeshDetail(*pmesh, *chf, cfg.detailSampleDist, cfg.detailSampleMaxError, *dmesh)) - return false; - - delete chf; - delete cset; - - return true; -} - -static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh, Base* base) -{ - float co[3], rot[3]; - EditMesh *em; - int i,j, k; - unsigned short* v; - int face[3]; - Main *bmain = CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - Object* obedit; - int createob = base==NULL; - zero_v3(co); - zero_v3(rot); - if (createob) - { - //create new object - obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); - } - else - { - obedit = base->object; - scene_select_base(scene, base); - copy_v3_v3(obedit->loc, co); - copy_v3_v3(obedit->rot, rot); - } - - ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); - em = BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - - if (!createob) - { - //clear - if(em->verts.first) free_vertlist(em, &em->verts); - if(em->edges.first) free_edgelist(em, &em->edges); - if(em->faces.first) free_facelist(em, &em->faces); - if(em->selected.first) BLI_freelistN(&(em->selected)); - } - - //create verts for polygon mesh - for(i = 0; i < pmesh->nverts; i++) { - v = &pmesh->verts[3*i]; - co[0] = pmesh->bmin[0] + v[0]*pmesh->cs; - co[1] = pmesh->bmin[1] + v[1]*pmesh->ch; - co[2] = pmesh->bmin[2] + v[2]*pmesh->cs; - SWAP(float, co[1], co[2]); - addvertlist(em, co, NULL); - } - - //create custom data layer to save polygon idx - CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "recastData"); - - //create verts and faces for detailed mesh - for (i=0; inmeshes; i++) - { - int uniquevbase = em->totvert; - unsigned short vbase = dmesh->meshes[4*i+0]; - unsigned short ndv = dmesh->meshes[4*i+1]; - unsigned short tribase = dmesh->meshes[4*i+2]; - unsigned short trinum = dmesh->meshes[4*i+3]; - const unsigned short* p = &pmesh->polys[i*pmesh->nvp*2]; - int nv = 0; - for (j = 0; j < pmesh->nvp; ++j) - { - if (p[j] == 0xffff) break; - nv++; - } - //create unique verts - for (j=nv; jverts[3*(vbase + j)]); - SWAP(float, co[1], co[2]); - addvertlist(em, co, NULL); - } - - EM_init_index_arrays(em, 1, 0, 0); - - //create faces - for (j=0; jtris[4*(tribase+j)]; - EditFace* newFace; - for (k=0; k<3; k++) - { - if (tri[k]fdata, newFace->data, CD_RECAST); - *polygonIdx = i+1; //add 1 to avoid zero idx - } - - EM_free_index_arrays(); - } - - delete pmesh; pmesh = NULL; - delete dmesh; dmesh = NULL; - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - - ED_object_exit_editmode(C, EM_FREEDATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - if (createob) - { - obedit->gameflag &= ~OB_COLLISION; - obedit->gameflag |= OB_NAVMESH; - obedit->body_type = OB_BODY_TYPE_NAVMESH; - rename_id((ID *)obedit, "Navmesh"); - } - - ModifierData *md= modifiers_findByType(obedit, eModifierType_NavMesh); - if (!md) - { - ED_object_modifier_add(NULL, bmain, scene, obedit, NULL, eModifierType_NavMesh); - } - - return obedit; -} - -static int create_navmesh_exec(bContext *C, wmOperator *op) -{ - Scene* scene = CTX_data_scene(C); - int nverts, ntris; - float* verts; - int* tris; - rcPolyMesh* pmesh; - rcPolyMeshDetail* dmesh; - LinkNode* obs = NULL; - Base* navmeshBase = NULL; - //CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) //expand macros to avoid error in convertion from void* - { - ListBase ctx_data_list; - CollectionPointerLink *ctx_link; - CTX_data_selected_editable_bases(C, &ctx_data_list); - for(ctx_link = (CollectionPointerLink *)ctx_data_list.first; - ctx_link; ctx_link = (CollectionPointerLink *)ctx_link->next) { - Base* base= (Base*)ctx_link->ptr.data; - { - if (base->object->body_type==OB_BODY_TYPE_NAVMESH) - { - if (!navmeshBase || base==CTX_data_active_base(C)) - navmeshBase = base; - } - else - BLI_linklist_append(&obs, (void*)base->object); - } - CTX_DATA_END; - createVertsTrisData(C, obs, nverts, verts, ntris, tris); - BLI_linklist_free(obs, NULL); - buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh); - createRepresentation(C, pmesh, dmesh, navmeshBase); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_create_navmesh(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Create navigation mesh"; - ot->description= "Create navigation mesh for selected objects"; - ot->idname= "OBJECT_OT_create_navmesh"; - - /* api callbacks */ - ot->exec= create_navmesh_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int assign_navpolygon_poll(bContext *C) -{ - Object *ob= (Object *)CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - if (!ob || !ob->data) - return 0; - return (((Mesh*)ob->data)->edit_mesh != NULL); -} - -static int assign_navpolygon_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - //do work here - int targetPolyIdx = -1; - EditFace *ef, *efa; - efa = EM_get_actFace(em, 0); - if (efa) - { - if (CustomData_has_layer(&em->fdata, CD_RECAST)) - { - targetPolyIdx = *(int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST); - targetPolyIdx = targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx; - if (targetPolyIdx>0) - { - //set target poly idx to other selected faces - ef = (EditFace*)em->faces.last; - while(ef) - { - if((ef->f & SELECT )&& ef!=efa) - { - int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - *recastDataBlock = targetPolyIdx; - } - ef = ef->prev; - } - } - } - } - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - return OPERATOR_FINISHED; -} - -void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Assign polygon index"; - ot->description= "Assign polygon index to face by active face"; - ot->idname= "OBJECT_OT_assign_navpolygon"; - - /* api callbacks */ - ot->poll = assign_navpolygon_poll; - ot->exec= assign_navpolygon_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int compare(const void * a, const void * b){ - return ( *(int*)a - *(int*)b ); -} -static int findFreeNavPolyIndex(EditMesh* em) -{ - //construct vector of indices - int numfaces = em->totface; - int* indices = new int[numfaces]; - EditFace* ef = (EditFace*)em->faces.last; - int idx = 0; - while(ef) - { - int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - indices[idx] = polyIdx; - idx++; - ef = ef->prev; - } - qsort(indices, numfaces, sizeof(int), compare); - //search first free index - int freeIdx = 1; - for (int i=0; ifreeIdx) - break; - } - delete [] indices; - return freeIdx; -} - -static int assign_new_navpolygon_exec(bContext *C, wmOperator *op) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - EditFace *ef; - if (CustomData_has_layer(&em->fdata, CD_RECAST)) - { - int targetPolyIdx = findFreeNavPolyIndex(em); - if (targetPolyIdx>0) - { - //set target poly idx to selected faces - ef = (EditFace*)em->faces.last; - while(ef) - { - if(ef->f & SELECT ) - { - int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - *recastDataBlock = targetPolyIdx; - } - ef = ef->prev; - } - } - } - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - return OPERATOR_FINISHED; -} - -void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Assign new polygon index"; - ot->description= "Assign new polygon index to face"; - ot->idname= "OBJECT_OT_assign_new_navpolygon"; - - /* api callbacks */ - ot->poll = assign_navpolygon_poll; - ot->exec= assign_new_navpolygon_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} -} -- cgit v1.2.3 From dcccf3fc1f915d0c8a3f2f8763170b6ff9394b8a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 27 Sep 2011 09:09:52 +0000 Subject: navmesh: solve bad level calls to edit mesh functions Move navmesh operators from editors/object to editors/mesh --- source/blender/editors/object/CMakeLists.txt | 10 - source/blender/editors/object/object_intern.h | 5 - source/blender/editors/object/object_navmesh.c | 684 ------------------------- source/blender/editors/object/object_ops.c | 6 - 4 files changed, 705 deletions(-) delete mode 100644 source/blender/editors/object/object_navmesh.c (limited to 'source/blender/editors/object') diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index b0b4f9dc0eb..c78c9fddbe8 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -58,16 +58,6 @@ set(SRC object_intern.h ) -if(WITH_GAMEENGINE) - list(APPEND INC - ../../../../extern/recastnavigation - ) - - list(APPEND SRC - object_navmesh.c - ) -endif() - if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 434111c1227..7bb98f4aeb1 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -225,10 +225,5 @@ void OBJECT_OT_group_remove(struct wmOperatorType *ot); /* object_bake.c */ void OBJECT_OT_bake_image(wmOperatorType *ot); -/* object_navmesh.cpp */ -void OBJECT_OT_create_navmesh(struct wmOperatorType *ot); -void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot); -void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot); - #endif /* ED_OBJECT_INTERN_H */ diff --git a/source/blender/editors/object/object_navmesh.c b/source/blender/editors/object/object_navmesh.c deleted file mode 100644 index 413d8757be2..00000000000 --- a/source/blender/editors/object/object_navmesh.c +++ /dev/null @@ -1,684 +0,0 @@ -/** -* $Id$ -* -* ***** BEGIN GPL LICENSE BLOCK ***** -* -* This program is free software; you can redistribute it and/or -* modify it under the terms of the GNU General Public License -* as published by the Free Software Foundation; either version 2 -* of the License, or (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software Foundation, -* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -* -* The Original Code is Copyright (C) 2004 by Blender Foundation -* All rights reserved. -* -* The Original Code is: all of this file. -* -* Contributor(s): none yet. -* -* ***** END GPL LICENSE BLOCK ***** -*/ - -#include - -#include "MEM_guardedalloc.h" - -#include "DNA_scene_types.h" -#include "DNA_object_types.h" -#include "DNA_meshdata_types.h" -#include "DNA_modifier_types.h" -#include "DNA_ID.h" - -#include "BKE_library.h" -#include "BKE_depsgraph.h" -#include "BKE_context.h" -#include "BKE_main.h" -#include "BKE_mesh.h" -#include "BKE_modifier.h" -#include "BKE_scene.h" -#include "BKE_DerivedMesh.h" -#include "BKE_cdderivedmesh.h" - -#include "BLI_editVert.h" -#include "BLI_listbase.h" -#include "BLI_utildefines.h" -#include "BLI_math_vector.h" - -#include "ED_object.h" -#include "ED_mesh.h" - -#include "RNA_access.h" - -#include "WM_api.h" -#include "WM_types.h" - -#include "recast-capi.h" - -/*mesh/mesh_intern.h */ -extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example); -extern struct EditFace *addfacelist(EditMesh *em, struct EditVert *v1, struct EditVert *v2, struct EditVert *v3, struct EditVert *v4, struct EditFace *example, struct EditFace *exampleEdges); -extern void free_vertlist(EditMesh *em, ListBase *edve); -extern void free_edgelist(EditMesh *em, ListBase *lb); -extern void free_facelist(EditMesh *em, ListBase *lb); - -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; iv4) - ntris+=1; - } - } - - //create data - verts = MEM_mallocN(sizeof(float)*3*nverts, "verts"); - tris = MEM_mallocN(sizeof(int)*3*ntris, "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; ico); - 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; iv1; 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; -} - -static int buildNavMesh(const RecastData *recastParams, int nverts, float *verts, int ntris, int *tris, - struct recast_polyMesh **pmesh, struct recast_polyMeshDetail **dmesh) -{ - float bmin[3], bmax[3]; - struct recast_heightfield *solid; - unsigned char *triflags; - struct recast_compactHeightfield* chf; - struct recast_contourSet *cset; - int width, height, walkableHeight, walkableClimb, walkableRadius; - int minRegionSize, mergeRegionSize, maxEdgeLen; - float detailSampleDist, detailSampleMaxError; - - recast_calcBounds(verts, nverts, bmin, bmax); - - // - // Step 1. Initialize build config. - // - { -/* - float cellsize = 0.3f; - float cellheight = 0.2f; - float agentmaxslope = M_PI/4; - float agentmaxclimb = 0.9f; - float agentheight = 2.0f; - float agentradius = 0.6f; - float edgemaxlen = 12.0f; - float edgemaxerror = 1.3f; - float regionminsize = 50.f; - float regionmergesize = 20.f; - int vertsperpoly = 6; - float detailsampledist = 6.0f; - float detailsamplemaxerror = 1.0f; - cfg.cs = cellsize; - cfg.ch = cellheight; - cfg.walkableSlopeAngle = agentmaxslope/M_PI*180.f; - cfg.walkableHeight = (int)ceilf(agentheight/ cfg.ch); - cfg.walkableClimb = (int)floorf(agentmaxclimb / cfg.ch); - cfg.walkableRadius = (int)ceilf(agentradius / cfg.cs); - cfg.maxEdgeLen = (int)(edgemaxlen/cellsize); - cfg.maxSimplificationError = edgemaxerror; - cfg.minRegionSize = (int)rcSqr(regionminsize); - cfg.mergeRegionSize = (int)rcSqr(regionmergesize); - cfg.maxVertsPerPoly = vertsperpoly; - cfg.detailSampleDist = detailsampledist< 0.9f ? 0 : cellsize * detailsampledist; - cfg.detailSampleMaxError = cellheight * detailsamplemaxerror; -*/ -#if 0 - cfg.cs = recastParams.cellsize; - cfg.ch = recastParams.cellheight; - cfg.walkableSlopeAngle = recastParams.agentmaxslope/((float)M_PI)*180.f; - cfg.walkableHeight = (int)ceilf(recastParams.agentheight/ cfg.ch); - cfg.walkableClimb = (int)floorf(recastParams.agentmaxclimb / cfg.ch); - cfg.walkableRadius = (int)ceilf(recastParams.agentradius / cfg.cs); - cfg.maxEdgeLen = (int)(recastParams.edgemaxlen/recastParams.cellsize); - cfg.maxSimplificationError = recastParams.edgemaxerror; - cfg.minRegionSize = (int)rcSqr(recastParams.regionminsize); - cfg.mergeRegionSize = (int)rcSqr(recastParams.regionmergesize); - cfg.maxVertsPerPoly = recastParams.vertsperpoly; - cfg.detailSampleDist = recastParams.detailsampledist< 0.9f ? 0 : - recastParams.cellsize * recastParams.detailsampledist; - cfg.detailSampleMaxError = recastParams.cellheight * recastParams.detailsamplemaxerror; -#endif - } - - walkableHeight = (int)ceilf(recastParams->agentheight/ recastParams->cellheight); - walkableClimb = (int)floorf(recastParams->agentmaxclimb / recastParams->cellheight); - walkableRadius = (int)ceilf(recastParams->agentradius / recastParams->cellsize); - minRegionSize = (int)(recastParams->regionminsize * recastParams->regionminsize); - mergeRegionSize = (int)(recastParams->regionmergesize * recastParams->regionmergesize); - maxEdgeLen = (int)(recastParams->edgemaxlen/recastParams->cellsize); - detailSampleDist = recastParams->detailsampledist< 0.9f ? 0 : - recastParams->cellsize * recastParams->detailsampledist; - detailSampleMaxError = recastParams->cellheight * recastParams->detailsamplemaxerror; - - // Set the area where the navigation will be build. - recast_calcGridSize(bmin, bmax, recastParams->cellsize, &width, &height); - - // - // Step 2. Rasterize input polygon soup. - // - // Allocate voxel heightfield where we rasterize our input data to. - solid = recast_newHeightfield(); - - if (!recast_createHeightfield(solid, width, height, bmin, bmax, recastParams->cellsize, recastParams->cellheight)) { - recast_destroyHeightfield(solid); - - return 0; - } - - // Allocate array that can hold triangle flags. - triflags = MEM_callocN(sizeof(unsigned char)*ntris, "triflags"); - - // Find triangles which are walkable based on their slope and rasterize them. - recast_markWalkableTriangles(RAD2DEG(recastParams->agentmaxslope), verts, nverts, tris, ntris, triflags); - recast_rasterizeTriangles(verts, nverts, tris, triflags, ntris, solid); - MEM_freeN(triflags); - - // - // Step 3. Filter walkables surfaces. - // - recast_filterLedgeSpans(walkableHeight, walkableClimb, solid); - recast_filterWalkableLowHeightSpans(walkableHeight, solid); - - // - // Step 4. Partition walkable surface to simple regions. - // - - chf = recast_newCompactHeightfield(); - if (!recast_buildCompactHeightfield(walkableHeight, walkableClimb, RECAST_WALKABLE, solid, chf)) { - recast_destroyHeightfield(solid); - recast_destroyCompactHeightfield(chf); - - return 0; - } - - recast_destroyHeightfield(solid); - - // Prepare for region partitioning, by calculating distance field along the walkable surface. - if (!recast_buildDistanceField(chf)) { - recast_destroyCompactHeightfield(chf); - - return 0; - } - - // Partition the walkable surface into simple regions without holes. - if (!recast_buildRegions(chf, walkableRadius, 0, minRegionSize, mergeRegionSize)) { - recast_destroyCompactHeightfield(chf); - - return 0; - } - - // - // Step 5. Trace and simplify region contours. - // - // Create contours. - cset = recast_newContourSet(); - - if (!recast_buildContours(chf, recastParams->edgemaxerror, maxEdgeLen, cset)) { - recast_destroyCompactHeightfield(chf); - recast_destroyContourSet(cset); - - return 0; - } - - // - // Step 6. Build polygons mesh from contours. - // - *pmesh = recast_newPolyMesh(); - if (!recast_buildPolyMesh(cset, recastParams->vertsperpoly, *pmesh)) { - recast_destroyCompactHeightfield(chf); - recast_destroyContourSet(cset); - recast_destroyPolyMesh(*pmesh); - - return 0; - } - - - // - // Step 7. Create detail mesh which allows to access approximate height on each polygon. - // - - *dmesh = recast_newPolyMeshDetail(); - if (!recast_buildPolyMeshDetail(*pmesh, chf, detailSampleDist, detailSampleMaxError, *dmesh)) { - recast_destroyCompactHeightfield(chf); - recast_destroyContourSet(cset); - recast_destroyPolyMesh(*pmesh); - recast_destroyPolyMeshDetail(*dmesh); - - return 0; - } - - recast_destroyCompactHeightfield(chf); - recast_destroyContourSet(cset); - - return 1; -} - -static Object* createRepresentation(bContext *C, struct recast_polyMesh *pmesh, struct recast_polyMeshDetail *dmesh, Base* base) -{ - float co[3], rot[3]; - EditMesh *em; - int i,j, k; - unsigned short* v; - int face[3]; - Main *bmain = CTX_data_main(C); - Scene *scene= CTX_data_scene(C); - Object* obedit; - int createob = base==NULL; - int nverts, nmeshes, nvp; - unsigned short *verts, *meshes, *polys; - float bmin[3], cs, ch, *dverts; - unsigned char *tris; - ModifierData *md; - - zero_v3(co); - zero_v3(rot); - - if (createob) - { - //create new object - obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1); - } - else - { - obedit = base->object; - scene_select_base(scene, base); - copy_v3_v3(obedit->loc, co); - copy_v3_v3(obedit->rot, rot); - } - - ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); - em = BKE_mesh_get_editmesh(((Mesh *)obedit->data)); - - if (!createob) - { - //clear - if(em->verts.first) free_vertlist(em, &em->verts); - if(em->edges.first) free_edgelist(em, &em->edges); - if(em->faces.first) free_facelist(em, &em->faces); - if(em->selected.first) BLI_freelistN(&(em->selected)); - } - - //create verts for polygon mesh - verts = recast_polyMeshGetVerts(pmesh, &nverts); - recast_polyMeshGetBoundbox(pmesh, bmin, NULL); - recast_polyMeshGetCell(pmesh, &cs, &ch); - - for(i = 0; i < nverts; i++) { - v = &verts[3*i]; - co[0] = bmin[0] + v[0]*cs; - co[1] = bmin[1] + v[1]*ch; - co[2] = bmin[2] + v[2]*cs; - SWAP(float, co[1], co[2]); - addvertlist(em, co, NULL); - } - - //create custom data layer to save polygon idx - CustomData_add_layer_named(&em->fdata, CD_RECAST, CD_CALLOC, NULL, 0, "recastData"); - - //create verts and faces for detailed mesh - meshes = recast_polyMeshDetailGetMeshes(dmesh, &nmeshes); - polys = recast_polyMeshGetPolys(pmesh, NULL, &nvp); - dverts = recast_polyMeshDetailGetVerts(dmesh, NULL); - tris = recast_polyMeshDetailGetTris(dmesh, NULL); - - for (i=0; itotvert; - unsigned short vbase = meshes[4*i+0]; - unsigned short ndv = meshes[4*i+1]; - unsigned short tribase = meshes[4*i+2]; - unsigned short trinum = meshes[4*i+3]; - const unsigned short* p = &polys[i*nvp*2]; - int nv = 0; - for (j = 0; j < nvp; ++j) - { - if (p[j] == 0xffff) break; - nv++; - } - //create unique verts - for (j=nv; jfdata, newFace->data, CD_RECAST); - *polygonIdx = i+1; //add 1 to avoid zero idx - } - - EM_free_index_arrays(); - } - - recast_destroyPolyMesh(pmesh); - recast_destroyPolyMeshDetail(dmesh); - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - - ED_object_exit_editmode(C, EM_FREEDATA); - WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); - - if (createob) - { - obedit->gameflag &= ~OB_COLLISION; - obedit->gameflag |= OB_NAVMESH; - obedit->body_type = OB_BODY_TYPE_NAVMESH; - rename_id((ID *)obedit, "Navmesh"); - } - - md= modifiers_findByType(obedit, eModifierType_NavMesh); - if (!md) - { - ED_object_modifier_add(NULL, bmain, scene, obedit, NULL, eModifierType_NavMesh); - } - - return obedit; -} - -static int create_navmesh_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Scene* scene = CTX_data_scene(C); - int nverts, ntris; - float* verts; - int* tris; - struct recast_polyMesh *pmesh; - struct recast_polyMeshDetail *dmesh; - LinkNode* obs = NULL; - Base* navmeshBase = NULL; - - //CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) //expand macros to avoid error in convertion from void* - { - ListBase ctx_data_list; - CollectionPointerLink *ctx_link; - CTX_data_selected_editable_bases(C, &ctx_data_list); - for(ctx_link = (CollectionPointerLink *)ctx_data_list.first; - ctx_link; ctx_link = (CollectionPointerLink *)ctx_link->next) { - Base* base= (Base*)ctx_link->ptr.data; - { - if (base->object->body_type==OB_BODY_TYPE_NAVMESH) - { - if (!navmeshBase || base==CTX_data_active_base(C)) - navmeshBase = base; - } - else - BLI_linklist_append(&obs, (void*)base->object); - } - CTX_DATA_END; - createVertsTrisData(C, obs, &nverts, &verts, &ntris, &tris); - BLI_linklist_free(obs, NULL); - buildNavMesh(&scene->gm.recastData, nverts, verts, ntris, tris, &pmesh, &dmesh); - createRepresentation(C, pmesh, dmesh, navmeshBase); - - return OPERATOR_FINISHED; -} - -void OBJECT_OT_create_navmesh(wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Create navigation mesh"; - ot->description= "Create navigation mesh for selected objects"; - ot->idname= "OBJECT_OT_create_navmesh"; - - /* api callbacks */ - ot->exec= create_navmesh_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int assign_navpolygon_poll(bContext *C) -{ - Object *ob= (Object *)CTX_data_pointer_get_type(C, "object", &RNA_Object).data; - if (!ob || !ob->data) - return 0; - return (((Mesh*)ob->data)->edit_mesh != NULL); -} - -static int assign_navpolygon_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - //do work here - int targetPolyIdx = -1; - EditFace *ef, *efa; - efa = EM_get_actFace(em, 0); - if (efa) - { - if (CustomData_has_layer(&em->fdata, CD_RECAST)) - { - targetPolyIdx = *(int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST); - targetPolyIdx = targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx; - if (targetPolyIdx>0) - { - //set target poly idx to other selected faces - ef = (EditFace*)em->faces.last; - while(ef) - { - if((ef->f & SELECT )&& ef!=efa) - { - int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - *recastDataBlock = targetPolyIdx; - } - ef = ef->prev; - } - } - } - } - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - return OPERATOR_FINISHED; -} - -void OBJECT_OT_assign_navpolygon(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Assign polygon index"; - ot->description= "Assign polygon index to face by active face"; - ot->idname= "OBJECT_OT_assign_navpolygon"; - - /* api callbacks */ - ot->poll = assign_navpolygon_poll; - ot->exec= assign_navpolygon_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} - -static int compare(const void * a, const void * b){ - return ( *(int*)a - *(int*)b ); -} - -static int findFreeNavPolyIndex(EditMesh* em) -{ - //construct vector of indices - int numfaces = em->totface; - int* indices = MEM_callocN(sizeof(int)*numfaces, "findFreeNavPolyIndex(indices)"); - EditFace* ef = (EditFace*)em->faces.last; - int i, idx = 0, freeIdx = 1; - - while(ef) - { - int polyIdx = *(int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - indices[idx] = polyIdx; - idx++; - ef = ef->prev; - } - - qsort(indices, numfaces, sizeof(int), compare); - - //search first free index - freeIdx = 1; - for (i=0; ifreeIdx) - break; - } - - MEM_freeN(indices); - - return freeIdx; -} - -static int assign_new_navpolygon_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit= CTX_data_edit_object(C); - EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); - - EditFace *ef; - if (CustomData_has_layer(&em->fdata, CD_RECAST)) - { - int targetPolyIdx = findFreeNavPolyIndex(em); - if (targetPolyIdx>0) - { - //set target poly idx to selected faces - ef = (EditFace*)em->faces.last; - while(ef) - { - if(ef->f & SELECT ) - { - int* recastDataBlock = (int*)CustomData_em_get(&em->fdata, ef->data, CD_RECAST); - *recastDataBlock = targetPolyIdx; - } - ef = ef->prev; - } - } - } - - DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); - - BKE_mesh_end_editmesh((Mesh*)obedit->data, em); - return OPERATOR_FINISHED; -} - -void OBJECT_OT_assign_new_navpolygon(struct wmOperatorType *ot) -{ - /* identifiers */ - ot->name= "Assign new polygon index"; - ot->description= "Assign new polygon index to face"; - ot->idname= "OBJECT_OT_assign_new_navpolygon"; - - /* api callbacks */ - ot->poll = assign_navpolygon_poll; - ot->exec= assign_new_navpolygon_exec; - - /* flags */ - ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; -} diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index a9cb0423739..5a2437b1911 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -214,12 +214,6 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_bake_image); WM_operatortype_append(OBJECT_OT_drop_named_material); - -#ifdef WITH_GAMEENGINE - WM_operatortype_append(OBJECT_OT_create_navmesh); - WM_operatortype_append(OBJECT_OT_assign_navpolygon); - WM_operatortype_append(OBJECT_OT_assign_new_navpolygon); -#endif } -- cgit v1.2.3 From 018fa1540eaef603b28c04fd5b8533d21122e36f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 28 Sep 2011 05:53:40 +0000 Subject: whitespace edits, make formatting for functions consustent at least within the file. --- source/blender/editors/object/object_bake.c | 3 ++- source/blender/editors/object/object_vgroup.c | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) (limited to 'source/blender/editors/object') diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 07c006a7995..446c359b9f2 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -883,7 +883,8 @@ static void multiresbake_start(MultiresBakeRender *bkr) finish_images(bkr); } -static int multiresbake_check(bContext *C, wmOperator *op) { +static int multiresbake_check(bContext *C, wmOperator *op) +{ Scene *scene= CTX_data_scene(C); Object *ob; Mesh *me; diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index e55a99ae2ab..49205318fd4 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -756,7 +756,8 @@ static void vgroup_normalize(Object *ob) It returns the number that it added (0-2) It relies on verts having -1 for unassigned indices */ -static int tryToAddVerts(int *verts, int length, int a, int b) { +static int tryToAddVerts(int *verts, int length, int a, int b) +{ char containsA = FALSE; char containsB = FALSE; int added = 0; @@ -786,7 +787,8 @@ and returns an array of indices of size count count is an int passed by reference so it can be assigned the value of the length here. */ -static int* getSurroundingVerts(Mesh *me, int vert, int *count) { +static int* getSurroundingVerts(Mesh *me, int vert, int *count) +{ int length = 0; int *tverts; int *verts = NULL; @@ -848,7 +850,8 @@ static int* getSurroundingVerts(Mesh *me, int vert, int *count) { /* get a single point in space by averaging a point cloud (vectors of size 3) coord is the place the average is stored, points is the point cloud, count is the number of points in the cloud */ -static void getSingleCoordinate(MVert *points, int count, float coord[3]) { +static void getSingleCoordinate(MVert *points, int count, float coord[3]) +{ int i; zero_v3(coord); for(i = 0; i < count; i++) { @@ -875,7 +878,8 @@ static void getNearestPointOnPlane(const float norm[3], const float coord[3], co } /* distance of two vectors a and b of size length */ -static float distance(float* a, float *b, int length) { +static float distance(float* a, float *b, int length) +{ int i; float sum = 0; for(i = 0; i < length; i++) { @@ -888,7 +892,8 @@ static float distance(float* a, float *b, int length) { compute the amount of vertical distance relative to the plane and store it in dists, then get the horizontal and vertical change and store them in changes */ -static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float (*changes)[2], float *dists, int index) { +static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, float *start, float distToStart, float *end, float (*changes)[2], float *dists, int index) +{ // A=Q-((Q-P).N)N // D = (a*x0 + b*y0 +c*z0 +d) float projA[3] = {0}, projB[3] = {0}; @@ -906,7 +911,8 @@ static void getVerticalAndHorizontalChange(float *norm, float d, float *coord, f } // I need the derived mesh to be forgotten so the positions are recalculated with weight changes (see dm_deform_recalc) -static void dm_deform_clear(DerivedMesh *dm, Object *ob) { +static void dm_deform_clear(DerivedMesh *dm, Object *ob) +{ if(ob->derivedDeform && (ob->derivedDeform)==dm) { ob->derivedDeform->needsFree = 1; ob->derivedDeform->release(ob->derivedDeform); @@ -919,7 +925,8 @@ static void dm_deform_clear(DerivedMesh *dm, Object *ob) { } // recalculate the deformation -static DerivedMesh* dm_deform_recalc(Scene *scene, Object *ob) { +static DerivedMesh* dm_deform_recalc(Scene *scene, Object *ob) +{ return mesh_get_derived_deform(scene, ob, CD_MASK_BAREMESH); } @@ -931,7 +938,8 @@ index is the index of the vertex being moved norm and d are the plane's properties for the equation: ax + by + cz + d = 0 coord is a point on the plane */ -static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) { +static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, int index, float norm[3], float coord[3], float d, float distToBe, float strength, float cp) +{ DerivedMesh *dm; MDeformWeight *dw; MVert m; -- cgit v1.2.3