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;
	}
Esempio n. 2
0
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);
}
Esempio n. 5
0
/** 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;
}