Rotation в NeoAxis
| |
Cyber | Дата: Воскресенье, 02 Июня 2013, 14:17 | Сообщение # 1 |
был не раз
Сейчас нет на сайте
| Нужно чтобы пуля попадала в террейн куда указывает курсор. Сделал вычисление Rotation для этого через тригонометрические функции и векторную математику, но пуля попадает постоянно выше того места куда должна попасть. В чем проблема? Может из за перепада высот террейна? И можно ли получить нужное значение Rotation через вектор указывающий направление (Direction), если да то можете привести код в пример?
|
|
| |
Undead | Дата: Понедельник, 03 Июня 2013, 07:03 | Сообщение # 2 |
NeoAxis User
Сейчас нет на сайте
| Cyber, У оружия есть такой параметр, как точность стрельбы. Или ты своё что-то пишешь? Цитата (Cyber) если да то можете привести код в пример? Какой именно?
Вcем зла.
|
|
| |
Cyber | Дата: Понедельник, 03 Июня 2013, 17:54 | Сообщение # 3 |
был не раз
Сейчас нет на сайте
| Вы немного не так меня поняли, Я знаю что у оружия есть параметр разброса пуль (DispersionAngle или как то так). А задача другая - есть точка на террейне, и есть позиция оружия, нужно высчитать поворот по всем трем осям координат, по X и Y координатам поворот считается на ура, а вот по Z оси, оружие стреляет чуть выше чем хотелось бы. Не знаю в чем проблема, вроде геометрию знаю пространственную)
И да, пишу свое, вертолетное орудие, пулемет. Напрявляется мышкой, точку на террейне считаю через вьювпорт. А код правильного рассчета поворота в точку указанную мышкой,ну или на мысль правильную по этому поводу наведите хотя бы
Сообщение отредактировал Cyber - Понедельник, 03 Июня 2013, 17:57 |
|
| |
Undead | Дата: Вторник, 04 Июня 2013, 20:28 | Сообщение # 4 |
NeoAxis User
Сейчас нет на сайте
| Тут лучше поступить по аналогии с танком. Там пушка на башне тоже обычное оружие. Покажи, как поворот считаешь.
Вcем зла.
|
|
| |
Cyber | Дата: Суббота, 08 Июня 2013, 10:06 | Сообщение # 5 |
был не раз
Сейчас нет на сайте
| Вот именно что по аналогии с танком не вышло. Почему то вертолет не хочет как танк находить у себя в прикрепленных объектах мой класс.
А так вот код, буду рад если поможете его домыслить) А то пули летят не туда куда нужно, по оси Z.
Код [color=blue] using System; using System.Collections.Generic; using System.Text; using System.ComponentModel; using Engine; using Engine.Renderer; using Engine.MathEx; using Engine.SoundSystem; using Engine.UISystem; using Engine.EntitySystem; using Engine.MapSystem; using Engine.PhysicsSystem; using Engine.FileSystem; using Engine.Utils; using GameCommon; using GameEntities;
namespace GameEntities { public class AircraftGunType : GunType { }
public class AircraftGun : Gun {
AircraftGunType _type = null; public new AircraftGunType Type { get { return _type; } }
/*Ствол*/ MapObjectAttachedObject mainGun;
float lastFireTime = 0;
protected override void OnPostCreate(bool loaded) { base.OnPostCreate(loaded);
mainGun = GetAttachedObjectByAlias("gun"); /*Ствол пушки*/ } /*Вычисление поворота для пули. Чтобы летела туда куда надо*/ private Quat GetBulletRotation() { Vec3 posToTurn = GetNeedPositionToTurnGun();
Vec3 diff = posToTurn - Position;
Radian horizontalAngle = MathFunctions.ATan(diff.Y, diff.X); Radian verticalAngle = MathFunctions.ATan(diff.Z, diff.ToVec2().Length());
Quat horRot = new Angles(0, verticalAngle.InDegrees(), -horizontalAngle.InDegrees()).ToQuat(); return horRot;
/*Quat rot = baseBody.Rotation.GetInverse() * turretBody.Rotation;
Quat verticalRot = new Angles(0, verticalAngle.InDegrees(), 0).ToQuat();
mainGunAttachedObject.PositionOffset = rot * mainGunOffsetPosition; mainGunAttachedObject.RotationOffset = rot * verticalRot;*/
}
/*Лучше не смотреть на этот код. (Исправить по возможности)*/ /*Поворот ствола к курсору*/ public void TurnMainGun() { Vec3 diff = GetNeedPositionToTurnGun() - Position;
Radian horizontalAngle = MathFunctions.ATan(diff.Y, diff.X); Radian verticalAngle = MathFunctions.ATan( diff.Z, diff.ToVec2().Length() );
/*По горизонтали поворот ствола относительно вертолета. Т.к. attachedObject*/ Angles resultHorizontal = (new Angles(0, 0, -horizontalAngle.InDegrees()) - Rotation.ToAngles());
mainGun.RotationOffset = (new Angles(0, verticalAngle.InDegrees(), 0) + resultHorizontal).ToQuat(); }
protected Quat TurnEffect() { Vec3 diff = GetNeedPositionToTurnGun() - Position;
Radian horizontalAngle = MathFunctions.ATan(diff.Y, diff.X); Radian verticalAngle = MathFunctions.ATan(diff.Z, diff.ToVec2().Length());
Angles resultHorizontal = (new Angles(0, 0, -horizontalAngle.InDegrees()) - Rotation.ToAngles());
return (new Angles(0, verticalAngle.InDegrees(), 0) + resultHorizontal).ToQuat(); }
protected override void CreateBullet(Mode mode) { Bullet obj = (Bullet)Entities.Instance.Create(mode.typeMode.BulletType, Parent); obj.SourceUnit = GetParentUnitHavingIntellect(); obj.Position = GetFirePosition(mode.typeMode);
{ Vec3 startPos = Position; if (AttachedMapObjectParent != null) startPos = AttachedMapObjectParent.Position;
Ray ray = new Ray(startPos, obj.Position - startPos); if (ray.Direction != Vec3.Zero) { RayCastResult[] piercingResult = PhysicsWorld.Instance.RayCastPiercing( ray, (int)ContactGroup.CastOnlyContact);
foreach (RayCastResult result in piercingResult) { MapObject mapObject = MapSystemWorld.GetMapObjectByBody(result.Shape.Body);
if (mapObject != null) { if (mapObject == this) continue; if (mapObject == this.AttachedMapObjectParent) continue; }
obj.Position = result.Position - ray.Direction * .01f; break; } } }
Quat rot = GetBulletRotation(); Radian dispersionAngle = mode.typeMode.DispersionAngle; if (dispersionAngle != 0) { EngineRandom random = World.Instance.Random;
Mat3 matrix; matrix = Mat3.FromRotateByX(random.NextFloat() * MathFunctions.PI * 2); matrix *= Mat3.FromRotateByZ(random.NextFloat() * dispersionAngle);
rot *= matrix.ToQuat(); } mode.typeMode.FireObjects[0].Rotation = mainGun.RotationOffset; mode.typeMode.FireObjects.CreateObjects(this); obj.Rotation = rot;
obj.PostCreate();
float coef = obj.DamageCoefficient; Unit unit = GetParentUnitHavingIntellect(); if (unit != null && unit.BigDamageInfluence != null) coef *= unit.BigDamageInfluence.Type.Coefficient; obj.DamageCoefficient = coef; }
/*---------------Вычисление позиции на поворот для пушки--------------*/ public Vec3 GetNeedPositionToTurnGun() {
RayCastResult results = PhysicsWorld.Instance.RayCast( RendererWorld.Instance.DefaultCamera.GetCameraToViewportRay(EngineApp.Instance.MousePosition), (int)ContactGroup.CastOnlyContact);
if (results.Position == Vec3.Zero) { return Vec3.Zero; }
return results.Position; }
protected override void OnTick() { base.OnTick();
if (EngineApp.Instance.IsMouseButtonPressed(EMouseButtons.Left)) if ((LastTickTime - lastFireTime) > 0.08f) { CreateBullet(NormalMode); lastFireTime = LastTickTime; }
TurnMainGun(); }
} } Добавлено (08.06.2013, 10:06) --------------------------------------------- http://rghost.ru/46595574
Тот же код на обменнике, чтобы было удобней смотреть) Не знал что тут такое маленькое окошко
|
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 08:41 | Сообщение # 6 |
NeoAxis User
Сейчас нет на сайте
| тебе не нужно модифицировать класс оружия. Оно должно быть просто приаттаченым объектом. Достаточно только вращать его. Считать вращения нужно в классе твоего юнита.
Цитата (Cyber) Вот именно что по аналогии с танком не вышло. Почему то вертолет не хочет как танк находить у себя в прикрепленных объектах мой класс. Значит искал не правильно. Если дашь объекту оружия псевдоним, то найти его можно 1 стокой кода Код Gun mainGun = (Gun)GetAttachedObjectByAlias("alias");
Вcем зла.
|
|
| |
Cyber | Дата: Воскресенье, 09 Июня 2013, 12:19 | Сообщение # 7 |
был не раз
Сейчас нет на сайте
| Благодарю за ответ) Попробую сделать как вы сказали, если что еще напишу тут)
Добавлено (09.06.2013, 12:16) --------------------------------------------- Только у вас там ошибочка, преобразование типа MapObjectAttachedObject в Gun невозможно
Сообщение отредактировал Cyber - Воскресенье, 09 Июня 2013, 12:21 |
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 13:24 | Сообщение # 8 |
NeoAxis User
Сейчас нет на сайте
| Цитата (Cyber) Только у вас там ошибочка, преобразование типа MapObjectAttachedObject в Gun невозможно Вот здесь я просмотрел. Исправлять не стал, думал, что сам найдёшь. Код Gun mainGun = (Gun)( (MapObjectAttachedMapObject)GetAttachedObjectByAlias("alias") ).MapObject;
Вcем зла.
|
|
| |
Cyber | Дата: Воскресенье, 09 Июня 2013, 13:39 | Сообщение # 9 |
был не раз
Сейчас нет на сайте
| А уже это я знаю) Но факт в том что не ищется пушка у вертолета никаким способом. Ни вашим, ни по аналогии с танком. Именно для этого я и сделал новый класс, чтобы даже искать ее не приходилось) Вот просто не находит, ни в OnPostCreate ни в OnTick Добавлено (09.06.2013, 13:39) --------------------------------------------- Думаете я бы стал сюда писать если бы проблема была настолько тривиальна?) Я знаю что у танка точно такой же способ крепления пушки, первое что я попробовал сделать это скопировать код у танка - не вышло, ссылка на несущесвующий объект. Так же я потом догадался что прикрепеленному объекту можно задать псевдоним, и и скать по нему - сслыка на несуществующий объект. Странно, всё что я могу тут сказать)
|
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 14:40 | Сообщение # 10 |
NeoAxis User
Сейчас нет на сайте
| Cyber, Код работает. Ты в редакторе ресурсов накосячил просто. Кинь *.type файлы в архиве. Скажу, где.
Вcем зла.
|
|
| |
Cyber | Дата: Воскресенье, 09 Июня 2013, 15:03 | Сообщение # 11 |
был не раз
Сейчас нет на сайте
| Я согласен что код работает, он обязан работать) И с вами я тоже согласен, проблема либо в типе пушки, либо в типе вертолета. Рад буду если укажете на ошибку)
http://rghost.ru/46624418
Здесь два типа, пушка и вертолет
|
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 16:21 | Сообщение # 12 |
NeoAxis User
Сейчас нет на сайте
| Пушку лучше сделай на основе класса Gun, а не AircraftGun Код Gun maingun = (Gun)( (MapObjectAttachedMapObject)GetAttachedObjectByAlias("mainGun") ).MapObject; Вот так всё должно работать. Ты случаем не в классе оружия аттаченый объект ищешь? Нужно же в классе Aircraft.
Вcем зла.
Сообщение отредактировал Undead - Воскресенье, 09 Июня 2013, 16:25 |
|
| |
Cyber | Дата: Воскресенье, 09 Июня 2013, 16:24 | Сообщение # 13 |
был не раз
Сейчас нет на сайте
| Конечно я ищу приаттаченную пушку в классе вертолета. Точнее я искал, пока не понял что это бесполезно. Я делал пушку на основе Gun, тот же самый результат что и с моей AircraftGun - не находит, ищу в классе самого вертолета к которому она относится
|
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 16:29 | Сообщение # 14 |
NeoAxis User
Сейчас нет на сайте
| ХЗ, где то у тебя там баг. Кидай твой класс Aircraft, там посмотрим.
Вcем зла.
|
|
| |
Cyber | Дата: Воскресенье, 09 Июня 2013, 17:53 | Сообщение # 15 |
был не раз
Сейчас нет на сайте
| Извиняюсь!) Благодарю за помощь) Пушка определяется, мой косяк, не знаю из за чего. Но я так и не понял почему пули летят не туда.
Код public Vec3 GetNeedPositionToTurnGun() { RayCastResult results = PhysicsWorld.Instance.RayCast( RendererWorld.Instance.DefaultCamera.GetCameraToViewportRay(EngineApp.Instance.MousePosition), (int)ContactGroup.CastOnlyContact);
if (results.Position == Vec3.Zero) { return Vec3.Zero; }
if (Math.Abs((Position - results.Position).Length()) < 10.0f) { return oldTurnGunPosition; }
oldTurnGunPosition = results.Position; return results.Position; } Здесь я определяю точку на которую указывает крусор
Код private Quat GetBulletRotation() { Vec3 posToTurn = GetNeedPositionToTurnGun();
Vec3 diff = posToTurn - Position;
Radian horizontalAngle = MathFunctions.ATan(diff.Y, diff.X); Radian verticalAngle = MathFunctions.ATan(diff.Z, diff.ToVec2().Length());
Quat conRot = new Angles(0, verticalAngle.InDegrees(), -horizontalAngle.InDegrees()).ToQuat(); return conRot; } А здесь я считаю куда должна повернуться пуля чтобы смотреть в сторону куда указывает курсор и лететь туда. Но она не летит туда куда указывает курсор) Можете помочь советом?
|
|
| |
Undead | Дата: Воскресенье, 09 Июня 2013, 18:16 | Сообщение # 16 |
NeoAxis User
Сейчас нет на сайте
| Тебе не нужно ничего менять в классе оружия. Метод GetNeedPositionToTurnGun на первый взгляд нормально работает. Проблема должна быть в неверном вращении самого оружия.
Вcем зла.
|
|
| |
Cyber | Дата: Понедельник, 10 Июня 2013, 18:07 | Сообщение # 17 |
был не раз
Сейчас нет на сайте
| А вот в том то и дело что я для тестов сделал что пули вообще не зависят от вращения оружия. Я для чего метод GetBulletRotation то привел, вот в этом методе и вычисляется вращение пули, от этого вращения зависит куда она полетит. По моему в моей тригонометрии всё нормально, а пули так и летят выше чем нужно
|
|
| |
Undead | Дата: Понедельник, 10 Июня 2013, 19:23 | Сообщение # 18 |
NeoAxis User
Сейчас нет на сайте
| Зря ты так сделал. Вращай пушку и всё будет норм. Тут уже не понятно, почему они у тебя выше летят. Ты поведение пули менял? Может ты для пули положительную гравитацию случайно поставил) Попробуй так считать: Код private Quat GetBulletRotation() { Vec3 posToTurn = GetNeedPositionToTurnGun(); Vec3 diff = posToTurn - Position;
return Quat.FromDirectionZAxisUp(diff); }
Вcем зла.
Сообщение отредактировал Undead - Понедельник, 10 Июня 2013, 20:16 |
|
| |
Cyber | Дата: Понедельник, 10 Июня 2013, 19:36 | Сообщение # 19 |
был не раз
Сейчас нет на сайте
| А я и не знал, что этот метод настолько полезен! Не расслабляйтесь, я еще здесь появлюсь) Благодарю, вы сильно помогли)) Добавлено (10.06.2013, 19:36) --------------------------------------------- Поведение пули не менял) Гравитацию не трогал) Но уже неважно, возьму на заметку эту полезнейшую функцию
|
|
| |
Undead | Дата: Понедельник, 10 Июня 2013, 20:23 | Сообщение # 20 |
NeoAxis User
Сейчас нет на сайте
| Теперь прямо летят?
Добавлено (10.06.2013, 20:23) --------------------------------------------- Цитата (Cyber) Не расслабляйтесь, я еще здесь появлюсь) Появляйся. Я вот только не видел здесь других, кто бы отвечал на вопросы по NeoAxis.
Вcем зла.
Сообщение отредактировал Undead - Понедельник, 10 Июня 2013, 20:24 |
|
| |
|