summaryrefslogtreecommitdiff
path: root/src/content_cao.cpp
diff options
context:
space:
mode:
authorMirceaKitsune <sonichedgehog_hyperblast00@yahoo.com>2012-10-27 15:14:24 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-11-25 18:14:15 +0200
commit948b5a8be7b13a346c873c157567a72b4e7e320a (patch)
treece5a770f27043ee1b4ec21e3730d959c559ce6fe /src/content_cao.cpp
parente42eeec8f626acbaa54ae31c10ca06c868c7931c (diff)
downloadminetest-948b5a8be7b13a346c873c157567a72b4e7e320a.tar.gz
minetest-948b5a8be7b13a346c873c157567a72b4e7e320a.tar.bz2
minetest-948b5a8be7b13a346c873c157567a72b4e7e320a.zip
Complete the attachment framework.
The child ID can now be checked against the parent ID in content_cao.cpp so the parent can be detected. Actual attachment code to come Divide attachment system between server attachments and client attachments, neither coded right now. As explained in the code comment: // Attachments need to be handled on both the server and client. // If we attach only on the server, models (which are client-side) // can't be read so we don't know the origin and orientation of bones. // If we attach only on the client, the real position of attachments is // not updated and you can't click them for example.
Diffstat (limited to 'src/content_cao.cpp')
-rw-r--r--src/content_cao.cpp155
1 files changed, 104 insertions, 51 deletions
diff --git a/src/content_cao.cpp b/src/content_cao.cpp
index 3e18337d2..613ec6153 100644
--- a/src/content_cao.cpp
+++ b/src/content_cao.cpp
@@ -581,6 +581,10 @@ private:
int m_frame_speed;
int m_frame_blend;
std::map<std::string, core::vector2d<v3f> > m_bone_posrot;
+ ClientActiveObject* m_attachment_parent;
+ std::string m_attachment_bone;
+ v3f m_attacmhent_position;
+ v3f m_attachment_rotation;
int m_anim_frame;
int m_anim_num_frames;
float m_anim_framelength;
@@ -615,6 +619,14 @@ public:
m_tx_basepos(0,0),
m_initial_tx_basepos_set(false),
m_tx_select_horiz_by_yawpitch(false),
+ m_frames(v2f(0,0)),
+ m_frame_speed(15),
+ m_frame_blend(0),
+ // Nothing to do for m_bone_posrot
+ m_attachment_parent(NULL),
+ m_attachment_bone(""),
+ m_attacmhent_position(v3f(0,0,0)),
+ m_attachment_rotation(v3f(0,0,0)),
m_anim_frame(0),
m_anim_num_frames(1),
m_anim_framelength(0.2),
@@ -906,6 +918,9 @@ public:
void updateNodePos()
{
+ if(m_attachment_parent != NULL)
+ return;
+
if(m_meshnode){
m_meshnode->setPosition(pos_translator.vect_show);
v3f rot = m_meshnode->getRotation();
@@ -933,51 +948,53 @@ public:
addToScene(m_smgr, m_gamedef->tsrc(), m_irr);
updateAnimations();
updateBonePosRot();
- updateAttachment();
}
- if(m_prop.physical){
- core::aabbox3d<f32> box = m_prop.collisionbox;
- box.MinEdge *= BS;
- box.MaxEdge *= BS;
- collisionMoveResult moveresult;
- f32 pos_max_d = BS*0.125; // Distance per iteration
- f32 stepheight = 0;
- v3f p_pos = m_position;
- v3f p_velocity = m_velocity;
- v3f p_acceleration = m_acceleration;
- IGameDef *gamedef = env->getGameDef();
- moveresult = collisionMoveSimple(&env->getMap(), gamedef,
- pos_max_d, box, stepheight, dtime,
- p_pos, p_velocity, p_acceleration);
- // Apply results
- m_position = p_pos;
- m_velocity = p_velocity;
- m_acceleration = p_acceleration;
-
- bool is_end_position = moveresult.collides;
- pos_translator.update(m_position, is_end_position, dtime);
- pos_translator.translate(dtime);
- updateNodePos();
- } else {
- m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
- m_velocity += dtime * m_acceleration;
- pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
- pos_translator.translate(dtime);
- updateNodePos();
- }
+ if(m_attachment_parent == NULL) // Attachments should be glued to their parent by Irrlicht
+ {
+ if(m_prop.physical){
+ core::aabbox3d<f32> box = m_prop.collisionbox;
+ box.MinEdge *= BS;
+ box.MaxEdge *= BS;
+ collisionMoveResult moveresult;
+ f32 pos_max_d = BS*0.125; // Distance per iteration
+ f32 stepheight = 0;
+ v3f p_pos = m_position;
+ v3f p_velocity = m_velocity;
+ v3f p_acceleration = m_acceleration;
+ IGameDef *gamedef = env->getGameDef();
+ moveresult = collisionMoveSimple(&env->getMap(), gamedef,
+ pos_max_d, box, stepheight, dtime,
+ p_pos, p_velocity, p_acceleration);
+ // Apply results
+ m_position = p_pos;
+ m_velocity = p_velocity;
+ m_acceleration = p_acceleration;
+
+ bool is_end_position = moveresult.collides;
+ pos_translator.update(m_position, is_end_position, dtime);
+ pos_translator.translate(dtime);
+ updateNodePos();
+ } else {
+ m_position += dtime * m_velocity + 0.5 * dtime * dtime * m_acceleration;
+ m_velocity += dtime * m_acceleration;
+ pos_translator.update(m_position, pos_translator.aim_is_end, pos_translator.anim_time);
+ pos_translator.translate(dtime);
+ updateNodePos();
+ }
- float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
- m_step_distance_counter += moved;
- if(m_step_distance_counter > 1.5*BS){
- m_step_distance_counter = 0;
- if(!m_is_local_player && m_prop.makes_footstep_sound){
- INodeDefManager *ndef = m_gamedef->ndef();
- v3s16 p = floatToInt(getPosition() + v3f(0,
- (m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS);
- MapNode n = m_env->getMap().getNodeNoEx(p);
- SimpleSoundSpec spec = ndef->get(n).sound_footstep;
- m_gamedef->sound()->playSoundAt(spec, false, getPosition());
+ float moved = lastpos.getDistanceFrom(pos_translator.vect_show);
+ m_step_distance_counter += moved;
+ if(m_step_distance_counter > 1.5*BS){
+ m_step_distance_counter = 0;
+ if(!m_is_local_player && m_prop.makes_footstep_sound){
+ INodeDefManager *ndef = m_gamedef->ndef();
+ v3s16 p = floatToInt(getPosition() + v3f(0,
+ (m_prop.collisionbox.MinEdge.Y-0.5)*BS, 0), BS);
+ MapNode n = m_env->getMap().getNodeNoEx(p);
+ SimpleSoundSpec spec = ndef->get(n).sound_footstep;
+ m_gamedef->sound()->playSoundAt(spec, false, getPosition());
+ }
}
}
@@ -1193,10 +1210,38 @@ public:
}
}
}
-
- void updateAttachment()
+
+ void updateAttachments()
{
- // Code for attachments goes here
+ // REMAINING ATTACHMENT ISSUES:
+ // We get to this function when the object is an attachment that needs to
+ // be attached to its parent. If a bone is set we attach it to that skeletal
+ // bone, otherwise just to the object's origin. Attachments should not copy parent
+ // position as that's laggy... instead the Irrlicht function(s) to attach should
+ // be used. If the parent object is NULL that means this object should be detached.
+ // This function is only called whenever a GENERIC_CMD_SET_ATTACHMENT message is received.
+
+ // We already attach our entity on the server too (copy position). Reason we attach
+ // to the client as well is first of all lag. The server sends the position
+ // of the child separately than that of the parent, so even on localhost
+ // you'd see the child lagging behind. Models are also client-side, so this is
+ // needed to read bone data and attach to joints.
+
+ // Functions:
+ // - m_attachment_parent is ClientActiveObject* for the parent entity.
+ // - m_attachment_bone is std::string of the bone, "" means none.
+ // - m_attachment_position is v3f and represents the position offset of the attachment.
+ // - m_attachment_rotation is v3f and represents the rotation offset of the attachment.
+
+ // Implementation information:
+ // From what I know, we need to get the AnimatedMeshSceneNode of m_attachment_parent then
+ // use parent_node->addChild(m_animated_meshnode) for position attachment. For skeletal
+ // attachment I don't know yet. Same must be used to detach when a NULL parent is received.
+
+ //Useful links:
+ // http://irrlicht.sourceforge.net/forum/viewtopic.php?t=7514
+ // http://www.irrlicht3d.org/wiki/index.php?n=Main.HowToUseTheNewAnimationSystem
+ // Irrlicht documentation: http://irrlicht.sourceforge.net/docu/
}
void processMessage(const std::string &data)
@@ -1225,6 +1270,8 @@ public:
}
else if(cmd == GENERIC_CMD_UPDATE_POSITION)
{
+ // Not sent by the server if the object is an attachment
+
m_position = readV3F1000(is);
m_velocity = readV3F1000(is);
m_acceleration = readV3F1000(is);
@@ -1238,7 +1285,7 @@ public:
// the ground due to sucky collision detection...
if(m_prop.physical)
m_position += v3f(0,0.002,0);
-
+
if(do_interpolate){
if(!m_prop.physical)
pos_translator.update(m_position, is_end_position, update_interval);
@@ -1287,12 +1334,18 @@ public:
}
else if(cmd == GENERIC_CMD_SET_ATTACHMENT)
{
- // Part of the attachment structure, not used yet!
-
- // Get properties here.
+ ClientActiveObject *obj;
+ int parent_id = readS16(is);
+ if(parent_id > 0)
+ obj = m_env->getActiveObject(parent_id);
+ else
+ obj = NULL;
+ m_attachment_parent = obj;
+ m_attachment_bone = deSerializeString(is);
+ m_attacmhent_position = readV3F1000(is);
+ m_attachment_rotation = readV3F1000(is);
- updateAttachment();
- expireVisuals();
+ updateAttachments();
}
else if(cmd == GENERIC_CMD_PUNCHED)
{