void GOComponent::NotifyOwnerGO() { GameObjectPtr ownerGO = mOwnerGO.lock(); if (!ownerGO.get()) return; UpdatePosition(ownerGO->GetGlobalPosition()); UpdateOrientation(ownerGO->GetGlobalOrientation()); UpdateScale(ownerGO->GetGlobalScale()); }
void GOComponent::ReceiveMessage(Msg &msg) { if (msg.typeID == GameObject::MessageIDs::UPDATE_COMPONENT_TRANSFORM) { GameObjectPtr owner = mOwnerGO.lock(); if (owner) { UpdatePosition(owner->GetGlobalPosition()); UpdateOrientation(owner->GetGlobalOrientation()); } } if (msg.typeID == GameObject::MessageIDs::UPDATE_COMPONENT_POSITION) UpdatePosition(msg.params.GetValue<Ogre::Vector3>(0)); else if (msg.typeID == GameObject::MessageIDs::UPDATE_COMPONENT_ORIENTATION) UpdateOrientation(msg.params.GetValue<Ogre::Quaternion>(0)); else if (msg.typeID == GameObject::MessageIDs::UPDATE_COMPONENT_SCALE) UpdateScale(msg.params.GetValue<Ogre::Vector3>(0)); }
void GOCCharacterController::ReceiveMessage(Msg &msg) { GOComponent::ReceiveMessage(msg); if (msg.typeID == GlobalMessageIDs::PHYSICS_SUBSTEP && !mFreezed) { GameObjectPtr owner = mOwnerGO.lock(); float time = msg.params.GetFloat("TIME"); Ogre::Vector3 finalDir = Ogre::Vector3(0,0,0); Ogre::Vector3 userDir = owner->GetGlobalOrientation() * mDirection; if (mActor.getPxActor()->isSleeping()) mActor.getPxActor()->wakeUp(); //Gravity fix Ogre::Vector3 playerHalfSize = mDimensions * 0.5f; PxTransform transform(OgrePhysX::toPx(owner->GetGlobalPosition()), OgrePhysX::toPx(owner->GetGlobalOrientation())); transform.p.y += playerHalfSize.y; //sweep filter data - only check against shapes with filter data DYNAMICBODY or STATICBODY PxSceneQueryFilterData filterData; filterData.data.word0 = CollisionGroups::DYNAMICBODY|CollisionGroups::STATICBODY; filterData.flags = PxSceneQueryFilterFlag::eDYNAMIC|PxSceneQueryFilterFlag::eSTATIC; //touches ground check PxBoxGeometry playerGeometry(playerHalfSize.x, playerHalfSize.y+0.1f, playerHalfSize.z); PxShape *outShape; mTouchesGround = Main::Instance().GetPhysXScene()->getPxScene()->overlapAny(playerGeometry, transform, outShape, filterData); //stair maxStepHeight float maxStepHeight = 0.6f; PxVec3 currPos = OgrePhysX::Convert::toPx(owner->GetGlobalPosition()); //feet capsule PxBoxGeometry feetVolume(playerHalfSize.x, maxStepHeight*0.5f, playerHalfSize.z); //body capsule float bodyHeight = mDimensions.y-maxStepHeight; PxBoxGeometry bodyVolume(playerHalfSize.x, bodyHeight*0.5f, playerHalfSize.z); PxVec3 sweepDirection = OgrePhysX::toPx(userDir); float userDirLength = sweepDirection.normalize(); /* We perform two sweeps: O ==> bodyHit? | ==> bodyHit? / \ ==> feetHit? If there are no hits character can walk in the desired direction. If there is a feetHit but no bodyHit player can climb stairs (we add an y-Offset). If there is a bodyHit the player can not move. */ PxSweepHit sweepHit; transform.p.y = owner->GetGlobalPosition().y + maxStepHeight + bodyHeight*0.5f; bool bodyHit = Main::Instance().GetPhysXScene()->getPxScene()->sweepSingle(bodyVolume, transform, sweepDirection, time*userDirLength, PxSceneQueryFlags(), sweepHit, filterData); transform.p.y = owner->GetGlobalPosition().y + maxStepHeight*0.5f; bool feetHit = Main::Instance().GetPhysXScene()->getPxScene()->sweepSingle(feetVolume, transform, sweepDirection, time*userDirLength, PxSceneQueryFlags(), sweepHit, filterData); if (!bodyHit) { finalDir += userDir; //add player movement if (feetHit) finalDir += Ogre::Vector3(0,3,0); //climb stairs } if (finalDir != Ogre::Vector3(0,0,0)) mActor.getPxActor()->setGlobalPose(PxTransform(currPos + OgrePhysX::Convert::toPx(finalDir*time))); if (mJumping && mTouchesGround && (timeGetTime() - mJumpStartTime > 400)) { mJumping = false; Msg jump_response; jump_response.typeID = ObjectMessageIDs::END_JUMP; BroadcastObjectMessage(jump_response); } } if (msg.typeID == GlobalMessageIDs::PHYSICS_END && !mFreezed) { SetOwnerPosition(mActor.getGlobalPosition()); //SetOwnerOrientation(mActor->getGlobalOrientation()); } if (msg.typeID == ObjectMessageIDs::UPDATE_CHARACTER_MOVEMENTSTATE) { mDirection = Ogre::Vector3(0,0,0); int movementFlags = msg.params.GetInt("CharacterMovementState"); if (movementFlags & CharacterMovement::FORWARD) mDirection.z += 1; if (movementFlags & CharacterMovement::BACKWARD) mDirection.z -= 1; if (movementFlags & CharacterMovement::LEFT) mDirection.x += 1; if (movementFlags & CharacterMovement::RIGHT) mDirection.x -= 1; mDirection.normalise(); mDirection*=(mMovementSpeed*mSpeedFactor); } if (msg.typeID == ObjectMessageIDs::INPUT_START_JUMP) { if (mTouchesGround && !mJumping) { mJumping = true; mJumpStartTime = timeGetTime(); mActor.getPxActor()->addForce(PxVec3(0, mActor.getPxActor()->getMass()*8, 0), PxForceMode::eIMPULSE); Msg startJumpMsg; startJumpMsg.typeID = ObjectMessageIDs::START_JUMP; BroadcastObjectMessage(startJumpMsg); } } if (msg.typeID == ObjectMessageIDs::CHARACTER_KILL) { mFreezed = true; } }