Пример #1
0
    def __init__(self, filename, view):
        Model.__init__(self, filename, view)
        TriangleMesh.__init__(self, filename)

        # Create rigid body
        tvia = TriangleIndexVertexArray()
        tvia.addIndexedMesh(self.mesh)
        shape = BvhTriangleMeshShape(tvia)
        shape.buildOptimizedBvh()
        transform = Transform()
        transform.setIdentity()
        transform.setOrigin(bVector3(0, 0, 0))
        motion = DefaultMotionState()
        motion.setWorldTransform(transform)

        self.body = RigidBody.fromConstructionInfo(motion,              #  MotionState motion
                                                   shape,               #  CollisionShape shape
                                                   0.0,                 #  btScalar mass
                                                   bVector3(0, 0, 0),   #  Vector3 inertia
                                                   transform,           #  Transform worldTransform
                                                   0.0,               	#  btScalar linearDamping
                                                   0.0,               	#  btScalar angularDamping
                                                   0.75,                #  btScalar friction
                                                   0.95,                #  btScalar restitution
                                                   0.0,                 #  btScalar linearSleepingThreshold
                                                   0.0)                 #  btScalar angularSleepingThreshold
        self.motion = motion
        self.body.setContactProcessingThreshold(0)
Пример #2
0
    def internal_tick_callback(self, timeStep):
        if self._cue_ball_rest():
            disp = self.world.getDispatcher()
            n = disp.getNumManifolds()
            for i in xrange(n):
                cm = disp.getManifoldByIndexInternal(i)
                contacts = cm.getNumContacts()
                for c in xrange(contacts):
                    obA = cm.getBody0().getUserPointer()
                    obB = cm.getBody1().getUserPointer()
                    if obA == 'Cue' and obB == 'Cue Ball' \
                    or obA == 'Cue Ball' and obB == 'Cue':
                        p = cm.getContactPoint(c)
                        if p.getDistance() < 0.0: # test for penetration
                            # The cue's strike force is calculated from actual
                            # linear velocity applied to the cues orientation vector
                            b = self.cue.body.getLinearVelocity()
                            v = eVector3(b.x, b.y, b.z)
                            d = self.cue.direction if hasattr(self.cue, 'direction') \
                                                   else self.view.dir
                            # get force
                            impuls = v.magnitude() * SCALE_FACTOR * 25.
                            force = bVector3(d.x * impuls,
                                             d.y * impuls,
                                             0.0)
                            # span offset to [0..1]
                            offset = eVector3(self.cue.dx * 4., 0., self.cue.dy * 4.)

                            # calculate offset from cue's position [convert from eye into object space]
                            # TODO: (rewrite this in compact form of vector vs. matrix multiplication)
                            moffset = self.view.orient.inverse() * Matrix4.new_translate(*offset)
                            offset = eVector3(moffset.d, moffset.h, moffset.l)
                            cue = self.ball['cue']
                            cue.body.clearForces()
                            cue.body.applyGravity()
                            cue.body.applyForce(force, bVector3(offset.x, offset.y, offset.z))

                            # Restore cue
                            self._reset_cue()

        def ball_cant_fly(ball):
            # check for flying
            pos = ball.motion.getWorldTransform().getOrigin()
            if pos.z > ball.radius:
                ball.body.applyCentralForce(bVector3(0, 0, -15 * SCALE_FACTOR))
            # check for ball speed
            v = ball.body.getLinearVelocity()
            vel = eVector3(v.x, v.y, v.z)
            if vel.magnitude_squared() > PoolWindow.BALL_MAX_SPEED:
                ball.body.setLinearVelocity(v * 0.9)

        for ball in self.ball.values():
            ball_cant_fly(ball)
Пример #3
0
    def __init__(self, filename, view, mass, position=eVector3()):
        super(CueBall, self).__init__(filename, view)
        self.radius = self.model.dimension.z / 2.0
        self.mass = mass
        # Update z pos from radius
        position.z = self.radius

        # Init Transform
        transform = Transform()
        self.position = position
        self.do_transformation_matrix()
        self.mnumpy = array(self.m, 'f')
        transform.setFromOpenGLMatrix(self.mnumpy)

        # The Rigid Body
        mass = self.mass * SCALE_FACTOR
        shape = SphereShape(self.radius)
        i = shape.getLocalInertia(mass) * 0.65
        self.motion = DefaultMotionState()
        self.motion.setWorldTransform(transform)
        self.body = RigidBody.fromConstructionInfo(self.motion,         #  MotionState motion
                                                   shape,               #  CollisionShape shape
                                                   mass,                	#  btScalar mass
                                                   bVector3(i.x, i.y, i.z), #  Vector3 inertia
                                                   transform,           #  Transform worldTransform
                                                   0.2,              	#  btScalar linearDamping
                                                   0.65,              	#  btScalar angularDamping
                                                   0.25,                #  btScalar friction
                                                   0.7,          		#  btScalar restitution
                                                   1.5,                 #  btScalar linearSleepingThreshold
                                                   1.5)                 #  btScalar angularSleepingThreshold

        self.body.setContactProcessingThreshold(0)
        self.body.setCcdMotionThreshold(0)
        self.body.setHitFraction(0.1 * SCALE_FACTOR)
Пример #4
0
 def ball_cant_fly(ball):
     # check for flying
     pos = ball.motion.getWorldTransform().getOrigin()
     if pos.z > ball.radius:
         ball.body.applyCentralForce(bVector3(0, 0, -15 * SCALE_FACTOR))
     # check for ball speed
     v = ball.body.getLinearVelocity()
     vel = eVector3(v.x, v.y, v.z)
     if vel.magnitude_squared() > PoolWindow.BALL_MAX_SPEED:
         ball.body.setLinearVelocity(v * 0.9)
Пример #5
0
    def __init__(self, filename, view, cball_radius):
        super(CueStick, self).__init__(filename, view)
        self.half = self.model.dimension / 2.0
        self.tip_radius = self.half.x
        self.pivot = eVector3(0, 0, self.half.z + cball_radius)
        self.org_pivot = eVector3(*self.pivot)
        shape = CapsuleShapeZ(self.tip_radius, self.model.dimension.z - self.tip_radius * 2)
        #shape = CylinderShapeZ(bVector3(*self.half))
        transform = Transform()
        transform.setIdentity()
        self.motion = CSMotionState()
        self.motion.cue = self
        self.delta = 0.
        self.dx = 0.
        self.dy = 0.
        self.motion.setWorldTransform(transform)
        self.body = RigidBody.fromConstructionInfo(self.motion,         #  MotionState motion
                                                   shape,               #  CollisionShape shape
                                                   0.0,                 #  btScalar mass
                                                   bVector3(0, 0, 0),   #  Vector3 inertia
                                                   transform,           #  Transform worldTransform
                                                   0.0,                 #  btScalar linearDamping
                                                   0.0,                 #  btScalar angularDamping
                                                   0.0,                 #  btScalar friction
                                                   0.71,                #  btScalar restitution
                                                   0.0,                 #  btScalar linearSleepingThreshold
                                                   0.0)                 #  btScalar angularSleepingThreshold
        self.body.setContactProcessingThreshold(0)
        self.body.setCcdMotionThreshold(0)
        self.body.setHitFraction(0.1 * SCALE_FACTOR)
        self.body.setGravity(bVector3(0, 0, 0))

        # Make it kinematic body with collision contacts generation but no response impulses
        flags = self.body.getCollisionFlags() | CueStick.CF_KINEMATIC_OBJECT | CueStick.CF_NO_CONTACT_RESPONSE
        self.body.setCollisionFlags(flags)
        self.body.setActivationState(DISABLE_DEACTIVATION)
Пример #6
0
    def __init__(self, *args, **kwargs):
        super(PoolWindow, self).__init__(*args, **kwargs)
        self.set_size(1680, 1000)
        #self.set_fullscreen()
        self.keys = key.KeyStateHandler()
        self.push_handlers(self.keys)

        # Setup GL
        self.set_vsync(True)
        glClearColor(.15, .15, .15, 1)
        glEnable(GL_DEPTH_TEST)
        glEnable(GL_CULL_FACE)
        glShadeModel(GL_SMOOTH)

        self.lpos1 = (0, 0.5 * SCALE_FACTOR, 1 * SCALE_FACTOR, 0)
        self.lpos2 = (0, -0.5 * SCALE_FACTOR, 1 * SCALE_FACTOR, 0)
        glLightfv(GL_LIGHT0, GL_POSITION, vec(*self.lpos1))
        glLightfv(GL_LIGHT1, GL_POSITION, vec(*self.lpos2))

        glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE)
        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_LIGHT1)

        # Scroll zoom
        self.wheel_step = PoolWindow.ZOOM_SCROLL_STEP

        # Setup view
        self.view = View(eye=(0, -3 * SCALE_FACTOR, .75 * SCALE_FACTOR),
                         center=(0, 0, -SCALE_FACTOR))
        self.view.set_distance(SCALE_FACTOR)

        # The scene
        self.table = Table('obj/table.obj', self.view)
        self.rails = Rails('obj/rails.obj', self.view)
        self.ball = {}
        self.ball['cue'] = CueBall('obj/ball.obj', self.view, .260)
        self.ball['red'] = CueBall('obj/red.obj', self.view, .260,
                                   eVector3(0, 0.5 * SCALE_FACTOR, 0))
        self.ball['yellow'] = CueBall('obj/yellow.obj', self.view, .260,
                                      eVector3(0, -0.5 * SCALE_FACTOR, 0))
        self.cue = CueStick('obj/cue.obj', self.view, self.ball['cue'].radius)

        self.table.body.setUserPointer("Table")
        self.rails.body.setUserPointer("Rails")
        self.cue.body.setUserPointer("Cue")
        self.ball['cue'].body.setUserPointer("Cue Ball")
        self.ball['red'].body.setUserPointer("Red")
        self.ball['yellow'].body.setUserPointer("Yellow")

        # Set view center
        pos = self.ball['cue'].motion.getWorldTransform().getOrigin()
        self.view.set_center(eVector3(pos.x, pos.y, pos.z))

        # Setup cue (position and orient)
        self._reset_cue()

        # Initialize physics
        self.world = DiscreteDynamicsWorld()
        self.debug = DebugDraw()
        self.world.setDebugDrawer(self.debug)
        self.world.addRigidBody(self.table.body)
        self.world.addRigidBody(self.cue.body)
        self.world.addRigidBody(self.rails.body)
        for ball in self.ball.values():
            self.world.addRigidBody(ball.body)
        self.world.setGravity(bVector3(0, 0, -9.81 * SCALE_FACTOR))

        # Register call-backs
        # A 1/60 call-back to run physics (the same as render)
        pyglet.clock.schedule(self._step)
        # Physic clock callback (usually few times faster than render clock)
        self.world.setInternalTickCallback(self.internal_tick_callback, True)

        self._setup_pan()
        self.topview = False
        self.helper = True

        self.push_handlers(on_key_press=self._on_key_press)