void PhysicsBody::setMass(float mass)
{
    if (mass <= 0)
    {
        return;
    }

    int oldMass = _mass;
    _mass = mass;
    _massDefault = false;
    
    // update density
    if (_mass == PHYSICS_INFINITY)
    {
        _density = PHYSICS_INFINITY;
    }
    else
    {
        if (_area > 0)
        {
            _density = _mass / _area;
        }else
        {
            _density = 0;
        }
    }
    
    // the static body's mass and moment is always infinity
    if (_dynamic)
    {
        updateMass(oldMass, _mass);
    }
}
Exemple #2
0
// This must be called at the start of every loop.
void movementStart() {
    // Setting motion data:
    api.getMyZRState(ZRState);
    //api.getOtherZRState(OZRState);
    for (int i = 0; i < 3; i++) {
        position[i] = ZRState[i];
        velocity[i] = ZRState[i + 3];
    }
    mathVecSubtract(acceleration, velocity, lastVelocity, 3);
    updateMass();
    lastForceMagnitude = 0.f; // Very important in mass calculation [Positioning in loop included].
}
Exemple #3
0
ZPunctum::ZPunctum()
  : m_score(1.0)
{
  setColor(255, 255, 0, 255);
  setX(-1);
  setY(-1);
  setZ(-1);
  setRadius(2.0);
  setMaxIntensity(255);
  setMeanIntensity(255);
  setSDevOfIntensity(0);
  updateVolSize();
  updateMass();
}
Exemple #4
0
ZPunctum::ZPunctum(double x, double y, double z, double r)
  : m_score(1.0)
{
  setColor(255, 255, 0, 255);
  setX(x);
  setY(y);
  setZ(z);
  setRadius(r);
  setMaxIntensity(255);
  setMeanIntensity(255);
  setSDevOfIntensity(0);
  updateVolSize();
  updateMass();
}
void PhysicsBody::addMass(float mass)
{
    float oldMass = _mass;
    
    if (mass == PHYSICS_INFINITY)
    {
        _mass = PHYSICS_INFINITY;
        _massDefault = false;
        _density = PHYSICS_INFINITY;
    }
    else if (mass == -PHYSICS_INFINITY)
    {
        return;
    }
    else
    {
        if (_massDefault)
        {
            _mass = 0;
            _massDefault = false;
        }
        
        if (_mass + mass > 0)
        {
            _mass +=  mass;
        }else
        {
            _mass = MASS_DEFAULT;
            _massDefault = true;
        }
        
        if (_area > 0)
        {
            _density = _mass / _area;
        }
        else
        {
            _density = 0;
        }
    }
    
    // the static body's mass and moment is always infinity
    if (_dynamic)
    {
        updateMass(oldMass, _mass);
    }
}
void ColaMintBottle::setBottleStatus(BottleStatus aNewStat)
{
    switch (aNewStat) {
    case UNTRIGGERED:
        // allow to set arbitrary 'volume' of the fluid in the bottle
        // it doesn't afffect the size, though - magic :-D
        theProps.property2Float(Property::MASS_STRING, &theColaAmount);
        updateMass();
        theSplatterCount = 0;
        theBottleStatus = UNTRIGGERED;
        break;
    case TRIGGERED:
        theBottleStatus = TRIGGERED;
        theCountdown = 100;
        break;
    case BLOWING:
        theBottleStatus = BLOWING;
        break;
    case EMPTY:
        theBottleStatus = EMPTY;
        break;
    }
}
void ColaMintBottle::newSplatter(unsigned int aSequenceNr)
{
    // the first splatter is to reach 1.5m height, improving to 2.5m with the 20th
    // then deteriorating quickly - until none left
    //
    // for simplicity, we assume that a horizontal bottle has the same
    // exit velocity and such...
    //
    // the opening exit velocity can be calculated using energy:  m*g*h = 0.5*m*v*v
    // i.e.  v = sqrt(2*g*h)    <- note that the mass of the splatter is not in there

    // so we need a 2nd order equation that starts at (0, 1.5), reaches (20,2.5)
    // and then decays until (40, 1.5) again.
    // then we use a linear equation for the remainder
    //
    //   h=height, n=splatternumber
    // i.e. h = -1/400*n*n + 1/10*n + 1.5
    // and from 40 onwards:
    //      h = 1.5 - 3*(n-40)/220
    //
    // TODO/FIXME: there is a discontinuity in h' - that can be fixed by calculating
    // the point where the extension of h' goes through (150,0) -> for later :-)

    std::shared_ptr<ColaSplatter> mySplatterPtr =
        ObjectFactory::createChildObject<ColaSplatter>();

    // Start position for the splatter is above the opening:
    // i.e. (0, +0.59*object height). The magic number 0.59 is "slightly more than 1/2"...
    // I figured out the number by experiment
    const qreal SPLATTER_START = 0.60;
    Position myStartPos = getTempCenter();
    myStartPos = myStartPos + Vector(0, SPLATTER_START * getTheHeight());
    // we need this 90 degrees because the bottle is modelled vertical,
    // not horizontal
    myStartPos.angle += PI / 2.0;

    // departure velocity
    qreal myH;
    if (aSequenceNr < 40)
        myH = (-1 / 400) * aSequenceNr * aSequenceNr + 0.1 * aSequenceNr + 1.5;
    else
        myH = 1.5 - 3 * (aSequenceNr - 40) / 220;

    // if the expected height is less than 0, we're no longer blowing
    if (myH < 0.0)
        return;

    // note: hardcoded constant for G here, because we're using constants from the
    // normal world to calculate it - not related to the G in a alternative world.
    // (otherwise, the cola bottle would blow as high on the moon as on earth)
    qreal myV = sqrt(2.0 * 9.81 * myH);
    const qreal mySplatterMass = 0.015;
    mySplatterPtr->setAll(myStartPos, myV, mySplatterMass);
    theWorldPtr->addObject(mySplatterPtr);

    theColaAmount -= mySplatterMass;
    updateMass();

    // Small HACK :-)
    // if we're out-of-bounds, let's misuse the thrust to limit the velocity...
    // this will have two effects:
    //   1) the last splatter (giving impulse to a nearly-empty bottle) won't work
    //   2) and using thrust in the wrong direction actually limits speed!
    if (myStartPos.x > 1.4 * theWorldPtr->getTheWorldWidth() ||
            myStartPos.y > 1.4 * theWorldPtr->getTheWorldHeight()) {
        if (theThrust > 0)
            theThrust = - 0.7;
    }

    // and don't forget Newton's action = -reaction !!!
    qreal myImpulse = mySplatterMass * myV;
    // HACK HACK HACK: to improve the "feeling", we help the impulse a bit here...
    // The Thrust is actually adjustable as a property
    // - default is 2.0 (see createPhysicsObject()).
    qreal myAngle = getTempCenter().angle;
    Vector myImpulseVector = -theThrust * Vector(-myImpulse * sin(myAngle), myImpulse * cos(myAngle));
    theB2BodyPtr->ApplyLinearImpulse(myImpulseVector.toB2Vec2(), myStartPos.toB2Vec2(), true);
}