Example #1
0
bool Ray::intersectAABB(const AABB &aabb) const {
	Vector3d dirFrac;
	dirFrac.x() = 1.0f / _direction.x();
	dirFrac.y() = 1.0f / _direction.y();
	dirFrac.z() = 1.0f / _direction.z();

	float t1 = (aabb.getMin().x() - _origin.x()) * dirFrac.x();
	float t2 = (aabb.getMax().x() - _origin.x()) * dirFrac.x();
	float t3 = (aabb.getMin().y() - _origin.y()) * dirFrac.y();
	float t4 = (aabb.getMax().y() - _origin.y()) * dirFrac.y();
	float t5 = (aabb.getMin().z() - _origin.z()) * dirFrac.z();
	float t6 = (aabb.getMax().z() - _origin.z()) * dirFrac.z();

	float tMin = MAX(MAX(MIN(t1, t2), MIN(t3, t4)), MIN(t5, t6));
	float tMax = MIN(MIN(MAX(t1, t2), MAX(t3, t4)), MAX(t5, t6));

	// If tMax < 0, the ray is intersecting the AABB, but the whole AABB is in the opposite direction
	if (tMax < 0) {
		return false;
	}

	// If tMin > tMax, the ray doesn't intersect the AABB
	if (tMin > tMax) {
		return false;
	}

	return true;
}
Example #2
0
void Collide::pointBoxCollide(const Body * point_, const Body * box)
{
	Point *point = (Point*)point_;
	AABB *aabb = (AABB*)box;

	if (point->getPoint().GetX() > aabb->getMin().GetX() && point->getPoint().GetX() < aabb->getMax().GetX() &&
		point->getPoint().GetY() > aabb->getMin().GetY() && point->getPoint().GetY() < aabb->getMax().GetY() &&
		point->getPoint().GetZ() > aabb->getMin().GetZ() && point->getPoint().GetZ() < aabb->getMax().GetZ())
	{
		setCollide(true);
		// haven't calculate the distance
		setDistance(-1);
	}
	else
	{
		setCollide(false);
		// haven't calculate the distance
		setDistance(1);
	}

	// compute the response vectors
	Vector3 responseObject1 = point_->getCenter() - box->getCenter();
	Vector3 responseObject2 = box->getCenter() - point_->getCenter();
	setResponseObject1(responseObject1);
	setResponseObject2(responseObject2);
}
Example #3
0
AABB<3, T> operator*(const Transform<T>& lhs, const AABB<3, T>& rhs)
{
	Vector<3, T> min = lhs.getScale() * rhs.getMin();
	Vector<3, T> max = lhs.getScale() * rhs.getMax();

	const Vector<3, T> corners[8] =
	{
		Vector<3, T>(min.x, min.y, min.z),
		Vector<3, T>(min.x, min.y, max.z),
		Vector<3, T>(min.x, max.y, min.z),
		Vector<3, T>(min.x, max.y, max.z),
		Vector<3, T>(max.x, min.y, min.z),
		Vector<3, T>(max.x, min.y, max.z),
		Vector<3, T>(max.x, max.y, min.z),
		Vector<3, T>(max.x, max.y, max.z),
	};

	min.x = min.y = min.z = std::numeric_limits<T>::max();
	max.x = max.y = max.z = std::numeric_limits<T>::min();

	for (std::size_t i = 0; i < 8; ++i)
	{
		Vector<3, T> v = lhs.getRotation() * corners[i];

		min.x = std::min(min.x, v.x);
		min.y = std::min(min.y, v.y);
		min.z = std::min(min.z, v.z);

		max.x = std::max(max.x, v.x);
		max.y = std::max(max.y, v.y);
		max.z = std::max(max.z, v.z);
	}

	return AABB<3, T>(lhs.getTranslation() + min, lhs.getTranslation() + max);
}
Example #4
0
bool AABB::isColliding(const AABB & box) const
{
    const Vector2 bMin = box.getMin();
    const Vector2 bMax = box.getMax();
    return bMin.getX() < m_max.getX() && bMax.getX() > m_min.getX()
        && bMin.getY() < m_max.getY() && bMax.getY() > m_min.getY();
}
Example #5
0
bool
Frustum::inside(AABB const& aabb) const 
{
	glm::vec3 minimum = aabb.getMin();
	glm::vec3 maximum = aabb.getMax();
	//for each plane do ...
	glm::vec3 pos;
	glm::vec3 neg;
	bool result = true;
	for(int i = 0; i < FrustumPlane::NUM_PLANES; ++i) {
		pos = minimum;
		neg = maximum;
		if (mPlanes[i].normal.x > 0.f) { pos.x = maximum.x; neg.x = minimum.x; }
		if (mPlanes[i].normal.y > 0.f) { pos.y = maximum.y; neg.y = minimum.y; }
		if (mPlanes[i].normal.z > 0.f) { pos.z = maximum.z; neg.z = minimum.z; }
		// is the positive vertex outside?
		if (mPlanes[i].distance(pos) < 0.f) {
			return false;
		}
		// is the negative vertex outside?	
		else if (mPlanes[i].distance(neg) < 0.f)
			result = true; // intersection
	}
	return result;
}
Example #6
0
bool AABB::isCollide(AABB& a) {
    const float * a_min = a.getMin();
    const float * a_max = a.getMax();
    if (min_v[0] > a_max[0]) return false;
    if (max_v[0] < a_min[0]) return false;
    if (min_v[1] > a_max[1]) return false;
    if (max_v[1] < a_min[1]) return false;
    if (min_v[2] > a_max[2]) return false;
    if (max_v[2] < a_min[2]) return false;

    return true;
}
std::shared_ptr<OctreeSDF> OctreeSDF::sampleSDF(SolidGeometry* otherSDF, const AABB& aabb, int maxDepth)
{
    auto ts = Profiler::timestamp();
	std::shared_ptr<OctreeSDF> octreeSDF = std::make_shared<OctreeSDF>();
	Ogre::Vector3 aabbSize = aabb.getMax() - aabb.getMin();
	float cubeSize = std::max(std::max(aabbSize.x, aabbSize.y), aabbSize.z);
	octreeSDF->m_CellSize = cubeSize / (1 << maxDepth);
	otherSDF->prepareSampling(aabb, octreeSDF->m_CellSize);
	octreeSDF->m_RootArea = Area(Vector3i(0, 0, 0), maxDepth, aabb.getMin(), cubeSize);
	octreeSDF->m_RootNode = octreeSDF->createNode(octreeSDF->m_RootArea, *otherSDF);
    Profiler::printJobDuration("OctreeSDF::sampleSDF", ts);
	return octreeSDF;
}
Example #8
0
wiSPTree* wiSPTree::updateTree(Node* node){
	if(this && node)
	{

		vector<Cullable*> bad(0);
		for(Cullable* object : node->objects){
#ifdef SP_TREE_BOX_CONTAIN
			if( node->box.intersects(object->bounds)!=AABB::INSIDE )
#else
			if( !node->box.intersects(object->translation) )
#endif
				bad.push_back(object);
		}

		if(!bad.empty()){
		
			for(Cullable* object : bad){
				node->objects.remove(object);
			}

			if(node->parent){
				AddObjects(node->parent,bad);
			}
			else{
				CulledList culledItems;
				getVisible(node,node->box,culledItems);
				for(Cullable* item : culledItems){
					bad.push_back(item);
				}

				wiSPTree* tree;
				if(childCount==8) 
					tree = new Octree();
				else 
					tree = new QuadTree();
				AABB nbb = node->box*1.5;
				tree->initialize(bad,nbb.getMin(),nbb.getMax());
				return tree;
			}
		}
		if(!node->children.empty()){
			for (unsigned int i = 0; i<node->children.size(); ++i)
				updateTree(node->children[i]);
		}

	}
	return NULL;
}
Example #9
0
/// NOTE: Expects @param nodes to be a link list along the left child
AABB::AABB(AABB *nodes) : left(0), right(0), move(0) {
  if (!nodes) return;

  // Compute bounds
  unsigned count = 0;
  for (AABB *it = nodes; it; it = it->left) {
    if (it->right) THROW("Unexpected right-hand AABB node");
    add(*it);
    count++;
  }

  // Degenerate cases
  if (count < 3) {
    if (count == 2) right = nodes->left;
    left = nodes->prepend(0);
    return;
  }

  // Decide split
  unsigned axis = getDimensions().findLargest();
  real cut = getMax()[axis] + getMin()[axis];

  // Partition nodes
  AABB *lessThan = 0;
  AABB *greaterThan = 0;
  unsigned lessCount = 0;
  unsigned greaterCount = 0;

  for (AABB *it = nodes; it;) {
    AABB *next = it->left;
    bool less = it->getMax()[axis] + it->getMin()[axis] < cut;

    if (less) {lessThan = it->prepend(lessThan); lessCount++;}
    else {greaterThan = it->prepend(greaterThan); greaterCount++;}

    it = next;
  }

  // Check for bad partition
  if (!lessThan) lessThan = greaterThan->split(greaterCount / 2);
  if (!greaterThan) greaterThan = lessThan->split(lessCount / 2);

  // Recur
  left = new AABB(lessThan);
  right = new AABB(greaterThan);
}
Example #10
0
void OverlayBatch::addOverlay(const AABB<2, float>& bounds, const AABB<2, float>& imageRegion, const Vector<4, float>& color)
{
	if (isFull())
	{
		throw MemoryException("Overlay batch exceeded capacity.");
	}

	float vertices[4][9];

	vertices[0][0] = bounds.getMax().x;
	vertices[0][1] = bounds.getMin().y;
	vertices[0][2] = 0.0f;
	vertices[0][3] = imageRegion.getMax().x;
	vertices[0][4] = imageRegion.getMax().y;
	vertices[0][5] = color.r;
	vertices[0][6] = color.g;
	vertices[0][7] = color.b;
	vertices[0][8] = color.a;

	vertices[1][0] = bounds.getMin().x;
	vertices[1][1] = bounds.getMin().y;
	vertices[1][2] = 0.0f;
	vertices[1][3] = imageRegion.getMin().x;
	vertices[1][4] = imageRegion.getMax().y;
	vertices[1][5] = color.r;
	vertices[1][6] = color.g;
	vertices[1][7] = color.b;
	vertices[1][8] = color.a;

	vertices[2][0] = bounds.getMin().x;
	vertices[2][1] = bounds.getMax().y;
	vertices[2][2] = 0.0f;
	vertices[2][3] = imageRegion.getMin().x;
	vertices[2][4] = imageRegion.getMin().y;
	vertices[2][5] = color.r;
	vertices[2][6] = color.g;
	vertices[2][7] = color.b;
	vertices[2][8] = color.a;

	vertices[3][0] = bounds.getMax().x;
	vertices[3][1] = bounds.getMax().y;
	vertices[3][2] = 0.0f;
	vertices[3][3] = imageRegion.getMax().x;
	vertices[3][4] = imageRegion.getMin().y;
	vertices[3][5] = color.r;
	vertices[3][6] = color.g;
	vertices[3][7] = color.b;
	vertices[3][8] = color.a;

	vertexBuffer->setData(vertices, overlayCount * 4, 4);	

	++overlayCount;
}
Example #11
0
AABB<N, T> operator*(const Matrix<N + 1, N + 1, T>& lhs, const AABB<N, T>& rhs)
{
	Vector<N, T> min(lhs[N]);
	Vector<N, T> max(lhs[N]);
	
	for (std::size_t i = 0; i < N; ++i)
	{
		for (std::size_t j = 0; j < N; ++j)
		{
			T a = lhs[i][j] * rhs.getMin()[j];
			T b = lhs[i][j] * rhs.getMax()[j];
			
			min[i] += std::min(a, b);
			max[i] += std::max(a, b);
		}
	}
	
	return AABB<N, T>(min, max);
}
Example #12
0
// If AABB intersects the frustum, an output clip mask is returned as well
(indicating which
// planes are crossed by the AABB). This information can be used to optimize
testing of
// child nodes or objects inside the nodes (pass value as 'inClipMask').

bool intersectAABBFrustum (const AABB& a, const Vector4* p, unsigned int&
outClipMask, unsigned int inClipMask)
{
Vector3 m = a.getCenter(); // center of AABB
Vector3 d = a.getMax() - m; // half-diagonal
unsigned int mk = 1;
outClipMask = 0; // init outclip mask
while (mk <= inClipMask){ // loop while there are active planes..
if (inClipMask&mk){ // if clip plane is active...
float NP = (float)(d.x*fabs(p->x)+d.y*fabs(p->y)+d.z*fabs(p->z));
float MP = m.x*p->x+m.y*p->y+m.z*p->z+p->w;
if ((MP+NP) < 0.0f) return false; // behind clip plane
if ((MP-NP) < 0.0f) outClipMask |= mk;
}
mk+=mk; // mk = (1<<iter)
p++; // next plane
}
return true; // AABB intersects frustum
}
Example #13
0
void AABB::include(const AABB& other)
{
	include(other.getMin());
	include(other.getMax());
}
KdTreeBase::SplitCandidate KdTreeSahNlog2N::determineSplitpos(const AABB& v, const unsigned int* primitves, const unsigned int primitveCount) {

  SAHCost bestCost(false, 10000.0f);

  SAHCost currentCost;
  SplitCandidate currentSplit;
  SplitCandidate bestSplit = { 0.0f, 3, false};
  bestSplit.axis = 3; // to mark that there's been no good one yet

  for (unsigned int axis = 0; axis < 3; ++axis) {
    List<KdTreeSahNlog2N::Event>events;
    events.reserve(primitveCount * 2);
  
    for ( unsigned int p = 0; p < primitveCount; ++p) {
      const Primitive& currentPrimitive = scene.getPrimitive(primitves[p]);
      const AABB& currBB = getAABBForPrimitiv(primitves[p]);
      if ( (currentPrimitive.getNormal() == AXIS[axis]) 
          ||  (( -1.0 * currentPrimitive.getNormal()) == AXIS[axis])) {
          events.push_back(Event(fmaxf(currBB.getMin(axis), v.getMin(axis)), INPLANE));
      } else {
          events.push_back(Event(fmaxf(currBB.getMin(axis), v.getMin(axis)), START));
          events.push_back(Event(fminf(currBB.getMax(axis), v.getMax(axis)), END));
      }
    }
  
    sort(events.begin(), events.end());
    unsigned int inplane = 0, leftOf = 0, rightOf = primitveCount;
    currentSplit.axis = axis;
    unsigned int dend, dstart, dplane;
    List<Event>::const_iterator iter = events.begin();

//     for (; iter != events.end(); ++iter) {
//       std::cout << (*iter).t << ":";
//       switch((*iter).type) {
//         case START: std::cout << "START";break;
//         case END: std::cout << "END";break;
//         case INPLANE: std::cout << "PLANE";break;
//       }
//     std::cout << "\n";
//     }
//     iter = events.begin();
    while (iter != events.end()) {
      dend = dstart = dplane = 0;
      currentSplit.pos = (*iter).t;

      while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == END ) {
        ++dend;
        ++iter;
      }
      
      while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == INPLANE ) {
        ++dplane;
        ++iter;
      }
      
      while ( (iter != events.end()) && ((*iter).t == currentSplit.pos ) && (*iter).type == START ) {
        ++dstart;
        ++iter;
      }

      inplane = dplane;
      leftOf -= dplane;
      rightOf -= dend;
      currentCost =  SAH(v, currentSplit , leftOf, rightOf, inplane);
//       std::cout << currentSplit.pos << ":" << currentCost<< "," << leftOf << ","<< rightOf << ","<< inplane << "\n";

      if ( currentCost < bestCost ) {
        bestCost = currentCost;
        bestSplit = currentSplit;
        bestSplit.putInPlaneLeft = bestCost.putInPlaneLeft;
      }

      leftOf += dstart;
      leftOf += dplane;
      inplane = 0;

    }
  }
// std::cout << std::endl;
  return bestSplit;
}
Example #15
0
void
LightComponent::_prePassIterationRendering(
	Pass const* pass, 
	int iterationIndex, 
	CameraComponent const* mainCamera, 
	glm::mat4 const& mainCameraSpaceMatrix,
	glm::mat4& passProjectionMatrix,
	glm::mat4& passCameraSpaceMatrix,
	AABB const& worldAABB
) 
{
	if( pass->getPov() == PointOfView::LOCAL &&
		pass->getRenderTarget().getRenderTargetType() == RenderTargetType::RT_2D_ARRAY &&
		mType == LightType::DIRECTIONAL)
	{
		// prepare to render Cascaded Shadow Maps
		// -> set the model view matrix to look into light direction
		passCameraSpaceMatrix = glm::lookAt(glm::vec3(),-getTransformedDirection(), glm::vec3(-1.f, 0.f, 0.f));

		setupFrustumPoints(
			iterationIndex, 
			mainCamera->getViewportWidth(), 
			mainCamera->getViewportHeight(), 
			mainCamera->getFovY(), 
			mainCameraSpaceMatrix, 
			glm::inverse(mainCameraSpaceMatrix), 
			mainCamera->getInverseCameraRotation()
		);
		// APPLY CROP MATRIX TO PROJECTION MATRIX
		float maxX = -FLT_MAX;
		float maxY = -FLT_MAX;
		float maxZ;
		float minX =  FLT_MAX;
		float minY =  FLT_MAX;
		float minZ;

		glm::mat4 nv_mvp;
		glm::vec4 transf;	
	
		// find the z-range of the current frustum as seen from the light
		// in order to increase precision
	
		// note that only the z-component is need and thus
		// the multiplication can be simplified
		// transf.z = shad_modelview[2] * f.point[0].x + shad_modelview[6] * f.point[0].y + shad_modelview[10] * f.point[0].z + shad_modelview[14];
		// frustum points are in inverse camera space!

		// passCameraSpaceMatrix contains lookAt of light!

		transf = passCameraSpaceMatrix*mLightEffectState->frustumPoints[iterationIndex*8];
		minZ = transf.z;
		maxZ = transf.z;
		for(int l=1; l<8; l++) {
			transf = passCameraSpaceMatrix*mLightEffectState->frustumPoints[iterationIndex*8+l];
			if(transf.z > maxZ) maxZ = transf.z;
			if(transf.z < minZ) minZ = transf.z;
		}

		// @todo only a hack, because there is some bug in aabb retrieval of hole scene (value here should be reseted to 1.0 which was the default).
		float radius = 0.0;
		// make sure all relevant shadow casters are included
		// note that these here are dummy objects at the edges of our scene
		// @todo here we should use the AABB of the hole Scene 
					
		transf.z = worldAABB.getMin().z;
		if(transf.z + radius > maxZ) maxZ = transf.z + radius;
		if(transf.z - radius < minZ) minZ = transf.z - radius;
		transf.z = worldAABB.getMax().z;
		if(transf.z + radius > maxZ) maxZ = transf.z + radius;
		if(transf.z - radius < minZ) minZ = transf.z - radius;

		// set the projection matrix with the new z-bounds
		// note the inversion because the light looks at the neg. z axis
		// gluPerspective(LIGHT_FOV, 1.0, maxZ, minZ); // for point lights
		passProjectionMatrix = glm::ortho(-1.f,1.f,-1.f,1.f,-maxZ,-minZ);

		glm::mat4 shadowModelViewProjection = passProjectionMatrix * passCameraSpaceMatrix;


		// find the extends of the frustum slice as projected in light's homogeneous coordinates

		for(int l=0; l<8; l++) {
			transf = shadowModelViewProjection*mLightEffectState->frustumPoints[iterationIndex*8+l];

			transf.x /= transf.w;
			transf.y /= transf.w;

			if(transf.x > maxX) maxX = transf.x;
			if(transf.x < minX) minX = transf.x;
			if(transf.y > maxY) maxY = transf.y;
			if(transf.y < minY) minY = transf.y;
		}

		float scaleX = 2.0f/(maxX - minX);
		float scaleY = 2.0f/(maxY - minY);
		float offsetX = -0.5f*(maxX + minX)*scaleX;
		float offsetY = -0.5f*(maxY + minY)*scaleY;

		// apply a crop matrix to modify the projection matrix we got from glOrtho.
		glm::mat4 cropMatrix;
		cropMatrix = glm::translate(cropMatrix, glm::vec3(offsetX, offsetY,0.0f) );
		cropMatrix = glm::scale(cropMatrix, glm::vec3( scaleX, scaleY, 1.0f) );
					
					
		// adjust the view frustum of the light, so that it encloses the camera frustum slice fully.
		// note that this function calculates the projection matrix as it sees best fit
		passProjectionMatrix = cropMatrix * passProjectionMatrix;

		glm::mat4 passMVP = passProjectionMatrix*passCameraSpaceMatrix;

		//mShadowDescriptor.setOrthoFrustum(iterationIndex, passMVP);
		// build up a matrix to transform a vertex from eye space to light clip space
		mLightEffectState->eyeToLightClip[iterationIndex] = BIAS * passMVP * glm::inverse(mainCameraSpaceMatrix);

		// farClip[i] is originally in eye space - tells us how far we can see.
		// Here we compute it in camera homogeneous coordinates. Basically, we calculate
		// cam_proj * (0, 0, f[i].fard, 1)^t and then normalize to [0; 1]
		mLightEffectState->farClipsHomogenous[iterationIndex] = 0.5f*(-mLightEffectState->farClips[iterationIndex]*glm::value_ptr(mainCamera->getProjectionMatrix())[10]+glm::value_ptr(mainCamera->getProjectionMatrix())[14])/mLightEffectState->farClips[iterationIndex] + 0.5f;
	}
}
Example #16
0
void Player::update(float deltaTime) {
	checkMapStatus();
	vec3f initPos = pos;

	//Animation Conditions
	bool collidingSides = false;
	bool collidingFloor = false;
	bool running = false;

	//PHYSICS
	// apply forces
	vec3f dir(0);
	if(input.getKeyState(InputHandler::PLAYER_LEFT)) {
		dir += vec3f(-1, 0, 0);
		running = true;
	}
	if(input.getKeyState(InputHandler::PLAYER_RIGHT)) {
		dir += vec3f(1, 0, 0);
		running = true;
	}

	vec3f friction(0);
	if(!(fabs(velocity.x) < 0.08f)) friction = FRICTION_COEFF*vec3f(velocity.x > 0 ? -1.0 : 1.0, 0, 0);


	totalForce += ACCELERATION*dir + vec3f(0, -GRAVITY, 0) + friction;

	bool saltito = false;
	// apply impulses
	if (animState != Player::JUMP && input.getKeyDown(InputHandler::PLAYER_UP)) {
		velocity.y += JUMP_IMPULSE;
		saltito = true;
	}
	// integration
	velocity = glm::clamp(velocity + totalForce*deltaTime, vec3f(-MAX_VELOCITY), vec3f(MAX_VELOCITY));
	if (fabs(velocity.x) < 0.08f) velocity.x = 0;


	//Reset totalForce;
	totalForce = vec3f(0.0f);



	vec3f disp = velocity*deltaTime;


	//NOT PHYSICS

	// collision detection
	Map* map = (Map*)getGame()->getObjectByName("map");
	AABB aabb = modelAabb;
	mat4f trans = fullTransform*modelOffset;
	aabb = AABB(vec3f(trans*vec4f(aabb.getMin(), 1.0f)), vec3f(trans*vec4f(aabb.getMax(), 1.0f)));

	vec3f bbmin = vec3f(trans*vec4f(modelAabb.getMin(), 1.0f));
    vec3f bbmax = vec3f(trans*vec4f(modelAabb.getMin() + modelAabb.getDimensions()*vec3f(0.2f, 0.05f, 1.0f), 1.0f));
	AABB brushBox(bbmin + disp, bbmax + disp);

	colliding = false;
	bool isBrushColliding = false;



	//Y
	AABB newboxY(aabb.getMin()+vec3f(0,disp.y,0), aabb.getMax()+vec3f(0,disp.y,0));
	Color blockColor;
	if(map->isColliding(newboxY, blockColor)) {
		float min = 0;
		float max = 1;
        Color foo;
        isBrushColliding = map->isColliding(brushBox, foo);
		while(max-min > 0.001) { //search for the maximum distance you can move
			float m = (max+min)/2;
			newboxY = AABB(aabb.getMin()+vec3f(0,disp.y*m,0), aabb.getMax()+vec3f(0,disp.y*m,0));
			if(map->isColliding(newboxY, foo))
				max = m;
			else
				min = m;
		}
		if(velocity.y < 0) collidingFloor = true;
		velocity.y = 0;
		disp.y *= min;
		colliding = true;
		isBrushColliding = true;
	}

	pos.y += disp.y;
	aabb = AABB(aabb.getMin()+vec3f(0,disp.y,0), aabb.getMax()+vec3f(0,disp.y,0));

	//X
	bool isRightWall = false;
	AABB newboxX(aabb.getMin()+vec3f(disp.x,0,0), aabb.getMax()+vec3f(disp.x,0,0));
	if(map->isColliding(newboxX, blockColor)) {

		Color foo;
        isBrushColliding = isBrushColliding || map->isColliding(brushBox, foo);

		float min = 0;
		float max = 1;
		while(max-min > 0.001) { //search for the maximum distance you can move
			float m = (max+min)/2;
			newboxX = AABB(aabb.getMin()+vec3f(disp.x*m,0,0), aabb.getMax()+vec3f(disp.x*m,0,0));
			if(map->isColliding(newboxX, foo))
				max = m;
			else
				min = m;
		}
		//WALL JUMP
		vec3f wallFriction(0);
		if(velocity.x != 0) {
			wallFriction = FRICTION_COEFF*vec3f(0, velocity.y > 0 ? -.1 : .4, 0);
			collidingSides = true;
		}
		totalForce += wallFriction;

		if(velocity.x > 0 ) {
			if (input.getKeyDown(InputHandler::PLAYER_UP))
			{
				velocity.x -= JUMP_IMPULSE*5;
				emitter->boomSide(20, -1);
				saltito = false;
			}
			isRightWall = true;
		} else if(velocity.x < 0 ) {
			if (input.getKeyDown(InputHandler::PLAYER_UP))
			{
				velocity.x += JUMP_IMPULSE*5;
				emitter->boomSide(20, 1);
				saltito = false;
			}

		} else velocity.x = 0;

		disp.x *= min;
		colliding = true;
	}

	if(saltito)
		emitter->boom(20);

	pos.x += disp.x;

	//ANIMATION
	if(collidingSides)  {
		animState = Player::WALL;
		anim = velocity.y > 0 ? "wallu" : "walld";
	} else if(collidingFloor) {
		if(running)      {
			animState = Player::RUN;
			anim = fabs(velocity.x) >= MAX_VELOCITY/2 ? "runb" : "runa";
		} else {
			animState = Player::IDLE;
			anim = "idle";

		}
	} else {
		animState = Player::JUMP;
		anim = fabs(velocity.x) > MAX_VELOCITY/2 ? "jumpb" : "jumpa";
	}

	animCount += deltaTime;
	if(animCount >= animTime) {
		animCount -= animTime;
		animTime = randomFloat(0.1f, 0.2f);
		animIter = 1 - animIter;
	}
	std::string s = "brush" + anim + toString(animIter);
	model.mesh = Meshes.get(s);



	// TRAILS

	if(collidingFloor && !prevOnfloor)
		emitter->boom(20);

	if (collidingFloor && isBrushColliding && (blockColor == Color::WHITE || blockColor == color) ) {
		Trails* trails = (Trails*)getGame()->getObjectByName("trails");
        trails->addTrailSegment(color, Trails::HORIZONTAL, pos.x, initPos.x, int(pos.y - 0.1), 1.5f*modelAabb.getDimensions().x);
	}
	if (collidingSides && isBrushColliding && (blockColor == Color::WHITE || blockColor == color) ) {
		Trails* trails = (Trails*)getGame()->getObjectByName("trails");
		Trails::Direction dir;
		if (isRightWall)
			dir = Trails::VERTICAL_RIGHT;
		else
			dir = Trails::VERTICAL_LEFT;

		float off = 0.21;
        trails->addTrailSegment(color, dir, pos.y-off, initPos.y-off, int(pos.x+(isRightWall?1:0)), 1.5f*modelAabb.getDimensions().x);
	}
	prevOnfloor = collidingFloor;
	prevOnside = collidingSides;



	//transform stuff
	for(int i = 0; i < 3; ++i) {
		if(rot[i] < 0) rot[i] = rot[i]+360;
		else if(rot[i] >= 360.0f) rot[i] = rot[i]-360;
	}
	transform = glm::translate(mat4f(1), pos);
	transform = glm::scale(transform, scale);

	if(pos.y < -2) die();
}
Example #17
0
AABB::AABB(const AABB &copy) {
    min = copy.getMin();
    max = copy.getMax();
}