ya2 · news · projects · code · about

pmachines/ -> game/
[pmachines.git] / pmachines / items / item.py
diff --git a/pmachines/items/item.py b/pmachines/items/item.py
deleted file mode 100644 (file)
index fabd391..0000000
+++ /dev/null
@@ -1,339 +0,0 @@
-from panda3d.core import CullFaceAttrib, Point3, NodePath, Point2, Texture, \
-    Plane, Vec3, BitMask32
-from panda3d.bullet import BulletBoxShape, BulletRigidBodyNode, BulletGhostNode
-from direct.gui.OnscreenText import OnscreenText
-from lib.lib.p3d.gfx import P3dGfxMgr, set_srgb
-
-
-class Command:
-
-    def __init__(self, pos, rot):
-        self.pos = pos
-        self.rot = rot
-
-
-class FixedStrategy:
-
-    def win_condition(self):
-        return True
-
-
-class StillStrategy:
-
-    def __init__(self, np):
-        self._np = np
-        self._positions = []
-        self._rotations = []
-
-    def win_condition(self):
-        self._positions += [self._np.get_pos()]
-        self._rotations += [self._np.get_hpr()]
-        if len(self._positions) > 30:
-            self._positions.pop(0)
-        if len(self._rotations) > 30:
-            self._rotations.pop(0)
-        if len(self._positions) < 28:
-            return
-        avg_x = sum(pos.x for pos in self._positions) / len(self._positions)
-        avg_y = sum(pos.y for pos in self._positions) / len(self._positions)
-        avg_z = sum(pos.z for pos in self._positions) / len(self._positions)
-        avg_h = sum(rot.x for rot in self._rotations) / len(self._rotations)
-        avg_p = sum(rot.y for rot in self._rotations) / len(self._rotations)
-        avg_r = sum(rot.z for rot in self._rotations) / len(self._rotations)
-        avg_pos = Point3(avg_x, avg_y, avg_z)
-        avg_rot = Point3(avg_h, avg_p, avg_r)
-        return all((pos - avg_pos).length() < .1 for pos in self._positions) and \
-            all((rot - avg_rot).length() < 1 for rot in self._rotations)
-
-
-class Item:
-
-    def __init__(self, world, plane_node, cb_inst, curr_bottom, scene_repos, model_path, model_scale=1, exp_num_contacts=1, mass=1, pos=(0, 0, 0), r=0, count=0, restitution=.5, friction=.5):
-        self._world = world
-        self._plane_node = plane_node
-        self._count = count
-        self._cb_inst = cb_inst
-        self._paused = False
-        self._overlapping = False
-        self._first_command = True
-        self.repos_done = False
-        self._mass = mass
-        self._pos = pos
-        self._r = r
-        self.strategy = FixedStrategy()
-        self._exp_num_contacts = exp_num_contacts
-        self._curr_bottom = curr_bottom
-        self._scene_repos = scene_repos
-        self._model_scale = model_scale
-        self._model_path = model_path
-        self._commands = []
-        self._command_idx = -1
-        self._restitution = restitution
-        self._friction = friction
-        self._positions = []
-        self._rotations = []
-        if count:
-            self.node = BulletGhostNode(self.__class__.__name__)
-        else:
-            self.node = BulletRigidBodyNode(self.__class__.__name__)
-        self._set_shape(count)
-        self._np = render.attach_new_node(self.node)
-        if count:
-            world.attach_ghost(self.node)
-        else:
-            world.attach_rigid_body(self.node)
-        self._model = loader.load_model(model_path)
-        set_srgb(self._model)
-        self._model.flatten_light()
-        self._model.reparent_to(self._np)
-        self._np.set_scale(model_scale)
-        self._np.flatten_strong()
-        if count:
-            self._set_outline_model()
-            set_srgb(self._outline_model)
-            self._model.hide(BitMask32(0x01))
-            self._outline_model.hide(BitMask32(0x01))
-        self._start_drag_pos = None
-        self._prev_rot_info = None
-        self._last_nonoverlapping_pos = None
-        self._last_nonoverlapping_rot = None
-        self._instantiated = not count
-        self.interactable = count
-        self._box_tsk = taskMgr.add(self.on_frame, 'on_frame')
-        if count:
-            self._repos()
-        else:
-            self._np.set_pos(pos)
-            self._np.set_r(r)
-
-    def _set_shape(self, apply_scale=True):
-        pass
-
-    def set_strategy(self, strategy):
-        self.strategy = strategy
-
-    def _repos(self):
-        p_from, p_to = P3dGfxMgr.world_from_to((-1, 1))
-        for hit in self._world.ray_test_all(p_from, p_to).get_hits():
-            if hit.get_node() == self._plane_node:
-                pos = hit.get_hit_pos()
-        corner = P3dGfxMgr.screen_coord(pos)
-        bounds = self._np.get_tight_bounds()
-        bounds = bounds[0] - self._np.get_pos(), bounds[1] - self._np.get_pos()
-        self._np.set_pos(pos)
-        plane = Plane(Vec3(0, 1, 0), bounds[0][1])
-        pos3d, near_pt, far_pt = Point3(), Point3(), Point3()
-        margin, ar = .04, base.get_aspect_ratio()
-        margin_x = margin / ar if ar >= 1 else margin
-        margin_z = margin * ar if ar < 1 else margin
-        top = self._curr_bottom()
-        base.camLens.extrude((-1 + margin_x, top - margin_z), near_pt, far_pt)
-        plane.intersects_line(
-            pos3d, render.get_relative_point(base.camera, near_pt),
-            render.get_relative_point(base.camera, far_pt))
-        delta = Vec3(bounds[1][0], bounds[1][1], bounds[0][2])
-        self._np.set_pos(pos3d + delta)
-        if not hasattr(self, '_txt'):
-            font = base.loader.load_font('assets/fonts/Hanken-Book.ttf')
-            font.clear()
-            font.set_pixels_per_unit(60)
-            font.set_minfilter(Texture.FTLinearMipmapLinear)
-            font.set_outline((0, 0, 0, 1), .8, .2)
-            self._txt = OnscreenText(
-                str(self._count), font=font, scale=0.06, fg=(.9, .9, .9, 1))
-        pos = self._np.get_pos() + (bounds[1][0], bounds[0][1], bounds[0][2])
-        p2d = P3dGfxMgr.screen_coord(pos)
-        self._txt['pos'] = p2d
-        self.repos_done = True
-
-    def repos_x(self, x):
-        self._np.set_x(x)
-        bounds = self._np.get_tight_bounds()
-        bounds = bounds[0] - self._np.get_pos(), bounds[1] - self._np.get_pos()
-        pos = self._np.get_pos() + (bounds[1][0], bounds[0][1], bounds[0][2])
-        p2d = P3dGfxMgr.screen_coord(pos)
-        self._txt['pos'] = p2d
-
-    def get_bottom(self):
-        bounds = self._np.get_tight_bounds()
-        bounds = bounds[0] - self._np.get_pos(), bounds[1] - self._np.get_pos()
-        pos = self._np.get_pos() + (bounds[1][0], bounds[1][1], bounds[0][2])
-        p2d = P3dGfxMgr.screen_coord(pos)
-        ar = base.get_aspect_ratio()
-        return p2d[1] if ar >= 1 else (p2d[1] * ar)
-
-    def get_corner(self):
-        bounds = self._np.get_tight_bounds()
-        return bounds[1][0], bounds[1][1], bounds[0][2]
-
-    def _set_outline_model(self):
-        self._outline_model = loader.load_model(self._model_path)
-        #clockw = CullFaceAttrib.MCullClockwise
-        #self._outline_model.set_attrib(CullFaceAttrib.make(clockw))
-        self._outline_model.set_attrib(CullFaceAttrib.make_reverse())
-        self._outline_model.reparent_to(self._np)
-        self._outline_model.set_scale(1.08)
-        self._outline_model.set_light_off()
-        self._outline_model.set_color(.4, .4, .4, 1)
-        self._outline_model.set_color_scale(.4, .4, .4, 1)
-        self._outline_model.hide()
-
-    def on_frame(self, task):
-        self._np.set_y(0)
-        return task.cont
-
-    def undo(self):
-        self._command_idx -= 1
-        self._np.set_pos(self._commands[self._command_idx].pos)
-        self._np.set_hpr(self._commands[self._command_idx].rot)
-
-    def redo(self):
-        self._command_idx += 1
-        self._np.set_pos(self._commands[self._command_idx].pos)
-        self._np.set_hpr(self._commands[self._command_idx].rot)
-
-    def play(self):
-        if not self._instantiated:
-            return
-        self._world.remove_rigid_body(self.node)
-        self.node.set_mass(self._mass)
-        self._world.attach_rigid_body(self.node)
-        self.node.set_restitution(self._restitution)
-        self.node.set_friction(self._friction)
-
-    def on_click_l(self, pos):
-        if self._paused: return
-        self._start_drag_pos = pos, self._np.get_pos()
-        loader.load_sfx('assets/audio/sfx/grab.ogg').play()
-        if not self._instantiated:
-            self._world.remove_ghost(self.node)
-            pos = self._np.get_pos()
-            self._np.remove_node()
-            self.node = BulletRigidBodyNode('box')
-            self._set_shape()
-            self._np = render.attach_new_node(self.node)
-            self._world.attach_rigid_body(self.node)
-            self._model.reparent_to(self._np)
-            self._np.set_pos(pos)
-            self._set_outline_model()
-            self._np.set_scale(self._model_scale)
-            self._model.show(BitMask32(0x01))
-            self._outline_model.hide(BitMask32(0x01))
-            self._instantiated = True
-            self._txt.destroy()
-            self._count -= 1
-            if self._count:
-                item = self.__class__(self._world, self._plane_node, self._cb_inst, self._curr_bottom, self._scene_repos, count=self._count, mass=self._mass, pos=self._pos, r=self._r)  # pylint: disable=no-value-for-parameter
-                self._cb_inst(item)
-            self._scene_repos()
-
-    def on_click_r(self, pos):
-        if self._paused or not self._instantiated: return
-        self._prev_rot_info = pos, self._np.get_pos(), self._np.get_r()
-        loader.load_sfx('assets/audio/sfx/grab.ogg').play()
-
-    def on_release(self):
-        if self._start_drag_pos or self._prev_rot_info:
-            loader.load_sfx('assets/audio/sfx/release.ogg').play()
-            self._command_idx += 1
-            self._commands = self._commands[:self._command_idx]
-            self._commands += [Command(self._np.get_pos(), self._np.get_hpr())]
-            self._first_command = False
-        self._start_drag_pos = self._prev_rot_info = None
-        if self._overlapping:
-            self._np.set_pos(self._last_nonoverlapping_pos)
-            self._np.set_hpr(self._last_nonoverlapping_rot)
-            self._outline_model.set_color(.4, .4, .4, 1)
-            self._outline_model.set_color_scale(.4, .4, .4, 1)
-            self._overlapping = False
-
-    def on_mouse_on(self):
-        if not self._paused and self.interactable:
-            self._outline_model.show()
-
-    def on_mouse_off(self):
-        if self._start_drag_pos or self._prev_rot_info: return
-        if self.interactable:
-            self._outline_model.hide()
-
-    def on_mouse_move(self, pos):
-        if self._start_drag_pos:
-            d_pos =  pos - self._start_drag_pos[0]
-            self._np.set_pos(self._start_drag_pos[1] + d_pos)
-        if self._prev_rot_info:
-            start_vec = self._prev_rot_info[0] - self._prev_rot_info[1]
-            curr_vec = pos - self._prev_rot_info[1]
-            d_angle = curr_vec.signed_angle_deg(start_vec, (0, -1, 0))
-            self._np.set_r(self._prev_rot_info[2] + d_angle)
-            self._prev_rot_info = pos, self._np.get_pos(), self._np.get_r()
-        if self._start_drag_pos or self._prev_rot_info:
-            res = self._world.contact_test(self.node)
-            nres = res.get_num_contacts()
-            if nres <= self._exp_num_contacts:
-                self._overlapping = False
-                self._outline_model.set_color(.4, .4, .4, 1)
-                self._outline_model.set_color_scale(.4, .4, .4, 1)
-            if nres > self._exp_num_contacts and not self._overlapping:
-                actual_nres = 0
-                for contact in res.get_contacts():
-                    for node in [contact.get_node0(), contact.get_node1()]:
-                        if isinstance(node, BulletRigidBodyNode) and \
-                                node != self.node:
-                            actual_nres += 1
-                if actual_nres >= 1:
-                    self._overlapping = True
-                    loader.load_sfx('assets/audio/sfx/overlap.ogg').play()
-                    self._outline_model.set_color(.9, .1, .1, 1)
-                    self._outline_model.set_color_scale(.9, .1, .1, 1)
-        if not self._overlapping:
-            self._last_nonoverlapping_pos = self._np.get_pos()
-            self._last_nonoverlapping_rot = self._np.get_hpr()
-
-    def on_aspect_ratio_changed(self):
-        if not self._instantiated:
-            self._repos()
-
-    def store_state(self):
-        self._paused = True
-        self._model.set_transparency(True)
-        self._model.set_alpha_scale(.3)
-        if hasattr(self, '_txt') and not self._txt.is_empty():
-            self._txt.set_alpha_scale(.3)
-
-    def restore_state(self):
-        self._paused = False
-        self._model.set_alpha_scale(1)
-        if hasattr(self, '_txt') and not self._txt.is_empty():
-            self._txt.set_alpha_scale(1)
-
-    def fail_condition(self):
-        if self._np.get_z() < -6:
-            return True
-        self._positions += [self._np.get_pos()]
-        self._rotations += [self._np.get_hpr()]
-        if len(self._positions) > 30:
-            self._positions.pop(0)
-        if len(self._rotations) > 30:
-            self._rotations.pop(0)
-        if len(self._positions) < 28:
-            return
-        avg_x = sum(pos.x for pos in self._positions) / len(self._positions)
-        avg_y = sum(pos.y for pos in self._positions) / len(self._positions)
-        avg_z = sum(pos.z for pos in self._positions) / len(self._positions)
-        avg_h = sum(rot.x for rot in self._rotations) / len(self._rotations)
-        avg_p = sum(rot.y for rot in self._rotations) / len(self._rotations)
-        avg_r = sum(rot.z for rot in self._rotations) / len(self._rotations)
-        avg_pos = Point3(avg_x, avg_y, avg_z)
-        avg_rot = Point3(avg_h, avg_p, avg_r)
-        return all((pos - avg_pos).length() < .1 for pos in self._positions) and \
-            all((rot - avg_rot).length() < 1 for rot in self._rotations)
-
-    def destroy(self):
-        self._np.remove_node()
-        taskMgr.remove(self._box_tsk)
-        if hasattr(self, '_txt'):
-            self._txt.destroy()
-        if not self._instantiated:
-            self._world.remove_ghost(self.node)
-        else:
-            self._world.remove_rigid_body(self.node)