Skip to content

Commit e53ed4d

Browse files
committed
gizmo initial
#976
1 parent bd14fd7 commit e53ed4d

10 files changed

Lines changed: 246 additions & 3 deletions

File tree

‎common/graphics/renderer.cpp‎

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ void Renderer::onWorldChanged() {
229229
resetSkyFog();
230230
}
231231

232+
void Renderer::setGizmo(bool enable, Tempest::Vec3 center) {
233+
gizmo.enable = enable;
234+
gizmo.center = center;
235+
}
236+
232237
void Renderer::updateCamera(const WorldView& wview, const Camera& camera) {
233238
proj = camera.projective();
234239
viewProj = camera.viewProj();
@@ -700,6 +705,7 @@ void Renderer::draw(Tempest::Attachment& result, Encoder<CommandBuffer>& cmd, ui
700705

701706
cmd.setFramebuffer({{sceneLinear, Tempest::Preserve, Tempest::Preserve}});
702707
drawReflections(cmd, wview);
708+
drawGizmo(cmd, wview);
703709
if(camera.isInWater()) {
704710
cmd.setDebugMarker("Underwater");
705711
drawUnderwater(cmd, wview);
@@ -915,6 +921,23 @@ void Renderer::drawSunMoon(Tempest::Encoder<Tempest::CommandBuffer>& cmd, const
915921
cmd.draw(nullptr, 0, 6);
916922
}
917923

924+
void Renderer::drawGizmo(Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview) {
925+
if(!gizmo.enable)
926+
return;
927+
928+
auto cen = gizmo.center;
929+
float w = 1;
930+
auto vp = wview.sceneGlobals().viewProject();
931+
vp.project(cen.x, cen.y, cen.z, w);
932+
933+
cmd.setPushData(gizmo.center);
934+
cmd.setDebugMarker("Hud-Gizmo");
935+
cmd.setBinding(0, wview.sceneGlobals().uboGlobal[SceneGlobals::V_Main]);
936+
cmd.setBinding(1, zbuffer);
937+
cmd.setPipeline(shaders.gizmo);
938+
cmd.draw(nullptr, 0, 36, 0, 3);
939+
}
940+
918941
void Renderer::drawSwRT(Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview) {
919942
if(!settings.swrtEnabled)
920943
return;

‎common/graphics/renderer.h‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class Renderer final {
2121
~Renderer();
2222

2323
void onWorldChanged();
24+
void setGizmo(bool enable, Tempest::Vec3 center);
2425

2526
void draw(Tempest::Attachment& result, Tempest::Encoder<Tempest::CommandBuffer>& cmd, uint8_t fId,
2627
Tempest::VectorImage::Mesh& uiLayer, Tempest::VectorImage::Mesh& numOverlay,
@@ -97,6 +98,7 @@ class Renderer final {
9798
void drawFog (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
9899
void drawSunMoon (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
99100
void drawSunMoon (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview, bool isSun);
101+
void drawGizmo (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
100102

101103
void drawSwRT (Tempest::Encoder<Tempest::CommandBuffer>& cmd, const WorldView& wview);
102104
void drawPathtrace (Tempest::Encoder<Tempest::CommandBuffer>& cmd, WorldView& wview, uint8_t fId);
@@ -293,6 +295,11 @@ class Renderer final {
293295
Tempest::StorageImage outputImage;
294296
} swrt;
295297

298+
struct {
299+
Tempest::Vec3 center = {};
300+
bool enable = false;
301+
} gizmo;
302+
296303
Tempest::TextureFormat shadowFormat = Tempest::TextureFormat::Depth16;
297304
Tempest::TextureFormat zBufferFormat = Tempest::TextureFormat::Depth16;
298305

‎common/graphics/shaders.cpp‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ void Shaders::compileShaders() {
177177
cmaa2DeferredColorApply2x2 = device.pipeline(Tempest::Points,RenderState(),vs,fs);
178178
}
179179

180+
{
181+
RenderState state;
182+
//state.setCullFaceMode(RenderState::CullMode::NoCull);
183+
184+
auto sh = GothicShader::get("gizmo.vert.sprv");
185+
auto vs = device.shader(sh.data,sh.len);
186+
sh = GothicShader::get("gizmo.frag.sprv");
187+
auto fs = device.shader(sh.data,sh.len);
188+
gizmo = device.pipeline(Triangles,state,vs,fs);
189+
}
190+
180191
hiZPot = computeShader("hiz_pot.comp.sprv");
181192
hiZMip = computeShader("hiz_mip.comp.sprv");
182193

‎common/graphics/shaders.h‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ class Shaders {
6868
Tempest::ComputePipeline cmaa2ProcessCandidates;
6969
Tempest::RenderPipeline cmaa2DeferredColorApply2x2;
7070

71+
// HUD
72+
Tempest::RenderPipeline gizmo;
73+
7174
// HiZ
7275
Tempest::ComputePipeline hiZPot, hiZMip;
7376

‎shader/CMakeLists.txt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,10 @@ function(add_frag_shader OUTPUT)
113113
set(OPENGOTHIC_SHADERS_SPRV ${OPENGOTHIC_SHADERS_SPRV} PARENT_SCOPE)
114114
endfunction(add_frag_shader)
115115

116+
# editor hud
117+
add_shader(gizmo.vert hud/gizmo.vert)
118+
add_shader(gizmo.frag hud/gizmo.frag)
119+
116120
# cluster culling
117121
add_shader(cluster_init.comp materials/cluster_init.comp)
118122
add_shader(cluster_patch.comp materials/cluster_patch.comp)

‎shader/hud/gizmo.frag‎

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
#version 460
2+
3+
#extension GL_EXT_samplerless_texture_functions : enable
4+
5+
#include "scene.glsl"
6+
#include "common.glsl"
7+
8+
layout(location = 0) out vec4 outColor;
9+
10+
layout(location = 0) in flat uint axis;
11+
layout(location = 1) in flat float scale;
12+
13+
layout(std140, push_constant) uniform Push {
14+
vec3 origin;
15+
};
16+
layout(binding = 0, std140) uniform UboScene {
17+
SceneDesc scene;
18+
};
19+
layout(binding = 1) uniform texture2D depth;
20+
21+
22+
float dot2(vec3 v) { return dot(v,v); }
23+
24+
vec4 cylIntersect(vec3 ro, vec3 rd, vec3 a, vec3 b, float ra ) {
25+
vec3 ba = b - a;
26+
vec3 oc = ro - a;
27+
28+
float baba = dot(ba,ba);
29+
float bard = dot(ba,rd);
30+
float baoc = dot(ba,oc);
31+
float k2 = baba - bard*bard;
32+
float k1 = baba*dot(oc,rd) - baoc*bard;
33+
float k0 = baba*dot(oc,oc) - baoc*baoc - ra*ra*baba;
34+
float h = k1*k1 - k2*k0;
35+
36+
if( h<0.0 )
37+
return vec4(-1.0);//no intersection
38+
h = sqrt(h);
39+
float t = (-k1-h)/k2;
40+
// body
41+
float y = baoc + t*bard;
42+
if( y>0.0 && y<baba )
43+
return vec4((oc+t*rd - ba*y/baba)/ra, t);
44+
45+
// caps
46+
t = ( ((y<0.0) ? 0.0 : baba) - baoc)/bard;
47+
if(abs(k1+k2*t) < h)
48+
return vec4(ba*sign(y)/sqrt(baba), t);
49+
50+
return vec4(-1.0);//no intersection
51+
}
52+
53+
vec4 coneIntersect(vec3 ro, vec3 rd, vec3 pa, vec3 pb, float ra, float rb) {
54+
vec3 ba = pb - pa;
55+
vec3 oa = ro - pa;
56+
vec3 ob = ro - pb;
57+
float m0 = dot(ba,ba);
58+
float m1 = dot(oa,ba);
59+
float m2 = dot(rd,ba);
60+
float m3 = dot(rd,oa);
61+
float m5 = dot(oa,oa);
62+
float m9 = dot(ob,ba);
63+
64+
// caps
65+
if(m1 < 0.0) {
66+
if(dot2(oa*m2-rd*m1) < (ra*ra*m2*m2)) // delayed division
67+
return vec4(-ba*inversesqrt(m0), -m1/m2);
68+
}
69+
else if(m9 > 0.0) {
70+
float t = -m9/m2; // NOTE delayed division
71+
if(dot2(ob+rd*t) < (rb*rb))
72+
return vec4(ba*inversesqrt(m0), t);
73+
}
74+
75+
// body
76+
float rr = ra - rb;
77+
float hy = m0 + rr*rr;
78+
float k2 = m0*m0 - m2*m2*hy;
79+
float k1 = m0*m0*m3 - m1*m2*hy + m0*ra*(rr*m2*1.0 );
80+
float k0 = m0*m0*m5 - m1*m1*hy + m0*ra*(rr*m1*2.0 - m0*ra);
81+
float h = k1*k1 - k2*k0;
82+
if(h < 0.0)
83+
return vec4(-1.0); //no intersection
84+
float t = (-k1-sqrt(h))/k2;
85+
float y = m1 + t*m2;
86+
if(y < 0.0 || y > m0)
87+
return vec4(-1.0); //no intersection
88+
return vec4(normalize(m0*(m0*(oa+t*rd)+rr*ba*ra)-ba*hy*y), t);
89+
}
90+
91+
vec4 arrowIntersect(vec3 ro, vec3 rd) {
92+
vec3 off0 = vec3(0), off1 = vec3(0), off2 = vec3(0);
93+
off0[axis] = scale*10;
94+
off1[axis] = scale*160;
95+
off2[axis] = scale*200;
96+
97+
vec4 body = cylIntersect (ro, rd, origin, origin + off1, 4.0 * scale);
98+
vec4 cap = coneIntersect(ro, rd, origin + off1, origin + off2, 10.0 * scale, 0);
99+
if(body.w>=0 && (body.w<cap.w || cap.w<=0))
100+
return body;
101+
return cap;
102+
}
103+
104+
void main() {
105+
const vec2 fragCoord = (gl_FragCoord.xy*scene.screenResInv)*2.0-vec2(1.0);
106+
const vec4 start4 = scene.viewProjectInv*vec4(fragCoord.x, fragCoord.y, 1.0, 1.0);
107+
const vec3 start = start4.xyz/start4.w;
108+
109+
const vec3 camPos = scene.camPos;
110+
const vec3 view = normalize(start - camPos);
111+
112+
const vec4 nort = arrowIntersect(camPos, view);
113+
if(nort.w>0) {
114+
vec3 clr = vec3(0);
115+
clr[axis] = 1;
116+
clr *= (max(0.0, dot(scene.sunDir, nort.xyz))*0.8 + 0.2);
117+
float d = texelFetch(depth, ivec2(gl_FragCoord.xy), 0).x;
118+
float dl = linearDepth(d, scene.clipInfo);
119+
if(nort.w > dl) {
120+
ivec2 id = ivec2(gl_FragCoord.xy)/4;
121+
clr *= (id.x+id.y)%2==0 ? 0.1 : 0.9;
122+
}
123+
outColor = vec4(clr,1);
124+
return;
125+
}
126+
127+
discard;
128+
}

‎shader/hud/gizmo.vert‎

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#version 450
2+
3+
#include "scene.glsl"
4+
5+
layout(location = 0) out flat uint axis;
6+
layout(location = 1) out flat float scale;
7+
8+
layout(std140, push_constant) uniform Push {
9+
vec3 origin;
10+
};
11+
12+
layout(binding = 0, std140) uniform UboScene {
13+
SceneDesc scene;
14+
};
15+
16+
const vec3 v[8] = {
17+
{-1,-1,-1},
18+
{ 1,-1,-1},
19+
{ 1, 1,-1},
20+
{-1, 1,-1},
21+
22+
{-1,-1, 1},
23+
{ 1,-1, 1},
24+
{ 1, 1, 1},
25+
{-1, 1, 1},
26+
};
27+
28+
const uint index[36] = {
29+
0, 1, 3, 3, 1, 2,
30+
1, 5, 2, 2, 5, 6,
31+
5, 4, 6, 6, 4, 7,
32+
4, 0, 7, 7, 0, 3,
33+
3, 2, 7, 7, 2, 6,
34+
4, 5, 0, 0, 5, 1
35+
};
36+
37+
void main() {
38+
const vec3 vert = v[index[gl_VertexIndex]];
39+
40+
scale = (scene.viewProject * vec4(origin, 1.0)).w/1000.0;
41+
42+
vec3 size = vec3(200,10,10) * scale;
43+
vec3 pos = vert * size;
44+
pos.x = max(pos.x, 10 * scale);
45+
46+
if(gl_InstanceIndex==0) {
47+
pos = pos.xyz;
48+
axis = 0;
49+
}
50+
else if(gl_InstanceIndex==1) {
51+
pos = pos.yxz;
52+
axis = 1;
53+
}
54+
else if(gl_InstanceIndex==2) {
55+
pos = pos.yzx;
56+
axis = 2;
57+
}
58+
else if(gl_InstanceIndex==3) {
59+
pos = pos.zzz;
60+
axis = 4;
61+
}
62+
gl_Position = scene.viewProject * vec4(origin + pos, 1.0);
63+
}

‎spacer/objects/worldedit.cpp‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ WorldEdit::WorldEdit(std::string_view wname) {
4949
WorldEdit::~WorldEdit() {
5050
}
5151

52-
void WorldEdit::load(Vob& out, std::vector<std::shared_ptr<zenkit::VirtualObject> >& child) {
52+
void WorldEdit::load(Vob& out, std::vector<std::shared_ptr<zenkit::VirtualObject>>& child) {
5353
out.child.reserve(child.size());
5454
for(size_t i=0; i<child.size(); ++i) {
5555
out.child.emplace_back(vobNextId); ++vobNextId;

‎spacer/objects/worldedit.h‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@ class WorldEdit {
5050

5151
Vob* validatePointer(const zenkit::VirtualObject* ptr, Vob& v);
5252

53-
Vob rootVob {0};
54-
size_t vobNextId = 1;
5553
std::unique_ptr<DynamicWorld> physics;
5654
std::unique_ptr<WorldView> wview;
55+
Vob rootVob {0};
56+
size_t vobNextId = 1;
5757
};
5858

‎spacer/ui/editors/worldeditor.cpp‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,10 @@ WorldEdit::Vob* WorldEditor::rayQuery(Tempest::Point mpos) {
189189
}
190190

191191
void WorldEditor::selectVob(const WorldEdit::Vob& vob) {
192+
if(vob.get()==nullptr)
193+
return;
194+
const auto pos = vob.get()->position;
195+
renderer.setGizmo(true, Vec3(pos.x,pos.y,pos.z));
192196
treeDelegate->setVob(&vob);
193197
propertyDelegate->setVob(&vob);
194198
update();

0 commit comments

Comments
 (0)