--[[Glass3D, Copyright 2016 Trientalis
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
(Это свободная программа: вы можете перераспространять ее и/или изменять
ее на условиях Стандартной общественной лицензии GNU в том виде, в каком
она была опубликована Фондом свободного программного обеспечения; либо
версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она будет полезной,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
.)]]
--Как-то, так :)
local bufferPolygons={}
local groups={{isPrimal=true,indexes={}}}
local polygons={}
local vertices={}
local lib={}
local stage=require("component").openperipheral_bridge
local focalLenght=100
local function removeElementFromTable(element,t)
for i=1,#t do
if(t[i]==element)then
table.remove(t,i)
return t,element
end
end
end
local function to2D(vertex)
local s=focalLenght/(focalLenght-vertex.z)
return vertex.x*s,vertex.y*s
end
function lib.addVertices3D(vertexList)--lib.addVertices3D({x1,y1,z1,x2,y2,z2...})
local result={}
for i=1,#vertexList,3 do
table.insert(result,lib.addVertex3D(vertexList[i],vertexList[i+1],vertexList[i+2]))
end
return result
end
function lib.addVertex3D(x,y,z,h)
local index=#vertices+1
vertices[index]={x=x,y=y,z=z,h=h or 1}
table.insert(groups[1].indexes,index)
vertices[index].group=groups[1]
return index
end
function lib.removeVertex3D(index)
vertices[index]=nil
end
function lib.addPolygon3D(vertexList,fill)--lib.addPolygon3D({v1,v2,v3},{color=0xffffff,opacity=1 or nil})
table.sort(vertexList)
local name=""..vertexList[1].."_"..vertexList[2].."_"..vertexList[3]
if(polygons[name])then return "polygon alrady created" end
polygons[name]={}
local object=polygons[name]
object.name=name
object.vertexList=vertexList
object.fill=fill
table.insert(bufferPolygons,object)
return name
end
function lib.removePolygon3D(name)
removeElementFromTable(polygons[name],bufferPolygons)
polygons[name]=nil
end
local function removeFromGroup(index,group)
removeElementFromTable(index,group)
vertices[index].group=groups[1]
end
function lib.transform(vertexIndexList,matrix)--lib.transform({v1,v2,v3,...},{numbers...}) #matrix==16
local groupList={}
for i=1,#vertexIndexList do
local index=vertexIndexList[i]
local group=vertices[index].group
groupList[group]=groupList[group] or {}
groupList[group].indexes=groupList[group].indexes or {}
table.insert(groupList[group].indexes,index)
if(not groupList[group].matrix)then
if(group.matrix)then
local result={};
for i=1,4 do
for j=1,4 do
result[i+4*(j-1)] = 0.0;
for k=1,4 do
result[i+4*(j-1)] = result[i+4*(j-1)]+group.matrix[i+(k-1)*4]*matrix[k+4*(j-1)]
end
end
end
groupList[group].matrix=result
else
groupList[group].matrix=matrix
end
end
removeFromGroup(vertexIndexList[i],group)
if(#group.indexes==0 and not group.isPrimal)then removeElementFromTable(groups,group) end
vertices[index].group=groupList[group]
table.insert(groups,groupList[group])
end
end
function lib.update()
stage.clear()
for i=1,#groups do
local group=groups[i]
local matrix=group.matrix
if(matrix)then
for i=1,#group.indexes do--Применяем матрицы
local vertex=vertices[group.indexes[i]]
local x=matrix[1]*vertex.x+matrix[2]*vertex.y+matrix[3]*vertex.z+matrix[4]*vertex.h
local y=matrix[5]*vertex.x+matrix[6]*vertex.y+matrix[7]*vertex.z+matrix[8]*vertex.h
local z=matrix[9]*vertex.x+matrix[10]*vertex.y+matrix[11]*vertex.z+matrix[12]*vertex.h
local h=matrix[13]*vertex.x+matrix[14]*vertex.y+matrix[15]*vertex.z+matrix[16]*vertex.h
vertex.x=x*h
vertex.y=y*h
vertex.z=z*h
vertex.h=1
removeFromGroup(group.indexes[i],group)
vertex.group=groups[1]
end
end
end
local depthArray={}--Z-сортировка, она не обработает полигоны попиксельно, но сгодится для непересекающихся
for j=1,#bufferPolygons do
local depth=0
local vertexList=bufferPolygons[j].vertexList
for i=1,3 do
depth=depth+vertices[vertexList[i]].z
end
table.insert(depthArray,{bufferPolygons[j],depth})
end
table.sort(depthArray,function(a,b)return a[2]>b[2] end)
for j=1,#depthArray do
local x1,y1=to2D(vertices[depthArray[j][1].vertexList[1]])
local x2,y2=to2D(vertices[depthArray[j][1].vertexList[2]])
local x3,y3=to2D(vertices[depthArray[j][1].vertexList[3]])
local fill=depthArray[j][1].fill
local polygon=stage.addPolygon(fill.color,fill.opacity or 1,{x=x1,y=y1},{x=x2,y=y2},{x=x3,y=y3})
polygon.setScreenAnchor("MIDDLE","MIDDLE")
end
stage.sync()
end
function lib.setFocalLenght(newFocalLenght)--Расстояние от глаза до экрана
focalLenght=newFocalLenght
return focalLenght
end
function lib.getFocalLenght()
return focalLenght
end
return lib