Example #1
0
/* adds a torque given by the vector vec to the body b,
 * relative to the body reference frame */
void body_add_rel_torque (dBodyID b, const t_real *vec) {
  /* let's check if we have the surface, in which case we exit doing nothing */
  if (b == SURFACE_BODY_ID) return;

  /* in all other cases, we add the torque to the body */
  dBodyAddRelTorque (b, vec[0], vec[1], vec[2]);
}
Example #2
0
    void cPhysicsObject::AddTorqueRelativeToObjectNm(const physvec_t& torqueNm)
    {
      /*// Get our current rotation
      breathe::math::cQuaternion qOriginal;
      qOriginal.SetFromODEQuaternion(dBodyGetQuaternion(body));

      // Find our desired rotation (Current but with x=0, y=0)
      breathe::math::cQuaternion qDesired = qOriginal;
      qDesired.x = 0.0f;
      qDesired.y = 0.0f;
      float quat_len = sqrt(qDesired.z * qDesired.z + qDesired.w * qDesired.w);
      qDesired.z /= quat_len;
      qDesired.w /= quat_len;

      // Set our rotation to a rotation in between these two quaternions
      breathe::math::cQuaternion qInterpolated;
      qInterpolated.Slerp(qOriginal, qDesired, 0.1f);
      dReal values[4];
      qInterpolated.GetODEQuaternion(values);
      dBodySetQuaternion(body, values);

      // Get rid of our x,y angular velocity as well
      const dReal* rot = dBodyGetAngularVel(body);
      dBodySetAngularVel(body, 0.0f, 0.0f, rot[2]);*/


      dBodyAddRelTorque(body, torqueNm.x, torqueNm.y, torqueNm.z);
    }
Example #3
0
void Balaenidae::doDynamics(dBodyID body)
{
    Vec3f Ft;

    Ft[0]=0;Ft[1]=0;Ft[2]=getThrottle();
    dBodyAddRelForce(body,Ft[0],Ft[1],Ft[2]);

    dBodyAddRelTorque(body,0.0f,Balaenidae::rudder*1000,0.0f);

    if (offshoring == 1) {
        offshoring=0;
        setStatus(Balaenidae::SAILING);
    }
    else if (offshoring > 0)
    {
        // Add a retractive force to keep it out of the island.
        Vec3f ap = Balaenidae::ap;

        setThrottle(0.0);

        Vec3f V = ap*(-10000);

        dBodyAddRelForce(body,V[0],V[1],V[2]);
        offshoring--;
    }


    // Buyoncy
    //if (pos[1]<0.0f)
    //    dBodyAddRelForce(me,0.0,9.81*20050.0f,0.0);

    dReal *v = (dReal *)dBodyGetLinearVel(body);

    dVector3 O;
    dBodyGetRelPointPos( body, 0,0,0, O);

    dVector3 F;
    dBodyGetRelPointPos( body, 0,0,1, F);

    F[0] = (F[0]-O[0]);
    F[1] = (F[1]-O[1]);
    F[2] = (F[2]-O[2]);

    Vec3f vec3fF;
    vec3fF[0] = F[0];vec3fF[1] = F[1]; vec3fF[2] = F[2];

    Vec3f vec3fV;
    vec3fV[0]= v[0];vec3fV[1] = v[1]; vec3fV[2] = v[2];

    speed = vec3fV.magnitude();

    VERIFY(speed, me);

    vec3fV = vec3fV * 0.02f;

    dBodyAddRelForce(body,vec3fV[0],vec3fV[1],vec3fV[2]);

    wrapDynamics(body);
}
Example #4
0
IoObject *IoODEBody_addRelTorque(IoODEBody *self, IoObject *locals, IoMessage *m)
{
	const double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
	const double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
	const double z = IoMessage_locals_doubleArgAt_(m, locals, 2);

	IoODEBody_assertValidBody(self, locals, m);
	dBodyAddRelTorque(BODYID, x, y, z);
	return self;
}
Example #5
0
void ODE_ForceHandle::updateActuators() {
	if(mHostBody != 0 && mActivateForces->get()) {
		dBodyID hostBodyId = mHostBody->getRigidBodyID();
		if(hostBodyId != 0) {
			if(mApplyRelativeForces->get()) {
				dBodyAddForce(hostBodyId, mAppliedForce->getX(), mAppliedForce->getY(), mAppliedForce->getZ());
				dBodyAddTorque(hostBodyId, mAppliedTorque->getX(), mAppliedTorque->getY(),mAppliedTorque->getZ());
			}
			else {
				dBodyAddRelForce(hostBodyId, mAppliedForce->getX(), mAppliedForce->getY(), mAppliedForce->getZ());
				dBodyAddRelTorque(hostBodyId, mAppliedTorque->getX(), mAppliedTorque->getY(),mAppliedTorque->getZ());
			}
		}
	}
}
Example #6
0
void RigidBody::addRelativeTorque(const ngl::Vec3 &_t)
{
  dBodyAddRelTorque(m_id,_t.m_x,_t.m_y,_t.m_z);
}
Example #7
0
	void ODESimulator::stepPhysics()
	{
		// Apply linear and angular damping; if using the "add opposing
		// forces" method, be sure to do this before calling ODE step
		// function.
		std::vector<Solid*>::iterator iter;
		for (iter = mSolidList.begin(); iter != mSolidList.end(); ++iter)
		{
			ODESolid* solid = (ODESolid*) (*iter);

			if (!solid->isStatic())
			{
				if (solid->isSleeping())
				{
					// Reset velocities, force, & torques of objects that go
					// to sleep; ideally, this should happen in the ODE
					// source only once - when the object initially goes to
					// sleep.

					dBodyID bodyID = ((ODESolid*) solid)->internal_getBodyID();
					dBodySetLinearVel(bodyID, 0, 0, 0);
					dBodySetAngularVel(bodyID, 0, 0, 0);
					dBodySetForce(bodyID, 0, 0, 0);
					dBodySetTorque(bodyID, 0, 0, 0);
				}
				else
				{
					// Dampen Solid motion.  3 possible methods:
					// 1) apply a force/torque in the opposite direction of
					// motion scaled by the body's velocity
					// 2) same as 1, but scale the opposing force by
					// the body's momentum (this automatically handles
					// different mass values)
					// 3) reduce the body's linear and angular velocity by
					// scaling them by 1 - damping * stepsize

					dBodyID bodyID = solid->internal_getBodyID();
					dMass mass;
					dBodyGetMass(bodyID, &mass);

					// Method 1
					//const dReal* l = dBodyGetLinearVel(bodyID);
					//dReal damping = -solid->getLinearDamping();
					//dBodyAddForce(bodyID, damping*l[0], damping*l[1], damping*l[2]);
					//const dReal* a = dBodyGetAngularVel(bodyID);
					//damping = -solid->getAngularDamping();
					//dBodyAddTorque(bodyID, damping*a[0], damping*a[1], damping*a[2]);

					// Method 2
					// Since the ODE mass.I inertia matrix is local, angular
					// velocity and torque also need to be local.

					// Linear damping
					real linearDamping = solid->getLinearDamping();
					if (0 != linearDamping)
					{
						const dReal * lVelGlobal = dBodyGetLinearVel(bodyID);

						// The damping force depends on the damping amount,
						// mass, and velocity (i.e. damping amount and
						// momentum).
						dReal dampingFactor = -linearDamping * mass.mass;
						dVector3 dampingForce = {
						                            dampingFactor * lVelGlobal[0],
						                            dampingFactor * lVelGlobal[1],
						                            dampingFactor * lVelGlobal[2] };

						// Add a global force opposite to the global linear
						// velocity.
						dBodyAddForce(bodyID, dampingForce[0],
						               dampingForce[1], dampingForce[2]);
					}

					// Angular damping
					real angularDamping = solid->getAngularDamping();
					if (0 != angularDamping)
					{
						const dReal * aVelGlobal = dBodyGetAngularVel(bodyID);
						dVector3 aVelLocal;
						dBodyVectorFromWorld(bodyID, aVelGlobal[0],
						                      aVelGlobal[1], aVelGlobal[2], aVelLocal);

						// The damping force depends on the damping amount,
						// mass, and velocity (i.e. damping amount and
						// momentum).
						//dReal dampingFactor = -angularDamping * mass.mass;
						dReal dampingFactor = -angularDamping;
						dVector3 aMomentum;

						// Make adjustments for inertia tensor.
						dMULTIPLYOP0_331(aMomentum, = , mass.I, aVelLocal);
						dVector3 dampingTorque = {
						                             dampingFactor * aMomentum[0],
						                             dampingFactor * aMomentum[1],
						                             dampingFactor * aMomentum[2] };

						// Add a local torque opposite to the local angular
						// velocity.
						dBodyAddRelTorque(bodyID, dampingTorque[0],
						                   dampingTorque[1], dampingTorque[2]);
					}

					//dMass mass;
					//dBodyGetMass(bodyID, &mass);
					//const dReal* l = dBodyGetLinearVel(bodyID);
					//dReal damping = -solid->getLinearDamping() * mass.mass;
					//dBodyAddForce(bodyID, damping*l[0], damping*l[1], damping*l[2]);
					//const dReal* aVelLocal = dBodyGetAngularVel(bodyID);
					////dVector3 aVelLocal;
					////dBodyVectorFromWorld(bodyID, aVelGlobal[0], aVelGlobal[1], aVelGlobal[2], aVelLocal);
					//damping = -solid->getAngularDamping();
					//dVector3 aMomentum;
					//dMULTIPLYOP0_331(aMomentum, =, aVelLocal, mass.I);
					//dBodyAddTorque(bodyID, damping*aMomentum[0], damping*aMomentum[1],
					//  damping*aMomentum[2]);

					// Method 3
					//const dReal* l = dBodyGetLinearVel(bodyID);
					//dReal damping = (real)1.0 - solid->getLinearDamping() * mStepSize;
					//dBodySetLinearVel(bodyID, damping*l[0], damping*l[1], damping*l[2]);
					//const dReal* a = dBodyGetAngularVel(bodyID);
					//damping = (real)1.0 - solid->getAngularDamping() * mStepSize;
					//dBodySetAngularVel(bodyID, damping*a[0], damping*a[1], damping*a[2]);
				}
			}
		}

		// Do collision detection; add contacts to the contact joint group.
		dSpaceCollide(mRootSpaceID, this,
		               &ode_hidden::internal_collisionCallback);

		// Take a simulation step.
		if (SOLVER_QUICKSTEP == mSolverType)
		{
			dWorldQuickStep(mWorldID, mStepSize);
		}
		else
		{
			dWorldStep(mWorldID, mStepSize);
		}

		// Remove all joints from the contact group.
		dJointGroupEmpty(mContactJointGroupID);

		// Fix angular velocities for freely-spinning bodies that have
		// gained angular velocity through explicit integrator inaccuracy.
		for (iter = mSolidList.begin(); iter != mSolidList.end(); ++iter)
		{
			ODESolid* s = (ODESolid*) (*iter);
			if (!s->isSleeping() && !s->isStatic())
			{
				s->internal_doAngularVelFix();
			}
		}
	}
void PhysicsBody::addRelTorque(const Vec3f &v)
{
    dBodyAddRelTorque(_BodyID,v.x(), v.y(), v.z());
}
Example #9
0
void AvatarGameObj::step_impl() {
  dBodyID body = get_entity().get_id();
  
  const Channel* chn;
  
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::TranslateX);
  if (chn->is_on()) {
    float v = (chn->get_value())*(MAX_STRAFE/MAX_FPS);
    dBodyAddRelForce(body, -v, 0.0, 0.0);
  }
  
  bool pushing_up = false;
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::TranslateY);
  if (chn->is_on()) {
    float v = (chn->get_value())*(MAX_STRAFE/MAX_FPS);
    if (Saving::get().config().invertTranslateY()) {
      v = -v;
    }
    dBodyAddRelForce(body, 0.0, -v, 0.0);
    if (v < 0) {
      pushing_up = true;
    }
  }
  
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::TranslateZ);
  if (chn->is_on()) {
    float v = (chn->get_value())*(MAX_ACCEL/MAX_FPS);
    dBodyAddRelForce(body, 0.0, 0.0, -v);
  }
  
  const dReal* avel = dBodyGetAngularVel(body);
  dVector3 rel_avel;
  dBodyVectorFromWorld(body, avel[0], avel[1], avel[2], rel_avel);
  
  // X-turn and x-counterturn
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::RotateY);
  if (chn->is_on()) {
    float v = -(chn->get_value())*(MAX_TURN/MAX_FPS);
    dBodyAddRelTorque(body, 0.0, v, 0.0);
  } else {
    float cv = rel_avel[1]*-CTURN_COEF/MAX_FPS;
    dBodyAddRelTorque(body, 0.0, cv, 0.0);
  }
  
  // Y-turn and y-counterturn
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::RotateX);
  if (chn->is_on()) {
    float v = (chn->get_value())*(MAX_TURN/MAX_FPS);
    if (Saving::get().config().invertRotateY()) {
      v = -v;
    }
    dBodyAddRelTorque(body, v, 0.0, 0.0);
  } else {
    float cv = rel_avel[0]*-CTURN_COEF/MAX_FPS;
    dBodyAddRelTorque(body, cv, 0.0, 0.0);
  }
  
  // Roll and counter-roll
  chn = &Input::get_axis_ch(ORSave::AxisBoundAction::RotateZ);
  if (chn->is_on()) {
    float v = (chn->get_value())*(MAX_ROLL/MAX_FPS);
    dBodyAddRelTorque(body, 0.0, 0.0, v);
  } else {
    float cv = rel_avel[2]*(-CROLL_COEF/MAX_FPS);
    dBodyAddRelTorque(body, 0.0, 0.0, cv);
  }
  
  // Changing stance between superman-style and upright
  if (_attached) {
    _uprightness += UPRIGHTNESS_STEP_DIFF;
  } else {
    _uprightness -= UPRIGHTNESS_STEP_DIFF;
  }
  if (_uprightness > 1.0) { _uprightness = 1.0; } else if (_uprightness < 0.0) { _uprightness = 0.0; }
  
  update_geom_offsets();
  
  _attached = _attached_this_frame;
  
  // If we are attached, work to keep ourselves ideally oriented to the attachment surface
  if (_attached) {
    Vector sn_rel = vector_from_world(_sn);
    Vector lvel = Vector(dBodyGetLinearVel(body));
    Vector lvel_rel = vector_from_world(lvel);
    Vector avel = Vector(dBodyGetAngularVel(body));
    Vector avel_rel = vector_from_world(avel);
    
    // Apply as much of each delta as we can
    
    // X and Z orientation delta
    // TODO Maybe should translate body so that the contact point stays in the same spot through rotation
    float a = limit_abs(_zrot_delta, RUNNING_ADJ_RATE_Z_ROT/MAX_FPS);
    Vector body_x(vector_to_world(Vector(cos(a), sin(a), 0)));
    a = limit_abs(-_xrot_delta, RUNNING_ADJ_RATE_X_ROT/MAX_FPS);
    Vector body_y(vector_to_world(Vector(0, cos(a), sin(a))));
    dMatrix3 matr;
    dRFrom2Axes(matr, body_x.x, body_x.y, body_x.z, body_y.x, body_y.y, body_y.z);
    dBodySetRotation(body, matr);
    
    // Y position delta
    // If the user is pushing up, set the target point high above the ground so we escape sticky attachment
    set_pos(get_pos() + _sn*limit_abs(_ypos_delta + (pushing_up ? RUNNING_MAX_DELTA_Y_POS*2 : 0), RUNNING_ADJ_RATE_Y_POS/MAX_FPS));
    
    // Y linear velocity delta
    lvel_rel.y += limit_abs(_ylvel_delta, RUNNING_ADJ_RATE_Y_LVEL/MAX_FPS);
    lvel = vector_to_world(lvel_rel);
    dBodySetLinearVel(body, lvel.x, lvel.y, lvel.z);
    
    // X and Z angular velocity delta
    avel_rel.x += limit_abs(_xavel_delta, RUNNING_ADJ_RATE_X_AVEL/MAX_FPS);
    avel_rel.z += limit_abs(_zavel_delta, RUNNING_ADJ_RATE_Z_AVEL/MAX_FPS);
    avel = vector_to_world(avel_rel);
    dBodySetAngularVel(body, avel.x, avel.y, avel.z);
  }
  
  if (_attached_this_frame) {
    _attached_this_frame = false;
    dGeomEnable(get_entity().get_geom("sticky_attach"));
  } else {
    dGeomDisable(get_entity().get_geom("sticky_attach"));
  }
}