Advertisement
Guest User

Untitled

a guest
Nov 14th, 2013
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 18.28 KB | None | 0 0
  1. zones = {
  2.     [clsid.obj_climable]             = "net_alife_object_climable", -- CSE_ALifeObjectClimable
  3.     --
  4.     [clsid.script_zone]              = "net_alife_space_restrictor", -- CSE_ALifeSpaceRestrictor
  5.     [clsid.space_restrictor]         = "net_alife_space_restrictor", -- CSE_ALifeSpaceRestrictor
  6.     [clsid.script_restr]             = "net_alife_space_restrictor", -- CSE_ALifeSpaceRestrictor
  7.     --
  8.     [clsid.level_changer]            = "net_alife_level_changer", -- CSE_ALifeLevelChanger
  9.     --[clsid.team_base_zone]         = 4 -- CSE_ALifeTeamBaseZone
  10.     [clsid.smart_zone]               = "net_alife_smart_zone", -- CSE_ALifeSmartZone
  11.     [clsid.respawn]                  = "net_alife_smart_zone", -- CSE_ALifeSmartZone
  12.     [clsid.smart_terrain]            = "net_alife_smart_zone", -- CSE_ALifeSmartZone
  13.     [clsid.zone]                     = "net_alife_custom_zone", -- CSE_ALifeCustomZone
  14.     --
  15.     [clsid.torrid_zone]              = "net_alife_torrid_zone", -- CSE_ALifeTorridZone
  16.     [clsid.ameba_zone]               = "net_zone_anom", -- CSE_ALifeAnomalousZone
  17.     [clsid.nogravity_zone]           = "net_zone_anom", -- CSE_ALifeAnomalousZone
  18.     [clsid.zone_dead]                = "net_zone_anom", -- CSE_ALifeAnomalousZone
  19.     [clsid.zone_galantine]           = "net_zone_anom", -- CSE_ALifeAnomalousZone
  20.     [clsid.zone_mincer]              = "net_zone_anom", -- CSE_ALifeAnomalousZone
  21.     [clsid.zone_mosquito_bald]       = "net_zone_anom", -- CSE_ALifeAnomalousZone
  22.     [clsid.zone_radioactive]         = "net_zone_anom", -- CSE_ALifeAnomalousZone
  23.     [clsid.zone_acid_fog]            = "net_zone_anom", -- CSE_ALifeAnomalousZone
  24.     [clsid.zone_galant_s]            = "net_zone_anom", -- CSE_ALifeAnomalousZone
  25.     [clsid.zone_mbald_s]             = "net_zone_anom", -- CSE_ALifeAnomalousZone
  26.     [clsid.zone_mincer_s]            = "net_zone_anom", -- CSE_ALifeAnomalousZone
  27.     [clsid.zone_bfuzz]               = "net_zone_anom", -- CSE_ALifeZoneVisual
  28.     --[clsid.zone_campfire]          = true
  29.     [clsid.zone_rusty_hair]          = "net_alife_zone_visual", -- CSE_ALifeZoneVisual
  30.     [clsid.zone_bfuzz_s]             = "net_alife_zone_visual", -- CSE_ALifeZoneVisual
  31. }
  32. ----------------------------------------------------------------------------------------------------
  33. -- выделение из матрицы углов поворота в последовательности x,z,y
  34. -- подразумевается, что матрица является правильной матрицей поворота
  35. -- функция содрана из библиотеки Wild Magic 5
  36. function extract_euler_xzy(m)
  37.     if m.i.y < 1 then
  38.         if m.i.y > -1 then
  39.             local az = math.asin(-m.i.y)
  40.             local ax = math.atan2(m.k.y, m.j.y)
  41.             local ay = math.atan2(m.i.z, m.i.x)
  42.             return ax, az, ay
  43.         else
  44.             local az = math.pi / 2
  45.             local ax = -math.atan2(-m.k.x, m.k.z)
  46.             local ay = 0
  47.             return ax, az, ay
  48.         end
  49.     else
  50.         local az = -math.pi / 2
  51.         local ax = math.atan2(-m.k.x, m.k.z)
  52.         local ay = 0
  53.         return ax, az, ay
  54.     end
  55. end
  56. function rot_matrix_x(alpha)
  57.     local tr_matr = matrix():set(
  58.         vector():set(1,0,0),
  59.         vector():set(0,math.cos(alpha),-math.sin(alpha)),
  60.         vector():set(0,math.sin(alpha), math.cos(alpha)),
  61.         vector():set(0,0,0)
  62.     )
  63.     tr_matr._44_ = 1
  64.     return tr_matr
  65. end
  66. function rot_matrix_y(alpha)
  67.     local tr_matr = matrix():set(
  68.         vector():set( math.cos(alpha),0,math.sin(alpha)),
  69.         vector():set(0, 1,0),
  70.         vector():set(-math.sin(alpha),0,math.cos(alpha)),
  71.         vector():set(0,0,0)
  72.     )
  73.     tr_matr._44_ = 1
  74.     return tr_matr
  75. end
  76. function rot_matrix_z(alpha)
  77.     local tr_matr = matrix():set(
  78.         vector():set(math.cos(alpha),-math.sin(alpha),0),
  79.         vector():set(math.sin(alpha), math.cos(alpha),0),
  80.         vector():set(0,0,1),
  81.         vector():set(0,0,0)
  82.     )
  83.     tr_matr._44_ = 1
  84.     return tr_matr
  85. end
  86. function scale_matrix(x,y,z)
  87.     local tr_matr = matrix():set(
  88.         vector():set(x,0,0),
  89.         vector():set(0,y,0),
  90.         vector():set(0,0,z),
  91.         vector():set(0,0,0)
  92.     )
  93.     tr_matr._44_ = 1
  94.     return tr_matr
  95. end
  96. function shear_matrix(a01,a02,a12)
  97.     local sh_matr = matrix():set(
  98.         vector():set(1.0,a01,a02),
  99.         vector():set(0.0,1.0,a12),
  100.         vector():set(0.0,0.0,1.0),
  101.         vector():set(0,0,0)
  102.     )
  103.     sh_matr._44_ = 1
  104.     return sh_matr
  105. end
  106. function translation_matrix(x,y,z)
  107.     local tr_matr = matrix():set(
  108.         vector():set(1,0,0),
  109.         vector():set(0,1,0),
  110.         vector():set(0,0,1),
  111.         vector():set(x,y,z)
  112.     )
  113.     tr_matr._44_ = 1
  114.     return tr_matr
  115. end
  116. function make_euler_xzy(ax, az, ay)
  117.     local xmat = rot_matrix_x(ax)
  118.     local zmat = rot_matrix_z(az)
  119.     local ymat = rot_matrix_y(ay)
  120.  
  121.     --return matrix():mul_43(matrix():mul_43(ymat, zmat), xmat)
  122.     return mul_43(matrix(), mul_43(matrix(), ymat, zmat), xmat)
  123. end
  124.  
  125. function mul_43(res, m1, m2)
  126.     if res.mul_43 then
  127.         res:mul_43(m1, m2)
  128.     else
  129.         local res_00 = m1.j.x * m2.i.y + m1.k.x * m2.i.z + m1.i.x * m2.i.x;
  130.         local res_01 = m1.j.y * m2.i.y + m1.k.y * m2.i.z + m1.i.y * m2.i.x;
  131.         local res_02 = m1.j.z * m2.i.y + m1.k.z * m2.i.z + m1.i.z * m2.i.x;
  132.         --
  133.         local res_10 = m1.i.x * m2.j.x + m1.k.x * m2.j.z + m1.j.x * m2.j.y;
  134.         local res_11 = m1.k.y * m2.j.z + m1.j.y * m2.j.y + m1.i.y * m2.j.x;
  135.         local res_12 = m1.k.z * m2.j.z + m1.j.z * m2.j.y + m1.i.z * m2.j.x;
  136.         --
  137.         local res_20 = m1.i.x * m2.k.x + m1.k.x * m2.k.z + m1.j.x * m2.k.y;
  138.         local res_21 = m1.k.y * m2.k.z + m1.j.y * m2.k.y + m1.i.y * m2.k.x;
  139.         local res_22 = m1.k.z * m2.k.z + m1.j.z * m2.k.y + m1.i.z * m2.k.x;
  140.         --
  141.         local res_30 = m1.i.x * m2.c.x + m1.k.x * m2.c.z + m1.j.x * m2.c.y + m1.c.x;
  142.         local res_31 = m1.k.y * m2.c.z + m1.j.y * m2.c.y + m1.i.y * m2.c.x + m1.c.y;
  143.         local res_32 = m1.k.z * m2.c.z + m1.j.z * m2.c.y + m1.i.z * m2.c.x + m1.c.z;
  144.         --
  145.         res:set(
  146.             vector():set(res_00, res_01, res_02),
  147.             vector():set(res_10, res_11, res_12),
  148.             vector():set(res_20, res_21, res_22),
  149.             vector():set(res_30, res_31, res_32)
  150.             )
  151.         res._14_ = 0.0
  152.         res._24_ = 0.0
  153.         res._34_ = 0.0
  154.         res._44_ = 1.0
  155.     end
  156.     return res
  157. end
  158. --[[function mul_43(m1, m2)
  159.     return matrix():mul_43(m1, m2)
  160. end]]
  161. function transform_tiny(m, v)
  162.     local res = vector()
  163.     return transform_tiny_(m, res, v)
  164. end
  165. function transform_tiny_(m, res, v)
  166.     res.x = m.i.x * v.x + m.k.x * v.z + m.j.x * v.y + m.c.x;
  167.     res.y = m.k.y * v.z + m.j.y * v.y + m.i.y * v.x + m.c.y;
  168.     res.z = m.k.z * v.z + m.j.z * v.y + m.i.z * v.x + m.c.z;
  169.     return res
  170. end
  171. --[[function combine_transformations(transl, scale, rotation, shear)
  172.     return matrix():mul_43(
  173.         transl,
  174.         matrix():mul_43(
  175.             shear,
  176.             matrix():mul_43(rotation, scale)
  177.         )
  178.     )
  179. end]]
  180. function combine_transformations(transl, scale, rotation, shear)
  181.     return mul_43(
  182.         matrix(),
  183.         transl,
  184.         mul_43(
  185.             matrix(),
  186.             shear,
  187.             mul_43(
  188.                 matrix(),
  189.                 rotation,
  190.                 scale)
  191.         )
  192.     )
  193. end
  194.  
  195. --[[ функция выполняет декомпозицию исходной матрицы 'm' на матрицу масштабирования 'scale'
  196. -- и вращения 'rotation'. Подразумевается, что исходная матрица не содержит трансформации
  197. -- сдвига, поэтому сдвиговая матрица попросту выкидывается. Это допущение достаточно обосновано,
  198. -- поскольку в редакторе SDK нет возможности задавать сдвиг. Т.е. там нельзя сделать бокс
  199. -- не перпендикулярной формы. Если сдвиговые компоненты и возникают, то только как результат
  200. -- накопленных ошибок округления и их можно смело выкидывать. В любом случае, это справедливо для
  201. -- большинства традиционных зон: рестрикторов, смартов, переходов, аномалий и т.п.]]
  202. function decompose_matrix(m, offset, scale, rotation, shear)
  203.     offset:set(
  204.         vector():set(1,0,0),
  205.         vector():set(0,1,0),
  206.         vector():set(0,0,1),
  207.         m.c)
  208.     offset._44_ = 1.0
  209.     --
  210.     local sx = m.i:magnitude()
  211.     local sy = m.j:magnitude()
  212.     local sz = m.k:magnitude()
  213.     scale:set(
  214.         vector():set(sx,0,0),
  215.         vector():set(0,sy,0),
  216.         vector():set(0,0,sz),
  217.         vector())
  218.     scale._44_ = 1.0
  219.     rotation:set(
  220.         vector():set(m.i:div(sx)),
  221.         vector():set(m.j:div(sy)),
  222.         vector():set(m.k:div(sz)),
  223.         vector())
  224.     rotation._44_ = 1.0
  225.     shear:set(matrix():identity())
  226.    
  227.    
  228.     --[[do return end
  229.     local sc1, sc2, sc3, r11,r12,r13,r21,r22,r23,r31,r32,r33, sh12,sh13,sh23 = math.decompose_matrix(m.i.x, m.i.y, m.i.z, m.j.x, m.j.y, m.j.z, m.k.x, m.k.y, m.k.z)
  230.     scale:set(
  231.         vector():set(sc1,0,0),
  232.         vector():set(0,sc2,0),
  233.         vector():set(0,0,sc3),
  234.         vector())
  235.     scale._44_ = 1.0
  236.     rotation:set(
  237.         vector():set(r11,r12,r13),
  238.         vector():set(r21,r22,r23),
  239.         vector():set(r31,r32,r33),
  240.         vector())
  241.     rotation._44_ = 1.0
  242.     shear:set(
  243.         vector():set(1.0,sh12,sh13),
  244.         vector():set(0.0,1.0,sh23),
  245.         vector():set(0.0,0.0,1.0),
  246.         vector())
  247.     shear._44_ = 1.0]]
  248. end
  249. -- получение world-трансформации объекта
  250. function get_xform(cobj)
  251.     local xform = matrix()
  252.     if type(cobj.get_go_float) == "function" then
  253.         local a = {}
  254.         for i=0,15 do
  255.             a[i] = cobj:get_go_float(80 + i*4)
  256.         end
  257.         xform:set(
  258.             vector():set(a[0], a[1], a[2]),
  259.             vector():set(a[4], a[5], a[6]),
  260.             vector():set(a[8], a[9], a[10]),
  261.             vector():set(a[12], a[13], a[14])
  262.         )
  263.     else
  264.         xform:set(
  265.             vector():set(1, 0, 0),
  266.             vector():set(0, 1, 0),
  267.             vector():set(0, 0, 1),
  268.             cobj:position()
  269.         )
  270.     end
  271.     xform._14_ = 0
  272.     xform._24_ = 0
  273.     xform._34_ = 0
  274.     xform._44_ = 1
  275.     --print_matrix("xform", xform)
  276.     --print_vector("pos", cobj:position())
  277.     return xform
  278. end
  279.  
  280. function build_plane(arg1, arg2, arg3)
  281.     local d13 = vector():sub(arg3, arg1)
  282.     local d12 = vector():sub(arg2, arg1)
  283.     local plane = {}
  284.     plane.n = vector():crossproduct(d13, d12):normalize()
  285.     plane.d = - arg1:dotproduct(plane.n)
  286.     return plane
  287. end
  288. function inside_box(planes, point, radius)
  289.     for i,plane in ipairs(planes) do
  290.         -- плоскость задана нормалью и растоянием
  291.         if plane.n:dotproduct(point) < (radius - plane.d) then
  292.             return false
  293.         end
  294.     end
  295.     return true
  296. end
  297. function distance_from_shape_boundary(pos, shape, point)
  298.     --log1(type(shape))
  299.     if shape.t == shape_type.sphere then
  300.         --log1("sphere")
  301.         return (shape.r - vector():sub(vector():add(pos, shape.offset), point):magnitude())
  302.     elseif shape.t == shape_type.box then
  303.         local dist = math.huge
  304.         for _,plane in ipairs(shape.planes) do
  305.             -- плоскость задана нормалью и растоянием
  306.             local a = plane.n:dotproduct(point) + plane.d
  307.             if a < dist then
  308.                 dist = a
  309.             end
  310.         end
  311.         return dist
  312.     else
  313.         abort("")
  314.     end
  315. end
  316. function distance_from_zone_boundary(zone_data, point)
  317.     --log1("distance_from_zone_boundary")
  318.     --log1(type(shapes))
  319.     local dist = -math.huge
  320.     --log3("num=%d", #shapes)
  321.     for i,shape in ipairs(zone_data.shapes) do
  322.         --log3("i=%d", i)
  323.         local d = distance_from_shape_boundary(zone_data.xform.c, shape, point)
  324.         if d > dist then
  325.             dist = d
  326.         end
  327.     end
  328.     return dist
  329. end
  330. local base_box_vertices = {
  331.     vector():set(-.5, -.5, -.5),
  332.     vector():set(-.5, -.5,  .5),
  333.     vector():set(-.5,  .5,  .5),
  334.     vector():set(-.5,  .5, -.5),
  335.     vector():set( .5,  .5,  .5),
  336.     vector():set( .5,  .5, -.5),
  337.     vector():set( .5, -.5,  .5),
  338.     vector():set( .5, -.5, -.5),
  339. }
  340. function build_box_vertices(xformed_box_transformation)
  341.     --print_matrix("xformed_box_transformation", xformed_box_transformation)
  342.     local vertices = {}
  343.     for i,v in ipairs(base_box_vertices) do
  344.         vertices[i] = transform_tiny(xformed_box_transformation, v)
  345.     end
  346.     return vertices
  347. end
  348. --[[для онлайнового объекта, имеющего составной шейп, вернуть таблицу с полной информацией
  349. -- о его положении и каждом элементарном шейпе. Формат таблицы:
  350. -- {
  351. --     obj = <сам клиентский объект>, -- на всякий случай
  352. --     sobj = <серверный объект>,     -- тоже на всякий случай
  353. --     xform = <матрица глобальной трансформации объекта>,
  354. --            реально в этой матрице для объектов на уровне используется только трансформация
  355. --            смещения, т.е. компонент матрицы 'xform.c', который в сущности просто является
  356. --            вектором глобальных координат объекта
  357. --     shapes = { -- массив элементарных шейпов: боксов или сфер
  358. --         { -- формат сферы
  359. --             t = shape_type.sphere,
  360. --             offset = <центр сферы в виде объекта vector>,
  361. --             r = <радиус сферы>,
  362. --         },
  363. --         { -- формат бокса
  364. --             t = shape_type.box,
  365. --             m = <матрица трансформации>,
  366. --             -- v - это массив кординат вертексов бокса в виде объектов класса vector
  367. --             -- в целом бокс представляет собой исходно куб со стороной 1 игровой метр и центром
  368. --             -- в точке с координатами [0,0,0], подвергнутый последовательно двум трансформациям:
  369. --             -- 1. самого объекта (xform), что по-сути просто является сдвигом центра единичного
  370. --             --    куба в центр локальной системы координат объекта
  371. --             -- 2. локальной трансформации, описываемой матрицей m, которая может включать
  372. --             --    трансформации масштабирования (задаёт размеры бокса), вращения и
  373. --             --    дополнительного смещения центра бокса относительно начала локальной системы
  374. --             --    координат (или иными словами, относительно формального расположения
  375. --             --    объекта)
  376. --             -- ниже перечислены вершины и исходные вершины единичного куба,
  377. --             -- из которых они получены (порядок выбран произвольно, но от этого
  378. --             -- момента надо его соблюдать).
  379. --             v = {
  380. --                 [1] = ..., --[-.5, -.5, -.5],
  381. --                 [2] = ..., --[-.5, -.5,  .5],
  382. --                 [3] = ..., --[-.5,  .5,  .5],
  383. --                 [4] = ..., --[-.5,  .5, -.5],
  384. --                 [5] = ..., --[ .5,  .5,  .5],
  385. --                 [6] = ..., --[ .5,  .5, -.5],
  386. --                 [7] = ..., --[ .5, -.5,  .5],
  387. --                 [8] = ..., --[ .5, -.5, -.5],
  388. --             },
  389. --             -- Не забывайте обновлять этот список при изменении матрицы m! Для этого есть
  390. --             -- функция build_box_vertices
  391. --         },
  392. --     },
  393. -- }
  394. ]]
  395. function get_all_shapes_data(cobj)
  396.     --log1("get_all_shapes_data")
  397.     local data = {}
  398.     data.cobj = cobj
  399.     data.sobj = alife():object(cobj:id())
  400.     --log1("_-3")
  401.     local fun_name = zones[cobj:clsid()]
  402.     ASSERT(fun_name, "get_all_shapes_data: unknown zone type")
  403.     --log3("fun_name: %s", fun_name)
  404.     local pk = xs_netpk[fun_name](data.sobj)
  405.     --log1("_-1")
  406.     local row_data = pk:get()
  407.     --log1("1")
  408.     local shapes_row_data = row_data.shapes
  409.     local xform_orig = get_xform(cobj)
  410.     --print_matrix("xform_orig", xform_orig)
  411.     local xoffset = matrix()
  412.     local xscale = matrix()
  413.     local xrot = matrix()
  414.     local xshear = matrix()
  415.     --log1("2")
  416.     decompose_matrix(xform_orig, xoffset, xscale, xrot, xshear)
  417.     --print_matrix("xoffset", xoffset)
  418.     --print_matrix("xscale", xscale)
  419.     --print_matrix("xrot", xrot)
  420.     --print_matrix("xshear", xshear)
  421.     --log1("3")
  422.     local xform_comp = combine_transformations(matrix():identity(), xscale, xrot, xshear)
  423.     data.xform = xoffset
  424.     --
  425.     data.game_vertex_id = row_data.game_vertex_id
  426.     data.distance = row_data.distance
  427.     data.level_vertex_id = row_data.level_vertex_id
  428.    
  429.     data.shapes = {}
  430.     --log3("shapes_row_data:count = %d", shapes_row_data:count())
  431.     for k = 1, shapes_row_data:count() do
  432.         local shape = {}
  433.         data.shapes[k] = shape
  434.         local shp = shapes_row_data:get(k)
  435.         if shp:isSphere() then
  436.             shape.t = shape_type.sphere
  437.             shape.offset = shp.offset
  438.             shape.r = shp.r
  439.         else
  440.             shape.t = shape_type.box
  441.             local m = matrix():set(shp.box_matrix)
  442.             shape.m = mul_43(matrix(), xform_comp, m)
  443.             shape.v = build_box_vertices(mul_43(matrix(), data.xform, shape.m))
  444.             shape.planes = {}
  445.             shape.planes[1] = build_plane(shape.v[1],shape.v[4],shape.v[6])
  446.             shape.planes[2] = build_plane(shape.v[2],shape.v[3],shape.v[4])
  447.             shape.planes[3] = build_plane(shape.v[7],shape.v[6],shape.v[5])
  448.             shape.planes[4] = build_plane(shape.v[5],shape.v[3],shape.v[2])
  449.             shape.planes[5] = build_plane(shape.v[4],shape.v[3],shape.v[5])
  450.             shape.planes[6] = build_plane(shape.v[2],shape.v[1],shape.v[7])
  451.  
  452.             local offset = matrix()
  453.             local scale = matrix()
  454.             local rotation = matrix()
  455.             local shear = matrix()
  456.             decompose_matrix(shape.m, offset, scale, rotation, shear)
  457.             shape.a = {extract_euler_xzy(rotation)}
  458.             shape.offset = {offset.c.x, offset.c.y, offset.c.z}
  459.             shape.scale = {scale.i.x, scale.j.y, scale.k.z}
  460.             shape.shear = {shear.i.y, shear.i.z, shear.j.z}
  461.             --
  462.             --log1("----------------------------------------------------------------------------------")
  463.             --print_matrix("shape.m", shape.m)
  464.             --log1(string.format("ax=%f, az=%f, ay=%f", unpack(shape.a)))
  465.             --print_matrix("scale", scale)
  466.             --print_matrix("shear", shear)
  467.             --local a2 = make_euler_xzy(unpack(shape.a))
  468.             --print_matrix("rotation2", a2)
  469.             --print_matrix("sh2", shear_matrix(unpack(shape.shear)))
  470.             --local mm = get_shape_transformations(shape)
  471.             --print_matrix("mm", mm)
  472.             --local transl = translation_matrix(unpack(shape.offset))
  473.             --local m2 = combine_transformations(transl, scale, rotation, shear)
  474.             --print_matrix("m2", m2)
  475.         end
  476.     end
  477.     return data
  478. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement