ultra fast lod

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
jeromegz
Posts: 14
Joined: Sat Aug 02, 2008 10:51 am

ultra fast lod

Post by jeromegz »

hi everybody , i try to make a lod scenenode :

here is the orgininal paper for implement fast sqrt
http://www.azillionmonkeys.com/qed/sqroot.html
(Paul Hsieh's release as free licence code )
For calculate LOd, you need adapt formula
distance = sqrt(pow (x2-x1)+pow(y2-y2)) // you can add z2-z1
ok , now , this is my fast sqrt in the irrlicht /c++ code :

Code: Select all

double InvSqrt (double y) { //NOTE : THIS IS NOT THE Q3 or LEMON //InvSqrt fonction :  //read carrefully , i'm not using it !!!!!!  

    double x, z, tempf;
    unsigned long *tfptr = ((unsigned long *)&tempf) + 1;

	tempf = y;
	*tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */
	x =  tempf;
	z =  y*0.5;                        /* hoist out the “/2”    */
	x = (1.5*x) - (x*x)*(x*z);         /* iteration formula     */ 
//	x = (1.5*x) – (x*x)*(x*z); //répéter pour plus de pécision (dans un fps , faut pas réver )
	//x = (1.5*x) – (x*x)*(x*z); //repeat for more 
	//x = (1.5*x) – (x*x)*(x*z);
	//x = (1.5*x) – (x*x)*(x*z);//tout cela est puissant, les modèles se changent vite
	return x*y;
    }
now the POW function, i have septic answers with it , because, pow is
not reliable for all architectures (w86 ) , 32 etc, in somes cases , like this , the best methode is calculate with "*"

Code: Select all

     unsigned pow_a(unsigned int x, unsigned int exp)
{
unsigned int retval = 1;
 
for (;exp;--exp) retval *= x;
 
return retval;
} 


now, the player LOD : you need 2 versions of your mesh :

for exemple :

Code: Select all

Player lodlow[9];Player lodhight[9];//le modele correspond au modele 
  lodlow[1].CreatePlayer(driver, smgr, "../../media/PlL.obj", "../../media/sss.jpg", 
      core::vector3df(2333,3036,11222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));
      
      //on va chercher l'emplacement  si <> L
       lodhight[1].CreatePlayer(driver, smgr, "../../media/pLH.obj", "../../media/sss.jpg", 
      core::vector3df(2333,3063,11222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));static int distancelod  = 4800;  
    //  lodhight[1].getPlayer()->show(false)
      
        lodlow[2].CreatePlayer(driver, smgr, "../../media/rocherL.obj", "../../media/sss.jpg", 
      core::vector3df(14333,36,11222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));
      
      //on va chercher l'emplacement  si <> L
       lodhight[2].CreatePlayer(driver, smgr, "../../media/rocherH.obj", "../../media/sss.jpg", 
      core::vector3df(14333,63,11222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));   
  
    
      
       lodlow[3].CreatePlayer(driver, smgr, "../../media/LOWA.obj", "../../media/sss.jpg", 
      core::vector3df(18333,-16,8222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));
      
      //on va chercher l'emplacement  si <> L
       lodhight[3].CreatePlayer(driver, smgr, "../../media/HIGA.obj", "../../media/sss.jpg", 
      core::vector3df(18333,-16,8222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(129, 129, 129));   
      
      
      
      
       lodlow[4].CreatePlayer(driver, smgr, "../../media/l03.obj", "../../media/sss.jpg", 
      core::vector3df(13333,116,9222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(229, 829, 229));
      
      //on va chercher l'emplacement  si <> L
       lodhight[4].CreatePlayer(driver, smgr, "../../media/h03.obj", "../../media/sss.jpg", 
      core::vector3df(13333,116,9222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(229, 829, 229));   
      
      
           lodlow[4].CreatePlayer(driver, smgr, "../../media/l02.obj", "../../media/sss.jpg", 
      core::vector3df(13333,116,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(229, 829, 229));
      
      //on va chercher l'emplacement  si <> L
       lodhight[4].CreatePlayer(driver, smgr, "../../media/h02.obj", "../../media/sss.jpg", 
      core::vector3df(13333,116,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(229, 829, 229));  
      
      
       lodlow[5].CreatePlayer(driver, smgr, "../../media/ec.obj", "../../media/sss.jpg", 
      core::vector3df(13333,7516,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(49, 529, 49));
      
      //on va chercher l'emplacement  si <> L
       lodhight[5].CreatePlayer(driver, smgr, "../../media/ech.obj", "../../media/sss.jpg", 
      core::vector3df(13333,7516,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(49, 529, 49)); 
      
      
       lodlow[6].CreatePlayeri(driver, smgr, "../../../l/l/Cube.011.irrmesh", "../../media/sss.jpg", 
      core::vector3df(13333,860,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,2260,0  ), core::vector3df(589, 89, 589));
      
      //on va chercher l'emplacement  si <> L
       lodhight[6].CreatePlayeri(driver, smgr, "../../../l/h/Cube.011.irrmesh", "../../media/sss.jpg", 
      core::vector3df(13333,860,4222  /*sin(i)*2 (sin(turn)*2*/), 
      core::vector3df(0,0,0  ), core::vector3df(589, 89, 589));

Now, the player , put it before main()

Code: Select all


  
class Player
{
      public:
             Player();        // constructeur
             ~Player();     // destructeur
             
             void CreatePlayer(video::IVideoDriver* driver, scene::ISceneManager* smgr, char model[256], char Texture[256], irr::core::vector3df position, irr::core::vector3df rotation, irr::core::vector3df scale);  // pour cree le nouveau player
             void CreatePlayeri(video::IVideoDriver* driver, scene::ISceneManager* smgr, char model[256], char Texture[256], irr::core::vector3df position, irr::core::vector3df rotation, irr::core::vector3df scale);  // pour cree le nouveau player
            void Createempty(){} //modele chargé // pour cree le nouveau player
            
             void CreateBillboard(video::IVideoDriver* driver, scene::ISceneManager* smgr, char image[256], int x, int y);  // pour ajouter un billoard au dessu du player
            
             //pour cette partie je me passe de commentaire

             void setPosition(irr::core::vector3df Pposition);
             void setRotation(irr::core::vector3df Protation);
             void setFrameLoop(int debut, int fin);
            void changer_de_mesh( const c8* fn , char nouveau_mesh[256],scene::ISceneManager* smgr);
             void setadaptation(int adaptation);
             int getadaptation();
             //pour la webcam setmaterialtexture
              void nouvelledestination(int debut, int fin);   
                  /*  void setv(bool vs);*/
             IAnimatedMeshSceneNode* getPlayer();
             
             irr::core::vector3df getPosition();
             
             double getPositionX();
             double getPositionY();
             double getPositionZ();
             double getRotationX();
             double getRotationY();
             double getRotationZ();
             
             
             
             
             irr::core::vector3df getRotation();
             //int gene[20];
              
             
             void Update(int elapsedTime);//sinon sans elapsed time un update tout eul
             
      private:
             irr::scene::IAnimatedMeshSceneNode* NodePlayer;                 // le node du player
             f32 x,y,z;
              irr::scene::IAnimatedMesh* mesha;
             irr::scene::IBillboardSceneNode *bilo;                    // le billoard
             int adaptation_;//a enlever si le node n'et pas une plante ou organisme
             
             
             irr::core::vector3df NodePlayerVector;                   // vector 3d
             irr::core::vector3df NodePlayerRotationVector;       // vector 3d
             
             video::ITexture *TXTbiloard;                                 // texture du billboard
             
              irr::core::vector3df deb_destination_player;      
              irr::core::vector3df fin_destination_player;    
              
             char FileModel[256];
             char FileTexture[256];
};




Player::Player()
{               
}
Player::~Player()
{                
}

/* ---------------------------------------- */
/* ---------------------------------------- */
/* ---------------------------------------- */

void Player::CreatePlayer(video::IVideoDriver* driver, 
                          scene::ISceneManager* smgr,
                          char model[256], 
                          char Texture[256], 
                          irr::core::vector3df position, 
                          irr::core::vector3df rotation,
                          irr::core::vector3df scale
                          )
{
      strcpy(FileModel, model);
      strcpy(FileTexture, Texture);
      
     
      
       mesha = smgr->getMesh(model);
        NodePlayer = smgr->addAnimatedMeshSceneNode(mesha);  
        NodePlayer->setMaterialFlag(video::EMF_LIGHTING, false);//en attendant
        
         //	NodePlayer->setMaterialFlag(video::EMF_FOG_ENABLE, true);
      NodePlayer->setMaterialTexture( 0, driver->getTexture(Texture));
       NodePlayer->setMaterialTexture(1, driver->getTexture("../../media/water.jpg"));
      NodePlayer->setPosition(position);
      NodePlayer->setScale(scale);
         NodePlayer->setRotation(rotation);
        NodePlayer->getMaterial(0).SpecularColor.set(25,55,255,255);
 //nodefs->getMaterial(0).SpecularColor.set(0,1,1,0);
  NodePlayer->getMaterial(0).Shininess = 30.0f;
  
  //f32 hasard
  NodePlayer->getMaterial(1).EmissiveColor = irr::video::SColor(56,122,222,170);
  // nodefs->getMaterial(0).EmissiveColor  = 20.0f;
      //NodePlayer->getMaterial(0).DiffuseColor   = 30;
      NodePlayer->setMaterialType(video::EMT_REFLECTION_2_LAYER);
      //create tengante ? = true , set shader material if support shader -> create player (true else (false
//il faut creer des ombres pour ces plantes
//NodePlayer->addShadowVolumeSceneNode();



}

void Player::CreatePlayeri(video::IVideoDriver* driver, 
                          scene::ISceneManager* smgr,
                          char model[256], 
                          char Texture[256], 
                          irr::core::vector3df position, 
                          irr::core::vector3df rotation,
                          irr::core::vector3df scale
                          )
{
      strcpy(FileModel, model);
      strcpy(FileTexture, Texture);
      
     
      
       mesha = smgr->getMesh(model);
        NodePlayer = smgr->addAnimatedMeshSceneNode(mesha);  
      
      NodePlayer->setPosition(position);
      NodePlayer->setScale(scale);
         NodePlayer->setRotation(rotation);
       
 
}
void Player::CreateBillboard(video::IVideoDriver* driver, scene::ISceneManager* smgr, char image[256], int x, int y)
{
     bilo = smgr->addBillboardSceneNode(NULL, core::dimension2d<f32>(x, y), NodePlayer->getPosition());
     bilo->setMaterialFlag(irr::video::EMF_LIGHTING, false);
     bilo->setMaterialType(irr::video::EMT_TRANSPARENT_ADD_COLOR);
     TXTbiloard = driver->getTexture(image);
     bilo->setMaterialTexture(0,TXTbiloard);                        
}

void Player::setPosition(irr::core::vector3df Pposition)
{
      NodePlayer->setPosition(Pposition);            
}

 /*void setv(bool vs)
{  NodePlayer->setVisible(vs);
}
 ---------------------------------------- */

void Player::setRotation(irr::core::vector3df Protation)
{
     NodePlayer->setRotation(Protation);                
}


IAnimatedMeshSceneNode* Player::getPlayer()
{
     return NodePlayer;
}

/* ---------------------------------------- */

irr::core::vector3df Player::getPosition()
{
     return NodePlayer->getPosition();
}
double Player::getPositionX()
{
     return NodePlayer->getPosition().X;
}
double Player::getPositionY()
{
     return NodePlayer->getPosition().Y;
}
double Player::getPositionZ()
{
     return NodePlayer->getPosition().Z;
}
/* ---------------------------------------- */

irr::core::vector3df Player::getRotation()
{
     return NodePlayer->getRotation();                
}
double Player::getRotationX()
{
     return NodePlayer->getRotation().X;
}
double Player::getRotationY()
{
     return NodePlayer->getRotation().Y;
}
double Player::getRotationZ()
{
     return NodePlayer->getRotation().Z;
}

/* ---------------------------------------- */

void Player::setFrameLoop(int debut, int fin)
{
     NodePlayer->setFrameLoop(debut, fin);
}
void Player::changer_de_mesh( const c8* fn, char nouveau_mesh[256],scene::ISceneManager* smgr)//ne marche pas
{
    
   NodePlayer->setMesh(smgr->getMesh(nouveau_mesh)); //NodePlayer->remove();
      
     }
     
     
 void Player::setadaptation(int adaptation)
{
      adaptation_ = adaptation;
    // NodePlayer->setFrameLoop(debut, fin);
}
int Player::getadaptation()
{
      return adaptation_;
}
/* ---------------------------------------- */
/* ---------------------------------------- */
/* ---------------------------------------- */

void Player::nouvelledestination(int debut, int fin) 
{

}


void Player::Update(int elapsedTime)//*time elapsed à enlever si l'on peut
{
    // bilo->setPosition(vector3df(NodePlayer->getPosition().X, NodePlayer->getPosition().Y + 75,NodePlayer->getPosition().Z));
	//udpade vers destination du player


}

note that the player open .irr mesh and obj etc...
for .irr : createplayeri
for others : createplayer
for bilboard : createbilboard

now, the main while function :

WHILE()

Code: Select all



 for(i=1;i<7;i++)
       if (  Invsqrt(pow_a(   ( camera->getAbsolutePosition().X- lodlow[i].getPlayer()->getAbsolutePosition().X  ),2)+ pow_a ( ( camera->getAbsolutePosition().Z - lodlow[i].getPlayer()->getAbsolutePosition().Z     ),2) )  >      distancelod   ){// || camera->getAbsolutePosition().Y > nodeff->getAbsolutePosition().Y + distancelod  || camera->getAbsolutePosition().Z > nodeff->getAbsolutePosition().Z + distancelod ){
   
                    
                      
                           lodlow[i].getPlayer()->setVisible(true);
                         lodhight[i].getPlayer()->setVisible(false);
                        
                     
			} 
			else
		{	 
                     
                    
                    
                  
                    
             lodlow[i].getPlayer()->setVisible(false);
                         lodhight[i].getPlayer()->setVisible(true);
                         
                    
                                  
                
        }
you can use pow if you want

you can calculate distance only 1*/seconde with timers fonctions


-------------------------------------------
change

we can improve the structure by parsing
2 scene node in the player class

createplaer( first , second )
private
animatedmeshscenenode hight;
animatedmeshscenenode low;

and put the lod fonction ( instead of in while function ) in player

player::onanimatelod(){
if (Invsqrt(pow_a ( camera.......
{ hight->setvisble(true); low->setvisible(false);
}else
{ low->setvisble(true); hight->setvisible(false);
}

and :
while()
{ for (...<7)
player->onanimatelod();
}


Code: Select all


void Player::CreatePlayerlod(video::IVideoDriver* driver, 
                          scene::ISceneManager* smgr,
                          char model[256], char modelb[256]
                          char Texture[256], 
                          irr::core::vector3df position, 
                          irr::core::vector3df rotation,
                          irr::core::vector3df scale
                          )
{
      strcpy(FileModel, model);
      strcpy(FileTexture, Texture);
      strcpy(FileModel, modelb);
     
       meshb = smgr->getMesh(modelb);
       mesha = smgr->getMesh(model);
        NodePlayer = smgr->addAnimatedMeshSceneNode(mesha);  
       NodePlayerhight = smgr->addAnimatedMeshSceneNode(meshb);  
      NodePlayer->setPosition(position);
      NodePlayer->setScale(scale);
      NodePlayerhight->setPosition(position);
      NodePlayerhight->setScale(scale);
       NodePlayerhight->setRotation(rotation);
         NodePlayer->setRotation(rotation);
       
 
}

in class Player put

Code: Select all


  private:
             irr::scene::IAnimatedMeshSceneNode* NodePlayer;                 // le node du player
             f32 x,y,z;
              irr::scene::IAnimatedMesh* mesha;
              
               irr::scene::IAnimatedMeshSceneNode* NodePlayerhight;                 // le node du player
             f32 x,y,z;
              irr::scene::IAnimatedMesh* meshb;

declare with (create any versions of that , for irrmesh , bilboard, special mesh etc...:

Code: Select all

   void CreatePlayerlod(video::IVideoDriver* driver, scene::ISceneManager* smgr, char model[256], char modellod[256], char Texture[256], irr::core::vector3df position, irr::core::vector3df rotation, irr::core::vector3df scale);  // pour cree le nouveau player
          

Code: Select all



void Player::Update() 
{
      if (  sqrt(pow_a(   ( camera->getAbsolutePosition().X- NodePlayer.getPlayer()->getAbsolutePosition().X  ),2)+ pow_a( ( camera->getAbsolutePosition().Z - NodePlayer.getPlayer()->getAbsolutePosition().Z     ),2) )  >      distancelod   ){ 
  
  NodePlaye->setvisible(false);
    NodePlayerhight->setvisible(true);
 }else
{
 NodePlaye->setvisible(true);
    NodePlayerhight->setvisible(false);

}


}
in WHILE()
{ for (i = 1; i<7;i++)
player->update;
...
}//fin while
Hello
Post Reply