Changeset View
Changeset View
Standalone View
Standalone View
source/gameengine/Ketsji/KX_NavMeshObject.cpp
| Context not available. | |||||
| #include "KX_NavMeshObject.h" | #include "KX_NavMeshObject.h" | ||||
| #include "RAS_MeshObject.h" | #include "RAS_MeshObject.h" | ||||
| #include "RAS_Polygon.h" | #include "RAS_Polygon.h" | ||||
| #include "RAS_ITexVert.h" | |||||
| #include "DNA_mesh_types.h" | #include "DNA_mesh_types.h" | ||||
| #include "DNA_meshdata_types.h" | #include "DNA_meshdata_types.h" | ||||
| Context not available. | |||||
| #include "BKE_navmesh_conversion.h" | #include "BKE_navmesh_conversion.h" | ||||
| } | } | ||||
| #include "KX_PythonInit.h" | #include "KX_Globals.h" | ||||
| #include "KX_PyMath.h" | #include "KX_PyMath.h" | ||||
| #include "EXP_Value.h" | #include "EXP_Value.h" | ||||
| #include "Recast.h" | #include "Recast.h" | ||||
| #include "DetourStatNavMeshBuilder.h" | #include "DetourStatNavMeshBuilder.h" | ||||
| #include "KX_ObstacleSimulation.h" | #include "KX_ObstacleSimulation.h" | ||||
| #include "CM_Message.h" | |||||
| #define MAX_PATH_LEN 256 | #define MAX_PATH_LEN 256 | ||||
| static const float polyPickExt[3] = {2, 4, 2}; | static const float polyPickExt[3] = {2, 4, 2}; | ||||
| Context not available. | |||||
| KX_GameObject::ProcessReplica(); | KX_GameObject::ProcessReplica(); | ||||
| m_navMesh = NULL; /* without this, building frees the navmesh we copied from */ | m_navMesh = NULL; /* without this, building frees the navmesh we copied from */ | ||||
| if (!BuildNavMesh()) { | if (!BuildNavMesh()) { | ||||
| std::cout << "Error in " << __func__ << ": unable to build navigation mesh" << std::endl; | CM_FunctionError("unable to build navigation mesh"); | ||||
| return; | return; | ||||
| } | } | ||||
| KX_Scene* scene = KX_GetActiveScene(); | KX_ObstacleSimulation* obssimulation = GetScene()->GetObstacleSimulation(); | ||||
| KX_ObstacleSimulation* obssimulation = scene->GetObstacleSimulation(); | |||||
| if (obssimulation) | if (obssimulation) | ||||
| obssimulation->AddObstaclesForNavMesh(this); | obssimulation->AddObstaclesForNavMesh(this); | ||||
| } | } | ||||
| Context not available. | |||||
| int idxInPoly = polyFindVertex(poly, vertsPerPoly, newVertexIdx); | int idxInPoly = polyFindVertex(poly, vertsPerPoly, newVertexIdx); | ||||
| if (idxInPoly==-1) | if (idxInPoly==-1) | ||||
| { | { | ||||
| printf("Building NavMeshObject: Error! Can't find vertex in polygon\n"); | CM_Error("building NavMeshObject, can't find vertex in polygon\n"); | ||||
| return false; | return false; | ||||
| } | } | ||||
| dtri[k] = idxInPoly; | dtri[k] = idxInPoly; | ||||
| Context not available. | |||||
| raspoly = meshobj->GetPolygon(p); | raspoly = meshobj->GetPolygon(p); | ||||
| for (int v=0; v<raspoly->VertexCount()-2; v++) | for (int v=0; v<raspoly->VertexCount()-2; v++) | ||||
| { | { | ||||
| poly[0] = raspoly->GetVertex(0)->getOrigIndex(); | poly[0] = raspoly->GetVertexInfo(0).getOrigIndex(); | ||||
| for (size_t i=1; i<3; i++) | for (size_t i=1; i<3; i++) | ||||
| { | { | ||||
| poly[i] = raspoly->GetVertex(v+i)->getOrigIndex(); | poly[i] = raspoly->GetVertexInfo(v+i).getOrigIndex(); | ||||
| } | } | ||||
| poly += 6; | poly += 6; | ||||
| } | } | ||||
| Context not available. | |||||
| if (GetMeshCount()==0) | if (GetMeshCount()==0) | ||||
| { | { | ||||
| printf("Can't find mesh for navmesh object: %s\n", m_name.ReadPtr()); | CM_Error("can't find mesh for navmesh object: " << m_name); | ||||
| return false; | return false; | ||||
| } | } | ||||
| Context not available. | |||||
| dmeshes, dvertices, ndvertsuniq, dtris, ndtris, vertsPerPoly ) | dmeshes, dvertices, ndvertsuniq, dtris, ndtris, vertsPerPoly ) | ||||
| || vertsPerPoly<3) | || vertsPerPoly<3) | ||||
| { | { | ||||
| printf("Can't build navigation mesh data for object:%s\n", m_name.ReadPtr()); | CM_Error("can't build navigation mesh data for object: " << m_name); | ||||
| if (vertices) { | if (vertices) { | ||||
| delete[] vertices; | delete[] vertices; | ||||
| } | } | ||||
| Context not available. | |||||
| return false; | return false; | ||||
| } | } | ||||
| MT_Point3 pos; | MT_Vector3 pos; | ||||
| if (dmeshes==NULL) | if (dmeshes==NULL) | ||||
| { | { | ||||
| for (int i=0; i<nverts; i++) | for (int i=0; i<nverts; i++) | ||||
| Context not available. | |||||
| } | } | ||||
| if (!buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly)) { | if (!buildMeshAdjacency(polys, npolys, nverts, vertsPerPoly)) { | ||||
| std::cout << __func__ << ": unable to build mesh adjacency information." << std::endl; | CM_FunctionError("unable to build mesh adjacency information."); | ||||
| delete[] vertices; | delete[] vertices; | ||||
| return false; | return false; | ||||
| } | } | ||||
| Context not available. | |||||
| { | { | ||||
| if (!m_navMesh) | if (!m_navMesh) | ||||
| return; | return; | ||||
| MT_Vector3 color(0.f, 0.f, 0.f); | MT_Vector4 color(0.0f, 0.0f, 0.0f, 1.0f); | ||||
| switch (renderMode) | switch (renderMode) | ||||
| { | { | ||||
| Context not available. | |||||
| continue; | continue; | ||||
| const float* vif = m_navMesh->getVertex(poly->v[i]); | const float* vif = m_navMesh->getVertex(poly->v[i]); | ||||
| const float* vjf = m_navMesh->getVertex(poly->v[j]); | const float* vjf = m_navMesh->getVertex(poly->v[j]); | ||||
| MT_Point3 vi(vif[0], vif[2], vif[1]); | MT_Vector3 vi(vif[0], vif[2], vif[1]); | ||||
| MT_Point3 vj(vjf[0], vjf[2], vjf[1]); | MT_Vector3 vj(vjf[0], vjf[2], vjf[1]); | ||||
| vi = TransformToWorldCoords(vi); | vi = TransformToWorldCoords(vi); | ||||
| vj = TransformToWorldCoords(vj); | vj = TransformToWorldCoords(vj); | ||||
| KX_RasterizerDrawDebugLine(vi, vj, color); | KX_RasterizerDrawDebugLine(vi, vj, color); | ||||
| Context not available. | |||||
| for (int j = 0; j < pd->ntris; ++j) | for (int j = 0; j < pd->ntris; ++j) | ||||
| { | { | ||||
| const unsigned char* t = m_navMesh->getDetailTri(pd->tbase+j); | const unsigned char* t = m_navMesh->getDetailTri(pd->tbase+j); | ||||
| MT_Point3 tri[3]; | MT_Vector3 tri[3]; | ||||
| for (int k = 0; k < 3; ++k) | for (int k = 0; k < 3; ++k) | ||||
| { | { | ||||
| const float* v; | const float* v; | ||||
| Context not available. | |||||
| } | } | ||||
| } | } | ||||
| MT_Point3 KX_NavMeshObject::TransformToLocalCoords(const MT_Point3& wpos) | MT_Vector3 KX_NavMeshObject::TransformToLocalCoords(const MT_Vector3& wpos) | ||||
| { | { | ||||
| MT_Matrix3x3 orientation = NodeGetWorldOrientation(); | MT_Matrix3x3 orientation = NodeGetWorldOrientation(); | ||||
| const MT_Vector3& scaling = NodeGetWorldScaling(); | const MT_Vector3& scaling = NodeGetWorldScaling(); | ||||
| Context not available. | |||||
| MT_Transform worldtr(NodeGetWorldPosition(), orientation); | MT_Transform worldtr(NodeGetWorldPosition(), orientation); | ||||
| MT_Transform invworldtr; | MT_Transform invworldtr; | ||||
| invworldtr.invert(worldtr); | invworldtr.invert(worldtr); | ||||
| MT_Point3 lpos = invworldtr(wpos); | MT_Vector3 lpos = invworldtr(wpos); | ||||
| return lpos; | return lpos; | ||||
| } | } | ||||
| MT_Point3 KX_NavMeshObject::TransformToWorldCoords(const MT_Point3& lpos) | MT_Vector3 KX_NavMeshObject::TransformToWorldCoords(const MT_Vector3& lpos) | ||||
| { | { | ||||
| MT_Matrix3x3 orientation = NodeGetWorldOrientation(); | MT_Matrix3x3 orientation = NodeGetWorldOrientation(); | ||||
| const MT_Vector3& scaling = NodeGetWorldScaling(); | const MT_Vector3& scaling = NodeGetWorldScaling(); | ||||
| orientation.scale(scaling[0], scaling[1], scaling[2]); | orientation.scale(scaling[0], scaling[1], scaling[2]); | ||||
| MT_Transform worldtr(NodeGetWorldPosition(), orientation); | MT_Transform worldtr(NodeGetWorldPosition(), orientation); | ||||
| MT_Point3 wpos = worldtr(lpos); | MT_Vector3 wpos = worldtr(lpos); | ||||
| return wpos; | return wpos; | ||||
| } | } | ||||
| int KX_NavMeshObject::FindPath(const MT_Point3& from, const MT_Point3& to, float* path, int maxPathLen) | int KX_NavMeshObject::FindPath(const MT_Vector3& from, const MT_Vector3& to, float* path, int maxPathLen) | ||||
| { | { | ||||
| if (!m_navMesh) | if (!m_navMesh) | ||||
| return 0; | return 0; | ||||
| MT_Point3 localfrom = TransformToLocalCoords(from); | MT_Vector3 localfrom = TransformToLocalCoords(from); | ||||
| MT_Point3 localto = TransformToLocalCoords(to); | MT_Vector3 localto = TransformToLocalCoords(to); | ||||
| float spos[3], epos[3]; | float spos[3], epos[3]; | ||||
| localfrom.getValue(spos); flipAxes(spos); | localfrom.getValue(spos); flipAxes(spos); | ||||
| localto.getValue(epos); flipAxes(epos); | localto.getValue(epos); flipAxes(epos); | ||||
| Context not available. | |||||
| for (int i=0; i<pathLen; i++) | for (int i=0; i<pathLen; i++) | ||||
| { | { | ||||
| flipAxes(&path[i*3]); | flipAxes(&path[i*3]); | ||||
| MT_Point3 waypoint(&path[i*3]); | MT_Vector3 waypoint(&path[i*3]); | ||||
| waypoint = TransformToWorldCoords(waypoint); | waypoint = TransformToWorldCoords(waypoint); | ||||
| waypoint.getValue(&path[i*3]); | waypoint.getValue(&path[i*3]); | ||||
| } | } | ||||
| Context not available. | |||||
| return pathLen; | return pathLen; | ||||
| } | } | ||||
| float KX_NavMeshObject::Raycast(const MT_Point3& from, const MT_Point3& to) | float KX_NavMeshObject::Raycast(const MT_Vector3& from, const MT_Vector3& to) | ||||
| { | { | ||||
| if (!m_navMesh) | if (!m_navMesh) | ||||
| return 0.f; | return 0.f; | ||||
| MT_Point3 localfrom = TransformToLocalCoords(from); | MT_Vector3 localfrom = TransformToLocalCoords(from); | ||||
| MT_Point3 localto = TransformToLocalCoords(to); | MT_Vector3 localto = TransformToLocalCoords(to); | ||||
| float spos[3], epos[3]; | float spos[3], epos[3]; | ||||
| localfrom.getValue(spos); flipAxes(spos); | localfrom.getValue(spos); flipAxes(spos); | ||||
| localto.getValue(epos); flipAxes(epos); | localto.getValue(epos); flipAxes(epos); | ||||
| Context not available. | |||||
| return t; | return t; | ||||
| } | } | ||||
| void KX_NavMeshObject::DrawPath(const float *path, int pathLen, const MT_Vector3& color) | void KX_NavMeshObject::DrawPath(const float *path, int pathLen, const MT_Vector4& color) | ||||
| { | { | ||||
| MT_Vector3 a,b; | MT_Vector3 a,b; | ||||
| for (int i=0; i<pathLen-1; i++) | for (int i=0; i<pathLen-1; i++) | ||||
| Context not available. | |||||
| }; | }; | ||||
| PyAttributeDef KX_NavMeshObject::Attributes[] = { | PyAttributeDef KX_NavMeshObject::Attributes[] = { | ||||
| { NULL } //Sentinel | KX_PYATTRIBUTE_NULL //Sentinel | ||||
| }; | }; | ||||
| //KX_PYMETHODTABLE_NOARGS(KX_GameObject, getD), | //KX_PYMETHODTABLE_NOARGS(KX_GameObject, getD), | ||||
| Context not available. | |||||
| PyObject *ob_from, *ob_to; | PyObject *ob_from, *ob_to; | ||||
| if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) | if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) | ||||
| return NULL; | return NULL; | ||||
| MT_Point3 from, to; | MT_Vector3 from, to; | ||||
| if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) | if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) | ||||
| return NULL; | return NULL; | ||||
| Context not available. | |||||
| PyObject *pathList = PyList_New( pathLen ); | PyObject *pathList = PyList_New( pathLen ); | ||||
| for (int i=0; i<pathLen; i++) | for (int i=0; i<pathLen; i++) | ||||
| { | { | ||||
| MT_Point3 point(&path[3*i]); | MT_Vector3 point(&path[3*i]); | ||||
| PyList_SET_ITEM(pathList, i, PyObjectFrom(point)); | PyList_SET_ITEM(pathList, i, PyObjectFrom(point)); | ||||
| } | } | ||||
| Context not available. | |||||
| PyObject *ob_from, *ob_to; | PyObject *ob_from, *ob_to; | ||||
| if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) | if (!PyArg_ParseTuple(args,"OO:getPath",&ob_from,&ob_to)) | ||||
| return NULL; | return NULL; | ||||
| MT_Point3 from, to; | MT_Vector3 from, to; | ||||
| if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) | if (!PyVecTo(ob_from, from) || !PyVecTo(ob_to, to)) | ||||
| return NULL; | return NULL; | ||||
| float hit = Raycast(from, to); | float hit = Raycast(from, to); | ||||
| Context not available. | |||||