Beispiel #1
0
    def _move (self, dt, rd):

        if self._at_rest:
            return

        pos = self._pos
        quat = self._quat
        vel = self._vel
        angvel = self._angvel

        gracc = self.world.gravacc
        pos1 = pos + vel * dt + gracc * (0.5 * dt**2)
        vel1 = vel + gracc * dt
        touch = self.world.below_surface(pos, elev=self._fix_elev)
        if touch:
            gpos = self.world.intersect_surface(pos, pos1, elev=self._fix_elev)
            gnorm = vtof(self.world.elevation(gpos, wnorm=True)[1])
            pos1 -= gnorm * (pos1 - gpos).dot(gnorm) * 2
            vel1_el = unitv(pos1 - pos) * vel1.length()
            vel1_el_n = gnorm * vel1_el.dot(gnorm)
            vel1_el_t = vel1_el - vel1_el_n
            vel1 = vel1_el_n * self._norm_rest_fac + vel1_el_t * self._tang_rest_fac
            self._at_rest = (vel1.length() < 0.5)
            if self._at_rest:
                pos1 = gpos
                vel1 = Vec3(0.0, 0.0, 0.0)
        self.node.setPos(pos1)

        raxis = unitv(self._angvel)
        if raxis.length() == 0.0:
            raxis = Vec3(0.0, 0.0, 1.0)
        absangvel1 = self._angvel.length()
        if touch:
            absangvel1 *= self._tumble_rest_fac
        dquat = Quat()
        dquat.setFromAxisAngleRad(absangvel1 * dt, raxis)
        quat1 = quat * dquat
        angvel1 = raxis * absangvel1
        self.node.setQuat(quat1)

        self._pos = pos1
        self._quat = quat1
        self._vel = vel1
        self._angvel = angvel1
Beispiel #2
0
    def __call__(self, task):
        for moment in self.dataStream:
            for prevSegment, segment, controlJoint, jointName, endJointName in zip(self.prevFobSegments, 
                                                                                   segmentsFromMoment(moment), 
                                                                                   self.controlJoints[:-1],
                                                                                   self.joints[:-1],
                                                                                   self.joints[1:]):
                while self.paused:
                    return Task.cont

                self.prevFobSegments.pop(0)
                
                exposedJoint = self.actor.exposeJoint(None, "modelRoot", jointName)
                exposedEndJoint = self.actor.exposeJoint(None, "modelRoot", endJointName)
                prevJointSegment = Vec3(exposedEndJoint.getNetTransform().getPos()) - Vec3(exposedJoint.getNetTransform().getPos())

                prevSegment.normalize()
                segment.normalize()
                prevJointSegment.normalize()

                axis = prevJointSegment.cross(segment)
                axis.normalize()

                import logging
#                logging.debug("moment: %s" % (moment,))
#                logging.debug("segment: %s, prevSegment: %s, prevJointSegment: %s" % (segment, prevSegment, prevJointSegment))
#                logging.debug("prevJointSegment: %s" % (prevJointSegment,))
#                logging.debug("axis: %s" % (axis,))
                
                angle = prevSegment.angleRad(segment)

                quat = Quat()
                quat.setFromAxisAngleRad(angle, axis)

                controlJoint.setQuat(controlJoint, quat)

                self.prevFobSegments.append(segment)
            if not self.stopped:
                return Task.cont
            else:
                return Task.done
        return Task.done
Beispiel #3
0
    def _move (self, dt, rd):

        pos = self._pos
        quat = self._quat
        fvel = self._fvel
        tvel = self._tvel

        termspeed = self._termspeed
        gracc = self.world.gravacc
        fspeed = fvel.length()
        fdir = unitv(fvel)
        absdracc = self.world.absgravacc * (fspeed**2 / termspeed**2)
        if fspeed - absdracc * dt < 0.0:
            absdracc = (fspeed / dt) * 0.5
        dracc = fdir * -absdracc
        facc = gracc + dracc
        #facc = Vec3()
        dfpos = fvel * dt + facc * (0.5 * dt**2)
        fvel1 = fvel + facc * dt

        rollspeed = self._rollspeed
        rollrad = self._rollrad
        if rollspeed != 0.0 and rollrad != 0.0:
            rollspeed1 = rollspeed * (1.0 - rd)**2
            rollrad1 = rollrad * (1.0 - rd)**2
            tdir = unitv(tvel) * (sign(rollspeed * rollrad) or 1)
            fdir1 = unitv(fvel1)
            dsroll = rollspeed1 * dt
            dtquat = Quat()
            dtquat.setFromAxisAngleRad(dsroll, fdir)
            tdir1p = Vec3(dtquat.xform(tdir))
            tdir1 = unitv(fdir1.cross(tdir1p).cross(fdir1))
            tspeed1 = rollspeed1 * rollrad1
            dtpos = tvel * dt
            tvel1 = tdir1 * tspeed1
        else:
            dtpos = Vec3()
            dtquat = Quat()
            tvel1 = Vec3()

        pos1 = pos + dfpos + dtpos
        self.node.setPos(pos1)

        fdir1 = unitv(fvel1)
        paxis = fdir.cross(fdir1)
        if paxis.length() > 1e-5:
            paxis.normalize()
            dspitch = fdir.signedAngleRad(fdir1, paxis)
        else:
            paxis = quat.getRight()
            paxis.normalize()
            dspitch = 0.0
        dfquat = Quat()
        dfquat.setFromAxisAngleRad(dspitch, paxis)
        quat1 = quat * dfquat * dtquat
        self.node.setQuat(quat1)

        self._pos = pos1
        self._quat = quat1
        self._fvel = fvel1
        self._tvel = tvel1
Beispiel #4
0
    def move (self, dt):
        # Base override.
        # Called by world at end of frame.

        # Store or pop the turret.
        pos = self.node.getPos()
        pos1 = pos
        vel = Vec3()
        if self._storepos is not None:
            speed = self._storespeed
            tpos = self._storepos if self._stored else self._pos
            dpos = tpos - pos
            tdist = dpos.length()
            if tdist > 1e-3:
                if speed * dt > tdist:
                    speed = tdist / dt
                tdir = unitv(dpos)
                vel = tdir * speed
                pos1 = pos + vel * dt
                stfac = ((pos1 - self._storepos).length() /
                         (self._pos - self._storepos).length())
                stfac = clamp(stfac, 0.0, 1.0)
                if self._storedecof:
                    self._storedecof(stfac)

        # Rotate towards the target intercept direction.
        idir = self._target_intdir
        quat = self._aimref_sviw.getQuat() # to self._aimref_base
        if idir is not None:
            tdir = self._aimref_base.getRelativeVector(self.world.node, idir)
        else:
            tdir = hprtovec(Vec3(self.hcenter, self.pcenter, 0.0))
        fdir = quat.getForward()
        zdir = Vec3(0, 0, 1)
        rdir = unitv(fdir.cross(zdir))

        cturn = atan2(tdir[1], -tdir[0])
        tturn = atan2(fdir[1], -fdir[0])
        dturn = norm_ang_delta(cturn, tturn)

        celev = atan2(fdir[2], fdir.getXy().length())
        telev = atan2(tdir[2], tdir.getXy().length())
        delev = norm_ang_delta(celev, telev)

        turnrate = self.turnrate
        if turnrate * dt > abs(dturn):
            turnrate = abs(dturn) / dt
        turnrate *= sign(dturn)

        elevrate = self.elevrate
        if elevrate * dt > abs(delev):
            elevrate = abs(delev) / dt
        elevrate *= sign(delev)

        angvel = zdir * turnrate + rdir * elevrate

        # Compute new rotation unconstrained.
        angspeed = angvel.length()
        if angspeed > 1e-5:
            adir = unitv(angvel)
            dquat = Quat()
            dquat.setFromAxisAngleRad(angspeed * dt, adir)
            quat1 = quat * dquat
            # Limit to movement arc.
            h, p, r = quat1.getHpr()
            if isinstance(self.harc, tuple):
                harc1, harc2 = self.harc
            else:
                harc1 = self.hcenter - 0.5 * self.harc
                harc2 = self.hcenter + 0.5 * self.harc
            h = pclamp(h, harc1, harc2, -180, 180)
            if isinstance(self.parc, tuple):
                parc1, parc2 = self.parc
            else:
                parc1 = self.pcenter - 0.5 * self.parc
                parc2 = self.pcenter + 0.5 * self.parc
            p = pclamp(p, parc1, parc2, -90, 90, mirror=True)
            hpr1 = Vec3(h, p, r)
        else:
            hpr1 = quat.getHpr()

        self._update_pos_hpr(pos1, hpr1)

        # Needed in base class.
        self._prev_vel = self._vel
        self._vel = vel
        self._acc = (self._vel - self._prev_vel) / dt
        self._prev_angvel = self._angvel
        self._angvel = angvel
        self._angacc = (self._angvel - self._prev_angvel) / dt
Beispiel #5
0
    def __init__ (self, world, name, side, texture=None,
                  pos=None, hpr=None, speed=None, sink=None, damage=None):

        if pos is None:
            pos = Point3()
        if hpr is None:
            hpr = Vec3()
        if sink is None:
            sink = 0.0
        if speed is None:
            speed = 0.0
        pos = Point3(pos[0], pos[1], 0.0)

        self.texture = texture

        if isinstance(self.modelpath, basestring):
            shdmodind = 0
        elif self.modelpath:
            shdmodind = min(len(self.modelpath) - 1, 1)
        else:
            shdmodind = None

        Body.__init__(self,
            world=world,
            family=self.family, species=self.species,
            hitforce=(self.strength * 0.1),
            name=name, side=side,
            modeldata=AutoProps(
                path=self.modelpath, shadowpath=self.shdmodelpath,
                texture=texture, normalmap=self.normalmap,
                glowmap=self.glowmap, glossmap=self.glossmap,
                scale=self.modelscale,
                offset=self.modeloffset, rot=self.modelrot),
            hitboxdata=self.hitboxdata,
            hitlight=AutoProps(),
            hitdebris=self.hitdebris, hitflash=self.hitflash,
            amblit=True, dirlit=True, pntlit=2, fogblend=True,
            obright=True, shdshow=True, shdmodind=shdmodind,
            ltrefl=(self.glossmap is not None),
            pos=pos, hpr=hpr, vel=speed)

        self.maxbracc = self.maxspeed / 4.0

        # Detect shotdown maps.
        self._shotdown_texture = self.texture
        self._shotdown_normalmap = self.normalmap
        self._shotdown_glowmap = self.glowmap if not isinstance(self.glowmap, Vec4) else None
        self._shotdown_glossmap = self.glossmap
        self._shotdown_change_maps = False
        if isinstance(self.modelpath, basestring):
            ref_modelpath = self.modelpath
        elif isinstance(self.modelpath, (tuple, list)):
            ref_modelpath = self.modelpath[0]
        else:
            ref_modelpath = None
        if ref_modelpath:
            ref_modeldir = path_dirname(ref_modelpath)
            ref_modelname = path_basename(ref_modeldir)
            if self.texture:
                test_path = self.texture.replace("_tex.", "_burn.")
                if path_exists("data", test_path):
                    self._shotdown_texture = test_path
                    self._shotdown_change_maps = True
            if self.normalmap:
                test_path = join_path(ref_modeldir,
                                      ref_modelname + "_burn_nm.png")
                if path_exists("data", test_path):
                    self._shotdown_normalmap = test_path
                    self._shotdown_change_maps = True
            if self.glowmap and not isinstance(self.glowmap, Vec4):
                test_path = join_path(ref_modeldir,
                                      ref_modelname + "_burn_gw.png")
                if path_exists("data", test_path):
                    self._shotdown_glowmap = test_path
                    self._shotdown_change_maps = True
            if self.glossmap:
                test_path = join_path(ref_modeldir,
                                      ref_modelname + "_burn_gls.png")
                if path_exists("data", test_path):
                    self._shotdown_glossmap = test_path
                    self._shotdown_change_maps = True

        # Prepare shotdown model.
        self._shotdown_modelnode = None
        if self.sdmodelpath:
            modelchain = self.sdmodelpath
            if isinstance(modelchain, basestring):
                modelchain = [modelchain]
            ret = load_model_lod_chain(
                    world.vfov, modelchain,
                    texture=self._shotdown_texture,
                    normalmap=self._shotdown_normalmap,
                    glowmap=self._shotdown_glowmap,
                    glossmap=self._shotdown_glossmap,
                    shadowmap=self.world.shadow_texture,
                    scale=self.modelscale,
                    pos=self.modeloffset, hpr=self.modelrot)
            lnode, models, fardists = ret[:3]
            lnode.setShader(self.shader)
            self._shotdown_modelnode = lnode
            self._shotdown_models = models
            self._shotdown_fardists = fardists
            for mlevel, model in enumerate(models):
                model.setTwoSided(True)

        # Locally reposition and reorient vehicle such as that
        # all ground contact points have local z-coordinates zero.
        # Do this by first rotating ground contact plane around axis
        # normal to z-axis and to initial ground contact plane normal,
        # until the ground contact plane normal becomes the z-axis,
        # then shift ground contact plane along z-axis to become xy-plane.
        if len(self.groundcontact) != 3:
            raise StandardError(
                "There must be exactly 3 ground contact points.")
        self._platform = self.node.attachNewNode("vehicle-platform")
        gcf, gcl, gcr = self.groundcontact
        gcn = unitv((gcl - gcf).cross(gcr - gcf))
        zdir = Vec3(0, 0, 1)
        graxis = gcn.cross(zdir)
        if graxis.normalize():
            gang = gcn.signedAngleRad(zdir, graxis)
            q = Quat()
            q.setFromAxisAngleRad(gang, graxis)
            self._platform.setQuat(q)
        self._modgndcnts = []
        for rgcp in self.groundcontact:
            rgcp1 = self.node.getRelativePoint(self._platform, rgcp)
            goffz = rgcp1[2] # equal by construction for all points
            rgcp1[2] = 0.0
            self._modgndcnts.append(rgcp1)
        self._platform.setPos(gcn * -goffz)
        self.modelnode.reparentTo(self._platform)

        # Fix vehicle to the ground, according to contact points.
        self.sink = sink
        self._gyro = world.node.attachNewNode("vehicle-gyro-%s" % name)
        gfix = Vehicle._fix_to_ground(self.world, self._gyro,
                                      self._modgndcnts, self.sink,
                                      ptod(pos), vtod(hpr))
        pos1, hpr1 = gfix[:2]
        self.node.setPos(ptof(pos1))
        self.node.setHpr(vtof(hpr1))
        self._prev_gfix = gfix

        tvelg = speed
        self._prev_dyn = (tvelg,)

        width, length, height = self.bbox
        self.size = (length + width + height) / 3
        self._length = length
        self._size_xy = min(width, length)

        # Models for detecting moving parts.
        mvpt_models = list(self.models)
        if base.with_world_shadows and self.shadow_node is not None:
            mvpt_models += [self.shadow_node]
        if self.sdmodelpath:
            mvpt_models += self._shotdown_models

        # Detect turning axles.
        self._axles = []
        for model in mvpt_models:
            axlends = model.findAllMatches("**/axle*")
            for axlend in axlends:
                c1, c2 = axlend.getTightBounds()
                dx, dy, dz = c2 - c1
                wheelrad = 0.5 * (abs(dy) + abs(dz)) / 2
                self._axles.append((axlend, wheelrad))

        # Detect turning tracks.
        # Use ambient light as shader input for uv-scroll.
        self._tracks = []
        for model in mvpt_models:
            tracknds = model.findAllMatches("**/track*")
            for it, tracknd in enumerate(tracknds):
                spdfac = self.trkspdfac[it]
                kwargs = dict(self.shader_kwargs)
                kwargs["uvscrn"] = "INuvscr"
                shader = make_shader(**kwargs)
                tracknd.setShader(shader)
                uvscr = AmbientLight(name=("uvscr-track-%d" % it))
                tracknd.setShaderInput(kwargs["uvscrn"], NodePath(uvscr))
                uvoff = Vec4()
                uvscr.setColor(uvoff)
                self._tracks.append((tracknd, spdfac, uvoff, uvscr))

        # Detect lights.
        # Set up turning on/off through glow factor.
        self._lights = []
        for model in mvpt_models:
            for lnd in model.findAllMatches("**/lights"):
                kwargs = dict(self.shader_kwargs)
                kwargs["glow"] = rgba(255, 255, 255, 1.0)
                kwargs["glowfacn"] = self.world.shdinp.glowfacn
                shader = make_shader(**kwargs)
                lnd.setShader(shader)
                self._lights.append(lnd)
        self.set_lights(on=False)

        if self.engsoundname:
            self.engine_sound = Sound3D(
                path=("audio/sounds/%s.ogg" % self.engsoundname),
                parent=self, maxdist=3000, limnum="hum",
                volume=self.engmaxvol, loop=True, fadetime=2.5)
            self.engine_sound.play()
        else:
            self.engine_sound = None

        self.damage = damage or 0.0

        self.damage_trails = []

        self.launchers = []
        self.turrets = []
        self.decoys = []

        self._prev_path = None
        self._path_pos = 0.0
        self._throttle = 0.0

        # Control inputs.
        self.zero_inputs()

        # Autopilot constants.
        self._ap_adjperiod = 1.03
        self._ap_adjpfloat = 0.2

        # Autopilot state.
        self.zero_ap()

        # Route settings.
        self._route_current_point = None
        self._route_points = []
        self._route_point_inc = 1
        self._route_patrol = False
        self._route_circle = False

        self._state_info_text = None
        self._wait_time_state_info = 0.0

        base.taskMgr.add(self._loop, "vehicle-loop-%s" % self.name)