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;
}
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));
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
}
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 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);
}
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;
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);
}
}
{ for (i = 1; i<7;i++)
player->update;
...
}//fin while