def __init__(self, game):
     self.game = game
     self.cells = {}
     self.cells_by_collider = {}
     self.cell_picker_world = NodePath('cell_picker_world')
     self.ray = CollisionRay()
     self.ray.setDirection(LVector3.down())
     cnode = CollisionNode('cell_raycast_cnode')
     self.ray_nodepath = self.cell_picker_world.attachNewNode(cnode)
     self.ray_nodepath.node().addSolid(self.ray)
     self.ray_nodepath.node().setIntoCollideMask(0) # not for colliding into
     self.ray_nodepath.node().setFromCollideMask(1)
     self.traverser = CollisionTraverser('traverser')
     self.last_known_cell = None
Esempio n. 2
0
 def __init__(self, game):
     self.game = game
     self.cells = {}
     self.cells_by_collider = {}
     self.cell_picker_world = NodePath('cell_picker_world')
     self.ray = CollisionRay()
     self.ray.setDirection(LVector3.down())
     cnode = CollisionNode('cell_raycast_cnode')
     self.ray_nodepath = self.cell_picker_world.attachNewNode(cnode)
     self.ray_nodepath.node().addSolid(self.ray)
     self.ray_nodepath.node().setIntoCollideMask(
         0)  # not for colliding into
     self.ray_nodepath.node().setFromCollideMask(1)
     self.traverser = CollisionTraverser('traverser')
     self.last_known_cell = None
    def deform_terrain(self, mode="raise", duration=1.0):
        self.deform_duration = duration
        """
        Calculate distance to the spot at which we want to raise the terrain.
        At its current speed the vehicle would reach it in 2.5 seconds.
        [km/h] / 3.6 = [m/s] * [s] = [m]
        """
        distance = self.vehicle.get_current_speed_km_hour() / 3.6 * 2.5
        spot_pos_world = (self.vehicleNP.get_pos() +
                          self.vehicle.get_forward_vector() * distance)

        spot_pos_heightfield = self.terrain_node.world_to_heightfield(
            spot_pos_world)
        xcenter = spot_pos_heightfield.x
        ycenter = spot_pos_heightfield.y
        """
        To create a smooth hill/depression we call PfmFile.pull_spot to create
        a sort of gradient. You can use self.cardmaker_debug to view it.
        
        From the Panda3D API documentation of PfmFile.pull_spot:
        Applies delta * t to the point values within radius (xr, yr)
        distance of (xc, yc). The t value is scaled from 1.0 at the center
        to 0.0 at radius (xr, yr), and this scale follows the specified
        exponent. Returns the number of points affected.
        """
        # Delta to apply to the point values in DynamicHeightfield array.
        delta = LVector4(0.001)
        # Make the raised spot elliptical.
        xradius = 10.0  # meters
        yradius = 6.0  # meters
        # Choose an exponent
        exponent = 0.6
        # Counter-clockwise angle between Y-axis 
        angle = self.vehicle.get_forward_vector().signed_angle_deg(
            LVector3.forward(), LVector3.down())
            
        # Define all we need to repeatedly deform the terrain using a task.    
        self.spot_params = [delta, xcenter, ycenter, xradius, yradius,
                            exponent, mode]
                            
        # Clear staging area to a size that fits our raised region.
        self.StagingPFM.clear(int(xradius)*2, int(yradius)*2, num_channels=1)
        
        """
        There are two options:
        (1) Rotate our hill/depression to be perpendicular
            to the vehicle's trajectory. This is the default.
        (2) Just put it in the terrain unrotated.
        """

        # Option (1)
        self.StagingPFM.pull_spot(delta,
                                  xradius-0.5, yradius-0.5,
                                  xradius, yradius,
                                  exponent)
        
        # Rotate wider side so it's perpendicular to vehicle's trajectory.
        self.RotorPFM.rotate_from(self.StagingPFM, angle)
        
        self.raise_start_time = globalClock.get_real_time()
        taskMgr.do_method_later(0.03, self.deform_perpendicular,
                                "DeformPerpendicularSpot")