Пример #1
0
void EnemyGrunt::render(sf::RenderTarget &rt) {
	sf::Sprite shadowSprite;
	shadowSprite.setTexture(_assets->_gruntShadow);

	shadowSprite.setOrigin(_assets->_gruntShadow.getSize().x * 0.5f, _assets->_gruntShadow.getSize().y * 0.5f);

	shadowSprite.setPosition(_position);

	rt.draw(shadowSprite);

	sf::Sprite footSprite;
	footSprite.setTexture(_assets->_gruntFoot);

	footSprite.setOrigin(2.0f, 2.5f);

	sf::Vector2f perpendicular(std::cos(_rotation * ltbl::_pi / 180.0f), std::sin(_rotation * ltbl::_pi / 180.0f));
	sf::Vector2f forward(perpendicular.y, -perpendicular.x);

	const float feetSpread = 1.5f;
	const float feetStepDistance = 2.5f;

	float leftFootOffset = std::sin(2.0f * ltbl::_pi * _footCycle);

	footSprite.setRotation(_rotation);

	footSprite.setPosition(_position - perpendicular * feetSpread + forward * feetStepDistance * leftFootOffset - forward * 1.0f);

	rt.draw(footSprite);

	footSprite.setPosition(_position + perpendicular * feetSpread - forward * feetStepDistance * leftFootOffset - forward * 1.0f);

	rt.draw(footSprite);

	sf::Sprite bodySprite;

	if (_pTarget == nullptr) {
		bodySprite.setTexture(_assets->_gruntBodyWalk);

		bodySprite.setPosition(_position);
	}
	else {
		std::uniform_real_distribution<float> noiseDist(-0.5f, 0.5f);

		// Show flash for only a bit of the flash cycle time
		if (_firingCycle < 0.3f) {
			bodySprite.setPosition(_position + sf::Vector2f(noiseDist(getGame()->_generator), noiseDist(getGame()->_generator)));
			bodySprite.setTexture(_assets->_gruntBodyFlashes[_currentFlash]);
		}
		else {
			bodySprite.setPosition(_position);
			bodySprite.setTexture(_assets->_gruntBodyNoFire);
		}
	}

	bodySprite.setOrigin(sf::Vector2f(_assets->_gruntBodyWalk.getSize().x * 0.5f, _assets->_gruntBodyWalk.getSize().y * 0.5f));

	bodySprite.setRotation(_rotation + leftFootOffset * 8.0f); // Sway a bit

	rt.draw(bodySprite);
}
Пример #2
0
math_vector math_vector::rotate(const math_vector& offset, const math_vector& displacement)const
{
    if( this->num_elements() != offset.num_elements() )
    {
        std::stringstream errMsg;
        errMsg << "math_vector::rotate called with offset of size " << offset.num_elements()
               << " on vector of size  " << this->num_elements()
               << ".  They must be of the same dimension." << std::endl;
        throw FlexibleExeption(errMsg.str());
    }
    if( offset.num_elements() != displacement.num_elements() )
    {
        std::stringstream errMsg;
        errMsg << "math_vector::rotate called with offset of size " << offset.num_elements()
               << " and displacment of size  " << displacement.num_elements()
               << ".  They must be of the same dimension." << std::endl;
        throw FlexibleExeption(errMsg.str());
    }

    if( (offset.magnatude() < sEFFECTIVELY_ZERO) || (displacement.magnatude() < sEFFECTIVELY_ZERO))
    {
        return math_vector(*this);
    }

    cout<<"rotate"<<endl;
    double theta = (displacement.perpendicular(offset).magnatude())/(offset.magnatude());
    theta /= 10;

    math_vector X_unit = offset/offset.magnatude();
    cout<<"X unit: "<<X_unit.write()<<endl;

    math_vector Y_unit = displacement.perpendicular(offset);
    Y_unit /= Y_unit.magnatude();
    cout<<"Y unit: "<<Y_unit.write()<<endl;

    cout<<"X: ";
    //double X ((parallel(X_unit)).magnatude());
    double X(along(X_unit));
    cout<<X<<endl;
    cout<<"Y: ";
    //double Y ((parallel(Y_unit)).magnatude());
    double Y(along(Y_unit));
    cout<<Y<<endl;
    //cout<<"Z"<<endl;
    math_vector Z(perpendicular(offset).perpendicular(displacement));

    math_vector u = X_unit*(X*cos(theta) - Y*sin(theta));
    math_vector v = Y_unit*(Y*cos(theta) + X*sin(theta));
    //math_vector w = Z;
    math_vector result((u+v)+Z);

    cout<<"input: "<<write()<<"    offset: "<<offset.write()<<"    displacement: "<<displacement.write()<<endl;
    cout<<"theta: "<<theta<<endl;
//    cout<<"X: "<<X.write()<<"    Y: "<<Y.write()<<"    Z: "<<Z.write()<<endl;
    cout<<"u: "<<u.write()<<"    v: "<<v.write()<<"    w: "<<Z.write()<<endl;
    cout<<"output: "<<result.write()<<endl;
    cout<<"magnatude: "<<result.magnatude()<<endl<<endl;

    return result;//since w = Z
}
      static void processOneEdge(const V2 &edge,
                                 const carve::csg::detail::LoopEdges &a_edge_map,
                                 const carve::csg::detail::LoopEdges &b_edge_map,
                                 Classification &a_classification,
                                 Classification &b_classification,
								 double EPSILON) {
        GrpEdgeSurfMap a_edge_surfaces;
        GrpEdgeSurfMap b_edge_surfaces;

        carve::geom3d::Vector edge_vector = (edge.second->v - edge.first->v).normalized();
        carve::geom3d::Vector base_vector = perpendicular(edge_vector);

        carve::csg::detail::LoopEdges::const_iterator ae_f = a_edge_map.find(edge);
        carve::csg::detail::LoopEdges::const_iterator ae_r = a_edge_map.find(flip(edge));
        CARVE_ASSERT(ae_f != a_edge_map.end() || ae_r != a_edge_map.end());

        carve::csg::detail::LoopEdges::const_iterator be_f = b_edge_map.find(edge);
        carve::csg::detail::LoopEdges::const_iterator be_r = b_edge_map.find(flip(edge));
        CARVE_ASSERT(be_f != b_edge_map.end() || be_r != b_edge_map.end());

        if (ae_f != a_edge_map.end() && !processForwardEdgeSurfaces(a_edge_surfaces, (*ae_f).second, edge_vector, base_vector,EPSILON)) return;
        if (ae_r != a_edge_map.end() && !processReverseEdgeSurfaces(a_edge_surfaces, (*ae_r).second, edge_vector, base_vector,EPSILON)) return;
        if (be_f != b_edge_map.end() && !processForwardEdgeSurfaces(b_edge_surfaces, (*be_f).second, edge_vector, base_vector,EPSILON)) return;
        if (be_r != b_edge_map.end() && !processReverseEdgeSurfaces(b_edge_surfaces, (*be_r).second, edge_vector, base_vector,EPSILON)) return;

        classifyAB(a_edge_surfaces, b_edge_surfaces, b_classification);
        classifyAB(b_edge_surfaces, a_edge_surfaces, a_classification);
      }
Пример #4
0
QPointF KoConnectionShapePrivate::perpendicularDirection(const QPointF &p1, const QPointF &d1, const QPointF &p2)
{
    QPointF perpendicular(d1.y(), -d1.x());
    qreal sp = scalarProd(perpendicular, p2 - p1);
    if (sp < 0.0)
        perpendicular *= -1.0;

    return perpendicular;
}
Пример #5
0
void DebugDrawing::arrow(Vector2<> start, Vector2<> end,
                         Drawings::PenStyle penStyle, int width, ColorRGBA color)
{
  Vector2<> startToEnd((end.x - start.x) / 4, (end.y - start.y) / 4);
  Vector2<> perpendicular(startToEnd.y, -1 * startToEnd.x);
  // start to endpoint
  line((int)start.x, (int)start.y, (int)(end.x), (int)(end.y), penStyle, width, color);
  // endpoint to left and right
  line((int)(end.x), (int)(end.y), (int)(end.x - startToEnd.x + perpendicular.x), (int)(end.y - startToEnd.y + perpendicular.y), penStyle, width, color);
  line((int)(end.x), (int)(end.y), (int)(end.x - startToEnd.x - perpendicular.x), (int)(end.y - startToEnd.y - perpendicular.y), penStyle, width, color);
}
Пример #6
0
void DebugDrawing::arrow(Vector2f start, Vector2f end,
                         Drawings::PenStyle penStyle, int width, ColorRGBA color)
{
  Vector2f startToEnd((end.x() - start.x()) / 4, (end.y() - start.y()) / 4);
  Vector2f perpendicular(startToEnd.y(), -1 * startToEnd.x());
  // start to endpoint
  line((int)start.x(), (int)start.y(), (int)(end.x()), (int)(end.y()), penStyle, width, color);
  // endpoint to left and right
  line((int)(end.x()), (int)(end.y()), (int)(end.x() - startToEnd.x() + perpendicular.x()), (int)(end.y() - startToEnd.y() + perpendicular.y()), penStyle, width, color);
  line((int)(end.x()), (int)(end.y()), (int)(end.x() - startToEnd.x() - perpendicular.x()), (int)(end.y() - startToEnd.y() - perpendicular.y()), penStyle, width, color);
}
Пример #7
0
bool PlayerShip::update(float globalTimeMultiplier) {
	// Rotating the ship
	{
		auto diff = _mouse_position - _screen_position;
		float angle = atan(diff.y / diff.x) * 57.296f + 90.f;
		if(diff.x < 0.f) {
			angle += 180.f;
		}
		_ship_sprite.setRotation(angle);
	}

	// Move the ship
	{
		if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up) ||
		   sf::Keyboard::isKeyPressed(sf::Keyboard::W)) {
			_acceleration.y -= .1f;
		}
		if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down) ||
		   sf::Keyboard::isKeyPressed(sf::Keyboard::S)) {
			_acceleration.y += .1f;
		}
		if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left) ||
		   sf::Keyboard::isKeyPressed(sf::Keyboard::A)) {
			_acceleration.x -= .1f;
		}
		if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right) ||
		   sf::Keyboard::isKeyPressed(sf::Keyboard::D)) {
			_acceleration.x += .1f;
		}

		_acceleration *= .8f;
		_velocity += _acceleration;
		_velocity *= .9f; // Friction in space :P
		_ship_sprite.move(_velocity);
		_shield_sprite.move(_velocity);
		_screen_position = default_screen_position + 5.f * _velocity;
	}

	// Fire bullets
	if(--_reload < 0 && sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
		_reload = 10.f;
		std::shared_ptr<EntityManager> entity_manager(_entity_manager.lock());
		if(entity_manager) {
			sf::Vector2f diff = _mouse_position - _screen_position;
			sf::Vector2f velocity = diff / (float)sqrt(diff.x*diff.x + diff.y*diff.y);
			sf::Vector2f perpendicular(-velocity.y, velocity.x);
			entity_manager->add(std::unique_ptr<Entity>(new Bullet(BulletType::FRIENDLY, 10.f, _shield_sprite.getPosition() + 40.f * velocity + 20.f * perpendicular, 5.0f*velocity)));
			entity_manager->add(std::unique_ptr<Entity>(new Bullet(BulletType::FRIENDLY, 10.f, _shield_sprite.getPosition() + 40.f * velocity - 20.f * perpendicular, 5.0f*velocity)));
		}
	}

	return getShipHealth() <= 0.f;
}
// The main program:
int main(int  argc, char* argv[])
{
  Polygon_2 polygon;

  const char* filename = (argc > 1) ? argv[1] : "polygon.dat";
  std::ifstream input_file(filename);
  if (! input_file.is_open()) {
    std::cerr << "Failed to open the " << filename << std::endl;
    return -1;
  }
  input_file >> polygon;
  input_file.close();

  // Example for is_pullout_direction_single_mold_translational_casting_2 that
  // accepts the edge
  size_t index(0);
  for (auto e_it = polygon.edges_begin(); e_it != polygon.edges_end(); ++e_it,
         ++index)
  {
    auto orientation = polygon.orientation();
    auto segment_outer_circle =
      SMS::internal::get_segment_outer_circle<Kernel>(*e_it, orientation);
    auto d = segment_outer_circle.first;
    d = d.perpendicular(CGAL::CLOCKWISE);
    auto res = casting::is_pullout_direction(polygon, e_it, d);
    std::cout << "The polygon is " << (res ? "" : "not ")
              << "castable using edge "
              << index << " in vartical translation (" << d << ")" << std::endl;

  }

  std::cout << "-----------------------------------"<< std::endl;

  // Example for is_pullout_direction_single_mold_translational_casting_2 that
  // do not accepts the edge
  {
    Vector_2 v (Point_2(0,0), Point_2(1,0));
    Direction_2 d(v);
    auto res = casting::is_pullout_direction(polygon, d);
    if (res != polygon.edges_end()) {
      std::cout << "The polygon is castable in direction d (" << d
                << ") using edge "<< *res << std::endl;

    }
    else {
      std::cout << "The polygon is not castable in direction d (" << d << ")"
                << std::endl;
    }
  }

  return 0;
}
Пример #9
0
bool TraceGraphPoint::correctTracePosition(Trace::TracePointer trace,
                                           Point2D* i_newPoint) {
  LOG_DEBUG("correctTracePosition");
  // if it is a line, it is always ok
  if (trace->getTraceType() == Trace::Line) {
    LOG_DEBUG("No need to correct it, its a line");
    return false;
  }
  // if it is a curve
  RotationTrace::RotationTracePointer rotationTrace;
  rotationTrace = std::dynamic_pointer_cast<RotationTrace>(trace);
  if (!curveNeedsCorrection(rotationTrace, *i_newPoint)) {
    return false;
  }
  LOG_DEBUG("Needing to fix it!");
  // correcting it here
  switch (m_positionOnTrace) {
  case TraceGraphPoint::CenterPoint : {
    // calculate the vector between the start and stop position
    Vector2D betweenPoints = trace->getEndPoint() - trace->getStartPoint();
    // calculate the vector perpendicular to it
    Vector2D perpendicular(betweenPoints.y, -betweenPoints.x);
    // calculate the point between the center point between the start and stop position
    *i_newPoint = rotationTrace->getPointBetweenStartAndStopPosition() +
      Vector2D::dotProduct(*i_newPoint - rotationTrace->getPointBetweenStartAndStopPosition(),
                           perpendicular.normalize()) * perpendicular.normalize();
    break;
  }
  case TraceGraphPoint::StartPoint : {
    // start point is handled the same as the end point
  }
  case TraceGraphPoint::EndPoint : {
    LOG_DEBUG("Fixing the end or start point");
    LOG_DEBUG("Point: " << i_newPoint->x << " , " << i_newPoint->y);
    try {
      *i_newPoint = rotationTrace->intersectingPoint(*i_newPoint);
    } catch (std::runtime_error) {
      LOG_DEBUG("Could not find intersecting point!");
      if (m_positionOnTrace == TraceGraphPoint::EndPoint) {
       *i_newPoint = rotationTrace->getEndPoint();
      } else if (m_positionOnTrace == TraceGraphPoint::StartPoint) {
        *i_newPoint = rotationTrace->getStartPoint();
      }
    }
    break;
  }
  default : {
    LOG_ERROR("unknown PointPosition");
    break;
  }}
  return true;
}
Пример #10
0
Vec3 Vec3::random_deviant(const Degrees& angle, const Vec3 up) const {
    //Lovingly adapted from ogre
    Vec3 new_up = (up == Vec3()) ? perpendicular() : up;

    Quaternion q;
    kmQuaternionRotationAxisAngle(&q, this, random_gen::random_float(0, 1) * (PI * 2.0));
    kmQuaternionMultiplyVec3(&new_up, &q, &new_up);
    kmQuaternionRotationAxisAngle(&q, &new_up, Radians(angle).value_);

    Vec3 ret;
    kmQuaternionMultiplyVec3(&ret, &q, this);

    return ret;
}
Пример #11
0
void SpinePoint::assign(const Vector& topMiddlePoint, const SpinePoint* prev) {
	_topMiddle = topMiddlePoint;
	Vector point_dir = topMiddlePoint - prev->topMiddle();
	auto n = point_dir.norm();
	ASSERT(n != 0);
	point_dir /= n;
	Vector perpendicular(point_dir.y(),-point_dir.x(),0);
	auto sideMovement = perpendicular * SNAKE_WIDTH_HALF;
	_bottomLeft = _topMiddle + sideMovement;
	_bottomLeft.set_z(SNAKE_FLOOR);
	_bottomRight = _topMiddle - sideMovement;
	_bottomRight.set_z(SNAKE_FLOOR);
	_poly_is_dirty = true;
	_previous = prev;
}
Пример #12
0
int main(int argc, char *argv[])
{
	//!!!Broken
	vgl_vector_3d<double> perpendicular(0, 1, 0);
	
	vgl_vector_3d<double> up(0,0,1);
	
	vgl_vector_3d<double> forward(1.0,0.0,0.0);
	
	//vgl_vector_3d<double> v(1.0,0.0,0.0);
	
	//vgl_vector_3d<double> Rotated = AxisAngle(forward, up, M_PI/2.0); //should be = perpendicular
	
	//cout << "Rotated = " << Rotated << endl;
	return 0;
}
Пример #13
0
void GCSWrapper::point_segment_coincidence(int id1, int id2)	// id1 = point, id2 = line
{
	SaPoint* p = (SaPoint*)get_shape(id1);
	SaLine* l1 = (SaLine*)get_shape(id2);

	double l1_lgh;
	double l1_midx;
	double l1_midy;
	calculate_line_length(l1, l1_lgh);
	calculate_line_midpoint(l1, l1_midx, l1_midy);

    //int p = add_point(5.0, 5.0);
	//int c = add_circle(10.0, 10.0, 3.0);
	int c = add_circle(l1_midx, l1_midy, l1_lgh/2);
	SaCircle* circle = (SaCircle*)get_shape(c);


	coincident_line_circle(id2, c);	
	//solve();
	gcs_sys.addConstraintPointOnLine(circle->get_gcs_circle().center, l1->get_gcs_line(), 1);
	//solve();

	collinear_point_line(id1, id2);
	//solve();
	
	double l2_x1, l2_y1, l2_x2, l2_y2;
	calculate_rotate_line(l1, l2_x1, l2_y1, l2_x2, l2_y2);
	int l2 = add_segment(l2_x1, l2_y1, l2_x2, l2_y2);

	perpendicular(id2, l2);
	//solve();
	
	coincident_line_circle(l2, c);
	//solve();

	//collinear_point_line(p, id2);
	collinear_point_line(id1, l2);
	//solve();
	
	 //circle->get_gcs_circle().center;	
}
Пример #14
0
vec3 brakkeScattering(const vec3 &vector, double delta) {
    vec3 perp = perpendicular(vector);
    perp.Normalize();
    const vec3 &w = vector;
    const vec3 &u = perp;
    const vec3 v = w.Cross(u);
    const double exponent = 1/(delta+1);

    vec3 perturbed = -vector;
    while(perturbed.z *  vector.z < 0) {
        double polar = acos(pow(RANDOM_FUNCTION(), exponent));
        double azimuthal = 2*M_PI*RANDOM_FUNCTION();

        double sp = sin(polar);
        double sa = sin(azimuthal);
        double cp = cos(polar);
        double ca = cos(azimuthal);

        perturbed = u * (sp*ca) + (v*sp*sa) + (w*cp);
    }

    return perturbed;
}
Пример #15
0
void Laser::Draw() {
    if (state) {
        //TODO: set up shade model in game engine when possible
        //glShadeModel(GL_SMOOTH);

/*
        double dirX = direction.x * WINDOW_DIAG;
        double dirY = direction.y * WINDOW_DIAG;
        double widX = direction.y * width;
        double widY = -direction.x * width;

        glBegin(GL_QUADS);

        glColor3ubv(color.arr());
        glVertex2d(position.x + widX, position.y + widY);
        glVertex2d(position.x + widX + dirX, position.y + widY + dirY);

        glColor3ubv(gWhite.arr());
        glVertex2d(position.x + dirX, position.y + dirY);
        glVertex2d(position.x, position.y);


        glVertex2d(position.x + dirX, position.y + dirY);
        glVertex2d(position.x, position.y);

        glColor3ubv(color.arr());
        glVertex2d(position.x - widX, position.y - widY);
        glVertex2d(position.x - widX + dirX, position.y - widY + dirY);


        glEnd();
*/
        glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
        glColor3ubv(color.arr());
        texture.Draw(position + direction * WINDOW_DIAG / 2, direction, 
                     2 * (int)width, WINDOW_DIAG);
        glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_REPLACE);
        
        /* Electricity effect, consists of random poly lines  */
        glColor3ub(250, 250, 255);
        glBegin(GL_LINE_STRIP);
        
        double randX = 0.0, randY = 0.0;
        Vector2 temp(position);
        Vector2 point;
        Vector2 perpendicular(direction.y, -direction.x);
        /* generate electricity until reaches edge of screen */
        while (temp.x > 0 && temp.x < WINDOW_WID 
            && temp.y > 0 && temp.y < WINDOW_HEI) {
                
            randX = rand()%(2*(int)width+8) - width - 4;
            randY = rand() % 80;
            
            point = temp + perpendicular * randX; 
            glVertex2d(point.x, point.y);
            temp += direction * randY;
            
            /* random break */
            if (rand()%5 == 0) {
                glEnd();
                glBegin(GL_LINE_STRIP);
            }
        }

        glEnd();
    }
}
Пример #16
0
void GameSessionInput::moveSelectedUnits()
{
    vec3 clickPos = Root::shared().getDepthResult();
    vec2 clickPos2(clickPos.x, clickPos.z);

    Faction* lf = session->getLocalFaction();
    if(!lf) return;

    // did we click on an enemy unit
    Unit* best_unit = 0;
    float best_distance = 100.0;
    //Faction* from_faction = 0;

    float dist;
    for(unsigned int j = 0; j < session->getFactions().size(); ++j) {
        if(session->getFactions()[j] == lf) continue;

        for(list<Unit*>::iterator it = session->getFactions()[j]->getUnits().begin();
                it != session->getFactions()[j]->getUnits().end(); ++it)
        {
            dist = glm::distance((*it)->getPosition2(), clickPos2);
            if(dist < (*it)->getInfo()->radius && dist < best_distance)
            {
                best_distance = dist; 
                best_unit = (*it);
            }
        }
    }

    vec2 centerPos(0,0); //average position of selected units
    vector<int> unitIds;
    vector<vec2> unitPositions;
    for(list<Unit*>::iterator it = lf->getUnits().begin(); it != lf->getUnits().end(); ++it)
        if((*it)->isSelected())
        {
            centerPos += (*it)->getPosition2();
            unitPositions.push_back((*it)->getPosition2());
            unitIds.push_back((*it)->getId());
        }

    int numSelected = unitIds.size();

    if(!numSelected) return;

    centerPos /= (float)numSelected;

    //FOR NOW: we only use pathfinding for normal walking, not for attacking
	if(best_unit)
	{
		Event& ev = Game::shared().getEventManager()->createEvent(EVENT_ATTACK_MOVE_UNIT_REQUEST);
		ev << numSelected;
		for(unsigned int i = 0; i < unitIds.size(); ++i)
			ev << unitIds[i] << best_unit->getId();

		ev.send();
	}
    else
    {
        //Movement from centerPos to clickPos
        vec2 target(clickPos.x, clickPos.z);

        //Find a path
        std::vector<vec2> pathNodes;
        //session->findPath(centerPos,target,pathNodes);
        if(pathNodes.empty()) pathNodes.push_back(target);

        //Now calculate the position of each unit relative to each other
        vector<vec2> relativePositions(unitIds.size());

        vec2 direction = glm::normalize(target - centerPos);
		vec2 perpendicular(-direction.y, direction.x); //right hand rule

		float spread = 20.0f;
		int perRow = (int)(glm::sqrt((float)numSelected) + 0.99);

		direction *= spread;
		perpendicular *= spread;

        vector<bool> unitTaken(unitIds.size(),false);
		for(int i = 0; i < numSelected; ++i)
		{
			//This loops over the target spots in such a way that it first loops the points that are furthest away.
			//When the units are coming from the BOTTOM the order is like this:
			//1 2 3
			//4 5 6
			//7 8 9
			vec2 targetSpot = target + float(perRow/2 - i/perRow)*direction + float(i%perRow - perRow/2)*perpendicular;
			//Select closest unit
			int bestIndex = -1;
			float bestDistance = 0;
			for(int j = 0; j < numSelected; ++j)
			{
                if(unitTaken[j]) continue;
				float dist = glm::distance(unitPositions[j],targetSpot);
				if(bestIndex == -1 || dist < bestDistance)
				{
					bestIndex = j;
					bestDistance = dist;
				}
			}
            relativePositions[bestIndex] = targetSpot - target;
            unitTaken[bestIndex] = true;
		}

        //Relative positions to center have been calculated. Now send the packet
        Event& ev = Game::shared().getEventManager()->createEvent(EVENT_MOVE_UNIT_REQUEST);
        ev << numSelected;
        for(int i = 0; i < numSelected; ++i)
        {
            ev << unitIds[i];
            ev << (int)pathNodes.size();
            for(unsigned int j = 0; j < pathNodes.size(); ++j)
            {
                ev << pathNodes[j] + relativePositions[i];
            }
        }
		ev.send();
	}
}
Пример #17
0
compute::buffer cape::fighter_to_fixed_vec(vec3f p1, vec3f p2, vec3f p3, vec3f rot)
{
    vec3f rotation = rot;

    vec3f diff = p3 - p1;

    float shrink = 0.12f;

    diff = diff * shrink;

    p3 = p3 - diff;
    p1 = p1 + diff;

    vec3f lpos = p1;
    vec3f rpos = p3;

    ///approximation
    ///could also use body scaling
    float ldepth = (p3 - p1).length() / 3.f;
    float rdepth = ldepth;
    ///we should move perpendicularly away, not zdistance away

    vec2f ldir = {p3.v[0], p3.v[2]};

    ldir = ldir - (vec2f){p1.v[0], p1.v[2]};

    vec2f perp = perpendicular(ldir.norm());

    vec3f perp3 = {perp.v[0], 0.f, perp.v[1]};

    lpos = lpos + perp3 * ldepth;
    rpos = rpos + perp3 * ldepth;

    lpos.v[1] += bodypart::scale / 4;
    rpos.v[1] += bodypart::scale / 4;

    ///dir could also just be (p3 - p1).rot ???
    vec3f dir = rpos - lpos;

    int len = width;

    vec3f step = dir / (float)(len - 1);

    vec3f current = lpos;

    compute::buffer buf = compute::buffer(cl::context, sizeof(float)*width*3, CL_MEM_READ_WRITE, nullptr);

    if(!cape_init)
    {
        gpu_cape.resize(width * 3);
        cape_init = true;
    }

    //cl_float* mem_map = (cl_float*) clEnqueueMapBuffer(cl::cqueue.get(), buf.get(), CL_TRUE, CL_MAP_WRITE_INVALIDATE_REGION, 0, sizeof(cl_float)*width*3, 0, NULL, NULL, NULL);

    float sag = bodypart::scale/32.f;

    //sag = 0;

    for(int i=0; i<len; i++)
    {
        float xf = (float)i / len;

        float yval = 4 * xf * (xf - 1) * sag + sin(xf * 30);

        /*mem_map[i*3 + 0] = current.v[0];
        mem_map[i*3 + 1] = current.v[1] + yval;
        mem_map[i*3 + 2] = current.v[2];*/

        gpu_cape[i*3 + 0] = current.v[0];
        gpu_cape[i*3 + 1] = current.v[1] + yval;
        gpu_cape[i*3 + 2] = current.v[2];

        current = current + step;
    }

    clEnqueueWriteBuffer(cl::cqueue.get(), buf.get(), CL_FALSE, 0, sizeof(cl_float) * width * 3, gpu_cape.data(), 0, NULL, NULL);

    //clEnqueueUnmapMemObject(cl::cqueue.get(), buf.get(), mem_map, 0, NULL, NULL);

    return buf;
}
Пример #18
0
bool is_valid_rect() {
    int i, k;
    bool marked[4];
    for(i=0;i<4;i++) {
        if(lines[i].length_square == 0) {
            printf("length_square == 0\n");
            return false;
        }
        marked[i] = false;
    }
    rect.p[0].x = lines->p[0].x;
    rect.p[0].y = lines->p[0].y;
    rect.p[1].x = lines->p[1].x;
    rect.p[1].y = lines->p[1].y;
    marked[0] = true;
    bool found;
    for(i=2;i<4;i++) {
        found = false;
        for(k=0;k<4;k++) {
            if(!marked[k]) {
                if(same_point(lines[k].p, rect.p+i-1)) {
                    found = true;
                    rect.p[i].x = lines[k].p[1].x;
                    rect.p[i].y = lines[k].p[1].y;
                    marked[k] = true;
                    break;
                }
                else if(same_point(lines[k].p+1, rect.p+i-1)) {
                    found = true;
                    rect.p[i].x = lines[k].p[0].x;
                    rect.p[i].y = lines[k].p[0].y;
                    marked[k] = true;
                    break;
                }
            }
        }
        if(!found) {
            return false;
        }
    }
    for(i=0;i<4;i++)
        if(!marked[i]) {
            if(same_point(lines[i].p, rect.p)) {
                if(!(same_point(lines[i].p+1, rect.p+3)))
                    return false;
            }
            else if(same_point(lines[i].p+1, rect.p)) {
                if(!(same_point(lines[i].p, rect.p+3)))
                    return false;
            }
            else
                return false;
            break;
        }
    for(i=0;i<4;i++) {
        Point *a = i == 0 ? rect.p+3 : rect.p+i-1;
        Point *o = rect.p+i;
        Point *b = i == 4 ? rect.p : rect.p+i+1;
        if(!perpendicular(a, o, b))
            return false;
    }
    return true;
}
Пример #19
0
 Vector2 Vector2::rotated90CW() const
 {
     return perpendicular();
 }
Пример #20
0
void EnemyGrunt::update(float dt) {
	_isSelected = getGame()->_selection.find(this) != getGame()->_selection.end();

	if (!_hitWall && ltbl::vectorMagnitude(_target - _position) < 0.5f * _stats->_walkRate * dt) {
		_attack = true;
		_target = _position;

		// Settle feet
		_footCycle += (0.0f - _footCycle) * 1.2f * dt;
	}
	else if (!_hold && _pTarget == nullptr) {
		sf::Vector2f dir = ltbl::vectorNormalize(_target - _position);

		_position += dir * _stats->_walkRate * dt;

		// Rotate to target rotation
		float angle = std::atan2(dir.y, dir.x) * 180.0f / ltbl::_pi + 90.0f;

		face(angle, dt, _stats->_spinRate);

		_footCycle = std::fmod(_footCycle + _stats->_walkRate * _footCycleRate * dt, 1.0f);

		quadtreeUpdate();
	}

	if (_attack && _pTarget == nullptr) {
		// Search for enemy in range
		std::vector<QuadtreeOccupant*> occupants;

		sf::FloatRect rangeRect = ltbl::rectFromBounds(_position - sf::Vector2f(_stats->_range, _stats->_range), _position + sf::Vector2f(_stats->_range, _stats->_range));

		getRoom()->getQuadtree().queryRegion(occupants, rangeRect);

		float minDist = 999999.0f;

		for (int i = 0; i < occupants.size(); i++) {
			Entity* pEntity = static_cast<Entity*>(occupants[i]);

			if (pEntity->_type == 1) {
				Friendly* pEnemy = static_cast<Friendly*>(occupants[i]);

				float dist = ltbl::vectorMagnitude(pEnemy->getPosition() - _position);

				if (dist < minDist) {
					minDist = dist;

					_pTarget = pEnemy;
				}
			}
		}

		if (minDist > _stats->_range)
			_pTarget = nullptr;
	}

	if (_pTarget != nullptr) {
		float dist = ltbl::vectorMagnitude(_pTarget->getPosition() - _position);

		if (dist > _stats->_range)
			_pTarget = nullptr;
		else {
			sf::Vector2f dir = ltbl::vectorNormalize(_pTarget->getPosition() - _position);

			float angle = std::atan2(dir.y, dir.x) * 180.0f / ltbl::_pi + 90.0f;

			face(angle, dt, _stats->_spinRate);

			// Play firing animation
			if (_firingCycle >= 1.0f) {
				_firingCycle = 0.0f;

				// Spawn shell
				std::shared_ptr<Shell> shell = std::make_shared<Shell>();

				sf::Vector2f perpendicular(std::cos(_rotation * ltbl::_pi / 180.0f), std::sin(_rotation * ltbl::_pi / 180.0f));
				sf::Vector2f forward(perpendicular.y, -perpendicular.x);

				std::uniform_real_distribution<float> positionNoise(-15.0f, 15.0f);
				std::uniform_real_distribution<float> rotationNoise(-10.0f, 10.0f);

				getRoom()->add(shell, false);

				shell->create(perpendicular * 20.0f + sf::Vector2f(positionNoise(getGame()->_generator), positionNoise(getGame()->_generator)), _position + perpendicular * 2.0f, rotationNoise(getGame()->_generator), _rotation, 1.0f, 2.0f);

				_currentFlash = (_currentFlash + 1) % _assets->_gruntBodyFlashes.size();
			}
			else
				_firingCycle += _firingCycleRate * dt;

			// Play firing sound
			if (_firingSound.getStatus() != sf::Sound::Playing) {
				if (_fireSoundTimer <= 0.0f) {
					// Randomize pitch and volume a bit
					std::uniform_real_distribution<float> pitchDist(0.8f, 1.0f);
					std::uniform_real_distribution<float> volumeDist(10.0f, 20.0f);

					_firingSound.setPitch(pitchDist(getGame()->_generator));
					_firingSound.setVolume(volumeDist(getGame()->_generator));

					_firingSound.play();
				}
				else
					_fireSoundTimer -= dt;
			}
			else {
				std::uniform_real_distribution<float> fireSoundDist(0.0f, _maxFireSoundTime);

				_fireSoundTimer = fireSoundDist(getGame()->_generator);
			}

			// Damage target
			_pTarget->_hp -= _stats->_damage * dt;
		}
	}
	else {
		_firingCycle = 0.0f;
	}

	if (!_hitWall && ltbl::vectorMagnitude(_position - _prevPosition) < 0.25f * _stats->_walkRate * dt) {
		// Stop walking, stuck
		_target = _position;
	}

	// If not walking
	if (std::abs(_footCycle) < 0.02f) {
		if (_idleFaceTimer < 0.0f) {
			std::uniform_real_distribution<float> newTimeDist(_idleFaceTime * 0.5f, _idleFaceTime);

			_idleFaceTimer = newTimeDist(getGame()->_generator);

			std::uniform_real_distribution<float> idleFaceDist(-30.0f, 30.0f);

			_idleFaceDirection = _lastFacedDirection + idleFaceDist(getGame()->_generator);
		}
		else
			_idleFaceTimer -= dt;

		face(_idleFaceDirection, dt, _stats->_idleSpinRate);
	}
	else {
		_idleFaceTimer = _idleFaceTime;

		_idleFaceDirection = _rotation;
	}

	// Death
	if (_hp <= 0.0f) {
		remove();

		// Spawn splat
		std::shared_ptr<Splat> splat = std::make_shared<Splat>();

		std::uniform_real_distribution<float> rotationNoise(0.0f, 360.0f);

		getRoom()->add(splat, false);

		splat->create(_position, _rotation + rotationNoise(getGame()->_generator), 30.0f);
	}

    // AI
    {
        // Search room for friendlies, find closest
        sf::Vector2f attackPosition = getPosition();

        float minDistance = 99999.0f;

        for (int i = 0; i < getRoom()->getEntities().size(); i++) {
            Entity* pEntity = getRoom()->getEntities()[i].get();

            if (pEntity->_type == 1) { // Friendly
                Friendly* pFriendly = static_cast<Friendly*>(pEntity);

                float distance = ltbl::vectorMagnitude(pFriendly->getPosition() - getPosition());

                if (distance < minDistance) {
                    attackPosition = pFriendly->getPosition();

                    minDistance = distance;
                }
            }
        }

        attackMove(attackPosition);
    }

	_hitWall = false;

	_prevPosition = _position;
}
Пример #21
0
vector3<T> tangent_space_to_world_space(const vector3<T>& v, const vector3<T>& nrm)
{
	const vector3<T>& t1 = perpendicular(nrm);
	const vector3<T>& t2 = cross(nrm, t1);
	return (v.x() * t1 + v.y() * t2 + v.z() * nrm).normalized();
}
Пример #22
0
int calc_hb(char o_str[256],int i, int j)
{
    int       l, /*ri, rj, gap,*/ h, near_h;
    
    /*char      bndtyp[3], acctyp[4], dontyp[4], space=' ';*/
    float     /*ca_d,*/ d, ha2,/*IM*/tmp_d, hd, ha, haaa_ang, daaa_ang;
    struct vect nearest, tmp_point, aromatic_axis, aa[MAXCON] /* acceptor antecedants*/;
    
    
    char buf1[20],buf2[20]; /* buffers for atomid routines */
    
    /* void find_ss()*/
    /* {*/
    /*     int i,j;*/
    /*     float d;*/
    short aromatic_flg;
    

    *o_str=0;
    
/*    if(i==203 && j==210)
    {
	printf("Testing from %s",atomid(i,buf1));
	printf(" to %s at start of calc_hb.\n",atomid(j,buf1));
    	debug=0;
    }
    else
	debug=0;
  */  

    d = length_squared( to(atom[i].p, atom[j].p) );
    if (debug==2)
	printf("don-acc distance ^2 = %f\n",d);
    
    if (d <= SQR(HBDIST))
	/* these are nearby ! */; /*IM begins*/
    else return(0);
    
    if (debug) printf("Acceptable distance\n");
    
    /* time to fill the acceptor array */
    daaa_ang= -99.9; /* reset it . . . . */
    
    aromatic_flg =  ( atom[j].aacode < TOTNAA )?(accepts[atom[j].aacode][atom[j].atmtyp] < 0):0;
    
    if (!aromatic_flg)    
    {
	for(l=0;l<MAXCON;l++)
	{
	    if (icon[j][l]>-1) 
	    {
		float daaa_tmp,aaa;
		char buf1[20],buf2[20];
		
		aa[l]=atom[icon[j][l] ].p;
		
		daaa_tmp= dot_product(
 						  to( aa[l], atom[j].p ), to( atom[i].p, atom[j].p )       ); /* = DA * A-AA * cos D-A-AA */
 			    aaa=vector_length ( to(aa[l], atom[j].p) );
 			    
 			    daaa_tmp/= aaa * sqrt( d); /* = cos D-A-AA */
 			    /* d= DA^2 */
 			    if (daaa_tmp>daaa_ang) daaa_ang=daaa_tmp; /* select lowest */
 			    if (aaa<0.8 || aaa > 6.0) 
				printf("WARNING: %5.2fA between %s and %s ((D..)A-AA bond).\n", aaa,atomid(icon[j][l],buf1),atomid(j,buf2));
 			   
 			}
 		    }
 		    if (daaa_ang > cosMIN_DAAA && daaa_ang>-99.9) 
 			if (!nnbflg)
 			    return(0);
 		    
 		    /*NB -99 was not originally used as a default whilst checking
 		      because we were wrongly trying to find a lowest possible 
 		      value */
 		    /*	printf("lowest daaa_ang %6.1f\n",daaa_ang);*/
 		}
 		else /*aromatic_hbond*/
 		{
 		    float daaa_tmp;
 		    /*if( !strncmp("4DFR/A0030-TRP CE3",atomid(j,buf1),18))
		      debug=1;*/
 		    
 		    if (debug){
 			printf("NOTE: %s is aromatic.\n",atomid(j,buf1));
 			printf("      connects to ");
 			for(l=0;l< atom[j].ncon;l++)
 			    printf("%s ",atomid(icon[j][l],buf1));
 			printf("\n");
 			
 		    }
 		    
 		    if ( accepts[atom[j].aacode][atom[j].atmtyp] != -1 )
 			printf("BUG: %s not registered as aromatic acceptor in \"aromatic_hbond\".\n",atomid(j,buf1));
 		    if ( atom[j].ncon!=2 && atom[j].ncon!=3 )
 			printf("BUG: %s has connectivity %d but is registered as aromatic.\n",atomid(j,buf1),atom[j].ncon);
 		    if ( atom[j].ncon==3 )
 		    {
 			aromatic_axis = unit_vector(
						    vector_plus( perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][1] ].p),
								vector_plus( perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][2] ].p),
									    perpendicular( atom[ icon[j][1] ].p, atom[j].p, atom[ icon[j][2] ].p) ) ) );
 			
 		    }
 		    else
 			aromatic_axis = unit_vector(perpendicular( atom[ icon[j][0] ].p, atom[j].p, atom[ icon[j][1] ].p));
 		    
 		    aa[0]= vector_plus( aromatic_axis, atom[j].p );
 		    aa[1]= vector_plus( float_times_vect( -1.0, aromatic_axis), atom[j].p );
 		    if (debug) printf("Perpendicular gives angles %5.3f and %5.3f with 1,2 / %d.\n",angle( atom[ icon[j][0] ].p, atom[j].p, aa[0] ), angle( atom[ icon[j][1] ].p, atom[j].p, aa[0] ) , atom[j].ncon);
 		    
 		    for(l=0;l<2;l++)
 		    {
 			daaa_tmp= dot_product( to( aa[l], atom[j].p), to( atom[i].p, atom[j].p ) ); /*=DA*A-AA*cosD-A-AA */
 			daaa_tmp /= sqrt(d); /* = cos D-A-AX */
 			if ( daaa_tmp > daaa_ang ) daaa_ang=daaa_tmp; /* select high values of cos D-A-AX ie low, better angles*/
 			if (debug) printf("Cosine of D-A-AX = %5.3f\n",daaa_tmp);
 		        if (debug) {
 			    printf("AX co-ods");
 			    printf(TF,VXYZ( aa[l] ) );
 			    printf("\n");
 			}
 			
 		    }
 		    if (daaa_ang < cosMAX_DAAX)
 		    {
 			if (debug)
 			    printf("Rejected because DAAX too high.\n");
 			if (!nnbflg)
 			    return(0);
 		    }
 		}
 		
 		
#define nearer(vector) { tmp_d=length_squared( to( atom[j].p, vector ) ); if (ha2>tmp_d) { ha2=tmp_d; nearest=vector; near_h = h;} }
 		
 		/* find the nearest possible H position on donor i */
 		ha2=100;
		/*	if (i==362) debug=1;
			else debug=0;*/
 		
 		if (debug && atom[i].hetflg) printf("H on %s %d  ",atom[i].resnam, atom[i].aanum);
 		if (debug) printf("%d Hs positioned\n",atom[i].nh);
 		
 		for(h=atom[i].h_ptr;h<atom[i].nh+atom[i].h_ptr;h++)
 		{
 		    if (debug)
 			printf("Hydrogen %d - type %d\n",atom[i].h_ptr,h_atm[h].typ);
 		    if (debug) printf("atom[i].nh %d, ].h_ptr %d, h %d\n",atom[i].nh,atom[i].h_ptr,h);
 		    
 		    switch (h_atm[h].typ)
 		    {
 		    case 0:
 			if (debug) printf("Atom %d (%s%s %d) has H %d missing\n",i,atom[i].atmnam,atom[i].resnam, atom[i].aanum, h);
 			/* no H present, must be HETATM */
 			;/* used to be ha2=1, cannot decide why */
 			break;
 		    case alternatives:
 			nearer( h_atm[h].a );
 			if (debug) printf("Checked alternative position: ha2 = %f\n",ha2);			    			    
 		    case fixed:
 			nearer( h_atm[h].p );
 			if (debug) printf("Checked default position: ha2 = %f\n",ha2);
 			break;
 		    case circle:
 			tmp_point= intersect(to(atom[i].p,h_atm[h].a),
 					     h_atm[h].p, atom[i].p, atom[j].p );
 			tmp_point= onto_sphere(tmp_point, h_atm[h].a,
 					       vector_length( to(h_atm[h].a, h_atm[h].p) ));
 			nearer(tmp_point);
 			tmp_point= vector_plus( tmp_point,
 					       float_times_vect(2,to(tmp_point, h_atm[h].a)));
 			nearer(tmp_point);
 			break;
 		    default:
 			printf("\nBUG: Unforseen htyp for atom %s in find_hb.\n", atomid(i,buf1));
 			printf("Please mail [email protected]\n");
			
 		    }/* end of switch*/
 		}/* end of h loop */
 		
 		if (ha2<100) /* ie if any Hydrogens have been found and
 				their positions taken.  Or, to put it 
 				another way, if it anything other than a hetatm 
 				which is flagged in .nh as having hydrogens but
 				has no positons in h_atm[].typ. */
 		{
 		    
 		    hd=vector_length( to(nearest, atom[i].p));
 		    ha=vector_length( to(nearest, atom[j].p));
 		    if (hd<0.9 || hd > 2.0) 
 		    {
 			printf("WARNING: %5.2fA between %s and %d (H).\n", hd, atomid(i,buf1),near_h-atom[i].h_ptr+1);		
 			if (debug) printf("atom[i].nh %d, ].h_ptr %d, h %d\n",atom[i].nh,atom[i].h_ptr,h);
 		    }
 		    
		    if (debug) printf("hd=%f,  ha=%f\n",hd,ha);
 		    
 		    if (!nnbflg)
 		    {
 			if (ha>MAX_HA)
 			    return(0);
 			if (debug)
 			    printf("HA length OK\n");
 			
 			if (dot_product( to(nearest, atom[i].p), 
 					to(nearest, atom[j].p) ) >= hd*ha*cosMIN_DHA)
 			    return(0);
 		    }
 		    
 		    haaa_ang=100.0; /* reset it . . . . */
 		    
 		    if (!aromatic_flg)
 		    {	
 			for(l=0;l<MAXCON;l++)
 			{
 			    if (icon[j][l]>-1) 
 			    {
 				float haaa_tmp,aaa;
 				aa[l]=atom[icon[j][l] ].p;
 				haaa_tmp= dot_product(
 						      to(atom[j].p, aa[l] ), to( atom[j].p, nearest )       );
 				aaa= vector_length( to(aa[l],atom[j].p) );
 				
 				haaa_tmp/= aaa *ha;
 				if (haaa_tmp<haaa_ang) haaa_ang=haaa_tmp; /* select lowest */
 				if (aaa<0.8 || aaa > 6.0) 
 				    printf("WARNING: %5.2fA between %s and %s ((H..)A-AA).\n", aaa,atomid(j,buf1),atomid(icon[j][l],buf2));		    
 			    }
 			}
 			if ((haaa_ang > cosMIN_HAAA && haaa_ang<100.0) && !nnbflg) 
 			    return(0);
 			else
 			    if (haaa_ang==100.0)
 				haaa_ang= -99.9;
 			/*NB -99 could not have been used as a default whilst checking
 			  because we are trying to find a lowest possible value */
 			
 			if (debug)
 			    printf("Angle OK\n");
 		    }
 		    else
 		    {
 			float haaa_tmp;
 			haaa_ang= -99; /*dealing with hAax, prefer small, ie big cosines*/
 			for(l=0;l<2;l++)
 			{
 			    
 			    haaa_tmp=dot_product( to(atom[j].p,aa[l]),to(atom[j ].p,nearest));
 			    haaa_tmp/= ha;
 			    if (debug) printf("Cosine of H-A-AX = %5.3f\n",haaa_tmp);
 			    if (haaa_tmp > haaa_ang) {
 				if (debug) printf("%5.3f > %5.3f.\n",haaa_tmp,haaa_ang);
 				
 				haaa_ang=haaa_tmp; /* select the low ie more meaningful */
 				if (debug) printf("Lowest yet.\n");
 			    }
 			    
 			}
 			if (haaa_ang < cosMAX_HAAX /* && haaa_ang<100.0 */ )
 			{
 			    if (debug) {
 				printf("Rejected because of wide HAAX angle.\n");
 				printf("Cos haaa_ang = %5.3f, cosMAX_HAAX = %5.3f.\n", haaa_ang, cosMAX_HAAX);
 			    }
 			    if (!nnbflg)
 				return(0);
 			}
 		    }
 		    
 		    
 		}/* end of 'if any Hs actually found' clause */
 		else
 		    if (d>SQR(MAX_HA+1.0))
 			if (!nnbflg)
 			    return(0); /* if the hydrogens are unfixed, knock
					 anything more than 1.0 Ang - the 
					 normal DH distance - back. */

    sprintf_hb(o_str,i,j,nearest,d,ha,daaa_ang,haaa_ang);
    return(1);
}