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 |
|
| |