Add track object copying to child process

This commit is contained in:
Benau 2020-02-28 19:52:17 +08:00
parent f3b5938b8e
commit 607c6932f0
5 changed files with 152 additions and 5 deletions

View File

@ -1018,3 +1018,108 @@ void PhysicalObject::joinToMainTrack()
}
} // joinToMainTrack
// ----------------------------------------------------------------------------
void PhysicalObject::copyFromMainProcess(TrackObject* track_obj)
{
m_no_server_state = false;
m_body_added = false;
m_object = track_obj;
if (m_triangle_mesh)
{
const TriangleMesh& old_tm = *m_triangle_mesh;
m_triangle_mesh = new TriangleMesh(/*can_be_transformed*/true);
m_triangle_mesh->copyFrom(old_tm);
}
// At the moment no bullet collision shape here has pointer in used in
// their member values, so we can use copy constructor directly
switch (m_body_type)
{
case MP_CONE_Y:
{
m_shape = new btConeShape(*static_cast<btConeShape*>(m_shape));
break;
}
case MP_CONE_X:
{
m_shape = new btConeShapeX(*static_cast<btConeShapeX*>(m_shape));
break;
}
case MP_CONE_Z:
{
m_shape = new btConeShapeZ(*static_cast<btConeShapeZ*>(m_shape));
break;
}
case MP_CYLINDER_Y:
{
m_shape = new btCylinderShape(*static_cast<btCylinderShape*>(m_shape));
break;
}
case MP_CYLINDER_X:
{
m_shape = new btCylinderShapeX(*static_cast<btCylinderShapeX*>(m_shape));
break;
}
case MP_CYLINDER_Z:
{
m_shape = new btCylinderShapeZ(*static_cast<btCylinderShapeZ*>(m_shape));
break;
}
case MP_SPHERE:
{
m_shape = new btSphereShape(*static_cast<btSphereShape*>(m_shape));
break;
}
case MP_EXACT:
{
assert(m_triangle_mesh);
m_triangle_mesh->createCollisionShape();
m_shape = &m_triangle_mesh->getCollisionShape();
break;
}
case MP_NONE:
default:
Log::warn("PhysicalObject", "Uninitialised moving shape");
// intended fall-through
case MP_BOX:
{
m_shape = new btBoxShape(*static_cast<btBoxShape*>(m_shape));
break;
}
}
m_motion_state = new btDefaultMotionState(m_init_pos);
btVector3 inertia(1,1,1);
if (m_body_type != MP_EXACT)
m_shape->calculateLocalInertia(m_mass, inertia);
else
{
if (m_mass == 0)
inertia.setValue(0, 0, 0);
}
btRigidBody::btRigidBodyConstructionInfo info(m_mass, m_motion_state,
m_shape, inertia);
btRigidBody* old_body = m_body;
if (m_triangle_mesh)
m_body = new TriangleMesh::RigidBodyTriangleMesh(m_triangle_mesh, info);
else
m_body = new btRigidBody(info);
m_user_pointer.set(this);
m_body->setUserPointer(&m_user_pointer);
m_body->setFriction(old_body->getFriction());
m_body->setRestitution(old_body->getRestitution());
m_body->setLinearFactor(old_body->getLinearFactor());
m_body->setAngularFactor(old_body->getAngularFactor());
m_body->setDamping(old_body->getLinearDamping(), old_body->getAngularDamping());
if (!m_is_dynamic)
{
m_body->setCollisionFlags( m_body->getCollisionFlags()
| btCollisionObject::CF_KINEMATIC_OBJECT);
m_body->setActivationState(DISABLE_DEACTIVATION);
}
if (m_triangle_mesh)
m_triangle_mesh->setBody(m_body);
} // copyFromMainProcess

View File

@ -27,8 +27,6 @@
#include "network/smooth_network_body.hpp"
#include "physics/user_pointer.hpp"
#include "utils/vec3.hpp"
#include "utils/leak_check.hpp"
class Material;
class TrackObject;
@ -197,6 +195,7 @@ private:
* when the object is not moving */
bool m_no_server_state;
void copyFromMainProcess(TrackObject* track_obj);
public:
PhysicalObject(bool is_dynamic, const Settings& settings,
TrackObject* object);
@ -293,7 +292,12 @@ public:
virtual std::function<void()> getLocalStateRestoreFunction();
bool hasTriangleMesh() const { return m_triangle_mesh != NULL; }
void joinToMainTrack();
LEAK_CHECK()
std::shared_ptr<PhysicalObject> clone(TrackObject* track_obj)
{
PhysicalObject* obj = new PhysicalObject(*this);
obj->copyFromMainProcess(track_obj);
return std::shared_ptr<PhysicalObject>(obj);
}
}; // PhysicalObject
#endif

View File

@ -2909,7 +2909,14 @@ void Track::copyFromMainProcess()
m_check_manager->add(cs->clone());
}
TrackObjectManager* main_tom = m_track_object_manager;
m_track_object_manager = new TrackObjectManager();
for (auto* to : main_tom->getObjects().m_contents_vector)
{
TrackObject* clone = to->cloneToChild();
if (clone)
m_track_object_manager->insertObject(clone);
}
m_track_mesh = new TriangleMesh(/*can_be_transformed*/false);
m_gfx_effect_mesh = new TriangleMesh(/*can_be_transformed*/false);
@ -2940,6 +2947,12 @@ void Track::initChildTrack()
Physics::get()->init(m_aabb_min, m_aabb_max);
m_track_mesh->createPhysicalBody(m_friction);
m_gfx_effect_mesh->createCollisionShape();
// All child track objects are only cloned if they have physical objects
for (auto* to : m_track_object_manager->getObjects().m_contents_vector)
to->getPhysicalObject()->addBody();
m_track_object_manager->init();
if (auto sl = LobbyProtocol::get<ServerLobby>())
{
sl->saveInitialItems(

View File

@ -779,3 +779,27 @@ bool TrackObject::joinToMainTrack()
m_physical_object.reset();
return true;
} // joinToMainTrack
// ----------------------------------------------------------------------------
TrackObject* TrackObject::cloneToChild()
{
// Only clone object that is enabled and has a physical object
// Soccer ball is made disabled by soccer world to hide initially
if ((isEnabled() || m_soccer_ball) && m_physical_object)
{
TrackObject* to_clone = new TrackObject(*this);
// We handle visibility condition in main process already
to_clone->m_visibility_condition.clear();
to_clone->m_presentation = NULL;
to_clone->m_render_info.reset();
to_clone->m_animator = NULL;
to_clone->m_parent_library = NULL;
to_clone->m_movable_children.clear();
to_clone->m_children.clear();
to_clone->m_physical_object = m_physical_object->clone(to_clone);
// All track objects need to be initially enabled in init
to_clone->m_enabled = true;
return to_clone;
}
return NULL;
} // joinToMainTrack

View File

@ -25,7 +25,6 @@
#include "scriptengine/scriptvec3.hpp"
#include "tracks/track_object_presentation.hpp"
#include "utils/cpp2011.hpp"
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp"
#include <string>
#include "animations/three_d_animation.hpp"
@ -43,7 +42,7 @@ class XMLNode;
* might also have a skeletal animation. This is used by objects that
* have an IPO animation, as well as physical objects.
*/
class TrackObject : public NoCopy
class TrackObject
{
//public:
// The different type of track objects: physical objects, graphical
@ -262,6 +261,8 @@ public:
void movePhysicalBodyToGraphicalNode(const core::vector3df& xyz, const core::vector3df& hpr);
// ------------------------------------------------------------------------
bool joinToMainTrack();
// ------------------------------------------------------------------------
TrackObject* cloneToChild();
LEAK_CHECK()
}; // TrackObject