NPC rendering

Everything about development and the OpenMW source code.
Locked
User avatar
lgromanowski
Site Admin
Posts: 1151
Joined: 05 Aug 2011, 22:21
Location: Wroclaw, Poland
Github profile: https://github.com/lgromanowski
Contact:

NPC rendering

Post by lgromanowski » 15 Aug 2011, 09:09

Zini wrote: To keep the discussion a bit more sorted, we should continue the discussion about NPC rendering in a separate thread.

@ape: I saw your implementation of insertObj in your fork. I am pretty sure, that it won't work that way. You are constructing the nif file name manually from the head name. What you actually should do is look up the body part according to the head value given in the NPC struct. The model name given there is the one you should use.
ape wrote: I've updated the code. Is it better now?

It seems that every race hast two pieces of every body part. One female and one male piece. Each id ends with the name of the body part. These names seem to be the same between the factions except for Argonians. Their Skins.nif contains the feet and they have tails.

I guess that the animation files are describing the positions of these parts. Can these files somehow be read by the engine right now? Is there any idea of how the animation system will be implemented to the engine?
Zini wrote: Looks better.

As you can see on the roeadmap work on the animation system has started, but no one is currently working on it. You probably will find the code in:

components/nif

or

components/nifogre

or both. This is Nico's baby, so I can't really offer much help with it.
ape wrote: hey nico can you help me out with your nif code?

As far is understand the task of npc rendering my first goal is to convert the nif bone structure (contained in a NiSkinInstance record with its bones contained in NiSkinData from an animation file like xbase_anim.nif) to the ogre bone structure, am i on the right way?

How do i get this bone structures while loading the resource with the ogre nif loader? The loader starts at the rood node and iterates through all child nodes, but only NiNodes and NiTrishape ones are found in the anim file although the NiSkin nodes are read from the nif file.

I hardly understand your nif code, it seems messy to me.
ape wrote: I've created a wiki page where i gather information about nif files: http://openmw.org/wiki/index.php?title=Nif

Feel free to update that page if you know something essential.
ape wrote: Status update:

Skeleton creation works in the ogre_nif_loader. If you give me some time i'll look also into the two issues currently on github.

Edit: I would like to change the Nif Types Vector and Matrix to the Ogre ones (Vector3 and Matrix3) that would make the vector and matrix math functions in the nif loader obsolete because the ogre types provide them already. Is it okay for you nico, or is there a reason against this step?
Zini wrote: Great! But it seems we have a ugly merge ahead. Most of the cellimp code has been moved to other files. In this case you probably want to look at apps/openmw/mwclass/npc.cpp. Could you please merge in Nico's or my fork? The merge will become only more ugly if we delay it further.
ape wrote: I've merged nicos branch. My modification in cellimp is obsolete :).
Zini wrote: Now I am getting a crash too. Not sure if that is related to the recent NPC rendering changes, but it happens in Ogre and I have not seen it before the merge today.

Here is the backtrace:

http://gist.github.com/527520
nicolay wrote:
ape wrote:hey nico can you help me out with your nif code?

As far is understand the task of npc rendering my first goal is to convert the nif bone structure (contained in a NiSkinInstance record with its bones contained in NiSkinData from an animation file like xbase_anim.nif) to the ogre bone structure, am i on the right way?

How do i get this bone structures while loading the resource with the ogre nif loader? The loader starts at the rood node and iterates through all child nodes, but only NiNodes and NiTrishape ones are found in the anim file although the NiSkin nodes are read from the nif file.

I hardly understand your nif code, it seems messy to me.
Sorry for being so slow in responding to this. I agree that the code is messy. Really I woudn't mind if you (or anyone) rewrote it completely, in fact I that might be a very good idea. It was really only ever meant to be a quick fix to get meshes up and running. (It too is a port from some very early D code.)

However, this isn't exactly a simple job, so rather than answer your questions directly I think I should explain the situation a bit first (forgive me if you already know most of this stuff:)

The NIF and Ogre mesh structures are very different. In the NIF world, each mesh is a tree structure of various components and submeshes, where each submesh can have its own children, the childs of a node can be animated, etc.

OGRE doesn't have anything parallel to this. OGRE only has one main mesh/root node, and a flat list of submeshes (not a hierarchy.) You can add bones on top of that to move the submeshes, but this is has its own limitations. OGRE also has scene nodes, which form a nice hierarchy just as in the NIFs, but they are part of the scene not part of the mesh. Ie. they are not made to be loaded once and then cloned multiple times.

There are three ways to translate NIFs into Ogre meshes that have been tried so far:

1) Add all submeshes in a NIF as submeshes in the Ogre mesh, add bones to them, and use a skeleton to transform them into place. This was the first thing I tried. Only problem is: Ogre only supports 100 bones per skeleton. That's a hard-coded limit, and some meshes (especially in some mods) have more than 100 submeshes. There's also a problem with animations - NIF animations can (if I understand the file format correctly) apply only to a subpart of the hierarchy. Which means only a small set of the bones are ever animated. This might also mean that a NIF can have several independent animations at different places in the tree, but I haven't checked if any NIFs actually do that.

2) Set up the mesh as a scene node tree, then 'clone' that tree and insert it into the world whenever we place the mesh. This works and is what we did for most of the lifetime of the D version. But it's messy, you have to write all the clone code yourself, and most importantly you are now circumventing Ogre's mesh resource handling, which means that you have to do a lot of work if Ogre wants to unload and reload meshes. In addition, this also isn't very compatible with animations - the best way I could think of was to have bones in a skeleton and then attach the required scene nodes to them.

3) The third way is what we were doing now: add all NIF submeshes to the flat OGRE submesh list, but transform them on a vertex level so we don't have to use bones for all of them (remember, we only have 100 bones per skeleton.) For animations (which isn't implemented yet), we have to pick out those nodes (subtrees) in the NIF that are animated and make an exception for them - don't transform them this way but _instead_ add them as bones to a skeleton.

All this is further complicated by the fact that the NIFs are split in two, something the current code also isn't very well designed for.

So in short it's pretty messy :) Maybe there is a 4th and better way that I haven't thought of yet tho - all suggestions are very welcome!
Star-Demon wrote:
nicolay wrote:Sorry for being so slow in responding to this. I agree that the code is messy. Really I woudn't mind if you (or anyone) rewrote it completely, in fact I that might be a very good idea. It was really only ever meant to be a quick fix to get meshes up and running. (It too is a port from some very early D code.)

However, this isn't exactly a simple job, so rather than answer your questions directly I think I should explain the situation a bit first (forgive me if you already know most of this stuff:)

The NIF and Ogre mesh structures are very different. In the NIF world, each mesh is a tree structure of various components and submeshes, where each submesh can have its own children, the childs of a node can be animated, etc.
What a mess.
There are three ways to translate NIFs into Ogre meshes that have been tried so far:

1) Add all submeshes in a NIF as submeshes in the Ogre mesh, add bones to them, and use a skeleton to transform them into place. This was the first thing I tried. Only problem is: Ogre only supports 100 bones per skeleton. That's a hard-coded limit, and some meshes (especially in some mods) have more than 100 submeshes. There's also a problem with animations - NIF animations can (if I understand the file format correctly) apply only to a subpart of the hierarchy. Which means only a small set of the bones are ever animated. This might also mean that a NIF can have several independent animations at different places in the tree, but I haven't checked if any NIFs actually do that.
Wow. I didn't know that about ogre. 100...
Well, Maybe we should unhard-code it. It may be MIT license, but it's still Copyleft, open source. :)
2) Set up the mesh as a scene node tree, then 'clone' that tree and insert it into the world whenever we place the mesh. This works and is what we did for most of the lifetime of the D version. But it's messy, you have to write all the clone code yourself, and most importantly you are now circumventing Ogre's mesh resource handling, which means that you have to do a lot of work if Ogre wants to unload and reload meshes. In addition, this also isn't very compatible with animations - the best way I could think of was to have bones in a skeleton and then attach the required scene nodes to them.

3) The third way is what we were doing now: add all NIF submeshes to the flat OGRE submesh list, but transform them on a vertex level so we don't have to use bones for all of them (remember, we only have 100 bones per skeleton.) For animations (which isn't implemented yet), we have to pick out those nodes (subtrees) in the NIF that are animated and make an exception for them - don't transform them this way but _instead_ add them as bones to a skeleton.
Wait, are you saying that some bones simply won't be animated, or that there will be a reduced number after translation? How does the program decide which are more important all the time?
All this is further complicated by the fact that the NIFs are split in two, something the current code also isn't very well designed for.

So in short it's pretty messy :) Maybe there is a 4th and better way that I haven't thought of yet tho - all suggestions are very welcome!
Well, considering that the format being used for meshes is more or less a hassle to use with OGRE, what would you say if we, instead of demanding computing time and increasing complexity, and possibly making changes to OGRE, which we shouldn't have to do, ideally, we simply make a utility that does the job of converting all meshes into something easily usable, and then use our new OGRE-friendly meshes?

The code for conversion, as you've been laying out might still have to be written, but is it possible to forget about demanding a lot of complex recalculations, loading, unloading, and so on, instead of just trading it off for prep-time for a build? We already have this kind of prep time when installing mods and adding their statics and activators to the HDR list in MGE, why not do the same for meshes and make it easier?

That doesn't erase the 100 bones problem, and since you mentioned that some mods already exceed that...we either have to find a better way to work with NIF out there, Mod OGRE, or something else...Maybe we can't get around making changes to OGRE...
ape wrote:
nicolay wrote:1) Add all submeshes in a NIF as submeshes in the Ogre mesh, add bones to them, and use a skeleton to transform them into place. This was the first thing I tried. Only problem is: Ogre only supports 100 bones per skeleton. That's a hard-coded limit, and some meshes (especially in some mods) have more than 100 submeshes.
The ogre manual 1.7 says that a skeleton can have a unlimited number of bones.

So in my latest push i've implemented the creation of the main bone tree ("Bip01") and i've ordered the vertices using the skeleton, it works fine with nifs containing skeletons that i've tried (i've tested it not enough!). I'll add the bone assignment and if it works and the ogre manual is right i think it isn't that hard to implement animation. (that would be way No 1)

Can you give me a example nif with lots of bones to test my code?

I'm interested in rewriting parts of the code if i get things working and i know more about the whole stuff.
Star-Demon wrote:Well, considering that the format being used for meshes is more or less a hassle to use with OGRE, what would you say if we, instead of demanding computing time and increasing complexity, and possibly making changes to OGRE, which we shouldn't have to do, ideally, we simply make a utility that does the job of converting all meshes into something easily usable, and then use our new OGRE-friendly meshes?
Hmm, afaik it's easier to create an ogre mesh and then serialize it. That would save us learning and writing the ogre mesh format.
Zini wrote: That Ogre-related crash I had is gone apparently. Good!
Zini wrote: New crash. Looks NPC rendering related too:
openmw: /usr/local/include/OGRE/OgreSharedPtr.h:160: T* Ogre::SharedPtr<T>::operator->() const [with T = Ogre::Skeleton]: Assertion `pRep' failed.
Happened in cell Ald'ruhn, The Rat in The Pot

But it also happens in quite a few exterior cells, which makes working on the exterior cell code rather problematic. I would appreciate it, if this could be resolved quickly.
ape wrote: I think i fixed that crash, check out my latest commit.
Zini wrote: Yeah, that did it. Thanks!
ape wrote: as i will not have time for at least a month, i can't continue on this task (although i'd like to). If someone else is interested in working on this task, here is the current status (pushed while i'm posting this) and my plan for the future.

The skeleton is build up (gaining informations from the ninodes) with Bip01 or "Root Bone" as the root bone.
Vertices of a nitrishape with niskindata will be assigned to the right bones and vertices without niskindata will be assigned to the parent ninode of the nitrishape.

Todo:
create the skeleton from the root node of the nif file because there are animated objects outside of the "root bone skeleton" (see r/atronach_storm.nif). Maybe figure out which bones aren't needed for animation or disable skeletons for nifs without animation to decrease the loading time.
After that i would have tried to implement animation and later on looked into the particle effects.

I wanted to proper load a nif file with animation before making thoughts on npc rendering. Because this requires to concatenate multiple meshes together and therefore it may be necessary to rewrite parts of the nif code.

That would be my plan (and i don't know if it's the/a right way), feel free to use it or not if you'd like to work on this task.

Good luck and best regards
Ape
nicolay wrote: Thanks a lot for doing this, it is much appreciated. Hope to see you back at a later date!
sir_herrbatka wrote: What happens to this branch?
Zini wrote: Nothing for now.
jhooks1 wrote: It seems that we have most creatures displaying correctly already, we just need to add animations to them.

For npcs, it looks like they are built out of body parts. Each body part is a separate mesh, and these body parts need to be connected correctly in the right x, y, z coordinates to display the npc. This is different than creatures, since they consist of only a single mesh.

So should these connections between the separate body parts all be made within the Npc::insertObj() function?
jhooks1 wrote: Looks like I should have read ape's post more closely
I wanted to proper load a nif file with animation before making thoughts on npc rendering. Because this requires to concatenate multiple meshes together and therefore it may be necessary to rewrite parts of the nif code.
So the improvements he committed to git (a while back) were mostly towards getting animations setup for creatures. So there hasn't really been any code written yet towards combining meshes at the right joints to make up npcs.

I wonder if standard rotations and translations would be fine to use to connect npc body parts, could be a problem when it is time to implement animations.
Zini wrote: insertObj is the right function, yes. I guess we might have to extend the CellRenderImp interface for animations (apps/openmw/mwrender/cellimp.hpp).

But the highest priority for any work on the animation system though should be fixing the crash bug, that we still have occasionally
openmw: /usr/local/include/OGRE/OgreSharedPtr.h:160: T* Ogre::SharedPtr<T>::operator->() const [with T = Ogre::Skeleton]: Assertion `pRep' failed.
jhooks1 wrote: I have started on npc rendering, here is an image of my progress.

Image

This version is far from perfect. Currently there exists one body part for dual body parts in the ESM (arms, legs, feet, etc. This basically means the character has two right feet, two right legs, etc. Somehow I need to mirror the meshes to get the opposite parts, which I haven't figured out how to do yet.
EDIT: Looking at the CS more closely it looks like there is a count of two for arms, legs, etc. I will see if I can iterate to the other part.

I don't have tails or hands placed properly yet.

The way my code works is for each body part we create a child Ogre::SceneNode We end up with a hierarchy of parts that goes like this:


Chest - the root node
Upper Arm->Forearm->Wrist->Hand
Upper Arm2->Forearm->Wrist->Hand

Groin-> Upper Leg->Knee->Ankle->Foot
Upper Leg2->Knee2->Ankle2->Foot2
Neck-->Head->Hair

So each npc consists of multiple SceneNodes that are linked together. To add a new part you pass to a function its parents as an array of strings.

std::string addresses[5] = {npcName + " chest", npcName + "upper arm", "", "", ""};

addresses and npcName + "Forearm" would be passed to the new insertMesh function. The function will search for a "chest" child, then if it finds "chest" it will search chest's children for npcName + "upper arm". If it finds the upper arm it will create a new child node named npcName + "Forearm"


So if I move the upper arm via a translation or rotation, the forearm, wrist and hand will move along with it.
Zini wrote: That's a good start.
jhooks1 wrote: To mirror the mesh you just have to scale in the negative corresponding direction. Now my npcs have a right foot and left foot. This will have to be done for some of the body parts at the top of the chain (upper leg2, upper arm2).
Hircine wrote: this is coming along nicely, good work, Jason is it?
Guest wrote:
Hircine wrote:this is coming along nicely, good work, Jason is it?
Yep.

I have been trying to get hands implemented. For some reason the MW devs put hands and chest in the same NIF file. I am trying to separate them into different meshes by using bounding boxes, and removing the submeshes that are out of bounds. I haven't had any luck with it yet though.
jhooks1 wrote: I haven't posted in a while, but I have been working on openmw.
I tried three approaches to separating the hands from the chest. The first approach was to use bounding boxes and destroySubMesh(), this left behind some garbage from the parts of the mesh I wanted to delete. I also tried to read the meshes into a buffer and get rid of nodes that weren't needed, this didn't work right either.

Finally I modified the load resource function and handleNode function. I made it so the unwanted shapes were never added. This worked. This simple solution, if I had tried it first would have saved me many many hours.
When you add the chest body part, loadResource() detects it and gets rid of the hand meshes. Later you add the hands.1st or hand.1st mesh, and loadResource gets rid of one of the hands (2 exist in that mesh).



There are still a few problems:
1. hands.1st for male Redguards and male Dunmer links to the female hand mesh. I am not sure if there actually exists proper hands.1st files for these two. I might have to use the Skins.nif and delete the chest from it, which would complicate things.

2. Constants for scaling, translation, rotation need to be changed to make the npcs look proper
3. Wood Elves may need to be scaled down


I will try to get my code up on git soon.
jhooks1 wrote: More Pics:
jhooks1 wrote: More:
ap0 wrote: awesome.
jhooks1 wrote: Female Breton, Male Breton, and Female Imperial.
Star-Demon wrote: Unnngh...the human races first? :P
jhooks1 wrote: I am working on beast races too, I am having a few problems with them though and want to get them looking good before I post them.
raevol wrote: Amazing, great work. I don't know if the philosophy is to get things on git before they are completed as long as they aren't crashy, or to wait until they are completely done before pushing? Either way make sure we don't lose your progress if you go MIA. ;)
jhooks1 wrote: Code is up on git, let me know if everything compiles right. Some of the code is redundant and will be cleaned up and/or rewritten later.


More Screens below.
raevol wrote: So exciting. :D

What's it going to take for animations?
jhooks1 wrote: I have committed some new code. It fixes male Altmers (hands were still in chest mesh), male Redguards (now have male hands), male Dunmer (now have male hands), and male Nords (now have male hands).

Animation will be the next step after the beast races are corrected. I am not sure how to animate, I imagine the nif animation files contain rotations, translations and the time to complete them in.
raevol wrote: Great work. Thank you for the frequent updates and screenshots. OpenMW lives!
Star-Demon wrote: Looks very good so far.

One question: Using this system, is it possible to support more complex meshes or bodies?

What would the current constraints be?
jhooks1 wrote:
Star-Demon wrote:Looks very good so far.

One question: Using this system, is it possible to support more complex meshes or bodies?

What would the current constraints be?
From earlier in the thread:
2) Set up the mesh as a scene node tree, then 'clone' that tree and insert it into the world whenever we place the mesh. This works and is what we did for most of the lifetime of the D version. But it's messy, you have to write all the clone code yourself, and most importantly you are now circumventing Ogre's mesh resource handling, which means that you have to do a lot of work if Ogre wants to unload and reload meshes. In addition, this also isn't very compatible with animations - the best way I could think of was to have bones in a skeleton and then attach the required scene nodes to them.


I am not sure if this would work well with creature meshes or not. With a creatures everything is inside one mesh. NPCs are constructed from body part (each part is a separate mesh) which are then joined together with SceneNodes.

I guess you could split a creature mesh into multiple parts, instructing OgreCreateSubMesh,handleNode, handleNiTriShape, and related functions to only write to a certain range. Then you could join the mesh back together with SceneNodes.

Is that what you meant by more complex/meshes or bodies?
Star-Demon wrote: Well, by more complex I meant more bones, higher poly meshes, parts, etc.
jhooks1 wrote: I got beast races working more or less. For female argonians I had to use the male forearm, it looks fine though. The beast races stand like a human instead of a beast. They should be standing somewhat hunched over on the balls of their feet with knees bent. This will have to fixed down the road, but I feel it is good enough for now. Also the tail needs to be changed to be pointing down more.

The tail, chest, and feet were all in the same skins.nif file so I had to clone each part into a new MeshPtr.

I will be diving into animations next. I have a feeling that tails (they will have to bend/curve) and hands (the fingers will have to open and close) will be the hardest to animate.

I will commit the new code sometime soon.
jhooks1 wrote: More Pics.
sir_herrbatka wrote: oh, MW standard bodies are ugly.

Anyway, they are rendered ok. Next step is animation (i guess that this is issue with beast races standing like humans)?
Chris wrote:
jhooks1 wrote:The beast races stand like a human instead of a beast. They should be standing somewhat hunched over on the balls of their feet with knees bent. This will have to fixed down the road, but I feel it is good enough for now. Also the tail needs to be changed to be pointing down more.
This is likely typical bind-pose settings. The way the vertices are laid out in the base model. Applying the initial bone positions to the skeleton (with the model being properly deformed by the skeleton) would probably get them hunched over, but that will come with the animation system.
Star-Demon wrote:
Chris wrote:
jhooks1 wrote:The beast races stand like a human instead of a beast. They should be standing somewhat hunched over on the balls of their feet with knees bent. This will have to fixed down the road, but I feel it is good enough for now. Also the tail needs to be changed to be pointing down more.
This is likely typical bind-pose settings. The way the vertices are laid out in the base model. Applying the initial bone positions to the skeleton (with the model being properly deformed by the skeleton) would probably get them hunched over, but that will come with the animation system.
What he said - it's normal to make a "default" pose where the characteris upright and arms are out and such while you are editing the mesh or the mesh's armatures.

Do not worry, all is well.
jhooks1 wrote: Code committed to git.

EDIT: I hope all this holds up with animation and I don't have to do a lot of recoding.
jhooks1 wrote: Animations for npc's are stored in the bsa as a single file base_anim.nif (applies to all npcs). You can view the animation names and line numbers in the construction set.

The first thing to do is to read the animations and figure out the format they are stored as.
Zini wrote: I have some questions:

1. What is components/nifogre/oldnpccode.txt? Is that a leftover or do we really need to have it in the repository?

2. What is MWClass::isChest? (in npc.hpp) Doesn't look like what I would call clean or correct (not to mention, that it produces tons of warning messages)

3. Are the log messages still needed or can they be removed?
NPC: Laire
RACEb_n_redguard_f_
NPC: Rerilie Llandu
RACEb_n_dark elf_f_
NPC: Nirtunus Crunus
RACEb_n_imperial_m_
NPC: Galam Llendu
RACEb_n_dark elf_m_
NPC: Varasa Dreloth
RACEb_n_dark elf_f_
NPC: Urnel Relas
Zini wrote: 4. Looks like we have a bit of a problem here. You are creating new Ogre movable objects that confuse the activation detection. We need to address this problem before we can have a release, because else we will crash without end.
Zini wrote: Considering 4. again, its probably no worth fixing, since the whole activation system will be changed with the introduction of physics. I will implement a workaround, that protects us from these crashes. That means we can't run any NPC dialogues in this release, but the dialogue stuff isn't ready for the public anyway.
jhooks1 wrote: Yes we can get rid of the MWClass::isChest. The oldnpccode.txt is just a mess of code of attempts at trying to get npcs working, it can be deleted. The log messages can be commented out.

I will look and see if there is an easy way to get npcs working with the current activation system.
Zini wrote:
I will look and see if there is an easy way to get npcs working with the current activation system.
Don't bother for now. I have got the crash-protection workaround in already.

This can be addressed properly after the release. Or not at all, if we get someone working on bullet. Little point in fixing code, that will be kicked out in a week or two.

Just get the other 3 points sorted out and we are ready for the release.
jhooks1 wrote: Changed the npc leg constants, I think the legs look a little more lined up and better now. I will do the same thing for the arms.
Zini wrote: Merged. Thanks. Still get a couple of warnings about unused variables, but we can sort that out later. Its not as if OpenMW would compile warning free anyway (which we definitely have to address at some point).
jhooks1 wrote: Ok, I used a bsa unpacker to get to all the NIFs in Morrowind.bsa.

I used an open source program called NifSkope to first view some normal body part meshes, they looked as I expected they would. Head body parts contain animations, eyes blink and mouths move. All other body parts do not contain animations.

I opened up base_anim.nif and was presented with a skeleton of points. No graphical nodes actually exist in this file. You can hit play and it will run through all the animations for human male npcs, there are quite a lot.

There exists more animations for npcs in separate files, including anim_dancinggirl.nif, argonian_swimkna.nif, base_anim_female.nif, base_anim.1st, and more.

I am very impressed by NifSkope. The animations look exactly like they would in the game.
NifSkope is written in c++, which is very convenient for us, our animation system will most likely end up pulling some code from this project.

You can find nifskope here: http://niftools.sourceforge.net/wiki/NifSkope

I also tried reading in the ExtraData (which I think is where the animation data would lie with our current system). I got what looks like a 8digit hex output, but I haven't looked further than that. I think it will be a lot easier just to reuse the pertaining code of NifSkope
raevol wrote: Wow, that's really exciting jhooks! It would be great if you could get some video of this, even of just nifskope at work? I know that's a big request for such a small thing, but this is a huge step forward!
Star-Demon wrote: I've heard of nifscope, but I never knew that about the animations. I always thought the armatures were included.

That's a complete pain, though. Mods that scale NPCs would also have to scale the skeleton and animations according to race, and there's no way that those mods will know about custom animations not on the default skeleton.

How about collision? Where's that data?

Wow...this also presents the problem of assigning weights to the parts of the body. When we implement Bullet we should be keeping track of what the weight of each bodypart node has on it...

jeez...
gus wrote: Actually, if we do not want to use Ragdoll, we don't need to use the exact collision mesh for NPC. In fact, many games use just a capsule for players collisions mesh. (never seen your hand/foot go through a wall?). It would be a way simpler. Of course, physic for dead corpse would use ragdoll but that's a post 0.1 feature as far as i understand.
Star-Demon wrote:
gus wrote:Actually, if we do not want to use Ragdoll, we don't need to use the exact collision mesh for NPC. In fact, many games use just a capsule for players collisions mesh. (never seen your hand/foot go through a wall?). It would be a way simpler. Of course, physic for dead corpse would use ragdoll but that's a post 0.1 feature as far as i understand.
That's true, we don't have to use ragdoll, but as it stands the capsule is getting people stuck on stuff and it's annoying.
gus wrote: I am not sure, but i think that you have more chance of getting stuck if you use the "real" mesh instead of a capsule.

Edit: but i don't know if the original morrowind use capsules. It might give some strange results with some animations.
jhooks1 wrote:
raevol wrote:Wow, that's really exciting jhooks! It would be great if you could get some video of this, even of just nifskope at work? I know that's a big request for such a small thing, but this is a huge step forward!
Sure, I'll see if I can get one up on youtube.
jhooks1 wrote: Heres the base_anim.nif in nifskope.

http://www.youtube.com/watch?v=DxRUdsFcHcg
raevol wrote:
jhooks1 wrote:Heres the base_anim.nif in nifskope.

http://www.youtube.com/watch?v=DxRUdsFcHcg
So. Damn. Cool.
Star-Demon wrote: Yeah, those animations could use some fine-tuning...

I'm not very good with rigging, yet, so unfortunately I can't do any improvements.
Chris wrote: The way I've found it works is that a mesh contains named bone nodes, which are positioned in a 'default' stance of sorts (which is not the bind pose). One of the nodes (the base, I think) contains a NiTextKeyExtraData, and these are my notes on it:

Code: Select all

// Animation and soundgen information is apparently stored in an array
// like this. The string key is specified as like "Idle: Start",
// "SwimWalkLeft: Loop Stop", and "Soundgen: Land", and the float value
// is the time in seconds along the animation track that corresponds
// with the action. There can be more than one text key action per
// pair, separated by a newline. Need to look into why some text keys
// are empty, though, and some have an errant newline at the end. A
// blank action may mean something, or it may be left-over junk.
The animation tracks are in .kf files, or in .nif files with a skeleton, though I'm not sure how they're stored yet (NiKeyframeData contains transform positions, but this is not enough info; as with other Ni*Data records, they're most likely referenced by other node types).

The biggest problem I foresee is that Ogre likes referencing bones by index, while Nifs seem to base on names. This will be a problem when trying to apply an animation to multiple skeletons, as the different skeletons can have a different name:index mapping. What would likely have to happen is that all the meshes get remapped to a single skeleton, or at least a skeleton with indentical name:index mappings.

In Oblivion, NPCs (and the player) all referenced one of a handful of Nifs which contained skeleton and colission nodes (two for human types, two for beast races), so assuming Morrowind is similar, it should prevent mass duplication of animations. When specific body parts are used, they'd have their bone weights remapped to whichever skeleton the NPC is using. Ogre does allow specifying the same animation on multiple skeletons, each with different scales, though I still need to look into how well it can share the same skeleton with different scales.

Note that this is still largely theoretical. In my attempts, I haven't gotten any farther than actually loading bones from the mesh nif in their default idle stance (to which, the visible mesh isn't even properly applied).
http://img577.imageshack.us/img577/750/ ... 011213.png
You can see the bones in the proper positions, but I have not yet figured out how to get Ogre to deform the mesh to it.


Also, note that there's multiple types of animations. The full-body animations are skeletal, but some of the "finer" animations (like lip movement) are vertex- or morph-based. That's why you only see one or two nodes for a head when many more would be needed to do eye or lip movements.
jhooks1 wrote: I am trying to convert my code from using SceneNodes to attach body parts together to using the skeleton (from base_anim.nif) with each body part mesh attached to a bone (or possibly bones). I think if I can put this together it will animate better, however I am not sure if this is even possible with OGRE.

I have the required Skeleton in a SkeletonPtr, the current body part mesh path, and the bone it should be attached to all being passed into a insertMesh() function. I am puzzled on how to actually join them though.


EDIT: Skeletons have to exist within a mesh, they can't stand alone. I might be able to load the base_anim.nif to act as a empty mesh containing a skeleton, and store it in an Entity. Then I could bind other entities (Body Parts) to it with Entity::attachObjectToBone()
Chris wrote:
jhooks1 wrote:EDIT: Skeletons have to exist within a mesh, they can't stand alone. I might be able to load the base_anim.nif to act as a empty mesh containing a skeleton, and store it in an Entity. Then I could bind other entities (Body Parts) to it with Entity::attachObjectToBone()
Something like that. From what I've seen, a Nif with an actual mesh will still have bones defined in it so proper weights can be applied to the vertices. Perhaps you can attach the mesh's bones to the base nif's bones, then animating the base skeleton will also animate the mesh's bones.
jhooks1 wrote: The first small step is down, getting a mesh attached to the base_anim.nif skeleton. I attached the chest body part to the "Chest" bone and it appears. Will put my code on git.

EDIT: I think there is something wrong with our skeletons, I assigned body parts to bones that are right next to each other and the parts are drawn very far apart.

I am still conflicted thinking whether I should use this method or bail back to scenenode method.
With scenenodes I already have the npcs being rendered but it will probably be harder to animate.

With the skeletons I have to redo npcs, but it will most likely be easier to animate.
jhooks1 wrote: I checked the positions of Chest and Bip01 Spine in openmw versus the one's from NifSkope, they are correct. I am not sure about the rotations though, in openmw they are quaternions and in NifSkope they are represented by yaw, pitch, and roll. Will have to look into the math behind that.

The code is committed under "Attempting NPCs with skeletons" currently it is just a bunch of chest objects attached to a few different bones.
Zini wrote: While you are at it, could you also have a look at the random NPC rendering crashes? These are skeleton-related it seems.
Peppe wrote:
Zini wrote:While you are at it, could you also have a look at the random NPC rendering crashes? These are skeleton-related it seems.
If you mean

Code: Select all

include/Ogre/OgreSharedPtr.h:160: T* Ogre::SharedPtr<T>::operator->() const [with T = Ogre::Skeleton]: Assertion `pRep' failed.
I can reproduce that consistently, just try to go through the door out of the caves. loading exterior cell '5, -11'... crash...

Call comes from NIFLoader::handleNiTriShape, rebuilding with a bit more debug symbols to get more out of the core dump.

Edit:
The problem in handleNiTriShape occur at line 647 (components/nifogre/ogre_nif_loader.cpplooking at dd4d022)

Code: Select all

//get the bone from bones array of skindata
bonePtr = skel->getBone(shape->skin->bones[boneIndex].name.toString()); 
Apparently skel is not all as we expect at this point.

Code: Select all

skel = {<Ogre::SharedPtr<Ogre::Skeleton>> = {_vptr.SharedPtr = 0xa56ed0, pRep = 0x0, pUseCount = 0x0, useFreeMethod = Ogre::SPFM_DELETE, mutex = 0x0}, <No data fields>}
gus wrote:
I am not sure about the rotations though, in openmw they are quaternions and in NifSkope they are represented by yaw, pitch, and roll. Will have to look into the math behind that.
NifSkope is an editor, so i guess it converted the quaternion in something more understandable by humans ;) Using quaternion is just fine for Ogre.
jhooks1 wrote: Each part/entity can only attach to one bone in OGRE as far as I can tell. This could be a problem, there are more bones in base_anim.nif than there are body parts. It could be though that the extra bones are for armor and clothes.

EDIT: For now I have decided to use the Bip01 bones (e.g. "Bip01 Spine" instead of "Chest")
jhooks1 wrote: I am now reading in the NiKeyframeData, this is the core of the NIF animation data. Each NiKeyframeData contains the scalings, rotations, and translations of a particular bone. Right now I am storing the data in std::vector objects (may change later).

The NIFSkope source code didn't help, it was easier just to write it from scratch, and our nif filesystem classes already had enough functionality to make this really simple. NifSkope itself did help as a reference though.

There are still a few more things I need to add to the NiKeyframeData reading code, but I have most of what we need for npc animations implemented.
jhooks1 wrote: When I try to access the NiKeyframeController from within the handleNode()

Nif::Controller *go = (node->controller).getPtr();

Nif::NiKeyframeController *f = dynamic_cast<Nif::NiKeyframeController*>(go);

At runtime I get a message "error during rendering: Access Violation - No RTTI data!"









I can access the data from loadResource() using nif.getRecord(i), so for now I will just use that approach.

EDIT: Making some good progress, starting to load animation tracks.
jhooks1 wrote: There are a few things I am still trying to figure out:

How to apply TBC (tension, bias, continuity) to a Ogre::TransformKeyFrame, most NiKeyframes don't use this (The weapon bone does though).

Also, How to apply forwards and backwards in scale. I haven't actually seen this type of scale in a NIF yet, so maybe we don't need it.
jhooks1 wrote: A tough problem I am trying to solve is flipping a mesh (-1 scale). This was easy to do with SceneNodes.

With attachObjectToBone there is only a quaternion offset and a translation offset. Trying to scale the actual bone makes openmw crash. Without this the meshes will have two left arms, left legs, etc.


EDIT: MeshMagick may be a solution to this
http://www.ogre3d.org/tikiwiki/MeshMagi ... ture=Tools
jhooks1 wrote: I've been trying to build MeshMagick as a library so I can use it in the new rendering code. It uses cmake, I got the visual studio project for it generated. I am experiencing linker errors related to the tootle library. I will update when/if I figure this out.
jhooks1 wrote: I got the MeshMagick library built (.lib), but I am getting linker errors when trying to use it in openmw.

EDIT: Here is the error log

Code: Select all

1>interior.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall meshmagick::MeshMagick::~MeshMagick(void)" (__imp_??1MeshMagick@meshmagick@@QAE@XZ) referenced in function "private: virtual void __thiscall MWRender::InteriorCellRender::insertMesh(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Ogre::Entity *,class Ogre::Quaternion,class Ogre::Vector3)" (?insertMesh@InteriorCellRender@MWRender@@EAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V34@PAVEntity@Ogre@@VQuaternion@6@VVector3@6@@Z)
1>interior.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall meshmagick::TransformTool::transform(class Ogre::MeshPtr,class Ogre::Matrix4,bool)" (__imp_?transform@TransformTool@meshmagick@@QAEXVMeshPtr@Ogre@@VMatrix4@4@_N@Z) referenced in function "private: virtual void __thiscall MWRender::InteriorCellRender::insertMesh(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Ogre::Entity *,class Ogre::Quaternion,class Ogre::Vector3)" (?insertMesh@InteriorCellRender@MWRender@@EAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V34@PAVEntity@Ogre@@VQuaternion@6@VVector3@6@@Z)
1>interior.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class meshmagick::TransformTool * __thiscall meshmagick::MeshMagick::getTransformTool(void)" (__imp_?getTransformTool@MeshMagick@meshmagick@@QAEPAVTransformTool@2@XZ) referenced in function "private: virtual void __thiscall MWRender::InteriorCellRender::insertMesh(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Ogre::Entity *,class Ogre::Quaternion,class Ogre::Vector3)" (?insertMesh@InteriorCellRender@MWRender@@EAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V34@PAVEntity@Ogre@@VQuaternion@6@VVector3@6@@Z)
1>interior.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall meshmagick::MeshMagick::MeshMagick(class Ogre::Log *)" (__imp_??0MeshMagick@meshmagick@@QAE@PAVLog@Ogre@@@Z) referenced in function "private: virtual void __thiscall MWRender::InteriorCellRender::insertMesh(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const&,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Ogre::Entity *,class Ogre::Quaternion,class Ogre::Vector3)" (?insertMesh@InteriorCellRender@MWRender@@EAEXABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@V34@PAVEntity@Ogre@@VQuaternion@6@VVector3@6@@Z)
Any ideas on how to fix this?
Zini wrote: Looks like you missed some parts when linking the library. Or maybe when building the library?

btw. is it only me or are the "Code" type boxes a bit hard to read on this forum (low contrast and such).
Zini wrote: Unrelated to this I found a problem with the NPC rendering code. You are using the ID as an Ogre handle. That won't work because there can be multiple NPCs with the same ID (think guards and other generic people), while Ogre handles need to be unique.
Star-Demon wrote: Can you grab a unique ID from the data?

Oh, actually, you can - this is why there are base IDs and reference IDs. using that should fix it.
jhooks1 wrote: Basically I need vs2010 to output a .dll and a .lib. I build as a dll and all it outputs is a .lib (and an .exe, but that is the command line meshmagick tool, unrelated) even though I have the dll option option set in Configuration Properties->General->Configuration Type for meshmagick_lib). I am going to give up with the meshmagick for now and go back to coding. For now we will just have to have to deal with two left legs, feet, etc :(.
Benbat wrote: But, couldn't you do the mirroring using the quaternions ?

See http://www.euclideanspace.com/maths/geo ... /index.htm for an explanation.
jhooks1 wrote: I just tried that, it didn't work for me. I am pretty sure that is only for points, so I would have to apply that to every point of the mesh.
jhooks1 wrote: Just committed some new code that adds the amount of time that has passed into the NPC model and runs the animation. Currently it crashes openmw (you have to uncomment a line in engine.cpp to get the process running and get the crash). I put the NPC base model in LiveCellRef, it couldn't go in the NPC struct (loadnpc.hpp) because of its const property.

At this time I think my animation loading code in ogre_nif_loader.cpp is not formatted right and is causing the crash.
Zini wrote: Looks like we have a problem here. Your git client has lost your identity. Also, you broke tons of source files totally unrelated to NPC rendering. A botched merge maybe?
jhooks1 wrote: I fixed the loading code, the crashes are gone and the body parts are moving around onscreen.

Zini, which commit of mine caused the problem? Which files are affected? I can still build and run the code on my machine.
Zini wrote: Oops! My fault. Was checking the wrong branch. All good.

However putting the Entity pointer into LiveCellRef is not so good. For the purpose of reusability the esm store component should not depend on Ogre. Also, we should be very careful with adding stuff to LiveCellRef, because that can become very expensive memory wise. Why do you need to store it at all? Usually we work just with the handles.
jhooks1 wrote: I will try to change it to use the SceneManager to get to the model mesh.
jhooks1 wrote: I have tried to combine the rotations and translations into TransformKeyFrames. The end result does not look good, the npc moves around across the screen from place to place at the beginning idle animations, where there should be very little movement. At this time I have only bound a few body parts, but it is enough to see that something is wrong.

OpenMW can display the translations by themselves or the rotation by themselves of animation properly. Its when we use an algorithm to put them together that problems occur. I may post a video of whats going on.

Using a custom animation system instead of OGRE's may solve these problems. If anyone wants to look at the code/see if they can figure out a solution check my git.
raevol wrote:
jhooks1 wrote:The end result does not look good, the npc moves around across the screen from place to place at the beginning idle animations, where there should be very little movement. At this time I have only bound a few body parts, but it is enough to see that something is wrong. ... I may post a video of whats going on.
I'm not going to have any valuable input for you, but I'd love to see a video of this. In-progress Dev stuff like this makes me giddy.
jhooks1 wrote: I got it working :D I made two separate animations, one containing all the rotations and one containing all the translations. Then I used a blend mask to combine them. Videos to come soon.
Hircine wrote: could you send me a copy of the video in a PM?

so i can host it up on moddb.

cheers
jhooks1 wrote: Here is the video,

http://www.youtube.com/watch?v=17sRu-z5Sn0


I may upload an older one that uses calf bones and looks a little different.


Right now each body part is only being attached to one bone. I haven't figured out how to attach to multiple bones yet (we will need to). The parts aren't connected quite right, this can be somewhat fixed by adjusting the rotation and translation offsets. Also the character in the video is slanted diagonally, this can be fixed by adjusting the scenenode.

Hircine, if you are still up for it I will send you the video.

I will try to fix some of these problems and then upload another video.
Hircine wrote: pm or email me a mediafire download link :)

yay for progress.

awesome work. can't wait til your next batch of progress.

keep it up.
jhooks1 wrote: I am going to try to use the Head, Chest, Right Upper Leg, etc bones (using the bip01 bones now). I think they might work better.
sir_herrbatka wrote: I hope. The last video was just scary like very bad nightmare.
Hircine wrote: I have decided against uploading this to moddb. its cool. but not something we want to show to the public. (they won't really understand).

the kind of video that we can show them is one where an npc moves its arm or legs or walks or something. even if its partially broken(bones don't stay together etc).
jhooks1 wrote: I've started back working on this, there is movement from time to time (it looks different than the old video) but the legs stay locked at the knees. Not sure how to get this working right, if I can't figure this out soon I might just work on another area of OpenMW
gus wrote: I'm having a crash with your code:
when trying to load the vivec Cell, it tries to load the mes "meshes\x\Ex_V_ban_hlaalu_01.NIF" and it crash. Here is the call stack:
msvcr100d.dll!_NMSG_WRITE(int rterrnum) Ligne 217 C
msvcr100d.dll!abort() Ligne 61 + 0x7 octets C
msvcr100d.dll!_wassert(const wchar_t * expr, const wchar_t * filename, unsigned int lineno) Ligne 153 C
OgreMain_d.dll!513030df()
[Les frames ci-dessous sont peut-??tre incorrects et/ou manquants, aucun symbole charg?Š pour OgreMain_d.dll]
openmw.exe!NIFLoader::handleNiTriShape(Nif::NiTriShape * shape, int flags, BoundsFinder & bounds) Ligne 647 + 0xe octets C++
openmw.exe!NIFLoader::handleNode(Nif::Node * node, int flags, const Nif::Transformation * trafo, BoundsFinder & bounds, Ogre::Bone * parentBone) Ligne 878 C++
openmw.exe!NIFLoader::handleNode(Nif::Node * node, int flags, const Nif::Transformation * trafo, BoundsFinder & bounds, Ogre::Bone * parentBone) Ligne 837 C++
openmw.exe!NIFLoader::handleNode(Nif::Node * node, int flags, const Nif::Transformation * trafo, BoundsFinder & bounds, Ogre::Bone * parentBone) Ligne 837 C++
> openmw.exe!NIFLoader::loadResource(Ogre::Resource * resource) Ligne 1071 C++
OgreMain_d.dll!5159cbf6()
OgreMain_d.dll!513ee322()
OgreMain_d.dll!5124135a()
OgreMain_d.dll!51415e2e()
OgreMain_d.dll!51656a4f()
OgreMain_d.dll!5163da24()
OgreMain_d.dll!5163db16()
openmw.exe!MWRender::ExteriorCellRender::insertMesh(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > & mesh) Ligne 205 + 0x24 octets C++
openmw.exe!MWClass::Activator::insertObj(const MWWorld::Ptr & ptr, MWRender::CellRenderImp & cellRender, MWWorld::Environment & environment) Ligne 25 + 0x35 octets C++
openmw.exe!insertCellRefList<ESMS::CellRefList<ESM::Activator,MWWorld::RefData> >(MWRender::CellRenderImp & cellRender, MWWorld::Environment & environment, ESMS::CellRefList<ESM::Activator,MWWorld::RefData> & cellRefList, ESMS::CellStore<MWWorld::RefData> & cell) Ligne 30 + 0x1e octets C++
openmw.exe!MWRender::CellRenderImp::insertCell(ESMS::CellStore<MWWorld::RefData> & cell, MWWorld::Environment & environment) Ligne 47 + 0x18 octets C++
openmw.exe!MWRender::ExteriorCellRender::show() Ligne 337 C++
openmw.exe!MWWorld::World::loadCell(ESMS::CellStore<MWWorld::RefData> * cell, MWRender::CellRender * render) Ligne 304 + 0x1d octets C++
openmw.exe!MWWorld::World::changeCell(int X, int Y, const ESM::Position & position, bool adjustPlayerPos) Ligne 381 C++
openmw.exe!MWWorld::World::changeToExteriorCell(const ESM::Position & position) Ligne 726 C++
openmw.exe!OMW::Engine::go() Ligne 399 C++
openmw.exe!main(int argc, char * * argv) Ligne 119 C++
openmw.exe!__tmainCRTStartup() Ligne 555 + 0x19 octets C
openmw.exe!mainCRTStartup() Ligne 371 C
kernel32.dll!76e33677()
ntdll.dll!77c79d42()
ntdll.dll!77c79d15()


After a little debuging, it seems that the "skel" is not created. (maybe related to the fix me stuff with the root scene Node ?)
Zini wrote: That is the same bug you encountered before. It is already fixed in my master branch.
gus wrote: Sorry, i didn't realized it was already fixed :oops:
jhooks1 wrote: I am still having the same problem as I mentioned in my last post. I will post a video soon to show what I mean.

Currently body part meshes are attached to the base_anim model using attachObjectToBone()
I think instead attaching each vertex of a body part's NiTriShape/submesh to a bone of base_anim may fix it. This will take a lot of work though, and it may end up with the same problem that we have now.

Any gurus out there on skeleton animation think that by attaching each individual vertex of a body part to a bone of the base_anim skeleton will solve this?
jhooks1 wrote: Here is the video, http://www.youtube.com/watch?v=Sy4O0SDWaRo

If you look at the lower body of the npc the knees never bend.

The parts/bones I have bound are: Right Upper Arm, Left Upper Arm, Neck, Head, Right Upper Leg, Left Upper Leg, Left Ankle, Right Ankle, Left Foot, Right Foot, Left Knee, Right Knee, Groin
jhooks1 wrote: I wrote some new code trying to bind the submeshes of body parts to the base mesh. The code doesn't work though so I am not going to bother with committing it.

I am going to go in a different direction by trying working on creature animation, since all the data needed is contained within one mesh.
Greendogo wrote: Your progress looks very promising Jhooks, considering implementing animation can be pretty difficult. I'd say that torsoless monstrosity is one of the most beautiful sights I've seen yet in OpenMW. :D
jhooks1 wrote: I updated my master branch to zini's latest. I am getting a cmake error that it can't find bullet. I downloaded bullet and C:\bullet-2.77\src is my bullet include directory.

OpenMW pre-built binaries not found. Using standard locations.
Looking for OGRE
Using OGRE SDK
Looking for OIS...
Found OIS: optimized;C:/OgreSDK_vc10_v1-7-1/lib/release/OIS.lib;debug;C:/OgreSDK_vc10_v1-7-1/lib/debug/OIS_d.lib
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:91 (MESSAGE):
Could NOT find Bullet (missing: BULLET_DYNAMICS_LIBRARY
BULLET_COLLISION_LIBRARY BULLET_MATH_LIBRARY BULLET_SOFTBODY_LIBRARY)
Call Stack (most recent call first):
C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/FindPackageHandleStandardArgs.cmake:252 (_FPHSA_FAILURE_MESSAGE)
cmake/FindBullet.cmake:66 (FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:259 (find_package)


Configuring incomplete, errors occurred!
jhooks1 wrote: Reviving this thread. I just committed some new code with a few new ideas I got from nifskope's source. Ditched ogre's built-in animation system, we are now manually moving bones. Right now only npc's can be animated using this method (no creatures), which I suspect has something to do with vertex bone mapping.

Body parts are all over the place right now, but the lower body does seem to stick together. Knees are bending for the first time (wasn't working before with ogre's built-in system). Translations are disable atm, they seem to throw everything apart. Crashes on cell change.
Zini wrote: I see you are adding more stuff to the engine class. Please don't! The engine class is meant to join all the different parts of OpenMW together (Facade pattern). It should barely do anything itself.

It seems you are deriving your new code from your old animation branch, which by accident was merged into your directories branch. I have spend quite a bit of time to remove various dirty bits from it and I can say that it definitely needs a cleanup (among others you are including Ogre.h, which you should never do, and you are also adding OGRE stuff to the ESM/ESMStore components, which also should be avoided).
Unless your old animation branch has a substantial amount of code you need for your new attempt, I suggest to start with a new, clean branch.
jhooks1 wrote: Animation has to be updated through frameStarted(), where do you recommend putting this code? In a new class?

Also please recommend a proper place to put the NiKeyframedata and entity pointer instead of LiveCellRef. This data needs to be accessible from the creature or npc list.

The code does need a cleanup like you mentioned.
Zini wrote: That's difficult. The whole rendering system is still scheduled for refactoring. What I can advise you now, may not be correct in a version or two anymore.

For now most stuff should go into the MWScene class or the renderer classes (Interior, Exterior). Same for the management of all animated actors in the scene.
Adding stuff to LiveCellRef directly should be avoided. Runtime-data goes into the mData member (which is of type MWWorld::RefData in OpenMW; the editor will probably define a separate class). But even here we should only keep persistent data, because adding more data members to RefData can potentially blow up the memory consumption a lot. From your description I take it the data you want to add is not persistent (it only exists as long as the object is in an active cell).

This is probably not the best time to work on rendering features. Unless you are very determined to continue with the animation, I suggest to wait until the refactoring is done.

I haven't heard from the people who wanted to do terrain for a while. If that continues, we can as well move Terrain to 0.13.0 and mwrender refactoring to 0.12.0.
jhooks1 wrote: Hey guys!!! This is very exciting for me, animations are now working on NPCs (no creatures yet). I am going to hand my gui task off to akebono and continue working on animation features.

I pushed my code to the animation branch. Videos will be up soon.

EDIT: I need to fix things on this branch, still crashes if the cell contains creatures. Also needs some cleanup.
jhooks1 wrote: Just did some cleanup and fixed the creature crash error.
sir_herrbatka wrote: wow, can't wait to see the video. :)
jhooks1 wrote: I have integrated the meshmagick TransformTool code with my latest commit. Much of the code that was included with the meshmagick library I removed to make things simpler. I have included only scaling functionality.

There is a problem though. Once we scale the MeshPtr, the mesh/entity does not get updated.

The relevant code:
void InteriorCellRender::insertMesh(const std::string &mesh, Ogre::Vector3 vec)
{
assert (insert);

MeshPtr flip = NIFLoader::load(mesh);
mTool->processMeshFile(flip, vec);
//flip = NIFLoader::load("meshes\\b\\b_n_argonian_f_knee.nif");
MovableObject *ent = scene.getMgr()->createEntity(mesh);
insert->attachObject(ent);

if (mInsertMesh.empty())
mInsertMesh = mesh;
}

We need flip to replace the previous mesh, but it is not happening. Also if you uncomment the argonian line above the mesh does not change.

The mesh could be saved to a file and then reloaded in ogre_nif_loader. This would be inefficient and messy though. For this we would need to use our new resource loader.

There is a patch that allows you to make an entity from a name and an existing MeshPtr. It is not official though, and I haven't tried it yet.

Anyone have any ideas to solve this?

I haven't forgotten about the video, but I want to get meshmagick working first so the npcs will have the proper mirrored parts.
Zini wrote: Is that a meshmagick-specific problem? Because otherwise I don't get what is bothering you. OGRE can handle meshes generated at runtime. Just use a ManualResourceLoader (which does not need to load stuff from disc, it can also take procedurally generated meshes).
jhooks1 wrote: Thanks, I will try the manual resource loader.
jhooks1 wrote: I am having trouble figuring out how to implement this.

First I load the mesh through the NIFLoader, then scale it with the TransformTool.

I make a class that inherits from the ManualResourceLoader. The classhas a load function that you pass in the name of the mesh and the scaled MeshPtr? Is loadResource() is called automatically?

After that I create the entity with the name of the mesh?

This is confusing.
Zini wrote: You use the Ogre resources manager to create the resource, e.g. Ogre::MeshManager::createManual
jhooks1 wrote: So I don't need to make a class that inherits from ManualResourceLoader? I get that I can make a new mesh with createManual, but I need it to have the contents of a MeshPtr that was loaded in the NIFLoader, and scaled by meshmagick. How would I put this content into the new mesh?
Zini wrote: You can call createManual without a ManualResourceLoader, but Ogre will then give you a warning about what you are doing being dangerous. Which it is. Ogre may remove resources that have not been used for a while from its resources system. And if that happens to a manually created resource without a ManualResourcesLoader, Ogre won't know how to get it back, when it is used again later.
jhooks1 wrote: Ok, I'll use a class that inherits from the ManualResourceLoader. How do I get the contents of the MeshPtr that was loaded in the NIFLoader and scaled by MeshMagick into this newly created Mesh?
Zini wrote: Sorry, no clue about MeshMagick
jhooks1 wrote: Maybe it would be easier to just use the meshmagick.lib. How do I add a new .lib library into our cmake setup?

This page has some info about meshmagick http://www.ogre3d.org/tikiwiki/MeshMagick
Zini wrote: You need to write a FindNameOfLibrary.cmake file. There are several examples in the cmake directory. That would create an additional dependency though. Might be better to add it as an external library (extern directory).
Star-Demon wrote: Just a comment first - then question -

I've been watching this one on and off since I am learning about characters and animation implementing them.

I have to say - the difficulty with which we're trying to make a character mesh work with this segmented body is showing me how important a good content pipeline, a good design, and good technology is. I can respect how complicated a character model can be - having never completed one myself, but it seems we've been cursed with a 10-year-old technology conforming to a system that replaces entire body parts to handle clothes.

Through out this 13-page saga (and comments elsewhere) - Nif and Morrowind's actors have proven rather archaic and hard to use. For all the modding that's been done and the massive amount of existing work done (have you seen the new House Dres velothi structures for TR? Wow.), I really don't understand why it has to be so hard to not only find a functioning exporter for Blender (that doesn't require an old version ala anything I've experienced with python-anything. grrrr), but also implement characters and creatures because they were structured so differently.

Anyways - My question:

I got lost a little while back on this thread - we are working on correctly positioning NPC parts on the skeleton and then animating them, but to do this we have to do the transformations and scaling ourselves during the whole process, but it's unclear if OGRE's API is sufficient enough to do this?
jhooks1 wrote: When I tried using ogre's system for animation, it did not work at all for nifs. The way ogre's animation system works is you have each keyframe at a specific time. You can specify a translation, a scale, and a rotation for each keyframe. This means as soon as you reach the next keyframe, the old keyframe is done. You cannot specify a specific an absolute position or orientation of a bone through ogre's animation system. NIF's system uses absolute rotations and positions.

With ogre's system there was also a problem with many bones being locked, (e.g. the knees would never bend). Not sure why it did this, but this does not happen in the new custom implementation.

The way morrowind's system works is:
1. There is a list of Quaternions (rotation) and times. This is the bone's current rotation for that specific time. It is not a Quaternion of how much you want to rotate the bone from its current value, it is the actual new rotation/orientation of the bone.

2. There is another list of positions and times. This is the bone's current position for that time.

3. Some nif's contain a list of scales and times, but I have not seen one yet in morrowind.


The #1 list and #2 list occur at different times
An example of the times: (base_anim.nif bip01)
#1 (rotation) 0 2.6 2.667 2.7333 2.88
#2 (translation) 0 1.333 2.667 2.733 3.7333

So the rotations and translations occur at different times, at times a new rotation will start when an old translation is still active (and vice versa). But it all must be rendered simultaneously.

Right now the biggest roadblock is getting meshmagick to work so we can scale body parts (useful for mirroring parts, could also be useful for making bosmers smaller and scaling long swords). We may also need to use meshmagick's alignment functionality to center some parts (not sure yet). I have used the meshmagick exe to scale some .mesh files, and it did look proper in an ogre demo. We just need to get it to work in openmw.

Also, I am not sure about entire body parts always being replaced for armor. With many characters in morrowind you could see the armor but there are gaps where you can see the skin/clothes underneath. I already have an idea of how to implement it, but it will have to wait until the more fundamental/base animation stuff is done.
Star-Demon wrote: Cool - Thanks much, jhooks. :)
jhooks1 wrote: I am trying to use the meshmagick_lib.lib. Zini, do you think you can look at my latest commit and tell me if I am doing the cmake stuff right? I took the FindAudiere.cmake and modified it for meshmagick.

I get the following linking errors in visual studio:

1>ogre_nif_loader.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall meshmagick::MeshMagick::~MeshMagick(void)" (__imp_??1MeshMagick@meshmagick@@QAE@XZ) referenced in function "public: virtual void __thiscall NIFLoader::loadResource(class Ogre::Resource *)" (?loadResource@NIFLoader@@UAEXPAVResource@Ogre@@@Z)
1>ogre_nif_loader.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: void __thiscall meshmagick::TransformTool::transform(class Ogre::MeshPtr,class Ogre::Matrix4,bool)" (__imp_?transform@TransformTool@meshmagick@@QAEXVMeshPtr@Ogre@@VMatrix4@4@_N@Z) referenced in function "public: virtual void __thiscall NIFLoader::loadResource(class Ogre::Resource *)" (?loadResource@NIFLoader@@UAEXPAVResource@Ogre@@@Z)
1>ogre_nif_loader.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class meshmagick::TransformTool * __thiscall meshmagick::MeshMagick::getTransformTool(void)" (__imp_?getTransformTool@MeshMagick@meshmagick@@QAEPAVTransformTool@2@XZ) referenced in function "public: virtual void __thiscall NIFLoader::loadResource(class Ogre::Resource *)" (?loadResource@NIFLoader@@UAEXPAVResource@Ogre@@@Z)
1>ogre_nif_loader.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: __thiscall meshmagick::MeshMagick::MeshMagick(class Ogre::Log *)" (__imp_??0MeshMagick@meshmagick@@QAE@PAVLog@Ogre@@@Z) referenced in function "public: virtual void __thiscall NIFLoader::loadResource(class Ogre::Resource *)" (?loadResource@NIFLoader@@UAEXPAVResource@Ogre@@@Z)
1>C:\a\openmw\new5\Release\openmw.exe : fatal error LNK1120: 4 unresolved externals
Zini wrote: Obviously it does not work. I tried to merge in your branch, but I get tons of merge conflicts and I really don't have the time to sort through them right now.

Did the cmake phase of the build process produce any error messages? Also, does your find script set the cmake variables correctly? (see CMakeCache.txt).

Edit: From what I see you decided to add meshmagick as an external library (though you forgot to add it to the repository). In this case you don't need a find file. Instead you should add a cmake file to the meshmagick subdirectory (as it is done for Caelum and MyGUI).
jhooks1 wrote: I tried adding meshmagick to extern but I had even more error messages than now. Right now I am trying to use the .lib. Cmake doesn't seem to complain about anything.
jhooks1 wrote: I got meshmagick working in the extern directory with my latest commit. Still having trouble getting meshes/entities updated to new scales.
jhooks1 wrote: Still having the same problem, I think it is either one of two things:

1. We are not running in standalone mode. Standalone mode initializes a few ogre related objects, the meshmagick exe runs in this mode.

2. The vertex buffering process is different. The NIFLoader and meshmagick have their vertex buffers coded in different ways. Whether they are compatible with each other is unknown.


EDIT: Looking at the code now, if I can't get the scaling to update, I think I can apply the transformation directly to the vertices in NIFLoader::createOgreSubMesh() before they are written to the buffer. However, I would like to avoid doing this.
jhooks1 wrote: I added the necessary code into NIFLoader::createSubMesh()

It works for regular scaling, (e.g. 3,3,3 making the mesh 3 times bigger in every direction). It does not work properly if you need to flip something (e.g. 1,-1,1). I am pretty sure the texture needs to be flipped for this to mirror parts correctly, I don't think it is being flipped the moment.
jhooks1 wrote: Even though I don't have mesh mirroring working, I think I am going to post a video soon.

I just realized that more than one mesh can be attached to each bone in OGRE. I attached hair to the head bone (head mesh already attached) and it worked flawlessly. This means that attaching armor and clothes should be just as easy.
jhooks1 wrote: It's been a few weeks since I got the custom animation system working and I have not uploaded any videos. Here is the first http://www.youtube.com/watch?v=KP5wAOTe3A4 . This is a rendering of the base animation file, it contains most of the morrowind npc animations. It is being applied to a female Redguard. The animation lasts approximately 360 seconds.

I highly recommend setting youtube to 720p when you watch this. I had record this at 10fps, when I tried recording at 30fps it played back super fast. As a result the video is a little choppy.

I could have made the right hand proper (there is a right and left in the skins file) but I wanted to get something up tonight. Once I get mirrored parts working I am going to try to have a system where if you add a "#" on the end of a filename ogre knows to delete the "#", process and flip the mesh.

Right now the character stays in the same spot. Obviously when the npc runs he needs to move forward, not stay in the same position. We could be implemented by moving the scenenode with AI, but I am pretty sure this can be fixed without doing that.

Some of the animations suffer because of the npc not moving, especially the death animations. My theory on why this is happening is the npc is not allowed to exit its bounding box. When bip01 tries to move past the box it cannot. If we move the scenenode with the transformations of bip01 instead of bip01 I think it might fix this problem.
heilkitty wrote: Just a note: meshes for bodies can be asymmetrical too (see Asymmetrical Hands for Better Bodies, Asymmetric BB Models, Left-handed in Morrowind).
raevol wrote: This is so exciting! Great work dude! I am so happy to see this, the familiar morrowind npc flailing! :D

I notice that especially in the hips and shoulders, the body parts seem to come "unglued" from each other. Do you know the cause of this?
sir_herrbatka wrote: your soul is saved jhooks :D
jhooks1 wrote:
raevol wrote:This is so exciting! Great work dude! I am so happy to see this, the familiar morrowind npc flailing! :D

I notice that especially in the hips and shoulders, the body parts seem to come "unglued" from each other. Do you know the cause of this?
I think I know what you mean, the groin piece doesn't really seem to move. Also when the arms move to a certain height they do look detached. Could be related to the positions and rotation offsets.
Zini wrote: Just to make sure, that we are on the same page:

Your animation branch has diverged too much from the primary line of development (currently the next branch) for an automatic merge. Even a semi-automatic merge will be a lot of additional work (not even counting the substantial clean up work required) and with the MWRender rewrite gus is doing now it will become entirely impossible to merge your branch in.

Therefore I see your animation branch as a place to experiment and find out how things work. The idea is for you to create a new branch, once gus is done and to transplant the code from your old branch to the new one (moving it into the functions gus will have prepared for you). Is that agreeable?
jhooks1 wrote: Yes that sounds good. When gus is done I will start a new branch.
jhooks1 wrote: Found the following program that converts from .dds to many popular image formats (JPEG,gif). I tried it and it works, now I need to flip the jpg texture output file and try to load it in handleNiTriShape().

http://www.xnview.com/en/download_nc.html
It is not opensource, but is available for free for many platforms, and is a command line tool.
Zini wrote:
It is not opensource, but is available for free for many platforms, and is a command line tool.
That is actually a big problem. Available for many platforms is not good enough and "Commercial use is not authorized without agreement or ordering." is especially problematic (after all a commercial OpenMW-derived game is entirely possible as long as the source stays open). I don't think we can use this tool.
ap0 wrote: This tool is not released under a free license, imho it should be be used in openmw.
jhooks1 wrote: I've been looking at the hands.1st.nif files in nifskope.

They contain 3 NiTriShapes for the left hand and another 3 NiTriShapes for the right.

The respective NiTriShapes share the same texture files though. The NiTriShapes contain different texture coordinates. I think I can mimic this process/algorithm of changing the texture coordinates. If it works I won't have to deal with modifying texture files.
jhooks1 wrote: Yay!! Found a bug in my code that fixed the whole texture thing (wish I had found it earlier, would have saved a whole whole lot of time). Expect another video soon. Meshes can now be flipped.
Zini wrote: Good! We still have to decide if we need a separate class for NPCs and creatures in the new MWRender subsystem or not. See this thread: <!-- l --><a class="postlink-local" href="http://openmw.org/forum/viewtopic.php?f=14&t=494]viewtopic.php?f=14&t=494</a><!-- l -->
Could you provide some input?
jhooks1 wrote: Zini,

I want to load the same mesh twice. Once in its normal form and once scaled in the negative direction. The NIFLoader works but when you try to load the mesh (mirrored) it replaces the first form.

What would be a good way to have the same mesh exist twice (in different forms) in ogre? Maybe they could have different names?


EDIT: Found a solution, just make the case of one of the letters different. Not sure if this is a good solution, but it works for now. Ogre will treat them as different mesh names.
Zini wrote: No, that is not a good idea. We can't be sure, that your modified name won't collide with another mesh. Okay, it is not a problem now (Windows case folding and such). But we should not take the risk anyway. I suggest to add a unique suffix, that contains at least one character that is normally not allowed in filenames.
jhooks1 wrote: Sweet, modified the bsa_archive.cpp and it is now working. # is used for meshes to be scaled, and we get rid of the # when loading.
jhooks1 wrote: New video with proper mesh mirroring. http://www.youtube.com/watch?v=-9gAGiDy2jI

Next thing to work on is getting the npc position updated, should fix the death animations.
raevol wrote: :D Yaaay so amazing! Great work!
Zini wrote: With the current amount of progress, would you agree that it makes sense to add NPC animation to the 0.12.0 roadmap?
jhooks1 wrote: Yes, I agree. We may even be able to implement some basic NPC AI for .12 (Idle and Wander).
Zini wrote:
We may even be able to implement some basic NPC AI for .12 (Idle and Wander).
I suggest we don't. At least not in 0.12.0. This stuff needs a proper fundament and not just some ad-hoc added features. There are also other world-model related problems with moving things and especially NPCs around. We may consider it for 0.14.0 (maybe even together with some of the more advanced AI-packages).

Edit: Nah, forgot that. Even 0.14.0 is too early for the more advanced AI-packages (unless our focus and/or progress changes drastically). But at least idle should be possible in 0.13.0 or 0.14.0.
jhooks1 wrote: Still working on getting the death animations right. I have it now so rotations to bip01 rotate the scenenode. Translations go to the bone if the npc is still in the original bounding box area, if not we move the scenenode. If we are moving back to the original bounding box area the scenenode is reset to its original orientation and position.

Right now it does not look like the way nifskope shows it.
jhooks1 wrote: Here's a video of one of my recent attempts. http://www.youtube.com/watch?v=v6i7rpP8mxM The position changing is working, but rotation is not working properly yet. I think this is going to be a tough problem to fix. I have even tried expanding the bounding boxes and it hasn't helped.

I will be unable to work on OpenMW for the next few days.

EDIT: It seems that the values I am putting in are not changing the actual entity bounding box.
jhooks1 wrote: I have two new videos of beast races. Beast races use a different animation file.

Khajiit in the Balmora Mage Guild http://www.youtube.com/watch?v=cLdlRpfIS0w

Argonian in the Ald-ruhn Mage Guild http://www.youtube.com/watch?v=vUX8HawH6MU Forgot to turn off the show bounding boxes condition on this one.

The death animations on these look pretty good. What is happening is the tail is pushing the bounding box out initially. Since the bounding box is bigger we have more room to rotate around.

I think a tactic like this could be implemented for non-beasts. I will try binding an invisible mesh to a bone, and set the offsets so it pushes the bounding box out farther.


I commented out the scenenode positioning code because it would not work correctly for all npcs.

Edit: Tails need to be pointed down more

Edit2: Trying to get into the inventory now, going to try out clothes and armor
lgro wrote:
jhooks1 wrote:I have two new videos of beast races. Beast races use a different animation file.

Khajiit in the Balmora Mage Guild http://www.youtube.com/watch?v=cLdlRpfIS0w

Argonian in the Ald-ruhn Mage Guild http://www.youtube.com/watch?v=vUX8HawH6MU Forgot to turn off the show bounding boxes condition on this one.
Wow, It looks really cool! :D
Zini wrote:
Edit2: Trying to get into the inventory now, going to try out clothes and armor
Not supported in the world model yet. I guess you can play around with it in your experimental branch, but that's it for now.

btw. really great videos
jhooks1 wrote: Animations take a big performance hit. A lot of the time openmw runs at less than 10fps. Will refactoring help with this?
Zini wrote: Unlikely. There aren't any major performance problems in the current rendering code. Any problems you got, are your own. You are running in release mode, right? If you do, then you have a rather big problem somewhere.
jhooks1 wrote: I am running in release mode. When I comment out the animation code, openmw runs very fast. The animation code is very short and simple.
Zini wrote: Which means you did something wrong somewhere that is probably simple and extremely hard to spot. I suggest you forget the problem for now and revisit it when your code has properly integrated into the new MWRender subsystem.
jhooks1 wrote: Working on clothes. I didn't notice until now that morrowind only renders amulets, belts, and rings when you drop them in the game world. They are not attached to the npc body.
jhooks1 wrote: The parts list for each piece of clothing is empty, maybe I should add code to populate the list myself.

EDIT: It may be a good idea to go ahead and make a new branch from next, and replace the scenenode npcs with skeleton npcs. When the refactoring is done the animation code could then be added.
Zini wrote: Sorry, I don't understand what you mean here. Neither your original post nor your edit.
jhooks1 wrote:
Zini wrote:Sorry, I don't understand what you mean here. Neither your original post nor your edit.
The old way of rendering npcs was through scenenodes, and it was not the correct way of doing it. I have replaced it by binding parts to a base animation skeleton.
Zini wrote: We handle these issues when the MWRender rewrite is done.
jhooks1 wrote: I fixed the part lists. Parts were not being added to the vector in loadarmo.hpp
jhooks1 wrote: Right now clothes are being drawn, but there are some parts where there are "holes" (skin is shown instead, when clothes should be covering it). I might put a screenshot of this up later.

Also certain chest pieces are causing RTTI data access violations. This causes the entire npc to not be displayed, so I have disabled chest pieces for now. This problem lies within the NIFLoader, I have to investigate this and see what is going wrong.
raevol wrote: Keep up the good work dude, this is so awesome. :) I'll be excited to see ordinators stomping around in their gear again!
jhooks1 wrote: I have been messing around in morrowind in ToddTest. I think I was wrong before, clothes/armor don't lie on top of body parts. They actually replace them, except for open helms.
sir_herrbatka wrote:
I think I was wrong before, clothes/armor don't lie on top of body parts.
Yes.
except for open helms.
Open helms replaces hair.

Sry that I didn't tell you about it before â?? i thought that you already know it.

PS
The problem is that every cloth that has to be visable on the character has to replace some part of body. So all this silly backpacks, wings etc added by mods usualy replaces neck.
Ace (SWE) wrote:
sir_herrbatka wrote:The problem is that every cloth that has to be visable on the character has to replace some part of body. So all this silly backpacks, wings etc added by mods usualy replaces neck.
Something to think about for a post-1.0 feature perhaps, clothes that don't replace?
sir_herrbatka wrote:
Something to think about for a post-1.0 feature perhaps, clothes that don't replace?
This feature would be very handy (plus ability to make your own colthing slots), but jhooks is the person to ask if it's easy to add (low hanging fruit to quote zini).
Zini wrote: Clothing that does not replace body elements sounds problematic. At least it would be a waste of rendering power. At worst (with tight clothing) we get a depths fight.

Additional clothing slots on the other hand should be relative easy, once we have a working editor and can extend the esm/p format. Probably depending a bit on what kind of slots you want
sir_herrbatka wrote:
Clothing that does not replace body elements sounds problematic.
Yup.
At least it would be a waste of rendering power.
Dunno. If I want to display quiver on a character â?? is it wasting?
At worst (with tight clothing) we get a depths fight.
I guess that this won't get any worse than in MW.

But I was just thinking about some kind of (eeeeeeeeeee?) flag that tells "I'm not replacing body part! I'm just attached to it!" that could be used by modder. I really don't know if is it possible.
Probably depending a bit on what kind of slots you want
Socks? :D This brings another issue... Layers... Maybe We could use some sort of -1 layer (displayed only if there is nothing on layer>(-1)) and mark bare body as (-666) layer. I'm not propossing solution â?? i'm just pointing the limitation of MW.
Zini wrote:
Dunno. If I want to display quiver on a character â?? is it wasting?
A quiver is hardly clothing. We will have to investigate how to handle such additions best, but I suspect a quiver would be better implemented like a weapon then like a piece of clothing.
I guess that this won't get any worse than in MW.
If you render a piece of tight clothing on top of the body model? That would be very bad. Constant flickering almost guaranteed.
This brings another issue... Layers..
Exclusive, non-slot-overlapping layers are easy. Everything else will be bloody hard.
sir_herrbatka wrote:
A quiver is hardly clothing. We will have to investigate how to handle such additions best, but I suspect a quiver would be better implemented like a weapon then like a piece of clothing.
Well... It's attached to the body â?? that's it! The same comes to backpacks cloaks etc. I'm wonder if is it possible, that's all.
If you render a piece of tight clothing on top of the body model?
Then we may flame any n00b who makes such clothing, and add "It's not a bug â?? it's a feature! You little pervert!". ;-)
Zini wrote:
Well... It's attached to the body â?? that's it! The same comes to backpacks cloaks etc. I'm wonder if is it possible, that's all.
There are two possible techniques.

1. Replace a part of the original body mesh with a clothing/armour mesh.

This is good for most types of clothing.

2. Attach a separate mesh to some point of the body.

Weapons and shields being the obvious application. But it might work for backpacks and quivers too. Maybe even for cloaks. Just because the modding community went with option #1 (because they had no choice), doesn't mean we have to do the same.
Then we may flame any n00b who makes such clothing, and add "It's not a bug â?? it's a feature! You little pervert!".
Funny! Note that tightness (i.e. the distance between skin and clothing) is relative here. If you view a NPC from a large distance, the limited precision of the z-buffer may make slightly less tight clothing classify as tight.
Really, layering surfaces in this way is something you just don't do with current rendering technologies. At best you waste GPU power and more likely you get rendering errors. And I don't even want to mention the problems you might get with animations.
heilkitty wrote:
Zini wrote:A quiver is hardly clothing. We will have to investigate how to handle such additions best, but I suspect a quiver would be better implemented like a weapon then like a piece of clothing.
Quivers are usually implemented as armor pieces in mods.
Zini wrote:
Quivers are usually implemented as armor pieces in mods.
That is exactly my point. Mods are constraint by not having access to the game engine's source code. Therefore they often have no choice but to implement a feature using a suboptimal method.
We, on the other hand, are in a completely different situation. No disrespect towards the MW modding community. They have done amazing things. But having an open source engine changes the rules completely and will make most of the modder's past implementation choices irrelevant.
sir_herrbatka wrote: Anyway: Community expects "better bikini expierience". Replacing body parts as seen in MW is not perfect since modders basicly have to create workarounds (how to replace without actualy replacing).

This is not so important but it's good to keep this in the mind.
Rhys wrote: Aren't there differences between race body shapes (not just scale) Im not sure?. If so the tight clothing(bikini) problem has basic issues from the get go anyway...
Unless the clothes mesh automatically wrap itself to the different bodies with a decent margin so as to get no zfighting. :o
Or even use the same mesh structure and merging it with the body on-load/on-equip and deleting the faces of the underlying body. ah, mm.

A flag to display the clothing item as armour/attached could be all that's needed, with recommendations to keep the distance between the body and clothing at a decent level (which if the races are different shapes, you need anyway).
jhooks1 wrote: Clothes work now, except for robes.

http://imageshack.us/f/856/clothesworking.jpg
http://imageshack.us/photo/my-images/20 ... rking2.jpg

http://imageshack.us/content_round.php? ... ad&newlp=1

Robes are going to be very hard to implement, much harder than armor. Everything is in one chest piece. Stupid Bethesda, making things complicated.
raevol wrote: jhooks1, you are a machine. So awesome.
jhooks1 wrote: I think that the way that robes work is with skin instancing, transformations from the base animation are transferred to the bones in the robe. These bones change the NiTriShape. I am not completely sure about how this works yet though.

I think if we can get tails curving and hands opening/closing, afterwards we should be able to apply the same method to get robes working (I think robes will be harder).
Rhys wrote: Wo, that's awesome :o
jhooks1 wrote: I just got a major speedup on npc animation. I was not clearing the animation lists, with each npc, so garbage was building up. Getting a solid 45fps now!!! :D :D :D

Animations look so smooth now.
swick wrote: n1
want to see that :)
jhooks1 wrote: New video http://www.youtube.com/watch?v=9TJYrsYPp4c, notice the fps counter. Unfortunately the video was captured at 10fps (only setting that will play back right in hypercam). Capturing slows down the performance too, I typically get around 35fps in Beshara with animations running on all npcs (without hypercam).

Problems:
NPCs are positioned higher than normal. This has to do with the npc positioning code, which is composed of one track of the bip01 transformations applied to standard ogre animation.

Gauntlets aren't positioned correctly. Normal body part hands are though. If I change the translation and rotation offsets for gauntlets it should fix this.

Robes issue as mentioned earlier
raevol wrote:
Incredibly awesome. :)
sir_herrbatka wrote: I'm not realy sure if the higher position of npc's is a bug. I don't have windows on my pc and MW CS does not work with wine but if I rember correctly npcs are just above the ground initially.
best regards,
Lukasz

Locked

Who is online

Users browsing this forum: No registered users and 2 guests