Jump to content

How to export mesh shape with local transform from its parent node, using BGS official fallout 4 plugin?


Recommended Posts

On 4/9/2024 at 3:38 PM, South8028 said:

Hi Chuck. Have you found a way to run gamebryo sequences for furniture? I'm trying to find a simple way. Any sequence that switches furniture into an invisible state. For example, switching uv animation to the alpha channel. Then it would be possible to replace the furniture with an animObject... The actor uses the furniture > the furniture becomes invisible > the havok annotation launches an animObject as a model of the same furniture, but animated. I wonder if it is possible to somehow trigger a furniture sequence using the havok annotation?

https://disk.yandex.ru/i/RtbZHrHogMBe2w

Here I used the sequence from extractorchair. But unfortunately, the sequence is rendered exclusively in 1st person and does not work correctly. If there is a Done tag, the sequence is not looped. If there is no tag, the sequence loops forever.

I haven't done any work on FO4 stuff for a while, but in the nif itself you can set up a NiVisController to make the mesh invisible during the sit part of the animation, and once the furniture is exited it would revert to the visible state. And I don't mean "state" as it pertains to behavior graphs or whatnot, just in general. I'd base it off the water pump furniture, or something with a similar set of NiController sequences. NiVisControllers are pretty much the easiest to use of the texture animators. They just use a NiBoolInterpolator for on and off. The interpolator has basic on/off functionality, but you can also attach a NiBoolData node to it to adjust the timing if you need to. In other words, if you simply use the NiBoolInterpolator to trigger the off state at the beginning of the Enter sequence, but it stays visible for a split second too long, or becomes invisible too soon, you attach the NiBoolData node to the interpolator and then you can input the exact time to trigger the visible/invisible state. Off the top of my head, I'm pretty sure it wouldn't even need to be scripted since the furniture BGED is what calls the different NiController sequences.  That, in combination with your AnimObject should get you the results you're looking for.

As for the 1st person vs. 3rd person issue, I know I've made furniture objects that don't lock the player into a perspective, but I'd have to root through everything I've made to see which ones they were and how I set up the animation. I know the water pump locks you into 1st person as well, but that has nothing to do with the nif, but how the furniture object is set up in the CK. If I'm not mistaken, you should be able to set up the additive subgraph with just 3rd person animations, and give the furniture object a Force 3rd Person keyword. 

One other thing to consider. I've never done what you're planning and I don't know for sure if the furniture collision would have any effect on your animation.  The NiVisController just turns off the texture...basically, but the object is still there, including the collision...I'm pretty sure. The AnimObject wouldn't have any collision that would cause issues, but the player does. If your animation moves the player beyond the boundaries of the furniture collision,  it might result in the player mesh spasming around. If that's the case, you could alternately write a short script to enable/disable the furniture during your animation. If you did that, you wouldn't need to mess around with the NiVisController and all that entails. Also, if you're using a custom mesh for your furniture, you could give it a very minimal collision that would just allow for interaction. A small box with no back or sides. That would allow you to place it and interact with it and not get in the way of the player collision during the animation. Just something else to consider.

BTW, I really like the work you've been doing. You do a great job of making new and unique things that most of us have never even thought of. Also, thanks for reaching out. I've always enjoyed our interactions.

 

EDIT: Okay...I went on that long explanation without watching your video. Jumping the gun like always. Is this what your working on or was there another object? In this case, since the animated punching bag and player are well away from the furniture punching bag, the collision wouldn't be an issue. I'd use the NiVisController for something like this.  Also, using the water pump as a jumping off point would allow for the punching animation to carry on until the player exits the furniture. The extractor chair has it's own BGED which probably triggers all the animation states in a specific manner. The water pump uses the generic furniture BGED which allows for more open ended modifications. In case you go looking for it, the water pump is in the Set Dressing file path, not the Furniture file path. There are other objects that use the generic furniture BGED as well, but I've always used the water pump as a starting point since I know how everything works with it. Well, not everything, but most things.

Edited by ChuckYufarley
  • Like 1
Link to comment
Share on other sites

1 hour ago, ChuckYufarley said:

I haven't done any work on FO4 stuff for a while, but in the nif itself you can set up a NiVisController to make the mesh invisible during the sit part of the animation, and once the furniture is exited it would revert to the visible state. And I don't mean "state" as it pertains to behavior graphs or whatnot, just in general. I'd base it off the water pump furniture, or something with a similar set of NiController sequences. NiVisControllers are pretty much the easiest to use of the texture animators. They just use a NiBoolInterpolator for on and off. The interpolator has basic on/off functionality, but you can also attach a NiBoolData node to it to adjust the timing if you need to. In other words, if you simply use the NiBoolInterpolator to trigger the off state at the beginning of the Enter sequence, but it stays visible for a split second too long, or becomes invisible too soon, you attach the NiBoolData node to the interpolator and then you can input the exact time to trigger the visible/invisible state. Off the top of my head, I'm pretty sure it wouldn't even need to be scripted since the furniture BGED is what calls the different NiController sequences.  That, in combination with your AnimObject should get you the results you're looking for.

As for the 1st person vs. 3rd person issue, I know I've made furniture objects that don't lock the player into a perspective, but I'd have to root through everything I've made to see which ones they were and how I set up the animation. I know the water pump locks you into 1st person as well, but that has nothing to do with the nif, but how the furniture object is set up in the CK. If I'm not mistaken, you should be able to set up the additive subgraph with just 3rd person animations, and give the furniture object a Force 3rd Person keyword. 

One other thing to consider. I've never done what you're planning and I don't know for sure if the furniture collision would have any effect on your animation.  The NiVisController just turns off the texture...basically, but the object is still there, including the collision...I'm pretty sure. The AnimObject wouldn't have any collision that would cause issues, but the player does. If your animation moves the player beyond the boundaries of the furniture collision,  it might result in the player mesh spasming around. If that's the case, you could alternately write a short script to enable/disable the furniture during your animation. If you did that, you wouldn't need to mess around with the NiVisController and all that entails. Also, if you're using a custom mesh for your furniture, you could give it a very minimal collision that would just allow for interaction. A small box with no back or sides. That would allow you to place it and interact with it and not get in the way of the player collision during the animation. Just something else to consider.

BTW, I really like the work you've been doing. You do a great job of making new and unique things that most of us have never even thought of. Also, thanks for reaching out. I've always enjoyed our interactions.

 

EDIT: Okay...I went on that long explanation without watching your video. Jumping the gun like always. Is this what your working on or was there another object? In this case, since the animated punching bag and player are well away from the furniture punching bag, the collision wouldn't be an issue. I'd use the NiVisController for something like this.  Also, using the water pump as a jumping off point would allow for the punching animation to carry on until the player exits the furniture. The extractor chair has it's own BGED which probably triggers all the animation states in a specific manner. The water pump uses the generic furniture BGED which allows for more open ended modifications. In case you go looking for it, the water pump is in the Set Dressing file path, not the Furniture file path. There are other objects that use the generic furniture BGED as well, but I've always used the water pump as a starting point since I know how everything works with it. Well, not everything, but most things.

I'll try niVisController. For me, working with nif is probably easier than dealing with a script. I didn't understand the explanation very well... It would be great to find nif with an example. What I need to achieve is switching the furniture to an invisible state in the Havok Entrance animation. Because using animObj is much more versatile than looking for ways to animate furniture specifically. The furniture is ordinary static, which is replaced upon Login by animObj. Collision is not an issue for havok animations. For both the actor and animObject, there are no collisions while the animation is playing. The only collision that interacts with the actor in animation is the Z axis. The actor will simply ignore the invisible object.This has been verified experimentally. Anyway... Thank you Chuck. I hope you will continue to create mods and find advanced solutions. I don't do mods. More precisely, I have a lot of models and animations, but it’s all just a bunch of models and animations that are not thematically related. I just love working in 3D, not at all professionally and solely for the sake of passing time.🙂

Link to comment
Share on other sites

5 hours ago, South8028 said:

I'll try niVisController. For me, working with nif is probably easier than dealing with a script. I didn't understand the explanation very well... It would be great to find nif with an example. What I need to achieve is switching the furniture to an invisible state in the Havok Entrance animation. Because using animObj is much more versatile than looking for ways to animate furniture specifically. The furniture is ordinary static, which is replaced upon Login by animObj. Collision is not an issue for havok animations. For both the actor and animObject, there are no collisions while the animation is playing. The only collision that interacts with the actor in animation is the Z axis. The actor will simply ignore the invisible object.This has been verified experimentally. Anyway... Thank you Chuck. I hope you will continue to create mods and find advanced solutions. I don't do mods. More precisely, I have a lot of models and animations, but it’s all just a bunch of models and animations that are not thematically related. I just love working in 3D, not at all professionally and solely for the sake of passing time.🙂

Here's a simple example I made that demonstrates how to use the NiVisController.  I assigned the NiVisController to the Couch NiNode. You can either assign it to the NiNode, or to the  BSTriShape contained in the NiNode. There are benefits to either method. Assigning it to the NiNode will turn off visibility for everything contained within it. Assigning separate NiVisControllers to each BSTriShape allows you to turn on/off visibility for each item however or whenever you want.  For this example I assigned it to the NiNode.

Within the NiControllerManager there are 4 NiControllerSequences. I named the sequences to match those used in the water pump nif. They correspond to the sequences called out by the generic furniture BGED. Each sequence has 1 controlled block, the Couch NiNode. If you expand the controlled block in the first sequence, unoccupied, you'll see 4 values filled in.  I will explain them out of order, so it makes more sense.

Under Node Name I entered the bracketed number that follows the NiNode name, in this case [2].  That is the string number for the NiNode, which can be found under the Header tab, if you expand the Strings dropdown. You have to use that number and not the block number when assigning this value.

Under Controller,  I entered the block number of the NiVisController I assigned to the Couch NiNode. I really don't know why in some instances you enter block numbers and others you enter the string number, but that's just how it works.

Under Controller Type  I clicked on the "Txt" icon and entered the text "NiVisController". Doing this creates a string that informs the NiControllerManager what sort of functionality to assign to the controlled block. In some cases the "NiVisController" string might already be in place, in which case you just need to double click on the blank space next to the "Txt" icon and enter the string number, in this case 3. Since there are 4 sequences and each has the same controlled block, once I created the "NiVisController" string for the first sequence, I just needed to enter the string number for the remaining  sequences.

Finally, under Interpolator, I entered the Block number of the unique NiBoolInterpolator I created for the "unoccupied" sequence. If you expand the "unoccupied" sequence and select the number 6 NiBoolInterpolator, you'll see that the value given to it is "yes" and there is no data block attached. In the case of a NiBoolInterpolator, yes means visible, no means invisible. In the case of your punching bag, you want the furniture nif visible when it's not in use, so the "unoccupied" sequence gets a yes NiBoolInterpolator.

For the remaining NiControllerSequences, the only differences contained in the controlled block values are that each has it's own unique NiBoolInterpolator. In the "occupied" sequence, since this is when your animation will be playing and you want the furniture nif to be invisible, I assigned a NiBoolInterpolator with a value of no, and no data node attached. 

For the "enter" and "exit" sequences, in order to demonstrate how they work, I attached NiBoolData nodes to each of the remaining NiBoolInterpolators. First, I set the stop time for each sequence to 2 seconds. For the "enter" sequence I gave the NiBoolData node 4 keys that contain time stamps and on/off values. The values are simple. 1 is on, 0 is off. Since this is a simple demonstration I only need 4 keys to transition the visibility from on to off once during the sequence. In the case of a flashing sign I might set 10, 20, 30 different keys to transition back and forth over the length of the sequence. The time stamp for the first key is always 0.0. That is to indicate what value (1 or 0) to assign at the beginning of the sequence. The next time stamp is the last instant the on (1) value will be assigned. The next time stamp is the first instant the off (0) value is to be assigned. and finally, the last time stamp is that last instant the off value will be assigned. So, over the course of the 2 second sequence, the nif remains visible for the first second, then becomes invisible, and remains invisible for the rest of the sequence. Once that NiBoolData block is complete, I enter it's block number in the data field of the number 14 NiBoolInterpolator. 

For the "exit" sequence, I just copy/paste the previous NiBoolInterpolator, expand the NiBoolData keys and transpose the values, changing the 1s to 0s, and the 0s to 1s. Now the sequence starts in the off state and ends in the on state. 

If you open the nif in the Creation Kit preview window,  click each of the Gamebryo Anims in this order...unoccupied, enter, occupied,  exit and it will cycle the on/off states in the order the generic furniture BGED will play them when the furniture is interacted with.

I hope this helps and you were able to follow my over explaining.

FurnitureExample.nif

  • Thanks 2
Link to comment
Share on other sites

4 hours ago, ChuckYufarley said:

Here's a simple example I made that demonstrates how to use the NiVisController.  I assigned the NiVisController to the Couch NiNode. You can either assign it to the NiNode, or to the  BSTriShape contained in the NiNode. There are benefits to either method. Assigning it to the NiNode will turn off visibility for everything contained within it. Assigning separate NiVisControllers to each BSTriShape allows you to turn on/off visibility for each item however or whenever you want.  For this example I assigned it to the NiNode.

Within the NiControllerManager there are 4 NiControllerSequences. I named the sequences to match those used in the water pump nif. They correspond to the sequences called out by the generic furniture BGED. Each sequence has 1 controlled block, the Couch NiNode. If you expand the controlled block in the first sequence, unoccupied, you'll see 4 values filled in.  I will explain them out of order, so it makes more sense.

Under Node Name I entered the bracketed number that follows the NiNode name, in this case [2].  That is the string number for the NiNode, which can be found under the Header tab, if you expand the Strings dropdown. You have to use that number and not the block number when assigning this value.

Under Controller,  I entered the block number of the NiVisController I assigned to the Couch NiNode. I really don't know why in some instances you enter block numbers and others you enter the string number, but that's just how it works.

Under Controller Type  I clicked on the "Txt" icon and entered the text "NiVisController". Doing this creates a string that informs the NiControllerManager what sort of functionality to assign to the controlled block. In some cases the "NiVisController" string might already be in place, in which case you just need to double click on the blank space next to the "Txt" icon and enter the string number, in this case 3. Since there are 4 sequences and each has the same controlled block, once I created the "NiVisController" string for the first sequence, I just needed to enter the string number for the remaining  sequences.

Finally, under Interpolator, I entered the Block number of the unique NiBoolInterpolator I created for the "unoccupied" sequence. If you expand the "unoccupied" sequence and select the number 6 NiBoolInterpolator, you'll see that the value given to it is "yes" and there is no data block attached. In the case of a NiBoolInterpolator, yes means visible, no means invisible. In the case of your punching bag, you want the furniture nif visible when it's not in use, so the "unoccupied" sequence gets a yes NiBoolInterpolator.

For the remaining NiControllerSequences, the only differences contained in the controlled block values are that each has it's own unique NiBoolInterpolator. In the "occupied" sequence, since this is when your animation will be playing and you want the furniture nif to be invisible, I assigned a NiBoolInterpolator with a value of no, and no data node attached. 

For the "enter" and "exit" sequences, in order to demonstrate how they work, I attached NiBoolData nodes to each of the remaining NiBoolInterpolators. First, I set the stop time for each sequence to 2 seconds. For the "enter" sequence I gave the NiBoolData node 4 keys that contain time stamps and on/off values. The values are simple. 1 is on, 0 is off. Since this is a simple demonstration I only need 4 keys to transition the visibility from on to off once during the sequence. In the case of a flashing sign I might set 10, 20, 30 different keys to transition back and forth over the length of the sequence. The time stamp for the first key is always 0.0. That is to indicate what value (1 or 0) to assign at the beginning of the sequence. The next time stamp is the last instant the on (1) value will be assigned. The next time stamp is the first instant the off (0) value is to be assigned. and finally, the last time stamp is that last instant the off value will be assigned. So, over the course of the 2 second sequence, the nif remains visible for the first second, then becomes invisible, and remains invisible for the rest of the sequence. Once that NiBoolData block is complete, I enter it's block number in the data field of the number 14 NiBoolInterpolator. 

For the "exit" sequence, I just copy/paste the previous NiBoolInterpolator, expand the NiBoolData keys and transpose the values, changing the 1s to 0s, and the 0s to 1s. Now the sequence starts in the off state and ends in the on state. 

If you open the nif in the Creation Kit preview window,  click each of the Gamebryo Anims in this order...unoccupied, enter, occupied,  exit and it will cycle the on/off states in the order the generic furniture BGED will play them when the furniture is interacted with.

I hope this helps and you were able to follow my over explaining.

FurnitureExample.nif 36.57 kB · 0 downloads

Thank you so much, Chuck. Excellent explanation. This is a complete manual, I am sure that I can do everything according to such a detailed lesson. I am very glad for your participation. I remember seeing your jukebox mod for the first time a long time ago. I was amazed at the complexity of your work. You are one of those people who made me want to master 3D in fo4 and you continue to be an example for me.

Link to comment
Share on other sites

12 hours ago, South8028 said:

Thank you so much, Chuck. Excellent explanation. This is a complete manual, I am sure that I can do everything according to such a detailed lesson. I am very glad for your participation. I remember seeing your jukebox mod for the first time a long time ago. I was amazed at the complexity of your work. You are one of those people who made me want to master 3D in fo4 and you continue to be an example for me.

You're very welcome.  I have a feeling you'll make a bunch of great new stuff using this technique. Thank you so much for the high praise. It really made my day. 

There's just a couple more things I realized I left out, however. When creating the NiVisController and assigning it to an object, there are a couple of steps that makes the controller usable within an animation sequence. First of all, in order to bypass the steps I'm about to explain, all you really need to do is copy a NiVisController from another nif and paste it into your nif. If you paste it directly into the object you want to assign it to all the necessary links will automatically be created, so this is by far the easiest way to do it. If you have several NiNodes or BSTriShapes you want to assign a NiVisController to, just copy it once and paste it into each object, one by one. This creates unique controllers for each object.

Sometimes it's necessary to create the NiVisController from scratch, though. To do this, right click the 0 NiNode and select Block > Insert > NiVisController. The controller will be added to the bottom of the block list, but since it's not assigned yet, it is not added to the block hierarchy. If you collapse the 0 NiNode, you'll see that the new controller is still listed at the bottom, as a loose block. Select the NiVisController and under the Flags heading, change the value to 108. This value indicates that the controller will be utilized within the NiControllerManager. The original value of 76 indicates that it will be utilized directly on the object, for creating an animation that will play constantly, with no need for animation sequences. For now, you don't need to change any of the other values. 

Now, you need to create and assign an interpolator to the NVisController. In this instance, since the controller will be utilized within the NiControllerManager, you create a NiBlendBoolInterpolator. Right click the 0 NiNode and select Block > Insert > NiBlendBoolInterpolator. Basically, any interpolator containing the word "Blend" indicates that the controller can switch between any number of unique interpolators assigned in the NiContollerSequences.  Select the NiBlendBoolInterpolator. In the Flags heading, double click the 0 value. That will open a dropdown list with 2 choices. Select Manager Controlled. I've never used the other value, so I don't know how it works. Under the Array Size heading change the 0 value to 2.

Now, go back and select the NiVisController. Under the Interpolator heading, double click the "None" value and enter  the block number of the NiBlendBoolInterpolator. Now the NiVisCOntroller is ready to be assigned to an object. Aside from NiNodes and BSTriShapes, it can be assigned to other types of blocks as well. Off the top of my head, I only know for sure that I've assigned a NiVisCOntroller to a BSValueNode as well.  In the case of a BSValueNode, it must be assigned it's own NiVisController. If you have a NiNode containing a BSValueNode, and assign the NiVisController to the NiNode, it will not affect the BSValueNode. Don't know why this is, it just is. I've also used the NiVisController on elements contained within a NiParticleSystem, but can't recall which at the moment.

The easy way to assign the controller you just created it is to copy/paste it the same way you would when copying one from another nif. This creates a new instance of the NiVisController in the controlled object's hierarchy and the original will remain as a loose block at the bottom of the Block List. The original can be deleted. The hard way isn't all that hard. it just takes a couple of steps. Select the object you're assigning it to. Under the Controller heading, enter the block number of the NiVisController. It will become nested in the object's hierarchy, but still requires one more step. Expand the block you've assigned the controller to. Select the NiVisController and under the Target heading, enter the block number of the controlled object. 

The other thing I thought you might find useful is when assigning NiBoolInterpolators in the animation sequences, you can use the same one within any number of sequences. Say for instance you create a nif with 8 animation sequences and 4 of them are just going to need an off interpolator. Rather than creating 4 unique off interpolators, you only need to create 1 and assign it in each of the 4 sequences. I've noticed that vanilla nifs do use unique interpolators in this type of situation. I don't know why Bethesda did that as it isn't necessary.

If you run into anything else that needs explaining, feel free to contact me.

  • Like 1
Link to comment
Share on other sites

Hi guys, if you are using 3DS Max, controlling visibility is much simpler.

Here's how :

1) select the object you want to animate the visibility of.

2) Open Dope Sheet (Graph Editors -> Dope Sheet).

3) Select the object in the dope sheet, and from "Edit" menu, select Visibility Track -> Add.  This creates a visibility track.

4) Add keys to the track.  Value 1.0 = visible, 0 = invisible.

That's it.  The exporter picks it right up and creates the necessary Controllers for the Nif automatically.

One issue while you do this is, though, once you assign the BS Lighting FX, you can't preview the visibility animation in 3DS (it will work after the export, but no preview).  You need to use the 3DS' default materials while you create keys.

 

Controlling visibility of Havok anim can be done via annotations : CullBone.**bonename** (make the bone invisible), UncullBone.**bonename** (make the bone visible)

  • Thanks 1
Link to comment
Share on other sites

1 hour ago, DiodeLadder said:

Hi guys, if you are using 3DS Max, controlling visibility is much simpler.

Here's how :

1) select the object you want to animate the visibility of.

2) Open Dope Sheet (Graph Editors -> Dope Sheet).

3) Select the object in the dope sheet, and from "Edit" menu, select Visibility Track -> Add.  This creates a visibility track.

4) Add keys to the track.  Value 1.0 = visible, 0 = invisible.

That's it.  The exporter picks it right up and creates the necessary Controllers for the Nif automatically.

One issue while you do this is, though, once you assign the BS Lighting FX, you can't preview the visibility animation in 3DS (it will work after the export, but no preview).  You need to use the 3DS' default materials while you create keys.

 

Controlling visibility of Havok anim can be done via annotations : CullBone.**bonename** (make the bone invisible), UncullBone.**bonename** (make the bone visible)

Wow! Great information. Don't have a list of annotations with explanations? I know a limited number of annotations... These are SoundPlay, FaceEmotion, AnimObjLoad/Draw. But I know that there are a lot of annotations in havok. I have a list of several dozen annotations, but I don't know how to use them all.

https://disk.yandex.ru/d/th8tI0jnFwF6-g

Edited by South8028
Link to comment
Share on other sites

Honestly, the only annotations I know so far are the ones used in gun animations, and those are not many.  The CullBone/UncullBone are used in the Lever Action Rifle reload (to hide/show cartridges), and NPC reloads (they hide the entire mag).

I've looked at your list, but yeah, without the contexts, it's hard to know how to use them  I think the only way to learn these is via exporting XML files from the particular animations you are interested in.

  • Thanks 1
Link to comment
Share on other sites

On 4/12/2024 at 11:44 PM, DiodeLadder said:

Honestly, the only annotations I know so far are the ones used in gun animations, and those are not many.  The CullBone/UncullBone are used in the Lever Action Rifle reload (to hide/show cartridges), and NPC reloads (they hide the entire mag).

I've looked at your list, but yeah, without the contexts, it's hard to know how to use them  I think the only way to learn these is via exporting XML files from the particular animations you are interested in.

Unfortunately, cullBone does not work with animObject. Abstract "CullBone. name of the bone"? Did I understand correctly?

Link to comment
Share on other sites

Yeah, CullBone.bone name is it in the context of gun animations (for example, "CullBone.WeaponMagazine").  I suppose how the engine handles weapons is different from AnimObjects?

I think many of these annotations are context sensitive.  Sorry about wasting your time.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...