src/proto2/Physics.cc
author terom
Tue, 18 Nov 2008 22:58:50 +0000
branchno-netsession
changeset 35 e21cfda0edde
child 41 ca80cd67785d
permissions -rw-r--r--
Merge from at r31:36
35
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     1
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     2
#include "Physics.hh"
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     3
#include "Engine.hh"
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     4
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     5
#include <algorithm>
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     6
#include <functional>
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     7
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     8
PhysicsWorld::PhysicsWorld (Vector gravity, Vector dimensions)
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
     9
    : tick_timer(PHYSICS_TICK_MS), gravity(gravity), dimensions(dimensions) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    10
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    11
    slots.connect(tick_timer.sig_timer(), this, &PhysicsWorld::tick);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    12
    tick_timer.enable();
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    13
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    14
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    15
void PhysicsWorld::addObject (PhysicsObject *object) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    16
    objects.push_back(object);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    17
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    18
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    19
void PhysicsWorld::tick () {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    20
//    Engine::log(DEBUG, "physics.apply_force") << "*tick*";
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    21
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    22
	for (std::vector<PhysicsObject*>::iterator i = objects.begin(); i != objects.end(); i++) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    23
       	(*i)->tick(); 
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    24
  	}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    25
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    26
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    27
PhysicsObject::PhysicsObject (PhysicsWorld &world, float mass, Vector position, Vector velocity)
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    28
    : world(world), mass(mass), position(position), velocity(velocity) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    29
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    30
    world.addObject(this);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    31
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    32
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    33
void PhysicsObject::updatePosition () {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    34
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    35
	// Check if the player is moving on the ground
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    36
	/*if (this->velocity.y == 0 && (position.y >= world.dimensions.y - 3)) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    37
    	position.x += 50 * velocity.x * (PHYSICS_TICK_MS / 1000.0);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    38
		velocity.x = 0;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    39
		return;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    40
	}*/
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    41
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    42
	// If not moving on the ground, apply normal physics
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    43
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    44
    // Calculate gravity's influence on the velocity vector
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    45
    this->velocity += world.gravity * (PHYSICS_TICK_MS / 1000.0);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    46
        
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    47
    Vector newPosition = position + velocity * (PHYSICS_TICK_MS / 1000.0);
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    48
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    49
    //TODO Handle the object as a square or a polygon
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    50
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    51
//    Engine::log(DEBUG, "physics.update_position") << "position=" << newPosition << ", velocity=" << velocity;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    52
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    53
    bool collided = false;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    54
     
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    55
    if (newPosition.x < 0 || (newPosition.x > world.dimensions.x)) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    56
        // CRASH!
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    57
        this->velocity.x *= -0.5;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    58
		
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    59
		// If the velocity drops under some fixed constant we decide it is zero.
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    60
		// This is to prevent the object from bouncing eternally.
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    61
		if (abs(this->velocity.x) < 0.1)
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    62
			this->velocity.x = 0;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    63
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    64
        collided = true;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    65
    } else {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    66
        this->position.x = newPosition.x;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    67
    }
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    68
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    69
    if (newPosition.y <= 0 || (newPosition.y >= world.dimensions.y)) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    70
		this->velocity.y *= -0.3;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    71
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    72
		
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    73
 
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    74
		if (abs(this->velocity.y) < 0.1) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    75
			this->velocity.y = 0;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    76
			// Friction
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    77
			this->velocity.x *= 0.95;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    78
		} else {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    79
        	// Bigger friction
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    80
			this->velocity.x *= 0.75;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    81
		}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    82
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    83
        collided = true;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    84
	} else {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    85
        this->position.y = newPosition.y;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    86
	}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    87
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    88
    if(!collided) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    89
        this->position = newPosition;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    90
    }
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    91
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    92
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    93
void PhysicsObject::applyForce (Vector force, uint16_t dt) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    94
    Vector oldVelocity = velocity;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    95
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    96
    this->velocity += force * dt / 1000 / mass;  // The last factor denotes the time.
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    97
    // It should be scaled somehow.
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    98
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
    99
//    Engine::log(DEBUG, "physics.apply_force") << "force=" << force << ", velocity " << oldVelocity << " -> " << velocity;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   100
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   101
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   102
void PhysicsObject::updatePhysics (Vector position, Vector velocity) {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   103
    this->position = position;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   104
    this->velocity = velocity;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   105
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   106
    
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   107
Vector PhysicsObject::getPosition () {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   108
    return this->position;
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   109
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   110
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   111
void PhysicsObject::tick () {
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   112
    this->updatePosition();
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   113
}
e21cfda0edde Merge from at r31:36
terom
parents:
diff changeset
   114