forked from bartvdbraak/blender
- fixed bug in steering actuator: calculate 2d distance to target for seeking and fleeing
- added possibility to add navmesh modifier manually in order to transform manually created mesh to navigation mesh (with navigation polygons data layer) - added possibility to use existed navigation mesh object for navmesh generation (so new object won't be created, but existed object will be updated)
This commit is contained in:
parent
14171324b7
commit
870e0e37e5
@ -310,11 +310,18 @@ bool buildNavMeshData(const int nverts, const float* verts,
|
|||||||
{
|
{
|
||||||
memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3);
|
memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3);
|
||||||
}
|
}
|
||||||
//create new recast data corresponded to dtris
|
//create new recast data corresponded to dtris and renumber for continious indices
|
||||||
|
int prevPolyIdx=-1, curPolyIdx, newPolyIdx=0;
|
||||||
dtrisToPolysMap = new int[ndtris];
|
dtrisToPolysMap = new int[ndtris];
|
||||||
for (int i=0; i<ndtris; i++)
|
for (int i=0; i<ndtris; i++)
|
||||||
{
|
{
|
||||||
dtrisToPolysMap[i] = recastData[trisToFacesMap[dtrisToTrisMap[i]]];
|
curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]];
|
||||||
|
if (curPolyIdx!=prevPolyIdx)
|
||||||
|
{
|
||||||
|
newPolyIdx++;
|
||||||
|
prevPolyIdx=curPolyIdx;
|
||||||
|
}
|
||||||
|
dtrisToPolysMap[i] = newPolyIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -43,6 +43,8 @@ extern "C"
|
|||||||
#include "BKE_depsgraph.h"
|
#include "BKE_depsgraph.h"
|
||||||
#include "BKE_context.h"
|
#include "BKE_context.h"
|
||||||
#include "BKE_mesh.h"
|
#include "BKE_mesh.h"
|
||||||
|
#include "BKE_modifier.h"
|
||||||
|
#include "BKE_scene.h"
|
||||||
#include "BKE_DerivedMesh.h"
|
#include "BKE_DerivedMesh.h"
|
||||||
#include "BKE_cdderivedmesh.h"
|
#include "BKE_cdderivedmesh.h"
|
||||||
#include "BLI_editVert.h"
|
#include "BLI_editVert.h"
|
||||||
@ -57,6 +59,9 @@ extern "C"
|
|||||||
/*mesh/mesh_intern.h */
|
/*mesh/mesh_intern.h */
|
||||||
extern struct EditVert *addvertlist(EditMesh *em, float *vec, struct EditVert *example);
|
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 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_api.h"
|
||||||
#include "WM_types.h"
|
#include "WM_types.h"
|
||||||
@ -301,23 +306,43 @@ static bool buildNavMesh(const RecastData& recastParams, int nverts, float* vert
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh)
|
static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshDetail*& dmesh, Base* base)
|
||||||
{
|
{
|
||||||
Object *obedit;
|
|
||||||
float co[3], rot[3];
|
float co[3], rot[3];
|
||||||
EditMesh *em;
|
EditMesh *em;
|
||||||
int i,j, k, polyverts;
|
int i,j, k, polyverts;
|
||||||
unsigned short* v;
|
unsigned short* v;
|
||||||
int face[3];
|
int face[3];
|
||||||
Scene *scene= CTX_data_scene(C);
|
Scene *scene= CTX_data_scene(C);
|
||||||
|
Object* obedit;
|
||||||
|
int createob = base==NULL;
|
||||||
zero_v3(co);
|
zero_v3(co);
|
||||||
zero_v3(rot);
|
zero_v3(rot);
|
||||||
|
if (createob)
|
||||||
|
{
|
||||||
|
//create new object
|
||||||
obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1);
|
obedit = ED_object_add_type(C, OB_MESH, co, rot, FALSE, 1);
|
||||||
ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER);
|
}
|
||||||
|
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));
|
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
|
//create verts for polygon mesh
|
||||||
for(i = 0; i < pmesh->nverts; i++) {
|
for(i = 0; i < pmesh->nverts; i++) {
|
||||||
v = &pmesh->verts[3*i];
|
v = &pmesh->verts[3*i];
|
||||||
@ -392,13 +417,20 @@ static Object* createRepresentation(bContext *C, rcPolyMesh*& pmesh, rcPolyMeshD
|
|||||||
ED_object_exit_editmode(C, EM_FREEDATA);
|
ED_object_exit_editmode(C, EM_FREEDATA);
|
||||||
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
|
WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit);
|
||||||
|
|
||||||
|
if (createob)
|
||||||
|
{
|
||||||
obedit->gameflag &= ~OB_COLLISION;
|
obedit->gameflag &= ~OB_COLLISION;
|
||||||
obedit->gameflag |= OB_NAVMESH;
|
obedit->gameflag |= OB_NAVMESH;
|
||||||
obedit->body_type = OB_BODY_TYPE_NAVMESH;
|
obedit->body_type = OB_BODY_TYPE_NAVMESH;
|
||||||
rename_id((ID *)obedit, "Navmesh");
|
rename_id((ID *)obedit, "Navmesh");
|
||||||
|
}
|
||||||
|
|
||||||
|
ModifierData *md= modifiers_findByType(obedit, eModifierType_NavMesh);
|
||||||
|
if (!md)
|
||||||
|
{
|
||||||
ED_object_modifier_add(NULL, scene, obedit, NULL, eModifierType_NavMesh);
|
ED_object_modifier_add(NULL, scene, obedit, NULL, eModifierType_NavMesh);
|
||||||
//ModifierData *md= modifiers_findByType(ob, eModifierType_NavMesh);
|
}
|
||||||
|
|
||||||
return obedit;
|
return obedit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,15 +443,22 @@ static int create_navmesh_exec(bContext *C, wmOperator *op)
|
|||||||
rcPolyMesh* pmesh;
|
rcPolyMesh* pmesh;
|
||||||
rcPolyMeshDetail* dmesh;
|
rcPolyMeshDetail* dmesh;
|
||||||
LinkNode* obs = NULL;
|
LinkNode* obs = NULL;
|
||||||
|
Base* navmeshBase = NULL;
|
||||||
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases)
|
CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases)
|
||||||
{
|
{
|
||||||
|
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);
|
BLI_linklist_append(&obs, (void*)base->object);
|
||||||
}
|
}
|
||||||
CTX_DATA_END;
|
CTX_DATA_END;
|
||||||
createVertsTrisData(C, obs, nverts, verts, ntris, tris);
|
createVertsTrisData(C, obs, nverts, verts, ntris, tris);
|
||||||
BLI_linklist_free(obs, NULL);
|
BLI_linklist_free(obs, NULL);
|
||||||
buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh);
|
buildNavMesh(scene->gm.recastData, nverts, verts, ntris, tris, pmesh, dmesh);
|
||||||
createRepresentation(C, pmesh, dmesh);
|
createRepresentation(C, pmesh, dmesh, navmeshBase);
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
@ -520,7 +559,6 @@ static int findFreeNavPolyIndex(EditMesh* em)
|
|||||||
qsort(indices, numfaces, sizeof(int), compare);
|
qsort(indices, numfaces, sizeof(int), compare);
|
||||||
//search first free index
|
//search first free index
|
||||||
int freeIdx = 1;
|
int freeIdx = 1;
|
||||||
int maxIdx = indices[numfaces-1];
|
|
||||||
for (int i=0; i<numfaces; i++)
|
for (int i=0; i<numfaces; i++)
|
||||||
{
|
{
|
||||||
if (indices[i]==freeIdx)
|
if (indices[i]==freeIdx)
|
||||||
|
@ -61,7 +61,6 @@ EnumPropertyItem modifier_type_items[] ={
|
|||||||
{eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
|
{eModifierType_Solidify, "SOLIDIFY", ICON_MOD_SOLIDIFY, "Solidify", ""},
|
||||||
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
|
{eModifierType_Subsurf, "SUBSURF", ICON_MOD_SUBSURF, "Subdivision Surface", ""},
|
||||||
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
|
{eModifierType_UVProject, "UV_PROJECT", ICON_MOD_UVPROJECT, "UV Project", ""},
|
||||||
{eModifierType_NavMesh, "NAVMESH", ICON_MOD_DECIM, "Navigation mesh", ""},
|
|
||||||
{0, "", 0, "Deform", ""},
|
{0, "", 0, "Deform", ""},
|
||||||
{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
|
{eModifierType_Armature, "ARMATURE", ICON_MOD_ARMATURE, "Armature", ""},
|
||||||
{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
|
{eModifierType_Cast, "CAST", ICON_MOD_CAST, "Cast", ""},
|
||||||
@ -84,6 +83,7 @@ EnumPropertyItem modifier_type_items[] ={
|
|||||||
{eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""},
|
{eModifierType_Smoke, "SMOKE", ICON_MOD_SMOKE, "Smoke", ""},
|
||||||
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
|
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
|
||||||
{eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""},
|
{eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""},
|
||||||
|
{eModifierType_NavMesh, "NAVMESH", ICON_MOD_PHYSICS, "Navigation mesh", ""},
|
||||||
{0, NULL, 0, NULL, NULL}};
|
{0, NULL, 0, NULL, NULL}};
|
||||||
|
|
||||||
#ifdef RNA_RUNTIME
|
#ifdef RNA_RUNTIME
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#include "NavMeshConversion.h"
|
#include "NavMeshConversion.h"
|
||||||
|
|
||||||
extern "C"{
|
extern "C"{
|
||||||
|
#include "DNA_mesh_types.h"
|
||||||
#include "DNA_meshdata_types.h"
|
#include "DNA_meshdata_types.h"
|
||||||
#include "BLI_math.h"
|
#include "BLI_math.h"
|
||||||
#include "BKE_cdderivedmesh.h"
|
#include "BKE_cdderivedmesh.h"
|
||||||
@ -125,9 +125,6 @@ static void navDM_drawFacesSolid(DerivedMesh *dm,
|
|||||||
static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm)
|
static DerivedMesh *createNavMeshForVisualization(NavMeshModifierData *mmd,DerivedMesh *dm)
|
||||||
{
|
{
|
||||||
DerivedMesh *result;
|
DerivedMesh *result;
|
||||||
int numVerts, numEdges, numFaces;
|
|
||||||
int maxVerts = dm->getNumVerts(dm);
|
|
||||||
int maxEdges = dm->getNumEdges(dm);
|
|
||||||
int maxFaces = dm->getNumFaces(dm);
|
int maxFaces = dm->getNumFaces(dm);
|
||||||
|
|
||||||
result = CDDM_copy(dm);
|
result = CDDM_copy(dm);
|
||||||
@ -209,8 +206,38 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
|
|||||||
{
|
{
|
||||||
DerivedMesh *result = NULL;
|
DerivedMesh *result = NULL;
|
||||||
NavMeshModifierData *nmmd = (NavMeshModifierData*) md;
|
NavMeshModifierData *nmmd = (NavMeshModifierData*) md;
|
||||||
|
bool hasRecastData = CustomData_has_layer(&derivedData->faceData, CD_PROP_INT)>0;
|
||||||
|
if (ob->body_type!=OB_BODY_TYPE_NAVMESH || !hasRecastData )
|
||||||
|
{
|
||||||
|
//convert to nav mesh object:
|
||||||
|
//1)set physics type
|
||||||
|
ob->gameflag &= ~OB_COLLISION;
|
||||||
|
ob->gameflag |= OB_NAVMESH;
|
||||||
|
ob->body_type = OB_BODY_TYPE_NAVMESH;
|
||||||
|
//2)add and init recast data layer
|
||||||
|
if (!hasRecastData)
|
||||||
|
{
|
||||||
|
int numFaces = derivedData->getNumFaces(derivedData);
|
||||||
|
CustomData_add_layer_named(&derivedData->faceData, CD_PROP_INT, CD_CALLOC, NULL, numFaces, "recastData");
|
||||||
|
int* recastData = (int*)CustomData_get_layer(&derivedData->faceData, CD_PROP_INT);
|
||||||
|
for (int i=0; i<numFaces; i++)
|
||||||
|
{
|
||||||
|
recastData[i] = i+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh* obmesh = (Mesh *)ob->data;
|
||||||
|
if (obmesh)
|
||||||
|
{
|
||||||
|
CustomData_add_layer_named(&obmesh->fdata, CD_PROP_INT, CD_CALLOC, NULL, numFaces, "recastData");
|
||||||
|
int* recastData = (int*)CustomData_get_layer(&obmesh->fdata, CD_PROP_INT);
|
||||||
|
for (int i=0; i<numFaces; i++)
|
||||||
|
{
|
||||||
|
recastData[i] = i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ob->body_type==OB_BODY_TYPE_NAVMESH)
|
|
||||||
result = createNavMeshForVisualization(nmmd, derivedData);
|
result = createNavMeshForVisualization(nmmd, derivedData);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -223,7 +250,7 @@ ModifierTypeInfo modifierType_NavMesh = {
|
|||||||
/* structSize */ sizeof(NavMeshModifierData),
|
/* structSize */ sizeof(NavMeshModifierData),
|
||||||
/* type */ eModifierTypeType_Constructive,
|
/* type */ eModifierTypeType_Constructive,
|
||||||
/* flags */ (ModifierTypeFlag) (eModifierTypeFlag_AcceptsMesh
|
/* flags */ (ModifierTypeFlag) (eModifierTypeFlag_AcceptsMesh
|
||||||
| eModifierTypeFlag_NoUserAdd),
|
| eModifierTypeFlag_Single),
|
||||||
/* copyData */ copyData,
|
/* copyData */ copyData,
|
||||||
/* deformVerts */ 0,
|
/* deformVerts */ 0,
|
||||||
/* deformVertsEM */ 0,
|
/* deformVertsEM */ 0,
|
||||||
|
@ -173,13 +173,15 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
|||||||
const MT_Point3& mypos = obj->NodeGetWorldPosition();
|
const MT_Point3& mypos = obj->NodeGetWorldPosition();
|
||||||
const MT_Point3& targpos = m_target->NodeGetWorldPosition();
|
const MT_Point3& targpos = m_target->NodeGetWorldPosition();
|
||||||
MT_Vector3 vectotarg = targpos - mypos;
|
MT_Vector3 vectotarg = targpos - mypos;
|
||||||
|
MT_Vector3 vectotarg2d = vectotarg;
|
||||||
|
vectotarg2d.z() = 0;
|
||||||
MT_Vector3 steervec = MT_Vector3(0, 0, 0);
|
MT_Vector3 steervec = MT_Vector3(0, 0, 0);
|
||||||
bool apply_steerforce = false;
|
bool apply_steerforce = false;
|
||||||
bool terminate = true;
|
bool terminate = true;
|
||||||
|
|
||||||
switch (m_mode) {
|
switch (m_mode) {
|
||||||
case KX_STEERING_SEEK:
|
case KX_STEERING_SEEK:
|
||||||
if (vectotarg.length2()>m_distance*m_distance)
|
if (vectotarg2d.length2()>m_distance*m_distance)
|
||||||
{
|
{
|
||||||
terminate = false;
|
terminate = false;
|
||||||
steervec = vectotarg;
|
steervec = vectotarg;
|
||||||
@ -188,7 +190,7 @@ bool KX_SteeringActuator::Update(double curtime, bool frame)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KX_STEERING_FLEE:
|
case KX_STEERING_FLEE:
|
||||||
if (vectotarg.length2()<m_distance*m_distance)
|
if (vectotarg2d.length2()<m_distance*m_distance)
|
||||||
{
|
{
|
||||||
terminate = false;
|
terminate = false;
|
||||||
steervec = -vectotarg;
|
steervec = -vectotarg;
|
||||||
|
Loading…
Reference in New Issue
Block a user