From 4ea6e14299c87509c556a53115b15d0859ba0086 Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Thu, 22 Jan 2015 20:16:28 +0000 Subject: [PATCH] Improve vehicle door dynamics + Vehicle doors should move in the right direction now + Fix debugging draw class for bullet --- rwengine/include/objects/VehicleObject.hpp | 2 + rwengine/include/render/DebugDraw.hpp | 23 ++--- rwengine/src/ai/CharacterController.cpp | 30 ++++-- rwengine/src/loaders/TextureLoader.cpp | 2 +- rwengine/src/objects/VehicleObject.cpp | 50 ++++++---- rwengine/src/render/DebugDraw.cpp | 104 +++++++++++---------- rwengine/src/render/OpenGLRenderer.cpp | 1 - rwgame/RWGame.cpp | 28 +++++- 8 files changed, 150 insertions(+), 90 deletions(-) diff --git a/rwengine/include/objects/VehicleObject.hpp b/rwengine/include/objects/VehicleObject.hpp index 5b4b5c08..8dbc296a 100644 --- a/rwengine/include/objects/VehicleObject.hpp +++ b/rwengine/include/objects/VehicleObject.hpp @@ -40,6 +40,8 @@ public: btHingeConstraint* constraint; bool holdAngle; float targetAngle; + float openAngle; + float closedAngle; }; std::map dynamicParts; diff --git a/rwengine/include/render/DebugDraw.hpp b/rwengine/include/render/DebugDraw.hpp index 7a91a9b3..2c4c7b01 100644 --- a/rwengine/include/render/DebugDraw.hpp +++ b/rwengine/include/render/DebugDraw.hpp @@ -1,11 +1,8 @@ #pragma once #include - -#define GLEW_STATIC -#include -#include -#include +#include +#include "Model.hpp" class DebugDraw : public btIDebugDraw { @@ -21,21 +18,21 @@ public: void setDebugMode(int debugMode); int getDebugMode() const; - void drawAllLines(); + void flush(GameRenderer* renderer); - void setShaderProgram(GLuint shaderProgram) { + void setShaderProgram(Renderer::ShaderProgram* shaderProgram) { this->shaderProgram = shaderProgram; } protected: int debugMode; - std::vector lines; - size_t maxlines; + std::vector lines; + size_t maxlines; + GeometryBuffer* lineBuff; + DrawBuffer* dbuff; - btVector3 color; + Renderer::ShaderProgram* shaderProgram; - GLuint shaderProgram; - - GLuint vbo, vao, texture; + GLuint texture; }; diff --git a/rwengine/src/ai/CharacterController.cpp b/rwengine/src/ai/CharacterController.cpp index 0ef4a41c..52b38189 100644 --- a/rwengine/src/ai/CharacterController.cpp +++ b/rwengine/src/ai/CharacterController.cpp @@ -1,8 +1,11 @@ #include #include #include + +#include #include #include +#include bool CharacterController::updateActivity() { @@ -69,6 +72,22 @@ void CharacterController::update(float dt) if( _currentActivity == nullptr ) { /// @todo play _low variant if car has low flag. character->playAnimation(character->animations.car_sit, true); + + // If character is idle in vehicle, close door. + if( glm::length( d ) <= 0.1f ) + { + auto entryDoor = character->getCurrentVehicle()->getSeatEntryDoor(character->getCurrentSeat()); + + if( entryDoor && entryDoor->constraint ) + { + character->getCurrentVehicle()->setPartTarget(entryDoor, true, entryDoor->closedAngle); + } + } + else + { + auto entryDoor = character->getCurrentVehicle()->getSeatEntryDoor(character->getCurrentSeat()); + entryDoor->holdAngle = false; + } } } else { @@ -242,7 +261,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr } else if( entryDoor && character->animator->getAnimationTime() >= 0.5f ) { - vehicle->setPartTarget(entryDoor, true, 1.f); + vehicle->setPartTarget(entryDoor, true, entryDoor->openAngle); } else { //character->setPosition(vehicle->getSeatEntryPosition(seat)); @@ -251,11 +270,6 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr } else if( character->animator->getAnimation() == anm_enter ) { if( character->animator->isCompleted() ) { - if( entryDoor ) - { - vehicle->setPartTarget(entryDoor, true, 0.f); - } - // VehicleGetIn is over, finish activity return true; } @@ -275,7 +289,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr character->rotation = vehicle->getRotation(); // Determine if the door open animation should be skipped. - if( entryDoor == nullptr || (entryDoor->constraint != nullptr && entryDoor->constraint->getHingeAngle() >= 0.6f ) ) + if( entryDoor == nullptr || (entryDoor->constraint != nullptr && glm::abs(entryDoor->constraint->getHingeAngle()) >= 0.6f ) ) { character->playAnimation(anm_enter, false); character->enterVehicle(vehicle, seat); @@ -329,7 +343,7 @@ bool Activities::ExitVehicle::update(CharacterObject *character, CharacterContro auto door = vehicle->getSeatEntryDoor(character->getCurrentSeat()); if( door ) { - vehicle->setPartTarget(door, true, 1.f); + vehicle->setPartTarget(door, true, door->openAngle); } } diff --git a/rwengine/src/loaders/TextureLoader.cpp b/rwengine/src/loaders/TextureLoader.cpp index 44f9f33c..ca1967a5 100644 --- a/rwengine/src/loaders/TextureLoader.cpp +++ b/rwengine/src/loaders/TextureLoader.cpp @@ -159,7 +159,7 @@ GLuint createTexture(RW::BSTextureNative& texNative, RW::BinaryStreamSection& ro break; } - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, texFilter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, texFilter); GLenum texwrap = GL_REPEAT; diff --git a/rwengine/src/objects/VehicleObject.cpp b/rwengine/src/objects/VehicleObject.cpp index f56dc860..48fa2ae8 100644 --- a/rwengine/src/objects/VehicleObject.cpp +++ b/rwengine/src/objects/VehicleObject.cpp @@ -8,7 +8,7 @@ #include #include -#define PART_CLOSE_VELOCITY 0.5f +#define PART_CLOSE_VELOCITY 0.25f VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, ModelHandle* model, VehicleDataHandle data, VehicleInfoHandle info, const glm::u8vec3& prim, const glm::u8vec3& sec) : GameObject(engine, pos, rot, model), @@ -297,25 +297,30 @@ void VehicleObject::tickPhysics(float dt) if(it.second.body == nullptr) continue; auto inv = glm::inverse(getRotation()); auto rot = it.second.body->getWorldTransform().getRotation(); + auto pos = it.second.body->getWorldTransform().getOrigin(); auto r2 = inv * glm::quat(rot.w(), rot.x(), rot.y(), rot.z()); + //auto p2 = inv * (glm::vec3(pos.x(), pos.y(), pos.z()) - getPosition()); auto& prev = skeleton->getData(it.second.dummy->getIndex()).a; auto next = prev; next.rotation = r2; + //next.translation = p2; skeleton->setData(it.second.dummy->getIndex(), { next, prev, true } ); if( it.second.holdAngle ) { it.second.constraint->setMotorTarget(it.second.targetAngle, 0.1f); } + it.second.constraint->enableMotor( it.second.holdAngle ); // If the part is moving quite fast and near the limit, lock it. /// @TODO not all parts rotate in the z axis. if(it.second.body->getAngularVelocity().getZ() >= PART_CLOSE_VELOCITY) { - auto d = it.second.constraint->getHingeAngle() - it.second.constraint->getLowerLimit(); - if( std::abs(d) < 0.01f ) + auto d = it.second.constraint->getHingeAngle() - it.second.closedAngle; + if( std::abs(d) < 0.05f ) { + it.second.holdAngle = false; setPartLocked(&(it.second), true); } } @@ -602,19 +607,28 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part) auto& geom = model->model->geometries[okframe->getGeometries()[0]]; auto gbounds = geom->geometryBounds; - + if( fn.find("door") != fn.npos ) { hingeAxis = {0.f, 0.f, 1.f}; - hingePosition = {0.f, 0.2f, 0.f}; - boxSize = {0.1f, 0.4f, gbounds.radius/2.f}; - boxOffset = {0.f,-0.2f, gbounds.center.z/2.f}; - if( sign > 0.f ) { - hingeMin = -glm::quarter_pi() * 1.5f; - hingeMax = 0.f; - } - else { + //hingePosition = {0.f, 0.2f, 0.f}; + boxSize = {0.15f, 0.5f, 0.6f}; + //boxOffset = {0.f,-0.2f, gbounds.center.z/2.f}; + auto tf = gbounds.center; + boxOffset = btVector3(tf.x, tf.y, tf.z); + hingePosition = -boxOffset; + + if( sign < 0.f ) { hingeMax = glm::quarter_pi() * 1.5f; hingeMin = 0.f; + part->openAngle = hingeMax; + part->closedAngle = hingeMin; + } + else + { + hingeMin = glm::quarter_pi() * -1.5f; + hingeMax = 0.f; + part->openAngle = hingeMin; + part->closedAngle = hingeMax; } } else if( fn.find("bonnet") != fn.npos ) { @@ -637,14 +651,11 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part) auto o = glm::toQuat(part->dummy->getDefaultRotation()); tr.setOrigin(btVector3(p.x, p.y, p.z)); tr.setRotation(btQuaternion(o.x, o.y, o.z, o.w)); - dms->setWorldTransform(local * tr); - btCompoundShape* cs = new btCompoundShape; - btCollisionShape* bshape = new btBoxShape( boxSize ); + btCollisionShape* cs = new btBoxShape( boxSize ); btTransform t; t.setIdentity(); t.setOrigin(boxOffset); - cs->addChildShape(t, bshape); btVector3 inertia; cs->calculateLocalInertia(10.f, inertia); @@ -659,9 +670,10 @@ void VehicleObject::createObjectHinge(btTransform& local, Part *part) tr.getOrigin(), hingePosition, hingeAxis, hingeAxis); hinge->setLimit(hingeMin, hingeMax); - - //engine->dynamicsWorld->addRigidBody(subObject); - //engine->dynamicsWorld->addConstraint(hinge, true); + hinge->setBreakingImpulseThreshold(250.f); + + engine->dynamicsWorld->addRigidBody(subObject); + engine->dynamicsWorld->addConstraint(hinge, true); part->body = subObject; part->constraint = hinge; diff --git a/rwengine/src/render/DebugDraw.cpp b/rwengine/src/render/DebugDraw.cpp index 2041f54e..2d0aa112 100644 --- a/rwengine/src/render/DebugDraw.cpp +++ b/rwengine/src/render/DebugDraw.cpp @@ -10,25 +10,48 @@ #include DebugDraw::DebugDraw() +: shaderProgram(nullptr) { - glGenBuffers(1, &vbo); - glGenVertexArrays(1, &vao); + lineBuff = new GeometryBuffer; + dbuff = new DrawBuffer; + dbuff->setFaceType(GL_LINES); + glGenTextures(1, &texture); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture); + int img = 0xFFFFFFFF; + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, + 0, GL_RGBA, GL_UNSIGNED_BYTE, &img + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + maxlines = 0; } DebugDraw::~DebugDraw() { - glDeleteBuffers(1, &vbo); - glDeleteVertexArrays(1, &vbo); - glDeleteTextures(1, &texture); + delete dbuff; + delete lineBuff; } void DebugDraw::drawLine(const btVector3 &from, const btVector3 &to, const btVector3 &color) { - lines.push_back(glm::vec3(from.getX(), from.getY(), from.getZ())); - lines.push_back(glm::vec3(to.getX(), to.getY(), to.getZ())); - this->color = color; + btVector3 c = color * 255; + lines.push_back({ + glm::vec3(from.getX(), from.getY(), from.getZ()), + glm::vec3(0.f), + glm::vec2(0.f), + glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255) + }); + lines.push_back({ + glm::vec3(to.getX(), to.getY(), to.getZ()), + glm::vec3(0.f), + glm::vec2(0.f), + glm::u8vec4(c.getX(), c.getY(), c.getZ(), 255) + }); } void DebugDraw::drawTriangle(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &color, btScalar alpha) @@ -72,48 +95,35 @@ void DebugDraw::drawContactPoint(const btVector3 &pointOnB, const btVector3 &nor } -void DebugDraw::drawAllLines() +void DebugDraw::flush(GameRenderer* renderer) { - if(lines.size() == 0) { - return; - } + if(lines.size() == 0) { + return; + } + + renderer->getRenderer()->useProgram(shaderProgram); + + lineBuff->uploadVertices(lines); + dbuff->addGeometry(lineBuff); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - float img[] = {color.getX(), color.getY(), color.getZ()}; - glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGB, 1, 1, - 0, GL_RGB, GL_FLOAT, img - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + Renderer::DrawParameters dp; + dp.texture = texture; + dp.ambient = 1.f; + dp.colour = glm::u8vec4(255, 255, 255, 255); + dp.start = 0; + dp.count = lines.size(); + dp.diffuse = 1.f; + + renderer->getRenderer()->drawArrays(glm::mat4(1.f), dbuff, dp); + + renderer->getRenderer()->invalidate(); + + glUseProgram(0); + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + glBindVertexArray( 0 ); - GLint posAttrib = glGetAttribLocation(shaderProgram, "position"); - GLint uniModel = glGetUniformLocation(shaderProgram, "model"); - - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - if( lines.size() > maxlines ) { - glBufferData(GL_ARRAY_BUFFER, sizeof(glm::vec3) * lines.size(), &lines[0].x, GL_STREAM_DRAW); - } - else { - glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(glm::vec3) * lines.size(), &lines[0].x); - } - maxlines = std::max(maxlines, lines.size()); - - glEnableVertexAttribArray(posAttrib); - glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0); - - glm::mat4 model; - glUniformMatrix4fv(uniModel, 1, GL_FALSE, glm::value_ptr(model)); - - glDrawArrays(GL_LINES, 0, lines.size()); - - lines.clear(); + lines.clear(); } void DebugDraw::reportErrorWarning(const char *warningString) diff --git a/rwengine/src/render/OpenGLRenderer.cpp b/rwengine/src/render/OpenGLRenderer.cpp index bf43c258..01962c5e 100644 --- a/rwengine/src/render/OpenGLRenderer.cpp +++ b/rwengine/src/render/OpenGLRenderer.cpp @@ -212,7 +212,6 @@ void OpenGLRenderer::draw(const glm::mat4& model, DrawBuffer* draw, const Render void OpenGLRenderer::drawArrays(const glm::mat4& model, DrawBuffer* draw, const Renderer::DrawParameters& p) { - useDrawBuffer(draw); useTexture(p.texture); diff --git a/rwgame/RWGame.cpp b/rwgame/RWGame.cpp index e843ffa9..544e710f 100644 --- a/rwgame/RWGame.cpp +++ b/rwgame/RWGame.cpp @@ -5,10 +5,15 @@ #include #include #include +#include #include