Skip to content

Commit cf99318

Browse files
committed
Add camera
1 parent a442fc4 commit cf99318

5 files changed

Lines changed: 325 additions & 31 deletions

File tree

graphics/neurons/camera.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include <bx/uint32_t.h>
2+
#include <bx/timer.h>
3+
#include <bx/math.h>
4+
#include <bgfx/bgfx.h>
5+
#include <bx/bx.h>
6+
#include <bx/filepath.h>
7+
#include <bx/string.h>
8+
9+
struct Camera
10+
{
11+
Camera()
12+
{
13+
reset();
14+
}
15+
16+
void reset()
17+
{
18+
m_target.curr = { 0.0f, 0.0f, 0.0f };
19+
m_target.dest = { 0.0f, 0.0f, 0.0f };
20+
21+
m_pos.curr = { 0.0f, 0.0f, -3.0f };
22+
m_pos.dest = { 0.0f, 0.0f, -3.0f };
23+
24+
m_orbit[0] = 0.0f;
25+
m_orbit[1] = 0.0f;
26+
}
27+
28+
void mtxLookAt(float* _outViewMtx)
29+
{
30+
bx::mtxLookAt(_outViewMtx, m_pos.curr, m_target.curr);
31+
}
32+
33+
void orbit(float _dx, float _dy)
34+
{
35+
m_orbit[0] += _dx;
36+
m_orbit[1] += _dy;
37+
}
38+
39+
void dolly(float _dz)
40+
{
41+
const float cnear = 1.0f;
42+
const float cfar = 100.0f;
43+
44+
const bx::Vec3 toTarget = bx::sub(m_target.dest, m_pos.dest);
45+
const float toTargetLen = bx::length(toTarget);
46+
const float invToTargetLen = 1.0f / (toTargetLen + bx::kFloatSmallest);
47+
const bx::Vec3 toTargetNorm = bx::mul(toTarget, invToTargetLen);
48+
49+
float delta = toTargetLen * _dz;
50+
float newLen = toTargetLen + delta;
51+
if ( (cnear < newLen || _dz < 0.0f)
52+
&& (newLen < cfar || _dz > 0.0f) )
53+
{
54+
m_pos.dest = bx::mad(toTargetNorm, delta, m_pos.dest);
55+
}
56+
}
57+
58+
void consumeOrbit(float _amount)
59+
{
60+
float consume[2];
61+
consume[0] = m_orbit[0] * _amount;
62+
consume[1] = m_orbit[1] * _amount;
63+
m_orbit[0] -= consume[0];
64+
m_orbit[1] -= consume[1];
65+
66+
const bx::Vec3 toPos = bx::sub(m_pos.curr, m_target.curr);
67+
const float toPosLen = bx::length(toPos);
68+
const float invToPosLen = 1.0f / (toPosLen + bx::kFloatSmallest);
69+
const bx::Vec3 toPosNorm = bx::mul(toPos, invToPosLen);
70+
71+
float ll[2];
72+
bx::toLatLong(&ll[0], &ll[1], toPosNorm);
73+
ll[0] += consume[0];
74+
ll[1] -= consume[1];
75+
ll[1] = bx::clamp(ll[1], 0.02f, 0.98f);
76+
77+
const bx::Vec3 tmp = bx::fromLatLong(ll[0], ll[1]);
78+
const bx::Vec3 diff = bx::mul(bx::sub(tmp, toPosNorm), toPosLen);
79+
80+
m_pos.curr = bx::add(m_pos.curr, diff);
81+
m_pos.dest = bx::add(m_pos.dest, diff);
82+
}
83+
84+
void update(float _dt)
85+
{
86+
const float amount = bx::min(_dt / 0.12f, 1.0f);
87+
88+
consumeOrbit(amount);
89+
90+
m_target.curr = bx::lerp(m_target.curr, m_target.dest, amount);
91+
m_pos.curr = bx::lerp(m_pos.curr, m_pos.dest, amount);
92+
}
93+
94+
void envViewMtx(float* _mtx)
95+
{
96+
const bx::Vec3 toTarget = bx::sub(m_target.curr, m_pos.curr);
97+
const float toTargetLen = bx::length(toTarget);
98+
const float invToTargetLen = 1.0f / (toTargetLen + bx::kFloatSmallest);
99+
const bx::Vec3 toTargetNorm = bx::mul(toTarget, invToTargetLen);
100+
101+
const bx::Vec3 right = bx::normalize(bx::cross({ 0.0f, 1.0f, 0.0f }, toTargetNorm) );
102+
const bx::Vec3 up = bx::normalize(bx::cross(toTargetNorm, right) );
103+
104+
_mtx[ 0] = right.x;
105+
_mtx[ 1] = right.y;
106+
_mtx[ 2] = right.z;
107+
_mtx[ 3] = 0.0f;
108+
_mtx[ 4] = up.x;
109+
_mtx[ 5] = up.y;
110+
_mtx[ 6] = up.z;
111+
_mtx[ 7] = 0.0f;
112+
_mtx[ 8] = toTargetNorm.x;
113+
_mtx[ 9] = toTargetNorm.y;
114+
_mtx[10] = toTargetNorm.z;
115+
_mtx[11] = 0.0f;
116+
_mtx[12] = 0.0f;
117+
_mtx[13] = 0.0f;
118+
_mtx[14] = 0.0f;
119+
_mtx[15] = 1.0f;
120+
}
121+
122+
struct Interp3f
123+
{
124+
bx::Vec3 curr = bx::InitNone;
125+
bx::Vec3 dest = bx::InitNone;
126+
};
127+
128+
Interp3f m_target;
129+
Interp3f m_pos;
130+
float m_orbit[2];
131+
};

graphics/neurons/mouse.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include <stdint.h>
2+
3+
struct Mouse
4+
{
5+
Mouse()
6+
: m_dx(0.0f)
7+
, m_dy(0.0f)
8+
, m_prevMx(0.0f)
9+
, m_prevMy(0.0f)
10+
, m_scroll(0)
11+
, m_scrollPrev(0)
12+
{
13+
}
14+
15+
void update(float _mx, float _my, int32_t _mz, uint32_t _width, uint32_t _height)
16+
{
17+
const float widthf = float(int32_t(_width));
18+
const float heightf = float(int32_t(_height));
19+
20+
// Delta movement.
21+
m_dx = float(_mx - m_prevMx)/widthf;
22+
m_dy = float(_my - m_prevMy)/heightf;
23+
24+
m_prevMx = _mx;
25+
m_prevMy = _my;
26+
27+
// Scroll.
28+
m_scroll = _mz - m_scrollPrev;
29+
m_scrollPrev = _mz;
30+
}
31+
32+
float m_dx; // Screen space.
33+
float m_dy;
34+
float m_prevMx;
35+
float m_prevMy;
36+
int32_t m_scroll;
37+
int32_t m_scrollPrev;
38+
};

graphics/neurons/network.hpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ struct Network {
3030

3131
void step(uint8_t input[784]) {
3232

33-
for (size_t i = 0; i < 784; i++)
34-
{
35-
if (input[i] > 0) {
36-
neurons[i].v += 1.5f * (input[i] / 255.0f) * 0.2f; // inject current to neuron 0
37-
}
38-
}
33+
// for (size_t i = 0; i < 784; i++)
34+
// {
35+
// if (input[i] > 0) {
36+
// neurons[i].v += 1.5f * (input[i] / 255.0f) * 0.2f; // inject current to neuron 0
37+
// }
38+
// }
3939

4040
std::vector<float> inputs(neurons.size(), 0.0f);
4141

graphics/neurons/neurons_gui.cpp

Lines changed: 91 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
#include "render/neuron_render.hpp"
2020
#include "render/network_render.hpp"
2121

22+
#include "camera.cpp"
23+
#include "mouse.cpp"
24+
#include "settings.cpp"
25+
2226
// TODO:
2327
// ImGui different look
2428
// https://github.com/GraphicsProgramming/dear-imgui-styles
@@ -65,7 +69,7 @@ namespace
6569
: entry::AppI("NEUF", "spiking network simulator", "")
6670
{
6771
// TODO: data dimensions should come from MnistData
68-
const uint32_t width = 28, height = 28;
72+
const uint32_t width = 8, height = 8;
6973

7074
net.setSize(width * height);
7175
auto ctx = std::make_shared<NetworkVisualContext>(net);
@@ -189,7 +193,13 @@ namespace
189193
// Check if instancing is supported.
190194
const bool instancingSupported = 0 != (BGFX_CAPS_INSTANCING & caps->supported);
191195

192-
float time = (float)((bx::getHPCounter() - m_timeOffset) / double(bx::getHPFrequency()));
196+
int64_t now = bx::getHPCounter();
197+
static int64_t last = now;
198+
const int64_t frameTime = now - last;
199+
last = now;
200+
const double freq = double(bx::getHPFrequency());
201+
float time = (float)((now - m_timeOffset) / freq);
202+
const float deltaTimeSec = float(double(frameTime)/freq);
193203

194204
ImGui::Text("Time %.2f", time);
195205

@@ -214,38 +224,89 @@ namespace
214224

215225
imguiEndFrame();
216226

217-
// Set view 0 default viewport.
218-
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
219-
220-
// This dummy draw call is here to make sure that view 0 is cleared
221-
// if no other draw calls are submitted to view 0.
222-
bgfx::touch(0);
223-
224-
225-
226-
// if (!instancingSupported)
227227
// {
228-
// // When instancing is not supported by GPU, implement alternative
229-
// // code path that doesn't use instancing.
230-
// bool blink = uint32_t(time * 3.0f) & 1;
231-
// bgfx::dbgTextPrintf(0, 0, blink ? 0x4f : 0x04, " Instancing is not supported by GPU. ");
232-
228+
// // Set view 0 default viewport.
229+
// bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
230+
231+
// // This dummy draw call is here to make sure that view 0 is cleared
232+
// // if no other draw calls are submitted to view 0.
233+
// bgfx::touch(0);
234+
235+
// const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
236+
// const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f };
237+
238+
// // Set view and projection matrix for view 0.
239+
// {
240+
// float view[16];
241+
// bx::mtxLookAt(view, eye, at);
242+
243+
// float proj[16];
244+
// bx::mtxProj(
245+
// proj,
246+
// 60.0f,
247+
// float(m_width) / float(m_height),
248+
// 0.1f,
249+
// 100.0f,
250+
// bgfx::getCaps()->homogeneousDepth);
251+
// bgfx::setViewTransform(0, view, proj);
252+
253+
// // Set view 0 default viewport.
254+
// bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
255+
// }
233256
// }
234257

235-
const bx::Vec3 at = { 0.0f, 0.0f, 0.0f };
236-
const bx::Vec3 eye = { 0.0f, 0.0f, -35.0f };
237-
238-
// Set view and projection matrix for view 0.
239258
{
259+
const bool mouseOverGui = ImGui::MouseOverArea();
260+
m_mouse.update(float(m_mouseState.m_mx), float(m_mouseState.m_my), m_mouseState.m_mz, m_width, m_height);
261+
if (!mouseOverGui)
262+
{
263+
if (m_mouseState.m_buttons[entry::MouseButton::Left])
264+
{
265+
m_camera.orbit(m_mouse.m_dx, m_mouse.m_dy);
266+
}
267+
else if (m_mouseState.m_buttons[entry::MouseButton::Right])
268+
{
269+
m_camera.dolly(m_mouse.m_dx + m_mouse.m_dy);
270+
}
271+
else if (m_mouseState.m_buttons[entry::MouseButton::Middle])
272+
{
273+
m_settings.m_envRotDest += m_mouse.m_dx*2.0f;
274+
}
275+
else if (0 != m_mouse.m_scroll)
276+
{
277+
m_camera.dolly(float(m_mouse.m_scroll)*0.05f);
278+
}
279+
}
280+
m_camera.update(deltaTimeSec);
281+
// bx::memCopy(m_uniforms.m_cameraPos, &m_camera.m_pos.curr.x, 3*sizeof(float) );
282+
283+
// View Transform 0.
240284
float view[16];
241-
bx::mtxLookAt(view, eye, at);
285+
// bx::mtxIdentity(view);
242286

243287
float proj[16];
244-
bx::mtxProj(proj, 60.0f, float(m_width) / float(m_height), 0.1f, 100.0f, bgfx::getCaps()->homogeneousDepth);
288+
// bx::mtxOrtho(proj, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f, 0.0, caps->homogeneousDepth);
289+
// bgfx::setViewTransform(0, view, proj);
290+
291+
// View Transform 1.
292+
m_camera.mtxLookAt(view);
293+
bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f, caps->homogeneousDepth);
245294
bgfx::setViewTransform(0, view, proj);
246295

247-
// Set view 0 default viewport.
248-
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height));
296+
// View rect.
297+
bgfx::setViewRect(0, 0, 0, uint16_t(m_width), uint16_t(m_height) );
298+
// bgfx::setViewRect(1, 0, 0, uint16_t(m_width), uint16_t(m_height) );
299+
300+
// Env rotation.
301+
const float amount = bx::min(deltaTimeSec/0.12f, 1.0f);
302+
m_settings.m_envRotCurr = bx::lerp(m_settings.m_envRotCurr, m_settings.m_envRotDest, amount);
303+
304+
// Env mtx.
305+
float mtxEnvView[16];
306+
m_camera.envViewMtx(mtxEnvView);
307+
float mtxEnvRot[16];
308+
bx::mtxRotateY(mtxEnvRot, m_settings.m_envRotCurr);
309+
249310
}
250311

251312
m_lastFrameMissing = 0;
@@ -281,6 +342,11 @@ namespace
281342
bgfx::ProgramHandle m_program;
282343

283344
int64_t m_timeOffset;
345+
346+
Camera m_camera;
347+
Mouse m_mouse;
348+
Settings m_settings;
349+
284350
};
285351

286352
} // namespace

0 commit comments

Comments
 (0)