Ticket #768: dbg_camera_smooth_move.lua

File dbg_camera_smooth_move.lua, 6.3 KB (added by beherith, 7 years ago)

Heres is a nice slow, smooth camera panning widget. Click and hold middle mouse button to use. Must be enabled in f11 menu.

Line 
1--------------------------------------------------------------------------------
2--------------------------------------------------------------------------------
3--
4-- file: camera_smooth_scroll.lua
5-- brief: Alternate camera scrolling for the middle mouse button
6-- author: Dave Rodgers
7--
8-- Copyright (C) 2007.
9-- Licensed under the terms of the GNU GPL, v2 or later.
10--
11--------------------------------------------------------------------------------
12--------------------------------------------------------------------------------
13
14function widget:GetInfo()
15 return {
16 name = "dbg_camera_smooth_move for sereiya",
17 desc = "Alternate view movement for the middle mouse button",
18 author = "trepan,beherith",
19 date = "Feb 27, 2007",
20 license = "GNU GPL, v2 or later",
21 layer = 1, -- after the normal widgets
22 enabled = false -- loaded by default?
23 }
24end
25
26--------------------------------------------------------------------------------
27--------------------------------------------------------------------------------
28
29-- Automatically generated local definitions
30
31local GL_LINES = GL.LINES
32local GL_POINTS = GL.POINTS
33
34local glBeginEnd = gl.BeginEnd
35local glColor = gl.Color
36local glLineWidth = gl.LineWidth
37local glPointSize = gl.PointSize
38local glVertex = gl.Vertex
39
40local spGetCameraState = Spring.GetCameraState
41local spGetCameraVectors = Spring.GetCameraVectors
42local spGetModKeyState = Spring.GetModKeyState
43local spGetMouseState = Spring.GetMouseState
44local spIsAboveMiniMap = Spring.IsAboveMiniMap
45local spSendCommands = Spring.SendCommands
46local spSetCameraState = Spring.SetCameraState
47local spSetMouseCursor = Spring.SetMouseCursor
48local spTraceScreenRay = Spring.TraceScreenRay
49local spWarpMouse = Spring.WarpMouse
50
51
52--------------------------------------------------------------------------------
53--------------------------------------------------------------------------------
54--
55-- NOTES:
56--
57-- 1. The GetCameraState() table is supposed to be opaque.
58--
59
60local blockModeSwitching = false
61
62
63local vsx, vsy = widgetHandler:GetViewSizes()
64function widget:ViewResize(viewSizeX, viewSizeY)
65 vsx = viewSizeX
66 vsy = viewSizeY
67end
68
69
70local decayFactor = 1
71local speedFactor = 0.33
72
73local mx, my
74local active = false
75
76
77--------------------------------------------------------------------------------
78
79function widget:Update(dt)
80 if (active) then
81 local x, y, lmb, mmb, rmb = spGetMouseState()
82 local cs = spGetCameraState()
83 local speed = dt * speedFactor
84
85 if (cs.name == 'free') then
86 local a,c,m,s = spGetModKeyState()
87 if (c) then
88 return
89 end
90 -- clear the velocities
91 cs.vx = 0; cs.vy = 0; cs.vz = 0
92 cs.avx = 0; cs.avy = 0; cs.avz = 0
93 end
94 if (cs.name == 'ta') then
95 local flip = -cs.flipped
96 -- simple, forward and right are locked
97 cs.px = cs.px + (speed * flip * (x - mx))
98 if (false) then
99 cs.py = cs.py + (speed * flip * (my - y))
100 else
101 cs.pz = cs.pz + (speed * flip * (my - y))
102 end
103 else
104 -- forward, up, right, top, bottom, left, right
105 local camVecs = spGetCameraVectors()
106 local cf = camVecs.forward
107 local len = math.sqrt((cf[1] * cf[1]) + (cf[3] * cf[3]))
108 local dfx = cf[1] / len
109 local dfz = cf[3] / len
110 local cr = camVecs.right
111 local len = math.sqrt((cr[1] * cr[1]) + (cr[3] * cr[3]))
112 local drx = cr[1] / len
113 local drz = cr[3] / len
114 local mxm = (speed * (x - mx))
115 local mym = (speed * (y - my))
116 cs.px = cs.px + (mxm * drx) + (mym * dfx)
117 cs.pz = cs.pz + (mxm * drz) + (mym * dfz)
118 end
119
120 spSetCameraState(cs, 0)
121
122 if (mmb) then
123 spSetMouseCursor('none')
124 end
125 end
126end
127
128
129function widget:MousePress(x, y, button)
130 --Spring.Echo('mousepress',x,y,button)
131 if (button ~= 2) then
132 return false
133 end
134 if (spIsAboveMiniMap(x, y)) then
135 return false
136 end
137 local cs = spGetCameraState()
138 if (blockModeSwitching and (cs.name ~= 'ta') and (cs.name ~= 'free')) then
139 local a,c,m,s = spGetModKeyState()
140 return (c or s) -- block the mode toggling
141 end
142 if (cs.name == 'free') then
143 local a,c,m,s = spGetModKeyState()
144 if (m and (not (c or s))) then
145 return false
146 end
147 end
148 active = not active
149 if (active) then
150 mx = vsx * 0.5
151 my = vsy * 0.5
152 spWarpMouse(mx, my)
153 spSendCommands({'trackoff'})
154 end
155 return true
156end
157
158
159function widget:MouseRelease(x, y, button)
160 active = false
161 return -1
162end
163
164
165-- FIXME -- this algo could still use some lovin'
166function widget:MouseWheel(up, value)
167 local cs = spGetCameraState()
168 local a,c,m,s = spGetModKeyState()
169 if (m) then
170 local py = math.abs(cs.py)
171 local dy = (1 + math.pow(py * 100, 0.25)) * (up and -1 or 1)
172 local dy = (py / 10) * (up and -1 or 1)
173 print(dy)
174 spSetCameraState({
175 py = py + dy,
176 }, 0)
177 return true
178 end
179 if (cs.name ~= 'free') then
180 return false
181 end
182 local scale = value * 10
183 local mx, my = spGetMouseState()
184 local _, gpos = spTraceScreenRay(mx, my, true)
185 if (not gpos) then
186 spSetCameraState({ vy = cs.vy + scale}, 0)
187 else
188 local dx = gpos[1] - cs.px
189 local dy = gpos[2] - cs.py
190 local dz = gpos[3] - cs.pz
191 local d = math.sqrt((dx * dx) + (dy * dy) + (dz * dz))
192 local s = (up and 1 or -1) * (1 / 8)
193
194 dx = dx * s
195 dy = dy * s
196 dz = dz * s
197 local newCS = {
198 px = cs.px + dx,
199 py = cs.py + dy,
200 pz = cs.pz + dz,
201 vx = 0,
202 vy = 0,
203 vz = 0,
204 }
205 spSetCameraState(newCS, 0)
206 end
207 return true
208end
209
210
211local function DrawPoint(x, y, c, s)
212 glPointSize(s)
213 glColor(c)
214 glBeginEnd(GL_POINTS, glVertex, x, y)
215end
216
217
218local function DrawLine(x0, y0, c0, x1, y1, c1)
219 glColor(c0); glVertex(x0, y0)
220 glColor(c1); glVertex(x1, y1)
221end
222
223
224local red = { 1, 0, 0 }
225local green = { 0, 1, 0 }
226local black = { 0, 0, 0 }
227local white = { 1, 1, 1 }
228
229
230function widget:DrawScreen()
231 if true then return end
232 if (active) then
233 local x, y = spGetMouseState()
234
235 DrawPoint(mx, my, black, 14)
236 DrawPoint(mx, my, white, 11)
237 DrawPoint(mx, my, black, 8)
238 DrawPoint(mx, my, red, 5)
239
240 glLineWidth(2)
241 glBeginEnd(GL_LINES, DrawLine, x, y, green, mx, my, red)
242 glLineWidth(1)
243
244 DrawPoint(x, y, { 0, 1, 0 }, 5)
245
246 glPointSize(1)
247 end
248end
249
250
251--------------------------------------------------------------------------------
252