//static int matchCounter = 0;
bool SetOperations::CollectFacetVisitor::AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex)
{
  if (rclFacet.IsFlag(MeshFacet::MARKED) && rclFrom.IsFlag(MeshFacet::MARKED))
  { // facet connected to an edge
    unsigned long pt0 = rclFrom._aulPoints[neighbourIndex], pt1 = rclFrom._aulPoints[(neighbourIndex+1)%3];
    Edge edge(_mesh.GetPoint(pt0), _mesh.GetPoint(pt1));

    std::map<Edge, EdgeInfo>::iterator it = _edges.find(edge);

    if (it != _edges.end())
    {
      if (_addFacets == -1)
      { // detemine if the facets shoud add or not only once
        MeshGeomFacet facet = _mesh.GetFacet(rclFrom); // triangulated facet
        MeshGeomFacet facetOther = it->second.facets[1-_side][0]; // triangulated facet from same edge and other mesh
        Vector3f normalOther = facetOther.GetNormal();
        //Vector3f normal = facet.GetNormal();

        Vector3f edgeDir = it->first.pt1 - it->first.pt2;
        Vector3f ocDir = (edgeDir % (facet.GetGravityPoint() - it->first.pt1)) % edgeDir;
        ocDir.Normalize();
        Vector3f ocDirOther = (edgeDir % (facetOther.GetGravityPoint() - it->first.pt1)) % edgeDir;
        ocDirOther.Normalize();

        //Vector3f dir = ocDir % normal;
        //Vector3f dirOther = ocDirOther % normalOther;

        bool match = ((ocDir * normalOther) * _mult) < 0.0f;

        //if (matchCounter == 1)
        //{
        //  // _builder.addSingleArrow(it->second.pt1, it->second.pt1 + edgeDir, 3, 0.0, 1.0, 0.0);

        //  _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3.0, 1.0, 0.0, 0.0);
        //  // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + ocDir, 3, 1.0, 0.0, 0.0);
        //  _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + normal, 3, 1.0, 0.5, 0.0);
        //  // _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dir, 3, 1.0, 1.0, 0.0);

        //  _builder.addSingleTriangle(facetOther._aclPoints[0], facetOther._aclPoints[1], facetOther._aclPoints[2], true, 3.0, 0.0, 0.0, 1.0);
        //  // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + ocDirOther, 3, 0.0, 0.0, 1.0);
        //  _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + normalOther, 3, 0.0, 0.5, 1.0);
        //  // _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirOther, 3, 0.0, 1.0, 1.0);

        //}

       // float scalar = dir * dirOther * _mult;
       // bool match = scalar > 0.0f;


        //MeshPoint pt0 = it->first.pt1;
        //MeshPoint pt1 = it->first.pt2;

        //int i, n0 = -1, n1 = -1, m0 = -1, m1 = -1;
        //for (i = 0; i < 3; i++)
        //{
        //  if ((n0 == -1) && (facet._aclPoints[i] == pt0))
        //    n0 = i;
        //  if ((n1 == -1) && (facet._aclPoints[i] == pt1))
        //    n1 = i;
        //  if ((m0 == -1) && (facetOther._aclPoints[i] == pt0))
        //    m0 = i;
        //  if ((m1 == -1) && (facetOther._aclPoints[i] == pt1))
        //    m1 = i;
        //}

        //if ((n0 != -1) && (n1 != -1) && (m0 != -1) && (m1 != -1))
        //{
        //  bool orient_n = n1 > n0;
        //  bool orient_m = m1 > m0;

        //  Vector3f dirN = facet._aclPoints[n1] - facet._aclPoints[n0];
        //  Vector3f dirM = facetOther._aclPoints[m1] - facetOther._aclPoints[m0];

        //  if (matchCounter == 1)
        //  {
        //    _builder.addSingleArrow(facet.GetGravityPoint(), facet.GetGravityPoint() + dirN, 3, 1.0, 1.0, 0.0);
        //    _builder.addSingleArrow(facetOther.GetGravityPoint(), facetOther.GetGravityPoint() + dirM, 3, 0.0, 1.0, 1.0);
        //  }

        //  if (_mult > 0.0)
        //    match = orient_n == orient_m;
        //  else
        //    match = orient_n != orient_m;
        //}
  
        if (match)
          _addFacets = 0;
        else
          _addFacets = 1;

        //matchCounter++;
      }

      return false;
    }    
  }

  return true;
}
Example #2
0
void ExportPovrayCamera(Camera* pcamera, FILE *fp)
{
	Vector3f pos, upvec, viewdir, lookat;
	float fov, fovpi;
	assert(pcamera!=NULL);
	assert(fp!=NULL);

	//output camera info.
	Vec posvec = pcamera->position();
	pos = Vector3f(posvec.x, posvec.y, posvec.z);
	Vec up = pcamera->upVector(); 
	upvec = Vector3f(up.x, up.y, up.z);
	Vec view = pcamera->viewDirection(); 
	viewdir = Vector3f(view.x, view.y, view.z);
	fovpi = pcamera->horizontalFieldOfView();
	fov = fovpi * 180 / PI;

	upvec.Normalize();
	viewdir.Normalize();
	Vector3f xAxis = CrossProd(viewdir,upvec);
	if (Magnitude(xAxis) < 1E-10){
      // target is aligned with upVector, this means a rotation around X axis
      // X axis is then unchanged, let's keep it !
		//xAxis = pcamera->frame()->inverseTransformOf(Vec(1.0, 0.0, 0.0));
		assert(0);
    }
	xAxis.Normalize();
	
	//the size matter;
	float znear = 1.0f; //pcamera->zNear();
	viewdir = viewdir*znear;
	double dw = 2*znear*tan(fovpi * 0.5);
	dw *= (800.0/pcamera->screenWidth());
	xAxis = xAxis * dw;
	//upvec = upvec * (dw / pcamera->aspectRatio());
	upvec = upvec * dw; 
	lookat = pos + viewdir;

	pos = VEC2POVVEC(pos);
	upvec = VEC2POVVEC(upvec);
	viewdir = VEC2POVVEC(viewdir);
	xAxis = VEC2POVVEC(xAxis);
	lookat = VEC2POVVEC(lookat);

	fprintf(fp, "//Window width=%d, height=%d.\n", pcamera->screenWidth(), pcamera->screenHeight());
	fprintf(fp, "camera {\n");
	fprintf(fp, "\tperspective\n");
	fprintf(fp, "\tlocation <%f, %f, %f>\n", pos.x, pos.y, pos.z);
	fprintf(fp, "\tdirection <%f, %f, %f>\n", viewdir.x, viewdir.y, viewdir.z);
	fprintf(fp, "\tright <%f, %f, %f>\n", xAxis.x, xAxis.y, xAxis.z);
	fprintf(fp, "\tup <%f, %f, %f> *(image_height/image_width)\n", upvec.x, upvec.y, upvec.z);
	//fprintf(fp, "\tlook_at <%f, %f, %f>\n", lookat.x, lookat.y, lookat.z);
	fprintf(fp, "\tangle %f\n", fov);
	fprintf(fp, "}\n\n\n");
	
	//export a view associated camera;
	fprintf(fp, "light_source{\n");
	fprintf(fp, "\t<%f, %f, %f>\n", pos.x, pos.y, pos.z); 
    fprintf(fp, "\trgb <1.0, 1.0, 1.0>*EYELIGHT_INTENSITY\n");  
    fprintf(fp, "\tshadowless");
	fprintf(fp, "}\n\n\n");
}
void SetOperations::TriangulateMesh (const MeshKernel &cutMesh, int side)
{
  // Triangulate Mesh 
  std::map<unsigned long, std::list<std::set<MeshPoint>::iterator> >::iterator it1;
  for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); it1++)
  {
    std::vector<Vector3f> points;
    std::set<MeshPoint>   pointsSet;

    unsigned long fidx = it1->first;
    MeshGeomFacet f = cutMesh.GetFacet(fidx);

    //if (side == 1)
    //    _builder.addSingleTriangle(f._aclPoints[0], f._aclPoints[1], f._aclPoints[2], 3, 0, 1, 1);

     // facet corner points
    //const MeshFacet& mf = cutMesh._aclFacetArray[fidx];
    int i;
    for (i = 0; i < 3; i++)
    {
      pointsSet.insert(f._aclPoints[i]);
      points.push_back(f._aclPoints[i]);
    }
    
    // triangulated facets
    std::list<std::set<MeshPoint>::iterator>::iterator it2;
    for (it2 = it1->second.begin(); it2 != it1->second.end(); it2++)
    {
      if (pointsSet.find(*(*it2)) == pointsSet.end())
      {
        pointsSet.insert(*(*it2));
        points.push_back(*(*it2));
      }

    }

    Vector3f normal = f.GetNormal();
    Vector3f base = points[0];
    Vector3f dirX = points[1] - points[0];
    dirX.Normalize();
    Vector3f dirY = dirX % normal;

    // project points to 2D plane
    i = 0;
    std::vector<Vector3f>::iterator it;
    std::vector<Vector3f> vertices;
    for (it = points.begin(); it != points.end(); it++)
    {
      Vector3f pv = *it;
      pv.TransformToCoordinateSystem(base, dirX, dirY);
      vertices.push_back(pv);
    }

    DelaunayTriangulator tria;
    tria.SetPolygon(vertices);
    tria.TriangulatePolygon();

    std::vector<MeshFacet> facets = tria.GetFacets();
    for (std::vector<MeshFacet>::iterator it = facets.begin(); it != facets.end(); ++it)
    {
      if ((it->_aulPoints[0] == it->_aulPoints[1]) ||
          (it->_aulPoints[1] == it->_aulPoints[2]) ||
          (it->_aulPoints[2] == it->_aulPoints[0]))
      { // two same triangle corner points
        continue;
      }
  
      MeshGeomFacet facet(points[it->_aulPoints[0]],
                          points[it->_aulPoints[1]],
                          points[it->_aulPoints[2]]);

      //if (side == 1)
      // _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1);

      //if (facet.Area() < 0.0001f)
      //{ // too small facet
      //  continue;
      //}

      float dist0 = facet._aclPoints[0].DistanceToLine
          (facet._aclPoints[1],facet._aclPoints[1] - facet._aclPoints[2]);
      float dist1 = facet._aclPoints[1].DistanceToLine
          (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[2]);
      float dist2 = facet._aclPoints[2].DistanceToLine
          (facet._aclPoints[0],facet._aclPoints[0] - facet._aclPoints[1]);

      if ((dist0 < _minDistanceToPoint) ||
          (dist1 < _minDistanceToPoint) ||
          (dist2 < _minDistanceToPoint))
      {
        continue;
      }

      //dist0 = (facet._aclPoints[0] - facet._aclPoints[1]).Length();
      //dist1 = (facet._aclPoints[1] - facet._aclPoints[2]).Length();
      //dist2 = (facet._aclPoints[2] - facet._aclPoints[3]).Length();

      //if ((dist0 < _minDistanceToPoint) || (dist1 < _minDistanceToPoint) || (dist2 < _minDistanceToPoint))
      //{
      //  continue;
      //}

      facet.CalcNormal();
      if ((facet.GetNormal() * f.GetNormal()) < 0.0f)
      { // adjust normal
         std::swap(facet._aclPoints[0], facet._aclPoints[1]);
         facet.CalcNormal();
      }


      int j;
      for (j = 0; j < 3; j++)
      {
        std::map<Edge, EdgeInfo>::iterator eit = _edges.find(Edge(facet._aclPoints[j], facet._aclPoints[(j+1)%3]));

        if (eit != _edges.end())
        {

          if (eit->second.fcounter[side] < 2)
          {
            //if (side == 0)
            //   _builder.addSingleTriangle(facet._aclPoints[0], facet._aclPoints[1], facet._aclPoints[2], true, 3, 0, 1, 1);

            eit->second.facet[side] = fidx;
            eit->second.facets[side][eit->second.fcounter[side]] = facet;
            eit->second.fcounter[side]++;
            facet.SetFlag(MeshFacet::MARKED); // set all facets connected to an edge: MARKED

          }
        }
      }

      _newMeshFacets[side].push_back(facet);

    } // for (i = 0; i < (out->numberoftriangles * 3); i += 3)
  } // for (it1 = _facet2points[side].begin(); it1 != _facet2points[side].end(); it1++)
}
Example #4
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	if ((m_Target != NULL) && m_Target->IsDestroyed())
		m_Target = NULL;

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		if (m_bOnGround)
		{
			m_Destination.y = FindFirstNonAirBlockPosition(m_Destination.x, m_Destination.z);

			if (DoesPosYRequireJump((int)floor(m_Destination.y)))
			{
				m_bOnGround = false;
				AddPosY(1.5); // Jump!!
			}
		}

		Vector3f Distance = m_Destination - GetPosition();
		if(!ReachedDestination() && !ReachedFinalDestination()) // If we haven't reached any sort of destination, move
		{
			Distance.y = 0;
			Distance.Normalize();
			Distance *= 5;
			SetSpeedX(Distance.x);
			SetSpeedZ(Distance.z);

			if (m_EMState == ESCAPING)
			{	//Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
		}
		else
		{
			if (ReachedFinalDestination()) // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate
			{
				FinishPathFinding();
			}
			else
			{
				TickPathFinding(); // We have reached the next point in our path, calculate another point
			}
		}
	}

	SetPitchAndYawFromDestination();
	HandleFalling();

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}	
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}	
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
	}  // switch (m_EMState)

	BroadcastMovementUpdate();
}
Example #5
0
//==============================
// BitmapFontSurfaceLocal::Finish
// transform all vertex blocks into the vertices array so they're ready to be uploaded to the VBO
// We don't have to do this for each eye because the billboarded surfaces are sorted / aligned
// based on their distance from / direction to the camera view position and not the camera direction.
void BitmapFontSurfaceLocal::Finish( Matrix4f const & viewMatrix )
{
    DROID_ASSERT( this != NULL, "BitmapFont" );

	//SPAM( "BitmapFontSurfaceLocal::Finish" );

	Matrix4f invViewMatrix = viewMatrix.Inverted(); // if the view is never scaled or sheared we could use Transposed() here instead
	Vector3f viewPos = invViewMatrix.GetTranslation();

	// sort vertex blocks indices based on distance to pivot
	int const MAX_VERTEX_BLOCKS = 256;
	vbSort_t vbSort[MAX_VERTEX_BLOCKS];
	int const n = VertexBlocks.GetSizeI();
	for ( int i = 0; i < n; ++i )
	{
		vbSort[i].VertexBlockIndex = i;
		VertexBlockType & vb = VertexBlocks[i];
		vbSort[i].DistanceSquared = ( vb.Pivot - viewPos ).LengthSq();
	}

	qsort( vbSort, n, sizeof( vbSort[0] ), VertexBlockSortFn );

	// transform the vertex blocks into the vertices array
	CurIndex = 0;
	CurVertex = 0;

	// TODO:
	// To add multiple-font-per-surface support, we need to add a 3rd component to s and t, 
	// then get the font for each vertex block, and set the texture index on each vertex in 
	// the third texture coordinate.
	for ( int i = 0; i < VertexBlocks.GetSizeI(); ++i )
	{		
		VertexBlockType & vb = VertexBlocks[vbSort[i].VertexBlockIndex];
		Matrix4f transform;
		if ( vb.Billboard )
		{
			if ( vb.TrackRoll )
			{
				transform = invViewMatrix;
			}
			else
			{
                Vector3f textNormal = viewPos - vb.Pivot;
                textNormal.Normalize();
                transform = Matrix4f::CreateFromBasisVectors( textNormal, Vector3f( 0.0f, 1.0f, 0.0f ) );
			}
			transform.SetTranslation( vb.Pivot );
		}
		else
		{
			transform.SetIdentity();
			transform.SetTranslation( vb.Pivot );
		}

		for ( int j = 0; j < vb.NumVerts; j++ )
		{
			fontVertex_t const & v = vb.Verts[j];
			Vertices[CurVertex].xyz = transform.Transform( v.xyz );
			Vertices[CurVertex].s = v.s;
			Vertices[CurVertex].t = v.t;			
			*(UInt32*)(&Vertices[CurVertex].rgba[0]) = *(UInt32*)(&v.rgba[0]);
			*(UInt32*)(&Vertices[CurVertex].fontParms[0]) = *(UInt32*)(&v.fontParms[0]);
			CurVertex++;
		}
		CurIndex += ( vb.NumVerts / 2 ) * 3;
		// free this vertex block
		vb.Free();
	}
	// remove all elements from the vertex block (but don't free the memory since it's likely to be 
	// needed on the next frame.
	VertexBlocks.Clear();

	glBindVertexArrayOES_( Geo.vertexArrayObject );
	glBindBuffer( GL_ARRAY_BUFFER, Geo.vertexBuffer );
	glBufferSubData( GL_ARRAY_BUFFER, 0, CurVertex * sizeof( fontVertex_t ), (void *)Vertices );
	glBindVertexArrayOES_( 0 );
	
    Geo.indexCount = CurIndex;
}
Example #6
0
void Camera::Update(Device* device) {
	/* Handle key input */
	if(device->IsKeyPressed(Key::UP) || device->IsKeyPressed(Key::W)) {
		m_position += m_lookAt * m_increment;
	}
	if(device->IsKeyPressed(Key::DOWN) || device->IsKeyPressed(Key::S)) {
		m_position -= m_lookAt * m_increment;
	}
	if(device->IsKeyPressed(Key::LEFT) || device->IsKeyPressed(Key::A)) {
		Vector3f left = m_lookAt.Cross(m_up);
		left.Normalize();
		left *= m_increment;
		m_position += left; 
	}
	if(device->IsKeyPressed(Key::RIGHT) || device->IsKeyPressed(Key::D)) {
		Vector3f right = m_up.Cross(m_lookAt);
		right.Normalize();
		right *= m_increment;
		m_position += right; 
	}
	if(device->IsKeyPressed(Key::I)) {
		Vector3f right = m_up.Cross(m_lookAt);
		m_lookAt = Vector3f::RotateAxis(
			m_lookAt,
			right,
			-2.0f
		);
		m_lookAt.Normalize();
		m_up = Vector3f::RotateAxis(
			m_up,
			right,
			-2.0f
		);
		m_up.Normalize();
	}
	if(device->IsKeyPressed(Key::K)) {
		Vector3f right = m_up.Cross(m_lookAt);
		m_lookAt = Vector3f::RotateAxis(
			m_lookAt,
			right,
			2.0f
		);
		m_lookAt.Normalize();
		m_up = Vector3f::RotateAxis(
			m_up,
			right,
			2.0f
		);
		m_up.Normalize();
	}
	if(device->IsKeyPressed(Key::J)) {
		m_lookAt = Vector3f::RotateAxis(
			m_lookAt,
			m_up,
			-2.0f
		);
		m_lookAt.Normalize();
	}
	if(device->IsKeyPressed(Key::L)) {
		m_lookAt = Vector3f::RotateAxis(
			m_lookAt,
			m_up,
			2.0f
		);
		m_lookAt.Normalize();
	}
	return;
}
Example #7
0
/// Time passed in seconds..!
void PongPlayerProperty::Process(int timeInMs)
{
	List<Entity*> entities = MapMan.GetEntities();

	Time now = Time::Now();
	int secondsSinceLastInput = (now - lastUserInput).Seconds();
	if (secondsSinceLastInput < 1)
	{
		StopMovement();
		return;
	}

	bool moved = false;
	Entity * closestBall = 0;
	float closestDistance = 1000000.f;
	/// Check distance to ball. Fetch closest/most dangerous one!
	for (int i = 0; i < entities.Size(); ++i)
	{
		Entity * ball = entities[i];
		if (!ball->physics)
			continue;
		PongBallProperty * pbp = (PongBallProperty*) ball->GetProperty("PongBallProperty");
		if (!pbp)
			continue;
		if (pbp->sleeping)
			continue;

		// Check distance.
		Vector3f ballToPaddle = owner->position - ball->position;
		// Ignore balls going away.
		if (ball->physics->velocity.DotProduct(lookAt) > 0)
			continue;
		float distance = AbsoluteValue(ballToPaddle[0]);
		if (!ball->physics)
			continue;
		if (distance > 500.f)
			continue;
		if (distance < closestDistance)
		{
			closestBall = ball;
			closestDistance = distance;
		}
	}
	if (closestBall)
	{
		/// Ball on the wya here?!
		if (lookAt.DotProduct(closestBall->physics->velocity) < 0)
		{
			// Head towards it!
			Vector3f ballToPaddle = owner->position - closestBall->position;
			Vector3f toMove = -ballToPaddle;
			toMove.Normalize();
			toMove *= aiSpeed;
			toMove[1] += closestBall->physics->velocity[1] * 0.5f;
			toMove[0] = toMove[2] = 0;
			Physics.QueueMessage(new PMSetEntity(owner, PT_VELOCITY, Vector3f(toMove)));
			moved = true;
		}
	}
	if (!moved)
		StopMovement();
	
}
Example #8
0
int cTracer::GetHitNormal(const Vector3f & start, const Vector3f & end, const Vector3i & a_BlockPos)
{
	Vector3i SmallBlockPos = a_BlockPos;
	char BlockID = m_World->GetBlock( a_BlockPos.x, a_BlockPos.y, a_BlockPos.z);

	if (BlockID == E_BLOCK_AIR || IsBlockWater(BlockID))
	{
		return 0;
	}

	Vector3f BlockPos;
	BlockPos = Vector3f(SmallBlockPos);

	Vector3f Look = (end - start);
	Look.Normalize();

	float dot = Look.Dot( Vector3f(-1, 0, 0));  // first face normal is x -1
	if (dot < 0)
	{
		int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x, BlockPos.y, BlockPos.x, BlockPos.y + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x, BlockPos.z, BlockPos.x, BlockPos.z + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(-1, 0, 0));
				return 1;
			}
		}
	}
	dot = Look.Dot( Vector3f(0, 0, -1));  // second face normal is z -1
	if (dot < 0)
	{
		int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z, BlockPos.y, BlockPos.z, BlockPos.y + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z, BlockPos.x, BlockPos.z, BlockPos.x + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, 0, -1));
				return 2;
			}
		}
	}
	dot = Look.Dot( Vector3f(1, 0, 0));  // third face normal is x 1
	if (dot < 0)
	{
		int Lines = LinesCross( start.x, start.y, end.x, end.y, BlockPos.x + 1, BlockPos.y, BlockPos.x + 1, BlockPos.y + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.x, start.z, end.x, end.z, BlockPos.x + 1, BlockPos.z, BlockPos.x + 1, BlockPos.z + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(1, 0, 0), Vector3f(1, 0, 0));
				return 3;
			}
		}
	}
	dot = Look.Dot( Vector3f(0, 0, 1));  // fourth face normal is z 1
	if (dot < 0)
	{
		int Lines = LinesCross( start.z, start.y, end.z, end.y, BlockPos.z + 1, BlockPos.y, BlockPos.z + 1, BlockPos.y + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.z, start.x, end.z, end.x, BlockPos.z + 1, BlockPos.x, BlockPos.z + 1, BlockPos.x + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 0, 1), Vector3f(0, 0, 1));
				return 4;
			}
		}
	}
	dot = Look.Dot( Vector3f(0, 1, 0));  // fifth face normal is y 1
	if (dot < 0)
	{
		int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y + 1, BlockPos.x, BlockPos.y + 1, BlockPos.x + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y + 1, BlockPos.z, BlockPos.y + 1, BlockPos.z + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos + Vector3f(0, 1, 0), Vector3f(0, 1, 0));
				return 5;
			}
		}
	}
	dot = Look.Dot( Vector3f(0, -1, 0));  // sixth face normal is y -1
	if (dot < 0)
	{
		int Lines = LinesCross( start.y, start.x, end.y, end.x, BlockPos.y, BlockPos.x, BlockPos.y, BlockPos.x + 1);
		if (Lines == 1)
		{
			Lines = LinesCross( start.y, start.z, end.y, end.z, BlockPos.y, BlockPos.z, BlockPos.y, BlockPos.z + 1);
			if (Lines == 1)
			{
				intersect3D_SegmentPlane( start, end, BlockPos, Vector3f(0, -1, 0));
				return 6;
			}
		}
	}
	return 0;
}
/** Checks states via InputManager. Regular key-bindings should probably still be defined in the main game state 
	and then passed on as messages to the character with inputFocus turned on.
*/
void FirstPersonPlayerProperty::ProcessInput()
{
	// Skip if CTLR is pressed, should be some other binding then.
	if (InputMan.KeyPressed(KEY::CTRL) || InputMan.KeyPressed(KEY::ALT))
		return;
	forward = 0.f;
	// Should probably check some lexicon of key-bindings here too. or?
	if (InputMan.KeyPressed(KEY::W))
		forward -= 1.f;
	if (InputMan.KeyPressed(KEY::S))
		forward += 1.f;
	right = 0.f;
	if (InputMan.KeyPressed(KEY::A))
		right -= 1.f;
	if (InputMan.KeyPressed(KEY::D))
		right += 1.f;

	/// o.o
	if (InputMan.KeyPressedThisFrame(KEY::R))
	{
		ToggleAutorun();
	}

	if (InputMan.KeyPressed(KEY::SPACE))
	{
		if (!jumping)
		{
			// Jump!
			PhysicsQueue.Add(new PMApplyImpulse(owner, Vector3f(0,jumpSpeed,0), Vector3f()));
			lastJump = Time::Now();
			jumping = true;
			PhysicsQueue.Add(new PMSetEntity(owner, PT_ACCELERATION, Vector3f()));
			/// Cancel auto run as well.
			PhysicsQueue.Add(new PMSetEntity(owner, PT_RELATIVE_ACCELERATION, Vector3f()));
		}
	}

	forward *= movementSpeed;

	float rotationSpeed = 1.2f;
	right *= rotationSpeed;

	Vector3f acc;
	acc[2] = forward;

//	Vector3f rot;
//	rot[1] = right;

	// 
	// Auto-running,.
	if (autorun)
	{
		if (lastAcc != acc)
		{
		}
		if (right != lastRight)
		{
			// Rotate int Y..
			Quaternion q = Quaternion(Vector3f(0,1,0), right);
			PhysicsQueue.Add(new PMSetEntity(owner, PT_ROTATIONAL_VELOCITY, q));
			lastRight = right;
		}
	}
			
	/// o-o cameraaaa focsuuuuuu!
	if (owner->cameraFocus)
	{
		
		// Check mouse position.
		if (raycast)
			UpdateTargetsByCursorPosition();


		// Free-form running (relative to camera)
		if (!autorun)
		{
			/// Get camera transform.
			Camera * camera = owner->cameraFocus;
			if (!camera)
				return;
			Vector3f camLookAt = camera->LookingAt();
			Vector3f forwardVector = -forward * camLookAt;
			forwardVector.Normalize();
			Vector3f rightwardVector = -right * camera->LeftVector();
			rightwardVector.Normalize();
			Vector3f newVelocity = forwardVector + rightwardVector;
			// Remove Y-component.
			newVelocity[1] = 0;
			Vector3f normalizedVelocity = newVelocity.NormalizedCopy();
			// Multiply movement speed.
			newVelocity = normalizedVelocity * movementSpeed;
			UpdateVelocity(newVelocity);
		}


		/// Make sure the camera is rotating around the center of the entity. <- wat.
		float height = 1.7f;
		if (owner->cameraFocus->relativePosition[1] != height)
		{
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_RELATIVE_POSITION_Y, height));
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_TRACKING_POSITION_OFFSET, Vector3f(0,height,0)));
		}
		/// Camera Control, Booyakasha!
		float cameraRight = 0.f;
		if (InputMan.KeyPressed(KEY::LEFT))
			cameraRight += 1.f;
		if (InputMan.KeyPressed(KEY::RIGHT))
			cameraRight -= 1.f;

		// Set it! :D
		static float pastCameraRight = 0.f;
		if (cameraRight != pastCameraRight)
		{
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_ROTATION_SPEED_YAW, -cameraRight));
			pastCameraRight = cameraRight;
		}

		/// Camera updown
		float cameraUp = 0.f;
		if (InputMan.KeyPressed(KEY::UP))
			cameraUp += 1.f;
		if (InputMan.KeyPressed(KEY::DOWN))
			cameraUp -= 1.f;
		static float pastCameraUp = 0.f;
		if (cameraUp != pastCameraUp)
		{
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_ROTATION_SPEED_PITCH, -cameraUp)); 
			pastCameraUp = cameraUp;
		}


		float cameraZoom = 0.f;
		float cameraZoomMultiplier = 1.00f;
#define CONSTANT_ZOOM_SPEED 2.2f
#define ZOOM_MULTIPLIER_SPEED 1.5f
		if (InputMan.KeyPressed(KEY::PG_DOWN))
		{
			cameraZoomMultiplier *= ZOOM_MULTIPLIER_SPEED;
			cameraZoom = CONSTANT_ZOOM_SPEED;
		}
		if (InputMan.KeyPressed(KEY::PG_UP))
		{
			cameraZoomMultiplier /= ZOOM_MULTIPLIER_SPEED;
			cameraZoom = - CONSTANT_ZOOM_SPEED;
		}
		static float pastCameraZoom = 1.f;
		if (cameraZoom != pastCameraZoom)
		{
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_DISTANCE_FROM_CENTER_OF_MOVEMENT_SPEED, cameraZoom));
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_DISTANCE_FROM_CENTER_OF_MOVEMENT_SPEED_MULTIPLIER, cameraZoomMultiplier));
			pastCameraZoom = cameraZoom;
		}
		float cameraTurn = 0.f;
		if (InputMan.KeyPressed(KEY::LEFT))
			cameraTurn += 1.f;
		if (InputMan.KeyPressed(KEY::RIGHT))
			cameraTurn += -1;
		static float pastCameraTurn = 0.f;
		if (cameraTurn != pastCameraTurn)
		{
			cameraTurn *= 2.f;
			pastCameraTurn = cameraTurn;
			GraphicsQueue.Add(new GMSetCamera(owner->cameraFocus, CT_ROTATION_SPEED_YAW, cameraTurn));
		}
	}
}
Example #10
0
void Mesh::_CalculateNormalsAndTangents()
{
	if (mT.IsValid() || mV.IsEmpty()) return;

	// Don't bother with points or lines
	if (mPrimitive == IGraphics::Primitive::Point	||
		mPrimitive == IGraphics::Primitive::Line	||
		mPrimitive == IGraphics::Primitive::LineStrip) return;

	// Allocate a temporary buffer to store binormals
	Array<Vector3f> binormals (mV.GetSize());

	// Remember whether we already have normals to work with
	bool calculateNormals  = (mV.GetSize() != mN.GetSize());

	// We can only calculate tangents if the texture coordinates are available
	bool calculateTangents = (mV.GetSize() == mTc0.GetSize());

	// If we should calculate normals, clear the existing normal array
	if (calculateNormals)
	{
		mN.Clear();
		mN.ExpandTo(mV.GetSize());
	}

	// Expand the tangent array
	if (calculateTangents) mT.ExpandTo(mV.GetSize());

	// The number of indices
	uint size = mIndices.IsValid() ? mIndices.GetSize() : GetNumberOfVertices();

	// Triangles
	if (size > 2)
	{
		bool even = true;
		uint i0, i1, i2;

		for (uint i = 0; i + 2 < size; )
		{
			i0 = i;
			i1 = i+1;
			i2 = i+2;

			if (mIndices.IsValid())
			{
				i0 = mIndices[i0];
				i1 = mIndices[i1];
				i2 = mIndices[i2];
			}

			ASSERT(i0 < mV.GetSize(), "Index out of bounds!");
			ASSERT(i1 < mV.GetSize(), "Index out of bounds!");
			ASSERT(i2 < mV.GetSize(), "Index out of bounds!");

			const Vector3f& v0 ( mV[i0] );
			const Vector3f& v1 ( mV[i1] );
			const Vector3f& v2 ( mV[i2] );

			Vector3f v10 (v1 - v0);
			Vector3f v20 (v2 - v0);

			if (calculateNormals)
			{
				Vector3f normal (Cross(v10, v20));

				mN[i0] += normal;
				mN[i1] += normal;
				mN[i2] += normal;
			}

			if (calculateTangents)
			{
				const Vector2f& t0 ( mTc0[i0] );
				const Vector2f& t1 ( mTc0[i1] );
				const Vector2f& t2 ( mTc0[i2] );

				Vector2f t10 (t1 - t0);
				Vector2f t20 (t2 - t0);

				float denominator = t10.x * t20.y - t20.x * t10.y;

				if ( Float::IsNotZero(denominator) )
				{
					float scale = 1.0f / denominator;

					Vector3f tangent ((v10.x * t20.y - v20.x * t10.y) * scale,
									  (v10.y * t20.y - v20.y * t10.y) * scale,
									  (v10.z * t20.y - v20.z * t10.y) * scale);

					Vector3f binormal((v20.x * t10.x - v10.x * t20.x) * scale,
									  (v20.y * t10.x - v10.y * t20.x) * scale,
									  (v20.z * t10.x - v10.z * t20.x) * scale);

					mT[i0] += tangent;
					mT[i1] += tangent;
					mT[i2] += tangent;

					binormals[i0] += binormal;
					binormals[i1] += binormal;
					binormals[i2] += binormal;
				}
			}

			if (mPrimitive == IGraphics::Primitive::Triangle)
			{
				i += 3;
			}
			else if (mPrimitive == IGraphics::Primitive::Quad)
			{
				if (even) ++i;
				else i += 3;
				even = !even;
			}
			else ++i;
		}

		// If we're calculating normals we need to match all normals with identical vertices
		if (calculateNormals)
		{
			Array<uint> matches;

			for (uint i = 0; i < mV.GetSize(); ++i)
			{
				matches.Clear();
				matches.Expand() = i;
				Vector3f N = mN[i];

				const Vector3f& V (mV[i]);

				for (uint b = 0; b < mV.GetSize(); ++b)
				{
					if (i != b && V == mV[b])
					{
						matches.Expand() = b;
						N += mN[b];
					}
				}

				N.Normalize();

				for (uint b = 0; b < matches.GetSize(); ++b)
				{
					mN[ matches[b] ] = N;
				}
			}
		}
	}

	if (calculateTangents)
	{
		// Normalize all tangents
		for (uint i = 0; i < mV.GetSize(); ++i)
		{
			Vector3f&  T (mT[i]);
			Vector3f&  B (binormals[i]);
			Vector3f&  N (mN[i]);

			// In order to avoid visible seams, the tangent should be 90 degrees to the normal
			// Note to self: Gram-Schmidt formula for the cross product below: T = T - N * Dot(N, T);
			T = Cross(B, N);
			T.Normalize();

			// Flip the tangent if the handedness is incorrect
			if (Dot(Cross(T, B), N) < 0.0f) T.Flip();
		}
	}
}
Example #11
0
//----------------------------------------------------------------------------------------------------
Vector3f Vector3f::Normalize( const Vector3f& A )
{
    Vector3f vec = A;
    vec.Normalize();
    return vec;
}
Example #12
0
void Movement::MoveToLocation()
{
	Vector3f pos;
	bool isPosition = false;
	/// Check if we reached our destination?
	switch(location)
	{
		case Location::VECTOR:
		{
			// Adjust movement vector?
			pos = levelEntity->worldPosition + vec;
			isPosition = true;
			break;
		}
		case Location::LEFT_EDGE:
		{
			if (state == 0)
			{
				SetDirection(Vector3f(-1,0,0));
				++state;
			}
			else if (shipEntity->worldPosition.x < leftEdge && state == 1)
			{
				SetDirection(Vector2f());
				++state;
			}
			break;
		}
		case Location::RIGHT_EDGE:
			if (state == 0)
			{
				SetDirection(Vector3f(1,0,0));
				++state;
			}
			else if (shipEntity->worldPosition.x > rightEdge && state == 1)
			{
				SetDirection(Vector2f());
				++state;
			}
			break;
		case Location::UPPER_EDGE:
		{
			if (state == 0)
			{
				SetDirection(Vector3f(0,1,0));
				++state;
			}
			else if (shipEntity->worldPosition[1] > 20.f && state == 1)
			{
				SetDirection(Vector2f());
				++state;
			}
			break;
		}
		case Location::LOWER_EDGE:
		{
			if (state == 0)
			{
				SetDirection(Vector3f(0,-1,0));
				++state;
			}
			if (shipEntity->worldPosition[1] < 0.f && state == 1)
			{
				SetDirection(Vector2f());
				++state;
			}
			break;
		}
		case Location::CENTER: 
			pos = levelEntity->worldPosition;
			isPosition = true;
			break;
		case Location::PLAYER:
			if (playerShip->entity)
			{
				pos = playerShip->entity->worldPosition;
				isPosition = true;
			}
			else {
				SetDirection(Vector3f());
				return;
			}
			break;
		default:
			assert(false && "Movement unidentified");
	}
	if (isPosition)
	{
		Vector3f toPos = pos - shipEntity->worldPosition;
		if (toPos.LengthSquared() > 1)
			toPos.Normalize();
		SetDirection(toPos);
	}
}
Example #13
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	if ((m_Target != NULL) && m_Target->IsDestroyed())
		m_Target = NULL;

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		if (m_bOnGround)
		{
			if (DoesPosYRequireJump((int)floor(m_Destination.y)))
			{
				m_bOnGround = false;

				// TODO: Change to AddSpeedY once collision detection is fixed - currently, mobs will go into blocks attempting to jump without a teleport
				AddPosY(1.2);  // Jump!!
			}
		}

		Vector3f Distance = m_Destination - GetPosition();
		if (!ReachedDestination() && !ReachedFinalDestination())  // If we haven't reached any sort of destination, move
		{
			Distance.y = 0;
			Distance.Normalize();

			if (m_bOnGround)
			{
				Distance *= 2.5f;
			}
			else if (IsSwimming())
			{
				Distance *= 1.3f;
			}
			else
			{
				// Don't let the mob move too much if he's falling.
				Distance *= 0.25f;
			}

			AddSpeedX(Distance.x);
			AddSpeedZ(Distance.z);

			// It's too buggy!
			/*
			if (m_EMState == ESCAPING)
			{
				// Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
			*/
		}
		else
		{
			if (ReachedFinalDestination())  // If we have reached the ultimate, final destination, stop pathfinding and attack if appropriate
			{
				FinishPathFinding();
			}
			else
			{
				TickPathFinding();  // We have reached the next point in our path, calculate another point
			}
		}
	}

	SetPitchAndYawFromDestination();
	HandleFalling();

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
			
		case ATTACKING: break;
	}  // switch (m_EMState)

	BroadcastMovementUpdate();
}
void Particle::Render(Camera* camera, unsigned int i, bool drawAxes)
{
    switch( this->_type )
    {
    case BillBoard:
        break;
    case VectorAligned:
        break;
    case ScreenFacing:
    default:
    {
        Vector3f particleToCamera = camera->GetPosition()-this->_position;
        this->_depth = particleToCamera.Length();

        Vector3f cameraYAxis = camera->GetEulerRotation()*Vector3f(sin(this->_rotation), cos(this->_rotation), 0.0f);
        Vector3f localX = cameraYAxis.Cross(particleToCamera);
        Vector3f localY = particleToCamera.Cross(localX);

        localX.Normalize();
        localY.Normalize();

        // Set blend mode
        switch( this->_blendMode )
        {
        case Subtractive:
            glBlendFunc(GL_ONE_MINUS_SRC_ALPHA, GL_ONE);
            break;
        case Additive:
            glBlendFunc(GL_SRC_ALPHA, GL_ONE);
            break;
        case Normal:
        default:
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            break;
        }

        // Evaluate animators
        float t = 1.0f-this->_life/this->_maxLife;

        Vector2f size = this->_size->GetValue(t);

        // Bind texture
        if( this->_texture )
        {
            glBindTexture(GL_TEXTURE_2D, this->_texture->GetTextureName());
        }

        // Render
        glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
        glBegin(GL_QUADS);

        glColor4f(this->_color.r, this->_color.g, this->_color.b, this->_color.a);

        // TODO (Viet Nguyen): Get rid of texture coordinate hacks!!!!

        glTexCoord2f(0.0f, 0.0f);
        glVertex3fv((float*)
                    (this->_position+(-localX)*size.width+(-localY)*size.height));

        glTexCoord2f(1.0f/4.0f/*!!!!*/, 0.0f);
        glVertex3fv((float*)
                    (this->_position+localX*size.width+(-localY)*size.height));

        glTexCoord2f(1.0f/4.0f/*!!!!*/, 1.0f);
        glVertex3fv((float*)
                    (this->_position+localX*size.width+localY*size.height));

        glTexCoord2f(0.0f, 1.0f);
        glVertex3fv((float*)
                    (this->_position+(-localX)*size.width+localY*size.height));

        glEnd();

        // Unbind texture
        if( this->_texture)
        {
            glBindTexture(GL_TEXTURE_2D, 0);
        }

        if( drawAxes )
        {
            glBegin(GL_LINES);
            glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);

            glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
            glVertex3fv((float*)(this->_position));
            glVertex3fv((float*)(this->_position+localX*size.width));

            glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
            glVertex3fv((float*)(this->_position));
            glVertex3fv((float*)(this->_position+localY*size.height));

            glEnd();
        }
    }
    }
}
Example #15
0
void Player::HandleMovement(double dt, std::vector<Ptr<CollisionModel> >* collisionModels,
	                        std::vector<Ptr<CollisionModel> >* groundCollisionModels, bool shiftDown)
{
    // Handle keyboard movement.
    // This translates BasePos based on the orientation and keys pressed.
    // Note that Pitch and Roll do not affect movement (they only affect view).
    Vector3f controllerMove;
    if(MoveForward || MoveBack || MoveLeft || MoveRight)
    {
        if (MoveForward)
        {
            controllerMove += ForwardVector;
        }
        else if (MoveBack)
        {
            controllerMove -= ForwardVector;
        }

        if (MoveRight)
        {
            controllerMove += RightVector;
        }
        else if (MoveLeft)
        {
            controllerMove -= RightVector;
        }
    }
    else if (GamepadMove.LengthSq() > 0)
    {
        controllerMove = GamepadMove;
    }
    controllerMove = GetOrientation(bMotionRelativeToBody).Rotate(controllerMove);    
    controllerMove.y = 0; // Project to the horizontal plane
    if (controllerMove.LengthSq() > 0)
    {
        // Normalize vector so we don't move faster diagonally.
        controllerMove.Normalize();
        controllerMove *= OVR::Alg::Min<float>(MoveSpeed * (float)dt * (shiftDown ? 3.0f : 1.0f), 1.0f);
    }

    // Compute total move direction vector and move length
    Vector3f orientationVector = controllerMove;
    float moveLength = orientationVector.Length();
    if (moveLength > 0)
        orientationVector.Normalize();
        
    float   checkLengthForward = moveLength;
    Planef  collisionPlaneForward;
    bool    gotCollision = false;

    for(size_t i = 0; i < collisionModels->size(); ++i)
    {
        // Checks for collisions at model base level, which should prevent us from
		// slipping under walls
        if (collisionModels->at(i)->TestRay(BodyPos, orientationVector, checkLengthForward,
				                            &collisionPlaneForward))
        {
            gotCollision = true;
            break;
        }
    }

    if (gotCollision)
    {
        // Project orientationVector onto the plane
        Vector3f slideVector = orientationVector - collisionPlaneForward.N
			* (orientationVector.Dot(collisionPlaneForward.N));

        // Make sure we aren't in a corner
        for(size_t j = 0; j < collisionModels->size(); ++j)
        {
            if (collisionModels->at(j)->TestPoint(BodyPos - Vector3f(0.0f, RailHeight, 0.0f) +
					                                (slideVector * (moveLength))) )
            {
                moveLength = 0;
                break;
            }
        }
        if (moveLength != 0)
        {
            orientationVector = slideVector;
        }
    }
    // Checks for collisions at foot level, which allows us to follow terrain
    orientationVector *= moveLength;
    BodyPos += orientationVector;

    Planef collisionPlaneDown;
    float adjustedUserEyeHeight = GetFloorDistanceFromTrackingOrigin(ovrTrackingOrigin_EyeLevel);
    float finalDistanceDown = adjustedUserEyeHeight + 10.0f;

    // Only apply down if there is collision model (otherwise we get jitter).
    if (groundCollisionModels->size())
    {
        for(size_t i = 0; i < groundCollisionModels->size(); ++i)
        {
            float checkLengthDown = adjustedUserEyeHeight + 10;
            if (groundCollisionModels->at(i)->TestRay(BodyPos, Vector3f(0.0f, -1.0f, 0.0f),
                checkLengthDown, &collisionPlaneDown))
            {
                finalDistanceDown = Alg::Min(finalDistanceDown, checkLengthDown);
            }
        }

        // Maintain the minimum camera height
        if (adjustedUserEyeHeight - finalDistanceDown < 1.0f)
        {
            BodyPos.y += adjustedUserEyeHeight - finalDistanceDown;
        }
    }
    
    SetBodyPos(BodyPos, false);
}
Example #16
0
void cMonster::Tick(float a_Dt, cChunk & a_Chunk)
{
	super::Tick(a_Dt, a_Chunk);

	if (m_Health <= 0)
	{
		// The mob is dead, but we're still animating the "puff" they leave when they die
		m_DestroyTimer += a_Dt / 1000;
		if (m_DestroyTimer > 1)
		{
			Destroy(true);
		}
		return;
	}

	// Burning in daylight
	HandleDaylightBurning(a_Chunk);
	
	HandlePhysics(a_Dt,a_Chunk);
	BroadcastMovementUpdate();

	a_Dt /= 1000;

	if (m_bMovingToDestination)
	{
		Vector3f Pos( GetPosition() );
		Vector3f Distance = m_Destination - Pos;
		if( !ReachedDestination() )
		{
			Distance.y = 0;
			Distance.Normalize();
			Distance *= 3;
			SetSpeedX( Distance.x );
			SetSpeedZ( Distance.z );

			if (m_EMState == ESCAPING)
			{	//Runs Faster when escaping :D otherwise they just walk away
				SetSpeedX (GetSpeedX() * 2.f);
				SetSpeedZ (GetSpeedZ() * 2.f);
			}
		}
		else
		{
			m_bMovingToDestination = false;
		}

		if( GetSpeed().SqrLength() > 0.f )
		{
			if( m_bOnGround )
			{
				Vector3f NormSpeed = Vector3f(GetSpeed()).NormalizeCopy();
				Vector3f NextBlock = Vector3f( GetPosition() ) + NormSpeed;
				int NextHeight;
				if (!m_World->TryGetHeight((int)NextBlock.x, (int)NextBlock.z, NextHeight))
				{
					// The chunk at NextBlock is not loaded
					return;
				}
				if( NextHeight > (GetPosY() - 1.0) && (NextHeight - GetPosY()) < 2.5 )
				{
					m_bOnGround = false;
					SetSpeedY(5.f); // Jump!!
				}
			}
		}
	}

	Vector3d Distance = m_Destination - GetPosition();
	if (Distance.SqrLength() > 0.1f)
	{
		double Rotation, Pitch;
		Distance.Normalize();
		VectorToEuler( Distance.x, Distance.y, Distance.z, Rotation, Pitch );
		SetHeadYaw (Rotation);
		SetRotation( Rotation );
		SetPitch( -Pitch );
	}

	switch (m_EMState)
	{
		case IDLE:
		{
			// If enemy passive we ignore checks for player visibility
			InStateIdle(a_Dt);
			break;
		}
	
		case CHASING:
		{
			// If we do not see a player anymore skip chasing action
			InStateChasing(a_Dt);
			break;
		}
	
		case ESCAPING:
		{
			InStateEscaping(a_Dt);
			break;
		}
	}  // switch (m_EMState)
}
Example #17
0
/**
 * If this matrix describes a rotation around an arbitrary axis with a translation (in axis direction)
 * then the base point of the axis, its direction, the rotation angle and the translation part get calculated.
 * In this case the return value is set to true, if this matrix doesn't describe a rotation false is returned. 
 *
 * The translation vector can be calculated with \a fTranslation * \a rclDir, whereas the length of \a rclDir
 * is normalized to 1.
 *
 * Note: In case the \a fTranslation part is zero then passing \a rclBase, \a rclDir and \a rfAngle to a new
 * matrix object creates an identical matrix.
 */
bool Matrix4D::toAxisAngle (Vector3f& rclBase, Vector3f& rclDir, float& rfAngle, float& fTranslation) const
{
  // First check if the 3x3 submatrix is orthogonal
  for ( int i=0; i<3; i++ ) {
    // length must be one
    if ( fabs(dMtrx4D[0][i]*dMtrx4D[0][i]+dMtrx4D[1][i]*dMtrx4D[1][i]+dMtrx4D[2][i]*dMtrx4D[2][i]-1.0) > 0.01 )
      return false;
    // scalar product with other rows must be zero
    if ( fabs(dMtrx4D[0][i]*dMtrx4D[0][(i+1)%3]+dMtrx4D[1][i]*dMtrx4D[1][(i+1)%3]+dMtrx4D[2][i]*dMtrx4D[2][(i+1)%3]) > 0.01 )
      return false;
  }

  // Okay, the 3x3 matrix is orthogonal.
  // Note: The section to get the rotation axis and angle was taken from WildMagic Library.
  //
  // Let (x,y,z) be the unit-length axis and let A be an angle of rotation.
  // The rotation matrix is R = I + sin(A)*P + (1-cos(A))*P^2 where
  // I is the identity and
  //
  //       +-        -+
  //   P = |  0 -z +y |
  //       | +z  0 -x |
  //       | -y +x  0 |
  //       +-        -+
  //
  // If A > 0, R represents a counterclockwise rotation about the axis in
  // the sense of looking from the tip of the axis vector towards the
  // origin.  Some algebra will show that
  //
  //   cos(A) = (trace(R)-1)/2  and  R - R^t = 2*sin(A)*P
  //
  // In the event that A = pi, R-R^t = 0 which prevents us from extracting
  // the axis through P.  Instead note that R = I+2*P^2 when A = pi, so
  // P^2 = (R-I)/2.  The diagonal entries of P^2 are x^2-1, y^2-1, and
  // z^2-1.  We can solve these for axis (x,y,z).  Because the angle is pi,
  // it does not matter which sign you choose on the square roots.
  //
  // For more details see also http://www.math.niu.edu/~rusin/known-math/97/rotations

  double fTrace = dMtrx4D[0][0] + dMtrx4D[1][1] + dMtrx4D[2][2];
  double fCos = 0.5*(fTrace-1.0);
  rfAngle = (float)acos(fCos);  // in [0,PI]

  if ( rfAngle > 0.0f )
  {
    if ( rfAngle < F_PI )
    {
      rclDir.x = (float)(dMtrx4D[2][1]-dMtrx4D[1][2]);
      rclDir.y = (float)(dMtrx4D[0][2]-dMtrx4D[2][0]);
      rclDir.z = (float)(dMtrx4D[1][0]-dMtrx4D[0][1]);
      rclDir.Normalize();
    }
    else
    {
      // angle is PI
      double fHalfInverse;
      if ( dMtrx4D[0][0] >= dMtrx4D[1][1] )
      {
        // r00 >= r11
        if ( dMtrx4D[0][0] >= dMtrx4D[2][2] )
        {
          // r00 is maximum diagonal term
          rclDir.x = (float)(0.5*sqrt(dMtrx4D[0][0] - dMtrx4D[1][1] - dMtrx4D[2][2] + 1.0));
          fHalfInverse = 0.5/rclDir.x;
          rclDir.y = (float)(fHalfInverse*dMtrx4D[0][1]);
          rclDir.z = (float)(fHalfInverse*dMtrx4D[0][2]);
        }
        else
        {
          // r22 is maximum diagonal term
          rclDir.z = (float)(0.5*sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
          fHalfInverse = 0.5/rclDir.z;
          rclDir.x = (float)(fHalfInverse*dMtrx4D[0][2]);
          rclDir.y = (float)(fHalfInverse*dMtrx4D[1][2]);
        }
      }
      else
      {
        // r11 > r00
        if ( dMtrx4D[1][1] >= dMtrx4D[2][2] )
        {
          // r11 is maximum diagonal term
          rclDir.y = (float)(0.5*sqrt(dMtrx4D[1][1] - dMtrx4D[0][0] - dMtrx4D[2][2] + 1.0));
          fHalfInverse  = 0.5/rclDir.y;
          rclDir.x = (float)(fHalfInverse*dMtrx4D[0][1]);
          rclDir.z = (float)(fHalfInverse*dMtrx4D[1][2]);
        }
        else
        {
          // r22 is maximum diagonal term
          rclDir.z = (float)(0.5*sqrt(dMtrx4D[2][2] - dMtrx4D[0][0] - dMtrx4D[1][1] + 1.0));
          fHalfInverse = 0.5/rclDir.z;
          rclDir.x = (float)(fHalfInverse*dMtrx4D[0][2]);
          rclDir.y = (float)(fHalfInverse*dMtrx4D[1][2]);
        }
      }
    }
  }
  else
  {
    // The angle is 0 and the matrix is the identity.  Any axis will
    // work, so just use the x-axis.
    rclDir.x = 1.0f;
    rclDir.y = 0.0f;
    rclDir.z = 0.0f;
    rclBase.x = 0.0f;
    rclBase.y = 0.0f;
    rclBase.z = 0.0f;
  }

  // This is the translation part in axis direction
  fTranslation = (float)(dMtrx4D[0][3]*rclDir.x+dMtrx4D[1][3]*rclDir.y+dMtrx4D[2][3]*rclDir.z);
  Vector3f cPnt((float)dMtrx4D[0][3],(float)dMtrx4D[1][3],(float)dMtrx4D[2][3]); 
  cPnt = cPnt - fTranslation * rclDir;

  // This is the base point of the rotation axis
  if ( rfAngle > 0.0f )
  {
    double factor = 0.5*(1.0+fTrace)/sin(rfAngle);
    rclBase.x = (float)(0.5*(cPnt.x+factor*(rclDir.y*cPnt.z-rclDir.z*cPnt.y)));
    rclBase.y = (float)(0.5*(cPnt.y+factor*(rclDir.z*cPnt.x-rclDir.x*cPnt.z)));
    rclBase.z = (float)(0.5*(cPnt.z+factor*(rclDir.x*cPnt.y-rclDir.y*cPnt.x)));
  }

  return true;
}
Example #18
0
void Npc::Move(const Vector3f& destination, float elapsedTime) 
{
	if (elapsedTime == 0)
		return;
	// Gravité
	float distanceY = (m_speedGravity * elapsedTime) + (GRAVITY * elapsedTime * elapsedTime / 2.0f);
	if (!CheckCollision(Vector3f(m_pos.x, m_pos.y - distanceY, m_pos.z)))
	{
		m_speedGravity -= GRAVITY * elapsedTime;
	}
	else
	{
		m_speedGravity = 0;
		distanceY = 0;
	}

	// Test si atteint la destination
	if(	abs(destination.x - m_pos.x) < 1
		&& abs(destination.y - m_pos.y) < 1 
		&& abs(destination.z - m_pos.z) < 1) {
	}
	else {
		Vector3f deplacement;
		deplacement = m_rot * m_speed * elapsedTime;

		// chemin le plus court
		Vector3f distance;
		distance.x = m_pos.x - destination.x;
		distance.y = m_pos.y - destination.y;
		distance.z = m_pos.z - destination.z;

		// calculer l'angle entre les 2 vecteurs
		// fix imprecision float
		float n = distance.Dot(deplacement) / (distance.Lenght() * deplacement.Lenght());
		if (n > 1)
			n = 1;
		else if (n < -1)
			n = -1;
		float angleA = acos(n);
		Vector3f axis = distance.Cross(deplacement);
		axis.Normalize();
		// rotation autour de laxe
		float rotation;
		if (abs(angleA) >= m_maxRot && abs(angleA) < PII - m_maxRot)
			rotation = (angleA > 0) ? -m_maxRot : m_maxRot;
		else
			rotation = angleA - PII;
		Quaternion q;
		q.FromAxis(rotation, axis);
		q.Normalise();

		m_rot = q * m_rot;
		m_rot.Normalise();

		// Check collisions
		Vector3f curPos = m_pos;
		Vector3f newPos;
		newPos.x = curPos.x + deplacement.x;
		newPos.y = curPos.y;
		newPos.z = curPos.z;
		if(!CheckCollision(newPos + Vector3f(0,1,0)))
			m_pos.x += deplacement.x;

		newPos.x = curPos.x;
		newPos.y = curPos.y + deplacement.y;
		newPos.z = curPos.z;
		if(!CheckCollision(newPos + Vector3f(0,1,0)))
			m_pos.y += deplacement.y;

		newPos.x = curPos.x;
		newPos.y = curPos.y;
		newPos.z = curPos.z + deplacement.z;
		if(!CheckCollision(newPos + Vector3f(0,1,0)))
			m_pos.z += deplacement.z;

	}

	if (!m_flying)
		m_pos.y += distanceY;
}