Oh come on, i read thought that topic, but didn't check the second page -_-
Huge thanks though, lemme give it a try..
Edit: Works beautifully, thanks <3
Edit 2: Okay, turns out its playing up when moving a child after parenting. What should happen is when the child is moved, it recalculates the position offset again, so that when the parent is updated, it doesn't jump back to where it was. I'm pretty sure i'm calculating the position offset incorrectly, even though it should be just parent's position - child position..
Another problem I found is when the parent is rotated by 0 1 0 in euler, the child is rotated the wrong direction. I could just invert it, but id like to know why it happens so i can patch it properly.
Heres the updated code:
// Gets called whenever a holo is moved, rotated or scaled
function holo_updateChildren(%parent)
{
advVCEDebug("Updating children on" SPC %parent @ ".");
if(%parent.class !$= "holo" || !isObject(%parent) || getWordCount(%parent.children) < 1)
return;
%parentPos = %parent.getPosition();
%parentPosX = getWord(%parentPos,0);
%parentPosY = getWord(%parentPos,1);
%parentPosZ = getWord(%parentPos,2);
%parentRot = axisToEuler(getWords(%parent.getTransform(),3,6));
%ParentRotX = getWord(%parentRot,0);
%ParentRotY = getWord(%parentRot,1);
%ParentRotZ = getWord(%parentRot,2);
%parentScale = %parent.getScale();
%parentScaleX = getWord(%parentScale, 0);
%parentScaleY = getWord(%parentScale, 1);
%parentScaleZ = getWord(%parentScale, 2);
for(%i=0; %i < getWordCount(%parent.children); %i++)
{
%child = getWord(%parent.children,%i);
// Check if the child exists, and if it is a Hologram
if(isObject(%child) && %child.class $= "holo")
{
advVCEDebug("Updating child" SPC %child @ ".");
%childPos = %child.posOffset;
%childPosX = getWord(%childPos,0);
%childPosY = getWord(%childPos,1);
%childPosZ = getWord(%childPos,2);
%childRot = axisToEuler(getWords(%child.getTransform(), 3, 6));
%childRotX = getWord(%childRot,0);
%childRotY = getWord(%childRot,1);
%childRotZ = getWord(%childRot,2);
%childPosOffset = %child.posOffset;
%childRotOffset = %child.rotOffset;
%childScale = %child.scaleFactor; //Gets set when parented
%childScaleX = getWord(%childScale, 0);
%childScaleY = getWord(%childScale, 1);
%childScaleZ = getWord(%childScale, 2);
%scale = %childScaleX*%parentScaleX SPC %childScaleY*%parentScaleY SPC %childScaleZ*%parentScaleZ;
//Begin the awesome code which positions it!
%curtransform = %parent.gettransform();
%u["x"] = getword(%curtransform,3);
%u["y"] = getword(%curtransform,4);
%u["z"] = getword(%curtransform,5);
%angl = getword(%curtransform,6) * -1;
%cos = mcos(%angl);
%sin = msin(%angl);
%a[1,1] = %cos + (%u["x"] * %u["x"] * (1 - %cos));
%a[1,2] = (%u["x"] * %u["y"] * (1 - %cos)) - (%u["z"] * %sin);
%a[1,3] = (%u["x"] * %u["z"] * (1 - %cos)) + (%u["y"] * %sin);
%a[2,1] = (%u["y"] * %u["x"] * (1 - %cos)) + (%u["z"] * %sin);
%a[2,2] = %cos + (%u["y"] * %u["y"] * (1 - %cos));
%a[2,3] = (%u["y"] * %u["z"] * (1 - %cos)) - (%u["x"] * %sin);
%a[3,1] = (%u["z"] * %u["x"] * (1 - %cos)) - (%u["y"] * %sin);
%a[3,2] = (%u["z"] * %u["y"] * (1 - %cos)) + (%u["x"] * %sin);
%a[3,3] = %cos + (%u["z"] * %u["z"] * (1 - %cos));
%pos = getwords(%curtransform,0,3);
%x = getword(%child.posOffset,0);
%y = getword(%child.posOffset,1);
%z = getword(%child.posOffset,2);
%newx = (%a[1,1] * %x) + (%a[1,2] * %y) + (%a[1,3] * %z);
%newy = (%a[2,1] * %x) + (%a[2,2] * %y) + (%a[2,3] * %z);
%newz = (%a[3,1] * %x) + (%a[3,2] * %y) + (%a[3,3] * %z);
%newoffset = %newx SPC %newy SPC %newz;
%pos = vectoradd(%pos, %newoffset);
//Epic code done, back to my code
%rot = vectorAdd(%parentRot, %childRotOffset);
%child.setTransform(%pos SPC eulerToAxis(%rot));
%child.setScale(%scale);
holo_updateChildren(%child); //Update any of the child's children
} else
%parent.unChild(%child);
}
}
function fxDtsBrick::holo_Move(%brick,%type,%str,%client)
{
%holo = %brick.holo;
advVCEDebug("Moving holo:" SPC %holo @ ".");
if(!isObject(%holo))
return;
if(isFunction(filterVariableString)) //VCE support
%str = filterVariableString(%str,%brick,%client,%client.player);
%vec = vectorAdd(%str, "0 0 0"); //Forces it to be a 3d vector
switch(%type)
{
case 0: //Set
%pos = %vec;
case 1: //Move
%pos = vectorAdd(%vec,%holo.getPosition());
}
if(isObject(%holo.parent))
{
%holo.posOffset = vectorSub(%pos, %holo.parent.getPosition()); //Make sure to update the position offset
}
%rot = getWords(%holo.getTransform(),3,6);
%holo.setTransform(%pos SPC %rot);
holo_updateChildren(%holo);
}
function fxDtsBrick::holo_Rotate(%brick,%type,%str,%client)
{
%holo = %brick.holo;
advVCEDebug("Rotating holo:" SPC %holo @ ".");
if(!isObject(%holo))
return;
if(isFunction(filterVariableString)) //VCE support
%str = filterVariableString(%str,%brick,%client,%client.player);
%vec = vectorAdd(%str, "0 0 0"); //Forces it to be a 3d vector
%rot = axisToEuler(getWords(%holo.getTransform(), 3, 6));
switch(%type)
{
case 0: //Set
%rot = %vec;
case 1: //Add
%rot = vectorAdd(%vec,%rot);
}
if(isObject(%holo.parent))
%holo.rotOffset = vectorSub(%rot,axisToEuler(getWords(%holo.parent.getTransform(), 3, 6))); //Make sure to update the rotation offset
%pos = %holo.getPosition();
%holo.setTransform(%pos SPC eulerToAxis(%rot));
holo_updateChildren(%holo);
}