AI Class For Irrlicht

A forum to store posts deemed exceptionally wise and useful
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

your are never going to stip improving this ai until it is more inteligent than humans

:wink:

i was doing a 2 point patrol system but it doesnt work so can u please help :D


i have added a new patrol feature so enemies can walk between 2 point when they doesnt see the player

but there is a problem

the enemy goes to one point then he cant come back to the first heres the source


i cant see where the prob is

CODE

if(patrol==true)
{

if(pat1done==false)
{
core::vector3df rot2pat1=getTargetAngle(enemynode->getAbsolutePosition(),pat1);
enemynode->setRotation(core::vector3df(selfrot.X,rot2pat1.Y-90,selfrot.Z));
m.setRotationDegrees(core::vector3df(selfrot.X,rot2pat1.Y,selfrot.Z));
m.transformVect(vel);
enemynode->setPosition(enemynode->getAbsolutePosition() + vel);
core::line3d<f32> line2pat1(enemynode->getAbsolutePosition(),pat1);
float dist2pat1=line2pat1.getLength();
if(dist2pat1<10)
{
pat2done==false;
pat1done==false;
}
}

if(pat1done==true)
{
core::vector3df rot2pat2=getTargetAngle(enemynode->getAbsolutePosition(),pat2);
enemynode->setRotation(core::vector3df(selfrot.X,rot2pat2.Y-90,selfrot.Z));
m.setRotationDegrees(core::vector3df(selfrot.X,rot2pat2.Y,selfrot.Z));
m.transformVect(vel);
enemynode->setPosition(enemynode->getAbsolutePosition() + vel);
core::line3d<f32> line2pat2(enemynode->getAbsolutePosition(), pat2);
float dist2pat2=line2pat2.getLength();
if(dist2pat2<10)
{
pat1done==false;
pat2done==true;
}
}
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

thanks for your kind words.

i think that,in first path

instead of

Code: Select all

if(dist2pat1<10) 
{ 
pat2done==false; 
pat1done==false; 
} 
must be as this

Code: Select all

if(dist2pat1<10) 
{ 
pat2done==false; 
pat1done==true;
}
so when it is near and less than 10 it must to execute the next path
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

thanx ill try it
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi ALL

i have updated the addPathPoint function so you could specify the
start angle and the end angle of the sector view while our enemy
moveing from point to the next one.

here is a demo that i created to show you the powre of AI Class
Image

you could download it from here source code included
http://www.freewebs.com/bcxdx/irrlicht3d.htm
Guest

Post by Guest »

I'm sorry if you have already listed this, but what are the "terms of use" for your AI class?
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

btw how do u add new pages to the wiki?
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

sorry i did not get your question well, so what do you mean by
"terms of use" for your AI class?
omaremad
Competition winner
Posts: 1027
Joined: Fri Jul 15, 2005 11:30 pm
Location: Cairo,Egypt

Post by omaremad »

i think he is asking if he can directly copy it and use it for free
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

omaremad wrote:btw how do u add new pages to the wiki?
1- go to the page that you want to create your page under it.
2- click on "Edit this page"
3- insert your like to your own page then click "save page"
4- go to your balnk page and start to edit it as in #2 step

hope that is clear for you,good luck
Guest

Post by Guest »

Emil_halim wrote:sorry i did not get your question well, so what do you mean by
"terms of use" for your AI class?

I apologize, let me rephrase, what I would like to know is what license are you distributing your code under? If no liscense how do you want to be credited? I hope this is clearer. :)
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

omaremad wrote:i think he is asking if he can directly copy it and use it for free
yes, any one can use it for free ,but please cridet me with his work
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

If no liscense how do you want to be credited? I hope this is clearer.
just put my name with your work that is all
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Post by Emil_halim »

Hi All

I have added a new functions and modified the moveForwared function
so that while our node move in forward direction and found an other
node that we want our node to not go through it but instead of that
when it is very close to the other node it stop moving and start to rotrat
to finding a new direction then it will move in that direction.

added functions
1- setAvoidedNode
2- FindDirction

and here is the new TMove class

Code: Select all

   enum  MStatue
     {
         scan,
         found
     };

   class TMove
    {
          bool               flag;  
          vector3df          Curforward;
          f32                RotSpeed;
          ISceneNode*        ScnNode;
          ISceneManager*     SceneMgr;
          ITriangleSelector* Selector;
          array<triangle3df> Triangles;
          array<vector3df>   Path;
          array<f32>         StartAngle;
          array<f32>         EndAngle;
          vector3df          CurRot;
          s32                indx;
          f32                fctr; 
          f32                MovSpeed; 
          MStatue            statue;
          line3d<f32>        line;
          f32                BultFctr;
          ISceneNode*        RestrictNodes;
          
                    
        public:
          TMove(ISceneNode* node,ISceneManager* ScnMgr)
            {
                ScnNode  = node;
                SceneMgr = ScnMgr;
                RotSpeed = 0.1;
                flag = TRUE;
                Selector = NULL;
                indx = 0;
                MovSpeed = 0.0001;
                fctr = 0.0;
                statue = scan;
                BultFctr = 0;
                RestrictNodes = NULL;
                Curforward.set(1,0,0);
                ScnNode->getAbsoluteTransformation().rotateVect(Curforward);
            }
          ~TMove() {} 
          void Disable() {  flag = FALSE; }
          void Enable()  {  flag = TRUE;  }
          void setRotationSpeed(f32 RotSpd) { RotSpeed = RotSpd; }
          void setMoveSpeed(f32 MovSpd) { MovSpeed = MovSpd; }
          void setTriangleSelector(ITriangleSelector* Sel) { Selector = Sel; }
          void setAvoidedNode(ISceneNode* an) { RestrictNodes = an; }
          void addPathPoint(vector3df& point,f32 srtAngl = 0,f32 endAngl = 360)
            { 
               Path.push_back( point ); 
               StartAngle.push_back(srtAngl);
               EndAngle.push_back(endAngl);
            }  
          vector3df getLineStart() { return line.start;}
          vector3df getLineEnd() { return line.end;}
          vector3df getBulletCoords(f32 BultSpeed) 
            {
                BultFctr += BultSpeed; 
                if (BultFctr >= 1.0)BultFctr = 0;
                return (line.end.getInterpolated(line.start,BultFctr));
            }
          bool ScanArea(ISceneNode* trgt,f32 redus = 100000.f,f32 startAngl=0,f32 endAngl=360)
            {
               if (flag)
                {
                   if (statue == scan)
                    { 
                       startAngl = StartAngle[indx];
                       endAngl = EndAngle[indx]; 
                       if (fctr == 0) 
                        {
                            if (CurRot.Y < startAngl)ScnNode->setRotation(vector3df(0,startAngl,0));
                            if (CurRot.Y > endAngl)ScnNode->setRotation(vector3df(0,endAngl,0));
                        }    
                       vector3df p = Path[indx+1].getInterpolated(Path[indx],fctr);  
                       fctr += MovSpeed;
                       if (fctr >= 1.0) {indx++; fctr = 0.0;}
                       if (indx >= Path.size()-1) indx = 0;
                       ScnNode->setPosition(p);
                    }
                   
                   CurRot = ScnNode->getRotation();
                   CurRot.Y += RotSpeed; 
                   if (CurRot.Y > 360) CurRot.Y -= 360;
                   if (CurRot.Y >= startAngl) RotSpeed *= -1; 
                   if (CurRot.Y <= endAngl)   RotSpeed *= -1;
                   ScnNode->setRotation(CurRot);  
                   Curforward.set(1,0,0);
                   ScnNode->getAbsoluteTransformation().rotateVect(Curforward);
                   line.start = ScnNode->getPosition(); 
                   line.end = line.start + Curforward * redus; 
                   if (trgt->getTransformedBoundingBox().intersectsWithLine(line))
                    {     
                      if (Selector)
                       { 
                           s32           count;
                           vector3df     intersection;
                           s32 totalcnt = Selector->getTriangleCount();
                           Triangles.set_used(totalcnt);
                           Selector->getTriangles(Triangles.pointer(),totalcnt,count,line);
                           for(int i =0; i < count; i++)
                            {
                              if (Triangles[i].getIntersectionWithLimitedLine(line,intersection))
                               {
                                  f64 L1 = ScnNode->getPosition().getDistanceFrom(trgt->getPosition()); 
                                  f64 L2 = ScnNode->getPosition().getDistanceFrom(intersection);
                                  if (L1 < L2) goto pass;
                                  statue = scan;
                                  return FALSE; 
                               } 
                            }    
                        } 
                       pass:      
                        RotSpeed /= 2;
                        if (RotSpeed < 0.001)
                         {
                             ScnNode->setRotation(getTargetAngle(trgt)); 
                             statue = found;
                         }    
                         return TRUE;
                    }    
                }        
            }
           void MoveForward(f32 speed,f32 minDistance = 10)
            {  
               if (RestrictNodes)
                {
                  if (GetDistance(RestrictNodes) <= minDistance)
                   {
                      if (FindDirction(RestrictNodes)) speed = 0 ;
                   }      
                }    
                vector3df newPos= ScnNode->getPosition() + (Curforward * speed); 
                ScnNode->setPosition(newPos); 
            }  
           f64 GetDistance(ISceneNode* trgt)
            {
                vector3df pos = ScnNode->getPosition();
                return  pos.getDistanceFrom(trgt->getPosition());  
            } 
           vector3df getTargetAngle(ISceneNode* trgt) 
            { 
                vector3df v = ScnNode->getPosition();
                vector3df r = trgt->getPosition();
                vector3df angle; 
                float x,y,z; 
                x = r.X - v.X; 
                y = r.Y - v.Y; 
                z = r.Z - v.Z;  
                angle.Y = atan2 (x, z); 
                angle.Y *= (180 / PI);  
                angle.Y-=90; 
                if(angle.Y < 0) angle.Y += 360; 
                if(angle.Y >= 360) angle.Y -= 360;  
                float z1 = sqrt(x*x + z*z); 
                angle.X = atan2 (z1, y); 
                angle.X *= (180 / PI);  
                angle.X -= 90; 
                if(angle.X < 0) angle.X += 360; 
                if(angle.X >= 360) angle.X -= 360; 
                return angle; 
            } 
          bool FindDirction(ISceneNode* trgt,f32 EscapAngle = 25,f32 redus = 100000.f)
            {  
                static f32 Rotconst=0; 
                static f32 RotFactor=0;
                CurRot = ScnNode->getRotation();
                CurRot.Y += RotFactor; 
                if (CurRot.Y > 360) CurRot.Y -= 360;
                ScnNode->setRotation(CurRot);  
                Curforward.set(1,0,0);
                ScnNode->getAbsoluteTransformation().rotateVect(Curforward);
                line.start = ScnNode->getPosition(); 
                line.end = line.start + Curforward * redus; 
                if (trgt->getTransformedBoundingBox().intersectsWithLine(line))
                 {
                     RotFactor = 0.01;
                     Rotconst=0; 
                     return false;
                 }
                else 
                 {   
                     Rotconst += RotFactor; 
                     if (Rotconst > EscapAngle) { RotFactor = 0.0; return true;}
                     return false;
                 }       
            } 
    };   
here is a code showing you how to use it

Code: Select all

       static x! = 0.01
       MyNode->MoveForward(x)
       if MyNode->GetDistance(otherNode) < 10 then  
          '//if our node is very close to othernode less than 10
          '//we stop moving and start to find new direction
          '//and if we found it we will move in that direction
          x = 0
          if MyNode->FindDirction(otherNode) then x = 0.01 
       end if 
i think that AI class will make our enemy start to thinking then will
act.

hope it is usefull for someone
Emil_halim
Posts: 518
Joined: Tue Mar 29, 2005 9:02 pm
Location: Alex,Egypt
Contact:

Using AI CLASS for DOOR OPENNING Demo

Post by Emil_halim »

Hi ALL

this time i will show you how to use AI class for Openning door demo.

the demo start for that , our model moving in his path and at the same time looking for the Door node of our room ,so if the model found it ie will move forward to the door,and when distance between our model and the door less than 150 the door start to rotate and our model still moving forward to the door direction.

here is a screen shot of our demo , the first is while model look for the Door , and the second is when it found it and the door start to open.

Image
Image

here is the code for BCX

Code: Select all

'**********************************************
' using Irrlicht 3D Engine With BCX
'
' 
' OpenDoor AI demo
'
' By Emil Halim
' http://www.freewebs.com/bcxdx/index.htm
'**********************************************
$Cpp
GUI "Irrlict & BCXDX",PIXELS
$include "../../Classes/StartUp.inc"
SUB FORMLOAD
Global irrDevice as IrrlichtDevice ptr
irrDevice = createDevice(dimension2d<s32>(640,480),32,false,false,false,0)
irrDevice->setWindowCaption(L"BCXDX9 &Irrlicht Engine")
Global irrVideo as IVideoDriver ptr
irrVideo = irrDevice->getVideoDriver()
Global irrSceneMgr as ISceneManager ptr
irrSceneMgr = irrDevice->getSceneManager()



Global roomMesh  as IAnimatedMesh ptr 
roomMesh = irrSceneMgr->getMesh("../media1/room.3ds")
irrSceneMgr->getMeshManipulator()->makePlanarTextureMapping(roomMesh->getMesh(0),0.008f)
Global room = 0 as ISceneNode ptr
room = irrSceneMgr->addOctTreeSceneNode(roomMesh->getMesh(0))
room->setMaterialTexture(0, irrVideo->getTexture("../media/wall.jpg"))
room->setPosition(vector3df(0,-40,0))
Global door as ISceneNode ptr
door = irrSceneMgr->addTestSceneNode()
door->setMaterialTexture(0, irrVideo->getTexture("../media/t351sml.jpg"))
door->setPosition(vector3df(12,20,350))
door->setScale(vector3df(16,60,0.2))
dim mesh as IAnimatedMesh ptr                      
mesh = irrSceneMgr->getMesh("../media/faerie.md2")                         
Global node1 as IAnimatedMeshSceneNode ptr
node1 = irrSceneMgr->addAnimatedMeshSceneNode( mesh )
node1->setMaterialFlag(EMF_LIGHTING, false)
node1->setMD2Animation(EMAT_STAND)
node1->setMaterialTexture( 0, irrVideo->getTexture("../media/Faerie5.BMP"))
!TMove* MyNode = new  TMove(node1,irrSceneMgr);
MyNode->setTriangleSelector(room->getTriangleSelector())
MyNode->setRotationSpeed(0.1)
MyNode->setMoveSpeed(0.0005)
MyNode->addPathPoint(vector3df(0,0,-100),290,350)
MyNode->addPathPoint(vector3df(50,0,-80),290-20,350-20)
MyNode->addPathPoint(vector3df(100,0,-30),290-45,350-45)
MyNode->addPathPoint(vector3df(130,0,30))



Global font as IGUIFont ptr
font = irrDevice->getGUIEnvironment()->getFont("../media/fonthaettenschweiler.bmp")
'irrSceneMgr->addCameraSceneNode(0, vector3df(140,30,-150), vector3df(0,5,0))
Global camera as ICameraSceneNode ptr
camera =  irrSceneMgr->addCameraSceneNodeFPS(0,100.0f,300.0f)
camera->setPosition(vector3df(140,30,-150))
!int lastFPS = -1;
While  irrDevice->run()
      
      irrVideo->beginScene(true, true, SColor(0,200,200,200))
      static Mx! = 0 ,DoorRot! = 0
      if MyNode->ScanArea(door,400) then
         if MyNode->GetDistance(door) < 400 then Mx = 0.1  
         if MyNode->GetDistance(door) < 150  then 
             DoorRot+= 0.2
             if DoorRot > 90 then DoorRot = 90
             door->setRotation(vector3df(0,DoorRot,0))    
         End if    
         MyNode->MoveForward(Mx)
      End if     
            
      irrSceneMgr->drawAll()
      irrVideo->endScene() 
      $Ccode
        int fps = irrVideo->getFPS();
        if (lastFPS != fps)
        {
            stringw str = L"Irrlicht Engine - example [";
            str += irrVideo->getName();
            str += "] FPS:";
            str += fps;
            irrDevice->setWindowCaption(str.c_str());    
            lastFPS = fps;
        }
      $Ccode
Wend     
irrDevice->drop()                     
PostQuitMessage(0)
End sub
BEGIN EVENTS
END EVENTS 
Enjoy it

thanks
VcDeveloper
Posts: 7
Joined: Mon Jul 05, 2010 12:21 am

Post by VcDeveloper »

@Emil
Are you still around and I woud like to see your latest class.
Coding is like a box of chocolates!...
Post Reply