public ODERayCastRequestManager(ODEPhysicsScene pScene) { m_scene = pScene; nearCallback = NearSpace; ContactgeomsArray = Marshal.AllocHGlobal(contactsPerCollision * d.ContactGeom.unmanagedSizeOf); }
public PhysicsScene GetScene() { lock (m_lock) { if (_mScene == null) { if (!m_initialized) //Only initialize ode once! { // Initializing ODE only when a scene is created allows alternative ODE plugins to co-habit (according to // http://opensimulator.org/mantis/view.php?id=2750). d.InitODE (); m_initialized = true; } _mScene = new ODEPhysicsScene (); } return _mScene; } }
public ODESpecificAvatar(String avName, ODEPhysicsScene parent_scene, Vector3 pos, Quaternion rotation, Vector3 size) : base(avName, parent_scene, pos, rotation, size) { _parent_ref = this; }
public ODECharacter(String avName, ODEPhysicsScene parent_scene, Vector3 pos, Quaternion rotation, Vector3 size) { m_uuid = UUID.Random(); _parent_scene = parent_scene; m_taintRotation = rotation; if (pos.IsFinite()) { if (pos.Z > 9999999f || pos.Z < -90f) { pos.Z = _parent_scene.GetTerrainHeightAtXY(_parent_scene.Region.RegionSizeX*0.5f, _parent_scene.Region.RegionSizeY*0.5f) + 5.0f; } _position = pos; } else { _position.X = _parent_scene.Region.RegionSizeX*0.5f; _position.Y = _parent_scene.Region.RegionSizeY*0.5f; _position.Z = _parent_scene.GetTerrainHeightAtXY(_position.X, _position.Y) + 10f; MainConsole.Instance.Warn("[ODE Physics]: Got NaN Position on Character Create"); } m_isPhysical = false; // current status: no ODE information exists Size = size; Name = avName; }
public ODEPrim(string name, byte physicsType, PrimitiveBaseShape shape, Vector3 position, Vector3 size, Quaternion rotation, int material, float friction, float restitution, float gravityMultiplier, float density, ODEPhysicsScene parent_scene) { m_vehicle = new ODEDynamics(); // correct for changed timestep PID_D /= (parent_scene.ODE_STEPSIZE*50f); // original ode fps of 50 PID_G /= (parent_scene.ODE_STEPSIZE*50f); body_autodisable_frames = parent_scene.bodyFramesAutoDisable; prim_geom = IntPtr.Zero; _name = name; PhysicsShapeType = physicsType; _size = size; _position = position; fakepos = 0; _orientation = rotation; fakeori = 0; _pbs = shape; _parent_scene = parent_scene; m_targetSpace = IntPtr.Zero; /* m_isphysical = pisPhysical; if (m_isphysical) m_targetSpace = _parent_scene.space; */ m_isphysical = false; m_forceacc = Vector3.Zero; m_angularforceacc = Vector3.Zero; hasOOBoffsetFromMesh = false; _triMeshData = IntPtr.Zero; SetMaterial(material, friction, restitution, gravityMultiplier, density); CalcPrimBodyData(); _parent_scene.AddSimulationChange(() => ChangeAdd()); }
void MoveAngular(float pTimestep, ODEPhysicsScene _pParentScene, ODEPrim parent) { bool ishovering = false; d.Vector3 d_angularVelocity = d.BodyGetAngularVel(Body); d.Vector3 d_lin_vel_now = d.BodyGetLinearVel(Body); d.Quaternion drotq = d.BodyGetQuaternion(Body); Quaternion rotq = new Quaternion(drotq.X, drotq.Y, drotq.Z, drotq.W); rotq *= m_referenceFrame; //add reference rotation to rotq Quaternion irotq = new Quaternion(-rotq.X, -rotq.Y, -rotq.Z, rotq.W); Vector3 angularVelocity = new Vector3(d_angularVelocity.X, d_angularVelocity.Y, d_angularVelocity.Z); Vector3 linearVelocity = new Vector3(d_lin_vel_now.X, d_lin_vel_now.Y, d_lin_vel_now.Z); Vector3 friction = Vector3.Zero; Vector3 vertattr = Vector3.Zero; Vector3 deflection = Vector3.Zero; Vector3 banking = Vector3.Zero; //limit maximum rotation speed if(angularVelocity.LengthSquared() > 1e3f) { angularVelocity = Vector3.Zero; d.BodySetAngularVel(Body, angularVelocity.X, angularVelocity.Y, angularVelocity.Z); } angularVelocity *= irotq; //world to body orientation if(m_VhoverTimescale * pTimestep <= 300.0f && m_VhoverHeight > 0.0f) ishovering = true; #region Angular motor Vector3 motorDirection = Vector3.Zero; if(Type == Vehicle.TYPE_BOAT) { //keep z flat for boats, no sidediving lol Vector3 tmp = new Vector3(0.0f, 0.0f, m_angularMotorDirection.Z); m_angularMotorDirection.Z = 0.0f; m_angularMotorDirection += tmp * irotq; } if(parent.LinkSetIsColliding || Type == Vehicle.TYPE_AIRPLANE || Type == Vehicle.TYPE_BALLOON || ishovering){ motorDirection = m_angularMotorDirection * 0.34f; //0.3f; } m_angularMotorVelocity.X = (motorDirection.X - angularVelocity.X) / m_angularMotorTimescale; m_angularMotorVelocity.Y = (motorDirection.Y - angularVelocity.Y) / m_angularMotorTimescale; m_angularMotorVelocity.Z = (motorDirection.Z - angularVelocity.Z) / m_angularMotorTimescale; m_angularMotorDirection *= (1.0f - 1.0f/m_angularMotorDecayTimescale); if(m_angularMotorDirection.LengthSquared() > 0.0f) { if(angularVelocity.X > m_angularMotorDirection.X && m_angularMotorDirection.X >= 0.0f) m_angularMotorVelocity.X = 0.0f; if(angularVelocity.Y > m_angularMotorDirection.Y && m_angularMotorDirection.Y >= 0.0f) m_angularMotorVelocity.Y = 0.0f; if(angularVelocity.Z > m_angularMotorDirection.Z && m_angularMotorDirection.Z >= 0.0f) m_angularMotorVelocity.Z = 0.0f; if(angularVelocity.X < m_angularMotorDirection.X && m_angularMotorDirection.X <= 0.0f) m_angularMotorVelocity.X = 0.0f; if(angularVelocity.Y < m_angularMotorDirection.Y && m_angularMotorDirection.Y <= 0.0f) m_angularMotorVelocity.Y = 0.0f; if(angularVelocity.Z < m_angularMotorDirection.Z && m_angularMotorDirection.Z <= 0.0f) m_angularMotorVelocity.Z = 0.0f; } #endregion #region friction float initialFriction = 0.0001f; if(angularVelocity.X > initialFriction) friction.X += initialFriction; if(angularVelocity.Y > initialFriction) friction.Y += initialFriction; if(angularVelocity.Z > initialFriction) friction.Z += initialFriction; if(angularVelocity.X < -initialFriction) friction.X -= initialFriction; if(angularVelocity.Y < -initialFriction) friction.Y -= initialFriction; if(angularVelocity.Z < -initialFriction) friction.Z -= initialFriction; if(angularVelocity.X > 0.0f) friction.X += angularVelocity.X * angularVelocity.X / m_angularFrictionTimescale.X; else friction.X -= angularVelocity.X * angularVelocity.X / m_angularFrictionTimescale.X; if(angularVelocity.Y > 0.0f) friction.Y += angularVelocity.Y * angularVelocity.Y / m_angularFrictionTimescale.Y; else friction.Y -= angularVelocity.Y * angularVelocity.Y / m_angularFrictionTimescale.Y; if(angularVelocity.Z > 0.0f) friction.Z += angularVelocity.Z * angularVelocity.Z / m_angularFrictionTimescale.Z; else friction.Z -= angularVelocity.Z * angularVelocity.Z / m_angularFrictionTimescale.Z; if(Math.Abs(m_angularMotorDirection.X) > 0.01f) friction.X = 0.0f; if(Math.Abs(m_angularMotorDirection.Y) > 0.01f) friction.Y = 0.0f; if(Math.Abs(m_angularMotorDirection.Z) > 0.01f) friction.Z = 0.0f; #endregion #region Vertical attraction if(m_verticalAttractionTimescale < 300) { float VAservo = 38.0f / m_verticalAttractionTimescale; if(Type == Vehicle.TYPE_CAR) VAservo = 10.0f / m_verticalAttractionTimescale; Vector3 verterr = new Vector3(0.0f, 0.0f, 1.0f); verterr *= rotq; vertattr.X = verterr.Y; vertattr.Y = -verterr.X; vertattr.Z = 0.0f; vertattr *= irotq; //when upsidedown prefer x rotation of body, to keep forward movement direction the same if(verterr.Z < 0.0f) { vertattr.Y = -vertattr.Y * 2.0f; if(vertattr.X < 0.0f) vertattr.X = -2.0f - vertattr.X; else vertattr.X = 2.0f - vertattr.X; } vertattr *= VAservo; vertattr.X += (vertattr.X - angularVelocity.X) * (0.004f * m_verticalAttractionEfficiency + 0.0001f); vertattr.Y += (vertattr.Y - angularVelocity.Y) * (0.004f * m_verticalAttractionEfficiency + 0.0001f); if((m_flags & (VehicleFlag.LIMIT_ROLL_ONLY)) != 0) vertattr.Y = 0.0f; } #endregion #region deflection //rotates body to direction of movement (linearMovement vector) // temporary disabled due to instabilities, needs to be rewritten if(m_angularDeflectionTimescale < 300) { float Dservo = 0.05f * m_angularDeflectionTimescale * m_angularDeflectionEfficiency; float mag = linearVelocity.LengthSquared(); if(mag > 0.01f) { linearVelocity.Y = -linearVelocity.Y; linearVelocity *= rotq; mag = (float)Math.Sqrt(mag); linearVelocity.Y /= mag; linearVelocity.Z /= mag; deflection.Y = -linearVelocity.Z; deflection.Z = -linearVelocity.Y; deflection *= Dservo; } } // #endregion #region banking if(m_verticalAttractionTimescale < 300 && m_bankingEfficiency > 0) { //vertical attraction must be enabled float mag = (linearVelocity.X * linearVelocity.X + linearVelocity.Y * linearVelocity.Y); if(mag > 0.01f) { mag = (float)Math.Sqrt(mag); if(mag > 20.0f) mag = 1.0f; else mag /= 20.0f; } else mag = 0.0f; float b_static = -m_angularMotorDirection.X * 0.12f * (1.0f - m_bankingMix); float b_dynamic = -m_angularMotorDirection.X * 0.12f * mag * m_bankingMix; banking.Z = (b_static + b_dynamic - d_angularVelocity.Z) / m_bankingTimescale * m_bankingEfficiency; } #endregion m_lastAngularVelocity = angularVelocity; if(parent.LinkSetIsColliding || Type == Vehicle.TYPE_AIRPLANE || Type == Vehicle.TYPE_BALLOON || ishovering) { angularVelocity += deflection; angularVelocity -= friction; } else { banking = Vector3.Zero; } angularVelocity += m_angularMotorVelocity; angularVelocity += vertattr; angularVelocity *= rotq; angularVelocity += banking; if(angularVelocity.LengthSquared() < 1e-5f) { d.BodySetAngularVel(Body, 0, 0, 0); m_angularZeroFlag = true; } else { d.BodySetAngularVel(Body, angularVelocity.X, angularVelocity.Y, angularVelocity.Z); m_angularZeroFlag = false; } }
// end Step void MoveLinear(float pTimestep, ODEPhysicsScene _pParentScene, ODEPrim parent) { bool ishovering = false; bool bypass_buoyancy = false; d.Vector3 dpos = d.BodyGetPosition(Body); d.Vector3 dvel_now = d.BodyGetLinearVel(Body); d.Quaternion drotq_now = d.BodyGetQuaternion(Body); Vector3 pos = new Vector3(dpos.X, dpos.Y, dpos.Z); Vector3 vel_now = new Vector3(dvel_now.X, dvel_now.Y, dvel_now.Z); Quaternion rotq = new Quaternion(drotq_now.X, drotq_now.Y, drotq_now.Z, drotq_now.W); rotq *= m_referenceFrame; //add reference rotation to rotq Quaternion irotq = new Quaternion(-rotq.X, -rotq.Y, -rotq.Z, rotq.W); m_newVelocity = Vector3.Zero; if (!(m_lastPositionVector.X == 0 && m_lastPositionVector.Y == 0 && m_lastPositionVector.Z == 0)) { ///Only do this if we have a last position m_lastposChange.X = pos.X - m_lastPositionVector.X; m_lastposChange.Y = pos.Y - m_lastPositionVector.Y; m_lastposChange.Z = pos.Z - m_lastPositionVector.Z; } #region Blocking Change if (m_BlockingEndPoint != Vector3.Zero) { bool needUpdateBody = false; if(pos.X >= (m_BlockingEndPoint.X - 1)) { pos.X -= m_lastposChange.X + 1; needUpdateBody = true; } if(pos.Y >= (m_BlockingEndPoint.Y - 1)) { pos.Y -= m_lastposChange.Y + 1; needUpdateBody = true; } if(pos.Z >= (m_BlockingEndPoint.Z - 1)) { pos.Z -= m_lastposChange.Z + 1; needUpdateBody = true; } if(pos.X <= 0) { pos.X += m_lastposChange.X + 1; needUpdateBody = true; } if(pos.Y <= 0) { pos.Y += m_lastposChange.Y + 1; needUpdateBody = true; } if(needUpdateBody) d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } #endregion #region Terrain checks float terrainHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); if(pos.Z < terrainHeight - 5) { pos.Z = terrainHeight + 2; m_lastPositionVector = pos; d.BodySetPosition(Body, pos.X, pos.Y, pos.Z); } else if(pos.Z < terrainHeight) { m_newVelocity.Z += 1; } #endregion #region Hover Vector3 hovervel = Vector3.Zero; if(m_VhoverTimescale * pTimestep <= 300.0f && m_VhoverHeight > 0.0f) { ishovering = true; if ((m_flags & VehicleFlag.HOVER_WATER_ONLY) != 0) { m_VhoverTargetHeight = (float) _pParentScene.GetWaterLevel(pos.X, pos.Y) + 0.3f + m_VhoverHeight; } else if ((m_flags & VehicleFlag.HOVER_TERRAIN_ONLY) != 0) { m_VhoverTargetHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y) + m_VhoverHeight; } else if ((m_flags & VehicleFlag.HOVER_GLOBAL_HEIGHT) != 0) { m_VhoverTargetHeight = m_VhoverHeight; } else { float waterlevel = (float)_pParentScene.GetWaterLevel(pos.X, pos.Y) + 0.3f; float terrainlevel = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); if(waterlevel > terrainlevel) { m_VhoverTargetHeight = waterlevel + m_VhoverHeight; } else { m_VhoverTargetHeight = terrainlevel + m_VhoverHeight; } } float tempHoverHeight = m_VhoverTargetHeight; if((m_flags & VehicleFlag.HOVER_UP_ONLY) != 0) { // If body is aready heigher, use its height as target height if (pos.Z > tempHoverHeight) { tempHoverHeight = pos.Z; bypass_buoyancy = true; //emulate sl bug } } if((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) { if((pos.Z - tempHoverHeight) > .2 || (pos.Z - tempHoverHeight) < -.2) { float h = tempHoverHeight; float groundHeight = _pParentScene.GetTerrainHeightAtXY(pos.X, pos.Y); if(groundHeight >= tempHoverHeight) h = groundHeight; d.BodySetPosition(Body, pos.X, pos.Y, h); } } else { hovervel.Z -= ((dvel_now.Z * 0.1f * m_VhoverEfficiency) + (pos.Z - tempHoverHeight)) / m_VhoverTimescale; hovervel.Z *= 7.0f * (1.0f + m_VhoverEfficiency); if(hovervel.Z > 50.0f) hovervel.Z = 50.0f; if(hovervel.Z < -50.0f) hovervel.Z = -50.0f; } } #endregion #region limitations //limit maximum velocity if(vel_now.LengthSquared() > 1e6f) { vel_now /= vel_now.Length(); vel_now *= 1000f; d.BodySetLinearVel(Body, vel_now.X, vel_now.Y, vel_now.Z); } //block movement in x and y when low velocity bool enable_ode_gravity = true; if(vel_now.LengthSquared() < 0.02f) { d.BodySetLinearVel(Body, 0.0f, 0.0f, 0.0f); vel_now = Vector3.Zero; if(parent.LinkSetIsColliding) enable_ode_gravity = false; } #endregion #region Linear motors //cancel directions of linear friction for certain vehicles without having effect on ode gravity Vector3 vt_vel_now = vel_now; bool no_grav_calc = false; if((Type != Vehicle.TYPE_AIRPLANE && Type != Vehicle.TYPE_BALLOON) && m_VehicleBuoyancy != 1.0f) { vt_vel_now.Z = 0.0f; no_grav_calc = true; } if(!bypass_buoyancy) { //apply additional gravity force over ode gravity if(m_VehicleBuoyancy == 1.0f) enable_ode_gravity = false; else if(m_VehicleBuoyancy != 0.0f && enable_ode_gravity) { float grav = _pParentScene.gravityz * parent.GravityMultiplier * -m_VehicleBuoyancy; m_newVelocity.Z += grav * Mass; } } //set ode gravity d.BodySetGravityMode(Body, enable_ode_gravity); //add default linear friction (mimic sl friction as much as possible) float initialFriction = 0.055f; float defaultFriction = 180f; Vector3 friction = Vector3.Zero; if(parent.LinkSetIsColliding || ishovering) { if(vt_vel_now.X > 0.0f) friction.X += initialFriction; if(vt_vel_now.Y > 0.0f) friction.Y += initialFriction; if(vt_vel_now.Z > 0.0f) friction.Z += initialFriction; if(vt_vel_now.X < 0.0f) friction.X -= initialFriction; if(vt_vel_now.Y < 0.0f) friction.Y -= initialFriction; if(vt_vel_now.Z < 0.0f) friction.Z -= initialFriction; friction += vt_vel_now / defaultFriction; friction *= irotq; } //world -> body orientation vel_now *= irotq; vt_vel_now *= irotq; //add linear friction if(vt_vel_now.X > 0.0f) friction.X += vt_vel_now.X * vt_vel_now.X / m_linearFrictionTimescale.X; else friction.X -= vt_vel_now.X * vt_vel_now.X / m_linearFrictionTimescale.X; if(vt_vel_now.Y > 0.0f) friction.Y += vt_vel_now.Y * vt_vel_now.Y / m_linearFrictionTimescale.Y; else friction.Y -= vt_vel_now.Y * vt_vel_now.Y / m_linearFrictionTimescale.Y; if(vt_vel_now.Z > 0.0f) friction.Z += vt_vel_now.Z * vt_vel_now.Z / m_linearFrictionTimescale.Z; else friction.Z -= vt_vel_now.Z * vt_vel_now.Z / m_linearFrictionTimescale.Z; friction /= 1.35f; //1.5f; //add linear forces //not the best solution, but it is really close to sl motor velocity, and just works Vector3 motorVelocity = (m_linearMotorDirection * 3.0f - vel_now) / m_linearMotorTimescale / 5.0f; //2.8f; Vector3 motorfrictionamp = new Vector3(4.0f, 4.0f, 4.0f); Vector3 motorfrictionstart = new Vector3(1.0f, 1.0f, 1.0f); motorVelocity *= motorfrictionstart + motorfrictionamp / (m_linearFrictionTimescale * pTimestep); float addVel = 0.15f; if(motorVelocity.LengthSquared() > 0.01f) { if(motorVelocity.X > 0.0f) motorVelocity.X += addVel; if(motorVelocity.Y > 0.0f) motorVelocity.Y += addVel; if(motorVelocity.Z > 0.0f) motorVelocity.Z += addVel; if(motorVelocity.X < 0.0f) motorVelocity.X -= addVel; if(motorVelocity.Y < 0.0f) motorVelocity.Y -= addVel; if(motorVelocity.Z < 0.0f) motorVelocity.Z -= addVel; } //free run if(vel_now.X > m_linearMotorDirection.X && m_linearMotorDirection.X >= 0.0f) motorVelocity.X = 0.0f; if(vel_now.Y > m_linearMotorDirection.Y && m_linearMotorDirection.Y >= 0.0f) motorVelocity.Y = 0.0f; if(vel_now.Z > m_linearMotorDirection.Z && m_linearMotorDirection.Z >= 0.0f) motorVelocity.Z = 0.0f; if(vel_now.X < m_linearMotorDirection.X && m_linearMotorDirection.X <= 0.0f) motorVelocity.X = 0.0f; if(vel_now.Y < m_linearMotorDirection.Y && m_linearMotorDirection.Y <= 0.0f) motorVelocity.Y = 0.0f; if(vel_now.Z < m_linearMotorDirection.Z && m_linearMotorDirection.Z <= 0.0f) motorVelocity.Z = 0.0f; //decay linear motor m_linearMotorDirection *= (1.0f - 1.0f/m_linearMotorDecayTimescale); #endregion #region Deflection //does only deflect on x axis from world orientation with z axis rotated to body //it is easier to filter out gravity deflection for vehicles(car) without rotation problems Quaternion irotq_z = irotq; irotq_z.X = 0.0f; irotq_z.Y = 0.0f; float mag = (float)Math.Sqrt(irotq_z.W * irotq_z.W + irotq_z.Z * irotq_z.Z); //normalize irotq_z.W /= mag; irotq_z.Z /= mag; Vector3 vel_defl = new Vector3(dvel_now.X, dvel_now.Y, dvel_now.Z); vel_defl *= irotq_z; if(no_grav_calc) { vel_defl.Z = 0.0f; if(!parent.LinkSetIsColliding) vel_defl.Y = 0.0f; } Vector3 deflection = vel_defl / m_linearDeflectionTimescale * m_linearDeflectionEfficiency * 100.0f; float deflectionLengthY = Math.Abs(deflection.Y); float deflectionLengthX = Math.Abs(deflection.X); deflection.Z = 0.0f; if((m_flags & (VehicleFlag.NO_DEFLECTION_UP)) == 0) { deflection.Z = deflectionLengthX; deflection.X = -deflection.X; } if(vel_defl.X < 0.0f) deflection.X = -deflectionLengthY; else if(vel_defl.X >= 0.0f) deflection.X = deflectionLengthY; deflection.Y = -deflection.Y; irotq_z.W = -irotq_z.W; deflection *= irotq_z; #endregion #region Deal with tainted forces Vector3 TaintedForce = new Vector3(); if(m_forcelist.Count != 0) { try { TaintedForce = m_forcelist.Aggregate(TaintedForce, (current, t) => current + (t)); } catch(IndexOutOfRangeException) { TaintedForce = Vector3.Zero; } catch(ArgumentOutOfRangeException) { TaintedForce = Vector3.Zero; } m_forcelist = new List<Vector3>(); } #endregion #region Add Forces //add forces m_newVelocity -= (friction *= Mass / pTimestep); m_newVelocity += TaintedForce; motorVelocity *= Mass / pTimestep; #endregion #region No X,Y,Z if((m_flags & (VehicleFlag.NO_X)) != 0) m_newVelocity.X = -vel_now.X * Mass / pTimestep; if((m_flags & (VehicleFlag.NO_Y)) != 0) m_newVelocity.Y = -vel_now.Y * Mass / pTimestep; if((m_flags & (VehicleFlag.NO_Z)) != 0) m_newVelocity.Z = -vel_now.Z * Mass / pTimestep; #endregion m_newVelocity *= rotq; m_newVelocity += (hovervel *= Mass / pTimestep); if(parent.LinkSetIsColliding || Type == Vehicle.TYPE_AIRPLANE || Type == Vehicle.TYPE_BALLOON || ishovering) { m_newVelocity += deflection; motorVelocity *= rotq; if((m_flags & (VehicleFlag.LIMIT_MOTOR_UP)) != 0 && motorVelocity.Z > 0.0f) motorVelocity.Z = 0.0f; m_newVelocity += motorVelocity; } d.BodyAddForce(Body, m_newVelocity.X, m_newVelocity.Y, m_newVelocity.Z); }
internal void Step(IntPtr pBody, float pTimestep, ODEPhysicsScene pParentScene, ODEPrim parent) { m_body = pBody; if (pBody == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) return; if (Mass == 0) GetMass(pBody); if (Mass == 0) return; //No noMass vehicles... if (!d.BodyIsEnabled(Body)) d.BodyEnable(Body); frcount++; // used to limit debug comment output if (frcount > 100) frcount = 0; // scale time so parameters work as before // until we scale then acording to ode step time MoveLinear(pTimestep, pParentScene, parent); MoveAngular(pTimestep, pParentScene, parent); LimitRotation(pTimestep); }
internal void Enable(IntPtr pBody, ODEPrim parent, ODEPhysicsScene pParentScene) { if (m_enabled) return; if (pBody == IntPtr.Zero || m_type == Vehicle.TYPE_NONE) return; m_body = pBody; d.BodySetGravityMode(Body, true); m_enabled = true; m_lastLinearVelocityVector = parent.Velocity; m_lastPositionVector = parent.Position; m_lastAngularVelocity = parent.RotationalVelocity; parent.ThrottleUpdates = false; GetMass(pBody); }
/// <summary> /// Dereference the creator scene so that it can be garbage collected if needed. /// </summary> internal void Dispose() { m_scene = null; if (ContactgeomsArray != IntPtr.Zero) Marshal.FreeHGlobal(ContactgeomsArray); }