Skinning Bone matrix with 4x3 instead of 4x4

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

O.K. I thought perhaps normals "do" get updated and they just "look static" in debug view,
so I changed the colour output in the HLSL shader to reflect the normals in "range compressed" form..
i.e.

Code: Select all

 
   OUT.Color.x = (Normal.x / 2.0) + 0.5;
   OUT.Color.y = (Normal.y / 2.0) + 0.5;
   OUT.Color.z = (Normal.z / 2.0) + 0.5;
 
I had a good look at the vertex colours to see if they change during the animation, and guess what,
they dont..

So I'm convinced that as cool as hardware skinning could be, it just wont work for me..
(I am rather disappointed)

Perhaps later versions of DX could solve the issue (as Mel wisely stated) .

Here is a shot of the normals as generated in the shader:
Image
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

Hey! Hardware Skinning is a cool concept so please keep at it The_Glitch because if you get further than me, I'll definitely be watching closely!
Cheers!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

Oh! how do I see how the 4 x 4 / 4 x 3 matrix is structured in terms of scale translation and position?
If you use only the rotation (most common) and get rid of everything else, then maybe you could save a lot of space..
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by The_Glitch »

I know if you use float4x3 instead of float4x4 you can increase the bone count a lot. I have some characters that are pretty good but the bone count is from 58 to 89 bones so I'm not sure how to use them with Irrlicht if even at all possible as If I let Irrlicht animate the character with 89 bones the game lags bad drops from 60fps to 40fps with this one character.

I've looked into using the direct3d11 driver with irrlicht in hopes to use a better skinning shader but irrlicht just crashes I'm not to sure if the hardware skinning example supports direct3d11 yet sadly to say. :(

Right now my main project hardware skinning is fine as my characters only have maybe 30 something bones so it works fine.

Vectrotek can you update your code snippet for updating tangents and binormals for shader pipeline it would save me a lot of time bud.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

The_Glitch.. I'm ashamed to say that I don't know how to even start working with "Shader Pipeline".. :oops:
I'm still figuring it out.. Why don't you just post them to where-ever and let someone else do it for now?
It's simple code..
Sorry Pal! Where do I read up on these things?
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Mel »

Vectrotek wrote:If what Mel stated is correct, which it certainly seems, then I have a filthy suspicion that we've just witnessed the death of DX9 in terms of hardware skinning.. Sorry chaps!
I cannot see the all important normals surviving this either.
Cheers!
Not necesarily. Think that the bonecount limitation is PER MESBUFFER. You can create a model with several meshbuffers, and each of them may have a bone subset of a whole hierarchy, it means more drawcalls, but it is not so limiting really.

Also: read this: http://http.developer.nvidia.com/GPUGem ... _ch04.html and take special attention to the Accumulated Matrix Skinning section, i think it says something very interesting regarding the skinning. If you know how to create the correct lighting for a static normal mapped model, you should be able to do the same with a skinned model, The only diference is that normals/tangents/b-vectors WON'T DO TRANSLATIONS, you only need to apply rotations on them, and that is achieved by nullifying the last column of the 4x3 matrix, setting it to 0. Other than that, everything works the same.
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by The_Glitch »

@Vectrotek It's alright bud I'll fix it up when I get a chance shader pipeline is just like the default irrlicht version it just has some differences but it's easy to use I enjoy it.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

Thanks, The Glitch! Posting this right now. Check it out....

@Mel.. I stand corrected yet again dear sir!
Yes, I see that there is hope after-all based on what you say about the limitation
being "Mesh Buffer" specific..
This would be very good if one could somehow combine, say, the Head, Arms and Torso of a character
with the Hips and Legs but as separate mesh buffers..
Now, does this mean that I would have to treat them as "completely separate objects" then
somehow manage their positions etc as a single unit? or..

I did notice that with debug render enumeration "EDS_BBOX_BUFFERS" the boxes seem to be related
to the "amount of Materials" in the model. (see the screengrab)..

How can I be sure that these boxes actually refer to different "Mesh Buffers"?

I think I'll do a test. I found a cool little program titled "24. Hardware Skinning" which
is an example of Hardware skinning. I'm sure You and The_Glitch has also looked at it.

O.K. The first thing I noticed is that the GLSL part dont work so I fixed that
and made a few changes to the GLSL and HLSL shaders to only deal with the important stuff..
(see in the code (OnSetConstants) the shader's 'Array' vs 'Array[0]' trick)
I wish Nadro wasn't so quiet, but I see he's fixing Bugs.

I also took "main.cpp", "HardwareSkinCallback.h" and "main.cpp" and combined them all into
a Single "Main.cpp" file (easier to work with in my editor).
Then I added a routine that shifts the Debug Rendermode with keys "Q" and "E".

Now I'll try to break this model up into even more pieces / materials (easly done in Blender) and see
if that helps because more buffers would mean less vertices per buffer.. (our solution?)
In the mean time however, I'll post this project (quite small) and you guys could have a look at it aswell..
It includes my standard Irrlicht 1.8.2 DLL so anyone can see it work for HLSL and GLSL.
It still has the same options in the console at the start of the app.

Here is a screenshot (in GLSL as the mess in HLSL obstructs the view):
Image
The model was "decimated" to make it smaller so it looks a bit rough..


The rest of what you said sounds inspiring and the "Dawn" material in GPU Gems is pretty usefull.
(I actually read it a long time ago)
Do you think that if I increased the buffer count there would be improvement?
(feeding the normals to the shader under H/W Skining is another matter which I hope to call you on)

Here is the project as it is now: (very small, 1.4 Meg )
http://s000.tinyupload.com/?file_id=538 ... 6137936416

New features include controllable camera etc..
If you play around long enough with the different debug modes and
starting options you'll notice that there are a whole lot of questions to be answered..


When I use more Materials and thus more Buffers (which should be soon) then I'll post that aswell.
Hold thumbs. I hope it works!
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

THIS IS THE CRAP YOU SOMETIMES GET FROM TINY PIC!
This definitely is NOT the image I posted.
I will leave it here as testament to
"TinyPics" professionalism.. "Horse S#|t!"
Image
Last edited by Vectrotek on Sun May 22, 2016 4:32 pm, edited 1 time in total.
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

More questions like "What happens to Bounding Box culling?".
Also important is that Normals must make it to the Vertex Program
and after "World Matrix Mult" must end up in the Fragment Shader.
(for me atleast)
Image

I Love 3D engines!
The_Glitch
Competition winner
Posts: 523
Joined: Tue Jan 15, 2013 6:36 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by The_Glitch »

I had looked into breaking down characters into mesh buffers in the past as I've been skinning and rigging meshes in 3ds max since 2008. It's not all ways so simple. You would have to have a way to combine the meshes in irrlicht which I've tried in the past but ran into a lot of issues. I broke down one character and had it working great in 3ds max but when loaded into Irrlicht the character was destroyed as I believe the .X format handles animations and parent and child nodes or bones in a certain way which made it problmatic
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

Sadly..

Image

It took some doing to get a model with TWO Images and FOUR Materials / Buffers into Irrlicht!
(at least I learned how to do it with *.x and *.b3d)

Is Mesh Buffer Box culling possible?
Mel
Competition winner
Posts: 2292
Joined: Wed May 07, 2008 11:40 am
Location: Granada, Spain

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Mel »

The_Glitch wrote:I had looked into breaking down characters into mesh buffers in the past as I've been skinning and rigging meshes in 3ds max since 2008. It's not all ways so simple. You would have to have a way to combine the meshes in irrlicht which I've tried in the past but ran into a lot of issues. I broke down one character and had it working great in 3ds max but when loaded into Irrlicht the character was destroyed as I believe the .X format handles animations and parent and child nodes or bones in a certain way which made it problmatic
It is somewhat tricky indeed, the problem is that to the meshbuffers, the bone indices must appear consecutive, i.e. meshbuffer1 must use bones 1,2,3,5 out of 10 and those must index like 0,1,2,3 But it is a problem that has already been solved, because in the past, the hardware skinning had even more limitations, the matrix paletted skinning could store 16 joint matrices at most. If i remember correctly, the ASSIMP library split the skinned meshes into smaller meshes so each submesh didn't exceed a certain bone count.

http://assimp.sourceforge.net/main_features_pp.html

With regard to the normals, also, there was a setting on the skinned meshes that enabled and disabled explicitly the normals recalculation, maybe you have disabled those?
"There is nothing truly useless, it always serves as a bad example". Arthur A. Schmitt
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

This is all I can say about hardware skinning:
(I even tried explicitly updating the normals)

Code: Select all

 
 
 //   002_MAIN_CPP  
 
 // I dont know who wrote the original code, but I made some changes
 // and made GLSL also work.
 // All three the original files were also combined into this single file..
 
 #include <irrlicht.h>
 #include <iostream>
 
 #pragma comment(lib,"irrlicht.lib") 
 
 using namespace irr;
 using namespace scene;
 using namespace video;
 using namespace io;
 using namespace core;
 
 class HWSkinCB : public video::IShaderConstantSetCallBack
  {private:
   IrrlichtDevice *device;
   ISkinnedMesh* mesh;
   void copyMat(f32* pointer, matrix4 &mat);
   u32 oldtimer;
   u32 delay;
   bool lightsenabled;
   public:
   HWSkinCB();
  ~HWSkinCB();
   static HWSkinCB* getInstance();
   void setupNode(IrrlichtDevice* device, IAnimatedMeshSceneNode* node, u32 refresh);
   virtual void OnSetConstants(video::IMaterialRendererServices* services, s32 userData);
  };
 
 HWSkinCB::HWSkinCB() {delay = 0;} // (17 ms = appr 1/60th of a second = 60 FPS)    
                                   // I didn't quite get this..
 HWSkinCB::~HWSkinCB() {this->drop();}
 //-------------------- ---- --- -- -
 HWSkinCB* HWSkinCB::getInstance()
  {static HWSkinCB* instance = 0;
   if (!instance) instance = new HWSkinCB();
   return instance;
  }
 void HWSkinCB::setupNode(IrrlichtDevice *device, IAnimatedMeshSceneNode* node, u32 refresh)
  {if (refresh) delay = refresh;
   bool result = node->getMaterial(0).getFlag(video::EMF_LIGHTING); 
   if (result == false) lightsenabled = false;
   else lightsenabled = true;
   this->device = device;
   this->mesh = (ISkinnedMesh*)node->getMesh();
   //   this->mesh->setHardwareMappingHint(EHM_STREAM);
                                      // Just for interest's sake..
                                      // EHM_NEVER    Don't store on the hardware. 
                                      // EHM_STATIC   Rarely changed, usually stored completely on the hardware. 
                                      // EHM_DYNAMIC  Sometimes changed, driver optimized placement. 
                                      // EHM_STREAM   Always changed, cache optimizing on the GPU. 
 
 
   this->mesh->setHardwareMappingHint(EHM_DYNAMIC, EBT_VERTEX_AND_INDEX); // Didn't really help..
   // Enumerator: 
   // EBT_NONE  Does not change anything. 
   // EBT_VERTEX  Change the vertex mapping. 
   // EBT_INDEX  Change the index mapping. 
   // EBT_VERTEX_AND_INDEX  Change both vertex and index mapping to the same value. 
   //-------------------- ---- --- -- -
   ISceneManager* smgr = device->getSceneManager();
   IVideoDriver* driver = device->getVideoDriver();
 
   // for(u32 BufferIndex = 0; BufferIndex < this->mesh->getMeshBuffers().size(); ++BufferIndex)
   for(u32 BufferIndex = 0; BufferIndex < this->mesh->getMeshBuffers().size(); BufferIndex++) 
    {for(u32 g = 0; g < this->mesh->getMeshBuffers()[BufferIndex]->getVertexCount(); g++)
      {this->mesh->getMeshBuffers()[BufferIndex]->getVertex(g)->Color = SColor(0,0,0,0);
      }
    }
   for(u32 JointIndex = 0; JointIndex < this->mesh->getJointCount(); JointIndex++)
    {for(u32 WeightIndex = 0; WeightIndex < this->mesh->getAllJoints()[JointIndex]->Weights.size(); WeightIndex++)
      {int buffId = this->mesh->getAllJoints()[JointIndex]->Weights[WeightIndex].buffer_id;   // how is this assigned?
       int vertexId = this->mesh->getAllJoints()[JointIndex]->Weights[WeightIndex].vertex_id;
       SColor* vColor = &this->mesh->getMeshBuffers()[buffId]->getVertex(vertexId)->Color;
       if(vColor->getRed() == 0) vColor->setRed(JointIndex + 1);
       else if(vColor->getGreen() == 0) vColor->setGreen(JointIndex + 1);
       else if(vColor->getBlue() == 0)  vColor->setBlue(JointIndex + 1);
       else if(vColor->getAlpha() == 0) vColor->setAlpha(JointIndex + 1);
      }
    }
   printf("Joint Num: %d, current limit is 55 joints.\n", mesh->getJointCount()); // What sort of difference did this make?
   // Applying the shader..
   IGPUProgrammingServices* gpu = driver->getGPUProgrammingServices();
   int HWSkinMat = EMT_SOLID;
   if(driver->getDriverType() == EDT_OPENGL && !lightsenabled)
    {HWSkinMat = gpu->addHighLevelShaderMaterialFromFiles   ("HWSkinV.glsl","main",EVST_VS_2_0,"","",EPST_PS_2_0,this);
    }
   if(driver->getDriverType() == EDT_OPENGL && lightsenabled)
    {HWSkinMat = gpu->addHighLevelShaderMaterialFromFiles ("HWSkinV_lights.glsl","main",EVST_VS_2_0,"","",EPST_PS_2_0,this);
    }
   if(driver->getDriverType() != EDT_OPENGL)
    {HWSkinMat = gpu->addHighLevelShaderMaterialFromFiles   ("HWSkin.hlsl","vertexMain",EVST_VS_2_0,"","",EPST_PS_2_0,this);
    }
   node->setMaterialType((E_MATERIAL_TYPE)HWSkinMat);
   mesh->setHardwareSkinning(true); // Now...
  }
 // ------------------------------------------------- ---- --- -- -
 // CopyMatrix..
 void HWSkinCB::copyMat(f32* pointer, matrix4 &mat)
  {for(int MatrixIndex = 0; MatrixIndex < 16; MatrixIndex++) *pointer++ = mat[MatrixIndex];
  }
 // ------------------------------------------------- ---- --- -- -
 //                                                                                                                                                
 
 void HWSkinCB::OnSetConstants(video::IMaterialRendererServices* services, s32 userData)
  {if(services->getVideoDriver()->getDriverType() == EDT_DIRECT3D9)
    {core::matrix4 worldViewProj;
     worldViewProj = services->getVideoDriver()->getTransform(video::ETS_PROJECTION);
     worldViewProj *= services->getVideoDriver()->getTransform(video::ETS_VIEW);
     worldViewProj *= services->getVideoDriver()->getTransform(video::ETS_WORLD);
     core::matrix4 world;
     world = services->getVideoDriver()->getTransform(video::ETS_WORLD)[0];
     services->setVertexShaderConstant("mWorldViewProj", &worldViewProj[0], 16);
     // COMPLETELY DISABLED LIGHTS IN GLS AS I DO THEM IN FRAGMENT SHADER..
    }
   u32 timer = device->getTimer()->getRealTime();
   if (timer - oldtimer >= delay)
    {oldtimer = timer;
     if (mesh)
      {f32* JointArray = new f32[(mesh->getJointCount() + 1) * 16];  // DONT NEW AND DELETE IN A LOOP!!!
       int copyIncrement = 0;
       for(u32 JointIndex = 0; JointIndex < this->mesh->getJointCount(); JointIndex++)
        {core::matrix4 JointVertexPull(core::matrix4::EM4CONST_NOTHING);
         // Set this matrix to be the product of two matrices.. i.e. Multiply by another matrix.. Calculate b*a??
         // Definition at line 688 of file matrix4.h.
         JointVertexPull.setbyproduct(mesh->getAllJoints()[JointIndex]->GlobalAnimatedMatrix, 
                                      mesh->getAllJoints()[JointIndex]->GlobalInversedMatrix);
         copyMat(JointArray + copyIncrement, JointVertexPull);
         copyIncrement += 16;               
        } // Is The Glitch's question related to this?
         // IMPORTANT "ARRAY ACCESS" DIFFERENCE BETWEEN GLSL AND HLSL!!
        if(services->getVideoDriver()->getDriverType() == EDT_DIRECT3D9)
         {bool success = services->setVertexShaderConstant("JointTransform", JointArray, mesh->getJointCount() * 16);
         }
        // Using this secret "[0]" works for GLSL and we HAVE NO FRAMERATE DROP!! (when no lights active)
        if(services->getVideoDriver()->getDriverType() == EDT_OPENGL)
         {bool success = services->setVertexShaderConstant("JointTransform[0]", JointArray, mesh->getJointCount() * 16);
         }
        delete(JointArray);
       }
     }
   }
 // Yey for globals... (thats for sure!)=/
 IrrlichtDevice*          device = 0;
 IrrlichtDevice*          TheIRRNullDevice = 0;
 IAnimatedMeshSceneNode*  dwarf;  // here now because it is refered to in the event receiver..
 ISkinnedMesh*            mesh;
 core::dimension2d<u32>   TheDeskResolution;
 int                      DebugRendMode;
 float                    CameraFov;
 f32                      CurrentAnimSpeed; // Couldnt get this one right..
 scene::ICameraSceneNode* TheCamera; 
 
 
// core::matrix4                   M01World;              // For use (un-altered) in the Vertex Program for fixing Raw Vertex Normals..
 
 
 
 class MyEventReceiver : public IEventReceiver
  {public:
   MyEventReceiver() 
    {for (u32 i = 0; i < KEY_KEY_CODES_COUNT; ++i) KeyIsDown[i] = false;
    }
   virtual bool OnEvent(const SEvent& CurrEvent) 
   // AUTOMATICALLY BECAUSE WE DID.. TheDevice = createDevice(video::EDT_DIRECT3D9,TheDeskResolution, 32,x,x, x, &TheReceiver);"..
    {if(CurrEvent.EventType == irr::EET_KEY_INPUT_EVENT)
      {KeyIsDown[CurrEvent.KeyInput.Key] = CurrEvent.KeyInput.PressedDown; 
       if(!CurrEvent.KeyInput.PressedDown)
        {switch(CurrEvent.KeyInput.Key) 
          {case irr::KEY_KEY_E: DebugRendMode ++; break;
           case irr::KEY_KEY_Q: DebugRendMode --; break;
           case irr::KEY_KEY_O: CameraFov *= 1.1;
           TheCamera->setFOV(CameraFov * 0.017453 );
           break;
           case irr::KEY_KEY_P:  CameraFov *= (1.0 / 1.1);
           TheCamera->setFOV(CameraFov * 0.017453 );
           break;
           case irr::KEY_KEY_T: 
           CurrentAnimSpeed *= 2.0;
           mesh->setAnimationSpeed (CurrentAnimSpeed) ;
           break;
           case irr::KEY_KEY_Y: 
           CurrentAnimSpeed *= (1.0 / 2.0);
           mesh->setAnimationSpeed (CurrentAnimSpeed) ;
           break;
          }
        }
      }
     return false;
    }
   virtual bool IsKeyDown(EKEY_CODE keyCode) const {return KeyIsDown[keyCode];}
   private:
   bool KeyIsDown[KEY_KEY_CODES_COUNT];
  };
 
 // ==================================================== ===== ==== === == = 
 
 int main()
  {char i = 0; char j = 0; char k = 0;
   printf("Dx or Ogl?\n1.Dx\n2.Ogl\n");
   std::cin >> i;
   // Why was this removed, yet kept to be seen?
   //printf("Use ATI Technique?\n1.Yes\n2.No\n");
   //std::cin >> use_ati;
   printf("Activate the hardware skinning?\n1.Yes\n2.No\n3.Disable skinning\n");
   std::cin >> j;
   printf("Enable Lighting?\n1.Yes\n2.No\n");
   std::cin >> k;
 
   TheIRRNullDevice    = createDevice(video::EDT_NULL);    // Null Device for us to get our windows resolution..
   TheDeskResolution   = TheIRRNullDevice->getVideoModeList()->getDesktopResolution();    // As set by you in windows setup..
   TheIRRNullDevice->drop();  // We got the desktop resolution, so drop the Null Device..
   MyEventReceiver TheReceiver; // This receiver is the one assigned in the CREATE DEVICE function..
 
   if(i == '1') device = createDevice(EDT_DIRECT3D9, TheDeskResolution, 32, false, false, false, &TheReceiver);
   else device = createDevice(EDT_OPENGL, TheDeskResolution, 32, false, false, false, &TheReceiver);  
   ISceneManager* smgr = device->getSceneManager();
   IVideoDriver* driver = device->getVideoDriver();
 
   DebugRendMode = 0; 
   CurrentAnimSpeed = 20.0;
 
   // CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA 
   SKeyMap keyMap[8];
   keyMap[0].Action  = EKA_MOVE_FORWARD;  keyMap[0].KeyCode = KEY_UP;   // Arrow keys and "WASD"..
   keyMap[1].Action  = EKA_MOVE_FORWARD;  keyMap[1].KeyCode = KEY_KEY_W;
   keyMap[2].Action  = EKA_MOVE_BACKWARD; keyMap[2].KeyCode = KEY_DOWN;
   keyMap[3].Action  = EKA_MOVE_BACKWARD; keyMap[3].KeyCode = KEY_KEY_S;
   keyMap[4].Action  = EKA_STRAFE_LEFT;   keyMap[4].KeyCode = KEY_LEFT;
   keyMap[5].Action  = EKA_STRAFE_LEFT;   keyMap[5].KeyCode = KEY_KEY_A;
   keyMap[6].Action  = EKA_STRAFE_RIGHT;  keyMap[6].KeyCode = KEY_RIGHT;
   keyMap[7].Action  = EKA_STRAFE_RIGHT;  keyMap[7].KeyCode = KEY_KEY_D;
   TheCamera = smgr->addCameraSceneNodeFPS(0, 200, 0.0800, -1, keyMap, 8);  
   TheCamera->setPosition(core::vector3df(0.0,0.0,100.0));
   TheCamera->setTarget(core::vector3df(0.0, 0.0, 0.0)); // This changes unseen when a FPS camera is mouse-aimed and moved around..
   CameraFov = 80.0;
   TheCamera->setFOV(CameraFov * 0.017453 ); 
   // CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA  CAMERA 
   dwarf = smgr->addAnimatedMeshSceneNode(smgr->getMesh("X_009_ULTRA_LOWRES_FRAGFIX.x"));
   // I could write a lot about preparing models for Irrlicht..
 
   mesh = (ISkinnedMesh*)dwarf->getMesh();
 
   dwarf->setScale(vector3df( 9.0 , 9.0 , 9.0 )); // If you thought of scaleing it..
   if (j=='3') mesh->setHardwareSkinning(true); // Now the GLSL side of it works fine with this NOT SET..
   if (k=='1') dwarf->setMaterialFlag(EMF_LIGHTING, true); // We could ofcourse have the shader do the lighting!
   else dwarf->setMaterialFlag(EMF_LIGHTING, false);
 
   // if (j == '1') HWSkinCB::getInstance()->setupNode(device,dwarf,17);
   if (j == '1') HWSkinCB::getInstance()->setupNode(device,dwarf,1); // Plaued with delay..
 
   // Here we clone the item into a SQUADRON OF INSTANCES! 
   // How do Culling handle these??
   for(int z = 0; z < 3; z++)
    {for(int x = 0; x <= 3; x++)
      {if (x != 0 || z != 0)
        {ISceneNode* dwarfClone = dwarf->clone();
         dwarf->setPosition(vector3df(x*50, 0, z*50));
        }
      }
    }
   // I didnt concentrate on lighting.. (not my code)
   ILightSceneNode* light = smgr->addLightSceneNode(0,vector3df(0,0,0));
   light->addAnimator(smgr->createFlyCircleAnimator(vector3df(125,180,125),100,0.001f));
   light->getLightData().DiffuseColor = SColorf(0.5f,0.5f,0.0f,0.0f);
   light = smgr->addLightSceneNode(0,vector3df(0.0f,0.0f,0.0f));
   light->addAnimator(smgr->createFlyCircleAnimator(vector3df(125,180,125),100.0f,-0.001f));
   light->getLightData().DiffuseColor = SColorf(0.0f,1.0f,0.0f,0.0f);
   light = smgr->addLightSceneNode(0,vector3df(0.0f,0.0f,0.0f));
   light->addAnimator(smgr->createFlyCircleAnimator(vector3df(125,180,125),80.0f,0.001f));
   light->getLightData().DiffuseColor = SColorf(0.0f,0.5f,1.0f,0.0f);
   light = smgr->addLightSceneNode(0,vector3df(0.0f,0.0f,0.0f));
   light->addAnimator(smgr->createFlyCircleAnimator(vector3df(125,180,125),60.0f,-0.002f));
   light->getLightData().DiffuseColor = SColorf(0.8f,0.2f,0.0f,0.0f);
   int lastFPS=0;
 
   while(device->run())
    {mesh->setAnimationSpeed(CurrentAnimSpeed);  // ???
     if (DebugRendMode > 8)  {DebugRendMode = 0;}
     if (DebugRendMode < 0)  {DebugRendMode = 8;}
     if (DebugRendMode == 0) {dwarf->setDebugDataVisible(EDS_OFF);}
     if (DebugRendMode == 1) {dwarf->setDebugDataVisible(EDS_BBOX);}
     if (DebugRendMode == 2) {dwarf->setDebugDataVisible(EDS_NORMALS);}
     if (DebugRendMode == 3) {dwarf->setDebugDataVisible(EDS_SKELETON);}
     if (DebugRendMode == 4) {dwarf->setDebugDataVisible(EDS_MESH_WIRE_OVERLAY);}
     if (DebugRendMode == 5) {dwarf->setDebugDataVisible(EDS_HALF_TRANSPARENCY);}
     if (DebugRendMode == 6) {dwarf->setDebugDataVisible(EDS_BBOX_BUFFERS);}      // THIS ONE !!!
     if (DebugRendMode == 7) {dwarf->setDebugDataVisible(EDS_BBOX_ALL);}
     if (DebugRendMode == 8) {dwarf->setDebugDataVisible(EDS_FULL);}
     // Yes.. I know.. "Should have been a SWITCH" 
 
     driver->beginScene(true,true,SColor( 255 , 207 , 211 , 192 ));
     smgr->drawAll();
     driver->endScene();
     int fps = driver->getFPS();
     if (lastFPS != fps)
      {core::stringw str = L"Hardware Skinning example";
       if (j=='2') str += "(Hardware Skinning is disabled)";
       str += " FPS:";
       str += fps;
       device->setWindowCaption(str.c_str());
       lastFPS = fps;
      }
    }
   device->closeDevice();
   device->drop();
   return 0;
  };
 
 // O.K.   
 
 
 
 
 
 
Vectrotek
Competition winner
Posts: 1087
Joined: Sat May 02, 2015 5:05 pm

Re: Skinning Bone matrix with 4x3 instead of 4x4

Post by Vectrotek »

I get 1024 characters dancing at "14" frames per second..
I also get 1024 characters dancing at "16" frames per second with H/W skinning and VERY simple HLSLS/GLSL shaders..
I'll wait around until I see something worth wile under H/W skinning.. (I think Irrlicht does a proper job the way it is)
Culling will also be a big ballsup and will take a long time to fix but be fixed it can!

I've got a "True Physically Based Lighting" GLSL and HLSL shader to write for an Oculus project.
Ill post an Irrlicht version soon under another topic..

Here is the 1024 Dancing Characters that shows my Nvidia 9700 GT doing H/W Skinning no favors: (no, they're not North Koreans)
Image

Cheers! Ill be keeping an eye on this!

P.S. Could someone please do something about "Vertex Buffer Box Culling"..
Post Reply