Combine static physical objects with irrlicht GeometryCreator

This commit is contained in:
Benau 2019-02-27 11:06:18 +08:00 committed by Deve
parent 4496dc305b
commit 7fb3aa7570
7 changed files with 181 additions and 4 deletions

View File

@ -873,3 +873,136 @@ std::function<void()> PhysicalObject::getLocalStateRestoreFunction()
} }
}; };
} // getLocalStateRestoreFunction } // getLocalStateRestoreFunction
// ----------------------------------------------------------------------------
void PhysicalObject::joinToMainTrack()
{
auto sm = irr_driver->getSceneManager();
auto gc = sm->getGeometryCreator();
scene::IMeshManipulator* mani =
irr_driver->getVideoDriver()->getMeshManipulator();
if (m_body_type == MP_EXACT)
{
TrackObjectPresentationSceneNode* presentation =
m_object->getPresentation<TrackObjectPresentationSceneNode>();
assert(presentation);
Track::getCurrentTrack()->convertTrackToBullet(presentation->getNode());
}
else if (m_body_type == MP_CYLINDER_X || m_body_type == MP_CYLINDER_Y ||
m_body_type == MP_CYLINDER_Z)
{
btCylinderShape* cylinder = dynamic_cast<btCylinderShape*>(m_shape);
assert(cylinder);
btTransform t;
m_motion_state->getWorldTransform(t);
int up_axis = cylinder->getUpAxis();
scene::IMesh* mesh =
gc->createCylinderMesh(cylinder->getRadius(),
cylinder->getHalfExtentsWithMargin()[up_axis] * 2.0f,
std::max((int)(cylinder->getRadius() / 2.0f), 4));
scene::ISceneNode* node = sm->addMeshSceneNode(mesh);
mesh->drop();
core::matrix4 translate(core::matrix4::EM4CONST_IDENTITY);
Vec3 offset;
offset.setY(-cylinder->getHalfExtentsWithMargin()[up_axis]);
translate.setTranslation(offset.toIrrVector());
mani->transform(mesh, translate);
core::matrix4 adjust_axis(core::matrix4::EM4CONST_IDENTITY);
if (m_body_type == MP_CYLINDER_X)
adjust_axis.setRotationDegrees(core::vector3df(0, 0, -90));
else if (m_body_type == MP_CYLINDER_Z)
adjust_axis.setRotationDegrees(core::vector3df(90, 0, 0));
mani->transform(mesh, adjust_axis);
node->setPosition(Vec3(t.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(t.getRotation());
node->setRotation(hpr.toIrrHPR());
Track::getCurrentTrack()->convertTrackToBullet(node);
node->remove();
}
else if (m_body_type == MP_CONE_X || m_body_type == MP_CONE_Y ||
m_body_type == MP_CONE_Z)
{
btConeShape* cone = dynamic_cast<btConeShape*>(m_shape);
assert(cone);
btTransform t;
m_motion_state->getWorldTransform(t);
scene::IMesh* mesh =
gc->createConeMesh(cone->getRadius(),
cone->getHeight(),
std::max((int)(cone->getRadius() / 2.0f), 4));
scene::ISceneNode* node = sm->addMeshSceneNode(mesh);
mesh->drop();
core::matrix4 translate(core::matrix4::EM4CONST_IDENTITY);
Vec3 offset;
offset.setY(cone->getHeight() * -0.5f);
translate.setTranslation(offset.toIrrVector());
mani->transform(mesh, translate);
core::matrix4 adjust_axis(core::matrix4::EM4CONST_IDENTITY);
if (m_body_type == MP_CONE_X)
adjust_axis.setRotationDegrees(core::vector3df(0, 0, -90));
else if (m_body_type == MP_CONE_Z)
adjust_axis.setRotationDegrees(core::vector3df(90, 0, 0));
mani->transform(mesh, adjust_axis);
node->setPosition(Vec3(t.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(t.getRotation());
node->setRotation(hpr.toIrrHPR());
Track::getCurrentTrack()->convertTrackToBullet(node);
node->remove();
}
else if (m_body_type == MP_SPHERE)
{
btSphereShape* sphere = dynamic_cast<btSphereShape*>(m_shape);
assert(sphere);
btTransform t;
m_motion_state->getWorldTransform(t);
scene::IMesh* mesh =
gc->createSphereMesh(sphere->getRadius(),
std::max((int)(sphere->getRadius() / 2.0f), 4),
std::max((int)(sphere->getRadius() / 2.0f), 4));
scene::ISceneNode* node = sm->addMeshSceneNode(mesh);
mesh->drop();
node->setPosition(Vec3(t.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(t.getRotation());
node->setRotation(hpr.toIrrHPR());
Track::getCurrentTrack()->convertTrackToBullet(node);
node->remove();
}
else if (m_body_type == MP_BOX)
{
btBoxShape* box = dynamic_cast<btBoxShape*>(m_shape);
assert(box);
scene::IMesh* mesh =
gc->createCubeMesh(
Vec3(box->getHalfExtentsWithMargin() * 2.0f).toIrrVector());
scene::ISceneNode* node = sm->addMeshSceneNode(mesh);
mesh->drop();
btTransform t;
m_motion_state->getWorldTransform(t);
node->setPosition(Vec3(t.getOrigin()).toIrrVector());
Vec3 hpr;
hpr.setHPR(t.getRotation());
node->setRotation(hpr.toIrrHPR());
Track::getCurrentTrack()->convertTrackToBullet(node);
node->remove();
}
} // joinToMainTrack

View File

@ -286,6 +286,8 @@ public:
virtual void restoreState(BareNetworkString *buffer, int count); virtual void restoreState(BareNetworkString *buffer, int count);
virtual void undoState(BareNetworkString *buffer) {} virtual void undoState(BareNetworkString *buffer) {}
virtual std::function<void()> getLocalStateRestoreFunction(); virtual std::function<void()> getLocalStateRestoreFunction();
bool hasTriangleMesh() const { return m_triangle_mesh != NULL; }
void joinToMainTrack();
LEAK_CHECK() LEAK_CHECK()
}; // PhysicalObject }; // PhysicalObject

View File

@ -997,9 +997,9 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
Vec3 normals[3]; Vec3 normals[3];
#ifndef SERVER_ONLY #ifndef SERVER_ONLY
if (CVS->isGLSL()) SP::SPMeshBuffer* spmb = dynamic_cast<SP::SPMeshBuffer*>(mb);
if (spmb)
{ {
SP::SPMeshBuffer* spmb = static_cast<SP::SPMeshBuffer*>(mb);
video::S3DVertexSkinnedMesh* mbVertices = (video::S3DVertexSkinnedMesh*)mb->getVertices(); video::S3DVertexSkinnedMesh* mbVertices = (video::S3DVertexSkinnedMesh*)mb->getVertices();
for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++) for (unsigned int matrix_index = 0; matrix_index < matrices.size(); matrix_index++)
{ {
@ -2144,6 +2144,14 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
#endif #endif
main_loop->renderGUI(5500); main_loop->renderGUI(5500);
// Join all static physics only object to main track if possible
// Take the visibility condition by scripting into account
for (auto* to : m_track_object_manager->getObjects().m_contents_vector)
{
if (to->joinToMainTrack())
m_track_object_manager->removeDriveableObject(to);
}
createPhysicsModel(main_track_count); createPhysicsModel(main_track_count);
main_loop->renderGUI(5600); main_loop->renderGUI(5600);

View File

@ -394,7 +394,6 @@ private:
void loadDriveGraph(unsigned int mode_id, const bool reverse); void loadDriveGraph(unsigned int mode_id, const bool reverse);
void loadArenaGraph(const XMLNode &node); void loadArenaGraph(const XMLNode &node);
btQuaternion getArenaStartRotation(const Vec3& xyz, float heading); btQuaternion getArenaStartRotation(const Vec3& xyz, float heading);
void convertTrackToBullet(scene::ISceneNode *node);
bool loadMainTrack(const XMLNode &node); bool loadMainTrack(const XMLNode &node);
void loadMinimap(); void loadMinimap();
void createWater(const XMLNode &node); void createWater(const XMLNode &node);
@ -695,6 +694,8 @@ public:
const btTransform& getBlueFlag() const { return m_blue_flag; } const btTransform& getBlueFlag() const { return m_blue_flag; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isAddon() const { return m_is_addon; } bool isAddon() const { return m_is_addon; }
// ------------------------------------------------------------------------
void convertTrackToBullet(scene::ISceneNode *node);
}; // class Track }; // class Track
#endif #endif

View File

@ -31,6 +31,7 @@
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "input/device_manager.hpp" #include "input/device_manager.hpp"
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "network/network_config.hpp"
#include "physics/physical_object.hpp" #include "physics/physical_object.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "scriptengine/script_engine.hpp" #include "scriptengine/script_engine.hpp"
@ -740,3 +741,33 @@ scene::IAnimatedMeshSceneNode* TrackObject::getMesh()
Log::debug("TrackObject", "No animated mesh"); Log::debug("TrackObject", "No animated mesh");
return NULL; return NULL;
} // getMesh } // getMesh
// ----------------------------------------------------------------------------
bool TrackObject::joinToMainTrack()
{
// If no physical object or there is animator, skip it
// Also no joining if will affect kart (like moveable, flatten...)
if (!isEnabled() || !m_physical_object || m_animator ||
m_physical_object->isDynamic() || m_physical_object->isCrashReset() ||
m_physical_object->isExplodeKartObject() ||
m_physical_object->isFlattenKartObject())
return false;
// Scripting exploding barrel is assumed to be joinable in networking
// as it doesn't support it
if (!NetworkConfig::get()->isNetworking() &&
(!m_physical_object->getOnKartCollisionFunction().empty() ||
!m_physical_object->getOnItemCollisionFunction().empty()))
return false;
// Skip driveable non-exact shape object
// Notice driveable object should always has exact shape specified in
// blender
if (m_is_driveable && !m_physical_object->hasTriangleMesh())
return false;
m_physical_object->joinToMainTrack();
// This will remove the separated body
m_physical_object.reset();
return true;
} // joinToMainTrack

View File

@ -249,6 +249,8 @@ public:
std::vector<TrackObject*>& getChildren() { return m_children; } std::vector<TrackObject*>& getChildren() { return m_children; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void movePhysicalBodyToGraphicalNode(const core::vector3df& xyz, const core::vector3df& hpr); void movePhysicalBodyToGraphicalNode(const core::vector3df& xyz, const core::vector3df& hpr);
// ------------------------------------------------------------------------
bool joinToMainTrack();
LEAK_CHECK() LEAK_CHECK()
}; // TrackObject }; // TrackObject

View File

@ -71,7 +71,7 @@ public:
void insertObject(TrackObject* object); void insertObject(TrackObject* object);
void removeObject(TrackObject* who); void removeObject(TrackObject* who);
void removeDriveableObject(TrackObject* obj) { m_driveable_objects.remove(obj); }
TrackObject* getTrackObject(const std::string& libraryInstance, const std::string& name); TrackObject* getTrackObject(const std::string& libraryInstance, const std::string& name);
PtrVector<TrackObject>& getObjects() { return m_all_objects; } PtrVector<TrackObject>& getObjects() { return m_all_objects; }