示例#1
0
    def integrate(self, duration):
        '''
            method which updates the particle properties each time step
            ---------
            args:
                duration - double - duration of time step
        '''

        assert (duration > 0)
        #update position by velocity
        # Pn = Pn-1 + v*t
        self.position.addScaledVector(self.velocity, duration)

        #Calculate acceleration from force
        resultAcceleration = Vector(self.acceleration.x, self.acceleration.y,
                                    self.acceleration.z)
        resultAcceleration.addScaledVector(self.forceAccum, self.inverseMass)

        #update velocity using acceleration
        self.velocity.addScaledVector(resultAcceleration, duration)

        #Calculate drag
        self.velocity *= self.damping**duration

        #clear all forces
        self.clearAccumulator()
示例#2
0
    def create(self, firework, parent=None):
        '''
            create a firework and optionally apply a parent to it
            ---------
            args:
                firework - Firework        - Firework to be filled 
                parent   - Firework = None - Parent of firework if it is a child (payload)
        '''

        firework.type = self.type
        firework.age = uniform(self.minAge, self.maxAge)
        velocity = Vector(0, 0, 0)
        firework.ball.visible = True

        if (parent):
            pos = parent.getPosition()
            firework.setPosition(pos.x, pos.y, pos.z)
            velocity += parent.getVelocity()
        else:
            randposx = uniform(0, 50)
            randposy = uniform(0, 100)
            firework.setPosition(randposx, randposy, 0)

        randx = uniform(self.minVelocity.x, self.maxVelocity.x)
        randy = uniform(self.minVelocity.y, self.maxVelocity.y)
        randz = uniform(self.minVelocity.z, self.maxVelocity.z)

        velocity += Vector(randx, randy, randz)
        firework.setVelocity(velocity.x, velocity.y, velocity.z)
        firework.setMass(1)
        firework.setDamping(self.damping)
        firework.setAcceleration(0, 0, -20)
        #Acceleration due to gravity
        firework.clearAccumulator()
示例#3
0
    def initiateFireworkRule(self):
        '''
            Method which stores all rules for simulation
        '''

        rule = FireworkRule(1, 0.5, 2.1, Vector(-5, -5, 25), Vector(5, 5, 28),
                            0.8, 2)
        rule.payloads.append(FireworkRule.PayLoad(3, 5))
        rule.payloads.append(FireworkRule.PayLoad(5, 1))
        self.rules.append(rule)

        rule = FireworkRule(2, 0.5, 1, Vector(-5, -5, 20), Vector(5, 5, 30),
                            0.1, 1)
        rule.payloads.append(FireworkRule.PayLoad(4, 7))
        self.rules.append(rule)

        rule = FireworkRule(3, 0.5, 3, Vector(-20, 10, 40), Vector(5, 20, 80),
                            0.2, 0)
        self.rules.append(rule)

        rule = FireworkRule(4, 0.2, 2.1, Vector(-20, 5, 50), Vector(20, 5, 95),
                            0.2, 0)
        self.rules.append(rule)

        rule = FireworkRule(5, 0.2, 1.7, Vector(-20, 5, 5), Vector(20, 5, 30),
                            0.2, 2)
        rule.payloads.append(FireworkRule.PayLoad(2, 2))
        rule.payloads.append(FireworkRule.PayLoad(3, 3))
        self.rules.append(rule)
示例#4
0
 def __init__(self):
     '''
         Class constractor
     '''
     self.particles = [None] * 2
     self.restitution = 0
     self.contactNormal = Vector(0, 0, 0)
     self.penetration = 0
     self.particleMovement = [Vector(0, 0, 0), Vector(0, 0, 0)]
示例#5
0
    def __mul__(self, o):
        '''
            operation overload for * operator 
                - returns a 3x3 Matrix if o is Matrix3
                - return a vector if o is a Vector
            ---------
            args:
                o - Matrix3
                o - Vector 
        '''

        if isinstance(o, Matrix3):
            return Matrix3(\
                self.data[0]*o.data[0] + self.data[1]*o.data[3] + self.data[2]*o.data[6],\
                self.data[0]*o.data[1] + self.data[1]*o.data[4] + self.data[2]*o.data[7],\
                self.data[0]*o.data[2] + self.data[1]*o.data[5] + self.data[2]*o.data[8],\

                self.data[3]*o.data[0] + self.data[4]*o.data[3] + self.data[5]*o.data[6],\
                self.data[3]*o.data[1] + self.data[4]*o.data[4] + self.data[5]*o.data[7],\
                self.data[3]*o.data[2] + self.data[4]*o.data[5] + self.data[5]*o.data[8],\

                self.data[6]*o.data[0] + self.data[7]*o.data[3] + self.data[8]*o.data[6],\
                self.data[6]*o.data[1] + self.data[7]*o.data[4] + self.data[8]*o.data[7],\
                self.data[6]*o.data[2] + self.data[7]*o.data[5] + self.data[8]*o.data[8]
                )
        else:
            return Vector(\
               o.x * self.data[0] + o.y * self.data[1] + o.z * self.data[2],\
               o.x * self.data[3] + o.y * self.data[4] + o.z * self.data[5],\
               o.x * self.data[6] + o.y * self.data[7] + o.z * self.data[8])
示例#6
0
    def getAcceleration(self):
        '''
            Returns a new vector which represents the acceleration of the particle
        '''

        return Vector(self.acceleration.x, self.acceleration.y,
                      self.acceleration.z)
示例#7
0
    def getAxisVector(self, i):
        '''
            Return a new vector representing a column in this matrix
            ---------
            args:
                i - int - index of column
        '''

        return Vector(self.data[i], self.data[i + 4], self.data[i + 8])
示例#8
0
    def transformInverse(self, vector):
        '''
            Return a new vector of the transform of the given direction vector by transformational inverse of this matrix
            It is assumed that this matrix is a pure rotation matrix (inverse is transpose)
            ---------
            args:
                vector - Vector 
        '''

        tmp = Vector(vector.x, vector.y, vector.z)
        tmp.x -= self.data[3]
        tmp.y -= self.data[7]
        tmp.z -= self.data[11]
        return Vector(
            tmp.x * self.data[0] + tmp.y * self.data[4] + tmp.z * self.data[8],
            tmp.x * self.data[1] + tmp.y * self.data[5] + tmp.z * self.data[9],
            tmp.x * self.data[2] + tmp.y * self.data[6] +
            tmp.z * self.data[10])
示例#9
0
    def getAxisVector(self, i):
        '''
            return a vector representing an a column in this matrix
            ---------
            args:
                i - int - number of column to return    
        '''

        return Vector(self.data[i], self.data[i + 3], self.data[i + 6])
示例#10
0
    def getRowVector(self, i):
        '''
            return a vector representing row i in this matrix
            ---------
            args:
                i - int - number of row to return    
        '''

        return Vector(self.data[i * 3], self.data[i * 3 + 1],
                      self.data[i * 3 + 2])
示例#11
0
    def __mul__(self, o):
        '''
            operation overload for * operator 
                - returns a 3x4 Matrix if o is Matrix4
                - return a vector if o is a Vector
            ---------
            args:
                o - Matrix4
                o - Vector 
        '''

        if isinstance(o, Matrix4):
            result = Matrix4()
            result.data[0] = (o.data[0] * self.data[0]) + (
                o.data[4] * self.data[1]) + (o.data[8] * self.data[2])
            result.data[4] = (o.data[0] * self.data[4]) + (
                o.data[4] * self.data[5]) + (o.data[8] * self.data[6])
            result.data[8] = (o.data[0] * self.data[8]) + (
                o.data[4] * self.data[9]) + (o.data[8] * self.data[10])

            result.data[1] = (o.data[1] * self.data[0]) + (
                o.data[5] * self.data[1]) + (o.data[9] * self.data[2])
            result.data[5] = (o.data[1] * self.data[4]) + (
                o.data[5] * self.data[5]) + (o.data[9] * self.data[6])
            result.data[9] = (o.data[1] * self.data[8]) + (
                o.data[5] * self.data[9]) + (o.data[9] * self.data[10])

            result.data[2] = (o.data[2] * self.data[0]) + (
                o.data[6] * self.data[1]) + (o.data[10] * self.data[2])
            result.data[6] = (o.data[2] * self.data[4]) + (
                o.data[6] * self.data[5]) + (o.data[10] * self.data[6])
            result.data[10] = (o.data[2] * self.data[8]) + (
                o.data[6] * self.data[9]) + (o.data[10] * self.data[10])

            result.data[3] = (o.data[3] * self.data[0]) + (
                o.data[7] * self.data[1]) + (o.data[11] *
                                             self.data[2]) + self.data[3]
            result.data[7] = (o.data[3] * self.data[4]) + (
                o.data[7] * self.data[5]) + (o.data[11] *
                                             self.data[6]) + self.data[7]
            result.data[11] = (o.data[3] * self.data[8]) + (
                o.data[7] * self.data[9]) + (o.data[11] *
                                             self.data[10]) + self.data[11]

            return result
        else:
            return Vector(
                o.x * self.data[0] + o.y * self.data[1] + o.z * self.data[2] +
                self.data[3], o.x * self.data[4] + o.y * self.data[5] +
                o.z * self.data[6] + self.data[7], o.x * self.data[8] +
                o.y * self.data[9] + o.z * self.data[10] + self.data[11])
示例#12
0
    def transformTranspose(self, vector):
        '''
            Transform a vector by transpose of this matrix
            ---------
            args:
                vector - Vector   
        '''

        return Vector(
            vector.x * self.data[0] + vector.y * self.data[3] +
            vector.z * self.data[6], vector.x * self.data[1] +
            vector.y * self.data[4] + vector.z * self.data[7],
            vector.x * self.data[2] + vector.y * self.data[5] +
            vector.z * self.data[8])
示例#13
0
    def transformDirection(self, vector):
        '''
            Return a new vector of the transform of the given direction vector by this matrix.
            ---------
            args:
                vector - Vector 
        '''

        return Vector(
            vector.x * self.data[0] + vector.y * self.data[1] +
            vector.z * self.data[2], vector.x * self.data[4] +
            vector.y * self.data[5] + vector.z * self.data[6],
            vector.x * self.data[8] + vector.y * self.data[9] +
            vector.z * self.data[10])
示例#14
0
 def transformInverseDirection(self, vector):
     '''
         Return a new vector of the transform of the given direction vector by inverse of this matrix
         It is assumed that this matrix is a pure rotation matrix (inverse is transpose)
         ---------
         args:
             vector - Vector 
     '''
     return Vector(
         vector.x * self.data[0] + vector.y * self.data[4] +
         vector.z * self.data[8], vector.x * self.data[1] +
         vector.y * self.data[5] + vector.z * self.data[9],
         vector.x * self.data[2] + vector.y * self.data[6] +
         vector.z * self.data[10])
示例#15
0
    def __init__(self):
        '''
            Class constractor
        '''

        self.position = Vector(0, 0, 0)
        self.velocity = Vector(0, 0, 0)
        self.acceleration = Vector(0, 0, 0)
        #Daming is used to make the paricle lose energy
        #damping = 0 -> object stops, damping = 1 -> velocity doesnt change
        self.damping = 1
        #inverse mass = 0 -> infinte mass whichis dealt to immovable objects
        #inverse mass = infinity -> object is super fast (which is not useful in games)
        self.inverseMass = 0
        #the value of the forceAccum is zeroed in each intergration step
        self.forceAccum = Vector(0, 0, 0)
示例#16
0
    def addContact(self, contacts, limit, iterator):
        '''
            Fills the given contact structure with the generated
            contact and return the number of contacts that have been written.
        ---------
            args:
                contacts - list - particle on which the force is applied
                limit    - int  - maximum number of contacts in the array that can be written to
                iterator - int  - index to contact to access in the contacts array  
        '''

        count = 0
        for particle in self.particles:
            y = particle.getPosition().y
            if y < 0:
                contacts[iterator].contactNormal = Vector(0, 1, 0)
                contacts[iterator].particles[0] = particle
                contacts[iterator].particles[1] = None
                contacts[iterator].penetration = -y
                contacts[iterator].restitution = 0
                count += 1
                iterator += 1
                if (count >= limit): return count
        return count
示例#17
0
    def getPosition(self):
        '''
            Returns a new vector which represents the location of the particle
        '''

        return Vector(self.position.x, self.position.y, self.position.z)
示例#18
0
class Particle:
    '''
        Class responsible for simulating particle behaviour
        ---------
        properties:
            position - Vector - represent location of particle in 3D space
            velocity - Vector - represent velocity of particle in 3 axes
            acceleration - Vector - represent acceleration of particle in 3 axes
            damping - double - represent damping applied to velocity of particle each time step
            inverseMass - double - store inverse mass of particle 
            forceAccum - vector - represent force applied to particle in the next time step only
        ---------
        methods:
            setters & getters
            integrate - Update the particle properties each time step
            hasFiniteMass - Return true if object is movable
            clearAccumulator - clears the force applied to the particle in this time step
            addForce - add force to the forceAccum in this time step
    '''
    def __init__(self):
        '''
            Class constractor
        '''

        self.position = Vector(0, 0, 0)
        self.velocity = Vector(0, 0, 0)
        self.acceleration = Vector(0, 0, 0)
        #Daming is used to make the paricle lose energy
        #damping = 0 -> object stops, damping = 1 -> velocity doesnt change
        self.damping = 1
        #inverse mass = 0 -> infinte mass whichis dealt to immovable objects
        #inverse mass = infinity -> object is super fast (which is not useful in games)
        self.inverseMass = 0
        #the value of the forceAccum is zeroed in each intergration step
        self.forceAccum = Vector(0, 0, 0)

    def integrate(self, duration):
        '''
            method which updates the particle properties each time step
            ---------
            args:
                duration - double - duration of time step
        '''

        assert (duration > 0)
        #update position by velocity
        # Pn = Pn-1 + v*t
        self.position.addScaledVector(self.velocity, duration)

        #Calculate acceleration from force
        resultAcceleration = Vector(self.acceleration.x, self.acceleration.y,
                                    self.acceleration.z)
        resultAcceleration.addScaledVector(self.forceAccum, self.inverseMass)

        #update velocity using acceleration
        self.velocity.addScaledVector(resultAcceleration, duration)

        #Calculate drag
        self.velocity *= self.damping**duration

        #clear all forces
        self.clearAccumulator()

    def setMass(self, mass):
        '''
            method which set mass particle properties each time step
            ---------
            args:
                mass - double - mass of the object, cannot be zero
        '''

        assert (mass != 0)
        self.inverseMass = 1 / mass

    def getMass(self):
        if self.inverseMass == 0:
            return float_info.max
        else:
            return 1 / self.inverseMass

    def setInverseMass(self, inverseMass):
        self.inverseMass = inverseMass

    def getInverseMass(self):
        return self.inverseMass

    def hasFiniteMass(self):
        if self.inverseMass >= 0:
            return True
        return False

    def setDamping(self, damping):
        self.damping = damping

    def getDamping(self):
        return self.damping

    def setPosition(self, x, y, z):
        self.position.x = x
        self.position.y = y
        self.position.z = z

    def getPosition(self):
        '''
            Returns a new vector which represents the location of the particle
        '''

        return Vector(self.position.x, self.position.y, self.position.z)

    def setVelocity(self, x, y, z):
        self.velocity.x = x
        self.velocity.y = y
        self.velocity.z = z

    def getVelocity(self):
        '''
            Returns a new vector which represents the velocity of the particle
        '''

        return Vector(self.velocity.x, self.velocity.y, self.velocity.z)

    def setAcceleration(self, x, y, z):
        self.acceleration.x = x
        self.acceleration.y = y
        self.acceleration.z = z

    def getAcceleration(self):
        '''
            Returns a new vector which represents the acceleration of the particle
        '''

        return Vector(self.acceleration.x, self.acceleration.y,
                      self.acceleration.z)

    def clearAccumulator(self):
        '''
            Clears the accumulated force on the particle
        '''

        self.forceAccum.clear()

    def addForce(self, force):
        '''
            Add force to the accumulated force on the object
            ---------
            args:
                force - Vector - additional force applied to the particle
        '''

        self.forceAccum += force

    def __str__(self):
        return "position: " + str(self.position) + "\n" \
               "velocity: " + str(self.velocity) + "\n" \
               "acceleration: " + str(self.acceleration) + "\n" \
               "force: " + str(self.forceAccum) + "\n" \
               "damping: " + str(self.damping) + "\n" \
               "mass: " + str(self.getMass()) + "n"
示例#19
0
    def getVelocity(self):
        '''
            Returns a new vector which represents the velocity of the particle
        '''

        return Vector(self.velocity.x, self.velocity.y, self.velocity.z)