Page 9 of 21

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 22:46
by Chris
jhooks1 wrote:You got it working? Can you try an ancestor ghost? What all is different in this code in comparison to your last release? Is it just the Matrix44 mat = data->GetBoneTransform(b) * bones->GetWorldTransform();

The ancestor ghost is mostly correct. The face is positioned wrong, but that's not a skinning problem because it isn't skinned, it's attached directly to the bone like the werewolf head (funny enough the werewolf head works now without needing extra rotations, though Hircine's spear and the ghost face are still wrong).

Code: Select all

Matrix44 mat = data->GetBoneTransform(b) * bones[b]->GetWorldTransform();
is one bit that was changed, as well as the bone creation:

Code: Select all

static void buildBones(Ogre::Skeleton *skel, NiNodeRef node, Ogre::Bone *bone = NULL)
{
    //if(bone || node->IsSkeletonRoot())
    {
        Ogre::Bone *newbone = skel->createBone(node->GetName());
        if(!node->IsSkeletonRoot() && bone)
            bone->addChild(newbone);

        Vector3 srcTrans = node->GetLocalTranslation();
        Matrix33 srcRot = node->GetLocalRotation();
        float scale = node->GetLocalScale();

        Ogre::Vector3 trans(srcTrans.x, srcTrans.y, srcTrans.z);
        Ogre::Matrix3 rot(srcRot[0][0], srcRot[1][0], srcRot[2][0],
                          srcRot[0][1], srcRot[1][1], srcRot[2][1],
                          srcRot[0][2], srcRot[1][2], srcRot[2][2]);

        newbone->setOrientation(rot);
        newbone->setPosition(trans);
        newbone->setScale(Ogre::Vector3(scale));
        newbone->setBindingPose();
        newbone->setInitialState();

        bone = newbone;
    }

    std::vector<NiAVObjectRef> list = node->GetChildren();
    for(size_t i = 0;i < list.size();i++)
    {
        if(list[i]->IsDerivedType(NiNode::TYPE))
            buildBones(skel, StaticCast<NiNode>(list[i]), bone);
    }
}
and animation adjustment:

Code: Select all

            Ogre::Bone *bone = skel->getBone(targetnames[idx]);
            const Ogre::Quaternion startquat = bone->getInitialOrientation();
            const Ogre::Vector3 starttrans = bone->getInitialPosition();
            const Ogre::Vector3 startscale = bone->getInitialScale();
            Ogre::NodeAnimationTrack *nodetrack = (*anim)->getNodeTrack(bone->getHandle());

            Ogre::Quaternion lastquat, curquat;
            Ogre::Vector3 lasttrans(0.0f), curtrans(0.0f);
            Ogre::Vector3 lastscale(1.0f), curscale(1.0f);
            if(quatiter != quatkeys.end())
                lastquat = curquat = startquat.Inverse() * ConvertQuaternion(quatiter->data);
            if(traniter != trankeys.end())
                lasttrans = curtrans = ConvertVector3(traniter->data) - starttrans;
            if(scaleiter != scalekeys.end())
                lastscale = curscale = Ogre::Vector3(scaleiter->data) / startscale;

            ...

                while(quatiter != quatkeys.end() && curtime >= quatiter->time)
                {
                    lastquat = curquat;
                    curquat = startquat.Inverse() * ConvertQuaternion(quatiter->data);
                    quatiter++;
                }
                while(traniter != trankeys.end() && curtime >= traniter->time)
                {
                    lasttrans = curtrans;
                    curtrans = ConvertVector3(traniter->data) - starttrans;
                    traniter++;
                }
                while(scaleiter != scalekeys.end() && curtime >= scaleiter->time)
                {
                    lastscale = curscale;
                    curscale = Ogre::Vector3(scaleiter->data) / startscale;
                    scaleiter++;
                }
                ...

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 22:48
by jhooks1
Wow dude, you did it!!!! :shock:

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 22:55
by Tarius
Wow, now this is cool. This is a major step to getting things done.

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 23:07
by Chris
I still don't quite like how the vertex manipulation is done before it's loaded into Ogre. It could make sharing meshes with different skeletons difficult (e.g. the robe mesh being loaded using its own skeleton's bones for transformations, but then have it attached to an NPC's skeleton for animating). It's difficult to know what would happen without knowing more about how NIFs are expected to be used, or how the two sets of bones can be linked up within Ogre.

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 23:08
by edmondo
Nice stuff guys! :D And thanks for it.

Re: Making better use of Ogre's capbilities?

Posted: 20 Jun 2012, 23:18
by jhooks1
How do I do the following with openmw's nif system:

Code: Select all

bones[b]->GetWorldTransform()



Are these the node's transformation, without the parent applied:

Code: Select all

Vector3 srcTrans = node->GetLocalTranslation();
        Matrix33 srcRot = node->GetLocalRotation();
        float scale = node->GetLocalScale();

Re: Making better use of Ogre's capbilities?

Posted: 21 Jun 2012, 09:20
by Chris
jhooks1 wrote:How do I do the following with openmw's nif system:

Code: Select all

bones[b]->GetWorldTransform()
NifLib does it like this:

Code: Select all

Matrix44 NiAVObject::GetWorldTransform() const {
        //Get Parent Transform if there is one
        NiNodeRef par = GetParent();

        if ( par != NULL ) {
                //Multipy local matrix and parent world matrix for result
                return GetLocalTransform() * par->GetWorldTransform();
        }
        else {
                //No parent transform, simply return local transform
                return GetLocalTransform();
        }
}
For OpenMW, it looks like the "Node" class will need to be modified so it can store a pointer/reference to its parent, and recursively apply the world transform of all the parents up to the root node (with the local transform being a 4x4 matrix constructed using the Node::trafo; Ogre's Matrix4 class should be able to help).
Are these the node's transformation, without the parent applied:

Code: Select all

Vector3 srcTrans = node->GetLocalTranslation();
Matrix33 srcRot = node->GetLocalRotation();
float scale = node->GetLocalScale();
Yes, they would be the Node::trafo, as far as I can tell.

Re: Making better use of Ogre's capbilities?

Posted: 22 Jun 2012, 03:51
by jhooks1
Trying to fix a problem I was having on my animexperimental2 branch. In certain cells, when you quit openmw it crashes.

It looks like the crash is related to having separate loaders for the meshes and skeletons. I even made a new branch from the current master - animexperimental3 (in a commit - "starting another branch") which contains the separated loaders, but still uses the old animation system. This branch has the same problem. Would be a good idea to get this problem fixed before going any further, trying to figure out what is wrong :cry: .

Re: Making better use of Ogre's capbilities?

Posted: 22 Jun 2012, 07:54
by scrawl
Could it be possible that you load the same resource name with both loaders, and it gets double-freed on exit? Just guessing.

Re: Making better use of Ogre's capbilities?

Posted: 22 Jun 2012, 17:16
by Chris
Make sure the actual loader object remains valid, too (if it's declared in a function mark it static, or make it global).