Перейти к содержимому

TC1061

Пользователи
  • Публикации

    35
  • Зарегистрирован

  • Посещение

  • Победитель дней

    3

Сообщения, опубликованные пользователем TC1061


  1. Интересно, для чего тебе вращение трехмерных векторов при написании рейкастера, если соль алгоритма именно в минимизации векторных расчетов и статичной производительности?

    А как без вращения 3D точек сделать 3D рэйкастер? Я не знаю как. Вот у меня вот такие функции отвечают за рэйкастинг:

     

     

    function ray.ray(bd,sx,sy,sz,x,y,z,ax,ay,l,f)
    	--assert(x>=sx or y>=sy or z>=sz,"out of bounds")
    	l=l or 100
    	f=(f==true) and true or false
    	bgr,bgg,bgb=128,128,255
    	local fog=f and 255/(l/4) or 0
    	local r,g,b,a=0,0,0,0
    	local p=0
    	local ox,oy,oz=ray.rotateV3(0,0,1,ay,ax)
    	local rl=0.01
    	local rla=0.01
    	local rl2=0
    	while a<255 and p<l do
    		--print("R",p,math.floor(x),math.floor(y),math.floor(z),"|",r,g,b,a)
    		local br,bg,bb,ba=0,0,0,0
    		do
    			local x,y,z=math.floor(x),math.floor(y),math.floor(z)
    			--if x < sx and x >= 0 and y < sy and y >= 0 and z < sz and z >= 0 then
    				br,bg,bb,ba=ray.get(bd,x,y,z)
    				if ba > 0 then				
    				rl2=1
    				end
    			--end
    		end
    		do
    			local _
    			local x,y,z=math.floor(x+ox*0.5),math.floor(y+oy*0.5),math.floor(z+oz*0.5)
    			local br,bg,bb,ba=0,0,0,0
    			--if x < sx and x >= 0 and y < sy and y >= 0 and z < sz and z >= 0 then
    			--	local pia=x*(sy*sz*4)+y*(sz*4)+z*4+1
    			--	--print(pia>=#bd,pia,#bd)
    				_,_,_,ba=ray.get(bd,x,y,z)
    			--end
    			if ba<=0 then rl2=0.5 end
    		end
    		r=r+br*(ba/255)+((l-l/4<=p) and fog*rl or 0)
    		g=g+bg*(ba/255)+((l-l/4<=p) and fog*rl or 0)
    		b=b+bb*(ba/255)+((l-l/4<=p) and fog*rl or 0)
    		a=a+ba+((l-l/4<=p) and fog*rl or 0)
    		p=p+rl
    		x,y,z=x+ox*math.max(rl,rl2),y+oy*math.max(rl,rl2),z+oz*math.max(rl,rl2)
    		rl=rl+rla
    		rla=rla*1.01
    		if rl2 > 0 then
    			rl2=0
    		end
    	end
    	return r,g,b,a
    end
    function ray.rayidata(idata,b,sx,sy,sz,f,vl,cx,cy,cz,ax,ay,py,px)
    	local hwidth=idata:getWidth()/2
    	local hheight=idata:getHeight()/2
    	local py2=py/(idata:getWidth())
    	local px2=px/(idata:getHeight())
    	local function convert(x,y)
    		local width=idata:getWidth()-1
    		local height=idata:getHeight()-1
    		return py2*(x)+ay,px2*(y)+ax
    	end
    	idata:mapPixel(function(x,y)
    		local ay,ax=convert((x-hwidth),(y-hheight))
    		--local ay2,ax2=convert(-(x-hwidth),-(y-hheight))
    		--print((x-hwidth),(y-hheight),"|",ay-ay2,ax-ax2,"|",py2,px2)
    		local r,g,b,a=ray.ray(b,sx,sy,sz,cx,cy,cz,ax,ay,vl,f)
    		--print(x,y,"|",r,g,b,a,"|",(ax-hwidth)*py2,(ay-hheight)*px2)
    		return r/255,g/255,b/255,a/255
    	end)
    end
    

     

     

     

    Если что, то это все работает в love2d. Вот я поставил твои функции, но все равно как то не то. На рендеринг поставлен плоский мир, и он должен выглядеть соотвествующе, но как бы не так:

     

     

    2018_06_12_14_30_20.png

     

     

    Может, нужно использовать углы Эйлера или кватернионы?


  2. Ну вообщем, я пытался сделать воксельный рэйкастер. Мне нужна была функция вращения 3D вектора.
    Она должна принимать 5 аргументов, координаты вектора (X,Y,Z) и углы вращения (по Y, по X) и вращать вектор вокруг нулевой точки (0,0,0). Я вот попытался свою функцию реализовать, но она работает неправильно:

     

     

    local function rotateV3X(x,y,z,a)
    	local a=math.rad(a)
    	local m11,m12,m13=1,0,0
    	local m21,m22,m23=0,math.cos(a),-math.sin(a)
    	local m31,m32,m33=0,math.sin(a),math.cos(a)
    	return x*m11+y*m12+z*m13,  x*m21+y*m22+z*m23,  x*m31+y*m32+z*m33
    end
    local function rotateV3Y(x,y,z,a)
    	local a=math.rad(a)
    	local m11,m12,m13=math.cos(a),0,math.sin(a)
    	local m21,m22,m23=0,1,0
    	local m31,m32,m33=-math.sin(a),0,math.cos(a)
    	return x*m11+y*m12+z*m13,  x*m21+y*m22+z*m23,  x*m31+y*m32+z*m33
    end
    local function rotateV3Z(x,y,z,a)
    	local a=math.rad(a)
    	local m11,m12,m13=math.cos(a),-math.sin(a),0
    	local m21,m22,m23=math.sin(a),math.cos(a),0
    	local m31,m32,m33=0,0,1
    	return x*m11+y*m12+z*m13,  x*m21+y*m22+z*m23,  x*m31+y*m32+z*m33
    end
    function ray.rotateV3(x,y,z,ry,rx)
    	ry,rx=ray.normangle(ry),ray.normangle(rx)
    	x,y,z=rotateV3Y(x,y,z,ry)
    	x,y,z=rotateV3X(x,y,z,rx)
    	x,y,z=rotateV3Z(x,y,z,0)
    	return x,y,z
    end
    

     

     

    Кто нибудь может написать правильно вращающий эквивалент? Буду очень благодарен.


  3. Думаю, резать программы по строчкам как-то не правильно. А вдруг кто-то запихнет 9 килобайтов кода в одну строку? Лучше по килобайту считывать и отправлять

    P.S. кто-то может и по байту в строку положить

    • Нравится 2

  4. SoundLib by TC1061

    Здравствуйте! Сегодня я наконец-то доделал свою прекрасную либу для работы со звуковой картой! Она позволяет легко и быстро использовать этого зверя. На стороне вашей программы лежит лишь загрузка либы и ее использование (и удаление объектов звука)! Не нужно даже следить за тем, есть ли звуковая карта. Без нее библиотека никаких ошибок не выдает, но скорее всего не будет проигрывать звук. И главная ее особенность - она может проигрывать сколько угодно звуков одновременно (пока оперативка не кончится :giggle: ). Вообщем скачать ее можно здесь . Ну а на опенкомпе выполнить команду:

    pastebin get 0LwEez14 /lib/soundlib.lua
    

    Документация:

    soundlib.init=function():boolean -- Инициализирует библиотеку. Возвращает, получилось ли это сделать.
    soundlib.deinit=function():boolean -- Тоже, что и init, но наоборот.
    soundlib.reinit=function() -- Выполняет deinit, а затем init.
    soundlib.process=function([interval:number]):boolean -- Проигрывает звук. Нужно выполнять эту функцию как можно чаще, или звук будет прерывистым. Задерживает программу примерно на interval или 10 мс. Рекомендуется ставить interval на 50. Возвращает, получилось ли это сделать.
    soundlib.newSound=function(size:number,delay:number):sound -- Создает объект звука с количеством сэмплов (кусочков звука), у каждого из которых длительность delay. Остается навсегда, если потерять его, не уничтожив с помощью sound:destroy()
    soundlib.getSoundCount():number -- Возвращает количество созданных не уничтоженных звуковых объектов
    
    sound:play()=function() -- Воспроизводит звук.
    sound:rewind()=function() -- Возвращает в начало звука
    sound:pause()=function() -- Приостанавливает звук
    sound:stop()=function() -- sound:rewind+sound:pause
    sound:setVolume(volume:number) -- Поставить звук, от 0 до math.huge. Настоящая громкость получается при volume 1.
    sound:getVolume():number -- Возвращает громкость звука.
    sound:setLooping(state:boolean)=function() -- Переключить повтор звука.
    sound:isLooping():boolean -- Возвращает, включен ли повтор.
    sound:getDuration():number -- Возвращает длительность звука в секундах.
    sound:seek():number -- Возвращает позицию воспроизведения в секундах.
    sound:setSeek(pos:number) -- Устанавливает позицию воспроизведения в секундах.
    sound:getCurrentSample():number -- Тоже, что и sound:seek, но в семплах (может быть дробным)
    sound:getSampleCount():number -- Возвращает size, который вы указали в soundlib.newSound
    sound:set(rawpos:number,wave:string,freq:number,vol:number) -- Ставит на сэмпле rawpos частоту freq с громкостью vol на типе волны wave
    sound:get(rawpos:number):number, number -- Возвращает частоту и громкость сэмпла rawpos
    
    
    
    

    Пример кода:

    print("Initialising.")
    local sound
    xpcall(function()
      local computer=require"computer"
      local term=require"term"
      local slib=require"soundlib"
      slib.reinit()
      print("Generating sound.")
      local sizesd=1000
      print("Selected size "..sizesd)
      sound=slib.newSound(sizesd,0.001)
      sound:setVolume(1)
      print("Generating samples")
      for n=0,sizesd-1 do
        sound:set(n,"sine",500,1-n/sizesd)
      end
      print("Playing sound.")
      sound:setLooping(true)
      sound:play()
      local n=computer.uptime()+10
      local c=0
      local prevcheck=computer.uptime()
      local processOk=true
      repeat
        processOk=slib.process(50) and processOk
        c=c+1
        if c>=50 then
          local t=computer.uptime()-prevcheck
          print(math.floor(50/t) .. " PPS, sound is "..(sound:isPlaying() and "playing" or "NOT playing")..", "..(processOk and "no errors" or "errored"))
          c=0
          processOk=true
          prevcheck=computer.uptime()
          pcall(os.sleep,0)
        end
      until computer.uptime() > n
      sound:stop() -- Необязательно т.к. он все равно не будет проигрываться
      sound:destroy() -- А вот это уже обязательно. Иначе при следующем запуске soundlib.process в любой программе, звук перемешается с нашим.
    end,function(err) if sound then sound:stop() sound:destroy() end print(debug.traceback(err,-2)) end)
    • Нравится 4

  5. Спустя этой просьбы прошёл почти год, когда я написал свой гайд по этой штуке в трёх частях с подробным объяснением. Больше мне не нужно ничего в этом топике, естественно.

     

    Ну и по коду: указание волны и процессинг нужно вынести из цикла, а ещё лучше будет заюзать треугольный FM-модулятор.

    Ой простите. Но, если вынести из цикла указание волны и процессинг, звук ведь совсем не такой выйдет?


  6. CarWar

    Здравствуйте уважаемые форумчане! Я сдалал давненько такую игру, теперь выкладываю ее сюда. В этой игре мы играем за машинок. Другие игроки тоже играют за машинок (игроки могут быть и ботами!). Вообщем вся суть в том, чтобы стрелять в другие машинки и ломать их. За это мы получаем очки. Когда мы зарабатываем достаточно очков, уровень повышается. А это нам увеличивает размер,скорострельность и урон который мы наносим. Нас конечно тоже могут поломать, так что надо быть осторожнее и держаться подальше от больших машинок.

     

    Скриншоты:

     

     

     

    tYJCoA7.png

     

     

    qOBD69x.png

     

    ppvM9Ef.png

     

     

     

    Скачать:

    CarWar.zip -  Windows и Android

    CarWar.love -  Linux

    • Нравится 2

  7. Вообщем повозился с вашей карточкой и вышло вот что:

    component.sound.open(1)
    -- Создаем очередь из частот и сразу обрабатываем
    for n=1,1000 do
      component.sound.setWave(1,component.sound.modes.sine)
      component.sound.setFrequency(1,n)
      component.sound.delay(1)
      component.sound.process()
    end
    -- Слушаем получившийся бульк и радуемся что все работает 
    

  8. Кстати, о законе.

     

    За гриферами (как и за вампирами) закрепился негативный смысл, и связано это с тем, что Майнкрафт является песочницей. Там игроки лепят куличики и строят домики. Понятно, что их печалит несанкционированная порча своих творений. Это, конечно, плохо.

     

    Но на индустриальном сервере, где всю нудную работу могут выполнить роботы и другие механизмы, утрата становится менее существенной. А при наличии полностью защищенной базы, сохраняющей всё самое ценное, некоторый запас роботов, инструментов и небольшое производство, потеря завода перестаёт быть трагедией, особенно, если учесть, как быстро окупают себя заводы в Майнкрафте. Если на сервере любая постройка может быть собрана и разобрана роботом, ресурсы для построек тоже добыты роботом, то и постройки и ресурсы перестают иметь решающую ценность. И, как говорит @qwertyMAN, ресурсы для грифера тоже вторичны. Первичен же сам процесс. И если процесс завязан на использование роботов, то такой процесс на computercraft.ru должен быть не только не запрещенным, но и поощряемым.

     

    Мне кажется, имеет смысл пересмотреть роль грифера на наших серверах. Понятно, что это не относится к PVP и сканированию или убийству игрока с помощью SGSC. Но грифер, льющий воду на мельницу Lua, достоин не наказания, а уважения.

    Согласен, такие гриферы заставляют игроков думать о защите и обороне, и это добавляет интерес и игре.


  9.   В мегабите, действительно - 125 килобайт. :)  Т.к. приставки : кило-, мега-, гига-, тера-, пета- ну и т.п., это всё - десятичные приставки. А у двоичной системы - есть свои. :smile44:

    Будем считать, что байт-8 бит, килобайт-1024 байт, мегабайт - 1024 килобайт, кто будет говорить кибибайт или мебибайт? Язык заплетается!


  10. Привет, подскажите пожалуйста как можно сделать задержку. То есть если условие верно, то ожидание 2 секунды затем выполнятся действие. Задержка не должна быть sleep. Задержка должна минимально нагружать CPU.

    ок. Не sleep? ихихихихихи. Ну тогда будет называтся wait:

    function wait(interval)
      local deadline = os.clock()+interval
      repeat
      until os.clock()>=deadline
    end
    

  11. просто только учусь делать проги для opencomp, и хочется разобраться что и для чего в коде, а не просто пользоваться готовым кодом.

    вот например, что не понимаю:

    1. куда писать имя таблицы, которую сохраняем?

    2.

     

    что делает каждая из этих строк?

    3.

     

    что это и зачем вызывать функцию загрузки?

     

    кароче, почти ничего из того кода не понял[

    1. Имя таблицы надо писать в функцию serialization.serialize(). Но в начале программы надо поставить serialization=require("serialization")

    2. Первая строка проверяет, является ли первый аргумент функции table.fromPath строкой. Вторая проверяет, есть ли файл. Дальше идет проверка, является ли файл папкой. Если да, выводит ошибку.

    3. Это чтение данных из файла и передача его в функцию десериализации (превращение строковых данных в таблицу). file - это хендлер файла, а :read - это читальщик файла - он читает данные из файла и возращает их. Можно дать ему числовой аргумент - и он прочитает столько, сколько указано прочитать. Если дать ему math.huge или "*a", он прочитает весь файл


  12. Жаль что не пашет(

    Что-то вы все не так делаете. У меня на интерпретаторе Lua 5.1 все норм пашет. В Lua 5.2 тоже должно - ведь работает же в OpenComputers такое, да? С Lua 5.3 тоже самое. 

     

    P. S. Теперь я понял. Оказывается, у меня тоже не работает. Хотя, можно это все обернуть в функцию:

    t={}
    pseudofunctionTable=setmetatable({},{__call=function(self,...) print("it works!",...) end})
    mt={__call=function(self,...) pseudofunctionTable(...) end}
    setmetatable(t,mt)
    t("and this is cool.")
    

  13. Да даже гугл не нужен особо, просто пишешь в консоли:

    вообщето я так пробовал, и не все функции пишутся! Так что никакой не PROFIT. Вот так надежней:

    /# lua
    bla-bla-bla Lua 5.2 bla-bla-bla PUC-Rio
    lua> for k,v in pairs(component.debug) do print("  ",tostring(k).."="..tostring(v)) end
    lua> print("PROFIT")
    
    • Нравится 1

  14. И довольно быстро упёрся в разные проблемы с этим: например, я хочу, не создавая инстанс класса, создать кастомный класс, чтобы заменить какую-то константу в исходном классе. Надо унаследоваться и заменить. У меня надо было таскать мета-таблицу, у тебя — прототип. А в той вкусной либе

    Та вкусная либа даже слишком вкусная! Притерная   :D. Надо опробовать. А может и нет.


  15. Если цикл бесконечный, то он в любом случае, даже если программа работает в однозадачном режиме, должен содержать os.sleep, event.pull или другую функцию, ожидающую событие. В противном случае компьютер отключится. Именно ожидание события и есть переключение между задачами. У меня, по крайней мере так.

    А что, если пройтись по синтаксису каждой программы, и поставить везде вызов такой функции?

    function nanoyield(...)
      coroutine.yield("no-event")
      return ...
    end
    

    Таким образом, код

    while true do
      var = io.open("file","r")
      s = var:read("*a")
      var:close()
    end 

    превратится примерно в

    while nanoyield(true) do nanoyield()
      var = nanoyield(io.open("file","r"))
      s = var:read("*a")
      nanoyield(var:close())
    end
       

    Таким образом, получится шедевральное распределение ресурсов процессора.

    А хост-программа будет обрабатывать "no-event" как пропуск передачи события в код потока. У каждого потока будет стек событий. Если все потоки вернули "no-event", то события и вовсе не будут проверяться, пока не пройдет таймер, и не придется взять событие, дабы избежать ошибок в системе.

    Вот это был бы шедевр...

    • Нравится 1

  16. Добро пожаловать на форум:

     

     

    55.jpg

     

     

     

    Даже порекламировать свои проги нельзя, сразу тапком кинут.

     

    Если ты это прочитал, значит ты читер.

    "Даже порекламировать свои проги нельзя, сразу тапком кинут.

     

     Если ты это прочитал, значит ты читер."

     

     

    я это прочитал и я не читер


  17. На minecraft-ru.gamepedia.com по-русски, но чтобы не надеяться на добрых людей, которым не лень делать перевод, то в GoogleChrome можно нажать ПКМ на странице и выбрать перевод на русский. А еще есть translate.ru, например.

    Фу ненавижу этих роботов-переводчиков. Они грамматику не знают. И не понимают ниче.


  18. легче создать proxy диска компьютера, который сам будет обращаться к другому компу и получать с него данные, а потом возвращать. потом через fs.mount смонтировать, или работать напрямую через прокси

    дадададададдадададада классная идея это надо будет изменить component.proxy к примеру чтобы если она получила "network" то тогда возвратила прокси сети компов с этой же прогой. Но это не все - ведь если резидентная программа будет только требовать файлы из сети - кто ей даст? Никто. Поэтому нужно сделать функцию распространения файликов к примеру через копирование файлов в папку "network/mf" ("network" - туда мы смонтируем сетевую FS) и выбрав загрузочную ФС для хранения сетевых файлов (т. е. в папке etc создать mf которая будет отображаться также и в прокси сетевой FS). Это будет шикарно если сделать. Суперская ФТП получится

×
×
  • Создать...