Vehicle component based, wheel rotation and position not working.

This commit is contained in:
ViktorLjung
2014-04-22 19:14:35 +02:00
parent f0b2f2a659
commit eb6cc266a3
7 changed files with 410 additions and 18 deletions
+4 -2
View File
@@ -3,13 +3,15 @@
#include "Component.h"
namespace Components
{
struct Vehicle : Component
{
struct Vehicle : Component
{
Vehicle()
: MaxTorque(500.0f), MinRPM(1000.0f), OptimalRPM(5500.0f), MaxRPM(7500.0f), MaxSteeringAngle(35), TopSpeed(50.0f) { }
float MaxTorque;
float MinRPM;
float OptimalRPM;
+7
View File
@@ -3,11 +3,15 @@
#include "Component.h"
namespace Systems { class PhysicsSystem; }
namespace Components
{
struct Wheel : Component
{
friend class Systems::PhysicsSystem;
Wheel()
: AxleID(0), Radius(0), Width(0), Mass(0), Steering(false), DownDirection(glm::vec3(0, -1, 0)), Friction(1.5f), SlipAngle(0.0f),
MaxBreakingTorque(1500.0f), ConnectedToHandbrake(false), SuspensionStrength(50.0f) { }
@@ -26,6 +30,9 @@ struct Wheel : Component
float SlipAngle;
float MaxBreakingTorque;
bool ConnectedToHandbrake;
private:
int ID;
};
}
+22 -5
View File
@@ -41,10 +41,11 @@ void GameWorld::Initialize()
}
for (int i = 0; i < 1; i++)
{
auto car = CreateEntity();
auto transform = AddComponent<Components::Transform>(car, "Transform");
transform->Position = glm::vec3(0, 5, 0);
transform->Position = glm::vec3(0, (i+1)*5, 0);
transform->Scale = glm::vec3(3, 1, 5);
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
auto model = AddComponent<Components::Model>(car, "Model");
@@ -56,58 +57,74 @@ void GameWorld::Initialize()
box->Height = 0.5f;
box->Depth = 2.5f;
auto vehicle = AddComponent<Components::Vehicle>(car, "Vehicle");
vehicle->TopSpeed = 500.f;
vehicle->MaxTorque = 1000.f;
AddComponent<Components::Input>(car, "Input");
{
// Front Right Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5);
transform->Position = glm::vec3(1.1f, -0.5f, -1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(1.1f, 0.f, -1.3f);// HACK: make into component
Wheel->AxleID = 0;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Radius = 0.5f;
Wheel->Steering = true;
auto model = AddComponent<Components::Model>(ent, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
CommitEntity(ent);
}
{
// Front Left Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5);
transform->Position = glm::vec3(-1.1f, -0.5f, -1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, -1.3f);
Wheel->AxleID = 0;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Radius = 0.5f;
Wheel->Steering = true;
auto model = AddComponent<Components::Model>(ent, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
CommitEntity(ent);
}
{
// Back Right Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5);
transform->Position = glm::vec3(1.1f, -0.5f, 1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(1.1f, 0.f, 1.3f);
Wheel->AxleID = 1;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Radius = 0.5f;
Wheel->Steering = false;
Wheel->ConnectedToHandbrake = true;
auto model = AddComponent<Components::Model>(ent, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
CommitEntity(ent);
}
{
// Back Left Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Scale = glm::vec3(1)/glm::vec3(3, 1, 5);
transform->Position = glm::vec3(-1.1f, -0.5f, 1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, 1.3f);
Wheel->AxleID = 1;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Radius = 0.5f;
Wheel->Steering = false;
Wheel->ConnectedToHandbrake = true;
auto model = AddComponent<Components::Model>(ent, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
CommitEntity(ent);
}
+233
View File
@@ -0,0 +1,233 @@
#include "PrecompiledHeader.h"
#include "GameWorld.h"
void GameWorld::Initialize()
{
World::Initialize();
{
auto camera = CreateEntity();
auto transform = AddComponent<Components::Transform>(camera, "Transform");
transform->Position.z = 20.f;
transform->Position.y = 20.f;
transform->Orientation = glm::quat(glm::vec3(glm::pi<float>() / 8.f, 0.f, 0.f));
auto cameraComp = AddComponent<Components::Camera>(camera, "Camera");
cameraComp->FarClip = 2000.f;
AddComponent(camera, "Input");
auto freeSteering = AddComponent<Components::FreeSteering>(camera, "FreeSteering");
CommitEntity(camera);
}
{
auto ground = CreateEntity();
auto transform = AddComponent<Components::Transform>(ground, "Transform");
transform->Position = glm::vec3(0, -5, 0);
transform->Scale = glm::vec3(1000.0f, 10.0f, 1000.0f);
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
auto model = AddComponent<Components::Model>(ground, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube.obj";
auto box = AddComponent<Components::Box>(ground, "Box");
box->Width = 500;
box->Height = 5;
box->Depth = 500;
auto physics = AddComponent<Components::Physics>(ground, "Physics");
physics->Mass = 10;
<<<<<<< HEAD
physics->Static = true;
=======
CommitEntity(ground);
>>>>>>> 84d6911... Barebones entity component commit events
}
{
auto car = CreateEntity();
auto transform = AddComponent<Components::Transform>(car, "Transform");
transform->Position = glm::vec3(0, 5, 0);
transform->Scale = glm::vec3(3, 1, 5);
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
auto model = AddComponent<Components::Model>(car, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
auto physics = AddComponent<Components::Physics>(car, "Physics");
physics->Mass = 1200;
auto box = AddComponent<Components::Box>(car, "Box");
box->Width = 1.5f;
box->Height = 0.5f;
box->Depth = 2.5f;
auto vehicle = AddComponent<Components::Vehicle>(car, "Vehicle");
AddComponent<Components::Input>(car, "Input");
{
// Front Right Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Position = glm::vec3(1.1f, -0.5f, -1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(1.1f, 0.f, -1.3f);// HACK: make into component
Wheel->AxleID = 0;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Steering = true;
}
{
// Front Left Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Position = glm::vec3(-1.1f, -0.5f, -1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, -1.3f);
Wheel->AxleID = 0;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Steering = true;
}
{
// Back Right Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Position = glm::vec3(1.1f, -0.5f, 1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(1.1f, 0.f, 1.3f);
Wheel->AxleID = 1;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Steering = false;
}
{
// Back Left Wheel
auto ent = CreateEntity(car);
auto transform = AddComponent<Components::Transform>(ent, "Transform");
transform->Position = glm::vec3(-1.1f, -0.5f, 1.3f);
auto Wheel = AddComponent<Components::Wheel>(ent, "Wheel");
Wheel->Hardpoint = glm::vec3(-1.1f, 0.f, 1.3f);
Wheel->AxleID = 1;
Wheel->Mass = 10;
Wheel->Radius = 0.6f;
Wheel->Steering = false;
}
<<<<<<< HEAD
}
=======
auto model = AddComponent<Components::Model>(TankTest, "Model");
model->ModelFile = "Models/Placeholders/tank/Chassi.obj";
CommitEntity(TankTest);
}
for(int i = 0; i < 83; i++)
{
auto light = CreateEntity();
auto transform = AddComponent<Components::Transform>(light, "Transform");
transform->Position = glm::vec3((float)(2*i)*glm::sin((float)i), 3, (float)(2*i)*glm::cos((float)i));
auto pointLight = AddComponent<Components::PointLight>(light, "PointLight");
pointLight->Specular = glm::vec3(0.1f, 0.1f, 0.1f);
pointLight->Diffuse = glm::vec3(0.05f, 0.36f, 1.f);
pointLight->constantAttenuation = 0.03f;
pointLight->linearAttenuation = 0.009f;
pointLight->quadraticAttenuation = 0.07f;
pointLight->spotExponent = 0.0f;
auto model = AddComponent<Components::Model>(light, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/PointLight.obj";
CommitEntity(light);
}
>>>>>>> 84d6911... Barebones entity component commit events
for(int i = 0; i < 50; i++)
{
auto ball = CreateEntity();
auto transform = AddComponent<Components::Transform>(ball, "Transform");
transform->Position = glm::vec3(243, 10 + i*10, 0);
transform->Scale = glm::vec3(10);
transform->Orientation = glm::quat(glm::vec3(0.0f, 0.0f, 0.0f));
auto model = AddComponent<Components::Model>(ball, "Model");
model->ModelFile = "Models/Placeholders/PhysicsTest/Cube2.obj";
auto physics = AddComponent<Components::Physics>(ball, "Physics");
<<<<<<< HEAD
physics->Mass = 100;
auto box = AddComponent<Components::Box>(ball, "Box");
box->Width = 5.f;
box->Height = 5.f;
box->Depth = 5.f;
=======
physics->Mass = 1;
CommitEntity(ball);
>>>>>>> 84d6911... Barebones entity component commit events
}
{
auto entity = CreateEntity();
AddComponent(entity, "Transform");
auto emitter = AddComponent<Components::SoundEmitter>(entity, "SoundEmitter");
emitter->Path = "Sounds/korvring.wav";
emitter->Loop = true;
GetSystem<Systems::SoundSystem>("SoundSystem")->PlaySound(emitter);
}
}
void GameWorld::Update(double dt)
{
World::Update(dt);
}
void GameWorld::RegisterComponents()
{
m_ComponentFactory.Register("Camera", []() { return new Components::Camera(); });
m_ComponentFactory.Register("DirectionalLight", []() { return new Components::DirectionalLight(); });
m_ComponentFactory.Register("Input", []() { return new Components::Input(); });
m_ComponentFactory.Register("Model", []() { return new Components::Model(); });
m_ComponentFactory.Register("ParticleEmitter", []() { return new Components::ParticleEmitter(); });
m_ComponentFactory.Register("PointLight", []() { return new Components::PointLight(); });
m_ComponentFactory.Register("SoundEmitter", []() { return new Components::SoundEmitter(); });
m_ComponentFactory.Register("Sprite", []() { return new Components::Sprite(); });
m_ComponentFactory.Register("Template", []() { return new Components::Template(); });
m_ComponentFactory.Register("Transform", []() { return new Components::Transform(); });
m_ComponentFactory.Register("FreeSteering", []() { return new Components::FreeSteering(); });
m_ComponentFactory.Register("Physics", []() { return new Components::Physics(); });
m_ComponentFactory.Register("Sphere", []() { return new Components::Sphere(); });
m_ComponentFactory.Register("Box", []() { return new Components::Box (); });
m_ComponentFactory.Register("Vehicle", []() { return new Components::Vehicle(); });
m_ComponentFactory.Register("Wheel", []() { return new Components::Wheel(); });
}
void GameWorld::RegisterSystems()
{
m_SystemFactory.Register("TransformSystem", [this]() { return new Systems::TransformSystem(this); });
//m_SystemFactory.Register("LevelGenerationSystem", [this]() { return new Systems::LevelGenerationSystem(this); });
m_SystemFactory.Register("InputSystem", [this]() { return new Systems::InputSystem(this, m_Renderer); });
//m_SystemFactory.Register("CollisionSystem", [this]() { return new Systems::CollisionSystem(this); });
////m_SystemFactory.Register("ParticleSystem", [this]() { return new Systems::ParticleSystem(this); });
//m_SystemFactory.Register("PlayerSystem", [this]() { return new Systems::PlayerSystem(this); });
m_SystemFactory.Register("FreeSteeringSystem", [this]() { return new Systems::FreeSteeringSystem(this); });
m_SystemFactory.Register("SoundSystem", [this]() { return new Systems::SoundSystem(this); });
m_SystemFactory.Register("PhysicsSystem", [this]() { return new Systems::PhysicsSystem(this); });
m_SystemFactory.Register("RenderSystem", [this]() { return new Systems::RenderSystem(this, m_Renderer); });
}
void GameWorld::AddSystems()
{
AddSystem("TransformSystem");
//AddSystem("LevelGenerationSystem");
AddSystem("InputSystem");
//AddSystem("CollisionSystem");
////AddSystem("ParticleSystem");
//AddSystem("PlayerSystem");
AddSystem("FreeSteeringSystem");
AddSystem("SoundSystem");
AddSystem("PhysicsSystem");
AddSystem("RenderSystem");
}
+1 -1
View File
@@ -253,7 +253,7 @@ void VehicleSetup::setupComponent(const hkpVehicleData& data, hkpVehicleDefaultS
suspension.m_wheelParams[i].m_hardpointChassisSpace.set(m_Wheels[i].WheelComponent->Hardpoint.x, m_Wheels[i].WheelComponent->Hardpoint.y, m_Wheels[i].WheelComponent->Hardpoint.z);
suspension.m_wheelParams[0].m_directionChassisSpace = hkVector4(m_Wheels[i].WheelComponent->DownDirection.x, m_Wheels[i].WheelComponent->DownDirection.y, m_Wheels[i].WheelComponent->DownDirection.z);
suspension.m_wheelParams[i].m_directionChassisSpace = hkVector4(m_Wheels[i].WheelComponent->DownDirection.x, m_Wheels[i].WheelComponent->DownDirection.y, m_Wheels[i].WheelComponent->DownDirection.z);
}
}
+141 -8
View File
@@ -102,18 +102,36 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p
auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
if (!transformComponent)
return;
if (m_RigidBodies.find(entity) == m_RigidBodies.end())
auto wheelComponent = m_World->GetComponent<Components::Wheel>(entity, "Wheel");
if (wheelComponent)
{
SetUpPhysicsState(entity, parent);
EntityID car = m_World->GetEntityParent(entity);
if(m_Vehicles.find(car) != m_Vehicles.end())
{
hkVector4 position;
hkQuaternion orientation;
m_Vehicles[car]->calcCurrentPositionAndRotation(m_RigidBodies[car], m_Vehicles[car]->m_suspension, wheelComponent->ID, position, orientation);
hkVector4 chassisPosition = m_RigidBodies[car]->getPosition();
hkQuaternion chassisOrientation = m_RigidBodies[car]->getRotation();
glm::vec3 relativePos = glm::vec3(chassisPosition(0), chassisPosition(1), chassisPosition(2)) - glm::vec3(position(0), position(1), position(2));
glm::quat relativeOrientation = glm::quat(orientation(3), orientation(0), orientation(1), orientation(2));
transformComponent->Position = relativePos;
//transformComponent->Orientation = relativeOrientation;
}
}
else
{
hkVector4 position = m_RigidBodies[entity]->getPosition();
transformComponent->Position = glm::vec3(position(0), position(1), position(2));
hkQuaternion orientation = m_RigidBodies[entity]->getRotation();
transformComponent->Orientation = glm::quat(orientation(3),orientation(0), orientation(1), orientation(2));
if(m_Vehicles.find(entity) != m_Vehicles.end())
{
hkVector4 position = m_RigidBodies[entity]->getPosition();
transformComponent->Position = glm::vec3(position(0), position(1), position(2));
hkQuaternion orientation = m_RigidBodies[entity]->getRotation();
transformComponent->Orientation = glm::quat(orientation(3),orientation(0), orientation(1), orientation(2));
}
}
// HACK: Vehicle test-controls
auto vehicleComponent = m_World->GetComponent<Components::Vehicle>(entity, "Vehicle");
@@ -127,6 +145,118 @@ void Systems::PhysicsSystem::UpdateEntity(double dt, EntityID entity, EntityID p
}
}
void Systems::PhysicsSystem::OnEntityCommit( EntityID entity )
{
auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
if (!transformComponent)
return;
auto wheelComponent = m_World->GetComponent<Components::Wheel>(entity, "Wheel");
if (wheelComponent)
{
wheelComponent->ID = m_Wheels.size();
m_Wheels.push_back(entity);
}
auto physicsComponent = m_World->GetComponent<Components::Physics>(entity, "Physics");
if (!physicsComponent)
return;
auto sphereComponent = m_World->GetComponent<Components::Sphere >(entity, "Sphere");
auto boxComponent = m_World->GetComponent<Components::Box >(entity, "Box");
hkpConvexShape* shape;
hkpRigidBodyCinfo rigidBodyInfo;
hkMassProperties massProperties;
if (sphereComponent)
{
shape = new hkpSphereShape(sphereComponent->Radius);
rigidBodyInfo.m_shape = shape;
if (physicsComponent->Static)
{
rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED;
}
else
{
rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA;
}
hkpInertiaTensorComputer::computeSphereVolumeMassProperties(sphereComponent->Radius, physicsComponent->Mass, massProperties);
}
else if (boxComponent)
{
hkReal thickness = 0.05;
shape = new hkpBoxShape(hkVector4(boxComponent->Width - thickness, boxComponent->Height - thickness, boxComponent->Depth - thickness));
rigidBodyInfo.m_shape = shape;
if (physicsComponent->Static)
{
rigidBodyInfo.m_motionType = hkpMotion::MOTION_FIXED;
}
else
{
rigidBodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
}
hkpInertiaTensorComputer::computeBoxSurfaceMassProperties(hkVector4(boxComponent->Width - thickness, boxComponent->Height - thickness, boxComponent->Depth - thickness), physicsComponent->Mass, thickness, massProperties);
}
else
{
return;
}
rigidBodyInfo.m_position.set(transformComponent->Position.x, transformComponent->Position.y, transformComponent->Position.z);
rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass;
rigidBodyInfo.m_mass = massProperties.m_mass;
// Create RigidBody
hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo);
auto vehicleComponent = m_World->GetComponent<Components::Vehicle >(entity, "Vehicle");
if (vehicleComponent && m_Vehicles.find(entity) == m_Vehicles.end())
{
for (int i = 0; i < m_Wheels.size(); i++)
{
if(m_World->GetEntityParent(m_Wheels[i]) != entity)
{
m_Wheels.erase(m_Wheels.begin() + i);
i--;
}
}
VehicleSetup vehicleSetup;
// Create the basic vehicle.
m_Vehicles[entity] = new hkpVehicleInstance(rigidBody);
vehicleSetup.buildVehicle(m_World, m_PhysicsWorld, *m_Vehicles[entity], entity, m_Wheels);
// Add the vehicle's entities and phantoms to the world
m_Vehicles[entity]->addToWorld(m_PhysicsWorld);
m_RigidBodies[entity] = rigidBody;
// The vehicle is an action
m_PhysicsWorld->addAction(m_Vehicles[entity]);
//m_Vehicles[entity]->m_rpm = 0.0f; // Not sure why this one should be here
m_Wheels.clear();
shape->removeReference();
rigidBody->removeReference();
}
else
{
m_PhysicsWorld->addEntity(rigidBody);
m_RigidBodies[entity] = rigidBody;
shape->removeReference();
rigidBody->removeReference();
}
}
/*
void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent)
{
auto transformComponent = m_World->GetComponent<Components::Transform>(entity, "Transform");
@@ -221,6 +351,8 @@ void Systems::PhysicsSystem::SetUpPhysicsState(EntityID entity, EntityID parent)
rigidBody->removeReference();
}
}
*/
@@ -268,6 +400,7 @@ void Systems::PhysicsSystem::StepVisualDebugger()
void HK_CALL Systems::PhysicsSystem::HavokErrorReport(const char* msg, void*)
{
LOG_DEBUG("%s", msg);
LOG_INFO("%s", msg);
}
+2 -2
View File
@@ -58,7 +58,7 @@ public:
void UpdateEntity(double dt, EntityID entity, EntityID parent) override;
void OnComponentCreated(std::string type, std::shared_ptr<Component> component) override;
void OnComponentRemoved(std::string type, Component* component) override;
void OnEntityCommit(EntityID entity) override;
private:
double m_Accumulator;
@@ -75,7 +75,7 @@ private:
std::unordered_map<EntityID, hkpRigidBody*> m_RigidBodies;
std::unordered_map<EntityID, hkpVehicleInstance*> m_Vehicles;
std::vector<EntityID> m_Wheels;
hkpVehicleInstance* Systems::PhysicsSystem::createVehicle(VehicleSetup& vehicleSetup, hkpRigidBody* chassis);
};