Fairly long post; if you don't want to read it please just skip to the bottom
Okay so the picture you see above results from this code (only included the parts that operate on item position) and you can see the problem (now I have finally posted a picture!):
Code:
void Inventory::update(...)
{
if(C OrientP *point=cskel.findPoint("HandL"))
{
item = &T.item(slots[SLOT_HAND_L]);
Matrix matrix=item->matrix(); // get current matrix
Matrix& finalPos = Matrix().setPosDir(point->pos, point->dir);
item->matrix(finalPos);
}
}
So at this point when I thought about getting the offset in local space and then Abril suggested it I started to try and implement Abrils suggestion. I added this line to Item::create to store the displacement from the center of the weapon (where the hand is currently holding it to the "grip") in local space:
Code:
void Item::create(NetItem& src)
{
gripOffset = mesh->skeleton()->getPoint("grip").pos - mesh->box.center();
}
Next step was to transform that offset and move the item to that position which I tried to do like this:
Code:
void Inventory::update(...)
{
if(C OrientP *point=cskel.findPoint("HandL"))
{
item = &T.item(slots[SLOT_HAND_L]);
Matrix matrix = item->matrix(); // get current matrix
Vec displacement = item->gripOffset * matrix;
Matrix& finalPos = Matrix().setPosDir(point->pos, point->dir);
finalPos.move(displacement);
item->matrix(finalPos);
}
}
Loaded up the client and uh oh, look whats happened:
So I had a look at the vectors/matrixes at runtime and the displacement vector components were getting bigger and bigger. Then I figured out why; item position is being set to point->pos ( .setPosDir(point->pos...) ), then moved by displacement ( finalPos.move(displacement) ) every frame. Then in the next call to Inventory::update the item matrix pos has now changed...but then it applies the same calculation again and so on and basically it gets larger and larger so that is completely wrong.
So first step I removed:
Code:
Vec displacement = item->gripOffset * matrix;
and replaced it with:
Code:
Vec displacement = item->gripOffset;
So here is what it looked like now:
So at least the weapon is there now but obviously it isn't correct since displacement vec hasn't been transformed to world space. So I replaced:
Code:
Vec displacement = item->gripOffset;
with
Code:
Vec displacement = item->gripOffset * Matrix().setPosDir(point->pos, point->dir, point->cross());
and changed this line
Code:
Matrix& finalPos = Matrix().setPosDir(point->pos, point->dir);
to
Code:
Matrix& finalPos = Matrix().setPosDir(d, point->dir);
and now I am so much closer, but we are gripping the wrong end of the item now:
Only reason that could happen is if the displacement vector was in the wrong direction, and of course it was because I was doing gripPosition - weaponCenter so all I had to do was then flip it around weaponCenter - gripPosition and here we have it:
A massive massive massive thank you to Abril and Aceio76, really appreciate the help on this