Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
GameDevWeek
Sommersemester 2019
Cpp
PhaseShifter
Commits
03be0527
Commit
03be0527
authored
Sep 18, 2019
by
Georg Schäfer
Browse files
Add ray level intersection.
parent
f3fde2ae
Pipeline
#3252
failed with stage
in 1 minute and 47 seconds
Changes
6
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/level/level.cpp
View file @
03be0527
...
...
@@ -3,7 +3,7 @@
#include
<sstream>
namespace
phase_shifter
::
level
{
Level
::
Level
(
Tileset_ptr
tileset
,
vector_2d
<
char
>
tiles
)
:
_
tileset
(
tileset
),
_
tiles
(
tiles
)
{}
Level
::
Level
(
Tileset_ptr
tileset
,
vector_2d
<
char
>
tiles
)
:
tileset
(
tileset
),
tiles
(
tiles
)
{}
}
// namespace phase_shifter::level
namespace
mirrage
::
asset
{
...
...
src/level/level.hpp
View file @
03be0527
...
...
@@ -25,19 +25,14 @@ namespace phase_shifter::level {
using
Tileset_ptr
=
mirrage
::
asset
::
Ptr
<
Tileset
>
;
class
Level
{
friend
class
Level_system
;
public:
struct
Level
{
template
<
typename
T
>
using
vector_2d
=
std
::
vector
<
std
::
vector
<
T
>>
;
Level
(
Tileset_ptr
tileset
,
vector_2d
<
char
>
tiles
);
private:
Tileset_ptr
_tileset
;
vector_2d
<
char
>
_tiles
;
Tileset_ptr
tileset
;
vector_2d
<
char
>
tiles
;
};
using
Level_ptr
=
mirrage
::
asset
::
Ptr
<
Level
>
;
...
...
src/level/level_system.cpp
View file @
03be0527
...
...
@@ -36,28 +36,72 @@ namespace phase_shifter::level {
});
}
auto
Level_system
::
load
(
const
std
::
string
&
name
)
->
void
{
_current_level
=
_assets
.
load
<
Level
>
(
mirrage
::
asset
::
AID
(
"level:"
+
name
));
auto
&
level
=
_current_level
.
get_blocking
();
auto
&
tiles
=
level
.
_tileset
->
tiles
;
auto
offset
=
level
.
_tileset
->
tile_size
;
glm
::
vec3
position
{
0.
f
};
for
(
auto
&&
row
:
level
.
_tiles
)
{
position
.
x
=
0.
f
;
for
(
auto
&&
tile_key
:
row
)
{
std
::
string
key
(
1
,
tile_key
);
if
(
auto
tile_it
=
tiles
.
find
(
key
);
tile_it
!=
tiles
.
end
())
{
auto
&
tile
=
tile_it
->
second
;
_entities
.
entity_builder
(
tile
.
blueprint
).
position
(
position
).
create
();
if
(
tile
.
spawn
)
{
_spawn_function
(
key
)(
tile
,
position
);
namespace
{
using
action
=
std
::
function
<
auto
(
const
Tileset
&
tileset
,
const
std
::
string
&
key
,
const
Tile
&
tile
,
const
glm
::
vec3
&
position
)
->
void
>
;
auto
for_each
(
const
Level
&
level
,
const
action
&
action
)
{
auto
&
tiles
=
level
.
tileset
->
tiles
;
auto
offset
=
level
.
tileset
->
tile_size
;
glm
::
vec3
position
{
0.
f
};
for
(
auto
&&
row
:
level
.
tiles
)
{
position
.
x
=
0.
f
;
for
(
auto
&&
tile_key
:
row
)
{
std
::
string
key
(
1
,
tile_key
);
if
(
auto
tile_it
=
tiles
.
find
(
key
);
tile_it
!=
tiles
.
end
())
{
auto
&
tile
=
tile_it
->
second
;
action
(
level
.
tileset
.
get_blocking
(),
key
,
tile
,
position
);
position
.
x
+=
offset
;
}
position
.
x
+=
offset
;
}
position
.
z
+=
offset
;
}
position
.
z
+=
offset
;
}
}
// namespace
auto
Level_system
::
load
(
const
std
::
string
&
name
)
->
void
{
_current_level
=
_assets
.
load
<
Level
>
(
mirrage
::
asset
::
AID
(
"level:"
+
name
));
auto
&
level
=
_current_level
.
get_blocking
();
for_each
(
level
,
[
&
](
auto
&
,
const
std
::
string
&
key
,
const
Tile
&
tile
,
const
glm
::
vec3
&
position
)
{
_entities
.
entity_builder
(
tile
.
blueprint
).
position
(
position
).
create
();
if
(
tile
.
spawn
)
{
_spawn_function
(
key
)(
tile
,
position
);
}
});
}
auto
Level_system
::
ray_cast
(
const
glm
::
vec2
&
origin
,
const
glm
::
vec2
&
direction
)
->
std
::
pair
<
bool
,
util
::
Contact
>
{
auto
&
level
=
_current_level
.
get_blocking
();
std
::
pair
<
bool
,
util
::
Contact
>
result
{
false
,
{}};
for_each
(
level
,
[
&
](
const
Tileset
&
tileset
,
const
std
::
string
&
key
,
const
Tile
&
tile
,
const
glm
::
vec3
&
position
)
{
if
(
!
tile
.
solid
)
{
return
;
}
glm
::
vec2
tile_origin
{
position
.
x
,
position
.
z
};
auto
half_size
=
tileset
.
tile_size
/
2.
f
;
glm
::
vec2
half_vector
{
half_size
,
half_size
};
auto
[
hit
,
contact
]
=
util
::
intersect
({
origin
,
direction
},
{
tile_origin
,
half_vector
});
if
(
!
hit
)
{
return
;
}
if
(
contact
.
distance2
<
result
.
second
.
distance2
)
{
result
.
first
=
true
;
result
.
second
=
contact
;
}
});
return
result
;
}
auto
Level_system
::
_spawn_function
(
const
std
::
string
&
key
)
...
...
src/level/level_system.hpp
View file @
03be0527
#pragma once
#include
"../util/collision.hpp"
#include
"level.hpp"
#include
<functional>
...
...
@@ -21,6 +22,7 @@ namespace phase_shifter::level {
Level_system
(
mirrage
::
ecs
::
Entity_manager
&
entities
,
mirrage
::
asset
::
Asset_manager
&
assets
);
auto
load
(
const
std
::
string
&
name
)
->
void
;
auto
ray_cast
(
const
glm
::
vec2
&
origin
,
const
glm
::
vec2
&
direction
)
->
std
::
pair
<
bool
,
util
::
Contact
>
;
private:
auto
_spawn_function
(
const
std
::
string
&
key
)
...
...
src/util/collision.cpp
0 → 100644
View file @
03be0527
#include
"collision.hpp"
namespace
phase_shifter
::
util
{
auto
intersect
(
const
Ray
&
ray
,
const
Aabb
&
aabb
)
->
std
::
pair
<
bool
,
Contact
>
{
auto
min
=
aabb
.
origin
-
aabb
.
half_vec
;
auto
max
=
aabb
.
origin
+
aabb
.
half_vec
;
float
tmin
=
(
min
.
x
-
ray
.
origin
.
x
)
/
ray
.
direction
.
x
;
float
tmax
=
(
max
.
x
-
ray
.
origin
.
x
)
/
ray
.
direction
.
x
;
if
(
tmin
>
tmax
)
{
tmin
=
tmax
;
}
float
tymin
=
(
min
.
y
-
ray
.
origin
.
y
)
/
ray
.
direction
.
y
;
float
tymax
=
(
max
.
y
-
ray
.
origin
.
y
)
/
ray
.
direction
.
y
;
if
(
tymin
>
tymax
)
{
tymin
=
tymax
;
}
if
((
tmin
>
tymax
)
||
(
tymin
>
tmax
))
{
return
{
false
,
{}};
}
if
(
tymin
>
tmin
)
{
tmin
=
tymin
;
}
glm
::
vec2
point
{
ray
.
origin
+
tmin
*
ray
.
direction
};
return
{
true
,
{
point
,
glm
::
distance2
(
point
,
ray
.
origin
)}};
}
}
// namespace phase_shifter::util
src/util/collision.hpp
0 → 100644
View file @
03be0527
#pragma once
#include
<tuple>
#include
<glm/vec3.hpp>
namespace
phase_shifter
::
util
{
struct
Contact
{
glm
::
vec2
point
{
0.
f
};
float
distance2
=
std
::
numeric_limits
<
float
>::
max
();
};
struct
Ray
{
glm
::
vec2
origin
;
glm
::
vec2
direction
;
};
struct
Aabb
{
glm
::
vec2
origin
;
glm
::
vec2
half_vec
;
};
auto
intersect
(
const
Ray
&
ray
,
const
Aabb
&
aabb
)
->
std
::
pair
<
bool
,
Contact
>
;
}
// namespace phase_shifter::util
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment