[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
Страница 1 из 11
Форум Panda3D - по русски » Panda3D » Общие вопросы » ODE + AI (Как наложить "умное" поведение на физический объект)
ODE + AI
SergNefДата: Понедельник, 23.03.2015, 15:45 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 6
Награды: 0
Репутация: 0
Статус: Offline
Здравствуйте! Начал изучать Панду несколько недель назад. Нашел, что можно, используя ODE или Bullet, задавать гравитацию и силы определенному объекту, и также задавать этому объекту определенную массу. Тут возник вопрос, как сделать так, чтобы сила действовала какое-то время, а не весь сценарий?

Дальше нашел, что в Панде есть библиотека PandAI, которая позволяет реализовывать различные модели движения, такие как преследование цели, обхождение препятствий, поведение роя. Но это все реализуется отдельно, в каком-то вакууме. Как мне реализовать это умное поведение для конкретных физических объектов из OdeWorld, у которых есть масса и на которых действуют различные силы?

Я пытался написать отдельный класс World, в котором бы как-то объединились ODE и AI:


Код
class World(DirectObject):

     def __init__(self):
         base.disableMouse()
         base.cam.setPos(80,-140,80)
   
         self.loadModels()
         self.setAI()
         self.setMovement()

     def loadModels(self):
         # Seeker
         self.flockers = []   

         for i in range(3):
             # Setup the geometry
             flocker = loader.loadModel("fighter.egg")
             self.flockersNP = flocker.copyTo(render)
             self.flockersNP.setPos(20*i, 1, 21)
             self.flockersNP.setColor(random(), random(), random(), 1)
             #fighter_tex=loader.loadTexture("models/alice-scifi--fighter-pic.jpg")
             #sphereNP.setTexture(fighter_tex, 1)

             # Create the body and set the mass
             self.flockersBody = OdeBody(world)
             M = OdeMass()
             M.setBox(100, 1, 1, 1)
             #M.setSphere(100.0, 1.0)
             self.flockersBody.setMass(M)
             self.flockersBody.setPosition(sphereNP.getPos(render))
             self.flockersBody.setQuaternion(sphereNP.getQuat(render))
             self.flockers.append((self.flockersNP, self.flockersBody))

         #for self.flockersNP in self.flockers:
         #    AIchar.append(AICharacter("flockers"+str(i),self.flockers[i], 100, 0.05, 5))

         self.target = Actor("models/boeing707")
         self.target.setColor(1,1,1)
         self.target.setPos(0,0,0)
         self.target.setScale(0.01)
         self.target.reparentTo(render)         

     def setAI(self):
         #Creating AI World
         self.AIworld = AIWorld(render)
   
         #Flock functions
         self.MyFlock = Flock(1, 270, 5, 10, 0.001, 10)
         self.AIworld.addFlock(self.MyFlock)
         self.AIworld.flockOn(1);

   
         self.AIchar = []
         self.AIbehaviors = []
         for np, body in self.flockers:
             self.AIchar.append(AICharacter("flockers"+str(np),np, 100, 0.05, 5))
             self.AIworld.addAiChar(self.AIchar[np])
             self.AIbehaviors.append(self.AIchar[np].getAiBehaviors())
             self.MyFlock.addAiChar(self.AIchar[np])
             self.AIbehaviors[np].flock(0.5)              
             self.AIbehaviors[np].pursue(self.target, 0.5)

         #AI World update         
         taskMgr.add(self.AIUpdate,"AIUpdate")          

     def Mover(self,task):
         startPos = self.target.getPos()
         if (self.keyMap["left"]!=0):
                 self.target.setPos(startPos + Point3(-speed,0,0))
         if (self.keyMap["right"]!=0):
                 self.target.setPos(startPos + Point3(speed,0,0))
         if (self.keyMap["up"]!=0):
                 self.target.setPos(startPos + Point3(0,speed,0))
         if (self.keyMap["down"]!=0):
                 self.target.setPos(startPos + Point3(0,-speed,0))
       
         return Task.cont

     def setMovement(self):
         self.keyMap = {"left":0, "right":0, "up":0, "down":0}
         self.accept("arrow_left", self.setKey, ["left",1])
         self.accept("arrow_right", self.setKey, ["right",1])
         self.accept("arrow_up", self.setKey, ["up",1])
         self.accept("arrow_down", self.setKey, ["down",1])
         self.accept("arrow_left-up", self.setKey, ["left",0])
         self.accept("arrow_right-up", self.setKey, ["right",0])
         self.accept("arrow_up-up", self.setKey, ["up",0])
         self.accept("arrow_down-up", self.setKey, ["down",0])
         #movement task
         taskMgr.add(self.Mover,"Mover")

     # The task for our simulation

     def simulationTask(task):
       global deltaTimeAccumulator
       # Set the force on the body to push it off the ridge
       for (np, body) in spheres:
           body.setForce(0, 0, 1500)
       targetBody.setForce(0,100, 1500)     
         # Add the deltaTime for the task to the accumulator
       deltaTimeAccumulator += globalClock.getDt()
       while deltaTimeAccumulator > stepSize:
         # Remove a stepSize from the accumulator until
         # the accumulated time is less than the stepsize
         deltaTimeAccumulator -= stepSize
         # Step the simulation
         world.quickStep(stepSize)
       # set the new positions
       for (np, body) in spheres:
           np.setPosQuat(render, body.getPosition(), Quat(body.getQuaternion()))
       target.setPosQuat(render, targetBody.getPosition(), Quat(targetBody.getQuaternion()))     
       return task.cont

но проблема в том, что у AIchar.append(AICharacter("flockers"+str(np),np, 100, 0.05, 5)) во втором аргументе должен приходить int, а не NodePath.

P.S. Опирался вот на этот пример: http://www.panda3d.org/manual/index.php/Flock
 
ninthДата: Понедельник, 23.03.2015, 15:53 | Сообщение # 2
Admin
Группа: Администраторы
Сообщений: 1555
Награды: 5
Репутация: 46
Статус: Offline
Я бы советовал попробовать Bullet http://www.panda3d.org/manual/index.php/Bullet_Character_Controller он более заточен под подобные игровые вещи. ODE - это, грубо говоря, сферический конь в вакууме, т.е. ODE требует чтобы всё управление осуществлялось посредством приложения сил. Bullet в этом плане проще.
 
SergNefДата: Четверг, 26.03.2015, 17:02 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 6
Награды: 0
Репутация: 0
Статус: Offline
Возникает такая проблема: я хочу создать группу объектов из BulletWorld, которым можно задать массу и прочие атрибуты, которые можно задавать объектам из BulletWorld. И затем эти объекты использовать для Flock. Но чтобы создать эту группу объектов, я не создаю список, а использую NodePath, и каждый объект у меня привязан к узлу, у которого родительский узел это BulletRigidBodyNode. А Flock, как я понял, с узлами не работает. Как эту проблему можно обойти? И существует ли вообще решение этой проблемы?

Сообщение отредактировал SergNef - Четверг, 26.03.2015, 17:03
 
Форум Panda3D - по русски » Panda3D » Общие вопросы » ODE + AI (Как наложить "умное" поведение на физический объект)
Страница 1 из 11
Поиск: