// Calculates the desired position for the physics box, so that its center will be superimposed with AABB center of provided entity.
// Also adjusts upwards to avoid any obvious floor clipping.  Returns desired Position for entity.
Vec3 CIntersectionAssistanceUnit::CalculateTargetAdjustPoint(const IEntity* pEntity, const Matrix34 &wMat, const Vec3& vStartingPos) const
{
    // (if present + desired) adjust physbox center to that of owner Ent - to make sure centers of PhysBox + focal ent superimposed
    // at the desired position
    const IEntity* pFocalEnt = gEnv->pEntitySystem->GetEntity(m_focalEntityId);
    if(pFocalEnt)
        {
            OBB focalOBB;
            AABB focalAABB;

            // Compensate for actor/non actor entities that require different paths :(
            if(CPlayer* pPlayer = static_cast<CPlayer*>(g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(m_focalEntityId)))
                {
                    EStance playerStance = pPlayer->GetStance();
                    focalAABB = pPlayer->GetStanceInfo(playerStance)->GetStanceBounds();
                }
            else
                {
                    pFocalEnt->GetLocalBounds(focalAABB);
                }
            focalOBB.SetOBBfromAABB(Quat(IDENTITY), focalAABB);

            // shift to match focus ent Center (taking into account crouch etc if player).
            float fVerticalAdjust = focalOBB.h.z;

            // Additionally.. if the new test pos *would* immediately penetrate the floor (assumption based on any part of the volume being < player AABB z min value)
            // shift it up.
            float fFloorPenetrationAdjust = 0.0f;
            AABB wEntABB;
            pEntity->GetLocalBounds(wEntABB);
            wEntABB.SetTransformedAABB(wMat,wEntABB);
            float fFloorClearance =  focalOBB.h.z - (wEntABB.GetSize().z * 0.5f);

            fFloorPenetrationAdjust += (0.0f - min(fFloorClearance, 0.0f));

            // Apply floor clearance + Vertical adjust
            Vec3 desiredPos = wMat.GetTranslation() + Vec3(0.0f,0.0f,(fFloorPenetrationAdjust) * kFloorAdjustConstant);
            desiredPos += (fVerticalAdjust * pFocalEnt->GetWorldTM().GetColumn2() * kFloorAdjustConstant);
            return desiredPos;
        }

    return wMat.GetTranslation();
}
Example #2
0
void OBB::getInterval(const OBB& box, const Vec3& axis, float &min, float &max)const
{
    Vec3 corners[8];
    box.getCorners(corners);
    float value;
    min = max = projectPoint(axis, corners[0]);
    for(int i = 1; i < 8; i++)
    {
        value = projectPoint(axis, corners[i]);
        min = MIN(min, value);
        max = MAX(max, value);
    }
}
Example #3
0
void const SphereCollider::render()
{
	glLoadIdentity();
	getGameObject()->getTransform()->apply();

	glColor4f(1,0,0,0.7);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_POINT_SMOOTH);

	glPointSize(2.0 * radius);

	glBegin(GL_POINTS);
	glVertex3f(center.x,center.y,-1);
	glEnd();
	point* points = sweep();
	OBB* swept = new OBB(points);
	swept->render();
	delete swept;
	delete points;

}
Example #4
0
OBB Frustum::MinimalEnclosingOBB(float expandGuardband) const
{
	assume(IsFinite());
	assume(front.IsNormalized());
	assume(up.IsNormalized());

	OBB obb;
	obb.pos = pos + (nearPlaneDistance + farPlaneDistance) * 0.5f * front;
	obb.axis[1] = up;
	obb.axis[2] = -front;
	obb.axis[0] = Cross(obb.axis[1], obb.axis[2]);
	obb.r = float3::zero;
	for(int i = 0; i < 8; ++i)
		obb.Enclose(CornerPoint(i));

	// Expand the generated OBB very slightly to avoid numerical issues when
	// testing whether this Frustum actually is contained inside the generated OBB.
	obb.r.x += expandGuardband;
	obb.r.y += expandGuardband;
	obb.r.z += expandGuardband;
	return obb;
}
void CBoundingContainer::HideContainedItems()
{
	IEntity* pEntity = GetEntity();
	if (pEntity)
	{
		// Proximity query all entities in area
		AABB aabbBounds(m_vBoundingMin, m_vBoundingMax);

		OBB	obbBounds;
		Matrix34	worldTM = pEntity->GetWorldTM();
		obbBounds.SetOBBfromAABB(Matrix33(worldTM), aabbBounds);
		aabbBounds.Reset();
		aabbBounds.SetAABBfromOBB(pEntity->GetWorldPos(), obbBounds);

		SEntityProximityQuery query;
		query.box = aabbBounds;
		gEnv->pEntitySystem->QueryProximity(query);
		const int iQueryCount = query.nCount;
		for (int i = 0; i < iQueryCount; ++i)
		{
			IEntity* pQueryEntity = query.pEntities[i];
			if (pQueryEntity)
			{
				const EntityId queryEntityId = pQueryEntity->GetId();
				
				if (!stl::find(m_hiddenEntities, queryEntityId)) // Only if not already hidden
				{
					// Make sure entity type should be hidden and entity pos is also inside, not just an intersection
					if (ShouldHide(queryEntityId, pQueryEntity) && aabbBounds.IsContainPoint(pQueryEntity->GetWorldPos()))
					{
						pQueryEntity->Hide(true);
						m_hiddenEntities.push_back(pQueryEntity->GetId());
					}
				}
			}
		}
	}
}
bool BasicPrimitiveTests::IntersectingRayAgainstOBB(const Ray & ray, const OBB & obb, float & rtn_t)
{
	
	Eigen::Matrix3f obb_rotation;
	obb.GetRotationMatrix(obb_rotation);
	Eigen::Vector3f ray_d_obb = obb_rotation * ray.GetDirection();
	Eigen::Vector3f ray_o_obb = obb_rotation * (ray.GetOrigin() - obb.GetCenter());

	
	rtn_t = 0.0f;
	float tmax = FLT_MAX;
	Eigen::Vector3f aabb_min = -obb.GetExtents();
	Eigen::Vector3f aabb_max = obb.GetExtents();
	for (int i = 0; i < 3; ++i)
	{
		if (abs(ray_d_obb[i]) < EPSILON)
		{
			//Ray is parallel to slab. Not hit if origin not within slab.
			if (ray_o_obb[i] < aabb_min[i] || ray_o_obb[i] > aabb_max[i])
			{
				return false;
			}
		}
		else
		{
			float one_over_direction = 1.0f / ray_d_obb[i];
			float t1 = (aabb_min[i] - ray_o_obb[i]) * one_over_direction;
			float t2 = (aabb_max[i] - ray_o_obb[i]) * one_over_direction;
			if (t1 > t2) Swap(t1, t2);
			if (t1 > rtn_t) rtn_t = t1;
			if (t2 > tmax) tmax = t2;
			if (rtn_t > tmax) return false;
		}
	}
	
	
	return true;
}
Example #7
0
OBB AABB::Transform(const Quat &transform) const
{
	OBB obb;
	obb.SetFrom(*this, transform);
	return obb;
}
Example #8
0
OBB AABB::Transform(const float4x4 &transform) const
{
	OBB obb;
	obb.SetFrom(*this, transform);
	return obb;
}
Example #9
0
void AABB::Init(const OBB& shp) { Max = vec3(shp.XSize(), shp.YSize(), shp.ZSize()); Min = -Max;}
Example #10
0
void Sphere::Enclose(const OBB &obb)
{
	///@todo This might not be very optimal at all. Perhaps better to enclose the farthest point first.
	for(int i = 0; i < 8; ++i)
		Enclose(obb.CornerPoint(i));
}
Example #11
0
bool Polygon::Intersects(const OBB &obb) const
{
	return obb.Intersects(*this);
}
Example #12
0
float float3::Distance(const OBB &rhs) const { return rhs.Distance(*this); }
Example #13
0
float Sphere::Distance(const OBB &obb) const
{
	return obb.Distance(*this);
}
Example #14
0
OBB RigidBox::GetOBBWorldSpace()
{
   OBB obb;
   obb.ObjectTransform(m_obb, m_worldMat);
   return obb;
}
Example #15
0
//------------------------------------------------------------------------
void CVehicleViewSteer::Update(float dt)
{
	IEntity* pEntity = m_pVehicle->GetEntity();
	assert(pEntity);

	IVehicleMovement* pVehicleMovement = m_pVehicle->GetMovement();
	if (pVehicleMovement == NULL)
		return;

	IPhysicalEntity* pPhysEntity = pEntity->GetPhysics();
	if (!pPhysEntity)
		return;

	pe_status_dynamics dynStatus;
	pPhysEntity->GetStatus(&dynStatus);

	SMovementState movementState;
	pVehicleMovement->GetMovementState(movementState);
	const float     pedal        = pVehicleMovement->GetEnginePedal();
	const float     maxSpeed     = movementState.maxSpeed;
	const Matrix34 &pose         = m_pAimPart ? m_pAimPart->GetWorldTM() : pEntity->GetWorldTM();
	const Vec3      entityPos    = pose.GetColumn3();
	const Vec3      xAxis        = pose.GetColumn0();
	const Vec3      yAxis        = pose.GetColumn1();
	const Vec3      zAxis        = pose.GetColumn2();
	const float     forwardSpeed = dynStatus.v.dot(yAxis);
	const float     speedNorm    = clamp_tpl(forwardSpeed / maxSpeed, 0.0f, 1.0f);
	const Vec3      maxRotation  = m_maxRotation + speedNorm * (m_maxRotation2 - m_maxRotation);

	CalcLookAt(pose);
	if (m_lookAt.IsValid())
	{
		if (!m_lastOffset.IsValid())
		{
			m_position             = pose * m_localSpaceCameraOffset;
			m_lastOffset           = m_position - m_lookAt;
			m_lastOffsetBeforeElev = m_lastOffset;
		}

		Vec3 offset = m_lastOffsetBeforeElev;

		if (pedal < 0.1f && forwardSpeed < 1.0f)
		{
			// Going Backwards
			m_flags &= ~(eVCam_goingForwards | m_forwardFlags);
			m_flags |= m_backwardsFlags;
		}

		if (offset.dot(yAxis) < 0.8f && forwardSpeed > 1.f)
		{
			// Going Forwards
			m_flags &= ~m_backwardsFlags;
			m_flags |= eVCam_goingForwards | m_forwardFlags;
		}

		float sensitivity = (1.f - speedNorm) * m_stickSensitivity.z + speedNorm * m_stickSensitivity2.z;
		float rotate      = -m_rotatingAction.z * sensitivity;
		rotate = rotate * dt;

		if (zAxis.z > 0.1f)
		{
			// Safe to update curYaw
			Vec3 projectedX = xAxis;
			projectedX.z = 0.f;
			Vec3 projectedY = yAxis;
			projectedY.z = 0.f;
			const float newYaw    = atan2_tpl(offset.dot(projectedX), -(offset.dot(projectedY)));
			const float maxChange = DEG2RAD(270.f) * dt;
			const float delta     = clamp_tpl(newYaw - m_curYaw, -maxChange, +maxChange);
			m_curYaw += delta;
		}

		// Rotation Action
		{
			if (m_flags & eVCam_rotationClamp)
			{
				float newYaw = clamp_tpl(m_curYaw + rotate, -maxRotation.z, +maxRotation.z);
				rotate        = newYaw - m_curYaw;
				rotate        = clamp_tpl(newYaw - m_curYaw, -fabsf(rotate), +fabsf(rotate));
				m_rotation.z += rotate;
			}
			else
			{
				m_rotation.z = 0.f;
			}

			if (speedNorm > 0.1f)
			{
				float reduce = dt * 1.f;
				m_rotation.z = m_rotation.z - reduce * m_rotation.z / (fabsf(m_rotation.z) + reduce);
			}
		}

		// Ang Spring
		{
			float angSpeedCorrection = dt * dt * m_angSpeedCorrection / (dt * m_angSpeedCorrection + 1.f) * dynStatus.w.z;
			if ((m_flags & eVCam_rotationSpring) == 0)
			{
				m_angReturnSpeed   = 0.f;
				angSpeedCorrection = 0.f;
			}

			float difference = m_rotation.z - m_curYaw;
			float relax      = difference * (m_angReturnSpeed * dt) / ((m_angReturnSpeed * dt) + 1.f);

			const float delta = +relax + angSpeedCorrection + rotate;
			m_curYaw += delta;

			Matrix33 rot = Matrix33::CreateRotationZ(delta);
			offset = rot * offset;

			// Lerp the spring speed
			float angSpeedTarget = m_angReturnSpeed1 + speedNorm * (m_angReturnSpeed2 - m_angReturnSpeed1);
			m_angReturnSpeed     += (angSpeedTarget - m_angReturnSpeed) * (dt / (dt + 0.3f));
			m_angSpeedCorrection += (m_angSpeedCorrection0 - m_angSpeedCorrection) * (dt / (dt + 0.3f));
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		// Velocity influence
		Vec3 displacement = -((2.f - speedNorm) * dt) * dynStatus.v;// - yAxis*(0.0f*speedNorm*(yAxis.dot(dynStatus.v))));

		float dot = offset.dot(displacement);
		if (dot < 0.f)
		{
			displacement = displacement + offset * -0.1f * (offset.dot(displacement) / offset.GetLengthSquared());
		}
		offset = offset + displacement;

		const float radius0   = fabsf(m_localSpaceCameraOffset.y);
		const float minRadius = radius0 * m_radiusMin;
		const float maxRadius = radius0 * m_radiusMax;
		float       radiusXY  = sqrtf(sqr(offset.x) + sqr(offset.y));

		Vec3 offsetXY = offset;
		offsetXY.z = 0.f;
		Vec3  accelerationV = (dynStatus.v - m_lastVehVel);
		float acceleration  = offsetXY.dot(accelerationV) / radiusXY;

		m_lastVehVel = dynStatus.v;
		m_radiusVel -= acceleration;
		m_radius    += m_radiusVel * dt - dt * m_radiusVelInfluence * offsetXY.dot(dynStatus.v) / radiusXY;
		m_radiusVel *= expf(-dt * m_radiusDampRate);
		m_radius    += (radius0 - m_radius) * (dt * m_radiusRelaxRate) / (dt * m_radiusRelaxRate + 1.f);
		m_radius     = clamp_tpl(m_radius, minRadius, maxRadius);
		offset       = offset * (m_radius / radiusXY);

		// Vertical motion
		float targetOffsetHeight = m_localSpaceCameraOffset.z * (m_radius / radius0);
		float oldOffsetHeight    = offset.z;
		offset.z += (targetOffsetHeight - offset.z) * (dt / (dt + 0.3f));
		Limit(offset.z, targetOffsetHeight - 2.f, targetOffsetHeight + 2.f);
		float verticalChange = offset.z - oldOffsetHeight;

		m_lastOffsetBeforeElev = offset;

		// Add up and down camera tilt
		{
			offset.z     -= verticalChange;
			m_rotation.x += dt * m_stickSensitivity.x * m_rotatingAction.x;
			m_rotation.x  = clamp_tpl(m_rotation.x, -maxRotation.x, +maxRotation.x);

			float elevAngleVehicle = m_inheritedElev * yAxis.z;     // yAxis.z == approx elevation angle

			float elevationAngle = m_rotation.x - elevAngleVehicle;

			float sinElev, cosElev;
			sincos_tpl(elevationAngle, &sinElev, &cosElev);
			float horizLen    = sqrtf(offset.GetLengthSquared2D());
			float horizLenNew = horizLen * cosElev - sinElev * offset.z;
			if (horizLen > 1e-4f)
			{
				horizLenNew /= horizLen;
				offset.x    *= horizLenNew;
				offset.y    *= horizLenNew;
				offset.z     = offset.z * cosElev + sinElev * horizLen;
			}
			offset.z += verticalChange;
		}

		if (!offset.IsValid()) offset = m_lastOffset;

		m_position = m_lookAt + offset;

		// Perform world intersection test.
		{
			// Initialise sphere and direction.
			primitives::sphere sphere;

			sphere.center = m_lookAt;
			sphere.r      = g_SteerCameraRadius;

			Vec3 direction = m_position - m_lookAt;

			// Calculate camera bounds.
			AABB localBounds;

			m_pVehicle->GetEntity()->GetLocalBounds(localBounds);

			const float cameraBoundsScale = 0.75f;

			localBounds.min *= cameraBoundsScale;
			localBounds.max *= cameraBoundsScale;

			OBB cameraBounds;

			Matrix34 worldTM = m_pVehicle->GetEntity()->GetWorldTM();

			cameraBounds.SetOBBfromAABB(Matrix33(worldTM), localBounds);

			// Try to find point on edge of camera bounds to begin swept sphere intersection test.
			Vec3 rayBoxIntersect;

			if (Intersect::Ray_OBB(Ray(m_position, -direction), worldTM.GetTranslation(), cameraBounds, rayBoxIntersect) > 0)
			{
				Vec3 temp = m_position - rayBoxIntersect;

				if (direction.Dot(temp) > 0.0f)
				{
					sphere.center = rayBoxIntersect;
					direction     = temp;
				}
			}

			// Perform swept sphere intersection test against world.
			geom_contact* pContact = NULL;

			IPhysicalEntity* pSkipEntities[10];

			float distance = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(sphere.type, &sphere, direction, ent_static | ent_terrain | ent_rigid | ent_sleeping_rigid,
			                                                                  &pContact, 0, (geom_colltype_player << rwi_colltype_bit) | rwi_stop_at_pierceable, 0, 0, 0,
			                                                                  pSkipEntities, m_pVehicle->GetSkipEntities(pSkipEntities, 10));

			if (distance > 0.0f)
			{
				// Sweep intersects world so calculate new offset.
				offset = (sphere.center + (direction.GetNormalizedSafe() * distance)) - m_lookAt;
			}
		}

		Interpolate(m_lastOffset, offset, 10.f, dt);

		m_position = m_lookAt + m_lastOffset;
	}
	else
	{
		CRY_ASSERT_MESSAGE(0, "camera will fail because lookat position is invalid");
	}

	m_rotatingAction.zero();
}
void CExactPositioningTrigger::Update( float frameTime, Vec3 userPos, Quat userOrient, bool allowTriggering )
{
	if (m_state == eS_Invalid)
		return;

	CRY_ASSERT(m_pos.IsValid());
	CRY_ASSERT(m_userPos.IsValid());
	CRY_ASSERT(m_orient.IsValid());
	CRY_ASSERT(m_userOrient.IsValid());
	CRY_ASSERT(m_posSize.IsValid());
	CRY_ASSERT(NumberValid(m_cosOrientTolerance));

	CRY_ASSERT(NumberValid(frameTime));
	CRY_ASSERT(userPos.IsValid());
	CRY_ASSERT(userOrient.IsValid());

	m_userPos = userPos;
	m_userOrient = userOrient;

	if (m_state == eS_Initializing)
		m_state = eS_Before;

	Plane threshold;
	threshold.SetPlane( m_orient.GetColumn1(), m_pos );
	if (threshold.DistFromPlane(userPos) >= 0.0f)
	{
		if (m_sideTime < 0.0f)
			m_sideTime = 0.0f;
		else
			m_sideTime += frameTime;
	}
	else
	{
		if (m_sideTime > 0.0f)
			m_sideTime = 0.0f;
		else
			m_sideTime -= frameTime;
	}

	Vec3 curDir = userOrient.GetColumn1();
	Vec3 wantDir = m_orient.GetColumn1();

	if (m_state == eS_Before)
	{
		OBB triggerBox;
		triggerBox.SetOBB( Matrix33(m_orient), m_posSize+Vec3(0.5f,0.5f,0), ZERO );
		if (Overlap::Point_OBB(m_userPos, m_pos, triggerBox))
			m_state = eS_Optimizing;
	}

	if ((m_state == eS_Optimizing) && allowTriggering)
	{
#ifdef INCLUDE_EXACTPOS_DEBUGGING
		bool debug = (CAnimationGraphCVars::Get().m_debugExactPos != 0);
		CPersistantDebug* pPD = CCryAction::GetCryAction()->GetPersistantDebug();
#endif

		Vec3 bump(0.0f, 0.0f, 0.1f);

		Vec3 posDistanceError = m_userPos - m_pos;
		if ( posDistanceError.z > -1.0f && posDistanceError.z < 1.0f )
			posDistanceError.z = 0;

		Vec3 orientFwd = m_orient.GetColumn1(); orientFwd.z = 0.0f; orientFwd.Normalize();
		Vec3 rotAnimMovementWanted = orientFwd * m_animMovementLength;

		Vec3 userFwd = m_userOrient.GetColumn1(); userFwd.z = 0.0f; userFwd.Normalize();
		Vec3 rotAnimMovementUser = userFwd * m_animMovementLength;

		float cosRotError = orientFwd.Dot( userFwd );
		float rotError = CLAMP(m_cosOrientTolerance - cosRotError, 0.0f, 1.0f);
		//Vec3 rotDistanceError = rotAnimMovementUser - rotAnimMovementWanted;

		float fwdDistance = fabsf(orientFwd.Dot( posDistanceError ));
		float sideDistance = max( 0.0f, sqrtf( MAX(0,posDistanceError.GetLengthSquared2D() - sqr(fwdDistance)) ) - m_width );

		float deltaFwd = m_oldFwdDir < fwdDistance ? fwdDistance - m_oldFwdDir : 0.0f;
		m_oldFwdDir = fwdDistance;
		fwdDistance += deltaFwd * 0.5f;
		deltaFwd = max(0.1f, deltaFwd);

		f32 distanceError = sqrtf(sqr(fwdDistance) + sqr(sideDistance)); // posDistanceError.len() * m_distanceErrorFactor;
		f32 temp = 1.0f-sqr(1.0f-rotError*rotError);
		temp = max(temp,0.0f); //never do a sqrtf with a negative value 
		f32 orientError = sqrtf(temp) * m_animMovementLength; // rotDistanceError.len();
		f32 totalDistanceError = distanceError + orientError;
		if (((m_distanceError * 1.05f) < distanceError) && ((m_orientError * 1.05f) < orientError) && (totalDistanceError < deltaFwd) ||
			(totalDistanceError < deltaFwd*0.5f))
		{ // found local minimum in distance error, force triggering.
			m_state = eS_Triggered;
			m_oldFwdDir = 0.0f;

#ifdef INCLUDE_EXACTPOS_DEBUGGING
			if (debug)
			{
				pPD->Begin("AnimationTrigger LocalMinima Triggered", false);
				pPD->AddPlanarDisc(m_pos + bump, 0.0f, m_distanceError, ColorF(0,1,0,0.5), 10.0f);
			}
#endif
		}
		else
		{
			m_distanceError = m_distanceError > distanceError ? distanceError : m_distanceError * 0.999f; // should timeout in ~2 secs. on 50 FPS
			m_orientError = m_orientError > orientError ? orientError : m_orientError - 0.0001f;

#ifdef INCLUDE_EXACTPOS_DEBUGGING
			if (debug)
			{
				pPD->Begin("AnimationTrigger LocalMinima Optimizing", true);
				pPD->AddPlanarDisc(m_pos + bump, 0.0f, m_distanceError, ColorF(1,1,0,0.5), 10.0f);
			}
#endif
		}

#ifdef INCLUDE_EXACTPOS_DEBUGGING
		if (debug)
		{
			pPD->AddLine(m_userPos + bump, m_pos + bump, ColorF(1,0,0,1), 10.0f);
			pPD->AddLine(m_userPos + rotAnimMovementUser + bump, m_pos + rotAnimMovementWanted + bump, ColorF(1,0,0,1), 10.0f);
			pPD->AddLine(m_pos + bump, m_pos + rotAnimMovementWanted + bump, ColorF(1,0.5,0,1), 10.0f);
			pPD->AddLine(m_userPos + bump, m_pos + rotAnimMovementUser + bump, ColorF(1,0.5,0,1), 10.0f);
		}
#endif
	}

	CRY_ASSERT(m_pos.IsValid());
	CRY_ASSERT(m_userPos.IsValid());
	CRY_ASSERT(m_orient.IsValid());
	CRY_ASSERT(m_userOrient.IsValid());
	CRY_ASSERT(m_posSize.IsValid());
	CRY_ASSERT(NumberValid(m_cosOrientTolerance));
}
Example #17
0
bool Plane::Intersects(const OBB &obb) const
{
    return obb.Intersects(*this);
}
Example #18
0
bool const OBB::overlaps(OBB& other)
{
	if((overlapsOneWay(other)==true)&&(other.overlapsOneWay(*this)))
	    return true;
	return false;
}
Example #19
0
File: AABB.cpp Project: katik/naali
void AABB::Enclose(const OBB &obb)
{
	for(int i = 0; i < 8; ++i)
		Enclose(obb.CornerPoint(i));
}
Example #20
0
bool AABB::Contains(const OBB &obb) const
{
	return Contains(obb.MinimalEnclosingAABB());
}
Example #21
0
bool AABB::Intersects(const OBB &obb) const
{
	return obb.Intersects(*this);
}
Example #22
0
bool Triangle::Intersects(const OBB &obb) const
{
    return obb.Intersects(*this);
}
Example #23
0
bool Sphere::Intersects(const OBB &obb, vec *closestPointOnOBB) const
{
	return obb.Intersects(*this, closestPointOnOBB);
}
Example #24
0
File: Ray.cpp Project: Ilikia/naali
bool Ray::Intersects(const OBB &obb, float *dNear, float *dFar) const
{
    return obb.Intersects(*this, dNear, dFar);
}
Example #25
0
void GraphicsWorld::DebugDrawOBB(const OBB &obb, const Color &clr, bool depthTest)
{
    for(int i = 0; i < 12; ++i)
        DebugDrawLineSegment(obb.Edge(i), clr, depthTest);
}
Example #26
0
bool Capsule::Intersects(const OBB &obb) const
{
	return Intersects(obb.ToPolyhedron());
}
bool CIntersectionAssistanceUnit::TestForIntersectionAtLocation(const eTestMethod testMethod, const Matrix34& wMat, EntityId testEntityId, EntityId ignoreEnt, QuatT& outAdjustedResult, const bool bCentreOnFocalEnt /* = false */, bool bRenderOnFail /* = true */, const int index /* = -1*/)
{
    // Build an OOBB that surrounds this entity, test for intersection between that and world
    IEntity* pEntity = gEnv->pEntitySystem->GetEntity(testEntityId);
    if(pEntity)
        {
            IPhysicalEntity* pPhysical = pEntity->GetPhysics();
            if(pPhysical)
                {
                    OBB entOBB;
                    AABB entAABB;
                    pEntity->GetLocalBounds(entAABB);
                    entOBB.SetOBBfromAABB(Quat(IDENTITY), entAABB);

                    // Do Primitive world intersection
                    primitives::box physBox;
                    physBox.bOriented = 1;

                    // LSpace
                    physBox.center = entOBB.c;
                    physBox.Basis = entOBB.m33;
                    physBox.size.x = entOBB.h.x;
                    physBox.size.y = entOBB.h.y;
                    physBox.size.z = entOBB.h.z;

                    // WSpace
                    physBox.center					= wMat.TransformPoint(physBox.center);
                    physBox.Basis					  *= Matrix33(wMat).GetInverted();

                    // Optional tweak - We can get away with a little bit of scaling down (if edges are slightly embedded the physics pushes them out easily)
                    physBox.size = physBox.size.scale(kPhysBoxScaleFactor);

                    // adjust
                    Vec3 vAdjustments(0.0f,0.0f,0.0f);
                    if(bCentreOnFocalEnt && m_focalEntityId)
                        {
                            Vec3 vDesiredPos = CalculateTargetAdjustPoint(pEntity, wMat, physBox.center);
                            vAdjustments = (vDesiredPos - physBox.center);
                            physBox.center += vAdjustments;
                        }

                    IEntity* pIgnoreEnt = gEnv->pEntitySystem->GetEntity(ignoreEnt);
                    IPhysicalEntity* pIgnorePhys = pIgnoreEnt ? pIgnoreEnt->GetPhysics() : NULL;

                    // Test
                    if(testMethod == eTM_Immediate
#ifndef _RELEASE
                            || g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled >= 1
#endif // #ifndef _RELEASE
                      )
                        {
                            geom_contact *contacts;
                            intersection_params params;
                            float numHits = gEnv->pPhysicalWorld->PrimitiveWorldIntersection(primitives::box::type, &physBox, Vec3(ZERO),
                                            ent_static|ent_terrain, &contacts, 0,
                                            3, &params, 0, 0, &pIgnorePhys, pIgnorePhys ? 1 : 0);

                            // Debug
#ifndef _RELEASE
                            if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled)
                                {

                                    const bool bIntersect = numHits <= 0.0f ? false : true;
                                    if(bRenderOnFail || !bIntersect)
                                        {
                                            const ColorB colorPositive = ColorB(16, 96, 16);
                                            const ColorB colorNegative = ColorB(128, 0, 0);
                                            const ColorB colorSelected = ColorB(0,255,0);

                                            if(numHits > 0.0f)
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(contacts->pt, 0.1f, colorPositive);
                                                }

                                            OBB finalOBB;
                                            finalOBB.SetOBB(Matrix33(IDENTITY), physBox.size, Vec3(0.0f,0.0f,0.0f));
                                            Matrix34 drawMat = wMat;
                                            drawMat.AddTranslation(physBox.center - wMat.GetTranslation());
                                            if(index != -1 && index == m_currentBestIndex)
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, colorSelected, eBBD_Faceted);
                                                }
                                            else
                                                {
                                                    gEnv->pRenderer->GetIRenderAuxGeom()->DrawOBB(finalOBB, drawMat, false, bIntersect ? colorNegative : colorPositive, eBBD_Faceted);
                                                }

                                        }
                                }
#endif //#ifndef RELEASE

                            // If we performed an adjust, make sure we pass out the QuatT representing the FINAL ENTITY POSITION that passed/failed (not the phys box etc)
                            outAdjustedResult.t = wMat.GetTranslation() + vAdjustments;
                            outAdjustedResult.q = Quat(wMat);

#ifndef _RELEASE
                            // allow optional debug drawing of last known good positions by retaining non adjusted position
                            if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 1)
                                {
                                    outAdjustedResult.t = wMat.GetTranslation();
                                }
#endif // #ifndef _RELEASE

                            return (numHits > 0.0f);
                        }
                    else
                        {
                            // QUEUE primitive intersection check
                            outAdjustedResult.t = wMat.GetTranslation() + vAdjustments;
                            outAdjustedResult.q = Quat(wMat);
                            CRY_ASSERT(index >= 0);
                            m_intersectionTester.DoCheck(index,physBox,outAdjustedResult,pIgnorePhys);
                            return false;
                        }
                }
        }

    return false;
}
bool Frustum::collision(const CollisionObject * pCollisionObject, bool calculateNormal)
{
	calculateNormal;

	if(pCollisionObject->getCollisionType()==CollisionType_Sphere)
	{
		Sphere * pSphere = (Sphere*) pCollisionObject;

		float x = pSphere->getX();
		float y = pSphere->getY();
		float z = pSphere->getZ();
		float r = pSphere->getR();
		
		for(int i=0;i<6;i++)
		{
			if(mPlanes[i].a * x + mPlanes[i].b * y + mPlanes[i].c * z + mPlanes[i].d <= -r)
			{
				return false;
			}
		}
		
		return true;
	}
	else if(pCollisionObject->getCollisionType()==CollisionType_AABB)
	{
		AABB * pAABB = (AABB*) pCollisionObject;
		
		for(unsigned int j=0;j<6;j++)
		{
			unsigned int cornersInside = 8;

			for(unsigned int i=0;i<8;i++)
			{
				D3DXVECTOR3 corner = pAABB->getCorner(i);

				/*
				if(mPlanes[j].a * corner.x + mPlanes[j].b * corner.y + mPlanes[j].c * corner.z + mPlanes[j].d <= 0)
				{
					cornersInside--;
				}
				*/

				if(D3DXPlaneDotNormal(&mPlanes[j], &corner) +  mPlanes[j].d <= 0)
				{
					cornersInside--;
				}
			}

			if(cornersInside==0)
			{
				return false;
			}
		}
		
		return true;
	}
	if(pCollisionObject->getCollisionType()==CollisionType_OBB)
	{
		OBB * pOBB = (OBB*)pCollisionObject;

		for(unsigned int j=0;j<6;j++)
		{
			unsigned int cornersInside = 8;

			for(unsigned int i=0; i<8; i++)
			{
				D3DXVECTOR3 corner = pOBB->getCorner(i);

				if(D3DXPlaneDotNormal(&mPlanes[j], &corner) +  mPlanes[j].d <= 0)
				{
					cornersInside--;
				}				
			}

			if(cornersInside==0)
			{
				return false;
			}
		}
		
		return true;
	}

	return false;
}
bool CIntersectionAssistanceUnit::GetHighestScoringLastKnownGoodPosition( const QuatT& baseOrientation, QuatT& outQuat ) const
{
    bool bFlippedIsBest = false;

    if(!m_lastKnownGoodPositions.empty())
        {
            // Higher is better
            float fBestScore = 0.0f;
            int bestIndex = -1;
            Vec3 vBaseUpDir = baseOrientation.q.GetColumn2().GetNormalized();
            for(uint8 i = 0; i < m_lastKnownGoodPositions.size(); ++i)
                {
                    const QuatT& qLastKnownGood = m_lastKnownGoodPositions[i];
                    if(IsPositionWithinAcceptedLimits(qLastKnownGood.t, baseOrientation.t, kDistanceTolerance))
                        {
                            // Generate [0.0f,1.0f] score for distance
                            const Vec3 distVec = (qLastKnownGood.t - baseOrientation.t);

                            const float length = max(distVec.GetLengthFast(),0.0001f);
                            const float distanceScore = max(1.0f - (length * kInverseDistanceTolerance) * kDistanceWeight, 0.0f);

                            Vec3 vUpDir		 = qLastKnownGood.q.GetColumn2();

                            const float regularOrientationScore = vBaseUpDir.Dot(vUpDir);
                            const float flippedOrientationScore = vBaseUpDir.Dot(-vUpDir);

                            float orientationScore = max(regularOrientationScore, flippedOrientationScore);
                            orientationScore *= kOrientationWeight;

                            const float fCandidateScore = distanceScore + orientationScore;

#ifndef _RELEASE
                            if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 2)
                                {
                                    CryWatch("[INDEX(%d)] : D[%.3f] O[%.3f] T[%.3f] (%s)", i, distanceScore, orientationScore, fCandidateScore, flippedOrientationScore > regularOrientationScore ? "*F*" : "R");
                                }
#endif //#ifndef _RELEASE

                            if(fCandidateScore > fBestScore)
                                {
                                    bestIndex	 = i;
                                    fBestScore = fCandidateScore;
                                    bFlippedIsBest = (flippedOrientationScore > regularOrientationScore);
                                }
                        }
                }

            if(bestIndex >= 0)
                {
                    outQuat = m_lastKnownGoodPositions[bestIndex];
                    if(bFlippedIsBest)
                        {
                            Matrix34 wMat(outQuat);
                            Vec3 vFlippedUpDir = -outQuat.q.GetColumn2().GetNormalized();
                            Vec3 vForwardDir	 = outQuat.q.GetColumn1().GetNormalized();
                            Vec3 vSideDir			 = -outQuat.q.GetColumn0().GetNormalized();
                            Matrix34 wFlippedMat;
                            wFlippedMat = Matrix34::CreateFromVectors(vSideDir, vForwardDir, vFlippedUpDir, wMat.GetTranslation());
                            outQuat = QuatT(wFlippedMat);

                            // Adjust pos (rotating around OOBB centre effectively)
                            const IEntity* pSubjectEntity = gEnv->pEntitySystem->GetEntity(m_subjectEntityId);
                            if(pSubjectEntity)
                                {
                                    AABB entAABB;
                                    OBB  entOBB;
                                    pSubjectEntity->GetLocalBounds(entAABB);
                                    entOBB.SetOBBfromAABB(Quat(IDENTITY), entAABB);

                                    Vec3 Centre = wMat.TransformPoint(entOBB.c);
                                    Vec3 toCentre = Centre - outQuat.t;
                                    outQuat.t += (toCentre * 2.0f);
                                }
                        }

#ifndef _RELEASE
                    if(g_pGameCVars->pl_pickAndThrow.intersectionAssistDebugEnabled == 2)
                        {
                            m_currentBestIndex = bestIndex;
                            CryWatch("[BEST INDEX] : %d", bestIndex);
                        }
#endif // ifndef _RELEASE

                    return true;
                }
        }

#ifndef _RELEASE
    m_currentBestIndex = -1;
#endif // ifndef _RELEASE

    return false;
}
Example #30
0
bool Line::Intersects(const OBB &obb, float &dNear, float &dFar) const
{
    return obb.Intersects(*this, dNear, dFar);
}