Вы не вошли.

Уважаемый гость, добро пожаловать на форум: CRYMOD.NET - Портал сообщества CryENGINE. Если вы здесь впервые, то, пожалуйста, прочитайте раздел Помощь. В этом разделе можно подробно ознакомится с функционалом данной системы. Что бы использовать все возможности системы, необходимо зарегистрироваться. Для этого пройдите по ссылке и узнайте подробнее о процессе регистрации. В случае если вы уже зарегистрировались – войдите под своей учётной записью.

1

Понедельник, 24 Октябрь 2016, 15:41

Коллизия камеры от третьего лица

Камера постоянно проваливается в стены/потолок
Нажмите сюда, чтобы узнать больше
https://gfycat.com/ClumsyDecisiveIndiancow

Нашел в этой функции CDefaultCameraMode::ThirdPersonCameraPose() вот такой кусок, который как я понимаю как раз отвечает за коллизии

Код

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Handle camera collisions
	if (g_pGameCVars->cl_tpvCameraCollision)
	{
		IPhysicalEntity *pSkipEnts[5];
		const int nSkipEnts = clientPlayer.GetPhysicalSkipEntities(pSkipEnts, CRY_ARRAY_COUNT(pSkipEnts));
		
		primitives::sphere spherePrim;
		spherePrim.center = tpCrosshairPosition;
		spherePrim.r = g_pGameCVars->cl_tpvCameraCollisionOffset;

		float fDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(spherePrim.type, &spherePrim, -tpCameraDirection,
			ent_all, nullptr, 0, geom_colltype0, nullptr, nullptr, 0, pSkipEnts, nSkipEnts);
		if (fDist <= 0.0f)
		{
			fDist = g_pGameCVars->cl_tpvDist;
		}
		fDist = max(g_pGameCVars->cl_tpvMinDist, fDist);
		
		Interpolate(m_lastTpvDistance, fDist, g_pGameCVars->cl_tpvInterpolationSpeed, viewParams.frameTime);
		tpCameraPosition = tpCrosshairPosition - (tpCameraDirection.GetNormalized() * m_lastTpvDistance);
	}

Если я прав, то походу придется его переписать? Ибо это какой то зародыш обработчика коллизий...

2

Вторник, 25 Октябрь 2016, 05:09

Да, это он, можешь убедиться в этом отключив cl_tpvCameraCollision. Рекомендую так же посмотреть на то как реализована коллизия для камеры "наблюдателя" в мультиплеере, и совместить их реализацию, получится неплохой вариант. Хотя можно просто перенести реализацию коллизии для камеры "наблюдателя" с небольшими изменениями.

3

Пятница, 28 Октябрь 2016, 12:20

Объясните плз как работает эта функция PrimitiveWorldIntersection(spherePrim.type, &spherePrim, -tpCameraDirection, ent_all, nullptr, 0, geom_colltype0, nullptr, nullptr, 0, pSkipEnts, nSkipEnts);

Возвращает она какую то дистанцию, какую вообще не понимаю. А еще на кой то черт в параметрах есть некий вектор направления tpCameraDirection, он то тут зачем? 8|

4

Пятница, 28 Октябрь 2016, 13:20

А она очень просто работает, создаётся примитивная физ. геометрия указанной формы(в данном случае сфера) и тестируется на наличие внутри или пересекающих эту геометрию других физ. объектов заданного типа. Дирекция нужна опционального параметра "sweepDir", который указывает дирекцию для постоянных дополнительных проверок в указанном направлении вне основного радиуса геомертии. В данной ситуации используется перевёрнутое значение дирекции камеры игрока от точки spherePrim.center = tpCrosshairPosition;, т.е от позиции прицела игрока. Массив указателей pSkipEnts передаваемый в функцию определяет указатели на физ. объекты которые будут проигнорированы при выполнении функции и всех её физ. проверках. Дистанция возвращается от точки центра созданной геометрии - spherePrim.center до обнаруженного пересечения с другим физ. объектом, но иногда может вернуть единицу или ноль.

5

Пятница, 28 Октябрь 2016, 14:32

Я понял, тогда вопрос: Почему коллизию камеры(эту самую сферу) спаунят для проверки на месте курсора(всегда думал что курсор двумерный, а позиции в трехмерном мире задаются 3 координатами))) а не на месте камеры? Есть ли какой то метод/член для определения, была коллизия или нет?

6

Пятница, 28 Октябрь 2016, 14:52

Ну позиция курсора по сути двухмерная(номера пикселей по вертикали и горизонтали), но ты можешь получить реальное положение курсора в трёхмерном мире, так же как и положение любого пикселя итоговой картинки. А так сфера получается почти на месте камеры, только чуть дальше вглубь от её фактического положения. Но походу такая реализация некорректна, а потом см. функцию CameraCollide(а походу её у тебя небудет(или будет, дефолтное решение отсутствует немогу посмотреть), но точно будет CSpectatorFollowCameraMode::UpdateView, тамошнюю реализацию надо будет доработать), там более корректная реализация без всяких курсоров и прочего. Можно передать в функцию указатель на структуру geom_contact

Код

1
2
geom_contact*  pContact = NULL;
			float  hitDist = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, sphereDir, (ent_static | ent_terrain | ent_rigid), &pContact, 0, (rwi_ignore_noncolliding | rwi_stop_at_pierceable), 0, 0, 0, !skipList.empty() ? &skipList[0] : NULL, skipList.size());
и потом проверив этот указатель на наличие(функция проведёт с ним необходимые операции) вытащить всё инфу о контакте, включая точки соприкосновения и т.д. Ещё если коллизии небыло то функция должна вернуть нулевое значение дистанции.

Это сообщение было отредактировано 1 раз(а), последнее редактирование в "Npc" (28 Октябрь 2016, 15:00)