예제 #1
0
파일: Dynamics.py 프로젝트: Caian/Asparagus
 def mkattach(self, obj, mode = 'p'):
     if mode == 'p':
         dname = Globals.getAttachProp(obj['$.name'], 'd')
         tname = Globals.getAttachProp(obj['$.name'], 'theta')
         # The angle will always be constant and relative to the 
         # angular position of the body
         t = self.symbols.getSymbol(self.name, tname)
         d = self.symbols.getSymbol(self.name, dname, nonnegative=True)
         # (distance from center of mass, angle)
         return (d, t, mode)
     elif mode == 'r':
         xname = Globals.getAttachProp(obj['$.name'], 'x')
         yname = Globals.getAttachProp(obj['$.name'], 'y')
         # Without moment of inertia, the attachment position will be constant 
         x = self.symbols.getSymbol(self.name, xname)
         y = self.symbols.getSymbol(self.name, yname)
         # (x distance from center of mass, y distance from center of mass)
         return (x, y, mode)
     else:
         raise Exception('invalid attachment mode %s' % str(mode))
예제 #2
0
파일: T3Engine.py 프로젝트: Caian/Asparagus
    def loadDynamic(self, name, props, data, aliases):
        dyn = data["dynamic"]
        bodies = [self.getObject(n[0]) for n in data["attach"]]
        attmodes = [n[1] if len(n) > 1 else "p" for n in data["attach"]]
        attoffs = [n[2] if len(n) > 1 else None for n in data["attach"]]
        offs = data["offset"]
        showangles = props.get("showangles", False)

        # A few assert funtions...
        def assert_bodies(name, n):
            if len(bodies) != n:
                raise Exception("%s dynamic expects %d body, provided %d" % (name, n, len(bodies)))

        def assert_offs(name, n):
            if len(offs) != n:
                raise Exception("%s dynamic expects %d offsets, provided %d" % (name, n, len(offs)))

        def aliasify(s, p):
            alias = aliases.get(s, None)
            if alias != None:
                self.aliases[p] = alias
            return str(p)

        # Roll assertions

        def get0Rolls(what):
            roll = props.get("roll", None)
            if roll == None:
                roll = props.get("rolla", None)

            if roll == "1" or roll == "1":
                self.printer.print_diagnostic(2, "dynamic %s does not have roll because it is %s." % (name, what))

        def get1Roll():
            roll = props.get("roll", None)
            if roll == None:
                roll = props.get("rolla", None)

            if roll == "1" or roll == "1":
                self.printer.print_diagnostic(
                    3, "dynamic %s set to roll mode on body %s." % (name, bodies[0]["$.name"])
                )
                roll = True
            else:
                roll = False

            return roll

        def get2Rolls():
            rolla = props.get("rolla", None)
            if rolla == "1" or rolla == "1":
                self.printer.print_diagnostic(
                    3, "dynamic %s set to roll mode on body %s." % (name, bodies[0]["$.name"])
                )
                rolla = True
            else:
                rolla = False

            rollb = props.get("rollb", None)
            if rollb == "1" or rollb == "1":
                self.printer.print_diagnostic(
                    3, "dynamic %s set to roll mode on body %s." % (name, bodies[1]["$.name"])
                )
                rollb = True
            else:
                rollb = False

            return (rolla, rollb)

        # Resolve the attachments
        for b, m, o in zip(bodies, attmodes, attoffs):
            if o != None:
                if m == "p":
                    ata = Globals.getAttachProp(b["$.name"], "d")
                    atb = Globals.getAttachProp(b["$.name"], "theta")
                elif m == "r":
                    ata = Globals.getAttachProp(b["$.name"], "x")
                    atb = Globals.getAttachProp(b["$.name"], "y")

                self.symbols.addReplacement(name, ata, o[0])
                self.symbols.addReplacement(name, atb, o[1])

        # Switch the dynamic type
        if dyn == "force":
            assert_bodies("force", 1)
            assert_offs("force", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            att = (bodies[0], attmodes[0])

            # Constant Force has only one roll
            roll = get1Roll()

            d = Dynamics.ForceDynamic(name, att, roll, self.symbols)

            t = aliasify("theta", d.theta)
            title = aliasify("F", d.getFSym())

        elif dyn == "weight":
            # TODO ignore offset and force it to center of mass
            assert_bodies("weight", 1)
            assert_offs("weight", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            # Weight Force only has an att if the center of mass is different
            # from the fixture point, which means the translation axes MUST
            # be fixed, enforce this rule

            # By default the attachment must be zero even if nothing is
            # specified (center of mass assumed)
            mustlock = True

            # Enforce att lock if the axes are not
            if not isTimeConstant(bodies[0]["tr.x"], self.symbols) or not isTimeConstant(
                bodies[0]["tr.y"], self.symbols
            ):
                if attoffs[0] != None:
                    self.printer.print_diagnostic(
                        2,
                        "offset for %s will be ignored because the body %s is not locked in x and y."
                        % (name, bodies[0]["$.name"]),
                    )
            else:
                if attoffs[0] != None:
                    mustlock = False

            if mustlock:
                attmodes[0] = "p"
                ata = Globals.getAttachProp(b["$.name"], "d")
                atb = Globals.getAttachProp(b["$.name"], "theta")
                self.symbols.addReplacement(name, ata, 0)
                self.symbols.addReplacement(name, atb, 0)

            att = (bodies[0], attmodes[0])

            # Weight Force only has no rolls :/

            get0Rolls("weight")

            d = Dynamics.WeightDynamic(name, att, self.symbols)

            title = str(d.getFSym())
            showangles = False  # Do not show theta for gravity

        elif dyn == "rod":
            assert_bodies("rod", 2)
            assert_offs("rod", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            att0 = (bodies[0], attmodes[0])
            att1 = (bodies[1], attmodes[1])

            # Rod has two rolls, for a and b points
            rolla, rollb = get2Rolls()

            d = Dynamics.RodDynamic(name, att0, rolla, att1, rollb, self.symbols)

            aliasify("l", d.l)
            t = aliasify("thetaa", d.thetaa)
            title = aliasify("T", d.getTSym())

        elif dyn == "spring":
            assert_bodies("spring", 2)
            assert_offs("spring", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            att0 = (bodies[0], attmodes[0])
            att1 = (bodies[1], attmodes[1])

            # Spring has two rolls, for a and b points
            rolla, rollb = get2Rolls()

            d = Dynamics.SpringDynamic(name, att0, rolla, att1, rollb, self.symbols)

            aliasify("l", d.l)
            aliasify("d", d.d)
            aliasify("T", d.getTSym())
            t = aliasify("thetaa", d.thetaa)
            title = aliasify("k", d.k)

        elif dyn == "dampener":
            assert_bodies("dampener", 2)
            assert_offs("dampener", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            att0 = (bodies[0], attmodes[0])
            att1 = (bodies[1], attmodes[1])

            # Dampener has two rolls, for a and b points
            rolla, rollb = get2Rolls()

            d = Dynamics.DampenerDynamic(name, att0, rolla, att1, rollb, self.symbols)

            aliasify("l", d.l)
            aliasify("d", d.d)
            aliasify("T", d.getTSym())
            t = aliasify("thetaa", d.thetaa)
            title = aliasify("b", d.b)

        elif dyn == "torque":
            assert_bodies("torque", 1)
            assert_offs("torque", 2)

            flipped = int(props.get("direction", 1))
            flipped = flipped != 0

            pos = (offs["x1"], offs["y1"])

            # Angular dynamics have no rolls
            get0Rolls()

            d = Dynamics.TorqueDynamic(name, obj, flipped, self.symbols)

            title = aliasify("k", d.k)

        elif dyn == "angularspring":
            assert_bodies("angularspring", 1)
            assert_offs("angularspring", 2)

            pos = (offs["x1"], offs["y1"])

            # Angular dynamics have no rolls
            get0Rolls()

            d = Dynamics.AngularSpringDynamic(name, obj, self.symbols)

            title = aliasify("k", d.k)

        elif dyn == "angulardampener":
            assert_bodies("angulardampener", 1)
            assert_offs("angulardampener", 2)

            pos = (offs["x1"], offs["y1"])

            # Angular dynamics have no rolls
            get0Rolls()

            d = Dynamics.AngularDampenerDynamic(name, obj, self.symbols)

            title = aliasify("b", d.b)

        elif dyn == "belt":
            assert_bodies("belt", 2)
            assert_offs("belt", 4)

            pos = (offs["x1"], offs["y1"], offs["x2"], offs["y2"])

            att0 = (bodies[0], attmodes[0])
            att1 = (bodies[1], attmodes[1])

            # Angular dynamics have no rolls
            get0Rolls()

            d = Dynamics.BeltDynamic(name, att0, att1, self.symbols)

            title = aliasify("b", d.b)

        else:
            raise Exception("unknown dynamic type %s" % dyn)

        # Add dynamic to the list of dynamic in the scene
        self.scene["dynamics"].append(d)

        # Add dynamic to the collection of dynamics of each body
        for body in bodies:
            self.scene["attachments"][body["$.name"]].append(d)

        # Draw the dynamic
        self.printer.print_dynamic(name, dyn, pos, title, props)

        # Draw the angle of the dynamic, if specified
        if showangles == "1" or showangles == True:
            self.printer.print_angle(name, t)