1
0
Fork 0
blockofighter/src/object.cpp

212 lines
5.0 KiB
C++

#include "main.h"
#include <stdlib.h>
#include "object.h"
#include "vector.h"
#include "collision.h"
#include "utils.h"
#include "fight.h"
#include "glapi.h"
Object::Object(void) {
appearance = NULL;
geometry = NULL;
invmass = 0.0;
setPosition(0, 0, 0);
vectorSet(momentum, 0, 0, 0);
invmomentofinertia = 0.0;
matrixIdentity(rotation);
vectorSet(angularmomentum, 0, 0, 0);
setCollisionGroup(COLLISIONGROUP_NONE);
gravity = false;
}
void Object::prepare(void) {
if (appearance != NULL)
appearance->prepare();
}
#define DT 0.01
void Object::move(void) { moveStep(DT); }
void Object::moveStep(float dt) {
if (invmass == 0)
return;
if (vectorDot(momentum, momentum) > 1.0e+5)
vectorSet(momentum, 0, 0, 0);
if (vectorDot(angularmomentum, angularmomentum) > 1.0e+5)
vectorSet(angularmomentum, 0, 0, 0);
calculateStateVariables();
float velocitydt[3];
vectorScale(velocitydt, velocity, dt);
vectorAdd(position, velocitydt);
float rotationdt[9];
if (vectorIsZero(angularmomentum)) {
matrixIdentity(rotationdt);
} else {
float angularvelocitydt[3];
vectorScale(angularvelocitydt, angularvelocity, dt);
matrixCreateRotation(rotationdt, angularvelocitydt);
}
matrixMultiply(rotation, rotation, rotationdt);
vectorScale(angularmomentum, 0.99);
}
void Object::calculateStateVariables(void) {
getVelocity(velocity);
if (vectorIsZero(angularmomentum)) {
invmomentofinertia = 0;
} else {
invmomentofinertia =
invmass * 1.0 / geometry->calculateMomentOfInertia(angularmomentum);
}
vectorScale(angularvelocity, angularmomentum, invmomentofinertia);
}
void Object::setPosition(float x, float y, float z) {
position[0] = x;
position[1] = y;
position[2] = z;
}
void Object::getPosition(float *position) {
vectorCopy(position, this->position);
}
void Object::getVelocity(float *velocity) {
vectorCopy(velocity, momentum);
vectorScale(velocity, invmass);
}
void Object::getVelocity(float *velocity, float *point) {
getVelocity(velocity);
float tangentialvelocity[3];
getTangentialVelocity(tangentialvelocity, point);
// float tv[3];
// transformVector(tv, tangentialvelocity);
vectorAdd(velocity, tangentialvelocity);
}
void Object::getTangentialVelocity(float *target, float *point) {
if (vectorIsZero(angularmomentum)) {
vectorSet(target, 0, 0, 0);
return;
}
vectorCross(target, angularmomentum, point);
vectorScale(target, invmomentofinertia);
}
void Object::getMomentum(float *momentum) {
vectorCopy(momentum, this->momentum);
}
void Object::setMass(float mass) {
if (mass == 0)
this->invmass = 0;
else
this->invmass = 1.0 / mass;
}
float Object::getMass(void) {
if (invmass == 0)
return 0;
return 1.0 / invmass;
}
void Object::setCollisionGroup(int group) { this->collisiongroup = group; }
int Object::getCollisionGroup(void) { return collisiongroup; }
void Object::addImpulse(float *impulse, float *contactpoint) {
if (invmass == 0)
return;
float angularimpulse[3];
vectorCross(angularimpulse, contactpoint, impulse);
vectorAdd(angularmomentum, angularimpulse);
vectorAdd(momentum, impulse);
float t1[3], t2[3];
vectorAdd(t1, contactpoint, position);
vectorNormalize(t2, impulse);
vectorAdd(t2, t1);
// addGraphicsVector(t1, t2, vectorLength(impulse));
}
void Object::addExternalForce(float *force) {
float impulse[3];
vectorScale(impulse, force, DT);
float contact[3] = {0, 0, 0};
this->addImpulse(impulse, contact);
}
void Object::transformPoint(float *newpoint, float *oldpoint) {
vectorMatrixMultiply(newpoint, oldpoint, rotation);
vectorAdd(newpoint, position);
}
void Object::unTransformPoint(float *newpoint, float *oldpoint) {
vectorSub(newpoint, oldpoint, position);
float rotmat[9];
matrixTranspose(rotmat, rotation);
vectorMatrixMultiply(newpoint, newpoint, rotmat);
}
void Object::transformVector(float *newvector, float *oldvector) {
vectorMatrixMultiply(newvector, oldvector, rotation);
}
void Object::unTransformVector(float *newvector, float *oldvector) {
float rotmat[9];
matrixTranspose(rotmat, rotation);
vectorMatrixMultiply(newvector, oldvector, rotmat);
}
void Object::hitForce(float speed, float *speed2, Object *source) {
float tolerance = 1.0;
if (speed > tolerance) {
Sound *sound;
if (rand() & 1)
sound = softhitsound1;
else
sound = softhitsound2;
float volume = (speed - tolerance) * 2;
if (volume > 1)
volume = 1;
sound->setVolume(volume);
sound->play(30 + random(70));
}
}
void Object::setGravity(bool enabled) { gravity = enabled; }
void Object::draw(void) {
glPushMatrix();
glTranslatef(position[0], position[1], position[2]);
GLfloat glmatrix[16] = {rotation[0], rotation[1], rotation[2], 0,
rotation[3], rotation[4], rotation[5], 0,
rotation[6], rotation[7], rotation[8], 0,
0, 0, 0, 1};
glMultMatrixf(glmatrix);
if (appearance != NULL)
appearance->draw();
glPopMatrix();
}