Working on different collider types.
This commit is contained in:
		@@ -9,4 +9,6 @@ target_sources(${DAWN_TARGET_NAME}
 | 
			
		||||
    BoxCollider.cpp
 | 
			
		||||
    Collider2D.cpp
 | 
			
		||||
    CharacterController2D.cpp
 | 
			
		||||
    SolidController2D.cpp
 | 
			
		||||
    TriggerCollider2D.cpp
 | 
			
		||||
)
 | 
			
		||||
@@ -14,23 +14,23 @@ CharacterController2D::CharacterController2D(SceneItem *i) :
 | 
			
		||||
 | 
			
		||||
void CharacterController2D::onStart() {
 | 
			
		||||
  useEvent([&](float_t delta){
 | 
			
		||||
    // Friction
 | 
			
		||||
    velocity -= velocity * friction * delta;
 | 
			
		||||
 | 
			
		||||
    // Common variables
 | 
			
		||||
    auto myCollider = item->getComponent<Collider2D>();
 | 
			
		||||
    glm::vec2 currentPosition(
 | 
			
		||||
      this->transform->getLocalPosition().x,
 | 
			
		||||
      this->transform->getLocalPosition().z
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Friction
 | 
			
		||||
    velocity -= velocity * friction * delta;
 | 
			
		||||
 | 
			
		||||
    // Perform movement and check for collisions.
 | 
			
		||||
    // Solid Collision Check
 | 
			
		||||
    glm::vec2 moveAmount;
 | 
			
		||||
    if(myCollider == nullptr) {
 | 
			
		||||
      moveAmount = velocity;
 | 
			
		||||
    } else {
 | 
			
		||||
      // Perform sweep
 | 
			
		||||
      auto allColliders = getScene()->findComponents<Collider2D>();
 | 
			
		||||
      auto allColliders = getScene()->findComponents<SolidController2D>();
 | 
			
		||||
      auto itColliders = allColliders.begin();
 | 
			
		||||
 | 
			
		||||
      struct CharacterController2DCollisionEventInfo info;
 | 
			
		||||
@@ -40,16 +40,17 @@ void CharacterController2D::onStart() {
 | 
			
		||||
      while(itColliders != allColliders.end()) {
 | 
			
		||||
        auto c = *itColliders;
 | 
			
		||||
        ++itColliders;
 | 
			
		||||
        if(c == myCollider) continue;
 | 
			
		||||
        result = myCollider->getCollidingResult(
 | 
			
		||||
        if(c->item == this->item) continue;
 | 
			
		||||
        result = c->getCollidingResult(
 | 
			
		||||
          velocity,
 | 
			
		||||
          c,
 | 
			
		||||
          myCollider,
 | 
			
		||||
          info.normal,
 | 
			
		||||
          info.entryTime,
 | 
			
		||||
          info.exitTime,
 | 
			
		||||
          info.entryPoint,
 | 
			
		||||
          info.exitPoint
 | 
			
		||||
        ) && info.entryTime <= delta;
 | 
			
		||||
 | 
			
		||||
        if(result) {
 | 
			
		||||
          info.collider = c;
 | 
			
		||||
          break;
 | 
			
		||||
@@ -73,5 +74,18 @@ void CharacterController2D::onStart() {
 | 
			
		||||
    transform->setLocalPosition(
 | 
			
		||||
      transform->getLocalPosition() + (glm::vec3(moveAmount.x, 0, moveAmount.y) * delta)
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Now perform trigger collision check
 | 
			
		||||
    auto allTriggers = getScene()->findComponents<TriggerController2D>();
 | 
			
		||||
    auto itTriggers = allTriggers.begin();
 | 
			
		||||
    while(itTriggers != allTriggers.end()) {
 | 
			
		||||
      auto c = *itTriggers;
 | 
			
		||||
      ++itTriggers;
 | 
			
		||||
      if(c->item == this->item) continue;
 | 
			
		||||
      if(c->getCollidingResult(myCollider)) {
 | 
			
		||||
        c->eventTriggerEnter.invoke(this);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  }, getScene()->eventSceneUpdate);
 | 
			
		||||
}
 | 
			
		||||
@@ -4,11 +4,12 @@
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "SolidController2D.hpp"
 | 
			
		||||
#include "TriggerController2D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  struct CharacterController2DCollisionEventInfo {
 | 
			
		||||
    Collider2D *collider;
 | 
			
		||||
    SolidController2D *collider;
 | 
			
		||||
    glm::vec2 normal;
 | 
			
		||||
    float_t entryTime;
 | 
			
		||||
    float_t exitTime;
 | 
			
		||||
 
 | 
			
		||||
@@ -10,58 +10,4 @@ using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
Collider2D::Collider2D(SceneItem *i) : SceneItemComponent(i) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t Collider2D::getCollidingResult(
 | 
			
		||||
  glm::vec2 movement,
 | 
			
		||||
  Collider2D *other,
 | 
			
		||||
  glm::vec2 &normal,
 | 
			
		||||
  float_t &entryTime,
 | 
			
		||||
  float_t &exitTime,
 | 
			
		||||
  glm::vec2 &entryPoint,
 | 
			
		||||
  glm::vec2 &exitPoint
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(other);
 | 
			
		||||
  if(movement.x == 0 && movement.y == 0) return false;
 | 
			
		||||
 | 
			
		||||
  auto localPos = this->transform->getLocalPosition();
 | 
			
		||||
  glm::vec2 myPos(localPos.x, localPos.z);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Check what THIS is
 | 
			
		||||
  switch(this->getColliderType()) {
 | 
			
		||||
    case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
      auto box1 = dynamic_cast<BoxCollider*>(this);
 | 
			
		||||
      assertNotNull(box1);
 | 
			
		||||
 | 
			
		||||
      // Box VS ?
 | 
			
		||||
      switch(other->getColliderType()) {
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = dynamic_cast<BoxCollider*>(other);
 | 
			
		||||
          assertNotNull(box2);
 | 
			
		||||
          auto localPos2 = box2->transform->getLocalPosition();
 | 
			
		||||
          glm::vec2 otherPos(localPos2.x, localPos2.z);
 | 
			
		||||
 | 
			
		||||
          return boxCheckCollision(
 | 
			
		||||
            myPos, box1->min, box1->max,
 | 
			
		||||
            otherPos, box2->min, box2->max,
 | 
			
		||||
            movement,
 | 
			
		||||
            normal, entryTime, exitTime, entryPoint, exitPoint
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        default: {
 | 
			
		||||
          assertUnreachable();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default: {
 | 
			
		||||
      assertUnreachable();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  assertUnreachable();
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
@@ -30,29 +30,5 @@ namespace Dawn {
 | 
			
		||||
       * @return The collider type that this is.
 | 
			
		||||
       */
 | 
			
		||||
      virtual enum Collider2DType getColliderType() = 0;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Gets the result of checking if two collider bodies are intersecting.
 | 
			
		||||
       * This is performed WITH movement to return entry and exit times.
 | 
			
		||||
       * 
 | 
			
		||||
       * @param result Where to store the results of the calculation.
 | 
			
		||||
       * @param movement Movement operation that THIS object is performing.
 | 
			
		||||
       * @param other Other Collider that is being compared.
 | 
			
		||||
       * @param normal Output normal of the intersection.
 | 
			
		||||
       * @param entryTime Output entry time when the two objects will intersect.
 | 
			
		||||
       * @param exitTime Output exit time when the object will pass through.
 | 
			
		||||
       * @param entryPoint Output point in 2D space where object will enter.
 | 
			
		||||
       * @param exitPoint Output point where object will have passed through.
 | 
			
		||||
       * @return True if the two objects will intersect at move otherwise false.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t getCollidingResult(
 | 
			
		||||
        glm::vec2 movement,
 | 
			
		||||
        Collider2D *other,
 | 
			
		||||
        glm::vec2 &normal,
 | 
			
		||||
        float_t &entryTime,
 | 
			
		||||
        float_t &exitTime,
 | 
			
		||||
        glm::vec2 &entryPoint,
 | 
			
		||||
        glm::vec2 &exitPoint
 | 
			
		||||
      );
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										72
									
								
								src/dawn/scene/components/physics/2d/SolidController2D.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/dawn/scene/components/physics/2d/SolidController2D.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,72 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "SolidController2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
SolidController2D::SolidController2D(SceneItem *item) : SceneItemComponent(item) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<SceneItemComponent*> SolidController2D::getDependencies() {
 | 
			
		||||
  return {
 | 
			
		||||
    (this->collider = item->getComponent<Collider2D>())
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t SolidController2D::getCollidingResult(
 | 
			
		||||
  glm::vec2 movement,
 | 
			
		||||
  Collider2D *movingObject,
 | 
			
		||||
  glm::vec2 &normal,
 | 
			
		||||
  float_t &entryTime,
 | 
			
		||||
  float_t &exitTime,
 | 
			
		||||
  glm::vec2 &entryPoint,
 | 
			
		||||
  glm::vec2 &exitPoint
 | 
			
		||||
) {
 | 
			
		||||
  assertNotNull(this->collider);
 | 
			
		||||
  assertNotNull(movingObject);
 | 
			
		||||
  if(movement.x == 0 && movement.y == 0) return false;
 | 
			
		||||
 | 
			
		||||
  auto localPos = this->transform->getLocalPosition();
 | 
			
		||||
  glm::vec2 myPos(localPos.x, localPos.z);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // Check what THIS is
 | 
			
		||||
  switch(movingObject->getColliderType()) {
 | 
			
		||||
    case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
      auto box1 = dynamic_cast<BoxCollider*>(this);
 | 
			
		||||
      assertNotNull(box1);
 | 
			
		||||
 | 
			
		||||
      // Box VS ?
 | 
			
		||||
      switch(collider->getColliderType()) {
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = dynamic_cast<BoxCollider*>(collider);
 | 
			
		||||
          assertNotNull(box2);
 | 
			
		||||
          auto localPos2 = box2->transform->getLocalPosition();
 | 
			
		||||
          glm::vec2 otherPos(localPos2.x, localPos2.z);
 | 
			
		||||
 | 
			
		||||
          return boxCheckCollision(
 | 
			
		||||
            myPos, box1->min, box1->max,
 | 
			
		||||
            otherPos, box2->min, box2->max,
 | 
			
		||||
            movement,
 | 
			
		||||
            normal, entryTime, exitTime, entryPoint, exitPoint
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        default: {
 | 
			
		||||
          assertUnreachable();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    default: {
 | 
			
		||||
      assertUnreachable();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  assertUnreachable();
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										42
									
								
								src/dawn/scene/components/physics/2d/SolidController2D.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/dawn/scene/components/physics/2d/SolidController2D.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,42 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
#include "BoxCollider.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class SolidController2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      Collider2D *collider = nullptr;
 | 
			
		||||
 | 
			
		||||
      SolidController2D(SceneItem *item);
 | 
			
		||||
      std::vector<SceneItemComponent*> getDependencies() override;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Gets the result of checking if two collider bodies are intersecting.
 | 
			
		||||
       * This is performed WITH movement to return entry and exit times.
 | 
			
		||||
       * 
 | 
			
		||||
       * @param result Where to store the results of the calculation.
 | 
			
		||||
       * @param movement Movement operation that THIS object is performing.
 | 
			
		||||
       * @param movingObject Moving Object Collider that is being compared.
 | 
			
		||||
       * @param normal Output normal of the intersection.
 | 
			
		||||
       * @param entryTime Output entry time when the two objects will intersect.
 | 
			
		||||
       * @param exitTime Output exit time when the object will pass through.
 | 
			
		||||
       * @param entryPoint Output point in 2D space where object will enter.
 | 
			
		||||
       * @param exitPoint Output point where object will have passed through.
 | 
			
		||||
       * @return True if the two objects will intersect at move otherwise false.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t getCollidingResult(
 | 
			
		||||
        glm::vec2 movement,
 | 
			
		||||
        Collider2D *movingObject,
 | 
			
		||||
        glm::vec2 &normal,
 | 
			
		||||
        float_t &entryTime,
 | 
			
		||||
        float_t &exitTime,
 | 
			
		||||
        glm::vec2 &entryPoint,
 | 
			
		||||
        glm::vec2 &exitPoint
 | 
			
		||||
      );
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										50
									
								
								src/dawn/scene/components/physics/2d/TriggerController2D.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								src/dawn/scene/components/physics/2d/TriggerController2D.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,50 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#include "TriggerController2D.hpp"
 | 
			
		||||
 | 
			
		||||
using namespace Dawn;
 | 
			
		||||
 | 
			
		||||
TriggerController2D::TriggerController2D(SceneItem *i) : SceneItemComponent(i) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<SceneItemComponent*> TriggerController2D::getDependencies() {
 | 
			
		||||
  return {
 | 
			
		||||
    (this->collider = this->item->getComponent<Collider2D>())
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool_t TriggerController2D::getCollidingResult(Collider2D* movingObject) {
 | 
			
		||||
  assertNotNull(this->collider);
 | 
			
		||||
  assertNotNull(movingObject);
 | 
			
		||||
 | 
			
		||||
  switch(movingObject->getColliderType()) {
 | 
			
		||||
    case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
      auto box1 = dynamic_cast<BoxCollider*>(movingObject);
 | 
			
		||||
      assertNotNull(box1);
 | 
			
		||||
 | 
			
		||||
      // Box VS ?
 | 
			
		||||
      switch(collider->getColliderType()) {
 | 
			
		||||
        case COLLIDER2D_TYPE_BOX: {
 | 
			
		||||
          auto box2 = dynamic_cast<BoxCollider*>(collider);
 | 
			
		||||
          assertNotNull(box2);
 | 
			
		||||
          return boxIsBoxColliding(
 | 
			
		||||
            box1->transform->getWorldPosition(), box1->min, box1->max,
 | 
			
		||||
            box2->transform->getWorldPosition(), box2->min, box2->max
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        default: {
 | 
			
		||||
          assertUnreachable();
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    default: {
 | 
			
		||||
      assertUnreachable();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										25
									
								
								src/dawn/scene/components/physics/2d/TriggerController2D.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								src/dawn/scene/components/physics/2d/TriggerController2D.hpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
// Copyright (c) 2023 Dominic Masters
 | 
			
		||||
// 
 | 
			
		||||
// This software is released under the MIT License.
 | 
			
		||||
// https://opensource.org/licenses/MIT
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "Collider2D.hpp"
 | 
			
		||||
 | 
			
		||||
namespace Dawn {
 | 
			
		||||
  class TriggerController2D : public SceneItemComponent {
 | 
			
		||||
    public:
 | 
			
		||||
      Collider2D *collider = nullptr;
 | 
			
		||||
 | 
			
		||||
      StateEvent<CharacterController2D*> eventTriggerEnter;
 | 
			
		||||
 | 
			
		||||
      TriggerController2D(SceneItem *i);
 | 
			
		||||
      std::vector<SceneItemComponent*> getDependencies() override;
 | 
			
		||||
 | 
			
		||||
      /**
 | 
			
		||||
       * Returns whether or not the given moving object is colliding with this
 | 
			
		||||
       * trigger collider.
 | 
			
		||||
       */
 | 
			
		||||
      bool_t getCollidingResult(Collider2D* movingObject)
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user