void GravitationalForce::apply_fun(float d_t){ for (unsigned int i = 0; i < mInfluencedPhysics.size()-1; i++){ Physics* lhs = mInfluencedPhysics[i]; for (unsigned int j = i+1 ; j < mInfluencedPhysics.size(); j++){ Physics* rhs = mInfluencedPhysics[j]; Vector3 distanceVector = rhs->getPosition()-lhs->getPosition(); float distance = distanceVector.length(); //Distanz in Ordnung if (distance < getMaxDistance() && distance >= 1.0){ if(distance < 1){ distance = 1; } distanceVector.normalize(); //Anziehungskraft berechnen float force = mScale * (rhs->getMass()*lhs->getMass() / (distance*distance)); //Anziehungskraft in Ordnung if (force > getMinForce()){ Vector3 Rhs_forceVector = distanceVector; Rhs_forceVector *= force; //Anziehungskraft um d_t skaliert anwenden lhs->applyForce(Rhs_forceVector*d_t); Vector3 Lhs_forceVector = (-1.0) * distanceVector; Lhs_forceVector *= force; //Anziehungskraft um d_t skaliert anwenden rhs->applyForce(Lhs_forceVector*d_t); } } } } }
void DampedSpring::apply_fun(float d_t){ for (unsigned int i = 0; i < mPairs.size(); i++){ Physics* lhs = mInfluencedPhysics[mPairs[i].i]; Physics* rhs = mInfluencedPhysics[mPairs[i].j]; Vector3 pos_lhs = lhs->getPosition(); Vector3 pos_rhs = rhs->getPosition(); Vector3 pos_dif = (pos_rhs-pos_lhs); Vector3 vel_dif = rhs->getVelocity()-lhs->getVelocity(); float pos_dif_length = pos_dif.length(); //Tension --> "Gespanntheit" Berücksichtigt Länge der Feder in Ruheposition float tension = pos_dif_length-mRestLength; Vector3 f_b = pos_dif; f_b.normalize(); f_b *= (mSpringConstant * tension + mDampConstant * ((vel_dif * pos_dif) / pos_dif_length))*d_t; Vector3 f_a = (-1.0) * f_b; lhs->applyForce(f_b); rhs->applyForce(f_a); } }
// Run by GLUT every [tickspeed] miliseconds void tick(int in) { // Local handles to objects Level *currentLevel = levelController->getCurrentLevel(); Ball *ball = currentLevel->getBall(); Physics *physics = ball->getPhysics(); Tile* currentTile = currentLevel->getTile(ball->getCurrentTileID()); vector<int> borderIDs = currentTile->getNeighborIDs(); vector<Shape*> borderShapes = currentTile->getBorders()->getInwardShapes(); vec3 ballPosition = physics->getPosition(); // Debug -- Highlight current tile if (DEBUG_TILE_PAINT) { currentTile->getShapes()[0]->changeColor(TILE_HIGHLIGHT_COLOR); currentTile->getShapes()[0]->reload(); } // Collision with cup glm::vec3 ballPos = physics->getPosition(); glm::vec3 cupPos = currentLevel->getCup()->getPhysics()->getPosition(); float cupPlaneDist = sqrt(((ballPos.x - cupPos.x)*(ballPos.x - cupPos.x)) + ((ballPos.z - cupPos.z)*(ballPos.z - cupPos.z))); if(cupPlaneDist < (CUP_RADIUS - (0.8 * BALL_RADIUS)) && abs(cupPos.y - ballPos.y) <= 1.1*BALL_OFFSET){ // allow for slight error //Play SFX for falling in hole sound->getEngine()->play2D("sfx/retro_cup.wav"); //----------------CHANGE TO NEXT HOLE----------------// nextHole(); } // Physics and collision calculations vec3 newDirection = physics->getDirection(); // used for tile transitions if(ballMoving) { // Check for collision if(detectCollisions(currentTile, physics, sound)){ newDirection = physics->getDirection(); } // Update ball direction newDirection = updateBallDirection(levelController, sound); // Update current tile currentTile = currentLevel->getTile(ball->getCurrentTileID()); // Update ball speed double ballSpeed = physics->getSpeed(); if(currentTile->getShapes().at(0)->normals()[0] == glm::vec3(0.0,1.0,0.0)){ // flat tile if(ballSpeed > 0.01){ physics->setSpeed(ballSpeed - TILE_DEFAULT_FRICTION); ballSpeed = physics->getSpeed(); } else{ physics->setSpeed(0.0); ballStopped(); } } else if(newDirection.y > 0){ // going up hill //cout << endl << "UP"; //cout << "Direction y-value: " << newDirection.y << endl; if(ballSpeed > 0.01){ physics->setSpeed(ballSpeed - (TILE_DEFAULT_FRICTION + (2.0*currentTile->getSlope()*TILE_DEFAULT_FRICTION))); ballSpeed = physics->getSpeed(); } } else{ // going down hill //cout << endl << "DOWN"; //cout << "Direction y-value: " << newDirection.y << endl; if(ballSpeed <= (100.0/100.1)){ physics->setSpeed(ballSpeed + TILE_DEFAULT_FRICTION); } else{ // clmap speed ballSpeed = (100.0/100.1); } } // Update ballPosition physics->updatePosition(); // Update shape using velocity Shape* ballShape = ball->getShapes().at(0); ballShape->translate(physics->getVelocity()); // Update ball direction physics->setDirection(newDirection); // Snap ball to correct y value -- hacky if(currentTile->getShapes().at(0)->normals()[0] == glm::vec3(0.0,1.0,0.0)){ // flat tile if(physics->getPosition().y != (currentTile->getPhysics()->getPosition().y + BALL_OFFSET)){ // Snap ball shape ball->getShapes()[0]->translate(vec3(0.0, -(physics->getPosition().y), 0.0)); ball->getShapes()[0]->translate(vec3(0.0, (currentTile->getPhysics()->getPosition().y + BALL_OFFSET), 0.0)); // Update ball physics physics->setPosition(vec3(physics->getPosition().x, (currentTile->getPhysics()->getPosition().y + BALL_OFFSET), physics->getPosition().z)); } } else{// sloped tile float correctY = currentTile->getShapes()[0]->yValueAtPoint(physics->getPosition().x, physics->getPosition().z); if(physics->getPosition().y != correctY){ // Snap ball shape ball->getShapes()[0]->translate(vec3(0.0, -(physics->getPosition().y), 0.0)); ball->getShapes()[0]->translate(vec3(0.0, correctY, 0.0)); // Update ball physics physics->setPositionY(correctY); } } // Reload shape ballShape->reload(); } // Update HUD currentLevel = levelController->getCurrentLevel(); updateHUD(currentLevel->getLevelName(), fileIO->getNumHoles(), currentHoleScore, currentLevel->getPar()); //If controls are enabled (ball not yet launched), then make ball direction equal to launchVector if (angleSpinner->enabled) { float launchAngleRadians = launchAngle * (PI/180); launchVector = normalize(vec3(sin(launchAngleRadians), 0.0, cos(launchAngleRadians))); updateCamera(physics->getPosition(), launchVector, false); } else { updateCamera(physics->getPosition(), physics->getDirection(), true); } glutTimerFunc(tickSpeed, tick, 0); }