-
Notifications
You must be signed in to change notification settings - Fork 0
/
3d_example.cpp
155 lines (135 loc) · 3.99 KB
/
3d_example.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#if 0
// 𝐍𝐎𝐓𝐄: You will not be able to compile this as it relies on a simple 3d rendering engine which is
// not included. It is provided as an example of something interesting - programming
// interactively in a notebook interface while allowing full real-time virtual reality rendering.
//
// The way it works is it exports a few simple functions that call into a 3d rendering library for
// interactive visualization that uses vulkan or directx12 to give you a real-time 3d window with
// WASD controls and vr support.
//
// The interface provided is cheesy - all you can do is add spheres to the scene. From Julia you
// initialize it by calling StartRendering() which will spawn a thread to run the 3d ui. This
// means that rendering and camera movement will not be blocked by computation or compilation on
// the main thread.
#include <codebase/all.h>
#include <exposer/exposer.h>
#include "codebase/filesystem.h"
#include "codebase/application.h"
#include <codebase/fixedvector.h>
#include <Eigen/Core>
#include <random>
#include <math.h>
#include <codebase/stringtokens.h>
#include "assimp_helpers/assimp_helpers.h"
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <assimp/matrix4x4.h>
#include "tbb/tbb.h"
#include "tbb/flow_graph.h"
#include "numeric/numeric_optimization.h"
#include "3dclient/3dclient.h"
struct Sphere_t
{
v3f m_vPos;
v3f m_vColor;
float m_flRadius;
};
class CTestApp : public I3DBaseClient
{
typedef I3DBaseClient BaseClass;
public:
using I3DBaseClient::I3DBaseClient;
CLockableVector<Sphere_t> m_vSpheres;
BlockingConcurrentQueue<int> m_msgQueue;
bool m_bStarted = false;
void RunMainLoop() override;
void SetupFrame( CRenderFrame *pFrame ) override;
void SetupUI()
{
BaseClass::SetupUI();
}
void AddSphere( float flX, float flY, float flZ, float flRad, float flRed, float flGreen, float flBlue )
{
with_lock( m_vSpheres )
{
Sphere_t newOne = { v3f( flX, flY, flZ ), v3f( flRed, flGreen, flBlue ), flRad };
m_vSpheres.push_back( newOne );
}
}
void MoveSphere( int nSphereIndex, float flX, float flY, float flZ )
{
with_lock( m_vSpheres )
{
if ( nSphereIndex < m_vSpheres.Count() )
{
m_vSpheres[nSphereIndex].m_vPos.x = flX;
m_vSpheres[nSphereIndex].m_vPos.y = flY;
m_vSpheres[nSphereIndex].m_vPos.z = flZ;
}
}
}
};
void CTestApp::SetupFrame( CRenderFrame *pFrame )
{
BaseClass::SetupFrame( pFrame );
with_lock( m_vSpheres )
{
for( Sphere_t const &sph : m_vSpheres )
{
pFrame->Draw3DMesh( &Renderer()->m_sphereMesh, sph.m_vPos, { 0, 0, sph.m_flRadius }, { 0, sph.m_flRadius, 0 }, sph.m_vColor );
}
}
}
void CTestApp::RunMainLoop()
{
BaseClass::RunMainLoop();
}
CTestApp *g_pApp;
void ClearSpheres()
{
with_lock( g_pApp->m_vSpheres )
{
g_pApp->m_vSpheres.clear();
}
}
void MoveSphere( int nSphereIndex, float flX, float flY, float flZ )
{
g_pApp->MoveSphere( nSphereIndex, flX, flY, flZ );
}
void AddSphere( float flX, float flY, float flZ, float flRad , float flRed, float flGreen, float flBlue )
{
g_pApp->AddSphere( flX, flY, flZ, flRad, flRed, flGreen, flBlue );
}
void StopRendering()
{
g_pApp->RequestQuit();
}
void StartRendering()
{
if ( ! g_pApp->m_bStarted )
{
g_pApp->m_msgQueue.enqueue( 1 );
}
}
void StartDLL( int argc, char **argv )
{
// Call this before setting the application object so that we can look at the command line args
ApplicationInit( argc, argv );
ExposeGeo();
EXPOSEFN( StopRendering );
EXPOSEFN( AddSphere );
EXPOSEFN( MoveSphere );
EXPOSEFN( ClearSpheres );
EXPOSEFN( StartRendering );
CTestApp *pApp = new CTestApp( 0, nullptr );
g_pApp = pApp;
new std::thread( []{
// Wait for start message. We need to create the window on this thread so that windows
// messages will get here
int nMessage;
g_pApp->m_msgQueue.wait_dequeue( nMessage );
g_pApp->Initialize();
g_pApp->RunMainLoop();
} );
}
#endif