-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathProjectile.cpp
More file actions
112 lines (86 loc) · 3.21 KB
/
Projectile.cpp
File metadata and controls
112 lines (86 loc) · 3.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include "precomp.h"
#include "Projectile.h"
#include "AssetManager.h"
#include "Mesh.h"
#include "Scene.h"
#include "Terrain.h"
#include "Unit.h"
#include "Physics.h"
#include "Explosion.h"
#include "EntityManager.h"
#include "Inquirer.h"
#include "Scope.h"
RTS::Projectile::Projectile(Framework::Scene& scene, const glm::vec3& position, const glm::vec3& velocity, const float explosionForce) :
Framework::Entity(scene),
mExplosionForce(explosionForce)
{
mMeshId = Framework::AssetManager::Inst().GetAsset<Framework::Mesh>("models/projectile.obj")->GetMeshId();
Framework::Transform& myTransform = GetTransform();
myTransform.SetLocalPosition(position);
myTransform.SetLocalForward(glm::normalize(velocity));
static btBoxShape* shape{};
static btVector3 inertia{};
constexpr float mass = .2f;
if (shape == nullptr)
{
shape = new btBoxShape({ 0.1f, 0.1f, 0.5f });
shape->calculateLocalInertia(mass, inertia);
}
std::unique_ptr<btRigidBody> rigidBody = std::make_unique<btRigidBody>(mass, &myTransform, shape, inertia);
rigidBody->setFriction(100000.0f);
rigidBody->setLinearVelocity(Framework::Math::ToBullet(velocity));
mCollisionObject = std::move(rigidBody);
mCollisionObject->setUserPointer(this);
mScene.mPhysics->AddCollisionObjectToWorld(mCollisionObject.get(), Framework::Physics::Group::projectileGroup, Framework::Physics::Mask::projectileMask);
mHasCollisionCallback = true;
mHasFixedTick = true;
}
RTS::Projectile::~Projectile()
{
mScene.mPhysics->RemoveCollisionObjectFromWorld(std::move(mCollisionObject));
}
void RTS::Projectile::FixedTick()
{
const btRigidBody* rigidbody = static_cast<btRigidBody*>(mCollisionObject.get());
const glm::vec3 currentLinearVelocity = Framework::Math::ToGLM(rigidbody->getLinearVelocity());
Framework::Transform& myTransform = GetTransform();
myTransform.SetLocalForward(currentLinearVelocity);
const glm::vec3 myPosition = myTransform.GetLocalPosition();
const Framework::TerrainData* terrainData = mScene.mTerrain->GetData();
if (!terrainData->mWorldBounds.Contains({ myPosition.x, myPosition.z }))
{
Hit();
}
}
bool RTS::Projectile::Serialize(Framework::Data::Scope& parentScope) const
{
Entity::Serialize(parentScope);
parentScope.AddChild("Projectile").AddVariable("explosionForce") << mExplosionForce;
return true;
}
void RTS::Projectile::Deserialize(const Framework::Data::Scope& parentScope)
{
Entity::Deserialize(parentScope);
parentScope.GetScope("Projectile").GetVariable("explosionForce") >> mExplosionForce;
}
void RTS::Projectile::OnCollision(const btCollisionObject* object)
{
Hit();
Unit* unit = dynamic_cast<Unit*>(static_cast<Entity*>(object->getUserPointer()));
if (unit != nullptr)
{
unit->ReceiveDamage(sDirectHitDamage);
}
}
void RTS::Projectile::Hit()
{
// Make sure we don't destroy ourselves multiple times, if we hit multiple objects in one frame.
if (mHasBeenDestroyed)
{
return;
}
const Framework::Transform& myTransform = GetTransform();
mScene.mEntityManager->AddEntity<Explosion>(myTransform, mExplosionForce);
Destroy();
mHasBeenDestroyed = true;
}