def ship(self): an = ActorNode() an.getPhysicsObject().setMass(100) self.fighter = self.render.attachNewNode(an) self.physicsMgr.attachPhysicalNode(an) self.anpo = an.getPhysicsObject() fn = ForceNode("force-node-fighter") self.fighter.attachNewNode(fn) self.pft = LinearVectorForce(Vec3(0, +1, 0) * 500) # forward thrust self.prt = LinearVectorForce(Vec3(0, -1, 0) * 500) # reverse thrust self.pft.setMassDependent(1) self.prt.setMassDependent(1) self.pft.setActive(False) self.prt.setActive(False) fn.addForce(self.pft) fn.addForce(self.prt) an.getPhysical(0).addLinearForce(self.pft) an.getPhysical(0).addLinearForce(self.prt) self.camera.reparentTo(self.fighter) from_obj = self.fighter.attachNewNode(CollisionNode('fighter')) from_obj.node().setFromCollideMask(BitMask32(0x1)) from_obj.setCollideMask(BitMask32(0x1)) from_obj.node().addSolid(CollisionSphere(0, 0, 0, 1)) # from_obj.show() self.pusher.addCollider(from_obj, self.fighter) self.cTrav.addCollider(from_obj, self.pusher)
def __init__(self, base, name, speed, scale, color, mask, relA, xyz, relB, lookat, life): an = ActorNode() self.anp = base.render.attachNewNode(an) base.physicsMgr.attachPhysicalNode(an) self.anpo = an.getPhysicsObject() fn = ForceNode("force-missile") self.anp.attachNewNode(fn) bft = LinearVectorForce(Vec3(0, 1, 0)*speed) fn.addForce(bft) an.getPhysical(0).addLinearForce(bft) missile = base.loader.loadModel("./mdl/missile.egg") missile.setColor(color) missile.setScale(scale) missile.reparentTo(self.anp) missile.setTag(name, '1') missile_from_obj = missile.attachNewNode(CollisionNode(name)) missile_from_obj.node().addSolid(CollisionSphere(0, 0, 0, 1)) missile_from_obj.node().setFromCollideMask(mask) missile_from_obj.setCollideMask(mask) base.pusher.addCollider(missile_from_obj, self.anp) base.cTrav.addCollider(missile_from_obj, base.pusher) self.anp.setPos(relA, xyz) self.anp.lookAt(relB, lookat) # light the missile mlight = DirectionalLight('mlight') mlight.setColor(VBase4(1., 1., 1., 1)) mlnp = base.render.attachNewNode(mlight) mlnp.setHpr(self.anp.getHpr()) self.anp.setLightOff() self.anp.setLight(mlnp) # remove the missile base.taskMgr.doMethodLater(life, self.remove_missile, 'task-remove-missile', extraArgs=[self.anp], appendTask=True)
def createBarrel(self): barrelNode = NodePath("PhysicalBarrel") barrelNode.reparentTo(self.scene) barrelNode.setPos(self.scene, 0,0,0) physicsBarrel = ActorNode("physics_barrel") physicsBarrel.getPhysicsObject().setMass(0.01) #in what units? (69 kindda 3 lbs) barrel = barrelNode.attachNewNode(physicsBarrel) base.physicsMgr.attachPhysicalNode(physicsBarrel) barrel.setPos(barrelNode, 0,0,0) visual_barrel = self.scene.attachNewNode("BarrelCopy") originalBarrel = self.scene.find("barrel") originalBarrel.instanceTo(visual_barrel) visual_barrel.reparentTo(barrel) visual_barrel.setPos(self.scene, -6.5,0,-24.5 ) dataNode = barrelNode.attachNewNode(AuxData("Sequence",None)) seq = self.createBarrelGraphicSequence(visual_barrel, physicsBarrel, dataNode) dataNode.node().getPythonTag("subclass").sequence = seq #sphere = CollisionSphere(6.6,0,4.78, 0.5) sphere = CollisionSphere(6.6,0,24.7, 0.5) cnodePath = visual_barrel.attachNewNode(CollisionNode('barrelCollider')) cnodePath.node().addSolid(sphere) cnodePath.node().setFromCollideMask(0xD) # crash with default and mario body and walls cnodePath.node().setIntoCollideMask(0xD) # crash with default and mario body and walls self.showCollision(cnodePath) #cnodePath.show() self.physicsCollisionPusher.addCollider(cnodePath,barrel) base.cTrav.addCollider(cnodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode('barrelForce') barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-7,0,0, 1, False) # barrelForce.setMassDependent(0) barrelForceNode.addForce(barrelForce) physicsBarrel.getPhysical(0).addLinearForce(barrelForce) # starting barrel point :D barrelNode.setPos(self.scene,6.5,0,4.5)
def __init__(self, base, name, speed, scale, color, mask, relA, xyz, relB, lookat, life): an = ActorNode() self.anp = base.render.attachNewNode(an) base.physicsMgr.attachPhysicalNode(an) self.anpo = an.getPhysicsObject() fn = ForceNode("force-missile") self.anp.attachNewNode(fn) bft = LinearVectorForce(Vec3(0, 1, 0) * speed) fn.addForce(bft) an.getPhysical(0).addLinearForce(bft) missile = base.loader.loadModel("./mdl/missile.egg") missile.setColor(color) missile.setScale(scale) missile.reparentTo(self.anp) missile.setTag(name, '1') missile_from_obj = missile.attachNewNode(CollisionNode(name)) missile_from_obj.node().addSolid(CollisionSphere(0, 0, 0, 1)) missile_from_obj.node().setFromCollideMask(mask) missile_from_obj.setCollideMask(mask) base.pusher.addCollider(missile_from_obj, self.anp) base.cTrav.addCollider(missile_from_obj, base.pusher) self.anp.setPos(relA, xyz) self.anp.lookAt(relB, lookat) # light the missile mlight = DirectionalLight('mlight') mlight.setColor(VBase4(1., 1., 1., 1)) mlnp = base.render.attachNewNode(mlight) mlnp.setHpr(self.anp.getHpr()) self.anp.setLightOff() self.anp.setLight(mlnp) # remove the missile base.taskMgr.doMethodLater(life, self.remove_missile, 'task-remove-missile', extraArgs=[self.anp], appendTask=True)
def createBarrel(self): barrelNode = NodePath("PhysicalBarrel") barrelNode.reparentTo(self.scene) physicsBarrel = ActorNode("physics_barrel") physicsBarrel.getPhysicsObject().setMass( 0.01) #in what units? (69 kindda 3 lbs) barrel = barrelNode.attachNewNode(physicsBarrel) base.physicsMgr.attachPhysicalNode(physicsBarrel) barrel.setPos(0, 0, 2) visual_barrel = self.scene.attachNewNode("BarrelCopy") originalBarrel = self.scene.find("barrel") originalBarrel.instanceTo(visual_barrel) visual_barrel.reparentTo(barrel) sphere = CollisionSphere(6.6, 0, 4.78, 0.5) cnodePath = visual_barrel.attachNewNode( CollisionNode('barrelCollider')) cnodePath.node().addSolid(sphere) cnodePath.node().setFromCollideMask( 0xD) # crash with default and mario body and walls cnodePath.node().setIntoCollideMask( 0xD) # crash with default and mario body and walls cnodePath.show() self.physicsCollisionPusher.addCollider(cnodePath, barrel) base.cTrav.addCollider(cnodePath, self.physicsCollisionPusher) barrelForceNode = ForceNode('barrelForce') barrel.attachNewNode(barrelForceNode) barrelForce = LinearVectorForce(-7, 0, 0, 1, False) # barrelForce.setMassDependent(0) barrelForceNode.addForce(barrelForce) physicsBarrel.getPhysical(0).addLinearForce(barrelForce)
class QuadRotorSimulation(ShowBase): def __init__(self): ShowBase.__init__(self) self.scene = self.loader.loadModel(models_dir + "hallway.bam") # Load the environment model self.scene.reparentTo(self.render) self.scene.setScale(1, 1, 1) self.scene.setPos(0, 0, 1) self.scene.setHpr(90, 0, 0) # Add an ambient light and set sky color sky_col = VBase3(135 / 255.0, 206 / 255.0, 235 / 255.0) self.set_background_color(sky_col) alight = AmbientLight("sky") alight.set_color(VBase4(sky_col * 0.04, 1)) alight_path = self.render.attachNewNode(alight) self.render.set_light(alight_path) # # 4 perpendicular lights (flood light) for light_no in range(4): d_light = DirectionalLight('directionalLight') d_light.setColor(Vec4(*([0.3] * 4))) d_light_NP = self.render.attachNewNode(d_light) d_light_NP.setHpr(-90 * light_no, 0, 0) self.render.setLight(d_light_NP) # # 1 directional light (Sun) sun_light = DirectionalLight('directionalLight') sun_light.setColor(Vec4(*([0.7] * 4))) # directional light is dim green sun_light.getLens().setFilmSize(Vec2(0.8, 0.8)) sun_light.getLens().setNearFar(-0.3, 12) sun_light.setShadowCaster(True, 2 ** 7, 2 ** 7) self.dlightNP = self.render.attachNewNode(sun_light) self.dlightNP.setHpr(0, -65, 0) # Turning shader and lights on self.render.setLight(self.dlightNP) # Load and transform the quadrotor actor. self.quad_model = self.loader.loadModel(models_dir + f'{quad_model_filename}.egg') self.prop_models = [] for prop_no in range(4): prop = self.loader.loadModel(models_dir + 'propeller.egg') x = 0 if prop_no % 2 == 1 else (-0.26 if prop_no == 0 else 0.26) y = 0 if prop_no % 2 == 0 else (-0.26 if prop_no == 3 else 0.26) prop.setPos(x, y, 0) prop.reparentTo(self.quad_model) self.prop_models.append(prop) self.prop_models = tuple(self.prop_models) # self.quad_model.reparentTo(self.scene) self.quad_model.setPos(0, 0, 2) self.quad_neutral_hpr = (90, 0, 0) self.quad_model.setHpr(*self.quad_neutral_hpr) # env cam self.cam_neutral_pos = (0, -4, 3) self.cam.reparentTo(self.scene) # self.cam_neutral_pos = (-4, 0, 1) # self.cam.reparentTo(self.quad_model) self.cam.setPos(*self.cam_neutral_pos) self.cam.lookAt(self.quad_model) self.enableParticles() node = NodePath("PhysicsNode") node.reparentTo(self.scene) self.actor_node = ActorNode("quadrotor-physics") # self.actor_node.getPhysicsObject().setMass(1) self.actor_node_physics = node.attachNewNode(self.actor_node) self.physicsMgr.attachPhysicalNode(self.actor_node) self.quad_model.reparentTo(self.actor_node_physics) # add gravity # gravity_force_node = ForceNode('world-forces') # gravityForce = LinearVectorForce(0, 0, -0.1) # gravity acceleration # gravity_force_node.addForce(gravityForce) # self.physicsMgr.addLinearForce(gravityForce) self.time = datetime.datetime.today().strftime('%Y-%m-%d-%H.%M.%S') self.simulation_folder = "\sims\\" + self.time + '\\' self.simulation_folder_path = ROOT_DIR + self.simulation_folder os.makedirs(self.simulation_folder_path) self.movements = '' self.taskMgr.add(self.camera_move, 'Camera Movement') self.taskMgr.add(self.quad_move, 'Quad Movement') self.taskMgr.add(self.rotate_propellers, 'Propellers Rotation') self.taskMgr.add(self.save_image, 'Screenshot Capture') # self.buffer: GraphicsBuffer = self.win.makeTextureBuffer(name='buffer', x_size=84, y_size=84, tex=None, to_ram=True) # self.buffer.setActive(1) self.images = [] self.image_index = 1 def camera_move(self, task): """ Moves the camera about the quadcopter """ keys_vs_moves = {'k': i, 'h': -i, 'i': j, 'y': -j, 'u': k, 'j': -k } mat = np.array(self.cam.getMat())[0:3, 0:3] move_total = LPoint3f(0, 0, 0) for key, move in keys_vs_moves.items(): pressed_key = self.mouseWatcherNode.is_button_down(KeyboardButton.asciiKey(key)) if pressed_key: move = LPoint3f(move) move_total += move # if any([abs(coordinate) > 0 for coordinate in move_total]): # ROTATE COORDINATE SYSTEM (TO CAMERA) move_total = LPoint3f(*tuple(np.dot(mat.T, np.array(move_total)))) proportionality_constant = 0.05 cam_pos = self.cam.getPos() + move_total * proportionality_constant self.cam.setPos(cam_pos) self.cam.lookAt(self.quad_model) return task.cont def quad_move(self, task): position_proportionality_constant = 0.0007 angle_proportionality_constant = 0.2 angle_max = 10 angle_directions = {i: k, j: -j} keys_vs_moves = {'w': i, 's': -i, 'a': j, 'd': -j, 'e': k, 'q': -k} move_total = LPoint3f(0, 0, 0) angle_total = LPoint3f(0, 0, 0) for key, move in keys_vs_moves.items(): pressed_key = self.mouseWatcherNode.is_button_down(KeyboardButton.asciiKey(key)) if pressed_key: move_total += move if key not in ['e', 'q', 'm']: angle_total += LPoint3f(*tuple(sign(move) * np.array( angle_directions[LPoint3f(*tuple(int(abs(c)) for c in move))]) * angle_proportionality_constant)) else: prop_sign = 1 if key == 'e' else -1 for prop in self.prop_models: prop.setHpr(prop.get_hpr() + LPoint3f(10 * prop_sign, 0, 0)) self.movements += key with open(ROOT_DIR + self.simulation_folder + 'movements.txt', 'w') as file: file.write(self.movements) # self.movie(namePrefix=self.simulation_folder, duration=1.0, fps=30, # format='png', sd=4, source=None) if any([abs(coordinate) > 0 for coordinate in angle_total]): # tilt_force_node = ForceNode('tilt-force') # tilt_force = AngularVectorForce(*angle_total) # tilt_force_node.addForce(tilt_force) # # self.actor_node.getPhysical(0).addAngularForce(tilt_force) desired_quad_hpr = list(self.quad_model.getHpr() + angle_total) for index, coordinate in enumerate(desired_quad_hpr): if coordinate: desired_quad_hpr[index] = sign(coordinate) * min(abs(coordinate), 90 + angle_max if index == 0 else angle_max) desired_quad_hpr = LPoint3f(*desired_quad_hpr) self.quad_model.setHpr(desired_quad_hpr) if any([abs(coordinate) > 0 for coordinate in move_total]): movement_force_node = ForceNode('movement-force') movement_force = LinearVectorForce(*(- move_total * position_proportionality_constant)) # movement_force.setMassDependent(1) movement_force_node.addForce(movement_force) self.actor_node.getPhysical(0).addLinearForce(movement_force) # time.sleep(0.1) # thruster.setP(-45) # bend the thruster nozzle out at 45 degrees # desired_quad_pos = self.quad_model.getPos() + move_total * position_proportionality_constant # self.quad_model.setPos(desired_quad_pos) return task.cont def rotate_propellers(self, task): for prop in self.prop_models: prop.setHpr(prop.get_hpr() + LPoint3f(30, 0, 0)) return task.cont # def produce_video(self): def save_image(self, task): self.image_index += 1 if self.image_index % 10 == 0: self.screenshot(namePrefix=rf'{self.simulation_folder}\image') if self.image_index % 100 == 0: # p = Process(target=my_function, args=(queue, 1)) # p.start() video_name = rf'{self.simulation_folder_path}\video.avi' images = [img for img in os.listdir(self.simulation_folder_path) if img.endswith(".jpg")] frame = cv2.imread(os.path.join(self.simulation_folder_path, images[0])) height, width, layers = frame.shape video = cv2.VideoWriter(video_name, 0, 30, (width, height)) for image in images: video.write(cv2.imread(os.path.join(self.simulation_folder_path, image))) cv2.destroyAllWindows() video.release() return task.cont
class Bullet(DirectObject): def __init__(self, playerID, color=LPoint3f(0,0,0)): self.color = color self.playerID = playerID self.bulletNP = NodePath("Bullet-%d" % id(self)) self.bulletAN = ActorNode("bullet-physics-%d" % id(self)) # set the mass of the ball to 3.3g = average weight of a paintball self.bulletAN.getPhysicsObject().setMass(0.033) self.bulletANP = self.bulletNP.attachNewNode(self.bulletAN) base.physicsMgr.attachPhysicalNode(self.bulletAN) self.bullet = loader.loadModel("Bullet") self.bullet.setScale(2) self.bullet.setColorScale( self.color.getX(), self.color.getY(), self.color.getZ(), 1.0) self.bullet.reparentTo(self.bulletANP) # setup the collision detection # 17.3 mm (0.0173) = size of a .68cal paintball self.bulletColName = "bulletCollision-%02d" % id(self) self.bulletSphere = CollisionSphere(0, 0, 0, 0.0173*2) self.bulletCollision = self.bulletANP.attachNewNode(CollisionNode(self.bulletColName)) self.bulletCollision.node().addSolid(self.bulletSphere) #self.bulletCollision.show() base.physicpusher.addCollider(self.bulletCollision, self.bulletANP) base.cTrav.addCollider(self.bulletCollision, base.physicpusher) def shoot(self, pos, shootVec=None): if shootVec != None: v = shootVec v *= 214.0 else: # Get from/to points from mouse click pMouse = base.mouseWatcherNode.getMouse() pFrom = Point3() pTo = Point3() base.camLens.extrude(pMouse, pFrom, pTo) pFrom = render.getRelativePoint(base.cam, pFrom) pTo = render.getRelativePoint(base.cam, pTo) # Calculate initial velocity v = pTo - pFrom v.normalize() v *= 214.0 self.bulletNP.setPos(pos) self.bulletNP.reparentTo(render) self.bulletFN = ForceNode("Bullet-force-%d" % id(self)) self.bulletFNP = self.bulletNP.attachNewNode(self.bulletFN) # speed of a paintball when he leafes the muzzle: 214 fps self.lvf = LinearVectorForce(v) self.lvf.setMassDependent(1) self.bulletFN.addForce(self.lvf) self.bulletAN.getPhysical(0).addLinearForce(self.lvf) self.accept("bulletCollision-%d-hit" % id(self), self.bulletHit) taskMgr.doMethodLater( 2, self.doRemove, 'doRemove-%d' % id(self), appendTask=True) def doRemove(self, task): if self is None: return task.done self.ignoreAll() self.bulletNP.removeNode() self.bulletAN.getPhysical(0).removeLinearForce(self.lvf) return task.done def bulletHit(self, entry): hitName = entry.getIntoNode().getName() if str(self.playerID) not in hitName and \ self.bulletColName not in hitName: base.messenger.send("Bulet-hit-%s" % hitName, [entry, self.color]) self.bulletNP.removeNode() self.bulletAN.getPhysical(0).removeLinearForce(self.lvf)