bool onCollision(const ISceneNodeAnimatorCollisionResponse& animator) { const vector3df & collisionPoint = animator.getCollisionPoint(); logTestString("Collision callback at %f %f %f\n", collisionPoint.X, collisionPoint.Y, collisionPoint.Z); if(collisionPoint != ExpectedCollisionPoint) { logTestString("*** Error: collision point, expected %f %f %f\n", ExpectedCollisionPoint.X, ExpectedCollisionPoint.Y, ExpectedCollisionPoint.Z); expectedCollisionCallbackPositions = false; assert(false); } const vector3df & nodePosition = animator.getCollisionResultPosition(); if(nodePosition != ExpectedNodePosition) { logTestString("*** Error: result position, expected %f %f %f\n", ExpectedNodePosition.X, ExpectedNodePosition.Y, ExpectedNodePosition.Z); expectedCollisionCallbackPositions = false; assert(false); } if(animator.getTargetNode() != ExpectedTarget) { logTestString("*** Error: wrong node\n"); expectedCollisionCallbackPositions = false; assert(false); } return ConsumeNextCollision; }
void Player::Init(UnitObject* pUnit,ITriangleSelector* pTerrain) { Irrdevice* pDevice = Irrdevice::GetInstance(); m_pUnitObject = pUnit; ISceneManager* pSmgr = pDevice->GetSceneManager(); SKeyMap aKeyMap[5]; aKeyMap[0].Action = EKA_MOVE_FORWARD; aKeyMap[0].KeyCode = KEY_KEY_W; aKeyMap[1].Action = EKA_MOVE_BACKWARD; aKeyMap[1].KeyCode = KEY_KEY_S; aKeyMap[2].Action = EKA_STRAFE_LEFT; aKeyMap[2].KeyCode = KEY_KEY_A; aKeyMap[3].Action = EKA_STRAFE_RIGHT; aKeyMap[3].KeyCode = KEY_KEY_D; aKeyMap[4].Action = EKA_JUMP_UP; aKeyMap[4].KeyCode = KEY_SPACE; //각 유닛마다 카메라 생성 m_pCamera = pSmgr->addCameraSceneNodeFPS(0,100.0f,0.5f,-1,aKeyMap,9,false,0,false,false); m_pCollisionAnimator = static_cast<ISceneNodeAnimatorCameraFPS*>(*(m_pCamera->getAnimators().begin())); //카메라가 가지고 있는 FPS 카메라 애니메이션 을 가지온다. 이것은 줌 확대 기능 등!! //카메라 따라댕기는 유닉 오브젝트... 방향에 대한것도 설정해줘야함... 이것은 일단 나중에 테스트를 위하여 m_pUnitObject->GetAnimatedNode()->setParent(m_pCamera); IMeshSceneNode* pNode = pSmgr->addCubeSceneNode(10,m_pCamera); m_pCamera->addChild(pUnit->GetAnimatedNode()); pNode->setVisible(true); m_pMyTriangle = pSmgr->createTriangleSelector(pNode->getMesh(),pNode); m_pMetaTriangle = pSmgr->createMetaTriangleSelector(); m_pMetaTriangle->addTriangleSelector(pTerrain); //역시 스크립트 적용 안할 수가 없다... 파일을 읽어와서 적용하던지.... 아우 ISceneNodeAnimatorCollisionResponse * pani = pSmgr->createCollisionResponseAnimator(m_pMetaTriangle,m_pCamera); m_pCamera->addAnimator(pani); pani->drop(); }
void CSSceneNodeAnimatorFPS::animateNode(ISceneNode* node, u32 timeMs) { if (!node || node->getType() != ESNT_CAMERA) return; ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); if (firstUpdate) { camera->updateAbsolutePosition(); if (CursorControl) { CursorControl->setPosition(m_CursorOffsetX, m_CursorOffsetY); CursorPos = CenterCursor = CursorControl->getRelativePosition(); } LastAnimationTime = timeMs; firstUpdate = false; } // If the camera isn't the active camera, and receiving input, then don't process it. if (!camera->isInputReceiverEnabled()) { firstInput = true; return; } if (firstInput) { allKeysUp(); firstInput = false; } scene::ISceneManager * smgr = camera->getSceneManager(); if (smgr && smgr->getActiveCamera() != camera) return; // get time f32 timeDiff = (f32)(timeMs - LastAnimationTime); LastAnimationTime = timeMs; // update position core::vector3df pos = camera->getPosition(); // Update rotation core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); core::vector3df relativeRotation = target.getHorizontalAngle(); if (CursorControl) { if (CursorPos != CenterCursor) { relativeRotation.Y -= (m_CursorOffsetX - CursorPos.X) * RotateSpeed; relativeRotation.X -= (m_CursorOffsetY - CursorPos.Y) * RotateSpeed * MouseYDirection; // X < MaxVerticalAngle or X > 360-MaxVerticalAngle if (relativeRotation.X > MaxVerticalAngle * 2 && relativeRotation.X < 360.0f - MaxVerticalAngle) { relativeRotation.X = 360.0f - MaxVerticalAngle; } else if (relativeRotation.X > MaxVerticalAngle && relativeRotation.X < 360.0f - MaxVerticalAngle) { relativeRotation.X = MaxVerticalAngle; } // Do the fix as normal, special case below // reset cursor position to the centre of the window. CursorControl->setPosition(m_CursorOffsetX, m_CursorOffsetY); CenterCursor = CursorControl->getRelativePosition(); // needed to avoid problems when the event receiver is disabled CursorPos = CenterCursor; } // Special case, mouse is whipped outside of window before it can update. video::IVideoDriver* driver = smgr->getVideoDriver(); core::vector2d<u32> mousepos(u32(CursorControl->getPosition().X), u32(CursorControl->getPosition().Y)); core::rect<u32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height); // Only if we are moving outside quickly. bool reset = !screenRect.isPointInside(mousepos); if (reset) { // Force a reset. CursorControl->setPosition(m_CursorOffsetX, m_CursorOffsetY); CenterCursor = CursorControl->getRelativePosition(); CursorPos = CenterCursor; } } // set target target.set(0, 0, core::max_(1.f, pos.getLength())); core::vector3df movedir = target; core::matrix4 mat; mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0)); mat.transformVect(target); if (NoVerticalMovement) { mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0)); mat.transformVect(movedir); } else { movedir = target; } movedir.normalize(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; if (CursorKeys[EKA_MOVE_BACKWARD]) pos -= movedir * timeDiff * MoveSpeed; // strafing core::vector3df strafevect = target; strafevect = strafevect.crossProduct(camera->getUpVector()); if (NoVerticalMovement) strafevect.Y = 0.0f; strafevect.normalize(); if (CursorKeys[EKA_STRAFE_LEFT]) pos += strafevect * timeDiff * MoveSpeed; if (CursorKeys[EKA_STRAFE_RIGHT]) pos -= strafevect * timeDiff * MoveSpeed; // For jumping, we find the collision response animator attached to our camera // and if it's not falling, we tell it to jump. if (CursorKeys[EKA_JUMP_UP]) { const ISceneNodeAnimatorList& animators = camera->getAnimators(); ISceneNodeAnimatorList::ConstIterator it = animators.begin(); while (it != animators.end()) { if (ESNAT_COLLISION_RESPONSE == (*it)->getType()) { ISceneNodeAnimatorCollisionResponse * collisionResponse = static_cast<ISceneNodeAnimatorCollisionResponse *>(*it); if (!collisionResponse->isFalling()) collisionResponse->jump(JumpSpeed); } it++; } } // write translation camera->setPosition(pos); // write right target target += pos; camera->setTarget(target); }
void CSceneNodeAnimatorCameraFPS::animateNode(ISceneNode* node, u32 timeMs) { if (node->getType() != ESNT_CAMERA) return; ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node); if (firstUpdate) { camera->updateAbsolutePosition(); if (CursorControl && camera) { CursorControl->setPosition(0.5f, 0.5f); CursorPos = CenterCursor = CursorControl->getRelativePosition(); } LastAnimationTime = timeMs; firstUpdate = false; } // get time f32 timeDiff = (f32) ( timeMs - LastAnimationTime ); LastAnimationTime = timeMs; // update position core::vector3df pos = camera->getPosition(); // Update rotation core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition()); core::vector3df relativeRotation = target.getHorizontalAngle(); if (CursorControl) { if (CursorPos != CenterCursor) { relativeRotation.Y -= (0.5f - CursorPos.X) * RotateSpeed; relativeRotation.X -= (0.5f - CursorPos.Y) * RotateSpeed; // X < MaxVerticalAngle or X > 360-MaxVerticalAngle if (relativeRotation.X > MaxVerticalAngle*2 && relativeRotation.X < 360.0f-MaxVerticalAngle) { relativeRotation.X = 360.0f-MaxVerticalAngle; } else if (relativeRotation.X > MaxVerticalAngle && relativeRotation.X < 360.0f-MaxVerticalAngle) { relativeRotation.X = MaxVerticalAngle; } // reset cursor position CursorControl->setPosition(0.5f, 0.5f); CenterCursor = CursorControl->getRelativePosition(); // needed to avoid problems when the ecent receiver is // disabled CursorPos = CenterCursor; } } // set target target.set(0,0, core::max_(1.f, pos.getLength())); core::vector3df movedir = target; core::matrix4 mat; mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0)); mat.transformVect(target); if (NoVerticalMovement) { mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0)); mat.transformVect(movedir); } else { movedir = target; } movedir.normalize(); if (CursorKeys[EKA_MOVE_FORWARD]) pos += movedir * timeDiff * MoveSpeed; if (CursorKeys[EKA_MOVE_BACKWARD]) pos -= movedir * timeDiff * MoveSpeed; // strafing core::vector3df strafevect = target; strafevect = strafevect.crossProduct(camera->getUpVector()); if (NoVerticalMovement) strafevect.Y = 0.0f; strafevect.normalize(); if (CursorKeys[EKA_STRAFE_LEFT]) pos += strafevect * timeDiff * MoveSpeed; if (CursorKeys[EKA_STRAFE_RIGHT]) pos -= strafevect * timeDiff * MoveSpeed; // For jumping, we find the collision response animator attached to our camera // and if it's not falling, we tell it to jump. if (CursorKeys[EKA_JUMP_UP]) { const core::list<ISceneNodeAnimator*> & animators = camera->getAnimators(); core::list<ISceneNodeAnimator*>::ConstIterator it = animators.begin(); while(it != animators.end()) { if(ESNAT_COLLISION_RESPONSE == (*it)->getType()) { ISceneNodeAnimatorCollisionResponse * collisionResponse = static_cast<ISceneNodeAnimatorCollisionResponse *>(*it); if(!collisionResponse->isFalling()) collisionResponse->jump(JumpSpeed); } it++; } } // write translation camera->setPosition(pos); // write right target TargetVector = target; target += pos; camera->setTarget(target); }
/** Test functionality of the ISceneNodeAnimator implementations. */ bool sceneNodeAnimator(void) { IrrlichtDevice * device = irr::createDevice(video::EDT_NULL, dimension2d<u32>(160, 120)); assert_log(device); if(!device) return false; ISceneManager * smgr = device->getSceneManager(); // Test the hasFinished() method. ISceneNodeAnimatorCollisionResponse* collisionResponseAnimator = smgr->createCollisionResponseAnimator(0, 0); ISceneNodeAnimator* deleteAnimator = smgr->createDeleteAnimator(1); ISceneNodeAnimator* flyCircleAnimator = smgr->createFlyCircleAnimator(); ISceneNodeAnimator* flyStraightAnimator = smgr->createFlyStraightAnimator(vector3df(0, 0, 0), vector3df(0, 0, 0), 1, false); ISceneNodeAnimator* flyStraightAnimatorLooping = smgr->createFlyStraightAnimator(vector3df(0, 0, 0), vector3df(0, 0, 0), 1, true); ISceneNodeAnimator* rotationAnimator = smgr->createRotationAnimator(vector3df(0, 0, 0)); array<vector3df> points; points.push_back(vector3df(0, 0, 0)); points.push_back(vector3df(0, 0, 0)); ISceneNodeAnimator* followSplineAnimator = smgr->createFollowSplineAnimator(0, points, 1000.f); array<video::ITexture*> textures; textures.push_back(0); textures.push_back(0); ISceneNodeAnimator* textureAnimator = smgr->createTextureAnimator(textures, 1, false); ISceneNodeAnimator* textureAnimatorLooping = smgr->createTextureAnimator(textures, 1, true); bool result = true; ISceneNode * deletedNode = smgr->addEmptySceneNode(); deletedNode->addAnimator(deleteAnimator); ISceneNode * testNode = smgr->addEmptySceneNode(); testNode->addAnimator(collisionResponseAnimator); testNode->addAnimator(deleteAnimator); testNode->addAnimator(flyCircleAnimator); testNode->addAnimator(flyStraightAnimator); testNode->addAnimator(flyStraightAnimatorLooping); testNode->addAnimator(rotationAnimator); testNode->addAnimator(followSplineAnimator); testNode->addAnimator(textureAnimator); testNode->addAnimator(textureAnimatorLooping); result &= !collisionResponseAnimator->hasFinished(); result &= !deleteAnimator->hasFinished(); result &= !flyCircleAnimator->hasFinished(); result &= !flyStraightAnimator->hasFinished(); result &= !flyStraightAnimatorLooping->hasFinished(); result &= !rotationAnimator->hasFinished(); result &= !followSplineAnimator->hasFinished(); result &= !textureAnimator->hasFinished(); result &= !textureAnimatorLooping->hasFinished(); device->run(); device->sleep(10); device->run(); smgr->drawAll(); // These animators don't have an endpoint. result &= !collisionResponseAnimator->hasFinished(); result &= !flyCircleAnimator->hasFinished(); result &= !rotationAnimator->hasFinished(); result &= !followSplineAnimator->hasFinished(); // These animators are looping and so can't finish. result &= !flyStraightAnimatorLooping->hasFinished(); result &= !textureAnimatorLooping->hasFinished(); // These have an endpoint and have reached it. result &= deleteAnimator->hasFinished(); result &= flyStraightAnimator->hasFinished(); result &= textureAnimator->hasFinished(); collisionResponseAnimator->drop(); deleteAnimator->drop(); flyCircleAnimator->drop(); flyStraightAnimator->drop(); flyStraightAnimatorLooping->drop(); rotationAnimator->drop(); followSplineAnimator->drop(); textureAnimator->drop(); textureAnimatorLooping->drop(); device->closeDevice(); device->run(); device->drop(); if(!result) { logTestString("One or more animators has a bad hasFinished() state\n."); assert_log(false); } return result; }