bool HitBox::IsCollision(Vector2 offset, HitBox *pHitBox, Vector2 hitBoxOffset, CollisionParameter *pParam) const
{
    bool isCollision = false;
    Vector2 overlapCompensation = Vector2(0, 0);

    if (pHitBox != NULL)
    {
        for (unsigned int i = 0; i < collidableObjectList.size(); i++)
        {
            CollidableObject *pCollidableObject1 = collidableObjectList[i];

            for (unsigned int j = 0; j < pHitBox->collidableObjectList.size(); j++)
            {
                CollidableObject *pCollidableObject2 = pHitBox->collidableObjectList[j];
                CollisionParameter tempParam;

                if (CollisionExists(pCollidableObject1, offset + overlapCompensation, pCollidableObject2, hitBoxOffset, &tempParam)
                    && fabs(tempParam.OverlapDistance) > 0.0001)
                {
                    for (unsigned int k = 0; k < tempParam.OverlapEntryList.size(); k++)
                    {
                        pParam->OverlapEntryList.push_back(tempParam.OverlapEntryList[k]);
                    }

                    overlapCompensation += tempParam.OverlapAxis * tempParam.OverlapDistance;
                    isCollision = true;
                }
            }
        }
    }

    pParam->OverlapDistance = overlapCompensation.Length();
    pParam->OverlapAxis = overlapCompensation.Normalize();
    return isCollision;
}
예제 #2
0
Number TransformGizmo::getTransformPlaneAngle() {
	
	Ray gizmoRay;
	gizmoRay.origin = getConcatenatedMatrix().getPosition();
	gizmoRay.direction = localTransformPlane * -1;
				
	Vector3 gizmoIntersect = gizmoRay.planeIntersectPoint(transformPlane, transformPlaneDistance);
    gizmoIntersect = planeMatrix.Inverse() * gizmoIntersect;
	   
    
	Ray ray = targetScene->projectRayFromCameraAndViewportCoordinate(targetCamera, coreInput->getMousePosition());	
	Vector3 mouseIntersect = ray.planeIntersectPoint(transformPlane, transformPlaneDistance);
    mouseIntersect = planeMatrix.Inverse() * mouseIntersect;
    
	Vector2 planePosition;
    
	if(localTransformPlane.x > 0) {
		planePosition.x = mouseIntersect.z - gizmoIntersect.z;
		planePosition.y = mouseIntersect.y - gizmoIntersect.y;
	} else if(localTransformPlane.y > 0.0) {
		planePosition.x = mouseIntersect.x - gizmoIntersect.x;
		planePosition.y = mouseIntersect.z - gizmoIntersect.z;
	} else if(localTransformPlane.z > 0.0) {
		planePosition.x = mouseIntersect.x - gizmoIntersect.x;
		planePosition.y = mouseIntersect.y - gizmoIntersect.y;
	}
    
	planePosition.Normalize();
	
	return atan2(planePosition.x, planePosition.y);
}
예제 #3
0
float Vector2::AngleBetween(Vector2 v) const {
	if (this->Magnitude() == 0 || v.Magnitude() == 0) {
		return 0;
	}

	Vector2 left = this->Normalize();
	Vector2 right = v.Normalize();

	if (left == right) {
		return 0;
	}

	float dot = left.Dot(right);

	// Floating points check
	if (dot > 1.0f) {
		dot = 1.0f;
	}
	else if (dot < -1.0f) {
		dot = -1.0f;
	}

	float rot = acos(dot);

	// http://stackoverflow.com/questions/11022446/direction-of-shortest-rotation-between-two-vectors
	// Use cross vector3 to determine direction
	Vector3 cross = Vector3(left.x, left.y).Cross(Vector3(right.x, right.y));
	if (cross.z > 0) {
		return -rot;
	}
	else {
		return rot;
	}
}
예제 #4
0
void Object::Move(int64 diff) {

	if(!target)
	  return;
   Vector2 to(target->getX(), target->getY());
   Vector2 cur(x, y);
   
   Vector2 goingTo (to - cur);
	Vector2 norm (goingTo.Normalize());

	double deltaMovement = (double)(getMoveSpeed()) * 0.000001f*diff;

	float xx = norm.X * deltaMovement;
	float yy = norm.Y * deltaMovement;

      
   x+= xx;
   y+=yy;

	/* If the target was a simple point, stop when it is reached */
	if(target->isSimpleTarget() && distanceWith(target) < deltaMovement*3) {
	   if(++curWaypoint >= waypoints.size()) {
         setTarget(0);
      } else {
         setTarget(waypoints[curWaypoint].toTarget());
      }
	}
}
void GalaxianReturnToFormationState::Update(Galaxian* a_galaxian, float a_fDeltaTime)
{
	m_deltaTimeMap[a_galaxian] += a_fDeltaTime;
	if(m_referanceMap[a_galaxian]->m_state == EntityState::REMOVED)
	{
		m_referanceMap[a_galaxian] = m_formation->GetFirstGalaxianInFormation();
	}
	Vector2 referancePosition = m_referanceMap[a_galaxian]->GetPosition();
	int xOffset = a_galaxian->GetPositionInFormation().x - m_referanceMap[a_galaxian]->GetPositionInFormation().x;
	int yOffset = a_galaxian->GetPositionInFormation().y - m_referanceMap[a_galaxian]->GetPositionInFormation().y;
	Vector2 targetPosition = referancePosition + Vector2(xOffset * (GalaxianFormation::SPRITE_WIDTH+12), yOffset * (GalaxianFormation::SPRITE_HEIGHT+6));

	if(a_galaxian->GetPosition().Distance(targetPosition) > 5)
	{
		Vector2 direction = targetPosition - a_galaxian->GetPosition();
		direction.Normalize();
		a_galaxian->Move(direction * a_fDeltaTime * 200);
	}
	else
	{
		a_galaxian->SetPosition(targetPosition);
		a_galaxian->SetDirection(Vector2(0,1));
		a_galaxian->ChangeState(GalaxianInFormationState::getInstance());
	}
}
예제 #6
0
//-----------------------------------------------------------------------------------------------------------------------------------
void Camera::Update(DX::StepTimer const& timer)
{
	// If the camera is fixed we should not do any more updating
	if (m_cameraMode == CameraMode::kFixed)
	{
		return;
	}

	KeyboardInput& keyboard = ScreenManager::GetKeyboardInput();
	Vector2 diff = Vector2::Zero;

	if (keyboard.IsKeyDown(Keyboard::Keys::Left))
	{
		diff.x = -1;
	}
	if (keyboard.IsKeyDown(Keyboard::Keys::Right))
	{
		diff.x = 1;
	}
	if (keyboard.IsKeyDown(Keyboard::Keys::Up))
	{
		diff.y = -1;
	}
	if (keyboard.IsKeyDown(Keyboard::Keys::Down))
	{
		diff.y = 1;
	}

	if (diff != Vector2::Zero)
	{
		diff.Normalize();
		m_position += diff * (float)timer.GetElapsedSeconds() * m_panSpeed;
	}
}
예제 #7
0
Vector2 Physics_Response(const float dt, const Vector2& src, const Vector2& contact, const Vector2& velocity, const float restitution/* = 2.0f*/)
{
	if (dt == 0.0f)
	{
		return Vector2(0.f, 0.f);
	}

	Vector2 normal = contact - src;
	normal.Normalize();

	Vector2 vel_dt = velocity * dt;
	SGE::Graphics_DebugLine(src, src + vel_dt, 0xAAAAFF);
	SGE::Graphics_DebugLine(contact, src, 0x00FF00);

	float dot = SGE::Math_Dot(vel_dt, normal);
	Vector2 A = (normal * restitution) * dot;

	SGE::Graphics_DebugLine(contact, contact + A, 0xFFFFFF);

	Vector2 X = vel_dt - A;
	SGE::Graphics_DebugLine(src, src + X, 0xFF0000);

	Vector2 response_vel = X * (1.f/dt);
	return response_vel;
}
예제 #8
0
파일: Object.cpp 프로젝트: JNeiger/IntWars
void Object::Move(int64 diff) {

   if (!target)
   {
      direction = Vector2();
      return;
   }

   currentUpwardDisplacement = map->getHeightAtLocation(getPosition().X, getPosition().Y);

   Vector2 to(target->getX(), target->getY());
   Vector2 cur(x, y);
   
   Vector2 goingTo (to - cur);
	direction = goingTo.Normalize();

	double deltaMovement = (double)(getMoveSpeed()) * 0.000001f*diff;

   float xx = direction.X * deltaMovement;
   float yy = direction.Y * deltaMovement;

      
   x+= xx;
   y+= yy;

	/* If the target was a simple point, stop when it is reached */
	if(target->isSimpleTarget() && distanceWith(target) < deltaMovement*3) {
	   if(++curWaypoint >= waypoints.size()) {
         setTarget(0);
      } else {
         setTarget(waypoints[curWaypoint].toTarget());
      }
	}
}
예제 #9
0
void Worm::MoveInDirection(Vector2& direction, float distance)
{
   direction.Normalize();
   Vector2 newPoint = Vector2( m_head->GetPosition() + (direction * distance) );	

   m_head->SetPosition(newPoint);
   m_tail->moveTo(newPoint, distance);
}
예제 #10
0
파일: Evasion.cpp 프로젝트: doveiya/isilme
	Vector2 Evasion::CalcVelocity()
	{
		Vector2 offset = mActor->GetPosition()  - mTarget->GetPosition();
		float distance = offset.Length();
		float timeInterval = std::min(0.1f, distance / mActor->GetMaxVelocity());
		Vector2 v = mActor->GetPosition() - mTarget->PredictFuturePosition(timeInterval); // Inefficient!!!

		v.Normalize();
		v = mActor->GetMaxVelocity() * v;
		v -= mActor->GetVelocity();

		// Limit
		v.Normalize();
		v = mActor->GetMaxVelocity() * v;

		return v;
	}
예제 #11
0
Vector2 Vector2::RandomXY()
{
    Vector2 v;
    v.X = (float)(Random::Instance->NextDouble() - 0.5);
    v.Y = (float)(Random::Instance->NextDouble() - 0.5);
    v.Normalize();
    return v;
}
예제 #12
0
void
BatMan::AliveUpdate()
{
	Vector2 vec = (_playerRef.GetCollider().Center() - _collider.Center());//normalizeで変な値になってる
	vec = vec.Normalize();
	_pos.x += vec.x * 2;
	_collider.pos = _pos + Vector2(_cameraRef.OffsetX(), 0);
	_walkFrame++;
}
예제 #13
0
파일: Flee.cpp 프로젝트: doveiya/isilme
	Vector2 Flee::CalcVelocity()
	{
		Vector2 v = mActor->GetPosition() - mTarget;
		v.Normalize();
		v = mActor->GetMaxVelocity() * v;
		v -= mActor->GetVelocity();

		return v;
	}
void FieldCharacter::UpdateDirection(Vector2 directionVector)
{
    directionVector = directionVector.Normalize();

    // We'll snap the player's direction vector according to
    // the nearest direction for which we have an animation.
    double angleToHorizontal = acos(directionVector.GetX());

    // acos() only returns values from 0 to pi,
    // so to get the full circle we need to check
    // whether we're in the bottom two quandrants,
    // and change the angle to account for this if so.
    if (directionVector.GetY() > 0)
    {
        angleToHorizontal = 2 * M_PI - angleToHorizontal;
    }

    if (angleToHorizontal <= M_PI / 8 || angleToHorizontal > M_PI * 15 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionSide);
        SetDirection(CharacterDirectionRight);
    }
    else if (angleToHorizontal > M_PI / 8 && angleToHorizontal <= M_PI * 3 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionDiagonalUp);
        SetDirection(CharacterDirectionRight);
    }
    else if (angleToHorizontal > 3 * M_PI / 8 && angleToHorizontal <= M_PI * 5 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionUp);
    }
    else if (angleToHorizontal > 5 * M_PI / 8 && angleToHorizontal <= M_PI * 7 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionDiagonalUp);
        SetDirection(CharacterDirectionLeft);
    }
    else if (angleToHorizontal > 7 * M_PI / 8 && angleToHorizontal <= M_PI * 9 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionSide);
        SetDirection(CharacterDirectionLeft);
    }
    else if (angleToHorizontal > 9 * M_PI / 8 && angleToHorizontal <= M_PI * 11 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionDiagonalDown);
        SetDirection(CharacterDirectionLeft);
    }
    else if (angleToHorizontal > 11 * M_PI / 8 && angleToHorizontal <= M_PI * 13 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionDown);
    }
    else if (angleToHorizontal > 13 * M_PI / 8 && angleToHorizontal <= M_PI * 15 / 8)
    {
        SetSpriteDirection(FieldCharacterDirectionDiagonalDown);
        SetDirection(CharacterDirectionRight);
    }
}
예제 #15
0
    void SegmentShape2D::SetDirection(Vector2 value)
    {
        if (value != Vector2::Zero)
            value.Normalize();

        if (GetDirection() != value)
        {
            direction = value;
            revision = -1;
        }
    }
예제 #16
0
파일: Sun.cpp 프로젝트: Natman64/Icarus
void Sun::finalAttack()
{
	Vector2 playerPos(world_->getPlayer().x(), world_->getPlayer().y());
	Vector2 dir = playerPos - position_;
	
	dir.Normalize();
	dir *= 760.0f;

	velocity_ = dir;
	
	phase_time_ = 6000000;
}
예제 #17
0
void
VNode::addRandomizedChildren(const Vector2& startPoint, const Vector2& targetPoint)
{
    static const float fudgeFactor = 0.3f;
    Vector2 orientation = targetPoint - startPoint;
    orientation.Normalize();
    orientation.X = MathUtil::RandomFloatInRange( orientation.X - fudgeFactor, orientation.X + fudgeFactor );
    orientation.Y = MathUtil::RandomFloatInRange( orientation.Y - fudgeFactor, orientation.Y + fudgeFactor );

    // n times...
    m_children.push_back( new VNode(startPoint, orientation) );
}
예제 #18
0
	void Ball::Update()
	{
		// store our last position
		Vector2 lastPosition = position;

		// update our current position using velocity
		position += velocity * Monocle::deltaTime;

		// check collisions against the paddles
		Collider* collider = Collide("Paddle");
		if (collider)
		{
			Debug::Log("Ball hit an entity tagged with 'Paddle'");
			position = lastPosition;
			
			Vector2 diff = position - collider->GetEntity()->position;
			diff.Normalize();
			diff *= velocity.GetMagnitude();
			velocity = diff;
            
            // Calculate panning
            float pan = ((collider->GetEntity()->position.x / Graphics::GetVirtualWidth()) - 0.5) * 2.0;

            if (sfxWall)
                sfxWall->Play(1,1.0,pan); // Play it with panning! (STEREO, baby :D)
		}

		// if we hit the top or bottom of the screen
		if (position.y < 0 || position.y > 600)
		{
			position = lastPosition;
			velocity.y *= -1;
            
            // Calculate panning
            float pan = ((position.x / Graphics::GetVirtualWidth()) - 0.5) * 2.0;
            
            if (sfxWall)
                sfxWall->Play(1,1.0,pan,2.0); // Play it higher, you won't even notice it's the same ;D
		}
		
		// if we go off the left side of the screen
		if (position.x < 0)
		{
			SendNoteToScene("BallOffLeft");
		}

		// if we go off the right side of the screen
		if (position.x > 800)
		{
			SendNoteToScene("BallOffRight");
		}
	}
void StreamEmitter::Tick(GameData* _GD)
{
	spawnTimer += _GD->m_dt;

	while (spawnTimer > 1.f / rate)
	{
		bool particleSpawned = false;
		//Iterates through the particle list 
		for (Particle* particle : myParticles)
		{
			if (!particle->isAlive())
			{
				Vector2 particlePos = m_pos;

				//Sets the direction of travel of the particle to downwards

				Vector2 particleDir = Vector2(0, 1);

				//Sets the direction of travel for the particle

				particlePos = Vector2::Transform(particlePos, m_worldMat);
				particlePos.Normalize();
				particleDir.Normalize();
				//Spawn the particle with the values calculated above

				particle->Spawn(life, m_pos, particleDir);
				particleSpawned = true;
				spawnTimer -= 1.f / rate;
				break;
			}
		}
		break;
	}
	//Sort the particles using the function declared above to make sure particles are being added and removed in the correct order
	myParticles.sort(compareParticles);
	Emitter::Tick(_GD);

}
예제 #20
0
int IntrLine2Segment2<Real>::Classify (Real* afS, Vector2<Real>* pkDiff,
    Vector2<Real>* pkDiffN)
{
    // The intersection of two lines is a solution to P0+s0*D0 = P1+s1*D1.
    // Rewrite this as s0*D0 - s1*D1 = P1 - P0 = Q.  If D0.Dot(Perp(D1)) = 0,
    // the lines are parallel.  Additionally, if Q.Dot(Perp(D1)) = 0, the
    // lines are the same.  If D0.Dot(Perp(D1)) is not zero, then
    //   s0 = Q.Dot(Perp(D1))/D0.Dot(Perp(D1))
    // produces the point of intersection.  Also,
    //   s1 = Q.Dot(Perp(D0))/D0.Dot(Perp(D1))

    Vector2<Real> kDiff = m_pkSegment->Origin - m_pkLine->Origin;
    if (pkDiff)
    {
        *pkDiff = kDiff;
    }

    Real fD0DotPerpD1 = m_pkLine->Direction.DotPerp(m_pkSegment->Direction);
    if (Math<Real>::FAbs(fD0DotPerpD1) > Math<Real>::ZERO_TOLERANCE)
    {
        // lines intersect in a single point
        if (afS)
        {
            Real fInvD0DotPerpD1 = ((Real)1.0)/fD0DotPerpD1;
            Real fDiffDotPerpD0 = kDiff.DotPerp(m_pkLine->Direction);
            Real fDiffDotPerpD1 = kDiff.DotPerp(m_pkSegment->Direction);
            afS[0] = fDiffDotPerpD1*fInvD0DotPerpD1;
            afS[1] = fDiffDotPerpD0*fInvD0DotPerpD1;
        }
        return IT_POINT;
    }

    // lines are parallel
    kDiff.Normalize();
    if (pkDiffN)
    {
        *pkDiffN = kDiff;
    }

    Real fDiffNDotPerpD1 = kDiff.DotPerp(m_pkSegment->Direction);
    if (Math<Real>::FAbs(fDiffNDotPerpD1) <= Math<Real>::ZERO_TOLERANCE)
    {
        // lines are colinear
        return IT_SEGMENT;
    }

    // lines are parallel, but distinct
    return IT_EMPTY;
}
예제 #21
0
int IntrSegment2Segment2<Real>::Classify (Real* s, Vector2<Real>* diff,
    Vector2<Real>* diffN)
{
    // The intersection of two lines is a solution to P0+s0*D0 = P1+s1*D1.
    // Rewrite this as s0*D0 - s1*D1 = P1 - P0 = Q.  If D0.Dot(Perp(D1)) = 0,
    // the lines are parallel.  Additionally, if Q.Dot(Perp(D1)) = 0, the
    // lines are the same.  If D0.Dot(Perp(D1)) is not zero, then
    //   s0 = Q.Dot(Perp(D1))/D0.Dot(Perp(D1))
    // produces the point of intersection.  Also,
    //   s1 = Q.Dot(Perp(D0))/D0.Dot(Perp(D1))

    Vector2<Real> originDiff = mSegment1->Center - mSegment0->Center;
    if (diff)
    {
        *diff = originDiff;
    }

    Real D0DotPerpD1 = mSegment0->Direction.DotPerp(mSegment1->Direction);
    if (Math<Real>::FAbs(D0DotPerpD1) > Math<Real>::ZERO_TOLERANCE)
    {
        // Lines intersect in a single point.
        if (s)
        {
            Real invD0DotPerpD1 = ((Real)1)/D0DotPerpD1;
            Real diffDotPerpD0 = originDiff.DotPerp(mSegment0->Direction);
            Real diffDotPerpD1 = originDiff.DotPerp(mSegment1->Direction);
            s[0] = diffDotPerpD1*invD0DotPerpD1;
            s[1] = diffDotPerpD0*invD0DotPerpD1;
        }
        return IT_POINT;
    }

    // Lines are parallel.
    originDiff.Normalize();
    if (diffN)
    {
        *diffN = originDiff;
    }

    Real diffNDotPerpD1 = originDiff.DotPerp(mSegment1->Direction);
    if (Math<Real>::FAbs(diffNDotPerpD1) <= Math<Real>::ZERO_TOLERANCE)
    {
        // Lines are colinear.
        return IT_SEGMENT;
    }

    // Lines are parallel, but distinct.
    return IT_EMPTY;
}
예제 #22
0
	void Player::Update()
	{
		Entity::Update();

		if (Input::IsMouseButtonHeld(MOUSE_BUTTON_LEFT))
		{
			Vector2 dir = Input::GetWorldMousePosition() - position;
			dir.Normalize();
			velocity += force * dir * Monocle::deltaTime;
		}

		position += velocity * Monocle::deltaTime;

		Game::GetScene()->GetCamera()->position = position;
		//Graphics::SetCameraPosition(position);
	}
예제 #23
0
Vector2 AIFleeComponent::calculateForce(AIMovementComponent::MovementParameters& params)
{
   // Should we use our specific flee target, or the one provided?
   Point2F target = params.target;
   if (!mFleeTargetObject.isNull())
   {
      target = mFleeTargetObject->getPosition();
   }

   Vector2 direction = params.ownerPosition - target;
   direction.Normalize();

   Vector2 desiredVelocity = direction * params.ownerMaxSpeed;

   return desiredVelocity - params.ownerVelocity;
}
예제 #24
0
void GameObject::update(double deltaTime) {

	if (moveBy != Vector2::Zero) {

		Vector2 dir = moveBy;
		dir.Normalize();

		dir *= deltaTime * 100;
		moveBy -= dir;
		move(dir);

		if ((Vector2::Distance(position, waypoint) <= Globals::WAYPOINT_TOLERANCE)) {
			moveBy = Vector2::Zero;
		}
	}
}
예제 #25
0
Vector2 Actor::GetDirectionVector() const
{
  Vector2 r = Deku2D::Const::Math::V2_ZERO;

  for (int i = 0; i < 4; i++)
  {
    if (directions_[i])
    {
      r += directionToVector[i];
    }
  }

  if (r.x * r.y != 0.0f)
  {
    r.Normalize();
  }
  return r;
}
예제 #26
0
void FrogShip::update(double deltaTime, PlayerShip* player, vector<Bullet*>& liveBullets) {
	
	GameObject::updateDebug(deltaTime);
	timeAlive += deltaTime;

	double percent = timeAlive / TIME_TO_CLIMAX;
	percent = 1 - cos(percent*XM_PIDIV2);
	double rt = 1 - percent;
	position = camera.screenToWorld(float(rt*rt)*startPos + 2 * float(rt*percent)*controlPoint
		+ float(percent*percent)*climaxPos);

	if (percent > .25) {
		// start aiming at player
		Vector2 dirToPlayer = player->getCenter() - position;
		dirToPlayer.Normalize();

		float angleToPlayer = atan2(dirToPlayer.y, dirToPlayer.x) + XM_PIDIV2;
		dirToPlayer = Vector2(cos(angleToPlayer), sin(angleToPlayer));
		//dirToPlayer += Vector2(cos(XM_PIDIV2), sin(XM_PIDIV2));
		Vector2 currentRot(cos(rotation), sin(rotation));

		currentRot += (dirToPlayer - currentRot) * float(deltaTime * rotationSpeed);
		setRotation(atan2(currentRot.y, currentRot.x));


		if (timeAlive >= TIME_TO_FIRE && closeEnough(dirToPlayer, currentRot)) {
			for (auto const& weapon : weaponSystems) {
				weapon->timeSinceFired += deltaTime;
				weapon->updatePosition(position);
				if (weapon->ready()) {
					weapon->fired = true;
					Bullet* bullet = weapon->launchBullet(player->getCenter());
					liveBullets.push_back(bullet);
				}
			}
		}
	}

	if (position.y > camera.screenToWorld(Vector2(0, float(camera.viewportHeight + 120))).y) {
		reset();
	}
}
예제 #27
0
void NavMesh::Grow(Vertices& vertices, float amount) {
    
    std::vector<Vector2> normals;
    normals.resize(vertices.size(), Vector2(0,0));
    for(NavTriangle* t : triangles) {
        for (int i=0; i<3; i++) {
            if (!t->neighbors[i]) {
                int index0 = t->corners[i];
                int index1 = t->corners[i<2 ? i + 1 : 0];
                Vector2 direction = vertices[index1] - vertices[index0];
                Vector2 normal = { -direction.y, direction.x };
                normal.Normalize();
                normals[index0] += normal;
                normals[index1] += normal;
            }
        }
    }

    for (int i=0; i<vertices.size(); i++) {
        vertices[i] -= normals[i].Normalized() * amount;
    }
}
예제 #28
0
void GhostEnemy::Update(double dt)
{
	// Get a direction to the target
	Vector2 moveVector = Vector3(m_target.x, m_target.y) - m_transforms.Translation;
	if (moveVector != Vector2::ZERO_VECTOR)
	{
		moveVector.Normalize();
	}

	// Set the length to move
	moveVector = moveVector * m_moveSpeed * dt;

	m_transforms.Translation += moveVector;

	// Update the weapon
	if (m_weapon != NULL)
	{
		m_weapon->Update(dt);
	}

	// Shoot when possitble
	m_attacked = Attack();
}
예제 #29
0
void NavMesh::AddPoly(std::vector<double>& points, std::vector<int>& segments, std::vector<double>& holes, std::vector<Vector2>& polyPoints) {
    int index = (int)points.size()/2;
    
    Vector2 holePosition = 0;
    for (int i=0; i<polyPoints.size(); i++) {
        points.push_back(polyPoints[i].x);
        points.push_back(polyPoints[i].y);
    
        segments.push_back(index + i);
        segments.push_back(index + ((i==polyPoints.size()-1) ? 0 : i + 1));
        
        holePosition += polyPoints[i];
        
    }
    holePosition *= (1.0f / polyPoints.size());
    
     for (int i=0; i<polyPoints.size(); i++) {
        Vector2 toCenter = holePosition - polyPoints[i];
        toCenter.Normalize();
        holes.push_back(polyPoints[i].x + toCenter.x * 4);
        holes.push_back(polyPoints[i].y + toCenter.y * 4);
    }
    
}
예제 #30
0
    MinBox2<Real>::MinBox2 ( int numPoints, const Vector2<Real>* points,
                             Real epsilon, Query::Type queryType, bool isConvexPolygon )
    {
        // Get the convex hull of the points.
        Vector2<Real>* hullPoints = 0;
        if ( isConvexPolygon )
        {
            hullPoints = ( Vector2<Real>* )points;
        }
        else
        {
            ConvexHull2<Real> hull( numPoints, ( Vector2<Real>* )points, epsilon,
                                    false, queryType );
            int hullDim = hull.GetDimension();
            int hullNumSimplices = hull.GetNumSimplices();
            const int* hullIndices = hull.GetIndices();

            if ( hullDim == 0 )
            {
                mMinBox.Center = points[0];
                mMinBox.Axis[0] = Vector2<Real>::UNIT_X;
                mMinBox.Axis[1] = Vector2<Real>::UNIT_Y;
                mMinBox.Extent[0] = ( Real )0;
                mMinBox.Extent[1] = ( Real )0;
                return;
            }

            if ( hullDim == 1 )
            {
                ConvexHull1<Real>* hull1 = hull.GetConvexHull1();
                hullIndices = hull1->GetIndices();

                mMinBox.Center = ( ( Real )0.5 ) * ( points[hullIndices[0]] +
                                                     points[hullIndices[1]] );
                Vector2<Real> diff =
                    points[hullIndices[1]] - points[hullIndices[0]];
                mMinBox.Extent[0] = ( ( Real )0.5 ) * diff.Normalize();
                mMinBox.Extent[1] = ( Real )0.0;
                mMinBox.Axis[0] = diff;
                mMinBox.Axis[1] = -mMinBox.Axis[0].Perp();

                delete0( hull1 );
                return;
            }

            numPoints = hullNumSimplices;
            hullPoints = new1<Vector2<Real> >( numPoints );
            for ( int i = 0; i < numPoints; ++i )
            {
                hullPoints[i] = points[hullIndices[i]];
            }
        }

        // The input points are V[0] through V[N-1] and are assumed to be the
        // vertices of a convex polygon that are counterclockwise ordered.  The
        // input points must not contain three consecutive collinear points.

        // Unit-length edge directions of convex polygon.  These could be
        // precomputed and passed to this routine if the application requires it.
        int numPointsM1 = numPoints - 1;
        Vector2<Real>* edges = new1<Vector2<Real> >( numPoints );
        bool* visited = new1<bool>( numPoints );
        int i;
        for ( i = 0; i < numPointsM1; ++i )
        {
            edges[i] = hullPoints[i + 1] - hullPoints[i];
            edges[i].Normalize();
            visited[i] = false;
        }
        edges[numPointsM1] = hullPoints[0] - hullPoints[numPointsM1];
        edges[numPointsM1].Normalize();
        visited[numPointsM1] = false;

        // Find the smallest axis-aligned box containing the points.  Keep track
        // of the extremum indices, L (left), R (right), B (bottom), and T (top)
        // so that the following constraints are met:
        //   V[L].X() <= V[i].X() for all i and V[(L+1)%N].X() > V[L].X()
        //   V[R].X() >= V[i].X() for all i and V[(R+1)%N].X() < V[R].X()
        //   V[B].Y() <= V[i].Y() for all i and V[(B+1)%N].Y() > V[B].Y()
        //   V[T].Y() >= V[i].Y() for all i and V[(T+1)%N].Y() < V[T].Y()
        Real xmin = hullPoints[0].X(), xmax = xmin;
        Real ymin = hullPoints[0].Y(), ymax = ymin;
        int LIndex = 0, RIndex = 0, BIndex = 0, TIndex = 0;
        for ( i = 1; i < numPoints; ++i )
        {
            if ( hullPoints[i].X() <= xmin )
            {
                xmin = hullPoints[i].X();
                LIndex = i;
            }
            if ( hullPoints[i].X() >= xmax )
            {
                xmax = hullPoints[i].X();
                RIndex = i;
            }

            if ( hullPoints[i].Y() <= ymin )
            {
                ymin = hullPoints[i].Y();
                BIndex = i;
            }
            if ( hullPoints[i].Y() >= ymax )
            {
                ymax = hullPoints[i].Y();
                TIndex = i;
            }
        }

        // Apply wrap-around tests to ensure the constraints mentioned above are
        // satisfied.
        if ( LIndex == numPointsM1 )
        {
            if ( hullPoints[0].X() <= xmin )
            {
                xmin = hullPoints[0].X();
                LIndex = 0;
            }
        }

        if ( RIndex == numPointsM1 )
        {
            if ( hullPoints[0].X() >= xmax )
            {
                xmax = hullPoints[0].X();
                RIndex = 0;
            }
        }

        if ( BIndex == numPointsM1 )
        {
            if ( hullPoints[0].Y() <= ymin )
            {
                ymin = hullPoints[0].Y();
                BIndex = 0;
            }
        }

        if ( TIndex == numPointsM1 )
        {
            if ( hullPoints[0].Y() >= ymax )
            {
                ymax = hullPoints[0].Y();
                TIndex = 0;
            }
        }

        // The dimensions of the axis-aligned box.  The extents store width and
        // height for now.
        mMinBox.Center.X() = ( ( Real )0.5 ) * ( xmin + xmax );
        mMinBox.Center.Y() = ( ( Real )0.5 ) * ( ymin + ymax );
        mMinBox.Axis[0] = Vector2<Real>::UNIT_X;
        mMinBox.Axis[1] = Vector2<Real>::UNIT_Y;
        mMinBox.Extent[0] = ( ( Real )0.5 ) * ( xmax - xmin );
        mMinBox.Extent[1] = ( ( Real )0.5 ) * ( ymax - ymin );
        Real minAreaDiv4 = mMinBox.Extent[0] * mMinBox.Extent[1];

        // The rotating calipers algorithm.
        Vector2<Real> U = Vector2<Real>::UNIT_X;
        Vector2<Real> V = Vector2<Real>::UNIT_Y;

        bool done = false;
        while ( !done )
        {
            // Determine the edge that forms the smallest angle with the current
            // box edges.
            int flag = F_NONE;
            Real maxDot = ( Real )0;

            Real dot = U.Dot( edges[BIndex] );
            if ( dot > maxDot )
            {
                maxDot = dot;
                flag = F_BOTTOM;
            }

            dot = V.Dot( edges[RIndex] );
            if ( dot > maxDot )
            {
                maxDot = dot;
                flag = F_RIGHT;
            }

            dot = -U.Dot( edges[TIndex] );
            if ( dot > maxDot )
            {
                maxDot = dot;
                flag = F_TOP;
            }

            dot = -V.Dot( edges[LIndex] );
            if ( dot > maxDot )
            {
                maxDot = dot;
                flag = F_LEFT;
            }

            switch ( flag )
            {
            case F_BOTTOM:
                if ( visited[BIndex] )
                {
                    done = true;
                }
                else
                {
                    // Compute box axes with E[B] as an edge.
                    U = edges[BIndex];
                    V = -U.Perp();
                    UpdateBox( hullPoints[LIndex], hullPoints[RIndex],
                               hullPoints[BIndex], hullPoints[TIndex], U, V,
                               minAreaDiv4 );

                    // Mark edge visited and rotate the calipers.
                    visited[BIndex] = true;
                    if ( ++BIndex == numPoints )
                    {
                        BIndex = 0;
                    }
                }
                break;
            case F_RIGHT:
                if ( visited[RIndex] )
                {
                    done = true;
                }
                else
                {
                    // Compute box axes with E[R] as an edge.
                    V = edges[RIndex];
                    U = V.Perp();
                    UpdateBox( hullPoints[LIndex], hullPoints[RIndex],
                               hullPoints[BIndex], hullPoints[TIndex], U, V,
                               minAreaDiv4 );

                    // Mark edge visited and rotate the calipers.
                    visited[RIndex] = true;
                    if ( ++RIndex == numPoints )
                    {
                        RIndex = 0;
                    }
                }
                break;
            case F_TOP:
                if ( visited[TIndex] )
                {
                    done = true;
                }
                else
                {
                    // Compute box axes with E[T] as an edge.
                    U = -edges[TIndex];
                    V = -U.Perp();
                    UpdateBox( hullPoints[LIndex], hullPoints[RIndex],
                               hullPoints[BIndex], hullPoints[TIndex], U, V,
                               minAreaDiv4 );

                    // Mark edge visited and rotate the calipers.
                    visited[TIndex] = true;
                    if ( ++TIndex == numPoints )
                    {
                        TIndex = 0;
                    }
                }
                break;
            case F_LEFT:
                if ( visited[LIndex] )
                {
                    done = true;
                }
                else
                {
                    // Compute box axes with E[L] as an edge.
                    V = -edges[LIndex];
                    U = V.Perp();
                    UpdateBox( hullPoints[LIndex], hullPoints[RIndex],
                               hullPoints[BIndex], hullPoints[TIndex], U, V,
                               minAreaDiv4 );

                    // Mark edge visited and rotate the calipers.
                    visited[LIndex] = true;
                    if ( ++LIndex == numPoints )
                    {
                        LIndex = 0;
                    }
                }
                break;
            case F_NONE:
                // The polygon is a rectangle.
                done = true;
                break;
            }
        }

        delete1( visited );
        delete1( edges );
        if ( !isConvexPolygon )
        {
            delete1( hullPoints );
        }
    }