bool PhysXCharacterController::filter(const PxController& a, const PxController& b) { CharacterController* controllerA = (CharacterController*)a.getUserData(); CharacterController* controllerB = (CharacterController*)b.getUserData(); bool canCollide = gPhysics().isCollisionEnabled(controllerA->getLayer(), controllerB->getLayer()); return canCollide; }
/// Let's check if actors are okay void PhysicsSystemPhysX::syncActors() { for (std::size_t i = 0; i < mWorld->actors.size(); ++i) { Actor* actor = mWorld->actors[i]; for (std::size_t j = 0; j < actor->components.size(); ++j) { ACharacterComponent* chr = dynamic_cast<ACharacterComponent*>(actor->components[j]); if (chr) { // We have a character controller in this actor, needs to be handled if (chr->userData) { PxController* cc = (PxController*)chr->userData; chr->t.position.x = cc->getPosition().x; chr->t.position.y = cc->getPosition().y; chr->t.position.z = cc->getPosition().z; //Log("Updated actor"); } else { PxMaterial* mat = mPhysics->createMaterial(0.1, 0.1, 0.1); PxCapsuleControllerDesc* desc = new PxCapsuleControllerDesc; desc->height = 5; desc->radius = 5; desc->position = PxExtendedVec3(0, 0, 0); desc->material = mat; Log("BOX VALID: %d", desc->isValid()); PxController* c = manager->createController(*desc); if (!c) { Log("Failed to instance a controller"); } if (c) { chr->userData = c; chr->moving.connect(sigc::mem_fun(this, &PhysicsSystemPhysX::TestCharacterMove)); Log("PhysX validated an actor's character controller"); } } } } } }
void PhysicsSystemPhysX::TestCharacterMove(Vector3D displacement, Actor* a) { ACharacterComponent* chr = dynamic_cast<ACharacterComponent*>(a->getRootComponent()); if (chr) { if (chr->userData) { PxController* cc = (PxController*)chr->userData; PxControllerFilters filters; cc->move(PxVec3(displacement.x, displacement.y, displacement.z), 0.01f, 1.f / 60.f, filters); //Log("Moving.."); } } }
void CharacterControllerManager::releaseController(PxController& controller) { for (PxU32 i = 0; i<mControllers->size(); i++) if ((*mControllers)[i]->getNxController() == &controller) { mControllers->replaceWithLast(i); break; } if (controller.getType() == PxControllerShapeType::eCAPSULE) { CapsuleController* cc = (CapsuleController*)&controller; cc->~CapsuleController(); mAllocator->deallocate(cc); } else if (controller.getType() == PxControllerShapeType::eBOX) { BoxController* bc = (BoxController*)&controller; bc->~BoxController(); mAllocator->deallocate(bc); } else PX_ASSERT(0); }
void CharacterControllerManager::releaseController(PxController& controller) { for(PxU32 i = 0; i<mControllers.size(); i++) { if(mControllers[i]->getPxController() == &controller) { mControllers.replaceWithLast(i); break; } } if(controller.getType() == PxControllerShapeType::eCAPSULE) { CapsuleController* cc = (CapsuleController*)&controller; PX_DELETE(cc); } else if(controller.getType() == PxControllerShapeType::eBOX) { BoxController* bc = (BoxController*)&controller; PX_DELETE(bc); } else PX_ASSERT(0); }
void *timer_handler(void *ptr) { if(timer_disable == 1) { return NULL; } struct timespec _t; static struct timeval now, prev; double dt = 0; clock_gettime(CLOCK_REALTIME, &_t); static PxController ctrlr; // SioClient initialization ------------------------------------------------- SioClientWrapper client; sio::message::ptr data; //発生するイベント名一覧をstd::vector<std::string>としてclientに渡す std::vector<std::string> eventList(0); eventList.push_back("landing"); eventList.push_back("direction"); eventList.push_back("px_bounce"); eventList.push_back("px_start"); eventList.push_back("px_position"); eventList.push_back("px_velocity"); client.setEventList(eventList); //自身を表す部屋名を設定する(Phenoxなら例えば"Phenox"と決める) client.setMyRoom("Phenox"); //データの送信宛先となる部屋名を設定する(Gameサーバなら例えば"Game") client.setDstRoom("Game"); //URLを指定して接続開始 client.start("http://localhost:8000"); while(1) { pxset_keepalive(); pxset_systemlog(); pxset_img_seq(cameraid); static unsigned long msec_cnt = 0; msec_cnt++; gettimeofday(&now, NULL); dt = (now.tv_sec - prev.tv_sec) + (now.tv_usec - prev.tv_usec) * 1.0E-6; if(dt < 0){ cout << "dt < 0" << endl; continue; } prev = now; // vision control static px_selfstate st; static Vector2f pos; pxget_selfstate(&st); pos << st.vision_tx, st.vision_ty; Vector2f norm, norm_start; Vector2f norm2, norm_start2; static Vector2f input(0,0); // ------------------------------------------------------------------- // get boundary norm ------------------------------------------------- // ------------------------------------------------------------------- int boundary_cnt = 0; if(pthread_mutex_trylock(&mutex) != EBUSY){ norm = gnorm; norm_start = gnorm_start; norm2 = gnorm2; norm_start2 = gnorm_start2; boundary_cnt = gboundary_cnt; //cout << "boundary cnt = " << boundary_cnt << endl; //cout << "norm = \n" << norm << endl; //cout << "norm2 = \n" << norm2 << endl; pthread_mutex_unlock(&mutex); ctrlr.boundHandler(boundary_cnt,norm,norm2,pos); } // -------------------------------------------------------------------- // get landing and direction------------------------------------------- // -------------------------------------------------------------------- //"landing"に対応するデータが来ているかチェック if (client.isUpdated("landing")){ data = client.getData("landing");//データをsio::message::ptrとして取得 parseLanding(data);//データ抽出用関数に渡す std::cout << "landing=" << landing << std::endl; } //"direction"に対応するデータが来ているかチェック if (client.isUpdated("direction")){ data = client.getData("direction");//データをsio::message::ptrとして取得 parseDirection(data);//データ抽出用関数に渡す std::cout << "direction = [" << direction[0] << ", " << direction[1] << "]" << std::endl; } // -------------------------------------------------------------------- // Sample of data sending --------------------------------------------- // -------------------------------------------------------------------- // 送りたいところに移動してね Vector2f px_position(0, 0); Vector2f px_velocity(0, 0); client.sendData("px_start", makePxStart());// client.sendData("px_bounce", makePxBounce());// client.sendData("px_position", makePxPosition());// client.sendData("px_velocity", makePxVelocity());// //cout << ctrlr.vx() << "," << ctrlr.vy() << endl; // save log static ofstream ofs_deg("output_deg"); ofs_deg << st.degx << "," << st.degy << endl; static ofstream ofs_ctl("output_v"); ofs_ctl << ctrlr.vx() << "," << ctrlr.vy() << "," << norm.x() << "," << norm.y() << endl; static ofstream ofs_vision("output_vision"); ofs_vision << st.vision_tx << "," << st.vision_ty << "," << input.x() << "," << input.y() << endl; // if(!(msec_cnt % 30)){ // printf("%.2f %.2f %.2f | %.2f %.2f %.2f | %.2f | \n",st.degx,st.degy,st.degz,st.vision_tx,st.vision_ty,st.vision_tz,st.height); // } static int hover_cnt = 0; static Vector2f origin(0,0); if(pxget_operate_mode() == PX_UP){ pxset_visualselfposition(0, 0); hover_cnt = 0; } if(pxget_operate_mode() == PX_HOVER) { if(hover_cnt < 500){ hover_cnt++; } else if (hover_cnt == 500) { cout << "start control" << endl; ctrlr.init(0,1,origin,pos); hover_cnt++; } else{ input = ctrlr.controlStep(pos, dt); pxset_visioncontrol_xy(input.x(),input.y()); } } static int prev_operatemode = PX_HALT; if((prev_operatemode == PX_UP) && (pxget_operate_mode() == PX_HOVER)) { origin << st.vision_tx, st.vision_ty; pxset_visioncontrol_xy(origin.x(),origin.y()); } prev_operatemode = pxget_operate_mode(); if(pxget_whisle_detect() == 1) { if(pxget_operate_mode() == PX_HOVER) { pxset_operate_mode(PX_DOWN); } else if(pxget_operate_mode() == PX_HALT) { pxset_rangecontrol_z(150); pxset_operate_mode(PX_UP); } } if(pxget_battery() == 1) { timer_disable = 1; system("shutdown -h now\n"); exit(1); } struct timespec remains; _t.tv_nsec += 10000000; clock_nanosleep(CLOCK_REALTIME, TIMER_ABSTIME, &_t, &remains); // while (get_time() - t < 10.0) { // usleep(500); // } clock_gettime(CLOCK_REALTIME, &_t); } }
PxController* ControlledActor::init(const ControlledActorDesc& desc, PxControllerManager* manager) { const float radius = desc.mRadius; float height = desc.mHeight; float crouchHeight = desc.mCrouchHeight; PxControllerDesc* cDesc; PxBoxControllerDesc boxDesc; PxCapsuleControllerDesc capsuleDesc; if(desc.mType==PxControllerShapeType::eBOX) { height *= 0.5f; height += radius; crouchHeight *= 0.5f; crouchHeight += radius; boxDesc.halfHeight = height; boxDesc.halfSideExtent = radius; boxDesc.halfForwardExtent = radius; cDesc = &boxDesc; } else { PX_ASSERT(desc.mType==PxControllerShapeType::eCAPSULE); capsuleDesc.height = height; capsuleDesc.radius = radius; capsuleDesc.climbingMode = PxCapsuleClimbingMode::eCONSTRAINED; cDesc = &capsuleDesc; } cDesc->density = desc.mProxyDensity; cDesc->scaleCoeff = desc.mProxyScale; cDesc->material = &mOwner.getDefaultMaterial(); cDesc->position = desc.mPosition; cDesc->slopeLimit = desc.mSlopeLimit; cDesc->contactOffset = desc.mContactOffset; cDesc->stepOffset = desc.mStepOffset; cDesc->invisibleWallHeight = desc.mInvisibleWallHeight; cDesc->maxJumpHeight = desc.mMaxJumpHeight; // cDesc->nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING_AND_FORCE_SLIDING; cDesc->reportCallback = desc.mReportCallback; cDesc->behaviorCallback = desc.mBehaviorCallback; cDesc->volumeGrowth = desc.mVolumeGrowth; mType = desc.mType; mInitialPosition = desc.mPosition; mStandingSize = height; mCrouchingSize = crouchHeight; mControllerRadius = radius; PxController* ctrl = static_cast<PxBoxController*>(manager->createController(*cDesc)); PX_ASSERT(ctrl); // remove controller shape from scene query for standup overlap test PxRigidDynamic* actor = ctrl->getActor(); if(actor) { if(actor->getNbShapes()) { PxShape* ctrlShape; actor->getShapes(&ctrlShape,1); ctrlShape->setFlag(PxShapeFlag::eSCENE_QUERY_SHAPE, false); Renderer* renderer = mOwner.getRenderer(); if(desc.mType==PxControllerShapeType::eBOX) { const PxVec3 standingExtents(radius, height, radius); const PxVec3 crouchingExtents(radius, crouchHeight, radius); mRenderActorStanding = SAMPLE_NEW(RenderBoxActor)(*renderer, standingExtents); mRenderActorCrouching = SAMPLE_NEW(RenderBoxActor)(*renderer, crouchingExtents); } else if(desc.mType==PxControllerShapeType::eCAPSULE) { mRenderActorStanding = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, height*0.5f); mRenderActorCrouching = SAMPLE_NEW(RenderCapsuleActor)(*renderer, radius, crouchHeight*0.5f); } } } mController = ctrl; return ctrl; }