toxi::geom::Vec2D toxi::geom::Polygon2D::getCentroid() { Vec2D res = Vec2D(); for (int i = 0, num = vertices.size(); i < num; i++) { Vec2D a = vertices.at(i); Vec2D b = vertices.at( ( i + 1 ) % num ); double crossP = a.getX() * b.getY() - b.getX() * a.getY(); res.set( res.getX() + (a.getX() + b.getX()) * crossP, res.getY() + (a.getY() + b.getY()) * crossP ); } return res.scale(1 / (6 * getArea())); }
Debris::Debris(Ship* s, Player* p, Vec2D location, Vec2D direction, bool collides, bool draw) : ParticleEffect(0, p, none, location, direction, NULL, collides, draw) { this->mesh = this; shipFinalDir = s->dir; Vec2D rotationpoint; Vec2D midpoint; Mesh* m = (Mesh*)(s->mesh); Mesh* meshpart = NULL; for(unsigned int i = 0; i < m->polyNum; ++i) { for(unsigned int p = 0; p < m->polys[i].length - 1; ++p) { meshpart = new Mesh(); meshpart->polyNum = 1; meshpart->mountNum = 0; meshpart->polys = new sf2::Polygon[1]; meshpart->polys[0].length = 2; meshpart->polys[0].vertices = new sf2::CUSTOMVERTEX[2]; meshpart->polys[0].vertices[0] = m->polys[i].vertices[p]; meshpart->polys[0].vertices[1] = m->polys[i].vertices[p+1]; midpoint = Vec2D(meshpart->polys[0].vertices[1].X + meshpart->polys[0].vertices[0].X, meshpart->polys[0].vertices[1].Y + meshpart->polys[0].vertices[0].Y)/2.0f; meshpart->radius = Distance(Vec2D(meshpart->polys[0].vertices[0].X, meshpart->polys[0].vertices[0].Y), Vec2D(meshpart->polys[0].vertices[1].X, meshpart->polys[0].vertices[1].Y)) / 2.0f; Vec2D addedVel = 3.0f/midpoint; //difference between midpoint and ship's midpoint addedVel.scale(meshpart->radius); //scale by size of part //rotationpoint Vec2D start(m->polys[i].vertices[p]); Vec2D end = Vec2D(m->polys[i].vertices[p+1]); rotationpoint = start - end; rotationpoint.scale(randomFloat(0.0f, 1.0f)); rotationpoint += end; float limit = 3.14159f * 2 / meshpart->radius; float rotationspeed = randomFloat(-limit, limit); LoadToVRAM(meshpart); parts.insert(parts.end(), new DebrisPart(meshpart, randomFloat(1.0f, 5.0f), s->loc, s->vel + addedVel, rotationpoint, midpoint, rotationspeed)); } } }
Vec2D Segment::intersectionPoint(Segment const& other) const { Vec2D selfDelta = delta(); Vec2D otherDelta = other.delta(); if(selfDelta.cross(otherDelta) != 0) { float t = other.a.subtract(a).cross(otherDelta) / selfDelta.cross(otherDelta); float u = other.a.subtract(a).cross(selfDelta) / selfDelta.cross(otherDelta); if(t >= 0 && t <= 1 && u >= 0 && u <= 1) { return a.add(selfDelta.scale(t)); } } return Vec2D(0, 0); }
void Ship::run(float deltaTime) { if(Distance(this->loc, Vec2D()) > getGame()->arena->radius && GetTickCount()%100 == 0) { Vec2D projection = loc; projection.scale(1.5f); getGame()->insertObject(new hostileDrone(getGame()->getNextIndex(), NULL, _hostileDrone, projection, Vec2D(0.0f, 1.0f), this)); } InputData* id = &getGame()->inputdata; //special abilitiy timers if(abilityTimer > 0.0f) { abilityTimer -= deltaTime; if(abilityTimer <= 0.0f && EndSpecialAbility != NULL) //ability just ended its time EndSpecialAbility(this); } else if(abilityCooldownTimer > 0.0f) abilityCooldownTimer -= deltaTime; if(hitpoints <= 0) { getGame()->debug.AddEvent("Ship died"); die(); //explosion getGame()->insertObject(new ShipExplosion(getGame()->getNextIndex(), this->loc, (int)this->mesh->radius)); //debris getGame()->insertObject(new Debris(this, this->owner, this->loc, this->dir, false, true)); } if(this->owner == getGame()->pc) { if(!dead) { if(id->up.downState || id->w.downState) { if(SpecialAbility == &Cloak && abilityTimer > 0.0f) thrusting = false; else thrusting = true; //for turning on thruster particle effects thrust(deltaTime); } else { thrusting = false; acc.zero(); // resec accel to 0 } if(id->down.downState || id->s.downState || id->r.downState) slow(deltaTime); if(id->left.downState || id->a.downState) turnLeft(deltaTime); if(id->right.downState || id->d.downState) turnRight(deltaTime); if(id->enter.hitEvent) { if(abilityCooldownTimer <= 0.0f && SpecialAbility != NULL) SpecialAbility(this); else if(SpecialAbility == NULL) getGame()->messages.addMessage("No special ability for this ship!"); else { if(abilityTimer > 0.0f) getGame()->messages.addMessage("Special ability is running!"); else getGame()->messages.addMessage("Special ability is cooling down!"); } id->enter.ResetEvent(); } } } vel += acc; if(abilityTimer > 0.0f) //special ability is active vel.limit(abilityVelLimit); else vel.limit(maxSpeed); //if(this->owner == getGame()->pc) //{ // if(id->h.downState) //devhax // { // vel.zero(); // } //} loc += vel * deltaTime; bb->Update(loc.x - mesh->radius, loc.y + mesh->radius); if(targetObj) target = targetObj->loc; if(this->owner == getGame()->pc) { if ((id->space.downState || id->mouse.left.downState) && weapon) weapon->shoot(); if(id->y.downState) targetObj = NULL; if(!targetObj && getGame()->cursortarget) target = getGame()->cursortarget->loc; } }
void Ship::update(float const delta) { if(gameWorld->getPaused()) return; if(dead) return; if(turningLeft) glhckObjectRotatef(o, 0, 0, delta * 120); if(turningRight) glhckObjectRotatef(o, 0, 0, delta * -120); if(accelerating) { kmScalar angle = glhckObjectGetRotation(o)->z; Vec2D acceleration(0, 120 * delta); acceleration.rotatei(angle / 360); v += acceleration; } if(v.lengthSquared() > MAX_SPEED * MAX_SPEED) { v.uniti().scalei(MAX_SPEED); } ActionType at = DEFAULT; if(accelerating) { at = turningLeft && !turningRight ? LEFT_ACCELERATING : turningRight && !turningLeft ? RIGHT_ACCELERATING : ACCELERATING; } else { at = turningLeft && !turningRight ? LEFT : turningRight && !turningLeft ? RIGHT : DEFAULT; } WeaponType wt; if(weapon->getWeaponId() == LaserWeapon::ID) wt = RAPID; else if(weapon->getWeaponId() == SpreadWeapon::ID) wt = SPREAD; else if(weapon->getWeaponId() == BeamWeapon::ID) wt = BEAM; else wt = PLASMA; ImageType it = static_cast<ImageType>(wt * NUM_ACTIONS + at); glhckMaterialTextureTransform(glhckObjectGetMaterial(o), &atlas.getTransform(it).transform, atlas.getTransform(it).degree); glhckObjectMovef(o, v.x * delta, v.y * delta, 0); // FIXME: Do proper wrapping kmVec3 const* pos = glhckObjectGetPosition(o); if(pos->x < -400) { glhckObjectMovef(o, 800, 0, 0); } else if(pos->x > 400) { glhckObjectMovef(o, -800, 0, 0); } if(pos->y < -240) { glhckObjectMovef(o, 0, 480, 0); } else if(pos->y > 240) { glhckObjectMovef(o, 0, -480, 0); } shape.center = getPosition(); for(Weapon* weapon : weapons) { weapon->update(delta); } if(shooting) { Vec2D direction = Vec2D(0, 1).rotatei(glhckObjectGetRotation(o)->z / 360); weapon->shoot(getPosition() + direction.scale(RADIUS), direction); } glhckObjectPosition(shield, glhckObjectGetPosition(o)); if(immortalityLeft > 0) { immortalityLeft -= delta; } }