Bugfixes n sector picking n more

This commit is contained in:
KP 2024-07-27 21:07:41 -05:00
parent da83fa0e0d
commit cf5b61c87a
13 changed files with 510 additions and 440 deletions

View file

@ -2,6 +2,8 @@
uniform vec3 u_campos;
uniform vec3 u_highlight;
in vec3 v_position;
in vec3 v_normal;
in vec3 v_proj_normal;
@ -63,6 +65,8 @@ void main()
v_output = mix(v_output, texv, 0.66);
v_output.rgb *= u_highlight;
/*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 B

After

Width:  |  Height:  |  Size: 144 B

View file

@ -1,269 +1,167 @@
[05:25:18 PM] Info: Starting...
[09:06:03 PM] Info: Starting...
KP3D version 2
===============================
Copyright (C) kpworld.xyz 2018-2024
Contact me! @kp_cftsz
[05:25:18 PM] Info: Initializing SDL
[05:25:18 PM] Info: Initializing OpenGL
[05:25:18 PM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
[05:25:18 PM] Info: Initializing GLEW
[05:25:18 PM] Info: Initializing SDL_mixer
[05:25:18 PM] Info: Reticulating splines...
[05:25:18 PM] Info: Ready!
[05:25:18 PM] Info: SECTOR HIERARCHY
[05:25:18 PM] Info: Sector 3 (area: 1)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - 1
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - [NO CHILDREN]
[05:25:18 PM] Info: -----
[05:25:18 PM] Info: Sector 4 (area: 1)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - 2
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - [NO CHILDREN]
[05:25:18 PM] Info: -----
[05:25:18 PM] Info: Sector 6 (area: 6)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - 1
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - [NO CHILDREN]
[05:25:18 PM] Info: -----
[05:25:18 PM] Info: Sector 2 (area: 19)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - 1
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - 4
[05:25:18 PM] Info: -----
[05:25:18 PM] Info: Sector 5 (area: 34)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - [NO PARENT]
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - [NO CHILDREN]
[05:25:18 PM] Info: -----
[05:25:18 PM] Info: Sector 1 (area: 105.5)
[05:25:18 PM] Info: Parent:
[05:25:18 PM] Info: - [NO PARENT]
[05:25:18 PM] Info: Children:
[05:25:18 PM] Info: - 3
[05:25:18 PM] Info: - 6
[05:25:18 PM] Info: - 2
[05:25:18 PM] Info: -----
[05:25:30 PM] Info: SECTOR HIERARCHY
[05:25:30 PM] Info: Sector 3 (area: 1)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - 1
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - [NO CHILDREN]
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 4 (area: 1)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - 2
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - [NO CHILDREN]
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 6 (area: 6)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - 1
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - [NO CHILDREN]
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 7 (area: 15)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - [NO PARENT]
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - [NO CHILDREN]
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 2 (area: 19)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - 1
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - 4
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 5 (area: 34)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - [NO PARENT]
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - [NO CHILDREN]
[05:25:30 PM] Info: -----
[05:25:30 PM] Info: Sector 1 (area: 105.5)
[05:25:30 PM] Info: Parent:
[05:25:30 PM] Info: - [NO PARENT]
[05:25:30 PM] Info: Children:
[05:25:30 PM] Info: - 3
[05:25:30 PM] Info: - 6
[05:25:30 PM] Info: - 2
[05:25:30 PM] Info: -----
[05:25:35 PM] Info: SECTOR HIERARCHY
[05:25:35 PM] Info: Sector 3 (area: 1)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - 1
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 4 (area: 1)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - 2
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 8 (area: 3)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - [NO PARENT]
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 6 (area: 6)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - 1
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 7 (area: 15)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - [NO PARENT]
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 2 (area: 19)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - 1
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - 4
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 5 (area: 34)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - [NO PARENT]
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - [NO CHILDREN]
[05:25:35 PM] Info: -----
[05:25:35 PM] Info: Sector 1 (area: 105.5)
[05:25:35 PM] Info: Parent:
[05:25:35 PM] Info: - [NO PARENT]
[05:25:35 PM] Info: Children:
[05:25:35 PM] Info: - 3
[05:25:35 PM] Info: - 6
[05:25:35 PM] Info: - 2
[05:25:35 PM] Info: -----
[05:25:47 PM] Info: SECTOR HIERARCHY
[05:25:47 PM] Info: Sector 3 (area: 1)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - 1
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 4 (area: 1)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - 2
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 8 (area: 3)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - [NO PARENT]
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 6 (area: 6)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - 1
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 9 (area: 8)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - [NO PARENT]
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 7 (area: 15)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - [NO PARENT]
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 2 (area: 19)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - 1
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - 4
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 5 (area: 34)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - [NO PARENT]
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - [NO CHILDREN]
[05:25:47 PM] Info: -----
[05:25:47 PM] Info: Sector 1 (area: 105.5)
[05:25:47 PM] Info: Parent:
[05:25:47 PM] Info: - [NO PARENT]
[05:25:47 PM] Info: Children:
[05:25:47 PM] Info: - 3
[05:25:47 PM] Info: - 6
[05:25:47 PM] Info: - 2
[05:25:47 PM] Info: -----
[05:25:56 PM] Info: SECTOR HIERARCHY
[05:25:56 PM] Info: Sector 3 (area: 1)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - 1
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 4 (area: 1)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - 2
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 8 (area: 3)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 10 (area: 4)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 6 (area: 6)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - 1
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 9 (area: 8)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 7 (area: 15)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 2 (area: 19)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - 1
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - 4
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 5 (area: 34)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - [NO CHILDREN]
[05:25:56 PM] Info: -----
[05:25:56 PM] Info: Sector 1 (area: 105.5)
[05:25:56 PM] Info: Parent:
[05:25:56 PM] Info: - [NO PARENT]
[05:25:56 PM] Info: Children:
[05:25:56 PM] Info: - 3
[05:25:56 PM] Info: - 6
[05:25:56 PM] Info: - 2
[05:25:56 PM] Info: -----
[09:06:03 PM] Info: Initializing SDL
[09:06:03 PM] Info: Initializing OpenGL
[09:06:03 PM] Info: OpenGL version: 4.6.0 NVIDIA 536.23
[09:06:03 PM] Info: Initializing GLEW
[09:06:03 PM] Info: Initializing SDL_mixer
[09:06:03 PM] Info: Reticulating splines...
[09:06:03 PM] Info: Ready!
[09:06:03 PM] Info: Finalize mesh with 45 batches
[09:06:10 PM] Info: Finalize mesh with 48 batches
[09:06:19 PM] Info: Finalize mesh with 55 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:24 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:25 PM] Info: Finalize mesh with 56 batches
[09:06:26 PM] Info: Finalize mesh with 56 batches
[09:06:26 PM] Info: Finalize mesh with 56 batches
[09:06:26 PM] Info: Finalize mesh with 56 batches
[09:06:26 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:28 PM] Info: Finalize mesh with 56 batches
[09:06:29 PM] Info: Finalize mesh with 56 batches
[09:06:29 PM] Info: Finalize mesh with 56 batches
[09:06:29 PM] Info: Finalize mesh with 56 batches
[09:06:29 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:36 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:37 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:53 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:54 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 56 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:06:56 PM] Info: Finalize mesh with 54 batches
[09:07:03 PM] Info: Finalize mesh with 54 batches
[09:07:03 PM] Info: Finalize mesh with 54 batches
[0

View file

@ -47,10 +47,30 @@ bool SectorContains(const kp3d::Sector& outer, const kp3d::Sector& inner)
return completely_inside || (count > 0 && partial_count < 4); // stupid
}
// Callback used by the renderer and editor
// kind of ugly the way this works...
kp3d::uint ShouldHighlight(const kp3d::RenderBatch3D& batch)
{
if (!kp3d::editor_hovered_batch)
return 0xFFFFFFFF;
if (&batch != kp3d::editor_hovered_batch)
return 0xFFFFFFFF;
kp3d::BatchSectorInfo info = std::any_cast<kp3d::BatchSectorInfo>(batch.userdata);
// if (info.wall)
// return 0xFF5555FF;
// else if (info.flat)
// return 0xFFFF55FF;
// else
if (info.sector)
return 0x5555FFFF;
}
}
namespace kp3d {
RenderBatch3D* editor_hovered_batch = nullptr;
Map::Map()
{
}
@ -165,8 +185,9 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
flat.triangulated_data.push_back(vtxa);
flat.triangulated_data.push_back(vtxb);
flat.triangulated_data.push_back(vtxc);
BatchSectorInfo info = {BatchSectorInfo::BATCH_FLAT, &sector, &flat, nullptr};
if (flat.texture)
m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert);
m_mesh.AddBatch(flat.texture, { vtxa, vtxb, vtxc }, !invert, std::make_any<BatchSectorInfo>(info));
}
}
@ -176,7 +197,7 @@ void Map::BuildFlat(Sector& sector, Flat& flat, bool invert)
* To do this we perform a similar approach to BuildFlat, but because the walls aren't strictly along one axis we have to
* "flatten" them to perform the math to triangulate them. This is done by projecting the 3D points to 2D.
*/
void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset)
void Map::BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset)
{
if (!texture)
return;
@ -251,8 +272,9 @@ void Map::BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Tex
Vertex3D vtxa = Vertex3D(fva, Vec2(au * tw, av * th));
Vertex3D vtxb = Vertex3D(fvb, Vec2(bu * tw, bv * th));
Vertex3D vtxc = Vertex3D(fvc, Vec2(cu * tw, cv * th));
BatchSectorInfo info = {BatchSectorInfo::BATCH_WALL, &sector, nullptr, &wall};
if (texture)
m_mesh.AddBatch(texture, { vtxa, vtxb, vtxc }, flip);
m_mesh.AddBatch(texture, {vtxa, vtxb, vtxc}, flip, std::make_any<BatchSectorInfo>(info));
}
}
}
@ -261,15 +283,15 @@ void Map::BuildWall(Sector& sector, Wall& wall)
{
Vec3 a = {wall.start.x, 0.0f, wall.start.y};
Vec3 b = {wall.end.x, 0.0f, wall.end.y};
BuildQuad(sector, sector.floor, sector.ceiling, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]);
BuildQuad(sector, wall, sector.floor, sector.ceiling, wall.textures[TEX_FRONT], a, b, false, false, false, wall.uv_offset[TEX_FRONT]);
if (wall.flags & Wall::FLAG_OPENING)
{
// Build upper and lower walls for sectors connected to other sectors (or sectors within sectors)
bool flip = wall.portal->floor.base_height < sector.floor.base_height;
BuildQuad(sector, sector.floor, wall.portal->floor, wall.textures[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
BuildQuad(sector, wall, sector.floor, wall.portal->floor, wall.textures[TEX_LOWER], a, b, flip, false, false, wall.uv_offset[TEX_LOWER]);
flip = wall.portal->ceiling.base_height < sector.ceiling.base_height;
BuildQuad(sector, sector.ceiling, wall.portal->ceiling, wall.textures[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
BuildQuad(sector, wall, sector.ceiling, wall.portal->ceiling, wall.textures[TEX_UPPER], a, b, !flip, false, false, wall.uv_offset[TEX_UPPER]);
}
}
@ -280,8 +302,11 @@ void Map::JoinSectors(Sector& sector)
for (int i = 0; i < sector.walls.size(); i++)
{
Wall& ld = sector.walls[i];
for (Sector& s: sectors)
if (ld.flags & Wall::FLAG_TOUCHED)
continue;
for (const auto& sp: sectors)
{
Sector& s = *sp;
if (s.id == sector.id)
continue;
@ -296,6 +321,8 @@ void Map::JoinSectors(Sector& sector)
for (Wall& l : s.walls)
{
//if (l.flags & Wall::FLAG_TOUCHED)
// continue;
bool good = false;
bool start_cmp = PosCmp({l.start.x, 0.0f, l.start.y}, {pos_a.x, 0.0f, pos_a.z}, e) ||
PosCmp({l.start.x, 0.0f, l.start.y}, {pos_b.x, 0.0f, pos_b.z}, e);
@ -354,7 +381,7 @@ void Map::JoinSectors(Sector& sector)
w1.end.x = l.start.x;
w1.end.y = l.start.y;
w1.textures[TEX_FRONT] = nullptr;
w1.flags = Wall::FLAG_OPENING;
// w1.flags = Wall::FLAG_OPENING;
w1.portal = &s;
w1.flags = Wall::FLAG_TOUCHED;
InsertLine(sector.walls, i + 1, w1);
@ -427,6 +454,7 @@ void Map::Init()
{
sectors.clear();
m_mesh.Reset();
sectors.reserve(10000);
BuildSkybox("skybox_16.jpg");
BuildGrid();
@ -454,19 +482,19 @@ void Map::Init()
XYf points6[] = {{1, 4}, {3, 4}, {3, 7}, {1, 7}};
auto build_sector = [&](Texture* wall, Texture* floor, Texture* ceil, float floor_height, float ceil_height, int id, XYf* points, size_t num_points, bool inverted = false)
{
Sector s;
s.ceiling.texture = ceil;
s.floor.texture = floor;
s.floor.floor = true;
s.floor.base_height = floor_height;
s.ceiling.base_height = ceil_height;
s.id = id;
s.parent_id = 0;
s.inverted = inverted;
std::shared_ptr<Sector> s = std::make_unique<Sector>();
s->ceiling.texture = ceil;
s->floor.texture = floor;
s->floor.floor = true;
s->floor.base_height = floor_height;
s->ceiling.base_height = ceil_height;
s->id = id;
s->parent_id = 0;
s->inverted = inverted;
float scl = 1.0f;
for (size_t i = 0; i < num_points; i++)
s.walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, points[i], points[(i + 1) % num_points], Wall::NO_FLAGS, (uint)i });
original_sectors.push_back(s);
s->walls.push_back(Wall{ {wall,wall,wall}, {{0, 0}}, points[i], points[(i + 1) % num_points], Wall::NO_FLAGS, (uint)i });
sectors.push_back(s);
};
build_sector(&tex3, &tex, &tex2, -1.0f, 5.0f, 1, points, std::size(points));
build_sector(&tex4, &tex2, &tex2, -1.5f, 4.0f, 2, points2, std::size(points2));
@ -482,36 +510,42 @@ void Map::Rebuild(NormalGenType gen_normals)
{
m_mesh.Reset();
sectors.clear();
for (Sector& s : original_sectors)
{
sectors.push_back(s);
}
//sectors.clear();
//for (Sector& s : original_sectors)
//{
// s.original = &s;
// sectors.push_back(s);
//}
// Correct sectors with counter-clockwise linedef order using the shoelace formula,
// also while we're at it grab the sector areas (will be useful later) and reset old data.
int i = 0;
for (Sector& s: sectors)
for (const auto& sp: sectors)
{
Sector& s = *sp;
// Since we're regenerating the map, we don't want to re-use this data, it may be old.
s.children.clear();
s.floor.triangulated_data.clear();
s.floor.steiner_points.clear();
s.ceiling.triangulated_data.clear();
s.ceiling.steiner_points.clear();
s.area = 0.0f;
s.flags = Sector::NO_FLAGS;
s.parent_id = 0;
s.id = ++i;
// s.id = ++i;
// Now perform the swap + save the area
float area = 0.0f;
for (Wall& l: s.walls)
{
bool touched = l.flags & Wall::FLAG_TOUCHED;
bool no_collisions = l.flags & Wall::FLAG_NO_COLLISION;
l.flags = Wall::NO_FLAGS;
if (touched)
l.flags |= Wall::FLAG_TOUCHED;
if (no_collisions)
l.flags |= Wall::FLAG_NO_COLLISION;
l.portal = nullptr;
//bool touched = l.flags & Wall::FLAG_TOUCHED;
//bool no_collisions = l.flags & Wall::FLAG_NO_COLLISION;
//l.flags = Wall::NO_FLAGS;
//if (touched)
// l.flags |= Wall::FLAG_TOUCHED;
//if (no_collisions)
// l.flags |= Wall::FLAG_NO_COLLISION;
//l.portal = nullptr;
area += l.start.x * l.end.y;
area -= l.end.x * l.start.y;
@ -527,11 +561,13 @@ void Map::Rebuild(NormalGenType gen_normals)
}
// Now perform the process of "parenting" sectors; this essentially takes in our flat list of sectors and creates a hierarchy.
std::sort(sectors.begin(), sectors.end(), [](const Sector& a, const Sector& b) { return a.area < b.area; });
for (Sector& sector: sectors)
std::sort(sectors.begin(), sectors.end(), [](const auto& a, const auto& b) { return a->area < b->area; });
for (const auto& sp: sectors)
{
for (Sector& potential_parent: sectors)
Sector& sector = *sp;
for (const auto& spp: sectors)
{
Sector& potential_parent = *spp;
if (sector.id == potential_parent.id)
continue;
if (SectorContains(potential_parent, sector))
@ -543,7 +579,7 @@ void Map::Rebuild(NormalGenType gen_normals)
}
}
#if 1
#if 0
// Debug: Print out the sector hierachy
KP3D_LOG_INFO("SECTOR HIERARCHY");
for (Sector& s: sectors)
@ -561,8 +597,9 @@ void Map::Rebuild(NormalGenType gen_normals)
#endif
// Preproc (really just part of the test map building process again)
for (Sector& s: sectors)
for (const auto& sp: sectors)
{
Sector& s = *sp;
// Build up "steiner points" for terrain only
// We'll do this along a grid for now; it should be noted that this will be expected to be part of the sector data later
int num_steiners_along_xy = 50;
@ -590,26 +627,26 @@ void Map::Rebuild(NormalGenType gen_normals)
if (s.id == 1 || s.id == 5)
{
float yv0 = PerlinNoise2D(steiner_point.x, steiner_point.y, 1.0, 10.0);
float yv1 = -PerlinNoise2D(steiner_point.x, steiner_point.y, 0.5, 9.0);
s.floor.steiner_points.push_back({ steiner_point.x, yv0, steiner_point.y });
s.ceiling.steiner_points.push_back({ steiner_point.x, yv1, steiner_point.y });
//float yv0 = PerlinNoise2D(steiner_point.x, steiner_point.y, 1.0, 10.0);
//float yv1 = -PerlinNoise2D(steiner_point.x, steiner_point.y, 0.5, 9.0);
//s.floor.steiner_points.push_back({ steiner_point.x, yv0, steiner_point.y });
//s.ceiling.steiner_points.push_back({ steiner_point.x, yv1, steiner_point.y });
}
}
}
}
// Build level geometry
for (Sector& s: sectors)
JoinSectors(s);
for (Sector& s: sectors)
for (const auto& s: sectors)
JoinSectors(*s);
for (const auto& s: sectors)
{
BuildFlat(s, s.floor, false);
BuildFlat(s, s.ceiling, true);
BuildFlat(*s, s->floor, false);
BuildFlat(*s, s->ceiling, true);
}
for (Sector& s: sectors)
for (Wall& ld: s.walls)
BuildWall(s, ld);
for (const auto& s: sectors)
for (Wall& ld: s->walls)
BuildWall(*s, ld);
// Invert the map on the Z axis; not doing this for any other reason besides compatibility with KP3D 1.0
for (RenderBatch3D& b : m_mesh.GetBatchesRef())
@ -624,7 +661,25 @@ void Map::Rebuild(NormalGenType gen_normals)
}
// Finalize the mesh
m_mesh.Finalize(gen_normals);
m_mesh.Finalize(
gen_normals,
[](const RenderBatch3D& a, const RenderBatch3D& b) -> bool
{
return a.texture->GetGLID() < b.texture->GetGLID() &&
std::any_cast<BatchSectorInfo>(a.userdata).type < std::any_cast<BatchSectorInfo>(b.userdata).type;
},
[](const RenderBatch3D& a, const RenderBatch3D& b) -> bool
{
const auto& au = std::any_cast<BatchSectorInfo>(a.userdata);
const auto& bu = std::any_cast<BatchSectorInfo>(b.userdata);
return a.texture->GetGLID() != b.texture->GetGLID() ||
au.sector != bu.sector ||
au.flat != bu.flat ||
au.wall != bu.wall;
}
);
KP3D_LOG_INFO("Finalize mesh with {} batches", m_mesh.GetBatchesRef().size());
}
void Map::Update()
@ -638,7 +693,7 @@ void Map::Render()
// Map
kp3d::Renderer3D::PushShader(kp3d::Renderer3D::GetMapShader());
kp3d::Renderer3D::DrawMesh(m_mesh, m_transform);
kp3d::Renderer3D::DrawMesh(m_mesh, m_transform, true, ShouldHighlight);
kp3d::Renderer3D::PopShader();
// Debug dots
@ -754,4 +809,9 @@ void Map::RenderGrid()
Renderer3D::PopShader();
}
StaticMesh& Map::GetMeshRef()
{
return m_mesh;
}
} // namespace kp3d

View file

@ -40,6 +40,7 @@ struct Wall
uint uid;
Sector* portal = nullptr;
//int portal = 0;
};
struct Flat
@ -85,6 +86,8 @@ struct Sector
float area = 0.0f;
Sector* original;
};
struct Skybox
@ -94,6 +97,20 @@ struct Skybox
Transform transform;
};
// Information we can associate with render batches to find out what parts of the map a piece of geometry represents
struct BatchSectorInfo
{
enum
{
BATCH_SECTOR,
BATCH_FLAT,
BATCH_WALL
} type;
kp3d::Sector* sector = nullptr;
kp3d::Flat* flat = nullptr;
kp3d::Wall* wall = nullptr;
};
class Map
{
public:
@ -104,7 +121,7 @@ public:
ErrCode SaveToFile(const std::string& path);
void BuildFlat(Sector& sector, Flat& flat, bool invert);
void BuildQuad(Sector& sector, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset);
void BuildQuad(Sector& sector, Wall& wall, Flat& flat_top, Flat& flat_bottom, const Texture* texture, Vec3 pos_a, Vec3 pos_b, bool flip, bool flip_u, bool flip_v, XYf uv_offset);
void BuildWall(Sector& sector, Wall& wall);
void JoinSectors(Sector& sector);
@ -121,10 +138,11 @@ public:
void BuildGrid();
void RenderGrid();
StaticMesh& GetMeshRef();
public:
bool join_disabled = false;
std::vector<Sector> original_sectors;
std::vector<Sector> sectors;
std::vector<std::shared_ptr<Sector>> sectors;
bool render_wireframe = true;
float texture_scale = 128.0f;
Vec3 grid_box[6];
@ -143,4 +161,6 @@ private:
};
extern RenderBatch3D* editor_hovered_batch; // hack
}

View file

@ -165,18 +165,8 @@ void Renderer3D::End()
r3d_state->active = false;
}
void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader, uint (*func_highlight)(const RenderBatch3D&))
{
if (bind_shader)
r3d_state->shader->Bind();
r3d_state->shader->SetUniform("u_mvp", m);
r3d_state->shader->SetUniform("u_campos", r3d_state->v->position);
r3d_state->shader->SetUniform("u_camdir", r3d_state->v->forward);
r3d_state->shader->SetUniform("u_time", r3d_state->time);
// TODO: Remove this:
r3d_state->shader->SetUniform("u_transmat", Mat4().InitIdentity());
glBindVertexArray(mesh.m_gl_vao_id);
// The reason the blending shit works like this here is
@ -186,12 +176,27 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
glAlphaFunc(GL_GREATER, 0.1f);
glEnable(GL_ALPHA_TEST);
if (mesh.skinnable)
for (const RenderBatch3D& batch: mesh.m_batches)
{
if (bind_shader)
r3d_state->shader->Bind();
r3d_state->shader->SetUniform("u_mvp", m);
r3d_state->shader->SetUniform("u_campos", r3d_state->v->position);
r3d_state->shader->SetUniform("u_camdir", r3d_state->v->forward);
r3d_state->shader->SetUniform("u_time", r3d_state->time);
// Optional highlight function used by the editor
if (func_highlight)
{
std::array<float, 4> arr = ColorToFloats(func_highlight(batch));
Vec3 color = { arr[0], arr[1], arr[2] };
r3d_state->shader->SetUniform("u_highlight", color);
}
else
{
r3d_state->shader->SetUniform("u_highlight", Vec3(1.0f, 1.0f, 1.0f));
}
for (const auto& batch: mesh.m_batches)
{
bool indexed = !batch.index_data.empty();
bool skinned = !batch.bone_data.empty();
@ -205,7 +210,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
glEnableVertexAttribArray(2);
if (skinned)
{
// glBindBuffer(GL_ARRAY_BUFFER, batch.gl_bbo_id);
glEnableVertexAttribArray(3);
glEnableVertexAttribArray(4);
}
@ -234,8 +238,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
);
}
// if (!skinned)
//{
if (!batch.index_data.empty())
{
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batch.gl_ibo_id);
@ -245,12 +247,6 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
{
glDrawArrays(GL_TRIANGLES, 0, batch.vertex_data.size());
}
//}
// else
//{
// // glDrawElementsBaseVertex(GL_TRIANGLES, batch.index_data.size(), GL_UNSIGNED_INT, (void*)(sizeof(uint) *
//base_index), base_vertex)
//}
if (skinned)
{
@ -268,9 +264,9 @@ void Renderer3D::DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader)
glBindVertexArray(0);
}
void Renderer3D::DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader)
void Renderer3D::DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader, uint (*func_highlight)(const RenderBatch3D&))
{
DrawMesh(mesh, m.GetProjectedTransformationMatrix(*r3d_state->v, *r3d_state->p), bind_shader);
DrawMesh(mesh, m.GetProjectedTransformationMatrix(*r3d_state->v, *r3d_state->p), bind_shader, func_highlight);
}
void Renderer3D::DrawBillboard(const Texture& texture, const Vec3& position, Vec2 size, bool both_axes, float yaw)
@ -364,26 +360,20 @@ void Renderer3D::DrawModel(Model& model, const Mat4& m)
if (!mesh)
continue;
// float* data = new float[MAX_BONES*16];
for (int i = 0; i < transforms.size(); i++)
{
if (i >= MAX_BONES)
continue;
// for (int j = 0; j < 16; j++)
// data[i * 16 + j] = transforms[i].mat.data()[j];
std::string u = "u_bones[" + std::to_string(i) + "]";
// r3d_state->shader->SetUniform(u, transforms[i]);
glUniformMatrix4fv(
glGetUniformLocation(r3d_state->shader->GetGLID(), u.c_str()), 1, GL_FALSE, transforms[i].mat.data()
);
// glUniformMatrix4fv(glGetUniformLocation(r3d_state->shader->GetGLID(), "u_bones"), MAX_BONES, GL_TRUE, data);
}
if (mesh->skinnable)
r3d_state->shader->SetUniform("u_has_bones", 1);
DrawMesh(*mesh, m);
if (mesh->skinnable)
r3d_state->shader->SetUniform("u_has_bones", 0);
// delete[] data;
}
}

View file

@ -15,6 +15,7 @@ class StaticMesh;
class Texture;
class Shader;
class Model;
struct RenderBatch3D;
class Renderer3D
{
@ -22,8 +23,8 @@ public:
static void Begin(const Camera& v, const Mat4& p);
static void End();
static void DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader = true);
static void DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader = true);
static void DrawMesh(StaticMesh& mesh, const Mat4& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr);
static void DrawMesh(StaticMesh& mesh, Transform& m, bool bind_shader = true, uint (*func_highlight)(const RenderBatch3D&) = nullptr);
static void DrawBillboard(const Texture& texture, const Vec3& position, Vec2 size, bool both_axes = false, float yaw = 90.0f);
static void DrawSmartBillboard(
const std::vector<Texture*>& textures,

View file

@ -78,7 +78,7 @@ StaticMesh::~StaticMesh()
glDeleteVertexArrays(1, &m_gl_vao_id);
}
void StaticMesh::AddBatch(const Texture* texture, const std::vector<Vertex3D>& vertex_data, bool flip)
void StaticMesh::AddBatch(const Texture* texture, const std::vector<Vertex3D>& vertex_data, bool flip, std::any user_data)
{
// "flipping" the vertex data basically means changing the order of the vertices so it faces
// a different direction than it did previously, useful for making sure stuff works with culling
@ -102,6 +102,7 @@ void StaticMesh::AddBatch(const Texture* texture, const std::vector<Vertex3D>& v
// Clean me/move me somewhere else
auto& current = m_batches.back();
current.userdata = user_data;
for (size_t j = 0; j < current.vertex_data.size(); j += 3)
{
Vertex3D& v0 = current.vertex_data[j + 0];
@ -169,15 +170,19 @@ void StaticMesh::AddSkinnedBatch(
}
}
m_batches.push_back({0, texture, vertex_data, 0, flipped_data, 0, bone_data});
m_batches.push_back({0, texture, vertex_data, 0, flipped_data, bone_data});
}
// This code probably isn't good...
// Take the batches, order them by texture ID, and have one draw call per texture use.
// I might make another version of this which sets up texture atlases so that way you don't
// have to have a new VBO for every batch. You'd be rendering one VBO with different
// texture coordinates.
void StaticMesh::Finalize(NormalGenType gen_normals)
//
// Also, you may optionally provide "sort" and "criteria" callbacks to control how the mesh
// will get batched. By default, batching will be performed based on texture ID, but you can
// set up any conditions.
//
void StaticMesh::Finalize(NormalGenType gen_normals, BatchComparison sort, BatchComparison criteria)
{
std::vector<Vertex3D> total_vertices;
@ -185,7 +190,7 @@ void StaticMesh::Finalize(NormalGenType gen_normals)
std::sort(
m_batches.begin(),
m_batches.end(),
[](const RenderBatch3D& a, const RenderBatch3D& b) { return a.texture->GetGLID() < b.texture->GetGLID(); }
sort ? sort : [](const RenderBatch3D& a, const RenderBatch3D& b) { return a.texture->GetGLID() < b.texture->GetGLID(); }
);
for (size_t i = 0; i < m_batches.size(); i++)
@ -199,10 +204,18 @@ void StaticMesh::Finalize(NormalGenType gen_normals)
// If their texture has switched (or there isn't another one), split the draw call
if (auto next = std::next(m_batches.begin() + i, 1); next < m_batches.end())
{
if (criteria)
{
if (criteria(current, *next))
setup = true;
}
else
{
if (next->texture->GetGLID() != current.texture->GetGLID())
setup = true;
}
}
else
{
setup = true;

View file

@ -3,6 +3,7 @@
#include <assert.h>
#include <vector>
#include <any>
#include "KP3D_Common.h"
#include "KP3D_Math.h"
@ -56,9 +57,9 @@ struct RenderBatch3D
std::vector<Vertex3D> vertex_data;
GLuint gl_ibo_id = 0;
std::vector<uint> index_data;
GLuint gl_bbo_id = 0;
std::vector<VertexBoneData> bone_data;
bool flipped = false;
std::any userdata;
};
enum NormalGenType
@ -68,13 +69,15 @@ enum NormalGenType
GEN_SMOOTH_NORMALS
};
using BatchComparison = bool (*)(const RenderBatch3D&, const RenderBatch3D&);
class StaticMesh
{
public:
StaticMesh();
~StaticMesh();
void AddBatch(const Texture* texture, const std::vector<Vertex3D>& vertex_data, bool flip = false);
void AddBatch(const Texture* texture, const std::vector<Vertex3D>& vertex_data, bool flip = false, std::any user_data = {});
void AddIndexedBatch(const Texture* texture, const std::vector<Vertex3D>& vertex_data, const std::vector<uint>& index_data);
void AddSkinnedBatch(
const Texture* texture,
@ -83,7 +86,7 @@ public:
const std::vector<VertexBoneData>& bone_data,
bool flip = true
);
void Finalize(NormalGenType gen_normals = GEN_NORMALS);
void Finalize(NormalGenType gen_normals = GEN_NORMALS, BatchComparison sort = nullptr, BatchComparison criteria = nullptr);
void Reset();
std::vector<RenderBatch3D>& GetBatchesRef();

View file

@ -6,6 +6,7 @@
#include "KP3D_Raycast.h"
#include "KP3D_Math.h"
#include "KP3D_Geometry.h"
#include "KP3D_Console.h"
#include "Sandbox.h"
@ -51,6 +52,125 @@ void Editor::Update()
KEY_SHORTCUT(C, m_mode = MODE_SECTOR_EDIT);
if (m_mode == MODE_BUILD)
{
UpdateModeBuild();
return;
}
// Raycast through everything on the map
using namespace kp3d;
struct Target
{
Vec3 position;
float distance;
RenderBatch3D* b;
};
std::vector<Target> targets;
for (RenderBatch3D& b: sandbox->map.GetMeshRef().GetBatchesRef())
{
for (size_t i = 0; i < b.vertex_data.size(); i += 3)
{
Vec3 pos;
Triangle tri = {b.vertex_data[i].position, b.vertex_data[i + 1].position, b.vertex_data[i + 2].position};
auto ray = GetRayFromCamera(sandbox->camera);
bool raycast = RayIntersectsTriangle(ray[0], ray[1], &tri, pos);
if (raycast)
{
float dist = sqrtf(
pow(pos.x - sandbox->camera.position.x, 2) +
pow(pos.y - sandbox->camera.position.y, 2) +
pow(pos.z - sandbox->camera.position.z, 2)
);
targets.push_back({pos, dist, &b});
}
}
if (!targets.empty())
{
std::sort(targets.begin(), targets.end(), [&](const Target& a, const Target& b) { return a.distance > b.distance; });
const Target& target = targets.back();
editor_hovered_batch = target.b;
}
else
editor_hovered_batch = nullptr;
}
if (editor_hovered_batch)
{
auto info = std::any_cast<BatchSectorInfo>(editor_hovered_batch->userdata);
if (info.flat)
{
if (sandbox->IsKeyDown(KEY_PAGEUP))
{
info.flat->base_height += 0.1f;
sandbox->map.Rebuild(GEN_NORMALS);
}
if (sandbox->IsKeyDown(KEY_PAGEDOWN))
{
info.flat->base_height -= 0.1f;
sandbox->map.Rebuild(GEN_NORMALS);
}
}
}
}
void Editor::RenderMap()
{
// Render the map grid
sandbox->map.RenderGrid();
// Render the points we're drawing
if (points.size() > 1)
{
for (int i = 0; i < points.size() - 1; i++)
RenderLine(points[i], points[i + 1], 0xFF00FFFF);
}
if (points.size() > 0)
RenderLine(points.back(), m_stem_pos, 0xFFFF00FF);
// Render the "stem"
auto ray = kp3d::GetRayFromCamera(sandbox->camera);
kp3d::Vec3 pos{5,0,0};
float dist = 0.0f;
kp3d::Triangle tri0 = {{sandbox->map.grid_box[0], sandbox->map.grid_box[1], sandbox->map.grid_box[2]}, 0, 0};
kp3d::Triangle tri1 = {{sandbox->map.grid_box[3], sandbox->map.grid_box[4], sandbox->map.grid_box[5]}, 0, 0};
bool on_grid = kp3d::RayIntersectsTriangle(ray[0], ray[1], &tri0, pos) || kp3d::RayIntersectsTriangle(ray[0], ray[1], &tri1, pos);
pos.x = Align(pos.x, 1.0f);
pos.z = Align(pos.z, 1.0f);
RenderStem(pos);
m_stem_pos = pos;
}
void Editor::RenderStem(kp3d::Vec3 position)
{
using namespace kp3d;
if (m_mode != MODE_BUILD)
return;
Vec2 size = {1.0f, (float) m_stem.GetHeight() / (float) m_stem.GetWidth()};
const Camera* camera = Renderer3D::GetPrimaryCamera();
kp3d::Vec3 player_distance = position - camera->position;
float vec_distance = sqrtf(
player_distance.x * player_distance.x + player_distance.y * player_distance.y + player_distance.z * player_distance.z
);
float scale = 1.0f;
if (vec_distance > scale)
scale = vec_distance * 0.1f;
if (scale > 1.0f)
scale = 1.0f;
size.x *= scale;
size.y *= scale;
Renderer3D::DrawBillboard(m_stem, {position.x, position.y + size.y * 0.5f, position.z}, size);
}
void Editor::UpdateModeBuild()
{
if (sandbox->IsMouseButtonDown(kp3d::MOUSE_BUTTON_LEFT))
{
@ -58,15 +178,15 @@ void Editor::Update()
if (points.size() >= 3 && kp3d::PosCmp(points.back(), points.front(), 1.0f / 128.0f))// points.back() == points.front())
{
kp3d::Sector s;
s.ceiling.texture = &m_block;
s.floor.texture = &m_block;
s.floor.floor = true;
s.floor.base_height = 0.0f;
s.ceiling.base_height = 2.0f;
s.id = sandbox->map.sectors.size() + 1;
s.parent_id = 0;
s.inverted = false;
std::shared_ptr<kp3d::Sector> s = std::make_shared<kp3d::Sector>();
s->ceiling.texture = &m_block;
s->floor.texture = &m_block;
s->floor.floor = true;
s->floor.base_height = 0.0f;
s->ceiling.base_height = 2.0f;
s->id = sandbox->map.sectors.size() + 1;
s->parent_id = 0;
s->inverted = false;
for (int i = 0; i < points.size() - 1; i++)
{
kp3d::Wall wall;
@ -76,10 +196,10 @@ void Editor::Update()
for (int j = 0; j < 3; j++)
wall.textures[j] = &m_block;
s.walls.push_back(wall);
s->walls.push_back(wall);
}
sandbox->map.original_sectors.push_back(s);
sandbox->map.sectors.push_back(s);
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
points.clear();
@ -108,15 +228,15 @@ void Editor::Update()
{
if (has_start_pos)
{
kp3d::Sector s;
s.ceiling.texture = &m_block;
s.floor.texture = &m_block;
s.floor.floor = true;
s.floor.base_height = 0.0f;
s.ceiling.base_height = 2.0f;
s.id = sandbox->map.sectors.size() + 1;
s.parent_id = 0;
s.inverted = false;
std::shared_ptr<kp3d::Sector> s = std::make_shared<kp3d::Sector>();
s->ceiling.texture = &m_block;
s->floor.texture = &m_block;
s->floor.floor = true;
s->floor.base_height = 0.0f;
s->ceiling.base_height = 2.0f;
s->id = sandbox->map.sectors.size() + 1;
s->parent_id = 0;
s->inverted = false;
for (int i = 0; i < points.size() - 1; i++)
{
kp3d::Wall wall;
@ -126,67 +246,16 @@ void Editor::Update()
for (int j = 0; j < 3; j++)
wall.textures[j] = &m_block;
s.walls.push_back(wall);
s->walls.push_back(wall);
}
sandbox->map.original_sectors.push_back(s);
sandbox->map.sectors.push_back(s);
sandbox->map.Rebuild(kp3d::GEN_NORMALS);
points.clear();
has_start_pos = false;
}
}
}
}
void Editor::RenderMap()
{
// Render the map grid
sandbox->map.RenderGrid();
// Render the points we're drawing
if (points.size() > 1)
{
for (int i = 0; i < points.size() - 1; i++)
RenderLine(points[i], points[i + 1], 0xFF00FFFF);
}
if (points.size() > 0)
RenderLine(points.back(), m_stem_pos, 0xFFFF00FF);
// Render the "stem"
auto ray = kp3d::GetRayFromCamera(sandbox->camera);
kp3d::Vec3 pos{5,0,0};
float dist = 0.0f;
kp3d::Triangle tri0 = {{sandbox->map.grid_box[0], sandbox->map.grid_box[1], sandbox->map.grid_box[2]}, 0, 0};
kp3d::Triangle tri1 = {{sandbox->map.grid_box[3], sandbox->map.grid_box[4], sandbox->map.grid_box[5]}, 0, 0};
bool on_grid = kp3d::RayIntersectsTriangle(ray[0], ray[1], &tri0, pos) || kp3d::RayIntersectsTriangle(ray[0], ray[1], &tri1, pos);
pos.x = Align(pos.x, 1.0f);
pos.z = Align(pos.z, 1.0f);
RenderStem(pos);
m_stem_pos = pos;
}
void Editor::RenderStem(kp3d::Vec3 position)
{
using namespace kp3d;
Vec2 size = {1.0f, (float) m_stem.GetHeight() / (float) m_stem.GetWidth()};
const Camera* camera = Renderer3D::GetPrimaryCamera();
kp3d::Vec3 player_distance = position - camera->position;
float vec_distance = sqrtf(
player_distance.x * player_distance.x + player_distance.y * player_distance.y + player_distance.z * player_distance.z
);
float scale = 1.0f;
if (vec_distance > scale)
scale = vec_distance * 0.1f;
if (scale > 1.0f)
scale = 1.0f;
size.x *= scale;
size.y *= scale;
Renderer3D::DrawBillboard(m_stem, {position.x, position.y + size.y * 0.5f, position.z}, size);
}
void Editor::RenderUI()
{
@ -199,11 +268,14 @@ void Editor::RenderUI()
}
if (ImGui::BeginMenu("Edit"))
{
if (ImGui::MenuItem("Undo")) {}
if (ImGui::MenuItem("Redo")) {}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("View"))
{
ImGui::Checkbox("Info overlay", &show_info_overlay);
ImGui::Checkbox("Console", &kp3d::console::open);
ImGui::EndMenu();
}
ImGui::EndMainMenuBar();

View file

@ -21,6 +21,8 @@ public:
void RenderMap();
void RenderStem(kp3d::Vec3 position);
void UpdateModeBuild();
void RenderModeBuild();
void RenderModeSectorEdit();

View file

@ -16,6 +16,7 @@ Sandbox::Sandbox(const std::string& path):
kp3d::Game(path, "sandbox-cfg.json", "sandbox-log.txt")
{
tex.Load("logo.png");
crosshair.Load(".kp3d/crosshair.png");
m_projection.InitPerspective(70.0f, (float) GetWidth() / (float) GetHeight());
map.Init();
@ -134,6 +135,11 @@ void Sandbox::Render()
kp3d::Renderer2D::Begin();
for (auto& p : points)
kp3d::Renderer2D::DrawTexture(tex, p.x, p.y, 50, 50);
kp3d::Renderer2D::DrawTexture(
crosshair,
(float) GetWidth() * 0.5f - (float) crosshair.GetWidth() * 0.5f,
(float) GetHeight() * 0.5f - (float) crosshair.GetHeight() * 0.5f
);
kp3d::Renderer2D::End();
if (m_mode == MODE_EDIT)

View file

@ -32,6 +32,7 @@ public:
kp3d::Map map;
Editor editor;
kp3d::Camera camera;
kp3d::Texture crosshair;
private:
// KP3D essentials