mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +02:00
Intial vehicle physics
This commit is contained in:
parent
22cb749073
commit
d4064480d1
@ -6,25 +6,27 @@
|
||||
GTACharacter::GTACharacter(GTAEngine* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::PEDS_t> ped)
|
||||
: GTAObject(engine, pos, rot, model), ped(ped), currentActivity(None), controller(nullptr)
|
||||
{
|
||||
animator = new Animator();
|
||||
animator->setModel(model);
|
||||
// Don't create anything without a valid model.
|
||||
if(model) {
|
||||
animator = new Animator();
|
||||
animator->setModel(model);
|
||||
|
||||
btTransform tf;
|
||||
tf.setIdentity();
|
||||
tf.setOrigin(btVector3(pos.x, pos.y, pos.z));
|
||||
btTransform tf;
|
||||
tf.setIdentity();
|
||||
tf.setOrigin(btVector3(pos.x, pos.y, pos.z));
|
||||
|
||||
physObject = new btPairCachingGhostObject;
|
||||
physObject->setWorldTransform(tf);
|
||||
physShape = new btBoxShape(btVector3(0.25f, 0.25f, 1.f));
|
||||
physObject->setCollisionShape(physShape);
|
||||
physObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
physCharacter = new btKinematicCharacterController(physObject, physShape, 0.65f, 2);
|
||||
physObject = new btPairCachingGhostObject;
|
||||
physObject->setWorldTransform(tf);
|
||||
physShape = new btBoxShape(btVector3(0.25f, 0.25f, 1.f));
|
||||
physObject->setCollisionShape(physShape);
|
||||
physObject->setCollisionFlags(btCollisionObject::CF_CHARACTER_OBJECT);
|
||||
physCharacter = new btKinematicCharacterController(physObject, physShape, 0.65f, 2);
|
||||
|
||||
engine->dynamicsWorld->addCollisionObject(physObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
|
||||
engine->dynamicsWorld->addAction(physCharacter);
|
||||
|
||||
changeAction(Idle);
|
||||
engine->dynamicsWorld->addCollisionObject(physObject, btBroadphaseProxy::CharacterFilter, btBroadphaseProxy::StaticFilter|btBroadphaseProxy::DefaultFilter);
|
||||
engine->dynamicsWorld->addAction(physCharacter);
|
||||
|
||||
changeAction(Idle);
|
||||
}
|
||||
}
|
||||
|
||||
void GTACharacter::changeAction(Activity newAction)
|
||||
|
@ -88,6 +88,7 @@ void GTAData::load()
|
||||
|
||||
loadCarcols(datpath+"/data/carcols.dat");
|
||||
loadWeather(datpath+"/data/timecyc.dat");
|
||||
loadHandling(datpath+"/data/handling.cfg");
|
||||
loadWaterpro(datpath+"/data/waterpro.dat");
|
||||
loadWater(datpath+"/data/water.dat");
|
||||
|
||||
@ -279,6 +280,60 @@ void GTAData::loadWeather(const std::string &path)
|
||||
weatherLoader.load(path);
|
||||
}
|
||||
|
||||
void GTAData::loadHandling(const std::string& path)
|
||||
{
|
||||
std::ifstream hndFile(path.c_str());
|
||||
|
||||
if(! hndFile.is_open()) {
|
||||
std::cerr << "Error loadind handling data " << path << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::string lineBuff;
|
||||
|
||||
while(std::getline(hndFile, lineBuff)) {
|
||||
if(lineBuff.at(0) == ';') continue;
|
||||
std::stringstream ss(lineBuff);
|
||||
|
||||
VehicleHandlingInfo info;
|
||||
ss >> info.ID;
|
||||
ss >> info.mass;
|
||||
ss >> info.dimensions.x;
|
||||
ss >> info.dimensions.y;
|
||||
ss >> info.dimensions.z;
|
||||
ss >> info.centerOfMass.x;
|
||||
ss >> info.centerOfMass.y;
|
||||
ss >> info.centerOfMass.z;
|
||||
ss >> info.percentSubmerged;
|
||||
ss >> info.tractionMulti;
|
||||
ss >> info.tractionLoss;
|
||||
ss >> info.tractionBias;
|
||||
ss >> info.numGears;
|
||||
ss >> info.maxVelocity;
|
||||
ss >> info.acceleration;
|
||||
char dt, et;
|
||||
ss >> dt; ss >> et;
|
||||
info.driveType = (VehicleHandlingInfo::DriveType)dt;
|
||||
info.engineType = (VehicleHandlingInfo::EngineType)et;
|
||||
ss >> info.brakeDeceleration;
|
||||
ss >> info.brakeBias;
|
||||
ss >> info.ABS;
|
||||
ss >> info.steeringLock;
|
||||
ss >> info.suspensionForce;
|
||||
ss >> info.suspensionDamping;
|
||||
ss >> info.seatOffset;
|
||||
ss >> info.damageMulti;
|
||||
ss >> info.value;
|
||||
ss >> info.suspensionUpperLimit;
|
||||
ss >> info.suspensionLowerLimit;
|
||||
ss >> info.suspensionBias;
|
||||
ss >> std::hex >> info.flags;
|
||||
|
||||
vehicleInfo.insert({info.ID, {info}});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GTAData::loadWaterpro(const std::string& path)
|
||||
{
|
||||
std::ifstream ifstr(path.c_str());
|
||||
|
@ -247,21 +247,23 @@ void GTAEngine::createVehicle(const uint16_t id, const glm::vec3& pos, const glm
|
||||
}
|
||||
}
|
||||
|
||||
Model* model = gameData.models[vti->second->modelName];
|
||||
if(model) {
|
||||
if( vti->second->wheelPositions.size() == 0 ) {
|
||||
Model* model = gameData.models[vti->second->modelName];
|
||||
auto info = gameData.vehicleInfo.find(vti->second->handlingID);
|
||||
if(model && info != gameData.vehicleInfo.end()) {
|
||||
if( info->second.wheels.size() == 0 ) {
|
||||
for( size_t f = 0; f < model->frames.size(); ++f) {
|
||||
if( model->frameNames.size() > f) {
|
||||
std::string& name = model->frameNames[f];
|
||||
if( name.substr(0, 5) == "wheel" ) {
|
||||
vti->second->wheelPositions.push_back(model->frames[f].defaultTranslation);
|
||||
auto frameTrans = model->getFrameMatrix(f);
|
||||
info->second.wheels.push_back({glm::vec3(frameTrans[3])});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vehicleInstances.push_back(new GTAVehicle{ this, pos, rot, model, vti->second, prim, sec });
|
||||
vehicleInstances.push_back(new GTAVehicle{ this, pos, rot, model, vti->second, info->second, prim, sec });
|
||||
}
|
||||
}
|
||||
|
||||
@ -283,10 +285,12 @@ GTACharacter* GTAEngine::createPedestrian(const uint16_t id, const glm::vec3 &po
|
||||
|
||||
Model* model = gameData.models[pt->modelName];
|
||||
|
||||
auto ped = new GTACharacter( this, pos, rot, model, pt );
|
||||
pedestrians.push_back(ped);
|
||||
new GTADefaultAIController(ped);
|
||||
return ped;
|
||||
if(model != nullptr) {
|
||||
auto ped = new GTACharacter( this, pos, rot, model, pt );
|
||||
pedestrians.push_back(ped);
|
||||
new GTADefaultAIController(ped);
|
||||
return ped;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -362,19 +362,21 @@ void GTARenderer::renderWorld()
|
||||
matrixModel = glm::translate(matrixModel, inst->getPosition());
|
||||
matrixModel = matrixModel * glm::mat4_cast(inst->getRotation());
|
||||
|
||||
glm::mat4 matrixVehicle = matrixModel;
|
||||
|
||||
renderModel(inst->model, matrixModel, inst);
|
||||
|
||||
// Draw wheels n' stuff
|
||||
for( size_t w = 0; w < inst->vehicle->wheelPositions.size(); ++w) {
|
||||
for( size_t w = 0; w < inst->info.wheels.size(); ++w) {
|
||||
auto woi = engine->objectTypes.find(inst->vehicle->wheelModelID);
|
||||
if(woi != engine->objectTypes.end()) {
|
||||
Model* wheelModel = engine->gameData.models["wheels"];
|
||||
if( wheelModel) {
|
||||
glm::mat4 wheelMatrix = glm::translate(glm::mat4(), inst->vehicle->wheelPositions[w]);
|
||||
wheelMatrix = glm::scale(wheelMatrix, glm::vec3(1.f, inst->vehicle->wheelScale, inst->vehicle->wheelScale));
|
||||
renderNamedFrame(wheelModel, matrixVehicle * wheelMatrix, woi->second->modelName);
|
||||
// Tell bullet to update the matrix for this wheel.
|
||||
inst->physVehicle->updateWheelTransform(w, false);
|
||||
glm::mat4 wheel_tf;
|
||||
inst->physVehicle->getWheelTransformWS(w).getOpenGLMatrix(glm::value_ptr(wheel_tf));
|
||||
wheel_tf = glm::scale(wheel_tf, glm::vec3(inst->vehicle->wheelScale));
|
||||
wheel_tf = glm::rotate(wheel_tf, inst->physVehicle->getWheelInfo(w).m_rotation, glm::vec3(1.f, 0.f, 0.f));
|
||||
renderNamedFrame(wheelModel, /*matrixVehicle **/ wheel_tf, woi->second->modelName);
|
||||
}
|
||||
else {
|
||||
std::cout << "Wheel model " << woi->second->modelName << " not loaded" << std::endl;
|
||||
|
@ -1,8 +1,9 @@
|
||||
#include <renderwure/objects/GTAVehicle.hpp>
|
||||
#include <renderwure/engine/GTAEngine.hpp>
|
||||
#include <BulletDynamics/Vehicle/btRaycastVehicle.h>
|
||||
|
||||
GTAVehicle::GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::CARS_t> veh, const glm::vec3& prim, const glm::vec3& sec)
|
||||
: GTAObject(engine, pos, rot, model), vehicle(veh), colourPrimary(prim), colourSecondary(sec), physBody(nullptr)
|
||||
GTAVehicle::GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::CARS_t> veh, const VehicleInfo& info, const glm::vec3& prim, const glm::vec3& sec)
|
||||
: GTAObject(engine, pos, rot, model), vehicle(veh), info(info), colourPrimary(prim), colourSecondary(sec), physBody(nullptr), physVehicle(nullptr)
|
||||
{
|
||||
if(! veh->modelName.empty()) {
|
||||
auto phyit = engine->gameData.collisions.find(veh->modelName);
|
||||
@ -19,6 +20,8 @@ GTAVehicle::GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat&
|
||||
));
|
||||
CollisionInstance& physInst = *phyit->second.get();
|
||||
|
||||
btVector3 com(info.handling.centerOfMass.x, info.handling.centerOfMass.y, info.handling.centerOfMass.z);
|
||||
|
||||
// Boxes
|
||||
for( size_t i = 0; i < physInst.boxes.size(); ++i ) {
|
||||
CollTBox& box = physInst.boxes[i];
|
||||
@ -54,12 +57,36 @@ GTAVehicle::GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat&
|
||||
}
|
||||
|
||||
btVector3 inertia(0,0,0);
|
||||
cmpShape->calculateLocalInertia(1000.f, inertia);
|
||||
cmpShape->calculateLocalInertia(info.handling.mass, inertia);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo info(1000.f, msta, cmpShape, inertia);
|
||||
btRigidBody::btRigidBodyConstructionInfo rginfo(info.handling.mass, msta, cmpShape, inertia);
|
||||
|
||||
physBody = new btRigidBody(info);
|
||||
physBody = new btRigidBody(rginfo);
|
||||
engine->dynamicsWorld->addRigidBody(physBody);
|
||||
|
||||
physRaycaster = new btDefaultVehicleRaycaster(engine->dynamicsWorld);
|
||||
btRaycastVehicle::btVehicleTuning tuning;
|
||||
|
||||
float travel = info.handling.suspensionUpperLimit - info.handling.suspensionLowerLimit;
|
||||
tuning.m_maxSuspensionTravelCm = (travel)*100.f;
|
||||
tuning.m_frictionSlip = info.handling.tractionMulti * 10.f;
|
||||
|
||||
physVehicle = new btRaycastVehicle(tuning, physBody, physRaycaster);
|
||||
physVehicle->setCoordinateSystem(0, 2, 1);
|
||||
physBody->setActivationState(DISABLE_DEACTIVATION);
|
||||
engine->dynamicsWorld->addVehicle(physVehicle);
|
||||
|
||||
for(size_t w = 0; w < info.wheels.size(); ++w) {
|
||||
btVector3 connection(info.wheels[w].position.x, info.wheels[w].position.y, info.wheels[w].position.z);
|
||||
bool front = connection.y() > 0;
|
||||
btWheelInfo& wi = physVehicle->addWheel(connection, btVector3(0.f, 0.f, -1.f), btVector3(1.f, 0.f, 0.f), travel*0.45f, veh->wheelScale / 2.f, tuning, front);
|
||||
wi.m_wheelsSuspensionForce = info.handling.mass * 1.5f;
|
||||
wi.m_suspensionStiffness = 20.f;
|
||||
wi.m_wheelsDampingRelaxation = 2.3;
|
||||
wi.m_wheelsDampingCompression = 4.4f;
|
||||
wi.m_frictionSlip = tuning.m_frictionSlip * (front ? info.handling.tractionBias : 1.f - info.handling.tractionBias);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,3 +108,22 @@ glm::quat GTAVehicle::getRotation() const
|
||||
}
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void GTAVehicle::tick(float dt)
|
||||
{
|
||||
if(physVehicle) {
|
||||
for(size_t w = 0; w < physVehicle->getNumWheels(); ++w) {
|
||||
btWheelInfo& wi = physVehicle->getWheelInfo(w);
|
||||
if( info.handling.driveType == VehicleHandlingInfo::All ||
|
||||
(info.handling.driveType == VehicleHandlingInfo::Forward && wi.m_bIsFrontWheel) ||
|
||||
(info.handling.driveType == VehicleHandlingInfo::Rear && !wi.m_bIsFrontWheel))
|
||||
{
|
||||
physVehicle->applyEngineForce(info.handling.acceleration * info.handling.mass * 0.1f, w);
|
||||
}
|
||||
|
||||
/*if(wi.m_bIsFrontWheel) {
|
||||
physVehicle->setSteeringValue(info.handling.steeringLock*(3.141/180.f), w);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <renderwure/loaders/LoaderIFP.hpp>
|
||||
#include <renderwure/loaders/WeatherLoader.hpp>
|
||||
#include <renderwure/loaders/LoaderCOL.hpp>
|
||||
#include <renderwure/objects/VehicleInfo.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -94,6 +95,8 @@ public:
|
||||
void loadCarcols(const std::string& path);
|
||||
|
||||
void loadWeather(const std::string& path);
|
||||
|
||||
void loadHandling(const std::string& path);
|
||||
|
||||
/**
|
||||
* Loads water level data
|
||||
@ -168,6 +171,11 @@ public:
|
||||
* The vehicle colours for each vehicle type
|
||||
*/
|
||||
std::map<std::string, std::vector<std::pair<size_t,size_t>>> vehiclePalettes;
|
||||
|
||||
/**
|
||||
* Vehicle information
|
||||
*/
|
||||
std::map<std::string, VehicleInfo> vehicleInfo;
|
||||
|
||||
/**
|
||||
* Texture Loader
|
||||
|
@ -91,7 +91,6 @@ public:
|
||||
int16_t modelLOD; // used only when type == PLANE
|
||||
};
|
||||
float wheelScale; // used only when type == CAR
|
||||
std::vector<glm::vec3> wheelPositions;
|
||||
};
|
||||
|
||||
struct PEDS_t
|
||||
|
@ -3,6 +3,7 @@
|
||||
#define _GTAVEHICLE_HPP_
|
||||
#include <renderwure/engine/GTAObject.hpp>
|
||||
#include <bullet/btBulletDynamicsCommon.h>
|
||||
#include <renderwure/objects/VehicleInfo.hpp>
|
||||
|
||||
/**
|
||||
* @class GTAVehicle
|
||||
@ -11,18 +12,30 @@
|
||||
struct GTAVehicle : public GTAObject
|
||||
{
|
||||
std::shared_ptr<LoaderIDE::CARS_t> vehicle; /// Vehicle type
|
||||
VehicleInfo info;
|
||||
glm::vec3 colourPrimary;
|
||||
glm::vec3 colourSecondary;
|
||||
|
||||
btRigidBody* physBody;
|
||||
btVehicleRaycaster* physRaycaster;
|
||||
btRaycastVehicle* physVehicle;
|
||||
|
||||
GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<LoaderIDE::CARS_t> veh, const glm::vec3& prim, const glm::vec3& sec);
|
||||
GTAVehicle(GTAEngine* engine,
|
||||
const glm::vec3& pos,
|
||||
const glm::quat& rot,
|
||||
Model* model,
|
||||
std::shared_ptr<LoaderIDE::CARS_t> veh,
|
||||
const VehicleInfo& info,
|
||||
const glm::vec3& prim,
|
||||
const glm::vec3& sec);
|
||||
|
||||
glm::vec3 getPosition() const;
|
||||
|
||||
glm::quat getRotation() const;
|
||||
|
||||
Type type() { return Vehicle; }
|
||||
|
||||
void tick(float dt);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
83
framework2/include/renderwure/objects/VehicleInfo.hpp
Normal file
83
framework2/include/renderwure/objects/VehicleInfo.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
#pragma once
|
||||
#ifndef _VEHICLE_INFO_HPP_
|
||||
#define _VEHICLE_INFO_HPP_
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
struct VehicleHandlingInfo
|
||||
{
|
||||
enum EngineType
|
||||
{
|
||||
Diesel = 'D',
|
||||
Petrol = 'P',
|
||||
Electric = 'E'
|
||||
};
|
||||
|
||||
enum DriveType
|
||||
{
|
||||
Forward = 'F',
|
||||
Rear = 'R',
|
||||
All = '4'
|
||||
};
|
||||
|
||||
std::string ID;
|
||||
float mass;
|
||||
glm::vec3 dimensions;
|
||||
glm::vec3 centerOfMass;
|
||||
float percentSubmerged;
|
||||
float tractionMulti;
|
||||
float tractionLoss;
|
||||
float tractionBias;
|
||||
size_t numGears;
|
||||
float maxVelocity;
|
||||
float acceleration;
|
||||
DriveType driveType;
|
||||
EngineType engineType;
|
||||
float brakeDeceleration;
|
||||
float brakeBias;
|
||||
bool ABS;
|
||||
float steeringLock;
|
||||
float suspensionForce;
|
||||
float suspensionDamping;
|
||||
float seatOffset;
|
||||
float damageMulti;
|
||||
size_t value;
|
||||
float suspensionUpperLimit;
|
||||
float suspensionLowerLimit;
|
||||
float suspensionBias;
|
||||
uint32_t flags;
|
||||
|
||||
enum /*VehicleFlags*/ {
|
||||
VF_1G_BOOST = 1 << 0,
|
||||
VF_2G_BOOST = 2 << 0,
|
||||
VF_REV_BONNET = 4 << 0,
|
||||
VF_HANGING_BOOT = 8 << 0,
|
||||
VF_NO_DOORS = 1 << 8,
|
||||
VF_IS_VAN = 2 << 8,
|
||||
VF_IS_BUS = 4 << 8,
|
||||
VF_IS_LOW = 8 << 8,
|
||||
VF_DBL_EXHAUST = 1 << 16,
|
||||
VF_TAILGATE_BOOT= 2 << 16,
|
||||
VF_NOSWING_BOOT = 4 << 16,
|
||||
VF_NONPLAYER_STABILIZER = 8 << 16,
|
||||
VF_NEUTRALHANDLING = 1 << 16,
|
||||
VF_HAS_NO_ROOF = 2 << 16,
|
||||
VF_IS_BIG = 4 << 16,
|
||||
VF_HALOGEN_LIGHTS = 8 << 16
|
||||
};
|
||||
};
|
||||
|
||||
struct WheelInfo
|
||||
{
|
||||
glm::vec3 position;
|
||||
};
|
||||
|
||||
struct VehicleInfo
|
||||
{
|
||||
VehicleHandlingInfo handling;
|
||||
|
||||
std::vector<WheelInfo> wheels;
|
||||
};
|
||||
|
||||
#endif
|
@ -7,6 +7,7 @@
|
||||
#include <renderwure/ai/GTAAIController.hpp>
|
||||
#include <renderwure/ai/GTAPlayerAIController.hpp>
|
||||
#include <renderwure/objects/GTACharacter.hpp>
|
||||
#include <renderwure/objects/GTAVehicle.hpp>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
@ -97,17 +98,18 @@ void init(std::string gtapath)
|
||||
|
||||
plyPos = gta->itemCentroid / (float) gta->itemCount + glm::vec3(0, 0, 2);
|
||||
|
||||
glm::vec3 spawnPos = plyPos + glm::vec3(-5, -20, 0);
|
||||
glm::vec3 spawnPos = plyPos + glm::vec3(-5, -20, 0.0);
|
||||
size_t k = 1;
|
||||
// Spawn every vehicle, cause why not.
|
||||
for(std::map<uint16_t, std::shared_ptr<LoaderIDE::CARS_t>>::iterator it = gta->vehicleTypes.begin();
|
||||
it != gta->vehicleTypes.end(); ++it) {
|
||||
if(it->first == 140) continue; // get this plane out of here.
|
||||
gta->createVehicle(it->first, spawnPos);
|
||||
spawnPos += glm::vec3(5, 0, 0);
|
||||
if((k++ % 4) == 0) { spawnPos += glm::vec3(-20, -15, 0); }
|
||||
}
|
||||
|
||||
spawnPos = plyPos + glm::vec3(-5, 20 + (2.5 * gta->pedestrianTypes.size()/4), 0);
|
||||
spawnPos = plyPos + glm::vec3(-5, 20 + (2.5 * gta->pedestrianTypes.size()/4), 0);
|
||||
k = 1;
|
||||
// Spawn every pedestrian.
|
||||
for(auto it = gta->pedestrianTypes.begin();
|
||||
@ -193,10 +195,14 @@ void update(float dt)
|
||||
gta->renderer.camera.worldPos = plyPos;
|
||||
gta->renderer.camera.frustum.view = view;
|
||||
|
||||
// TODO: move this inside the engine
|
||||
for( size_t p = 0; p < gta->pedestrians.size(); ++p ) {
|
||||
gta->pedestrians[p]->tick(dt);
|
||||
}
|
||||
|
||||
for( size_t v = 0; v < gta->vehicleInstances.size(); ++v ) {
|
||||
gta->vehicleInstances[v]->tick(dt);
|
||||
}
|
||||
|
||||
gta->dynamicsWorld->stepSimulation(dt);
|
||||
}
|
||||
}
|
||||
@ -327,7 +333,7 @@ int main(int argc, char *argv[])
|
||||
while (window.pollEvent(event)) {
|
||||
handleEvent(event);
|
||||
}
|
||||
|
||||
|
||||
accum += clock.restart().asSeconds();
|
||||
|
||||
while ( accum >= ts ) {
|
||||
|
Loading…
Reference in New Issue
Block a user