Exemplo n.º 1
0
bool CPersistantDebug::GetEntityParams(EntityId entityId, Vec3& baseCenterPos, float& height)
{
    IEntity *ent = gEnv->pEntitySystem->GetEntity(entityId);
    if (ent)
    {
        AABB bounds;
        ent->GetWorldBounds(bounds);
        baseCenterPos = bounds.GetCenter();
        baseCenterPos.z = bounds.min.z;
        height = bounds.GetSize().z;
        return true;
    }

    return false;
}
Exemplo n.º 2
0
  virtual void GetDimension(BaseObject* op, Vector* mp, Vector* rad) override
  {
    // Find the Minimum/Maximum of the object's bounding
    // box by all hidden child-objects in its hierarchy.
    AABB bbox;
    for (NodeIterator<BaseObject> it(op->GetDown(), op); it; ++it)
    {
      // We skip objects that are being controlled by
      // a generator object.
      if (it->GetInfo() & OBJECT_GENERATOR && !IsControlledByGenerator(*it))
        bbox.Expand(*it, it->GetMg(), false);
    }

    *mp = bbox.GetMidpoint();
    *rad = bbox.GetSize();
  }
// 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();
}
Exemplo n.º 4
0
//------------------------------------------------------------------------
void CGameRules::CullEntitiesInExplosion(const ExplosionInfo &explosionInfo)
{
	if (!g_pGameCVars->g_ec_enable || explosionInfo.damage <= 0.1f)
		return;

	IPhysicalEntity **pents;
	float radiusScale = g_pGameCVars->g_ec_radiusScale;
	float minVolume = g_pGameCVars->g_ec_volume;
	float minExtent = g_pGameCVars->g_ec_extent;
	int   removeThreshold = max(1, g_pGameCVars->g_ec_removeThreshold);

	IActor *pClientActor = g_pGame->GetIGameFramework()->GetClientActor();
	Vec3 radiusVec(radiusScale * explosionInfo.physRadius);
	int i = gEnv->pPhysicalWorld->GetEntitiesInBox(explosionInfo.pos-radiusVec,explosionInfo.pos+radiusVec,pents, ent_rigid|ent_sleeping_rigid);
	int removedCount = 0;

	static IEntityClass* s_pInteractiveEntityClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("InteractiveEntity");
	static IEntityClass* s_pDeadBodyClass = gEnv->pEntitySystem->GetClassRegistry()->FindClass("DeadBody");

	if (i > removeThreshold)
	{
		int entitiesToRemove = i - removeThreshold;
		for(--i;i>=0;i--)
		{
			if(removedCount>=entitiesToRemove)
				break;

			IEntity * pEntity = (IEntity*) pents[i]->GetForeignData(PHYS_FOREIGN_ID_ENTITY);
			if (pEntity)
			{
				// don't remove if entity is held by the player
				if (pClientActor && pEntity->GetId()==pClientActor->GetGrabbedEntityId())
					continue;

				// don't remove items/pickups
				if (IItem* pItem = g_pGame->GetIGameFramework()->GetIItemSystem()->GetItem(pEntity->GetId()))
				{
					continue;
				}
				// don't remove enemies/ragdolls
				if (IActor* pActor = g_pGame->GetIGameFramework()->GetIActorSystem()->GetActor(pEntity->GetId()))
				{
					continue;
				}

				// if there is a flowgraph attached, never remove!
				if (pEntity->GetProxy(ENTITY_PROXY_FLOWGRAPH) != 0)
					continue;

				IEntityClass* pClass = pEntity->GetClass();
				if (pClass == s_pInteractiveEntityClass || pClass == s_pDeadBodyClass)
					continue;

				// get bounding box
				if (IEntityPhysicalProxy* pPhysProxy = (IEntityPhysicalProxy*)pEntity->GetProxy(ENTITY_PROXY_PHYSICS))
				{
					AABB aabb;
					pPhysProxy->GetWorldBounds(aabb);

					// don't remove objects which are larger than a predefined minimum volume
					if (aabb.GetVolume() > minVolume)
						continue;

					// don't remove objects which are larger than a predefined minimum volume
					Vec3 size(aabb.GetSize().abs());
					if (size.x > minExtent || size.y > minExtent || size.z > minExtent)
						continue;
				}

				// marcok: somehow editor doesn't handle deleting non-dynamic entities very well
				// but craig says, hiding is not synchronized for DX11 breakable MP, so we remove entities only when playing pure game
				// alexl: in SinglePlayer, we also currently only hide the object because it could be part of flowgraph logic
				//        which would break if Entity was removed and could not propagate events anymore
				if (gEnv->bMultiplayer == false || gEnv->IsEditor())
				{
					pEntity->Hide(true);
				}
				else
				{
					gEnv->pEntitySystem->RemoveEntity(pEntity->GetId());
				}
				removedCount++;
			}
		}
	}
}
//----------------------------------------------------------------------------------------------------------------------------------
///  Init  dynamics
//----------------------------------------------------------------------------------------------------------------------------------
void CARDYNAMICS::Init(
	class SETTINGS* pSet1, class Scene* pScene1, class FluidsXml* pFluids1,
	COLLISION_WORLD & world,
	const MODEL & chassisModel, const MODEL & wheelModelFront, const MODEL & wheelModelRear,
	const MATHVECTOR<Dbl,3> & position, const QUATERNION<Dbl> & orientation)
{
	pSet = pSet1;  pScene = pScene1;  pFluids = pFluids1;
	this->world = &world;

	MATHVECTOR<Dbl,3> zero(0, 0, 0);
	body.SetPosition(position);
	body.SetOrientation(orientation);
	body.SetInitialForce(zero);
	body.SetInitialTorque(zero);

	// init engine
	engine.SetInitialConditions();


	// init chassis
	btTransform tr;
	tr.setIdentity();

	AABB <float> box = chassisModel.GetAABB();
	for (int i = 0; i < 4; i++)
	{
		MATHVECTOR<float,3> wheelpos = GetLocalWheelPosition(WHEEL_POSITION(i), 0);

		const MODEL * wheelmodel = &wheelModelFront;
		if (i > 1) wheelmodel = &wheelModelRear;

		AABB <float> wheelaabb;
		float sidefactor = 1.0;
		if (i == 1 || i == 3) sidefactor = -1.0;

		wheelaabb.SetFromCorners(
			wheelpos - wheelmodel->GetAABB().GetSize() * 0.5 * sidefactor,
			wheelpos + wheelmodel->GetAABB().GetSize() * 0.5 * sidefactor);
		box.CombineWith(wheelaabb);
	}


	///  chassis shape  ---------------------------------------------------------
	const MATHVECTOR<Dbl,3> verticalMargin(0, 0, 0.3);
	btVector3 origin = ToBulletVector(box.GetCenter() + verticalMargin - center_of_mass);
	btVector3 size = ToBulletVector(box.GetSize() - verticalMargin);

	//btCompoundShape * chassisShape = new btCompoundShape(false);
	#if 0
		//btBoxShape * hull = new btBoxShape( btVector3(1.8,0.8,0.5) );
		btBoxShape * hull = new btBoxShape( btVector3(1.7,0.7,0.3) );
		tr.setOrigin(origin + btVector3(0,0,0.2));
		chassisShape->addChildShape(tr, hull);
	#else
		/// todo: all params in .car
		// y| length  x- width  z^ height
		btScalar w = size.getX()*0.2, r = size.getZ()*0.3, h = 0.45;

		///  spheres
		btScalar l0 = 0.f, w0 = 0.f, h0 = 0.f;
		if (coll_R > 0.f)  r = coll_R;  l0 = coll_Lofs;
		if (coll_W > 0.f)  w = coll_W;  w0 = coll_Wofs;
		if (coll_H > 0.f)  h = coll_H;	h0 = coll_Hofs;
		origin = btVector3(l0, w0, h0);

		btScalar r2 = r*0.6;
		btScalar l1 = coll_posLfront, l2 = coll_posLback, l1m = l1*0.5, l2m = l2*0.5;

		//LogO("Car shape dims:  r="+toStr(r)+"  w="+toStr(w)+"  h="+toStr(h)+"  h0="+toStr(h0));
		//LogO("Car offset:  x="+toStr(origin.x())+"  y="+toStr(origin.y())+"  z="+toStr(origin.z()));

		const int numSph = 14;  int i = 0;
		btScalar rad[numSph];  btVector3 pos[numSph];
		pos[i] = btVector3( l1 , -w,    -h);    	rad[i] = r2;  ++i;  // front
		pos[i] = btVector3( l1 ,  w,    -h);    	rad[i] = r2;  ++i;
		pos[i] = btVector3( l1m, -w,    -h);    	rad[i] = r;   ++i;  // front near
		pos[i] = btVector3( l1m,  w,    -h);    	rad[i] = r;   ++i;

		pos[i] = btVector3( l2m, -w,    -h);    	rad[i] = r;   ++i;  // rear near
		pos[i] = btVector3( l2m,  w,    -h);    	rad[i] = r;   ++i;
		pos[i] = btVector3( l2 , -w,    -h);    	rad[i] = r2;  ++i;  // rear
		pos[i] = btVector3( l2 ,  w,    -h);    	rad[i] = r2;  ++i;

		pos[i] = btVector3( 0.4, -w*0.8, h*0.2);	rad[i] = r2;  ++i;  // top
		pos[i] = btVector3( 0.4,  w*0.8, h*0.2);	rad[i] = r2;  ++i;
		pos[i] = btVector3(-0.3, -w*0.8, h*0.4);	rad[i] = r2;  ++i;
		pos[i] = btVector3(-0.3,  w*0.8, h*0.4);	rad[i] = r2;  ++i;
		pos[i] = btVector3(-1.1, -w*0.8, h*0.2);	rad[i] = r2;  ++i;  // top rear
		pos[i] = btVector3(-1.1,  w*0.8, h*0.2);	rad[i] = r2;  ++i;

		for (i=0; i < numSph; ++i)
			pos[i] += origin;
		btMultiSphereShape* chassisShape = new btMultiSphereShape(pos, rad, numSph);
		//chassisShape->setMargin(0.2f);
	#endif


	Dbl chassisMass = body.GetMass();// * 0.4;  // Magic multiplier makes collisions better - problem: mud is very different
	MATRIX3 <Dbl> inertia = body.GetInertia();
	btVector3 chassisInertia(inertia[0], inertia[4], inertia[8]);

	btTransform transform;
	transform.setOrigin(ToBulletVector(position));
	transform.setRotation(ToBulletQuaternion(orientation));
	btDefaultMotionState * chassisState = new btDefaultMotionState();
	chassisState->setWorldTransform(transform);

	btRigidBody::btRigidBodyConstructionInfo info(chassisMass, chassisState, chassisShape, chassisInertia);
	info.m_angularDamping = ang_damp;
	info.m_restitution = 0.0;  //...
	info.m_friction = coll_friction;  /// 0.4~ 0.7
	///  chasis^
	chassis = world.AddRigidBody(info, true, pSet->game.collis_cars);
	chassis->setActivationState(DISABLE_DEACTIVATION);
	chassis->setUserPointer(new ShapeData(ST_Car, this, 0));  ///~~
	
	world.AddAction(this);
	

	///  join chassis and wheel triggers
	//________________________________________________________
	{
		for (int w=0; w < 4; ++w)
		{
			WHEEL_POSITION wp = WHEEL_POSITION(w);
			Dbl whR = GetWheel(wp).GetRadius() * 1.2;  //bigger par..
			MATHVECTOR<float,3> wheelpos = GetWheelPosition(wp, 0);  //par
			wheelpos[0] += coll_Lofs;
			wheelpos[2] += coll_flTrig_H;

			btSphereShape* whSph = new btSphereShape(whR);
			//btCylinderShapeX* whSph = new btCylinderShapeX(btVector3(whR,whR,whR));//todo..
			whTrigs = new btRigidBody(0.001f, 0, whSph);
			
			whTrigs->setUserPointer(new ShapeData(ST_Wheel, this, 0, w));  ///~~
			whTrigs->setActivationState(DISABLE_DEACTIVATION);
			whTrigs->setCollisionFlags(whTrigs->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE);
			world.world->addRigidBody(whTrigs);
			world.shapes.push_back(whSph);
				
			//todo: collision mask only to fluid triggers
			//todo: optimize- 1 constr only or none?
			//todo: cylinders? fixed constr\_
			/*btTransform f1,f2;  f1.setIdentity();  f2.setIdentity();
			f1.setOrigin(ToBulletVector(wheelpos));
			btGeneric6DofConstraint* constr = new btGeneric6DofConstraint(*chassis, *whTrigs, f1, f2, true);
			constr->setLimit(0,0,0);  constr->setLimit(1,0,1);  constr->setLimit(2,0,0);
			//constr->setLimit(3,0,0);
			//constr->setLimit(4,0,0);
			constr->setLimit(5,0,0);/*??*/
			btTypedConstraint* constr = new btPoint2PointConstraint(*chassis, *whTrigs,
				ToBulletVector(wheelpos), btVector3(0,0,0));
			world.world->addConstraint(constr, true);
			world.constraints.push_back(constr);
		}

		///  init poly for buoyancy computations
		//________________________________________________________
		if (poly == NULL)
		{
			poly = new Polyhedron();
			poly->numVerts = 8;  poly->numFaces = 12;
			poly->verts = new Vec3[8];
			poly->faces = new Face[12];

			float hx = 1.2f, hy = 0.7f, hz = 0.4f;  // box dim
			poly->verts[0] = Vec3(-hx,-hy,-hz);	poly->verts[1] = Vec3(-hx,-hy, hz);
			poly->verts[2] = Vec3(-hx, hy,-hz);	poly->verts[3] = Vec3(-hx, hy, hz);
			poly->verts[4] = Vec3( hx,-hy,-hz);	poly->verts[5] = Vec3( hx,-hy, hz);
			poly->verts[6] = Vec3( hx, hy,-hz);	poly->verts[7] = Vec3( hx, hy, hz);

			poly->faces[0] = Face(0,1,3);	poly->faces[1] = Face(0,3,2);	poly->faces[2] = Face(6,3,7);	poly->faces[3] = Face(6,2,3);
			poly->faces[4] = Face(4,6,5);	poly->faces[5] = Face(6,7,5);	poly->faces[6] = Face(4,5,0);	poly->faces[7] = Face(0,5,1);
			poly->faces[8] = Face(5,7,1);	poly->faces[9] = Face(7,3,1);	poly->faces[10]= Face(0,6,4);	poly->faces[11]= Face(0,2,6);

			poly->length = 1.0f;  //  approx. length-?
			poly->volume = ComputeVolume(*poly);

			body_mass = 1900.0f * 2.688;  //poly->volume;  // car density
			body_inertia = (4.0f * body_mass / 12.0f) * btVector3(hy*hz, hx*hz, hx*hy);
		}
	}
	//-------------------------------------------------------------	


	// init wheels, suspension
	for (int i = 0; i < WHEEL_POSITION_SIZE; i++)
	{
		wheel[WHEEL_POSITION(i)].SetInitialConditions();
		wheel_velocity[i].Set(0.0);
		wheel_position[i] = GetWheelPositionAtDisplacement(WHEEL_POSITION(i), 0);
		wheel_orientation[i] = orientation * GetWheelSteeringAndSuspensionOrientation(WHEEL_POSITION(i));
	}

	AlignWithGround();//--
}
Exemplo n.º 6
0
//-----------------------------------------------------------------------
void gkAuxRenderer::AuxRenderAABB( const AABB& aabb, ColorF& color /*= ColorF(1.0,1.0,1.0,1.0)*/, bool ignoreZ )
{

	//Vec3 vecAABB = aabb.GetCenter();
	AuxRender3DBoxFrame( aabb.GetCenter(), aabb.GetSize(), color, ignoreZ );
}