PageRenderTime 44ms CodeModel.GetById 5ms RepoModel.GetById 1ms app.codeStats 0ms

/tools/jselect.lua

https://bitbucket.org/itraykov/boxy
Lua | 206 lines | 183 code | 17 blank | 6 comment | 37 complexity | 5085b14b11d616ac4fc74875fb8a7475 MD5 | raw file
  1. --
  2. -- Selects joints
  3. --
  4. JSelectTool = {}
  5. JSelectToolMT = { __index = JSelectTool }
  6. setmetatable(JSelectTool, { __index = Tool })
  7. function JSelectTool:Create(owner)
  8. local self = Tool:Create(owner, JSelectToolMT)
  9. return self
  10. end
  11. function JSelectTool:Destroy()
  12. Tool.Destroy(self)
  13. end
  14. function JSelectTool:MousePress(wx, wy, alt, shift, ctrl)
  15. local owner = self.owner
  16. local gstate = owner.gstate
  17. local scene = owner:get_scene()
  18. local selection = gstate.selection
  19. local selection2 = gstate.selection2
  20. local z = scene:GetZoom()
  21. local j, b = gstate:QueryAnchors(selection2, wx, wy, 5*z)
  22. if #j > 0 then
  23. owner:set_tool(AnchorTool, wx, wy, j[1], b[1])
  24. return
  25. end
  26. local q, j = gstate:QueryJoints(wx, wy, wx, wy, 5*z)
  27. if #q > 0 and alt == false and shift == false then
  28. local i = table.find(selection, q[1])
  29. if i then
  30. gstate:ShiftSelection(i, 1)
  31. else
  32. gstate:ClearSelection()
  33. gstate:AddToSelection({ q[1] }, { j[1] })
  34. end
  35. owner:set_tool(JTranslateTool, selection, selection2)
  36. owner.tool:MousePress(wx, wy, alt, shift)
  37. else
  38. self.alt, self.shift = alt, shift
  39. self.sx, self.sy = wx, wy
  40. if alt == true or shift == true then
  41. self.oldselect = { unpack(gstate.selection) }
  42. self.oldselect2 = { unpack(gstate.selection2) }
  43. else
  44. gstate:ClearSelection()
  45. end
  46. end
  47. end
  48. function JSelectTool:MouseMove(wx, wy, owx, owy)
  49. local sx, sy = self.sx, self.sy
  50. if sx == nil or sy == nil then
  51. return
  52. end
  53. local scene = self.owner:get_scene()
  54. local gstate = self.owner.gstate
  55. self.ex, self.ey = wx, wy
  56. local z = scene:GetZoom()
  57. local q, s = gstate:QueryJoints(sx, sy, wx, wy, z*4)
  58. gstate:ClearSelection()
  59. if self.oldselect then
  60. gstate:AddToSelection(self.oldselect, self.oldselect2)
  61. end
  62. if self.alt == true then
  63. gstate:RemoveFromSelection(q, s)
  64. else
  65. gstate:AddToSelection(q, s)
  66. end
  67. end
  68. function JSelectTool:MouseRelease(wx, wy)
  69. self:MouseMove(wx, wy, wx, wy)
  70. self.alt, self.shift = nil, nil
  71. self.sx, self.sy = nil, nil
  72. self.ex, self.ey = nil, nil
  73. self.oldselect = nil
  74. self.oldselect2 = nil
  75. end
  76. function JSelectTool:Redraw(dt)
  77. local owner = self.owner
  78. local gstate = owner.gstate
  79. local scene = owner:get_scene()
  80. local camera = owner:get_camera()
  81. if self.ex and self.ey then
  82. local sx, sy = self.sx, self.sy
  83. local ex, ey = self.ex, self.ey
  84. scene:DrawLine(sx, sy, sx, ey, 1, WHITE, 1)
  85. scene:DrawLine(sx, ey, ex, ey, 1, WHITE, 1)
  86. scene:DrawLine(ex, ey, ex, sy, 1, WHITE, 1)
  87. scene:DrawLine(ex, sy, sx, sy, 1, WHITE, 1)
  88. scene:DrawStatus("Selecting joints (shift/alt to modify)")
  89. return
  90. end
  91. self:RedrawAnchors()
  92. local z = scene:GetZoom()
  93. local mx, my = mouse.xaxis, mouse.yaxis
  94. local wx, wy = camera:get_world_point(mx, my)
  95. if #gstate.selection > 0 then
  96. local f = "%d joint controls selected"
  97. local sz = string.format(f, #gstate.selection)
  98. scene:DrawStatus(sz)
  99. local j, b = gstate:QueryAnchors(gstate.selection2, wx, wy, 4*z)
  100. if #j > 0 then
  101. local f = "Anchor\n body:%d "
  102. local sz = string.format(f, b[1].id)
  103. scene:DrawTooltip(sz, wx, wy)
  104. end
  105. else
  106. scene:DrawStatus("Edit joints")
  107. local v, j = gstate:QueryJoints(wx, wy, wx, wy, 4*z)
  108. v = v[1]
  109. j = j[1]
  110. if v then
  111. local t = j:GetType()
  112. local sz
  113. if t == 'revolute' then
  114. if j:IsLimitEnabled() then
  115. local l = j:GetLowerLimit()
  116. local u = j:GetUpperLimit()
  117. sz = string.format("\n limits:%g, %g ", l, u)
  118. end
  119. elseif t == 'distance' then
  120. local len = j.def.length
  121. sz = string.format("\n length:%g ", len)
  122. elseif t == 'rope' then
  123. local len = j.def.maxLength
  124. sz = string.format("\n maxLength:%g ", len)
  125. elseif t == 'prismatic' then
  126. local ax, ay = j:GetWorldAxis()
  127. sz = string.format("\n axis:%g, %g", ax, ay)
  128. if j:IsLimitEnabled() then
  129. local l = j:GetLowerLimit()
  130. local u = j:GetUpperLimit()
  131. sz = sz .. string.format(" \n limits:%g, %g ", l, u)
  132. end
  133. elseif t == 'gear' then
  134. local j1 = j:GetJoint1().id
  135. local j2 = j:GetJoint2().id
  136. sz = string.format("\n joint1:%g \n joint2:%g", j1, j2)
  137. end
  138. sz = sz or ""
  139. local x, y = j.def.body1:GetWorldPoint(v.x, v.y)
  140. local cc = "false"
  141. if j.def.collideConnected == true then
  142. cc = "true"
  143. end
  144. local f = "Joint \n id:%d \n type:%s \n x:%g \n y:%g \n body1:%d \n body2:%d \n collideconnected: %s %s "
  145. local sz = string.format(f, j.id, t, x, y, j.def.body1.id, j.def.body2.id, cc, sz)
  146. scene:DrawTooltip(sz, wx, wy)
  147. end
  148. end
  149. end
  150. function JSelectTool:RedrawAnchors()
  151. local owner = self.owner
  152. local world = owner:get_world()
  153. local scene = owner:get_scene()
  154. local gstate = owner.gstate
  155. for i, anchor in ipairs(gstate.selection) do
  156. local joint = gstate.selection2[i]
  157. local b1, b2 = joint.def.body1, joint.def.body2
  158. if anchor == joint.def.localAnchor2 then
  159. b1, b2 = b2, b1
  160. end
  161. local wvx, wvy = anchor.x, anchor.y
  162. if anchor == joint.def.localAnchor1 or anchor == joint.def.localAnchor2 then
  163. wvx, wvy = b1:GetWorldPoint(anchor.x, anchor.y)
  164. end
  165. -- draw lines from the joint to the attached bodies
  166. local cm1x, cm1y = b1:GetWorldCenter()
  167. local z = scene:GetZoom()
  168. local dx, dy = (cm1x - wvx)/2, (cm1y - wvy)/2
  169. local cx, cy = wvx + dx, wvy + dy
  170. scene:DrawLine(wvx, wvy, cm1x, cm1y, 1, DARKORANGE, 1)
  171. --scene:DrawLine(cx, cy, cx + dy, cy - dx, 1, RED, 1)
  172. --scene:DrawCurve(wvx, wvy, cm1x, cm1y, cx + dy, cy - dx, 1, DARKORANGE, 1)
  173. scene:DrawImage("circle", cm1x, cm1y)
  174. local ox, oy = -9*z, -9*z
  175. local a, b = 1, 2
  176. if anchor == joint.def.localAnchor2 then
  177. ox = -ox
  178. a, b = b, a
  179. end
  180. scene:DrawImage("anchor" .. a, cm1x + ox, cm1y + oy)
  181. local type = joint:GetType()
  182. if type ~= 'distance' and type ~= 'prismatic' and type ~= 'rope' then
  183. local cm2x, cm2y = b2:GetWorldCenter()
  184. scene:DrawLine(wvx, wvy, cm2x, cm2y, 1, DARKORANGE, 1)
  185. scene:DrawImage("circle", cm2x, cm2y)
  186. scene:DrawImage("anchor" .. b, cm2x - ox, cm2y + oy)
  187. end
  188. end
  189. end