Combine static physical objects with irrlicht GeometryCreator
This commit is contained in:
parent
4496dc305b
commit
7fb3aa7570
@ -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 @@ public:
|
||||
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 @@ private:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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 @@ public:
|
||||
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; }
|
||||
|
Loading…
Reference in New Issue
Block a user