Making better use of Ogre's capbilities?

Everything about development and the OpenMW source code.
Chris
Posts: 1626
Joined: 04 Sep 2011, 08:33

Re: Making better use of Ogre's capbilities?

Post 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++;
                }
                ...
jhooks1
Posts: 780
Joined: 06 Aug 2011, 21:34

Re: Making better use of Ogre's capbilities?

Post by jhooks1 »

Wow dude, you did it!!!! :shock:
Tarius
Posts: 574
Joined: 24 Oct 2011, 19:29

Re: Making better use of Ogre's capbilities?

Post by Tarius »

Wow, now this is cool. This is a major step to getting things done.
Chris
Posts: 1626
Joined: 04 Sep 2011, 08:33

Re: Making better use of Ogre's capbilities?

Post 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.
edmondo
Posts: 36
Joined: 14 May 2012, 14:04
Contact:

Re: Making better use of Ogre's capbilities?

Post by edmondo »

Nice stuff guys! :D And thanks for it.
jhooks1
Posts: 780
Joined: 06 Aug 2011, 21:34

Re: Making better use of Ogre's capbilities?

Post 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();
Chris
Posts: 1626
Joined: 04 Sep 2011, 08:33

Re: Making better use of Ogre's capbilities?

Post 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.
jhooks1
Posts: 780
Joined: 06 Aug 2011, 21:34

Re: Making better use of Ogre's capbilities?

Post 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: .
User avatar
scrawl
Posts: 2152
Joined: 18 Feb 2012, 11:51

Re: Making better use of Ogre's capbilities?

Post 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.
Chris
Posts: 1626
Joined: 04 Sep 2011, 08:33

Re: Making better use of Ogre's capbilities?

Post 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).
Post Reply