*Shoker* 322 Опубликовано 27 Января 2013 Может кто нибудь помочь вывести векторную формулу? У меня совсем туго с векторной алгеброй =\ Суть в том, что я спавню физический объект перед камерой игрока, и мне надо чтобы его нос был направлен туда, куда смотрит игрок. Что есть: v1 = device().cam_pos -- Вектор. Позиция камеры игрока v1_dir = device().cam_dir -- Направляющий (?) вектор, v1 + v1_dir = точка в метре от игрока, в которую он смотрит Мне нужно из этой информации получить вектор в радианах, который содержит поворот объекта по каждой из трёх осей (x,y,z, значения от 0 до 3.14) Мысли в голове крутятся, но никак не могу что то сообразить стоящее =\ Лишь тыкать наугад формулами. Подозреваю что мне надо получить углы между осями каждого вектора и перевести их в радианы, но опять таки как это правильно сделать... Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 27 Января 2013 (изменено) *Shoker*, если не секрет конечно, по средством какого метода ты пытаешься развернуть объект при спавне? Меняю в момент спавна, переписывая abstract-пакет объекта в STATE_Write, старый метод ещё с ТЧ. ColR_iT, я не знаю про какую версию игры идёт речь, но в ЗП у серверного объекта есть свойство angle, которое доступно и на запись. Кусок из treasure_manager: Речь про ЧН, но ЗП тоже подразумевается. Про angle знаю, но нет в ЧН + тоже не даёт требуемой точности. Нормально - никак не получишь. cam_dir - нормализованный view-space вектор направления камеры. Если тебе нужны углы Эйлера, нужно возиться с матрицами поворота и арксинусами/арккосинусами. В принципе, вся нужная инфа есть даже в википедии. Если тебе надо не очень точно, лучше взять direction у актора. Там как раз углы Эйлера, только вот обновляются они реже, чем хотелось бы. Подстава =\ Нужна именно высокая точность, т.к объект спавнится близко к экрану. А дирекция игрока от ног идёт.... хотя попробую, м.б такой хватит. Знаний для работы с матрицами поворота у меня не хватает. Оффтоп: где то уже говорили, но как отключить выделение элементов сайта при попытке копирования. А то я даже имя не могу скопировать чтобы вместе с ним не скопировался фон сайта и шрифт текста. _______________________ Ладно, вопрос в принципе снимается, в итоге решил отказаться от своей затеи и просто рэндомную дирекцию делать. Также db.actor:position() не похоже что содержит углы Эйлера, он по моему аналогичен cam_dir. Хотя если у кого то будут всё же идеи как повернуть объект по направлению взгляда ГГ то на будущее рад буду если подскажите. Всем спасибо за помощь Изменено 27 Января 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 4 Февраля 2013 (изменено) =\ В наличии есть нормированный направляющий вектор, смотрящий ровно вперёд от объекта Надо каким то образом из него получить похожий вектор, но направленный уже строго вправо относительно объекта и строго вверх относительно объекта. Для игрока в классе камеры эти векторы уже доступны через: vector cam_dir; // единичный вектор направления взгляда vector cam_right; // единичный вектор, перпендикулярный направлению камеры и направленный вправо vector cam_top; // единичный вектор, перпендикулярный направлению камеры и направленный вверх Однако для объектов два нижних вектора не доступны, доступен лишь вектор направления. Соответственно я стал эксперементировать на игроке с вектором cam_dir дабы вывести формулу для получения двух оставшихся. Сперва я попытался получить вектор cam_right путём поворота (через матрицы) направляющего вектора cam_dir по оси Y на 90 градусов вбок. Однако этот приём работает лишь когда игрок смотрит ровно прямо, без наклона головы вверх\вниз --\\ Поворот вектора на заданные углы function vector_rotate(V, rY) local vI = vector():set(math.cos(rY), 0, math.sin(rY)) local vJ = vector():set(0, 1, 0) local vK = vector():set(-math.sin(rY), 0, math.cos(rY)) V.x = vI.x * V.x + vI.y * V.y + vI.z * V.z V.y = vJ.x * V.x + vJ.y * V.y + vJ.z * V.z V.z = vK.x * V.x + vK.y * V.y + vK.z * V.z return V end Ежели игрок наклоняет голову, то точка начинает выписывать овал. Я так понял что поворот вектора по оси Y идёт не относительно СВОЕЙ оси Y а относительно некого вектора (0,1,0). Какую формулу мне надо использовать дабы вектор крутился вокруг своей собственной оси Y? (и в перспективе аналогичный метод для оси X) Или какие ещё методы можно применить для получения искомых векторов cam_right и cam_top Конкретно поворот на произвольный угол не интересует, мне лишь нужно найти формулу для расчёта перпендикулярных векторов.... Чёрт, только щас дошло -___- _____________________________________________________________________ Кто нибудь может пож-ста словами или готовым кодом написать формулу для нахождения перпендикулярного вектора направленного вбок от искомого и перпендикулярного вектора, направленного вверх от искомого? Только полную пож-ста, сокращённые или перегруженные коды на просторах сети мой мозг отказывается переваривать =\ Изменено 4 Февраля 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 6 Февраля 2013 (изменено) Спасибище всем за помощь :ny_santa: Сам бы врятли справился бы. Простое решение как обычно прошло мимо меня Получилось что то такое: function get_all_direction(dir) --* "Вправо" local dir_right = vector() dir_right:crossproduct(dir, vector():set(0,1,0)) dir_right = dir_right:normalize() --* "Вверх" local dir_up = vector() dir_up:crossproduct(dir_right, dir) dir_up = dir_up:normalize() return dir_right:invert(), dir_up end local item = db.actor:active_item() local vX, vY = get_all_direction(item:direction()) В принципе теперь я могу доделать то, что планировал Однако в данной функции есть один недостаток - она не учитывает Roll (наклон объекта вбок) То есть если игрок выглядывает из за угла (наклоняется вправо\влево), то этот наклон не учитывается при расчёте боковых векторов. Есть ли не шибко сложный способ это поправить? Функцию юзаю на оружии в руках у НПС, а они могут например стрелять из укрытия, заваливая ствол на бок. Это в принципе для меня не настолько критично но всё же если есть способ то лучше поправить. Изменено 6 Февраля 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 6 Февраля 2013 (изменено) Пытаюсь допилить 3D-гильзы от выстрелов. Механизм уже готов для ГГ, сейчас вот адаптирую схему под НПС, в связи с тем нет возможности использовать векторы от камеры =\ В принципе в момент выстрела ствол обычно смотрит ровно, но ведь НПС может стрелять и из укрытия вслепую, но в принципе это всё довольно редкие события поэтому наличие таких мелких "недоработок" в принципе не критично. Дирекция мне нужна чтобы указать в какую сторону отлететь гильзе (для хита) X-Ray ext применять не хочу, также можно было бы ещё просто в оружии добавить новые кости (одна у затвора, другая левее) и через них считать направляющий вектор, но в обоих случаях схема перестаёт быть универсальной. malandrinus Я именно про оружие в руках НПС, а не про худ - с худом то как раз проблем нету Просто я тестировал с камерой игрока т.к у меня скрипт был под неё настроен + можно было сравнить получившиеся векторы с "эталонными" от device() Изменено 6 Февраля 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 13 Февраля 2013 Старлей Видимо скрипт ни в одном моде не тестировали [size=4]local smart_ids = {4869,209}[/size] for k,v in pairs(smart_ids) do smart = squad.board.smarts[v].smrt Таблица smarts находится в скрипте sim_board.script --' Таблица содержащая смарты и данные о них в формате: --' smart = {smrt, targets = {}, dangers = {}, squads = {}, stayed_squad_quan = 0} self.smarts = {} И она в качестве индекса содержит id (идентификатор) объекта (смарта) self.smarts[obj.id] = ... Который при КАЖДОЙ новой игре всегда разный. (здесь видимо спутали со story id) В скрипте же идёт попытка получить смарт по его id, который к новой игре уже не применим, т.к объекта с таким id уже просто не существует. squad.board.smarts[v] Где v = 4869 - нет такого смарта, что и генерирует вылет при попытке далее взять значение поля smrt _______________________________________________ А вообще при беглом осмотре там какой то бред получается, скрипт скорее всего не доделан и как он попал в моды вообще не понятно. В частности вся суть function update_squad(squad,pflag) сводится к тому, чтобы проверить два указанных смарта с id {4869,209}, (притом что при новой игре эти значения уже будут не верны, что наводит на мысль что автор скрипта просто тестировал что то своё) Далее если смарт находится не на одном уровне с игроком, то из него выгоняются все отряды кроме одного, который был передан в функцию. Как вариант попробуй сократить функцию до: [/size] function update_squad(squad,pflag) for k,v in pairs(squad.squad_npc) do local npc = level.object_by_id(k) if npc ~= nil then npc:remove_all_restrictions() end end end М.б всё заработает. CRAZY_STALKER666 Раскоментируй везде dbg.log (если у тебя в моде есть такой скрипт, в противном случае выводи сообщения любым другим способом) и смотри в консоли\в игре в каком моменте скрипт перестаёт выполняться. 2 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 11 Апреля 2013 (изменено) Давно со скриптами сталкера не работал, мозги немного заплыли жиром. Хочу попробовать "грубо" реализовать тело игрока от первого лица через физ объект с анимациями, но для этого нужно решить некоторые проблемы, в частности ни у кого нет идей каким образом можно двигать физ. объект (коллизия у него будет отключена) вместе с игроком? Функции телепортации для физ. объектов вроде как нету, пока рассматриваю вариант пытаться двигать объект за игроком через физику, но это будет то ещё извращение. Работаю на ЧН, но сойдёт и ЗП вариант. Как вариант - посмотри реализацию грави-пушки. ColR_iT Изменено 11 Апреля 2013 пользователем ColR_iT Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 18 Мая 2013 (изменено) Всё работает, просто ты перепутал типы объекта. В игре у почти каждого объекта есть клиентская и серверная часть. Функцией alife():create() ты создаёшь СЕРВЕРНЫЙ объект (а у него свои функции и свойства)А уже в апдейте ты (как один из вариантов) получаешь клиентский объект для которого функции position(), level_vertex_id() и прочие существуют. Собственно в твоём примере надо obj:position() заменить на obj.position Аналогично obj:game_vertex_id() на obj.m_game_vertex_id Откуда я это знаю? Открываешь scripts\lua_help.script Дальше ты должен знать название класса серверного объекта предмета который ты спавнишь (это уже сам как нить найдёшь), но в принципе этим можно пренебречь поскольку функции практически одинаковы для всех объектов. Допустим ты спавнишь сталкера, у него серверный класс это class cse_alife_creature_abstract Ищешь его в lua_help.script local obj=alife():create(spawn_item, pos, vid, gvid) В obj будет хранится именно объект серверного класса. Вообще если посмотришь этот класс то увидишь что функций position() и прочих в нём нету. Однако в замен есть СВОЙСТВА C++ class cse_alife_creature_abstract : cse_alife_dynamic_object_visual { property group; property id; property m_game_vertex_id; property m_level_vertex_id; property m_story_id; property online; property parent_id; property position; property script_version; ...И вот тут ты как раз можешь получить свою позицию. local pos = obj.position Чтобы в дальнейшем не путаться советую серверные объекты обозначать как sobj или типа того, просто чтобы самому была видна разница. Ну а клиентский объект можно получить через функцию local obj = level.object_by_id(<id-объекта>) Почему не сделать так? local sobj = alife():create(spawn_item, pos, vid, gvid) local obj = level.object_by_id(sobj.id) obj:position() Потому что когда ты спавнишь объект, создаётся его серверная часть (sobj) однако клиентской (obj) ещё не существует, она будет создана лишь на следующих апдейтах. PS: Извиняюсь за кривой пост, когда копирую текст он копируется вместе с задним фоном и форматированием. Забыл как выключить это. Изменено 18 Мая 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 19 Июня 2013 (изменено) Кто нибудь случаем не находил способ менять дирекцию (взгляд) физического онлайн объекта чтобы изменения были видны сразу?Допустим на земле валяется аптечка и нужно менять её дирекцию с достаточной большой скоростью. Я в данный момент пытался физикой это сделать, сделал себе модель-болванку и через класс physics_joint пытался указывать направление джоинта через функции типа set_axis_dir_global(number, number, number, number); В оригинале эти функции никак не используются, примера глянуть негде, в игре на них никакой реакции не было. Может кто то уже придумал как изменить дирекцию объекта допустим через физику? Изменено 19 Июня 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 19 Июня 2013 Вариант сделать под объектом джоинт типа "колесо" и крутить его в одну сторону щас тоже наверно буду пробовать Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 19 Июня 2013 Есть ещё вариант, тут его читал как раз. Через функцию get_console():execute("команда значение") присвоить какой либо не используемой\незначительной консольной команде (список команд через help получить можно) своё значение (отличное от значения по умолчанию), а потом при следующем запуске из этой же консоли его и считать (class CConsole в scripts\lua_help.script глянь) Из плюсов - значение вроде как хранится в user.ltx а потому у каждого игрока он свой, из минусов - user.ltx могут удалить игроки) Вариант с переименовыванием в этом плане понадёжней. Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 20 Июня 2013 dukekan> Значение переменной vaue после загрузки будет не числовым, а строковым Вместо get_string используй другую функцию, и будет грузить число. Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 7 Августа 2013 (изменено) Хотел спросить, уже достаточно много времени прошло, никто не нашёл в ЗП более\менее адекватную замену функции level.main_input_receiver()? Эта функция возвращала текущее UI-окно, позволяя его изменять, но лично я её использовал чтобы определить что игрок сейчас не находится в инвентаре\ПДА\диалоге и вообще любом интерфейсе. Вроде одно время мелькало сообщение, что где то нашли функцию-замену в одном из UI-классов или типа того. Ну или вообще какие есть более\менее адекватные варианты чтобы определить что в данный момент у игрока не открыта никакая UI-менюшка (как движковые ПДА\Инвентори, так и скриптово добавленные окна) чтобы не делать для каждого из них персональную проверку. _______________Нашёл этот пост (в прошлый раз не так поиском воспользовался), он закрывает вопросы по level.main_input_receiver(), но всё ещё остаётся вопрос о том как универсальным методом определить что открыто любое UI-окно. (без правок движка) Изменено 7 Августа 2013 пользователем *Shoker* 1 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 10 Августа 2013 (изменено) @abramcumner,@Shredder, @Viнt@rь, Спасибо за советы, я просто искал универсальный метод, т.к если мои наработки будут использоваться в других модах, об этом могут тупо забыть. ----------------------------------------------------------------------- Такой вот вопросец по биндеру объектов, возможно это уже баян, но для меня было новостью.Может даже косяк из за правленых экзешников, но сейчас уже поздно проверять и это, надо игру переставлять, собстно такое дело:Платформа ЗП 1.6.02, экзешники из Мизери и там хз какие правки вносились но по идее стандартные на рендер, солнце и т.д, собственно сделал в скриптах свой биндер (object_binder) в него добавил методы save\load чтобы сохранять свои данные. И тут вылезла такая проблема. Если сохранять\загружать игру на одной и той же локации то оба метода прекрасно вызываются, однако если перейти на другую локацию а потом обратно то метод load у объекта не вызывается, соответственно сохранённые данные уже не грузятся и полезность данных методов падает до нуля. Я сперва думал что проблема тока с моим биндером, но потом сделал вывод в консоль из motivator_binder (который хранит инфу о онлайн-сталкерах) и оказалось что там та-же самая проблема, притом что ПЫС хранят там в save\load довольно много инфы, а функция load просто не вызывается при переходе из другой локации соответственно вся сохранённая инфа теряется, и это ведь только один из кучи биндеров!Я завтра ещё проверю но вообще интересно - это нормальная ситуация? Сбоев с игрой я пока не ловил, но я уже давно не делал в ней длинные сессии, да и то всегда на одной локации. Изменено 14 Августа 2013 пользователем ColR_iT Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 11 Августа 2013 (изменено) @abramcumner, "для оригинального", а что есть решение? На других частях сталкера всё нормально? Или ты просто имеешь ввиду что в ЗП так и должно быть, если да то странно. Просто на save\load же повешены пстор и прочие данные объектов, я вообще удивлён что игра после этого ещё работает. Вообщем разобрался, оказывается чтобы клиентские данные сохранялись при переходе на другой уровень нужно в серверном классе добавить метод keep_saved_data_anyway(), возвращающий true.Другой вопрос что у тех же сталкеров в ЗП этот метод в серверном классе не прописан, остаётся выяснить - это баг или фича. %) Изменено 11 Августа 2013 пользователем *Shoker* 1 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 13 Августа 2013 (изменено) @Dennis_Chikin, ну дык игрой наверно не предусмотрено удаление смарта прямо во время игры, это всё таки довольно комплексная вещь на которую завязаны многие скрипты, и оригинальная игра не предусматривает внезапное удаление смарта соответственно в скриптах нет никаких проверок на его существование, а того гляди и в движке какая нибудь хрень вылезет. Вообще странно зачем удалять смарт во время игры а не сделать это через all.spawn? Но если это так критично, то попробуй в скрипте smart_terrain.script там в классе class "se_smart_terrain" (cse_alife_smart_zone) в функциях, которые регистрируют созданный смарт поставить проверку по имени на ненужный тебе смарт, чтобы он не регистрировался ни в какие скрипты. Аналогично в биндере проверку по имени делай и не позволяй смарту заносить себя в какие либо таблицы, или даже можешь попробовать в биндере в функции net_spawn() возвращать false для ненужного смарта, тогда по идее он не заспавнится или не перейдёт в онлайн. Изменено 13 Августа 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 23 Августа 2013 (изменено) local cam_position = device().cam_pos --> Позиция камеры local pos = db.actor:bone_position("bip01_head") --> Позиция головы игрока local distance = cam_position:distance_to(pos) --> Расстояние от камеры до головы ГГ Не совсем понял как ты хочешь по разнице Y-ов определять что включён вид от 3-го лица с фиксированной или свободной камерой. Как вариант настройки камеры от разного лица хранятся в файле system.ltx, actor_cam_look_ или как то так, найдёшь там вообщем. Там есть такой параметр как максимальное удаление\приближение камеры к игроку (на +\-) Настрой эти параметры так чтобы от 3-го лица с фиксированной камерой приближение было одно (например от 2 до 5 метров или ровно 5-5 чтобы камера всегда в одном месте висела), а со свободной другое (от 5\6 и больше). Что то вроде этого. Тогда уже через distance определяй как далеко от игрока находится камера и соответственно для какого вида это расстояние приемлимо. Изменено 23 Августа 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 26 Августа 2013 @Сталкер Лом, глянь скрипты ui_save_dialog\ui_load_dialog.scriptЭто скрипты сохранения\загрузки и там показан пример проверки наличия текстуры в папке с сейвами.Делай по аналогии для своего скрипта проверку что такой файл существует. Само собой это при условии что ты знаешь название текстуры. По парт-текстуру первый раз слышу или не понял что это такое. 1 Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 2 Сентября 2013 (изменено) Я не смотрел скрипт АМК, поэтому не знаю что делает функция readvu8uN но в остальном тут не должно быть ошибок. Но вообще для работы с нэт-пакетами лучше использовать скрипт m_netpk (или как то так, ещё может m_net_utils.script называться) из Simbion Mod-а (потому что на форуме будет проблематично его найти) Там очень удобная библиотека функций для работы с нэт-пакетами. Ну или найди последние посты xStream-а в которых как раз обсуждались нэт-пакеты. Собстно вбей в поиск по этой теме m_netpk и найдёшь тут один из вариантов (если ещё нету более новых) Изменено 2 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение
*Shoker* 322 Опубликовано 8 Сентября 2013 (изменено) @boryan67, покажи 143-ю строчку скрипта (в Notepad++ например их видно) Скорее всего ты забыл добавить функцию table.size(), которая считает кол-во элементов в таблице. Кажется она сидит в m_helpers.script хотя точно не уверен, видимо ты его не до конца подключил. Так что или подруби её или перенеси её вручную в se_stor, поменяй название на какое нибудь table_size()и в скрипте измени все вызовы. Изменено 8 Сентября 2013 пользователем *Shoker* Можно просто Shoker, форум АМК съел моё старое имя и не хочет отдавать о_О Мастер аномалий на свою заднюю точку. Поделиться этим сообщением Ссылка на сообщение