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 __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")