| 
| 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 Группа: Администраторы Сообщений: 1582 Награды: 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 |  |  |  |  |