Skip to content
Permalink
Browse files

Combine static physical objects with irrlicht GeometryCreator

  • Loading branch information...
Benau authored and deveee committed Feb 27, 2019
1 parent 4496dc3 commit 7fb3aa7570aeee3c04e51841dbedaaaee6ab1fa7
@@ -873,3 +873,136 @@ std::function<void()> PhysicalObject::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
@@ -286,6 +286,8 @@ class PhysicalObject : public Rewinder,
virtual void restoreState(BareNetworkString *buffer, int count);
virtual void undoState(BareNetworkString *buffer) {}
virtual std::function<void()> getLocalStateRestoreFunction();
bool hasTriangleMesh() const { return m_triangle_mesh != NULL; }
void joinToMainTrack();
LEAK_CHECK()
}; // PhysicalObject

@@ -997,9 +997,9 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
Vec3 normals[3];

#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();
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
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);
main_loop->renderGUI(5600);

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

#endif
@@ -31,6 +31,7 @@
#include "io/xml_node.hpp"
#include "input/device_manager.hpp"
#include "items/item_manager.hpp"
#include "network/network_config.hpp"
#include "physics/physical_object.hpp"
#include "race/race_manager.hpp"
#include "scriptengine/script_engine.hpp"
@@ -740,3 +741,33 @@ scene::IAnimatedMeshSceneNode* TrackObject::getMesh()
Log::debug("TrackObject", "No animated mesh");
return NULL;
} // 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
@@ -249,6 +249,8 @@ class TrackObject : public NoCopy
std::vector<TrackObject*>& getChildren() { return m_children; }
// ------------------------------------------------------------------------
void movePhysicalBodyToGraphicalNode(const core::vector3df& xyz, const core::vector3df& hpr);
// ------------------------------------------------------------------------
bool joinToMainTrack();
LEAK_CHECK()
}; // TrackObject

@@ -71,7 +71,7 @@ class TrackObjectManager
void insertObject(TrackObject* object);

void removeObject(TrackObject* who);

void removeDriveableObject(TrackObject* obj) { m_driveable_objects.remove(obj); }
TrackObject* getTrackObject(const std::string& libraryInstance, const std::string& name);

PtrVector<TrackObject>& getObjects() { return m_all_objects; }

0 comments on commit 7fb3aa7

Please sign in to comment.
You can’t perform that action at this time.