Да однозначно надо рефоржед ставить - уже в процессе. Проверил твою функцию в 1.26а - в старом патче нулевые координаты это левый верхний угол, по твоему коду получается левый нижний и такая же погрешность как и у меня, она скорее всего из-за широкоформатного фикса.
А не, это не погрешность видимо в рефоржед возможны отрицательные координаты мыши типа -0.124 в левой стороне экрана и оси местами поменяли, когда в старом патче меньше 0 числа невозможны
Вообще классический фрозентрон хранит позицию мыши в двух переменных по адресам 6FACE690 для X и 6FACE694 для Y и их можно напрямую дернуть мемхаком, а вот какая архитектура в рефоржеде и можно ли извратиться для получения куска памяти я не знаю - никогда не пробовал его дизассемблировать
P.S множители 0.4 и 0.355, если память не изменяет это для 16/9 на других соотношениях поплывет, если получить разрешение напрямую нельзя, то стоит запрашивать их у игрока принудительно и пока не введет в игру не пускать
Smeto, я сейчас практически переписал код на рабочий вариант, но у меня патч 1.26а с вайдскрин фиксом - поэтому я конвертирую позицию юнита в экранные координаты и пока у меня есть погрешность. Надо качать рефоржед и проверять там, если можно то вышли в личку эту тормозящую версию -я поставлю и попробую ускорить.
На вскидку: можно не получать ротаторы камеры каждую конверсию, а писать их в переменные при изменении камеры, только вопрос: можно ли в рефоржед отловить нажатия клавиш поворота камеры и прокрутку колеса мыши, что бы при этих действиях тоже обновлять?
Сейчас почитал, это вроде только массивы vJass нельзя локально объявлять, а стандартные по идее можно - да, надо тестировать самому все-таки, смутно помню что как
Smeto, Claude 4 sonnet.
Мда, забыл я джазз за 10 лет, оказывается)
Думаю переделать под корректный синтаксис можно, если время появится попробую рефоржед поставить и поколдовать над скриптом, если сам не переделаешь к тому времени Хотя, еще на балнсе пару баксов есть, можно твой коммент прислать, пусть исправляет)
Корректнее будет пересчитать мировые координаты в экранные на основе параметров камеры и пропорций экрана, по-моему, реализация для старых патчей была в DGUI - стоит попробовать портировать функцию оттуда
ИИ-шный код на JASS. Не тестировал, но на первый взгляд выглядит корректно
Код
// Глобальные переменные для результата конвертации
globals
integer udg_ScreenX = 0
integer udg_ScreenY = 0
real udg_ScreenDepth = 0.0
endglobals
// Умножение матриц 4x4 (результат в matrixC)
function MultiplyMatrix4x4 takes real array matrixA, real array matrixB, real array matrixC returns nothing
local integer i = 0
local integer j = 0
local integer k = 0
loop
exitwhen i > 3
set j = 0
loop
exitwhen j > 3
set matrixC[i * 4 + j] = 0.0
set k = 0
loop
exitwhen k > 3
set matrixC[i * 4 + j] = matrixC[i * 4 + j] + matrixA[i * 4 + k] * matrixB[k * 4 + j]
set k = k + 1
endloop
set j = j + 1
endloop
set i = i + 1
endloop
endfunction
// Создание матрицы вида на основе параметров камеры
function CreateViewMatrix takes real camX, real camY, real camZ, real yawDeg, real pitchDeg, real rollDeg, real array viewMatrix returns nothing
local real yawRad = yawDeg * 3.141592653589793 / 180.0
local real pitchRad = pitchDeg * 3.141592653589793 / 180.0
local real rollRad = rollDeg * 3.141592653589793 / 180.0
local real cosY = Cos(yawRad)
local real sinY = Sin(yawRad)
local real cosX = Cos(pitchRad)
local real sinX = Sin(pitchRad)
local real cosZ = Cos(rollRad)
local real sinZ = Sin(rollRad)
// Временные матрицы
local real array rotY[16]
local real array rotX[16]
local real array rotZ[16]
local real array rotation[16]
local real array translation[16]
local real array temp[16]
// Матрица поворота Y (Yaw)
set rotY[0] = cosY // [0,0]
set rotY[1] = 0.0 // [0,1]
set rotY[2] = sinY // [0,2]
set rotY[3] = 0.0 // [0,3]
set rotY[4] = 0.0 // [1,0]
set rotY[5] = 1.0 // [1,1]
set rotY[6] = 0.0 // [1,2]
set rotY[7] = 0.0 // [1,3]
set rotY[8] = -sinY // [2,0]
set rotY[9] = 0.0 // [2,1]
set rotY[10] = cosY // [2,2]
set rotY[11] = 0.0 // [2,3]
set rotY[12] = 0.0 // [3,0]
set rotY[13] = 0.0 // [3,1]
set rotY[14] = 0.0 // [3,2]
set rotY[15] = 1.0 // [3,3]
// Матрица поворота X (Pitch)
set rotX[0] = 1.0 // [0,0]
set rotX[1] = 0.0 // [0,1]
set rotX[2] = 0.0 // [0,2]
set rotX[3] = 0.0 // [0,3]
set rotX[4] = 0.0 // [1,0]
set rotX[5] = cosX // [1,1]
set rotX[6] = -sinX // [1,2]
set rotX[7] = 0.0 // [1,3]
set rotX[8] = 0.0 // [2,0]
set rotX[9] = sinX // [2,1]
set rotX[10] = cosX // [2,2]
set rotX[11] = 0.0 // [2,3]
set rotX[12] = 0.0 // [3,0]
set rotX[13] = 0.0 // [3,1]
set rotX[14] = 0.0 // [3,2]
set rotX[15] = 1.0 // [3,3]
// Матрица поворота Z (Roll)
set rotZ[0] = cosZ // [0,0]
set rotZ[1] = -sinZ // [0,1]
set rotZ[2] = 0.0 // [0,2]
set rotZ[3] = 0.0 // [0,3]
set rotZ[4] = sinZ // [1,0]
set rotZ[5] = cosZ // [1,1]
set rotZ[6] = 0.0 // [1,2]
set rotZ[7] = 0.0 // [1,3]
set rotZ[8] = 0.0 // [2,0]
set rotZ[9] = 0.0 // [2,1]
set rotZ[10] = 1.0 // [2,2]
set rotZ[11] = 0.0 // [2,3]
set rotZ[12] = 0.0 // [3,0]
set rotZ[13] = 0.0 // [3,1]
set rotZ[14] = 0.0 // [3,2]
set rotZ[15] = 1.0 // [3,3]
// Матрица трансляции
set translation[0] = 1.0 // [0,0]
set translation[1] = 0.0 // [0,1]
set translation[2] = 0.0 // [0,2]
set translation[3] = -camX // [0,3]
set translation[4] = 0.0 // [1,0]
set translation[5] = 1.0 // [1,1]
set translation[6] = 0.0 // [1,2]
set translation[7] = -camY // [1,3]
set translation[8] = 0.0 // [2,0]
set translation[9] = 0.0 // [2,1]
set translation[10] = 1.0 // [2,2]
set translation[11] = -camZ // [2,3]
set translation[12] = 0.0 // [3,0]
set translation[13] = 0.0 // [3,1]
set translation[14] = 0.0 // [3,2]
set translation[15] = 1.0 // [3,3]
// Комбинируем повороты: Z * X * Y
call MultiplyMatrix4x4(rotZ, rotX, temp)
call MultiplyMatrix4x4(temp, rotY, rotation)
// View matrix = Rotation * Translation
call MultiplyMatrix4x4(rotation, translation, viewMatrix)
endfunction
// Создание матрицы проекции
function CreateProjectionMatrix takes real fovDeg, real screenWidth, real screenHeight, real nearPlane, real farPlane, real array projMatrix returns nothing
local real aspect = screenWidth / screenHeight
local real fovRad = fovDeg * 3.141592653589793 / 180.0
local real f = 1.0 / Tan(fovRad / 2.0)
local real rangeInv = 1.0 / (nearPlane - farPlane)
local integer i = 0
// Очищаем матрицу
loop
exitwhen i > 15
set projMatrix[i] = 0.0
set i = i + 1
endloop
// Заполняем матрицу проекции
set projMatrix[0] = f / aspect // [0,0]
set projMatrix[5] = f // [1,1]
set projMatrix[10] = (nearPlane + farPlane) * rangeInv // [2,2]
set projMatrix[11] = 2.0 * nearPlane * farPlane * rangeInv // [2,3]
set projMatrix[14] = -1.0 // [3,2]
endfunction
// ОСНОВНАЯ ФУНКЦИЯ: Конвертация мировых координат в экранные
// Параметры:
// worldX, worldY, worldZ - мировые координаты точки
// camX, camY, camZ - позиция камеры
// yawDeg, pitchDeg, rollDeg - углы поворота камеры в градусах
// fovDeg - угол обзора в градусах
// screenWidth, screenHeight - разрешение экрана в пикселях
// nearPlane, farPlane - ближняя и дальняя плоскости отсечения
// Результат: true если точка видна, координаты в udg_ScreenX, udg_ScreenY
function WorldToScreen takes real worldX, real worldY, real worldZ, real camX, real camY, real camZ, real yawDeg, real pitchDeg, real rollDeg, real fovDeg, real screenWidth, real screenHeight, real nearPlane, real farPlane returns boolean
local real array viewMatrix[16]
local real array projMatrix[16]
local real array viewProjMatrix[16]
local real clipX
local real clipY
local real clipZ
local real clipW
local real ndcX
local real ndcY
local real ndcZ
// Создаем матрицы трансформации
call CreateViewMatrix(camX, camY, camZ, yawDeg, pitchDeg, rollDeg, viewMatrix)
call CreateProjectionMatrix(fovDeg, screenWidth, screenHeight, nearPlane, farPlane, projMatrix)
call MultiplyMatrix4x4(projMatrix, viewMatrix, viewProjMatrix)
// Умножение на view-projection матрицу
set clipX = viewProjMatrix[0] * worldX + viewProjMatrix[1] * worldY + viewProjMatrix[2] * worldZ + viewProjMatrix[3]
set clipY = viewProjMatrix[4] * worldX + viewProjMatrix[5] * worldY + viewProjMatrix[6] * worldZ + viewProjMatrix[7]
set clipZ = viewProjMatrix[8] * worldX + viewProjMatrix[9] * worldY + viewProjMatrix[10] * worldZ + viewProjMatrix[11]
set clipW = viewProjMatrix[12] * worldX + viewProjMatrix[13] * worldY + viewProjMatrix[14] * worldZ + viewProjMatrix[15]
// Проверка, что точка не за камерой
if clipW <= 0.0 then
return false
endif
// Perspective divide
set ndcX = clipX / clipW
set ndcY = clipY / clipW
set ndcZ = clipZ / clipW
// Проверка, что точка в пределах frustum
if ndcX < -1.0 or ndcX > 1.0 or ndcY < -1.0 or ndcY > 1.0 or ndcZ < -1.0 or ndcZ > 1.0 then
return false
endif
// Конвертация в экранные координаты
set udg_ScreenX = R2I((ndcX + 1.0) * 0.5 * screenWidth)
set udg_ScreenY = R2I((1.0 - ndcY) * 0.5 * screenHeight)
set udg_ScreenDepth = ndcZ
return true
endfunction
// Пример использования
function TestWorldToScreenConversion takes nothing returns nothing
local boolean visible
// Указать параметры камеры( лучше получить динамически актуальные)
local real cameraX = 0.0
local real cameraY = 0.0
local real cameraZ = 100.0
local real cameraYaw = 0.0 // градусы
local real cameraPitch = -30.0 // градусы
local real cameraRoll = 0.0 // градусы
local real fov = 60.0 // градусы
// Тестируем точку в мире
set visible = WorldToScreen(100.0, 200.0, 0.0, cameraX, cameraY, cameraZ, cameraYaw, cameraPitch, cameraRoll, fov, 1920.0, 1080.0, 0.1, 1000.0)
if visible then
call BJDebugMsg("Точка видна на экране: X=" + I2S(udg_ScreenX) + " Y=" + I2S(udg_ScreenY))
else
call BJDebugMsg("Точка не видна камере")
endif
endfunction
Вот манипулирование объектами я как раз и хочу исправить в первую очередь, а по поводу импорта хотелось бы услышать пожелания - я реализовал относительные пути к текстурам вместо абсолютных, но потом подумал что у игроков без мода не запустится корректо и вырезал эту фичу. А вот улучшить работу с импортом именно в редакторе идея очень даже интересная
LongbowMan, ух, ты не видел что с ними сделали китайцы, даже то что мы делали будучи новичками умудрились перековеркать, я уже второй месяц исправляю). (так как исходников и доступа к репозиторию уже 100 лет нет, пришлось все запчасти собирать в Китае).
Дорабатывая RE я делаю упор в совместимость, но я еще думаю сделать набор инструментов и скриптов для новичков, для компоновки тех же атласов, например, что бы они автоматически собирали допкарты, если у оригинальных элементов они были.
И возможно переписать еще кусок редактора, после 8 лет анрила работая в WE чувствую себя кастратом)
LongbowMan, понял - в принципе логично, ничего карты сгенерируем с минимальной ретушью значит) В RE тени у юнитов пришлось временно порезать, там жуткий ботлнек с ними - оставил у декораций, послее ряда оптимизаций. Хотя думаю все-таки включить юнитам-зданиям, но фильтровать их придется пока по текстурам и скорее всего уже в следующих версиях.
А по поводу совместимости: вмешательства в формат моделей нет, так что игрок без мода получит точь в точь то что и сейчас, обычный рендер без карт
P.S пользуясь случаем спрошу, могу ли я использовать твои модели зданий альянса из WAA, в графической демке? т.к планирую помимо полностью нестандартной еще и мили-карту собрать
Никаких карт нормалей или спекулярок не используется, чтобы не переусложнять работу и сохранить совместимость с классическим Warcraft III.
В ближайшее время RenderEdge получит обновление с поддержкой normal, roughness, metallic, specular, emissive, так что эти карты бы не помешали и для классики, в случае если карту запускает игрок без мода они просто не будут использоваться, не нарушая совместимости)
Empyreal, лимит на tga не распространяется, только вес не для мультиплеера конечно, если лимит не снимать - а если снимать то можно и с blp заодно ограничение отключить сразу, если патчить
darkowlom, на жассе можно объявлять локалки внутри цикла?
МрачныйВорон, это сижасс. Он переносит объявления локалок вверх функции. Из-за чего особо одарённые картоделы начинают думать, что можно объявлять локалки где попало и в итоге отстреливают себе колено.
Ты сам ответил, там не чистый джазз Чистым еще кто-то пользуется вообще? 0_о
не надо делать внутри лупа local так может варик лагануть, лучше наверху лупа поставь локал u и в лупе set u =
С чего бы? Локальная переменная объявленная внутри цикла существует только в теле этого цикла и только время его выполнения, соответственно, если не пытаться к ней обращаться после его завершения поведение всегда стабильно
N7 Molot, я списывался с ними по этому вопросу - там упор на безопасность, такие ограничения ради недопущения мемхака и вредоносных модов. В целом ты можешь обсуждать с ними весь нужный тебе функционал, но получишь правки или инструкции по зажатию функций, потом предоставляешь код редактора на инспекцию и тд.
В общем для себя я решил что мне проще написать ряд фактори для создания ассетов прямо из игры и внутриигровой редактор
Как пример такого редактора vfx-tools "Fluid Ninja" технически - игровая карта вызывающая на выходе фактори который создает текстуры и ассеты. Если ее собрать в отдельный билд, то это и будет такой отдельный редактор, не являющийся редактором в рамках лиц.соглашения
N7 Molot, для поставки редактора с игрой, эпик геймс требует заключения с ними особого соглашения, в котором будет указано что именно, ты как разработчик, имеешь право включить в поставку редактора. Внутриигровой редактор таких заморчоек не требует, но он будет более ограничен
SNART, вообще можно пропечь симуляцию воды в анимацию, например из гудини, и текстуры для каждого кадра также пропечь - будет сносно, только весить будет тоже)
Ред. darkowlom
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Ред. darkowlom
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Ред. darkowlom
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Ред. darkowlom
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Ред. darkowlom
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
Мда, забыл я джазз за 10 лет, оказывается)
Думаю переделать под корректный синтаксис можно, если время появится попробую рефоржед поставить и поколдовать над скриптом, если сам не переделаешь к тому времени
Хотя, еще на балнсе пару баксов есть, можно твой коммент прислать, пусть исправляет)
» WarCraft 3 / [2.0.3 vJass] UI - Move Able Frame - Перетаскиваем фрейм мышкой
» Warcraft 3 Classic HD / Warcraft 3 Classic HD
Ред. darkowlom
» Warcraft 3 Classic HD / Warcraft 3 Classic HD
И возможно переписать еще кусок редактора, после 8 лет анрила работая в WE чувствую себя кастратом)
Ред. darkowlom
» Warcraft 3 Classic HD / Warcraft 3 Classic HD
А по поводу совместимости: вмешательства в формат моделей нет, так что игрок без мода получит точь в точь то что и сейчас, обычный рендер без карт
» Warcraft 3 Classic HD / Warcraft 3 Classic HD
» Game Dev / Шейдерные эффекты
Ред. darkowlom
» WarCraft 3 / Антиспелл
Чистым еще кто-то пользуется вообще? 0_о
Ред. darkowlom
» WarCraft 3 / Антиспелл
» WarCraft 3 / Связь Warcraft MDX с миром большого 3D
Ред. darkowlom
» WarCraft 3 / Проблема с blp.
» Мир безумного / Frost Giant делает RTS на Unreal Engine 5
Ред. darkowlom
» Мир безумного / Frost Giant делает RTS на Unreal Engine 5
» RenderEdge / [RenderEdge] Widescreen Fix
» XGM Конкурсы / Mini-Game Contest: Reforged
» Мир безумного / Конкурс - "Инди месяца" от "Игромания" и "LG"
» WarCraft 3 / Реалистичная вода
» Мир безумного / GDC 2019 итоги
» WarCraft 3 / Проблема с тенями (моделинг)
GreatGorgile, это сбитые нормали, можешь вручную в мдлвизе их повернуть, но в максе это делается в один клик