private void ConstructClone(Body body, Geom geometry, Vector2 offset, float rotationOffset) { _id = GetNextId(); _collisonGridCellSize = geometry._collisonGridCellSize; grid = geometry.grid.Clone(); restitutionCoefficient = geometry.restitutionCoefficient; frictionCoefficient = geometry.frictionCoefficient; collisionGroup = geometry.collisionGroup; collisionEnabled = geometry.collisionEnabled; collsionResponseEnabled = geometry.collsionResponseEnabled; _collisonGridCellSize = geometry._collisonGridCellSize; _offset = offset; _rotationOffset = rotationOffset; collisionCategories = geometry.collisionCategories; collidesWith = geometry.collidesWith; SetVertices(geometry.localVertices); SetBody(body); }
public void changefloatonwater(float timestep) { m_collidesWater = m_taintCollidesWater; if (prim_geom != IntPtr.Zero) { if (m_collidesWater) { m_collisionFlags |= CollisionCategories.Water; } else { m_collisionFlags &= ~CollisionCategories.Water; } d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } }
/// <summary> /// Add a child prim to this parent prim. /// </summary> /// <param name="prim">Child prim</param> public void AddChildPrim(OdePrim prim) { //Console.WriteLine("AddChildPrim " + Name); if (this.m_localID != prim.m_localID) { if (Body == IntPtr.Zero) { Body = d.BodyCreate(_parent_scene.world); setMass(); } if (Body != IntPtr.Zero) { lock (childrenPrim) { if (!childrenPrim.Contains(prim)) { //Console.WriteLine("childrenPrim.Add " + prim); childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) { d.Mass m2; d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prim.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); d.MassRotate(ref m2, ref mat); d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); d.MassAdd(ref pMass, ref m2); } foreach (OdePrim prm in childrenPrim) { prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); if (prm.prim_geom == IntPtr.Zero) { m_log.WarnFormat( "[PHYSICS]: Unable to link one of the linkset elements {0} for parent {1}. No geom yet", prm.Name, prim.Name); continue; } //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)prm.m_collisionFlags); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); if (Body != IntPtr.Zero) { d.GeomSetBody(prm.prim_geom, Body); prm.childPrim = true; d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); } else { m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); } prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { prm.createAMotor(m_angularlock); } prm.Body = Body; _parent_scene.addActivePrim(prm); } m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; quat2.Y = _orientation.Y; quat2.Z = _orientation.Z; d.Matrix3 mat2 = new d.Matrix3(); d.RfromQ(out mat2, ref quat2); d.GeomSetBody(prim_geom, Body); d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); //d.GeomSetOffsetRotation(prim_geom, ref mat2); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0f)) && _parent == null) { createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); _parent_scene.addActivePrim(this); } } } } }
// for now removes all colisions etc from childs, full body reconstruction is needed after this public void DestroyBody() { //this kills the body so things like 'mesh' can re-create it. lock (this) { if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int) m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int) m_collisionFlags); UpdateDataFromGeom(); SetInStaticSpace(this); } if (!childPrim) { lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { _parent_scene.remActivePrim(prm); prm.m_collisionCategories &= ~CollisionCategories.Body; prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prm.prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prm.prim_geom, (int) m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int) m_collisionFlags); prm.UpdateDataFromGeom(); prm.Body = IntPtr.Zero; SetInStaticSpace(prm); } prm._mass = prm.primMass; } } m_vehicle.Disable(this); d.BodyDestroy(Body); } } Body = IntPtr.Zero; } _mass = primMass; m_disabled = true; }
/// <summary> /// Change prim in response to a float on water taint. /// </summary> /// <param name="timestep"></param> private void changefloatonwater() { m_collidesWater = m_taintCollidesWater; if (m_collidesWater) { m_collisionFlags |= CollisionCategories.Water; } else { m_collisionFlags &= ~CollisionCategories.Water; } if (m_assetFailed) d.GeomSetCollideBits(prim_geom, BadMeshAssetCollideBits); else d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); }
void MakeBody() { // d.Vector3 dvtmp; // d.Vector3 dbtmp; if (m_blockPhysicalReconstruction) // building is blocked return; if (childPrim) // child prims don't get own bodies; return; if (prim_geom == IntPtr.Zero) { MainConsole.Instance.Warn("[ODE Physics]: Unable to link the linkset. Root has no geom yet"); return; } if (!m_isphysical) // only physical things get a body return; if (Body != IntPtr.Zero) // who shouldn't have one already ? { d.BodyDestroy(Body); Body = IntPtr.Zero; MainConsole.Instance.Warn("[ODE Physics]: MakeBody called having a body"); } d.Mass objdmass = new d.Mass {}; d.Matrix3 mymat = new d.Matrix3(); d.Quaternion myrot = new d.Quaternion(); // fiddle for incompatible typecasting var actorType = (int)ActorTypes.Prim; var ptrActorType = (IntPtr)actorType; Body = d.BodyCreate(_parent_scene.world); d.BodySetData(Body, ptrActorType); DMassDup(ref primdMass, out objdmass); // rotate inertia myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.RfromQ(out mymat, ref myrot); d.MassRotate(ref objdmass, ref mymat); // set the body rotation and position d.BodySetRotation(Body, ref mymat); // recompute full object inertia if needed if (childrenPrim.Count > 0) { d.Matrix3 mat = new d.Matrix3(); d.Quaternion quat = new d.Quaternion(); d.Mass tmpdmass = new d.Mass {}; Vector3 rcm; rcm.X = _position.X + objdmass.c.X; rcm.Y = _position.Y + objdmass.c.Y; rcm.Z = _position.Z + objdmass.c.Z; lock (childrenPrim) { foreach (ODEPrim prm in childrenPrim) { if (prm.prim_geom == IntPtr.Zero) { MainConsole.Instance.Warn( "[ODE Physics]: Unable to link one of the linkset elements, skipping it. No geom yet"); continue; } DMassCopy(ref prm.primdMass, ref tmpdmass); // apply prim current rotation to inertia quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.RfromQ(out mat, ref quat); d.MassRotate(ref tmpdmass, ref mat); Vector3 ppos = prm._position; ppos.X += tmpdmass.c.X - rcm.X; ppos.Y += tmpdmass.c.Y - rcm.Y; ppos.Z += tmpdmass.c.Z - rcm.Z; // refer inertia to root prim center of mass position d.MassTranslate(ref tmpdmass, ppos.X, ppos.Y, ppos.Z); d.MassAdd(ref objdmass, ref tmpdmass); // add to total object inertia // fix prim colision cats d.GeomClearOffset(prm.prim_geom); d.GeomSetBody(prm.prim_geom, Body); prm.Body = Body; d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); // set relative rotation } } } d.GeomClearOffset(prim_geom); // make sure we don't have a hidden offset // associate root geom with body d.GeomSetBody(prim_geom, Body); d.BodySetPosition(Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); d.GeomSetOffsetWorldPosition(prim_geom, _position.X, _position.Y, _position.Z); d.MassTranslate(ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body myrot.W = -myrot.W; d.RfromQ(out mymat, ref myrot); d.MassRotate(ref objdmass, ref mymat); d.BodySetMass(Body, ref objdmass); _mass = objdmass.mass; m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); // disconnect from world gravity so we can apply buoyancy // if (!testRealGravity) d.BodySetGravityMode(Body, false); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); d.BodySetDamping(Body, .001f, .0002f); m_disabled = false; d.GeomSetCategoryBits(prim_geom, (int) m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int) m_collisionFlags); if (m_targetSpace != _parent_scene.space) { if (d.SpaceQuery(m_targetSpace, prim_geom)) d.SpaceRemove(m_targetSpace, prim_geom); m_targetSpace = _parent_scene.space; d.SpaceAdd(m_targetSpace, prim_geom); } lock (childrenPrim) { foreach (ODEPrim prm in childrenPrim) { if (prm.prim_geom == IntPtr.Zero) continue; Vector3 ppos = prm._position; d.GeomSetOffsetWorldPosition(prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); d.GeomSetCategoryBits(prm.prim_geom, (int) prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int) prm.m_collisionFlags); if (prm.m_targetSpace != _parent_scene.space) { if (d.SpaceQuery(prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove(prm.m_targetSpace, prm.prim_geom); prm.m_targetSpace = _parent_scene.space; d.SpaceAdd(m_targetSpace, prm.prim_geom); } prm.m_disabled = false; _parent_scene.AddActivePrim(prm); } } // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.One, 0.0f)) && _parent == null) { CreateAMotor(m_angularlock); } if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, this, _parent_scene); _parent_scene.AddActivePrim(this); }
public void MakeBody () { // d.Vector3 dvtmp; // d.Vector3 dbtmp; d.Mass tmpdmass = new d.Mass { }; d.Mass objdmass = new d.Mass { }; d.Matrix3 mat = new d.Matrix3 (); d.Matrix3 mymat = new d.Matrix3 (); d.Quaternion quat = new d.Quaternion (); d.Quaternion myrot = new d.Quaternion (); Vector3 rcm; if (childPrim) // child prims don't get own bodies; return; if (Body != IntPtr.Zero) // who shouldn't have one already ? { d.BodyDestroy (Body); Body = IntPtr.Zero; } if (!m_isphysical) // only physical things get a body return; Body = d.BodyCreate (_parent_scene.world); calcdMass (); // compute inertia on local frame DMassDup (ref primdMass, out objdmass); // rotate inertia myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.RfromQ (out mymat, ref myrot); d.MassRotate (ref objdmass, ref mymat); // set the body rotation and position d.BodySetRotation (Body, ref mymat); // recompute full object inertia if needed if (childrenPrim.Count > 0) { rcm.X = _position.X + objdmass.c.X; rcm.Y = _position.Y + objdmass.c.Y; rcm.Z = _position.Z + objdmass.c.Z; lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { prm.calcdMass (); // recompute inertia on local frame DMassCopy (ref prm.primdMass, ref tmpdmass); // apply prim current rotation to inertia quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.RfromQ (out mat, ref quat); d.MassRotate (ref tmpdmass, ref mat); Vector3 ppos = prm._position; ppos.X += tmpdmass.c.X - rcm.X; ppos.Y += tmpdmass.c.Y - rcm.Y; ppos.Z += tmpdmass.c.Z - rcm.Z; // refer inertia to root prim center of mass position d.MassTranslate (ref tmpdmass, ppos.X, ppos.Y, ppos.Z); d.MassAdd (ref objdmass, ref tmpdmass); // add to total object inertia // fix prim colision cats if (prm.prim_geom == IntPtr.Zero) { m_log.Warn ("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); continue; } d.GeomClearOffset (prm.prim_geom); d.GeomSetBody (prm.prim_geom, Body); d.GeomSetOffsetWorldRotation (prm.prim_geom, ref mat); // set relative rotation } } } d.GeomClearOffset (prim_geom); // make sure we don't have a hidden offset // associate root geom with body d.GeomSetBody (prim_geom, Body); d.BodySetPosition (Body, _position.X + objdmass.c.X, _position.Y + objdmass.c.Y, _position.Z + objdmass.c.Z); d.GeomSetOffsetWorldPosition (prim_geom, _position.X, _position.Y, _position.Z); d.MassTranslate (ref objdmass, -objdmass.c.X, -objdmass.c.Y, -objdmass.c.Z); // ode wants inertia at center of body myrot.W = -myrot.W; d.RfromQ (out mymat, ref myrot); d.MassRotate (ref objdmass, ref mymat); d.BodySetMass (Body, ref objdmass); _mass = objdmass.mass; m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); // disconnect from world gravity so we can apply buoyancy if (!testRealGravity) d.BodySetGravityMode (Body, false); d.BodySetAutoDisableFlag (Body, true); d.BodySetAutoDisableSteps (Body, body_autodisable_frames); // d.BodySetLinearDampingThreshold(Body, 0.01f); // d.BodySetAngularDampingThreshold(Body, 0.001f); d.BodySetDamping (Body, .001f, .001f); m_disabled = false; d.GeomSetCategoryBits (prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits (prim_geom, (int)m_collisionFlags); m_interpenetrationcount = 0; m_collisionscore = 0; if (m_targetSpace != _parent_scene.space) { _parent_scene.waitForSpaceUnlock (m_targetSpace); if (d.SpaceQuery (m_targetSpace, prim_geom)) d.SpaceRemove (m_targetSpace, prim_geom); m_targetSpace = _parent_scene.space; d.SpaceAdd (m_targetSpace, prim_geom); } lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { if (prm.prim_geom == IntPtr.Zero) { m_log.Warn ("[PHYSICS]: Unable to link one of the linkset elements. No geom yet"); continue; } Vector3 ppos = prm._position; d.GeomSetOffsetWorldPosition (prm.prim_geom, ppos.X, ppos.Y, ppos.Z); // set relative position prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); d.GeomSetCategoryBits (prm.prim_geom, (int)prm.m_collisionCategories); d.GeomSetCollideBits (prm.prim_geom, (int)prm.m_collisionFlags); prm.Body = Body; prm.m_disabled = false; prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; _parent_scene.addActivePrim (prm); if (prm.m_targetSpace != _parent_scene.space) { _parent_scene.waitForSpaceUnlock (m_targetSpace); if (d.SpaceQuery (prm.m_targetSpace, prm.prim_geom)) d.SpaceRemove (prm.m_targetSpace, prm.prim_geom); prm.m_targetSpace = _parent_scene.space; d.SpaceAdd (m_targetSpace, prm.prim_geom); } } } // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals (Vector3.One, 0.0f)) && _parent == null) { createAMotor (m_angularlock); } if (m_vehicle.Type != Vehicle.TYPE_NONE) { m_vehicle.Enable (Body, this, _parent_scene); } _parent_scene.addActivePrim (this); /* d.Mass mtmp; d.BodyGetMass(Body, out mtmp); d.Matrix3 mt = d.GeomGetRotation(prim_geom); d.Matrix3 mt2 = d.BodyGetRotation(Body); dvtmp = d.GeomGetPosition(prim_geom); dbtmp = d.BodyGetPosition(Body); */ }
private void changeSelectedStatus(bool newsel) { bool isphys = IsPhysical; if (newsel) { m_collisionCategories = CollisionCategories.Selected; m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); // We do the body disable soft twice because 'in theory' a collision could have happened // in between the disabling and the collision properties setting // which would wake the physical body up from a soft disabling and potentially cause it to fall // through the ground. // NOTE FOR JOINTS: this doesn't always work for jointed assemblies because if you select // just one part of the assembly, the rest of the assembly is non-selected and still simulating, // so that causes the selected part to wake up and continue moving. // even if you select all parts of a jointed assembly, it is not guaranteed that the entire // assembly will stop simulating during the selection, because of the lack of atomicity // of select operations (their processing could be interrupted by a thread switch, causing // simulation to continue before all of the selected object notifications trickle down to // the physics engine). // e.g. we select 100 prims that are connected by joints. non-atomically, the first 50 are // selected and disabled. then, due to a thread switch, the selection processing is // interrupted and the physics engine continues to simulate, so the last 50 items, whose // selection was not yet processed, continues to simulate. this wakes up ALL of the // first 50 again. then the last 50 are disabled. then the first 50, which were just woken // up, start simulating again, which in turn wakes up the last 50. if (isphys) { disableBodySoft(); } if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } if (isphys) { disableBodySoft(); } } else { m_collisionCategories = CollisionCategories.Geom; if (isphys) m_collisionCategories |= CollisionCategories.Body; m_collisionFlags = m_default_collisionFlags; if (m_collidesLand) m_collisionFlags |= CollisionCategories.Land; if (m_collidesWater) m_collisionFlags |= CollisionCategories.Water; if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } if (isphys) { if (Body != IntPtr.Zero) { d.BodySetLinearVel(Body, 0f, 0f, 0f); d.BodySetAngularVel(Body, 0f, 0f, 0f); d.BodySetForce(Body, 0, 0, 0); d.BodySetTorque(Body, 0, 0, 0); enableBodySoft(); } } } resetCollisionAccounting(); m_isSelected = newsel; }//end changeSelectedStatus
/// <summary> /// Add a child prim to this parent prim. /// </summary> /// <param name="prim">Child prim</param> private void AddChildPrim(OdePrim prim) { if (LocalID == prim.LocalID) return; if (Body == IntPtr.Zero) { Body = d.BodyCreate(_parent_scene.world); setMass(); } lock (childrenPrim) { if (childrenPrim.Contains(prim)) return; // m_log.DebugFormat( // "[ODE PRIM]: Linking prim {0} {1} to {2} {3}", prim.Name, prim.LocalID, Name, LocalID); childrenPrim.Add(prim); foreach (OdePrim prm in childrenPrim) { d.Mass m2; d.MassSetZero(out m2); d.MassSetBoxTotal(out m2, prm.CalculateMass(), prm._size.X, prm._size.Y, prm._size.Z); d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); d.MassRotate(ref m2, ref mat); d.MassTranslate(ref m2, Position.X - prm.Position.X, Position.Y - prm.Position.Y, Position.Z - prm.Position.Z); d.MassAdd(ref pMass, ref m2); } foreach (OdePrim prm in childrenPrim) { prm.m_collisionCategories |= CollisionCategories.Body; prm.m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); //Console.WriteLine(" GeomSetCategoryBits 1: " + prm.prim_geom + " - " + (int)prm.m_collisionCategories + " for " + Name); if (prm.m_assetFailed) { d.GeomSetCategoryBits(prm.prim_geom, 0); d.GeomSetCollideBits(prm.prim_geom, (uint)prm.BadMeshAssetCollideBits); } else { d.GeomSetCategoryBits(prm.prim_geom, (uint)prm.m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (uint)prm.m_collisionFlags); } d.Quaternion quat = new d.Quaternion(); quat.W = prm._orientation.W; quat.X = prm._orientation.X; quat.Y = prm._orientation.Y; quat.Z = prm._orientation.Z; d.Matrix3 mat = new d.Matrix3(); d.RfromQ(out mat, ref quat); if (Body != IntPtr.Zero) { d.GeomSetBody(prm.prim_geom, Body); prm.childPrim = true; d.GeomSetOffsetWorldPosition(prm.prim_geom, prm.Position.X , prm.Position.Y, prm.Position.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); d.GeomSetOffsetWorldRotation(prm.prim_geom, ref mat); //d.GeomSetOffsetRotation(prm.prim_geom, ref mat); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); } else { m_log.DebugFormat("[PHYSICS]: {0} ain't got no boooooooooddy, no body", Name); } prm.m_interpenetrationcount = 0; prm.m_collisionscore = 0; prm.m_disabled = false; prm.Body = Body; _parent_scene.ActivatePrim(prm); } m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); if (m_assetFailed) { d.GeomSetCategoryBits(prim_geom, 0); d.GeomSetCollideBits(prim_geom, (uint)BadMeshAssetCollideBits); } else { //Console.WriteLine("GeomSetCategoryBits 2: " + prim_geom + " - " + (int)m_collisionCategories + " for " + Name); d.GeomSetCategoryBits(prim_geom, (uint)m_collisionCategories); //Console.WriteLine(" Post GeomSetCategoryBits 2"); d.GeomSetCollideBits(prim_geom, (uint)m_collisionFlags); } d.Quaternion quat2 = new d.Quaternion(); quat2.W = _orientation.W; quat2.X = _orientation.X; quat2.Y = _orientation.Y; quat2.Z = _orientation.Z; d.Matrix3 mat2 = new d.Matrix3(); d.RfromQ(out mat2, ref quat2); d.GeomSetBody(prim_geom, Body); d.GeomSetOffsetWorldPosition(prim_geom, Position.X - pMass.c.X, Position.Y - pMass.c.Y, Position.Z - pMass.c.Z); //d.GeomSetOffsetPosition(prim.prim_geom, // (Position.X - prm.Position.X) - pMass.c.X, // (Position.Y - prm.Position.Y) - pMass.c.Y, // (Position.Z - prm.Position.Z) - pMass.c.Z); //d.GeomSetOffsetRotation(prim_geom, ref mat2); d.MassTranslate(ref pMass, -pMass.c.X, -pMass.c.Y, -pMass.c.Z); d.BodySetMass(Body, ref pMass); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here // or remove if (_parent == null) { createAMotor(m_angularlock); } d.BodySetPosition(Body, Position.X, Position.Y, Position.Z); if (m_vehicle.Type != Vehicle.TYPE_NONE) m_vehicle.Enable(Body, _parent_scene); _parent_scene.ActivatePrim(this); } }
/// <summary> /// Change prim in response to a float on water taint. /// </summary> /// <param name="timestep"></param> private void changefloatonwater() { m_collidesWater = m_taintCollidesWater; if (m_collidesWater) { m_collisionFlags |= CollisionCategories.Water; } else { m_collisionFlags &= ~CollisionCategories.Water; } d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); }
/// <summary> /// Make a prim subject to physics. /// </summary> public void enableBody() { // Don't enable this body if we're a child prim // this should be taken care of in the parent function not here if (!childPrim) { // Sets the geom to a body Body = d.BodyCreate(_parent_scene.world); setMass(); d.BodySetPosition(Body, _position.X, _position.Y, _position.Z); d.Quaternion myrot = new d.Quaternion(); myrot.X = _orientation.X; myrot.Y = _orientation.Y; myrot.Z = _orientation.Z; myrot.W = _orientation.W; d.BodySetQuaternion(Body, ref myrot); d.GeomSetBody(prim_geom, Body); m_collisionCategories |= CollisionCategories.Body; m_collisionFlags |= (CollisionCategories.Land | CollisionCategories.Wind); d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); d.BodySetAutoDisableFlag(Body, true); d.BodySetAutoDisableSteps(Body, body_autodisable_frames); // disconnect from world gravity so we can apply buoyancy d.BodySetGravityMode (Body, false); m_interpenetrationcount = 0; m_collisionscore = 0; m_disabled = false; // The body doesn't already have a finite rotation mode set here if ((!m_angularlock.ApproxEquals(Vector3.Zero, 0.0f)) && _parent == null) { createAMotor(m_angularlock); } if (m_vehicle.Type != Vehicle.TYPE_NONE) { m_vehicle.Enable(Body, _parent_scene); } _parent_scene.addActivePrim(this); } }
private void DestroyBody() { if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); UpdateDataFromGeom(); SetInStaticSpace(this); } if (!childPrim) { lock (childrenPrim) { foreach (OdePrim prm in childrenPrim) { _parent_scene.remActivePrim(prm); prm.m_collisionCategories &= ~CollisionCategories.Body; prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prm.prim_geom != IntPtr.Zero) { prm.UpdateDataFromGeom(); d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); SetInStaticSpace(prm); } prm.Body = IntPtr.Zero; prm._mass = prm.primMass; } } d.BodyDestroy(Body); } Body = IntPtr.Zero; } _mass = primMass; m_disabled = true; m_collisionscore = 0; }
/// <summary> /// Stop a prim from being subject to physics. /// </summary> public void disableBody() { //this kills the body so things like 'mesh' can re-create it. lock (this) { if (!childPrim) { if (Body != IntPtr.Zero) { _parent_scene.remActivePrim(this); m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } d.BodyDestroy(Body); lock (childrenPrim) { if (childrenPrim.Count > 0) { foreach (OdePrim prm in childrenPrim) { _parent_scene.remActivePrim(prm); prm.Body = IntPtr.Zero; } } } Body = IntPtr.Zero; } } else { _parent_scene.remActivePrim(this); m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } Body = IntPtr.Zero; } } m_disabled = true; m_collisionscore = 0; }
private void changeSelectedStatus(bool newval) { m_isSelected = newval; Stop(); if (newval) { m_collisionCategories = CollisionCategories.Selected; m_collisionFlags = (CollisionCategories.Sensor | CollisionCategories.Space); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } disableBodySoft(); } else { m_collisionCategories = CollisionCategories.Geom; if (m_isphysical) m_collisionCategories |= CollisionCategories.Body; m_collisionFlags = m_default_collisionFlags; if (m_collidesLand) m_collisionFlags |= CollisionCategories.Land; if (m_collidesWater) m_collisionFlags |= CollisionCategories.Water; if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } enableBodySoft(); } resetCollisionAccounting(); }
public void changefloatonwater(object arg) { m_collidesWater = (bool) arg; if (prim_geom != IntPtr.Zero) { if (m_collidesWater) { m_collisionFlags |= CollisionCategories.Water; } else { m_collisionFlags &= ~CollisionCategories.Water; } d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } }
private void changeFloatOnWater(bool newval) { m_collidesWater = newval; if (prim_geom != IntPtr.Zero) { if (m_collidesWater) { m_collisionFlags |= CollisionCategories.Water; } else { m_collisionFlags &= ~CollisionCategories.Water; } d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } }
public void DestroyBody() // for now removes all colisions etc from childs, full body reconstruction is needed after this { //this kills the body so things like 'mesh' can re-create it. lock (this) { if (Body != IntPtr.Zero) _parent_scene.remActivePrim(this); m_collisionCategories &= ~CollisionCategories.Body; m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prim_geom, (int)m_collisionFlags); } if (!childPrim) { lock (childrenPrim) { foreach (AuroraODEPrim prm in childrenPrim) { _parent_scene.remActivePrim(prm); prm.m_collisionCategories &= ~CollisionCategories.Body; prm.m_collisionFlags &= ~(CollisionCategories.Wind | CollisionCategories.Land); if (prm.prim_geom != IntPtr.Zero) { d.GeomSetCategoryBits(prm.prim_geom, (int)m_collisionCategories); d.GeomSetCollideBits(prm.prim_geom, (int)m_collisionFlags); } prm.Body = IntPtr.Zero; } } if (Body != IntPtr.Zero) { m_vehicle.Disable(this); d.BodyDestroy(Body); } } _mass = primMass; Body = IntPtr.Zero; } m_disabled = true; m_collisionscore = 0; }
public void ChangeFloatOnWater(bool arg) { m_collidesWater = arg; if (prim_geom != IntPtr.Zero) { if (m_collidesWater) m_collisionFlags |= CollisionCategories.Water; else m_collisionFlags &= ~CollisionCategories.Water; d.GeomSetCollideBits(prim_geom, (int) m_collisionFlags); } }