//------------------------------------------------------------------------------------- PyObject* ScriptVector3::__py_pyDistTo(PyObject* self, PyObject* args) { if (PyTuple_Size(args) != 1) { PyErr_SetString(PyExc_TypeError, "args > 1 is error!\n"); PyErr_PrintEx(0); S_Return; } ScriptVector3* sv = static_cast<ScriptVector3*>(self); Vector3& v = sv->getVector(); Vector3 v1; convertPyObjectToVector3(v1, PyTuple_GET_ITEM(args, 0)); Vector3 rv = (v - v1); return PyFloat_FromDouble(KBEVec3Length(&rv)); //计算长度并返回 }
//------------------------------------------------------------------------------------- int NavMeshHandle::findRandomPointAroundCircle(int layer, const Position3D& centerPos, std::vector<Position3D>& points, uint32 max_points, float maxRadius) { std::map<int, NavmeshLayer>::iterator iter = navmeshLayer.find(layer); if(iter == navmeshLayer.end()) { ERROR_MSG(fmt::format("NavMeshHandle::findRandomPointAroundCircle: not found layer({})\n", layer)); return NAV_ERROR; } dtNavMeshQuery* navmeshQuery = iter->second.pNavmeshQuery; dtQueryFilter filter; filter.setIncludeFlags(0xffff); filter.setExcludeFlags(0); if (maxRadius <= 0.0001f) { Position3D currpos; for (uint32 i = 0; i < max_points; i++) { float pt[3]; dtPolyRef ref; dtStatus status = navmeshQuery->findRandomPoint(&filter, frand, &ref, pt); if (dtStatusSucceed(status)) { currpos.x = pt[0]; currpos.y = pt[1]; currpos.z = pt[2]; points.push_back(currpos); } } return (int)points.size(); } const float extents[3] = {2.f, 4.f, 2.f}; dtPolyRef startRef = INVALID_NAVMESH_POLYREF; float spos[3]; spos[0] = centerPos.x; spos[1] = centerPos.y; spos[2] = centerPos.z; float startNearestPt[3]; navmeshQuery->findNearestPoly(spos, extents, &filter, &startRef, startNearestPt); if (!startRef) { ERROR_MSG(fmt::format("NavMeshHandle::findRandomPointAroundCircle({1}): Could not find any nearby poly's ({0})\n", startRef, resPath)); return NAV_ERROR_NEARESTPOLY; } Position3D currpos; bool done = false; int itry = 0; while (itry++ < 3 && points.size() == 0) { max_points -= points.size(); for (uint32 i = 0; i < max_points; i++) { float pt[3]; dtPolyRef ref; dtStatus status = navmeshQuery->findRandomPointAroundCircle(startRef, spos, maxRadius, &filter, frand, &ref, pt); if (dtStatusSucceed(status)) { done = true; currpos.x = pt[0]; currpos.y = pt[1]; currpos.z = pt[2]; Position3D v = centerPos - currpos; float dist_len = KBEVec3Length(&v); if (dist_len > maxRadius) continue; points.push_back(currpos); } } if (!done) break; } return (int)points.size(); }
//------------------------------------------------------------------------------------- bool MoveToPointHandler::update() { if(pController_ == NULL) { delete this; return false; } Entity* pEntity = pController_->pEntity(); const Position3D& dstPos = destPos(); Position3D currpos = pEntity->getPosition(); Direction3D direction = pEntity->getDirection(); Vector3 movement = dstPos - currpos; if (!moveVertically_) movement.y = 0.f; bool ret = true; if(KBEVec3Length(&movement) < velocity_ + range_) { float y = currpos.y; currpos = dstPos; if(range_ > 0.0f) { // 单位化向量 KBEVec3Normalize(&movement, &movement); movement *= range_; currpos -= movement; } if (!moveVertically_) currpos.y = y; ret = false; } else { // 单位化向量 KBEVec3Normalize(&movement, &movement); // 移动位置 movement *= velocity_; currpos += movement; } // 是否需要改变面向 if (faceMovement_ && (movement.x != 0.f || movement.z != 0.f)) direction.yaw(movement.yaw()); // 设置entity的新位置和面向 if(pController_) pEntity->setPositionAndDirection(currpos, direction); // 非navigate都不能确定其在地面上 if(pController_) pEntity->isOnGround(isOnGround()); // 通知脚本 if(pController_) pEntity->onMove(pController_->id(), pyuserarg_); // 如果达到目的地则返回true if(!ret) { return !requestMoveOver(); } return true; }
//------------------------------------------------------------------------------------- bool MoveToPointHandler::update(TimerHandle& handle) { if(pEntity_ == NULL) { handle.cancel(); return false; } Entity* pEntity = pEntity_; const Position3D& dstPos = destPos(); Position3D currpos = pEntity->position(); Position3D currpos_backup = currpos; Direction3D direction = pEntity->direction(); Vector3 movement = dstPos - currpos; if (!moveVertically_) movement.y = 0.f; bool ret = true; if(KBEVec3Length(&movement) < velocity_ + distance_) { float y = currpos.y; currpos = dstPos; if(distance_ > 0.0f) { // 单位化向量 KBEVec3Normalize(&movement, &movement); movement *= distance_; currpos -= movement; } if (!moveVertically_) currpos.y = y; ret = false; } else { // 单位化向量 KBEVec3Normalize(&movement, &movement); // 移动位置 movement *= velocity_; currpos += movement; } // 是否需要改变面向 if (faceMovement_ && (movement.x != 0.f || movement.z != 0.f)) direction.yaw(movement.yaw()); // 设置entity的新位置和面向 pEntity_->position(currpos); pEntity_->direction(direction); // 非navigate都不能确定其在地面上 pEntity_->isOnGound(false); // 通知脚本 pEntity->onMove(scriptCallbacks_.getIDForHandle(handle), layer_, currpos_backup, pyuserarg_); // 如果达到目的地则返回true if(!ret) { return !requestMoveOver(handle, currpos_backup); } return true; }
//------------------------------------------------------------------------------------- PyObject* ScriptVector3::pyGetVectorLength() { return PyFloat_FromDouble(KBEVec3Length(&getVector())); }