Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Univerxel
Univerxel
Commits
f7b34f74
Commit
f7b34f74
authored
Aug 03, 2020
by
Shu
🍠
Browse files
Area position
parent
5c6ccd48
Changes
18
Hide whitespace changes
Inline
Side-by-side
src/contouring/Abstract.hpp
View file @
f7b34f74
...
...
@@ -18,10 +18,11 @@ namespace contouring {
virtual
void
update
(
const
voxel_pos
&
pos
,
const
world
::
area_map
&
areas
)
=
0
;
/// Chunk data change
virtual
void
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
,
geometry
::
Faces
neighbors
)
=
0
;
/// @param offset priority position offset
virtual
void
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
,
geometry
::
Faces
neighbors
)
=
0
;
/// Chunk existante ping
/// @note notify for chunks entering view while moving
virtual
void
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
)
=
0
;
virtual
void
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
)
=
0
;
/// Display ImGui config
virtual
void
onGui
()
=
0
;
/// Get options
...
...
src/contouring/AbstractFlat.cpp
View file @
f7b34f74
...
...
@@ -3,34 +3,40 @@
#include
<imgui.h>
// NOLINT
#include
<toml.h>
#include
"../world/Chunk.hpp"
#include
"../world/Area.hpp"
namespace
contouring
{
void
AbstractFlat
::
update
(
const
voxel_pos
&
pos
,
const
world
::
area_map
&
areas
)
{
center
=
glm
::
divide
(
pos
)
;
size_t
AbstractFlat
::
clear
(
const
voxel_pos
&
pos
,
const
world
::
area_map
&
areas
)
{
size_t
buffer_count
=
0
;
auto
it_a
=
buffers
.
begin
();
while
(
it_a
!=
buffers
.
end
())
{
// Remove out of range buffers
if
(
const
auto
area
=
areas
.
find
(
it_a
->
first
);
area
!=
areas
.
end
())
{
//Update
auto
it
=
it_a
->
second
.
begin
();
while
(
it
!=
it_a
->
second
.
end
())
{
if
(
inKeepRange
(
it
->
first
/*TODO: + area.second->getPosition() */
))
{
++
it
;
}
else
{
const
auto
&
offset
=
it_a
->
second
.
first
=
area
->
second
->
getOffset
();
const
auto
center
=
glm
::
divide
(
pos
-
offset
);
auto
&
bfs
=
it_a
->
second
.
second
;
auto
it
=
bfs
.
begin
();
while
(
it
!=
bfs
.
end
())
{
if
(
glm
::
length2
(
center
-
it
->
first
)
>
glm
::
pow2
(
keepDistance
))
{
if
(
it
->
second
!=
NULL
)
delete
it
->
second
;
it
=
it_a
->
second
.
erase
(
it
);
it
=
bfs
.
erase
(
it
);
}
else
{
buffer_count
++
;
++
it
;
}
}
++
it_a
;
}
else
{
for
(
auto
&
buffer
:
it_a
->
second
)
{
for
(
auto
&
buffer
:
it_a
->
second
.
second
)
{
if
(
buffer
.
second
!=
NULL
)
delete
buffer
.
second
;
}
it_a
=
buffers
.
erase
(
it_a
);
}
}
return
buffer_count
;
}
AbstractFlat
::
AbstractFlat
(
const
std
::
string
&
str
)
:
Abstract
()
{
...
...
@@ -54,9 +60,9 @@ namespace contouring {
void
AbstractFlat
::
getModels
(
std
::
vector
<
std
::
pair
<
glm
::
mat4
,
buffer
::
Abstract
*
const
>>
&
out
,
const
std
::
optional
<
geometry
::
Frustum
>
&
frustum
,
const
glm
::
llvec3
&
offset
,
int
density
)
{
const
auto
scaling
=
glm
::
scale
(
glm
::
mat4
(
1
),
glm
::
vec3
(
1.
f
/
density
));
for
(
const
auto
[
_
,
bfs
]
:
buffers
)
{
for
(
const
auto
[
pos
,
buffer
]
:
bfs
)
{
const
glm
::
vec3
fPos
=
glm
::
vec3
(
glm
::
multiply
(
pos
/*TODO: + area.position*/
)
-
offset
*
glm
::
llvec3
(
density
))
/
glm
::
vec3
(
density
);
for
(
const
auto
[
_
,
area
]
:
buffers
)
{
for
(
const
auto
[
pos
,
buffer
]
:
area
.
second
)
{
const
glm
::
vec3
fPos
=
glm
::
vec3
(
area
.
first
+
glm
::
multiply
(
pos
)
-
offset
*
glm
::
llvec3
(
density
))
/
glm
::
vec3
(
density
);
if
(
buffer
!=
NULL
&&
(
!
frustum
.
has_value
()
||
frustum
.
value
().
contains
(
geometry
::
Box
::
fromMin
(
fPos
,
glm
::
vec3
(
CHUNK_LENGTH
/
(
float
)
density
)))))
out
.
emplace_back
(
glm
::
translate
(
scaling
,
fPos
*
(
float
)
density
),
buffer
);
}}
...
...
src/contouring/AbstractFlat.hpp
View file @
f7b34f74
...
...
@@ -10,9 +10,6 @@ namespace contouring {
AbstractFlat
(
const
std
::
string
&
str
);
virtual
~
AbstractFlat
()
{}
/// Each frame ping. Used to clear out of range
void
update
(
const
voxel_pos
&
,
const
world
::
area_map
&
areas
)
override
;
/// Display ImGui config
void
onGui
()
override
;
...
...
@@ -23,16 +20,10 @@ namespace contouring {
void
getModels
(
std
::
vector
<
std
::
pair
<
glm
::
mat4
,
buffer
::
Abstract
*
const
>>
&
out
,
const
std
::
optional
<
geometry
::
Frustum
>
&
frustum
,
const
glm
::
llvec3
&
offset
,
int
density
)
override
;
protected:
bool
inline
inLoadRange
(
const
chunk_pos
&
point
)
const
{
return
glm
::
length2
(
center
-
point
)
<=
loadDistance
*
loadDistance
;
}
bool
inline
inKeepRange
(
const
chunk_pos
&
point
)
const
{
return
glm
::
length2
(
center
-
point
)
<=
keepDistance
*
keepDistance
;
}
size_t
clear
(
const
voxel_pos
&
,
const
world
::
area_map
&
areas
);
//MAYBE: store position copy
robin_hood
::
unordered_flat_map
<
area_id
,
robin_hood
::
unordered_flat_map
<
chunk_pos
,
buffer
::
Abstract
*>>
buffers
;
chunk_pos
center
=
chunk_pos
(
INT_MAX
);
robin_hood
::
unordered_flat_map
<
area_id
,
robin_hood
::
pair
<
voxel_pos
,
robin_hood
::
unordered_flat_map
<
chunk_pos
,
buffer
::
Abstract
*>>>
buffers
;
int
loadDistance
=
3
;
int
keepDistance
=
4
;
...
...
src/contouring/Dummy.hpp
View file @
f7b34f74
...
...
@@ -10,8 +10,8 @@ namespace contouring {
virtual
~
Dummy
()
{
}
void
update
(
const
voxel_pos
&
,
const
world
::
area_map
&
)
override
{}
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
{}
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
)
override
{}
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
{}
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
)
override
{}
void
onGui
()
override
{
}
std
::
string
getOptions
()
override
{
return
""
;
}
void
getModels
(
std
::
vector
<
std
::
pair
<
glm
::
mat4
,
buffer
::
Abstract
*
const
>>
&
,
const
std
::
optional
<
geometry
::
Frustum
>&
,
const
glm
::
llvec3
&
,
int
)
override
{
}
...
...
src/contouring/FlatDualMC.cpp
View file @
f7b34f74
...
...
@@ -49,9 +49,9 @@ namespace contouring {
return
ss
.
str
();
}
void
FlatDualMC
::
enqueue
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
)
{
void
FlatDualMC
::
enqueue
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
)
{
rmt_ScopedCPUSample
(
EnqueueContouring
,
RMTSF_Aggregate
);
const
auto
dist2
=
glm
::
length2
(
center
-
pos
.
second
);
//TODO: - area.pos
const
auto
dist2
=
glm
::
length2
(
offset
-
pos
.
second
);
if
(
dist2
<=
loadDistance
*
loadDistance
)
{
surrounding
::
corners
surrounding
;
if
(
surrounding
::
load
(
surrounding
,
pos
.
second
,
data
))
{
...
...
@@ -60,31 +60,30 @@ namespace contouring {
}
}
void
FlatDualMC
::
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
,
geometry
::
Faces
neighbors
)
{
enqueue
(
pos
,
data
);
void
FlatDualMC
::
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
,
geometry
::
Faces
neighbors
)
{
enqueue
(
pos
,
offset
,
data
);
if
(
neighbors
&&
(
geometry
::
Faces
::
Left
|
geometry
::
Faces
::
Down
|
geometry
::
Faces
::
Backward
))
{
for
(
size_t
i
=
1
;
i
<
8
;
i
++
)
{
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
-
surrounding
::
g_corner_offsets
[
i
]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
-
surrounding
::
g_corner_offsets
[
i
]),
offset
,
data
);
}
}
}
void
FlatDualMC
::
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
)
{
void
FlatDualMC
::
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
)
{
const
auto
it
=
buffers
.
find
(
pos
.
first
);
if
(
it
==
buffers
.
end
()
||
it
->
second
.
find
(
pos
.
second
)
==
it
->
second
.
end
())
{
enqueue
(
pos
,
data
);
if
(
it
==
buffers
.
end
()
||
it
->
second
.
second
.
find
(
pos
.
second
)
==
it
->
second
.
second
.
end
())
{
enqueue
(
pos
,
offset
,
data
);
}
}
void
FlatDualMC
::
update
(
const
voxel_pos
&
pos
,
const
world
::
area_map
&
areas
)
{
AbstractFlat
::
update
(
pos
,
areas
);
std
::
pair
<
area_
<
chunk_pos
>
,
buffer
::
ShortIndexed
::
Data
>
out
;
reports
.
load
.
push
(
loadQueue
.
size
());
//MAYBE: clear out of range loadQueue.trim(keepDistance * keepDistance)
reports
.
loaded
.
push
(
loadedQueue
.
size
());
while
(
loadedQueue
.
pop
(
out
))
{
const
auto
buffer
=
new
buffer
::
ShortIndexed
(
GL_TRIANGLES
,
out
.
second
);
auto
&
bfs
=
buffers
[
out
.
first
.
first
]
;
auto
&
bfs
=
buffers
[
out
.
first
.
first
]
.
second
;
//NOTE: buffer.first uninitialized (will be set in clear())
if
(
const
auto
it
=
bfs
.
find
(
out
.
first
.
second
);
it
!=
bfs
.
end
())
{
if
(
it
->
second
!=
NULL
)
delete
it
->
second
;
...
...
@@ -94,7 +93,8 @@ namespace contouring {
bfs
.
emplace
(
out
.
first
.
second
,
buffer
);
}
}
reports
.
count
.
push
(
buffers
.
size
());
//FIXME: get from AbstractFlat
size_t
count
=
AbstractFlat
::
clear
(
pos
,
areas
);
reports
.
count
.
push
(
count
);
}
void
FlatDualMC
::
onGui
()
{
...
...
src/contouring/FlatDualMC.hpp
View file @
f7b34f74
...
...
@@ -26,10 +26,10 @@ namespace contouring {
std
::
string
getOptions
()
override
;
/// Chunk data change
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
;
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
;
/// Chunk existante ping
/// @note notify for chunks entering view while moving
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
)
override
;
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
)
override
;
protected:
safe_priority_queue_map
<
area_
<
chunk_pos
>
,
surrounding
::
corners
,
int
,
area_hash
>
loadQueue
;
...
...
@@ -44,7 +44,7 @@ namespace contouring {
bool
running
=
true
;
std
::
vector
<
std
::
thread
>
workers
;
void
enqueue
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
);
void
enqueue
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
);
float
iso
=
.1
f
;
bool
manifold
=
true
;
...
...
src/contouring/FlatSurroundingBox.cpp
View file @
f7b34f74
...
...
@@ -36,9 +36,9 @@ namespace contouring {
}
}
void
FlatSurroundingBox
::
enqueue
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
)
{
void
FlatSurroundingBox
::
enqueue
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
)
{
rmt_ScopedCPUSample
(
EnqueueContouring
,
RMTSF_Aggregate
);
const
auto
dist2
=
glm
::
length2
(
center
-
pos
.
second
/*TODO: - area.pos */
);
const
auto
dist2
=
glm
::
length2
(
offset
-
pos
.
second
);
if
(
dist2
<=
loadDistance
*
loadDistance
)
{
surrounding
::
faces
surrounding
;
if
(
surrounding
::
load
(
surrounding
,
pos
.
second
,
data
))
{
...
...
@@ -47,43 +47,42 @@ namespace contouring {
}
}
void
FlatSurroundingBox
::
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
,
Faces
neighbors
)
{
enqueue
(
pos
,
data
);
void
FlatSurroundingBox
::
onUpdate
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
,
Faces
neighbors
)
{
enqueue
(
pos
,
offset
,
data
);
if
(
neighbors
&&
Faces
::
Right
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Right
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Right
)]),
offset
,
data
);
if
(
neighbors
&&
Faces
::
Left
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Left
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Left
)]),
offset
,
data
);
if
(
neighbors
&&
Faces
::
Up
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Up
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Up
)]),
offset
,
data
);
if
(
neighbors
&&
Faces
::
Down
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Down
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Down
)]),
offset
,
data
);
if
(
neighbors
&&
Faces
::
Forward
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Forward
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Forward
)]),
offset
,
data
);
if
(
neighbors
&&
Faces
::
Backward
)
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Backward
)]),
data
);
enqueue
(
std
::
make_pair
(
pos
.
first
,
pos
.
second
+
g_face_offsets
[
static_cast
<
int
>
(
Face
::
Backward
)]),
offset
,
data
);
}
void
FlatSurroundingBox
::
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
world
::
ChunkContainer
&
data
)
{
void
FlatSurroundingBox
::
onNotify
(
const
area_
<
chunk_pos
>
&
pos
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
data
)
{
const
auto
it
=
buffers
.
find
(
pos
.
first
);
if
(
it
==
buffers
.
end
()
||
it
->
second
.
find
(
pos
.
second
)
==
it
->
second
.
end
())
{
enqueue
(
pos
,
data
);
if
(
it
==
buffers
.
end
()
||
it
->
second
.
second
.
find
(
pos
.
second
)
==
it
->
second
.
second
.
end
())
{
enqueue
(
pos
,
offset
,
data
);
}
}
void
FlatSurroundingBox
::
update
(
const
voxel_pos
&
pos
,
const
world
::
area_map
&
areas
)
{
AbstractFlat
::
update
(
pos
,
areas
);
std
::
pair
<
area_
<
chunk_pos
>
,
buffer
::
ShortIndexed
::
Data
>
out
;
reports
.
load
.
push
(
loadQueue
.
size
());
//MAYBE: clear out of range loadQueue.trim(keepDistance * keepDistance)
reports
.
loaded
.
push
(
loadedQueue
.
size
());
while
(
loadedQueue
.
pop
(
out
))
{
const
auto
buffer
=
new
buffer
::
ShortIndexed
(
GL_TRIANGLES
,
out
.
second
);
auto
&
bfs
=
buffers
[
out
.
first
.
first
]
;
auto
&
bfs
=
buffers
[
out
.
first
.
first
]
.
second
;
//NOTE: buffer.first uninitialized
if
(
const
auto
it
=
bfs
.
find
(
out
.
first
.
second
);
it
!=
bfs
.
end
())
{
if
(
it
->
second
!=
NULL
)
delete
it
->
second
;
...
...
@@ -93,7 +92,8 @@ namespace contouring {
bfs
.
emplace
(
out
.
first
.
second
,
buffer
);
}
}
reports
.
count
.
push
(
buffers
.
size
());
//FIXME: get from AbstractFlat
size_t
count
=
AbstractFlat
::
clear
(
pos
,
areas
);
reports
.
count
.
push
(
count
);
}
void
FlatSurroundingBox
::
onGui
()
{
...
...
src/contouring/FlatSurroundingBox.hpp
View file @
f7b34f74
...
...
@@ -24,10 +24,10 @@ namespace contouring {
void
onGui
()
override
;
/// Chunk data change
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
;
void
onUpdate
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
,
geometry
::
Faces
)
override
;
/// Chunk existante ping
/// @note notify for chunks entering view while moving
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
)
override
;
void
onNotify
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
,
const
world
::
ChunkContainer
&
)
override
;
protected:
safe_priority_queue_map
<
area_
<
chunk_pos
>
,
surrounding
::
faces
,
int
,
area_hash
>
loadQueue
;
...
...
@@ -42,7 +42,7 @@ namespace contouring {
bool
running
=
true
;
std
::
vector
<
std
::
thread
>
workers
;
void
enqueue
(
const
area_
<
chunk_pos
>
&
,
const
world
::
ChunkContainer
&
);
void
enqueue
(
const
area_
<
chunk_pos
>
&
,
const
chunk_pos
&
offset
,
const
world
::
ChunkContainer
&
);
private:
static
inline
bool
isTransparent
(
const
surrounding
::
faces
&
surrounding
,
const
std
::
pair
<
ushort
,
ushort
>
&
idx
);
...
...
src/data/geometry/Box.hpp
View file @
f7b34f74
#pragma once
#include
<glm/glm.hpp>
#include
<iostream>
namespace
geometry
{
/// Axis Aligned Floating Box
...
...
src/data/geometry/IBox.hpp
0 → 100644
View file @
f7b34f74
#pragma once
#include
<glm/glm.hpp>
namespace
geometry
{
/// Axis Aligned Long Box
struct
IBox
{
using
pos_t
=
glm
::
llvec3
;
enum
class
ContainmentType
{
Disjoint
=
false
,
Intersects
,
Contains
};
IBox
(
pos_t
min
,
pos_t
max
)
:
Min
(
min
),
Max
(
max
)
{
assert
((
max
.
x
>=
min
.
x
&&
max
.
y
>=
min
.
y
&&
max
.
z
>=
min
.
z
)
&&
"Min > Max"
);
}
inline
static
IBox
fromCenter
(
pos_t
center
,
pos_t
::
value_type
radius
)
{
return
IBox
(
center
-
radius
,
center
+
radius
);
}
inline
static
IBox
fromMin
(
pos_t
min
,
pos_t
size
)
{
return
IBox
(
min
,
min
+
size
);
}
pos_t
Min
;
pos_t
Max
;
ContainmentType
contains
(
const
IBox
&
box
)
const
{
//test if all corner is in the same side of a face by just checking min and max
if
(
box
.
Max
.
x
<
Min
.
x
||
box
.
Min
.
x
>
Max
.
x
||
box
.
Max
.
y
<
Min
.
y
||
box
.
Min
.
y
>
Max
.
y
||
box
.
Max
.
z
<
Min
.
z
||
box
.
Min
.
z
>
Max
.
z
)
return
ContainmentType
::
Disjoint
;
if
(
box
.
Min
.
x
>=
Min
.
x
&&
box
.
Max
.
x
<=
Max
.
x
&&
box
.
Min
.
y
>=
Min
.
y
&&
box
.
Max
.
y
<=
Max
.
y
&&
box
.
Min
.
z
>=
Min
.
z
&&
box
.
Max
.
z
<=
Max
.
z
)
return
ContainmentType
::
Contains
;
return
ContainmentType
::
Intersects
;
}
constexpr
bool
contains
(
const
pos_t
&
pos
)
const
{
return
pos
.
x
>=
Min
.
x
&&
pos
.
x
<=
Max
.
x
&&
pos
.
y
>=
Min
.
y
&&
pos
.
y
<=
Max
.
y
&&
pos
.
z
>=
Min
.
z
&&
pos
.
z
<=
Max
.
z
;
}
};
}
\ No newline at end of file
src/data/geometry/Ray.hpp
View file @
f7b34f74
#pragma once
#include
"Box.hpp"
#include
"
I
Box.hpp"
#include
"../../world/position.h"
namespace
geometry
{
...
...
@@ -83,5 +83,44 @@ namespace geometry {
}
points
.
push_back
(
current
);
}
IBox
::
ContainmentType
intersect
(
const
IBox
&
box
)
const
{
const
glm
::
llvec3
start
=
from
.
as_voxel
();
if
(
box
.
contains
(
start
))
return
IBox
::
ContainmentType
::
Contains
;
const
auto
inv
=
1.
/
glm
::
dvec3
(
dir
);
glm
::
f64
tmin
=
((
inv
.
x
<
0
?
box
.
Max
:
box
.
Min
).
x
-
start
.
x
)
*
inv
.
x
;
glm
::
f64
tmax
=
((
inv
.
x
<
0
?
box
.
Min
:
box
.
Max
).
x
-
start
.
x
)
*
inv
.
x
;
glm
::
f64
tymin
=
((
inv
.
y
<
0
?
box
.
Max
:
box
.
Min
).
y
-
start
.
y
)
*
inv
.
y
;
glm
::
f64
tymax
=
((
inv
.
y
<
0
?
box
.
Min
:
box
.
Max
).
y
-
start
.
y
)
*
inv
.
y
;
if
((
tmin
>
tymax
)
||
(
tymin
>
tmax
)){
return
IBox
::
ContainmentType
::
Disjoint
;
}
if
(
tymin
>
tmin
)
{
tmin
=
tymin
;
}
if
(
tymax
<
tmax
){
tmax
=
tymax
;
}
glm
::
f64
tzmin
=
((
inv
.
z
<
0
?
box
.
Max
:
box
.
Min
).
z
-
start
.
z
)
*
inv
.
z
;
glm
::
f64
tzmax
=
((
inv
.
z
<
0
?
box
.
Min
:
box
.
Max
).
z
-
start
.
z
)
*
inv
.
z
;
if
((
tmin
>
tzmax
)
||
(
tzmin
>
tmax
)){
return
IBox
::
ContainmentType
::
Disjoint
;
}
if
(
tzmin
>
tmin
){
tmin
=
tzmin
;
}
if
(
tzmax
<
tmax
){
tmax
=
tzmax
;
}
// this last check is different from the 'ray' case in below references:
// we need to check that the segment is on the span of the line
// that intersects the box
return
tmax
<
0.0
f
||
tmin
>
1.0
f
?
IBox
::
ContainmentType
::
Intersects
:
IBox
::
ContainmentType
::
Disjoint
;
}
};
}
src/data/math.hpp
View file @
f7b34f74
...
...
@@ -7,9 +7,12 @@ namespace glm {
constexpr
ivec3
inline
iround
(
const
vec3
&
p
)
{
return
ivec3
(
std
::
round
<
int
>
(
p
.
x
),
std
::
round
<
int
>
(
p
.
y
),
std
::
round
<
int
>
(
p
.
z
));
}
constexpr
int
inline
length2
(
const
ivec3
&
a
)
{
constexpr
long
inline
length2
(
const
ivec3
&
a
)
{
return
a
.
x
*
a
.
x
+
a
.
y
*
a
.
y
+
a
.
z
*
a
.
z
;
}
constexpr
long
inline
pow2
(
int
v
)
{
return
v
*
v
;
}
constexpr
ivec3
inline
diff
(
const
ivec3
&
a
,
const
ivec3
&
b
)
{
return
glm
::
abs
(
glm
::
abs
(
a
)
-
glm
::
abs
(
b
));
}
...
...
src/main.cpp
View file @
f7b34f74
...
...
@@ -100,9 +100,9 @@ int main(int /*unused*/, char */*unused*/[]){
state
.
look_at
=
world
.
raycast
(
camera
.
getRay
()
*
options
.
voxel_density
);
if
(
state
.
capture_mouse
&&
state
.
look_at
.
has_value
())
{
if
(
inputs
.
isPressing
(
Mouse
::
Left
))
world
.
setCube
(
state
.
look_at
.
value
().
first
,
world
::
Voxel
(
0
),
options
.
tool
.
radius
);
world
.
setCube
(
state
.
look_at
.
value
().
pos
,
world
::
Voxel
(
0
),
options
.
tool
.
radius
);
else
if
(
inputs
.
isPressing
(
Mouse
::
Right
))
world
.
setCube
(
state
.
look_at
.
value
().
first
,
world
::
Voxel
(
options
.
tool
.
material
,
world
::
Voxel
::
DENSITY_MAX
),
options
.
tool
.
radius
);
world
.
setCube
(
state
.
look_at
.
value
().
pos
,
world
::
Voxel
(
options
.
tool
.
material
,
world
::
Voxel
::
DENSITY_MAX
),
options
.
tool
.
radius
);
}
world
.
update
((
state
.
position
*
options
.
voxel_density
).
as_voxel
(),
reports
.
world
);
inputs
.
saveKeys
();
...
...
@@ -171,7 +171,7 @@ int main(int /*unused*/, char */*unused*/[]){
if
(
state
.
look_at
.
has_value
())
{
lookProgram
->
useIt
();
lookProgram
->
start
(
renderer
);
const
auto
model
=
glm
::
scale
(
glm
::
translate
(
glm
::
scale
(
glm
::
mat4
(
1
),
1.
f
/
glm
::
vec3
(
options
.
voxel_density
)),
glm
::
vec3
(
state
.
look_at
.
value
().
first
.
second
-
offset
*
glm
::
llvec3
(
options
.
voxel_density
))
-
glm
::
vec3
(
.5
+
options
.
tool
.
radius
)),
glm
::
vec3
(
1
+
options
.
tool
.
radius
*
2
));
const
auto
model
=
glm
::
scale
(
glm
::
translate
(
glm
::
scale
(
glm
::
mat4
(
1
),
1.
f
/
glm
::
vec3
(
options
.
voxel_density
)),
glm
::
vec3
(
state
.
look_at
.
value
().
pos
.
second
+
state
.
look_at
.
value
().
offset
-
offset
*
glm
::
llvec3
(
options
.
voxel_density
))
-
glm
::
vec3
(
.5
+
options
.
tool
.
radius
)),
glm
::
vec3
(
1
+
options
.
tool
.
radius
*
2
));
lookBuffer
.
draw
(
lookProgram
->
setup
(
renderer
,
model
));
}
renderer
->
postProcess
();
...
...
src/render/UI.cpp
View file @
f7b34f74
...
...
@@ -166,8 +166,11 @@ UI::Actions UI::draw(options &options, state &state, const reports &reports, GLu
if
(
options
.
editor_show
)
{
ImGui
::
Begin
(
"Editor"
,
&
options
.
editor_show
,
ImGuiWindowFlags_AlwaysAutoResize
);
if
(
state
.
look_at
.
has_value
())
{
ImGui
::
Text
(
"Look at: (%ld: %lld, %lld, %lld) (%s, %.1f)"
,
state
.
look_at
.
value
().
first
.
first
,
state
.
look_at
.
value
().
first
.
second
.
x
,
state
.
look_at
.
value
().
first
.
second
.
y
,
state
.
look_at
.
value
().
first
.
second
.
z
,
world
::
materials
::
textures
[
state
.
look_at
.
value
().
second
.
material
()].
c_str
(),
state
.
look_at
.
value
().
second
.
density
()
*
1.
/
world
::
Voxel
::
DENSITY_MAX
);
ImGui
::
Text
(
"(%.3f, %.3f, %.3f)"
,
state
.
look_at
.
value
().
first
.
second
.
x
*
1.
/
options
.
voxel_density
,
state
.
look_at
.
value
().
first
.
second
.
y
*
1.
/
options
.
voxel_density
,
state
.
look_at
.
value
().
first
.
second
.
z
*
1.
/
options
.
voxel_density
);
const
auto
&
look
=
state
.
look_at
.
value
();
ImGui
::
Text
(
"Look at: (%ld: %lld, %lld, %lld) (%s, %.1f)"
,
look
.
pos
.
first
,
look
.
pos
.
second
.
x
,
look
.
pos
.
second
.
y
,
look
.
pos
.
second
.
z
,
world
::
materials
::
textures
[
look
.
value
.
material
()].
c_str
(),
look
.
value
.
density
()
*
1.
/
world
::
Voxel
::
DENSITY_MAX
);
const
auto
w_pos
=
look
.
pos
.
second
+
look
.
offset
;
ImGui
::
Text
(
"(%.3f, %.3f, %.3f)"
,
w_pos
.
x
*
1.
/
options
.
voxel_density
,
w_pos
.
y
*
1.
/
options
.
voxel_density
,
w_pos
.
z
*
1.
/
options
.
voxel_density
);
}
else
{
ImGui
::
Text
(
"Look at: none"
);
}
...
...
src/state.h
View file @
f7b34f74
...
...
@@ -107,7 +107,7 @@ struct options {
{
"mode"
,
contouring
::
names
[
contouring_idx
]},
{
"options"
,
toml
::
table
()}
}));
for
(
auto
opt
:
contouring_data
)
{
for
(
const
auto
opt
:
contouring_data
)
{
if
(
!
opt
.
second
.
empty
())
config
[
"mesh"
][
"options"
].
as_table
()
->
insert_or_assign
(
opt
.
first
,
opt
.
second
);
}
...
...
@@ -181,7 +181,7 @@ struct options {
struct
state
{
bool
capture_mouse
=
true
;
camera_pos
position
=
camera_pos
(
voxel_pos
(
0
),
1
);
std
::
optional
<
std
::
pair
<
area_
<
voxel_pos
>
,
world
::
Voxel
>
>
look_at
=
{};
std
::
optional
<
world
::
Universe
::
ray_target
>
look_at
=
{};
std
::
shared_ptr
<
contouring
::
Abstract
>
contouring
;
...
...
src/world/Area.hpp
View file @
f7b34f74
...
...
@@ -5,6 +5,7 @@
using
namespace
libguarded
;
#include
"region/index.hpp"
#include
"Generator.hpp"
#include
"../data/geometry/IBox.hpp"
namespace
world
{
/// Chunk map with restricted access
...
...
@@ -13,8 +14,10 @@ namespace world {
int
radius
;
public:
/// Area radius in chunks
constexpr
inline
int
getRadius
()
const
{
return
radius
;
}
ChunkContainer
(
int
radius
)
:
radius
(
radius
)
{
assert
(
radius
<
(
1
<<
22
)
/
CHUNK_LENGTH
);
assert
(
radius
>
0
&&
radius
<
(
1
<<
22
)
/
CHUNK_LENGTH
);
}
inline
bool
inRange
(
const
chunk_pos
&
pos
)
const
{
return
glm
::
abs
(
pos
.
x
)
<
radius
&&
glm
::
abs
(
pos
.
y
)
<
radius
&&
glm
::
abs
(
pos
.
z
)
<
radius
;
...
...
@@ -29,16 +32,32 @@ namespace world {
using
regions_t
=
robin_hood
::
unordered_map
<
region_pos
,
std
::
shared_ptr
<
Region
>>
;
/// radius: size in chunk (length = radius * 2 + 1)
Area
(
int
radius
,
int
seed
=
42
)
:
chunks
(
radius
),
generator
(
seed
)
{
}
Area
(
const
voxel_pos
&
center
,
int
radius
,
int
seed
=
42
)
:
center
(
center
),
chunks
(
radius
),
generator
(
seed
)
{
}
inline
const
voxel_pos
&
getOffset
()
const
{
return
center
;
}
inline
geometry
::
IBox
getBounding
()
const
{
return
geometry
::
IBox
(
center
-
voxel_pos
(
CHUNK_LENGTH
*
(
chunks
.
getRadius
()
-
1
)),
center
+
voxel_pos
(
CHUNK_LENGTH
*
chunks
.
getRadius
()));
}
/// Move offset return if chunk_change
constexpr
bool
inline
move
(
const
voxel_pos
&
offset
)
{
const
auto
prev
=
glm
::
divide
(
center
);
center
+=
offset
;
return
prev
!=
glm
::
divide
(
center
);
}
inline
const
ChunkContainer
&
getChunks
()
const
{
return
chunks
;
}
inline
ChunkContainer
&
setChunks
()
{
return
chunks
;
}
std
::
shared_ptr
<
Region
>
getRegion
(
const
std
::
string
&
folderPath
,
const
area_
<
region_pos
>
&
);
shared_guarded
<
regions_t
>::
handle
getRegions
()
{
return
regions
.
lock
();
}
inline
Generator
&
getGenerator
()
{
return
generator
;
}
private:
//TODO: position rotation
voxel_pos
center
;
//TODO: rotation
ChunkContainer
chunks
;
shared_guarded
<
regions_t
>
regions
;
...
...
src/world/Universe.cpp
View file @
f7b34f74
...
...
@@ -21,8 +21,8 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
running
=
true
;
std
::
filesystem
::
create_directories
(
folderPath
);
areas
.
emplace
(
MAIN_AREA
,
std
::
make_shared
<
Area
>
(
1
<<
2
));
areas
.
emplace
(
2
,
std
::
make_shared
<
Area
>
(
1
<<
2
,
43
));
areas
.
emplace
(
MAIN_AREA
,
std
::
make_shared
<
Area
>
(
glm
::
multiply
(
chunk_pos
(
1
<<
8
,
0
,
0
)),
1
<<
2
0
));
areas
.
emplace
(
2
,
std
::
make_shared
<
Area
>
(
voxel_pos
(
0
),
1
<<
2
0
));
// Load workers
for
(
size_t
i
=
0
;
i
<
4
;
i
++
)
{
...
...
@@ -73,18 +73,19 @@ Universe::Universe(const Universe::options &options): dicts("content/zstd.dict"
}
}
Universe
::~
Universe
()
{
contouring
=
NULL
;
contouring
=
nullptr
;
// Save all
for
(
auto
&
area
:
areas
)
{
for
(
auto
&
chunk
:
area
.
second
->
getChunks
())
for
(
const
auto
&
chunk
:
area
.
second
->
getChunks
())
saveQueue
.
emplace
(
area
,
chunk
);
}