23 bool isMultiTile =
false;
24 bool isMainTile =
false;
34 glm::i32vec2 mainTilePos;
51 template<
typename Integer>
56 constexpr Float one_twelfth = 1.0f / 12.0f;
58 return one_twelfth *
getMass(tileDimensions) * (sqaure(tileWidth * tileDimensions.x) + sqaure(tileHeight * tileDimensions.y));
66 template<
typename Integer>
67 Float
getMass(
const glm::vec<2, Integer>& tileDimensions)
const {
70 return (tileWidth * (Float)tileDimensions.x) * (tileHeight * (Float)tileDimensions.y) * density;
75 uint8_t staticFriction = 255;
76 uint8_t dynamicFriction = 255;
77 uint8_t restitution = 0;
81template<
typename TileType>
87template<
typename TileType>
90 template<
class ATileType,
class TileMapAllocator,
class PhysicsWorld>
109 return m_physicsTiles.find(tilePos)->second;
120 return m_tiles.find(tilePos)->second;
162 bool removeTile(
const glm::i32vec2& pos)
noexcept;
174 auto& props = m_tiles.find(pos)->second;
176 if (props.isMultiTile) {
177 assert(props.isMainTile);
178 return { props.mutliTile.width, props.mutliTile.height };
203 return m_tiles.size();
220 using ContainerIterator =
typename FlatMap<glm::i32vec2, TileProperties<TileType>>::iterator;
222 ContainerIterator m_it;
224 Iterator(
const ContainerIterator& it)
227 const glm::i32vec2& operator*()
const {
241 bool operator!=(
const Iterator& other)
const {
242 return m_it != other.m_it;
247 Iterator end() {
return Iterator(m_tiles.end()); }
258 FlatMap<glm::i32vec2, TileProperties<TileType>> m_tiles;
259 FlatMap<glm::i32vec2, PhysicsTileProperties> m_physicsTiles;
270template<
typename TileType>
272 friend class TileMap<TileType>;
286 : aabb(aabb), pos(pos) {
293 inline bool operator==(
const SpatialIndex& other)
const {
294 return pos == other.pos;
332 const SinCos& sincos = m_transform.sincos;
335 return { vec2(sincos.cos, sincos.sin), vec2(-sincos.sin, sincos.cos) };
347 return (vec2)iPos * vec2(tileWidth, tileHeight) + m_tileMap.getRealTileDimensions(iPos) * Float(0.5f);
383 tileOBB.extent = m_tileMap.getRealTileDimensions(iPos) * Float(0.5);
385 tileOBB.transform.rot = m_transform.rot;
386 tileOBB.transform.sincos = m_transform.sincos;
400 vec2 extent = m_tileMap.getRealTileDimensions(iPos) * Float(0.5);
402 const vec2 wExt = rotate({ extent.x, extent.y }, m_transform.sincos);
403 const vec2 blExt = rotate({ extent.x, -extent.y }, m_transform.sincos);
404 const vec2 trExt = -blExt;
408 {worldPos.x + blExt.x, worldPos.y + blExt.y},
410 {worldPos.x + trExt.x, worldPos.y + trExt.y}
422 vec2 tileDim = m_tileMap.getRealTileDimensions(iPos);
424 return AABB(
getTileWorldPoint(iPos), tileDim.x * Float(0.5), tileDim.y * Float(0.5)).rotate(m_transform.sincos);
435 vec2 tileDim = m_tileMap.getRealTileDimensions(iPos);
437 return {
getTileLocalPoint(iPos), tileDim.x * Float(0.5), tileDim.y * Float(0.5) };
449 template<
typename OutIt>
454 assert(minChunk.x <= maxChunk.x);
455 assert(minChunk.y <= maxChunk.y);
457 for (int32_t y = minChunk.y; y <= maxChunk.y; y++) {
458 for (int32_t x = minChunk.x; x <= maxChunk.x; x++) {
459 glm::i32vec2 coord(x, y);
461 if (m_chunks.contains(coord)) {
477 template<
typename OutIt>
482 assert(minTiles.x <= maxTiles.x);
483 assert(minTiles.y <= maxTiles.y);
485 for (int32_t y = minTiles.y; y <= maxTiles.y; y++) {
486 for (int32_t x = minTiles.x; x <= maxTiles.x; x++) {
487 glm::i32vec2 coord(x, y);
489 if (m_tileMap.m_tiles.contains(coord)) {
491 if (m_tileMap.m_tiles[coord].isMultiTile && !m_tileMap.m_tiles[coord].isMainTile)
492 *tiles =
SpatialIndex(m_tileMap.m_tiles[coord].mainTilePos);
508 return (glm::i32vec2)glm::floor(localCoords / (tileSize * vec2(chunkWidth, chunkHeight)));
519 glm::i32vec2 chunk = {
520 tileCoords.x / chunkWidth,
521 tileCoords.y / chunkHeight
535 return (glm::i32vec2)glm::floor(localCoords / (tileSize));
546 constexpr vec2 chunkDim((Float)(tileWidth * chunkWidth), (Float)(tileHeight * chunkHeight));
548 return AABB((vec2)chunk * chunkDim + chunkDim * Float(0.5f), chunkDim.x * Float(0.5), chunkDim.y * Float(0.5));
552 inline void insertIntoChunk(
const glm::i32vec2& tile) {
553 glm::i32vec2 chunk = getChunk(tile);
555 if (m_chunks.find(chunk) == m_chunks.end()) {
556 m_chunks.insert(chunk);
562 const vec2 halfDim = {
563 (Float)corners.width() * tileWidth * Float(0.5f) + tileWidth * Float(0.5f),
564 (Float)corners.height() * tileHeight * Float(0.5f) + tileHeight * Float(0.5f)
566 return AABB(halfDim) + getTileLocalPointNoDim(corners.min()) + halfDim;
570 inline vec2 getTileLocalPointNoDim(
const glm::i32vec2& iPos)
const {
571 return (vec2)iPos * vec2(tileWidth, tileHeight);
574 inline void calculateRotationalInertia() {
576 for (
const auto& pair : m_tileMap.m_physicsTiles) {
577 auto tileDimensions = m_tileMap.getTileDimensions(pair.first);
578 m_I += parallelAxisTheorem<Float>(
579 pair.second.template getMomentOfInertia<uint16_t>(tileDimensions),
580 pair.second.template getMass<uint16_t>(tileDimensions),
583 if (m_I != 0.0f && !m_flags[IS_STATIC])
584 m_inverseI = 1.0f / m_I;
589 inline void calculateRotationalInertiaAndAABB() {
592 auto& min = corners.min();
593 auto& max = corners.max();
594 for (
const auto& pair : m_tileMap.m_physicsTiles) {
595 const glm::i32vec2& tilePos = pair.first;
596 const glm::u16vec2 tileDimensions = m_tileMap.getTileDimensions(tilePos);
598 if (tilePos.x < min.x) {
601 if (tilePos.y < min.y) {
604 if (tilePos.x + (tileDimensions.x - 1) > max.x) {
605 max.x = tilePos.x + (tileDimensions.x - 1);
607 if (tilePos.y + (tileDimensions.y - 1) > max.y) {
608 max.y = tilePos.y + (tileDimensions.y - 1);
611 m_I += parallelAxisTheorem<Float>(
612 pair.second.template getMomentOfInertia<uint16_t>(tileDimensions),
613 pair.second.template getMass<uint16_t>(tileDimensions),
617 if (m_I != 0.0f && !m_flags[IS_STATIC])
618 m_inverseI = 1.0f / m_I;
624 void addTile(
const glm::i32vec2& iPos) {
626 const glm::u16vec2 tileDimensions = m_tileMap.getTileDimensions(iPos);
628 const Float tileMass = physicsProperties.
getMass<uint16_t>(tileDimensions);
630 m_unweightedCentroid += pos;
631 m_centroid = m_unweightedCentroid / (Float)m_tileMap.m_physicsTiles.size();
633 calculateRotationalInertia();
637 if(!m_flags[IS_STATIC])
638 m_inverseMass = 1.0f / m_mass;
639 m_unweightedCom += tileMass * pos;
640 m_com = m_unweightedCom * m_inverseMass;
642 for (
auto y = iPos.y; y < (iPos.y + (int32_t)tileDimensions.y); y++) {
643 for (
auto x = iPos.x; x < (iPos.x + (int32_t)tileDimensions.x); x++) {
644 insertIntoChunk({ x, y });
648 auto& min = corners.min();
649 auto& max = corners.max();
650 if (iPos.x < min.x) {
653 if (iPos.y < min.y) {
656 if (iPos.x + (tileDimensions.x - 1) > max.x) {
657 max.x = iPos.x + (tileDimensions.x - 1);
659 if (iPos.y + (tileDimensions.y - 1) > max.y) {
660 max.y = iPos.y + (tileDimensions.y - 1);
666 void removeTile(
const glm::i32vec2& iPos) {
668 const glm::u16vec2 tileDimensions = m_tileMap.getTileDimensions(iPos);
670 const Float tileMass = physicsProperties.
getMass<uint16_t>(tileDimensions);
673 if (m_mass != 0.0f && !m_flags[IS_STATIC])
674 m_inverseMass = 1.0f / m_mass;
676 m_inverseMass = 0.0f;
677 m_unweightedCom -= tileMass * pos;
678 m_com = m_unweightedCom * m_inverseMass;
680 m_unweightedCentroid -= pos;
681 m_centroid = m_unweightedCentroid / (Float)(m_tileMap.m_physicsTiles.size() - 1);
683 calculateRotationalInertiaAndAABB();
689 void beginBulkInsert() {
693 void endBulkInsert() {
696 calculateRotationalInertia();
699 void beginBulkErase() {
703 void endBulkErase() {
706 calculateRotationalInertiaAndAABB();
711 corners.setMin(glm::i32vec2(std::numeric_limits<int32_t>::max()));
712 corners.setMax(glm::i32vec2(-std::numeric_limits<int32_t>::max()));
715 bool isBulkErase =
false;
716 bool isBulkAdd =
false;
719 boost::unordered_flat_set<glm::i32vec2> m_chunks;
722template<
typename TileType>
726 if (m_tiles.contains(pos))
729 if (props.isMultiTile) {
730 glm::i32vec2 endPos = {
731 pos.x + props.mutliTile.width,
732 pos.y + props.mutliTile.height
736 bufferTileProperties.isMainTile =
false;
737 bufferTileProperties.mainTilePos = pos;
740 for (
auto y = pos.y; y < endPos.y; y++) {
741 for (
auto x = pos.x; x < endPos.x; x++) {
742 if (m_tiles.contains({ x, y })) {
748 for (
auto y = pos.y; y < endPos.y; y++) {
749 for (
auto x = pos.x; x < endPos.x; x++) {
750 m_tiles[{x, y}] = bufferTileProperties;
755 m_tiles[pos] = props;
756 m_physicsTiles.insert(std::pair(pos, physicsProperties));
757 m_body->addTile(pos);
762template<
typename TileType>
766 if (!m_tiles.contains(pos))
769 m_body->removeTile(pos);
770 m_physicsTiles.erase(pos);
773 if (tileProperties.isMultiTile) {
774 if (!tileProperties.isMainTile)
775 throw "Attempt to remove multi tile that isn't the main tile\n";
777 glm::i32vec2 endPos = {
778 pos.x + tileProperties.mutliTile.width,
779 pos.y + tileProperties.mutliTile.height
782 for (
auto y = pos.y; y < endPos.y; y++) {
783 for (
auto x = pos.x; x < endPos.x; x++) {
784 m_tiles.erase({ x, y });
796template<
typename TileType>
799 m_body->beginBulkInsert();
802template<
typename TileType>
805 m_body->endBulkInsert();
808template<
typename TileType>
811 m_body->beginBulkErase();
814template<
typename TileType>
817 m_body->endBulkErase();
820template<
typename TileType>
825template<
class TileType,
class TileMapAllocator,
class PhysicsWorld>
827 std::pair<TileMap<TileType>*,
Body*> operator()(TileMapAllocator& tileMapAllocator, PhysicsWorld& physicsWorld) {
829 Body* tileBody = physicsWorld.createTileBody(*tileMap);
831 return { tileMap, tileBody };
843template<
class TileType,
class TileMapAllocator,
class PhysicsWorld>
Contains different types of rigid bodies aside from TileBody. See tileMap.hpp.
Extends the functionality of WorldBody to allow for things such as angular velocity.
Definition body.hpp:238
virtual void integrate(Float dt) override
Integerates this body, meaning the linear velocity and angular velocity will be integrated into the p...
Definition body.hpp:253
virtual vec2 getWorldPoint(const vec2 &localPoint) const override
Gets a local position thats within the local space of this body and transforms into the world space.
Definition body.hpp:278
For use with a TileMap<>, allows collisions with other rigid bodies inside World<>
Definition tileMap.hpp:271
TileMap< TileType > & tileMap() const
Returns the tile map attached to this rigid body.
Definition tileMap.hpp:322
void queryChunks(const AABB< Float > &intersectBox, OutIt chunks) const
Will get the list of chunks that intersect intersectBox, along with their AABBS.
Definition tileMap.hpp:450
vec2 getTileLocalPoint(const glm::i32vec2 &iPos) const
Returns the local center of the tile located at iPos.
Definition tileMap.hpp:346
virtual AABB< Float > getAABB() const override
Returns the AABB of this body.
Definition tileMap.hpp:313
AABB< Float > getTileWorldAABB(const glm::i32vec2 &iPos) const
Returns the world AABB of a tile located at iPos.
Definition tileMap.hpp:421
std::array< vec2, 2 > normals() const
Returns the normals of this body. Can be used for all tiles of this body.
Definition tileMap.hpp:331
AABB< Float > getChunkAABB(const glm::i32vec2 &chunk) const
Get the AABB of the chunk located at chunk.
Definition tileMap.hpp:545
glm::i32vec2 getTileCoords(const vec2 &localCoords) const
Get the tile that contains localCoords. Tile may or may not exist.
Definition tileMap.hpp:534
glm::i32vec2 getChunkCoords(const glm::i32vec2 &tileCoords) const
Get the chunk that contains tileCoords. Chunk may or may not exist.
Definition tileMap.hpp:518
void queryTiles(const AABB< Float > &intersectBox, OutIt tiles) const
Will get the list of tiles that intersect intersectBox.
Definition tileMap.hpp:478
vec2 getTileWorldPoint(const glm::i32vec2 &iPos) const
Returns the world center of the tile located at iPos.
Definition tileMap.hpp:357
glm::i32vec2 getChunkCoords(const vec2 &localCoords) const
Get the chunk that contains localCoords. Chunk may or may not exist.
Definition tileMap.hpp:507
std::array< vec2, 4 > getTileWorldOBBOffsetVertices(const glm::i32vec2 &iPos, const vec2 &worldOffset) const
Returns the world vertices of the tile located at iPos. with an added offset.
Definition tileMap.hpp:399
TOBB getTileWorldOBBOffset(const glm::i32vec2 &iPos, const vec2 &worldOffset) const
Returns the world oriented bounding box of the tile located at iPos. with an added offset.
Definition tileMap.hpp:380
TOBB getTileWorldOBB(const glm::i32vec2 &iPos) const
Returns the world oriented bounding box of the tile located at iPos.
Definition tileMap.hpp:368
AABB< Float > getTileLocalAABB(const glm::i32vec2 &iPos) const
Returns the local AABB of a tile located at iPos.
Definition tileMap.hpp:434
virtual void integrate(Float dt) override
Integerates this body, meaning the linear velocity and angular velocity will be integrated into the p...
Definition tileMap.hpp:309
TileBody(TileMap< TileType > &tileMap, uint32_t id)
Do not call directly, to construct a TileBody use createTileMap()
Definition tileMap.hpp:302
Definition tileMap.hpp:88
void beginBulkErase()
Used to speed up the erasure of a large amount of tiles. To use for speed up, call before erasing a l...
Definition tileMap.hpp:809
vec2 getRealTileDimensions(const glm::i32vec2 &pos) const
Returns the REAL tile dimensions, meaning world dimensions, of the tile located at pos.
Definition tileMap.hpp:193
TileMap(_CreateTileMap)
Do not call directly, to construct a tileMap use createTileMap()
Definition tileMap.hpp:97
bool removeTile(const glm::i32vec2 &pos) noexcept
Removes a tile at pos.
Definition tileMap.hpp:763
const PhysicsTileProperties & getPhysicsTileProperties(const glm::i32vec2 &tilePos) const
Returns the physical properties of a tile located at tilePos.
Definition tileMap.hpp:108
TileProperties< TileType > & getTileProperties(const glm::i32vec2 &tilePos)
Returns the properties of a tile located at tilePos.
Definition tileMap.hpp:119
TileBody< TileType > & body()
Returns the rigid body attached to this tile map.
Definition tileMap.hpp:821
void beginBulkInsert()
Used to speed up the insert of a large amount of tiles. To use for speed up, call before inserting a ...
Definition tileMap.hpp:797
bool addTile(const glm::i32vec2 &pos, const TileProperties< TileType > &props, const PhysicsTileProperties &physicsProperties={})
Adds a tile at pos with the properties of props and the physics properties set to physicsProperties....
Definition tileMap.hpp:723
glm::u16vec2 getTileDimensions(const glm::i32vec2 &pos) const
Returns the tile dimensions of the tile located at pos.
Definition tileMap.hpp:173
void endBulkErase()
Used to speed up the erasure of a large amount of tiles. To use for speed up, call after erasing a la...
Definition tileMap.hpp:815
size_t count() const
Returns the amount of tiles, including the sub-tiles of multi-tiles.
Definition tileMap.hpp:202
void setTileBody(TileBody< TileType > *body)
Definition tileMap.hpp:253
void endBulkInsert()
Used to speed up the insert of a large amount of tiles. To use for speed up, call after inserting a l...
Definition tileMap.hpp:803
The abstract base class of all Rigid Bodies that defines essential methods and members to be used in ...
Definition body.hpp:30
uint32_t id() const
Returns the id assigned to this body the physics world.
Definition body.hpp:48
Definition tileMap.hpp:85
Definition tileMap.hpp:826
Contains the physical properties of a tile, such as elasticity.
Definition tileMap.hpp:45
Float getMass(const glm::vec< 2, Integer > &tileDimensions) const
Returns the mass of this tile with using the area calculated from tileDimensions.
Definition tileMap.hpp:67
Float getMomentOfInertia(const glm::vec< 2, Integer > &tileDimensions) const
Returns the rotational inertia of this tile.
Definition tileMap.hpp:52
Used to simplify the use of precalculated values for sine and cosine.
Definition math.hpp:80
A spatial index where pos may point towards a chunk or tile.
Definition tileMap.hpp:279
Allows iteration of tiles with for loops/.
Definition tileMap.hpp:219
Contains the data of a tile or multi tile.
Definition tileMap.hpp:21
std::pair< TileMap< TileType > *, WorldBody * > createTileMap(TileMapAllocator &tileMapAllocator, PhysicsWorld &physicsWorld)
Creates a tile map and a tile body using tileMapAllocator for the tileMap and the physicsWorld for th...
Definition tileMap.hpp:844