<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
	<title type="html"><![CDATA[Maratis forum - Bones manipulation]]></title>
	<link rel="self" href="http://forum.maratis3d.com/extern.php?action=feed&amp;tid=728&amp;type=atom"/>
	<updated>2014-02-10T17:32:56Z</updated>
	<generator>PunBB</generator>
	<id>http://forum.maratis3d.com/viewtopic.php?id=728</id>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6415#p6415"/>
			<content type="html"><![CDATA[<p>good <img src="http://forum.maratis3d.com/img/smilies/smile.png" width="15" height="15" alt="smile" /></p><p>yes, that&#039;s what I figured out, a non-uniform scale (not the same scale on each axis) can deform the rotation angles, it&#039;s a bit tricky.</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-10T17:32:56Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6415#p6415</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6412#p6412"/>
			<content type="html"><![CDATA[<p>Yes your code works perfectly in my project too.<br />Your &quot;CopyTransformation&quot; function as it is in your zip file is everything I needed.<br />In my <a href="http://forum.maratis3d.com/viewtopic.php?pid=6377#p6377">first post about this problem</a> I wrote that the part that I suspected was not working was this:<br /></p><div class="codebox"><pre><code>  //Bone copys from Ragdoll&#039;s part (DOESN&#039;T WORK)
        MMatrix4x4 myMatrix = characterEntity-&gt;getMatrix()-&gt;getInverse() * (*ragdollPart-&gt;getMatrix());
        MObject3d* parentBone = bone-&gt;getParent();
        if(parentBone)
            myMatrix = parentBone-&gt;getMatrix()-&gt;getInverse() * myMatrix;
        bone-&gt;setEulerRotation(myMatrix.getEulerAngles());</code></pre></div><p>And indeed replacing this with your code solved everything. Now the ragdoll works fine. <img src="http://forum.maratis3d.com/img/smilies/smile.png" width="15" height="15" alt="smile" /><br />It was that &quot;no scale&quot; trick that was missing.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-10T16:33:27Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6412#p6412</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6410#p6410"/>
			<content type="html"><![CDATA[<p>It&#039;s maybe not optimal for you as you are updating the full armature, but it can help you debug your code or prototype ?<br />Let me know if it worked with your armature.</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-10T16:15:59Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6410#p6410</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6408#p6408"/>
			<content type="html"><![CDATA[<p>Ah! You did it!<br />And there&#039;s no need to call armature-&gt;processBonesLinking() or bone-&gt;computeLocalMatrix().<br />Thank you very much anael.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-10T16:06:25Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6408#p6408</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6401#p6401"/>
			<content type="html"><![CDATA[<p>I made a small example with a behavior code to attach a bone to an entity : <a href="http://www.maratis3d.org/download/Armature.zip">http://www.maratis3d.org/download/Armature.zip</a></p><p>After compiling, open the project.<br />Select &quot;Jules&quot; and look at the behaviors.<br />You can see the effect in-editor by moving the transparent boxes.</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-10T14:32:48Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6401#p6401</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6399#p6399"/>
			<content type="html"><![CDATA[<p>I&#039;ve disabled the physics (commented every part of code which has something to do with the physics).<br />Ragdoll parts have now no parent-child relationships, no physics and no constraints.<br />Copying the bone rotation and position from the armature to the ragdoll, the result is what is seen in the first image that I&#039;ve posted (the one on the left): <a href="http://forum.maratis3d.com/viewtopic.php?pid=6377#p6377">http://forum.maratis3d.com/viewtopic.php?pid=6377#p6377</a>, as expected.<br />Which is the default position of the armature, the same that it&#039;s on the Blender file.</p><p>If this is of any help, in the Blender file the bones in their default position (as seen in the image) are considered to be at rotation zero (0,0,0) on the 3 axis. In Maratis tough it&#039;s not the same, because if I set them at (0,0,0) they all point straight to the axis +Y.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-10T11:14:59Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6399#p6399</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6398#p6398"/>
			<content type="html"><![CDATA[<p>What I specially have a doubt is the order of the matrix multiplication for the offset, I need to check my math.</p><p>What you should do to check this potential axis problem is to visualize the bones in space,<br />disable the physics and all the parenting of your ragdoll objects and copy the bones transformation to the ragdoll objects.<br />At least you&#039;ll be able to see how the bones are oriented.</p><div class="codebox"><pre><code>MMatrix4X4 boneWorldMatrix = (*entity-&gt;getMatrix()) * (*bone-&gt;getMatrix);
*object-&gt;getMatrix = boneWorldMatrix;
object-&gt;setPosition(boneWorldMatrix.getTranslationPart());
object-&gt;setEulerRotation(boneWorldMatrix.getEulerAngles());</code></pre></div>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-10T10:34:14Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6398#p6398</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6391#p6391"/>
			<content type="html"><![CDATA[<p>Your code as it is makes everything blow up, similarly to the previous image that I&#039;ve posted.<br />But I think we&#039;re on the right path.<br />I remember having tried something similar in the past: <a href="http://forum.maratis3d.com/viewtopic.php?pid=5562#p5562">http://forum.maratis3d.com/viewtopic.php?pid=5562#p5562</a><br />although the situation was a bit different. But yes, I also thought about the offset so I guess this is the way to go.<br />Still, the code as it is doesn&#039;t seem to work.</p><p>If nothing works I could use that old code of mine, but it&#039;s not that good because it uses a specific axis which may be different depending on where the bone is (e.g. leg and arms need a different calculation). So using matrices should be better.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-10T00:19:17Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6391#p6391</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6390#p6390"/>
			<content type="html"><![CDATA[<p>For the offset calculation, I&#039;m not totally sure, but it should be something like that (to be tested) :</p><div class="codebox"><pre><code>// call this only at the first frame
MMatrix4X4 boneWorldMatrix = (*entity-&gt;getMatrix()) * (*bone-&gt;getMatrix());
MMatrix4X4 offsetMatrix = object-&gt;getMatrix()-&gt;getInverse() * boneWorldMatrix;
... // store the offset matrix</code></pre></div><div class="codebox"><pre><code>void copyTransformation(MOEntity * entity, MOBone * bone, MObject3d * object, MMatrix4X4 * offsetMatrix)
{
    MMatrix4X4 correctedWorldMatrix = (*object-&gt;getMatrix()) * (*offsetMatrix);
    MMatrix4X4 targetMatrix = entity-&gt;getMatrix()-&gt;getInverse * correctedWorldMatrix;

    *bone-&gt;getMatrix() = targetMatrix; // this is the actual armature space matrix

    // what comes after is only used to update the local coordinates position and rotation
    MObject3d * parentBone = bone-&gt;getParent();
    if(parentBone)
    {
        // calculate target matrix in parentBone&#039;s space
        targetMatrix = parentBone-&gt;getMatrix()-&gt;getInverse() * targetMatrix;
    }

    // get position and rotation coords from targetMatrix
    bone-&gt;setPosition(targetMatrix.getTranslationPart());
    bone-&gt;setEulerRotation(targetMatrix.getEulerAngles());
}</code></pre></div><p>If you are 100% sure the bones are sorted, you can simplify the call :<br /></p><div class="codebox"><pre><code>for(i=0; i&lt;bonesNumber; i++)
{
    MObject3d * object = ... // get the ragdoll
    MMatrix4X4 * offsetMatrix = ... // get the offset matrix
    copyTransformation(entity, armature-&gt;getBone(i), object, offsetMatrix);
}

// no need to call armature-&gt;processBonesLinking();
armature-&gt;updateBonesSkinMatrix(); // optional, is normally called by the renderer</code></pre></div>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-09T23:26:59Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6390#p6390</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6389#p6389"/>
			<content type="html"><![CDATA[<p>I don&#039;t see something wrong in the code, if you get the same result, your code is right too, but you should not call &quot;armature-&gt;processBonesLinking();&quot; multiple time in your loop (it&#039;s slow because it update all the armature each time).</p><p>So if it&#039;s not that, the problem should be that the bones and the ragdoll objects axis are not synchronized :<br />- because the ragdoll objects are not oriented the same axis as the bones<br />- or because the bones are not oriented in a consistent way</p><p>Lets say they are not synchronized, but you manually placed the ragdoll on the first frame.<br />You can calculate the offset matrix at the first frame and store it.<br />Then, when you update the bones, you use this offset.</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-09T23:02:13Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6389#p6389</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6387#p6387"/>
			<content type="html"><![CDATA[<p>Yes, the order is important but I got it right.<br />I use a makehuman mesh (basic rig), the bones are already put in a decent order in the mesh file and there is only one root bone, so your code solution is not required.</p><p>Anyway, both my original code and yours give the same result.<br />So the bug is not about the order.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-09T22:13:57Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6387#p6387</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6385#p6385"/>
			<content type="html"><![CDATA[<p>yes should be child.<br />the order is important, because you need the parent matrix to be updated to get the correct child matrix.</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-09T21:54:25Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6385#p6385</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6384#p6384"/>
			<content type="html"><![CDATA[<p>Not quite right.<br /><span class="postimg"><img src="http://oi62.tinypic.com/1zqwpsk.jpg" alt="http://oi62.tinypic.com/1zqwpsk.jpg" /></span></p><p>LOL.<br />In the processChilds function of your code I think this lines:<br /></p><div class="codebox"><pre><code>        // compute parenting (parent matrix * child local matrix)
        copyTransformation(entity, bone, object);
        (*child-&gt;getMatrix()) = (*bone-&gt;getMatrix()) * (*child-&gt;getMatrix());
        processChilds(entity, child);</code></pre></div><p>should actually be:<br /></p><div class="codebox"><pre><code>        // compute parenting (parent matrix * child local matrix)
        copyTransformation(entity, child, object);   //   &lt;--------
        (*child-&gt;getMatrix()) = (*bone-&gt;getMatrix()) * (*child-&gt;getMatrix());
        processChilds(entity, child);</code></pre></div><p>otherwise it doesn&#039;t make sense.</p><p>Compiling with this correction I get the exact same result of the first image that I&#039;ve posted (the one on the right), which is: the rotation is not quite right.</p><p>So as I thought it&#039;s not about the order. IMHO some matrix operation is not correct. Or the bug may be somewhere else, but I triple-checked every single line of my code.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-09T20:47:03Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6384#p6384</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6383#p6383"/>
			<content type="html"><![CDATA[<p>My for loop is<br /></p><div class="codebox"><pre><code>for(i=0; i&lt;bonesNumber; i++)</code></pre></div><p>and the mesh has one single root bone, which is bone 0.<br />After each bone is rotated, I do:<br /></p><div class="codebox"><pre><code>armature-&gt;processBonesLinking();
armature-&gt;updateBonesSkinMatrix();</code></pre></div><p>inside the brackets of the for loop, and then I process the next bone (i++).<br />So I don&#039;t really think that the problem is about order.</p><p>I will try your code anyway and let you know.</p>]]></content>
			<author>
				<name><![CDATA[255]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2540</uri>
			</author>
			<updated>2014-02-09T20:29:09Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6383#p6383</id>
		</entry>
		<entry>
			<title type="html"><![CDATA[Re: Bones manipulation]]></title>
			<link rel="alternate" href="http://forum.maratis3d.com/viewtopic.php?pid=6381#p6381"/>
			<content type="html"><![CDATA[<p>You have to process the bones in the right order, from the roots to the childs.<br />It should be something like that :</p><div class="codebox"><pre><code>void copyTransformation(MOEntity * entity, MOBone * bone, MObject3d * object)
{
    MMatrix4X4 targetMatrix = entity-&gt;getMatrix()-&gt;getInverse * (*object-&gt;getMatrix()); // get object matrix in armature space

    MObject3d * parentBone = bone-&gt;getParent();
    if(parentBone)
    {
        // calculate target matrix in parentBone&#039;s space
        targetMatrix = parentBone-&gt;getMatrix()-&gt;getInverse() * targetMatrix;
    }

    // get position and rotation coords from targetMatrix
    bone-&gt;setPosition(targetMatrix.getTranslationPart());
    bone-&gt;setEulerRotation(targetMatrix.getEulerAngles());
    bone-&gt;computeLocalMatrix();
}

void processChilds(MOEntity * entity, MOBone * bone)
{
    unsigned int i, childsNumber = bone-&gt;getChildsNumber();

    for(i=0; i&lt;childsNumber; i++) // for all childs
    {
        MOBone * child = (MOBone *)bone-&gt;getChild(i);
        MObject3d * object = ... // get the associated ragdol object

        // compute parenting (parent matrix * child local matrix)
        copyTransformation(entity, child, object);
        (*child-&gt;getMatrix()) = (*bone-&gt;getMatrix()) * (*child-&gt;getMatrix());
        processChilds(entity, child);
    }
}</code></pre></div><p>and during the update :</p><div class="codebox"><pre><code>// start from the roots to the childs
for(i=0; i&lt;bonesNumber; i++)
{
    MOBone * bone = armature-&gt;getBone(i);
    if(! bone-&gt;hasParent())
    {
        MObject3d * object = ... // get the associated ragdol object
        copyTransformation(entity, bone, object);
        processChilds(entity, bone);
    }
}</code></pre></div><p>And in this case you don&#039;t need to call &quot;armature-&gt;processBonesLinking();&quot;</p>]]></content>
			<author>
				<name><![CDATA[anael]]></name>
				<uri>http://forum.maratis3d.com/profile.php?id=2</uri>
			</author>
			<updated>2014-02-09T19:55:03Z</updated>
			<id>http://forum.maratis3d.com/viewtopic.php?pid=6381#p6381</id>
		</entry>
</feed>
